diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 40dad7be253..eec448fed1f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,6 +4,15 @@ on: push: workflow_dispatch: # Allow to run manually + inputs: + platform: + description: 'Platform' + required: true + default: 'ubuntu-focal-standard' + docker_tag: + description: 'Docker tag' + required: true + default: 'dev' concurrency: # Cancel previous runs of this workflow for the same branch @@ -13,7 +22,7 @@ concurrency: jobs: build: runs-on: ubuntu-latest - container: ghcr.io/sagemath/sage/sage-docker-ubuntu-focal-standard-with-targets:dev + container: ghcr.io/sagemath/sage/sage-docker-${{ github.event.inputs.platform || 'ubuntu-focal-standard' }}-with-targets:${{ github.event.inputs.docker_tag || 'dev'}} steps: - name: Checkout id: checkout @@ -23,10 +32,16 @@ jobs: id: prepare run: | # Install test tools. - # Installation of python3-venv can be removed as soon as a - # base image with a release including #33822 is available - apt-get update - apt-get install -y git python3-venv + if apt-get update && apt-get install -y git python3-venv; then + # Debian-specific temporary code: + # Installation of python3-venv can be removed as soon as a + # base image with a release including #33822 is available + : + else + export PATH="build/bin:$PATH" + eval $(sage-print-system-package-command auto update) + eval $(sage-print-system-package-command auto --spkg --yes --no-install-recommends install git) + fi # Reuse built SAGE_LOCAL contained in the Docker image ./bootstrap ./configure --enable-build-as-root --prefix=/sage/local --with-sage-venv --enable-editable --enable-download-from-upstream-url diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 2cd99caa7cd..8456f3666dc 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -36,3 +36,19 @@ jobs: run: pip install tox relint - name: Lint using relint run: tox -e relint src/sage/ + lint-rst: + name: Validate docstring markup as RST + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.8 + - name: Install tox + run: pip install tox + - name: Lint using tox -e rst + run: tox -e rst + # Until all errors are fixed: + continue-on-error: true diff --git a/.zenodo.json b/.zenodo.json index 70b795b82de..521a275f9f9 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,10 +1,10 @@ { "description": "Mirror of the Sage https://sagemath.org/ source tree", "license": "other-open", - "title": "sagemath/sage: 9.7.beta5", - "version": "9.7.beta5", + "title": "sagemath/sage: 9.7.beta6", + "version": "9.7.beta6", "upload_type": "software", - "publication_date": "2022-07-10", + "publication_date": "2022-07-24", "creators": [ { "affiliation": "SageMath.org", @@ -15,7 +15,7 @@ "related_identifiers": [ { "scheme": "url", - "identifier": "https://github.com/sagemath/sage/tree/9.7.beta5", + "identifier": "https://github.com/sagemath/sage/tree/9.7.beta6", "relation": "isSupplementTo" }, { diff --git a/VERSION.txt b/VERSION.txt index b67ee65e457..f863f2ae553 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 9.7.beta5, Release Date: 2022-07-10 +SageMath version 9.7.beta6, Release Date: 2022-07-24 diff --git a/bootstrap-conda b/bootstrap-conda index 6638afde3d7..596b449e3e0 100755 --- a/bootstrap-conda +++ b/bootstrap-conda @@ -45,7 +45,7 @@ for PKG_BASE in $(sage-package list --has-file distros/conda.txt); do fi fi done -echo >&2 $0:$LINENO: generate conda enviroment files +echo >&2 $0:$LINENO: generate conda environment files echo "name: sage-build" > environment.yml echo "channels:" >> environment.yml echo " - conda-forge" >> environment.yml diff --git a/build/bin/sage-logger b/build/bin/sage-logger index 14ab1297022..1682ccbc079 100755 --- a/build/bin/sage-logger +++ b/build/bin/sage-logger @@ -79,7 +79,7 @@ if [ -n "$SAGE_SILENT_BUILD" -a ${use_prefix} = true ]; then status=$? if [[ $status != 0 ]]; then echo " [$logname] error installing, exit status $status. End of log file:" - tail -n 40 "$logfile" | sed "/Please email sage-devel/,$ d;s;^; [$logname] ;" >&2 + tail -n 72 "$logfile" | sed "/Please email sage-devel/,$ d;s;^; [$logname] ;" >&2 echo " [$logname] Full log file: $logfile" else echo " [$logname] successfully installed." diff --git a/build/bin/sage-sdist b/build/bin/sage-sdist index 5b7c04c71f9..f2774e6b6bd 100755 --- a/build/bin/sage-sdist +++ b/build/bin/sage-sdist @@ -25,11 +25,11 @@ if [ $# -gt 1 ]; then fi if [ -z "$SAGE_ROOT" ]; then - die "must be run from within a Sage enviroment, or with SAGE_ROOT provided" + die "must be run from within a Sage environment, or with SAGE_ROOT provided" fi if [ -z "$SAGE_SRC" ]; then - die "must be run from within a Sage enviroment, or with SAGE_SRC provided" + die "must be run from within a Sage environment, or with SAGE_SRC provided" fi if [ "$#" -gt 0 ]; then diff --git a/build/make/Makefile.in b/build/make/Makefile.in index 9ddd6d1005a..2a33ae6c323 100644 --- a/build/make/Makefile.in +++ b/build/make/Makefile.in @@ -625,9 +625,9 @@ $(1)-$(4)-no-deps: SAGE_INST_LOCAL=$$($(4)) \ sage-logger -p 'SAGE_CHECK=$$(SAGE_CHECK_$(1)) $$(SAGE_ROOT)/build/pkgs/$(1)/spkg-install' '$$(SAGE_LOGS)/$(1)-$(2).log' && \ touch "$$($(4))/$(SPKG_INST_RELDIR)/$(1)-$(2)"; \ - else \ + else ( \ echo; \ - echo "Error: $(1) is a dummy script package that the Sage distribution uses"; \ + echo "Note: $(1) is a dummy script package that the Sage distribution uses"; \ echo "to provide information about equivalent system packages."; \ echo "It cannot be installed using the Sage distribution."; \ echo "Please install it manually, for example using the system packages"; \ @@ -635,7 +635,9 @@ $(1)-$(4)-no-deps: echo "See below for package-specific information."; \ echo; \ $$(SAGE_ROOT)/build/bin/sage-spkg-info $(1); \ - exit 1; \ + echo; \ + echo "Error: $(1) is a dummy script package and "; \ + echo "cannot be installed using the Sage distribution." ) | sage-logger -p 'cat; exit 1' '$$(SAGE_LOGS)/$(1)-$(2).log'; \ fi $(1)-no-deps: $(1)-$(4)-no-deps diff --git a/build/pkgs/build/SPKG.rst b/build/pkgs/build/SPKG.rst deleted file mode 100644 index 8d222b8f6cc..00000000000 --- a/build/pkgs/build/SPKG.rst +++ /dev/null @@ -1,18 +0,0 @@ -build: A simple, correct PEP517 package builder -=============================================== - -Description ------------ - -A simple, correct PEP517 package builder - -License -------- - -MIT - -Upstream Contact ----------------- - -https://pypi.org/project/build/ - diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 06492185c15..d69d37294c9 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=b5a2cfbb85e9d1afd3c151429525944f1e0ca84f -md5=8cf9a8e717fe11a7c6fb7aa41975a7a1 -cksum=2226307451 +sha1=7df04dc0c2e0d7cdfd767dfb86dd3a60d3af1767 +md5=f8e92133f5447c39196fc45a026ed49d +cksum=1963708627 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 1668ffac530..463c496acf2 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -413ff13c54c4738b14d64eb7e7e6b2d06439d12c +e3ababd22689e7cc6e89a01b1e8bd6d770e7b1cf diff --git a/build/pkgs/giac/checksums.ini b/build/pkgs/giac/checksums.ini index f01435d5423..2fb1d3fdf31 100644 --- a/build/pkgs/giac/checksums.ini +++ b/build/pkgs/giac/checksums.ini @@ -1,5 +1,5 @@ tarball=giac-VERSION.tar.bz2 -sha1=b0e81969eb2527964efc802bf35c31d140031571 -md5=f8253082e5dcde5724b4d6f2300d8669 -cksum=3973759340 -upstream_url=https://trac.sagemath.org/raw-attachment/ticket/31562/giac-VERSION.tar.bz2 +sha1=78c15badd19b49b7d111ac204b611a4378ce3d15 +md5=8fbd43a5c60848b6813b7fc8698a0199 +cksum=1923149665 +upstream_url=https://trac.sagemath.org/raw-attachment/ticket/31563/giac-VERSION.tar.bz2 diff --git a/build/pkgs/giac/dependencies b/build/pkgs/giac/dependencies index 9a60603c750..a051202507e 100644 --- a/build/pkgs/giac/dependencies +++ b/build/pkgs/giac/dependencies @@ -1,4 +1,4 @@ -readline libpng $(MP_LIBRARY) mpfr mpfi ntl gsl pari glpk curl cliquer $(findstring libnauty,$(OPTIONAL_INSTALLED_PACKAGES)) +readline libpng $(MP_LIBRARY) mpfr mpfi ntl gsl pari glpk curl cliquer ecm $(findstring libnauty,$(OPTIONAL_INSTALLED_PACKAGES)) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/giac/package-version.txt b/build/pkgs/giac/package-version.txt index f490da152c5..ff6a74aad02 100644 --- a/build/pkgs/giac/package-version.txt +++ b/build/pkgs/giac/package-version.txt @@ -1 +1 @@ -1.6.0.47p3.p0 +1.9.0.15p0 diff --git a/build/pkgs/giac/patches/0001-src-global.cc-Do-not-send-SIGINT-to-process-1.patch b/build/pkgs/giac/patches/0001-src-global.cc-Do-not-send-SIGINT-to-process-1.patch index 5ab40921c98..ca33e850d2e 100644 --- a/build/pkgs/giac/patches/0001-src-global.cc-Do-not-send-SIGINT-to-process-1.patch +++ b/build/pkgs/giac/patches/0001-src-global.cc-Do-not-send-SIGINT-to-process-1.patch @@ -11,10 +11,10 @@ diff --git a/src/global.cc b/src/global.cc index c343aea..87e4575 100755 --- a/src/global.cc +++ b/src/global.cc -@@ -1978,7 +1978,7 @@ extern "C" void Sleep(unsigned int miliSecond); +@@ -3762,7 +3762,7 @@ extern "C" void Sleep(unsigned int miliSecond); void ctrl_c_signal_handler(int signum){ ctrl_c=true; - #if !defined KHICAS && !defined NSPIRE_NEWLIB && !defined WIN32 && !defined BESTA_OS && !defined NSPIRE && !defined FXCG && !defined POCKETCAS + #if !defined KHICAS && !defined NSPIRE_NEWLIB && !defined WIN32 && !defined BESTA_OS && !defined NSPIRE && !defined FXCG && !defined POCKETCAS && !defined __MINGW_H - if (child_id) + if (child_id && child_id != 1) kill(child_id,SIGINT); diff --git a/build/pkgs/giac/patches/autotools/0001-configure.ac-Do-not-link-to-libintl-if-USE_NLS-is-no.patch b/build/pkgs/giac/patches/autotools/0001-configure.ac-Do-not-link-to-libintl-if-USE_NLS-is-no.patch deleted file mode 100644 index 8d838f8bd32..00000000000 --- a/build/pkgs/giac/patches/autotools/0001-configure.ac-Do-not-link-to-libintl-if-USE_NLS-is-no.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 2285c11b3cfebc31aa2c032015c76820e3a62030 Mon Sep 17 00:00:00 2001 -From: Matthias Koeppe -Date: Thu, 25 Mar 2021 18:00:38 -0700 -Subject: [PATCH] configure.ac: Do not link to libintl if USE_NLS is no - ---- - configure.ac | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index bfa767d..43c6ff9 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -464,7 +464,12 @@ AC_CHECK_FUNCS(system, , AC_DEFINE(HAVE_NO_SYSTEM, 1, [Set if system() function - ALL_LINGUAS="es fr el pt it en zh de" - AM_GNU_GETTEXT - AM_GNU_GETTEXT_VERSION([0.14.5]) --AC_CHECK_LIB(intl, main) -+AS_VAR_IF([USE_NLS], [yes], -+ dnl Whether this is needed at all, after all the AM_GNU_GETTEXT macros -+ dnl were run, is unknown. But at least we should disable it if NLS -+ dnl is disabled. -+ AC_CHECK_LIB(intl, main) -+])dnl - dnl auto-check will work if the function checked is alone in a file - dnl and independant from the whole micropython library - dnl otherwise it will fail because it depends on giac --- -2.28.0 - diff --git a/build/pkgs/giac/patches/autotools/giac-1.5.0.87-gsl_lapack.patch b/build/pkgs/giac/patches/autotools/giac-1.5.0.87-gsl_lapack.patch index 5b7a9d3a2ad..8a023d3b6ba 100644 --- a/build/pkgs/giac/patches/autotools/giac-1.5.0.87-gsl_lapack.patch +++ b/build/pkgs/giac/patches/autotools/giac-1.5.0.87-gsl_lapack.patch @@ -73,10 +73,10 @@ index b5dd325..d45b553 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,6 +14,8 @@ libgiac_la_SOURCES = input_lexer.ll sym2poly.cc gausspol.cc threaded.cc \ - help.cc lpsolve.cc optimization.cc signalprocessing.cc \ - graphe.cc graphtheory.cc nautywrapper.c markup.cc kdisplay.cc kadd.cc # Ugh.. + caseval.c cutils.c graphic.c libbf.c libregexp.c libunicode.c \ + qjsgiac.c quickjs.c quickjs-libc.c js.c --libgiac_la_LIBADD = $(NTL_LIBS) $(COCOA_LIBS) $(PARI_LIBS) $(GSL_LIBS) +-libgiac_la_LIBADD = $(NTL_LIBS) $(COCOA_LIBS) $(PARI_LIBS) $(GSL_LIBS) +libgiac_la_LIBADD = $(NTL_LIBS) $(COCOA_LIBS) $(PARI_LIBS) $(GSL_LIBS) $(LAPACK_LIBS) $(BLAS_LIBS) + +AM_LDFLAGS = -no-undefined diff --git a/build/pkgs/giac/patches/macos-ifactor.patch b/build/pkgs/giac/patches/macos-ifactor.patch index 34e84dda7ef..e8c4deb53b3 100644 --- a/build/pkgs/giac/patches/macos-ifactor.patch +++ b/build/pkgs/giac/patches/macos-ifactor.patch @@ -1,12 +1,11 @@ --- a/src/ifactor.cc 2014-10-11 16:29:01.000000000 +0200 +++ b/src/ifactor.cc 2014-10-11 16:29:28.000000000 +0200 -@@ -4007,7 +4007,7 @@ +@@ -4034,7 +4034,4 @@ #endif #ifdef HAVE_LIBPARI - #ifdef __APPLE__ -- return vecteur(1,gensizeerr(gettext("(Mac OS) Large number, you can try pari(); pari_factor(")+n0.print(contextptr)+")")); -+ // return vecteur(1,gensizeerr(gettext("(Mac OS) Large number, you can try pari(); pari_factor(")+n0.print(contextptr)+")")); - #endif - gen g(pari_ifactor(n0),contextptr); - if (g.type==_VECT){ - + if (ifactor_pari){ +-#ifdef __APPLE__ +- return vecteur(1,gensizeerr(gettext("(Mac OS) Large number, you can try pari(); pari_factor(")+n0.print(contextptr)+")")); +-#endif + gen g(pari_ifactor(n0),contextptr); + if (g.type==_VECT){ diff --git a/build/pkgs/giac/spkg-install.in b/build/pkgs/giac/spkg-install.in index ca30dc6ea62..c20671a7b88 100644 --- a/build/pkgs/giac/spkg-install.in +++ b/build/pkgs/giac/spkg-install.in @@ -16,6 +16,9 @@ if [ `uname -m` = "ppc64" ]; then CPPFLAGS="-Dx86_64 $CPPFLAGS" fi +# #31563: Kick the can down the road +CPPFLAGS="-DUSE_OBJET_BIDON=1 $CPPFLAGS" + # Using pari in a C++17 file with "using namespace std doesn't # work due to a conflict between std::rank and pari's rank # -std=c++17 is in the default flags on conda; @@ -53,7 +56,7 @@ if [ "$UNAME" = "CYGWIN" ]; then export ac_cv_header_nauty_naututil_h=no fi -sdh_configure --disable-gui --disable-ao "$DISABLENLS" --enable-png=no --disable-samplerate --disable-static --disable-micropy +sdh_configure --disable-gui --disable-ao "$DISABLENLS" --enable-png=no --disable-samplerate --disable-static --disable-micropy --disable-quickjs ############################################################# # Build diff --git a/build/pkgs/giac/spkg-src b/build/pkgs/giac/spkg-src index 064c7a092e0..830c4a47c65 100755 --- a/build/pkgs/giac/spkg-src +++ b/build/pkgs/giac/spkg-src @@ -13,9 +13,9 @@ fi # Exit on failure set -e -VERSION="1.6.0" -VERSIONREV="47" -PATCHSUFFIX="p3" +VERSION="1.9.0" +VERSIONREV="15" +PATCHSUFFIX="p0" # The upstream tarball name is: giac"$SOURCEORIG".tar.gz SOURCEORIG=_"$VERSION"-"$VERSIONREV" @@ -49,6 +49,9 @@ mv giac-"$VERSION" src # remove unnecessary files rm -rf src/doc/pari/*.html +rm -f src/doc/*.wasm src/doc/*.js +sed -E -i.bak '/XCASHTML/s/[^ ]*[.](wasm|js)//g' src/doc/Makefile.am + # removing french html doc, but keep keywords, and working makefiles. # NB: the french html doc is huge and not GPL. # it is freely redistributable only for non commercial purposes. diff --git a/build/pkgs/python_build/SPKG.rst b/build/pkgs/python_build/SPKG.rst new file mode 100644 index 00000000000..9249861c610 --- /dev/null +++ b/build/pkgs/python_build/SPKG.rst @@ -0,0 +1,18 @@ +python_build: A simple, correct PEP517 package builder +====================================================== + +Description +----------- + +``build`` is a simple, correct PEP517 package builder + +License +------- + +MIT + +Upstream Contact +---------------- + +https://pypi.org/project/build/ + diff --git a/build/pkgs/build/dependencies b/build/pkgs/python_build/dependencies similarity index 100% rename from build/pkgs/build/dependencies rename to build/pkgs/python_build/dependencies diff --git a/build/pkgs/build/requirements.txt b/build/pkgs/python_build/requirements.txt similarity index 100% rename from build/pkgs/build/requirements.txt rename to build/pkgs/python_build/requirements.txt diff --git a/build/pkgs/build/type b/build/pkgs/python_build/type similarity index 100% rename from build/pkgs/build/type rename to build/pkgs/python_build/type diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index 2d13b49ef28..8ec83b2b905 100644 --- a/build/pkgs/sage_conf/install-requires.txt +++ b/build/pkgs/sage_conf/install-requires.txt @@ -1 +1,2 @@ -sage-conf ~= 9.7.b3 +# This file is updated on every release by the sage-update-version script +sage-conf ~= 9.7b6 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index b6e14e76015..9199fde5772 100644 --- a/build/pkgs/sage_docbuild/install-requires.txt +++ b/build/pkgs/sage_docbuild/install-requires.txt @@ -1 +1,2 @@ -sage_docbuild +# This file is updated on every release by the sage-update-version script +sage-docbuild ~= 9.7b6 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index 17adea02d63..4497f3f35a9 100644 --- a/build/pkgs/sage_setup/install-requires.txt +++ b/build/pkgs/sage_setup/install-requires.txt @@ -1 +1,2 @@ -sage-setup ~= 9.7.b3 +# This file is updated on every release by the sage-update-version script +sage-setup ~= 9.7b6 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index b489fda6aeb..aabd0d31807 100644 --- a/build/pkgs/sage_sws2rst/install-requires.txt +++ b/build/pkgs/sage_sws2rst/install-requires.txt @@ -1 +1,2 @@ -sage_sws2rst +# This file is updated on every release by the sage-update-version script +sage-sws2rst ~= 9.7b6 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index 29a9a5df969..35f845894d6 100644 --- a/build/pkgs/sagelib/install-requires.txt +++ b/build/pkgs/sagelib/install-requires.txt @@ -1 +1,2 @@ -sagemath-standard +# This file is updated on every release by the sage-update-version script +sagelib ~= 9.7b6 diff --git a/build/pkgs/sagemath_categories/dependencies b/build/pkgs/sagemath_categories/dependencies index 8084ffef958..b8d566d84de 100644 --- a/build/pkgs/sagemath_categories/dependencies +++ b/build/pkgs/sagemath_categories/dependencies @@ -1 +1 @@ -$(PYTHON) cysignals gmpy2 sagemath_objects | $(PYTHON_TOOLCHAIN) sagemath_environment sage_setup cython pkgconfig build $(and $(filter-out no,$(SAGE_CHECK_sagemath_categories)), tox sagemath_repl) +$(PYTHON) cysignals gmpy2 sagemath_objects | $(PYTHON_TOOLCHAIN) sagemath_environment sage_setup cython pkgconfig python_build diff --git a/build/pkgs/sagemath_categories/dependencies_check b/build/pkgs/sagemath_categories/dependencies_check new file mode 100644 index 00000000000..7d2fe6c3064 --- /dev/null +++ b/build/pkgs/sagemath_categories/dependencies_check @@ -0,0 +1 @@ +tox sagemath_repl diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index e35667f8201..da1b503c697 100644 --- a/build/pkgs/sagemath_categories/install-requires.txt +++ b/build/pkgs/sagemath_categories/install-requires.txt @@ -1 +1,2 @@ -sagemath-categories ~= 9.5b6 +# This file is updated on every release by the sage-update-version script +sagemath-categories ~= 9.7b6 diff --git a/build/pkgs/sagemath_environment/dependencies b/build/pkgs/sagemath_environment/dependencies index 942ea0d61e3..605611e7a21 100644 --- a/build/pkgs/sagemath_environment/dependencies +++ b/build/pkgs/sagemath_environment/dependencies @@ -1 +1 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) build $(and $(filter-out no,$(SAGE_CHECK_sagemath_environment)), tox) +$(PYTHON) | $(PYTHON_TOOLCHAIN) python_build diff --git a/build/pkgs/sagemath_environment/dependencies_check b/build/pkgs/sagemath_environment/dependencies_check new file mode 100644 index 00000000000..053148f8486 --- /dev/null +++ b/build/pkgs/sagemath_environment/dependencies_check @@ -0,0 +1 @@ +tox diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index 2a9064d9451..1dd6c84bc68 100644 --- a/build/pkgs/sagemath_environment/install-requires.txt +++ b/build/pkgs/sagemath_environment/install-requires.txt @@ -1 +1,2 @@ -sagemath-environment ~= 9.6rc3 +# This file is updated on every release by the sage-update-version script +sagemath-environment ~= 9.7b6 diff --git a/build/pkgs/sagemath_objects/dependencies b/build/pkgs/sagemath_objects/dependencies index c94ad110a24..807b8b17215 100644 --- a/build/pkgs/sagemath_objects/dependencies +++ b/build/pkgs/sagemath_objects/dependencies @@ -1 +1,3 @@ -FORCE $(PYTHON) cysignals gmpy2 | $(PYTHON_TOOLCHAIN) sagemath_environment sage_setup cython pkgconfig build +FORCE $(PYTHON) cysignals gmpy2 | $(PYTHON_TOOLCHAIN) sagemath_environment sage_setup cython pkgconfig python_build + +# FORCE: Always run the spkg-install script diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index 06766454a53..b28d0b381ca 100644 --- a/build/pkgs/sagemath_objects/install-requires.txt +++ b/build/pkgs/sagemath_objects/install-requires.txt @@ -1,2 +1,2 @@ -# Pinned in Trac #29941 until proper namespace packages are supported in #28925. -sagemath-objects == 9.6rc3.post4 +# This file is updated on every release by the sage-update-version script +sagemath-objects ~= 9.7b6 diff --git a/build/pkgs/sagemath_objects/spkg-install b/build/pkgs/sagemath_objects/spkg-install index b21c198671b..6cc85e07e55 100755 --- a/build/pkgs/sagemath_objects/spkg-install +++ b/build/pkgs/sagemath_objects/spkg-install @@ -25,5 +25,5 @@ wheel=$(cd "$DIST_DIR" && sdh_store_wheel . && echo $wheel) ls -l "$wheel" if [ "$SAGE_CHECK" != no ]; then - tox -r -v -e sagepython-norequirements-sagewheels-nopypi --installpkg $wheel + tox -r -v -e sagepython-sagewheels-nopypi-norequirements --installpkg $wheel fi diff --git a/build/pkgs/sagemath_repl/dependencies b/build/pkgs/sagemath_repl/dependencies index fd34bf2ba44..6c22cd39e91 100644 --- a/build/pkgs/sagemath_repl/dependencies +++ b/build/pkgs/sagemath_repl/dependencies @@ -1 +1 @@ -$(PYTHON) sagemath_objects ipython | $(PYTHON_TOOLCHAIN) build $(and $(filter-out no,$(SAGE_CHECK_sagemath_repl)), tox) +$(PYTHON) sagemath_objects ipython | $(PYTHON_TOOLCHAIN) python_build diff --git a/build/pkgs/sagemath_repl/dependencies_check b/build/pkgs/sagemath_repl/dependencies_check new file mode 100644 index 00000000000..053148f8486 --- /dev/null +++ b/build/pkgs/sagemath_repl/dependencies_check @@ -0,0 +1 @@ +tox diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index d81a6e1675a..40b60fa7bd0 100644 --- a/build/pkgs/sagemath_repl/install-requires.txt +++ b/build/pkgs/sagemath_repl/install-requires.txt @@ -1 +1,2 @@ -sagemath-repl +# This file is updated on every release by the sage-update-version script +sagemath-repl ~= 9.7b6 diff --git a/m4/ppl.m4 b/m4/ppl.m4 index 8a23895dc9b..2f4dc127e74 100644 --- a/m4/ppl.m4 +++ b/m4/ppl.m4 @@ -180,7 +180,7 @@ main() { << "\n*** was found! If ppl-config was correct, then it is best" "\n*** to remove the old version of PPL." " You may also be able to fix the error" - "\n*** by modifying your LD_LIBRARY_PATH enviroment variable," + "\n*** by modifying your LD_LIBRARY_PATH environment variable," " or by editing" "\n*** /etc/ld.so.conf." " Make sure you have run ldconfig if that is" @@ -224,7 +224,7 @@ main() { " variable to point" "\n*** to the correct copy of ppl-config. (In this case," " you will have to" - "\n*** modify your LD_LIBRARY_PATH enviroment" + "\n*** modify your LD_LIBRARY_PATH environment" " variable or edit /etc/ld.so.conf" "\n*** so that the correct libraries are found at run-time.)" << endl; diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 1d3a97792b7..ec1cd2281f6 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -9.7.beta5 +9.7.beta6 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 1d3a97792b7..ec1cd2281f6 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -9.7.beta5 +9.7.beta6 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 1d3a97792b7..ec1cd2281f6 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -9.7.beta5 +9.7.beta6 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 1d3a97792b7..ec1cd2281f6 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -9.7.beta5 +9.7.beta6 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 1d3a97792b7..ec1cd2281f6 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -9.7.beta5 +9.7.beta6 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 1d3a97792b7..ec1cd2281f6 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -9.7.beta5 +9.7.beta6 diff --git a/pkgs/sagemath-categories/tox.ini b/pkgs/sagemath-categories/tox.ini index 4d8df6befa4..44ca511ac22 100644 --- a/pkgs/sagemath-categories/tox.ini +++ b/pkgs/sagemath-categories/tox.ini @@ -25,14 +25,15 @@ passenv = PKG_CONFIG_PATH # Parallel build SAGE_NUM_THREADS - # SAGE_VENV only for finding the wheels - sagewheels: SAGE_VENV + SAGE_NUM_THREADS_PARALLEL + # SAGE_VENV only for referring to the basepython or finding the wheels + sagepython, sagewheels: SAGE_VENV # Location of the wheels sagewheels: SAGE_SPKG_WHEELS setenv = # Sage scripts such as sage-runtests like to use $HOME/.sage - HOME={envdir} + HOME={envdir} # We supply pip options by environment variables so that they # apply both to the installation of the dependencies and of the package sagewheels: PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} @@ -48,10 +49,19 @@ commands = # Test that importing sage.categories.all initializes categories {envpython} -c 'import sys; "" in sys.path and sys.path.remove(""); from sage.categories.all import *; SimplicialComplexes(); FunctionFields()' - bash -c 'cd {temp_dir} && SAGE_SRC=$(python -c "from sage.env import SAGE_SRC; print(SAGE_SRC)") && sage-runtests --environment=sage.all__sagemath_categories --optional=sage $SAGE_SRC/sage/structure || echo "(lots of doctest failures are expected)"' + bash -c 'cd {temp_dir} && SAGE_SRC=$(python -c "from sage.env import SAGE_SRC; print(SAGE_SRC)") && sage-runtests --initial --environment=sage.all__sagemath_categories --optional=sage $SAGE_SRC/sage/structure || echo "(lots of doctest failures are expected)"' [testenv:sagepython] -passenv = - SAGE_VENV +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:sagepython-sagewheels-nopypi] +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:sagepython-sagewheels-nopypi-norequirements] +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:sagepython-sagewheels] +basepython = {env:SAGE_VENV}/bin/python3 +[testenv:sagepython-norequirements] basepython = {env:SAGE_VENV}/bin/python3 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 1d3a97792b7..ec1cd2281f6 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -9.7.beta5 +9.7.beta6 diff --git a/pkgs/sagemath-environment/tox.ini b/pkgs/sagemath-environment/tox.ini index e926daf4052..f4875e6228c 100644 --- a/pkgs/sagemath-environment/tox.ini +++ b/pkgs/sagemath-environment/tox.ini @@ -1,34 +1,33 @@ # To build and test in the tox environment: # -# ./sage -sh -c '(cd pkgs/sagemath-environment && tox -v -v)' +# ./sage -sh -c '(cd pkgs/sagemath-environment && tox -v -v -e sagepython)' # # To test interactively: # -# pkgs/sagemath-environment/.tox/python/bin/python +# pkgs/sagemath-environment/.tox/sagepython/bin/python # [tox] envlist = sagepython-norequirements +isolated_build = True + [testenv] deps = !norequirements: -rrequirements.txt passenv = - # Variables set by .homebrew-build-env - CPATH - LIBRARY_PATH - PKG_CONFIG_PATH # Parallel build SAGE_NUM_THREADS - # SAGE_VENV only for finding the wheels - sagewheels: SAGE_VENV + SAGE_NUM_THREADS_PARALLEL + # SAGE_VENV only for referring to the basepython or finding the wheels + sagepython, sagewheels: SAGE_VENV # Location of the wheels sagewheels: SAGE_SPKG_WHEELS setenv = # Sage scripts such as sage-runtests like to use $HOME/.sage - HOME={envdir} + HOME={envdir} # We supply pip options by environment variables so that they # apply both to the installation of the dependencies and of the package sagewheels: PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} @@ -42,7 +41,16 @@ commands = {envpython} -c 'import sys; "" in sys.path and sys.path.remove(""); from sage.features.all import all_features; print(sorted(all_features(), key=lambda x: x.name)); import sage.misc.package' [testenv:sagepython] -passenv = - SAGE_VENV +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:sagepython-sagewheels-nopypi] +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:sagepython-sagewheels-nopypi-norequirements] +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:sagepython-sagewheels] +basepython = {env:SAGE_VENV}/bin/python3 +[testenv:sagepython-norequirements] basepython = {env:SAGE_VENV}/bin/python3 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 1d3a97792b7..ec1cd2281f6 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -9.7.beta5 +9.7.beta6 diff --git a/pkgs/sagemath-objects/tox.ini b/pkgs/sagemath-objects/tox.ini index 96983056162..babc128ff0c 100644 --- a/pkgs/sagemath-objects/tox.ini +++ b/pkgs/sagemath-objects/tox.ini @@ -23,14 +23,15 @@ passenv = PKG_CONFIG_PATH # Parallel build SAGE_NUM_THREADS - # SAGE_VENV only for finding the wheels - sagewheels: SAGE_VENV + SAGE_NUM_THREADS_PARALLEL + # SAGE_VENV only for referring to the basepython or finding the wheels + sagepython, sagewheels: SAGE_VENV # Location of the wheels sagewheels: SAGE_SPKG_WHEELS setenv = # Sage scripts such as sage-runtests like to use $HOME/.sage - HOME={envdir} + HOME={envdir} # We supply pip options by environment variables so that they # apply both to the installation of the dependencies and of the package sagewheels: PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} @@ -45,10 +46,19 @@ commands = {envpython} -c 'import sys; "" in sys.path and sys.path.remove(""); from sage.all__sagemath_objects import *' - #bash -c 'cd {temp_dir} && SAGE_SRC=$(python -c "from sage.env import SAGE_SRC; print(SAGE_SRC)") && sage-runtests --environment=sage.all__sagemath_objects --optional=sage $SAGE_SRC/sage/structure || echo "(lots of doctest failures are expected)"' + #bash -c 'cd {temp_dir} && SAGE_SRC=$(python -c "from sage.env import SAGE_SRC; print(SAGE_SRC)") && sage-runtests --environment=sage.all__sagemath_objects --initial --optional=sage $SAGE_SRC/sage/structure || echo "(lots of doctest failures are expected)"' [testenv:sagepython] -passenv = - SAGE_VENV +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:sagepython-sagewheels-nopypi] +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:sagepython-sagewheels-nopypi-norequirements] +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:sagepython-sagewheels] +basepython = {env:SAGE_VENV}/bin/python3 +[testenv:sagepython-norequirements] basepython = {env:SAGE_VENV}/bin/python3 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 1d3a97792b7..ec1cd2281f6 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -9.7.beta5 +9.7.beta6 diff --git a/pkgs/sagemath-repl/tox.ini b/pkgs/sagemath-repl/tox.ini index f81f72d8df9..b564bcda707 100644 --- a/pkgs/sagemath-repl/tox.ini +++ b/pkgs/sagemath-repl/tox.ini @@ -1,10 +1,10 @@ # To build and test in the tox environment: # -# ./sage -sh -c '(cd pkgs/sagemath-repl && tox -v -v)' +# ./sage -sh -c '(cd pkgs/sagemath-repl && tox -v -v -e sagepython)' # # To test interactively: # -# pkgs/sagemath-repl/.tox/python/bin/python +# pkgs/sagemath-repl/.tox/sagepython/bin/python # [tox] envlist = @@ -13,7 +13,8 @@ envlist = isolated_build = True [testenv] -deps = -rrequirements.txt +deps = + !norequirements: -rrequirements.txt passenv = # Variables set by .homebrew-build-env @@ -22,14 +23,15 @@ passenv = PKG_CONFIG_PATH # Parallel build SAGE_NUM_THREADS - # SAGE_VENV only for finding the wheels - sagewheels: SAGE_VENV + SAGE_NUM_THREADS_PARALLEL + # SAGE_VENV only for referring to the basepython or finding the wheels + sagepython, sagewheels: SAGE_VENV # Location of the wheels sagewheels: SAGE_SPKG_WHEELS setenv = # Sage scripts such as sage-runtests like to use $HOME/.sage - HOME={envdir} + HOME={envdir} # We supply pip options by environment variables so that they # apply both to the installation of the dependencies and of the package sagewheels: PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} @@ -40,12 +42,21 @@ whitelist_externals = commands = # Beware of the treacherous non-src layout. "./sage/" shadows the installed sage package. - python -c 'import sys; "" in sys.path and sys.path.remove(""); import sage.repl.all; import sage.doctest.all' + {envpython} -c 'import sys; "" in sys.path and sys.path.remove(""); import sage.repl.all; import sage.doctest.all' - bash -c 'cd bin && SAGE_SRC=$(python -c "from sage.env import SAGE_SRC; print(SAGE_SRC)") && sage-runtests --environment=sage.all__sagemath_repl --optional=sage $SAGE_SRC/sage/repl $SAGE_SRC/sage/doctest $SAGE_SRC/sage/misc/sage_input.py $SAGE_SRC/sage/misc/sage_eval.py || echo "(lots of doctest failures are expected)"' + bash -c 'cd bin && SAGE_SRC=$({envpython} -c "from sage.env import SAGE_SRC; print(SAGE_SRC)") && sage-runtests --environment=sage.all__sagemath_repl --initial --optional=sage $SAGE_SRC/sage/repl $SAGE_SRC/sage/doctest $SAGE_SRC/sage/misc/sage_input.py $SAGE_SRC/sage/misc/sage_eval.py || echo "(lots of doctest failures are expected)"' [testenv:sagepython] -passenv = - SAGE_VENV +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:sagepython-sagewheels-nopypi] +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:sagepython-sagewheels-nopypi-norequirements] +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:sagepython-sagewheels] +basepython = {env:SAGE_VENV}/bin/python3 +[testenv:sagepython-norequirements] basepython = {env:SAGE_VENV}/bin/python3 diff --git a/pkgs/sagemath-standard/tox.ini b/pkgs/sagemath-standard/tox.ini index b80af350be4..f021a7d2b22 100644 --- a/pkgs/sagemath-standard/tox.ini +++ b/pkgs/sagemath-standard/tox.ini @@ -82,10 +82,9 @@ passenv = PKG_CONFIG_PATH # Parallel build SAGE_NUM_THREADS - # SAGE_VENV only for finding the wheels + # SAGE_VENV only for referring to the basepython or finding the wheels sagepython, sagewheels: SAGE_VENV - # Location of the wheels (needs to include a PEP 503 compliant - # Simple Repository index, i.e., a subdirectory "simple") + # Location of the wheels sagewheels: SAGE_SPKG_WHEELS setenv = diff --git a/src/VERSION.txt b/src/VERSION.txt index 1d3a97792b7..ec1cd2281f6 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -9.7.beta5 +9.7.beta6 diff --git a/src/bin/sage-env b/src/bin/sage-env index 5875e617c32..6459c5aca78 100644 --- a/src/bin/sage-env +++ b/src/bin/sage-env @@ -200,7 +200,7 @@ fi if [ 1 = 2 ]; then - echo "The following enviroment variables can be set by the user" + echo "The following environment variables can be set by the user" echo "AR The archiver (e.g. ar, /usr/ccs/bin/ar or /usr/bin/ar)" echo "AS The assembler (e.g. as, /usr/ccs/bin/as or /usr/bin/as)" echo "CC The C compiler (e.g cc, /opt/SUNWspro/bin/cc or /usr/bin/gcc)" @@ -217,10 +217,10 @@ if [ 1 = 2 ]; then echo "SHAREDFLAGS Flag(s) necessary for building a shared library (e.g. -fPIC or -xcode=pic32)" echo "We attempt to set this to sensible values, but check below to" echo "ensure they are OK. If you wish to override any then please use:" - echo "setenv NAME_OF_ENVIROMENT_VARIABLE value_of_enviroment_variable" + echo "setenv NAME_OF_ENVIRONMENT_VARIABLE value_of_environment_variable" echo "(if you use tcsh, csh or a similar shell) or" - echo "NAME_OF_ENVIROMENT_VARIABLE value_of_enviroment_variable" - echo "export NAME_OF_ENVIROMENT_VARIABLE" + echo "NAME_OF_ENVIRONMENT_VARIABLE value_of_environment_variable" + echo "export NAME_OF_ENVIRONMENT_VARIABLE" echo "if you use sh, bash or a similar shell" fi diff --git a/src/bin/sage-update-version b/src/bin/sage-update-version index be312ed5775..dfd4d228eae 100755 --- a/src/bin/sage-update-version +++ b/src/bin/sage-update-version @@ -22,11 +22,11 @@ if [ $# -ne 1 ]; then fi if [ -z "$SAGE_ROOT" ]; then - die "must be run from within a Sage enviroment, or with SAGE_ROOT provided" + die "must be run from within a Sage environment, or with SAGE_ROOT provided" fi if [ -z "$SAGE_SRC" ]; then - die "must be run from within a Sage enviroment, or with SAGE_SRC provided" + die "must be run from within a Sage environment, or with SAGE_SRC provided" fi set -e @@ -43,6 +43,21 @@ for version_file in "$SAGE_ROOT"/pkgs/*/VERSION.txt; do fi done +# Update install-requires.txt for all distribution packages +( cd "$SAGE_ROOT"/build/pkgs/ && for spkg in sage*; do + if [ -f "$spkg"/install-requires.txt -a -d "$spkg"/src ]; then + ( echo "# This file is updated on every release by the sage-update-version script" + # Normalize the package name to PyPI convention (dashes, not underscores) + pkg=${spkg//_/-} + # Normalize the version (updated above as VERSION.txt) according to PEP440. + version=$(cat "$spkg"/package-version.txt) + version=${version//.beta/b} + version=${version//.rc/rc} + # ~= asks for a compatible release. https://peps.python.org/pep-0440/#compatible-release + echo "$pkg ~= $version" ) > "$spkg"/install-requires.txt + fi + done ) + # Update Sage version file for Python in SAGE_SRC/sage cat < "$SAGE_SRC/sage/version.py" # Sage version information for Python scripts @@ -81,6 +96,7 @@ git commit -m "Updated SageMath version to $SAGE_VERSION" -- \ "$SAGE_SRC/bin/sage-version.sh" \ "$SAGE_ROOT/build/pkgs/configure/checksums.ini" \ "$SAGE_ROOT/build/pkgs/configure/package-version.txt" \ + "$SAGE_ROOT/build/pkgs/*/install-requires.txt" \ "$SAGE_ROOT"/pkgs/*/VERSION.txt \ || die "Error committing to the repository." diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index a189f800535..c66568933c0 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -1,5 +1,5 @@ # Sage version information for shell scripts # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='9.7.beta5' -SAGE_RELEASE_DATE='2022-07-10' -SAGE_VERSION_BANNER='SageMath version 9.7.beta5, Release Date: 2022-07-10' +SAGE_VERSION='9.7.beta6' +SAGE_RELEASE_DATE='2022-07-24' +SAGE_VERSION_BANNER='SageMath version 9.7.beta6, Release Date: 2022-07-24' diff --git a/src/doc/en/developer/coding_basics.rst b/src/doc/en/developer/coding_basics.rst index 3e46c9ba0fe..5f27ccd05c2 100644 --- a/src/doc/en/developer/coding_basics.rst +++ b/src/doc/en/developer/coding_basics.rst @@ -113,7 +113,7 @@ of the directory containing the Sage sources: upstream/ # tarballs of upstream sources local/ # installed binaries -Python Sage library code goes into ``src/`` and uses the following +Python Sage library code goes into ``src/sage/`` and uses the following conventions. Directory names may be plural (e.g. ``rings``) and file names are almost always singular (e.g. ``polynomial_ring.py``). Note that the file ``polynomial_ring.py`` might still contain definitions @@ -125,29 +125,34 @@ of several different types of polynomial rings. discussions, etc., in your package. Make these plain text files (with extension ``.txt``) in a subdirectory called ``notes``. -If you want to create a new directory in the Sage library -``SAGE_ROOT/src/sage`` (say, ``measure_theory``), that directory -should contain a file ``__init__.py`` that contains the single line -``import all`` in addition to whatever -files you want to add (say, ``borel_measure.py`` and -``banach_tarski.py``), and also a file ``all.py`` listing imports from -that directory that are important enough to be in the Sage’s global -namespace at startup. -The file ``all.py`` might look like this:: +If you want to create a new directory (`package +`_) in the +Sage library ``SAGE_ROOT/src/sage`` (say, ``measure_theory``), that +directory will usually contain an empty file ``__init__.py``, which +marks the directory as an ordinary package (see +:ref:`section_namespace_packages`), and also a file ``all.py``, +listing imports from this package that are user-facing and important +enough to be in the global namespace of Sage at startup. The file +``all.py`` might look like this:: - from borel_measure import BorelMeasure - from banach_tarski import BanachTarskiParadox + from .borel_measure import BorelMeasure + from .banach_tarski import BanachTarskiParadox -but it is generally better to use the lazy import framework:: +but it is generally better to use the :mod:`~sage.misc.lazy_import` +framework:: from sage.misc.lazy_import import lazy_import - lazy_import('sage.measure_theory.borel_measue', 'BorelMeasure') + lazy_import('sage.measure_theory.borel_measure', 'BorelMeasure') lazy_import('sage.measure_theory.banach_tarski', 'BanachTarskiParadox') Then in the file ``SAGE_ROOT/src/sage/all.py``, add a line :: from sage.measure_theory.all import * +Adding new top-level packages below :mod:`sage` should be done +sparingly. It is often better to create subpackages of existing +packages. + Non-Python Sage source code and supporting files can be included in one of the following places: diff --git a/src/doc/en/developer/coding_in_python.rst b/src/doc/en/developer/coding_in_python.rst index da8d7de2d08..55633c8a029 100644 --- a/src/doc/en/developer/coding_in_python.rst +++ b/src/doc/en/developer/coding_in_python.rst @@ -496,7 +496,8 @@ Importing ========= We mention two issues with importing: circular imports and importing -large third-party modules. +large third-party modules. See also :ref:`section_dependencies_distributions` +for a discussion of imports from the viewpoint of modularization. First, you must avoid circular imports. For example, suppose that the file ``SAGE_ROOT/src/sage/algebras/steenrod_algebra.py`` @@ -542,7 +543,7 @@ look like this (omitting the documentation string): return steenrod_algebra_basis(n, basis=self._basis_name, p=self.prime) Second, do not import at the top level of your module a third-party -module that will take a long time to initialize (e.g. matplotlib). As +module that will take a long time to initialize (e.g. :mod:`matplotlib`). As above, you might instead import specific components of the module when they are needed, rather than at the top level of your file. @@ -555,6 +556,27 @@ import but delay it until the object is actually used. See :ref:`chapter-directory-structure` for an example using lazy imports for a new module. +If your module needs to make some precomputed data available at the top level, +you can reduce its load time (and thus startup time, unless your module is +imported using :mod:`sage.misc.lazy_import`) by using the decorator +:func:`sage.misc.cachefunc.cached_function` instead. For example, replace + +.. CODE-BLOCK:: python + + big_data = initialize_big_data() # bad: runs at module load time + +by + +.. CODE-BLOCK:: python + + from sage.misc.cachefunc import cached_function + + @cached_function # good: runs on first use + def big_data(): + return initialize_big_data() + + + Deprecation =========== diff --git a/src/doc/en/developer/packaging_sage_library.rst b/src/doc/en/developer/packaging_sage_library.rst index 7ed73ed6fe4..c792b8ee68e 100644 --- a/src/doc/en/developer/packaging_sage_library.rst +++ b/src/doc/en/developer/packaging_sage_library.rst @@ -75,6 +75,8 @@ Sage-specific distribution. Examples: :mod:`sage.ext.memory_allocator`, a part of the Sage library. +.. _section_namespace_packages: + Ordinary packages vs. implicit namespace packages ------------------------------------------------- @@ -203,6 +205,7 @@ Because the distribution packages are included in the source tree, we set them up as "script packages" instead of "normal packages", see :ref:`section-package-source-types`. +.. _section_dependencies_distributions: Dependencies and distribution packages ====================================== diff --git a/src/doc/en/developer/ticket_badges.png b/src/doc/en/developer/ticket_badges.png new file mode 100644 index 00000000000..1da26d4e867 Binary files /dev/null and b/src/doc/en/developer/ticket_badges.png differ diff --git a/src/doc/en/developer/tools.rst b/src/doc/en/developer/tools.rst index 924b8acf7d6..ee2e8bf0b1c 100644 --- a/src/doc/en/developer/tools.rst +++ b/src/doc/en/developer/tools.rst @@ -8,6 +8,8 @@ Additional development and testing tools ======================================== +.. _section-tools-tox: + Tox === @@ -72,6 +74,8 @@ Sage doctester in the normal Sage environment. This is equivalent to using the command ``./sage -t``; see :ref:`chapter-doctesting`. +.. _section-tools-coverage: + Coverage ======== @@ -82,6 +86,8 @@ arguments are provided) or ``./sage --coverage`` (if arguments are provided). +.. _section-tools-startuptime: + Startuptime =========== @@ -90,6 +96,8 @@ built already. ``startuptime`` is a special tox environment that is equivalent to using the command ``./sage --startuptime``. +.. _section-tools-pycodestyle: + Pycodestyle =========== `Pycodestyle `_ (formerly known as pep8) @@ -195,6 +203,8 @@ or a few related issues:: *Documentation:* https://pycodestyle.pycqa.org/en/latest/index.html +.. _section-tools-relint: + Relint ====== @@ -210,6 +220,8 @@ documentation markup, and modularization anti-patterns. *Documentation:* https://pypi.org/project/relint/ +.. _section-tools-codespell: + Codespell ========= `Codespell `_ uses a dictionary to check for @@ -241,6 +253,8 @@ Sage defines a configuration for codespell:: - ``SAGE_ROOT/src/.codespell-dictionary.txt`` and ``SAGE_ROOT/src/.codespell-ignore.txt`` +.. _section-tools-pytest: + Pytest ====== `Pytest `_ is a testing framework. @@ -271,6 +285,9 @@ package :mod:`sage.numerical.backends` and some modules in *Documentation:* https://docs.pytest.org/en/stable/index.html + +.. _section-tools-pyright: + Pyright ======= `Pyright `_ is static type checker. @@ -291,10 +308,16 @@ Pyright *Documentation:* https://github.com/microsoft/pyright#documentation + +.. _section-tools-pyflakes: + Pyflakes ======== `Pyflakes `_ checks for common coding errors. + +.. _section-tools-lgtm: + LGTM ==== The website ``lgtm.com`` offers a detailed diagnostic about the global code quality and its evolution. diff --git a/src/doc/en/developer/trac.rst b/src/doc/en/developer/trac.rst index be65f073993..8b8872b9eef 100644 --- a/src/doc/en/developer/trac.rst +++ b/src/doc/en/developer/trac.rst @@ -280,15 +280,63 @@ Working on Tickets If you manage to fix a bug or enhance Sage you are our hero. See :ref:`chapter-walkthrough` for making changes to the Sage source code, uploading them to the Sage trac server, and finally putting your -new branch on the trac ticket. The following are some other relevant -issues: +new branch on the trac ticket. -* The Patch buildbot will automatically test your ticket. See `the - patchbot wiki `_ for more - information about its features and limitations. Make sure that you +.. image:: ticket_badges.png + +After pushing a branch to a ticket, the ticket will show badges +linking to results of automated tests that run on the patchbot and +other tests that run on GitHub Actions. + +* The Patch buildbot will automatically test your ticket. See :trac:`wiki/patchbot` + for more information about its features and limitations. Make sure that you look at the log, especially if the patch buildbot did not give you the green blob. +* A `linting workflow + `_ + runs on all pushes to a branch on Trac. It checks that the code of + the current branch adheres to the style guidelines using + :ref:`section-tools-pycodestyle` (in the ``pycodestyle-minimal`` + configuration) and :ref:`section-tools-relint`. + + In order to see details when it fails, you can click on the badge + and then select the most recent workflow run. + +* The `incremental build and test workflow + `_ + on GitHub Actions builds Sage for the current branch (incrementally + on top of an installation of the ``develop`` branch) and runs the + test. Note that in contrast to the patchbot, the ticket branch is + not merged into the current beta version. + + Details are again available by clicking on the badge. + + The automatic workflow runs on a container based on + ``ubuntu-focal-standard``. To request a run of the workflow on a + different platform, you can issue a `workflow_dispatch + `_. + You can select any of the platforms for which a `prebuilt container + image + `_ + exists. + +* The `build documentation workflow + `_ + on GitHub Actions builds the HTML documentation for the current + branch. + + If you click on the badge, you get the HTML output of the successful + run. The idea is to use this to easily inspect changes to the + documentation without the need to locally rebuild the docs + yourself. If the doc build fails, you can go to `the Actions tab of + sagemath/sagetrac-mirror repo + `_ + and choose the particular branch to see what went wrong. + + +The following are some other relevant issues: + * Every bug fixed should result in a doctest. * This is not an issue with defects, but there are many enhancements diff --git a/src/doc/en/reference/graphs/index.rst b/src/doc/en/reference/graphs/index.rst index b1ec35240de..496f00ebcba 100644 --- a/src/doc/en/reference/graphs/index.rst +++ b/src/doc/en/reference/graphs/index.rst @@ -113,6 +113,7 @@ Libraries of algorithms sage/graphs/generic_graph_pyx sage/graphs/orientations sage/graphs/connectivity + sage/graphs/edge_connectivity sage/graphs/domination .. include:: ../footer.txt diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 33d876d08eb..e8f8640e1ae 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -775,6 +775,12 @@ REFERENCES: of invariant theory for the symmetric group* `\mathsf{S}_n`. Preprint (2017). :arxiv:`1707.1410` +.. [BHKP2008] Anand Bhalgat, Ramesh Hariharan, Telikepalli Kavitha and Debmalya + Panigrah. *Fast edge splitting and Edmonds' arborescence + construction for unweighted graphs*. ACM-SIAM Symposium on + Discrete Algorithms (SODA), pp 455-464, 2008. + :doi:`10.5555/1347082.1347132` + .. [BHS2008] Robert Bradshaw, David Harvey and William Stein. strassen_window_multiply_c. strassen.pyx, Sage 3.0, 2008. http://www.sagemath.org @@ -2451,6 +2457,11 @@ REFERENCES: .. [Ga02] Shuhong Gao, A new algorithm for decoding Reed-Solomon Codes, January 31, 2002 +.. [Gabow1995] Harold N. Gabow. *A Matroid Approach to Finding Edge Connectivity + and Packing Arborescences*. Journal of Computer and System Sciences, + 50(2):259-273, 1995. + :doi:`10.1006/jcss.1995.1022` + .. [Gallai] T. Gallai, Elementare Relationen bezueglich der Glieder und trennenden Punkte von Graphen, Magyar Tud. Akad. Mat. Kutato Int. Kozl. 9 (1964) 235-236 @@ -2572,6 +2583,12 @@ REFERENCES: .. [GK2013] Roland Grinis and Alexander Kasprzyk, Normal forms of convex lattice polytopes, :arxiv:`1301.6641` +.. [GKLP2021] Loukas Georgiadis, Dionysios Kefallinos, Luigi Laura, Nikos + Parotsidis. *An Experimental Study of Algorithms for Computing the + Edge Connectivity of a Directed Graph*. SIAM Symposium on + Algorithm Engineering and Experiments (ALENEX), pp 85-97, 2021. + :doi:`10.1137/1.9781611976472.7` + .. [GKP2011] Sylvain Gravier, Matjaz Kovse and Aline Parreau. *Generalized Sierpinski graphs*. Poster, European Conference on Combinatorics, Graph Theory and Applications (EuroComb’11), diff --git a/src/sage/algebras/askey_wilson.py b/src/sage/algebras/askey_wilson.py index 33014835bf0..37303e030c3 100644 --- a/src/sage/algebras/askey_wilson.py +++ b/src/sage/algebras/askey_wilson.py @@ -237,7 +237,7 @@ def __classcall_private__(cls, R, q=None): raise ValueError("q={} is not invertible in {}".format(q, R)) if R not in Rings().Commutative(): raise ValueError("{} is not a commutative ring".format(R)) - return super(AskeyWilsonAlgebra, cls).__classcall__(cls, R, q) + return super().__classcall__(cls, R, q) def __init__(self, R, q): r""" @@ -932,4 +932,4 @@ def _composition_(self, right, homset): return AlgebraMorphism(homset.domain(), [right(g) for g in self._on_generators], codomain=homset.codomain(), category=cat) - return super(self, AlgebraMorphism)._composition_(right, homset) + return super()._composition_(right, homset) diff --git a/src/sage/algebras/associated_graded.py b/src/sage/algebras/associated_graded.py index 499dd790c88..5e9d7b1f6b9 100644 --- a/src/sage/algebras/associated_graded.py +++ b/src/sage/algebras/associated_graded.py @@ -249,7 +249,7 @@ def _element_constructor_(self, x): if isinstance(x, CombinatorialFreeModule.Element): if x.parent() is self._A: return self._from_dict(dict(x)) - return super(AssociatedGradedAlgebra, self)._element_constructor_(x) + return super()._element_constructor_(x) def gen(self, *args, **kwds): """ diff --git a/src/sage/algebras/clifford_algebra.py b/src/sage/algebras/clifford_algebra.py index ece1c6e73a6..0c583b04f6c 100644 --- a/src/sage/algebras/clifford_algebra.py +++ b/src/sage/algebras/clifford_algebra.py @@ -463,7 +463,7 @@ def __classcall_private__(cls, Q, names=None): names = tuple( '{}{}'.format(names[0], i) for i in range(Q.dim()) ) else: raise ValueError("the number of variables does not match the number of generators") - return super(CliffordAlgebra, cls).__classcall__(cls, Q, names) + return super().__classcall__(cls, Q, names) def __init__(self, Q, names, category=None): r""" @@ -637,7 +637,7 @@ def _coerce_map_from_(self, V): if self.free_module().has_coerce_map_from(V): return True - return super(CliffordAlgebra, self)._coerce_map_from_(V) + return super()._coerce_map_from_(V) def _element_constructor_(self, x): """ @@ -682,7 +682,7 @@ def _element_constructor_(self, x): R = self.base_ring() return self.element_class(self, {i: R(c) for i,c in x if R(c) != R.zero()}) - return super(CliffordAlgebra, self)._element_constructor_(x) + return super()._element_constructor_(x) def gen(self, i): """ @@ -1369,7 +1369,7 @@ def __classcall_private__(cls, R, names=None, n=None): names = tuple( '{}{}'.format(names[0], i) for i in range(n) ) else: raise ValueError("the number of variables does not match the number of generators") - return super(ExteriorAlgebra, cls).__classcall__(cls, R, names) + return super().__classcall__(cls, R, names) def __init__(self, R, names): """ @@ -2211,7 +2211,7 @@ def __classcall__(cls, E, s_coeff): if isinstance(v, dict): R = E.base_ring() - v = E._from_dict({(i,): R(c) for i,c in v.items()}) + v = E._from_dict({(i,): R(c) for i, c in v.items()}) else: # Make sure v is in ``E`` v = E(v) @@ -2227,7 +2227,7 @@ def __classcall__(cls, E, s_coeff): d[(k[1], k[0])] = -v from sage.sets.family import Family - return super(ExteriorAlgebraDifferential, cls).__classcall__(cls, E, Family(d)) + return super().__classcall__(cls, E, Family(d)) def __init__(self, E, s_coeff): """ diff --git a/src/sage/algebras/cluster_algebra.py b/src/sage/algebras/cluster_algebra.py index b2ba26176b7..81615828b56 100644 --- a/src/sage/algebras/cluster_algebra.py +++ b/src/sage/algebras/cluster_algebra.py @@ -1338,7 +1338,7 @@ def __classcall__(self, data, **kwargs): # Determine scalars kwargs.setdefault('scalars', ZZ) - return super(ClusterAlgebra, self).__classcall__(self, B0, **kwargs) + return super().__classcall__(self, B0, **kwargs) def __init__(self, B, **kwargs): """ diff --git a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py index d14a3bde46a..1b466d157b7 100644 --- a/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +++ b/src/sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py @@ -140,8 +140,8 @@ def __classcall_private__(cls, k, table, names='e', assume_associative=False, names = normalize_names(n, names) - return super(FiniteDimensionalAlgebra, cls).__classcall__(cls, k, table, - names, category=cat) + return super().__classcall__(cls, k, table, + names, category=cat) def __init__(self, k, table, names='e', category=None): """ @@ -249,7 +249,7 @@ def _Hom_(self, B, category): if category.is_subcategory(cat): from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra_morphism import FiniteDimensionalAlgebraHomset return FiniteDimensionalAlgebraHomset(self, B, category=category) - return super(FiniteDimensionalAlgebra, self)._Hom_(B, category) + return super()._Hom_(B, category) def ngens(self): """ diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index 0b4c4ba8dbc..c53ab5da0e2 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -783,7 +783,7 @@ def quotient(self, mons, mats=None, names=None, **args): Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Rational Field """ if mats is None: - return super(FreeAlgebra_generic, self).quotient(mons, names) + return super().quotient(mons, names) from . import free_algebra_quotient return free_algebra_quotient.FreeAlgebraQuotient(self, mons, mats, names) @@ -1088,7 +1088,7 @@ def __classcall_private__(cls, R, n=None, names=None): if n is None: n = len(names) alg = FreeAlgebra(R, n, names) - return super(PBWBasisOfFreeAlgebra, cls).__classcall__(cls, alg) + return super().__classcall__(cls, alg) def __init__(self, alg): """ @@ -1137,7 +1137,7 @@ def _repr_term(self, w): 3*PBW[1] """ if len(w) == 0: - return super(PBWBasisOfFreeAlgebra, self)._repr_term(w) + return super()._repr_term(w) ret = '' p = 1 cur = None @@ -1149,7 +1149,7 @@ def _repr_term(self, w): if p != 1: ret += "^{}".format(p) ret += "*" - ret += super(PBWBasisOfFreeAlgebra, self)._repr_term(x.to_monoid_element()) + ret += super()._repr_term(x.to_monoid_element()) cur = x p = 1 if p != 1: diff --git a/src/sage/algebras/free_algebra_element.py b/src/sage/algebras/free_algebra_element.py index 8b7c39873c6..378f06479db 100644 --- a/src/sage/algebras/free_algebra_element.py +++ b/src/sage/algebras/free_algebra_element.py @@ -224,11 +224,11 @@ def _acted_upon_(self, scalar, self_on_left=False): if self_on_left: return Factorization([(self, 1)]) * scalar return scalar * Factorization([(self, 1)]) - return super(FreeAlgebraElement, self)._acted_upon_(scalar, self_on_left) + return super()._acted_upon_(scalar, self_on_left) # For backward compatibility - #_lmul_ = _acted_upon_ - #_rmul_ = _acted_upon_ + # _lmul_ = _acted_upon_ + # _rmul_ = _acted_upon_ def variables(self): """ diff --git a/src/sage/algebras/free_algebra_quotient.py b/src/sage/algebras/free_algebra_quotient.py index e3b325c4e57..d5f8050a1c9 100644 --- a/src/sage/algebras/free_algebra_quotient.py +++ b/src/sage/algebras/free_algebra_quotient.py @@ -83,10 +83,11 @@ def __classcall__(cls, A, mons, mats, names): M = M.parent()(M) M.set_immutable() new_mats.append(M) - return super(FreeAlgebraQuotient, cls).__classcall__(cls, A, tuple(mons), - tuple(new_mats), tuple(names)) + return super().__classcall__(cls, A, tuple(mons), + tuple(new_mats), tuple(names)) Element = FreeAlgebraQuotientElement + def __init__(self, A, mons, mats, names): """ Return a quotient algebra defined via the action of a free algebra diff --git a/src/sage/algebras/free_zinbiel_algebra.py b/src/sage/algebras/free_zinbiel_algebra.py index c87c48b6c9a..39ac9091618 100644 --- a/src/sage/algebras/free_zinbiel_algebra.py +++ b/src/sage/algebras/free_zinbiel_algebra.py @@ -211,10 +211,9 @@ def __classcall_private__(cls, R, n=None, names=None, side = '<' if side not in ['<', '>']: raise ValueError("side must be either '<' or '>'") - superclass = super(FreeZinbielAlgebra, cls) if names is None: - return superclass.__classcall__(cls, R, n, None, prefix, side) - return superclass.__classcall__(cls, R, n, tuple(names), prefix, side) + return super().__classcall__(cls, R, n, None, prefix, side) + return super().__classcall__(cls, R, n, tuple(names), prefix, side) def __init__(self, R, n, names, prefix, side): """ @@ -603,7 +602,7 @@ def _coerce_map_from_(self, R): return (all(x in self.variable_names() for x in R.variable_names()) and self.base_ring().has_coerce_map_from(R.base_ring())) - return super(FreeZinbielAlgebra, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) def construction(self): """ diff --git a/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py b/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py index 3cfb9c2c1d6..42a8de981b3 100644 --- a/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py +++ b/src/sage/algebras/hecke_algebras/ariki_koike_algebra.py @@ -311,7 +311,7 @@ def __classcall_private__(cls, r, n, q=None, u=None, R=None): raise TypeError("base ring must be a commutative ring") q = R(q) u = tuple(u) - return super(ArikiKoikeAlgebra, cls).__classcall__(cls, r, n, q, u, R) + return super().__classcall__(cls, r, n, q, u, R) def __init__(self, r, n, q, u, R): r""" diff --git a/src/sage/algebras/iwahori_hecke_algebra.py b/src/sage/algebras/iwahori_hecke_algebra.py index 5dde1e17330..ebbeb565341 100644 --- a/src/sage/algebras/iwahori_hecke_algebra.py +++ b/src/sage/algebras/iwahori_hecke_algebra.py @@ -449,7 +449,7 @@ def __classcall_private__(cls, W, q1, q2=-1, base_ring=None): else: q1 = base_ring(q1) q2 = base_ring(q2) - return super(IwahoriHeckeAlgebra, cls).__classcall__(cls, W, q1, q2, base_ring) + return super().__classcall__(cls, W, q1, q2, base_ring) def __init__(self, W, q1, q2, base_ring): r""" @@ -2498,7 +2498,7 @@ def __init__(self, IHAlgebra, prefix=None): except (TypeError, ZeroDivisionError): raise TypeError('the A-basis is defined only when 2 is invertible') - super(IwahoriHeckeAlgebra.A, self).__init__(IHAlgebra, prefix) + super().__init__(IHAlgebra, prefix) # Define and register coercions from the A basis to the T basis and back again from_A_to_T = self.module_morphism(self.to_T_basis, codomain=IHAlgebra.T(), @@ -2630,7 +2630,7 @@ def __init__(self, IHAlgebra, prefix=None): except (TypeError, ZeroDivisionError): raise TypeError('the B-basis is defined only when 2 is invertible') - super(IwahoriHeckeAlgebra.B, self).__init__(IHAlgebra, prefix) + super().__init__(IHAlgebra, prefix) # Define and register coercions from the B basis to the T basis and back again from_B_to_T = self.module_morphism(self.to_T_basis, codomain=IHAlgebra.T(), @@ -2745,7 +2745,7 @@ def __classcall_private__(cls, W): """ if W not in CoxeterGroups(): W = CoxeterGroup(W) - return super(IwahoriHeckeAlgebra_nonstandard, cls).__classcall__(cls, W) + return super().__classcall__(cls, W) def __init__(self, W): r""" diff --git a/src/sage/algebras/lie_algebras/abelian.py b/src/sage/algebras/lie_algebras/abelian.py index 3627c97b6ad..b0f3f685ee1 100644 --- a/src/sage/algebras/lie_algebras/abelian.py +++ b/src/sage/algebras/lie_algebras/abelian.py @@ -54,7 +54,7 @@ def __classcall_private__(cls, R, names=None, index_set=None, category=None, **k names, index_set = standardize_names_index_set(names, index_set) if index_set.cardinality() == infinity: return InfiniteDimensionalAbelianLieAlgebra(R, index_set, **kwds) - return super(AbelianLieAlgebra, cls).__classcall__(cls, R, names, index_set, category=category, **kwds) + return super().__classcall__(cls, R, names, index_set, category=category, **kwds) def __init__(self, R, names, index_set, category, **kwds): """ diff --git a/src/sage/algebras/lie_algebras/affine_lie_algebra.py b/src/sage/algebras/lie_algebras/affine_lie_algebra.py index 2464030edd9..90ecf56a5f0 100644 --- a/src/sage/algebras/lie_algebras/affine_lie_algebra.py +++ b/src/sage/algebras/lie_algebras/affine_lie_algebra.py @@ -174,7 +174,7 @@ def __classcall_private__(cls, arg0, cartan_type=None, kac_moody=True): if not cartan_type.is_untwisted_affine(): raise NotImplementedError("only currently implemented for untwisted affine types") - return super(AffineLieAlgebra, cls).__classcall__(cls, g, kac_moody) + return super().__classcall__(cls, g, kac_moody) def __init__(self, g, kac_moody): """ @@ -273,7 +273,7 @@ def _element_constructor_(self, x): if P == self._g: zero = self.base_ring().zero() return self.element_class(self, {0: x}, zero, zero) - return super(AffineLieAlgebra, self)._element_constructor_(x) + return super()._element_constructor_(x) def _coerce_map_from_(self, R): """ @@ -292,7 +292,7 @@ def _coerce_map_from_(self, R): """ if R is self.derived_subalgebra() or R is self._g: return True - return super(AffineLieAlgebra, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) def derived_subalgebra(self): """ diff --git a/src/sage/algebras/lie_algebras/classical_lie_algebra.py b/src/sage/algebras/lie_algebras/classical_lie_algebra.py index e157153e905..1ae47fa7a31 100644 --- a/src/sage/algebras/lie_algebras/classical_lie_algebra.py +++ b/src/sage/algebras/lie_algebras/classical_lie_algebra.py @@ -1568,8 +1568,7 @@ def __classcall_private__(cls, R, cartan_type): cartan_type = cartan_type.cartan_type() else: cartan_type = CartanType(cartan_type) - return super(LieAlgebraChevalleyBasis, cls).__classcall__( - cls, R, cartan_type) + return super().__classcall__(cls, R, cartan_type) def __init__(self, R, cartan_type): r""" diff --git a/src/sage/algebras/lie_algebras/free_lie_algebra.py b/src/sage/algebras/lie_algebras/free_lie_algebra.py index 4604328fbe7..8a02e5265c6 100644 --- a/src/sage/algebras/lie_algebras/free_lie_algebra.py +++ b/src/sage/algebras/lie_algebras/free_lie_algebra.py @@ -19,8 +19,8 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# ***************************************************************************** from sage.misc.abstract_method import abstract_method from sage.misc.cachefunc import cached_method @@ -169,7 +169,7 @@ def _element_constructor_(self, x): """ if not isinstance(x, list) and x in self._indices: return self.monomial(x) - return super(FreeLieBasis_abstract, self)._element_constructor_(x) + return super()._element_constructor_(x) def monomial(self, x): """ @@ -185,7 +185,7 @@ def monomial(self, x): """ if not isinstance(x, (LieGenerator, GradedLieBracket)): if isinstance(x, list): - return super(FreeLieBasis_abstract, self)._element_constructor_(x) + return super()._element_constructor_(x) else: i = self._indices.index(x) x = LieGenerator(x, i) @@ -363,7 +363,7 @@ def __classcall_private__(cls, R, names=None, index_set=None): True """ names, index_set = standardize_names_index_set(names, index_set) - return super(FreeLieAlgebra, cls).__classcall__(cls, R, names, index_set) + return super().__classcall__(cls, R, names, index_set) def __init__(self, R, names, index_set): """ diff --git a/src/sage/algebras/lie_algebras/heisenberg.py b/src/sage/algebras/lie_algebras/heisenberg.py index b2f81946a32..4662a3e313f 100644 --- a/src/sage/algebras/lie_algebras/heisenberg.py +++ b/src/sage/algebras/lie_algebras/heisenberg.py @@ -328,7 +328,7 @@ def _coerce_map_from_(self, H): if H._n <= self._n and self.base_ring().has_coerce_map_from(H.base_ring()): return H.module_morphism(lambda i: self.basis()[i], codomain=self) return None # Otherwise no coercion - return super(HeisenbergAlgebra_fd, self)._coerce_map_from_(H) + return super()._coerce_map_from_(H) class HeisenbergAlgebra(HeisenbergAlgebra_fd, HeisenbergAlgebra_abstract, @@ -547,15 +547,16 @@ def _coerce_map_from_(self, H): if isinstance(H, HeisenbergAlgebra_fd): if self.base_ring().has_coerce_map_from(H.base_ring()): return H.module_morphism(self._from_fd_on_basis, codomain=self) - return None # Otherwise no coercion + return None # Otherwise no coercion if isinstance(H, InfiniteHeisenbergAlgebra): if self.base_ring().has_coerce_map_from(H.base_ring()): return lambda C,x: self._from_dict(x._monomial_coefficients, coerce=True) - return None # Otherwise no coercion - return super(InfiniteHeisenbergAlgebra, self)._coerce_map_from_(H) + return None # Otherwise no coercion + return super()._coerce_map_from_(H) + ####################################################### -## Finite rank Heisenberg algebra using matrices +# Finite rank Heisenberg algebra using matrices class HeisenbergAlgebra_matrix(HeisenbergAlgebra_fd, LieAlgebraFromAssociative): r""" diff --git a/src/sage/algebras/lie_algebras/lie_algebra.py b/src/sage/algebras/lie_algebras/lie_algebra.py index 6a13a314175..0aa08d2a823 100644 --- a/src/sage/algebras/lie_algebras/lie_algebra.py +++ b/src/sage/algebras/lie_algebras/lie_algebra.py @@ -599,7 +599,7 @@ def __getitem__(self, x): return x[1].ideal(x[0]) # Otherwise it is the bracket of two elements return self(x[0])._bracket_(self(x[1])) - return super(LieAlgebra, self).__getitem__(x) + return super().__getitem__(x) def _coerce_map_from_(self, R): """ @@ -1132,8 +1132,8 @@ def __classcall_private__(cls, A, gens=None, names=None, index_set=None, index_set=index_set, category=category) - return super(LieAlgebraFromAssociative, cls).__classcall__(cls, - A, gens, names=names, index_set=index_set, category=category) + return super().__classcall__(cls, A, gens, names=names, + index_set=index_set, category=category) def __init__(self, A, gens=None, names=None, index_set=None, category=None): """ @@ -1352,7 +1352,7 @@ def is_abelian(self): """ if self._assoc.is_commutative(): return True - return super(LieAlgebraFromAssociative, self).is_abelian() + return super().is_abelian() def _an_element_(self): """ diff --git a/src/sage/algebras/lie_algebras/nilpotent_lie_algebra.py b/src/sage/algebras/lie_algebras/nilpotent_lie_algebra.py index e22c1a0fd25..a97e422e54b 100644 --- a/src/sage/algebras/lie_algebras/nilpotent_lie_algebra.py +++ b/src/sage/algebras/lie_algebras/nilpotent_lie_algebra.py @@ -129,8 +129,8 @@ def __classcall_private__(cls, R, s_coeff, names=None, index_set=None, cat = LieAlgebras(R).FiniteDimensional().WithBasis().Nilpotent() category = cat.or_subcategory(category) - return super(NilpotentLieAlgebra_dense, cls).__classcall__( - cls, R, s_coeff, names, index_set, category=category, **kwds) + return super().__classcall__(cls, R, s_coeff, names, + index_set, category=category, **kwds) def __init__(self, R, s_coeff, names, index_set, step=None, **kwds): r""" @@ -158,7 +158,7 @@ def _repr_(self): sage: L Nilpotent Lie algebra on 4 generators (X, Y, Z, W) over Rational Field """ - return "Nilpotent %s" % (super(NilpotentLieAlgebra_dense, self)._repr_()) + return "Nilpotent %s" % (super()._repr_()) class FreeNilpotentLieAlgebra(NilpotentLieAlgebra_dense): @@ -334,7 +334,7 @@ def __classcall_private__(cls, R, r, s, names=None, naming=None, category=None, cat = LieAlgebras(R).FiniteDimensional().WithBasis() category = cat.Graded().Stratified().or_subcategory(category) - return super(FreeNilpotentLieAlgebra, cls).__classcall__( + return super().__classcall__( cls, R, r, s, names=tuple(names), naming=naming, category=category, **kwds) @@ -452,4 +452,4 @@ def _repr_(self): sage: L Free Nilpotent Lie algebra on 5 generators (X_1, X_2, X_12, X_112, X_122) over Rational Field """ - return "Free %s" % (super(FreeNilpotentLieAlgebra, self)._repr_()) + return "Free %s" % (super()._repr_()) diff --git a/src/sage/algebras/lie_algebras/poincare_birkhoff_witt.py b/src/sage/algebras/lie_algebras/poincare_birkhoff_witt.py index 34df1d3281f..dbfc3d3d5ec 100644 --- a/src/sage/algebras/lie_algebras/poincare_birkhoff_witt.py +++ b/src/sage/algebras/lie_algebras/poincare_birkhoff_witt.py @@ -111,8 +111,8 @@ def __classcall_private__(cls, g, basis_key=None, prefix='PBW', **kwds): sage: P1 is P2 True """ - return super(PoincareBirkhoffWittBasis, cls).__classcall__(cls, - g, basis_key, prefix, **kwds) + return super().__classcall__(cls, + g, basis_key, prefix, **kwds) def __init__(self, g, basis_key, prefix, **kwds): """ @@ -345,7 +345,8 @@ def inv_supp(m): I = self._indices def basis_function(x): - return self.prod(self.monomial(I.gen(g)**e) for g,e in x._sorted_items()) + return self.prod(self.monomial(I.gen(g)**e) + for g, e in x._sorted_items()) # TODO: this diagonal, but with a smaller indexing set... return R.module_morphism(basis_function, codomain=self) coerce_map = self._g.coerce_map_from(R._g) @@ -359,7 +360,7 @@ def basis_function(x): # TODO: this diagonal, but with a smaller indexing set... return R.module_morphism(basis_function, codomain=self) - return super(PoincareBirkhoffWittBasis, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) def lie_algebra(self): """ diff --git a/src/sage/algebras/lie_algebras/quotient.py b/src/sage/algebras/lie_algebras/quotient.py index d3c5c226bb9..7fe6b29677f 100644 --- a/src/sage/algebras/lie_algebras/quotient.py +++ b/src/sage/algebras/lie_algebras/quotient.py @@ -233,9 +233,8 @@ def __classcall_private__(cls, I, ambient=None, names=None, cat = cat.Nilpotent() category = cat.Subquotients().or_subcategory(category) - sup = super(LieQuotient_finite_dimensional_with_basis, cls) - return sup.__classcall__(cls, I, ambient, names, index_set, - category=category) + return super().__classcall__(cls, I, ambient, names, index_set, + category=category) def __init__(self, I, L, names, index_set, category=None): r""" @@ -416,5 +415,4 @@ def from_vector(self, v, order=None, coerce=False): if len(v) == self.ambient().dimension(): return self.retract(self.ambient().from_vector(v)) - sup = super(LieQuotient_finite_dimensional_with_basis, self) - return sup.from_vector(v) + return super().from_vector(v) diff --git a/src/sage/algebras/lie_algebras/structure_coefficients.py b/src/sage/algebras/lie_algebras/structure_coefficients.py index 3f8cd1fd5e6..8eb6033c4c4 100644 --- a/src/sage/algebras/lie_algebras/structure_coefficients.py +++ b/src/sage/algebras/lie_algebras/structure_coefficients.py @@ -137,8 +137,7 @@ def __classcall_private__(cls, R, s_coeff, names=None, index_set=None, **kwds): from sage.algebras.lie_algebras.abelian import AbelianLieAlgebra return AbelianLieAlgebra(R, names, index_set, **kwds) - return super(LieAlgebraWithStructureCoefficients, cls).__classcall__( - cls, R, s_coeff, names, index_set, **kwds) + return super().__classcall__(cls, R, s_coeff, names, index_set, **kwds) @staticmethod def _standardize_s_coeff(s_coeff, index_set): diff --git a/src/sage/algebras/lie_algebras/verma_module.py b/src/sage/algebras/lie_algebras/verma_module.py index 2ba5da72c2c..5a9d5956557 100644 --- a/src/sage/algebras/lie_algebras/verma_module.py +++ b/src/sage/algebras/lie_algebras/verma_module.py @@ -253,7 +253,7 @@ def _repr_generator(self, m): sage: 2 * M.highest_weight_vector() 2*v[(-1/14, 3/7)] """ - ret = super(VermaModule, self)._repr_generator(m) + ret = super()._repr_generator(m) if ret == '1': ret = '' else: @@ -280,7 +280,7 @@ def _latex_generator(self, m): sage: latex(M.highest_weight_vector()) v_{-\frac{1}{14} e_{0} + \frac{3}{7} e_{1}} """ - ret = super(VermaModule, self)._latex_generator(m) + ret = super()._latex_generator(m) if ret == '1': ret = '' from sage.misc.latex import latex @@ -421,7 +421,7 @@ def _coerce_map_from_(self, R): H = Hom(R, self) if H.dimension() == 1: return H.natural_map() - return super(VermaModule, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) def _element_constructor_(self, x): r""" @@ -449,7 +449,7 @@ def _element_constructor_(self, x): return self._from_dict({self._indices.one(): x}) if isinstance(x, self._pbw.element_class): return self.highest_weight_vector()._acted_upon_(x, False) - return super(VermaModule, self)._element_constructor_(self, x) + return super()._element_constructor_(self, x) @lazy_attribute def _dominant_data(self): @@ -929,7 +929,7 @@ def _composition_(self, right, homset): if (isinstance(right, VermaModuleMorphism) and right.domain()._g is self.codomain()._g): return homset.element_class(homset, right._scalar * self._scalar) - return super(VermaModuleMorphism, self)._composition_(right, homset) + return super()._composition_(right, homset) def is_injective(self): r""" @@ -1051,7 +1051,7 @@ def __call__(self, x, **options): return self.zero() return self.element_class(self, self.base_ring()(x)) - return super(VermaModuleHomset, self).__call__(x, **options) + return super().__call__(x, **options) def _an_element_(self): """ diff --git a/src/sage/algebras/lie_algebras/virasoro.py b/src/sage/algebras/lie_algebras/virasoro.py index c6bb515600a..16589b60391 100644 --- a/src/sage/algebras/lie_algebras/virasoro.py +++ b/src/sage/algebras/lie_algebras/virasoro.py @@ -877,7 +877,7 @@ def __classcall_private__(cls, V, c, h): True """ R = V.base_ring() - return super(VermaModule, cls).__classcall__(cls, V, R(c), R(h)) + return super().__classcall__(cls, V, R(c), R(h)) @staticmethod def _partition_to_neg_tuple(x): @@ -978,7 +978,7 @@ def _monomial(self, index): if index >= 0: raise ValueError("sequence must have non-positive entries") index = (index,) - return super(VermaModule, self)._monomial(index) + return super()._monomial(index) def central_charge(self): """ diff --git a/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py index a2c4d607cb6..e5cddaed759 100644 --- a/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py @@ -102,18 +102,18 @@ def __init__(self, R, ngens=2, names=None, index_set=None): names,index_set = standardize_names_index_set(names=names, index_set=index_set, ngens=ngens) - A = identity_matrix(R,ngens/2) + A = identity_matrix(R, ngens // 2) from sage.matrix.special import block_matrix gram_matrix = block_matrix([[R.zero(),A],[-A,R.zero()]]) ghostsdict = { (i,j): {0: {('K',0): gram_matrix[index_set.rank(i), index_set.rank(j)]}} for i in index_set for j in index_set} weights = (1,)*(ngens//2) + (0,)*(ngens//2) - super(BosonicGhostsLieConformalAlgebra,self).__init__(R, - ghostsdict,names=names, - latex_names=latex_names, - index_set=index_set, - weights=weights, - central_elements=('K',)) + super().__init__(R, + ghostsdict,names=names, + latex_names=latex_names, + index_set=index_set, + weights=weights, + central_elements=('K',)) def _repr_(self): """ diff --git a/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py index 1615ae1bdca..4a74d9f9357 100644 --- a/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py @@ -98,20 +98,20 @@ def __init__(self,R,ngens=2,names=None,index_set=None): index_set=index_set, ngens=ngens) from sage.matrix.special import identity_matrix - A = identity_matrix(R,ngens/2) + A = identity_matrix(R, ngens // 2) from sage.matrix.special import block_matrix gram_matrix = block_matrix([[R.zero(),A],[A,R.zero()]]) ghostsdict = { (i,j): {0: {('K',0): gram_matrix[index_set.rank(i), index_set.rank(j)]}} for i in index_set for j in index_set} weights = (1,)*(ngens//2) + (0,)*(ngens//2) parity = (1,)*ngens - super(FermionicGhostsLieConformalAlgebra,self).__init__(R, - ghostsdict,names=names, - latex_names=latex_names, - index_set=index_set, - weights=weights, - parity=parity, - central_elements=('K',)) + super().__init__(R, + ghostsdict,names=names, + latex_names=latex_names, + index_set=index_set, + weights=weights, + parity=parity, + central_elements=('K',)) def _repr_(self): """ diff --git a/src/sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py b/src/sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py index b204c4a89b7..96f6c99defe 100644 --- a/src/sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +++ b/src/sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py @@ -30,8 +30,8 @@ class FinitelyFreelyGeneratedLCA(FreelyGeneratedLieConformalAlgebra): number of generators. """ def __init__(self, R, index_set=None, central_elements=None, category=None, - element_class=None, prefix=None, names=None, latex_names=None, - **kwds): + element_class=None, prefix=None, names=None, latex_names=None, + **kwds): """ Initialize self. @@ -50,10 +50,10 @@ def __init__(self, R, index_set=None, central_elements=None, category=None, if index_set not in Sets().Finite(): raise TypeError("index_set must be a finite set") - super(FinitelyFreelyGeneratedLCA,self).__init__(R, - index_set=index_set, central_elements=central_elements, - category=category, element_class=element_class, - prefix=prefix, **kwds) + super().__init__(R, + index_set=index_set, central_elements=central_elements, + category=category, element_class=element_class, + prefix=prefix, **kwds) self._ngens = len(self._generators) self._names = names self._latex_names = latex_names diff --git a/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py index d936fcb9f8a..f462a933a38 100644 --- a/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py @@ -36,7 +36,7 @@ class FreelyGeneratedLieConformalAlgebra(LieConformalAlgebraWithBasis): We now only accept direct sums of free modules plus some central generators `C_i` such that `TC_i = 0`. """ - def __init__(self,R, index_set=None, central_elements=None, category=None, + def __init__(self, R, index_set=None, central_elements=None, category=None, element_class=None, prefix=None, **kwds): """ Initialize self. @@ -52,11 +52,10 @@ def __init__(self,R, index_set=None, central_elements=None, category=None, self._generators = DisjointUnionEnumeratedSets([index_set, Family(central_elements)]) E = DisjointUnionEnumeratedSets((cartesian_product([ - Family(central_elements), {Integer(0)}]),E)) + Family(central_elements), {Integer(0)}]), E)) - super(FreelyGeneratedLieConformalAlgebra,self).__init__(R, basis_keys=E, - element_class=element_class, category=category, prefix=prefix, - **kwds) + super().__init__(R, basis_keys=E, element_class=element_class, + category=category, prefix=prefix, **kwds) if central_elements is not None: self._central_elements = Family(central_elements) diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py index e56785601fe..ae4882dbad0 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py @@ -50,7 +50,7 @@ class LieConformalAlgebraWithBasis(CombinatorialFreeModule): sage: R._repr_generator(R.0) 'e' """ - def __init__(self,R, basis_keys=None, element_class=None, category=None, + def __init__(self, R, basis_keys=None, element_class=None, category=None, prefix=None, **kwds): """ Initialize self. @@ -60,7 +60,6 @@ def __init__(self,R, basis_keys=None, element_class=None, category=None, sage: V = lie_conformal_algebras.Affine(QQ,'A1') sage: TestSuite(V).run() """ - if prefix is None: prefix = '' kwds['bracket'] = '' @@ -72,6 +71,5 @@ def __init__(self,R, basis_keys=None, element_class=None, category=None, except ValueError: category = default_category.Super().or_subcategory(category) - super(LieConformalAlgebraWithBasis,self).__init__(R, - basis_keys=basis_keys, element_class=element_class, - category=category, prefix=prefix, names=None, **kwds) + super().__init__(R, basis_keys=basis_keys, element_class=element_class, + category=category, prefix=prefix, names=None, **kwds) diff --git a/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py index bd2fa01b0a7..ee47970a31f 100644 --- a/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py @@ -162,16 +162,16 @@ def __init__(self,R,ngens=None, gram_matrix=None, names=None, names = 'alpha' latex_names = tuple(r'\alpha_{%d}' % i for i in range(ngens)) + ('K',) - names,index_set = standardize_names_index_set(names=names, + names, index_set = standardize_names_index_set(names=names, index_set=index_set, ngens=ngens) weyldict = { (i,j): {0: {('K',0): gram_matrix[index_set.rank(i), index_set.rank(j)]}} for i in index_set for j in index_set} - super(WeylLieConformalAlgebra,self).__init__(R,weyldict,names=names, - latex_names=latex_names, - index_set=index_set, - central_elements=('K',)) + super().__init__(R, weyldict, names=names, + latex_names=latex_names, + index_set=index_set, + central_elements=('K',)) self._gram_matrix = gram_matrix def _repr_(self): diff --git a/src/sage/algebras/orlik_solomon.py b/src/sage/algebras/orlik_solomon.py index 5de7269ac14..ffbbbb6a5af 100644 --- a/src/sage/algebras/orlik_solomon.py +++ b/src/sage/algebras/orlik_solomon.py @@ -99,7 +99,7 @@ def __classcall_private__(cls, R, M, ordering=None): """ if ordering is None: ordering = sorted(M.groundset()) - return super(OrlikSolomonAlgebra, cls).__classcall__(cls, R, M, tuple(ordering)) + return super().__classcall__(cls, R, M, tuple(ordering)) def __init__(self, R, M, ordering=None): """ diff --git a/src/sage/algebras/orlik_terao.py b/src/sage/algebras/orlik_terao.py index 128e6156ba7..458bb07b926 100644 --- a/src/sage/algebras/orlik_terao.py +++ b/src/sage/algebras/orlik_terao.py @@ -118,7 +118,7 @@ def __classcall_private__(cls, R, M, ordering=None): """ if ordering is None: ordering = sorted(M.groundset()) - return super(OrlikTeraoAlgebra, cls).__classcall__(cls, R, M, tuple(ordering)) + return super().__classcall__(cls, R, M, tuple(ordering)) def __init__(self, R, M, ordering=None): """ diff --git a/src/sage/algebras/q_system.py b/src/sage/algebras/q_system.py index 1050f148c48..f7d495aac50 100644 --- a/src/sage/algebras/q_system.py +++ b/src/sage/algebras/q_system.py @@ -149,7 +149,7 @@ def __classcall__(cls, base_ring, cartan_type, level=None, twisted=False): raise ValueError("the Cartan type is not tamely-laced") if twisted and not cartan_type.is_affine() and not cartan_type.is_untwisted_affine(): raise ValueError("the Cartan type must be of twisted type") - return super(QSystem, cls).__classcall__(cls, base_ring, cartan_type, level, twisted) + return super().__classcall__(cls, base_ring, cartan_type, level, twisted) def __init__(self, base_ring, cartan_type, level, twisted): """ diff --git a/src/sage/algebras/quantum_clifford.py b/src/sage/algebras/quantum_clifford.py index 35b84838f4c..8d11f400478 100644 --- a/src/sage/algebras/quantum_clifford.py +++ b/src/sage/algebras/quantum_clifford.py @@ -149,7 +149,7 @@ def __classcall_private__(cls, n, k=1, q=None, F=None): q = F(q) if F not in Fields(): raise TypeError("base ring must be a field") - return super(QuantumCliffordAlgebra, cls).__classcall__(cls, n, k, q, F) + return super().__classcall__(cls, n, k, q, F) def __init__(self, n, k, q, F): r""" diff --git a/src/sage/algebras/quantum_groups/ace_quantum_onsager.py b/src/sage/algebras/quantum_groups/ace_quantum_onsager.py index 990f06bd03e..91138258e5a 100644 --- a/src/sage/algebras/quantum_groups/ace_quantum_onsager.py +++ b/src/sage/algebras/quantum_groups/ace_quantum_onsager.py @@ -135,7 +135,7 @@ def __classcall_private__(cls, R=None, q=None): R = q.parent() else: q = R(q) - return super(ACEQuantumOnsagerAlgebra, cls).__classcall__(cls, R, q) + return super().__classcall__(cls, R, q) def __init__(self, R, q): r""" diff --git a/src/sage/algebras/quantum_groups/fock_space.py b/src/sage/algebras/quantum_groups/fock_space.py index 978a996125d..dea28fd1760 100644 --- a/src/sage/algebras/quantum_groups/fock_space.py +++ b/src/sage/algebras/quantum_groups/fock_space.py @@ -336,7 +336,7 @@ def __classcall_private__(cls, n, multicharge=[0], q=None, base_ring=None, trunc multicharge = tuple(M(e) for e in multicharge) if truncated is not None: return FockSpaceTruncated(n, truncated, q, base_ring) - return super(FockSpace, cls).__classcall__(cls, n, multicharge, q, base_ring) + return super().__classcall__(cls, n, multicharge, q, base_ring) def __init__(self, n, multicharge, q, base_ring): r""" @@ -1676,7 +1676,7 @@ def __classcall_private__(cls, n, k, q=None, base_ring=None): base_ring = q.parent() base_ring = FractionField(base_ring) q = base_ring(q) - return super(FockSpace, cls).__classcall__(cls, n, k, q, base_ring) + return super().__classcall__(cls, n, k, q, base_ring) def __init__(self, n, k, q, base_ring): r""" diff --git a/src/sage/algebras/quantum_groups/quantum_group_gap.py b/src/sage/algebras/quantum_groups/quantum_group_gap.py index 3e58d5576e8..0a647ffee17 100644 --- a/src/sage/algebras/quantum_groups/quantum_group_gap.py +++ b/src/sage/algebras/quantum_groups/quantum_group_gap.py @@ -353,7 +353,7 @@ def __classcall_private__(cls, cartan_type, q=None): True """ cartan_type = CartanType(cartan_type) - return super(QuantumGroup, cls).__classcall__(cls, cartan_type, q) + return super().__classcall__(cls, cartan_type, q) def __init__(self, cartan_type, q): """ @@ -1721,7 +1721,7 @@ def __classcall_private__(cls, Q, weight): weight = P.sum(la * weight[i] for i, la in enumerate(La)) else: weight = P(weight) - return super(HighestWeightModule, cls).__classcall__(cls, Q, weight) + return super().__classcall__(cls, Q, weight) def __init__(self, Q, weight): """ @@ -2141,7 +2141,7 @@ def __classcall_private__(cls, Q): from sage.combinat.root_system.cartan_type import CartanType_abstract if isinstance(Q, CartanType_abstract): Q = QuantumGroup(Q) - return super(LowerHalfQuantumGroup, cls).__classcall__(cls, Q) + return super().__classcall__(cls, Q) def __init__(self, Q): """ diff --git a/src/sage/algebras/quantum_groups/representations.py b/src/sage/algebras/quantum_groups/representations.py index efd977f45cf..b874d264669 100644 --- a/src/sage/algebras/quantum_groups/representations.py +++ b/src/sage/algebras/quantum_groups/representations.py @@ -52,7 +52,7 @@ def __classcall__(cls, R, C, q=None): """ if q is None: q = R.gen() - return super(QuantumGroupRepresentation, cls).__classcall__(cls, R, C, q) + return super().__classcall__(cls, R, C, q) def __init__(self, R, C, q): """ diff --git a/src/sage/algebras/quantum_matrix_coordinate_algebra.py b/src/sage/algebras/quantum_matrix_coordinate_algebra.py index 9dfff20cc70..1579896fa86 100644 --- a/src/sage/algebras/quantum_matrix_coordinate_algebra.py +++ b/src/sage/algebras/quantum_matrix_coordinate_algebra.py @@ -58,9 +58,8 @@ def __classcall__(cls, q=None, bar=None, R=None, **kwds): q = R(q) if q is None: q = LaurentPolynomialRing(R, 'q').gen() - return super(QuantumMatrixCoordinateAlgebra_abstract, - cls).__classcall__(cls, - q=q, bar=bar, R=q.parent(), **kwds) + return super().__classcall__(cls, + q=q, bar=bar, R=q.parent(), **kwds) def __init__(self, gp_indices, n, q, bar, R, category, indices_key=None): """ @@ -502,9 +501,9 @@ def __classcall_private__(cls, m, n=None, q=None, bar=None, R=None): """ if n is None: n = m - return super(QuantumMatrixCoordinateAlgebra, cls).__classcall__(cls, m=m, n=n, - q=q, bar=bar, - R=R) + return super().__classcall__(cls, m=m, n=n, + q=q, bar=bar, + R=R) def __init__(self, m, n, q, bar, R): """ @@ -739,7 +738,7 @@ def __classcall_private__(cls, n, q=None, bar=None, R=None): sage: O1 is O4 False """ - return super(QuantumGL, cls).__classcall__(cls, n=n, q=q, bar=bar, R=R) + return super().__classcall__(cls, n=n, q=q, bar=bar, R=R) def __init__(self, n, q, bar, R): """ @@ -878,7 +877,7 @@ def product_on_basis(self, a, b): c_exp += db.pop('c') b = I(db) # a and b contain no powers of c - p = super(QuantumGL, self).product_on_basis(a, b) + p = super().product_on_basis(a, b) if c_exp == 0: return p c = self._indices.monoid_generators()['c'] diff --git a/src/sage/algebras/rational_cherednik_algebra.py b/src/sage/algebras/rational_cherednik_algebra.py index 204fcfc6020..597954c7249 100644 --- a/src/sage/algebras/rational_cherednik_algebra.py +++ b/src/sage/algebras/rational_cherednik_algebra.py @@ -114,7 +114,7 @@ def __classcall_private__(cls, ct, c=1, t=None, base_ring=None, prefix=('a', 's' else: c = (c, c) - return super(RationalCherednikAlgebra, cls).__classcall__(cls, ct, c, t, base_ring, tuple(prefix)) + return super().__classcall__(cls, ct, c, t, base_ring, tuple(prefix)) def __init__(self, ct, c, t, base_ring, prefix): r""" diff --git a/src/sage/algebras/schur_algebra.py b/src/sage/algebras/schur_algebra.py index a700b6b8854..ba606ded999 100644 --- a/src/sage/algebras/schur_algebra.py +++ b/src/sage/algebras/schur_algebra.py @@ -528,7 +528,7 @@ def _acted_upon_(self, elt, self_on_left=False): elif elt in P._schur: # self_on_left is False return P._schur_action(elt, self) - return super(SchurTensorModule.Element, self)._acted_upon_(elt, self_on_left) + return super()._acted_upon_(elt, self_on_left) def GL_irreducible_character(n, mu, KK): diff --git a/src/sage/algebras/shuffle_algebra.py b/src/sage/algebras/shuffle_algebra.py index d5e7b524c5f..7ef009fd61f 100644 --- a/src/sage/algebras/shuffle_algebra.py +++ b/src/sage/algebras/shuffle_algebra.py @@ -140,8 +140,8 @@ def __classcall_private__(cls, R, names, prefix=None): """ if prefix is None: prefix = 'B' - return super(ShuffleAlgebra, cls).__classcall__(cls, R, - Alphabet(names), prefix) + return super().__classcall__(cls, R, + Alphabet(names), prefix) def __init__(self, R, names, prefix): r""" @@ -661,7 +661,7 @@ def __classcall_private__(cls, R, names): sage: D1 is D2 True """ - return super(DualPBWBasis, cls).__classcall__(cls, R, Alphabet(names)) + return super().__classcall__(cls, R, Alphabet(names)) def __init__(self, R, names): """ @@ -709,7 +709,7 @@ def _element_constructor_(self, x): x = W(x) elif isinstance(x.parent(), ShuffleAlgebra): return self._alg.to_dual_pbw_element(self._alg(x)) - return super(DualPBWBasis, self)._element_constructor_(x) + return super()._element_constructor_(x) def _coerce_map_from_(self, R): """ diff --git a/src/sage/algebras/splitting_algebra.py b/src/sage/algebras/splitting_algebra.py index 0eb2fed7746..e19a2bb6d9a 100644 --- a/src/sage/algebras/splitting_algebra.py +++ b/src/sage/algebras/splitting_algebra.py @@ -83,8 +83,7 @@ def __invert__(self): if self in inv_elements: return inv_elements[self] - return super(SplittingAlgebraElement, self).__invert__() - + return super().__invert__() def is_unit(self): r""" @@ -101,7 +100,7 @@ def is_unit(self): if self in inv_elements: return True - return super(SplittingAlgebraElement, self).is_unit() + return super().is_unit() def dict(self): r""" @@ -464,7 +463,7 @@ def _element_constructor_(self, x): if isinstance(x, SplittingAlgebraElement): # coercion from covering fixes pickling problems return self(x.lift()) - return super(SplittingAlgebra, self)._element_constructor_(x) + return super()._element_constructor_(x) def hom(self, im_gens, codomain=None, check=True, base_map=None): r""" @@ -492,19 +491,19 @@ def hom(self, im_gens, codomain=None, check=True, base_map=None): """ base_ring = self.base_ring() - if not isinstance(im_gens, (list,tuple)): + if not isinstance(im_gens, (list, tuple)): im_gens = [im_gens] all_gens = self.gens_dict_recursive() if len(im_gens) != len(all_gens): - return super(SplittingAlgebra, self).hom(im_gens, codomain=codomain, check=check, base_map=base_map) + return super().hom(im_gens, codomain=codomain, check=check, base_map=base_map) num_gens = len(self.gens()) - im_gens_start = [img for img in im_gens if im_gens.index(img) < num_gens] - im_gens_end = [img for img in im_gens if im_gens.index(img) >= num_gens] + im_gens_start = [img for img in im_gens if im_gens.index(img) < num_gens] + im_gens_end = [img for img in im_gens if im_gens.index(img) >= num_gens] if not im_gens_end: - return super(SplittingAlgebra, self).hom(im_gens, codomain=codomain, check=check, base_map=base_map) + return super().hom(im_gens, codomain=codomain, check=check, base_map=base_map) verbose('base %s im_gens_end %s codomain %s check %s base_map %s' % (base_ring, im_gens_end, codomain, check, base_map)) hom_on_base_recurs = base_ring.hom(im_gens_end, codomain=codomain, check=check, base_map=base_map) diff --git a/src/sage/algebras/steenrod/steenrod_algebra.py b/src/sage/algebras/steenrod/steenrod_algebra.py index f18797dc0de..9e9ad450358 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra.py +++ b/src/sage/algebras/steenrod/steenrod_algebra.py @@ -509,9 +509,10 @@ def __classcall__(self, p=2, basis='milnor', **kwds): raise ValueError("option 'generic' is not a boolean") std_basis = get_basis_name(basis, p, generic=std_generic) - std_profile, std_type = normalize_profile(profile, precision=precision, truncation_type=truncation_type, p=p, generic=std_generic) - return super(SteenrodAlgebra_generic, self).__classcall__(self, p=p, basis=std_basis, profile=std_profile, - truncation_type=std_type, generic=std_generic) + std_profile, std_type = normalize_profile(profile, precision=precision, + truncation_type=truncation_type, p=p, generic=std_generic) + return super().__classcall__(self, p=p, basis=std_basis, profile=std_profile, + truncation_type=std_type, generic=std_generic) def __init__(self, p=2, basis='milnor', **kwds): r""" diff --git a/src/sage/algebras/tensor_algebra.py b/src/sage/algebras/tensor_algebra.py index 5d44e1057a9..664027ee6ae 100644 --- a/src/sage/algebras/tensor_algebra.py +++ b/src/sage/algebras/tensor_algebra.py @@ -375,7 +375,7 @@ def _coerce_map_from_(self, R): for i,M in enumerate(modules)]), codomain=self) - return super(TensorAlgebra, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) def construction(self): """ diff --git a/src/sage/algebras/weyl_algebra.py b/src/sage/algebras/weyl_algebra.py index c43cc7839dd..13604578430 100644 --- a/src/sage/algebras/weyl_algebra.py +++ b/src/sage/algebras/weyl_algebra.py @@ -739,7 +739,7 @@ def __classcall__(cls, R, names=None): raise ValueError("the names must be specified") elif R not in Rings().Commutative(): raise TypeError("argument R must be a commutative ring") - return super(DifferentialWeylAlgebra, cls).__classcall__(cls, R, names) + return super().__classcall__(cls, R, names) def __init__(self, R, names=None): r""" @@ -888,7 +888,7 @@ def _coerce_map_from_(self, R): if isinstance(R, DifferentialWeylAlgebra): return ( R.variable_names() == self.variable_names() and self.base_ring().has_coerce_map_from(R.base_ring()) ) - return super(DifferentialWeylAlgebra, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) def degree_on_basis(self, i): """ diff --git a/src/sage/algebras/yangian.py b/src/sage/algebras/yangian.py index e7d1945ab31..b63648bbb95 100644 --- a/src/sage/algebras/yangian.py +++ b/src/sage/algebras/yangian.py @@ -368,9 +368,9 @@ def __classcall_private__(cls, base_ring, n, level=None, return YangianLevel(base_ring, n, level, variable_name, filtration) # We need to specify the parameter name for pickling, so it doesn't pass # ``variable_name`` as ``level`` - return super(Yangian, cls).__classcall__(cls, base_ring, n, - variable_name=variable_name, - filtration=filtration) + return super().__classcall__(cls, base_ring, n, + variable_name=variable_name, + filtration=filtration) def __init__(self, base_ring, n, variable_name, filtration): r""" @@ -507,7 +507,7 @@ def _element_constructor_(self, x): if isinstance(x.parent(), Yangian) and x.parent()._n <= self._n: R = self.base_ring() return self._from_dict({i: R(c) for i, c in x}, coerce=False) - return super(Yangian, self)._element_constructor_(x) + return super()._element_constructor_(x) def gen(self, r, i=None, j=None): """ @@ -894,7 +894,7 @@ def _coerce_map_from_(self, R): return False on_gens = lambda m: self.prod(self.gen(*a)**exp for a,exp in m._sorted_items()) return R.module_morphism(on_gens, codomain=self) - return super(YangianLevel, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) def level(self): """ diff --git a/src/sage/algebras/yokonuma_hecke_algebra.py b/src/sage/algebras/yokonuma_hecke_algebra.py index 7ec49b4b87e..6ccd9c985a6 100644 --- a/src/sage/algebras/yokonuma_hecke_algebra.py +++ b/src/sage/algebras/yokonuma_hecke_algebra.py @@ -136,7 +136,7 @@ def __classcall_private__(cls, d, n, q=None, R=None): q = R(q) if R not in Rings().Commutative(): raise TypeError("base ring must be a commutative ring") - return super(YokonumaHeckeAlgebra, cls).__classcall__(cls, d, n, q, R) + return super().__classcall__(cls, d, n, q, R) def __init__(self, d, n, q, R): """ @@ -154,7 +154,7 @@ def __init__(self, d, n, q, R): self._Pn = Permutations(n) import itertools C = itertools.product(*([range(d)]*n)) - indices = list( itertools.product(C, self._Pn)) + indices = list(itertools.product(C, self._Pn)) cat = Algebras(R).WithBasis() CombinatorialFreeModule.__init__(self, R, indices, prefix='Y', category=cat) diff --git a/src/sage/calculus/desolvers.py b/src/sage/calculus/desolvers.py index 02e4d0562d8..1e5d87de635 100644 --- a/src/sage/calculus/desolvers.py +++ b/src/sage/calculus/desolvers.py @@ -683,7 +683,7 @@ def sanitize_var(exprs): ## sage: de = lambda y: diff(y,x,x) - 2*diff(y,x) + y ## sage: desolve_laplace(de(f(x)),[f,x]) ## #x*%e^x*(?%at('diff('f(x),x,1),x=0))-'f(0)*x*%e^x+'f(0)*%e^x -## sage: desolve_laplace(de(f(x)),[f,x],[0,1,2]) ## IC option does not work +## sage: desolve_laplace(de(f(x)),[f,x],[0,1,2]) # IC option does not work ## #x*%e^x*(?%at('diff('f(x),x,1),x=0))-'f(0)*x*%e^x+'f(0)*%e^x ## AUTHOR: David Joyner (1st version 1-2006, 8-2007) diff --git a/src/sage/calculus/wester.py b/src/sage/calculus/wester.py index ef01bc0fc1b..10a64d25471 100644 --- a/src/sage/calculus/wester.py +++ b/src/sage/calculus/wester.py @@ -294,7 +294,9 @@ True sage: abs(float(a)) < 1e-10 True - sage: ## or we can do it using number fields. + +Or we can do it using number fields. :: + sage: reset('x') sage: k. = NumberField(x^3-2) sage: a = (b + b^2)^3 - 6*(b + b^2) - 6 @@ -326,8 +328,7 @@ sage: # (NO) Ln((2*Sqrt(r) + 1)/Sqrt(4*r 4*Sqrt(r) 1))=0. sage: var('r') r - sage: f = log( (2*sqrt(r) + 1) / sqrt(4*r + 4*sqrt(r) + 1)) - sage: f + sage: f = log( (2*sqrt(r) + 1) / sqrt(4*r + 4*sqrt(r) + 1)); f log((2*sqrt(r) + 1)/sqrt(4*r + 4*sqrt(r) + 1)) sage: bool(f == 0) False diff --git a/src/sage/categories/additive_magmas.py b/src/sage/categories/additive_magmas.py index 35fcfeb9d21..e81dcf9d4b9 100644 --- a/src/sage/categories/additive_magmas.py +++ b/src/sage/categories/additive_magmas.py @@ -278,7 +278,7 @@ def addition_table(self, names='letters', elements=None): has an addition defined.The default is to represent elements as lowercase ASCII letters. :: - sage: R=IntegerModRing(5) + sage: R = IntegerModRing(5) sage: R.addition_table() + a b c d e +---------- @@ -293,8 +293,8 @@ def addition_table(self, names='letters', elements=None): representation of the elements of the set. Requesting ``digits`` will include leading zeros as padding. :: - sage: R=IntegerModRing(11) - sage: P=R.addition_table(names='elements') + sage: R = IntegerModRing(11) + sage: P = R.addition_table(names='elements') sage: P + 0 1 2 3 4 5 6 7 8 9 10 +--------------------------------- @@ -310,7 +310,7 @@ def addition_table(self, names='letters', elements=None): 9| 9 10 0 1 2 3 4 5 6 7 8 10| 10 0 1 2 3 4 5 6 7 8 9 - sage: T=R.addition_table(names='digits') + sage: T = R.addition_table(names='digits') sage: T + 00 01 02 03 04 05 06 07 08 09 10 +--------------------------------- @@ -329,7 +329,7 @@ def addition_table(self, names='letters', elements=None): Specifying the elements in an alternative order can provide more insight into how the operation behaves. :: - sage: S=IntegerModRing(7) + sage: S = IntegerModRing(7) sage: elts = [0, 3, 6, 2, 5, 1, 4] sage: S.addition_table(elements=elts) + a b c d e f g @@ -350,7 +350,7 @@ def addition_table(self, names='letters', elements=None): the elements be represented with their usual string representation. :: - sage: T=IntegerModRing(12) + sage: T = IntegerModRing(12) sage: elts=[0, 3, 6, 9] sage: T.addition_table(names='elements', elements=elts) + 0 3 6 9 @@ -365,8 +365,8 @@ def addition_table(self, names='letters', elements=None): :class:`~sage.matrix.operation_table.OperationTable` for more comprehensive documentation. :: - sage: R=IntegerModRing(3) - sage: T=R.addition_table() + sage: R = IntegerModRing(3) + sage: T = R.addition_table() sage: T.column_keys() (0, 1, 2) sage: sorted(T.translation().items()) @@ -476,8 +476,8 @@ def _add_(self, right): (1, x) sage: e+e (2, 0) - sage: e=groups.misc.AdditiveCyclic(8) - sage: x=e.cartesian_product(e)((e(1),e(2))) + sage: e = groups.misc.AdditiveCyclic(8) + sage: x = e.cartesian_product(e)((e(1),e(2))) sage: x (1, 2) sage: 4*x diff --git a/src/sage/categories/algebras.py b/src/sage/categories/algebras.py index dc14daf4c08..253d64a2819 100644 --- a/src/sage/categories/algebras.py +++ b/src/sage/categories/algebras.py @@ -73,7 +73,7 @@ def __contains__(self, x): sage: QQ['x'] in Algebras(CDF) False """ - if super(Algebras, self).__contains__(x): + if super().__contains__(x): return True from sage.rings.ring import Algebra return isinstance(x, Algebra) and x.base_ring() == self.base_ring() diff --git a/src/sage/categories/cartesian_product.py b/src/sage/categories/cartesian_product.py index e2d415d6c74..33f5c5b9b02 100644 --- a/src/sage/categories/cartesian_product.py +++ b/src/sage/categories/cartesian_product.py @@ -188,9 +188,9 @@ def __call__(self, args, **kwds): from sage.sets.cartesian_product import CartesianProduct return CartesianProduct((), cat) elif self._forced_category is not None: - return super(CartesianProductFunctor, self).__call__(args, category=self._forced_category, **kwds) + return super().__call__(args, category=self._forced_category, **kwds) - return super(CartesianProductFunctor, self).__call__(args, **kwds) + return super().__call__(args, **kwds) def __eq__(self, other): r""" diff --git a/src/sage/categories/category.py b/src/sage/categories/category.py index a52b95dda00..09547c3b4c2 100644 --- a/src/sage/categories/category.py +++ b/src/sage/categories/category.py @@ -444,7 +444,7 @@ class of ``C`` is a dynamic subclass ``Cs_with_category`` of """ if isinstance(cls, DynamicMetaclass): cls = cls.__base__ - return super(Category, cls).__classcall__(cls, *args, **options) + return super().__classcall__(cls, *args, **options) def __init__(self, s=None): """ @@ -3257,7 +3257,7 @@ def _repr_(self, as_join = False): """ if not as_join: try: - return super(JoinCategory, self)._repr_() + return super()._repr_() except ValueError: pass return "Join of " + " and ".join(str(cat) for cat in self._super_categories) diff --git a/src/sage/categories/category_singleton.pyx b/src/sage/categories/category_singleton.pyx index 7c02aad63e3..1a5095e6017 100644 --- a/src/sage/categories/category_singleton.pyx +++ b/src/sage/categories/category_singleton.pyx @@ -320,7 +320,7 @@ class Category_singleton(Category): from sage.categories.category_with_axiom import CategoryWithAxiom_singleton assert (cls.__mro__[1] is Category_singleton or cls.__mro__[1] is CategoryWithAxiom_singleton), \ "{} is not a direct subclass of {}".format(cls, Category_singleton) - obj = super(Category_singleton, cls).__classcall__(cls, *args) + obj = super().__classcall__(cls, *args) cls._set_classcall(ConstantFunction(obj)) obj.__class__._set_classcall(ConstantFunction(obj)) return obj diff --git a/src/sage/categories/category_types.py b/src/sage/categories/category_types.py index 67bc36fc19a..4469a57a996 100644 --- a/src/sage/categories/category_types.py +++ b/src/sage/categories/category_types.py @@ -508,7 +508,7 @@ def __contains__(self, x): else: return x.base_ring() is self.base_ring() else: - return super(Category_over_base_ring, self).__contains__(x) + return super().__contains__(x) except AttributeError: return False @@ -592,12 +592,10 @@ def __contains__(self, x): sage: IntegerRing().zero_ideal() in C True """ - if super(Category_ideal, self).__contains__(x): + if super().__contains__(x): return True from sage.rings.ideal import is_Ideal - if is_Ideal(x) and x.ring() == self.ring(): - return True - return False + return is_Ideal(x) and x.ring() == self.ring() def __call__(self, v): """ diff --git a/src/sage/categories/category_with_axiom.py b/src/sage/categories/category_with_axiom.py index dd01c69a050..e9faa85ab57 100644 --- a/src/sage/categories/category_with_axiom.py +++ b/src/sage/categories/category_with_axiom.py @@ -1993,7 +1993,7 @@ def __classcall__(cls, *args, **options): """ (base_category_class, axiom) = cls._base_category_class_and_axiom if len(args) == 1 and not options and isinstance(args[0], base_category_class): - return super(CategoryWithAxiom, cls).__classcall__(cls, args[0]) + return super().__classcall__(cls, args[0]) else: # The "obvious" idiom ## return cls(base_category_class(*args, **options)) @@ -2352,7 +2352,7 @@ def __reduce__(self): additive magma is implemented as ``MagmasAndAdditiveMagmas.Distributive.AdditiveAssociative.AdditiveCommutative`` and not - ``MagmasAndAdditiveMagmas.Distributive.AdditiveCommutative.AdditiveAssociative``:: + ``MagmasAndAdditiveMagmas.Distributive.AdditiveCommutative.AdditiveAssociative``. EXAMPLES:: diff --git a/src/sage/categories/chain_complexes.py b/src/sage/categories/chain_complexes.py index 1cf64c011d7..531fc48e4cd 100644 --- a/src/sage/categories/chain_complexes.py +++ b/src/sage/categories/chain_complexes.py @@ -235,7 +235,7 @@ def _apply_functor_to_morphism(self, f): r""" Apply ``self`` to a chain map. - TESTS: + TESTS:: sage: E3 = EuclideanSpace(3) # optional - sage.symbolic sage: C = E3.de_rham_complex() # optional - sage.symbolic diff --git a/src/sage/categories/commutative_algebras.py b/src/sage/categories/commutative_algebras.py index 14ab0084d42..ec4037f9a84 100644 --- a/src/sage/categories/commutative_algebras.py +++ b/src/sage/categories/commutative_algebras.py @@ -56,5 +56,5 @@ def __contains__(self, A): TODO: get rid of this method once all commutative algebras in Sage declare themselves in this category """ - return super(CommutativeAlgebras, self).__contains__(A) or \ + return super().__contains__(A) or \ (A in Algebras(self.base_ring()) and hasattr(A, "is_commutative") and A.is_commutative()) diff --git a/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py b/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py index bb58d78cbde..497f29a433b 100644 --- a/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py +++ b/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py @@ -19,6 +19,7 @@ from sage.categories.category_with_axiom import CategoryWithAxiom from sage.categories.groups import Groups + class ComplexReflectionOrGeneralizedCoxeterGroups(Category_singleton): r""" The category of complex reflection groups or generalized Coxeter groups. @@ -402,9 +403,9 @@ def some_elements(self): """ return list(self.simple_reflections()) + [self.one(), self.an_element()] - ########################################################################## + ###################################################################### # Reflections - ########################################################################## + ###################################################################### @abstract_method(optional=True) def reflection_index_set(self): @@ -719,7 +720,7 @@ def from_reduced_word(self, word, word_type='simple'): TESTS:: - sage: W=WeylGroup(['E',6]) + sage: W = WeylGroup(['E',6]) sage: W.from_reduced_word([2,3,4,2]) [ 0 1 0 0 0 0 0 0] [ 0 0 -1 0 0 0 0 0] @@ -896,7 +897,7 @@ def apply_simple_reflection_right(self, i): EXAMPLES:: - sage: W=CoxeterGroups().example() + sage: W = CoxeterGroups().example() sage: w = W.an_element(); w (1, 2, 3, 0) sage: w.apply_simple_reflection_right(0) diff --git a/src/sage/categories/covariant_functorial_construction.py b/src/sage/categories/covariant_functorial_construction.py index b6389c69725..96dbf891bc9 100644 --- a/src/sage/categories/covariant_functorial_construction.py +++ b/src/sage/categories/covariant_functorial_construction.py @@ -315,7 +315,7 @@ def __classcall__(cls, category=None, *args): """ base_category_class = cls._base_category_class[0] if isinstance(category, base_category_class): - return super(FunctorialConstructionCategory, cls).__classcall__(cls, category, *args) + return super().__classcall__(cls, category, *args) else: return cls.category_of(base_category_class(category, *args)) @@ -435,7 +435,7 @@ def __init__(self, category, *args): assert isinstance(category, Category) self._base_category = category self._args = args - super(FunctorialConstructionCategory, self).__init__(*args) + super().__init__(*args) def base_category(self): """ @@ -684,4 +684,5 @@ def default_super_categories(cls, category, *args): sage: C.__class__.default_super_categories(C.base_category(), *C._args) Category of unital subquotients of semigroups """ - return Category.join([category, super(RegressiveCovariantConstructionCategory, cls).default_super_categories(category, *args)]) + return Category.join([category, + super().default_super_categories(category, *args)]) diff --git a/src/sage/categories/crystals.py b/src/sage/categories/crystals.py index d595a854ad2..68c2edd7a29 100644 --- a/src/sage/categories/crystals.py +++ b/src/sage/categories/crystals.py @@ -1977,7 +1977,7 @@ def __call__(self, x, *args, **kwds): """ if x is None: return None - return super(CrystalMorphism, self).__call__(x, *args, **kwds) + return super().__call__(x, *args, **kwds) def virtualization(self): r""" diff --git a/src/sage/categories/enumerated_sets.py b/src/sage/categories/enumerated_sets.py index 7b36a19c4bd..563a8025e6d 100644 --- a/src/sage/categories/enumerated_sets.py +++ b/src/sage/categories/enumerated_sets.py @@ -179,7 +179,7 @@ def __iter__(self): If none of these are provided, raise a ``NotImplementedError``. - EXAMPLES:: + EXAMPLES: We start with an example where nothing is implemented:: diff --git a/src/sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py b/src/sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py index 7f0fc4433c7..306e0091e12 100644 --- a/src/sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +++ b/src/sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py @@ -76,8 +76,7 @@ def __classcall_private__(cls, R, n=None, M=None, ambient=None): else: M = M.change_ring(R) n = M.dimension() - return super(AbelianLieAlgebra, cls).__classcall__(cls, R, n=n, M=M, - ambient=ambient) + return super().__classcall__(cls, R, n=n, M=M, ambient=ambient) def __init__(self, R, n=None, M=None, ambient=None): """ @@ -219,7 +218,7 @@ def is_ideal(self, A): False """ if not isinstance(A, AbelianLieAlgebra): - return super(AbelianLieAlgebra, self).is_ideal(A) + return super().is_ideal(A) if A == self or A == self._ambient: return True if self._ambient != A._ambient: diff --git a/src/sage/categories/examples/lie_algebras.py b/src/sage/categories/examples/lie_algebras.py index 1b435a5e4ee..cdde62e6760 100644 --- a/src/sage/categories/examples/lie_algebras.py +++ b/src/sage/categories/examples/lie_algebras.py @@ -75,7 +75,7 @@ def __classcall_private__(cls, gens): sage: L1 is L2 True """ - return super(LieAlgebraFromAssociative, cls).__classcall__(cls, tuple(gens)) + return super().__classcall__(cls, tuple(gens)) def __init__(self, gens): """ diff --git a/src/sage/categories/examples/sets_cat.py b/src/sage/categories/examples/sets_cat.py index 6cc88bc551b..a9e8933901d 100644 --- a/src/sage/categories/examples/sets_cat.py +++ b/src/sage/categories/examples/sets_cat.py @@ -390,7 +390,7 @@ def __init__(self): sage: type(P(2)+P(3)) """ - super(PrimeNumbers_Inherits, self).__init__() + super().__init__() self._populate_coercion_lists_(embedding=IntegerRing()) def __contains__(self, p): diff --git a/src/sage/categories/filtered_modules.py b/src/sage/categories/filtered_modules.py index 9a4b7d360d0..780ef974956 100644 --- a/src/sage/categories/filtered_modules.py +++ b/src/sage/categories/filtered_modules.py @@ -53,7 +53,7 @@ def __init__(self, base_category): sage: HopfAlgebrasWithBasis(QQ).Filtered().base_ring() Rational Field """ - super(FilteredModulesCategory, self).__init__(base_category, base_category.base_ring()) + super().__init__(base_category, base_category.base_ring()) _functor_category = "Filtered" diff --git a/src/sage/categories/filtered_modules_with_basis.py b/src/sage/categories/filtered_modules_with_basis.py index 61e492e1c11..bd75b8f8e8a 100644 --- a/src/sage/categories/filtered_modules_with_basis.py +++ b/src/sage/categories/filtered_modules_with_basis.py @@ -644,9 +644,9 @@ def is_homogeneous(self): EXAMPLES:: sage: A = ModulesWithBasis(ZZ).Filtered().example() - sage: x=A(Partition((3,2,1))) - sage: y=A(Partition((4,4,1))) - sage: z=A(Partition((2,2,2))) + sage: x = A(Partition((3,2,1))) + sage: y = A(Partition((4,4,1))) + sage: z = A(Partition((2,2,2))) sage: (3*x).is_homogeneous() True sage: (x - y).is_homogeneous() diff --git a/src/sage/categories/graded_modules.py b/src/sage/categories/graded_modules.py index 137c503c562..ff66b885913 100644 --- a/src/sage/categories/graded_modules.py +++ b/src/sage/categories/graded_modules.py @@ -42,7 +42,7 @@ def __init__(self, base_category): sage: GradedModules(ZZ) is Modules(ZZ).Graded() True """ - super(GradedModulesCategory, self).__init__(base_category, base_category.base_ring()) + super().__init__(base_category, base_category.base_ring()) _functor_category = "Graded" @@ -93,9 +93,10 @@ def default_super_categories(cls, category, *args): Join of Category of filtered algebras over Rational Field and Category of graded vector spaces over Rational Field """ - cat = super(GradedModulesCategory, cls).default_super_categories(category, *args) + cat = super().default_super_categories(category, *args) return Category.join([category.Filtered(), cat]) + class GradedModules(GradedModulesCategory): r""" The category of graded modules. diff --git a/src/sage/categories/group_algebras.py b/src/sage/categories/group_algebras.py index 0d7c42d22fe..0df6bf44165 100644 --- a/src/sage/categories/group_algebras.py +++ b/src/sage/categories/group_algebras.py @@ -265,9 +265,9 @@ def counit_on_basis(self,g): EXAMPLES:: - sage: A=CyclicPermutationGroup(6).algebra(ZZ);A + sage: A = CyclicPermutationGroup(6).algebra(ZZ);A Algebra of Cyclic group of order 6 as a permutation group over Integer Ring - sage: g=CyclicPermutationGroup(6).an_element();g + sage: g = CyclicPermutationGroup(6).an_element();g (1,2,3,4,5,6) sage: A.counit_on_basis(g) 1 diff --git a/src/sage/categories/groups.py b/src/sage/categories/groups.py index 2e1129fcbdb..809ef93e3e1 100644 --- a/src/sage/categories/groups.py +++ b/src/sage/categories/groups.py @@ -298,7 +298,7 @@ def cayley_table(self, names='letters', elements=None): you can choose to just use the string representations of the elements themselves. :: - sage: C=CyclicPermutationGroup(11) + sage: C = CyclicPermutationGroup(11) sage: C.cayley_table(names='digits') * 00 01 02 03 04 05 06 07 08 09 10 +--------------------------------- @@ -316,8 +316,8 @@ def cayley_table(self, names='letters', elements=None): :: - sage: G=QuaternionGroup() - sage: names=['1', 'I', '-1', '-I', 'J', '-K', '-J', 'K'] + sage: G = QuaternionGroup() + sage: names = ['1', 'I', '-1', '-I', 'J', '-K', '-J', 'K'] sage: G.cayley_table(names=names) * 1 I -1 -I J -K -J K +------------------------ @@ -332,7 +332,7 @@ def cayley_table(self, names='letters', elements=None): :: - sage: A=AbelianGroup([2,2]) + sage: A = AbelianGroup([2,2]) sage: A.cayley_table(names='elements') * 1 f1 f0 f0*f1 +------------------------ @@ -345,8 +345,8 @@ def cayley_table(self, names='letters', elements=None): routine behaves similarly, but changes an existing table "in-place." :: - sage: G=AlternatingGroup(3) - sage: T=G.cayley_table() + sage: G = AlternatingGroup(3) + sage: T = G.cayley_table() sage: T.change_names('digits') sage: T * 0 1 2 @@ -360,7 +360,7 @@ def cayley_table(self, names='letters', elements=None): Elements will be coerced into the group as part of setting up the table. :: - sage: G=SL(2,ZZ) + sage: G = SL(2,ZZ) sage: G Special Linear Group of degree 2 over Integer Ring sage: identity = matrix(ZZ, [[1,0], [0,1]]) diff --git a/src/sage/categories/isomorphic_objects.py b/src/sage/categories/isomorphic_objects.py index fe3569cd3cd..f1473997c14 100644 --- a/src/sage/categories/isomorphic_objects.py +++ b/src/sage/categories/isomorphic_objects.py @@ -68,4 +68,4 @@ def default_super_categories(cls, category): Category of isomorphic objects of sets """ return Category.join([category.Subobjects(), category.Quotients(), - super(IsomorphicObjectsCategory, cls).default_super_categories(category)]) + super().default_super_categories(category)]) diff --git a/src/sage/categories/lambda_bracket_algebras.py b/src/sage/categories/lambda_bracket_algebras.py index c0f8a00c661..531cfb826b1 100644 --- a/src/sage/categories/lambda_bracket_algebras.py +++ b/src/sage/categories/lambda_bracket_algebras.py @@ -54,7 +54,7 @@ def __classcall_private__(cls, R, check=True): if check: if not (R in _CommutativeRings): raise ValueError("base must be a commutative ring got {}".format(R)) - return super(LambdaBracketAlgebras, cls).__classcall__(cls, R) + return super().__classcall__(cls, R) @cached_method def super_categories(self): diff --git a/src/sage/categories/magmas.py b/src/sage/categories/magmas.py index e00ebb91353..c4a35fe6f1a 100644 --- a/src/sage/categories/magmas.py +++ b/src/sage/categories/magmas.py @@ -931,7 +931,7 @@ def multiplication_table(self, names='letters', elements=None): the elements be represented with their usual string representation. :: - sage: L=LeftRegularBand(('a','b','c')) + sage: L = LeftRegularBand(('a','b','c')) sage: elts=['a', 'c', 'ac', 'ca'] sage: L.multiplication_table(names='elements', elements=elts) * 'a' 'c' 'ac' 'ca' @@ -946,8 +946,8 @@ def multiplication_table(self, names='letters', elements=None): :class:`~sage.matrix.operation_table.OperationTable` for more comprehensive documentation. :: - sage: G=AlternatingGroup(3) - sage: T=G.multiplication_table() + sage: G = AlternatingGroup(3) + sage: T = G.multiplication_table() sage: T.column_keys() ((), (1,2,3), (1,3,2)) sage: T.translation() diff --git a/src/sage/categories/metric_spaces.py b/src/sage/categories/metric_spaces.py index 0791c95d29c..6608ca7d4e5 100644 --- a/src/sage/categories/metric_spaces.py +++ b/src/sage/categories/metric_spaces.py @@ -60,7 +60,7 @@ def default_super_categories(cls, category): Join of Category of topological groups and Category of metric spaces """ return Category.join([category.Topological(), - super(MetricSpacesCategory, cls).default_super_categories(category)]) + super().default_super_categories(category)]) # We currently don't have a use for this, but we probably will def _repr_object_names(self): diff --git a/src/sage/categories/modules.py b/src/sage/categories/modules.py index 2dafd6ec4ee..d37b4812209 100644 --- a/src/sage/categories/modules.py +++ b/src/sage/categories/modules.py @@ -152,7 +152,7 @@ def __classcall_private__(cls, base_ring, dispatch=True): and base_ring.is_subcategory(_Fields)): from .vector_spaces import VectorSpaces return VectorSpaces(base_ring, check=False) - result = super(Modules, cls).__classcall__(cls, base_ring) + result = super().__classcall__(cls, base_ring) result._reduction[2]['dispatch'] = False return result diff --git a/src/sage/categories/modules_with_basis.py b/src/sage/categories/modules_with_basis.py index e616ce19241..49d91c17049 100644 --- a/src/sage/categories/modules_with_basis.py +++ b/src/sage/categories/modules_with_basis.py @@ -2166,7 +2166,7 @@ def __call_on_basis__(self, **options): sage: phi(x[1] + x[2] + x[3]) B[1] + 4*B[2] + 9*B[3] - TESTS:: + TESTS: As for usual homsets, the argument can be a Python function:: diff --git a/src/sage/categories/primer.py b/src/sage/categories/primer.py index f49c7e5396f..1663a30d9ab 100644 --- a/src/sage/categories/primer.py +++ b/src/sage/categories/primer.py @@ -80,8 +80,8 @@ sage: GL(2,2).cardinality() 6 - sage: A=random_matrix(ZZ,6,3,x=7) - sage: L=LatticePolytope(A.rows()) + sage: A = random_matrix(ZZ,6,3,x=7) + sage: L = LatticePolytope(A.rows()) sage: L.npoints() # oops! # random 37 @@ -97,7 +97,7 @@ :: - sage: m=random_matrix(QQ, 4, algorithm='echelonizable', rank=3, upper_bound=60) + sage: m = random_matrix(QQ, 4, algorithm='echelonizable', rank=3, upper_bound=60) sage: m^8 == m*m*m*m*m*m*m*m == ((m^2)^2)^2 True diff --git a/src/sage/categories/pushout.py b/src/sage/categories/pushout.py index 5fbc590fb8e..c48ec6ec672 100644 --- a/src/sage/categories/pushout.py +++ b/src/sage/categories/pushout.py @@ -3800,10 +3800,10 @@ def pushout(R, S): sage: from sage.categories.pushout import ConstructionFunctor sage: class EvenPolynomialRing(type(QQ['x'])): ....: def __init__(self, base, var): - ....: super(EvenPolynomialRing, self).__init__(base, var) + ....: super().__init__(base, var) ....: self.register_embedding(base[var]) ....: def __repr__(self): - ....: return "Even Power " + super(EvenPolynomialRing, self).__repr__() + ....: return "Even Power " + super().__repr__() ....: def construction(self): ....: return EvenPolynomialFunctor(), self.base()[self.variable_name()] ....: def _coerce_map_from_(self, R): @@ -3857,7 +3857,7 @@ def pushout(R, S): ....: self.coefficients = coefficients ....: self.var = var ....: self.exponents = exponents - ....: super(GPolynomialRing, self).__init__(category=Rings()) + ....: super().__init__(category=Rings()) ....: def _repr_(self): ....: return 'Generalized Polynomial Ring in %s^(%s) over %s' % ( ....: self.var, self.exponents, self.coefficients) @@ -3979,7 +3979,7 @@ def pushout(R, S): sage: class CartesianProductPoly(CartesianProduct): ....: def __init__(self, polynomial_rings): ....: sort = sorted(polynomial_rings, key=lambda P: P.variable_name()) - ....: super(CartesianProductPoly, self).__init__(sort, Sets().CartesianProducts()) + ....: super().__init__(sort, Sets().CartesianProducts()) ....: def vars(self): ....: return tuple(P.variable_name() for P in self.cartesian_factors()) ....: def _pushout_(self, other): diff --git a/src/sage/categories/quotient_fields.py b/src/sage/categories/quotient_fields.py index 033c1499d05..5e4cf0c7edc 100644 --- a/src/sage/categories/quotient_fields.py +++ b/src/sage/categories/quotient_fields.py @@ -518,15 +518,15 @@ def partial_fraction_decomposition(self, decompose_powers=True): This was fixed in :trac:`16240`:: sage: R. = QQ['x'] - sage: p=1/(-x + 1) + sage: p = 1/(-x + 1) sage: whole,parts = p.partial_fraction_decomposition() sage: p == sum(parts) True - sage: p=3/(-x^4 + 1) + sage: p = 3/(-x^4 + 1) sage: whole,parts = p.partial_fraction_decomposition() sage: p == sum(parts) True - sage: p=(6*x^2 - 9*x + 5)/(-x^3 + 3*x^2 - 3*x + 1) + sage: p = (6*x^2 - 9*x + 5)/(-x^3 + 3*x^2 - 3*x + 1) sage: whole,parts = p.partial_fraction_decomposition() sage: p == sum(parts) True diff --git a/src/sage/categories/quotients.py b/src/sage/categories/quotients.py index d444c7455e9..bda06208d80 100644 --- a/src/sage/categories/quotients.py +++ b/src/sage/categories/quotients.py @@ -59,4 +59,4 @@ def default_super_categories(cls, category): sage: sage.categories.quotients.QuotientsCategory.default_super_categories(Groups()) Join of Category of groups and Category of subquotients of monoids and Category of quotients of semigroups """ - return Category.join([category.Subquotients(), super(QuotientsCategory, cls).default_super_categories(category)]) + return Category.join([category.Subquotients(), super().default_super_categories(category)]) diff --git a/src/sage/categories/regular_crystals.py b/src/sage/categories/regular_crystals.py index ead1a1dc198..739a5ecc598 100644 --- a/src/sage/categories/regular_crystals.py +++ b/src/sage/categories/regular_crystals.py @@ -299,7 +299,7 @@ def _test_stembridge_local_axioms(self, index_set=None, verbose=False, complete= sage: T._test_stembridge_local_axioms(index_set=[1,3]) True - sage: B=Crystals().example(choice='naive') + sage: B = Crystals().example(choice='naive') sage: B._test_stembridge_local_axioms() Traceback (most recent call last): ... @@ -597,10 +597,10 @@ def stembridgeDelta_depth(self,i,j): EXAMPLES:: sage: T = crystals.Tableaux(['A',2], shape=[2,1]) - sage: t=T(rows=[[1,2],[2]]) + sage: t = T(rows=[[1,2],[2]]) sage: t.stembridgeDelta_depth(1,2) 0 - sage: s=T(rows=[[2,3],[3]]) + sage: s = T(rows=[[2,3],[3]]) sage: s.stembridgeDelta_depth(1,2) -1 """ @@ -620,10 +620,10 @@ def stembridgeDelta_rise(self,i,j): EXAMPLES:: sage: T = crystals.Tableaux(['A',2], shape=[2,1]) - sage: t=T(rows=[[1,2],[2]]) + sage: t = T(rows=[[1,2],[2]]) sage: t.stembridgeDelta_rise(1,2) -1 - sage: s=T(rows=[[2,3],[3]]) + sage: s = T(rows=[[2,3],[3]]) sage: s.stembridgeDelta_rise(1,2) 0 """ @@ -643,10 +643,10 @@ def stembridgeDel_depth(self,i,j): EXAMPLES:: sage: T = crystals.Tableaux(['A',2], shape=[2,1]) - sage: t=T(rows=[[1,1],[2]]) + sage: t = T(rows=[[1,1],[2]]) sage: t.stembridgeDel_depth(1,2) 0 - sage: s=T(rows=[[1,3],[3]]) + sage: s = T(rows=[[1,3],[3]]) sage: s.stembridgeDel_depth(1,2) -1 """ @@ -666,10 +666,10 @@ def stembridgeDel_rise(self,i,j): EXAMPLES:: sage: T = crystals.Tableaux(['A',2], shape=[2,1]) - sage: t=T(rows=[[1,1],[2]]) + sage: t = T(rows=[[1,1],[2]]) sage: t.stembridgeDel_rise(1,2) -1 - sage: s=T(rows=[[1,3],[3]]) + sage: s = T(rows=[[1,3],[3]]) sage: s.stembridgeDel_rise(1,2) 0 """ @@ -692,20 +692,20 @@ def stembridgeTriple(self,i,j): EXAMPLES:: sage: T = crystals.Tableaux(['A',2], shape=[2,1]) - sage: t=T(rows=[[1,1],[2]]) + sage: t = T(rows=[[1,1],[2]]) sage: t.stembridgeTriple(1,2) - sage: s=T(rows=[[1,2],[2]]) + sage: s = T(rows=[[1,2],[2]]) sage: s.stembridgeTriple(1,2) (-1, 0, -1) sage: T = crystals.Tableaux(['B',2], shape=[2,1]) - sage: t=T(rows=[[1,2],[2]]) + sage: t = T(rows=[[1,2],[2]]) sage: t.stembridgeTriple(1,2) (-2, 0, -2) - sage: s=T(rows=[[-1,-1],[0]]) + sage: s = T(rows=[[-1,-1],[0]]) sage: s.stembridgeTriple(1,2) (-2, -2, 0) - sage: u=T(rows=[[0,2],[1]]) + sage: u = T(rows=[[0,2],[1]]) sage: u.stembridgeTriple(1,2) (-2, -1, -1) """ @@ -739,7 +739,7 @@ def _test_stembridge_local_axioms(self, index_set=None, verbose=False, **options EXAMPLES:: sage: T = crystals.Tableaux(['A',2], shape=[2,1]) - sage: t=T(rows=[[1,1],[2]]) + sage: t = T(rows=[[1,1],[2]]) sage: t._test_stembridge_local_axioms() True sage: t._test_stembridge_local_axioms(index_set=[1,3]) @@ -748,7 +748,7 @@ def _test_stembridge_local_axioms(self, index_set=None, verbose=False, **options True """ tester = self._tester(**options) - goodness=True + goodness = True if index_set is None: index_set=self.index_set() diff --git a/src/sage/categories/schemes.py b/src/sage/categories/schemes.py index 73eef1d15d4..45ef3943239 100644 --- a/src/sage/categories/schemes.py +++ b/src/sage/categories/schemes.py @@ -72,8 +72,7 @@ def __classcall_private__(cls, X = None): if not is_Scheme(X): X = Schemes()(X) return Schemes_over_base(X) - else: - return super(Schemes, cls).__classcall__(cls) + return super().__classcall__(cls) def super_categories(self): """ diff --git a/src/sage/categories/semigroups.py b/src/sage/categories/semigroups.py index b3e33ca5a51..0ff287386b3 100644 --- a/src/sage/categories/semigroups.py +++ b/src/sage/categories/semigroups.py @@ -217,7 +217,7 @@ def cayley_graph(self, side="right", simple=False, elements = None, generators = sage: G = A5.cayley_graph(generators=[A5.gens()[0]]) sage: G.num_edges() 60 - sage: g=PermutationGroup([(i+1,j+1) for i in range(5) for j in range(5) if j!=i]) + sage: g = PermutationGroup([(i+1,j+1) for i in range(5) for j in range(5) if j!=i]) sage: g.cayley_graph(generators=[(1,2),(2,3)]) Digraph on 120 vertices diff --git a/src/sage/categories/sets_cat.py b/src/sage/categories/sets_cat.py index ea95ab2e527..09a57770a3b 100644 --- a/src/sage/categories/sets_cat.py +++ b/src/sage/categories/sets_cat.py @@ -1471,10 +1471,10 @@ def construction(self): def _test_construction(self, **options): """ - Test that the construction returned by self really yields self. + Test that the construction returned by ``self`` really yields ``self``. - :meth:`construction` either returns None or a pair ``(F,O)``, - and if it returns the latter, then it is supposed that ``F(O)==self`. + :meth:`construction` either returns None or a pair ``(F, O)``, + and if it returns the latter, then it is supposed that ``F(O) == self``. The test verifies this assumption. EXAMPLES: diff --git a/src/sage/categories/subobjects.py b/src/sage/categories/subobjects.py index c8eef3852cb..53ad660d75a 100644 --- a/src/sage/categories/subobjects.py +++ b/src/sage/categories/subobjects.py @@ -59,4 +59,4 @@ def default_super_categories(cls, category): sage: sage.categories.subobjects.SubobjectsCategory.default_super_categories(Groups()) Join of Category of groups and Category of subquotients of monoids and Category of subobjects of sets """ - return Category.join([category.Subquotients(), super(SubobjectsCategory, cls).default_super_categories(category)]) + return Category.join([category.Subquotients(), super().default_super_categories(category)]) diff --git a/src/sage/categories/super_modules.py b/src/sage/categories/super_modules.py index 5eb8db949bc..091b808408e 100644 --- a/src/sage/categories/super_modules.py +++ b/src/sage/categories/super_modules.py @@ -49,7 +49,7 @@ def default_super_categories(cls, category, *args): Category of finite dimensional super hopf algebras with basis over Integer Ring """ axioms = axiom_whitelist.intersection(category.axioms()) - C = super(SuperModulesCategory, cls).default_super_categories(category, *args) + C = super().default_super_categories(category, *args) return C._with_axioms(axioms) def __init__(self, base_category): @@ -70,7 +70,7 @@ def __init__(self, base_category): sage: HopfAlgebrasWithBasis(QQ).Super().base_ring() Rational Field """ - super(SuperModulesCategory, self).__init__(base_category, base_category.base_ring()) + super().__init__(base_category, base_category.base_ring()) _functor_category = "Super" diff --git a/src/sage/categories/vector_spaces.py b/src/sage/categories/vector_spaces.py index 2f70c93bc61..7568c705326 100644 --- a/src/sage/categories/vector_spaces.py +++ b/src/sage/categories/vector_spaces.py @@ -67,7 +67,7 @@ def __classcall_private__(cls, K, check=True): (isinstance(K, Category) and K.is_subcategory(_Fields))): raise ValueError("base must be a field or a subcategory of Fields();" + " got {}".format(K)) - return super(VectorSpaces, cls).__classcall__(cls, K) + return super().__classcall__(cls, K) def __init__(self, K): """ diff --git a/src/sage/categories/weyl_groups.py b/src/sage/categories/weyl_groups.py index 79cba3cf8b1..0c5e6ba6416 100644 --- a/src/sage/categories/weyl_groups.py +++ b/src/sage/categories/weyl_groups.py @@ -574,11 +574,11 @@ def stanley_symmetric_function(self): @cached_in_parent_method def reflection_to_root(self): r""" - Returns the root associated with the reflection ``self``. + Return the root associated with the reflection ``self``. EXAMPLES:: - sage: W=WeylGroup(['C',2],prefix="s") + sage: W = WeylGroup(['C',2],prefix="s") sage: W.from_reduced_word([1,2,1]).reflection_to_root() 2*alpha[1] + alpha[2] sage: W.from_reduced_word([1,2]).reflection_to_root() @@ -590,7 +590,6 @@ def reflection_to_root(self): ... ValueError: s2*s1*s2*s1 is not a reflection """ - i = self.first_descent() if i is None: raise ValueError("{} is not a reflection".format(self)) @@ -604,11 +603,11 @@ def reflection_to_root(self): @cached_in_parent_method def reflection_to_coroot(self): r""" - Returns the coroot associated with the reflection ``self``. + Return the coroot associated with the reflection ``self``. EXAMPLES:: - sage: W=WeylGroup(['C',2],prefix="s") + sage: W = WeylGroup(['C',2],prefix="s") sage: W.from_reduced_word([1,2,1]).reflection_to_coroot() alphacheck[1] + alphacheck[2] sage: W.from_reduced_word([1,2]).reflection_to_coroot() @@ -620,7 +619,6 @@ def reflection_to_coroot(self): ... ValueError: s2*s1*s2*s1 is not a reflection """ - i = self.first_descent() if i is None: raise ValueError("{} is not a reflection".format(self)) @@ -650,8 +648,8 @@ def inversions(self, side = 'right', inversion_type = 'reflections'): EXAMPLES:: - sage: W=WeylGroup(['C',2], prefix="s") - sage: w=W.from_reduced_word([1,2]) + sage: W = WeylGroup(['C',2], prefix="s") + sage: w = W.from_reduced_word([1,2]) sage: w.inversions() [s2, s2*s1*s2] sage: w.inversions(inversion_type = 'reflections') @@ -666,9 +664,7 @@ def inversions(self, side = 'right', inversion_type = 'reflections'): [alpha[1], 2*alpha[1] + alpha[2]] sage: w.inversions(side = 'left', inversion_type = 'coroots') [alphacheck[1], alphacheck[1] + alphacheck[2]] - """ - if side == 'left': self = self.inverse() reflections = self.inversions_as_reflections() @@ -678,7 +674,7 @@ def inversions(self, side = 'right', inversion_type = 'reflections'): return [r.reflection_to_root() for r in reflections] if inversion_type == 'coroots': return [r.reflection_to_coroot() for r in reflections] - raise ValueError("inversion_type {} is invalid".format(inversion_type)) + raise ValueError(f"inversion_type {inversion_type} is invalid") def inversion_arrangement(self, side='right'): r""" diff --git a/src/sage/coding/delsarte_bounds.py b/src/sage/coding/delsarte_bounds.py index f2c7ae86f26..15d5ade7887 100644 --- a/src/sage/coding/delsarte_bounds.py +++ b/src/sage/coding/delsarte_bounds.py @@ -678,29 +678,29 @@ def delsarte_bound_Q_matrix(q, d, return_data=False, solver="PPL", isinteger=Fal (ILP), rather that an LP solver. Can be very slow if set to ``True``. - EXAMPLES: + EXAMPLES: - The bound on dimension of linear `F_2`-codes of length 10 and minimal distance 6:: + The bound on dimension of linear `F_2`-codes of length 10 and minimal distance 6:: - sage: q_matrix = Matrix([[codes.bounds.krawtchouk(10,2,i,j) for i in range(11)] for j in range(11)]) - sage: codes.bounds.delsarte_bound_Q_matrix(q_matrix, 6) - 2 + sage: q_matrix = Matrix([[codes.bounds.krawtchouk(10,2,i,j) for i in range(11)] for j in range(11)]) + sage: codes.bounds.delsarte_bound_Q_matrix(q_matrix, 6) + 2 - sage: a,p,val = codes.bounds.delsarte_bound_Q_matrix(q_matrix, 6, return_data=True) - sage: [j for i,j in p.get_values(a).items()] - [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] + sage: a,p,val = codes.bounds.delsarte_bound_Q_matrix(q_matrix, 6, return_data=True) + sage: [j for i,j in p.get_values(a).items()] + [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] - TESTS: + TESTS: - cases for using Hamming scheme Q matrix:: + Cases for using Hamming scheme Q matrix:: - sage: q_matrix = Matrix([[codes.bounds.krawtchouk(10,2,i,j) for i in range(11)] for j in range(11)]) - sage: codes.bounds.delsarte_bound_Q_matrix(q_matrix, 6) - 2 + sage: q_matrix = Matrix([[codes.bounds.krawtchouk(10,2,i,j) for i in range(11)] for j in range(11)]) + sage: codes.bounds.delsarte_bound_Q_matrix(q_matrix, 6) + 2 - sage: a,p,val = codes.bounds.delsarte_bound_Q_matrix(q_matrix, 6, return_data=True) - sage: [j for i,j in p.get_values(a).items()] - [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] + sage: a,p,val = codes.bounds.delsarte_bound_Q_matrix(q_matrix, 6, return_data=True) + sage: [j for i,j in p.get_values(a).items()] + [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] """ diff --git a/src/sage/coding/gabidulin_code.py b/src/sage/coding/gabidulin_code.py index 353f76c6ee4..dc1c319dc62 100644 --- a/src/sage/coding/gabidulin_code.py +++ b/src/sage/coding/gabidulin_code.py @@ -45,13 +45,13 @@ class GabidulinCode(AbstractLinearRankMetricCode): EXAMPLES: - A Gabidulin Code can be constructed in the following way: + A Gabidulin Code can be constructed in the following way:: - sage: Fqm = GF(16) - sage: Fq = GF(4) - sage: C = codes.GabidulinCode(Fqm, 2, 2, Fq) - sage: C - [2, 2, 1] linear Gabidulin code over GF(16)/GF(4) + sage: Fqm = GF(16) + sage: Fq = GF(4) + sage: C = codes.GabidulinCode(Fqm, 2, 2, Fq) + sage: C + [2, 2, 1] linear Gabidulin code over GF(16)/GF(4) """ _registered_encoders = {} _registered_decoders = {} @@ -113,7 +113,7 @@ def __init__(self, base_field, length, dimension, sub_field=None, ValueError: 'length' can be at most the degree of the extension, 3 If the number of evaluation points is not equal to the length - of the code, an error is raised: + of the code, an error is raised:: sage: Fqm = GF(5^20) sage: Fq = GF(5) @@ -125,7 +125,7 @@ def __init__(self, base_field, length, dimension, sub_field=None, ValueError: the number of evaluation points should be equal to the length of the code If evaluation points are not linearly independent over the ``base_field``, - an error is raised: + an error is raised:: sage: evals = [ aa*i for i in range(2) ] sage: C = codes.GabidulinCode(Fqm, 2, 2, Fq, None, evals) @@ -134,7 +134,7 @@ def __init__(self, base_field, length, dimension, sub_field=None, ValueError: the evaluation points provided are not linearly independent If an evaluation point does not belong to the ``base_field``, an error - is raised: + is raised:: sage: a = GF(3).gen() sage: evals = [ a*i for i in range(2) ] @@ -146,7 +146,7 @@ def __init__(self, base_field, length, dimension, sub_field=None, Given that both ``sub_field`` and ``twisting_homomorphism`` are specified and ``twisting_homomorphism`` has a fixed field method. If the fixed field of ``twisting_homomorphism`` is not ``sub_field``, an error is - raised: + raised:: sage: Fqm = GF(64) sage: Fq = GF(8) @@ -158,7 +158,7 @@ def __init__(self, base_field, length, dimension, sub_field=None, If ``twisting_homomorphism`` is given, but ``sub_field`` is not. In case ``twisting_homomorphism`` does not have a fixed field method, and error - is raised: + is raised:: sage: Fqm. = GF(64) sage: sigma = Hom(Fqm, Fqm)[1]; sigma @@ -417,7 +417,7 @@ def __init__(self, code): TESTS: - If the code is not a Gabidulin code, an error is raised: + If the code is not a Gabidulin code, an error is raised:: sage: C = codes.HammingCode(GF(4), 2) sage: E = codes.encoders.GabidulinVectorEvaluationEncoder(C) @@ -433,7 +433,7 @@ def _repr_(self): """ Return a string representation of ``self``. - EXAMPLES: + EXAMPLES:: sage: Fqm = GF(5^20) sage: Fq = GF(5^4) @@ -447,7 +447,7 @@ def _latex_(self): r""" Return a latex representation of ``self``. - EXAMPLES: + EXAMPLES:: sage: Fqm = GF(5^20) sage: Fq = GF(5^4) @@ -571,7 +571,7 @@ def __init__(self, code): TESTS: - If the code is not a Gabidulin code, an error is raised: + If the code is not a Gabidulin code, an error is raised:: sage: C = codes.HammingCode(GF(4), 2) sage: E = codes.encoders.GabidulinPolynomialEvaluationEncoder(C) @@ -587,7 +587,7 @@ def _repr_(self): """ Return a string representation of ``self``. - EXAMPLES: + EXAMPLES:: sage: Fqm = GF(5^20) sage: Fq = GF(5^4) @@ -601,7 +601,7 @@ def _latex_(self): r""" Return a latex representation of ``self``. - EXAMPLES: + EXAMPLES:: sage: Fqm = GF(5^20) sage: Fq = GF(5^4) @@ -648,7 +648,7 @@ def message_space(self): r""" Return the message space of the associated code of ``self``. - EXAMPLES: + EXAMPLES:: sage: Fqm = GF(5^20) sage: Fq = GF(5^4) @@ -680,7 +680,7 @@ def encode(self, p, form="vector"): - a codeword corresponding to `p` in vector or matrix form - EXAMPLES: + EXAMPLES:: sage: Fqm = GF(2^9) sage: Fq = GF(2^3) @@ -749,7 +749,7 @@ def unencode_nocheck(self, c): - a skew polynomial of degree less than ``self.code().dimension()`` - EXAMPLES: + EXAMPLES:: sage: Fqm = GF(2^9) sage: Fq = GF(2^3) @@ -800,7 +800,7 @@ def __init__(self, code): TESTS: - If the code is not a Gabidulin code, an error is raised: + If the code is not a Gabidulin code, an error is raised:: sage: C = codes.HammingCode(GF(4), 2) sage: D = codes.decoders.GabidulinGaoDecoder(C) @@ -816,7 +816,7 @@ def _repr_(self): """ Return a string representation of ``self``. - EXAMPLES: + EXAMPLES:: sage: Fqm = GF(5^20) sage: Fq = GF(5^4) @@ -830,7 +830,7 @@ def _latex_(self): r""" Return a latex representation of ``self``. - EXAMPLES: + EXAMPLES:: sage: Fqm = GF(5^20) sage: Fq = GF(5^4) @@ -894,7 +894,7 @@ def _partial_xgcd(self, a, b, d_stop): - ``u_c`` -- right linearized quotient of `a` and `b` - EXAMPLES: + EXAMPLES:: sage: Fqm = GF(2^9) sage: Fq = GF(2^3) @@ -942,7 +942,7 @@ def _decode_to_code_and_message(self, r): - the decoded codeword and decoded message corresponding to the received codeword `r` - EXAMPLES: + EXAMPLES:: sage: Fqm = GF(2^9) sage: Fq = GF(2^3) @@ -993,7 +993,7 @@ def decode_to_code(self, r): - the decoded codeword corresponding to the received codeword - EXAMPLES: + EXAMPLES:: sage: Fqm = GF(3^20) sage: Fq = GF(3) @@ -1026,7 +1026,7 @@ def decode_to_message(self, r): - the message corresponding to the received codeword - EXAMPLES: + EXAMPLES:: sage: Fqm = GF(2^9) sage: Fq = GF(2^3) @@ -1047,7 +1047,7 @@ def decoding_radius(self): """ Return the decoding radius of the Gabidulin Gao Decoder. - EXAMPLES: + EXAMPLES:: sage: Fqm = GF(5^20) sage: Fq = GF(5) diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index cfd84e86e5c..3fe439bb848 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -2274,9 +2274,10 @@ def __init__(self, generator, d=None): sage: C.minimum_distance() 3 - We can construct a linear code directly from a vector space - sage: VS = matrix(GF(2), [[1,0,1],\ - [1,0,1]]).row_space() + We can construct a linear code directly from a vector space:: + + sage: VS = matrix(GF(2), [[1,0,1], + ....: [1,0,1]]).row_space() sage: C = LinearCode(VS); C [3, 1] linear code over GF(2) diff --git a/src/sage/combinat/abstract_tree.py b/src/sage/combinat/abstract_tree.py index 5d0caa16a48..3054ef00995 100644 --- a/src/sage/combinat/abstract_tree.py +++ b/src/sage/combinat/abstract_tree.py @@ -2085,7 +2085,7 @@ def __init__(self, parent, children, label=None, check=True): """ # We must initialize the label before the subtrees to allows rooted # trees canonization. Indeed it needs that ``self``._hash_() is working - # at the end of the call super(..., self).__init__(...) + # at the end of the call super().__init__(...) if isinstance(children, AbstractLabelledTree): if label is None: self._label = children._label @@ -2093,7 +2093,7 @@ def __init__(self, parent, children, label=None, check=True): self._label = label else: self._label = label - super(AbstractLabelledTree, self).__init__(parent, children, check=check) + super().__init__(parent, children, check=check) def _repr_(self): """ @@ -2211,8 +2211,7 @@ def __eq__(self, other): sage: t1 == t2 False """ - return (super(AbstractLabelledTree, self).__eq__(other) and - self._label == other._label) + return super().__eq__(other) and self._label == other._label def _hash_(self): """ diff --git a/src/sage/combinat/alternating_sign_matrix.py b/src/sage/combinat/alternating_sign_matrix.py index 146ff0cdfce..c7c7317811c 100644 --- a/src/sage/combinat/alternating_sign_matrix.py +++ b/src/sage/combinat/alternating_sign_matrix.py @@ -313,7 +313,7 @@ def inversion_number(self): sage: asm = A([[0, 1, 0],[1, -1, 1],[0, 1, 0]]) sage: asm.inversion_number() 2 - sage: P=Permutations(5) + sage: P = Permutations(5) sage: all(p.number_of_inversions()==AlternatingSignMatrix(p.to_matrix()).inversion_number() for p in P) True """ diff --git a/src/sage/combinat/baxter_permutations.py b/src/sage/combinat/baxter_permutations.py index 0e3c722f480..382e4abcdab 100644 --- a/src/sage/combinat/baxter_permutations.py +++ b/src/sage/combinat/baxter_permutations.py @@ -81,7 +81,7 @@ def __init__(self, n): self.element_class = Permutations(n).element_class self._n = ZZ(n) from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets - super(BaxterPermutations_size, self).__init__(category=FiniteEnumeratedSets()) + super().__init__(category=FiniteEnumeratedSets()) def _repr_(self): """ diff --git a/src/sage/combinat/blob_algebra.py b/src/sage/combinat/blob_algebra.py index 3731b8c973e..5da88de497f 100644 --- a/src/sage/combinat/blob_algebra.py +++ b/src/sage/combinat/blob_algebra.py @@ -429,7 +429,7 @@ def __classcall_private__(cls, k, q1, q2, q3, base_ring=None, prefix='B'): q1 = base_ring(q1) q2 = base_ring(q2) q3 = base_ring(q3) - return super(BlobAlgebra, cls).__classcall__(cls, k, q1, q2, q3, base_ring, prefix) + return super().__classcall__(cls, k, q1, q2, q3, base_ring, prefix) def __init__(self, k, q1, q2, q3, base_ring, prefix): r""" diff --git a/src/sage/combinat/chas/fsym.py b/src/sage/combinat/chas/fsym.py index d618f44d3fd..a2dfd12f621 100644 --- a/src/sage/combinat/chas/fsym.py +++ b/src/sage/combinat/chas/fsym.py @@ -158,7 +158,7 @@ def coerce_base_ring(self, x): # Otherwise lift that basis up and then coerce over target = getattr(FSym, R._realization_name())() return self._coerce_map_via([target], R) - return super(FSymBasis_abstract, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) def some_elements(self): r""" @@ -633,7 +633,7 @@ def R_to_G_on_basis(alpha): if descent_composition(t) == alpha) return ribbon.module_morphism(R_to_G_on_basis, codomain=self) return self._coerce_map_via([ribbon], R) - return super(FreeSymmetricFunctions.Fundamental, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) def dual_basis(self): r""" @@ -963,7 +963,7 @@ def s_to_F_on_basis(mu): return self.sum_of_monomials(StandardTableaux(mu)) return s.module_morphism(s_to_F_on_basis, codomain=self) return self._coerce_map_via([s], R) - return super(FreeSymmetricFunctions_Dual.FundamentalDual, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) def dual_basis(self): r""" diff --git a/src/sage/combinat/chas/wqsym.py b/src/sage/combinat/chas/wqsym.py index 8a8ee533e8e..238d0281030 100644 --- a/src/sage/combinat/chas/wqsym.py +++ b/src/sage/combinat/chas/wqsym.py @@ -233,7 +233,7 @@ def coerce_base_ring(self, x): # Otherwise lift that basis up and then coerce over target = getattr(self.realization_of(), R._basis_name)() return self._coerce_map_via([target], R) - return super(WQSymBasis_abstract, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) @cached_method def an_element(self): diff --git a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py index c49673b8342..440be02ffdd 100644 --- a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py +++ b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py @@ -2384,7 +2384,7 @@ def mutate(self, sequence, inplace=True, input_type=None): sage: S.cluster() [(b + 1)/a, (a*c*d + b + 1)/(a*b), c, (a*c*d + b^2 + 2*b + 1)/(a*b*d)] - sage: S=ClusterSeed(DiGraph([[5, 'b']])) + sage: S = ClusterSeed(DiGraph([[5, 'b']])) sage: S.mutate(5) sage: S.cluster() [(b + 1)/x5, b] @@ -2395,7 +2395,7 @@ def mutate(self, sequence, inplace=True, input_type=None): sage: S.cluster() [(b + 1)/x5, b] - sage: S=ClusterSeed(DiGraph([[1, 2]])) + sage: S = ClusterSeed(DiGraph([[1, 2]])) sage: S.cluster() [x1, x2] sage: S.mutate(1) @@ -4345,27 +4345,27 @@ def get_upper_cluster_algebra_element(self,a): EXAMPLES:: - sage: B=matrix([[0,3,-3],[-3,0,3],[3,-3,0],[1,0,0],[0,1,0],[0,0,1]]) - sage: C=ClusterSeed(B) + sage: B = matrix([[0,3,-3],[-3,0,3],[3,-3,0],[1,0,0],[0,1,0],[0,0,1]]) + sage: C = ClusterSeed(B) sage: C.get_upper_cluster_algebra_element([1,1,0]) (x0^3*x2^3*x3*x4 + x2^6*x3 + x1^3*x2^3)/(x0*x1) sage: C.get_upper_cluster_algebra_element([1,1,1]) x0^2*x1^2*x2^2*x3*x4*x5 + x0^2*x1^2*x2^2 - sage: B=matrix([[0,3,0],[-3,0,3],[0,-3,0]]) - sage: C=ClusterSeed(B) + sage: B = matrix([[0,3,0],[-3,0,3],[0,-3,0]]) + sage: C = ClusterSeed(B) sage: C.get_upper_cluster_algebra_element([1,1,0]) (x1^3*x2^3 + x0^3 + x2^3)/(x0*x1) sage: C.get_upper_cluster_algebra_element([1,1,1]) (x0^3*x1^3 + x1^3*x2^3 + x0^3 + x2^3)/(x0*x1*x2) - sage: B=matrix([[0,2],[-3,0],[4,-5]]) - sage: C=ClusterSeed(B) + sage: B = matrix([[0,2],[-3,0],[4,-5]]) + sage: C = ClusterSeed(B) sage: C.get_upper_cluster_algebra_element([1,1]) (x2^9 + x1^3*x2^5 + x0^2*x2^4)/(x0*x1) - sage: B=matrix([[0,3,-5],[-3,0,4],[5,-4,0]]) - sage: C=ClusterSeed(B) + sage: B = matrix([[0,3,-5],[-3,0,4],[5,-4,0]]) + sage: C = ClusterSeed(B) sage: C.get_upper_cluster_algebra_element([1,1,1]) x0^4*x1^2*x2^3 + x0^2*x1^3*x2^4 """ diff --git a/src/sage/combinat/colored_permutations.py b/src/sage/combinat/colored_permutations.py index 3a3c8f0ab87..d3bfadcccfd 100644 --- a/src/sage/combinat/colored_permutations.py +++ b/src/sage/combinat/colored_permutations.py @@ -727,13 +727,13 @@ def _coerce_map_from_(self, C): False """ if isinstance(C, Permutations) and C.n == self._n: - return lambda P, x: P.element_class(P, [P._C.zero()]*P._n, x) + return lambda P, x: P.element_class(P, [P._C.zero()] * P._n, x) if self._m == 2 and isinstance(C, SignedPermutations) and C._n == self._n: return lambda P, x: P.element_class(P, [P._C.zero() if v == 1 else P._C.one() for v in x._colors], x._perm) - return super(ColoredPermutations, self)._coerce_map_from_(C) + return super()._coerce_map_from_(C) def __iter__(self): """ diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index 48475d117dc..e5ad98ea4ab 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -1572,7 +1572,7 @@ def __init__(self, parent, *args, **kwds): L, = kwds.values() else: raise TypeError("__init__() takes exactly 2 arguments ({} given)".format(1 + len(args) + len(kwds))) - super(CombinatorialElement, self).__init__(L) + super().__init__(L) super(CombinatorialObject, self).__init__(parent) diff --git a/src/sage/combinat/composition.py b/src/sage/combinat/composition.py index 46a6be10fad..cc709bc5091 100644 --- a/src/sage/combinat/composition.py +++ b/src/sage/combinat/composition.py @@ -1907,7 +1907,7 @@ def __classcall_private__(cls, n): sage: C is C3 True """ - return super(Compositions_n, cls).__classcall__(cls, Integer(n)) + return super().__classcall__(cls, Integer(n)) def __init__(self, n): """ diff --git a/src/sage/combinat/composition_tableau.py b/src/sage/combinat/composition_tableau.py index 64c98d81bf5..0092a043e8a 100644 --- a/src/sage/combinat/composition_tableau.py +++ b/src/sage/combinat/composition_tableau.py @@ -448,7 +448,7 @@ def __init__(self, **kwds): kwds.pop('max_entry') else: self.max_entry = None - super(CompositionTableaux, self).__init__(**kwds) + super().__init__(**kwds) Element = CompositionTableau @@ -588,11 +588,11 @@ def __init__(self, n, max_entry=None): """ if max_entry is None: max_entry = n - super(CompositionTableaux_size, self).__init__(max_entry=max_entry, - category=FiniteEnumeratedSets()) + super().__init__(max_entry=max_entry, + category=FiniteEnumeratedSets()) self.size = n - def __contains__(self,x): + def __contains__(self, x): r""" TESTS:: @@ -677,7 +677,7 @@ class CompositionTableaux_shape(CompositionTableaux): """ def __init__(self, comp, max_entry=None): """ - Initialize ``sefl``. + Initialize ``self``. TESTS:: @@ -689,8 +689,8 @@ def __init__(self, comp, max_entry=None): """ if max_entry is None: max_entry = sum(comp) - super(CompositionTableaux_shape, self).__init__(max_entry = max_entry, - category = FiniteEnumeratedSets()) + super().__init__(max_entry=max_entry, + category=FiniteEnumeratedSets()) self.shape = comp def __iter__(self): diff --git a/src/sage/combinat/core.py b/src/sage/combinat/core.py index 3e699ee4295..362c169a913 100644 --- a/src/sage/combinat/core.py +++ b/src/sage/combinat/core.py @@ -316,20 +316,18 @@ def affine_symmetric_group_simple_action(self, i): sage: c = Core([4,2],3) sage: W = c.to_grassmannian().parent() - sage: i=0 + sage: i = 0 sage: c.affine_symmetric_group_simple_action(i).to_grassmannian() == W.simple_reflection(i)*c.to_grassmannian() True - sage: i=1 + sage: i = 1 sage: c.affine_symmetric_group_simple_action(i).to_grassmannian() == W.simple_reflection(i)*c.to_grassmannian() True """ mu = self.to_partition() - corners = mu.outside_corners() - corners = [p for p in corners + corners = [p for p in mu.outside_corners() if mu.content(p[0], p[1]) % self.k() == i] if not corners: - corners = mu.corners() - corners = [p for p in corners + corners = [p for p in mu.corners() if mu.content(p[0], p[1]) % self.k() == i] if not corners: return self diff --git a/src/sage/combinat/crystals/affine_factorization.py b/src/sage/combinat/crystals/affine_factorization.py index b88f1e3adb1..1bc568aeb71 100644 --- a/src/sage/combinat/crystals/affine_factorization.py +++ b/src/sage/combinat/crystals/affine_factorization.py @@ -212,6 +212,7 @@ def _tableaux_isomorphism(self): """ # Constructing the tableaux crystal from sage.combinat.crystals.tensor_product import CrystalOfTableaux + def mg_to_shape(mg): l = list(mg.weight().to_vector()) while l and l[-1] == 0: diff --git a/src/sage/combinat/crystals/kirillov_reshetikhin.py b/src/sage/combinat/crystals/kirillov_reshetikhin.py index fe666082fe6..700768dce68 100644 --- a/src/sage/combinat/crystals/kirillov_reshetikhin.py +++ b/src/sage/combinat/crystals/kirillov_reshetikhin.py @@ -3124,8 +3124,9 @@ def promotion_on_highest_weight_vectors(self): hw_dual = [t for t in T_dual if t.is_highest_weight(index_set=ind)] dic_weight = {tuple(t.weight().to_vector()): t for t in hw} dic_weight_dual = {tuple(t.weight().to_vector()): t for t in hw_dual} + def neg(x): - y = list(x) # map a (shallow) copy + y = list(x) # map a (shallow) copy y[0] = -y[0] return tuple(y) return {dic_weight[w]: dic_weight_dual[neg(w)] for w in dic_weight} diff --git a/src/sage/combinat/crystals/littelmann_path.py b/src/sage/combinat/crystals/littelmann_path.py index 3e6db2ce2fe..9eb8ecd6dcd 100644 --- a/src/sage/combinat/crystals/littelmann_path.py +++ b/src/sage/combinat/crystals/littelmann_path.py @@ -805,6 +805,7 @@ def one_dimensional_configuration_sum(self, q=None, group_components=True): #P0 = self.weight_lattice_realization().classical() P0 = RootSystem(self.cartan_type().classical()).weight_lattice() B = P0.algebra(q.parent()) + 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()) @@ -1144,6 +1145,7 @@ def energy_function(self): Qd = RootSystem(cartan_dual).root_lattice() dualize = lambda x: Qv.from_vector(x.to_vector()) L = [Wd.from_reduced_word(x.reduced_word()) for x in L] + def stretch_short_root(a): # stretches roots by translation factor if ct.dual().type() == 'BC': diff --git a/src/sage/combinat/crystals/multisegments.py b/src/sage/combinat/crystals/multisegments.py index 81b01f17fcc..38367628485 100644 --- a/src/sage/combinat/crystals/multisegments.py +++ b/src/sage/combinat/crystals/multisegments.py @@ -216,9 +216,11 @@ def _repr_(self): """ if not self.value: return '0' + def sort_key(mc): x = mc[0] return (-x[0], ZZ(x[1])) + def seg(x): m, c = x if c != 1: @@ -243,9 +245,11 @@ def _latex_(self): """ if not self.value: return "0" + def sort_key(mc): x = mc[0] return (-x[0], ZZ(x[1])) + def seg(x): m, c = x if c != 1: diff --git a/src/sage/combinat/debruijn_sequence.pyx b/src/sage/combinat/debruijn_sequence.pyx index 6b96c2f6a8b..d98a3e66c87 100644 --- a/src/sage/combinat/debruijn_sequence.pyx +++ b/src/sage/combinat/debruijn_sequence.pyx @@ -242,18 +242,14 @@ class DeBruijnSequences(UniqueRepresentation, Parent): sage: DeBruijnSequences(1, 3).an_element() [0] - Setting ``n`` to 1 will return the alphabet: - - :: + Setting ``n`` to 1 will return the alphabet:: sage: DeBruijnSequences(3, 1).an_element() [0, 1, 2] - The test suite: - - :: + The test suite:: - sage: d=DeBruijnSequences(2, 3) + sage: d = DeBruijnSequences(2, 3) sage: TestSuite(d).run() """ def __init__(self, k, n): diff --git a/src/sage/combinat/derangements.py b/src/sage/combinat/derangements.py index e8e25e9cd79..00bdeca728c 100644 --- a/src/sage/combinat/derangements.py +++ b/src/sage/combinat/derangements.py @@ -146,8 +146,8 @@ def __classcall_private__(cls, x): True """ if x in ZZ: - x = list(range(1, x + 1)) - return super(Derangements, cls).__classcall__(cls, tuple(x)) + x = tuple(range(1, x + 1)) + return super().__classcall__(cls, tuple(x)) def __init__(self, x): """ diff --git a/src/sage/combinat/designs/twographs.py b/src/sage/combinat/designs/twographs.py index c0e15ed24fe..11211ffbefb 100644 --- a/src/sage/combinat/designs/twographs.py +++ b/src/sage/combinat/designs/twographs.py @@ -169,7 +169,8 @@ def complement(self): sage: is_twograph(pc) True """ - return super(TwoGraph, self).complement(uniform=True) + return super().complement(uniform=True) + def taylor_twograph(q): r""" diff --git a/src/sage/combinat/dyck_word.py b/src/sage/combinat/dyck_word.py index f8a7bd6952c..7c1c5bc5878 100644 --- a/src/sage/combinat/dyck_word.py +++ b/src/sage/combinat/dyck_word.py @@ -491,7 +491,7 @@ def _repr_list(self) -> str: sage: DyckWord('(())') [1, 1, 0, 0] """ - return super(DyckWord, self)._repr_() + return super()._repr_() def _repr_lattice(self, type=None, labelling=None, underpath=True) -> str: r""" diff --git a/src/sage/combinat/fast_vector_partitions.pyx b/src/sage/combinat/fast_vector_partitions.pyx index d25a1d1d445..2a1e093104b 100644 --- a/src/sage/combinat/fast_vector_partitions.pyx +++ b/src/sage/combinat/fast_vector_partitions.pyx @@ -43,7 +43,7 @@ cdef list vector_halve(list v): OUTPUT: A list, understood as the integer vector halfway down the list of - lexicographically ordered vectors between between ``v`` and zero. + lexicographically ordered vectors between ``v`` and zero. EXAMPLES:: diff --git a/src/sage/combinat/fqsym.py b/src/sage/combinat/fqsym.py index 97b8cd6455a..28244d5b684 100644 --- a/src/sage/combinat/fqsym.py +++ b/src/sage/combinat/fqsym.py @@ -160,7 +160,7 @@ def G_to_G_on_basis(t): else: return self.coerce_map_from(G) * phi - return super(FQSymBasis_abstract, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) @cached_method def an_element(self): @@ -476,7 +476,7 @@ def __getitem__(self, r): r = list(r) elif r == 1: r = [1] - return super(FreeQuasisymmetricFunctions.F, self).__getitem__(r) + return super().__getitem__(r) def degree_on_basis(self, t): """ @@ -787,7 +787,7 @@ def __getitem__(self, r): r = list(r) elif r == 1: r = [1] - return super(FreeQuasisymmetricFunctions.G, self).__getitem__(r) + return super().__getitem__(r) def _G_to_F_on_basis(self, w): r""" @@ -1005,7 +1005,7 @@ def __getitem__(self, r): r = list(r) elif r == 1: r = [1] - return super(FreeQuasisymmetricFunctions.M, self).__getitem__(r) + return super().__getitem__(r) def _F_to_M_on_basis(self, w): r""" diff --git a/src/sage/combinat/free_dendriform_algebra.py b/src/sage/combinat/free_dendriform_algebra.py index ffac8fd2452..04b8cf1208e 100644 --- a/src/sage/combinat/free_dendriform_algebra.py +++ b/src/sage/combinat/free_dendriform_algebra.py @@ -139,8 +139,7 @@ def __classcall_private__(cls, R, names=None): if R not in Rings(): raise TypeError("argument R must be a ring") - return super(FreeDendriformAlgebra, cls).__classcall__(cls, R, - names) + return super().__classcall__(cls, R, names) def __init__(self, R, names=None): """ diff --git a/src/sage/combinat/free_prelie_algebra.py b/src/sage/combinat/free_prelie_algebra.py index 8fe464d34bd..2354cbbe576 100644 --- a/src/sage/combinat/free_prelie_algebra.py +++ b/src/sage/combinat/free_prelie_algebra.py @@ -193,7 +193,7 @@ def __classcall_private__(cls, R, names=None): if R not in Rings(): raise TypeError("argument R must be a ring") - return super(FreePreLieAlgebra, cls).__classcall__(cls, R, names) + return super().__classcall__(cls, R, names) def __init__(self, R, names=None): """ diff --git a/src/sage/combinat/fully_commutative_elements.py b/src/sage/combinat/fully_commutative_elements.py index e85f7be7672..b8f26d8ba8b 100644 --- a/src/sage/combinat/fully_commutative_elements.py +++ b/src/sage/combinat/fully_commutative_elements.py @@ -923,7 +923,7 @@ def __classcall_private__(cls, data): group = data else: group = CoxeterGroup(data) - return super(cls, FullyCommutativeElements).__classcall__(cls, group) + return super().__classcall__(cls, group) def __init__(self, coxeter_group): r""" diff --git a/src/sage/combinat/gelfand_tsetlin_patterns.py b/src/sage/combinat/gelfand_tsetlin_patterns.py index 5595dbc5dd3..a210a4cc370 100644 --- a/src/sage/combinat/gelfand_tsetlin_patterns.py +++ b/src/sage/combinat/gelfand_tsetlin_patterns.py @@ -642,7 +642,7 @@ def __classcall_private__(cls, n=None, k=None, strict=False, top_row=None): if n is not None and n != len(top_row): raise ValueError("n must be the length of the specified top row") return GelfandTsetlinPatternsTopRow(top_row, strict) - return super(GelfandTsetlinPatterns, cls).__classcall__(cls, n, k, strict) + return super().__classcall__(cls, n, k, strict) def __init__(self, n, k, strict): """ @@ -1030,7 +1030,7 @@ def _toggle_markov_chain(self, chain_state, row, col, direction): TESTS: - sage: G=GelfandTsetlinPatterns(3,4) + sage: G = GelfandTsetlinPatterns(3,4) sage: state = [[3,2,1],[3,1],[2]] sage: G._toggle_markov_chain(state, 0, 0, 1) sage: state diff --git a/src/sage/combinat/grossman_larson_algebras.py b/src/sage/combinat/grossman_larson_algebras.py index 35d49447c64..8fcf8a2e5ec 100644 --- a/src/sage/combinat/grossman_larson_algebras.py +++ b/src/sage/combinat/grossman_larson_algebras.py @@ -161,7 +161,7 @@ def __classcall_private__(cls, R, names=None): if R not in Rings(): raise TypeError("argument R must be a ring") - return super(GrossmanLarsonAlgebra, cls).__classcall__(cls, R, names) + return super().__classcall__(cls, R, names) def __init__(self, R, names=None): """ diff --git a/src/sage/combinat/growth.py b/src/sage/combinat/growth.py index da7c0d0f92d..62032b03019 100644 --- a/src/sage/combinat/growth.py +++ b/src/sage/combinat/growth.py @@ -3735,11 +3735,11 @@ class RuleRSK(RulePartitions): sage: [G.P_symbol(), G.Q_symbol()] == RSK(m.transpose()) True - sage: n=5; l=[(pi, RuleRSK(pi)) for pi in Permutations(n)] + sage: n = 5; l = [(pi, RuleRSK(pi)) for pi in Permutations(n)] sage: all([G.P_symbol(), G.Q_symbol()] == RSK(pi) for pi, G in l) True - sage: n=5; l=[(w, RuleRSK(w)) for w in Words([1,2,3], 5)] + sage: n = 5; l = [(w, RuleRSK(w)) for w in Words([1,2,3], 5)] sage: all([G.P_symbol(), G.Q_symbol()] == RSK(pi) for pi, G in l) True """ diff --git a/src/sage/combinat/hillman_grassl.py b/src/sage/combinat/hillman_grassl.py index a942b8072b1..1abbc3d56bd 100644 --- a/src/sage/combinat/hillman_grassl.py +++ b/src/sage/combinat/hillman_grassl.py @@ -198,7 +198,7 @@ def conjugate(self): sage: c.parent() Weak Reverse Plane Partitions """ - C = super(WeakReversePlanePartition, self).conjugate() + C = super().conjugate() return WeakReversePlanePartition(C) def hillman_grassl_inverse(self): @@ -437,7 +437,7 @@ def __classcall_private__(cls, shape=None, **kwds): # from sage.combinat.partition import Partition # return RibbonShapedTableaux_shape(Partition(shape)) - return super(WeakReversePlanePartitions, cls).__classcall__(cls, **kwds) + return super().__classcall__(cls, **kwds) def __init__(self): """ diff --git a/src/sage/combinat/integer_lists/invlex.pyx b/src/sage/combinat/integer_lists/invlex.pyx index 93ee9e6422c..2f12ada7438 100644 --- a/src/sage/combinat/integer_lists/invlex.pyx +++ b/src/sage/combinat/integer_lists/invlex.pyx @@ -670,7 +670,7 @@ class IntegerListsLex(IntegerLists, metaclass=ClasscallMetaclass): [[3], [2, 1], [1, 2]] sage: [1,1,1] in I False - sage: I=IntegerListsLex(10, ceiling=[4], max_length=1, min_part=1) + sage: I = IntegerListsLex(10, ceiling=[4], max_length=1, min_part=1) sage: I.list() [] sage: [4,6] in I diff --git a/src/sage/combinat/integer_vector.py b/src/sage/combinat/integer_vector.py index ea9be362fdc..ee73284a59c 100644 --- a/src/sage/combinat/integer_vector.py +++ b/src/sage/combinat/integer_vector.py @@ -1096,7 +1096,7 @@ def __classcall_private__(cls, n, comp): sage: IntegerVectors(4, [2,1]) is IntegerVectors(int(4), (2,1)) True """ - return super(IntegerVectors_nnondescents, cls).__classcall__(cls, n, tuple(comp)) + return super().__classcall__(cls, n, tuple(comp)) def __init__(self, n, comp): """ diff --git a/src/sage/combinat/k_regular_sequence.py b/src/sage/combinat/k_regular_sequence.py index c09134f339c..ae5e573fd0b 100644 --- a/src/sage/combinat/k_regular_sequence.py +++ b/src/sage/combinat/k_regular_sequence.py @@ -152,8 +152,7 @@ def __init__(self, parent, mu, left=None, right=None): :doc:`k-regular sequence `, :class:`kRegularSequenceSpace`. """ - super(kRegularSequence, self).__init__( - parent=parent, mu=mu, left=left, right=right) + super().__init__(parent=parent, mu=mu, left=left, right=right) def _repr_(self): r""" @@ -828,8 +827,8 @@ def __normalize__(cls, k, coefficient_ring, **kwds): {0, 1} """ from sage.arith.srange import srange - nargs = super(kRegularSequenceSpace, cls).__normalize__( - coefficient_ring, alphabet=srange(k), **kwds) + nargs = super().__normalize__(coefficient_ring, + alphabet=srange(k), **kwds) return (k,) + nargs def __init__(self, k, *args, **kwds): @@ -863,7 +862,7 @@ def __init__(self, k, *args, **kwds): :class:`kRegularSequence`. """ self.k = k - super(kRegularSequenceSpace, self).__init__(*args, **kwds) + super().__init__(*args, **kwds) def __reduce__(self): r""" diff --git a/src/sage/combinat/knutson_tao_puzzles.py b/src/sage/combinat/knutson_tao_puzzles.py index bd5ca49fc5b..b29990d51a0 100644 --- a/src/sage/combinat/knutson_tao_puzzles.py +++ b/src/sage/combinat/knutson_tao_puzzles.py @@ -1986,7 +1986,7 @@ def __classcall_private__(cls, puzzle_pieces, max_letter=None): puzzle_pieces = BK_pieces(max_letter) else: raise ValueError("max_letter needs to be specified") - return super(KnutsonTaoPuzzleSolver, cls).__classcall__(cls, puzzle_pieces) + return super().__classcall__(cls, puzzle_pieces) def __call__(self, lamda, mu, algorithm='strips'): r""" diff --git a/src/sage/combinat/lr_tableau.py b/src/sage/combinat/lr_tableau.py index 3a24b1007d3..8e8fefaa1c5 100644 --- a/src/sage/combinat/lr_tableau.py +++ b/src/sage/combinat/lr_tableau.py @@ -97,7 +97,7 @@ def __init__(self, parent, t): """ self._shape = parent._shape self._weight = parent._weight - super(LittlewoodRichardsonTableau, self).__init__(parent, list(t)) + super().__init__(parent, list(t)) def check(self): r""" @@ -127,7 +127,7 @@ def check(self): ... ValueError: weight of the parent does not agree with the weight of the tableau """ - super(LittlewoodRichardsonTableau, self).check() + super().check() if not [i for a in self.parent()._weight for i in a] == self.weight(): raise ValueError("weight of the parent does not agree " "with the weight of the tableau") @@ -135,6 +135,7 @@ def check(self): raise ValueError("shape of the parent does not agree " "with the shape of the tableau") + class LittlewoodRichardsonTableaux(SemistandardTableaux): r""" Littlewood-Richardson tableaux. diff --git a/src/sage/combinat/matrices/hadamard_matrix.py b/src/sage/combinat/matrices/hadamard_matrix.py index 184309dac0f..9ca538ac482 100644 --- a/src/sage/combinat/matrices/hadamard_matrix.py +++ b/src/sage/combinat/matrices/hadamard_matrix.py @@ -116,12 +116,12 @@ def hadamard_matrix_paleyI(n, normalize=True): Otherwise, it returns a skew Hadamard matrix `H`, i.e. `H=S+I`, with `S=-S^\top` :: - sage: M=hadamard_matrix_paleyI(4, normalize=False); M + sage: M = hadamard_matrix_paleyI(4, normalize=False); M [ 1 1 1 1] [-1 1 1 -1] [-1 -1 1 1] [-1 1 -1 1] - sage: S=M-identity_matrix(4); -S==S.T + sage: S = M - identity_matrix(4); -S == S.T True TESTS:: @@ -247,7 +247,7 @@ def is_hadamard_matrix(M, normalized=False, skew=False, verbose=False): sage: is_hadamard_matrix(h) True sage: from sage.combinat.matrices.hadamard_matrix import skew_hadamard_matrix - sage: h=skew_hadamard_matrix(12) + sage: h = skew_hadamard_matrix(12) sage: is_hadamard_matrix(h, skew=True) True sage: h = matrix.hadamard(12) @@ -270,12 +270,12 @@ def is_hadamard_matrix(M, normalized=False, skew=False, verbose=False): sage: is_hadamard_matrix(h, skew=True, verbose=True) The matrix is not skew False - sage: h=skew_hadamard_matrix(12) + sage: h = skew_hadamard_matrix(12) sage: is_hadamard_matrix(h, skew=True, verbose=True) True sage: is_hadamard_matrix(h, skew=False, verbose=True) True - sage: h=-h + sage: h = -h sage: is_hadamard_matrix(h, skew=True, verbose=True) The matrix is not skew - diagonal entries must be all 1 False @@ -899,24 +899,24 @@ def williamson_goethals_seidel_skew_hadamard_matrix(a, b, c, d, check=True): EXAMPLES:: sage: from sage.combinat.matrices.hadamard_matrix import williamson_goethals_seidel_skew_hadamard_matrix as WGS - sage: a=[ 1, 1, 1, -1, 1, -1, 1, -1, -1] - sage: b=[ 1, -1, 1, 1, -1, -1, 1, 1, -1] - sage: c=[-1, -1]+[1]*6+[-1] - sage: d=[ 1, 1, 1, -1, 1, 1, -1, 1, 1] - sage: M=WGS(a,b,c,d,check=True) + sage: a = [ 1, 1, 1, -1, 1, -1, 1, -1, -1] + sage: b = [ 1, -1, 1, 1, -1, -1, 1, 1, -1] + sage: c = [-1, -1]+[1]*6+[-1] + sage: d = [ 1, 1, 1, -1, 1, 1, -1, 1, 1] + sage: M = WGS(a,b,c,d,check=True) REFERENCES: .. [GS70s] \J.M. Goethals and J. J. Seidel, - A skew Hadamard matrix of order 36, + *A skew Hadamard matrix of order 36*, J. Aust. Math. Soc. 11(1970), 343-344 .. [Wall71] \J. Wallis, - A skew-Hadamard matrix of order 92, + *A skew-Hadamard matrix of order 92*, Bull. Aust. Math. Soc. 5(1971), 203-204 .. [KoSt08] \C. Koukouvinos, S. Stylianou - On skew-Hadamard matrices, + *On skew-Hadamard matrices*, Discrete Math. 308(2008) 2723-2731 """ n = len(a) @@ -1174,7 +1174,7 @@ def symmetric_conference_matrix(n, check=True): EXAMPLES:: sage: from sage.combinat.matrices.hadamard_matrix import symmetric_conference_matrix - sage: C=symmetric_conference_matrix(10); C + sage: C = symmetric_conference_matrix(10); C [ 0 1 1 1 1 1 1 1 1 1] [ 1 0 -1 -1 1 -1 1 1 1 -1] [ 1 -1 0 -1 1 1 -1 -1 1 1] @@ -1185,7 +1185,7 @@ def symmetric_conference_matrix(n, check=True): [ 1 1 -1 1 1 1 -1 0 -1 -1] [ 1 1 1 -1 -1 1 1 -1 0 -1] [ 1 -1 1 1 1 -1 1 -1 -1 0] - sage: C^2==9*identity_matrix(10) and C==C.T + sage: C^2 == 9*identity_matrix(10) and C == C.T True """ from sage.graphs.strongly_regular_db import strongly_regular_graph as srg @@ -1302,7 +1302,7 @@ def rshcd_from_prime_power_and_conference_matrix(n): sage: from sage.combinat.matrices.hadamard_matrix import is_hadamard_matrix sage: H = rshcd_from_prime_power_and_conference_matrix(7); H 36 x 36 dense matrix over Integer Ring (use the '.str()' method to see the entries) - sage: H==H.T and is_hadamard_matrix(H) and H.diagonal()==[1]*36 and list(sum(H))==[6]*36 + sage: H == H.T and is_hadamard_matrix(H) and H.diagonal() == [1]*36 and list(sum(H)) == [6]*36 True Bigger examples, only provided by this construction :: @@ -1310,7 +1310,7 @@ def rshcd_from_prime_power_and_conference_matrix(n): sage: H = rshcd_from_prime_power_and_conference_matrix(27) # long time sage: H == H.T and is_hadamard_matrix(H) # long time True - sage: H.diagonal()==[1]*676 and list(sum(H))==[26]*676 # long time + sage: H.diagonal() == [1]*676 and list(sum(H)) == [26]*676 # long time True In this example the conference matrix is not Paley, as 45 is not a prime power :: diff --git a/src/sage/combinat/ncsf_qsym/generic_basis_code.py b/src/sage/combinat/ncsf_qsym/generic_basis_code.py index 3457b4cdd03..6f153c232bf 100644 --- a/src/sage/combinat/ncsf_qsym/generic_basis_code.py +++ b/src/sage/combinat/ncsf_qsym/generic_basis_code.py @@ -136,7 +136,7 @@ def one_basis(self): EXAMPLES:: - sage: L=NonCommutativeSymmetricFunctions(QQ).L() + sage: L = NonCommutativeSymmetricFunctions(QQ).L() sage: parent(L) sage: parent(L).one_basis() @@ -161,10 +161,10 @@ def sum_of_finer_compositions(self, composition): EXAMPLES:: - sage: L=NonCommutativeSymmetricFunctions(QQ).L() + sage: L = NonCommutativeSymmetricFunctions(QQ).L() sage: L.sum_of_finer_compositions(Composition([2,1])) L[1, 1, 1] + L[2, 1] - sage: R=NonCommutativeSymmetricFunctions(QQ).R() + sage: R = NonCommutativeSymmetricFunctions(QQ).R() sage: R.sum_of_finer_compositions(Composition([1,3])) R[1, 1, 1, 1] + R[1, 1, 2] + R[1, 2, 1] + R[1, 3] """ @@ -186,10 +186,10 @@ def sum_of_fatter_compositions(self, composition): EXAMPLES:: - sage: L=NonCommutativeSymmetricFunctions(QQ).L() + sage: L = NonCommutativeSymmetricFunctions(QQ).L() sage: L.sum_of_fatter_compositions(Composition([2,1])) L[2, 1] + L[3] - sage: R=NonCommutativeSymmetricFunctions(QQ).R() + sage: R = NonCommutativeSymmetricFunctions(QQ).R() sage: R.sum_of_fatter_compositions(Composition([1,3])) R[1, 3] + R[4] """ @@ -216,7 +216,7 @@ def alternating_sum_of_compositions(self, n): EXAMPLES:: - sage: L=NonCommutativeSymmetricFunctions(QQ).L() + sage: L = NonCommutativeSymmetricFunctions(QQ).L() sage: L.alternating_sum_of_compositions(0) L[] sage: L.alternating_sum_of_compositions(1) @@ -225,7 +225,7 @@ def alternating_sum_of_compositions(self, n): L[1, 1] - L[2] sage: L.alternating_sum_of_compositions(3) L[1, 1, 1] - L[1, 2] - L[2, 1] + L[3] - sage: S=NonCommutativeSymmetricFunctions(QQ).S() + sage: S = NonCommutativeSymmetricFunctions(QQ).S() sage: S.alternating_sum_of_compositions(3) S[1, 1, 1] - S[1, 2] - S[2, 1] + S[3] """ @@ -1424,7 +1424,7 @@ def internal_product_by_coercion(self, left, right): EXAMPLES:: - sage: S=NonCommutativeSymmetricFunctions(QQ).S() + sage: S = NonCommutativeSymmetricFunctions(QQ).S() sage: S.internal_product_by_coercion(S[2,1], S[3]) S[2, 1] sage: S.internal_product_by_coercion(S[2,1], S[4]) diff --git a/src/sage/combinat/ncsf_qsym/ncsf.py b/src/sage/combinat/ncsf_qsym/ncsf.py index a746239b155..7a53a902b94 100644 --- a/src/sage/combinat/ncsf_qsym/ncsf.py +++ b/src/sage/combinat/ncsf_qsym/ncsf.py @@ -1644,7 +1644,7 @@ def to_symmetric_group_algebra(self): EXAMPLES:: - sage: R=NonCommutativeSymmetricFunctions(QQ).R() + sage: R = NonCommutativeSymmetricFunctions(QQ).R() sage: R[2,1].to_symmetric_group_algebra() [1, 3, 2] + [2, 3, 1] sage: R([]).to_symmetric_group_algebra() @@ -2224,7 +2224,7 @@ def antipode(self): EXAMPLES:: - sage: S=NonCommutativeSymmetricFunctions(QQ).S() + sage: S = NonCommutativeSymmetricFunctions(QQ).S() sage: S.antipode Generic endomorphism of Non-Commutative Symmetric Functions over the Rational Field in the Complete basis """ @@ -2245,7 +2245,7 @@ def coproduct(self): EXAMPLES:: - sage: S=NonCommutativeSymmetricFunctions(QQ).S() + sage: S = NonCommutativeSymmetricFunctions(QQ).S() sage: S.coproduct Generic morphism: From: Non-Commutative Symmetric Functions over the Rational Field in the Complete basis @@ -2585,7 +2585,7 @@ def dual(self): EXAMPLES:: - sage: R=NonCommutativeSymmetricFunctions(QQ).ribbon() + sage: R = NonCommutativeSymmetricFunctions(QQ).ribbon() sage: R.dual() Quasisymmetric functions over the Rational Field in the Fundamental basis """ @@ -2683,7 +2683,7 @@ def to_symmetric_function_on_basis(self, I): EXAMPLES:: - sage: R=NonCommutativeSymmetricFunctions(QQ).R() + sage: R = NonCommutativeSymmetricFunctions(QQ).R() sage: R.to_symmetric_function_on_basis(Composition([3,1,1])) s[3, 1, 1] sage: R.to_symmetric_function_on_basis(Composition([4,2,1])) @@ -3039,7 +3039,7 @@ def to_symmetric_function_on_basis(self, I): EXAMPLES:: - sage: S=NonCommutativeSymmetricFunctions(QQ).complete() + sage: S = NonCommutativeSymmetricFunctions(QQ).complete() sage: S.to_symmetric_function_on_basis([2,1,3]) h[3, 2, 1] sage: S.to_symmetric_function_on_basis([]) @@ -3097,7 +3097,7 @@ def _to_symmetric_group_algebra_on_basis(self, I): EXAMPLES:: - sage: S=NonCommutativeSymmetricFunctions(QQ).S() + sage: S = NonCommutativeSymmetricFunctions(QQ).S() sage: S._to_symmetric_group_algebra_on_basis(Composition([1,2])) [1, 2, 3] + [2, 1, 3] + [3, 1, 2] sage: S._to_symmetric_group_algebra_on_basis(Composition([])) @@ -4710,7 +4710,7 @@ def _H(self, alpha): EXAMPLES:: - sage: I=NonCommutativeSymmetricFunctions(QQ).I() + sage: I = NonCommutativeSymmetricFunctions(QQ).I() sage: I._H([2,0,1]) S[2, 1] sage: I._H([2,0,1,-1]) @@ -4741,7 +4741,7 @@ def _to_complete_on_basis(self, alpha): EXAMPLES:: - sage: I=NonCommutativeSymmetricFunctions(QQ).I() + sage: I = NonCommutativeSymmetricFunctions(QQ).I() sage: I._to_complete_on_basis(Composition([])) S[] sage: I._to_complete_on_basis(Composition([2,1,3])) @@ -4775,7 +4775,7 @@ def _from_complete_on_basis(self, comp_content): EXAMPLES:: - sage: I=NonCommutativeSymmetricFunctions(QQ).I() + sage: I = NonCommutativeSymmetricFunctions(QQ).I() sage: I._from_complete_on_basis(Composition([])) I[] sage: I._from_complete_on_basis(Composition([2,1,3])) @@ -4800,7 +4800,7 @@ def dual(self): EXAMPLES:: - sage: I=NonCommutativeSymmetricFunctions(QQ).Immaculate() + sage: I = NonCommutativeSymmetricFunctions(QQ).Immaculate() sage: I.dual() Quasisymmetric functions over the Rational Field in the dualImmaculate basis diff --git a/src/sage/combinat/ncsf_qsym/qsym.py b/src/sage/combinat/ncsf_qsym/qsym.py index 00471232782..086b68c6175 100644 --- a/src/sage/combinat/ncsf_qsym/qsym.py +++ b/src/sage/combinat/ncsf_qsym/qsym.py @@ -1581,7 +1581,7 @@ def expand(self, n, alphabet='x'): EXAMPLES:: - sage: F=QuasiSymmetricFunctions(QQ).Fundamental() + sage: F = QuasiSymmetricFunctions(QQ).Fundamental() sage: F[3].expand(3) x0^3 + x0^2*x1 + x0*x1^2 + x1^3 + x0^2*x2 + x0*x1*x2 + x1^2*x2 + x0*x2^2 + x1*x2^2 + x2^3 sage: F[2,1].expand(3) @@ -1590,7 +1590,7 @@ def expand(self, n, alphabet='x'): One can use a different set of variable by adding an optional argument ``alphabet=...`` :: - sage: F=QuasiSymmetricFunctions(QQ).Fundamental() + sage: F = QuasiSymmetricFunctions(QQ).Fundamental() sage: F[3].expand(2,alphabet='y') y0^3 + y0^2*y1 + y0*y1^2 + y1^3 @@ -1798,7 +1798,7 @@ def coproduct_on_basis(self, compo): EXAMPLES:: - sage: M=QuasiSymmetricFunctions(QQ).Monomial() + sage: M = QuasiSymmetricFunctions(QQ).Monomial() sage: M[4,2,3].coproduct() M[] # M[4, 2, 3] + M[4] # M[2, 3] + M[4, 2] # M[3] + M[4, 2, 3] # M[] sage: M.coproduct_on_basis(Composition([])) @@ -2022,7 +2022,7 @@ def expand(self, n, alphabet='x'): One can use a different set of variables by using the optional argument ``alphabet``:: - sage: M=QuasiSymmetricFunctions(QQ).Monomial() + sage: M = QuasiSymmetricFunctions(QQ).Monomial() sage: M[2,1,1].expand(4,alphabet='y') y0^2*y1*y2 + y0^2*y1*y3 + y0^2*y2*y3 + y1^2*y2*y3 diff --git a/src/sage/combinat/ncsf_qsym/tutorial.py b/src/sage/combinat/ncsf_qsym/tutorial.py index 6236a3ba2af..5efc8d43728 100644 --- a/src/sage/combinat/ncsf_qsym/tutorial.py +++ b/src/sage/combinat/ncsf_qsym/tutorial.py @@ -99,7 +99,7 @@ The usual methods on free modules are available such as coefficients, degrees, and the support:: - sage: z=3*M[1,2]+M[3]^2; z + sage: z = 3*M[1,2]+M[3]^2; z 3*M[1, 2] + 2*M[3, 3] + M[6] sage: z.coefficient([1,2]) diff --git a/src/sage/combinat/ncsym/bases.py b/src/sage/combinat/ncsym/bases.py index 398883f1d80..6d8b1b86185 100644 --- a/src/sage/combinat/ncsym/bases.py +++ b/src/sage/combinat/ncsym/bases.py @@ -45,7 +45,7 @@ def _element_constructor_(self, x): """ if isinstance(x, (list, tuple)): x = SetPartition(x) - return super(NCSymBasis_abstract, self)._element_constructor_(x) + return super()._element_constructor_(x) class NCSymOrNCSymDualBases(Category_realization_of_parent): diff --git a/src/sage/combinat/necklace.py b/src/sage/combinat/necklace.py index bbfb5c215d2..a065cabdd2c 100644 --- a/src/sage/combinat/necklace.py +++ b/src/sage/combinat/necklace.py @@ -87,11 +87,9 @@ def __classcall_private__(cls, content): sage: Necklaces([2,1,1]) is Necklaces(Composition([2,1,1])) True """ - if isinstance(content, Composition): - return super(Necklaces_evaluation, cls).__classcall__(cls, content) - else: + if not isinstance(content, Composition): content = Composition(content) - return super(Necklaces_evaluation, cls).__classcall__(cls, content) + return super().__classcall__(cls, content) def __init__(self, content): r""" diff --git a/src/sage/combinat/nu_tamari_lattice.py b/src/sage/combinat/nu_tamari_lattice.py index e90fc4d6791..0d6b391aa8b 100644 --- a/src/sage/combinat/nu_tamari_lattice.py +++ b/src/sage/combinat/nu_tamari_lattice.py @@ -62,7 +62,7 @@ def NuTamariLattice(nu): INPUT: - - `\nu` -- a list of of 0s and 1s or a string of 0s and 1s. + - `\nu` -- a list of 0s and 1s or a string of 0s and 1s. OUTPUT: diff --git a/src/sage/combinat/ordered_tree.py b/src/sage/combinat/ordered_tree.py index acb9eddc652..8157b4a95a3 100644 --- a/src/sage/combinat/ordered_tree.py +++ b/src/sage/combinat/ordered_tree.py @@ -1021,7 +1021,7 @@ def __init__(self, size): sage: TestSuite(OrderedTrees_size(0)).run() sage: for i in range(6): TestSuite(OrderedTrees_size(i)).run() """ - super(OrderedTrees_size, self).__init__(category=FiniteEnumeratedSets()) + super().__init__(category=FiniteEnumeratedSets()) self._size = size def _repr_(self): diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 769d38b13ed..46462aaab89 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -4578,21 +4578,21 @@ def from_kbounded_to_reduced_word(self, k): EXAMPLES:: - sage: p=Partition([2,1,1]) + sage: p = Partition([2,1,1]) sage: p.from_kbounded_to_reduced_word(2) [2, 1, 2, 0] - sage: p=Partition([3,1]) + sage: p = Partition([3,1]) sage: p.from_kbounded_to_reduced_word(3) [3, 2, 1, 0] sage: p.from_kbounded_to_reduced_word(2) Traceback (most recent call last): ... ValueError: the partition must be 2-bounded - sage: p=Partition([]) + sage: p = Partition([]) sage: p.from_kbounded_to_reduced_word(2) [] """ - p=self.k_skew(k)[0] + p = self.k_skew(k)[0] result = [] while not p.is_empty(): corners = p.corners() @@ -4613,18 +4613,18 @@ def from_kbounded_to_grassmannian(self, k): EXAMPLES:: - sage: p=Partition([2,1,1]) + sage: p = Partition([2,1,1]) sage: p.from_kbounded_to_grassmannian(2) [-1 1 1] [-2 2 1] [-2 1 2] - sage: p=Partition([]) + sage: p = Partition([]) sage: p.from_kbounded_to_grassmannian(2) [1 0 0] [0 1 0] [0 0 1] """ - return WeylGroup(['A',k,1]).from_reduced_word(self.from_kbounded_to_reduced_word(k)) + return WeylGroup(['A', k,1 ]).from_reduced_word(self.from_kbounded_to_reduced_word(k)) def to_list(self): r""" @@ -5049,7 +5049,7 @@ def dimension(self, smaller=None, k=1): A check coming from the theory of `k`-differentiable posets:: - sage: k=2; core = Partition([2,1]) + sage: k = 2; core = Partition([2,1]) sage: all(sum(mu.dimension(core,k=2)^2 ....: for mu in Partitions(3+i*2) if mu.core(2) == core) ....: == 2^i*factorial(i) for i in range(10)) @@ -5170,7 +5170,7 @@ def outline(self, variable=None): sage: Partition([1]).outline() abs(x + 1) + abs(x - 1) - abs(x) - sage: y=sage.symbolic.ring.var("y") + sage: y = SR.var("y") sage: Partition([6,5,1]).outline(variable=y) abs(y + 6) - abs(y + 5) + abs(y + 4) - abs(y + 3) + abs(y - 1) - abs(y - 2) + abs(y - 3) @@ -6437,7 +6437,7 @@ def cardinality(self, algorithm='flint'): indeed agree:: sage: q = PowerSeriesRing(QQ, 'q', default_prec=9).gen() - sage: prod([(1-q^k)^(-1) for k in range(1,9)]) ## partial product of + sage: prod([(1-q^k)^(-1) for k in range(1,9)]) # partial product of 1 + q + 2*q^2 + 3*q^3 + 5*q^4 + 7*q^5 + 11*q^6 + 15*q^7 + 22*q^8 + O(q^9) sage: [Partitions(k).cardinality() for k in range(2,10)] [2, 3, 5, 7, 11, 15, 22, 30] @@ -8659,7 +8659,7 @@ def _an_element_(self): ######################################################################### -#### partitions +# partitions def number_of_partitions(n, algorithm='default'): r""" @@ -8726,7 +8726,7 @@ def number_of_partitions(n, algorithm='default'): instead agree:: sage: q = PowerSeriesRing(QQ, 'q', default_prec=9).gen() - sage: prod([(1-q^k)^(-1) for k in range(1,9)]) ## partial product of + sage: prod([(1-q^k)^(-1) for k in range(1,9)]) # partial product of 1 + q + 2*q^2 + 3*q^3 + 5*q^4 + 7*q^5 + 11*q^6 + 15*q^7 + 22*q^8 + O(q^9) sage: [number_of_partitions(k) for k in range(2,10)] [2, 3, 5, 7, 11, 15, 22, 30] diff --git a/src/sage/combinat/perfect_matching.py b/src/sage/combinat/perfect_matching.py index 975a682b233..bde046e0d8b 100644 --- a/src/sage/combinat/perfect_matching.py +++ b/src/sage/combinat/perfect_matching.py @@ -603,7 +603,7 @@ def __classcall_private__(cls, s): except AttributeError: pass s = frozenset(s) - return super(PerfectMatchings, cls).__classcall__(cls, s) + return super().__classcall__(cls, s) def _repr_(self): """ diff --git a/src/sage/combinat/plane_partition.py b/src/sage/combinat/plane_partition.py index 4413916886a..49edf8abdea 100644 --- a/src/sage/combinat/plane_partition.py +++ b/src/sage/combinat/plane_partition.py @@ -806,7 +806,7 @@ def __classcall_private__(cls, box_size): sage: P1 is P2 True """ - return super(PlanePartitions, cls).__classcall__(cls, tuple(box_size)) + return super().__classcall__(cls, tuple(box_size)) def __init__(self, box_size): r""" diff --git a/src/sage/combinat/posets/cartesian_product.py b/src/sage/combinat/posets/cartesian_product.py index 473024e80b9..e8c602895cd 100644 --- a/src/sage/combinat/posets/cartesian_product.py +++ b/src/sage/combinat/posets/cartesian_product.py @@ -111,8 +111,7 @@ def __init__(self, sets, category, order=None, **kwargs): if not isinstance(category, tuple): category = (category,) category = Category.join(category + (Posets(),)) - super(CartesianProductPoset, self).__init__( - sets, category, **kwargs) + super().__init__(sets, category, **kwargs) def le(self, left, right): r""" diff --git a/src/sage/combinat/posets/incidence_algebras.py b/src/sage/combinat/posets/incidence_algebras.py index 65dc086118a..2d621cef967 100644 --- a/src/sage/combinat/posets/incidence_algebras.py +++ b/src/sage/combinat/posets/incidence_algebras.py @@ -117,7 +117,7 @@ def _coerce_map_from_(self, R): """ if isinstance(R, ReducedIncidenceAlgebra) and R._ambient is self: return copy(R.lift) - return super(IncidenceAlgebra, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) def reduced_subalgebra(self, prefix='R'): """ diff --git a/src/sage/combinat/posets/lattices.py b/src/sage/combinat/posets/lattices.py index 26d756a11e8..00f50e68f19 100644 --- a/src/sage/combinat/posets/lattices.py +++ b/src/sage/combinat/posets/lattices.py @@ -2022,7 +2022,7 @@ def complements(self, element=None): EXAMPLES:: - sage: L=LatticePoset({0:['a','b','c'], 'a':[1], 'b':[1], 'c':[1]}) + sage: L = LatticePoset({0:['a','b','c'],'a':[1],'b':[1],'c':[1]}) sage: C = L.complements() Let us check that 'a' and 'b' are complements of each other:: @@ -2037,7 +2037,7 @@ def complements(self, element=None): sage: L.complements() # random order {0: [1], 1: [0], 'a': ['b', 'c'], 'b': ['c', 'a'], 'c': ['b', 'a']} - sage: L=LatticePoset({0:[1,2],1:[3],2:[3],3:[4]}) + sage: L = LatticePoset({0:[1,2],1:[3],2:[3],3:[4]}) sage: L.complements() # random order {0: [4], 4: [0]} sage: L.complements(1) @@ -2047,7 +2047,7 @@ def complements(self, element=None): TESTS:: - sage: L=LatticePoset({0:['a','b','c'], 'a':[1], 'b':[1], 'c':[1]}) + sage: L = LatticePoset({0:['a','b','c'], 'a':[1], 'b':[1], 'c':[1]}) sage: for v,v_complements in L.complements().items(): ....: for v_c in v_complements: ....: assert L.meet(v,v_c) == L.bottom() @@ -3163,7 +3163,7 @@ def sublattice(self, elms): EXAMPLES:: - sage: L=LatticePoset(( [], [[1,2],[1,17],[1,8],[2,3],[2,22],[2,5],[2,7],[17,22],[17,13],[8,7],[8,13],[3,16],[3,9],[22,16],[22,18],[22,10],[5,18],[5,14],[7,9],[7,14],[7,10],[13,10],[16,6],[16,19],[9,19],[18,6],[18,33],[14,33],[10,19],[10,33],[6,4],[19,4],[33,4]] )) + sage: L = LatticePoset(([], [[1,2],[1,17],[1,8],[2,3],[2,22],[2,5],[2,7],[17,22],[17,13],[8,7],[8,13],[3,16],[3,9],[22,16],[22,18],[22,10],[5,18],[5,14],[7,9],[7,14],[7,10],[13,10],[16,6],[16,19],[9,19],[18,6],[18,33],[14,33],[10,19],[10,33],[6,4],[19,4],[33,4]])) sage: L.sublattice([14, 13, 22]).list() [1, 2, 8, 7, 14, 17, 13, 22, 10, 33] diff --git a/src/sage/combinat/posets/linear_extensions.py b/src/sage/combinat/posets/linear_extensions.py index 8c2a4fa3d0a..d47c4c56179 100644 --- a/src/sage/combinat/posets/linear_extensions.py +++ b/src/sage/combinat/posets/linear_extensions.py @@ -453,7 +453,7 @@ def __classcall_private__(cls, poset, facade=False): sage: L is LinearExtensionsOfPoset(P,facade=False) True """ - return super(LinearExtensionsOfPoset, cls).__classcall__(cls, poset, facade=facade) + return super().__classcall__(cls, poset, facade=facade) def __init__(self, poset, facade): """ @@ -641,7 +641,7 @@ def __contains__(self, obj): """ if not self._is_facade: - return super(LinearExtensionsOfPoset, self).__contains__(obj) + return super().__contains__(obj) return (isinstance(obj, (list, tuple)) and self.poset().is_linear_extension(obj)) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index d79dfaf67ea..0ec9fdfee20 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -1000,10 +1000,10 @@ def __classcall__(cls, hasse_diagram, elements=None, category=None, facade=None, if category is not None and category.is_subcategory(Sets().Facade()): category = category._without_axiom("Facade") category = Category.join([FinitePosets().or_subcategory(category), FiniteEnumeratedSets()]) - return super(FinitePoset, cls).__classcall__(cls, hasse_diagram=hasse_diagram, - elements=elements, - category=category, facade=facade, - key=key) + return super().__classcall__(cls, hasse_diagram=hasse_diagram, + elements=elements, + category=category, facade=facade, + key=key) def __init__(self, hasse_diagram, elements, category, facade, key): r""" diff --git a/src/sage/combinat/root_system/hecke_algebra_representation.py b/src/sage/combinat/root_system/hecke_algebra_representation.py index e146784ad98..bde28234214 100644 --- a/src/sage/combinat/root_system/hecke_algebra_representation.py +++ b/src/sage/combinat/root_system/hecke_algebra_representation.py @@ -460,6 +460,7 @@ def _test_relations(self, **options): q1 = self._q1 q2 = self._q2 T = self + def Ti(x,i,c): return T[i](x)+c*x # Check the quadratic relation diff --git a/src/sage/combinat/root_system/integrable_representations.py b/src/sage/combinat/root_system/integrable_representations.py index e17e6b3c7fe..6aedd4aefb2 100644 --- a/src/sage/combinat/root_system/integrable_representations.py +++ b/src/sage/combinat/root_system/integrable_representations.py @@ -919,6 +919,7 @@ def dominant_maximal_weights(self): """ k = self.level() Lambda = self._P.fundamental_weights() + def next_level(wt): return [wt + Lambda[i] for i in self._index_set_classical if (wt + Lambda[i]).level() <= k] @@ -1191,6 +1192,7 @@ def branch(self, i=None, weyl_character_ring=None, sequence=None, depth=5): sequence[j] = j+1 elif j > i: sequence[j] = j + def next_level(x): ret = [] for j in self._index_set: 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 86b1e561f87..4d26225011a 100644 --- a/src/sage/combinat/root_system/root_lattice_realization_algebras.py +++ b/src/sage/combinat/root_system/root_lattice_realization_algebras.py @@ -848,6 +848,7 @@ def T0_check_on_basis(self, q1, q2, convention="antidominant"): translation = A0.monomial(-L0.simple_root(j)/a0) Tv = T[v] Tinv = T.Tw_inverse(v+(j,)) + def T0_check(weight): return -q1*q2*Tinv( translation * Tv(A0.monomial(weight))) # For debugging purposes diff --git a/src/sage/combinat/root_system/root_lattice_realizations.py b/src/sage/combinat/root_system/root_lattice_realizations.py index 766b7932cdb..f6713d00d33 100644 --- a/src/sage/combinat/root_system/root_lattice_realizations.py +++ b/src/sage/combinat/root_system/root_lattice_realizations.py @@ -804,6 +804,7 @@ def positive_real_roots(self): # Start with the classical positive roots alpha = self.simple_roots() + def lift(x): """ Lift up the classical element into ``self``. @@ -1133,6 +1134,7 @@ def generalized_nonnesting_partition_lattice(self, m, facade=False): for multilist in combinations_with_replacement(list(range(len(chain))), m): if len(set(multilist)) == len(chain): multichains.append(tuple([chain[i] for i in multilist])) + def is_saturated_chain(chain): for i in range(1, m + 1): for j in range(1, m - i + 1): @@ -1710,6 +1712,7 @@ def tau_epsilon_operator_on_almost_positive_roots(self, J): t = W.from_reduced_word(J) simple_roots = self.simple_roots() other_negative_simple_roots = set(-simple_roots[i] for i in self.index_set() if i not in J) + def tau_epsilon(alpha): if alpha in other_negative_simple_roots: return alpha @@ -2702,6 +2705,7 @@ def plot_alcoves(self, alcoves=True, alcove_labels=False, wireframe=False, **opt def alcove_in_bounding_box(w): return any(plot_options.in_bounding_box(w.action(fundamental_alcove_rays[i])) for i in I) + def alcove_facet(w, i): # Alcove facets with degenerate intersection with the # bounding box bring no information; we might as well @@ -2712,6 +2716,7 @@ def alcove_facet(w, i): thickness=plot_options.thickness(i), wireframe=wireframe, draw_degenerate=False) + def alcove_label(w): label = "$1$" if w.is_one() else "$s_{"+"".join(str(j) for j in w.reduced_word())+"}$" position = plot_options.projection(w.action(rho)) @@ -3497,6 +3502,7 @@ def _dot_orbit_iter(self): (2, 0, 1), (0, 1, 2), (0, 2, 1)] """ I = self.parent().index_set() + def apply_action(la): return [la.dot_action([i]) for i in I] R = RecursivelyEnumeratedSet([self], apply_action, structure=None, diff --git a/src/sage/combinat/root_system/root_space.py b/src/sage/combinat/root_system/root_space.py index bf2e2858413..c36a721e02c 100644 --- a/src/sage/combinat/root_system/root_space.py +++ b/src/sage/combinat/root_system/root_space.py @@ -226,6 +226,7 @@ def to_ambient_space_morphism(self): else: L = self.cartan_type().root_system().ambient_space() basis = L.simple_roots() + def basis_value(basis, i): return basis[i] return self.module_morphism(on_basis = functools.partial(basis_value, basis) , codomain=L) diff --git a/src/sage/combinat/root_system/type_folded.py b/src/sage/combinat/root_system/type_folded.py index 9482ec494c4..b8ef07d88e2 100644 --- a/src/sage/combinat/root_system/type_folded.py +++ b/src/sage/combinat/root_system/type_folded.py @@ -284,6 +284,7 @@ def scaling_factors(self): """ if self._cartan_type.is_finite(): L = self._cartan_type.root_system().ambient_space() + def f(i): root = L.simple_root(i) coroot = L.simple_coroot(i) diff --git a/src/sage/combinat/root_system/weight_space.py b/src/sage/combinat/root_system/weight_space.py index 6dd7f347ca9..a532df0b343 100644 --- a/src/sage/combinat/root_system/weight_space.py +++ b/src/sage/combinat/root_system/weight_space.py @@ -451,6 +451,7 @@ def to_ambient_space_morphism(self): raise TypeError("No implemented map from the coweight space to the ambient space") L = self.cartan_type().root_system().ambient_space() basis = L.fundamental_weights() + def basis_value(basis, i): return basis[i] return self.module_morphism(on_basis = functools.partial(basis_value, basis), codomain=L) diff --git a/src/sage/combinat/root_system/weyl_group.py b/src/sage/combinat/root_system/weyl_group.py index 76c4314c463..42aa218115c 100644 --- a/src/sage/combinat/root_system/weyl_group.py +++ b/src/sage/combinat/root_system/weyl_group.py @@ -376,6 +376,7 @@ def reflections(self): NotImplementedError: only implemented for finite and affine Cartan types """ prr = self.domain().positive_real_roots() + def to_elt(alp): ref = self.domain().reflection(alp) m = Matrix([ref(x).to_vector() for x in self.domain().basis()]) @@ -1297,6 +1298,7 @@ def distinguished_reflections(self): Q = self._cartan_type.root_system().root_lattice() pos_roots = list(Q.positive_roots()) Phi = pos_roots + [-x for x in pos_roots] + def build_elt(index): r = pos_roots[index] perm = [Phi.index(x.reflection(r))+1 for x in Phi] diff --git a/src/sage/combinat/rooted_tree.py b/src/sage/combinat/rooted_tree.py index ace4009f3ef..b28b1b89b9e 100644 --- a/src/sage/combinat/rooted_tree.py +++ b/src/sage/combinat/rooted_tree.py @@ -633,7 +633,7 @@ def __init__(self, n): sage: for i in range(1, 6): ....: TestSuite(RootedTrees(i)).run() """ - super(RootedTrees_size, self).__init__(category=FiniteEnumeratedSets()) + super().__init__(category=FiniteEnumeratedSets()) self._n = n def _repr_(self): diff --git a/src/sage/combinat/rsk.py b/src/sage/combinat/rsk.py index f5a3432b208..2400ef86fdd 100644 --- a/src/sage/combinat/rsk.py +++ b/src/sage/combinat/rsk.py @@ -613,9 +613,8 @@ def _backward_format_output(self, lower_row, upper_row, output, raise TypeError("p must be standard to have a valid permutation as output") from sage.combinat.permutation import Permutation return Permutation(reversed(lower_row)) - else: - return super(RuleRSK, self)._backward_format_output(lower_row, upper_row, output, - p_is_standard, q_is_standard) + return super()._backward_format_output(lower_row, upper_row, output, + p_is_standard, q_is_standard) class RuleEG(Rule): @@ -798,8 +797,8 @@ def _backward_format_output(self, lower_row, upper_row, output, from sage.combinat.permutation import Permutations return Permutations(n).from_reduced_word(list(lower_row)) else: - return super(RuleEG, self)._backward_format_output(lower_row, upper_row, output, - p_is_standard, q_is_standard) + return super()._backward_format_output(lower_row, upper_row, output, + p_is_standard, q_is_standard) class RuleHecke(Rule): @@ -1483,8 +1482,8 @@ def _backward_format_output(self, lower_row, upper_row, output, from sage.combinat.permutation import Permutation return Permutation(reversed(lower_row)) else: - return super(RuleDualRSK, self)._backward_format_output(lower_row, upper_row, output, - p_is_standard, q_is_standard) + return super()._backward_format_output(lower_row, upper_row, output, + p_is_standard, q_is_standard) def _forward_format_output(self, p, q, check_standard): r""" diff --git a/src/sage/combinat/set_partition.py b/src/sage/combinat/set_partition.py index 3e426f16e85..fdd394e1369 100644 --- a/src/sage/combinat/set_partition.py +++ b/src/sage/combinat/set_partition.py @@ -2735,7 +2735,7 @@ def __classcall_private__(cls, s): sage: S1 is S2, S1 is S3 (True, True) """ - return super(SetPartitions_set, cls).__classcall__(cls, frozenset(s)) + return super().__classcall__(cls, frozenset(s)) def __init__(self, s): """ @@ -2914,7 +2914,7 @@ def __classcall_private__(cls, s, parts): """ if isinstance(s, (int, Integer)): s = list(range(1, s + 1)) - return super(SetPartitions_setparts, cls).__classcall__(cls, frozenset(s), Partition(parts)) + return super().__classcall__(cls, frozenset(s), Partition(parts)) def __init__(self, s, parts): """ @@ -3170,7 +3170,7 @@ def __classcall_private__(cls, s, k): sage: S1 is S2, S1 is S3 (True, True) """ - return super(SetPartitions_setn, cls).__classcall__(cls, frozenset(s), k) + return super().__classcall__(cls, frozenset(s), k) def __init__(self, s, k): """ diff --git a/src/sage/combinat/set_partition_ordered.py b/src/sage/combinat/set_partition_ordered.py index 9e648ed722e..f2f201eb7f2 100644 --- a/src/sage/combinat/set_partition_ordered.py +++ b/src/sage/combinat/set_partition_ordered.py @@ -1398,8 +1398,8 @@ def _coerce_map_from_(self, X): if X is self: return True if isinstance(X, OrderedSetPartitions): - return X._set == frozenset(range(1,len(X._set)+1)) - return super(OrderedSetPartitions_all, self)._coerce_map_from_(X) + return X._set == frozenset(range(1, len(X._set) + 1)) + return super()._coerce_map_from_(X) def _repr_(self): """ diff --git a/src/sage/combinat/sf/dual.py b/src/sage/combinat/sf/dual.py index 677a8dcfd3f..4ec49461f59 100644 --- a/src/sage/combinat/sf/dual.py +++ b/src/sage/combinat/sf/dual.py @@ -277,7 +277,7 @@ def _repr_(self): Dual basis to Symmetric Functions over Rational Field in the monomial basis with respect to the Hall scalar product """ if hasattr(self, "_basis"): - return super(SymmetricFunctionAlgebra_dual, self)._repr_() + return super()._repr_() if self._scalar_name: return "Dual basis to %s" % self._dual_basis + " with respect to the " + self._scalar_name else: diff --git a/src/sage/combinat/sf/schur.py b/src/sage/combinat/sf/schur.py index daa9ef79f85..e132b753e11 100644 --- a/src/sage/combinat/sf/schur.py +++ b/src/sage/combinat/sf/schur.py @@ -185,7 +185,7 @@ def _element_constructor_(self, x): try: return self.skew_schur(x) except ValueError: - return super(SymmetricFunctionAlgebra_schur, self)._element_constructor_(x) + return super()._element_constructor_(x) def _repeated_bernstein_creation_operator_on_basis(self, la, nu): r""" diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index d658eeb1898..d1fd77e8c69 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -2853,7 +2853,7 @@ def _latex_term(self, m): sage: latex(f) m_{1,1,1} + m_{2,1} + m_{3} """ - return super(SymmetricFunctionAlgebra_generic, self)._latex_term(','.join(str(i) for i in m)) + return super()._latex_term(','.join(str(i) for i in m)) def from_polynomial(self, poly, check=True): r""" @@ -5465,7 +5465,7 @@ def skew_by(self, x): TESTS:: - sage: f=s[3,2] + sage: f = s[3,2] sage: f.skew_by([1]) Traceback (most recent call last): ... diff --git a/src/sage/combinat/similarity_class_type.py b/src/sage/combinat/similarity_class_type.py index 8febf66ec03..234224eafd6 100644 --- a/src/sage/combinat/similarity_class_type.py +++ b/src/sage/combinat/similarity_class_type.py @@ -614,7 +614,7 @@ def __classcall_private__(cls, n, min=None): min = (min[0], Partition(min[1])) else: raise ValueError("min must be a PrimarySimilarityClassType") - return super(PrimarySimilarityClassTypes, cls).__classcall__(cls, n, min) + return super().__classcall__(cls, n, min) def __init__(self, n, min): r""" @@ -1027,7 +1027,7 @@ def __classcall_private__(cls, n, min=None): min = PrimarySimilarityClassType(min[0], min[1]) if not isinstance(min, PrimarySimilarityClassType): raise ValueError("min must be a PrimarySimilarityClassType") - return super(SimilarityClassTypes, cls).__classcall__(cls, n, min) + return super().__classcall__(cls, n, min) def __init__(self, n, min): r""" diff --git a/src/sage/combinat/six_vertex_model.py b/src/sage/combinat/six_vertex_model.py index 936a7e95b52..a3b28126923 100644 --- a/src/sage/combinat/six_vertex_model.py +++ b/src/sage/combinat/six_vertex_model.py @@ -8,6 +8,7 @@ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.combinat.combinatorial_map import combinatorial_map + class SixVertexConfiguration(ClonableArray): """ A configuration in the six vertex model. @@ -451,7 +452,7 @@ def __classcall_private__(cls, n, m=None, boundary_conditions=None): boundary_conditions = ((False,)*m, (True,)*n)*2 else: boundary_conditions = tuple(tuple(x) for x in boundary_conditions) - return super(SixVertexModel, cls).__classcall__(cls, n, m, boundary_conditions) + return super().__classcall__(cls, n, m, boundary_conditions) def __init__(self, n, m, boundary_conditions): """ diff --git a/src/sage/combinat/skew_partition.py b/src/sage/combinat/skew_partition.py index 80c6871d235..87ce705ae74 100644 --- a/src/sage/combinat/skew_partition.py +++ b/src/sage/combinat/skew_partition.py @@ -636,13 +636,14 @@ def is_overlap(self, n): def is_ribbon(self): r""" - Return ``True`` if and only if ``self`` is a ribbon, that is, - if it has exactly one cell in each of `q` consecutive - diagonals for some nonnegative integer `q`. + Return ``True`` if and only if ``self`` is a ribbon. + + This means that if it has exactly one cell in each of `q` + consecutive diagonals for some nonnegative integer `q`. EXAMPLES:: - sage: P=SkewPartition([[4,4,3,3],[3,2,2]]) + sage: P = SkewPartition([[4,4,3,3],[3,2,2]]) sage: P.pp() * ** @@ -651,7 +652,7 @@ def is_ribbon(self): sage: P.is_ribbon() True - sage: P=SkewPartition([[4,3,3],[1,1]]) + sage: P = SkewPartition([[4,3,3],[1,1]]) sage: P.pp() *** ** @@ -659,7 +660,7 @@ def is_ribbon(self): sage: P.is_ribbon() False - sage: P=SkewPartition([[4,4,3,2],[3,2,2]]) + sage: P = SkewPartition([[4,4,3,2],[3,2,2]]) sage: P.pp() * ** @@ -668,7 +669,7 @@ def is_ribbon(self): sage: P.is_ribbon() False - sage: P=SkewPartition([[4,4,3,3],[4,2,2,1]]) + sage: P = SkewPartition([[4,4,3,3],[4,2,2,1]]) sage: P.pp() ** @@ -677,7 +678,7 @@ def is_ribbon(self): sage: P.is_ribbon() True - sage: P=SkewPartition([[4,4,3,3],[4,2,2]]) + sage: P = SkewPartition([[4,4,3,3],[4,2,2]]) sage: P.pp() ** @@ -1575,6 +1576,7 @@ def __iter__(self): yield self.element_class(self, p) n += 1 + class SkewPartitions_n(SkewPartitions): """ The set of skew partitions of ``n`` with overlap at least @@ -1612,7 +1614,7 @@ def __classcall_private__(cls, n, overlap=0): """ if overlap == 'connected': overlap = 1 - return super(cls, SkewPartitions_n).__classcall__(cls, n, overlap) + return super().__classcall__(cls, n, overlap) def __init__(self, n, overlap): """ @@ -1823,7 +1825,7 @@ def __classcall_private__(cls, co, overlap=0): co = Compositions()(co) if overlap == 'connected': overlap = 1 - return super(SkewPartitions_rowlengths, cls).__classcall__(cls, co, overlap) + return super().__classcall__(cls, co, overlap) def __init__(self, co, overlap): """ diff --git a/src/sage/combinat/skew_tableau.py b/src/sage/combinat/skew_tableau.py index 906b86f2930..170d7630f72 100644 --- a/src/sage/combinat/skew_tableau.py +++ b/src/sage/combinat/skew_tableau.py @@ -1366,7 +1366,7 @@ def is_ribbon(self): EXAMPLES:: - sage: S=SkewTableau([[None, None, 1, 2],[None, None, 3],[1, 3, 4]]) + sage: S = SkewTableau([[None, None, 1, 2],[None, None, 3],[1, 3, 4]]) sage: S.pp() . . 1 2 . . 3 @@ -1374,7 +1374,7 @@ def is_ribbon(self): sage: S.is_ribbon() True - sage: S=SkewTableau([[None, 1, 1, 2],[None, 2, 3],[1, 3, 4]]) + sage: S = SkewTableau([[None, 1, 1, 2],[None, 2, 3],[1, 3, 4]]) sage: S.pp() . 1 1 2 . 2 3 @@ -1382,7 +1382,7 @@ def is_ribbon(self): sage: S.is_ribbon() False - sage: S=SkewTableau([[None, None, 1, 2],[None, None, 3],[1]]) + sage: S = SkewTableau([[None, None, 1, 2],[None, None, 3],[1]]) sage: S.pp() . . 1 2 . . 3 @@ -1390,7 +1390,7 @@ def is_ribbon(self): sage: S.is_ribbon() False - sage: S=SkewTableau([[None, None, None, None],[None, None, 3],[1, 2, 4]]) + sage: S = SkewTableau([[None, None, None, None],[None, None, 3],[1, 2, 4]]) sage: S.pp() . . . . . . 3 @@ -1398,7 +1398,7 @@ def is_ribbon(self): sage: S.is_ribbon() True - sage: S=SkewTableau([[None, None, None, None],[None, None, 3],[None, 2, 4]]) + sage: S = SkewTableau([[None, None, None, None],[None, None, 3],[None, 2, 4]]) sage: S.pp() . . . . . . 3 @@ -1406,13 +1406,12 @@ def is_ribbon(self): sage: S.is_ribbon() True - sage: S=SkewTableau([[None, None],[None]]) + sage: S = SkewTableau([[None, None],[None]]) sage: S.pp() . . . sage: S.is_ribbon() True - """ lam = list(self.outer_shape()) mu = list(self.inner_shape()) @@ -1422,31 +1421,31 @@ def is_ribbon(self): if l_out == 0: return True - else: - # Find the least u for which lam[u]>mu[u], if it exists. - # If it does not exist then u will equal l_out. - u = 0 - u_test = True - while u_test: - if u >= l_out or lam[u] > mu[u]: - u_test = False - else: - u += 1 - - # Find the least v strictly greater than u for which - # lam[v] != mu[v-1]+1 - v = u + 1 - v_test = True - while v_test: - if v >= l_out or lam[v] != mu[v - 1] + 1: - v_test = False - else: - v += 1 - # Check if lam[i]==mu[i] for all i >= v - for i in range(v, l_out): - if lam[i] != mu[i]: - return False + # Find the least u for which lam[u]>mu[u], if it exists. + # If it does not exist then u will equal l_out. + u = 0 + u_test = True + while u_test: + if u >= l_out or lam[u] > mu[u]: + u_test = False + else: + u += 1 + + # Find the least v strictly greater than u for which + # lam[v] != mu[v-1]+1 + v = u + 1 + v_test = True + while v_test: + if v >= l_out or lam[v] != mu[v - 1] + 1: + v_test = False + else: + v += 1 + + # Check if lam[i]==mu[i] for all i >= v + for i in range(v, l_out): + if lam[i] != mu[i]: + return False return True @@ -1990,7 +1989,7 @@ def __classcall_private__(cls, skp): sage: S is S2 True """ - return super(StandardSkewTableaux_shape, cls).__classcall__(cls, SkewPartition(skp)) + return super().__classcall__(cls, SkewPartition(skp)) def __init__(self, skp): """ @@ -2385,7 +2384,7 @@ def __classcall_private__(cls, n, mu): sage: S is S2 True """ - return super(SemistandardSkewTableaux_size_weight, cls).__classcall__(cls, n, tuple(mu)) + return super().__classcall__(cls, n, tuple(mu)) def __init__(self, n, mu): """ @@ -2465,7 +2464,7 @@ def __classcall_private__(cls, p, max_entry=None): """ if max_entry is None: max_entry = sum(p[0]) - sum(p[1]) - return super(SemistandardSkewTableaux_shape, cls).__classcall__(cls, SkewPartition(p), max_entry) + return super().__classcall__(cls, SkewPartition(p), max_entry) def __init__(self, p, max_entry): """ @@ -2544,7 +2543,7 @@ def __classcall_private__(cls, p, mu): """ p = SkewPartition(p) mu = tuple(mu) - return super(SemistandardSkewTableaux_shape_weight, cls).__classcall__(cls, p, mu) + return super().__classcall__(cls, p, mu) def __init__(self, p, mu): """ diff --git a/src/sage/combinat/subsets_pairwise.py b/src/sage/combinat/subsets_pairwise.py index aeceb704936..fc64df2e48f 100644 --- a/src/sage/combinat/subsets_pairwise.py +++ b/src/sage/combinat/subsets_pairwise.py @@ -79,14 +79,14 @@ class PairwiseCompatibleSubsets(RecursivelyEnumeratedSet_forest): lexicographic order. """ - #@staticmethod - #def __classcall__(cls, ambient, predicate): - # ambient = Set(ambient) - # return super(PairwiseCompatibleSubsets, cls).__classcall__(cls, ambient, predicate) + # @staticmethod + # def __classcall__(cls, ambient, predicate): + # ambient = Set(ambient) + # return super().__classcall__(cls, ambient, predicate) __len__ = None - def __init__(self, ambient, predicate, maximal = False, element_class = Set_object_enumerated): + def __init__(self, ambient, predicate, maximal=False, element_class=Set_object_enumerated): """ TESTS:: diff --git a/src/sage/combinat/subword_complex.py b/src/sage/combinat/subword_complex.py index 95d92c696cd..15af1d67ba0 100644 --- a/src/sage/combinat/subword_complex.py +++ b/src/sage/combinat/subword_complex.py @@ -1059,7 +1059,7 @@ def __classcall__(cls, Q, w, algorithm="inductive"): True """ Q = tuple(Q) - return super(SubwordComplex, cls).__classcall__(cls, Q, w, algorithm=algorithm) + return super().__classcall__(cls, Q, w, algorithm=algorithm) def __init__(self, Q, w, algorithm="inductive"): r""" diff --git a/src/sage/combinat/super_tableau.py b/src/sage/combinat/super_tableau.py index 07ab5e244b6..9be91778022 100644 --- a/src/sage/combinat/super_tableau.py +++ b/src/sage/combinat/super_tableau.py @@ -134,7 +134,7 @@ def __init__(self, parent, t, check=True, preprocessed=False): """ if not preprocessed: t = self._preprocess(t) - super(SemistandardSuperTableau, self).__init__(parent, t, check=check) + super().__init__(parent, t, check=check) @staticmethod def _preprocess(t): @@ -186,7 +186,7 @@ def check(self): ValueError: the entries of a semistandard super tableau must be non-negative primed integers """ - super(SemistandardSuperTableau, self).check() + super().check() for row in self: if not all(isinstance(c, PrimedEntry) and c > 0 for c in row): raise ValueError("the entries of a semistandard super tableau" @@ -299,7 +299,7 @@ def check(self): ValueError: the entries in each row of a semistandard super tableau must be weakly increasing """ - super(StandardSuperTableau, self).check() + super().check() # t is semistandard so we only need to check # that its entries are in bijection with {1',1,2', 2, ..., n} flattened_list = [i for row in self for i in row] @@ -737,8 +737,7 @@ def __init__(self, p): sage: TestSuite( StandardSuperTableaux([2,2,1]) ).run() """ - super(StandardSuperTableaux_shape, self).__init__( - category=FiniteEnumeratedSets()) + super().__init__(category=FiniteEnumeratedSets()) StandardSuperTableaux.__init__(self) self.shape = p diff --git a/src/sage/combinat/symmetric_group_algebra.py b/src/sage/combinat/symmetric_group_algebra.py index 603f4df9f3f..c3d67555a6b 100644 --- a/src/sage/combinat/symmetric_group_algebra.py +++ b/src/sage/combinat/symmetric_group_algebra.py @@ -368,7 +368,7 @@ def _coerce_map_from_(self, S): phi = S.to_symmetric_group_algebra return phi.codomain().canonical_embedding(self) * phi - return super(SymmetricGroupAlgebra_n, self)._coerce_map_from_(S) + return super()._coerce_map_from_(S) def _element_constructor_(self, x): """ @@ -392,7 +392,7 @@ def _element_constructor_(self, x): return self.monomial_from_smaller_permutation( from_permutation_group_element(x)) - return super(SymmetricGroupAlgebra_n, self)._element_constructor_(x) + return super()._element_constructor_(x) def _sibling(self, n): r""" @@ -757,7 +757,7 @@ def cell_module(self, la, **kwds): """ la = _Partitions(la) kwds['bracket'] = kwds.get('bracket', False) - return super(SymmetricGroupAlgebra_n, self).cell_module(la, **kwds) + return super().cell_module(la, **kwds) def retract_plain(self, f, m): r""" diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 834cfabe51d..4feabaacce0 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -220,7 +220,7 @@ def __init__(self, parent, t, check=True): sage: t = Tableaux()([[1,1],[1]]) sage: s = Tableaux(3)([[1,1],[1]]) - sage: s==t + sage: s == t True sage: t.parent() Tableaux @@ -1113,13 +1113,13 @@ def to_sign_matrix(self, max_entry=None): [ 0 0 0 1 0 0 0] [ 0 1 0 -1 1 0 0] [ 1 -1 1 0 -1 0 0] - sage: t=Tableau([(4,5,4,3),(2,1,3)]) + sage: t = Tableau([(4,5,4,3),(2,1,3)]) sage: t.to_sign_matrix(5) [ 0 0 1 0 0] [ 0 0 0 1 0] [ 1 0 -1 -1 1] [-1 1 0 1 -1] - sage: s=Tableau([(1,0,-2,4),(3,4,5)]) + sage: s = Tableau([(1,0,-2,4),(3,4,5)]) sage: s.to_sign_matrix(6) Traceback (most recent call last): ... @@ -1952,7 +1952,7 @@ def restrict(self, n): If possible the restricted tableau will belong to the same category as the original tableau:: - sage: S=StandardTableau([[1,2,4,7],[3,5],[6]]); S.category() + sage: S = StandardTableau([[1,2,4,7],[3,5],[6]]); S.category() Category of elements of Standard tableaux sage: S.restrict(4).category() Category of elements of Standard tableaux @@ -3938,15 +3938,15 @@ def first_row_descent(self): EXAMPLES:: - sage: t=Tableau([[1,3,2],[4]]); t.first_row_descent() + sage: t = Tableau([[1,3,2],[4]]); t.first_row_descent() (0, 1) sage: Tableau([[1,2,3],[4]]).first_row_descent() is None True """ for row in range(len(self)): for col in range(len(self[row])-1): - if self[row][col]>self[row][col+1]: - return (row,col) + if self[row][col] > self[row][col+1]: + return (row, col) return None def first_column_descent(self): @@ -4614,8 +4614,8 @@ def dominates(self, t): EXAMPLES:: - sage: s=StandardTableau([[1,2,3],[4,5]]) - sage: t=StandardTableau([[1,2],[3,5],[4]]) + sage: s = StandardTableau([[1,2,3],[4,5]]) + sage: t = StandardTableau([[1,2],[3,5],[4]]) sage: s.dominates(t) True sage: t.dominates(s) @@ -6112,7 +6112,7 @@ def __init__(self, max_entry=None): sage: T = sage.combinat.tableau.SemistandardTableaux_all() sage: TestSuite(T).run() - sage: T=sage.combinat.tableau.SemistandardTableaux_all(max_entry=3) + sage: T = sage.combinat.tableau.SemistandardTableaux_all(max_entry=3) sage: TestSuite(T).run() # long time """ if max_entry is not PlusInfinity(): diff --git a/src/sage/combinat/tableau_residues.py b/src/sage/combinat/tableau_residues.py index 021865daaaa..9f2748fa70c 100644 --- a/src/sage/combinat/tableau_residues.py +++ b/src/sage/combinat/tableau_residues.py @@ -265,7 +265,7 @@ def __init__(self, parent, residues, check): sage: TestSuite( ResidueSequence(3, [0,0,1,2])).run(skip='_test_pickling') """ residues = tuple(parent._base_ring(i) for i in residues) - super(ResidueSequence, self).__init__(parent, residues, check) + super().__init__(parent, residues, check) def check(self): r""" @@ -727,7 +727,7 @@ def __init__(self, e, multicharge=(0,)): self._quantum_characteristic = e self._base_ring = IntegerModRing(self._quantum_characteristic) self._multicharge = tuple(self._base_ring(i) for i in multicharge) - super(ResidueSequences, self).__init__(category=Sets()) + super().__init__(category=Sets()) def _repr_(self): r""" diff --git a/src/sage/combinat/tableau_tuple.py b/src/sage/combinat/tableau_tuple.py index 4425dcb4f27..34565ecb642 100644 --- a/src/sage/combinat/tableau_tuple.py +++ b/src/sage/combinat/tableau_tuple.py @@ -363,7 +363,7 @@ def __classcall_private__(self, t): EXAMPLES:: - sage: t=TableauTuple([[[1,1],[1]],[[1,1,1]],[[1],[1],[1]],[[1]]]) + sage: t = TableauTuple([[[1,1],[1]],[[1,1,1]],[[1],[1],[1]],[[1]]]) sage: t.parent() Tableau tuples sage: t.category() @@ -526,7 +526,7 @@ def _latex_(self): EXAMPLES:: - sage: t=TableauTuple([ [[1,2],[3]], [], [[4,5],[6,7]] ]) + sage: t = TableauTuple([ [[1,2],[3]], [], [[4,5],[6,7]] ]) sage: latex(t) # indirect doctest \Bigg( {\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}} \raisebox{-.6ex}{$\begin{array}[b]{*{2}c}\cline{1-2} @@ -1498,7 +1498,7 @@ def __classcall_private__(self, t): EXAMPLES:: - sage: t=RowStandardTableauTuple([[[3,4,6],[1]],[[2],[5]]]) + sage: t = RowStandardTableauTuple([[[3,4,6],[1]],[[2],[5]]]) sage: t.parent() Row standard tableau tuples sage: t.category() @@ -1769,8 +1769,8 @@ class StandardTableauTuple(RowStandardTableauTuple): is the size of the underlying partition tuple, such that the entries increase along rows and down columns in each component of the tuple. - sage: s=StandardTableauTuple([[1,2,3],[4,5]]) - sage: t=StandardTableauTuple([[1,2],[3,5],[4]]) + sage: s = StandardTableauTuple([[1,2,3],[4,5]]) + sage: t = StandardTableauTuple([[1,2],[3,5],[4]]) sage: s.dominates(t) True sage: t.dominates(s) @@ -1804,7 +1804,8 @@ class StandardTableauTuple(RowStandardTableauTuple): EXAMPLES:: - sage: t=TableauTuple([ [[1,3,4],[7,9]], [[2,8,11],[6]], [[5,10]] ]); t + sage: t = TableauTuple([ [[1,3,4],[7,9]], [[2,8,11],[6]], [[5,10]] ]) + sage: t ([[1, 3, 4], [7, 9]], [[2, 8, 11], [6]], [[5, 10]]) sage: t[0][0][0] 1 @@ -1884,7 +1885,7 @@ def __classcall_private__(self, t): EXAMPLES:: - sage: t=StandardTableauTuple([[[1,3,4],[6]],[[2],[5]]]) + sage: t = StandardTableauTuple([[[1,3,4],[6]],[[2],[5]]]) sage: t.parent() Standard tableau tuples sage: t.category() diff --git a/src/sage/combinat/tuple.py b/src/sage/combinat/tuple.py index 9b773e0be70..7e7f85c61ef 100644 --- a/src/sage/combinat/tuple.py +++ b/src/sage/combinat/tuple.py @@ -63,7 +63,7 @@ def __classcall_private__(cls, S, k): sage: T = Tuples(['l','i','t'],2); T Tuples of ('l', 'i', 't') of length 2 """ - return super(Tuples, cls).__classcall__(cls, tuple(S), k) + return super().__classcall__(cls, tuple(S), k) def __init__(self, S, k): """ @@ -166,7 +166,7 @@ def __classcall_private__(cls, S, k): sage: T = UnorderedTuples(['l','i','t'],2); T Unordered tuples of ('l', 'i', 't') of length 2 """ - return super(UnorderedTuples, cls).__classcall__(cls, tuple(S), k) + return super().__classcall__(cls, tuple(S), k) def __init__(self, S, k): """ diff --git a/src/sage/combinat/vector_partition.py b/src/sage/combinat/vector_partition.py index 49c9c25c2e4..953e450d8a1 100644 --- a/src/sage/combinat/vector_partition.py +++ b/src/sage/combinat/vector_partition.py @@ -200,7 +200,7 @@ class VectorPartitions(UniqueRepresentation, Parent): [[2, 2]] """ @staticmethod - def __classcall_private__(cls, vec, min = None): + def __classcall_private__(cls, vec, min=None): r""" Create the class of vector partitions of ``vec`` where all parts are greater than or equal to the vector ``min``. @@ -213,10 +213,10 @@ def __classcall_private__(cls, vec, min = None): True """ if min is None: - min = find_min(vec)#tuple([0 for v in vec[:-1]]+[1]) + min = find_min(vec) # tuple([0 for v in vec[:-1]]+[1]) min = tuple(min) vec = tuple(vec) - return super(VectorPartitions, cls).__classcall__(cls, tuple(vec), min) + return super().__classcall__(cls, tuple(vec), min) def __init__(self, vec, min): r""" @@ -227,7 +227,7 @@ def __init__(self, vec, min): sage: VP = VectorPartitions([2, 2]) sage: TestSuite(VP).run() """ - Parent.__init__(self, category = FiniteEnumeratedSets()) + Parent.__init__(self, category=FiniteEnumeratedSets()) self._vec = vec self._min = min diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index 3f5de242bf4..cc290129080 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -2373,7 +2373,7 @@ def longest_common_suffix(self, other): With an infinite word:: - sage: t=words.ThueMorseWord('ab') + sage: t = words.ThueMorseWord('ab') sage: w.longest_common_suffix(t) Traceback (most recent call last): ... diff --git a/src/sage/combinat/words/suffix_trees.py b/src/sage/combinat/words/suffix_trees.py index 1cfdb629213..fe36d4187cc 100644 --- a/src/sage/combinat/words/suffix_trees.py +++ b/src/sage/combinat/words/suffix_trees.py @@ -1729,7 +1729,7 @@ def _complete_labeling(self): EXAMPLES:: sage: from sage.combinat.words.suffix_trees import DecoratedSuffixTree - sage: w=Word('aabbaaba') + sage: w = Word('aabbaaba') sage: DecoratedSuffixTree(w)._complete_labeling() {(2, 7): [1], (5, 4): [1]} """ diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index 5cb363d248a..e7110609d63 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -222,13 +222,13 @@ def __init__(self, p, q, alphabet=(0,1), algorithm='cf'): w = u + v else: raise ValueError('Unknown algorithm (=%s)' % algorithm) - super(LowerChristoffelWord, self).__init__(FiniteWords(alphabet), w) + super().__init__(FiniteWords(alphabet), w) self.__p = p self.__q = q def markoff_number(self): r""" - Returns the Markoff number associated to the Christoffel word self. + Return the Markoff number associated to the Christoffel word ``self``. The *Markoff number* of a Christoffel word `w` is `trace(M(w))/3`, where `M(w)` is the `2\times 2` matrix obtained by applying the diff --git a/src/sage/combinat/yang_baxter_graph.py b/src/sage/combinat/yang_baxter_graph.py index 022ef775148..69fd04cbd04 100644 --- a/src/sage/combinat/yang_baxter_graph.py +++ b/src/sage/combinat/yang_baxter_graph.py @@ -586,7 +586,7 @@ def __init__(self, partition): root = sum([tuple(range(b)) for b in beta], tuple())[::-1] operators = [SwapIncreasingOperator(i) for i in range(sum(partition) - 1)] - super(YangBaxterGraph_partition, self).__init__(root, operators) + super().__init__(root, operators) def __repr__(self): r""" @@ -632,7 +632,7 @@ def _digraph(self): sage: Y.edges() [((0, 1, 0), (1, 0, 0), Swap positions 0 and 1)] """ - digraph = super(YangBaxterGraph_partition, self)._digraph + digraph = super()._digraph for (u, v, op) in digraph.edges(): digraph.set_edge_label(u, v, SwapOperator(op.position())) return digraph @@ -720,7 +720,7 @@ def vertex_relabelling_dict(self, v): (2, 0, 1, 0): (3, 4, 2, 1), (2, 1, 0, 0): (3, 2, 4, 1)} """ - return super(YangBaxterGraph_partition, self).vertex_relabelling_dict(v, self._swap_operator) + return super().vertex_relabelling_dict(v, self._swap_operator) def relabel_vertices(self, v, inplace=True): r""" diff --git a/src/sage/cpython/_py2_random.py b/src/sage/cpython/_py2_random.py index b1a4cf37ba9..745834f0cd1 100644 --- a/src/sage/cpython/_py2_random.py +++ b/src/sage/cpython/_py2_random.py @@ -471,7 +471,7 @@ def gammavariate(self, alpha, beta): Conditions on the parameters are alpha > 0 and beta > 0. - The probability distribution function is: + The probability distribution function is:: x ** (alpha - 1) * math.exp(-x / beta) pdf(x) = -------------------------------------- diff --git a/src/sage/data_structures/sparse_bitset.pxd b/src/sage/data_structures/sparse_bitset.pxd index ce1a0f0a468..742ac26c6a5 100644 --- a/src/sage/data_structures/sparse_bitset.pxd +++ b/src/sage/data_structures/sparse_bitset.pxd @@ -49,8 +49,7 @@ cdef struct sparse_bitset_s: # Storing the non zero positions can safe time, when performing # multiple comparisons. # E.g. one can set them while computing the intersection - # and then use those those to ``bitset_issubset`` many - # times in a row. + # and then use those to ``bitset_issubset`` many times in a row. # Any modification, will invalidate the already computed positions. # It is stored, whether the non zero chunks are correctly initialized diff --git a/src/sage/databases/findstat.py b/src/sage/databases/findstat.py index 2b04d96678e..ad1de8a0c3f 100644 --- a/src/sage/databases/findstat.py +++ b/src/sage/databases/findstat.py @@ -776,7 +776,7 @@ def _distribution_from_data(data, domain, max_values, generating_functions=False [1, 1, 2, 2, 3, 3])] """ lvl_dict = {} # lvl: elts, vals - total = min(max_values, FINDSTAT_MAX_VALUES) + total = max_values iterator = iter(data) levels_with_sizes = domain.levels_with_sizes() while total > 0: @@ -1937,7 +1937,8 @@ def _fetch_first_terms(self): return [(from_str(obj), Integer(val)) for obj, val in self._first_terms_raw_cache] - def _generating_functions_dict(self): + def _generating_functions_dict(self, + max_values=FINDSTAT_MAX_SUBMISSION_VALUES): r""" Return the generating functions of ``self`` as dictionary of dictionaries, computed from ``self.first_terms``. @@ -1952,10 +1953,14 @@ def _generating_functions_dict(self): lvls = {} domain = self.domain() levels_with_sizes = domain.levels_with_sizes() + total = 0 for elt, val in self.first_terms().items(): + if total == max_values: + break lvl = domain.element_level(elt) if lvl not in levels_with_sizes: continue + total += 1 if lvl not in gfs: gfs[lvl] = {} gfs[lvl][val] = gfs[lvl].get(val, 0) + 1 @@ -1966,7 +1971,8 @@ def _generating_functions_dict(self): del gfs[lvl] return gfs - def generating_functions(self, style="polynomial"): + def generating_functions(self, style="polynomial", + max_values=FINDSTAT_MAX_SUBMISSION_VALUES): r""" Return the generating functions of the statistic as a dictionary. @@ -2012,9 +2018,30 @@ def generating_functions(self, style="polynomial"): sage: st.generating_functions(style="list") # optional -- internet {2: [1], 4: [2, 1], 6: [5, 6, 3, 1], 8: [14, 28, 28, 20, 10, 4, 1]} - """ - return _generating_functions_from_dict(self._generating_functions_dict(), - style=style) + + TESTS:: + + sage: st = findstat(41) # optional -- internet + sage: st.generating_functions(max_values=19) # optional -- internet + {2: 1, 4: q + 2, 6: q^3 + 3*q^2 + 6*q + 5} + + sage: st = findstat("graphs", lambda G: G.size(), max_values=100) # optional -- internet + sage: st.generating_functions(max_values=18) # optional -- internet + {1: 1, + 2: q + 1, + 3: q^3 + q^2 + q + 1, + 4: q^6 + q^5 + 2*q^4 + 3*q^3 + 2*q^2 + q + 1} + sage: st.generating_functions(max_values=1252) # optional -- internet + {1: 1, + 2: q + 1, + 3: q^3 + q^2 + q + 1, + 4: q^6 + q^5 + 2*q^4 + 3*q^3 + 2*q^2 + q + 1, + 5: q^10 + q^9 + 2*q^8 + 4*q^7 + 6*q^6 + 6*q^5 + 6*q^4 + 4*q^3 + 2*q^2 + q + 1, + 6: q^15 + q^14 + 2*q^13 + 5*q^12 + 9*q^11 + 15*q^10 + 21*q^9 + 24*q^8 + 24*q^7 + 21*q^6 + 15*q^5 + 9*q^4 + 5*q^3 + 2*q^2 + q + 1, + 7: q^21 + q^20 + 2*q^19 + 5*q^18 + 10*q^17 + 21*q^16 + 41*q^15 + 65*q^14 + 97*q^13 + 131*q^12 + 148*q^11 + 148*q^10 + 131*q^9 + 97*q^8 + 65*q^7 + 41*q^6 + 21*q^5 + 10*q^4 + 5*q^3 + 2*q^2 + q + 1} + """ + d = self._generating_functions_dict(max_values=max_values) + return _generating_functions_from_dict(d, style) def oeis_search(self, search_size=32, verbose=True): r""" @@ -2651,7 +2678,8 @@ def _first_terms_raw(self, max_values): return [(to_str(obj), val) for obj, val in self.first_terms(max_values=max_values).items()] - def _generating_functions_dict(self, max_values=FINDSTAT_MAX_VALUES): + def _generating_functions_dict(self, + max_values=FINDSTAT_MAX_SUBMISSION_VALUES): """ Return the generating functions of the levels where all values can be determined. diff --git a/src/sage/databases/knotinfo_db.py b/src/sage/databases/knotinfo_db.py index 7d789b42229..21be7479ef4 100644 --- a/src/sage/databases/knotinfo_db.py +++ b/src/sage/databases/knotinfo_db.py @@ -162,8 +162,8 @@ class KnotInfoFilename(Enum): r""" Enum for the different data files. The following choices are possible: - - ``knots`` -- contains the the data from KnotInfo - - ``links`` -- contains the the data for proper links from LinkInfo + - ``knots`` -- contains the data from KnotInfo + - ``links`` -- contains the data for proper links from LinkInfo Examples:: diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index beccbeacf1f..db40b1e7b49 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -301,7 +301,7 @@ class Logger(): 'hello world\n' """ def __init__(self, *files): - """ + r""" Initialize the logger for writing to all files in ``files``. TESTS:: diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 07575dc2754..c814b81987a 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -5810,7 +5810,7 @@ def _is_preperiodic(self, P, err=0.1, return_period=False): # however precision issues can occur so we can only tell *not* preperiodic # if the value is larger than the error if h <= err: - # if the canonical height is less than than the + # if the canonical height is less than the # error, then we suspect preperiodic so check # either we can find the cycle or the height is # larger than the difference between the canonical height diff --git a/src/sage/functions/hyperbolic.py b/src/sage/functions/hyperbolic.py index 2ca5284f505..4487a3b3641 100644 --- a/src/sage/functions/hyperbolic.py +++ b/src/sage/functions/hyperbolic.py @@ -604,6 +604,7 @@ def __init__(self): GinacFunction.__init__(self, "arccoth", latex_name=r"\operatorname{arcoth}", conversions=dict(maxima='acoth', sympy='acoth', + mathematica='ArcCoth', giac='acoth', fricas='acoth')) def _eval_numpy_(self, x): @@ -649,6 +650,7 @@ def __init__(self): GinacFunction.__init__(self, "arcsech", latex_name=r"\operatorname{arsech}", conversions=dict(maxima='asech', sympy='asech', + mathematica='ArcSech', fricas='asech')) def _eval_numpy_(self, x): @@ -701,7 +703,9 @@ def __init__(self): """ GinacFunction.__init__(self, "arccsch", latex_name=r"\operatorname{arcsch}", - conversions=dict(maxima='acsch', sympy='acsch', fricas='acsch')) + conversions=dict(maxima='acsch', + mathematica='ArcCsch', + sympy='acsch', fricas='acsch')) def _eval_numpy_(self, x): """ diff --git a/src/sage/functions/piecewise.py b/src/sage/functions/piecewise.py index b9a5156c534..688db13a3b8 100644 --- a/src/sage/functions/piecewise.py +++ b/src/sage/functions/piecewise.py @@ -108,7 +108,7 @@ def __call__(self, function_pieces, **kwds): domain and a symbolic function. - ``var=x`` -- a symbolic variable or ``None`` (default). The - real variable in which the function is piecewise in. + real variable in which the function is piecewise in. OUTPUT: diff --git a/src/sage/functions/trig.py b/src/sage/functions/trig.py index a705648a8ce..fb97a5e8c58 100644 --- a/src/sage/functions/trig.py +++ b/src/sage/functions/trig.py @@ -738,6 +738,7 @@ def __init__(self): """ GinacFunction.__init__(self, 'arccot', latex_name=r"\operatorname{arccot}", conversions=dict(maxima='acot', sympy='acot', + mathematica='ArcCot', fricas='acot', giac='acot')) def _eval_numpy_(self, x): @@ -797,6 +798,7 @@ def __init__(self): """ GinacFunction.__init__(self, 'arccsc', latex_name=r"\operatorname{arccsc}", conversions=dict(maxima='acsc', sympy='acsc', + mathematica='ArcCsc', fricas='acsc', giac='acsc')) def _eval_numpy_(self, x): @@ -858,6 +860,7 @@ def __init__(self): """ GinacFunction.__init__(self, 'arcsec', latex_name=r"\operatorname{arcsec}", conversions=dict(maxima='asec', sympy='asec', + mathematica='ArcSec', fricas='asec', giac='asec')) def _eval_numpy_(self, x): diff --git a/src/sage/game_theory/normal_form_game.py b/src/sage/game_theory/normal_form_game.py index 2e27caa4a60..f1adc424e3e 100644 --- a/src/sage/game_theory/normal_form_game.py +++ b/src/sage/game_theory/normal_form_game.py @@ -1137,7 +1137,7 @@ def _gambit_(self, as_integer=False, maximization=True): { "" 3, 5, 8 } { "" 2, 6, 4 } } - 1 2 3 4 5 6 7 8 + 1 2 3 4 5 6 7 8 """ from decimal import Decimal diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index 94fd2008a7b..290c7ab0eda 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -1504,7 +1504,7 @@ def __init__(self, rays=None, lattice=None, True sage: TestSuite(sc).run() """ - superinit = super(ConvexRationalPolyhedralCone, self).__init__ + superinit = super().__init__ if ambient is None: superinit(rays, lattice) self._ambient = self @@ -1892,8 +1892,7 @@ def cartesian_product(self, other, lattice=None): in 2-d lattice N+N """ assert is_Cone(other) - rc = super(ConvexRationalPolyhedralCone, self).cartesian_product( - other, lattice) + rc = super().cartesian_product(other, lattice) return ConvexRationalPolyhedralCone(rc.rays(), rc.lattice()) def __neg__(self): @@ -1917,7 +1916,7 @@ def __neg__(self): N( 0, -1) in 2-d lattice N """ - rc = super(ConvexRationalPolyhedralCone, self).__neg__() + rc = super().__neg__() return ConvexRationalPolyhedralCone(rc.rays(), rc.lattice()) def __richcmp__(self, right, op): diff --git a/src/sage/geometry/fan.py b/src/sage/geometry/fan.py index fb9f2d08e84..2f84a662fdb 100644 --- a/src/sage/geometry/fan.py +++ b/src/sage/geometry/fan.py @@ -1047,8 +1047,8 @@ def __init__(self, ambient, ambient_ray_indices): 1-d cone of Rational polyhedral fan in 2-d lattice N sage: TestSuite(cone).run() # optional - palp """ - super(Cone_of_fan, self).__init__( - ambient=ambient, ambient_ray_indices=ambient_ray_indices) + super().__init__(ambient=ambient, + ambient_ray_indices=ambient_ray_indices) self._is_strictly_convex = True # Because if not, this cone should not have been constructed @@ -1207,7 +1207,7 @@ def __init__(self, cones, rays, lattice, sage: f = Fan([(0,)], [(0,1)]) sage: TestSuite(f).run() """ - super(RationalPolyhedralFan, self).__init__(rays, lattice) + super().__init__(rays, lattice) self._generating_cones = tuple(Cone_of_fan(self, c) for c in cones) for i, cone in enumerate(self._generating_cones): cone._star_generator_indices = (i,) @@ -1676,8 +1676,7 @@ def cartesian_product(self, other, lattice=None): 6 """ assert is_Fan(other) - rc = super(RationalPolyhedralFan, self).cartesian_product( - other, lattice) + rc = super().cartesian_product(other, lattice) self_cones = [cone.ambient_ray_indices() for cone in self] n = self.nrays() other_cones = [tuple(n + i for i in cone.ambient_ray_indices()) diff --git a/src/sage/geometry/fan_morphism.py b/src/sage/geometry/fan_morphism.py index 966947f0b22..d7ba7ac7ea6 100644 --- a/src/sage/geometry/fan_morphism.py +++ b/src/sage/geometry/fan_morphism.py @@ -287,7 +287,7 @@ def __init__(self, morphism, domain_fan, else: raise TypeError("morphism must be either a FreeModuleMorphism " "or a matrix!\nGot: %s" % morphism) - super(FanMorphism, self).__init__(parent, A) + super().__init__(parent, A) self._domain_fan = domain_fan self._image_cone = dict() self._preimage_cones = dict() diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_isometry.py b/src/sage/geometry/hyperbolic_space/hyperbolic_isometry.py index a524407fc4c..f6365aa90c5 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_isometry.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_isometry.py @@ -939,12 +939,11 @@ def __mul__(self, other): #PD Isometry in PD [ 5/8 3/8*I] [-3/8*I 5/8] - """ if isinstance(other, HyperbolicIsometry): - M = self._cached_isometry*other._cached_isometry + M = self._cached_isometry * other._cached_isometry return M.to_model('PD') - return super(HyperbolicIsometryPD, self).__mul__(other) + return super().__mul__(other) def __pow__(self, n): #PD r""" diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_model.py b/src/sage/geometry/hyperbolic_space/hyperbolic_model.py index 46e911e9a58..7890b222f37 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_model.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_model.py @@ -822,7 +822,7 @@ def _coerce_map_from_(self, X): return CoercionKMtoUHP(Hom(X, self)) if isinstance(X, HyperbolicModelHM): return CoercionHMtoUHP(Hom(X, self)) - return super(HyperbolicModelUHP, self)._coerce_map_from_(X) + return super()._coerce_map_from_(X) def point_in_model(self, p): r""" @@ -1200,7 +1200,7 @@ def _coerce_map_from_(self, X): return CoercionKMtoPD(Hom(X, self)) if isinstance(X, HyperbolicModelHM): return CoercionHMtoPD(Hom(X, self)) - return super(HyperbolicModelPD, self)._coerce_map_from_(X) + return super()._coerce_map_from_(X) def point_in_model(self, p): r""" @@ -1325,7 +1325,7 @@ def _coerce_map_from_(self, X): return CoercionPDtoKM(Hom(X, self)) if isinstance(X, HyperbolicModelHM): return CoercionHMtoKM(Hom(X, self)) - return super(HyperbolicModelKM, self)._coerce_map_from_(X) + return super()._coerce_map_from_(X) def point_in_model(self, p): r""" @@ -1448,7 +1448,7 @@ def _coerce_map_from_(self, X): return CoercionPDtoHM(Hom(X, self)) if isinstance(X, HyperbolicModelKM): return CoercionKMtoHM(Hom(X, self)) - return super(HyperbolicModelHM, self)._coerce_map_from_(X) + return super()._coerce_map_from_(X) def point_in_model(self, p): r""" diff --git a/src/sage/geometry/hyperplane_arrangement/arrangement.py b/src/sage/geometry/hyperplane_arrangement/arrangement.py index e83b6aeacd7..5b2534677a1 100644 --- a/src/sage/geometry/hyperplane_arrangement/arrangement.py +++ b/src/sage/geometry/hyperplane_arrangement/arrangement.py @@ -403,7 +403,7 @@ def __init__(self, parent, hyperplanes, check=True, backend=None): sage: A.regions()[0].backend() # optional - pynormaliz # optional - sage.rings.number_field 'normaliz' """ - super(HyperplaneArrangementElement, self).__init__(parent) + super().__init__(parent) self._hyperplanes = hyperplanes self._backend = backend if check: @@ -3423,7 +3423,7 @@ def __init__(self, base_ring, names=tuple()): from sage.rings.ring import _Fields if base_ring not in _Fields: raise ValueError('base ring must be a field') - super(HyperplaneArrangements, self).__init__(category=Sets()) + super().__init__(category=Sets()) self._base_ring = base_ring self._names = names @@ -3690,4 +3690,4 @@ def _coerce_map_from_(self, P): return True if isinstance(P, HyperplaneArrangements): return self.base_ring().has_coerce_map_from(P.base_ring()) - return super(HyperplaneArrangements, self)._coerce_map_from_(P) + return super()._coerce_map_from_(P) diff --git a/src/sage/geometry/hyperplane_arrangement/hyperplane.py b/src/sage/geometry/hyperplane_arrangement/hyperplane.py index 146cf2db80a..378ffaf9c5c 100644 --- a/src/sage/geometry/hyperplane_arrangement/hyperplane.py +++ b/src/sage/geometry/hyperplane_arrangement/hyperplane.py @@ -160,7 +160,7 @@ def __init__(self, parent, coefficients, constant): Hyperplane 1.00000000000000*x + 0.000000000000000*y + 0.000000000000000 sage: TestSuite(x+y-1).run() """ - super(Hyperplane, self).__init__(parent, coefficients, constant) + super().__init__(parent, coefficients, constant) def _repr_(self): """ diff --git a/src/sage/geometry/linear_expression.py b/src/sage/geometry/linear_expression.py index dbe09170c4c..7f4a91b3194 100644 --- a/src/sage/geometry/linear_expression.py +++ b/src/sage/geometry/linear_expression.py @@ -88,7 +88,7 @@ def __init__(self, parent, coefficients, constant, check=True): sage: TestSuite(linear).run() """ - super(LinearExpression, self).__init__(parent) + super().__init__(parent) self._coeffs = coefficients self._const = constant if check: @@ -490,7 +490,7 @@ def __init__(self, base_ring, names=tuple()): sage: TestSuite(L).run() """ from sage.categories.modules import Modules - super(LinearExpressionModule, self).__init__(base_ring, category=Modules(base_ring).WithBasis().FiniteDimensional()) + super().__init__(base_ring, category=Modules(base_ring).WithBasis().FiniteDimensional()) self._names = names @cached_method @@ -746,7 +746,7 @@ def _coerce_map_from_(self, P): self.base().has_coerce_map_from(P.base()) except AttributeError: pass - return super(LinearExpressionModule, self)._coerce_map_from_(P) + return super()._coerce_map_from_(P) def _repr_(self): """ diff --git a/src/sage/geometry/point_collection.pyx b/src/sage/geometry/point_collection.pyx index 2769f24e3fc..fcfb45b1d9b 100644 --- a/src/sage/geometry/point_collection.pyx +++ b/src/sage/geometry/point_collection.pyx @@ -166,7 +166,7 @@ cdef class PointCollection(SageObject): over the principal ideal domain Integer Ring sage: TestSuite(c).run() """ - super(PointCollection, self).__init__() + super().__init__() self._points = tuple(points) self._module = self._points[0].parent() if module is None else module diff --git a/src/sage/geometry/polyhedron/backend_cdd.py b/src/sage/geometry/polyhedron/backend_cdd.py index e7f9afbf8e3..442aabbd328 100644 --- a/src/sage/geometry/polyhedron/backend_cdd.py +++ b/src/sage/geometry/polyhedron/backend_cdd.py @@ -244,19 +244,19 @@ def _init_from_cdd_output(self, cddout): Check that :trac:`31253` is fixed:: - sage: P = polytopes.permutahedron(2, backend='cdd') - sage: P.Hrepresentation() - (An inequality (0, 1) x - 1 >= 0, - An inequality (1, 0) x - 1 >= 0, - An equation (1, 1) x - 3 == 0) - sage: Q = Polyhedron(P.vertices(), backend='cdd') - sage: Q.Hrepresentation() - (An inequality (-1, 0) x + 2 >= 0, - An inequality (1, 0) x - 1 >= 0, - An equation (1, 1) x - 3 == 0) - sage: [x.ambient_Hrepresentation() for x in P.facets()] - [(An inequality (1, 0) x - 1 >= 0, An equation (1, 1) x - 3 == 0), - (An inequality (0, 1) x - 1 >= 0, An equation (1, 1) x - 3 == 0)] + sage: P = polytopes.permutahedron(2, backend='cdd') + sage: P.Hrepresentation() + (An inequality (0, 1) x - 1 >= 0, + An inequality (1, 0) x - 1 >= 0, + An equation (1, 1) x - 3 == 0) + sage: Q = Polyhedron(P.vertices(), backend='cdd') + sage: Q.Hrepresentation() + (An inequality (-1, 0) x + 2 >= 0, + An inequality (1, 0) x - 1 >= 0, + An equation (1, 1) x - 3 == 0) + sage: [x.ambient_Hrepresentation() for x in P.facets()] + [(An inequality (1, 0) x - 1 >= 0, An equation (1, 1) x - 3 == 0), + (An inequality (0, 1) x - 1 >= 0, An equation (1, 1) x - 3 == 0)] """ cddout = cddout.splitlines() diff --git a/src/sage/geometry/polyhedron/backend_field.py b/src/sage/geometry/polyhedron/backend_field.py index 4ddf271143e..6b921d23a68 100644 --- a/src/sage/geometry/polyhedron/backend_field.py +++ b/src/sage/geometry/polyhedron/backend_field.py @@ -330,4 +330,4 @@ def _init_empty_polyhedron(self): The empty polyhedron in QQ^0 sage: Polyhedron(backend='field')._init_empty_polyhedron() """ - super(Polyhedron_field, self)._init_empty_polyhedron() + super()._init_empty_polyhedron() diff --git a/src/sage/geometry/polyhedron/backend_normaliz.py b/src/sage/geometry/polyhedron/backend_normaliz.py index b22f92d4091..4b5902da342 100644 --- a/src/sage/geometry/polyhedron/backend_normaliz.py +++ b/src/sage/geometry/polyhedron/backend_normaliz.py @@ -1050,7 +1050,7 @@ def _init_empty_polyhedron(self): The empty polyhedron in ZZ^0 sage: Polyhedron(backend='normaliz')._init_empty_polyhedron() # optional - pynormaliz """ - super(Polyhedron_normaliz, self)._init_empty_polyhedron() + super()._init_empty_polyhedron() # Can't seem to set up an empty _normaliz_cone. # For example, PyNormaliz.NmzCone(vertices=[]) gives # error: Some error in the normaliz input data detected: All input matrices empty! @@ -1237,7 +1237,7 @@ def __copy__(self): sage: P._normaliz_cone is Q._normaliz_cone # optional - pynormaliz False """ - other = super(Polyhedron_normaliz, self).__copy__() + other = super().__copy__() # Make a copy of the cone. cone = self._normaliz_cone @@ -1251,32 +1251,32 @@ def __getstate__(self): TESTS:: - sage: P = polytopes.simplex(backend='normaliz') # optional - pynormaliz - sage: P.__getstate__() # optional - pynormaliz - (Polyhedra in ZZ^4, - {'_Hrepresentation': (An inequality (0, 0, 0, 1) x + 0 >= 0, - An inequality (0, 0, 1, 0) x + 0 >= 0, - An inequality (0, 1, 0, 0) x + 0 >= 0, - An inequality (1, 0, 0, 0) x + 0 >= 0, - An equation (1, 1, 1, 1) x - 1 == 0), - '_Vrepresentation': (A vertex at (0, 0, 0, 1), - A vertex at (0, 0, 1, 0), - A vertex at (0, 1, 0, 0), - A vertex at (1, 0, 0, 0)), - '_normaliz_field': Rational Field, - '_pickle_equations': [(-1, 1, 1, 1, 1)], - '_pickle_inequalities': [(0, 0, 0, 0, 1), - (0, 0, 0, 1, 0), - (0, 0, 1, 0, 0), - (0, 1, 0, 0, 0)], - '_pickle_lines': [], - '_pickle_rays': [], - '_pickle_vertices': [(0, 0, 0, 1), - (0, 0, 1, 0), - (0, 1, 0, 0), - (1, 0, 0, 0)]}) + sage: P = polytopes.simplex(backend='normaliz') # optional - pynormaliz + sage: P.__getstate__() # optional - pynormaliz + (Polyhedra in ZZ^4, + {'_Hrepresentation': (An inequality (0, 0, 0, 1) x + 0 >= 0, + An inequality (0, 0, 1, 0) x + 0 >= 0, + An inequality (0, 1, 0, 0) x + 0 >= 0, + An inequality (1, 0, 0, 0) x + 0 >= 0, + An equation (1, 1, 1, 1) x - 1 == 0), + '_Vrepresentation': (A vertex at (0, 0, 0, 1), + A vertex at (0, 0, 1, 0), + A vertex at (0, 1, 0, 0), + A vertex at (1, 0, 0, 0)), + '_normaliz_field': Rational Field, + '_pickle_equations': [(-1, 1, 1, 1, 1)], + '_pickle_inequalities': [(0, 0, 0, 0, 1), + (0, 0, 0, 1, 0), + (0, 0, 1, 0, 0), + (0, 1, 0, 0, 0)], + '_pickle_lines': [], + '_pickle_rays': [], + '_pickle_vertices': [(0, 0, 0, 1), + (0, 0, 1, 0), + (0, 1, 0, 0), + (1, 0, 0, 0)]}) """ - state = super(Polyhedron_normaliz, self).__getstate__() + state = super().__getstate__() state = (state[0], state[1].copy()) # Remove the unpicklable entries. del state[1]['_normaliz_cone'] @@ -1349,7 +1349,7 @@ def __setstate__(self, state): else: vertices = None - super(Polyhedron_normaliz, self).__setstate__(state) + super().__setstate__(state) if self.is_empty(): # Special case to avoid. @@ -1495,7 +1495,7 @@ def _volume_normaliz(self, measure='euclidean'): sage: cube._volume_normaliz(measure='induced_lattice') # optional - pynormaliz 6 - Or one can can calculate the ambient volume, which is the above multiplied by the + Or one can calculate the ambient volume, which is the above multiplied by the volume of the unimodular simplex (or zero if not full-dimensional):: sage: cube._volume_normaliz(measure='ambient') # optional - pynormaliz @@ -2248,8 +2248,8 @@ def _Hstar_function_normaliz(self, acting_group=None, output=None): - ``acting_group`` -- (default=None) a permgroup object. A subgroup of ``self``'s ``restricted_automorphism_group`` output as a permutation. - If ``None``, it is set to the full ``restricted_automorphism_group`` - of ``self``. The acting group should always use output='permutation'. + If ``None``, it is set to the full ``restricted_automorphism_group`` + of ``self``. The acting group should always use output='permutation'. - ``output`` -- string. an output option. The allowed values are: diff --git a/src/sage/geometry/polyhedron/backend_polymake.py b/src/sage/geometry/polyhedron/backend_polymake.py index 776cb613074..97dfdc2c63e 100644 --- a/src/sage/geometry/polyhedron/backend_polymake.py +++ b/src/sage/geometry/polyhedron/backend_polymake.py @@ -592,8 +592,7 @@ def _polymake_(self, polymake): if self._polymake_polytope.parent() is polymake: # Same polymake interface, can just return our object return self._polymake_polytope - else: - return super(Polyhedron_polymake, self)._polymake_(polymake) + return super()._polymake_(polymake) def __getstate__(self): r""" @@ -601,29 +600,29 @@ def __getstate__(self): TESTS:: - sage: P = polytopes.simplex(backend='polymake') # optional - polymake - sage: P.__getstate__() # optional - polymake - (Polyhedra in QQ^4, - {'_Hrepresentation': (An inequality (0, -1, -1, -1) x + 1 >= 0, - An inequality (0, 1, 0, 0) x + 0 >= 0, - An inequality (0, 0, 1, 0) x + 0 >= 0, - An inequality (0, 0, 0, 1) x + 0 >= 0, - An equation (1, 1, 1, 1) x - 1 == 0), - '_Vrepresentation': (A vertex at (1, 0, 0, 0), - A vertex at (0, 1, 0, 0), - A vertex at (0, 0, 1, 0), - A vertex at (0, 0, 0, 1)), - '_pickle_equations': [(-1, 1, 1, 1, 1)], - '_pickle_inequalities': [(1, 0, -1, -1, -1), - (0, 0, 1, 0, 0), - (0, 0, 0, 1, 0), - (0, 0, 0, 0, 1)], - '_pickle_lines': [], - '_pickle_rays': [], - '_pickle_vertices': [(1, 0, 0, 0), - (0, 1, 0, 0), - (0, 0, 1, 0), - (0, 0, 0, 1)]}) + sage: P = polytopes.simplex(backend='polymake') # optional - polymake + sage: P.__getstate__() # optional - polymake + (Polyhedra in QQ^4, + {'_Hrepresentation': (An inequality (0, -1, -1, -1) x + 1 >= 0, + An inequality (0, 1, 0, 0) x + 0 >= 0, + An inequality (0, 0, 1, 0) x + 0 >= 0, + An inequality (0, 0, 0, 1) x + 0 >= 0, + An equation (1, 1, 1, 1) x - 1 == 0), + '_Vrepresentation': (A vertex at (1, 0, 0, 0), + A vertex at (0, 1, 0, 0), + A vertex at (0, 0, 1, 0), + A vertex at (0, 0, 0, 1)), + '_pickle_equations': [(-1, 1, 1, 1, 1)], + '_pickle_inequalities': [(1, 0, -1, -1, -1), + (0, 0, 1, 0, 0), + (0, 0, 0, 1, 0), + (0, 0, 0, 0, 1)], + '_pickle_lines': [], + '_pickle_rays': [], + '_pickle_vertices': [(1, 0, 0, 0), + (0, 1, 0, 0), + (0, 0, 1, 0), + (0, 0, 0, 1)]}) """ state = super().__getstate__() state = (state[0], state[1].copy()) diff --git a/src/sage/geometry/polyhedron/backend_ppl.py b/src/sage/geometry/polyhedron/backend_ppl.py index 4315d202c57..1caafb52a93 100644 --- a/src/sage/geometry/polyhedron/backend_ppl.py +++ b/src/sage/geometry/polyhedron/backend_ppl.py @@ -405,7 +405,7 @@ def _init_empty_polyhedron(self): The empty polyhedron in ZZ^0 sage: Polyhedron(backend='ppl')._init_empty_polyhedron() """ - super(Polyhedron_ppl, self)._init_empty_polyhedron() + super()._init_empty_polyhedron() self._ppl_polyhedron = C_Polyhedron(self.ambient_dim(), 'empty') @staticmethod diff --git a/src/sage/geometry/polyhedron/base3.py b/src/sage/geometry/polyhedron/base3.py index c6288b5cef2..ff144d04e39 100644 --- a/src/sage/geometry/polyhedron/base3.py +++ b/src/sage/geometry/polyhedron/base3.py @@ -1100,7 +1100,7 @@ def a_maximal_chain(self): sage: [face.ambient_V_indices() for face in chain] [(), (5,), (0, 5), (0, 3, 4, 5), (0, 1, 2, 3, 4, 5, 6, 7)] - TESTS:: + TESTS: Check output for the empty polyhedron:: diff --git a/src/sage/geometry/polyhedron/base_ZZ.py b/src/sage/geometry/polyhedron/base_ZZ.py index cfb62d03834..07c7bbd6a4c 100644 --- a/src/sage/geometry/polyhedron/base_ZZ.py +++ b/src/sage/geometry/polyhedron/base_ZZ.py @@ -48,8 +48,7 @@ def __getattribute__(self, name): """ if name in ['ehrhart_quasipolynomial']: raise AttributeError(name) - else: - return super(Polyhedron_ZZ, self).__getattribute__(name) + return super().__getattribute__(name) def __dir__(self): r""" diff --git a/src/sage/geometry/polyhedron/constructor.py b/src/sage/geometry/polyhedron/constructor.py index a0ff5a08ae7..66a6036ee47 100644 --- a/src/sage/geometry/polyhedron/constructor.py +++ b/src/sage/geometry/polyhedron/constructor.py @@ -207,7 +207,7 @@ Be careful when you construct polyhedra with floating point numbers. The only available backend for such computation is ``cdd`` which uses machine floating - point numbers which have have limited precision. If the input consists of + point numbers which have limited precision. If the input consists of floating point numbers and the ``base_ring`` is not specified, the base ring is set to be the ``RealField`` with the precision given by the minimal bit precision of the input. Then, if the obtained minimum is 53 bits of precision, the diff --git a/src/sage/geometry/polyhedron/double_description_inhomogeneous.py b/src/sage/geometry/polyhedron/double_description_inhomogeneous.py index 068c3317434..9b7882a5bcd 100644 --- a/src/sage/geometry/polyhedron/double_description_inhomogeneous.py +++ b/src/sage/geometry/polyhedron/double_description_inhomogeneous.py @@ -199,7 +199,7 @@ def __init__(self, base_ring, dim, inequalities, equations): [0||1 0] [0||0 1] """ - super(Hrep2Vrep, self).__init__(base_ring, dim) + super().__init__(base_ring, dim) inequalities = [list(x) for x in inequalities] equations = [list(x) for x in equations] if not inequalities and not equations: @@ -442,7 +442,7 @@ def __init__(self, base_ring, dim, vertices, rays, lines): sage: Vrep2Hrep(QQ, 2, [(-1/2,0)], [], [(1,-2/3), (1,0)]) [] """ - super(Vrep2Hrep, self).__init__(base_ring, dim) + super().__init__(base_ring, dim) if rays or lines: assert len(vertices) > 0 if not vertices and not rays and not lines: diff --git a/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py b/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py index cd97821a951..6255650b84f 100644 --- a/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py +++ b/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py @@ -92,11 +92,11 @@ def __classcall__(cls, base_ring, dimension, basis, category=None): raise TypeError(f"{P} does not belong to the ambient space") if category is None: category = GradedModulesWithBasis(base_ring) - return super(FormalPolyhedraModule, cls).__classcall__(cls, - base_ring=base_ring, - dimension=dimension, - basis=basis, - category=category) + return super().__classcall__(cls, + base_ring=base_ring, + dimension=dimension, + basis=basis, + category=category) def __init__(self, base_ring, dimension, basis, category): """ @@ -113,7 +113,7 @@ def __init__(self, base_ring, dimension, basis, category): sage: M = FormalPolyhedraModule(QQ, 1, basis=[I01, I11, I12, I02]) sage: TestSuite(M).run() """ - super(FormalPolyhedraModule, self).__init__(base_ring, basis, prefix="", category=category) + super().__init__(base_ring, basis, prefix="", category=category) def degree_on_basis(self, m): r""" diff --git a/src/sage/geometry/ribbon_graph.py b/src/sage/geometry/ribbon_graph.py index 3d3502d16b8..60375b20ce2 100644 --- a/src/sage/geometry/ribbon_graph.py +++ b/src/sage/geometry/ribbon_graph.py @@ -299,7 +299,7 @@ def __classcall_private__(cls, sigma, rho, bipartite=False): M = sigma.parent() if len(M.domain()) < len(rho.parent().domain()): M = rho.parent() - return super(RibbonGraph, cls).__classcall__(cls, M(sigma), M(rho)) + return super().__classcall__(cls, M(sigma), M(rho)) def __init__(self, sigma, rho): r""" diff --git a/src/sage/geometry/toric_lattice_element.pyx b/src/sage/geometry/toric_lattice_element.pyx index 68265734f8a..0c8ff89b36c 100644 --- a/src/sage/geometry/toric_lattice_element.pyx +++ b/src/sage/geometry/toric_lattice_element.pyx @@ -342,7 +342,7 @@ cdef class ToricLatticeElement(Vector_integer_dense): sage: e._latex_() '\\left(1,\\,2,\\,3\\right)_{L^*}' """ - return "%s_{%s}" % (super(ToricLatticeElement, self)._latex_(), + return "%s_{%s}" % (super()._latex_(), self.parent().ambient_module()._latex_name) def _repr_(self): @@ -361,7 +361,7 @@ cdef class ToricLatticeElement(Vector_integer_dense): 'L*(1, 2, 3)' """ return (self.parent().ambient_module()._name - + super(ToricLatticeElement, self)._repr_()) + + super()._repr_()) def __reduce__(self): """ diff --git a/src/sage/geometry/toric_plotter.py b/src/sage/geometry/toric_plotter.py index 923fb43440d..988c180431a 100644 --- a/src/sage/geometry/toric_plotter.py +++ b/src/sage/geometry/toric_plotter.py @@ -198,7 +198,7 @@ def __init__(self, all_options, dimension, generators=None): sage: tp = ToricPlotter(dict(), 2) sage: TestSuite(tp).run() """ - super(ToricPlotter, self).__init__() + super().__init__() sd = self.__dict__ extra_options = dict() self.extra_options = extra_options diff --git a/src/sage/geometry/triangulation/point_configuration.py b/src/sage/geometry/triangulation/point_configuration.py index 6928f80ba18..db8d5a89092 100644 --- a/src/sage/geometry/triangulation/point_configuration.py +++ b/src/sage/geometry/triangulation/point_configuration.py @@ -326,9 +326,8 @@ def __classcall__(cls, points, projective=False, connected=True, fine=False, reg if len(star_point) # # 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 libc.stdint cimport uint32_t from cysignals.signals cimport sig_on, sig_off @@ -67,6 +67,7 @@ from memory_allocator cimport MemoryAllocator from sage.data_structures.bitset_base cimport * from sage.graphs.base.static_sparse_graph cimport short_digraph, init_short_digraph, free_short_digraph + def is_asteroidal_triple_free(G, certificate=False): """ Test if the input graph is asteroidal triple-free @@ -137,8 +138,8 @@ def is_asteroidal_triple_free(G, certificate=False): # ==> Initialize some data structures for is_asteroidal_triple_free_C cdef MemoryAllocator mem = MemoryAllocator() - cdef uint32_t* waiting_list = mem.allocarray(n, sizeof(uint32_t)) - cdef uint32_t* _connected_structure = mem.calloc(n * n, sizeof(uint32_t)) + cdef uint32_t* waiting_list = mem.allocarray(n, sizeof(uint32_t)) + cdef uint32_t* _connected_structure = mem.calloc(n * n, sizeof(uint32_t)) cdef uint32_t** connected_structure = mem.allocarray(n, sizeof(uint32_t*)) # Copying the whole graph to obtain the list of neighbors quicker than by @@ -182,7 +183,7 @@ def is_asteroidal_triple_free(G, certificate=False): cdef list is_asteroidal_triple_free_C(uint32_t n, short_digraph sd, uint32_t** connected_structure, - uint32_t* waiting_list, + uint32_t* waiting_list, bitset_t seen): """ INPUT: @@ -206,8 +207,8 @@ cdef list is_asteroidal_triple_free_C(uint32_t n, See the module's documentation. """ cdef uint32_t waiting_beginning = 0 - cdef uint32_t waiting_end = 0 - cdef uint32_t idx_cc = 0 + cdef uint32_t waiting_end = 0 + cdef uint32_t idx_cc = 0 cdef uint32_t source, u, v, w cdef uint32_t* p_tmp cdef uint32_t* end @@ -288,8 +289,8 @@ cdef list is_asteroidal_triple_free_C(uint32_t n, if connected_structure[u][v]: for w in range(v + 1, n): if (connected_structure[u][v] == connected_structure[u][w] and - connected_structure[v][u] == connected_structure[v][w] and - connected_structure[w][u] == connected_structure[w][v]): + connected_structure[v][u] == connected_structure[v][w] and + connected_structure[w][u] == connected_structure[w][v]): # We have found an asteroidal triple return [u, v, w] diff --git a/src/sage/graphs/base/c_graph.pyx b/src/sage/graphs/base/c_graph.pyx index 2bf83ab294e..f2d3a8cfd52 100644 --- a/src/sage/graphs/base/c_graph.pyx +++ b/src/sage/graphs/base/c_graph.pyx @@ -53,9 +53,11 @@ from sage.rings.integer_ring import ZZ from cysignals.memory cimport check_allocarray, sig_free from sage.data_structures.bitset cimport FrozenBitset + cdef extern from "Python.h": int unlikely(int) nogil # Defined by Cython + cdef class CGraph: """ Compiled sparse and dense graphs. @@ -327,7 +329,7 @@ cdef class CGraph: "requested vertex is past twice the allocated range: " "use realloc") if (k >= self.active_vertices.size or - (k == -1 and self.active_vertices.size == self.num_verts)): + (k == -1 and self.active_vertices.size == self.num_verts)): self.realloc(2 * self.active_vertices.size) return self.add_vertex_unsafe(k) @@ -521,7 +523,6 @@ cdef class CGraph: if self.has_vertex(v): self.del_vertex_unsafe(v) - cpdef int current_allocation(self): r""" Report the number of vertices allocated. @@ -1003,7 +1004,7 @@ cdef class CGraph: self.check_vertex(v) if l < 0: raise ValueError("Label ({0}) must be a nonnegative integer.".format(l)) - self.del_arc_label_unsafe(u,v,l) + self.del_arc_label_unsafe(u, v, l) cpdef bint has_arc_label(self, int u, int v, int l): """ @@ -1035,7 +1036,7 @@ cdef class CGraph: self.check_vertex(v) if l < 0: raise ValueError("Label ({0}) must be a nonnegative integer.".format(l)) - return self.has_arc_label_unsafe(u,v,l) == 1 + return self.has_arc_label_unsafe(u, v, l) == 1 ################################### # Neighbor Functions @@ -1603,9 +1604,8 @@ cdef class CGraphBackend(GenericGraphBackend): sage: G.add_vertices(A) sage: Set(G.vertices()) == A True - """ - cdef dict vertex_ints = self.vertex_ints + cdef dict vertex_ints = self.vertex_ints cdef dict vertex_labels = self.vertex_labels cdef CGraph G = self.cg() cdef long u_long @@ -1735,9 +1735,9 @@ cdef class CGraphBackend(GenericGraphBackend): retval = None if name is None: name = 0 - while name in self.vertex_ints or ( - name not in self.vertex_labels and - bitset_in(self.cg().active_vertices, name)): + while (name in self.vertex_ints or + (name not in self.vertex_labels and + bitset_in(self.cg().active_vertices, name))): name += 1 retval = name @@ -1921,8 +1921,8 @@ cdef class CGraphBackend(GenericGraphBackend): i = bitset_first(self.cg().active_vertices) while i != -1: if (i not in self.vertex_labels - and i not in self.vertex_ints): - yield i + and i not in self.vertex_ints): + yield i i = bitset_next(self.cg().active_vertices, i + 1) return @@ -2345,16 +2345,16 @@ cdef class CGraphBackend(GenericGraphBackend): (5, 6, None)] """ - cdef object u,v,l,e + cdef object u, v, l, e for e in edges: if len(e) == 3: - u,v,l = e + u, v, l = e else: - u,v = e + u, v = e l = None if unlikely(remove_loops and u == v): continue - self.add_edge(u,v,l,directed) + self.add_edge(u, v, l, directed) cpdef add_edge(self, object u, object v, object l, bint directed): """ @@ -2428,8 +2428,10 @@ cdef class CGraphBackend(GenericGraphBackend): sage: D.shortest_path(1, 2) [] """ - if u is None: u = self.add_vertex(None) - if v is None: v = self.add_vertex(None) + if u is None: + u = self.add_vertex(None) + if v is None: + v = self.add_vertex(None) cdef int u_int = self.check_labelled_vertex(u, False) cdef int v_int = self.check_labelled_vertex(v, False) @@ -2477,14 +2479,14 @@ cdef class CGraphBackend(GenericGraphBackend): [] """ - cdef object u,v,l,e + cdef object u, v, l, e for e in edges: if len(e) == 3: - u,v,l = e + u, v, l = e else: - u,v = e + u, v = e l = None - self.del_edge(u,v,l,directed) + self.del_edge(u, v, l, directed) cpdef del_edge(self, object u, object v, object l, bint directed): """ @@ -2870,7 +2872,7 @@ cdef class CGraphBackend(GenericGraphBackend): # Yield the arc/arcs. v_copy = v if _reorganize_edge(v, u, modus): - u,v = v,u + u, v = v, u if not self._multiple_edges: if labels: @@ -3199,7 +3201,6 @@ cdef class CGraphBackend(GenericGraphBackend): # in this case there is nothing to do return 1 - cdef int length = len(b_vertices) cdef int i cdef int* vertices_translation = sig_malloc(b_vertices.capacity() * sizeof(int)) @@ -3657,9 +3658,9 @@ cdef class CGraphBackend(GenericGraphBackend): return [] def bidirectional_dijkstra_special(self, x, y, weight_function=None, - exclude_vertices=None, exclude_edges=None, - include_vertices=None, distance_flag=False, - reduced_weight=None): + exclude_vertices=None, exclude_edges=None, + include_vertices=None, distance_flag=False, + reduced_weight=None): r""" Return the shortest path or distance from ``x`` to ``y`` using a bidirectional version of Dijkstra's algorithm. @@ -4104,8 +4105,8 @@ cdef class CGraphBackend(GenericGraphBackend): def shortest_path_all_vertices(self, v, cutoff=None, distance_flag=False): r""" - Return for each vertex ``u`` a shortest ``v-u`` path or distance from - ``v`` to ``u``. + Return for each reachable vertex ``u`` a shortest ``v-u`` path or + distance from ``v`` to ``u``. INPUT: @@ -4145,7 +4146,7 @@ cdef class CGraphBackend(GenericGraphBackend): sage: g._backend.shortest_path_all_vertices(0, distance_flag=True) {0: 0, 1: 1, 2: 2, 3: 2, 4: 1, 5: 1, 6: 2, 7: 2, 8: 2, 9: 2} - On a disconnected graph :: + On a disconnected graph:: sage: g = 2 * graphs.RandomGNP(20, .3) sage: paths = g._backend.shortest_path_all_vertices(0) @@ -4203,13 +4204,6 @@ cdef class CGraphBackend(GenericGraphBackend): current_layer = next_layer next_layer = [] - # If the graph is not connected, vertices which have not been - # seen should be associated to the empty path - - #for 0 <= v_int < (self._cg).active_vertices.size: - # if bitset_in((self._cg).active_vertices, v_int) and not bitset_in(seen, v_int): - # distances[vertex_label(v_int, self.vertex_ints, self.vertex_labels, self._cg)] = [] - bitset_free(seen) return distances @@ -4688,7 +4682,7 @@ cdef class CGraphBackend(GenericGraphBackend): tmp = u while u != uu: - u = parent.get(u,uu) + u = parent.get(u, uu) cycle.append(self.vertex_label(u)) cycle.reverse() diff --git a/src/sage/graphs/base/dense_graph.pyx b/src/sage/graphs/base/dense_graph.pyx index 008b26685fb..14d9172f3c7 100644 --- a/src/sage/graphs/base/dense_graph.pyx +++ b/src/sage/graphs/base/dense_graph.pyx @@ -99,15 +99,15 @@ It also contains the following variables:: cdef binary_matrix_t edges """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008-9 Robert L. Miller # # 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.data_structures.bitset_base cimport * @@ -115,9 +115,11 @@ from cysignals.memory cimport sig_calloc, sig_realloc, sig_free from sage.data_structures.binary_matrix cimport * from libc.string cimport memcpy + cdef extern from "Python.h": int unlikely(int) nogil # Defined by Cython + cdef class DenseGraph(CGraph): """ Compiled dense graphs. @@ -160,12 +162,12 @@ cdef class DenseGraph(CGraph): raise RuntimeError('dense graphs must allocate space for vertices') self.num_verts = nverts - self.num_arcs = 0 + self.num_arcs = 0 cdef int total_verts = nverts + extra_vertices self._directed = directed binary_matrix_init(self.edges, total_verts, total_verts) - self.in_degrees = sig_calloc(total_verts, sizeof(int)) + self.in_degrees = sig_calloc(total_verts, sizeof(int)) self.out_degrees = sig_calloc(total_verts, sizeof(int)) if not self.in_degrees or not self.out_degrees: @@ -257,11 +259,11 @@ cdef class DenseGraph(CGraph): # Resize of self.edges binary_matrix_realloc(self.edges, total_verts, total_verts) - self.in_degrees = sig_realloc(self.in_degrees , total_verts * sizeof(int)) + self.in_degrees = sig_realloc(self.in_degrees, total_verts * sizeof(int)) self.out_degrees = sig_realloc(self.out_degrees, total_verts * sizeof(int)) for i in range(self.active_vertices.size, total_verts): - self.in_degrees[i] = 0 + self.in_degrees[i] = 0 self.out_degrees[i] = 0 bitset_realloc(self.active_vertices, total_verts) @@ -405,9 +407,9 @@ cdef class DenseGraph(CGraph): while i != -1: self.add_arc_unsafe(i, i) bitset_xor(self.edges.rows[i], self.edges.rows[i], self.active_vertices) - self.in_degrees[i] = self.num_verts-self.in_degrees[i] + self.in_degrees[i] = self.num_verts-self.in_degrees[i] self.out_degrees[i] = self.num_verts-self.out_degrees[i] - i = bitset_next(self.active_vertices, i+1) + i = bitset_next(self.active_vertices, i + 1) self.num_arcs = self.num_verts*(self.num_verts - 1) - num_arcs_old @@ -426,7 +428,7 @@ cdef class DenseGraph(CGraph): Set ``l`` to be the label of the first arc. """ l[0] = 0 - return bitset_next(self.edges.rows[u], v+1) + return bitset_next(self.edges.rows[u], v + 1) cdef inline int next_in_neighbor_unsafe(self, int v, int u, int* l) except -2: """ @@ -440,13 +442,14 @@ cdef class DenseGraph(CGraph): """ l[0] = 0 cdef size_t i - i = bitset_next(self.active_vertices, u+1) + i = bitset_next(self.active_vertices, u + 1) while i != -1: if binary_matrix_get(self.edges, i, v): return i - i = bitset_next(self.active_vertices, i+1) + i = bitset_next(self.active_vertices, i + 1) return -1 + cdef int copy_dense_graph(DenseGraph dest, DenseGraph src) except -1: r""" Unsafely copy ``dest`` over ``src``. @@ -464,7 +467,8 @@ cdef int copy_dense_graph(DenseGraph dest, DenseGraph src) except -1: binary_matrix_copy(dest.edges, src.edges) bitset_copy(dest.active_vertices, src.active_vertices) dest.num_verts = src.num_verts - dest.num_arcs = src.num_arcs + dest.num_arcs = src.num_arcs + ############################## # Further tests. Unit tests for methods, functions, classes defined with cdef. @@ -518,6 +522,7 @@ def _test_adjacency_sequence_out(): sig_free(seq) sig_free(V) + ########################################### # Dense Graph Backend ########################################### diff --git a/src/sage/graphs/base/graph_backends.pyx b/src/sage/graphs/base/graph_backends.pyx index 79705778590..9daf0702185 100644 --- a/src/sage/graphs/base/graph_backends.pyx +++ b/src/sage/graphs/base/graph_backends.pyx @@ -740,23 +740,24 @@ cdef class GenericGraphBackend(SageObject): else: raise Exception multiedges = ( self)._multiple_edges - directed = ( self)._directed - loops = ( self)._loops + directed = ( self)._directed + loops = ( self)._loops else: raise Exception # Vertices and edges vertices = list(self.iterator_verts(None)) if directed: - edges = list(self.iterator_out_edges(vertices, True)) + edges = list(self.iterator_out_edges(vertices, True)) else: - edges = list(self.iterator_edges(vertices, True)) + edges = list(self.iterator_edges(vertices, True)) return (unpickle_graph_backend, (directed, vertices, edges, {'loops': loops, 'multiedges': multiedges})) + def unpickle_graph_backend(directed, vertices, edges, kwds): r""" Return a backend from its pickled data diff --git a/src/sage/graphs/base/sparse_graph.pyx b/src/sage/graphs/base/sparse_graph.pyx index b606a9aa0d1..d46b374f86e 100644 --- a/src/sage/graphs/base/sparse_graph.pyx +++ b/src/sage/graphs/base/sparse_graph.pyx @@ -179,15 +179,15 @@ working on a general-purpose Cython-based red black tree, which would be optimal for both of these uses. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008-9 Robert L. Miller # # 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 libc.string cimport memset @@ -196,6 +196,7 @@ from cysignals.memory cimport check_malloc, check_allocarray, sig_free from sage.data_structures.bitset_base cimport * from sage.data_structures.bitset cimport * + cdef enum: BT_REORDERING_CONSTANT = 145533211 # Since the binary tree will often see vertices coming in already sorted, @@ -205,16 +206,18 @@ cdef enum: # things, but it may just be on binary trees that are never bigger than two # or three nodes. + cdef inline int compare(int a, int b): # Here we rely on the fact that C performs arithmetic on unsigned # ints modulo 2^wordsize. - cdef unsigned int aa = a, bb = b # signed ints lead to badness like a>b>c>a... + cdef unsigned int aa = a, bb = b # signed ints lead to badness like a>b>c>a... if aa*BT_REORDERING_CONSTANT > bb*BT_REORDERING_CONSTANT: return 1 elif aa*BT_REORDERING_CONSTANT < bb*BT_REORDERING_CONSTANT: return -1 return 0 + cdef class SparseGraph(CGraph): """ Compiled sparse graphs. @@ -248,7 +251,8 @@ cdef class SparseGraph(CGraph): """ - def __cinit__(self, int nverts, int expected_degree = 16, int extra_vertices = 10, verts=None, arcs=None, directed=True): + def __cinit__(self, int nverts, int expected_degree=16, int extra_vertices=10, + verts=None, arcs=None, directed=True): """ Allocation and initialization happen in one place. @@ -303,8 +307,8 @@ cdef class SparseGraph(CGraph): self.add_vertices(verts) if arcs is not None: - for u,v,l in arcs: - self.add_arc_label(u,v,l) + for u, v, l in arcs: + self.add_arc_label(u, v, l) def __dealloc__(self): """ @@ -446,11 +450,11 @@ cdef class SparseGraph(CGraph): # self.in_degrees memset(self.in_degrees + self.active_vertices.size, 0, - new_vertices * sizeof(int)) + new_vertices * sizeof(int)) # self.out_degrees memset(self.out_degrees + self.active_vertices.size, 0, - new_vertices * sizeof(int)) + new_vertices * sizeof(int)) # self.active_vertices bitset_realloc(self.active_vertices, s_total) @@ -499,7 +503,7 @@ cdef class SparseGraph(CGraph): parent = &(parent[0].left) elif compared < 0: parent = &(parent[0].right) - else:# if parent[0].vertex == v: + else: # if parent[0].vertex == v: break # If not found, there is no arc to delete ! @@ -689,7 +693,7 @@ cdef class SparseGraph(CGraph): # We fall back to it, if we do not find anything smaller. last_larger = temp temp = temp.left - else: # note compare < 0 + else: # note compare < 0 temp = temp.right if last_larger: return last_larger @@ -876,7 +880,6 @@ cdef class SparseGraph(CGraph): self.out_degrees[v] += 1 self.num_arcs += 1 - self.in_degrees[v] += 1 self.out_degrees[u] += 1 self.num_arcs += 1 @@ -907,13 +910,12 @@ cdef class SparseGraph(CGraph): sage: G.add_arc_label(1,2,2) sage: G.arc_label(1,2) 2 - """ self.check_vertex(u) self.check_vertex(v) if l < 0: raise ValueError("Label ({0}) must be a nonnegative integer.".format(l)) - self.add_arc_label_unsafe(u,v,l) + self.add_arc_label_unsafe(u, v, l) cdef int arc_label_unsafe(self, int u, int v) except -1: """ @@ -973,7 +975,7 @@ cdef class SparseGraph(CGraph): temp = temp.left elif compared < 0: temp = temp.right - else: # temp.vertex == v: + else: # temp.vertex == v: break if not temp: return 0 @@ -1017,7 +1019,7 @@ cdef class SparseGraph(CGraph): temp = temp.left elif compared < 0: temp = temp.right - else: # temp.vertex == v: + else: # temp.vertex == v: break if not temp: return NULL @@ -1047,18 +1049,21 @@ cdef class SparseGraph(CGraph): parent = &(parent[0].left) elif compared < 0: parent = &(parent[0].right) - else: # if parent[0].vertex == v: + else: # if parent[0].vertex == v: break if not parent[0]: - return 1 # indicate an error + return 1 # indicate an error if l == 0: - if parent[0].number > 1: parent[0].number -= 1 + if parent[0].number > 1: + parent[0].number -= 1 elif parent[0].number == 1: if not parent[0].labels: self._del_arc_unsafe(u, v, old_parent) return 0 - else: parent[0].number -= 1 - else: return 1 # indicate an error + else: + parent[0].number -= 1 + else: + return 1 # indicate an error else: labels = &(parent[0].labels) while labels[0] and labels[0].label != l: @@ -1092,7 +1097,7 @@ cdef class SparseGraph(CGraph): - ``1`` -- No arc with label ``l`` """ if self._del_arc_label_unsafe(u, v, l, self.vertices): - return 1 # indicate an error + return 1 # indicate an error if u != v or self.is_directed(): # We remove the reverse copy only if u != v or graph is directed. @@ -1133,7 +1138,7 @@ cdef class SparseGraph(CGraph): temp = temp.left elif compared < 0: temp = temp.right - else:# if temp.vertex == v: + else: # if temp.vertex == v: break if not temp: return 0 @@ -1148,6 +1153,7 @@ cdef class SparseGraph(CGraph): label = label.next return 0 + ############################## # Further tests. Unit tests for methods, functions, classes defined with cdef. ############################## @@ -1200,6 +1206,7 @@ def _test_adjacency_sequence_out(): sig_free(seq) sig_free(V) + ########################################### # Sparse Graph Backend ########################################### @@ -1305,7 +1312,6 @@ cdef class SparseGraphBackend(CGraphBackend): [(0, 1, 1), (2, 3, 2), (4, 5, 3), (5, 6, 2)] sage: D.get_edge_label(3,2) 2 - """ cdef int l_int if not self.has_vertex(u): @@ -1315,10 +1321,10 @@ cdef class SparseGraphBackend(CGraphBackend): cdef int u_int = self.get_vertex(u) cdef int v_int = self.get_vertex(v) if not self._cg.has_arc_unsafe(u_int, v_int): - raise LookupError("({0}, {1}) is not an edge of the graph.".format(repr(u),repr(v))) + raise LookupError("({0}, {1}) is not an edge of the graph.".format(repr(u), repr(v))) if self.multiple_edges(None): return [self.edge_labels[l_int] if l_int != 0 else None - for l_int in self._cg.all_arcs(u_int, v_int)] + for l_int in self._cg.all_arcs(u_int, v_int)] l_int = self._cg.arc_label(u_int, v_int) return self.edge_labels[l_int] if l_int else None @@ -1421,7 +1427,7 @@ cdef class SparseGraphBackend(CGraphBackend): return if self.multiple_edges(None): if len(self.get_edge_label(u, v)) > 1: - raise RuntimeError("Cannot set edge label, since there are multiple edges from %s to %s."%(u,v)) + raise RuntimeError("Cannot set edge label, since there are multiple edges from %s to %s." % (u, v)) # now we know there is exactly one edge from u to v cdef int l_int, ll_int if l is None: diff --git a/src/sage/graphs/base/static_dense_graph.pyx b/src/sage/graphs/base/static_dense_graph.pyx index a26212d0d1c..3b5c3a5f0cc 100644 --- a/src/sage/graphs/base/static_dense_graph.pyx +++ b/src/sage/graphs/base/static_dense_graph.pyx @@ -111,7 +111,7 @@ cdef dict dense_graph_init(binary_matrix_t m, g, translation=None, force_undirec if not d_translation: d_translation = {v: i for i, v in enumerate(g.vertices())} - for u,v in g.edge_iterator(labels=False): + for u, v in g.edge_iterator(labels=False): binary_matrix_set1(m, d_translation[u], d_translation[v]) if is_undirected: binary_matrix_set1(m, d_translation[v], d_translation[u]) @@ -119,6 +119,7 @@ cdef dict dense_graph_init(binary_matrix_t m, g, translation=None, force_undirec if translation is True: return d_translation + def is_strongly_regular(g, parameters=False): r""" Check whether the graph is strongly regular. @@ -214,7 +215,7 @@ def is_strongly_regular(g, parameters=False): cdef int inter cdef int i, j, l, k - if not g.order() or not g.size(): # no vertices or no edges + if not g.order() or not g.size(): # no vertices or no edges return False if g.is_clique(): @@ -265,6 +266,7 @@ def is_strongly_regular(g, parameters=False): else: return True + def is_triangle_free(G, certificate=False): r""" Check whether `G` is triangle free. @@ -325,6 +327,7 @@ def is_triangle_free(G, certificate=False): binary_matrix_free(g) return (True, []) if certificate else True + def triangles_count(G): r""" Return the number of triangles containing `v`, for every `v`. @@ -354,7 +357,7 @@ def triangles_count(G): cdef bitset_t b_tmp bitset_init(b_tmp, n) - cdef int i,j + cdef int i, j cdef uint64_t tmp_count = 0 for i in range(n): @@ -374,6 +377,7 @@ def triangles_count(G): return ans + def connected_subgraph_iterator(G, k=None, bint vertices_only=False): r""" Iterator over the induced connected subgraphs of order at most `k`. @@ -497,12 +501,12 @@ def connected_subgraph_iterator(G, k=None, bint vertices_only=False): cdef bitset_t current # current subset of vertices cdef bitset_t left # remaining vertices to consider - cdef bitset_t boundary # neighbors of the current subset + cdef bitset_t boundary # neighbors of the current subset # candidate vertices for extending the current subset, i.e., vertices that # are both in left and in boundary cdef bitset_t candidates = stack.rows[3 * n + 3] - cdef Py_ssize_t l = 0 + cdef Py_ssize_t level cdef Py_ssize_t u, v, a # We first generate subsets containing vertex 0, then the subsets containing @@ -520,54 +524,54 @@ def connected_subgraph_iterator(G, k=None, bint vertices_only=False): # in left, and N(u) in boundary bitset_clear(stack.rows[0]) bitset_add(stack.rows[0], u) - bitset_set_first_n(stack.rows[1], u+1) + bitset_set_first_n(stack.rows[1], u + 1) bitset_complement(stack.rows[1], stack.rows[1]) bitset_copy(stack.rows[2], DG.rows[u]) - l = 0 + level = 0 - while l >= 0: + while level >= 0: sig_check() # We take the values at the top of the stack - current = stack.rows[l] - left = stack.rows[l + 1] - boundary = stack.rows[l + 2] + current = stack.rows[level] + left = stack.rows[level + 1] + boundary = stack.rows[level + 2] bitset_and(candidates, left, boundary) # Search for a candidate vertex v - v = bitset_next(candidates, u+1) + v = bitset_next(candidates, u + 1) if v >= 0 and bitset_len(current) < mk: # We select vertex v bitset_discard(left, v) - # Since we have not modified l, the bitsets for iterating without - # v are already at the top of the stack, with correct values + # Since we have not modified 'level', the bitsets for iterating + # without v are already at the top of the stack, with correct + # values # We also build the subset with v and so we add values at the # top of the stack - l += 3 - bitset_copy(stack.rows[l], current) - bitset_add(stack.rows[l], v) - bitset_copy(stack.rows[l + 1], left) - bitset_union(stack.rows[l + 2], boundary, DG.rows[v]) + level += 3 + bitset_copy(stack.rows[level], current) + bitset_add(stack.rows[level], v) + bitset_copy(stack.rows[level + 1], left) + bitset_union(stack.rows[level + 2], boundary, DG.rows[v]) # We yield that new subset if vertices_only: yield [int_to_vertex[a] for a in range(u, n) - if bitset_in(stack.rows[l], a)] + if bitset_in(stack.rows[level], a)] else: yield G.subgraph([int_to_vertex[a] for a in range(u, n) - if bitset_in(stack.rows[l], a)]) + if bitset_in(stack.rows[level], a)]) else: # We cannot extend the current subset, either due to a lack of # candidate (v == -1), or because the current subset has maximum # size. We pop - l -= 3 + level -= 3 sig_on() binary_matrix_free(stack) binary_matrix_free(DG) sig_off() - diff --git a/src/sage/graphs/base/static_sparse_backend.pyx b/src/sage/graphs/base/static_sparse_backend.pyx index 2e85c2290fe..9ef4b6c74b1 100644 --- a/src/sage/graphs/base/static_sparse_backend.pyx +++ b/src/sage/graphs/base/static_sparse_backend.pyx @@ -303,7 +303,7 @@ cdef class StaticSparseCGraph(CGraph): cdef int out_neighbors_unsafe(self, int u, int *neighbors, int size) except -2: cdef int degree = self.g.neighbors[u+1] - self.g.neighbors[u] cdef int i - for i in range(min(degree,size)): + for i in range(min(degree, size)): neighbors[i] = self.g.neighbors[u][i] return -1 if size < degree else degree @@ -421,6 +421,7 @@ cdef class StaticSparseCGraph(CGraph): else: return self.g_rev.neighbors[u+1] - self.g_rev.neighbors[u] + cdef class StaticSparseBackend(CGraphBackend): def __init__(self, G, loops=False, multiedges=False): @@ -517,7 +518,6 @@ cdef class StaticSparseBackend(CGraphBackend): self._directed = cg._directed - self._order = G.order() # Does it allow loops/multiedges ? @@ -766,11 +766,11 @@ cdef class StaticSparseBackend(CGraphBackend): # not necessarily toward the right label. As there may be many uv edges # with different labels, we first make edge point toward the leftmost uv # edge, then scan them all to find the right label. - while edge > cg.g.neighbors[u] and (edge - 1)[0] == v : + while edge > cg.g.neighbors[u] and (edge - 1)[0] == v: edge -= 1 while edge[0] == v and edge < cg.g.neighbors[u+1]: - if edge_label(cg.g,edge) == l: + if edge_label(cg.g, edge) == l: return True edge += 1 @@ -1194,7 +1194,6 @@ cdef class StaticSparseBackend(CGraphBackend): if not cg_other.has_arc_unsafe(vertices_translation[v_int], vertices_translation[u_int]): return 0 - finally: sig_free(vertices_translation) @@ -1422,7 +1421,7 @@ cdef class StaticSparseBackend(CGraphBackend): yield self._vertex_to_labels[u] seen.add(u) - def add_vertex(self,v): + def add_vertex(self, v): r""" Addition of vertices is not available on an immutable graph. @@ -1440,7 +1439,7 @@ cdef class StaticSparseBackend(CGraphBackend): """ ( self._cg).add_vertex(v) - def del_vertex(self,v): + def del_vertex(self, v): r""" Removal of vertices is not available on an immutable graph. @@ -1458,6 +1457,7 @@ cdef class StaticSparseBackend(CGraphBackend): """ ( self._cg).del_vertex(v) + def _run_it_on_static_instead(f): r""" A decorator function to force the (Di)Graph functions to compute from a diff --git a/src/sage/graphs/bliss.pyx b/src/sage/graphs/bliss.pyx index 140b83b4e3b..65a27d3f12d 100644 --- a/src/sage/graphs/bliss.pyx +++ b/src/sage/graphs/bliss.pyx @@ -29,7 +29,7 @@ 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 libc.limits cimport LONG_MAX @@ -47,20 +47,20 @@ cdef extern from "bliss/graph.hh" namespace "bliss": cdef cppclass Graph(AbstractGraph): Graph(const unsigned int) void add_edge(const unsigned int, const unsigned int) - void find_automorphisms(Stats&, void (*)(void* , unsigned int, - const unsigned int*), void*) + void find_automorphisms(Stats&, void (*)(void*, unsigned int, + const unsigned int*), void*) void change_color(const unsigned int, const unsigned int) - const unsigned int* canonical_form(Stats&, void (*)(void*,unsigned int, - const unsigned int*), void*) + const unsigned int* canonical_form(Stats&, void (*)(void*, unsigned int, + const unsigned int*), void*) cdef cppclass Digraph(AbstractGraph): Digraph(const unsigned int) void add_edge(const unsigned int, const unsigned int) - void find_automorphisms(Stats&, void (*)(void* , unsigned int, - const unsigned int*), void*) + void find_automorphisms(Stats&, void (*)(void*, unsigned int, + const unsigned int*), void*) void change_color(const unsigned int, const unsigned int) - const unsigned int* canonical_form(Stats&, void (*)(void*,unsigned int, - const unsigned int*), void*) + const unsigned int* canonical_form(Stats&, void (*)(void*, unsigned int, + const unsigned int*), void*) unsigned int get_hash() @@ -97,9 +97,9 @@ cdef void add_gen(void *user_param, unsigned int n, const unsigned int *aut): - ``aut`` -- ``int *``; an automorphism of the graph """ cdef int N - cdef int tmp = 0 - cdef int cur = 0 - cdef list perm = [] + cdef int tmp = 0 + cdef int cur = 0 + cdef list perm = [] cdef bint* done = check_calloc(n, sizeof(bint)) cdef int i @@ -124,7 +124,8 @@ cdef void add_gen(void *user_param, unsigned int n, const unsigned int *aut): sig_free(done) -cdef void empty_hook(void *user_param , unsigned int n, const unsigned int *aut): + +cdef void empty_hook(void *user_param, unsigned int n, const unsigned int *aut): return ##################################################### @@ -303,7 +304,7 @@ cdef Digraph *bliss_digraph_from_labelled_edges(int Vnr, int Lnr, Vout, Vin, lab ##################################################### cdef canonical_form_from_edge_list(int Vnr, list Vout, list Vin, int Lnr=1, list labels=[], - list partition=None, bint directed=False, bint certificate=False): + list partition=None, bint directed=False, bint certificate=False): r""" Return an unsorted list of labelled edges of a canonical form. @@ -380,6 +381,7 @@ cdef canonical_form_from_edge_list(int Vnr, list Vout, list Vin, int Lnr=1, list else: return new_edges + cpdef canonical_form(G, partition=None, return_graph=False, use_edge_labels=True, certificate=False): r""" Return a canonical label for the given (di)graph. @@ -512,8 +514,8 @@ cpdef canonical_form(G, partition=None, return_graph=False, use_edge_labels=True cdef bint directed = G.is_directed() cdef int labInd - cdef list Vout = [] - cdef list Vin = [] + cdef list Vout = [] + cdef list Vin = [] cdef list labels = [] cdef list int2vert @@ -554,15 +556,15 @@ cpdef canonical_form(G, partition=None, return_graph=False, use_edge_labels=True # NOTE: use edge labels might not be hashable or sortable... # rely loosely on string representation edge_labels = sorted(set(map(str, G.edge_labels()))) - lab_to_index = {lab: i for i,lab in enumerate(edge_labels)} - for x,y,lab in G.edge_iterator(labels=True): + lab_to_index = {lab: i for i, lab in enumerate(edge_labels)} + for x, y, lab in G.edge_iterator(labels=True): Vout.append(vert2int[x]) Vin.append(vert2int[y]) labels.append(lab_to_index[str(lab)]) else: - lab_to_index = {lab:i for i,lab in enumerate(edge_labels)} - for x,y,lab in G.edge_iterator(labels=True): + lab_to_index = {lab: i for i, lab in enumerate(edge_labels)} + for x, y, lab in G.edge_iterator(labels=True): Vout.append(vert2int[x]) Vin.append(vert2int[y]) labels.append(lab_to_index[lab]) @@ -570,7 +572,7 @@ cpdef canonical_form(G, partition=None, return_graph=False, use_edge_labels=True Lnr = len(lab_to_index) else: - for x,y in G.edge_iterator(labels=False): + for x, y in G.edge_iterator(labels=False): Vout.append(vert2int[x]) Vin.append(vert2int[y]) @@ -593,12 +595,13 @@ cpdef canonical_form(G, partition=None, return_graph=False, use_edge_labels=True # Warning: this may break badly in Python 3 if the graph is not simple return (sorted(new_edges), relabel) if certificate else sorted(new_edges) + ##################################################### # automorphism group from graphs ##################################################### cdef automorphism_group_gens_from_edge_list(int Vnr, Vout, Vin, int Lnr=1, labels=[], - int2vert=[], partition=None, bint directed=False): + int2vert=[], partition=None, bint directed=False): r""" Return an unsorted list of labelled edges of a canonical form. @@ -757,7 +760,8 @@ cpdef automorphism_group(G, partition=None, use_edge_labels=True): sage: G.add_edges((i,j,"D") for i in range(9,14) for j in range(14,20)) # optional - bliss sage: A = automorphism_group(G) # optional - bliss sage: print(A.gens()) # random, optional - bliss - [(9,13), (18,19), (17,18), (16,17), (15,16), (14,15), (12,9), (11,12), (10,11), (7,8), (6,7), (5,6), (3,4), (2,3), (0,1)] + [(9,13), (18,19), (17,18), (16,17), (15,16), (14,15), (12,9), (11,12), + (10,11), (7,8), (6,7), (5,6), (3,4), (2,3), (0,1)] sage: A.cardinality() == prod(factorial(n) for n in [2,3,4,5,6]) # optional - bliss True @@ -770,7 +774,9 @@ cpdef automorphism_group(G, partition=None, use_edge_labels=True): sage: G.add_edges((alpha[i],alpha[j],"D") for i in range(9,14) for j in range(14,20)) # optional - bliss sage: A = automorphism_group(G) # optional - bliss sage: print(A.gens()) # random, optional - bliss - [('r','t'), ('s','r'), ('p','s'), ('q','p'), ('o','q'), ('l','n'), ('m','l'), ('j','m'), ('k','j'), ('i','h'), ('f','i'), ('g','f'), ('e','d'), ('c','e'), ('a','b')] + [('r','t'), ('s','r'), ('p','s'), ('q','p'), ('o','q'), ('l','n'), + ('m','l'), ('j','m'), ('k','j'), ('i','h'), ('f','i'), ('g','f'), + ('e','d'), ('c','e'), ('a','b')] sage: A.cardinality() == prod(factorial(n) for n in [2,3,4,5,6]) # optional - bliss True @@ -791,8 +797,8 @@ cpdef automorphism_group(G, partition=None, use_edge_labels=True): cdef bint directed = G.is_directed() cdef int labInd - cdef list Vout = [] - cdef list Vin = [] + cdef list Vout = [] + cdef list Vin = [] cdef list labels = [] cdef list int2vert @@ -814,7 +820,7 @@ cpdef automorphism_group(G, partition=None, use_edge_labels=True): # - Vin[i] : destination of the ith edge # - labels[i] : label of the ith edge if use_edge_labels is True # On the way, assign a unique integer to each distinct label - for x,y,lab in G.edge_iterator(labels=True): + for x, y, lab in G.edge_iterator(labels=True): Vout.append(vert2int[x]) Vin.append(vert2int[y]) if use_edge_labels: @@ -894,7 +900,7 @@ cdef Digraph *bliss_digraph(G, partition, vert2int, int2vert): vert2int[v] = i int2vert[i] = v - for x,y in G.edge_iterator(labels=False): + for x, y in G.edge_iterator(labels=False): g.add_edge(vert2int[x], vert2int[y]) if partition: diff --git a/src/sage/graphs/centrality.pyx b/src/sage/graphs/centrality.pyx index d73787a4b10..852b86c34e8 100755 --- a/src/sage/graphs/centrality.pyx +++ b/src/sage/graphs/centrality.pyx @@ -35,6 +35,7 @@ ctypedef fused numerical_type: cimport cython + def centrality_betweenness(G, bint exact=False, bint normalize=True): r""" Return the centrality betweenness of `G` @@ -120,6 +121,7 @@ def centrality_betweenness(G, bint exact=False, bint normalize=True): else: return centrality_betweenness_C(G, 0, normalize=normalize) + @cython.cdivision(True) cdef dict centrality_betweenness_C(G, numerical_type _, bint normalize=True): r""" @@ -154,11 +156,11 @@ cdef dict centrality_betweenness_C(G, numerical_type _, bint normalize=True): cdef int n = G.order() - cdef bitset_t seen # Vertices whose neighbors have been explored - cdef bitset_t next_layer # Unexplored neighbors of vertices in 'seen' + cdef bitset_t seen # Vertices whose neighbors have been explored + cdef bitset_t next_layer # Unexplored neighbors of vertices in 'seen' - cdef uint32_t* queue = NULL # BFS queue - cdef uint32_t* degrees = NULL # degree[v] = nb of vertices which discovered v + cdef uint32_t* queue = NULL # BFS queue + cdef uint32_t* degrees = NULL # degree[v] = nb of vertices which discovered v cdef numerical_type* n_paths_from_source = NULL cdef numerical_type* betweenness_source = NULL @@ -180,11 +182,11 @@ cdef dict centrality_betweenness_C(G, numerical_type _, bint normalize=True): init_short_digraph(g, G, edge_labelled=False, vertex_list=int_to_vertex) init_reverse(bfs_dag, g) - queue = check_allocarray(n, sizeof(uint32_t)) - degrees = check_allocarray(n, sizeof(uint32_t)) + queue = check_allocarray(n, sizeof(uint32_t)) + degrees = check_allocarray(n, sizeof(uint32_t)) n_paths_from_source = check_allocarray(n, sizeof(numerical_type)) - betweenness_source = check_allocarray(n, sizeof(numerical_type)) - betweenness = check_allocarray(n, sizeof(numerical_type)) + betweenness_source = check_allocarray(n, sizeof(numerical_type)) + betweenness = check_allocarray(n, sizeof(numerical_type)) bitset_init(seen, n) bitset_init(next_layer, n) @@ -219,8 +221,8 @@ cdef dict centrality_betweenness_C(G, numerical_type _, bint normalize=True): queue[0] = source layer_current_beginning = 0 - layer_current_end = 1 - layer_next_end = 1 + layer_current_end = 1 + layer_next_end = 1 # The number of shortest paths from 'source' to every other vertex. # @@ -261,7 +263,7 @@ cdef dict centrality_betweenness_C(G, numerical_type _, bint normalize=True): bitset_add(seen, queue[j]) layer_current_beginning = layer_current_end - layer_current_end = layer_next_end + layer_current_end = layer_next_end # Compute the betweenness from the number of paths # @@ -270,7 +272,7 @@ cdef dict centrality_betweenness_C(G, numerical_type _, bint normalize=True): u = queue[i] for j in range(degrees[u]): v = bfs_dag.neighbors[u][j] - if v != source: # better to not 'if' but set it to 0 afterwards? + if v != source: # better to not 'if' but set it to 0 afterwards? if numerical_type is double: betweenness_source[v] += (betweenness_source[u] + 1) * (n_paths_from_source[v] / n_paths_from_source[u]) else: @@ -287,7 +289,7 @@ cdef dict centrality_betweenness_C(G, numerical_type _, bint normalize=True): else: mpq_add(betweenness[i], betweenness[i], betweenness_source[i]) - sig_check() # check for KeyboardInterrupt + sig_check() # check for KeyboardInterrupt if numerical_type is double: betweenness_list = [betweenness[i] for i in range(n)] @@ -324,6 +326,7 @@ cdef dict centrality_betweenness_C(G, numerical_type _, bint normalize=True): return {vv: betweenness_list[i] for i, vv in enumerate(int_to_vertex)} + cdef void _estimate_reachable_vertices_dir(short_digraph g, int* reachL, int* reachU): r""" For each vertex ``v``, bounds the number of vertices reachable from ``v``. @@ -456,6 +459,7 @@ cdef void _estimate_reachable_vertices_dir(short_digraph g, int* reachL, int* re reachL[i] = reachL_scc[scc[i]] reachU[i] = min(reachU_scc[scc[i]], g.n) + cdef void _compute_reachable_vertices_undir(short_digraph g, int* reachable): r""" For each vertex ``v``, compute the number of vertices reachable from ``v``. @@ -508,6 +512,7 @@ cdef void _compute_reachable_vertices_undir(short_digraph g, int* reachable): for v in currentcc: reachable[v] = len(currentcc) + cdef void _sort_vertices_degree(short_digraph g, int* sorted_verts): r""" Sort vertices in decreasing order of degree. @@ -730,8 +735,8 @@ def centrality_closeness_top_k(G, int k=1, int verbose=0): pred[v] = -1 layer_current_beginning = 0 - layer_current_end = 1 - layer_next_end = 1 + layer_current_end = 1 + layer_next_end = 1 d = 0 f = 0 # We are at level 0, and gamma is the number of arcs exiting level 0 @@ -794,7 +799,7 @@ def centrality_closeness_top_k(G, int k=1, int verbose=0): break # 'next_layer' becomes 'current_layer' layer_current_beginning = layer_current_end - layer_current_end = layer_next_end + layer_current_end = layer_next_end if not stopped: farness[x] = (( f) * (n - 1)) / ((nd - 1) * (nd - 1)) @@ -827,6 +832,7 @@ def centrality_closeness_top_k(G, int k=1, int verbose=0): res = sorted(res, reverse=True, key=lambda vv: vv[0]) return res + def centrality_closeness_random_k(G, int k=1): r""" Return an estimation of the closeness centrality of `G`. @@ -914,20 +920,20 @@ def centrality_closeness_random_k(G, int k=1): partial_farness[i] = 0 # Shuffle the vertices - cdef list l = list(range(n)) - random.shuffle(l) + cdef list V = list(range(n)) + random.shuffle(V) if G.weighted(): # For all random nodes take as a source then run Dijstra and # calculate closeness centrality for k random vertices from l. for i in range(k): farness = 0 - distances = boost_shortest_paths(G, int_to_vertex[l[i]], algorithm='Dijkstra')[0] + distances = boost_shortest_paths(G, int_to_vertex[V[i]], algorithm='Dijkstra')[0] for vertex in distances: farness += float(distances[vertex]) partial_farness[vertex_to_int[vertex]] += float(distances[vertex]) - closeness_centrality_array[int_to_vertex[l[i]]] = (n - 1) / farness + closeness_centrality_array[int_to_vertex[V[i]]] = (n - 1) / farness # G is unweighted graph else: @@ -943,18 +949,18 @@ def centrality_closeness_random_k(G, int k=1): # Run BFS for random k vertices for i in range(k): farness = 0 - simple_BFS(sd, l[i], distance, NULL, waiting_list, seen) + simple_BFS(sd, V[i], distance, NULL, waiting_list, seen) for j in range(n): farness += distance[j] partial_farness[j] += distance[j] - closeness_centrality_array[int_to_vertex[l[i]]] = (n - 1) / farness + closeness_centrality_array[int_to_vertex[V[i]]] = (n - 1) / farness bitset_free(seen) free_short_digraph(sd) # Estimate the closeness centrality for remaining n-k vertices. for i in range(k, n): - closeness_centrality_array[int_to_vertex[l[i]]] = k / partial_farness[l[i]] + closeness_centrality_array[int_to_vertex[V[i]]] = k / partial_farness[V[i]] return closeness_centrality_array diff --git a/src/sage/graphs/chrompoly.pyx b/src/sage/graphs/chrompoly.pyx index 4fb9f382894..d3afec0e278 100644 --- a/src/sage/graphs/chrompoly.pyx +++ b/src/sage/graphs/chrompoly.pyx @@ -13,7 +13,7 @@ REFERENCE: sparse graphs. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 Robert Miller # Copyright (C) 2008 Gordon Royle # @@ -21,8 +21,8 @@ REFERENCE: # 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_check from memory_allocator cimport MemoryAllocator @@ -34,6 +34,7 @@ from sage.rings.ring cimport Algebra from sage.rings.polynomial.polynomial_integer_dense_flint cimport Polynomial_integer_dense_flint from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + def chromatic_polynomial(G, return_tree_basis=False, algorithm='C', cache=None): """ Compute the chromatic polynomial of the graph G. @@ -172,22 +173,22 @@ def chromatic_polynomial(G, return_tree_basis=False, algorithm='C', cache=None): nedges = G.num_edges() cdef MemoryAllocator mem = MemoryAllocator() - queue = mem.allocarray(nverts, sizeof(int)) - chords1 = mem.allocarray((nedges - nverts + 1), sizeof(int)) - chords2 = mem.allocarray((nedges - nverts + 1), sizeof(int)) - parent = mem.allocarray(nverts, sizeof(int)) - bfs_reorder = mem.allocarray(nverts, sizeof(int)) - tot = mem.allocarray((nverts+1), sizeof(mpz_t)) - coeffs = mem.allocarray((nverts+1), sizeof(mpz_t)) + queue = mem.allocarray(nverts, sizeof(int)) + chords1 = mem.allocarray((nedges - nverts + 1), sizeof(int)) + chords2 = mem.allocarray((nedges - nverts + 1), sizeof(int)) + parent = mem.allocarray(nverts, sizeof(int)) + bfs_reorder = mem.allocarray(nverts, sizeof(int)) + tot = mem.allocarray((nverts+1), sizeof(mpz_t)) + coeffs = mem.allocarray((nverts+1), sizeof(mpz_t)) num_chords = 0 # Breadth first search from 0: bfs_reorder[0] = 0 - mpz_init(tot[0]) # sets to 0 + mpz_init(tot[0]) # sets to 0 for i from 0 < i < nverts: bfs_reorder[i] = -1 - mpz_init(tot[i]) # sets to 0 - mpz_init(tot[nverts]) # sets to 0 + mpz_init(tot[i]) # sets to 0 + mpz_init(tot[nverts]) # sets to 0 queue[0] = 0 top = 1 bot = 0 @@ -196,7 +197,7 @@ def chromatic_polynomial(G, return_tree_basis=False, algorithm='C', cache=None): v = queue[bot] bot += 1 for u in G.neighbor_iterator(v): - if bfs_reorder[u] == -1: # if u is not yet in tree + if bfs_reorder[u] == -1: # if u is not yet in tree bfs_reorder[u] = next_v next_v += 1 queue[top] = u @@ -230,7 +231,7 @@ def chromatic_polynomial(G, return_tree_basis=False, algorithm='C', cache=None): mpz_clear(tot[i]) raise for i from 0 <= i <= nverts: - mpz_init(coeffs[i]) # also sets them to 0 + mpz_init(coeffs[i]) # also sets them to 0 mpz_init(coeff) mpz_init_set_si(m, -1) # start with the zero polynomial: f(x) = 0 @@ -270,15 +271,15 @@ def chromatic_polynomial(G, return_tree_basis=False, algorithm='C', cache=None): cdef int contract_and_count(int *chords1, int *chords2, int num_chords, int nverts, - mpz_t *tot, int *parent) except -1: + mpz_t *tot, int *parent) except -1: if num_chords == 0: mpz_add_ui(tot[nverts], tot[nverts], 1) return 0 cdef MemoryAllocator mem = MemoryAllocator() cdef int *new_chords1 = mem.allocarray(num_chords, sizeof(int)) cdef int *new_chords2 = mem.allocarray(num_chords, sizeof(int)) - cdef int *ins_list1 = mem.allocarray(num_chords, sizeof(int)) - cdef int *ins_list2 = mem.allocarray(num_chords, sizeof(int)) + cdef int *ins_list1 = mem.allocarray(num_chords, sizeof(int)) + cdef int *ins_list2 = mem.allocarray(num_chords, sizeof(int)) cdef int i, j, k, x1, xj, z, num, insnum, parent_checked for i in range(num_chords): sig_check() @@ -302,7 +303,7 @@ cdef int contract_and_count(int *chords1, int *chords2, int num_chords, int nver ins_list1[insnum] = parent[z] ins_list2[insnum] = x1 insnum += 1 - if not parent[x1] == xj: # then {x1, xj} isn't already a tree edge + if not parent[x1] == xj: # then {x1, xj} isn't already a tree edge ins_list1[insnum] = x1 ins_list2[insnum] = xj insnum += 1 @@ -321,14 +322,14 @@ cdef int contract_and_count(int *chords1, int *chords2, int num_chords, int nver num = 0 k = 0 while k < insnum and j < num_chords: - if chords1[j] > ins_list1[k] or \ - (chords1[j] == ins_list1[k] and chords2[j] > ins_list2[k]): + if (chords1[j] > ins_list1[k] or + (chords1[j] == ins_list1[k] and chords2[j] > ins_list2[k])): new_chords1[num] = chords1[j] new_chords2[num] = chords2[j] num += 1 j += 1 - elif chords1[j] < ins_list1[k] or \ - (chords1[j] == ins_list1[k] and chords2[j] < ins_list2[k]): + elif (chords1[j] < ins_list1[k] or + (chords1[j] == ins_list1[k] and chords2[j] < ins_list2[k])): new_chords1[num] = ins_list1[k] new_chords2[num] = ins_list2[k] num += 1 diff --git a/src/sage/graphs/cliquer.pyx b/src/sage/graphs/cliquer.pyx index cd82d00ef4f..e53d90d2dbc 100644 --- a/src/sage/graphs/cliquer.pyx +++ b/src/sage/graphs/cliquer.pyx @@ -39,7 +39,7 @@ cdef extern from "sage/graphs/cliquer/cl.c": cdef int sage_clique_max(graph_t *g, int ** list_of_vertices) cdef int sage_all_clique_max(graph_t *g, int ** list_of_vertices) cdef int sage_clique_number(graph_t *g) - cdef int sage_find_all_clique(graph_t *g,int ** list_of_vertices, int min_size, int max_size) + cdef int sage_find_all_clique(graph_t *g, int ** list_of_vertices, int min_size, int max_size) def max_clique(graph): @@ -73,7 +73,7 @@ def max_clique(graph): cdef dict vertex_to_int = {v: i for i, v in enumerate(int_to_vertex)} cdef graph_t* g = graph_new(graph.order()) - for u,v in graph.edge_iterator(labels=None): + for u, v in graph.edge_iterator(labels=None): GRAPH_ADD_EDGE(g, vertex_to_int[u], vertex_to_int[v]) cdef int* list_of_vertices @@ -140,7 +140,7 @@ def all_max_clique(graph): cdef dict vertex_to_int = {v: i for i, v in enumerate(int_to_vertex)} cdef graph_t* g = graph_new(graph.order()) - for u,v in graph.edge_iterator(labels=None): + for u, v in graph.edge_iterator(labels=None): GRAPH_ADD_EDGE(g, vertex_to_int[u], vertex_to_int[v]) cdef int* list_of_vertices @@ -256,7 +256,7 @@ def all_cliques(graph, min_size=0, max_size=0): cdef dict vertex_to_int = {v: i for i, v in enumerate(int_to_vertex)} cdef graph_t* g = graph_new(graph.order()) - for u,v in graph.edge_iterator(labels=None): + for u, v in graph.edge_iterator(labels=None): GRAPH_ADD_EDGE(g, vertex_to_int[u], vertex_to_int[v]) cdef int* list_of_vertices @@ -284,7 +284,7 @@ def all_cliques(graph, min_size=0, max_size=0): sig_free(list_of_vertices) -#computes the clique number of a graph +# computes the clique number of a graph def clique_number(graph): """ @@ -319,7 +319,7 @@ def clique_number(graph): cdef dict vertex_to_int = {v: i for i, v in enumerate(graph)} cdef graph_t* g = graph_new(graph.order()) - for u,v in graph.edge_iterator(labels=None): + for u, v in graph.edge_iterator(labels=None): GRAPH_ADD_EDGE(g, vertex_to_int[u], vertex_to_int[v]) cdef int c diff --git a/src/sage/graphs/comparability.pyx b/src/sage/graphs/comparability.pyx index d81887a2b12..3957e425cc9 100644 --- a/src/sage/graphs/comparability.pyx +++ b/src/sage/graphs/comparability.pyx @@ -189,25 +189,26 @@ Methods ------- """ -#***************************************************************************** -# Copyright (C) 2012 Nathann Cohen +# **************************************************************************** +# Copyright (C) 2012 Nathann Cohen # # 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 sig_free - +from sage.graphs.distances_all_pairs cimport c_distances_all_pairs from copy import copy + ##################### # Greedy Algorithms # ##################### -def greedy_is_comparability(g, no_certificate = False, equivalence_class = False): +def greedy_is_comparability(g, no_certificate=False, equivalence_class=False): r""" Tests whether the graph is a comparability graph (greedy algorithm) @@ -251,37 +252,37 @@ def greedy_is_comparability(g, no_certificate = False, equivalence_class = False sage: is_comparability(g) True """ - cdef int i,j + cdef int i, j # Each vertex can partition its neighbors into equivalence classes equivalence_classes = {} for v in g: - equivalence_classes[v] = g.subgraph(vertices = g.neighbors(v)).complement().connected_components() + equivalence_classes[v] = g.subgraph(vertices=g.neighbors(v)).complement().connected_components() # We build a graph h with one vertex per (vertex of g + equivalence class) from sage.graphs.graph import Graph h = Graph() - h.add_vertices([(v,i) for v in g for i in range(len(equivalence_classes[v]))]) + h.add_vertices([(v, i) for v in g for i in range(len(equivalence_classes[v]))]) # We add an edge between two vertices of h if they represent # opposed equivalence classes - for u,v in g.edge_iterator(labels=False): + for u, v in g.edge_iterator(labels=False): - for i,s in enumerate(equivalence_classes[v]): + for i, s in enumerate(equivalence_classes[v]): if u in s: break - for j,s in enumerate(equivalence_classes[u]): + for j, s in enumerate(equivalence_classes[u]): if v in s: break - h.add_edge((v,i),(u,j)) + h.add_edge((v, i), (u, j)) # Is it a comparability graph ? cdef int isit - isit, certif = h.is_bipartite(certificate = True) + isit, certif = h.is_bipartite(certificate=True) if isit: if equivalence_class: @@ -290,16 +291,16 @@ def greedy_is_comparability(g, no_certificate = False, equivalence_class = False cc = sorted(h.connected_components(), key=len)[-1] edges = [] - for v,sid in cc: + for v, sid in cc: s = equivalence_classes[v][sid] # For each edge we pick the good orientations - if certif[v,sid] == 1: + if certif[v, sid] == 1: for vv in s: - edges.append((v,vv)) + edges.append((v, vv)) else: for vv in s: - edges.append((vv,v)) + edges.append((vv, v)) # We return the value but take care of removing edges that were # added twice. @@ -310,12 +311,13 @@ def greedy_is_comparability(g, no_certificate = False, equivalence_class = False else: if no_certificate: certif.append(certif[0]) - cycle = [v for v,_ in certif] + cycle = [v for v, _ in certif] return False, cycle else: return False -def greedy_is_comparability_with_certificate(g, certificate = False): + +def greedy_is_comparability_with_certificate(g, certificate=False): r""" Tests whether the graph is a comparability graph and returns certificates(greedy algorithm). @@ -370,9 +372,9 @@ def greedy_is_comparability_with_certificate(g, certificate = False): h = DiGraph() h.add_vertices(gg) - for u,v in certif: - gg.delete_edge(u,v) - h.add_edge(u,v) + for u, v in certif: + gg.delete_edge(u, v) + h.add_edge(u, v) # While there are some edges left to be oriented while gg.size(): @@ -381,12 +383,13 @@ def greedy_is_comparability_with_certificate(g, certificate = False): isit, certif = greedy_is_comparability(gg, no_certificate=True, equivalence_class=True) # Then remove it from the former graph - for u,v in certif: - gg.delete_edge(u,v) - h.add_edge(u,v) + for u, v in certif: + gg.delete_edge(u, v) + h.add_edge(u, v) return True, h + ################### # Integer Program # ################### @@ -436,30 +439,30 @@ def is_comparability_MILP(g, certificate=False, solver=None, verbose=0): p = MixedIntegerLinearProgram(solver=solver) o = p.new_variable(binary=True) - for u,v in g.edge_iterator(labels=False): - p.add_constraint( o[u,v] + o[v,u] == 1) + for u, v in g.edge_iterator(labels=False): + p.add_constraint(o[u, v] + o[v, u] == 1) for u in g: neighbors = g.neighbors(u) for i in range(len(neighbors)): v = neighbors[i] - for j in range(i+1,len(neighbors)): + for j in range(i + 1, len(neighbors)): vv = neighbors[j] # If there is an edge between v and vv, we must be # sure it is in the good direction when v-u-vv is a # directed path - if g.has_edge(v,vv): - p.add_constraint(o[u,v] + o[vv,u] - o[vv,v] <= 1) - p.add_constraint(o[u,vv] + o[v,u] - o[v,vv] <= 1) + if g.has_edge(v, vv): + p.add_constraint(o[u, v] + o[vv, u] - o[vv, v] <= 1) + p.add_constraint(o[u, vv] + o[v, u] - o[v, vv] <= 1) # If there is no edge, there are only two # orientations possible (see the module's documentation # about edges which imply each other) else: - p.add_constraint(o[u,v] + o[vv,u] <= 1) - p.add_constraint(o[u,vv] + o[v,u] <= 1) + p.add_constraint(o[u, v] + o[vv, u] <= 1) + p.add_constraint(o[u, vv] + o[v, u] <= 1) try: p.solve(log=verbose) @@ -473,11 +476,11 @@ def is_comparability_MILP(g, certificate=False, solver=None, verbose=0): tol = 0 if p.base_ring().is_exact() else 1e-6 o = p.get_values(o, convert=True, tolerance=tol) - for u,v in g.edge_iterator(labels=False): - if o[u,v]: - d.add_edge(u,v) + for u, v in g.edge_iterator(labels=False): + if o[u, v]: + d.add_edge(u, v) else: - d.add_edge(v,u) + d.add_edge(v, u) return True, d @@ -486,6 +489,7 @@ def is_comparability_MILP(g, certificate=False, solver=None, verbose=0): return False, None return False + ############### # Empty shell # ############### @@ -566,16 +570,17 @@ def is_comparability(g, algorithm="greedy", certificate=False, check=True, isit, certif = comparability_test if check and isit and (not certif.is_transitive()): - raise ValueError("Looks like there is a bug somewhere. The "+ - "algorithm thinks that the orientation is "+ - "transitive, but we just checked and it is not."+ - "Please report the bug on sage-devel, and give"+ + raise ValueError("Looks like there is a bug somewhere. The " + "algorithm thinks that the orientation is " + "transitive, but we just checked and it is not." + "Please report the bug on sage-devel, and give" "us the graph that made this method fail !") return isit, certif + def is_permutation(g, algorithm="greedy", certificate=False, check=True, - solver=None, verbose=0): + solver=None, verbose=0): r""" Tests whether the graph is a permutation graph. @@ -689,8 +694,8 @@ def is_permutation(g, algorithm="greedy", certificate=False, check=True, # Building the two orderings tmp = list(co_certif.edges(labels=False, sort=False)) - for u,v in certif.edge_iterator(labels=False): - co_certif.add_edge(v,u) + for u, v in certif.edge_iterator(labels=False): + co_certif.add_edge(v, u) certif.add_edges(tmp) ordering = certif.topological_sort() @@ -702,18 +707,17 @@ def is_permutation(g, algorithm="greedy", certificate=False, check=True, from sage.graphs.graph_generators import GraphGenerators pg = GraphGenerators().PermutationGraph(ordering, co_ordering) if not pg.is_isomorphic(g): - raise ValueError("There is a mistake somewhere ! It looks like "+ - "the Permutation Graph model computed does "+ + raise ValueError("There is a mistake somewhere ! It looks like " + "the Permutation Graph model computed does " "not match the input graph !") return True, (ordering, co_ordering) # No certificate... A piece of cake else: - return (is_comparability(g, algorithm=algorithm, solver=solver, verbose=verbose) and \ + return (is_comparability(g, algorithm=algorithm, solver=solver, verbose=verbose) and is_comparability(g.complement(), algorithm=algorithm, solver=solver, verbose=verbose)) -from sage.graphs.distances_all_pairs cimport c_distances_all_pairs def is_transitive(g, certificate=False): r""" @@ -768,8 +772,7 @@ def is_transitive(g, certificate=False): for j in range(n): for i in range(n): - if ((c_distances[i] != -1) and - (c_distances[i] > 1)): + if c_distances[i] != -1 and c_distances[i] > 1: sig_free(distances) if certificate: diff --git a/src/sage/graphs/convexity_properties.pyx b/src/sage/graphs/convexity_properties.pyx index c260daff32e..a7243cc8d7a 100644 --- a/src/sage/graphs/convexity_properties.pyx +++ b/src/sage/graphs/convexity_properties.pyx @@ -50,6 +50,7 @@ from sage.graphs.base.static_sparse_graph cimport (short_digraph, out_degree, simple_BFS) + cdef class ConvexityProperties: r""" This class gathers the algorithms related to convexity in a graph. @@ -251,7 +252,7 @@ cdef class ConvexityProperties: """ cdef int count cdef int tmp_count - cdef int i,j + cdef int i, j cdef bitset_t * p_bitset @@ -283,7 +284,6 @@ cdef class ConvexityProperties: # Next bitset ! p_bitset = p_bitset + 1 - tmp_count = bitset_len(hull) # If we added nothing new during the previous loop, our set is @@ -418,7 +418,7 @@ cdef class ConvexityProperties: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] """ cdef int i - cdef list constraint # temporary variable to add constraints to the LP + cdef list constraint # temporary variable to add constraints to the LP if self._n <= 2: if value_only: diff --git a/src/sage/graphs/digraph.py b/src/sage/graphs/digraph.py index a17d008e6b1..5b4c53e6f2c 100644 --- a/src/sage/graphs/digraph.py +++ b/src/sage/graphs/digraph.py @@ -3941,9 +3941,10 @@ def _rec_out_branchings(depth): This function makes use of the following to keep track of partial out branchings: - list_edges -- list of edges in self. - list_merged_edges -- list of edges that are currently merged - graph -- a copy of self where edges have an appropriate label + + - ``list_edges`` -- list of edges in self. + - ``list_merged_edges`` -- list of edges that are currently merged + - ``graph`` -- a copy of self where edges have an appropriate label """ if not depth: # We have enough merged edges to form a out_branching @@ -4158,9 +4159,10 @@ def _rec_in_branchings(depth): This function makes use of the following to keep track of partial in branchings: - list_edges -- list of edges in self. - list_merged_edges -- list of edges that are currently merged - graph -- a copy of self where edges have an appropriate label + + - ``list_edges`` -- list of edges in self. + - ``list_merged_edges`` -- list of edges that are currently merged + - ``graph`` -- a copy of self where edges have an appropriate label """ if not depth: # We have enough merged edges to form a in_branching diff --git a/src/sage/graphs/domination.py b/src/sage/graphs/domination.py index 73d8314b69e..69648d66658 100644 --- a/src/sage/graphs/domination.py +++ b/src/sage/graphs/domination.py @@ -15,7 +15,7 @@ :meth:`~is_dominating` | Check whether a set of vertices dominates a graph. :meth:`~is_redundant` | Check whether a set of vertices has redundant vertices (with respect to domination). :meth:`~private_neighbors` | Return the private neighbors of a vertex with respect to other vertices. - :meth:`~greedy_dominating_set` | Return a greedy distance-`k` dominating set of of the graph. + :meth:`~greedy_dominating_set` | Return a greedy distance-`k` dominating set of the graph. EXAMPLES: @@ -513,7 +513,7 @@ def _aux_with_rep(H, to_dom, u_next): .. WARNING:: - The same output may be output several times (up to |H| times). + The same output may be output several times (up to `|H|` times). In order to later remove duplicates, we here output pairs ``(ext, i)`` where ``ext`` is the output candidate extension and ``i`` counts how @@ -593,7 +593,7 @@ def minimal_dominating_sets(G, to_dominate=None, work_on_copy=True): - ``work_on_copy`` -- boolean (default: ``True``); whether or not to work on a copy of the input graph; if set to ``False``, the input graph will be modified (relabeled). - + OUTPUT: An iterator over the inclusion-minimal sets of vertices of ``G``. diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx new file mode 100644 index 00000000000..ca0469e1902 --- /dev/null +++ b/src/sage/graphs/edge_connectivity.pyx @@ -0,0 +1,1026 @@ +# cython: binding=True +# distutils: language = c++ +r""" +Edge connectivity + +This module implements methods for computing the edge-connectivity of graphs and +digraphs. It also implements methods to extract `k` edge-disjoint spanning trees +from a `2k` edge-connected graph or a `k` edge-connected digraph. + +.. TODO:: + + - Add speedup methods proposed in [GKLP2021]_ for the edge connectivity + - Implement the tree-packing algorithms proposed in [Gabow1995]_ and + [BHKP2008]_ + - Extend to digraphs with multiple edges + - Extend to weighted digraphs +""" +# **************************************************************************** +# Copyright (c) 2022 David Coudert +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from memory_allocator cimport MemoryAllocator +from cysignals.signals cimport sig_check +from sage.graphs.generic_graph_pyx cimport GenericGraph_pyx +from libc.limits cimport INT_MAX +from libcpp.pair cimport pair +from libcpp.vector cimport vector +from libcpp.queue cimport queue + + +cdef class GabowEdgeConnectivity: + r""" + Gabow's algorithm for finding the edge connectivity of digraphs. + + This class implements the algorithm proposed in [Gabow1995]_ for finding the + edge connectivity of a directed graph and `k` edge disjoint spanning trees + if the digraph is `k` edge connected. + + .. WARNING:: + + Multiple edges are currently not supported. The current implementation + act as if the digraph is simple and so the return results might not be + correct. We therefore raise an error if the digraph has multiple edges. + + INPUT: + + - ``D`` -- a :class:`~sage.graphs.digraph.DiGraph` + + EXAMPLES: + + 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(): + ....: D = DiGraph(graphs.RandomRegular(6, 50)) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 6 + + TESTS: + + :trac:`32169`:: + + sage: dig6_string = r'[E_S?_hKIH@eos[BSg???Q@FShGC?hTHUGM?IPug?' + sage: dig6_string += r'JOEYCdOzdkQGo@ADA@AAg?GAQW?' + sage: dig6_string += r'[aIaSwHYcD@qQb@Dd?\hJTI@OHlJ_?C_OEIKoeCR@_BC?Q?' + sage: dig6_string += r'?YBFosqITEA?IvCU_' + sage: D = DiGraph(dig6_string) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 5 + sage: GabowEdgeConnectivity(D).edge_disjoint_spanning_trees() + Traceback (most recent call last): + ... + NotImplementedError: this method has not been implemented yet + + Corner cases:: + + sage: [GabowEdgeConnectivity(DiGraph(n)).edge_connectivity() for n in range(4)] + [0, 0, 0, 0] + sage: D = digraphs.Circuit(3) * 2 + sage: D.add_edge(0, 3) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 0 + sage: D.add_edge(3, 0) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 1 + + Looped digraphs are supported but not digraphs with multiple edges:: + + sage: D = digraphs.Complete(5, loops=True) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + sage: D.allow_multiple_edges(True) + sage: D.add_edges(D.edges()) + sage: GabowEdgeConnectivity(D).edge_connectivity() + Traceback (most recent call last): + ... + ValueError: This method is not known to work on graphs with multiedges. ... + """ + cdef MemoryAllocator mem + cdef Py_ssize_t n # number of nodes + cdef Py_ssize_t m # number of arcs + + cdef int max_ec # upper bound on the edge connectivity + cdef int ec # current (proven) value of edge connectivity + cdef bint ec_checked # whether we have well computed edge connectivity + + cdef int UNUSED + cdef int FIRSTEDGE + + # The graph is stored as lists of incident edges + cdef readonly GenericGraph_pyx G # the original graph + cdef list int_to_vertex # mapping from integers to vertex labels + cdef vector[vector[int]] g_out + cdef vector[vector[int]] g_in + cdef vector[vector[int]] my_g # either g_out or g_in + + # values associated to edges + cdef int* tail # source of edge j + cdef int* head # target of edge j + cdef int* my_from # either tail or head + cdef int* my_to # either tail or head + + cdef int* labels # label of each edge given by the labeling algorithm, UNUSED if unlabeled + + cdef int* edge_state_1 # index of forest Ti to which belongs the arc j of g_out, UNUSED if not used + cdef int* edge_state_2 # index of forest Ti to which belongs the arc j of g_in, UNUSED if not used + cdef int* my_edge_state # either edge_state_1 or edge_state_2 + + # values associated to trees and forests + cdef int root_vertex # 0 by default + cdef int current_tree # index of the current tree + cdef int next_f_tree + cdef int augmenting_root + cdef bint* tree_flag # indicate whether a tree Ti has been touched + cdef int* root # current root vertex of f_tree i + cdef int* L_roots # L_roots of the trees + cdef bint* forests # indicate whether the f_tree is active or inactive + cdef bint** labeled # + + cdef int** parent_1 # parent of v in tree/forest Ti + cdef int** parent_2 # parent of v in tree/forest Ti + cdef int** my_parent # either parent_1 or parent_2 + cdef int** parent_edge_id_1 # edge id of parent of v in tree/forest Ti + cdef int** parent_edge_id_2 # edge id of parent of v in tree/forest Ti + cdef int** my_parent_edge_id # either parent_edge_id_1 or parent_edge_id_2 + cdef int** depth_1 # depth of v in tree/forest Ti + cdef int** depth_2 # depth of v in tree/forest Ti + cdef int** my_depth # either depth_1 or depth_2 + + # to store a path + cdef vector[int] A_path + cdef vector[int] left_traverse + cdef vector[int] right_traverse + + cdef bint* seen # for method re_init + cdef int* stack # stack of vertices for DFS in re_init + cdef vector[vector[int]] tree_edges # used to organise the edges of the trees + cdef vector[vector[int]] F # used to store a proven k-intersection (copy of tree_edges) + cdef vector[vector[int]] tree_edges_incident # lists of incident edges of a given tree + + cdef queue[int] my_Q # queue of labeled edges + cdef queue[pair[int, int]] joining_edges # queue of tuples (edge id, edge state) + cdef queue[int] incident_edges_Q # queue of edges + + def __init__(self, G): + r""" + Initialize this object. + + INPUT: + + - ``G`` -- a :class:`~sage.graphs.digraph.DiGraph` + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + self.ec_checked = False + from sage.graphs.digraph import DiGraph + if not isinstance(G, DiGraph): + raise ValueError("this method is for directed graphs only") + G._scream_if_not_simple(allow_loops=True) + if G.size() > INT_MAX - 2: + raise ValueError("the graph is too large for this code") + + # Trivial cases + if not G or not G.is_strongly_connected(): + self.ec = 0 + self.ec_checked = True + self.F.clear() + return + + # Set upper bound on the edge connectivity + self.max_ec = min(min(G.out_degree_iterator()), min(G.in_degree_iterator())) + + # + # Initialize some data structures + # + self.G = G + self.n = G.order() + self.m = G.size() + self.mem = MemoryAllocator() + + # Build compact graph data structure with out and in adjacencies + self.build_graph_data_structure() + # From now on, vertices are numbered in [0..n-1] and edges in [0..m-1] + + self.labels = self.mem.calloc(self.m, sizeof(int)) + self.tree_flag = self.mem.calloc(self.max_ec, sizeof(bint)) + self.forests = self.mem.calloc(self.n, sizeof(bint)) + self.L_roots = self.mem.calloc(self.max_ec, sizeof(int)) + self.labeled = self.mem.calloc(self.max_ec, sizeof(bint*)) + self.seen = self.mem.calloc(self.n, sizeof(bint)) + self.root = self.mem.calloc(self.n, sizeof(int)) + self.edge_state_1 = self.mem.calloc(self.m, sizeof(int)) + self.edge_state_2 = self.mem.calloc(self.m, sizeof(int)) + self.parent_1 = self.mem.calloc(self.max_ec, sizeof(int*)) + self.parent_2 = self.mem.calloc(self.max_ec, sizeof(int*)) + self.parent_edge_id_1 = self.mem.calloc(self.max_ec, sizeof(int*)) + self.parent_edge_id_2 = self.mem.calloc(self.max_ec, sizeof(int*)) + self.depth_1 = self.mem.calloc(self.max_ec, sizeof(int*)) + self.depth_2 = self.mem.calloc(self.max_ec, sizeof(int*)) + self.stack = self.mem.calloc(self.n, sizeof(int)) + self.tree_edges.resize(self.max_ec) + self.tree_edges_incident.resize(self.n) + + # Set some constants + self.UNUSED = INT_MAX + self.FIRSTEDGE = INT_MAX - 1 + + cdef int i + for i in range(self.m): + self.edge_state_1[i] = self.UNUSED # edge i is unused + self.edge_state_2[i] = self.UNUSED + self.labels[i] = self.UNUSED # edge i is unlabeled + + _ = self.compute_edge_connectivity() + sig_check() + + cdef build_graph_data_structure(self): + r""" + Build graph data structures. + + We assign each arc (u, v) a unique id and store in arrays the tail/head + of each arc. We use vector of vectors to quickly access incident edges. + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int i + self.int_to_vertex = list(self.G) + cdef dict vertex_to_int = {u: i for i, u in enumerate(self.int_to_vertex)} + + self.tail = self.mem.calloc(self.m, sizeof(int)) + self.head = self.mem.calloc(self.m, sizeof(int)) + self.g_out.resize(self.n) + self.g_in.resize(self.n) + for i in range(self.n): + self.g_out[i].clear() + self.g_in[i].clear() + + cdef int x, y + cdef int e_id = 0 + for x, u in enumerate(self.int_to_vertex): + for v in self.G.neighbor_out_iterator(u): + y = vertex_to_int[v] + self.g_out[x].push_back(e_id) + self.g_in[y].push_back(e_id) + self.tail[e_id] = x + self.head[e_id] = y + e_id += 1 + + cdef bint compute_edge_connectivity(self) except -1: + """ + Compute the edge connectivity using Round Robin algorithm. + + The method returns ``True`` if the computation ends normally. Otherwise + an exception is raised, for instance due to a keyboard interruption. + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int i + + self.root_vertex = 0 + self.next_f_tree = 0 + + # Search successively trees in g_in and g_out + self.ec = 0 + for i in range(self.max_ec): + if self.construct_trees(False, i) and self.construct_trees(True, i): + # We found both an in-arborescence and an out-arborescence. + # So we can increase the edge connectivity + self.ec += 1 + # and save the current k-intersection + self.save_current_k_intersection() + sig_check() + self.ec_checked = True + return True + + cdef bint construct_trees(self, bint reverse, int tree) except -1: + r""" + Search for an in or out arborescence. + + INPUT: + + - ``reverse`` -- boolean; whether to search for an in-arborescence + (``True``) or an out-arborescence (``False``) + + - ``tree`` -- integer; index of the tree + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + if reverse: + # Search for a spanning tree in g-reversed + self.my_g = self.g_out + self.my_from = self.head + self.my_to = self.tail + self.my_parent = self.parent_2 + self.my_depth = self.depth_2 + self.my_parent_edge_id = self.parent_edge_id_2 + self.my_edge_state = self.edge_state_2 + else: + # Search for a spanning tree in g using incoming arcs + self.my_g = self.g_in + self.my_from = self.tail + self.my_to = self.head + self.my_parent = self.parent_1 + self.my_depth = self.depth_1 + self.my_parent_edge_id = self.parent_edge_id_1 + self.my_edge_state = self.edge_state_1 + + self.current_tree = tree + self.increase_memory_for_new_tree(tree) + + cdef int njoins = 0 + cdef int z + + while njoins < self.n - 1: + # Get the root of an active subtree or INT_MAX if none exists + z = self.choose_root() + while z != INT_MAX: + if self.search_joining(z): + # We have augmented the root of the corresponding f_tree + njoins += 1 + else: + # We cannot find a tree + return False + + z = self.choose_root() + + # Trace the paths in order to transfer the edges to the appropriate + # tree Ti + self.augmentation_algorithm() + # Reinitialize data structures and make all f_trees active for next round + self.re_init(tree) + sig_check() + + return True + + cdef void increase_memory_for_new_tree(self, int tree): + """ + Allocate data structure for the new tree/forest. + + This method also initializes data structures for this tree index. Data + structures for a given tree index are allocatated only once. + + INPUT: + + - ``tree`` -- integer; index of the tree + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + if not self.labeled[tree]: + self.labeled[tree] = self.mem.calloc(self.n, sizeof(bint)) + if not self.my_parent[tree]: + self.my_parent[tree] = self.mem.calloc(self.n, sizeof(int)) + if not self.my_depth[tree]: + self.my_depth[tree] = self.mem.calloc(self.n, sizeof(int)) + if not self.my_parent_edge_id[tree]: + self.my_parent_edge_id[tree] = self.mem.calloc(self.n, sizeof(int)) + + cdef int j + for j in range(self.n): + self.my_parent[tree][j] = 0 + self.my_parent_edge_id[tree][j] = self.UNUSED + self.my_depth[tree][j] = 0 + self.labeled[tree][j] = False + self.root[j] = j + self.forests[j] = True + + # Set inactive the f_trees of the root vertex + self.forests[self.root_vertex] = False + + self.L_roots[tree] = self.UNUSED + self.tree_flag[tree] = False + + cdef int choose_root(self): + """ + Return the root of an active f_tree, or INT_MAX if none exists. + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int v + cdef int i + + for i in range(self.next_f_tree, self.n): + v = self.root[i] + if self.forests[v]: + # this forest is active + self.next_f_tree = i + 1 + return v + return INT_MAX + + cdef bint search_joining(self, int x) except -1: + """ + Try to augment the f_tree rooted at x. + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int y + cdef int joining_edge + cdef int e_id, ep + + # Store the vertex that is about to be augmented + self.augmenting_root = x + + # Consider the incoming arcs of x + for e_id in self.my_g[x]: + y = self.my_from[e_id] + # find the root of the f_tree + y = self.root[y] + + if self.my_edge_state[e_id] == self.UNUSED: + # The edge is available + if x != y: + # ... and the f_trees have different roots. We set the + # label of edges in the queue to UNUSED and clear the queue + while not self.my_Q.empty(): + ep = self.my_Q.front() + self.my_Q.pop() + self.labels[ep] = self.UNUSED + # We then assign the edge to the current_tree + self.join(e_id) + return True + else: + # The f_trees have the same root (cycle). + # We add the edge to the queue + self.my_Q.push(e_id) + # and indicate the first edge of the path + self.labels[e_id] = self.FIRSTEDGE + + # If we did not find a free joining edge, we check for a sequence of + # swaps in order to free a joining edge + + # Initialize the L_i tree of every T_i with vertex x and make x labeled + cdef int i + for i in range(self.current_tree + 1): + self.L_roots[i] = x + self.labeled[i][x] = True + + # Start cycle_scanning algorithm + joining_edge = self.next_joining_edge_step() + sig_check() + + if joining_edge != INT_MAX: + # We found a joining edge + self.joining_edges.push((joining_edge, self.my_edge_state[joining_edge])) + self.join(joining_edge) + return True + return False + + cdef void join(self, int e_id): + """ + Assign edge e_id to current tree. + + This method joins 2 f_trees and updates the root of the new f_tree. + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int x = self.my_from[e_id] + cdef int y = self.my_to[e_id] + cdef int root_x = self.root[x] + cdef int root_y = self.root[y] + + # Add the edge to the current tree + self.my_edge_state[e_id] = self.current_tree + + # Make the 2 joined f_trees inactive + self.forests[root_x] = False + self.forests[root_y] = False + + # Update the root of the joining f_tree + if self.augmenting_root == root_y: + self.root[root_y] = self.root[root_x] + else: + self.root[root_x] = self.root[root_y] + + # Empty the queue + while not self.my_Q.empty(): + self.my_Q.pop() + + cdef int next_joining_edge_step(self) except -1: + """ + Process edges in the queue and start labeling until the queue is empty + or a joining edge is found. + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int e_id + cdef int found_joining + cdef int tree = 0 + + while not self.my_Q.empty(): + e_id = self.my_Q.front() + self.my_Q.pop() + + if self.my_edge_state[e_id] == tree: + # edge e_id is in Ti + tree += 1 + if tree > self.current_tree: + tree = 0 + + self.tree_flag[tree] = True + + # Search for the fundamental cycle of e_id in Ti + found_joining = self.fundamental_cycle_step(e_id, tree) + sig_check() + if found_joining != INT_MAX: + return found_joining + + return INT_MAX + + cdef int fundamental_cycle_step(self, int e_id, int tree) except -1: + """ + Traverse tree paths from the endpoints of edge e_id to build A_path + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int x = self.my_to[e_id] + cdef int y = self.my_from[e_id] + cdef bint left_first = True + + if self.labeled[tree][x]: + # Node x is labeled. We go to the root of Li + x = self.L_roots[tree] + elif not self.labeled[tree][y]: + raise ValueError("error in labeling") + if self.labeled[tree][y]: + # Node y is labeled. We go to the root of Li + y = self.L_roots[tree] + left_first = False + if x == y: + # The fundamental cycle contains no unlabeled edge + return INT_MAX + + cdef bint stop = False + cdef int q + cdef vector[int] left_traverse + cdef vector[int] right_traverse + left_traverse.clear() + right_traverse.clear() + + # Start double traversal + while True: + + while self.my_depth[tree][x] >= self.my_depth[tree][y]: + self.labeled[tree][x] = True + q = self.my_parent_edge_id[tree][x] + if q == self.UNUSED: + raise ValueError("did not find the right edge") + # We check if edge q is unlabeled + if self.labels[q] == self.UNUSED: + # If so, we place it in left_traverse array + left_traverse.push_back(q) + if self.is_joining_edge(q): + self.labels[q] = e_id + return q + x = self.my_parent[tree][x] + else: + # Otherwise, we stop + stop = True + break + if x == y: + break + + while self.my_depth[tree][y] > self.my_depth[tree][x]: + self.labeled[tree][y] = True + q = self.my_parent_edge_id[tree][y] + if q == self.UNUSED: + raise ValueError("did not find the right edge") + # We check if edge q is unlabeled + if self.labels[q] == self.UNUSED: + # If so, we place it in right_traverse array + right_traverse.push_back(q) + if self.is_joining_edge(q): + self.labels[q] = e_id + return q + y = self.my_parent[tree][y] + else: + # Otherwise, we stop + stop = True + break + + if x == y or stop: + break + + if x == y: + # Update the L_root of the tree + self.L_roots[tree] = x + self.labeled[tree][x] = True + + # Compute A_path + self.A_path.clear() + if left_first: + for x in left_traverse: + self.A_path.push_back(x) + for x in range(right_traverse.size() - 1, -1, -1): + self.A_path.push_back(right_traverse[x]) + else: + for x in right_traverse: + self.A_path.push_back(x) + for x in range(left_traverse.size() - 1, -1, -1): + self.A_path.push_back(left_traverse[x]) + + return self.label_A_path(e_id) + + cdef bint is_joining_edge(self, int e_id): + """ + Check if edge e_id is joining. + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int root_x = self.root[self.my_from[e_id]] + cdef int root_y = self.root[self.my_to[e_id]] + return (root_x != root_y) and (root_x == self.augmenting_root or root_y == self.augmenting_root) + + cdef int label_A_path(self, int e_id): + """ + Labels the incident unused edges as the label_A_step of the algorithm + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int e, ep + + for e in self.A_path: + # Run label step with edge e and label e_id + if self.label_step(e, e_id): + return e + + if self.any_unused_is_unlabeled(self.my_to[e]): + while not self.incident_edges_Q.empty(): + ep = self.incident_edges_Q.front() + self.incident_edges_Q.pop() + if e != ep: + # Label each unused and unlabeled edge ep with e + if self.label_step(ep, e): + while not self.incident_edges_Q.empty(): + self.incident_edges_Q.pop() + return ep + + while not self.incident_edges_Q.empty(): + self.incident_edges_Q.pop() + + return INT_MAX + + cdef bint label_step(self, int e_id, int e_label): + """ + Label edge e_id with e_label and check wheteher edge e_id is joining. + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + self.labels[e_id] = e_label + + cdef int root_x = self.root[self.my_from[e_id]] + cdef int root_y = self.root[self.my_to[e_id]] + + if root_x == root_y: + self.my_Q.push(e_id) + return False + # The roots are different. Check whether one of them is on the f_tree + return root_x == self.augmenting_root or root_y == self.augmenting_root + + cdef bint any_unused_is_unlabeled(self, int x): + """ + Check if each unused edge directed to x is unlabeled + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int e_id + for e_id in self.my_g[x]: + if self.my_edge_state[e_id] == self.UNUSED: + if self.labels[e_id] != self.UNUSED: + return False + self.incident_edges_Q.push(e_id) + + return True + + cdef void augmentation_algorithm(self): + """ + Trace the path of the found joining edges + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int e_id, e_state + while not self.joining_edges.empty(): + e_id, e_state = self.joining_edges.front() + self.joining_edges.pop() + self.trace_back(e_id, e_state) + + cdef void trace_back(self, int e_id, int e_state): + """ + Trace the path of a joining edge and transfer the edges to the + appropriate tree Ti. + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + # Target x and source y of joining edge e_id + cdef int x = self.my_to[e_id] + cdef int y = self.my_from[e_id] + # Previous state (tree Ti or unused) of an edge + cdef int previous_state = self.FIRSTEDGE + + cdef int tree + cdef int e = self.labels[e_id] + cdef int ep = self.labels[e] + + if e_state == self.UNUSED: + tree = self.my_edge_state[e] + previous_state = self.my_edge_state[ep] + + # Transfer edge ep to tree Ti and remove edge e + self.my_edge_state[ep] = tree + self.my_edge_state[e] = self.UNUSED + + e = ep + ep = self.labels[e] + else: + tree = e_state + 1 + if tree > self.current_tree: + tree = 0 + e = e_id + ep = self.labels[e] + + # Transfer edges to the appropriate Ti + while ep != self.FIRSTEDGE: + tree -= 1 + if tree < 0: + tree = self.current_tree + + if previous_state == self.UNUSED: + e = ep + ep = self.labels[e] + self.my_edge_state[e] = self.UNUSED + + previous_state = self.my_edge_state[ep] + self.my_edge_state[ep] = tree + e = ep + ep = self.labels[e] + + cdef re_init(self, int tree): + """ + Make f_trees active (except the f_tree of the root), update depths and + parent values, and clear the labels. + + This method is called at the end of each round of method + construct_trees, right after the call to augmentation_algorithm. + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int i, j + for j in range(self.m): + self.labels[j] = self.UNUSED + + # Arrange the edges of each tree + for j in range(tree + 1): + self.tree_edges[j].clear() + for j in range(self.m): + if self.my_edge_state[j] != self.UNUSED: + self.tree_edges[self.my_edge_state[j]].push_back(j) + + for j in range(tree + 1): + if not j or j == tree or self.tree_flag[j]: + # Build adjacency lists of incident edges (ignore direction) + for i in range(self.n): + self.tree_edges_incident[i].clear() + for i in self.tree_edges[j]: + self.tree_edges_incident[self.my_from[i]].push_back(i) + self.tree_edges_incident[self.my_to[i]].push_back(i) + + self.update_parents_depths(j) + + for i in range(tree + 1): + self.L_roots[i] = self.UNUSED # clear the root of each Li + self.tree_flag[i] = False + + # Unlabel all nodes from every Ti + for j in range(self.n): + self.labeled[i][j] = False + + self.next_f_tree = 0 + + # Finally, set active the roots of subtrees + for i in range(self.n): + j = self.root[i] + if j != self.root_vertex: + self.forests[j] = True + + cdef void update_parents_depths(self, int tree): + """ + Update parents, depths, and, if current_tree is k, the vertex labels to + the root of each f_tree. + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int i, v + + for i in range(self.n): + self.my_parent[tree][i] = i + self.my_depth[tree][i] = 0 + self.seen[i] = False + + self.update_parents_dfs(tree, self.root_vertex) + + if tree == self.current_tree: + for i in range(self.n): + v = self.root[i] + if self.root[v] != v: + v = self.root[v] + if not self.seen[v]: + self.update_parents_dfs(tree, v) + self.root[i] = self.root[v] + + cdef void update_parents_dfs(self, int tree, int x): + """ + Helper method for ``update_parents_depths``. + + This method updates parents and depths in specified ``tree`` starting + from vertex ``x`` in depth first search manner. + + INPUT: + + - ``tree`` -- integer; index of the tree in which to update data + + - ``x`` -- integer; vertex from which to start the DFS + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int u, v, e_id + cdef int depth + cdef int i = 1 + self.stack[0] = x + self.seen[x] = True + + while i > 0: + i -= 1 + u = self.stack[i] + depth = self.my_depth[tree][u] + 1 + for e_id in self.tree_edges_incident[u]: + v = self.my_to[e_id] + if v == u: + v = self.my_from[e_id] + if not self.seen[v]: + self.stack[i] = v + i += 1 + self.seen[v] = True + self.my_parent[tree][v] = u + self.my_parent_edge_id[tree][v] = e_id + self.my_depth[tree][v] = depth + + cdef void save_current_k_intersection(self): + """ + Save the current k-intersection. + + This method is called each time the upper bound on the edge connectivity + has been increased. The k-intersection will be used to extract the + edge-disjoint spanning trees. If asking for the edge connectivity only, + there is no need to call this method. + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + cdef int i, j + cdef int size = self.tree_edges.size() + self.F.resize(size) + for i in range(size): + self.F[i].clear() + for j in self.tree_edges[i]: + self.F[i].push_back(j) + + def edge_connectivity(self): + """ + Return the edge connectivity of the digraph. + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_connectivity() + 4 + """ + if self.ec_checked: + return self.ec + raise ValueError("the value of the edge connectivity has not been " + "properly computed. This may result from an interruption") + + + # + # Packing arborescences + # + + def edge_disjoint_spanning_trees(self): + r""" + Iterator over the edge disjoint spanning trees. + + EXAMPLES:: + + sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity + sage: D = digraphs.Complete(5) + sage: GabowEdgeConnectivity(D).edge_disjoint_spanning_trees() + Traceback (most recent call last): + ... + NotImplementedError: this method has not been implemented yet + """ + raise NotImplementedError('this method has not been implemented yet') diff --git a/src/sage/graphs/generators/basic.py b/src/sage/graphs/generators/basic.py index a105262525a..8a7e19080ff 100644 --- a/src/sage/graphs/generators/basic.py +++ b/src/sage/graphs/generators/basic.py @@ -742,23 +742,23 @@ def ToroidalGrid2dGraph(p, q): sage: tgrid.is_regular() True """ - g = Grid2dGraph(p, q, set_positions=False) + g = Grid2dGraph(p, q, set_positions=True) g.add_edges([((i, 0), (i, q - 1)) for i in range(p)]) g.add_edges([((0, i), (p - 1, i)) for i in range(q)]) g.name("Toroidal 2D Grid Graph with parameters {},{}".format(p, q)) - d = g.get_pos() + pos = g._pos p += 0. q += 0. uf = (p / 2) * (p / 2) vf = (q / 2) * (q / 2) - for u, v in d: - x, y = d[u, v] + for u, v in g: + x, y = pos[u, v] x += 0.25 * (1.0 + u * (u - p + 1) / uf) - y += 0.25 * (1 + v * (v - q + 1) / vf) - d[u, v] = (x, y) + y += 0.25 * (1.0 + v * (v - q + 1) / vf) + pos[u, v] = (x, y) return g diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index aab205a94f8..1632b658353 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -3068,11 +3068,11 @@ def petersen_family(generate=False): g = Graph('Fs\\zw') g._circle_embedding([1, 2, 3]) g._circle_embedding([4, 5, 6], radius=.7) - g.get_pos()[0] = (0, 0) + g._pos[0] = (0, 0) l.append(g) g = Graph('GYQ[p{') g._circle_embedding([1, 4, 6, 0, 5, 7, 3], shift=0.25) - g.get_pos()[2] = (0, 0) + g._pos[2] = (0, 0) l.append(g) return l @@ -3755,7 +3755,7 @@ def RingedTree(k, vertex_labels = True): g._circle_embedding(vertices, radius = radius, shift = shift) # Specific position for the central vertex - g.get_pos()[0] = (0,0.2) + g._pos[0] = (0,0.2) # Relabel vertices as binary words if not vertex_labels: diff --git a/src/sage/graphs/generators/smallgraphs.py b/src/sage/graphs/generators/smallgraphs.py index 0feadd997a8..00ce30403bb 100644 --- a/src/sage/graphs/generators/smallgraphs.py +++ b/src/sage/graphs/generators/smallgraphs.py @@ -1217,7 +1217,7 @@ def BlanusaFirstSnarkGraph(): g.add_cycle(list(range(17))) g._circle_embedding(list(range(17)), shift=0.25) - g.get_pos()[17] = (0, 0) + g._pos[17] = (0, 0) return g @@ -1715,7 +1715,7 @@ def KittellGraph(): g._circle_embedding(list(range(3)), shift=.75) g._circle_embedding(list(range(3, 13)), radius=.4) g._circle_embedding(list(range(15, 22)), radius=.2, shift=-.15) - pos = g.get_pos() + pos = g._pos pos[13] = (-.65, -.35) pos[14] = (.65, -.35) pos[22] = (0, 0) @@ -1887,7 +1887,7 @@ def CoxeterGraph(): g._circle_embedding(list(range(24))) g._circle_embedding([24, 25, 26], radius=.5) - g.get_pos()[27] = (0, 0) + g._pos[27] = (0, 0) g.name("Coxeter Graph") @@ -2210,7 +2210,7 @@ def EllinghamHorton54Graph(): g._circle_embedding(list(range(40, 46)), center=(1.5, -1), radius=.5) g._circle_embedding(list(range(46, 52)), center=(1.5, -1), radius=.7) - d = g.get_pos() + d = g._pos d[52] = (-.3, -2.5) d[53] = (.3, -2.5) d[31] = (-2.2, -.9) @@ -2280,7 +2280,7 @@ def EllinghamHorton78Graph(): g._circle_embedding([45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 75, 59], center=(2.5, -1.5)) - d = g.get_pos() + d = g._pos d[76] = (-.2, -.1) d[77] = (.2, .1) @@ -3898,7 +3898,7 @@ def PoussinGraph(): g._circle_embedding(list(range(3)), shift=.75) g._circle_embedding(list(range(3, 9)), radius=.4, shift=0) g._circle_embedding(list(range(9, 14)), radius=.2, shift=.4) - g.get_pos()[14] = (0, 0) + g._pos[14] = (0,0) return g @@ -4251,7 +4251,7 @@ def SousselierGraph(): g.add_edges([(15, i) for i in range(15) if i % 3 == 1]) g._circle_embedding(list(range(15)), shift=-.25) - g.get_pos()[15] = (0, 0) + g._pos[15] = (0, 0) return g @@ -4547,7 +4547,7 @@ def TutteGraph(): radius=.2, center=(.6*cos(2*(i + .25)*pi/3), .6*sin(2*(i + .25)*pi/3))) - g.get_pos()[0] = (0, 0) + g._pos[0] = (0,0) return g @@ -4671,7 +4671,6 @@ def WienerArayaGraph(): g.add_edge((3, 4), (2, 14)) g.add_edge((3, 1), (3, 4)) - g.get_pos().pop(0) g.relabel() return g diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index c5ef0c06ec5..e6ca8a4c09c 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -314,7 +314,7 @@ :meth:`~GenericGraph.multicommodity_flow` | Solve a multicommodity flow problem. :meth:`~GenericGraph.disjoint_routed_paths` | Return a set of disjoint routed paths. :meth:`~GenericGraph.dominating_set` | Return a minimum dominating set of the graph - :meth:`~GenericGraph.greedy_dominating_set` | Return a greedy distance-`k` dominating set of of the graph. + :meth:`~GenericGraph.greedy_dominating_set` | Return a greedy distance-`k` dominating set of the graph. :meth:`~GenericGraph.subgraph_search` | Return a copy of ``G`` in ``self``. :meth:`~GenericGraph.subgraph_search_count` | Return the number of labelled occurrences of ``G`` in ``self``. :meth:`~GenericGraph.subgraph_search_iterator` | Return an iterator over the labelled copies of ``G`` in ``self``. @@ -2244,7 +2244,7 @@ def distance_matrix(self, vertices=None, *, base_ring=None, **kwds): * :meth:`~sage.graphs.generic_graph.GenericGraph.distance_all_pairs` -- computes the distance between any two vertices. - TESTS:: + TESTS: Asking for an immutable matrix:: @@ -2662,12 +2662,12 @@ def set_embedding(self, embedding): def get_embedding(self): """ - Return the attribute ``_embedding`` if it exists. + Return the stored embedding or ``None``. - ``_embedding`` is a dictionary organized with vertex labels as keys and - a list of each vertex's neighbors in clockwise order. - - Error-checked to insure valid embedding is returned. + If the stored embedding is no longer valid (because of vertex/edge + additions) then the stored embedding is discarded and ``None`` is + returned. In case some vertex/edge has been deleted, the stored + embedding is updated accordingly. EXAMPLES:: @@ -2676,11 +2676,57 @@ def get_embedding(self): 1 sage: G.get_embedding() {0: [1, 4, 5], 1: [0, 2, 6], 2: [1, 3, 7], 3: [2, 4, 8], 4: [0, 3, 9], 5: [0, 7, 8], 6: [1, 9, 8], 7: [2, 5, 9], 8: [3, 6, 5], 9: [4, 6, 7]} + + Note that the embeddings gets properly modified on vertex or edge deletion:: + + sage: G.delete_edge(0, 1) + sage: G.delete_vertex(3) + sage: G.get_embedding() + {0: [4, 5], + 1: [2, 6], + 2: [1, 7], + 4: [0, 9], + 5: [0, 7, 8], + 6: [1, 9, 8], + 7: [2, 5, 9], + 8: [6, 5], + 9: [4, 6, 7]} + + But not under edge addition:: + + sage: G.add_edge(0, 7) + sage: G.get_embedding() is None + True """ - if self._check_embedding_validity(): - return self._embedding - else: - raise ValueError('%s has been modified and the embedding is no longer valid'%self) + try: + embedding = self._embedding + except AttributeError: + embedding = None + if embedding is not None: + # remove vertices not anymore in the graph + to_remove = set(v for v in embedding if v not in self) + if to_remove: + for v in to_remove: + del embedding[v] + for v in embedding: + embedding[v] = [w for w in embedding[v] if w not in to_remove] + + # remove edges not anymore in the graph + for u in embedding: + i = 0 + while i < len(embedding[u]): + v = embedding[u][i] + if not (self.has_edge(u, v) or self.has_edge(v, u)): + del embedding[u][i] + else: + i += 1 + + if self._check_embedding_validity(): + return embedding + else: + self._embedding = None + + return None def _check_embedding_validity(self, embedding=None, boolean=True): """ @@ -2733,7 +2779,10 @@ def _check_embedding_validity(self, embedding=None, boolean=True): """ if embedding is None: - embedding = getattr(self, '_embedding', None) + try: + embedding = self._embedding + except AttributeError: + pass if embedding is None: if boolean: return False @@ -3490,14 +3539,49 @@ def get_pos(self, dim=2): {0: (0.0, 1.0), ... 9: (0.475..., 0.154...)} + + Note that the position dictionary is modified on vertex removal:: + + sage: G.delete_vertex(0) + sage: G.get_pos() + {1: (-0.951..., 0.309...), + ... + 9: (0.475..., 0.154...)} + + But is deleted on vertex addition:: + + sage: G.add_vertex(0) + sage: G.get_pos() is None + True """ if dim == 2: - return self._pos + try: + pos = self._pos + except AttributeError: + pos = None elif dim == 3: - return getattr(self, "_pos3d", None) + try: + pos = self._pos3d + except AttributeError: + pos = None else: raise ValueError("dim must be 2 or 3") + if pos is not None: + # take care of possible vertex removal + for v in list(pos): + if v not in self: + del pos[v] + + if self._check_pos_validity(dim=dim): + return pos + elif dim == 2: + pos = self._pos = None + else: + pos = self._pos3d = None + + return pos + def _check_pos_validity(self, pos=None, dim=2): r""" Check whether ``pos`` specifies two (resp. 3) coordinates for every @@ -3525,7 +3609,16 @@ def _check_pos_validity(self, pos=None, dim=2): True """ if pos is None: - pos = self.get_pos(dim=dim) + if dim == 2: + try: + pos = self._pos + except AttributeError: + pass + elif dim == 3: + try: + pos = self._pos3d + except AttributeError: + pass if pos is None: return False if len(pos) != self.order(): @@ -3549,10 +3642,7 @@ def set_pos(self, pos, dim=2): - ``dim`` -- integer (default: 2); the number of coordinates per vertex - EXAMPLES: - - Note that :meth:`~GenericGraph.set_pos` will allow you to do ridiculous - things, which will not blow up until plotting:: + EXAMPLES:: sage: G = graphs.PetersenGraph() sage: G.get_pos() @@ -3560,14 +3650,19 @@ def set_pos(self, pos, dim=2): ... 9: (..., ...)} - :: + The method :meth:`get_pos` check the position dictionary so that + invalid positioning are ignored:: - sage: G.set_pos('spam') - sage: P = G.plot() - Traceback (most recent call last): - ... - TypeError: string indices must be integers... + sage: G.set_pos(dict(enumerate('abcdefghi'))) + sage: P = G.plot() # positions are ignored + sage: G.get_pos() is None + True """ + if pos is None: + return + + if not isinstance(pos, dict): + raise ValueError('pos must be a dictionary whose keys are vertices and values the positions') if dim == 2: self._pos = pos elif dim == 3: @@ -5124,6 +5219,13 @@ def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, se ....: assert (hasattr(G, '_embedding') and G._embedding is not None) == set_embedding, (set_embedding, set_pos) ....: assert (hasattr(G, '_pos') and G._pos is not None) == set_pos, (set_embedding, set_pos) + :trac:`34122`:: + + sage: G = DiGraph([[1, 2], [1, 4], [1, 5], [2, 3], [2, 4], [2, 5], + ....: [3, 4], [3, 5], [4, 5], [5, 1]]) + sage: G.is_planar() + True + Corner cases:: sage: graphs.EmptyGraph().is_planar() @@ -5133,7 +5235,8 @@ def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, se """ # Quick check first if (on_embedding is None and not kuratowski and not set_embedding and not set_pos - and not self.allows_loops() and not self.allows_multiple_edges()): + and not self.allows_loops() and not self.allows_multiple_edges() + and not self.is_directed()): if self.order() > 4 and self.size() > 3 * self.order() - 6: return False @@ -5151,7 +5254,7 @@ def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, se G = self.to_undirected() if hasattr(G, '_immutable'): G = copy(G) - planar = is_planar(G,kuratowski=kuratowski, set_pos=set_pos, set_embedding=set_embedding) + planar = is_planar(G, kuratowski=kuratowski, set_pos=set_pos, set_embedding=set_embedding) if kuratowski: bool_result = planar[0] else: @@ -7342,6 +7445,7 @@ def max_cut(self, value_only=True, use_edge_labels=False, vertices=False, if use_edge_labels: from sage.rings.real_mpfr import RR + def weight(x): return x if x in RR else 1 else: @@ -9097,6 +9201,7 @@ def flow(self, x, y, value_only=True, integer=False, use_edge_labels=True, from sage.rings.real_mpfr import RR if integer: from math import floor + def capacity(z): return floor(z) if z in RR else 1 else: @@ -10388,19 +10493,17 @@ def delete_vertex(self, vertex, in_order=False): if vertex not in self: raise ValueError("vertex (%s) not in the graph"%str(vertex)) - attributes_to_update = ('_pos', '_assoc') - for attr in attributes_to_update: - if hasattr(self, attr) and getattr(self, attr) is not None: - getattr(self, attr).pop(vertex, None) + # TODO: remove this update from this method which should be as fast + # as possible + try: + assoc = self._assoc + except AttributeError: + assoc = None + if assoc is not None: + assoc.pop(vertex, None) - if hasattr(self, '_embedding'): - embedding = self._embedding - if embedding is not None: - neighbors = set(self.neighbor_iterator(vertex)) - neighbors.discard(vertex) - for w in neighbors: - embedding[w] = [x for x in embedding[w] if x != vertex] - embedding.pop(vertex, None) + # NOTE: we do not update _embedding, _pos or _pos3d as this is done in + # the get_embedding and get_pos methods self._backend.del_vertex(vertex) @@ -10441,21 +10544,18 @@ def delete_vertices(self, vertices): if v not in self: raise ValueError("vertex (%s) not in the graph"%str(v)) - for attr in ('_pos', '_assoc'): - if hasattr(self, attr) and getattr(self, attr) is not None: - attr_dict = getattr(self, attr) - for v in vertices: - attr_dict.pop(v, None) + # TODO: remove this update from this method which should be as fast + # as possible + try: + assoc = self._assoc + except AttributeError: + assoc = None + if assoc is not None: + for v in vertices: + assoc.pop(v, None) - if hasattr(self, '_embedding'): - embedding = self._embedding - if embedding is not None: - neighbors = set().union(*[self.neighbor_iterator(v) for v in vertices]) - neighbors.difference_update(vertices) - for w in neighbors: - embedding[w] = [x for x in embedding[w] if x not in vertices] - for v in vertices: - embedding.pop(v, None) + # NOTE: the _embedding, _pos and _pos3d attributes are modified directly + # in get_embedding and get_pos methods self._backend.del_vertices(vertices) @@ -10761,12 +10861,14 @@ def set_vertex(self, vertex, object): ... ValueError: vertex (4) not in the graph """ - if hasattr(self, '_assoc') is False: - self._assoc = {} - if not self.has_vertex(vertex): raise ValueError('vertex (%s) not in the graph' % str(vertex)) + try: + assoc = self._assoc + except AttributeError: + assoc = self._assoc = {} + self._assoc[vertex] = object def get_vertex(self, vertex): @@ -10816,7 +10918,7 @@ def get_vertices(self, verts=None): if verts is None: verts = list(self) - if hasattr(self, '_assoc') is False: + if not hasattr(self, '_assoc'): return dict.fromkeys(verts, None) return {v: self._assoc.get(v, None) for v in verts} @@ -12491,33 +12593,25 @@ def clear(self): EXAMPLES:: - sage: G=graphs.CycleGraph(4); G.set_vertices({0:'vertex0'}) - sage: G.order(); G.size() - 4 - 4 - sage: len(G._pos) - 4 + sage: G = graphs.CycleGraph(4) + sage: G.set_vertices({0:'vertex0'}) + sage: print(G.order(), G.size()) + 4 4 sage: G.name() 'Cycle graph' sage: G.get_vertex(0) 'vertex0' sage: H = G.copy(sparse=True) sage: H.clear() - sage: H.order(); H.size() - 0 - 0 - sage: len(H._pos) - 0 + sage: print(H.order(), H.size()) + 0 0 sage: H.name() '' sage: H.get_vertex(0) sage: H = G.copy(sparse=False) sage: H.clear() - sage: H.order(); H.size() - 0 - 0 - sage: len(H._pos) - 0 + sage: print(H.order(), H.size()) + 0 0 sage: H.name() '' sage: H.get_vertex(0) @@ -13138,11 +13232,22 @@ def _subgraph_by_adding(self, vertices=None, edges=None, edge_property=None, imm edges_to_keep = [e for e in edges_to_keep if edge_property(e)] G.add_edges(edges_to_keep) - attributes_to_update = ('_pos', '_assoc') - for attr in attributes_to_update: - if hasattr(self, attr) and getattr(self, attr) is not None: - value = {v: getattr(self, attr).get(v, None) for v in G} - setattr(G, attr, value) + # copy _assoc, _pos, _pos3d and _embedding to the subgraph + try: + assoc = self._assoc + except AttributeError: + assoc = None + if assoc is not None: + G._assoc = {v: assoc[v] for v in G if v in assoc} + pos = self.get_pos() + if pos is not None: + G._pos = {v: pos[v] for v in G if v in pos} + pos3d = self.get_pos(dim=3) + if pos3d is not None: + G._pos3d = {v: pos3d[v] for v in G if v in pos3d} + embedding = self.get_embedding() + if embedding is not None: + G._embedding = {u: [v for v in embedding[u] if u in G] for u in G} if immutable is None: immutable = self.is_immutable() @@ -15428,7 +15533,7 @@ def _girth_bfs(self, odd=False, certificate=False): INPUT: - ``odd`` -- boolean (default: ``False``); whether to compute the odd - girth instead instead of the girth + girth instead of the girth - ``certificate`` -- boolean (default: ``False``); whether to return ``(g, c)``, where ``g`` is the (odd) girth and ``c`` is a list @@ -19594,11 +19699,7 @@ def layout_tree(self, tree_orientation="down", tree_root=None, raise RuntimeError("cannot use tree layout on this graph: " "self.is_tree() returns False") - try: - emb = self.get_embedding() - use_embedding = True - except ValueError: - use_embedding = False + emb = self.get_embedding() if tree_root is None: root = self.center()[0] @@ -19608,7 +19709,7 @@ def layout_tree(self, tree_orientation="down", tree_root=None, pos = {} # The children and parent of each vertex - if not use_embedding: + if emb is None: children = {root: self.neighbors(root)} else: children = {root: emb[root]} @@ -19686,7 +19787,7 @@ def slide(v, dx): pt = parent[t] - if not use_embedding: + if emb is None: ct = [u for u in self.neighbor_iterator(t) if u != pt] else: ct = emb[t] @@ -19904,9 +20005,17 @@ def _circle_embedding(self, vertices, center=(0, 0), radius=1, shift=0, angle=0, c_x, c_y = center vertices = list(vertices) n = len(vertices) - d = self.get_pos() - if d is None or return_dict: - d = {} + + if return_dict: + pos = {} + else: + pos = None + try: + pos = self._pos + except AttributeError: + pass + if pos is None: + pos = self._pos = {} from math import sin, cos, pi for i,v in enumerate(vertices): @@ -19915,12 +20024,10 @@ def _circle_embedding(self, vertices, center=(0, 0), radius=1, shift=0, angle=0, # when asking for sin(pi) v_x = c_x + radius * round(cos(angle + 2*i*pi / n), 10) v_y = c_y + radius * round(sin(angle + 2*i*pi / n), 10) - d[v] = (v_x, v_y) + pos[v] = (v_x, v_y) if return_dict: - return d - else: - self.set_pos(d) + return pos def _line_embedding(self, vertices, first=(0, 0), last=(0, 1), return_dict=False): r""" @@ -19971,9 +20078,17 @@ def _line_embedding(self, vertices, first=(0, 0), last=(0, 1), return_dict=False {} """ vertices = list(vertices) - d = self.get_pos() - if d is None or return_dict: - d = {} + + if return_dict: + pos = {} + else: + pos = None + try: + pos = self._pos + except AttributeError: + pass + if pos is None: + pos = self._pos = {} n = len(vertices) - 1. @@ -19986,14 +20101,12 @@ def _line_embedding(self, vertices, first=(0, 0), last=(0, 1), return_dict=False dx = dy = 0 for v in vertices: - d[v] = (fx, fy) + pos[v] = (fx, fy) fx += dx fy += dy if return_dict: - return d - else: - self.set_pos(d) + return pos def graphplot(self, **options): """ @@ -20790,6 +20903,7 @@ def _keys_for_vertices(self): sage: s = g.graphviz_string() """ label = {v: 'node_{0}'.format(i) for i, v in enumerate(self)} + def get_label(vertex): return label[vertex] return get_label @@ -22099,19 +22213,23 @@ def relabel(self, perm=None, inplace=True, return_map=False, check_input=True, c for t in perm.values(): hash(t) - self._backend.relabel(perm, self._directed) - - attributes_to_update = ('_pos', '_assoc', '_embedding') - for attr in attributes_to_update: - if hasattr(self, attr) and getattr(self, attr) is not None: - new_attr = {} - for v, value in getattr(self, attr).items(): - if attr != '_embedding': - new_attr[perm[v]] = value - else: - new_attr[perm[v]] = [perm[w] for w in value] + embedding = self.get_embedding() + if embedding is not None: + self._embedding = {perm[u]: [perm[v] for v in neighbors] for u, neighbors in embedding.items()} + pos = self.get_pos() + if pos is not None: + self._pos = {perm[u]: x for u, x in pos.items()} + pos3d = self.get_pos(dim=3) + if pos3d is not None: + self._pos3d = {perm[u]: x for u, x in pos3d.items()} + try: + assoc = self._assoc + except AttributeError: + assoc = None + if assoc is not None: + self._assoc = {perm[v]: value for v, value in assoc.items()} - setattr(self, attr, new_attr) + self._backend.relabel(perm, self._directed) if return_map: return perm diff --git a/src/sage/graphs/genus.pyx b/src/sage/graphs/genus.pyx index a4fe3776eaa..d56c1ba8461 100644 --- a/src/sage/graphs/genus.pyx +++ b/src/sage/graphs/genus.pyx @@ -27,21 +27,21 @@ described throughout the file. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010 Tom Boothby # # 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 libc.string cimport memcpy from memory_allocator cimport MemoryAllocator from cysignals.signals cimport sig_on, sig_off -cimport sage.combinat.permutation_cython +# cimport sage.combinat.permutation_cython from sage.combinat.permutation_cython cimport next_swap, reset_swap @@ -55,7 +55,8 @@ cdef inline int edge_map(int i): slippery. This is the fastest way I could find to establish the correspondence `i <-> i + 1` if `i` is even. """ - return i - 2 * ( i & 1) + 1 + return i - 2 * (i & 1) + 1 + cdef class simple_connected_genus_backtracker: r""" @@ -101,7 +102,6 @@ cdef class simple_connected_genus_backtracker: sage: bt = sage.graphs.genus.simple_connected_genus_backtracker(G._backend.c_graph()[0]) sage: bt.genus() 2 - """ cdef MemoryAllocator mem cdef int **vertex_darts @@ -125,7 +125,6 @@ cdef class simple_connected_genus_backtracker: sage: gb = sage.graphs.genus.simple_connected_genus_backtracker(G._backend.c_graph()[0]) sage: gb.genus() 0 - """ self.num_darts = G.num_arcs self.num_verts = G.num_verts @@ -135,14 +134,14 @@ cdef class simple_connected_genus_backtracker: # Allocate arrays self.mem = MemoryAllocator() - self.degree = self.mem.malloc(self.num_verts * sizeof(int)) - self.face_map = self.mem.malloc(self.num_darts * sizeof(int)) - self.visited = self.mem.malloc(self.num_darts * sizeof(int)) - self.face_freeze = self.mem.malloc(self.num_darts * sizeof(int)) + self.degree = self.mem.malloc(self.num_verts * sizeof(int)) + self.face_map = self.mem.malloc(self.num_darts * sizeof(int)) + self.visited = self.mem.malloc(self.num_darts * sizeof(int)) + self.face_freeze = self.mem.malloc(self.num_darts * sizeof(int)) self.vertex_darts = self.mem.malloc(self.num_verts * sizeof(int *)) - self.swappers = self.mem.malloc(self.num_verts * sizeof(int *)) - cdef int *w = self.mem.malloc((self.num_verts + self.num_darts) * sizeof(int)) - cdef int *s = self.mem.malloc(2 * (self.num_darts - self.num_verts) * sizeof(int)) + self.swappers = self.mem.malloc(self.num_verts * sizeof(int *)) + cdef int *w = self.mem.malloc((self.num_verts + self.num_darts) * sizeof(int)) + cdef int *s = self.mem.malloc(2 * (self.num_darts - self.num_verts) * sizeof(int)) cdef int i, j, du, dv, u, v @@ -173,7 +172,7 @@ cdef class simple_connected_genus_backtracker: self.vertex_darts[v][dv] = i + 1 self.degree[u] += 1 dv += 1 - i += 2 + i += 2 self.degree[v] = dv @@ -203,7 +202,6 @@ cdef class simple_connected_genus_backtracker: # print(self.face_map[v], end="") # print(']') - cdef inline void freeze_face(self): """ Quickly store the current face_map so we can recover @@ -300,7 +298,7 @@ cdef class simple_connected_genus_backtracker: return 1 cdef void flip(self, int v, int i): - """ + r""" This is where the real work happens. Once cycles have been counted for the initial face_map, we make small local changes, and look at their effect on the number of cycles. @@ -384,7 +382,6 @@ cdef class simple_connected_genus_backtracker: self.num_cycles += (2 * k + 1 - j) % 4 - face_map[e0] = v2 face_map[e1] = f2 face_map[e2] = v1 @@ -392,7 +389,6 @@ cdef class simple_connected_genus_backtracker: w[i] = v2 w[i + 1] = v1 - cdef int count_cycles(self): """ Count all cycles. @@ -432,7 +428,6 @@ cdef class simple_connected_genus_backtracker: the minimal or maximal genus for self's graph. - EXAMPLES:: sage: import sage.graphs.genus @@ -481,10 +476,9 @@ cdef class simple_connected_genus_backtracker: return next_swap(d, self.swappers[v], self.swappers[v] + d) cdef int genus_backtrack(self, - int cutoff, - bint record_embedding, - (int (*)(simple_connected_genus_backtracker,int,bint,int))check_embedding - ): + int cutoff, + bint record_embedding, + (int (*)(simple_connected_genus_backtracker, int, bint, int))check_embedding): """ Here's the main backtracking routine. @@ -621,7 +615,7 @@ def simple_connected_graph_genus(G, set_embedding=False, check=True, minimal=Tru cutoff = 1 else: style = 2 - cutoff = 1 + (G.num_edges() - G.num_verts()) / 2 # rounding here is ok + cutoff = 1 + (G.num_edges() - G.num_verts()) / 2 # rounding here is ok g = GG.genus(style=style, cutoff=cutoff, record_embedding=set_embedding) if set_embedding: @@ -631,4 +625,3 @@ def simple_connected_graph_genus(G, set_embedding=False, check=True, minimal=Tru oE[backmap[v]] = [backmap[x] for x in E[v]] oG.set_embedding(oE) return g - diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 8739f6aee79..00ffa0f2eee 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -3159,6 +3159,7 @@ def minimum_outdegree_orientation(self, use_edge_labels=False, solver=None, verb if use_edge_labels: from sage.rings.real_mpfr import RR + def weight(e): l = self.edge_label(e) return l if l in RR else 1 @@ -3178,6 +3179,7 @@ def weight(e): # Whether an edge adjacent to a vertex u counts positively or # negatively. To do so, we first fix an arbitrary extremity per edge uv. ext = {frozenset(e): e[0] for e in self.edge_iterator(labels=False)} + def outgoing(u, e, variable): if u == ext[frozenset(e)]: return variable @@ -4159,6 +4161,7 @@ def matching(self, value_only=False, algorithm="Edmonds", ValueError: algorithm must be set to either "Edmonds" or "LP" """ from sage.rings.real_mpfr import RR + def weight(x): if x in RR: return x @@ -7949,6 +7952,7 @@ def modular_decomposition(self, algorithm=None, style='tuple'): if style == 'tuple': if D is None: return tuple() + def relabel(x): if x.node_type == NodeType.NORMAL: return x.children[0] @@ -7959,6 +7963,7 @@ def relabel(x): from sage.combinat.rooted_tree import LabelledRootedTree if D is None: return LabelledRootedTree([]) + def to_tree(x): if x.node_type == NodeType.NORMAL: return LabelledRootedTree([], label=x.children[0]) diff --git a/src/sage/graphs/graph_generators.py b/src/sage/graphs/graph_generators.py index 5555b222b1f..94ea1ed6bf3 100644 --- a/src/sage/graphs/graph_generators.py +++ b/src/sage/graphs/graph_generators.py @@ -792,12 +792,14 @@ def property(x): def property(x): D = sorted(x.degree()) return all(degree_sequence[i] >= d for i, d in enumerate(D)) + def extra_property(x): return degree_sequence == sorted(x.degree()) else: def property(x): D = sorted(x.degree() + [0] * (vertices - x.num_verts())) return all(degree_sequence[i] >= d for i, d in enumerate(D)) + def extra_property(x): if x.num_verts() != vertices: return False diff --git a/src/sage/groups/abelian_gps/abelian_group_element.py b/src/sage/groups/abelian_gps/abelian_group_element.py index 2ddbf16203f..1b0c9cd590c 100644 --- a/src/sage/groups/abelian_gps/abelian_group_element.py +++ b/src/sage/groups/abelian_gps/abelian_group_element.py @@ -99,7 +99,7 @@ def as_permutation(self): sage: G = AbelianGroup(3,[2,3,4],names="abc"); G Multiplicative Abelian group isomorphic to C2 x C3 x C4 - sage: a,b,c=G.gens() + sage: a,b,c = G.gens() sage: Gp = G.permutation_group(); Gp Permutation Group with generators [(6,7,8,9), (3,4,5), (1,2)] sage: a.as_permutation() diff --git a/src/sage/groups/additive_abelian/additive_abelian_group.py b/src/sage/groups/additive_abelian/additive_abelian_group.py index ca76bff7633..0a326d42c60 100644 --- a/src/sage/groups/additive_abelian/additive_abelian_group.py +++ b/src/sage/groups/additive_abelian/additive_abelian_group.py @@ -56,55 +56,55 @@ def AdditiveAbelianGroup(invs, remember_generators = True): that pair up naturally with the invariants. We create the same element repeatedly. :: - sage: H=AdditiveAbelianGroup([3,2,0], remember_generators=True) + sage: H = AdditiveAbelianGroup([3,2,0], remember_generators=True) sage: H.gens() ((1, 0, 0), (0, 1, 0), (0, 0, 1)) sage: [H.0, H.1, H.2] [(1, 0, 0), (0, 1, 0), (0, 0, 1)] - sage: p=H.0+H.1+6*H.2; p + sage: p = H.0+H.1+6*H.2; p (1, 1, 6) sage: H.smith_form_gens() ((2, 1, 0), (0, 0, 1)) - sage: q=H.linear_combination_of_smith_form_gens([5,6]); q + sage: q = H.linear_combination_of_smith_form_gens([5,6]); q (1, 1, 6) - sage: p==q + sage: p == q True - sage: r=H(vector([1,1,6])); r + sage: r = H(vector([1,1,6])); r (1, 1, 6) - sage: p==r + sage: p == r True - sage: s=H(p) - sage: p==s + sage: s = H(p) + sage: p == s True Again, but now where the generators are the minimal set. Coercing a list or a vector works as before, but the default generators are different. :: - sage: G=AdditiveAbelianGroup([3,2,0], remember_generators=False) + sage: G = AdditiveAbelianGroup([3,2,0], remember_generators=False) sage: G.gens() ((2, 1, 0), (0, 0, 1)) sage: [G.0, G.1] [(2, 1, 0), (0, 0, 1)] - sage: p=5*G.0+6*G.1; p + sage: p = 5*G.0+6*G.1; p (1, 1, 6) sage: H.smith_form_gens() ((2, 1, 0), (0, 0, 1)) - sage: q=G.linear_combination_of_smith_form_gens([5,6]); q + sage: q = G.linear_combination_of_smith_form_gens([5,6]); q (1, 1, 6) - sage: p==q + sage: p == q True - sage: r=G(vector([1,1,6])); r + sage: r = G(vector([1,1,6])); r (1, 1, 6) - sage: p==r + sage: p == r True - sage: s=H(p) - sage: p==s + sage: s = H(p) + sage: p == s True """ invs = [ZZ(x) for x in invs] @@ -246,13 +246,13 @@ def _latex_(self): EXAMPLES:: - sage: G=AdditiveAbelianGroup([66, 77, 0, 0]) + sage: G = AdditiveAbelianGroup([66, 77, 0, 0]) sage: G._latex_() '\\frac{\\ZZ}{11\\ZZ} \\oplus \\frac{\\ZZ}{462\\ZZ} \\oplus \\ZZ \\oplus \\ZZ' A trivial group is represented as zero, rather than Z/1Z. :: - sage: G=AdditiveAbelianGroup([1]) + sage: G = AdditiveAbelianGroup([1]) sage: G._latex_() '0' """ @@ -378,19 +378,19 @@ def is_cyclic(self): With no common factors between the orders of the generators, the group will be cyclic. :: - sage: G=AdditiveAbelianGroup([6, 7, 55]) + sage: G = AdditiveAbelianGroup([6, 7, 55]) sage: G.is_cyclic() True Repeating primes in the orders will create a non-cyclic group. :: - sage: G=AdditiveAbelianGroup([6, 15, 21, 33]) + sage: G = AdditiveAbelianGroup([6, 15, 21, 33]) sage: G.is_cyclic() False A trivial group is trivially cyclic. :: - sage: T=AdditiveAbelianGroup([1]) + sage: T = AdditiveAbelianGroup([1]) sage: T.is_cyclic() True """ diff --git a/src/sage/groups/braid.py b/src/sage/groups/braid.py index 751f20b73ec..efbbf2ce225 100644 --- a/src/sage/groups/braid.py +++ b/src/sage/groups/braid.py @@ -1243,9 +1243,9 @@ def annular_khovanov_complex(self, qagrad=None, ring=None): EXAMPLES:: - sage: B=BraidGroup(3) - sage: b=B([1,-2,1,-2]) - sage: C=b.annular_khovanov_complex() + sage: B = BraidGroup(3) + sage: b = B([1,-2,1,-2]) + sage: C = b.annular_khovanov_complex() sage: C {(-5, -1): Chain complex with at most 1 nonzero terms over Integer Ring, (-3, -3): Chain complex with at most 1 nonzero terms over Integer Ring, @@ -1264,7 +1264,7 @@ def annular_khovanov_complex(self, qagrad=None, ring=None): TESTS:: - sage: C=BraidGroup(2)([]).annular_khovanov_complex() + sage: C = BraidGroup(2)([]).annular_khovanov_complex() sage: {qa: C[qa].homology() for qa in C} {(-2, -2): {0: Z}, (0, 0): {0: Z x Z}, (2, 2): {0: Z}} diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py index b1605b855ff..2a61bbf91dc 100644 --- a/src/sage/groups/finitely_presented.py +++ b/src/sage/groups/finitely_presented.py @@ -591,9 +591,9 @@ def gap(self): EXAMPLES:: - sage: F.=FreeGroup() - sage: G=F/[a*a,b*b] - sage: k=G.rewriting_system() + sage: F. = FreeGroup() + sage: G = F/[a*a,b*b] + sage: k = G.rewriting_system() sage: k.gap() Knuth Bendix Rewriting System for Monoid( [ a, A, b, B ] ) with rules [ [ a^2, ], [ a*A, ], @@ -839,10 +839,10 @@ def _latex_(self): TESTS:: - sage: F=FreeGroup(4) + sage: F = FreeGroup(4) sage: F.inject_variables() Defining x0, x1, x2, x3 - sage: G=F.quotient([x0*x2, x3*x1*x3, x2*x1*x2]) + sage: G = F.quotient([x0*x2, x3*x1*x3, x2*x1*x2]) sage: G._latex_() '\\langle x_{0}, x_{1}, x_{2}, x_{3} \\mid x_{0}\\cdot x_{2} , x_{3}\\cdot x_{1}\\cdot x_{3} , x_{2}\\cdot x_{1}\\cdot x_{2}\\rangle' """ diff --git a/src/sage/groups/free_group.py b/src/sage/groups/free_group.py index 68c0f909bf0..2846028b5e7 100644 --- a/src/sage/groups/free_group.py +++ b/src/sage/groups/free_group.py @@ -404,17 +404,17 @@ def fox_derivative(self, gen, im_gens=None, ring=None): If ``im_gens`` is given, the images of the generators are mapped to them:: - sage: F=FreeGroup(3) - sage: a=F([2,1,3,-1,2]) + sage: F = FreeGroup(3) + sage: a = F([2,1,3,-1,2]) sage: a.fox_derivative(F([1])) x1 - x1*x0*x2*x0^-1 - sage: R.=LaurentPolynomialRing(ZZ) + sage: R. = LaurentPolynomialRing(ZZ) sage: a.fox_derivative(F([1]),[t,t,t]) t - t^2 - sage: S.=LaurentPolynomialRing(ZZ) + sage: S. = LaurentPolynomialRing(ZZ) sage: a.fox_derivative(F([1]),[t1,t2,t3]) -t2*t3 + t2 - sage: R.=QQ[] + sage: R. = QQ[] sage: a.fox_derivative(F([1]),[x,y,z]) -y*z + y sage: a.inverse().fox_derivative(F([1]),[x,y,z]) @@ -435,11 +435,11 @@ def fox_derivative(self, gen, im_gens=None, ring=None): TESTS:: - sage: F=FreeGroup(3) - sage: a=F([]) + sage: F = FreeGroup(3) + sage: a = F([]) sage: a.fox_derivative(F([1])) 0 - sage: R.=LaurentPolynomialRing(ZZ) + sage: R. = LaurentPolynomialRing(ZZ) sage: a.fox_derivative(F([1]),[t,t,t]) 0 """ @@ -943,9 +943,9 @@ def quotient(self, relations, **kwds): Relations are converted to the free group, even if they are not elements of it (if possible) :: - sage: F1.=FreeGroup() - sage: F2.=FreeGroup() - sage: r=a*b/a + sage: F1. = FreeGroup() + sage: F2. = FreeGroup() + sage: r = a*b/a sage: r.parent() Free Group on generators {a, b} sage: F1/[r] diff --git a/src/sage/groups/generic.py b/src/sage/groups/generic.py index e1f13a2994c..de015974697 100644 --- a/src/sage/groups/generic.py +++ b/src/sage/groups/generic.py @@ -159,14 +159,12 @@ def multiple(a, n, operation='*', identity=None, inverse=None, op=None): sage: multiple(1,10^1000) 1 - sage: E=EllipticCurve('389a1') - sage: P=E(-1,1) + sage: E = EllipticCurve('389a1') + sage: P = E(-1,1) sage: multiple(P,10,'+') (645656132358737542773209599489/22817025904944891235367494656 : 525532176124281192881231818644174845702936831/3446581505217248068297884384990762467229696 : 1) sage: multiple(P,-10,'+') (645656132358737542773209599489/22817025904944891235367494656 : -528978757629498440949529703029165608170166527/3446581505217248068297884384990762467229696 : 1) - - """ from operator import inv, mul, neg, add @@ -254,8 +252,8 @@ class multiples: sage: list(multiples(1,10,100)) [100, 101, 102, 103, 104, 105, 106, 107, 108, 109] - sage: E=EllipticCurve('389a1') - sage: P=E(-1,1) + sage: E = EllipticCurve('389a1') + sage: P = E(-1,1) sage: for Q in multiples(P,5): print((Q, Q.height()/P.height())) ((0 : 1 : 0), 0.000000000000000) ((-1 : 1 : 1), 1.00000000000000) @@ -263,7 +261,7 @@ class multiples: ((26/361 : -5720/6859 : 1), 9.00000000000000) ((47503/16641 : 9862190/2146689 : 1), 16.0000000000000) - sage: R.=ZZ[] + sage: R. = ZZ[] sage: list(multiples(x,5)) [0, x, 2*x, 3*x, 4*x] sage: list(multiples(x,5,operation='*')) @@ -408,8 +406,8 @@ def bsgs(a, b, bounds, operation='*', identity=None, inverse=None, op=None): sage: bsgs(b, a, (0,36)) 20 - sage: p=next_prime(10^20) - sage: a=Mod(2,p); b=a^(10^25) + sage: p = next_prime(10^20) + sage: a = Mod(2,p); b = a^(10^25) sage: bsgs(a, b, (10^25-10^6,10^25+10^6)) == 10^25 True @@ -419,8 +417,8 @@ def bsgs(a, b, bounds, operation='*', identity=None, inverse=None, op=None): sage: bsgs(a, b, (0,K.order()-1)) 210 - sage: K.=CyclotomicField(230) - sage: w=z^500 + sage: K. = CyclotomicField(230) + sage: w = z^500 sage: bsgs(z,w,(0,229)) 40 @@ -735,8 +733,8 @@ def discrete_log(a, base, ord=None, bounds=None, operation='*', identity=None, i sage: v.log(w) 0 - sage: K.=CyclotomicField(230) - sage: w=z^50 + sage: K. = CyclotomicField(230) + sage: w = z^50 sage: discrete_log(w,z) 50 @@ -766,14 +764,14 @@ def discrete_log(a, base, ord=None, bounds=None, operation='*', identity=None, i An additive example: elliptic curve DLOG:: - sage: F=GF(37^2,'a') - sage: E=EllipticCurve(F,[1,1]) - sage: F.=GF(37^2,'a') - sage: E=EllipticCurve(F,[1,1]) - sage: P=E(25*a + 16 , 15*a + 7 ) + sage: F = GF(37^2,'a') + sage: E = EllipticCurve(F,[1,1]) + sage: F. = GF(37^2,'a') + sage: E = EllipticCurve(F,[1,1]) + sage: P = E(25*a + 16 , 15*a + 7 ) sage: P.order() 672 - sage: Q=39*P; Q + sage: Q = 39*P; Q (36*a + 32 : 5*a + 12 : 1) sage: discrete_log(Q,P,P.order(),operation='+') 39 @@ -975,10 +973,10 @@ def linear_relation(P, Q, operation='+', identity=None, inverse=None, op=None): An additive example (in an elliptic curve group):: - sage: F.=GF(3^6,'a') - sage: E=EllipticCurve([a^5 + 2*a^3 + 2*a^2 + 2*a, a^4 + a^3 + 2*a + 1]) - sage: P=E(a^5 + a^4 + a^3 + a^2 + a + 2 , 0) - sage: Q=E(2*a^3 + 2*a^2 + 2*a , a^3 + 2*a^2 + 1) + sage: F. = GF(3^6,'a') + sage: E = EllipticCurve([a^5 + 2*a^3 + 2*a^2 + 2*a,a^4 + a^3 + 2*a + 1]) + sage: P = E(a^5 + a^4 + a^3 + a^2 + a + 2 , 0) + sage: Q = E(2*a^3 + 2*a^2 + 2*a , a^3 + 2*a^2 + 1) sage: linear_relation(P,Q,'+') (1, 2) sage: P == 2*Q @@ -986,11 +984,11 @@ def linear_relation(P, Q, operation='+', identity=None, inverse=None, op=None): A multiplicative example (in a finite field's multiplicative group):: - sage: F.=GF(3^6,'a') + sage: F. = GF(3^6,'a') sage: a.multiplicative_order().factor() 2^3 * 7 * 13 - sage: b=a^7 - sage: c=a^13 + sage: b = a^7 + sage: c = a^13 sage: linear_relation(b,c,'*') (13, 7) sage: b^13==c^7 @@ -1091,14 +1089,14 @@ def order_from_multiple(P, m, plist=None, factorization=None, check=True, sage: order_from_multiple(Q, M, factorization=F, operation='+') 7 - sage: K.=CyclotomicField(230) - sage: w=z^50 + sage: K. = CyclotomicField(230) + sage: w = z^50 sage: order_from_multiple(w,230,operation='*') 23 - sage: F=GF(2^1279,'a') - sage: n=F.cardinality()-1 # Mersenne prime - sage: order_from_multiple(F.random_element(),n,factorization=[(n,1)],operation='*')==n + sage: F = GF(2^1279,'a') + sage: n = F.cardinality()-1 # Mersenne prime + sage: order_from_multiple(F.random_element(),n,factorization=[(n,1)],operation='*') == n True sage: K. = GF(3^60) @@ -1228,10 +1226,9 @@ def order_from_bounds(P, bounds, d=None, operation='+', 3227 sage: K.=CyclotomicField(230) - sage: w=z^50 + sage: w = z^50 sage: order_from_bounds(w,(200,250),operation='*') 23 - """ from operator import mul, add @@ -1302,11 +1299,11 @@ def merge_points(P1, P2, operation='+', sage: od == lcm(ob,oc) True - sage: E=EllipticCurve([a^5 + 2*a^3 + 2*a^2 + 2*a, a^4 + a^3 + 2*a + 1]) - sage: P=E(2*a^5 + 2*a^4 + a^3 + 2 , a^4 + a^3 + a^2 + 2*a + 2) + sage: E = EllipticCurve([a^5 + 2*a^3 + 2*a^2 + 2*a,a^4 + a^3 + 2*a + 1]) + sage: P = E(2*a^5 + 2*a^4 + a^3 + 2 , a^4 + a^3 + a^2 + 2*a + 2) sage: P.order() 7 - sage: Q=E(2*a^5 + 2*a^4 + 1 , a^5 + 2*a^3 + 2*a + 2 ) + sage: Q = E(2*a^5 + 2*a^4 + 1 , a^5 + 2*a^3 + 2*a + 2 ) sage: Q.order() 4 sage: R,m = merge_points((P,7),(Q,4), operation='+') @@ -1402,7 +1399,7 @@ def structure_description(G, latex=False): Works for finitely presented groups (:trac:`17573`):: sage: F. = FreeGroup() - sage: G=F / [x^2*y^-1, x^3*y^2, x*y*x^-1*y^-1] + sage: G = F / [x^2*y^-1, x^3*y^2, x*y*x^-1*y^-1] sage: G.structure_description() 'C7' diff --git a/src/sage/groups/libgap_mixin.py b/src/sage/groups/libgap_mixin.py index 018d438fffe..b51679410e1 100644 --- a/src/sage/groups/libgap_mixin.py +++ b/src/sage/groups/libgap_mixin.py @@ -752,7 +752,7 @@ def is_isomorphic(self, H): True sage: F.is_isomorphic(H) True - sage: F==G, G==H, F==H + sage: F == G, G == H, F == H (False, False, False) """ return self.gap().IsomorphismGroups(H.gap()) != libgap.fail diff --git a/src/sage/groups/matrix_gps/finitely_generated.py b/src/sage/groups/matrix_gps/finitely_generated.py index a87658e746d..a6d3dc02513 100644 --- a/src/sage/groups/matrix_gps/finitely_generated.py +++ b/src/sage/groups/matrix_gps/finitely_generated.py @@ -600,9 +600,9 @@ def as_permutation_group(self, algorithm=None, seed=None): TESTS:: - sage: A= matrix(QQ, 2, [0, 1, 1, 0]) - sage: B= matrix(QQ, 2, [1, 0, 0, 1]) - sage: a, b= MatrixGroup([A, B]).as_permutation_group().gens() + sage: A = matrix(QQ, 2, [0, 1, 1, 0]) + sage: B = matrix(QQ, 2, [1, 0, 0, 1]) + sage: a, b = MatrixGroup([A, B]).as_permutation_group().gens() sage: a.order(), b.order() (2, 1) @@ -737,7 +737,7 @@ def invariant_generators(self): sage: MS = MatrixSpace(F,2,2) sage: g1 = MS([[1/a, 1/a], [1/a, -1/a]]) sage: g2 = MS([[-b, 0], [0, b]]) - sage: G=MatrixGroup([g1,g2]) + sage: G = MatrixGroup([g1,g2]) sage: G.invariant_generators() [x1^4 + 2*x1^2*x2^2 + x2^4, x1^5*x2 - x1*x2^5, diff --git a/src/sage/groups/matrix_gps/orthogonal.py b/src/sage/groups/matrix_gps/orthogonal.py index d457890eeda..f6721afaacd 100644 --- a/src/sage/groups/matrix_gps/orthogonal.py +++ b/src/sage/groups/matrix_gps/orthogonal.py @@ -389,7 +389,7 @@ def SO(n, R, e=None, var='a', invariant_form=None): Using the ``invariant_form`` option:: sage: CF3 = CyclotomicField(3); e3 = CF3.gen() - sage: m=matrix(CF3, 3,3, [[1,e3,0],[e3,2,0],[0,0,1]]) + sage: m = matrix(CF3, 3,3, [[1,e3,0],[e3,2,0],[0,0,1]]) sage: SO3 = SO(3, CF3) sage: SO3m = SO(3, CF3, invariant_form=m) sage: SO3 == SO3m @@ -454,7 +454,7 @@ class OrthogonalMatrixGroup_generic(NamedMatrixGroup_generic): \text{SO}_{3}(\Bold{F}_{5}) sage: CF3 = CyclotomicField(3); e3 = CF3.gen() - sage: m=matrix(CF3, 3,3, [[1,e3,0],[e3,2,0],[0,0,1]]) + sage: m = matrix(CF3, 3,3, [[1,e3,0],[e3,2,0],[0,0,1]]) sage: G = SO(3, CF3, invariant_form=m) sage: latex(G) \text{SO}_{3}(\Bold{Q}(\zeta_{3}))\text{ with respect to non positive definite symmetric form }\left(\begin{array}{rrr} diff --git a/src/sage/groups/matrix_gps/unitary.py b/src/sage/groups/matrix_gps/unitary.py index d51b92e8976..f4d8df525be 100644 --- a/src/sage/groups/matrix_gps/unitary.py +++ b/src/sage/groups/matrix_gps/unitary.py @@ -211,7 +211,7 @@ def GU(n, R, var='a', invariant_form=None): Using the ``invariant_form`` option:: sage: UCF = UniversalCyclotomicField(); e5=UCF.gen(5) - sage: m=matrix(UCF, 3,3, [[1,e5,0],[e5.conjugate(),2,0],[0,0,1]]) + sage: m = matrix(UCF, 3,3, [[1,e5,0],[e5.conjugate(),2,0],[0,0,1]]) sage: G = GU(3, UCF) sage: Gm = GU(3, UCF, invariant_form=m) sage: G == Gm @@ -224,7 +224,7 @@ def GU(n, R, var='a', invariant_form=None): [ 1 E(5) 0] [E(5)^4 2 0] [ 0 0 1] - sage: pm=Permutation((1,2,3)).to_matrix() + sage: pm = Permutation((1,2,3)).to_matrix() sage: g = G(pm); g in G; g True [0 0 1] @@ -311,7 +311,7 @@ def SU(n, R, var='a', invariant_form=None): Using the ``invariant_form`` option:: sage: CF3 = CyclotomicField(3); e3 = CF3.gen() - sage: m=matrix(CF3, 3,3, [[1,e3,0],[e3.conjugate(),2,0],[0,0,1]]) + sage: m = matrix(CF3, 3,3, [[1,e3,0],[e3.conjugate(),2,0],[0,0,1]]) sage: G = SU(3, CF3) sage: Gm = SU(3, CF3, invariant_form=m) sage: G == Gm @@ -324,7 +324,7 @@ def SU(n, R, var='a', invariant_form=None): [ 1 zeta3 0] [-zeta3 - 1 2 0] [ 0 0 1] - sage: pm=Permutation((1,2,3)).to_matrix() + sage: pm = Permutation((1,2,3)).to_matrix() sage: G(pm) [0 0 1] [1 0 0] @@ -373,7 +373,7 @@ class UnitaryMatrixGroup_generic(NamedMatrixGroup_generic): \text{SU}_{3}(\Bold{F}_{5^{2}}) sage: CF3 = CyclotomicField(3); e3 = CF3.gen() - sage: m=matrix(CF3, 3,3, [[1,e3,0],[e3.conjugate(),2,0],[0,0,1]]) + sage: m = matrix(CF3, 3,3, [[1,e3,0],[e3.conjugate(),2,0],[0,0,1]]) sage: G = SU(3, CF3, invariant_form=m) sage: latex(G) \text{SU}_{3}(\Bold{Q}(\zeta_{3}))\text{ with respect to positive definite hermitian form }\left(\begin{array}{rrr} diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx index 541cf8ddd23..5f54d4f8ac2 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx @@ -153,7 +153,7 @@ cdef class LinearBinaryCodeStruct(BinaryCodeStruct): sage: B.automorphism_group()[1] 2304 - sage: M=Matrix(GF(2),[\ + sage: M = Matrix(GF(2),[\ ....: [1,0,0,1,1,1,1,0,0,1,0,0,0,0,0,0,0],\ ....: [0,1,0,0,1,1,1,1,0,0,1,0,0,0,0,0,0],\ ....: [0,0,1,0,0,1,1,1,1,0,0,1,0,0,0,0,0],\ @@ -177,7 +177,7 @@ cdef class LinearBinaryCodeStruct(BinaryCodeStruct): sage: B.automorphism_group()[1] 2160 - sage: M=Matrix(GF(2),[\ + sage: M = Matrix(GF(2),[\ ....: [0,1,0,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1,1,1,0,1],\ ....: [1,0,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1,1,1,0,1,0],\ ....: [0,1,1,1,0,0,0,1,0,0,1,1,0,0,0,1,1,1,0,1,0,0],\ diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx index bf87e5bde7a..dafa6e007c7 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx @@ -288,7 +288,7 @@ def search_tree(G_in, partition, lab=True, dig=False, dict_rep=False, certificat sage: for i,j,_ in G.edge_iterator(): ....: GD.add_arc(i,j); GD.add_arc(j,i) ....: GS.add_arc(i,j); GS.add_arc(j,i) - sage: Pi=[range(20)] + sage: Pi = [range(20)] sage: a,b = st(G, Pi) sage: asp,bsp = st(GS, Pi) sage: ade,bde = st(GD, Pi) @@ -338,7 +338,7 @@ def search_tree(G_in, partition, lab=True, dig=False, dict_rep=False, certificat sage: D2 = DiGraph({1:[2],2:[1],0:[0]}, loops=True) sage: a,b = st(D1, [D1.vertices()], dig=True, use_indicator_function=False) sage: c,d = st(D2, [D2.vertices()], dig=True, use_indicator_function=False) - sage: b==d + sage: b == d True This example is due to Chris Godsil:: diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index 082dcc7f6b0..0df45da623d 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -215,7 +215,7 @@ def direct_product_permgroups(P): sage: D.order() 1728 sage: D = direct_product_permgroups([G1]) - sage: D==G1 + sage: D == G1 True sage: direct_product_permgroups([]) Symmetric group of order 0! as a permutation group @@ -910,7 +910,7 @@ def _coerce_map_from_(self, G): sage: MG = GU(3,2).as_matrix_group() sage: PG = MG.as_permutation_group() - sage: f=PG._coerce_map_from_(MG) + sage: f = PG._coerce_map_from_(MG) sage: mg = MG.an_element() sage: p = f(mg); p (2,33,32,23,31,55)(3,49,38,44,40,28)(4,17,59,62,58,46)(5,21,47,20,43,8)(6,53,50)(7,37,12,57,14,29)(9,41,56,34,64,10)(11,25,19)(13,61,26,51,22,15)(16,45,36)(18,27,35,48,52,54)(24,63,42)(30,39,60) @@ -2306,7 +2306,7 @@ def socle(self): EXAMPLES:: - sage: G=SymmetricGroup(4) + sage: G = SymmetricGroup(4) sage: G.socle() Subgroup generated by [(1,2)(3,4), (1,4)(2,3)] of (Symmetric group of order 4! as a permutation group) sage: G.socle().socle() @@ -2323,10 +2323,10 @@ def frattini_subgroup(self): EXAMPLES:: - sage: G=PermutationGroup([[(1,2,3,4)],[(2,4)]]) + sage: G = PermutationGroup([[(1,2,3,4)],[(2,4)]]) sage: G.frattini_subgroup() Subgroup generated by [(1,3)(2,4)] of (Permutation Group with generators [(2,4), (1,2,3,4)]) - sage: G=SymmetricGroup(4) + sage: G = SymmetricGroup(4) sage: G.frattini_subgroup() Subgroup generated by [()] of (Symmetric group of order 4! as a permutation group) @@ -2342,10 +2342,10 @@ def fitting_subgroup(self): EXAMPLES:: - sage: G=PermutationGroup([[(1,2,3,4)],[(2,4)]]) + sage: G = PermutationGroup([[(1,2,3,4)],[(2,4)]]) sage: G.fitting_subgroup() Subgroup generated by [(2,4), (1,2,3,4), (1,3)] of (Permutation Group with generators [(2,4), (1,2,3,4)]) - sage: G=PermutationGroup([[(1,2,3,4)],[(1,2)]]) + sage: G = PermutationGroup([[(1,2,3,4)],[(1,2)]]) sage: G.fitting_subgroup() Subgroup generated by [(1,2)(3,4), (1,3)(2,4)] of (Permutation Group with generators [(1,2), (1,2,3,4)]) @@ -2361,13 +2361,12 @@ def solvable_radical(self): EXAMPLES:: - sage: G=SymmetricGroup(4) + sage: G = SymmetricGroup(4) sage: G.solvable_radical() Subgroup generated by [(1,2), (1,2,3,4)] of (Symmetric group of order 4! as a permutation group) - sage: G=SymmetricGroup(5) + sage: G = SymmetricGroup(5) sage: G.solvable_radical() Subgroup generated by [()] of (Symmetric group of order 5! as a permutation group) - """ return self.subgroup(gap_group=self._libgap_().RadicalGroup()) @@ -2609,9 +2608,9 @@ def direct_product(self, other, maps=True): From: Permutation Group with generators [(5,6,7,8), (1,2,3,4)] To: Cyclic group of order 4 as a permutation group Defn: Projection( Group( [ (1,2,3,4), (5,6,7,8) ] ), 2 ) - sage: g=D([(1,3),(2,4)]); g + sage: g = D([(1,3),(2,4)]); g (1,3)(2,4) - sage: d=D([(1,4,3,2),(5,7),(6,8)]); d + sage: d = D([(1,4,3,2),(5,7),(6,8)]); d (1,4,3,2)(5,7)(6,8) sage: iota1(g); iota2(g); pr1(d); pr2(d) (1,3)(2,4) @@ -3862,7 +3861,7 @@ def cosets(self, S, side='right'): The subgroup argument is checked to see if it is a permutation group. Even a legitimate GAP object can be rejected. :: - sage: G=SymmetricGroup(3) + sage: G = SymmetricGroup(3) sage: G.cosets(gap(3)) Traceback (most recent call last): ... diff --git a/src/sage/groups/perm_gps/permgroup_element.pyx b/src/sage/groups/perm_gps/permgroup_element.pyx index 2c4977a8a84..037884f55da 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pyx +++ b/src/sage/groups/perm_gps/permgroup_element.pyx @@ -1557,7 +1557,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): sage: prod(primes(150)) 1492182350939279320058875736615841068547583863326864530410 sage: L = [tuple(range(sum(primes(p))+1, sum(primes(p))+1+p)) for p in primes(150)] - sage: t=PermutationGroupElement(L).multiplicative_order(); t + sage: t = PermutationGroupElement(L).multiplicative_order(); t 1492182350939279320058875736615841068547583863326864530410 sage: type(t) diff --git a/src/sage/groups/perm_gps/permgroup_named.py b/src/sage/groups/perm_gps/permgroup_named.py index fa6fcc9887e..43e47f7574e 100644 --- a/src/sage/groups/perm_gps/permgroup_named.py +++ b/src/sage/groups/perm_gps/permgroup_named.py @@ -838,7 +838,7 @@ class DiCyclicGroup(PermutationGroup_unique): A large generalized quaternion group (order is a power of 2):: sage: n = 2^10 - sage: G=DiCyclicGroup(n) + sage: G = DiCyclicGroup(n) sage: G.order() 4096 sage: a = G.gen(0) @@ -858,7 +858,7 @@ class DiCyclicGroup(PermutationGroup_unique): subgroup of order 2 (thus has the unique element of order 2 as its non-identity element). :: - sage: G=DiCyclicGroup(3*5*4) + sage: G = DiCyclicGroup(3*5*4) sage: G.order() 240 sage: two = [g for g in G if g.order()==2]; two @@ -1145,7 +1145,7 @@ def _repr_(self): r""" EXAMPLES:: - sage: Q=QuaternionGroup(); Q + sage: Q = QuaternionGroup(); Q Quaternion group of order 8 as a permutation group """ return "Quaternion group of order 8 as a permutation group" diff --git a/src/sage/interfaces/cleaner.py b/src/sage/interfaces/cleaner.py index 7e67a478f25..54bfac779ac 100644 --- a/src/sage/interfaces/cleaner.py +++ b/src/sage/interfaces/cleaner.py @@ -5,19 +5,18 @@ "The Cleaner" from Pulp Fiction: http://www.frankjankowski.de/quiz/illus/keitel.jpg """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 William Stein # # 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/ -#***************************************************************************** - +# https://www.gnu.org/licenses/ +# **************************************************************************** import os +import atexit +import tempfile -import atexit, tempfile _spd = tempfile.TemporaryDirectory() SAGE_SPAWNED_PROCESS_FILE = os.path.join(_spd.name, "spawned_processes") atexit.register(lambda: _spd.cleanup()) diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 69d8d1295fd..c4dc2d4f27a 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -165,7 +165,7 @@ def __init__(self, name, prompt, command=None, env={}, server=None, self._session_number = 0 self.__init_code = init_code - #Handle the log file + # Handle the log file if isinstance(logfile, str): self.__logfile = None self.__logfilename = logfile @@ -198,9 +198,9 @@ def set_server_and_command(self, server=None, command=None, server_tmpdir=None, self._server = server if server is not None: if ulimit: - command = "ssh -t %s 'ulimit %s; %s'"%(server, ulimit, command) + command = "ssh -t %s 'ulimit %s; %s'" % (server, ulimit, command) else: - command = "ssh -t %s '%s'"%(server, command) + command = "ssh -t %s '%s'" % (server, command) self.__is_remote = True self._eval_using_file_cutoff = 0 # don't allow this! if self.__verbose_start: @@ -208,7 +208,7 @@ def set_server_and_command(self, server=None, command=None, server_tmpdir=None, print(command) if server_tmpdir is None: # TO DO: Why default to /tmp/? Might be better to use the expect process itself to get a tmp folder - print("No remote temporary directory (option server_tmpdir) specified, using /tmp/ on "+server) + print("No remote temporary directory (option server_tmpdir) specified, using /tmp/ on " + server) self.__remote_tmpdir = "/tmp/" else: self.__remote_tmpdir = server_tmpdir @@ -277,7 +277,7 @@ def is_running(self): if self._expect is None: return False try: - os.kill(self._expect.pid,0) + os.kill(self._expect.pid, 0) except OSError: # This means the process is not running return False @@ -291,11 +291,11 @@ def _so_far(self, wait=0.1, alternate_prompt=None): done, new = self._get(wait=wait, alternate_prompt=alternate_prompt) try: if done: - #if new is not None: + # if new is not None: X = self.__so_far + new del self.__so_far return True, X, new - #new = self._expect.before + # new = self._expect.before try: self.__so_far += new except (AttributeError, TypeError): @@ -430,7 +430,6 @@ def _install_hints_ssh_through_gate(self): """ - def _do_cleaner(self): try: return self.__do_cleaner @@ -456,8 +455,8 @@ def _start(self, alt_message=None, block_during_init=True): os.makedirs(logs, exist_ok=True) filename = '{name}-{pid}-{id}-{session}'.format( - name=self.name(), pid=os.getpid(), id=id(self), - session=self._session_number) + name=self.name(), pid=os.getpid(), id=id(self), + session=self._session_number) self.__logfilename = os.path.join(logs, filename) if self.__logfilename is not None: self.__logfile = open(self.__logfilename, 'wb') @@ -737,14 +736,13 @@ def _local_tmpfile(self): AUTHOR: - Simon King (2010-09): Making the tmp-file unique for the interface instance - """ try: return self.__local_tmpfile except AttributeError: pass - import atexit, os + import atexit from tempfile import NamedTemporaryFile # FriCAS uses the ".input" suffix, and the other # interfaces are suffix-agnostic, so using ".input" here @@ -761,7 +759,7 @@ def _remote_tmpfile(self): try: return self.__remote_tmpfile except AttributeError: - self.__remote_tmpfile = self._remote_tmpdir()+"/interface_%s:%s"%(LOCAL_IDENTIFIER,self.pid()) + self.__remote_tmpfile = self._remote_tmpdir() + "/interface_%s:%s" % (LOCAL_IDENTIFIER, self.pid()) return self.__remote_tmpfile def _send_tmpfile_to_server(self, local_file=None, remote_file=None): @@ -769,15 +767,15 @@ def _send_tmpfile_to_server(self, local_file=None, remote_file=None): local_file = self._local_tmpfile() if remote_file is None: remote_file = self._remote_tmpfile() - cmd = 'scp "%s" %s:"%s" 1>&2 2>/dev/null'%(local_file, self._server, remote_file) + cmd = 'scp "%s" %s:"%s" 1>&2 2>/dev/null' % (local_file, self._server, remote_file) os.system(cmd) - def _get_tmpfile_from_server(self, local_file=None,remote_file=None): + def _get_tmpfile_from_server(self, local_file=None, remote_file=None): if local_file is None: local_file = self._local_tmpfile() if remote_file is None: remote_file = self._remote_tmpfile() - cmd = 'scp %s:"%s" "%s" 1>&2 2>/dev/null'%( self._server, remote_file, local_file) + cmd = 'scp %s:"%s" "%s" 1>&2 2>/dev/null' % (self._server, remote_file, local_file) os.system(cmd) def _remove_tmpfile_from_server(self): @@ -847,7 +845,7 @@ def _eval_line_using_file(self, line, restart_if_needed=True): if self._quit_string() in line: # we expect to get an EOF if we're quitting. return '' - elif restart_if_needed: # the subprocess might have crashed + elif restart_if_needed: # the subprocess might have crashed try: self._synchronize() return self._post_process_from_file(self._eval_line_using_file(line, restart_if_needed=False)) @@ -997,7 +995,7 @@ def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if self._synchronize() except (TypeError, RuntimeError): pass - return self._eval_line(line,allow_use_file=allow_use_file, wait_for_prompt=wait_for_prompt, restart_if_needed=False) + return self._eval_line(line, allow_use_file=allow_use_file, wait_for_prompt=wait_for_prompt, restart_if_needed=False) raise RuntimeError("%s\nError evaluating %s in %s" % (msg, line, self)) if line: @@ -1019,13 +1017,13 @@ def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if if self._quit_string() in line: # we expect to get an EOF if we're quitting. return '' - elif restart_if_needed: # the subprocess might have crashed + elif restart_if_needed: # the subprocess might have crashed try: self._synchronize() - return self._eval_line(line,allow_use_file=allow_use_file, wait_for_prompt=wait_for_prompt, restart_if_needed=False) + return self._eval_line(line, allow_use_file=allow_use_file, wait_for_prompt=wait_for_prompt, restart_if_needed=False) except (TypeError, RuntimeError): pass - raise RuntimeError("%s\n%s crashed executing %s"%(msg,self, line)) + raise RuntimeError("%s\n%s crashed executing %s" % (msg, self, line)) if self._terminal_echo: out = self._before() else: @@ -1041,9 +1039,9 @@ def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if if self._terminal_echo: i = out.find("\n") j = out.rfind("\r") - return out[i+1:j].replace('\r\n','\n') + return out[i + 1:j].replace('\r\n', '\n') else: - return out.replace('\r\n','\n') + return out.replace('\r\n', '\n') def _keyboard_interrupt(self): print("Interrupting %s..." % self) @@ -1051,7 +1049,7 @@ def _keyboard_interrupt(self): try: self._close() except pexpect.ExceptionPexpect as msg: - raise pexpect.ExceptionPexpect( "THIS IS A BUG -- PLEASE REPORT. This should never happen.\n" + msg) + raise pexpect.ExceptionPexpect("THIS IS A BUG -- PLEASE REPORT. This should never happen.\n" + msg) self._start() raise KeyboardInterrupt("Restarting %s (WARNING: all variables defined in previous session are now invalid)" % self) else: @@ -1147,7 +1145,7 @@ def _readline(self, size=-1, encoding=None, errors=None): def _interrupt(self): for i in range(15): try: - self._sendstr('quit;\n'+chr(3)) + self._sendstr('quit;\n' + chr(3)) self._expect_expr(timeout=2) except pexpect.TIMEOUT: pass @@ -1394,7 +1392,7 @@ def eval(self, code, strip=True, synchronize=False, locals=None, allow_use_file= if not isinstance(code, str): raise TypeError('input code must be a string.') - #Remove extra whitespace + # Remove extra whitespace code = code.strip() try: @@ -1404,14 +1402,14 @@ def eval(self, code, strip=True, synchronize=False, locals=None, allow_use_file= return self._eval_line_using_file(code) elif split_lines: return '\n'.join([self._eval_line(L, allow_use_file=allow_use_file, **kwds) - for L in code.split('\n') if L != '']) + for L in code.split('\n') if L != '']) else: return self._eval_line(code, allow_use_file=allow_use_file, **kwds) # DO NOT CATCH KeyboardInterrupt, as it is being caught # by _eval_line # In particular, do NOT call self._keyboard_interrupt() except TypeError as s: - raise TypeError('error evaluating "%s":\n%s'%(code,s)) + raise TypeError('error evaluating "%s":\n%s' % (code, s)) ############################################################ # Functions for working with variables. @@ -1458,6 +1456,7 @@ class ExpectFunction(InterfaceFunction): """ pass + @instancedoc class FunctionElement(InterfaceFunctionElement): """ @@ -1507,8 +1506,7 @@ def __hash__(self): Returns the hash of self. This is a default implementation of hash which just takes the hash of the string of self. """ - return hash('%s%s'%(self, self._session_number)) - + return hash('%s%s' % (self, self._session_number)) def _check_valid(self): """ @@ -1520,8 +1518,8 @@ def _check_valid(self): try: P = self.parent() if P is None or P._session_number == BAD_SESSION or self._session_number == -1 or \ - P._session_number != self._session_number: - raise ValueError("The %s session in which this object was defined is no longer running."%P.name()) + P._session_number != self._session_number: + raise ValueError("The %s session in which this object was defined is no longer running." % P.name()) except AttributeError: raise ValueError("The session in which this object was defined is no longer running.") return P @@ -1541,7 +1539,7 @@ def __del__(self): pass # def _sage_repr(self): -#TO DO: this could use file transfers when self.is_remote() +# TO DO: this could use file transfers when self.is_remote() class StdOutContext: diff --git a/src/sage/interfaces/mathematica.py b/src/sage/interfaces/mathematica.py index 81da91093b2..2a523086873 100644 --- a/src/sage/interfaces/mathematica.py +++ b/src/sage/interfaces/mathematica.py @@ -369,6 +369,45 @@ e^x sage: exp(x)._mathematica_().sage() # optional -- mathematica e^x + +Check that all trig/hyperbolic functions and their reciprocals are correctly +translated to Mathematica (:trac:`34087`):: + + sage: x=var('x') # optional - mathematica + sage: FL=[sin, cos, tan, csc, sec, cot, # optional - mathematica + ....: sinh, cosh, tanh, csch, sech, coth] + sage: IFL=[arcsin, arccos, arctan, arccsc, # optional - mathematica + ....: arcsec, arccot, arcsinh, arccosh, + ....: arctanh, arccsch, arcsech, arccoth] + sage: [mathematica.TrigToExp(u(x)).sage() # optional - mathematica + ....: for u in FL] + [-1/2*I*e^(I*x) + 1/2*I*e^(-I*x), + 1/2*e^(I*x) + 1/2*e^(-I*x), + (-I*e^(I*x) + I*e^(-I*x))/(e^(I*x) + e^(-I*x)), + 2*I/(e^(I*x) - e^(-I*x)), + 2/(e^(I*x) + e^(-I*x)), + -(-I*e^(I*x) - I*e^(-I*x))/(e^(I*x) - e^(-I*x)), + -1/2*e^(-x) + 1/2*e^x, + 1/2*e^(-x) + 1/2*e^x, + -e^(-x)/(e^(-x) + e^x) + e^x/(e^(-x) + e^x), + -2/(e^(-x) - e^x), + 2/(e^(-x) + e^x), + -(e^(-x) + e^x)/(e^(-x) - e^x)] + sage: [mathematica.TrigToExp(u(x)).sage() # optional - mathematica + ....: for u in IFL] + [-I*log(I*x + sqrt(-x^2 + 1)), + 1/2*pi + I*log(I*x + sqrt(-x^2 + 1)), + -1/2*I*log(I*x + 1) + 1/2*I*log(-I*x + 1), + -I*log(sqrt(-1/x^2 + 1) + I/x), + 1/2*pi + I*log(sqrt(-1/x^2 + 1) + I/x), + -1/2*I*log(I/x + 1) + 1/2*I*log(-I/x + 1), + log(x + sqrt(x^2 + 1)), + log(sqrt(x + 1)*sqrt(x - 1) + x), + 1/2*log(x + 1) - 1/2*log(-x + 1), + log(sqrt(1/x^2 + 1) + 1/x), + log(sqrt(1/x + 1)*sqrt(1/x - 1) + 1/x), + 1/2*log(1/x + 1) - 1/2*log(-1/x + 1)] + """ # **************************************************************************** diff --git a/src/sage/interfaces/tachyon.py b/src/sage/interfaces/tachyon.py index a5b11f4cfab..23671e50892 100644 --- a/src/sage/interfaces/tachyon.py +++ b/src/sage/interfaces/tachyon.py @@ -4,6 +4,673 @@ AUTHOR: - John E. Stone + +This documentation, which was written by John Stone, describes how to +create scene files. + +At the present time, scene description files are very simple. The parser +can’t handle multiple file scene descriptions, although they may be +added in the future. Most of the objects and their scene description are +closely related to the RAY API. *(See the API docs for additional info.)* + +Basic Scene Requirements +------------------------ + +Unlike some other ray tracers out there, RAY requires that you specify +most of the scene parameters in the scene description file itself. If +users would rather specify some of these parameters at the command line, +then I may add that feature in the future. A scene description file +contains keywords, and values associated or grouped with a keyword. All +keywords can be in caps, lower case, or mixed case for the convenience +of the user. File names and texture names are normally case-sensitive, +although the behavior for file names is operating system-dependent. All +values are either character strings, or floating point numbers. In some +cases, the presence of one keyword will require additional keyword / +value pairs. + +At the moment there are several keywords with values, that must appear +in every scene description file. Every scene description file must begin +with the ``BEGIN_SCENE`` keyword, and end with the ``END_SCENE`` +keyword. All definitions and declarations of any kind must be inside the +``BEGIN_SCENE``, ``END_SCENE`` pair. The ``RESOLUTION`` keyword is +followed by an x resolution and a y resolution in terms of pixels on +each axis. There are currently no limits placed on the resolution of an +output image other than the computer’s available memory and reasonable +execution time. An example of a simple scene description skeleton is +show below: + +:: + + BEGIN_SCENE + RESOLUTION 1024 1024 + ... + ... Camera definition.. + ... + ... Other objects, etc.. + ... + + END_SCENE + +Camera and viewing parameters +----------------------------- + +One of the most important parts of any scene, is the camera position and +orientation. Having a good angle on a scene can make the difference +between an average looking scene and a strikingly interesting one. There +may be multiple camera definitions in a scene file, but the last camera +definition overrides all previous definitions. There are several +parameters that control the camera in , ``PROJECTION``, ``ZOOM``, +``ASPECTRATIO``, ``ANTIALIASING``, ``CENTER``, ``RAYDEPTH``, +``VIEWDIR``, and ``UPDIR``. + +The first and last keywords required in the definition of a camera are +the ``CAMERA`` and ``END_CAMERA`` keywords. The ``PROJECTION`` keyword +is optional, the remaining camera keywords are required, and must be +written in the sequence they are listed in the examples in this section. + +Camera projection modes +~~~~~~~~~~~~~~~~~~~~~~~ + +The ``PROJECTION`` keyword must be followed by one of the supported +camera projection mode identifiers ``PERSPECTIVE``, ``PERSPECTIVE_DOF``, +``ORTHOGRAPHIC``, or ``FISHEYE``. The ``FISHEYE`` projection mode +requires two extra parameters ``FOCALLENGTH`` and ``APERTURE`` which +precede the regular camera options. + +:: + + Camera + projection perspective_dof + focallength 0.75 + aperture 0.02 + Zoom 0.666667 + Aspectratio 1.000000 + Antialiasing 128 + Raydepth 30 + Center 0.000000 0.000000 -2.000000 + Viewdir -0.000000 -0.000000 2.000000 + Updir 0.000000 1.000000 -0.000000 + End_Camera + +Common camera parameters +~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``ZOOM`` parameter controls the camera in a way similar to a +telephoto lens on a 35mm camera. A zoom value of 1.0 is standard, with a +90 degree field of view. By changing the zoom factor to 2.0, the +relative size of any feature in the frame is twice as big, while the +field of view is decreased slightly. The zoom effect is implemented as a +scaling factor on the height and width of the image plane relative to +the world. + +The ``ASPECTRATIO`` parameter controls the aspect ratio of the resulting +image. By using the aspect ratio parameter, one can produce images which +look correct on any screen. Aspect ratio alters the relative width of +the image plane, while keeping the height of the image plane constant. +In general, most workstation displays have an aspect ratio of 1.0. To +see what aspect ratio your display has, you can render a simple sphere, +at a resolution of 512x512 and measure the ratio of its width to its +height. + +The ``ANTIALIASING`` parameter controls the maximum level of +supersampling used to obtain higher image quality. The parameter given +sets the number of additional rays to trace per-pixel to attain higher +image quality. + +The ``RAYDEPTH`` parameter tells RAY what the maximum level of +reflections, refraction, or in general the maximum recursion depth to +trace rays to. A value between 4 and 12 is usually good. A value of 1 +will disable rendering of reflective or transmissive objects (they’ll be +black). + +The remaining three camera parameters are the most important, because +they define the coordinate system of the camera, and its position in the +scene. The ``CENTER`` parameter is an X, Y, Z coordinate defining the +center of the camera *(also known as the Center of Projection)*. Once +you have determined where the camera will be placed in the scene, you +need to tell RAY what the camera should be looking at. The ``VIEWDIR`` +parameter is a vector indicating the direction the camera is facing. It +may be useful for me to add a "Look At" type keyword in the future to +make camera aiming easier. If people want or need the "Look At" style +camera, let me know. The last parameter needed to completely define a +camera is the "up" direction. The ``UPDIR`` parameter is a vector which +points in the direction of the "sky". I wrote the camera so that +``VIEWDIR`` and ``UPDIR`` don’t have to be perpendicular, and there +shouldn’t be a need for a "right" vector although some other ray tracers +require it. Here’s a snippet of a camera definition: + +:: + + CAMERA + ZOOM 1.0 + ASPECTRATIO 1.0 + ANTIALIASING 0 + RAYDEPTH 12 + CENTER 0.0 0.0 2.0 + VIEWDIR 0 0 -1 + UPDIR 0 1 0 + END_CAMERA + +Viewing frustum +~~~~~~~~~~~~~~~ + +An optional ``FRUSTUM`` parameter provides a means for rendering +sub-images in a larger frame, and correct stereoscopic images. The +``FRUSTUM`` keyword must be followed by four floating parameters, which +indicate the top, bottom, left and right coordinates of the image plane +in eye coordinates. When the projection mode is set to ``FISHEYE``, the +frustum parameters correspond to spherical coordinates specified in +radians. + +:: + + CAMERA + ZOOM 1.0 + ASPECTRATIO 1.0 + ANTIALIASING 0 + RAYDEPTH 4 + CENTER 0.0 0.0 -6.0 + VIEWDIR 0.0 0.0 1.0 + UPDIR 0.0 1.0 0.0 + FRUSTUM -0.5 0.5 -0.5 0.5 + END_CAMERA + +Including Files +--------------- + +The ``INCLUDE`` keyword is used anywhere after the camera description, +and is immediately followed by a valid filename, for a file containing +additional scene description information. The included file is opened, +and processing continues as if it were part of the current file, until +the end of the included file is reached. Parsing of the current file +continues from where it left off prior to the included file. + +Scene File Comments +------------------- + +The ``#`` keyword is used anywhere after the camera +description, and will cause RAY to ignore all characters from the +``#`` to the end of the input line. The ``#`` +character must be surrounded by whitespace in order to be recognized. A +sequence such as ``###`` will not be recognized as a comment. + +Lights +------ + +The most frequently used type of lights provided by RAY are positional +point light sources. The lights are actually small spheres, which are +visible. A point light is composed of three pieces of information, a +center, a radius (since its a sphere), and a color. To define a light, +simply write the ``LIGHT`` keyword, followed by its ``CENTER`` (a X, Y, +Z coordinate), its ``RAD`` (radius, a scalar), and its ``COLOR`` (a Red +Green Blue triple). The radius parameter will accept any value of 0.0 or +greater. Lights of radius 0.0 will not be directly visible in the +rendered scene, but contribute light to the scene normally. For a light, +the color values range from 0.0 to 1.0, any values outside this range +may yield unpredictable results. A simple light definition looks like +this: + +:: + + LIGHT CENTER 4.0 3.0 2.0 + RAD 0.2 + COLOR 0.5 0.5 0.5 + +This light would be gray colored if seen directly, and would be 50% +intensity in each RGB color component. + +RAY supports simple directional lighting, commonly used in CAD and +scientific visualization programs for its performance advantages over +positional lights. Directional lights cannot be seen directly in scenes +rendered by , only their illumination contributes to the final image. + +:: + + DIRECTIONAL_LIGHT + DIRECTION 0.0 -1.0 0.0 + COLOR 1.0 0.0 0.0 + +RAY supports spotlights, which are described very similarly to a point +light, but they are attenuated by angle from the direction vector, based +on a “falloff start” angle and “falloff end”angle. Between the starting +and ending angles, the illumination is attenuated linearly. The syntax +for a spotlight description in a scene file is as follows. + +:: + + SPOTLIGHT + CENTER 0.0 3.0 17.0 + RAD 0.2 + DIRECTION 0.0 -1.0 0.0 + FALLOFF_START 20.0 + FALLOFF_END 45.0 + COLOR 1.0 0.0 0.0 + +The lighting system implemented by RAY provides various levels of +distance-based lighting attenuation. By default, a light is not +attenuated by distance. If the *attenuation* keywords is present +immediately prior to the light’s color, RAY will accept coefficients +which are used to calculate distance-based attenuation, which is applied +the light by multiplying with the resulting value. The attenuation +factor is calculated from the equation + +.. math:: 1/(K_c + K_l d + k_q d^2) + +This attenuation equation should be familiar to some as it is the same +lighting attenuation equation used by OpenGL. The constant, linear, and +quadratic terms are specified in a scene file as shown in the following +example. + +:: + + LIGHT + CENTER -5.0 0.0 10.0 + RAD 1.0 + ATTENUATION CONSTANT 1.0 LINEAR 0.2 QUADRATIC 0.05 + COLOR 1.0 0.0 0.0 + +Atmospheric effects +------------------- + +RAY currently only implements one atmospheric effect, simple +distance-based fog. + +Fog +~~~ + +RAY provides a simple distance-based fog effect intended to provide +functionality similar to that found in OpenGL, for compatibility with +software that requires an OpenGL-like fog implementation. Much like +OpenGL, RAY provides linear, exponential, and exponential-squared fog. + +:: + + FOG + LINEAR START 0.0 END 50.0 DENSITY 1.0 COLOR 1.0 1.0 1.0 + +:: + + FOG + EXP START 0.0 END 50.0 DENSITY 1.0 COLOR 1.0 1.0 1.0 + +:: + + FOG + EXP2 START 0.0 END 50.0 DENSITY 1.0 COLOR 1.0 1.0 1.0 + +Objects +------- + +Spheres +~~~~~~~ + +Spheres are the simplest object supported by RAY and they are also the +fastest object to render. Spheres are defined as one would expect, with +a ``CENTER``, ``RAD`` (radius), and a texture. The texture may be +defined along with the object as discussed earlier, or it may be +declared and assigned a name. Here’s a sphere definition using a +previously defined "NitrogenAtom" texture: + +:: + + SPHERE CENTER 26.4 27.4 -2.4 RAD 1.0 NitrogenAtom + +A sphere with an inline texture definition is declared like this: + +:: + + Sphere center 1.0 0.0 10.0 + Rad 1.0 + Texture Ambient 0.2 Diffuse 0.8 Specular 0.0 Opacity 1.0 + Color 1.0 0.0 0.5 + TexFunc 0 + +Notice that in this example I used mixed case for the keywords, this is +allowable... Review the section on textures if the texture definitions +are confusing. + +Triangles +~~~~~~~~~ + +Triangles are also fairly simple objects, constructed by listing the +three vertices of the triangle, and its texture. The order of the +vertices isn’t important, the triangle object is "double sided", so the +surface normal is always pointing back in the direction of the incident +ray. The triangle vertices are listed as ``V1``, ``V2``, and ``V3`` each +one is an X, Y, Z coordinate. An example of a triangle is shown below: + +:: + + TRI + V0 0.0 -4.0 12.0 + V1 4.0 -4.0 8.0 + V2 -4.0 -4.0 8.0 + TEXTURE + AMBIENT 0.1 DIFFUSE 0.2 SPECULAR 0.7 OPACITY 1.0 + COLOR 1.0 1.0 1.0 + TEXFUNC 0 + +Smoothed Triangles +~~~~~~~~~~~~~~~~~~ + +Smoothed triangles are just like regular triangles, except that the +surface normal for each of the three vertices is used to determine the +surface normal across the triangle by linear interpolation. Smoothed +triangles yield curved looking objects and have nice reflections. + +:: + + STRI + V0 1.4 0.0 2.4 + V1 1.35 -0.37 2.4 + V2 1.36 -0.32 2.45 + N0 -0.9 -0.0 -0.4 + N1 -0.8 0.23 -0.4 + N2 -0.9 0.27 -0.15 + TEXTURE + AMBIENT 0.1 DIFFUSE 0.2 SPECULAR 0.7 OPACITY 1.0 + COLOR 1.0 1.0 1.0 + TEXFUNC 0 + +Infinite Planes +~~~~~~~~~~~~~~~ + +Useful for things like desert floors, backgrounds, skies etc, the +infinite plane is pretty easy to use. An infinite plane only consists of +two pieces of information, the ``CENTER`` of the plane, and a ``NORMAL`` +to the plane. The center of the plane is just any point on the plane +such that the point combined with the surface normal define the equation +for the plane. As with triangles, planes are double sided. Here is an +example of an infinite plane: + +:: + + PLANE + CENTER 0.0 -5.0 0.0 + NORMAL 0.0 1.0 0.0 + TEXTURE + AMBIENT 0.1 DIFFUSE 0.9 SPECULAR 0.0 OPACITY 1.0 + COLOR 1.0 1.0 1.0 + TEXFUNC 1 + CENTER 0.0 -5.0 0.0 + ROTATE 0. 0.0 0.0 + SCALE 1.0 1.0 1.0 + +Rings +~~~~~ + +Rings are a simple object, they are really a not-so-infinite plane. +Rings are simply an infinite plane cut into a washer shaped ring, +infinitely thing just like a plane. A ring only requires two more pieces +of information than an infinite plane does, an inner and outer radius. +Here’s an example of a ring: + +:: + + Ring + Center 1.0 1.0 1.0 + Normal 0.0 1.0 0.0 + Inner 1.0 + Outer 5.0 + MyNewRedTexture + +Infinite Cylinders +~~~~~~~~~~~~~~~~~~ + +Infinite cylinders are quite simple. They are defined by a center, an +axis, and a radius. An example of an infinite cylinder is: + +:: + + Cylinder + Center 0.0 0.0 0.0 + Axis 0.0 1.0 0.0 + Rad 1.0 + SomeRandomTexture + +Finite Cylinders +~~~~~~~~~~~~~~~~ + +Finite cylinders are almost the same as infinite ones, but the center +and length of the axis determine the extents of the cylinder. The finite +cylinder is also really a shell, it doesn’t have any caps. If you need +to close off the ends of the cylinder, use two ring objects, with the +inner radius set to 0.0 and the normal set to be the axis of the +cylinder. Finite cylinders are built this way to enhance speed. + +:: + + FCylinder + Center 0.0 0.0 0.0 + Axis 0.0 9.0 0.0 + Rad 1.0 + SomeRandomTexture + +This defines a finite cylinder with radius 1.0, going from 0.0 0.0 0.0, +to 0.0 9.0 0.0 along the Y axis. The main difference between an infinite +cylinder and a finite cylinder is in the interpretation of the ``AXIS`` +parameter. In the case of the infinite cylinder, the length of the axis +vector is ignored. In the case of the finite cylinder, the axis +parameter is used to determine the length of the overall cylinder. + +Axis Aligned Boxes +~~~~~~~~~~~~~~~~~~ + +Axis aligned boxes are fast, but of limited usefulness. As such, I’m not +going to waste much time explaining ’em. An axis aligned box is defined +by a ``MIN`` point, and a ``MAX`` point. The volume between the min and +max points is the box. Here’s a simple box: + +:: + + BOX + MIN -1.0 -1.0 -1.0 + MAX 1.0 1.0 1.0 + Boxtexture1 + +Fractal Landscapes +~~~~~~~~~~~~~~~~~~ + +Currently fractal landscapes are a built-in function. In the near future +I’ll allow the user to load an image map for use as a heightfield. +Fractal landscapes are currently forced to be axis aligned. Any +suggestion on how to make them more appealing to users is welcome. A +fractal landscape is defined by its "resolution" which is the number of +grid points along each axis, and by its scale and center. The "scale" is +how large the landscape is along the X, and Y axes in world coordinates. +Here’s a simple landscape: + +:: + + SCAPE + RES 30 30 + SCALE 80.0 80.0 + CENTER 0.0 -4.0 20.0 + TEXTURE + AMBIENT 0.1 DIFFUSE 0.9 SPECULAR 0.0 OPACITY 1.0 + COLOR 1.0 1.0 1.0 + TEXFUNC 0 + +The landscape shown above generates a square landscape made of 1,800 +triangles. When time permits, the heightfield code will be rewritten to +be more general and to increase rendering speed. + +Arbitrary Quadric Surfaces +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Docs soon. I need to add these into the parser, must have forgotten +before ;-) + +Volume Rendered Scalar Voxels +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These are a little trickier than the average object :-) These are likely +to change substantially in the very near future so I’m not going to get +too detailed yet. A volume rendered data set is described by its axis +aligned bounding box, and its resolution along each axis. The final +parameter is the voxel data file. If you are seriously interested in +messing with these, get hold of me and I’ll give you more info. Here’s a +quick example: + +:: + + SCALARVOL + MIN -1.0 -1.0 -0.4 + MAX 1.0 1.0 0.4 + DIM 256 256 100 + FILE /cfs/johns/vol/engine.256x256x110 + TEXTURE + AMBIENT 1.0 DIFFUSE 0.0 SPECULAR 0.0 OPACITY 8.1 + COLOR 1.0 1.0 1.0 + TEXFUNC 0 + +Texture and Color +----------------- + +Simple Texture Characteristics +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The surface textures applied to an object drastically alter its overall +appearance, making textures and color one of the most important topics +in this manual. As with many other renderers, textures can be declared +and associated with a name so that they may be used over and over again +in a scene definition with less typing. If a texture is only need once, +or it is unique to a particular object in the scene, then it may be +declared along with the object it is applied to, and does not need a +name. + +The simplest texture definition is a solid color with no image mapping +or procedural texture mapping. A solid color texture is defined by the +``AMBIENT``, ``DIFFUSE``, ``SPECULAR``, ``OPACITY`` and ``COLOR`` +parameters. The ``AMBIENT`` parameter defines the ambient lighting +coefficient to be used when shading the object. Similarly, the +``DIFFUSE`` parameter is the relative contribution of the diffuse +shading to the surface appearance. The ``SPECULAR`` parameter is the +contribution from perfectly reflected rays, as if on a mirrored surface. +``OPACITY`` defines how transparent a surface is. An ``OPACITY`` value +of 0.0 renders the object completely invisible. An ``OPACITY`` value of +1.0 makes the object completely solid, and non-transmissive. In general, +the values for the ambient, diffuse, and specular parameters should add +up to 1.0, if they don’t then pixels may be over or underexposed quite +easily. These parameters function in a manner similar to that of other +ray tracers. The ``COLOR`` parameter is an RGB triple with each value +ranging from 0.0 to 1.0 inclusive. If the RGB values stray from 0.0 to +1.0, results are undefined. In the case of solid textures, a final +parameter, ``TEXFUNC`` is set to zero (integer). + +Texture Declaration and Aliasing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To define a simple texture for use on several objects in a scene, the +``TEXDEF`` keyword is used. The ``TEXDEF`` keyword is followed by a case +sensitive texture name, which will subsequently be used while defining +objects. If many objects in a scene use the same texture through texture +definition, a significant amount of memory may be saved since only one +copy of the texture is present in memory, and its shared by all of the +objects. Here is an example of a solid texture definition: + +:: + + TEXDEF MyNewRedTexture + AMBIENT 0.1 DIFFUSE 0.9 SPECULAR 0.0 OPACITY 1.0 + COLOR 1.0 0.0 0.0 TEXFUNC 0 + +When this texture is used in an object definition, it is referenced only +by name. Be careful not to use one of the other keywords as a defined +texture, this will probably cause the parser to explode, as I don’t +check for use of keywords as texture names. + +When a texture is declared within an object definition, it appears in an +identical format to the ``TEXDEF`` declaration, but the ``TEXTURE`` +keyword is used instead of ``TEXDEF``. If it is useful to have several +names for the same texture (when you are too lazy to actually finish +defining different variations of a wood texture for example, and just +want to be approximately correct for example) aliases can be constructed +using the ``TEXALIAS`` keyword, along with the alias name, and the +original name. An example of a texture alias is: + +:: + + TEXALIAS MyNewestRedTexture MyNewRedTexture + +This line would alias MyNewestRedTexture to be the same thing as the +previously declared MyNewRedTexture. Note that the source texture must +be declared before any aliases that use it. + +Image Maps and Procedural Textures +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Image maps and procedural textures very useful in making realistic +looking scenes. A good image map can do as much for the realism of a +wooden table as any amount of sophisticated geometry or lighting. Image +maps are made by wrapping an image on to an object in one of three ways, +a spherical map, a cylindrical map, and a planar map. Procedural +textures are used in a way similar to the image maps, but they are on +the fly and do not use much memory compared to the image maps. The main +disadvantage of the procedural maps is that they must be hard-coded into +RAY when it is compiled. + +The syntax used for all texture maps is fairly simple to learn. The +biggest problem with the way that the parser is written now is that the +different mappings are selected by an integer, which is not very user +friendly. I expect to rewrite this section of the parser sometime in the +near future to alleviate this problem. When I rewrite the parser, I may +also end up altering the parameters that are used to describe a texture +map, and some of them may become optional rather than required. + +.. container:: center + + +---------------------------+-----------------------------------------+ + | Texture Mapping Functions | | + +===========================+=========================================+ + | Value for TEXFUNC | Mapping and Texture Description | + +---------------------------+-----------------------------------------+ + | 0 | No special texture, plain shading | + +---------------------------+-----------------------------------------+ + | 1 | 3D checkerboard function, like a | + | | Rubik’s cube | + +---------------------------+-----------------------------------------+ + | 2 | Grit Texture, randomized surface color | + +---------------------------+-----------------------------------------+ + | 3 | 3D marble texture, uses object’s base | + | | color | + +---------------------------+-----------------------------------------+ + | 4 | 3D wood texture, light and dark brown, | + | | not very good yet | + +---------------------------+-----------------------------------------+ + | 5 | 3D gradient noise function (can’t | + | | remember what it look like | + +---------------------------+-----------------------------------------+ + | 6 | Don’t remember | + +---------------------------+-----------------------------------------+ + | 7 | Cylindrical Image Map, requires ppm | + | | filename | + +---------------------------+-----------------------------------------+ + | 8 | Spherical Image Map, requires ppm | + | | filename | + +---------------------------+-----------------------------------------+ + | 9 | Planar Image Map, requires ppm filename | + +---------------------------+-----------------------------------------+ + +Here’s an example of a sphere, with a spherical image map applied to its +surface: + +:: + + SPHERE + CENTER 2.0 0.0 5.0 + RAD 2.0 + TEXTURE + AMBIENT 0.4 DIFFUSE 0.8 SPECULAR 0.0 OPACITY 1.0 + COLOR 1.0 1.0 1.0 + TEXFUNC 7 /cfs/johns/imaps/fire644.ppm + CENTER 2.0 0.0 5.0 + ROTATE 0.0 0.0 0.0 + SCALE 2.0 -2.0 1.0 + +Basically, the image maps require the center, rotate and scale +parameters so that you can position the image map on the object +properly. """ #***************************************************************************** @@ -19,6 +686,7 @@ from sage.cpython.string import bytes_to_str from sage.misc.pager import pager +from sage.misc.superseded import deprecation from sage.misc.temporary_file import tmp_filename from sage.structure.sage_object import SageObject @@ -27,12 +695,13 @@ class TachyonRT(SageObject): r""" The Tachyon Ray Tracer - tachyon_rt(model, outfile='sage.png', verbose=1, block=True, extra_opts='') + Usage: + ``tachyon_rt(model, outfile='sage.png', verbose=1, block=True, extra_opts='')`` INPUT: - ``model`` - a string that describes a 3d model in - the Tachyon modeling format. Type tachyon_rt.help() for a + the Tachyon modeling format. Type ``sage.interfaces.tachyon?`` for a description of this format. - ``outfile`` - (default: 'sage.png') output filename; @@ -63,684 +732,14 @@ class TachyonRT(SageObject): - ``extra_opts`` - passed directly to tachyon command line. Use tachyon_rt.usage() to see some of the possibilities. - OUTPUT: - Some text may be displayed onscreen. - The file outfile is created. - - This help, which was written by John Stone, describes how to create - scene files. - - At the present time, scene description files are very simple. The parser - can’t handle multiple file scene descriptions, although they may be - added in the future. Most of the objects and their scene description are - closely related to the RAY API *(See the API docs for additional info.)* - - Basic Scene Requirements - ------------------------ - - Unlike some other ray tracers out there, RAY requires that you specify - most of the scene parameters in the scene description file itself. If - users would rather specify some of these parameters at the command line, - then I may add that feature in the future. A scene description file - contains keywords, and values associated or grouped with a keyword. All - keywords can be in caps, lower case, or mixed case for the convenience - of the user. File names and texture names are normally case-sensitive, - although the behavior for file names is operating system-dependent. All - values are either character strings, or floating point numbers. In some - cases, the presence of one keyword will require additional keyword / - value pairs. - - At the moment there are several keywords with values, that must appear - in every scene description file. Every scene description file must begin - with the ``BEGIN_SCENE`` keyword, and end with the ``END_SCENE`` - keyword. All definitions and declarations of any kind must be inside the - ``BEGIN_SCENE``, ``END_SCENE`` pair. The ``RESOLUTION`` keyword is - followed by an x resolution and a y resolution in terms of pixels on - each axis. There are currently no limits placed on the resolution of an - output image other than the computer’s available memory and reasonable - execution time. An example of a simple scene description skeleton is - show below: - - :: - - BEGIN_SCENE - RESOLUTION 1024 1024 - ... - ... Camera definition.. - ... - ... Other objects, etc.. - ... - - END_SCENE - - Camera and viewing parameters - ----------------------------- - - One of the most important parts of any scene, is the camera position and - orientation. Having a good angle on a scene can make the difference - between an average looking scene and a strikingly interesting one. There - may be multiple camera definitions in a scene file, but the last camera - definition overrides all previous definitions. There are several - parameters that control the camera in , ``PROJECTION``, ``ZOOM``, - ``ASPECTRATIO``, ``ANTIALIASING``, ``CENTER``, ``RAYDEPTH``, - ``VIEWDIR``, and ``UPDIR``. - - The first and last keywords required in the definition of a camera are - the ``CAMERA`` and ``END_CAMERA`` keywords. The ``PROJECTION`` keyword - is optional, the remaining camera keywords are required, and must be - written in the sequence they are listed in the examples in this section. - - Camera projection modes - ~~~~~~~~~~~~~~~~~~~~~~~ - - The ``PROJECTION`` keyword must be followed by one of the supported - camera projection mode identifiers ``PERSPECTIVE``, ``PERSPECTIVE_DOF``, - ``ORTHOGRAPHIC``, or ``FISHEYE``. The ``FISHEYE`` projection mode - requires two extra parameters ``FOCALLENGTH`` and ``APERTURE`` which - precede the regular camera options. - - :: - - Camera - projection perspective_dof - focallength 0.75 - aperture 0.02 - Zoom 0.666667 - Aspectratio 1.000000 - Antialiasing 128 - Raydepth 30 - Center 0.000000 0.000000 -2.000000 - Viewdir -0.000000 -0.000000 2.000000 - Updir 0.000000 1.000000 -0.000000 - End_Camera - - Common camera parameters - ~~~~~~~~~~~~~~~~~~~~~~~~ - - The ``ZOOM`` parameter controls the camera in a way similar to a - telephoto lens on a 35mm camera. A zoom value of 1.0 is standard, with a - 90 degree field of view. By changing the zoom factor to 2.0, the - relative size of any feature in the frame is twice as big, while the - field of view is decreased slightly. The zoom effect is implemented as a - scaling factor on the height and width of the image plane relative to - the world. - - The ``ASPECTRATIO`` parameter controls the aspect ratio of the resulting - image. By using the aspect ratio parameter, one can produce images which - look correct on any screen. Aspect ratio alters the relative width of - the image plane, while keeping the height of the image plane constant. - In general, most workstation displays have an aspect ratio of 1.0. To - see what aspect ratio your display has, you can render a simple sphere, - at a resolution of 512x512 and measure the ratio of its width to its - height. - - The ``ANTIALIASING`` parameter controls the maximum level of - supersampling used to obtain higher image quality. The parameter given - sets the number of additional rays to trace per-pixel to attain higher - image quality. - - The ``RAYDEPTH`` parameter tells RAY what the maximum level of - reflections, refraction, or in general the maximum recursion depth to - trace rays to. A value between 4 and 12 is usually good. A value of 1 - will disable rendering of reflective or transmissive objects (they’ll be - black). - - The remaining three camera parameters are the most important, because - they define the coordinate system of the camera, and its position in the - scene. The ``CENTER`` parameter is an X, Y, Z coordinate defining the - center of the camera *(also known as the Center of Projection)*. Once - you have determined where the camera will be placed in the scene, you - need to tell RAY what the camera should be looking at. The ``VIEWDIR`` - parameter is a vector indicating the direction the camera is facing. It - may be useful for me to add a "Look At" type keyword in the future to - make camera aiming easier. If people want or need the "Look At" style - camera, let me know. The last parameter needed to completely define a - camera is the "up" direction. The ``UPDIR`` parameter is a vector which - points in the direction of the "sky". I wrote the camera so that - ``VIEWDIR`` and ``UPDIR`` don’t have to be perpendicular, and there - shouldn’t be a need for a "right" vector although some other ray tracers - require it. Here’s a snippet of a camera definition: - - :: - - CAMERA - ZOOM 1.0 - ASPECTRATIO 1.0 - ANTIALIASING 0 - RAYDEPTH 12 - CENTER 0.0 0.0 2.0 - VIEWDIR 0 0 -1 - UPDIR 0 1 0 - END_CAMERA - - Viewing frustum - ~~~~~~~~~~~~~~~ - - An optional ``FRUSTUM`` parameter provides a means for rendering - sub-images in a larger frame, and correct stereoscopic images. The - ``FRUSTUM`` keyword must be followed by four floating parameters, which - indicate the top, bottom, left and right coordinates of the image plane - in eye coordinates. When the projection mode is set to ``FISHEYE``, the - frustum parameters correspond to spherical coordinates specified in - radians. - - :: - - CAMERA - ZOOM 1.0 - ASPECTRATIO 1.0 - ANTIALIASING 0 - RAYDEPTH 4 - CENTER 0.0 0.0 -6.0 - VIEWDIR 0.0 0.0 1.0 - UPDIR 0.0 1.0 0.0 - FRUSTUM -0.5 0.5 -0.5 0.5 - END_CAMERA - - Including Files - --------------- - - The ``INCLUDE`` keyword is used anywhere after the camera description, - and is immediately followed by a valid filename, for a file containing - additional scene description information. The included file is opened, - and processing continues as if it were part of the current file, until - the end of the included file is reached. Parsing of the current file - continues from where it left off prior to the included file. - - Scene File Comments - ------------------- - - The ``#`` keyword is used anywhere after the camera - description, and will cause RAY to ignore all characters from the - ``#`` to the end of the input line. The ``#`` - character must be surrounded by whitespace in order to be recognized. A - sequence such as ``###`` will not be recognized as a comment. - - Lights - ------ - - The most frequently used type of lights provided by RAY are positional - point light sources. The lights are actually small spheres, which are - visible. A point light is composed of three pieces of information, a - center, a radius (since its a sphere), and a color. To define a light, - simply write the ``LIGHT`` keyword, followed by its ``CENTER`` (a X, Y, - Z coordinate), its ``RAD`` (radius, a scalar), and its ``COLOR`` (a Red - Green Blue triple). The radius parameter will accept any value of 0.0 or - greater. Lights of radius 0.0 will not be directly visible in the - rendered scene, but contribute light to the scene normally. For a light, - the color values range from 0.0 to 1.0, any values outside this range - may yield unpredictable results. A simple light definition looks like - this: - - :: - - LIGHT CENTER 4.0 3.0 2.0 - RAD 0.2 - COLOR 0.5 0.5 0.5 - - This light would be gray colored if seen directly, and would be 50% - intensity in each RGB color component. - - RAY supports simple directional lighting, commonly used in CAD and - scientific visualization programs for its performance advantages over - positional lights. Directional lights cannot be seen directly in scenes - rendered by , only their illumination contributes to the final image. - - :: - - DIRECTIONAL_LIGHT - DIRECTION 0.0 -1.0 0.0 - COLOR 1.0 0.0 0.0 - - RAY supports spotlights, which are described very similarly to a point - light, but they are attenuated by angle from the direction vector, based - on a “falloff start” angle and “falloff end”angle. Between the starting - and ending angles, the illumination is attenuated linearly. The syntax - for a spotlight description in a scene file is as follows. - - :: - - SPOTLIGHT - CENTER 0.0 3.0 17.0 - RAD 0.2 - DIRECTION 0.0 -1.0 0.0 - FALLOFF_START 20.0 - FALLOFF_END 45.0 - COLOR 1.0 0.0 0.0 - - The lighting system implemented by RAY provides various levels of - distance-based lighting attenuation. By default, a light is not - attenuated by distance. If the *attenuation* keywords is present - immediately prior to the light’s color, RAY will accept coefficients - which are used to calculate distance-based attenuation, which is applied - the light by multiplying with the resulting value. The attenuation - factor is calculated from the equation - - .. math:: 1/(K_c + K_l d + k_q d^2) - - This attenuation equation should be familiar to some as it is the same - lighting attenuation equation used by OpenGL. The constant, linear, and - quadratic terms are specified in a scene file as shown in the following - example. - - :: - - LIGHT - CENTER -5.0 0.0 10.0 - RAD 1.0 - ATTENUATION CONSTANT 1.0 LINEAR 0.2 QUADRATIC 0.05 - COLOR 1.0 0.0 0.0 - - Atmospheric effects - ------------------- - - RAY currently only implements one atmospheric effect, simple - distance-based fog. - - Fog - ~~~ - - RAY provides a simple distance-based fog effect intended to provide - functionality similar to that found in OpenGL, for compatibility with - software that requires an OpenGL-like fog implementation. Much like - OpenGL, RAY provides linear, exponential, and exponential-squared fog. - - :: - - FOG - LINEAR START 0.0 END 50.0 DENSITY 1.0 COLOR 1.0 1.0 1.0 - - :: - - FOG - EXP START 0.0 END 50.0 DENSITY 1.0 COLOR 1.0 1.0 1.0 - - :: - - FOG - EXP2 START 0.0 END 50.0 DENSITY 1.0 COLOR 1.0 1.0 1.0 - - Objects - ------- - - Spheres - ~~~~~~~ - - Spheres are the simplest object supported by RAY and they are also the - fastest object to render. Spheres are defined as one would expect, with - a ``CENTER``, ``RAD`` (radius), and a texture. The texture may be - defined along with the object as discussed earlier, or it may be - declared and assigned a name. Here’s a sphere definition using a - previously defined "NitrogenAtom" texture: - - :: - - SPHERE CENTER 26.4 27.4 -2.4 RAD 1.0 NitrogenAtom - - A sphere with an inline texture definition is declared like this: - - :: - - Sphere center 1.0 0.0 10.0 - Rad 1.0 - Texture Ambient 0.2 Diffuse 0.8 Specular 0.0 Opacity 1.0 - Color 1.0 0.0 0.5 - TexFunc 0 - - Notice that in this example I used mixed case for the keywords, this is - allowable... Review the section on textures if the texture definitions - are confusing. - - Triangles - ~~~~~~~~~ - - Triangles are also fairly simple objects, constructed by listing the - three vertices of the triangle, and its texture. The order of the - vertices isn’t important, the triangle object is "double sided", so the - surface normal is always pointing back in the direction of the incident - ray. The triangle vertices are listed as ``V1``, ``V2``, and ``V3`` each - one is an X, Y, Z coordinate. An example of a triangle is shown below: - - :: - - TRI - V0 0.0 -4.0 12.0 - V1 4.0 -4.0 8.0 - V2 -4.0 -4.0 8.0 - TEXTURE - AMBIENT 0.1 DIFFUSE 0.2 SPECULAR 0.7 OPACITY 1.0 - COLOR 1.0 1.0 1.0 - TEXFUNC 0 - - Smoothed Triangles - ~~~~~~~~~~~~~~~~~~ - - Smoothed triangles are just like regular triangles, except that the - surface normal for each of the three vertices is used to determine the - surface normal across the triangle by linear interpolation. Smoothed - triangles yield curved looking objects and have nice reflections. - - :: - - STRI - V0 1.4 0.0 2.4 - V1 1.35 -0.37 2.4 - V2 1.36 -0.32 2.45 - N0 -0.9 -0.0 -0.4 - N1 -0.8 0.23 -0.4 - N2 -0.9 0.27 -0.15 - TEXTURE - AMBIENT 0.1 DIFFUSE 0.2 SPECULAR 0.7 OPACITY 1.0 - COLOR 1.0 1.0 1.0 - TEXFUNC 0 - - Infinite Planes - ~~~~~~~~~~~~~~~ - - Useful for things like desert floors, backgrounds, skies etc, the - infinite plane is pretty easy to use. An infinite plane only consists of - two pieces of information, the ``CENTER`` of the plane, and a ``NORMAL`` - to the plane. The center of the plane is just any point on the plane - such that the point combined with the surface normal define the equation - for the plane. As with triangles, planes are double sided. Here is an - example of an infinite plane: - - :: - - PLANE - CENTER 0.0 -5.0 0.0 - NORMAL 0.0 1.0 0.0 - TEXTURE - AMBIENT 0.1 DIFFUSE 0.9 SPECULAR 0.0 OPACITY 1.0 - COLOR 1.0 1.0 1.0 - TEXFUNC 1 - CENTER 0.0 -5.0 0.0 - ROTATE 0. 0.0 0.0 - SCALE 1.0 1.0 1.0 - - Rings - ~~~~~ - - Rings are a simple object, they are really a not-so-infinite plane. - Rings are simply an infinite plane cut into a washer shaped ring, - infinitely thing just like a plane. A ring only requires two more pieces - of information than an infinite plane does, an inner and outer radius. - Here’s an example of a ring: - - :: - - Ring - Center 1.0 1.0 1.0 - Normal 0.0 1.0 0.0 - Inner 1.0 - Outer 5.0 - MyNewRedTexture - - Infinite Cylinders - ~~~~~~~~~~~~~~~~~~ - - Infinite cylinders are quite simple. They are defined by a center, an - axis, and a radius. An example of an infinite cylinder is: - - :: - - Cylinder - Center 0.0 0.0 0.0 - Axis 0.0 1.0 0.0 - Rad 1.0 - SomeRandomTexture - - Finite Cylinders - ~~~~~~~~~~~~~~~~ - - Finite cylinders are almost the same as infinite ones, but the center - and length of the axis determine the extents of the cylinder. The finite - cylinder is also really a shell, it doesn’t have any caps. If you need - to close off the ends of the cylinder, use two ring objects, with the - inner radius set to 0.0 and the normal set to be the axis of the - cylinder. Finite cylinders are built this way to enhance speed. - - :: - - FCylinder - Center 0.0 0.0 0.0 - Axis 0.0 9.0 0.0 - Rad 1.0 - SomeRandomTexture - - This defines a finite cylinder with radius 1.0, going from 0.0 0.0 0.0, - to 0.0 9.0 0.0 along the Y axis. The main difference between an infinite - cylinder and a finite cylinder is in the interpretation of the ``AXIS`` - parameter. In the case of the infinite cylinder, the length of the axis - vector is ignored. In the case of the finite cylinder, the axis - parameter is used to determine the length of the overall cylinder. - - Axis Aligned Boxes - ~~~~~~~~~~~~~~~~~~ - - Axis aligned boxes are fast, but of limited usefulness. As such, I’m not - going to waste much time explaining ’em. An axis aligned box is defined - by a ``MIN`` point, and a ``MAX`` point. The volume between the min and - max points is the box. Here’s a simple box: - - :: - - BOX - MIN -1.0 -1.0 -1.0 - MAX 1.0 1.0 1.0 - Boxtexture1 - - Fractal Landscapes - ~~~~~~~~~~~~~~~~~~ - - Currently fractal landscapes are a built-in function. In the near future - I’ll allow the user to load an image map for use as a heightfield. - Fractal landscapes are currently forced to be axis aligned. Any - suggestion on how to make them more appealing to users is welcome. A - fractal landscape is defined by its "resolution" which is the number of - grid points along each axis, and by its scale and center. The "scale" is - how large the landscape is along the X, and Y axes in world coordinates. - Here’s a simple landscape: - - :: - - SCAPE - RES 30 30 - SCALE 80.0 80.0 - CENTER 0.0 -4.0 20.0 - TEXTURE - AMBIENT 0.1 DIFFUSE 0.9 SPECULAR 0.0 OPACITY 1.0 - COLOR 1.0 1.0 1.0 - TEXFUNC 0 - - The landscape shown above generates a square landscape made of 1,800 - triangles. When time permits, the heightfield code will be rewritten to - be more general and to increase rendering speed. - - Arbitrary Quadric Surfaces - ~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Docs soon. I need to add these into the parser, must have forgotten - before ;-) - - Volume Rendered Scalar Voxels - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - These are a little trickier than the average object :-) These are likely - to change substantially in the very near future so I’m not going to get - too detailed yet. A volume rendered data set is described by its axis - aligned bounding box, and its resolution along each axis. The final - parameter is the voxel data file. If you are seriously interested in - messing with these, get hold of me and I’ll give you more info. Here’s a - quick example: - - :: - - SCALARVOL - MIN -1.0 -1.0 -0.4 - MAX 1.0 1.0 0.4 - DIM 256 256 100 - FILE /cfs/johns/vol/engine.256x256x110 - TEXTURE - AMBIENT 1.0 DIFFUSE 0.0 SPECULAR 0.0 OPACITY 8.1 - COLOR 1.0 1.0 1.0 - TEXFUNC 0 - - Texture and Color - ----------------- - - Simple Texture Characteristics - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - The surface textures applied to an object drastically alter its overall - appearance, making textures and color one of the most important topics - in this manual. As with many other renderers, textures can be declared - and associated with a name so that they may be used over and over again - in a scene definition with less typing. If a texture is only need once, - or it is unique to a particular object in the scene, then it may be - declared along with the object it is applied to, and does not need a - name. - - The simplest texture definition is a solid color with no image mapping - or procedural texture mapping. A solid color texture is defined by the - ``AMBIENT``, ``DIFFUSE``, ``SPECULAR``, ``OPACITY`` and ``COLOR`` - parameters. The ``AMBIENT`` parameter defines the ambient lighting - coefficient to be used when shading the object. Similarly, the - ``DIFFUSE`` parameter is the relative contribution of the diffuse - shading to the surface appearance. The ``SPECULAR`` parameter is the - contribution from perfectly reflected rays, as if on a mirrored surface. - ``OPACITY`` defines how transparent a surface is. An ``OPACITY`` value - of 0.0 renders the object completely invisible. An ``OPACITY`` value of - 1.0 makes the object completely solid, and non-transmissive. In general, - the values for the ambient, diffuse, and specular parameters should add - up to 1.0, if they don’t then pixels may be over or underexposed quite - easily. These parameters function in a manner similar to that of other - ray tracers. The ``COLOR`` parameter is an RGB triple with each value - ranging from 0.0 to 1.0 inclusive. If the RGB values stray from 0.0 to - 1.0, results are undefined. In the case of solid textures, a final - parameter, ``TEXFUNC`` is set to zero (integer). - - Texture Declaration and Aliasing - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - To define a simple texture for use on several objects in a scene, the - ``TEXDEF`` keyword is used. The ``TEXDEF`` keyword is followed by a case - sensitive texture name, which will subsequently be used while defining - objects. If many objects in a scene use the same texture through texture - definition, a significant amount of memory may be saved since only one - copy of the texture is present in memory, and its shared by all of the - objects. Here is an example of a solid texture definition: - - :: - - TEXDEF MyNewRedTexture - AMBIENT 0.1 DIFFUSE 0.9 SPECULAR 0.0 OPACITY 1.0 - COLOR 1.0 0.0 0.0 TEXFUNC 0 - - When this texture is used in an object definition, it is referenced only - by name. Be careful not to use one of the other keywords as a defined - texture, this will probably cause the parser to explode, as I don’t - check for use of keywords as texture names. - - When a texture is declared within an object definition, it appears in an - identical format to the ``TEXDEF`` declaration, but the ``TEXTURE`` - keyword is used instead of ``TEXDEF``. If it is useful to have several - names for the same texture (when you are too lazy to actually finish - defining different variations of a wood texture for example, and just - want to be approximately correct for example) aliases can be constructed - using the ``TEXALIAS`` keyword, along with the alias name, and the - original name. An example of a texture alias is: - - :: - - TEXALIAS MyNewestRedTexture MyNewRedTexture - - This line would alias MyNewestRedTexture to be the same thing as the - previously declared MyNewRedTexture. Note that the source texture must - be declared before any aliases that use it. - - Image Maps and Procedural Textures - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Image maps and procedural textures very useful in making realistic - looking scenes. A good image map can do as much for the realism of a - wooden table as any amount of sophisticated geometry or lighting. Image - maps are made by wrapping an image on to an object in one of three ways, - a spherical map, a cylindrical map, and a planar map. Procedural - textures are used in a way similar to the image maps, but they are on - the fly and do not use much memory compared to the image maps. The main - disadvantage of the procedural maps is that they must be hard-coded into - RAY when it is compiled. - - The syntax used for all texture maps is fairly simple to learn. The - biggest problem with the way that the parser is written now is that the - different mappings are selected by an integer, which is not very user - friendly. I expect to rewrite this section of the parser sometime in the - near future to alleviate this problem. When I rewrite the parser, I may - also end up altering the parameters that are used to describe a texture - map, and some of them may become optional rather than required. - - .. container:: center - - +---------------------------+-----------------------------------------+ - | Texture Mapping Functions | | - +===========================+=========================================+ - | Value for TEXFUNC | Mapping and Texture Description | - +---------------------------+-----------------------------------------+ - | 0 | No special texture, plain shading | - +---------------------------+-----------------------------------------+ - | 1 | 3D checkerboard function, like a | - | | Rubik’s cube | - +---------------------------+-----------------------------------------+ - | 2 | Grit Texture, randomized surface color | - +---------------------------+-----------------------------------------+ - | 3 | 3D marble texture, uses object’s base | - | | color | - +---------------------------+-----------------------------------------+ - | 4 | 3D wood texture, light and dark brown, | - | | not very good yet | - +---------------------------+-----------------------------------------+ - | 5 | 3D gradient noise function (can’t | - | | remember what it look like | - +---------------------------+-----------------------------------------+ - | 6 | Don’t remember | - +---------------------------+-----------------------------------------+ - | 7 | Cylindrical Image Map, requires ppm | - | | filename | - +---------------------------+-----------------------------------------+ - | 8 | Spherical Image Map, requires ppm | - | | filename | - +---------------------------+-----------------------------------------+ - | 9 | Planar Image Map, requires ppm filename | - +---------------------------+-----------------------------------------+ - - Here’s an example of a sphere, with a spherical image map applied to its - surface: - - :: - - SPHERE - CENTER 2.0 0.0 5.0 - RAD 2.0 - TEXTURE - AMBIENT 0.4 DIFFUSE 0.8 SPECULAR 0.0 OPACITY 1.0 - COLOR 1.0 1.0 1.0 - TEXFUNC 7 /cfs/johns/imaps/fire644.ppm - CENTER 2.0 0.0 5.0 - ROTATE 0.0 0.0 0.0 - SCALE 2.0 -2.0 1.0 - - Basically, the image maps require the center, rotate and scale - parameters so that you can position the image map on the object - properly. - EXAMPLES: - .. automethod:: __call__ """ def _repr_(self): @@ -854,22 +853,16 @@ def usage(self, use_pager=True): def help(self, use_pager=True): """ - Prints (pages) the help file written by John Stone describing scene files for Tachyon. The output is paged unless use_pager=False. + Deprecated: type 'sage.interfaces.tachyon?' for help TESTS:: sage: from sage.interfaces.tachyon import TachyonRT sage: t = TachyonRT() sage: t.help(use_pager=False) - The Tachyon Ray Tracer... This help, which was written by John Stone, describes ... + doctest:...: DeprecationWarning: type 'sage.interfaces.tachyon?' for help + See https://trac.sagemath.org/34066 for details. """ - from sage.misc.sagedoc import format - f = format(self.__doc__) - if use_pager: - pager()(f) - else: - print(f) + deprecation(34066, "type 'sage.interfaces.tachyon?' for help") tachyon_rt = TachyonRT() - - diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index 45417f83757..ed0f90dc1b9 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -848,7 +848,7 @@ def is_knot(self): @cached_method def name_unoriented(self): r""" - Return the the part of the name of ``self`` which is independent on the + Return the part of the name of ``self`` which is independent on the orientation. EXAMPLES:: diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index c2068ac0842..dafb088c24b 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -3963,7 +3963,7 @@ def get_knotinfo(self, mirror_version=True, unique=True): sage: Ks10_83.sage_link().get_knotinfo() # optional - snappy (, False) - TESTS: + TESTS:: sage: L = KnotInfo.L10a171_1_1_0 # optional - database_knotinfo sage: l = L.link(L.items.braid_notation) # optional - database_knotinfo diff --git a/src/sage/libs/gmp/randomize.pxd b/src/sage/libs/gmp/randomize.pxd index 51087eaa02e..cdbef70f2c7 100644 --- a/src/sage/libs/gmp/randomize.pxd +++ b/src/sage/libs/gmp/randomize.pxd @@ -53,6 +53,6 @@ cdef inline void mpq_randomize_entry_recip_uniform(mpq_t x): mpq_canonicalize(x) cdef inline void mpq_randomize_entry_recip_uniform_nonzero(mpq_t x): - mpq_randomize_entry_recip_uniform_nonzero(x) + mpq_randomize_entry_recip_uniform(x) while mpq_sgn(x) == 0: - mpq_randomize_entry_recip_uniform_nonzero(x) + mpq_randomize_entry_recip_uniform(x) diff --git a/src/sage/libs/ntl/ntl_ZZX.pyx b/src/sage/libs/ntl/ntl_ZZX.pyx index 759ba34640f..8d38fcb7f8f 100644 --- a/src/sage/libs/ntl/ntl_ZZX.pyx +++ b/src/sage/libs/ntl/ntl_ZZX.pyx @@ -968,7 +968,7 @@ cdef class ntl_ZZX(): def trace_mod(self, ntl_ZZX modulus): """ Return the trace of this polynomial modulus the modulus. - The modulus must be monic, and of positive degree degree bigger + The modulus must be monic, and of positive degree bigger than the degree of self. EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_ZZ_pEX.pyx b/src/sage/libs/ntl/ntl_ZZ_pEX.pyx index 73af622fc98..f9d2e982343 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEX.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pEX.pyx @@ -1048,7 +1048,7 @@ cdef class ntl_ZZ_pEX(): def trace_mod(self, ntl_ZZ_pEX modulus): """ Return the trace of this polynomial modulo the modulus. - The modulus must be monic, and of positive degree degree bigger + The modulus must be monic, and of positive degree bigger than the degree of self. EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_ZZ_pX.pyx b/src/sage/libs/ntl/ntl_ZZ_pX.pyx index 2d03c23a88f..95d77f727fa 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pX.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pX.pyx @@ -1203,7 +1203,7 @@ cdef class ntl_ZZ_pX(): def trace_mod(self, ntl_ZZ_pX modulus): """ Return the trace of this polynomial modulus the modulus. - The modulus must be monic, and of positive degree degree bigger + The modulus must be monic, and of positive degree bigger than the degree of self. EXAMPLES:: diff --git a/src/sage/libs/singular/standard_options.py b/src/sage/libs/singular/standard_options.py index 4756a6ec1db..6797cb05001 100644 --- a/src/sage/libs/singular/standard_options.py +++ b/src/sage/libs/singular/standard_options.py @@ -100,7 +100,7 @@ def __exit__(self, typ, value, tb): self.libsingular_option_context.__exit__(typ,value,tb) def libsingular_gb_standard_options(func): - """ + r""" Decorator to force a reduced Singular groebner basis. TESTS:: diff --git a/src/sage/manifolds/differentiable/scalarfield.py b/src/sage/manifolds/differentiable/scalarfield.py index b2efd06ca9a..9763bf46352 100644 --- a/src/sage/manifolds/differentiable/scalarfield.py +++ b/src/sage/manifolds/differentiable/scalarfield.py @@ -890,7 +890,7 @@ def hodge_dual( self, nondegenerate_tensor: Union[PseudoRiemannianMetric, SymplecticForm] ) -> DiffForm: r""" - Compute the Hodge dual of the scalar field with respect to to some non-degenerate + Compute the Hodge dual of the scalar field with respect to some non-degenerate bilinear form (Riemannian metric or symplectic form). If `M` is the domain of the scalar field (denoted by `f`), `n` is the diff --git a/src/sage/manifolds/differentiable/vectorfield_module.py b/src/sage/manifolds/differentiable/vectorfield_module.py index cec856eb103..cf3f1dc687d 100644 --- a/src/sage/manifolds/differentiable/vectorfield_module.py +++ b/src/sage/manifolds/differentiable/vectorfield_module.py @@ -2241,7 +2241,7 @@ def sym_bilinear_form(self, name=None, latex_name=None): INPUT: - ``name`` -- string (default: ``None``); name given to the - symmetric bilinear bilinear form + symmetric bilinear form - ``latex_name`` -- string (default: ``None``); LaTeX symbol to denote the symmetric bilinear form; if ``None``, the LaTeX symbol is set to ``name`` diff --git a/src/sage/matrix/matrix_rational_dense.pyx b/src/sage/matrix/matrix_rational_dense.pyx index 03eb4b8e120..b86023f5ef9 100644 --- a/src/sage/matrix/matrix_rational_dense.pyx +++ b/src/sage/matrix/matrix_rational_dense.pyx @@ -2351,6 +2351,13 @@ cdef class Matrix_rational_dense(Matrix_dense): False sage: any(b[i,j].is_zero() for i in range(10) for j in range(10)) False + + Check that :trac:`34103` is fixed:: + + sage: a = matrix(QQ, 10, 10, 1) + sage: a.randomize(nonzero=True, distribution='1/n') + sage: bool(a) + True """ density = float(density) if density <= 0.0: diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index d14addb5bfb..c29bcc64260 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -538,7 +538,7 @@ def __classcall__(cls, base_ring, nrows, ncols=None, sparse=False, implementatio ... ValueError: unknown matrix implementation 'foobar' over Integer Ring - Check that :trac:`29466`is fixed:: + Check that :trac:`29466` is fixed:: sage: class MyMatrixSpace(MatrixSpace): ....: @staticmethod @@ -580,7 +580,7 @@ def __init__(self, base_ring, nrows, ncols, sparse, implementation): r""" INPUT: - - ``base_ring` + - ``base_ring`` - ``nrows`` - (positive integer) the number of rows @@ -1107,7 +1107,7 @@ def _coerce_map_from_base_ring(self): return self._generic_coerce_map(self.base_ring()) def _coerce_map_from_(self, S): - """ + r""" Canonical coercion from ``S`` to this matrix space. EXAMPLES:: diff --git a/src/sage/misc/abstract_method.py b/src/sage/misc/abstract_method.py index 99604777c08..720f7f5a7f0 100644 --- a/src/sage/misc/abstract_method.py +++ b/src/sage/misc/abstract_method.py @@ -182,7 +182,7 @@ def __repr__(self): return "<" + ("optional " if self._optional else "") + "abstract method %s at %s>" % (self.__name__, hex(id(self._f))) def _sage_src_lines_(self): - """ + r""" Returns the source code location for the wrapped function. EXAMPLES:: diff --git a/src/sage/misc/cython.py b/src/sage/misc/cython.py index 5a7927b2e1e..1f495803536 100644 --- a/src/sage/misc/cython.py +++ b/src/sage/misc/cython.py @@ -528,6 +528,10 @@ def cython_import(filename, **kwds): try: sys.path.append(build_dir) return builtins.__import__(name) + except ModuleNotFoundError: + import importlib + importlib.invalidate_caches() + return builtins.__import__(name) finally: sys.path = oldpath diff --git a/src/sage/misc/inline_fortran.py b/src/sage/misc/inline_fortran.py index d7ed02fe92b..6e71016c427 100644 --- a/src/sage/misc/inline_fortran.py +++ b/src/sage/misc/inline_fortran.py @@ -47,7 +47,7 @@ def _import_module_from_path(name, path=None): def _import_module_from_path_impl(name, path): - """Implement ``_import_module_from_path for Python 3.4+.""" + """Implement ``_import_module_from_path`` for Python 3.4+.""" # This is remarkably tricky to do right, considering that the new # importlib is supposed to make direct interaction with the import diff --git a/src/sage/misc/sagedoc.py b/src/sage/misc/sagedoc.py index 644341f36bd..7d837a2213f 100644 --- a/src/sage/misc/sagedoc.py +++ b/src/sage/misc/sagedoc.py @@ -39,14 +39,13 @@ # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - - import os import re import sys import pydoc from sage.misc.temporary_file import tmp_dir from .viewer import browser +from . import sageinspect import sage.version from sage.env import SAGE_DOC, SAGE_SRC @@ -88,7 +87,7 @@ (r'\\ast', ' *'), (r' \\times', ' x'), (r'\\times', ' x'), - (r'\\backslash','\\'), + (r'\\backslash', '\\'), (r'\\mapsto', ' |--> '), (r'\\longmapsto', ' |---> '), (r'\\lvert', '|'), @@ -98,24 +97,24 @@ (r'\\circ', ' o') ] nonmath_substitutes = [ - ('\\_','_'), + ('\\_', '_'), ('\\item', '* '), - ('',''), + ('', ''), ('\\bf', ''), ('\\sage', 'Sage'), ('\\SAGE', 'Sage'), ('\\Sage', 'Sage'), ('\\rm', ''), - ('backslash','\\'), - ('begin{enumerate}',''), - ('end{enumerate}',''), - ('begin{description}',''), - ('end{description}',''), - ('begin{itemize}',''), - ('end{itemize}',''), - ('begin{verbatim}',''), - ('end{verbatim}',''), - ('note{','NOTE: '), + ('backslash', '\\'), + ('begin{enumerate}', ''), + ('end{enumerate}', ''), + ('begin{description}', ''), + ('end{description}', ''), + ('begin{itemize}', ''), + ('end{itemize}', ''), + ('begin{verbatim}', ''), + ('end{verbatim}', ''), + ('note{', 'NOTE: '), ] @@ -152,7 +151,7 @@ def _rmcmd(s, cmd, left='', right=''): if i == -1: return s nesting = 1 - j = i+len(c)+1 + j = i + len(c) + 1 while j < len(s) and nesting > 0: if s[j] == '{': nesting += 1 @@ -161,7 +160,7 @@ def _rmcmd(s, cmd, left='', right=''): j += 1 j -= 1 # j is position of closing '}' if j < len(s): - s = s[:i] + left + s[i+len(c):j] + right + s[j+1:] + s = s[:i] + left + s[i + len(c):j] + right + s[j + 1:] else: return s @@ -172,16 +171,17 @@ def _rmcmd(s, cmd, left='', right=''): # the above works fine. # -## import re -## def _rmcmd(s, cmd, left='', right=''): -## c = '\\%s{.*}'%cmd -## r = re.compile(c, re.DOTALL) -## while True: -## m = r.search(s) -## if m is None: break -## s = s[:m.start()] + left + s[m.start()+len(cmd)+1:m.end()-1] \ -## + right + s[m.end():] -## return s +# import re +# def _rmcmd(s, cmd, left='', right=''): +# c = '\\%s{.*}'%cmd +# r = re.compile(c, re.DOTALL) +# while True: +# m = r.search(s) +# if m is None: break +# s = s[:m.start()] + left + s[m.start()+len(cmd)+1:m.end()-1] \ +# + right + s[m.end():] +# return s + itempattern = re.compile(r"\\item\[?([^]]*)\]? *(.*)") itemreplace = r"* \1 \2" @@ -236,9 +236,9 @@ def detex(s, embedded=False): s = re.sub(itempattern, itemreplace, s) - for a,b in nonmath_substitutes: - s = s.replace(a,b) - if not embedded: # not in the notebook + for a, b in nonmath_substitutes: + s = s.replace(a, b) + if not embedded: # not in the notebook s = _rmcmd(s, 'mathop') s = _rmcmd(s, 'mathrm') try: @@ -251,10 +251,11 @@ def detex(s, embedded=False): # TeX commands like "\\blah". Do a regular expression # replacement to replace "\\blah" but not "\\blahxyz", etc.: # test to make sure the next character is not a letter. - for a,b in math_substitutes: - s = re.sub(a+'([^a-zA-Z])', b+'\\1', s) + for a, b in math_substitutes: + s = re.sub(a + '([^a-zA-Z])', b + '\\1', s) return s + def skip_TESTS_block(docstring): r""" Remove blocks labeled "TESTS:" from ``docstring``. @@ -395,7 +396,8 @@ def skip_TESTS_block(docstring): s += "\n" s += l previous = l - return s[1:] # Remove empty line from the beginning. + return s[1:] # Remove empty line from the beginning. + def process_dollars(s): r"""nodetex @@ -456,7 +458,7 @@ def process_dollars(s): # find how much leading whitespace s has, for later comparison: # ignore all $ on lines which start with more whitespace. whitespace = re.match(r'\s*\S', s.lstrip('\n')) - whitespace = ' ' * (whitespace.end() - 1) # leading whitespace + whitespace = ' ' * (whitespace.end() - 1) # leading whitespace # Indices will be a list of pairs of positions in s, to search between. # If the following search has no matches, then indices will be (0, len(s)). indices = [0] @@ -482,14 +484,14 @@ def process_dollars(s): # except that this doesn't work, so use the equivalent regular # expression without the 're.X' option. Maybe 'whitespace' gets # eaten up by re.X? - regexp = "^" + "(%s)?"%whitespace + r"(\S.*?)?(?>>') + j = s[i_0 + i + 3:].find('>>>') if j == -1: break - obj = s[i_0+i+3 : i_0+i+3+j] + obj = s[i_0 + i + 3:i_0 + i + 3 + j] if obj in docs: t = '' else: try: - x = eval('sage.all.%s'%obj, locals()) + x = eval('sage.all.%s' % obj, locals()) except AttributeError: # A pair <<<...>>> has been found, but the object not. - i_0 += i+6+j + i_0 += i + 6 + j continue except SyntaxError: # This is a simple heuristics to cover the case of # a non-matching set of <<< and >>> - i_0 += i+3 + i_0 += i + 3 continue t0 = sage.misc.sageinspect.sage_getdef(x, obj) t1 = sage.misc.sageinspect.sage_getdoc(x) t = 'Definition: ' + t0 + '\n\n' + t1 docs.add(obj) - s = s[:i_0+i] + '\n' + t + s[i_0+i+6+j:] + s = s[:i_0 + i] + '\n' + t + s[i_0 + i + 6 + j:] i_0 += i if 'nodetex' not in directives: @@ -764,6 +769,7 @@ def format(s, embedded=False): s = detex(s, embedded=embedded) return s + def format_src(s): """ Format Sage source code ``s`` for viewing with IPython. @@ -796,23 +802,24 @@ def format_src(s): i = s.find("<<<") if i == -1: break - j = s[i+3:].find('>>>') + j = s[i + 3:].find('>>>') if j == -1: break - obj = s[i+3:i+3+j] + obj = s[i + 3:i + 3 + j] if obj in docs: t = '' else: - x = eval('sage.all.%s'%obj, locals()) + x = eval('sage.all.%s' % obj, locals()) t = my_getsource(x) docs.add(obj) if t is None: print(x) t = '' - s = s[:i] + '\n' + t + s[i+6+j:] + s = s[:i] + '\n' + t + s[i + 6 + j:] return s + ############################### def _search_src_or_doc(what, string, extra1='', extra2='', extra3='', @@ -956,7 +963,7 @@ def _search_src_or_doc(what, string, extra1='', extra2='', extra3='', for extra in extra_regexps: if extra: match_list = [s for s in match_list - if re.search(extra, s[1], re.MULTILINE | flags)] + if re.search(extra, s[1], re.MULTILINE | flags)] for num, line in match_list: results.append('{}:{}:{}'.format( filename[strip:].lstrip('/'), num + 1, line)) @@ -967,6 +974,7 @@ def _search_src_or_doc(what, string, extra1='', extra2='', extra3='', return text_results html_results = format_search_as_html(title, results, [string] + extras) + # potentially used below # Pass through the IPython pager in a mime bundle from IPython.core.page import page @@ -975,11 +983,12 @@ def _search_src_or_doc(what, string, extra1='', extra2='', extra3='', page({ 'text/plain': text_results, - # 'text/html': html_results # don't return HTML results since - # they currently are not correctly - # formatted for Jupyter use + # 'text/html': html_results + # don't return HTML results since they currently are not + # correctly formatted for Jupyter use }) + def search_src(string, extra1='', extra2='', extra3='', extra4='', extra5='', **kwds): r""" @@ -1156,6 +1165,7 @@ def search_src(string, extra1='', extra2='', extra3='', extra4='', extra3=extra3, extra4=extra4, extra5=extra5, **kwds) + def search_doc(string, extra1='', extra2='', extra3='', extra4='', extra5='', **kwds): r""" @@ -1197,6 +1207,7 @@ def search_doc(string, extra1='', extra2='', extra3='', extra4='', extra3=extra3, extra4=extra4, extra5=extra5, **kwds) + def search_def(name, extra1='', extra2='', extra3='', extra4='', extra5='', **kwds): r""" @@ -1246,6 +1257,7 @@ def search_def(name, extra1='', extra2='', extra3='', extra4='', extra2=extra2, extra3=extra3, extra4=extra4, extra5=extra5, **kwds) + def format_search_as_html(what, results, search): r""" Format the output from ``search_src``, ``search_def``, or @@ -1326,9 +1338,9 @@ def format_search_as_html(what, results, search): ####################################### -## Add detex'ing of documentation +# Add detex'ing of documentation ####################################### -from . import sageinspect + def my_getsource(obj, oname=''): """ @@ -1359,6 +1371,7 @@ def my_getsource(obj, oname=''): print('Error getting source:', msg) return None + class _sage_doc: """ Open Sage documentation in a web browser, from either the @@ -1518,10 +1531,10 @@ def __call__(self, obj, output='html', view=True): """ - html = template % { 'html': html, - 'static_path': static_path, - 'title': title, - 'version': sage.version.version } + html = template % {'html': html, + 'static_path': static_path, + 'title': title, + 'version': sage.version.version} filed.write(html) filed.close() diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py index 13f0fc1bec3..9add0610149 100644 --- a/src/sage/misc/sageinspect.py +++ b/src/sage/misc/sageinspect.py @@ -886,7 +886,7 @@ def visit_UnaryOp(self, node): def _grep_first_pair_of_parentheses(s): - """ + r""" Return the first matching pair of parentheses in a code string. INPUT: diff --git a/src/sage/misc/superseded.py b/src/sage/misc/superseded.py index eb2ff9c2b27..2bc69b0ffb8 100644 --- a/src/sage/misc/superseded.py +++ b/src/sage/misc/superseded.py @@ -383,7 +383,7 @@ def __init__(self, trac_number, func, module, instance=None, unbound=None): @lazy_attribute def __name__(self): - """ + r""" TESTS:: sage: from sage.misc.superseded import deprecated_function_alias diff --git a/src/sage/misc/viewer.py b/src/sage/misc/viewer.py index 9bdde290365..de84f31ddf4 100644 --- a/src/sage/misc/viewer.py +++ b/src/sage/misc/viewer.py @@ -161,7 +161,7 @@ def _set(self, app=None, TYPE='browser'): - ``app`` -- ``None`` or a string, the program to use - ``TYPE`` -- a string, must be in the list ``VIEWERS`` defined in - :module:`sage.misc.viewer`. Default 'browser'. + :mod:`sage.misc.viewer`. Default 'browser'. EXAMPLES:: diff --git a/src/sage/modular/abvar/abvar.py b/src/sage/modular/abvar/abvar.py index 80467d9b5b0..885b029d938 100644 --- a/src/sage/modular/abvar/abvar.py +++ b/src/sage/modular/abvar/abvar.py @@ -2345,11 +2345,11 @@ def frobenius_polynomial(self, p, var='x'): EXAMPLES:: sage: f = Newform('39b','a') - sage: A=AbelianVariety(f) + sage: A = AbelianVariety(f) sage: A.frobenius_polynomial(5) x^4 + 2*x^2 + 25 - sage: J=J0(23) + sage: J = J0(23) sage: J.frobenius_polynomial(997) x^4 + 20*x^3 + 1374*x^2 + 19940*x + 994009 @@ -2870,28 +2870,31 @@ def _ambient_cuspidal_subgroup(self, rational_only=False, rational_subgroup=Fals def shimura_subgroup(self): r""" - Return the Shimura subgroup of this modular abelian variety. This is - the kernel of `J_0(N) \rightarrow J_1(N)` under the natural map. - Here we compute the Shimura subgroup as the kernel of - `J_0(N) \rightarrow J_0(Np)` where the map is the difference between the - two degeneracy maps. + Return the Shimura subgroup of this modular abelian variety. + + This is the kernel of `J_0(N) \rightarrow J_1(N)` under the + natural map. + + Here we compute the Shimura subgroup as the kernel of `J_0(N) + \rightarrow J_0(Np)` where the map is the difference between + the two degeneracy maps. EXAMPLES:: - sage: J=J0(11) + sage: J = J0(11) sage: J.shimura_subgroup() Finite subgroup with invariants [5] over QQ of Abelian variety J0(11) of dimension 1 - sage: J=J0(17) - sage: G=J.cuspidal_subgroup(); G + sage: J = J0(17) + sage: G = J.cuspidal_subgroup(); G Finite subgroup with invariants [4] over QQ of Abelian variety J0(17) of dimension 1 - sage: S=J.shimura_subgroup(); S + sage: S = J.shimura_subgroup(); S Finite subgroup with invariants [4] over QQ of Abelian variety J0(17) of dimension 1 sage: G.intersection(S) Finite subgroup with invariants [2] over QQ of Abelian variety J0(17) of dimension 1 - sage: J=J0(33) - sage: A=J.decomposition()[0] + sage: J = J0(33) + sage: A = J.decomposition()[0] sage: A.shimura_subgroup() Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33) sage: J.shimura_subgroup() diff --git a/src/sage/modular/btquotients/btquotient.py b/src/sage/modular/btquotients/btquotient.py index f2b1ff39328..7b3fc44316c 100644 --- a/src/sage/modular/btquotients/btquotient.py +++ b/src/sage/modular/btquotients/btquotient.py @@ -2598,7 +2598,7 @@ def get_edge_stabilizers(self): EXAMPLES:: - sage: X=BruhatTitsQuotient(3,2) + sage: X = BruhatTitsQuotient(3,2) sage: s = X.get_edge_stabilizers() sage: len(s) == X.get_num_ordered_edges()/2 True @@ -2632,7 +2632,7 @@ def get_stabilizers(self): EXAMPLES:: - sage: X=BruhatTitsQuotient(3,5) + sage: X = BruhatTitsQuotient(3,5) sage: s = X.get_stabilizers() sage: len(s) == X.get_num_ordered_edges() True diff --git a/src/sage/modular/btquotients/pautomorphicform.py b/src/sage/modular/btquotients/pautomorphicform.py index 10b71899389..540da704d3f 100644 --- a/src/sage/modular/btquotients/pautomorphicform.py +++ b/src/sage/modular/btquotients/pautomorphicform.py @@ -672,7 +672,7 @@ def __classcall__(cls, X, k, prec=None, basis_matrix=None, base_field=None): - ``k`` - integer - The weight. It must be even. - ``prec`` - integer (default: None). If specified, the - precision for the coefficient module + precision for the coefficient module - ``basis_matrix`` - a matrix (default: None). @@ -2223,12 +2223,12 @@ def __classcall__(cls, domain, U, prec=None, t=None, R=None, it automatically from ``prec``, ``U`` and the ``overconvergent`` flag. - ``R`` -- (default : None). If specified, coefficient field of the automorphic forms. - If not specified it defaults to the base ring of the distributions ``U``, or to `Q_p` - with the working precision ``prec``. + If not specified it defaults to the base ring of the distributions ``U``, or to `Q_p` + with the working precision ``prec``. - ``overconvergent`` -- Boolean (default = False). If True, will construct overconvergent - `p`-adic automorphic forms. Otherwise it constructs the finite dimensional space of - `p`-adic automorphic forms which is isomorphic to the space of harmonic cocycles. + `p`-adic automorphic forms. Otherwise it constructs the finite dimensional space of + `p`-adic automorphic forms which is isomorphic to the space of harmonic cocycles. EXAMPLES: @@ -2464,14 +2464,14 @@ def _element_constructor_(self, data): sage: X = BruhatTitsQuotient(13,5) sage: H = X.harmonic_cocycles(2,prec=10) - sage: h=H.an_element() # indirect doctest + sage: h = H.an_element() # indirect doctest sage: A = X.padic_automorphic_forms(2,prec=10) sage: A(h) p-adic automorphic form of cohomological weight 0 """ # Code how to coerce x into the space # Admissible values of x? - if type(data) is list: + if isinstance(data, list): return self.element_class(self, [self._U(o, normalize=False) for o in data]) if isinstance(data, pAdicAutomorphicFormElement): diff --git a/src/sage/modular/cusps.py b/src/sage/modular/cusps.py index 0a40b57294c..b7cd341e800 100644 --- a/src/sage/modular/cusps.py +++ b/src/sage/modular/cusps.py @@ -332,7 +332,7 @@ def numerator(self): EXAMPLES:: - sage: x=Cusp(6,9); x + sage: x = Cusp(6,9); x 2/3 sage: x.numerator() 2 @@ -349,7 +349,7 @@ def denominator(self): EXAMPLES:: - sage: x=Cusp(6,9); x + sage: x = Cusp(6,9); x 2/3 sage: x.denominator() 3 @@ -900,7 +900,7 @@ def galois_action(self, t, N): 1/170 sage: Cusp(oo).galois_action(3, 50) Infinity - sage: c=Cusp(0).galois_action(3, 50); c + sage: c = Cusp(0).galois_action(3, 50); c 50/17 sage: Gamma0(50).reduce_cusp(c) 0 diff --git a/src/sage/modular/dirichlet.py b/src/sage/modular/dirichlet.py index 402edc4fa54..fd6f3c1f7cd 100644 --- a/src/sage/modular/dirichlet.py +++ b/src/sage/modular/dirichlet.py @@ -1637,7 +1637,7 @@ def kloosterman_sum_numerical(self, prec=53, a=1, b=0): The real component of the numerical value of e is near zero:: - sage: v=e.kloosterman_sum_numerical() + sage: v = e.kloosterman_sum_numerical() sage: v.real() < 1.0e15 True sage: v.imag() diff --git a/src/sage/modular/hecke/algebra.py b/src/sage/modular/hecke/algebra.py index e840b306d3e..646f0ecb2cb 100644 --- a/src/sage/modular/hecke/algebra.py +++ b/src/sage/modular/hecke/algebra.py @@ -206,9 +206,9 @@ def __call__(self, x, check=True): - something that can be converted into an element of the underlying matrix space. - In the last case, the parameter ``check'' controls whether or + In the last case, the parameter ``check`` controls whether or not to check that this element really does lie in the - appropriate algebra. At present, setting ``check=True'' raises + appropriate algebra. At present, setting ``check=True`` raises a NotImplementedError unless x is a scalar (or a diagonal matrix). diff --git a/src/sage/modular/hecke/ambient_module.py b/src/sage/modular/hecke/ambient_module.py index e0b0a1772d1..03f1f27da08 100644 --- a/src/sage/modular/hecke/ambient_module.py +++ b/src/sage/modular/hecke/ambient_module.py @@ -198,13 +198,11 @@ def complement(self): EXAMPLES:: - sage: M=ModularSymbols(11,2,1) - sage: M + sage: M = ModularSymbols(11,2,1); M Modular Symbols space of dimension 2 for Gamma_0(11) of weight 2 with sign 1 over Rational Field sage: M.complement() Modular Symbols subspace of dimension 0 of Modular Symbols space of dimension 2 for Gamma_0(11) of weight 2 with sign 1 over Rational Field - sage: C=M.cuspidal_subspace() - sage: C + sage: C = M.cuspidal_subspace(); C Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 2 for Gamma_0(11) of weight 2 with sign 1 over Rational Field sage: C.complement() Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 2 for Gamma_0(11) of weight 2 with sign 1 over Rational Field diff --git a/src/sage/modular/modform/ambient_R.py b/src/sage/modular/modform/ambient_R.py index a99b080062f..29fe271b62e 100644 --- a/src/sage/modular/modform/ambient_R.py +++ b/src/sage/modular/modform/ambient_R.py @@ -22,7 +22,7 @@ def __init__(self, M, base_ring): EXAMPLES:: - sage: M = ModularForms(23,2,base_ring=GF(7)) ## indirect doctest + sage: M = ModularForms(23,2,base_ring=GF(7)) # indirect doctest sage: M Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(23) of weight 2 over Finite Field of size 7 sage: M == loads(dumps(M)) @@ -57,11 +57,11 @@ def modular_symbols(self,sign=0): def _repr_(self): """ - String representation for self. + String representation for ``self``. EXAMPLES:: - sage: M = ModularForms(23,2,base_ring=GF(7)) ## indirect doctest + sage: M = ModularForms(23,2,base_ring=GF(7)) # indirect doctest sage: M._repr_() 'Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(23) of weight 2 over Finite Field of size 7' @@ -73,7 +73,7 @@ def _repr_(self): i = s.find('over') if i != -1: s = s[:i] - return s + 'over %s'%self.base_ring() + return s + 'over %s' % self.base_ring() def _compute_q_expansion_basis(self, prec=None): """ diff --git a/src/sage/modular/modform/cuspidal_submodule.py b/src/sage/modular/modform/cuspidal_submodule.py index fcf3ee51df6..decc402a839 100644 --- a/src/sage/modular/modform/cuspidal_submodule.py +++ b/src/sage/modular/modform/cuspidal_submodule.py @@ -242,7 +242,7 @@ def _compute_hecke_matrix_prime(self, p): EXAMPLES:: - sage: C=CuspForms(38, 2) + sage: C = CuspForms(38, 2) sage: C._compute_hecke_matrix_prime(7) [-1 0 0 0] [ 0 -1 0 0] diff --git a/src/sage/modular/modform/eisenstein_submodule.py b/src/sage/modular/modform/eisenstein_submodule.py index ab041a78fc4..0d606affd6d 100644 --- a/src/sage/modular/modform/eisenstein_submodule.py +++ b/src/sage/modular/modform/eisenstein_submodule.py @@ -11,11 +11,11 @@ from sage.rings.all import CyclotomicField from sage.arith.all import lcm, euler_phi - from . import eis_series from . import element from . import submodule + class EisensteinSubmodule(submodule.ModularFormsSubmodule): """ The Eisenstein submodule of an ambient space of modular forms. @@ -26,7 +26,7 @@ def __init__(self, ambient_space): EXAMPLES:: - sage: E = ModularForms(23,4).eisenstein_subspace() ## indirect doctest + sage: E = ModularForms(23,4).eisenstein_subspace() # indirect doctest sage: E Eisenstein subspace of dimension 2 of Modular Forms space of dimension 7 for Congruence Subgroup Gamma0(23) of weight 4 over Rational Field sage: E == loads(dumps(E)) @@ -44,15 +44,15 @@ def __init__(self, ambient_space): def _repr_(self): """ - Return the string representation of self. + Return the string representation of ``self``. EXAMPLES:: - sage: E = ModularForms(23,4).eisenstein_subspace() ## indirect doctest + sage: E = ModularForms(23,4).eisenstein_subspace() # indirect doctest sage: E._repr_() 'Eisenstein subspace of dimension 2 of Modular Forms space of dimension 7 for Congruence Subgroup Gamma0(23) of weight 4 over Rational Field' """ - return "Eisenstein subspace of dimension %s of %s"%(self.dimension(), self.ambient_module()) + return "Eisenstein subspace of dimension %s of %s" % (self.dimension(), self.ambient_module()) def eisenstein_submodule(self): """ diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index c8dc792e139..90043b2bb12 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -262,7 +262,7 @@ def __eq__(self, other): sage: f = ModularForms(6,4).0 sage: g = ModularForms(23,2).0 - sage: f == g ## indirect doctest + sage: f == g # indirect doctest False sage: f == f True @@ -1668,7 +1668,7 @@ def modsym_eigenspace(self, sign=0): [ 0 1 -1 1 0] sage: V.0 in M.free_module() True - sage: V=N.modsym_eigenspace(-1); V + sage: V = N.modsym_eigenspace(-1); V Vector space of degree 5 and dimension 1 over Rational Field Basis matrix: [ 0 0 0 1 -1/2] @@ -2440,7 +2440,7 @@ def _compute_q_expansion(self, prec): EXAMPLES:: sage: f = EllipticCurve('37a').modular_form() - sage: f.q_expansion() ## indirect doctest + sage: f.q_expansion() # indirect doctest q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + O(q^6) sage: f._compute_q_expansion(10) @@ -2462,7 +2462,7 @@ def _add_(self, other): sage: g 1 + (-14/73*zeta8^3 + 57/73*zeta8^2 + 13/73*zeta8 - 6/73)*q^2 + (-90/73*zeta8^3 + 64/73*zeta8^2 - 52/73*zeta8 + 24/73)*q^3 + (-81/73*zeta8^3 + 189/73*zeta8^2 - 3/73*zeta8 + 153/73)*q^4 + (72/73*zeta8^3 + 124/73*zeta8^2 + 100/73*zeta8 + 156/73)*q^5 + O(q^6) - sage: f+g ## indirect doctest + sage: f+g # indirect doctest 1 + q + (-14/73*zeta8^3 - 16/73*zeta8^2 + 13/73*zeta8 + 140/73)*q^2 + (-90/73*zeta8^3 + 64/73*zeta8^2 + 21/73*zeta8 + 243/73)*q^3 + (-81/73*zeta8^3 + 43/73*zeta8^2 - 3/73*zeta8 + 372/73)*q^4 + (72/73*zeta8^3 + 124/73*zeta8^2 + 27/73*zeta8 + 521/73)*q^5 + O(q^6) """ return ModularFormElement(self.parent(), self.element() + other.element()) @@ -2774,7 +2774,7 @@ def _compute_element(self): """ M = self.parent() S = M.cuspidal_subspace() -## return S.find_in_space( self.__E.q_expansion( S.q_expansion_basis()[0].prec() ) ) + [0] * ( M.dimension() - S.dimension() ) +# return S.find_in_space( self.__E.q_expansion( S.q_expansion_basis()[0].prec() ) ) + [0] * ( M.dimension() - S.dimension() ) return vector(S.find_in_space(self.__E.q_expansion(S.sturm_bound())) + [0] * (M.dimension() - S.dimension())) def _compute_q_expansion(self, prec): @@ -2867,7 +2867,7 @@ def __init__(self, parent, vector, t, chi, psi): EXAMPLES:: - sage: E = EisensteinForms(1,12) ## indirect doctest + sage: E = EisensteinForms(1,12) # indirect doctest sage: E.eisenstein_series() [ 691/65520 + q + 2049*q^2 + 177148*q^3 + 4196353*q^4 + 48828126*q^5 + O(q^6) @@ -2895,7 +2895,6 @@ def __init__(self, parent, vector, t, chi, psi): if chi.parent().base_ring() != K or psi.parent().base_ring() != K: raise ArithmeticError("Incompatible base rings") t = int(t) - #if not isinstance(t, int): raise TypeError, "weight must be an int" if parent.weight() == 2 and chi.is_trivial() \ and psi.is_trivial() and t==1: raise ArithmeticError("If chi and psi are trivial and k=2, then t must be >1.") diff --git a/src/sage/modular/modform/ring.py b/src/sage/modular/modform/ring.py index 67b0b236fbb..db1c76ab382 100644 --- a/src/sage/modular/modform/ring.py +++ b/src/sage/modular/modform/ring.py @@ -202,7 +202,7 @@ def __init__(self, group, base_ring=QQ): - ``base_ring`` (ring, default: `\QQ`) -- a base ring, which should be `\QQ`, `\ZZ`, or the integers mod `p` for some prime `p` - TESTS:: + TESTS: Check that :trac:`15037` is fixed:: diff --git a/src/sage/modular/modform/space.py b/src/sage/modular/modform/space.py index 5674a03e4be..42ed9a9072e 100644 --- a/src/sage/modular/modform/space.py +++ b/src/sage/modular/modform/space.py @@ -1057,9 +1057,9 @@ def _element_constructor_(self, x, check=True): ... TypeError: unable to create modular form from exact non-zero polynomial - sage: E=ModularForms(3,12).cuspidal_subspace() - sage: f=E.gens()[0] - sage: g=f-f + sage: E = ModularForms(3,12).cuspidal_subspace() + sage: f = E.gens()[0] + sage: g = f - f sage: g.is_old() True diff --git a/src/sage/modular/modform_hecketriangle/abstract_ring.py b/src/sage/modular/modform_hecketriangle/abstract_ring.py index ed30e5e7af1..52922f6a1f2 100644 --- a/src/sage/modular/modform_hecketriangle/abstract_ring.py +++ b/src/sage/modular/modform_hecketriangle/abstract_ring.py @@ -52,7 +52,7 @@ def __init__(self, group, base_ring, red_hom, n): - ``group`` -- The Hecke triangle group (default: ``HeckeTriangleGroup(3)``) - - ``base_ring`` -- The base_ring (default: `\Z). + - ``base_ring`` -- The base_ring (default: `\Z`). - ``red_hom`` -- If ``True`` then results of binary operations are considered homogeneous whenever it makes sense (default: ``False``). diff --git a/src/sage/modular/modform_hecketriangle/graded_ring_element.py b/src/sage/modular/modform_hecketriangle/graded_ring_element.py index 48e8c7cc566..233fbc7fa75 100644 --- a/src/sage/modular/modform_hecketriangle/graded_ring_element.py +++ b/src/sage/modular/modform_hecketriangle/graded_ring_element.py @@ -1043,7 +1043,7 @@ def diff_op(self, op, new_parent=None): sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing sage: MR = QuasiMeromorphicModularFormsRing(n=8, red_hom=True) sage: (X,Y,Z,dX,dY,dZ) = MR.diff_alg().gens() - sage: n=MR.hecke_n() + sage: n = MR.hecke_n() sage: mul_op = 4/(n-2)*X*dX + 2*n/(n-2)*Y*dY + 2*Z*dZ sage: der_op = MR._derivative_op() sage: ser_op = MR._serre_derivative_op() @@ -1459,7 +1459,7 @@ def reduce(self, force=False): sage: ModularFormsRing(n=7)(x+1).reduce(force=True).parent() ModularFormsRing(n=7) over Integer Ring - sage: y=var("y") + sage: y = var("y") sage: ModularFormsRing(n=infinity)(x-y^2).reduce(force=True) 64*q - 512*q^2 + 1792*q^3 - 4096*q^4 + O(q^5) """ @@ -1490,7 +1490,7 @@ def reduced_parent(self): sage: el.reduced_parent() ModularFormsRing(n=3) over Integer Ring - sage: y=var("y") + sage: y = var("y") sage: QuasiMeromorphicModularFormsRing(n=infinity)(x-y^2).reduced_parent() ModularForms(n=+Infinity, k=4, ep=1) over Integer Ring sage: QuasiMeromorphicModularFormsRing(n=infinity)(x*(x-y^2)).reduced_parent() diff --git a/src/sage/modular/modsym/ambient.py b/src/sage/modular/modsym/ambient.py index b28de8d9d5e..5022b0fc07e 100644 --- a/src/sage/modular/modsym/ambient.py +++ b/src/sage/modular/modsym/ambient.py @@ -631,13 +631,13 @@ def _modular_symbol_0_to_alpha(self, alpha, i=0): if self.weight() > two: R = ZZ['X'] X = R.gen(0) - ## need to add first two terms, which aren't necessarily - ## zero in this case. we do the first here, and the - ## second in the k=0 case below, so as to avoid code - ## duplication + # need to add first two terms, which aren't necessarily + # zero in this case. we do the first here, and the + # second in the k=0 case below, so as to avoid code + # duplication a += self.manin_symbol((i,0,1), check=False) for k in range(0,len(c)): - ## matrix entries associated to this partial sum + # matrix entries associated to this partial sum if k == 0: x = c[0][0] y = -1 @@ -652,23 +652,23 @@ def _modular_symbol_0_to_alpha(self, alpha, i=0): y = -y w = -w - ## two options here: write out the polynomial directly, - ## and deal with all the separate cases, or create two - ## polynomials and then exponentiate and multiply them. - ## given how fast ntl/flint/etc are, the second may - ## be faster. - - ## method 1: write out solution. this is currently - ## incorrect, because it ends up doing 0^0 in the sum, - ## so I'll fix it and do timings soon. -## for s in range(0,self.weight()-two+1): -## coeff = sum([ binomial(i,t)*binomial(self.weight()-two-i,s-t)* -## x**t * y**(i-t) * z**(s-t) * -## w**(self.weight()-two-i-s+t) for t in range(0,s) ]) -## m = coeff * self.manin_symbol((s, y, w), check=False) -## a += m - - ## method 2 + # two options here: write out the polynomial directly, + # and deal with all the separate cases, or create two + # polynomials and then exponentiate and multiply them. + # given how fast ntl/flint/etc are, the second may + # be faster. + + # method 1: write out solution. this is currently + # incorrect, because it ends up doing 0^0 in the sum, + # so I'll fix it and do timings soon. +# for s in range(0,self.weight()-two+1): +# coeff = sum([ binomial(i,t)*binomial(self.weight()-two-i,s-t)* +# x**t * y**(i-t) * z**(s-t) * +# w**(self.weight()-two-i-s+t) for t in range(0,s) ]) +# m = coeff * self.manin_symbol((s, y, w), check=False) +# a += m + + # method 2 p1 = x*X+y p2 = z*X+w if i == 0: @@ -1406,8 +1406,8 @@ def cuspidal_submodule(self): S = self.boundary_map().kernel() S._set_is_cuspidal(True) S._is_full_hecke_module = True - ## We know the cuspidal subspace is stable, so - ## if it's one-dimensional, it must be simple + # We know the cuspidal subspace is stable, so + # if it's one-dimensional, it must be simple if S.dimension() == 1: S._is_simple = True if self.base_ring().characteristic() == 0: @@ -1682,54 +1682,54 @@ def factorization(self): (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 7 and level 38, weight 2, character [zeta3], sign 1, over Cyclotomic Field of order 3 and degree 2) """ -## EXAMPLES:: - -## sage: M = ModularSymbols(Gamma0(22), 2); M -## Modular Symbols space of dimension 7 for Gamma_0(22) of weight 2 with sign 0 over Rational Field -## sage: M.factorization(): -## ... print b.dimension(), b.level(), e -## 1 11 2 -## 1 11 2 -## 1 11 2 -## 1 22 1 - -## An example with sign 1:: - -## sage: M = ModularSymbols(Gamma0(22), 2, sign=1); M -## Modular Symbols space of dimension 5 for Gamma_0(22) of weight 2 with sign 1 over Rational Field -## sage: for b, e in M.factorization(): -## ... print b.dimension(), b.level(), e -## 1 11 2 -## 1 11 2 -## 1 22 1 - -## An example for Gamma1:: - -## sage: M = ModularSymbols(Gamma1(26), 2, sign=1); M -## Modular Symbols space of dimension 33 for Gamma_1(26) of weight 2 with sign 1 over Rational Field -## sage: for b, e in M.factorization(): -## ... print b.dimension(), b.level(), e -## 1 13 2 -## 1 13 2 -## 1 13 2 -## 2 13 2 -## 2 13 2 -## 2 13 2 -## 2 13 2 -## 2 13 2 -## 1 26 1 -## 1 26 1 -## 1 26 1 -## 2 26 1 -## 2 26 1 - -## An example with level divisible by a square:: - -## sage: M = ModularSymbols(Gamma0(2*9),2); M -## ??? -## sage: for b, e in M.factorization(): -## ... print b.dimension(), b.level(), e -## ??? +# EXAMPLES:: + +# sage: M = ModularSymbols(Gamma0(22), 2); M +# Modular Symbols space of dimension 7 for Gamma_0(22) of weight 2 with sign 0 over Rational Field +# sage: M.factorization(): +# ... print b.dimension(), b.level(), e +# 1 11 2 +# 1 11 2 +# 1 11 2 +# 1 22 1 + +# An example with sign 1:: + +# sage: M = ModularSymbols(Gamma0(22), 2, sign=1); M +# Modular Symbols space of dimension 5 for Gamma_0(22) of weight 2 with sign 1 over Rational Field +# sage: for b, e in M.factorization(): +# ... print b.dimension(), b.level(), e +# 1 11 2 +# 1 11 2 +# 1 22 1 + +# An example for Gamma1:: + +# sage: M = ModularSymbols(Gamma1(26), 2, sign=1); M +# Modular Symbols space of dimension 33 for Gamma_1(26) of weight 2 with sign 1 over Rational Field +# sage: for b, e in M.factorization(): +# ... print b.dimension(), b.level(), e +# 1 13 2 +# 1 13 2 +# 1 13 2 +# 2 13 2 +# 2 13 2 +# 2 13 2 +# 2 13 2 +# 2 13 2 +# 1 26 1 +# 1 26 1 +# 1 26 1 +# 2 26 1 +# 2 26 1 + +# An example with level divisible by a square:: + +# sage: M = ModularSymbols(Gamma0(2*9),2); M +# ??? +# sage: for b, e in M.factorization(): +# ... print b.dimension(), b.level(), e +# ??? try: return self._factorization except AttributeError: @@ -1759,10 +1759,10 @@ def factorization(self): # In the special case of weight 2 we have to do a bunch of # annoying extra work below to deal with the Eisenstein series E_2. - ## If the characteristic of the base ring is 2, - ## the star involution is the identity, so we - ## want to avoid adding each cuspidal submodule - ## twice. + # If the characteristic of the base ring is 2, + # the star involution is the identity, so we + # want to avoid adding each cuspidal submodule + # twice. if self.base_ring().characteristic() == 2: skip_minus = True else: @@ -2007,7 +2007,7 @@ def _compute_sign_submodule(self, sign, compute_dual=True): EXAMPLES:: - sage: ModularSymbols(1,12,0,GF(5)).minus_submodule() ## indirect doctest + sage: ModularSymbols(1,12,0,GF(5)).minus_submodule() # indirect doctest Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Finite Field of size 5 """ S = self.star_involution().matrix() - self.base_ring()(sign) @@ -2048,8 +2048,8 @@ def star_involution(self): return self.__star_involution except AttributeError: pass - S = self.__heilbronn_operator(self, [[-1,0, 0,1]], 1) - S.name("Star involution on %s"%self) + S = self.__heilbronn_operator(self, [[-1, 0, 0, 1]], 1) + S.name("Star involution on %s" % self) self.__star_involution = S return self.__star_involution diff --git a/src/sage/modular/modsym/modsym.py b/src/sage/modular/modsym/modsym.py index 8b98ea11303..a30f53a8a9e 100644 --- a/src/sage/modular/modsym/modsym.py +++ b/src/sage/modular/modsym/modsym.py @@ -167,15 +167,14 @@ def ModularSymbols_clear_cache(): Make sure :trac:`10548` is fixed:: sage: import gc - sage: m=ModularSymbols(Gamma1(29)) - sage: m=[] + sage: m = ModularSymbols(Gamma1(29)) + sage: m = [] sage: ModularSymbols_clear_cache() sage: gc.collect() # random 3422 - sage: a=[x for x in gc.get_objects() if isinstance(x,sage.modular.modsym.ambient.ModularSymbolsAmbient_wtk_g1)] + sage: a = [x for x in gc.get_objects() if isinstance(x,sage.modular.modsym.ambient.ModularSymbolsAmbient_wtk_g1)] sage: a [] - """ global _cache _cache = {} diff --git a/src/sage/modular/modsym/modular_symbols.py b/src/sage/modular/modsym/modular_symbols.py index cd629a3f18d..c832cb8be05 100644 --- a/src/sage/modular/modsym/modular_symbols.py +++ b/src/sage/modular/modsym/modular_symbols.py @@ -292,7 +292,7 @@ def apply(self, g): sage: s = ModularSymbols(11,2).1.modular_symbol_rep()[0][1]; s {-1/8, 0} - sage: a=1;b=2;c=3;d=4; s.apply([a,b,c,d]) + sage: a = 1; b = 2; c = 3; d = 4; s.apply([a,b,c,d]) {15/29, 1/2} sage: x = -1/8; (a*x+b)/(c*x+d) 15/29 @@ -303,12 +303,12 @@ def apply(self, g): sage: s.apply([a,b,c,d]) 16*X^2*{11/21, 1/2} - 16*X*Y*{11/21, 1/2} + 4*Y^2*{11/21, 1/2} sage: P = s.polynomial_part() - sage: X,Y = P.parent().gens() + sage: X, Y = P.parent().gens() sage: P(d*X-b*Y, -c*X+a*Y) 16*X^2 - 16*X*Y + 4*Y^2 - sage: x=-1/6; (a*x+b)/(c*x+d) + sage: x = -1/6; (a*x+b)/(c*x+d) 11/21 - sage: x=0; (a*x+b)/(c*x+d) + sage: x = 0; (a*x+b)/(c*x+d) 1/2 sage: type(s.apply([a,b,c,d])) diff --git a/src/sage/modular/modsym/p1list.pyx b/src/sage/modular/modsym/p1list.pyx index 05ef4951f8c..880462748cf 100644 --- a/src/sage/modular/modsym/p1list.pyx +++ b/src/sage/modular/modsym/p1list.pyx @@ -515,10 +515,9 @@ def p1list(N): sage: from sage.modular.modsym.p1list import p1list sage: list(p1list(7)) [(0, 1), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6)] - sage: N=23456 + sage: N = 23456 sage: len(p1list(N)) == N*prod([1+1/p for p,e in N.factor()]) True - """ if N <= 0: raise ValueError("N must be a positive integer") @@ -526,8 +525,8 @@ def p1list(N): return p1list_int(N) if N <= 2147483647: return p1list_llong(N) - else: - raise OverflowError("p1list not defined for such large N.") + raise OverflowError("p1list not defined for such large N") + def p1_normalize(int N, int u, int v): r""" @@ -1231,8 +1230,7 @@ def lift_to_sl2z_int(int c, int d, int N): sage: from sage.modular.modsym.p1list import lift_to_sl2z_int sage: lift_to_sl2z_int(2,6,11) [1, 8, 2, 17] - sage: m=Matrix(Integers(),2,2,lift_to_sl2z_int(2,6,11)) - sage: m + sage: m = Matrix(Integers(),2,2,lift_to_sl2z_int(2,6,11)); m [ 1 8] [ 2 17] @@ -1282,6 +1280,7 @@ def lift_to_sl2z_int(int c, int d, int N): return [z2, -z1, c, d] + def lift_to_sl2z_llong(llong c, llong d, int N): r""" Lift a pair `(c, d)` (modulo `N`) to an element of `SL(2, \ZZ)`. @@ -1301,8 +1300,7 @@ def lift_to_sl2z_llong(llong c, llong d, int N): sage: from sage.modular.modsym.p1list import lift_to_sl2z_llong sage: lift_to_sl2z_llong(2,6,11) [1, 8, 2, 17] - sage: m=Matrix(Integers(),2,2,lift_to_sl2z_llong(2,6,11)) - sage: m + sage: m = Matrix(Integers(),2,2,lift_to_sl2z_llong(2,6,11)); m [ 1 8] [ 2 17] diff --git a/src/sage/modular/modsym/space.py b/src/sage/modular/modsym/space.py index 4d818262a1c..cd9ed42cf91 100644 --- a/src/sage/modular/modsym/space.py +++ b/src/sage/modular/modsym/space.py @@ -449,8 +449,7 @@ def is_simple(self): Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(33) of weight 2 with sign 1 over Rational Field, Modular Symbols subspace of dimension 3 of Modular Symbols space of dimension 6 for Gamma_0(33) of weight 2 with sign 1 over Rational Field ] - sage: C=ModularSymbols(1,14,0,GF(5)).cuspidal_submodule() - sage: C + sage: C = ModularSymbols(1,14,0,GF(5)).cuspidal_submodule(); C Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 2 for Gamma_0(1) of weight 14 with sign 0 over Finite Field of size 5 sage: C.is_simple() True diff --git a/src/sage/modular/overconvergent/genus0.py b/src/sage/modular/overconvergent/genus0.py index 8c5f36fa933..5031d38377c 100644 --- a/src/sage/modular/overconvergent/genus0.py +++ b/src/sage/modular/overconvergent/genus0.py @@ -687,7 +687,7 @@ def _element_constructor_(self, input): sage: M = OverconvergentModularForms(3, 0, 1/2, prec=5) sage: R. = QQ[[]] - sage: f=M(q + q^2 - q^3 + O(q^16)); f + sage: f = M(q + q^2 - q^3 + O(q^16)); f 3-adic overconvergent modular form of weight-character 0 with q-expansion q + q^2 - q^3 + O(q^5) sage: M.coordinate_vector(f) (0, 1/27, -11/729, 173/19683, -3172/531441) @@ -1535,11 +1535,11 @@ def is_integral(self): def _repr_(self): r""" - String representation of self. + String representation of ``self``. EXAMPLES:: - sage: o=OverconvergentModularForms(3, 0, 1/2) + sage: o = OverconvergentModularForms(3, 0, 1/2) sage: o([1, 0, 1, 3])._repr_() '3-adic overconvergent modular form of weight-character 0 with q-expansion 1 + 729*q^2 + 76545*q^3 + O(q^4)' """ @@ -1565,7 +1565,7 @@ def r_ord(self, r): EXAMPLES:: - sage: o=OverconvergentModularForms(3, 0, 1/2) + sage: o = OverconvergentModularForms(3, 0, 1/2) sage: t = o([1, 1, 1/3]) sage: t.r_ord(1/2) 1 @@ -1610,8 +1610,8 @@ def governing_term(self, r): EXAMPLES:: - sage: o=OverconvergentModularForms(3, 0, 1/2) - sage: f=o.eigenfunctions(10)[1] + sage: o = OverconvergentModularForms(3, 0, 1/2) + sage: f = o.eigenfunctions(10)[1] sage: f.governing_term(1/2) 1 """ @@ -1635,8 +1635,8 @@ def valuation_plot(self, rmax = None): EXAMPLES:: - sage: o=OverconvergentModularForms(3, 0, 1/2) - sage: f=o.eigenfunctions(4)[1] + sage: o = OverconvergentModularForms(3, 0, 1/2) + sage: f = o.eigenfunctions(4)[1] sage: f.valuation_plot() Graphics object consisting of 1 graphics primitive """ diff --git a/src/sage/modular/pollack_stevens/modsym.py b/src/sage/modular/pollack_stevens/modsym.py index 7c71fd24a13..1b6b2164b1a 100644 --- a/src/sage/modular/pollack_stevens/modsym.py +++ b/src/sage/modular/pollack_stevens/modsym.py @@ -1283,7 +1283,7 @@ def _lift_to_OMS(self, p, M, new_base_ring, algorithm = 'greenberg'): OUTPUT: - An overconvergent modular symbol whose specialization - equals self up to some Eisenstein error. + equals self up to some Eisenstein error. EXAMPLES:: diff --git a/src/sage/modular/pollack_stevens/sigma0.py b/src/sage/modular/pollack_stevens/sigma0.py index fa2f4ac7d81..88d86a7a06b 100644 --- a/src/sage/modular/pollack_stevens/sigma0.py +++ b/src/sage/modular/pollack_stevens/sigma0.py @@ -9,6 +9,7 @@ Over `\QQ` or `\ZZ`, it is the monoid of matrices `2\times2` matrices `\begin{pmatrix} a & b \\ c & d \end{pmatrix}` such that + - `ad - bc \ne 0`, - `a` is integral and invertible at the primes dividing `N`, - `c` has valuation at least `v_p(N)` for each `p` dividing `N` (but may be diff --git a/src/sage/modules/fp_graded/free_morphism.py b/src/sage/modules/fp_graded/free_morphism.py index ab1bd91015b..8044fb3883b 100755 --- a/src/sage/modules/fp_graded/free_morphism.py +++ b/src/sage/modules/fp_graded/free_morphism.py @@ -55,7 +55,7 @@ class FreeGradedModuleMorphism(FPModuleMorphism): Defn: b[4] |--> (Sq(0,2)+Sq(3,1)+Sq(6))*d[2] b[5] |--> (Sq(1,2)+Sq(7))*d[2] + (Sq(0,2)+Sq(3,1)+Sq(6))*d[3] - TESTS:: + TESTS: A non-example because the degree is not well-defined:: diff --git a/src/sage/modules/fp_graded/morphism.py b/src/sage/modules/fp_graded/morphism.py index 816425c8aea..0417bd72347 100755 --- a/src/sage/modules/fp_graded/morphism.py +++ b/src/sage/modules/fp_graded/morphism.py @@ -1689,7 +1689,7 @@ def _resolve_kernel(self, top_dim=None, verbose=False): # 1) `j` be a homomorphism into `\ker(self)`, and # 2) 'n' be an integer. # - # The induction loop starts each iteration assuming that that `j` is onto + # The induction loop starts each iteration assuming that `j` is onto # the kernel in degrees below `n`. Each iteration of the loop then # extends the map `j` minimally so that `j_n` becomes onto the kernel. # @@ -1821,7 +1821,7 @@ def _resolve_image(self, top_dim=None, verbose=False): # 1) `j` be a homomorphism into `\im(self)`, and # 2) 'n' be an integer. # - # The induction loop starts each iteration assuming that that `j` is onto + # The induction loop starts each iteration assuming that `j` is onto # the image in degrees below `n`. Each iteration of the loop then # extends the map `j` minimally so that `j_n` becomes onto the image. # diff --git a/src/sage/modules/fp_graded/steenrod/morphism.py b/src/sage/modules/fp_graded/steenrod/morphism.py index d55b51faf4a..595db1a33aa 100755 --- a/src/sage/modules/fp_graded/steenrod/morphism.py +++ b/src/sage/modules/fp_graded/steenrod/morphism.py @@ -280,7 +280,7 @@ def _resolve_kernel(self, top_dim=None, verbose=False): OUTPUT: A homomorphism `j: F \rightarrow D` where `D` is the domain of this homomorphism, `F` is free and such that `\ker(self) = \operatorname{im}(j)`. - TESTS: + TESTS:: sage: from sage.modules.fp_graded.steenrod.module import SteenrodFPModule sage: A = SteenrodAlgebra(2) @@ -328,7 +328,7 @@ def _resolve_image(self, top_dim=None, verbose=False): of this homomorphism, `F` is free, and `\operatorname{im}(self) = \operatorname{im}(j)`. - TESTS: + TESTS:: sage: from sage.modules.fp_graded.steenrod.module import SteenrodFPModule sage: A = SteenrodAlgebra(2) @@ -348,7 +348,7 @@ def _action(self, method, *args, **kwds): Changes the ground ring to a finite algebra, acts by the given method and changes back into the original ground ring before returning. - TESTS: + TESTS:: sage: from sage.modules.fp_graded.steenrod.module import SteenrodFPModule sage: from sage.modules.fp_graded.morphism import FPModuleMorphism diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 628ffb636c8..deb966b9e7f 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -5321,7 +5321,7 @@ def echelonized_basis_matrix(self): def _echelon_matrix_richcmp(self, other, op): r""" - Compare the free module ``self`` with ``other`. + Compare the free module ``self`` with ``other``. This compares modules by their ambient spaces, then by dimension, then in order by their echelon matrices. However, if diff --git a/src/sage/modules/quotient_module.py b/src/sage/modules/quotient_module.py index fbb370a018c..f7aa99210a1 100644 --- a/src/sage/modules/quotient_module.py +++ b/src/sage/modules/quotient_module.py @@ -155,7 +155,7 @@ def _coerce_map_from_(self, M): """ Return a coercion map from `M` to ``self``, or ``None``. - TESTS: + TESTS:: sage: S. = PolynomialRing(QQ) sage: M = S**2 diff --git a/src/sage/modules/vector_space_homspace.py b/src/sage/modules/vector_space_homspace.py index 75727ba261d..13004ea14ce 100644 --- a/src/sage/modules/vector_space_homspace.py +++ b/src/sage/modules/vector_space_homspace.py @@ -249,14 +249,17 @@ def __call__(self, A, check=True, **kwds): - ``A`` - one of several possible inputs representing a morphism from this vector space homspace. + - a vector space morphism in this homspace - a matrix representation relative to the bases of the vector spaces, which acts on a vector placed to the left of the matrix - a list or tuple containing images of the domain's basis vectors - a function from the domain to the codomain + - ``check`` (default: True) - ``True`` or ``False``, required for compatibility with calls from :meth:`sage.structure.parent.Parent.hom`. + - the keyword ``side`` can be assigned the values ``"left"`` or ``"right"``. It corresponds to the side of vectors relative to the matrix. diff --git a/src/sage/numerical/gauss_legendre.pyx b/src/sage/numerical/gauss_legendre.pyx index 347a47a61d4..175513687df 100644 --- a/src/sage/numerical/gauss_legendre.pyx +++ b/src/sage/numerical/gauss_legendre.pyx @@ -301,7 +301,7 @@ def integrate_vector_N(f, prec, N=3): .. NOTE:: The nodes and weights are calculated in the real field with ``prec`` - bits of precision. If the the vector space in which ``f`` takes values + bits of precision. If the vector space in which ``f`` takes values is over a field which is incompatible with this field (e.g. a finite field) then a TypeError occurs. """ diff --git a/src/sage/parallel/decorate.py b/src/sage/parallel/decorate.py index bde55df0df4..c14518af570 100644 --- a/src/sage/parallel/decorate.py +++ b/src/sage/parallel/decorate.py @@ -232,7 +232,7 @@ def _sage_argspec_(self): """ Returns the argument specification for this object, which is just the argument specification for the underlying function. - See :module:`sage.misc.sageinspect` for more information on + See :mod:`sage.misc.sageinspect` for more information on this convention. EXAMPLES:: @@ -252,7 +252,7 @@ def _sage_src_(self): """ Returns the source code for this object, which is just the source code for the underlying function. See - :module:`sage.misc.sageinspect` for more information on this + :mod:`sage.misc.sageinspect` for more information on this convention. EXAMPLES:: @@ -269,10 +269,10 @@ def _sage_src_(self): return sage_getsource(self.func) def _instancedoc_(self): - """ + r""" Returns the docstring for this object, which is just the docstring for the underlying function. See - :module:`sage.misc.sageinspect` for more information on this + :mod:`sage.misc.sageinspect` for more information on this convention. EXAMPLES:: diff --git a/src/sage/plot/graphics.py b/src/sage/plot/graphics.py index b80f61dc3c2..e779e1210e3 100644 --- a/src/sage/plot/graphics.py +++ b/src/sage/plot/graphics.py @@ -1331,6 +1331,7 @@ def _set_scale(self, subplot, scale=None, base=None): only for internal use. INPUT: + - ``subplot`` -- matplotlib Axes instance. - ``scale`` -- the scale of the figure. Values it can take are ``"linear"``, ``"loglog"``, ``"semilogx"``, ``"semilogy"``. See @@ -2482,13 +2483,13 @@ def _get_vmin_vmax(self, vmin, vmax, basev, axes_pad): plot; otherwise the reader may assume that the scale is linear. For internal use only. - We check if this case occurs (for e.g. assuming xmin < xmax): + We check if this case occurs (for e.g. assuming xmin < xmax):: floor(logxmin) ceil(logxmax) ----|---------+----------+----------|----------------------|-- logxmin logxmax - Or if this case occurs (assuming xmin < xmax): + Or if this case occurs (assuming xmin < xmax):: floor(logxmin) floor(logxmax) ceil(logxmax) ----|---------+---------------------|-----+----------------|-- diff --git a/src/sage/plot/plot.py b/src/sage/plot/plot.py index ba571ef5f92..95735332b72 100644 --- a/src/sage/plot/plot.py +++ b/src/sage/plot/plot.py @@ -2064,7 +2064,7 @@ def _plot(funcs, xrange, parametric=False, OUTPUT: a ``Graphics`` object - EXAMPLES:: + EXAMPLES: See :func:`plot` for many, many implicit examples. Here is an explicit one:: @@ -2106,8 +2106,6 @@ def _plot(funcs, xrange, parametric=False, sage: q2 Graphics object consisting of 2 graphics primitives - :: - Make sure that we don't get multiple legend labels for plot segments (:trac:`11998`):: diff --git a/src/sage/plot/plot3d/list_plot3d.py b/src/sage/plot/plot3d/list_plot3d.py index 4c04f5f99ef..417b9a3528a 100644 --- a/src/sage/plot/plot3d/list_plot3d.py +++ b/src/sage/plot/plot3d/list_plot3d.py @@ -506,6 +506,7 @@ def list_plot3d_tuples(v, interpolation_type, **kwds): pi = float(pi) m = matrix(RDF, 6, [sin(i**2 + j**2) for i in np.linspace(0,pi,6) for j in np.linspace(0,pi,6)]) sphinx_plot(list_plot3d(m, color='yellow', interpolation_type='spline', frame_aspect_ratio=[1, 1, 1/3])) + :: sage: show(list_plot3d([[1, 1, 1], [1, 2, 1], [0, 1, 3], [1, 0, 4]], point_list=True)) diff --git a/src/sage/plot/streamline_plot.py b/src/sage/plot/streamline_plot.py index 615390ebb8c..8e34bcc297b 100644 --- a/src/sage/plot/streamline_plot.py +++ b/src/sage/plot/streamline_plot.py @@ -108,7 +108,7 @@ def _repr_(self): sage: P[0] StreamlinePlot defined by a 20 x 20 vector grid - TESTS: + TESTS:: sage: x, y = var('x y') sage: P = streamline_plot((sin(x), cos(y)), (x,-3,3), (y,-3,3), wrong_option='nonsense') diff --git a/src/sage/quadratic_forms/genera/genus.py b/src/sage/quadratic_forms/genera/genus.py index a3e6fd7c9e5..6cc57b8688c 100644 --- a/src/sage/quadratic_forms/genera/genus.py +++ b/src/sage/quadratic_forms/genera/genus.py @@ -1612,7 +1612,7 @@ def automorphous_numbers(self): for r in I: # We need to consider all pairs in I # since at most 2 elements are part of a pair - # we need need at most 2 of each type + # we need at most 2 of each type if I.count(r) > 2: I.remove(r) # products of all pairs @@ -1650,7 +1650,7 @@ def automorphous_numbers(self): L = I + II # We need to consider all pairs in L # since at most 2 elements are part of a pair - # we need need at most 2 of each type + # we need at most 2 of each type for r in L: # remove triplicates if L.count(r) > 2: L.remove(r) diff --git a/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py b/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py index 4ca4a0d0910..bce9d38ed3f 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py +++ b/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py @@ -210,7 +210,7 @@ def __init__(self, Q): def __repr__(self): - """ + r""" Print the local conditions. INPUT: diff --git a/src/sage/quivers/paths.pyx b/src/sage/quivers/paths.pyx index c31701d4348..6fb990f8821 100644 --- a/src/sage/quivers/paths.pyx +++ b/src/sage/quivers/paths.pyx @@ -1,7 +1,6 @@ """ Quiver Paths """ - # **************************************************************************** # Copyright (C) 2012 Jim Stark # 2013/14 Simon King @@ -26,6 +25,7 @@ from cpython.slice cimport PySlice_GetIndicesEx from sage.structure.richcmp cimport rich_to_bool from sage.data_structures.bitset_base cimport * + cdef class QuiverPath(MonoidElement): r""" Class for paths in a quiver. @@ -116,7 +116,6 @@ cdef class QuiverPath(MonoidElement): sage: from sage.quivers.paths import QuiverPath sage: Q = DiGraph({1:{2:['a']}, 2:{3:['b']}}).path_semigroup() sage: p = Q(['a']) * Q(['b']) # indirect doctest - """ cdef QuiverPath out = QuiverPath.__new__(self._parent.element_class) out._parent = self._parent @@ -174,7 +173,6 @@ cdef class QuiverPath(MonoidElement): True sage: loads(dumps(p)) is p False - """ return NewQuiverPath, (self._parent, self._start, self._end, biseq_pickle(self._path)) @@ -189,12 +187,11 @@ cdef class QuiverPath(MonoidElement): sage: q = Q([(1, 1)]) sage: {p:1, q:2}[Q(['a','b'])] # indirect doctest 1 - """ - if self._path.length==0: + if self._path.length == 0: return hash(self._start) cdef Py_hash_t h = self._start*(1073807360) + biseq_hash(self._path) - if h==-1: + if h == -1: return -2 return h ## bitset_hash is not a good hash either @@ -418,29 +415,29 @@ cdef class QuiverPath(MonoidElement): PySlice_GetIndicesEx(index, self._path.length, &start, &stop, &step, &slicelength) - if step!=1 and step!=-1: + if step != 1 and step != -1: raise ValueError("slicing only possible for step +/-1") - if step==-1: + if step == -1: return self.reversal()[self._path.length-1-start:self._path.length-1-stop] - if start==0 and stop==self._path.length: + if start == 0 and stop == self._path.length: return self - if start>stop: + if start > stop: stop=start E = self._parent._sorted_edges if start < self._path.length: init = E[biseq_getitem(self._path, start)][0] else: init = self._end - if start=self._path.length: + if index < 0 or index >= self._path.length: raise IndexError("list index out of range") E = self._parent._sorted_edges init = E[biseq_getitem(self._path, index)][0] @@ -537,7 +534,7 @@ cdef class QuiverPath(MonoidElement): # Handle trivial case if self._start != right._start: return None - if right._path.length==0: + if right._path.length == 0: return self # If other is the beginning, return the rest @@ -563,7 +560,7 @@ cdef class QuiverPath(MonoidElement): OUTPUT: - - :class:`QuiverPath`s ``(C1,G,C2)`` such that ``self==C1*G`` and ``P=G*C2``, or + - :class:`QuiverPath`s ``(C1,G,C2)`` such that ``self = C1*G`` and ``P = G*C2``, or - ``(None, None, None)``, if the paths do not overlap (or belong to different quivers). EXAMPLES:: @@ -612,7 +609,7 @@ cdef class QuiverPath(MonoidElement): cpdef tuple complement(self, QuiverPath subpath): """ - Return a pair ``(a,b)`` of paths s.t. ``self==a*subpath*b``, + Return a pair ``(a,b)`` of paths s.t. ``self = a*subpath*b``, or ``(None, None)`` if ``subpath`` is not a subpath of this path. .. NOTE:: @@ -672,7 +669,7 @@ cdef class QuiverPath(MonoidElement): cdef size_t max_i, bitsize if self._path.length < subpath._path.length: return 0 - if biseq_contains(self._path, subpath._path, 0)==-1: + if biseq_contains(self._path, subpath._path, 0) == -1: return 0 return 1 @@ -707,7 +704,7 @@ cdef class QuiverPath(MonoidElement): raise ValueError("the two paths belong to different quivers") if self._start != subpath._start: return 0 - if subpath._path.length==0: + if subpath._path.length == 0: return 1 if biseq_startswith(self._path, subpath._path): return 1 @@ -769,7 +766,7 @@ cdef class QuiverPath(MonoidElement): """ Q = self._parent.reverse() # Handle trivial paths - if self._path.length==0: + if self._path.length == 0: return Q.element_class(Q, self._end, self._start, []) # Reverse all the edges in the path, then reverse the path diff --git a/src/sage/repl/rich_output/backend_emacs.py b/src/sage/repl/rich_output/backend_emacs.py index 820682a046c..c1c54a27ea6 100644 --- a/src/sage/repl/rich_output/backend_emacs.py +++ b/src/sage/repl/rich_output/backend_emacs.py @@ -78,7 +78,7 @@ def default_preferences(self): return DisplayPreferences() def displayhook(self, plain_text, rich_output): - """ + r""" Backend implementation of the displayhook INPUT: diff --git a/src/sage/rings/asymptotic/term_monoid.py b/src/sage/rings/asymptotic/term_monoid.py index 53dfbc621a1..36b3d2e4f33 100644 --- a/src/sage/rings/asymptotic/term_monoid.py +++ b/src/sage/rings/asymptotic/term_monoid.py @@ -1916,7 +1916,7 @@ def _validate_growth_or_error_(self, kwds_construction): - ``kwds_construction`` -- a dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and - :meth:`TermWithCoefficient.construction`) + :meth:`TermWithCoefficient.construction`) OUTPUT: @@ -1976,7 +1976,7 @@ def _validate_coefficient_or_error_(self, kwds_construction): - ``kwds_construction`` -- a dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and - :meth:`TermWithCoefficient.construction`) + :meth:`TermWithCoefficient.construction`) OUTPUT: @@ -2068,7 +2068,7 @@ def _convert_construction_(self, kwds_construction): - ``kwds_construction`` -- a dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and - :meth:`TermWithCoefficient.construction`) + :meth:`TermWithCoefficient.construction`) OUTPUT: @@ -2991,7 +2991,7 @@ def _convert_construction_(self, kwds_construction): - ``kwds_construction`` -- a dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and - :meth:`TermWithCoefficient.construction`) + :meth:`TermWithCoefficient.construction`) OUTPUT: @@ -3588,7 +3588,7 @@ def _validate_coefficient_or_error_(self, kwds_construction): - ``kwds_construction`` -- a dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and - :meth:`TermWithCoefficient.construction`) + :meth:`TermWithCoefficient.construction`) OUTPUT: @@ -3676,7 +3676,7 @@ def _convert_construction_(self, kwds_construction): - ``kwds_construction`` -- a dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and - :meth:`TermWithCoefficient.construction`) + :meth:`TermWithCoefficient.construction`) OUTPUT: @@ -4453,7 +4453,7 @@ def _convert_construction_(self, kwds_construction): - ``kwds_construction`` -- a dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and - :meth:`TermWithCoefficient.construction`) + :meth:`TermWithCoefficient.construction`) OUTPUT: @@ -4995,7 +4995,7 @@ def _convert_construction_(self, kwds_construction): - ``kwds_construction`` -- a dictionary representing the keyword arguments of a term in its construction (see also :meth:`GenericTerm.construction` and - :meth:`TermWithCoefficient.construction`) + :meth:`TermWithCoefficient.construction`) OUTPUT: diff --git a/src/sage/rings/complex_arb.pyx b/src/sage/rings/complex_arb.pyx index 60571c5f9cd..0ea3defd0a4 100644 --- a/src/sage/rings/complex_arb.pyx +++ b/src/sage/rings/complex_arb.pyx @@ -351,7 +351,7 @@ class ComplexBallField(UniqueRepresentation, sage.rings.abc.ComplexBallField): sage: ComplexBallField(53) is ComplexBallField() True """ - return super(ComplexBallField, cls).__classcall__(cls, precision) + return super().__classcall__(cls, precision) def __init__(self, long precision=53): r""" diff --git a/src/sage/rings/complex_interval_field.py b/src/sage/rings/complex_interval_field.py index effc3b60648..f5a4693c98a 100644 --- a/src/sage/rings/complex_interval_field.py +++ b/src/sage/rings/complex_interval_field.py @@ -12,7 +12,7 @@ - Carl Witty (2007-10-24): rewrite for intervals -- Niles Johnson (2010-08): :Trac:`3893`: ``random_element()`` +- Niles Johnson (2010-08): :trac:`3893`: ``random_element()`` should pass on ``*args`` and ``**kwds``. - Travis Scrimshaw (2012-10-18): Added documentation to get full coverage. @@ -360,7 +360,7 @@ def real_field(self): """ return RealIntervalField(self._prec) - # For compatibility with with other complex number implementations + # For compatibility with other complex number implementations # such as CC. _real_field = real_field diff --git a/src/sage/rings/continued_fraction.py b/src/sage/rings/continued_fraction.py index a0cc3bba82a..f4c10b009ad 100644 --- a/src/sage/rings/continued_fraction.py +++ b/src/sage/rings/continued_fraction.py @@ -1673,7 +1673,7 @@ def _latex_(self): + \frac{\displaystyle 1}{\displaystyle \dots}}}}}}}}}} """ if self._x2[0] is not Infinity: - return super(ContinuedFraction_periodic, self)._latex_() + return super()._latex_() v = self._x1 if len(v) == 0: return '0' diff --git a/src/sage/rings/derivation.py b/src/sage/rings/derivation.py index 8ac75e718d9..11d8a76d3a8 100644 --- a/src/sage/rings/derivation.py +++ b/src/sage/rings/derivation.py @@ -487,7 +487,7 @@ def _coerce_map_from_(self, R): return True except (AttributeError, NotImplementedError): pass - return super(RingDerivationModule, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) def _repr_(self): """ diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index 5c3d7492c7a..ffad0442389 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -523,7 +523,7 @@ cdef class FiniteField(Field): from sage.rings.finite_rings.homset import FiniteFieldHomset if category.is_subcategory(FiniteFields()): return FiniteFieldHomset(self, codomain, category) - return super(FiniteField, self)._Hom_(codomain, category) + return super()._Hom_(codomain, category) def _squarefree_decomposition_univariate_polynomial(self, f): """ diff --git a/src/sage/rings/finite_rings/finite_field_givaro.py b/src/sage/rings/finite_rings/finite_field_givaro.py index dbeddd8705e..6b34b7e66be 100644 --- a/src/sage/rings/finite_rings/finite_field_givaro.py +++ b/src/sage/rings/finite_rings/finite_field_givaro.py @@ -205,7 +205,7 @@ def _repr_option(self, key): """ if key == 'element_is_atomic': return self._cache.repr != 0 # 0 means repr='poly' - return super(FiniteField_givaro, self)._repr_option(key) + return super()._repr_option(key) def random_element(self, *args, **kwds): """ diff --git a/src/sage/rings/finite_rings/hom_finite_field.pyx b/src/sage/rings/finite_rings/hom_finite_field.pyx index 62f42e6a451..81c7620d42d 100644 --- a/src/sage/rings/finite_rings/hom_finite_field.pyx +++ b/src/sage/rings/finite_rings/hom_finite_field.pyx @@ -271,7 +271,7 @@ cdef class FiniteFieldHomomorphism_generic(RingHomomorphism_im_gens): To: Finite Field in z2 of size 2^2 Defn: 1 |--> 1 """ - cdef FiniteFieldHomomorphism_generic out = super(FiniteFieldHomomorphism_generic, self).__copy__() + cdef FiniteFieldHomomorphism_generic out = super().__copy__() out._section_class = self._section_class return out diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index 40eb6413ff4..12c3c71c5ba 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -195,7 +195,7 @@ class IntegerModFactory(UniqueFactory): """ def get_object(self, version, key, extra_args): - out = super(IntegerModFactory, self).get_object(version, key, extra_args) + out = super().get_object(version, key, extra_args) category = extra_args.get('category', None) if category is not None: out._refine_category_(category) diff --git a/src/sage/rings/fraction_field.py b/src/sage/rings/fraction_field.py index eba5c22d8bf..7edef3616bc 100644 --- a/src/sage/rings/fraction_field.py +++ b/src/sage/rings/fraction_field.py @@ -1063,7 +1063,7 @@ def _coerce_map_from_(self, R): from sage.rings.function_field.maps import FunctionFieldToFractionField return parent.__make_element_class__(FunctionFieldToFractionField)(parent) - return super(FractionField_1poly_field, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) class FractionFieldEmbedding(DefaultConvertMap_unique): diff --git a/src/sage/rings/function_field/place.py b/src/sage/rings/function_field/place.py index 190d0329efc..a05d9ae3fae 100644 --- a/src/sage/rings/function_field/place.py +++ b/src/sage/rings/function_field/place.py @@ -941,7 +941,7 @@ def _residue_field(self, name=None): def to_V(e): """ - An example to show the idea: Suppose that + An example to show the idea: Suppose that:: [x 0 0] M = [0 1 0] and v = (x^10, x^7 + x^3, x^7 + x^4 + x^3 + 1) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index a4399439015..4138e095cca 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -6024,7 +6024,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): TESTS:: sage: n = 10^10000000 - sage: m = n.__pari__() ## crash from trac 875 + sage: m = n.__pari__() # crash from trac 875 sage: m % 1234567 1041334 diff --git a/src/sage/rings/integer_ring.pyx b/src/sage/rings/integer_ring.pyx index ad1c0f74aad..709e9ead4c3 100644 --- a/src/sage/rings/integer_ring.pyx +++ b/src/sage/rings/integer_ring.pyx @@ -865,7 +865,7 @@ cdef class IntegerRing_class(PrincipalIdealDomain): """ if key == 'element_is_atomic': return True - return super(IntegerRing_class, self)._repr_option(key) + return super()._repr_option(key) def is_field(self, proof = True): """ diff --git a/src/sage/rings/invariants/invariant_theory.py b/src/sage/rings/invariants/invariant_theory.py index c37af37cc7c..bb249b60560 100644 --- a/src/sage/rings/invariants/invariant_theory.py +++ b/src/sage/rings/invariants/invariant_theory.py @@ -541,7 +541,7 @@ def __init__(self, n, d, polynomial, *args, **kwds): str(n-1)+' variables, got '+str(variables)) ring = polynomial.parent() homogeneous = variables[-1] is not None - super(AlgebraicForm, self).__init__(n, homogeneous, ring, variables) + super().__init__(n, homogeneous, ring, variables) self._check() def _check(self): @@ -989,8 +989,7 @@ def __init__(self, n, d, polynomial, *args): Ternary quadratic with coefficients (1, 1, 0, 0, 0, 0) """ assert d == 2 - super(QuadraticForm, self).__init__(n, 2, polynomial, *args) - + super().__init__(n, 2, polynomial, *args) @classmethod def from_invariants(cls, discriminant, x, z, *args, **kwargs): @@ -1363,11 +1362,10 @@ def __init__(self, n, d, polynomial, *args): Binary quartic with coefficients (1, 0, 0, 0, 1) """ assert n == 2 and d == 4 - super(BinaryQuartic, self).__init__(2, 4, polynomial, *args) + super().__init__(2, 4, polynomial, *args) self._x = self._variables[0] self._y = self._variables[1] - @cached_method def monomials(self): """ @@ -1689,7 +1687,7 @@ def __init__(self, n, d, polynomial, *args): Binary quintic with coefficients (0, 3, 0, 2, 0, 1) """ assert n == 2 and d == 5 - super(BinaryQuintic, self).__init__(2, 5, polynomial, *args) + super().__init__(2, 5, polynomial, *args) self._x = self._variables[0] self._y = self._variables[1] @@ -2587,12 +2585,11 @@ def __init__(self, n, d, polynomial, *args): Ternary quadratic with coefficients (1, 1, 1, 0, 0, 0) """ assert n == 3 and d == 2 - super(QuadraticForm, self).__init__(3, 2, polynomial, *args) + super().__init__(3, 2, polynomial, *args) self._x = self._variables[0] self._y = self._variables[1] self._z = self._variables[2] - @cached_method def monomials(self): """ @@ -2765,12 +2762,11 @@ def __init__(self, n, d, polynomial, *args): sage: cubic._check_covariant('J_covariant') """ assert n == d == 3 - super(TernaryCubic, self).__init__(3, 3, polynomial, *args) + super().__init__(3, 3, polynomial, *args) self._x = self._variables[0] self._y = self._variables[1] self._z = self._variables[2] - @cached_method def monomials(self): """ @@ -3170,7 +3166,7 @@ def __init__(self, forms): """ forms = tuple(forms) f = forms[0] - super(SeveralAlgebraicForms, self).__init__(f._n, f._homogeneous, f._ring, f._variables) + super().__init__(f._n, f._homogeneous, f._ring, f._variables) s = set(f._variables) if not all(set(f._variables) == s for f in forms): raise ValueError('all forms must be in the same variables') diff --git a/src/sage/rings/localization.py b/src/sage/rings/localization.py index 3ffe60192e6..829485d7cee 100644 --- a/src/sage/rings/localization.py +++ b/src/sage/rings/localization.py @@ -1018,4 +1018,4 @@ def is_field(self, proof=True): return False except NotImplementedError: pass - return super(Localization, self).is_field(proof=proof) + return super().is_field(proof=proof) diff --git a/src/sage/rings/multi_power_series_ring.py b/src/sage/rings/multi_power_series_ring.py index c6a6a0893d1..7f0d5d1bfb8 100644 --- a/src/sage/rings/multi_power_series_ring.py +++ b/src/sage/rings/multi_power_series_ring.py @@ -296,9 +296,9 @@ def __classcall__(cls, base_ring, num_gens, name_list, True """ - order = TermOrder(order,num_gens) - return super(MPowerSeriesRing_generic,cls).__classcall__(cls, base_ring, num_gens, name_list, - order, default_prec, sparse) + order = TermOrder(order, num_gens) + return super().__classcall__(cls, base_ring, num_gens, name_list, + order, default_prec, sparse) def __init__(self, base_ring, num_gens, name_list, order='negdeglex', default_prec=10, sparse=False): diff --git a/src/sage/rings/number_field/bdd_height.py b/src/sage/rings/number_field/bdd_height.py index 39ab3ceca09..7e863142524 100644 --- a/src/sage/rings/number_field/bdd_height.py +++ b/src/sage/rings/number_field/bdd_height.py @@ -454,14 +454,14 @@ def rational_in(x, y): def delta_approximation(x, delta): r""" - Compute a rational number in range (x-delta, x+delta) + Compute a rational number in range `(x-delta, x+delta)` """ return rational_in(x - delta, x + delta) def vector_delta_approximation(v, delta): r""" - Compute a rational vector w=(w1, ..., wn) - such that |vi-wi| = NumberField(x) + sage: K([1]).parent() + Number Field in a with defining polynomial x """ if isinstance(x, number_field_element.NumberFieldElement): K = x.parent() @@ -1820,10 +1826,7 @@ def _element_constructor_(self, x, check=True): if len(x) != self.relative_degree(): raise ValueError("Length must be equal to the degree of this number field") base = self.base_ring() - result = base(x[0]) - for i in range(1, self.relative_degree()): - result += base(x[i])*self.gen(0)**i - return result + return sum(base(c) * g for c, g in zip(x, self.gen(0).powers(len(x)))) return self._convert_non_number_field_element(x) def _convert_non_number_field_element(self, x): @@ -4207,7 +4210,7 @@ def _pari_absolute_structure(self): - ``beta`` is the image of `x \bmod g` under the inverse isomorphism `\phi^{-1}\colon K[x]/(g) \to K[x]/(f)` - EXAMPLES:: + EXAMPLES: If `f` is monic and integral, the result satisfies ``g = f`` and ``alpha = beta = x``:: @@ -8918,7 +8921,7 @@ def free_module(self, base=None, basis=None, map=True): if base is None: base = QQ elif base is self: - return super(NumberField_absolute, self).free_module(base=base, basis=basis, map=map) + return super().free_module(base=base, basis=basis, map=map) if basis is not None or base is not QQ: raise NotImplementedError V = QQ**self.degree() @@ -11413,7 +11416,7 @@ def embeddings(self, K): v = [] except AttributeError: # zeta not defined - return super(NumberField_cyclotomic, self).embeddings(K) + return super().embeddings(K) else: X = [m for m in range(n) if arith.gcd(m,n) == 1] v = [self.hom([z**i], check=False) for i in X] diff --git a/src/sage/rings/number_field/number_field_rel.py b/src/sage/rings/number_field/number_field_rel.py index 0a022049f02..d33980c4b10 100644 --- a/src/sage/rings/number_field/number_field_rel.py +++ b/src/sage/rings/number_field/number_field_rel.py @@ -933,7 +933,7 @@ def _convert_non_number_field_element(self, x): return self._element_class(self, f(self.gen()).polynomial() ) # Anything else: use the code for generic number fields - return super(NumberField_relative, self)._convert_non_number_field_element(x) + return super()._convert_non_number_field_element(x) def _coerce_map_from_(self, R): """ @@ -1529,7 +1529,7 @@ def _pari_relative_structure(self): - ``beta`` is the image of `x \bmod g` under the inverse isomorphism `\phi^{-1}\colon K[x]/(g) \to K[x]/(f)`. - EXAMPLES:: + EXAMPLES: If the defining polynomials are monic and integral, the result satisfies ``g = f`` and ``alpha = beta = x``:: @@ -2303,27 +2303,26 @@ def order(self, *gens, **kwds): def is_free(self, proof=None): r""" - Determine whether or not `L/K` is free (i.e. if `\mathcal{O}_L` is - a free `\mathcal{O}_K`-module). + Determine whether or not `L/K` is free. + + (i.e. if `\mathcal{O}_L` is a free `\mathcal{O}_K`-module). INPUT: - - ``proof`` -- default: True + - ``proof`` -- default: ``True`` EXAMPLES:: sage: x = polygen(QQ) sage: K. = NumberField(x^2+6) sage: x = polygen(K) - sage: L. = K.extension(x^2 + 3) ## extend by x^2+3 + sage: L. = K.extension(x^2 + 3) # extend by x^2+3 sage: L.is_free() False """ proof = proof_flag(proof) base_bnf = self._pari_base_bnf(proof) - if base_bnf.rnfisfree(self.pari_relative_polynomial()) == 1: - return True - return False + return base_bnf.rnfisfree(self.pari_relative_polynomial()) == 1 def _factor_univariate_polynomial(self, poly, **kwargs): """ diff --git a/src/sage/rings/number_field/order.py b/src/sage/rings/number_field/order.py index 8f4d5349505..0bfeefb1da7 100644 --- a/src/sage/rings/number_field/order.py +++ b/src/sage/rings/number_field/order.py @@ -1727,7 +1727,7 @@ def _assume_maximal(self, is_maximal=True, p=None): Record that this order ``is_maximal`` at the integer prime ``p``. To support the deprecated behavior for - ``is_maximal="non-maximal-non-unique"`, this returns an order. + ``is_maximal="non-maximal-non-unique"``, this returns an order. Typically, the order itself. EXAMPLES:: @@ -2319,7 +2319,7 @@ def _assume_maximal(self, is_maximal=True, p=None): Record that this order ``is_maximal`` at the integer prime ``p``. To support the deprecated behavior for - ``is_maximal="non-maximal-non-unique"`, this returns an order. + ``is_maximal="non-maximal-non-unique"``, this returns an order. Typically, the order itself. EXAMPLES:: diff --git a/src/sage/rings/number_field/selmer_group.py b/src/sage/rings/number_field/selmer_group.py index 77facaaf86a..c534aaa9f66 100644 --- a/src/sage/rings/number_field/selmer_group.py +++ b/src/sage/rings/number_field/selmer_group.py @@ -445,7 +445,7 @@ def pSelmerGroup(K, S, p, proof=None, debug=False): EXAMPLES: - Over `\QQ` the the unit contribution is trivial unless `p=2` and + Over `\QQ` the unit contribution is trivial unless `p=2` and the class group is trivial:: sage: from sage.rings.number_field.selmer_group import pSelmerGroup diff --git a/src/sage/rings/number_field/splitting_field.py b/src/sage/rings/number_field/splitting_field.py index 8818e5d1bad..6dc15cc6bc9 100644 --- a/src/sage/rings/number_field/splitting_field.py +++ b/src/sage/rings/number_field/splitting_field.py @@ -46,10 +46,11 @@ def __init__(self, div, mult): self.degree_divisor = div self.degree_multiple = mult if div == mult: - msg = "degree of splitting field equals %s"%div + msg = "degree of splitting field equals %s" % div else: - msg = "degree of splitting field is a multiple of %s"%div - super(SplittingFieldAbort, self).__init__(msg) + msg = "degree of splitting field is a multiple of %s" % div + super().__init__(msg) + class SplittingData: """ diff --git a/src/sage/rings/padics/lattice_precision.py b/src/sage/rings/padics/lattice_precision.py index a041394d635..6b1386e4121 100644 --- a/src/sage/rings/padics/lattice_precision.py +++ b/src/sage/rings/padics/lattice_precision.py @@ -1306,11 +1306,13 @@ def history(self, compact=True, separate_reduce=False, timings=True, output_type 0.000009s oo~~o~o~ooo~o~ooo~o~ 0.014250s oooooooooooo - The legend is the following:: + The legend is the following: + - the symbol ``o`` represents a tracked element, - the symbol ``~`` represents an element which is marked for deletion. On the history, we see: + - 1st line: twenty new elements were created (this corresponds to the affectation of the list ``L``); - 2nd line: elements at prime positions were marked for deletion @@ -1489,6 +1491,7 @@ def timings(self, action=None): a dictionary Here are the meanings of the keywords above: + - ``add``: time spent in adding new columns to the precision matrix (corresponding to the creation of new elements) - ``mark``: time spent in marking elements for deletion diff --git a/src/sage/rings/padics/padic_extension_leaves.py b/src/sage/rings/padics/padic_extension_leaves.py index 48359ef12ab..14fe737b0a1 100644 --- a/src/sage/rings/padics/padic_extension_leaves.py +++ b/src/sage/rings/padics/padic_extension_leaves.py @@ -226,7 +226,7 @@ def _coerce_map_from_(self, R): from sage.rings.padics.qadic_flint_CA import pAdicCoercion_CA_frac_field return pAdicCoercion_CA_frac_field(R, self) - return super(UnramifiedExtensionFieldCappedRelative, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) class UnramifiedExtensionRingCappedAbsolute(UnramifiedExtensionGeneric, pAdicCappedAbsoluteRingGeneric): diff --git a/src/sage/rings/padics/padic_valuation.py b/src/sage/rings/padics/padic_valuation.py index cc6c6a1e658..830d88a1a3e 100644 --- a/src/sage/rings/padics/padic_valuation.py +++ b/src/sage/rings/padics/padic_valuation.py @@ -810,7 +810,7 @@ def extensions(self, ring): return [pAdicValuation(ring, approximant, approximants) for approximant in approximants] if ring.base_ring() is not ring and self.domain().is_subring(ring.base_ring()): return sum([w.extensions(ring) for w in self.extensions(ring.base_ring())], []) - return super(pAdicValuation_base, self).extensions(ring) + return super().extensions(ring) def restriction(self, ring): r""" diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index 3b2cf903df2..ae56110610d 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -2358,7 +2358,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): if c.parent() is not P.base_ring(): P = P.change_ring(c.parent()) return P({e: c}) - return super(LaurentPolynomial_mpair, self).__invert__() + return super().__invert__() def __pow__(LaurentPolynomial_mpair self, n, m): """ diff --git a/src/sage/rings/polynomial/ore_polynomial_ring.py b/src/sage/rings/polynomial/ore_polynomial_ring.py index 1694eb9289a..0914fcb822b 100644 --- a/src/sage/rings/polynomial/ore_polynomial_ring.py +++ b/src/sage/rings/polynomial/ore_polynomial_ring.py @@ -976,7 +976,7 @@ def random_element(self, degree=(-1, 2), monic=False, *args, **kwds): (3*t^2 + 1)*x^4 + (4*t + 2)*x^3 + (4*t + 1)*x^2 + (t^2 + 3*t + 3)*x + 3*t^2 + 2*t + 2 - TESTS:: + TESTS: If the first tuple element is greater than the second, a ``ValueError`` is raised:: diff --git a/src/sage/rings/polynomial/polynomial_complex_arb.pyx b/src/sage/rings/polynomial/polynomial_complex_arb.pyx index a9296e20e01..ed4617dd951 100644 --- a/src/sage/rings/polynomial/polynomial_complex_arb.pyx +++ b/src/sage/rings/polynomial/polynomial_complex_arb.pyx @@ -880,6 +880,13 @@ cdef class Polynomial_complex_arb(Polynomial): sage: pol(matrix([[1,2],[3,4]])) [6.000000000000000 10.00000000000000] [15.00000000000000 21.00000000000000] + + TESTS:: + + sage: P. = CBF[] + sage: Q. = CBF[] + sage: x(y) + y """ cdef ComplexBall ball cdef Polynomial_complex_arb poly @@ -895,7 +902,7 @@ cdef class Polynomial_complex_arb(Polynomial): sig_off() return ball elif isinstance(point, Polynomial_complex_arb): - poly = self._new() + poly = ( point)._new() sig_on() acb_poly_compose(poly.__poly, self.__poly, ( point).__poly, prec(self)) diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index feb7483f5a7..19d0aa29a68 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -2135,7 +2135,7 @@ def is_injective(self): return True else: return self.domain().modulus().degree() == 0 # domain and codomain are the zero ring - return super(PolynomialQuotientRing_coercion, self).is_injective() + return super().is_injective() def is_surjective(self): r""" @@ -2168,7 +2168,7 @@ def is_surjective(self): return True if self.domain().modulus().change_ring(self.codomain().base_ring()) == self.codomain().modulus(): return constant_map_is_surjective - return super(PolynomialQuotientRing_coercion, self).is_surjective() + return super().is_surjective() def _richcmp_(self, other, op): r""" diff --git a/src/sage/rings/puiseux_series_ring.py b/src/sage/rings/puiseux_series_ring.py index bf7edc8224e..27a91d6a187 100644 --- a/src/sage/rings/puiseux_series_ring.py +++ b/src/sage/rings/puiseux_series_ring.py @@ -78,7 +78,7 @@ def __classcall__(cls, *args, **kwds): else: laurent_series = LaurentSeriesRing(*args, **kwds) - return super(PuiseuxSeriesRing, cls).__classcall__(cls, laurent_series) + return super().__classcall__(cls, laurent_series) def __init__(self, laurent_series): """ diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 72e87d0ff79..7db32272b26 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -1136,7 +1136,7 @@ def _repr_option(self, key): """ if key == 'element_is_atomic': return True - return super(AlgebraicRealField, self)._repr_option(key) + return super()._repr_option(key) # Is there a standard representation for this? def _latex_(self): diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index 90f177f9694..3a085cd4e47 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -959,7 +959,7 @@ def ideal(self, *gens, **kwds): if not isinstance(self.__R, MPolynomialRing_libsingular) and \ (not hasattr(self.__R, '_has_singular') or not self.__R._has_singular): # pass through - return super(QuotientRing_nc, self).ideal(gens, **kwds) + return super().ideal(gens, **kwds) if is_SingularElement(gens): gens = list(gens) elif not isinstance(gens, (list, tuple)): diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 6f29e8bfabd..65efe594ef7 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -1783,7 +1783,7 @@ cdef class Rational(sage.structure.element.FieldElement): ## Deal with finite primes e, m = self.val_unit(p) - if e % 2 == 1: + if e % 2: return False if p == 2: @@ -2145,9 +2145,9 @@ cdef class Rational(sage.structure.element.FieldElement): """ if n == 0: raise ValueError("n cannot be zero") - if n<0: + if n < 0: n = -n - if n%2==0 and self<0: + if not n % 2 and self < 0: return False return self.numerator().nth_root(n, 1)[1]\ and self.denominator().nth_root(n, 1)[1] @@ -2300,7 +2300,7 @@ cdef class Rational(sage.structure.element.FieldElement): """ if n == 0 or n == -1: return self - raise IndexError("index n (=%s) out of range; it must be 0" % n) + raise IndexError(f"index n (={n}) out of range; it must be 0") ################################################################ # Optimized arithmetic @@ -3558,7 +3558,7 @@ cdef class Rational(sage.structure.element.FieldElement): import sage.rings.infinity if self.is_one(): return integer.Integer(1) - elif mpz_cmpabs(mpq_numref(self.value),mpq_denref(self.value))==0: + elif mpz_cmpabs(mpq_numref(self.value),mpq_denref(self.value)) == 0: # if the numerator and the denominator are equal in absolute value, # then the rational number is -1 return integer.Integer(2) @@ -3579,7 +3579,7 @@ cdef class Rational(sage.structure.element.FieldElement): True """ # A rational number is equal to 1 iff its numerator and denominator are equal - return mpz_cmp(mpq_numref(self.value),mpq_denref(self.value))==0 + return mpz_cmp(mpq_numref(self.value),mpq_denref(self.value)) == 0 def is_integral(self): r""" @@ -3671,7 +3671,7 @@ cdef class Rational(sage.structure.element.FieldElement): [1, 2, 4, 5, 8, 10] """ a = self.abs() - if a==1: + if a == 1: return True if S is None: return False diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index 4df45a0cecb..f2fee51b8d5 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -263,7 +263,7 @@ def _repr_option(self, key): """ if key == 'element_is_atomic': return True - return super(RationalField, self)._repr_option(key) + return super()._repr_option(key) def _latex_(self): r""" @@ -460,7 +460,7 @@ def __truediv__(self, I): elif isinstance(I, Ideal_generic) and I.base_ring() is ZZ: return QmodnZ(I.gen()) else: - return super(RationalField, self).__truediv__(I) + return super().__truediv__(I) def range_by_height(self, start, end=None): r""" @@ -1109,7 +1109,7 @@ def polynomial(self): r""" Return a defining polynomial of `\QQ`, as for other number fields. - This is is also aliased to :meth:`self.defining_polynomial()` + This is also aliased to :meth:`self.defining_polynomial()` and :meth:`self.absolute_polynomial()`. EXAMPLES:: diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx index cf395208ff9..4fc1de6cce8 100644 --- a/src/sage/rings/real_arb.pyx +++ b/src/sage/rings/real_arb.pyx @@ -386,7 +386,7 @@ class RealBallField(UniqueRepresentation, sage.rings.abc.RealBallField): sage: RealBallField(53) is RealBallField() is RBF True """ - return super(RealBallField, cls).__classcall__(cls, precision) + return super().__classcall__(cls, precision) def __init__(self, long precision=53): r""" @@ -576,7 +576,7 @@ class RealBallField(UniqueRepresentation, sage.rings.abc.RealBallField): if key == 'element_is_atomic': return True - return super(RealBallField, self)._repr_option(key) + return super()._repr_option(key) def gens(self): r""" diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index 3d995d38226..a1e9f12d46c 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -237,7 +237,7 @@ cdef class RealDoubleField_class(sage.rings.abc.RealDoubleField): """ if key == 'element_is_atomic': return True - return super(RealDoubleField_class, self)._repr_option(key) + return super()._repr_option(key) def __richcmp__(self, x, op): """ diff --git a/src/sage/rings/real_mpfi.pyx b/src/sage/rings/real_mpfi.pyx index 9eada6a2bc0..a9e4b1eed16 100644 --- a/src/sage/rings/real_mpfi.pyx +++ b/src/sage/rings/real_mpfi.pyx @@ -977,7 +977,7 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): """ if key == 'element_is_atomic': return True - return super(RealIntervalField_class, self)._repr_option(key) + return super()._repr_option(key) def characteristic(self): """ diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index 3ea8c1dee1f..c9214785c3c 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -943,7 +943,7 @@ cdef class RealField_class(sage.rings.abc.RealField): """ if key == 'element_is_atomic': return True - return super(RealField_class, self)._repr_option(key) + return super()._repr_option(key) def characteristic(self): """ diff --git a/src/sage/rings/tests.py b/src/sage/rings/tests.py index 4938a3f72e8..56cb05ba256 100644 --- a/src/sage/rings/tests.py +++ b/src/sage/rings/tests.py @@ -310,7 +310,8 @@ def test_random_elements(level=MAX_LEVEL, trials=1): Create random elements of random rings until a crash occurs, in which case an exception is raised. Defaults to running a single trial, but more can be specified. To run tests in an infinite - loop, you could use: + loop, you could use:: + while True: test_random_elements(trials=100, print_seed=True) INPUT: @@ -358,7 +359,8 @@ def test_random_arith(level=MAX_LEVEL, trials=1): Create random elements of random rings and does some arithmetic with them, until a crash occurs, in which case an exception is raised. Defaults to running a single trial, but more can be - specified. To run tests in an infinite loop, you could use: + specified. To run tests in an infinite loop, you could use:: + while True: test_random_arith(trials=100, print_seed=True) INPUT: diff --git a/src/sage/rings/universal_cyclotomic_field.py b/src/sage/rings/universal_cyclotomic_field.py index 2a4e6d39958..2291f0ed393 100644 --- a/src/sage/rings/universal_cyclotomic_field.py +++ b/src/sage/rings/universal_cyclotomic_field.py @@ -1305,7 +1305,7 @@ def __classcall__(cls, names=None): sage: E(3,2) E(3)^2 """ - return super(UniversalCyclotomicField, cls).__classcall__(cls, None) + return super().__classcall__(cls, None) def __init__(self, names=None): r""" diff --git a/src/sage/rings/valuation/augmented_valuation.py b/src/sage/rings/valuation/augmented_valuation.py index fbad8a0a39d..4ede1f1d734 100644 --- a/src/sage/rings/valuation/augmented_valuation.py +++ b/src/sage/rings/valuation/augmented_valuation.py @@ -576,7 +576,7 @@ def extensions(self, ring): ret.append(AugmentedValuation(v, f, mu)) return ret - return super(AugmentedValuation_base, self).extensions(ring) + return super().extensions(ring) def restriction(self, ring): r""" @@ -599,7 +599,7 @@ def restriction(self, ring): from sage.rings.polynomial.polynomial_ring import is_PolynomialRing if is_PolynomialRing(ring): # univariate return base.augmentation(self.phi().change_ring(ring.base_ring()), self._mu) - return super(AugmentedValuation_base, self).restriction(ring) + return super().restriction(ring) def uniformizer(self): r""" @@ -689,7 +689,7 @@ def _ge_(self, other): else: return False - return super(AugmentedValuation_base, self)._ge_(other) + return super()._ge_(other) def is_trivial(self): r""" @@ -724,7 +724,7 @@ def scale(self, scalar): """ if scalar in QQ and scalar > 0 and scalar != 1: return self._base_valuation.scale(scalar).augmentation(self.phi(), scalar * self._mu) - return super(AugmentedValuation_base, self).scale(scalar) + return super().scale(scalar) def _residue_ring_generator_name(self): r""" @@ -820,7 +820,7 @@ def change_domain(self, ring): from sage.rings.polynomial.polynomial_ring import is_PolynomialRing if is_PolynomialRing(ring) and ring.variable_name() == self.domain().variable_name(): return self._base_valuation.change_domain(ring).augmentation(self.phi().change_ring(ring.base_ring()), self._mu, check=False) - return super(AugmentedValuation_base, self).change_domain(ring) + return super().change_domain(ring) class FinalAugmentedValuation(AugmentedValuation_base, FinalInductiveValuation): diff --git a/src/sage/rings/valuation/gauss_valuation.py b/src/sage/rings/valuation/gauss_valuation.py index 2431b5982ad..fce282aa0c7 100644 --- a/src/sage/rings/valuation/gauss_valuation.py +++ b/src/sage/rings/valuation/gauss_valuation.py @@ -528,7 +528,7 @@ def change_domain(self, ring): if is_PolynomialRing(ring) and ring.ngens() == 1: base_valuation = self._base_valuation.change_domain(ring.base_ring()) return GaussValuation(self.domain().change_ring(ring.base_ring()), base_valuation) - return super(GaussValuation_generic, self).change_domain(ring) + return super().change_domain(ring) def extensions(self, ring): r""" @@ -547,7 +547,7 @@ def extensions(self, ring): if is_PolynomialRing(ring) and ring.ngens() == 1: if self.domain().is_subring(ring): return [GaussValuation(ring, w) for w in self._base_valuation.extensions(ring.base_ring())] - return super(GaussValuation_generic, self).extensions(ring) + return super().extensions(ring) def restriction(self, ring): r""" @@ -568,7 +568,7 @@ def restriction(self, ring): if is_PolynomialRing(ring) and ring.ngens() == 1: if ring.base().is_subring(self.domain().base()): return GaussValuation(ring, self._base_valuation.restriction(ring.base())) - return super(GaussValuation_generic, self).restriction(ring) + return super().restriction(ring) def is_gauss_valuation(self): r""" @@ -676,7 +676,7 @@ def _ge_(self, other): return False if other.is_trivial(): return other.is_discrete_valuation() - return super(GaussValuation_generic, self)._ge_(other) + return super()._ge_(other) def scale(self, scalar): r""" @@ -693,7 +693,7 @@ def scale(self, scalar): from sage.rings.rational_field import QQ if scalar in QQ and scalar > 0 and scalar != 1: return GaussValuation(self.domain(), self._base_valuation.scale(scalar)) - return super(GaussValuation_generic, self).scale(scalar) + return super().scale(scalar) def _relative_size(self, f): r""" diff --git a/src/sage/rings/valuation/inductive_valuation.py b/src/sage/rings/valuation/inductive_valuation.py index e98ce1b2573..8cc999d5bbd 100644 --- a/src/sage/rings/valuation/inductive_valuation.py +++ b/src/sage/rings/valuation/inductive_valuation.py @@ -578,7 +578,7 @@ def extensions(self, other): # extend to K[x] and from there to K(x) v = self.extension(self.domain().change_ring(self.domain().base().fraction_field())) return [other.valuation(v)] - return super(FiniteInductiveValuation, self).extensions(other) + return super().extensions(other) class NonFinalInductiveValuation(FiniteInductiveValuation, DiscreteValuation): @@ -1677,7 +1677,7 @@ def change_domain(self, ring): from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing if is_PolynomialQuotientRing(ring) and ring.base() is self.domain() and ring.modulus() == self.phi(): return self.restriction(self.domain().base())._extensions_to_quotient(ring, approximants=[self])[0] - return super(InfiniteInductiveValuation, self).change_domain(ring) + return super().change_domain(ring) def _lift_to_maximal_precision(c): diff --git a/src/sage/rings/valuation/limit_valuation.py b/src/sage/rings/valuation/limit_valuation.py index a64bc844a75..2820c7123a9 100644 --- a/src/sage/rings/valuation/limit_valuation.py +++ b/src/sage/rings/valuation/limit_valuation.py @@ -420,7 +420,7 @@ def extensions(self, ring): # we need to recompute the mac lane approximants over this base # ring because it could split differently pass - return super(MacLaneLimitValuation, self).extensions(ring) + return super().extensions(ring) def lift(self, F): r""" @@ -714,7 +714,7 @@ def _ge_(self, other): return (self._initial_approximation >= other._initial_approximation or self._initial_approximation <= other._initial_approximation) - return super(MacLaneLimitValuation, self)._ge_(other) + return super()._ge_(other) def restriction(self, ring): r""" @@ -733,7 +733,7 @@ def restriction(self, ring): """ if ring.is_subring(self.domain().base()): return self._initial_approximation.restriction(ring) - return super(MacLaneLimitValuation, self).restriction(ring) + return super().restriction(ring) def _weakly_separating_element(self, other): r""" diff --git a/src/sage/rings/valuation/mapped_valuation.py b/src/sage/rings/valuation/mapped_valuation.py index 87799bc9b20..e2ec88ae306 100644 --- a/src/sage/rings/valuation/mapped_valuation.py +++ b/src/sage/rings/valuation/mapped_valuation.py @@ -472,7 +472,7 @@ def restriction(self, ring): """ if ring.is_subring(self._base_valuation.domain().base()): return self._base_valuation.restriction(ring) - return super(FiniteExtensionFromInfiniteValuation, self).restriction(ring) + return super().restriction(ring) def _weakly_separating_element(self, other): r""" @@ -496,7 +496,7 @@ def _weakly_separating_element(self, other): """ if isinstance(other, FiniteExtensionFromInfiniteValuation): return self.domain()(self._base_valuation._weakly_separating_element(other._base_valuation)) - super(FiniteExtensionFromInfiniteValuation, self)._weakly_separating_element(other) + super()._weakly_separating_element(other) def _relative_size(self, x): r""" diff --git a/src/sage/rings/valuation/scaled_valuation.py b/src/sage/rings/valuation/scaled_valuation.py index 214e209ff26..31e06ddb483 100644 --- a/src/sage/rings/valuation/scaled_valuation.py +++ b/src/sage/rings/valuation/scaled_valuation.py @@ -298,7 +298,7 @@ def _ge_(self, other): assert not self.is_trivial() if self._base_valuation <= other: return False - return super(ScaledValuation_generic, self)._ge_(other) + return super()._ge_(other) def _le_(self, other): r""" diff --git a/src/sage/rings/valuation/valuation.py b/src/sage/rings/valuation/valuation.py index 4cbe63fe2f9..33492bd2fa8 100644 --- a/src/sage/rings/valuation/valuation.py +++ b/src/sage/rings/valuation/valuation.py @@ -415,7 +415,7 @@ def mac_lane_approximants(self, G, assume_squarefree=False, require_final_EF=Tru at least that valuation. - ``require_incomparability`` -- a boolean (default: ``False``); - whether to require require the returned valuations to be incomparable + whether to require the returned valuations to be incomparable (with respect to the partial order on valuations defined by comparing them pointwise.) @@ -1013,7 +1013,7 @@ def _ge_(self, other): """ if other.is_trivial(): return other.is_discrete_valuation() - return super(DiscreteValuation, self)._ge_(other) + return super()._ge_(other) class MacLaneApproximantNode(): diff --git a/src/sage/rings/valuation/valuation_space.py b/src/sage/rings/valuation/valuation_space.py index 332fede825d..182e3a80639 100644 --- a/src/sage/rings/valuation/valuation_space.py +++ b/src/sage/rings/valuation/valuation_space.py @@ -146,7 +146,7 @@ def _abstract_element_class(self): """ class_name = "%s._abstract_element_class" % self.__class__.__name__ from sage.structure.dynamic_class import dynamic_class - return dynamic_class(class_name, (super(DiscretePseudoValuationSpace, self)._abstract_element_class, self.__class__.ElementMethods)) + return dynamic_class(class_name, (super()._abstract_element_class, self.__class__.ElementMethods)) def _get_action_(self, S, op, self_on_left): r""" diff --git a/src/sage/rings/valuation/value_group.py b/src/sage/rings/valuation/value_group.py index 4ef2038f70f..ca4ea2ba83b 100644 --- a/src/sage/rings/valuation/value_group.py +++ b/src/sage/rings/valuation/value_group.py @@ -154,9 +154,8 @@ def __classcall__(cls, generator): True """ - generator = QQ.coerce(generator) - generator = generator.abs() - return super(DiscreteValueGroup, cls).__classcall__(cls, generator) + generator = QQ.coerce(generator).abs() + return super().__classcall__(cls, generator) def __init__(self, generator): r""" @@ -476,7 +475,7 @@ def __classcall__(cls, generators): simplified_generators.remove(h) break - return super(DiscreteValueSemigroup, cls).__classcall__(cls, tuple(simplified_generators)) + return super().__classcall__(cls, tuple(simplified_generators)) def __init__(self, generators): r""" diff --git a/src/sage/schemes/elliptic_curves/ell_modular_symbols.py b/src/sage/schemes/elliptic_curves/ell_modular_symbols.py index a9fcd8705e2..72489b121f9 100644 --- a/src/sage/schemes/elliptic_curves/ell_modular_symbols.py +++ b/src/sage/schemes/elliptic_curves/ell_modular_symbols.py @@ -123,8 +123,8 @@ def modular_symbol_space(E, sign, base_ring, bound=None): EXAMPLES:: sage: import sage.schemes.elliptic_curves.ell_modular_symbols - sage: E=EllipticCurve('11a1') - sage: M=sage.schemes.elliptic_curves.ell_modular_symbols.modular_symbol_space(E,-1,GF(37)) + sage: E = EllipticCurve('11a1') + sage: M = sage.schemes.elliptic_curves.ell_modular_symbols.modular_symbol_space(E,-1,GF(37)) sage: M Modular Symbols space of dimension 1 for Gamma_0(11) of weight 2 with sign -1 over Finite Field of size 37 """ @@ -244,15 +244,15 @@ def __init__(self, E, sign, nap=1000): Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: M(0) 1/5 - sage: E=EllipticCurve('11a2') - sage: M=sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolECLIB(E,+1) + sage: E = EllipticCurve('11a2') + sage: M = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolECLIB(E,+1) sage: M(0) 1 This is a rank 1 case with vanishing positive twists:: - sage: E=EllipticCurve('121b1') - sage: M=sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolECLIB(E,+1) + sage: E = EllipticCurve('121b1') + sage: M = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolECLIB(E,+1) sage: M(0) 0 sage: M(1/7) @@ -389,26 +389,26 @@ def __init__(self, E, sign, normalize="L_ratio"): EXAMPLES:: - sage: E=EllipticCurve('11a1') + sage: E = EllipticCurve('11a1') sage: import sage.schemes.elliptic_curves.ell_modular_symbols - sage: M=sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,+1) + sage: M = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,+1) sage: M Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: M(0) 1/5 - sage: E=EllipticCurve('11a2') - sage: M=sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,+1) + sage: E = EllipticCurve('11a2') + sage: M = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,+1) sage: M(0) 1 - sage: M=sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,-1) + sage: M = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,-1) sage: M(1/3) 1/2 This is a rank 1 case with vanishing positive twists. The modular symbol is adjusted by -2:: - sage: E=EllipticCurve('121b1') - sage: M=sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,-1,normalize='L_ratio') + sage: E = EllipticCurve('121b1') + sage: M = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,-1,normalize='L_ratio') sage: M(1/3) 1 sage: M._scaling diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 6b1f1bc1868..7e24738dcf1 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -3567,7 +3567,7 @@ def _generalized_congmod_numbers(self, M, invariant="both"): - ``M`` -- non-negative integer; this function is only ever called on `M > 1`, although the algorithm works fine for the case `M = 1` - - ``invariant`` -- string (default: "both"``); options are: + - ``invariant`` -- string (default: ``"both"``); options are: - "both" -- both modular degree and congruence number at level `MN` are computed diff --git a/src/sage/schemes/elliptic_curves/hom_composite.py b/src/sage/schemes/elliptic_curves/hom_composite.py index 8b5c41356fe..8184e86a7dc 100644 --- a/src/sage/schemes/elliptic_curves/hom_composite.py +++ b/src/sage/schemes/elliptic_curves/hom_composite.py @@ -414,7 +414,7 @@ def _eval(self, P): INPUT: a sequence of 3 coordinates defining a point on ``self`` - OUTPUT: the result of evaluating ``self'' at the given point + OUTPUT: the result of evaluating ``self`` at the given point EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/mod_sym_num.pyx b/src/sage/schemes/elliptic_curves/mod_sym_num.pyx index cff51b53659..dd452869e2e 100644 --- a/src/sage/schemes/elliptic_curves/mod_sym_num.pyx +++ b/src/sage/schemes/elliptic_curves/mod_sym_num.pyx @@ -3109,7 +3109,7 @@ cdef class ModularSymbolNumerical: else: y += m x -= a - # Note: it could still still be non-unitary. + # Note: it could still be non-unitary. # Example: N=36 a=2, m=5 uu = (-y) % N vv = m % N diff --git a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py index 4df16edf3b2..13617317e4b 100644 --- a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py +++ b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py @@ -586,7 +586,7 @@ def _eval(self, P): INPUT: a sequence of 3 coordinates defining a point on ``self`` - OUTPUT: the result of evaluating ``self'' at the given point + OUTPUT: the result of evaluating ``self`` at the given point EXAMPLES:: diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py b/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py index 457d037cc89..c7cdf99a83f 100644 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py @@ -228,7 +228,7 @@ def geometric_endomorphism_algebra_is_field(self, B=200, proof=False): Return whether the geometric endomorphism algebra is a field. This implies that the Jacobian of the curve is geometrically - simple. It is based on Algorithm 4.10 from from [Lom2019]_ + simple. It is based on Algorithm 4.10 from [Lom2019]_ INPUT: diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py b/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py index 287cab4a49f..f7b0a1f67f0 100644 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py @@ -76,13 +76,13 @@ def __call__(self, P): 0. A point P in J = Jac(C), returning P; 1. A point P on the curve C such that J = Jac(C), where C is - an odd degree model, returning [P - oo]; + an odd degree model, returning [P - oo]; 2. A pair of points (P, Q) on the curve C such that J = Jac(C), - returning [P-Q]; + returning [P-Q]; 3. A list of polynomials (a,b) such that `b^2 + h*b - f = 0 mod a`, - returning [(a(x),y-b(x))]. + returning [(a(x),y-b(x))]. EXAMPLES:: diff --git a/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py b/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py index 9240426dafc..b1f10eb1344 100644 --- a/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +++ b/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py @@ -3018,7 +3018,7 @@ def _richcmp_(self, other, op): This does not compare elements by any reduction; it only compares the coefficients. The comparison - should be be done against a normal form or possibly + should be done against a normal form or possibly after some reduction steps. EXAMPLES:: diff --git a/src/sage/structure/global_options.py b/src/sage/structure/global_options.py index 57c3cb74b00..a529d39cd5e 100644 --- a/src/sage/structure/global_options.py +++ b/src/sage/structure/global_options.py @@ -1384,7 +1384,7 @@ def __getstate__(self): def __eq__(self, other): r""" - Two options classes are equal if they return the same :meth:`__getstate__. + Two options classes are equal if they return the same :meth:`__getstate__`. EXAMPLES:: diff --git a/src/sage/structure/sequence.py b/src/sage/structure/sequence.py index 49fa26c7490..6cdaa84e4ef 100644 --- a/src/sage/structure/sequence.py +++ b/src/sage/structure/sequence.py @@ -405,7 +405,7 @@ class Sequence_generic(sage.structure.sage_object.SageObject, list): """ def __init__(self, x, universe=None, check=True, immutable=False, cr=False, cr_str=None, use_sage_types=False): - """ + r""" Create a sequence. EXAMPLES:: @@ -685,7 +685,7 @@ def _latex_(self): return list_latex_function(self) def __str__(self): - """ + r""" EXAMPLES:: sage: s = Sequence([1,2,3], cr=False) diff --git a/src/sage/symbolic/assumptions.py b/src/sage/symbolic/assumptions.py index 522edd5ecd3..706de96005d 100644 --- a/src/sage/symbolic/assumptions.py +++ b/src/sage/symbolic/assumptions.py @@ -939,12 +939,11 @@ def __init__(self, *args, **kwds): EXAMPLES:: sage: forget() - sage: foo=assuming(x>0) + sage: foo = assuming(x>0) sage: foo.Ass (x > 0,) sage: bool(x>-1) False - """ self.replace=kwds.pop("replace",False) self.Ass=args @@ -954,7 +953,7 @@ def __enter__(self): EXAMPLES:: sage: forget() - sage: foo=assuming(x>0) + sage: foo = assuming(x>0) sage: bool(x>-1) False sage: foo.__enter__() @@ -963,7 +962,6 @@ def __enter__(self): sage: foo.__exit__() sage: bool(x>-1) False - """ if self.replace: self.OldAss=assumptions() @@ -975,7 +973,7 @@ def __exit__(self, *args, **kwds): EXAMPLES:: sage: forget() - sage: foo=assuming(x>0) + sage: foo = assuming(x>0) sage: bool(x>-1) False sage: foo.__enter__() @@ -985,7 +983,6 @@ def __exit__(self, *args, **kwds): sage: bool(x>-1) False sage: forget() - """ if self.replace: forget(assumptions()) diff --git a/src/sage/symbolic/benchmark.py b/src/sage/symbolic/benchmark.py index 720b700255f..66d8217e315 100644 --- a/src/sage/symbolic/benchmark.py +++ b/src/sage/symbolic/benchmark.py @@ -32,7 +32,7 @@ Problem R4:: - sage: u=[e,pi,sqrt(2)]; Tuples(u,3).cardinality() + sage: u = [e,pi,sqrt(2)]; Tuples(u,3).cardinality() 27 Problem R5:: @@ -64,7 +64,6 @@ sage: a = [random() + random()*I for w in [0..100]] sage: a.sort() - Problem W3:: sage: acos(cos(x)) @@ -72,26 +71,23 @@ PROBLEM S1:: - sage: _=var('x,y,z') + sage: _ = var('x,y,z') sage: f = (x+y+z+1)^10 sage: g = expand(f*(f+1)) - PROBLEM S2:: - sage: _=var('x,y') + sage: _ = var('x,y') sage: a = expand((x^sin(x) + y^cos(y) - z^(x+y))^100) PROBLEM S3:: - sage: _=var('x,y,z') + sage: _ = var('x,y,z') sage: f = expand((x^y + y^z + z^x)^50) sage: g = f.diff(x) PROBLEM S4:: - w = (sin(x)*cos(x)).series(x,400) - - + sage: w = (sin(x)*cos(x)).series(x,400) """ diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index b8e50e04149..56b8caeeb98 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -122,11 +122,11 @@ Test if comparison bugs from :trac:`6256` are fixed:: Test if :trac:`9947` is fixed:: - sage: r=real_part(1+2*(sqrt(2)+1)*(sqrt(2)-1)); r + sage: r = real_part(1+2*(sqrt(2)+1)*(sqrt(2)-1)); r 2*(sqrt(2) + 1)*(sqrt(2) - 1) + 1 sage: r.expand() 3 - sage: a=(sqrt(4*(sqrt(3) - 5)*(sqrt(3) + 5) + 48) + 4*sqrt(3))/ (sqrt(3) + 5) + sage: a = (sqrt(4*(sqrt(3) - 5)*(sqrt(3) + 5) + 48) + 4*sqrt(3))/ (sqrt(3) + 5) sage: a.real_part() 4*sqrt(3)/(sqrt(3) + 5) sage: a.imag_part() @@ -890,7 +890,7 @@ cdef class Expression(Expression_abc): Check that user-defined functions get the same treatment (:trac:`19194`):: - sage: f=function('f')(x) + sage: f = function('f')(x) sage: f._dbgprinttree() function f ... x (symbol) ... @@ -2127,7 +2127,7 @@ cdef class Expression(Expression_abc): sage: num_vars = 10; max_order=7 sage: X = var(' '.join('x' + str(i) for i in range(num_vars))) sage: f = function('f')(*X) - sage: hashes=set() + sage: hashes = set() sage: for length in range(1,max_order+1): # long time (4s on sage.math, 2012) ....: for s in UnorderedTuples(X, length): ....: deriv = f.diff(*s) @@ -2406,7 +2406,7 @@ cdef class Expression(Expression_abc): sage: forget() sage: n = var('n') - sage: foo=sin((-1)*n*pi) + sage: foo = sin((-1)*n*pi) sage: foo.simplify() -sin(pi*n) sage: assume(n, 'odd') @@ -3590,11 +3590,11 @@ cdef class Expression(Expression_abc): Check that :trac:`18896` is fixed:: - sage: m=540579833922455191419978421211010409605356811833049025*sqrt(1/2) - sage: m1=382247666339265723780973363167714496025733124557617743 - sage: (m==m1).test_relation(domain=QQbar) + sage: m = 540579833922455191419978421211010409605356811833049025*sqrt(1/2) + sage: m1 = 382247666339265723780973363167714496025733124557617743 + sage: (m == m1).test_relation(domain=QQbar) False - sage: (m==m1).test_relation() + sage: (m == m1).test_relation() False Try the examples from :trac:`31424` and :trac:`31665`:: @@ -4467,7 +4467,7 @@ cdef class Expression(Expression_abc): True sage: float((24*sqrt(3))^(100/51)) 1493.0092154... - sage: t=((1/10)*I/pi)^(3/2) + sage: t = ((1/10)*I/pi)^(3/2) sage: t^2 -1/1000*I/pi^3 sage: (2*pi)^QQ(2) @@ -5039,11 +5039,10 @@ cdef class Expression(Expression_abc): Check that ticket :trac:`7472` is fixed (Taylor polynomial in more variables):: - sage: x,y=var('x y'); taylor(x*y^3,(x,1),(y,1),4) + sage: x,y = var('x y'); taylor(x*y^3,(x,1),(y,1),4) (x - 1)*(y - 1)^3 + 3*(x - 1)*(y - 1)^2 + (y - 1)^3 + 3*(x - 1)*(y - 1) + 3*(y - 1)^2 + x + 3*y - 3 sage: expand(_) x*y^3 - """ from sage.rings.integer import Integer from sage.symbolic.ring import SR @@ -5326,8 +5325,8 @@ cdef class Expression(Expression_abc): EXAMPLES:: - sage: y=var('y') - sage: f=sin(x)*cos(x)^3+sin(y)^2 + sage: y = var('y') + sage: f = sin(x)*cos(x)^3+sin(y)^2 sage: f.reduce_trig() -1/2*cos(2*y) + 1/8*sin(4*x) + 1/4*sin(2*x) + 1/2 @@ -7056,14 +7055,14 @@ cdef class Expression(Expression_abc): Series coefficients are now handled correctly (:trac:`17399`):: - sage: s=(1/(1-x)).series(x,6); s + sage: s = (1/(1-x)).series(x,6); s 1 + 1*x + 1*x^2 + 1*x^3 + 1*x^4 + 1*x^5 + Order(x^6) sage: s.coefficients() [[1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [1, 5]] sage: s.coefficients(x, sparse=False) [1, 1, 1, 1, 1, 1] sage: x,y = var("x,y") - sage: s=(1/(1-y*x-x)).series(x,3); s + sage: s = (1/(1-y*x-x)).series(x,3); s 1 + (y + 1)*x + ((y + 1)^2)*x^2 + Order(x^3) sage: s.coefficients(x, sparse=False) [1, y + 1, (y + 1)^2] @@ -7151,7 +7150,7 @@ cdef class Expression(Expression_abc): -2*sqrt(2)*a*x + 2*a^2 + x^2 + x + 1 sage: p.list(a) [x^2 + x + 1, -2*sqrt(2)*x, 2] - sage: s=(1/(1-x)).series(x,6); s + sage: s = (1/(1-x)).series(x,6); s 1 + 1*x + 1*x^2 + 1*x^3 + 1*x^4 + 1*x^5 + Order(x^6) sage: s.list() [1, 1, 1, 1, 1, 1] @@ -7160,7 +7159,7 @@ cdef class Expression(Expression_abc): def leading_coefficient(self, s): """ - Return the leading coefficient of s in self. + Return the leading coefficient of ``s`` in ``self``. EXAMPLES:: @@ -7739,8 +7738,8 @@ cdef class Expression(Expression_abc): Fraction Field of Univariate Polynomial Ring in x over Symbolic Ring sage: parent(((pi+sqrt(2))/x).fraction(SR)) Fraction Field of Univariate Polynomial Ring in x over Symbolic Ring - sage: y=var('y') - sage: fr=((3*x^5 - 5*y^5)^7/(x*y)).fraction(GF(7)); fr + sage: y = var('y') + sage: fr = ((3*x^5 - 5*y^5)^7/(x*y)).fraction(GF(7)); fr (3*x^35 + 2*y^35)/(x*y) sage: parent(fr) Fraction Field of Multivariate Polynomial Ring in x, y over Finite Field of size 7 @@ -10997,12 +10996,11 @@ cdef class Expression(Expression_abc): In some cases we do not want to expand:: - sage: f=tan(3*x) + sage: f = tan(3*x) sage: f.simplify_trig() -(4*cos(x)^2 - 1)*sin(x)/(4*cos(x)*sin(x)^2 - cos(x)) sage: f.simplify_trig(False) sin(3*x)/cos(3*x) - """ # much better to expand first, since it often doesn't work # right otherwise! @@ -11066,7 +11064,7 @@ cdef class Expression(Expression_abc): combine logarithm and the rational function into one fraction:: - sage: f=(x^2-1)/(x+1)-ln(x)/(x+2) + sage: f = (x^2-1)/(x+1)-ln(x)/(x+2) sage: f.simplify_rational() (x^2 + x - log(x) - 2)/(x + 2) sage: f.simplify_rational(map=True) @@ -11086,7 +11084,7 @@ cdef class Expression(Expression_abc): With option ``algorithm='noexpand'`` we only convert to common denominators and add. No expansion of products is performed:: - sage: f=1/(x+1)+x/(x+2)^2 + sage: f = 1/(x+1)+x/(x+2)^2 sage: f.simplify_rational() (2*x^2 + 5*x + 4)/(x^3 + 5*x^2 + 8*x + 4) sage: f.simplify_rational(algorithm='noexpand') @@ -11487,7 +11485,7 @@ cdef class Expression(Expression_abc): EXAMPLES:: - sage: x,y,t=var('x y t') + sage: x,y,t = var('x y t') Only two first terms are contracted in the following example; the logarithm with coefficient `\frac{1}{2}` is not contracted:: @@ -11741,7 +11739,7 @@ cdef class Expression(Expression_abc): sage: var("j,k,p,q", domain="integer") (j, k, p, q) - sage: X,Y,Z,f,g=function("X,Y,Z,f,g") + sage: X,Y,Z,f,g = function("X,Y,Z,f,g") sage: var("x,a,b") (x, a, b) sage: sum(X(j)+Y(j),j,1,p) @@ -12225,7 +12223,7 @@ cdef class Expression(Expression_abc): sage: var('f6,f5,f4,x') (f6, f5, f4, x) - sage: e=15*f6*x^2 + 5*f5*x + f4 + sage: e = 15*f6*x^2 + 5*f5*x + f4 sage: res = e.roots(x); res [(-1/30*(5*f5 + sqrt(25*f5^2 - 60*f4*f6))/f6, 1), (-1/30*(5*f5 - sqrt(25*f5^2 - 60*f4*f6))/f6, 1)] sage: e.subs(x=res[0][0]).is_zero() @@ -12353,7 +12351,7 @@ cdef class Expression(Expression_abc): but you can substitute them with specific integer values:: sage: x,y,z = var('x,y,z') - sage: sol=solve_diophantine(x^2-y==0); sol + sage: sol = solve_diophantine(x^2-y==0); sol (t, t^2) sage: [(sol[0].subs(t=t),sol[1].subs(t=t)) for t in range(-3,4)] [(-3, 9), (-2, 4), (-1, 1), (0, 0), (1, 1), (2, 4), (3, 9)] @@ -13114,7 +13112,7 @@ cdef class Expression(Expression_abc): x^4 + 20*x^3 + 127*x^2 + 288*x + 180 sage: (i^2).prod(i,1,7) 25401600 - sage: f=function('f') + sage: f = function('f') sage: f(i).prod(i,1,7) f(7)*f(6)*f(5)*f(4)*f(3)*f(2)*f(1) sage: f(i).prod(i,1,n) @@ -13453,7 +13451,7 @@ cdef class Expression(Expression_abc): cpdef _repr_Expression(x): r""" - Return the string representation of the eexpression ``x``. + Return the string representation of the expression ``x``. EXAMPLES:: @@ -13668,7 +13666,7 @@ cpdef new_Expression(parent, x): sage: K. = QuadraticField(-3) sage: a + sin(x) I*sqrt(3) + sin(x) - sage: x=var('x'); y0,y1=PolynomialRing(ZZ,2,'y').gens() + sage: x = var('x'); y0,y1 = PolynomialRing(ZZ,2,'y').gens() sage: x+y0/y1 x + y0/y1 sage: x.subs(x=y0/y1) diff --git a/src/sage/symbolic/expression_conversions.py b/src/sage/symbolic/expression_conversions.py index b4952b359fc..e681f480589 100644 --- a/src/sage/symbolic/expression_conversions.py +++ b/src/sage/symbolic/expression_conversions.py @@ -1590,8 +1590,8 @@ def polynomial(ex, base_ring=None, ring=None): sage: _.parent() Multivariate Polynomial Ring in x, y over Rational Field - sage: s,t=var('s,t') - sage: expr=t^2-2*s*t+1 + sage: s,t = var('s,t') + sage: expr = t^2-2*s*t+1 sage: expr.polynomial(None,ring=SR['t']) t^2 - 2*s*t + 1 sage: _.parent() @@ -2108,7 +2108,7 @@ def __init__(self, ex, *args): sage: s(1/foo(foo(x)) + foo(2)) 1/bar(bar(x)) + bar(2) - TESTS:: + TESTS: Check that the old syntax still works:: @@ -2218,7 +2218,7 @@ def __init__(self, ex): EXAMPLES:: sage: from sage.symbolic.expression_conversions import Exponentialize - sage: d=Exponentialize(sin(x)) + sage: d = Exponentialize(sin(x)) sage: d(sin(x)) -1/2*I*e^(I*x) + 1/2*I*e^(-I*x) sage: d(cosh(x)) @@ -2262,7 +2262,7 @@ def __init__(self, ex, force=False): sage: a, b = SR.var("a, b") sage: from sage.symbolic.expression_conversions import DeMoivre - sage: d=DeMoivre(e^a) + sage: d = DeMoivre(e^a) sage: d(e^(a+I*b)) (cos(b) + I*sin(b))*e^a """ diff --git a/src/sage/symbolic/ginac/power.h b/src/sage/symbolic/ginac/power.h index f19bea6fbe4..e47186f4994 100644 --- a/src/sage/symbolic/ginac/power.h +++ b/src/sage/symbolic/ginac/power.h @@ -34,7 +34,7 @@ class numeric; class add; class mul; -/** This class holds a two-component object, a basis and and exponent +/** This class holds a two-component object, a basis and exponent * representing exponentiation. */ class power : public basic { diff --git a/src/sage/symbolic/integration/external.py b/src/sage/symbolic/integration/external.py index 7e91380de60..0760f20920b 100644 --- a/src/sage/symbolic/integration/external.py +++ b/src/sage/symbolic/integration/external.py @@ -94,8 +94,6 @@ def mma_free_integrator(expression, v, a=None, b=None): sage: result.simplify_trig() # optional - internet -1/2*cos(y)*sin(y) + 1/2*y - :: - Check that :trac:`14764` is resolved:: sage: integrate(x^2, x, 0, 1, algorithm="mathematica_free") # optional - internet diff --git a/src/sage/symbolic/operators.py b/src/sage/symbolic/operators.py index 986ad38ad6c..52351f0867b 100644 --- a/src/sage/symbolic/operators.py +++ b/src/sage/symbolic/operators.py @@ -3,13 +3,14 @@ import operator from sage.symbolic.ring import is_SymbolicVariable, SR -def add_vararg(first,*rest): + +def add_vararg(first, *rest): r""" Addition of a variable number of arguments. INPUT: - - ``first``, ``rest`` - arguments to add + - ``first``, ``rest`` -- arguments to add OUTPUT: sum of arguments @@ -18,22 +19,22 @@ def add_vararg(first,*rest): sage: from sage.symbolic.operators import add_vararg sage: add_vararg(1,2,3,4,5,6,7) 28 - sage: F=(1+x+x^2) + sage: F = (1+x+x^2) sage: bool(F.operator()(*F.operands()) == F) True """ - for r in rest: first = first + r return first -def mul_vararg(first,*rest): + +def mul_vararg(first, *rest): r""" Multiplication of a variable number of arguments. INPUT: - - ``args`` - arguments to multiply + - ``args`` -- arguments to multiply OUTPUT: product of arguments @@ -42,15 +43,15 @@ def mul_vararg(first,*rest): sage: from sage.symbolic.operators import mul_vararg sage: mul_vararg(9,8,7,6,5,4) 60480 - sage: G=x*cos(x)*sin(x) + sage: G = x*cos(x)*sin(x) sage: bool(G.operator()(*G.operands())==G) True """ - for r in rest: first = first * r return first + arithmetic_operators = {add_vararg: '+', mul_vararg: '*', operator.add: '+', diff --git a/src/sage/symbolic/relation.py b/src/sage/symbolic/relation.py index 24ded86bdf7..037d22a89f2 100644 --- a/src/sage/symbolic/relation.py +++ b/src/sage/symbolic/relation.py @@ -644,7 +644,7 @@ def solve(f, *args, **kwds): [x == 0, y == 1]] sage: solve([sqrt(x) + sqrt(y) == 5, x + y == 10], x, y) [[x == -5/2*I*sqrt(5) + 5, y == 5/2*I*sqrt(5) + 5], [x == 5/2*I*sqrt(5) + 5, y == -5/2*I*sqrt(5) + 5]] - sage: solutions=solve([x^2+y^2 == 1, y^2 == x^3 + x + 1], x, y, solution_dict=True) + sage: solutions = solve([x^2+y^2 == 1, y^2 == x^3 + x + 1], x, y, solution_dict=True) sage: for solution in solutions: print("{} , {}".format(solution[x].n(digits=3), solution[y].n(digits=3))) -0.500 - 0.866*I , -1.27 + 0.341*I -0.500 - 0.866*I , 1.27 - 0.341*I @@ -779,9 +779,9 @@ def solve(f, *args, **kwds): sage: solve(x^2>8,x) [[x < -2*sqrt(2)], [x > 2*sqrt(2)]] - sage: x,y=var('x,y'); (ln(x)-ln(y)>0).solve(x) + sage: x,y = var('x,y'); (ln(x)-ln(y)>0).solve(x) [[log(x) - log(y) > 0]] - sage: x,y=var('x,y'); (ln(x)>ln(y)).solve(x) # random + sage: x,y = var('x,y'); (ln(x)>ln(y)).solve(x) # random [[0 < y, y < x, 0 < x]] [[y < x, 0 < y]] @@ -871,7 +871,9 @@ def solve(f, *args, **kwds): We use ``use_grobner`` in Maxima if no solution is obtained from Maxima's ``to_poly_solve``:: - sage: x,y=var('x y'); c1(x,y)=(x-5)^2+y^2-16; c2(x,y)=(y-3)^2+x^2-9 + sage: x,y = var('x y') + sage: c1(x,y) = (x-5)^2+y^2-16 + sage: c2(x,y) = (y-3)^2+x^2-9 sage: solve([c1(x,y),c2(x,y)],[x,y]) [[x == -9/68*sqrt(55) + 135/68, y == -15/68*sqrt(55) + 123/68], [x == 9/68*sqrt(55) + 135/68, y == 15/68*sqrt(55) + 123/68]] @@ -1204,7 +1206,7 @@ def _solve_expression(f, x, explicit_solutions, multiplicities, :trac:`7491` fixed:: - sage: y=var('y') + sage: y = var('y') sage: solve(y==y,y) [y == r1] sage: solve(y==y,y,multiplicities=True) @@ -1781,7 +1783,7 @@ def solve_ineq_fourier(ineq, vars=None): EXAMPLES:: sage: from sage.symbolic.relation import solve_ineq_fourier - sage: y=var('y') + sage: y = var('y') sage: solve_ineq_fourier([x+y<9,x-y>4],[x,y]) [[y + 4 < x, x < -y + 9, y < (5/2)]] sage: solve_ineq_fourier([x+y<9,x-y>4],[y,x]) @@ -1879,7 +1881,7 @@ def solve_ineq(ineq, vars=None): System of inequalities with automatically detected inequalities:: - sage: y=var('y') + sage: y = var('y') sage: solve_ineq([x-y<0,x+y-3<0],[y,x]) [[x < y, y < -x + 3, x < (3/2)]] sage: solve_ineq([x-y<0,x+y-3<0],[x,y]) diff --git a/src/sage/symbolic/ring.pyx b/src/sage/symbolic/ring.pyx index 0985a2217fe..bd0b89f9374 100644 --- a/src/sage/symbolic/ring.pyx +++ b/src/sage/symbolic/ring.pyx @@ -257,7 +257,7 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): sage: K. = QuadraticField(-3) sage: a + sin(x) I*sqrt(3) + sin(x) - sage: x=var('x'); y0,y1=PolynomialRing(ZZ,2,'y').gens() + sage: x = var('x'); y0,y1 = PolynomialRing(ZZ,2,'y').gens() sage: x+y0/y1 x + y0/y1 sage: x.subs(x=y0/y1) diff --git a/src/sage/symbolic/series_impl.pxi b/src/sage/symbolic/series_impl.pxi index 2aa2011265c..cb68f8fe893 100644 --- a/src/sage/symbolic/series_impl.pxi +++ b/src/sage/symbolic/series_impl.pxi @@ -194,7 +194,7 @@ cdef class SymbolicSeries(Expression): EXAMPLES:: - sage: s=(1/(1-x)).series(x,3); s + sage: s = (1/(1-x)).series(x,3); s 1 + 1*x + 1*x^2 + Order(x^3) sage: s.default_variable() x @@ -226,18 +226,17 @@ cdef class SymbolicSeries(Expression): EXAMPLES:: - sage: s=(1/(1-x)).series(x,6); s + sage: s = (1/(1-x)).series(x,6); s 1 + 1*x + 1*x^2 + 1*x^3 + 1*x^4 + 1*x^5 + Order(x^6) sage: s.coefficients() [[1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [1, 5]] sage: s.coefficients(x, sparse=False) [1, 1, 1, 1, 1, 1] sage: x,y = var("x,y") - sage: s=(1/(1-y*x-x)).series(x,3); s + sage: s = (1/(1-y*x-x)).series(x,3); s 1 + (y + 1)*x + ((y + 1)^2)*x^2 + Order(x^3) sage: s.coefficients(x, sparse=False) [1, y + 1, (y + 1)^2] - """ if x is None: x = self.default_variable() @@ -259,14 +258,15 @@ cdef class SymbolicSeries(Expression): def power_series(self, base_ring): """ - Return algebraic power series associated to this symbolic - series. The coefficients must be coercible to the base ring. + Return the algebraic power series associated to this symbolic series. + + The coefficients must be coercible to the base ring. EXAMPLES:: - sage: ex=(gamma(1-x)).series(x,3); ex + sage: ex = (gamma(1-x)).series(x,3); ex 1 + euler_gamma*x + (1/2*euler_gamma^2 + 1/12*pi^2)*x^2 + Order(x^3) - sage: g=ex.power_series(SR); g + sage: g = ex.power_series(SR); g 1 + euler_gamma*x + (1/2*euler_gamma^2 + 1/12*pi^2)*x^2 + O(x^3) sage: g.parent() Power Series Ring in x over Symbolic Ring @@ -274,4 +274,3 @@ cdef class SymbolicSeries(Expression): from sage.rings.all import PowerSeriesRing R = PowerSeriesRing(base_ring, names=str(self.default_variable())) return R(self.list(), self.degree(self.default_variable())) - diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index be4e2626ee9..fc6f9c36f71 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -290,6 +290,7 @@ def lattice_paths(t1, t2, length=None): [path + [(t1[-1], t2[-1])] for path in lattice_paths(t1[:-1], t2[:-1], length=length-1)]) + def rename_vertex(n, keep, left=True): """ Rename a vertex: the vertices from the list ``keep`` get @@ -315,7 +316,7 @@ def rename_vertex(n, keep, left=True): sage: rename_vertex(3, [5, 6, 7], left=False) 'R3' """ - lookup = {i:v for v,i in enumerate(keep)} + lookup = {i: v for v, i in enumerate(keep)} try: return lookup[n] except KeyError: @@ -324,6 +325,7 @@ def rename_vertex(n, keep, left=True): else: return "R" + str(n) + @total_ordering class Simplex(SageObject): """ @@ -814,6 +816,7 @@ def _latex_(self): """ return latex(self.__tuple) + class SimplicialComplex(Parent, GenericCellComplex): r""" Define a simplicial complex. @@ -1052,7 +1055,7 @@ def __init__(self, try: normalize_names(1, v) except ValueError: - raise ValueError("the vertex %s does not have an appropriate name"%v) + raise ValueError("the vertex %s does not have an appropriate name" % v) # build dictionary of generator names try: gen_dict[v] = 'x%s' % int(v) @@ -1521,7 +1524,7 @@ def f_triangle(self): EXAMPLES:: sage: X = SimplicialComplex([[1,2,3], [3,4,5], [1,4], [1,5], [2,4], [2,5]]) - sage: X.f_triangle() ## this complex is not pure + sage: X.f_triangle() # this complex is not pure [[0], [0, 0], [0, 0, 4], @@ -1851,7 +1854,7 @@ def cone(self, is_mutable=True): True """ return self.join(SimplicialComplex([["0"]], is_mutable=is_mutable), - rename_vertices = True) + rename_vertices=True) def suspension(self, n=1, is_mutable=True): r""" @@ -1926,7 +1929,7 @@ def suspension(self, n=1, is_mutable=True): return SimplicialComplex(new_facets) else: return self.join(SimplicialComplex([["0"], ["1"]], is_mutable=is_mutable), - rename_vertices = True) + rename_vertices=True) return self.suspension(1, is_mutable).suspension(int(n-1), is_mutable) def disjoint_union(self, right, rename_vertices=True, is_mutable=True): @@ -2230,7 +2233,7 @@ def _homology_(self, dim=None, base_ring=ZZ, subcomplex=None, :type reduced: boolean; optional, default ``True`` :param generators: If ``True``, return the homology groups and - also generators for them. + also generators for them. :type reduced: boolean; optional, default ``False`` @@ -2364,8 +2367,8 @@ def _homology_(self, dim=None, base_ring=ZZ, subcomplex=None, for (H, gen) in H_with_gens: v = gen.vector(i) new_gen = chains.zero() - for (coeff, chain) in zip(v, chains.gens()): - new_gen += coeff * chain + for (coeff, chaine) in zip(v, chains.gens()): + new_gen += coeff * chaine new_H.append((H, new_gen)) answer[i] = new_H @@ -4072,7 +4075,7 @@ def fundamental_group(self, base_point=None, simplify=True): # don't have to worry about it. Convert spanning_tree to a set # to make lookup faster. spanning_tree = set(frozenset((int_to_v[e[0]], int_to_v[e[1]])) - for e in spanning_tree) + for e in spanning_tree) gens_dict = {frozenset(g): i for i, g in enumerate(gens)} FG = FreeGroup(len(gens), 'e') rels = [] @@ -4722,6 +4725,7 @@ def intersection(self, other): F = F + [s for s in self.faces()[k] if s in other.faces()[k]] return SimplicialComplex(F) + # Miscellaneous utility functions. # The following two functions can be used to generate the facets for @@ -4790,4 +4794,4 @@ def facets_for_K3(): G = PermutationGroup([[(1,3,8,4,9,16,15,2,14,12,6,7,13,5,10)], [(1,11,16),(2,10,14),(3,12,13),(4,9,15),(5,7,8)]]) return ([tuple([g(i) for i in (1,2,3,8,12)]) for g in G] - +[tuple([g(i) for i in (1,2,5,8,14)]) for g in G]) + + [tuple([g(i) for i in (1,2,5,8,14)]) for g in G]) diff --git a/src/sage/version.py b/src/sage/version.py index 7fd94a3db6f..d7d504505d1 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '9.7.beta5' -date = '2022-07-10' -banner = 'SageMath version 9.7.beta5, Release Date: 2022-07-10' +version = '9.7.beta6' +date = '2022-07-24' +banner = 'SageMath version 9.7.beta6, Release Date: 2022-07-24' diff --git a/src/tox.ini b/src/tox.ini index 15cc6d181e0..4d46c4f5ff3 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -21,7 +21,7 @@ ## in a virtual environment. ## [tox] -envlist = doctest, coverage, startuptime, pycodestyle-minimal, relint, codespell +envlist = doctest, coverage, startuptime, pycodestyle-minimal, relint, codespell, rst # When adding environments above, also update the delegations in SAGE_ROOT/tox.ini skipsdist = true @@ -94,6 +94,7 @@ description = check against Sage's minimal style conventions # Check for the following issues: # E111: indentation is not a multiple of four + # E306: expected 1 blank line before a nested definition, found 0 # E401: multiple imports on one line # E701: multiple statements on one line (colon) # E702: multiple statements on one line (semicolon) @@ -106,7 +107,7 @@ description = # W605: invalid escape sequence ‘x’ # See https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes deps = pycodestyle -commands = pycodestyle --select E111,E401,E701,E702,E703,W605,E711,E712,E713,E721,E722 {posargs:{toxinidir}/sage/} +commands = pycodestyle --select E111,E306,E401,E701,E702,E703,W605,E711,E712,E713,E721,E722 {posargs:{toxinidir}/sage/} pycodestyle --select E111,E401,E703,E712,E713,E721,E722 --filename *.pyx {posargs:{toxinidir}/sage/} [pycodestyle] @@ -172,6 +173,49 @@ commands = codespell \ --ignore-words={toxinidir}/.codespell-ignore.txt \ {posargs:{toxinidir}/sage/} +[testenv:rst] +description = + validate Python docstrings markup as reStructuredText +deps = flake8-rst-docstrings +commands = flake8 --select=RST {posargs:{toxinidir}/sage/} + +[flake8] +rst-roles = + # Sphinx + doc, + file, + ref, + # Sphinx - https://www.sphinx-doc.org/en/master/usage/restructuredtext/domains.html#the-standard-domain (selection) + envvar, + # Sphinx - https://www.sphinx-doc.org/en/master/usage/restructuredtext/domains.html#cross-referencing-python-objects + attr, + class, + const, + data, + exc, + func, + meth, + mod, + obj, + # from src/sage/misc/sagedoc.py + arxiv, + doi, + mathscinet, + oeis, + pari, + python, + trac, + wikipedia +rst-directives = + automethod, + ONLY, + PLOT, + SEEALSO, + TODO +extend-ignore = + # Ignore RST306 Unknown target name -- because of references to the global bibliography + RST306 + [pytest] python_files = *_test.py norecursedirs = local prefix venv build pkgs .git src/doc src/bin diff --git a/tox.ini b/tox.ini index e445ad45d2d..ff0f1b690b4 100644 --- a/tox.ini +++ b/tox.ini @@ -750,3 +750,11 @@ passenv = {[sage_src]passenv} envdir = {[sage_src]envdir} commands = {[sage_src]commands} whitelist_externals = {[sage_src]whitelist_externals} + +[testenv:rst] +description = + validate Python docstrings markup as reStructuredText +passenv = {[sage_src]passenv} +envdir = {[sage_src]envdir} +commands = {[sage_src]commands} +whitelist_externals = {[sage_src]whitelist_externals}