diff --git a/.github/workflows/doc-publish.yml b/.github/workflows/doc-publish.yml index 351b3277f92..538e77322fc 100644 --- a/.github/workflows/doc-publish.yml +++ b/.github/workflows/doc-publish.yml @@ -75,7 +75,7 @@ jobs: [Documentation preview for this PR](${{ steps.deploy-netlify.outputs.NETLIFY_URL }}) (built with commit ${{ steps.source-run-info.outputs.sourceHeadSha }}) is ready! :tada: - name: Update deployment status PR check - uses: myrotvorets/set-commit-status-action@1.1.6 + uses: myrotvorets/set-commit-status-action@v1.1.7 if: ${{ always() }} env: DEPLOY_SUCCESS: Successfully deployed preview. diff --git a/.zenodo.json.in b/.zenodo.json.in deleted file mode 100644 index 744e020705a..00000000000 --- a/.zenodo.json.in +++ /dev/null @@ -1,27 +0,0 @@ -{ - "description": "Mirror of the Sage https://sagemath.org/ source tree", - "license": "other-open", - "title": "sagemath/sage: ${SAGE_VERSION}", - "version": "${SAGE_VERSION}", - "upload_type": "software", - "publication_date": "${SAGE_RELEASE_DATE}", - "creators": [ - { - "affiliation": "SageMath.org", - "name": "The SageMath Developers" - } - ], - "access_right": "open", - "related_identifiers": [ - { - "scheme": "url", - "identifier": "https://github.com/sagemath/sage/tree/${SAGE_VERSION}", - "relation": "isSupplementTo" - }, - { - "scheme": "doi", - "identifier": "10.5281/zenodo.593563", - "relation": "isNewVersionOf" - } - ] -} diff --git a/CITATION.cff b/CITATION.cff index d97e13cb2cb..29721b280a3 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,8 +4,8 @@ title: SageMath abstract: SageMath is a free open-source mathematics software system. authors: - name: "The SageMath Developers" -version: 9.5 +version: 10.1.beta3 doi: 10.5281/zenodo.593563 -date-released: 2022-01-18 +date-released: 2023-06-11 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/CITATION.cff.in b/CITATION.cff.in new file mode 100644 index 00000000000..bf7d5d3e58c --- /dev/null +++ b/CITATION.cff.in @@ -0,0 +1,11 @@ +cff-version: 1.2.0 +message: "If you use this software, please cite it as below." +title: SageMath +abstract: SageMath is a free open-source mathematics software system. +authors: +- name: "The SageMath Developers" +version: ${SAGE_VERSION} +doi: 10.5281/zenodo.593563 +date-released: ${SAGE_RELEASE_DATE} +repository-code: "https://github.com/sagemath/sage" +url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index c4c9b181ed8..22e57381881 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.1.beta2, Release Date: 2023-06-03 +SageMath version 10.1.beta3, Release Date: 2023-06-11 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index aba45904375..7a9a8380e2c 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=05ff783186ba44f6afec3fad5fecea42acb32db6 -md5=ecd17bd2d001b1c17586fa7877550bf9 -cksum=1852648534 +sha1=c7c1743bdc3941301764422bef5694849cd1e265 +md5=610ce114c46a794ffd70346581012808 +cksum=2506747194 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 4d8c8abae1e..d10b3c6b793 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -17aa7f7ea5b8522f028ef5a87613f1979978a748 +464d3d20aaa0a04237ebc98378cf1eec48505e17 diff --git a/build/pkgs/igraph/checksums.ini b/build/pkgs/igraph/checksums.ini index f7d3336bda8..279cba457a9 100644 --- a/build/pkgs/igraph/checksums.ini +++ b/build/pkgs/igraph/checksums.ini @@ -1,5 +1,5 @@ tarball=igraph-VERSION.tar.gz -sha1=20587332f0f36d6d7eb3cca248e2dab76e1e58ad -md5=af41eb9c614946c4a92a51834e9cab4a -cksum=4011381306 +sha1=fc3c6627f889b13581b2b468e1b16aceff453cfc +md5=10a3f325425970c75a7ba8359376e208 +cksum=3103730646 upstream_url=https://github.com/igraph/igraph/releases/download/VERSION/igraph-VERSION.tar.gz diff --git a/build/pkgs/igraph/package-version.txt b/build/pkgs/igraph/package-version.txt index 5eef0f10e8c..9b40aa6c214 100644 --- a/build/pkgs/igraph/package-version.txt +++ b/build/pkgs/igraph/package-version.txt @@ -1 +1 @@ -0.10.2 +0.10.4 diff --git a/build/pkgs/info/spkg-configure.m4 b/build/pkgs/info/spkg-configure.m4 index 85fe1ea4731..76ea2cc7565 100644 --- a/build/pkgs/info/spkg-configure.m4 +++ b/build/pkgs/info/spkg-configure.m4 @@ -9,6 +9,7 @@ SAGE_SPKG_CONFIGURE([info], [ AS_IF([makeinfo -c foo 2>&1 | grep -q invalid], [ dnl makeinfo found, but too old, and does not support all options that ecl likes to use sage_spkg_install_info=yes]) + rm -f stdin.info ]) ]) ]) diff --git a/build/pkgs/maxima/spkg-install.in b/build/pkgs/maxima/spkg-install.in index cdb6fbf2069..ef044cbf010 100644 --- a/build/pkgs/maxima/spkg-install.in +++ b/build/pkgs/maxima/spkg-install.in @@ -20,6 +20,10 @@ cd src/ # Use newer version of config.guess and config.sub (see Trac #19734) cp "$SAGE_ROOT"/config/config.* . +# Patch out bad 'multiple targets' rule +# https://github.com/sagemath/sage/pull/35619#issuecomment-1567351409 +sed -i.bak 's/^maxima_singlepage.html //' doc/info/Makefile.in + # Note that maxima configure checks for git and, if it finds it, uses # versions information from the repo. See #15529. We disable this with # git_found=false diff --git a/build/pkgs/networkx/checksums.ini b/build/pkgs/networkx/checksums.ini index 00b6f1fa335..dd792a15a2e 100644 --- a/build/pkgs/networkx/checksums.ini +++ b/build/pkgs/networkx/checksums.ini @@ -1,5 +1,5 @@ tarball=networkx-VERSION.tar.gz -sha1=40e981041664856ba473c9079006367ed0d0e71b -md5=22139ab5a47818fa00cbaa91eb126381 -cksum=4201985987 +sha1=d4b1d6117b7c54db61f6cbec8f0ccfb0f7d47293 +md5=1a9baa93b7fd4470c80e29a7a6d93ccf +cksum=1675580484 upstream_url=https://pypi.io/packages/source/n/networkx/networkx-VERSION.tar.gz diff --git a/build/pkgs/networkx/install-requires.txt b/build/pkgs/networkx/install-requires.txt index 9b1205be0a8..ea173da7538 100644 --- a/build/pkgs/networkx/install-requires.txt +++ b/build/pkgs/networkx/install-requires.txt @@ -1,2 +1 @@ -# features removed in 3.0 listed in https://networkx.org/documentation/stable/developer/deprecations.html#version-3-0 -networkx >=2.4, <3.0 +networkx >=2.4, <3.2 diff --git a/build/pkgs/networkx/package-version.txt b/build/pkgs/networkx/package-version.txt index 80803faf1b9..8c50098d8ae 100644 --- a/build/pkgs/networkx/package-version.txt +++ b/build/pkgs/networkx/package-version.txt @@ -1 +1 @@ -2.8.8 +3.1 diff --git a/build/pkgs/pyflakes/SPKG.rst b/build/pkgs/pyflakes/SPKG.rst deleted file mode 100644 index 88c3f07d2a7..00000000000 --- a/build/pkgs/pyflakes/SPKG.rst +++ /dev/null @@ -1,18 +0,0 @@ -pyflakes: Passive checker of Python programs -============================================ - -Description ------------ - -passive checker of Python programs - -License -------- - -MIT - -Upstream Contact ----------------- - -https://pypi.org/project/pyflakes/ - diff --git a/build/pkgs/pyflakes/distros/conda.txt b/build/pkgs/pyflakes/distros/conda.txt deleted file mode 100644 index 38675cb44a2..00000000000 --- a/build/pkgs/pyflakes/distros/conda.txt +++ /dev/null @@ -1 +0,0 @@ -pyflakes diff --git a/build/pkgs/pyflakes/distros/macports.txt b/build/pkgs/pyflakes/distros/macports.txt deleted file mode 100644 index 399db8ac7bb..00000000000 --- a/build/pkgs/pyflakes/distros/macports.txt +++ /dev/null @@ -1 +0,0 @@ -py-pyflakes diff --git a/build/pkgs/pyflakes/distros/opensuse.txt b/build/pkgs/pyflakes/distros/opensuse.txt deleted file mode 100644 index a16ae878a72..00000000000 --- a/build/pkgs/pyflakes/distros/opensuse.txt +++ /dev/null @@ -1 +0,0 @@ -python3-pyflakes diff --git a/build/pkgs/pyflakes/distros/repology.txt b/build/pkgs/pyflakes/distros/repology.txt deleted file mode 100644 index 9990e60b2eb..00000000000 --- a/build/pkgs/pyflakes/distros/repology.txt +++ /dev/null @@ -1,2 +0,0 @@ -pyflakes -python:pyflakes diff --git a/build/pkgs/pyflakes/distros/void.txt b/build/pkgs/pyflakes/distros/void.txt deleted file mode 100644 index a16ae878a72..00000000000 --- a/build/pkgs/pyflakes/distros/void.txt +++ /dev/null @@ -1 +0,0 @@ -python3-pyflakes diff --git a/build/pkgs/pyflakes/requirements.txt b/build/pkgs/pyflakes/requirements.txt deleted file mode 100644 index 38675cb44a2..00000000000 --- a/build/pkgs/pyflakes/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -pyflakes diff --git a/build/pkgs/pyflakes/type b/build/pkgs/pyflakes/type deleted file mode 100644 index 134d9bc32d5..00000000000 --- a/build/pkgs/pyflakes/type +++ /dev/null @@ -1 +0,0 @@ -optional diff --git a/build/pkgs/python_igraph/checksums.ini b/build/pkgs/python_igraph/checksums.ini index 5f8bc59a4de..7247680193c 100644 --- a/build/pkgs/python_igraph/checksums.ini +++ b/build/pkgs/python_igraph/checksums.ini @@ -1,5 +1,5 @@ tarball=python-igraph-VERSION.tar.gz -sha1=6a6bca77737ff501e97f808aa18a9045e86b3e3e -md5=6951cc2e803118b74209ae21d54de38a -cksum=650236223 +sha1=807a95ad4080d8eb500e7797325d6f11a5c46892 +md5=2ac3561dda7e7321789041261a29aba4 +cksum=754615899 upstream_url=https://pypi.io/packages/source/i/igraph/igraph-VERSION.tar.gz diff --git a/build/pkgs/python_igraph/package-version.txt b/build/pkgs/python_igraph/package-version.txt index 5eef0f10e8c..9b40aa6c214 100644 --- a/build/pkgs/python_igraph/package-version.txt +++ b/build/pkgs/python_igraph/package-version.txt @@ -1 +1 @@ -0.10.2 +0.10.4 diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index d50a8e7117e..89c7f89092e 100644 --- a/build/pkgs/sage_conf/install-requires.txt +++ b/build/pkgs/sage_conf/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-conf ~= 10.1b2 +sage-conf ~= 10.1b3 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index bd6be79c3ef..3853df189b7 100644 --- a/build/pkgs/sage_docbuild/install-requires.txt +++ b/build/pkgs/sage_docbuild/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-docbuild ~= 10.1b2 +sage-docbuild ~= 10.1b3 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index e2f10b4a6b5..cbe875cbadf 100644 --- a/build/pkgs/sage_setup/install-requires.txt +++ b/build/pkgs/sage_setup/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-setup ~= 10.1b2 +sage-setup ~= 10.1b3 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index cae34b0b6fe..15283c90e87 100644 --- a/build/pkgs/sage_sws2rst/install-requires.txt +++ b/build/pkgs/sage_sws2rst/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-sws2rst ~= 10.1b2 +sage-sws2rst ~= 10.1b3 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index 35c2a8040ec..26f47a8cfe0 100644 --- a/build/pkgs/sagelib/install-requires.txt +++ b/build/pkgs/sagelib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagelib ~= 10.1b2 +sagelib ~= 10.1b3 diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index 1b18527c75d..5b009ccfdcb 100644 --- a/build/pkgs/sagemath_categories/install-requires.txt +++ b/build/pkgs/sagemath_categories/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-categories ~= 10.1b2 +sagemath-categories ~= 10.1b3 diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index dddc4170942..0d2a87143f3 100644 --- a/build/pkgs/sagemath_environment/install-requires.txt +++ b/build/pkgs/sagemath_environment/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-environment ~= 10.1b2 +sagemath-environment ~= 10.1b3 diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index 8254467164b..3f15a34d3aa 100644 --- a/build/pkgs/sagemath_objects/install-requires.txt +++ b/build/pkgs/sagemath_objects/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-objects ~= 10.1b2 +sagemath-objects ~= 10.1b3 diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index 6b98d320073..bc8bda08722 100644 --- a/build/pkgs/sagemath_repl/install-requires.txt +++ b/build/pkgs/sagemath_repl/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-repl ~= 10.1b2 +sagemath-repl ~= 10.1b3 diff --git a/build/pkgs/symengine/checksums.ini b/build/pkgs/symengine/checksums.ini index 712c4eddb90..1c1813e7eea 100644 --- a/build/pkgs/symengine/checksums.ini +++ b/build/pkgs/symengine/checksums.ini @@ -1,5 +1,5 @@ tarball=symengine-VERSION.tar.gz -sha1=87a0104d8682cb2f192d8b4bf3435a514bdb6f4c -md5=967b913b365eda9fb30ecb3f1ded46f2 -cksum=2359123828 +sha1=11885879ddcd0a9ab69e36a79b93aef836d6c95d +md5=4673c85b423241ce85a9df35a7ed61bb +cksum=1344562381 upstream_url=https://github.com/symengine/symengine/releases/download/vVERSION/symengine-VERSION.tar.gz diff --git a/build/pkgs/symengine/package-version.txt b/build/pkgs/symengine/package-version.txt index 6f4eebdf6f6..571215736a6 100644 --- a/build/pkgs/symengine/package-version.txt +++ b/build/pkgs/symengine/package-version.txt @@ -1 +1 @@ -0.8.1 +0.10.1 diff --git a/build/pkgs/symengine_py/checksums.ini b/build/pkgs/symengine_py/checksums.ini index 3b0db282ffa..0235c5e9cd9 100644 --- a/build/pkgs/symengine_py/checksums.ini +++ b/build/pkgs/symengine_py/checksums.ini @@ -1,5 +1,5 @@ tarball=symengine.py-VERSION.tar.gz -sha1=16da67020baf6ab95cd517f58618fa7af1c8fc5e -md5=1c365dd039f8568b732c39fa4c9a7cf4 -cksum=3244910588 +sha1=fbbf052e66077ec51df319444b71f94114f33d9e +md5=fc5d2d7f571a880aa2e040214aed2ff0 +cksum=2535731241 upstream_url=https://github.com/symengine/symengine.py/archive/vVERSION.tar.gz diff --git a/build/pkgs/symengine_py/package-version.txt b/build/pkgs/symengine_py/package-version.txt index 25329dc9cba..78bc1abd14f 100644 --- a/build/pkgs/symengine_py/package-version.txt +++ b/build/pkgs/symengine_py/package-version.txt @@ -1 +1 @@ -0.8.1.p0 +0.10.0 diff --git a/build/pkgs/symengine_py/patches/0001-Fix-getting-string-representation-of-sage-objects.patch b/build/pkgs/symengine_py/patches/0001-Fix-getting-string-representation-of-sage-objects.patch deleted file mode 100644 index 78c71610b53..00000000000 --- a/build/pkgs/symengine_py/patches/0001-Fix-getting-string-representation-of-sage-objects.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 68c90c14ae3e779b88a513195cc89db599d10efb Mon Sep 17 00:00:00 2001 -From: Isuru Fernando -Date: Fri, 1 Oct 2021 19:25:07 -0700 -Subject: [PATCH] Fix getting string representation of sage objects - ---- - symengine/lib/pywrapper.cpp | 17 ++++++----------- - symengine/lib/symengine_wrapper.pyx | 9 ++++++--- - symengine/tests/test_sage.py | 10 +++------- - symengine/tests/test_sympy_conv.py | 1 + - 4 files changed, 16 insertions(+), 21 deletions(-) - -diff --git a/symengine/lib/pywrapper.cpp b/symengine/lib/pywrapper.cpp -index ca7b7c1..c321ea3 100644 ---- a/symengine/lib/pywrapper.cpp -+++ b/symengine/lib/pywrapper.cpp -@@ -175,17 +175,12 @@ RCP PyNumber::eval(long bits) const { - } - - std::string PyNumber::__str__() const { -- PyObject* temp; -- std::string str; --#if PY_MAJOR_VERSION > 2 -- temp = PyUnicode_AsUTF8String(pyobject_); -- str = std::string(PyBytes_AsString(temp)); --#else -- temp = PyObject_Str(pyobject_); -- str = std::string(PyString_AsString(temp)); --#endif -- Py_XDECREF(temp); -- return str; -+ Py_ssize_t size; -+ PyObject *pystr = PyObject_Str(pyobject_); -+ const char* data = PyUnicode_AsUTF8AndSize(pystr, &size); -+ std::string result = std::string(data, size); -+ Py_XDECREF(pystr); -+ return result; - } - - // PyFunctionClass -diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx -index d178afe..d18c058 100644 ---- a/symengine/lib/symengine_wrapper.pyx -+++ b/symengine/lib/symengine_wrapper.pyx -@@ -2690,7 +2690,7 @@ class FunctionSymbol(Function): - def _sage_(self): - import sage.all as sage - name = self.get_name() -- return sage.function(name, *self.args_as_sage()) -+ return sage.function(name)(*self.args_as_sage()) - - def func(self, *values): - name = self.get_name() -@@ -2711,7 +2711,7 @@ cdef rcp_const_basic pynumber_to_symengine(PyObject* o1): - - cdef PyObject* symengine_to_sage(rcp_const_basic o1): - import sage.all as sage -- t = sage.SR(c2py(o1)._sage_()) -+ t = c2py(o1)._sage_() - Py_XINCREF(t) - return (t) - -@@ -2765,7 +2765,10 @@ cdef class PyNumber(Number): - - def _sage_(self): - import sage.all as sage -- return sage.SR(self.pyobject()) -+ res = self.pyobject() -+ if hasattr(res, '_sage_'): -+ return res._sage_() -+ return res - - def pyobject(self): - return deref(symengine.rcp_static_cast_PyNumber(self.thisptr)).get_py_object() -diff --git a/symengine/tests/test_sage.py b/symengine/tests/test_sage.py -index 3b994ab..e364bd6 100644 ---- a/symengine/tests/test_sage.py -+++ b/symengine/tests/test_sage.py -@@ -66,9 +66,9 @@ def test_sage_conversions(): - assert cos(x1)._sage_() == sage.cos(x) - assert cos(x1) == sympify(sage.cos(x)) - -- assert function_symbol('f', x1, y1)._sage_() == sage.function('f', x, y) -+ assert function_symbol('f', x1, y1)._sage_() == sage.function('f')(x, y) - assert (function_symbol('f', 2 * x1, x1 + y1).diff(x1)._sage_() == -- sage.function('f', 2 * x, x + y).diff(x)) -+ sage.function('f')(2 * x, x + y).diff(x)) - - assert LambertW(x1) == LambertW(x) - assert LambertW(x1)._sage_() == sage.lambert_w(x) -@@ -142,11 +142,7 @@ def test_sage_conversions(): - b = b + 8 - assert isinstance(b, PyNumber) - assert b._sage_() == a -- -- a = a + x -- b = b + x -- assert isinstance(b, Add) -- assert b._sage_() == a -+ assert str(a) == str(b) - - # Sage Function - e = x1 + wrap_sage_function(sage.log_gamma(x)) -diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py -index 3f8b152..ee070a8 100644 ---- a/symengine/tests/test_sympy_conv.py -+++ b/symengine/tests/test_sympy_conv.py -@@ -760,6 +760,7 @@ def test_pynumber(): - assert isinstance(b, PyNumber) - assert b == a # Check equality via SymEngine - assert a == b # Check equality via SymPy -+ assert str(a) == str(b) - - a = 1 - a - b = 1 - b --- -2.7.4 - diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/src/VERSION.txt b/src/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/src/bin/sage-update-version b/src/bin/sage-update-version index 40df8926f74..fd6d2a8dcf3 100755 --- a/src/bin/sage-update-version +++ b/src/bin/sage-update-version @@ -86,17 +86,17 @@ echo "$SAGE_VERSION_BANNER" > "$SAGE_ROOT/VERSION.txt" # Regenerate auto-generated files tarball "$SAGE_ROOT/bootstrap" -s -# Create json file for Zenodo +# Create CITATION file for Zenodo-GitHub integration export SAGE_VERSION export SAGE_RELEASE_DATE -envsubst <"$SAGE_ROOT/.zenodo.json.in" >"$SAGE_ROOT/.zenodo.json" +envsubst <"$SAGE_ROOT/CITATION.cff.in" >"$SAGE_ROOT/CITATION.cff" # Commit auto-generated changes git commit -m "Updated SageMath version to $SAGE_VERSION" -- \ "$SAGE_ROOT/VERSION.txt" \ - "$SAGE_ROOT/.zenodo.json" \ "$SAGE_SRC/sage/version.py" \ "$SAGE_SRC/VERSION.txt" \ + "$SAGE_ROOT/CITATION.cff" \ "$SAGE_SRC/bin/sage-version.sh" \ "$SAGE_ROOT/build/pkgs/configure/checksums.ini" \ "$SAGE_ROOT/build/pkgs/configure/package-version.txt" \ diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 1a398cd9676..00fd83ccd47 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -4,6 +4,6 @@ # which stops "setup.py develop" from rewriting it as a Python file. : # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='10.1.beta2' -SAGE_RELEASE_DATE='2023-06-03' -SAGE_VERSION_BANNER='SageMath version 10.1.beta2, Release Date: 2023-06-03' +SAGE_VERSION='10.1.beta3' +SAGE_RELEASE_DATE='2023-06-11' +SAGE_VERSION_BANNER='SageMath version 10.1.beta3, Release Date: 2023-06-11' diff --git a/src/doc/en/reference/matrices/index.rst b/src/doc/en/reference/matrices/index.rst index 25aed6c2cb3..fb06992c1e1 100644 --- a/src/doc/en/reference/matrices/index.rst +++ b/src/doc/en/reference/matrices/index.rst @@ -79,6 +79,7 @@ objects like operation tables (e.g. the multiplication table of a group). sage/matrix/matrix_modn_dense_float sage/matrix/matrix_modn_sparse sage/matrix/matrix_symbolic_dense + sage/matrix/matrix_symbolic_sparse sage/matrix/matrix_complex_double_dense sage/matrix/matrix_complex_ball_dense sage/matrix/matrix_polynomial_dense diff --git a/src/doc/en/reference/modules/index.rst b/src/doc/en/reference/modules/index.rst index 8bf760a6ed8..93a337db04c 100644 --- a/src/doc/en/reference/modules/index.rst +++ b/src/doc/en/reference/modules/index.rst @@ -99,10 +99,14 @@ Vectors :maxdepth: 1 sage/modules/vector_integer_dense + sage/modules/vector_integer_sparse sage/modules/vector_mod2_dense sage/modules/vector_modn_dense + sage/modules/vector_modn_sparse sage/modules/vector_rational_dense + sage/modules/vector_rational_sparse sage/modules/vector_symbolic_dense + sage/modules/vector_symbolic_sparse sage/modules/vector_callable_symbolic_dense sage/modules/vector_double_dense sage/modules/vector_real_double_dense diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 52f520395d6..76d56d4cb65 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -3038,6 +3038,9 @@ REFERENCES: .. [Har1994] Frank Harary. *Graph Theory*. Reading, MA: Addison-Wesley, 1994. +.. [Har2009] Harvey, David. *Efficient computation of p-adic heights*. + LMS J. Comput. Math. **11** (2008), 40–59. + .. [Harako2020] Shuichi Harako. *The second homology group of the commutative case of Kontsevich's symplectic derivation Lie algebra*. Preprint, 2020, :arxiv:`2006.06064`. @@ -4737,17 +4740,21 @@ REFERENCES: sharpening of the Parikh mapping*. Theoret. Informatics Appl. 35 (2001) 551-564. +.. [MST2006] Barry Mazur, William Stein, John Tate. + *Computation of p-adic heights and log convergence*. + Doc. Math. 2006, Extra Vol., 577-614. + .. [MSZ2013] Michael Maschler, Solan Eilon, and Zamir Shmuel. *Game Theory*. Cambridge: Cambridge University Press, (2013). ISBN 9781107005488. -.. [MT1991] Mazur, B., & Tate, J. (1991). The `p`-adic sigma - function. Duke Mathematical Journal, 62(3), 663-688. +.. [MT1991] Mazur, B., & Tate, J. (1991). *The `p`-adic sigma + function*. Duke Mathematical Journal, **62** (3), 663-688. -.. [MTT1986] \B. Mazur, J. Tate, and J. Teitelbaum, On `p`-adic - analogues of the conjectures of Birch and - Swinnerton-Dyer, Inventiones Mathematicae 84, (1986), - 1-48. +.. [MTT1986] \B. Mazur, J. Tate, and J. Teitelbaum, + *On `p`-adic analogues of the conjectures of Birch and + Swinnerton-Dyer*, + Inventiones Mathematicae **84**, (1986), 1-48. .. [Mu1997] Murty, M. Ram. *Congruences between modular forms*. In "Analytic Number Theory" (ed. Y. Motohashi), London Math. Soc. Lecture Notes diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index d8127cc0585..3159fc608d8 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -3886,9 +3886,8 @@ class CohomologyClass(SageObject, CachedRepresentation): sage: CohomologyClass(x^2+2*y*z, A) [2*y*z + x^2] - TESTS: - + In order for the cache to not confuse objects with the same representation, we can pass the parent of the representative as a parameter:: diff --git a/src/sage/algebras/lie_algebras/affine_lie_algebra.py b/src/sage/algebras/lie_algebras/affine_lie_algebra.py index 5bde5399c3d..f94866cd1c6 100644 --- a/src/sage/algebras/lie_algebras/affine_lie_algebra.py +++ b/src/sage/algebras/lie_algebras/affine_lie_algebra.py @@ -1211,4 +1211,4 @@ def __iter__(self): for r in self._roots: yield P((r, i)) for r in self._ac: - yield P((r, i)) \ No newline at end of file + yield P((r, i)) diff --git a/src/sage/categories/simplicial_sets.py b/src/sage/categories/simplicial_sets.py index 952053b907d..245868ce900 100644 --- a/src/sage/categories/simplicial_sets.py +++ b/src/sage/categories/simplicial_sets.py @@ -500,7 +500,7 @@ def covering_map(self, character): faces_dict[cell] = grelems cover = SimplicialSet(faces_dict, base_point=cells_dict[(self.base_point(), G.one())]) cover_map_data = {c : s[0] for (s,c) in cells_dict.items()} - return SimplicialSetMorphism(data = cover_map_data, domain = cover, codomain = self) + return SimplicialSetMorphism(data=cover_map_data, domain=cover, codomain=self) def cover(self, character): r""" diff --git a/src/sage/coding/code_constructions.py b/src/sage/coding/code_constructions.py index 812d5d88df9..abe26710355 100644 --- a/src/sage/coding/code_constructions.py +++ b/src/sage/coding/code_constructions.py @@ -367,8 +367,8 @@ def DuadicCodeEvenPair(F,S1,S2): x = P2.gen() gg1 = P2([_lift2smallest_field(c)[0] for c in g1.coefficients(sparse=False)]) gg2 = P2([_lift2smallest_field(c)[0] for c in g2.coefficients(sparse=False)]) - C1 = CyclicCode(length = n, generator_pol = gg1) - C2 = CyclicCode(length = n, generator_pol = gg2) + C1 = CyclicCode(length=n, generator_pol=gg1) + C2 = CyclicCode(length=n, generator_pol=gg2) return C1,C2 def DuadicCodeOddPair(F,S1,S2): @@ -422,8 +422,8 @@ def DuadicCodeOddPair(F,S1,S2): gg2 = P2(coeffs2) gg1 = gcd(gg1, x**n - 1) gg2 = gcd(gg2, x**n - 1) - C1 = CyclicCode(length = n, generator_pol = gg1) - C2 = CyclicCode(length = n, generator_pol = gg2) + C1 = CyclicCode(length=n, generator_pol=gg1) + C2 = CyclicCode(length=n, generator_pol=gg2) return C1,C2 def ExtendedQuadraticResidueCode(n,F): diff --git a/src/sage/coding/decoder.py b/src/sage/coding/decoder.py index 8a8e6496f74..300464c7d28 100644 --- a/src/sage/coding/decoder.py +++ b/src/sage/coding/decoder.py @@ -343,7 +343,7 @@ def input_space(self): else: raise NotImplementedError("Decoder does not have an _input_space parameter") - @abstract_method(optional = True) + @abstract_method(optional=True) def decoding_radius(self, **kwargs): r""" Return the maximal number of errors that ``self`` is able to correct. diff --git a/src/sage/coding/encoder.py b/src/sage/coding/encoder.py index ba1070633fd..69dc8d46edf 100644 --- a/src/sage/coding/encoder.py +++ b/src/sage/coding/encoder.py @@ -356,7 +356,7 @@ def message_space(self): """ return self.code().base_field()**(self.code().dimension()) - @abstract_method(optional = True) + @abstract_method(optional=True) def generator_matrix(self): r""" Returns a generator matrix of the associated code of ``self``. diff --git a/src/sage/coding/extended_code.py b/src/sage/coding/extended_code.py index 6065d4c2c96..3add539a192 100644 --- a/src/sage/coding/extended_code.py +++ b/src/sage/coding/extended_code.py @@ -301,7 +301,7 @@ class ExtendedCodeOriginalCodeDecoder(Decoder): Decoder of Extension of [15, 7, 9] Reed-Solomon Code over GF(16) through Gao decoder for [15, 7, 9] Reed-Solomon Code over GF(16) """ - def __init__(self, code, original_decoder = None, **kwargs): + def __init__(self, code, original_decoder=None, **kwargs): r""" TESTS: diff --git a/src/sage/coding/guruswami_sudan/gs_decoder.py b/src/sage/coding/guruswami_sudan/gs_decoder.py index 830d49238dc..cfbef3fae0f 100644 --- a/src/sage/coding/guruswami_sudan/gs_decoder.py +++ b/src/sage/coding/guruswami_sudan/gs_decoder.py @@ -238,7 +238,7 @@ class GRSGuruswamiSudanDecoder(Decoder): ####################### static methods ############################### @staticmethod - def parameters_given_tau(tau, C = None, n_k = None): + def parameters_given_tau(tau, C=None, n_k=None): r""" Returns the smallest possible multiplicity and list size given the given parameters of the code and decoding radius. @@ -307,7 +307,7 @@ def try_l(l): return (s, l) @staticmethod - def guruswami_sudan_decoding_radius(C = None, n_k = None, l = None, s = None): + def guruswami_sudan_decoding_radius(C=None, n_k=None, l=None, s=None): r""" Returns the maximal decoding radius of the Guruswami-Sudan decoder and the parameter choices needed for this. @@ -364,7 +364,7 @@ def get_tau(s,l): return gilt(n - n/2*(s+1)/(l+1) - (k-1)/2*l/s) if l is None and s is None: tau = gilt(johnson_radius(n, n - k + 1)) - return (tau, GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k))) + return (tau, GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k=(n, k))) if l is not None and s is not None: return (get_tau(s,l), (s,l)) @@ -401,7 +401,7 @@ def find_integral_max(real_max, f): return (tau, (s,l)) @staticmethod - def _suitable_parameters_given_tau(tau, C = None, n_k = None): + def _suitable_parameters_given_tau(tau, C=None, n_k=None): r""" Return quite good multiplicity and list size parameters for the code parameters and the decoding radius. @@ -473,7 +473,7 @@ def _suitable_parameters_given_tau(tau, C = None, n_k = None): return (s, l) @staticmethod - def gs_satisfactory(tau, s, l, C = None, n_k = None): + def gs_satisfactory(tau, s, l, C=None, n_k=None): r""" Returns whether input parameters satisfy the governing equation of Guruswami-Sudan. @@ -535,7 +535,7 @@ def gs_satisfactory(tau, s, l, C = None, n_k = None): return l > 0 and s > 0 and n * s * (s+1) < (l+1) * (2*s*(n-tau) - (k-1) * l) ####################### decoder itself ############################### - def __init__(self, code, tau = None, parameters = None, interpolation_alg = None, root_finder = None): + def __init__(self, code, tau=None, parameters=None, interpolation_alg=None, root_finder=None): r""" TESTS: @@ -585,16 +585,16 @@ def __init__(self, code, tau = None, parameters = None, interpolation_alg = None raise ValueError("code has to be a generalized Reed-Solomon code") n, k = code.length(), code.dimension() if tau and parameters: - if not GRSGuruswamiSudanDecoder.gs_satisfactory(tau, parameters[0], parameters[1], C = code): + if not GRSGuruswamiSudanDecoder.gs_satisfactory(tau, parameters[0], parameters[1], C=code): raise ValueError("Impossible parameters for the Guruswami-Sudan algorithm") self._tau, self._s, self._ell = tau, parameters[0], parameters[1] elif tau: self._tau = tau - self._s, self._ell = GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) + self._s, self._ell = GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k=(n, k)) elif parameters: self._s = parameters[0] self._ell = parameters[1] - (self._tau,_) = GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(C = code, s=self._s, l=self._ell) + (self._tau,_) = GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(C=code, s=self._s, l=self._ell) else: raise ValueError("Specify either tau or parameters") if callable(interpolation_alg): @@ -834,7 +834,7 @@ def decode_to_code(self, r): raise ValueError("The provided interpolation algorithm has a wrong signature. See the documentation of `codes.decoders.GRSGuruswamiSudanDecoder.interpolation_algorithm()` for details") ## EXAMINE THE FACTORS AND CONVERT TO CODEWORDS try: - polynomials = self.rootfinding_algorithm()(Q, maxd = wy) + polynomials = self.rootfinding_algorithm()(Q, maxd=wy) except TypeError: raise ValueError("The provided root-finding algorithm has a wrong signature. See the documentation of `codes.decoders.GRSGuruswamiSudanDecoder.rootfinding_algorithm()` for details") if not polynomials: diff --git a/src/sage/coding/information_set_decoder.py b/src/sage/coding/information_set_decoder.py index fb4612fa69b..c99550aa7dd 100644 --- a/src/sage/coding/information_set_decoder.py +++ b/src/sage/coding/information_set_decoder.py @@ -115,7 +115,7 @@ class InformationSetAlgorithm(SageObject): ISD Algorithm (MinimalISD) for [24, 12, 8] Extended Golay code over GF(2) decoding up to 4 errors """ - def __init__(self, code, decoding_interval, algorithm_name, parameters = None): + def __init__(self, code, decoding_interval, algorithm_name, parameters=None): r""" TESTS:: @@ -394,7 +394,7 @@ class LeeBrickellISDAlgorithm(InformationSetAlgorithm): sage: A = LeeBrickellISDAlgorithm(C, (2,3)); A ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding between 2 and 3 errors """ - def __init__(self, code, decoding_interval, search_size = None): + def __init__(self, code, decoding_interval, search_size=None): r""" TESTS: diff --git a/src/sage/coding/linear_code_no_metric.py b/src/sage/coding/linear_code_no_metric.py index bb70d6a74c5..5e490c42345 100644 --- a/src/sage/coding/linear_code_no_metric.py +++ b/src/sage/coding/linear_code_no_metric.py @@ -406,7 +406,7 @@ def basis(self): """ gens = self.gens() from sage.structure.sequence import Sequence - return Sequence(gens, universe=self.ambient_space(), check = False, immutable=True, cr=True) + return Sequence(gens, universe=self.ambient_space(), check=False, immutable=True, cr=True) @cached_method def parity_check_matrix(self): diff --git a/src/sage/coding/punctured_code.py b/src/sage/coding/punctured_code.py index 0c85dddbd77..6b99d843f3e 100644 --- a/src/sage/coding/punctured_code.py +++ b/src/sage/coding/punctured_code.py @@ -57,7 +57,7 @@ def _puncture(v, points): new_v = [v[i] for i in range(len(v)) if i not in points] return S(new_v) -def _insert_punctured_positions(l, punctured_points, value = None): +def _insert_punctured_positions(l, punctured_points, value=None): r""" Returns ``l`` with ``value`` inserted in the corresponding position from ``punctured_points``. @@ -485,7 +485,7 @@ class PuncturedCodeOriginalCodeDecoder(Decoder): True """ - def __init__(self, code, strategy = None, original_decoder = None, **kwargs): + def __init__(self, code, strategy=None, original_decoder=None, **kwargs): r""" TESTS: @@ -671,7 +671,7 @@ def decode_to_code(self, y): y = A(yl) return _puncture(D.decode_to_code(y), pts) - def decoding_radius(self, number_erasures = None): + def decoding_radius(self, number_erasures=None): r""" Returns maximal number of errors that ``self`` can decode. diff --git a/src/sage/coding/subfield_subcode.py b/src/sage/coding/subfield_subcode.py index b3861707d6b..9f898bfed1d 100644 --- a/src/sage/coding/subfield_subcode.py +++ b/src/sage/coding/subfield_subcode.py @@ -285,7 +285,7 @@ class SubfieldSubcodeOriginalCodeDecoder(Decoder): Decoder of Subfield subcode of [13, 5, 9] Reed-Solomon Code over GF(16) down to GF(4) through Gao decoder for [13, 5, 9] Reed-Solomon Code over GF(16) """ - def __init__(self, code, original_decoder = None, **kwargs): + def __init__(self, code, original_decoder=None, **kwargs): r""" TESTS: diff --git a/src/sage/combinat/cluster_algebra_quiver/mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/mutation_type.py index da766a9c108..ba4759f56ae 100644 --- a/src/sage/combinat/cluster_algebra_quiver/mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/mutation_type.py @@ -284,7 +284,7 @@ def _check_special_BC_cases(dg, n, check_letter_list, check_twist_list, return 'unknown' # divides into cases depending on whether or not a list 'conn_vert_list' of connecting vertices is given. if conn_vert_list: - mut_type = _connected_mutation_type_AAtildeD( dg, ret_conn_vert = True ) + mut_type = _connected_mutation_type_AAtildeD( dg, ret_conn_vert=True ) # when 'conn_vert_list' is given, the output of _connected_mutation_type_AAtildeD is # either 'unknown' or a pair (mut_type, conn_verts). Then, it is tested if the vertices can be glued together as desired. if not mut_type == 'unknown': @@ -292,7 +292,7 @@ def _check_special_BC_cases(dg, n, check_letter_list, check_twist_list, else: # when conn_vert_list == False, the output of _connected_mutation_type _AAtildeD is simply 'unknown' or the mutation type. # no 'connecting vertices' need to be computed. - mut_type = _connected_mutation_type_AAtildeD( dg, ret_conn_vert = False ) + mut_type = _connected_mutation_type_AAtildeD( dg, ret_conn_vert=False ) conn_verts = [] # when the mutation type is recognized, program now tries more specifically to figure out 'letter' and 'twist' if not mut_type == 'unknown': diff --git a/src/sage/combinat/crystals/affine_factorization.py b/src/sage/combinat/crystals/affine_factorization.py index 9528a3a1f87..eca08c2f3bd 100644 --- a/src/sage/combinat/crystals/affine_factorization.py +++ b/src/sage/combinat/crystals/affine_factorization.py @@ -95,7 +95,7 @@ class AffineFactorizationCrystal(UniqueRepresentation, Parent): ValueError: x cannot be in reduced word of s0*s3*s2 """ @staticmethod - def __classcall_private__(cls, w, n, x = None, k = None): + def __classcall_private__(cls, w, n, x=None, k=None): r""" Classcall to mend the input. @@ -120,7 +120,7 @@ def __classcall_private__(cls, w, n, x = None, k = None): w = w0*(w1.inverse()) return super().__classcall__(cls, w, n, x) - def __init__(self, w, n, x = None): + def __init__(self, w, n, x=None): r""" EXAMPLES:: @@ -146,7 +146,7 @@ def __init__(self, w, n, x = None): sage: B = crystals.AffineFactorization(w,3) sage: TestSuite(B).run() # long time """ - Parent.__init__(self, category = ClassicalCrystals()) + Parent.__init__(self, category=ClassicalCrystals()) self.n = n self.k = w.parent().n-1 self.w = w diff --git a/src/sage/combinat/crystals/alcove_path.py b/src/sage/combinat/crystals/alcove_path.py index 75badb3bde2..ef1ad7a9c75 100644 --- a/src/sage/combinat/crystals/alcove_path.py +++ b/src/sage/combinat/crystals/alcove_path.py @@ -1426,7 +1426,7 @@ class RootsWithHeight(UniqueRepresentation, Parent): """ @staticmethod - def __classcall_private__(cls, starting_weight, cartan_type = None): + def __classcall_private__(cls, starting_weight, cartan_type=None): """ Classcall to mend the input. @@ -1472,7 +1472,7 @@ def __init__(self, weight): sage: R = RootsWithHeight(['A',2],[3,2]) sage: TestSuite(R).run() """ - Parent.__init__(self, category = Sets() ) + Parent.__init__(self, category=Sets() ) cartan_type = weight.parent().cartan_type() self._cartan_type = cartan_type @@ -1959,7 +1959,7 @@ def _test_against_tableaux(R, N, k, clss=CrystalOfAlcovePaths): shapes = Partitions(k).list() for shape in shapes: print("** Shape ", shape) - T = CrystalOfTableaux(R, shape = shape) + T = CrystalOfTableaux(R, shape=shape) ct = len(T.list()) print(" T has ", ct, " nodes.") #T.digraph().show(edge_labels=True) diff --git a/src/sage/combinat/crystals/fast_crystals.py b/src/sage/combinat/crystals/fast_crystals.py index 874f278ee93..d12812f8bce 100644 --- a/src/sage/combinat/crystals/fast_crystals.py +++ b/src/sage/combinat/crystals/fast_crystals.py @@ -100,7 +100,7 @@ class FastCrystal(UniqueRepresentation, Parent): [2, 1, 0]] """ @staticmethod - def __classcall__(cls, cartan_type, shape, format = "string"): + def __classcall__(cls, cartan_type, shape, format="string"): """ Normalize the input arguments to ensure unique representation @@ -126,7 +126,7 @@ def __init__(self, ct, shape, format): The fast crystal for A2 with shape [4,1] sage: TestSuite(C).run() """ - Parent.__init__(self, category = ClassicalCrystals()) + Parent.__init__(self, category=ClassicalCrystals()) # super().__init__(category = FiniteEnumeratedSets()) self._cartan_type = ct if ct[1] != 2: diff --git a/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py b/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py index 5861e84493c..caa2c52fdbc 100644 --- a/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py +++ b/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py @@ -390,7 +390,7 @@ def __init__(self, w, factors, excess): sage: F = DecreasingHeckeFactorizations(w, 3, 1) sage: TestSuite(F).run() """ - Parent.__init__(self, category = FiniteEnumeratedSets()) + Parent.__init__(self, category=FiniteEnumeratedSets()) self.w = tuple(w.reduced_word()) self.factors = factors self.H = w.parent() @@ -566,7 +566,7 @@ def __init__(self, w, factors, excess): if p.has_pattern([3,2,1]): raise ValueError("w should be fully commutative") - Parent.__init__(self, category = ClassicalCrystals()) + Parent.__init__(self, category=ClassicalCrystals()) self.w = tuple(word) self.factors = factors self.H = w.parent() diff --git a/src/sage/combinat/crystals/highest_weight_crystals.py b/src/sage/combinat/crystals/highest_weight_crystals.py index 35cac6fa5eb..1b1d7f315e8 100644 --- a/src/sage/combinat/crystals/highest_weight_crystals.py +++ b/src/sage/combinat/crystals/highest_weight_crystals.py @@ -288,7 +288,7 @@ def __init__(self, dominant_weight): self._highest_weight = dominant_weight assert dominant_weight.is_dominant() self.rename() - Parent.__init__(self, category = ClassicalCrystals()) + Parent.__init__(self, category=ClassicalCrystals()) self.module_generators = [self.module_generator()] def _repr_(self): @@ -377,7 +377,7 @@ def __init__(self, dominant_weight): 2430 """ B1 = CrystalOfLetters(['E',6]) - B6 = CrystalOfLetters(['E',6], dual = True) + B6 = CrystalOfLetters(['E',6], dual=True) self.column_crystal = {1 : B1, 6 : B6, 4 : TensorProductOfCrystals(B1,B1,B1,generators=[[B1([-3,4]),B1([-1,3]),B1([1])]]), 3 : TensorProductOfCrystals(B1,B1,generators=[[B1([-1,3]),B1([1])]]), diff --git a/src/sage/combinat/crystals/kirillov_reshetikhin.py b/src/sage/combinat/crystals/kirillov_reshetikhin.py index ee7175e8a03..5f79d8e1898 100644 --- a/src/sage/combinat/crystals/kirillov_reshetikhin.py +++ b/src/sage/combinat/crystals/kirillov_reshetikhin.py @@ -1640,7 +1640,7 @@ def classical_decomposition(self): The crystal of tableaux of type ['B', 2] and shape(s) [[], [2], [2, 2]] """ return CrystalOfTableaux(['B', self.cartan_type().rank()-1], - shapes = horizontal_dominoes_removed(self.r(),self.s())) + shapes=horizontal_dominoes_removed(self.r(),self.s())) def ambient_crystal(self): r""" @@ -1920,7 +1920,7 @@ def classical_decomposition(self): The crystal of tableaux of type ['B', 3] and shape(s) [[], [1], [2], [1, 1], [3], [2, 1], [3, 1], [2, 2], [3, 2], [3, 3]] """ return CrystalOfTableaux(self.cartan_type().classical(), - shapes = partitions_in_box(self.r(),self.s())) + shapes=partitions_in_box(self.r(),self.s())) def ambient_crystal(self): r""" @@ -2443,7 +2443,7 @@ def classical_decomposition(self): sage: K.classical_decomposition() The crystal of tableaux of type ['C', 3] and shape(s) [[2, 2, 2]] """ - return CrystalOfTableaux(self.cartan_type().classical(), shape = [self.s()]*self.r() ) + return CrystalOfTableaux(self.cartan_type().classical(), shape=[self.s()]*self.r() ) def from_highest_weight_vector_to_pm_diagram(self, b): r""" @@ -2678,7 +2678,7 @@ def classical_decomposition(self): s = s // 2 else: s = s / 2 - return CrystalOfTableaux(self.cartan_type().classical(), shape = [s]*self.r() ) + return CrystalOfTableaux(self.cartan_type().classical(), shape=[s]*self.r() ) def from_highest_weight_vector_to_pm_diagram(self, b): r""" @@ -3733,7 +3733,7 @@ class PMDiagram(CombinatorialObject): True """ - def __init__(self, pm_diagram, from_shapes = None): + def __init__(self, pm_diagram, from_shapes=None): r""" Initialize ``self``. diff --git a/src/sage/combinat/crystals/littelmann_path.py b/src/sage/combinat/crystals/littelmann_path.py index 7bb0a67ed08..1af0fed2dcb 100644 --- a/src/sage/combinat/crystals/littelmann_path.py +++ b/src/sage/combinat/crystals/littelmann_path.py @@ -121,7 +121,7 @@ class CrystalOfLSPaths(UniqueRepresentation, Parent): """ @staticmethod - def __classcall_private__(cls, starting_weight, cartan_type = None, starting_weight_parent = None): + def __classcall_private__(cls, starting_weight, cartan_type=None, starting_weight_parent=None): """ Classcall to mend the input. @@ -150,7 +150,7 @@ def __classcall_private__(cls, starting_weight, cartan_type = None, starting_wei extended = cartan_type.is_affine() R = RootSystem(cartan_type) - P = R.weight_space(extended = extended) + P = R.weight_space(extended=extended) Lambda = P.basis() offset = R.index_set()[Integer(0)] starting_weight = P.sum(starting_weight[j-offset]*Lambda[j] for j in R.index_set()) @@ -162,7 +162,7 @@ def __classcall_private__(cls, starting_weight, cartan_type = None, starting_wei if starting_weight.parent() != starting_weight_parent: raise ValueError("The passed parent is not equal to parent of the inputted weight!") - return super().__classcall__(cls, starting_weight, starting_weight_parent = starting_weight_parent) + return super().__classcall__(cls, starting_weight, starting_weight_parent=starting_weight_parent) def __init__(self, starting_weight, starting_weight_parent): """ @@ -808,7 +808,7 @@ def weight(x): w = x.weight() return P0.sum(int(c)*P0.basis()[i] for i,c in w if i in P0.index_set()) if group_components: - G = self.digraph(index_set = self.cartan_type().classical().index_set()) + G = self.digraph(index_set=self.cartan_type().classical().index_set()) C = G.connected_components() return sum(q**(c[0].energy_function())*B.sum(B(weight(b)) for b in c) for c in C) return B.sum(q**(b.energy_function())*B(weight(b)) for b in self) diff --git a/src/sage/combinat/crystals/tensor_product.py b/src/sage/combinat/crystals/tensor_product.py index fe90ccc0d9d..0318f6528ae 100644 --- a/src/sage/combinat/crystals/tensor_product.py +++ b/src/sage/combinat/crystals/tensor_product.py @@ -493,7 +493,7 @@ def __init__(self, crystals, generators, cartan_type): assert isinstance(crystals, tuple) assert isinstance(generators, tuple) category = Category.meet([crystal.category() for crystal in crystals]) - Parent.__init__(self, category = category) + Parent.__init__(self, category=category) self.crystals = crystals self._cartan_type = cartan_type self.module_generators = tuple([self(*x) for x in generators]) @@ -891,7 +891,7 @@ class CrystalOfTableaux(CrystalOfWords): """ @staticmethod - def __classcall_private__(cls, cartan_type, shapes = None, shape = None): + def __classcall_private__(cls, cartan_type, shapes=None, shape=None): """ Normalizes the input arguments to ensure unique representation, and to delegate the construction of spin tableaux. @@ -991,7 +991,7 @@ def __init__(self, cartan_type, shapes): sage: TestSuite(T).run() """ # super().__init__(category = FiniteEnumeratedSets()) - Parent.__init__(self, category = ClassicalCrystals()) + Parent.__init__(self, category=ClassicalCrystals()) self.letters = CrystalOfLetters(cartan_type) self.shapes = shapes self.module_generators = tuple(self.module_generator(la) for la in shapes) diff --git a/src/sage/combinat/designs/bibd.py b/src/sage/combinat/designs/bibd.py index 2265e113040..59d9ad6bad3 100644 --- a/src/sage/combinat/designs/bibd.py +++ b/src/sage/combinat/designs/bibd.py @@ -1036,7 +1036,7 @@ def _PBD_4_5_8_9_12_closure(B): BB = [] for X in B: if len(X) not in [4,5,8,9,12]: - PBD = PBD_4_5_8_9_12(len(X), check = False) + PBD = PBD_4_5_8_9_12(len(X), check=False) X = [[X[i] for i in XX] for XX in PBD] BB.extend(X) else: diff --git a/src/sage/combinat/designs/database.py b/src/sage/combinat/designs/database.py index 57060962e69..53fd144746f 100644 --- a/src/sage/combinat/designs/database.py +++ b/src/sage/combinat/designs/database.py @@ -5008,13 +5008,13 @@ def BIBD_56_11_2(): for k in sorted(EDS)) __doc__ = __doc__.format( - LIST_OF_OA_CONSTRUCTIONS = LIST_OF_OA_CONSTRUCTIONS, - LIST_OF_MOLS_CONSTRUCTIONS = LIST_OF_MOLS_CONSTRUCTIONS, - LIST_OF_VMT_VECTORS = LIST_OF_VMT_VECTORS, - LIST_OF_BIBD = LIST_OF_BIBD, - LIST_OF_DF = LIST_OF_DF, - LIST_OF_DM = LIST_OF_DM, - LIST_OF_QDM = LIST_OF_QDM, - LIST_OF_EDS = LIST_OF_EDS) + LIST_OF_OA_CONSTRUCTIONS=LIST_OF_OA_CONSTRUCTIONS, + LIST_OF_MOLS_CONSTRUCTIONS=LIST_OF_MOLS_CONSTRUCTIONS, + LIST_OF_VMT_VECTORS=LIST_OF_VMT_VECTORS, + LIST_OF_BIBD=LIST_OF_BIBD, + LIST_OF_DF=LIST_OF_DF, + LIST_OF_DM=LIST_OF_DM, + LIST_OF_QDM=LIST_OF_QDM, + LIST_OF_EDS=LIST_OF_EDS) del LIST_OF_OA_CONSTRUCTIONS, LIST_OF_MOLS_CONSTRUCTIONS, LIST_OF_VMT_VECTORS,LIST_OF_DF, LIST_OF_DM, LIST_OF_QDM, LIST_OF_EDS, LIST_OF_BIBD del PolynomialRing, ZZ, a, diff --git a/src/sage/combinat/designs/group_divisible_designs.py b/src/sage/combinat/designs/group_divisible_designs.py index 74425c5516f..738cec0222c 100644 --- a/src/sage/combinat/designs/group_divisible_designs.py +++ b/src/sage/combinat/designs/group_divisible_designs.py @@ -122,12 +122,12 @@ def group_divisible_design(v,K,G,existence=False,check=False): if blocks: return GroupDivisibleDesign(v, - groups = groups, - blocks = blocks, - G = G, - K = K, - check = check, - copy = True) + groups=groups, + blocks=blocks, + G=G, + K=K, + check=check, + copy=True) if existence: return Unknown @@ -193,12 +193,12 @@ def GDD_4_2(q,existence=False,check=True): for g in G for j in range(2)] return GroupDivisibleDesign(2*q, - groups = [[i,i+1] for i in range(0,2*q,2)], - blocks = sum(classes,[]), - K = [4], - G = [2], - check = check, - copy = False) + groups=[[i,i+1] for i in range(0,2*q,2)], + blocks=sum(classes,[]), + K=[4], + G=[2], + check=check, + copy=False) class GroupDivisibleDesign(IncidenceStructure): r""" diff --git a/src/sage/combinat/designs/incidence_structures.py b/src/sage/combinat/designs/incidence_structures.py index 1aa6c34d733..c1b0f8c85ec 100644 --- a/src/sage/combinat/designs/incidence_structures.py +++ b/src/sage/combinat/designs/incidence_structures.py @@ -2172,7 +2172,7 @@ def _spring_layout(self): for x in s: g.add_edge((0, s), (1, x)) - _ = g.plot(iterations = 50000,save_pos=True) + _ = g.plot(iterations=50000,save_pos=True) # The values are rounded as TikZ does not like accuracy. return {k[1]: (round(x, 3), round(y, 3)) @@ -2257,7 +2257,7 @@ def _latex_(self): # "center", i.e. the vertex representing the set s cx, cy = pos[Set(s)] s = [pos[_] for _ in s] - s = sorted(s, key = lambda x_y: arctan2(x_y[0] - cx, x_y[1] - cy)) + s = sorted(s, key=lambda x_y: arctan2(x_y[0] - cx, x_y[1] - cy)) for x in s: tex += str(x)+" " diff --git a/src/sage/combinat/designs/orthogonal_arrays.py b/src/sage/combinat/designs/orthogonal_arrays.py index 2fb4d7ecde8..094a8118245 100644 --- a/src/sage/combinat/designs/orthogonal_arrays.py +++ b/src/sage/combinat/designs/orthogonal_arrays.py @@ -360,7 +360,7 @@ def transversal_design(k, n, resolvable=False, check=True, existence=False): return False raise EmptySetError("There exists no TD({},{})!".format(k,n)) - OA = orthogonal_array(k,n, check = False) + OA = orthogonal_array(k,n, check=False) TD = [[i*n+c for i,c in enumerate(l)] for l in OA] else: @@ -1843,7 +1843,7 @@ def OA_from_Vmt(m,t,V): sage: _ = designs.orthogonal_arrays.build(6,46) # indirect doctest """ Fq, M = QDM_from_Vmt(m,t,V) - return OA_from_quasi_difference_matrix(M,Fq,add_col = False) + return OA_from_quasi_difference_matrix(M,Fq,add_col=False) def QDM_from_Vmt(m,t,V): diff --git a/src/sage/combinat/designs/resolvable_bibd.py b/src/sage/combinat/designs/resolvable_bibd.py index e9b90579bc2..623b10be3d2 100644 --- a/src/sage/combinat/designs/resolvable_bibd.py +++ b/src/sage/combinat/designs/resolvable_bibd.py @@ -125,7 +125,7 @@ def resolvable_balanced_incomplete_block_design(v,k,existence=False): B = BalancedIncompleteBlockDesign(v, sum(classes,[]), - k = k, + k=k, check=True, copy=False) B._classes = classes @@ -355,7 +355,7 @@ def kirkman_triple_system(v,existence=False): classs.append([2*i,2*i+1,v-1]) KTS = BalancedIncompleteBlockDesign(v, - blocks = [tr for cl in classes for tr in cl], + blocks=[tr for cl in classes for tr in cl], k=3, lambd=1, check=True, @@ -428,7 +428,7 @@ def v_4_1_rbibd(v,existence=False): for g in G] BIBD = BalancedIncompleteBlockDesign(v, - blocks = sum(classes,[]), + blocks=sum(classes,[]), k=4, check=True, copy=False) @@ -603,8 +603,8 @@ def PBD_4_7(v,check=True, existence=False): S_4_5_7 = [X.intersection(S) for S in AF] S_4_5_7 = [S for S in S_4_5_7 if len(S)>1] S_4_5_7 = PairwiseBalancedDesign(X, - blocks = S_4_5_7, - K = [4,5,7], + blocks=S_4_5_7, + K=[4,5,7], check=False) S_4_5_7.relabel() return PBD_4_7_from_Y(S_4_5_7,check=check) @@ -626,11 +626,11 @@ def PBD_4_7(v,check=True, existence=False): groups = [[x] for x in range(40)] groups.append(list(range(40,40+points_to_add))) GDD = GroupDivisibleDesign(40+points_to_add, - groups = groups, - blocks = GDD, - K = [2,4,5,7], - check = False, - copy = False) + groups=groups, + blocks=GDD, + K=[2,4,5,7], + check=False, + copy=False) return PBD_4_7_from_Y(GDD,check=check) @@ -669,18 +669,18 @@ def PBD_4_7(v,check=True, existence=False): domain = set(range(vv)) GDD = transversal_design(5,g) GDD = GroupDivisibleDesign(vv, - groups = [[x for x in gr if x in domain] for gr in GDD.groups()], - blocks = [[x for x in B if x in domain] for B in GDD], - G = set([g,u]), - K = [4,5], + groups=[[x for x in gr if x in domain] for gr in GDD.groups()], + blocks=[[x for x in B if x in domain] for B in GDD], + G=set([g,u]), + K=[4,5], check=False) return PBD_4_7_from_Y(GDD,check=check) return PairwiseBalancedDesign(v, - blocks = blocks, - K = [4,7], - check = check, - copy = False) + blocks=blocks, + K=[4,7], + check=check, + copy=False) def PBD_4_7_from_Y(gdd,check=True): r""" @@ -771,7 +771,7 @@ def PBD_4_7_from_Y(gdd,check=True): for x in B]) return PairwiseBalancedDesign(3*gdd.num_points()+1, - blocks = PBD, - K = [4,7], - check = check, - copy = False) + blocks=PBD, + K=[4,7], + check=check, + copy=False) diff --git a/src/sage/combinat/designs/steiner_quadruple_systems.py b/src/sage/combinat/designs/steiner_quadruple_systems.py index 0f21f3138bd..8a7ede7af6d 100644 --- a/src/sage/combinat/designs/steiner_quadruple_systems.py +++ b/src/sage/combinat/designs/steiner_quadruple_systems.py @@ -677,7 +677,7 @@ def barP_system(m): return pairs @cached_function -def steiner_quadruple_system(n, check = False): +def steiner_quadruple_system(n, check=False): r""" Return a Steiner Quadruple System on `n` points. @@ -712,29 +712,29 @@ def steiner_quadruple_system(n, check = False): if not ((n%6) in [2, 4]): raise ValueError("n mod 6 must be equal to 2 or 4") elif n == 4: - sqs = IncidenceStructure(4, [[0,1,2,3]], copy = False, check = False) + sqs = IncidenceStructure(4, [[0,1,2,3]], copy=False, check=False) elif n == 14: - sqs = IncidenceStructure(14, _SQS14(), copy = False, check = False) + sqs = IncidenceStructure(14, _SQS14(), copy=False, check=False) elif n == 38: - sqs = IncidenceStructure(38, _SQS38(), copy = False, check = False) + sqs = IncidenceStructure(38, _SQS38(), copy=False, check=False) elif n%12 in [4, 8]: nn = n // 2 - sqs = two_n(steiner_quadruple_system(nn, check = False)) + sqs = two_n(steiner_quadruple_system(nn, check=False)) elif n%18 in [4,10]: nn = (n+2) // 3 - sqs = three_n_minus_two(steiner_quadruple_system(nn, check = False)) + sqs = three_n_minus_two(steiner_quadruple_system(nn, check=False)) elif (n%36) == 34: nn = (n+8) // 3 - sqs = three_n_minus_eight(steiner_quadruple_system(nn, check = False)) + sqs = three_n_minus_eight(steiner_quadruple_system(nn, check=False)) elif (n%36) == 26: nn = (n+4) // 3 - sqs = three_n_minus_four(steiner_quadruple_system(nn, check = False)) + sqs = three_n_minus_four(steiner_quadruple_system(nn, check=False)) elif n%24 in [2, 10]: nn = (n+6) // 4 - sqs = four_n_minus_six(steiner_quadruple_system(nn, check = False)) + sqs = four_n_minus_six(steiner_quadruple_system(nn, check=False)) elif n%72 in [14, 38]: nn = (n+10) // 12 - sqs = twelve_n_minus_ten(steiner_quadruple_system(nn, check = False)) + sqs = twelve_n_minus_ten(steiner_quadruple_system(nn, check=False)) else: raise ValueError("this should never happen") diff --git a/src/sage/combinat/fully_packed_loop.py b/src/sage/combinat/fully_packed_loop.py index 070275077cd..149385ca643 100644 --- a/src/sage/combinat/fully_packed_loop.py +++ b/src/sage/combinat/fully_packed_loop.py @@ -881,9 +881,9 @@ def plot(self, **options): squares = set((i,j) for i in range(n) for j in range(n)) colors = _make_color_list(2*n, - colors = link_options.pop('colors', None), - color_map = link_options.pop('color_map', None), - randomize = link_options.pop('color_randomize', False)) + colors=link_options.pop('colors', None), + color_map=link_options.pop('color_map', None), + randomize=link_options.pop('color_randomize', False)) G = Graphics() for i in range(2*n): @@ -910,9 +910,9 @@ def plot(self, **options): if loop: colors = _make_color_list(len(loops), - colors = loop_options.pop('colors', None), - color_map = loop_options.pop('color_map', None), - randomize = loop_options.pop('color_randomize', False)) + colors=loop_options.pop('colors', None), + color_map=loop_options.pop('color_map', None), + randomize=loop_options.pop('color_randomize', False)) fill = loop_options.pop('fill') diff --git a/src/sage/combinat/growth.py b/src/sage/combinat/growth.py index 763f8f7e482..8a38d0cb9ba 100644 --- a/src/sage/combinat/growth.py +++ b/src/sage/combinat/growth.py @@ -2608,7 +2608,7 @@ def forward_rule(self, y, e, t, f, x, content): # the addable cell with largest content at most e cprime = sorted([c for c in y.to_partition().addable_cells() if c[1]-c[0] <= e], - key = lambda c: -(c[1]-c[0]))[0] + key=lambda c: -(c[1]-c[0]))[0] h = cprime[1] - cprime[0] z = y.affine_symmetric_group_simple_action(h % self.k) diff --git a/src/sage/combinat/integer_vector.py b/src/sage/combinat/integer_vector.py index 9f01bfd787d..e12e6cc27cd 100644 --- a/src/sage/combinat/integer_vector.py +++ b/src/sage/combinat/integer_vector.py @@ -363,7 +363,7 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", from sage.numerical.mip import MixedIntegerLinearProgram k1, k2=len(p1), len(p2) p = MixedIntegerLinearProgram(solver=solver) - b = p.new_variable(binary = True) + b = p.new_variable(binary=True) for (i,c) in enumerate(p1): p.add_constraint(p.sum([b[i,j] for j in range(k2)]) ==c) for (i,c) in enumerate(p2): diff --git a/src/sage/combinat/integer_vector_weighted.py b/src/sage/combinat/integer_vector_weighted.py index 1b110c34140..7fa72fb60fd 100644 --- a/src/sage/combinat/integer_vector_weighted.py +++ b/src/sage/combinat/integer_vector_weighted.py @@ -319,7 +319,7 @@ def __contains__(self, x): and len(x) == len(self._weights) and all(i in ZZ and i >= 0 for i in x)) - def subset(self, size = None): + def subset(self, size=None): """ EXAMPLES:: diff --git a/src/sage/combinat/integer_vectors_mod_permgroup.py b/src/sage/combinat/integer_vectors_mod_permgroup.py index 539fc59b9c0..d3ea07b7d78 100644 --- a/src/sage/combinat/integer_vectors_mod_permgroup.py +++ b/src/sage/combinat/integer_vectors_mod_permgroup.py @@ -278,7 +278,7 @@ def __init__(self, G, sgs=None): Category of infinite enumerated quotients of sets sage: TestSuite(I).run() """ - RecursivelyEnumeratedSet_forest.__init__(self, algorithm = 'breadth', category = InfiniteEnumeratedSets().Quotients()) + RecursivelyEnumeratedSet_forest.__init__(self, algorithm='breadth', category=InfiniteEnumeratedSets().Quotients()) self._permgroup = G self.n = G.degree() @@ -602,7 +602,7 @@ def __init__(self, G, d, max_part, sgs=None): sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]), 6, max_part=4) """ - RecursivelyEnumeratedSet_forest.__init__(self, algorithm = 'breadth', category = (FiniteEnumeratedSets(), FiniteEnumeratedSets().Quotients())) + RecursivelyEnumeratedSet_forest.__init__(self, algorithm='breadth', category=(FiniteEnumeratedSets(), FiniteEnumeratedSets().Quotients())) self._permgroup = G self.n = G.degree() self._sum = d @@ -757,7 +757,7 @@ def __iter__(self): else: SF = RecursivelyEnumeratedSet_forest((self([0]*(self.n), check=False),), lambda x : [self(y, check=False) for y in canonical_children(self._sgs, x, self._max_part)], - algorithm = 'breadth') + algorithm='breadth') if self._sum is None: return iter(SF) else: diff --git a/src/sage/combinat/interval_posets.py b/src/sage/combinat/interval_posets.py index a2d4f6e607c..3466a57f255 100644 --- a/src/sage/combinat/interval_posets.py +++ b/src/sage/combinat/interval_posets.py @@ -2146,31 +2146,26 @@ def add_relations(poset, n, m): if poset.le(n, m): # there is already a link n->m, so we go to the next n - for pos in add_relations(poset, n - 1, m): - yield pos + yield from add_relations(poset, n - 1, m) elif poset.le(m, n): # there is an inverse link m->n, we know we won't be able # to create a link i->m with i<=n, so we go to the next m - for pos in add_relations(poset, m, m + 1): - yield pos + yield from add_relations(poset, m, m + 1) else: # there is no link n->m # first option : we don't create the link and go to the next m # (since the lack of a link n->m forbids any links i->m # with im already exist for all # n Integer: r""" diff --git a/src/sage/combinat/k_tableau.py b/src/sage/combinat/k_tableau.py index 5fb1d56b82c..d5dd17d20b2 100644 --- a/src/sage/combinat/k_tableau.py +++ b/src/sage/combinat/k_tableau.py @@ -48,7 +48,7 @@ import copy -def WeakTableau(t, k, inner_shape = [], representation = "core"): +def WeakTableau(t, k, inner_shape=[], representation="core"): r""" This is the dispatcher method for the element class of weak `k`-tableaux. @@ -188,12 +188,12 @@ def WeakTableau(t, k, inner_shape = [], representation = "core"): elif representation == "bounded": return WeakTableau_bounded(t, k) elif representation == "factorized_permutation": - return WeakTableau_factorized_permutation(t, k, inner_shape = inner_shape) + return WeakTableau_factorized_permutation(t, k, inner_shape=inner_shape) else: raise NotImplementedError("The representation option needs to be 'core', 'bounded', or 'factorized_permutation'") -def WeakTableaux(k, shape , weight, representation = "core"): +def WeakTableaux(k, shape , weight, representation="core"): r""" This is the dispatcher method for the parent class of weak `k`-tableaux. @@ -477,7 +477,7 @@ def chi(x): else: return "["+"".join(self[i]._latex_()+',' for i in range(len(self)-1))+self[len(self)-1]._latex_()+"]" - def representation(self, representation = 'core'): + def representation(self, representation='core'): r""" Return the analogue of ``self`` in the specified representation. @@ -605,7 +605,7 @@ def size(self): else: return self._outer_shape.length() - self._inner_shape.length() - def representation(self, representation = 'core'): + def representation(self, representation='core'): r""" Return the analogue of ``self`` in the specified representation. @@ -656,7 +656,7 @@ def representation(self, representation = 'core'): if self._representation == 'bounded' and (representation in ['core', 'factorized_permutation']): outer_shape = outer_shape.to_core(self.k) inner_shape = inner_shape.to_core(self.k) - return WeakTableaux(self.k, [outer_shape, inner_shape], weight, representation = representation) + return WeakTableaux(self.k, [outer_shape, inner_shape], weight, representation=representation) #Weak Tableaux in terms of cores @@ -898,7 +898,7 @@ def to_factorized_permutation_tableau(self): """ shapes = [ Core(p,self.k+1).to_grassmannian() for p in self.intermediate_shapes() ] perms = [ shapes[i]*(shapes[i-1].inverse()) for i in range(len(shapes)-1,0,-1)] - return WeakTableau_factorized_permutation(perms, self.k, inner_shape = self.parent()._inner_shape) + return WeakTableau_factorized_permutation(perms, self.k, inner_shape=self.parent()._inner_shape) def residues_of_entries(self, v): r""" @@ -1033,7 +1033,7 @@ def list_of_standard_cells(self): out.append(standard_cells) return out - def k_charge(self, algorithm = "I"): + def k_charge(self, algorithm="I"): r""" Return the `k`-charge of ``self``. @@ -1289,7 +1289,7 @@ def __init__(self, k, shape, weight): self._shape = (self._outer_shape, self._inner_shape) self._weight = weight self._representation = 'core' - Parent.__init__(self, category = FiniteEnumeratedSets()) + Parent.__init__(self, category=FiniteEnumeratedSets()) def _repr_(self): """ @@ -1653,7 +1653,7 @@ def from_core_tableau(cls, t, k): l = l_new return cls(l, k) - def k_charge(self, algorithm = 'I'): + def k_charge(self, algorithm='I'): r""" Return the `k`-charge of ``self``. @@ -1680,7 +1680,7 @@ def k_charge(self, algorithm = 'I'): sage: t.k_charge() 12 """ - return self.to_core_tableau().k_charge(algorithm = algorithm) + return self.to_core_tableau().k_charge(algorithm=algorithm) class WeakTableaux_bounded(WeakTableaux_abstract): @@ -1755,7 +1755,7 @@ def __init__(self, k, shape, weight): self._shape = (self._outer_shape, self._inner_shape) self._weight = tuple(weight) self._representation = 'bounded' - Parent.__init__(self, category = FiniteEnumeratedSets()) + Parent.__init__(self, category=FiniteEnumeratedSets()) def _repr_(self): """ @@ -1837,7 +1837,7 @@ def straighten_input(t, k): return w_tuple @staticmethod - def __classcall_private__(cls, t, k, inner_shape = []): + def __classcall_private__(cls, t, k, inner_shape=[]): r""" Implements the shortcut ``WeakTableau_factorized_permutation(t, k)`` to ``WeakTableaux_factorized_permutation(k, shape, weight)(t)`` @@ -2085,9 +2085,9 @@ def from_core_tableau(cls, t, k): t = SkewTableau(list(t)) shapes = [ Core(p, k+1).to_grassmannian() for p in intermediate_shapes(t) ] #t.to_chain() ] perms = [ shapes[i]*(shapes[i-1].inverse()) for i in range(len(shapes)-1,0,-1)] - return cls(perms, k, inner_shape = t.inner_shape()) + return cls(perms, k, inner_shape=t.inner_shape()) - def k_charge(self, algorithm = 'I'): + def k_charge(self, algorithm='I'): r""" Return the `k`-charge of ``self``. @@ -2107,7 +2107,7 @@ def k_charge(self, algorithm = 'I'): sage: t.k_charge() 12 """ - return self.to_core_tableau().k_charge(algorithm = algorithm) + return self.to_core_tableau().k_charge(algorithm=algorithm) class WeakTableaux_factorized_permutation(WeakTableaux_abstract): @@ -2178,7 +2178,7 @@ def __init__(self, k, shape, weight): self._shape = (self._outer_shape, self._inner_shape) self._weight = weight self._representation = 'factorized_permutation' - Parent.__init__(self, category = FiniteEnumeratedSets()) + Parent.__init__(self, category=FiniteEnumeratedSets()) def _repr_(self): """ @@ -3945,7 +3945,7 @@ def __init__( self, k, shape, weight ): self._weight = (1,)*(self._outer_shape.length()-self._inner_shape.length()) else: self._weight = weight - Parent.__init__(self, category = FiniteEnumeratedSets()) + Parent.__init__(self, category=FiniteEnumeratedSets()) @staticmethod def __classcall_private__(cls, k, shape, weight=None): @@ -4591,7 +4591,7 @@ def transpositions_to_standard_strong( self, transeq, k, emptyTableau=[] ): out = copy.deepcopy(emptyTableau) for i in range(1,len(transeq)+1): out = StrongTableaux._left_action_list(out, transeq[-i], i, k) - return StrongTableau(out, k, weight = (1,)*len(transeq)) + return StrongTableau(out, k, weight=(1,)*len(transeq)) Element = StrongTableau diff --git a/src/sage/combinat/ncsf_qsym/combinatorics.py b/src/sage/combinat/ncsf_qsym/combinatorics.py index cddfdc1ef2c..cba0de3d45b 100644 --- a/src/sage/combinat/ncsf_qsym/combinatorics.py +++ b/src/sage/combinat/ncsf_qsym/combinatorics.py @@ -255,7 +255,7 @@ def number_of_fCT(content_comp, shape_comp): return 1 else: return 0 - C = Compositions(content_comp.size()-content_comp[-1], outer = list(shape_comp)) + C = Compositions(content_comp.size()-content_comp[-1], outer=list(shape_comp)) s = 0 for x in C: if len(x) >= len(shape_comp)-1: diff --git a/src/sage/combinat/ncsf_qsym/generic_basis_code.py b/src/sage/combinat/ncsf_qsym/generic_basis_code.py index 0f2b819457f..012f8bd7ce1 100644 --- a/src/sage/combinat/ncsf_qsym/generic_basis_code.py +++ b/src/sage/combinat/ncsf_qsym/generic_basis_code.py @@ -234,7 +234,7 @@ def alternating_sum_of_compositions(self, n): return (-ring.one())**(n)*self.sum_of_terms( (compo, ring((-1)**(len(compo)))) for compo in Compositions(n) ) - def alternating_sum_of_finer_compositions(self, composition, conjugate = False): + def alternating_sum_of_finer_compositions(self, composition, conjugate=False): """ Return the alternating sum of finer compositions in a basis of the non-commutative symmetric functions. @@ -996,7 +996,7 @@ class AlgebraMorphism(ModuleMorphismByLinearity): # Find a better name A class for algebra morphism defined on a free algebra from the image of the generators """ - def __init__(self, domain, on_generators, position = 0, codomain = None, category = None, anti = False): + def __init__(self, domain, on_generators, position=0, codomain=None, category=None, anti=False): """ Given a map on the multiplicative basis of a free algebra, this method returns the algebra morphism that is the linear extension of its image diff --git a/src/sage/combinat/ncsf_qsym/ncsf.py b/src/sage/combinat/ncsf_qsym/ncsf.py index a17d14b33d9..f9aafb014aa 100644 --- a/src/sage/combinat/ncsf_qsym/ncsf.py +++ b/src/sage/combinat/ncsf_qsym/ncsf.py @@ -2208,7 +2208,7 @@ def to_symmetric_function(self): h[1, 1, 1, 1] - 3*h[2, 1, 1] + 3*h[3, 1] """ codom = self.to_symmetric_function_on_generators(1).parent() - return self.algebra_morphism(self.to_symmetric_function_on_generators, codomain = codom) + return self.algebra_morphism(self.to_symmetric_function_on_generators, codomain=codom) @lazy_attribute def antipode(self): @@ -2232,7 +2232,7 @@ def antipode(self): Generic endomorphism of Non-Commutative Symmetric Functions over the Rational Field in the Complete basis """ if hasattr(self, "antipode_on_generators"): - return self.algebra_morphism(self.antipode_on_generators, codomain = self, anti = True) + return self.algebra_morphism(self.antipode_on_generators, codomain=self, anti=True) else: return NotImplemented @@ -2256,7 +2256,7 @@ def coproduct(self): """ from sage.categories.tensor import tensor if hasattr(self, "coproduct_on_generators"): - return self.algebra_morphism(self.coproduct_on_generators, codomain = tensor([self, self])) + return self.algebra_morphism(self.coproduct_on_generators, codomain=tensor([self, self])) else: return NotImplemented @@ -4521,15 +4521,15 @@ def __init__(self, NCSF): S = NCSF.complete() Psi = NCSF.Psi() to_S = self.module_morphism( - on_basis = self._to_complete_on_basis, - codomain = S, - category = category) + on_basis=self._to_complete_on_basis, + codomain=S, + category=category) to_S.register_as_coercion() from_psi = Psi.module_morphism( - on_basis = self._from_psi_on_basis, - codomain = self, - category = category) + on_basis=self._from_psi_on_basis, + codomain=self, + category=category) from_psi.register_as_coercion() def _to_complete_on_basis(self, I): @@ -4680,15 +4680,15 @@ def __init__(self, NCSF): category = self.category() S = self.realization_of().complete() to_S = self.module_morphism( - on_basis = self._to_complete_on_basis, - codomain = S, - category = category) + on_basis=self._to_complete_on_basis, + codomain=S, + category=category) to_S.register_as_coercion() from_S = S.module_morphism( - on_basis = self._from_complete_on_basis, - codomain = self, - category = category) + on_basis=self._from_complete_on_basis, + codomain=self, + category=category) from_S.register_as_coercion() def _realization_name(self): @@ -4968,15 +4968,15 @@ def __init__(self, NCSF): category = self.category() self._S = self.realization_of().complete() to_S = self.module_morphism( - on_basis = self._to_complete_on_basis, - codomain = self._S, - category = category) + on_basis=self._to_complete_on_basis, + codomain=self._S, + category=category) to_S.register_as_coercion() from_S = self._S.module_morphism( - on_basis = self._from_complete_on_basis, - codomain = self, - category = category) + on_basis=self._from_complete_on_basis, + codomain=self, + category=category) from_S.register_as_coercion() def _realization_name(self): diff --git a/src/sage/combinat/ncsf_qsym/qsym.py b/src/sage/combinat/ncsf_qsym/qsym.py index 9169e38e1d1..fe4e58277b1 100644 --- a/src/sage/combinat/ncsf_qsym/qsym.py +++ b/src/sage/combinat/ncsf_qsym/qsym.py @@ -561,7 +561,7 @@ def __init__(self, R): self._base = R # Won't be needed once CategoryObject won't override base_ring category = GradedHopfAlgebras(R).Commutative() self._category = category - Parent.__init__(self, category = category.WithRealizations()) + Parent.__init__(self, category=category.WithRealizations()) # Bases Monomial = self.Monomial() @@ -578,11 +578,11 @@ def __init__(self, R): ).register_as_coercion() #This changes dualImmaculate into Monomial dualImmaculate.module_morphism(dualImmaculate._to_Monomial_on_basis, - codomain = Monomial, category = category + codomain=Monomial, category=category ).register_as_coercion() #This changes Monomial into dualImmaculate Monomial.module_morphism(dualImmaculate._from_Monomial_on_basis, - codomain = dualImmaculate, category = category + codomain=dualImmaculate, category=category ).register_as_coercion() #This changes Quasisymmetric Schur into Monomial QS .module_morphism(QS._to_monomial_on_basis, @@ -1922,7 +1922,7 @@ def lambda_of_monomial(self, I, n): QQ_result *= (-1) ** n # QQ_result is now \lambda^n(M_I) over QQ. result = self.sum_of_terms([(J, ZZ(coeff)) for (J, coeff) in QQ_result], - distinct = True) + distinct=True) return result class Element(CombinatorialFreeModule.Element): @@ -2052,7 +2052,7 @@ def on_basis(comp, i): return x[i-1]**comp[-1] * on_basis(comp[:-1], i-1) + \ on_basis(comp, i-1) return M._apply_module_morphism(self, lambda comp: on_basis(comp,n), - codomain = P) + codomain=P) def is_symmetric( self ): r""" @@ -3380,11 +3380,11 @@ def __init_extra__(self): category = self.realization_of()._category # This changes Monomial into Hazewinkel Lambda M.module_morphism(self._from_Monomial_on_basis, - codomain = self, category = category + codomain=self, category=category ).register_as_coercion() # This changes Hazewinkel Lambda into Monomial self.module_morphism(self._to_Monomial_on_basis, - codomain = M, category = category + codomain=M, category=category ).register_as_coercion() # cache for the coordinates of the elements diff --git a/src/sage/combinat/ncsym/ncsym.py b/src/sage/combinat/ncsym/ncsym.py index 551ca834b1d..64772ade2d7 100644 --- a/src/sage/combinat/ncsym/ncsym.py +++ b/src/sage/combinat/ncsym/ncsym.py @@ -297,7 +297,7 @@ def __init__(self, R): assert(R in Fields() or R in Rings()) # side effect of this statement assures MRO exists for R self._base = R # Won't be needed once CategoryObject won't override base_ring category = GradedHopfAlgebras(R) # TODO: .Cocommutative() - Parent.__init__(self, category = category.WithRealizations()) + Parent.__init__(self, category=category.WithRealizations()) def _repr_(self): r""" diff --git a/src/sage/combinat/necklace.py b/src/sage/combinat/necklace.py index bcfb0d45185..32d345c7e11 100644 --- a/src/sage/combinat/necklace.py +++ b/src/sage/combinat/necklace.py @@ -295,8 +295,7 @@ def _ffc(content, equality=False): if not e[0]: # == 0 dll.hide(0) - for x in _fast_fixed_content(a, e, 2, 1, k, r, 2, dll, equality=equality): - yield x + yield from _fast_fixed_content(a, e, 2, 1, k, r, 2, dll, equality=equality) def _fast_fixed_content(a, content, t, p, k, r, s, dll, equality=False): @@ -347,13 +346,13 @@ def _fast_fixed_content(a, content, t, p, k, r, s, dll, equality=False): sp = t + 1 if j == a[t - p - 1]: - for x in _fast_fixed_content(a[:], content, t + 1, p, - k, r, sp, dll, equality=equality): - yield x + yield from _fast_fixed_content(a[:], content, t + 1, p, + k, r, sp, dll, + equality=equality) else: - for x in _fast_fixed_content(a[:], content, t + 1, t, - k, r, sp, dll, equality=equality): - yield x + yield from _fast_fixed_content(a[:], content, t + 1, t, + k, r, sp, dll, + equality=equality) if not content[j]: # == 0 dll.unhide(j) @@ -392,8 +391,7 @@ def _lfc(content, equality=False): if not content[0]: # == 0 dll.hide(0) - for z in _list_fixed_content(a, content, 2, 1, k, dll, equality=equality): - yield z + yield from _list_fixed_content(a, content, 2, 1, k, dll, equality=equality) def _list_fixed_content(a, content, t, p, k, dll, equality=False): @@ -434,13 +432,11 @@ def _list_fixed_content(a, content, t, p, k, dll, equality=False): dll.hide(j) if j == a[t - p - 1]: - for z in _list_fixed_content(a[:], content[:], t + 1, p, - k, dll, equality=equality): - yield z + yield from _list_fixed_content(a[:], content[:], t + 1, p, + k, dll, equality=equality) else: - for z in _list_fixed_content(a[:], content[:], t + 1, t, - k, dll, equality=equality): - yield z + yield from _list_fixed_content(a[:], content[:], t + 1, t, + k, dll, equality=equality) if not content[j]: # == 0 dll.unhide(j) @@ -519,13 +515,11 @@ def _simple_fixed_content(a, content, t, p, k, equality=False): a[t - 1] = j content[j] -= 1 if j == a[t - p - 1]: - for z in _simple_fixed_content(a[:], content, t + 1, p, - k, equality=equality): - yield z + yield from _simple_fixed_content(a[:], content, t + 1, p, + k, equality=equality) else: - for z in _simple_fixed_content(a[:], content, t + 1, t, - k, equality=equality): - yield z + yield from _simple_fixed_content(a[:], content, t + 1, t, + k, equality=equality) content[j] += 1 diff --git a/src/sage/combinat/non_decreasing_parking_function.py b/src/sage/combinat/non_decreasing_parking_function.py index 9b04286372c..532b4bf8762 100644 --- a/src/sage/combinat/non_decreasing_parking_function.py +++ b/src/sage/combinat/non_decreasing_parking_function.py @@ -419,8 +419,7 @@ def __iter__(self): [[], [1], [1, 1], [1, 2], [1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 2]] """ for n in NN: - for pf in NonDecreasingParkingFunctions_n(n): - yield pf + yield from NonDecreasingParkingFunctions_n(n) def graded_component(self, n): """ diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 8e3b777c35e..6b0c3017928 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -4403,7 +4403,7 @@ def k_boundary(self, k): """ return SkewPartition([self, self.k_interior(k)]) - def add_cell(self, i, j = None): + def add_cell(self, i, j=None): r""" Return a partition corresponding to ``self`` with a cell added in row ``i``. (This does not change ``self``.) @@ -6670,7 +6670,7 @@ def cardinality(self, algorithm='flint'): raise ValueError("unknown algorithm '%s'" % algorithm) - def random_element(self, measure = 'uniform'): + def random_element(self, measure='uniform'): """ Return a random partitions of `n` for the specified measure. diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index 9593055e9ed..cacdf386e47 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -1738,7 +1738,7 @@ def show(self, representation="cycles", orientation="landscape", **args): if representation == "cycles": d.show(**args) else: - d.show(layout = "circular", **args) + d.show(layout="circular", **args) elif representation == "braid": from sage.plot.line import line @@ -1759,7 +1759,7 @@ def show(self, representation="cycles", orientation="landscape", **args): L += line([r(i, 1.0), r(p[i]-1, 0)]) L += text(str(i), r(i, 1.05)) + text(str(i), r(p[i]-1, -.05)) - return L.show(axes = False, **args) + return L.show(axes=False, **args) else: raise ValueError("The value of 'representation' must be equal to "+ @@ -4808,7 +4808,7 @@ def rec(perm): return LBT(None) mn = compare(perm) k = perm.index(mn) - return LBT([rec(perm[:k]), rec(perm[k + 1:])], label = mn) + return LBT([rec(perm[:k]), rec(perm[k + 1:])], label=mn) return rec(self) @combinatorial_map(name="Increasing tree") @@ -4883,7 +4883,7 @@ def binary_search_tree(self, left_to_right=True): res = res.binary_search_insert(i) return res - @combinatorial_map(name = "Binary search tree (left to right)") + @combinatorial_map(name="Binary search tree (left to right)") def binary_search_tree_shape(self, left_to_right=True): r""" Return the shape of the binary search tree of the permutation @@ -5263,7 +5263,7 @@ def hyperoctahedral_double_coset_type(self): # Binary operations # ##################### - def shifted_concatenation(self, other, side = "right"): + def shifted_concatenation(self, other, side="right"): r""" Return the right (or left) shifted concatenation of ``self`` with a permutation ``other``. These operations are also known @@ -7787,7 +7787,7 @@ def from_reduced_word(rw, parent=None): return parent(p) -def bistochastic_as_sum_of_permutations(M, check = True): +def bistochastic_as_sum_of_permutations(M, check=True): r""" Return the positive sum of permutations corresponding to the bistochastic matrix ``M``. @@ -7887,7 +7887,7 @@ def bistochastic_as_sum_of_permutations(M, check = True): if not all(x >= 0 for x in M.list()): raise ValueError("The matrix should have nonnegative entries") - if check and not M.is_bistochastic(normalized = False): + if check and not M.is_bistochastic(normalized=False): raise ValueError("The matrix is not bistochastic") if not RR.has_coerce_map_from(M.base_ring()): diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index 7e1f1c6e4c6..7de90832e67 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -889,8 +889,7 @@ def upper_covers_iterator(self, element): sage: list(H.upper_covers_iterator(7)) [] """ - for x in self.neighbor_out_iterator(element): - yield x + yield from self.neighbor_out_iterator(element) def lower_covers_iterator(self, element): r""" @@ -905,8 +904,7 @@ def lower_covers_iterator(self, element): sage: list(H.lower_covers_iterator(4)) [1, 2] """ - for x in self.neighbor_in_iterator(element): - yield x + yield from self.neighbor_in_iterator(element) def cardinality(self): r""" diff --git a/src/sage/combinat/rigged_configurations/bij_abstract_class.py b/src/sage/combinat/rigged_configurations/bij_abstract_class.py index c06680c4cf2..66ad0ac37ce 100644 --- a/src/sage/combinat/rigged_configurations/bij_abstract_class.py +++ b/src/sage/combinat/rigged_configurations/bij_abstract_class.py @@ -17,7 +17,7 @@ - Travis Scrimshaw (2011-04-15): Initial version """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2011, 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -29,8 +29,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from copy import deepcopy from sage.misc.abstract_method import abstract_method @@ -120,19 +120,19 @@ def run(self, verbose=False): """ if verbose: from sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element \ - import TensorProductOfKirillovReshetikhinTableauxElement + import TensorProductOfKirillovReshetikhinTableauxElement for cur_crystal in reversed(self.tp_krt): target = cur_crystal.parent()._r # Iterate through the columns for col_number, cur_column in enumerate(reversed(cur_crystal.to_array(False))): - self.cur_path.insert(0, []) # Prepend an empty list + self.cur_path.insert(0, []) # Prepend an empty list self.cur_dims.insert(0, [0, 1]) for letter in reversed(cur_column): self.cur_dims[0][0] = self._next_index(self.cur_dims[0][0], target) - val = letter.value # Convert from a CrystalOfLetter to an Integer + val = letter.value # Convert from a CrystalOfLetter to an Integer if verbose: print("====================") @@ -142,7 +142,7 @@ def run(self, verbose=False): print("--------------------\n") # Build the next state - self.cur_path[0].insert(0, [letter]) # Prepend the value + self.cur_path[0].insert(0, [letter]) # Prepend the value self.next_state(val) # If we've split off a column, we need to merge the current column @@ -166,7 +166,7 @@ def run(self, verbose=False): for a in range(self.n): self._update_vacancy_nums(a) - self.ret_rig_con.set_immutable() # Return it to immutable + self.ret_rig_con.set_immutable() # Return it to immutable return self.ret_rig_con @abstract_method @@ -220,7 +220,7 @@ def _update_vacancy_nums(self, a): """ # Check to make sure we have a valid index (currently removed) # If the current tableau is empty, there is nothing to do - if not self.ret_rig_con[a]: # Check to see if we have vacancy numbers + if not self.ret_rig_con[a]: # Check to see if we have vacancy numbers return # Setup the first block @@ -268,7 +268,7 @@ def _update_partition_values(self, a): pos = 0 width = rigged_partition[index] val = rigged_partition.rigging[index] - for i in reversed(range(index-1)): + for i in reversed(range(index - 1)): if rigged_partition[i] > width or rigged_partition.rigging[i] >= val: pos = i + 1 break @@ -333,7 +333,7 @@ def __init__(self, RC_element): # This is a dummy edge to start the process cp = RC_element.__copy__() cp.set_immutable() - self._graph = [ [[], (cp, 0)] ] + self._graph = [[[], (cp, 0)]] def __eq__(self, rhs): r""" @@ -414,7 +414,7 @@ def run(self, verbose=False, build_graph=False): y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), 'ls']) - while self.cur_dims[0][0]: # > 0: + while self.cur_dims[0][0]: # > 0: if verbose: print("====================") print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True))) @@ -427,16 +427,16 @@ def run(self, verbose=False, build_graph=False): b = self.next_state(ht) # Make sure we have a crystal letter - ret_crystal_path[-1].append(letters(b)) # Append the rank + ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) - self.cur_dims.pop(0) # Pop off the leading column + self.cur_dims.pop(0) # Pop off the leading column if build_graph: - self._graph.pop(0) # Remove the dummy at the start + self._graph.pop(0) # Remove the dummy at the start from sage.graphs.digraph import DiGraph from sage.graphs.dot2tex_utils import have_dot2tex self._graph = DiGraph(self._graph, format="list_of_edges") diff --git a/src/sage/combinat/rigged_configurations/bij_infinity.py b/src/sage/combinat/rigged_configurations/bij_infinity.py index fa1067ccd93..8d9700e168a 100644 --- a/src/sage/combinat/rigged_configurations/bij_infinity.py +++ b/src/sage/combinat/rigged_configurations/bij_infinity.py @@ -175,13 +175,13 @@ def _call_(self, x): if ct.type() == 'D': lam[-2] = max(lam[-2], lam[-1]) lam.pop() - l = sum([ [[r+1,1]]*v for r,v in enumerate(lam[:-1]) ], []) + l = sum([[[r+1, 1]]*v for r, v in enumerate(lam[:-1])], []) n = len(I) - l = l + sum([ [[n,1], [n-1,1]] for k in range(lam[-1])], []) + l = l + sum([[[n,1], [n-1,1]] for k in range(lam[-1])], []) else: if ct.type() == 'B': lam[-1] *= 2 - l = sum([ [[r,1]]*lam[i] for i,r in enumerate(I) ], []) + l = sum([[[r, 1]]*lam[i] for i, r in enumerate(I)], []) RC = RiggedConfigurations(ct.affine(), reversed(l)) elt = RC(x) diff --git a/src/sage/combinat/rigged_configurations/bij_type_A.py b/src/sage/combinat/rigged_configurations/bij_type_A.py index a700b0b4ba7..198ba0fc433 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_A.py +++ b/src/sage/combinat/rigged_configurations/bij_type_A.py @@ -21,7 +21,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2011, 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -33,8 +33,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_abstract_class import KRTToRCBijectionAbstract from sage.combinat.rigged_configurations.bij_abstract_class import RCToKRTBijectionAbstract @@ -122,7 +122,7 @@ def next_state(self, height): sage: bijection.next_state(1) 5 """ - height -= 1 # indexing + height -= 1 # indexing n = self.n ell = [None] * n b = None @@ -158,4 +158,4 @@ def next_state(self, height): if row_num is not None: self.cur_partitions[n - 1].rigging[row_num] = self.cur_partitions[n - 1].vacancy_numbers[row_num] - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_A2_dual.py b/src/sage/combinat/rigged_configurations/bij_type_A2_dual.py index 934a92851a5..dee72713e12 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_A2_dual.py +++ b/src/sage/combinat/rigged_configurations/bij_type_A2_dual.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_C import KRTToRCBijectionTypeC from sage.combinat.rigged_configurations.bij_type_C import RCToKRTBijectionTypeC @@ -155,7 +155,7 @@ def next_state(self, val): else: j = i - 1 while j >= 0 and partition._list[j] <= max_width + 2: - partition.rigging[j+1] = partition.rigging[j] # Shuffle it along + partition.rigging[j+1] = partition.rigging[j] # Shuffle it along j -= 1 partition._list.pop(i) partition._list.insert(j+1, max_width + 2) @@ -219,7 +219,7 @@ def next_state(self, height): sage: bijection.next_state(2) -1 """ - height -= 1 # indexing + height -= 1 # indexing n = self.n ell = [None] * (2*n) case_S = [False] * n @@ -333,4 +333,4 @@ def next_state(self, height): else: self.cur_partitions[n-1].rigging[row_num_bar_next] = self.cur_partitions[n-1].vacancy_numbers[row_num_bar_next] - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_A2_even.py b/src/sage/combinat/rigged_configurations/bij_type_A2_even.py index 76dcca00f1f..1c0d587139a 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_A2_even.py +++ b/src/sage/combinat/rigged_configurations/bij_type_A2_even.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_A import KRTToRCBijectionTypeA from sage.combinat.rigged_configurations.bij_type_C import KRTToRCBijectionTypeC @@ -139,7 +139,7 @@ def next_state(self, height): sage: bijection.next_state(2) -1 """ - height -= 1 # indexing + height -= 1 # indexing n = self.n ell = [None] * (2*n) case_S = [False] * n @@ -213,4 +213,4 @@ def next_state(self, height): if row_num_bar is not None: self.cur_partitions[n-1].rigging[row_num_bar] = self.cur_partitions[n-1].vacancy_numbers[row_num_bar] - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_A2_odd.py b/src/sage/combinat/rigged_configurations/bij_type_A2_odd.py index 477cbf6f9ab..42a8cf956fb 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_A2_odd.py +++ b/src/sage/combinat/rigged_configurations/bij_type_A2_odd.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_A import KRTToRCBijectionTypeA from sage.combinat.rigged_configurations.bij_type_A import RCToKRTBijectionTypeA @@ -126,7 +126,7 @@ def next_state(self, height): sage: bijection.next_state(1) -2 """ - height -= 1 # indexing + height -= 1 # indexing n = self.n ell = [None] * (2*n) b = None @@ -194,4 +194,4 @@ def next_state(self, height): if ret_row_next is not None: self.cur_partitions[n-1].rigging[ret_row_next] = self.cur_partitions[n-1].vacancy_numbers[ret_row_next] - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_B.py b/src/sage/combinat/rigged_configurations/bij_type_B.py index 0f672e8fc2b..fd924150380 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_B.py +++ b/src/sage/combinat/rigged_configurations/bij_type_B.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_A import KRTToRCBijectionTypeA from sage.combinat.rigged_configurations.bij_type_C import KRTToRCBijectionTypeC @@ -92,7 +92,7 @@ def run(self, verbose=False): """ if verbose: from sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element \ - import TensorProductOfKirillovReshetikhinTableauxElement + import TensorProductOfKirillovReshetikhinTableauxElement for cur_crystal in reversed(self.tp_krt): r = cur_crystal.parent().r() @@ -108,7 +108,7 @@ def run(self, verbose=False): if verbose: print("====================") if len(self.cur_path) == 0: - print(repr([])) # Special case for displaying when the rightmost factor is a spinor + print(repr([])) # Special case for displaying when the rightmost factor is a spinor else: print(repr(TensorProductOfKirillovReshetikhinTableauxElement(self.tp_krt.parent(), self.cur_path))) print("--------------------") @@ -143,14 +143,14 @@ def run(self, verbose=False): r = cur_crystal.parent().r() # Iterate through the columns for col_number, cur_column in enumerate(reversed(cur_crystal.to_array(False))): - bij.cur_path.insert(0, []) # Prepend an empty list + bij.cur_path.insert(0, []) # Prepend an empty list bij.cur_dims.insert(0, [0, 1]) # Note that we do not need to worry about iterating over columns # (see previous note about the data structure). for letter in reversed(cur_column): bij.cur_dims[0][0] += 1 - val = letter.value # Convert from a CrystalOfLetter to an Integer + val = letter.value # Convert from a CrystalOfLetter to an Integer if verbose: print("====================") @@ -160,7 +160,7 @@ def run(self, verbose=False): print("--------------------\n") # Build the next state - bij.cur_path[0].insert(0, [letter]) # Prepend the value + bij.cur_path[0].insert(0, [letter]) # Prepend the value bij.next_state(val) # If we've split off a column, we need to merge the current column @@ -201,14 +201,14 @@ def run(self, verbose=False): # Perform the regular type B_n^{(1)} bijection # Iterate through the columns for col_number, cur_column in enumerate(reversed(cur_crystal.to_array(False))): - self.cur_path.insert(0, []) # Prepend an empty list + self.cur_path.insert(0, []) # Prepend an empty list self.cur_dims.insert(0, [0, 1]) # Note that we do not need to worry about iterating over columns # (see previous note about the data structure). for letter in reversed(cur_column): self.cur_dims[0][0] += 1 - val = letter.value # Convert from a CrystalOfLetter to an Integer + val = letter.value # Convert from a CrystalOfLetter to an Integer if verbose: print("====================") @@ -218,7 +218,7 @@ def run(self, verbose=False): print("--------------------\n") # Build the next state - self.cur_path[0].insert(0, [letter]) # Prepend the value + self.cur_path[0].insert(0, [letter]) # Prepend the value self.next_state(val) # If we've split off a column, we need to merge the current column @@ -241,7 +241,7 @@ def run(self, verbose=False): # And perform the inverse column splitting map on the RC for a in range(self.n): self._update_vacancy_nums(a) - self.ret_rig_con.set_immutable() # Return it to immutable + self.ret_rig_con.set_immutable() # Return it to immutable return self.ret_rig_con def next_state(self, val): @@ -371,7 +371,7 @@ def next_state(self, val): # Add 2 boxes j = i - 1 while j >= 0 and p._list[j] <= max_width + 2: - p.rigging[j+1] = p.rigging[j] # Shuffle it along + p.rigging[j+1] = p.rigging[j] # Shuffle it along j -= 1 p._list.pop(i) p._list.insert(j+1, max_width + 2) @@ -379,7 +379,7 @@ def next_state(self, val): break if p._list[i] == max_width and not singular_max_width: - p._list[i] += 1 # We always at least add a box to the first singular value + p._list[i] += 1 # We always at least add a box to the first singular value p.rigging[i] = None if case_QS: width_n = p._list[i] @@ -402,7 +402,7 @@ def next_state(self, val): # to attempt both # Make a *deep* copy of the element cp = self.ret_rig_con.__copy__() - for i,rp in enumerate(cp): + for i, rp in enumerate(cp): cp[i] = rp._clone() # We attempt case (S) first self._insert_cell_case_S(p) @@ -493,7 +493,7 @@ def other_outcome(self, rc, pos_val, width_n): p.rigging[i] = None case_QS = True break - if not case_QS: # we have not added a box yet + if not case_QS: # we have not added a box yet p._list.append(1) p.rigging.append(None) p.vacancy_numbers.append(None) @@ -641,7 +641,7 @@ def run(self, verbose=False, build_graph=False): y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), 'ls']) - while bij.cur_dims[0][0]: # > 0: + while bij.cur_dims[0][0]: # > 0: if verbose: print("====================") print(repr(RC(*bij.cur_partitions, use_vacancy_numbers=True))) @@ -653,15 +653,15 @@ def run(self, verbose=False, build_graph=False): bij.cur_dims[0][0] = bij._next_index(ht) b = bij.next_state(ht) # Make sure we have a crystal letter - ret_crystal_path[-1].append(letters(b)) # Append the rank + ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) - bij.cur_dims.pop(0) # Pop off the leading column + bij.cur_dims.pop(0) # Pop off the leading column - self.cur_dims.pop(0) # Pop off the spin rectangle + self.cur_dims.pop(0) # Pop off the spin rectangle self.cur_partitions = bij.cur_partitions # Convert the n-th partition back into the special type B one @@ -712,7 +712,7 @@ def run(self, verbose=False, build_graph=False): y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), '2x']) - while self.cur_dims[0][0]: #> 0: + while self.cur_dims[0][0]: # > 0: if verbose: print("====================") print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True))) @@ -720,20 +720,20 @@ def run(self, verbose=False, build_graph=False): print(ret_crystal_path) print("--------------------\n") - self.cur_dims[0][0] -= 1 # This takes care of the indexing + self.cur_dims[0][0] -= 1 # This takes care of the indexing b = self.next_state(self.cur_dims[0][0]) # Make sure we have a crystal letter - ret_crystal_path[-1].append(letters(b)) # Append the rank + ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) - self.cur_dims.pop(0) # Pop off the leading column + self.cur_dims.pop(0) # Pop off the leading column if build_graph: - self._graph.pop(0) # Remove the dummy at the start + self._graph.pop(0) # Remove the dummy at the start from sage.graphs.digraph import DiGraph from sage.graphs.dot2tex_utils import have_dot2tex self._graph = DiGraph(self._graph) @@ -796,7 +796,7 @@ def next_state(self, height): last_size = partition[j] case_S = True break - if not case_Q: # We found a singular string above the quasi-singular one + if not case_Q: # We found a singular string above the quasi-singular one break ell[n-1] = i last_size = partition[i] @@ -882,7 +882,7 @@ def next_state(self, height): self._update_vacancy_numbers(n - 1) if row_num_next is not None: self.cur_partitions[n-1].rigging[row_num_next] = self.cur_partitions[n-1].vacancy_numbers[row_num_next] - if row_num_bar_next is not None: # If we enter here, it means case (Q, S) holds + if row_num_bar_next is not None: # If we enter here, it means case (Q, S) holds vac_num = self.cur_partitions[n-1].vacancy_numbers[row_num_bar_next] self.cur_partitions[n-1].rigging[row_num_bar_next] = vac_num if make_quasisingular: @@ -895,4 +895,4 @@ def next_state(self, height): j += 1 self.cur_partitions[n-1].rigging[j-1] = vac_num - 1 - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_C.py b/src/sage/combinat/rigged_configurations/bij_type_C.py index 0d18e575043..d04267b5569 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_C.py +++ b/src/sage/combinat/rigged_configurations/bij_type_C.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_A import KRTToRCBijectionTypeA from sage.combinat.rigged_configurations.bij_type_A import RCToKRTBijectionTypeA @@ -151,7 +151,7 @@ def _insert_cell_case_S(self, partition): if partition.rigging[i] is None: j = i - 1 while j >= 0 and partition._list[j] == partition._list[i]: - partition.rigging[j+1] = partition.rigging[j] # Shuffle it along + partition.rigging[j+1] = partition.rigging[j] # Shuffle it along j -= 1 partition._list[j+1] += 1 partition.rigging[j+1] = None @@ -176,7 +176,7 @@ def next_state(self, height): sage: bijection.next_state(1) -1 """ - height -= 1 # indexing + height -= 1 # indexing n = self.n ell = [None] * (2*n) case_S = [False] * n @@ -214,7 +214,7 @@ def next_state(self, height): if a >= height and self.cur_partitions[a][ell[a]] == last_size: ell[n+a] = ell[a] case_S[a] = True - else: # note last_size > 1 + else: # note last_size > 1 ell[n+a] = self._find_singular_string(self.cur_partitions[a], last_size) if ell[n + a] is None: @@ -262,4 +262,4 @@ def next_state(self, height): if row_num_next is not None: self.cur_partitions[n-1].rigging[row_num_next] = self.cur_partitions[n-1].vacancy_numbers[row_num_next] - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_D.py b/src/sage/combinat/rigged_configurations/bij_type_D.py index a09c9383f1c..12fb6c6be2c 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2011, 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_A import KRTToRCBijectionTypeA from sage.combinat.rigged_configurations.bij_type_A import RCToKRTBijectionTypeA @@ -83,7 +83,7 @@ def run(self, verbose=False): r = cur_crystal.parent().r() # Iterate through the columns for col_number, cur_column in enumerate(reversed(cur_crystal.to_array(False))): - self.cur_path.insert(0, []) # Prepend an empty list + self.cur_path.insert(0, []) # Prepend an empty list # Check to see if we are a spinor column if r >= self.n-1: @@ -102,7 +102,7 @@ def run(self, verbose=False): # This check is needed for the n-1 spin column if self.cur_dims[0][0] < r: self.cur_dims[0][0] += 1 - val = letter.value # Convert from a CrystalOfLetter to an Integer + val = letter.value # Convert from a CrystalOfLetter to an Integer if verbose: print("====================") @@ -112,7 +112,7 @@ def run(self, verbose=False): print("--------------------\n") # Build the next state - self.cur_path[0].insert(0, [letter]) # Prepend the value + self.cur_path[0].insert(0, [letter]) # Prepend the value self.next_state(val) # Check to see if we are a spinor column @@ -139,7 +139,7 @@ def run(self, verbose=False): for a in range(self.n): self._update_vacancy_nums(a) - self.ret_rig_con.set_immutable() # Return it to immutable + self.ret_rig_con.set_immutable() # Return it to immutable return self.ret_rig_con def next_state(self, val): @@ -495,7 +495,7 @@ def run(self, verbose=False, build_graph=False): b = self.next_state(self.n) if b == self.n: b = -self.n - ret_crystal_path[-1].append(letters(b)) # Append the rank + ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) @@ -509,7 +509,7 @@ def run(self, verbose=False, build_graph=False): print(ret_crystal_path) print("--------------------\n") - self.cur_dims[0][0] -= 1 # This takes care of the indexing + self.cur_dims[0][0] -= 1 # This takes care of the indexing b = self.next_state(self.cur_dims[0][0]) # Corrections for spinor @@ -518,13 +518,13 @@ def run(self, verbose=False, build_graph=False): b = -(self.n-1) # Make sure we have a crystal letter - ret_crystal_path[-1].append(letters(b)) # Append the rank + ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) - self.cur_dims.pop(0) # Pop off the leading column + self.cur_dims.pop(0) # Pop off the leading column # Check to see if we were a spinor if dim[0] >= self.n-1: @@ -677,7 +677,7 @@ def next_state(self, height): self.cur_partitions[n - 1].rigging[ret_row_bar_next] = \ self.cur_partitions[n - 1].vacancy_numbers[ret_row_bar_next] - return(b) + return b def doubling_map(self): r""" diff --git a/src/sage/combinat/rigged_configurations/bij_type_D_tri.py b/src/sage/combinat/rigged_configurations/bij_type_D_tri.py index e0796bf880d..f143b3ce38a 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D_tri.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D_tri.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2014 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_A import KRTToRCBijectionTypeA from sage.combinat.rigged_configurations.bij_type_A import RCToKRTBijectionTypeA @@ -169,7 +169,7 @@ def next_state(self, val): else: j = i - 1 while j >= 0 and P._list[j] <= max_width + 2: - P.rigging[j+1] = P.rigging[j] # Shuffle it along + P.rigging[j+1] = P.rigging[j] # Shuffle it along j -= 1 P._list.pop(i) P._list.insert(j+1, max_width + 2) @@ -193,7 +193,7 @@ def next_state(self, val): if P.rigging[i] is None: j = i - 1 while j >= 0 and P._list[j] == P._list[i]: - P.rigging[j+1] = P.rigging[j] # Shuffle it along + P.rigging[j+1] = P.rigging[j] # Shuffle it along j -= 1 P._list[j+1] += 1 P.rigging[j+1] = None @@ -210,7 +210,7 @@ def next_state(self, val): if P.rigging[i] is None: j = i - 1 while j >= 0 and P._list[j] == P._list[i]: - P.rigging[j+1] = P.rigging[j] # Shuffle it along + P.rigging[j+1] = P.rigging[j] # Shuffle it along j -= 1 P._list[j+1] += 1 P.rigging[j+1] = None @@ -254,7 +254,7 @@ def next_state(self, height): sage: bijection.next_state(2) -3 """ - height -= 1 # indexing + height -= 1 # indexing ell = [None] * 6 case_S = [False] * 3 case_Q = False @@ -305,7 +305,7 @@ def next_state(self, height): else: b = 0 - if b is None: # Going back + if b is None: # Going back if self.cur_partitions[1][ell[1]] == last_size: ell[4] = ell[1] case_S[1] = True @@ -317,7 +317,7 @@ def next_state(self, height): else: last_size = self.cur_partitions[1][ell[4]] - if b is None: # Final partition + if b is None: # Final partition P = self.cur_partitions[0] if ell[0] is not None and P[ell[0]] == last_size: ell[5] = ell[0] @@ -346,7 +346,7 @@ def next_state(self, height): if case_S[0]: row0 = [self.cur_partitions[0].remove_cell(ell[5], 2)] - row0.append( self.cur_partitions[0].remove_cell(ell[3], 2) ) + row0.append(self.cur_partitions[0].remove_cell(ell[3], 2)) else: if case_Q: if ell[0] is None or ell[0] < ell[2]: @@ -360,9 +360,9 @@ def next_state(self, height): else: row0 = [self.cur_partitions[0].remove_cell(ell[0])] if case_S[2]: - row0.append( self.cur_partitions[0].remove_cell(ell[3], 2) ) + row0.append(self.cur_partitions[0].remove_cell(ell[3], 2)) - row0.append( self.cur_partitions[0].remove_cell(ell[5]) ) + row0.append(self.cur_partitions[0].remove_cell(ell[5])) self._update_vacancy_numbers(0) self._update_vacancy_numbers(1) @@ -387,4 +387,4 @@ def next_state(self, height): j += 1 P.rigging[j-1] = vac_num - 1 - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py b/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py index e9c13e4b54d..dbc049d6ae0 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2011, 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_A import KRTToRCBijectionTypeA from sage.combinat.rigged_configurations.bij_type_A2_even import KRTToRCBijectionTypeA2Even @@ -84,7 +84,7 @@ def run(self, verbose=False): r = cur_crystal.parent().r() # Iterate through the columns for col_number, cur_column in enumerate(reversed(cur_crystal.to_array(False))): - self.cur_path.insert(0, []) # Prepend an empty list + self.cur_path.insert(0, []) # Prepend an empty list # Check to see if we are a spinor column if r == self.n: @@ -101,7 +101,7 @@ def run(self, verbose=False): for letter in reversed(cur_column): self.cur_dims[0][0] += 1 - val = letter.value # Convert from a CrystalOfLetter to an Integer + val = letter.value # Convert from a CrystalOfLetter to an Integer if verbose: print("====================") @@ -111,7 +111,7 @@ def run(self, verbose=False): print("--------------------\n") # Build the next state - self.cur_path[0].insert(0, [letter]) # Prepend the value + self.cur_path[0].insert(0, [letter]) # Prepend the value self.next_state(val) # Check to see if we are a spinor column @@ -138,7 +138,7 @@ def run(self, verbose=False): for a in range(self.n): self._update_vacancy_nums(a) - self.ret_rig_con.set_immutable() # Return it to immutable + self.ret_rig_con.set_immutable() # Return it to immutable return self.ret_rig_con def next_state(self, val): @@ -571,4 +571,4 @@ def next_state(self, height): else: self.cur_partitions[n-1].rigging[row_num_bar_next] = self.cur_partitions[n-1].vacancy_numbers[row_num_bar_next] - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_E67.py b/src/sage/combinat/rigged_configurations/bij_type_E67.py index 6fedd39c5a0..3d258443276 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_E67.py +++ b/src/sage/combinat/rigged_configurations/bij_type_E67.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2011, 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_abstract_class import KRTToRCBijectionAbstract from sage.combinat.rigged_configurations.bij_abstract_class import RCToKRTBijectionAbstract @@ -91,8 +91,8 @@ def find_singular_string(p, max_width): if not data: break - max_val = max(l for a,l in data) - for a,l in data: + max_val = max(l for a, l in data) + for a, l in data: if l == max_val: self.ret_rig_con[a-1].insert_cell(max_width) max_width = l @@ -153,7 +153,7 @@ def _next_index(self, r, target): return 2 if r == 2: return 5 - else: # rank == 7 + else: # rank == 7 # 1-2-3 # / # 0-7-6-5-4 @@ -240,12 +240,12 @@ def next_state(self, r): data = [(a, self._find_singular_string(self.cur_partitions[a-1], last_size)) for a in b.value if a > 0] data = [(val, a, self.cur_partitions[a-1][val]) - for a,val in data if val is not None] + for a, val in data if val is not None] if not data: break - min_val = min(l for i,a,l in data) - for i,a,l in data: + min_val = min(l for i, a, l in data) + for i, a, l in data: if l == min_val: found = True last_size = l @@ -253,13 +253,13 @@ def next_state(self, r): b = b.f(a) break - for a,p in enumerate(self.cur_partitions): + for a, p in enumerate(self.cur_partitions): self._update_vacancy_numbers(a) for i in range(len(p)): if p.rigging[i] is None: p.rigging[i] = p.vacancy_numbers[i] - return(b) + return b def _next_index(self, r): """ @@ -290,7 +290,7 @@ def _next_index(self, r): return 2 if r == 6: return 1 - else: # rank == 7 + else: # rank == 7 # 1-2-3 # / # 0-7-6-5-4 @@ -346,7 +346,7 @@ def endpoint6(r): sage: endpoint6(6) (-1, 6) """ - C = CrystalOfLetters(['E',6]) + C = CrystalOfLetters(['E', 6]) if r == 1: return C.module_generators[0] # C((1,)) elif r == 2: @@ -383,7 +383,7 @@ def endpoint7(r): sage: endpoint7(7) (7,) """ - C = CrystalOfLetters(['E',7]) + C = CrystalOfLetters(['E', 7]) if r == 1: return C((-7, 1)) elif r == 2: diff --git a/src/sage/combinat/rigged_configurations/kleber_tree.py b/src/sage/combinat/rigged_configurations/kleber_tree.py index 82c99e8ad73..7805d0b7f4b 100644 --- a/src/sage/combinat/rigged_configurations/kleber_tree.py +++ b/src/sage/combinat/rigged_configurations/kleber_tree.py @@ -170,7 +170,7 @@ def _draw_tree(tree_node, node_label=True, style_point=None, style_node='fill=wh else: lines_str += "\\draw%s (%s%s) -- (%s%s%s);\n"%(style_line_str, node_name, node_place_str, node_name, i, node_place_str) - #drawing root + # drawing root if style_node is None: style_node = '' else: @@ -429,8 +429,8 @@ def _repr_(self): sage: KT.root Kleber tree node with weight [0, 2, 0, 2, 0] and upwards edge root [0, 0, 0, 0, 0] """ - return "Kleber tree node with weight %s and upwards edge root %s"%( - list(self.weight.to_vector()), list(self.up_root.to_vector()) ) + return "Kleber tree node with weight %s and upwards edge root %s" % ( + list(self.weight.to_vector()), list(self.up_root.to_vector())) def _latex_(self): r""" diff --git a/src/sage/combinat/rigged_configurations/rc_crystal.py b/src/sage/combinat/rigged_configurations/rc_crystal.py index fbd149f6c0c..dbd7fd047fe 100644 --- a/src/sage/combinat/rigged_configurations/rc_crystal.py +++ b/src/sage/combinat/rigged_configurations/rc_crystal.py @@ -179,7 +179,7 @@ def __init__(self, wt, WLR): else: category = (RegularCrystals(), HighestWeightCrystals(), InfiniteEnumeratedSets()) Parent.__init__(self, category=category) - n = self._cartan_type.rank() #== len(self._cartan_type.index_set()) + n = self._cartan_type.rank() # == len(self._cartan_type.index_set()) self.module_generators = (self.element_class(self, partition_list=[[] for _ in repeat(None, n)]),) options = RiggedConfigurations.options @@ -444,7 +444,7 @@ def from_virtual(self, vrc): sage: elt == RC.from_virtual(RC.to_virtual(elt)) True """ - gamma = list(self._folded_ct.scaling_factors()) #map(int, self._folded_ct.scaling_factors()) + gamma = list(self._folded_ct.scaling_factors()) # map(int, self._folded_ct.scaling_factors()) sigma = self._folded_ct._orbit n = self._cartan_type.rank() partitions = [None] * n diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index 727322f0efd..542649cf9dd 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -232,8 +232,8 @@ def __init__(self, parent, rigged_partitions=[], **options): nu = [] for i in range(n): nu.append(RiggedPartition()) - #raise ValueError("Invalid input") - #raise ValueError("Incorrect number of rigged partitions") + # raise ValueError("Invalid input") + # raise ValueError("Incorrect number of rigged partitions") # Set the vacancy numbers for a, partition in enumerate(nu): @@ -330,7 +330,7 @@ def _repr_vertical(self): ret_str = "" for tableau in self: ret_str += "\n" + repr(tableau) - return(ret_str) + return ret_str def _repr_horizontal(self): """ @@ -1039,7 +1039,7 @@ def f(self, a): return self.parent().from_virtual(virtual_rc) ########################################################## -## Highest weight crystal rigged configuration elements ## +# Highest weight crystal rigged configuration elements # ########################################################## @@ -1229,7 +1229,7 @@ def weight(self): return self.parent()._wt - sum(sum(x) * alpha[i] for i,x in enumerate(self)) ############################################## -## KR crystal rigged configuration elements ## +# KR crystal rigged configuration elements # ############################################## @@ -2278,7 +2278,7 @@ def cocharge(self): sage: RC(partition_list=[[1,1],[2,1],[1,1]]).cocharge() 1 """ - #return self.to_virtual_configuration().cocharge() / self.parent()._folded_ct.gamma[0] + # return self.to_virtual_configuration().cocharge() / self.parent()._folded_ct.gamma[0] vct = self.parent()._folded_ct cc = ZZ.zero() rigging_sum = ZZ.zero() diff --git a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py index 74d923e0fd9..ce4c2ad2ab4 100644 --- a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +++ b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py @@ -45,7 +45,7 @@ False """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010-2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -57,8 +57,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.misc.cachefunc import cached_method from sage.structure.unique_representation import UniqueRepresentation @@ -68,9 +68,9 @@ from sage.combinat.root_system.cartan_type import CartanType from sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element \ - import TensorProductOfKirillovReshetikhinTableauxElement + import TensorProductOfKirillovReshetikhinTableauxElement from sage.combinat.rigged_configurations.kr_tableaux import KirillovReshetikhinTableaux, \ - KirillovReshetikhinTableauxElement + KirillovReshetikhinTableauxElement from sage.rings.integer import Integer @@ -339,8 +339,8 @@ def __iter__(self): index_set = self._cartan_type.classical().index_set() from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet return RecursivelyEnumeratedSet(self.module_generators, - lambda x: [x.f(i) for i in index_set], - structure=None).naive_search_iterator() + lambda x: [x.f(i) for i in index_set], + structure=None).naive_search_iterator() def _test_bijection(self, **options): r""" @@ -360,7 +360,7 @@ def _test_bijection(self, **options): if z != x: rejects.append((x, z)) - tester.assertEqual(len(rejects), 0, "Bijection is not correct: %s"%rejects) + tester.assertEqual(len(rejects), 0, "Bijection is not correct: %s" % rejects) if rejects: return rejects @@ -415,7 +415,7 @@ def _module_generators_brute_force(self): """ index_set = self.cartan_type().classical().index_set() return tuple(x for x in FullTensorProductOfRegularCrystals.__iter__(self) - if x.is_highest_weight(index_set)) + if x.is_highest_weight(index_set)) @cached_method def rigged_configurations(self): diff --git a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py index fb43642a004..c816d2140a6 100644 --- a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +++ b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py @@ -9,7 +9,7 @@ - Travis Scrimshaw (2010-09-26): Initial version """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010, 2011, 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -21,8 +21,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.crystals.tensor_product import TensorProductOfRegularCrystalsElement @@ -158,7 +158,7 @@ def _repr_(self): ret_str = repr(self[0]) for i in range(1, len(self)): ret_str += " (X) " + repr(self[i]) - return(ret_str) + return ret_str def _repr_diagram(self): """ @@ -179,7 +179,7 @@ def _repr_diagram(self): sage: Partitions.options._reset() """ comp = [crys._repr_diagram().splitlines() for crys in self] - num_comp = len(comp) # number of components + num_comp = len(comp) # number of components col_len = [len(t) > 0 and len(t[0]) or 1 for t in comp] # columns per component num_rows = max(len(t) for t in comp) # number of rows @@ -190,11 +190,11 @@ def _repr_diagram(self): diag += '\n' for c in range(num_comp): if c > 0: - diag += ' ' # For the tensor symbol + diag += ' ' # For the tensor symbol if row < len(comp[c]): diag += comp[c][row] else: - diag += ' '*col_len[c] + diag += ' ' * col_len[c] return diag def pp(self): @@ -244,7 +244,7 @@ def lusztig_involution(self): Tensor product of Kirillov-Reshetikhin tableaux of type ['A', 3, 1] and factor(s) ((1, 3), (2, 2)) """ from sage.combinat.rigged_configurations.tensor_product_kr_tableaux \ - import TensorProductOfKirillovReshetikhinTableaux + import TensorProductOfKirillovReshetikhinTableaux P = self.parent() P = TensorProductOfKirillovReshetikhinTableaux(P._cartan_type, reversed(P.dims)) return P(*[x.lusztig_involution() for x in reversed(self)]) @@ -266,11 +266,11 @@ def left_split(self): P = self.parent() if P.dims[0][1] == 1: raise ValueError("cannot split a single column") - r,s = P.dims[0] - B = [[r,1], [r,s-1]] + r, s = P.dims[0] + B = [[r, 1], [r, s - 1]] B.extend(P.dims[1:]) from sage.combinat.rigged_configurations.tensor_product_kr_tableaux \ - import TensorProductOfKirillovReshetikhinTableaux + import TensorProductOfKirillovReshetikhinTableaux TP = TensorProductOfKirillovReshetikhinTableaux(P._cartan_type, B) x = self[0].left_split() return TP(*(list(x) + self[1:])) @@ -298,12 +298,12 @@ def right_split(self): P = self.parent() if P.dims[-1][1] == 1: raise ValueError("cannot split a single column") - r,s = P.dims[-1] + r, s = P.dims[-1] B = list(P.dims[:-1]) - B.append([r, s-1]) + B.append([r, s - 1]) B.append([r, 1]) from sage.combinat.rigged_configurations.tensor_product_kr_tableaux \ - import TensorProductOfKirillovReshetikhinTableaux + import TensorProductOfKirillovReshetikhinTableaux TP = TensorProductOfKirillovReshetikhinTableaux(P._cartan_type, B) x = self[-1].right_split() return TP(*(self[:-1] + list(x))) diff --git a/src/sage/combinat/root_system/cartan_type.py b/src/sage/combinat/root_system/cartan_type.py index 6c89e131c9d..d8a37f350ce 100644 --- a/src/sage/combinat/root_system/cartan_type.py +++ b/src/sage/combinat/root_system/cartan_type.py @@ -1142,7 +1142,7 @@ def index_set(self): # be used for Coxeter groups etc. (experimental feature) _index_set_coloring = {1:"blue", 2:"red", 3:"green"} - @abstract_method(optional = True) + @abstract_method(optional=True) def coxeter_diagram(self): """ Return the Coxeter diagram for ``self``. @@ -1734,7 +1734,7 @@ def symmetrizer(self): from sage.matrix.constructor import matrix, diagonal_matrix m = self.cartan_matrix() n = m.nrows() - M = matrix(ZZ, n, n*n, sparse = True) + M = matrix(ZZ, n, n*n, sparse=True) for (i,j) in m.nonzero_positions(): M[i, n * i + j] = m[i,j] M[j, n * i + j] -= m[j,i] @@ -2082,7 +2082,7 @@ def basic_untwisted(self): ['D', 4] """ - def row_annihilator(self, m = None): + def row_annihilator(self, m=None): r""" Return the unique minimal non trivial annihilating linear combination of `\alpha_0, \alpha_1, \ldots, \alpha_n` with @@ -2423,7 +2423,7 @@ def other_affinization(self): class CartanType_standard(UniqueRepresentation, SageObject): # Technical methods - def _repr_(self, compact = False): + def _repr_(self, compact=False): """ TESTS:: @@ -2681,7 +2681,7 @@ class CartanType_standard_affine(CartanType_standard, CartanType_affine): A concrete class for affine simple Cartan types. """ - def __init__(self, letter, n, affine = 1): + def __init__(self, letter, n, affine=1): """ EXAMPLES:: @@ -2706,7 +2706,7 @@ def __init__(self, letter, n, affine = 1): self.n = n self.affine = affine - def _repr_(self, compact = False): + def _repr_(self, compact=False): """ TESTS:: @@ -3016,7 +3016,7 @@ def index_set(self): class SuperCartanType_standard(UniqueRepresentation, SageObject): # Technical methods - def _repr_(self, compact = False): + def _repr_(self, compact=False): """ TESTS:: diff --git a/src/sage/combinat/root_system/extended_affine_weyl_group.py b/src/sage/combinat/root_system/extended_affine_weyl_group.py index 87fe3399169..1fcd553da5a 100644 --- a/src/sage/combinat/root_system/extended_affine_weyl_group.py +++ b/src/sage/combinat/root_system/extended_affine_weyl_group.py @@ -574,7 +574,7 @@ def __init__(self, cartan_type, general_linear, **print_options): self._extended = True - Parent.__init__(self, category = Groups().WithRealizations().Infinite()) + Parent.__init__(self, category=Groups().WithRealizations().Infinite()) # create the realizations (they are cached) PW0 = self.PW0() @@ -1974,7 +1974,7 @@ def __init__(self, E): def twist(w,l): return E.exp_lattice()(w.action(l.value)) - GroupSemidirectProduct.__init__(self, E.exp_lattice(), E.classical_weyl(), twist = twist, act_to_right=False, prefix0=E._prefixt, print_tuple = E._print_tuple, category=E.Realizations()) + GroupSemidirectProduct.__init__(self, E.exp_lattice(), E.classical_weyl(), twist=twist, act_to_right=False, prefix0=E._prefixt, print_tuple=E._print_tuple, category=E.Realizations()) self._style = "PW0" def _repr_(self): @@ -2348,7 +2348,7 @@ def __init__(self, E): def twist(g,w): return g.act_on_affine_weyl(w) - GroupSemidirectProduct.__init__(self, E.affine_weyl(), E.fundamental_group(), twist = twist, act_to_right=False, print_tuple = E._print_tuple, category=E.Realizations()) + GroupSemidirectProduct.__init__(self, E.affine_weyl(), E.fundamental_group(), twist=twist, act_to_right=False, print_tuple=E._print_tuple, category=E.Realizations()) self._style = "WF" def _repr_(self): @@ -2506,7 +2506,7 @@ def __init__(self, E): def twist(g,w): return g.act_on_affine_weyl(w) - GroupSemidirectProduct.__init__(self, E.fundamental_group(), E.affine_weyl(), twist = twist, act_to_right=True, print_tuple = E._print_tuple, category=E.Realizations()) + GroupSemidirectProduct.__init__(self, E.fundamental_group(), E.affine_weyl(), twist=twist, act_to_right=True, print_tuple=E._print_tuple, category=E.Realizations()) self._style = "FW" def _repr_(self): @@ -2678,7 +2678,7 @@ def __init__(self, E): def twist(w,l): return E.exp_dual_lattice()(w.action(l.value)) - GroupSemidirectProduct.__init__(self, E.exp_dual_lattice(), E.dual_classical_weyl(), twist = twist, act_to_right=False, prefix0=E._prefixt, print_tuple = E._print_tuple, category=E.Realizations()) + GroupSemidirectProduct.__init__(self, E.exp_dual_lattice(), E.dual_classical_weyl(), twist=twist, act_to_right=False, prefix0=E._prefixt, print_tuple=E._print_tuple, category=E.Realizations()) self._style = "PvW0" def _repr_(self): @@ -2844,7 +2844,7 @@ def __init__(self, E): def twist(w,l): return E.exp_dual_lattice()(w.action(l.value)) - GroupSemidirectProduct.__init__(self, E.dual_classical_weyl(), E.exp_dual_lattice(), twist = twist, act_to_right=True, prefix1=E._prefixt, print_tuple = E._print_tuple, category=E.Realizations()) + GroupSemidirectProduct.__init__(self, E.dual_classical_weyl(), E.exp_dual_lattice(), twist=twist, act_to_right=True, prefix1=E._prefixt, print_tuple=E._print_tuple, category=E.Realizations()) self._style = "W0Pv" def _repr_(self): diff --git a/src/sage/combinat/root_system/fundamental_group.py b/src/sage/combinat/root_system/fundamental_group.py index 87b6e1094e0..f42acd0a44a 100644 --- a/src/sage/combinat/root_system/fundamental_group.py +++ b/src/sage/combinat/root_system/fundamental_group.py @@ -406,7 +406,7 @@ def leading_support(beta): EnumeratedSets())) else: cat = Groups().Commutative().Infinite() - Parent.__init__(self, category = cat) + Parent.__init__(self, category=cat) @cached_method def one(self): diff --git a/src/sage/combinat/root_system/hecke_algebra_representation.py b/src/sage/combinat/root_system/hecke_algebra_representation.py index 8ac99319bec..8de4bce6107 100644 --- a/src/sage/combinat/root_system/hecke_algebra_representation.py +++ b/src/sage/combinat/root_system/hecke_algebra_representation.py @@ -392,7 +392,7 @@ def Tw(self, word, signs=None, scalar=None): """ word = self.straighten_word(word) result = self._domain.module_morphism(functools.partial(self.on_basis, word=word, signs=signs, scalar=scalar), - codomain = self._domain) + codomain=self._domain) # For debugging purpose, make the parameters easily accessible: result.word = word result.signs = signs @@ -802,7 +802,7 @@ class CherednikOperatorsEigenvectors(UniqueRepresentation, SageObject): classical operators `T_1, \ldots, T_n` from `T` and `T_Y` coincide. """ - def __init__(self, T, T_Y = None, normalized = True): + def __init__(self, T, T_Y=None, normalized=True): r""" INPUT: diff --git a/src/sage/combinat/root_system/pieri_factors.py b/src/sage/combinat/root_system/pieri_factors.py index 14d78e3b3f4..e0e3053d8e3 100644 --- a/src/sage/combinat/root_system/pieri_factors.py +++ b/src/sage/combinat/root_system/pieri_factors.py @@ -175,7 +175,7 @@ def __iter__(self): """ return iter(self.elements()) - def generating_series(self, weight = None): + def generating_series(self, weight=None): r""" Return a length generating series for the elements of ``self``. @@ -755,7 +755,7 @@ def cardinality(self): if self._min_length == len(self._min_support) and self._max_length == len(self._max_support) -1: return Integer(2**(len(self._extra_support)) - 1) else: - return self.generating_series(weight = ConstantFunction(1)) + return self.generating_series(weight=ConstantFunction(1)) def generating_series(self, weight=None): r""" diff --git a/src/sage/combinat/root_system/plot.py b/src/sage/combinat/root_system/plot.py index ee23f9fe836..354ae0ca741 100644 --- a/src/sage/combinat/root_system/plot.py +++ b/src/sage/combinat/root_system/plot.py @@ -1404,7 +1404,7 @@ def cone(self, rays=[], lines=[], color="black", thickness=1, alpha=1, wireframe rays = [ ray for ray in rays if ray ] # Polyhedron does not accept yet zero rays # Build the polyhedron - p = Polyhedron(vertices=vertices, rays = rays) + p = Polyhedron(vertices=vertices, rays=rays) if as_polyhedron: return p @@ -1417,7 +1417,7 @@ def cone(self, rays=[], lines=[], color="black", thickness=1, alpha=1, wireframe q = q.translation(-center).dilation(ZZ(95)/ZZ(100)).translation(center) else: options = dict(wireframe=False, line={"thickness":thickness}) - result = q.plot(color = color, alpha=alpha, **options) + result = q.plot(color=color, alpha=alpha, **options) if label is not None: # Put the label on the vertex having largest z, then y, then x coordinate. vertices = sorted([vector(v) for v in q.vertices()], @@ -1489,7 +1489,7 @@ def reflection_hyperplane(self, coroot, as_polyhedron=False): text_label = "H_%s$" % (str(label)) else: text_label = "$H_{%s}$" % (latex(label)) - return self.cone(lines = basis, color = self.color(label), label=text_label, + return self.cone(lines=basis, color=self.color(label), label=text_label, as_polyhedron=as_polyhedron) diff --git a/src/sage/combinat/root_system/reflection_group_real.py b/src/sage/combinat/root_system/reflection_group_real.py index 8b230e27ee6..885e0ee549e 100644 --- a/src/sage/combinat/root_system/reflection_group_real.py +++ b/src/sage/combinat/root_system/reflection_group_real.py @@ -271,9 +271,9 @@ def __init__(self, W_types, index_set=None, hyperplane_index_set=None, reflectio cls = IrreducibleComplexReflectionGroup else: cls = ComplexReflectionGroup - cls.__init__(self, W_types, index_set = index_set, - hyperplane_index_set = hyperplane_index_set, - reflection_index_set = reflection_index_set) + cls.__init__(self, W_types, index_set=index_set, + hyperplane_index_set=hyperplane_index_set, + reflection_index_set=reflection_index_set) def _repr_(self): r""" 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 71059e21548..dcc3fa99d29 100644 --- a/src/sage/combinat/root_system/root_lattice_realization_algebras.py +++ b/src/sage/combinat/root_system/root_lattice_realization_algebras.py @@ -577,7 +577,7 @@ def demazure_lusztig_operators(self, q1, q2, convention="antidominant"): ....: T._test_relations(elements=elements) """ T_on_basis = functools.partial(self.demazure_lusztig_operator_on_basis, - q1 = q1, q2 = q2, convention = convention) + q1=q1, q2=q2, convention=convention) return HeckeAlgebraRepresentation(self, T_on_basis, self.cartan_type(), q1, q2, side="left") def demazure_lusztig_operator_on_classical_on_basis(self, weight, i, q, q1, q2, convention="antidominant"): @@ -1117,7 +1117,7 @@ def twisted_demazure_lusztig_operators(self, q1, q2, convention="antidominant"): T_on_basis, self.cartan_type().classical().dual().affine().dual(), q1, q2, - side = "left") + side="left") class ElementMethods: diff --git a/src/sage/combinat/root_system/root_lattice_realizations.py b/src/sage/combinat/root_system/root_lattice_realizations.py index faadbe3ea21..84a7b847f43 100644 --- a/src/sage/combinat/root_system/root_lattice_realizations.py +++ b/src/sage/combinat/root_system/root_lattice_realizations.py @@ -195,7 +195,7 @@ def __init_extra__(self): # Build and register the embeddings for domain in domains: domain.module_morphism(self.simple_root, - codomain = self + codomain=self ).register_as_coercion() if self.cartan_type().is_affine(): self._to_classical.register_as_conversion() @@ -693,7 +693,7 @@ def positive_roots(self, index_set=None): structure='graded', enumeration='breadth') @cached_method - def nonparabolic_positive_roots(self, index_set = None): + def nonparabolic_positive_roots(self, index_set=None): r""" Return the positive roots of ``self`` that are not in the parabolic subsystem indicated by ``index_set``. @@ -869,7 +869,7 @@ def positive_imaginary_roots(self): return F @cached_method - def positive_roots_by_height(self, increasing = True): + def positive_roots_by_height(self, increasing=True): r""" Returns a list of positive roots in increasing order by height. @@ -906,7 +906,7 @@ def positive_roots_by_height(self, increasing = True): return [x.element for x in roots] @cached_method - def positive_roots_parabolic(self, index_set = None): + def positive_roots_parabolic(self, index_set=None): r""" Return the set of positive roots for the parabolic subsystem with Dynkin node set ``index_set``. @@ -941,7 +941,7 @@ def parabolic_covers(alpha): structure='graded', enumeration='breadth') @cached_method - def positive_roots_nonparabolic(self, index_set = None): + def positive_roots_nonparabolic(self, index_set=None): r""" Returns the set of positive roots outside the parabolic subsystem with Dynkin node set ``index_set``. @@ -973,7 +973,7 @@ def positive_roots_nonparabolic(self, index_set = None): return [x for x in self.positive_roots() if not x.is_parabolic_root(index_set)] @cached_method - def positive_roots_nonparabolic_sum(self, index_set = None): + def positive_roots_nonparabolic_sum(self, index_set=None): r""" Returns the sum of positive roots outside the parabolic subsystem with Dynkin node set ``index_set``. @@ -1212,7 +1212,7 @@ def coroot_lattice(self): """ return self.root_system.coroot_lattice() - def coroot_space(self, base_ring = QQ): + def coroot_space(self, base_ring=QQ): r""" Return the coroot space over ``base_ring``. @@ -1229,7 +1229,7 @@ def coroot_space(self, base_ring = QQ): Coroot space over the Univariate Polynomial Ring in q over Rational Field of the Root system of type ['A', 2] """ - return self.root_system.coroot_space(base_ring = base_ring) + return self.root_system.coroot_space(base_ring=base_ring) def simple_coroot(self, i): """ @@ -1870,7 +1870,7 @@ def _to_classical(self): sage: L._to_classical(e[2]) (0, 0, 1) """ - return self.module_morphism(self._to_classical_on_basis, codomain = self.classical()) + return self.module_morphism(self._to_classical_on_basis, codomain=self.classical()) def _classical_alpha_0(self): """ @@ -2610,7 +2610,7 @@ def plot_fundamental_chamber(self, style="normal", **options): else: I = cartan_type.index_set() lines = [] - return plot_options.cone(rays = [Lambda[i] for i in I], + return plot_options.cone(rays=[Lambda[i] for i in I], lines=lines, color="lightgrey", alpha=.3) @@ -3562,7 +3562,7 @@ def associated_coroot(self): alphacheck[1] """ - def reflection(self, root, use_coroot = False): + def reflection(self, root, use_coroot=False): r""" Reflects ``self`` across the hyperplane orthogonal to ``root``. @@ -3665,7 +3665,7 @@ def descents(self, index_set=None, positive=False): index_set=self.parent().index_set() return [ i for i in index_set if self.has_descent(i, positive) ] - def to_dominant_chamber(self, index_set = None, positive = True, reduced_word = False): + def to_dominant_chamber(self, index_set=None, positive=True, reduced_word=False): r""" Returns the unique dominant element in the Weyl group orbit of the vector ``self``. @@ -3759,7 +3759,7 @@ def to_dominant_chamber(self, index_set = None, positive = True, reduced_word = direction.append(i) self = self.simple_reflection(i) - def reduced_word(self, index_set = None, positive = True): + def reduced_word(self, index_set=None, positive=True): r""" Returns a reduced word for the inverse of the shortest Weyl group element that sends the vector ``self`` into the dominant chamber. @@ -3778,9 +3778,9 @@ def reduced_word(self, index_set = None, positive = True): [2] """ - return self.to_dominant_chamber(index_set=index_set,positive=positive,reduced_word = True)[1] + return self.to_dominant_chamber(index_set=index_set,positive=positive,reduced_word=True)[1] - def is_dominant(self, index_set = None, positive = True): + def is_dominant(self, index_set=None, positive=True): r""" Returns whether self is dominant. diff --git a/src/sage/combinat/root_system/root_space.py b/src/sage/combinat/root_system/root_space.py index d4e6f8746d2..790b45f9606 100644 --- a/src/sage/combinat/root_system/root_space.py +++ b/src/sage/combinat/root_system/root_space.py @@ -64,9 +64,9 @@ def __init__(self, root_system, base_ring): self.root_system = root_system CombinatorialFreeModule.__init__(self, base_ring, root_system.index_set(), - prefix = "alphacheck" if root_system.dual_side else "alpha", - latex_prefix = "\\alpha^\\vee" if root_system.dual_side else "\\alpha", - category = RootLatticeRealizations(base_ring)) + prefix="alphacheck" if root_system.dual_side else "alpha", + latex_prefix="\\alpha^\\vee" if root_system.dual_side else "\\alpha", + category=RootLatticeRealizations(base_ring)) if base_ring is not ZZ: # Register the partial conversion back from ``self`` to the root lattice # See :meth:`_to_root_lattice` for tests @@ -139,7 +139,7 @@ def to_coroot_space_morphism(self): """ R = self.base_ring() C = self.cartan_type().symmetrizer().map(R) - return self.module_morphism(diagonal = C.__getitem__, + return self.module_morphism(diagonal=C.__getitem__, codomain=self.coroot_space(R)) def _to_root_lattice(self, x): @@ -228,7 +228,7 @@ def to_ambient_space_morphism(self): def basis_value(basis, i): return basis[i] - return self.module_morphism(on_basis = functools.partial(basis_value, basis) , codomain=L) + return self.module_morphism(on_basis=functools.partial(basis_value, basis) , codomain=L) class RootSpaceElement(CombinatorialFreeModule.Element): diff --git a/src/sage/combinat/root_system/root_system.py b/src/sage/combinat/root_system/root_system.py index fc84a35b4c1..82512778857 100644 --- a/src/sage/combinat/root_system/root_system.py +++ b/src/sage/combinat/root_system/root_system.py @@ -531,7 +531,7 @@ def coroot_space(self, base_ring=QQ): return self.dual.root_space(base_ring) @cached_method - def weight_lattice(self, extended = False): + def weight_lattice(self, extended=False): """ Returns the weight lattice associated to self. @@ -549,10 +549,10 @@ def weight_lattice(self, extended = False): sage: RootSystem(['A',3,1]).weight_space(extended = True) Extended weight space over the Rational Field of the Root system of type ['A', 3, 1] """ - return WeightSpace(self, ZZ, extended = extended) + return WeightSpace(self, ZZ, extended=extended) @cached_method - def weight_space(self, base_ring=QQ, extended = False): + def weight_space(self, base_ring=QQ, extended=False): """ Returns the weight space associated to self. @@ -570,9 +570,9 @@ def weight_space(self, base_ring=QQ, extended = False): sage: RootSystem(['A',3,1]).weight_space(extended = True) Extended weight space over the Rational Field of the Root system of type ['A', 3, 1] """ - return WeightSpace(self, base_ring, extended = extended) + return WeightSpace(self, base_ring, extended=extended) - def coweight_lattice(self, extended = False): + def coweight_lattice(self, extended=False): """ Returns the coweight lattice associated to self. @@ -592,9 +592,9 @@ def coweight_lattice(self, extended = False): sage: RootSystem(['A',3,1]).coweight_lattice(extended = True) Extended coweight lattice of the Root system of type ['A', 3, 1] """ - return self.dual.weight_lattice(extended = extended) + return self.dual.weight_lattice(extended=extended) - def coweight_space(self, base_ring=QQ, extended = False): + def coweight_space(self, base_ring=QQ, extended=False): """ Returns the coweight space associated to self. @@ -614,7 +614,7 @@ def coweight_space(self, base_ring=QQ, extended = False): sage: RootSystem(['A',3,1]).coweight_space(extended=True) Extended coweight space over the Rational Field of the Root system of type ['A', 3, 1] """ - return self.dual.weight_space(base_ring, extended = extended) + return self.dual.weight_space(base_ring, extended=extended) def ambient_lattice(self): r""" diff --git a/src/sage/combinat/root_system/type_Q.py b/src/sage/combinat/root_system/type_Q.py index a8884c8905a..e9a0e15d941 100644 --- a/src/sage/combinat/root_system/type_Q.py +++ b/src/sage/combinat/root_system/type_Q.py @@ -49,7 +49,7 @@ def __init__(self, m): assert m >= 2 CartanType_standard_finite.__init__(self, "Q", m-1) - def _repr_(self, compact = False): + def _repr_(self, compact=False): """ TESTS:: diff --git a/src/sage/combinat/root_system/type_affine.py b/src/sage/combinat/root_system/type_affine.py index b24f2d2afa5..db1daad875a 100644 --- a/src/sage/combinat/root_system/type_affine.py +++ b/src/sage/combinat/root_system/type_affine.py @@ -158,10 +158,10 @@ def sortkey(x): return (1 if isinstance(x, str) else 0, x) CombinatorialFreeModule.__init__(self, base_ring, basis_keys, - prefix = "e", - latex_prefix = "e", + prefix="e", + latex_prefix="e", sorting_key=sortkey, - category = WeightLatticeRealizations(base_ring)) + category=WeightLatticeRealizations(base_ring)) self._weight_space = self.root_system.weight_space(base_ring=base_ring,extended=True) self.classical().module_morphism(self.monomial, codomain=self).register_as_coercion() # Duplicated from ambient_space.AmbientSpace diff --git a/src/sage/combinat/root_system/type_dual.py b/src/sage/combinat/root_system/type_dual.py index 8922a4cd9ac..38d39b80b90 100644 --- a/src/sage/combinat/root_system/type_dual.py +++ b/src/sage/combinat/root_system/type_dual.py @@ -163,7 +163,7 @@ def __init__(self, type): _stable_abstract_classes = [ cartan_type.CartanType_simple] - def _repr_(self, compact = False): + def _repr_(self, compact=False): """ EXAMPLES:: diff --git a/src/sage/combinat/root_system/type_relabel.py b/src/sage/combinat/root_system/type_relabel.py index f37c6a724e6..624619db3fc 100644 --- a/src/sage/combinat/root_system/type_relabel.py +++ b/src/sage/combinat/root_system/type_relabel.py @@ -229,7 +229,7 @@ def _repr_(self, compact=False): return 'D4^3' return "['D', 4, 3]" relab = pformat(self._relabelling) - return self._type._repr_(compact = compact) + " relabelled by {}".format(relab) + return self._type._repr_(compact=compact) + " relabelled by {}".format(relab) 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 a088fd912c8..126a045327a 100644 --- a/src/sage/combinat/root_system/weight_lattice_realizations.py +++ b/src/sage/combinat/root_system/weight_lattice_realizations.py @@ -228,7 +228,7 @@ def __init_extra__(self): # Build and register the embeddings for domain in domains: domain.module_morphism(self.fundamental_weight, - codomain = self + codomain=self ).register_as_coercion() def _test_weight_lattice_realization(self, **options): @@ -813,7 +813,7 @@ def rho_classical(self): Lambda = self.fundamental_weights() return rho - Lambda[0] * rho.level() / Lambda[0].level() - def embed_at_level(self, x, level = 1): + def embed_at_level(self, x, level=1): r""" Embed the classical weight `x` in the level ``level`` hyperplane @@ -1065,7 +1065,7 @@ def symmetric_form(self, la): # assert( t == self.plus(t.scalar(alphac[i]) * Lambda[i] for i in self.index_set() ) ) # t = self.plus( t.scalar(alphac[i]) * c[i] * Lambda[i] for i in self.index_set() ) - def to_weight_space(self, base_ring = None): + def to_weight_space(self, base_ring=None): r""" Map ``self`` to the weight space. diff --git a/src/sage/combinat/root_system/weight_space.py b/src/sage/combinat/root_system/weight_space.py index 808067aef1f..9e700a26f5a 100644 --- a/src/sage/combinat/root_system/weight_space.py +++ b/src/sage/combinat/root_system/weight_space.py @@ -187,17 +187,17 @@ def sortkey(x): self.root_system = root_system CombinatorialFreeModule.__init__(self, base_ring, basis_keys, - prefix = "Lambdacheck" if root_system.dual_side else "Lambda", - latex_prefix = "\\Lambda^\\vee" if root_system.dual_side else "\\Lambda", + prefix="Lambdacheck" if root_system.dual_side else "Lambda", + latex_prefix="\\Lambda^\\vee" if root_system.dual_side else "\\Lambda", sorting_key=sortkey, - category = WeightLatticeRealizations(base_ring)) + category=WeightLatticeRealizations(base_ring)) if root_system.cartan_type().is_affine() and not extended: # For an affine type, register the quotient map from the # extended weight lattice/space to the weight lattice/space domain = root_system.weight_space(base_ring, extended=True) domain.module_morphism(self.fundamental_weight, - codomain = self + codomain=self ).register_as_coercion() def is_extended(self): @@ -451,7 +451,7 @@ def to_ambient_space_morphism(self): def basis_value(basis, i): return basis[i] - return self.module_morphism(on_basis = functools.partial(basis_value, basis), codomain=L) + return self.module_morphism(on_basis=functools.partial(basis_value, basis), codomain=L) class WeightSpaceElement(CombinatorialFreeModule.Element): diff --git a/src/sage/combinat/sidon_sets.py b/src/sage/combinat/sidon_sets.py index ec5038eb2c4..9ba6bdb5c71 100644 --- a/src/sage/combinat/sidon_sets.py +++ b/src/sage/combinat/sidon_sets.py @@ -16,7 +16,7 @@ from sage.rings.integer import Integer -def sidon_sets(N, g = 1): +def sidon_sets(N, g=1): r""" Return the set of all Sidon-`g` sets that have elements less than or equal to `N`. diff --git a/src/sage/combinat/skew_partition.py b/src/sage/combinat/skew_partition.py index dd66961a807..bd65d1ee5ff 100644 --- a/src/sage/combinat/skew_partition.py +++ b/src/sage/combinat/skew_partition.py @@ -1874,7 +1874,7 @@ def cardinality(self): return ZZ.one() if self.overlap > 0: - gg = Compositions(self.n, min_part = max(1, self.overlap)) + gg = Compositions(self.n, min_part=max(1, self.overlap)) else: gg = Compositions(self.n) @@ -1925,7 +1925,7 @@ def __iter__(self): sage: SkewPartitions(3, overlap=4).list() [] """ - for co in Compositions(self.n, min_part = max(1, self.overlap)): + for co in Compositions(self.n, min_part=max(1, self.overlap)): for sp in SkewPartitions(row_lengths=co, overlap=self.overlap): yield self.element_class(self, sp) diff --git a/src/sage/combinat/species/functorial_composition_species.py b/src/sage/combinat/species/functorial_composition_species.py index d97460e29e4..118e924d426 100644 --- a/src/sage/combinat/species/functorial_composition_species.py +++ b/src/sage/combinat/species/functorial_composition_species.py @@ -71,8 +71,7 @@ def _structures(self, structure_class, s): {{1, 2}*{3}, {1, 3}*{2}, {2, 3}*{1}}] """ gs = self._G.structures(s).list() - for f in self._F.structures(gs): - yield f + yield from self._F.structures(gs) def _isotypes(self, structure_class, s): """ diff --git a/src/sage/combinat/subset.py b/src/sage/combinat/subset.py index c27b1eb04ed..5a486b0f551 100644 --- a/src/sage/combinat/subset.py +++ b/src/sage/combinat/subset.py @@ -1130,8 +1130,7 @@ def __iter__(self): [1, 2, 2, 3]] """ for k in range(len(self._l) + 1): - for s in SubMultiset_sk(self._l, k): - yield s + yield from SubMultiset_sk(self._l, k) def __call__(self, el): r""" diff --git a/src/sage/combinat/subsets_pairwise.py b/src/sage/combinat/subsets_pairwise.py index fc64df2e48f..ed5613157f2 100644 --- a/src/sage/combinat/subsets_pairwise.py +++ b/src/sage/combinat/subsets_pairwise.py @@ -105,7 +105,7 @@ def __init__(self, ambient, predicate, maximal=False, element_class=Set_object_e # TODO: use self.element_class for consistency # At this point (2011/03) TestSuite fails if we do so self._element_class = element_class - RecursivelyEnumeratedSet_forest.__init__(self, algorithm = 'depth', category = FiniteEnumeratedSets()) + RecursivelyEnumeratedSet_forest.__init__(self, algorithm='depth', category=FiniteEnumeratedSets()) def __eq__(self, other): """ diff --git a/src/sage/combinat/tiling.py b/src/sage/combinat/tiling.py index 640f1c6d096..d3e194956cb 100644 --- a/src/sage/combinat/tiling.py +++ b/src/sage/combinat/tiling.py @@ -1220,8 +1220,7 @@ def isometric_copies(self, box, orientation_preserving=True, all_distinct_cano = self.canonical_isometric_copies(orientation_preserving, mod_box_isometries) for cano in all_distinct_cano: - for t in cano.translated_copies(box=box): - yield t + yield from cano.translated_copies(box=box) def isometric_copies_intersection(self, box, orientation_preserving=True): r""" diff --git a/src/sage/combinat/vector_partition.py b/src/sage/combinat/vector_partition.py index 03a142c8034..b9a6882d207 100644 --- a/src/sage/combinat/vector_partition.py +++ b/src/sage/combinat/vector_partition.py @@ -60,7 +60,7 @@ def find_min(vect): return min -def IntegerVectorsIterator(vect, min = None): +def IntegerVectorsIterator(vect, min=None): """ Return an iterator over the list of integer vectors which are componentwise less than or equal to ``vect``, and lexicographically greater than or equal @@ -161,7 +161,7 @@ def partition_at_vertex(self, i): sage: V.partition_at_vertex(1) [4, 2] """ - return Partition(sorted([vec[i] for vec in self._list], reverse = True)) + return Partition(sorted([vec[i] for vec in self._list], reverse=True)) class VectorPartitions(UniqueRepresentation, Parent): diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index d1aeb7c5b8a..b38241efc25 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -1731,8 +1731,7 @@ def left_special_factors_iterator(self, n=None): """ if n is None: for i in range(self.length()): - for w in self.left_special_factors_iterator(i): - yield w + yield from self.left_special_factors_iterator(i) else: left_extensions = defaultdict(set) for w in self.factor_iterator(n+1): @@ -1799,8 +1798,7 @@ def right_special_factors_iterator(self, n=None): """ if n is None: for i in range(self.length()): - for w in self.right_special_factors_iterator(i): - yield w + yield from self.right_special_factors_iterator(i) else: right_extensions = defaultdict(set) for w in self.factor_iterator(n+1): @@ -1890,8 +1888,7 @@ def bispecial_factors_iterator(self, n=None): """ if n is None: for i in range(self.length()): - for w in self.bispecial_factors_iterator(i): - yield w + yield from self.bispecial_factors_iterator(i) else: left_extensions = defaultdict(set) right_extensions = defaultdict(set) diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index 9c42e379cd4..2dba020eb34 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -1048,7 +1048,7 @@ def KolakoskiWord(self, alphabet=(1,2)): if a not in ZZ or a <= 0 or b not in ZZ or b <= 0 or a == b: msg = 'the alphabet (=%s) must consist of two distinct positive integers' % (alphabet,) raise ValueError(msg) - return InfiniteWords(alphabet)(self._KolakoskiWord_iterator(a, b), datatype = 'iter') + return InfiniteWords(alphabet)(self._KolakoskiWord_iterator(a, b), datatype='iter') def _KolakoskiWord_iterator(self, a=1, b=2): r""" diff --git a/src/sage/combinat/yang_baxter_graph.py b/src/sage/combinat/yang_baxter_graph.py index 426095f6332..7b05bc68337 100644 --- a/src/sage/combinat/yang_baxter_graph.py +++ b/src/sage/combinat/yang_baxter_graph.py @@ -665,8 +665,7 @@ def __iter__(self): sage: list(Y.__iter__()) [(1, 0, 2, 1, 0), (1, 2, 0, 1, 0), (1, 2, 1, 0, 0), (2, 1, 0, 1, 0), (2, 1, 1, 0, 0)] """ - for v in self._vertex_ordering: - yield v + yield from self._vertex_ordering def _swap_operator(self, operator, u): r""" diff --git a/src/sage/crypto/cipher.py b/src/sage/crypto/cipher.py index 32c06571483..6d6ed6dd2b3 100644 --- a/src/sage/crypto/cipher.py +++ b/src/sage/crypto/cipher.py @@ -73,7 +73,7 @@ class PublicKeyCipher(Cipher): """ Public key cipher class """ - def __init__(self, parent, key, public = True): + def __init__(self, parent, key, public=True): """ Create a public key cipher diff --git a/src/sage/crypto/classical_cipher.py b/src/sage/crypto/classical_cipher.py index 72ea18a3117..2d5722b04df 100644 --- a/src/sage/crypto/classical_cipher.py +++ b/src/sage/crypto/classical_cipher.py @@ -503,7 +503,7 @@ def __init__(self, parent, key): raise ValueError("key (= %s) must have block length %s" % (key, n)) SymmetricKeyCipher.__init__(self, parent, key) - def __call__(self, M, mode = "ECB"): + def __call__(self, M, mode="ECB"): S = self.domain() # = plaintext_space = ciphertext_space if not isinstance(M, StringMonoidElement) and M.parent() == S: raise TypeError("Argument M (= %s) must be a string in the plaintext space." % M) @@ -555,7 +555,7 @@ def __init__(self, parent, key): """ SymmetricKeyCipher.__init__(self, parent, key) - def __call__(self, M, mode = "ECB"): + def __call__(self, M, mode="ECB"): S = self.domain() # = plaintext_space = ciphertext_space if not isinstance(M, StringMonoidElement) and M.parent() == S: raise TypeError("Argument M (= %s) must be a string in the plaintext space." % M) diff --git a/src/sage/crypto/mq/sr.py b/src/sage/crypto/mq/sr.py index b00952486de..a79b0868175 100644 --- a/src/sage/crypto/mq/sr.py +++ b/src/sage/crypto/mq/sr.py @@ -1091,7 +1091,7 @@ def random_vector(self, *args, **kwds): """ return self.vector(self.random_state_array(*args, **kwds)) - def random_element(self, elem_type = "vector", *args, **kwds): + def random_element(self, elem_type="vector", *args, **kwds): """ Return a random element for self. Other arguments and keywords are passed to random_* methods. @@ -1569,7 +1569,7 @@ def varstr(self, name, nr, rc, e): format_string = self.varformatstr(name, self.n, self.r*self.c, self.e) return format_string % (nr, rc, e) - def varstrs(self, name, nr, rc = None, e = None): + def varstrs(self, name, nr, rc=None, e=None): """ Return a list of strings representing variables in ``self``. @@ -2284,7 +2284,7 @@ def shift_rows_matrix(self): return shift_rows - def lin_matrix(self, length = None): + def lin_matrix(self, length=None): """ Return the ``Lin`` matrix. @@ -3051,7 +3051,7 @@ def inversion_polynomials_single_sbox(self, x=None, w=None, biaffine_only=None, return l - def _inversion_polynomials_single_sbox(self, x= None, w=None, biaffine_only=None, correct_only=None): + def _inversion_polynomials_single_sbox(self, x=None, w=None, biaffine_only=None, correct_only=None): """ Generate inversion polynomials of a single S-box. diff --git a/src/sage/crypto/stream.py b/src/sage/crypto/stream.py index 8526aca4c44..71d8ffb9a21 100644 --- a/src/sage/crypto/stream.py +++ b/src/sage/crypto/stream.py @@ -28,7 +28,7 @@ class LFSRCryptosystem(SymmetricKeyCryptosystem): """ Linear feedback shift register cryptosystem class """ - def __init__(self, field = None): + def __init__(self, field=None): """ Create a linear feedback shift cryptosystem. diff --git a/src/sage/crypto/stream_cipher.py b/src/sage/crypto/stream_cipher.py index 07a9bf08251..198e93d9216 100644 --- a/src/sage/crypto/stream_cipher.py +++ b/src/sage/crypto/stream_cipher.py @@ -61,9 +61,9 @@ def __init__(self, parent, poly, IS): sage: E == loads(dumps(E)) True """ - SymmetricKeyCipher.__init__(self, parent, key = (poly, IS)) + SymmetricKeyCipher.__init__(self, parent, key=(poly, IS)) - def __call__(self, M, mode = "ECB"): + def __call__(self, M, mode="ECB"): r""" Generate key stream from the binary string ``M``. @@ -179,7 +179,7 @@ def __init__(self, parent, e1, e2): raise TypeError("Argument e1 (= %s) must be a LFSR cipher." % e1) if not isinstance(e2, LFSRCipher): raise TypeError("Argument e2 (= %s) must be a LFSR cipher." % e2) - SymmetricKeyCipher.__init__(self, parent, key = (e1, e2)) + SymmetricKeyCipher.__init__(self, parent, key=(e1, e2)) def keystream_cipher(self): """ @@ -221,7 +221,7 @@ def decimating_cipher(self): """ return self.key()[1] - def __call__(self, M, mode = "ECB"): + def __call__(self, M, mode="ECB"): r""" INPUT: diff --git a/src/sage/databases/oeis.py b/src/sage/databases/oeis.py index 8dfe567a810..368ee80e120 100644 --- a/src/sage/databases/oeis.py +++ b/src/sage/databases/oeis.py @@ -1481,9 +1481,8 @@ def __iter__(self): sage: s = oeis._imaginary_sequence(ident='A999991', keywords='sign,full') sage: for i in s: pass """ - for x in self.first_terms(): - yield x - if not self.is_full() is True: + yield from self.first_terms() + if self.is_full() is not True: raise LookupError("future values not provided by OEIS") def references(self): diff --git a/src/sage/games/sudoku.py b/src/sage/games/sudoku.py index 2d2a2b36ab3..abcadd08ca3 100644 --- a/src/sage/games/sudoku.py +++ b/src/sage/games/sudoku.py @@ -719,8 +719,7 @@ def backtrack(self): """ from .sudoku_backtrack import backtrack_all solutions = backtrack_all(self.n, self.puzzle) - for soln in solutions: - yield soln + yield from solutions def dlx(self, count_only=False): r""" diff --git a/src/sage/graphs/all.py b/src/sage/graphs/all.py index edb920f6897..2cbc65d0e23 100644 --- a/src/sage/graphs/all.py +++ b/src/sage/graphs/all.py @@ -4,7 +4,7 @@ lazy_import("sage.graphs.graph_generators", "graphs") lazy_import("sage.graphs.digraph_generators", "digraphs") lazy_import("sage.graphs.hypergraph_generators", "hypergraphs") -from .graph_database import GraphDatabase, GenericGraphQuery, GraphQuery +lazy_import("sage.graphs.graph_database", ["GraphDatabase", "GenericGraphQuery", "GraphQuery"]) from .graph import Graph from .digraph import DiGraph from .bipartite_graph import BipartiteGraph @@ -13,7 +13,7 @@ import sage.graphs.partial_cube from . import graph_list as graphs_list lazy_import("sage.graphs", "graph_coloring") -from .graph_database import graph_db_info +lazy_import("sage.graphs.graph_database", "graph_db_info") lazy_import("sage.graphs.graph_editor", "graph_editor") from sage.graphs.isgci import graph_classes diff --git a/src/sage/graphs/base/boost_graph.pyx b/src/sage/graphs/base/boost_graph.pyx index 22a6f4e5ba4..d6508f172f8 100644 --- a/src/sage/graphs/base/boost_graph.pyx +++ b/src/sage/graphs/base/boost_graph.pyx @@ -572,7 +572,7 @@ cpdef bandwidth_heuristics(g, algorithm='cuthill_mckee'): from sage.graphs.base.boost_graph import bandwidth_heuristics sage: bandwidth_heuristics(Graph()) (0, []) - sage: bandwidth_heuristics(graphs.RandomGNM(10,0)) + sage: bandwidth_heuristics(graphs.RandomGNM(10,0)) # optional - networkx (0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) """ @@ -1964,8 +1964,8 @@ cpdef diameter_DHV(g, weight_function=None, check_weight=True): TESTS:: - sage: G = graphs.RandomBarabasiAlbert(17,6) - sage: diameter_DHV(G) == G.diameter(algorithm = 'Dijkstra_Boost') + sage: G = graphs.RandomBarabasiAlbert(17,6) # optional - networkx + sage: diameter_DHV(G) == G.diameter(algorithm = 'Dijkstra_Boost') # optional - networkx True sage: G = Graph([(0,1,-1)], weighted=True) sage: diameter_DHV(G) diff --git a/src/sage/graphs/base/c_graph.pyx b/src/sage/graphs/base/c_graph.pyx index 83a01eb4f9b..d6fb119d3cf 100644 --- a/src/sage/graphs/base/c_graph.pyx +++ b/src/sage/graphs/base/c_graph.pyx @@ -1577,11 +1577,11 @@ cdef class CGraphBackend(GenericGraphBackend): We check that the bug described in :trac:`8406` is gone:: sage: G = Graph() - sage: R. = GF(3**3) - sage: S. = R[] - sage: G.add_vertex(a**2) - sage: G.add_vertex(x) - sage: G.vertices(sort=True) + sage: R. = GF(3**3) # optional - sage.rings.finite_rings + sage: S. = R[] # optional - sage.rings.finite_rings + sage: G.add_vertex(a**2) # optional - sage.rings.finite_rings + sage: G.add_vertex(x) # optional - sage.rings.finite_rings + sage: G.vertices(sort=True) # optional - sage.rings.finite_rings [a^2, x] And that the bug described in :trac:`9610` is gone:: @@ -2107,9 +2107,9 @@ cdef class CGraphBackend(GenericGraphBackend): Ensure that :trac:`13664` is fixed :: - sage: W = WeylGroup(["A",1]) - sage: G = W.cayley_graph() - sage: Graph(G).degree() + sage: W = WeylGroup(["A",1]) # optional - sage.combinat sage.groups + sage: G = W.cayley_graph() # optional - sage.combinat sage.groups + sage: Graph(G).degree() # optional - sage.combinat sage.groups [1, 1] sage: h = Graph() sage: h.add_edge(1,2,"a") @@ -4406,9 +4406,9 @@ cdef class CGraphBackend(GenericGraphBackend): TESTS:: - sage: P = posets.PentagonPoset() - sage: H = P._hasse_diagram - sage: H._backend.is_connected() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: H = P._hasse_diagram # optional - sage.modules + sage: H._backend.is_connected() # optional - sage.modules True """ cdef int v_int @@ -4589,9 +4589,9 @@ cdef class CGraphBackend(GenericGraphBackend): TESTS:: - sage: m = Matrix(3,[0, 1, 1, 0, 0, 0, 0, 1, 0]) - sage: g = DiGraph(m) - sage: g.is_directed_acyclic(certificate=True) + sage: m = Matrix(3,[0, 1, 1, 0, 0, 0, 0, 1, 0]) # optional - sage.modules + sage: g = DiGraph(m) # optional - sage.modules + sage: g.is_directed_acyclic(certificate=True) # optional - sage.modules (True, [0, 2, 1]) """ if not self._directed: diff --git a/src/sage/graphs/base/static_sparse_backend.pyx b/src/sage/graphs/base/static_sparse_backend.pyx index c380777c0e7..a8de583d4db 100644 --- a/src/sage/graphs/base/static_sparse_backend.pyx +++ b/src/sage/graphs/base/static_sparse_backend.pyx @@ -446,17 +446,17 @@ cdef class StaticSparseBackend(CGraphBackend): :: - sage: g = DiGraph(digraphs.DeBruijn(4, 3), data_structure="static_sparse") - sage: gi = DiGraph(g, data_structure="static_sparse") - sage: gi.edges(sort=True)[0] + sage: g = DiGraph(digraphs.DeBruijn(4, 3), data_structure="static_sparse") # optional - sage.combinat + sage: gi = DiGraph(g, data_structure="static_sparse") # optional - sage.combinat + sage: gi.edges(sort=True)[0] # optional - sage.combinat ('000', '000', '0') - sage: sorted(gi.edges_incident('111')) + sage: sorted(gi.edges_incident('111')) # optional - sage.combinat [('111', '110', '0'), ('111', '111', '1'), ('111', '112', '2'), ('111', '113', '3')] - sage: set(g.edges(sort=False)) == set(gi.edges(sort=False)) + sage: set(g.edges(sort=False)) == set(gi.edges(sort=False)) # optional - sage.combinat True :: @@ -671,10 +671,10 @@ cdef class StaticSparseBackend(CGraphBackend): :: sage: from sage.graphs.base.static_sparse_backend import StaticSparseBackend - sage: g = StaticSparseBackend(digraphs.DeBruijn(3, 2)) - sage: g.has_edge('00', '01', '1') + sage: g = StaticSparseBackend(digraphs.DeBruijn(3, 2)) # optional - sage.combinat + sage: g.has_edge('00', '01', '1') # optional - sage.combinat True - sage: g.has_edge('00', '01', '0') + sage: g.has_edge('00', '01', '0') # optional - sage.combinat False """ try: diff --git a/src/sage/graphs/bipartite_graph.py b/src/sage/graphs/bipartite_graph.py index 9b843ca965e..86b6f4bba15 100644 --- a/src/sage/graphs/bipartite_graph.py +++ b/src/sage/graphs/bipartite_graph.py @@ -47,6 +47,9 @@ from sage.rings.integer import Integer from sage.misc.decorators import rename_keyword from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import + +lazy_import('networkx', ['MultiGraph', 'Graph'], as_=['networkx_MultiGraph', 'networkx_Graph']) class BipartiteGraph(Graph): @@ -195,16 +198,16 @@ class BipartiteGraph(Graph): #. From a reduced adjacency matrix:: - sage: M = Matrix([(1,1,1,0,0,0,0), (1,0,0,1,1,0,0), + sage: M = Matrix([(1,1,1,0,0,0,0), (1,0,0,1,1,0,0), # optional - sage.modules ....: (0,1,0,1,0,1,0), (1,1,0,1,0,0,1)]) - sage: M + sage: M # optional - sage.modules [1 1 1 0 0 0 0] [1 0 0 1 1 0 0] [0 1 0 1 0 1 0] [1 1 0 1 0 0 1] - sage: H = BipartiteGraph(M); H + sage: H = BipartiteGraph(M); H # optional - sage.modules Bipartite graph on 11 vertices - sage: H.edges(sort=True) + sage: H.edges(sort=True) # optional - sage.modules [(0, 7, None), (0, 8, None), (0, 10, None), @@ -221,9 +224,9 @@ class BipartiteGraph(Graph): :: - sage: M = Matrix([(1, 1, 2, 0, 0), (0, 2, 1, 1, 1), (0, 1, 2, 1, 1)]) - sage: B = BipartiteGraph(M, multiedges=True, sparse=True) - sage: B.edges(sort=True) + sage: M = Matrix([(1, 1, 2, 0, 0), (0, 2, 1, 1, 1), (0, 1, 2, 1, 1)]) # optional - sage.modules + sage: B = BipartiteGraph(M, multiedges=True, sparse=True) # optional - sage.modules + sage: B.edges(sort=True) # optional - sage.modules [(0, 5, None), (1, 5, None), (1, 6, None), @@ -241,13 +244,13 @@ class BipartiteGraph(Graph): :: - sage: F. = GF(4) - sage: MS = MatrixSpace(F, 2, 3) - sage: M = MS.matrix([[0, 1, a + 1], [a, 1, 1]]) - sage: B = BipartiteGraph(M, weighted=True, sparse=True) - sage: B.edges(sort=True) + sage: F. = GF(4) # optional - sage.modules sage.rings.finite_rings + sage: MS = MatrixSpace(F, 2, 3) # optional - sage.modules sage.rings.finite_rings + sage: M = MS.matrix([[0, 1, a + 1], [a, 1, 1]]) # optional - sage.modules sage.rings.finite_rings + sage: B = BipartiteGraph(M, weighted=True, sparse=True) # optional - sage.modules sage.rings.finite_rings + sage: B.edges(sort=True) # optional - sage.modules sage.rings.finite_rings [(0, 4, a), (1, 3, 1), (1, 4, 1), (2, 3, a + 1), (2, 4, 1)] - sage: B.weighted() + sage: B.weighted() # optional - sage.modules sage.rings.finite_rings True #. From an alist file:: @@ -261,7 +264,7 @@ class BipartiteGraph(Graph): ....: 1 2 4 7 \n") ....: f.flush() ....: B = BipartiteGraph(f.name) - sage: B.is_isomorphic(H) + sage: B.is_isomorphic(H) # optional - sage.modules True #. From a ``graph6`` string:: @@ -325,15 +328,15 @@ class BipartiteGraph(Graph): Ensure that we can construct a ``BipartiteGraph`` with isolated vertices via the reduced adjacency matrix (:trac:`10356`):: - sage: a = BipartiteGraph(matrix(2, 2, [1, 0, 1, 0])) - sage: a + sage: a = BipartiteGraph(matrix(2, 2, [1, 0, 1, 0])) # optional - sage.modules + sage: a # optional - sage.modules Bipartite graph on 4 vertices - sage: a.vertices(sort=True) + sage: a.vertices(sort=True) # optional - sage.modules [0, 1, 2, 3] - sage: g = BipartiteGraph(matrix(4, 4, [1] * 4 + [0] * 12)) - sage: g.vertices(sort=True) + sage: g = BipartiteGraph(matrix(4, 4, [1] * 4 + [0] * 12)) # optional - sage.modules + sage: g.vertices(sort=True) # optional - sage.modules [0, 1, 2, 3, 4, 5, 6, 7] - sage: sorted(g.left.union(g.right)) + sage: sorted(g.left.union(g.right)) # optional - sage.modules [0, 1, 2, 3, 4, 5, 6, 7] Make sure that loops are not allowed (:trac:`23275`):: @@ -504,8 +507,7 @@ def __init__(self, data=None, partition=None, check=True, hash_labels=None, *arg if len(left) + len(right) != self.num_verts(): raise ValueError("not all vertices appear in partition") - import networkx - if isinstance(data, (networkx.MultiGraph, networkx.Graph)): + if isinstance(data, (networkx_MultiGraph, networkx_Graph)): if hasattr(data, "node_type"): # Assume the graph is bipartite self.left = set() @@ -1289,10 +1291,10 @@ def is_bipartite(self, certificate=False): EXAMPLES:: - sage: g = BipartiteGraph(graphs.RandomBipartite(3, 3, .5)) - sage: g.is_bipartite() + sage: g = BipartiteGraph(graphs.RandomBipartite(3, 3, .5)) # optional - numpy + sage: g.is_bipartite() # optional - numpy True - sage: g.is_bipartite(certificate=True) # random + sage: g.is_bipartite(certificate=True) # random # optional - numpy (True, {(0, 0): 0, (0, 1): 0, (0, 2): 0, (1, 0): 1, (1, 1): 1, (1, 2): 1}) TESTS:: @@ -1625,7 +1627,7 @@ def perfect_matchings(self, labels=False): sage: B = BipartiteGraph(graphs.CompleteBipartiteGraph(4, 4)) sage: len(list(B.perfect_matchings())) 24 - sage: B.matching_polynomial(algorithm='rook')(0) + sage: B.matching_polynomial(algorithm='rook')(0) # optional - sage.modules 24 TESTS:: @@ -1701,8 +1703,7 @@ def rec(G): # For each unlabeled matching, we yield all its possible labelings for m in rec(G): - for pm in itertools.product(*[edges[frozenset(e)] for e in m]): - yield pm + yield from itertools.product(*[edges[frozenset(e)] for e in m]) def load_afile(self, fname): r""" @@ -1803,26 +1804,26 @@ def save_afile(self, fname): EXAMPLES:: - sage: M = Matrix([(1,1,1,0,0,0,0), (1,0,0,1,1,0,0), + sage: M = Matrix([(1,1,1,0,0,0,0), (1,0,0,1,1,0,0), # optional - sage.modules ....: (0,1,0,1,0,1,0), (1,1,0,1,0,0,1)]) - sage: M + sage: M # optional - sage.modules [1 1 1 0 0 0 0] [1 0 0 1 1 0 0] [0 1 0 1 0 1 0] [1 1 0 1 0 0 1] - sage: b = BipartiteGraph(M) - sage: import tempfile - sage: with tempfile.NamedTemporaryFile() as f: + sage: b = BipartiteGraph(M) # optional - sage.modules + sage: import tempfile # optional - sage.modules + sage: with tempfile.NamedTemporaryFile() as f: # optional - sage.modules ....: b.save_afile(f.name) ....: b2 = BipartiteGraph(f.name) - sage: b.is_isomorphic(b2) + sage: b.is_isomorphic(b2) # optional - sage.modules True TESTS:: sage: import tempfile sage: f = tempfile.NamedTemporaryFile() - sage: for order in range(3, 13, 3): + sage: for order in range(3, 13, 3): # optional - sage.combinat ....: num_chks = int(order / 3) ....: num_vars = order - num_chks ....: partition = (list(range(num_vars)), list(range(num_vars, num_vars+num_chks))) @@ -1920,78 +1921,78 @@ def reduced_adjacency_matrix(self, sparse=True, *, base_ring=None, **kwds): Bipartite graphs that are not weighted will return a matrix over ZZ, unless a base ring is specified:: - sage: M = Matrix([(1,1,1,0,0,0,0), (1,0,0,1,1,0,0), + sage: M = Matrix([(1,1,1,0,0,0,0), (1,0,0,1,1,0,0), # optional - sage.modules ....: (0,1,0,1,0,1,0), (1,1,0,1,0,0,1)]) - sage: B = BipartiteGraph(M) - sage: N = B.reduced_adjacency_matrix() - sage: N + sage: B = BipartiteGraph(M) # optional - sage.modules + sage: N = B.reduced_adjacency_matrix() # optional - sage.modules + sage: N # optional - sage.modules [1 1 1 0 0 0 0] [1 0 0 1 1 0 0] [0 1 0 1 0 1 0] [1 1 0 1 0 0 1] - sage: N == M + sage: N == M # optional - sage.modules True - sage: N[0,0].parent() + sage: N[0,0].parent() # optional - sage.modules Integer Ring - sage: N2 = B.reduced_adjacency_matrix(base_ring=RDF); N2 + sage: N2 = B.reduced_adjacency_matrix(base_ring=RDF); N2 # optional - sage.modules [1.0 1.0 1.0 0.0 0.0 0.0 0.0] [1.0 0.0 0.0 1.0 1.0 0.0 0.0] [0.0 1.0 0.0 1.0 0.0 1.0 0.0] [1.0 1.0 0.0 1.0 0.0 0.0 1.0] - sage: N2[0, 0].parent() + sage: N2[0, 0].parent() # optional - sage.modules Real Double Field Multi-edge graphs also return a matrix over ZZ, unless a base ring is specified:: - sage: M = Matrix([(1,1,2,0,0), (0,2,1,1,1), (0,1,2,1,1)]) - sage: B = BipartiteGraph(M, multiedges=True, sparse=True) - sage: N = B.reduced_adjacency_matrix() - sage: N == M + sage: M = Matrix([(1,1,2,0,0), (0,2,1,1,1), (0,1,2,1,1)]) # optional - sage.modules + sage: B = BipartiteGraph(M, multiedges=True, sparse=True) # optional - sage.modules + sage: N = B.reduced_adjacency_matrix() # optional - sage.modules + sage: N == M # optional - sage.modules True - sage: N[0,0].parent() + sage: N[0,0].parent() # optional - sage.modules Integer Ring - sage: N2 = B.reduced_adjacency_matrix(base_ring=RDF) - sage: N2[0, 0].parent() + sage: N2 = B.reduced_adjacency_matrix(base_ring=RDF) # optional - sage.modules + sage: N2[0, 0].parent() # optional - sage.modules Real Double Field Weighted graphs will return a matrix over the ring given by their (first) weights, unless a base ring is specified:: - sage: F. = GF(4) - sage: MS = MatrixSpace(F, 2, 3) - sage: M = MS.matrix([[0, 1, a+1], [a, 1, 1]]) - sage: B = BipartiteGraph(M, weighted=True, sparse=True) - sage: N = B.reduced_adjacency_matrix(sparse=False) - sage: N == M + sage: F. = GF(4) # optional - sage.modules sage.rings.finite_rings + sage: MS = MatrixSpace(F, 2, 3) # optional - sage.modules sage.rings.finite_rings + sage: M = MS.matrix([[0, 1, a+1], [a, 1, 1]]) # optional - sage.modules sage.rings.finite_rings + sage: B = BipartiteGraph(M, weighted=True, sparse=True) # optional - sage.modules sage.rings.finite_rings + sage: N = B.reduced_adjacency_matrix(sparse=False) # optional - sage.modules sage.rings.finite_rings + sage: N == M # optional - sage.modules sage.rings.finite_rings True - sage: N[0,0].parent() + sage: N[0,0].parent() # optional - sage.modules sage.rings.finite_rings Finite Field in a of size 2^2 - sage: N2 = B.reduced_adjacency_matrix(base_ring=F) - sage: N2[0, 0].parent() + sage: N2 = B.reduced_adjacency_matrix(base_ring=F) # optional - sage.modules sage.rings.finite_rings + sage: N2[0, 0].parent() # optional - sage.modules sage.rings.finite_rings Finite Field in a of size 2^2 TESTS:: sage: B = BipartiteGraph() - sage: B.reduced_adjacency_matrix() + sage: B.reduced_adjacency_matrix() # optional - sage.modules [] - sage: M = Matrix([[0,0], [0,0]]) - sage: BipartiteGraph(M).reduced_adjacency_matrix() == M + sage: M = Matrix([[0,0], [0,0]]) # optional - sage.modules + sage: BipartiteGraph(M).reduced_adjacency_matrix() == M # optional - sage.modules True - sage: M = Matrix([[10,2/3], [0,0]]) - sage: B = BipartiteGraph(M, weighted=True, sparse=True) - sage: M == B.reduced_adjacency_matrix() + sage: M = Matrix([[10,2/3], [0,0]]) # optional - sage.modules + sage: B = BipartiteGraph(M, weighted=True, sparse=True) # optional - sage.modules + sage: M == B.reduced_adjacency_matrix() # optional - sage.modules True An error is raised if the specified base ring is not compatible with the type of the weights of the bipartite graph:: - sage: F. = GF(4) - sage: MS = MatrixSpace(F, 2, 3) - sage: M = MS.matrix([[0, 1, a+1], [a, 1, 1]]) - sage: B = BipartiteGraph(M, weighted=True, sparse=True) - sage: B.reduced_adjacency_matrix(base_ring=RDF) + sage: F. = GF(4) # optional - sage.modules sage.rings.finite_rings + sage: MS = MatrixSpace(F, 2, 3) # optional - sage.modules sage.rings.finite_rings + sage: M = MS.matrix([[0, 1, a+1], [a, 1, 1]]) # optional - sage.modules sage.rings.finite_rings + sage: B = BipartiteGraph(M, weighted=True, sparse=True) # optional - sage.modules sage.rings.finite_rings + sage: B.reduced_adjacency_matrix(base_ring=RDF) # optional - sage.modules sage.rings.finite_rings Traceback (most recent call last): ... TypeError: float() argument must be a string or a ...number, not 'sage.rings.finite_rings.element_givaro.FiniteField_givaroElement' @@ -2097,7 +2098,7 @@ class :class:`MixedIntegerLinearProgram Maximum matching in a cycle graph:: sage: G = BipartiteGraph(graphs.CycleGraph(10)) - sage: G.matching() + sage: G.matching() # optional - networkx [(0, 1, None), (2, 3, None), (4, 5, None), (6, 7, None), (8, 9, None)] The size of a maximum matching in a complete bipartite graph using @@ -2124,7 +2125,7 @@ class :class:`MixedIntegerLinearProgram sage: B = BipartiteGraph([(u,v,2) for u,v in G.edges(sort=True, labels=0)]) sage: sorted(B.matching(use_edge_labels=True)) [(0, 3, 2), (1, 2, 2)] - sage: B.matching(use_edge_labels=True, value_only=True) + sage: B.matching(use_edge_labels=True, value_only=True) # optional - networkx 4 sage: B.matching(use_edge_labels=True, value_only=True, algorithm='Edmonds') 4 @@ -2138,9 +2139,9 @@ class :class:`MixedIntegerLinearProgram Traceback (most recent call last): ... ValueError: use_edge_labels cannot be used with "Hopcroft-Karp" or "Eppstein" - sage: B.matching(use_edge_labels=False, value_only=True, algorithm='Hopcroft-Karp') + sage: B.matching(use_edge_labels=False, value_only=True, algorithm='Hopcroft-Karp') # optional - networkx 2 - sage: B.matching(use_edge_labels=False, value_only=True, algorithm='Eppstein') + sage: B.matching(use_edge_labels=False, value_only=True, algorithm='Eppstein') # optional - networkx 2 sage: B.matching(use_edge_labels=False, value_only=True, algorithm='Edmonds') 2 @@ -2284,9 +2285,9 @@ def vertex_cover(self, algorithm="Konig", value_only=False, On the Cycle Graph:: sage: B = BipartiteGraph(graphs.CycleGraph(6)) - sage: len(B.vertex_cover()) + sage: len(B.vertex_cover()) # optional - networkx 3 - sage: B.vertex_cover(value_only=True) + sage: B.vertex_cover(value_only=True) # optional - networkx 3 The two algorithms should return the same result:: diff --git a/src/sage/graphs/bliss.pyx b/src/sage/graphs/bliss.pyx index 86af7ea988e..24e32c35a7c 100644 --- a/src/sage/graphs/bliss.pyx +++ b/src/sage/graphs/bliss.pyx @@ -479,11 +479,11 @@ cpdef canonical_form(G, partition=None, return_graph=False, use_edge_labels=True Check that it works with non hashable non sortable edge labels (relying on string representations of the labels):: - sage: g1 = Graph([(0, 1, matrix(ZZ, 2)), (0, 2, RDF.pi()), (1, 2, 'a')]) - sage: g2 = Graph([(1, 2, matrix(ZZ, 2)), (2, 0, RDF.pi()), (0, 1, 'a')]) - sage: g1can = canonical_form(g1, use_edge_labels=True) # optional - bliss - sage: g2can = canonical_form(g2, use_edge_labels=True) # optional - bliss - sage: g1can == g2can # optional - bliss + sage: g1 = Graph([(0, 1, matrix(ZZ, 2)), (0, 2, RDF.pi()), (1, 2, 'a')]) # optional - sage.modules + sage: g2 = Graph([(1, 2, matrix(ZZ, 2)), (2, 0, RDF.pi()), (0, 1, 'a')]) # optional - sage.modules + sage: g1can = canonical_form(g1, use_edge_labels=True) # optional - bliss sage.modules + sage: g2can = canonical_form(g2, use_edge_labels=True) # optional - bliss sage.modules + sage: g1can == g2can # optional - bliss sage.modules True Check that :trac:`32395` is fixed:: diff --git a/src/sage/graphs/centrality.pyx b/src/sage/graphs/centrality.pyx index 91f0fc21a52..9de214115f9 100755 --- a/src/sage/graphs/centrality.pyx +++ b/src/sage/graphs/centrality.pyx @@ -99,11 +99,11 @@ def centrality_betweenness(G, bint exact=False, bint normalize=True): Compare with NetworkX:: - sage: import networkx # optional - networkx - sage: g = graphs.RandomGNP(100, .2) # optional - networkx - sage: nw = networkx.betweenness_centrality(g.networkx_graph()) # optional - networkx - sage: sg = centrality_betweenness(g) # optional - networkx - sage: max(abs(nw[x] - sg[x]) for x in g) # abs tol 1e-10 # optional - networkx + sage: import networkx # optional - networkx + sage: g = graphs.RandomGNP(100, .2) # optional - networkx + sage: nw = networkx.betweenness_centrality(g.networkx_graph()) # optional - networkx + sage: sg = centrality_betweenness(g) # optional - networkx + sage: max(abs(nw[x] - sg[x]) for x in g) # abs tol 1e-10 # optional - networkx 0 Stupid cases:: @@ -642,13 +642,13 @@ def centrality_closeness_top_k(G, int k=1, int verbose=0): sage: n = 20 sage: m = random.randint(1, n * (n - 1) / 2) sage: k = random.randint(1, n) - sage: g = graphs.RandomGNM(n, m) - sage: topk = centrality_closeness_top_k(g, k) - sage: centr = g.centrality_closeness(algorithm='BFS') - sage: sorted_centr = sorted(centr.values(), reverse=True) - sage: len(topk) == min(k, len(sorted_centr)) + sage: g = graphs.RandomGNM(n, m) # optional - networkx + sage: topk = centrality_closeness_top_k(g, k) # optional - networkx + sage: centr = g.centrality_closeness(algorithm='BFS') # optional - networkx + sage: sorted_centr = sorted(centr.values(), reverse=True) # optional - networkx + sage: len(topk) == min(k, len(sorted_centr)) # optional - networkx True - sage: all(abs(topk[i][0] - sorted_centr[i]) < 1e-12 for i in range(len(topk))) + sage: all(abs(topk[i][0] - sorted_centr[i]) < 1e-12 for i in range(len(topk))) # optional - networkx True Directed case:: @@ -658,13 +658,13 @@ def centrality_closeness_top_k(G, int k=1, int verbose=0): sage: n = 20 sage: m = random.randint(1, n * (n - 1)) sage: k = random.randint(1, n) - sage: g = digraphs.RandomDirectedGNM(n, m) - sage: topk = centrality_closeness_top_k(g, k) - sage: centr = g.centrality_closeness(algorithm='BFS') - sage: sorted_centr = sorted(centr.values(), reverse=True) - sage: len(topk) == min(k, len(sorted_centr)) + sage: g = digraphs.RandomDirectedGNM(n, m) # optional - networkx + sage: topk = centrality_closeness_top_k(g, k) # optional - networkx + sage: centr = g.centrality_closeness(algorithm='BFS') # optional - networkx + sage: sorted_centr = sorted(centr.values(), reverse=True) # optional - networkx + sage: len(topk) == min(k, len(sorted_centr)) # optional - networkx True - sage: all(abs(topk[i][0] - sorted_centr[i]) < 1e-12 for i in range(len(topk))) + sage: all(abs(topk[i][0] - sorted_centr[i]) < 1e-12 for i in range(len(topk))) # optional - networkx True """ cdef list res diff --git a/src/sage/graphs/comparability.pyx b/src/sage/graphs/comparability.pyx index 0585473a75d..0271f43d9d8 100644 --- a/src/sage/graphs/comparability.pyx +++ b/src/sage/graphs/comparability.pyx @@ -745,15 +745,15 @@ def is_transitive(g, certificate=False): (0, 2) sage: digraphs.RandomDirectedGNP(30,.2).is_transitive() False - sage: D = digraphs.DeBruijn(5, 2) - sage: D.is_transitive() + sage: D = digraphs.DeBruijn(5, 2) # optional - sage.combinat + sage: D.is_transitive() # optional - sage.combinat False - sage: cert = D.is_transitive(certificate=True) - sage: D.has_edge(*cert) + sage: cert = D.is_transitive(certificate=True) # optional - sage.combinat + sage: D.has_edge(*cert) # optional - sage.combinat False - sage: bool(D.shortest_path(*cert)) + sage: bool(D.shortest_path(*cert)) # optional - sage.combinat True - sage: digraphs.RandomDirectedGNP(20,.2).transitive_closure().is_transitive() + sage: digraphs.RandomDirectedGNP(20,.2).transitive_closure().is_transitive() # optional - networkx True """ cdef int n = g.order() diff --git a/src/sage/graphs/connectivity.pyx b/src/sage/graphs/connectivity.pyx index 2837f63201d..0cbcb87dd8d 100644 --- a/src/sage/graphs/connectivity.pyx +++ b/src/sage/graphs/connectivity.pyx @@ -4246,8 +4246,8 @@ def is_triconnected(G): Comparing different methods on random graphs that are not always triconnected:: - sage: G = graphs.RandomBarabasiAlbert(50, 3) - sage: G.is_triconnected() == G.vertex_connectivity(k=3) + sage: G = graphs.RandomBarabasiAlbert(50, 3) # optional - networkx + sage: G.is_triconnected() == G.vertex_connectivity(k=3) # optional - networkx True .. SEEALSO:: diff --git a/src/sage/graphs/digraph.py b/src/sage/graphs/digraph.py index 203a6a4f299..b1d046ee25d 100644 --- a/src/sage/graphs/digraph.py +++ b/src/sage/graphs/digraph.py @@ -357,7 +357,7 @@ class DiGraph(GenericGraph): sage: g = DiGraph([[1..12], lambda i,j: i != j and i.divides(j)]) sage: g.vertices(sort=True) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] - sage: g.adjacency_matrix() + sage: g.adjacency_matrix() # optional - sage.modules [0 1 1 1 1 1 1 1 1 1 1 1] [0 0 0 1 0 1 0 1 0 1 0 1] [0 0 0 0 0 1 0 0 1 0 0 1] @@ -377,34 +377,36 @@ class DiGraph(GenericGraph): - an adjacency matrix:: - sage: M = Matrix([[0, 1, 1, 1, 0],[0, 0, 0, 0, 0],[0, 0, 0, 0, 1],[0, 0, 0, 0, 0],[0, 0, 0, 0, 0]]); M + sage: M = Matrix([[0, 1, 1, 1, 0], [0, 0, 0, 0, 0], # optional - sage.modules + ....: [0, 0, 0, 0, 1], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]); M [0 1 1 1 0] [0 0 0 0 0] [0 0 0 0 1] [0 0 0 0 0] [0 0 0 0 0] - sage: DiGraph(M) + sage: DiGraph(M) # optional - sage.modules Digraph on 5 vertices - sage: M = Matrix([[0,1,-1],[-1,0,-1/2],[1,1/2,0]]); M + sage: M = Matrix([[0,1,-1], [-1,0,-1/2], [1,1/2,0]]); M # optional - sage.modules [ 0 1 -1] [ -1 0 -1/2] [ 1 1/2 0] - sage: G = DiGraph(M,sparse=True,weighted=True); G + sage: G = DiGraph(M, sparse=True, weighted=True); G # optional - sage.modules Digraph on 3 vertices - sage: G.weighted() + sage: G.weighted() # optional - sage.modules True - an incidence matrix:: - sage: M = Matrix(6, [-1,0,0,0,1, 1,-1,0,0,0, 0,1,-1,0,0, 0,0,1,-1,0, 0,0,0,1,-1, 0,0,0,0,0]); M + sage: M = Matrix(6, [-1,0,0,0,1, 1,-1,0,0,0, 0,1,-1,0,0, # optional - sage.modules + ....: 0,0,1,-1,0, 0,0,0,1,-1, 0,0,0,0,0]); M [-1 0 0 0 1] [ 1 -1 0 0 0] [ 0 1 -1 0 0] [ 0 0 1 -1 0] [ 0 0 0 1 -1] [ 0 0 0 0 0] - sage: DiGraph(M) + sage: DiGraph(M) # optional - sage.modules Digraph on 6 vertices #. A ``dig6`` string: Sage automatically recognizes whether a string is in @@ -530,12 +532,12 @@ def __init__(self, data=None, pos=None, loops=None, format=None, sage: loads(dumps(D)) == D True - sage: a = matrix(2,2,[1,2,0,1]) - sage: DiGraph(a,sparse=True).adjacency_matrix() == a + sage: a = matrix(2,2,[1,2,0,1]) # optional - sage.modules + sage: DiGraph(a, sparse=True).adjacency_matrix() == a # optional - sage.modules True - sage: a = matrix(2,2,[3,2,0,1]) - sage: DiGraph(a,sparse=True).adjacency_matrix() == a + sage: a = matrix(2,2,[3,2,0,1]) # optional - sage.modules + sage: DiGraph(a, sparse=True).adjacency_matrix() == a # optional - sage.modules True The positions are copied when the DiGraph is built from another DiGraph @@ -575,11 +577,12 @@ def __init__(self, data=None, pos=None, loops=None, format=None, Problem with weighted adjacency matrix (:trac:`13919`):: - sage: B = {0:{1:2,2:5,3:4},1:{2:2,4:7},2:{3:1,4:4,5:3},3:{5:4},4:{5:1,6:5},5:{4:1,6:7,5:1}} + sage: B = {0:{1:2,2:5,3:4},1:{2:2,4:7},2:{3:1,4:4,5:3}, + ....: 3:{5:4},4:{5:1,6:5},5:{4:1,6:7,5:1}} sage: grafo3 = DiGraph(B, weighted=True) - sage: matad = grafo3.weighted_adjacency_matrix() - sage: grafo4 = DiGraph(matad, format="adjacency_matrix", weighted=True) - sage: grafo4.shortest_path(0, 6, by_weight=True) + sage: matad = grafo3.weighted_adjacency_matrix() # optional - sage.modules + sage: grafo4 = DiGraph(matad, format="adjacency_matrix", weighted=True) # optional - sage.modules + sage: grafo4.shortest_path(0, 6, by_weight=True) # optional - sage.modules [0, 1, 2, 5, 4, 6] Building a DiGraph with ``immutable=False`` returns a mutable graph:: @@ -1454,8 +1457,8 @@ def degree_polynomial(self): EXAMPLES:: - sage: G = posets.PentagonPoset().hasse_diagram() - sage: G.degree_polynomial() + sage: G = posets.PentagonPoset().hasse_diagram() # optional - sage.matrix + sage: G.degree_polynomial() # optional - sage.matrix x^2 + 3*x*y + y^2 sage: G = posets.BooleanLattice(4).hasse_diagram() @@ -2068,9 +2071,10 @@ def reverse_edges(self, edges, inplace=True, multiedges=None): [(0, 5, None), (1, 0, None), (2, 1, None), (3, 2, None), (4, 3, None), (5, 4, None)] - sage: D = digraphs.Kautz(2, 3) - sage: Dr = D.reverse_edges(D.edges(sort=True), inplace=False, multiedges=True) - sage: Dr.edges(sort=True) == D.reverse().edges(sort=True) + sage: D = digraphs.Kautz(2, 3) # optional - sage.combinat + sage: Dr = D.reverse_edges(D.edges(sort=True), inplace=False, # optional - sage.combinat + ....: multiedges=True) + sage: Dr.edges(sort=True) == D.reverse().edges(sort=True) # optional - sage.combinat True """ tempG = self if inplace else copy(self) @@ -2173,37 +2177,37 @@ def eccentricity(self, v=None, by_weight=False, algorithm=None, sage: G.eccentricity(with_labels=True) {0: 0} sage: G = DiGraph([(0,1,2), (1,2,3), (2,0,2)]) - sage: G.eccentricity(algorithm = 'BFS') + sage: G.eccentricity(algorithm='BFS') [2, 2, 2] - sage: G.eccentricity(algorithm = 'Floyd-Warshall-Cython') + sage: G.eccentricity(algorithm='Floyd-Warshall-Cython') [2, 2, 2] - sage: G.eccentricity(by_weight = True, algorithm = 'Dijkstra_NetworkX') + sage: G.eccentricity(by_weight=True, algorithm='Dijkstra_NetworkX') # optional - networkx [5, 5, 4] - sage: G.eccentricity(by_weight = True, algorithm = 'Dijkstra_Boost') + sage: G.eccentricity(by_weight=True, algorithm='Dijkstra_Boost') [5, 5, 4] - sage: G.eccentricity(by_weight = True, algorithm = 'Johnson_Boost') + sage: G.eccentricity(by_weight=True, algorithm='Johnson_Boost') [5, 5, 4] - sage: G.eccentricity(by_weight = True, algorithm = 'Floyd-Warshall-Python') + sage: G.eccentricity(by_weight=True, algorithm='Floyd-Warshall-Python') [5, 5, 4] - sage: G.eccentricity(dist_dict = G.shortest_path_all_pairs(by_weight = True)[0]) + sage: G.eccentricity(dist_dict=G.shortest_path_all_pairs(by_weight=True)[0]) [5, 5, 4] TESTS: A non-implemented algorithm:: - sage: G.eccentricity(algorithm = 'boh') + sage: G.eccentricity(algorithm='boh') Traceback (most recent call last): ... ValueError: unknown algorithm "boh" An algorithm that does not work with edge weights:: - sage: G.eccentricity(by_weight = True, algorithm = 'BFS') + sage: G.eccentricity(by_weight=True, algorithm='BFS') Traceback (most recent call last): ... ValueError: algorithm 'BFS' does not work with weights - sage: G.eccentricity(by_weight = True, algorithm = 'Floyd-Warshall-Cython') + sage: G.eccentricity(by_weight=True, algorithm='Floyd-Warshall-Cython') Traceback (most recent call last): ... ValueError: algorithm 'Floyd-Warshall-Cython' does not work with weights @@ -2211,15 +2215,15 @@ def eccentricity(self, v=None, by_weight=False, algorithm=None, An algorithm that computes the all-pair-shortest-paths when not all vertices are needed:: - sage: G.eccentricity(0, algorithm = 'Floyd-Warshall-Cython') + sage: G.eccentricity(0, algorithm='Floyd-Warshall-Cython') Traceback (most recent call last): ... ValueError: algorithm 'Floyd-Warshall-Cython' works only if all eccentricities are needed - sage: G.eccentricity(0, algorithm = 'Floyd-Warshall-Python') + sage: G.eccentricity(0, algorithm='Floyd-Warshall-Python') Traceback (most recent call last): ... ValueError: algorithm 'Floyd-Warshall-Python' works only if all eccentricities are needed - sage: G.eccentricity(0, algorithm = 'Johnson_Boost') + sage: G.eccentricity(0, algorithm='Johnson_Boost') Traceback (most recent call last): ... ValueError: algorithm 'Johnson_Boost' works only if all eccentricities are needed @@ -2442,11 +2446,11 @@ def diameter(self, by_weight=False, algorithm=None, weight_function=None, EXAMPLES:: - sage: G = digraphs.DeBruijn(5,4) - sage: G.diameter() + sage: G = digraphs.DeBruijn(5,4) # optional - sage.combinat + sage: G.diameter() # optional - sage.combinat 4 - sage: G = digraphs.GeneralizedDeBruijn(9, 3) - sage: G.diameter() + sage: G = digraphs.GeneralizedDeBruijn(9, 3) # optional - sage.combinat + sage: G.diameter() # optional - sage.combinat 2 TESTS:: @@ -3152,9 +3156,10 @@ def topological_sort(self, implementation="default"): Using the NetworkX implementation :: - sage: s = list(D.topological_sort(implementation="NetworkX")); s # random + sage: s = list(D.topological_sort(implementation="NetworkX")); s # random # optional - networkx [0, 4, 1, 3, 2, 5, 6, 9, 7, 8, 10] - sage: all(s.index(u) < s.index(v) for u, v in D.edges(sort=False, labels=False)) + sage: all(s.index(u) < s.index(v) # optional - networkx + ....: for u, v in D.edges(sort=False, labels=False)) True :: @@ -3221,8 +3226,9 @@ def topological_sort_generator(self): sage: D = DiGraph({0: [1, 2], 1: [3], 2: [3, 4]}) sage: D.plot(layout='circular').show() # optional - sage.plot - sage: list(D.topological_sort_generator()) - [[0, 1, 2, 3, 4], [0, 2, 1, 3, 4], [0, 2, 1, 4, 3], [0, 2, 4, 1, 3], [0, 1, 2, 4, 3]] + sage: list(D.topological_sort_generator()) # optional - sage.modules sage.rings.finite_rings + [[0, 1, 2, 3, 4], [0, 2, 1, 3, 4], [0, 2, 1, 4, 3], + [0, 2, 4, 1, 3], [0, 1, 2, 4, 3]] :: @@ -3586,7 +3592,7 @@ def flow_polytope(self, edges=None, ends=None, backend=None): Flow polytopes can also be built through the ``polytopes.`` object:: - sage: polytopes.flow_polytope(digraphs.Path(5)) + sage: polytopes.flow_polytope(digraphs.Path(5)) # optional - sage.geometry.polyhedron A 0-dimensional polyhedron in QQ^4 defined as the convex hull of 1 vertex EXAMPLES: @@ -3594,26 +3600,26 @@ def flow_polytope(self, edges=None, ends=None, backend=None): A commutative square:: sage: G = DiGraph({1: [2, 3], 2: [4], 3: [4]}) - sage: fl = G.flow_polytope(); fl + sage: fl = G.flow_polytope(); fl # optional - sage.geometry.polyhedron A 1-dimensional polyhedron in QQ^4 defined as the convex hull of 2 vertices - sage: fl.vertices() + sage: fl.vertices() # optional - sage.geometry.polyhedron (A vertex at (0, 1, 0, 1), A vertex at (1, 0, 1, 0)) Using a different order for the edges of the graph:: - sage: fl = G.flow_polytope(edges=G.edges(key=lambda x: x[0] - x[1])); fl + sage: fl = G.flow_polytope(edges=G.edges(key=lambda x: x[0] - x[1])); fl # optional - sage.geometry.polyhedron A 1-dimensional polyhedron in QQ^4 defined as the convex hull of 2 vertices - sage: fl.vertices() + sage: fl.vertices() # optional - sage.geometry.polyhedron (A vertex at (0, 1, 1, 0), A vertex at (1, 0, 0, 1)) A tournament on 4 vertices:: sage: H = digraphs.TransitiveTournament(4) - sage: fl = H.flow_polytope(); fl + sage: fl = H.flow_polytope(); fl # optional - sage.geometry.polyhedron A 3-dimensional polyhedron in QQ^6 defined as the convex hull of 4 vertices - sage: fl.vertices() + sage: fl.vertices() # optional - sage.geometry.polyhedron (A vertex at (0, 0, 1, 0, 0, 0), A vertex at (0, 1, 0, 0, 0, 1), A vertex at (1, 0, 0, 0, 1, 0), @@ -3621,41 +3627,40 @@ def flow_polytope(self, edges=None, ends=None, backend=None): Restricting to a subset of the edges:: - sage: fl = H.flow_polytope(edges=[(0, 1, None), (1, 2, None), - ....: (2, 3, None), (0, 3, None)]) - sage: fl + sage: fl = H.flow_polytope(edges=[(0, 1, None), (1, 2, None), # optional - sage.geometry.polyhedron + ....: (2, 3, None), (0, 3, None)]); fl A 1-dimensional polyhedron in QQ^4 defined as the convex hull of 2 vertices - sage: fl.vertices() + sage: fl.vertices() # optional - sage.geometry.polyhedron (A vertex at (0, 0, 0, 1), A vertex at (1, 1, 1, 0)) Using a different choice of sources and sinks:: - sage: fl = H.flow_polytope(ends=([1], [3])); fl + sage: fl = H.flow_polytope(ends=([1], [3])); fl # optional - sage.geometry.polyhedron A 1-dimensional polyhedron in QQ^6 defined as the convex hull of 2 vertices - sage: fl.vertices() + sage: fl.vertices() # optional - sage.geometry.polyhedron (A vertex at (0, 0, 0, 1, 0, 1), A vertex at (0, 0, 0, 0, 1, 0)) - sage: fl = H.flow_polytope(ends=([0, 1], [3])); fl + sage: fl = H.flow_polytope(ends=([0, 1], [3])); fl # optional - sage.geometry.polyhedron The empty polyhedron in QQ^6 - sage: fl = H.flow_polytope(ends=([3], [0])); fl + sage: fl = H.flow_polytope(ends=([3], [0])); fl # optional - sage.geometry.polyhedron The empty polyhedron in QQ^6 - sage: fl = H.flow_polytope(ends=([0, 1], [2, 3])); fl + sage: fl = H.flow_polytope(ends=([0, 1], [2, 3])); fl # optional - sage.geometry.polyhedron A 3-dimensional polyhedron in QQ^6 defined as the convex hull of 5 vertices - sage: fl.vertices() + sage: fl.vertices() # optional - sage.geometry.polyhedron (A vertex at (0, 0, 1, 1, 0, 0), A vertex at (0, 1, 0, 0, 1, 0), A vertex at (1, 0, 0, 2, 0, 1), A vertex at (1, 0, 0, 1, 1, 0), A vertex at (0, 1, 0, 1, 0, 1)) - sage: fl = H.flow_polytope(edges=[(0, 1, None), (1, 2, None), + sage: fl = H.flow_polytope(edges=[(0, 1, None), (1, 2, None), # optional - sage.geometry.polyhedron ....: (2, 3, None), (0, 2, None), ....: (1, 3, None)], ....: ends=([0, 1], [2, 3])); fl A 2-dimensional polyhedron in QQ^5 defined as the convex hull of 4 vertices - sage: fl.vertices() + sage: fl.vertices() # optional - sage.geometry.polyhedron (A vertex at (0, 0, 0, 1, 1), A vertex at (1, 2, 1, 0, 0), A vertex at (1, 1, 0, 0, 1), @@ -3664,27 +3669,25 @@ def flow_polytope(self, edges=None, ends=None, backend=None): A digraph with one source and two sinks:: sage: Y = DiGraph({1: [2], 2: [3, 4]}) - sage: Y.flow_polytope() + sage: Y.flow_polytope() # optional - sage.geometry.polyhedron The empty polyhedron in QQ^3 A digraph with one vertex and no edge:: sage: Z = DiGraph({1: []}) - sage: Z.flow_polytope() + sage: Z.flow_polytope() # optional - sage.geometry.polyhedron A 0-dimensional polyhedron in QQ^0 defined as the convex hull of 1 vertex A digraph with multiple edges (:trac:`28837`):: - sage: G = DiGraph([(0, 1), (0,1)], multiedges=True) - sage: G + sage: G = DiGraph([(0, 1), (0,1)], multiedges=True); G Multi-digraph on 2 vertices - sage: P = G.flow_polytope() - sage: P + sage: P = G.flow_polytope(); P # optional - sage.geometry.polyhedron A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices - sage: P.vertices() + sage: P.vertices() # optional - sage.geometry.polyhedron (A vertex at (1, 0), A vertex at (0, 1)) - sage: P.lines() + sage: P.lines() # optional - sage.geometry.polyhedron () """ from sage.geometry.polyhedron.constructor import Polyhedron diff --git a/src/sage/graphs/digraph_generators.py b/src/sage/graphs/digraph_generators.py index 2b864b54284..b9a87601a47 100644 --- a/src/sage/graphs/digraph_generators.py +++ b/src/sage/graphs/digraph_generators.py @@ -1747,8 +1747,7 @@ def extra_property(x): if vertices is None: vertices = 0 while True: - for g in self(vertices, sparse=sparse, copy=copy): - yield g + yield from self(vertices, sparse=sparse, copy=copy) vertices += 1 from sage.graphs.graph_generators import canaug_traverse_edge diff --git a/src/sage/graphs/distances_all_pairs.pyx b/src/sage/graphs/distances_all_pairs.pyx index 87e83b4f5ce..2451de506fd 100644 --- a/src/sage/graphs/distances_all_pairs.pyx +++ b/src/sage/graphs/distances_all_pairs.pyx @@ -545,7 +545,7 @@ def is_distance_regular(G, parameters=False): sage: graphs.PathGraph(2).is_distance_regular(parameters=True) ([1, None], [None, 1]) - sage: graphs.Tutte12Cage().is_distance_regular(parameters=True) + sage: graphs.Tutte12Cage().is_distance_regular(parameters=True) # optional - networkx ([3, 2, 2, 2, 2, 2, None], [None, 1, 1, 1, 1, 1, 3]) """ @@ -843,8 +843,8 @@ cdef uint32_t * c_eccentricity_DHV(short_digraph sd) except NULL: TESTS: - sage: G = graphs.RandomBarabasiAlbert(50, 2) - sage: eccentricity(G, algorithm='bounds') == eccentricity(G, algorithm='DHV') + sage: G = graphs.RandomBarabasiAlbert(50, 2) # optional - networkx + sage: eccentricity(G, algorithm='bounds') == eccentricity(G, algorithm='DHV') # optional - networkx True """ cdef uint32_t n = sd.n @@ -1777,26 +1777,26 @@ def diameter(G, algorithm=None, source=None): Comparison of exact algorithms for graphs:: - sage: G = graphs.RandomBarabasiAlbert(100, 2) - sage: d1 = diameter(G, algorithm='standard') - sage: d2 = diameter(G, algorithm='iFUB') - sage: d3 = diameter(G, algorithm='iFUB', source=G.random_vertex()) - sage: d4 = diameter(G, algorithm='DHV') - sage: if d1 != d2 or d1 != d3 or d1 != d4: print("Something goes wrong!") + sage: G = graphs.RandomBarabasiAlbert(100, 2) # optional - networkx + sage: d1 = diameter(G, algorithm='standard') # optional - networkx + sage: d2 = diameter(G, algorithm='iFUB') # optional - networkx + sage: d3 = diameter(G, algorithm='iFUB', source=G.random_vertex()) # optional - networkx + sage: d4 = diameter(G, algorithm='DHV') # optional - networkx + sage: if d1 != d2 or d1 != d3 or d1 != d4: print("Something goes wrong!") # optional - networkx Comparison of lower bound algorithms:: - sage: lb2 = diameter(G, algorithm='2sweep') - sage: lbm = diameter(G, algorithm='multi-sweep') - sage: if not (lb2 <= lbm and lbm <= d3): print("Something goes wrong!") + sage: lb2 = diameter(G, algorithm='2sweep') # optional - networkx + sage: lbm = diameter(G, algorithm='multi-sweep') # optional - networkx + sage: if not (lb2 <= lbm and lbm <= d3): print("Something goes wrong!") # optional - networkx Comparison of exact algorithms for digraphs:: - sage: D = DiGraph(graphs.RandomBarabasiAlbert(50, 2)) - sage: d1 = diameter(D, algorithm='standard') - sage: d2 = diameter(D, algorithm='DiFUB') - sage: d3 = diameter(D, algorithm='DiFUB', source=D.random_vertex()) - sage: d1 == d2 and d1 == d3 + sage: D = DiGraph(graphs.RandomBarabasiAlbert(50, 2)) # optional - networkx + sage: d1 = diameter(D, algorithm='standard') # optional - networkx + sage: d2 = diameter(D, algorithm='DiFUB') # optional - networkx + sage: d3 = diameter(D, algorithm='DiFUB', source=D.random_vertex()) # optional - networkx + sage: d1 == d2 and d1 == d3 # optional - networkx True TESTS: @@ -2438,8 +2438,8 @@ def distances_distribution(G): The de Bruijn digraph dB(2,3):: - sage: D = digraphs.DeBruijn(2,3) - sage: D.distances_distribution() + sage: D = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: D.distances_distribution() # optional - sage.combinat {1: 1/4, 2: 11/28, 3: 5/14} """ cdef size_t n = G.order() diff --git a/src/sage/graphs/dot2tex_utils.py b/src/sage/graphs/dot2tex_utils.py index cfa4613fdf9..95850012885 100644 --- a/src/sage/graphs/dot2tex_utils.py +++ b/src/sage/graphs/dot2tex_utils.py @@ -74,7 +74,7 @@ def quoted_latex(x): EXAMPLES:: - sage: sage.graphs.dot2tex_utils.quoted_latex(matrix([[1,1],[0,1],[0,0]])) + sage: sage.graphs.dot2tex_utils.quoted_latex(matrix([[1,1],[0,1],[0,0]])) # optional - sage.modules '\\left(\\begin{array}{rr}1 & 1 \\\\0 & 1 \\\\0 & 0\\end{array}\\right)' """ return re.sub("\"|\r|(%[^\n]*)?\n", "", latex(x)) @@ -89,9 +89,9 @@ def quoted_str(x): EXAMPLES:: - sage: sage.graphs.dot2tex_utils.quoted_str(matrix([[1,1],[0,1],[0,0]])) + sage: sage.graphs.dot2tex_utils.quoted_str(matrix([[1,1],[0,1],[0,0]])) # optional - sage.modules '[1 1]\\n\\\n[0 1]\\n\\\n[0 0]' - sage: print(sage.graphs.dot2tex_utils.quoted_str(matrix([[1,1],[0,1],[0,0]]))) + sage: print(sage.graphs.dot2tex_utils.quoted_str(matrix([[1,1],[0,1],[0,0]]))) # optional - sage.modules [1 1]\n\ [0 1]\n\ [0 0] diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index 5263e712db5..c4cf6a4f81b 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -56,28 +56,31 @@ cdef class GabowEdgeConnectivity: A random `d`-regular digraph is `d`-edge-connected:: sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity - sage: D = DiGraph(graphs.RandomRegular(6, 50)) - sage: while not D.is_strongly_connected(): + sage: D = DiGraph(graphs.RandomRegular(6, 50)) # optional - networkx + sage: while not D.is_strongly_connected(): # optional - networkx ....: D = DiGraph(graphs.RandomRegular(6, 50)) - sage: GabowEdgeConnectivity(D).edge_connectivity() + sage: GabowEdgeConnectivity(D).edge_connectivity() # optional - networkx 6 A complete digraph with `n` vertices is `n-1`-edge-connected:: sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity sage: D = DiGraph(digraphs.Complete(10)) - sage: GabowEdgeConnectivity(D, use_rec = True).edge_connectivity() + sage: GabowEdgeConnectivity(D, use_rec=True).edge_connectivity() 9 Check that we get the same result when with and without the DFS-based speed-up initialization proposed in [GKLP2021]_:: - sage: G = graphs.RandomBarabasiAlbert(100, 2) - sage: D = DiGraph(G) - sage: ec1 = GabowEdgeConnectivity(D, dfs_preprocessing=False).edge_connectivity() - sage: ec2 = GabowEdgeConnectivity(D, dfs_preprocessing=True).edge_connectivity() - sage: ec3 = GabowEdgeConnectivity(D, dfs_preprocessing=True, use_rec=True).edge_connectivity() - sage: ec1 == ec2 and ec2 == ec3 + sage: G = graphs.RandomBarabasiAlbert(100, 2) # optional - networkx + sage: D = DiGraph(G) # optional - networkx + sage: ec1 = GabowEdgeConnectivity(D, # optional - networkx + ....: dfs_preprocessing=False).edge_connectivity() + sage: ec2 = GabowEdgeConnectivity(D, # optional - networkx + ....: dfs_preprocessing=True).edge_connectivity() + sage: ec3 = GabowEdgeConnectivity(D, dfs_preprocessing=True, # optional - networkx + ....: use_rec=True).edge_connectivity() + sage: ec1 == ec2 and ec2 == ec3 # optional - networkx True TESTS: diff --git a/src/sage/graphs/generators/basic.py b/src/sage/graphs/generators/basic.py index 27578e76e4b..43e0b683703 100644 --- a/src/sage/graphs/generators/basic.py +++ b/src/sage/graphs/generators/basic.py @@ -20,8 +20,6 @@ # import from Sage library from sage.graphs.graph import Graph from math import sin, cos, pi -from numpy import corrcoef -from sage.matrix.constructor import Matrix def BullGraph(): @@ -406,18 +404,20 @@ def CorrelationGraph(seqs, alpha, include_anticorrelation): EXAMPLES: sage: from sage.graphs.generators.basic import CorrelationGraph - sage: data=[[1,2,3],[4,5,6],[7,8,9999]] - sage: CG1 = CorrelationGraph(data, 0.9, False) - sage: CG2 = CorrelationGraph(data, 0.9, True) - sage: CG3 = CorrelationGraph(data, 0.1, True) - sage: CG1.edges(sort=False) + sage: data = [[1,2,3], [4,5,6], [7,8,9999]] + sage: CG1 = CorrelationGraph(data, 0.9, False) # optional - numpy + sage: CG2 = CorrelationGraph(data, 0.9, True) # optional - numpy + sage: CG3 = CorrelationGraph(data, 0.1, True) # optional - numpy + sage: CG1.edges(sort=False) # optional - numpy [(0, 0, None), (0, 1, None), (1, 1, None), (2, 2, None)] - sage: CG2.edges(sort=False) + sage: CG2.edges(sort=False) # optional - numpy [(0, 0, None), (0, 1, None), (1, 1, None), (2, 2, None)] - sage: CG3.edges(sort=False) + sage: CG3.edges(sort=False) # optional - numpy [(0, 0, None), (0, 1, None), (0, 2, None), (1, 1, None), (1, 2, None), (2, 2, None)] """ + from numpy import corrcoef + from sage.matrix.constructor import Matrix # compute pairwise correlation coeffecients corrs = corrcoef(seqs) @@ -825,11 +825,11 @@ def Toroidal6RegularGrid2dGraph(p, q): sage: g = graphs.Toroidal6RegularGrid2dGraph(5,5) sage: g.is_regular(k=6) True - sage: g.is_vertex_transitive() + sage: g.is_vertex_transitive() # optional - sage.groups True - sage: g.line_graph().is_vertex_transitive() + sage: g.line_graph().is_vertex_transitive() # optional - sage.groups True - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 300 sage: g.is_hamiltonian() True diff --git a/src/sage/graphs/generators/classical_geometries.py b/src/sage/graphs/generators/classical_geometries.py index 059d46d0c7f..680402dc476 100644 --- a/src/sage/graphs/generators/classical_geometries.py +++ b/src/sage/graphs/generators/classical_geometries.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.modules r""" Families of graphs derived from classical geometries over finite fields @@ -39,7 +39,7 @@ def SymplecticPolarGraph(d, q, algorithm=None): - ``d,q`` -- integers; note that only even values of `d` are accepted by the function. - - ``algorithm`` -- string (default: ``None``); if set to 'gap' then the + - ``algorithm`` -- string (default: ``None``); if set to ``'gap'``, then the computation is carried via GAP library interface, computing totally singular subspaces, which is faster for `q>3`. Otherwise it is done directly. @@ -60,17 +60,18 @@ def SymplecticPolarGraph(d, q, algorithm=None): sage: G = graphs.SymplecticPolarGraph(4,3) sage: G.is_strongly_regular(parameters=True) (40, 12, 2, 4) - sage: O=graphs.OrthogonalPolarGraph(5,3) + sage: O = graphs.OrthogonalPolarGraph(5,3) sage: O.is_strongly_regular(parameters=True) (40, 12, 2, 4) sage: O.is_isomorphic(G) False - sage: graphs.SymplecticPolarGraph(6,4,algorithm="gap").is_strongly_regular(parameters=True) # not tested (long time) + sage: S = graphs.SymplecticPolarGraph(6,4,algorithm="gap") # not tested (long time) # optional - sage.libs.gap + sage: S.is_strongly_regular(parameters=True) # not tested (long time) # optional - sage.libs.gap (1365, 340, 83, 85) TESTS:: - sage: graphs.SymplecticPolarGraph(4,4,algorithm="gap").is_strongly_regular(parameters=True) + sage: graphs.SymplecticPolarGraph(4,4,algorithm="gap").is_strongly_regular(parameters=True) # optional - sage.libs.gap (85, 20, 3, 5) sage: graphs.SymplecticPolarGraph(4,4).is_strongly_regular(parameters=True) (85, 20, 3, 5) @@ -223,61 +224,61 @@ def _orthogonal_polar_graph(m, q, sign="+", point_type=[0]): Petersen graph:: sage: from sage.graphs.generators.classical_geometries import _orthogonal_polar_graph - sage: g=_orthogonal_polar_graph(3,5,point_type=[2,3]) - sage: g.is_strongly_regular(parameters=True) + sage: g = _orthogonal_polar_graph(3,5,point_type=[2,3]) # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (10, 3, 0, 1) A locally Petersen graph (a.k.a. Doro graph, a.k.a. Hall graph):: - sage: g=_orthogonal_polar_graph(4,5,'-',point_type=[2,3]) - sage: g.is_distance_regular(parameters=True) + sage: g = _orthogonal_polar_graph(4,5,'-',point_type=[2,3]) # optional - sage.libs.gap + sage: g.is_distance_regular(parameters=True) # optional - sage.libs.gap ([10, 6, 4, None], [None, 1, 2, 5]) Various big and slow to build graphs: `NO^+(7,3)`:: - sage: g=_orthogonal_polar_graph(7,3,point_type=[1]) # not tested (long time) - sage: g.is_strongly_regular(parameters=True) # not tested (long time) + sage: g = _orthogonal_polar_graph(7,3,point_type=[1]) # not tested (long time) + sage: g.is_strongly_regular(parameters=True) # not tested (long time) (378, 117, 36, 36) `NO^-(7,3)`:: - sage: g=_orthogonal_polar_graph(7,3,point_type=[-1]) # not tested (long time) - sage: g.is_strongly_regular(parameters=True) # not tested (long time) + sage: g = _orthogonal_polar_graph(7,3,point_type=[-1]) # not tested (long time) + sage: g.is_strongly_regular(parameters=True) # not tested (long time) (351, 126, 45, 45) `NO^+(6,3)`:: - sage: g=_orthogonal_polar_graph(6,3,point_type=[1]) - sage: g.is_strongly_regular(parameters=True) + sage: g = _orthogonal_polar_graph(6,3,point_type=[1]) # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (117, 36, 15, 9) `NO^-(6,3)`:: - sage: g=_orthogonal_polar_graph(6,3,'-',point_type=[1]) - sage: g.is_strongly_regular(parameters=True) + sage: g = _orthogonal_polar_graph(6,3,'-',point_type=[1]) # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (126, 45, 12, 18) `NO^{-,\perp}(5,5)`:: - sage: g=_orthogonal_polar_graph(5,5,point_type=[2,3]) # long time - sage: g.is_strongly_regular(parameters=True) # long time + sage: g = _orthogonal_polar_graph(5,5,point_type=[2,3]) # long time, optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (300, 65, 10, 15) `NO^{+,\perp}(5,5)`:: - sage: g=_orthogonal_polar_graph(5,5,point_type=[1,-1]) # not tested (long time) - sage: g.is_strongly_regular(parameters=True) # not tested (long time) + sage: g = _orthogonal_polar_graph(5,5,point_type=[1,-1]) # not tested (long time) + sage: g.is_strongly_regular(parameters=True) # not tested (long time) (325, 60, 15, 10) TESTS:: - sage: g=_orthogonal_polar_graph(5,3,point_type=[-1]) - sage: g.is_strongly_regular(parameters=True) + sage: g = _orthogonal_polar_graph(5,3,point_type=[-1]) # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (45, 12, 3, 3) - sage: g=_orthogonal_polar_graph(5,3,point_type=[1]) - sage: g.is_strongly_regular(parameters=True) + sage: g = _orthogonal_polar_graph(5,3,point_type=[1]) # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (36, 15, 6, 6) """ @@ -341,34 +342,34 @@ def OrthogonalPolarGraph(m, q, sign="+"): EXAMPLES:: - sage: G = graphs.OrthogonalPolarGraph(6,3,"+"); G + sage: G = graphs.OrthogonalPolarGraph(6,3,"+"); G # optional - sage.libs.gap Orthogonal Polar Graph O^+(6, 3): Graph on 130 vertices - sage: G.is_strongly_regular(parameters=True) + sage: G.is_strongly_regular(parameters=True) # optional - sage.libs.gap (130, 48, 20, 16) - sage: G = graphs.OrthogonalPolarGraph(6,3,"-"); G + sage: G = graphs.OrthogonalPolarGraph(6,3,"-"); G # optional - sage.libs.gap Orthogonal Polar Graph O^-(6, 3): Graph on 112 vertices - sage: G.is_strongly_regular(parameters=True) + sage: G.is_strongly_regular(parameters=True) # optional - sage.libs.gap (112, 30, 2, 10) - sage: G = graphs.OrthogonalPolarGraph(5,3); G + sage: G = graphs.OrthogonalPolarGraph(5,3); G # optional - sage.libs.gap Orthogonal Polar Graph O(5, 3): Graph on 40 vertices - sage: G.is_strongly_regular(parameters=True) + sage: G.is_strongly_regular(parameters=True) # optional - sage.libs.gap (40, 12, 2, 4) - sage: G = graphs.OrthogonalPolarGraph(8,2,"+"); G + sage: G = graphs.OrthogonalPolarGraph(8,2,"+"); G # optional - sage.libs.gap Orthogonal Polar Graph O^+(8, 2): Graph on 135 vertices - sage: G.is_strongly_regular(parameters=True) + sage: G.is_strongly_regular(parameters=True) # optional - sage.libs.gap (135, 70, 37, 35) - sage: G = graphs.OrthogonalPolarGraph(8,2,"-"); G + sage: G = graphs.OrthogonalPolarGraph(8,2,"-"); G # optional - sage.libs.gap Orthogonal Polar Graph O^-(8, 2): Graph on 119 vertices - sage: G.is_strongly_regular(parameters=True) + sage: G.is_strongly_regular(parameters=True) # optional - sage.libs.gap (119, 54, 21, 27) TESTS:: - sage: G = graphs.OrthogonalPolarGraph(4,3,"") + sage: G = graphs.OrthogonalPolarGraph(4,3,"") # optional - sage.libs.gap Traceback (most recent call last): ... ValueError: sign must be equal to either '-' or '+' when m is even - sage: G = graphs.OrthogonalPolarGraph(5,3,"-") + sage: G = graphs.OrthogonalPolarGraph(5,3,"-") # optional - sage.libs.gap Traceback (most recent call last): ... ValueError: sign must be equal to either '' or '+' when m is odd @@ -416,71 +417,74 @@ def NonisotropicOrthogonalPolarGraph(m, q, sign="+", perp=None): `NO^-(4,2)` is isomorphic to Petersen graph:: - sage: g=graphs.NonisotropicOrthogonalPolarGraph(4,2,'-'); g + sage: g = graphs.NonisotropicOrthogonalPolarGraph(4,2,'-'); g # optional - sage.libs.gap NO^-(4, 2): Graph on 10 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (10, 3, 0, 1) `NO^-(6,2)` and `NO^+(6,2)`:: - sage: g=graphs.NonisotropicOrthogonalPolarGraph(6,2,'-') - sage: g.is_strongly_regular(parameters=True) + sage: g = graphs.NonisotropicOrthogonalPolarGraph(6,2,'-') # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (36, 15, 6, 6) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(6,2,'+'); g + sage: g = graphs.NonisotropicOrthogonalPolarGraph(6,2,'+'); g # optional - sage.libs.gap NO^+(6, 2): Graph on 28 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (28, 15, 6, 10) `NO^+(8,2)`:: - sage: g=graphs.NonisotropicOrthogonalPolarGraph(8,2,'+') - sage: g.is_strongly_regular(parameters=True) + sage: g = graphs.NonisotropicOrthogonalPolarGraph(8,2,'+') # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (120, 63, 30, 36) Wilbrink's graphs for `q=5`:: - sage: graphs.NonisotropicOrthogonalPolarGraph(5,5,perp=1).is_strongly_regular(parameters=True) # long time + sage: g = graphs.NonisotropicOrthogonalPolarGraph(5,5,perp=1) # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (325, 60, 15, 10) - sage: graphs.NonisotropicOrthogonalPolarGraph(5,5,'-',perp=1).is_strongly_regular(parameters=True) # long time + sage: g = graphs.NonisotropicOrthogonalPolarGraph(5,5,'-',perp=1) # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (300, 65, 10, 15) Wilbrink's graphs:: - sage: g=graphs.NonisotropicOrthogonalPolarGraph(5,4,'+') - sage: g.is_strongly_regular(parameters=True) + sage: g = graphs.NonisotropicOrthogonalPolarGraph(5,4,'+') # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (136, 75, 42, 40) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(5,4,'-') - sage: g.is_strongly_regular(parameters=True) + sage: g = graphs.NonisotropicOrthogonalPolarGraph(5,4,'-') # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (120, 51, 18, 24) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(7,4,'+'); g # not tested (long time) + sage: g = graphs.NonisotropicOrthogonalPolarGraph(7,4,'+'); g # not tested (long time) NO^+(7, 4): Graph on 2080 vertices - sage: g.is_strongly_regular(parameters=True) # not tested (long time) + sage: g.is_strongly_regular(parameters=True) # not tested (long time) (2080, 1071, 558, 544) TESTS:: - sage: g=graphs.NonisotropicOrthogonalPolarGraph(4,2); g + sage: g = graphs.NonisotropicOrthogonalPolarGraph(4,2); g # optional - sage.libs.gap NO^+(4, 2): Graph on 6 vertices - sage: graphs.NonisotropicOrthogonalPolarGraph(4,3,'-').is_strongly_regular(parameters=True) + sage: g = graphs.NonisotropicOrthogonalPolarGraph(4,3,'-') # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (15, 6, 1, 3) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(3,5,'-',perp=1); g + sage: g = graphs.NonisotropicOrthogonalPolarGraph(3,5,'-',perp=1); g # optional - sage.libs.gap NO^-,perp(3, 5): Graph on 10 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (10, 3, 0, 1) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(6,3,'+') # long time - sage: g.is_strongly_regular(parameters=True) # long time + sage: g = graphs.NonisotropicOrthogonalPolarGraph(6,3,'+') # long time, optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (117, 36, 15, 9) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(6,3,'-'); g # long time + sage: g = graphs.NonisotropicOrthogonalPolarGraph(6,3,'-'); g # long time, optional - sage.libs.gap NO^-(6, 3): Graph on 126 vertices - sage: g.is_strongly_regular(parameters=True) # long time + sage: g.is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (126, 45, 12, 18) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(5,5,'-') # long time - sage: g.is_strongly_regular(parameters=True) # long time + sage: g = graphs.NonisotropicOrthogonalPolarGraph(5,5,'-') # long time, optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (300, 104, 28, 40) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(5,5,'+') # long time - sage: g.is_strongly_regular(parameters=True) # long time + sage: g = graphs.NonisotropicOrthogonalPolarGraph(5,5,'+') # long time, optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (325, 144, 68, 60) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(6,4,'+') + sage: g = graphs.NonisotropicOrthogonalPolarGraph(6,4,'+') # optional - sage.libs.gap Traceback (most recent call last): ... ValueError: for m even q must be 2 or 3 @@ -561,9 +565,9 @@ def _polar_graph(m, q, g, intersection_size=None): TESTS:: sage: from sage.graphs.generators.classical_geometries import _polar_graph - sage: _polar_graph(4, 4, libgap.GeneralUnitaryGroup(4, 2)) + sage: _polar_graph(4, 4, libgap.GeneralUnitaryGroup(4, 2)) # optional - sage.libs.gap Graph on 45 vertices - sage: _polar_graph(4, 4, libgap.GeneralUnitaryGroup(4, 2), intersection_size=1) + sage: _polar_graph(4, 4, libgap.GeneralUnitaryGroup(4, 2), intersection_size=1) # optional - sage.libs.gap Graph on 27 vertices """ from sage.libs.gap.libgap import libgap @@ -605,20 +609,20 @@ def UnitaryPolarGraph(m, q, algorithm="gap"): EXAMPLES:: - sage: G = graphs.UnitaryPolarGraph(4,2); G + sage: G = graphs.UnitaryPolarGraph(4,2); G # optional - sage.libs.gap Unitary Polar Graph U(4, 2); GQ(4, 2): Graph on 45 vertices - sage: G.is_strongly_regular(parameters=True) + sage: G.is_strongly_regular(parameters=True) # optional - sage.libs.gap (45, 12, 3, 3) - sage: graphs.UnitaryPolarGraph(5,2).is_strongly_regular(parameters=True) + sage: graphs.UnitaryPolarGraph(5,2).is_strongly_regular(parameters=True) # optional - sage.libs.gap (165, 36, 3, 9) - sage: graphs.UnitaryPolarGraph(6,2) # not tested (long time) + sage: graphs.UnitaryPolarGraph(6,2) # not tested (long time) # optional - sage.libs.gap Unitary Polar Graph U(6, 2): Graph on 693 vertices TESTS:: - sage: graphs.UnitaryPolarGraph(4,3, algorithm="gap").is_strongly_regular(parameters=True) + sage: graphs.UnitaryPolarGraph(4,3, algorithm="gap").is_strongly_regular(parameters=True) # optional - sage.libs.gap (280, 36, 8, 4) - sage: graphs.UnitaryPolarGraph(4,3).is_strongly_regular(parameters=True) + sage: graphs.UnitaryPolarGraph(4,3).is_strongly_regular(parameters=True) # optional - sage.libs.gap (280, 36, 8, 4) sage: graphs.UnitaryPolarGraph(4,3, algorithm="foo") Traceback (most recent call last): @@ -672,18 +676,18 @@ def NonisotropicUnitaryPolarGraph(m, q): EXAMPLES:: - sage: g=graphs.NonisotropicUnitaryPolarGraph(5,2); g + sage: g = graphs.NonisotropicUnitaryPolarGraph(5,2); g # optional - sage.libs.gap NU(5, 2): Graph on 176 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (176, 135, 102, 108) TESTS:: - sage: graphs.NonisotropicUnitaryPolarGraph(4,2).is_strongly_regular(parameters=True) + sage: graphs.NonisotropicUnitaryPolarGraph(4,2).is_strongly_regular(parameters=True) # optional - sage.libs.gap (40, 27, 18, 18) - sage: graphs.NonisotropicUnitaryPolarGraph(4,3).is_strongly_regular(parameters=True) # long time + sage: graphs.NonisotropicUnitaryPolarGraph(4,3).is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (540, 224, 88, 96) - sage: graphs.NonisotropicUnitaryPolarGraph(6,6) + sage: graphs.NonisotropicUnitaryPolarGraph(6,6) # optional - sage.libs.gap Traceback (most recent call last): ... ValueError: q must be a prime power @@ -738,16 +742,16 @@ def UnitaryDualPolarGraph(m, q): The point graph of a generalized quadrangle (see :wikipedia:`Generalized_quadrangle`, [PT2009]_) of order (8,4):: - sage: G = graphs.UnitaryDualPolarGraph(5,2); G # long time + sage: G = graphs.UnitaryDualPolarGraph(5,2); G # long time # optional - sage.libs.gap Unitary Dual Polar Graph DU(5, 2); GQ(8, 4): Graph on 297 vertices - sage: G.is_strongly_regular(parameters=True) # long time + sage: G.is_strongly_regular(parameters=True) # long time # optional - sage.libs.gap (297, 40, 7, 5) Another way to get the generalized quadrangle of order (2,4):: - sage: G = graphs.UnitaryDualPolarGraph(4,2); G + sage: G = graphs.UnitaryDualPolarGraph(4,2); G # optional - sage.libs.gap Unitary Dual Polar Graph DU(4, 2); GQ(2, 4): Graph on 27 vertices - sage: G.is_isomorphic(graphs.OrthogonalPolarGraph(6,2,'-')) + sage: G.is_isomorphic(graphs.OrthogonalPolarGraph(6,2,'-')) # optional - sage.libs.gap True A bigger graph:: @@ -759,7 +763,7 @@ def UnitaryDualPolarGraph(m, q): TESTS:: - sage: graphs.UnitaryDualPolarGraph(6,6) + sage: graphs.UnitaryDualPolarGraph(6,6) # optional - sage.libs.gap Traceback (most recent call last): ... GAPError: Error, must be a prime or a finite field @@ -796,11 +800,11 @@ def SymplecticDualPolarGraph(m, q): TESTS:: - sage: G = graphs.SymplecticDualPolarGraph(6,2); G + sage: G = graphs.SymplecticDualPolarGraph(6,2); G # optional - sage.libs.gap Symplectic Dual Polar Graph DSp(6, 2): Graph on 135 vertices - sage: G.is_distance_regular(parameters=True) + sage: G.is_distance_regular(parameters=True) # optional - sage.libs.gap ([14, 12, 8, None], [None, 1, 3, 7]) - sage: graphs.SymplecticDualPolarGraph(6,6) + sage: graphs.SymplecticDualPolarGraph(6,6) # optional - sage.libs.gap Traceback (most recent call last): ... GAPError: Error, must be a prime or a finite field @@ -844,28 +848,28 @@ def TaylorTwographDescendantSRG(q, clique_partition=False): EXAMPLES:: - sage: g=graphs.TaylorTwographDescendantSRG(3); g + sage: g = graphs.TaylorTwographDescendantSRG(3); g # optional - sage.rings.finite_rings Taylor two-graph descendant SRG: Graph on 27 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (27, 10, 1, 5) sage: from sage.combinat.designs.twographs import taylor_twograph - sage: T = taylor_twograph(3) # long time - sage: g.is_isomorphic(T.descendant(T.ground_set()[1])) # long time + sage: T = taylor_twograph(3) # long time, optional - sage.rings.finite_rings + sage: g.is_isomorphic(T.descendant(T.ground_set()[1])) # long time, optional - sage.rings.finite_rings True - sage: g=graphs.TaylorTwographDescendantSRG(5) # not tested (long time) - sage: g.is_strongly_regular(parameters=True) # not tested (long time) + sage: g = graphs.TaylorTwographDescendantSRG(5) # not tested (long time) + sage: g.is_strongly_regular(parameters=True) # not tested (long time) (125, 52, 15, 26) TESTS:: - sage: g,l,_=graphs.TaylorTwographDescendantSRG(3,clique_partition=True) - sage: all(g.is_clique(x) for x in l) + sage: g,l,_ = graphs.TaylorTwographDescendantSRG(3, clique_partition=True) # optional - sage.rings.finite_rings + sage: all(g.is_clique(x) for x in l) # optional - sage.rings.finite_rings True - sage: graphs.TaylorTwographDescendantSRG(4) + sage: graphs.TaylorTwographDescendantSRG(4) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: q must be an odd prime power - sage: graphs.TaylorTwographDescendantSRG(6) + sage: graphs.TaylorTwographDescendantSRG(6) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: q must be an odd prime power @@ -918,9 +922,9 @@ def TaylorTwographSRG(q): EXAMPLES:: - sage: t=graphs.TaylorTwographSRG(3); t + sage: t = graphs.TaylorTwographSRG(3); t # optional - sage.rings.finite_rings Taylor two-graph SRG: Graph on 28 vertices - sage: t.is_strongly_regular(parameters=True) + sage: t.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (28, 15, 6, 10) """ G, l, v0 = TaylorTwographDescendantSRG(q, clique_partition=True) @@ -955,13 +959,13 @@ def AhrensSzekeresGeneralizedQuadrangleGraph(q, dual=False): EXAMPLES:: - sage: g=graphs.AhrensSzekeresGeneralizedQuadrangleGraph(5); g + sage: g = graphs.AhrensSzekeresGeneralizedQuadrangleGraph(5); g # optional - sage.rings.finite_rings AS(5); GQ(4, 6): Graph on 125 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (125, 28, 3, 7) - sage: g=graphs.AhrensSzekeresGeneralizedQuadrangleGraph(5,dual=True); g + sage: g = graphs.AhrensSzekeresGeneralizedQuadrangleGraph(5, dual=True); g # optional - sage.rings.finite_rings AS(5)*; GQ(6, 4): Graph on 175 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (175, 30, 5, 5) """ from sage.combinat.designs.incidence_structures import IncidenceStructure @@ -1025,34 +1029,35 @@ def T2starGeneralizedQuadrangleGraph(q, dual=False, hyperoval=None, field=None, using the built-in construction:: - sage: g=graphs.T2starGeneralizedQuadrangleGraph(4); g + sage: g = graphs.T2starGeneralizedQuadrangleGraph(4); g # optional - sage.rings.finite_rings T2*(O,4); GQ(3, 5): Graph on 64 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (64, 18, 2, 6) - sage: g=graphs.T2starGeneralizedQuadrangleGraph(4,dual=True); g + sage: g = graphs.T2starGeneralizedQuadrangleGraph(4, dual=True); g # optional - sage.rings.finite_rings T2*(O,4)*; GQ(5, 3): Graph on 96 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (96, 20, 4, 4) supplying your own hyperoval:: - sage: F=GF(4,'b') - sage: O=[vector(F,(0,0,0,1)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] - sage: g=graphs.T2starGeneralizedQuadrangleGraph(4, hyperoval=O, field=F); g + sage: F = GF(4,'b') # optional - sage.rings.finite_rings + sage: O = [vector(F,(0,0,0,1)),vector(F,(0,0,1,0))] + [vector(F, (0,1,x^2,x)) # optional - sage.rings.finite_rings + ....: for x in F] + sage: g = graphs.T2starGeneralizedQuadrangleGraph(4, hyperoval=O, field=F); g # optional - sage.rings.finite_rings T2*(O,4); GQ(3, 5): Graph on 64 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (64, 18, 2, 6) TESTS:: - sage: F=GF(4,'b') # repeating a point... - sage: O=[vector(F,(0,1,0,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] - sage: graphs.T2starGeneralizedQuadrangleGraph(4, hyperoval=O, field=F) + sage: F = GF(4,'b') # repeating a point... + sage: O = [vector(F,(0,1,0,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] # optional - sage.rings.finite_rings + sage: graphs.T2starGeneralizedQuadrangleGraph(4, hyperoval=O, field=F) # optional - sage.rings.finite_rings Traceback (most recent call last): ... RuntimeError: incorrect hyperoval size - sage: O=[vector(F,(0,1,1,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] - sage: graphs.T2starGeneralizedQuadrangleGraph(4, hyperoval=O, field=F) + sage: O = [vector(F,(0,1,1,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] # optional - sage.rings.finite_rings + sage: graphs.T2starGeneralizedQuadrangleGraph(4, hyperoval=O, field=F) # optional - sage.rings.finite_rings Traceback (most recent call last): ... RuntimeError: incorrect hyperoval @@ -1144,35 +1149,35 @@ def HaemersGraph(q, hyperoval=None, hyperoval_matching=None, field=None, check_h using the built-in constructions:: - sage: g=graphs.HaemersGraph(4); g + sage: g = graphs.HaemersGraph(4); g # optional - sage.rings.finite_rings Haemers(4): Graph on 96 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (96, 19, 2, 4) supplying your own hyperoval_matching:: - sage: g=graphs.HaemersGraph(4,hyperoval_matching=((0,5),(1,4),(2,3))); g + sage: g = graphs.HaemersGraph(4, hyperoval_matching=((0,5),(1,4),(2,3))); g # optional - sage.rings.finite_rings Haemers(4): Graph on 96 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (96, 19, 2, 4) TESTS:: - sage: F=GF(4,'b') # repeating a point... - sage: O=[vector(F,(0,1,0,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] - sage: graphs.HaemersGraph(4, hyperoval=O, field=F) + sage: F=GF(4,'b') # repeating a point... # optional - sage.rings.finite_rings + sage: O=[vector(F,(0,1,0,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] # optional - sage.rings.finite_rings + sage: graphs.HaemersGraph(4, hyperoval=O, field=F) # optional - sage.rings.finite_rings Traceback (most recent call last): ... RuntimeError: incorrect hyperoval size - sage: O=[vector(F,(0,1,1,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] - sage: graphs.HaemersGraph(4, hyperoval=O, field=F) + sage: O=[vector(F,(0,1,1,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] # optional - sage.rings.finite_rings + sage: graphs.HaemersGraph(4, hyperoval=O, field=F) # optional - sage.rings.finite_rings Traceback (most recent call last): ... RuntimeError: incorrect hyperoval - sage: g=graphs.HaemersGraph(8); g # not tested (long time) + sage: g = graphs.HaemersGraph(8); g # not tested (long time) # optional - sage.rings.finite_rings Haemers(8): Graph on 640 vertices - sage: g.is_strongly_regular(parameters=True) # not tested (long time) + sage: g.is_strongly_regular(parameters=True) # not tested (long time) # optional - sage.rings.finite_rings (640, 71, 6, 8) """ @@ -1259,20 +1264,20 @@ def CossidentePenttilaGraph(q): For `q=3` one gets Sims-Gewirtz graph. :: - sage: G=graphs.CossidentePenttilaGraph(3) # optional - gap_packages (grape) - sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape) + sage: g = graphs.CossidentePenttilaGraph(3) # optional - gap_packages (grape) + sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape) (56, 10, 0, 2) For `q>3` one gets new graphs. :: - sage: G=graphs.CossidentePenttilaGraph(5) # optional - gap_packages (grape) - sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape) + sage: g = graphs.CossidentePenttilaGraph(5) # optional - gap_packages (grape) + sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape) (378, 52, 1, 8) TESTS:: - sage: G=graphs.CossidentePenttilaGraph(7) # optional - gap_packages (grape) # long time - sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape) # long time + sage: g = graphs.CossidentePenttilaGraph(7) # optional - gap_packages (grape) # long time + sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape) # long time (1376, 150, 2, 18) sage: graphs.CossidentePenttilaGraph(2) Traceback (most recent call last): @@ -1367,32 +1372,33 @@ def Nowhere0WordsTwoWeightCodeGraph(q, hyperoval=None, field=None, check_hyperov using the built-in construction:: - sage: g=graphs.Nowhere0WordsTwoWeightCodeGraph(8); g + sage: g = graphs.Nowhere0WordsTwoWeightCodeGraph(8); g # optional - sage.rings.finite_rings Nowhere0WordsTwoWeightCodeGraph(8): Graph on 196 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (196, 60, 14, 20) - sage: g=graphs.Nowhere0WordsTwoWeightCodeGraph(16) # not tested (long time) - sage: g.is_strongly_regular(parameters=True) # not tested (long time) + sage: g = graphs.Nowhere0WordsTwoWeightCodeGraph(16) # not tested (long time) + sage: g.is_strongly_regular(parameters=True) # not tested (long time) (1800, 728, 268, 312) supplying your own hyperoval:: - sage: F=GF(8) - sage: O=[vector(F,(0,0,1)),vector(F,(0,1,0))]+[vector(F, (1,x^2,x)) for x in F] - sage: g=graphs.Nowhere0WordsTwoWeightCodeGraph(8,hyperoval=O,field=F); g + sage: F = GF(8) + sage: O = [vector(F,(0,0,1)),vector(F,(0,1,0))] + [vector(F, (1,x^2,x)) # optional - sage.rings.finite_rings + ....: for x in F] + sage: g = graphs.Nowhere0WordsTwoWeightCodeGraph(8,hyperoval=O,field=F); g # optional - sage.rings.finite_rings Nowhere0WordsTwoWeightCodeGraph(8): Graph on 196 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (196, 60, 14, 20) TESTS:: - sage: F=GF(8) # repeating a point... - sage: O=[vector(F,(1,0,0)),vector(F,(0,1,0))]+[vector(F, (1,x^2,x)) for x in F] - sage: graphs.Nowhere0WordsTwoWeightCodeGraph(8,hyperoval=O,field=F) + sage: F = GF(8) # repeating a point... # optional - sage.rings.finite_rings + sage: O = [vector(F,(1,0,0)),vector(F,(0,1,0))]+[vector(F, (1,x^2,x)) for x in F] # optional - sage.rings.finite_rings + sage: graphs.Nowhere0WordsTwoWeightCodeGraph(8,hyperoval=O,field=F) # optional - sage.rings.finite_rings Traceback (most recent call last): ... RuntimeError: incorrect hyperoval size - sage: O=[vector(F,(1,1,0)),vector(F,(0,1,0))]+[vector(F, (1,x^2,x)) for x in F] + sage: O = [vector(F,(1,1,0)),vector(F,(0,1,0))]+[vector(F, (1,x^2,x)) for x in F] # optional - sage.rings.finite_rings sage: graphs.Nowhere0WordsTwoWeightCodeGraph(8,hyperoval=O,field=F) Traceback (most recent call last): ... @@ -1461,13 +1467,13 @@ def OrthogonalDualPolarGraph(e, d, q): EXAMPLES:: - sage: G = graphs.OrthogonalDualPolarGraph(1,3,2) - sage: G.is_distance_regular(True) + sage: G = graphs.OrthogonalDualPolarGraph(1,3,2) # optional - sage.libs.gap + sage: G.is_distance_regular(True) # optional - sage.libs.gap ([7, 6, 4, None], [None, 1, 3, 7]) - sage: G = graphs.OrthogonalDualPolarGraph(0,3,3) # long time - sage: G.is_distance_regular(True) # long time + sage: G = graphs.OrthogonalDualPolarGraph(0,3,3) # long time # optional - sage.libs.gap + sage: G.is_distance_regular(True) # long time # optional - sage.libs.gap ([39, 36, 27, None], [None, 1, 4, 13]) - sage: G.order() # long time + sage: G.order() # long time # optional - sage.libs.gap 1120 REFERENCES: @@ -1476,17 +1482,17 @@ def OrthogonalDualPolarGraph(e, d, q): TESTS:: - sage: G = graphs.OrthogonalDualPolarGraph(0,3,2) - sage: G.is_distance_regular(True) + sage: G = graphs.OrthogonalDualPolarGraph(0,3,2) # optional - sage.libs.gap + sage: G.is_distance_regular(True) # optional - sage.libs.gap ([14, 12, 8, None], [None, 1, 3, 7]) - sage: G = graphs.OrthogonalDualPolarGraph(-1,3,2) # long time - sage: G.is_distance_regular(True) # long time + sage: G = graphs.OrthogonalDualPolarGraph(-1,3,2) # long time # optional - sage.libs.gap + sage: G.is_distance_regular(True) # long time # optional - sage.libs.gap ([28, 24, 16, None], [None, 1, 3, 7]) - sage: G = graphs.OrthogonalDualPolarGraph(1,3,4) - sage: G.is_distance_regular(True) + sage: G = graphs.OrthogonalDualPolarGraph(1,3,4) # optional - sage.libs.gap + sage: G.is_distance_regular(True) # optional - sage.libs.gap ([21, 20, 16, None], [None, 1, 5, 21]) - sage: G = graphs.OrthogonalDualPolarGraph(1,4,2) - sage: G.is_distance_regular(True) + sage: G = graphs.OrthogonalDualPolarGraph(1,4,2) # optional - sage.libs.gap + sage: G.is_distance_regular(True) # optional - sage.libs.gap ([15, 14, 12, 8, None], [None, 1, 3, 7, 15]) """ from sage.libs.gap.libgap import libgap diff --git a/src/sage/graphs/generators/degree_sequence.py b/src/sage/graphs/generators/degree_sequence.py index 606f96fb3fd..071878d124e 100644 --- a/src/sage/graphs/generators/degree_sequence.py +++ b/src/sage/graphs/generators/degree_sequence.py @@ -41,25 +41,25 @@ def DegreeSequence(deg_sequence): EXAMPLES:: - sage: G = graphs.DegreeSequence([3,3,3,3]) - sage: G.edges(sort=True, labels=False) + sage: G = graphs.DegreeSequence([3,3,3,3]) # optional - networkx + sage: G.edges(sort=True, labels=False) # optional - networkx [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)] - sage: G.show() # long time + sage: G.show() # long time # optional - networkx sage.plot :: - sage: G = graphs.DegreeSequence([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]) - sage: G.show() # long time + sage: G = graphs.DegreeSequence([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]) # optional - networkx + sage: G.show() # long time # optional - networkx sage.plot :: - sage: G = graphs.DegreeSequence([4,4,4,4,4,4,4,4]) - sage: G.show() # long time + sage: G = graphs.DegreeSequence([4,4,4,4,4,4,4,4]) # optional - networkx + sage: G.show() # long time # optional - networkx sage.plot :: - sage: G = graphs.DegreeSequence([1,2,3,4,3,4,3,2,3,2,1]) - sage: G.show() # long time + sage: G = graphs.DegreeSequence([1,2,3,4,3,4,3,2,3,2,1]) # optional - networkx + sage: G.show() # long time # optional - networkx sage.plot """ import networkx return Graph(networkx.havel_hakimi_graph([int(i) for i in deg_sequence])) @@ -93,15 +93,15 @@ def DegreeSequenceBipartite(s1, s2): If we are given as sequences ``[2,2,2,2,2]`` and ``[5,5]`` we are given as expected the complete bipartite graph `K_{2,5}`:: - sage: g = graphs.DegreeSequenceBipartite([2,2,2,2,2],[5,5]) - sage: g.is_isomorphic(graphs.CompleteBipartiteGraph(5,2)) + sage: g = graphs.DegreeSequenceBipartite([2,2,2,2,2],[5,5]) # optional - sage.modules + sage: g.is_isomorphic(graphs.CompleteBipartiteGraph(5,2)) # optional - sage.modules True Some sequences being incompatible if, for example, their sums are different, the functions raises a ``ValueError`` when no graph corresponding to the degree sequences exists:: - sage: g = graphs.DegreeSequenceBipartite([2,2,2,2,1],[5,5]) + sage: g = graphs.DegreeSequenceBipartite([2,2,2,2,1],[5,5]) # optional - sage.modules Traceback (most recent call last): ... ValueError: there exists no bipartite graph corresponding to the given degree sequences @@ -110,7 +110,7 @@ def DegreeSequenceBipartite(s1, s2): :trac:`12155`:: - sage: graphs.DegreeSequenceBipartite([2,2,2,2,2],[5,5]).complement() + sage: graphs.DegreeSequenceBipartite([2,2,2,2,2],[5,5]).complement() # optional - sage.modules Graph on 7 vertices """ from sage.combinat.integer_vector import gale_ryser_theorem @@ -147,20 +147,20 @@ def DegreeSequenceConfigurationModel(deg_sequence, seed=None): EXAMPLES:: - sage: G = graphs.DegreeSequenceConfigurationModel([1,1]) - sage: G.adjacency_matrix() + sage: G = graphs.DegreeSequenceConfigurationModel([1,1]) # optional - networkx + sage: G.adjacency_matrix() # optional - networkx sage.modules [0 1] [1 0] The output is allowed to contain both loops and multiple edges:: - sage: deg_sequence = [3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3] - sage: G = graphs.DegreeSequenceConfigurationModel(deg_sequence) - sage: G.order(), G.size() + sage: deg_sequence = [3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3] # optional - networkx + sage: G = graphs.DegreeSequenceConfigurationModel(deg_sequence) # optional - networkx + sage: G.order(), G.size() # optional - networkx (20, 30) - sage: G.has_loops() or G.has_multiple_edges() # random + sage: G.has_loops() or G.has_multiple_edges() # random # optional - networkx True - sage: G.show() # long time + sage: G.show() # long time # optional - networkx sage.plot REFERENCE: @@ -191,10 +191,9 @@ def DegreeSequenceTree(deg_sequence): EXAMPLES:: - sage: G = graphs.DegreeSequenceTree([3,1,3,3,1,1,1,2,1]) - sage: G + sage: G = graphs.DegreeSequenceTree([3,1,3,3,1,1,1,2,1]); G # optional - networkx Graph on 9 vertices - sage: G.show() # long time + sage: G.show() # long time # optional - networkx sage.plot """ import networkx return Graph(networkx.degree_sequence_tree([int(i) for i in deg_sequence])) @@ -220,10 +219,9 @@ def DegreeSequenceExpected(deg_sequence, seed=None): EXAMPLES:: - sage: G = graphs.DegreeSequenceExpected([1,2,3,2,3]) - sage: G + sage: G = graphs.DegreeSequenceExpected([1,2,3,2,3]); G # optional - networkx Looped graph on 5 vertices - sage: G.show() # long time + sage: G.show() # long time # optional - networkx sage.plot REFERENCE: diff --git a/src/sage/graphs/generators/distance_regular.pyx b/src/sage/graphs/generators/distance_regular.pyx index 0df5f3e66b5..dd809a835af 100644 --- a/src/sage/graphs/generators/distance_regular.pyx +++ b/src/sage/graphs/generators/distance_regular.pyx @@ -35,15 +35,12 @@ AUTHORS: # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.coding import codes_catalog as codes -from sage.graphs.graph import Graph -from sage.libs.gap.libgap import libgap -from sage.modules.free_module import VectorSpace -from sage.modules.free_module_element import vector -from sage.rings.finite_rings.finite_field_constructor import GF -from sage.matrix.constructor import Matrix import itertools + from cysignals.signals cimport sig_check + +from sage.graphs.graph import Graph +from sage.misc.lazy_import import LazyImport from sage.graphs.generators.smallgraphs import (FosterGraph, BiggsSmithGraph, CoxeterGraph, LivingstoneGraph, WellsGraph, GossetGraph, @@ -53,6 +50,13 @@ from sage.graphs.generators.smallgraphs import (FosterGraph, BiggsSmithGraph, from sage.graphs.generators.platonic_solids import DodecahedralGraph from sage.graphs.strongly_regular_db import strongly_regular_graph +codes = LazyImport('sage.coding', 'codes_catalog', as_name='codes') +libgap = LazyImport('sage.libs.gap.libgap', 'libgap') +Matrix = LazyImport('sage.matrix.constructor', 'Matrix') +VectorSpace = LazyImport('sage.modules.free_module', 'VectorSpace') +vector = LazyImport('sage.modules.free_module_element', 'vector') +GF = LazyImport('sage.rings.finite_rings.finite_field_constructor', 'GF') + def cocliques_HoffmannSingleton(): r""" diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index f6c7b89bca7..30396e1ab9e 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -452,7 +452,7 @@ def HammingGraph(n, q, X=None): True sage: g.is_regular() True - sage: g.is_vertex_transitive() + sage: g.is_vertex_transitive() # optional - sage.groups True A Hamming graph with parameters (1,q) is isomorphic to the @@ -526,9 +526,9 @@ def BalancedTree(r, h): A balanced tree whose root node has degree `r = 2`, and of height `h = 1`, has order 3 and size 2:: - sage: G = graphs.BalancedTree(2, 1); G + sage: G = graphs.BalancedTree(2, 1); G # optional - networkx Balanced tree: Graph on 3 vertices - sage: G.order(); G.size() + sage: G.order(); G.size() # optional - networkx 3 2 sage: r = 2; h = 1 @@ -539,21 +539,21 @@ def BalancedTree(r, h): Plot a balanced tree of height 5, whose root node has degree `r = 3`:: - sage: G = graphs.BalancedTree(3, 5) - sage: G.show() # long time + sage: G = graphs.BalancedTree(3, 5) # optional - networkx + sage: G.show() # long time # optional - networkx sage.plot A tree is bipartite. If its vertex set is finite, then it is planar. :: sage: r = randint(2, 5); h = randint(1, 7) - sage: T = graphs.BalancedTree(r, h) - sage: T.is_bipartite() + sage: T = graphs.BalancedTree(r, h) # optional - networkx + sage: T.is_bipartite() # optional - networkx True - sage: T.is_planar() + sage: T.is_planar() # optional - networkx True - sage: v = (r^(h + 1) - 1) / (r - 1) - sage: T.order() == v + sage: v = (r^(h + 1) - 1) / (r - 1) # optional - networkx + sage: T.order() == v # optional - networkx True - sage: T.size() == v - 1 + sage: T.size() == v - 1 # optional - networkx True TESTS: @@ -562,13 +562,13 @@ def BalancedTree(r, h): has degree `r \geq 2`, but the construction degenerates gracefully:: - sage: graphs.BalancedTree(1, 10) + sage: graphs.BalancedTree(1, 10) # optional - networkx Balanced tree: Graph on 11 vertices Similarly, we usually want the tree must have height `h \geq 1` but the algorithm also degenerates gracefully here:: - sage: graphs.BalancedTree(3, 0) + sage: graphs.BalancedTree(3, 0) # optional - networkx Balanced tree: Graph on 1 vertex """ import networkx @@ -627,11 +627,11 @@ def BarbellGraph(n1, n2): True sage: K_n1 = graphs.CompleteGraph(n1) sage: P_n2 = graphs.PathGraph(n2) - sage: s_K = g.subgraph_search(K_n1, induced=True) - sage: s_P = g.subgraph_search(P_n2, induced=True) - sage: K_n1.is_isomorphic(s_K) + sage: s_K = g.subgraph_search(K_n1, induced=True) # optional - sage.modules + sage: s_P = g.subgraph_search(P_n2, induced=True) # optional - sage.modules + sage: K_n1.is_isomorphic(s_K) # optional - sage.modules True - sage: P_n2.is_isomorphic(s_P) + sage: P_n2.is_isomorphic(s_P) # optional - sage.modules True TESTS:: @@ -1025,13 +1025,13 @@ def chang_graphs(): Construct the Chang graphs by Seidel switching:: - sage: c3c5=graphs.CycleGraph(3).disjoint_union(graphs.CycleGraph(5)) - sage: c8=graphs.CycleGraph(8) - sage: s=[K8.subgraph_search(c8).edges(sort=False), - ....: [(0,1,None),(2,3,None),(4,5,None),(6,7,None)], - ....: K8.subgraph_search(c3c5).edges(sort=False)] - sage: list(map(lambda x,G: T8.seidel_switching(x, inplace=False).is_isomorphic(G), - ....: s, chang_graphs)) + sage: c3c5 = graphs.CycleGraph(3).disjoint_union(graphs.CycleGraph(5)) + sage: c8 = graphs.CycleGraph(8) + sage: s = [K8.subgraph_search(c8).edges(sort=False), # optional - sage.modules + ....: [(0,1,None),(2,3,None),(4,5,None),(6,7,None)], + ....: K8.subgraph_search(c3c5).edges(sort=False)] + sage: [T8.seidel_switching(x, inplace=False).is_isomorphic(G) # optional - sage.modules + ....: for x, G in zip(s, chang_graphs)] [True, True, True] """ @@ -1353,8 +1353,8 @@ def DorogovtsevGoltsevMendesGraph(n): EXAMPLES:: - sage: G = graphs.DorogovtsevGoltsevMendesGraph(8) - sage: G.size() + sage: G = graphs.DorogovtsevGoltsevMendesGraph(8) # optional - networkx + sage: G.size() # optional - networkx 6561 REFERENCE: @@ -1538,7 +1538,7 @@ def FuzzyBallGraph(partition, q): EXAMPLES:: sage: F = graphs.FuzzyBallGraph([3,1],2) - sage: F.adjacency_matrix(vertices=list(F)) + sage: F.adjacency_matrix(vertices=list(F)) # optional - sage.modules [0 0 1 1 1 0 0 0] [0 0 0 0 0 1 0 0] [1 0 0 1 1 1 1 1] @@ -1553,10 +1553,14 @@ def FuzzyBallGraph(partition, q): `k` parts should be cospectral with respect to the normalized Laplacian:: - sage: m=4; q=2; k=2 - sage: g_list=[graphs.FuzzyBallGraph(p,q) for p in Partitions(m, length=k)] - sage: set([g.laplacian_matrix(normalized=True, vertices=list(g)).charpoly() for g in g_list]) # long time (7s on sage.math, 2011) - {x^8 - 8*x^7 + 4079/150*x^6 - 68689/1350*x^5 + 610783/10800*x^4 - 120877/3240*x^3 + 1351/100*x^2 - 931/450*x} + sage: m = 4; q = 2; k = 2 + sage: g_list = [graphs.FuzzyBallGraph(p,q) # optional - sage.combinat sage.modules + ....: for p in Partitions(m, length=k)] + sage: set(g.laplacian_matrix(normalized=True, # long time (7s on sage.math, 2011), optional - sage.combinat sage.modules + ....: vertices=list(g)).charpoly() + ....: for g in g_list) + {x^8 - 8*x^7 + 4079/150*x^6 - 68689/1350*x^5 + 610783/10800*x^4 + - 120877/3240*x^3 + 1351/100*x^2 - 931/450*x} """ from sage.graphs.generators.basic import CompleteGraph if len(partition) < 1: @@ -2203,30 +2207,31 @@ def LCFGraph(n, shift_list, repeats): EXAMPLES:: - sage: G = graphs.LCFGraph(4, [2,-2], 2) - sage: G.is_isomorphic(graphs.TetrahedralGraph()) + sage: G = graphs.LCFGraph(4, [2,-2], 2) # optional - networkx + sage: G.is_isomorphic(graphs.TetrahedralGraph()) # optional - networkx True :: - sage: G = graphs.LCFGraph(20, [10,7,4,-4,-7,10,-4,7,-7,4], 2) - sage: G.is_isomorphic(graphs.DodecahedralGraph()) + sage: G = graphs.LCFGraph(20, [10,7,4,-4,-7,10,-4,7,-7,4], 2) # optional - networkx + sage: G.is_isomorphic(graphs.DodecahedralGraph()) # optional - networkx True :: - sage: G = graphs.LCFGraph(14, [5,-5], 7) - sage: G.is_isomorphic(graphs.HeawoodGraph()) + sage: G = graphs.LCFGraph(14, [5,-5], 7) # optional - networkx + sage: G.is_isomorphic(graphs.HeawoodGraph()) # optional - networkx True The largest cubic nonplanar graph of diameter three:: - sage: G = graphs.LCFGraph(20, [-10,-7,-5,4,7,-10,-7,-4,5,7,-10,-7,6,-5,7,-10,-7,5,-6,7], 1) - sage: G.degree() + sage: G = graphs.LCFGraph(20, [-10,-7,-5,4,7,-10,-7,-4,5,7, # optional - networkx + ....: -10,-7,6,-5,7,-10,-7,5,-6,7], 1) + sage: G.degree() # optional - networkx [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] - sage: G.diameter() + sage: G.diameter() # optional - networkx 3 - sage: G.show() # long time + sage: G.show() # long time # optional - networkx sage.plot PLOTTING: LCF Graphs are plotted as an n-cycle with edges in the middle, as described above. @@ -2583,9 +2588,9 @@ def PasechnikGraph(n): EXAMPLES:: - sage: graphs.PasechnikGraph(4).is_strongly_regular(parameters=True) + sage: graphs.PasechnikGraph(4).is_strongly_regular(parameters=True) # optional - sage.combinat sage.modules (225, 98, 43, 42) - sage: graphs.PasechnikGraph(5).is_strongly_regular(parameters=True) # long time + sage: graphs.PasechnikGraph(5).is_strongly_regular(parameters=True) # long time, optional - sage.combinat sage.modules (361, 162, 73, 72) sage: graphs.PasechnikGraph(9).is_strongly_regular(parameters=True) # not tested (1225, 578, 273, 272) diff --git a/src/sage/graphs/generators/random.py b/src/sage/graphs/generators/random.py index a947f4488c9..288515ac397 100644 --- a/src/sage/graphs/generators/random.py +++ b/src/sage/graphs/generators/random.py @@ -97,7 +97,7 @@ def RandomGNP(n, p, seed=None, fast=True, algorithm='Sage'): sage: set_random_seed(0) sage: graphs.RandomGNP(50,.2, algorithm="Sage").size() 243 - sage: graphs.RandomGNP(50,.2, algorithm="networkx").size() + sage: graphs.RandomGNP(50,.2, algorithm="networkx").size() # optional - networkx 279 # 32-bit 209 # 64-bit """ @@ -149,35 +149,35 @@ def RandomBarabasiAlbert(n, m, seed=None): We show the edge list of a random graph on 6 nodes with `m = 2`:: - sage: G = graphs.RandomBarabasiAlbert(6,2) - sage: G.order(), G.size() + sage: G = graphs.RandomBarabasiAlbert(6,2) # optional - networkx + sage: G.order(), G.size() # optional - networkx (6, 8) - sage: G.degree_sequence() # random + sage: G.degree_sequence() # random # optional - networkx [4, 3, 3, 2, 2, 2] We plot a random graph on 12 nodes with `m = 3`:: - sage: ba = graphs.RandomBarabasiAlbert(12,3) - sage: ba.show() # long time + sage: ba = graphs.RandomBarabasiAlbert(12,3) # optional - networkx + sage: ba.show() # long time # optional - networkx sage.plot We view many random graphs using a graphics array:: sage: g = [] sage: j = [] - sage: for i in range(1,10): + sage: for i in range(1,10): # optional - networkx ....: k = graphs.RandomBarabasiAlbert(i+3, 3) ....: g.append(k) - sage: for i in range(3): # optional - sage.plot + sage: for i in range(3): # optional - networkx sage.plot ....: n = [] ....: for m in range(3): ....: n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False)) ....: j.append(n) - sage: G = graphics_array(j) # optional - sage.plot - sage: G.show() # long time # optional - sage.plot + sage: G = graphics_array(j) # optional - networkx sage.plot + sage: G.show() # long time # optional - networkx sage.plot When `m = 1`, the generated graph is a tree:: - sage: graphs.RandomBarabasiAlbert(6, 1).is_tree() + sage: graphs.RandomBarabasiAlbert(6, 1).is_tree() # optional - networkx True """ if seed is None: @@ -206,35 +206,35 @@ def RandomBipartite(n1, n2, p, set_position=False, seed=None): EXAMPLES:: - sage: g = graphs.RandomBipartite(5, 2, 0.5) - sage: g.vertices(sort=True) + sage: g = graphs.RandomBipartite(5, 2, 0.5) # optional - numpy + sage: g.vertices(sort=True) # optional - numpy [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1)] TESTS:: - sage: g = graphs.RandomBipartite(5, -3, 0.5) + sage: g = graphs.RandomBipartite(5, -3, 0.5) # optional - numpy Traceback (most recent call last): ... ValueError: n1 and n2 should be integers strictly greater than 0 - sage: g = graphs.RandomBipartite(5, 3, 1.5) + sage: g = graphs.RandomBipartite(5, 3, 1.5) # optional - numpy Traceback (most recent call last): ... ValueError: parameter p is a probability, and so should be a real value between 0 and 1 :trac:`12155`:: - sage: graphs.RandomBipartite(5, 6, .2).complement() + sage: graphs.RandomBipartite(5, 6, .2).complement() # optional - numpy complement(Random bipartite graph of order 5+6 with edge probability 0.200000000000000): Graph on 11 vertices Test assigned positions:: - sage: graphs.RandomBipartite(1, 2, .1, set_position=True).get_pos() + sage: graphs.RandomBipartite(1, 2, .1, set_position=True).get_pos() # optional - numpy {(0, 0): (1, 1.0), (1, 0): (0, 0), (1, 1): (2.0, 0.0)} - sage: graphs.RandomBipartite(2, 1, .1, set_position=True).get_pos() + sage: graphs.RandomBipartite(2, 1, .1, set_position=True).get_pos() # optional - numpy {(0, 0): (0, 1), (0, 1): (2.0, 1.0), (1, 0): (1, 0.0)} - sage: graphs.RandomBipartite(2, 2, .1, set_position=True).get_pos() + sage: graphs.RandomBipartite(2, 2, .1, set_position=True).get_pos() # optional - numpy {(0, 0): (0, 1), (0, 1): (2.0, 1.0), (1, 0): (0, 0), (1, 1): (2.0, 0.0)} - sage: graphs.RandomBipartite(2, 2, .1, set_position=False).get_pos() + sage: graphs.RandomBipartite(2, 2, .1, set_position=False).get_pos() # optional - numpy """ if not (p >= 0 and p <= 1): @@ -665,12 +665,12 @@ def RandomGNM(n, m, dense=False, seed=None): INPUT: - - ``n`` - number of vertices. + - ``n`` -- number of vertices. - - ``m`` - number of edges. + - ``m`` -- number of edges. - - ``dense`` - whether to use NetworkX's - dense_gnm_random_graph or gnm_random_graph + - ``dense`` -- whether to use NetworkX's + :func:`dense_gnm_random_graph` or :func:`gnm_random_graph` - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random number generator (default: ``None``) @@ -679,28 +679,28 @@ def RandomGNM(n, m, dense=False, seed=None): We show the edge list of a random graph on 5 nodes with 10 edges:: - sage: graphs.RandomGNM(5, 10).edges(sort=True, labels=False) + sage: graphs.RandomGNM(5, 10).edges(sort=True, labels=False) # optional - networkx [(0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] We plot a random graph on 12 nodes with m = 12:: - sage: gnm = graphs.RandomGNM(12, 12) - sage: gnm.show() # long time + sage: gnm = graphs.RandomGNM(12, 12) # optional - networkx + sage: gnm.show() # long time # optional - networkx sage.plot We view many random graphs using a graphics array:: sage: g = [] sage: j = [] - sage: for i in range(9): + sage: for i in range(9): # optional - networkx ....: k = graphs.RandomGNM(i+3, i^2-i) ....: g.append(k) - sage: for i in range(3): # optional - sage.plot + sage: for i in range(3): # optional - networkx sage.plot ....: n = [] ....: for m in range(3): ....: n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False)) ....: j.append(n) - sage: G = graphics_array(j) # optional - sage.plot - sage: G.show() # long time # optional - sage.plot + sage: G = graphics_array(j) # optional - networkx sage.plot + sage: G.show() # long time # optional - networkx sage.plot """ if seed is None: seed = int(current_randstate().long_seed() % sys.maxsize) @@ -737,33 +737,33 @@ def RandomNewmanWattsStrogatz(n, k, p, seed=None): We check that the generated graph contains a cycle of order `n`:: - sage: G = graphs.RandomNewmanWattsStrogatz(7, 2, 0.2) - sage: G.order() + sage: G = graphs.RandomNewmanWattsStrogatz(7, 2, 0.2) # optional - networkx + sage: G.order() # optional - networkx 7 - sage: C7 = graphs.CycleGraph(7) - sage: G.subgraph_search(C7) + sage: C7 = graphs.CycleGraph(7) # optional - networkx + sage: G.subgraph_search(C7) # optional - networkx Subgraph of (): Graph on 7 vertices - sage: G.diameter() <= C7.diameter() + sage: G.diameter() <= C7.diameter() # optional - networkx True :: - sage: G = graphs.RandomNewmanWattsStrogatz(12, 2, .3) - sage: G.show() # long time + sage: G = graphs.RandomNewmanWattsStrogatz(12, 2, .3) # optional - networkx + sage: G.show() # long time # optional - networkx sage.plot TESTS: We check that when `k = 2` and `p = 0`, the generated graph is a cycle:: - sage: G = graphs.RandomNewmanWattsStrogatz(7, 2, 0) - sage: G.is_cycle() + sage: G = graphs.RandomNewmanWattsStrogatz(7, 2, 0) # optional - networkx + sage: G.is_cycle() # optional - networkx True We check that when `k = 4` and `p = 0`, the generated graph is a circulant graph of parameters ``[1, 2]``:: - sage: G = graphs.RandomNewmanWattsStrogatz(7, 4, 0) - sage: G.is_isomorphic(graphs.CirculantGraph(7, [1, 2])) + sage: G = graphs.RandomNewmanWattsStrogatz(7, 4, 0) # optional - networkx + sage: G.is_isomorphic(graphs.CirculantGraph(7, [1, 2])) # optional - networkx True REFERENCE: @@ -807,8 +807,8 @@ def RandomHolmeKim(n, m, p, seed=None): EXAMPLES:: - sage: G = graphs.RandomHolmeKim(12, 3, .3) - sage: G.show() # long time + sage: G = graphs.RandomHolmeKim(12, 3, .3) # optional - networkx + sage: G.show() # long time # optional - networkx sage.plot REFERENCE: @@ -952,8 +952,8 @@ def connecting_nodes(T, l): sage: from sage.graphs.generators.random import connecting_nodes sage: T = graphs.RandomTree(10) - sage: S = connecting_nodes(T, 5) - sage: len(S) + sage: S = connecting_nodes(T, 5) # optional - numpy + sage: len(S) # optional - numpy 10 """ from sage.combinat.permutation import Permutations @@ -1178,8 +1178,8 @@ def RandomChordalGraph(n, algorithm="growing", k=None, l=None, f=None, s=None, s sage: T = RandomChordalGraph(20, algorithm="growing", k=5) sage: T.is_chordal() True - sage: T = RandomChordalGraph(20, algorithm="connecting", l=3) - sage: T.is_chordal() + sage: T = RandomChordalGraph(20, algorithm="connecting", l=3) # optional - numpy + sage: T.is_chordal() # optional - numpy True sage: T = RandomChordalGraph(20, algorithm="pruned", f=1/3, s=.5) sage: T.is_chordal() @@ -1303,13 +1303,13 @@ def RandomLobster(n, p, q, seed=None): We check a random graph with 12 backbone nodes and probabilities `p = 0.7` and `q = 0.3`:: - sage: G = graphs.RandomLobster(12, 0.7, 0.3) - sage: leaves = [v for v in G.vertices(sort=False) if G.degree(v) == 1] - sage: G.delete_vertices(leaves) # caterpillar - sage: leaves = [v for v in G.vertices(sort=False) if G.degree(v) == 1] - sage: G.delete_vertices(leaves) # path - sage: s = G.degree_sequence() - sage: if G: + sage: G = graphs.RandomLobster(12, 0.7, 0.3) # optional - networkx + sage: leaves = [v for v in G.vertices(sort=False) if G.degree(v) == 1] # optional - networkx + sage: G.delete_vertices(leaves) # caterpillar # optional - networkx + sage: leaves = [v for v in G.vertices(sort=False) if G.degree(v) == 1] # optional - networkx + sage: G.delete_vertices(leaves) # path # optional - networkx + sage: s = G.degree_sequence() # optional - networkx + sage: if G: # optional - networkx ....: if G.num_verts() == 1: ....: assert s == [0] ....: else: @@ -1318,8 +1318,8 @@ def RandomLobster(n, p, q, seed=None): :: - sage: G = graphs.RandomLobster(9, .6, .3) - sage: G.show() # long time + sage: G = graphs.RandomLobster(9, .6, .3) # optional - networkx + sage: G.show() # long time # optional - networkx sage.plot """ if seed is None: seed = int(current_randstate().long_seed() % sys.maxsize) @@ -1434,16 +1434,16 @@ def RandomTreePowerlaw(n, gamma=3, tries=1000, seed=None): We check that the generated graph is a tree:: - sage: G = graphs.RandomTreePowerlaw(10, 3) - sage: G.is_tree() + sage: G = graphs.RandomTreePowerlaw(10, 3) # optional - networkx + sage: G.is_tree() # optional - networkx True - sage: G.order(), G.size() + sage: G.order(), G.size() # optional - networkx (10, 9) :: - sage: G = graphs.RandomTreePowerlaw(15, 2) - sage: if G: # random output, long time + sage: G = graphs.RandomTreePowerlaw(15, 2) # optional - networkx + sage: if G: # random output, long time # optional - networkx sage.plot ....: G.show() """ if seed is None: @@ -1474,16 +1474,16 @@ def RandomRegular(d, n, seed=None): We check that a random graph with 8 nodes each of degree 3 is 3-regular:: - sage: G = graphs.RandomRegular(3, 8) - sage: G.is_regular(k=3) + sage: G = graphs.RandomRegular(3, 8) # optional - networkx + sage: G.is_regular(k=3) # optional - networkx True - sage: G.degree_histogram() + sage: G.degree_histogram() # optional - networkx [0, 0, 0, 8] :: - sage: G = graphs.RandomRegular(3, 20) - sage: if G: # random output, long time + sage: G = graphs.RandomRegular(3, 20) # optional - networkx + sage: if G: # random output, long time # optional - networkx sage.plot ....: G.show() REFERENCES: @@ -1524,10 +1524,10 @@ def RandomShell(constructor, seed=None): EXAMPLES:: - sage: G = graphs.RandomShell([(10,20,0.8),(20,40,0.8)]) - sage: G.order(), G.size() + sage: G = graphs.RandomShell([(10,20,0.8),(20,40,0.8)]) # optional - networkx + sage: G.order(), G.size() # optional - networkx (30, 52) - sage: G.show() # long time + sage: G.show() # long time # optional - networkx sage.plot """ if seed is None: seed = int(current_randstate().long_seed() % sys.maxsize) @@ -2005,16 +2005,16 @@ def blossoming_contour(t, shift=0, seed=None): sage: print(blossoming_contour(BinaryTrees(1).an_element())) [('i', 0), ('xb',), ('i', 0), ('xb',), ('i', 0)] - sage: t = BinaryTrees(2).random_element() - sage: print(blossoming_contour(t)) # random + sage: t = BinaryTrees(2).random_element() # optional - sage.combinat + sage: print(blossoming_contour(t)) # random # optional - sage.combinat [('i', 0), ('xb',), ('i', 0), ('n', 2), ('i', 1), ('xb',), ('i', 1), ('xb',), ('i', 1), ('n', 2), ('x',), ('n', 2), ('i', 0)] - sage: w = blossoming_contour(BinaryTrees(3).random_element()); len(w) + sage: w = blossoming_contour(BinaryTrees(3).random_element()); len(w) # optional - sage.combinat 21 - sage: w.count(('xb',)) + sage: w.count(('xb',)) # optional - sage.combinat 4 - sage: w.count(('x',)) + sage: w.count(('x',)) # optional - sage.combinat 2 TESTS:: @@ -2099,16 +2099,16 @@ def RandomBicubicPlanar(n, seed=None): EXAMPLES:: sage: n = randint(200, 300) - sage: G = graphs.RandomBicubicPlanar(n) - sage: G.order() == 2*n + sage: G = graphs.RandomBicubicPlanar(n) # optional - sage.combinat + sage: G.order() == 2*n # optional - sage.combinat True - sage: G.size() == 3*n + sage: G.size() == 3*n # optional - sage.combinat True - sage: G.is_bipartite() and G.is_planar() and G.is_regular(3) + sage: G.is_bipartite() and G.is_planar() and G.is_regular(3) # optional - sage.combinat True - sage: dic = {'red': [v for v in G.vertices(sort=False) if v[0] == 'n'], + sage: dic = {'red': [v for v in G.vertices(sort=False) if v[0] == 'n'], # optional - sage.combinat ....: 'blue': [v for v in G.vertices(sort=False) if v[0] != 'n']} - sage: G.plot(vertex_labels=False, vertex_size=20, vertex_colors=dic) # optional - sage.plot + sage: G.plot(vertex_labels=False, vertex_size=20, vertex_colors=dic) # optional - sage.combinat sage.plot Graphics object consisting of ... graphics primitives .. PLOT:: @@ -2212,21 +2212,21 @@ def RandomUnitDiskGraph(n, radius=.1, side=1, seed=None): sage: from sage.misc.randstate import current_randstate sage: seed = current_randstate().seed() - sage: G = graphs.RandomUnitDiskGraph(20, radius=.5, side=1, seed=seed) - sage: H = graphs.RandomUnitDiskGraph(20, radius=.2, side=1, seed=seed) - sage: H.is_subgraph(G, induced=False) + sage: G = graphs.RandomUnitDiskGraph(20, radius=.5, side=1, seed=seed) # optional - scipy + sage: H = graphs.RandomUnitDiskGraph(20, radius=.2, side=1, seed=seed) # optional - scipy + sage: H.is_subgraph(G, induced=False) # optional - scipy True - sage: H.size() <= G.size() + sage: H.size() <= G.size() # optional - scipy True - sage: Gpos = G.get_pos() - sage: Hpos = H.get_pos() - sage: all(Gpos[u] == Hpos[u] for u in G) + sage: Gpos = G.get_pos() # optional - scipy + sage: Hpos = H.get_pos() # optional - scipy + sage: all(Gpos[u] == Hpos[u] for u in G) # optional - scipy True When the radius is more than `\sqrt{2 \text{side}}`, the graph is a clique:: - sage: G = graphs.RandomUnitDiskGraph(10, radius=2, side=1) - sage: G.is_clique() + sage: G = graphs.RandomUnitDiskGraph(10, radius=2, side=1) # optional - scipy + sage: G.is_clique() # optional - scipy True """ if seed is not None: diff --git a/src/sage/graphs/generators/smallgraphs.py b/src/sage/graphs/generators/smallgraphs.py index f25d5b4e561..36275b2ce57 100644 --- a/src/sage/graphs/generators/smallgraphs.py +++ b/src/sage/graphs/generators/smallgraphs.py @@ -139,21 +139,21 @@ def HarriesGraph(embedding=1): EXAMPLES:: - sage: g = graphs.HarriesGraph() - sage: g.order() + sage: g = graphs.HarriesGraph() # optional - networkx + sage: g.order() # optional - networkx 70 - sage: g.size() + sage: g.size() # optional - networkx 105 - sage: g.girth() + sage: g.girth() # optional - networkx 10 - sage: g.diameter() + sage: g.diameter() # optional - networkx 6 - sage: g.show(figsize=[10, 10]) # long time - sage: graphs.HarriesGraph(embedding=2).show(figsize=[10, 10]) # long time + sage: g.show(figsize=[10, 10]) # long time # optional - networkx sage.plot + sage: graphs.HarriesGraph(embedding=2).show(figsize=[10, 10]) # long time # optional - networkx sage.plot TESTS:: - sage: graphs.HarriesGraph(embedding=3) + sage: graphs.HarriesGraph(embedding=3) # optional - networkx Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 @@ -257,25 +257,25 @@ def HarriesWongGraph(embedding=1): EXAMPLES:: - sage: g = graphs.HarriesWongGraph() - sage: g.order() + sage: g = graphs.HarriesWongGraph() # optional - networkx + sage: g.order() # optional - networkx 70 - sage: g.size() + sage: g.size() # optional - networkx 105 - sage: g.girth() + sage: g.girth() # optional - networkx 10 - sage: g.diameter() + sage: g.diameter() # optional - networkx 6 - sage: orbits = g.automorphism_group(orbits=True)[-1] # long time - sage: g.show(figsize=[15, 15], partition=orbits) # long time + sage: orbits = g.automorphism_group(orbits=True)[-1] # long time # optional - networkx sage.groups + sage: g.show(figsize=[15, 15], partition=orbits) # long time # optional - networkx sage.groups sage.plot Alternative embedding:: - sage: graphs.HarriesWongGraph(embedding=2).show() # long time + sage: graphs.HarriesWongGraph(embedding=2).show() # long time # optional - networkx sage.plot TESTS:: - sage: graphs.HarriesWongGraph(embedding=3) + sage: graphs.HarriesWongGraph(embedding=3) # optional - networkx Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 @@ -679,7 +679,7 @@ def HallJankoGraph(from_string=True): sage: g = graphs.HallJankoGraph() sage: g.is_regular(36) True - sage: g.is_vertex_transitive() + sage: g.is_vertex_transitive() # optional - sage.groups True Is it really strongly regular with parameters 14, 12? :: @@ -804,20 +804,20 @@ def Balaban10Cage(embedding=1): EXAMPLES:: - sage: g = graphs.Balaban10Cage() - sage: g.girth() + sage: g = graphs.Balaban10Cage() # optional - networkx + sage: g.girth() # optional - networkx 10 - sage: g.chromatic_number() + sage: g.chromatic_number() # optional - networkx 2 - sage: g.diameter() + sage: g.diameter() # optional - networkx 6 - sage: g.is_hamiltonian() + sage: g.is_hamiltonian() # optional - networkx True - sage: g.show(figsize=[10,10]) # long time + sage: g.show(figsize=[10,10]) # long time # optional - networkx sage.plot TESTS:: - sage: graphs.Balaban10Cage(embedding='foo') + sage: graphs.Balaban10Cage(embedding='foo') # optional - networkx Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 @@ -897,7 +897,7 @@ def Balaban11Cage(embedding=1): 11 sage: g.diameter() 8 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 64 Our many embeddings:: @@ -905,9 +905,9 @@ def Balaban11Cage(embedding=1): sage: g1 = graphs.Balaban11Cage(embedding=1) sage: g2 = graphs.Balaban11Cage(embedding=2) sage: g3 = graphs.Balaban11Cage(embedding=3) - sage: g1.show(figsize=[10,10]) # long time - sage: g2.show(figsize=[10,10]) # long time - sage: g3.show(figsize=[10,10]) # long time + sage: g1.show(figsize=[10,10]) # long time # optional - sage.plot + sage: g2.show(figsize=[10,10]) # long time # optional - sage.plot + sage: g3.show(figsize=[10,10]) # long time # optional - sage.plot Proof that the embeddings are the same graph:: @@ -1114,26 +1114,26 @@ def BiggsSmithGraph(embedding=1): Basic properties:: - sage: g = graphs.BiggsSmithGraph() - sage: g.order() + sage: g = graphs.BiggsSmithGraph() # optional - networkx + sage: g.order() # optional - networkx 102 - sage: g.size() + sage: g.size() # optional - networkx 153 - sage: g.girth() + sage: g.girth() # optional - networkx 9 - sage: g.diameter() + sage: g.diameter() # optional - networkx 7 - sage: g.automorphism_group().cardinality() # long time + sage: g.automorphism_group().cardinality() # long time # optional - networkx 2448 - sage: g.show(figsize=[10, 10]) # long time + sage: g.show(figsize=[10, 10]) # long time # optional - networkx sage.plot The other embedding:: - sage: graphs.BiggsSmithGraph(embedding=2).show() # long time + sage: graphs.BiggsSmithGraph(embedding=2).show() # long time # optional - networkx TESTS:: - sage: graphs.BiggsSmithGraph(embedding='xyzzy') + sage: graphs.BiggsSmithGraph(embedding='xyzzy') # optional - networkx Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 @@ -1199,16 +1199,16 @@ def BlanusaFirstSnarkGraph(): EXAMPLES:: - sage: g = graphs.BlanusaFirstSnarkGraph() - sage: g.order() + sage: g = graphs.BlanusaFirstSnarkGraph() # optional - sage.groups + sage: g.order() # optional - sage.groups 18 - sage: g.size() + sage: g.size() # optional - sage.groups 27 - sage: g.diameter() + sage: g.diameter() # optional - sage.groups 4 - sage: g.girth() + sage: g.girth() # optional - sage.groups 5 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 8 """ g = Graph({17: [4, 7, 1], 0: [5], 3: [8], 13: [9], 12: [16], @@ -1234,16 +1234,16 @@ def BlanusaSecondSnarkGraph(): EXAMPLES:: - sage: g = graphs.BlanusaSecondSnarkGraph() - sage: g.order() + sage: g = graphs.BlanusaSecondSnarkGraph() # optional - sage.groups + sage: g.order() # optional - sage.groups 18 - sage: g.size() + sage: g.size() # optional - sage.groups 27 - sage: g.diameter() + sage: g.diameter() # optional - sage.groups 4 - sage: g.girth() + sage: g.girth() # optional - sage.groups 5 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 4 """ c0 = (-1, 0) @@ -1361,18 +1361,18 @@ def BrouwerHaemersGraph(): EXAMPLES:: - sage: g = graphs.BrouwerHaemersGraph() - sage: g + sage: g = graphs.BrouwerHaemersGraph() # optional - sage.modules + sage: g # optional - sage.modules Brouwer-Haemers: Graph on 81 vertices It is indeed strongly regular with parameters `(81,20,1,6)`:: - sage: g.is_strongly_regular(parameters=True) # long time + sage: g.is_strongly_regular(parameters=True) # long time # optional - sage.modules (81, 20, 1, 6) Its has as eigenvalues `20,2` and `-7`:: - sage: set(g.spectrum()) == {20,2,-7} + sage: set(g.spectrum()) == {20,2,-7} # optional - sage.modules True """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -1419,16 +1419,16 @@ def BuckyBall(): The Bucky Ball can also be created by extracting the 1-skeleton of the Bucky Ball polyhedron, but this is much slower:: - sage: g = polytopes.buckyball().vertex_graph() - sage: g.remove_loops() + sage: g = polytopes.buckyball().vertex_graph() # optional - sage.geometry.polyhedron + sage: g.remove_loops() # optional - sage.geometry.polyhedron sage: h = graphs.BuckyBall() - sage: g.is_isomorphic(h) + sage: g.is_isomorphic(h) # optional - sage.geometry.polyhedron True The graph is returned along with an attractive embedding:: sage: g = graphs.BuckyBall() # long time - sage: g.plot(vertex_labels=False, vertex_size=10).show() # long time + sage: g.plot(vertex_labels=False, vertex_size=10).show() # long time # optional - sage.plot """ edges = [(0, 2), (0, 48), (0, 59), (1, 3), (1, 9), (1, 58), (2, 3), (2, 36), (3, 17), (4, 6), (4, 8), (4, 12), @@ -1735,12 +1735,12 @@ def CameronGraph(): EXAMPLES:: - sage: g = graphs.CameronGraph() - sage: g.order() + sage: g = graphs.CameronGraph() # optional - sage.groups + sage: g.order() # optional - sage.groups 231 - sage: g.size() + sage: g.size() # optional - sage.groups 3465 - sage: g.is_strongly_regular(parameters = True) # long time + sage: g.is_strongly_regular(parameters=True) # long time # optional - sage.groups (231, 30, 9, 3) """ from sage.groups.perm_gps.permgroup_named import MathieuGroup @@ -1828,7 +1828,7 @@ def ClebschGraph(): EXAMPLES:: sage: g = graphs.ClebschGraph() - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 1920 sage: g.girth() 4 @@ -1836,7 +1836,7 @@ def ClebschGraph(): 4 sage: g.diameter() 2 - sage: g.show(figsize=[10, 10]) # long time + sage: g.show(figsize=[10, 10]) # long time # optional - sage.plot """ g = Graph(pos={}) x = 0 @@ -1865,7 +1865,7 @@ def CoxeterGraph(): EXAMPLES:: sage: g = graphs.CoxeterGraph() - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 336 sage: g.girth() 7 @@ -1873,7 +1873,7 @@ def CoxeterGraph(): 3 sage: g.diameter() 4 - sage: g.show(figsize=[10, 10]) # long time + sage: g.show(figsize=[10, 10]) # long time # optional - sage.plot """ g = Graph({ 27: [6, 22, 14], @@ -1931,10 +1931,10 @@ def DesarguesGraph(): EXAMPLES:: sage: D = graphs.DesarguesGraph() - sage: L = graphs.LCFGraph(20,[5,-5,9,-9],5) - sage: D.is_isomorphic(L) + sage: L = graphs.LCFGraph(20,[5,-5,9,-9],5) # optional - networkx + sage: D.is_isomorphic(L) # optional - networkx True - sage: D.show() # long time + sage: D.show() # long time # optional - sage.plot """ from sage.graphs.generators.families import GeneralizedPetersenGraph G = GeneralizedPetersenGraph(10, 3) @@ -2085,22 +2085,22 @@ def HortonGraph(): EXAMPLES:: - sage: g = graphs.HortonGraph() - sage: g.order() + sage: g = graphs.HortonGraph() # optional - networkx + sage: g.order() # optional - networkx 96 - sage: g.size() + sage: g.size() # optional - networkx 144 - sage: g.radius() + sage: g.radius() # optional - networkx 10 - sage: g.diameter() + sage: g.diameter() # optional - networkx 10 - sage: g.girth() + sage: g.girth() # optional - networkx 6 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - networkx 96 - sage: g.chromatic_number() + sage: g.chromatic_number() # optional - networkx 2 - sage: g.is_hamiltonian() # not tested -- veeeery long + sage: g.is_hamiltonian() # not tested -- veeeery long # optional - networkx False """ g = Graph(name="Horton Graph") @@ -2374,17 +2374,17 @@ def F26AGraph(): EXAMPLES:: - sage: g = graphs.F26AGraph(); g + sage: g = graphs.F26AGraph(); g # optional - networkx F26A Graph: Graph on 26 vertices - sage: g.order(),g.size() + sage: g.order(), g.size() # optional - networkx (26, 39) - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - networkx 78 - sage: g.girth() + sage: g.girth() # optional - networkx 6 - sage: g.is_bipartite() + sage: g.is_bipartite() # optional - networkx True - sage: g.characteristic_polynomial().factor() + sage: g.characteristic_polynomial().factor() # optional - networkx (x - 3) * (x + 3) * (x^4 - 5*x^2 + 3)^6 """ from sage.graphs.generators.families import LCFGraph @@ -2435,26 +2435,26 @@ def FolkmanGraph(): EXAMPLES:: - sage: g = graphs.FolkmanGraph() - sage: g.order() + sage: g = graphs.FolkmanGraph() # optional - networkx + sage: g.order() # optional - networkx 20 - sage: g.size() + sage: g.size() # optional - networkx 40 - sage: g.diameter() + sage: g.diameter() # optional - networkx 4 - sage: g.girth() + sage: g.girth() # optional - networkx 4 - sage: g.charpoly().factor() + sage: g.charpoly().factor() # optional - networkx (x - 4) * (x + 4) * x^10 * (x^2 - 6)^4 - sage: g.chromatic_number() + sage: g.chromatic_number() # optional - networkx 2 - sage: g.is_eulerian() + sage: g.is_eulerian() # optional - networkx True - sage: g.is_hamiltonian() + sage: g.is_hamiltonian() # optional - networkx True - sage: g.is_vertex_transitive() + sage: g.is_vertex_transitive() # optional - networkx False - sage: g.is_bipartite() + sage: g.is_bipartite() # optional - networkx True """ from sage.graphs.generators.families import LCFGraph @@ -2471,18 +2471,18 @@ def FosterGraph(): EXAMPLES:: - sage: g = graphs.FosterGraph() - sage: g.order() + sage: g = graphs.FosterGraph() # optional - networkx + sage: g.order() # optional - networkx 90 - sage: g.size() + sage: g.size() # optional - networkx 135 - sage: g.diameter() + sage: g.diameter() # optional - networkx 8 - sage: g.girth() + sage: g.girth() # optional - networkx 10 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - networkx 4320 - sage: g.is_hamiltonian() + sage: g.is_hamiltonian() # optional - networkx True """ from sage.graphs.generators.families import LCFGraph @@ -2565,18 +2565,18 @@ def FruchtGraph(): EXAMPLES:: - sage: FRUCHT = graphs.FruchtGraph() - sage: FRUCHT + sage: FRUCHT = graphs.FruchtGraph() # optional - networkx + sage: FRUCHT # optional - networkx Frucht graph: Graph on 12 vertices - sage: FRUCHT.graph6_string() + sage: FRUCHT.graph6_string() # optional - networkx 'KhCKM?_EGK?L' - sage: (graphs.FruchtGraph()).show() # long time + sage: (graphs.FruchtGraph()).show() # long time # optional - networkx TESTS:: - sage: import networkx - sage: G = graphs.FruchtGraph() - sage: G.is_isomorphic(Graph(networkx.frucht_graph())) + sage: import networkx # optional - networkx + sage: G = graphs.FruchtGraph() # optional - networkx + sage: G.is_isomorphic(Graph(networkx.frucht_graph())) # optional - networkx True """ edges = {0: [1, 6, 7], 1: [2, 7], 2: [3, 8], 3: [4, 9], 4: [5, 9], @@ -2888,8 +2888,8 @@ def HerschelGraph(): sage: G.chromatic_number() 2 - sage: ag = G.automorphism_group() - sage: ag.is_isomorphic(DihedralGroup(6)) + sage: ag = G.automorphism_group() # optional - sage.groups + sage: ag.is_isomorphic(DihedralGroup(6)) # optional - sage.groups True """ edge_dict = { @@ -2919,9 +2919,9 @@ def GritsenkoGraph(): EXAMPLES:: - sage: H = graphs.GritsenkoGraph(); H + sage: H = graphs.GritsenkoGraph(); H # optional - sage.groups Gritsenko strongly regular graph: Graph on 65 vertices - sage: H.is_strongly_regular(parameters=True) + sage: H.is_strongly_regular(parameters=True) # optional - sage.groups (65, 32, 15, 16) """ from sage.groups.perm_gps.permgroup import PermutationGroup @@ -3000,13 +3000,13 @@ def HigmanSimsGraph(relabel=True): which is of index 2 and is simple. It is known as the Higman-Sims group:: sage: H = graphs.HigmanSimsGraph() - sage: G = H.automorphism_group() - sage: g=G.order(); g + sage: G = H.automorphism_group() # optional - sage.groups + sage: g = G.order(); g # optional - sage.groups 88704000 - sage: K = G.normal_subgroups()[1] - sage: K.is_simple() + sage: K = G.normal_subgroups()[1] # optional - sage.groups + sage: K.is_simple() # optional - sage.groups True - sage: g//K.order() + sage: g//K.order() # optional - sage.groups 2 AUTHOR: @@ -3192,7 +3192,7 @@ def HoffmanGraph(): 3 sage: g.diameter() 4 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 48 """ g = Graph({ @@ -3231,7 +3231,7 @@ def HoltGraph(): Holt graph: Graph on 27 vertices sage: g.is_regular() True - sage: g.is_vertex_transitive() + sage: g.is_vertex_transitive() # optional - sage.groups True sage: g.chromatic_number() 3 @@ -3243,7 +3243,7 @@ def HoltGraph(): 3 sage: g.girth() 5 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 54 """ g = Graph(loops=False, name="Holt graph", pos={}) @@ -3324,7 +3324,7 @@ def Klein3RegularGraph(): (56, 84) sage: g.girth() 7 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 336 sage: g.chromatic_number() 3 @@ -3357,7 +3357,7 @@ def Klein7RegularGraph(): (24, 84) sage: g.girth() 3 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 336 sage: g.chromatic_number() 4 @@ -3413,21 +3413,21 @@ def LjubljanaGraph(embedding=1): EXAMPLES:: - sage: g = graphs.LjubljanaGraph() - sage: g.order() + sage: g = graphs.LjubljanaGraph() # optional - networkx + sage: g.order() # optional - networkx 112 - sage: g.size() + sage: g.size() # optional - networkx 168 - sage: g.girth() + sage: g.girth() # optional - networkx 10 - sage: g.diameter() + sage: g.diameter() # optional - networkx 8 - sage: g.show(figsize=[10, 10]) # long time - sage: graphs.LjubljanaGraph(embedding=2).show(figsize=[10, 10]) # long time + sage: g.show(figsize=[10, 10]) # long time # optional - networkx sage.plot + sage: graphs.LjubljanaGraph(embedding=2).show(figsize=[10, 10]) # long time # optional - networkx sage.plot TESTS:: - sage: graphs.LjubljanaGraph(embedding=3) + sage: graphs.LjubljanaGraph(embedding=3) # optional - networkx Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 @@ -3518,12 +3518,12 @@ def M22Graph(): EXAMPLES:: - sage: g = graphs.M22Graph() - sage: g.order() + sage: g = graphs.M22Graph() # optional - sage.groups + sage: g.order() # optional - sage.groups 77 - sage: g.size() + sage: g.size() # optional - sage.groups 616 - sage: g.is_strongly_regular(parameters = True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.groups (77, 16, 0, 4) """ from sage.groups.perm_gps.permgroup_named import MathieuGroup @@ -3561,11 +3561,11 @@ def MarkstroemGraph(): True sage: g.is_regular(3) True - sage: g.subgraph_search(graphs.CycleGraph(4)) is None + sage: g.subgraph_search(graphs.CycleGraph(4)) is None # optional - sage.modules True - sage: g.subgraph_search(graphs.CycleGraph(8)) is None + sage: g.subgraph_search(graphs.CycleGraph(8)) is None # optional - sage.modules True - sage: g.subgraph_search(graphs.CycleGraph(16)) + sage: g.subgraph_search(graphs.CycleGraph(16)) # optional - sage.modules Subgraph of (Markstroem Graph): Graph on 16 vertices """ g = Graph(name="Markstroem Graph") @@ -3602,21 +3602,21 @@ def McGeeGraph(embedding=2): EXAMPLES:: - sage: g = graphs.McGeeGraph() - sage: g.order() + sage: g = graphs.McGeeGraph() # optional - networkx + sage: g.order() # optional - networkx 24 - sage: g.size() + sage: g.size() # optional - networkx 36 - sage: g.girth() + sage: g.girth() # optional - networkx 7 - sage: g.diameter() + sage: g.diameter() # optional - networkx 4 - sage: g.show() # optional - sage.plot - sage: graphs.McGeeGraph(embedding=1).show() # long time # optional - sage.plot + sage: g.show() # optional - networkx sage.plot + sage: graphs.McGeeGraph(embedding=1).show() # long time # optional - networkx sage.plot TESTS:: - sage: graphs.McGeeGraph(embedding=3) + sage: graphs.McGeeGraph(embedding=3) # optional - networkx Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 @@ -3830,7 +3830,7 @@ def NauruGraph(embedding=2): Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 - sage: graphs.NauruGraph(embedding=1).is_isomorphic(g) + sage: graphs.NauruGraph(embedding=1).is_isomorphic(g) # optional - networkx True """ @@ -3858,9 +3858,9 @@ def PappusGraph(): sage: G = graphs.PappusGraph() sage: G.show() # long time # optional - sage.plot - sage: L = graphs.LCFGraph(18, [5,7,-7,7,-7,-5], 3) - sage: L.show() # long time # optional - sage.plot - sage: G.is_isomorphic(L) + sage: L = graphs.LCFGraph(18, [5,7,-7,7,-7,-5], 3) # optional - networkx + sage: L.show() # long time # optional - networkx sage.plot + sage: G.is_isomorphic(L) # optional - networkx True """ edges = {0: [1, 5, 6], 1: [2, 7], 2: [3, 8], 3: [4, 9], 4: [5, 10], 5: [11], @@ -3970,22 +3970,23 @@ def RobertsonGraph(): EXAMPLES:: - sage: g = graphs.RobertsonGraph() - sage: g.order() + sage: g = graphs.RobertsonGraph() # optional - networkx + sage: g.order() # optional - networkx 19 - sage: g.size() + sage: g.size() # optional - networkx 38 - sage: g.diameter() + sage: g.diameter() # optional - networkx 3 - sage: g.girth() + sage: g.girth() # optional - networkx 5 - sage: g.charpoly().factor() - (x - 4) * (x - 1)^2 * (x^2 + x - 5) * (x^2 + x - 1) * (x^2 - 3)^2 * (x^2 + x - 4)^2 * (x^2 + x - 3)^2 - sage: g.chromatic_number() + sage: g.charpoly().factor() # optional - networkx + (x - 4) * (x - 1)^2 * (x^2 + x - 5) * (x^2 + x - 1) + * (x^2 - 3)^2 * (x^2 + x - 4)^2 * (x^2 + x - 3)^2 + sage: g.chromatic_number() # optional - networkx 3 - sage: g.is_hamiltonian() + sage: g.is_hamiltonian() # optional - networkx True - sage: g.is_vertex_transitive() + sage: g.is_vertex_transitive() # optional - networkx False """ from sage.graphs.generators.families import LCFGraph @@ -4023,7 +4024,7 @@ def SchlaefliGraph(): The graph is vertex-transitive:: - sage: S.is_vertex_transitive() + sage: S.is_vertex_transitive() # optional - sage.groups True The neighborhood of each vertex is isomorphic to the complement of the @@ -4235,7 +4236,7 @@ def SousselierGraph(): 2 sage: g.diameter() 3 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 2 sage: g.is_hamiltonian() False @@ -4342,9 +4343,9 @@ def TietzeGraph(): 3 sage: g.girth() 3 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 12 - sage: g.automorphism_group().is_isomorphic(groups.permutation.Dihedral(6)) + sage: g.automorphism_group().is_isomorphic(groups.permutation.Dihedral(6)) # optional - sage.groups True """ g = Graph([(0, 9), (3, 10), (6, 11), (1, 5), (2, 7), (4, 8)], @@ -4396,7 +4397,7 @@ def TruncatedTetrahedralGraph(): Truncated Tetrahedron: Graph on 12 vertices sage: g.order(), g.size() (12, 18) - sage: g.is_isomorphic(polytopes.simplex(3).truncation().graph()) + sage: g.is_isomorphic(polytopes.simplex(3).truncation().graph()) # optional - sage.geometry.polyhedron True """ g = Graph(':K`ESwC_EOyDl\\MCi', loops=False, multiedges=False) @@ -4415,16 +4416,16 @@ def Tutte12Cage(): EXAMPLES:: - sage: g = graphs.Tutte12Cage() - sage: g.order() + sage: g = graphs.Tutte12Cage() # optional - networkx + sage: g.order() # optional - networkx 126 - sage: g.size() + sage: g.size() # optional - networkx 189 - sage: g.girth() + sage: g.girth() # optional - networkx 12 - sage: g.diameter() + sage: g.diameter() # optional - networkx 6 - sage: g.show() # optional - sage.plot + sage: g.show() # optional - networkx sage.plot """ L = [17, 27, -13, -59, -35, 35, -11, 13, -53, 53, -27, 21, 57, 11, -21, -57, 59, -17] @@ -4448,21 +4449,21 @@ def TutteCoxeterGraph(embedding=2): EXAMPLES:: - sage: g = graphs.TutteCoxeterGraph() - sage: g.order() + sage: g = graphs.TutteCoxeterGraph() # optional - networkx + sage: g.order() # optional - networkx 30 - sage: g.size() + sage: g.size() # optional - networkx 45 - sage: g.girth() + sage: g.girth() # optional - networkx 8 - sage: g.diameter() + sage: g.diameter() # optional - networkx 4 - sage: g.show() # optional - sage.plot - sage: graphs.TutteCoxeterGraph(embedding=1).show() # long time + sage: g.show() # optional - networkx sage.plot + sage: graphs.TutteCoxeterGraph(embedding=1).show() # long time # optional - networkx sage.plot TESTS:: - sage: graphs.TutteCoxeterGraph(embedding=3) + sage: graphs.TutteCoxeterGraph(embedding=3) # optional - networkx Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 @@ -4515,7 +4516,7 @@ def TutteGraph(): 3 sage: g.girth() 4 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 3 sage: g.is_hamiltonian() False @@ -4561,16 +4562,16 @@ def WagnerGraph(): EXAMPLES:: - sage: g = graphs.WagnerGraph() - sage: g.order() + sage: g = graphs.WagnerGraph() # optional - networkx + sage: g.order() # optional - networkx 8 - sage: g.size() + sage: g.size() # optional - networkx 12 - sage: g.girth() + sage: g.girth() # optional - networkx 4 - sage: g.diameter() + sage: g.diameter() # optional - networkx 2 - sage: g.show() # optional - sage.plot + sage: g.show() # optional - networkx sage.plot """ from sage.graphs.generators.families import LCFGraph g = LCFGraph(8, [4], 8) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index cd1be3f851a..1f8db82faed 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -440,15 +440,16 @@ from sage.misc.cachefunc import cached_method from sage.misc.prandom import random from sage.misc.superseded import deprecation -from sage.misc.lazy_import import LazyImport +from sage.misc.lazy_import import lazy_import, LazyImport from sage.rings.integer_ring import ZZ from sage.rings.integer import Integer from sage.rings.rational import Rational -from sage.matrix.constructor import matrix from sage.rings.rational_field import QQ from sage.features.igraph import python_igraph as igraph_feature +lazy_import('sage.matrix.constructor', 'matrix') + to_hex = LazyImport('matplotlib.colors', 'to_hex') @@ -908,7 +909,7 @@ def _latex_(self): sage: from sage.graphs.graph_latex import check_tkz_graph sage: check_tkz_graph() # random - depends on TeX installation sage: g = graphs.CompleteGraph(2) - sage: print(g._latex_()) + sage: print(g._latex_()) # optional - sage.plot \begin{tikzpicture} \definecolor{cv0}{rgb}{0.0,0.0,0.0} \definecolor{cfv0}{rgb}{1.0,1.0,1.0} @@ -945,21 +946,21 @@ def _matrix_(self, R=None, vertices=None): EXAMPLES:: sage: G = graphs.CompleteBipartiteGraph(2, 3) - sage: m = matrix(G); m.parent() + sage: m = matrix(G); m.parent() # optional - sage.modules Full MatrixSpace of 5 by 5 dense matrices over Integer Ring - sage: m + sage: m # optional - sage.modules [0 0 1 1 1] [0 0 1 1 1] [1 1 0 0 0] [1 1 0 0 0] [1 1 0 0 0] - sage: G._matrix_() + sage: G._matrix_() # optional - sage.modules [0 0 1 1 1] [0 0 1 1 1] [1 1 0 0 0] [1 1 0 0 0] [1 1 0 0 0] - sage: factor(m.charpoly()) + sage: factor(m.charpoly()) # optional - sage.modules x^3 * (x^2 - 6) """ return self.am(vertices=vertices, base_ring=R) @@ -1368,24 +1369,24 @@ def export_to_file(self, filename, format=None, **kwds): sage: g = graphs.PetersenGraph() sage: filename = tmp_filename(ext=".pajek") - sage: g.export_to_file(filename) + sage: g.export_to_file(filename) # optional - networkx sage: import networkx # optional - networkx sage: G_networkx = networkx.read_pajek(filename) # optional - networkx sage: Graph(G_networkx).is_isomorphic(g) # optional - networkx True sage: filename = tmp_filename(ext=".edgelist") - sage: g.export_to_file(filename, data=False) + sage: g.export_to_file(filename, data=False) # optional - networkx sage: h = Graph(networkx.read_edgelist(filename)) # optional - networkx sage: g.is_isomorphic(h) # optional - networkx True TESTS:: - sage: g.export_to_file("hey", format="When I feel heavy metaaaaaallll...") + sage: g.export_to_file("hey", format="When I feel heavy metaaaaaallll...") # optional - networkx Traceback (most recent call last): ... ValueError: format 'When I feel heavy metaaaaaallll...' unknown - sage: g.export_to_file("my_file.Yeeeeppeeeeee") + sage: g.export_to_file("my_file.Yeeeeppeeeeee") # optional - networkx Traceback (most recent call last): ... RuntimeError: the file format could not be guessed from 'my_file.Yeeeeppeeeeee' @@ -1507,20 +1508,24 @@ def networkx_graph(self, weight_function=None): EXAMPLES:: sage: G = graphs.TetrahedralGraph() - sage: N = G.networkx_graph() - sage: type(N) + sage: N = G.networkx_graph() # optional - networkx + sage: type(N) # optional - networkx sage: def weight_fn(e): ....: return e[2] sage: G1 = Graph([(1,2,1), (1,3,4), (2,3,3), (3,4,4)]) - sage: H = G1.networkx_graph(weight_function=weight_fn) - sage: H.edges(data=True) - EdgeDataView([(1, 2, {'weight': 1}), (1, 3, {'weight': 4}), (2, 3, {'weight': 3}), (3, 4, {'weight': 4})]) - sage: G2 = DiGraph([(1,2,1), (1,3,4), (2,3,3), (3,4,4), (3,4,5)], multiedges=True) - sage: H = G2.networkx_graph(weight_function=weight_fn) - sage: H.edges(data=True) - OutMultiEdgeDataView([(1, 2, {'weight': 1}), (1, 3, {'weight': 4}), (2, 3, {'weight': 3}), (3, 4, {'weight': 5}), (3, 4, {'weight': 4})]) + sage: H = G1.networkx_graph(weight_function=weight_fn) # optional - networkx + sage: H.edges(data=True) # optional - networkx + EdgeDataView([(1, 2, {'weight': 1}), (1, 3, {'weight': 4}), + (2, 3, {'weight': 3}), (3, 4, {'weight': 4})]) + sage: G2 = DiGraph([(1,2,1), (1,3,4), (2,3,3), (3,4,4), (3,4,5)], + ....: multiedges=True) + sage: H = G2.networkx_graph(weight_function=weight_fn) # optional - networkx + sage: H.edges(data=True) # optional - networkx + OutMultiEdgeDataView([(1, 2, {'weight': 1}), (1, 3, {'weight': 4}), + (2, 3, {'weight': 3}), (3, 4, {'weight': 5}), + (3, 4, {'weight': 4})]) """ if weight_function is not None: @@ -1907,7 +1912,7 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds EXAMPLES:: sage: G = graphs.CubeGraph(4) - sage: G.adjacency_matrix() + sage: G.adjacency_matrix() # optional - sage.modules [0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0] [1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0] [1 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0] @@ -1927,7 +1932,7 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds :: - sage: matrix(GF(2),G) # matrix over GF(2) + sage: matrix(GF(2), G) # matrix over GF(2) # optional - sage.modules sage.rings.finite_rings [0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0] [1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0] [1 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0] @@ -1947,8 +1952,9 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds :: - sage: D = DiGraph({0: [1, 2, 3], 1: [0, 2], 2: [3], 3: [4], 4: [0, 5], 5: [1]}) - sage: D.adjacency_matrix() + sage: D = DiGraph({0: [1, 2, 3], 1: [0, 2], 2: [3], + ....: 3: [4], 4: [0, 5], 5: [1]}) + sage: D.adjacency_matrix() # optional - sage.modules [0 1 1 1 0 0] [1 0 1 0 0 0] [0 0 0 1 0 0] @@ -1958,7 +1964,7 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds A different ordering of the vertices:: - sage: graphs.PathGraph(5).adjacency_matrix(vertices=[2, 4, 1, 3, 0]) + sage: graphs.PathGraph(5).adjacency_matrix(vertices=[2, 4, 1, 3, 0]) # optional - sage.modules [0 0 1 1 0] [0 0 0 1 0] [1 0 0 0 1] @@ -1967,18 +1973,19 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds A different base ring:: - sage: graphs.PathGraph(5).adjacency_matrix(base_ring=RDF) + sage: graphs.PathGraph(5).adjacency_matrix(base_ring=RDF) # optional - sage.modules [0.0 1.0 0.0 0.0 0.0] [1.0 0.0 1.0 0.0 0.0] [0.0 1.0 0.0 1.0 0.0] [0.0 0.0 1.0 0.0 1.0] [0.0 0.0 0.0 1.0 0.0] - sage: type(_) + sage: type(_) # optional - sage.modules A different matrix implementation:: - sage: graphs.PathGraph(5).adjacency_matrix(sparse=False, implementation='numpy') + sage: graphs.PathGraph(5).adjacency_matrix(sparse=False, # optional - sage.modules + ....: implementation='numpy') [0 1 0 0 0] [1 0 1 0 0] [0 1 0 1 0] @@ -1989,7 +1996,8 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds As an immutable matrix:: - sage: M = graphs.PathGraph(5).adjacency_matrix(sparse=False, immutable=True); M + sage: M = graphs.PathGraph(5).adjacency_matrix(sparse=False, # optional - sage.modules + ....: immutable=True); M [0 1 0 0 0] [1 0 1 0 0] [0 1 0 1 0] @@ -1998,21 +2006,23 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds sage: M[2, 2] = 1 Traceback (most recent call last): ... - ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M). + ValueError: matrix is immutable; please change a copy instead + (i.e., use copy(M) to change a copy of M). TESTS:: - sage: graphs.CubeGraph(8).adjacency_matrix().parent() + sage: graphs.CubeGraph(8).adjacency_matrix().parent() # optional - sage.modules Full MatrixSpace of 256 by 256 dense matrices over Integer Ring - sage: graphs.CubeGraph(9).adjacency_matrix().parent() + sage: graphs.CubeGraph(9).adjacency_matrix().parent() # optional - sage.modules Full MatrixSpace of 512 by 512 sparse matrices over Integer Ring - sage: Graph([(i,i+1) for i in range(500)]+[(0,1),], multiedges=True).adjacency_matrix().parent() + sage: Graph([(i, i+1) for i in range(500)] + [(0,1),], # optional - sage.modules + ....: multiedges=True).adjacency_matrix().parent() Full MatrixSpace of 501 by 501 dense matrices over Integer Ring - sage: graphs.PathGraph(5).adjacency_matrix(vertices=[0,0,0,0,0]) + sage: graphs.PathGraph(5).adjacency_matrix(vertices=[0,0,0,0,0]) # optional - sage.modules Traceback (most recent call last): ... ValueError: ``vertices`` must be a permutation of the vertices - sage: graphs.PathGraph(5).adjacency_matrix(vertices=[1,2,3]) + sage: graphs.PathGraph(5).adjacency_matrix(vertices=[1,2,3]) # optional - sage.modules Traceback (most recent call last): ... ValueError: ``vertices`` must be a permutation of the vertices @@ -2119,7 +2129,7 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None EXAMPLES:: sage: G = graphs.PetersenGraph() - sage: G.incidence_matrix() + sage: G.incidence_matrix() # optional - sage.modules [1 1 1 0 0 0 0 0 0 0 0 0 0 0 0] [1 0 0 1 1 0 0 0 0 0 0 0 0 0 0] [0 0 0 1 0 1 1 0 0 0 0 0 0 0 0] @@ -2130,7 +2140,7 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None [0 0 0 0 0 0 1 0 0 0 1 0 0 0 1] [0 0 0 0 0 0 0 0 1 0 0 1 1 0 0] [0 0 0 0 0 0 0 0 0 1 0 0 0 1 1] - sage: G.incidence_matrix(oriented=True) + sage: G.incidence_matrix(oriented=True) # optional - sage.modules [-1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0] [ 1 0 0 -1 -1 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 1 0 -1 -1 0 0 0 0 0 0 0 0] @@ -2143,18 +2153,18 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None [ 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1] sage: G = digraphs.Circulant(4, [1, 3]) - sage: G.incidence_matrix() + sage: G.incidence_matrix() # optional - sage.modules [-1 -1 1 0 0 0 1 0] [ 1 0 -1 -1 1 0 0 0] [ 0 0 0 1 -1 -1 0 1] [ 0 1 0 0 0 1 -1 -1] - sage: graphs.CompleteGraph(3).incidence_matrix() + sage: graphs.CompleteGraph(3).incidence_matrix() # optional - sage.modules [1 1 0] [1 0 1] [0 1 1] sage: G = Graph([(0, 0), (0, 1), (0, 1)], loops=True, multiedges=True) - sage: G.incidence_matrix(oriented=False) + sage: G.incidence_matrix(oriented=False) # optional - sage.modules [2 1 1] [0 1 1] @@ -2163,30 +2173,30 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None Kirchhoff matrix:: sage: G = graphs.PetersenGraph() - sage: m = G.incidence_matrix(oriented=True) - sage: m * m.transpose() == G.kirchhoff_matrix() + sage: m = G.incidence_matrix(oriented=True) # optional - sage.modules + sage: m * m.transpose() == G.kirchhoff_matrix() # optional - sage.modules True sage: K = graphs.CompleteGraph(3) - sage: m = K.incidence_matrix(oriented=True) - sage: m * m.transpose() == K.kirchhoff_matrix() + sage: m = K.incidence_matrix(oriented=True) # optional - sage.modules + sage: m * m.transpose() == K.kirchhoff_matrix() # optional - sage.modules True sage: H = Graph([(0, 0), (0, 1), (0, 1)], loops=True, multiedges=True) - sage: m = H.incidence_matrix(oriented=True) - sage: m * m.transpose() == H.kirchhoff_matrix() + sage: m = H.incidence_matrix(oriented=True) # optional - sage.modules + sage: m * m.transpose() == H.kirchhoff_matrix() # optional - sage.modules True A different ordering of the vertices:: sage: P5 = graphs.PathGraph(5) - sage: P5.incidence_matrix() + sage: P5.incidence_matrix() # optional - sage.modules [1 0 0 0] [1 1 0 0] [0 1 1 0] [0 0 1 1] [0 0 0 1] - sage: P5.incidence_matrix(vertices=[2, 4, 1, 3, 0]) + sage: P5.incidence_matrix(vertices=[2, 4, 1, 3, 0]) # optional - sage.modules [0 1 1 0] [0 0 0 1] [1 1 0 0] @@ -2196,13 +2206,13 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None A different ordering of the edges:: sage: E = list(P5.edge_iterator(labels=False)) - sage: P5.incidence_matrix(edges=E[::-1]) + sage: P5.incidence_matrix(edges=E[::-1]) # optional - sage.modules [0 0 0 1] [0 0 1 1] [0 1 1 0] [1 1 0 0] [1 0 0 0] - sage: P5.incidence_matrix(vertices=[2, 4, 1, 3, 0], edges=E[::-1]) + sage: P5.incidence_matrix(vertices=[2, 4, 1, 3, 0], edges=E[::-1]) # optional - sage.modules [0 1 1 0] [1 0 0 0] [0 0 1 1] @@ -2211,7 +2221,7 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None A different base ring:: - sage: P5.incidence_matrix(base_ring=RDF) + sage: P5.incidence_matrix(base_ring=RDF) # optional - sage.modules [1.0 0.0 0.0 0.0] [1.0 1.0 0.0 0.0] [0.0 1.0 1.0 0.0] @@ -2220,29 +2230,30 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None Creating an immutable matrix:: - sage: m = P5.incidence_matrix(immutable=True); m + sage: m = P5.incidence_matrix(immutable=True); m # optional - sage.modules [1 0 0 0] [1 1 0 0] [0 1 1 0] [0 0 1 1] [0 0 0 1] - sage: m[1,2] = 1 + sage: m[1,2] = 1 # optional - sage.modules Traceback (most recent call last): ... - ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M). + ValueError: matrix is immutable; please change a copy instead + (i.e., use copy(M) to change a copy of M). TESTS:: sage: P5 = graphs.PathGraph(5) - sage: P5.incidence_matrix(vertices=[1] * P5.order()) + sage: P5.incidence_matrix(vertices=[1] * P5.order()) # optional - sage.modules Traceback (most recent call last): ... ValueError: ``vertices`` must be a permutation of the vertices - sage: P5.incidence_matrix(edges=[(0, 1)] * P5.size()) + sage: P5.incidence_matrix(edges=[(0, 1)] * P5.size()) # optional - sage.modules Traceback (most recent call last): ... ValueError: ``edges`` must be a permutation of the edges - sage: P5.incidence_matrix(edges=P5.edges(sort=False, labels=True)) + sage: P5.incidence_matrix(edges=P5.edges(sort=False, labels=True)) # optional - sage.modules [1 0 0 0] [1 1 0 0] [0 1 1 0] @@ -2331,19 +2342,19 @@ def distance_matrix(self, vertices=None, *, base_ring=None, **kwds): EXAMPLES:: sage: d = DiGraph({1: [2, 3], 2: [3], 3: [4], 4: [1]}) - sage: d.distance_matrix() + sage: d.distance_matrix() # optional - sage.modules [0 1 1 2] [3 0 1 2] [2 3 0 1] [1 2 2 0] - sage: d.distance_matrix(vertices=[4, 3, 2, 1]) + sage: d.distance_matrix(vertices=[4, 3, 2, 1]) # optional - sage.modules [0 2 2 1] [1 0 3 2] [2 1 0 3] [2 1 1 0] sage: G = graphs.CubeGraph(3) - sage: G.distance_matrix() + sage: G.distance_matrix() # optional - sage.modules [0 1 1 2 1 2 2 3] [1 0 2 1 2 1 3 2] [1 2 0 1 2 3 1 2] @@ -2357,7 +2368,8 @@ def distance_matrix(self, vertices=None, *, base_ring=None, **kwds): of the distance matrix of any tree of order `n` is `(-1)^{n-1}(n-1)2^{n-2}`:: - sage: all(T.distance_matrix().det() == (-1)^9*(9)*2^8 for T in graphs.trees(10)) + sage: all(T.distance_matrix().det() == (-1)^9*(9)*2^8 # optional - sage.modules + ....: for T in graphs.trees(10)) True .. SEEALSO:: @@ -2370,18 +2382,18 @@ def distance_matrix(self, vertices=None, *, base_ring=None, **kwds): Asking for an immutable matrix:: sage: G = Graph([(0, 1)]) - sage: G.distance_matrix().is_immutable() + sage: G.distance_matrix().is_immutable() # optional - sage.modules False - sage: G.distance_matrix(immutable=True).is_immutable() + sage: G.distance_matrix(immutable=True).is_immutable() # optional - sage.modules True Specifying a base ring:: sage: G = Graph([(0, 1)]) - sage: G.distance_matrix(vertices=[0, 1], base_ring=ZZ) + sage: G.distance_matrix(vertices=[0, 1], base_ring=ZZ) # optional - sage.modules [0 1] [1 0] - sage: G.distance_matrix(vertices=[0, 1], base_ring=RDF) + sage: G.distance_matrix(vertices=[0, 1], base_ring=RDF) # optional - sage.modules [0.0 1.0] [1.0 0.0] @@ -2389,7 +2401,7 @@ def distance_matrix(self, vertices=None, *, base_ring=None, **kwds): constructor:: sage: G = Graph([(0, 1)]) - sage: G.distance_matrix(vertices=[0, 1], weight_function=lambda e:2) + sage: G.distance_matrix(vertices=[0, 1], weight_function=lambda e:2) # optional - sage.modules [0 2] [2 0] """ @@ -2467,15 +2479,15 @@ def weighted_adjacency_matrix(self, sparse=True, vertices=None, sage: G = Graph(sparse=True, weighted=True) sage: G.add_edges([(0, 1, 1), (1, 2, 2), (0, 2, 3), (0, 3, 4)]) - sage: M = G.weighted_adjacency_matrix(); M + sage: M = G.weighted_adjacency_matrix(); M # optional - sage.modules [0 1 3 4] [1 0 2 0] [3 2 0 0] [4 0 0 0] - sage: H = Graph(data=M, format='weighted_adjacency_matrix', sparse=True) - sage: H == G + sage: H = Graph(data=M, format='weighted_adjacency_matrix', sparse=True) # optional - sage.modules + sage: H == G # optional - sage.modules True - sage: G.weighted_adjacency_matrix(vertices=[3, 2, 1, 0]) + sage: G.weighted_adjacency_matrix(vertices=[3, 2, 1, 0]) # optional - sage.modules [0 0 0 4] [0 0 2 3] [0 2 0 1] @@ -2483,7 +2495,8 @@ def weighted_adjacency_matrix(self, sparse=True, vertices=None, Using a different matrix implementation:: - sage: M = G.weighted_adjacency_matrix(sparse=False, base_ring=ZZ, implementation='numpy'); M + sage: M = G.weighted_adjacency_matrix(sparse=False, base_ring=ZZ, # optional - numpy sage.modules + ....: implementation='numpy'); M [0 1 3 4] [1 0 2 0] [3 2 0 0] @@ -2491,22 +2504,23 @@ def weighted_adjacency_matrix(self, sparse=True, vertices=None, As an immutable matrix:: - sage: M = G.weighted_adjacency_matrix(immutable=True); M + sage: M = G.weighted_adjacency_matrix(immutable=True); M # optional - sage.modules [0 1 3 4] [1 0 2 0] [3 2 0 0] [4 0 0 0] - sage: M[2, 2] = 1 + sage: M[2, 2] = 1 # optional - sage.modules Traceback (most recent call last): ... - ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M). + ValueError: matrix is immutable; please change a copy instead + (i.e., use copy(M) to change a copy of M). TESTS: The following doctest verifies that :trac:`4888` is fixed:: sage: G = DiGraph({0:{}, 1:{0:1}, 2:{0:1}}, weighted=True, sparse=True) - sage: G.weighted_adjacency_matrix() + sage: G.weighted_adjacency_matrix() # optional - sage.modules [0 0 0] [1 0 0] [1 0 0] @@ -2514,15 +2528,16 @@ def weighted_adjacency_matrix(self, sparse=True, vertices=None, Check error message for non numerical edge weights (:trac:`33562`):: sage: G = Graph([(0, 1)]) - sage: G.weighted_adjacency_matrix() + sage: G.weighted_adjacency_matrix() # optional - sage.modules Traceback (most recent call last): ... - ValueError: cannot find the weight of (0, 1, None). Consider setting parameter 'default_weight' - sage: G.weighted_adjacency_matrix(default_weight=3) + ValueError: cannot find the weight of (0, 1, None). + Consider setting parameter 'default_weight' + sage: G.weighted_adjacency_matrix(default_weight=3) # optional - sage.modules [0 3] [3 0] sage: G = Graph([(0, 1, 'a')]) - sage: G.weighted_adjacency_matrix() + sage: G.weighted_adjacency_matrix() # optional - sage.modules Traceback (most recent call last): ... TypeError: Cannot convert NoneType to sage.structure.parent.Parent @@ -2641,33 +2656,33 @@ def kirchhoff_matrix(self, weighted=None, indegree=True, normalized=False, signl sage: G = Graph(sparse=True) sage: G.add_edges([(0, 1, 1), (1, 2, 2), (0, 2, 3), (0, 3, 4)]) - sage: M = G.kirchhoff_matrix(weighted=True); M + sage: M = G.kirchhoff_matrix(weighted=True); M # optional - sage.modules [ 8 -1 -3 -4] [-1 3 -2 0] [-3 -2 5 0] [-4 0 0 4] - sage: M = G.kirchhoff_matrix(); M + sage: M = G.kirchhoff_matrix(); M # optional - sage.modules [ 3 -1 -1 -1] [-1 2 -1 0] [-1 -1 2 0] [-1 0 0 1] - sage: M = G.laplacian_matrix(normalized=True); M # optional - sage.symbolic + sage: M = G.laplacian_matrix(normalized=True); M # optional - sage.modules sage.symbolic [ 1 -1/6*sqrt(3)*sqrt(2) -1/6*sqrt(3)*sqrt(2) -1/3*sqrt(3)] [-1/6*sqrt(3)*sqrt(2) 1 -1/2 0] [-1/6*sqrt(3)*sqrt(2) -1/2 1 0] [ -1/3*sqrt(3) 0 0 1] - sage: M = G.kirchhoff_matrix(weighted=True, signless=True); M + sage: M = G.kirchhoff_matrix(weighted=True, signless=True); M # optional - sage.modules [8 1 3 4] [1 3 2 0] [3 2 5 0] [4 0 0 4] sage: G = Graph({0: [], 1: [2]}) - sage: G.laplacian_matrix(normalized=True) + sage: G.laplacian_matrix(normalized=True) # optional - sage.modules [ 0 0 0] [ 0 1 -1] [ 0 -1 1] - sage: G.laplacian_matrix(normalized=True,signless=True) + sage: G.laplacian_matrix(normalized=True, signless=True) # optional - sage.modules [0 0 0] [0 1 1] [0 1 1] @@ -2675,14 +2690,14 @@ def kirchhoff_matrix(self, weighted=None, indegree=True, normalized=False, signl A weighted directed graph with loops, changing the variable ``indegree`` :: sage: G = DiGraph({1: {1: 2, 2: 3}, 2: {1: 4}}, weighted=True, sparse=True) - sage: G.laplacian_matrix() + sage: G.laplacian_matrix() # optional - sage.modules [ 4 -3] [-4 3] :: sage: G = DiGraph({1: {1: 2, 2: 3}, 2: {1: 4}}, weighted=True, sparse=True) - sage: G.laplacian_matrix(indegree=False) + sage: G.laplacian_matrix(indegree=False) # optional - sage.modules [ 3 -3] [-4 4] @@ -2691,12 +2706,12 @@ def kirchhoff_matrix(self, weighted=None, indegree=True, normalized=False, signl sage: G = Graph(sparse=True) sage: G.add_edges([(0, 1, 1), (1, 2, 2), (0, 2, 3), (0, 3, 4)]) - sage: M = G.kirchhoff_matrix(vertices=[3, 2, 1, 0]); M + sage: M = G.kirchhoff_matrix(vertices=[3, 2, 1, 0]); M # optional - sage.modules [ 1 0 0 -1] [ 0 2 -1 -1] [ 0 -1 2 -1] [-1 -1 -1 3] - sage: M = G.kirchhoff_matrix(weighted=True, vertices=[3, 2, 1, 0]); M + sage: M = G.kirchhoff_matrix(weighted=True, vertices=[3, 2, 1, 0]); M # optional - sage.modules [ 4 0 0 -4] [ 0 5 -2 -3] [ 0 -2 3 -1] @@ -2706,8 +2721,8 @@ def kirchhoff_matrix(self, weighted=None, indegree=True, normalized=False, signl immutable:: sage: G = Graph([(0, 1)]) - sage: M = G.kirchhoff_matrix(vertices=[0, 1], immutable=True) - sage: M.is_immutable() + sage: M = G.kirchhoff_matrix(vertices=[0, 1], immutable=True) # optional - sage.modules + sage: M.is_immutable() # optional - sage.modules True """ from sage.matrix.constructor import diagonal_matrix @@ -3959,21 +3974,21 @@ def antisymmetric(self): A directed acyclic graph is antisymmetric:: - sage: G = digraphs.RandomDirectedGNR(20, 0.5) - sage: G.antisymmetric() + sage: G = digraphs.RandomDirectedGNR(20, 0.5) # optional - networkx + sage: G.antisymmetric() # optional - networkx True Loops are allowed:: - sage: G.allow_loops(True) - sage: G.add_edge(0, 0) - sage: G.antisymmetric() + sage: G.allow_loops(True) # optional - networkx + sage: G.add_edge(0, 0) # optional - networkx + sage: G.antisymmetric() # optional - networkx True An undirected graph is never antisymmetric unless it is just a union of isolated vertices (with possible loops):: - sage: graphs.RandomGNP(20, 0.5).antisymmetric() + sage: graphs.RandomGNP(20, 0.5).antisymmetric() # optional - networkx False sage: Graph(3).antisymmetric() True @@ -4055,7 +4070,7 @@ def is_bipartite(self, certificate=False): True sage: graphs.CycleGraph(5).is_bipartite() False - sage: graphs.RandomBipartite(10, 10, 0.7).is_bipartite() + sage: graphs.RandomBipartite(10, 10, 0.7).is_bipartite() # optional - numpy True A random graph is very rarely bipartite:: @@ -4659,37 +4674,45 @@ def min_spanning_tree(self, sage: weight = lambda e: 1 / ((e[0] + 1) * (e[1] + 1)) sage: sorted(g.min_spanning_tree(weight_function=weight)) [(0, 4, None), (1, 4, None), (2, 4, None), (3, 4, None)] - sage: sorted(g.min_spanning_tree(weight_function=weight, algorithm='Kruskal_Boost')) + sage: sorted(g.min_spanning_tree(weight_function=weight, + ....: algorithm='Kruskal_Boost')) [(0, 4, None), (1, 4, None), (2, 4, None), (3, 4, None)] sage: g = graphs.PetersenGraph() sage: g.allow_multiple_edges(True) sage: g.add_edges(g.edge_iterator()) sage: sorted(g.min_spanning_tree()) - [(0, 1, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 6, None), (3, 8, None), (5, 7, None), (5, 8, None), (6, 9, None)] + [(0, 1, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 6, None), + (3, 8, None), (5, 7, None), (5, 8, None), (6, 9, None)] Boruvka's algorithm:: sage: sorted(g.min_spanning_tree(algorithm='Boruvka')) - [(0, 1, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 6, None), (2, 3, None), (2, 7, None), (3, 8, None), (4, 9, None)] + [(0, 1, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 6, None), + (2, 3, None), (2, 7, None), (3, 8, None), (4, 9, None)] Prim's algorithm:: sage: g = graphs.CompleteGraph(5) - sage: sorted(g.min_spanning_tree(algorithm='Prim_edge', starting_vertex=2, weight_function=weight)) + sage: sorted(g.min_spanning_tree(algorithm='Prim_edge', + ....: starting_vertex=2, weight_function=weight)) [(0, 4, None), (1, 4, None), (2, 4, None), (3, 4, None)] - sage: sorted(g.min_spanning_tree(algorithm='Prim_fringe', starting_vertex=2, weight_function=weight)) + sage: sorted(g.min_spanning_tree(algorithm='Prim_fringe', + ....: starting_vertex=2, weight_function=weight)) [(0, 4, None), (1, 4, None), (2, 4, None), (3, 4, None)] - sage: sorted(g.min_spanning_tree(weight_function=weight, algorithm='Prim_Boost')) + sage: sorted(g.min_spanning_tree(weight_function=weight, + ....: algorithm='Prim_Boost')) [(0, 4, None), (1, 4, None), (2, 4, None), (3, 4, None)] NetworkX algorithm:: - sage: sorted(g.min_spanning_tree(algorithm='NetworkX')) + sage: sorted(g.min_spanning_tree(algorithm='NetworkX')) # optional - networkx [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None)] More complicated weights:: - sage: G = Graph([(0,1,{'name':'a','weight':1}), (0,2,{'name':'b','weight':3}), (1,2,{'name':'b','weight':1})]) + sage: G = Graph([(0, 1, {'name': 'a', 'weight': 1}), + ....: (0, 2, {'name': 'b', 'weight': 3}), + ....: (1, 2, {'name': 'b', 'weight': 1})]) sage: sorted(G.min_spanning_tree(weight_function=lambda e: e[2]['weight'])) [(0, 1, {'name': 'a', 'weight': 1}), (1, 2, {'name': 'b', 'weight': 1})] @@ -4733,7 +4756,7 @@ def min_spanning_tree(self, [(0, 1, 1), (1, 2, 1)] sage: sorted(g.min_spanning_tree(algorithm='Prim_Boost')) [(0, 1, 1), (1, 2, 1)] - sage: sorted(g.min_spanning_tree(algorithm='NetworkX')) + sage: sorted(g.min_spanning_tree(algorithm='NetworkX')) # optional - networkx [(0, 1, 1), (1, 2, 1)] sage: sorted(g.min_spanning_tree(algorithm='Boruvka')) [(0, 1, 1), (1, 2, 1)] @@ -4755,7 +4778,7 @@ def min_spanning_tree(self, [(0, 2, 10), (1, 2, 1)] sage: sorted(g.min_spanning_tree(algorithm='Prim_Boost', weight_function=weight)) [(0, 2, 10), (1, 2, 1)] - sage: sorted(g.min_spanning_tree(algorithm='NetworkX', weight_function=weight)) + sage: sorted(g.min_spanning_tree(algorithm='NetworkX', weight_function=weight)) # optional - networkx [(0, 2, 10), (1, 2, 1)] sage: sorted(g.min_spanning_tree(algorithm='Boruvka', weight_function=weight)) [(0, 2, 10), (1, 2, 1)] @@ -4954,13 +4977,13 @@ def spanning_trees_count(self, root_vertex=None): :: - sage: M = matrix(3, 3, [0, 1, 0, 0, 0, 1, 1, 1, 0]) - sage: D = DiGraph(M) - sage: D.spanning_trees_count() + sage: M = matrix(3, 3, [0, 1, 0, 0, 0, 1, 1, 1, 0]) # optional - sage.modules + sage: D = DiGraph(M) # optional - sage.modules + sage: D.spanning_trees_count() # optional - sage.modules 1 - sage: D.spanning_trees_count(0) + sage: D.spanning_trees_count(0) # optional - sage.modules 1 - sage: D.spanning_trees_count(2) + sage: D.spanning_trees_count(2) # optional - sage.modules 2 """ if not self.order(): @@ -5018,33 +5041,35 @@ def cycle_basis(self, output='vertex'): A cycle basis in Petersen's Graph :: sage: g = graphs.PetersenGraph() - sage: g.cycle_basis() - [[1, 6, 8, 5, 0], [4, 9, 6, 8, 5, 0], [7, 9, 6, 8, 5], [4, 3, 8, 5, 0], [1, 2, 3, 8, 5, 0], [7, 2, 3, 8, 5]] + sage: g.cycle_basis() # optional - networkx + [[1, 6, 8, 5, 0], [4, 9, 6, 8, 5, 0], [7, 9, 6, 8, 5], + [4, 3, 8, 5, 0], [1, 2, 3, 8, 5, 0], [7, 2, 3, 8, 5]] One can also get the result as a list of lists of edges:: - sage: g.cycle_basis(output='edge') + sage: g.cycle_basis(output='edge') # optional - networkx [[(1, 6, None), (6, 8, None), (8, 5, None), (5, 0, None), - (0, 1, None)], [(4, 9, None), (9, 6, None), (6, 8, None), - (8, 5, None), (5, 0, None), (0, 4, None)], [(7, 9, None), - (9, 6, None), (6, 8, None), (8, 5, None), (5, 7, None)], - [(4, 3, None), (3, 8, None), (8, 5, None), (5, 0, None), - (0, 4, None)], [(1, 2, None), (2, 3, None), (3, 8, None), - (8, 5, None), (5, 0, None), (0, 1, None)], [(7, 2, None), - (2, 3, None), (3, 8, None), (8, 5, None), (5, 7, None)]] + (0, 1, None)], [(4, 9, None), (9, 6, None), (6, 8, None), + (8, 5, None), (5, 0, None), (0, 4, None)], [(7, 9, None), + (9, 6, None), (6, 8, None), (8, 5, None), (5, 7, None)], + [(4, 3, None), (3, 8, None), (8, 5, None), (5, 0, None), + (0, 4, None)], [(1, 2, None), (2, 3, None), (3, 8, None), + (8, 5, None), (5, 0, None), (0, 1, None)], [(7, 2, None), + (2, 3, None), (3, 8, None), (8, 5, None), (5, 7, None)]] Checking the given cycles are algebraically free:: - sage: g = graphs.RandomGNP(30, .4) - sage: basis = g.cycle_basis() + sage: g = graphs.RandomGNP(30, .4) # optional - networkx + sage: basis = g.cycle_basis() # optional - networkx Building the space of (directed) edges over `Z/2Z`. On the way, building a dictionary associating a unique vector to each undirected edge:: sage: m = g.size() - sage: edge_space = VectorSpace(FiniteField(2), m) - sage: edge_vector = dict(zip(g.edges(labels=False, sort=False), edge_space.basis())) - sage: for (u, v), vec in list(edge_vector.items()): + sage: edge_space = VectorSpace(FiniteField(2), m) # optional - sage.modules sage.rings.finite_rings + sage: edge_vector = dict(zip(g.edges(labels=False, sort=False), # optional - sage.modules sage.rings.finite_rings + ....: edge_space.basis())) + sage: for (u, v), vec in list(edge_vector.items()): # optional - sage.modules sage.rings.finite_rings ....: edge_vector[(v, u)] = vec Defining a lambda function associating a vector to the vertices of a @@ -5055,27 +5080,29 @@ def cycle_basis(self, output='vertex'): Finally checking the cycles are a free set:: - sage: basis_as_vectors = [cycle_to_vector(_) for _ in basis] - sage: edge_space.span(basis_as_vectors).rank() == len(basis) + sage: basis_as_vectors = [cycle_to_vector(_) for _ in basis] # optional - sage.modules sage.rings.finite_rings + sage: edge_space.span(basis_as_vectors).rank() == len(basis) # optional - sage.modules sage.rings.finite_rings True For undirected graphs with multiple edges:: - sage: G = Graph([(0, 2, 'a'), (0, 2, 'b'), (0, 1, 'c'), (1, 2, 'd')], multiedges=True) - sage: G.cycle_basis() + sage: G = Graph([(0, 2, 'a'), (0, 2, 'b'), (0, 1, 'c'), (1, 2, 'd')], + ....: multiedges=True) + sage: G.cycle_basis() # optional - networkx [[0, 2], [2, 1, 0]] - sage: G.cycle_basis(output='edge') + sage: G.cycle_basis(output='edge') # optional - networkx [[(0, 2, 'a'), (2, 0, 'b')], [(2, 1, 'd'), (1, 0, 'c'), (0, 2, 'a')]] - sage: H = Graph([(1, 2), (2, 3), (2, 3), (3, 4), (1, 4), (1, 4), (4, 5), (5, 6), (4, 6), (6, 7)], multiedges=True) - sage: H.cycle_basis() + sage: H = Graph([(1, 2), (2, 3), (2, 3), (3, 4), (1, 4), + ....: (1, 4), (4, 5), (5, 6), (4, 6), (6, 7)], multiedges=True) + sage: H.cycle_basis() # optional - networkx [[1, 4], [2, 3], [4, 3, 2, 1], [6, 5, 4]] Disconnected graph:: sage: G.add_cycle(["Hey", "Wuuhuu", "Really ?"]) - sage: [sorted(c) for c in G.cycle_basis()] + sage: [sorted(c) for c in G.cycle_basis()] # optional - networkx [['Hey', 'Really ?', 'Wuuhuu'], [0, 2], [0, 1, 2]] - sage: [sorted(c) for c in G.cycle_basis(output='edge')] + sage: [sorted(c) for c in G.cycle_basis(output='edge')] # optional - networkx [[('Hey', 'Wuuhuu', None), ('Really ?', 'Hey', None), ('Wuuhuu', 'Really ?', None)], @@ -5086,13 +5113,13 @@ def cycle_basis(self, output='vertex'): sage: G = graphs.CycleGraph(3) sage: G.allow_multiple_edges(True) - sage: G.cycle_basis() + sage: G.cycle_basis() # optional - networkx [[2, 1, 0]] Not yet implemented for directed graphs:: sage: G = DiGraph([(0, 2, 'a'), (0, 1, 'c'), (1, 2, 'd')]) - sage: G.cycle_basis() + sage: G.cycle_basis() # optional - networkx Traceback (most recent call last): ... NotImplementedError: not implemented for directed graphs @@ -5101,10 +5128,11 @@ def cycle_basis(self, output='vertex'): :trac:`27538`:: - sage: G= Graph([(1, 2, 'a'), (2, 3, 'b'), (2, 3, 'c'), (3, 4, 'd'), (3, 4, 'e'), (4, 1, 'f')], multiedges=True) - sage: G.cycle_basis() + sage: G = Graph([(1, 2, 'a'), (2, 3, 'b'), (2, 3, 'c'), + ....: (3, 4, 'd'), (3, 4, 'e'), (4, 1, 'f')], multiedges=True) + sage: G.cycle_basis() # optional - networkx [[2, 3], [4, 3, 2, 1], [4, 3, 2, 1]] - sage: G.cycle_basis(output='edge') + sage: G.cycle_basis(output='edge') # optional - networkx [[(2, 3, 'b'), (3, 2, 'c')], [(4, 3, 'd'), (3, 2, 'b'), (2, 1, 'a'), (1, 4, 'f')], [(4, 3, 'e'), (3, 2, 'b'), (2, 1, 'a'), (1, 4, 'f')]] @@ -5179,14 +5207,15 @@ def minimum_cycle_basis(self, algorithm=None, weight_function=None, by_weight=Fa EXAMPLES:: - sage: g = Graph([(1, 2, 3), (2, 3, 5), (3, 4, 8), (4, 1, 13), (1, 3, 250), (5, 6, 9), (6, 7, 17), (7, 5, 20)]) + sage: g = Graph([(1, 2, 3), (2, 3, 5), (3, 4, 8), (4, 1, 13), + ....: (1, 3, 250), (5, 6, 9), (6, 7, 17), (7, 5, 20)]) sage: sorted(g.minimum_cycle_basis(by_weight=True)) [[1, 2, 3], [1, 2, 3, 4], [5, 6, 7]] sage: sorted(g.minimum_cycle_basis(by_weight=False)) [[1, 2, 3], [1, 3, 4], [5, 6, 7]] - sage: sorted(g.minimum_cycle_basis(by_weight=True, algorithm='NetworkX')) + sage: sorted(g.minimum_cycle_basis(by_weight=True, algorithm='NetworkX')) # optional - networkx [[1, 2, 3], [1, 2, 3, 4], [5, 6, 7]] - sage: g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX') + sage: g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX') # optional - networkx [[1, 2, 3], [1, 3, 4], [5, 6, 7]] :: @@ -5194,7 +5223,7 @@ def minimum_cycle_basis(self, algorithm=None, weight_function=None, by_weight=Fa sage: g = Graph([(1, 2), (2, 3), (3, 4), (4, 5), (5, 1), (5, 3)]) sage: sorted(g.minimum_cycle_basis(by_weight=False)) [[1, 2, 3, 5], [3, 4, 5]] - sage: sorted(g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX')) + sage: sorted(g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX')) # optional - networkx [[1, 2, 3, 5], [3, 4, 5]] TESTS:: @@ -5323,7 +5352,7 @@ def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, se :: sage: g = graphs.PetersenGraph() - sage: (g.is_planar(kuratowski=True))[1].adjacency_matrix() + sage: (g.is_planar(kuratowski=True))[1].adjacency_matrix() # optional - sage.modules [0 1 0 0 0 1 0 0 0] [1 0 1 0 0 0 1 0 0] [0 1 0 1 0 0 0 1 0] @@ -5350,15 +5379,18 @@ def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, se sage: G.is_planar(on_embedding={}) Traceback (most recent call last): ... - NotImplementedError: cannot compute with embeddings of multiple-edged or looped graphs + NotImplementedError: cannot compute with embeddings of + multiple-edged or looped graphs sage: G.is_planar(set_pos=True) Traceback (most recent call last): ... - NotImplementedError: cannot compute with embeddings of multiple-edged or looped graphs + NotImplementedError: cannot compute with embeddings of + multiple-edged or looped graphs sage: G.is_planar(set_embedding=True) Traceback (most recent call last): ... - NotImplementedError: cannot compute with embeddings of multiple-edged or looped graphs + NotImplementedError: cannot compute with embeddings of + multiple-edged or looped graphs sage: G.is_planar(kuratowski=True) (True, None) @@ -5699,11 +5731,11 @@ def layout_planar(self, set_embedding=False, on_embedding=None, 7: [2, 4], 8: [1, 6], 9: [2, 5]} - sage: g = graphs.BalancedTree(3, 4) - sage: pos = g.layout(layout='planar', save_pos=True, test=True) - sage: pos[0] + sage: g = graphs.BalancedTree(3, 4) # optional - networkx + sage: pos = g.layout(layout='planar', save_pos=True, test=True) # optional - networkx + sage: pos[0] # optional - networkx [0, 119] - sage: pos[120] + sage: pos[120] # optional - networkx [21, 37] sage: g = graphs.CycleGraph(7) sage: g.layout(layout='planar', save_pos=True, test=True) @@ -5725,20 +5757,21 @@ def layout_planar(self, set_embedding=False, on_embedding=None, Choose the embedding:: sage: H = graphs.LadderGraph(4) - sage: em = {0:[1,4], 4:[0,5], 1:[5,2,0], 5:[4,6,1], 2:[1,3,6], 6:[7,5,2], 3:[7,2], 7:[3,6]} + sage: em = {0:[1,4], 4:[0,5], 1:[5,2,0], 5:[4,6,1], + ....: 2:[1,3,6], 6:[7,5,2], 3:[7,2], 7:[3,6]} sage: p = H.layout_planar(on_embedding=em) - sage: p # random + sage: p # random {2: [8.121320343559642, 1], - 3: [2.1213203435596424, 6], - 7: [3.1213203435596424, 0], - 0: [5.121320343559642, 3], - 1: [3.1213203435596424, 5], - 4: [4.121320343559642, 3], - 5: [4.121320343559642, 2], - 6: [3.1213203435596424, 1], - 9: [9.698670612749268, 1], - 8: [8.698670612749268, 1], - 10: [9.698670612749268, 0]} + 3: [2.1213203435596424, 6], + 7: [3.1213203435596424, 0], + 0: [5.121320343559642, 3], + 1: [3.1213203435596424, 5], + 4: [4.121320343559642, 3], + 5: [4.121320343559642, 2], + 6: [3.1213203435596424, 1], + 9: [9.698670612749268, 1], + 8: [8.698670612749268, 1], + 10: [9.698670612749268, 0]} TESTS:: @@ -5746,7 +5779,8 @@ def layout_planar(self, set_embedding=False, on_embedding=None, sage: G.layout(layout='planar', external_face=(1, 2)) Traceback (most recent call last): ... - ValueError: (1, 2) is not an edge of Graph on 4 vertices but has been provided as an edge of the external face + ValueError: (1, 2) is not an edge of Graph on 4 vertices + but has been provided as an edge of the external face Check the dependence of the computed position on the given combinatorial embedding (:trac:`28152`):: @@ -10127,12 +10161,14 @@ def _build_flow_graph(self, flow, integer): The method removes zero-cost flow cycles and updates the values accordingly:: - sage: g = digraphs.DeBruijn(2,3) - sage: flow = {('001', '010'): 1, ('010', '100'): 1, ('010', '101'): 1, ('101', '010'): 1} + sage: g = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: flow = {('001', '010'): 1, ('010', '100'): 1, + ....: ('010', '101'): 1, ('101', '010'): 1} sage: flow_graph = g._build_flow_graph(flow, True) sage: flow_graph.edges(sort=True) [('001', '010', 1), ('010', '100', 1)] - sage: flow = {('001', '010'): 2, ('010', '101'): 3, ('101', '011'): 2, ('101', '010'): 1} + sage: flow = {('001', '010'): 2, ('010', '101'): 3, + ....: ('101', '011'): 2, ('101', '010'): 1} sage: flow_graph = g._build_flow_graph(flow, True) sage: flow_graph.edges(sort=True) [('001', '010', 2), ('010', '101', 2), ('101', '011', 2)] @@ -10444,54 +10480,55 @@ def pagerank(self, alpha=0.85, personalization=None, by_weight=False, EXAMPLES:: sage: G = graphs.CycleGraph(4) - sage: G.pagerank(algorithm="Networkx") + sage: G.pagerank(algorithm="Networkx") # optional - networkx {0: 0.25, 1: 0.25, 2: 0.25, 3: 0.25} - sage: G.pagerank(alpha=0.50, algorithm="igraph") # optional - python_igraph # abs tol 1e-9 + sage: G.pagerank(alpha=0.50, algorithm="igraph") # abs tol 1e-9, optional - python_igraph {0: 0.25, 1: 0.25, 2: 0.25, 3: 0.25} - sage: G = Graph([(1, 2, 40), (2, 3, 50), (3, 4, 60), (1, 4, 70), (4, 5, 80), (5, 6, 20)]) - sage: G.pagerank(algorithm="NetworkX") # abs tol 1e-9 + sage: G = Graph([(1, 2, 40), (2, 3, 50), (3, 4, 60), + ....: (1, 4, 70), (4, 5, 80), (5, 6, 20)]) + sage: G.pagerank(algorithm="NetworkX") # abs tol 1e-9 # optional - networkx {1: 0.16112205885619563, 2: 0.1619531043247219, 3: 0.16112205885619563, 4: 0.2374999999999999, 5: 0.17775588228760858, 6: 0.100546895675278} - sage: G.pagerank(algorithm="NetworkX", by_weight=True) # abs tol 1e-9 + sage: G.pagerank(algorithm="NetworkX", by_weight=True) # abs tol 1e-9 # optional - networkx {1: 0.16459583718588994, 2: 0.13977928595154515, 3: 0.16539840184339605, 4: 0.3063198690713853, 5: 0.1700057609707141, 6: 0.05390084497706962} - sage: G.pagerank(algorithm="Scipy") # abs tol 1e-9 + sage: G.pagerank(algorithm="Scipy") # abs tol 1e-9 # optional - scipy {1: 0.16112205885619563, 2: 0.1619531043247219, 3: 0.16112205885619563, 4: 0.2374999999999999, 5: 0.17775588228760858, 6: 0.100546895675278} - sage: G.pagerank(algorithm="Scipy", by_weight=True) # abs tol 1e-9 + sage: G.pagerank(algorithm="Scipy", by_weight=True) # abs tol 1e-9 # optional - scipy {1: 0.16459583718588994, 2: 0.13977928595154515, 3: 0.16539840184339605, 4: 0.3063198690713853, 5: 0.1700057609707141, 6: 0.05390084497706962} - sage: G.pagerank(algorithm="igraph") # optional - python_igraph # abs tol 1e-9 + sage: G.pagerank(algorithm="igraph") # abs tol 1e-9, optional - python_igraph {1: 0.16112198303979128, 2: 0.16195368558382262, 3: 0.16112198303979125, 4: 0.23749999999999993, 5: 0.17775603392041744, 6: 0.10054631441617742} - sage: G.pagerank() # abs tol 1e-9 + sage: G.pagerank() # abs tol 1e-9 {1: 0.16112205885619563, 2: 0.1619531043247219, 3: 0.16112205885619563, 4: 0.2374999999999999, 5: 0.17775588228760858, 6: 0.100546895675278} - sage: G.pagerank(by_weight=True) # abs tol 1e-9 + sage: G.pagerank(by_weight=True) # abs tol 1e-9 {1: 0.16459583718588994, 2: 0.13977928595154515, 3: 0.16539840184339605, @@ -10502,7 +10539,8 @@ def pagerank(self, alpha=0.85, personalization=None, by_weight=False, TESTS:: sage: G = Graph([(1, 2), (2, 3), (3, 4), (1, 3)]) - sage: G.pagerank(algorithm="NetworkX", personalization={1:0, 2:3, 3:-2, 4:-1}) + sage: G.pagerank(algorithm="NetworkX", # optional - networkx + ....: personalization={1:0, 2:3, 3:-2, 4:-1}) Traceback (most recent call last): ... ZeroDivisionError... @@ -12941,13 +12979,13 @@ def degree(self, vertices=None, labels=False): returned list is the degree of the `i`-th vertex in the list ``list(self)``:: - sage: D = digraphs.DeBruijn(4, 2) - sage: D.delete_vertex('20') - sage: print(D.degree()) + sage: D = digraphs.DeBruijn(4, 2) # optional - sage.combinat + sage: D.delete_vertex('20') # optional - sage.combinat + sage: print(D.degree()) # optional - sage.combinat [7, 7, 6, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 7, 8] - sage: print(D.degree(vertices=list(D))) + sage: print(D.degree(vertices=list(D))) # optional - sage.combinat [7, 7, 6, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 7, 8] - sage: print(D.degree(vertices=D.vertices(sort=False))) + sage: print(D.degree(vertices=D.vertices(sort=False))) # optional - sage.combinat [7, 7, 6, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 7, 8] """ if labels: @@ -13085,11 +13123,11 @@ def degree_iterator(self, vertices=None, labels=False): When ``vertices=None`` yields values in the order of ``list(D)``:: sage: V = list(D) - sage: D = digraphs.DeBruijn(4, 2) - sage: D.delete_vertex('20') - sage: print(list(D.degree_iterator())) + sage: D = digraphs.DeBruijn(4, 2) # optional - sage.combinat + sage: D.delete_vertex('20') # optional - sage.combinat + sage: print(list(D.degree_iterator())) # optional - sage.combinat [7, 7, 6, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 7, 8] - sage: print([D.degree(v) for v in D]) + sage: print([D.degree(v) for v in D]) # optional - sage.combinat [7, 7, 6, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 7, 8] """ if vertices is None: @@ -13720,99 +13758,99 @@ def subgraph_search(self, G, induced=False): The Petersen graph contains the path graph `P_5`:: sage: g = graphs.PetersenGraph() - sage: h1 = g.subgraph_search(graphs.PathGraph(5)); h1 + sage: h1 = g.subgraph_search(graphs.PathGraph(5)); h1 # optional - sage.modules Subgraph of (Petersen graph): Graph on 5 vertices - sage: h1.vertices(sort=True); h1.edges(sort=True, labels=False) + sage: h1.vertices(sort=True); h1.edges(sort=True, labels=False) # optional - sage.modules [0, 1, 2, 3, 4] [(0, 1), (1, 2), (2, 3), (3, 4)] - sage: I1 = g.subgraph_search(graphs.PathGraph(5), induced=True); I1 + sage: I1 = g.subgraph_search(graphs.PathGraph(5), induced=True); I1 # optional - sage.modules Subgraph of (Petersen graph): Graph on 5 vertices - sage: I1.vertices(sort=True); I1.edges(sort=True, labels=False) + sage: I1.vertices(sort=True); I1.edges(sort=True, labels=False) # optional - sage.modules [0, 1, 2, 3, 8] [(0, 1), (1, 2), (2, 3), (3, 8)] It also contains the claw `K_{1,3}`:: - sage: h2 = g.subgraph_search(graphs.ClawGraph()); h2 + sage: h2 = g.subgraph_search(graphs.ClawGraph()); h2 # optional - sage.modules Subgraph of (Petersen graph): Graph on 4 vertices - sage: h2.vertices(sort=True); h2.edges(sort=True, labels=False) + sage: h2.vertices(sort=True); h2.edges(sort=True, labels=False) # optional - sage.modules [0, 1, 4, 5] [(0, 1), (0, 4), (0, 5)] - sage: I2 = g.subgraph_search(graphs.ClawGraph(), induced=True); I2 + sage: I2 = g.subgraph_search(graphs.ClawGraph(), induced=True); I2 # optional - sage.modules Subgraph of (Petersen graph): Graph on 4 vertices - sage: I2.vertices(sort=True); I2.edges(sort=True, labels=False) + sage: I2.vertices(sort=True); I2.edges(sort=True, labels=False) # optional - sage.modules [0, 1, 4, 5] [(0, 1), (0, 4), (0, 5)] Of course the induced copies are isomorphic to the graphs we were looking for:: - sage: I1.is_isomorphic(graphs.PathGraph(5)) + sage: I1.is_isomorphic(graphs.PathGraph(5)) # optional - sage.modules True - sage: I2.is_isomorphic(graphs.ClawGraph()) + sage: I2.is_isomorphic(graphs.ClawGraph()) # optional - sage.modules True However, the Petersen graph does not contain a subgraph isomorphic to `K_3`:: - sage: g.subgraph_search(graphs.CompleteGraph(3)) is None + sage: g.subgraph_search(graphs.CompleteGraph(3)) is None # optional - sage.modules True Nor does it contain a nonempty induced subgraph isomorphic to `P_6`:: - sage: g.subgraph_search(graphs.PathGraph(6), induced=True) is None + sage: g.subgraph_search(graphs.PathGraph(6), induced=True) is None # optional - sage.modules True The empty graph is a subgraph of every graph:: - sage: g.subgraph_search(graphs.EmptyGraph()) + sage: g.subgraph_search(graphs.EmptyGraph()) # optional - sage.modules Graph on 0 vertices - sage: g.subgraph_search(graphs.EmptyGraph(), induced=True) + sage: g.subgraph_search(graphs.EmptyGraph(), induced=True) # optional - sage.modules Graph on 0 vertices The subgraph may just have edges missing:: sage: k3 = graphs.CompleteGraph(3); p3 = graphs.PathGraph(3) sage: k3.relabel(list('abc')) - sage: s = k3.subgraph_search(p3) - sage: s.edges(sort=True, labels=False) + sage: s = k3.subgraph_search(p3) # optional - sage.modules + sage: s.edges(sort=True, labels=False) # optional - sage.modules [('a', 'b'), ('b', 'c')] Of course, `P_3` is not an induced subgraph of `K_3`, though:: sage: k3 = graphs.CompleteGraph(3); p3 = graphs.PathGraph(3) sage: k3.relabel(list('abc')) - sage: k3.subgraph_search(p3, induced=True) is None + sage: k3.subgraph_search(p3, induced=True) is None # optional - sage.modules True If the graph has labels, the labels are just ignored:: sage: g.set_vertex(0, 'foo') - sage: c = g.subgraph_search(graphs.PathGraph(5)) - sage: c.get_vertices() + sage: c = g.subgraph_search(graphs.PathGraph(5)) # optional - sage.modules + sage: c.get_vertices() # optional - sage.modules {0: 'foo', 1: None, 2: None, 3: None, 4: None} TESTS: Inside of a small graph (:trac:`13906`):: - sage: Graph(5).subgraph_search(Graph(1)) + sage: Graph(5).subgraph_search(Graph(1)) # optional - sage.modules Graph on 1 vertex For labelled edges (:trac:`14999`):: sage: G = graphs.CompleteGraph(10) - sage: C = G.subgraph_search(graphs.CycleGraph(4)) - sage: C.size() + sage: C = G.subgraph_search(graphs.CycleGraph(4)) # optional - sage.modules + sage: C.size() # optional - sage.modules 4 - sage: C.edges(sort=True) + sage: C.edges(sort=True) # optional - sage.modules [(0, 1, None), (0, 3, None), (1, 2, None), (2, 3, None)] sage: for (u,v) in G.edges(sort=True, labels=False): ....: G.set_edge_label(u, v, u) - sage: C = G.subgraph_search(graphs.CycleGraph(4)) - sage: C.edges(sort=True) + sage: C = G.subgraph_search(graphs.CycleGraph(4)) # optional - sage.modules + sage: C.edges(sort=True) # optional - sage.modules [(0, 1, 0), (0, 3, 0), (1, 2, 1), (2, 3, 2)] """ @@ -13853,12 +13891,12 @@ def subgraph_search_count(self, G, induced=False): Counting the number of paths `P_5` in a PetersenGraph:: sage: g = graphs.PetersenGraph() - sage: g.subgraph_search_count(graphs.PathGraph(5)) + sage: g.subgraph_search_count(graphs.PathGraph(5)) # optional - sage.modules 240 Requiring these subgraphs be induced:: - sage: g.subgraph_search_count(graphs.PathGraph(5), induced=True) + sage: g.subgraph_search_count(graphs.PathGraph(5), induced=True) # optional - sage.modules 120 If we define the graph `T_k` (the transitive tournament on `k` vertices) @@ -13867,36 +13905,36 @@ def subgraph_search_count(self, G, induced=False): `0`:: sage: T5 = digraphs.TransitiveTournament(5) - sage: T5.subgraph_search_count(digraphs.Circuit(3)) + sage: T5.subgraph_search_count(digraphs.Circuit(3)) # optional - sage.modules 0 If we count instead the number of `T_3` in `T_5`, we expect the answer to be `\binom{5}{3}`:: sage: T3 = digraphs.TransitiveTournament(3) - sage: T5.subgraph_search_count(T3) + sage: T5.subgraph_search_count(T3) # optional - sage.modules 10 sage: binomial(5,3) 10 - sage: T3.is_isomorphic(T5.subgraph(vertices=[0, 1, 2])) + sage: T3.is_isomorphic(T5.subgraph(vertices=[0, 1, 2])) # optional - sage.modules True The empty graph is a subgraph of every graph:: - sage: g.subgraph_search_count(graphs.EmptyGraph()) + sage: g.subgraph_search_count(graphs.EmptyGraph()) # optional - sage.modules 1 If the graph has vertex labels or edge labels, the label is just ignored:: sage: g.set_vertex(0, 'foo') - sage: g.subgraph_search_count(graphs.PathGraph(5)) + sage: g.subgraph_search_count(graphs.PathGraph(5)) # optional - sage.modules 240 TESTS: Inside of a small graph (:trac:`13906`):: - sage: Graph(5).subgraph_search_count(Graph(1)) + sage: Graph(5).subgraph_search_count(Graph(1)) # optional - sage.modules 5 """ from sage.graphs.generic_graph_pyx import SubgraphSearch @@ -13963,7 +14001,7 @@ def subgraph_search_iterator(self, G, induced=False, return_graphs=True): sage: g = graphs.PathGraph(5) sage: P3 = graphs.PathGraph(3) - sage: for p in g.subgraph_search_iterator(P3, return_graphs=False): + sage: for p in g.subgraph_search_iterator(P3, return_graphs=False): # optional - sage.modules ....: print(p) [0, 1, 2] [1, 2, 3] @@ -13971,7 +14009,7 @@ def subgraph_search_iterator(self, G, induced=False, return_graphs=True): [2, 3, 4] [3, 2, 1] [4, 3, 2] - sage: for p in g.subgraph_search_iterator(P3, return_graphs=True): + sage: for p in g.subgraph_search_iterator(P3, return_graphs=True): # optional - sage.modules ....: print(p) Subgraph of (Path graph) Subgraph of (Path graph) @@ -13979,13 +14017,13 @@ def subgraph_search_iterator(self, G, induced=False, return_graphs=True): Subgraph of (Path graph) Subgraph of (Path graph) Subgraph of (Path graph) - sage: all(h.is_isomorphic(P3) for h in g.subgraph_search_iterator(P3)) + sage: all(h.is_isomorphic(P3) for h in g.subgraph_search_iterator(P3)) # optional - sage.modules True If the graph has vertex labels or edge labels, the label is just ignored:: sage: g.set_vertex(0, 'foo') - sage: for p in g.subgraph_search_iterator(P3, return_graphs=False): + sage: for p in g.subgraph_search_iterator(P3, return_graphs=False): # optional - sage.modules ....: print(p) [0, 1, 2] [1, 2, 3] @@ -13998,45 +14036,47 @@ def subgraph_search_iterator(self, G, induced=False, return_graphs=True): sage: H = graphs.HouseGraph() sage: P4 = graphs.PathGraph(4) - sage: all(h.is_isomorphic(P4) for h in H.subgraph_search_iterator(P4, induced=True)) + sage: all(h.is_isomorphic(P4) # optional - sage.modules + ....: for h in H.subgraph_search_iterator(P4, induced=True)) True - sage: sum(1 for h in H.subgraph_search_iterator(P4, induced=True)) + sage: sum(1 for h in H.subgraph_search_iterator(P4, induced=True)) # optional - sage.modules 4 - sage: sum(1 for h in H.subgraph_search_iterator(P4, induced=False)) + sage: sum(1 for h in H.subgraph_search_iterator(P4, induced=False)) # optional - sage.modules 20 Search for subdigraphs:: sage: H = digraphs.Complete(5) sage: P4 = digraphs.Path(4) - sage: sum(1 for _ in H.subgraph_search_iterator(P4, induced=True)) + sage: sum(1 for _ in H.subgraph_search_iterator(P4, induced=True)) # optional - sage.modules 0 - sage: sum(1 for _ in H.subgraph_search_iterator(P4, induced=False)) + sage: sum(1 for _ in H.subgraph_search_iterator(P4, induced=False)) # optional - sage.modules 120 This method also works for bipartite graphs:: sage: K33 = BipartiteGraph(graphs.CompleteBipartiteGraph(3, 3)) sage: K22 = BipartiteGraph(graphs.CompleteBipartiteGraph(2, 2)) - sage: sum(1 for _ in K33.subgraph_search_iterator(K22)) + sage: sum(1 for _ in K33.subgraph_search_iterator(K22)) # optional - sage.modules 72 TESTS: Inside of a small graph (:trac:`13906`):: - sage: list(Graph(5).subgraph_search_iterator(Graph(1))) - [Graph on 1 vertex, Graph on 1 vertex, Graph on 1 vertex, Graph on 1 vertex, Graph on 1 vertex] + sage: list(Graph(5).subgraph_search_iterator(Graph(1))) # optional - sage.modules + [Graph on 1 vertex, Graph on 1 vertex, Graph on 1 vertex, + Graph on 1 vertex, Graph on 1 vertex] Check that the behavior of the method is consistent (:trac:`34004`):: sage: g = graphs.CycleGraph(3) - sage: for i in range(3): + sage: for i in range(3): # optional - sage.modules ....: g.subgraph_search_iterator(graphs.PathGraph(i)) sage: K4 = digraphs.Complete(4) sage: K3 = digraphs.Complete(3) - sage: for g in K4.subgraph_search_iterator(K3, return_graphs=True): + sage: for g in K4.subgraph_search_iterator(K3, return_graphs=True): # optional - sage.modules ....: print(type(g)) ....: break sage: K33 = BipartiteGraph(graphs.CompleteBipartiteGraph(3, 3)) sage: K22 = BipartiteGraph(graphs.CompleteBipartiteGraph(2, 2)) - sage: for b in K33.subgraph_search_iterator(K22, return_graphs=True): + sage: for b in K33.subgraph_search_iterator(K22, return_graphs=True): # optional - sage.modules ....: print(type(b)) ....: break sage: P5 = graphs.PathGraph(5) - sage: for b in K33.subgraph_search_iterator(P5, return_graphs=True): + sage: for b in K33.subgraph_search_iterator(P5, return_graphs=True): # optional - sage.modules ....: print(type(b)) ....: break - sage: for b in Graph(K33).subgraph_search_iterator(K22, return_graphs=True): + sage: for b in Graph(K33).subgraph_search_iterator(K22, return_graphs=True): # optional - sage.modules ....: print(type(b)) ....: break @@ -14142,7 +14182,7 @@ def is_chordal(self, certificate=False, algorithm="B"): cycle of length at least 4). Alternatively, chordality can be defined using a Perfect Elimination - Order : + Order: A Perfect Elimination Order of a graph `G` is an ordering `v_1,...,v_n` of its vertex set such that for all `i`, the neighbors of `v_i` whose @@ -14204,20 +14244,21 @@ def is_chordal(self, certificate=False, algorithm="B"): The same goes with the product of a random lobster (which is a tree) and a Complete Graph :: - sage: g = graphs.RandomLobster(10, .5, .5).lexicographic_product(graphs.CompleteGraph(3)) - sage: g.is_chordal() + sage: grl = graphs.RandomLobster(10, .5, .5) # optional - networkx + sage: g = grl.lexicographic_product(graphs.CompleteGraph(3)) # optional - networkx + sage: g.is_chordal() # optional - networkx True The disjoint union of chordal graphs is still chordal:: - sage: (2 * g).is_chordal() + sage: (2 * g).is_chordal() # optional - networkx True Let us check the certificate given by Sage is indeed a perfect elimination order:: - sage: _, peo = g.is_chordal(certificate=True) - sage: for v in peo: + sage: _, peo = g.is_chordal(certificate=True) # optional - networkx + sage: for v in peo: # optional - networkx ....: if not g.subgraph(g.neighbors(v)).is_clique(): ....: raise ValueError("this should never happen") ....: g.delete_vertex(v) @@ -14437,27 +14478,27 @@ def is_circulant(self, certificate=False): The Petersen graph is not a circulant graph:: sage: g = graphs.PetersenGraph() - sage: g.is_circulant() + sage: g.is_circulant() # optional - sage.groups False A cycle is obviously a circulant graph, but several sets of parameters can be used to define it:: sage: g = graphs.CycleGraph(5) - sage: g.is_circulant(certificate=True) + sage: g.is_circulant(certificate=True) # optional - sage.groups (True, [(5, [1, 4]), (5, [2, 3])]) The same goes for directed graphs:: sage: g = digraphs.Circuit(5) - sage: g.is_circulant(certificate=True) + sage: g.is_circulant(certificate=True) # optional - sage.groups (True, [(5, [1]), (5, [3]), (5, [2]), (5, [4])]) With this information, it is very easy to create (and plot) all possible drawings of a circulant graph:: sage: g = graphs.CirculantGraph(13, [2, 3, 10, 11]) - sage: for param in g.is_circulant(certificate=True)[1]: + sage: for param in g.is_circulant(certificate=True)[1]: # optional - sage.groups ....: graphs.CirculantGraph(*param) Circulant graph ([2, 3, 10, 11]): Graph on 13 vertices Circulant graph ([1, 5, 8, 12]): Graph on 13 vertices @@ -14465,13 +14506,13 @@ def is_circulant(self, certificate=False): TESTS:: - sage: digraphs.DeBruijn(3,1).is_circulant(certificate=True) + sage: digraphs.DeBruijn(3,1).is_circulant(certificate=True) # optional - sage.combinat sage.groups (True, [(3, [0, 1, 2])]) - sage: Graph(1).is_circulant(certificate=True) + sage: Graph(1).is_circulant(certificate=True) # optional - sage.groups (True, (1, [])) - sage: Graph(0).is_circulant(certificate=True) + sage: Graph(0).is_circulant(certificate=True) # optional - sage.groups (True, (0, [])) - sage: Graph({0: [0]}).is_circulant(certificate=True) + sage: Graph({0: [0]}).is_circulant(certificate=True) # optional - sage.groups (True, (1, [0])) """ self._scream_if_not_simple(allow_loops=True) @@ -15061,11 +15102,11 @@ def is_subgraph(self, other, induced=True, up_to_isomorphism=False): sage: p11 = graphs.PathGraph(11) sage: p15 = graphs.PathGraph(15) sage: g = graphs.Grid2dGraph(4, 4) - sage: p15.is_subgraph(g, induced=False, up_to_isomorphism=True) + sage: p15.is_subgraph(g, induced=False, up_to_isomorphism=True) # optional - sage.modules True - sage: p15.is_subgraph(g, induced=True, up_to_isomorphism=True) + sage: p15.is_subgraph(g, induced=True, up_to_isomorphism=True) # optional - sage.modules False - sage: p11.is_subgraph(g, induced=True, up_to_isomorphism=True) + sage: p11.is_subgraph(g, induced=True, up_to_isomorphism=True) # optional - sage.modules True TESTS: @@ -15143,7 +15184,7 @@ def cluster_triangles(self, nbunch=None, implementation=None): :: sage: G = graphs.RandomGNP(20, .3) - sage: d1 = G.cluster_triangles(implementation="networkx") + sage: d1 = G.cluster_triangles(implementation="networkx") # optional - networkx sage: d2 = G.cluster_triangles(implementation="dense_copy") sage: d3 = G.cluster_triangles(implementation="sparse_copy") sage: d1 == d2 and d1 == d3 @@ -15151,7 +15192,7 @@ def cluster_triangles(self, nbunch=None, implementation=None): TESTS:: - sage: DiGraph().cluster_triangles(implementation="networkx") + sage: DiGraph().cluster_triangles(implementation="networkx") # optional - networkx Traceback (most recent call last): ... ValueError: the 'networkx' implementation does not support directed graphs @@ -15211,7 +15252,7 @@ def clustering_average(self, implementation=None): sage: (graphs.FruchtGraph()).clustering_average() 1/4 - sage: (graphs.FruchtGraph()).clustering_average(implementation='networkx') + sage: (graphs.FruchtGraph()).clustering_average(implementation='networkx') # optional - networkx 0.25 TESTS: @@ -15226,9 +15267,11 @@ def clustering_average(self, implementation=None): The result is the same with all implementations:: sage: G = graphs.RandomGNM(10,20) + sage: impls = ['boost','sparse_copy','dense_copy'] + sage: impls += ['networkx'] # optional - networkx sage: coeffs = [G.clustering_average(implementation=impl) - ....: for impl in ['boost','sparse_copy','dense_copy','networkx']] - sage: max(coeffs)-min(coeffs) # tol abs 1e-12 + ....: for impl in impls] + sage: max(coeffs) - min(coeffs) # tol abs 1e-12 0 """ @@ -15305,10 +15348,10 @@ def clustering_coeff(self, sage: (graphs.FruchtGraph()).clustering_coeff(weight=True) {0: 0.3333333333333333, 1: 0.3333333333333333, 2: 0, - 3: 0.3333333333333333, 4: 0.3333333333333333, - 5: 0.3333333333333333, 6: 0.3333333333333333, - 7: 0.3333333333333333, 8: 0, 9: 0.3333333333333333, - 10: 0.3333333333333333, 11: 0} + 3: 0.3333333333333333, 4: 0.3333333333333333, + 5: 0.3333333333333333, 6: 0.3333333333333333, + 7: 0.3333333333333333, 8: 0, 9: 0.3333333333333333, + 10: 0.3333333333333333, 11: 0} sage: (graphs.FruchtGraph()).clustering_coeff(nodes=[0,1,2]) {0: 0.3333333333333333, 1: 0.3333333333333333, 2: 0.0} @@ -15411,7 +15454,7 @@ def cluster_transitivity(self): EXAMPLES:: - sage: graphs.FruchtGraph().cluster_transitivity() + sage: graphs.FruchtGraph().cluster_transitivity() # optional - networkx 0.25 """ import networkx @@ -15616,7 +15659,7 @@ def girth(self, certificate=False): Issue :trac:`12355`:: - sage: H=Graph([(0, 1), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 6), (2, 5), (3, 4), (5, 6)]) + sage: H = Graph([(0, 1), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 6), (2, 5), (3, 4), (5, 6)]) sage: H.girth() 3 @@ -15646,13 +15689,13 @@ def girth(self, certificate=False): sage: g = digraphs.Circuit(6) sage: g.girth() 6 - sage: g = digraphs.RandomDirectedGNC(10) - sage: g.girth() + sage: g = digraphs.RandomDirectedGNC(10) # optional - networkx + sage: g.girth() # optional - networkx +Infinity - sage: g = DiGraph([(0, 1), (1, 2), (1, 3), (2, 3), (3, 4), (4, 0)]) - sage: g.girth() + sage: g = DiGraph([(0, 1), (1, 2), (1, 3), (2, 3), (3, 4), (4, 0)]) # optional - networkx + sage: g.girth() # optional - networkx 4 - sage: Graph(g).girth() + sage: Graph(g).girth() # optional - networkx 3 """ # Cases where girth <= 2 @@ -15703,10 +15746,10 @@ def odd_girth(self, algorithm="bfs", certificate=False): The McGee graph has girth 7 and therefore its odd girth is 7 as well:: - sage: G = graphs.McGeeGraph() - sage: G.girth() + sage: G = graphs.McGeeGraph() # optional - networkx + sage: G.girth() # optional - networkx 7 - sage: G.odd_girth() + sage: G.odd_girth() # optional - networkx 7 Any complete (directed) graph on more than 2 vertices contains @@ -15731,15 +15774,15 @@ def odd_girth(self, algorithm="bfs", certificate=False): The odd girth of a (directed) graph with loops is 1:: - sage: G = graphs.RandomGNP(10, .5) - sage: G.allow_loops(True) - sage: G.add_edge(0, 0) - sage: G.odd_girth() + sage: G = graphs.RandomGNP(10, .5) # optional - networkx + sage: G.allow_loops(True) # optional - networkx + sage: G.add_edge(0, 0) # optional - networkx + sage: G.odd_girth() # optional - networkx 1 - sage: G = digraphs.RandomDirectedGNP(10, .5) - sage: G.allow_loops(True) - sage: G.add_edge(0, 0) - sage: G.odd_girth() + sage: G = digraphs.RandomDirectedGNP(10, .5) # optional - networkx + sage: G.allow_loops(True) # optional - networkx + sage: G.add_edge(0, 0) # optional - networkx + sage: G.odd_girth() # optional - networkx 1 .. SEEALSO:: @@ -15952,9 +15995,9 @@ def centrality_betweenness(self, k=None, normalized=True, weight=None, TESTS:: - sage: tests = ([graphs.RandomGNP(30,.1) for i in range(10)]+ + sage: tests = ([graphs.RandomGNP(30,.1) for i in range(10)]+ # optional - networkx ....: [digraphs.RandomDirectedGNP(30,.1) for i in range(10)]) - sage: for g in tests: + sage: for g in tests: # optional - networkx ....: r1 = g.centrality_betweenness(algorithm="Sage",exact=0) ....: r2 = g.centrality_betweenness(algorithm="Sage",exact=1) ....: r3 = g.centrality_betweenness(algorithm="NetworkX") @@ -16460,9 +16503,9 @@ def shortest_path(self, u, v, by_weight=False, algorithm=None, [4, 17, 16, 12, 13, 9] sage: D.shortest_path(4, 9, algorithm='BFS') [4, 3, 2, 1, 8, 9] - sage: D.shortest_path(4, 8, algorithm='Dijkstra_NetworkX') + sage: D.shortest_path(4, 8, algorithm='Dijkstra_NetworkX') # optional - networkx [4, 3, 2, 1, 8] - sage: D.shortest_path(4, 8, algorithm='Dijkstra_Bid_NetworkX') + sage: D.shortest_path(4, 8, algorithm='Dijkstra_Bid_NetworkX') # optional - networkx [4, 3, 2, 1, 8] sage: D.shortest_path(4, 9, algorithm='Dijkstra_Bid') [4, 3, 19, 0, 10, 9] @@ -16471,15 +16514,18 @@ def shortest_path(self, u, v, by_weight=False, algorithm=None, sage: D.delete_edges(D.edges_incident(13)) sage: D.shortest_path(13, 4) [] - sage: G = Graph({0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: 2}}, sparse = True) + sage: G = Graph({0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: 2}}, + ....: sparse=True) sage: G.plot(edge_labels=True).show() # long time sage: G.shortest_path(0, 3) [0, 4, 3] sage: G.shortest_path(0, 3, by_weight=True) [0, 1, 2, 3] - sage: G.shortest_path(0, 3, by_weight=True, algorithm='Dijkstra_NetworkX') + sage: G.shortest_path(0, 3, by_weight=True, # optional - networkx + ....: algorithm='Dijkstra_NetworkX') [0, 1, 2, 3] - sage: G.shortest_path(0, 3, by_weight=True, algorithm='Dijkstra_Bid_NetworkX') + sage: G.shortest_path(0, 3, by_weight=True, # optional - networkx + ....: algorithm='Dijkstra_Bid_NetworkX') [0, 1, 2, 3] TESTS: @@ -16517,15 +16563,11 @@ def shortest_path(self, u, v, by_weight=False, algorithm=None, sage: G = Graph() sage: G.add_vertices([1, 2]) - sage: for alg in ['BFS', 'BFS_Bid', 'Dijkstra_NetworkX', 'Dijkstra_Bid_NetworkX', - ....: 'Dijkstra_Bid', 'Bellman-Ford_Boost']: - ....: G.shortest_path(1, 2, algorithm=alg) - [] - [] - [] - [] - [] - [] + sage: algs = ['BFS', 'BFS_Bid', 'Dijkstra_Bid', 'Bellman-Ford_Boost'] + sage: algs += ['Dijkstra_NetworkX', 'Dijkstra_Bid_NetworkX'] # optional - networkx + sage: all(G.shortest_path(1, 2, algorithm=alg) == [] + ....: for alg in algs) + True .. TODO:: @@ -16646,9 +16688,9 @@ def shortest_path_length(self, u, v, by_weight=False, algorithm=None, 5 sage: D.shortest_path_length(4, 9, algorithm='BFS') 5 - sage: D.shortest_path_length(4, 9, algorithm='Dijkstra_NetworkX') + sage: D.shortest_path_length(4, 9, algorithm='Dijkstra_NetworkX') # optional - networkx 5 - sage: D.shortest_path_length(4, 9, algorithm='Dijkstra_Bid_NetworkX') + sage: D.shortest_path_length(4, 9, algorithm='Dijkstra_Bid_NetworkX') # optional - networkx 5 sage: D.shortest_path_length(4, 9, algorithm='Dijkstra_Bid') 5 @@ -16659,31 +16701,37 @@ def shortest_path_length(self, u, v, by_weight=False, algorithm=None, sage: D.delete_edges(D.edges_incident(13)) sage: D.shortest_path_length(13, 4) +Infinity - sage: G = Graph({0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: 2}}, sparse = True) - sage: G.plot(edge_labels=True).show() # long time + sage: G = Graph({0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: 2}}, + ....: sparse=True) + sage: G.plot(edge_labels=True).show() # long time sage: G.shortest_path_length(0, 3) 2 sage: G.shortest_path_length(0, 3, by_weight=True) 3 - sage: G.shortest_path_length(0, 3, by_weight=True, algorithm='Dijkstra_NetworkX') + sage: G.shortest_path_length(0, 3, by_weight=True, # optional - networkx + ....: algorithm='Dijkstra_NetworkX') 3 - sage: G.shortest_path_length(0, 3, by_weight=True, algorithm='Dijkstra_Bid_NetworkX') + sage: G.shortest_path_length(0, 3, by_weight=True, # optional - networkx + ....: algorithm='Dijkstra_Bid_NetworkX') 3 If Dijkstra is used with negative weights, usually it raises an error:: - sage: G = DiGraph({0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: -2}}, sparse = True) + sage: G = DiGraph({0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: -2}}, + ....: sparse=True) sage: G.shortest_path_length(4, 1, by_weight=True, algorithm=None) Traceback (most recent call last): ... ValueError: the graph contains an edge with negative weight - sage: G.shortest_path_length(4, 1, by_weight=True, algorithm='Bellman-Ford_Boost') + sage: G.shortest_path_length(4, 1, by_weight=True, + ....: algorithm='Bellman-Ford_Boost') -1 However, sometimes the result may be wrong, and no error is raised:: - sage: G = DiGraph([(0,1,1),(1,2,1),(0,3,1000),(3,4,-3000), (4,2,1000)]) - sage: G.shortest_path_length(0, 2, by_weight=True, algorithm='Bellman-Ford_Boost') + sage: G = DiGraph([(0,1,1), (1,2,1), (0,3,1000), (3,4,-3000), (4,2,1000)]) + sage: G.shortest_path_length(0, 2, by_weight=True, + ....: algorithm='Bellman-Ford_Boost') -1000 sage: G.shortest_path_length(0, 2, by_weight=True) 2 @@ -16705,15 +16753,11 @@ def shortest_path_length(self, u, v, by_weight=False, algorithm=None, sage: G = Graph() sage: G.add_vertices([1, 2]) - sage: for alg in ['BFS', 'BFS_Bid', 'Dijkstra_NetworkX', 'Dijkstra_Bid_NetworkX', - ....: 'Dijkstra_Bid', 'Bellman-Ford_Boost']: - ....: G.shortest_path_length(1, 2, algorithm=alg) - +Infinity - +Infinity - +Infinity - +Infinity - +Infinity - +Infinity + sage: algs = ['BFS', 'BFS_Bid', 'Dijkstra_Bid', 'Bellman-Ford_Boost'] + sage: algs += ['Dijkstra_NetworkX', 'Dijkstra_Bid_NetworkX'] # optional - networkx + sage: all(G.shortest_path_length(1, 2, algorithm=alg) == Infinity + ....: for alg in algs) + True """ if not self.has_vertex(u): raise ValueError("vertex '{}' is not in the (di)graph".format(u)) @@ -17214,20 +17258,23 @@ def shortest_path_lengths(self, u, by_weight=False, algorithm=None, sage: D = graphs.DodecahedralGraph() sage: D.shortest_path_lengths(0) - {0: 0, 1: 1, 2: 2, 3: 2, 4: 3, 5: 4, 6: 3, 7: 3, 8: 2, 9: 2, 10: 1, 11: 2, 12: 3, 13: 3, 14: 4, 15: 5, 16: 4, 17: 3, 18: 2, 19: 1} + {0: 0, 1: 1, 2: 2, 3: 2, 4: 3, 5: 4, 6: 3, 7: 3, 8: 2, 9: 2, 10: 1, + 11: 2, 12: 3, 13: 3, 14: 4, 15: 5, 16: 4, 17: 3, 18: 2, 19: 1} Weighted case:: - sage: G = Graph( { 0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: 2} }, sparse=True) - sage: G.plot(edge_labels=True).show() # long time + sage: G = Graph({0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: 2}}, + ....: sparse=True) + sage: G.plot(edge_labels=True).show() # long time # optional - sage.plot sage: G.shortest_path_lengths(0, by_weight=True) {0: 0, 1: 1, 2: 2, 3: 3, 4: 2} Using a weight function:: - sage: D = DiGraph([(0,1,{'weight':1}),(1,2,{'weight':3}),(0,2,{'weight':5})]) - sage: weight_function = lambda e:e[2]['weight'] - sage: D.shortest_path_lengths(1, algorithm='Dijkstra_NetworkX', by_weight=False) + sage: D = DiGraph([(0,1,{'weight':1}), (1,2,{'weight':3}), (0,2,{'weight':5})]) + sage: weight_function = lambda e: e[2]['weight'] + sage: D.shortest_path_lengths(1, algorithm='Dijkstra_NetworkX', # optional - networkx + ....: by_weight=False) {1: 0, 2: 1} sage: D.shortest_path_lengths(0, weight_function=weight_function) {0: 0, 1: 1, 2: 4} @@ -17236,13 +17283,13 @@ def shortest_path_lengths(self, u, by_weight=False, algorithm=None, Negative weights:: - sage: D = DiGraph([(0,1,{'weight':-1}),(1,2,{'weight':3}),(0,2,{'weight':5})]) + sage: D = DiGraph([(0,1,{'weight':-1}), (1,2,{'weight':3}), (0,2,{'weight':5})]) sage: D.shortest_path_lengths(0, weight_function=weight_function) {0: 0, 1: -1, 2: 2} Negative cycles:: - sage: D = DiGraph([(0,1,{'weight':-5}),(1,2,{'weight':3}),(2,0,{'weight':1})]) + sage: D = DiGraph([(0,1,{'weight':-5}), (1,2,{'weight':3}), (2,0,{'weight':1})]) sage: D.shortest_path_lengths(0, weight_function=weight_function) Traceback (most recent call last): ... @@ -17252,7 +17299,7 @@ def shortest_path_lengths(self, u, by_weight=False, algorithm=None, sage: g = graphs.Grid2dGraph(5,5) sage: d1 = g.shortest_path_lengths((0,0), algorithm="BFS") - sage: d2 = g.shortest_path_lengths((0,0), algorithm="Dijkstra_NetworkX") + sage: d2 = g.shortest_path_lengths((0,0), algorithm="Dijkstra_NetworkX") # optional - networkx sage: d3 = g.shortest_path_lengths((0,0), algorithm="Dijkstra_Boost") sage: d4 = g.shortest_path_lengths((0,0), algorithm="Bellman-Ford_Boost") sage: d1 == d2 == d3 == d4 @@ -18599,7 +18646,8 @@ def to_simple(self, to_undirected=True, keep_label='any', immutable=None): EXAMPLES:: sage: G = DiGraph(loops=True, multiedges=True, sparse=True) - sage: G.add_edges([(0, 0, None), (1, 1, None), (2, 2, None), (2, 3, 1), (2, 3, 2), (3, 2, None)]) + sage: G.add_edges([(0, 0, None), (1, 1, None), (2, 2, None), + ....: (2, 3, 1), (2, 3, 2), (3, 2, None)]) sage: G.edges(sort=True, labels=False) [(0, 0), (1, 1), (2, 2), (2, 3), (2, 3), (3, 2)] sage: H = G.to_simple() @@ -18845,9 +18893,9 @@ def cartesian_product(self, other): Cartesian product of digraphs:: sage: P = DiGraph([(0, 1)]) - sage: B = digraphs.DeBruijn(['a', 'b'], 2) - sage: Q = P.cartesian_product(B) - sage: Q.edges(sort=True, labels=None) + sage: B = digraphs.DeBruijn(['a', 'b'], 2) # optional - sage.combinat + sage: Q = P.cartesian_product(B) # optional - sage.combinat + sage: Q.edges(sort=True, labels=None) # optional - sage.combinat [((0, 'aa'), (0, 'aa')), ((0, 'aa'), (0, 'ab')), ((0, 'aa'), (1, 'aa')), ((0, 'ab'), (0, 'ba')), ((0, 'ab'), (0, 'bb')), ((0, 'ab'), (1, 'ab')), @@ -18858,10 +18906,10 @@ def cartesian_product(self, other): ((1, 'ab'), (1, 'ba')), ((1, 'ab'), (1, 'bb')), ((1, 'ba'), (1, 'aa')), ((1, 'ba'), (1, 'ab')), ((1, 'bb'), (1, 'ba')), ((1, 'bb'), (1, 'bb'))] - sage: Q.strongly_connected_components_digraph().num_verts() + sage: Q.strongly_connected_components_digraph().num_verts() # optional - sage.combinat 2 - sage: V = Q.strongly_connected_component_containing_vertex((0, 'aa')) - sage: B.is_isomorphic(Q.subgraph(V)) + sage: V = Q.strongly_connected_component_containing_vertex((0, 'aa')) # optional - sage.combinat + sage: B.is_isomorphic(Q.subgraph(V)) # optional - sage.combinat True """ self._scream_if_not_simple(allow_loops=True) @@ -19096,13 +19144,13 @@ def strong_product(self, other): Counting the edges (see :trac:`13699`):: - sage: g = graphs.RandomGNP(5, .5) - sage: gn,gm = g.order(), g.size() - sage: h = graphs.RandomGNP(5, .5) - sage: hn,hm = h.order(), h.size() - sage: product_size = g.strong_product(h).size() - sage: expected = gm * hn + hm * gn + 2 * gm * hm - sage: product_size == expected + sage: g = graphs.RandomGNP(5, .5) # optional - networkx + sage: gn,gm = g.order(), g.size() # optional - networkx + sage: h = graphs.RandomGNP(5, .5) # optional - networkx + sage: hn,hm = h.order(), h.size() # optional - networkx + sage: product_size = g.strong_product(h).size() # optional - networkx + sage: expected = gm * hn + hm * gn + 2 * gm * hm # optional - networkx + sage: product_size == expected # optional - networkx True """ self._scream_if_not_simple(allow_loops=True) @@ -19396,33 +19444,35 @@ def _color_by_label(self, format='hex', as_function=False, default_color="black" We consider the Cayley graph of the symmetric group, whose edges are labelled by the numbers 1,2, and 3:: - sage: G = SymmetricGroup(4).cayley_graph() # optional - sage.groups - sage: set(G.edge_labels()) # optional - sage.groups + sage: G = SymmetricGroup(4).cayley_graph() # optional - sage.groups + sage: set(G.edge_labels()) # optional - sage.groups {1, 2, 3} We first request the coloring as a function:: - sage: f = G._color_by_label(as_function=True) # optional - sage.groups - sage: [f(1), f(2), f(3)] # optional - sage.groups + sage: f = G._color_by_label(as_function=True) # optional - sage.groups + sage: [f(1), f(2), f(3)] # optional - sage.groups ['#0000ff', '#ff0000', '#00ff00'] - sage: f = G._color_by_label({1: "blue", 2: "red", 3: "green"}, as_function=True) # optional - sage.groups - sage: [f(1), f(2), f(3)] # optional - sage.groups + sage: f = G._color_by_label({1: "blue", 2: "red", 3: "green"}, # optional - sage.groups + ....: as_function=True) + sage: [f(1), f(2), f(3)] # optional - sage.groups ['blue', 'red', 'green'] - sage: f = G._color_by_label({1: "red"}, as_function=True) # optional - sage.groups - sage: [f(1), f(2), f(3)] # optional - sage.groups + sage: f = G._color_by_label({1: "red"}, as_function=True) # optional - sage.groups + sage: [f(1), f(2), f(3)] # optional - sage.groups ['red', 'black', 'black'] - sage: f = G._color_by_label({1: "red"}, as_function=True, default_color='blue') # optional - sage.groups - sage: [f(1), f(2), f(3)] # optional - sage.groups + sage: f = G._color_by_label({1: "red"}, as_function=True, # optional - sage.groups + ....: default_color='blue') + sage: [f(1), f(2), f(3)] # optional - sage.groups ['red', 'blue', 'blue'] The default output is a dictionary assigning edges to colors:: - sage: G._color_by_label() # optional - sage.groups + sage: G._color_by_label() # optional - sage.groups {'#0000ff': [((), (1,2), 1), ...], '#00ff00': [((), (3,4), 3), ...], '#ff0000': [((), (2,3), 2), ...]} - sage: G._color_by_label({1: "blue", 2: "red", 3: "green"}) # optional - sage.groups + sage: G._color_by_label({1: "blue", 2: "red", 3: "green"}) # optional - sage.groups {'blue': [((), (1,2), 1), ...], 'green': [((), (3,4), 3), ...], 'red': [((), (2,3), 2), ...]} @@ -19431,12 +19481,12 @@ def _color_by_label(self, format='hex', as_function=False, default_color="black" We check what happens when several labels have the same color:: - sage: result = G._color_by_label({1: "blue", 2: "blue", 3: "green"}) # optional - sage.groups - sage: sorted(result) # optional - sage.groups + sage: result = G._color_by_label({1: "blue", 2: "blue", 3: "green"}) # optional - sage.groups + sage: sorted(result) # optional - sage.groups ['blue', 'green'] - sage: len(result['blue']) # optional - sage.groups + sage: len(result['blue']) # optional - sage.groups 48 - sage: len(result['green']) # optional - sage.groups + sage: len(result['green']) # optional - sage.groups 24 """ if format is True: @@ -19490,8 +19540,8 @@ def latex_options(self): sage: opts = g.latex_options() sage: opts LaTeX options for Petersen graph: {} - sage: opts.set_option('tkz_style', 'Classic') - sage: opts + sage: opts.set_option('tkz_style', 'Classic') # optional - sage.plot + sage: opts # optional - sage.plot LaTeX options for Petersen graph: {'tkz_style': 'Classic'} """ if self._latex_opts is None: @@ -19519,9 +19569,9 @@ def set_latex_options(self, **kwds): EXAMPLES:: sage: g = graphs.PetersenGraph() - sage: g.set_latex_options(tkz_style='Welsh') - sage: opts = g.latex_options() - sage: opts.get_option('tkz_style') + sage: g.set_latex_options(tkz_style='Welsh') # optional - sage.plot + sage: opts = g.latex_options() # optional - sage.plot + sage: opts.get_option('tkz_style') # optional - sage.plot 'Welsh' """ opts = self.latex_options() @@ -19890,9 +19940,10 @@ def layout_forest(self, tree_orientation="down", forest_roots=None, sage: G.plot(pos=p) # random # optional - sage.plot Graphics object consisting of 28 graphics primitives - sage: H = graphs.PathGraph(5) + graphs.PathGraph(5) + graphs.BalancedTree(2,2) - sage: p = H.layout_forest(forest_roots=[14,3]) - sage: H.plot(pos=p) # optional - sage.plot + sage: P5 = graphs.PathGraph(5) + sage: H = P5 + P5 + graphs.BalancedTree(2,2) # optional - networkx + sage: p = H.layout_forest(forest_roots=[14,3]) # optional - networkx + sage: H.plot(pos=p) # optional - networkx sage.plot Graphics object consisting of 32 graphics primitives TESTS:: @@ -19962,16 +20013,16 @@ def layout_tree(self, tree_orientation="down", tree_root=None, sage: G.plot(layout="tree", tree_orientation="right") # optional - sage.plot Graphics object consisting of 160 graphics primitives - sage: T = graphs.RandomLobster(25, 0.3, 0.3) - sage: T.show(layout='tree', tree_orientation='up') # optional - sage.plot + sage: T = graphs.RandomLobster(25, 0.3, 0.3) # optional - networkx + sage: T.show(layout='tree', tree_orientation='up') # optional - networkx sage.plot sage: G = graphs.HoffmanSingletonGraph() sage: T = Graph() sage: T.add_edges(G.min_spanning_tree(starting_vertex=0)) sage: T.show(layout='tree', tree_root=0) # optional - sage.plot - sage: G = graphs.BalancedTree(2, 2) - sage: G.layout_tree(tree_root=0) + sage: G = graphs.BalancedTree(2, 2) # optional - networkx + sage: G.layout_tree(tree_root=0) # optional - networkx {0: [1.5, 0], 1: [2.5, -1], 2: [0.5, -1], @@ -19980,8 +20031,8 @@ def layout_tree(self, tree_orientation="down", tree_root=None, 5: [1.0, -2], 6: [0.0, -2]} - sage: G = graphs.BalancedTree(2, 4) - sage: G.plot(layout="tree", tree_root=0, tree_orientation="up") # optional - sage.plot + sage: G = graphs.BalancedTree(2, 4) # optional - networkx + sage: G.plot(layout="tree", tree_root=0, tree_orientation="up") # optional - networkx sage.plot Graphics object consisting of 62 graphics primitives Using the embedding when it exists:: @@ -20004,8 +20055,8 @@ def layout_tree(self, tree_orientation="down", tree_root=None, TESTS:: - sage: G = graphs.BalancedTree(2, 2) - sage: G.layout_tree(tree_root=0, tree_orientation='left') + sage: G = graphs.BalancedTree(2, 2) # optional - networkx + sage: G.layout_tree(tree_root=0, tree_orientation='left') # optional - networkx {0: [0, 1.5], 1: [-1, 2.5], 2: [-1, 0.5], @@ -20187,8 +20238,8 @@ def layout_graphviz(self, dim=2, prog='dot', **options): Graphics object consisting of 29 graphics primitives sage: g.plot(layout="graphviz", prog="fdp") # optional - dot2tex graphviz Graphics object consisting of 29 graphics primitives - sage: g = graphs.BalancedTree(5,2) - sage: g.plot(layout="graphviz", prog="circo") # optional - dot2tex graphviz + sage: g = graphs.BalancedTree(5,2) # optional - networkx + sage: g.plot(layout="graphviz", prog="circo") # optional - dot2tex graphviz networkx Graphics object consisting of 62 graphics primitives .. TODO:: @@ -20500,7 +20551,7 @@ def _rich_repr_(self, display_manager, **kwds): sage: dm.preferences.supplemental_plot 'never' sage: del dm.preferences.supplemental_plot - sage: graphs.RandomGNP(20,0.0) + sage: graphs.RandomGNP(20,0.0) # optional - networkx RandomGNP(20,0.000000000000000): Graph on 20 vertices (use the .plot() method to plot) sage: dm.preferences.supplemental_plot = 'never' """ @@ -20960,10 +21011,10 @@ def plot3d(self, bgcolor=(1, 1, 1), We plot a fairly complicated Cayley graph:: - sage: A5 = AlternatingGroup(5); A5 + sage: A5 = AlternatingGroup(5); A5 # optional - sage.groups Alternating group of order 5!/2 as a permutation group - sage: G = A5.cayley_graph() - sage: G.plot3d(vertex_size=0.03, edge_size=0.01, # long time, optional - sage.plot + sage: G = A5.cayley_graph() # optional - sage.groups + sage: G.plot3d(vertex_size=0.03, edge_size=0.01, # long time, optional - sage.groups sage.plot ....: vertex_colors={(1,1,1): list(G)}, bgcolor=(0,0,0), ....: color_by_label=True, iterations=200) Graphics3d Object @@ -21217,10 +21268,10 @@ def show3d(self, bgcolor=(1, 1, 1), vertex_colors=None, vertex_size=0.06, We plot a fairly complicated Cayley graph:: - sage: A5 = AlternatingGroup(5); A5 + sage: A5 = AlternatingGroup(5); A5 # optional - sage.groups Alternating group of order 5!/2 as a permutation group - sage: G = A5.cayley_graph() - sage: G.show3d(vertex_size=0.03, # long time, optional - sage.plot + sage: G = A5.cayley_graph() # optional - sage.groups + sage: G.show3d(vertex_size=0.03, # long time, optional - sage.groups sage.plot ....: edge_size=0.01, edge_size2=0.02, ....: vertex_colors={(1,1,1): list(G)}, bgcolor=(0,0,0), ....: color_by_label=True, iterations=200) @@ -21686,12 +21737,12 @@ def graphviz_string(self, **options): The following digraph has vertices with newlines in their string representations:: - sage: m1 = matrix(3, 3) - sage: m2 = matrix(3, 3, 1) - sage: m1.set_immutable() - sage: m2.set_immutable() - sage: g = DiGraph({m1: [m2]}) - sage: print(g.graphviz_string()) + sage: m1 = matrix(3, 3) # optional - sage.modules + sage: m2 = matrix(3, 3, 1) # optional - sage.modules + sage: m1.set_immutable() # optional - sage.modules + sage: m2.set_immutable() # optional - sage.modules + sage: g = DiGraph({m1: [m2]}) # optional - sage.modules + sage: print(g.graphviz_string()) # optional - sage.modules digraph { node_0 [label="[0 0 0]\n\ [0 0 0]\n\ @@ -22002,26 +22053,26 @@ def spectrum(self, laplacian=False): EXAMPLES:: sage: P = graphs.PetersenGraph() - sage: P.spectrum() + sage: P.spectrum() # optional - sage.modules [3, 1, 1, 1, 1, 1, -2, -2, -2, -2] - sage: P.spectrum(laplacian=True) + sage: P.spectrum(laplacian=True) # optional - sage.modules [5, 5, 5, 5, 2, 2, 2, 2, 2, 0] sage: D = P.to_directed() sage: D.delete_edge(7, 9) - sage: D.spectrum() + sage: D.spectrum() # optional - sage.modules [2.9032119259..., 1, 1, 1, 1, 0.8060634335..., -1.7092753594..., -2, -2, -2] :: sage: C = graphs.CycleGraph(8) - sage: C.spectrum() + sage: C.spectrum() # optional - sage.modules [2, 1.4142135623..., 1.4142135623..., 0, 0, -1.4142135623..., -1.4142135623..., -2] A digraph may have complex eigenvalues. Previously, the complex parts of graph eigenvalues were being dropped. For a 3-cycle, we have:: sage: T = DiGraph({0: [1], 1: [2], 2: [0]}) - sage: T.spectrum() + sage: T.spectrum() # optional - sage.modules [1, -0.5000000000... + 0.8660254037...*I, -0.5000000000... - 0.8660254037...*I] TESTS: @@ -22035,10 +22086,10 @@ def spectrum(self, laplacian=False): eigenvalues. :: sage: H = graphs.HoffmanSingletonGraph() - sage: evals = H.spectrum() - sage: lap = [7 - x for x in evals] - sage: lap.sort(reverse=True) - sage: lap == H.spectrum(laplacian=True) + sage: evals = H.spectrum() # optional - sage.modules + sage: lap = [7 - x for x in evals] # optional - sage.modules + sage: lap.sort(reverse=True) # optional - sage.modules + sage: lap == H.spectrum(laplacian=True) # optional - sage.modules True """ # Ideally the spectrum should return something like a Factorization object @@ -22084,11 +22135,11 @@ def characteristic_polynomial(self, var='x', laplacian=False): EXAMPLES:: sage: P = graphs.PetersenGraph() - sage: P.characteristic_polynomial() + sage: P.characteristic_polynomial() # optional - sage.modules x^10 - 15*x^8 + 75*x^6 - 24*x^5 - 165*x^4 + 120*x^3 + 120*x^2 - 160*x + 48 - sage: P.charpoly() + sage: P.charpoly() # optional - sage.modules x^10 - 15*x^8 + 75*x^6 - 24*x^5 - 165*x^4 + 120*x^3 + 120*x^2 - 160*x + 48 - sage: P.characteristic_polynomial(laplacian=True) + sage: P.characteristic_polynomial(laplacian=True) # optional - sage.modules x^10 - 30*x^9 + 390*x^8 - 2880*x^7 + 13305*x^6 - 39882*x^5 + 77640*x^4 - 94800*x^3 + 66000*x^2 - 20000*x """ @@ -22124,7 +22175,7 @@ def eigenvectors(self, laplacian=False): EXAMPLES:: sage: P = graphs.PetersenGraph() - sage: P.eigenvectors() + sage: P.eigenvectors() # optional - sage.modules [(3, [ (1, 1, 1, 1, 1, 1, 1, 1, 1, 1) ], 1), (-2, [ @@ -22144,7 +22195,7 @@ def eigenvectors(self, laplacian=False): graph is regular. However, since the output also contains the eigenvalues, the two outputs are slightly different:: - sage: P.eigenvectors(laplacian=True) + sage: P.eigenvectors(laplacian=True) # optional - sage.modules [(0, [ (1, 1, 1, 1, 1, 1, 1, 1, 1, 1) ], 1), (5, [ @@ -22163,7 +22214,7 @@ def eigenvectors(self, laplacian=False): :: sage: C = graphs.CycleGraph(8) - sage: C.eigenvectors() + sage: C.eigenvectors() # optional - sage.modules [(2, [ (1, 1, 1, 1, 1, 1, 1, 1) @@ -22193,7 +22244,7 @@ def eigenvectors(self, laplacian=False): graph eigenvalues were being dropped. For a 3-cycle, we have:: sage: T = DiGraph({0:[1], 1:[2], 2:[0]}) - sage: T.eigenvectors() + sage: T.eigenvectors() # optional - sage.modules [(1, [ (1, 1, 1) @@ -22234,7 +22285,7 @@ def eigenspaces(self, laplacian=False): EXAMPLES:: sage: P = graphs.PetersenGraph() - sage: P.eigenspaces() + sage: P.eigenspaces() # optional - sage.modules [ (3, Vector space of degree 10 and dimension 1 over Rational Field User basis matrix: @@ -22258,7 +22309,7 @@ def eigenspaces(self, laplacian=False): graph is regular. However, since the output also contains the eigenvalues, the two outputs are slightly different:: - sage: P.eigenspaces(laplacian=True) + sage: P.eigenspaces(laplacian=True) # optional - sage.modules [ (0, Vector space of degree 10 and dimension 1 over Rational Field User basis matrix: @@ -22283,7 +22334,7 @@ def eigenspaces(self, laplacian=False): corresponding eigenspace:: sage: C = graphs.CycleGraph(8) - sage: C.eigenspaces() + sage: C.eigenspaces() # optional - sage.modules [ (2, Vector space of degree 8 and dimension 1 over Rational Field User basis matrix: @@ -22306,7 +22357,7 @@ def eigenspaces(self, laplacian=False): we have:: sage: T = DiGraph({0: [1], 1: [2], 2: [0]}) - sage: T.eigenspaces() + sage: T.eigenspaces() # optional - sage.modules [ (1, Vector space of degree 3 and dimension 1 over Rational Field User basis matrix: @@ -22384,7 +22435,7 @@ def relabel(self, perm=None, inplace=True, return_map=False, check_input=True, c EXAMPLES:: sage: G = graphs.PathGraph(3) - sage: G.am() + sage: G.am() # optional - sage.modules [0 1 0] [1 0 1] [0 1 0] @@ -22392,7 +22443,7 @@ def relabel(self, perm=None, inplace=True, return_map=False, check_input=True, c Relabeling using a dictionary. Note that the dictionary does not define the new label of vertex `0`:: - sage: G.relabel({1:2,2:1}, inplace=False).am() + sage: G.relabel({1:2,2:1}, inplace=False).am() # optional - sage.modules [0 0 1] [0 0 1] [1 1 0] @@ -22402,21 +22453,22 @@ def relabel(self, perm=None, inplace=True, return_map=False, check_input=True, c vertices have an image can require some time, and this feature can be disabled (at your own risk):: - sage: G.relabel({1:2,2:1}, inplace=False, complete_partial_function=False).am() + sage: G.relabel({1:2,2:1}, inplace=False, # optional - sage.modules + ....: complete_partial_function=False).am() Traceback (most recent call last): ... KeyError: 0 Relabeling using a list:: - sage: G.relabel([0,2,1], inplace=False).am() + sage: G.relabel([0,2,1], inplace=False).am() # optional - sage.modules [0 0 1] [0 0 1] [1 1 0] Relabeling using an iterable:: - sage: G.relabel(iter((0,2,1)), inplace=False).am() + sage: G.relabel(iter((0,2,1)), inplace=False).am() # optional - sage.modules [0 0 1] [0 0 1] [1 1 0] @@ -22427,7 +22479,7 @@ def relabel(self, perm=None, inplace=True, return_map=False, check_input=True, c sage: from sage.groups.perm_gps.permgroup_named import SymmetricGroup # optional - sage.groups sage: S = SymmetricGroup(3) # optional - sage.groups sage: gamma = S('(1,2)') # optional - sage.groups - sage: G.relabel(gamma, inplace=False).am() # optional - sage.groups + sage: G.relabel(gamma, inplace=False).am() # optional - sage.groups sage.modules [0 0 1] [0 0 1] [1 1 0] @@ -22546,7 +22598,10 @@ def relabel(self, perm=None, inplace=True, return_map=False, check_input=True, c sage: G.relabel( [ i+1 for i in range(G.order()) ], inplace=True ) sage: G.relabel( [ i+1 for i in range(G.order()) ], inplace=True ) """ - from sage.groups.perm_gps.permgroup_element import PermutationGroupElement + try: + from sage.groups.perm_gps.permgroup_element import PermutationGroupElement + except ImportError: + PermutationGroupElement = () if not inplace: G = copy(self) @@ -22707,7 +22762,7 @@ def is_equitable(self, partition, quotient_matrix=False): False sage: G.is_equitable([[0,4],[1,3,5,9],[2,6,8,7]]) True - sage: G.is_equitable([[0,4],[1,3,5,9],[2,6,8,7]], quotient_matrix=True) + sage: G.is_equitable([[0,4],[1,3,5,9],[2,6,8,7]], quotient_matrix=True) # optional - sage.modules [1 2 0] [1 0 2] [0 2 1] @@ -23231,13 +23286,13 @@ def is_vertex_transitive(self, partition=None, verbosity=0, sage: G.is_vertex_transitive() False sage: P = graphs.PetersenGraph() - sage: P.is_vertex_transitive() + sage: P.is_vertex_transitive() # optional - sage.groups True sage: D = graphs.DodecahedralGraph() - sage: D.is_vertex_transitive() + sage: D.is_vertex_transitive() # optional - sage.groups True - sage: R = graphs.RandomGNP(2000, .01) - sage: R.is_vertex_transitive() + sage: R = graphs.RandomGNP(2000, .01) # optional - networkx + sage: R.is_vertex_transitive() # optional - networkx False """ if partition is None: @@ -23748,7 +23803,7 @@ class by some canonization function `c`. If `G` and `H` are graphs, sage: P = graphs.PetersenGraph() sage: DP = P.to_directed() - sage: DP.canonical_label(algorithm='sage').adjacency_matrix() + sage: DP.canonical_label(algorithm='sage').adjacency_matrix() # optional - sage.modules [0 0 0 0 0 0 0 1 1 1] [0 0 0 0 1 0 1 0 0 1] [0 0 0 1 0 0 1 0 1 0] @@ -23766,10 +23821,12 @@ class by some canonization function `c`. If `G` and `H` are graphs, sage: G.add_edges( [(0,1,'a'),(1,2,'b'),(2,3,'c'),(3,4,'b'),(4,0,'a')] ) sage: G.canonical_label(edge_labels=True) Graph on 5 vertices - sage: G.canonical_label(edge_labels=True, algorithm="bliss", certificate=True) # optional - bliss + sage: G.canonical_label(edge_labels=True, algorithm="bliss", # optional - bliss + ....: certificate=True) (Graph on 5 vertices, {0: 4, 1: 3, 2: 1, 3: 0, 4: 2}) - sage: G.canonical_label(edge_labels=True, algorithm="sage", certificate=True) + sage: G.canonical_label(edge_labels=True, algorithm="sage", + ....: certificate=True) (Graph on 5 vertices, {0: 4, 1: 3, 2: 0, 3: 1, 4: 2}) Another example where different canonization algorithms give @@ -23777,10 +23834,10 @@ class by some canonization function `c`. If `G` and `H` are graphs, sage: g = Graph({'a': ['b'], 'c': ['d']}) sage: g_sage = g.canonical_label(algorithm='sage') - sage: g_bliss = g.canonical_label(algorithm='bliss') # optional - bliss + sage: g_bliss = g.canonical_label(algorithm='bliss') # optional - bliss sage: g_sage.edges(sort=True, labels=False) [(0, 3), (1, 2)] - sage: g_bliss.edges(sort=True, labels=False) # optional - bliss + sage: g_bliss.edges(sort=True, labels=False) # optional - bliss [(0, 1), (2, 3)] TESTS:: @@ -23788,7 +23845,7 @@ class by some canonization function `c`. If `G` and `H` are graphs, sage: G = Graph([['a', 'b'], [('a', 'b')]]) sage: G.canonical_label(algorithm='sage', certificate=True) (Graph on 2 vertices, {'a': 0, 'b': 1}) - sage: G.canonical_label(algorithm='bliss', certificate=True) # optional - bliss + sage: G.canonical_label(algorithm='bliss', certificate=True) # optional - bliss (Graph on 2 vertices, {'a': 1, 'b': 0}) Check for immutable graphs (:trac:`16602`):: @@ -23970,15 +24027,15 @@ def is_cayley(self, return_group=False, mapping=False, A Petersen Graph is not a Cayley graph:: sage: g = graphs.PetersenGraph() - sage: g.is_cayley() + sage: g.is_cayley() # optional - sage.groups False A Cayley digraph is a Cayley graph:: - sage: C7 = groups.permutation.Cyclic(7) + sage: C7 = groups.permutation.Cyclic(7) # optional - sage.groups sage: S = [(1,2,3,4,5,6,7), (1,3,5,7,2,4,6), (1,5,2,6,3,7,4)] - sage: d = C7.cayley_graph(generators=S) - sage: d.is_cayley() + sage: d = C7.cayley_graph(generators=S) # optional - sage.groups + sage: d.is_cayley() # optional - sage.groups True Graphs with loops and multiedges will have identity and repeated @@ -24252,7 +24309,7 @@ def katz_matrix(self, alpha, nonedgesonly=False, vertices=None): We find the Katz matrix of an undirected 4-cycle. :: sage: G = graphs.CycleGraph(4) - sage: G.katz_matrix(1/20) + sage: G.katz_matrix(1/20) # optional - sage.modules [1/198 5/99 1/198 5/99] [ 5/99 1/198 5/99 1/198] [1/198 5/99 1/198 5/99] @@ -24261,7 +24318,7 @@ def katz_matrix(self, alpha, nonedgesonly=False, vertices=None): We find the Katz matrix of an undirected 4-cycle with all entries other than those which correspond to non-edges zeroed out. :: - sage: G.katz_matrix(1/20, True) + sage: G.katz_matrix(1/20, True) # optional - sage.modules [ 0 0 1/198 0] [ 0 0 0 1/198] [1/198 0 0 0] @@ -24273,7 +24330,7 @@ def katz_matrix(self, alpha, nonedgesonly=False, vertices=None): We find the Katz matrix in a fan on 6 vertices. :: sage: H = Graph([(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(1,2),(2,3),(3,4),(4,5)]) - sage: H.katz_matrix(1/10) + sage: H.katz_matrix(1/10) # optional - sage.modules [ 169/2256 545/4512 25/188 605/4512 25/188 545/4512 485/4512] [ 545/4512 7081/297792 4355/37224 229/9024 595/37224 4073/297792 109/9024] [ 25/188 4355/37224 172/4653 45/376 125/4653 595/37224 5/376] @@ -24289,22 +24346,22 @@ def katz_matrix(self, alpha, nonedgesonly=False, vertices=None): TESTS:: - sage: (graphs.CompleteGraph(4)).katz_matrix(1/4) + sage: (graphs.CompleteGraph(4)).katz_matrix(1/4) # optional - sage.modules [3/5 4/5 4/5 4/5] [4/5 3/5 4/5 4/5] [4/5 4/5 3/5 4/5] [4/5 4/5 4/5 3/5] - sage: (graphs.CompleteGraph(4)).katz_matrix(1/4, nonedgesonly=True) + sage: (graphs.CompleteGraph(4)).katz_matrix(1/4, nonedgesonly=True) # optional - sage.modules [0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0] - sage: (graphs.PathGraph(4)).katz_matrix(1/4, nonedgesonly=False) + sage: (graphs.PathGraph(4)).katz_matrix(1/4, nonedgesonly=False) # optional - sage.modules [15/209 60/209 16/209 4/209] [60/209 31/209 64/209 16/209] [16/209 64/209 31/209 60/209] [ 4/209 16/209 60/209 15/209] - sage: (graphs.PathGraph(4)).katz_matrix(1/4, nonedgesonly=True) + sage: (graphs.PathGraph(4)).katz_matrix(1/4, nonedgesonly=True) # optional - sage.modules [ 0 0 16/209 4/209] [ 0 0 0 16/209] [16/209 0 0 0] @@ -24369,7 +24426,7 @@ def katz_centrality(self, alpha, u=None): all 4 vertices have the same centrality) :: sage: G = graphs.CycleGraph(4) - sage: G.katz_centrality(1/20) + sage: G.katz_centrality(1/20) # optional - sage.modules {0: 1/9, 1: 1/9, 2: 1/9, 3: 1/9} Note that in the below example the nodes having indegree `0` also have @@ -24378,7 +24435,7 @@ def katz_centrality(self, alpha, u=None): sage: G = DiGraph({1: [10], 2:[10,11], 3:[10,11], 4:[], 5:[11, 4], 6:[11], ....: 7:[10,11], 8:[10,11], 9:[10], 10:[11, 5, 8], 11:[6]}) - sage: G.katz_centrality(.85) # rel tol 1e-14 + sage: G.katz_centrality(.85) # rel tol 1e-14 # optional - sage.modules {1: 0.000000000000000, 2: 0.000000000000000, 3: 0.000000000000000, @@ -24399,15 +24456,15 @@ def katz_centrality(self, alpha, u=None): TESTS:: - sage: graphs.PathGraph(3).katz_centrality(1/20) + sage: graphs.PathGraph(3).katz_centrality(1/20) # optional - sage.modules {0: 11/199, 1: 21/199, 2: 11/199} - sage: graphs.PathGraph(4).katz_centrality(1/20) + sage: graphs.PathGraph(4).katz_centrality(1/20) # optional - sage.modules {0: 21/379, 1: 41/379, 2: 41/379, 3: 21/379} - sage: graphs.PathGraph(3).katz_centrality(1/20,2) + sage: graphs.PathGraph(3).katz_centrality(1/20,2) # optional - sage.modules 11/199 - sage: graphs.PathGraph(4).katz_centrality(1/20,3) + sage: graphs.PathGraph(4).katz_centrality(1/20,3) # optional - sage.modules 21/379 - sage: (graphs.PathGraph(3) + graphs.PathGraph(4)).katz_centrality(1/20) + sage: (graphs.PathGraph(3) + graphs.PathGraph(4)).katz_centrality(1/20) # optional - sage.modules {0: 11/199, 1: 21/199, 2: 11/199, 3: 21/379, 4: 41/379, 5: 41/379, 6: 21/379} """ @@ -24458,29 +24515,29 @@ def edge_polytope(self, backend=None): The EP of a `4`-cycle is a square:: sage: G = graphs.CycleGraph(4) - sage: P = G.edge_polytope(); P + sage: P = G.edge_polytope(); P # optional - sage.geometry.polyhedron A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 4 vertices The EP of a complete graph on `4` vertices is cross polytope:: sage: G = graphs.CompleteGraph(4) - sage: P = G.edge_polytope(); P + sage: P = G.edge_polytope(); P # optional - sage.geometry.polyhedron A 3-dimensional polyhedron in ZZ^4 defined as the convex hull of 6 vertices - sage: P.is_combinatorially_isomorphic(polytopes.cross_polytope(3)) + sage: P.is_combinatorially_isomorphic(polytopes.cross_polytope(3)) # optional - sage.geometry.polyhedron True The EP of a graph is isomorphic to the subdirect sum of its connected components EPs:: sage: n = randint(3, 6) - sage: G1 = graphs.RandomGNP(n, 0.2) + sage: G1 = graphs.RandomGNP(n, 0.2) # optional - networkx sage: n = randint(3, 6) - sage: G2 = graphs.RandomGNP(n, 0.2) - sage: G = G1.disjoint_union(G2) - sage: P = G.edge_polytope() - sage: P1 = G1.edge_polytope() - sage: P2 = G2.edge_polytope() - sage: P.is_combinatorially_isomorphic(P1.subdirect_sum(P2)) + sage: G2 = graphs.RandomGNP(n, 0.2) # optional - networkx + sage: G = G1.disjoint_union(G2) # optional - networkx + sage: P = G.edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: P1 = G1.edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: P2 = G2.edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: P.is_combinatorially_isomorphic(P1.subdirect_sum(P2)) # optional - networkx sage.geometry.polyhedron True All trees on `n` vertices have isomorphic EPs:: @@ -24488,9 +24545,9 @@ def edge_polytope(self, backend=None): sage: n = randint(4, 10) sage: G1 = graphs.RandomTree(n) sage: G2 = graphs.RandomTree(n) - sage: P1 = G1.edge_polytope() - sage: P2 = G2.edge_polytope() - sage: P1.is_combinatorially_isomorphic(P2) + sage: P1 = G1.edge_polytope() # optional - sage.geometry.polyhedron + sage: P2 = G2.edge_polytope() # optional - sage.geometry.polyhedron + sage: P1.is_combinatorially_isomorphic(P2) # optional - sage.geometry.polyhedron True However, there are still many different EPs:: @@ -24498,14 +24555,14 @@ def edge_polytope(self, backend=None): sage: len(list(graphs(5))) 34 sage: polys = [] - sage: for G in graphs(5): + sage: for G in graphs(5): # optional - sage.geometry.polyhedron ....: P = G.edge_polytope() ....: for P1 in polys: ....: if P.is_combinatorially_isomorphic(P1): ....: break ....: else: ....: polys.append(P) - sage: len(polys) + sage: len(polys) # optional - sage.geometry.polyhedron 19 TESTS: @@ -24513,7 +24570,7 @@ def edge_polytope(self, backend=None): Obtain the EP with unsortable vertices:: sage: G = Graph([[1, (1, 2)]]) - sage: G.edge_polytope() + sage: G.edge_polytope() # optional - sage.geometry.polyhedron A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex """ from sage.matrix.special import identity_matrix @@ -24544,17 +24601,17 @@ def symmetric_edge_polytope(self, backend=None): The SEP of a `4`-cycle is a cube:: sage: G = graphs.CycleGraph(4) - sage: P = G.symmetric_edge_polytope(); P + sage: P = G.symmetric_edge_polytope(); P # optional - sage.geometry.polyhedron A 3-dimensional polyhedron in ZZ^4 defined as the convex hull of 8 vertices - sage: P.is_combinatorially_isomorphic(polytopes.cube()) + sage: P.is_combinatorially_isomorphic(polytopes.cube()) # optional - sage.geometry.polyhedron True The SEP of a complete graph on `4` vertices is a cuboctahedron:: sage: G = graphs.CompleteGraph(4) - sage: P = G.symmetric_edge_polytope(); P + sage: P = G.symmetric_edge_polytope(); P # optional - sage.geometry.polyhedron A 3-dimensional polyhedron in ZZ^4 defined as the convex hull of 12 vertices - sage: P.is_combinatorially_isomorphic(polytopes.cuboctahedron()) + sage: P.is_combinatorially_isomorphic(polytopes.cuboctahedron()) # optional - sage.geometry.polyhedron True The SEP of a graph with edges on `n` vertices has dimension `n` @@ -24562,26 +24619,26 @@ def symmetric_edge_polytope(self, backend=None): sage: n = randint(5, 12) sage: G = Graph() - sage: while not G.num_edges(): + sage: while not G.num_edges(): # optional - networkx ....: G = graphs.RandomGNP(n, 0.2) - sage: P = G.symmetric_edge_polytope() - sage: P.ambient_dim() == n + sage: P = G.symmetric_edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: P.ambient_dim() == n # optional - networkx sage.geometry.polyhedron True - sage: P.dim() == n - G.connected_components_number() + sage: P.dim() == n - G.connected_components_number() # optional - networkx sage.geometry.polyhedron True The SEP of a graph is isomorphic to the subdirect sum of its connected components SEP's:: sage: n = randint(3, 6) - sage: G1 = graphs.RandomGNP(n, 0.2) + sage: G1 = graphs.RandomGNP(n, 0.2) # optional - networkx sage: n = randint(3, 6) - sage: G2 = graphs.RandomGNP(n, 0.2) - sage: G = G1.disjoint_union(G2) - sage: P = G.symmetric_edge_polytope() - sage: P1 = G1.symmetric_edge_polytope() - sage: P2 = G2.symmetric_edge_polytope() - sage: P.is_combinatorially_isomorphic(P1.subdirect_sum(P2)) + sage: G2 = graphs.RandomGNP(n, 0.2) # optional - networkx + sage: G = G1.disjoint_union(G2) # optional - networkx + sage: P = G.symmetric_edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: P1 = G1.symmetric_edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: P2 = G2.symmetric_edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: P.is_combinatorially_isomorphic(P1.subdirect_sum(P2)) # optional - networkx sage.geometry.polyhedron True All trees on `n` vertices have isomorphic SEPs:: @@ -24589,9 +24646,9 @@ def symmetric_edge_polytope(self, backend=None): sage: n = randint(4, 10) sage: G1 = graphs.RandomTree(n) sage: G2 = graphs.RandomTree(n) - sage: P1 = G1.symmetric_edge_polytope() - sage: P2 = G2.symmetric_edge_polytope() - sage: P1.is_combinatorially_isomorphic(P2) + sage: P1 = G1.symmetric_edge_polytope() # optional - sage.geometry.polyhedron + sage: P2 = G2.symmetric_edge_polytope() # optional - sage.geometry.polyhedron + sage: P1.is_combinatorially_isomorphic(P2) # optional - sage.geometry.polyhedron True However, there are still many different SEPs:: @@ -24599,7 +24656,7 @@ def symmetric_edge_polytope(self, backend=None): sage: len(list(graphs(5))) 34 sage: polys = [] - sage: for G in graphs(5): + sage: for G in graphs(5): # optional - sage.geometry.polyhedron ....: P = G.symmetric_edge_polytope() ....: for P1 in polys: ....: if P.is_combinatorially_isomorphic(P1): @@ -24618,24 +24675,24 @@ def symmetric_edge_polytope(self, backend=None): sage: G2.add_edges([[0, 7], [7, 3]]) sage: G1.is_isomorphic(G2) False - sage: P1 = G1.symmetric_edge_polytope() - sage: P2 = G2.symmetric_edge_polytope() - sage: P1.is_combinatorially_isomorphic(P2) + sage: P1 = G1.symmetric_edge_polytope() # optional - sage.geometry.polyhedron + sage: P2 = G2.symmetric_edge_polytope() # optional - sage.geometry.polyhedron + sage: P1.is_combinatorially_isomorphic(P2) # optional - sage.geometry.polyhedron True Apparently, glueing two graphs together on a vertex gives isomorphic SEPs:: sage: n = randint(3, 7) - sage: g1 = graphs.RandomGNP(n, 0.2) - sage: g2 = graphs.RandomGNP(n, 0.2) - sage: G = g1.disjoint_union(g2) - sage: H = copy(G) - sage: G.merge_vertices(((0, randrange(n)), (1, randrange(n)))) - sage: H.merge_vertices(((0, randrange(n)), (1, randrange(n)))) - sage: PG = G.symmetric_edge_polytope() - sage: PH = H.symmetric_edge_polytope() - sage: PG.is_combinatorially_isomorphic(PH) + sage: g1 = graphs.RandomGNP(n, 0.2) # optional - networkx + sage: g2 = graphs.RandomGNP(n, 0.2) # optional - networkx + sage: G = g1.disjoint_union(g2) # optional - networkx + sage: H = copy(G) # optional - networkx + sage: G.merge_vertices(((0, randrange(n)), (1, randrange(n)))) # optional - networkx + sage: H.merge_vertices(((0, randrange(n)), (1, randrange(n)))) # optional - networkx + sage: PG = G.symmetric_edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: PH = H.symmetric_edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: PG.is_combinatorially_isomorphic(PH) # optional - networkx sage.geometry.polyhedron True TESTS: @@ -24643,7 +24700,7 @@ def symmetric_edge_polytope(self, backend=None): Obtain the SEP with unsortable vertices:: sage: G = Graph([[1, (1, 2)]]) - sage: G.symmetric_edge_polytope() + sage: G.symmetric_edge_polytope() # optional - sage.geometry.polyhedron A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices """ from itertools import chain diff --git a/src/sage/graphs/generic_graph_pyx.pyx b/src/sage/graphs/generic_graph_pyx.pyx index 712c2d955f0..520ea4283e2 100644 --- a/src/sage/graphs/generic_graph_pyx.pyx +++ b/src/sage/graphs/generic_graph_pyx.pyx @@ -650,7 +650,7 @@ cdef class SubgraphSearch: EXAMPLES:: sage: g = graphs.PetersenGraph() - sage: g.subgraph_search(graphs.CycleGraph(5)) + sage: g.subgraph_search(graphs.CycleGraph(5)) # optional - sage.modules Subgraph of (Petersen graph): Graph on 5 vertices TESTS: @@ -660,11 +660,11 @@ cdef class SubgraphSearch: computations with it:: sage: from sage.graphs.generic_graph_pyx import SubgraphSearch - sage: SubgraphSearch(Graph(5), Graph(1)) + sage: SubgraphSearch(Graph(5), Graph(1)) # optional - sage.modules Traceback (most recent call last): ... ValueError: Searched graph should have at least 2 vertices. - sage: SubgraphSearch(Graph(5), Graph(2)) + sage: SubgraphSearch(Graph(5), Graph(2)) # optional - sage.modules """ if H.order() <= 1: @@ -690,8 +690,8 @@ cdef class SubgraphSearch: sage: from sage.graphs.generic_graph_pyx import SubgraphSearch sage: g = graphs.PathGraph(5) sage: h = graphs.PathGraph(3) - sage: S = SubgraphSearch(g, h) - sage: for p in S: + sage: S = SubgraphSearch(g, h) # optional - sage.modules + sage: for p in S: # optional - sage.modules ....: print(p) [0, 1, 2] [1, 2, 3] @@ -721,8 +721,8 @@ cdef class SubgraphSearch: sage: from sage.graphs.generic_graph_pyx import SubgraphSearch sage: g = graphs.PathGraph(5) sage: h = graphs.PathGraph(3) - sage: S = SubgraphSearch(g, h) - sage: S.cardinality() + sage: S = SubgraphSearch(g, h) # optional - sage.modules + sage: S.cardinality() # optional - sage.modules 6 """ if self.nh > self.ng: @@ -756,18 +756,18 @@ cdef class SubgraphSearch: sage: from sage.graphs.generic_graph_pyx import SubgraphSearch sage: g = graphs.PathGraph(5) sage: h = graphs.PathGraph(3) - sage: S = SubgraphSearch(g, h) - sage: S.__next__() + sage: S = SubgraphSearch(g, h) # optional - sage.modules + sage: S.__next__() # optional - sage.modules [0, 1, 2] - sage: S._initialization() - sage: S.__next__() + sage: S._initialization() # optional - sage.modules + sage: S.__next__() # optional - sage.modules [0, 1, 2] TESTS: Check that :trac:`21828` is fixed:: - sage: Poset().is_incomparable_chain_free(1,1) # indirect doctest + sage: Poset().is_incomparable_chain_free(1,1) # indirect doctest # optional - sage.modules True """ cdef int i @@ -802,7 +802,7 @@ cdef class SubgraphSearch: EXAMPLES:: sage: g = graphs.PetersenGraph() - sage: g.subgraph_search(graphs.CycleGraph(5)) + sage: g.subgraph_search(graphs.CycleGraph(5)) # optional - sage.modules Subgraph of (Petersen graph): Graph on 5 vertices """ self.mem = MemoryAllocator() @@ -883,8 +883,8 @@ cdef class SubgraphSearch: sage: from sage.graphs.generic_graph_pyx import SubgraphSearch sage: g = graphs.PathGraph(5) sage: h = graphs.PathGraph(3) - sage: S = SubgraphSearch(g, h) - sage: S.__next__() + sage: S = SubgraphSearch(g, h) # optional - sage.modules + sage: S.__next__() # optional - sage.modules [0, 1, 2] """ if not self.ng: diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index b351b8501c0..a83da34a230 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -424,7 +424,7 @@ from sage.graphs.views import EdgesView from sage.parallel.decorate import parallel -from sage.misc.lazy_import import lazy_import +from sage.misc.lazy_import import lazy_import, LazyImport from sage.features import PythonModule lazy_import('sage.graphs.mcqd', ['mcqd'], feature=PythonModule('sage.graphs.mcqd', spkg='mcqd')) @@ -10022,7 +10022,7 @@ def bipartite_double(self, extended=False): # Aliases to functions defined in other modules from sage.graphs.weakly_chordal import is_long_hole_free, is_long_antihole_free, is_weakly_chordal from sage.graphs.asteroidal_triples import is_asteroidal_triple_free - from sage.graphs.chrompoly import chromatic_polynomial + chromatic_polynomial = LazyImport('sage.graphs.chrompoly', 'chromatic_polynomial', at_startup=True) from sage.graphs.graph_decompositions.rankwidth import rank_decomposition from sage.graphs.graph_decompositions.tree_decomposition import treewidth from sage.graphs.graph_decompositions.vertex_separation import pathwidth @@ -10030,7 +10030,7 @@ def bipartite_double(self, extended=False): from sage.graphs.graph_decompositions.clique_separators import atoms_and_clique_separators from sage.graphs.graph_decompositions.bandwidth import bandwidth from sage.graphs.graph_decompositions.cutwidth import cutwidth - from sage.graphs.matchpoly import matching_polynomial + matching_polynomial = LazyImport('sage.graphs.matchpoly', 'matching_polynomial', at_startup=True) from sage.graphs.cliquer import all_max_clique as cliques_maximum from sage.graphs.cliquer import all_cliques from sage.graphs.spanning_tree import random_spanning_tree @@ -10047,7 +10047,7 @@ def bipartite_double(self, extended=False): from sage.graphs.connectivity import is_triconnected from sage.graphs.comparability import is_comparability from sage.graphs.comparability import is_permutation - from sage.graphs.convexity_properties import geodetic_closure + geodetic_closure = LazyImport('sage.graphs.convexity_properties', 'geodetic_closure', at_startup=True) from sage.graphs.domination import is_dominating from sage.graphs.domination import is_redundant from sage.graphs.domination import private_neighbors diff --git a/src/sage/graphs/graph_coloring.pyx b/src/sage/graphs/graph_coloring.pyx index 844969f8b94..f04f1e382e8 100644 --- a/src/sage/graphs/graph_coloring.pyx +++ b/src/sage/graphs/graph_coloring.pyx @@ -65,13 +65,14 @@ Methods # **************************************************************************** from copy import copy -from sage.combinat.matrices.dlxcpp import DLXCPP from libcpp.vector cimport vector from libcpp.pair cimport pair -from sage.numerical.mip import MixedIntegerLinearProgram -from sage.numerical.mip import MIPSolverException from sage.graphs.independent_sets import IndependentSets +from sage.misc.lazy_import import LazyImport + +DLXCPP = LazyImport('sage.combinat.matrices.dlxcpp', 'DLXCPP') +MixedIntegerLinearProgram = LazyImport('sage.numerical.mip', 'MixedIntegerLinearProgram') def all_graph_colorings(G, n, count_only=False, hex_colors=False, vertex_color_dict=False): @@ -643,6 +644,7 @@ def vertex_coloring(g, k=None, value_only=False, hex_colors=False, solver=None, # it, and it can help. p.add_constraint(color[next(g.vertex_iterator()), 0], max=1, min=1) + from sage.numerical.mip import MIPSolverException try: if value_only: p.solve(objective_only=True, log=verbose) @@ -1038,6 +1040,7 @@ def grundy_coloring(g, k, value_only=True, solver=None, verbose=0, # Trying to use as many colors as possible p.set_objective(p.sum(is_used[i] for i in range(k))) + from sage.numerical.mip import MIPSolverException try: p.solve(log=verbose) except MIPSolverException: @@ -1227,6 +1230,7 @@ def b_coloring(g, k, value_only=True, solver=None, verbose=0, # We want to maximize the number of used colors p.set_objective(p.sum(is_used[i] for i in range(k))) + from sage.numerical.mip import MIPSolverException try: p.solve(log=verbose) except MIPSolverException: @@ -1458,6 +1462,8 @@ def edge_coloring(g, value_only=False, vizing=False, hex_colors=False, solver=No # We color the edges of the vertex of maximum degree for i, v in enumerate(h.neighbor_iterator(X)): p.add_constraint(color[frozenset((v, X)), i] == 1) + + from sage.numerical.mip import MIPSolverException try: p.solve(objective_only=value_only, log=verbose) except MIPSolverException: @@ -1885,6 +1891,7 @@ def linear_arboricity(g, plus_one=None, hex_colors=False, value_only=False, # no cycles p.add_constraint(p.sum(r[i, (u, v)] for v in g.neighbor_iterator(u)), max=MAD) + from sage.numerical.mip import MIPSolverException try: p.solve(objective_only=value_only, log=verbose) if value_only: @@ -2139,6 +2146,7 @@ def acyclic_edge_coloring(g, hex_colors=False, value_only=False, k=0, p.set_objective(None) + from sage.numerical.mip import MIPSolverException try: p.solve(objective_only=value_only, log=verbose) if value_only: @@ -2181,9 +2189,9 @@ def acyclic_edge_coloring(g, hex_colors=False, value_only=False, k=0, cdef class Test: r""" - This class performs randomized testing for all_graph_colorings. + This class performs randomized testing for :func:`all_graph_colorings`. - Since everything else in this file is derived from all_graph_colorings, this + Since everything else in this file is derived from :func:`all_graph_colorings`, this is a pretty good randomized tester for the entire file. Note that for a graph `G`, ``G.chromatic_polynomial()`` uses an entirely different algorithm, so we provide a good, independent test. diff --git a/src/sage/graphs/graph_decompositions/bandwidth.pyx b/src/sage/graphs/graph_decompositions/bandwidth.pyx index 874787d4713..d72c6e5ff80 100644 --- a/src/sage/graphs/graph_decompositions/bandwidth.pyx +++ b/src/sage/graphs/graph_decompositions/bandwidth.pyx @@ -160,7 +160,7 @@ def bandwidth(G, k=None): False sage: bandwidth(G) (5, [0, 4, 5, 8, 1, 9, 3, 7, 6, 2]) - sage: G.adjacency_matrix(vertices=[0, 4, 5, 8, 1, 9, 3, 7, 6, 2]) + sage: G.adjacency_matrix(vertices=[0, 4, 5, 8, 1, 9, 3, 7, 6, 2]) # optional - sage.modules [0 1 1 0 1 0 0 0 0 0] [1 0 0 0 0 1 1 0 0 0] [1 0 0 1 0 0 0 1 0 0] @@ -174,7 +174,7 @@ def bandwidth(G, k=None): sage: G = graphs.ChvatalGraph() sage: bandwidth(G) (6, [0, 5, 9, 4, 10, 1, 6, 11, 3, 8, 7, 2]) - sage: G.adjacency_matrix(vertices=[0, 5, 9, 4, 10, 1, 6, 11, 3, 8, 7, 2]) + sage: G.adjacency_matrix(vertices=[0, 5, 9, 4, 10, 1, 6, 11, 3, 8, 7, 2]) # optional - sage.modules [0 0 1 1 0 1 1 0 0 0 0 0] [0 0 0 1 1 1 0 1 0 0 0 0] [1 0 0 0 1 0 0 1 1 0 0 0] diff --git a/src/sage/graphs/graph_decompositions/graph_products.pyx b/src/sage/graphs/graph_decompositions/graph_products.pyx index ed85f6f7ef2..0a948360096 100644 --- a/src/sage/graphs/graph_decompositions/graph_products.pyx +++ b/src/sage/graphs/graph_decompositions/graph_products.pyx @@ -206,8 +206,8 @@ def is_cartesian_product(g, certificate=False, relabeling=False): Wagner's Graph (:trac:`13599`):: - sage: g = graphs.WagnerGraph() - sage: g.is_cartesian_product() + sage: g = graphs.WagnerGraph() # optional - networkx + sage: g.is_cartesian_product() # optional - networkx False Empty and one-element graph (:trac:`19546`):: diff --git a/src/sage/graphs/graph_decompositions/modular_decomposition.py b/src/sage/graphs/graph_decompositions/modular_decomposition.py index 0c1ae4da5b3..794c1d95d7b 100644 --- a/src/sage/graphs/graph_decompositions/modular_decomposition.py +++ b/src/sage/graphs/graph_decompositions/modular_decomposition.py @@ -16,8 +16,12 @@ # **************************************************************************** from enum import Enum + +from sage.misc.lazy_import import lazy_import from sage.misc.random_testing import random_testing +lazy_import('sage.groups.perm_gps.permgroup_element', 'PermutationGroupElement') + class NodeType(Enum): """ @@ -606,7 +610,7 @@ def habib_maurer_algorithm(graph, g_classes=None): decompositions. :: sage: from sage.graphs.graph_decompositions.modular_decomposition import permute_decomposition - sage: permute_decomposition(2, habib_maurer_algorithm, 20, 0.5) + sage: permute_decomposition(2, habib_maurer_algorithm, 20, 0.5) # optional - sage.groups """ if graph.is_directed(): raise ValueError("Graph must be undirected") @@ -1167,7 +1171,6 @@ def relabel_tree(root, perm): 2 1 """ - from sage.groups.perm_gps.permgroup_element import PermutationGroupElement # If perm is not a dictionary, we build one ! if perm is None: diff --git a/src/sage/graphs/graph_decompositions/vertex_separation.pyx b/src/sage/graphs/graph_decompositions/vertex_separation.pyx index 98ab0800e52..bf6070e9c8f 100644 --- a/src/sage/graphs/graph_decompositions/vertex_separation.pyx +++ b/src/sage/graphs/graph_decompositions/vertex_separation.pyx @@ -766,12 +766,12 @@ def vertex_separation(G, algorithm="BAB", cut_off=None, upper_bound=None, verbos Comparison of methods:: sage: from sage.graphs.graph_decompositions.vertex_separation import vertex_separation - sage: G = digraphs.DeBruijn(2,3) - sage: vs,L = vertex_separation(G, algorithm="BAB"); vs + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: vs,L = vertex_separation(G, algorithm="BAB"); vs # optional - sage.combinat 2 - sage: vs,L = vertex_separation(G, algorithm="exponential"); vs + sage: vs,L = vertex_separation(G, algorithm="exponential"); vs # optional - sage.combinat 2 - sage: vs,L = vertex_separation(G, algorithm="MILP"); vs + sage: vs,L = vertex_separation(G, algorithm="MILP"); vs # optional - sage.combinat 2 sage: G = graphs.Grid2dGraph(3,3) sage: vs,L = vertex_separation(G, algorithm="BAB"); vs @@ -954,8 +954,8 @@ def vertex_separation_exp(G, verbose=False): Graphs with non-integer vertices:: sage: from sage.graphs.graph_decompositions.vertex_separation import vertex_separation_exp - sage: D=digraphs.DeBruijn(2,3) - sage: vertex_separation_exp(D) + sage: D = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: vertex_separation_exp(D) # optional - sage.combinat (2, ['000', '001', '100', '010', '101', '011', '110', '111']) Given a too large graph:: @@ -1211,12 +1211,12 @@ def width_of_path_decomposition(G, L): Path decomposition of a BalancedTree:: sage: from sage.graphs.graph_decompositions import vertex_separation - sage: G = graphs.BalancedTree(3,2) - sage: pw, L = vertex_separation.path_decomposition(G) - sage: pw == vertex_separation.width_of_path_decomposition(G, L) + sage: G = graphs.BalancedTree(3,2) # optional - networkx + sage: pw, L = vertex_separation.path_decomposition(G) # optional - networkx + sage: pw == vertex_separation.width_of_path_decomposition(G, L) # optional - networkx True - sage: L.reverse() - sage: pw == vertex_separation.width_of_path_decomposition(G, L) + sage: L.reverse() # optional - networkx + sage: pw == vertex_separation.width_of_path_decomposition(G, L) # optional - networkx False Directed path decomposition of a circuit:: @@ -1305,9 +1305,9 @@ def _vertex_separation_MILP_formulation(G, integrality=False, solver=None): EXAMPLES:: sage: from sage.graphs.graph_decompositions.vertex_separation import _vertex_separation_MILP_formulation - sage: G = digraphs.DeBruijn(2,3) - sage: p, x, u, y, z = _vertex_separation_MILP_formulation(G) - sage: p + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: p, x, u, y, z = _vertex_separation_MILP_formulation(G) # optional - sage.combinat + sage: p # optional - sage.combinat Mixed Integer Program (minimization, 193 variables, 449 constraints) """ from sage.graphs.graph import Graph @@ -1420,12 +1420,12 @@ def vertex_separation_MILP(G, integrality=False, solver=None, verbose=0, Vertex separation of a De Bruijn digraph:: sage: from sage.graphs.graph_decompositions import vertex_separation - sage: G = digraphs.DeBruijn(2,3) - sage: vs, L = vertex_separation.vertex_separation_MILP(G); vs + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: vs, L = vertex_separation.vertex_separation_MILP(G); vs # optional - sage.combinat 2 - sage: vs == vertex_separation.width_of_path_decomposition(G, L) + sage: vs == vertex_separation.width_of_path_decomposition(G, L) # optional - sage.combinat True - sage: vse, Le = vertex_separation.vertex_separation(G); vse + sage: vse, Le = vertex_separation.vertex_separation(G); vse # optional - sage.combinat 2 The vertex separation of a circuit is 1:: diff --git a/src/sage/graphs/graph_input.py b/src/sage/graphs/graph_input.py index 1c952fcceae..39b22a44b56 100644 --- a/src/sage/graphs/graph_input.py +++ b/src/sage/graphs/graph_input.py @@ -185,8 +185,9 @@ def from_seidel_adjacency_matrix(G, M): sage: from sage.graphs.graph_input import from_seidel_adjacency_matrix sage: g = Graph() - sage: from_seidel_adjacency_matrix(g, graphs.PetersenGraph().seidel_adjacency_matrix()) - sage: g.is_isomorphic(graphs.PetersenGraph()) + sage: sam = graphs.PetersenGraph().seidel_adjacency_matrix() # optional - sage.modules + sage: from_seidel_adjacency_matrix(g, sam) # optional - sage.modules + sage: g.is_isomorphic(graphs.PetersenGraph()) # optional - sage.modules True """ from sage.structure.element import is_Matrix @@ -235,8 +236,8 @@ def from_adjacency_matrix(G, M, loops=False, multiedges=False, weighted=False): sage: from sage.graphs.graph_input import from_adjacency_matrix sage: g = Graph() - sage: from_adjacency_matrix(g, graphs.PetersenGraph().adjacency_matrix()) - sage: g.is_isomorphic(graphs.PetersenGraph()) + sage: from_adjacency_matrix(g, graphs.PetersenGraph().adjacency_matrix()) # optional - sage.modules + sage: g.is_isomorphic(graphs.PetersenGraph()) # optional - sage.modules True """ from sage.structure.element import is_Matrix @@ -311,8 +312,8 @@ def from_incidence_matrix(G, M, loops=False, multiedges=False, weighted=False): sage: from sage.graphs.graph_input import from_incidence_matrix sage: g = Graph() - sage: from_incidence_matrix(g, graphs.PetersenGraph().incidence_matrix()) - sage: g.is_isomorphic(graphs.PetersenGraph()) + sage: from_incidence_matrix(g, graphs.PetersenGraph().incidence_matrix()) # optional - sage.modules + sage: g.is_isomorphic(graphs.PetersenGraph()) # optional - sage.modules True """ from sage.structure.element import is_Matrix @@ -377,38 +378,37 @@ def from_oriented_incidence_matrix(G, M, loops=False, multiedges=False, weighted sage: from sage.graphs.graph_input import from_oriented_incidence_matrix sage: g = DiGraph() - sage: from_oriented_incidence_matrix(g, digraphs.Circuit(10).incidence_matrix()) - sage: g.is_isomorphic(digraphs.Circuit(10)) + sage: im = digraphs.Circuit(10).incidence_matrix() # optional - sage.modules + sage: from_oriented_incidence_matrix(g, im) # optional - sage.modules + sage: g.is_isomorphic(digraphs.Circuit(10)) # optional - sage.modules True TESTS: Fix bug reported in :trac:`22985`:: - sage: DiGraph(matrix ([[1,0,0,1],[0,0,1,1],[0,0,1,1]]).transpose()) + sage: DiGraph(matrix ([[1,0,0,1],[0,0,1,1],[0,0,1,1]]).transpose()) # optional - sage.modules Traceback (most recent call last): ... ValueError: each column represents an edge: -1 goes to 1 Handle incidence matrix containing a column with only zeros (:trac:`29275`):: - sage: m = Matrix([[0,1],[0,-1],[0,0]]) - sage: m + sage: m = Matrix([[0,1],[0,-1],[0,0]]); m # optional - sage.modules [ 0 1] [ 0 -1] [ 0 0] - sage: G = DiGraph(m,format='incidence_matrix') - sage: list(G.edges(sort=True, labels=False)) + sage: G = DiGraph(m, format='incidence_matrix') # optional - sage.modules + sage: list(G.edges(sort=True, labels=False)) # optional - sage.modules [(1, 0)] Handle incidence matrix [[1],[-1]] (:trac:`29275`):: - sage: m = Matrix([[1],[-1]]) - sage: m + sage: m = Matrix([[1],[-1]]); m # optional - sage.modules [ 1] [-1] - sage: G = DiGraph(m,format='incidence_matrix') - sage: list(G.edges(sort=True, labels=False)) + sage: G = DiGraph(m, format='incidence_matrix') # optional - sage.modules + sage: list(G.edges(sort=True, labels=False)) # optional - sage.modules [(1, 0)] """ from sage.structure.element import is_Matrix diff --git a/src/sage/graphs/graph_list.py b/src/sage/graphs/graph_list.py index ea84b183fb2..4a43987a79b 100644 --- a/src/sage/graphs/graph_list.py +++ b/src/sage/graphs/graph_list.py @@ -266,9 +266,9 @@ def to_graphics_array(graph_list, **kwds): options, all of which are available from :func:`to_graphics_array`:: sage: glist = [] - sage: for _ in range(10): + sage: for _ in range(10): # optional - networkx ....: glist.append(graphs.RandomLobster(41, .3, .4)) - sage: graphs_list.to_graphics_array(glist, layout='spring', vertex_size=20) # optional - sage.plot + sage: graphs_list.to_graphics_array(glist, layout='spring', vertex_size=20) # optional - networkx sage.plot Graphics Array of size 3 x 4 """ from sage.graphs import graph diff --git a/src/sage/graphs/graph_plot_js.py b/src/sage/graphs/graph_plot_js.py index 44b6274cf4c..ad846d7a474 100644 --- a/src/sage/graphs/graph_plot_js.py +++ b/src/sage/graphs/graph_plot_js.py @@ -174,14 +174,14 @@ def gen_html_code(G, sage: graphs.DodecahedralGraph().show(method="js") # optional -- internet sage.plot - sage: g = digraphs.DeBruijn(2, 2) - sage: g.allow_multiple_edges(True) - sage: g.add_edge("10", "10", "a") - sage: g.add_edge("10", "10", "b") - sage: g.add_edge("10", "10", "c") - sage: g.add_edge("10", "10", "d") - sage: g.add_edge("01", "11", "1") - sage: g.show(method="js", vertex_labels=True,edge_labels=True, # optional - sage.plot + sage: g = digraphs.DeBruijn(2, 2) # optional - sage.combinat + sage: g.allow_multiple_edges(True) # optional - sage.combinat + sage: g.add_edge("10", "10", "a") # optional - sage.combinat + sage: g.add_edge("10", "10", "b") # optional - sage.combinat + sage: g.add_edge("10", "10", "c") # optional - sage.combinat + sage: g.add_edge("10", "10", "d") # optional - sage.combinat + sage: g.add_edge("01", "11", "1") # optional - sage.combinat + sage: g.show(method="js", vertex_labels=True,edge_labels=True, # optional - sage.combinat sage.plot ....: link_distance=200, gravity=.05, charge=-500, ....: edge_partition=[[("11", "12", "2"), ("21", "21", "a")]], ....: edge_thickness=4) diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index 05fb3c3da79..ff2d20a4d80 100644 --- a/src/sage/graphs/hyperbolicity.pyx +++ b/src/sage/graphs/hyperbolicity.pyx @@ -146,7 +146,7 @@ Methods # 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/ +# http://www.gnu.org/licenses/ # **************************************************************************** from libc.string cimport memset @@ -157,7 +157,7 @@ from memory_allocator cimport MemoryAllocator from sage.graphs.distances_all_pairs cimport c_distances_all_pairs from sage.arith.misc import binomial from sage.rings.integer_ring import ZZ -from sage.rings.real_mpfr import RR +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 sage.graphs.base.static_sparse_graph cimport free_short_digraph @@ -1287,6 +1287,8 @@ def hyperbolicity(G, elif approximation_factor == 1.0: pass elif algorithm in ['CCL', 'CCL+FA', 'BCCM']: + from sage.rings.real_mpfr import RR + if approximation_factor not in RR or approximation_factor < 1.0: raise ValueError("the approximation factor must be >= 1.0") else: @@ -1297,6 +1299,8 @@ def hyperbolicity(G, elif additive_gap == 0.0: pass elif algorithm in ['CCL', 'CCL+FA', 'BCCM']: + from sage.rings.real_mpfr import RR + if additive_gap not in RR or additive_gap < 0.0: raise ValueError("the additive gap must be a real positive number") else: diff --git a/src/sage/graphs/hypergraph_generators.py b/src/sage/graphs/hypergraph_generators.py index a106f3fc7d8..c3e42da9565 100644 --- a/src/sage/graphs/hypergraph_generators.py +++ b/src/sage/graphs/hypergraph_generators.py @@ -306,34 +306,34 @@ def BinomialRandomUniform(self, n, k, p): EXAMPLES:: - sage: hypergraphs.BinomialRandomUniform(50, 3, 1).num_blocks() + sage: hypergraphs.BinomialRandomUniform(50, 3, 1).num_blocks() # optional - numpy 19600 - sage: hypergraphs.BinomialRandomUniform(50, 3, 0).num_blocks() + sage: hypergraphs.BinomialRandomUniform(50, 3, 0).num_blocks() # optional - numpy 0 TESTS:: - sage: hypergraphs.BinomialRandomUniform(50, 3, -0.1) + sage: hypergraphs.BinomialRandomUniform(50, 3, -0.1) # optional - numpy Traceback (most recent call last): ... ValueError: edge probability should be in [0,1] - sage: hypergraphs.BinomialRandomUniform(50, 3, 1.1) + sage: hypergraphs.BinomialRandomUniform(50, 3, 1.1) # optional - numpy Traceback (most recent call last): ... ValueError: edge probability should be in [0,1] - sage: hypergraphs.BinomialRandomUniform(-50, 3, 0.17) + sage: hypergraphs.BinomialRandomUniform(-50, 3, 0.17) # optional - numpy Traceback (most recent call last): ... ValueError: number of vertices should be non-negative - sage: hypergraphs.BinomialRandomUniform(50.9, 3, 0.17) + sage: hypergraphs.BinomialRandomUniform(50.9, 3, 0.17) # optional - numpy Traceback (most recent call last): ... ValueError: number of vertices should be an integer - sage: hypergraphs.BinomialRandomUniform(50, -3, 0.17) + sage: hypergraphs.BinomialRandomUniform(50, -3, 0.17) # optional - numpy Traceback (most recent call last): ... ValueError: the uniformity should be non-negative - sage: hypergraphs.BinomialRandomUniform(50, I, 0.17) + sage: hypergraphs.BinomialRandomUniform(50, I, 0.17) # optional - numpy Traceback (most recent call last): ... ValueError: the uniformity should be an integer diff --git a/src/sage/graphs/isoperimetric_inequalities.pyx b/src/sage/graphs/isoperimetric_inequalities.pyx index b7f6510ba94..b6dfa40d06d 100644 --- a/src/sage/graphs/isoperimetric_inequalities.pyx +++ b/src/sage/graphs/isoperimetric_inequalities.pyx @@ -209,8 +209,8 @@ def edge_isoperimetric_number(g): In general, for `d`-regular graphs the edge-isoperimetric number is `d` times larger than the Cheeger constant of the graph:: - sage: g = graphs.RandomRegular(3, 10) - sage: g.edge_isoperimetric_number() == g.cheeger_constant() * 3 + sage: g = graphs.RandomRegular(3, 10) # optional - networkx + sage: g.edge_isoperimetric_number() == g.cheeger_constant() * 3 # optional - networkx True And the edge-isoperimetric constant of a disconnected graph is `0`:: diff --git a/src/sage/graphs/line_graph.pyx b/src/sage/graphs/line_graph.pyx index 25cd48de951..656c9c08909 100644 --- a/src/sage/graphs/line_graph.pyx +++ b/src/sage/graphs/line_graph.pyx @@ -176,8 +176,8 @@ def is_line_graph(g, certificate=False): This is indeed the subgraph returned:: - sage: C = graphs.PetersenGraph().is_line_graph(certificate=True)[1] - sage: C.is_isomorphic(graphs.ClawGraph()) + sage: C = graphs.PetersenGraph().is_line_graph(certificate=True)[1] # optional - sage.modules + sage: C.is_isomorphic(graphs.ClawGraph()) # optional - sage.modules True The house graph is a line graph:: @@ -188,11 +188,11 @@ def is_line_graph(g, certificate=False): But what is the graph whose line graph is the house ?:: - sage: is_line, R, isom = g.is_line_graph(certificate=True) - sage: R.sparse6_string() + sage: is_line, R, isom = g.is_line_graph(certificate=True) # optional - sage.modules + sage: R.sparse6_string() # optional - sage.modules ':DaHI~' - sage: R.show() # optional - sage.plot - sage: isom + sage: R.show() # optional - sage.modules sage.plot + sage: isom # optional - sage.modules {0: (0, 1), 1: (0, 2), 2: (1, 3), 3: (2, 3), 4: (3, 4)} TESTS: @@ -201,8 +201,8 @@ def is_line_graph(g, certificate=False): sage: g = 2 * graphs.CycleGraph(3) sage: gl = g.line_graph().relabel(inplace=False) - sage: new_g = gl.is_line_graph(certificate=True)[1] - sage: g.line_graph().is_isomorphic(gl) + sage: new_g = gl.is_line_graph(certificate=True)[1] # optional - sage.modules + sage: g.line_graph().is_isomorphic(gl) # optional - sage.modules True Verify that :trac:`29740` is fixed:: @@ -309,12 +309,12 @@ def line_graph(g, labels=True): sage: h = g.line_graph() sage: h.vertices(sort=True) [(0, 1, None), - (0, 2, None), - (0, 3, None), - (1, 2, None), - (1, 3, None), - (2, 3, None)] - sage: h.am() + (0, 2, None), + (0, 3, None), + (1, 2, None), + (1, 3, None), + (2, 3, None)] + sage: h.am() # optional - sage.modules [0 1 1 1 1 0] [1 0 1 1 0 1] [1 1 0 0 1 1] @@ -330,11 +330,11 @@ def line_graph(g, labels=True): sage: h = g.line_graph() sage: h.vertices(sort=True) [(1, 2, None), - (1, 3, None), - (1, 4, None), - (2, 3, None), - (2, 4, None), - (3, 4, None)] + (1, 3, None), + (1, 4, None), + (2, 3, None), + (2, 4, None), + (3, 4, None)] sage: h.edges(sort=True) [((1, 2, None), (2, 3, None), None), ((1, 2, None), (2, 4, None), None), diff --git a/src/sage/graphs/partial_cube.py b/src/sage/graphs/partial_cube.py index bce06dee677..f7bb3e25173 100644 --- a/src/sage/graphs/partial_cube.py +++ b/src/sage/graphs/partial_cube.py @@ -110,8 +110,8 @@ def breadth_first_level_search(G, start): EXAMPLES:: - sage: H = digraphs.DeBruijn(3,2) - sage: list(sage.graphs.partial_cube.breadth_first_level_search(H, '00')) + sage: H = digraphs.DeBruijn(3,2) # optional - sage.combinat + sage: list(sage.graphs.partial_cube.breadth_first_level_search(H, '00')) # optional - sage.combinat [{'00': {'01', '02'}}, {'01': {'10', '11', '12'}, '02': {'20', '21', '22'}}, {'10': set(), @@ -162,9 +162,9 @@ def depth_first_traversal(G, start): EXAMPLES:: - sage: H = digraphs.DeBruijn(3,2) - sage: t = list(sage.graphs.partial_cube.depth_first_traversal(H, '00')) - sage: len(t) + sage: H = digraphs.DeBruijn(3,2) # optional - sage.combinat + sage: t = list(sage.graphs.partial_cube.depth_first_traversal(H, '00')) # optional - sage.combinat + sage: len(t) # optional - sage.combinat 16 """ neighbors = G.neighbor_out_iterator diff --git a/src/sage/graphs/pq_trees.py b/src/sage/graphs/pq_trees.py index 4c3f25081bf..2ddd39691e8 100644 --- a/src/sage/graphs/pq_trees.py +++ b/src/sage/graphs/pq_trees.py @@ -365,8 +365,7 @@ def __iter__(self): {2, 3} ('P', [{2, 4}, {8, 2}, {9, 2}]) """ - for i in self._children: - yield i + yield from self._children def number_of_children(self): r""" @@ -795,13 +794,11 @@ def orderings(self): ({2, 4}, {0, 8}, {1, 2}, {0, 5}) ({2, 4}, {0, 8}, {0, 5}, {1, 2}) ... - """ from itertools import permutations, product for p in permutations(self._children): - for o in product(*[x.orderings() if isinstance(x, PQ) else [x] - for x in p]): - yield o + yield from product(*[x.orderings() if isinstance(x, PQ) else [x] + for x in p]) class Q(PQ): @@ -1124,8 +1121,7 @@ def orderings(self): """ if len(self._children) == 1: c = self._children[0] - for o in (c.orderings() if isinstance(c, PQ) else [c]): - yield o + yield from (c.orderings() if isinstance(c, PQ) else [c]) else: from itertools import product for o in product(*[x.orderings() if isinstance(x, PQ) else [x] diff --git a/src/sage/graphs/spanning_tree.pyx b/src/sage/graphs/spanning_tree.pyx index 2fb5124596f..179625ab743 100644 --- a/src/sage/graphs/spanning_tree.pyx +++ b/src/sage/graphs/spanning_tree.pyx @@ -569,11 +569,12 @@ def filter_kruskal_iterator(G, threshold=10000, by_weight=True, weight_function= :func:`filter_kruskal_iterator` are the same:: sage: from sage.graphs.spanning_tree import kruskal_iterator - sage: G = graphs.RandomBarabasiAlbert(50, 2) - sage: for u, v in G.edge_iterator(labels=False): + sage: G = graphs.RandomBarabasiAlbert(50, 2) # optional - networkx + sage: for u, v in G.edge_iterator(labels=False): # optional - networkx ....: G.set_edge_label(u, v, randint(1, 10)) - sage: G.weighted(True) - sage: sum(e[2] for e in kruskal_iterator(G)) == sum(e[2] for e in filter_kruskal_iterator(G, threshold=20)) + sage: G.weighted(True) # optional - networkx + sage: sum(e[2] for e in kruskal_iterator(G)) == sum(e[2] # optional - networkx + ....: for e in filter_kruskal_iterator(G, threshold=20)) True TESTS: @@ -999,11 +1000,11 @@ def random_spanning_tree(G, output_as_graph=False, by_weight=False, weight_funct 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): + sage: G = graphs.RandomBarabasiAlbert(50, 2) # optional - networkx + sage: for u, v in G.edge_iterator(labels=False): # optional - networkx ....: 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() + sage: T = G.random_spanning_tree(by_weight=True, output_as_graph=True) # optional - networkx + sage: T.is_tree() # optional - networkx True TESTS:: @@ -1087,12 +1088,12 @@ def spanning_trees(g, labels=False): sage: G = Graph([(1,2),(1,2),(1,3),(1,3),(2,3),(1,4)], multiedges=True) sage: len(list(G.spanning_trees())) 8 - sage: G.spanning_trees_count() + sage: G.spanning_trees_count() # optional - sage.modules 8 sage: G = Graph([(1,2),(2,3),(3,1),(3,4),(4,5),(4,5),(4,6)], multiedges=True) sage: len(list(G.spanning_trees())) 6 - sage: G.spanning_trees_count() + sage: G.spanning_trees_count() # optional - sage.modules 6 .. SEEALSO:: diff --git a/src/sage/graphs/strongly_regular_db.pyx b/src/sage/graphs/strongly_regular_db.pyx index 24f471edd4e..4a72a2da568 100644 --- a/src/sage/graphs/strongly_regular_db.pyx +++ b/src/sage/graphs/strongly_regular_db.pyx @@ -30,21 +30,22 @@ Functions import json import os +from libc.math cimport sqrt, floor +from libc.stdint cimport uint_fast32_t + +from sage.arith.misc import divisors, is_prime_power, is_square from sage.categories.sets_cat import EmptySetError -from sage.misc.unknown import Unknown -from sage.arith.misc import is_square -from sage.arith.misc import is_prime_power -from sage.arith.misc import divisors -from sage.misc.cachefunc import cached_function -from sage.combinat.designs.orthogonal_arrays import orthogonal_array -from sage.combinat.designs.bibd import balanced_incomplete_block_design from sage.graphs.graph import Graph -from libc.math cimport sqrt, floor -from sage.matrix.constructor import Matrix -from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF -from sage.coding.linear_code import LinearCode +from sage.misc.cachefunc import cached_function +from sage.misc.lazy_import import LazyImport +from sage.misc.unknown import Unknown from sage.rings.sum_of_squares cimport two_squares_c -from libc.stdint cimport uint_fast32_t + +orthogonal_array = LazyImport('sage.combinat.designs.orthogonal_arrays', 'orthogonal_array') +balanced_incomplete_block_design = LazyImport('sage.combinat.designs.bibd', 'balanced_incomplete_block_design') +GF = LazyImport('sage.rings.finite_rings.finite_field_constructor', 'GF') +Matrix = LazyImport('sage.matrix.constructor', 'Matrix') +LinearCode = LazyImport('sage.coding.linear_code', 'LinearCode') cdef dict _brouwer_database = None _small_srg_database = None diff --git a/src/sage/graphs/traversals.pyx b/src/sage/graphs/traversals.pyx index e07c502973e..9ebc253b6f9 100644 --- a/src/sage/graphs/traversals.pyx +++ b/src/sage/graphs/traversals.pyx @@ -338,16 +338,16 @@ def lex_BFS(G, reverse=False, tree=False, initial_vertex=None, algorithm="fast") Different orderings for different traversals:: - sage: G = digraphs.DeBruijn(2,3) - sage: G.lex_BFS(initial_vertex='000', algorithm="fast") + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: G.lex_BFS(initial_vertex='000', algorithm="fast") # optional - sage.combinat ['000', '001', '100', '010', '011', '110', '101', '111'] - sage: G.lex_BFS(initial_vertex='000', algorithm="slow") + sage: G.lex_BFS(initial_vertex='000', algorithm="slow") # optional - sage.combinat ['000', '001', '100', '010', '011', '110', '101', '111'] - sage: G.lex_DFS(initial_vertex='000') + sage: G.lex_DFS(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '010', '101', '110', '011', '111'] - sage: G.lex_UP(initial_vertex='000') + sage: G.lex_UP(initial_vertex='000') # optional - sage.combinat ['000', '001', '010', '101', '110', '111', '011', '100'] - sage: G.lex_DOWN(initial_vertex='000') + sage: G.lex_DOWN(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '011', '010', '110', '111', '101'] TESTS: @@ -541,14 +541,14 @@ def lex_UP(G, reverse=False, tree=False, initial_vertex=None): Different orderings for different traversals:: - sage: G = digraphs.DeBruijn(2,3) - sage: G.lex_BFS(initial_vertex='000') + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: G.lex_BFS(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '010', '011', '110', '101', '111'] - sage: G.lex_DFS(initial_vertex='000') + sage: G.lex_DFS(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '010', '101', '110', '011', '111'] - sage: G.lex_UP(initial_vertex='000') + sage: G.lex_UP(initial_vertex='000') # optional - sage.combinat ['000', '001', '010', '101', '110', '111', '011', '100'] - sage: G.lex_DOWN(initial_vertex='000') + sage: G.lex_DOWN(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '011', '010', '110', '111', '101'] TESTS: @@ -714,14 +714,14 @@ def lex_DFS(G, reverse=False, tree=False, initial_vertex=None): Different orderings for different traversals:: - sage: G = digraphs.DeBruijn(2,3) - sage: G.lex_BFS(initial_vertex='000') + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: G.lex_BFS(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '010', '011', '110', '101', '111'] - sage: G.lex_DFS(initial_vertex='000') + sage: G.lex_DFS(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '010', '101', '110', '011', '111'] - sage: G.lex_UP(initial_vertex='000') + sage: G.lex_UP(initial_vertex='000') # optional - sage.combinat ['000', '001', '010', '101', '110', '111', '011', '100'] - sage: G.lex_DOWN(initial_vertex='000') + sage: G.lex_DOWN(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '011', '010', '110', '111', '101'] TESTS: @@ -889,14 +889,14 @@ def lex_DOWN(G, reverse=False, tree=False, initial_vertex=None): Different orderings for different traversals:: - sage: G = digraphs.DeBruijn(2,3) - sage: G.lex_BFS(initial_vertex='000') + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: G.lex_BFS(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '010', '011', '110', '101', '111'] - sage: G.lex_DFS(initial_vertex='000') + sage: G.lex_DFS(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '010', '101', '110', '011', '111'] - sage: G.lex_UP(initial_vertex='000') + sage: G.lex_UP(initial_vertex='000') # optional - sage.combinat ['000', '001', '010', '101', '110', '111', '011', '100'] - sage: G.lex_DOWN(initial_vertex='000') + sage: G.lex_DOWN(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '011', '010', '110', '111', '101'] TESTS: diff --git a/src/sage/graphs/views.pyx b/src/sage/graphs/views.pyx index 51a4a738e46..c49511207e5 100644 --- a/src/sage/graphs/views.pyx +++ b/src/sage/graphs/views.pyx @@ -175,11 +175,11 @@ cdef class EdgesView: With a directed graph:: - sage: G = digraphs.DeBruijn(2, 2) - sage: E = EdgesView(G, labels=False, sort=True); E + sage: G = digraphs.DeBruijn(2, 2) # optional - sage.combinat + sage: E = EdgesView(G, labels=False, sort=True); E # optional - sage.combinat [('00', '00'), ('00', '01'), ('01', '10'), ('01', '11'), ('10', '00'), ('10', '01'), ('11', '10'), ('11', '11')] - sage: E = EdgesView(G, labels=False, sort=True, key=lambda e:(e[1], e[0])); E + sage: E = EdgesView(G, labels=False, sort=True, key=lambda e:(e[1], e[0])); E # optional - sage.combinat [('00', '00'), ('10', '00'), ('00', '01'), ('10', '01'), ('01', '10'), ('11', '10'), ('01', '11'), ('11', '11')] diff --git a/src/sage/groups/abelian_gps/dual_abelian_group.py b/src/sage/groups/abelian_gps/dual_abelian_group.py index a1650f4eab0..2d5441daaca 100644 --- a/src/sage/groups/abelian_gps/dual_abelian_group.py +++ b/src/sage/groups/abelian_gps/dual_abelian_group.py @@ -405,5 +405,4 @@ def __iter__(self): sage: len([X for X in Gd if abs(X(x)-1)>0.01 and abs(X(y)-1)>0.01 and abs(X(z)-1)>0.01]) 880 """ - for g in self.list(): - yield g + yield from self.list() diff --git a/src/sage/groups/libgap_mixin.py b/src/sage/groups/libgap_mixin.py index fbf5ba3d349..6fb27280d8b 100644 --- a/src/sage/groups/libgap_mixin.py +++ b/src/sage/groups/libgap_mixin.py @@ -826,8 +826,7 @@ def __iter__(self): 60 """ if self.list.cache is not None: - for g in self.list(): - yield g + yield from self.list() return iterator = self.gap().Iterator() while not iterator.IsDoneIterator().sage(): diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index 260022d05b7..a832f695eb1 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -3652,7 +3652,6 @@ def delta(u, v): ims += sum(line(a[0], **kwargs) for a in im) return image - def _markov_move_cmp(self, braid): r""" Return whether ``self`` can be transformed to the closure of ``braid`` @@ -4120,7 +4119,6 @@ def answer_list(l): raise NotImplementedError('this link cannot be uniquely determined%s' %non_unique_hint) - self_m = self.mirror_image() ls, proved_s = self._knotinfo_matching_list() lm, proved_m = self_m._knotinfo_matching_list() @@ -4147,18 +4145,18 @@ def answer_list(l): cr = len(self.pd_code()) if self.is_knot() and cr > 12: # we cannot not be sure if this link is recorded in the KnotInfo database - raise NotImplementedError('this knot having more than 12 crossings cannot be%s determined%s' %uniq_txt) + raise NotImplementedError('this knot having more than 12 crossings cannot be%s determined%s' % uniq_txt) if not self.is_knot() and cr > 11: # we cannot not be sure if this link is recorded in the KnotInfo database - raise NotImplementedError('this link having more than 11 crossings cannot be%s determined%s' %uniq_txt) + raise NotImplementedError('this link having more than 11 crossings cannot be%s determined%s' % uniq_txt) H = self.homfly_polynomial(normalization='vz') if sum(exp for f, exp in H.factor()) > 1: # we cannot be sure if this is a prime link (see the example for the connected # sum of K4_1 and K5_2 in the doctest of :meth:`_knotinfo_matching_list`) - raise NotImplementedError('this (possibly non prime) link cannot be%s determined%s' %uniq_txt) + raise NotImplementedError('this (possibly non prime) link cannot be%s determined%s' % uniq_txt) if not l: from sage.features.databases import DatabaseKnotInfo @@ -4167,7 +4165,6 @@ def answer_list(l): return answer_list(l) - def is_isotopic(self, other): r""" Check whether ``self`` is isotopic to ``other``. diff --git a/src/sage/libs/eclib/homspace.pyx b/src/sage/libs/eclib/homspace.pyx index 090fa3b693d..dc52b144328 100644 --- a/src/sage/libs/eclib/homspace.pyx +++ b/src/sage/libs/eclib/homspace.pyx @@ -3,18 +3,16 @@ from cysignals.signals cimport sig_on, sig_off from cython.operator cimport dereference as deref from cython.operator cimport preincrement as inc -from libcpp.map cimport map -from ..eclib cimport vec, svec, mat, smat +from ..eclib cimport svec, mat, smat from .mat cimport MatrixFactory from sage.matrix.matrix_space import MatrixSpace -from sage.matrix.matrix_integer_sparse cimport Matrix_integer_sparse from sage.rings.integer_ring import ZZ -from sage.rings.integer cimport Integer cdef MatrixFactory MF = MatrixFactory() + cdef class ModularSymbols: """ Class of Cremona Modular Symbols of given level and sign (and weight 2). diff --git a/src/sage/libs/eclib/mwrank.pyx b/src/sage/libs/eclib/mwrank.pyx index e3b0b6b0000..11219ddefa6 100644 --- a/src/sage/libs/eclib/mwrank.pyx +++ b/src/sage/libs/eclib/mwrank.pyx @@ -18,9 +18,7 @@ EXAMPLES:: sage: t [[1:2:1]] """ - import os -import sys from cysignals.memory cimport sig_free from cysignals.signals cimport sig_on, sig_off diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index d9b47f19509..c5b793424c0 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -5,7 +5,6 @@ This document describes the individual wrappers for various GAP elements. For general information about GAP, you should read the :mod:`~sage.libs.gap.libgap` module documentation. """ - # **************************************************************************** # Copyright (C) 2012 Volker Braun # @@ -24,8 +23,6 @@ from .libgap import libgap from .util cimport * from .util import GAPError from sage.cpython.string cimport str_to_bytes, char_to_str -from sage.misc.cachefunc import cached_method -from sage.structure.sage_object cimport SageObject from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.real_double import RDF @@ -195,7 +192,7 @@ cdef Obj make_gap_record(sage_dict) except NULL: try: GAP_Enter() - rec = NEW_PREC(len(data)) + rec = GAP_NewPrecord(len(data)) for d in data: key, val = d rnam = RNamName(str_to_bytes(key)) @@ -305,9 +302,9 @@ cdef GapElement make_any_gap_element(parent, Obj obj): if obj is NULL: return make_GapElement(parent, obj) num = TNUM_OBJ(obj) - if IS_INT(obj): + if GAP_IsInt(obj): return make_GapElement_Integer(parent, obj) - elif num == T_MACFLOAT: + elif GAP_IsMacFloat(obj): return make_GapElement_Float(parent, obj) elif num == T_CYC: return make_GapElement_Cyclotomic(parent, obj) @@ -321,15 +318,15 @@ cdef GapElement make_any_gap_element(parent, Obj obj): return make_GapElement_Function(parent, obj) elif num == T_PERM2 or num == T_PERM4: return make_GapElement_Permutation(parent, obj) - elif IS_REC(obj): + elif GAP_IsRecord(obj): return make_GapElement_Record(parent, obj) - elif IS_LIST(obj) and LEN_LIST(obj) == 0: + elif GAP_IsList(obj) and GAP_LenList(obj) == 0: # Empty lists are lists and not strings in Python return make_GapElement_List(parent, obj) elif IsStringConv(obj): # GAP strings are lists, too. Make sure this comes before non-empty make_GapElement_List return make_GapElement_String(parent, obj) - elif IS_LIST(obj): + elif GAP_IsList(obj): return make_GapElement_List(parent, obj) elif num == T_CHAR: ch = make_GapElement(parent, obj).IntChar().sage() @@ -1209,7 +1206,7 @@ cdef class GapElement(RingElement): sage: libgap.eval('3/2').is_list() False """ - return IS_LIST(self.value) + return GAP_IsList(self.value) def is_record(self): r""" @@ -1226,7 +1223,7 @@ cdef class GapElement(RingElement): sage: libgap.eval('rec(a:=1, b:=3)').is_record() True """ - return IS_REC(self.value) + return GAP_IsRecord(self.value) cpdef is_bool(self): r""" @@ -1456,7 +1453,7 @@ cdef class GapElement_Integer(GapElement): sage: N.IsInt() true """ - return IS_INTOBJ(self.value) + return GAP_IsSmallInt(self.value) def _rational_(self): r""" @@ -1607,7 +1604,7 @@ cdef class GapElement_Float(GapElement): """ if ring is None: ring = RDF - return ring(VAL_MACFLOAT(self.value)) + return ring(GAP_ValueMacFloat(self.value)) def __float__(self): r""" @@ -1616,7 +1613,7 @@ cdef class GapElement_Float(GapElement): sage: float(libgap.eval("Float(3.5)")) 3.5 """ - return VAL_MACFLOAT(self.value) + return GAP_ValueMacFloat(self.value) @@ -2750,7 +2747,7 @@ cdef class GapElement_List(GapElement): sage: len(lst) 4 """ - return LEN_LIST(self.value) + return GAP_LenList(self.value) def __getitem__(self, i): r""" @@ -2798,15 +2795,15 @@ cdef class GapElement_List(GapElement): if isinstance(i, tuple): for j in i: - if not IS_LIST(obj): + if not GAP_IsList(obj): raise ValueError('too many indices') - if j < 0 or j >= LEN_LIST(obj): + if j < 0 or j >= GAP_LenList(obj): raise IndexError('index out of range') obj = ELM_LIST(obj, j+1) else: j = i - if j < 0 or j >= LEN_LIST(obj): + if j < 0 or j >= GAP_LenList(obj): raise IndexError('index out of range.') obj = ELM_LIST(obj, j+1) @@ -2869,12 +2866,12 @@ cdef class GapElement_List(GapElement): if isinstance(i, tuple): for j in i[:-1]: - if not IS_LIST(obj): + if not GAP_IsList(obj): raise ValueError('too many indices') - if j < 0 or j >= LEN_LIST(obj): + if j < 0 or j >= GAP_LenList(obj): raise IndexError('index out of range') obj = ELM_LIST(obj, j+1) - if not IS_LIST(obj): + if not GAP_IsList(obj): raise ValueError('too many indices') j = i[-1] else: diff --git a/src/sage/libs/gap/gap_includes.pxd b/src/sage/libs/gap/gap_includes.pxd index 4a1ab942cbf..24cd3df21ed 100644 --- a/src/sage/libs/gap/gap_includes.pxd +++ b/src/sage/libs/gap/gap_includes.pxd @@ -33,11 +33,6 @@ cdef extern from "gap/ariths.h" nogil: bint LT(Obj opL, Obj opR) -cdef extern from "gap/bool.h" nogil: - cdef Obj GAP_True "True" - cdef Obj GAP_False "False" - - cdef extern from "gap/calls.h" nogil: bint IS_FUNC(Obj) Obj CALL_0ARGS(Obj f) # 0 arguments @@ -50,17 +45,7 @@ cdef extern from "gap/calls.h" nogil: Obj CALL_XARGS(Obj f, Obj args) # more than 6 arguments -cdef extern from "gap/gasman.h" nogil: - void MarkBag(Obj bag) - UInt CollectBags(UInt size, UInt full) - - -cdef extern from "gap/integer.h" nogil: - Int IS_INT(Obj) - - cdef extern from "gap/intobj.h" nogil: - bint IS_INTOBJ(Obj obj) Obj INTOBJ_INT(Int) Int INT_INTOBJ(Obj) @@ -90,10 +75,26 @@ cdef extern from "gap/libgap-api.h" nogil: cdef void GAP_Leave() cdef int GAP_Error_Setjmp() except 0 + void GAP_MarkBag(Obj bag) + void GAP_CollectBags(UInt full) + + cdef Obj GAP_True + cdef Obj GAP_False + + bint GAP_IsMacFloat(Obj obj) + double GAP_ValueMacFloat(Obj obj) + + bint GAP_IsInt(Obj) + bint GAP_IsSmallInt(Obj) + + bint GAP_IsList(Obj lst) + UInt GAP_LenList(Obj lst) + + bint GAP_IsRecord(Obj obj) + Obj GAP_NewPrecord(Int capacity) + cdef extern from "gap/lists.h" nogil: - bint IS_LIST(Obj lst) - int LEN_LIST(Obj lst) Obj ELM_LIST(Obj lst, int pos) Obj ELM0_LIST(Obj lst, int pos) void ASS_LIST(Obj lst, int pos, Obj elt) @@ -103,10 +104,6 @@ cdef extern from "gap/listfunc.h" nogil: void AddList(Obj list, Obj obj) -cdef extern from "gap/macfloat.h" nogil: - double VAL_MACFLOAT(Obj obj) - - cdef extern from "gap/objects.h" nogil: bint IS_MUTABLE_OBJ(Obj obj) Obj SHALLOW_COPY_OBJ(Obj obj) @@ -119,7 +116,6 @@ cdef extern from "gap/objects.h" nogil: T_RAT T_CYC T_FFE - T_MACFLOAT T_PERM2 T_PERM4 T_BOOL @@ -142,7 +138,6 @@ cdef extern from "gap/permutat.h" nogil: cdef extern from "gap/precord.h" nogil: - Obj NEW_PREC(int len) int LEN_PREC(Obj rec) int GET_RNAM_PREC(Obj rec, int i) Obj GET_ELM_PREC(Obj rec, int i) @@ -151,7 +146,6 @@ cdef extern from "gap/precord.h" nogil: cdef extern from "gap/records.h" nogil: char* NAME_RNAM(UInt rnam) - bint IS_REC(Obj obj) Obj ELM_REC(Obj rec, UInt rnam) UInt RNamName(Char* name) diff --git a/src/sage/libs/gap/libgap.pyx b/src/sage/libs/gap/libgap.pyx index 6a36613aa8c..4157fcb1873 100644 --- a/src/sage/libs/gap/libgap.pyx +++ b/src/sage/libs/gap/libgap.pyx @@ -782,9 +782,7 @@ class Gap(Parent): sage: libgap.collect() """ initialize() - rc = CollectBags(0, 1) - if rc != 1: - raise RuntimeError('Garbage collection failed.') + GAP_CollectBags(1) libgap = Gap() diff --git a/src/sage/libs/gap/util.pyx b/src/sage/libs/gap/util.pyx index 02ab44d2cec..c282a59cb96 100644 --- a/src/sage/libs/gap/util.pyx +++ b/src/sage/libs/gap/util.pyx @@ -157,7 +157,7 @@ cdef void gasman_callback() with gil: """ global owned_objects_refcount for obj in owned_objects_refcount: - MarkBag((obj).value) + GAP_MarkBag((obj).value) ############################################################################ @@ -368,7 +368,7 @@ cdef Obj gap_eval(str gap_string) except? NULL: # If an error occurred in GAP_EvalString we won't even get # here if the error handler was set; but in case it wasn't # let's still check the result... - nresults = LEN_LIST(result) + nresults = GAP_LenList(result) if nresults > 1: # to mimick the old libGAP # TODO: Get rid of this restriction eventually? raise GAPError("can only evaluate a single statement") diff --git a/src/sage/libs/giac/giac.pyx b/src/sage/libs/giac/giac.pyx index 69ccf6426e4..a78e2199725 100644 --- a/src/sage/libs/giac/giac.pyx +++ b/src/sage/libs/giac/giac.pyx @@ -151,7 +151,7 @@ import math # sage includes from sage.ext.stdsage cimport PY_NEW -from sage.libs.gmp.mpz cimport mpz_t, mpz_init_set +from sage.libs.gmp.mpz cimport mpz_set from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ diff --git a/src/sage/libs/lcalc/lcalc_Lfunction.pyx b/src/sage/libs/lcalc/lcalc_Lfunction.pyx index a59a2207867..6e9005c502b 100644 --- a/src/sage/libs/lcalc/lcalc_Lfunction.pyx +++ b/src/sage/libs/lcalc/lcalc_Lfunction.pyx @@ -949,17 +949,17 @@ def Lfunction_from_character(chi, type="complex"): OMEGA=1.0/ ( CCC(0,1)**a * (CCC(modulus)).sqrt()/chi.gauss_sum() ) if type == "complex": - dir_coeffs = [CCC(chi(n)) for n in xrange(1, modulus + 1)] + dir_coeffs = [CCC(chi(n)) for n in range(1, modulus + 1)] return Lfunction_C("", 1,dir_coeffs, period,Q,OMEGA,[.5],[a/2.],poles,residues) if type not in ["double", "int"]: raise ValueError("unknown type") if chi.order() != 2: raise ValueError("For non quadratic characters you must use type=\"complex\"") if type == "double": - dir_coeffs = [RRR(chi(n)) for n in xrange(1, modulus + 1)] + dir_coeffs = [RRR(chi(n)) for n in range(1, modulus + 1)] return Lfunction_D("", 1,dir_coeffs, period,Q,OMEGA,[.5],[a/2.],poles,residues) if type == "int": - dir_coeffs = [Integer(chi(n)) for n in xrange(1, modulus + 1)] + dir_coeffs = [Integer(chi(n)) for n in range(1, modulus + 1)] return Lfunction_I("", 1,dir_coeffs, period,Q,OMEGA,[.5],[a/2.],poles,residues) @@ -990,15 +990,13 @@ def Lfunction_from_elliptic_curve(E, number_of_coeffs=10000): True sage: (L.value(0.5, derivative=1) - 0.305999773835200).abs() < 1e-6 True - """ - import sage.libs.lcalc.lcalc_Lfunction Q = RRR(E.conductor()).sqrt() / RRR(2 * pi) poles = [] residues = [] dir_coeffs = E.anlist(number_of_coeffs) dir_coeffs = [RRR(dir_coeffs[i]) / (RRR(i)).sqrt() - for i in xrange(1, number_of_coeffs)] + for i in range(1, number_of_coeffs)] OMEGA = E.root_number() return Lfunction_D("", 2, dir_coeffs, 0, Q, OMEGA, [1], [.5], poles, residues) diff --git a/src/sage/libs/linbox/linbox_flint_interface.pyx b/src/sage/libs/linbox/linbox_flint_interface.pyx index 337cdf65754..415cd473947 100644 --- a/src/sage/libs/linbox/linbox_flint_interface.pyx +++ b/src/sage/libs/linbox/linbox_flint_interface.pyx @@ -21,7 +21,7 @@ and C. Pernet. The functions available are: - ``void linbox_fmpz_mat_det(fmpz_t det, fmpz_mat_t A)``: set ``det`` to the determinant of the square matrix ``A`` """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 Martin Albrecht # Copyright (C) 2008 Clement Pernet # Copyright (C) 2017-2018 Vincent Delecroix @@ -30,15 +30,13 @@ and C. Pernet. The functions available are: # 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/ +# **************************************************************************** -from sage.libs.gmp.types cimport mpz_t, mpz_srcptr, mpz_ptr -from sage.libs.gmp.mpz cimport mpz_set -from sage.libs.flint.types cimport fmpz, fmpz_t +from sage.libs.flint.types cimport fmpz_t from sage.libs.flint.fmpz cimport fmpz_get_mpz, fmpz_set_mpz from sage.libs.flint.fmpz_mat cimport fmpz_mat_entry, fmpz_mat_nrows, fmpz_mat_ncols -from sage.libs.flint.fmpz_poly cimport fmpz_poly_set_coeff_mpz, fmpz_poly_fit_length, _fmpz_poly_set_length, fmpz_poly_one +from sage.libs.flint.fmpz_poly cimport fmpz_poly_set_coeff_mpz, fmpz_poly_fit_length, _fmpz_poly_set_length cimport sage.libs.linbox.givaro as givaro cimport sage.libs.linbox.linbox as linbox diff --git a/src/sage/libs/mpmath/ext_impl.pyx b/src/sage/libs/mpmath/ext_impl.pyx index 2d1382ef6f1..97a9ad39b9e 100644 --- a/src/sage/libs/mpmath/ext_impl.pyx +++ b/src/sage/libs/mpmath/ext_impl.pyx @@ -1898,7 +1898,7 @@ cdef MPF_complex_pow_re(MPF *zre, MPF *zim, MPF *xre, MPF *xim, MPF *y, MPopts o xret = MPF_to_tuple(xre) ximt = MPF_to_tuple(xim) yret = MPF_to_tuple(y) - from mpmath.libmp import mpc_pow_mpf, fzero + from mpmath.libmp import mpc_pow_mpf vr, vi = mpc_pow_mpf((xret, ximt), yret, opts.prec, rndmode_to_python(opts.rounding)) MPF_set_tuple(zre, vr) diff --git a/src/sage/libs/mpmath/ext_main.pyx b/src/sage/libs/mpmath/ext_main.pyx index e2cb779dd4d..237a6aa0cc3 100644 --- a/src/sage/libs/mpmath/ext_main.pyx +++ b/src/sage/libs/mpmath/ext_main.pyx @@ -480,7 +480,7 @@ cdef class Context: 100 sage: mp.prec = 53 """ - return libmp.prec_to_dps(global_opts.prec) + return prec_to_dps(global_opts.prec) dps = property(_get_dps, _set_dps, doc=_get_dps.__doc__) prec = property(_get_prec, _set_prec, doc=_get_dps.__doc__) diff --git a/src/sage/libs/ntl/ntl_GF2.pyx b/src/sage/libs/ntl/ntl_GF2.pyx index d6ada6cb100..7bbdaa09d05 100644 --- a/src/sage/libs/ntl/ntl_GF2.pyx +++ b/src/sage/libs/ntl/ntl_GF2.pyx @@ -5,7 +5,7 @@ # distutils: extra_link_args = NTL_LIBEXTRA # distutils: language = c++ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 Martin Albrecht # # Distributed under the terms of the GNU General Public License (GPL) @@ -17,10 +17,9 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** -from cysignals.signals cimport sig_on, sig_off from sage.ext.cplusplus cimport ccrepr, ccreadstr include 'misc.pxi' @@ -28,7 +27,6 @@ include 'decl.pxi' from cpython.object cimport Py_EQ, Py_NE from sage.rings.integer cimport Integer -from sage.rings.integer_ring cimport IntegerRing_class ############################################################################## # GF2: Bits diff --git a/src/sage/libs/ntl/ntl_GF2E.pyx b/src/sage/libs/ntl/ntl_GF2E.pyx index 54c7eef492a..c78fd6704db 100644 --- a/src/sage/libs/ntl/ntl_GF2E.pyx +++ b/src/sage/libs/ntl/ntl_GF2E.pyx @@ -33,7 +33,7 @@ from .ntl_GF2X cimport ntl_GF2X from .ntl_GF2EContext cimport ntl_GF2EContext_class from .ntl_GF2EContext import ntl_GF2EContext from sage.libs.ntl.ntl_ZZ import unpickle_class_args -from sage.misc.randstate cimport randstate, current_randstate +from sage.misc.randstate cimport current_randstate ############################################################################## diff --git a/src/sage/libs/ntl/ntl_GF2X.pyx b/src/sage/libs/ntl/ntl_GF2X.pyx index d4581467952..787169e6dc7 100644 --- a/src/sage/libs/ntl/ntl_GF2X.pyx +++ b/src/sage/libs/ntl/ntl_GF2X.pyx @@ -21,7 +21,6 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from cysignals.signals cimport sig_on, sig_off from sage.ext.cplusplus cimport ccrepr, ccreadstr include 'misc.pxi' @@ -29,7 +28,6 @@ include 'decl.pxi' from cpython.object cimport Py_EQ, Py_NE from sage.rings.integer cimport Integer -from sage.misc.superseded import deprecation_cython as deprecation from .ntl_ZZ import unpickle_class_value from .ntl_GF2 cimport ntl_GF2 diff --git a/src/sage/libs/ntl/ntl_ZZ.pyx b/src/sage/libs/ntl/ntl_ZZ.pyx index 8786675e6b9..41e14fdcf09 100644 --- a/src/sage/libs/ntl/ntl_ZZ.pyx +++ b/src/sage/libs/ntl/ntl_ZZ.pyx @@ -28,9 +28,8 @@ include 'decl.pxi' from sage.rings.integer cimport Integer from sage.libs.ntl.convert cimport PyLong_to_ZZ, mpz_to_ZZ -from sage.misc.randstate cimport randstate, current_randstate +from sage.misc.randstate cimport current_randstate from cpython.object cimport Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, Py_GE -from cpython.int cimport PyInt_AS_LONG cdef make_ZZ(ZZ_c* x): diff --git a/src/sage/libs/ntl/ntl_ZZX.pyx b/src/sage/libs/ntl/ntl_ZZX.pyx index e369f7152e4..891a28d0fb1 100644 --- a/src/sage/libs/ntl/ntl_ZZX.pyx +++ b/src/sage/libs/ntl/ntl_ZZX.pyx @@ -32,10 +32,7 @@ from cpython.object cimport Py_EQ, Py_NE from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ from sage.libs.ntl.ntl_ZZ import unpickle_class_value -from sage.rings.integer import Integer from sage.rings.integer_ring import IntegerRing -from sage.rings.integer cimport Integer -from sage.rings.integer_ring cimport IntegerRing_class from sage.arith.power cimport generic_power_pos ZZ = IntegerRing() diff --git a/src/sage/libs/ntl/ntl_ZZ_p.pyx b/src/sage/libs/ntl/ntl_ZZ_p.pyx index b5511abb891..d032d9b81b9 100644 --- a/src/sage/libs/ntl/ntl_ZZ_p.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_p.pyx @@ -17,7 +17,7 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** from cysignals.signals cimport sig_on, sig_off @@ -32,7 +32,6 @@ from sage.rings.integer_ring import IntegerRing from sage.rings.integer cimport Integer from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ from sage.rings.rational cimport Rational -from sage.rings.integer_ring cimport IntegerRing_class from sage.libs.ntl.ntl_ZZ import unpickle_class_args from sage.libs.ntl.convert cimport PyLong_to_ZZ, mpz_to_ZZ @@ -40,7 +39,7 @@ from sage.libs.ntl.convert cimport PyLong_to_ZZ, mpz_to_ZZ from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext -from sage.misc.randstate cimport randstate, current_randstate +from sage.misc.randstate cimport current_randstate ZZ_sage = IntegerRing() diff --git a/src/sage/libs/ntl/ntl_ZZ_pE.pyx b/src/sage/libs/ntl/ntl_ZZ_pE.pyx index ed45e34f0be..790d5c59648 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pE.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pE.pyx @@ -28,19 +28,13 @@ include 'decl.pxi' from cpython.object cimport Py_EQ, Py_NE -from sage.rings.integer import Integer from sage.rings.integer_ring import IntegerRing from sage.rings.integer cimport Integer from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p from sage.rings.integer cimport Integer -from sage.rings.integer_ring cimport IntegerRing_class from sage.libs.ntl.convert cimport PyLong_to_ZZ, mpz_to_ZZ -from sage.libs.ntl.ntl_ZZ import unpickle_class_args - -from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class -from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext from sage.libs.ntl.ntl_ZZ_pEContext cimport ntl_ZZ_pEContext_class from sage.libs.ntl.ntl_ZZ_pEContext import ntl_ZZ_pEContext diff --git a/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx b/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx index b6ff3c66b01..fca10d5667f 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx @@ -17,7 +17,7 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** include 'misc.pxi' @@ -25,8 +25,6 @@ include 'decl.pxi' from sage.ext.cplusplus cimport ccrepr from sage.libs.ntl.ntl_ZZ_pX cimport ntl_ZZ_pX -from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext -from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ ZZ_pEContextDict = {} diff --git a/src/sage/libs/ntl/ntl_ZZ_pEX.pyx b/src/sage/libs/ntl/ntl_ZZ_pEX.pyx index d5f10218a77..7d2d4bae905 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEX.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pEX.pyx @@ -36,14 +36,10 @@ include 'misc.pxi' include 'decl.pxi' from cpython.object cimport Py_EQ, Py_NE -from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ -from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p from sage.libs.ntl.ntl_ZZ_pE cimport ntl_ZZ_pE -from sage.libs.ntl.ntl_ZZ_pX cimport ntl_ZZ_pX from sage.libs.ntl.ntl_ZZ_pEContext cimport ntl_ZZ_pEContext_class from sage.libs.ntl.ntl_ZZ_pEContext import ntl_ZZ_pEContext from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class -from sage.libs.ntl.ntl_ZZ import unpickle_class_args from sage.arith.power cimport generic_power_pos ############################################################################## diff --git a/src/sage/libs/ntl/ntl_ZZ_pX.pyx b/src/sage/libs/ntl/ntl_ZZ_pX.pyx index 5021846b1e0..a8c0666ebc3 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pX.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pX.pyx @@ -34,7 +34,7 @@ from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext from sage.libs.ntl.ntl_ZZ import unpickle_class_args -from sage.misc.randstate cimport randstate, current_randstate +from sage.misc.randstate cimport current_randstate from sage.libs.gmp.mpz cimport * diff --git a/src/sage/libs/ntl/ntl_lzz_p.pyx b/src/sage/libs/ntl/ntl_lzz_p.pyx index 983e3056404..161d0782bc2 100644 --- a/src/sage/libs/ntl/ntl_lzz_p.pyx +++ b/src/sage/libs/ntl/ntl_lzz_p.pyx @@ -43,7 +43,6 @@ from cpython.object cimport Py_EQ, Py_NE from sage.rings.integer import Integer from sage.rings.integer_ring import IntegerRing from sage.rings.integer cimport Integer -from sage.rings.integer_ring cimport IntegerRing_class from sage.rings.finite_rings.integer_mod cimport IntegerMod_gmp, IntegerMod_int, IntegerMod_int64 diff --git a/src/sage/libs/ntl/ntl_lzz_pX.pyx b/src/sage/libs/ntl/ntl_lzz_pX.pyx index 98bd0d58658..24b503a9a62 100644 --- a/src/sage/libs/ntl/ntl_lzz_pX.pyx +++ b/src/sage/libs/ntl/ntl_lzz_pX.pyx @@ -34,7 +34,6 @@ from cpython.object cimport Py_EQ, Py_NE from sage.rings.integer import Integer from sage.rings.integer_ring import IntegerRing from sage.rings.integer cimport Integer -from sage.rings.integer_ring cimport IntegerRing_class from sage.rings.finite_rings.integer_mod cimport IntegerMod_gmp, IntegerMod_int, IntegerMod_int64 diff --git a/src/sage/libs/pari/convert_flint.pyx b/src/sage/libs/pari/convert_flint.pyx index 4c4be33ccef..07dd6cfc3dd 100644 --- a/src/sage/libs/pari/convert_flint.pyx +++ b/src/sage/libs/pari/convert_flint.pyx @@ -9,19 +9,19 @@ AUTHORS: generic C-interface in ``Pari`` (:trac:`20241`) """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2016 Luca De Feo # # 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/ +# **************************************************************************** from cysignals.signals cimport sig_on -from sage.libs.flint.fmpz cimport fmpz_get_mpz, COEFF_IS_MPZ, COEFF_TO_PTR, fmpz_is_one +from sage.libs.flint.fmpz cimport COEFF_IS_MPZ, COEFF_TO_PTR, fmpz_is_one from sage.libs.flint.fmpq cimport fmpq_numref, fmpq_denref from sage.libs.flint.fmpz_mat cimport fmpz_mat_nrows, fmpz_mat_ncols, fmpz_mat_entry from sage.libs.flint.fmpq_mat cimport fmpq_mat_nrows, fmpq_mat_ncols, fmpq_mat_entry diff --git a/src/sage/libs/pari/convert_gmp.pyx b/src/sage/libs/pari/convert_gmp.pyx index a39caa379b4..fcd212a8703 100644 --- a/src/sage/libs/pari/convert_gmp.pyx +++ b/src/sage/libs/pari/convert_gmp.pyx @@ -17,10 +17,10 @@ AUTHORS: # 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/ #***************************************************************************** -from cysignals.signals cimport sig_on, sig_off +from cysignals.signals cimport sig_on from sage.libs.gmp.all cimport * diff --git a/src/sage/libs/pari/convert_sage.pyx b/src/sage/libs/pari/convert_sage.pyx index 1d1db834f6e..71a1744698e 100644 --- a/src/sage/libs/pari/convert_sage.pyx +++ b/src/sage/libs/pari/convert_sage.pyx @@ -2,7 +2,7 @@ r""" Convert PARI objects to Sage types """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2016 Jeroen Demeyer # Copyright (C) 2016 Luca De Feo # Copyright (C) 2016 Vincent Delecroix @@ -11,8 +11,8 @@ Convert PARI objects to Sage types # 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/ +# **************************************************************************** from cysignals.signals cimport sig_on, sig_off @@ -20,9 +20,7 @@ from cypari2.types cimport (GEN, typ, t_INT, t_FRAC, t_REAL, t_COMPLEX, t_INTMOD, t_PADIC, t_INFINITY, t_VEC, t_COL, t_VECSMALL, t_MAT, t_STR, lg, precp) -from cypari2.pari_instance cimport prec_words_to_bits from cypari2.paridecl cimport * -from cypari2.gen cimport objtogen from cypari2.stack cimport new_gen from .convert_gmp cimport INT_to_mpz, new_gen_from_mpz_t, new_gen_from_mpq_t, INTFRAC_to_mpq diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index 229f6695e09..411b5eae678 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -93,11 +93,11 @@ from sage.rings.polynomial.plural cimport NCPolynomialRing_plural, NCPolynomial_ from sage.rings.polynomial.multi_polynomial_ideal import NCPolynomialIdeal from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal from sage.rings.polynomial.multi_polynomial_ideal_libsingular cimport sage_ideal_to_singular_ideal, singular_ideal_to_sage_sequence -from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence, PolynomialSequence_generic +from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence_generic from sage.libs.singular.decl cimport * from sage.libs.singular.option import opt_ctx -from sage.libs.singular.polynomial cimport singular_vector_maximal_component, singular_polynomial_check +from sage.libs.singular.polynomial cimport singular_vector_maximal_component from sage.libs.singular.singular cimport sa2si, si2sa, si2sa_intvec from sage.libs.singular.singular import error_messages diff --git a/src/sage/libs/singular/option.pyx b/src/sage/libs/singular/option.pyx index fc3b576ff71..d35415c2864 100644 --- a/src/sage/libs/singular/option.pyx +++ b/src/sage/libs/singular/option.pyx @@ -93,12 +93,12 @@ AUTHOR: - Martin Albrecht (2010-01): better interface, verbosity options - Simon King (2010-07): Python-ic option names; deg_bound and mult_bound """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010 Martin Albrecht # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.libs.singular.decl cimport singular_options, singular_verbose_options, Kstd1_deg, Kstd1_mu @@ -108,7 +108,7 @@ from sage.libs.singular.decl cimport OPT_WEIGHTM, Sy_bit from sage.libs.singular.decl cimport V_SHOW_MEM, V_YACC, V_REDEFINE, V_READING, V_LOAD_LIB, V_DEBUG_LIB from sage.libs.singular.decl cimport V_LOAD_PROC, V_DEF_RES, V_SHOW_USE, V_IMAP, V_PROMPT -from sage.libs.singular.decl cimport V_NSB, V_CONTENTSB, V_CANCELUNIT, V_DEG_STOP +from sage.libs.singular.decl cimport V_NSB, V_CONTENTSB, V_CANCELUNIT _options_py_to_singular={'return_sb':'returnSB', 'fast_hc':'fastHC', diff --git a/src/sage/libs/singular/polynomial.pyx b/src/sage/libs/singular/polynomial.pyx index 1a6dad39a6b..9f81a20b0a7 100644 --- a/src/sage/libs/singular/polynomial.pyx +++ b/src/sage/libs/singular/polynomial.pyx @@ -32,7 +32,7 @@ from sage.libs.singular.decl cimport p_Copy, p_Add_q, p_Neg, pp_Mult_nn, p_GetCo from sage.libs.singular.decl cimport p_GetMaxExp, pp_Mult_qq, pPower, p_String, p_GetExp, p_LDeg from sage.libs.singular.decl cimport n_Delete, idInit, fast_map_common_subexp, id_Delete from sage.libs.singular.decl cimport omAlloc0, omStrDup, omFree -from sage.libs.singular.decl cimport p_GetComp, p_SetComp +from sage.libs.singular.decl cimport p_GetComp from sage.libs.singular.decl cimport pSubst from sage.libs.singular.decl cimport p_Normalize from sage.libs.singular.decl cimport ndCopyMap, maMapPoly diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index 04bd16e8784..56dc364219c 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -9,30 +9,28 @@ AUTHORS: - Miguel Marco (2021): added transcendental extensions over Q """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2009 Martin Albrecht # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.cpython.string cimport str_to_bytes from sage.libs.gmp.types cimport __mpz_struct -from sage.libs.gmp.mpz cimport mpz_init_set_ui, mpz_init_set +from sage.libs.gmp.mpz cimport mpz_init_set_ui -from sage.libs.singular.decl cimport number, poly, ring, currRing -from sage.libs.singular.decl cimport rChangeCurrRing, rCopy0, rComplete, rDelete, idInit -from sage.libs.singular.decl cimport omAlloc0, omStrDup, omAlloc, omAlloc0Bin, sip_sring_bin, rnumber_bin +from sage.libs.singular.decl cimport ring, currRing +from sage.libs.singular.decl cimport rChangeCurrRing, rComplete, rDelete, idInit +from sage.libs.singular.decl cimport omAlloc0, omStrDup, omAlloc from sage.libs.singular.decl cimport ringorder_dp, ringorder_Dp, ringorder_lp, ringorder_rp, ringorder_ds, ringorder_Ds, ringorder_ls, ringorder_M, ringorder_c, ringorder_C, ringorder_wp, ringorder_Wp, ringorder_ws, ringorder_Ws, ringorder_a, rRingOrder_t -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, TransExtInfo +from sage.libs.singular.decl cimport prCopyR +from sage.libs.singular.decl cimport n_unknown, n_algExt, n_transExt, n_Z, n_Zn, n_Znm, n_Z2m +from sage.libs.singular.decl cimport n_coeffType +from sage.libs.singular.decl cimport rDefault, GFInfo, ZnmInfo, nInitChar, AlgExtInfo, TransExtInfo - -from sage.rings.integer cimport Integer from sage.rings.integer_ring cimport IntegerRing_class from sage.rings.integer_ring import ZZ import sage.rings.abc @@ -46,7 +44,7 @@ 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 sage.rings.fraction_field import FractionField_generic from cpython.object cimport Py_EQ, Py_NE diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 8924789c141..f357ce611c9 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -37,18 +37,17 @@ 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.fraction_field import FractionField_generic 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 -from sage.libs.pari.all import pari 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, MPolynomialRing_libsingular +from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular ctypedef struct fraction "fractionObject": poly *numerator diff --git a/src/sage/logic/logicparser.py b/src/sage/logic/logicparser.py index b854f416127..7c234f2ff7e 100644 --- a/src/sage/logic/logicparser.py +++ b/src/sage/logic/logicparser.py @@ -158,7 +158,7 @@ def polish_parse(s): raise SyntaxError("malformed statement") toks, vars_order = tokenize(s) - tree = tree_parse(toks, polish = True) + tree = tree_parse(toks, polish=True) # special case where the formula s is a single variable if isinstance(tree, str): return vars_order @@ -568,7 +568,7 @@ def tree_parse(toks, polish=False): while tok != '(': tok = stack.pop() lrtoks.insert(0, tok) - branch = parse_ltor(lrtoks[1:-1], polish = polish) + branch = parse_ltor(lrtoks[1:-1], polish=polish) stack.append(branch) return stack[0] @@ -643,7 +643,7 @@ def parse_ltor(toks, n=0, polish=False): toks[j - 1] = args del toks[j] j -= 1 - return parse_ltor(toks, n = n, polish = polish) + return parse_ltor(toks, n=n, polish=polish) else: args = [toks[i - 1], toks[i], toks[i + 1]] toks[i - 1] = [args[1], args[0], args[2]] diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 995d085573d..5de43333072 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -170,6 +170,8 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: type(matrix(SR, 2, 2, 0)) + sage: type(matrix(SR, 2, 2, 0, sparse=True)) + sage: type(matrix(GF(7), 2, range(4))) sage: type(matrix(GF(16007), 2, range(4))) @@ -400,6 +402,18 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): if isinstance(R, (sage.rings.abc.RealDoubleField, sage.rings.abc.ComplexDoubleField)): from . import matrix_double_sparse return matrix_double_sparse.Matrix_double_sparse + try: + from sage.symbolic.ring import SR + except ImportError: + pass + else: + if R is SR: + try: + from . import matrix_symbolic_sparse + except ImportError: + pass + else: + return matrix_symbolic_sparse.Matrix_symbolic_sparse # the fallback from sage.matrix.matrix_generic_sparse import Matrix_generic_sparse diff --git a/src/sage/matrix/matrix_symbolic_dense.pyx b/src/sage/matrix/matrix_symbolic_dense.pyx index 5a6fda44d57..0df43084de2 100644 --- a/src/sage/matrix/matrix_symbolic_dense.pyx +++ b/src/sage/matrix/matrix_symbolic_dense.pyx @@ -1,5 +1,5 @@ """ -Symbolic matrices +Symbolic dense matrices EXAMPLES:: diff --git a/src/sage/matrix/matrix_symbolic_sparse.pxd b/src/sage/matrix/matrix_symbolic_sparse.pxd new file mode 100644 index 00000000000..897754c837d --- /dev/null +++ b/src/sage/matrix/matrix_symbolic_sparse.pxd @@ -0,0 +1,4 @@ +from .matrix_generic_sparse cimport Matrix_generic_sparse + +cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): + pass diff --git a/src/sage/matrix/matrix_symbolic_sparse.pyx b/src/sage/matrix/matrix_symbolic_sparse.pyx new file mode 100644 index 00000000000..c03dba4e109 --- /dev/null +++ b/src/sage/matrix/matrix_symbolic_sparse.pyx @@ -0,0 +1,1035 @@ +""" +Symbolic sparse matrices + +EXAMPLES:: + + sage: matrix(SR, 2, 2, range(4), sparse=True) + [0 1] + [2 3] + sage: matrix(SR, 2, 2, var('t'), sparse=True) + [t 0] + [0 t] + +Arithmetic:: + + sage: -matrix(SR, 2, range(4), sparse=True) + [ 0 -1] + [-2 -3] + sage: m = matrix(SR, 2, [1..4], sparse=True); sqrt(2)*m + [ sqrt(2) 2*sqrt(2)] + [3*sqrt(2) 4*sqrt(2)] + sage: m = matrix(SR, 4, [1..4^2], sparse=True) + sage: m * m + [ 90 100 110 120] + [202 228 254 280] + [314 356 398 440] + [426 484 542 600] + + sage: m = matrix(SR, 3, [1, 2, 3], sparse=True); m + [1] + [2] + [3] + sage: m.transpose() * m + [14] + +Computing inverses:: + + sage: M = matrix(SR, 2, var('a,b,c,d'), sparse=True) + sage: ~M + [1/a - b*c/(a^2*(b*c/a - d)) b/(a*(b*c/a - d))] + [ c/(a*(b*c/a - d)) -1/(b*c/a - d)] + sage: (~M*M).simplify_rational() + [1 0] + [0 1] + sage: M = matrix(SR, 3, 3, range(9), sparse=True) - var('t') + sage: (~M * M).simplify_rational() + [1 0 0] + [0 1 0] + [0 0 1] + + sage: matrix(SR, 1, 1, 1, sparse=True).inverse() + [1] + sage: matrix(SR, 0, 0, sparse=True).inverse() + [] + sage: matrix(SR, 3, 0, sparse=True).inverse() + Traceback (most recent call last): + ... + ArithmeticError: self must be a square matrix + +Transposition:: + + sage: m = matrix(SR, 2, [sqrt(2), -1, pi, e^2], sparse=True) + sage: m.transpose() + [sqrt(2) pi] + [ -1 e^2] + +``.T`` is a convenient shortcut for the transpose:: + + sage: m.T + [sqrt(2) pi] + [ -1 e^2] + +Test pickling:: + + sage: m = matrix(SR, 2, [sqrt(2), 3, pi, e], sparse=True); m + [sqrt(2) 3] + [ pi e] + sage: TestSuite(m).run() + +Comparison:: + + sage: m = matrix(SR, 2, [sqrt(2), 3, pi, e], sparse=True) + sage: m == m + True + sage: m != 3 + True + sage: m = matrix(SR,2,[1..4], sparse=True); n = m^2 + sage: (exp(m+n) - exp(m)*exp(n)).simplify_rational() == 0 # indirect test + True + + +Determinant:: + + sage: M = matrix(SR, 2, 2, [x,2,3,4], sparse=True) + sage: M.determinant() + 4*x - 6 + sage: M = matrix(SR, 3,3,range(9), sparse=True) + sage: M.det() + 0 + sage: t = var('t') + sage: M = matrix(SR, 2, 2, [cos(t), sin(t), -sin(t), cos(t)], sparse=True) + sage: M.det() + cos(t)^2 + sin(t)^2 + sage: M = matrix([[sqrt(x),0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]], sparse=True) + sage: det(M) + sqrt(x) + +Permanents:: + + sage: M = matrix(SR, 2, 2, [x,2,3,4], sparse=True) + sage: M.permanent() + 4*x + 6 + +Rank:: + + sage: M = matrix(SR, 5, 5, range(25), sparse=True) + sage: M.rank() + 2 + sage: M = matrix(SR, 5, 5, range(25), sparse=True) - var('t') + sage: M.rank() + 5 + + .. warning:: + + :meth:`rank` may return the wrong answer if it cannot determine that a + matrix element that is equivalent to zero is indeed so. + +Copying symbolic matrices:: + + sage: m = matrix(SR, 2, [sqrt(2), 3, pi, e], sparse=True) + sage: n = copy(m) + sage: n[0,0] = sin(1) + sage: m + [sqrt(2) 3] + [ pi e] + sage: n + [sin(1) 3] + [ pi e] + +Conversion to Maxima:: + + sage: m = matrix(SR, 2, [sqrt(2), 3, pi, e], sparse=True) + sage: m._maxima_() + matrix([sqrt(2),3],[%pi,%e]) + +TESTS: + +Check that :trac:`12778` is fixed:: + + sage: M = Matrix([[1, 0.9, 1/5, x^2], [2, 1.9, 2/5, x^3], [3, 2.9, 3/5, x^4]], sparse=True); M + [ 1 0.900000000000000 1/5 x^2] + [ 2 1.90000000000000 2/5 x^3] + [ 3 2.90000000000000 3/5 x^4] + sage: parent(M) + Full MatrixSpace of 3 by 4 sparse matrices over Symbolic Ring + +Check that :issue:`35653` is fixed:: + + sage: diagonal_matrix([x]).inverse() + [1/x] + sage: M = MatrixSpace(SR,2,2,sparse=True) + sage: M([[x,0],[0,x]]).inverse() + [1/x 0] + [ 0 1/x] +""" +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.structure.element cimport ModuleElement, RingElement, Element +from sage.structure.factorization import Factorization + +from .matrix_generic_sparse cimport Matrix_generic_sparse +from .constructor import matrix + +cdef maxima + +from sage.calculus.calculus import symbolic_expression_from_maxima_string, maxima + +cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): + def echelonize(self, **kwds): + """ + Echelonize using the classical algorithm. + + + TESTS:: + + sage: m = matrix([[cos(pi/5), sin(pi/5)], [-sin(pi/5), cos(pi/5)]], sparse=True) + sage: m.echelonize(); m + [1 0] + [0 1] + """ + return super().echelonize(algorithm="classical", **kwds) + + def eigenvalues(self, extend=True): + """ + Compute the eigenvalues by solving the characteristic + polynomial in maxima. + + The argument ``extend`` is ignored but kept for compatibility with + other matrix classes. + + EXAMPLES:: + + sage: a=matrix(SR,[[1,2],[3,4]], sparse=True) + sage: a.eigenvalues() + [-1/2*sqrt(33) + 5/2, 1/2*sqrt(33) + 5/2] + + TESTS: + + Check for :trac:`31700`:: + + sage: m = matrix([[cos(pi/5), sin(pi/5)], [-sin(pi/5), cos(pi/5)]], sparse=True) + sage: t = linear_transformation(m) + sage: t.eigenvalues() + [1/4*sqrt(5) - 1/4*sqrt(2*sqrt(5) - 10) + 1/4, + 1/4*sqrt(5) + 1/4*sqrt(2*sqrt(5) - 10) + 1/4] + """ + maxima_evals = self._maxima_(maxima).eigenvalues()._sage_() + if not len(maxima_evals): + raise ArithmeticError("could not determine eigenvalues exactly using symbolic matrices; try using a different type of matrix via self.change_ring(), if possible") + return sum([[ev] * int(mult) for ev, mult in zip(*maxima_evals)], []) + + def eigenvectors_left(self, other=None): + r""" + Compute the left eigenvectors of a matrix. + + INPUT: + + - ``other`` -- a square matrix `B` (default: ``None``) in a generalized + eigenvalue problem; if ``None``, an ordinary eigenvalue problem is + solved (currently supported only if the base ring of ``self`` is + ``RDF`` or ``CDF``) + + OUTPUT: + + For each distinct eigenvalue, returns a list of the form (e,V,n) + where e is the eigenvalue, V is a list of eigenvectors forming a + basis for the corresponding left eigenspace, and n is the + algebraic multiplicity of the eigenvalue. + + EXAMPLES:: + + sage: A = matrix(SR,3,3,range(9), sparse=True); A + [0 1 2] + [3 4 5] + [6 7 8] + sage: es = A.eigenvectors_left(); es + [(-3*sqrt(6) + 6, [(1, -1/5*sqrt(6) + 4/5, -2/5*sqrt(6) + 3/5)], 1), + (3*sqrt(6) + 6, [(1, 1/5*sqrt(6) + 4/5, 2/5*sqrt(6) + 3/5)], 1), + (0, [(1, -2, 1)], 1)] + sage: eval, [evec], mult = es[0] + sage: delta = eval*evec - evec*A + sage: abs(abs(delta)) < 1e-10 + 3/5*sqrt(((2*sqrt(6) - 3)*(sqrt(6) - 2) + 7*sqrt(6) - 18)^2 + ((sqrt(6) - 2)*(sqrt(6) - 4) + 6*sqrt(6) - 14)^2) < (1.00000000000000e-10) + sage: abs(abs(delta)).n() < 1e-10 + True + + :: + + sage: A = matrix(SR, 2, 2, var('a,b,c,d'), sparse=True) + sage: A.eigenvectors_left() + [(1/2*a + 1/2*d - 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2), [(1, -1/2*(a - d + sqrt(a^2 + 4*b*c - 2*a*d + d^2))/c)], 1), (1/2*a + 1/2*d + 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2), [(1, -1/2*(a - d - sqrt(a^2 + 4*b*c - 2*a*d + d^2))/c)], 1)] + sage: es = A.eigenvectors_left(); es + [(1/2*a + 1/2*d - 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2), [(1, -1/2*(a - d + sqrt(a^2 + 4*b*c - 2*a*d + d^2))/c)], 1), (1/2*a + 1/2*d + 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2), [(1, -1/2*(a - d - sqrt(a^2 + 4*b*c - 2*a*d + d^2))/c)], 1)] + sage: eval, [evec], mult = es[0] + sage: delta = eval*evec - evec*A + sage: delta.apply_map(lambda x: x.full_simplify()) + (0, 0) + + This routine calls Maxima and can struggle with even small matrices + with a few variables, such as a `3\times 3` matrix with three variables. + However, if the entries are integers or rationals it can produce exact + values in a reasonable time. These examples create 0-1 matrices from + the adjacency matrices of graphs and illustrate how the format and type + of the results differ when the base ring changes. First for matrices + over the rational numbers, then the same matrix but viewed as a symbolic + matrix. :: + + sage: G=graphs.CycleGraph(5) + sage: am = G.adjacency_matrix(sparse=True) + sage: spectrum = am.eigenvectors_left() + sage: qqbar_evalue = spectrum[2][0] + sage: type(qqbar_evalue) + + sage: qqbar_evalue + 0.618033988749895? + + sage: am = G.adjacency_matrix(sparse=True).change_ring(SR) + sage: spectrum = am.eigenvectors_left() + sage: symbolic_evalue = spectrum[2][0] + sage: type(symbolic_evalue) + + sage: symbolic_evalue + 1/2*sqrt(5) - 1/2 + + sage: bool(qqbar_evalue == symbolic_evalue) + True + + A slightly larger matrix with a "nice" spectrum. :: + + sage: G = graphs.CycleGraph(6) + sage: am = G.adjacency_matrix(sparse=True).change_ring(SR) + sage: am.eigenvectors_left() + [(-1, [(1, 0, -1, 1, 0, -1), (0, 1, -1, 0, 1, -1)], 2), (1, [(1, 0, -1, -1, 0, 1), (0, 1, 1, 0, -1, -1)], 2), (-2, [(1, -1, 1, -1, 1, -1)], 1), (2, [(1, 1, 1, 1, 1, 1)], 1)] + + TESTS:: + + sage: A = matrix(SR, [[1, 2], [3, 4]], sparse=True) + sage: B = matrix(SR, [[1, 1], [0, 1]], sparse=True) + sage: A.eigenvectors_left(B) + Traceback (most recent call last): + ... + NotImplementedError: generalized eigenvector decomposition is + implemented for RDF and CDF, but not for Symbolic Ring + + Check that :trac:`23332` is fixed:: + + sage: matrix([[x, x^2], [1, 0]], sparse=True).eigenvectors_left() + [(-1/2*x*(sqrt(5) - 1), [(1, -1/2*x*(sqrt(5) + 1))], 1), + (1/2*x*(sqrt(5) + 1), [(1, 1/2*x*(sqrt(5) - 1))], 1)] + """ + if other is not None: + raise NotImplementedError('generalized eigenvector decomposition ' + 'is implemented for RDF and CDF, but ' + 'not for %s' % self.base_ring()) + + from sage.modules.free_module_element import vector + from sage.rings.integer_ring import ZZ + + [evals, mults], evecs = self.transpose()._maxima_(maxima).eigenvectors()._sage_() + result = [] + for e, evec, m in zip(evals, evecs, mults): + result.append((e, [vector(v) for v in evec], ZZ(m))) + + return result + + def eigenvectors_right(self, other=None): + r""" + Compute the right eigenvectors of a matrix. + + INPUT: + + - ``other`` -- a square matrix `B` (default: ``None``) in a generalized + eigenvalue problem; if ``None``, an ordinary eigenvalue problem is + solved (currently supported only if the base ring of ``self`` is + ``RDF`` or ``CDF``) + + OUTPUT: + + For each distinct eigenvalue, returns a list of the form (e,V,n) + where e is the eigenvalue, V is a list of eigenvectors forming a + basis for the corresponding right eigenspace, and n is the + algebraic multiplicity of the eigenvalue. + + EXAMPLES:: + + sage: A = matrix(SR,2,2,range(4), sparse=True); A + [0 1] + [2 3] + sage: right = A.eigenvectors_right(); right + [(-1/2*sqrt(17) + 3/2, [(1, -1/2*sqrt(17) + 3/2)], 1), (1/2*sqrt(17) + 3/2, [(1, 1/2*sqrt(17) + 3/2)], 1)] + + The right eigenvectors are nothing but the left eigenvectors of the + transpose matrix:: + + sage: left = A.transpose().eigenvectors_left(); left + [(-1/2*sqrt(17) + 3/2, [(1, -1/2*sqrt(17) + 3/2)], 1), (1/2*sqrt(17) + 3/2, [(1, 1/2*sqrt(17) + 3/2)], 1)] + sage: right[0][1] == left[0][1] + True + + TESTS:: + + sage: A = matrix(SR, [[1, 2], [3, 4]], sparse=True) + sage: B = matrix(SR, [[1, 1], [0, 1]], sparse=True) + sage: A.eigenvectors_right(B) + Traceback (most recent call last): + ... + NotImplementedError: generalized eigenvector decomposition is + implemented for RDF and CDF, but not for Symbolic Ring + + Check that :trac:`23332` is fixed:: + + sage: matrix([[x, x^2], [1, 0]], sparse=True).eigenvectors_right() + [(-1/2*x*(sqrt(5) - 1), [(1, -1/2*(sqrt(5) + 1)/x)], 1), + (1/2*x*(sqrt(5) + 1), [(1, 1/2*(sqrt(5) - 1)/x)], 1)] + """ + return self.transpose().eigenvectors_left(other=other) + + def exp(self): + r""" + Return the matrix exponential of this matrix `X`, which is the matrix + + .. MATH:: + + e^X = \sum_{k=0}^{\infty} \frac{X^k}{k!}. + + This function depends on maxima's matrix exponentiation + function, which does not deal well with floating point + numbers. If the matrix has floating point numbers, they will + be rounded automatically to rational numbers during the + computation. + + EXAMPLES:: + + sage: m = matrix(SR,2, [0,x,x,0], sparse=True); m + [0 x] + [x 0] + sage: m.exp() + [1/2*(e^(2*x) + 1)*e^(-x) 1/2*(e^(2*x) - 1)*e^(-x)] + [1/2*(e^(2*x) - 1)*e^(-x) 1/2*(e^(2*x) + 1)*e^(-x)] + sage: exp(m) + [1/2*(e^(2*x) + 1)*e^(-x) 1/2*(e^(2*x) - 1)*e^(-x)] + [1/2*(e^(2*x) - 1)*e^(-x) 1/2*(e^(2*x) + 1)*e^(-x)] + + Exponentiation works on 0x0 and 1x1 matrices, but the 1x1 example + requires a patched version of maxima (:trac:`32898`) for now:: + + sage: m = matrix(SR,0,[], sparse=True); m + [] + sage: m.exp() + [] + sage: m = matrix(SR,1,[2], sparse=True); m + [2] + sage: m.exp() # not tested, requires patched maxima + [e^2] + + Commuting matrices `m, n` have the property that + `e^{m+n} = e^m e^n` (but non-commuting matrices need not):: + + sage: m = matrix(SR,2,[1..4], sparse=True); n = m^2 + sage: m*n + [ 37 54] + [ 81 118] + sage: n*m + [ 37 54] + [ 81 118] + + sage: a = exp(m+n) - exp(m)*exp(n) + sage: a.simplify_rational() == 0 + True + + The input matrix must be square:: + + sage: m = matrix(SR,2,3,[1..6], sparse=True); exp(m) + Traceback (most recent call last): + ... + ValueError: exp only defined on square matrices + + In this example we take the symbolic answer and make it + numerical at the end:: + + sage: exp(matrix(SR, [[1.2, 5.6], [3,4]], sparse=True)).change_ring(RDF) # rel tol 1e-15 + [ 346.5574872980695 661.7345909344504] + [354.50067371488416 677.4247827652946] + + Another example involving the reversed identity matrix, which + we clumsily create:: + + sage: m = identity_matrix(SR,4, sparse=True) + sage: m = matrix(list(reversed(m.rows())), sparse=True) * x + sage: exp(m) + [1/2*(e^(2*x) + 1)*e^(-x) 0 0 1/2*(e^(2*x) - 1)*e^(-x)] + [ 0 1/2*(e^(2*x) + 1)*e^(-x) 1/2*(e^(2*x) - 1)*e^(-x) 0] + [ 0 1/2*(e^(2*x) - 1)*e^(-x) 1/2*(e^(2*x) + 1)*e^(-x) 0] + [1/2*(e^(2*x) - 1)*e^(-x) 0 0 1/2*(e^(2*x) + 1)*e^(-x)] + """ + if not self.is_square(): + raise ValueError("exp only defined on square matrices") + if self.nrows() == 0: + return self + # Maxima's matrixexp function chokes on floating point numbers + # so we automatically convert floats to rationals by passing + # keepfloat: false + m = self._maxima_(maxima) + z = maxima('matrixexp(%s), keepfloat: false' % m.name()) + if self.nrows() == 1: + # We do the following, because Maxima stupidly exp's 1x1 + # matrices into non-matrices! + z = maxima('matrix([%s])' % z.name()) + + return z._sage_() + + def charpoly(self, var='x', algorithm=None): + r""" + Compute the characteristic polynomial of ``self``, using maxima. + + .. NOTE:: + + The characteristic polynomial is defined as `\det(xI-A)`. + + INPUT: + + - ``var`` -- (default: 'x') name of variable of charpoly + + EXAMPLES:: + + sage: M = matrix(SR, 2, 2, var('a,b,c,d'), sparse=True) + sage: M.charpoly('t') + t^2 + (-a - d)*t - b*c + a*d + sage: matrix(SR, 5, [1..5^2], sparse=True).charpoly() + x^5 - 65*x^4 - 250*x^3 + + TESTS: + + The cached polynomial should be independent of the ``var`` + argument (:trac:`12292`). We check (indirectly) that the + second call uses the cached value by noting that its result is + not cached:: + + sage: M = MatrixSpace(SR, 2, sparse=True) + sage: A = M(range(0, 2^2)) + sage: type(A) + + sage: A.charpoly('x') + x^2 - 3*x - 2 + sage: A.charpoly('y') + y^2 - 3*y - 2 + sage: A._cache['charpoly'] + x^2 - 3*x - 2 + + Ensure the variable name of the polynomial does not conflict + with variables used within the matrix (:trac:`14403`):: + + sage: Matrix(SR, [[sqrt(x), x],[1,x]], sparse=True).charpoly().list() + [x^(3/2) - x, -x - sqrt(x), 1] + + Test that :trac:`13711` is fixed:: + + sage: matrix([[sqrt(2), -1], [pi, e^2]], sparse=True).charpoly() + x^2 + (-sqrt(2) - e^2)*x + pi + sqrt(2)*e^2 + + Test that :trac:`26427` is fixed:: + + sage: M = matrix(SR, 7, 7, SR.var('a', 49), sparse=True) + sage: M.charpoly().degree() # long time + 7 + """ + cache_key = 'charpoly' + cp = self.fetch(cache_key) + if cp is not None: + return cp.change_variable_name(var) + from sage.symbolic.ring import SR + + # We must not use a variable name already present in the matrix + vname = 'do_not_use_this_name_in_a_matrix_youll_compute_a_charpoly_of' + vsym = SR(vname) + + cp = self._maxima_(maxima).charpoly(vname)._sage_().expand() + cp = [cp.coefficient(vsym, i) for i in range(self.nrows() + 1)] + cp = SR[var](cp) + + # Maxima has the definition det(matrix-xI) instead of + # det(xI-matrix), which is what Sage uses elsewhere. We + # correct for the discrepancy. + if self.nrows() % 2 == 1: + cp = -cp + + self.cache(cache_key, cp) + return cp + + def minpoly(self, var='x'): + """ + Return the minimal polynomial of ``self``. + + EXAMPLES:: + + sage: M = Matrix.identity(SR, 2, sparse=True) + sage: M.minpoly() + x - 1 + + sage: t = var('t') + sage: m = matrix(2, [1, 2, 4, t], sparse=True) + sage: m.minimal_polynomial() + x^2 + (-t - 1)*x + t - 8 + + TESTS: + + Check that the variable `x` can occur in the matrix:: + + sage: m = matrix([[x]], sparse=True) + sage: m.minimal_polynomial('y') + y - x + + """ + mp = self.fetch('minpoly') + if mp is None: + mp = self._maxima_lib_().jordan().minimalPoly().expand() + d = mp.hipow('x') + mp = [mp.coeff('x', i) for i in xrange(int(d) + 1)] + mp = PolynomialRing(self.base_ring(), 'x')(mp) + self.cache('minpoly', mp) + return mp.change_variable_name(var) + + def fcp(self, var='x'): + """ + Return the factorization of the characteristic polynomial of ``self``. + + INPUT: + + - ``var`` -- (default: 'x') name of variable of charpoly + + EXAMPLES:: + + sage: a = matrix(SR,[[1,2],[3,4]], sparse=True) + sage: a.fcp() + x^2 - 5*x - 2 + sage: [i for i in a.fcp()] + [(x^2 - 5*x - 2, 1)] + sage: a = matrix(SR,[[1,0],[0,2]], sparse=True) + sage: a.fcp() + (x - 2) * (x - 1) + sage: [i for i in a.fcp()] + [(x - 2, 1), (x - 1, 1)] + sage: a = matrix(SR, 5, [1..5^2], sparse=True) + sage: a.fcp() + (x^2 - 65*x - 250) * x^3 + sage: list(a.fcp()) + [(x^2 - 65*x - 250, 1), (x, 3)] + + """ + from sage.symbolic.ring import SR + sub_dict = {var: SR.var(var)} + return Factorization(self.charpoly(var).subs(**sub_dict).factor_list()) + + def jordan_form(self, subdivide=True, transformation=False): + """ + Return a Jordan normal form of ``self``. + + INPUT: + + - ``self`` -- a square matrix + + - ``subdivide`` -- boolean (default: ``True``) + + - ``transformation`` -- boolean (default: ``False``) + + OUTPUT: + + If ``transformation`` is ``False``, only a Jordan normal form + (unique up to the ordering of the Jordan blocks) is returned. + Otherwise, a pair ``(J, P)`` is returned, where ``J`` is a + Jordan normal form and ``P`` is an invertible matrix such that + ``self`` equals ``P * J * P^(-1)``. + + If ``subdivide`` is ``True``, the Jordan blocks in the + returned matrix ``J`` are indicated by a subdivision in + the sense of :meth:`~sage.matrix.matrix2.subdivide`. + + EXAMPLES: + + We start with some examples of diagonalisable matrices:: + + sage: a,b,c,d = var('a,b,c,d') + sage: matrix([a], sparse=True).jordan_form() + [a] + sage: matrix([[a, 0], [1, d]], sparse=True).jordan_form(subdivide=True) + [d|0] + [-+-] + [0|a] + sage: matrix([[a, 0], [1, d]], sparse=True).jordan_form(subdivide=False) + [d 0] + [0 a] + sage: matrix([[a, x, x], [0, b, x], [0, 0, c]], sparse=True).jordan_form() + [c|0|0] + [-+-+-] + [0|b|0] + [-+-+-] + [0|0|a] + + In the following examples, we compute Jordan forms of some + non-diagonalisable matrices:: + + sage: matrix([[a, a], [0, a]], sparse=True).jordan_form() + [a 1] + [0 a] + sage: matrix([[a, 0, b], [0, c, 0], [0, 0, a]], sparse=True).jordan_form() + [c|0 0] + [-+---] + [0|a 1] + [0|0 a] + + The following examples illustrate the ``transformation`` flag. + Note that symbolic expressions may need to be simplified to + make consistency checks succeed:: + + sage: A = matrix([[x - a*c, a^2], [-c^2, x + a*c]], sparse=True) + sage: J, P = A.jordan_form(transformation=True) + sage: J, P + ( + [x 1] [-a*c 1] + [0 x], [-c^2 0] + ) + sage: A1 = P * J * ~P; A1 + [ -a*c + x (a*c - x)*a/c + a*x/c] + [ -c^2 a*c + x] + sage: A1.simplify_rational() == A + True + + sage: B = matrix([[a, b, c], [0, a, d], [0, 0, a]], sparse=True) + sage: J, T = B.jordan_form(transformation=True) + sage: J, T + ( + [a 1 0] [b*d c 0] + [0 a 1] [ 0 d 0] + [0 0 a], [ 0 0 1] + ) + sage: (B * T).simplify_rational() == T * J + True + + Finally, some examples involving square roots:: + + sage: matrix([[a, -b], [b, a]], sparse=True).jordan_form() + [a - I*b| 0] + [-------+-------] + [ 0|a + I*b] + sage: matrix([[a, b], [c, d]], sparse=True).jordan_form(subdivide=False) + [1/2*a + 1/2*d - 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2) 0] + [ 0 1/2*a + 1/2*d + 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2)] + """ + A = self._maxima_lib_() + jordan_info = A.jordan() + J = matrix(jordan_info.dispJordan()._sage_(), sparse=True) + if subdivide: + v = [x[1] for x in jordan_info] + w = [sum(v[0:i]) for i in xrange(1, len(v))] + J.subdivide(w, w) + if transformation: + P = A.diag_mode_matrix(jordan_info)._sage_() + return J, matrix(P, sparse=True) + else: + return J + + def simplify(self): + """ + Simplify ``self``. + + EXAMPLES:: + + sage: var('x,y,z') + (x, y, z) + sage: m = matrix([[z, (x+y)/(x+y)], [x^2, y^2+2]], sparse=True); m + [ z 1] + [ x^2 y^2 + 2] + sage: m.simplify() + [ z 1] + [ x^2 y^2 + 2] + """ + return self.parent()([x.simplify() for x in self.list()]) + + def simplify_trig(self): + """ + EXAMPLES:: + + sage: theta = var('theta') + sage: M = matrix(SR, 2, 2, [cos(theta), sin(theta), -sin(theta), cos(theta)], sparse=True) + sage: ~M + [1/cos(theta) - sin(theta)^2/((sin(theta)^2/cos(theta) + cos(theta))*cos(theta)^2) -sin(theta)/((sin(theta)^2/cos(theta) + cos(theta))*cos(theta))] + [ sin(theta)/((sin(theta)^2/cos(theta) + cos(theta))*cos(theta)) 1/(sin(theta)^2/cos(theta) + cos(theta))] + sage: (~M).simplify_trig() + [ cos(theta) -sin(theta)] + [ sin(theta) cos(theta)] + """ + return self._maxima_(maxima).trigexpand().trigsimp()._sage_() + + def simplify_rational(self): + """ + EXAMPLES:: + + sage: M = matrix(SR, 3, 3, range(9), sparse=True) - var('t') + sage: (~M*M)[0,0] + t*(3*(2/t + (6/t + 7)/((t - 3/t - 4)*t))*(2/t + (6/t + 5)/((t - 3/t + - 4)*t))/(t - (6/t + 7)*(6/t + 5)/(t - 3/t - 4) - 12/t - 8) + 1/t + + 3/((t - 3/t - 4)*t^2)) - 6*(2/t + (6/t + 5)/((t - 3/t - 4)*t))/(t - + (6/t + 7)*(6/t + 5)/(t - 3/t - 4) - 12/t - 8) - 3*(6/t + 7)*(2/t + + (6/t + 5)/((t - 3/t - 4)*t))/((t - (6/t + 7)*(6/t + 5)/(t - 3/t - + 4) - 12/t - 8)*(t - 3/t - 4)) - 3/((t - 3/t - 4)*t) + sage: expand((~M*M)[0,0]) + 1 + sage: (~M * M).simplify_rational() + [1 0 0] + [0 1 0] + [0 0 1] + """ + return self._maxima_(maxima).fullratsimp()._sage_() + + def simplify_full(self): + """ + Simplify a symbolic matrix by calling + :meth:`Expression.simplify_full()` componentwise. + + INPUT: + + - ``self`` -- the matrix whose entries we should simplify. + + OUTPUT: + + A copy of ``self`` with all of its entries simplified. + + EXAMPLES: + + Symbolic matrices will have their entries simplified:: + + sage: a,n,k = SR.var('a,n,k') + sage: f1 = sin(x)^2 + cos(x)^2 + sage: f2 = sin(x/(x^2 + x)) + sage: f3 = binomial(n,k)*factorial(k)*factorial(n-k) + sage: f4 = x*sin(2)/(x^a) + sage: A = matrix(SR, [[f1,f2],[f3,f4]], sparse=True) + sage: A.simplify_full() + [ 1 sin(1/(x + 1))] + [ factorial(n) x^(-a + 1)*sin(2)] + + """ + M = self.parent() + return M([expr.simplify_full() for expr in self]) + + def canonicalize_radical(self): + r""" + Choose a canonical branch of each entry of ``self`` by calling + :meth:`Expression.canonicalize_radical()` componentwise. + + EXAMPLES:: + + sage: var('x','y') + (x, y) + sage: l1 = [sqrt(2)*sqrt(3)*sqrt(6) , log(x*y)] + sage: l2 = [sin(x/(x^2 + x)) , 1] + sage: m = matrix([l1, l2], sparse=True) + sage: m + [sqrt(6)*sqrt(3)*sqrt(2) log(x*y)] + [ sin(x/(x^2 + x)) 1] + sage: m.canonicalize_radical() + [ 6 log(x) + log(y)] + [ sin(1/(x + 1)) 1] + """ + M = self.parent() + return M([expr.canonicalize_radical() for expr in self]) + + def factor(self): + """ + Operate point-wise on each element. + + EXAMPLES:: + + sage: M = matrix(SR, 2, 2, x^2 - 2*x + 1, sparse=True); M + [x^2 - 2*x + 1 0] + [ 0 x^2 - 2*x + 1] + sage: M.factor() + [(x - 1)^2 0] + [ 0 (x - 1)^2] + """ + return matrix(self._maxima_(maxima).factor()._sage_(), sparse=True) + + def expand(self): + """ + Operate point-wise on each element. + + EXAMPLES:: + + sage: M = matrix(2, 2, range(4)) - var('x') + sage: M*M + [ x^2 + 2 -2*x + 3] + [ -4*x + 6 (x - 3)^2 + 2] + sage: (M*M).expand() + [ x^2 + 2 -2*x + 3] + [ -4*x + 6 x^2 - 6*x + 11] + """ + from sage.misc.call import attrcall + return self.apply_map(attrcall('expand')) + + def variables(self): + """ + Return the variables of ``self``. + + EXAMPLES:: + + sage: var('a,b,c,x,y') + (a, b, c, x, y) + sage: m = matrix([[x, x+2], [x^2, x^2+2]], sparse=True); m + [ x x + 2] + [ x^2 x^2 + 2] + sage: m.variables() + (x,) + sage: m = matrix([[a, b+c], [x^2, y^2+2]], sparse=True); m + [ a b + c] + [ x^2 y^2 + 2] + sage: m.variables() + (a, b, c, x, y) + """ + vars = set(sum([op.variables() for op in self.list()], ())) + return tuple(sorted(vars, key=repr)) + + def arguments(self): + """ + Return a tuple of the arguments that ``self`` can take. + + EXAMPLES:: + + sage: var('x,y,z') + (x, y, z) + sage: M = MatrixSpace(SR,2,2, sparse=True) + sage: M(x).arguments() + (x,) + sage: M(x+sin(x)).arguments() + (x,) + """ + return self.variables() + + def number_of_arguments(self): + """ + Return the number of arguments that ``self`` can take. + + EXAMPLES:: + + sage: var('a,b,c,x,y') + (a, b, c, x, y) + sage: m = matrix([[a, (x+y)/(x+y)], [x^2, y^2+2]], sparse=True); m + [ a 1] + [ x^2 y^2 + 2] + sage: m.number_of_arguments() + 3 + """ + return len(self.variables()) + + def __call__(self, *args, **kwargs): + """ + EXAMPLES:: + + sage: var('x,y,z') + (x, y, z) + sage: M = MatrixSpace(SR,2,2, sparse=True) + sage: h = M(sin(x)+cos(x)) + sage: h + [cos(x) + sin(x) 0] + [ 0 cos(x) + sin(x)] + sage: h(x=1) + [cos(1) + sin(1) 0] + [ 0 cos(1) + sin(1)] + sage: h(x=x) + [cos(x) + sin(x) 0] + [ 0 cos(x) + sin(x)] + + sage: h = M((sin(x)+cos(x)).function(x)) + sage: h + [cos(x) + sin(x) 0] + [ 0 cos(x) + sin(x)] + + sage: f = M([0,x,y,z]); f + [0 x] + [y z] + sage: f.arguments() + (x, y, z) + sage: f() + [0 x] + [y z] + sage: f(x=1) + [0 1] + [y z] + sage: f(x=1,y=2) + [0 1] + [2 z] + sage: f(x=1,y=2,z=3) + [0 1] + [2 3] + sage: f({x:1,y:2,z:3}) + [0 1] + [2 3] + + TESTS:: + + sage: f(1, x=2) + Traceback (most recent call last): + ... + ValueError: args and kwargs cannot both be specified + sage: f(x=1,y=2,z=3,t=4) + [0 1] + [2 3] + + sage: h(1) + Traceback (most recent call last): + ... + ValueError: use named arguments, like EXPR(x=..., y=...) + """ + if kwargs and args: + raise ValueError("args and kwargs cannot both be specified") + + if args: + if len(args) == 1 and isinstance(args[0], dict): + kwargs = {repr(x): vx for x, vx in args[0].iteritems()} + else: + raise ValueError('use named arguments, like EXPR(x=..., y=...)') + + new_entries = [] + for entry in self.list(): + try: + new_entries.append(entry(**kwargs)) + except ValueError: + new_entries.append(entry) + + return self.parent(new_entries) + + cdef bint get_is_zero_unsafe(self, Py_ssize_t i, Py_ssize_t j) except -1: + r""" + Return 1 if the entry ``(i, j)`` is zero, otherwise 0. + + EXAMPLES:: + + sage: M = matrix(SR, [[0,1,0],[0,0,0]], sparse=True) + sage: M.zero_pattern_matrix() # indirect doctest + [1 0 1] + [1 1 1] + """ + entry = self.get_unsafe(i, j) + # See if we can avoid the full proof machinery that the entry is 0 + if entry.is_trivial_zero(): + return 1 + if entry: + return 0 + else: + return 1 + + def function(self, *args): + """ + Return a matrix over a callable symbolic expression ring. + + EXAMPLES:: + + sage: x, y = var('x,y') + sage: v = matrix([[x,y],[x*sin(y), 0]], sparse=True) + sage: w = v.function([x,y]); w + [ (x, y) |--> x (x, y) |--> y] + [(x, y) |--> x*sin(y) (x, y) |--> 0] + sage: w.parent() + Full MatrixSpace of 2 by 2 sparse matrices over Callable function ring with arguments (x, y) + """ + from sage.symbolic.callable import CallableSymbolicExpressionRing + return matrix(CallableSymbolicExpressionRing(args), + self.nrows(), self.ncols(), self.list(), sparse=True) diff --git a/src/sage/modular/multiple_zeta.py b/src/sage/modular/multiple_zeta.py index b6580211188..032a592ef36 100644 --- a/src/sage/modular/multiple_zeta.py +++ b/src/sage/modular/multiple_zeta.py @@ -575,8 +575,7 @@ def extend_multiplicative_basis(B, n) -> Iterator: [((7,),), ((5,), (2,)), ((3,), (2,), (2,))] """ for pi in Partitions(n, min_part=2): - for liste in cartesian_product([B[i] for i in pi]): - yield liste + yield from cartesian_product([B[i] for i in pi]) # several classes for the algebra of MZV diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 6e648c6bd70..8b1cc879d27 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -8184,9 +8184,13 @@ def element_class(R, is_sparse): 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 - 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 + elif isinstance(R, sage.rings.abc.SymbolicRing): + if not is_sparse: + import sage.modules.vector_symbolic_dense + return sage.modules.vector_symbolic_dense.Vector_symbolic_dense + else: + import sage.modules.vector_symbolic_sparse + return sage.modules.vector_symbolic_sparse.Vector_symbolic_sparse if is_sparse: return free_module_element.FreeModuleElement_generic_sparse diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 0532ea0c9bd..f4a1ec5c575 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -5080,7 +5080,7 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): This lack of bounds checking causes trouble later:: sage: v - ) failed: IndexError: list assignment index out of range> + ) failed: IndexError: list assignment index out of range> """ if value: self._entries[i] = value diff --git a/src/sage/modules/vector_symbolic_dense.py b/src/sage/modules/vector_symbolic_dense.py index 200d82ebf15..e4d9efff0b3 100644 --- a/src/sage/modules/vector_symbolic_dense.py +++ b/src/sage/modules/vector_symbolic_dense.py @@ -1,7 +1,7 @@ """ -Vectors over the symbolic ring +Dense vectors over the symbolic ring -Implements vectors over the symbolic ring. +Implements dense vectors over the symbolic ring. AUTHORS: diff --git a/src/sage/modules/vector_symbolic_sparse.py b/src/sage/modules/vector_symbolic_sparse.py new file mode 100644 index 00000000000..30ec55214c6 --- /dev/null +++ b/src/sage/modules/vector_symbolic_sparse.py @@ -0,0 +1,118 @@ +""" +Sparse vectors over the symbolic ring + +Implements vectors over the symbolic ring. + +AUTHORS: + +- Robert Bradshaw (2011-05-25): Added more element-wise simplification methods + +- Joris Vankerschaver (2011-05-15): Initial version + +- Dima Pasechnik (2023-06-04): cloning from the dense case + +EXAMPLES:: + + sage: x, y = var('x, y') + sage: u = vector([sin(x)^2 + cos(x)^2, log(2*y) + log(3*y)], sparse=True); u + (cos(x)^2 + sin(x)^2, log(3*y) + log(2*y)) + sage: type(u) + + sage: u.simplify_full() + (1, log(3*y) + log(2*y)) + +TESTS: + +Check that the outcome of arithmetic with symbolic vectors is again +a symbolic vector (:trac:`11549`):: + + sage: v = vector(SR, [1, 2], sparse=True) + sage: w = vector(SR, [sin(x), 0], sparse=True) + sage: type(v) + + sage: type(w) + + sage: type(v + w) + + sage: type(-v) + + sage: type(5*w) + + +Test pickling/unpickling:: + + sage: u = vector(SR, [sin(x^2)], sparse=True) + sage: loads(dumps(u)) == u + True + +""" + +#***************************************************************************** +# Copyright (C) 2011 Joris Vankerschaver (jv@caltech.edu) +# +# Distributed under the terms of the GNU General Public License (GPL) +# 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/ +#***************************************************************************** + +from . import free_module_element +from sage.symbolic.expression import Expression + + +def apply_map(phi): + """ + Returns a function that applies phi to its argument. + + EXAMPLES:: + + sage: from sage.modules.vector_symbolic_sparse import apply_map + sage: v = vector([1,2,3], sparse=True) + sage: f = apply_map(lambda x: x+1) + sage: f(v) + (2, 3, 4) + + """ + def apply(self, *args, **kwds): + """ + Generic function used to implement common symbolic operations + elementwise as methods of a vector. + + EXAMPLES:: + + sage: var('x,y') + (x, y) + sage: v = vector([sin(x)^2 + cos(x)^2, log(x*y), sin(x/(x^2 + x)), factorial(x+1)/factorial(x)], sparse=True) + sage: v.simplify_trig() + (1, log(x*y), sin(1/(x + 1)), factorial(x + 1)/factorial(x)) + sage: v.canonicalize_radical() + (cos(x)^2 + sin(x)^2, log(x) + log(y), sin(1/(x + 1)), factorial(x + 1)/factorial(x)) + sage: v.simplify_rational() + (cos(x)^2 + sin(x)^2, log(x*y), sin(1/(x + 1)), factorial(x + 1)/factorial(x)) + sage: v.simplify_factorial() + (cos(x)^2 + sin(x)^2, log(x*y), sin(x/(x^2 + x)), x + 1) + sage: v.simplify_full() + (1, log(x*y), sin(1/(x + 1)), x + 1) + + sage: v = vector([sin(2*x), sin(3*x)], sparse=True) + sage: v.simplify_trig() + (2*cos(x)*sin(x), (4*cos(x)^2 - 1)*sin(x)) + sage: v.simplify_trig(False) + (sin(2*x), sin(3*x)) + sage: v.simplify_trig(expand=False) + (sin(2*x), sin(3*x)) + """ + return self.apply_map(lambda x: phi(x, *args, **kwds)) + apply.__doc__ += "\nSee Expression." + phi.__name__ + "() for optional arguments." + return apply + + +class Vector_symbolic_sparse(free_module_element.FreeModuleElement_generic_sparse): + pass + +# Add elementwise methods. +for method in ['simplify', 'simplify_factorial', + 'simplify_log', 'simplify_rational', + 'simplify_trig', 'simplify_full', 'trig_expand', + 'canonicalize_radical', 'trig_reduce']: + setattr(Vector_symbolic_sparse, method, apply_map(getattr(Expression, method))) diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index d46ef531add..47833d9f386 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -2010,8 +2010,7 @@ def __iter__(self): newres = self._results.get() if newres is not None: logger.debug("Got some results") - for r in newres: - yield r + yield from newres else: active_proc -= 1 if active_proc == 0: diff --git a/src/sage/parallel/multiprocessing_sage.py b/src/sage/parallel/multiprocessing_sage.py index be9b980aba9..2ccab49ac0f 100644 --- a/src/sage/parallel/multiprocessing_sage.py +++ b/src/sage/parallel/multiprocessing_sage.py @@ -74,7 +74,6 @@ def parallel_iter(processes, f, inputs): result = p.imap_unordered(call_pickled_function, [(fp, t) for t in inputs]) - for res in result: - yield res + yield from result p.close() p.join() diff --git a/src/sage/quadratic_forms/count_local_2.pyx b/src/sage/quadratic_forms/count_local_2.pyx index 7ffedf8d8d2..95228c64208 100644 --- a/src/sage/quadratic_forms/count_local_2.pyx +++ b/src/sage/quadratic_forms/count_local_2.pyx @@ -1,13 +1,10 @@ r""" Optimized counting of congruence solutions """ - from sage.arith.misc import is_prime, kronecker as kronecker_symbol, valuation from sage.rings.finite_rings.integer_mod cimport IntegerMod_gmp from sage.rings.finite_rings.integer_mod import Mod from sage.rings.finite_rings.integer_mod_ring import IntegerModRing -from sage.rings.integer_ring import ZZ -from sage.sets.set import Set def count_modp__by_gauss_sum(n, p, m, Qdet): diff --git a/src/sage/quadratic_forms/ternary.pyx b/src/sage/quadratic_forms/ternary.pyx index a0c86f7c7cb..28db34fd5eb 100644 --- a/src/sage/quadratic_forms/ternary.pyx +++ b/src/sage/quadratic_forms/ternary.pyx @@ -9,14 +9,12 @@ Helper code for ternary quadratic forms # 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/ #***************************************************************************** from sage.arith.misc import gcd, inverse_mod, xgcd from sage.matrix.constructor import matrix, identity_matrix, diagonal_matrix from sage.misc.prandom import randint -from sage.modules.free_module_element import vector -from sage.quadratic_forms.extras import extend_to_primitive from sage.rings.finite_rings.integer_mod import mod from sage.rings.integer_ring import ZZ diff --git a/src/sage/rings/asymptotic/growth_group_cartesian.py b/src/sage/rings/asymptotic/growth_group_cartesian.py index 155adb2398e..79510d42eca 100644 --- a/src/sage/rings/asymptotic/growth_group_cartesian.py +++ b/src/sage/rings/asymptotic/growth_group_cartesian.py @@ -775,8 +775,7 @@ def pushout_univariate_factors(self, other, var, Sfactors, Ofactors): def subfactors(F): for f in F: if isinstance(f, GenericProduct): - for g in subfactors(f.cartesian_factors()): - yield g + yield from subfactors(f.cartesian_factors()) else: yield f diff --git a/src/sage/rings/complex_interval_field.py b/src/sage/rings/complex_interval_field.py index 81385cc7bfb..7cbf5d60929 100644 --- a/src/sage/rings/complex_interval_field.py +++ b/src/sage/rings/complex_interval_field.py @@ -627,7 +627,7 @@ def random_element(self, *args, **kwds): im = rand(*args, **kwds) return self.element_class(self, re, im) - def is_field(self, proof = True): + def is_field(self, proof=True): """ Return ``True``, since the complex numbers are a field. diff --git a/src/sage/rings/finite_rings/conway_polynomials.py b/src/sage/rings/finite_rings/conway_polynomials.py index d4a08e1fb4d..d947fa25cc8 100644 --- a/src/sage/rings/finite_rings/conway_polynomials.py +++ b/src/sage/rings/finite_rings/conway_polynomials.py @@ -273,7 +273,7 @@ def check_consistency(self, n): sage: PCL.check_consistency(60) # long time """ p = self.p - K = FiniteField(p**n, modulus = self.polynomial(n), names='a') + K = FiniteField(p**n, modulus=self.polynomial(n), names='a') a = K.gen() for m in n.divisors(): assert (a**((p**n-1)//(p**m-1))).minimal_polynomial() == self.polynomial(m) diff --git a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx index f6fa95241dc..33db43010b9 100644 --- a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx +++ b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx @@ -15,18 +15,18 @@ AUTHORS: - Martin Albrecht (2007-10) """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 Martin Albrecht # # 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/ +# **************************************************************************** from cysignals.memory cimport check_malloc, sig_free -from cysignals.signals cimport sig_on, sig_off +from cysignals.signals cimport sig_on from sage.ext.cplusplus cimport ccrepr, ccreadstr include "sage/libs/ntl/decl.pxi" diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index 8d203e9f019..69edbcec2f0 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -1015,7 +1015,7 @@ def __init__(self, R): sage: TestSuite(M).run() # optional - sage.rings.finite_rings """ self.Element = R._ideal_class - Parent.__init__(self, category = Monoids()) + Parent.__init__(self, category=Monoids()) self.__R = R self._populate_coercion_lists_() diff --git a/src/sage/rings/function_field/place.py b/src/sage/rings/function_field/place.py index 685af63a571..0c61671bffa 100644 --- a/src/sage/rings/function_field/place.py +++ b/src/sage/rings/function_field/place.py @@ -342,7 +342,7 @@ def __init__(self, field): sage: TestSuite(places).run() # optional - sage.rings.finite_rings sage.rings.function_field """ self.Element = field._place_class - Parent.__init__(self, category = Sets().Infinite()) + Parent.__init__(self, category=Sets().Infinite()) self._field = field diff --git a/src/sage/rings/homset.py b/src/sage/rings/homset.py index 77fa3323bc0..b89ba5a1ed7 100644 --- a/src/sage/rings/homset.py +++ b/src/sage/rings/homset.py @@ -36,7 +36,7 @@ def is_RingHomset(H): return isinstance(H, RingHomset_generic) -def RingHomset(R, S, category = None): +def RingHomset(R, S, category=None): """ Construct a space of homomorphisms between the rings ``R`` and ``S``. @@ -51,8 +51,8 @@ def RingHomset(R, S, category = None): if quotient_ring.is_QuotientRing(R): from .polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing if not is_PolynomialQuotientRing(R): # backwards compatibility - return RingHomset_quo_ring(R, S, category = category) - return RingHomset_generic(R, S, category = category) + return RingHomset_quo_ring(R, S, category=category) + return RingHomset_generic(R, S, category=category) class RingHomset_generic(HomsetWithBase): @@ -69,7 +69,7 @@ class RingHomset_generic(HomsetWithBase): Element = morphism.RingHomomorphism - def __init__(self, R, S, category = None): + def __init__(self, R, S, category=None): """ Initialize ``self``. diff --git a/src/sage/rings/ideal.py b/src/sage/rings/ideal.py index 998aa2beac2..2bb3a47e4d3 100644 --- a/src/sage/rings/ideal.py +++ b/src/sage/rings/ideal.py @@ -1690,7 +1690,7 @@ def residue_field(self): raise ValueError("The ideal (%s) is not prime"%self) from sage.rings.integer_ring import ZZ if self.ring() is ZZ: - return ZZ.residue_field(self, check = False) + return ZZ.residue_field(self, check=False) raise NotImplementedError("residue_field() is only implemented for ZZ and rings of integers of number fields.") class Ideal_fractional(Ideal_generic): diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index d1647ec445f..b58e21e655c 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -5101,24 +5101,24 @@ def _format_series(self, formatter, format_strings=False): poly = repr_lincomb([(1, m) for m in mons + bigO], is_latex=True, strip_one=True) elif formatter == ascii_art: if atomic_repr: - poly = ascii_art(*(mons + bigO), sep = " + ") + poly = ascii_art(*(mons + bigO), sep=" + ") else: def parenthesize(m): a = ascii_art(m) h = a.height() return ascii_art(ascii_left_parenthesis.character_art(h), a, ascii_right_parenthesis.character_art(h)) - poly = ascii_art(*([parenthesize(m) for m in mons] + bigO), sep = " + ") + poly = ascii_art(*([parenthesize(m) for m in mons] + bigO), sep=" + ") elif formatter == unicode_art: if atomic_repr: - poly = unicode_art(*(mons + bigO), sep = " + ") + poly = unicode_art(*(mons + bigO), sep=" + ") else: def parenthesize(m): a = unicode_art(m) h = a.height() return unicode_art(unicode_left_parenthesis.character_art(h), a, unicode_right_parenthesis.character_art(h)) - poly = unicode_art(*([parenthesize(m) for m in mons] + bigO), sep = " + ") + poly = unicode_art(*([parenthesize(m) for m in mons] + bigO), sep=" + ") return poly @@ -5415,24 +5415,24 @@ def _format_series(self, formatter, format_strings=False): poly = repr_lincomb([(1, m) for m in mons + bigO], is_latex=True, strip_one=True) elif formatter == ascii_art: if atomic_repr: - poly = ascii_art(*(mons + bigO), sep = " + ") + poly = ascii_art(*(mons + bigO), sep=" + ") else: def parenthesize(m): a = ascii_art(m) h = a.height() return ascii_art(ascii_left_parenthesis.character_art(h), a, ascii_right_parenthesis.character_art(h)) - poly = ascii_art(*([parenthesize(m) for m in mons] + bigO), sep = " + ") + poly = ascii_art(*([parenthesize(m) for m in mons] + bigO), sep=" + ") elif formatter == unicode_art: if atomic_repr: - poly = unicode_art(*(mons + bigO), sep = " + ") + poly = unicode_art(*(mons + bigO), sep=" + ") else: def parenthesize(m): a = unicode_art(m) h = a.height() return unicode_art(unicode_left_parenthesis.character_art(h), a, unicode_right_parenthesis.character_art(h)) - poly = unicode_art(*([parenthesize(m) for m in mons] + bigO), sep = " + ") + poly = unicode_art(*([parenthesize(m) for m in mons] + bigO), sep=" + ") return poly diff --git a/src/sage/rings/multi_power_series_ring.py b/src/sage/rings/multi_power_series_ring.py index 20e3cba3977..dd374ea0f75 100644 --- a/src/sage/rings/multi_power_series_ring.py +++ b/src/sage/rings/multi_power_series_ring.py @@ -365,8 +365,7 @@ def __init__(self, base_ring, num_gens, name_list, # Multivariate power series rings inherit from power series rings. But # apparently we can not call their initialisation. Instead, initialise # CommutativeRing and Nonexact: - CommutativeRing.__init__(self, base_ring, name_list, category = - _IntegralDomains if base_ring in + CommutativeRing.__init__(self, base_ring, name_list, category=_IntegralDomains if base_ring in _IntegralDomains else _CommutativeRings) Nonexact.__init__(self, default_prec) @@ -561,7 +560,7 @@ def change_ring(self, R): sage: S.change_ring(GF(5)) # optional - sage.rings.finite_rings Multivariate Power Series Ring in x, y over Finite Field of size 5 """ - return PowerSeriesRing(R, names = self.variable_names(), default_prec = self.default_prec()) + return PowerSeriesRing(R, names=self.variable_names(), default_prec=self.default_prec()) def remove_var(self, *var): """ diff --git a/src/sage/rings/number_field/number_field_ideal.py b/src/sage/rings/number_field/number_field_ideal.py index ce1e8bce645..7a4b3b2debc 100644 --- a/src/sage/rings/number_field/number_field_ideal.py +++ b/src/sage/rings/number_field/number_field_ideal.py @@ -3196,7 +3196,7 @@ def residue_field(self, names=None): """ if not self.is_prime(): raise ValueError("The ideal must be prime") - return self.number_field().residue_field(self, names = names) + return self.number_field().residue_field(self, names=names) def residue_class_degree(self): r""" diff --git a/src/sage/rings/number_field/number_field_ideal_rel.py b/src/sage/rings/number_field/number_field_ideal_rel.py index ce5cbbea12d..c53b80c2bc2 100644 --- a/src/sage/rings/number_field/number_field_ideal_rel.py +++ b/src/sage/rings/number_field/number_field_ideal_rel.py @@ -134,7 +134,7 @@ def pari_rhnf(self): self.__pari_rhnf = rnf.rnfidealabstorel(nfzk * L_hnf) return self.__pari_rhnf - def absolute_ideal(self, names = 'a'): + def absolute_ideal(self, names='a'): r""" If this is an ideal in the extension `L/K`, return the ideal with the same generators in the absolute field `L/\QQ`. diff --git a/src/sage/rings/number_field/number_field_rel.py b/src/sage/rings/number_field/number_field_rel.py index 9a42f30ec02..838bfd570d7 100644 --- a/src/sage/rings/number_field/number_field_rel.py +++ b/src/sage/rings/number_field/number_field_rel.py @@ -2156,7 +2156,7 @@ def automorphisms(self): abs_base_gens = [self_into_L(_) for _ in self.base_field().gens()] v = sorted([ self.hom([ L_into_self(aa(a)) ]) for aa in aas if all(aa(g) == g for g in abs_base_gens) ]) put_natural_embedding_first(v) - self.__automorphisms = Sequence(v, cr = (v != []), immutable=True, + self.__automorphisms = Sequence(v, cr=(v != []), immutable=True, check=False, universe=self.Hom(self)) return self.__automorphisms @@ -2673,7 +2673,7 @@ def relativize(self, alpha, names): L = K.relativize(beta, names) return K.relativize(beta, names, structure=structure.RelativeFromRelative(L)) - def uniformizer(self, P, others = "positive"): + def uniformizer(self, P, others="positive"): """ Returns an element of ``self`` with valuation 1 at the prime ideal `P`. diff --git a/src/sage/rings/padics/factory.py b/src/sage/rings/padics/factory.py index 25e5c796cc2..d3a701decfe 100644 --- a/src/sage/rings/padics/factory.py +++ b/src/sage/rings/padics/factory.py @@ -723,10 +723,10 @@ class Qp_class(UniqueFactory): sage: K = Qp(15, check=False); a = K(999); a 9 + 6*15 + 4*15^2 + O(15^20) """ - def create_key(self, p, prec = None, type = 'capped-rel', print_mode = None, - names = None, ram_name = None, print_pos = None, - print_sep = None, print_alphabet = None, print_max_terms = None, show_prec = None, check = True, - label = None): # specific to Lattice precision + def create_key(self, p, prec=None, type='capped-rel', print_mode=None, + names=None, ram_name=None, print_pos=None, + print_sep=None, print_alphabet=None, print_max_terms=None, show_prec=None, check=True, + label=None): # specific to Lattice precision r""" Creates a key from input parameters for ``Qp``. @@ -822,10 +822,10 @@ def create_object(self, version, key): # Qq -- unramified extensions ###################################################### -def Qq(q, prec = None, type = 'capped-rel', modulus = None, names=None, - print_mode=None, ram_name = None, res_name = None, print_pos = None, - print_sep = None, print_max_ram_terms = None, - print_max_unram_terms = None, print_max_terse_terms = None, show_prec=None, check = True, implementation = 'FLINT'): +def Qq(q, prec=None, type='capped-rel', modulus=None, names=None, + print_mode=None, ram_name=None, res_name=None, print_pos=None, + print_sep=None, print_max_ram_terms=None, + print_max_unram_terms=None, print_max_terse_terms=None, show_prec=None, check=True, implementation='FLINT'): r""" Given a prime power `q = p^n`, return the unique unramified extension of `\QQ_p` of degree `n`. @@ -1380,7 +1380,7 @@ def Qq(q, prec = None, type = 'capped-rel', modulus = None, names=None, # Short constructor names for different types ###################################################### -def QpCR(p, prec = None, *args, **kwds): +def QpCR(p, prec=None, *args, **kwds): r""" A shortcut function to create capped relative `p`-adic fields. @@ -1394,7 +1394,7 @@ def QpCR(p, prec = None, *args, **kwds): """ return Qp(p, prec, 'capped-rel', *args, **kwds) -def QpFP(p, prec = None, *args, **kwds): +def QpFP(p, prec=None, *args, **kwds): r""" A shortcut function to create floating point `p`-adic fields. @@ -1408,7 +1408,7 @@ def QpFP(p, prec = None, *args, **kwds): """ return Qp(p, prec, 'floating-point', *args, **kwds) -def QqCR(q, prec = None, *args, **kwds): +def QqCR(q, prec=None, *args, **kwds): r""" A shortcut function to create capped relative unramified `p`-adic fields. @@ -1423,7 +1423,7 @@ def QqCR(q, prec = None, *args, **kwds): """ return Qq(q, prec, 'capped-rel', *args, **kwds) -def QqFP(q, prec = None, *args, **kwds): +def QqFP(q, prec=None, *args, **kwds): r""" A shortcut function to create floating point unramified `p`-adic fields. @@ -1439,7 +1439,7 @@ def QqFP(q, prec = None, *args, **kwds): return Qq(q, prec, 'floating-point', *args, **kwds) @experimental(23505) -def QpLC(p, prec = None, *args, **kwds): +def QpLC(p, prec=None, *args, **kwds): r""" A shortcut function to create `p`-adic fields with lattice precision. @@ -1454,7 +1454,7 @@ def QpLC(p, prec = None, *args, **kwds): return Qp(p, prec, 'lattice-cap', *args, **kwds) @experimental(23505) -def QpLF(p, prec = None, *args, **kwds): +def QpLF(p, prec=None, *args, **kwds): r""" A shortcut function to create `p`-adic fields with lattice precision. @@ -1930,10 +1930,10 @@ class Zp_class(UniqueFactory): sage: a + b 1 + 5 + O(5^10) """ - def create_key(self, p, prec = None, type = 'capped-rel', print_mode = None, - names = None, ram_name = None, print_pos = None, print_sep = None, print_alphabet = None, - print_max_terms = None, show_prec = None, check = True, - label = None): + def create_key(self, p, prec=None, type='capped-rel', print_mode=None, + names=None, ram_name=None, print_pos=None, print_sep=None, print_alphabet=None, + print_max_terms=None, show_prec=None, check=True, + label=None): r""" Creates a key from input parameters for ``Zp``. @@ -2034,10 +2034,10 @@ def create_object(self, version, key): # Zq -- unramified extensions ###################################################### -def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, - print_mode=None, ram_name = None, res_name = None, print_pos = None, - print_sep = None, print_max_ram_terms = None, - print_max_unram_terms = None, print_max_terse_terms = None, show_prec = None, check = True, implementation = 'FLINT'): +def Zq(q, prec=None, type='capped-rel', modulus=None, names=None, + print_mode=None, ram_name=None, res_name=None, print_pos=None, + print_sep=None, print_max_ram_terms=None, + print_max_unram_terms=None, print_max_terse_terms=None, show_prec=None, check=True, implementation='FLINT'): r""" Given a prime power `q = p^n`, return the unique unramified extension of `\ZZ_p` of degree `n`. @@ -2599,7 +2599,7 @@ def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, # Short constructor names for different types ###################################################### -def ZpCR(p, prec = None, *args, **kwds): +def ZpCR(p, prec=None, *args, **kwds): r""" A shortcut function to create capped relative `p`-adic rings. @@ -2613,7 +2613,7 @@ def ZpCR(p, prec = None, *args, **kwds): """ return Zp(p, prec, 'capped-rel', *args, **kwds) -def ZpCA(p, prec = None, *args, **kwds): +def ZpCA(p, prec=None, *args, **kwds): r""" A shortcut function to create capped absolute `p`-adic rings. @@ -2626,7 +2626,7 @@ def ZpCA(p, prec = None, *args, **kwds): """ return Zp(p, prec, 'capped-abs', *args, **kwds) -def ZpFM(p, prec = None, *args, **kwds): +def ZpFM(p, prec=None, *args, **kwds): r""" A shortcut function to create fixed modulus `p`-adic rings. @@ -2639,7 +2639,7 @@ def ZpFM(p, prec = None, *args, **kwds): """ return Zp(p, prec, 'fixed-mod', *args, **kwds) -def ZpFP(p, prec = None, *args, **kwds): +def ZpFP(p, prec=None, *args, **kwds): r""" A shortcut function to create floating point `p`-adic rings. @@ -2653,7 +2653,7 @@ def ZpFP(p, prec = None, *args, **kwds): """ return Zp(p, prec, 'floating-point', *args, **kwds) -def ZqCR(q, prec = None, *args, **kwds): +def ZqCR(q, prec=None, *args, **kwds): r""" A shortcut function to create capped relative unramified `p`-adic rings. @@ -2667,7 +2667,7 @@ def ZqCR(q, prec = None, *args, **kwds): """ return Zq(q, prec, 'capped-rel', *args, **kwds) -def ZqCA(q, prec = None, *args, **kwds): +def ZqCA(q, prec=None, *args, **kwds): r""" A shortcut function to create capped absolute unramified `p`-adic rings. @@ -2680,7 +2680,7 @@ def ZqCA(q, prec = None, *args, **kwds): """ return Zq(q, prec, 'capped-abs', *args, **kwds) -def ZqFM(q, prec = None, *args, **kwds): +def ZqFM(q, prec=None, *args, **kwds): r""" A shortcut function to create fixed modulus unramified `p`-adic rings. @@ -2693,7 +2693,7 @@ def ZqFM(q, prec = None, *args, **kwds): """ return Zq(q, prec, 'fixed-mod', *args, **kwds) -def ZqFP(q, prec = None, *args, **kwds): +def ZqFP(q, prec=None, *args, **kwds): r""" A shortcut function to create floating point unramified `p`-adic rings. @@ -3235,12 +3235,12 @@ class pAdicExtension_class(UniqueFactory): sage: W.precision_cap() 12 """ - def create_key_and_extra_args(self, base, modulus, prec = None, print_mode = None, - names = None, var_name = None, res_name = None, - unram_name = None, ram_name = None, print_pos = None, - print_sep = None, print_alphabet = None, print_max_ram_terms = None, - print_max_unram_terms = None, print_max_terse_terms = None, - show_prec = None, check = True, unram = False, implementation='FLINT'): + def create_key_and_extra_args(self, base, modulus, prec=None, print_mode=None, + names=None, var_name=None, res_name=None, + unram_name=None, ram_name=None, print_pos=None, + print_sep=None, print_alphabet=None, print_max_ram_terms=None, + print_max_unram_terms=None, print_max_terse_terms=None, + show_prec=None, check=True, unram=False, implementation='FLINT'): r""" Creates a key from input parameters for :class:`pAdicExtension`. diff --git a/src/sage/rings/padics/generic_nodes.py b/src/sage/rings/padics/generic_nodes.py index 062bc28d8f8..c3d9dce2ded 100644 --- a/src/sage/rings/padics/generic_nodes.py +++ b/src/sage/rings/padics/generic_nodes.py @@ -1201,7 +1201,7 @@ def is_pAdicRing(R): class pAdicRingGeneric(pAdicGeneric, sage.rings.abc.pAdicRing): - def is_field(self, proof = True): + def is_field(self, proof=True): """ Return whether this ring is actually a field, ie ``False``. diff --git a/src/sage/rings/padics/local_generic.py b/src/sage/rings/padics/local_generic.py index 83d77282c2a..21f3e458255 100644 --- a/src/sage/rings/padics/local_generic.py +++ b/src/sage/rings/padics/local_generic.py @@ -231,7 +231,7 @@ def _latex_(self): sage: latex(Zq(27,names='a')) #indirect doctest \Bold{Z}_{3^{3}} """ - return self._repr_(do_latex = True) + return self._repr_(do_latex=True) def change(self, **kwds): r""" diff --git a/src/sage/rings/padics/local_generic_element.pyx b/src/sage/rings/padics/local_generic_element.pyx index 8df39a52363..5a757de50bb 100644 --- a/src/sage/rings/padics/local_generic_element.pyx +++ b/src/sage/rings/padics/local_generic_element.pyx @@ -23,7 +23,7 @@ AUTHORS: # **************************************************************************** from sage.rings.infinity import infinity -from sage.structure.element cimport ModuleElement, RingElement, CommutativeRingElement +from sage.structure.element cimport CommutativeRingElement from sage.structure.element import coerce_binop from itertools import islice diff --git a/src/sage/rings/padics/morphism.pyx b/src/sage/rings/padics/morphism.pyx index a24fea29ea3..73ae1d53471 100644 --- a/src/sage/rings/padics/morphism.pyx +++ b/src/sage/rings/padics/morphism.pyx @@ -1,31 +1,27 @@ """ Frobenius endomorphisms on p-adic fields """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013 Xavier Caruso # # 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/ +# **************************************************************************** from sage.rings.integer cimport Integer from sage.rings.infinity import Infinity -from sage.rings.ring import CommutativeRing from sage.categories.homset import Hom from sage.structure.element cimport Element from sage.structure.richcmp cimport (richcmp, rich_to_bool, - richcmp_not_equal) + richcmp_not_equal) from sage.rings.morphism cimport RingHomomorphism from .padic_generic import pAdicGeneric -from sage.categories.morphism cimport Morphism - cdef class FrobeniusEndomorphism_padics(RingHomomorphism): """ diff --git a/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx index ce11925e3a1..979f9d54ba5 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx @@ -175,7 +175,6 @@ from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class -from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext from sage.rings.padics.padic_generic_element cimport pAdicGenericElement from sage.libs.pari.all import pari_gen from sage.interfaces.abc import GpElement @@ -184,10 +183,6 @@ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing from sage.rings.padics.padic_ext_element cimport pAdicExtElement from sage.rings.padics.precision_error import PrecisionError -from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX -from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX_small_Eis -from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX_big_Eis - cdef object infinity from sage.rings.infinity import infinity diff --git a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx index 82982a40045..e3bd45e9037 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx @@ -176,8 +176,7 @@ AUTHORS: - Julian Rueth (2014-05-09): enable caching through ``_cache_key`` """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 David Roe # William Stein # 2014 Julian Rueth @@ -186,8 +185,8 @@ AUTHORS: # 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/ +# **************************************************************************** from cysignals.signals cimport sig_on, sig_off from sage.ext.stdsage cimport PY_NEW @@ -201,7 +200,6 @@ from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class -from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext from sage.rings.padics.padic_generic_element cimport pAdicGenericElement from sage.libs.pari.all import pari_gen from sage.interfaces.abc import GpElement @@ -209,13 +207,9 @@ from sage.rings.finite_rings.integer_mod import is_IntegerMod from sage.rings.padics.padic_ext_element cimport pAdicExtElement from sage.rings.padics.precision_error import PrecisionError -from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX_small_Eis from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX_big_Eis from sage.rings.finite_rings.integer_mod_ring import IntegerModRing -from sage.rings.padics.unramified_extension_generic import UnramifiedExtensionGeneric - -from sage.rings.real_double cimport RealDoubleElement cdef object infinity from sage.rings.infinity import infinity diff --git a/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx index 2f8db3f78f6..9dec3affd53 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx @@ -113,8 +113,7 @@ AUTHORS: - David Roe (2008-01-01) initial version """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 David Roe # William Stein # @@ -122,18 +121,14 @@ AUTHORS: # 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/ +# **************************************************************************** from cysignals.signals cimport sig_on, sig_off include "sage/libs/ntl/decl.pxi" from sage.structure.richcmp cimport rich_to_bool -from sage.structure.element cimport Element -from sage.rings.padics.padic_printing cimport pAdicPrinter_class -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.integer_ring import ZZ from sage.rings.integer cimport Integer from sage.rings.padics.padic_generic_element cimport pAdicGenericElement from sage.rings.padics.padic_ext_element cimport pAdicExtElement @@ -144,13 +139,11 @@ from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class -from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext from sage.rings.rational cimport Rational from sage.libs.pari.all import pari_gen from sage.interfaces.abc import GpElement from sage.rings.finite_rings.integer_mod import is_IntegerMod from sage.rings.finite_rings.integer_mod_ring import IntegerModRing -from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX_FM_Eis cdef class pAdicZZpXFMElement(pAdicZZpXElement): diff --git a/src/sage/rings/padics/padic_base_leaves.py b/src/sage/rings/padics/padic_base_leaves.py index 99823338bc4..8c4636e2904 100644 --- a/src/sage/rings/padics/padic_base_leaves.py +++ b/src/sage/rings/padics/padic_base_leaves.py @@ -729,7 +729,7 @@ def random_element(self, algorithm='default'): if (algorithm == 'default'): k = ZZ.random_element() a = ZZ.random_element(self.prime()**self.precision_cap()) - return self(self.prime()**k * a, absprec = k + self.precision_cap()) + return self(self.prime()**k * a, absprec=k + self.precision_cap()) else: raise NotImplementedError("Don't know %s algorithm"%algorithm) diff --git a/src/sage/rings/padics/padic_ext_element.pyx b/src/sage/rings/padics/padic_ext_element.pyx index 2728506f709..94a7d93c727 100644 --- a/src/sage/rings/padics/padic_ext_element.pyx +++ b/src/sage/rings/padics/padic_ext_element.pyx @@ -16,8 +16,7 @@ AUTHORS: - Julian Rueth (2012-10-18): added residue """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007-2010 David Roe # 2012 Julian Rueth # @@ -25,11 +24,10 @@ AUTHORS: # 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/ +# **************************************************************************** from sage.rings.padics.pow_computer cimport PowComputer_class -from sage.rings.integer import Integer from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p cdef class pAdicExtElement(pAdicGenericElement): diff --git a/src/sage/rings/padics/padic_generic.py b/src/sage/rings/padics/padic_generic.py index b7caad54122..a4596240d57 100644 --- a/src/sage/rings/padics/padic_generic.py +++ b/src/sage/rings/padics/padic_generic.py @@ -497,7 +497,7 @@ def integer_ring(self, print_mode=None): deprecation(23227, "Use the change method if you want to change print options in integer_ring()") return self.change(field=False, **print_mode) - def teichmuller(self, x, prec = None): + def teichmuller(self, x, prec=None): r""" Return the Teichmüller representative of ``x``. @@ -614,7 +614,7 @@ def teichmuller_system(self): # """ # raise NotImplementedError - def extension(self, modulus, prec = None, names = None, print_mode = None, implementation='FLINT', **kwds): + def extension(self, modulus, prec=None, names=None, print_mode=None, implementation='FLINT', **kwds): r""" Create an extension of this p-adic ring. @@ -665,7 +665,7 @@ def extension(self, modulus, prec = None, names = None, print_mode = None, imple print_mode[option] = kwds[option] else: print_mode[option] = self._printer.dict()[option] - return ExtensionFactory(base=self, modulus=modulus, prec=prec, names=names, check = True, implementation=implementation, **print_mode) + return ExtensionFactory(base=self, modulus=modulus, prec=prec, names=names, check=True, implementation=implementation, **print_mode) def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): r""" diff --git a/src/sage/rings/padics/padic_generic_element.pyx b/src/sage/rings/padics/padic_generic_element.pyx index 1315c6f9a74..a1beaa5110a 100644 --- a/src/sage/rings/padics/padic_generic_element.pyx +++ b/src/sage/rings/padics/padic_generic_element.pyx @@ -14,8 +14,7 @@ AUTHORS: - Julian Rueth: fixes for exp() and log(), implemented gcd, xgcd """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007-2013 David Roe # 2007 William Stein # 2013-2014 Julian Rueth @@ -24,11 +23,10 @@ AUTHORS: # 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/ +# **************************************************************************** from sage.ext.stdsage cimport PY_NEW -from cysignals.memory cimport sig_malloc, sig_free cimport sage.rings.padics.local_generic_element from sage.libs.gmp.mpz cimport mpz_set_si diff --git a/src/sage/rings/padics/pow_computer_ext.pyx b/src/sage/rings/padics/pow_computer_ext.pyx index fe60e6bde33..060e22719df 100644 --- a/src/sage/rings/padics/pow_computer_ext.pyx +++ b/src/sage/rings/padics/pow_computer_ext.pyx @@ -42,8 +42,7 @@ AUTHORS: - David Roe (2008-01-01) initial version """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 David Roe # William Stein # @@ -51,8 +50,8 @@ AUTHORS: # 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/ +# **************************************************************************** from cpython.list cimport * from cpython.dict cimport * @@ -61,9 +60,7 @@ from cysignals.signals cimport sig_on, sig_off include "sage/libs/ntl/decl.pxi" -import weakref from sage.misc.misc import cputime -from sage.rings.infinity import infinity from sage.libs.gmp.mpz cimport * from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_factory from sage.libs.ntl.ntl_ZZ_pContext import ZZ_pContext_factory diff --git a/src/sage/rings/padics/pow_computer_relative.pyx b/src/sage/rings/padics/pow_computer_relative.pyx index 29cee93968c..39051a681de 100644 --- a/src/sage/rings/padics/pow_computer_relative.pyx +++ b/src/sage/rings/padics/pow_computer_relative.pyx @@ -17,7 +17,7 @@ AUTHORS: - David Roe, Julian Rüth (2017-06-11): initial version """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2017 David Roe # 2017 Julian Rüth # @@ -25,19 +25,13 @@ AUTHORS: # 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/ +# **************************************************************************** -from cysignals.memory cimport sig_malloc, sig_free -from cysignals.signals cimport sig_on, sig_off - -from sage.libs.gmp.mpz cimport mpz_init, mpz_clear, mpz_pow_ui - -from cpython.object cimport Py_EQ, Py_NE from sage.rings.integer cimport Integer -from sage.rings.integer_ring import ZZ from sage.misc.cachefunc import cached_method + cdef class PowComputer_relative(PowComputer_class): r""" Base class for a ``PowComputer`` for use in `p`-adics implemented by Sage diff --git a/src/sage/rings/padics/relative_extension_leaves.py b/src/sage/rings/padics/relative_extension_leaves.py index 455af0bdd35..a9f20adce21 100644 --- a/src/sage/rings/padics/relative_extension_leaves.py +++ b/src/sage/rings/padics/relative_extension_leaves.py @@ -210,7 +210,7 @@ def __init__(self, exact_modulus, approx_modulus, prec, print_mode, shift_seed, """ self._exact_modulus = exact_modulus unram_prec = (prec + approx_modulus.degree() - 1) // approx_modulus.degree() - KFP = approx_modulus.base_ring().change(prec = unram_prec+1) + KFP = approx_modulus.base_ring().change(prec=unram_prec+1) self.prime_pow = PowComputer_relative_maker(approx_modulus.base_ring().prime(), max(min(unram_prec - 1, 30), 1), unram_prec, prec, False, exact_modulus.change_ring(KFP), shift_seed.change_ring(KFP), 'fixed-mod') self._implementation = 'Polynomial' EisensteinExtensionGeneric.__init__(self, approx_modulus, prec, print_mode, names, RelativeRamifiedFixedModElement) diff --git a/src/sage/rings/padics/unramified_extension_generic.py b/src/sage/rings/padics/unramified_extension_generic.py index c0602e71ca0..b73b88ebc1c 100644 --- a/src/sage/rings/padics/unramified_extension_generic.py +++ b/src/sage/rings/padics/unramified_extension_generic.py @@ -52,7 +52,7 @@ def __init__(self, poly, prec, print_mode, names, element_class): #else: # self._PQR = pqr.PolynomialQuotientRing_domain(poly.parent(), poly, name = names) pAdicExtensionGeneric.__init__(self, poly, prec, print_mode, names, element_class) - self._res_field = GF(self.prime_pow.pow_Integer_Integer(poly.degree()), name = names[1], modulus = poly.change_ring(poly.base_ring().residue_field())) + self._res_field = GF(self.prime_pow.pow_Integer_Integer(poly.degree()), name=names[1], modulus=poly.change_ring(poly.base_ring().residue_field())) def _extension_type(self): """ @@ -211,7 +211,7 @@ def gen(self, n=0): return self([0,1]) @cached_method - def _frob_gen(self, arithmetic = True): + def _frob_gen(self, arithmetic=True): """ Return frobenius of the generator for this unramified extension diff --git a/src/sage/rings/polynomial/groebner_fan.py b/src/sage/rings/polynomial/groebner_fan.py index 6c6548d9e85..5177b2eaf27 100644 --- a/src/sage/rings/polynomial/groebner_fan.py +++ b/src/sage/rings/polynomial/groebner_fan.py @@ -1157,8 +1157,7 @@ def __iter__(self): sage: next(a) [y^9 - 3*y^6 + 3*y^3 - y - 1, -y^3 + x + 1] """ - for x in self.reduced_groebner_bases(): - yield x + yield from self.reduced_groebner_bases() def __getitem__(self, i): """ diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index 8a4c88045e5..1634e061d28 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -1,7 +1,6 @@ r""" Elements of Laurent polynomial rings """ - # **************************************************************************** # 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 @@ -9,17 +8,15 @@ Elements of Laurent polynomial rings # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - -from sage.rings.integer cimport Integer from sage.categories.map cimport Map from sage.structure.element import coerce_binop, parent from sage.structure.factorization import Factorization from sage.misc.derivative import multi_derivative -from sage.rings.polynomial.polydict cimport monomial_exponent from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.polynomial.polynomial_ring import is_PolynomialRing from sage.structure.richcmp cimport richcmp, rich_to_bool + cdef class LaurentPolynomial(CommutativeAlgebraElement): """ Base class for Laurent polynomials. diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx index 4597219b678..b442c073250 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -1,7 +1,6 @@ r""" Elements of multivariate Laurent polynomial rings """ - # **************************************************************************** # 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 @@ -11,14 +10,11 @@ Elements of multivariate Laurent polynomial rings # **************************************************************************** from sage.rings.integer cimport Integer -from sage.categories.map cimport Map from sage.structure.element cimport CommutativeAlgebraElement, Element, ModuleElement, RingElement -from sage.structure.element import is_Element, coerce_binop, parent +from sage.structure.element import coerce_binop, parent from sage.structure.factorization import Factorization from sage.misc.derivative import multi_derivative from sage.rings.polynomial.polydict cimport monomial_exponent -from sage.rings.polynomial.polynomial_element import Polynomial -from sage.structure.richcmp cimport richcmp, rich_to_bool from sage.matrix.matrix0 cimport Matrix diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py index 93d8f9a4fc0..014fa20efaa 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py @@ -433,7 +433,7 @@ def is_finite(self): """ return False - def is_field(self, proof = True): + def is_field(self, proof=True): """ EXAMPLES:: @@ -480,7 +480,7 @@ def krull_dimension(self): """ raise NotImplementedError - def random_element(self, low_degree = -2, high_degree = 2, terms = 5, choose_degree=False,*args, **kwds): + def random_element(self, low_degree=-2, high_degree=2, terms=5, choose_degree=False,*args, **kwds): """ EXAMPLES:: @@ -530,11 +530,11 @@ def change_ring(self, base_ring=None, names=None, sparse=False, order=None): if names is None: names = self.variable_names() if isinstance(self, LaurentPolynomialRing_univariate): - return LaurentPolynomialRing(base_ring, names[0], sparse = sparse) + return LaurentPolynomialRing(base_ring, names[0], sparse=sparse) if order is None: order = self.polynomial_ring().term_order() - return LaurentPolynomialRing(base_ring, self._n, names, order = order) + return LaurentPolynomialRing(base_ring, self._n, names, order=order) def fraction_field(self): """ diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 2e007d4db5c..86d62c77bf9 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -2119,13 +2119,13 @@ def factor(self, proof=None): # try to use univariate factoring try: F = self.univariate_polynomial().factor() - return Factorization([(R(f),m) for f,m in F], unit=F.unit()) + return Factorization([(R(f), m) for f, m in F], unit=F.unit()) except TypeError: pass base_ring = self.base_ring() if base_ring.is_finite(): - if base_ring.characteristic() > 1<<29: + if base_ring.characteristic() > 1 << 29: raise NotImplementedError("Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") if proof is None: diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index b1d3bc8eaf4..98171e337cd 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -3052,7 +3052,7 @@ def hilbert_series(self, grading=None, algorithm='sage'): @require_field @handle_AA_and_QQbar - def hilbert_numerator(self, grading = None, algorithm = 'sage'): + def hilbert_numerator(self, grading=None, algorithm='sage'): r""" Return the Hilbert numerator of this ideal. @@ -3419,7 +3419,7 @@ def _reduce_using_macaulay2(self, f): return R(k) class NCPolynomialIdeal(MPolynomialIdeal_singular_repr, Ideal_nc): - def __init__(self, ring, gens, coerce=True, side = "left"): + def __init__(self, ring, gens, coerce=True, side="left"): r""" Creates a non-commutative polynomial ideal. @@ -3464,7 +3464,7 @@ def __init__(self, ring, gens, coerce=True, side = "left"): raise ValueError("Only left and two-sided ideals are allowed.") Ideal_nc.__init__(self, ring, gens, coerce=coerce, side=side) - def __call_singular(self, cmd, arg = None): + def __call_singular(self, cmd, arg=None): """ Internal function for calling a Singular function. diff --git a/src/sage/rings/polynomial/pbori/blocks.py b/src/sage/rings/polynomial/pbori/blocks.py index 4115c35f832..752e0a14ee8 100644 --- a/src/sage/rings/polynomial/pbori/blocks.py +++ b/src/sage/rings/polynomial/pbori/blocks.py @@ -366,8 +366,7 @@ def canonicalize(blocks): if isinstance(elt, str): yield elt else: - for subelt in elt: - yield subelt + yield from elt blocks = list(blocks) n = 0 diff --git a/src/sage/rings/polynomial/polynomial_element_generic.py b/src/sage/rings/polynomial/polynomial_element_generic.py index 2f012daca29..cf4e6344a8c 100644 --- a/src/sage/rings/polynomial/polynomial_element_generic.py +++ b/src/sage/rings/polynomial/polynomial_element_generic.py @@ -1108,12 +1108,12 @@ class Polynomial_generic_sparse_field(Polynomial_generic_sparse, Polynomial_gene sage: loads(f.dumps()) == f True """ - def __init__(self, parent, x=None, check=True, is_gen = False, construct=False): + def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): Polynomial_generic_sparse.__init__(self, parent, x, check, is_gen) class Polynomial_generic_dense_field(Polynomial_generic_dense, Polynomial_generic_field): - def __init__(self, parent, x=None, check=True, is_gen = False, construct=False): + def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): Polynomial_generic_dense.__init__(self, parent, x, check, is_gen) diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index c1ddac1ae1f..f30f9c58885 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -1031,7 +1031,7 @@ class of the image of the generator of the polynomial ring. self.__gen = self(self.polynomial_ring().gen()) return self.__gen - def is_field(self, proof = True): + def is_field(self, proof=True): """ Return whether or not this quotient ring is a field. @@ -1077,7 +1077,7 @@ def is_field(self, proof = True): self._refine_category_(Fields()) return ret - def is_integral_domain(self, proof = True): + def is_integral_domain(self, proof=True): """ Return whether or not this quotient ring is an integral domain. diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index ff1d3532124..5e6203a05c3 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -541,7 +541,7 @@ def _implementation_names_impl(implementation, base_ring, sparse): return [None, "generic"] return NotImplemented - def is_integral_domain(self, proof = True): + def is_integral_domain(self, proof=True): """ EXAMPLES:: @@ -552,7 +552,7 @@ def is_integral_domain(self, proof = True): """ return self.base_ring().is_integral_domain(proof) - def is_unique_factorization_domain(self, proof = True): + def is_unique_factorization_domain(self, proof=True): """ EXAMPLES:: @@ -1065,9 +1065,9 @@ def change_var(self, var): """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - return PolynomialRing(self.base_ring(), names = var, sparse=self.is_sparse()) + return PolynomialRing(self.base_ring(), names=var, sparse=self.is_sparse()) - def extend_variables(self, added_names, order = 'degrevlex'): + def extend_variables(self, added_names, order='degrevlex'): r""" Return a multivariate polynomial ring with the same base ring but with ``added_names`` as additional variables. @@ -1085,7 +1085,7 @@ def extend_variables(self, added_names, order = 'degrevlex'): if isinstance(added_names, str): added_names = added_names.split(',') - return PolynomialRing(self.base_ring(), names = self.variable_names() + tuple(added_names), order = order) + return PolynomialRing(self.base_ring(), names=self.variable_names() + tuple(added_names), order=order) def variable_names_recursive(self, depth=sage.rings.infinity.infinity): r""" @@ -1246,7 +1246,7 @@ def parameter(self): def is_exact(self): return self.base_ring().is_exact() - def is_field(self, proof = True): + def is_field(self, proof=True): """ Return False, since polynomial rings are never fields. @@ -1444,7 +1444,7 @@ def random_element(self, degree=(-1,2), *args, **kwds): return p - def _monics_degree( self, of_degree ): + def _monics_degree(self, of_degree): """ Refer to monics() for full documentation. """ @@ -1455,15 +1455,14 @@ def _monics_degree( self, of_degree ): coeffs.reverse() yield self(coeffs) - def _monics_max( self, max_degree ): + def _monics_max(self, max_degree): """ Refer to monics() for full documentation. """ for degree in range(max_degree + 1): - for m in self._monics_degree( degree ): - yield m + yield from self._monics_degree(degree) - def _polys_degree( self, of_degree ): + def _polys_degree(self, of_degree): """ Refer to polynomials() for full documentation. """ @@ -1553,7 +1552,7 @@ def set_karatsuba_threshold(self, Karatsuba_threshold): """ self._Karatsuba_threshold = int(Karatsuba_threshold) - def polynomials( self, of_degree = None, max_degree = None ): + def polynomials( self, of_degree=None, max_degree=None ): """ Return an iterator over the polynomials of specified degree. @@ -1618,7 +1617,7 @@ def polynomials( self, of_degree = None, max_degree = None ): return self._polys_max( max_degree ) raise ValueError("you should pass exactly one of of_degree and max_degree") - def monics( self, of_degree = None, max_degree = None ): + def monics( self, of_degree=None, max_degree=None ): """ Return an iterator over the monic polynomials of specified degree. @@ -1793,8 +1792,8 @@ def _roots_univariate_polynomial(self, p, ring=None, multiplicities=True, algori if ring is not None and ring is not self: p = p.change_ring(ring) if degree_bound is None: - return p.roots(multiplicities = multiplicities, algorithm = algorithm) - return p.roots(multiplicities = multiplicities, algorithm = algorithm, degree_bound = degree_bound) + return p.roots(multiplicities=multiplicities, algorithm=algorithm) + return p.roots(multiplicities=multiplicities, algorithm=algorithm, degree_bound=degree_bound) roots = p._roots_from_factorization(p.factor(), multiplicities) if degree_bound is not None: diff --git a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx index 6f30bf046d5..60ad8d82966 100644 --- a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx @@ -30,17 +30,17 @@ AUTHORS: - Burcin Erocal (2008-11) initial implementation - Martin Albrecht (2009-01) another initial implementation """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2009-2010 Burcin Erocal # Copyright (C) 2009 Martin Albrecht # # Distributed under the terms of the GNU General Public License (GPL), # version 2 or any later version. The full text of the GPL is available at: -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.libs.ntl.ntl_lzz_pX import ntl_zz_pX -from sage.structure.factorization import Factorization +from sage.structure.factorization import Factorization # removing breaks build from sage.structure.element cimport parent from sage.structure.element import coerce_binop from sage.rings.polynomial.polynomial_integer_dense_flint cimport Polynomial_integer_dense_flint diff --git a/src/sage/rings/power_series_ring.py b/src/sage/rings/power_series_ring.py index 65ed3311cd8..e023867b67e 100644 --- a/src/sage/rings/power_series_ring.py +++ b/src/sage/rings/power_series_ring.py @@ -1013,7 +1013,7 @@ def change_ring(self, R): Power Series Ring in T over Number Field in a with defining polynomial x^2 - 3 with a = 1.732050807568878? """ - return PowerSeriesRing(R, name = self.variable_name(), default_prec = self.default_prec()) + return PowerSeriesRing(R, name=self.variable_name(), default_prec=self.default_prec()) def change_var(self, var): """ @@ -1026,7 +1026,7 @@ def change_var(self, var): sage: R.change_var('D') Power Series Ring in D over Rational Field """ - return PowerSeriesRing(self.base_ring(), names = var, sparse=self.is_sparse()) + return PowerSeriesRing(self.base_ring(), names=var, sparse=self.is_sparse()) def is_exact(self): """ @@ -1184,7 +1184,7 @@ def __contains__(self, x): """ return self.has_coerce_map_from(parent(x)) - def is_field(self, proof = True): + def is_field(self, proof=True): """ Return ``False`` since the ring of power series over any ring is never a field. @@ -1351,4 +1351,4 @@ def unpickle_power_series_ring_v0(base_ring, name, default_prec, sparse): sage: loads(dumps(P)) == P # indirect doctest True """ - return PowerSeriesRing(base_ring, name=name, default_prec = default_prec, sparse=sparse) + return PowerSeriesRing(base_ring, name=name, default_prec=default_prec, sparse=sparse) diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 2a6f7ec70c7..f8eaf63c934 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -1012,7 +1012,7 @@ def NF_elem_map(e): trial = Factorization(factorization).value() - return Factorization(factorization, unit = f.lc() / trial.lc()) + return Factorization(factorization, unit=f.lc() / trial.lc()) class AlgebraicRealField(Singleton, AlgebraicField_common, sage.rings.abc.AlgebraicRealField): diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index b683889b79a..11ac5510cf9 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -832,7 +832,7 @@ def defining_ideal(self): return self.__I @cached_method - def is_field(self, proof = True): + def is_field(self, proof=True): r""" Returns ``True`` if the quotient ring is a field. Checks to see if the defining ideal is maximal. diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index a82c5493545..3fb31328e76 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -318,7 +318,7 @@ def construction(self): from . import integer_ring return FractionField(), integer_ring.ZZ - def completion(self, p, prec, extras = {}): + def completion(self, p, prec, extras={}): r""" Return the completion of `\QQ` at `p`. @@ -540,8 +540,7 @@ def primes_of_bounded_norm_iter(self, B): return from sage.arith.misc import primes - for p in primes(B+1): - yield p + yield from primes(B + 1) def discriminant(self): """ diff --git a/src/sage/rings/valuation/value_group.py b/src/sage/rings/valuation/value_group.py index 159bb675664..816f142e0c7 100644 --- a/src/sage/rings/valuation/value_group.py +++ b/src/sage/rings/valuation/value_group.py @@ -676,8 +676,7 @@ def some_elements(self): yield self(0) if self.is_trivial(): return - for g in self._generators: - yield g + yield from self._generators from sage.rings.integer_ring import ZZ for x in (ZZ**len(self._generators)).some_elements(): yield QQ.coerce(sum([abs(c) * g diff --git a/src/sage/schemes/elliptic_curves/BSD.py b/src/sage/schemes/elliptic_curves/BSD.py index f5522de2e00..85130f0a5f9 100644 --- a/src/sage/schemes/elliptic_curves/BSD.py +++ b/src/sage/schemes/elliptic_curves/BSD.py @@ -3,6 +3,7 @@ from sage.arith.misc import prime_divisors from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ from sage.rings.infinity import Infinity from sage.rings.number_field.number_field import QuadraticField from sage.functions.other import ceil @@ -89,11 +90,17 @@ def simon_two_descent_work(E, two_tor_rk): sage: from sage.schemes.elliptic_curves.BSD import simon_two_descent_work sage: E = EllipticCurve('14a') sage: simon_two_descent_work(E, E.two_torsion_rank()) + doctest:warning + ... + DeprecationWarning: Use E.rank(algorithm="pari") instead, as this script has been ported over to pari. + See https://github.com/sagemath/sage/issues/35621 for details. (0, 0, 0, 0, []) sage: E = EllipticCurve('37a') sage: simon_two_descent_work(E, E.two_torsion_rank()) (1, 1, 0, 0, [(0 : 0 : 1)]) """ + from sage.misc.superseded import deprecation + deprecation(35621, 'Use the two-descent in pari instead, as this script has been ported over to pari.') rank_lower_bd, two_sel_rk, gens = E.simon_two_descent() rank_upper_bd = two_sel_rk - two_tor_rk gens = [P for P in gens if P.additive_order() == Infinity] @@ -140,6 +147,55 @@ def mwrank_two_descent_work(E, two_tor_rk): sha2_upper_bd = MWRC.selmer_rank() - two_tor_rk - rank_lower_bd return rank_lower_bd, rank_upper_bd, sha2_lower_bd, sha2_upper_bd, gens +def pari_two_descent_work(E): + r""" + Prepare the output from pari by two-isogeny. + + INPUT: + + - ``E`` -- an elliptic curve + + OUTPUT: A tuple of 5 elements with the first 4 being integers. + + - a lower bound on the rank + + - an upper bound on the rank + + - a lower bound on the rank of Sha[2] + + - an upper bound on the rank of Sha[2] + + - a list of the generators found + + EXAMPLES:: + + sage: from sage.schemes.elliptic_curves.BSD import pari_two_descent_work + sage: E = EllipticCurve('14a') + sage: pari_two_descent_work(E) + (0, 0, 0, 0, []) + sage: E = EllipticCurve('37a') + sage: pari_two_descent_work(E) # random, up to sign + (1, 1, 0, 0, [(0 : -1 : 1)]) + sage: E = EllipticCurve('210e7') + sage: pari_two_descent_work(E) + (0, 2, 0, 2, []) + sage: E = EllipticCurve('66b3') + sage: pari_two_descent_work(E) + (0, 0, 2, 2, []) + + """ + ep = E.pari_curve() + lower, rank_upper_bd, s, pts = ep.ellrank() + gens = sorted([E.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts]) + gens = E.saturation(gens)[0] + # this is explained in the pari-gp documentation: + # s is the dimension of Sha[2]/2Sha[4], + # which is a lower bound for dim Sha[2] + # dim Sha[2] = dim Sel2 - rank E(Q) - dim tors + # rank_upper_bd = dim Sel_2 - dim tors - s + sha_upper_bd = rank_upper_bd - len(gens) + s + return len(gens), rank_upper_bd, s, sha_upper_bd, gens + def native_two_isogeny_descent_work(E, two_tor_rk): """ @@ -254,7 +310,7 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, - 2: print information about remaining primes - ``two_desc`` -- string (default ``'mwrank'``), what to use for the - two-descent. Options are ``'mwrank', 'simon', 'sage'`` + two-descent. Options are ``'mwrank', 'pari', 'sage'`` - ``proof`` -- bool or None (default: None, see proof.elliptic_curve or sage.structure.proof). If False, this @@ -317,7 +373,7 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, True for p = 3 by Kolyvagin bound True for p = 5 by Kolyvagin bound [] - sage: E.prove_BSD(two_desc='simon') + sage: E.prove_BSD(two_desc='pari') [] A rank two curve:: @@ -433,6 +489,15 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, p = 2: True by 2-descent True for p not in {2} by Kolyvagin. [] + + :: + + sage: E = EllipticCurve('66b3') + sage: E.prove_BSD(two_desc="pari",verbosity=1) + p = 2: True by 2-descent + True for p not in {2} by Kolyvagin. + [] + """ if proof is None: from sage.structure.proof.proof import get_flag @@ -461,8 +526,8 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, if two_desc == 'mwrank': M = mwrank_two_descent_work(BSD.curve, BSD.two_tor_rk) - elif two_desc == 'simon': - M = simon_two_descent_work(BSD.curve, BSD.two_tor_rk) + elif two_desc == 'pari': + M = pari_two_descent_work(BSD.curve) elif two_desc == 'sage': M = native_two_isogeny_descent_work(BSD.curve, BSD.two_tor_rk) else: diff --git a/src/sage/schemes/elliptic_curves/constructor.py b/src/sage/schemes/elliptic_curves/constructor.py index eae54a05fcd..770295962dd 100644 --- a/src/sage/schemes/elliptic_curves/constructor.py +++ b/src/sage/schemes/elliptic_curves/constructor.py @@ -308,7 +308,7 @@ class EllipticCurveFactory(UniqueFactory): TypeError: invalid input to EllipticCurve constructor """ def create_key_and_extra_args(self, x=None, y=None, j=None, minimal_twist=True, **kwds): - """ + r""" Return a ``UniqueFactory`` key and possibly extra parameters. INPUT: See the documentation for :class:`EllipticCurveFactory`. @@ -329,7 +329,7 @@ def create_key_and_extra_args(self, x=None, y=None, j=None, minimal_twist=True, sage: EllipticCurve.create_key_and_extra_args(j=8000) ((Rational Field, (0, 1, 0, -3, 1)), {}) - When constructing a curve over `\\QQ` from a Cremona or LMFDB + When constructing a curve over `\QQ` from a Cremona or LMFDB label, the invariants from the database are returned as ``extra_args``:: @@ -454,7 +454,7 @@ def create_key_and_extra_args(self, x=None, y=None, j=None, minimal_twist=True, return (R, tuple(R(a) for a in x)), kwds def create_object(self, version, key, **kwds): - """ + r""" Create an object from a ``UniqueFactory`` key. EXAMPLES:: @@ -466,7 +466,7 @@ def create_object(self, version, key, **kwds): .. NOTE:: Keyword arguments are currently only passed to the - constructor for elliptic curves over `\\QQ`; elliptic + constructor for elliptic curves over `\QQ`; elliptic curves over other fields do not support them. """ R, x = key @@ -494,7 +494,7 @@ def create_object(self, version, key, **kwds): def EllipticCurve_from_Weierstrass_polynomial(f): - """ + r""" Return the elliptic curve defined by a cubic in (long) Weierstrass form. @@ -534,7 +534,7 @@ def EllipticCurve_from_Weierstrass_polynomial(f): return EllipticCurve(coefficients_from_Weierstrass_polynomial(f)) def coefficients_from_Weierstrass_polynomial(f): - """ + r""" Return the coefficients `[a_1, a_2, a_3, a_4, a_6]` of a cubic in Weierstrass form. @@ -582,7 +582,7 @@ def coefficients_from_Weierstrass_polynomial(f): def EllipticCurve_from_c4c6(c4, c6): - """ + r""" Return an elliptic curve with given `c_4` and `c_6` invariants. @@ -664,7 +664,7 @@ def EllipticCurve_from_j(j, minimal_twist=True): def coefficients_from_j(j, minimal_twist=True): - """ + r""" Return Weierstrass coefficients `(a_1, a_2, a_3, a_4, a_6)` for an elliptic curve with given `j`-invariant. @@ -680,7 +680,7 @@ def coefficients_from_j(j, minimal_twist=True): sage: coefficients_from_j(1) [1, 0, 0, 36, 3455] - The ``minimal_twist`` parameter (ignored except over `\\QQ` and + The ``minimal_twist`` parameter (ignored except over `\QQ` and True by default) controls whether or not a minimal twist is computed:: @@ -1238,7 +1238,7 @@ def EllipticCurve_from_cubic(F, P=None, morphism=True): def tangent_at_smooth_point(C,P): - """Return the tangent at the smooth point `P` of projective curve `C`. + r"""Return the tangent at the smooth point `P` of projective curve `C`. INPUT: @@ -1278,7 +1278,7 @@ def tangent_at_smooth_point(C,P): return C.tangents(P,factor=False)[0] def chord_and_tangent(F, P): - """Return the third point of intersection of a cubic with the tangent at one point. + r"""Return the third point of intersection of a cubic with the tangent at one point. INPUT: @@ -1352,7 +1352,7 @@ def chord_and_tangent(F, P): def projective_point(p): - """ + r""" Return equivalent point with denominators removed INPUT: @@ -1384,7 +1384,7 @@ def projective_point(p): def are_projectively_equivalent(P, Q, base_ring): - """ + r""" Test whether ``P`` and ``Q`` are projectively equivalent. INPUT: @@ -1409,7 +1409,7 @@ def are_projectively_equivalent(P, Q, base_ring): def EllipticCurves_with_good_reduction_outside_S(S=[], proof=None, verbose=False): r""" - Return a sorted list of all elliptic curves defined over `Q` + Return a sorted list of all elliptic curves defined over `\QQ` with good reduction outside the set `S` of primes. INPUT: diff --git a/src/sage/schemes/elliptic_curves/ell_finite_field.py b/src/sage/schemes/elliptic_curves/ell_finite_field.py index cd1e9c1733c..a46d722fb51 100644 --- a/src/sage/schemes/elliptic_curves/ell_finite_field.py +++ b/src/sage/schemes/elliptic_curves/ell_finite_field.py @@ -861,8 +861,7 @@ def __iter__(self): ... (10 : 0 : 1) 2 """ - for P in self.points(): - yield P + yield from self.points() def __getitem__(self, n): """ diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 7aa20a1c2c1..b5f5de2bd3f 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -""" +r""" Elliptic curves over the rational numbers AUTHORS: @@ -200,7 +200,7 @@ def __init__(self, ainvs, **kwds): self._set_torsion_order(kwds['torsion_order']) def _set_rank(self, r): - """ + r""" Internal function to set the cached rank of this elliptic curve to ``r``. @@ -221,7 +221,7 @@ def _set_rank(self, r): self.__rank = (Integer(r), True) def _set_torsion_order(self, t): - """ + r""" Internal function to set the cached torsion order of this elliptic curve to ``t``. @@ -242,7 +242,7 @@ def _set_torsion_order(self, t): self.__torsion_order = Integer(t) def _set_cremona_label(self, L): - """ + r""" Internal function to set the cached label of this elliptic curve to ``L``. @@ -267,7 +267,7 @@ def _set_cremona_label(self, L): self.__cremona_label = L def _set_conductor(self, N): - """ + r""" Internal function to set the cached conductor of this elliptic curve to ``N.`` @@ -288,7 +288,7 @@ def _set_conductor(self, N): self.__conductor_pari = Integer(N) def _set_modular_degree(self, deg): - """ + r""" Internal function to set the cached modular degree of this elliptic curve to ``deg``. @@ -309,7 +309,7 @@ def _set_modular_degree(self, deg): self.__modular_degree = Integer(deg) def _set_gens(self, gens): - """ + r""" Internal function to set the cached generators of this elliptic curve to ``gens``. @@ -382,7 +382,7 @@ def is_p_integral(self, p): return bool(misc.mul([x.valuation(p) >= 0 for x in self.ainvs()])) def is_integral(self): - """ + r""" Return ``True`` if this elliptic curve has integral coefficients (in Z). @@ -476,7 +476,7 @@ def mwrank(self, options=''): return mwrank(list(self.a_invariants())) def conductor(self, algorithm="pari"): - """ + r""" Return the conductor of the elliptic curve. INPUT: @@ -576,7 +576,7 @@ def conductor(self, algorithm="pari"): #################################################################### def pari_curve(self): - """ + r""" Return the PARI curve corresponding to this elliptic curve. EXAMPLES:: @@ -629,7 +629,7 @@ def pari_curve(self): return self._pari_curve def pari_mincurve(self): - """ + r""" Return the PARI curve corresponding to a minimal model for this elliptic curve. @@ -653,7 +653,7 @@ def pari_mincurve(self): @cached_method def database_attributes(self): - """ + r""" Return a dictionary containing information about ``self`` in the elliptic curve database. @@ -688,7 +688,7 @@ def database_attributes(self): raise LookupError("Cremona database does not contain entry for " + repr(self)) def database_curve(self): - """ + r""" Return the curve in the elliptic curve database isomorphic to this curve, if possible. Otherwise raise a ``LookupError`` exception. @@ -760,7 +760,7 @@ def Np(self, p): # Access to mwrank #################################################################### def mwrank_curve(self, verbose=False): - """ + r""" Construct an mwrank_EllipticCurve from this elliptic curve The resulting mwrank_EllipticCurve has available methods from John @@ -792,7 +792,7 @@ def two_descent(self, verbose=True, second_limit=8, n_aux=-1, second_descent=1): - """ + r""" Compute 2-descent data for this curve. INPUT: @@ -1362,7 +1362,7 @@ def f(r): return f def pollack_stevens_modular_symbol(self, sign=0, implementation='eclib'): - """ + r""" Create the modular symbol attached to the elliptic curve, suitable for overconvergent calculations. @@ -1777,6 +1777,13 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=3, Return lower and upper bounds on the rank of the Mordell-Weil group `E(\QQ)` and a list of points of infinite order. + .. WARNING:: + + This function is deprecated as the functionality of + Simon's script for elliptic curves over the rationals + has been ported over to pari. + Use :meth:`.rank` with the keyword ``algorithm='pari'`` instead. + INPUT: - ``verbose`` -- 0, 1, 2, or 3 (default: 0), the verbosity level @@ -1829,6 +1836,10 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=3, sage: E = EllipticCurve('11a1') sage: E.simon_two_descent() + doctest:warning + ... + DeprecationWarning: Use E.rank(algorithm="pari") instead, as this script has been ported over to pari. + See https://github.com/sagemath/sage/issues/35621 for details. (0, 0, []) sage: E = EllipticCurve('37a1') sage: E.simon_two_descent() @@ -1909,6 +1920,9 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=3, sage: E.selmer_rank() # uses mwrank 1 """ + from sage.misc.superseded import deprecation + deprecation(35621, 'Use E.rank(algorithm="pari") instead, as this script has been ported over to pari.') + t = EllipticCurve_number_field.simon_two_descent(self, verbose=verbose, lim1=lim1, lim3=lim3, limtriv=limtriv, maxprob=maxprob, limbigprime=limbigprime, @@ -1978,8 +1992,9 @@ def three_selmer_rank(self, algorithm='UseSUnits'): def rank(self, use_database=True, verbose=False, only_use_mwrank=True, algorithm='mwrank_lib', - proof=None): - """ + proof=None, + pari_effort=0): + r""" Return the rank of this elliptic curve, assuming no conjectures. If we fail to provably compute the rank, raises a RuntimeError @@ -1999,6 +2014,8 @@ def rank(self, use_database=True, verbose=False, - ``'mwrank_lib'`` -- call mwrank c library + - ``'pari'`` -- call ellrank in pari + - ``only_use_mwrank`` -- (default: ``True``) if ``False`` try using analytic rank methods first @@ -2006,9 +2023,15 @@ def rank(self, use_database=True, verbose=False, ``proof.elliptic_curve`` or ``sage.structure.proof``); note that results obtained from databases are considered ``proof=True`` + - ``pari_effort`` -- (default: 0) parameter used in when + the algorithm ``pari`` is chosen. It measure of the effort + done to find rational points. Values up to 10 can be chosen; + the running times increase roughly like the cube of the + effort value. + OUTPUT: the rank of the elliptic curve as :class:`Integer` - IMPLEMENTATION: Uses L-functions, mwrank, and databases. + IMPLEMENTATION: Uses L-functions, mwrank, pari, and databases. EXAMPLES:: @@ -2024,7 +2047,7 @@ def rank(self, use_database=True, verbose=False, 4 sage: EllipticCurve([0, 0, 1, -79, 342]).rank(proof=False) 5 - sage: EllipticCurve([0, 0, 1, -79, 342]).simon_two_descent()[0] # long time (7s on sage.math, 2012) + sage: EllipticCurve([0, 0, 1, -79, 342]).rank(algorithm="pari") 5 Examples with denominators in defining equations:: @@ -2038,7 +2061,7 @@ def rank(self, use_database=True, verbose=False, sage: E.minimal_model().rank() 1 - A large example where mwrank doesn't determine the result with certainty:: + A large example where mwrank doesn't determine the result with certainty, but pari does:: sage: EllipticCurve([1,0,0,0,37455]).rank(proof=False) 0 @@ -2046,6 +2069,8 @@ def rank(self, use_database=True, verbose=False, Traceback (most recent call last): ... RuntimeError: rank not provably correct (lower bound: 0) + sage: EllipticCurve([1,0,0,0,37455]).rank(algorithm="pari") + 0 TESTS:: @@ -2054,6 +2079,14 @@ def rank(self, use_database=True, verbose=False, ... ValueError: unknown algorithm 'garbage' + An example to check if the points are saturated:: + + sage: E = EllipticCurve([0,0, 1, -7, 6]) + sage: E.gens(use_database=False, algorithm="pari") # random + [(2 : 0 : 1), (-1 : 3 : 1), (11 : 35 : 1)] + sage: E.saturation(_)[1] + 1 + Since :trac:`23962`, the default is to use the Cremona database. We also check that the result is cached correctly:: @@ -2068,6 +2101,15 @@ def rank(self, use_database=True, verbose=False, 0 sage: E._EllipticCurve_rational_field__rank (0, True) + + This example has Sha = Z/4 x Z/4 and the rank cannot be + determined using pari only:: + + sage: E =EllipticCurve([-113^2,0]) + sage: E.rank(use_database=False, verbose=False, algorithm="pari") + Traceback (most recent call last): + ... + RuntimeError: rank not provably correct (lower bound: 0, upper bound:2). Hint: increase pari_effort. """ if proof is None: from sage.structure.proof.proof import get_flag @@ -2168,6 +2210,27 @@ def rank(self, use_database=True, verbose=False, self.__rank = (rank, proof) return rank + if algorithm == 'pari': + ep = self.pari_curve() + # if we know already some points in _known_points + # we can give them to pari to speed it up + kpts = [ [x[0],x[1]] for x in self._known_points ] + lower, upper, s, pts = ep.ellrank(pari_effort, kpts) + ge = sorted([self.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts]) + ge = self.saturation(ge)[0] + self._known_points = ge + # note that lower is only a conjectural + # lower bound for the rank, the only + # proven lower bound is #ge. + if len(ge) == upper: + verbose_verbose(f"rank {upper} unconditionally determined by pari") + rank = Integer(upper) + self.__rank = (rank, True) + self.__gens = (ge, True) + return rank + else: + verbose_verbose(f"Warning -- rank could not be determined by pari; ellrank returned {lower=}, {upper=}, {s=}, {pts=}", level=1) + raise RuntimeError(f"rank not provably correct (lower bound: {len(ge)}, upper bound:{upper}). Hint: increase pari_effort.") raise ValueError("unknown algorithm {!r}".format(algorithm)) def gens(self, proof=None, **kwds): @@ -2194,6 +2257,8 @@ def gens(self, proof=None, **kwds): - ``'mwrank_lib'`` -- call mwrank C library + - ``'pari'`` -- use ellrank in pari + - ``only_use_mwrank`` -- bool (default True) if False, first attempts to use more naive, natively implemented methods @@ -2207,6 +2272,12 @@ def gens(self, proof=None, **kwds): points found by two-descent in the Mordell-Weil group is greater than this, a warning message will be displayed. + - ``pari_effort`` -- (default: 0) parameter used in when + the algorithm ``pari`` is chosen. It measure of the effort + done to find rational points. Values up to 10 can be chosen, + the running times increase roughly like the cube of the + effort value. + OUTPUT: - ``generators`` -- list of generators for the Mordell-Weil @@ -2218,13 +2289,18 @@ def gens(self, proof=None, **kwds): :meth:`~gens_certain` method to find out afterwards whether the generators were proved. - IMPLEMENTATION: Uses Cremona's mwrank C library. + IMPLEMENTATION: Uses Cremona's mwrank C++ library or ellrank in pari. EXAMPLES:: sage: E = EllipticCurve('389a') sage: E.gens() # random output [(-1 : 1 : 1), (0 : 0 : 1)] + sage: E.gens(algorithm="pari") # random output + [(5/4 : 5/8 : 1), (0 : 0 : 1)] + sage: E = EllipticCurve([0,2429469980725060,0,275130703388172136833647756388,0]) + sage: len(E.gens(algorithm="pari")) + 14 A non-integral example:: @@ -2240,6 +2316,9 @@ def gens(self, proof=None, **kwds): over Rational Field sage: E1.gens() # random (if database not used) [(-400 : 8000 : 1), (0 : -8000 : 1)] + sage: E1.gens(algorithm="pari") #random + [(-400 : 8000 : 1), (0 : -8000 : 1)] + """ if proof is None: from sage.structure.proof.proof import get_flag @@ -2266,7 +2345,8 @@ def _compute_gens(self, proof, only_use_mwrank=True, use_database=True, descent_second_limit=12, - sat_bound=1000): + sat_bound=1000, + pari_effort=0): r""" Return generators for the Mordell-Weil group `E(Q)` *modulo* torsion. @@ -2289,6 +2369,25 @@ def _compute_gens(self, proof, sage: gens, proved = E._compute_gens(proof=False) sage: proved True + + TESTS:: + + sage: E = EllipticCurve([-127^2,0]) + sage: E.gens(use_database=False, algorithm="pari") + Traceback (most recent call last): + ... + RuntimeError: generators could not be determined. So far we found []. Hint: increase pari_effort. + sage: E.gens(use_database=False, algorithm="pari",pari_effort=4) + [(611429153205013185025/9492121848205441 : 15118836457596902442737698070880/924793900700594415341761 : 1)] + + sage: E = EllipticCurve([-157^2,0]) + sage: E.gens(use_database=False, algorithm="pari") + Traceback (most recent call last): + ... + RuntimeError: generators could not be determined. So far we found []. Hint: increase pari_effort. + sage: E.gens(use_database=False, algorithm="pari",pari_effort=10) # long time + [(-166136231668185267540804/2825630694251145858025 : 167661624456834335404812111469782006/150201095200135518108761470235125 : 1)] + """ # If the optional extended database is installed and an # isomorphic curve is in the database then its gens will be @@ -2333,7 +2432,29 @@ def _compute_gens(self, proof, except RuntimeError: pass # end if (not_use_mwrank) - if algorithm == "mwrank_lib": + if algorithm == "pari": + ep = self.pari_curve() + # if we know already some points in _known_points + # we can give them to pari to speed it up + kpts = [ [x[0],x[1]] for x in self._known_points ] + lower, upper, s, pts = ep.ellrank(pari_effort, kpts) + ge = sorted([self.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts]) + ge = self.saturation(ge)[0] + self._known_points = ge + # note that lower is only a conjectural + # lower bound for the rank, the only + # proven lower bound is #ge. + if len(ge) == upper: + verbose_verbose(f"rank {upper} unconditionally determined by pari") + rank = Integer(upper) + self.__rank = (rank, True) + if len(ge) == rank: + self.__gens = (ge, True) + return ge, True + # cases when we did not find all points + verbose_verbose(f"Warning -- generators could not be determined by pari; ellrank returned {lower=}, {upper=}, {s=}, {pts=}", level=1) + raise RuntimeError(f"generators could not be determined. So far we found {ge}. Hint: increase pari_effort.") + elif algorithm == "mwrank_lib": verbose_verbose("Calling mwrank C++ library.") if not self.is_integral(): xterm = 1 @@ -2398,7 +2519,7 @@ def _compute_gens(self, proof, return G, proved def gens_certain(self): - """ + r""" Return ``True`` if the generators have been proven correct. EXAMPLES:: @@ -2853,86 +2974,118 @@ def point_search(self, height_limit, verbose=False, rank_bound=None): points = self.saturation(points, verbose=verbose)[0] return points - def selmer_rank(self): + def selmer_rank(self, algorithm="pari"): r""" - The rank of the 2-Selmer group of the curve. + Return the rank of the 2-Selmer group of the curve. - EXAMPLES: The following is the curve 960D1, which has rank 0, but - Sha of order 4. + INPUT: - :: + - ``algorithm`` -- (default:``'pari'``) + either ``'pari'`` or ``'mwrank'`` - sage: E = EllipticCurve([0, -1, 0, -900, -10098]) - sage: E.selmer_rank() - 3 - - Here the Selmer rank is equal to the 2-torsion rank (=1) plus - the 2-rank of Sha (=2), and the rank itself is zero:: + EXAMPLES: + This example has rank 1, Sha[2] of order 4 and + a single rational 2-torsion point:: - sage: E.rank() - 0 + sage: E = EllipticCurve([1, 1, 1, 508, -2551]) + sage: E.selmer_rank() + 4 + sage: E.selmer_rank(algorithm="mwrank") + 4 - In contrast, for the curve 571A, also with rank 0 and Sha of - order 4, we get a worse bound:: + The following is the curve 960d1, which has rank 0, but + Sha of order 4:: - sage: E = EllipticCurve([0, -1, 1, -929, -10595]) + sage: E = EllipticCurve([0, -1, 0, -900, -10098]) sage: E.selmer_rank() - 2 - sage: E.rank_bound() - 2 + 3 + sage: E.selmer_rank(algorithm="mwrank") + 3 - To establish that the rank is in fact 0 in this case, we would - need to carry out a higher descent:: + This curve has rank 1, and 4 elements in Sha[2]. + Yet the order of Sha is 16, so that group is the product + of two cyclic groups of order 4:: - sage: E.three_selmer_rank() # optional - magma - 0 + sage: E = EllipticCurve([1, 0, 0, -150752, -22541610]) + sage: E.selmer_rank() + 4 - Or use the L-function to compute the analytic rank:: + Instead in this last example of rank 0, Sha is a product of four cyclic groups of order 2:: - sage: E.rank(only_use_mwrank=False) + sage: E = EllipticCurve([1, 0, 0, -49280, -4214808]) + sage: E.selmer_rank() + 5 + sage: E.rank() 0 """ try: return self.__selmer_rank except AttributeError: - C = self.mwrank_curve() - self.__selmer_rank = C.selmer_rank() - return self.__selmer_rank + if algorithm=="pari": + ep = self.pari_curve() + lower, upper, s, pts = ep.ellrank() + tor = self.two_torsion_rank() + return upper + tor + s + elif algorithm=="mwrank": + C = self.mwrank_curve() + self.__selmer_rank = C.selmer_rank() + return self.__selmer_rank + else: + raise ValueError(f"unknown {algorithm=}") - def rank_bound(self): + def rank_bound(self, algorithm="pari"): r""" - Upper bound on the rank of the curve, computed using - 2-descent. + Return the upper bound on the rank of the curve, + computed using a 2-descent. + + INPUT: + + - ``algorithm`` -- (default:``'pari'``) + either ``'pari'`` or ``'mwrank'`` In many cases, this is the actual rank of the - curve. If the curve has no 2-torsion it is the same as the - 2-selmer rank. + curve. - EXAMPLES: The following is the curve 960D1, which has rank 0, but - Sha of order 4. + EXAMPLES:: - :: + sage: E = EllipticCurve("389a1") + sage: E.rank_bound() + 2 - sage: E = EllipticCurve([0, -1, 0, -900, -10098]) + The following is the curve 571a1, which has + rank 0, but Sha of order 4, yet pari, using the Cassels + pairing is able to show that the rank is 0. + The 2-descent in mwrank only determines a weaker upper bound:: + + sage: E = EllipticCurve([0, -1, 1, -929, -10595]) sage: E.rank_bound() 0 + sage: E.rank_bound(algorithm="mwrank") + 2 - It gives 0 instead of 2, because it knows Sha is nontrivial. In - contrast, for the curve 571A, also with rank 0 and Sha of order 4, - we get a worse bound:: + In the following last example, both algorithm only determine a rank bound larger than the actual rank:: - sage: E = EllipticCurve([0, -1, 1, -929, -10595]) + sage: E = EllipticCurve([1, 1, 1, -896670, -327184905]) sage: E.rank_bound() 2 - sage: E.rank(only_use_mwrank=False) # uses L-function + sage: E.rank_bound(algorithm="mwrank") + 2 + sage: E.rank(only_use_mwrank=False) # uses L-function 0 """ try: return self.__rank_bound except AttributeError: - C = self.mwrank_curve() - self.__rank_bound = C.rank_bound() - return self.__rank_bound + if algorithm=="pari": + ep = self.pari_curve() + lower, upper, s, pts = ep.ellrank() + return upper + elif algorithm=="mwrank": + C = self.mwrank_curve() + self.__rank_bound = C.rank_bound() + return self.__rank_bound + else: + raise ValueError(f"unknown {algorithm=}") def an(self, n): r""" @@ -2948,7 +3101,7 @@ def an(self, n): return Integer(self.pari_mincurve().ellak(n)) def ap(self, p): - """ + r""" The ``p``-th Fourier coefficient of the modular form corresponding to this elliptic curve, where ``p`` is prime. @@ -3009,7 +3162,7 @@ def is_minimal(self): return self.ainvs() == self.minimal_model().ainvs() def is_p_minimal(self, p): - """ + r""" Tests if curve is ``p``-minimal at a given prime ``p``. INPUT: @@ -3188,7 +3341,7 @@ def tamagawa_exponent(self, p): return 4 def tamagawa_product(self): - """ + r""" Return the product of the Tamagawa numbers. EXAMPLES:: @@ -3204,7 +3357,7 @@ def tamagawa_product(self): return self.__tamagawa_product def real_components(self): - """ + r""" Return the number of real components. EXAMPLES:: @@ -3361,7 +3514,7 @@ def elliptic_exponential(self, z, embedding=None): return self.period_lattice().elliptic_exponential(z) def lseries(self): - """ + r""" Return the L-series of this elliptic curve. Further documentation is available for the functions which apply to @@ -3911,7 +4064,7 @@ def congruence_number(self, M=1): return self._generalized_congmod_numbers(M)["congnum"] def cremona_label(self, space=False): - """ + r""" Return the Cremona label associated to (the minimal model) of this curve, if it is known. If not, raise a ``LookupError`` exception. @@ -4003,7 +4156,7 @@ def reduction(self,p): return self.change_ring(rings.GF(p)) def torsion_order(self): - """ + r""" Return the order of the torsion subgroup. EXAMPLES:: @@ -4107,7 +4260,7 @@ def torsion_subgroup(self): return self.__torsion_subgroup def torsion_points(self): - """ + r""" Return the torsion points of this elliptic curve as a sorted list. @@ -4375,7 +4528,7 @@ def has_rational_cm(self, field=None): raise ValueError("Error in has_rational_cm: %s is not an extension field of QQ" % field) def quadratic_twist(self, D): - """ + r""" Return the global minimal model of the quadratic twist of this curve by ``D``. @@ -4746,7 +4899,7 @@ def isogenies_prime_degree(self, l=None): return isogs def is_isogenous(self, other, proof=True, maxp=200): - """ + r""" Return whether or not self is isogenous to other. INPUT: @@ -4824,7 +4977,7 @@ def is_isogenous(self, other, proof=True, maxp=200): return E2 in E1.isogeny_class().curves def isogeny_degree(self, other): - """ + r""" Return the minimal degree of an isogeny between ``self`` and ``other``. @@ -4949,7 +5102,7 @@ def isogeny_degree(self, other): # """ def optimal_curve(self): - """ + r""" Given an elliptic curve that is in the installed Cremona database, return the optimal curve isogenous to it. @@ -5289,7 +5442,7 @@ def is_ordinary(self, p, ell=None): return self.ap(ell) % p != 0 def is_good(self, p, check=True): - """ + r""" Return ``True`` if ``p`` is a prime of good reduction for `E`. INPUT: @@ -5314,7 +5467,7 @@ def is_good(self, p, check=True): return self.conductor() % p != 0 def is_supersingular(self, p, ell=None): - """ + r""" Return ``True`` precisely when p is a prime of good reduction and the mod-``p`` representation attached to this elliptic curve is supersingular at ell. @@ -5344,7 +5497,7 @@ def is_supersingular(self, p, ell=None): return self.is_good(p) and not self.is_ordinary(p, ell) def supersingular_primes(self, B): - """ + r""" Return a list of all supersingular primes for this elliptic curve up to and possibly including B. @@ -5379,7 +5532,7 @@ def supersingular_primes(self, B): [P[i] for i in range(2,len(v)) if v[i] == 0 and N % P[i] != 0] def ordinary_primes(self, B): - """ + r""" Return a list of all ordinary primes for this elliptic curve up to and possibly including B. @@ -5463,7 +5616,7 @@ def eval_modular_form(self, points, order): ######################################################################## def sha(self): - """ + r""" Return an object of class 'sage.schemes.elliptic_curves.sha_tate.Sha' attached to this elliptic curve. @@ -5528,7 +5681,7 @@ def sha(self): matrix_of_frobenius = padics.matrix_of_frobenius def mod5family(self): - """ + r""" Return the family of all elliptic curves with the same mod-5 representation as ``self``. @@ -5836,7 +5989,7 @@ def integral_x_coords_in_interval(self,xmin,xmax): prove_BSD = BSD.prove_BSD def integral_points(self, mw_base='auto', both_signs=False, verbose=False): - """ + r""" Compute all integral points (up to sign) on this elliptic curve. INPUT: @@ -6233,7 +6386,7 @@ def point_preprocessing(free,tor): return int_points def S_integral_points(self, S, mw_base='auto', both_signs=False, verbose=False, proof=None): - """ + r""" Compute all S-integral points (up to sign) on this elliptic curve. INPUT: @@ -6910,7 +7063,7 @@ def S_integral_x_coords_with_abs_bounded_by(abs_bound): def cremona_curves(conductors): - """ + r""" Return iterator over all known curves (in database) with conductor in the list of conductors. @@ -6943,7 +7096,7 @@ def cremona_curves(conductors): return sage.databases.cremona.CremonaDatabase().iter(conductors) def cremona_optimal_curves(conductors): - """ + r""" Return iterator over all known optimal curves (in database) with conductor in the list of conductors. diff --git a/src/sage/schemes/elliptic_curves/ell_torsion.py b/src/sage/schemes/elliptic_curves/ell_torsion.py index 5cd89e9c2b5..9bd2b1e8f96 100644 --- a/src/sage/schemes/elliptic_curves/ell_torsion.py +++ b/src/sage/schemes/elliptic_curves/ell_torsion.py @@ -140,7 +140,7 @@ def __init__(self, E): INPUT: - - ``E`` -- An elliptic curve defined over a number field (including `\Q`) + - ``E`` -- An elliptic curve defined over a number field (including `\QQ`) EXAMPLES:: @@ -212,7 +212,7 @@ def __init__(self, E): [T1, T2], structure) def _repr_(self): - """ + r""" String representation of an instance of the EllipticCurveTorsionSubgroup class. EXAMPLES:: @@ -242,7 +242,7 @@ def __richcmp__(self, other, op): return richcmp(self.__E, other.__E, op) def curve(self): - """ + r""" Return the curve of this torsion subgroup. EXAMPLES:: @@ -259,7 +259,7 @@ def curve(self): @cached_method def points(self): - """ + r""" Return a list of all the points in this torsion subgroup. The list is cached. diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 2ec9d2fd747..58375d02a64 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -56,7 +56,7 @@ def __init__(self, *args, **kwds): From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field in z2 of size 257^2 To: Elliptic Curve defined by y^2 = x^3 + 151*x + 22 over Finite Field in z2 of size 257^2 sage: E.isogeny(P, algorithm='velusqrt') # indirect doctest - Elliptic-curve isogeny (using √élu) of degree 127: + Elliptic-curve isogeny (using square-root Vélu) of degree 127: From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field in z2 of size 257^2 To: Elliptic Curve defined by y^2 = x^3 + 119*x + 231 over Finite Field in z2 of size 257^2 sage: E.montgomery_model(morphism=True) # indirect doctest @@ -75,7 +75,7 @@ def __init__(self, *args, **kwds): self._domain._fetch_cached_order(self._codomain) def _repr_type(self): - """ + r""" Return a textual representation of what kind of morphism this is. Used by :meth:`Morphism._repr_`. @@ -89,7 +89,7 @@ def _repr_type(self): @staticmethod def _composition_impl(left, right): - """ + r""" Called by :meth:`_composition_`. TESTS:: @@ -101,7 +101,7 @@ def _composition_impl(left, right): return NotImplemented def _composition_(self, other, homset): - """ + r""" Return the composition of this elliptic-curve morphism with another elliptic-curve morphism. @@ -133,7 +133,7 @@ def _composition_(self, other, homset): @staticmethod def _comparison_impl(left, right, op): - """ + r""" Called by :meth:`_richcmp_`. TESTS:: @@ -626,7 +626,7 @@ def is_injective(self): return self.degree() == 1 def is_zero(self): - """ + r""" Check whether this elliptic-curve morphism is the zero map. .. NOTE:: @@ -664,7 +664,7 @@ def __neg__(self): @cached_method def __hash__(self): - """ + r""" Return a hash value for this elliptic-curve morphism. ALGORITHM: @@ -899,7 +899,7 @@ def compare_via_evaluation(left, right): d = left.degree() e = integer_floor(1 + 2 * (2*d.sqrt() + 1).log(q)) # from Hasse bound e = next(i for i, n in enumerate(E.count_points(e+1), 1) if n > 4*d) - EE = E.base_extend(F.extension(e)) + EE = E.base_extend(F.extension(e, 'U')) # named extension is faster Ps = EE.gens() return all(left._eval(P) == right._eval(P) for P in Ps) elif isinstance(F, number_field_base.NumberField): @@ -982,7 +982,7 @@ def find_post_isomorphism(phi, psi): if len(isos) <= 1: break else: - E = E.base_extend(E.base_field().extension(2)) + E = E.base_extend(E.base_field().extension(2, 'U')) # named extension is faster elif isinstance(F, number_field_base.NumberField): for _ in range(100): diff --git a/src/sage/schemes/elliptic_curves/hom_velusqrt.py b/src/sage/schemes/elliptic_curves/hom_velusqrt.py index b60e551d876..4bc84d944f8 100644 --- a/src/sage/schemes/elliptic_curves/hom_velusqrt.py +++ b/src/sage/schemes/elliptic_curves/hom_velusqrt.py @@ -1,7 +1,8 @@ r""" -√élu algorithm for elliptic-curve isogenies +Square‑root Vélu algorithm for elliptic-curve isogenies -The √élu algorithm computes isogenies of elliptic curves in time `\tilde +The square-root Vélu algorithm, also called the √élu algorithm, +computes isogenies of elliptic curves in time `\tilde O(\sqrt\ell)` rather than naïvely `O(\ell)`, where `\ell` is the degree. The core idea is to reindex the points in the kernel subgroup in a @@ -26,7 +27,7 @@ 10009 sage: phi = EllipticCurveHom_velusqrt(E, K) sage: phi - Elliptic-curve isogeny (using √élu) of degree 10009: + Elliptic-curve isogeny (using square-root Vélu) of degree 10009: From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 6666679 To: Elliptic Curve defined by y^2 = x^3 + 227975*x + 3596133 over Finite Field of size 6666679 sage: phi.codomain() @@ -56,7 +57,7 @@ sage: K = E(9091, 517864) sage: phi = EllipticCurveHom_velusqrt(E, K, model='montgomery') sage: phi - Elliptic-curve isogeny (using √élu) of degree 2999: + Elliptic-curve isogeny (using square-root Vélu) of degree 2999: From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 6666679 To: Elliptic Curve defined by y^2 = x^3 + 1559358*x^2 + x over Finite Field of size 6666679 @@ -68,7 +69,7 @@ sage: K.order() 37 sage: EllipticCurveHom_velusqrt(E, K) - Elliptic-curve isogeny (using √élu) of degree 37: + Elliptic-curve isogeny (using square-root Vélu) of degree 37: From: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Finite Field of size 101 To: Elliptic Curve defined by y^2 = x^3 + 66*x + 86 over Finite Field of size 101 @@ -88,7 +89,7 @@ Furthermore, the implementation is restricted to finite fields, since this appears to be the most relevant application for the -√élu algorithm:: +square-root Vélu algorithm:: sage: E = EllipticCurve('26b1') sage: P = E(1,0) @@ -534,7 +535,7 @@ def _point_outside_subgroup(P): Frobenius). Thus, once `\pi-1` can be represented in Sage, we may just return that in :meth:`~sage.schemes.elliptic_curves.ell_field.EllipticCurve_field.isogeny` - rather than insisting on using √élu. + rather than insisting on using square-root Vélu. """ E = P.curve() n = P.order() @@ -555,7 +556,7 @@ def _point_outside_subgroup(P): class EllipticCurveHom_velusqrt(EllipticCurveHom): r""" This class implements separable odd-degree isogenies of elliptic - curves over finite fields using the √élu algorithm. + curves over finite fields using the square-root Vélu algorithm. The complexity is `\tilde O(\sqrt{\ell})` base-field operations, where `\ell` is the degree. @@ -578,7 +579,7 @@ class EllipticCurveHom_velusqrt(EllipticCurveHom): sage: E = EllipticCurve(F, [t,t]) sage: K = E(2154*t^2 + 5711*t + 2899, 7340*t^2 + 4653*t + 6935) sage: phi = EllipticCurveHom_velusqrt(E, K); phi - Elliptic-curve isogeny (using √élu) of degree 601: + Elliptic-curve isogeny (using square-root Vélu) of degree 601: From: Elliptic Curve defined by y^2 = x^3 + t*x + t over Finite Field in t of size 10009^3 To: Elliptic Curve defined by y^2 = x^3 + (263*t^2+3173*t+4759)*x + (3898*t^2+6111*t+9443) over Finite Field in t of size 10009^3 sage: phi(K) @@ -644,7 +645,7 @@ class EllipticCurveHom_velusqrt(EllipticCurveHom): """ def __init__(self, E, P, *, codomain=None, model=None, Q=None): r""" - Initialize this √élu isogeny from a kernel point of odd order. + Initialize this square-root Vélu isogeny from a kernel point of odd order. EXAMPLES:: @@ -652,7 +653,7 @@ def __init__(self, E, P, *, codomain=None, model=None, Q=None): sage: E = EllipticCurve(GF(71), [5,5]) sage: P = E(-2, 22) sage: EllipticCurveHom_velusqrt(E, P) - Elliptic-curve isogeny (using √élu) of degree 19: + Elliptic-curve isogeny (using square-root Vélu) of degree 19: From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 71 To: Elliptic Curve defined by y^2 = x^3 + 13*x + 11 over Finite Field of size 71 @@ -661,16 +662,16 @@ def __init__(self, E, P, *, codomain=None, model=None, Q=None): sage: E.

= EllipticCurve(GF(419), [1,0]) sage: K = 4*P sage: EllipticCurveHom_velusqrt(E, K) - Elliptic-curve isogeny (using √élu) of degree 105: + Elliptic-curve isogeny (using square-root Vélu) of degree 105: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419 To: Elliptic Curve defined by y^2 = x^3 + 301*x + 86 over Finite Field of size 419 sage: E2 = EllipticCurve(GF(419), [0,6,0,385,42]) sage: EllipticCurveHom_velusqrt(E, K, codomain=E2) - Elliptic-curve isogeny (using √élu) of degree 105: + Elliptic-curve isogeny (using square-root Vélu) of degree 105: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419 To: Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 385*x + 42 over Finite Field of size 419 sage: EllipticCurveHom_velusqrt(E, K, model="montgomery") - Elliptic-curve isogeny (using √élu) of degree 105: + Elliptic-curve isogeny (using square-root Vélu) of degree 105: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419 To: Elliptic Curve defined by y^2 = x^3 + 6*x^2 + x over Finite Field of size 419 @@ -739,9 +740,10 @@ def __init__(self, E, P, *, codomain=None, model=None, Q=None): def _raw_eval(self, x, y=None): r""" - Evaluate the "inner" √élu isogeny (i.e., without applying - pre- and post-isomorphism) at either just an `x`-coordinate - or a pair `(x,y)` of coordinates. + Evaluate the "inner" square-root Vélu isogeny + (i.e., without applying pre- and post-isomorphism) + at either just an `x`-coordinate or a pair + `(x,y)` of coordinates. If the given point lies in the kernel, the empty tuple ``()`` is returned. @@ -812,7 +814,8 @@ def _raw_eval(self, x, y=None): def _compute_codomain(self, model=None): r""" - Helper method to compute the codomain of this √élu isogeny + Helper method to compute the codomain of this + square-root Vélu isogeny once the data for :meth:`_raw_eval` has been initialized. Called by the constructor. @@ -839,7 +842,7 @@ def _compute_codomain(self, model=None): sage: phi._compute_codomain('montgomery') sage: phi - Elliptic-curve isogeny (using √élu) of degree 19: + Elliptic-curve isogeny (using square-root Vélu) of degree 19: From: Elliptic Curve defined by y^2 = x^3 + 5*x^2 + x over Finite Field of size 71 To: Elliptic Curve defined by y^2 = x^3 + 40*x^2 + x over Finite Field of size 71 @@ -849,7 +852,7 @@ def _compute_codomain(self, model=None): sage: E = EllipticCurve([3*t, 2*t+4, 3*t+2, t+4, 3*t]) sage: K = E(3*t, 2) sage: EllipticCurveHom_velusqrt(E, K) # indirect doctest - Elliptic-curve isogeny (using √élu) of degree 19: + Elliptic-curve isogeny (using square-root Vélu) of degree 19: From: Elliptic Curve defined by y^2 + 3*t*x*y + (3*t+2)*y = x^3 + (2*t+4)*x^2 + (t+4)*x + 3*t over Finite Field in t of size 5^2 To: Elliptic Curve defined by y^2 = x^3 + (4*t+3)*x + 2 over Finite Field in t of size 5^2 """ @@ -883,7 +886,7 @@ def _compute_codomain(self, model=None): def _eval(self, P): r""" - Evaluate this √élu isogeny at a point. + Evaluate this square-root Vélu isogeny at a point. INPUT: @@ -896,7 +899,7 @@ def _eval(self, P): sage: K = E(4, 19) sage: phi = EllipticCurveHom_velusqrt(E, K, model='montgomery') sage: phi - Elliptic-curve isogeny (using √élu) of degree 19: + Elliptic-curve isogeny (using square-root Vélu) of degree 19: From: Elliptic Curve defined by y^2 = x^3 + 5*x^2 + x over Finite Field of size 71 To: Elliptic Curve defined by y^2 = x^3 + 40*x^2 + x over Finite Field of size 71 sage: phi(K) @@ -955,7 +958,7 @@ def _eval(self, P): def _repr_(self): r""" - Return basic information about this √élu isogeny as a string. + Return basic information about this square-root Vélu isogeny as a string. EXAMPLES:: @@ -963,18 +966,18 @@ def _repr_(self): sage: E.

= EllipticCurve(GF(71), [5,5]) sage: phi = EllipticCurveHom_velusqrt(E, P) sage: phi # indirect doctest - Elliptic-curve isogeny (using √élu) of degree 57: + Elliptic-curve isogeny (using square-root Vélu) of degree 57: From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 71 To: Elliptic Curve defined by y^2 = x^3 + 19*x + 45 over Finite Field of size 71 """ - return f'Elliptic-curve isogeny (using √élu) of degree {self._degree}:' \ + return f'Elliptic-curve isogeny (using square-root Vélu) of degree {self._degree}:' \ f'\n From: {self._domain}' \ f'\n To: {self._codomain}' @staticmethod def _comparison_impl(left, right, op): r""" - Compare a √élu isogeny to another elliptic-curve morphism. + Compare a square-root Vélu isogeny to another elliptic-curve morphism. Called by :meth:`EllipticCurveHom._richcmp_`. @@ -991,11 +994,11 @@ def _comparison_impl(left, right, op): sage: from sage.schemes.elliptic_curves.hom_velusqrt import EllipticCurveHom_velusqrt sage: E = EllipticCurve(GF(101), [5,5,5,5,5]) sage: phi = EllipticCurveHom_velusqrt(E, E.lift_x(11)); phi - Elliptic-curve isogeny (using √élu) of degree 59: + Elliptic-curve isogeny (using square-root Vélu) of degree 59: From: Elliptic Curve defined by y^2 + 5*x*y + 5*y = x^3 + 5*x^2 + 5*x + 5 over Finite Field of size 101 To: Elliptic Curve defined by y^2 = x^3 + 15*x + 25 over Finite Field of size 101 sage: psi = EllipticCurveHom_velusqrt(E, E.lift_x(-1)); psi - Elliptic-curve isogeny (using √élu) of degree 59: + Elliptic-curve isogeny (using square-root Vélu) of degree 59: From: Elliptic Curve defined by y^2 + 5*x*y + 5*y = x^3 + 5*x^2 + 5*x + 5 over Finite Field of size 101 To: Elliptic Curve defined by y^2 = x^3 + 15*x + 25 over Finite Field of size 101 sage: phi == psi @@ -1008,7 +1011,7 @@ def _comparison_impl(left, right, op): @cached_method def kernel_polynomial(self): r""" - Return the kernel polynomial of this √élu isogeny. + Return the kernel polynomial of this square-root Vélu isogeny. .. NOTE:: @@ -1039,19 +1042,20 @@ def kernel_polynomial(self): @cached_method def dual(self): r""" - Return the dual of this √élu isogeny as an :class:`EllipticCurveHom`. + Return the dual of this square-root Vélu + isogeny as an :class:`EllipticCurveHom`. .. NOTE:: The dual is computed by :class:`EllipticCurveIsogeny`, - hence it does not benefit from the √élu speedup. + hence it does not benefit from the square-root Vélu speedup. EXAMPLES:: sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) sage: K = E.cardinality() // 11 * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt'); phi - Elliptic-curve isogeny (using √élu) of degree 11: + Elliptic-curve isogeny (using square-root Vélu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 To: Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2 sage: phi.dual() @@ -1072,7 +1076,7 @@ def dual(self): @cached_method def rational_maps(self): r""" - Return the pair of explicit rational maps of this √élu isogeny + Return the pair of explicit rational maps of this square-root Vélu isogeny as fractions of bivariate polynomials in `x` and `y`. .. NOTE:: @@ -1084,7 +1088,7 @@ def rational_maps(self): sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) sage: K = (E.cardinality() // 11) * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt'); phi - Elliptic-curve isogeny (using √élu) of degree 11: + Elliptic-curve isogeny (using square-root Vélu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 To: Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2 sage: phi.rational_maps() @@ -1109,7 +1113,8 @@ def rational_maps(self): @cached_method def x_rational_map(self): r""" - Return the `x`-coordinate rational map of this √élu isogeny + Return the `x`-coordinate rational map of + this square-root Vélu isogeny as a univariate rational function in `x`. .. NOTE:: @@ -1121,7 +1126,7 @@ def x_rational_map(self): sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) sage: K = (E.cardinality() // 11) * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt'); phi - Elliptic-curve isogeny (using √élu) of degree 11: + Elliptic-curve isogeny (using square-root Vélu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 To: Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2 sage: phi.x_rational_map() @@ -1145,7 +1150,7 @@ def x_rational_map(self): def scaling_factor(self): r""" Return the Weierstrass scaling factor associated to this - √élu isogeny. + square-root Vélu isogeny. The scaling factor is the constant `u` (in the base field) such that `\varphi^* \omega_2 = u \omega_1`, where @@ -1158,7 +1163,7 @@ def scaling_factor(self): sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) sage: K = (E.cardinality() // 11) * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt', model='montgomery'); phi - Elliptic-curve isogeny (using √élu) of degree 11: + Elliptic-curve isogeny (using square-root Vélu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 To: Elliptic Curve defined by y^2 = x^3 + 61*x^2 + x over Finite Field in z2 of size 101^2 sage: phi.scaling_factor() @@ -1187,7 +1192,7 @@ def is_separable(self): def _random_example_for_testing(): r""" - Function to generate somewhat random valid √élu inputs + Function to generate somewhat random valid Vélu inputs for testing purposes. EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/padic_lseries.py b/src/sage/schemes/elliptic_curves/padic_lseries.py index f264ca20434..7f32eb10a21 100644 --- a/src/sage/schemes/elliptic_curves/padic_lseries.py +++ b/src/sage/schemes/elliptic_curves/padic_lseries.py @@ -1375,7 +1375,7 @@ def _prec_bounds(self, n, prec): return [infinity] + [2 * e[j] - c0 for j in range(1, len(e))] def _poly(self, a): - """ + r""" Given an element a in Qp[alpha] this returns the list containing the two coordinates in Qp. @@ -1672,7 +1672,9 @@ def Dp_valued_height(self,prec=20): elog = Ehat.log(prec + Integer(3)) # we will have to do it properly with David Harvey's _multiply_point() - n = LCM(E.tamagawa_numbers()) + # import here to avoid circular import + from sage.schemes.elliptic_curves.padics import _multiple_to_make_good_reduction + n = _multiple_to_make_good_reduction(E) n = LCM(n, E.Np(p)) # allowed here because E has good reduction at p def height(P,check=True): diff --git a/src/sage/schemes/elliptic_curves/padics.py b/src/sage/schemes/elliptic_curves/padics.py index 30587d1cfa5..f59e4b823fc 100644 --- a/src/sage/schemes/elliptic_curves/padics.py +++ b/src/sage/schemes/elliptic_curves/padics.py @@ -2,7 +2,7 @@ # # All these methods are imported in EllipticCurve_rational_field, # so there is no reason to add this module to the documentation. -""" +r""" Miscellaneous `p`-adic methods """ @@ -232,6 +232,8 @@ def padic_lseries(self, p, normalize=None, implementation='eclib', def padic_regulator(self, p, prec=20, height=None, check_hypotheses=True): r""" Compute the cyclotomic `p`-adic regulator of this curve. + The model of the curve needs to be integral and minimal at `p`. + Moreover the reduction at `p` should not be additive. INPUT: @@ -246,16 +248,11 @@ def padic_regulator(self, p, prec=20, height=None, check_hypotheses=True): - ``check_hypotheses`` -- boolean, whether to check that this is a curve for which the p-adic height makes sense - OUTPUT: The p-adic cyclotomic regulator of this curve, to the + OUTPUT: The `p`-adic cyclotomic regulator of this curve, to the requested precision. If the rank is 0, we output 1. - .. TODO:: - - Remove restriction that curve must be in minimal - Weierstrass form. This is currently required for E.gens(). - AUTHORS: - Liang Xiao: original implementation at the 2006 MSRI @@ -308,7 +305,7 @@ def padic_regulator(self, p, prec=20, height=None, check_hypotheses=True): sage: E.padic_regulator(7) == Em.padic_regulator(7) True - Allow a Python int as input:: + Allow a python int as input:: sage: E = EllipticCurve('37a') sage: E.padic_regulator(int(5)) @@ -343,9 +340,10 @@ def padic_regulator(self, p, prec=20, height=None, check_hypotheses=True): def padic_height_pairing_matrix(self, p, prec=20, height=None, check_hypotheses=True): r""" Computes the cyclotomic `p`-adic height pairing matrix of - this curve with respect to the basis self.gens() for the - Mordell-Weil group for a given odd prime p of good ordinary + this curve with respect to the basis ``self.gens()`` for the + Mordell-Weil group for a given odd prime `p` of good ordinary reduction. + The model needs to be integral and minimal at `p`. INPUT: @@ -360,14 +358,9 @@ def padic_height_pairing_matrix(self, p, prec=20, height=None, check_hypotheses= - ``check_hypotheses`` -- boolean, whether to check that this is a curve for which the p-adic height makes sense - OUTPUT: The p-adic cyclotomic height pairing matrix of this curve + OUTPUT: The `p`-adic cyclotomic height pairing matrix of this curve to the given precision. - .. TODO:: - - remove restriction that curve must be in minimal - Weierstrass form. This is currently required for E.gens(). - AUTHORS: - David Harvey, Liang Xiao, Robert Bradshaw, Jennifer @@ -428,14 +421,14 @@ def padic_height_pairing_matrix(self, p, prec=20, height=None, check_hypotheses= def _multiply_point(E, R, P, m): r""" - Computes coordinates of a multiple of P with entries in a ring. + Computes coordinates of a multiple of `P` with entries in a ring. INPUT: - - ``E`` -- elliptic curve over Q with integer + - ``E`` -- elliptic curve over `\QQ` with integer coefficients - - ``P`` -- a rational point on P that reduces to a + - ``P`` -- a rational point on `P` that reduces to a non-singular point at all primes - ``R`` -- a ring in which 2 is invertible (typically @@ -455,8 +448,7 @@ def _multiply_point(E, R, P, m): that the sign for `b'` will match the sign for `d'`. - ALGORITHM: Proposition 9 of "Efficient Computation of p-adic - Heights" (David Harvey, to appear in LMS JCM). + ALGORITHM: Proposition 9 in [Har2009]_. Complexity is soft-`O(\log L \log m + \log^2 m)`. @@ -584,12 +576,89 @@ def _multiply_point(E, R, P, m): return theta, omega, psi_m * d +def _multiple_to_make_good_reduction(E): + r""" + Return the integer `n_2` such that for all points `P` in `E(\QQ)` + `n_2*P` has good reduction at all primes. + If the model is globally minimal the lcm of the + Tamagawa numbers will do, otherwise we have to take into + account the change of the model. + + INPUT: + + - ``E`` -- an elliptic curve over `\QQ` + + OUTPUT: + + - a positive integer ``n2`` + + EXAMPLE (:trac:`34790`):: + + sage: from sage.schemes.elliptic_curves.padics import _multiple_to_make_good_reduction + sage: E = EllipticCurve([-1728,-100656]) + sage: _multiple_to_make_good_reduction(E) + 30 + + The number ``n_2`` is not always optimal but it is in this example. + The first multiple of the generator `P` with good reduction in this + non-minimal model is `30 P`. + + TESTS:: + + sage: from sage.schemes.elliptic_curves.padics import _multiple_to_make_good_reduction + sage: E = EllipticCurve([1/2,1/3]) + sage: _multiple_to_make_good_reduction(E) + Traceback (most recent call last): + ... + NotImplementedError: This only implemented for integral models. Please change the model first. + sage: E = EllipticCurve([0,3]) + sage: _multiple_to_make_good_reduction(E) + 1 + sage: E = EllipticCurve([0,5^7]) # min eq is additive + sage: _multiple_to_make_good_reduction(E) + 5 + sage: E = EllipticCurve([7,0,0,0,7^7]) # min eq is split mult + sage: _multiple_to_make_good_reduction(E) + 6 + sage: E = EllipticCurve([0,-3^2,0,0,3^7]) # min eq is non-split mult + sage: _multiple_to_make_good_reduction(E) + 4 + + """ + if not E.is_integral(): + st = ("This only implemented for integral models. " + "Please change the model first.") + raise NotImplementedError(st) + if E.is_minimal(): + n2 = arith.LCM(E.tamagawa_numbers()) + else: + # generalising to number fields one can get the u from local_data + Emin = E.global_minimal_model() + iota = E.isomorphism_to(Emin) + u = Integer(iota.u) + ps = u.prime_divisors() + li = [] + for p in ps: + np = u.valuation(p) + if Emin.discriminant() %p != 0: + li.append(Emin.Np(p) * p**(np-1)) + elif Emin.has_additive_reduction(p): + li.append(E.tamagawa_number(p) * p**np) + elif E.has_split_multiplicative_reduction(p): + li.append(E.tamagawa_number(p) * (p-1) * p**(np-1)) + else: # non split + li.append(E.tamagawa_number(p) * (p+1) * p**(np-1)) + otherbad = Integer(Emin.discriminant()).prime_divisors() + otherbad = [p for p in otherbad if u%p != 0 ] + li += [E.tamagawa_number(p) for p in otherbad] + n2 = arith.LCM(li) + return n2 def padic_height(self, p, prec=20, sigma=None, check_hypotheses=True): r""" - Compute the cyclotomic p-adic height. + Compute the cyclotomic `p`-adic height. - The equation of the curve must be minimal at `p`. + The equation of the curve must be integral and minimal at `p`. INPUT: @@ -606,7 +675,7 @@ def padic_height(self, p, prec=20, sigma=None, check_hypotheses=True): OUTPUT: A function that accepts two parameters: - - a Q-rational point on the curve whose height should be computed + - a `\QQ`-rational point on the curve whose height should be computed - optional boolean flag 'check': if False, it skips some input checking, and returns the p-adic height of that point to the @@ -614,8 +683,8 @@ def padic_height(self, p, prec=20, sigma=None, check_hypotheses=True): - The normalization (sign and a factor 1/2 with respect to some other normalizations that appear in the literature) is chosen in such a way - as to make the p-adic Birch Swinnerton-Dyer conjecture hold as stated - in [Mazur-Tate-Teitelbaum]. + as to make the `p`-adic Birch Swinnerton-Dyer conjecture hold as stated + in [MTT1986]_. AUTHORS: @@ -734,11 +803,10 @@ def padic_height(self, p, prec=20, sigma=None, check_hypotheses=True): # else good ordinary case - # For notation and definitions, see "Efficient Computation of - # p-adic Heights", David Harvey (unpublished) + # For notation and definitions, see [Har2009]_. n1 = self.change_ring(rings.GF(p)).cardinality() - n2 = arith.LCM(self.tamagawa_numbers()) + n2 = _multiple_to_make_good_reduction(self) n = arith.LCM(n1, n2) m = int(n / n2) @@ -792,7 +860,7 @@ def height(P, check=True): def padic_height_via_multiply(self, p, prec=20, E2=None, check_hypotheses=True): r""" - Computes the cyclotomic p-adic height. + Computes the cyclotomic `p`-adic height. The equation of the curve must be minimal at `p`. @@ -805,7 +873,7 @@ def padic_height_via_multiply(self, p, prec=20, E2=None, check_hypotheses=True): - ``E2`` -- precomputed value of E2. If not supplied, this function will call padic_E2 to compute it. The value supplied - must be correct mod `p^(prec-2)` (or slightly higher in the + must be correct mod `p^{prec-2}` (or slightly higher in the anomalous case; see the code for details). - ``check_hypotheses`` -- boolean, whether to check @@ -813,22 +881,21 @@ def padic_height_via_multiply(self, p, prec=20, E2=None, check_hypotheses=True): OUTPUT: A function that accepts two parameters: - - a Q-rational point on the curve whose height should be computed + - a `\QQ`-rational point on the curve whose height should be computed - optional boolean flag 'check': if False, it skips some input - checking, and returns the p-adic height of that point to the + checking, and returns the `p`-adic height of that point to the desired precision. - The normalization (sign and a factor 1/2 with respect to some other normalizations that appear in the literature) is chosen in such a way as to make the p-adic Birch Swinnerton-Dyer conjecture hold as stated - in [Mazur-Tate-Teitelbaum]. + in [MTT1986]_. AUTHORS: - David Harvey (2008-01): based on the padic_height() function, - using the algorithm of"Computing p-adic heights via - point multiplication" + using the algorithm of [Har2009]_. EXAMPLES:: @@ -879,11 +946,10 @@ def padic_height_via_multiply(self, p, prec=20, E2=None, check_hypotheses=True): if prec < 1: raise ValueError("prec (=%s) must be at least 1" % prec) - # For notation and definitions, see ``Computing p-adic heights via point - # multiplication'' (David Harvey, still in draft form) + # For notation and definitions, [Har2009]_ n1 = self.change_ring(rings.GF(p)).cardinality() - n2 = arith.LCM(self.tamagawa_numbers()) + n2 = _multiple_to_make_good_reduction(self) n = arith.LCM(n1, n2) m = int(n / n2) @@ -938,9 +1004,9 @@ def height(P, check=True): def padic_sigma(self, p, N=20, E2=None, check=False, check_hypotheses=True): r""" - Computes the p-adic sigma function with respect to the standard + Computes the `p`-adic sigma function with respect to the standard invariant differential `dx/(2y + a_1 x + a_3)`, as - defined by Mazur and Tate, as a power series in the usual + defined by Mazur and Tate in [MT1991]_, as a power series in the usual uniformiser `t` at the origin. The equation of the curve must be minimal at `p`. @@ -963,7 +1029,7 @@ def padic_sigma(self, p, N=20, E2=None, check=False, check_hypotheses=True): - ``differential equation`` -- note that this does NOT guarantee correctness of all the returned digits, but it comes - pretty close :-)) + pretty close. - ``check_hypotheses`` -- boolean, whether to check that this is a curve for which the p-adic sigma function makes @@ -984,9 +1050,9 @@ def padic_sigma(self, p, N=20, E2=None, check=False, check_hypotheses=True): `p`-adic digits). ALGORITHM: Described in "Efficient Computation of p-adic Heights" - (David Harvey), which is basically an optimised version of the + (David Harvey) [Har2009]_ which is basically an optimised version of the algorithm from "p-adic Heights and Log Convergence" (Mazur, Stein, - Tate). + Tate) [MST2006]_. Running time is soft-`O(N^2 \log p)`, plus whatever time is necessary to compute `E_2`. @@ -1159,7 +1225,7 @@ def padic_sigma_truncated(self, p, N=20, lamb=0, E2=None, check_hypotheses=True) r""" Compute the p-adic sigma function with respect to the standard invariant differential `dx/(2y + a_1 x + a_3)`, as - defined by Mazur and Tate, as a power series in the usual + defined by Mazur and Tate in [MT1991]_, as a power series in the usual uniformiser `t` at the origin. The equation of the curve must be minimal at `p`. @@ -1193,10 +1259,9 @@ def padic_sigma_truncated(self, p, N=20, lamb=0, E2=None, check_hypotheses=True) correct to precision `O(p^{N - 2 + (3 - j)(lamb + 1)})`. ALGORITHM: Described in "Efficient Computation of p-adic Heights" - (David Harvey, to appear in LMS JCM), which is basically an + [Har2009]_, which is basically an optimised version of the algorithm from "p-adic Heights and Log - Convergence" (Mazur, Stein, Tate), and "Computing p-adic heights - via point multiplication" (David Harvey, still draft form). + Convergence" (Mazur, Stein, Tate) [MST2006]_. Running time is soft-`O(N^2 \lambda^{-1} \log p)`, plus whatever time is necessary to compute `E_2`. @@ -1378,7 +1443,7 @@ def padic_E2(self, p, prec=20, check=False, check_hypotheses=True, algorithm="au trick. EXAMPLES: Here is the example discussed in the paper "Computation - of p-adic Heights and Log Convergence" (Mazur, Stein, Tate):: + of p-adic Heights and Log Convergence" (Mazur, Stein, Tate) [MST2006]_:: sage: EllipticCurve([-1, 1/4]).padic_E2(5) 2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + 4*5^10 + 2*5^11 + 2*5^12 + 2*5^14 + 3*5^15 + 3*5^16 + 3*5^17 + 4*5^18 + 2*5^19 + O(5^20) @@ -1673,7 +1738,7 @@ def _brent(F, p, N): some log-log factors. For more information, and a proof of the precision guarantees, see - Lemma 4 in "Efficient Computation of p-adic Heights" (David Harvey). + Lemma 4 in [Har2009]_. AUTHORS: diff --git a/src/sage/schemes/toric/points.py b/src/sage/schemes/toric/points.py index f72bd2eb3ba..8a70350a30e 100644 --- a/src/sage/schemes/toric/points.py +++ b/src/sage/schemes/toric/points.py @@ -350,8 +350,7 @@ def cone_iter(self): """ fan = self.fan for d in range(fan.dim(), -1, -1): - for cone in fan.cones(d): - yield cone + yield from fan.cones(d) def coordinate_iter(self): """ diff --git a/src/sage/sets/recursively_enumerated_set.pyx b/src/sage/sets/recursively_enumerated_set.pyx index 2ee74cbae1c..59f898ad830 100644 --- a/src/sage/sets/recursively_enumerated_set.pyx +++ b/src/sage/sets/recursively_enumerated_set.pyx @@ -827,8 +827,7 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): current_level = self._seeds known = set(current_level) if max_depth >= 0: - for x in current_level: - yield x + yield from current_level depth = 0 while current_level and depth < max_depth: next_level = [] @@ -1078,8 +1077,7 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): B = self._seeds set_B = set(B) if max_depth >= 0: - for x in B: - yield x + yield from B depth = 0 while B and depth < max_depth: C = list() @@ -1329,8 +1327,7 @@ cdef class RecursivelyEnumeratedSet_graded(RecursivelyEnumeratedSet_generic): max_depth = self._max_depth current_level = self._seeds if max_depth >= 0: - for x in current_level: - yield x + yield from current_level depth = 0 while current_level and depth < max_depth: next_level = list() @@ -1936,12 +1933,10 @@ class RecursivelyEnumeratedSet_forest(Parent): [] """ if depth == 0: - for node in self.roots(): - yield node + yield from self.roots() else: for father in self._elements_of_depth_iterator_rec(depth - 1): - for node in self.children(father): - yield node + yield from self.children(father) def elements_of_depth_iterator(self, depth=0): r""" diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 8461d4e7591..5a49a622f51 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -3084,14 +3084,11 @@ cdef class Expression(Expression_abc): if op.is_numeric(): yield op else: - for opp in numelems_gen(op): - yield opp + yield from numelems_gen(op) # stop at the first inexact number in the subexpression tree of self, # and if there is no such element, then self is exact - for nelem in numelems_gen(self): - if not nelem.pyobject().base_ring().is_exact(): - return False - return True + return all(nelem.pyobject().base_ring().is_exact() + for nelem in numelems_gen(self)) cpdef bint is_infinity(self): """ diff --git a/src/sage/tensor/modules/comp.py b/src/sage/tensor/modules/comp.py index 653b65d529e..198fdc7479a 100644 --- a/src/sage/tensor/modules/comp.py +++ b/src/sage/tensor/modules/comp.py @@ -2518,10 +2518,8 @@ def non_redundant_index_generator(self): sage: list(c.non_redundant_index_generator()) [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)] - """ - for ind in self.index_generator(): - yield ind + yield from self.index_generator() def symmetrize(self, *pos): r""" diff --git a/src/sage/tests/arxiv_0812_2725.py b/src/sage/tests/arxiv_0812_2725.py index 093025373e1..3f304803c31 100644 --- a/src/sage/tests/arxiv_0812_2725.py +++ b/src/sage/tests/arxiv_0812_2725.py @@ -73,8 +73,7 @@ def CompleteMatchings(n): integer depends on what [1..n] returns, and also on what range(1, len([1..n])) is. """ - for m in matchingsset(list(range(1, n + 1))): - yield m + yield from matchingsset(list(range(1, n + 1))) def matchingsset(L): diff --git a/src/sage/typeset/character_art.py b/src/sage/typeset/character_art.py index dd1107db48d..a4de0e23964 100644 --- a/src/sage/typeset/character_art.py +++ b/src/sage/typeset/character_art.py @@ -133,8 +133,7 @@ def __iter__(self): * * ***** """ - for elem in self._matrix: - yield elem + yield from self._matrix def _repr_(self): r""" diff --git a/src/sage/version.py b/src/sage/version.py index 0ac9bf873ed..5119b7def49 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 = '10.1.beta2' -date = '2023-06-03' -banner = 'SageMath version 10.1.beta2, Release Date: 2023-06-03' +version = '10.1.beta3' +date = '2023-06-11' +banner = 'SageMath version 10.1.beta3, Release Date: 2023-06-11' diff --git a/src/tox.ini b/src/tox.ini index 6c479f086df..7b99e519ff7 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -126,8 +126,8 @@ description = # W605: invalid escape sequence ‘x’ # See https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes deps = pycodestyle -commands = pycodestyle --select E111,E211,E271,E303,E306,E401,E502,E701,E702,E703,E714,W291,W293,W391,W605,E711,E712,E713,E721,E722 {posargs:{toxinidir}/sage/} - pycodestyle --select E111,E306,E401,E703,W293,W391,W605,E712,E713,E714,E721,E722 --filename *.pyx {posargs:{toxinidir}/sage/} +commands = pycodestyle --select E111,E21,E227,E271,E303,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605 {posargs:{toxinidir}/sage/} + pycodestyle --select E111,E306,E401,E703,W29,W391,W605,E712,E713,E714,E721,E722 --filename *.pyx {posargs:{toxinidir}/sage/} [pycodestyle] max-line-length = 160