diff --git a/.github/workflows/doc-build-pdf.yml b/.github/workflows/doc-build-pdf.yml index bfa32760934..7ae675d9e64 100644 --- a/.github/workflows/doc-build-pdf.yml +++ b/.github/workflows/doc-build-pdf.yml @@ -57,7 +57,7 @@ jobs: export PATH="build/bin:$PATH" eval $(sage-print-system-package-command auto update) eval $(sage-print-system-package-command auto --yes --no-install-recommends install zip) - eval $(sage-print-system-package-command auto --spkg --yes --no-install-recommends install git texlive) + eval $(sage-print-system-package-command auto --spkg --yes --no-install-recommends install git texlive texlive_luatex free_fonts xindy) - name: Add prebuilt tree as a worktree id: worktree diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 0c5200dbe81..9d82909ef5f 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -161,7 +161,7 @@ jobs: export PATH="build/bin:$PATH" eval $(sage-print-system-package-command auto update) eval $(sage-print-system-package-command auto --yes --no-install-recommends install zip) - eval $(sage-print-system-package-command auto --spkg --yes --no-install-recommends install git texlive) + eval $(sage-print-system-package-command auto --spkg --yes --no-install-recommends install git texlive texlive_luatex free_fonts xindy) export SAGE_USE_CDNS=yes export SAGE_LIVE_DOC=yes export SAGE_JUPYTER_SERVER=binder:sagemath/sage-binder-env/dev diff --git a/CITATION.cff b/CITATION.cff index cc293723139..a34996764e6 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,8 +4,8 @@ title: SageMath abstract: SageMath is a free open-source mathematics software system. authors: - name: "The SageMath Developers" -version: 10.3.beta3 +version: 10.3.beta4 doi: 10.5281/zenodo.593563 -date-released: 2023-12-18 +date-released: 2023-12-26 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index ed9ec729cc0..f34f97b89ee 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.3.beta3, Release Date: 2023-12-18 +SageMath version 10.3.beta4, Release Date: 2023-12-26 diff --git a/build/bin/sage-dist-helpers b/build/bin/sage-dist-helpers index 9def7350a37..ac588fc297c 100644 --- a/build/bin/sage-dist-helpers +++ b/build/bin/sage-dist-helpers @@ -244,7 +244,7 @@ sdh_pip_install() { # Our default after #33789 (Sage 9.7): We allow the package to provision # its build environment using the stored wheels. # We pass --find-links. - # The SPKG needs to declare "setuptools_wheel" as a dependency. + # The SPKG needs to declare "setuptools" as a dependency. build_isolation_option="--find-links=$SAGE_SPKG_WHEELS" ;; --no-build-isolation) diff --git a/build/bin/sage-get-system-packages b/build/bin/sage-get-system-packages index c8b9314c3fe..1b8aae79c16 100755 --- a/build/bin/sage-get-system-packages +++ b/build/bin/sage-get-system-packages @@ -41,7 +41,7 @@ case "$SYSTEM" in fi fi SYSTEM_PACKAGES_FILE_NAMES="distros/$SYSTEM.txt" - STRIP_COMMENTS="sed s/#.*//;" + STRIP_COMMENTS="sed s/#.*//;s/\${PYTHON_MINOR}/${PYTHON_MINOR}/g" COLLECT=echo ;; esac diff --git a/build/bin/sage-guess-package-system b/build/bin/sage-guess-package-system index 09eafd510c9..8e679c2eac9 100755 --- a/build/bin/sage-guess-package-system +++ b/build/bin/sage-guess-package-system @@ -11,6 +11,8 @@ if conda --version > /dev/null 2>&1; then fi if brew --version > /dev/null 2>&1; then echo homebrew +elif port version > /dev/null 2>&1; then + echo macports elif emerge --version > /dev/null 2>&1; then echo gentoo elif apt-get --version > /dev/null 2>&1; then diff --git a/build/bin/sage-print-system-package-command b/build/bin/sage-print-system-package-command index c36f64e19bf..722a7f75161 100755 --- a/build/bin/sage-print-system-package-command +++ b/build/bin/sage-print-system-package-command @@ -34,6 +34,16 @@ do ;; --prompt) PROMPT=' $ ' + CONTINUATION=' ' + ;; + --continuation=*) + CONTINUATION="${1#--continuation=}" + ;; + --wrap) + WRAP=78 + ;; + --wrap=*) + WRAP="${1#--wrap=}" ;; --no-install-recommends) NO_INSTALL_RECOMMENDS=yes @@ -79,7 +89,13 @@ function print_shell_command() echo ".. CODE-BLOCK:: bash" echo fi - echo "${PROMPT}$1" + # shell-quote arguments if necessary + quoted=$(for a in "$@"; do printf "%q " $a; done) + if [ -z "$WRAP" -o $# -lt 6 ]; then + echo "${PROMPT}${quoted}" + else + sage-bootstrap-python -c "import textwrap; print(' \\\\\n'.join(textwrap.wrap(r'''${quoted}''', $WRAP, initial_indent=r'''${PROMPT}''', subsequent_indent=r'''${CONTINUATION}''', break_long_words=False, break_on_hyphens=False)))" + fi if [ -n "$OUTPUT_RST" ]; then echo fi @@ -102,6 +118,15 @@ case $system:$command in [ -n "$SAGE_ROOT" ] || SAGE_ROOT=. echo "${PROMPT}source $SAGE_ROOT/.homebrew-build-env" ;; + macports*:setup-build-env) + $IF_VERBOSE echo "${COMMENT}" + $IF_VERBOSE echo "${COMMENT}WARNING: Use of MacPorts is experimental" + $IF_VERBOSE echo "${COMMENT}" + $IF_VERBOSE echo "${COMMENT}MacPorts does not provide unversioned gfortran executables by default" + $IF_VERBOSE echo "${COMMENT}To make gfortran available (and build with gcc from XCode), use:" + $IF_VERBOSE echo "${COMMENT}" + $IF_VERBOSE print_shell_command ./configure FC=gfortran-mp-11 + ;; *:setup-build-env) # Nothing needed ;; @@ -109,70 +134,74 @@ case $system:$command in # Verbs handled above are our own inventions. Verbs handled below are apt-get verbs. # @(debian*|ubuntu*):update) - print_shell_command "${SUDO}apt-get $command $system_packages" + print_shell_command ${SUDO}apt-get $command $system_packages ;; @(debian*|ubuntu*):*) [ "$NO_INSTALL_RECOMMENDS" = yes ] && options="$options --no-install-recommends" [ "$YES" = yes ] && options="$options --yes" env="DEBIAN_FRONTEND=noninteractive " - [ -n "$system_packages" ] && print_shell_command "${SUDO}${env}apt-get $command $options $system_packages" + [ -n "$system_packages" ] && print_shell_command ${SUDO}${env}apt-get $command $options $system_packages ;; @(fedora*|redhat*|centos*):install) [ "$YES" = yes ] && options="$options -y" - [ -n "$system_packages" ] && print_shell_command "${SUDO}yum install $options $system_packages" + [ -n "$system_packages" ] && print_shell_command ${SUDO}yum install $options $system_packages ;; gentoo*:install) - [ -n "$system_packages" ] && print_shell_command "${SUDO}emerge $system_packages" + [ -n "$system_packages" ] && print_shell_command ${SUDO}emerge $system_packages ;; arch*:update) print_shell_command "${SUDO}pacman -Sy" ;; arch*:install) [ "$YES" = yes ] && options="$options --noconfirm" - [ -n "$system_packages" ] && print_shell_command "${SUDO}pacman -S $options $system_packages" + [ -n "$system_packages" ] && print_shell_command ${SUDO}pacman -S $options $system_packages ;; void*:update) print_shell_command "${SUDO}xbps-install -Su" ;; void*:install) [ "$YES" = yes ] && options="$options --yes" - [ -n "$system_packages" ] && print_shell_command "${SUDO}xbps-install $options $system_packages" + [ -n "$system_packages" ] && print_shell_command ${SUDO}xbps-install $options $system_packages ;; opensuse*:install) - [ -n "$system_packages" ] && print_shell_command "${SUDO}zypper install $system_packages" + [ -n "$system_packages" ] && print_shell_command ${SUDO}zypper install $system_packages ;; *conda*:install) [ "$YES" = yes ] && options="$options --yes" - [ -n "$system_packages" ] && print_shell_command "conda install $options $system_packages" + [ -n "$system_packages" ] && print_shell_command conda install $options $system_packages ;; homebrew*:install) - [ -n "$system_packages" ] && print_shell_command "brew install $system_packages" + [ -n "$system_packages" ] && print_shell_command brew install $system_packages + ;; + macports*:install) + [ "$YES" = yes ] && options="$options -N" + [ -n "$system_packages" ] && print_shell_command ${SUDO}port $options install $system_packages ;; slackware*:install) - [ -n "$system_packages" ] && print_shell_command "${SUDO}slackpkg install $system_packages" + [ -n "$system_packages" ] && print_shell_command ${SUDO}slackpkg install $system_packages ;; cygwin*:update) print_comment "first install apt-cyg from https://github.com/transcode-open/apt-cyg" ;; cygwin*:install) - [ -n "$system_packages" ] && print_shell_command "apt-cyg install $system_packages" + [ -n "$system_packages" ] && print_shell_command apt-cyg install $system_packages ;; freebsd*:install) - [ -n "$system_packages" ] && print_shell_command "${SUDO}pkg install $system_packages" + [ -n "$system_packages" ] && print_shell_command ${SUDO}pkg install $system_packages ;; nix*:install) - [ -n "$system_packages" ] && print_shell_command "nix-env --install $system_packages" + [ -n "$system_packages" ] && print_shell_command nix-env --install $system_packages ;; alpine:update) print_shell_command "apk update" ;; alpine:install) - [ -n "$system_packages" ] && print_shell_command "apk add $system_packages" + [ -n "$system_packages" ] && print_shell_command apk add $system_packages ;; pip:install) - [ -n "$system_packages" ] && print_shell_command "sage -pip install $system_packages" + [ -n "$system_packages" ] && print_shell_command sage -pip install $system_packages ;; cpan:install) - [ -n "$system_packages" ] && print_shell_command "cpan -i $system_packages" + [ -n "$system_packages" ] && print_shell_command cpan -i $system_packages ;; repology:install) if [ -n "$system_packages" ]; then diff --git a/build/bin/sage-spkg b/build/bin/sage-spkg index 70256370549..e2a151b4adc 100755 --- a/build/bin/sage-spkg +++ b/build/bin/sage-spkg @@ -509,7 +509,9 @@ else # just copy to dist/ and create a simple install script. mkdir -p dist cp "$PKG_SRC" dist/ - echo "sdh_store_and_pip_install_wheel ." > spkg-install.in + if [ ! -f spkg-install.in ]; then + echo "sdh_store_and_pip_install_wheel ." > spkg-install.in + fi ;; *) # Source tarball diff --git a/build/bin/sage-spkg-info b/build/bin/sage-spkg-info index e43e516dc5b..6b66e584331 100755 --- a/build/bin/sage-spkg-info +++ b/build/bin/sage-spkg-info @@ -5,11 +5,26 @@ # # Assumes SAGE_ROOT is set PKG_BASE=$1 +if [ -n "$OUTPUT_DIR" ]; then + exec > "$OUTPUT_DIR"/$PKG_BASE.rst +fi +if [ -n "$OUTPUT_RST" ]; then + echo ".. _spkg_$PKG_BASE:" + echo + ref () { echo ":ref:\`$1\`"; } + issue () { echo ":issue:\`$1\`"; } + code () { echo "\`\`$*\`\`"; } +else + ref () { echo "$1"; } + issue () { echo "https://github.com/sagemath/sage/issues/$1"; } + code () { echo "$1"; } +fi PKG_SCRIPTS="$SAGE_ROOT/build/pkgs/$PKG_BASE" for ext in rst txt; do SPKG_FILE="$PKG_SCRIPTS/SPKG.$ext" if [ -f "$SPKG_FILE" ]; then - sed "1,3s/^ *Sage: Open Source Mathematics Software:/$PKG_BASE:/" "$SPKG_FILE" + # for sphinx 4.4 we need to replace all direct links by some "extlink" (issue 33272) + sed -e "1,3s/^ *Sage: Open Source Mathematics Software:/$PKG_BASE:/" -e "s|https://github.com/sagemath/sage/issues/\([0-9]*\)|:issue:\`\1\`|g" -e "s|https://arxiv.org/abs/cs/\([0-9]*\)|:arxiv:\`cs/\1\`|g" "$SPKG_FILE" break fi done @@ -39,9 +54,9 @@ for dep_file in dependencies dependencies_order_only; do # Dependencies like $(BLAS) \$\(*) echo "- $dep";; # Looks like a package - *) if [ -n "$OUTPUT_RST" -a -r "$SAGE_ROOT/build/pkgs/$dep/SPKG.rst" ]; then + *) if [ -r "$SAGE_ROOT/build/pkgs/$dep/SPKG.rst" ]; then # This RST label is set in src/doc/bootstrap - echo "- :ref:\`spkg_$dep\`" + echo "- $(ref spkg_$dep)" else echo "- $dep" fi;; @@ -103,7 +118,7 @@ for system in $systems; do echo "$system:" ;; esac - sage-print-system-package-command $system --prompt=' $ ' --sudo install $system_packages + sage-print-system-package-command $system --wrap --prompt=' $ ' --continuation=' ' --sudo install $system_packages echo done if [ -z "$system" ]; then @@ -114,15 +129,15 @@ else if [ -f "${SPKG_CONFIGURE}" ]; then if grep -q SAGE_PYTHON_PACKAGE_CHECK "${SPKG_CONFIGURE}"; then echo "If the system package is installed and if the (experimental) option" - echo "--enable-system-site-packages is passed to ./configure, then ./configure" + echo "$(code --enable-system-site-packages) is passed to $(code ./configure), then $(code ./configure)" echo "will check if the system package can be used." else - echo "If the system package is installed, ./configure will check if it can be used." + echo "If the system package is installed, $(code ./configure) will check if it can be used." fi else echo "However, these system packages will not be used for building Sage" - echo "because spkg-configure.m4 has not been written for this package;" - echo "see https://github.com/sagemath/sage/issues/27330" + echo "because $(code spkg-configure.m4) has not been written for this package;" + echo "see $(issue 27330)" fi fi echo diff --git a/build/bin/write-dockerfile.sh b/build/bin/write-dockerfile.sh index bfc4dd751a4..104f7c19b31 100755 --- a/build/bin/write-dockerfile.sh +++ b/build/bin/write-dockerfile.sh @@ -16,12 +16,15 @@ export PATH="$SAGE_ROOT"/build/bin:$PATH SYSTEM_PACKAGES=$EXTRA_SYSTEM_PACKAGES CONFIGURE_ARGS="--enable-option-checking " for SPKG in $(sage-package list --has-file=spkg-configure.m4 $SAGE_PACKAGE_LIST_ARGS) $EXTRA_SAGE_PACKAGES; do - SYSTEM_PACKAGE=$(sage-get-system-packages $SYSTEM $SPKG | sed 's/${PYTHON_MINOR}/'${PYTHON_MINOR}'/g') + SYSTEM_PACKAGE=$(sage-get-system-packages $SYSTEM $SPKG) if [ -n "${SYSTEM_PACKAGE}" ]; then - # SYSTEM_PACKAGE can be empty if, for example, the environment - # variable ENABLE_SYSTEM_SITE_PACKAGES is empty. - SYSTEM_PACKAGES+=" ${SYSTEM_PACKAGE}" - CONFIGURE_ARGS+="--with-system-${SPKG}=${WITH_SYSTEM_SPKG} " + # SYSTEM_PACKAGE can be empty if, for example, the environment + # variable ENABLE_SYSTEM_SITE_PACKAGES is empty. + for a in $SYSTEM_PACKAGE; do + # shell-quote package if necessary + SYSTEM_PACKAGES+=$(printf " %q" "$a") + done + CONFIGURE_ARGS+="--with-system-${SPKG}=${WITH_SYSTEM_SPKG} " fi done echo "# Automatically generated by SAGE_ROOT/build/bin/write-dockerfile.sh" diff --git a/build/make/Makefile.in b/build/make/Makefile.in index 0cbe86a90de..aac7a9164a2 100644 --- a/build/make/Makefile.in +++ b/build/make/Makefile.in @@ -324,7 +324,7 @@ all-toolchain: base-toolchain # Shorthand for a list of packages sufficient for building and installing # typical Python packages from source. Wheel packages only need pip. -PYTHON_TOOLCHAIN = setuptools pip setuptools_scm wheel setuptools_wheel +PYTHON_TOOLCHAIN = setuptools pip setuptools_scm wheel flit_core hatchling # Trac #32056: Avoid installed setuptools leaking into the build of python3 by uninstalling it. # It will have to be reinstalled anyway because of its dependency on $(PYTHON). diff --git a/build/pkgs/_bootstrap/distros/arch.txt b/build/pkgs/_bootstrap/distros/arch.txt index 33054ef918c..050de00ca70 100644 --- a/build/pkgs/_bootstrap/distros/arch.txt +++ b/build/pkgs/_bootstrap/distros/arch.txt @@ -1,3 +1,5 @@ # Packages needed for ./bootstrap -autoconf automake libtool +autoconf +automake +libtool pkgconf diff --git a/build/pkgs/_bootstrap/distros/cygwin.txt b/build/pkgs/_bootstrap/distros/cygwin.txt index b5d2db8cfb2..bde788ee5d9 100644 --- a/build/pkgs/_bootstrap/distros/cygwin.txt +++ b/build/pkgs/_bootstrap/distros/cygwin.txt @@ -1,2 +1,4 @@ # Packages needed for ./bootstrap -autoconf automake libtool +autoconf +automake +libtool diff --git a/build/pkgs/_bootstrap/distros/fedora.txt b/build/pkgs/_bootstrap/distros/fedora.txt index e8e9330eca1..5fe960ac3a0 100644 --- a/build/pkgs/_bootstrap/distros/fedora.txt +++ b/build/pkgs/_bootstrap/distros/fedora.txt @@ -1,4 +1,5 @@ # Packages needed for ./bootstrap -autoconf automake libtool -# Fedora 26 needs: +autoconf +automake +libtool pkg-config diff --git a/build/pkgs/_bootstrap/distros/freebsd.txt b/build/pkgs/_bootstrap/distros/freebsd.txt index 93d91f5c84b..5fe960ac3a0 100644 --- a/build/pkgs/_bootstrap/distros/freebsd.txt +++ b/build/pkgs/_bootstrap/distros/freebsd.txt @@ -1,2 +1,5 @@ # Packages needed for ./bootstrap -autoconf automake libtool pkg-config +autoconf +automake +libtool +pkg-config diff --git a/build/pkgs/_bootstrap/distros/homebrew.txt b/build/pkgs/_bootstrap/distros/homebrew.txt index 93d91f5c84b..5fe960ac3a0 100644 --- a/build/pkgs/_bootstrap/distros/homebrew.txt +++ b/build/pkgs/_bootstrap/distros/homebrew.txt @@ -1,2 +1,5 @@ # Packages needed for ./bootstrap -autoconf automake libtool pkg-config +autoconf +automake +libtool +pkg-config diff --git a/build/pkgs/_bootstrap/distros/macports.txt b/build/pkgs/_bootstrap/distros/macports.txt new file mode 100644 index 00000000000..5f6a8a4c191 --- /dev/null +++ b/build/pkgs/_bootstrap/distros/macports.txt @@ -0,0 +1,6 @@ +# Packages needed for ./bootstrap +gettext +autoconf +automake +libtool +pkgconfig diff --git a/build/pkgs/_bootstrap/distros/nix.txt b/build/pkgs/_bootstrap/distros/nix.txt index 93d91f5c84b..5fe960ac3a0 100644 --- a/build/pkgs/_bootstrap/distros/nix.txt +++ b/build/pkgs/_bootstrap/distros/nix.txt @@ -1,2 +1,5 @@ # Packages needed for ./bootstrap -autoconf automake libtool pkg-config +autoconf +automake +libtool +pkg-config diff --git a/build/pkgs/_bootstrap/distros/void.txt b/build/pkgs/_bootstrap/distros/void.txt index 6490cf773e7..904bd61a232 100644 --- a/build/pkgs/_bootstrap/distros/void.txt +++ b/build/pkgs/_bootstrap/distros/void.txt @@ -1,4 +1,7 @@ # Packages needed for ./bootstrap -autoconf automake libtool -xtools mk-configure +autoconf +automake +libtool +xtools +mk-configure pkg-config diff --git a/build/pkgs/_prereq/distros/alpine.txt b/build/pkgs/_prereq/distros/alpine.txt index 159c452cf30..3986f8ac849 100644 --- a/build/pkgs/_prereq/distros/alpine.txt +++ b/build/pkgs/_prereq/distros/alpine.txt @@ -1,3 +1,12 @@ +# This file, build/pkgs/_prereq/distros/alpine.txt, contains names of +# Alpine Linux packages needed for installation of Sage from source. +# +# In addition, the files build/pkgs/SPKG/distros/alpine.txt contain +# the names of packages that provide the equivalent of SPKG. +# +# One package per line. No need to escape special characters. +# Everything on a line after a # character is ignored. +# binutils make m4 diff --git a/build/pkgs/_prereq/distros/arch.txt b/build/pkgs/_prereq/distros/arch.txt index 9b9bf09e7e2..aac6d8f5976 100644 --- a/build/pkgs/_prereq/distros/arch.txt +++ b/build/pkgs/_prereq/distros/arch.txt @@ -1,3 +1,12 @@ +# This file, build/pkgs/_prereq/distros/arch.txt, contains names of +# Arch Linux packages needed for installation of Sage from source. +# +# In addition, the files build/pkgs/SPKG/distros/arch.txt contain +# the names of packages that provide the equivalent of SPKG. +# +# One package per line. No need to escape special characters. +# Everything on a line after a # character is ignored. +# binutils make m4 diff --git a/build/pkgs/_prereq/distros/conda.txt b/build/pkgs/_prereq/distros/conda.txt index d76388ce7bb..e8fcb099093 100644 --- a/build/pkgs/_prereq/distros/conda.txt +++ b/build/pkgs/_prereq/distros/conda.txt @@ -1,4 +1,13 @@ -compilers +# This file, build/pkgs/_prereq/distros/conda.txt, contains names of +# conda packages needed for installation of Sage from source. +# +# In addition, the files build/pkgs/SPKG/distros/conda.txt contain +# the names of packages that provide the equivalent of SPKG. +# +# One package per line. No need to escape special characters. +# Everything on a line after a # character is ignored. +# +compilers<=1.6.0 # 1.7 pulls in c-compiler v.16 make m4 perl diff --git a/build/pkgs/_prereq/distros/cygwin.txt b/build/pkgs/_prereq/distros/cygwin.txt index 2bf3164005b..7a05e1aaa54 100644 --- a/build/pkgs/_prereq/distros/cygwin.txt +++ b/build/pkgs/_prereq/distros/cygwin.txt @@ -1,19 +1,18 @@ -# This file, build/pkgs/cygwin.txt, contains name Cygwin packages -# needed for installation of Sage from source. +# This file, build/pkgs/_prereq/distros/cygwin.txt, contains names of +# Cygwin packages needed for installation of Sage from source. # -# In addition, the files build/pkgs/SPKG/cygwin.txt contain the names -# of packages that provide the equivalent of SPKG. -# -# See build/bin/sage-spkg, where this information is processed -# for use in "sage -info SPKG". +# In addition, the files build/pkgs/SPKG/distros/cygwin.txt contain +# the names of packages that provide the equivalent of SPKG. # +# One package per line. No need to escape special characters. # Everything on a line after a # character is ignored. # binutils make m4 # a system python is needed for downloading the sage packages, https://github.com/sagemath/sage/issues/29090 -python39-urllib3 python39 +python39-urllib3 +python39 perl perl-ExtUtils-MakeMaker tar diff --git a/build/pkgs/_prereq/distros/debian.txt b/build/pkgs/_prereq/distros/debian.txt index 50be6ac7e0b..785739528b4 100644 --- a/build/pkgs/_prereq/distros/debian.txt +++ b/build/pkgs/_prereq/distros/debian.txt @@ -1,16 +1,12 @@ -# This file, build/pkgs/debian.txt, contains names of Debian/Ubuntu packages -# needed for installation of Sage from source. +# This file, build/pkgs/_prereq/distros/debian.txt, contains names of +# Debian/Ubuntu/... packages needed for installation of Sage from source. # -# In addition, the files build/pkgs/SPKG/debian.txt contain the names -# of packages that provide the equivalent of SPKG. -# -# If distinctions between different distributions need to be made, -# files named debian....txt or ubuntu.....txt can be used. -# -# See build/bin/sage-spkg, where this information is processed -# for use in "sage -info SPKG". +# In addition, the files build/pkgs/SPKG/distros/debian.txt contain +# the names of packages that provide the equivalent of SPKG. # +# One package per line. No need to escape special characters. # Everything on a line after a # character is ignored. +# binutils make m4 diff --git a/build/pkgs/_prereq/distros/fedora.txt b/build/pkgs/_prereq/distros/fedora.txt index b35d7f64faf..2716e7eb0cd 100644 --- a/build/pkgs/_prereq/distros/fedora.txt +++ b/build/pkgs/_prereq/distros/fedora.txt @@ -1,15 +1,11 @@ -# This file, build/pkgs/fedora.txt, contains names of Fedora/Redhat/CentOS packages -# needed for installation of Sage from source. +# This file, build/pkgs/_prereq/distros/fedora.txt, contains names of +# Fedora/Redhat/CentOS/AlmaLinux packages needed for installation +# of Sage from source. # -# In addition, the files build/pkgs/SPKG/fedora.txt contain the names -# of packages that provide the equivalent of SPKG. -# -# If distinctions between different distributions need to be made, -# files named fedora....txt, redhat...txt, or centos....txt can be used. -# -# See build/bin/sage-spkg, where this information is processed -# for use in "sage -info SPKG". +# In addition, the files build/pkgs/SPKG/distros/fedora.txt contain +# the names of packages that provide the equivalent of SPKG. # +# One package per line. No need to escape special characters. # Everything on a line after a # character is ignored. # binutils diff --git a/build/pkgs/_prereq/distros/freebsd.txt b/build/pkgs/_prereq/distros/freebsd.txt index cc708ccfb2b..f9a4937520a 100644 --- a/build/pkgs/_prereq/distros/freebsd.txt +++ b/build/pkgs/_prereq/distros/freebsd.txt @@ -1,5 +1,5 @@ -# This file, build/pkgs/freebsd.txt, contains names of FreeBSD packages -# needed for installation of Sage from source. +# This file, build/pkgs/_prereq/distros/freebsd.txt, contains names of +# FreeBSD packages needed for installation of Sage from source. # # In addition, the files build/pkgs/SPKG/distros/freebsd.txt contain the # names of packages that provide the equivalent of SPKG. @@ -8,10 +8,9 @@ # $ cd /usr/ports/math/sage # $ sudo make install-missing-packages # -# See build/bin/sage-spkg, where this information is processed -# for use in "sage -info SPKG". -# +# One package per line. No need to escape special characters. # Everything on a line after a # character is ignored. +# gmake automake bash diff --git a/build/pkgs/_prereq/distros/gentoo.txt b/build/pkgs/_prereq/distros/gentoo.txt index 1e26c46cacc..455991e8a99 100644 --- a/build/pkgs/_prereq/distros/gentoo.txt +++ b/build/pkgs/_prereq/distros/gentoo.txt @@ -1,3 +1,12 @@ +# This file, build/pkgs/_prereq/distros/gentoo.txt, contains names of +# Gentoo packages needed for installation of Sage from source. +# +# In addition, the files build/pkgs/SPKG/distros/gentoo.txt contain +# the names of packages that provide the equivalent of SPKG. +# +# One package per line. No need to escape special characters. +# Everything on a line after a # character is ignored. +# sys-devel/binutils sys-libs/binutils-libs sys-devel/make diff --git a/build/pkgs/_prereq/distros/homebrew.txt b/build/pkgs/_prereq/distros/homebrew.txt index 863c22a6bee..2a85c39abfc 100644 --- a/build/pkgs/_prereq/distros/homebrew.txt +++ b/build/pkgs/_prereq/distros/homebrew.txt @@ -1,12 +1,11 @@ -# This file, build/pkgs/homebrew.txt, contains names of homebrew packages -# needed for installation of Sage from source (in addition to XCode). +# This file, build/pkgs/_prereq/distros/homebrew.txt, contains names of +# Homebrew packages needed for installation of Sage from source. # -# In addition, the files build/pkgs/SPKG/homebrew.txt contain the names -# of packages that provide the equivalent of SPKG. -# -# See build/bin/sage-spkg, where this information is processed -# for use in "sage -info SPKG". +# In addition, the files build/pkgs/SPKG/distros/homebrew.txt contain +# the names of packages that provide the equivalent of SPKG. # +# One package per line. No need to escape special characters. # Everything on a line after a # character is ignored. +# # No packages needed diff --git a/build/pkgs/_prereq/distros/macports.txt b/build/pkgs/_prereq/distros/macports.txt new file mode 100644 index 00000000000..e887cd91e80 --- /dev/null +++ b/build/pkgs/_prereq/distros/macports.txt @@ -0,0 +1,12 @@ +# This file, build/pkgs/_prereq/distros/macports.txt, contains names of macports packages +# needed for installation of Sage from source (in addition to XCode). +# +# In addition, the files build/pkgs/SPKG/distros/macports.txt contain the names +# of packages that provide the equivalent of SPKG. +# +# See build/bin/sage-spkg, where this information is processed +# for use in "sage -info SPKG". +# +# Everything on a line after a # character is ignored. + +# No packages needed diff --git a/build/pkgs/_prereq/distros/nix.txt b/build/pkgs/_prereq/distros/nix.txt index 01e5ed4e959..523fe272f7c 100644 --- a/build/pkgs/_prereq/distros/nix.txt +++ b/build/pkgs/_prereq/distros/nix.txt @@ -1,16 +1,12 @@ -# This file, build/pkgs/debian.txt, contains names of Debian/Ubuntu packages -# needed for installation of Sage from source. +# This file, build/pkgs/_prereq/distros/nix.txt, contains names of +# nix packages needed for installation of Sage from source. # -# In addition, the files build/pkgs/SPKG/debian.txt contain the names -# of packages that provide the equivalent of SPKG. -# -# If distinctions between different distributions need to be made, -# files named debian....txt or ubuntu.....txt can be used. -# -# See build/bin/sage-spkg, where this information is processed -# for use in "sage -info SPKG". +# In addition, the files build/pkgs/SPKG/distros/nix.txt contain +# the names of packages that provide the equivalent of SPKG. # +# One package per line. No need to escape special characters. # Everything on a line after a # character is ignored. +# binutils gnumake gnum4 diff --git a/build/pkgs/_prereq/distros/opensuse.txt b/build/pkgs/_prereq/distros/opensuse.txt index 6f7a11fea47..56f77da9bcf 100644 --- a/build/pkgs/_prereq/distros/opensuse.txt +++ b/build/pkgs/_prereq/distros/opensuse.txt @@ -1,13 +1,12 @@ -# This file, build/pkgs/opensuse.txt, contains names of OpenSuse packages -# needed for installation of Sage from source. +# This file, build/pkgs/_prereq/distros/opensuse.txt, contains names of +# OpenSuse packages needed for installation of Sage from source. # -# In addition, the files build/pkgs/SPKG/opensuse.txt contain the names -# of packages that provide the equivalent of SPKG. -# -# See build/bin/sage-spkg, where this information is processed -# for use in "sage -info SPKG". +# In addition, the files build/pkgs/SPKG/distros/opensuse.txt contain +# the names of packages that provide the equivalent of SPKG. # +# One package per line. No need to escape special characters. # Everything on a line after a # character is ignored. +# binutils make m4 diff --git a/build/pkgs/_prereq/distros/slackware.txt b/build/pkgs/_prereq/distros/slackware.txt index 4c957e45264..117762dcd00 100644 --- a/build/pkgs/_prereq/distros/slackware.txt +++ b/build/pkgs/_prereq/distros/slackware.txt @@ -1,11 +1,26 @@ +# This file, build/pkgs/_prereq/distros/slackware.txt, contains names of +# Slackware packages needed for installation of Sage from source. +# +# In addition, the files build/pkgs/SPKG/distros/slackware.txt contain +# the names of packages that provide the equivalent of SPKG. +# +# One package per line. No need to escape special characters. +# Everything on a line after a # character is ignored. +# binutils make -guile gc libffi # dependencies of make -"gcc-[0-9]" # So that slackpkg pattern matching does not pull in all gcc-* packages +# dependencies of make +guile +gc +libffi +gcc-[0-9] # So that slackpkg pattern matching does not pull in all gcc-* packages gcc-11 # on slackware-current gcc-g++ gcc-g++-11 # on slackware-current -libmpc glibc kernel-headers # dependencies of gcc +# dependencies of gcc +libmpc +glibc +kernel-headers perl m4 bc diff --git a/build/pkgs/_prereq/distros/void.txt b/build/pkgs/_prereq/distros/void.txt index 552b5a415f2..d5c2143c56c 100644 --- a/build/pkgs/_prereq/distros/void.txt +++ b/build/pkgs/_prereq/distros/void.txt @@ -1,3 +1,12 @@ +# This file, build/pkgs/_prereq/distros/void.txt, contains names of +# Void Linux packages needed for installation of Sage from source. +# +# In addition, the files build/pkgs/SPKG/distros/void.txt contain +# the names of packages that provide the equivalent of SPKG. +# +# One package per line. No need to escape special characters. +# Everything on a line after a # character is ignored. +# bc binutils gcc diff --git a/build/pkgs/_recommended/dependencies b/build/pkgs/_recommended/dependencies index f4baa9b1fb2..6e36fc6d390 100644 --- a/build/pkgs/_recommended/dependencies +++ b/build/pkgs/_recommended/dependencies @@ -1 +1 @@ -pandoc ffmpeg imagemagick texlive git libjpeg +pandoc ffmpeg imagemagick git libjpeg texlive texlive_luatex free_fonts xindy diff --git a/build/pkgs/_sagemath/distros/arch.txt b/build/pkgs/_sagemath/distros/arch.txt index 825a91411b0..b58e3f244a7 100644 --- a/build/pkgs/_sagemath/distros/arch.txt +++ b/build/pkgs/_sagemath/distros/arch.txt @@ -1 +1,2 @@ -sagemath sagemath-doc +sagemath +sagemath-doc diff --git a/build/pkgs/barvinok/distros/opensuse.txt b/build/pkgs/barvinok/distros/opensuse.txt index b3369e09db7..65092b1978a 100644 --- a/build/pkgs/barvinok/distros/opensuse.txt +++ b/build/pkgs/barvinok/distros/opensuse.txt @@ -1,2 +1,2 @@ barvinok -"pkgconfig(barvinok)" +pkgconfig(barvinok) diff --git a/build/pkgs/bzip2/distros/cygwin.txt b/build/pkgs/bzip2/distros/cygwin.txt index 8e127a3d331..8ef7f4d0734 100644 --- a/build/pkgs/bzip2/distros/cygwin.txt +++ b/build/pkgs/bzip2/distros/cygwin.txt @@ -1 +1,2 @@ -bzip2 libbz2-devel +bzip2 +libbz2-devel diff --git a/build/pkgs/bzip2/distros/fedora.txt b/build/pkgs/bzip2/distros/fedora.txt index f62dee917bb..13c12f2a5f6 100644 --- a/build/pkgs/bzip2/distros/fedora.txt +++ b/build/pkgs/bzip2/distros/fedora.txt @@ -1 +1,2 @@ -bzip2 bzip2-devel +bzip2 +bzip2-devel diff --git a/build/pkgs/bzip2/distros/opensuse.txt b/build/pkgs/bzip2/distros/opensuse.txt index ad77a92d4bb..ff839c0de00 100644 --- a/build/pkgs/bzip2/distros/opensuse.txt +++ b/build/pkgs/bzip2/distros/opensuse.txt @@ -1,3 +1,3 @@ # spkg-configure checks for both the program and the library bzip2 -"pkgconfig(bzip2)" +pkgconfig(bzip2) diff --git a/build/pkgs/calver/dependencies b/build/pkgs/calver/dependencies index 47296a7bace..644ad35f773 100644 --- a/build/pkgs/calver/dependencies +++ b/build/pkgs/calver/dependencies @@ -1,4 +1,4 @@ - | $(PYTHON_TOOLCHAIN) $(PYTHON) + | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/cbc/distros/fedora.txt b/build/pkgs/cbc/distros/fedora.txt index 3e1af7ad66b..d63f4439b2a 100644 --- a/build/pkgs/cbc/distros/fedora.txt +++ b/build/pkgs/cbc/distros/fedora.txt @@ -1 +1,2 @@ -coin-or-Cbc coin-or-Cbc-devel +coin-or-Cbc +coin-or-Cbc-devel diff --git a/build/pkgs/cddlib/distros/cygwin.txt b/build/pkgs/cddlib/distros/cygwin.txt index f9eaae4c7ad..d406d903210 100644 --- a/build/pkgs/cddlib/distros/cygwin.txt +++ b/build/pkgs/cddlib/distros/cygwin.txt @@ -1 +1,2 @@ -cddlib-devel cddlib-tools +cddlib-devel +cddlib-tools diff --git a/build/pkgs/cddlib/distros/opensuse.txt b/build/pkgs/cddlib/distros/opensuse.txt index ffb93647443..0d299e7ad0e 100644 --- a/build/pkgs/cddlib/distros/opensuse.txt +++ b/build/pkgs/cddlib/distros/opensuse.txt @@ -1,2 +1,2 @@ cddlib-tools -"pkgconfig(cddlib)" +pkgconfig(cddlib) diff --git a/build/pkgs/cliquer/distros/fedora.txt b/build/pkgs/cliquer/distros/fedora.txt index 4dadef53faa..718f9f6b2cf 100644 --- a/build/pkgs/cliquer/distros/fedora.txt +++ b/build/pkgs/cliquer/distros/fedora.txt @@ -1 +1,2 @@ -cliquer cliquer-devel +cliquer +cliquer-devel diff --git a/build/pkgs/cmake/distros/macports.txt b/build/pkgs/cmake/distros/macports.txt index a3ea3e4380f..de0e65cf914 100644 --- a/build/pkgs/cmake/distros/macports.txt +++ b/build/pkgs/cmake/distros/macports.txt @@ -1 +1,2 @@ -cmake +# Broken as of 2022-05-01 +#cmake diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index bdd96db7026..a10d1db6236 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=2389d2b093493c568deda190ffc326ff2b835169 -md5=545e80b50deb4efa46f14d0a543ba98f -cksum=169905223 +sha1=05115739db242cb5a48ae17f97d06b179fc70334 +md5=adc8208885e6be527b089b682079c464 +cksum=3321256447 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 033bf42aaae..fbcbbd235f8 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -73e52a419812253c3c3ce72bab7f1a5ddf4c0461 +e95536ccbad199de456e804968a775f2744e4bff diff --git a/build/pkgs/coxeter3/distros/fedora.txt b/build/pkgs/coxeter3/distros/fedora.txt index 3cfeb2f9fa0..0c6fb8a3e95 100644 --- a/build/pkgs/coxeter3/distros/fedora.txt +++ b/build/pkgs/coxeter3/distros/fedora.txt @@ -1 +1,3 @@ -coxeter coxeter-devel coxeter-tools +coxeter +coxeter-devel +coxeter-tools diff --git a/build/pkgs/curl/distros/cygwin.txt b/build/pkgs/curl/distros/cygwin.txt index 7bcb9889a4d..26bfd4d1186 100644 --- a/build/pkgs/curl/distros/cygwin.txt +++ b/build/pkgs/curl/distros/cygwin.txt @@ -1 +1,2 @@ -libcurl-devel curl +libcurl-devel +curl diff --git a/build/pkgs/curl/distros/fedora.txt b/build/pkgs/curl/distros/fedora.txt index 7bcb9889a4d..26bfd4d1186 100644 --- a/build/pkgs/curl/distros/fedora.txt +++ b/build/pkgs/curl/distros/fedora.txt @@ -1 +1,2 @@ -libcurl-devel curl +libcurl-devel +curl diff --git a/build/pkgs/curl/distros/macports.txt b/build/pkgs/curl/distros/macports.txt index 13368f82902..284d14f8d01 100644 --- a/build/pkgs/curl/distros/macports.txt +++ b/build/pkgs/curl/distros/macports.txt @@ -1 +1,2 @@ -curl +# Broken as of 2022-05-01 +#curl diff --git a/build/pkgs/curl/distros/opensuse.txt b/build/pkgs/curl/distros/opensuse.txt index ffd4f36dc86..a0ac40946fa 100644 --- a/build/pkgs/curl/distros/opensuse.txt +++ b/build/pkgs/curl/distros/opensuse.txt @@ -1,2 +1,2 @@ curl -"pkgconfig(libcurl)" +pkgconfig(libcurl) diff --git a/build/pkgs/deprecation/SPKG.rst b/build/pkgs/deprecation/SPKG.rst deleted file mode 100644 index 8aa6712f42b..00000000000 --- a/build/pkgs/deprecation/SPKG.rst +++ /dev/null @@ -1,18 +0,0 @@ -deprecation: A library to handle automated deprecations -======================================================= - -Description ------------ - -A library to handle automated deprecations - -License -------- - -Apache 2 - -Upstream Contact ----------------- - -https://pypi.org/project/deprecation/ - diff --git a/build/pkgs/deprecation/checksums.ini b/build/pkgs/deprecation/checksums.ini deleted file mode 100644 index b2e6c9d2964..00000000000 --- a/build/pkgs/deprecation/checksums.ini +++ /dev/null @@ -1,5 +0,0 @@ -tarball=deprecation-VERSION.tar.gz -sha1=34847e937ac203cfd0d8ea0a0f2579204cdb8fe4 -md5=6b79c6572fb241e3cecbbd7d539bb66b -cksum=1034714094 -upstream_url=https://pypi.io/packages/source/d/deprecation/deprecation-VERSION.tar.gz diff --git a/build/pkgs/deprecation/dependencies b/build/pkgs/deprecation/dependencies deleted file mode 100644 index 47296a7bace..00000000000 --- a/build/pkgs/deprecation/dependencies +++ /dev/null @@ -1,4 +0,0 @@ - | $(PYTHON_TOOLCHAIN) $(PYTHON) - ----------- -All lines of this file are ignored except the first. diff --git a/build/pkgs/deprecation/distros/conda.txt b/build/pkgs/deprecation/distros/conda.txt deleted file mode 100644 index 4ba9b7530ed..00000000000 --- a/build/pkgs/deprecation/distros/conda.txt +++ /dev/null @@ -1 +0,0 @@ -deprecation diff --git a/build/pkgs/deprecation/install-requires.txt b/build/pkgs/deprecation/install-requires.txt deleted file mode 100644 index 4ba9b7530ed..00000000000 --- a/build/pkgs/deprecation/install-requires.txt +++ /dev/null @@ -1 +0,0 @@ -deprecation diff --git a/build/pkgs/deprecation/package-version.txt b/build/pkgs/deprecation/package-version.txt deleted file mode 100644 index 7ec1d6db408..00000000000 --- a/build/pkgs/deprecation/package-version.txt +++ /dev/null @@ -1 +0,0 @@ -2.1.0 diff --git a/build/pkgs/deprecation/spkg-install.in b/build/pkgs/deprecation/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/deprecation/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/deprecation/type b/build/pkgs/deprecation/type deleted file mode 100644 index a6a7b9cd726..00000000000 --- a/build/pkgs/deprecation/type +++ /dev/null @@ -1 +0,0 @@ -standard diff --git a/build/pkgs/distlib/SPKG.rst b/build/pkgs/distlib/SPKG.rst index a4496c0427a..e59b0b7292c 100644 --- a/build/pkgs/distlib/SPKG.rst +++ b/build/pkgs/distlib/SPKG.rst @@ -9,7 +9,7 @@ Distribution utilities License ------- -Python license +PSF-2.0 Upstream Contact ---------------- diff --git a/build/pkgs/distlib/checksums.ini b/build/pkgs/distlib/checksums.ini index be255ceca11..b1a05ffc295 100644 --- a/build/pkgs/distlib/checksums.ini +++ b/build/pkgs/distlib/checksums.ini @@ -1,5 +1,5 @@ -tarball=distlib-VERSION.tar.gz -sha1=5c99f8bd1cc58c387a8d22afa632f81c6fec9993 -md5=44e4357e35bbd77fdf1b81e174e34f20 -cksum=3690000669 -upstream_url=https://pypi.io/packages/source/d/distlib/distlib-VERSION.tar.gz +tarball=distlib-VERSION-py2.py3-none-any.whl +sha1=97ea3bb71040f0348eaea272ec17fefea5806e87 +md5=cf336842ba81996e554ae4eb2cd76d5d +cksum=3779817199 +upstream_url=https://pypi.io/packages/py2.py3/d/distlib/distlib-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/distlib/dependencies b/build/pkgs/distlib/dependencies index 47296a7bace..644ad35f773 100644 --- a/build/pkgs/distlib/dependencies +++ b/build/pkgs/distlib/dependencies @@ -1,4 +1,4 @@ - | $(PYTHON_TOOLCHAIN) $(PYTHON) + | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/distlib/package-version.txt b/build/pkgs/distlib/package-version.txt index 0f82685331e..66784322096 100644 --- a/build/pkgs/distlib/package-version.txt +++ b/build/pkgs/distlib/package-version.txt @@ -1 +1 @@ -0.3.7 +0.3.8 diff --git a/build/pkgs/distlib/spkg-install.in b/build/pkgs/distlib/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/distlib/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/e_antic/checksums.ini b/build/pkgs/e_antic/checksums.ini index d24ae72e6f4..fe7fa852b76 100644 --- a/build/pkgs/e_antic/checksums.ini +++ b/build/pkgs/e_antic/checksums.ini @@ -1,5 +1,5 @@ tarball=e-antic-VERSION.tar.gz -sha1=4f551cf2ab58201fb2137ae994cb670c6fa8b154 -md5=6c6f38408994f7d79f814bbad8183fcb -cksum=2487959662 +sha1=587052e189f9a7a145ac3144e6b7f11fca54b1ff +md5=0b54042461b28c4b45239480af062546 +cksum=589498373 upstream_url=https://github.com/flatsurf/e-antic/releases/download/VERSION/e-antic-VERSION.tar.gz diff --git a/build/pkgs/e_antic/package-version.txt b/build/pkgs/e_antic/package-version.txt index f0bb29e7638..227cea21564 100644 --- a/build/pkgs/e_antic/package-version.txt +++ b/build/pkgs/e_antic/package-version.txt @@ -1 +1 @@ -1.3.0 +2.0.0 diff --git a/build/pkgs/eclib/checksums.ini b/build/pkgs/eclib/checksums.ini index 266e6bfac1c..b6a7efd95aa 100644 --- a/build/pkgs/eclib/checksums.ini +++ b/build/pkgs/eclib/checksums.ini @@ -1,5 +1,5 @@ tarball=eclib-VERSION.tar.bz2 -sha1=bd49acf96c4e7246c8ca3e5d188ae1b03a3aeff3 -md5=42721f2f1343c49dc774763a57a85ca6 -cksum=3624641360 +sha1=3028ac95e1b76699f5f9e871ac706cda363ab842 +md5=c96e1bb39a50552aeac6675b907709b8 +cksum=2027019032 upstream_url=https://github.com/JohnCremona/eclib/releases/download/vVERSION/eclib-VERSION.tar.bz2 diff --git a/build/pkgs/eclib/distros/fedora.txt b/build/pkgs/eclib/distros/fedora.txt index 7861ae6de2b..2bcdd8cb9a5 100644 --- a/build/pkgs/eclib/distros/fedora.txt +++ b/build/pkgs/eclib/distros/fedora.txt @@ -1 +1,2 @@ -eclib eclib-devel +eclib +eclib-devel diff --git a/build/pkgs/eclib/package-version.txt b/build/pkgs/eclib/package-version.txt index b5f339e560b..190b92f716b 100644 --- a/build/pkgs/eclib/package-version.txt +++ b/build/pkgs/eclib/package-version.txt @@ -1 +1 @@ -20230424 +20231212 diff --git a/build/pkgs/eclib/spkg-configure.m4 b/build/pkgs/eclib/spkg-configure.m4 index c98781201cc..133b44bfdc1 100644 --- a/build/pkgs/eclib/spkg-configure.m4 +++ b/build/pkgs/eclib/spkg-configure.m4 @@ -1,12 +1,12 @@ SAGE_SPKG_CONFIGURE([eclib], [ SAGE_SPKG_DEPCHECK([ntl pari flint], [ - dnl Trac #31443, #34029: use existing eclib only if the version reported by pkg-config is correct - m4_pushdef([SAGE_ECLIB_VER],["20230424"]) + dnl use existing eclib only if the version reported by pkg-config is recent enough + m4_pushdef([SAGE_ECLIB_VER],["20231212"]) PKG_CHECK_MODULES([ECLIB], [eclib = SAGE_ECLIB_VER], [ AC_CACHE_CHECK([for mwrank version == SAGE_ECLIB_VER], [ac_cv_path_MWRANK], [ AC_PATH_PROGS_FEATURE_CHECK([MWRANK], [mwrank], [ mwrank_version=`$ac_path_MWRANK -V 2>&1` - AX_COMPARE_VERSION([$mwrank_version], [eq], [SAGE_ECLIB_VER], [ + AX_COMPARE_VERSION([$mwrank_version], [ge], [SAGE_ECLIB_VER], [ ac_cv_path_MWRANK="$ac_path_MWRANK" ]) ]) diff --git a/build/pkgs/eclib/spkg-install.in b/build/pkgs/eclib/spkg-install.in index 4998cff1676..9618e8f5d19 100644 --- a/build/pkgs/eclib/spkg-install.in +++ b/build/pkgs/eclib/spkg-install.in @@ -5,22 +5,9 @@ export CFLAGS CXXFLAGS cd src/ -############################################################# -# the workaround with SAGE_CONFIGURE_FLINT_ECLIB -# introduced by #28401 may be removed once -# github.com/JohnCremona/eclib/pull/57 is in Sage -############################################################# -if test x$SAGE_FLINT_PREFIX = x; then - SAGE_CONFIGURE_FLINT_ECLIB="--with-flint" -else - SAGE_CONFIGURE_FLINT_ECLIB="--with-flint=$SAGE_FLINT_PREFIX" -fi - -echo $SAGE_CONFIGURE_FLINT_ECLIB - sdh_configure $SAGE_CONFIGURE_NTL \ $SAGE_CONFIGURE_PARI \ - $SAGE_CONFIGURE_FLINT_ECLIB \ + --with-flint=$SAGE_FLINT_PREFIX \ --with-boost="no" \ --disable-allprogs sdh_make diff --git a/build/pkgs/ecm/distros/fedora.txt b/build/pkgs/ecm/distros/fedora.txt index 45e62aa8032..0625c82b8b9 100644 --- a/build/pkgs/ecm/distros/fedora.txt +++ b/build/pkgs/ecm/distros/fedora.txt @@ -1 +1,2 @@ -gmp-ecm gmp-ecm-devel +gmp-ecm +gmp-ecm-devel diff --git a/build/pkgs/editables/dependencies b/build/pkgs/editables/dependencies index 47296a7bace..e0e94942dba 100644 --- a/build/pkgs/editables/dependencies +++ b/build/pkgs/editables/dependencies @@ -1,4 +1,4 @@ - | $(PYTHON_TOOLCHAIN) $(PYTHON) + | flit_core $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/fflas_ffpack/distros/opensuse.txt b/build/pkgs/fflas_ffpack/distros/opensuse.txt index 2dda5369b8d..cf55f69f450 100644 --- a/build/pkgs/fflas_ffpack/distros/opensuse.txt +++ b/build/pkgs/fflas_ffpack/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(fflas-ffpack)" +pkgconfig(fflas-ffpack) diff --git a/build/pkgs/filelock/checksums.ini b/build/pkgs/filelock/checksums.ini index 0d412bb2ca3..6c597d2d7aa 100644 --- a/build/pkgs/filelock/checksums.ini +++ b/build/pkgs/filelock/checksums.ini @@ -1,5 +1,5 @@ tarball=filelock-VERSION-py3-none-any.whl -sha1=74f5368865bf05ddc5b69949e4547ad25c078fc1 -md5=63b0f117cb65ef531ffafb566170661e -cksum=1046951951 +sha1=f1fa92751023660a10b248f8559d09f3c461403f +md5=d0af0f1a2ee56c24f630ece278cb062f +cksum=3749691502 upstream_url=https://pypi.io/packages/py3/f/filelock/filelock-VERSION-py3-none-any.whl diff --git a/build/pkgs/filelock/dependencies b/build/pkgs/filelock/dependencies index 47296a7bace..644ad35f773 100644 --- a/build/pkgs/filelock/dependencies +++ b/build/pkgs/filelock/dependencies @@ -1,4 +1,4 @@ - | $(PYTHON_TOOLCHAIN) $(PYTHON) + | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/filelock/package-version.txt b/build/pkgs/filelock/package-version.txt index 871f80a34be..c10780c628a 100644 --- a/build/pkgs/filelock/package-version.txt +++ b/build/pkgs/filelock/package-version.txt @@ -1 +1 @@ -3.12.3 +3.13.1 diff --git a/build/pkgs/flint/distros/fedora.txt b/build/pkgs/flint/distros/fedora.txt index 8df1db2cd08..12eb8937aea 100644 --- a/build/pkgs/flint/distros/fedora.txt +++ b/build/pkgs/flint/distros/fedora.txt @@ -1 +1,2 @@ -flint flint-devel +flint +flint-devel diff --git a/build/pkgs/fplll/distros/fedora.txt b/build/pkgs/fplll/distros/fedora.txt index ccf2e14dfee..29c3b897ae1 100644 --- a/build/pkgs/fplll/distros/fedora.txt +++ b/build/pkgs/fplll/distros/fedora.txt @@ -1 +1,2 @@ -libfplll libfplll-devel +libfplll +libfplll-devel diff --git a/build/pkgs/fplll/distros/opensuse.txt b/build/pkgs/fplll/distros/opensuse.txt index ee87c038706..2589161f43c 100644 --- a/build/pkgs/fplll/distros/opensuse.txt +++ b/build/pkgs/fplll/distros/opensuse.txt @@ -1,3 +1,3 @@ -"pkgconfig(fplll)" +pkgconfig(fplll) fplll-devel fplll diff --git a/build/pkgs/free_fonts/SPKG.rst b/build/pkgs/free_fonts/SPKG.rst new file mode 100644 index 00000000000..417954179a7 --- /dev/null +++ b/build/pkgs/free_fonts/SPKG.rst @@ -0,0 +1,23 @@ +free_fonts: a free family of scalable outline fonts +=================================================== + +Description +----------- + +This dummy package represents the GNU free fonts: a free family of scalable +outline fonts, suitable for general use on computers and for desktop +publishing. It is Unicode-encoded for compatibility with all modern operating +systems. + +We do not have an SPKG for it. The purpose of this dummy package is to +associate system package lists with it. + +License +------- + +GNU General Public License GPLv3+ + +Upstream Contact +---------------- + +https://www.gnu.org/software/freefont/ diff --git a/build/pkgs/free_fonts/distros/alpine.txt b/build/pkgs/free_fonts/distros/alpine.txt new file mode 100644 index 00000000000..756efd2627c --- /dev/null +++ b/build/pkgs/free_fonts/distros/alpine.txt @@ -0,0 +1 @@ +ttf-freefont diff --git a/build/pkgs/free_fonts/distros/arch.txt b/build/pkgs/free_fonts/distros/arch.txt new file mode 100644 index 00000000000..b03a4525c08 --- /dev/null +++ b/build/pkgs/free_fonts/distros/arch.txt @@ -0,0 +1 @@ +gnu-free-fonts diff --git a/build/pkgs/free_fonts/distros/conda.txt b/build/pkgs/free_fonts/distros/conda.txt new file mode 100644 index 00000000000..bdf05c629cf --- /dev/null +++ b/build/pkgs/free_fonts/distros/conda.txt @@ -0,0 +1 @@ +open-fonts diff --git a/build/pkgs/free_fonts/distros/debian.txt b/build/pkgs/free_fonts/distros/debian.txt new file mode 100644 index 00000000000..9dae6737769 --- /dev/null +++ b/build/pkgs/free_fonts/distros/debian.txt @@ -0,0 +1 @@ +fonts-freefont-otf diff --git a/build/pkgs/free_fonts/distros/fedora.txt b/build/pkgs/free_fonts/distros/fedora.txt new file mode 100644 index 00000000000..b03a4525c08 --- /dev/null +++ b/build/pkgs/free_fonts/distros/fedora.txt @@ -0,0 +1 @@ +gnu-free-fonts diff --git a/build/pkgs/free_fonts/distros/freebsd.txt b/build/pkgs/free_fonts/distros/freebsd.txt new file mode 100644 index 00000000000..34b729ae37f --- /dev/null +++ b/build/pkgs/free_fonts/distros/freebsd.txt @@ -0,0 +1 @@ +x11-fonts/freefont-ttf diff --git a/build/pkgs/free_fonts/distros/gentoo.txt b/build/pkgs/free_fonts/distros/gentoo.txt new file mode 100644 index 00000000000..f9711d7a9f2 --- /dev/null +++ b/build/pkgs/free_fonts/distros/gentoo.txt @@ -0,0 +1 @@ +media-fonts/freefont diff --git a/build/pkgs/free_fonts/distros/macports.txt b/build/pkgs/free_fonts/distros/macports.txt new file mode 100644 index 00000000000..d5a8b479117 --- /dev/null +++ b/build/pkgs/free_fonts/distros/macports.txt @@ -0,0 +1 @@ +freefont-ttf diff --git a/build/pkgs/free_fonts/distros/opensuse.txt b/build/pkgs/free_fonts/distros/opensuse.txt new file mode 100644 index 00000000000..b03a4525c08 --- /dev/null +++ b/build/pkgs/free_fonts/distros/opensuse.txt @@ -0,0 +1 @@ +gnu-free-fonts diff --git a/build/pkgs/free_fonts/distros/repology.txt b/build/pkgs/free_fonts/distros/repology.txt new file mode 100644 index 00000000000..0870af23017 --- /dev/null +++ b/build/pkgs/free_fonts/distros/repology.txt @@ -0,0 +1 @@ +gnu-freefont diff --git a/build/pkgs/free_fonts/distros/void.txt b/build/pkgs/free_fonts/distros/void.txt new file mode 100644 index 00000000000..d5a8b479117 --- /dev/null +++ b/build/pkgs/free_fonts/distros/void.txt @@ -0,0 +1 @@ +freefont-ttf diff --git a/build/pkgs/free_fonts/spkg-configure.m4 b/build/pkgs/free_fonts/spkg-configure.m4 new file mode 100644 index 00000000000..d6864f5b58c --- /dev/null +++ b/build/pkgs/free_fonts/spkg-configure.m4 @@ -0,0 +1,16 @@ +SAGE_SPKG_CONFIGURE([free_fonts], [ + sage_spkg_install_free_fonts=yes + m4_foreach([font], + [FreeSerif.ttf,FreeSerif.otf], + [ + AC_MSG_CHECKING([for ]font) + AS_IF([kpsewhich ]font[ >& AS_MESSAGE_LOG_FD 2>&1], [ + AC_MSG_RESULT([yes]) + sage_spkg_install_free_fonts=no + break + ], [ + AC_MSG_RESULT([no]) + ]) + ]) +]) + diff --git a/build/pkgs/free_fonts/type b/build/pkgs/free_fonts/type new file mode 100644 index 00000000000..134d9bc32d5 --- /dev/null +++ b/build/pkgs/free_fonts/type @@ -0,0 +1 @@ +optional diff --git a/build/pkgs/freetype/distros/macports.txt b/build/pkgs/freetype/distros/macports.txt index 098479093ff..a2e684ddd92 100644 --- a/build/pkgs/freetype/distros/macports.txt +++ b/build/pkgs/freetype/distros/macports.txt @@ -1 +1,2 @@ -freetype +# Broken as of 2022-05-01 +#freetype diff --git a/build/pkgs/freetype/distros/opensuse.txt b/build/pkgs/freetype/distros/opensuse.txt index 33f8f6b7bdd..9205ba71e27 100644 --- a/build/pkgs/freetype/distros/opensuse.txt +++ b/build/pkgs/freetype/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(freetype2)" +pkgconfig(freetype2) diff --git a/build/pkgs/furo/spkg-install.in b/build/pkgs/furo/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/furo/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/gc/distros/fedora.txt b/build/pkgs/gc/distros/fedora.txt index 1d6df64a216..b6940f8b6aa 100644 --- a/build/pkgs/gc/distros/fedora.txt +++ b/build/pkgs/gc/distros/fedora.txt @@ -1 +1,2 @@ -gc gc-devel +gc +gc-devel diff --git a/build/pkgs/gc/distros/opensuse.txt b/build/pkgs/gc/distros/opensuse.txt index 4620f6a8cb4..f250631fcc2 100644 --- a/build/pkgs/gc/distros/opensuse.txt +++ b/build/pkgs/gc/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(bdw-gc)" +pkgconfig(bdw-gc) diff --git a/build/pkgs/gf2x/distros/fedora.txt b/build/pkgs/gf2x/distros/fedora.txt index 726d8da490c..3d1d2bb46bb 100644 --- a/build/pkgs/gf2x/distros/fedora.txt +++ b/build/pkgs/gf2x/distros/fedora.txt @@ -1 +1,2 @@ -gf2x gf2x-devel +gf2x +gf2x-devel diff --git a/build/pkgs/gf2x/distros/opensuse.txt b/build/pkgs/gf2x/distros/opensuse.txt index 9a15ad0abe3..9fb7b9fd16e 100644 --- a/build/pkgs/gf2x/distros/opensuse.txt +++ b/build/pkgs/gf2x/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(gf2x)" +pkgconfig(gf2x) diff --git a/build/pkgs/gfortran/distros/macports.txt b/build/pkgs/gfortran/distros/macports.txt index c2878adf893..dfa7190f158 100644 --- a/build/pkgs/gfortran/distros/macports.txt +++ b/build/pkgs/gfortran/distros/macports.txt @@ -1 +1,2 @@ -gcc10 +gfortran +gcc10 ++gfortran diff --git a/build/pkgs/giac/distros/arch.txt b/build/pkgs/giac/distros/arch.txt index 7bdbd844d6c..f54c3286e4f 100644 --- a/build/pkgs/giac/distros/arch.txt +++ b/build/pkgs/giac/distros/arch.txt @@ -1 +1,2 @@ -libgiac giac +libgiac +giac diff --git a/build/pkgs/givaro/distros/fedora.txt b/build/pkgs/givaro/distros/fedora.txt index 6848d8c4e7f..9016d00aaab 100644 --- a/build/pkgs/givaro/distros/fedora.txt +++ b/build/pkgs/givaro/distros/fedora.txt @@ -1 +1,2 @@ -givaro givaro-devel +givaro +givaro-devel diff --git a/build/pkgs/givaro/distros/opensuse.txt b/build/pkgs/givaro/distros/opensuse.txt index 2a8103e6f6b..8de5fadae90 100644 --- a/build/pkgs/givaro/distros/opensuse.txt +++ b/build/pkgs/givaro/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(givaro)" +pkgconfig(givaro) diff --git a/build/pkgs/glpk/distros/cygwin.txt b/build/pkgs/glpk/distros/cygwin.txt index 2e6c6a10cb8..0fbb959079e 100644 --- a/build/pkgs/glpk/distros/cygwin.txt +++ b/build/pkgs/glpk/distros/cygwin.txt @@ -1 +1,2 @@ -glpk libglpk-devel +glpk +libglpk-devel diff --git a/build/pkgs/glpk/distros/fedora.txt b/build/pkgs/glpk/distros/fedora.txt index 73ab7f14b14..e028b246574 100644 --- a/build/pkgs/glpk/distros/fedora.txt +++ b/build/pkgs/glpk/distros/fedora.txt @@ -1 +1,3 @@ -glpk glpk-devel glpk-utils +glpk +glpk-devel +glpk-utils diff --git a/build/pkgs/gmp/distros/fedora.txt b/build/pkgs/gmp/distros/fedora.txt index bbe9ee39cab..1436ed982e7 100644 --- a/build/pkgs/gmp/distros/fedora.txt +++ b/build/pkgs/gmp/distros/fedora.txt @@ -1 +1,2 @@ -gmp gmp-devel +gmp +gmp-devel diff --git a/build/pkgs/gnumake_tokenpool/checksums.ini b/build/pkgs/gnumake_tokenpool/checksums.ini index 62f631ea40a..e79058d27e3 100644 --- a/build/pkgs/gnumake_tokenpool/checksums.ini +++ b/build/pkgs/gnumake_tokenpool/checksums.ini @@ -1,5 +1,5 @@ tarball=gnumake_tokenpool-VERSION-py3-none-any.whl -sha1=a060f03e0306a85bc1a91a450e457be83ed371e9 -md5=834ccc4d6d52741c5eabac1bdb8f39b2 -cksum=1679797266 +sha1=3dfcc8c466c17f974d90694f81f4481c3d84aecc +md5=5dae4c65e9609853085ae1970d4fe143 +cksum=612213211 upstream_url=https://pypi.io/packages/py3/g/gnumake_tokenpool/gnumake_tokenpool-VERSION-py3-none-any.whl diff --git a/build/pkgs/gnumake_tokenpool/install-requires.txt b/build/pkgs/gnumake_tokenpool/install-requires.txt index 0ee4452edd3..759ca97a680 100644 --- a/build/pkgs/gnumake_tokenpool/install-requires.txt +++ b/build/pkgs/gnumake_tokenpool/install-requires.txt @@ -1 +1 @@ -gnumake-tokenpool +gnumake-tokenpool >= 0.0.4 diff --git a/build/pkgs/gnumake_tokenpool/package-version.txt b/build/pkgs/gnumake_tokenpool/package-version.txt index bcab45af15a..81340c7e72d 100644 --- a/build/pkgs/gnumake_tokenpool/package-version.txt +++ b/build/pkgs/gnumake_tokenpool/package-version.txt @@ -1 +1 @@ -0.0.3 +0.0.4 diff --git a/build/pkgs/gsl/distros/fedora.txt b/build/pkgs/gsl/distros/fedora.txt index 5577d09957b..ce35d3d80bd 100644 --- a/build/pkgs/gsl/distros/fedora.txt +++ b/build/pkgs/gsl/distros/fedora.txt @@ -1 +1,2 @@ -gsl gsl-devel +gsl +gsl-devel diff --git a/build/pkgs/gsl/distros/opensuse.txt b/build/pkgs/gsl/distros/opensuse.txt index ccfee4f4e43..c1867648576 100644 --- a/build/pkgs/gsl/distros/opensuse.txt +++ b/build/pkgs/gsl/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(gsl)" +pkgconfig(gsl) diff --git a/build/pkgs/hatch_fancy_pypi_readme/checksums.ini b/build/pkgs/hatch_fancy_pypi_readme/checksums.ini index 6d48eb14be8..6da100dad5a 100644 --- a/build/pkgs/hatch_fancy_pypi_readme/checksums.ini +++ b/build/pkgs/hatch_fancy_pypi_readme/checksums.ini @@ -1,5 +1,5 @@ -tarball=hatch_fancy_pypi_readme-VERSION.tar.gz -sha1=8c8568bb86bdc65133e9d8b27493a464fa3320da -md5=8755cce1a4a4d5e5d84992089801acbf -cksum=2176903739 -upstream_url=https://pypi.io/packages/source/h/hatch_fancy_pypi_readme/hatch_fancy_pypi_readme-VERSION.tar.gz +tarball=hatch_fancy_pypi_readme-VERSION-py3-none-any.whl +sha1=4076ea14577b3c711a8345498d8f91b1c8a13d09 +md5=d7acd13333f6c71dcbfa62420c7f257b +cksum=1527082323 +upstream_url=https://pypi.io/packages/py3/h/hatch_fancy_pypi_readme/hatch_fancy_pypi_readme-VERSION-py3-none-any.whl diff --git a/build/pkgs/hatch_fancy_pypi_readme/dependencies b/build/pkgs/hatch_fancy_pypi_readme/dependencies index cfb7c484697..36380aee4e7 100644 --- a/build/pkgs/hatch_fancy_pypi_readme/dependencies +++ b/build/pkgs/hatch_fancy_pypi_readme/dependencies @@ -1,4 +1,4 @@ - | $(PYTHON_TOOLCHAIN) hatchling $(PYTHON) +hatchling | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/hatch_fancy_pypi_readme/spkg-install.in b/build/pkgs/hatch_fancy_pypi_readme/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/hatch_fancy_pypi_readme/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/hatch_vcs/SPKG.rst b/build/pkgs/hatch_vcs/SPKG.rst index 51f4780749e..6c11d8d95fb 100644 --- a/build/pkgs/hatch_vcs/SPKG.rst +++ b/build/pkgs/hatch_vcs/SPKG.rst @@ -9,6 +9,8 @@ Hatch plugin for versioning with your preferred VCS License ------- +MIT + Upstream Contact ---------------- diff --git a/build/pkgs/hatch_vcs/checksums.ini b/build/pkgs/hatch_vcs/checksums.ini index 9c1290bda3b..e9908b1540e 100644 --- a/build/pkgs/hatch_vcs/checksums.ini +++ b/build/pkgs/hatch_vcs/checksums.ini @@ -1,5 +1,5 @@ -tarball=hatch_vcs-VERSION.tar.gz -sha1=026b964066b38fd7e823900817fb9ea7af3f8d9b -md5=c2f2cbe6851b7b2969cb4aa24c4b9b2f -cksum=588874896 -upstream_url=https://pypi.io/packages/source/h/hatch_vcs/hatch_vcs-VERSION.tar.gz +tarball=hatch_vcs-VERSION-py3-none-any.whl +sha1=a4da813bf9a745ed2020bf462f4bc19a1ab7fc11 +md5=82bee9889b95170e550c98f8dd11bc61 +cksum=1575327634 +upstream_url=https://pypi.io/packages/py3/h/hatch_vcs/hatch_vcs-VERSION-py3-none-any.whl diff --git a/build/pkgs/hatch_vcs/dependencies b/build/pkgs/hatch_vcs/dependencies index cfb7c484697..36380aee4e7 100644 --- a/build/pkgs/hatch_vcs/dependencies +++ b/build/pkgs/hatch_vcs/dependencies @@ -1,4 +1,4 @@ - | $(PYTHON_TOOLCHAIN) hatchling $(PYTHON) +hatchling | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/hatch_vcs/package-version.txt b/build/pkgs/hatch_vcs/package-version.txt index 0d91a54c7d4..1d0ba9ea182 100644 --- a/build/pkgs/hatch_vcs/package-version.txt +++ b/build/pkgs/hatch_vcs/package-version.txt @@ -1 +1 @@ -0.3.0 +0.4.0 diff --git a/build/pkgs/hatch_vcs/spkg-install.in b/build/pkgs/hatch_vcs/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/hatch_vcs/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/hatchling/checksums.ini b/build/pkgs/hatchling/checksums.ini index d21781abeba..5d8b02696c5 100644 --- a/build/pkgs/hatchling/checksums.ini +++ b/build/pkgs/hatchling/checksums.ini @@ -1,5 +1,5 @@ -tarball=hatchling-VERSION.tar.gz -sha1=f3db8639e9bee89e2e2420d1bc7a048a910622c9 -md5=43f7203cacb6c3c178b93149b8a8151d -cksum=235277633 -upstream_url=https://pypi.io/packages/source/h/hatchling/hatchling-VERSION.tar.gz +tarball=hatchling-VERSION-py3-none-any.whl +sha1=aa9d69b9dd820716440252d737a4aeaf9b4e541f +md5=20e5ea4deea21f91759fb2269b71f0dd +cksum=446304413 +upstream_url=https://pypi.io/packages/py3/h/hatchling/hatchling-VERSION-py3-none-any.whl diff --git a/build/pkgs/hatchling/dependencies b/build/pkgs/hatchling/dependencies index 479f1630979..b1769861625 100644 --- a/build/pkgs/hatchling/dependencies +++ b/build/pkgs/hatchling/dependencies @@ -1,4 +1,4 @@ - pathspec tomli editables pluggy packaging trove_classifiers | $(PYTHON_TOOLCHAIN) $(PYTHON) + pathspec tomli editables pluggy packaging trove_classifiers | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/hatchling/package-version.txt b/build/pkgs/hatchling/package-version.txt index 84cc529467b..39893559155 100644 --- a/build/pkgs/hatchling/package-version.txt +++ b/build/pkgs/hatchling/package-version.txt @@ -1 +1 @@ -1.18.0 +1.20.0 diff --git a/build/pkgs/hatchling/spkg-install.in b/build/pkgs/hatchling/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/hatchling/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/igraph/checksums.ini b/build/pkgs/igraph/checksums.ini index 279cba457a9..51192799072 100644 --- a/build/pkgs/igraph/checksums.ini +++ b/build/pkgs/igraph/checksums.ini @@ -1,5 +1,5 @@ tarball=igraph-VERSION.tar.gz -sha1=fc3c6627f889b13581b2b468e1b16aceff453cfc -md5=10a3f325425970c75a7ba8359376e208 -cksum=3103730646 +sha1=40efbd2adf3c1cc0a2bb3e14f4c7898d053f1fe4 +md5=87d287445c44fdd19ad67a25e0e0859b +cksum=2559618807 upstream_url=https://github.com/igraph/igraph/releases/download/VERSION/igraph-VERSION.tar.gz diff --git a/build/pkgs/igraph/distros/fedora.txt b/build/pkgs/igraph/distros/fedora.txt index 8ca7a112d45..fa2dc51a2ce 100644 --- a/build/pkgs/igraph/distros/fedora.txt +++ b/build/pkgs/igraph/distros/fedora.txt @@ -1 +1,2 @@ -igraph igraph-devel +igraph +igraph-devel diff --git a/build/pkgs/igraph/package-version.txt b/build/pkgs/igraph/package-version.txt index 9b40aa6c214..1a46c7f13e7 100644 --- a/build/pkgs/igraph/package-version.txt +++ b/build/pkgs/igraph/package-version.txt @@ -1 +1 @@ -0.10.4 +0.10.8 diff --git a/build/pkgs/igraph/spkg-configure.m4 b/build/pkgs/igraph/spkg-configure.m4 index 30b5fcf9c53..5133fce98da 100644 --- a/build/pkgs/igraph/spkg-configure.m4 +++ b/build/pkgs/igraph/spkg-configure.m4 @@ -1,7 +1,9 @@ SAGE_SPKG_CONFIGURE([igraph], [ SAGE_SPKG_DEPCHECK([glpk openblas gmp], [ dnl check for igraph with pkg-config - PKG_CHECK_MODULES([IGRAPH], [igraph >= 0.10 igraph < 0.11], [], [ + dnl Per upstream in https://github.com/sagemath/sage/pull/36750#issuecomment-1826998762: + dnl each python-igraph release is only guaranteed to be compatible with the same C/igraph that it bundles + PKG_CHECK_MODULES([IGRAPH], [igraph >= 0.10.8 igraph < 0.10.9], [], [ sage_spkg_install_igraph=yes]) ]) ]) diff --git a/build/pkgs/iml/distros/fedora.txt b/build/pkgs/iml/distros/fedora.txt index 32307096d65..88a895a10f6 100644 --- a/build/pkgs/iml/distros/fedora.txt +++ b/build/pkgs/iml/distros/fedora.txt @@ -1 +1,2 @@ -iml iml-devel +iml +iml-devel diff --git a/build/pkgs/importlib_metadata/checksums.ini b/build/pkgs/importlib_metadata/checksums.ini index 8c978b57c5b..506ef54e9a5 100644 --- a/build/pkgs/importlib_metadata/checksums.ini +++ b/build/pkgs/importlib_metadata/checksums.ini @@ -1,5 +1,5 @@ -tarball=importlib_metadata-VERSION.tar.gz -sha1=0e5742cd1d559863573bfb4f6cb7ca9ad8dcf466 -md5=c04c814eee1abf42790cfa4bd0454af1 -cksum=1038169537 -upstream_url=https://pypi.io/packages/source/i/importlib_metadata/importlib_metadata-VERSION.tar.gz +tarball=importlib_metadata-VERSION-py3-none-any.whl +sha1=0e693ba704ac628065bab72a097dad3311213f4b +md5=67eac786f2f9e8bf5879e88ef527250a +cksum=1288292429 +upstream_url=https://pypi.io/packages/py3/i/importlib_metadata/importlib_metadata-VERSION-py3-none-any.whl diff --git a/build/pkgs/importlib_metadata/package-version.txt b/build/pkgs/importlib_metadata/package-version.txt index e029aa99b7d..66ce77b7ead 100644 --- a/build/pkgs/importlib_metadata/package-version.txt +++ b/build/pkgs/importlib_metadata/package-version.txt @@ -1 +1 @@ -6.8.0 +7.0.0 diff --git a/build/pkgs/importlib_metadata/spkg-install.in b/build/pkgs/importlib_metadata/spkg-install.in deleted file mode 100644 index cc03b63f4f2..00000000000 --- a/build/pkgs/importlib_metadata/spkg-install.in +++ /dev/null @@ -1,14 +0,0 @@ -if [ -z "$SAGE_LOCAL" ]; then - echo >&2 "SAGE_LOCAL undefined ... exiting" - echo >&2 "Maybe run 'sage --sh'?" - exit 1 -fi - -cd src - -sdh_pip_install . - -if [ $? -ne 0 ]; then - echo "Error installing importlib_metadata ... exiting" - exit 1 -fi diff --git a/build/pkgs/importlib_resources/checksums.ini b/build/pkgs/importlib_resources/checksums.ini index 39040fbf296..e733e142b52 100644 --- a/build/pkgs/importlib_resources/checksums.ini +++ b/build/pkgs/importlib_resources/checksums.ini @@ -1,5 +1,5 @@ -tarball=importlib_resources-VERSION.tar.gz -sha1=4af82ed75a1672a45157bfa7d09c4dfd0605802a -md5=525d238db212bdec2df06c0d4b479e73 -cksum=1494471486 -upstream_url=https://pypi.io/packages/source/i/importlib_resources/importlib_resources-VERSION.tar.gz +tarball=importlib_resources-VERSION-py3-none-any.whl +sha1=5caa4e8a9ee93123a5c3badb6edbc009b5d8494a +md5=a4ba26d808eed58bde249276da04c9e1 +cksum=2487282894 +upstream_url=https://pypi.io/packages/py3/i/importlib_resources/importlib_resources-VERSION-py3-none-any.whl diff --git a/build/pkgs/importlib_resources/dependencies b/build/pkgs/importlib_resources/dependencies index 655283898b7..30f71335acb 100644 --- a/build/pkgs/importlib_resources/dependencies +++ b/build/pkgs/importlib_resources/dependencies @@ -1,4 +1,4 @@ - zipp | $(PYTHON_TOOLCHAIN) $(PYTHON) +zipp | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/importlib_resources/package-version.txt b/build/pkgs/importlib_resources/package-version.txt index dfda3e0b4f0..f3b5af39e43 100644 --- a/build/pkgs/importlib_resources/package-version.txt +++ b/build/pkgs/importlib_resources/package-version.txt @@ -1 +1 @@ -6.1.0 +6.1.1 diff --git a/build/pkgs/importlib_resources/spkg-install.in b/build/pkgs/importlib_resources/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/importlib_resources/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/info/distros/fedora.txt b/build/pkgs/info/distros/fedora.txt index c0d8f74e0ad..c3ed35de973 100644 --- a/build/pkgs/info/distros/fedora.txt +++ b/build/pkgs/info/distros/fedora.txt @@ -1 +1,2 @@ -texinfo info +texinfo +info diff --git a/build/pkgs/isl/distros/opensuse.txt b/build/pkgs/isl/distros/opensuse.txt index 721c2bb0dcb..ec70829dde7 100644 --- a/build/pkgs/isl/distros/opensuse.txt +++ b/build/pkgs/isl/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(isl)" +pkgconfig(isl) diff --git a/build/pkgs/libatomic_ops/distros/fedora.txt b/build/pkgs/libatomic_ops/distros/fedora.txt index 3417f891c11..d1f77fa5ad7 100644 --- a/build/pkgs/libatomic_ops/distros/fedora.txt +++ b/build/pkgs/libatomic_ops/distros/fedora.txt @@ -1 +1,2 @@ -libatomic_ops libatomic_ops-devel +libatomic_ops +libatomic_ops-devel diff --git a/build/pkgs/libatomic_ops/distros/opensuse.txt b/build/pkgs/libatomic_ops/distros/opensuse.txt index 6e7e1c4cecb..0d82eae1b32 100644 --- a/build/pkgs/libatomic_ops/distros/opensuse.txt +++ b/build/pkgs/libatomic_ops/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(atomic_ops)" +pkgconfig(atomic_ops) diff --git a/build/pkgs/libffi/distros/fedora.txt b/build/pkgs/libffi/distros/fedora.txt index 8d342f491c1..70c40a27925 100644 --- a/build/pkgs/libffi/distros/fedora.txt +++ b/build/pkgs/libffi/distros/fedora.txt @@ -1 +1,2 @@ -libffi libffi-devel +libffi +libffi-devel diff --git a/build/pkgs/libffi/distros/opensuse.txt b/build/pkgs/libffi/distros/opensuse.txt index 1a6986d429e..39fa66806ec 100644 --- a/build/pkgs/libffi/distros/opensuse.txt +++ b/build/pkgs/libffi/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(libffi)" +pkgconfig(libffi) diff --git a/build/pkgs/libgd/distros/fedora.txt b/build/pkgs/libgd/distros/fedora.txt index d27cc48549e..1f276d6eb09 100644 --- a/build/pkgs/libgd/distros/fedora.txt +++ b/build/pkgs/libgd/distros/fedora.txt @@ -1 +1,2 @@ -gd gd-devel +gd +gd-devel diff --git a/build/pkgs/libgd/distros/macports.txt b/build/pkgs/libgd/distros/macports.txt index d44f88f27cc..ee5e3357f06 100644 --- a/build/pkgs/libgd/distros/macports.txt +++ b/build/pkgs/libgd/distros/macports.txt @@ -1 +1,2 @@ -gd2 +# broken as of 2022-05-01 -- and also has too many dependencies +#gd2 diff --git a/build/pkgs/libgd/distros/opensuse.txt b/build/pkgs/libgd/distros/opensuse.txt index 48195aa6b44..bcf953527f8 100644 --- a/build/pkgs/libgd/distros/opensuse.txt +++ b/build/pkgs/libgd/distros/opensuse.txt @@ -1,2 +1,2 @@ gd -"pkgconfig(gdlib)" +pkgconfig(gdlib) diff --git a/build/pkgs/libgd/distros/slackware.txt b/build/pkgs/libgd/distros/slackware.txt index 5d28bb87ae1..442f2e7f440 100644 --- a/build/pkgs/libgd/distros/slackware.txt +++ b/build/pkgs/libgd/distros/slackware.txt @@ -1,3 +1,8 @@ gd # shared library dependencies of gd -fontconfig libXpm libX11 libxcb libXau libXdmcp +fontconfig +libXpm +libX11 +libxcb +libXau +libXdmcp diff --git a/build/pkgs/liblzma/distros/fedora.txt b/build/pkgs/liblzma/distros/fedora.txt index 813a264efd5..87d41237fa8 100644 --- a/build/pkgs/liblzma/distros/fedora.txt +++ b/build/pkgs/liblzma/distros/fedora.txt @@ -1 +1,2 @@ -xz xz-devel +xz +xz-devel diff --git a/build/pkgs/liblzma/distros/opensuse.txt b/build/pkgs/liblzma/distros/opensuse.txt index f84d903df3e..96db709ccb8 100644 --- a/build/pkgs/liblzma/distros/opensuse.txt +++ b/build/pkgs/liblzma/distros/opensuse.txt @@ -1,2 +1,2 @@ xz -"pkgconfig(liblzma)" +pkgconfig(liblzma) diff --git a/build/pkgs/libogg/distros/opensuse.txt b/build/pkgs/libogg/distros/opensuse.txt index 886b7534f7b..cab88ad14f1 100644 --- a/build/pkgs/libogg/distros/opensuse.txt +++ b/build/pkgs/libogg/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(ogg)" +pkgconfig(ogg) diff --git a/build/pkgs/libpng/distros/opensuse.txt b/build/pkgs/libpng/distros/opensuse.txt index 3283fd2e697..40ec3d0a25c 100644 --- a/build/pkgs/libpng/distros/opensuse.txt +++ b/build/pkgs/libpng/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(libpng16)" +pkgconfig(libpng16) diff --git a/build/pkgs/libsemigroups/distros/opensuse.txt b/build/pkgs/libsemigroups/distros/opensuse.txt index aca27d4e0e3..3e58abf59c9 100644 --- a/build/pkgs/libsemigroups/distros/opensuse.txt +++ b/build/pkgs/libsemigroups/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(libsemigroups)" +pkgconfig(libsemigroups) diff --git a/build/pkgs/libtheora/distros/opensuse.txt b/build/pkgs/libtheora/distros/opensuse.txt index 19826d2aea6..156db81fdea 100644 --- a/build/pkgs/libtheora/distros/opensuse.txt +++ b/build/pkgs/libtheora/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(theora)" +pkgconfig(theora) diff --git a/build/pkgs/linbox/distros/opensuse.txt b/build/pkgs/linbox/distros/opensuse.txt index 1a52a7c51d3..efef6e5c743 100644 --- a/build/pkgs/linbox/distros/opensuse.txt +++ b/build/pkgs/linbox/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(linbox)" +pkgconfig(linbox) diff --git a/build/pkgs/m4ri/distros/opensuse.txt b/build/pkgs/m4ri/distros/opensuse.txt index c2a7c2c8f93..ea526e29d8e 100644 --- a/build/pkgs/m4ri/distros/opensuse.txt +++ b/build/pkgs/m4ri/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(m4ri)" +pkgconfig(m4ri) diff --git a/build/pkgs/m4rie/distros/opensuse.txt b/build/pkgs/m4rie/distros/opensuse.txt index 4b8fbfa44df..78287631a6b 100644 --- a/build/pkgs/m4rie/distros/opensuse.txt +++ b/build/pkgs/m4rie/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(m4rie)" +pkgconfig(m4rie) diff --git a/build/pkgs/mathjax/distros/gentoo.txt b/build/pkgs/mathjax/distros/gentoo.txt index a347f8c2348..e0d633a9b98 100644 --- a/build/pkgs/mathjax/distros/gentoo.txt +++ b/build/pkgs/mathjax/distros/gentoo.txt @@ -1 +1 @@ -">=dev-libs/mathjax-3" +>=dev-libs/mathjax-3 diff --git a/build/pkgs/mpc/distros/fedora.txt b/build/pkgs/mpc/distros/fedora.txt index 491a280bb72..19ae194c12c 100644 --- a/build/pkgs/mpc/distros/fedora.txt +++ b/build/pkgs/mpc/distros/fedora.txt @@ -1 +1,2 @@ -libmpc libmpc-devel +libmpc +libmpc-devel diff --git a/build/pkgs/mpfr/distros/opensuse.txt b/build/pkgs/mpfr/distros/opensuse.txt index 564517323f0..dadf66949a4 100644 --- a/build/pkgs/mpfr/distros/opensuse.txt +++ b/build/pkgs/mpfr/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(mpfr)" +pkgconfig(mpfr) diff --git a/build/pkgs/nauty/package-version.txt b/build/pkgs/nauty/package-version.txt index 80803faf1b9..b8635c72de3 100644 --- a/build/pkgs/nauty/package-version.txt +++ b/build/pkgs/nauty/package-version.txt @@ -1 +1 @@ -2.8.8 +2.8.8.p0 diff --git a/build/pkgs/nauty/spkg-configure.m4 b/build/pkgs/nauty/spkg-configure.m4 index 4d5bbcf2091..a0873e355c4 100644 --- a/build/pkgs/nauty/spkg-configure.m4 +++ b/build/pkgs/nauty/spkg-configure.m4 @@ -1,12 +1,9 @@ -# We don't use the "converseg" program, but we need to ensure that we -# only detect nauty >= 2.6 because we use the digraph6 format from -# that version -- and converseg was added in nauty-2.6. -# -# We also don't use the "genposetg" program (added in nauty 2.8) yet. -# We require it here to prepare Sage for the use of the major new features -# added in 2.7 and 2.8 (https://pallini.di.uniroma1.it/changes24-28.txt). +# We use the "genktreeg" program (added in nauty 2.8.8). This ensures that we +# detect nauty >= 2.8.8 and so we can use the major new features added in nauty +# since version 2.6. For instance, we use the digraph6 format from nauty >= 2.6 +# (https://pallini.di.uniroma1.it/changes24-28.txt). AC_DEFUN([SAGE_TEST_NAUTY_PROGS], [ - m4_foreach([nautyprog], [directg, gentourng, geng, genbg, gentreeg, converseg, genposetg], [ + m4_foreach([nautyprog], [directg, gentourng, geng, genbg, gentreeg, genktreeg, genposetg], [ AC_PATH_PROG([$2]nautyprog, [[$1]nautyprog]) AS_IF([test x$[$2]nautyprog = x], [sage_spkg_install_nauty=yes]) ]) diff --git a/build/pkgs/nauty/spkg-install.in b/build/pkgs/nauty/spkg-install.in index 5a2f957511d..a2557c3cd8e 100644 --- a/build/pkgs/nauty/spkg-install.in +++ b/build/pkgs/nauty/spkg-install.in @@ -13,11 +13,12 @@ sdh_make # No install target so we resort to manual copy PROGRAMS=" -addedgeg addptg amtog ancestorg assembleg biplabg catg complg converseg copyg countg cubhamg deledgeg -delptg dimacs2g directg dreadnaut dretodot dretog edgetransg genbg genbgL geng gengL genposetg genquarticg genrang -genspecialg gentourng gentreeg hamheuristic labelg linegraphg listg multig nbrhoodg -newedgeg pickg planarg productg ranlabg shortg showg subdivideg twohamg underlyingg vcolg -watercluster2 NRswitchg" +addedgeg addptg amtog ancestorg assembleg biplabg catg complg converseg copyg +countg countneg cubhamg deledgeg delptg dimacs2g directg dreadnaut dretodot +dretog edgetransg genbg genbgL geng gengL genposetg genquarticg genrang +genspecialg gentourng gentreeg genktreeg hamheuristic labelg linegraphg listg +multig nbrhoodg newedgeg pickg planarg productg ranlabg ransubg shortg showg +subdivideg twohamg underlyingg vcolg watercluster2 NRswitchg" sdh_install $PROGRAMS "$SAGE_LOCAL/bin" sdh_install nauty.h "$SAGE_LOCAL/include/nauty" diff --git a/build/pkgs/nbconvert/spkg-install.in b/build/pkgs/nbconvert/spkg-install.in deleted file mode 100644 index deba1bb42bb..00000000000 --- a/build/pkgs/nbconvert/spkg-install.in +++ /dev/null @@ -1 +0,0 @@ -cd src && sdh_pip_install . diff --git a/build/pkgs/ncurses/distros/opensuse.txt b/build/pkgs/ncurses/distros/opensuse.txt index b31c6886b17..f50c62d6ac4 100644 --- a/build/pkgs/ncurses/distros/opensuse.txt +++ b/build/pkgs/ncurses/distros/opensuse.txt @@ -1,2 +1,2 @@ -"pkgconfig(ncurses)" -"pkgconfig(ncursesw)" +pkgconfig(ncurses) +pkgconfig(ncursesw) diff --git a/build/pkgs/networkx/checksums.ini b/build/pkgs/networkx/checksums.ini index dd792a15a2e..6daf026581b 100644 --- a/build/pkgs/networkx/checksums.ini +++ b/build/pkgs/networkx/checksums.ini @@ -1,5 +1,5 @@ tarball=networkx-VERSION.tar.gz -sha1=d4b1d6117b7c54db61f6cbec8f0ccfb0f7d47293 -md5=1a9baa93b7fd4470c80e29a7a6d93ccf -cksum=1675580484 +sha1=b12cf95ed8bc3fe568e3c8e023473a3767c43f8d +md5=e81583dcb3d929b60660721912f3faed +cksum=2601544693 upstream_url=https://pypi.io/packages/source/n/networkx/networkx-VERSION.tar.gz diff --git a/build/pkgs/networkx/package-version.txt b/build/pkgs/networkx/package-version.txt index 8c50098d8ae..e4604e3afd0 100644 --- a/build/pkgs/networkx/package-version.txt +++ b/build/pkgs/networkx/package-version.txt @@ -1 +1 @@ -3.1 +3.2.1 diff --git a/build/pkgs/ninja_build/spkg-configure.m4 b/build/pkgs/ninja_build/spkg-configure.m4 index fb6c4f00985..5b83d189801 100644 --- a/build/pkgs/ninja_build/spkg-configure.m4 +++ b/build/pkgs/ninja_build/spkg-configure.m4 @@ -3,8 +3,10 @@ SAGE_SPKG_CONFIGURE( dnl meson_python needs 1.8.2 or later AC_CACHE_CHECK([for ninja >= 1.8.2], [ac_cv_path_NINJA], [ AC_PATH_PROGS_FEATURE_CHECK([NINJA], [ninja], [ + dnl support both two- and three-component version schemes + dnl since samurai (a ninja alternative) uses two ninja_version=`$ac_path_NINJA --version 2>&1 \ - | $SED -n -e 's/\([[0-9]]*\.[[0-9]]*\.[[0-9]]*\).*/\1/p'` + | $SED -n -e 's/\([[0-9]]*\(\.[[0-9]]*\)\{1,2\}\).*/\1/p'` AS_IF([test -n "$ninja_version"], [ AX_COMPARE_VERSION([$ninja_version], [ge], [1.8.2], [ ac_cv_path_NINJA="$ac_path_NINJA" diff --git a/build/pkgs/normaliz/package-version.txt b/build/pkgs/normaliz/package-version.txt index f870be23bad..2377fe517a0 100644 --- a/build/pkgs/normaliz/package-version.txt +++ b/build/pkgs/normaliz/package-version.txt @@ -1 +1 @@ -3.10.1 +3.10.1.p0 diff --git a/build/pkgs/normaliz/patches/flint3_d-torrance.patch b/build/pkgs/normaliz/patches/flint3_d-torrance.patch new file mode 100644 index 00000000000..5a6e36c51c4 --- /dev/null +++ b/build/pkgs/normaliz/patches/flint3_d-torrance.patch @@ -0,0 +1,55 @@ +--- a/source/libnormaliz/vector_operations.h ++++ b/source/libnormaliz/vector_operations.h +@@ -547,7 +547,10 @@ + + fmpq_poly_fit_length(flp, n); + for (size_t i = 0; i < poly_vector.size(); ++i) { +- fmpq_poly_set_coeff_mpq(flp, (slong)i, poly_vector[i].get_mpq_t()); ++ fmpq_t fcurrent_coeff; ++ fmpq_init(fcurrent_coeff); ++ fmpq_set_mpq(fcurrent_coeff, poly_vector[i].get_mpq_t()); ++ fmpq_poly_set_coeff_fmpq(flp, (slong)i, fcurrent_coeff); + } + } + +@@ -560,8 +563,11 @@ + poly_vector.resize(length); + for (slong i = 0; i < length; i++) { + mpq_t current_coeff; ++ fmpq_t fcurrent_coeff; + mpq_init(current_coeff); +- fmpq_poly_get_coeff_mpq(current_coeff, flp, (slong)i); ++ fmpq_init(fcurrent_coeff); ++ fmpq_poly_get_coeff_fmpq(fcurrent_coeff, flp, (slong)i); ++ fmpq_get_mpq(current_coeff, fcurrent_coeff); + poly_vector[i] = mpq_class(current_coeff); + } + } +--- a/source/libnormaliz/HilbertSeries.cpp ++++ b/source/libnormaliz/HilbertSeries.cpp +@@ -72,7 +72,10 @@ + slong n = (slong)nmzp.size(); + fmpz_poly_fit_length(flp, n); + for (size_t i = 0; i < nmzp.size(); ++i) { +- fmpz_poly_set_coeff_mpz(flp, (slong)i, nmzp[i].get_mpz_t()); ++ fmpz_t fc; ++ fmpz_init(fc); ++ fmpz_set_mpz(fc, nmzp[i].get_mpz_t()); ++ fmpz_poly_set_coeff_fmpz(flp, (slong)i, fc); + } + } + +@@ -80,9 +83,12 @@ + size_t n = (size_t)fmpz_poly_length(flp); + nmzp.resize(n); + mpz_t c; ++ fmpz_t fc; + mpz_init(c); ++ fmpz_init(fc); + for (size_t i = 0; i < nmzp.size(); ++i) { +- fmpz_poly_get_coeff_mpz(c, flp, i); ++ fmpz_poly_get_coeff_fmpz(fc, flp, i); ++ fmpz_get_mpz(c, fc); + nmzp[i] = mpz_class(c); + } + mpz_clear(c); diff --git a/build/pkgs/normaliz/spkg-install.in b/build/pkgs/normaliz/spkg-install.in index 0d329656614..683a3200e5b 100644 --- a/build/pkgs/normaliz/spkg-install.in +++ b/build/pkgs/normaliz/spkg-install.in @@ -8,6 +8,8 @@ cd src # that an error will be signalled if FLINT or E-ANTIC cannot be found, rather # than building normaliz without it. +export ac_cv_lib_flint_fmpz_poly_set_coeff_mpz=yes + sdh_configure --with-flint --with-e-antic --with-nauty sdh_make sdh_make_install diff --git a/build/pkgs/openblas/distros/cygwin.txt b/build/pkgs/openblas/distros/cygwin.txt index d2146131e38..055fa2733d1 100644 --- a/build/pkgs/openblas/distros/cygwin.txt +++ b/build/pkgs/openblas/distros/cygwin.txt @@ -1 +1,2 @@ -liblapack-devel libopenblas +liblapack-devel +libopenblas diff --git a/build/pkgs/openssl/distros/fedora.txt b/build/pkgs/openssl/distros/fedora.txt index dda63a9f276..a9579db4fca 100644 --- a/build/pkgs/openssl/distros/fedora.txt +++ b/build/pkgs/openssl/distros/fedora.txt @@ -1 +1,2 @@ -openssl openssl-devel +openssl +openssl-devel diff --git a/build/pkgs/openssl/distros/slackware.txt b/build/pkgs/openssl/distros/slackware.txt index 6ed59c09128..14c745a6bc8 100644 --- a/build/pkgs/openssl/distros/slackware.txt +++ b/build/pkgs/openssl/distros/slackware.txt @@ -1 +1,2 @@ -openssl openssl-solibs +openssl +openssl-solibs diff --git a/build/pkgs/pari/distros/conda.txt b/build/pkgs/pari/distros/conda.txt index 88ec4bef346..018d16817d3 100644 --- a/build/pkgs/pari/distros/conda.txt +++ b/build/pkgs/pari/distros/conda.txt @@ -1,3 +1,6 @@ pari=*=*_pthread # We add these data packages because they are checked by spkg-configure.m4 -pari-elldata pari-galdata pari-galpol pari-seadata +pari-elldata +pari-galdata +pari-galpol +pari-seadata diff --git a/build/pkgs/pari/distros/fedora.txt b/build/pkgs/pari/distros/fedora.txt index 95ba141d56c..d315900766c 100644 --- a/build/pkgs/pari/distros/fedora.txt +++ b/build/pkgs/pari/distros/fedora.txt @@ -2,7 +2,8 @@ pari-devel # spkg-configure checks for gp, gphelp. Access to the documentation is crucial # for the cypari2 build. #29342: By default configuration in /etc/dnf/dnf.conf, # installation of documentation may be suppressed; we override this. -pari-gp --setopt=tsflags= +pari-gp +--setopt=tsflags= # spkg-configure checks for data pari-galdata pari-galpol diff --git a/build/pkgs/pari/distros/gentoo.txt b/build/pkgs/pari/distros/gentoo.txt index 449975ac8e1..cd13d54e8cc 100644 --- a/build/pkgs/pari/distros/gentoo.txt +++ b/build/pkgs/pari/distros/gentoo.txt @@ -1 +1,2 @@ -sci-mathematics/pari sci-mathematics/pari-data +sci-mathematics/pari +sci-mathematics/pari-data diff --git a/build/pkgs/pari/distros/macports.txt b/build/pkgs/pari/distros/macports.txt index 67abbc9dec6..8960baaba3e 100644 --- a/build/pkgs/pari/distros/macports.txt +++ b/build/pkgs/pari/distros/macports.txt @@ -1 +1,2 @@ -pari +# incomplete, unusable for sage, causes cysignals build failure +#pari diff --git a/build/pkgs/pathspec/checksums.ini b/build/pkgs/pathspec/checksums.ini index a98c270d6e1..a562884cca1 100644 --- a/build/pkgs/pathspec/checksums.ini +++ b/build/pkgs/pathspec/checksums.ini @@ -1,5 +1,5 @@ -tarball=pathspec-VERSION.tar.gz -sha1=418ae4112af18af995c0f20a22e5a903b8ce50ae -md5=28c87c3581b10152c4581d10fe33f765 -cksum=2161527634 -upstream_url=https://pypi.io/packages/source/p/pathspec/pathspec-VERSION.tar.gz +tarball=pathspec-VERSION-py3-none-any.whl +sha1=e31b7b2b1a59ab192eb2e92ac283211a11039769 +md5=53caa061bbda861c5b4766f41b084ec8 +cksum=1745881358 +upstream_url=https://pypi.io/packages/py3/p/pathspec/pathspec-VERSION-py3-none-any.whl diff --git a/build/pkgs/pathspec/dependencies b/build/pkgs/pathspec/dependencies index 47296a7bace..644ad35f773 100644 --- a/build/pkgs/pathspec/dependencies +++ b/build/pkgs/pathspec/dependencies @@ -1,4 +1,4 @@ - | $(PYTHON_TOOLCHAIN) $(PYTHON) + | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/pathspec/package-version.txt b/build/pkgs/pathspec/package-version.txt index 5eef0f10e8c..34a83616bb5 100644 --- a/build/pkgs/pathspec/package-version.txt +++ b/build/pkgs/pathspec/package-version.txt @@ -1 +1 @@ -0.10.2 +0.12.1 diff --git a/build/pkgs/pathspec/spkg-install.in b/build/pkgs/pathspec/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/pathspec/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/perl_term_readline_gnu/distros/opensuse.txt b/build/pkgs/perl_term_readline_gnu/distros/opensuse.txt index ba80f6c445f..60563e056ca 100644 --- a/build/pkgs/perl_term_readline_gnu/distros/opensuse.txt +++ b/build/pkgs/perl_term_readline_gnu/distros/opensuse.txt @@ -1 +1 @@ -"perl(Term::ReadLine::Gnu)" +perl(Term::ReadLine::Gnu) diff --git a/build/pkgs/pip/checksums.ini b/build/pkgs/pip/checksums.ini index 52c2edb31f2..0558c5caa45 100644 --- a/build/pkgs/pip/checksums.ini +++ b/build/pkgs/pip/checksums.ini @@ -1,5 +1,5 @@ -tarball=pip-VERSION.tar.gz -sha1=d1400a4eb662e4741ac68957f47bc97d600743f8 -md5=f0c9fba61e9d9badcc9921062e993d84 -cksum=309527365 -upstream_url=https://pypi.io/packages/source/p/pip/pip-VERSION.tar.gz +tarball=pip-VERSION-py3-none-any.whl +sha1=4b2baddc0673f73017e531648a9ee27e47925e7a +md5=5d2d058044a3ae2800d18e358ddc72ca +cksum=1470281176 +upstream_url=https://pypi.io/packages/py3/p/pip/pip-VERSION-py3-none-any.whl diff --git a/build/pkgs/pip/dependencies b/build/pkgs/pip/dependencies index dac3579f7e3..d45a397db36 100644 --- a/build/pkgs/pip/dependencies +++ b/build/pkgs/pip/dependencies @@ -1,4 +1,4 @@ - setuptools wheel | $(PYTHON) + | $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/pip/spkg-install.in b/build/pkgs/pip/spkg-install.in index 651f5c1dc1e..567543149db 100644 --- a/build/pkgs/pip/spkg-install.in +++ b/build/pkgs/pip/spkg-install.in @@ -1,11 +1,6 @@ -cd src +# pip can install its own wheel! But first we need to ensure that the +# wheel file is on the PYTHONPATH +export PYTHONPATH=$(pwd)/$(cd dist && for w in *.whl; do cp $w ..; echo $w; break; done) -sdh_setup_bdist_wheel - -# pip can install its own wheel! But first we need to ensure that the pip -# source directory in on the PYTHONPATH -export PYTHONPATH="$(pwd)/src" - -# --ignore-installed makes sure that pip does not mistake -# its own source tree as an existing installation -sdh_store_and_pip_install_wheel --ignore-installed . +# This line is the same as what sage-spkg uses to install the wheel. +sdh_store_and_pip_install_wheel . diff --git a/build/pkgs/pip/spkg-pipinst.in b/build/pkgs/pip/spkg-pipinst.in index 3e3f6bbc94e..61007a3b8c8 100644 --- a/build/pkgs/pip/spkg-pipinst.in +++ b/build/pkgs/pip/spkg-pipinst.in @@ -1,5 +1,3 @@ -cd src - # pip can install its own wheel! But first we need to ensure that the pip -# source directory in on the PYTHONPATH -export PYTHONPATH="$(pwd)/src" +# wheelfile is on the PYTHONPATH +export PYTHONPATH=$(pwd)/$(echo *.whl) diff --git a/build/pkgs/planarity/distros/fedora.txt b/build/pkgs/planarity/distros/fedora.txt index b107ebbf96f..e3d211ca5d1 100644 --- a/build/pkgs/planarity/distros/fedora.txt +++ b/build/pkgs/planarity/distros/fedora.txt @@ -1 +1,2 @@ -planarity planarity-devel +planarity +planarity-devel diff --git a/build/pkgs/platformdirs/checksums.ini b/build/pkgs/platformdirs/checksums.ini index 99113c48626..3757f701faf 100644 --- a/build/pkgs/platformdirs/checksums.ini +++ b/build/pkgs/platformdirs/checksums.ini @@ -1,5 +1,5 @@ -tarball=platformdirs-VERSION.tar.gz -sha1=82e215dc9c45eedf9168584fede36d795714f677 -md5=a6ba3a442347fac346982acb597c8bf8 -cksum=2465457023 -upstream_url=https://pypi.io/packages/source/p/platformdirs/platformdirs-VERSION.tar.gz +tarball=platformdirs-VERSION-py3-none-any.whl +sha1=cafa761738da959f2df0a8a92da4c72fd8eaf93e +md5=487007776ff343efc509b68d08cd7fd7 +cksum=162426958 +upstream_url=https://pypi.io/packages/py3/p/platformdirs/platformdirs-VERSION-py3-none-any.whl diff --git a/build/pkgs/platformdirs/dependencies b/build/pkgs/platformdirs/dependencies index 952ebfb66cd..644ad35f773 100644 --- a/build/pkgs/platformdirs/dependencies +++ b/build/pkgs/platformdirs/dependencies @@ -1,4 +1,4 @@ - setuptools_scm | $(PYTHON_TOOLCHAIN) hatchling hatch_vcs $(PYTHON) + | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/platformdirs/package-version.txt b/build/pkgs/platformdirs/package-version.txt index afad818663d..ee74734aa22 100644 --- a/build/pkgs/platformdirs/package-version.txt +++ b/build/pkgs/platformdirs/package-version.txt @@ -1 +1 @@ -3.11.0 +4.1.0 diff --git a/build/pkgs/platformdirs/spkg-install.in b/build/pkgs/platformdirs/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/platformdirs/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/pluggy/dependencies b/build/pkgs/pluggy/dependencies index 47296a7bace..644ad35f773 100644 --- a/build/pkgs/pluggy/dependencies +++ b/build/pkgs/pluggy/dependencies @@ -1,4 +1,4 @@ - | $(PYTHON_TOOLCHAIN) $(PYTHON) + | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/polylib/distros/opensuse.txt b/build/pkgs/polylib/distros/opensuse.txt index f6432c31dfe..8b7f1e54de7 100644 --- a/build/pkgs/polylib/distros/opensuse.txt +++ b/build/pkgs/polylib/distros/opensuse.txt @@ -1,2 +1,2 @@ polylib -"pkgconfig(polylibgmp)" +pkgconfig(polylibgmp) diff --git a/build/pkgs/ptyprocess/distros/conda.txt b/build/pkgs/ptyprocess/distros/conda.txt index 4a518435c60..964d3f79453 100644 --- a/build/pkgs/ptyprocess/distros/conda.txt +++ b/build/pkgs/ptyprocess/distros/conda.txt @@ -1,3 +1,3 @@ # The version should be fixed to 0.5.1 (see https://github.com/sagemath/sage/issues/32147), but this is not available on conda-forge -# thus don't install ptyprocess with conda, but let pip handle it +# thus don't install ptyprocess with conda, but let pip handle it # ptyprocess diff --git a/build/pkgs/pynormaliz/package-version.txt b/build/pkgs/pynormaliz/package-version.txt index fc249e9a747..fae0ceb2953 100644 --- a/build/pkgs/pynormaliz/package-version.txt +++ b/build/pkgs/pynormaliz/package-version.txt @@ -1 +1 @@ -2.18 +2.18.p0 diff --git a/build/pkgs/python3/distros/macports.txt b/build/pkgs/python3/distros/macports.txt index 6a2d05c5edb..92826c681b4 100644 --- a/build/pkgs/python3/distros/macports.txt +++ b/build/pkgs/python3/distros/macports.txt @@ -1 +1 @@ -python39 +python310 diff --git a/build/pkgs/python_igraph/checksums.ini b/build/pkgs/python_igraph/checksums.ini index 7247680193c..e3ba512eb8f 100644 --- a/build/pkgs/python_igraph/checksums.ini +++ b/build/pkgs/python_igraph/checksums.ini @@ -1,5 +1,5 @@ tarball=python-igraph-VERSION.tar.gz -sha1=807a95ad4080d8eb500e7797325d6f11a5c46892 -md5=2ac3561dda7e7321789041261a29aba4 -cksum=754615899 +sha1=ef7ee85cb1bc83109c744d5dd6bbe5e37598ce3f +md5=788bd70bd286651774f15b20af956081 +cksum=1447848766 upstream_url=https://pypi.io/packages/source/i/igraph/igraph-VERSION.tar.gz diff --git a/build/pkgs/python_igraph/package-version.txt b/build/pkgs/python_igraph/package-version.txt index 9b40aa6c214..1a96df19c09 100644 --- a/build/pkgs/python_igraph/package-version.txt +++ b/build/pkgs/python_igraph/package-version.txt @@ -1 +1 @@ -0.10.4 +0.11.3 diff --git a/build/pkgs/qhull/distros/macports.txt b/build/pkgs/qhull/distros/macports.txt index 95d316779cf..703b7aadad9 100644 --- a/build/pkgs/qhull/distros/macports.txt +++ b/build/pkgs/qhull/distros/macports.txt @@ -1 +1,2 @@ -qhull +# broken as of 2022-05-01 +#qhull diff --git a/build/pkgs/r/distros/conda.txt b/build/pkgs/r/distros/conda.txt index 42e26b8d8ed..4c235733c5f 100644 --- a/build/pkgs/r/distros/conda.txt +++ b/build/pkgs/r/distros/conda.txt @@ -1 +1,2 @@ -r r-essentials +r +r-essentials diff --git a/build/pkgs/r/distros/fedora.txt b/build/pkgs/r/distros/fedora.txt index a5148a636ee..088b10653bb 100644 --- a/build/pkgs/r/distros/fedora.txt +++ b/build/pkgs/r/distros/fedora.txt @@ -1 +1,2 @@ -R R-devel +R +R-devel diff --git a/build/pkgs/r/distros/macports.txt b/build/pkgs/r/distros/macports.txt index 331bae08fb7..5798a47ae13 100644 --- a/build/pkgs/r/distros/macports.txt +++ b/build/pkgs/r/distros/macports.txt @@ -1 +1,2 @@ -R +# Broken as of 2022-05-01, and too many dependencies (X11) +# R diff --git a/build/pkgs/readline/distros/opensuse.txt b/build/pkgs/readline/distros/opensuse.txt index fffe7fdb306..66fd20246e7 100644 --- a/build/pkgs/readline/distros/opensuse.txt +++ b/build/pkgs/readline/distros/opensuse.txt @@ -1,3 +1,3 @@ readline-devel # not available on Leap 15.2: -"pkgconfig(readline)" +pkgconfig(readline) diff --git a/build/pkgs/referencing/dependencies b/build/pkgs/referencing/dependencies index 12067bf5c3e..39c6d3527b3 100644 --- a/build/pkgs/referencing/dependencies +++ b/build/pkgs/referencing/dependencies @@ -1,4 +1,4 @@ -attrs | $(PYTHON_TOOLCHAIN) $(PYTHON) +attrs pyrsistent | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index f58f8ff4bbb..3a9ab385d78 100644 --- a/build/pkgs/sage_conf/install-requires.txt +++ b/build/pkgs/sage_conf/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-conf ~= 10.3b3 +sage-conf ~= 10.3b4 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index 74baf1b835d..0c2be2f77db 100644 --- a/build/pkgs/sage_docbuild/install-requires.txt +++ b/build/pkgs/sage_docbuild/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-docbuild ~= 10.3b3 +sage-docbuild ~= 10.3b4 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index 352120f20fb..9e7d5a7398a 100644 --- a/build/pkgs/sage_setup/install-requires.txt +++ b/build/pkgs/sage_setup/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-setup ~= 10.3b3 +sage-setup ~= 10.3b4 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index f0a5a420fcb..d7e9353d351 100644 --- a/build/pkgs/sage_sws2rst/install-requires.txt +++ b/build/pkgs/sage_sws2rst/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-sws2rst ~= 10.3b3 +sage-sws2rst ~= 10.3b4 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index 7bf049c6a0c..4fddbc66d5f 100644 --- a/build/pkgs/sagelib/install-requires.txt +++ b/build/pkgs/sagelib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-standard ~= 10.3b3 +sagemath-standard ~= 10.3b4 diff --git a/build/pkgs/sagemath_bliss/install-requires.txt b/build/pkgs/sagemath_bliss/install-requires.txt index 0c4fe90f245..24bd560a768 100644 --- a/build/pkgs/sagemath_bliss/install-requires.txt +++ b/build/pkgs/sagemath_bliss/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-bliss ~= 10.3b3 +sagemath-bliss ~= 10.3b4 diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index c4de485cea4..73fde138fd8 100644 --- a/build/pkgs/sagemath_categories/install-requires.txt +++ b/build/pkgs/sagemath_categories/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-categories ~= 10.3b3 +sagemath-categories ~= 10.3b4 diff --git a/build/pkgs/sagemath_coxeter3/install-requires.txt b/build/pkgs/sagemath_coxeter3/install-requires.txt index 5f8c399c22f..0a7cf53f9cb 100644 --- a/build/pkgs/sagemath_coxeter3/install-requires.txt +++ b/build/pkgs/sagemath_coxeter3/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-coxeter3 ~= 10.3b3 +sagemath-coxeter3 ~= 10.3b4 diff --git a/build/pkgs/sagemath_doc_pdf/dependencies b/build/pkgs/sagemath_doc_pdf/dependencies index 21eb5295b36..7e3e7f136d2 100644 --- a/build/pkgs/sagemath_doc_pdf/dependencies +++ b/build/pkgs/sagemath_doc_pdf/dependencies @@ -1 +1 @@ -sagemath_doc_html texlive +sagemath_doc_html texlive texlive_luatex free_fonts xindy diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index 336f2357697..f2de063f119 100644 --- a/build/pkgs/sagemath_environment/install-requires.txt +++ b/build/pkgs/sagemath_environment/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-environment ~= 10.3b3 +sagemath-environment ~= 10.3b4 diff --git a/build/pkgs/sagemath_mcqd/install-requires.txt b/build/pkgs/sagemath_mcqd/install-requires.txt index 1c73893daab..f67c3865111 100644 --- a/build/pkgs/sagemath_mcqd/install-requires.txt +++ b/build/pkgs/sagemath_mcqd/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-mcqd ~= 10.3b3 +sagemath-mcqd ~= 10.3b4 diff --git a/build/pkgs/sagemath_meataxe/install-requires.txt b/build/pkgs/sagemath_meataxe/install-requires.txt index 0e070b2b415..d574ec0df6d 100644 --- a/build/pkgs/sagemath_meataxe/install-requires.txt +++ b/build/pkgs/sagemath_meataxe/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-meataxe ~= 10.3b3 +sagemath-meataxe ~= 10.3b4 diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index f341b061e8b..73ce709a5f5 100644 --- a/build/pkgs/sagemath_objects/install-requires.txt +++ b/build/pkgs/sagemath_objects/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-objects ~= 10.3b3 +sagemath-objects ~= 10.3b4 diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index 4a0e58e79ce..c9acb9a7e0b 100644 --- a/build/pkgs/sagemath_repl/install-requires.txt +++ b/build/pkgs/sagemath_repl/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-repl ~= 10.3b3 +sagemath-repl ~= 10.3b4 diff --git a/build/pkgs/sagemath_sirocco/install-requires.txt b/build/pkgs/sagemath_sirocco/install-requires.txt index 4737ab2e562..8fd980605d7 100644 --- a/build/pkgs/sagemath_sirocco/install-requires.txt +++ b/build/pkgs/sagemath_sirocco/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-sirocco ~= 10.3b3 +sagemath-sirocco ~= 10.3b4 diff --git a/build/pkgs/sagemath_tdlib/install-requires.txt b/build/pkgs/sagemath_tdlib/install-requires.txt index bbf9579b01b..377b21f5a09 100644 --- a/build/pkgs/sagemath_tdlib/install-requires.txt +++ b/build/pkgs/sagemath_tdlib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-tdlib ~= 10.3b3 +sagemath-tdlib ~= 10.3b4 diff --git a/build/pkgs/setuptools/checksums.ini b/build/pkgs/setuptools/checksums.ini index 150e3c25335..1a88d2a7464 100644 --- a/build/pkgs/setuptools/checksums.ini +++ b/build/pkgs/setuptools/checksums.ini @@ -1,5 +1,5 @@ -tarball=setuptools-VERSION.tar.gz -sha1=b0c9b16863c57d70adc22651906eea7eaee09803 -md5=d967ca2ba7f46db887daee2d5c9bd6a2 -cksum=2346145273 -upstream_url=https://pypi.io/packages/source/s/setuptools/setuptools-VERSION.tar.gz +tarball=setuptools-VERSION-py3-none-any.whl +sha1=4227225bb193e3a45542f45966caf777d4c913e8 +md5=f096ed836f4036a11aa277fa16dc09ff +cksum=263664173 +upstream_url=https://pypi.io/packages/py3/s/setuptools/setuptools-VERSION-py3-none-any.whl diff --git a/build/pkgs/setuptools/dependencies b/build/pkgs/setuptools/dependencies index d45a397db36..644ad35f773 100644 --- a/build/pkgs/setuptools/dependencies +++ b/build/pkgs/setuptools/dependencies @@ -1,4 +1,4 @@ - | $(PYTHON) + | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/setuptools/package-version.txt b/build/pkgs/setuptools/package-version.txt index fc312b9c8c1..2c021f541a8 100644 --- a/build/pkgs/setuptools/package-version.txt +++ b/build/pkgs/setuptools/package-version.txt @@ -1 +1 @@ -68.2.2 +69.0.2 diff --git a/build/pkgs/setuptools/spkg-install.in b/build/pkgs/setuptools/spkg-install.in deleted file mode 100644 index 09a8b8f65ce..00000000000 --- a/build/pkgs/setuptools/spkg-install.in +++ /dev/null @@ -1,5 +0,0 @@ -cd src -# Use --single-version-externally-managed to prevent setuptools from installing itself with easy_install -python3 setup.py --no-user-cfg install \ - --single-version-externally-managed --root="$SAGE_DESTDIR" || \ - sdh_die "Error building / installing setuptools for Python ${vers}" diff --git a/build/pkgs/setuptools_wheel/SPKG.rst b/build/pkgs/setuptools_wheel/SPKG.rst deleted file mode 100644 index c78602a296a..00000000000 --- a/build/pkgs/setuptools_wheel/SPKG.rst +++ /dev/null @@ -1,5 +0,0 @@ -setuptools_wheel: Build the setuptools package as a wheel -========================================================= - -After installing setuptools and wheel, we build a wheel of setuptools -to complete the set of wheels stored in our wheelhouse. diff --git a/build/pkgs/setuptools_wheel/checksums.ini b/build/pkgs/setuptools_wheel/checksums.ini deleted file mode 120000 index 4f64d3ce107..00000000000 --- a/build/pkgs/setuptools_wheel/checksums.ini +++ /dev/null @@ -1 +0,0 @@ -../setuptools/checksums.ini \ No newline at end of file diff --git a/build/pkgs/setuptools_wheel/dependencies b/build/pkgs/setuptools_wheel/dependencies deleted file mode 100644 index dac3579f7e3..00000000000 --- a/build/pkgs/setuptools_wheel/dependencies +++ /dev/null @@ -1,4 +0,0 @@ - setuptools wheel | $(PYTHON) - ----------- -All lines of this file are ignored except the first. diff --git a/build/pkgs/setuptools_wheel/distros b/build/pkgs/setuptools_wheel/distros deleted file mode 120000 index b22be5c01a6..00000000000 --- a/build/pkgs/setuptools_wheel/distros +++ /dev/null @@ -1 +0,0 @@ -../setuptools/distros \ No newline at end of file diff --git a/build/pkgs/setuptools_wheel/install-requires.txt b/build/pkgs/setuptools_wheel/install-requires.txt deleted file mode 120000 index c5cfb4ff0a9..00000000000 --- a/build/pkgs/setuptools_wheel/install-requires.txt +++ /dev/null @@ -1 +0,0 @@ -../setuptools/install-requires.txt \ No newline at end of file diff --git a/build/pkgs/setuptools_wheel/package-version.txt b/build/pkgs/setuptools_wheel/package-version.txt deleted file mode 120000 index 5268dbec8f6..00000000000 --- a/build/pkgs/setuptools_wheel/package-version.txt +++ /dev/null @@ -1 +0,0 @@ -../setuptools/package-version.txt \ No newline at end of file diff --git a/build/pkgs/setuptools_wheel/spkg-configure.m4 b/build/pkgs/setuptools_wheel/spkg-configure.m4 deleted file mode 100644 index db71392a8b0..00000000000 --- a/build/pkgs/setuptools_wheel/spkg-configure.m4 +++ /dev/null @@ -1 +0,0 @@ -SAGE_SPKG_CONFIGURE([setuptools_wheel], [SAGE_PYTHON_PACKAGE_CHECK([setuptools_wheel])]) diff --git a/build/pkgs/setuptools_wheel/spkg-install.in b/build/pkgs/setuptools_wheel/spkg-install.in deleted file mode 100644 index 7fdd493b5aa..00000000000 --- a/build/pkgs/setuptools_wheel/spkg-install.in +++ /dev/null @@ -1,3 +0,0 @@ -cd src -sdh_setup_bdist_wheel -sdh_store_wheel . diff --git a/build/pkgs/setuptools_wheel/type b/build/pkgs/setuptools_wheel/type deleted file mode 100644 index a6a7b9cd726..00000000000 --- a/build/pkgs/setuptools_wheel/type +++ /dev/null @@ -1 +0,0 @@ -standard diff --git a/build/pkgs/sqlite/distros/opensuse.txt b/build/pkgs/sqlite/distros/opensuse.txt index e5831abec57..80861d24415 100644 --- a/build/pkgs/sqlite/distros/opensuse.txt +++ b/build/pkgs/sqlite/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(sqlite3)" +pkgconfig(sqlite3) diff --git a/build/pkgs/suitesparse/distros/fedora.txt b/build/pkgs/suitesparse/distros/fedora.txt index 473f5afeb82..add9f88182c 100644 --- a/build/pkgs/suitesparse/distros/fedora.txt +++ b/build/pkgs/suitesparse/distros/fedora.txt @@ -1 +1,2 @@ -suitesparse suitesparse-devel +suitesparse +suitesparse-devel diff --git a/build/pkgs/suitesparse/distros/gentoo.txt b/build/pkgs/suitesparse/distros/gentoo.txt index 3b1b625f3e6..36650ca82e3 100644 --- a/build/pkgs/suitesparse/distros/gentoo.txt +++ b/build/pkgs/suitesparse/distros/gentoo.txt @@ -1 +1,4 @@ -sci-libs/amd sci-libs/cholmod sci-libs/suitesparseconfig sci-libs/umfpack +sci-libs/amd +sci-libs/cholmod +sci-libs/suitesparseconfig +sci-libs/umfpack diff --git a/build/pkgs/suitesparse/distros/macports.txt b/build/pkgs/suitesparse/distros/macports.txt index 45d8956e69e..93b99b56740 100644 --- a/build/pkgs/suitesparse/distros/macports.txt +++ b/build/pkgs/suitesparse/distros/macports.txt @@ -1 +1,2 @@ -SuiteSparse +# broken as of 2022-05-01 +#SuiteSparse diff --git a/build/pkgs/tachyon/distros/fedora.txt b/build/pkgs/tachyon/distros/fedora.txt index b1ee1e1bdbe..035020a8d5b 100644 --- a/build/pkgs/tachyon/distros/fedora.txt +++ b/build/pkgs/tachyon/distros/fedora.txt @@ -1 +1,2 @@ -tachyon tachyon-devel +tachyon +tachyon-devel diff --git a/build/pkgs/texlive_luatex/SPKG.rst b/build/pkgs/texlive_luatex/SPKG.rst new file mode 100644 index 00000000000..0bb7f65eb8b --- /dev/null +++ b/build/pkgs/texlive_luatex/SPKG.rst @@ -0,0 +1,21 @@ +texlive_luatex: LuaTeX packages +=============================== + +Description +----------- + +Packages for LuaTeX, a TeX engine using Lua as an embedded scripting and +extension language, with native support for Unicode, OpenType/TrueType fonts, +and both PDF and DVI output. + +The purpose of this dummy package is to associate system package lists with it. + +License +------- + +GNU General Public License version 2.0 (GPLv2) + +Upstream Contact +---------------- + +https://www.luatex.org/ diff --git a/build/pkgs/texlive_luatex/dependencies b/build/pkgs/texlive_luatex/dependencies new file mode 100644 index 00000000000..ba0ee3a029f --- /dev/null +++ b/build/pkgs/texlive_luatex/dependencies @@ -0,0 +1 @@ +texlive diff --git a/build/pkgs/texlive_luatex/distros/alpine.txt b/build/pkgs/texlive_luatex/distros/alpine.txt new file mode 100644 index 00000000000..d2b702df88a --- /dev/null +++ b/build/pkgs/texlive_luatex/distros/alpine.txt @@ -0,0 +1 @@ +texlive-luatex diff --git a/build/pkgs/texlive_luatex/distros/arch.txt b/build/pkgs/texlive_luatex/distros/arch.txt new file mode 100644 index 00000000000..2eec092a978 --- /dev/null +++ b/build/pkgs/texlive_luatex/distros/arch.txt @@ -0,0 +1 @@ +texlive-collection-luatex diff --git a/build/pkgs/texlive_luatex/distros/cygwin.txt b/build/pkgs/texlive_luatex/distros/cygwin.txt new file mode 100644 index 00000000000..ba0ee3a029f --- /dev/null +++ b/build/pkgs/texlive_luatex/distros/cygwin.txt @@ -0,0 +1 @@ +texlive diff --git a/build/pkgs/texlive_luatex/distros/debian.txt b/build/pkgs/texlive_luatex/distros/debian.txt new file mode 100644 index 00000000000..d2b702df88a --- /dev/null +++ b/build/pkgs/texlive_luatex/distros/debian.txt @@ -0,0 +1 @@ +texlive-luatex diff --git a/build/pkgs/texlive_luatex/distros/fedora.txt b/build/pkgs/texlive_luatex/distros/fedora.txt new file mode 100644 index 00000000000..d2b702df88a --- /dev/null +++ b/build/pkgs/texlive_luatex/distros/fedora.txt @@ -0,0 +1 @@ +texlive-luatex diff --git a/build/pkgs/texlive_luatex/distros/gentoo.txt b/build/pkgs/texlive_luatex/distros/gentoo.txt new file mode 100644 index 00000000000..6e651aec020 --- /dev/null +++ b/build/pkgs/texlive_luatex/distros/gentoo.txt @@ -0,0 +1 @@ +dev-texlive/texlive-luatex diff --git a/build/pkgs/texlive_luatex/distros/macports.txt b/build/pkgs/texlive_luatex/distros/macports.txt new file mode 100644 index 00000000000..d2b702df88a --- /dev/null +++ b/build/pkgs/texlive_luatex/distros/macports.txt @@ -0,0 +1 @@ +texlive-luatex diff --git a/build/pkgs/texlive_luatex/distros/opensuse.txt b/build/pkgs/texlive_luatex/distros/opensuse.txt new file mode 100644 index 00000000000..d2b702df88a --- /dev/null +++ b/build/pkgs/texlive_luatex/distros/opensuse.txt @@ -0,0 +1 @@ +texlive-luatex diff --git a/build/pkgs/texlive_luatex/distros/repology.txt b/build/pkgs/texlive_luatex/distros/repology.txt new file mode 100644 index 00000000000..d2b702df88a --- /dev/null +++ b/build/pkgs/texlive_luatex/distros/repology.txt @@ -0,0 +1 @@ +texlive-luatex diff --git a/build/pkgs/texlive_luatex/spkg-configure.m4 b/build/pkgs/texlive_luatex/spkg-configure.m4 new file mode 100644 index 00000000000..6fb53bbc171 --- /dev/null +++ b/build/pkgs/texlive_luatex/spkg-configure.m4 @@ -0,0 +1,10 @@ +SAGE_SPKG_CONFIGURE([texlive_luatex], [ + sage_spkg_install_texlive_luatex=no + AC_MSG_CHECKING([for luaotfload-main.lua]) + AS_IF([kpsewhich luaotfload-main.lua >& AS_MESSAGE_LOG_FD 2>&1], [ + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + sage_spkg_install_texlive_luatex=yes + ]) +]) diff --git a/build/pkgs/texlive_luatex/type b/build/pkgs/texlive_luatex/type new file mode 100644 index 00000000000..134d9bc32d5 --- /dev/null +++ b/build/pkgs/texlive_luatex/type @@ -0,0 +1 @@ +optional diff --git a/build/pkgs/trove_classifiers/checksums.ini b/build/pkgs/trove_classifiers/checksums.ini index d59736dbac2..7350f444667 100644 --- a/build/pkgs/trove_classifiers/checksums.ini +++ b/build/pkgs/trove_classifiers/checksums.ini @@ -1,5 +1,5 @@ -tarball=trove-classifiers-VERSION.tar.gz -sha1=c6821e6c6d57dc2eec2d4156d63cdca939373759 -md5=154ae4cdb69ac37bb35a35c6fbc477cd -cksum=84032195 -upstream_url=https://pypi.io/packages/source/t/trove_classifiers/trove-classifiers-VERSION.tar.gz +tarball=trove_classifiers-VERSION-py3-none-any.whl +sha1=c341abee77b5c87d913b86dc587e544553f0658c +md5=78e67f128f53b8417134429192810701 +cksum=3034057088 +upstream_url=https://pypi.io/packages/py3/t/trove_classifiers/trove_classifiers-VERSION-py3-none-any.whl diff --git a/build/pkgs/trove_classifiers/dependencies b/build/pkgs/trove_classifiers/dependencies index 2134b2a4179..cbe3cae5550 100644 --- a/build/pkgs/trove_classifiers/dependencies +++ b/build/pkgs/trove_classifiers/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) calver | $(PYTHON_TOOLCHAIN) +calver | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/trove_classifiers/package-version.txt b/build/pkgs/trove_classifiers/package-version.txt index b82d6dba095..a33bd2f9968 100644 --- a/build/pkgs/trove_classifiers/package-version.txt +++ b/build/pkgs/trove_classifiers/package-version.txt @@ -1 +1 @@ -2023.11.14 +2023.11.29 diff --git a/build/pkgs/trove_classifiers/spkg-install.in b/build/pkgs/trove_classifiers/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/trove_classifiers/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/virtualenv/checksums.ini b/build/pkgs/virtualenv/checksums.ini index b7def1fa7e0..90a2a903926 100644 --- a/build/pkgs/virtualenv/checksums.ini +++ b/build/pkgs/virtualenv/checksums.ini @@ -1,5 +1,5 @@ tarball=virtualenv-VERSION-py3-none-any.whl -sha1=a17fc6409d29b7e7b1427f37496bfc0fa399f9bf -md5=6374ee91c1ed02956a334aa01d9414ed -cksum=31593789 +sha1=9c942063d76d85361f0567b59cce8238c57f1183 +md5=7dec1148d91180767ae908dc49a7ebf5 +cksum=3612060825 upstream_url=https://pypi.io/packages/py3/v/virtualenv/virtualenv-VERSION-py3-none-any.whl diff --git a/build/pkgs/virtualenv/dependencies b/build/pkgs/virtualenv/dependencies index b0e964bba0c..148ef28948e 100644 --- a/build/pkgs/virtualenv/dependencies +++ b/build/pkgs/virtualenv/dependencies @@ -1,4 +1,4 @@ -distlib filelock platformdirs | $(PYTHON_TOOLCHAIN) $(PYTHON) +distlib filelock platformdirs | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/virtualenv/package-version.txt b/build/pkgs/virtualenv/package-version.txt index b744a5a46cb..242a1e92b72 100644 --- a/build/pkgs/virtualenv/package-version.txt +++ b/build/pkgs/virtualenv/package-version.txt @@ -1 +1 @@ -20.24.4 +20.25.0 diff --git a/build/pkgs/wheel/checksums.ini b/build/pkgs/wheel/checksums.ini index b12a1973b0c..4f2b8c5c534 100644 --- a/build/pkgs/wheel/checksums.ini +++ b/build/pkgs/wheel/checksums.ini @@ -1,5 +1,5 @@ -tarball=wheel-VERSION.tar.gz -sha1=34a787f7069762e267e5ed62ed31cc9c87ea910b -md5=06271a9e90c948b7e93dd7ce0fd90272 -cksum=444550709 -upstream_url=https://pypi.io/packages/source/w/wheel/wheel-VERSION.tar.gz +tarball=wheel-VERSION-py3-none-any.whl +sha1=fcf4ad8d5d8216d661bc98eede0d9210cbc5b697 +md5=779d91395ceb12e15e3a585b30b53f9f +cksum=1421399426 +upstream_url=https://pypi.io/packages/py3/w/wheel/wheel-VERSION-py3-none-any.whl diff --git a/build/pkgs/wheel/dependencies b/build/pkgs/wheel/dependencies index a8e327be793..644ad35f773 100644 --- a/build/pkgs/wheel/dependencies +++ b/build/pkgs/wheel/dependencies @@ -1,4 +1,4 @@ - setuptools | $(PYTHON) + | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/wheel/package-version.txt b/build/pkgs/wheel/package-version.txt index 6599454d402..787ffc30a81 100644 --- a/build/pkgs/wheel/package-version.txt +++ b/build/pkgs/wheel/package-version.txt @@ -1 +1 @@ -0.41.2 +0.42.0 diff --git a/build/pkgs/wheel/spkg-install.in b/build/pkgs/wheel/spkg-install.in deleted file mode 100644 index 5ad5c08fe0e..00000000000 --- a/build/pkgs/wheel/spkg-install.in +++ /dev/null @@ -1,13 +0,0 @@ -cd src - -python3 setup.py --no-user-cfg install \ - --single-version-externally-managed --root="$SAGE_DESTDIR" || \ - sdh_die "Error building / installing package 'wheel'" - -# Now build a wheel so that we have a complete set of wheels. - -# Because of staging, we cannot use the installed 'wheel' package yet. -export PYTHONPATH="$(pwd)/src" - -sdh_setup_bdist_wheel -sdh_store_wheel . diff --git a/build/pkgs/xindy/SPKG.rst b/build/pkgs/xindy/SPKG.rst new file mode 100644 index 00000000000..49733639b2f --- /dev/null +++ b/build/pkgs/xindy/SPKG.rst @@ -0,0 +1,20 @@ +xindy: a general-purpose index processor +======================================== + +Description +----------- + +This dummy package represents xindy: xindy was developed after an impasse had been encountered in the attempt to complete internationalisation of makeindex. Xindy can be used to process indexes for documents marked up using (LA)TEX, Nroff family and SGML-based languages. Xindy is highly configurable, both in markup terms and in terms of the collating order of the text being processed. + +We do not have an SPKG for it. The purpose of this dummy package is to +associate system package lists with it. + +License +------- + +GNU General Public License version 2.0 (GPLv2) + +Upstream Contact +---------------- + +http://www.xindy.org/ diff --git a/build/pkgs/xindy/distros/debian.txt b/build/pkgs/xindy/distros/debian.txt new file mode 100644 index 00000000000..aeb5474c700 --- /dev/null +++ b/build/pkgs/xindy/distros/debian.txt @@ -0,0 +1 @@ +xindy diff --git a/build/pkgs/xindy/distros/macports.txt b/build/pkgs/xindy/distros/macports.txt new file mode 100644 index 00000000000..aeb5474c700 --- /dev/null +++ b/build/pkgs/xindy/distros/macports.txt @@ -0,0 +1 @@ +xindy diff --git a/build/pkgs/xindy/distros/opensuse.txt b/build/pkgs/xindy/distros/opensuse.txt new file mode 100644 index 00000000000..aeb5474c700 --- /dev/null +++ b/build/pkgs/xindy/distros/opensuse.txt @@ -0,0 +1 @@ +xindy diff --git a/build/pkgs/xindy/distros/repology.txt b/build/pkgs/xindy/distros/repology.txt new file mode 100644 index 00000000000..aeb5474c700 --- /dev/null +++ b/build/pkgs/xindy/distros/repology.txt @@ -0,0 +1 @@ +xindy diff --git a/build/pkgs/xindy/spkg-configure.m4 b/build/pkgs/xindy/spkg-configure.m4 new file mode 100644 index 00000000000..07fbe71efa8 --- /dev/null +++ b/build/pkgs/xindy/spkg-configure.m4 @@ -0,0 +1,5 @@ +SAGE_SPKG_CONFIGURE([xindy], [ + sage_spkg_install_xindy=no + AC_PATH_PROG([XINDY], [xindy]) + AS_IF([test -z "$XINDY"], [sage_spkg_install_xindy=yes]) +]) diff --git a/build/pkgs/xindy/type b/build/pkgs/xindy/type new file mode 100644 index 00000000000..134d9bc32d5 --- /dev/null +++ b/build/pkgs/xindy/type @@ -0,0 +1 @@ +optional diff --git a/build/pkgs/zeromq/distros/fedora.txt b/build/pkgs/zeromq/distros/fedora.txt index 901dce11d4f..7ab081d69d9 100644 --- a/build/pkgs/zeromq/distros/fedora.txt +++ b/build/pkgs/zeromq/distros/fedora.txt @@ -1 +1,2 @@ -zeromq zeromq-devel +zeromq +zeromq-devel diff --git a/build/pkgs/zeromq/distros/macports.txt b/build/pkgs/zeromq/distros/macports.txt index 3f0b9927569..11d74369d60 100644 --- a/build/pkgs/zeromq/distros/macports.txt +++ b/build/pkgs/zeromq/distros/macports.txt @@ -1 +1,2 @@ -zmq-devel +# Broken as of 2022-05-01 +#zmq-devel diff --git a/build/pkgs/zeromq/distros/opensuse.txt b/build/pkgs/zeromq/distros/opensuse.txt index bf80cc05be1..1d10c00df82 100644 --- a/build/pkgs/zeromq/distros/opensuse.txt +++ b/build/pkgs/zeromq/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(libzmq)" +pkgconfig(libzmq) diff --git a/build/pkgs/zipp/checksums.ini b/build/pkgs/zipp/checksums.ini index 66cd13339d6..7c9d001b307 100644 --- a/build/pkgs/zipp/checksums.ini +++ b/build/pkgs/zipp/checksums.ini @@ -1,5 +1,5 @@ -tarball=zipp-VERSION.tar.gz -sha1=a9f9aebc205b7829c43b34e79c3f87c42b183176 -md5=a4cf8c530da863c27a04251724436681 -cksum=1303269799 -upstream_url=https://pypi.io/packages/source/z/zipp/zipp-VERSION.tar.gz +tarball=zipp-VERSION-py3-none-any.whl +sha1=8dd92e1b777b02ec6e1ebe72926d32a82c58b246 +md5=d93f0b8485000b37800a6de09ed6c1cb +cksum=3547254189 +upstream_url=https://pypi.io/packages/py3/z/zipp/zipp-VERSION-py3-none-any.whl diff --git a/build/pkgs/zipp/dependencies b/build/pkgs/zipp/dependencies index 995ddecb8f4..644ad35f773 100644 --- a/build/pkgs/zipp/dependencies +++ b/build/pkgs/zipp/dependencies @@ -1,4 +1,4 @@ - | $(PYTHON_TOOLCHAIN) setuptools_scm $(PYTHON) + | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/zipp/spkg-install.in b/build/pkgs/zipp/spkg-install.in deleted file mode 100644 index 6d596586150..00000000000 --- a/build/pkgs/zipp/spkg-install.in +++ /dev/null @@ -1,14 +0,0 @@ -if [ -z "$SAGE_LOCAL" ]; then - echo >&2 "SAGE_LOCAL undefined ... exiting" - echo >&2 "Maybe run 'sage --sh'?" - exit 1 -fi - -cd src - -sdh_pip_install . - -if [ $? -ne 0 ]; then - echo "Error installing zipp ... exiting" - exit 1 -fi diff --git a/build/pkgs/zlib/distros/opensuse.txt b/build/pkgs/zlib/distros/opensuse.txt index 734537742c0..74ff91e4b69 100644 --- a/build/pkgs/zlib/distros/opensuse.txt +++ b/build/pkgs/zlib/distros/opensuse.txt @@ -1 +1 @@ -"pkgconfig(zlib)" +pkgconfig(zlib) diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sagemath-bliss/pyproject.toml.m4 b/pkgs/sagemath-bliss/pyproject.toml.m4 index df61e7fac6a..40bfebf2489 100644 --- a/pkgs/sagemath-bliss/pyproject.toml.m4 +++ b/pkgs/sagemath-bliss/pyproject.toml.m4 @@ -2,7 +2,7 @@ include(`sage_spkg_versions_toml.m4')dnl' -*- conf-toml -*- [build-system] # Minimum requirements for the build system to execute. requires = [ - SPKG_INSTALL_REQUIRES_setuptools_wheel + SPKG_INSTALL_REQUIRES_setuptools SPKG_INSTALL_REQUIRES_sage_conf SPKG_INSTALL_REQUIRES_sage_setup SPKG_INSTALL_REQUIRES_sagemath_environment diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sagemath-categories/pyproject.toml.m4 b/pkgs/sagemath-categories/pyproject.toml.m4 index 72c75ccd11e..eed48a1db15 100644 --- a/pkgs/sagemath-categories/pyproject.toml.m4 +++ b/pkgs/sagemath-categories/pyproject.toml.m4 @@ -2,7 +2,7 @@ include(`sage_spkg_versions_toml.m4')dnl' -*- conf-toml -*- [build-system] # Minimum requirements for the build system to execute. requires = [ - SPKG_INSTALL_REQUIRES_setuptools_wheel + SPKG_INSTALL_REQUIRES_setuptools SPKG_INSTALL_REQUIRES_wheel SPKG_INSTALL_REQUIRES_sage_setup SPKG_INSTALL_REQUIRES_sagemath_environment diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sagemath-coxeter3/pyproject.toml.m4 b/pkgs/sagemath-coxeter3/pyproject.toml.m4 index a8d0e52a4b0..9f9c9dedd5e 100644 --- a/pkgs/sagemath-coxeter3/pyproject.toml.m4 +++ b/pkgs/sagemath-coxeter3/pyproject.toml.m4 @@ -2,7 +2,7 @@ include(`sage_spkg_versions_toml.m4')dnl' -*- conf-toml -*- [build-system] # Minimum requirements for the build system to execute. requires = [ - SPKG_INSTALL_REQUIRES_setuptools_wheel + SPKG_INSTALL_REQUIRES_setuptools SPKG_INSTALL_REQUIRES_sage_setup SPKG_INSTALL_REQUIRES_sagemath_environment SPKG_INSTALL_REQUIRES_cython diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sagemath-environment/pyproject.toml.m4 b/pkgs/sagemath-environment/pyproject.toml.m4 index 4061c8c46eb..44ddd190f99 100644 --- a/pkgs/sagemath-environment/pyproject.toml.m4 +++ b/pkgs/sagemath-environment/pyproject.toml.m4 @@ -2,7 +2,7 @@ include(`sage_spkg_versions_toml.m4')dnl' -*- conf-toml -*- [build-system] # Minimum requirements for the build system to execute. requires = [ - SPKG_INSTALL_REQUIRES_setuptools_wheel + SPKG_INSTALL_REQUIRES_setuptools SPKG_INSTALL_REQUIRES_wheel ] build-backend = "setuptools.build_meta" diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sagemath-mcqd/pyproject.toml.m4 b/pkgs/sagemath-mcqd/pyproject.toml.m4 index c94aface3fd..55a58611334 100644 --- a/pkgs/sagemath-mcqd/pyproject.toml.m4 +++ b/pkgs/sagemath-mcqd/pyproject.toml.m4 @@ -2,7 +2,7 @@ include(`sage_spkg_versions_toml.m4')dnl' -*- conf-toml -*- [build-system] # Minimum requirements for the build system to execute. requires = [ - SPKG_INSTALL_REQUIRES_setuptools_wheel + SPKG_INSTALL_REQUIRES_setuptools SPKG_INSTALL_REQUIRES_sage_setup SPKG_INSTALL_REQUIRES_sagemath_environment SPKG_INSTALL_REQUIRES_cython diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sagemath-meataxe/pyproject.toml.m4 b/pkgs/sagemath-meataxe/pyproject.toml.m4 index 0c8fd46d8be..b4a504c4f1f 100644 --- a/pkgs/sagemath-meataxe/pyproject.toml.m4 +++ b/pkgs/sagemath-meataxe/pyproject.toml.m4 @@ -2,7 +2,7 @@ include(`sage_spkg_versions_toml.m4')dnl' -*- conf-toml -*- [build-system] # Minimum requirements for the build system to execute. requires = [ - SPKG_INSTALL_REQUIRES_setuptools_wheel + SPKG_INSTALL_REQUIRES_setuptools SPKG_INSTALL_REQUIRES_sage_setup SPKG_INSTALL_REQUIRES_sagemath_environment SPKG_INSTALL_REQUIRES_cython diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sagemath-objects/pyproject.toml.m4 b/pkgs/sagemath-objects/pyproject.toml.m4 index 9214f1ffb8d..a8d7d83a44a 100644 --- a/pkgs/sagemath-objects/pyproject.toml.m4 +++ b/pkgs/sagemath-objects/pyproject.toml.m4 @@ -2,7 +2,7 @@ include(`sage_spkg_versions_toml.m4')dnl' -*- conf-toml -*- [build-system] # Minimum requirements for the build system to execute. requires = [ - SPKG_INSTALL_REQUIRES_setuptools_wheel + SPKG_INSTALL_REQUIRES_setuptools SPKG_INSTALL_REQUIRES_wheel SPKG_INSTALL_REQUIRES_sage_setup SPKG_INSTALL_REQUIRES_sagemath_environment diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sagemath-repl/pyproject.toml.m4 b/pkgs/sagemath-repl/pyproject.toml.m4 index dfdfb692c9b..2bc276158a4 100644 --- a/pkgs/sagemath-repl/pyproject.toml.m4 +++ b/pkgs/sagemath-repl/pyproject.toml.m4 @@ -2,7 +2,7 @@ include(`sage_spkg_versions_toml.m4')dnl' -*- conf-toml -*- [build-system] # Minimum requirements for the build system to execute. requires = [ - SPKG_INSTALL_REQUIRES_setuptools_wheel + SPKG_INSTALL_REQUIRES_setuptools SPKG_INSTALL_REQUIRES_wheel ] build-backend = "setuptools.build_meta" diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sagemath-sirocco/pyproject.toml.m4 b/pkgs/sagemath-sirocco/pyproject.toml.m4 index 55e400738d7..6f2874254ab 100644 --- a/pkgs/sagemath-sirocco/pyproject.toml.m4 +++ b/pkgs/sagemath-sirocco/pyproject.toml.m4 @@ -2,7 +2,7 @@ include(`sage_spkg_versions_toml.m4')dnl' -*- conf-toml -*- [build-system] # Minimum requirements for the build system to execute. requires = [ - SPKG_INSTALL_REQUIRES_setuptools_wheel + SPKG_INSTALL_REQUIRES_setuptools SPKG_INSTALL_REQUIRES_sage_setup SPKG_INSTALL_REQUIRES_sagemath_environment SPKG_INSTALL_REQUIRES_cython diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/pkgs/sagemath-tdlib/pyproject.toml.m4 b/pkgs/sagemath-tdlib/pyproject.toml.m4 index 8e3bcdd988f..d3efaf52cc1 100644 --- a/pkgs/sagemath-tdlib/pyproject.toml.m4 +++ b/pkgs/sagemath-tdlib/pyproject.toml.m4 @@ -2,7 +2,7 @@ include(`sage_spkg_versions_toml.m4')dnl' -*- conf-toml -*- [build-system] # Minimum requirements for the build system to execute. requires = [ - SPKG_INSTALL_REQUIRES_setuptools_wheel + SPKG_INSTALL_REQUIRES_setuptools SPKG_INSTALL_REQUIRES_sage_setup SPKG_INSTALL_REQUIRES_sagemath_environment SPKG_INSTALL_REQUIRES_cython diff --git a/src/VERSION.txt b/src/VERSION.txt index 0fca3e3265b..201b86839ab 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.3.beta3 +10.3.beta4 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 55fd24dfdf5..701727e3543 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -4,6 +4,6 @@ # which stops "setup.py develop" from rewriting it as a Python file. : # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='10.3.beta3' -SAGE_RELEASE_DATE='2023-12-18' -SAGE_VERSION_BANNER='SageMath version 10.3.beta3, Release Date: 2023-12-18' +SAGE_VERSION='10.3.beta4' +SAGE_RELEASE_DATE='2023-12-26' +SAGE_VERSION_BANNER='SageMath version 10.3.beta4, Release Date: 2023-12-26' diff --git a/src/doc/bootstrap b/src/doc/bootstrap index b6830ad7bb3..2371945a283 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -19,7 +19,6 @@ fi cd "$SAGE_ROOT" -STRIP_COMMENTS="sed s/#.*//;" OUTPUT_DIR="src/doc/en/installation" mkdir -p "$OUTPUT_DIR" @@ -37,9 +36,8 @@ for SYSTEM in arch debian fedora homebrew opensuse; do DEVELOP_SYSTEM_PACKAGES= for PKG_BASE in $(sage-package list --has-file distros/$SYSTEM.txt); do PKG_SCRIPTS=build/pkgs/$PKG_BASE - SYSTEM_PACKAGES_FILE=$PKG_SCRIPTS/distros/$SYSTEM.txt PKG_TYPE=$(cat $PKG_SCRIPTS/type) - PKG_SYSTEM_PACKAGES=$(echo $(${STRIP_COMMENTS} $SYSTEM_PACKAGES_FILE)) + PKG_SYSTEM_PACKAGES=$(sage-get-system-packages $SYSTEM $PKG_BASE) if [ -n "PKG_SYSTEM_PACKAGES" ]; then if [ -f $PKG_SCRIPTS/spkg-configure.m4 ]; then case "$PKG_BASE:$PKG_TYPE" in @@ -75,10 +73,10 @@ for SYSTEM in arch debian fedora homebrew opensuse; do if [ "${BOOTSTRAP_QUIET}" = "no" ]; then echo >&2 $0:$LINENO: installing "$OUTPUT_DIR"/$SYSTEM"*.txt" fi - echo "$(sage-print-system-package-command $SYSTEM --prompt --sudo install $(echo $(echo $SYSTEM_PACKAGES | xargs -n 1 echo | sort | uniq)))" > "$OUTPUT_DIR"/$SYSTEM.txt - echo "$(sage-print-system-package-command $SYSTEM --prompt --sudo install $(echo $(echo $OPTIONAL_SYSTEM_PACKAGES | xargs -n 1 echo | sort | uniq)))" > "$OUTPUT_DIR"/$SYSTEM-optional.txt - echo "$(sage-print-system-package-command $SYSTEM --prompt --sudo install $(echo $(echo $RECOMMENDED_SYSTEM_PACKAGES | xargs -n 1 echo | sort | uniq)))" > "$OUTPUT_DIR"/$SYSTEM-recommended.txt - echo "$(sage-print-system-package-command $SYSTEM --prompt --sudo install $(echo $(echo $DEVELOP_SYSTEM_PACKAGES | xargs -n 1 echo | sort | uniq)))" > "$OUTPUT_DIR"/$SYSTEM-develop.txt + echo "$(sage-print-system-package-command $SYSTEM --prompt --wrap --sudo install $(echo $(echo $SYSTEM_PACKAGES | xargs -n 1 echo | sort | uniq)))" > "$OUTPUT_DIR"/$SYSTEM.txt + echo "$(sage-print-system-package-command $SYSTEM --prompt --wrap --sudo install $(echo $(echo $OPTIONAL_SYSTEM_PACKAGES | xargs -n 1 echo | sort | uniq)))" > "$OUTPUT_DIR"/$SYSTEM-optional.txt + echo "$(sage-print-system-package-command $SYSTEM --prompt --wrap --sudo install $(echo $(echo $RECOMMENDED_SYSTEM_PACKAGES | xargs -n 1 echo | sort | uniq)))" > "$OUTPUT_DIR"/$SYSTEM-recommended.txt + echo "$(sage-print-system-package-command $SYSTEM --prompt --wrap --sudo install $(echo $(echo $DEVELOP_SYSTEM_PACKAGES | xargs -n 1 echo | sort | uniq)))" > "$OUTPUT_DIR"/$SYSTEM-develop.txt done OUTPUT_DIR="src/doc/en/reference/spkg" @@ -190,7 +188,7 @@ All External Packages EOF OUTPUT_INDEX="$OUTPUT_DIR"/index_alph.rst -cat >> "$OUTPUT_INDEX" < "$OUTPUT_DIR"/$PKG_BASE.rst - echo >> "$OUTPUT_INDEX" " $PKG_BASE" + echo " $PKG_BASE" done -cat >> "$OUTPUT_INDEX" < "$OUTPUT_INDEX" +sage-package list --has-file SPKG.rst | OUTPUT_DIR=$OUTPUT_DIR OUTPUT_RST=1 xargs -P 0 -n 1 sage-spkg-info diff --git a/src/doc/en/developer/coding_in_other.rst b/src/doc/en/developer/coding_in_other.rst index 544add15b88..6fb31770815 100644 --- a/src/doc/en/developer/coding_in_other.rst +++ b/src/doc/en/developer/coding_in_other.rst @@ -714,7 +714,7 @@ dumps the user into an Octave interactive shell: OUTPUT: - An list x (if it exists) which solves M*x = b + A list x (if it exists) which solves M*x = b EXAMPLES:: diff --git a/src/doc/en/developer/packaging.rst b/src/doc/en/developer/packaging.rst index 81b0044b44c..96eb302e2d3 100644 --- a/src/doc/en/developer/packaging.rst +++ b/src/doc/en/developer/packaging.rst @@ -512,10 +512,15 @@ containing files with names like :: arch.txt conda.txt debian.txt + fedora.txt homebrew.txt ... -corresponding to different packaging systems. +corresponding to different packaging systems. Each system package +should appear on a separate line. If the shell-style variable reference +``${PYTHON_MINOR}`` appears, it is replaced by the minor version of +Python, e.g., 12 for Python 3.12.x. Everything on a line after a ``#`` +character is ignored, so comments can be included in the files. For example, if ``./configure`` detects that the Homebrew packaging system is in use, and if the current package can be provided by a diff --git a/src/doc/en/developer/review.rst b/src/doc/en/developer/review.rst index 44a9214b9fe..b2bc38353cb 100644 --- a/src/doc/en/developer/review.rst +++ b/src/doc/en/developer/review.rst @@ -134,7 +134,7 @@ the patches have been applied to a given release, the issue would remain in limbo. **No Patch Bombs**: Code that goes into Sage is peer-reviewed. If -you show up with an 80,000 lines of code bundle that completely +you show up with 80,000 lines of code bundle that completely rips out a subsystem and replaces it with something else, you can imagine that the review process will be a little tedious. These huge patch bombs are problematic for several reasons and we prefer diff --git a/src/doc/en/reference/algebras/lie_algebras.rst b/src/doc/en/reference/algebras/lie_algebras.rst index 23152ac0449..457eb90f14e 100644 --- a/src/doc/en/reference/algebras/lie_algebras.rst +++ b/src/doc/en/reference/algebras/lie_algebras.rst @@ -19,6 +19,7 @@ Lie Algebras sage/algebras/lie_algebras/poincare_birkhoff_witt sage/algebras/lie_algebras/quotient sage/algebras/lie_algebras/rank_two_heisenberg_virasoro + sage/algebras/lie_algebras/representation sage/algebras/lie_algebras/structure_coefficients sage/algebras/lie_algebras/subalgebra sage/algebras/lie_algebras/symplectic_derivation diff --git a/src/doc/en/reference/coercion/index.rst b/src/doc/en/reference/coercion/index.rst index 27459609dc9..73dfd978008 100644 --- a/src/doc/en/reference/coercion/index.rst +++ b/src/doc/en/reference/coercion/index.rst @@ -323,7 +323,7 @@ Methods to implement the function is called on the potential codomain. To indicate that there is no coercion from S to R (self), return ``False`` or ``None``. This is the default behavior. If there is a coercion, - return ``True`` (in which case an morphism using + return ``True`` (in which case a morphism using ``R._element_constructor_`` will be created) or an actual :class:`Morphism` object with S as the domain and R as the codomain. @@ -386,87 +386,97 @@ but that would obscure the main points being made here.) :: - class Localization(Ring): - def __init__(self, primes): - """ - Localization of `\ZZ` away from primes. - """ - Ring.__init__(self, base=ZZ) - self._primes = primes - self._populate_coercion_lists_() - - def _repr_(self): - """ - How to print self. - """ - return "%s localized at %s" % (self.base(), self._primes) - - def _element_constructor_(self, x): - """ - Make sure x is a valid member of self, and return the constructed element. - """ - if isinstance(x, LocalizationElement): - x = x._value - else: - x = QQ(x) - for p, e in x.denominator().factor(): - if p not in self._primes: - raise ValueError("Not integral at %s" % p) - return LocalizationElement(self, x) - - def _coerce_map_from_(self, S): - """ - The only things that coerce into this ring are: - - - the integer ring - - - other localizations away from fewer primes - """ - if S is ZZ: - return True - elif isinstance(S, Localization): - return all(p in self._primes for p in S._primes) - - - class LocalizationElement(RingElement): - - def __init__(self, parent, x): - RingElement.__init__(self, parent) - self._value = x - - - # We're just printing out this way to make it easy to see what's going on in the examples. - - def _repr_(self): - return "LocalElt(%s)" % self._value - - # Now define addition, subtraction, and multiplication of elements. - # Note that left and right always have the same parent. - - def _add_(left, right): - return LocalizationElement(left.parent(), left._value + right._value) - - def _sub_(left, right): - return LocalizationElement(left.parent(), left._value - right._value) - - def _mul_(left, right): - return LocalizationElement(left.parent(), left._value * right._value) - - # The basering was set to ZZ, so c is guaranteed to be in ZZ - - def _rmul_(self, c): - return LocalizationElement(self.parent(), c * self._value) - - def _lmul_(self, c): - return LocalizationElement(self.parent(), self._value * c) + sage: from sage.structure.richcmp import richcmp + sage: from sage.structure.element import Element + + sage: class MyLocalization(Parent): + ....: def __init__(self, primes): + ....: r""" + ....: Localization of `\ZZ` away from primes. + ....: """ + ....: Parent.__init__(self, base=ZZ, category=Rings().Commutative()) + ....: self._primes = primes + ....: self._populate_coercion_lists_() + ....: + ....: def _repr_(self) -> str: + ....: """ + ....: How to print ``self``. + ....: """ + ....: return "%s localized at %s" % (self.base(), self._primes) + ....: + ....: def _element_constructor_(self, x): + ....: """ + ....: Make sure ``x`` is a valid member of ``self``, and return the constructed element. + ....: """ + ....: if isinstance(x, MyLocalizationElement): + ....: x = x._value + ....: else: + ....: x = QQ(x) + ....: for p, e in x.denominator().factor(): + ....: if p not in self._primes: + ....: raise ValueError("not integral at %s" % p) + ....: return self.element_class(self, x) + ....: + ....: def _an_element_(self): + ....: return self.element_class(self, 6) + ....: + ....: def _coerce_map_from_(self, S): + ....: """ + ....: The only things that coerce into this ring are: + ....: + ....: - the integer ring + ....: + ....: - other localizations away from fewer primes + ....: """ + ....: if S is ZZ: + ....: return True + ....: if isinstance(S, MyLocalization): + ....: return all(p in self._primes for p in S._primes) + + sage: class MyLocalizationElement(Element): + ....: + ....: def __init__(self, parent, x): + ....: Element.__init__(self, parent) + ....: self._value = x + ....: + ....: # We are just printing out this way to make it easy to see what's going on in the examples. + ....: + ....: def _repr_(self) -> str: + ....: return f"LocalElt({self._value})" + ....: + ....: # Now define addition, subtraction and multiplication of elements. + ....: # Note that self and right always have the same parent. + ....: + ....: def _add_(self, right): + ....: return self.parent()(self._value + right._value) + ....: + ....: def _sub_(self, right): + ....: return self.parent()(self._value - right._value) + ....: + ....: def _mul_(self, right): + ....: return self.parent()(self._value * right._value) + ....: + ....: # The basering was set to ZZ, so c is guaranteed to be in ZZ + ....: + ....: def _rmul_(self, c): + ....: return self.parent()(c * self._value) + ....: + ....: def _lmul_(self, c): + ....: return self.parent()(self._value * c) + ....: + ....: def _richcmp_(self, other, op): + ....: return richcmp(self._value, other._value, op) + + sage: MyLocalization.element_class = MyLocalizationElement That's all there is to it. Now we can test it out: -.. skip +.. link :: - sage: R = Localization([2]); R + sage: TestSuite(R).run(skip="_test_pickling") + sage: R = MyLocalization([2]); R Integer Ring localized at [2] sage: R(1) LocalElt(1) @@ -475,12 +485,12 @@ That's all there is to it. Now we can test it out: sage: R(1/3) Traceback (most recent call last): ... - ValueError: Not integral at 3 + ValueError: not integral at 3 sage: R.coerce(1) LocalElt(1) sage: R.coerce(1/4) - Traceback (click to the left for traceback) + Traceback (most recent call last): ... TypeError: no canonical coercion from Rational Field to Integer Ring localized at [2] @@ -497,12 +507,10 @@ That's all there is to it. Now we can test it out: sage: R(3/4) * 7 LocalElt(21/4) - sage: R.get_action(ZZ) - Right scalar multiplication by Integer Ring on Integer Ring localized at [2] sage: cm = sage.structure.element.get_coercion_model() sage: cm.explain(R, ZZ, operator.add) Coercion on right operand via - Conversion map: + Coercion map: From: Integer Ring To: Integer Ring localized at [2] Arithmetic performed after coercions. @@ -510,12 +518,15 @@ That's all there is to it. Now we can test it out: Integer Ring localized at [2] sage: cm.explain(R, ZZ, operator.mul) - Action discovered. - Right scalar multiplication by Integer Ring on Integer Ring localized at [2] + Coercion on right operand via + Coercion map: + From: Integer Ring + To: Integer Ring localized at [2] + Arithmetic performed after coercions. Result lives in Integer Ring localized at [2] Integer Ring localized at [2] - sage: R6 = Localization([2,3]); R6 + sage: R6 = MyLocalization([2,3]); R6 Integer Ring localized at [2, 3] sage: R6(1/3) - R(1/2) LocalElt(-1/6) @@ -525,12 +536,12 @@ That's all there is to it. Now we can test it out: sage: R.has_coerce_map_from(ZZ) True sage: R.coerce_map_from(ZZ) - Conversion map: + Coercion map: From: Integer Ring To: Integer Ring localized at [2] sage: R6.coerce_map_from(R) - Conversion map: + Coercion map: From: Integer Ring localized at [2] To: Integer Ring localized at [2, 3] @@ -539,7 +550,7 @@ That's all there is to it. Now we can test it out: sage: cm.explain(R, R6, operator.mul) Coercion on left operand via - Conversion map: + Coercion map: From: Integer Ring localized at [2] To: Integer Ring localized at [2, 3] Arithmetic performed after coercions. diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index d810bed4869..3f207ec0539 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -4520,6 +4520,10 @@ REFERENCES: .. [Mat2002] Jiří Matousek, "Lectures on Discrete Geometry", Springer, 2002 +.. [Mathas2004] Andrew Mathas. + *Matrix units and generic degrees for the Ariki-Koike algebras*. + J. Algebra. **281** (2004) pp. 695-730. + .. [Mas1995] Mason, Geoffrey. *The quantum double of a finite group and its role in conformal field theory*. Groups '93 Galway/St. Andrews, Vol. 2, 405-417, London Math. Soc. Lecture Note Ser., 212, Cambridge, 1995. diff --git a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/elliptic_curves.rst b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/elliptic_curves.rst index d1a2bda863b..6fe991abf45 100644 --- a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/elliptic_curves.rst +++ b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/elliptic_curves.rst @@ -5,7 +5,7 @@ Cremona's Databases ------------------- Cremona's databases of elliptic curves are part of Sage. The curves up -to conductor 10,000 come standard with Sage, and an there is an optional +to conductor 10,000 come standard with Sage, and there is an optional download to gain access to his complete tables. From a shell, you should run :: diff --git a/src/doc/en/thematic_tutorials/numerical_sage/f2py.rst b/src/doc/en/thematic_tutorials/numerical_sage/f2py.rst index 78cea180e2f..57fd4f1b977 100644 --- a/src/doc/en/thematic_tutorials/numerical_sage/f2py.rst +++ b/src/doc/en/thematic_tutorials/numerical_sage/f2py.rst @@ -204,7 +204,7 @@ you only care about its value before the function is called not afterwards. So in the above n tells us how many fiboncci numbers to compute we need to specify this as an input, however we don't need to get n back as it doesn't contain anything new. Similarly A is -intent(out) so we don't need A to have an specific value +intent(out) so we don't need A to have a specific value beforehand, we just care about the contents afterwards. F2py generates a Python function so you only pass those declared intent(in) and supplies empty workspaces for the remaining diff --git a/src/doc/en/thematic_tutorials/sandpile.rst b/src/doc/en/thematic_tutorials/sandpile.rst index 0d7907014b7..9c5c0919bcb 100644 --- a/src/doc/en/thematic_tutorials/sandpile.rst +++ b/src/doc/en/thematic_tutorials/sandpile.rst @@ -2865,7 +2865,7 @@ SandpileConfig **\*** - If ``other`` is an configuration, the recurrent element equivalent + If ``other`` is a configuration, the recurrent element equivalent to the sum. If ``other`` is an integer, the sum of configuration with itself ``other`` times. diff --git a/src/doc/fr/tutorial/conf.py b/src/doc/fr/tutorial/conf.py index 7208ddada17..f44315072ff 100644 --- a/src/doc/fr/tutorial/conf.py +++ b/src/doc/fr/tutorial/conf.py @@ -39,9 +39,6 @@ 'The Sage Group', 'manual'), ] -# Additional LaTeX stuff for the French version -#latex_elements['preamble'] += '\\DeclareUnicodeCharacter{00A0}{\\nobreakspace}\n' - # the definition of \\at in the standard preamble of the sphinx doc # conflicts with that in babel/french[b] latex_elements['preamble'] += '\\let\\at\\undefined' diff --git a/src/doc/ja/a_tour_of_sage/conf.py b/src/doc/ja/a_tour_of_sage/conf.py index bf1f84bf962..451d7cc5b58 100644 --- a/src/doc/ja/a_tour_of_sage/conf.py +++ b/src/doc/ja/a_tour_of_sage/conf.py @@ -25,6 +25,10 @@ name = 'a_tour_of_sage' language = "ja" +# The LaTeX engine to build the docs in Japanese. +# https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-latex_engine +latex_engine = 'uplatex' + # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". html_title = project + " v" + release diff --git a/src/doc/ja/tutorial/conf.py b/src/doc/ja/tutorial/conf.py index 9521bc91828..e4b79bd7875 100644 --- a/src/doc/ja/tutorial/conf.py +++ b/src/doc/ja/tutorial/conf.py @@ -25,6 +25,10 @@ name = 'tutorial-jp' language = "ja" +# The LaTeX engine to build the docs in Japanese. +# https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-latex_engine +latex_engine = 'uplatex' + # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". html_title = project + " v" + release diff --git a/src/doc/ru/tutorial/conf.py b/src/doc/ru/tutorial/conf.py index 0b7a8c4e3db..cda4d9762ed 100644 --- a/src/doc/ru/tutorial/conf.py +++ b/src/doc/ru/tutorial/conf.py @@ -38,6 +38,3 @@ ('index', 'SageTutorial_ru.tex', 'Sage Tutorial in Russian', 'The Sage Development Team', 'manual'), ] - -# Additional LaTeX stuff if necessary: -#latex_elements['preamble'] += '\\DeclareUnicodeCharacter{00A0}{\\nobreakspace}\n' diff --git a/src/pyproject.toml.m4 b/src/pyproject.toml.m4 index 2b61ea041ea..2d60708affa 100644 --- a/src/pyproject.toml.m4 +++ b/src/pyproject.toml.m4 @@ -7,7 +7,7 @@ requires = [ # https://github.com/pypa/pip/issues/6144 esyscmd(`sage-get-system-packages install-requires-toml \ sage_conf \ - setuptools_wheel \ + setuptools \ wheel \ sage_setup \ cypari \ diff --git a/src/sage/algebras/cellular_basis.py b/src/sage/algebras/cellular_basis.py index c80eee401ff..8c474420378 100644 --- a/src/sage/algebras/cellular_basis.py +++ b/src/sage/algebras/cellular_basis.py @@ -164,7 +164,7 @@ class CellularBasis(CombinatorialFreeModule): - C([2, 1], [[1, 3], [2]], [[1, 3], [2]]) + C([3], [[1, 2, 3]], [[1, 2, 3]]) """ - def __init__(self, A): + def __init__(self, A, to_algebra=None, from_algebra=None, **kwargs): r""" Initialize ``self``. @@ -181,21 +181,26 @@ def __init__(self, A): # TODO: Use instead A.category().Realizations() so # operations are defined by coercion? + prefix = kwargs.pop('prefix', 'C') cat = Algebras(A.category().base_ring()).FiniteDimensional().WithBasis().Cellular() CombinatorialFreeModule.__init__(self, A.base_ring(), I, - prefix='C', bracket=False, - category=cat) + prefix=prefix, bracket=False, + category=cat, **kwargs) # Register coercions - if A._to_cellular_element is not NotImplemented: - to_cellular = A.module_morphism(A._to_cellular_element, codomain=self, + if from_algebra is None: + from_algebra = A._to_cellular_element + if to_algebra is None: + to_algebra = A._from_cellular_index + if from_algebra is not NotImplemented: + to_cellular = A.module_morphism(from_algebra, codomain=self, category=cat) - if A._from_cellular_index is NotImplemented: + if to_algebra is NotImplemented: from_cellular = ~to_cellular else: - from_cellular = self.module_morphism(A._from_cellular_index, codomain=A, + from_cellular = self.module_morphism(to_algebra, codomain=A, category=cat) - if A._to_cellular_element is NotImplemented: + if from_algebra is NotImplemented: to_cellular = ~from_cellular to_cellular.register_as_coercion() from_cellular.register_as_coercion() diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index 35facfa7866..a65581f8db1 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -3087,7 +3087,7 @@ def is_cohomologous_to(self, other): def cohomology_class(self): r""" - Return the cohomology class of an homogeneous cycle, as an element + Return the cohomology class of a homogeneous cycle, as an element of the corresponding cohomology group. EXAMPLES:: diff --git a/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py b/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py index 5a3bd2ceb47..4f2a604aa8b 100644 --- a/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py +++ b/src/sage/algebras/hecke_algebras/cubic_hecke_algebra.py @@ -1458,7 +1458,7 @@ def one_basis(self): def _an_element_(self): r""" Overwrite the original method from :mod:`~sage.combinat.free_module` - to obtain an more interesting element for ``TestSuite``. + to obtain a more interesting element for ``TestSuite``. EXAMPLES:: @@ -2233,7 +2233,7 @@ def _braid_image_by_basis_extension(self, braid_tietze): sage: CHA5._basis_extension [[4], [-4], [4, 1]] - case where the braid already has an corresponding basis element:: + case where the braid already has a corresponding basis element:: sage: CHA5._braid_image_by_basis_extension((1,)) # optional - database_cubic_hecke c0 diff --git a/src/sage/algebras/lie_algebras/lie_algebra_element.pxd b/src/sage/algebras/lie_algebras/lie_algebra_element.pxd index 9005eae72fd..227ce2559f9 100644 --- a/src/sage/algebras/lie_algebras/lie_algebra_element.pxd +++ b/src/sage/algebras/lie_algebras/lie_algebra_element.pxd @@ -50,6 +50,7 @@ cdef class LieObject(SageObject): cdef class LieGenerator(LieObject): cdef public str _name + cpdef lift(self, dict UEA_gens_dict) cdef class LieBracket(LieObject): cdef public LieObject _left diff --git a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx index f221fe6ab55..ca53753153b 100644 --- a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx +++ b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx @@ -1232,9 +1232,9 @@ cdef class UntwistedAffineLieAlgebraElement(Element): return type(self)(self._parent, negate(self._t_dict), -self._c_coeff, -self._d_coeff) - cpdef _acted_upon_(self, x, bint self_on_left) noexcept: + cpdef _acted_upon_(self, scalar, bint self_on_left) noexcept: """ - Return ``self`` acted upon by ``x``. + Return ``self`` acted upon by ``scalar``. EXAMPLES:: @@ -1246,9 +1246,21 @@ cdef class UntwistedAffineLieAlgebraElement(Element): sage: -2 * x (-2*E[alpha[1]])#t^0 + (-2*h1)#t^-1 + -6*c + 4/5*d """ - return type(self)(self._parent, scal(x, self._t_dict, self_on_left), - x * self._c_coeff, - x * self._d_coeff) + # This was copied and IDK if it still applies (TCS): + # With the current design, the coercion model does not have + # enough information to detect apriori that this method only + # accepts scalars; so it tries on some elements(), and we need + # to make sure to report an error. + scalar_parent = parent(scalar) + if scalar_parent != self._parent.base_ring(): + # Temporary needed by coercion (see Polynomial/FractionField tests). + if self._parent.base_ring().has_coerce_map_from(scalar_parent): + scalar = self._parent.base_ring()(scalar) + else: + return None + return type(self)(self._parent, scal(scalar, self._t_dict, self_on_left), + scalar * self._c_coeff, + scalar * self._d_coeff) cpdef monomial_coefficients(self, bint copy=True) noexcept: """ @@ -1661,6 +1673,25 @@ cdef class LieGenerator(LieObject): """ return self._word + cpdef lift(self, dict UEA_gens_dict): + """ + Lift ``self`` to the universal enveloping algebra. + + ``UEA_gens_dict`` should be the dictionary for the + generators of the universal enveloping algebra. + + EXAMPLES:: + + sage: L = LieAlgebra(QQ, 'x,y,z') + sage: Lyn = L.Lyndon() + sage: x,y,z = Lyn.gens() + sage: x.lift() + x + sage: x.lift().parent() + Free Algebra on 3 generators (x, y, z) over Rational Field + """ + return UEA_gens_dict[self._name] + cdef class LieBracket(LieObject): """ An abstract Lie bracket (formally, just a binary tree). diff --git a/src/sage/algebras/lie_algebras/representation.py b/src/sage/algebras/lie_algebras/representation.py new file mode 100644 index 00000000000..9d96c42c6fc --- /dev/null +++ b/src/sage/algebras/lie_algebras/representation.py @@ -0,0 +1,435 @@ +r""" +Representations of Lie algebras + +AUTHORS: + +- Travis Scrimshaw (2023-08-31): initial version +""" + +# **************************************************************************** +# Copyright (C) 2023 Travis Scrimshaw +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from sage.sets.family import Family, AbstractFamily +from sage.combinat.free_module import CombinatorialFreeModule +from sage.categories.modules import Modules +from copy import copy + + +class Representation_abstract: + r""" + Mixin class for (left) representations of Lie algebras. + + INPUT: + + - ``lie_algebra`` -- a Lie algebra + """ + def __init__(self, lie_algebra): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: L = lie_algebras.sp(QQ, 6) + sage: R = L.trivial_representation() + sage: TestSuite(R).run() + """ + self._lie_algebra = lie_algebra + + def lie_algebra(self): + r""" + Return the Lie algebra whose representation ``self`` is. + + EXAMPLES:: + + sage: L = lie_algebras.sl(QQ, 4) + sage: R = L.trivial_representation() + sage: R.lie_algebra() is L + True + """ + return self._lie_algebra + + def side(self): + r""" + Return that ``self`` is a left representation. + + OUTPUT: + + - the string ``"left"`` + + EXAMPLES:: + + sage: L = lie_algebras.sl(QQ, 4) + sage: R = L.trivial_representation() + sage: R.side() + 'left' + """ + return 'left' + + def _test_representation(self, **options): + r""" + Check (on some elements) that ``self`` is a representation of the + given Lie algebra using the basis of the Lie algebra. + + EXAMPLES:: + + sage: L = lie_algebras.Heisenberg(QQ, 3) + sage: f = {b: b.adjoint_matrix() for b in L.basis()} + sage: R = L.representation(f) + sage: R._test_representation() + """ + tester = self._tester(**options) + S = tester.some_elements() + elts = self._lie_algebra.basis() + if elts.cardinality() == float('inf'): + elts = list(elts.some_elements()) + from sage.misc.misc import some_tuples + for x, y in some_tuples(elts, 2, tester._max_runs): + for v in S: + tester.assertEqual(x.bracket(y) * v, x * (y * v) - y * (x * v)) + + +class RepresentationByMorphism(CombinatorialFreeModule, Representation_abstract): + r""" + Representation of a Lie algebra defined by a Lie algebra morphism. + + INPUT: + + - ``lie_algebra`` -- a Lie algebra + - ``f`` -- the Lie algebra morphism defining the action of the basis + elements of ``lie_algebra`` + - ``index_set`` -- (optional) the index set of the module basis + - ``on_basis`` -- (default: ``False``) the function ``f`` defines a + map from the basis elements or from a generic element of ``lie_algebra`` + + If ``f`` is encoded as a ``dict`` or ``Family``, then the keys must + be indices of the basis of ``lie_algebra`` and the values being the + corresponding matrix defining the action. This sets ``on_basis=True``. + + EXAMPLES:: + + sage: L. = LieAlgebra(QQ, {('x','y'): {'y':1}}) + sage: f = {x: Matrix([[1,0],[0,0]]), y: Matrix([[0,1],[0,0]])} + sage: L.representation(f) + Representation of Lie algebra on 2 generators (x, y) over Rational Field defined by: + [1 0] + x |--> [0 0] + [0 1] + y |--> [0 0] + + We construct the direct sum of two copies of the trivial representation + for an infinite dimensional Lie algebra:: + + sage: L = lie_algebras.Affine(QQ, ['E',6,1]) + sage: R = L.representation(lambda b: matrix.zero(QQ, 2), index_set=['a','b']) + sage: x = L.an_element() + sage: v = R.an_element(); v + 2*R['a'] + 2*R['b'] + sage: x * v + 0 + + We construct a finite dimensional representation of the affline Lie algebra + of type `A_2^{(1)}`:: + + sage: L = lie_algebras.Affine(QQ, ['A',2,1]).derived_subalgebra() + sage: Phi_plus = list(RootSystem(['A',2]).root_lattice().positive_roots()) + sage: def aff_action(key): + ....: mat = matrix.zero(QQ, 3) + ....: if key == 'c': # central element + ....: return mat + ....: b, ell = key + ....: if b in Phi_plus: # positive root + ....: ind = tuple(sorted(b.to_ambient().support())) + ....: mat[ind] = 1 + ....: if ind[0] + 1 != ind[1]: + ....: mat[ind] = -1 + ....: elif -b in Phi_plus: # negative root + ....: ind = tuple(sorted(b.to_ambient().support(), reverse=True)) + ....: mat[ind] = 1 + ....: if ind[0] - 1 != ind[1]: + ....: mat[ind] = -1 + ....: else: # must be in the Cartan + ....: i = b.leading_support() + ....: mat[i,i] = -1 + ....: mat[i-1,i-1] = 1 + ....: return mat + sage: F = Family(L.basis(), aff_action, name="lifted natural repr") + sage: R = L.representation(index_set=range(1,4), on_basis=F) + sage: x = L.an_element(); x + (E[alpha[2]] + E[alpha[1]] + h1 + h2 + E[-alpha[2]] + E[-alpha[1]])#t^0 + + (E[-alpha[1] - alpha[2]])#t^1 + (E[alpha[1] + alpha[2]])#t^-1 + c + sage: v = R.an_element(); v + 2*R[1] + 2*R[2] + 3*R[3] + sage: x * v + R[1] + 5*R[2] - 3*R[3] + sage: R._test_representation() # verify that it is a representation + """ + @staticmethod + def __classcall_private__(cls, lie_algebra, f=None, index_set=None, on_basis=False, **kwargs): + r""" + Normalize inpute to ensure a unique representation. + + EXAMPLES:: + + sage: L. = LieAlgebra(QQ, {('x','y'): {'y':1}}) + sage: f1 = {'x': Matrix([[1,0],[0,0]]), 'y': Matrix([[0,1],[0,0]])} + sage: R1 = L.representation(f1) + sage: f2 = Family({x: Matrix([[1,0],[0,0]]), y: Matrix(QQ, [[0,1],[0,0]])}) + sage: R2 = L.representation(f2) + sage: R1 is R2 + True + + TESTS:: + + sage: L. = LieAlgebra(QQ, {('x','y'): {'y':1}}) + sage: f = {'x': Matrix([[1,0]]), 'y': Matrix([[0,1]])} + sage: L.representation(f) + Traceback (most recent call last): + ... + ValueError: all matrices must be square + + sage: f = {'x': Matrix([[1,0],[0,0]]), 'y': Matrix([[0]])} + sage: L.representation(f) + Traceback (most recent call last): + ... + ValueError: all matrices must be square of size 2 + + sage: L.representation(index_set=[1,2,3]) + Traceback (most recent call last): + ... + ValueError: either 'f' or 'on_basis' must be specified + sage: L.representation(on_basis=lambda x: QQ.zero()) + Traceback (most recent call last): + ... + ValueError: the index set needs to be specified + """ + from sage.sets.finite_enumerated_set import FiniteEnumeratedSet + base = lie_algebra.base_ring() + C = Modules(base).WithBasis().FiniteDimensional() + C = C.or_subcategory(kwargs.pop('category', C)) + B = lie_algebra.basis() + if not isinstance(on_basis, bool): + f = on_basis + on_basis = True + if isinstance(f, AbstractFamily): + if f.cardinality() < float('inf'): + f = dict(f) + on_basis = True + if isinstance(f, dict): + data = {} + dim = None + for k, mat in f.items(): + if k in B: + k = k.leading_support() + if not mat.is_square(): + raise ValueError("all matrices must be square") + if dim is None: + dim = mat.nrows() + elif mat.nrows() != dim or mat.ncols() != dim: + raise ValueError("all matrices must be square of size {}".format(dim)) + data[k] = mat.change_ring(base) + data[k].set_immutable() + + if index_set is None: + index_set = FiniteEnumeratedSet(range(dim)) + f = Family(data) + on_basis = True + + if f is None: + raise ValueError("either 'f' or 'on_basis' must be specified") + if index_set is None: + raise ValueError("the index set needs to be specified") + + index_set = FiniteEnumeratedSet(index_set) + + return super(cls, RepresentationByMorphism).__classcall__(cls, lie_algebra, + f, index_set, on_basis, category=C, **kwargs) + + def __init__(self, lie_algebra, f, index_set, on_basis, category, **kwargs): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: L. = LieAlgebra(QQ, {('x','y'): {'y':1}}) + sage: f = {'x': Matrix([[1,0],[0,0]]), 'y': Matrix([[0,1],[0,0]])} + sage: R = L.representation(f) + sage: TestSuite(R).run() + """ + if on_basis: + self._family = f + self._f = f.__getitem__ + else: + self._f = f + prefix = kwargs.pop("prefix", 'R') + self._on_basis = on_basis + + Representation_abstract.__init__(self, lie_algebra) + CombinatorialFreeModule.__init__(self, lie_algebra.base_ring(), index_set, + category=category, prefix=prefix, **kwargs) + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: L. = LieAlgebra(QQ, {('x','y'): {'y':1}}) + sage: f = {'x': Matrix([[1,0],[0,0]]), 'y': Matrix([[0,1],[0,0]])} + sage: L.representation(f) + Representation of Lie algebra on 2 generators (x, y) over Rational Field defined by: + [1 0] + x |--> [0 0] + [0 1] + y |--> [0 0] + + sage: L = lie_algebras.Affine(QQ, ['E',6,1]) + sage: F = Family(L.basis(), lambda b: matrix.zero(QQ, 2), name="zero map") + sage: L.representation(F, index_set=['a','b'], on_basis=True) + Representation of Affine Kac-Moody algebra of ['E', 6] in the Chevalley basis defined by: + Lazy family (zero map(i))_{i in Lazy family...} + + sage: L.representation(lambda b: matrix.zero(QQ, 2), index_set=['a','b']) + Representation of Affine Kac-Moody algebra of ['E', 6] in the Chevalley basis defined by: + at 0x...> + """ + ret = "Representation of {} defined by:".format(self._lie_algebra) + from sage.typeset.ascii_art import ascii_art + if self._on_basis: + B = self._lie_algebra.basis() + if B.cardinality() < float('inf'): + for k in B.keys(): + ret += '\n' + repr(ascii_art(B[k], self._f(k), sep=" |--> ", sep_baseline=0)) + else: + ret += '\n' + repr(self._family) + else: + ret += '\n' + repr(self._f) + return ret + + class Element(CombinatorialFreeModule.Element): + def _acted_upon_(self, scalar, self_on_left=False): + r""" + Return the action of ``scalar`` on ``self``. + + EXAMPLES:: + + sage: L. = LieAlgebra(QQ, {('x','y'): {'y':1}}) + sage: f = {'x': Matrix([[1,0],[0,0]]), 'y': Matrix([[0,1],[0,0]])} + sage: R = L.representation(f) + sage: v = R.an_element(); v + 2*R[0] + 2*R[1] + sage: x * v + 2*R[0] + sage: y * v + 2*R[0] + sage: (2*x + 5*y) * v + 14*R[0] + sage: v * x + Traceback (most recent call last): + ... + TypeError: unsupported operand parent(s) for *: ... + + sage: v = sum((i+4) * b for i, b in enumerate(R.basis())); v + 4*R[0] + 5*R[1] + sage: (1/3*x - 5*y) * v + -71/3*R[0] + + sage: L = lie_algebras.Affine(QQ, ['E',6,1]) + sage: F = Family(L.basis(), lambda b: matrix.zero(QQ, 2), name="zero map") + sage: R = L.representation(F, index_set=['a','b'], on_basis=True) + sage: R.an_element() + 2*R['a'] + 2*R['b'] + sage: L.an_element() * R.an_element() + 0 + """ + P = self.parent() + if scalar in P._lie_algebra: + if self_on_left: + return None + if not self: # we are (already) the zero vector + return self + scalar = P._lie_algebra(scalar) + if not scalar: # we are acting by zero + return P.zero() + if P._on_basis: + mat = sum(c * P._f(k) for k, c in scalar.monomial_coefficients(copy=False).items()) + else: + mat = P._f(scalar) + return P.from_vector(mat * self.to_vector()) + + return super()._acted_upon_(scalar, self_on_left) + + +class TrivialRepresentation(CombinatorialFreeModule, Representation_abstract): + r""" + The trivial representation of a Lie algebra. + + The trivial representation of a Lie algebra `L` over a commutative ring + `R` is the `1`-dimensional `R`-module on which every element of `L` + acts by zero. + + INPUT: + + - ``lie_algebra`` -- a Lie algebra + + REFERENCES: + + - :wikipedia:`Trivial_representation` + """ + def __init__(self, lie_algebra, **kwargs): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: L = lie_algebras.VirasoroAlgebra(QQ) + sage: R = L.trivial_representation() + sage: TestSuite(R).run() + """ + R = lie_algebra.base_ring() + cat = Modules(R).WithBasis().FiniteDimensional() + Representation_abstract.__init__(self, lie_algebra) + CombinatorialFreeModule.__init__(self, R, ['v'], prefix='T', category=cat, **kwargs) + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: L = lie_algebras.VirasoroAlgebra(QQ) + sage: L.trivial_representation() + Trivial representation of The Virasoro algebra over Rational Field + """ + return "Trivial representation of {}".format(self._lie_algebra) + + class Element(CombinatorialFreeModule.Element): + def _acted_upon_(self, scalar, self_on_left=False): + r""" + Return the action of ``scalar`` on ``self``. + + EXAMPLES:: + + sage: L = lie_algebras.VirasoroAlgebra(QQ) + sage: R = L.trivial_representation() + sage: L.an_element() * R.an_element() + 0 + sage: R.an_element() * L.an_element() + Traceback (most recent call last): + ... + TypeError: unsupported operand parent(s) for *: ... + sage: 3 / 5 * R.an_element() + 6/5*T['v'] + """ + P = self.parent() + if scalar in P._lie_algebra: + if self_on_left: + return None + return P.zero() + return super()._acted_upon_(scalar, self_on_left) diff --git a/src/sage/algebras/quantum_groups/fock_space.py b/src/sage/algebras/quantum_groups/fock_space.py index 3daf03099d5..eb60fd89788 100644 --- a/src/sage/algebras/quantum_groups/fock_space.py +++ b/src/sage/algebras/quantum_groups/fock_space.py @@ -166,7 +166,7 @@ class FockSpace(Parent, UniqueRepresentation): To go between the canonical basis and the natural basis, for level 1 Fock space, we follow the LLT algorithm [LLT1996]_. Indeed, we first - construct an basis `\{ A(\nu) \}` that is an approximation to the + construct a basis `\{ A(\nu) \}` that is an approximation to the lower global crystal basis, in the sense that it is bar-invariant, and then use Gaussian elimination to construct the lower global crystal basis. For higher level Fock space, we follow [Fayers2010]_, diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index 5d3ef49f7c5..22fa53b5a29 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -3696,6 +3696,12 @@ def binomial(x, m, **kwds): 0 sage: binomial(RealField()('2.5'), 2) # needs sage.rings.real_mpfr 1.87500000000000 + sage: binomial(Zp(5)(99),50) + 3 + 4*5^3 + 2*5^4 + 4*5^5 + 4*5^6 + 4*5^7 + 4*5^8 + 5^9 + 2*5^10 + 3*5^11 + + 4*5^12 + 4*5^13 + 2*5^14 + 3*5^15 + 3*5^16 + 4*5^17 + 4*5^18 + 2*5^19 + O(5^20) + sage: binomial(Qp(3)(2/3),2) + 2*3^-2 + 2*3^-1 + 2 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + + 2*3^8 + 2*3^9 + 2*3^10 + 2*3^11 + 2*3^12 + 2*3^13 + 2*3^14 + 2*3^15 + 2*3^16 + 2*3^17 + O(3^18) sage: n = var('n'); binomial(n, 2) # needs sage.symbolic 1/2*(n - 1)*n sage: n = var('n'); binomial(n, n) # needs sage.symbolic @@ -3792,6 +3798,27 @@ def binomial(x, m, **kwds): sage: binomial(n,2) # needs sage.symbolic 1/2*(n - 1)*n + Test p-adic numbers:: + + sage: binomial(Qp(3)(-1/2),4) # p-adic number with valuation >= 0 + 1 + 3 + 2*3^2 + 3^3 + 2*3^4 + 3^6 + 3^7 + 3^8 + 3^11 + 2*3^14 + 2*3^16 + 2*3^17 + 2*3^19 + O(3^20) + + Check that :trac:`35811` is fixed:: + + sage: binomial(Qp(3)(1/3),4) # p-adic number with negative valuation + 2*3^-5 + 2*3^-4 + 3^-3 + 2*3^-2 + 2*3^-1 + 2 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 2*3^11 + 2*3^12 + 2*3^13 + 2*3^14 + O(3^15) + + sage: binomial(Qp(3)(1/3),10).parent() + 3-adic Field with capped relative precision 20 + + sage: F.=Qq(9); binomial(w,4) # p-adic extension field + (w + 2)*3^-1 + (w + 1) + (2*w + 1)*3 + 2*w*3^2 + (2*w + 2)*3^3 + 2*w*3^4 + (2*w + 2)*3^5 + + 2*w*3^6 + (2*w + 2)*3^7 + 2*w*3^8 + (2*w + 2)*3^9 + 2*w*3^10 + (2*w + 2)*3^11 + 2*w*3^12 + + (2*w + 2)*3^13 + 2*w*3^14 + (2*w + 2)*3^15 + 2*w*3^16 + (2*w + 2)*3^17 + 2*w*3^18 + O(3^19) + sage: F.=Qq(9); binomial(w,10).parent() + 3-adic Unramified Extension Field in w defined by x^2 + 2*x + 2 + Invalid inputs:: sage: x = polygen(ZZ) @@ -3872,7 +3899,7 @@ def binomial(x, m, **kwds): # case 2: conversion to integers try: x = ZZ(x) - except TypeError: + except (TypeError, ValueError): pass else: # Check invertibility of factorial(m) in P diff --git a/src/sage/calculus/interpolators.pyx b/src/sage/calculus/interpolators.pyx index fb057f0fc2e..0e1f5fc7209 100644 --- a/src/sage/calculus/interpolators.pyx +++ b/src/sage/calculus/interpolators.pyx @@ -55,7 +55,7 @@ def polygon_spline(pts): ....: [lambda x: ps.derivative(real(x))], 0) sage: show(m.plot_colored() + m.plot_spiderweb()) # needs sage.plot - Polygon approximation of an circle:: + Polygon approximation of a circle:: sage: pts = [e^(I*t / 25) for t in range(25)] sage: ps = polygon_spline(pts) diff --git a/src/sage/calculus/ode.pyx b/src/sage/calculus/ode.pyx index 32ccfab5dfc..d7d0fc133f8 100644 --- a/src/sage/calculus/ode.pyx +++ b/src/sage/calculus/ode.pyx @@ -37,27 +37,27 @@ cdef class PyFunctionWrapper: self.y_n = x cdef class ode_system: - cdef int c_j(self,double t, double *y, double *dfdy,double *dfdt) noexcept: #void *params): + cdef int c_j(self, double t, double *y, double *dfdy, double *dfdt) noexcept: return 0 - cdef int c_f(self,double t, double* y, double* dydt) noexcept: #void *params): + cdef int c_f(self, double t, double* y, double* dydt) noexcept: return 0 -cdef int c_jac_compiled(double t, double *y, double *dfdy,double *dfdt, void * params) noexcept: +cdef int c_jac_compiled(double t, const double *y, double *dfdy, double *dfdt, void *params) noexcept: cdef int status cdef ode_system wrapper wrapper = params - status = wrapper.c_j(t,y,dfdy,dfdt) #Could add parameters + status = wrapper.c_j(t, y, dfdy, dfdt) # Could add parameters return status -cdef int c_f_compiled(double t, double *y, double *dydt, void *params) noexcept: +cdef int c_f_compiled(double t, const double *y, double *dydt, void *params) noexcept: cdef int status cdef ode_system wrapper wrapper = params - status = wrapper.c_f(t,y,dydt) #Could add parameters + status = wrapper.c_f(t, y, dydt) # Could add parameters return status -cdef int c_jac(double t,double *y,double *dfdy,double *dfdt,void *params) noexcept: +cdef int c_jac(double t, const double *y, double *dfdy, double *dfdt, void *params) noexcept: cdef int i cdef int j cdef int y_n @@ -84,7 +84,7 @@ cdef int c_jac(double t,double *y,double *dfdy,double *dfdt,void *params) noexce except Exception: return -1 -cdef int c_f(double t,double* y, double* dydt,void *params) noexcept: +cdef int c_f(double t, const double *y, double *dydt, void *params) noexcept: cdef int i cdef int y_n cdef int param_n diff --git a/src/sage/calculus/test_sympy.py b/src/sage/calculus/test_sympy.py index b99d5d7857e..0c360f8acab 100644 --- a/src/sage/calculus/test_sympy.py +++ b/src/sage/calculus/test_sympy.py @@ -156,7 +156,7 @@ sage: t1, t2 (omega + x, omega + x) - sage: e = sympy.sin(var("y"))+sage.all.cos(sympy.Symbol("x")) + sage: e = sympy.sin(var("y")) + sage.functions.trig.cos(sympy.Symbol("x")) sage: type(e) sage: e @@ -166,7 +166,7 @@ sage: e cos(x) + sin(y) - sage: e = sage.all.cos(var("y")**3)**4+var("x")**2 + sage: e = sage.functions.trig.cos(var("y")**3)**4+var("x")**2 sage: e = e._sympy_() sage: e x**2 + cos(y**3)**4 diff --git a/src/sage/categories/algebras_with_basis.py b/src/sage/categories/algebras_with_basis.py index dfd693a9520..0d1f72eb17c 100644 --- a/src/sage/categories/algebras_with_basis.py +++ b/src/sage/categories/algebras_with_basis.py @@ -1,13 +1,13 @@ r""" Algebras With Basis """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) # 2008-2013 Nicolas M. Thiery # # Distributed under the terms of the GNU General Public License (GPL) # https://www.gnu.org/licenses/ -#****************************************************************************** +# ***************************************************************************** from sage.categories.cartesian_product import CartesianProductsCategory from sage.categories.category_with_axiom import CategoryWithAxiom_over_base_ring @@ -106,7 +106,7 @@ class AlgebrasWithBasis(CategoryWithAxiom_over_base_ring): sage: TestSuite(AlgebrasWithBasis(QQ)).run() """ - def example(self, alphabet=('a','b','c')): + def example(self, alphabet=('a', 'b', 'c')): """ Return an example of algebra with basis. @@ -259,7 +259,7 @@ def one_from_cartesian_product_of_one_basis(self): ....: SymmetricGroupAlgebra(QQ, 4)]).one() B[(0, [1, 2, 3])] + B[(1, [1, 2, 3, 4])] """ - return self.sum_of_monomials( zip( self._sets_keys(), (set.one_basis() for set in self._sets)) ) + return self.sum_of_monomials(zip(self._sets_keys(), (set.one_basis() for set in self._sets))) @lazy_attribute def one(self): @@ -370,7 +370,8 @@ def product_on_basis(self, t1, t2): TODO: optimize this implementation! """ - return tensor( (module.monomial(x1)*module.monomial(x2) for (module, x1, x2) in zip(self._sets, t1, t2)) ) #. + return tensor(module.monomial(x1) * module.monomial(x2) + for module, x1, x2 in zip(self._sets, t1, t2)) class ElementMethods: """ diff --git a/src/sage/categories/category.py b/src/sage/categories/category.py index 54e0df67278..87b66a6615f 100644 --- a/src/sage/categories/category.py +++ b/src/sage/categories/category.py @@ -565,7 +565,7 @@ def an_instance(cls): def __call__(self, x, *args, **opts): """ Construct an object in this category from the data in ``x``, - or throw ``TypeError`` or ``NotImplementedError``. + or throw :class:`TypeError` or :class:`NotImplementedError`. If ``x`` is readily in ``self`` it is returned unchanged. Categories wishing to extend this minimal behavior should @@ -583,7 +583,7 @@ def __call__(self, x, *args, **opts): def _call_(self, x): """ Construct an object in this category from the data in ``x``, - or throw ``NotImplementedError``. + or throw :class:`NotImplementedError`. EXAMPLES:: diff --git a/src/sage/categories/category_with_axiom.py b/src/sage/categories/category_with_axiom.py index bb9dbbe2347..20668629649 100644 --- a/src/sage/categories/category_with_axiom.py +++ b/src/sage/categories/category_with_axiom.py @@ -500,7 +500,7 @@ class from the base category class:: (bilinearity). Of course this should be implemented at the level of :class:`~.magmatic_algebras.MagmaticAlgebras`, if not higher. - - :class:`Bialgebras`: defining an bialgebra as an algebra and + - :class:`Bialgebras`: defining a bialgebra as an algebra and coalgebra where the coproduct is a morphism for the product. - :class:`Bimodules`: defining a bimodule as a left and right @@ -2667,7 +2667,7 @@ def Blue_extra_super_categories(self): This currently fails because ``Blahs`` is the category where the axiom ``Blue`` is defined, and the specifications currently impose that a category defining an axiom should also - implement it (here in an category with axiom + implement it (here in a category with axiom ``Blahs.Blue``). In practice, due to this violation of the specifications, the axiom is lost during the join calculation. diff --git a/src/sage/categories/complex_reflection_groups.py b/src/sage/categories/complex_reflection_groups.py index 925ee1c228e..d9d30d41e40 100644 --- a/src/sage/categories/complex_reflection_groups.py +++ b/src/sage/categories/complex_reflection_groups.py @@ -21,7 +21,7 @@ class ComplexReflectionGroups(Category_singleton): The category of complex reflection groups. Let `V` be a complex vector space. A *complex reflection* is an - element of `\operatorname{GL}(V)` fixing an hyperplane pointwise + element of `\operatorname{GL}(V)` fixing a hyperplane pointwise and acting by multiplication by a root of unity on a complementary line. diff --git a/src/sage/categories/covariant_functorial_construction.py b/src/sage/categories/covariant_functorial_construction.py index e64bbaa35aa..ce4909a7b63 100644 --- a/src/sage/categories/covariant_functorial_construction.py +++ b/src/sage/categories/covariant_functorial_construction.py @@ -96,7 +96,7 @@ class CovariantFunctorialConstruction(UniqueRepresentation, SageObject): specify information and generic operations for elements of this category. - - ``_functor_name`` - an string which specifies the name of the + - ``_functor_name`` - a string which specifies the name of the functor, and also (when relevant) of the method on parents and elements used for calling the construction. diff --git a/src/sage/categories/coxeter_groups.py b/src/sage/categories/coxeter_groups.py index 972d3b4d716..f3ef677638d 100644 --- a/src/sage/categories/coxeter_groups.py +++ b/src/sage/categories/coxeter_groups.py @@ -701,7 +701,7 @@ def _test_reduced_word(self, **options): for x in tester.some_elements(): red = x.reduced_word() tester.assertEqual(self.from_reduced_word(red), x) - tester.assertEqual(self.prod((s[i] for i in red)), x) + tester.assertEqual(self.prod(s[i] for i in red), x) def simple_projection(self, i, side='right', length_increasing=True): r""" diff --git a/src/sage/categories/crystals.py b/src/sage/categories/crystals.py index ae900a93e66..c2a9b8de655 100644 --- a/src/sage/categories/crystals.py +++ b/src/sage/categories/crystals.py @@ -578,7 +578,7 @@ def _Hom_(self, Y, category=None, **options): The sole purpose of this method is to construct the homset as a :class:`~sage.categories.crystals.CrystalHomset`. If ``category`` is specified and is not a subcategory of - :class:`Crystals`, a ``TypeError`` is raised instead. + :class:`Crystals`, a :class:`TypeError` is raised instead. This method is not meant to be called directly. Please use :func:`sage.categories.homset.Hom` instead. diff --git a/src/sage/categories/discrete_valuation.py b/src/sage/categories/discrete_valuation.py index 4bb61a5aa67..24b15bca488 100644 --- a/src/sage/categories/discrete_valuation.py +++ b/src/sage/categories/discrete_valuation.py @@ -147,22 +147,31 @@ def quo_rem(self, other): Return the quotient and remainder for Euclidean division of ``self`` by ``other``. - TESTS:: + EXAMPLES:: sage: R. = GF(5)[[]] sage: (q^2 + q).quo_rem(q) (1 + q, 0) sage: (q + 1).quo_rem(q^2) (0, 1 + q) + + TESTS:: + sage: q.quo_rem(0) Traceback (most recent call last): ... ZeroDivisionError: Euclidean division by the zero element not defined + sage: L = PowerSeriesRing(QQ, 't') + sage: t = L.gen() + sage: F = algebras.Free(L, ['A', 'B']) + sage: A, B = F.gens() + sage: f = t*A+t**2*B/2 """ if not other: raise ZeroDivisionError("Euclidean division by the zero element not defined") P = self.parent() + other = P(other) if self.valuation() >= other.valuation(): return P(self / other), P.zero() else: @@ -263,7 +272,7 @@ def residue_field(self): def _matrix_hessenbergize(self, H): r""" - Replace `H` with an Hessenberg form of it. + Replace `H` with a Hessenberg form of it. EXAMPLES:: diff --git a/src/sage/categories/enumerated_sets.py b/src/sage/categories/enumerated_sets.py index 8ae3270491c..a5e0bbcefaf 100644 --- a/src/sage/categories/enumerated_sets.py +++ b/src/sage/categories/enumerated_sets.py @@ -182,7 +182,8 @@ def __iter__(self): It is also possible to override ``__iter__`` method itself. Then the methods of the first column are defined using ``__iter__`` - If none of these are provided, raise a ``NotImplementedError``. + If none of these are provided, this raises + a :class:`NotImplementedError`. EXAMPLES: @@ -928,7 +929,7 @@ def random_element(self): the probability is uniform. This is a generic implementation from the category - ``EnumeratedSets()``. It raise a ``NotImplementedError`` + ``EnumeratedSets()``. It raises a :class:`NotImplementedError` since one does not know whether the set is finite. EXAMPLES:: diff --git a/src/sage/categories/facade_sets.py b/src/sage/categories/facade_sets.py index 746622743fb..7bf2ac2f067 100644 --- a/src/sage/categories/facade_sets.py +++ b/src/sage/categories/facade_sets.py @@ -209,8 +209,8 @@ def _an_element_(self): For each parent ``self`` is a facade for, this default implementation tries the method ``an_element`` until it finds an - element in ``self``. If none is found raise a - ``NotImplementedError``. + element in ``self``. If none is found, this raises a + :class:`NotImplementedError`. EXAMPLES:: diff --git a/src/sage/categories/fields.py b/src/sage/categories/fields.py index 63ab62aabff..4f8bb141467 100644 --- a/src/sage/categories/fields.py +++ b/src/sage/categories/fields.py @@ -808,7 +808,7 @@ def inverse_of_unit(self): 1/2 Trying to invert the zero element typically raises a - ``ZeroDivisionError``:: + :class:`ZeroDivisionError`:: sage: QQ(0).inverse_of_unit() Traceback (most recent call last): diff --git a/src/sage/categories/filtered_modules_with_basis.py b/src/sage/categories/filtered_modules_with_basis.py index 15d0f490713..84e38b14976 100644 --- a/src/sage/categories/filtered_modules_with_basis.py +++ b/src/sage/categories/filtered_modules_with_basis.py @@ -156,7 +156,7 @@ def basis(self, d=None): over Integer Ring(i))_{i in Partitions} Checking this method on a filtered algebra. Note that this - will typically raise a ``NotImplementedError`` when this + will typically raise a :class:`NotImplementedError` when this feature is not implemented. :: sage: A = AlgebrasWithBasis(ZZ).Filtered().example() diff --git a/src/sage/categories/finite_complex_reflection_groups.py b/src/sage/categories/finite_complex_reflection_groups.py index 1a5ed06c42a..b1e89676728 100644 --- a/src/sage/categories/finite_complex_reflection_groups.py +++ b/src/sage/categories/finite_complex_reflection_groups.py @@ -555,22 +555,22 @@ def milnor_fiber_poset(self): sage: sum(x**P.rank(elt) for elt in P) 18*x^2 + 15*x + 1 - sage: W = ReflectionGroup(4) # optional - gap3 - sage: P = W.milnor_fiber_poset() # optional - gap3 - sage: P # optional - gap3 + sage: # optional - gap3 + sage: W = ReflectionGroup(4) + sage: P = W.milnor_fiber_poset(); P Finite meet-semilattice containing 41 elements - sage: sum(x**P.rank(elt) for elt in P) # optional - gap3 + sage: sum(x**P.rank(elt) for elt in P) 24*x^2 + 16*x + 1 - sage: W = ReflectionGroup([4,2,2]) # optional - gap3 - sage: W.is_well_generated() # optional - gap3 + sage: # optional - gap3 + sage: W = ReflectionGroup([4,2,2]) + sage: W.is_well_generated() False - sage: P = W.milnor_fiber_poset() # optional - gap3 - sage: P # optional - gap3 + sage: P = W.milnor_fiber_poset(); P Finite poset containing 47 elements - sage: sum(x**P.rank(elt) for elt in P) # optional - gap3 + sage: sum(x**P.rank(elt) for elt in P) 16*x^3 + 24*x^2 + 6*x + 1 - sage: P.is_meet_semilattice() # optional - gap3 + sage: P.is_meet_semilattice() False """ I = self.index_set() diff --git a/src/sage/categories/finite_groups.py b/src/sage/categories/finite_groups.py index 7461f6fabfd..c64b7fd8bf0 100644 --- a/src/sage/categories/finite_groups.py +++ b/src/sage/categories/finite_groups.py @@ -153,9 +153,9 @@ def conjugacy_classes(self): Return a list with all the conjugacy classes of the group. This will eventually be a fall-back method for groups not defined - over GAP. Right now just raises a ``NotImplementedError``, until - we include a non-GAP way of listing the conjugacy classes - representatives. + over GAP. Right now, it just raises a + :class:`NotImplementedError`, until we include a non-GAP + way of listing the conjugacy classes representatives. EXAMPLES:: diff --git a/src/sage/categories/finite_posets.py b/src/sage/categories/finite_posets.py index 49d9f2ba53f..68317bbb4c3 100644 --- a/src/sage/categories/finite_posets.py +++ b/src/sage/categories/finite_posets.py @@ -906,7 +906,7 @@ def birational_toggle(self, v, labelling): encoded to be understood by Sage. This implementation allows `\mathbf{K}` to be a semifield, not just a field. The birational `v`-toggle is only a rational map, so an exception (most - likely, ``ZeroDivisionError``) will be thrown if the + likely, :class:`ZeroDivisionError`) will be thrown if the denominator is zero. INPUT: @@ -1121,7 +1121,7 @@ def birational_toggles(self, vs, labelling): encoded to be understood by Sage. This implementation allows `\mathbf{K}` to be a semifield, not just a field. The birational `v`-toggle is only a rational map, so an exception (most - likely, ``ZeroDivisionError``) will be thrown if the + likely, :class:`ZeroDivisionError`) will be thrown if the denominator is zero. INPUT: @@ -1194,9 +1194,10 @@ def birational_rowmotion(self, labelling): `\mathbf{K}`-labellings and for an explanation of how `\mathbf{K}`-labellings are to be encoded to be understood by Sage. This implementation allows `\mathbf{K}` to be a - semifield, not just a field. Birational rowmotion is only a - rational map, so an exception (most likely, ``ZeroDivisionError``) - will be thrown if the denominator is zero. + semifield, not just a field. Birational rowmotion is only + a rational map, so an exception (most likely, + :class:`ZeroDivisionError`) will be thrown if the + denominator is zero. INPUT: diff --git a/src/sage/categories/functor.pyx b/src/sage/categories/functor.pyx index 32bd079fc73..e8cf2e5538f 100644 --- a/src/sage/categories/functor.pyx +++ b/src/sage/categories/functor.pyx @@ -74,9 +74,9 @@ cdef class Functor(SageObject): default call method: - ``_coerce_into_domain(self, x)``: Return an object of ``self``'s - domain, corresponding to ``x``, or raise a ``TypeError``. + domain, corresponding to ``x``, or raise a :class:`TypeError`. - - Default: Raise ``TypeError`` if ``x`` is not in ``self``'s domain. + - Default: Raise :class:`TypeError` if ``x`` is not in ``self``'s domain. - ``_apply_functor(self, x)``: Apply ``self`` to an object ``x`` of ``self``'s domain. @@ -282,11 +282,12 @@ cdef class Functor(SageObject): NOTE: A subclass of :class:`Functor` may overload this method. It should - return an object of self's domain, and should raise a ``TypeError`` - if this is impossible. + return an object of self's domain, and should raise a + :class:`TypeError` if this is impossible. - By default, the argument will not be changed, but a ``TypeError`` - will be raised if the argument does not belong to the domain. + By default, the argument will not be changed, but a + :class:`TypeError` will be raised if the argument does not + belong to the domain. TESTS:: diff --git a/src/sage/categories/graded_algebras_with_basis.py b/src/sage/categories/graded_algebras_with_basis.py index 95fcebbb7a7..62d4816b208 100644 --- a/src/sage/categories/graded_algebras_with_basis.py +++ b/src/sage/categories/graded_algebras_with_basis.py @@ -224,8 +224,8 @@ def product_on_basis(self, t0, t1): TODO: optimize this implementation! """ - basic = tensor_signed((module.monomial(x0) * module.monomial(x1) - for (module, x0, x1) in zip(self._sets, t0, t1))) + basic = tensor_signed(module.monomial(x0) * module.monomial(x1) + for (module, x0, x1) in zip(self._sets, t0, t1)) n = len(self._sets) parity0 = [self._sets[idx].degree_on_basis(x0) for (idx, x0) in enumerate(t0)] diff --git a/src/sage/categories/hecke_modules.py b/src/sage/categories/hecke_modules.py index 118e155654e..8a8da4f64ef 100644 --- a/src/sage/categories/hecke_modules.py +++ b/src/sage/categories/hecke_modules.py @@ -1,14 +1,14 @@ r""" Hecke modules """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2005 David Kohel # William Stein # 2008-2009 Nicolas M. Thiery # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#****************************************************************************** +# https://www.gnu.org/licenses/ +# ***************************************************************************** from sage.categories.category_types import Category_module from sage.categories.homsets import HomsetsCategory @@ -114,7 +114,7 @@ def _Hom_(self, Y, category): The sole purpose of this method is to construct the homset as a :class:`~sage.modular.hecke.homspace.HeckeModuleHomspace`. If ``category`` is specified and is not a subcategory of - :class:`HeckeModules`, a ``TypeError`` is raised instead + :class:`HeckeModules`, a :class:`TypeError` is raised instead This method is not meant to be called directly. Please use :func:`sage.categories.homset.Hom` instead. diff --git a/src/sage/categories/highest_weight_crystals.py b/src/sage/categories/highest_weight_crystals.py index 68e72a11b90..baf50566cc0 100644 --- a/src/sage/categories/highest_weight_crystals.py +++ b/src/sage/categories/highest_weight_crystals.py @@ -2,12 +2,12 @@ r""" Highest Weight Crystals """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010 Anne Schilling # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#****************************************************************************** +# https://www.gnu.org/licenses/ +# ***************************************************************************** from sage.misc.cachefunc import cached_method from sage.categories.category_singleton import Category_singleton @@ -15,6 +15,7 @@ CrystalMorphismByGenerators) from sage.categories.tensor import TensorProductsCategory + class HighestWeightCrystals(Category_singleton): """ The category of highest weight crystals. @@ -410,7 +411,8 @@ def _Hom_(self, Y, category=None, **options): The sole purpose of this method is to construct the homset as a :class:`~sage.categories.highest_weight_crystals.HighestWeightCrystalHomset`. If ``category`` is specified and is not a subcategory of - :class:`HighestWeightCrystals`, a ``TypeError`` is raised instead + :class:`HighestWeightCrystals`, a :class:`TypeError` is raised + instead This method is not meant to be called directly. Please use :func:`sage.categories.homset.Hom` instead. diff --git a/src/sage/categories/homset.py b/src/sage/categories/homset.py index d2203299512..bf4426aff87 100644 --- a/src/sage/categories/homset.py +++ b/src/sage/categories/homset.py @@ -178,7 +178,7 @@ def Hom(X, Y, category=None, check=True): A parent (or a parent class of a category) may specify how to construct certain homsets by implementing a method ``_Hom_(self, codomain, category)``. This method should either construct the - requested homset or raise a ``TypeError``. This hook is currently + requested homset or raise a :class:`TypeError`. This hook is currently mostly used to create homsets in some specific subclass of :class:`Homset` (e.g. :class:`sage.rings.homset.RingHomset`):: diff --git a/src/sage/categories/infinite_enumerated_sets.py b/src/sage/categories/infinite_enumerated_sets.py index 3c7a861a4b6..e65bf944b87 100644 --- a/src/sage/categories/infinite_enumerated_sets.py +++ b/src/sage/categories/infinite_enumerated_sets.py @@ -6,16 +6,17 @@ - Florent Hivert (2009-11): initial revision. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2009 Florent Hivert # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#****************************************************************************** +# https://www.gnu.org/licenses/ +# ***************************************************************************** from sage.categories.category_with_axiom import CategoryWithAxiom + class InfiniteEnumeratedSets(CategoryWithAxiom): """ The category of infinite enumerated sets @@ -99,9 +100,9 @@ def _test_enumerated_set_iter_cardinality(self, **options): For infinite enumerated sets: - * :meth:`.cardinality` is supposed to return `infinity` + * :meth:`.cardinality` is supposed to return ``infinity`` - * :meth:`.list` is supposed to raise a ``NotImplementedError``. + * :meth:`.list` is supposed to raise a :class:`NotImplementedError`. EXAMPLES:: diff --git a/src/sage/categories/lie_algebras.py b/src/sage/categories/lie_algebras.py index 32aa9f00041..4226c4dba61 100644 --- a/src/sage/categories/lie_algebras.py +++ b/src/sage/categories/lie_algebras.py @@ -697,6 +697,64 @@ def lie_group(self, name='G', **kwds): Lie group G of Heisenberg algebra of rank 1 over Rational Field """ + def trivial_representation(self): + """ + Return the trivial representation of ``self``. + + EXAMPLES:: + + sage: L = lie_algebras.strictly_upper_triangular_matrices(QQ, 4) + sage: L.trivial_representation() + Trivial representation of Lie algebra of 4-dimensional + strictly upper triangular matrices over Rational Field + """ + from sage.algebras.lie_algebras.representation import TrivialRepresentation + return TrivialRepresentation(self) + + def representation(self, f=None, index_set=None, on_basis=False, **kwargs): + """ + Return a representation of ``self``. + + If no arguments are given, then this returns the trivial + representation. + + Currently the only implemented method of constructing a + representation is by explicitly specifying the action of + + * the elements of ``self`` by matrices; + * the basis elements of ``self`` using a ``dict`` or + a :func:`Family`; + * a function on basis elements (either passed as ``on_basis`` + or setting ``on_basis=True``). + + INPUT: + + - ``f`` -- the function that defines the action + - ``index_set`` -- the index set of the representation + - ``on_basis`` -- (optional) see above + + .. SEEALSO:: + + :class:`~sage.algebras.lie_algebras.representation.RepresentationByMorphism` + + EXAMPLES:: + + sage: L. = LieAlgebra(QQ, {('x','y'): {'y':1}}) + sage: f = {x: Matrix([[1,0],[0,0]]), y: Matrix([[0,1],[0,0]])} + sage: L.representation(f) + Representation of Lie algebra on 2 generators (x, y) over Rational Field defined by: + [1 0] + x |--> [0 0] + [0 1] + y |--> [0 0] + sage: L.representation() + Trivial representation of Lie algebra on 2 generators (x, y) over Rational Field + """ + if f is None and on_basis is False and index_set is None: + return self.trivial_representation(**kwargs) + from sage.algebras.lie_algebras.representation import RepresentationByMorphism + return RepresentationByMorphism(self, f, index_set, on_basis, **kwargs) + def _test_jacobi_identity(self, **options): """ Test that the Jacobi identity is satisfied on (not diff --git a/src/sage/categories/magmas.py b/src/sage/categories/magmas.py index 603e68ad186..72b037c30b0 100644 --- a/src/sage/categories/magmas.py +++ b/src/sage/categories/magmas.py @@ -438,7 +438,7 @@ class CartesianProducts(CartesianProductsCategory): def extra_super_categories(self): r""" Implement the fact that a Cartesian product of commutative - additive magmas is still an commutative additive magmas. + additive magmas is still a commutative additive magmas. EXAMPLES:: diff --git a/src/sage/categories/map.pyx b/src/sage/categories/map.pyx index fadd066d7f4..a931ceaa6cb 100644 --- a/src/sage/categories/map.pyx +++ b/src/sage/categories/map.pyx @@ -1880,7 +1880,7 @@ cdef class FormalCompositeMap(Map): """ Tell whether ``self`` is injective. - It raises ``NotImplementedError`` if it can't be determined. + It raises :class:`NotImplementedError` if it cannot be determined. EXAMPLES:: @@ -1955,7 +1955,7 @@ cdef class FormalCompositeMap(Map): """ Tell whether ``self`` is surjective. - It raises ``NotImplementedError`` if it can't be determined. + It raises :class:`NotImplementedError` if it cannot be determined. EXAMPLES:: diff --git a/src/sage/categories/modules_with_basis.py b/src/sage/categories/modules_with_basis.py index c4933d0657f..aad3469e072 100644 --- a/src/sage/categories/modules_with_basis.py +++ b/src/sage/categories/modules_with_basis.py @@ -1081,7 +1081,7 @@ def sum_of_monomials(self): INPUT: - - ``indices`` -- an list (or iterable) of indices of basis + - ``indices`` -- a list (or iterable) of indices of basis elements EXAMPLES:: diff --git a/src/sage/categories/number_fields.py b/src/sage/categories/number_fields.py index 3c070bd65b2..6f9829cd499 100644 --- a/src/sage/categories/number_fields.py +++ b/src/sage/categories/number_fields.py @@ -95,7 +95,7 @@ def __contains__(self, x): def _call_(self, x): r""" Construct an object in this category from the data in ``x``, - or raise a ``TypeError``. + or raise a :class:`TypeError`. EXAMPLES:: diff --git a/src/sage/categories/quotient_fields.py b/src/sage/categories/quotient_fields.py index f5d8495489d..fe1b66a0fb4 100644 --- a/src/sage/categories/quotient_fields.py +++ b/src/sage/categories/quotient_fields.py @@ -632,7 +632,7 @@ def _derivative(self, var=None): Returns the derivative of this rational function with respect to the variable ``var``. - Over an ring with a working gcd implementation, the derivative of a + Over a ring with a working gcd implementation, the derivative of a fraction `f/g`, supposed to be given in lowest terms, is computed as `(f'(g/d) - f(g'/d))/(g(g'/d))`, where `d` is a greatest common divisor of `f` and `g`. diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 60ca92f971b..24a858f3525 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -387,7 +387,7 @@ def _Hom_(self, Y, category): The sole purpose of this method is to construct the homset as a :class:`~sage.rings.homset.RingHomset`. If ``category`` is specified and is not a subcategory of - :class:`Rings() `, a ``TypeError`` is raised instead + :class:`Rings() `, a :class:`TypeError` is raised instead This method is not meant to be called directly. Please use :func:`sage.categories.homset.Hom` instead. @@ -1416,7 +1416,7 @@ def inverse_of_unit(self): def _divide_if_possible(self, y): """ Divide ``self`` by ``y`` if possible and raise a - ``ValueError`` otherwise. + :class:`ValueError` otherwise. EXAMPLES:: diff --git a/src/sage/categories/sets_cat.py b/src/sage/categories/sets_cat.py index 16c117b286e..df0e3abee86 100644 --- a/src/sage/categories/sets_cat.py +++ b/src/sage/categories/sets_cat.py @@ -1830,7 +1830,7 @@ def __invert__(self): .. NOTE:: This is an optional method. A default implementation - raising ``NotImplementedError`` could be provided instead. + raising :class:`NotImplementedError` could be provided instead. """ def is_injective(self): diff --git a/src/sage/categories/simplicial_sets.py b/src/sage/categories/simplicial_sets.py index 2b45c4c98cb..7b7bbf827af 100644 --- a/src/sage/categories/simplicial_sets.py +++ b/src/sage/categories/simplicial_sets.py @@ -1108,7 +1108,7 @@ def connectivity(self, max_dim=None): return Infinity class Finite(CategoryWithAxiom): - class ParentMethods(): + class ParentMethods: def unset_base_point(self): """ diff --git a/src/sage/coding/ag_code_decoders.pyx b/src/sage/coding/ag_code_decoders.pyx index 15231e6aa87..9ce2aa2f8ce 100644 --- a/src/sage/coding/ag_code_decoders.pyx +++ b/src/sage/coding/ag_code_decoders.pyx @@ -29,17 +29,18 @@ EXAMPLES:: The ``decoder`` is now ready for correcting vectors received from a noisy channel:: - sage: channel = channels.StaticErrorRateChannel(code.ambient_space(), tau) # long time - sage: message_space = decoder.message_space() # long time - sage: message = message_space.random_element() # long time - sage: encoder = decoder.connected_encoder() # long time - sage: sent_codeword = encoder.encode(message) # long time - sage: received_vector = channel(sent_codeword) # long time - sage: (received_vector - sent_codeword).hamming_weight() # long time + sage: # long time + sage: channel = channels.StaticErrorRateChannel(code.ambient_space(), tau) + sage: message_space = decoder.message_space() + sage: message = message_space.random_element() + sage: encoder = decoder.connected_encoder() + sage: sent_codeword = encoder.encode(message) + sage: received_vector = channel(sent_codeword) + sage: (received_vector - sent_codeword).hamming_weight() 4 - sage: decoder.decode_to_code(received_vector) == sent_codeword # long time + sage: decoder.decode_to_code(received_vector) == sent_codeword True - sage: decoder.decode_to_message(received_vector) == message # long time + sage: decoder.decode_to_message(received_vector) == message True AUTHORS: diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index 6779708bfda..81065a7dbd3 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -3204,6 +3204,8 @@ cdef class BinaryCodeClassifier: ....: [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1]]) sage: B = BinaryCode(M) sage: gens, labeling, size, base = BC._aut_gp_and_can_label(B) + + sage: # needs sage.groups sage: S = SymmetricGroup(M.ncols()) sage: L = [S([x+1 for x in g]) for g in gens] sage: PermutationGroup(L).order() @@ -3218,6 +3220,8 @@ cdef class BinaryCodeClassifier: ....: [0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,1]]) sage: B = BinaryCode(M) sage: gens, labeling, size, base = BC._aut_gp_and_can_label(B) + + sage: # needs sage.groups sage: S = SymmetricGroup(M.ncols()) sage: L = [S([x+1 for x in g]) for g in gens] sage: PermutationGroup(L).order() @@ -3225,7 +3229,7 @@ cdef class BinaryCodeClassifier: sage: size 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], @@ -3236,6 +3240,8 @@ cdef class BinaryCodeClassifier: ....: [0,0,0,0,0,0,0,1,0,0,1,1,1,1,0,0,1]]) sage: B = BinaryCode(M) sage: gens, labeling, size, base = BC._aut_gp_and_can_label(B) + + sage: # needs sage.groups sage: S = SymmetricGroup(M.ncols()) sage: L = [S([x+1 for x in g]) for g in gens] sage: PermutationGroup(L).order() @@ -3243,7 +3249,7 @@ cdef class BinaryCodeClassifier: sage: size 136 - 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], @@ -3257,6 +3263,8 @@ cdef class BinaryCodeClassifier: ....: [0,0,1,0,1,1,1,0,0,0,1,1,0,0,1,0,0,0,1,1,1,0]]) sage: B = BinaryCode(M) sage: gens, labeling, size, base = BC._aut_gp_and_can_label(B) + + sage: # needs sage.groups sage: S = SymmetricGroup(M.ncols()) sage: L = [S([x+1 for x in g]) for g in gens] sage: PermutationGroup(L).order() @@ -3956,7 +3964,7 @@ cdef class BinaryCodeClassifier: sage: from sage.coding.binary_code import * sage: BC = BinaryCodeClassifier() sage: B = BinaryCode(Matrix(GF(2), [[1,1,1,1]])) - sage: BC.generate_children(B, 6, 4) + sage: BC.generate_children(B, 6, 4) # needs sage.groups [ [1 1 1 1 0 0] [0 1 0 1 1 1] diff --git a/src/sage/coding/channel.py b/src/sage/coding/channel.py index 50ea5f5cb1f..160afef9bd1 100644 --- a/src/sage/coding/channel.py +++ b/src/sage/coding/channel.py @@ -454,12 +454,12 @@ class ErrorErasureChannel(Channel): - ``space`` -- the input and output space - ``number_errors`` -- the number of errors created in each transmitted - message. It can be either an integer of a tuple. If an tuple is passed as + message. It can be either an integer of a tuple. If a tuple is passed as an argument, the number of errors will be a random integer between the two bounds of this tuple. - ``number_erasures`` -- the number of erasures created in each transmitted - message. It can be either an integer of a tuple. If an tuple is passed as an + message. It can be either an integer of a tuple. If a tuple is passed as an argument, the number of erasures will be a random integer between the two bounds of this tuple. @@ -564,7 +564,7 @@ def transmit_unsafe(self, message): Return ``message`` with as many errors as ``self._number_errors`` in it, and as many erasures as ``self._number_erasures`` in it. - If ``self._number_errors`` was passed as an tuple for the number of errors, it will + If ``self._number_errors`` was passed as a tuple for the number of errors, it will pick a random integer between the bounds of the tuple and use it as the number of errors. It does the same with ``self._number_erasures``. diff --git a/src/sage/coding/codecan/autgroup_can_label.pyx b/src/sage/coding/codecan/autgroup_can_label.pyx index 29efd21af56..f656771e179 100644 --- a/src/sage/coding/codecan/autgroup_can_label.pyx +++ b/src/sage/coding/codecan/autgroup_can_label.pyx @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.libs.pari r""" Canonical forms and automorphisms for linear codes over finite fields diff --git a/src/sage/coding/decoder.py b/src/sage/coding/decoder.py index 82a07775300..503c31a3b39 100644 --- a/src/sage/coding/decoder.py +++ b/src/sage/coding/decoder.py @@ -31,7 +31,7 @@ class Decoder(SageObject): Every decoder class for linear codes (of any metric) should inherit from this abstract class. - To implement an decoder, you need to: + To implement a decoder, you need to: - inherit from :class:`Decoder` diff --git a/src/sage/coding/goppa_code.py b/src/sage/coding/goppa_code.py index 2a974cf1ef2..a642fb86049 100644 --- a/src/sage/coding/goppa_code.py +++ b/src/sage/coding/goppa_code.py @@ -308,7 +308,7 @@ def distance_bound(self): [8, 2] Goppa code over GF(2) sage: C.distance_bound() 3 - sage: C.minimum_distance() + sage: C.minimum_distance() # needs sage.libs.gap 5 """ return 1 + (self._generating_pol).degree() diff --git a/src/sage/coding/reed_muller_code.py b/src/sage/coding/reed_muller_code.py index 6885532757b..6ea8a904722 100644 --- a/src/sage/coding/reed_muller_code.py +++ b/src/sage/coding/reed_muller_code.py @@ -906,7 +906,7 @@ def unencode_nocheck(self, c): OUTPUT: - - An polynomial of degree less than ``self.code().order()``. + - A polynomial of degree less than ``self.code().order()``. EXAMPLES:: diff --git a/src/sage/coding/subfield_subcode.py b/src/sage/coding/subfield_subcode.py index 9ec9650c43a..c876ef73e63 100644 --- a/src/sage/coding/subfield_subcode.py +++ b/src/sage/coding/subfield_subcode.py @@ -38,7 +38,7 @@ class SubfieldSubcode(AbstractLinearCode): - ``subfield`` -- the base field of ``self``. - - ``embedding`` -- (default: ``None``) an homomorphism from ``subfield`` to + - ``embedding`` -- (default: ``None``) a homomorphism from ``subfield`` to ``original_code``'s base field. If ``None`` is provided, it will default to the first homomorphism of the list of homomorphisms Sage can build. diff --git a/src/sage/combinat/abstract_tree.py b/src/sage/combinat/abstract_tree.py index ee797d990fa..e25c0606769 100644 --- a/src/sage/combinat/abstract_tree.py +++ b/src/sage/combinat/abstract_tree.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Abstract Recursive Trees @@ -73,7 +72,7 @@ # of it later. -class AbstractTree(): +class AbstractTree: """ Abstract Tree. @@ -1276,7 +1275,7 @@ def node_to_str(t): if hasattr(t, "label"): return str(t.label()) else: - return u"o" + return "o" # other possible choices for nodes would be u"█ ▓ ░ ╋ ╬" if self.is_empty(): @@ -1291,9 +1290,9 @@ def node_to_str(t): if len(self) == 1: repr_child = self[0]._unicode_art_() - sep = UnicodeArt([u" " * repr_child._root]) + sep = UnicodeArt([" " * repr_child._root]) t_repr = UnicodeArt([node_to_str(self)]) - repr_root = (sep + t_repr) * (sep + UnicodeArt([u"│"])) + repr_root = (sep + t_repr) * (sep + UnicodeArt(["│"])) t_repr = repr_root * repr_child t_repr._root = repr_child._root t_repr._baseline = t_repr._h - 1 @@ -1303,17 +1302,17 @@ def node_to_str(t): l_repr = [subtree._unicode_art_() for subtree in self] acc = l_repr.pop(0) whitesep = acc._root - lf_sep = u" " * whitesep + u"╭" + u"─" * (acc._l - acc._root) - ls_sep = u" " * whitesep + u"│" + u" " * (acc._l - acc._root) + lf_sep = " " * whitesep + "╭" + "─" * (acc._l - acc._root) + ls_sep = " " * whitesep + "│" + " " * (acc._l - acc._root) while l_repr: tr = l_repr.pop(0) - acc += UnicodeArt([u" "]) + tr + acc += UnicodeArt([" "]) + tr if not len(l_repr): - lf_sep += u"─" * (tr._root) + u"╮" - ls_sep += u" " * (tr._root) + u"│" + lf_sep += "─" * (tr._root) + "╮" + ls_sep += " " * (tr._root) + "│" else: - lf_sep += u"─" * (tr._root) + u"┬" + u"─" * (tr._l - tr._root) - ls_sep += u" " * (tr._root) + u"│" + u" " * (tr._l - tr._root) + lf_sep += "─" * (tr._root) + "┬" + "─" * (tr._l - tr._root) + ls_sep += " " * (tr._root) + "│" + " " * (tr._l - tr._root) mid = whitesep + (len(lf_sep) - whitesep) // 2 node = node_to_str(self) lf_sep = (lf_sep[:mid - len(node) // 2] + node + @@ -1358,10 +1357,10 @@ def canonical_labelling(self, shift=1): def to_hexacode(self): r""" - Transform a tree into an hexadecimal string. + Transform a tree into a hexadecimal string. The definition of the hexacode is recursive. The first letter is - the valence of the root as an hexadecimal (up to 15), followed by + the valence of the root as a hexadecimal (up to 15), followed by the concatenation of the hexacodes of the subtrees. This method only works for trees where every vertex has @@ -1501,7 +1500,7 @@ def create_node(self): . the matrix . and the edges """ - name = "".join((chr(ord(x) + 49) for x in str(num[0]))) + name = "".join(chr(ord(x) + 49) for x in str(num[0])) node = cmd + name nodes.append((name, (str(self.label()) if hasattr(self, "label") else "")) @@ -2460,11 +2459,11 @@ def map_labels(self, f): def from_hexacode(ch, parent=None, label='@'): r""" - Transform an hexadecimal string into a tree. + Transform a hexadecimal string into a tree. INPUT: - - ``ch`` -- an hexadecimal string + - ``ch`` -- a hexadecimal string - ``parent`` -- kind of trees to be produced. If ``None``, this will be ``LabelledOrderedTrees`` @@ -2510,11 +2509,11 @@ def from_hexacode(ch, parent=None, label='@'): def _from_hexacode_aux(ch, parent, label='@'): r""" - Transform an hexadecimal string into a tree and a remainder string. + Transform a hexadecimal string into a tree and a remainder string. INPUT: - - ``ch`` -- an hexadecimal string + - ``ch`` -- a hexadecimal string - ``parent`` -- kind of trees to be produced. diff --git a/src/sage/combinat/backtrack.py b/src/sage/combinat/backtrack.py index d0669580484..ab9c35bc23c 100644 --- a/src/sage/combinat/backtrack.py +++ b/src/sage/combinat/backtrack.py @@ -36,7 +36,7 @@ from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest -class GenericBacktracker(): +class GenericBacktracker: r""" A generic backtrack tool for exploring a search space organized as a tree, with branch pruning, etc. diff --git a/src/sage/combinat/baxter_permutations.py b/src/sage/combinat/baxter_permutations.py index 460969c062c..648ce9c6a26 100644 --- a/src/sage/combinat/baxter_permutations.py +++ b/src/sage/combinat/baxter_permutations.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Baxter permutations """ diff --git a/src/sage/combinat/bijectionist.py b/src/sage/combinat/bijectionist.py index b6c5cf53f98..60df5195e9e 100644 --- a/src/sage/combinat/bijectionist.py +++ b/src/sage/combinat/bijectionist.py @@ -2455,7 +2455,7 @@ def solutions_iterator(self): yield from self._bmilp.solutions_iterator(False, []) -class _BijectionistMILP(): +class _BijectionistMILP: r""" Wrapper class for the MixedIntegerLinearProgram (MILP). diff --git a/src/sage/combinat/binary_tree.py b/src/sage/combinat/binary_tree.py index f58f7558a73..d4afa9387cf 100644 --- a/src/sage/combinat/binary_tree.py +++ b/src/sage/combinat/binary_tree.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Binary Trees @@ -593,7 +592,7 @@ def _unicode_art_(self): o o o o """ def node_to_str(bt): - return str(bt.label()) if hasattr(bt, "label") else u"o" + return str(bt.label()) if hasattr(bt, "label") else "o" if self.is_empty(): from sage.typeset.unicode_art import empty_unicode_art @@ -609,14 +608,14 @@ def node_to_str(bt): node = node_to_str(self) rr_tree = self[1]._unicode_art_() if rr_tree._root > 2: - f_line = u" " * (rr_tree._root - 3) + node - s_line = u" " * (len(node) + rr_tree._root - 3) + u"╲" + f_line = " " * (rr_tree._root - 3) + node + s_line = " " * (len(node) + rr_tree._root - 3) + "╲" t_repr = UnicodeArt([f_line, s_line]) * rr_tree t_repr._root = rr_tree._root - 2 else: f_line = node - s_line = u" ╲" - t_line = u" " * (len(node) + 1) + s_line = " ╲" + t_line = " " * (len(node) + 1) t_repr = UnicodeArt([f_line, s_line]) * (UnicodeArt([t_line]) + rr_tree) t_repr._root = rr_tree._root t_repr._baseline = t_repr._h - 1 @@ -625,8 +624,8 @@ def node_to_str(bt): if self[1].is_empty(): node = node_to_str(self) lr_tree = self[0]._unicode_art_() - f_line = u" " * (lr_tree._root + 1) + node - s_line = u" " * lr_tree._root + u"╱" + f_line = " " * (lr_tree._root + 1) + node + s_line = " " * lr_tree._root + "╱" t_repr = UnicodeArt([f_line, s_line]) * lr_tree t_repr._root = lr_tree._root + 2 t_repr._baseline = t_repr._h - 1 @@ -638,10 +637,10 @@ def node_to_str(bt): nb_ = lr_tree._l - lr_tree._root + rr_tree._root - 1 nb_L = nb_ // 2 nb_R = nb_L + (nb_ % 2) - f_line = u" " * (lr_tree._root + 1) + u"_" * nb_L + node - f_line += u"_" * nb_R - s_line = u" " * lr_tree._root + u"╱" + u" " * (len(node) + rr_tree._root - 1 + (lr_tree._l - lr_tree._root)) + u"╲" - t_repr = UnicodeArt([f_line, s_line]) * (lr_tree + UnicodeArt([u" " * (len(node) + 2)]) + rr_tree) + f_line = " " * (lr_tree._root + 1) + "_" * nb_L + node + f_line += "_" * nb_R + s_line = " " * lr_tree._root + "╱" + " " * (len(node) + rr_tree._root - 1 + (lr_tree._l - lr_tree._root)) + "╲" + t_repr = UnicodeArt([f_line, s_line]) * (lr_tree + UnicodeArt([" " * (len(node) + 2)]) + rr_tree) t_repr._root = lr_tree._root + nb_L + 2 t_repr._baseline = t_repr._h - 1 return t_repr @@ -4262,7 +4261,7 @@ def random_element(self): EXAMPLES:: - sage: BinaryTrees(5).random_element() # random # needs sage.combinat + sage: BinaryTrees(5).random_element() # random # needs sage.combinat [., [., [., [., [., .]]]]] sage: BinaryTrees(0).random_element() # needs sage.combinat . diff --git a/src/sage/combinat/combinatorial_map.py b/src/sage/combinat/combinatorial_map.py index 5ec7871821c..84876e52f56 100644 --- a/src/sage/combinat/combinatorial_map.py +++ b/src/sage/combinat/combinatorial_map.py @@ -197,7 +197,7 @@ def combinatorial_map_wrapper(f=None, order=None, name=None): # combinatorial_map = combinatorial_map_wrapper -class CombinatorialMap(): +class CombinatorialMap: r""" This is a wrapper class for methods that are *combinatorial maps*. diff --git a/src/sage/combinat/composition.py b/src/sage/combinat/composition.py index 4d98a25108d..8d01e9ac081 100644 --- a/src/sage/combinat/composition.py +++ b/src/sage/combinat/composition.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Integer compositions diff --git a/src/sage/combinat/composition_tableau.py b/src/sage/combinat/composition_tableau.py index 18b1b85966c..8ee363fb275 100644 --- a/src/sage/combinat/composition_tableau.py +++ b/src/sage/combinat/composition_tableau.py @@ -120,7 +120,7 @@ def __init__(self, parent, t): CombinatorialElement.__init__(self, parent, t) - def _repr_diagram(self): + def _repr_diagram(self) -> str: r""" Return a string representation of ``self`` as an array. @@ -132,8 +132,8 @@ def _repr_diagram(self): 3 2 4 4 """ - return '\n'.join(("".join(("%3s" % str(x) for x in row)) - for row in self)) + return '\n'.join("".join("%3s" % str(x) for x in row) + for row in self) def __call__(self, *cell): r""" diff --git a/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py b/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py index 51a04179364..e63e1a4a3ce 100644 --- a/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py +++ b/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py @@ -769,7 +769,7 @@ def _check_decreasing_hecke_factorization(t): """ if not isinstance(t, DecreasingHeckeFactorization): if not isinstance(t, (tuple, list)): - raise ValueError("t should be an list or tuple") + raise ValueError("t should be a list or tuple") for factor in t: if not isinstance(factor, (tuple, list)): raise ValueError("each factor in t should be a list or tuple") diff --git a/src/sage/combinat/crystals/generalized_young_walls.py b/src/sage/combinat/crystals/generalized_young_walls.py index 36f6c259942..2c859c4d492 100644 --- a/src/sage/combinat/crystals/generalized_young_walls.py +++ b/src/sage/combinat/crystals/generalized_young_walls.py @@ -285,7 +285,7 @@ def generate_signature(self, i): strsig = ''.join( x[0] for x in sig) reducedsig = strsig while re.search(r"\+\s*-",reducedsig): - reducedsig = re.sub(r"\+\s*-", lambda match : str().ljust(len(match.group(int(0)))) , reducedsig) + reducedsig = re.sub(r"\+\s*-", lambda match : ''.ljust(len(match.group(0))) , reducedsig) return (sig,reducedsig) def signature(self, i): diff --git a/src/sage/combinat/crystals/tensor_product.py b/src/sage/combinat/crystals/tensor_product.py index a1b94ccf541..5604a24665c 100644 --- a/src/sage/combinat/crystals/tensor_product.py +++ b/src/sage/combinat/crystals/tensor_product.py @@ -655,7 +655,7 @@ class Element(TensorProductOfSuperCrystalsElement): pass -class QueerSuperCrystalsMixin(): +class QueerSuperCrystalsMixin: """ Mixin class with methods for a finite queer supercrystal. """ diff --git a/src/sage/combinat/decorated_permutation.py b/src/sage/combinat/decorated_permutation.py index e7281b7d3bb..f687818ef25 100644 --- a/src/sage/combinat/decorated_permutation.py +++ b/src/sage/combinat/decorated_permutation.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Decorated permutations diff --git a/src/sage/combinat/designs/database.py b/src/sage/combinat/designs/database.py index 98b8f0e598e..5eb2b90802a 100644 --- a/src/sage/combinat/designs/database.py +++ b/src/sage/combinat/designs/database.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Database of small combinatorial designs diff --git a/src/sage/combinat/designs/difference_family.py b/src/sage/combinat/designs/difference_family.py index b737b90b820..393ea4b9b47 100644 --- a/src/sage/combinat/designs/difference_family.py +++ b/src/sage/combinat/designs/difference_family.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Difference families @@ -1114,7 +1113,7 @@ def mcfarland_1973_construction(q, s): D = [] for k, H in zip(K, V.subspaces(s)): for v in H: - D.append(G((tuple(v) + (k,)))) + D.append(G(tuple(v) + (k,))) return G,[D] @@ -1749,7 +1748,7 @@ def supplementary_difference_set_from_rel_diff_set(q, existence=False, check=Tru EXAMPLES:: sage: from sage.combinat.designs.difference_family import supplementary_difference_set_from_rel_diff_set - sage: supplementary_difference_set_from_rel_diff_set(17) #random # needs sage.libs.pari + sage: supplementary_difference_set_from_rel_diff_set(17) #random # needs sage.libs.pari (Additive abelian group isomorphic to Z/16, [[(1), (5), (6), (7), (9), (13), (14), (15)], [(0), (2), (3), (5), (6), (10), (11), (13), (14)], diff --git a/src/sage/combinat/designs/ext_rep.py b/src/sage/combinat/designs/ext_rep.py index 0f5bdf339fa..2227a1e9f63 100644 --- a/src/sage/combinat/designs/ext_rep.py +++ b/src/sage/combinat/designs/ext_rep.py @@ -601,7 +601,7 @@ def _encode_attribute(string): else: return string -class XTree(): +class XTree: ''' A lazy class to wrap a rooted tree representing an XML document. The tree's nodes are tuples of the structure: @@ -774,7 +774,7 @@ def __len__(self): return len(self.xt_children) -class XTreeProcessor(): +class XTreeProcessor: ''' An incremental event-driven parser for ext-rep documents. The processing stages: diff --git a/src/sage/combinat/designs/incidence_structures.py b/src/sage/combinat/designs/incidence_structures.py index 46aada66a6e..ad60d30a6a1 100644 --- a/src/sage/combinat/designs/incidence_structures.py +++ b/src/sage/combinat/designs/incidence_structures.py @@ -48,7 +48,7 @@ lazy_import('sage.libs.gap.libgap', 'libgap') -class IncidenceStructure(): +class IncidenceStructure: r""" A base class for incidence structures (i.e. hypergraphs, i.e. set systems) diff --git a/src/sage/combinat/designs/latin_squares.py b/src/sage/combinat/designs/latin_squares.py index f67a2317a17..69b19540c22 100644 --- a/src/sage/combinat/designs/latin_squares.py +++ b/src/sage/combinat/designs/latin_squares.py @@ -291,12 +291,12 @@ def mutually_orthogonal_latin_squares(k, n, partitions=False, check=True): sage: designs.orthogonal_arrays.is_available(5+2, 5) # 5 MOLS of order 5 False - sage: designs.orthogonal_arrays.is_available(4+2,6) # 4 MOLS of order 6 # needs sage.schemes + sage: designs.orthogonal_arrays.is_available(4+2,6) # 4 MOLS of order 6 # needs sage.schemes False Sage, however, is not able to prove that the second MOLS do not exist:: - sage: designs.orthogonal_arrays.exists(4+2,6) # 4 MOLS of order 6 # needs sage.schemes + sage: designs.orthogonal_arrays.exists(4+2,6) # 4 MOLS of order 6 # needs sage.schemes Unknown If you ask for such a MOLS then you will respectively get an informative diff --git a/src/sage/combinat/designs/orthogonal_arrays.py b/src/sage/combinat/designs/orthogonal_arrays.py index b819d96c1db..312f6a4b375 100644 --- a/src/sage/combinat/designs/orthogonal_arrays.py +++ b/src/sage/combinat/designs/orthogonal_arrays.py @@ -2068,7 +2068,7 @@ def OA_from_wider_OA(OA,k): return OA return [L[:k] for L in OA] -class OAMainFunctions(): +class OAMainFunctions: r""" Functions related to orthogonal arrays. diff --git a/src/sage/combinat/designs/twographs.py b/src/sage/combinat/designs/twographs.py index 54d684cb9d2..8ba2bc12681 100644 --- a/src/sage/combinat/designs/twographs.py +++ b/src/sage/combinat/designs/twographs.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Two-graphs diff --git a/src/sage/combinat/diagram_algebras.py b/src/sage/combinat/diagram_algebras.py index 2838d1e38df..b09c2b40cca 100644 --- a/src/sage/combinat/diagram_algebras.py +++ b/src/sage/combinat/diagram_algebras.py @@ -2158,7 +2158,7 @@ def diagrams(self): return self.support() -class UnitDiagramMixin(): +class UnitDiagramMixin: """ Mixin class for diagram algebras that have the unit indexed by the :func:`identity_set_partition`. @@ -4558,59 +4558,59 @@ def is_planar(sp): sage: da.is_planar( da.to_set_partition([[1,-1],[2,-2]])) True """ - #Singletons don't affect planarity + # Singletons don't affect planarity to_consider = [x for x in map(list, sp) if len(x) > 1] n = len(to_consider) for i in range(n): - #Get the positive and negative entries of this part + # Get the positive and negative entries of this part ap = [x for x in to_consider[i] if x > 0] an = [abs(x) for x in to_consider[i] if x < 0] - #Check if a includes numbers in both the top and bottom rows + # Check if a includes numbers in both the top and bottom rows if ap and an: for j in range(n): if i == j: continue - #Get the positive and negative entries of this part + # Get the positive and negative entries of this part bp = [x for x in to_consider[j] if x > 0] bn = [abs(x) for x in to_consider[j] if x < 0] - #Skip the ones that don't involve numbers in both - #the bottom and top rows + # Skip the ones that don't involve numbers in both + # the bottom and top rows if not bn or not bp: continue - #Make sure that if min(bp) > max(ap) - #then min(bn) > max(an) + # Make sure that if min(bp) > max(ap) + # then min(bn) > max(an) if max(bp) > max(ap): if min(bn) < min(an): return False - #Go through the bottom and top rows + # Go through the bottom and top rows for row in [ap, an]: if len(row) > 1: row.sort() for s in range(len(row)-1): if row[s] + 1 == row[s+1]: - #No gap, continue on + # No gap, continue on continue rng = list(range(row[s] + 1, row[s+1])) - #Go through and make sure any parts that - #contain numbers in this range are completely - #contained in this range + # Go through and make sure any parts that + # contain numbers in this range are completely + # contained in this range for j in range(n): if i == j: continue - #Make sure we make the numbers negative again - #if we are in the bottom row + # Make sure we make the numbers negative again + # if we are in the bottom row if row is ap: sr = set(rng) else: - sr = set((-1*x for x in rng)) + sr = set(-x for x in rng) sj = set(to_consider[j]) intersection = sr.intersection(sj) @@ -4773,12 +4773,11 @@ def to_set_partition(l, k=None): [{-1, 1}, {-2, 3}, {2}, {-4, 4}, {-5, 5}, {-3}] """ if k is None: - if l == []: + if not l: return [] - else: - k = max( (max( map(abs, x) ) for x in l) ) + k = max(max(map(abs, x)) for x in l) - to_be_added = set( list(range(1, ceil(k+1))) + [-1*x for x in range(1, ceil(k+1))] ) + to_be_added = set(list(range(1, ceil(k+1))) + [-x for x in range(1, ceil(k+1))]) sp = [] for part in l: @@ -4790,7 +4789,7 @@ def to_set_partition(l, k=None): i = to_be_added.pop() if -i in to_be_added: to_be_added.remove(-i) - sp.append(set([i,-i])) + sp.append(set([i, -i])) else: sp.append(set([i])) diff --git a/src/sage/combinat/dyck_word.py b/src/sage/combinat/dyck_word.py index 41a3c199599..06cf887c936 100644 --- a/src/sage/combinat/dyck_word.py +++ b/src/sage/combinat/dyck_word.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Dyck Words diff --git a/src/sage/combinat/finite_state_machine.py b/src/sage/combinat/finite_state_machine.py index a76958e6e73..cc4588e676e 100644 --- a/src/sage/combinat/finite_state_machine.py +++ b/src/sage/combinat/finite_state_machine.py @@ -104,7 +104,7 @@ :meth:`~FiniteStateMachine.has_state` | Checks for a state :meth:`~FiniteStateMachine.has_initial_state` | Checks for an initial state :meth:`~FiniteStateMachine.has_initial_states` | Checks for initial states - :meth:`~FiniteStateMachine.has_final_state` | Checks for an final state + :meth:`~FiniteStateMachine.has_final_state` | Checks for a final state :meth:`~FiniteStateMachine.has_final_states` | Checks for final states :meth:`~FiniteStateMachine.has_transition` | Checks for a transition :meth:`~FiniteStateMachine.is_deterministic` | Checks for a deterministic machine @@ -3667,7 +3667,7 @@ def __call__(self, *args, **kwargs): sage: H.states() [('A', 1), ('B', 1), ('B', 2)] - An automaton or transducer can also act on an input (an list + An automaton or transducer can also act on an input (a list or other iterable of letters):: sage: binary_inverter = Transducer({'A': [('A', 0, 1), ('A', 1, 0)]}, @@ -12144,7 +12144,7 @@ class Transducer(FiniteStateMachine): This creates a transducer, which is a finite state machine, whose transitions have input and output labels. - An transducer has additional features like creating a simplified + A transducer has additional features like creating a simplified transducer. See class :class:`FiniteStateMachine` for more information. diff --git a/src/sage/combinat/finite_state_machine_generators.py b/src/sage/combinat/finite_state_machine_generators.py index aacc520999a..94342f9b4a3 100644 --- a/src/sage/combinat/finite_state_machine_generators.py +++ b/src/sage/combinat/finite_state_machine_generators.py @@ -97,7 +97,7 @@ from sage.rings.rational_field import QQ -class AutomatonGenerators(): +class AutomatonGenerators: r""" A collection of constructors for several common automata. @@ -346,7 +346,7 @@ def transition_function(read, input): final_states=[word]) -class TransducerGenerators(): +class TransducerGenerators: r""" A collection of constructors for several common transducers. diff --git a/src/sage/combinat/free_module.py b/src/sage/combinat/free_module.py index d8092f4bea1..8a97fbdc796 100644 --- a/src/sage/combinat/free_module.py +++ b/src/sage/combinat/free_module.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Free modules """ @@ -937,7 +936,7 @@ def get_order(self): EXAMPLES:: sage: QS2 = SymmetricGroupAlgebra(QQ,2) # needs sage.combinat - sage: QS2.get_order() # note: order changed on 2009-03-13 # needs sage.combinat + sage: QS2.get_order() # note: order changed on 2009-03-13 # needs sage.combinat [[2, 1], [1, 2]] """ if self._order is None: @@ -1670,7 +1669,7 @@ def _coerce_map_from_(self, R): return super()._coerce_map_from_(R) -class CartesianProductWithFlattening(): +class CartesianProductWithFlattening: """ A class for Cartesian product constructor, with partial flattening """ diff --git a/src/sage/combinat/free_prelie_algebra.py b/src/sage/combinat/free_prelie_algebra.py index 965c459720c..cb81e811ade 100644 --- a/src/sage/combinat/free_prelie_algebra.py +++ b/src/sage/combinat/free_prelie_algebra.py @@ -15,6 +15,7 @@ # the License, or (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +from itertools import product from sage.categories.magmatic_algebras import MagmaticAlgebras from sage.categories.lie_algebras import LieAlgebras @@ -26,6 +27,7 @@ from sage.categories.functor import Functor from sage.combinat.free_module import CombinatorialFreeModule +from sage.combinat.integer_vector import IntegerVectors from sage.combinat.words.alphabet import Alphabet from sage.combinat.rooted_tree import (RootedTrees, RootedTree, LabelledRootedTrees, @@ -34,6 +36,7 @@ from sage.misc.lazy_attribute import lazy_attribute from sage.misc.cachefunc import cached_method +from sage.functions.other import factorial from sage.sets.family import Family from sage.structure.coerce_exceptions import CoercionException @@ -530,6 +533,135 @@ def nap_product(self): codomain=self), position=1) + def corolla(self, x, y, n, N): + """ + Return the corolla obtained with ``x`` as root and ``y`` as leaves. + + INPUT: + + - ``x``, ``y`` -- two elements + - ``n`` -- integer; width of the corolla + - ``N`` -- integer; truncation order (up to order ``N`` included) + + OUTPUT: + + the sum over all possible ways to graft ``n`` copies of ``y`` + on top of ``x`` (with at most ``N`` vertices in total) + + This operation can be defined by induction starting from the + pre-Lie product. + + EXAMPLES:: + + sage: A = algebras.FreePreLie(QQ) + sage: a = A.gen(0) + sage: b = A.corolla(a,a,1,4); b + B[[[]]] + sage: A.corolla(b,b,2,7) + B[[[[[]], [[]]]]] + 2*B[[[[]], [[[]]]]] + B[[[], [[]], [[]]]] + + sage: A = algebras.FreePreLie(QQ, 'o') + sage: a = A.gen(0) + sage: b = A.corolla(a,a,1,4) + + sage: A = algebras.FreePreLie(QQ,'ab') + sage: a, b = A.gens() + sage: A.corolla(a,b,1,4) + B[a[b[]]] + sage: A.corolla(b,a,3,4) + B[b[a[], a[], a[]]] + + sage: A.corolla(a+b,a+b,2,4) + B[a[a[], a[]]] + 2*B[a[a[], b[]]] + B[a[b[], b[]]] + B[b[a[], a[]]] + + 2*B[b[a[], b[]]] + B[b[b[], b[]]] + + TESTS:: + + sage: A = algebras.FreePreLie(QQ,'ab') + sage: a, b = A.gens() + sage: A.corolla(a,A.zero(),2,2) + 0 + """ + if not x or not y: + return self.zero() + + basering = self.base_ring() + vx = x.valuation() + vy = y.valuation() + min_deg = vy * n + vx + if min_deg > N: + return self.zero() + + try: + self.gen(0).support()[0].label() + labels = True + except AttributeError: + labels = False + + deg_x = x.maximal_degree() + deg_y = y.maximal_degree() + max_x = min(deg_x, N - n * vy) + max_y = min(deg_y, N - vx - (n - 1) * vy) + xx = x.truncate(max_x + 1) + yy = y.truncate(max_y + 1) + + y_homog = {i: list(yy.homogeneous_component(i)) + for i in range(vy, max_y + 1)} + resu = self.zero() + for k in range(min_deg, N + 1): # total degree of (x ; y, y, y, y) + for mx, coef_x in xx: + dx = mx.node_number() + step = self.zero() + for pi in IntegerVectors(k - dx, n, min_part=vy, max_part=max_y): + for ly in product(*[y_homog[part] for part in pi]): + coef_y = basering.prod(mc[1] for mc in ly) + arbres_y = [mc[0] for mc in ly] + step += coef_y * self.sum(self(t) + for t in corolla_gen(mx, arbres_y, labels)) + resu += coef_x * step + return resu + + def group_product(self, x, y, n, N=10): + r""" + Return the truncated group product of ``x`` and ``y``. + + This is a weighted sum of all corollas with up to ``n`` leaves, with + ``x`` as root and ``y`` as leaves. + + The result is computed up to order ``N`` (included). + + When considered with infinitely many terms and infinite precision, + this is an analogue of the Baker-Campbell-Hausdorff formula: it + defines an associative product on the completed free pre-Lie algebra. + + INPUT: + + - ``x``, ``y`` -- two elements + - ``n`` -- integer; the maximal width of corollas + - ``N`` -- integer (default: 10); truncation order + + EXAMPLES: + + In the free pre-Lie algebra with one generator:: + + sage: PL = algebras.FreePreLie(QQ) + sage: a = PL.gen(0) + sage: PL.group_product(a, a, 3, 3) + B[[]] + B[[[]]] + 1/2*B[[[], []]] + + In the free pre-Lie algebra with several generators:: + + sage: PL = algebras.FreePreLie(QQ,'@O') + sage: a, b = PL.gens() + sage: PL.group_product(a, b, 3, 3) + B[@[]] + B[@[O[]]] + 1/2*B[@[O[], O[]]] + sage: PL.group_product(a, b, 3, 10) + B[@[]] + B[@[O[]]] + 1/2*B[@[O[], O[]]] + 1/6*B[@[O[], O[], O[]]] + """ + br = self.base_ring() + return x + self.sum(self.corolla(x, y, i, N) * ~br(factorial(i)) + for i in range(1, n + 1)) + def _element_constructor_(self, x): r""" Convert ``x`` into ``self``. @@ -703,6 +835,40 @@ def lift(self): for x, cf in self.monomial_coefficients(copy=False).items()} return UEA.element_class(UEA, data) + def valuation(self): + """ + Return the valuation of ``self``. + + EXAMPLES:: + + sage: a = algebras.FreePreLie(QQ).gen(0) + sage: a.valuation() + 1 + sage: (a*a).valuation() + 2 + + sage: a, b = algebras.FreePreLie(QQ,'ab').gens() + sage: (a+b).valuation() + 1 + sage: (a*b).valuation() + 2 + sage: (a*b+a).valuation() + 1 + + TESTS:: + + sage: z = algebras.FreePreLie(QQ).zero() + sage: z.valuation() + +Infinity + """ + if self == self.parent().zero(): + return Infinity + i = 0 + while True: + i += 1 + if self.homogeneous_component(i): + return i + class PreLieFunctor(ConstructionFunctor): """ @@ -872,3 +1038,106 @@ def _repr_(self): PreLie[x,y,z,t] """ return "PreLie[%s]" % ','.join(self.vars) + + +def tree_from_sortkey(ch, labels=True): + r""" + Transform a list of ``(valence, label)`` into a tree and a remainder. + + This is like an inverse of the ``sort_key`` method. + + INPUT: + + - ``ch`` -- a list of pairs ``(integer, label)`` + - ``labels`` -- (default ``True``) whether to use labelled trees + + OUTPUT: + + a pair ``(tree, remainder of the input)`` + + EXAMPLES:: + + sage: from sage.combinat.free_prelie_algebra import tree_from_sortkey + sage: a = algebras.FreePreLie(QQ).gen(0) + sage: t = (a*a*a*a).support() + sage: all(tree_from_sortkey(u.sort_key(), False)[0] == u for u in t) + True + + sage: a, b = algebras.FreePreLie(QQ,'ab').gens() + sage: t = (a*b*a*b).support() + sage: all(tree_from_sortkey(u.sort_key())[0] == u for u in t) + True + """ + if labels: + Trees = LabelledRootedTrees() + width, label = ch[0] + else: + Trees = RootedTrees() + width = ch[0] + + remainder = ch[1:] + if width == 0: + if labels: + return (Trees([], label), remainder) + return (Trees([]), remainder) + + branches = {} + for i in range(width): + tree, remainder = tree_from_sortkey(remainder, labels=labels) + branches[i] = tree + + if labels: + return (Trees(branches.values(), label), remainder) + return (Trees(branches.values()), remainder) + + +def corolla_gen(tx, list_ty, labels=True): + """ + Yield the terms in the corolla with given bottom tree and top trees. + + These are the possible terms in the simultaneous grafting of the + top trees on vertices of the bottom tree. + + INPUT: + + - ``tx`` -- a tree + - ``list_ty`` -- a list of trees + + EXAMPLES:: + + sage: from sage.combinat.free_prelie_algebra import corolla_gen + sage: a = algebras.FreePreLie(QQ).gen(0) + sage: ta = a.support()[0] + sage: list(corolla_gen(ta,[ta],False)) + [[[]]] + + sage: a, b = algebras.FreePreLie(QQ,'ab').gens() + sage: ta = a.support()[0] + sage: tb = b.support()[0] + sage: ab = (a*b).support()[0] + sage: list(corolla_gen(ta,[tb])) + [a[b[]]] + sage: list(corolla_gen(tb,[ta,ta])) + [b[a[], a[]]] + sage: list(corolla_gen(ab,[ab,ta])) + [a[a[], b[], a[b[]]], a[a[b[]], b[a[]]], a[a[], b[a[b[]]]], + a[b[a[], a[b[]]]]] + """ + n = len(list_ty) + zx = tx.sort_key() + nx = len(zx) + liste_zy = [t.sort_key() for t in list_ty] + for list_pos in product(range(nx), repeat=n): + new_zx = tuple(zx) + data = zip(list_pos, liste_zy) + sorted_data = sorted(data, reverse=True) + for pos_t in sorted_data: + if labels: + idx, lbl = new_zx[pos_t[0]] + new_zx = (new_zx[:pos_t[0]] + ((idx + 1, lbl),) + + pos_t[1] + new_zx[pos_t[0] + 1:]) + else: + idx = new_zx[pos_t[0]] + new_zx = (new_zx[:pos_t[0]] + (idx + 1,) + + pos_t[1] + new_zx[pos_t[0] + 1:]) + yield tree_from_sortkey(new_zx, labels=labels)[0] diff --git a/src/sage/combinat/growth.py b/src/sage/combinat/growth.py index 951d774931e..1b711ddde5f 100644 --- a/src/sage/combinat/growth.py +++ b/src/sage/combinat/growth.py @@ -4348,7 +4348,7 @@ def union(la, mu): ##################################################################### -class Rules(): +class Rules: """ Catalog of rules for growth diagrams. """ diff --git a/src/sage/combinat/hillman_grassl.py b/src/sage/combinat/hillman_grassl.py index 1abbc3d56bd..5a85d4e48d3 100644 --- a/src/sage/combinat/hillman_grassl.py +++ b/src/sage/combinat/hillman_grassl.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" The Hillman-Grassl correspondence diff --git a/src/sage/combinat/integer_lists/invlex.pyx b/src/sage/combinat/integer_lists/invlex.pyx index b517a108479..07036085ac0 100644 --- a/src/sage/combinat/integer_lists/invlex.pyx +++ b/src/sage/combinat/integer_lists/invlex.pyx @@ -99,7 +99,7 @@ class IntegerListsLex(IntegerLists, metaclass=ClasscallMetaclass): value is `\infty`. - ``min_slope`` -- an integer or `-\infty` (default: `-\infty`): - an lower bound on the slope between consecutive parts: + a lower bound on the slope between consecutive parts: ``min_slope <= l[i+1]-l[i]`` for ``0 <= i < len(l)-1`` - ``max_slope`` -- an integer or `+\infty` (defaults: `+\infty`) @@ -796,7 +796,7 @@ class IntegerListsLex(IntegerLists, metaclass=ClasscallMetaclass): cdef class IntegerListsBackend_invlex(IntegerListsBackend): """ - Cython back-end of an set of lists of integers with specified + Cython back-end of a set of lists of integers with specified constraints enumerated in inverse lexicographic order. """ def __init__(self, *args, check=True, **kwds): diff --git a/src/sage/combinat/interval_posets.py b/src/sage/combinat/interval_posets.py index c9f1e99984d..260a3aa6b48 100644 --- a/src/sage/combinat/interval_posets.py +++ b/src/sage/combinat/interval_posets.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Tamari Interval-posets diff --git a/src/sage/combinat/k_tableau.py b/src/sage/combinat/k_tableau.py index 0e4bbc41758..69feb00dd8b 100644 --- a/src/sage/combinat/k_tableau.py +++ b/src/sage/combinat/k_tableau.py @@ -4225,7 +4225,7 @@ def add_marking( cls, unmarkedT, marking, k, weight ): r""" Add markings to a partially marked strong tableau. - Given an partially marked standard tableau and a list of cells where the marks + Given a partially marked standard tableau and a list of cells where the marks should be placed along with a ``weight``, return the semi-standard marked strong tableau. The marking should complete the marking so that the result is a strong standard marked tableau. diff --git a/src/sage/combinat/knutson_tao_puzzles.py b/src/sage/combinat/knutson_tao_puzzles.py index 72c3ea9c52e..1c0215fa093 100644 --- a/src/sage/combinat/knutson_tao_puzzles.py +++ b/src/sage/combinat/knutson_tao_puzzles.py @@ -51,7 +51,7 @@ from sage.structure.unique_representation import UniqueRepresentation -class PuzzlePiece(): +class PuzzlePiece: r""" Abstract class for puzzle pieces. @@ -621,7 +621,7 @@ def edges(self) -> tuple: return ('north_west', 'north_east', 'south_east', 'south_west') -class PuzzlePieces(): +class PuzzlePieces: r""" Construct a valid set of puzzle pieces. @@ -1068,7 +1068,7 @@ def BK_pieces(max_letter): return pieces -class PuzzleFilling(): +class PuzzleFilling: r""" Create partial puzzles and provides methods to build puzzles from them. """ diff --git a/src/sage/combinat/matrices/hadamard_matrix.py b/src/sage/combinat/matrices/hadamard_matrix.py index 0693941851e..29276a3ddad 100644 --- a/src/sage/combinat/matrices/hadamard_matrix.py +++ b/src/sage/combinat/matrices/hadamard_matrix.py @@ -324,7 +324,7 @@ def hadamard_matrix_miyamoto_construction(n, existence=False, check=True): r""" Construct Hadamard matrix using the Miyamoto construction. - If `q = n/4` is a prime power, and there exists an Hadamard matrix of order + If `q = n/4` is a prime power, and there exists a Hadamard matrix of order `q-1`, then a Hadamard matrix of order `n` can be constructed (see [Miy1991]_). INPUT: @@ -442,7 +442,7 @@ def hadamard_matrix_williamson_type(a, b, c, d, check=True): - ``d`` -- (1,-1) list; the 1st row of `C` - ``c`` -- (1,-1) list; the 1st row of `D` - ``check`` -- boolean (default: ``True``); whether to check that the output - is an Hadamard matrix before returning it + is a Hadamard matrix before returning it EXAMPLES:: @@ -640,7 +640,7 @@ def williamson_hadamard_matrix_smallcases(n, existence=False, check=True): def hadamard_matrix_156(): r""" - Construct an Hadamard matrix of order 156. + Construct a Hadamard matrix of order 156. The matrix is created using the construction detailed in [BH1965]_. This uses four circulant matrices of size `13\times 13`, @@ -1030,13 +1030,13 @@ def hadamard_matrix_from_sds(n, existence=False, check=True): def hadamard_matrix_cooper_wallis_construction(x1, x2, x3, x4, A, B, C, D, check=True): r""" - Create an Hadamard matrix using the contruction detailed in [CW1972]_. + Create a Hadamard matrix using the contruction detailed in [CW1972]_. Given four circulant matrices `X_1`, X_2, X_3, X_4` of order `n` with entries (0, 1, -1) such that the entrywise product of two distinct matrices is always equal to `0` and that `\sum_{i=1}^{4}X_iX_i^\top = nI_n` holds, and four matrices `A, B, C, D` of order `m` with elements (1, -1) such that `MN^\top = NM^\top` for all distinct `M`, `N` and - `AA^\top + BB^\top + CC^\top + DD^\top = 4mI_n` holds, we construct an Hadamard matrix + `AA^\top + BB^\top + CC^\top + DD^\top = 4mI_n` holds, we construct a Hadamard matrix of order `4nm`. INPUT: @@ -1125,7 +1125,7 @@ def hadamard_matrix_cooper_wallis_smallcases(n, check=True, existence=False): - ``n`` -- integer; the order of the matrix to be constructed - ``check`` -- boolean (default: ``True``); if ``True``, check that the matrix - is an Hadamard matrix before returning + is a Hadamard matrix before returning - ``existence`` -- boolean (default: ``False``); if ``True``, only check if the matrix exists. @@ -1298,7 +1298,7 @@ def hadamard_matrix_turyn_type(a, b, c, d, e1, e2, e3, e4, check=True): - ``e3`` -- Matrix; the third Baumert-Hall unit - ``e4`` -- Matrix; the fourth Baumert-Hall unit - ``check`` -- boolean (default: ``True``); whether to check that the output - is an Hadamard matrix before returning it + is a Hadamard matrix before returning it EXAMPLES:: @@ -1352,11 +1352,11 @@ def hadamard_matrix_turyn_type(a, b, c, d, e1, e2, e3, e4, check=True): def turyn_type_hadamard_matrix_smallcases(n, existence=False, check=True): r""" - Construct an Hadamard matrix of order `n` from available 4-symbol `\delta` codes and Williamson quadruples. + Construct a Hadamard matrix of order `n` from available 4-symbol `\delta` codes and Williamson quadruples. The function looks for Baumert-Hall units and Williamson type matrices from :func:`four_symbol_delta_code_smallcases` and :func:`williamson_type_quadruples_smallcases` - and use them to construct an Hadamard matrix with the Turyn construction + and use them to construct a Hadamard matrix with the Turyn construction defined in :func:`hadamard_matrix_turyn_type`. INPUT: @@ -1365,7 +1365,7 @@ def turyn_type_hadamard_matrix_smallcases(n, existence=False, check=True): - ``existence`` -- boolean (default: ``False``): if ``True``, only check if the matrix exists - ``check`` -- boolean (default: ``True``): if ``True``, check that the matrix - is an Hadamard matrix before returning + is a Hadamard matrix before returning EXAMPLES:: @@ -1407,7 +1407,7 @@ def turyn_type_hadamard_matrix_smallcases(n, existence=False, check=True): def hadamard_matrix_spence_construction(n, existence=False, check=True): r""" - Create an Hadamard matrix of order `n` using the Spence construction. + Create a Hadamard matrix of order `n` using the Spence construction. This construction (detailed in [Spe1975]_), uses supplementary difference sets implemented in :func:`sage.combinat.designs.difference_family.supplementary_difference_set_from_rel_diff_set` to create the @@ -1419,7 +1419,7 @@ def hadamard_matrix_spence_construction(n, existence=False, check=True): - ``existence`` -- boolean (default: ``False``); if ``True``, only check if the matrix exists - ``check`` -- bolean (default: ``True``); if ``True``, check that the matrix - is an Hadamard matrix before returning + is a Hadamard matrix before returning OUTPUT: @@ -2968,7 +2968,7 @@ def skew_hadamard_matrix_from_good_matrices_smallcases(n, existence=False, check - ``existence`` -- boolean (default: ``False``); If ``True``, only return whether the Hadamard matrix can be constructed - ``check`` -- boolean (default: ``True``): if ``True``, check that the matrix - is an Hadamard matrix before returning it + is a Hadamard matrix before returning it OUTPUT: diff --git a/src/sage/combinat/matrices/latin.py b/src/sage/combinat/matrices/latin.py index 1a369bba355..460c44a6441 100644 --- a/src/sage/combinat/matrices/latin.py +++ b/src/sage/combinat/matrices/latin.py @@ -1531,7 +1531,7 @@ def isotopism(p): if isinstance(p, tuple): # We have a single cycle: if isinstance(p[0], Integer): - return Permutation(tuple((x+1 for x in p))) + return Permutation(tuple(x+1 for x in p)) # We have a tuple of cycles: if isinstance(p[0], tuple): diff --git a/src/sage/combinat/misc.py b/src/sage/combinat/misc.py index 8034531ed19..2a4341e8f4c 100644 --- a/src/sage/combinat/misc.py +++ b/src/sage/combinat/misc.py @@ -19,7 +19,7 @@ from sage.misc.misc_c import prod -class DoublyLinkedList(): +class DoublyLinkedList: """ A doubly linked list class that provides constant time hiding and unhiding of entries. diff --git a/src/sage/combinat/multiset_partition_into_sets_ordered.py b/src/sage/combinat/multiset_partition_into_sets_ordered.py index c544d9ae2ef..967f6ad93af 100755 --- a/src/sage/combinat/multiset_partition_into_sets_ordered.py +++ b/src/sage/combinat/multiset_partition_into_sets_ordered.py @@ -3394,7 +3394,7 @@ def val(self, q='q'): Verifying Example 4.5 from [BCHOPSY2017]_:: - sage: B = crystals.Minimaj(3, 4, 2) # for `Val_{4,1}^{(3)}` # needs sage.modules + sage: B = crystals.Minimaj(3, 4, 2) # for `Val_{4,1}^{(3)}` # needs sage.modules sage: B.val() # needs sage.modules (q^2+q+1)*s[2, 1, 1] + q*s[2, 2] """ diff --git a/src/sage/combinat/ncsf_qsym/ncsf.py b/src/sage/combinat/ncsf_qsym/ncsf.py index 0d91379f408..91284a4186f 100644 --- a/src/sage/combinat/ncsf_qsym/ncsf.py +++ b/src/sage/combinat/ncsf_qsym/ncsf.py @@ -1999,7 +1999,7 @@ def image_of_L_k(k, i): return x[i-1] * image_of_L_k(k - 1, i - 1) + image_of_L_k(k, i - 1) def on_basis(comp): - return P.prod((image_of_L_k(k, n) for k in comp)) + return P.prod(image_of_L_k(k, n) for k in comp) return L._apply_module_morphism(L(self), on_basis, codomain=P) class MultiplicativeBases(Category_realization_of_parent): diff --git a/src/sage/combinat/ordered_tree.py b/src/sage/combinat/ordered_tree.py index 59f4a4ad115..5041dd434a4 100644 --- a/src/sage/combinat/ordered_tree.py +++ b/src/sage/combinat/ordered_tree.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Ordered Rooted Trees diff --git a/src/sage/combinat/output.py b/src/sage/combinat/output.py index 6e9d2943cfd..7f223921d7e 100644 --- a/src/sage/combinat/output.py +++ b/src/sage/combinat/output.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Output functions @@ -505,7 +504,7 @@ def ascii_art_table(data, use_unicode=False, convention="English"): def get_len(e): if e is None: return 0 - return len(e) - list(str(e)).count(u"\u0304") + return len(e) - list(str(e)).count("\u0304") else: def get_len(e): if e is None: @@ -692,7 +691,7 @@ def ascii_art_table_russian(data, use_unicode=False, compact=False): def get_len(e): if e is None: return 0 - return len(e) - list(str(e)).count(u"\u0304") + return len(e) - list(str(e)).count("\u0304") else: def get_len(e): if e is None: diff --git a/src/sage/combinat/parallelogram_polyomino.py b/src/sage/combinat/parallelogram_polyomino.py index 190eeedef72..53d35bca831 100644 --- a/src/sage/combinat/parallelogram_polyomino.py +++ b/src/sage/combinat/parallelogram_polyomino.py @@ -2088,7 +2088,7 @@ def is_k_directed(self, k) -> bool: INPUT: - - ``k`` -- An non negative integer. + - ``k`` -- A non negative integer. EXAMPLES:: @@ -3958,7 +3958,7 @@ def _latex_drawing(self): ... \end{tikzpicture} """ - latex.add_package_to_preamble_if_available(str("tikz")) + latex.add_package_to_preamble_if_available("tikz") tikz_options = self.get_tikz_options() res = "\n\\begin{tikzpicture}[scale=%s]" % (tikz_options['scale']) res += self.to_tikz() diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 7d16d5d3410..ee5a9fd85db 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Integer partitions @@ -668,23 +667,23 @@ def _unicode_art_(self): from sage.typeset.unicode_art import UnicodeArt if not self._list: - return UnicodeArt(u'∅', baseline=0) + return UnicodeArt('∅', baseline=0) if self.parent().options.convention == "English": data = list(self) else: data = list(reversed(self)) - txt = [u'┌' + u'┬' * (data[0] - 1) + u'┐'] + txt = ['┌' + '┬' * (data[0] - 1) + '┐'] for i in range(len(data) - 1): p = data[i] q = data[i + 1] if p < q: - txt += [u'├' + u'┼' * p + u'┬' * (q - p - 1) + u'┐'] + txt += ['├' + '┼' * p + '┬' * (q - p - 1) + '┐'] elif p == q: - txt += [u'├' + u'┼' * (p - 1) + u'┤'] + txt += ['├' + '┼' * (p - 1) + '┤'] else: - txt += [u'├' + u'┼' * q + u'┴' * (p - q - 1) + u'┘'] - txt += [u'└' + u'┴' * (data[-1] - 1) + u'┘'] + txt += ['├' + '┼' * q + '┴' * (p - q - 1) + '┘'] + txt += ['└' + '┴' * (data[-1] - 1) + '┘'] return UnicodeArt(txt, baseline=0) @@ -4900,14 +4899,14 @@ def remove_horizontal_border_strip(self, k): :class:`Partitions_with_constraints`:: sage: Partition([5,3,1]).remove_horizontal_border_strip(5) - The subpartitions of [5, 3, 1] obtained by removing an horizontal border strip of length 5 + The subpartitions of [5, 3, 1] obtained by removing a horizontal border strip of length 5 TESTS:: sage: Partition([3,2,2]).remove_horizontal_border_strip(2).list() [[3, 2], [2, 2, 1]] sage: Partition([3,2,2]).remove_horizontal_border_strip(2).first().parent() - The subpartitions of [3, 2, 2] obtained by removing an horizontal border strip of length 2 + The subpartitions of [3, 2, 2] obtained by removing a horizontal border strip of length 2 sage: Partition([]).remove_horizontal_border_strip(0).list() [[]] sage: Partition([]).remove_horizontal_border_strip(6).list() @@ -4919,7 +4918,7 @@ def remove_horizontal_border_strip(self, k): floor=self[1:] + [0], ceiling=self[:], max_slope=0, - name=f"The subpartitions of {self} obtained by removing an horizontal border strip of length {k}") + name=f"The subpartitions of {self} obtained by removing a horizontal border strip of length {k}") def k_conjugate(self, k): r""" @@ -5549,9 +5548,9 @@ def simple_module_dimension(self, base_ring=None): sage: Partition([2,2,1]).simple_module_dimension() 5 - sage: Partition([2,2,1]).specht_module_dimension(GF(3)) # optional - sage.rings.finite_rings + sage: Partition([2,2,1]).specht_module_dimension(GF(3)) # needs sage.rings.finite_rings 5 - sage: Partition([2,2,1]).simple_module_dimension(GF(3)) # optional - sage.rings.finite_rings + sage: Partition([2,2,1]).simple_module_dimension(GF(3)) # needs sage.rings.finite_rings 4 sage: for la in Partitions(6, regular=3): @@ -6736,9 +6735,9 @@ def random_element(self, measure='uniform'): EXAMPLES:: - sage: Partitions(5).random_element() # random # needs sage.libs.flint + sage: Partitions(5).random_element() # random # needs sage.libs.flint [2, 1, 1, 1] - sage: Partitions(5).random_element(measure='Plancherel') # random # needs sage.libs.flint + sage: Partitions(5).random_element(measure='Plancherel') # random # needs sage.libs.flint [2, 1, 1, 1] """ if measure == 'uniform': @@ -6756,7 +6755,7 @@ def random_element_uniform(self): sage: Partitions(5).random_element_uniform() # random # needs sage.libs.flint [2, 1, 1, 1] - sage: Partitions(20).random_element_uniform() # random # needs sage.libs.flint + sage: Partitions(20).random_element_uniform() # random # needs sage.libs.flint [9, 3, 3, 2, 2, 1] TESTS:: diff --git a/src/sage/combinat/partition_algebra.py b/src/sage/combinat/partition_algebra.py index a52fc93c338..b5caf31d84b 100644 --- a/src/sage/combinat/partition_algebra.py +++ b/src/sage/combinat/partition_algebra.py @@ -1931,7 +1931,7 @@ def to_set_partition(l, k=None): if not l: return Set([]) else: - k = max((max(map(abs, x)) for x in l)) + k = max(max(map(abs, x)) for x in l) to_be_added = Set(list(range(1, k + 1)) + [-x for x in range(1, k + 1)]) diff --git a/src/sage/combinat/partition_kleshchev.py b/src/sage/combinat/partition_kleshchev.py index 29936e4db39..df8b31b552e 100644 --- a/src/sage/combinat/partition_kleshchev.py +++ b/src/sage/combinat/partition_kleshchev.py @@ -861,7 +861,7 @@ def is_restricted(self): return _is_restricted(self.to_list(), KP._multicharge, KP._convention) -class KleshchevCrystalMixin(): +class KleshchevCrystalMixin: """ Mixin class for the crystal structure of a Kleshchev partition. """ diff --git a/src/sage/combinat/perfect_matching.py b/src/sage/combinat/perfect_matching.py index 70c8652841c..84e481cb621 100644 --- a/src/sage/combinat/perfect_matching.py +++ b/src/sage/combinat/perfect_matching.py @@ -215,7 +215,7 @@ def _repr_(self): sage: PerfectMatching([3,8,1,7,6,5,4,2]) [(1, 3), (2, 8), (4, 7), (5, 6)] """ - return '[' + ', '.join(('(' + repr(sorted(x))[1:-1] + ')' for x in self)) + ']' + return '[' + ', '.join('(' + repr(sorted(x))[1:-1] + ')' for x in self) + ']' def _latex_(self): r""" diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index 3ed9a0a43fd..ba712588cf6 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Permutations diff --git a/src/sage/combinat/plane_partition.py b/src/sage/combinat/plane_partition.py index 21b8bb84334..b4f897b64f3 100644 --- a/src/sage/combinat/plane_partition.py +++ b/src/sage/combinat/plane_partition.py @@ -387,9 +387,9 @@ def _repr_diagram(self, show_box=False, use_unicode=False) -> str: drawing = [[" " for i in range(2 * x + y + z)] for j in range(y + z + 1)] - hori = u"_" if use_unicode else "_" - down = u"╲" if use_unicode else "\\" - up = u"╱" if use_unicode else "/" + hori = "_" if use_unicode else "_" + down = "╲" if use_unicode else "\\" + up = "╱" if use_unicode else "/" def superpose(l, c, letter): # add the given letter at line l and column c @@ -449,10 +449,10 @@ def add_leftside(i, j, k): check = False if not drawing: - return u"∅" if use_unicode else "" + return "∅" if use_unicode else "" if use_unicode: - return u'\n'.join(u"".join(row) for row in drawing) + return '\n'.join("".join(row) for row in drawing) return '\n'.join("".join(row) for row in drawing) def _ascii_art_(self): @@ -1548,7 +1548,7 @@ def __init__(self, box_size): EXAMPLES:: sage: PP = PlanePartitions([4,3,2]) - sage: TestSuite(PP).run() # long time, needs sage.modules + sage: TestSuite(PP).run() # long time # needs sage.modules """ super().__init__(box_size, category=FiniteEnumeratedSets()) diff --git a/src/sage/combinat/posets/lattices.py b/src/sage/combinat/posets/lattices.py index 8fb9055afdb..6af274fd18a 100644 --- a/src/sage/combinat/posets/lattices.py +++ b/src/sage/combinat/posets/lattices.py @@ -2298,8 +2298,8 @@ def is_orthocomplemented(self, unique=False): sage: D6.is_orthocomplemented(unique=True) # needs sage.groups False - sage: hexagon = LatticePoset({0:[1, 2], 1:[3], 2:[4], 3:[5], 4:[5]}) - sage: hexagon.is_orthocomplemented(unique=True) + sage: hexagon = LatticePoset({0: [1, 2], 1: [3], 2: [4], 3:[5], 4: [5]}) + sage: hexagon.is_orthocomplemented(unique=True) # needs sage.groups True .. SEEALSO:: @@ -4046,7 +4046,7 @@ def is_subdirectly_reducible(self, certificate=False): TESTS:: - sage: [posets.ChainPoset(i).is_subdirectly_reducible() for i in range(5)] + sage: [posets.ChainPoset(i).is_subdirectly_reducible() for i in range(5)] # needs sage.combinat [False, False, False, True, True] """ H = self._hasse_diagram @@ -4256,7 +4256,7 @@ def is_constructible_by_doublings(self, type) -> bool: sage: L = L.day_doubling([(3,0), (1,1), (2,1)]) # An upper pseudo-interval sage: L.is_constructible_by_doublings('upper') False - sage: L.is_constructible_by_doublings('convex') + sage: L.is_constructible_by_doublings('convex') # needs sage.combinat True An example of a lattice that can be constructed by doublings @@ -4378,18 +4378,20 @@ def is_isoform(self, certificate=False): EXAMPLES:: - sage: L = LatticePoset({1:[2, 3, 4], 2: [5, 6], 3: [6, 7], 4: [7], 5: [8], 6: [8], 7: [8]}) - sage: L.is_isoform() + sage: L = LatticePoset({1: [2, 3, 4], 2: [5, 6], 3: [6, 7], + ....: 4: [7], 5: [8], 6: [8], 7: [8]}) + sage: L.is_isoform() # needs sage.combinat True Every isoform lattice is (trivially) uniform, but the converse is not true:: - sage: L = LatticePoset({1: [2, 3, 6], 2: [4, 5], 3: [5], 4: [9, 8], 5: [7, 8], 6: [9], 7: [10], 8: [10], 9: [10]}) - sage: L.is_isoform(), L.is_uniform() + sage: L = LatticePoset({1: [2, 3, 6], 2: [4, 5], 3: [5], 4: [9, 8], + ....: 5: [7, 8], 6: [9], 7: [10], 8: [10], 9: [10]}) + sage: L.is_isoform(), L.is_uniform() # needs sage.combinat (False, True) - sage: L.is_isoform(certificate=True) + sage: L.is_isoform(certificate=True) # needs sage.combinat (False, {{1, 2, 4, 6, 9}, {3, 5, 7, 8, 10}}) .. SEEALSO:: @@ -4404,7 +4406,7 @@ def is_isoform(self, certificate=False): sage: [posets.ChainPoset(i).is_isoform() for i in range(5)] [True, True, True, False, False] - sage: posets.DiamondPoset(5).is_isoform() # Simple, so trivially isoform + sage: posets.DiamondPoset(5).is_isoform() # Simple, so trivially isoform # needs sage.combinat True """ ok = (True, None) if certificate else True @@ -4451,8 +4453,9 @@ def is_uniform(self, certificate=False): EXAMPLES:: - sage: L = LatticePoset({1: [2, 3, 4], 2: [6, 7], 3: [5], 4: [5], 5: [9, 8], 6: [9], 7: [10], 8: [10], 9: [10]}) - sage: L.is_uniform() + sage: L = LatticePoset({1: [2, 3, 4], 2: [6, 7], 3: [5], 4: [5], + ....: 5: [9, 8], 6: [9], 7: [10], 8: [10], 9: [10]}) + sage: L.is_uniform() # needs sage.combinat True Every uniform lattice is regular, but the converse is not true:: @@ -4461,7 +4464,7 @@ def is_uniform(self, certificate=False): sage: N6.is_uniform(), N6.is_regular() (False, True) - sage: N6.is_uniform(certificate=True) + sage: N6.is_uniform(certificate=True) # needs sage.combinat (False, {{1, 2, 3, 4}, {5, 6}}) .. SEEALSO:: @@ -4475,7 +4478,7 @@ def is_uniform(self, certificate=False): sage: [posets.ChainPoset(i).is_uniform() for i in range(5)] [True, True, True, False, False] - sage: posets.DiamondPoset(5).is_uniform() # Simple, so trivially uniform + sage: posets.DiamondPoset(5).is_uniform() # Simple, so trivially uniform # needs sage.combinat True """ ok = (True, None) if certificate else True @@ -4532,14 +4535,15 @@ def is_regular(self, certificate=False): EXAMPLES:: - sage: L = LatticePoset({1: [2, 3, 4], 2: [5, 6], 3: [8, 7], 4: [6, 7], 5: [8], 6: [9], 7: [9], 8: [9]}) - sage: L.is_regular() + sage: L = LatticePoset({1: [2, 3, 4], 2: [5, 6], 3: [8, 7], 4: [6, 7], + ....: 5: [8], 6: [9], 7: [9], 8: [9]}) + sage: L.is_regular() # needs sage.combinat True sage: N5 = posets.PentagonPoset() - sage: N5.is_regular() + sage: N5.is_regular() # needs sage.combinat False - sage: N5.is_regular(certificate=True) + sage: N5.is_regular(certificate=True) # needs sage.combinat (False, ({{0}, {1}, {2, 3}, {4}}, [0])) .. SEEALSO:: @@ -4552,7 +4556,7 @@ def is_regular(self, certificate=False): TESTS:: - sage: [posets.ChainPoset(i).is_regular() for i in range(5)] + sage: [posets.ChainPoset(i).is_regular() for i in range(5)] # needs sage.combinat [True, True, True, False, False] """ ok = (True, None) if certificate else True @@ -4598,6 +4602,7 @@ def is_simple(self, certificate=False): EXAMPLES:: + sage: # needs sage.combinat sage: posets.DiamondPoset(5).is_simple() # Smallest nontrivial example True sage: L = LatticePoset({1: [2, 3], 2: [4, 5], 3: [6], 4: [6], 5: [6]}) @@ -4611,11 +4616,11 @@ def is_simple(self, certificate=False): sage: L = LatticePoset({1: [2, 3, 4], 2: [5], 3: [5], 4: [6, 7], ....: 5: [8], 6: [8], 7: [8]}) - sage: L.is_simple() + sage: L.is_simple() # needs sage.combinat False sage: L = LatticePoset({1: [2, 3], 2: [4, 5], 3: [6, 7], 4: [8], ....: 5: [8], 6: [8], 7: [8]}) - sage: L.is_simple() + sage: L.is_simple() # needs sage.combinat True .. SEEALSO:: @@ -4652,9 +4657,10 @@ def subdirect_decomposition(self): EXAMPLES:: - sage: posets.ChainPoset(3).subdirect_decomposition() + sage: posets.ChainPoset(3).subdirect_decomposition() # needs sage.combinat [Finite lattice containing 2 elements, Finite lattice containing 2 elements] + sage: # needs sage.combinat sage: L = LatticePoset({1: [2, 4], 2: [3], 3: [6, 7], 4: [5, 7], ....: 5: [9, 8], 6: [9], 7: [9], 8: [10], 9: [10]}) sage: Ldecomp = L.subdirect_decomposition() @@ -4665,6 +4671,7 @@ def subdirect_decomposition(self): TESTS:: + sage: # needs sage.combinat sage: posets.ChainPoset(0).subdirect_decomposition() [Finite lattice containing 0 elements] sage: posets.ChainPoset(1).subdirect_decomposition() @@ -4676,7 +4683,7 @@ def subdirect_decomposition(self): has only one element:: sage: N5 = posets.PentagonPoset() - sage: N5.subdirect_decomposition() + sage: N5.subdirect_decomposition() # needs sage.combinat [Finite lattice containing 5 elements] """ H = self._hasse_diagram @@ -4737,6 +4744,7 @@ def congruence(self, S): EXAMPLES:: + sage: # needs sage.combinat sage: L = posets.DivisorLattice(12) sage: cong = L.congruence([[1, 3]]) sage: sorted(sorted(c) for c in cong) @@ -4745,19 +4753,20 @@ def congruence(self, S): {{1, 2, 4}, {3, 6, 12}} sage: L = LatticePoset({1: [2, 3], 2: [4], 3: [4], 4: [5]}) - sage: L.congruence([[1, 2]]) + sage: L.congruence([[1, 2]]) # needs sage.combinat {{1, 2}, {3, 4}, {5}} sage: L = LatticePoset({1: [2, 3], 2: [4, 5, 6], 4: [5], 5: [7, 8], ....: 6: [8], 3: [9], 7: [10], 8: [10], 9:[10]}) - sage: cong = L.congruence([[1, 2]]) - sage: cong[0] + sage: cong = L.congruence([[1, 2]]) # needs sage.combinat + sage: cong[0] # needs sage.combinat frozenset({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) .. SEEALSO:: :meth:`quotient` TESTS:: + sage: # needs sage.combinat sage: P = posets.PentagonPoset() sage: P.congruence([]) {{0}, {1}, {2}, {3}, {4}} @@ -4774,13 +4783,13 @@ def congruence(self, S): works:: sage: L = LatticePoset(DiGraph('P^??@_?@??B_?@??B??@_?@??B_?@??B??@??A??C??G??O???')) - sage: sorted(sorted(p) for p in L.congruence([[1,6]])) + sage: sorted(sorted(p) for p in L.congruence([[1,6]])) # needs sage.combinat [[0], [1, 6], [2], [3, 8], [4], [5, 10], [7, 12], [9, 14], [11], [13], [15], [16]] Simple lattice, i.e. a lattice without any nontrivial congruence:: sage: L = LatticePoset(DiGraph('GPb_@?OC@?O?')) - sage: L.congruence([[1,2]]) + sage: L.congruence([[1,2]]) # needs sage.combinat {{0, 1, 2, 3, 4, 5, 6, 7}} """ from sage.combinat.set_partition import SetPartition @@ -4821,6 +4830,7 @@ def quotient(self, congruence, labels='tuple'): EXAMPLES:: + sage: # needs sage.combinat sage: L = posets.PentagonPoset() sage: c = L.congruence([[0, 1]]) sage: I = L.quotient(c); I @@ -4831,6 +4841,7 @@ def quotient(self, congruence, labels='tuple'): sage: I.top() Finite lattice containing 3 elements + sage: # needs sage.combinat sage: B3 = posets.BooleanLattice(3) sage: c = B3.congruence([[0,1]]) sage: B2 = B3.quotient(c, labels='integer') @@ -4846,7 +4857,7 @@ def quotient(self, congruence, labels='tuple'): Finite lattice containing 0 elements sage: L = posets.PentagonPoset() - sage: L.quotient(L.congruence([[1]])).is_isomorphic(L) + sage: L.quotient(L.congruence([[1]])).is_isomorphic(L) # needs sage.combinat True """ if labels not in ['lattice', 'tuple', 'integer']: @@ -4894,6 +4905,7 @@ def congruences_lattice(self, labels='congruence'): EXAMPLES:: + sage: # needs sage.combinat sage: N5 = posets.PentagonPoset() sage: CL = N5.congruences_lattice(); CL Finite lattice containing 5 elements @@ -4903,12 +4915,13 @@ def congruences_lattice(self, labels='congruence'): [{{0, 1}, {2, 3, 4}}, {{0, 2, 3}, {1, 4}}] sage: C4 = posets.ChainPoset(4) - sage: CL = C4.congruences_lattice(labels='integer') - sage: CL.is_isomorphic(posets.BooleanLattice(3)) + sage: CL = C4.congruences_lattice(labels='integer') # needs sage.combinat + sage: CL.is_isomorphic(posets.BooleanLattice(3)) # needs sage.combinat True TESTS:: + sage: # needs sage.combinat sage: posets.ChainPoset(0).congruences_lattice() Finite lattice containing 1 elements sage: posets.ChainPoset(1).congruences_lattice() @@ -5002,6 +5015,7 @@ def feichtner_yuzvinsky_ring(self, G, use_defining=False, base_ring=None): We reproduce the example from Section 5 of [Coron2023]_:: + sage: # needs sage.geometry.polyhedron sage: H. = HyperplaneArrangements(QQ) sage: Arr = H(a-b, b-c, c-d, d-a) sage: P = LatticePoset(Arr.intersection_poset()) diff --git a/src/sage/combinat/posets/linear_extensions.py b/src/sage/combinat/posets/linear_extensions.py index 47792a7118f..cca9b098d4a 100644 --- a/src/sage/combinat/posets/linear_extensions.py +++ b/src/sage/combinat/posets/linear_extensions.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Linear Extensions of Posets diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index f8d10257c1f..0a8352274ee 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -3745,9 +3745,9 @@ def magnitude(self) -> Integer: sage: P.magnitude() == m1*m2 True - sage: Poset({}).magnitude() + sage: Poset({}).magnitude() # needs sage.libs.flint 0 - sage: Poset({1:[]}).magnitude() + sage: Poset({1: []}).magnitude() # needs sage.libs.flint 1 """ H = self._hasse_diagram @@ -4314,7 +4314,7 @@ def coxeter_transformation(self): EXAMPLES:: - sage: posets.PentagonPoset().coxeter_transformation() + sage: posets.PentagonPoset().coxeter_transformation() # needs sage.libs.flint [ 0 0 0 0 -1] [ 0 0 0 1 -1] [ 0 1 0 0 -1] @@ -4327,8 +4327,8 @@ def coxeter_transformation(self): TESTS:: - sage: M = posets.PentagonPoset().coxeter_transformation() - sage: M ** 8 == 1 + sage: M = posets.PentagonPoset().coxeter_transformation() # needs sage.libs.flint + sage: M ** 8 == 1 # needs sage.libs.flint True """ return self._hasse_diagram.coxeter_transformation() @@ -4348,11 +4348,11 @@ def coxeter_polynomial(self): EXAMPLES:: sage: P = posets.PentagonPoset() - sage: P.coxeter_polynomial() + sage: P.coxeter_polynomial() # needs sage.libs.flint x^5 + x^4 + x + 1 sage: p = posets.SymmetricGroupWeakOrderPoset(3) # needs sage.groups - sage: p.coxeter_polynomial() # needs sage.groups + sage: p.coxeter_polynomial() # needs sage.groups sage.libs.flint x^6 + x^5 - x^3 + x + 1 .. SEEALSO:: @@ -4398,7 +4398,7 @@ def coxeter_smith_form(self, algorithm='singular'): TESTS:: sage: P = posets.PentagonPoset() - sage: P.coxeter_smith_form(algorithm='sage') + sage: P.coxeter_smith_form(algorithm='sage') # needs sage.libs.flint [1, 1, 1, 1, x^5 + x^4 + x + 1] sage: P.coxeter_smith_form(algorithm='gap') # needs sage.libs.gap [1, 1, 1, 1, x^5 + x^4 + x + 1] @@ -8099,33 +8099,33 @@ def is_eulerian(self, k=None, certificate=False): sage: P = Poset({0: [1, 2, 3], 1: [4, 5], 2: [4, 6], 3: [5, 6], ....: 4: [7, 8], 5: [7, 8], 6: [7, 8], 7: [9], 8: [9]}) - sage: P.is_eulerian() + sage: P.is_eulerian() # needs sage.libs.flint True sage: P = Poset({0: [1, 2, 3], 1: [4, 5, 6], 2: [4, 6], 3: [5,6], ....: 4: [7], 5:[7], 6:[7]}) - sage: P.is_eulerian() + sage: P.is_eulerian() # needs sage.libs.flint False Canonical examples of Eulerian posets are the face lattices of convex polytopes:: sage: P = polytopes.cube().face_lattice() # needs sage.geometry.polyhedron - sage: P.is_eulerian() # needs sage.geometry.polyhedron + sage: P.is_eulerian() # needs sage.geometry.polyhedron sage.libs.flint True A poset that is 3- but not 4-eulerian:: sage: P = Poset(DiGraph('MWW@_?W?@_?W??@??O@_?W?@_?W?@??O??')); P Finite poset containing 14 elements - sage: P.is_eulerian(k=3) + sage: P.is_eulerian(k=3) # needs sage.libs.flint True - sage: P.is_eulerian(k=4) + sage: P.is_eulerian(k=4) # needs sage.libs.flint False Getting an interval that is not Eulerian:: sage: P = posets.DivisorLattice(12) - sage: P.is_eulerian(certificate=True) + sage: P.is_eulerian(certificate=True) # needs sage.libs.flint (False, (1, 4)) TESTS:: @@ -8143,7 +8143,7 @@ def is_eulerian(self, k=None, certificate=False): ... ValueError: the poset is not graded - sage: posets.BooleanLattice(3).is_eulerian(k=123, certificate=True) + sage: posets.BooleanLattice(3).is_eulerian(k=123, certificate=True) # needs sage.libs.flint (True, None) """ if k is not None: diff --git a/src/sage/combinat/q_analogues.py b/src/sage/combinat/q_analogues.py index 358b60ff322..bf346f03ad5 100644 --- a/src/sage/combinat/q_analogues.py +++ b/src/sage/combinat/q_analogues.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" `q`-Analogues """ diff --git a/src/sage/combinat/ranker.py b/src/sage/combinat/ranker.py index c370800bf22..1d51b8a04d2 100644 --- a/src/sage/combinat/ranker.py +++ b/src/sage/combinat/ranker.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Rankers """ diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index 173e061276b..161a7e05ec4 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -70,7 +70,7 @@ from sage.structure.unique_representation import UniqueRepresentation -class PrefixClosedSet(): +class PrefixClosedSet: def __init__(self, words): r""" A prefix-closed set. diff --git a/src/sage/combinat/regular_sequence.py b/src/sage/combinat/regular_sequence.py index c585e51e194..a2d5c09d94b 100644 --- a/src/sage/combinat/regular_sequence.py +++ b/src/sage/combinat/regular_sequence.py @@ -2337,7 +2337,7 @@ def from_recurrence(self, *args, **kwds): return self(mu, left, right) -class RecurrenceParser(): +class RecurrenceParser: r""" A parser for recurrence relations that allow the construction of a `k`-linear representation diff --git a/src/sage/combinat/rigged_configurations/rigged_partition.pyx b/src/sage/combinat/rigged_configurations/rigged_partition.pyx index 5b30b15608f..98a9047d6c9 100644 --- a/src/sage/combinat/rigged_configurations/rigged_partition.pyx +++ b/src/sage/combinat/rigged_configurations/rigged_partition.pyx @@ -7,7 +7,7 @@ configuration class. This is an internal class used by the rigged configurations and KR tableaux during the bijection, and is not to be used by the end-user. -We hold the partitions as an 1-dim array of positive integers where each +We hold the partitions as a 1-dim array of positive integers where each value corresponds to the length of the row. This is the shape of the partition which can be accessed by the regular index. diff --git a/src/sage/combinat/root_system/ambient_space.py b/src/sage/combinat/root_system/ambient_space.py index c9696b98fdb..a8aa765ee5d 100644 --- a/src/sage/combinat/root_system/ambient_space.py +++ b/src/sage/combinat/root_system/ambient_space.py @@ -55,9 +55,10 @@ class AmbientSpace(CombinatorialFreeModule): TESTS:: - sage: types = CartanType.samples(crystallographic = True)+[CartanType(["A",2],["C",5])] + sage: # needs sage.libs.gap + sage: types = CartanType.samples(crystallographic=True) + [CartanType(["A",2],["C",5])] sage: for e in [ct.root_system().ambient_space() for ct in types]: - ....: TestSuite(e).run() + ....: TestSuite(e).run() sage: e1 = RootSystem(['A',3]).ambient_lattice() sage: e2 = RootSystem(['B',3]).ambient_lattice() diff --git a/src/sage/combinat/root_system/associahedron.py b/src/sage/combinat/root_system/associahedron.py index 24140007081..448b1009036 100644 --- a/src/sage/combinat/root_system/associahedron.py +++ b/src/sage/combinat/root_system/associahedron.py @@ -129,7 +129,7 @@ def Associahedron(cartan_type, backend='ppl'): return parent(cartan_type) -class Associahedron_class_base(): +class Associahedron_class_base: r""" The base class of the Python class of an associahedron @@ -321,7 +321,7 @@ def Associahedra(base_ring, ambient_dim, backend='ppl'): raise ValueError("unknown backend") -class Associahedra_base(): +class Associahedra_base: """ Base class of parent of Associahedra of specified dimension diff --git a/src/sage/combinat/root_system/braid_move_calculator.py b/src/sage/combinat/root_system/braid_move_calculator.py index e932662bd5d..38931a00229 100644 --- a/src/sage/combinat/root_system/braid_move_calculator.py +++ b/src/sage/combinat/root_system/braid_move_calculator.py @@ -19,7 +19,7 @@ from sage.misc.cachefunc import cached_method -class BraidMoveCalculator(): +class BraidMoveCalculator: """ Helper class to compute braid moves. """ diff --git a/src/sage/combinat/root_system/cartan_matrix.py b/src/sage/combinat/root_system/cartan_matrix.py index c1ce04fba38..8019029d62a 100644 --- a/src/sage/combinat/root_system/cartan_matrix.py +++ b/src/sage/combinat/root_system/cartan_matrix.py @@ -452,7 +452,7 @@ def reflection_group(self, type="matrix"): EXAMPLES:: sage: C = CartanMatrix(['A',3]) # needs sage.graphs - sage: C.reflection_group() # needs sage.graphs + sage: C.reflection_group() # needs sage.graphs sage.libs.gap Weyl Group of type ['A', 3] (as a matrix group acting on the root space) """ RS = self.root_space() @@ -589,7 +589,7 @@ def subtype(self, index_set): """ ind = self.index_set() I = [ind.index(i) for i in index_set] - return CartanMatrix(self.matrix_from_rows_and_columns(I, I), index_set) + return CartanMatrix(self.matrix_from_rows_and_columns(I, I), index_set=index_set) def rank(self): r""" @@ -1135,13 +1135,39 @@ def find_cartan_type_from_matrix(CM): ['C', 3] relabelled by {1: 0, 2: 1, 3: 2} sage: CM = CartanMatrix([[2,-1,-2], [-1,2,-1], [-2,-1,2]]) sage: find_cartan_type_from_matrix(CM) + + TESTS: + + Check that :issue:`35987` is fixed:: + + sage: from sage.combinat.root_system.cartan_matrix import find_cartan_type_from_matrix + sage: cm = CartanMatrix(['A',7]).subtype([2,3,5]) + sage: find_cartan_type_from_matrix(cm) + A2xA1 relabelled by {1: 2, 2: 3, 3: 5} + + sage: cm = CartanMatrix(['B',10,1]).subtype([0,1,2,3,5,6,8,9,10]) + sage: ct = find_cartan_type_from_matrix(cm); ct + D4xB3xA2 relabelled by {1: 0, 2: 2, 3: 1, 4: 3, 5: 8, 6: 9, 7: 10, 8: 5, 9: 6} + sage: ct.dynkin_diagram() + O 3 + | + | + O---O---O + 0 2 1 + O---O=>=O + 8 9 10 + O---O + 5 6 + D4xB3xA2 relabelled by {1: 0, 2: 2, 3: 1, 4: 3, 5: 8, 6: 9, 7: 10, 8: 5, 9: 6} """ types = [] + relabel = [] for S in CM.dynkin_diagram().connected_components_subgraphs(): S = DiGraph(S) # We need a simple digraph here n = S.num_verts() # Build the list to test based upon rank if n == 1: + relabel.append({1: S.vertices()[0]}) types.append(CartanType(['A', 1])) continue @@ -1178,7 +1204,8 @@ def find_cartan_type_from_matrix(CM): T = DiGraph(ct.dynkin_diagram()) # We need a simple digraph here iso, match = T.is_isomorphic(S, certificate=True, edge_labels=True) if iso: - types.append(ct.relabel(match)) + types.append(ct) + relabel.append(match) found = True break @@ -1189,10 +1216,20 @@ def find_cartan_type_from_matrix(CM): T = DiGraph(ct.dynkin_diagram()) # We need a simple digraph here iso, match = T.is_isomorphic(S, certificate=True, edge_labels=True) if iso: - types.append(ct.relabel(match)) + types.append(ct) + relabel.append(match) found = True break if not found: return None - return CartanType(types) + if len(types) == 1: + # Irreducible, so just relabel + return CartanType(types[0]).relabel(relabel[0]) + ct = CartanType(types) + # ct._index_relabelling is a dict ``(ind, j): i``, where i is an index of + # ``ct``, ``ind`` is the position in the list of types, and j is the + # corresponding index of the type number ``ind``. + # In other words, the j-th node of ``types[ind]`` is the i-th node of ``ct``. + mapping = {i: relabel[d[0]][d[1]] for d, i in ct._index_relabelling.items()} + return ct.relabel(mapping) diff --git a/src/sage/combinat/root_system/cartan_type.py b/src/sage/combinat/root_system/cartan_type.py index 816fbadcd57..bd7ab5cdda4 100644 --- a/src/sage/combinat/root_system/cartan_type.py +++ b/src/sage/combinat/root_system/cartan_type.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Cartan types @@ -603,7 +602,7 @@ def __call__(self, *args): return CartanType(t[:-1]).dual() elif t[-1] == "~": return CartanType(t[:-1]).affine() - elif t in ["Aoo", u"A∞"]: + elif t in ["Aoo", "A∞"]: return CartanType(['A', Infinity]) elif t == "A+oo": from . import type_A_infinity @@ -974,7 +973,7 @@ class options(GlobalOptions): CartanType.__doc__ = __doc__ -class CartanType_abstract(): +class CartanType_abstract: r""" Abstract class for Cartan types @@ -1438,7 +1437,7 @@ def is_implemented(self): EXAMPLES:: - sage: CartanType(["A",4,1]).is_implemented() + sage: CartanType(["A",4,1]).is_implemented() # needs sage.graphs True sage: CartanType(['H',3]).is_implemented() True @@ -3075,7 +3074,7 @@ def __getitem__(self, i): # For backward compatibility -class CartanType_simple_finite(): +class CartanType_simple_finite: def __setstate__(self, dict): """ Implements the unpickling of Cartan types pickled by Sage <= 4.0. diff --git a/src/sage/combinat/root_system/coxeter_group.py b/src/sage/combinat/root_system/coxeter_group.py index 8fadad6035c..012daffdf87 100644 --- a/src/sage/combinat/root_system/coxeter_group.py +++ b/src/sage/combinat/root_system/coxeter_group.py @@ -86,7 +86,7 @@ def CoxeterGroup(data, implementation="reflection", base_ring=None, index_set=No [3 1 5] [2 5 1] - sage: W = CoxeterGroup(["H",3], implementation="reflection"); W # needs sage.rings.number_field + sage: W = CoxeterGroup(["H",3], implementation="reflection"); W # needs sage.libs.gap sage.rings.number_field Finite Coxeter group over Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? with Coxeter matrix: [1 3 2] @@ -116,7 +116,7 @@ def CoxeterGroup(data, implementation="reflection", base_ring=None, index_set=No TESTS:: - sage: W = groups.misc.CoxeterGroup(["H",3]) # needs sage.groups + sage: W = groups.misc.CoxeterGroup(["H",3]) # needs sage.graphs sage.groups """ if implementation not in ["permutation", "matrix", "coxeter3", "reflection", "chevie", None]: raise ValueError("invalid type implementation") diff --git a/src/sage/combinat/root_system/coxeter_matrix.py b/src/sage/combinat/root_system/coxeter_matrix.py index 719d23c3409..57e6030b9c4 100644 --- a/src/sage/combinat/root_system/coxeter_matrix.py +++ b/src/sage/combinat/root_system/coxeter_matrix.py @@ -850,6 +850,7 @@ def bilinear_form(self, R=None): EXAMPLES:: + sage: # needs sage.libs.gap sage: CoxeterType(['A', 2, 1]).bilinear_form() [ 1 -1/2 -1/2] [-1/2 1 -1/2] diff --git a/src/sage/combinat/root_system/coxeter_type.py b/src/sage/combinat/root_system/coxeter_type.py index ef1d4beb922..88a53e4bd98 100644 --- a/src/sage/combinat/root_system/coxeter_type.py +++ b/src/sage/combinat/root_system/coxeter_type.py @@ -357,7 +357,7 @@ def bilinear_form(self, R=None): EXAMPLES:: - sage: # needs sage.graphs sage.rings.number_field + sage: # needs sage.graphs sage.libs.gap sage: CoxeterType(['A', 2, 1]).bilinear_form() [ 1 -1/2 -1/2] [-1/2 1 -1/2] diff --git a/src/sage/combinat/root_system/fundamental_group.py b/src/sage/combinat/root_system/fundamental_group.py index 65426b786e3..8905471a5ab 100644 --- a/src/sage/combinat/root_system/fundamental_group.py +++ b/src/sage/combinat/root_system/fundamental_group.py @@ -1,4 +1,4 @@ -# sage.doctest: needs sage.graphs +# sage.doctest: needs sage.graphs sage.groups r""" Fundamental Group of an Extended Affine Weyl Group diff --git a/src/sage/combinat/root_system/integrable_representations.py b/src/sage/combinat/root_system/integrable_representations.py index 0278617a2e5..a1cb764e19a 100644 --- a/src/sage/combinat/root_system/integrable_representations.py +++ b/src/sage/combinat/root_system/integrable_representations.py @@ -426,7 +426,7 @@ def _inner_pq(self, pelt, qelt): def _inner_pp(self, pelt1, pelt2): """ - Symmetric form between an two elements of the weight lattice + Symmetric form between two elements of the weight lattice associated to ``self``. EXAMPLES:: @@ -860,21 +860,22 @@ def mult(self, mu): EXAMPLES:: + sage: # needs sage.libs.gap sage: L = RootSystem("B3~").weight_lattice(extended=True) sage: Lambda = L.fundamental_weights() sage: delta = L.null_root() sage: W = L.weyl_group(prefix="s") sage: [s0,s1,s2,s3] = W.simple_reflections() sage: V = IntegrableRepresentation(Lambda[0]) - sage: V.mult(Lambda[2]-2*delta) + sage: V.mult(Lambda[2] - 2*delta) 3 - sage: V.mult(Lambda[2]-Lambda[1]) + sage: V.mult(Lambda[2] - Lambda[1]) 0 - sage: weights = [w.action(Lambda[1]-4*delta) for w in [s1,s2,s0*s1*s2*s3]] + sage: weights = [w.action(Lambda[1] - 4*delta) for w in [s1,s2,s0*s1*s2*s3]] sage: weights [-Lambda[1] + Lambda[2] - 4*delta, - Lambda[1] - 4*delta, - -Lambda[1] + Lambda[2] - 4*delta] + Lambda[1] - 4*delta, + -Lambda[1] + Lambda[2] - 4*delta] sage: [V.mult(mu) for mu in weights] [35, 35, 35] @@ -1093,7 +1094,7 @@ def branch(self, i=None, weyl_character_ring=None, sequence=None, depth=5): sage: Lambda = RootSystem(['A',2,1]).weight_lattice(extended=true).fundamental_weights() sage: V = IntegrableRepresentation(2*Lambda[0]) - sage: b = V.branch(); b + sage: b = V.branch(); b # needs sage.libs.gap [A2(0,0), A2(1,1), A2(0,0) + 2*A2(1,1) + A2(2,2), @@ -1104,7 +1105,7 @@ def branch(self, i=None, weyl_character_ring=None, sequence=None, depth=5): If the parameter ``weyl_character_ring`` is omitted, the ring may be recovered as the parent of one of the branched coefficients:: - sage: A2 = b[0].parent(); A2 + sage: A2 = b[0].parent(); A2 # needs sage.libs.gap The Weyl Character Ring of Type A2 with Integer Ring coefficients If `i` is not zero then you should specify the :class:`WeylCharacterRing` that you @@ -1125,8 +1126,8 @@ def branch(self, i=None, weyl_character_ring=None, sequence=None, depth=5): Thus we have a branching to `\mathfrak{sl}(2) \times \mathfrak{sl}(2) \times \mathfrak{sl}(2)`:: - sage: A1xA1xA1 = WeylCharacterRing("A1xA1xA1",style="coroots") - sage: V.branch(i=2,weyl_character_ring=A1xA1xA1) + sage: A1xA1xA1 = WeylCharacterRing("A1xA1xA1",style="coroots") # needs sage.libs.gap + sage: V.branch(i=2,weyl_character_ring=A1xA1xA1) # needs sage.libs.gap [A1xA1xA1(1,0,0), A1xA1xA1(0,1,2), A1xA1xA1(1,0,0) + A1xA1xA1(1,2,0) + A1xA1xA1(1,0,2), @@ -1159,7 +1160,7 @@ def branch(self, i=None, weyl_character_ring=None, sequence=None, depth=5): The nodes `0, 2, 3, 4` of ``F4~`` correspond to ``1, 4, 3, 2`` of ``A1xC3`` and so we encode this in a dictionary:: - sage: V.branch(i=1,weyl_character_ring=A1xC3,sequence={0:1,2:4,3:3,4:2}) # long time + sage: V.branch(i=1, weyl_character_ring=A1xC3, sequence={0:1,2:4,3:3,4:2}) # long time [A1xC3(1,0,0,0), A1xC3(0,0,0,1), A1xC3(1,0,0,0) + A1xC3(1,2,0,0), diff --git a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py index a29b26fdde3..34e7e0817f1 100644 --- a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +++ b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py @@ -72,7 +72,7 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): Here is the nonsymmetric Macdonald polynomial with leading term `[2,0,1]`:: - sage: E[L0([2,0,1])] + sage: E[L0([2,0,1])] # needs sage.libs.gap ((-q*q1-q*q2)/(-q*q1-q2))*B[(1, 1, 1)] + ((-q1-q2)/(-q*q1-q2))*B[(2, 1, 0)] + B[(2, 0, 1)] @@ -92,7 +92,7 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): sage: q,t = K.gens() sage: E = NonSymmetricMacdonaldPolynomials(["A",2,1], q=q, q1=t, q2=-1) sage: vars = K['x0,x1,x2'].gens() - sage: E[L0([2,0,1])].expand(vars) + sage: E[L0([2,0,1])].expand(vars) # needs sage.libs.gap (t - 1)/(q*t - 1)*x0^2*x1 + x0^2*x2 + (q*t - q)/(q*t - 1)*x0*x1*x2 sage: from sage.combinat.sf.ns_macdonald import E # needs sage.combinat @@ -104,7 +104,7 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): sage: E = NonSymmetricMacdonaldPolynomials(["G",2,1]) sage: L0 = E.keys() sage: omega = L0.fundamental_weights() - sage: E[ omega[2]-omega[1] ] + sage: E[omega[2] - omega[1]] ((-q*q1^3*q2-q*q1^2*q2^2)/(q*q1^4-q2^4))*B[(0, 0, 0)] + B[(1, -1, 0)] + ((-q1*q2^3-q2^4)/(q*q1^4-q2^4))*B[(1, 0, -1)] @@ -1684,7 +1684,7 @@ def __getitem__(self, mu): ... ValueError: 1/2*e[0] + 1/2*e[1] does not lift to a level 0 element of the affine weight lattice - sage: E[2*omega[2]] + sage: E[2*omega[2]] # needs sage.libs.gap ((q^2*q1^2+q^2*q1*q2)/(q^2*q1^2-q2^2))*B[(0, 0)] + ((-q^2*q1^2-q^2*q1*q2)/(-q^2*q1^2+q2^2))*B[(1, 0)] + B[(1, 1)] + ((-q^2*q1^2-q^2*q1*q2)/(-q^2*q1^2+q2^2))*B[(0, 1)] @@ -1751,7 +1751,7 @@ def eigenvalue_experimental(self, mu, l): sage: KL = RootSystem(["A",1,1]).ambient_space().algebra(K) sage: E = NonSymmetricMacdonaldPolynomials(KL,q, q1, q2) sage: L0 = E.keys() - sage: E.eigenvalues(L0([0,0])) # Checked by hand by Mark and Arun + sage: E.eigenvalues(L0([0,0])) # Checked by hand by Mark and Arun # needs sage.libs.gap [1/(q*t), t] sage: alpha = E.Y().keys().simple_roots() sage: E.eigenvalue_experimental(L0([0,0]), alpha[0]) # todo: not implemented @@ -1761,6 +1761,7 @@ def eigenvalue_experimental(self, mu, l): Some examples of eigenvalues (not mathematically checked!!!):: + sage: # needs sage.libs.gap sage: E.eigenvalues(L0([1,0])) [t, 1/(q*t)] sage: E.eigenvalues(L0([0,1])) @@ -1880,13 +1881,13 @@ def symmetric_macdonald_polynomial(self, mu): sage: q,v,t = K.gens() sage: E = NonSymmetricMacdonaldPolynomials(['A',2,1], q, v, -1/v) sage: om = E.L0().fundamental_weights() - sage: E.symmetric_macdonald_polynomial(om[2]) + sage: E.symmetric_macdonald_polynomial(om[2]) # needs sage.libs.gap B[(1, 1, 0)] + B[(1, 0, 1)] + B[(0, 1, 1)] - sage: E.symmetric_macdonald_polynomial(2*om[1]) + sage: E.symmetric_macdonald_polynomial(2*om[1]) # needs sage.libs.gap ((q*v^2+v^2-q-1)/(q*v^2-1))*B[(1, 1, 0)] + ((q*v^2+v^2-q-1)/(q*v^2-1))*B[(1, 0, 1)] + B[(2, 0, 0)] + ((q*v^2+v^2-q-1)/(q*v^2-1))*B[(0, 1, 1)] + B[(0, 2, 0)] + B[(0, 0, 2)] - sage: f = E.symmetric_macdonald_polynomial(E.L0()((2,1,0))); f + sage: f = E.symmetric_macdonald_polynomial(E.L0()((2,1,0))); f # needs sage.libs.gap ((2*q*v^4+v^4-q*v^2+v^2-q-2)/(q*v^4-1))*B[(1, 1, 1)] + B[(1, 2, 0)] + B[(1, 0, 2)] + B[(2, 1, 0)] + B[(2, 0, 1)] + B[(0, 1, 2)] + B[(0, 2, 1)] @@ -1899,11 +1900,11 @@ def symmetric_macdonald_polynomial(self, mu): x0^2*x1 + x0*x1^2 + x0^2*x2 + (2*q*t^2 - q*t - q + t^2 + t - 2)/(q*t^2 - 1)*x0*x1*x2 + x1^2*x2 + x0*x2^2 + x1*x2^2 - sage: fe = f.expand(g.parent().gens()); fe + sage: fe = f.expand(g.parent().gens()); fe # needs sage.libs.gap x0^2*x1 + x0*x1^2 + x0^2*x2 + (2*q*v^4 - q*v^2 - q + v^4 + v^2 - 2)/(q*v^4 - 1)*x0*x1*x2 + x1^2*x2 + x0*x2^2 + x1*x2^2 - sage: g.map_coefficients(lambda x: x.subs(t=v*v)) == fe + sage: g.map_coefficients(lambda x: x.subs(t=v*v)) == fe # needs sage.libs.gap True sage: E = NonSymmetricMacdonaldPolynomials(['C',3,1], q, v, -1/v) diff --git a/src/sage/combinat/root_system/plot.py b/src/sage/combinat/root_system/plot.py index a1eec40e8df..c81d86b8484 100644 --- a/src/sage/combinat/root_system/plot.py +++ b/src/sage/combinat/root_system/plot.py @@ -830,7 +830,7 @@ "RootLatticeRealizations") -class PlotOptions(): +class PlotOptions: r""" A class for plotting options for root lattice realizations. diff --git a/src/sage/combinat/root_system/reflection_group_c.pyx b/src/sage/combinat/root_system/reflection_group_c.pyx index e2f5eff21b1..a44a5874b7f 100644 --- a/src/sage/combinat/root_system/reflection_group_c.pyx +++ b/src/sage/combinat/root_system/reflection_group_c.pyx @@ -1,4 +1,5 @@ # cython: wraparound=False, boundscheck=False +# sage.doctest: needs sage.graphs r""" This contains a few time-critical auxiliary cython functions for finite complex or real reflection groups. diff --git a/src/sage/combinat/root_system/reflection_group_complex.py b/src/sage/combinat/root_system/reflection_group_complex.py index 03fde46bf8d..6bf0e9936ea 100644 --- a/src/sage/combinat/root_system/reflection_group_complex.py +++ b/src/sage/combinat/root_system/reflection_group_complex.py @@ -1,4 +1,4 @@ -# sage.doctest: needs sage.libs.gap +# sage.doctest: optional - gap3, needs sage.libs.gap r""" Finite complex reflection groups ---------------------------------- @@ -13,16 +13,15 @@ The point of entry to work with reflection groups is :func:`~sage.combinat.root_system.reflection_group_real.ReflectionGroup` which can be used with finite Cartan-Killing types:: - sage: ReflectionGroup(['A',2]) # optional - gap3 + sage: ReflectionGroup(['A',2]) Irreducible real reflection group of rank 2 and type A2 - sage: ReflectionGroup(['F',4]) # optional - gap3 + sage: ReflectionGroup(['F',4]) Irreducible real reflection group of rank 4 and type F4 - sage: ReflectionGroup(['H',3]) # optional - gap3 + sage: ReflectionGroup(['H',3]) Irreducible real reflection group of rank 3 and type H3 or with Shephard-Todd types:: - sage: # optional - gap3 sage: ReflectionGroup((1,1,3)) Irreducible real reflection group of rank 2 and type A2 sage: ReflectionGroup((2,1,3)) @@ -38,14 +37,14 @@ Also reducible types are allowed using concatenation:: - sage: ReflectionGroup(['A',3],(4,2,3)) # optional - gap3 + sage: ReflectionGroup(['A',3],(4,2,3)) Reducible complex reflection group of rank 6 and type A3 x G(4,2,3) Some special cases also occur, among them are:: - sage: W = ReflectionGroup((2,2,2)); W # optional - gap3 + sage: W = ReflectionGroup((2,2,2)); W Reducible real reflection group of rank 2 and type A1 x A1 - sage: W = ReflectionGroup((2,2,3)); W # optional - gap3 + sage: W = ReflectionGroup((2,2,3)); W Irreducible real reflection group of rank 3 and type A3 .. WARNING:: Uses the GAP3 package *Chevie* which is available as an @@ -57,13 +56,13 @@ We start with the example type `B_2`:: - sage: W = ReflectionGroup(['B',2]); W # optional - gap3 + sage: W = ReflectionGroup(['B',2]); W Irreducible real reflection group of rank 2 and type B2 Most importantly, observe that the group elements are usually represented by permutations of the roots:: - sage: for w in W: print(w) # optional - gap3 + sage: for w in W: print(w) () (1,3)(2,6)(5,7) (1,5)(2,4)(6,8) @@ -76,7 +75,7 @@ This has the drawback that one can hardly see anything. Usually, one would look at elements with either of the following methods:: - sage: for w in W: w.reduced_word() # optional - gap3 + sage: for w in W: w.reduced_word() [] [2] [1] @@ -86,7 +85,7 @@ [1, 2, 1] [1, 2, 1, 2] - sage: for w in W: w.reduced_word_in_reflections() # optional - gap3 + sage: for w in W: w.reduced_word_in_reflections() [] [2] [1] @@ -96,7 +95,7 @@ [4] [1, 3] - sage: for w in W: w.reduced_word(); w.to_matrix(); print("") # optional - gap3 + sage: for w in W: w.reduced_word(); w.to_matrix(); print("") [] [1 0] [0 1] @@ -133,7 +132,7 @@ The standard references for actions of complex reflection groups have the matrices acting on the right, so:: - sage: W.simple_reflection(1).to_matrix() # optional - gap3 + sage: W.simple_reflection(1).to_matrix() [-1 0] [ 2 1] @@ -233,8 +232,8 @@ def __init__(self, W_types, index_set=None, hyperplane_index_set=None, reflectio TESTS:: sage: from sage.categories.complex_reflection_groups import ComplexReflectionGroups - sage: W = ComplexReflectionGroups().example() # optional - gap3 - sage: TestSuite(W).run() # optional - gap3 + sage: W = ComplexReflectionGroups().example() + sage: TestSuite(W).run() """ W_components = [] reflection_type = [] @@ -331,9 +330,9 @@ def _irrcomp_repr_(self,W_type): TESTS:: - sage: W = ReflectionGroup(25,[4,1,4],[1,1,4],[5,5,2]); W # optional - gap3 + sage: W = ReflectionGroup(25,[4,1,4],[1,1,4],[5,5,2]); W Reducible complex reflection group of rank 12 and type ST25 x G(4,1,4) x A3 x I2(5) - sage: for W_type in W._type: print(W._irrcomp_repr_(W_type)) # optional - gap3 + sage: for W_type in W._type: print(W._irrcomp_repr_(W_type)) ST25 G(4,1,4) A3 @@ -359,7 +358,7 @@ def _repr_(self): EXAMPLES:: - sage: W = ReflectionGroup(25, [4,1,4],[1,1,4],[5,5,2]); W # optional - gap3 + sage: W = ReflectionGroup(25, [4,1,4],[1,1,4],[5,5,2]); W Reducible complex reflection group of rank 12 and type ST25 x G(4,1,4) x A3 x I2(5) """ type_str = '' @@ -379,8 +378,8 @@ def iteration_tracking_words(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: for w in W.iteration_tracking_words(): w # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: for w in W.iteration_tracking_words(): w () (1,4)(2,3)(5,6) (1,3)(2,5)(4,6) @@ -400,7 +399,6 @@ def index_set(self): EXAMPLES:: - sage: # optional - gap3 sage: W = ReflectionGroup((1,1,4)) sage: W.index_set() (1, 2, 3) @@ -419,10 +417,10 @@ def simple_reflection(self, i): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: W.simple_reflection(1) # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: W.simple_reflection(1) (1,4)(2,3)(5,6) - sage: W.simple_reflections() # optional - gap3 + sage: W.simple_reflections() Finite family {1: (1,4)(2,3)(5,6), 2: (1,3)(2,5)(4,6)} """ return self.gens()[self._index_set_inverse[i]] @@ -439,9 +437,9 @@ def series(self): EXAMPLES:: - sage: ReflectionGroup((1,1,3)).series() # optional - gap3 + sage: ReflectionGroup((1,1,3)).series() ['A'] - sage: ReflectionGroup((3,1,3)).series() # optional - gap3 + sage: ReflectionGroup((3,1,3)).series() ['ST'] """ return [self._type[i]['series'] for i in range(len(self._type))] @@ -453,7 +451,6 @@ def hyperplane_index_set(self): EXAMPLES:: - sage: # optional - gap3 sage: W = ReflectionGroup((1,1,4)) sage: W.hyperplane_index_set() (1, 2, 3, 4, 5, 6) @@ -478,20 +475,20 @@ def distinguished_reflections(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: W.distinguished_reflections() # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: W.distinguished_reflections() Finite family {1: (1,4)(2,3)(5,6), 2: (1,3)(2,5)(4,6), 3: (1,5)(2,4)(3,6)} - sage: W = ReflectionGroup((1,1,3),hyperplane_index_set=['a','b','c']) # optional - gap3 - sage: W.distinguished_reflections() # optional - gap3 + sage: W = ReflectionGroup((1,1,3),hyperplane_index_set=['a','b','c']) + sage: W.distinguished_reflections() Finite family {'a': (1,4)(2,3)(5,6), 'b': (1,3)(2,5)(4,6), 'c': (1,5)(2,4)(3,6)} - sage: W = ReflectionGroup((3,1,1)) # optional - gap3 - sage: W.distinguished_reflections() # optional - gap3 + sage: W = ReflectionGroup((3,1,1)) + sage: W.distinguished_reflections() Finite family {1: (1,2,3)} - sage: W = ReflectionGroup((1,1,3),(3,1,2)) # optional - gap3 - sage: W.distinguished_reflections() # optional - gap3 + sage: W = ReflectionGroup((1,1,3),(3,1,2)) + sage: W.distinguished_reflections() Finite family {1: (1,6)(2,5)(7,8), 2: (1,5)(2,7)(6,8), 3: (3,9,15)(4,10,16)(12,17,23)(14,18,24)(20,25,29)(21,22,26)(27,28,30), 4: (3,11)(4,12)(9,13)(10,14)(15,19)(16,20)(17,21)(18,22)(23,27)(24,28)(25,26)(29,30), @@ -522,7 +519,6 @@ def distinguished_reflection(self, i): EXAMPLES:: - sage: # optional - gap3 sage: W = ReflectionGroup((1,1,3)) sage: W.distinguished_reflection(1) (1,4)(2,3)(5,6) @@ -531,12 +527,12 @@ def distinguished_reflection(self, i): sage: W.distinguished_reflection(3) (1,5)(2,4)(3,6) - sage: W = ReflectionGroup((3,1,1),hyperplane_index_set=['a']) # optional - gap3 - sage: W.distinguished_reflection('a') # optional - gap3 + sage: W = ReflectionGroup((3,1,1),hyperplane_index_set=['a']) + sage: W.distinguished_reflection('a') (1,2,3) - sage: W = ReflectionGroup((1,1,3),(3,1,2)) # optional - gap3 - sage: for i in range(W.number_of_reflection_hyperplanes()): # optional - gap3 + sage: W = ReflectionGroup((1,1,3),(3,1,2)) + sage: for i in range(W.number_of_reflection_hyperplanes()): ....: W.distinguished_reflection(i+1) (1,6)(2,5)(7,8) (1,5)(2,7)(6,8) @@ -563,8 +559,8 @@ def reflection_hyperplanes(self, as_linear_functionals=False, with_order=False): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: for H in W.reflection_hyperplanes(): H # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: for H in W.reflection_hyperplanes(): H Vector space of degree 2 and dimension 1 over Rational Field Basis matrix: [1 2] @@ -575,14 +571,14 @@ def reflection_hyperplanes(self, as_linear_functionals=False, with_order=False): Basis matrix: [ 1 -1] - sage: for H in W.reflection_hyperplanes(as_linear_functionals=True): H # optional - gap3 + sage: for H in W.reflection_hyperplanes(as_linear_functionals=True): H (1, -1/2) (1, -2) (1, 1) - sage: W = ReflectionGroup((2,1,2)) # optional - gap3 - sage: for H in W.reflection_hyperplanes(): H # optional - gap3 + sage: W = ReflectionGroup((2,1,2)) + sage: for H in W.reflection_hyperplanes(): H Vector space of degree 2 and dimension 1 over Rational Field Basis matrix: [1 1] @@ -596,13 +592,13 @@ def reflection_hyperplanes(self, as_linear_functionals=False, with_order=False): Basis matrix: [0 1] - sage: for H in W.reflection_hyperplanes(as_linear_functionals=True): H # optional - gap3 + sage: for H in W.reflection_hyperplanes(as_linear_functionals=True): H (1, -1) (1, -2) (0, 1) (1, 0) - sage: for H in W.reflection_hyperplanes(as_linear_functionals=True, with_order=True): H # optional - gap3 + sage: for H in W.reflection_hyperplanes(as_linear_functionals=True, with_order=True): H ((1, -1), 2) ((1, -2), 2) ((0, 1), 2) @@ -636,15 +632,15 @@ def reflection_hyperplane(self, i, as_linear_functional=False, with_order=False) EXAMPLES:: - sage: W = ReflectionGroup((2,1,2)) # optional - gap3 - sage: W.reflection_hyperplane(3) # optional - gap3 + sage: W = ReflectionGroup((2,1,2)) + sage: W.reflection_hyperplane(3) Vector space of degree 2 and dimension 1 over Rational Field Basis matrix: [1 0] One can ask for the result as a linear form:: - sage: W.reflection_hyperplane(3, True) # optional - gap3 + sage: W.reflection_hyperplane(3, True) (0, 1) """ return self.reflection_hyperplanes(as_linear_functionals=as_linear_functional, with_order=with_order)[i] @@ -656,7 +652,6 @@ def reflection_index_set(self): EXAMPLES:: - sage: # optional - gap3 sage: W = ReflectionGroup((1,1,4)) sage: W.reflection_index_set() (1, 2, 3, 4, 5, 6) @@ -677,20 +672,20 @@ def reflections(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: W.reflections() # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: W.reflections() Finite family {1: (1,4)(2,3)(5,6), 2: (1,3)(2,5)(4,6), 3: (1,5)(2,4)(3,6)} - sage: W = ReflectionGroup((1,1,3),reflection_index_set=['a','b','c']) # optional - gap3 - sage: W.reflections() # optional - gap3 + sage: W = ReflectionGroup((1,1,3),reflection_index_set=['a','b','c']) + sage: W.reflections() Finite family {'a': (1,4)(2,3)(5,6), 'b': (1,3)(2,5)(4,6), 'c': (1,5)(2,4)(3,6)} - sage: W = ReflectionGroup((3,1,1)) # optional - gap3 - sage: W.reflections() # optional - gap3 + sage: W = ReflectionGroup((3,1,1)) + sage: W.reflections() Finite family {1: (1,2,3), 2: (1,3,2)} - sage: W = ReflectionGroup((1,1,3),(3,1,2)) # optional - gap3 - sage: W.reflections() # optional - gap3 + sage: W = ReflectionGroup((1,1,3),(3,1,2)) + sage: W.reflections() Finite family {1: (1,6)(2,5)(7,8), 2: (1,5)(2,7)(6,8), 3: (3,9,15)(4,10,16)(12,17,23)(14,18,24)(20,25,29)(21,22,26)(27,28,30), 4: (3,11)(4,12)(9,13)(10,14)(15,19)(16,20)(17,21)(18,22)(23,27)(24,28)(25,26)(29,30), @@ -714,7 +709,6 @@ def reflection(self,i): EXAMPLES:: - sage: # optional - gap3 sage: W = ReflectionGroup((1,1,3)) sage: W.reflection(1) (1,4)(2,3)(5,6) @@ -723,10 +717,10 @@ def reflection(self,i): sage: W.reflection(3) (1,5)(2,4)(3,6) - sage: W = ReflectionGroup((3,1,1),reflection_index_set=['a','b']) # optional - gap3 - sage: W.reflection('a') # optional - gap3 + sage: W = ReflectionGroup((3,1,1),reflection_index_set=['a','b']) + sage: W.reflection('a') (1,2,3) - sage: W.reflection('b') # optional - gap3 + sage: W.reflection('b') (1,3,2) """ return self.reflections()[i] @@ -737,8 +731,8 @@ def reflection_character(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: W.reflection_character() # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: W.reflection_character() [2, 0, -1] """ return self._gap_group.ReflectionCharacter().sage() @@ -760,13 +754,13 @@ def discriminant(self): EXAMPLES:: - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: W.discriminant() # optional - gap3 + sage: W = ReflectionGroup(['A',2]) + sage: W.discriminant() x0^6 - 3*x0^5*x1 - 3/4*x0^4*x1^2 + 13/2*x0^3*x1^3 - 3/4*x0^2*x1^4 - 3*x0*x1^5 + x1^6 - sage: W = ReflectionGroup(['B',2]) # optional - gap3 - sage: W.discriminant() # optional - gap3 + sage: W = ReflectionGroup(['B',2]) + sage: W.discriminant() x0^6*x1^2 - 6*x0^5*x1^3 + 13*x0^4*x1^4 - 12*x0^3*x1^5 + 4*x0^2*x1^6 """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -787,16 +781,16 @@ def discriminant_in_invariant_ring(self, invariants=None): EXAMPLES:: - sage: W = ReflectionGroup(['A',3]) # optional - gap3 - sage: W.discriminant_in_invariant_ring() # optional - gap3 + sage: W = ReflectionGroup(['A',3]) + sage: W.discriminant_in_invariant_ring() 6*t0^3*t1^2 - 18*t0^4*t2 + 9*t1^4 - 36*t0*t1^2*t2 + 24*t0^2*t2^2 - 8*t2^3 - sage: W = ReflectionGroup(['B',3]) # optional - gap3 - sage: W.discriminant_in_invariant_ring() # optional - gap3 + sage: W = ReflectionGroup(['B',3]) + sage: W.discriminant_in_invariant_ring() -t0^2*t1^2*t2 + 16*t0^3*t2^2 + 2*t1^3*t2 - 36*t0*t1*t2^2 + 108*t2^3 - sage: W = ReflectionGroup(['H',3]) # optional - gap3 - sage: W.discriminant_in_invariant_ring() # long time # optional - gap3 + sage: W = ReflectionGroup(['H',3]) + sage: W.discriminant_in_invariant_ring() # long time (-829*E(5) - 1658*E(5)^2 - 1658*E(5)^3 - 829*E(5)^4)*t0^15 + (213700*E(5) + 427400*E(5)^2 + 427400*E(5)^3 + 213700*E(5)^4)*t0^12*t1 + (-22233750*E(5) - 44467500*E(5)^2 - 44467500*E(5)^3 - 22233750*E(5)^4)*t0^9*t1^2 @@ -872,29 +866,29 @@ def is_crystallographic(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)); W # optional - gap3 + sage: W = ReflectionGroup((1,1,3)); W Irreducible real reflection group of rank 2 and type A2 - sage: W.is_crystallographic() # optional - gap3 + sage: W.is_crystallographic() True - sage: W = ReflectionGroup((2,1,3)); W # optional - gap3 + sage: W = ReflectionGroup((2,1,3)); W Irreducible real reflection group of rank 3 and type B3 - sage: W.is_crystallographic() # optional - gap3 + sage: W.is_crystallographic() True - sage: W = ReflectionGroup(23); W # optional - gap3 + sage: W = ReflectionGroup(23); W Irreducible real reflection group of rank 3 and type H3 - sage: W.is_crystallographic() # optional - gap3 + sage: W.is_crystallographic() False - sage: W = ReflectionGroup((3,1,3)); W # optional - gap3 + sage: W = ReflectionGroup((3,1,3)); W Irreducible complex reflection group of rank 3 and type G(3,1,3) - sage: W.is_crystallographic() # optional - gap3 + sage: W.is_crystallographic() False - sage: W = ReflectionGroup((4,2,2)); W # optional - gap3 + sage: W = ReflectionGroup((4,2,2)); W Irreducible complex reflection group of rank 2 and type G(4,2,2) - sage: W.is_crystallographic() # optional - gap3 + sage: W.is_crystallographic() False """ return self.is_real() and all(t.to_matrix().base_ring() is QQ for t in self.simple_reflections()) @@ -905,12 +899,12 @@ def number_of_irreducible_components(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: W.number_of_irreducible_components() # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: W.number_of_irreducible_components() 1 - sage: W = ReflectionGroup((1,1,3),(2,1,3)) # optional - gap3 - sage: W.number_of_irreducible_components() # optional - gap3 + sage: W = ReflectionGroup((1,1,3),(2,1,3)) + sage: W.number_of_irreducible_components() 2 """ return len(self._type) @@ -922,12 +916,12 @@ def irreducible_components(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: W.irreducible_components() # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: W.irreducible_components() [Irreducible real reflection group of rank 2 and type A2] - sage: W = ReflectionGroup((1,1,3),(2,1,3)) # optional - gap3 - sage: W.irreducible_components() # optional - gap3 + sage: W = ReflectionGroup((1,1,3),(2,1,3)) + sage: W.irreducible_components() [Irreducible real reflection group of rank 2 and type A2, Irreducible real reflection group of rank 3 and type B3] """ @@ -949,21 +943,21 @@ def conjugacy_classes_representatives(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: [w.reduced_word() for w in W.conjugacy_classes_representatives()] # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: [w.reduced_word() for w in W.conjugacy_classes_representatives()] [[], [1], [1, 2]] - sage: W = ReflectionGroup((1,1,4)) # optional - gap3 - sage: [w.reduced_word() for w in W.conjugacy_classes_representatives()] # optional - gap3 + sage: W = ReflectionGroup((1,1,4)) + sage: [w.reduced_word() for w in W.conjugacy_classes_representatives()] [[], [1], [1, 3], [1, 2], [1, 3, 2]] - sage: W = ReflectionGroup((3,1,2)) # optional - gap3 - sage: [w.reduced_word() for w in W.conjugacy_classes_representatives()] # optional - gap3 + sage: W = ReflectionGroup((3,1,2)) + sage: [w.reduced_word() for w in W.conjugacy_classes_representatives()] [[], [1], [1, 1], [2, 1, 2, 1], [2, 1, 2, 1, 1], [2, 1, 1, 2, 1, 1], [2], [1, 2], [1, 1, 2]] - sage: W = ReflectionGroup(23) # optional - gap3 - sage: [w.reduced_word() for w in W.conjugacy_classes_representatives()] # optional - gap3 + sage: W = ReflectionGroup(23) + sage: [w.reduced_word() for w in W.conjugacy_classes_representatives()] [[], [1], [1, 2], @@ -985,22 +979,22 @@ def conjugacy_classes(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: for C in W.conjugacy_classes(): sorted(C) # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: for C in W.conjugacy_classes(): sorted(C) [()] [(1,3)(2,5)(4,6), (1,4)(2,3)(5,6), (1,5)(2,4)(3,6)] [(1,2,6)(3,4,5), (1,6,2)(3,5,4)] - sage: W = ReflectionGroup((1,1,4)) # optional - gap3 - sage: sum(len(C) for C in W.conjugacy_classes()) == W.cardinality() # optional - gap3 + sage: W = ReflectionGroup((1,1,4)) + sage: sum(len(C) for C in W.conjugacy_classes()) == W.cardinality() True - sage: W = ReflectionGroup((3,1,2)) # optional - gap3 - sage: sum(len(C) for C in W.conjugacy_classes()) == W.cardinality() # optional - gap3 + sage: W = ReflectionGroup((3,1,2)) + sage: sum(len(C) for C in W.conjugacy_classes()) == W.cardinality() True - sage: W = ReflectionGroup(23) # optional - gap3 - sage: sum(len(C) for C in W.conjugacy_classes()) == W.cardinality() # optional - gap3 + sage: W = ReflectionGroup(23) + sage: sum(len(C) for C in W.conjugacy_classes()) == W.cardinality() True """ return Family(self.conjugacy_classes_representatives(), @@ -1014,7 +1008,6 @@ def rank(self): EXAMPLES:: - sage: # optional - gap3 sage: W = ReflectionGroup((1,1,3)) sage: W.rank() 2 @@ -1038,35 +1031,35 @@ def degrees(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,4)) # optional - gap3 - sage: W.degrees() # optional - gap3 + sage: W = ReflectionGroup((1,1,4)) + sage: W.degrees() (2, 3, 4) - sage: W = ReflectionGroup((2,1,4)) # optional - gap3 - sage: W.degrees() # optional - gap3 + sage: W = ReflectionGroup((2,1,4)) + sage: W.degrees() (2, 4, 6, 8) - sage: W = ReflectionGroup((4,1,4)) # optional - gap3 - sage: W.degrees() # optional - gap3 + sage: W = ReflectionGroup((4,1,4)) + sage: W.degrees() (4, 8, 12, 16) - sage: W = ReflectionGroup((4,2,4)) # optional - gap3 - sage: W.degrees() # optional - gap3 + sage: W = ReflectionGroup((4,2,4)) + sage: W.degrees() (4, 8, 8, 12) - sage: W = ReflectionGroup((4,4,4)) # optional - gap3 - sage: W.degrees() # optional - gap3 + sage: W = ReflectionGroup((4,4,4)) + sage: W.degrees() (4, 4, 8, 12) Examples of reducible types:: - sage: W = ReflectionGroup((1,1,4), (3,1,2)); W # optional - gap3 + sage: W = ReflectionGroup((1,1,4), (3,1,2)); W Reducible complex reflection group of rank 5 and type A3 x G(3,1,2) - sage: W.degrees() # optional - gap3 + sage: W.degrees() (2, 3, 4, 3, 6) - sage: W = ReflectionGroup((1,1,4), (6,1,12), 23) # optional - gap3 # fails in GAP3 - sage: W.degrees() # optional - gap3 + sage: W = ReflectionGroup((1,1,4), (6,1,12), 23) + sage: W.degrees() (2, 3, 4, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 2, 6, 10) """ if self.is_irreducible(): @@ -1085,32 +1078,32 @@ def codegrees(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,4)) # optional - gap3 - sage: W.codegrees() # optional - gap3 + sage: W = ReflectionGroup((1,1,4)) + sage: W.codegrees() (2, 1, 0) - sage: W = ReflectionGroup((2,1,4)) # optional - gap3 - sage: W.codegrees() # optional - gap3 + sage: W = ReflectionGroup((2,1,4)) + sage: W.codegrees() (6, 4, 2, 0) - sage: W = ReflectionGroup((4,1,4)) # optional - gap3 - sage: W.codegrees() # optional - gap3 + sage: W = ReflectionGroup((4,1,4)) + sage: W.codegrees() (12, 8, 4, 0) - sage: W = ReflectionGroup((4,2,4)) # optional - gap3 - sage: W.codegrees() # optional - gap3 + sage: W = ReflectionGroup((4,2,4)) + sage: W.codegrees() (12, 8, 4, 0) - sage: W = ReflectionGroup((4,4,4)) # optional - gap3 - sage: W.codegrees() # optional - gap3 + sage: W = ReflectionGroup((4,4,4)) + sage: W.codegrees() (8, 8, 4, 0) - sage: W = ReflectionGroup((1,1,4), (3,1,2)) # optional - gap3 - sage: W.codegrees() # optional - gap3 + sage: W = ReflectionGroup((1,1,4), (3,1,2)) + sage: W.codegrees() (2, 1, 0, 3, 0) - sage: W = ReflectionGroup((1,1,4), (6,1,12), 23) # optional - gap3 # fails in GAP3 - sage: W.codegrees() # optional - gap3 + sage: W = ReflectionGroup((1,1,4), (6,1,12), 23) + sage: W.codegrees() (2, 1, 0, 66, 60, 54, 48, 42, 36, 30, 24, 18, 12, 6, 0, 8, 4, 0) """ if self.is_irreducible(): @@ -1135,13 +1128,13 @@ def reflection_eigenvalues_family(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: W.reflection_eigenvalues_family() # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: W.reflection_eigenvalues_family() Finite family {(): [0, 0], (1,4)(2,3)(5,6): [1/2, 0], (1,6,2)(3,5,4): [1/3, 2/3]} - sage: W = ReflectionGroup((3,1,2)) # optional - gap3 - sage: reflection_eigenvalues = W.reflection_eigenvalues_family() # optional - gap3 - sage: for elt in sorted(reflection_eigenvalues.keys()): # optional - gap3 + sage: W = ReflectionGroup((3,1,2)) + sage: reflection_eigenvalues = W.reflection_eigenvalues_family() + sage: for elt in sorted(reflection_eigenvalues.keys()): ....: print('%s %s'%(elt, reflection_eigenvalues[elt])) () [0, 0] (1,3,9)(2,4,10)(6,11,17)(8,12,18)(14,19,23)(15,16,20)(21,22,24) [1/3, 0] @@ -1153,9 +1146,9 @@ def reflection_eigenvalues_family(self): (1,9,3)(2,24,16)(4,21,20)(5,13,7)(6,23,12)(8,17,19)(10,22,15)(11,14,18) [2/3, 2/3] (1,13,9,7,3,5)(2,14,24,18,16,11)(4,6,21,23,20,12)(8,22,17,15,19,10) [1/3, 5/6] - sage: W = ReflectionGroup(23) # optional - gap3 - sage: reflection_eigenvalues = W.reflection_eigenvalues_family() # optional - gap3 - sage: for elt in sorted(reflection_eigenvalues.keys()): # optional - gap3 + sage: W = ReflectionGroup(23) + sage: reflection_eigenvalues = W.reflection_eigenvalues_family() + sage: for elt in sorted(reflection_eigenvalues.keys()): ....: print('%s %s'%(elt, reflection_eigenvalues[elt])) () [0, 0, 0] (1,8,4)(2,21,3)(5,10,11)(6,18,17)(7,9,12)(13,14,15)(16,23,19)(20,25,26)(22,24,27)(28,29,30) [1/3, 2/3, 0] @@ -1187,8 +1180,8 @@ def reflection_eigenvalues(self, w, is_class_representative=False): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: for w in W: # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: for w in W: ....: print('%s %s'%(w.reduced_word(), W.reflection_eigenvalues(w))) [] [0, 0] [2] [1/2, 0] @@ -1210,20 +1203,20 @@ def simple_roots(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: W.simple_roots() # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: W.simple_roots() Finite family {1: (1, 0), 2: (0, 1)} - sage: W = ReflectionGroup((1,1,4), (2,1,2)) # optional - gap3 - sage: W.simple_roots() # optional - gap3 + sage: W = ReflectionGroup((1,1,4), (2,1,2)) + sage: W.simple_roots() Finite family {1: (1, 0, 0, 0, 0), 2: (0, 1, 0, 0, 0), 3: (0, 0, 1, 0, 0), 4: (0, 0, 0, 1, 0), 5: (0, 0, 0, 0, 1)} - sage: W = ReflectionGroup((3,1,2)) # optional - gap3 - sage: W.simple_roots() # optional - gap3 + sage: W = ReflectionGroup((3,1,2)) + sage: W.simple_roots() Finite family {1: (1, 0), 2: (-1, 1)} - sage: W = ReflectionGroup((1,1,4), (3,1,2)) # optional - gap3 - sage: W.simple_roots() # optional - gap3 + sage: W = ReflectionGroup((1,1,4), (3,1,2)) + sage: W.simple_roots() Finite family {1: (1, 0, 0, 0, 0), 2: (0, 1, 0, 0, 0), 3: (0, 0, 1, 0, 0), 4: (0, 0, 0, 1, 0), 5: (0, 0, 0, -1, 1)} """ from sage.sets.family import Family @@ -1235,7 +1228,6 @@ def simple_root(self, i): EXAMPLES:: - sage: # optional - gap3 sage: W = ReflectionGroup(['A',3]) sage: W.simple_root(1) (1, 0, 0) @@ -1246,7 +1238,7 @@ def simple_root(self, i): TESTS:: - sage: W.simple_root(0) # optional - gap3 + sage: W.simple_root(0) Traceback (most recent call last): ... KeyError: 0 @@ -1262,20 +1254,20 @@ def simple_coroots(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: W.simple_coroots() # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: W.simple_coroots() Finite family {1: (2, -1), 2: (-1, 2)} - sage: W = ReflectionGroup((1,1,4), (2,1,2)) # optional - gap3 - sage: W.simple_coroots() # optional - gap3 + sage: W = ReflectionGroup((1,1,4), (2,1,2)) + sage: W.simple_coroots() Finite family {1: (2, -1, 0, 0, 0), 2: (-1, 2, -1, 0, 0), 3: (0, -1, 2, 0, 0), 4: (0, 0, 0, 2, -2), 5: (0, 0, 0, -1, 2)} - sage: W = ReflectionGroup((3,1,2)) # optional - gap3 - sage: W.simple_coroots() # optional - gap3 + sage: W = ReflectionGroup((3,1,2)) + sage: W.simple_coroots() Finite family {1: (-2*E(3) - E(3)^2, 0), 2: (-1, 1)} - sage: W = ReflectionGroup((1,1,4), (3,1,2)) # optional - gap3 - sage: W.simple_coroots() # optional - gap3 + sage: W = ReflectionGroup((1,1,4), (3,1,2)) + sage: W.simple_coroots() Finite family {1: (2, -1, 0, 0, 0), 2: (-1, 2, -1, 0, 0), 3: (0, -1, 2, 0, 0), 4: (0, 0, 0, -2*E(3) - E(3)^2, 0), 5: (0, 0, 0, -1, 1)} """ from sage.sets.family import Family @@ -1292,8 +1284,8 @@ def simple_coroot(self, i): EXAMPLES:: - sage: W = ReflectionGroup(['A',3]) # optional - gap3 - sage: W.simple_coroot(1) # optional - gap3 + sage: W = ReflectionGroup(['A',3]) + sage: W.simple_coroot(1) (2, -1, 0) """ return self.simple_coroots()[i] @@ -1310,14 +1302,14 @@ def independent_roots(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: W.independent_roots() # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: W.independent_roots() Finite family {1: (1, 0), 2: (0, 1)} - sage: W = ReflectionGroup((4,2,3)) # optional - gap3 - sage: W.simple_roots() # optional - gap3 + sage: W = ReflectionGroup((4,2,3)) + sage: W.simple_roots() Finite family {1: (1, 0, 0), 2: (-E(4), 1, 0), 3: (-1, 1, 0), 4: (0, -1, 1)} - sage: W.independent_roots() # optional - gap3 + sage: W.independent_roots() Finite family {1: (1, 0, 0), 2: (-E(4), 1, 0), 4: (0, -1, 1)} """ Delta = self.simple_roots() @@ -1339,12 +1331,12 @@ def roots(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: W.roots() # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: W.roots() [(1, 0), (0, 1), (1, 1), (-1, 0), (0, -1), (-1, -1)] - sage: W = ReflectionGroup((3,1,2)) # optional - gap3 - sage: W.roots() # optional - gap3 + sage: W = ReflectionGroup((3,1,2)) + sage: W.roots() [(1, 0), (-1, 1), (E(3), 0), (-E(3), 1), (0, 1), (1, -1), (0, E(3)), (1, -E(3)), (E(3)^2, 0), (-E(3)^2, 1), (E(3), -1), (E(3), -E(3)), (0, E(3)^2), (1, -E(3)^2), @@ -1352,16 +1344,16 @@ def roots(self): (E(3), -E(3)^2), (-E(3)^2, E(3)), (-1, E(3)^2), (-E(3), E(3)^2), (E(3)^2, -E(3)^2), (-E(3)^2, E(3)^2)] - sage: W = ReflectionGroup((4,2,2)) # optional - gap3 - sage: W.roots() # optional - gap3 + sage: W = ReflectionGroup((4,2,2)) + sage: W.roots() [(1, 0), (-E(4), 1), (-1, 1), (-1, 0), (E(4), 1), (1, 1), (0, -E(4)), (E(4), -1), (E(4), E(4)), (0, E(4)), (E(4), -E(4)), (0, 1), (1, -E(4)), (1, -1), (0, -1), (1, E(4)), (-E(4), 0), (-1, E(4)), (E(4), 0), (-E(4), E(4)), (-E(4), -1), (-E(4), -E(4)), (-1, -E(4)), (-1, -1)] - sage: W = ReflectionGroup((1,1,4), (3,1,2)) # optional - gap3 - sage: W.roots() # optional - gap3 + sage: W = ReflectionGroup((1,1,4), (3,1,2)) + sage: W.roots() [(1, 0, 0, 0, 0), (0, 1, 0, 0, 0), (0, 0, 1, 0, 0), (0, 0, 0, 1, 0), (0, 0, 0, -1, 1), (1, 1, 0, 0, 0), (0, 1, 1, 0, 0), (1, 1, 1, 0, 0), (-1, 0, 0, 0, 0), @@ -1390,16 +1382,16 @@ def braid_relations(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: W.braid_relations() # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: W.braid_relations() [[[1, 2, 1], [2, 1, 2]]] - sage: W = ReflectionGroup((2,1,3)) # optional - gap3 - sage: W.braid_relations() # optional - gap3 + sage: W = ReflectionGroup((2,1,3)) + sage: W.braid_relations() [[[1, 2, 1, 2], [2, 1, 2, 1]], [[1, 3], [3, 1]], [[2, 3, 2], [3, 2, 3]]] - sage: W = ReflectionGroup((2,2,3)) # optional - gap3 - sage: W.braid_relations() # optional - gap3 + sage: W = ReflectionGroup((2,2,3)) + sage: W.braid_relations() [[[1, 2, 1], [2, 1, 2]], [[1, 3], [3, 1]], [[2, 3, 2], [3, 2, 3]]] """ if self.is_real(): @@ -1414,12 +1406,12 @@ def fundamental_invariants(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: W.fundamental_invariants() # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: W.fundamental_invariants() (-2*x0^2 + 2*x0*x1 - 2*x1^2, 6*x0^2*x1 - 6*x0*x1^2) - sage: W = ReflectionGroup((3,1,2)) # optional - gap3 - sage: W.fundamental_invariants() # optional - gap3 + sage: W = ReflectionGroup((3,1,2)) + sage: W.fundamental_invariants() (x0^3 + x1^3, x0^3*x1^3) """ import re @@ -1455,11 +1447,11 @@ def jacobian_of_fundamental_invariants(self, invs=None): EXAMPLES:: - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: W.fundamental_invariants() # optional - gap3 + sage: W = ReflectionGroup(['A',2]) + sage: W.fundamental_invariants() (-2*x0^2 + 2*x0*x1 - 2*x1^2, 6*x0^2*x1 - 6*x0*x1^2) - sage: W.jacobian_of_fundamental_invariants() # optional - gap3 + sage: W.jacobian_of_fundamental_invariants() [ -4*x0 + 2*x1 2*x0 - 4*x1] [12*x0*x1 - 6*x1^2 6*x0^2 - 12*x0*x1] """ @@ -1484,8 +1476,8 @@ def primitive_vector_field(self, invs=None): EXAMPLES:: - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: W.primitive_vector_field() # optional - gap3 + sage: W = ReflectionGroup(['A',2]) + sage: W.primitive_vector_field() (3*x1/(6*x0^2 - 6*x0*x1 - 12*x1^2), 1/(6*x0^2 - 6*x0*x1 - 12*x1^2)) """ if not self.is_irreducible(): @@ -1508,8 +1500,8 @@ def apply_vector_field(self, f, vf=None): EXAMPLES:: - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: for x in W.primitive_vector_field()[0].parent().gens(): # optional - gap3 + sage: W = ReflectionGroup(['A',2]) + sage: for x in W.primitive_vector_field()[0].parent().gens(): ....: print(W.apply_vector_field(x)) 3*x1/(6*x0^2 - 6*x0*x1 - 12*x1^2) 1/(6*x0^2 - 6*x0*x1 - 12*x1^2) @@ -1535,23 +1527,23 @@ def cartan_matrix(self): EXAMPLES:: - sage: ReflectionGroup(['A',4]).cartan_matrix() # optional - gap3 + sage: ReflectionGroup(['A',4]).cartan_matrix() [ 2 -1 0 0] [-1 2 -1 0] [ 0 -1 2 -1] [ 0 0 -1 2] - sage: ReflectionGroup(['H',4]).cartan_matrix() # optional - gap3 + sage: ReflectionGroup(['H',4]).cartan_matrix() [ 2 E(5)^2 + E(5)^3 0 0] [E(5)^2 + E(5)^3 2 -1 0] [ 0 -1 2 -1] [ 0 0 -1 2] - sage: ReflectionGroup(4).cartan_matrix() # optional - gap3 + sage: ReflectionGroup(4).cartan_matrix() [-2*E(3) - E(3)^2 E(3)^2] [ -E(3)^2 -2*E(3) - E(3)^2] - sage: ReflectionGroup((4,2,2)).cartan_matrix() # optional - gap3 + sage: ReflectionGroup((4,2,2)).cartan_matrix() [ 2 -2*E(4) -2] [ E(4) 2 1 - E(4)] [ -1 1 + E(4) 2] @@ -1582,19 +1574,18 @@ def invariant_form(self, brute_force=False): EXAMPLES:: - sage: W = ReflectionGroup(['A',3]) # optional - gap3 - sage: F = W.invariant_form(); F # optional - gap3 + sage: W = ReflectionGroup(['A',3]) + sage: F = W.invariant_form(); F [ 1 -1/2 0] [-1/2 1 -1/2] [ 0 -1/2 1] To check that this is indeed the invariant form, see:: - sage: S = W.simple_reflections() # optional - gap3 - sage: all( F == S[i].matrix()*F*S[i].matrix().transpose() for i in W.index_set() ) # optional - gap3 + sage: S = W.simple_reflections() + sage: all( F == S[i].matrix()*F*S[i].matrix().transpose() for i in W.index_set() ) True - sage: # optional - gap3 sage: W = ReflectionGroup(['B',3]) sage: F = W.invariant_form(); F [ 1 -1 0] @@ -1604,44 +1595,44 @@ def invariant_form(self, brute_force=False): sage: w * F * w.transpose().conjugate() == F True - sage: S = W.simple_reflections() # optional - gap3 - sage: all( F == S[i].matrix()*F*S[i].matrix().transpose() for i in W.index_set() ) # optional - gap3 + sage: S = W.simple_reflections() + sage: all( F == S[i].matrix()*F*S[i].matrix().transpose() for i in W.index_set() ) True - sage: W = ReflectionGroup((3,1,2)) # optional - gap3 - sage: F = W.invariant_form(); F # optional - gap3 + sage: W = ReflectionGroup((3,1,2)) + sage: F = W.invariant_form(); F [1 0] [0 1] - sage: S = W.simple_reflections() # optional - gap3 - sage: all( F == S[i].matrix()*F*S[i].matrix().transpose().conjugate() for i in W.index_set() ) # optional - gap3 + sage: S = W.simple_reflections() + sage: all( F == S[i].matrix()*F*S[i].matrix().transpose().conjugate() for i in W.index_set() ) True It also worked for badly generated groups:: - sage: W = ReflectionGroup(7) # optional - gap3 - sage: W.is_well_generated() # optional - gap3 + sage: W = ReflectionGroup(7) + sage: W.is_well_generated() False - sage: F = W.invariant_form(); F # optional - gap3 + sage: F = W.invariant_form(); F [1 0] [0 1] - sage: S = W.simple_reflections() # optional - gap3 - sage: all( F == S[i].matrix()*F*S[i].matrix().transpose().conjugate() for i in W.index_set() ) # optional - gap3 + sage: S = W.simple_reflections() + sage: all( F == S[i].matrix()*F*S[i].matrix().transpose().conjugate() for i in W.index_set() ) True And also for reducible types:: - sage: W = ReflectionGroup(['B',3],(4,2,3),4,7); W # optional - gap3 + sage: W = ReflectionGroup(['B',3],(4,2,3),4,7); W Reducible complex reflection group of rank 10 and type B3 x G(4,2,3) x ST4 x ST7 - sage: F = W.invariant_form(); S = W.simple_reflections() # optional - gap3 - sage: all( F == S[i].matrix()*F*S[i].matrix().transpose().conjugate() for i in W.index_set() ) # optional - gap3 + sage: F = W.invariant_form(); S = W.simple_reflections() + sage: all( F == S[i].matrix()*F*S[i].matrix().transpose().conjugate() for i in W.index_set() ) True TESTS:: - sage: tests = [['A',3],['B',3],['F',4],(4,2,2),4,7] # optional - gap3 - sage: for ty in tests: # optional - gap3 + sage: tests = [['A',3],['B',3],['F',4],(4,2,2),4,7] + sage: for ty in tests: ....: W = ReflectionGroup(ty) ....: A = W.invariant_form() ....: B = W.invariant_form(brute_force=True) @@ -1713,8 +1704,8 @@ def _invariant_form_brute_force(self): EXAMPLES:: - sage: W = ReflectionGroup((3,1,2)) # optional - gap3 - sage: W._invariant_form_brute_force() # optional - gap3 + sage: W = ReflectionGroup((3,1,2)) + sage: W._invariant_form_brute_force() [1 0] [0 1] """ @@ -1774,7 +1765,6 @@ def invariant_form_standardization(self): EXAMPLES:: - sage: # optional - gap3 sage: W = ReflectionGroup((4,2,5)) sage: I = W.invariant_form() sage: A = W.invariant_form_standardization() @@ -1783,7 +1773,6 @@ def invariant_form_standardization(self): TESTS:: - sage: # optional - gap3 sage: W = ReflectionGroup(9) sage: A = W.invariant_form_standardization() sage: S = W.simple_reflections() @@ -1807,8 +1796,8 @@ def set_reflection_representation(self,refl_repr=None): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: for w in W: w.to_matrix(); print("-----") # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: for w in W: w.to_matrix(); print("-----") [1 0] [0 1] ----- @@ -1828,8 +1817,8 @@ def set_reflection_representation(self,refl_repr=None): [-1 0] ----- - sage: W.set_reflection_representation({1: matrix([[0,1,0],[1,0,0],[0,0,1]]), 2: matrix([[1,0,0],[0,0,1],[0,1,0]])}) # optional - gap3 - sage: for w in W: w.to_matrix(); print("-----") # optional - gap3 + sage: W.set_reflection_representation({1: matrix([[0,1,0],[1,0,0],[0,0,1]]), 2: matrix([[1,0,0],[0,0,1],[0,1,0]])}) + sage: for w in W: w.to_matrix(); print("-----") [1 0 0] [0 1 0] [0 0 1] @@ -1854,7 +1843,7 @@ def set_reflection_representation(self,refl_repr=None): [0 1 0] [1 0 0] ----- - sage: W.set_reflection_representation() # optional - gap3 + sage: W.set_reflection_representation() """ if refl_repr is None or set(refl_repr) == set(self.index_set()): self._reflection_representation = refl_repr @@ -1876,15 +1865,15 @@ def fake_degrees(self): EXAMPLES:: - sage: W = ReflectionGroup(12) # optional - gap3 - sage: W.fake_degrees() # optional - gap3 + sage: W = ReflectionGroup(12) + sage: W.fake_degrees() [1, q^12, q^11 + q, q^8 + q^4, q^7 + q^5, q^6 + q^4 + q^2, q^10 + q^8 + q^6, q^9 + q^7 + q^5 + q^3] - sage: W = ReflectionGroup(["H",4]) # optional - gap3 - sage: W.cardinality() # optional - gap3 + sage: W = ReflectionGroup(["H",4]) + sage: W.cardinality() 14400 - sage: sum(fdeg.subs(q=1)**2 for fdeg in W.fake_degrees()) # optional - gap3 + sage: sum(fdeg.subs(q=1)**2 for fdeg in W.fake_degrees()) 14400 """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -1918,7 +1907,6 @@ def coxeter_number(self, chi=None): EXAMPLES:: - sage: # optional - gap3 sage: W = ReflectionGroup(["H",4]) sage: W.coxeter_number() 30 @@ -1952,8 +1940,8 @@ def conjugacy_class_representative(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: for w in W: # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: for w in W: ....: print('%s %s'%(w.reduced_word(), w.conjugacy_class_representative().reduced_word())) [] [] [2] [1] @@ -1974,8 +1962,8 @@ def conjugacy_class(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: for w in W: sorted(w.conjugacy_class()) # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: for w in W: sorted(w.conjugacy_class()) [()] [(1,3)(2,5)(4,6), (1,4)(2,3)(5,6), (1,5)(2,4)(3,6)] [(1,3)(2,5)(4,6), (1,4)(2,3)(5,6), (1,5)(2,4)(3,6)] @@ -2020,20 +2008,20 @@ def reflection_length(self, in_unitary_group=False): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: sorted([t.reflection_length() for t in W]) # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: sorted([t.reflection_length() for t in W]) [0, 1, 1, 1, 2, 2] - sage: W = ReflectionGroup((2,1,2)) # optional - gap3 - sage: sorted([t.reflection_length() for t in W]) # optional - gap3 + sage: W = ReflectionGroup((2,1,2)) + sage: sorted([t.reflection_length() for t in W]) [0, 1, 1, 1, 1, 2, 2, 2] - sage: W = ReflectionGroup((2,2,2)) # optional - gap3 - sage: sorted([t.reflection_length() for t in W]) # optional - gap3 + sage: W = ReflectionGroup((2,2,2)) + sage: sorted([t.reflection_length() for t in W]) [0, 1, 1, 2] - sage: W = ReflectionGroup((3,1,2)) # optional - gap3 - sage: sorted([t.reflection_length() for t in W]) # optional - gap3 + sage: W = ReflectionGroup((3,1,2)) + sage: sorted([t.reflection_length() for t in W]) [0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] """ W = self.parent() @@ -2058,9 +2046,9 @@ def _repr_(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)); W # optional - gap3 + sage: W = ReflectionGroup((1,1,3)); W Irreducible real reflection group of rank 2 and type A2 - sage: W = ReflectionGroup((3,1,4)); W # optional - gap3 + sage: W = ReflectionGroup((3,1,4)); W Irreducible complex reflection group of rank 4 and type G(3,1,4) """ type_str = self._irrcomp_repr_(self._type[0]) @@ -2096,8 +2084,8 @@ def is_coxeter_element(self, which_primitive=1, is_class_representative=False): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: for w in W: # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: for w in W: ....: print('%s %s'%(w.reduced_word(), w.is_coxeter_element())) [] False [2] False @@ -2124,8 +2112,8 @@ def is_h_regular(self, is_class_representative=False): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: for w in W: # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: for w in W: ....: print('%s %s'%(w.reduced_word(), w.is_h_regular())) [] False [2] False @@ -2157,9 +2145,9 @@ def is_regular(self, h, is_class_representative=False): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: h = W.coxeter_number() # optional - gap3 - sage: for w in W: # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) + sage: h = W.coxeter_number() + sage: for w in W: ....: print("{} {}".format(w.reduced_word(), w.is_regular(h))) [] False [2] False @@ -2168,8 +2156,8 @@ def is_regular(self, h, is_class_representative=False): [2, 1] True [1, 2, 1] False - sage: W = ReflectionGroup(23); h = W.coxeter_number() # optional - gap3 - sage: for w in W: # optional - gap3 + sage: W = ReflectionGroup(23); h = W.coxeter_number() + sage: for w in W: ....: if w.is_regular(h): ....: w.reduced_word() [1, 2, 3] @@ -2199,7 +2187,6 @@ def is_regular(self, h, is_class_representative=False): Check that :trac:`25478` is fixed:: - sage: # optional - gap3 sage: W = ReflectionGroup(["A",5]) sage: w = W.from_reduced_word([1,2,3,5]) sage: w.is_regular(4) diff --git a/src/sage/combinat/root_system/reflection_group_element.pyx b/src/sage/combinat/root_system/reflection_group_element.pyx index 6cc6c6e25a2..4f01a5a2882 100644 --- a/src/sage/combinat/root_system/reflection_group_element.pyx +++ b/src/sage/combinat/root_system/reflection_group_element.pyx @@ -317,6 +317,7 @@ cdef class ComplexReflectionGroupElement(PermutationGroupElement): EXAMPLES:: + sage: # needs sage.graphs sage: W = WeylGroup(['A',2], prefix='s', implementation="permutation") sage: for w in W: ....: w.reduced_word() @@ -835,6 +836,7 @@ cdef class RealReflectionGroupElement(ComplexReflectionGroupElement): EXAMPLES:: + sage: # needs sage.graphs sage: W = CoxeterGroup(['A',4], implementation="permutation") sage: s = W.simple_reflections() sage: w = s[2] * s[1] * s[3] diff --git a/src/sage/combinat/root_system/reflection_group_real.py b/src/sage/combinat/root_system/reflection_group_real.py index aee6b1d9bd9..8ae2acee1c8 100644 --- a/src/sage/combinat/root_system/reflection_group_real.py +++ b/src/sage/combinat/root_system/reflection_group_real.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - gap3 r""" Finite real reflection groups ------------------------------- @@ -16,11 +17,11 @@ The point of entry to work with reflection groups is :func:`~sage.combinat.root_system.reflection_group_real.ReflectionGroup` which can be used with finite Cartan-Killing types:: - sage: ReflectionGroup(['A',2]) # optional - gap3 + sage: ReflectionGroup(['A',2]) Irreducible real reflection group of rank 2 and type A2 - sage: ReflectionGroup(['F',4]) # optional - gap3 + sage: ReflectionGroup(['F',4]) Irreducible real reflection group of rank 4 and type F4 - sage: ReflectionGroup(['H',3]) # optional - gap3 + sage: ReflectionGroup(['H',3]) Irreducible real reflection group of rank 3 and type H3 AUTHORS: @@ -76,49 +77,49 @@ def ReflectionGroup(*args,**kwds): Cartan-Killing classification types:: - sage: W = ReflectionGroup(['A',3]); W # optional - gap3 + sage: W = ReflectionGroup(['A',3]); W Irreducible real reflection group of rank 3 and type A3 - sage: W = ReflectionGroup(['H',4]); W # optional - gap3 + sage: W = ReflectionGroup(['H',4]); W Irreducible real reflection group of rank 4 and type H4 - sage: W = ReflectionGroup(['I',5]); W # optional - gap3 + sage: W = ReflectionGroup(['I',5]); W Irreducible real reflection group of rank 2 and type I2(5) the complex infinite family `G(r,p,n)` with `p` divides `r`:: - sage: W = ReflectionGroup((1,1,4)); W # optional - gap3 + sage: W = ReflectionGroup((1,1,4)); W Irreducible real reflection group of rank 3 and type A3 - sage: W = ReflectionGroup((2,1,3)); W # optional - gap3 + sage: W = ReflectionGroup((2,1,3)); W Irreducible real reflection group of rank 3 and type B3 Chevalley-Shepard-Todd exceptional classification types:: - sage: W = ReflectionGroup(23); W # optional - gap3 + sage: W = ReflectionGroup(23); W Irreducible real reflection group of rank 3 and type H3 Cartan types and matrices:: - sage: ReflectionGroup(CartanType(['A',2])) # optional - gap3 + sage: ReflectionGroup(CartanType(['A',2])) Irreducible real reflection group of rank 2 and type A2 - sage: ReflectionGroup(CartanType((['A',2],['A',2]))) # optional - gap3 + sage: ReflectionGroup(CartanType((['A',2],['A',2]))) Reducible real reflection group of rank 4 and type A2 x A2 - sage: C = CartanMatrix(['A',2]) # optional - gap3 - sage: ReflectionGroup(C) # optional - gap3 + sage: C = CartanMatrix(['A',2]) + sage: ReflectionGroup(C) Irreducible real reflection group of rank 2 and type A2 multiples of the above:: - sage: W = ReflectionGroup(['A',2],['B',2]); W # optional - gap3 + sage: W = ReflectionGroup(['A',2],['B',2]); W Reducible real reflection group of rank 4 and type A2 x B2 - sage: W = ReflectionGroup(['A',2],4); W # optional - gap3 + sage: W = ReflectionGroup(['A',2],4); W Reducible complex reflection group of rank 4 and type A2 x ST4 - sage: W = ReflectionGroup((4,2,2),4); W # optional - gap3 + sage: W = ReflectionGroup((4,2,2),4); W Reducible complex reflection group of rank 4 and type G(4,2,2) x ST4 """ if not is_chevie_available(): @@ -258,8 +259,8 @@ def __init__(self, W_types, index_set=None, hyperplane_index_set=None, reflectio TESTS:: - sage: W = ReflectionGroup(['A',3]) # optional - gap3 - sage: TestSuite(W).run() # optional - gap3 + sage: W = ReflectionGroup(['A',3]) + sage: TestSuite(W).run() """ W_types = tuple([tuple(W_type) if isinstance(W_type, (list,tuple)) else W_type for W_type in W_types]) @@ -283,8 +284,8 @@ def _repr_(self): EXAMPLES:: - sage: W = ReflectionGroup(['A',3],['B',2],['I',5],['I',6]) # optional - gap3 - sage: W._repr_() # optional - gap3 + sage: W = ReflectionGroup(['A',3],['B',2],['I',5],['I',6]) + sage: W._repr_() 'Reducible real reflection group of rank 9 and type A3 x B2 x I2(5) x G2' """ type_str = '' @@ -325,9 +326,9 @@ def iteration(self, algorithm="breadth", tracking_words=True): EXAMPLES:: - sage: W = ReflectionGroup(["B",2]) # optional - gap3 + sage: W = ReflectionGroup(["B",2]) - sage: for w in W.iteration("breadth",True): # optional - gap3 + sage: for w in W.iteration("breadth",True): ....: print("%s %s"%(w, w._reduced_word)) () [] (1,3)(2,6)(5,7) [1] @@ -338,7 +339,7 @@ def iteration(self, algorithm="breadth", tracking_words=True): (1,7)(3,5)(4,8) [0, 1, 0] (1,5)(2,6)(3,7)(4,8) [0, 1, 0, 1] - sage: for w in W.iteration("depth", False): w # optional - gap3 + sage: for w in W.iteration("depth", False): w () (1,3)(2,6)(5,7) (1,5)(2,4)(6,8) @@ -360,9 +361,9 @@ def __iter__(self): EXAMPLES:: - sage: W = ReflectionGroup(["B",2]) # optional - gap3 + sage: W = ReflectionGroup(["B",2]) - sage: for w in W: print("%s %s"%(w, w._reduced_word)) # optional - gap3 + sage: for w in W: print("%s %s"%(w, w._reduced_word)) () [] (1,3)(2,6)(5,7) [1] (1,5)(2,4)(6,8) [0] @@ -381,12 +382,12 @@ def bipartite_index_set(self): EXAMPLES:: - sage: W = ReflectionGroup(["A",5]) # optional - gap3 - sage: W.bipartite_index_set() # optional - gap3 + sage: W = ReflectionGroup(["A",5]) + sage: W.bipartite_index_set() [[1, 3, 5], [2, 4]] - sage: W = ReflectionGroup(["A",5],index_set=['a','b','c','d','e']) # optional - gap3 - sage: W.bipartite_index_set() # optional - gap3 + sage: W = ReflectionGroup(["A",5],index_set=['a','b','c','d','e']) + sage: W.bipartite_index_set() [['a', 'c', 'e'], ['b', 'd']] """ L, R = self._gap_group.BipartiteDecomposition().sage() @@ -401,25 +402,25 @@ def cartan_type(self): EXAMPLES:: - sage: W = ReflectionGroup(['A',3]) # optional - gap3 - sage: W.cartan_type() # optional - gap3 + sage: W = ReflectionGroup(['A',3]) + sage: W.cartan_type() ['A', 3] - sage: W = ReflectionGroup(['A',3], ['B',3]) # optional - gap3 - sage: W.cartan_type() # optional - gap3 + sage: W = ReflectionGroup(['A',3], ['B',3]) + sage: W.cartan_type() A3xB3 relabelled by {1: 3, 2: 2, 3: 1} TESTS: Check that dihedral types are handled properly:: - sage: W = ReflectionGroup(['I',3]); W # optional - gap3 + sage: W = ReflectionGroup(['I',3]); W Irreducible real reflection group of rank 2 and type A2 - sage: W = ReflectionGroup(['I',4]); W # optional - gap3 + sage: W = ReflectionGroup(['I',4]); W Irreducible real reflection group of rank 2 and type C2 - sage: W = ReflectionGroup(['I',5]); W # optional - gap3 + sage: W = ReflectionGroup(['I',5]); W Irreducible real reflection group of rank 2 and type I2(5) """ if len(self._type) == 1: @@ -440,8 +441,8 @@ def positive_roots(self): EXAMPLES:: - sage: W = ReflectionGroup(['A',3], ['B',2]) # optional - gap3 - sage: W.positive_roots() # optional - gap3 + sage: W = ReflectionGroup(['A',3], ['B',2]) + sage: W.positive_roots() [(1, 0, 0, 0, 0), (0, 1, 0, 0, 0), (0, 0, 1, 0, 0), @@ -453,8 +454,8 @@ def positive_roots(self): (1, 1, 1, 0, 0), (0, 0, 0, 2, 1)] - sage: W = ReflectionGroup(['A',3]) # optional - gap3 - sage: W.positive_roots() # optional - gap3 + sage: W = ReflectionGroup(['A',3]) + sage: W.positive_roots() [(1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (0, 1, 1), (1, 1, 1)] """ return self.roots()[:self.number_of_reflections()] @@ -465,8 +466,8 @@ def almost_positive_roots(self): EXAMPLES:: - sage: W = ReflectionGroup(['A',3], ['B',2]) # optional - gap3 - sage: W.almost_positive_roots() # optional - gap3 + sage: W = ReflectionGroup(['A',3], ['B',2]) + sage: W.almost_positive_roots() [(-1, 0, 0, 0, 0), (0, -1, 0, 0, 0), (0, 0, -1, 0, 0), @@ -483,8 +484,8 @@ def almost_positive_roots(self): (1, 1, 1, 0, 0), (0, 0, 0, 2, 1)] - sage: W = ReflectionGroup(['A',3]) # optional - gap3 - sage: W.almost_positive_roots() # optional - gap3 + sage: W = ReflectionGroup(['A',3]) + sage: W.almost_positive_roots() [(-1, 0, 0), (0, -1, 0), (0, 0, -1), @@ -503,8 +504,8 @@ def root_to_reflection(self, root): EXAMPLES:: - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: for beta in W.roots(): W.root_to_reflection(beta) # optional - gap3 + sage: W = ReflectionGroup(['A',2]) + sage: for beta in W.roots(): W.root_to_reflection(beta) (1,4)(2,3)(5,6) (1,3)(2,5)(4,6) (1,5)(2,4)(3,6) @@ -527,8 +528,8 @@ def reflection_to_positive_root(self, r): EXAMPLES:: - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: for r in W.reflections(): # optional - gap3 + sage: W = ReflectionGroup(['A',2]) + sage: for r in W.reflections(): ....: print(W.reflection_to_positive_root(r)) (1, 0) (0, 1) @@ -557,15 +558,14 @@ def fundamental_weights(self): EXAMPLES:: - sage: W = ReflectionGroup(['A',3], ['B',2]) # optional - gap3 - sage: W.fundamental_weights() # optional - gap3 + sage: W = ReflectionGroup(['A',3], ['B',2]) + sage: W.fundamental_weights() Finite family {1: (3/4, 1/2, 1/4, 0, 0), 2: (1/2, 1, 1/2, 0, 0), 3: (1/4, 1/2, 3/4, 0, 0), 4: (0, 0, 0, 1, 1/2), 5: (0, 0, 0, 1, 1)} - sage: W = ReflectionGroup(['A',3]) # optional - gap3 - sage: W.fundamental_weights() # optional - gap3 + sage: W = ReflectionGroup(['A',3]) + sage: W.fundamental_weights() Finite family {1: (3/4, 1/2, 1/4), 2: (1/2, 1, 1/2), 3: (1/4, 1/2, 3/4)} - sage: # optional - gap3 sage: W = ReflectionGroup(['A',3]) sage: S = W.simple_reflections() sage: N = W.fundamental_weights() @@ -598,8 +598,8 @@ def fundamental_weight(self, i): EXAMPLES:: - sage: W = ReflectionGroup(['A',3]) # optional - gap3 - sage: [ W.fundamental_weight(i) for i in W.index_set() ] # optional - gap3 + sage: W = ReflectionGroup(['A',3]) + sage: [ W.fundamental_weight(i) for i in W.index_set() ] [(3/4, 1/2, 1/4), (1/2, 1, 1/2), (1/4, 1/2, 3/4)] """ return self.fundamental_weights()[i] @@ -611,8 +611,8 @@ def coxeter_diagram(self): EXAMPLES:: - sage: G = ReflectionGroup(['B',3]) # optional - gap3 - sage: G.coxeter_diagram().edges(labels=True, sort=True) # optional - gap3 + sage: G = ReflectionGroup(['B',3]) + sage: G.coxeter_diagram().edges(labels=True, sort=True) [(1, 2, 4), (2, 3, 3)] """ from sage.graphs.graph import Graph @@ -634,8 +634,8 @@ def coxeter_matrix(self): EXAMPLES:: - sage: G = ReflectionGroup(['A',3]) # optional - gap3 - sage: G.coxeter_matrix() # optional - gap3 + sage: G = ReflectionGroup(['A',3]) + sage: G.coxeter_matrix() [1 3 2] [3 1 3] [2 3 1] @@ -650,8 +650,8 @@ def right_coset_representatives(self, J): EXAMPLES:: - sage: W = ReflectionGroup(["A",3]) # optional - gap3 - sage: for J in Subsets([1,2,3]): W.right_coset_representatives(J) # optional - gap3 + sage: W = ReflectionGroup(["A",3]) + sage: for J in Subsets([1,2,3]): W.right_coset_representatives(J) [(), (2,5)(3,9)(4,6)(8,11)(10,12), (1,4)(2,8)(3,5)(7,10)(9,11), (1,7)(2,4)(5,6)(8,10)(11,12), (1,2,10)(3,6,5)(4,7,8)(9,12,11), (1,4,6)(2,3,11)(5,8,9)(7,10,12), (1,6,4)(2,11,3)(5,9,8)(7,12,10), @@ -705,8 +705,8 @@ def simple_root_index(self, i): EXAMPLES:: - sage: W = ReflectionGroup(['A',3]) # optional - gap3 - sage: [W.simple_root_index(i) for i in W.index_set()] # optional - gap3 + sage: W = ReflectionGroup(['A',3]) + sage: [W.simple_root_index(i) for i in W.index_set()] [0, 1, 2] """ return self._index_set_inverse[i] @@ -736,14 +736,12 @@ def bruhat_cone(self, x, y, side='upper', backend='cdd'): EXAMPLES:: - sage: # optional - gap3 sage: W = ReflectionGroup(['A',2]) sage: x = W.from_reduced_word([1]) sage: y = W.w0 sage: W.bruhat_cone(x, y) A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays - sage: # optional - gap3 sage: W = ReflectionGroup(['E',6]) sage: x = W.one() sage: y = W.w0 @@ -752,7 +750,6 @@ def bruhat_cone(self, x, y, side='upper', backend='cdd'): TESTS:: - sage: # optional - gap3 sage: W = ReflectionGroup(['A',2]) sage: x = W.one() sage: y = W.w0 @@ -805,8 +802,8 @@ def right_coset_representatives(self): EXAMPLES:: - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: for w in W: # optional - gap3 + sage: W = ReflectionGroup(['A',2]) + sage: for w in W: ....: rcr = w.right_coset_representatives() ....: print("%s %s"%(w.reduced_word(), ....: [v.reduced_word() for v in rcr])) @@ -834,8 +831,8 @@ def left_coset_representatives(self): EXAMPLES:: - sage: W = ReflectionGroup(['A',2]) # optional - gap3 - sage: for w in W: # optional - gap3 + sage: W = ReflectionGroup(['A',2]) + sage: for w in W: ....: lcr = w.left_coset_representatives() ....: print("%s %s"%(w.reduced_word(), ....: [v.reduced_word() for v in lcr])) @@ -856,7 +853,7 @@ def _repr_(self): EXAMPLES:: - sage: for i in [2..7]: ReflectionGroup(["I", i]) # optional - gap3 + sage: for i in [2..7]: ReflectionGroup(["I", i]) Reducible real reflection group of rank 2 and type A1 x A1 Irreducible real reflection group of rank 2 and type A2 Irreducible real reflection group of rank 2 and type C2 diff --git a/src/sage/combinat/root_system/root_lattice_realizations.py b/src/sage/combinat/root_system/root_lattice_realizations.py index 80ed38c982f..d3e443d830b 100644 --- a/src/sage/combinat/root_system/root_lattice_realizations.py +++ b/src/sage/combinat/root_system/root_lattice_realizations.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Root lattice realizations """ @@ -1117,7 +1116,7 @@ def nonnesting_partition_lattice(self, facade=False): sage: RS = R.root_lattice() sage: P = RS.nonnesting_partition_lattice(); P # needs sage.graphs Finite lattice containing 14 elements - sage: P.coxeter_transformation()**10 == 1 # needs sage.graphs + sage: P.coxeter_transformation()**10 == 1 # needs sage.graphs sage.libs.flint True sage: # needs sage.graphs @@ -1125,7 +1124,7 @@ def nonnesting_partition_lattice(self, facade=False): sage: RS = R.root_lattice() sage: P = RS.nonnesting_partition_lattice(); P Finite lattice containing 20 elements - sage: P.coxeter_transformation()**7 == 1 + sage: P.coxeter_transformation()**7 == 1 # needs sage.libs.flint True REFERENCES: @@ -1157,7 +1156,7 @@ def generalized_nonnesting_partition_lattice(self, m, facade=False): sage: RS = R.root_lattice() sage: P = RS.generalized_nonnesting_partition_lattice(2); P # needs sage.graphs Finite lattice containing 12 elements - sage: P.coxeter_transformation()**20 == 1 # needs sage.graphs + sage: P.coxeter_transformation()**20 == 1 # needs sage.graphs sage.libs.flint True """ Phi_plus = self.positive_roots() @@ -1789,8 +1788,8 @@ def tau_plus_minus(self): We explore the example of [CFZ2002]_ Eq.(1.3):: sage: S = RootSystem(['A',2]).root_lattice() - sage: taup, taum = S.tau_plus_minus() # needs sage.graphs - sage: for beta in S.almost_positive_roots(): # needs sage.graphs + sage: taup, taum = S.tau_plus_minus() # needs sage.graphs sage.libs.gap + sage: for beta in S.almost_positive_roots(): # needs sage.graphs sage.libs.gap ....: print("{} , {} , {}".format(beta, taup(beta), taum(beta))) -alpha[1] , alpha[1] , -alpha[1] alpha[1] , -alpha[1] , alpha[1] + alpha[2] @@ -1817,14 +1816,14 @@ def almost_positive_roots_decomposition(self): EXAMPLES:: - sage: RootSystem(['A',2]).root_lattice().almost_positive_roots_decomposition() # needs sage.graphs + sage: RootSystem(['A',2]).root_lattice().almost_positive_roots_decomposition() # needs sage.graphs sage.libs.gap [[-alpha[1], alpha[1], alpha[1] + alpha[2], alpha[2], -alpha[2]]] - sage: RootSystem(['B',2]).root_lattice().almost_positive_roots_decomposition() # needs sage.graphs + sage: RootSystem(['B',2]).root_lattice().almost_positive_roots_decomposition() # needs sage.graphs sage.libs.gap [[-alpha[1], alpha[1], alpha[1] + 2*alpha[2]], [-alpha[2], alpha[2], alpha[1] + alpha[2]]] - sage: RootSystem(['D',4]).root_lattice().almost_positive_roots_decomposition() # needs sage.graphs + sage: RootSystem(['D',4]).root_lattice().almost_positive_roots_decomposition() # needs sage.graphs sage.libs.gap [[-alpha[1], alpha[1], alpha[1] + alpha[2], alpha[2] + alpha[3] + alpha[4]], [-alpha[2], alpha[2], alpha[1] + alpha[2] + alpha[3] + alpha[4], alpha[1] + 2*alpha[2] + alpha[3] + alpha[4]], @@ -4262,8 +4261,8 @@ def weyl_action(self, element, inverse=False): Acting by an element of the Coxeter or Weyl group on a vector in its own lattice of definition (implemented by matrix multiplication on a vector):: - sage: w = wl.weyl_group().from_reduced_word([1, 2]) # needs sage.graphs - sage: mudom.weyl_action(w) # needs sage.graphs + sage: w = wl.weyl_group().from_reduced_word([1, 2]) # needs sage.graphs sage.libs.gap + sage: mudom.weyl_action(w) # needs sage.graphs sage.libs.gap Lambda[1] - 2*Lambda[3] Acting by an element of an isomorphic Coxeter or Weyl group (implemented by the diff --git a/src/sage/combinat/root_system/root_space.py b/src/sage/combinat/root_system/root_space.py index cb7fc672ac2..a375b3b8074 100644 --- a/src/sage/combinat/root_system/root_space.py +++ b/src/sage/combinat/root_system/root_space.py @@ -429,12 +429,13 @@ def max_quantum_element(self): EXAMPLES:: + sage: # needs sage.graphs sage.libs.gap sage: Qvee = RootSystem(['C',2]).coroot_lattice() - sage: Qvee.from_vector(vector([1,2])).max_quantum_element() # needs sage.graphs + sage: Qvee.from_vector(vector([1,2])).max_quantum_element() [2, 1, 2, 1] - sage: Qvee.from_vector(vector([1,1])).max_quantum_element() # needs sage.graphs + sage: Qvee.from_vector(vector([1,1])).max_quantum_element() [1, 2, 1] - sage: Qvee.from_vector(vector([0,2])).max_quantum_element() # needs sage.graphs + sage: Qvee.from_vector(vector([0,2])).max_quantum_element() [2] """ diff --git a/src/sage/combinat/root_system/root_system.py b/src/sage/combinat/root_system/root_system.py index a26b9afa75c..c80cffbdb87 100644 --- a/src/sage/combinat/root_system/root_system.py +++ b/src/sage/combinat/root_system/root_system.py @@ -158,7 +158,7 @@ class RootSystem(UniqueRepresentation, SageObject): In finite type `A`, we recover the natural representation of the symmetric group as group of permutation matrices:: - sage: RootSystem(["A",2]).ambient_space().weyl_group().simple_reflections() # needs sage.libs.pari + sage: RootSystem(["A",2]).ambient_space().weyl_group().simple_reflections() # needs sage.libs.gap sage.libs.pari Finite family {1: [0 1 0] [1 0 0] [0 0 1], @@ -169,7 +169,7 @@ class RootSystem(UniqueRepresentation, SageObject): In type `B`, `C`, and `D`, we recover the natural representation of the Weyl group as groups of signed permutation matrices:: - sage: RootSystem(["B",3]).ambient_space().weyl_group().simple_reflections() # needs sage.libs.pari + sage: RootSystem(["B",3]).ambient_space().weyl_group().simple_reflections() # needs sage.libs.gap sage.libs.pari Finite family {1: [0 1 0] [1 0 0] [0 0 1], @@ -203,15 +203,17 @@ class RootSystem(UniqueRepresentation, SageObject): Here is the orbit of the identity under the action of the finite group:: - sage: W = L.weyl_group() # needs sage.libs.pari - sage: S3 = [ w.action(id) for w in W.classical() ] # needs sage.graphs sage.libs.pari - sage: [L.classical()(x) for x in S3] # needs sage.graphs sage.libs.pari + sage: # needs sage.graphs sage.libs.gap sage.libs.pari + sage: W = L.weyl_group() + sage: S3 = [ w.action(id) for w in W.classical() ] + sage: [L.classical()(x) for x in S3] [(1, 2, 3), (3, 1, 2), (2, 3, 1), (2, 1, 3), (1, 3, 2), (3, 2, 1)] And the action of `s_0` on these yields:: - sage: s = W.simple_reflections() # needs sage.libs.pari - sage: [L.classical()(s[0].action(x)) for x in S3] # needs sage.graphs sage.libs.pari + sage: # needs sage.graphs sage.libs.gap sage.libs.pari + sage: s = W.simple_reflections() + sage: [L.classical()(s[0].action(x)) for x in S3] [(0, 2, 4), (-1, 1, 6), (-2, 3, 5), (0, 1, 5), (-1, 3, 4), (-2, 2, 6)] We can also plot various components of the ambient spaces:: diff --git a/src/sage/combinat/root_system/type_E.py b/src/sage/combinat/root_system/type_E.py index 5771d6d948f..7c3292d6ea7 100644 --- a/src/sage/combinat/root_system/type_E.py +++ b/src/sage/combinat/root_system/type_E.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Root system data for type E """ diff --git a/src/sage/combinat/root_system/type_F.py b/src/sage/combinat/root_system/type_F.py index 524dd1f7c35..5d699d31c5a 100644 --- a/src/sage/combinat/root_system/type_F.py +++ b/src/sage/combinat/root_system/type_F.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Root system data for type F """ diff --git a/src/sage/combinat/root_system/weight_lattice_realizations.py b/src/sage/combinat/root_system/weight_lattice_realizations.py index be54faa6bcb..c33299f1012 100644 --- a/src/sage/combinat/root_system/weight_lattice_realizations.py +++ b/src/sage/combinat/root_system/weight_lattice_realizations.py @@ -551,7 +551,7 @@ def dynkin_diagram_automorphism_of_alcove_morphism(self, f): Translations by elements of the root lattice induce a trivial Dynkin diagram automorphism:: - sage: # needs sage.graphs + sage: # needs sage.graphs sage.libs.gap sage: R.dynkin_diagram_automorphism_of_alcove_morphism(alpha[0].translation) {0: 0, 1: 1, 2: 2} sage: R.dynkin_diagram_automorphism_of_alcove_morphism(alpha[1].translation) @@ -565,19 +565,19 @@ def dynkin_diagram_automorphism_of_alcove_morphism(self, f): sage: omega1 = Lambda[1] - Lambda[0] sage: omega2 = Lambda[2] - Lambda[0] - sage: # needs sage.graphs + sage: # needs sage.graphs sage.libs.gap sage: R.dynkin_diagram_automorphism_of_alcove_morphism(omega1.translation) {0: 1, 1: 2, 2: 0} sage: R.dynkin_diagram_automorphism_of_alcove_morphism(omega2.translation) {0: 2, 1: 0, 2: 1} - sage: # needs sage.graphs + sage: # needs sage.graphs sage.libs.gap sage: R = RootSystem(['C',2,1]).weight_lattice() sage: alpha = R.simple_roots() sage: R.dynkin_diagram_automorphism_of_alcove_morphism(alpha[1].translation) {0: 2, 1: 1, 2: 0} - sage: # needs sage.graphs + sage: # needs sage.graphs sage.libs.gap sage: R = RootSystem(['D',5,1]).weight_lattice() sage: Lambda = R.fundamental_weights() sage: omega1 = Lambda[1] - Lambda[0] @@ -704,9 +704,14 @@ def _test_reduced_word_of_translation(self, elements=None, **options): # dictionary assigning a simple root to its index rank_simple_roots = dict( (alpha[i],i) for i in self.index_set() ) + try: + W = self.weyl_group() + except ImportError: + return + for t in elements: t = t - self.base_ring()(t.level()/Lambda[0].level()) * Lambda[0] - w = self.weyl_group().from_reduced_word(self.reduced_word_of_translation(t)) + w = W.from_reduced_word(self.reduced_word_of_translation(t)) if self.null_root().is_zero(): # The following formula is only valid when the null root is zero tester.assertEqual(w.action(rho), rho + rho.level()*t) diff --git a/src/sage/combinat/root_system/weyl_characters.py b/src/sage/combinat/root_system/weyl_characters.py index 51baa89b661..a42929606b1 100644 --- a/src/sage/combinat/root_system/weyl_characters.py +++ b/src/sage/combinat/root_system/weyl_characters.py @@ -1,4 +1,4 @@ -# sage.doctest: needs sage.groups sage.modules +# sage.doctest: needs sage.graphs sage.groups sage.modules """ Weyl Character Rings """ @@ -691,7 +691,7 @@ def _demazure_weights(self, hwv, word="long", debug=False): dd = {} h = tuple(int(hwv.inner_product(alphacheck[j])) for j in self._space.index_set()) - dd[h] = int(1) + dd[h] = 1 return self._demazure_helper(dd, word=word, debug=debug) def _demazure_helper(self, dd, word="long", debug=False): diff --git a/src/sage/combinat/rsk.py b/src/sage/combinat/rsk.py index 2c787878768..96e5e29db5b 100644 --- a/src/sage/combinat/rsk.py +++ b/src/sage/combinat/rsk.py @@ -2968,7 +2968,7 @@ def _backward_format_output(self, obj1, obj2, output): return DecreasingHeckeFactorization(df) -class InsertionRules(): +class InsertionRules: r""" Catalog of rules for RSK-like insertion algorithms. """ diff --git a/src/sage/combinat/set_partition.py b/src/sage/combinat/set_partition.py index c7d5e98ea33..c08e1c7aef3 100644 --- a/src/sage/combinat/set_partition.py +++ b/src/sage/combinat/set_partition.py @@ -73,7 +73,7 @@ def _repr_(self): sage: S([[1,3],[2,4]]) {{1, 3}, {2, 4}} """ - return '{' + ', '.join(('{' + repr(sorted(x))[1:-1] + '}' for x in self)) + '}' + return '{' + ', '.join('{' + repr(sorted(x))[1:-1] + '}' for x in self) + '}' def __hash__(self): """ diff --git a/src/sage/combinat/set_partition_ordered.py b/src/sage/combinat/set_partition_ordered.py index 186835f7129..a76adfa8f9f 100644 --- a/src/sage/combinat/set_partition_ordered.py +++ b/src/sage/combinat/set_partition_ordered.py @@ -220,7 +220,7 @@ def _repr_(self): sage: OrderedSetPartition([[1,3],[2,4]]) [{1, 3}, {2, 4}] """ - return '[' + ', '.join(('{' + repr(sorted(x))[1:-1] + '}' for x in self)) + ']' + return '[' + ', '.join('{' + repr(sorted(x))[1:-1] + '}' for x in self) + ']' def check(self): """ diff --git a/src/sage/combinat/sf/k_dual.py b/src/sage/combinat/sf/k_dual.py index 4fa2e971e36..546695bc338 100644 --- a/src/sage/combinat/sf/k_dual.py +++ b/src/sage/combinat/sf/k_dual.py @@ -284,7 +284,7 @@ def _G_to_km_on_basis_single_level(self, w, m): return 0 ans = self.zero() for la in Partitions(m, max_part=self.k): - ans += g.homogeneous_basis_noncommutative_variables_zero_Hecke((la)).coefficient(w) * mon(la) + ans += g.homogeneous_basis_noncommutative_variables_zero_Hecke(la).coefficient(w) * mon(la) return ans def _AffineGrothendieck(self, w, m): diff --git a/src/sage/combinat/sf/macdonald.py b/src/sage/combinat/sf/macdonald.py index 09a3ef98798..1358c5779df 100644 --- a/src/sage/combinat/sf/macdonald.py +++ b/src/sage/combinat/sf/macdonald.py @@ -1843,7 +1843,7 @@ def _creation_by_determinant_helper(self, k, part): INPUT: - ``self`` -- an element of the Macdonald `S` basis - - ``k`` -- an positive integer at least as big as the + - ``k`` -- a positive integer at least as big as the length of ``part`` - ``part`` -- a partition diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index bca95b7f9da..2b42ebb7be6 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -196,7 +196,7 @@ - Darij Grinberg (2013) Sym over rings that are not characteristic 0 """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 Mike Hansen # 2012 Anne Schilling # 2012 Mike Zabrocki @@ -210,8 +210,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.misc.cachefunc import cached_method from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ @@ -306,7 +306,7 @@ def is_SymmetricFunction(x): return isinstance(x, SymmetricFunctionAlgebra_generic.Element) ##################################################################### -## Bases categories +# Bases categories from sage.categories.realizations import Category_realization_of_parent @@ -1429,30 +1429,30 @@ def carlitz_shareshian_wachs(self, n, d, s, comparison=None): # be folly. if comparison is None: def check_word(w): - if sum((1 for i in range(n-1) if w[i] > w[i+1])) != d: + if sum(1 for i in range(n-1) if w[i] > w[i+1]) != d: return False - if sum((1 for i in range(n-1) if w[i] == w[i+1])) != s: + if sum(1 for i in range(n-1) if w[i] == w[i+1]) != s: return False return True elif comparison == -1: def check_word(w): - if sum((1 for i in range(n-1) if w[i] > w[i+1])) != d: + if sum(1 for i in range(n-1) if w[i] > w[i+1]) != d: return False - if sum((1 for i in range(n-1) if w[i] == w[i+1])) != s: + if sum(1 for i in range(n-1) if w[i] == w[i+1]) != s: return False return w[0] < w[-1] elif comparison == 0: def check_word(w): - if sum((1 for i in range(n-1) if w[i] > w[i+1])) != d: + if sum(1 for i in range(n-1) if w[i] > w[i+1]) != d: return False - if sum((1 for i in range(n-1) if w[i] == w[i+1])) != s: + if sum(1 for i in range(n-1) if w[i] == w[i+1]) != s: return False return w[0] == w[-1] elif comparison == 1: def check_word(w): - if sum((1 for i in range(n-1) if w[i] > w[i+1])) != d: + if sum(1 for i in range(n-1) if w[i] > w[i+1]) != d: return False - if sum((1 for i in range(n-1) if w[i] == w[i+1])) != s: + if sum(1 for i in range(n-1) if w[i] == w[i+1]) != s: return False return w[0] > w[-1] @@ -4619,10 +4619,10 @@ def internal_coproduct(self): @cached_function def hnimage(n): - return result_parent.sum((tensor([parent(s(lam)), parent(s(lam))]) - for lam in Partitions(n))) + return result_parent.sum(tensor([parent(s(lam)), parent(s(lam))]) + for lam in Partitions(n)) for lam, a in h(self): - result += a * prod((hnimage(i) for i in lam)) + result += a * prod(hnimage(i) for i in lam) return result kronecker_coproduct = internal_coproduct @@ -5588,7 +5588,7 @@ def _is_positive(self, s): True """ s_self = s(self) - return all(( _nonnegative_coefficients(c) for c in s_self.coefficients() )) + return all(_nonnegative_coefficients(c) for c in s_self.coefficients()) def degree(self): r""" diff --git a/src/sage/combinat/shard_order.py b/src/sage/combinat/shard_order.py index e40198fc27a..d33bc2173f6 100644 --- a/src/sage/combinat/shard_order.py +++ b/src/sage/combinat/shard_order.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Shard intersection order diff --git a/src/sage/combinat/shifted_primed_tableau.py b/src/sage/combinat/shifted_primed_tableau.py index e9a320cd0ea..a05a8b0bee8 100644 --- a/src/sage/combinat/shifted_primed_tableau.py +++ b/src/sage/combinat/shifted_primed_tableau.py @@ -553,7 +553,7 @@ def _ascii_art_table(self, unicode=False): else: l1 += uh + h*width if unicode: - l2 += u"{}{:^{width}}".format(v, e, width=width) + l2 += "{}{:^{width}}".format(v, e, width=width) else: l2 += "{}{:^{width}}".format(v, e, width=width) if i <= n: diff --git a/src/sage/combinat/shuffle.py b/src/sage/combinat/shuffle.py index 50618a6388f..9da145671bf 100644 --- a/src/sage/combinat/shuffle.py +++ b/src/sage/combinat/shuffle.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Shuffle product of iterables diff --git a/src/sage/combinat/skew_partition.py b/src/sage/combinat/skew_partition.py index 484b4ceb7f3..e525c67ee39 100644 --- a/src/sage/combinat/skew_partition.py +++ b/src/sage/combinat/skew_partition.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Skew Partitions @@ -485,11 +484,11 @@ def _unicode_art_(self): out, inn = self inn = inn + [0] * (len(out) - len(inn)) if not any(self._list): - return UnicodeArt(u'∅') + return UnicodeArt('∅') if self.parent().options.convention == "French": - s, t, b, l, r, tr, tl, br, bl, x, h = list(u' ┴┬├┤┘└┐┌┼─') + s, t, b, l, r, tr, tl, br, bl, x, h = list(' ┴┬├┤┘└┐┌┼─') else: - s, t, b, l, r, tr, tl, br, bl, x, h = list(u' ┬┴├┤┐┌┘└┼─') + s, t, b, l, r, tr, tl, br, bl, x, h = list(' ┬┴├┤┐┌┘└┼─') # working with English conventions txt = [s * inn[0] + tl + t * (out[0] - inn[0] - 1) + tr] @@ -500,10 +499,10 @@ def _unicode_art_(self): i1 = inn[i + 1] if i0 == i1: - start = u' ' * i1 + l + start = ' ' * i1 + l d0 = 1 else: - start = u' ' * i1 + tl + start = ' ' * i1 + tl d0 = 0 if o0 == o1: diff --git a/src/sage/combinat/skew_tableau.py b/src/sage/combinat/skew_tableau.py index 4718f29f199..3019522d21e 100644 --- a/src/sage/combinat/skew_tableau.py +++ b/src/sage/combinat/skew_tableau.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Skew Tableaux diff --git a/src/sage/combinat/species/composition_species.py b/src/sage/combinat/species/composition_species.py index b60e5348985..ccfe0141803 100644 --- a/src/sage/combinat/species/composition_species.py +++ b/src/sage/combinat/species/composition_species.py @@ -116,7 +116,7 @@ def __init__(self, F, G, min=None, max=None, weight=None): sage: E = species.SetSpecies(); C = species.CycleSpecies() sage: L = E(C) sage: c = L.generating_series()[:3] - sage: L._check() #False due to isomorphism types not being implemented # needs sage.libs.flint + sage: L._check() #False due to isomorphism types not being implemented # needs sage.libs.flint False sage: L == loads(dumps(L)) True @@ -234,7 +234,7 @@ def _cis(self, series_ring, base_ring): sage: E = species.SetSpecies() sage: C = species.CycleSpecies(weight=t) sage: S = E(C) - sage: S.isotype_generating_series()[:5] #indirect # needs sage.modules + sage: S.isotype_generating_series()[:5] #indirect # needs sage.modules [1, t, t^2 + t, t^3 + t^2 + t, t^4 + t^3 + 2*t^2 + t] We do the same thing with set partitions weighted by the number of diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index d3f1e9d3867..705dbd22494 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -553,7 +553,7 @@ def _series_helper(self, series_ring_class, prefix, base_ring=None): pass # Try to return things like self._gs_callable(base_ring). - # This is used when the subclass just provides an callable + # This is used when the subclass just provides a callable # for the coefficients of the generating series. Optionally, # the subclass can specify the order of the series. try: diff --git a/src/sage/combinat/symmetric_group_algebra.py b/src/sage/combinat/symmetric_group_algebra.py index 7672c8c7649..031940f5283 100644 --- a/src/sage/combinat/symmetric_group_algebra.py +++ b/src/sage/combinat/symmetric_group_algebra.py @@ -19,6 +19,7 @@ from sage.combinat.partition import _Partitions, Partitions_n from sage.combinat.tableau import Tableau, StandardTableaux_size, StandardTableaux_shape, StandardTableaux from sage.algebras.group_algebra import GroupAlgebra_class +from sage.algebras.cellular_basis import CellularBasis from sage.categories.weyl_groups import WeylGroups from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import QQ @@ -688,8 +689,7 @@ def cell_poset(self): Finite poset containing 5 elements """ from sage.combinat.posets.posets import Poset - from sage.combinat.partition import Partitions - return Poset([Partitions(self.n), lambda x, y: y.dominates(x)]) + return Poset([Partitions_n(self.n), lambda x, y: y.dominates(x)]) def cell_module_indices(self, la): r""" @@ -732,40 +732,14 @@ def _from_cellular_index(self, x): sage: [S._from_cellular_index(i) for i in C.basis().keys()] [[1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + [3, 1, 2] + [3, 2, 1], [1, 2, 3] + [2, 1, 3], - [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [3, 1, 2], - [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1], - [1, 2, 3] + [1, 3, 2], + [1, 3, 2] + [3, 1, 2], + [1, 3, 2] + [2, 3, 1], + [1, 2, 3] + [3, 2, 1], [1, 2, 3]] sage: TestSuite(C).run() """ if ~factorial(self.n) not in self.base_ring(): - from sage.combinat.rsk import RSK_inverse - from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet - G = self.basis().keys() - R = self.base_ring() - one = R.one() - # check if the KL polynomials can be computed using ``coxeter3`` - try: - from sage.libs.coxeter3.coxeter_group import CoxeterGroup as Coxeter3Group - except ImportError: - # Falback to using the KL polynomial - from sage.combinat.kazhdan_lusztig import KazhdanLusztigPolynomial - from sage.groups.perm_gps.permgroup_named import SymmetricGroup - q = PolynomialRing(R, 'q').gen() - KLG = SymmetricGroup(self.n) - self._cellular_KL = KazhdanLusztigPolynomial(KLG, q) - polyfunc = self._cellular_KL.P - else: - self._cellular_KL = Coxeter3Group(['A', self.n+1]) - KLG = self._cellular_KL - polyfunc = self._cellular_KL.kazhdan_lusztig_polynomial - - def func(S, T, mult=None): - w = KLG.from_reduced_word(RSK_inverse(T, S, output="permutation").reduced_word()) - bruhat = RecursivelyEnumeratedSet([w], lambda u: u.bruhat_lower_covers(), structure='graded') - return self.element_class(self, {G.from_reduced_word(v.reduced_word()): R(c(q=one)) - for v in bruhat if (c := polyfunc(v, w))}) - + func = self.murphy_basis_element else: func = self.epsilon_ik @@ -2083,6 +2057,150 @@ def epsilon_ik(self, itab, ktab, star=0, mult='l2r'): else: return z.map_support(lambda x: x.inverse()) + def murphy_basis(self): + r""" + Return the :class:`Murphy basis + ` of ``self``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(QQ, 3) + sage: M = SGA.murphy_basis() + sage: M(SGA.an_element()) + -C([1, 1, 1], [[1], [2], [3]], [[1], [2], [3]]) + + C([2, 1], [[1, 2], [3]], [[1, 2], [3]]) + + C([2, 1], [[1, 2], [3]], [[1, 3], [2]]) + + 2*C([2, 1], [[1, 3], [2]], [[1, 2], [3]]) + + 4*C([2, 1], [[1, 3], [2]], [[1, 3], [2]]) + - 3*C([3], [[1, 2, 3]], [[1, 2, 3]]) + """ + return MurphyBasis(self) + + @cached_method(key=lambda s, X, Y: (StandardTableaux()(X), StandardTableaux()(Y))) + def murphy_basis_element(self, S, T): + r""" + Return the Murphy basis element indexed by ``S`` and ``T``. + + .. SEEALSO:: + + :class:`~sage.combinat.symmetric_group_algebra.MurphyBasis` + + EXAMPLES:: + + sage: import itertools + sage: SGA = SymmetricGroupAlgebra(QQ, 3) + sage: for S, T in itertools.product(StandardTableaux([2,1]), repeat=2): + ....: print(S, T, SGA.murphy_basis_element(S, T)) + [[1, 3], [2]] [[1, 3], [2]] [1, 2, 3] + [2, 1, 3] + [[1, 3], [2]] [[1, 2], [3]] [1, 3, 2] + [3, 1, 2] + [[1, 2], [3]] [[1, 3], [2]] [1, 3, 2] + [2, 3, 1] + [[1, 2], [3]] [[1, 2], [3]] [1, 2, 3] + [3, 2, 1] + + TESTS:: + + sage: SGA = SymmetricGroupAlgebra(QQ, 3) + sage: SGA.murphy_basis_element([[1,2,3,4]], [[1,2],[3,4]]) + Traceback (most recent call last): + ... + ValueError: [[1, 2, 3, 4]] is not an element of Standard tableaux of size 3 + sage: SGA.murphy_basis_element([[1,2,3]], [[1,2],[3]]) + Traceback (most recent call last): + ... + ValueError: S and T must have the same shape + """ + std_tab = StandardTableaux(self.n) + S = std_tab(S) + T = std_tab(T) + S = S.conjugate() + T = T.conjugate() + + la = S.shape() + if la != T.shape(): + raise ValueError("S and T must have the same shape") + + G = self.group() + ds = G(list(sum((row for row in S), ()))) + dt = G(list(sum((row for row in T), ()))) + return self.monomial(~ds) * self._row_stabilizer(la) * self.monomial(dt) + + @cached_method + def _row_stabilizer(self, la): + """ + Return the row stabilizer element of a canonical standard tableau + of shape ``la``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(QQ, 3) + sage: for la in Partitions(3): + ....: print(la, SGA._row_stabilizer(la)) + [3] [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + [3, 1, 2] + [3, 2, 1] + [2, 1] [1, 2, 3] + [2, 1, 3] + [1, 1, 1] [1, 2, 3] + """ + G = self.group() + return self.sum_of_monomials(G(list(w.tuple())) for w in la.young_subgroup()) + + def kazhdan_lusztig_cellular_basis(self): + r""" + Return the Kazhdan-Lusztig basis (at `q = 1`) of ``self`` + as a cellular basis. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(QQ, 3) + sage: KL = SGA.kazhdan_lusztig_cellular_basis() + sage: KL(SGA.an_element()) + C([2, 1], [[1, 2], [3]], [[1, 2], [3]]) + + C([2, 1], [[1, 3], [2]], [[1, 2], [3]]) + + 2*C([2, 1], [[1, 3], [2]], [[1, 3], [2]]) + - 3*C([3], [[1, 2, 3]], [[1, 2, 3]]) + """ + return KLCellularBasis(self) + + @cached_method + def kazhdan_lusztig_basis_element(self, w): + r""" + Return the Kazhdan-Lusztig `C'_w` basis element at `q = 1`. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(QQ, 3) + sage: for w in SGA.group(): + ....: print(w, SGA.kazhdan_lusztig_basis_element(w)) + [1, 2, 3] [1, 2, 3] + [1, 3, 2] [1, 2, 3] + [1, 3, 2] + [2, 1, 3] [1, 2, 3] + [2, 1, 3] + [2, 3, 1] [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + [3, 1, 2] [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [3, 1, 2] + [3, 2, 1] [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + [3, 1, 2] + [3, 2, 1] + """ + from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet + G = self.basis().keys() + R = self.base_ring() + one = R.one() + # check if the KL polynomials can be computed using ``coxeter3`` + try: + from sage.libs.coxeter3.coxeter_group import CoxeterGroup as Coxeter3Group + except ImportError: + # Falback to using the KL polynomial + from sage.combinat.kazhdan_lusztig import KazhdanLusztigPolynomial + from sage.groups.perm_gps.permgroup_named import SymmetricGroup + q = PolynomialRing(R, 'q').gen() + self._KLG = SymmetricGroup(self.n) + self._cellular_KL = KazhdanLusztigPolynomial(self._KLG, q) + polyfunc = self._cellular_KL.P + else: + self._cellular_KL = Coxeter3Group(['A', self.n+1]) + self._KLG = self._cellular_KL + polyfunc = self._cellular_KL.kazhdan_lusztig_polynomial + + if w.parent() is not self._KLG: + w = self._KLG.from_reduced_word(w.reduced_word()) + bruhat = RecursivelyEnumeratedSet([w], lambda u: u.bruhat_lower_covers(), structure='graded') + return self.element_class(self, {G.from_reduced_word(v.reduced_word()): R(c(q=one)) + for v in bruhat if (c := polyfunc(v, w))}) + epsilon_ik_cache = {} @@ -2634,6 +2752,179 @@ def seminormal_test(n): raise ValueError("3.1.20 - %s, %s" % (tab, tab2)) return True + +####################### + + +class SGACellularBasis(CellularBasis): + r""" + A cellular basis of the symmetric group algebra. + """ + def __init__(self, SGA): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 3) + sage: M = SGA.murphy_basis() + sage: TestSuite(M).run() + sage: KL = SGA.kazhdan_lusztig_cellular_basis() + sage: TestSuite(KL).run() + """ + CellularBasis.__init__(self, SGA, self._to_sga) + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 4) + sage: SGA.murphy_basis() + Murphy basis of Symmetric group algebra of order 4 over Finite Field of size 3 + sage: SGA.kazhdan_lusztig_cellular_basis() + Kazhdan-Lusztig basis of Symmetric group algebra of order 4 over Finite Field of size 3 + """ + return self._name + " basis of {}".format(self._algebra) + + @cached_method + def one_basis(self): + r""" + Return the index of the basis element for the multiplicative identity. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 4) + sage: M = SGA.murphy_basis() + sage: M.one_basis() + ([4], [[1, 2, 3, 4]], [[1, 2, 3, 4]]) + """ + la = _Partitions([self._algebra.n]) + col = la.standard_tableaux()[0] + return (la, col, col) + + @cached_method + def one(self): + r""" + Return the element `1` in ``self``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 4) + sage: M = SGA.murphy_basis() + sage: M.one() + C([4], [[1, 2, 3, 4]], [[1, 2, 3, 4]]) + """ + return self.monomial(self.one_basis()) + + +class MurphyBasis(SGACellularBasis): + r""" + The Murphy basis of a symmetric group algebra. + + Let `R` be a commutative ring, and let `A = R[S_n]` denote the group + algebra (over `R`) of `S_n`. The *Murphy basis* is the basis of `A` + defined as follows. Let `S, T` be standard tableaux of shape `\lambda`. + Define `T^{\lambda}` as the standard tableau of shape `\lambda` with + the first row filled with `1, \ldots, \lambda_1`, the second row + `\lambda_1+1, \ldots, \lambda_1+\lambda_2`, and so on. Let `d(S)` be + the unique permutation such that `S = T^{\lambda} d(S)` under the natural + action. Then the Murphy basis element indexed by `S` and `T` is + + .. MATH:: + + M_{S'T'} = d(S)^{-1} R_{\lambda} d(T), + + where `S'` denotes the conjugate tableau. + The Murphy basis is a :class:`cellular basis + ` of `A`. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 5) + sage: M = SGA.murphy_basis() + sage: for la in M.simple_module_parameterization(): + ....: CM = M.cell_module(la) + ....: print(la, CM.dimension(), CM.simple_module().dimension()) + [2, 2, 1] 5 4 + [3, 1, 1] 6 6 + [3, 2] 5 1 + [4, 1] 4 4 + [5] 1 1 + + REFERENCES: + + - [DJM1998]_ + - [Mathas2004]_ + """ + _name = "Murphy" + + def _to_sga(self, ind): + r""" + Return the element in the symmetric group algebra indexed by ``ind``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 3) + sage: M = SGA.murphy_basis() + sage: for ind in M.basis().keys(): + ....: print(ind, M._to_sga(ind)) + ([1, 1, 1], [[1], [2], [3]], [[1], [2], [3]]) [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + [3, 1, 2] + [3, 2, 1] + ([2, 1], [[1, 3], [2]], [[1, 3], [2]]) [1, 2, 3] + [2, 1, 3] + ([2, 1], [[1, 3], [2]], [[1, 2], [3]]) [1, 3, 2] + [3, 1, 2] + ([2, 1], [[1, 2], [3]], [[1, 3], [2]]) [1, 3, 2] + [2, 3, 1] + ([2, 1], [[1, 2], [3]], [[1, 2], [3]]) [1, 2, 3] + [3, 2, 1] + ([3], [[1, 2, 3]], [[1, 2, 3]]) [1, 2, 3] + """ + return self._algebra.murphy_basis_element(ind[1], ind[2]) + + +class KLCellularBasis(SGACellularBasis): + """ + The Kazhdan-Lusztig `C'` basis (at `q = 1`) of the symmetric group + algebra realized as a :class:`cellular basis + ` + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 5) + sage: KL = SGA.kazhdan_lusztig_cellular_basis() + sage: for la in KL.simple_module_parameterization(): + ....: CM = KL.cell_module(la) + ....: print(la, CM.dimension(), CM.simple_module().dimension()) + [2, 2, 1] 5 4 + [3, 1, 1] 6 6 + [3, 2] 5 1 + [4, 1] 4 4 + [5] 1 1 + """ + _name = "Kazhdan-Lusztig" + + def _to_sga(self, ind): + r""" + Return the element in the symmetric group algebra indexed by ``ind``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 3) + sage: KL = SGA.kazhdan_lusztig_cellular_basis() + sage: for ind in KL.basis().keys(): + ....: print(ind, KL._to_sga(ind)) + ([1, 1, 1], [[1], [2], [3]], [[1], [2], [3]]) [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + [3, 1, 2] + [3, 2, 1] + ([2, 1], [[1, 3], [2]], [[1, 3], [2]]) [1, 2, 3] + [2, 1, 3] + ([2, 1], [[1, 3], [2]], [[1, 2], [3]]) [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [3, 1, 2] + ([2, 1], [[1, 2], [3]], [[1, 3], [2]]) [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + ([2, 1], [[1, 2], [3]], [[1, 2], [3]]) [1, 2, 3] + [1, 3, 2] + ([3], [[1, 2, 3]], [[1, 2, 3]]) [1, 2, 3] + """ + from sage.combinat.rsk import RSK_inverse + S = ind[1] + T = ind[2] + w = RSK_inverse(T, S, output="permutation") + return self._algebra.kazhdan_lusztig_basis_element(w) + + ####################### diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index f716c7cd117..c4009853da6 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Tableaux diff --git a/src/sage/combinat/tableau_tuple.py b/src/sage/combinat/tableau_tuple.py index 96fc0f0c51c..807823a4af7 100644 --- a/src/sage/combinat/tableau_tuple.py +++ b/src/sage/combinat/tableau_tuple.py @@ -279,7 +279,7 @@ class TableauTuple(CombinatorialElement): The :meth:`level` of a tableau tuple is the length of the tuples. This corresponds to the level of the corresponding highest weight module. - In sage a :class:`TableauTuple` looks an behaves like a real tuple of + In sage a :class:`TableauTuple` looks and behaves like a real tuple of (level 1) :class:`Tableaux`. Many of the operations which are defined on :class:`Tableau` extend to :class:`TableauTuples`. Tableau tuples of level 1 are just ordinary :class:`Tableau`. diff --git a/src/sage/combinat/tiling.py b/src/sage/combinat/tiling.py index a543b50461d..723557eb9ab 100644 --- a/src/sage/combinat/tiling.py +++ b/src/sage/combinat/tiling.py @@ -163,7 +163,7 @@ sage: T = TilingSolver(L, box=(8,8), reflection=True) sage: solution = next(T.solve()) # long time (7s) sage: G = sum([piece.show2d() for piece in solution], Graphics()) # long time (<1s), needs sage.plot - sage: G.show(aspect_ratio=1, axes=False) # long time (2s), needs sage.plot + sage: G.show(aspect_ratio=1, axes=False) # long time (2s), needs sage.plot Compute the number of solutions:: @@ -199,7 +199,7 @@ sage: T = TilingSolver(L, box=(8,8,1)) sage: solution = next(T.solve()) # long time (8s) sage: G = sum([p.show3d(size=0.85) for p in solution], Graphics()) # long time (<1s), needs sage.plot - sage: G.show(aspect_ratio=1, viewer='tachyon') # long time (2s), needs sage.plot + sage: G.show(aspect_ratio=1, viewer='tachyon') # long time (2s), needs sage.plot Let us compute the number of solutions:: diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index a5edc7146ea..6f9fad1c5dd 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Introduction to combinatorics in Sage diff --git a/src/sage/combinat/words/alphabet.py b/src/sage/combinat/words/alphabet.py index 1de8838df00..19ac17054b8 100644 --- a/src/sage/combinat/words/alphabet.py +++ b/src/sage/combinat/words/alphabet.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Alphabet diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index 35fd6e69c55..41613ed61e2 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Finite word diff --git a/src/sage/combinat/words/lyndon_word.py b/src/sage/combinat/words/lyndon_word.py index 4c978680380..209f9099f18 100644 --- a/src/sage/combinat/words/lyndon_word.py +++ b/src/sage/combinat/words/lyndon_word.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Lyndon words """ diff --git a/src/sage/combinat/words/morphic.py b/src/sage/combinat/words/morphic.py index 0db7a8db6fe..c036db8e2ec 100644 --- a/src/sage/combinat/words/morphic.py +++ b/src/sage/combinat/words/morphic.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Morphic words diff --git a/src/sage/combinat/words/morphism.py b/src/sage/combinat/words/morphism.py index 279c238718e..abb99d9f685 100644 --- a/src/sage/combinat/words/morphism.py +++ b/src/sage/combinat/words/morphism.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Word morphisms/substitutions @@ -150,7 +149,7 @@ def get_cycles(f, domain): return cycles -class PeriodicPointIterator(): +class PeriodicPointIterator: r""" (Lazy) constructor of the periodic points of a word morphism. @@ -3158,7 +3157,7 @@ def immortal_letters(self): [] """ if not self.is_self_composable(): - raise TypeError(f'self ({self}) is not an self-composable') + raise TypeError(f'self ({self}) is not a self-composable') forward = {} backward = {letter: set() for letter in self._morph} diff --git a/src/sage/combinat/words/paths.py b/src/sage/combinat/words/paths.py index 5c84a784533..5106615ae9b 100644 --- a/src/sage/combinat/words/paths.py +++ b/src/sage/combinat/words/paths.py @@ -425,7 +425,7 @@ def __init__(self, alphabet, steps): #Construction of the steps from sage.structure.element import Vector - if all((isinstance(x, Vector) for x in steps)): + if all(isinstance(x, Vector) for x in steps): vsteps = steps else: try: diff --git a/src/sage/combinat/words/word.py b/src/sage/combinat/words/word.py index 132195589e9..222501a5dfd 100644 --- a/src/sage/combinat/words/word.py +++ b/src/sage/combinat/words/word.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Word classes @@ -197,11 +196,11 @@ def Word(data=None, alphabet=None, length=None, datatype=None, caching=True, RSK #if a list of a semistandard and a standard tableau or a pair of lists from sage.combinat.tableau import Tableau if isinstance(RSK_data, (tuple, list)) and len(RSK_data) == 2 and \ - all((isinstance(x, Tableau) for x in RSK_data)): + all(isinstance(x, Tableau) for x in RSK_data): from sage.combinat.rsk import RSK_inverse return RSK_inverse(*RSK_data, output='word') elif isinstance(RSK_data, (tuple, list)) and len(RSK_data) == 2 and \ - all((isinstance(x, (list, tuple)) for x in RSK_data)): + all(isinstance(x, (list, tuple)) for x in RSK_data): from sage.combinat.rsk import RSK_inverse P,Q = map(Tableau, RSK_data) return RSK_inverse(P, Q, 'word') diff --git a/src/sage/combinat/words/word_datatypes.pyx b/src/sage/combinat/words/word_datatypes.pyx index daf21a97469..9ab88d799ba 100644 --- a/src/sage/combinat/words/word_datatypes.pyx +++ b/src/sage/combinat/words/word_datatypes.pyx @@ -583,7 +583,7 @@ cdef class WordDatatype_str(WordDatatype): INPUT: - - ``other`` - word represented by an str + - ``other`` - word represented by a str OUTPUT: diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index 58886bd9108..641319f2ee7 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Common words @@ -314,7 +313,7 @@ def __reduce__(self): return self.__class__, (self.__p, self.__q, self.parent().alphabet()) -class WordGenerator(): +class WordGenerator: r""" Constructor of several famous words. diff --git a/src/sage/combinat/words/words.py b/src/sage/combinat/words/words.py index 0149df17598..2e3f82bede1 100644 --- a/src/sage/combinat/words/words.py +++ b/src/sage/combinat/words/words.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Set of words diff --git a/src/sage/databases/oeis.py b/src/sage/databases/oeis.py index 50ad342a2b2..e40ebc7c539 100644 --- a/src/sage/databases/oeis.py +++ b/src/sage/databases/oeis.py @@ -722,7 +722,7 @@ def online_update(self): except AttributeError: pass - def _field(self, key): + def _field(self, key, warn=True): r""" Return the ``key`` field of the entry of ``self``. @@ -741,7 +741,7 @@ def _field(self, key): for line in self.raw_entry().splitlines(): fields[line[1]].append(line[11:]) self._fields = fields - self.is_dead(warn_only=True) + self.is_dead(warn_only=warn) return self._fields[key] def id(self, format='A'): @@ -959,7 +959,7 @@ def author(self): """ return self._field('A')[0] - def keywords(self): + def keywords(self, warn=True): r""" Return the keywords associated to the sequence ``self``. @@ -985,7 +985,7 @@ def keywords(self): sage: s.keywords() ('nonn', 'hard') """ - return tuple(self._field('K')[0].split(',')) + return tuple(self._field('K', warn=warn)[0].split(',')) def natural_object(self): r""" @@ -1108,8 +1108,8 @@ def is_dead(self, warn_only=False): EXAMPLES: - A warn_only test is triggered as soon as some information on the - sequence is queried:: + A warning is triggered if any field of a dead sequence is accessed, + unless :meth:`is_dead` is called before:: sage: s = oeis(17) sage: s # optional -- internet @@ -1138,11 +1138,11 @@ def is_dead(self, warn_only=False): True """ if warn_only: - if 'dead' in self.keywords(): + if 'dead' in self.keywords(warn_only): from warnings import warn warn('This sequence is dead: "{}: {}"'.format(self.id(), self.name()), RuntimeWarning) else: - return 'dead' in self.keywords() + return 'dead' in self.keywords(warn_only) def is_finite(self): r""" @@ -2010,6 +2010,7 @@ def test_compile_sage_code(self): True """ if self.is_dead(): + self.is_dead(warn_only=True) return True filt = self.programs(language='sage') if filt: diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index 4315cd1ba9f..efd28d10abe 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -1806,12 +1806,13 @@ def parallel_dispatch(self): job_client = None try: from gnumake_tokenpool import JobClient, NoJobServer + except ImportError: + pass + else: try: - job_client = JobClient() + job_client = JobClient(use_cysignals=True) except NoJobServer: pass - except ImportError: - pass source_iter = iter(self.controller.sources) diff --git a/src/sage/doctest/sources.py b/src/sage/doctest/sources.py index 8c7b29bf1d4..cae09766f5d 100644 --- a/src/sage/doctest/sources.py +++ b/src/sage/doctest/sources.py @@ -238,7 +238,7 @@ def _process_doc(self, doctests, doc, namespace, start): # Line number refers to the end of the docstring sigon = doctest.Example(sig_on_count_doc_doctest, "0\n", lineno=docstring.count("\n")) sigon.sage_source = sig_on_count_doc_doctest - sigon.optional_tags = frozenset() + sigon.optional_tags = frozenset(self.file_optional_tags) sigon.probed_tags = frozenset() dt.examples.append(sigon) doctests.append(dt) diff --git a/src/sage/dynamics/cellular_automata/solitons.py b/src/sage/dynamics/cellular_automata/solitons.py index 4afb3f104a2..72ec9ed0104 100644 --- a/src/sage/dynamics/cellular_automata/solitons.py +++ b/src/sage/dynamics/cellular_automata/solitons.py @@ -73,7 +73,7 @@ class SolitonCellularAutomata(SageObject): current state: 34......224....2223 - We then apply an standard evolution:: + We then apply a standard evolution:: sage: B.evolve() sage: B diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index 0a1439b7530..962b743b0c8 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -576,7 +576,8 @@ def function_name(fn): Given a function, return a string giving a name for the function. For functions we recognize, we use our standard opcode name for the - function (so operator.add becomes 'add', and sage.all.sin becomes 'sin'). + function (so :func:`operator.add` becomes ``'add'``, and :func:`sage.functions.trig.sin` + becomes ``'sin'``). For functions we don't recognize, we try to come up with a name, but the name will be wrapped in braces; this is a signal that diff --git a/src/sage/ext_data/graphs/graph_plot_js.html b/src/sage/ext_data/graphs/graph_plot_js.html index 75d08f91662..c56ea71e2d0 100644 --- a/src/sage/ext_data/graphs/graph_plot_js.html +++ b/src/sage/ext_data/graphs/graph_plot_js.html @@ -237,7 +237,7 @@ return [cx+d*nx/nn,cy+d*ny/nn] } - // Applies an homothety to the points of the graph respecting the + // Applies a homothety to the points of the graph respecting the // aspect ratio, so that the graph takes the whole javascript // window and is centered function center_and_scale(graph){ diff --git a/src/sage/features/nauty.py b/src/sage/features/nauty.py index ebd2daeb311..4a07264f927 100644 --- a/src/sage/features/nauty.py +++ b/src/sage/features/nauty.py @@ -24,7 +24,7 @@ class NautyExecutable(Executable): EXAMPLES:: sage: from sage.features.nauty import NautyExecutable - sage: NautyExecutable('converseg').is_present() # optional - nauty + sage: NautyExecutable('converseg').is_present() # needs nauty FeatureTestResult('nauty_converseg', True) """ def __init__(self, name): @@ -49,7 +49,7 @@ class Nauty(JoinFeature): EXAMPLES:: sage: from sage.features.nauty import Nauty - sage: Nauty().is_present() # optional - nauty + sage: Nauty().is_present() # needs nauty FeatureTestResult('nauty', True) """ def __init__(self): @@ -62,7 +62,7 @@ def __init__(self): """ JoinFeature.__init__(self, "nauty", [NautyExecutable(name) - for name in ('directg', 'gentourng', 'geng', 'genbg', 'gentreeg', 'converseg')]) + for name in ('directg', 'gentourng', 'geng', 'genbg', 'gentreeg', 'genktreeg')]) def all_features(): diff --git a/src/sage/game_theory/gambit_docs.py b/src/sage/game_theory/gambit_docs.py index fae37766c96..b2d8af991e9 100644 --- a/src/sage/game_theory/gambit_docs.py +++ b/src/sage/game_theory/gambit_docs.py @@ -115,18 +115,19 @@ converted to Python integers (due to the preparser). Here is an example showing the Battle of the Sexes:: - sage: import gambit # optional - gambit - sage: g = gambit.Game.new_table([2,2]) # optional - gambit - sage: g[int(0), int(0)][int(0)] = int(2) # optional - gambit - sage: g[int(0), int(0)][int(1)] = int(1) # optional - gambit - sage: g[int(0), int(1)][int(0)] = int(0) # optional - gambit - sage: g[int(0), int(1)][int(1)] = int(0) # optional - gambit - sage: g[int(1), int(0)][int(0)] = int(0) # optional - gambit - sage: g[int(1), int(0)][int(1)] = int(0) # optional - gambit - sage: g[int(1), int(1)][int(0)] = int(1) # optional - gambit - sage: g[int(1), int(1)][int(1)] = int(2) # optional - gambit - sage: solver = gambit.nash.ExternalLCPSolver() # optional - gambit - sage: solver.solve(g) # optional - gambit + sage: # optional - gambit + sage: import gambit + sage: g = gambit.Game.new_table([2,2]) + sage: g[int(0), int(0)][int(0)] = int(2) + sage: g[int(0), int(0)][int(1)] = int(1) + sage: g[int(0), int(1)][int(0)] = int(0) + sage: g[int(0), int(1)][int(1)] = int(0) + sage: g[int(1), int(0)][int(0)] = int(0) + sage: g[int(1), int(0)][int(1)] = int(0) + sage: g[int(1), int(1)][int(0)] = int(1) + sage: g[int(1), int(1)][int(1)] = int(2) + sage: solver = gambit.nash.ExternalLCPSolver() + sage: solver.solve(g) [, , ] diff --git a/src/sage/game_theory/normal_form_game.py b/src/sage/game_theory/normal_form_game.py index 811e00aec62..275907d7276 100644 --- a/src/sage/game_theory/normal_form_game.py +++ b/src/sage/game_theory/normal_form_game.py @@ -72,7 +72,8 @@ sage: B = matrix([[2, 1], [0, 3]]) sage: battle_of_the_sexes = NormalFormGame([A, B]) sage: battle_of_the_sexes - Normal Form Game with the following utilities: {(0, 0): [3, 2], (0, 1): [1, 1], (1, 0): [0, 0], (1, 1): [2, 3]} + Normal Form Game with the following utilities: {(0, 0): [3, 2], + (0, 1): [1, 1], (1, 0): [0, 0], (1, 1): [2, 3]} To obtain the Nash equilibria we run the ``obtain_nash()`` method. In the first few examples, we will use the 'support enumeration' algorithm. @@ -159,8 +160,10 @@ sage: y = var('y') sage: A = matrix([[1, -1], [-1, 1]]) - sage: p = plot((A * vector([y, 1 - y]))[0], y, 0, 1, color='blue', legend_label='$u_1(r_1, (y, 1-y))$', axes_labels=['$y$', '']) - sage: p += plot((A * vector([y, 1 - y]))[1], y, 0, 1, color='red', legend_label='$u_1(r_2, (y, 1-y))$'); p + sage: p = plot((A * vector([y, 1 - y]))[0], y, 0, 1, color='blue', + ....: legend_label='$u_1(r_1, (y, 1-y))$', axes_labels=['$y$', '']) + sage: p += plot((A * vector([y, 1 - y]))[1], y, 0, 1, color='red', + ....: legend_label='$u_1(r_2, (y, 1-y))$'); p Graphics object consisting of 2 graphics primitives We see that the only point at which player 1 is indifferent amongst @@ -281,7 +284,8 @@ sage: f[1,1][0] = 4 sage: f[1,1][1] = 4 sage: f - Normal Form Game with the following utilities: {(0, 0): [1, 3], (0, 1): [2, 3], (1, 0): [3, 1], (1, 1): [4, 4]} + Normal Form Game with the following utilities: {(0, 0): [1, 3], + (0, 1): [2, 3], (1, 0): [3, 1], (1, 1): [4, 4]} Once this game is constructed we can view the payoff matrices and solve the game:: @@ -401,7 +405,9 @@ sage: threegame.obtain_nash() Traceback (most recent call last): ... - NotImplementedError: Nash equilibrium for games with more than 2 players have not been implemented yet. Please see the gambit website (http://gambit.sourceforge.net/) that has a variety of available algorithms + NotImplementedError: Nash equilibrium for games with more than 2 players + have not been implemented yet. Please see the gambit website + (http://gambit.sourceforge.net/) that has a variety of available algorithms There are however a variety of such algorithms available in gambit, further compatibility between Sage and gambit is actively being developed: @@ -424,18 +430,18 @@ It is also possible to generate a Normal form game from a gambit Game:: - sage: from gambit import Game # optional - gambit - sage: gambitgame= Game.new_table([2, 2]) # optional - gambit - sage: gambitgame[int(0), int(0)][int(0)] = int(8) # optional - gambit - sage: gambitgame[int(0), int(0)][int(1)] = int(8) # optional - gambit - sage: gambitgame[int(0), int(1)][int(0)] = int(2) # optional - gambit - sage: gambitgame[int(0), int(1)][int(1)] = int(10) # optional - gambit - sage: gambitgame[int(1), int(0)][int(0)] = int(10) # optional - gambit - sage: gambitgame[int(1), int(0)][int(1)] = int(2) # optional - gambit - sage: gambitgame[int(1), int(1)][int(0)] = int(5) # optional - gambit - sage: gambitgame[int(1), int(1)][int(1)] = int(5) # optional - gambit - sage: g = NormalFormGame(gambitgame) # optional - gambit - sage: g # optional - gambit + sage: # optional - gambit + sage: from gambit import Game + sage: gambitgame= Game.new_table([2, 2]) + sage: gambitgame[int(0), int(0)][int(0)] = int(8) + sage: gambitgame[int(0), int(0)][int(1)] = int(8) + sage: gambitgame[int(0), int(1)][int(0)] = int(2) + sage: gambitgame[int(0), int(1)][int(1)] = int(10) + sage: gambitgame[int(1), int(0)][int(0)] = int(10) + sage: gambitgame[int(1), int(0)][int(1)] = int(2) + sage: gambitgame[int(1), int(1)][int(0)] = int(5) + sage: gambitgame[int(1), int(1)][int(1)] = int(5) + sage: g = NormalFormGame(gambitgame); g Normal Form Game with the following utilities: {(0, 0): [8.0, 8.0], (0, 1): [2.0, 10.0], (1, 0): [10.0, 2.0], @@ -476,9 +482,9 @@ sage: B = matrix([[min(i,j) + 2 * sign(i-j) for j in range(K, 1, -1)] ....: for i in range(K, 1, -1)]) sage: g = NormalFormGame([A, B]) - sage: g.obtain_nash(algorithm='lrs') # optional - lrslib + sage: g.obtain_nash(algorithm='lrs') # optional - lrslib [[(0, 0, 0, 0, 0, 0, 0, 0, 1), (0, 0, 0, 0, 0, 0, 0, 0, 1)]] - sage: g.obtain_nash(algorithm='LCP') # optional - gambit + sage: g.obtain_nash(algorithm='LCP') # optional - gambit [[(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0)]] @@ -564,9 +570,9 @@ sage: A = matrix([[3,3],[2,5],[0,6]]) sage: B = matrix([[3,3],[2,6],[3,1]]) sage: degenerate_game = NormalFormGame([A,B]) - sage: degenerate_game.obtain_nash(algorithm='lrs') # random, optional - lrslib + sage: degenerate_game.obtain_nash(algorithm='lrs') # random, optional - lrslib [[(0, 1/3, 2/3), (1/3, 2/3)], [(1, 0, 0), (1/2, 3)], [(1, 0, 0), (1, 3)]] - sage: degenerate_game.obtain_nash(algorithm='LCP') # optional - gambit + sage: degenerate_game.obtain_nash(algorithm='LCP') # optional - gambit [[(0.0, 0.3333333333, 0.6666666667), (0.3333333333, 0.6666666667)], [(1.0, -0.0, 0.0), (0.6666666667, 0.3333333333)], [(1.0, 0.0, 0.0), (1.0, 0.0)]] @@ -705,22 +711,25 @@ def __init__(self, generator=None): sage: threegame.obtain_nash() Traceback (most recent call last): ... - NotImplementedError: Nash equilibrium for games with more than 2 players have not been implemented yet. Please see the gambit website (http://gambit.sourceforge.net/) that has a variety of available algorithms + NotImplementedError: Nash equilibrium for games with more than + 2 players have not been implemented yet. Please see the gambit + website (http://gambit.sourceforge.net/) that has a variety of + available algorithms Can initialise a game from a gambit game object:: - sage: from gambit import Game # optional - gambit - sage: gambitgame= Game.new_table([2, 2]) # optional - gambit - sage: gambitgame[int(0), int(0)][int(0)] = int(5) # optional - gambit - sage: gambitgame[int(0), int(0)][int(1)] = int(8) # optional - gambit - sage: gambitgame[int(0), int(1)][int(0)] = int(2) # optional - gambit - sage: gambitgame[int(0), int(1)][int(1)] = int(11) # optional - gambit - sage: gambitgame[int(1), int(0)][int(0)] = int(10) # optional - gambit - sage: gambitgame[int(1), int(0)][int(1)] = int(7) # optional - gambit - sage: gambitgame[int(1), int(1)][int(0)] = int(5) # optional - gambit - sage: gambitgame[int(1), int(1)][int(1)] = int(5) # optional - gambit - sage: g = NormalFormGame(gambitgame) # optional - gambit - sage: g # optional - gambit + sage: # optional - gambit + sage: from gambit import Game + sage: gambitgame= Game.new_table([2, 2]) + sage: gambitgame[int(0), int(0)][int(0)] = int(5) + sage: gambitgame[int(0), int(0)][int(1)] = int(8) + sage: gambitgame[int(0), int(1)][int(0)] = int(2) + sage: gambitgame[int(0), int(1)][int(1)] = int(11) + sage: gambitgame[int(1), int(0)][int(0)] = int(10) + sage: gambitgame[int(1), int(0)][int(1)] = int(7) + sage: gambitgame[int(1), int(1)][int(0)] = int(5) + sage: gambitgame[int(1), int(1)][int(1)] = int(5) + sage: g = NormalFormGame(gambitgame); g Normal Form Game with the following utilities: {(0, 0): [5.0, 8.0], (0, 1): [2.0, 11.0], (1, 0): [10.0, 7.0], @@ -790,10 +799,12 @@ def __delitem__(self, key): sage: B = matrix([[2, 0], [5, 4]]) sage: prisoners_dilemma = NormalFormGame([A, B]) sage: prisoners_dilemma - Normal Form Game with the following utilities: {(0, 0): [2, 2], (0, 1): [5, 0], (1, 0): [0, 5], (1, 1): [4, 4]} + Normal Form Game with the following utilities: {(0, 0): [2, 2], + (0, 1): [5, 0], (1, 0): [0, 5], (1, 1): [4, 4]} sage: del(prisoners_dilemma[(0,1)]) sage: prisoners_dilemma - Normal Form Game with the following utilities: {(0, 0): [2, 2], (1, 0): [0, 5], (1, 1): [4, 4]} + Normal Form Game with the following utilities: {(0, 0): [2, 2], + (1, 0): [0, 5], (1, 1): [4, 4]} """ self.utilities.pop(key, None) @@ -897,7 +908,8 @@ def _repr_(self): sage: p2 = matrix([[3, 3], [1, 4]]) sage: g = NormalFormGame([p1, p2]) sage: g - Normal Form Game with the following utilities: {(0, 0): [1, 3], (0, 1): [2, 3], (1, 0): [3, 1], (1, 1): [4, 4]} + Normal Form Game with the following utilities: {(0, 0): [1, 3], + (0, 1): [2, 3], (1, 0): [3, 1], (1, 1): [4, 4]} """ from pprint import pformat base_str = "Normal Form Game with the following utilities: {}" @@ -967,19 +979,19 @@ def _gambit_game(self, game): TESTS:: - sage: from gambit import Game # optional - gambit - sage: testgame = Game.new_table([2, 2]) # optional - gambit - sage: testgame[int(0), int(0)][int(0)] = int(8) # optional - gambit - sage: testgame[int(0), int(0)][int(1)] = int(8) # optional - gambit - sage: testgame[int(0), int(1)][int(0)] = int(2) # optional - gambit - sage: testgame[int(0), int(1)][int(1)] = int(10) # optional - gambit - sage: testgame[int(1), int(0)][int(0)] = int(10) # optional - gambit - sage: testgame[int(1), int(0)][int(1)] = int(2) # optional - gambit - sage: testgame[int(1), int(1)][int(0)] = int(5) # optional - gambit - sage: testgame[int(1), int(1)][int(1)] = int(5) # optional - gambit - sage: g = NormalFormGame() # optional - gambit - sage: g._gambit_game(testgame) # optional - gambit - sage: g # optional - gambit + sage: # optional - gambit + sage: from gambit import Game + sage: testgame = Game.new_table([2, 2]) + sage: testgame[int(0), int(0)][int(0)] = int(8) + sage: testgame[int(0), int(0)][int(1)] = int(8) + sage: testgame[int(0), int(1)][int(0)] = int(2) + sage: testgame[int(0), int(1)][int(1)] = int(10) + sage: testgame[int(1), int(0)][int(0)] = int(10) + sage: testgame[int(1), int(0)][int(1)] = int(2) + sage: testgame[int(1), int(1)][int(0)] = int(5) + sage: testgame[int(1), int(1)][int(1)] = int(5) + sage: g = NormalFormGame() + sage: g._gambit_game(testgame); g Normal Form Game with the following utilities: {(0, 0): [8.0, 8.0], (0, 1): [2.0, 10.0], (1, 0): [10.0, 2.0], @@ -1008,11 +1020,11 @@ def _gambit_(self, as_integer=False, maximization=True): TESTS:: - sage: from gambit import Game # optional - gambit + sage: # optional - gambit + sage: from gambit import Game sage: A = matrix([[2, 1], [1, 2.5]]) sage: g = NormalFormGame([A]) - sage: gg = g._gambit_() # optional - gambit - sage: gg # optional - gambit + sage: gg = g._gambit_(); gg NFG 1 R "" { "1" "2" } { { "1" "2" } @@ -1028,9 +1040,7 @@ def _gambit_(self, as_integer=False, maximization=True): } 1 2 3 4 - - sage: gg = g._gambit_(as_integer=True) # optional - gambit - sage: gg # optional - gambit + sage: gg = g._gambit_(as_integer=True); gg NFG 1 R "" { "1" "2" } { { "1" "2" } @@ -1049,11 +1059,11 @@ def _gambit_(self, as_integer=False, maximization=True): :: + sage: # optional - gambit sage: A = matrix([[2, 1], [1, 2.5]]) sage: B = matrix([[3, 2], [5.5, 4]]) sage: g = NormalFormGame([A, B]) - sage: gg = g._gambit_() # optional - gambit - sage: gg # optional - gambit + sage: gg = g._gambit_(); gg NFG 1 R "" { "1" "2" } { { "1" "2" } @@ -1069,9 +1079,7 @@ def _gambit_(self, as_integer=False, maximization=True): } 1 2 3 4 - - sage: gg = g._gambit_(as_integer = True) # optional - gambit - sage: gg # optional - gambit + sage: gg = g._gambit_(as_integer = True); gg NFG 1 R "" { "1" "2" } { { "1" "2" } @@ -1090,35 +1098,36 @@ def _gambit_(self, as_integer=False, maximization=True): :: - sage: threegame = NormalFormGame() # optional - gambit - sage: threegame.add_player(2) # optional - gambit - sage: threegame.add_player(2) # optional - gambit - sage: threegame.add_player(2) # optional - gambit - sage: threegame[0, 0, 0][0] = 3 # optional - gambit - sage: threegame[0, 0, 0][1] = 1 # optional - gambit - sage: threegame[0, 0, 0][2] = 4 # optional - gambit - sage: threegame[0, 0, 1][0] = 1 # optional - gambit - sage: threegame[0, 0, 1][1] = 5 # optional - gambit - sage: threegame[0, 0, 1][2] = 9 # optional - gambit - sage: threegame[0, 1, 0][0] = 2 # optional - gambit - sage: threegame[0, 1, 0][1] = 6 # optional - gambit - sage: threegame[0, 1, 0][2] = 5 # optional - gambit - sage: threegame[0, 1, 1][0] = 3 # optional - gambit - sage: threegame[0, 1, 1][1] = 5 # optional - gambit - sage: threegame[0, 1, 1][2] = 8 # optional - gambit - sage: threegame[1, 0, 0][0] = 9 # optional - gambit - sage: threegame[1, 0, 0][1] = 7 # optional - gambit - sage: threegame[1, 0, 0][2] = 9 # optional - gambit - sage: threegame[1, 0, 1][0] = 3 # optional - gambit - sage: threegame[1, 0, 1][1] = 2 # optional - gambit - sage: threegame[1, 0, 1][2] = 3 # optional - gambit - sage: threegame[1, 1, 0][0] = 8 # optional - gambit - sage: threegame[1, 1, 0][1] = 4 # optional - gambit - sage: threegame[1, 1, 0][2] = 6 # optional - gambit - sage: threegame[1, 1, 1][0] = 2 # optional - gambit - sage: threegame[1, 1, 1][1] = 6 # optional - gambit - sage: threegame[1, 1, 1][2] = 4 # optional - gambit - sage: threegame._gambit_(as_integer = True) # optional - gambit + sage: # optional - gambit + sage: threegame = NormalFormGame() + sage: threegame.add_player(2) + sage: threegame.add_player(2) + sage: threegame.add_player(2) + sage: threegame[0, 0, 0][0] = 3 + sage: threegame[0, 0, 0][1] = 1 + sage: threegame[0, 0, 0][2] = 4 + sage: threegame[0, 0, 1][0] = 1 + sage: threegame[0, 0, 1][1] = 5 + sage: threegame[0, 0, 1][2] = 9 + sage: threegame[0, 1, 0][0] = 2 + sage: threegame[0, 1, 0][1] = 6 + sage: threegame[0, 1, 0][2] = 5 + sage: threegame[0, 1, 1][0] = 3 + sage: threegame[0, 1, 1][1] = 5 + sage: threegame[0, 1, 1][2] = 8 + sage: threegame[1, 0, 0][0] = 9 + sage: threegame[1, 0, 0][1] = 7 + sage: threegame[1, 0, 0][2] = 9 + sage: threegame[1, 0, 1][0] = 3 + sage: threegame[1, 0, 1][1] = 2 + sage: threegame[1, 0, 1][2] = 3 + sage: threegame[1, 1, 0][0] = 8 + sage: threegame[1, 1, 0][1] = 4 + sage: threegame[1, 1, 0][2] = 6 + sage: threegame[1, 1, 1][0] = 2 + sage: threegame[1, 1, 1][1] = 6 + sage: threegame[1, 1, 1][2] = 4 + sage: threegame._gambit_(as_integer = True) NFG 1 R "" { "1" "2" "3" } { { "1" "2" } @@ -1274,7 +1283,9 @@ def add_player(self, num_strategies): sage: g.add_player(1) # Adding second player with 1 strategy sage: g.add_player(1) # Adding third player with 1 strategy sage: g - Normal Form Game with the following utilities: {(0, 0, 0): [False, False, False], (1, 0, 0): [False, False, False]} + Normal Form Game with the following utilities: + {(0, 0, 0): [False, False, False], + (1, 0, 0): [False, False, False]} """ self.players.append(_Player(num_strategies)) self._generate_utilities(True) @@ -1350,7 +1361,8 @@ def add_strategy(self, player): sage: t = matrix([[3, 2], [-1, 0]]) sage: example = NormalFormGame([s, t]) sage: example - Normal Form Game with the following utilities: {(0, 0): [1, 3], (0, 1): [0, 2], (1, 0): [-2, -1], (1, 1): [3, 0]} + Normal Form Game with the following utilities: {(0, 0): [1, 3], + (0, 1): [0, 2], (1, 0): [-2, -1], (1, 1): [3, 0]} sage: example.add_strategy(0) sage: example Normal Form Game with the following utilities: {(0, 0): [1, 3], @@ -1475,10 +1487,12 @@ def obtain_nash(self, algorithm=False, maximization=True, solver=None): ....: [3, 4, 1], ....: [4, 1, 20]]) sage: g=NormalFormGame([A, B]) - sage: g.obtain_nash(algorithm='lrs') # optional - lrslib + sage: g.obtain_nash(algorithm='lrs') # optional - lrslib [[(0, 0, 0, 1), (0, 0, 1)]] - sage: g.obtain_nash(algorithm='lrs', maximization=False) # optional - lrslib - [[(2/3, 1/12, 1/4, 0), (6333/8045, 247/8045, 293/1609)], [(3/4, 0, 1/4, 0), (0, 11/307, 296/307)], [(5/6, 1/6, 0, 0), (98/99, 1/99, 0)]] + sage: g.obtain_nash(algorithm='lrs', maximization=False) # optional - lrslib + [[(2/3, 1/12, 1/4, 0), (6333/8045, 247/8045, 293/1609)], + [(3/4, 0, 1/4, 0), (0, 11/307, 296/307)], + [(5/6, 1/6, 0, 0), (98/99, 1/99, 0)]] This particular game has 3 Nash equilibria:: @@ -1490,7 +1504,9 @@ def obtain_nash(self, algorithm=False, maximization=True, solver=None): ....: [3,1]]) sage: g = NormalFormGame([A, B]) sage: g.obtain_nash(algorithm='enumeration') - [[(0, 1/3, 2/3), (1/3, 2/3)], [(4/5, 1/5, 0), (2/3, 1/3)], [(1, 0, 0), (1, 0)]] + [[(0, 1/3, 2/3), (1/3, 2/3)], + [(4/5, 1/5, 0), (2/3, 1/3)], + [(1, 0, 0), (1, 0)]] Here is a slightly larger game:: @@ -1525,9 +1541,9 @@ def obtain_nash(self, algorithm=False, maximization=True, solver=None): sage: fivegame = NormalFormGame([player1, player2]) sage: fivegame.obtain_nash(algorithm='enumeration') [[(1, 0, 0, 0, 0), (0, 1, 0, 0, 0)]] - sage: fivegame.obtain_nash(algorithm='lrs') # optional - lrslib + sage: fivegame.obtain_nash(algorithm='lrs') # optional - lrslib [[(1, 0, 0, 0, 0), (0, 1, 0, 0, 0)]] - sage: fivegame.obtain_nash(algorithm='LCP') # optional - gambit + sage: fivegame.obtain_nash(algorithm='LCP') # optional - gambit [[(1.0, 0.0, 0.0, 0.0, 0.0), (0.0, 1.0, 0.0, 0.0, 0.0)]] Here are some examples of finding Nash equilibria for constant-sum games:: @@ -1536,24 +1552,24 @@ def obtain_nash(self, algorithm=False, maximization=True, solver=None): sage: cg = NormalFormGame([A]) sage: cg.obtain_nash(algorithm='lp') [[(0.5, 0.5), (0.5, 0.5)]] - sage: cg.obtain_nash(algorithm='lp', solver='Coin') # optional - sage_numerical_backends_coin + sage: cg.obtain_nash(algorithm='lp', solver='Coin') # optional - sage_numerical_backends_coin [[(0.5, 0.5), (0.5, 0.5)]] sage: cg.obtain_nash(algorithm='lp', solver='PPL') [[(1/2, 1/2), (1/2, 1/2)]] - sage: cg.obtain_nash(algorithm='lp', solver='gambit') # optional - gambit + sage: cg.obtain_nash(algorithm='lp', solver='gambit') # optional - gambit [[(0.5, 0.5), (0.5, 0.5)]] sage: A = matrix([[2, 1], [1, 3]]) sage: cg = NormalFormGame([A]) sage: ne = cg.obtain_nash(algorithm='lp', solver='glpk') sage: [[[round(el, 6) for el in v] for v in eq] for eq in ne] [[[0.666667, 0.333333], [0.666667, 0.333333]]] - sage: ne = cg.obtain_nash(algorithm='lp', solver='Coin') # optional - sage_numerical_backends_coin - sage: [[[round(el, 6) for el in v] for v in eq] for eq in ne] # optional - sage_numerical_backends_coin + sage: ne = cg.obtain_nash(algorithm='lp', solver='Coin') # optional - sage_numerical_backends_coin + sage: [[[round(el, 6) for el in v] for v in eq] for eq in ne] # optional - sage_numerical_backends_coin [[[0.666667, 0.333333], [0.666667, 0.333333]]] sage: cg.obtain_nash(algorithm='lp', solver='PPL') [[(2/3, 1/3), (2/3, 1/3)]] - sage: ne = cg.obtain_nash(algorithm='lp', solver='gambit') # optional - gambit - sage: [[[round(el, 6) for el in v] for v in eq] for eq in ne] # optional - gambit + sage: ne = cg.obtain_nash(algorithm='lp', solver='gambit') # optional - gambit + sage: [[[round(el, 6) for el in v] for v in eq] for eq in ne] # optional - gambit [[[0.666667, 0.333333], [0.666667, 0.333333]]] sage: A = matrix([[1, 2, 1], [1, 1, 2], [2, 1, 1]]) sage: B = matrix([[2, 1, 2], [2, 2, 1], [1, 2, 2]]) @@ -1561,13 +1577,13 @@ def obtain_nash(self, algorithm=False, maximization=True, solver=None): sage: ne = cg.obtain_nash(algorithm='lp', solver='glpk') sage: [[[round(el, 6) for el in v] for v in eq] for eq in ne] [[[0.333333, 0.333333, 0.333333], [0.333333, 0.333333, 0.333333]]] - sage: ne = cg.obtain_nash(algorithm='lp', solver='Coin') # optional - sage_numerical_backends_coin - sage: [[[round(el, 6) for el in v] for v in eq] for eq in ne] # optional - sage_numerical_backends_coin + sage: ne = cg.obtain_nash(algorithm='lp', solver='Coin') # optional - sage_numerical_backends_coin + sage: [[[round(el, 6) for el in v] for v in eq] for eq in ne] # optional - sage_numerical_backends_coin [[[0.333333, 0.333333, 0.333333], [0.333333, 0.333333, 0.333333]]] sage: cg.obtain_nash(algorithm='lp', solver='PPL') [[(1/3, 1/3, 1/3), (1/3, 1/3, 1/3)]] - sage: ne = cg.obtain_nash(algorithm='lp', solver='gambit') # optional - gambit - sage: [[[round(el, 6) for el in v] for v in eq] for eq in ne] # optional - gambit + sage: ne = cg.obtain_nash(algorithm='lp', solver='gambit') # optional - gambit + sage: [[[round(el, 6) for el in v] for v in eq] for eq in ne] # optional - gambit [[[0.333333, 0.333333, 0.333333], [0.333333, 0.333333, 0.333333]]] sage: A = matrix([[160, 205, 44], ....: [175, 180, 45], @@ -1609,19 +1625,19 @@ def obtain_nash(self, algorithm=False, maximization=True, solver=None): sage: gg = NormalFormGame([A]) sage: gg.obtain_nash(algorithm='enumeration') [[(0, 1), (0, 1)], [(0, 1), (1, 0)], [(1, 0), (0, 1)], [(1, 0), (1, 0)]] - sage: gg.obtain_nash(algorithm='lrs') # optional - lrs + sage: gg.obtain_nash(algorithm='lrs') # optional - lrs [[(0, 1), (0, 1)], [(0, 1), (1, 0)], [(1, 0), (0, 1)], [(1, 0), (1, 0)]] sage: gg.obtain_nash(algorithm='lp', solver='glpk') [[(1.0, 0.0), (1.0, 0.0)]] - sage: gg.obtain_nash(algorithm='LCP') # optional - gambit + sage: gg.obtain_nash(algorithm='LCP') # optional - gambit [[(1.0, 0.0), (1.0, 0.0)]] sage: gg.obtain_nash(algorithm='enumeration', maximization=False) [[(0, 1), (0, 1)], [(0, 1), (1, 0)], [(1, 0), (0, 1)], [(1, 0), (1, 0)]] - sage: gg.obtain_nash(algorithm='lrs', maximization=False) # optional - lrs + sage: gg.obtain_nash(algorithm='lrs', maximization=False) # optional - lrs [[(0, 1), (0, 1)], [(0, 1), (1, 0)], [(1, 0), (0, 1)], [(1, 0), (1, 0)]] sage: gg.obtain_nash(algorithm='lp', solver='glpk', maximization=False) [[(1.0, 0.0), (1.0, 0.0)]] - sage: gg.obtain_nash(algorithm='LCP', maximization=False) # optional - gambit + sage: gg.obtain_nash(algorithm='LCP', maximization=False) # optional - gambit [[(1.0, 0.0), (1.0, 0.0)]] Note that outputs for all algorithms are as lists of lists of @@ -1709,7 +1725,7 @@ def _solve_lrs(self, maximization=True): sage: A = matrix([[1, 2], [3, 4]]) sage: B = matrix([[3, 3], [1, 4]]) sage: C = NormalFormGame([A, B]) - sage: C._solve_lrs() # optional - lrslib + sage: C._solve_lrs() # optional - lrslib [[(0, 1), (0, 1)]] 2 random matrices:: @@ -1725,7 +1741,7 @@ def _solve_lrs(self, maximization=True): ....: [1, 0, 0, 0, 0,], ....: [1, -3, 1, 21, -2]]) sage: biggame = NormalFormGame([p1, p2]) - sage: biggame._solve_lrs() # optional - lrslib + sage: biggame._solve_lrs() # optional - lrslib [[(0, 0, 0, 20/21, 1/21), (11/12, 0, 0, 1/12, 0)]] Another test:: @@ -1737,7 +1753,7 @@ def _solve_lrs(self, maximization=True): ....: [6, -2, -3], ....: [-4, 6, -10]]) sage: biggame = NormalFormGame([p1, p2]) - sage: biggame._solve_lrs() # optional - lrslib + sage: biggame._solve_lrs() # optional - lrslib [[(0, 1, 0), (1, 0, 0)], [(1/3, 2/3, 0), (0, 1/6, 5/6)], [(1/3, 2/3, 0), (1/7, 0, 6/7)], @@ -1774,7 +1790,7 @@ def _solve_LCP(self, maximization): sage: a = matrix([[1, 0], [1, 4]]) sage: b = matrix([[2, 3], [2, 4]]) sage: c = NormalFormGame([a, b]) - sage: c._solve_LCP(maximization=True) # optional - gambit + sage: c._solve_LCP(maximization=True) # optional - gambit [[(0.0, 1.0), (0.0, 1.0)]] """ g = self._gambit_(maximization) @@ -1791,14 +1807,14 @@ def _solve_gambit_LP(self, maximization=True): sage: A = matrix([[2, 1], [1, 2.5]]) sage: g = NormalFormGame([A]) - sage: g._solve_gambit_LP() # optional - gambit + sage: g._solve_gambit_LP() # optional - gambit [[(0.6, 0.4), (0.6, 0.4)]] sage: A = matrix.identity(2) sage: g = NormalFormGame([A]) - sage: g._solve_gambit_LP() # optional - gambit + sage: g._solve_gambit_LP() # optional - gambit [[(0.5, 0.5), (0.5, 0.5)]] sage: g = NormalFormGame([A,A]) - sage: g._solve_gambit_LP() # optional - gambit + sage: g._solve_gambit_LP() # optional - gambit Traceback (most recent call last): ... RuntimeError: Method only valid for constant-sum games. @@ -1830,9 +1846,9 @@ def _solve_LP(self, solver='glpk', maximization=True): sage: g = NormalFormGame([A]) sage: g._solve_LP() [[(0.5, 0.5), (0.5, 0.5)]] - sage: g._solve_LP('gambit') # optional - gambit + sage: g._solve_LP('gambit') # optional - gambit [[(0.5, 0.5), (0.5, 0.5)]] - sage: g._solve_LP('Coin') # optional - sage_numerical_backends_coin + sage: g._solve_LP('Coin') # optional - sage_numerical_backends_coin [[(0.5, 0.5), (0.5, 0.5)]] sage: g._solve_LP('PPL') [[(1/2, 1/2), (1/2, 1/2)]] @@ -1841,11 +1857,11 @@ def _solve_LP(self, solver='glpk', maximization=True): sage: ne = g._solve_LP() sage: [[[round(el, 6) for el in v] for v in eq] for eq in ne] [[[0.666667, 0.333333], [0.666667, 0.333333]]] - sage: ne = g._solve_LP('gambit') # optional - gambit - sage: [[[round(el, 6) for el in v] for v in eq] for eq in ne] # optional - gambit + sage: ne = g._solve_LP('gambit') # optional - gambit + sage: [[[round(el, 6) for el in v] for v in eq] for eq in ne] # optional - gambit [[[0.666667, 0.333333], [0.666667, 0.333333]]] - sage: ne = g._solve_LP('Coin') # optional - sage_numerical_backends_coin - sage: [[[round(el, 6) for el in v] for v in eq] for eq in ne] # optional - sage_numerical_backends_coin + sage: ne = g._solve_LP('Coin') # optional - sage_numerical_backends_coin + sage: [[[round(el, 6) for el in v] for v in eq] for eq in ne] # optional - sage_numerical_backends_coin [[[0.666667, 0.333333], [0.666667, 0.333333]]] sage: g._solve_LP('PPL') [[(2/3, 1/3), (2/3, 1/3)]] @@ -1950,7 +1966,9 @@ def _solve_enumeration(self, maximization=True): ....: [3, 2, 1, 1]]) sage: C = NormalFormGame([A, B]) sage: C._solve_enumeration() - [[(0, 0, 0, 1), (1, 0, 0, 0)], [(2/7, 0, 0, 5/7), (5/11, 0, 6/11, 0)], [(1, 0, 0, 0), (0, 0, 1, 0)]] + [[(0, 0, 0, 1), (1, 0, 0, 0)], + [(2/7, 0, 0, 5/7), (5/11, 0, 6/11, 0)], + [(1, 0, 0, 0), (0, 0, 1, 0)]] Again:: @@ -2485,11 +2503,11 @@ def is_degenerate(self, certificate=False): ....: [-17, 25, -97, -82], ....: [30, 31, -1, 50]]) sage: d_game = NormalFormGame([a, b]) - sage: d_game.obtain_nash(algorithm='lrs') # optional - lrslib + sage: d_game.obtain_nash(algorithm='lrs') # optional - lrslib [[(0, 0, 1, 0), (0, 1, 0, 0)], [(17/29, 0, 0, 12/29), (0, 0, 42/73, 31/73)], [(122/145, 0, 23/145, 0), (0, 1, 0, 0)]] - sage: d_game.obtain_nash(algorithm='LCP') # optional - gambit + sage: d_game.obtain_nash(algorithm='LCP') # optional - gambit [[(0.5862068966, 0.0, 0.0, 0.4137931034), (0.0, 0.0, 0.5753424658, 0.4246575342)]] sage: d_game.obtain_nash(algorithm='enumeration') @@ -2532,7 +2550,8 @@ def is_degenerate(self, certificate=False): sage: g.is_degenerate() Traceback (most recent call last): ... - NotImplementedError: Tests for Degeneracy is not yet implemented for games with more than two players. + NotImplementedError: Tests for Degeneracy is not yet implemented for + games with more than two players. """ if len(self.players) > 2: raise NotImplementedError("Tests for Degeneracy is not yet " @@ -2607,7 +2626,7 @@ def best_responses(self, strategy, player): sage: g.best_responses((3/4, 1/4), player=0) [0] - To get the best responses for Player 2 we pass the argument :code:`player=1` + To get the best responses for Player 2 we pass the argument :code:`player=1`:: sage: g.best_responses((4/5, 1/5, 0), player=1) [0, 1] @@ -2658,7 +2677,7 @@ def best_responses(self, strategy, player): ValueError: Strategy is not of correct dimension If the strategy is not a true probability vector then an error is - passed: + passed:: sage: A = matrix([[3, 0], [0, 3], [1.5, 1.5]]) sage: B = matrix([[4, 3], [2, 6], [3, 1]]) diff --git a/src/sage/game_theory/parser.py b/src/sage/game_theory/parser.py index 0784e4bc184..d528116f244 100644 --- a/src/sage/game_theory/parser.py +++ b/src/sage/game_theory/parser.py @@ -194,18 +194,19 @@ def format_gambit(self, gambit_game): Here we construct a two by two game in gambit:: - sage: import gambit # optional - gambit + sage: # optional - gambit + sage: import gambit sage: from sage.game_theory.parser import Parser - sage: g = gambit.Game.new_table([2,2]) # optional - gambit - sage: g[int(0), int(0)][int(0)] = int(2) # optional - gambit - sage: g[int(0), int(0)][int(1)] = int(1) # optional - gambit - sage: g[int(0), int(1)][int(0)] = int(0) # optional - gambit - sage: g[int(0), int(1)][int(1)] = int(0) # optional - gambit - sage: g[int(1), int(0)][int(0)] = int(0) # optional - gambit - sage: g[int(1), int(0)][int(1)] = int(0) # optional - gambit - sage: g[int(1), int(1)][int(0)] = int(1) # optional - gambit - sage: g[int(1), int(1)][int(1)] = int(2) # optional - gambit - sage: solver = gambit.nash.ExternalLCPSolver() # optional - gambit + sage: g = gambit.Game.new_table([2,2]) + sage: g[int(0), int(0)][int(0)] = int(2) + sage: g[int(0), int(0)][int(1)] = int(1) + sage: g[int(0), int(1)][int(0)] = int(0) + sage: g[int(0), int(1)][int(1)] = int(0) + sage: g[int(1), int(0)][int(0)] = int(0) + sage: g[int(1), int(0)][int(1)] = int(0) + sage: g[int(1), int(1)][int(0)] = int(1) + sage: g[int(1), int(1)][int(1)] = int(2) + sage: solver = gambit.nash.ExternalLCPSolver() Here is the output of the LCP algorithm:: @@ -218,21 +219,24 @@ def format_gambit(self, gambit_game): The Parser class outputs the equilibrium:: sage: nasheq = Parser(LCP_output).format_gambit(g) # optional - gambit - sage: nasheq # optional - gambit - [[(1.0, 0.0), (1.0, 0.0)], [(0.6666666667, 0.3333333333), (0.3333333333, 0.6666666667)], [(0.0, 1.0), (0.0, 1.0)]] + sage: nasheq # optional - gambit + [[(1.0, 0.0), (1.0, 0.0)], + [(0.6666666667, 0.3333333333), (0.3333333333, 0.6666666667)], + [(0.0, 1.0), (0.0, 1.0)]] Here is another game:: - sage: g = gambit.Game.new_table([2,2]) # optional - gambit - sage: g[int(0), int(0)][int(0)] = int(4) # optional - gambit - sage: g[int(0), int(0)][int(1)] = int(8) # optional - gambit - sage: g[int(0), int(1)][int(0)] = int(0) # optional - gambit - sage: g[int(0), int(1)][int(1)] = int(1) # optional - gambit - sage: g[int(1), int(0)][int(0)] = int(1) # optional - gambit - sage: g[int(1), int(0)][int(1)] = int(3) # optional - gambit - sage: g[int(1), int(1)][int(0)] = int(1) # optional - gambit - sage: g[int(1), int(1)][int(1)] = int(0) # optional - gambit - sage: solver = gambit.nash.ExternalLCPSolver() # optional - gambit + sage: # optional - gambit + sage: g = gambit.Game.new_table([2,2]) + sage: g[int(0), int(0)][int(0)] = int(4) + sage: g[int(0), int(0)][int(1)] = int(8) + sage: g[int(0), int(1)][int(0)] = int(0) + sage: g[int(0), int(1)][int(1)] = int(1) + sage: g[int(1), int(0)][int(0)] = int(1) + sage: g[int(1), int(0)][int(1)] = int(3) + sage: g[int(1), int(1)][int(0)] = int(1) + sage: g[int(1), int(1)][int(1)] = int(0) + sage: solver = gambit.nash.ExternalLCPSolver() Here is the LCP output:: @@ -248,26 +252,27 @@ def format_gambit(self, gambit_game): Here is a larger degenerate game:: - sage: g = gambit.Game.new_table([3,3]) # optional - gambit - sage: g[int(0), int(0)][int(0)] = int(-7) # optional - gambit - sage: g[int(0), int(0)][int(1)] = int(-9) # optional - gambit - sage: g[int(0), int(1)][int(0)] = int(-5) # optional - gambit - sage: g[int(0), int(1)][int(1)] = int(7) # optional - gambit - sage: g[int(0), int(2)][int(0)] = int(5) # optional - gambit - sage: g[int(0), int(2)][int(1)] = int(9) # optional - gambit - sage: g[int(1), int(0)][int(0)] = int(5) # optional - gambit - sage: g[int(1), int(0)][int(1)] = int(6) # optional - gambit - sage: g[int(1), int(1)][int(0)] = int(5) # optional - gambit - sage: g[int(1), int(1)][int(1)] = int(-2) # optional - gambit - sage: g[int(1), int(2)][int(0)] = int(3) # optional - gambit - sage: g[int(1), int(2)][int(1)] = int(-3) # optional - gambit - sage: g[int(2), int(0)][int(0)] = int(1) # optional - gambit - sage: g[int(2), int(0)][int(1)] = int(-4) # optional - gambit - sage: g[int(2), int(1)][int(0)] = int(-6) # optional - gambit - sage: g[int(2), int(1)][int(1)] = int(6) # optional - gambit - sage: g[int(2), int(2)][int(0)] = int(1) # optional - gambit - sage: g[int(2), int(2)][int(1)] = int(-10) # optional - gambit - sage: solver = gambit.nash.ExternalLCPSolver() # optional - gambit + sage: # optional - gambit + sage: g = gambit.Game.new_table([3,3]) + sage: g[int(0), int(0)][int(0)] = int(-7) + sage: g[int(0), int(0)][int(1)] = int(-9) + sage: g[int(0), int(1)][int(0)] = int(-5) + sage: g[int(0), int(1)][int(1)] = int(7) + sage: g[int(0), int(2)][int(0)] = int(5) + sage: g[int(0), int(2)][int(1)] = int(9) + sage: g[int(1), int(0)][int(0)] = int(5) + sage: g[int(1), int(0)][int(1)] = int(6) + sage: g[int(1), int(1)][int(0)] = int(5) + sage: g[int(1), int(1)][int(1)] = int(-2) + sage: g[int(1), int(2)][int(0)] = int(3) + sage: g[int(1), int(2)][int(1)] = int(-3) + sage: g[int(2), int(0)][int(0)] = int(1) + sage: g[int(2), int(0)][int(1)] = int(-4) + sage: g[int(2), int(1)][int(0)] = int(-6) + sage: g[int(2), int(1)][int(1)] = int(6) + sage: g[int(2), int(2)][int(0)] = int(1) + sage: g[int(2), int(2)][int(1)] = int(-10) + sage: solver = gambit.nash.ExternalLCPSolver() Here is the LCP output:: diff --git a/src/sage/games/quantumino.py b/src/sage/games/quantumino.py index 9f8da835585..d5646406882 100644 --- a/src/sage/games/quantumino.py +++ b/src/sage/games/quantumino.py @@ -253,7 +253,7 @@ class QuantuminoState(SageObject): r""" A state of the Quantumino puzzle. - Used to represent an solution or a partial solution of the Quantumino + Used to represent a solution or a partial solution of the Quantumino puzzle. INPUT: diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index c2a9252bd72..0cebb40237c 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Convex rational polyhedral cones @@ -554,7 +553,7 @@ def _ambient_space_point(body, data): An integral, rational, real algebraic, or numeric point of the ambient space of ``body`` is returned if ``data`` were - successfully interpreted in such a way. A ``TypeError`` is raised + successfully interpreted in such a way. A :class:`TypeError` is raised otherwise. TESTS:: @@ -1664,7 +1663,7 @@ def _contains(self, point, region='whole cone'): otherwise, in particular when ``point`` is incompatible with the ambient space. - A ``ValueError`` is raised if ``region`` is not one of the + A :class:`ValueError` is raised if ``region`` is not one of the three allowed values. TESTS:: @@ -2340,8 +2339,8 @@ def embed(self, cone): or :meth:`~sage.geometry.cone.ConvexRationalPolyhedralCone.facet_of`. The cone returned by this method will have ``self`` as ambient. If ``cone`` - does not represent a valid cone of ``self``, ``ValueError`` exception - is raised. + does not represent a valid cone of ``self``, :class:`ValueError` + exception is raised. .. NOTE:: @@ -3017,8 +3016,8 @@ def intersection(self, other): - :class:`cone `. - Raises ``ValueError`` if the ambient space dimensions are not - compatible. + This raises :class:`ValueError` if the ambient space dimensions + are not compatible. EXAMPLES:: @@ -5349,7 +5348,7 @@ def random_element(self, ring=ZZ): Either a lattice element or vector contained in both this cone and its ambient vector space. If ``ring`` is ``ZZ``, a lattice element is returned; otherwise a vector is returned. If ``ring`` - is neither ``ZZ`` nor ``QQ``, then a ``NotImplementedError`` is + is neither ``ZZ`` nor ``QQ``, then a :class:`NotImplementedError` is raised. EXAMPLES: @@ -6267,7 +6266,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, A new, randomly generated cone. - A ``ValueError`` will be thrown under the following conditions: + A :class:`ValueError` will be thrown under the following conditions: * Any of ``min_ambient_dim``, ``max_ambient_dim``, ``min_rays``, or ``max_rays`` are negative. @@ -6425,7 +6424,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, provided. If the user requests too many rays in zero, one, or two dimensions, - a ``ValueError`` is thrown:: + a :class:`ValueError` is thrown:: sage: random_cone(max_ambient_dim=0, min_rays=1) Traceback (most recent call last): @@ -6513,7 +6512,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, sage: random_cone(lattice=L, strictly_convex=True) 0-d cone in 0-d lattice L - A ``ValueError`` is thrown if a non-solid cone is requested in a + A :class:`ValueError` is thrown if a non-solid cone is requested in a zero-dimensional lattice:: sage: L = ToricLattice(0) @@ -6527,7 +6526,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, ... ValueError: all cones are solid when max_ambient_dim is zero. - A ``ValueError`` is thrown if a solid cone is requested but the + A :class:`ValueError` is thrown if a solid cone is requested but the maximum number of rays is too few:: sage: random_cone(min_ambient_dim=4, max_rays=3, solid=True) @@ -6542,7 +6541,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, ValueError: max_rays must be at least 5 for a solid cone in this lattice. - A ``ValueError`` is thrown if a non-solid cone is requested but + A :class:`ValueError` is thrown if a non-solid cone is requested but ``min_rays`` guarantees a solid cone:: sage: random_cone(max_ambient_dim=4, min_rays=10, solid=False) diff --git a/src/sage/geometry/fan.py b/src/sage/geometry/fan.py index 3aecc84a55b..4ac1fdb497d 100644 --- a/src/sage/geometry/fan.py +++ b/src/sage/geometry/fan.py @@ -1956,7 +1956,7 @@ def cone_containing(self, *points): We think of the origin as of the smallest cone containing no rays at all. If there is no ray in ``self`` that contains all ``rays``, - a ``ValueError`` exception will be raised. + a :class:`ValueError` exception will be raised. EXAMPLES:: @@ -2352,8 +2352,8 @@ def embed(self, cone): or :meth:`~sage.geometry.cone.ConvexRationalPolyhedralCone.facet_of`. The cone returned by this method will have ``self`` as ambient. If ``cone`` - does not represent a valid cone of ``self``, ``ValueError`` exception - is raised. + does not represent a valid cone of ``self``, :class:`ValueError` + exception is raised. .. NOTE:: @@ -3504,8 +3504,8 @@ def complex(self, base_ring=ZZ, extended=False): OUTPUT: The complex associated to the fan as a :class:`ChainComplex - `. Raises a - ``ValueError`` if the extended complex is requested for a + `. This raises a + :class:`ValueError` if the extended complex is requested for a non-complete fan. EXAMPLES:: diff --git a/src/sage/geometry/fan_morphism.py b/src/sage/geometry/fan_morphism.py index 1d3cd1db886..d00e87083f7 100644 --- a/src/sage/geometry/fan_morphism.py +++ b/src/sage/geometry/fan_morphism.py @@ -520,8 +520,8 @@ def _ray_index_map(self): domain fan is mapped to the origin. If it is `j`, then the `i`-th ray of the domain fan is mapped onto the `j`-th ray of the codomain fan. If there is a ray in the domain fan which is mapped into the relative - interior of a higher dimensional cone, a ``ValueError`` exception is - raised. + interior of a higher dimensional cone, a :class:`ValueError` + exception is raised. .. NOTE:: @@ -601,8 +601,8 @@ def _subdivide_domain_fan(self, check, verbose): OUTPUT: - none, but the domain fan of self is replaced with its minimal - refinement, if possible. Otherwise a ``ValueError`` exception is - raised. + refinement, if possible. Otherwise a :class:`ValueError` + exception is raised. TESTS:: @@ -763,11 +763,11 @@ def _subdivide_domain_fan(self, check, verbose): def _support_error(self): r""" - Raise a ``ValueError`` exception due to support incompatibility. + Raise a :class:`ValueError` exception due to support incompatibility. OUTPUT: - - none, a ``ValueError`` exception is raised. + - none, a :class:`ValueError` exception is raised. TESTS: @@ -806,10 +806,10 @@ def _validate(self): OUTPUT: - - none, but a ``ValueError`` exception is raised if there is a cone of - the domain fan of ``self`` which is not completely contained in a - single cone of the codomain fan of ``self``, or if one of these fans - does not sit in the appropriate lattice. + - none, but a :class:`ValueError` exception is raised if there is + a cone of the domain fan of ``self`` which is not completely + contained in a single cone of the codomain fan of ``self``, + or if one of these fans does not sit in the appropriate lattice. EXAMPLES:: diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_coercion.py b/src/sage/geometry/hyperbolic_space/hyperbolic_coercion.py index fac28dfd161..ff509d0d97f 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_coercion.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_coercion.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Coercion Maps Between Hyperbolic Plane Models @@ -82,7 +81,7 @@ def _call_(self, x): """ C = self.codomain() if not C.is_bounded() and self.domain().is_bounded() and x.is_boundary(): - msg = u"boundary points are not implemented for the {}" + msg = "boundary points are not implemented for the {}" raise NotImplementedError(msg.format(C.name())) y = self.image_coordinates(x.coordinates()) diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py b/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py index 57354fad4d9..f8fb369bb39 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Hyperbolic Geodesics @@ -622,7 +621,7 @@ def is_parallel(self, other): def ideal_endpoints(self): r""" Return the ideal endpoints in bounded models. Raise a - ``NotImplementedError`` in models that are not bounded. + :class:`NotImplementedError` in models that are not bounded. EXAMPLES:: @@ -660,7 +659,7 @@ def ideal_endpoints(self): def complete(self): r""" Return the geodesic with ideal endpoints in bounded models. Raise a - ``NotImplementedError`` in models that are not bounded. + :class:`NotImplementedError` in models that are not bounded. In the following examples we represent complete geodesics by a dashed line. @@ -817,7 +816,7 @@ def common_perpendicula(self, other): r""" Return the unique hyperbolic geodesic perpendicular to two given geodesics, if such a geodesic exists. If none exists, raise a - ``ValueError``. + :class:`ValueError`. INPUT: @@ -1278,7 +1277,7 @@ def common_perpendicular(self, other): r""" Return the unique hyperbolic geodesic perpendicular to ``self`` and ``other``, if such a geodesic exists; otherwise raise a - ``ValueError``. + :class:`ValueError`. INPUT: diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_interface.py b/src/sage/geometry/hyperbolic_space/hyperbolic_interface.py index 38f6f4266af..11f4c08add9 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_interface.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_interface.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Interface to Hyperbolic Models diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_isometry.py b/src/sage/geometry/hyperbolic_space/hyperbolic_isometry.py index 08d68b2c518..0d9e0ec4a08 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_isometry.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_isometry.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Hyperbolic Isometries @@ -489,7 +488,7 @@ def classification(self): def translation_length(self): r""" For hyperbolic elements, return the translation length; - otherwise, raise a ``ValueError``. + otherwise, raise a :class:`ValueError`. EXAMPLES:: @@ -512,7 +511,7 @@ def translation_length(self): def axis(self): r""" For a hyperbolic isometry, return the axis of the - transformation; otherwise raise a ``ValueError``. + transformation; otherwise raise a :class:`ValueError`. EXAMPLES:: @@ -593,7 +592,7 @@ def fixed_geodesic(self): def repelling_fixed_point(self): r""" For a hyperbolic isometry, return the attracting fixed point; - otherwise raise a ``ValueError``. + otherwise raise a :class:`ValueError`. OUTPUT: @@ -612,7 +611,7 @@ def repelling_fixed_point(self): def attracting_fixed_point(self): r""" For a hyperbolic isometry, return the attracting fixed point; - otherwise raise a `ValueError``. + otherwise raise a :class:`ValueError`. OUTPUT: @@ -735,7 +734,7 @@ def classification(self): #UHP def translation_length(self): #UHP r""" For hyperbolic elements, return the translation length; - otherwise, raise a ``ValueError``. + otherwise, raise a :class:`ValueError`. EXAMPLES:: @@ -843,9 +842,11 @@ def fixed_point_set(self): # UHP return self.domain().get_geodesic(*pts) return pts - def repelling_fixed_point(self): #UHP + def repelling_fixed_point(self): # UHP r""" - Return the repelling fixed point; otherwise raise a ``ValueError``. + Return the repelling fixed point. + + Otherwise, this raises a :class:`ValueError`. OUTPUT: @@ -867,9 +868,11 @@ def repelling_fixed_point(self): #UHP return self.domain().get_point(infinity) return self.domain().get_point(v[0] / v[1]) - def attracting_fixed_point(self): #UHP + def attracting_fixed_point(self): # UHP r""" - Return the attracting fixed point; otherwise raise a ``ValueError``. + Return the attracting fixed point. + + Otherwise, this raises a :class:`ValueError`. OUTPUT: diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_model.py b/src/sage/geometry/hyperbolic_space/hyperbolic_model.py index 7890b222f37..33e5f0008fe 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_model.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_model.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Hyperbolic Models @@ -156,7 +155,7 @@ def _repr_(self): # Abstract sage: HyperbolicPlane().UHP() Hyperbolic plane in the Upper Half Plane Model """ - return u'Hyperbolic plane in the {}'.format(self._name) + return 'Hyperbolic plane in the {}'.format(self._name) def _element_constructor_(self, x, is_boundary=None, **graphics_options): # Abstract """ @@ -260,7 +259,7 @@ def point_in_model(self, p): def point_test(self, p): # Abstract r""" Test whether a point is in the model. If the point is in the - model, do nothing. Otherwise, raise a ``ValueError``. + model, do nothing. Otherwise, raise a :class:`ValueError`. EXAMPLES:: @@ -298,7 +297,7 @@ def boundary_point_in_model(self, p): # Abstract def bdry_point_test(self, p): # Abstract r""" Test whether a point is in the model. If the point is in the - model, do nothing; otherwise raise a ``ValueError``. + model, do nothing; otherwise raise a :class:`ValueError`. EXAMPLES:: @@ -340,7 +339,7 @@ def isometry_test(self, A): # Abstract Test whether an isometry ``A`` is in the model. If the isometry is in the model, do nothing. Otherwise, raise - a ``ValueError``. + a :class:`ValueError`. EXAMPLES:: @@ -1173,7 +1172,7 @@ def __init__(self, space): # name should really be 'Poincaré Disk Model', but utf8 is not # accepted by repr HyperbolicModel.__init__(self, space, - name=u'Poincare Disk Model', short_name="PD", + name='Poincare Disk Model', short_name="PD", bounded=True, conformal=True, dimension=2, isometry_group="PU(1, 1)", isometry_group_is_projective=True) diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_point.py b/src/sage/geometry/hyperbolic_space/hyperbolic_point.py index 6ae2e260aac..650c90a4403 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_point.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_point.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Hyperbolic Points diff --git a/src/sage/geometry/hyperplane_arrangement/arrangement.py b/src/sage/geometry/hyperplane_arrangement/arrangement.py index 90e620b71bc..1b429cdf804 100644 --- a/src/sage/geometry/hyperplane_arrangement/arrangement.py +++ b/src/sage/geometry/hyperplane_arrangement/arrangement.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Hyperplane Arrangements @@ -2723,7 +2722,7 @@ def region_containing_point(self, p): OUTPUT: - A polyhedron. A ``ValueError`` is raised if the point is not + A polyhedron. A :class:`ValueError` is raised if the point is not interior to a region, that is, sits on a hyperplane. EXAMPLES:: diff --git a/src/sage/geometry/hyperplane_arrangement/hyperplane.py b/src/sage/geometry/hyperplane_arrangement/hyperplane.py index 8d4b301f8d8..18e39e286a0 100644 --- a/src/sage/geometry/hyperplane_arrangement/hyperplane.py +++ b/src/sage/geometry/hyperplane_arrangement/hyperplane.py @@ -484,7 +484,7 @@ def orthogonal_projection(self, point): A vector in the ambient vector space that lies on the hyperplane. - In finite characteristic, a ``ValueError`` is raised if the + In finite characteristic, a :class:`ValueError` is raised if the the norm of the hyperplane normal is zero. EXAMPLES:: diff --git a/src/sage/geometry/hyperplane_arrangement/library.py b/src/sage/geometry/hyperplane_arrangement/library.py index 4ec9f9fdbdf..cdfaca2faf0 100644 --- a/src/sage/geometry/hyperplane_arrangement/library.py +++ b/src/sage/geometry/hyperplane_arrangement/library.py @@ -65,7 +65,7 @@ def make_parent(base_ring, dimension, names=None): return HyperplaneArrangements(base_ring, names=names) -class HyperplaneArrangementLibrary(): +class HyperplaneArrangementLibrary: """ The library of hyperplane arrangements. """ diff --git a/src/sage/geometry/integral_points.pxi b/src/sage/geometry/integral_points.pxi index 3ea46051b47..8d45f44714c 100644 --- a/src/sage/geometry/integral_points.pxi +++ b/src/sage/geometry/integral_points.pxi @@ -119,7 +119,7 @@ cpdef tuple parallelotope_points(spanning_points, lattice) noexcept: sage: parallelotope_points(c.rays(), c.lattice()) (N(0, 0), N(1, 1)) - A ``ValueError`` is raised if the ``spanning_points`` are not + A :class:`ValueError` is raised if the ``spanning_points`` are not linearly independent:: sage: rays = list(map(ToricLattice(2), [(1,1)]*2)) @@ -853,9 +853,9 @@ cdef class Inequality_int: OUTPUT: - Inequality `A x + b \geq 0`. A ``OverflowError`` is raised if a + Inequality `A x + b \geq 0`. A :class:`OverflowError` is raised if a machine integer is not long enough to hold the results. A - ``ValueError`` is raised if some of the input is not integral. + :class:`ValueError` is raised if some of the input is not integral. EXAMPLES:: diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 136cd370373..449143c8999 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Lattice and reflexive polytopes @@ -5017,8 +5016,8 @@ def part_of_point(self, i): Since a nef-partition induces a partition on the set of boundary lattice points of `\Delta^\circ`, the value of `j` is well-defined for all `i` but the one that corresponds to the origin, in which - case this method will raise a ``ValueError`` exception. (The origin - always belongs to all `\nabla_j`.) + case this method will raise a :class:`ValueError` exception. + (The origin always belongs to all `\nabla_j`.) See :class:`nef-partition ` class documentation for definitions and notation. diff --git a/src/sage/geometry/point_collection.pyx b/src/sage/geometry/point_collection.pyx index 3a67de459ed..aabb0bdcde3 100644 --- a/src/sage/geometry/point_collection.pyx +++ b/src/sage/geometry/point_collection.pyx @@ -756,7 +756,7 @@ cdef class PointCollection(SageObject): OUTPUT: - an integer if ``point`` is in ``self[start:stop]``, otherwise a - ``ValueError`` exception is raised. + :class:`ValueError` exception is raised. EXAMPLES:: diff --git a/src/sage/geometry/polyhedral_complex.py b/src/sage/geometry/polyhedral_complex.py index d6e3b075656..09200a60be9 100644 --- a/src/sage/geometry/polyhedral_complex.py +++ b/src/sage/geometry/polyhedral_complex.py @@ -163,7 +163,7 @@ class PolyhedralComplex(GenericCellComplex): - ``face_to_face_check`` -- boolean (default: ``False``); if ``True``, then the constructor checks whether the cells - are face-to-face, and it raises a ``ValueError`` if they are not + are face-to-face, and it raises a :class:`ValueError` if they are not - ``is_mutable`` and ``is_immutable`` -- boolean (default: ``True`` and ``False`` respectively); set ``is_mutable=False`` or ``is_immutable=True`` @@ -967,7 +967,7 @@ def __contains__(self, x): def __call__(self, x): """ If ``x`` is a polyhedron in this complex, return it. - Otherwise, raise a ``ValueError``. + Otherwise, raise a :class:`ValueError`. EXAMPLES:: @@ -1072,10 +1072,10 @@ def is_compact(self): def graph(self): """ - The 1-skeleton of this polyhedral complex, as a graph. + Return the 1-skeleton of this polyhedral complex, as a graph. - The vertices of the graph are of type ``vector``. Raises - a ``NotImplementedError`` if the polyhedral complex is unbounded. + The vertices of the graph are of type ``vector``. This raises + a :class:`NotImplementedError` if the polyhedral complex is unbounded. .. WARNING:: diff --git a/src/sage/geometry/polyhedron/backend_cdd.py b/src/sage/geometry/polyhedron/backend_cdd.py index f0e7e3ada8b..e35ea92fe67 100644 --- a/src/sage/geometry/polyhedron/backend_cdd.py +++ b/src/sage/geometry/polyhedron/backend_cdd.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" The cdd backend for polyhedral computations """ diff --git a/src/sage/geometry/polyhedron/backend_polymake.py b/src/sage/geometry/polyhedron/backend_polymake.py index 089e687f3f8..a2bce697e1c 100644 --- a/src/sage/geometry/polyhedron/backend_polymake.py +++ b/src/sage/geometry/polyhedron/backend_polymake.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ The polymake backend for polyhedral computations diff --git a/src/sage/geometry/polyhedron/base4.py b/src/sage/geometry/polyhedron/base4.py index 5313d64b357..2ba2a696b30 100644 --- a/src/sage/geometry/polyhedron/base4.py +++ b/src/sage/geometry/polyhedron/base4.py @@ -70,7 +70,7 @@ def vertex_facet_graph(self, labels=True): This function constructs a directed bipartite graph. The nodes of the graph correspond to the vertices of the polyhedron - and the facets of the polyhedron. There is an directed edge + and the facets of the polyhedron. There is a directed edge from a vertex to a face if and only if the vertex is incident to the face. INPUT: @@ -406,7 +406,7 @@ def hasse_diagram(self): sage: D.degree_polynomial() x^5 + x^4*y + x*y^4 + y^5 + 4*x^3*y + 8*x^2*y^2 + 4*x*y^3 - Faces of an mutable polyhedron are not hashable. Hence those are not suitable as + Faces of a mutable polyhedron are not hashable. Hence those are not suitable as vertices of the hasse diagram. Use the combinatorial polyhedron instead:: sage: # needs sage.rings.number_field diff --git a/src/sage/geometry/polyhedron/base7.py b/src/sage/geometry/polyhedron/base7.py index c1c06b90a28..99ca1b7ebe7 100644 --- a/src/sage/geometry/polyhedron/base7.py +++ b/src/sage/geometry/polyhedron/base7.py @@ -133,7 +133,7 @@ def centroid(self, engine='auto', **kwds): else: from sage.geometry.triangulation.point_configuration import PointConfiguration A, b = self.affine_hull_projection(as_affine_map=True, orthogonal=True, orthonormal=True, extend=True) - pc = PointConfiguration((A(v.vector()) for v in self.Vrep_generator())) + pc = PointConfiguration(A(v.vector()) for v in self.Vrep_generator()) barycenters = [sum(self.Vrepresentation(i).vector() for i in simplex)/(self.dim() + 1) for simplex in triangulation] volumes = [pc.volume(simplex) for simplex in triangulation] diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx index 8c23470e0e3..cd7b7316a43 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx @@ -547,7 +547,7 @@ cdef tuple face_as_combinatorial_polyhedron(ListOfFaces facets, ListOfFaces Vrep else: delete = mem.allocarray(max(facets.n_faces(), facets.n_atoms()), sizeof(bint)) - # Set ``delete[i]`` to one if ``i`` is not an vertex of ``face``. + # Set ``delete[i]`` to one if ``i`` is not a vertex of ``face``. for i in range(Vrep.n_faces()): if face_issubset(face, Vrep.data.faces[i]): delete[i] = 0 diff --git a/src/sage/geometry/polyhedron/library.py b/src/sage/geometry/polyhedron/library.py index a1a59cdfe65..d48cffd5c5c 100644 --- a/src/sage/geometry/polyhedron/library.py +++ b/src/sage/geometry/polyhedron/library.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Library of commonly used, famous, or interesting polytopes @@ -489,7 +488,7 @@ def gale_transform_to_primal(vectors, base_ring=None, backend=None): return m.right_kernel_matrix(basis='computed').columns() -class Polytopes(): +class Polytopes: """ A class of constructors for commonly used, famous, or interesting polytopes. @@ -1003,7 +1002,7 @@ def rhombic_dodecahedron(self, backend=None): sage: TestSuite(rd_norm).run() # optional - pynormaliz """ v = [[2,0,0],[-2,0,0],[0,2,0],[0,-2,0],[0,0,2],[0,0,-2]] - v.extend((itertools.product([1, -1], repeat=3))) + v.extend(itertools.product([1, -1], repeat=3)) return Polyhedron(vertices=v, base_ring=ZZ, backend=backend) def cuboctahedron(self, backend=None): @@ -2552,7 +2551,7 @@ def permutahedron(self, n, project=False, backend=None): sage: perm4.graph().is_isomorphic(graphs.BubbleSortGraph(4)) # needs sage.graphs True - As both Hrepresentation an Vrepresentation are known, the permutahedron can be set + As both Hrepresentation and Vrepresentation are known, the permutahedron can be set up with both using the backend ``field``. The following takes very very long time to recompute, e.g. with backend ``ppl``:: diff --git a/src/sage/geometry/polyhedron/plot.py b/src/sage/geometry/polyhedron/plot.py index 5c2362cfdda..78767803eb0 100644 --- a/src/sage/geometry/polyhedron/plot.py +++ b/src/sage/geometry/polyhedron/plot.py @@ -144,7 +144,7 @@ def projection_func_identity(x): return list(x) -class ProjectionFuncStereographic(): +class ProjectionFuncStereographic: """ The stereographic (or perspective) projection onto a codimension-1 linear subspace with respect to a sphere centered at the origin. @@ -238,7 +238,7 @@ def __call__(self, x): return vector(RDF, [img[i] / denom for i in range(self.dim - 1)]) -class ProjectionFuncSchlegel(): +class ProjectionFuncSchlegel: """ The Schlegel projection from the given input point. diff --git a/src/sage/geometry/riemannian_manifolds/surface3d_generators.py b/src/sage/geometry/riemannian_manifolds/surface3d_generators.py index ba8eff2ed2a..a75fdb0f2f2 100644 --- a/src/sage/geometry/riemannian_manifolds/surface3d_generators.py +++ b/src/sage/geometry/riemannian_manifolds/surface3d_generators.py @@ -23,7 +23,7 @@ ParametrizedSurface3D -class SurfaceGenerators(): +class SurfaceGenerators: """ A class consisting of generators for several common parametrized surfaces in 3D. diff --git a/src/sage/geometry/toric_lattice.py b/src/sage/geometry/toric_lattice.py index a72f31f04d2..4a34a6a510e 100644 --- a/src/sage/geometry/toric_lattice.py +++ b/src/sage/geometry/toric_lattice.py @@ -677,7 +677,7 @@ def quotient(self, sub, check=True, by Sublattice Attempting to quotient one lattice by a sublattice of another - will result in a ``ValueError``:: + will result in a :class:`ValueError`:: sage: N = ToricLattice(3) sage: M = ToricLattice(3, name='M') @@ -1467,7 +1467,7 @@ def __init__(self, V, W, check=True, positive_point=None, positive_dual_point=No sage: ToricLattice_quotient(N, N.span([N(1,2,3)])) 2-d lattice, quotient of 3-d lattice N by Sublattice - An ``ArithmeticError`` will be raised if ``W`` is not a + An :class:`ArithmeticError` will be raised if ``W`` is not a sublattice of ``V``:: sage: N = ToricLattice(3) diff --git a/src/sage/geometry/toric_lattice_element.pyx b/src/sage/geometry/toric_lattice_element.pyx index bc736243642..60782a805f4 100644 --- a/src/sage/geometry/toric_lattice_element.pyx +++ b/src/sage/geometry/toric_lattice_element.pyx @@ -300,7 +300,7 @@ cdef class ToricLatticeElement(Vector_integer_dense): # is wrong from our point of view. cpdef _dot_product_(self, Vector right) noexcept: """ - Raise a ``TypeError`` exception. + Raise a :class:`TypeError` exception. Dot product is not defined on toric lattices (there are actions of dual lattices on each other instead). @@ -311,7 +311,7 @@ cdef class ToricLatticeElement(Vector_integer_dense): OUTPUT: - - ``TypeError`` exception is raised. + - :class:`TypeError` exception is raised. TESTS:: diff --git a/src/sage/geometry/toric_plotter.py b/src/sage/geometry/toric_plotter.py index 950e3ba7ff8..2943daa49bd 100644 --- a/src/sage/geometry/toric_plotter.py +++ b/src/sage/geometry/toric_plotter.py @@ -746,7 +746,7 @@ def _unrecognized_option(option): OUTPUT: - - none, a ``KeyError`` exception is raised. + - none, a :class:`KeyError` exception is raised. TESTS:: diff --git a/src/sage/geometry/triangulation/base.pyx b/src/sage/geometry/triangulation/base.pyx index 61014429fdd..3161d19afba 100644 --- a/src/sage/geometry/triangulation/base.pyx +++ b/src/sage/geometry/triangulation/base.pyx @@ -588,7 +588,7 @@ cdef class PointConfiguration_base(Parent): def _assert_is_affine(self): """ - Raise a ``ValueError`` if the point configuration is not + Raise a :class:`ValueError` if the point configuration is not defined by affine points. EXAMPLES:: diff --git a/src/sage/geometry/triangulation/point_configuration.py b/src/sage/geometry/triangulation/point_configuration.py index 68ac3119945..89d486b1e4f 100644 --- a/src/sage/geometry/triangulation/point_configuration.py +++ b/src/sage/geometry/triangulation/point_configuration.py @@ -733,7 +733,7 @@ def _TOPCOM_triangulate(self, verbose=True): OUTPUT: A :class:`~sage.geometry.triangulation.element.Triangulation` - satisfying all restrictions imposed. Raises a ``ValueError`` + satisfying all restrictions imposed. This raises a :class:`ValueError` if no such triangulation exists. EXAMPLES:: @@ -1037,7 +1037,7 @@ def triangulate(self, verbose=False): OUTPUT: A :class:`~sage.geometry.triangulation.element.Triangulation` - satisfying all restrictions imposed. Raises a ``ValueError`` + satisfying all restrictions imposed. This raises a :class:`ValueError` if no such triangulation exists. EXAMPLES:: diff --git a/src/sage/graphs/base/boost_graph.pyx b/src/sage/graphs/base/boost_graph.pyx index 84b048c84c5..5c7aa0b61c8 100644 --- a/src/sage/graphs/base/boost_graph.pyx +++ b/src/sage/graphs/base/boost_graph.pyx @@ -2298,7 +2298,7 @@ cdef double diameter_DiFUB(BoostVecWeightedDiGraphU g_boost, Return the diameter of a weighted directed graph. The ``DiFUB`` (Directed iterative Fringe Upper Bound) algorithm calculates - the exact value of the diameter of an weighted directed graph [CGLM2012]_. + the exact value of the diameter of a weighted directed graph [CGLM2012]_. This algorithm starts from a vertex found through a 2Dsweep call (a directed version of the 2sweep method). The worst case time complexity of the DiFUB @@ -2492,11 +2492,11 @@ cpdef diameter(G, algorithm=None, source=None, - ``algorithm`` -- string (default: ``None``); specifies the algorithm to use among: - - ``'2Dsweep'`` -- Computes lower bound on the diameter of an weighted + - ``'2Dsweep'`` -- Computes lower bound on the diameter of a weighted directed graph using the weighted version of the algorithm proposed in [Broder2000]_. See the code's documentation for more details. - - ``'DiFUB'`` -- Computes the diameter of an weighted directed graph + - ``'DiFUB'`` -- Computes the diameter of a weighted directed graph using the weighted version of the algorithm proposed in [CGLM2012]_. See the code's documentation for more details. diff --git a/src/sage/graphs/connectivity.pyx b/src/sage/graphs/connectivity.pyx index 5c8166bd540..910fcc88df8 100644 --- a/src/sage/graphs/connectivity.pyx +++ b/src/sage/graphs/connectivity.pyx @@ -3969,7 +3969,7 @@ cdef class TriconnectivitySPQR: self.in_adj[eh_index] = e_virt_node # end type-1 search - # if an path starts at edge e, empty the tstack. + # if a path starts at edge e, empty the tstack. if self.starts_path[e_index]: while self.__tstack_not_eos(): self.t_stack_top -= 1 diff --git a/src/sage/graphs/digraph.py b/src/sage/graphs/digraph.py index a5d43d48085..58f902b10cd 100644 --- a/src/sage/graphs/digraph.py +++ b/src/sage/graphs/digraph.py @@ -1194,7 +1194,7 @@ def neighbor_in_iterator(self, vertex): """ Return an iterator over the in-neighbors of ``vertex``. - An vertex `u` is an in-neighbor of a vertex `v` if `uv` in an edge. + A vertex `u` is an in-neighbor of a vertex `v` if `uv` in an edge. EXAMPLES:: @@ -1671,7 +1671,7 @@ def feedback_edge_set(self, constraint_generation=True, value_only=False, p = MixedIntegerLinearProgram(constraint_generation=True, maximization=False, solver=solver) - # An variable for each edge + # A variable for each edge b = p.new_variable(binary=True) # Variables are binary, and their coefficient in the objective is diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index ca365540ffb..e6677c26803 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -8358,7 +8358,7 @@ def hamiltonian_path(self, s=None, t=None, use_edge_labels=False, EXAMPLES: - The `3 \times 3`-grid has an Hamiltonian path, an hamiltonian path + The `3 \times 3`-grid has a Hamiltonian path, a hamiltonian path starting from vertex `(0, 0)` and ending at vertex `(2, 2)`, but no Hamiltonian path starting from `(0, 0)` and ending at `(0, 1)`:: @@ -8530,7 +8530,7 @@ def hamiltonian_path(self, s=None, t=None, use_edge_labels=False, g.add_edge(v, new_s, 0) # - # We now search for an Hamiltonian Cycle in g + # We now search for a Hamiltonian Cycle in g # from sage.categories.sets_cat import EmptySetError try: @@ -14064,7 +14064,7 @@ def subgraph_search_count(self, G, induced=False): .. SEEALSO:: - - :meth:`~GenericGraph.subgraph_search` -- finds an subgraph + - :meth:`~GenericGraph.subgraph_search` -- finds a subgraph isomorphic to `H` inside of a graph `G` - :meth:`~GenericGraph.subgraph_search_iterator` -- iterator over @@ -14173,7 +14173,7 @@ def subgraph_search_iterator(self, G, induced=False, return_graphs=True): .. SEEALSO:: - - :meth:`~GenericGraph.subgraph_search` -- finds an subgraph + - :meth:`~GenericGraph.subgraph_search` -- finds a subgraph isomorphic to `H` inside of `G` - :meth:`~GenericGraph.subgraph_search_count` -- counts the number @@ -21633,7 +21633,7 @@ def graphviz_string(self, **options): - a HSV sequence in a string such as ``".52,.386,.22"`` - - an hexadecimal code such as ``"#DA3305"`` + - a hexadecimal code such as ``"#DA3305"`` - a 3-tuple of floating point (to be interpreted as RGB tuple). In this case the 3-tuple is converted in hexadecimal code. diff --git a/src/sage/graphs/generic_graph_pyx.pyx b/src/sage/graphs/generic_graph_pyx.pyx index d27b3b65047..653a36d43f3 100644 --- a/src/sage/graphs/generic_graph_pyx.pyx +++ b/src/sage/graphs/generic_graph_pyx.pyx @@ -501,7 +501,7 @@ def length_and_string_from_graph6(s): INPUT: - - ``s`` -- a graph6 string describing an binary vector (and encoding its + - ``s`` -- a graph6 string describing a binary vector (and encoding its length). EXAMPLES:: @@ -1349,7 +1349,7 @@ cpdef tuple find_hamiltonian(G, long max_iter=100000, long reset_bound=30000, find_path = (find_path > 0) if G.is_clique(induced=False): - # We have an hamiltonian path since n >= 2, but we have an hamiltonian + # We have a hamiltonian path since n >= 2, but we have a hamiltonian # cycle only if n >= 3 return find_path or n >= 3, list(G) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index adc3c39f43e..0308fbca960 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -884,7 +884,7 @@ class Graph(GenericGraph): sage: Graph(igraph.Graph(directed=True)) # optional - python_igraph Traceback (most recent call last): ... - ValueError: An *undirected* igraph graph was expected. To build an directed graph, call the DiGraph constructor. + ValueError: An *undirected* igraph graph was expected. To build a directed graph, call the DiGraph constructor. sage: # needs sage.modules sage: m = matrix([[0, -1], [-1, 0]]) @@ -1205,7 +1205,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None, elif format == 'igraph': if data.is_directed(): raise ValueError("An *undirected* igraph graph was expected. " - "To build an directed graph, call the DiGraph " + "To build a directed graph, call the DiGraph " "constructor.") self.add_vertices(range(data.vcount())) @@ -7984,7 +7984,7 @@ def modular_decomposition(self, algorithm=None, style='tuple'): vertex of `C` has a neighbor outside of it. * An anticomponent `C` (or the union of some --but not all-- of them) of - an non-anticonnected graph `G`, for the same reason (it is just the + a non-anticonnected graph `G`, for the same reason (it is just the complement of the previous graph !). These modules being of special interest, the disjoint union of graphs is diff --git a/src/sage/graphs/graph_generators.py b/src/sage/graphs/graph_generators.py index 3ba5dc6e91f..58a52a309f2 100644 --- a/src/sage/graphs/graph_generators.py +++ b/src/sage/graphs/graph_generators.py @@ -1192,6 +1192,121 @@ def nauty_genbg(self, options="", debug=False): G = BipartiteGraph(s[:-1], format='graph6', partition=partition) yield G + def nauty_genktreeg(self, options="", debug=False): + r""" + Return a generator which creates all `k`-trees using nauty.. + + A `k`-tree is an undirected graph formed by starting with a complete + graph on `k + 1` vertices and then repeatedly add vertices in such a + way that each added vertex `v` has exactly `k` neighbors `U` such that, + together, the `k + 1` vertices formed by `v` and `U` form a clique. + See the :wikipedia:`K-tree` for more details. + + INPUT: + + - ``options`` -- string (default: ``""``); a string passed to + ``genktreeg`` as if it was run at a system command line. At a minimum, + you *must* pass the number of vertices you desire. Sage expects the + graphs to be in nauty's "graph6" format, do not set an option to + change this default or results will be unpredictable. + + - ``debug`` -- boolean (default: ``False``); if ``True`` the first line + of ``genktreeg``'s output to standard error is captured and the first + call to the generator's ``next()`` function will return this line as a + string. A line leading with ">A" indicates a successful initiation of + the program with some information on the arguments, while a line + beginning with ">E" indicates an error with the input. + + The possible options, obtained as output of ``genktreeg --help``:: + + n : the number of vertices + -k : the value of `k`(default: 2) + res/mod : only generate subset res out of subsets 0..mod-1 + -l : canonically label output graphs + + Options which cause ``genktreeg`` to use an output format different than + the graph6 format are not listed above (-u, -s, -h) as they will confuse + the creation of a Sage graph. The res/mod option can be useful when + using the output in a routine run several times in parallel. + + OUTPUT: + + A generator which will produce the graphs as Sage graphs. + These will be simple graphs: no loops, no multiple edges, no + directed edges. + + EXAMPLES: + + A `k`-tree is a maximal graph with treewidth `k`:: + + sage: # needs nauty + sage: gen = graphs.nauty_genktreeg("10 -k4") + sage: G = next(gen); G + Graph on 10 vertices + sage: G.treewidth() + 4 + + A list of all 2-trees with 6, 7 and 8 vertices. This agrees with + :oeis:`A054581`:: + + sage: # needs nauty + sage: gen = graphs.nauty_genktreeg("6") + sage: len(list(gen)) + 5 + sage: gen = graphs.nauty_genktreeg("7") + sage: len(list(gen)) + 12 + sage: gen = graphs.nauty_genktreeg("8") + sage: len(list(gen)) + 39 + + The ``debug`` switch can be used to examine ``geng``'s reaction to the + input in the ``options`` string. We illustrate success. (A failure + will be a string beginning with ">E".) Passing the "-q" switch to + ``geng`` will suppress the indicator of a successful initiation, and so + the first returned value might be an empty string if ``debug`` is + ``True``:: + + sage: gen = graphs.nauty_genktreeg("7", debug=True) # needs nauty + sage: print(next(gen)) # needs nauty + >A ...genktreeg k=2 n=7 + + TESTS: + + Wrong input:: + + sage: # needs nauty + sage: list(graphs.nauty_genktreeg("4 -k5", debug=True)) + ['>E genktreeg: n cannot be less than k\n'] + sage: list(graphs.nauty_genktreeg("10 -k 4", debug=True)) + ['>E genktreeg -k: missing argument value\n'] + sage: list(graphs.nauty_genktreeg("-c3", debug=False)) + Traceback (most recent call last): + ... + ValueError: wrong format of parameter option + """ + import shlex + from sage.features.nauty import NautyExecutable + geng_path = NautyExecutable("genktreeg").absolute_filename() + sp = subprocess.Popen(shlex.quote(geng_path) + " {0}".format(options), shell=True, + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, close_fds=True, + encoding='latin-1') + msg = sp.stderr.readline() + if debug: + yield msg + elif msg.startswith('>E'): + raise ValueError('wrong format of parameter option') + gen = sp.stdout + while True: + try: + s = next(gen) + except StopIteration: + # Exhausted list of graphs from nauty geng + return + G = graph.Graph(s[:-1], format='graph6') + yield G + def cospectral_graphs(self, vertices, matrix_function=None, graphs=None): r""" Find all sets of graphs on ``vertices`` vertices (with diff --git a/src/sage/graphs/partial_cube.py b/src/sage/graphs/partial_cube.py index 147f1acb097..79b1edc957c 100644 --- a/src/sage/graphs/partial_cube.py +++ b/src/sage/graphs/partial_cube.py @@ -363,7 +363,7 @@ def is_partial_cube(G, certificate=False): # Make a digraph with edges labeled by the equivalence classes in unionfind g = DiGraph({v: {w: unionfind.find((v, w)) for w in G[v]} for v in G}) - # Associates to a vertex the token that acts on it, an check that + # Associates to a vertex the token that acts on it, and check that # no two edges on a single vertex have the same label action = {} for v in g: diff --git a/src/sage/graphs/strongly_regular_db.pyx b/src/sage/graphs/strongly_regular_db.pyx index 4095448b606..632016b0703 100644 --- a/src/sage/graphs/strongly_regular_db.pyx +++ b/src/sage/graphs/strongly_regular_db.pyx @@ -2829,7 +2829,7 @@ def strongly_regular_graph(int v, int k, int l, int mu=-1, bint existence=False, ... ValueError: There exists no (5, 5, 5, 5)-strongly regular graph - An set of parameters proved in a paper to be infeasible:: + A set of parameters proved in a paper to be infeasible:: sage: graphs.strongly_regular_graph(324,57,0,12,existence=True) # needs sage.combinat sage.modules False diff --git a/src/sage/groups/generic.py b/src/sage/groups/generic.py index 5e7f23af8d4..9ef099fa93e 100644 --- a/src/sage/groups/generic.py +++ b/src/sage/groups/generic.py @@ -117,10 +117,12 @@ from copy import copy +from sage.arith.misc import integer_ceil, integer_floor, xlcm +from sage.arith.srange import xsrange +from sage.misc.functional import log from sage.misc.misc_c import prod import sage.rings.integer_ring as integer_ring import sage.rings.integer -from sage.arith.srange import xsrange # # Lists of names (as strings) which the user may use to identify one @@ -1396,8 +1398,7 @@ def order_from_bounds(P, bounds, d=None, operation='+', if d > 1: Q = multiple(P, d, operation=operation) lb, ub = bounds - bounds = (sage.arith.all.integer_ceil(lb / d), - sage.arith.all.integer_floor(ub / d)) + bounds = (integer_ceil(lb / d), integer_floor(ub / d)) # Use generic bsgs to find n=d*m with lb<=n<=ub and n*P=0 @@ -1486,7 +1487,7 @@ def merge_points(P1, P2, operation='+', if n2.divides(n1): return (g1, n1) - m, k1, k2 = sage.arith.all.xlcm(n1, n2) + m, k1, k2 = xlcm(n1, n2) m1 = n1 // k1 m2 = n2 // k2 g1 = multiple(g1, m1, operation=operation) diff --git a/src/sage/interfaces/kenzo.py b/src/sage/interfaces/kenzo.py index 793b8f257f7..d6866117d57 100644 --- a/src/sage/interfaces/kenzo.py +++ b/src/sage/interfaces/kenzo.py @@ -430,7 +430,7 @@ def homology(self, n): OUTPUT: - - An homology group. + - A homology group. EXAMPLES:: diff --git a/src/sage/interfaces/macaulay2.py b/src/sage/interfaces/macaulay2.py index 9b11f02a85f..fde9556858d 100644 --- a/src/sage/interfaces/macaulay2.py +++ b/src/sage/interfaces/macaulay2.py @@ -239,7 +239,7 @@ def __init__(self, maxread=None, script_subdirectory=None, def __reduce__(self): """ - Used in serializing an Macaulay2 interface. + Used in serializing a Macaulay2 interface. EXAMPLES:: diff --git a/src/sage/interfaces/matlab.py b/src/sage/interfaces/matlab.py index 74354b77412..8ecfc3447cd 100644 --- a/src/sage/interfaces/matlab.py +++ b/src/sage/interfaces/matlab.py @@ -300,11 +300,11 @@ def chdir(self, directory): def sage2matlab_matrix_string(self, A): """ - Return an matlab matrix from a Sage matrix. + Return a matlab matrix from a Sage matrix. INPUT: A Sage matrix with entries in the rationals or reals. - OUTPUT: A string that evaluates to an Matlab matrix. + OUTPUT: A string that evaluates to a Matlab matrix. EXAMPLES:: diff --git a/src/sage/interfaces/scilab.py b/src/sage/interfaces/scilab.py index a5cb2c1abb9..a275306dbea 100644 --- a/src/sage/interfaces/scilab.py +++ b/src/sage/interfaces/scilab.py @@ -409,7 +409,7 @@ def sage2scilab_matrix_string(self, A): A Sage matrix with entries in the rationals or reals. OUTPUT: - A string that evaluates to an Scilab matrix. + A string that evaluates to a Scilab matrix. EXAMPLES:: diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index f110091f20b..eb3d51a883d 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -610,10 +610,17 @@ def __ne__(self, other): """ return not self.__eq__(other) - def braid(self): + def braid(self, remove_loops=False): r""" Return a braid representation of ``self``. + INPUT: + + - ``remove_loops`` -- boolean (default: ``False``). If set to ``True`` + loops will be removed first. This can reduce the number of strands + needed for an ambient isotopic braid closure. However, this can lead + to a loss of the regular isotopy. + OUTPUT: an element in the braid group .. WARNING:: @@ -634,6 +641,14 @@ def braid(self): sage: L.braid() (s0*s1^-1)^2*s1^-1 + using ``remove_loops=True``:: + + sage: L = Link([[2, 7, 1, 1], [7, 3, 9, 2], [4, 11, 3, 9], [11, 5, 5, 4]]) + sage: L.braid() + s0*s1^-1*s2*s3^-1 + sage: L.braid(remove_loops=True) + 1 + TESTS:: sage: L = Link([]) @@ -648,7 +663,20 @@ def braid(self): sage: A = Link([[[1, 2, -2, -1, -3, -4, 4, 3]], [1, 1, 1, 1]]) sage: A.braid() s0*s1*s2*s3 + + Check that :issue:`36884` is solved:: + + sage: L = Link([[1, 7, 2, 6], [3, 1, 4, 8], [5, 5, 6, 4], [7, 3, 8, 2]]) + sage: L.braid() + s0^3*s1*s0*s1^-1 + sage: L.braid(remove_loops=True) + s^3 """ + if remove_loops: + L = self.remove_loops() + if L != self: + return L.braid(remove_loops=remove_loops) + if self._braid is not None: return self._braid @@ -657,8 +685,8 @@ def braid(self): if len(comp) > 1: L1 = Link(comp[0]) L2 = Link(flatten(comp[1:], max_level=1)) - b1 = L1.braid() - b2 = L2.braid() + b1 = L1.braid(remove_loops=remove_loops) + b2 = L2.braid(remove_loops=remove_loops) n1 = b1.parent().strands() n2 = b2.parent().strands() t1 = list(b1.Tietze()) @@ -667,13 +695,26 @@ def braid(self): self._braid = B(t1 + t2) return self._braid - # look for possible Vogel moves, perform them and call recursively to the modified link pd_code = self.pd_code() if not pd_code: B = BraidGroup(2) self._braid = B.one() return self._braid + # look for possible Vogel moves, perform them and call recursively to the modified link + def idx(cross, edge): + r""" + Return the index of an edge in a crossing taking loops into account. + A loop appears as an edge which occurs twice in the crossing. + In all cases the second occurrence is the correct one needed in + the Vogel algorithm (see :issue:`36884`). + """ + i = cross.index(edge) + if cross.count(edge) > 1: + return cross.index(edge, i+1) + else: + return i + seifert_circles = self.seifert_circles() newedge = max(flatten(pd_code)) + 1 for region in self.regions(): @@ -702,12 +743,12 @@ def braid(self): # C1 C2 existing crossings # ------------------------------------------------- C1 = newPD[newPD.index(heads[a])] - C1[C1.index(a)] = newedge + 1 + C1[idx(C1, a)] = newedge + 1 C2 = newPD[newPD.index(tails[b])] - C2[C2.index(b)] = newedge + 2 + C2[idx(C2, b)] = newedge + 2 newPD.append([newedge + 3, newedge, b, a]) # D newPD.append([newedge + 2, newedge, newedge + 3, newedge + 1]) # E - self._braid = Link(newPD).braid() + self._braid = Link(newPD).braid(remove_loops=remove_loops) return self._braid else: # ------------------------------------------------- @@ -723,12 +764,12 @@ def braid(self): # / \ # ------------------------------------------------- C1 = newPD[newPD.index(heads[-a])] - C1[C1.index(-a)] = newedge + 1 + C1[idx(C1, -a)] = newedge + 1 C2 = newPD[newPD.index(tails[-b])] - C2[C2.index(-b)] = newedge + 2 + C2[idx(C2, -b)] = newedge + 2 newPD.append([newedge + 2, newedge + 1, newedge + 3, newedge]) # D newPD.append([newedge + 3, -a, -b, newedge]) # E - self._braid = Link(newPD).braid() + self._braid = Link(newPD).braid(remove_loops=remove_loops) return self._braid # We are in the case where no Vogel moves are necessary. @@ -2362,6 +2403,50 @@ def regions(self): regions.append(region) return regions + def remove_loops(self): + r""" + Return an ambient isotopic link in which all loops are removed. + + EXAMPLES:: + + sage: b = BraidGroup(4)((3, 2, -1, -1)) + sage: L = Link(b) + sage: L.remove_loops() + Link with 2 components represented by 2 crossings + sage: K4 = Link([[1, 7, 2, 6], [3, 1, 4, 8], [5, 5, 6, 4], [7, 3, 8, 2]]) + sage: K3 = K4.remove_loops() + sage: K3.pd_code() + [[1, 7, 2, 4], [3, 1, 4, 8], [7, 3, 8, 2]] + sage: U = Link([[1, 2, 2, 1]]) + sage: U.remove_loops() + Link with 1 component represented by 0 crossings + """ + pd = self.pd_code() + new_pd = [] + loop_crossings = [] + for cr in pd: + if len(set(cr)) == 4: + new_pd.append(list(cr)) + else: + loop_crossings.append(cr) + if not loop_crossings: + return self + if not new_pd: + # trivial knot + return type(self)([]) + new_edges = flatten(new_pd) + for cr in loop_crossings: + rem = set([e for e in cr if e in new_edges]) + if len(rem) == 2: + # put remaining edges together + a, b = sorted(rem) + for ncr in new_pd: + if b in ncr: + ncr[ncr.index(b)] = a + break + res = type(self)(new_pd) + return res.remove_loops() + @cached_method def mirror_image(self): r""" diff --git a/src/sage/libs/coxeter3/coxeter.pyx b/src/sage/libs/coxeter3/coxeter.pyx index 83cd1dccaee..0ef308c7aee 100644 --- a/src/sage/libs/coxeter3/coxeter.pyx +++ b/src/sage/libs/coxeter3/coxeter.pyx @@ -1,6 +1,7 @@ # distutils: language = c++ # distutils: libraries = coxeter3 # sage_setup: distribution = sagemath-coxeter3 +# sage.doctest: optional - coxeter3 """ Low level part of the interface to Fokko Ducloux's Coxeter 3 library @@ -35,10 +36,10 @@ cdef class String: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import String # optional - coxeter3 - sage: s = String("hello"); s # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import String + sage: s = String("hello"); s hello - sage: del s # optional - coxeter3 + sage: del s """ self.x = c_String(str_to_bytes(s)) @@ -46,9 +47,9 @@ cdef class String: """ EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import String # optional - coxeter3 - sage: s = String('Hi') # optional - coxeter3 - sage: s # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import String + sage: s = String('Hi') + sage: s Hi """ return bytes_to_str(self.x.ptr()) @@ -62,9 +63,9 @@ cdef class String: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import String # optional - coxeter3 - sage: s = String('hello') # optional - coxeter3 - sage: hash(s) == hash('hello') # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import String + sage: s = String('hello') + sage: hash(s) == hash('hello') True """ return hash(repr(self)) @@ -73,17 +74,17 @@ cdef class String: """ EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import String # optional - coxeter3 - sage: ta1 = String('A') # optional - coxeter3 - sage: ta2 = String('A') # optional - coxeter3 - sage: tb = String('b') # optional - coxeter3 - sage: ta1 == ta2 # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import String + sage: ta1 = String('A') + sage: ta2 = String('A') + sage: tb = String('b') + sage: ta1 == ta2 True - sage: tb != ta1 # optional - coxeter3 + sage: tb != ta1 True - sage: all([ta1 < tb, ta1 <= tb, ta1 <= ta1]) # optional - coxeter3 + sage: all([ta1 < tb, ta1 <= tb, ta1 <= ta1]) True - sage: all([tb > ta1, tb >= ta1, tb >= tb]) # optional - coxeter3 + sage: all([tb > ta1, tb >= ta1, tb >= tb]) True """ if type(other) is not type(self): @@ -113,9 +114,9 @@ cdef class String: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import String # optional - coxeter3 - sage: s = String('Hi') # optional - coxeter3 - sage: len(s) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import String + sage: s = String('Hi') + sage: len(s) 2 """ return self.x.length() @@ -124,9 +125,9 @@ cdef class String: """ EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import String # optional - coxeter3 - sage: s = String('Hi') # optional - coxeter3 - sage: TestSuite(s).run() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import String + sage: s = String('Hi') + sage: TestSuite(s).run() """ return (String, (repr(self),) ) @@ -138,10 +139,10 @@ cdef class Type: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import Type # optional - coxeter3 - sage: t = Type('A'); t # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import Type + sage: t = Type('A'); t A - sage: del t # optional - coxeter3 + sage: del t """ self.x = c_Type(str_to_bytes(s)) @@ -149,8 +150,8 @@ cdef class Type: """ EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import Type # optional - coxeter3 - sage: t = Type('A'); t # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import Type + sage: t = Type('A'); t A """ return bytes_to_str(self.x.name().ptr()) @@ -159,9 +160,9 @@ cdef class Type: """ EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import Type # optional - coxeter3 - sage: t = Type('A') # optional - coxeter3 - sage: t.name() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import Type + sage: t = Type('A') + sage: t.name() A """ return String(bytes_to_str(self.x.name().ptr())) @@ -175,12 +176,12 @@ cdef class Type: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import Type # optional - coxeter3 - sage: a = Type('A') # optional - coxeter3 - sage: b = Type('B') # optional - coxeter3 - sage: hash(a) == hash(b) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import Type + sage: a = Type('A') + sage: b = Type('B') + sage: hash(a) == hash(b) False - sage: d = {a: 1, b: 2} # optional - coxeter3 + sage: d = {a: 1, b: 2} """ return hash(('Type', self.name())) @@ -188,17 +189,17 @@ cdef class Type: """ EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import Type # optional - coxeter3 - sage: ta1 = Type('A') # optional - coxeter3 - sage: ta2 = Type('A') # optional - coxeter3 - sage: tb = Type('b') # optional - coxeter3 - sage: ta1 == ta2 # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import Type + sage: ta1 = Type('A') + sage: ta2 = Type('A') + sage: tb = Type('b') + sage: ta1 == ta2 True - sage: tb != ta1 # optional - coxeter3 + sage: tb != ta1 True - sage: all([ta1 < tb, ta1 <= tb, ta1 <= ta1]) # optional - coxeter3 + sage: all([ta1 < tb, ta1 <= tb, ta1 <= ta1]) True - sage: all([tb > ta1, tb >= ta1, tb >= tb]) # optional - coxeter3 + sage: all([tb > ta1, tb >= ta1, tb >= tb]) True """ if type(other) is not type(self): @@ -226,25 +227,26 @@ cdef class Type: """ EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import Type # optional - coxeter3 - sage: t = Type('A') # optional - coxeter3 - sage: TestSuite(t).run() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import Type + sage: t = Type('A') + sage: TestSuite(t).run() """ return (Type, (repr(self), )) + cdef class CoxGroup(SageObject): def __cinit__(self, cartan_type): """ EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 5]); W # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]); W Coxeter group of type A and rank 5 Coxeter 3 segfault's on the trivial Coxeter group; so we catch this and raise a not implemented error:: - sage: W = CoxGroup(['A', 0]); W # optional - coxeter3 + sage: W = CoxGroup(['A', 0]); W Traceback (most recent call last): ... NotImplementedError: Coxeter group of type ['A',0] using Coxeter 3 not yet implemented @@ -252,8 +254,8 @@ cdef class CoxGroup(SageObject): Successfully initializes from a relabeled Cartan type:: sage: ctype = CartanType(['B', 3]).relabel({1: 3, 2: 2, 3: 1}) - sage: W = CoxGroup(ctype) # optional - coxeter3 - sage: CoxeterMatrix(W.coxeter_matrix(), ctype.index_set()) == CoxeterMatrix(ctype) # optional - coxeter3 + sage: W = CoxGroup(ctype) + sage: CoxeterMatrix(W.coxeter_matrix(), ctype.index_set()) == CoxeterMatrix(ctype) True """ from sage.combinat.root_system.cartan_type import CartanType @@ -303,9 +305,9 @@ cdef class CoxGroup(SageObject): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: W._ordering_from_cartan_type(CartanType(['A',5])) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]) + sage: W._ordering_from_cartan_type(CartanType(['A',5])) [1, 2, 3, 4, 5] """ from sage.arith.srange import srange @@ -340,9 +342,9 @@ cdef class CoxGroup(SageObject): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: A4 = CoxGroup(['A', 4]) # optional - coxeter3 - sage: d = {A4: True} # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: A4 = CoxGroup(['A', 4]) + sage: d = {A4: True} """ return hash((self.__class__.__name__, self.type(), self.rank())) @@ -350,21 +352,21 @@ cdef class CoxGroup(SageObject): """ EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: A4 = CoxGroup(['A', 4]) # optional - coxeter3 - sage: A5 = CoxGroup(['A', 5]) # optional - coxeter3 - sage: B4 = CoxGroup(['B', 4]) # optional - coxeter3 - sage: A4 == A4 # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: A4 = CoxGroup(['A', 4]) + sage: A5 = CoxGroup(['A', 5]) + sage: B4 = CoxGroup(['B', 4]) + sage: A4 == A4 True - sage: A4 != B4 # optional - coxeter3 + sage: A4 != B4 True - sage: A4 < B4 # optional - coxeter3 + sage: A4 < B4 True - sage: A5 > A4 # optional - coxeter3 + sage: A5 > A4 True - sage: A4 >= A4 # optional - coxeter3 + sage: A4 >= A4 True - sage: B4 >= A5 # optional - coxeter3 + sage: B4 >= A5 True """ if type(other) is not type(self): @@ -394,9 +396,9 @@ cdef class CoxGroup(SageObject): """ EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: TestSuite((W)).run() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]) + sage: TestSuite((W)).run() """ return (CoxGroup, (self.cartan_type,)) @@ -406,9 +408,9 @@ cdef class CoxGroup(SageObject): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: del W # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]) + sage: del W """ del self.x @@ -418,8 +420,8 @@ cdef class CoxGroup(SageObject): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 5]); W # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]); W Coxeter group of type A and rank 5 """ return "Coxeter group of type %s and rank %s"%(self.type(), self.rank()) @@ -428,9 +430,9 @@ cdef class CoxGroup(SageObject): """ EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 2]) # optional - coxeter3 - sage: list(iter(W)) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 2]) + sage: list(iter(W)) [[], [1], [2], [1, 2], [2, 1], [1, 2, 1]] """ return CoxGroupIterator(self) @@ -441,9 +443,9 @@ cdef class CoxGroup(SageObject): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 2]) # optional - coxeter3 - sage: W.bruhat_interval([], [1,2]) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 2]) + sage: W.bruhat_interval([], [1,2]) [[], [1], [2], [1, 2]] """ cdef CoxGroupElement ww = CoxGroupElement(self, w) @@ -469,9 +471,9 @@ cdef class CoxGroup(SageObject): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: W.orderings() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]) + sage: W.orderings() ({1: 1, 2: 2, 3: 3, 4: 4, 5: 5}, {1: 1, 2: 2, 3: 3, 4: 4, 5: 5}) """ return self.in_ordering, self.out_ordering @@ -484,9 +486,9 @@ cdef class CoxGroup(SageObject): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: W.type() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]) + sage: W.type() A """ return Type(bytes_to_str(self.x.type().name().ptr())) @@ -497,9 +499,9 @@ cdef class CoxGroup(SageObject): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: W.rank() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]) + sage: W.rank() 5 """ return self.x.rank() @@ -510,12 +512,12 @@ cdef class CoxGroup(SageObject): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: W.order() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]) + sage: W.order() 720 - sage: W = CoxGroup(['A', 3, 1]) # optional - coxeter3 - sage: W.order() # optional - coxeter3 + sage: W = CoxGroup(['A', 3, 1]) + sage: W.order() +Infinity """ if self.is_finite(): @@ -530,12 +532,12 @@ cdef class CoxGroup(SageObject): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: W.is_finite() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]) + sage: W.is_finite() True - sage: W = CoxGroup(['A', 3, 1]) # optional - coxeter3 - sage: W.is_finite() # optional - coxeter3 + sage: W = CoxGroup(['A', 3, 1]) + sage: W.is_finite() False """ return isFiniteType(self.x) @@ -548,11 +550,11 @@ cdef class CoxGroup(SageObject): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 2]) # optional - coxeter3 - sage: W.full_context() # optional - coxeter3 - sage: W = CoxGroup(['A', 2,1]) # optional - coxeter3 - sage: W.full_context() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 2]) + sage: W.full_context() + sage: W = CoxGroup(['A', 2,1]) + sage: W.full_context() Traceback (most recent call last): ... TypeError: group needs to be finite @@ -563,20 +565,19 @@ cdef class CoxGroup(SageObject): if not fcoxgroup.isFullContext(): fcoxgroup.fullContext() - def long_element(self): """ Return the longest word in a finite Coxeter group. EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: W.long_element() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]) + sage: W.long_element() [1, 2, 1, 3, 2, 1, 4, 3, 2, 1, 5, 4, 3, 2, 1] - sage: W = CoxGroup(['A', 3, 1]) # optional - coxeter3 - sage: W.long_element() # optional - coxeter3 + sage: W = CoxGroup(['A', 3, 1]) + sage: W.long_element() Traceback (most recent call last): ... TypeError: group needs to be finite @@ -601,10 +602,10 @@ cdef class CoxGroup(SageObject): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: w = [1,1,3,5,4,5,4] # optional - coxeter3 - sage: W.__call__(w) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]) + sage: w = [1,1,3,5,4,5,4] + sage: W.__call__(w) [3, 4, 5] """ return CoxGroupElement(self, w).reduced() @@ -615,9 +616,9 @@ cdef class CoxGroup(SageObject): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: W.coxeter_matrix() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]) + sage: W.coxeter_matrix() [1 3 2 2 2] [3 1 3 2 2] [2 3 1 3 2] @@ -649,11 +650,11 @@ cdef class CoxGroup(SageObject): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup# optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: W.coxeter_graph() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]) + sage: W.coxeter_graph() Graph on 5 vertices - sage: W.coxeter_graph().edges(sort=True) # optional - coxeter3 + sage: W.coxeter_graph().edges(sort=True) [(1, 2, None), (2, 3, None), (3, 4, None), (4, 5, None)] """ from sage.graphs.graph import Graph @@ -669,26 +670,25 @@ cdef class CoxGroup(SageObject): return g - cdef class CoxGroupElement: def __init__(self, CoxGroup group, w, normal_form=True): """ TESTS:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupElement # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: w = CoxGroupElement(W, [2,1,2,1,1], normal_form=False); w # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupElement + sage: W = CoxGroup(['A', 5]) + sage: w = CoxGroupElement(W, [2,1,2,1,1], normal_form=False); w [2, 1, 2, 1, 1] - sage: w = CoxGroupElement(W, [1,1,4,5,4], normal_form=False); w # optional - coxeter3 + sage: w = CoxGroupElement(W, [1,1,4,5,4], normal_form=False); w [1, 1, 4, 5, 4] - sage: w = CoxGroupElement(W, [1,1,4,5,4]); w # optional - coxeter3 + sage: w = CoxGroupElement(W, [1,1,4,5,4]); w [4, 5, 4] - sage: W = CoxGroup(['A', 4]) # optional - coxeter3 - sage: CoxGroupElement(W, [1,2,3,2,3]) # optional - coxeter3 + sage: W = CoxGroup(['A', 4]) + sage: CoxGroupElement(W, [1,2,3,2,3]) [1, 3, 2] - sage: W = CoxGroup(['A', 4]) # optional - coxeter3 - sage: w = CoxGroupElement(W, [1,2,3,2,3]) # optional - coxeter3 - sage: del w # optional - coxeter3 + sage: W = CoxGroup(['A', 4]) + sage: w = CoxGroupElement(W, [1,2,3,2,3]) + sage: del w """ self.group = (group).x self._parent_group = group @@ -705,10 +705,10 @@ cdef class CoxGroupElement: TESTS:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupElement # optional - coxeter3 - sage: W = CoxGroup(['A', 4]) # optional - coxeter3 - sage: w = CoxGroupElement(W, [1,2,3,2,3]) # optional - coxeter3 - sage: w._coxnumber() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupElement + sage: W = CoxGroup(['A', 4]) + sage: w = CoxGroupElement(W, [1,2,3,2,3]) + sage: w._coxnumber() 7 """ return int(self.group.extendContext(self.word)) @@ -717,10 +717,10 @@ cdef class CoxGroupElement: """ EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A',5]) # optional - coxeter3 - sage: w = W([1,2,3]) # optional - coxeter3 - sage: TestSuite(w).run() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A',5]) + sage: w = W([1,2,3]) + sage: TestSuite(w).run() """ return (CoxGroupElement, (self._parent_group, list(self))) @@ -730,11 +730,10 @@ cdef class CoxGroupElement: EXAMPLES:: - - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A',5]) # optional - coxeter3 - sage: w = W([1,2,3]) # optional - coxeter3 - sage: ~w # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A',5]) + sage: w = W([1,2,3]) + sage: ~w [3, 2, 1] """ return CoxGroupElement(self._parent_group, reversed(self)) @@ -747,10 +746,10 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A',5]) # optional - coxeter3 - sage: w = W([1,2,3]) # optional - coxeter3 - sage: w.parent_group() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A',5]) + sage: w = W([1,2,3]) + sage: w.parent_group() Coxeter group of type A and rank 5 """ @@ -762,20 +761,20 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A',5]) # optional - coxeter3 - sage: w = W([1,2,3]) # optional - coxeter3 - sage: w[0] # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A',5]) + sage: w = W([1,2,3]) + sage: w[0] 1 - sage: w[2] # optional - coxeter3 + sage: w[2] 3 - sage: w[:-2] # optional - coxeter3 + sage: w[:-2] [1] - sage: w[-2:] # optional - coxeter3 + sage: w[-2:] [2, 3] - sage: w[3:0:-1] # optional - coxeter3 + sage: w[3:0:-1] [3, 2] - sage: w[4] # optional - coxeter3 + sage: w[4] Traceback (most recent call last): ... IndexError: The index (4) is out of range. @@ -796,9 +795,9 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A',5]) # optional - coxeter3 - sage: w = W([1,2,3]); w # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A',5]) + sage: w = W([1,2,3]); w [1, 2, 3] """ @@ -813,11 +812,11 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: w = W([1,2,3]) # optional - coxeter3 - sage: v = W([2,3,4]) # optional - coxeter3 - sage: hash(w) == hash(v) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A', 5]) + sage: w = W([1,2,3]) + sage: v = W([2,3,4]) + sage: hash(w) == hash(v) False """ return hash((self.__class__.__name__, self.parent_group(), tuple(self))) @@ -826,23 +825,23 @@ cdef class CoxGroupElement: """ EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: V = CoxGroup(['A', 6]) # optional - coxeter3 - sage: w1 = W([1,2,3]) # optional - coxeter3 - sage: w2 = W([2,3,4]) # optional - coxeter3 - sage: v1 = V([1,2,3]) # optional - coxeter3 - sage: w1 == w1 # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A', 5]) + sage: V = CoxGroup(['A', 6]) + sage: w1 = W([1,2,3]) + sage: w2 = W([2,3,4]) + sage: v1 = V([1,2,3]) + sage: w1 == w1 True - sage: w1 != w2 # optional - coxeter3 + sage: w1 != w2 True - sage: all([w1 < w2, w1 <= w2, w1 <= w1]) # optional - coxeter3 + sage: all([w1 < w2, w1 <= w2, w1 <= w1]) True - sage: all([w2 > w1, w2 >= w1, w2 >= w2]) # optional - coxeter3 + sage: all([w2 > w1, w2 >= w1, w2 >= w2]) True - sage: w1 == v1 # optional - coxeter3 + sage: w1 == v1 False - sage: w1 != v1 # optional - coxeter3 + sage: w1 != v1 True """ if type(other) is not type(self): @@ -874,10 +873,10 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A',5]) # optional - coxeter3 - sage: w = W([1,2,3]) # optional - coxeter3 - sage: [a for a in w] # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A',5]) + sage: w = W([1,2,3]) + sage: [a for a in w] [1, 2, 3] """ return (self[i] for i in range(len(self))) @@ -888,10 +887,10 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A',5]) # optional - coxeter3 - sage: w = W([1,2,3]) # optional - coxeter3 - sage: len(w) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A',5]) + sage: w = W([1,2,3]) + sage: len(w) 3 """ return self.word.length() @@ -902,10 +901,10 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A',5]) # optional - coxeter3 - sage: w = W([1,2,1]) # optional - coxeter3 - sage: w.left_descents() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A',5]) + sage: w = W([1,2,1]) + sage: w.left_descents() [1, 2] """ return LFlags_to_list(self._parent_group, self.group.ldescent(self.word)) @@ -916,10 +915,10 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A',5]) # optional - coxeter3 - sage: w = W([1,2,1]) # optional - coxeter3 - sage: w.right_descents() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A',5]) + sage: w = W([1,2,1]) + sage: w.right_descents() [1, 2] """ return LFlags_to_list(self._parent_group, self.group.rdescent(self.word)) @@ -930,15 +929,15 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A',5]) # optional - coxeter3 - sage: w = W([1,2,3,4,5,4]) # optional - coxeter3 - sage: v = W([1,2,4,5,4]) # optional - coxeter3 - sage: v.bruhat_le(w) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A',5]) + sage: w = W([1,2,3,4,5,4]) + sage: v = W([1,2,4,5,4]) + sage: v.bruhat_le(w) True - sage: w.bruhat_le(w) # optional - coxeter3 + sage: w.bruhat_le(w) True - sage: w.bruhat_le(v) # optional - coxeter3 + sage: w.bruhat_le(v) False """ cdef CoxGroupElement ww = CoxGroupElement(self._parent_group, w) @@ -950,10 +949,10 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A',2]) # optional - coxeter3 - sage: x = W([1,2,1]) # optional - coxeter3 - sage: x.is_two_sided_descent(1) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A',2]) + sage: x = W([1,2,1]) + sage: x.is_two_sided_descent(1) True """ cdef Generator ss = self._parent_group.in_ordering[s] @@ -973,11 +972,11 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A',2]) # optional - coxeter3 - sage: W([1,2,1]).coatoms() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A',2]) + sage: W([1,2,1]).coatoms() [[2, 1], [1, 2]] - sage: W([]).coatoms() # optional - coxeter3 + sage: W([]).coatoms() [] """ cdef c_List_CoxWord list = c_List_CoxWord(0) @@ -1002,11 +1001,11 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupElement # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: w = CoxGroupElement(W, [2,1,2], normal_form=False); w # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupElement + sage: W = CoxGroup(['A', 5]) + sage: w = CoxGroupElement(W, [2,1,2], normal_form=False); w [2, 1, 2] - sage: w.normal_form() # optional - coxeter3 + sage: w.normal_form() [1, 2, 1] """ @@ -1020,11 +1019,11 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupElement # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: w = CoxGroupElement(W, [2,1,2,1,1], normal_form=False); w # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupElement + sage: W = CoxGroup(['A', 5]) + sage: w = CoxGroupElement(W, [2,1,2,1,1], normal_form=False); w [2, 1, 2, 1, 1] - sage: w.reduced() # optional - coxeter3 + sage: w.reduced() [1, 2, 1] """ cdef CoxGroupElement res = self._new() @@ -1035,11 +1034,11 @@ cdef class CoxGroupElement: """ EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: W([1]) * W([1]) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]) + sage: W([1]) * W([1]) [] - sage: W([1,2]) * W([1]) # optional - coxeter3 + sage: W([1,2]) * W([1]) [1, 2, 1] """ cdef CoxGroupElement res = self._new() @@ -1053,11 +1052,11 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 5]) # optional - coxeter3 - sage: W([]).poincare_polynomial() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 5]) + sage: W([]).poincare_polynomial() 1 - sage: W([1,2,1]).poincare_polynomial() # optional - coxeter3 + sage: W([1,2,1]).poincare_polynomial() t^3 + 2*t^2 + 2*t + 1 """ cdef CoxGroup W = self.parent_group() @@ -1072,7 +1071,6 @@ cdef class CoxGroupElement: coefficients[result[j].length()] += 1 return ZZ['t'](coefficients) - def kazhdan_lusztig_polynomial(self, v): """ Return the Kazhdan-Lusztig polynomial `P_{u,v}` where `u` is ``self``. @@ -1082,11 +1080,11 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup # optional - coxeter3 - sage: W = CoxGroup(['A', 2]) # optional - coxeter3 - sage: W([]).kazhdan_lusztig_polynomial([1,2,1]) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup + sage: W = CoxGroup(['A', 2]) + sage: W([]).kazhdan_lusztig_polynomial([1,2,1]) 1 - sage: W([1,2,1]).kazhdan_lusztig_polynomial([]) # optional - coxeter3 + sage: W([1,2,1]).kazhdan_lusztig_polynomial([]) 0 """ cdef CoxGroupElement vv @@ -1114,15 +1112,15 @@ cdef class CoxGroupElement: EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A',5]) # optional - coxeter3 - sage: w = W([1,2,3,4,5,4]) # optional - coxeter3 - sage: v = W([1,2,4,5,4]) # optional - coxeter3 - sage: w.mu_coefficient(v) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A',5]) + sage: w = W([1,2,3,4,5,4]) + sage: v = W([1,2,4,5,4]) + sage: w.mu_coefficient(v) 0 - sage: w.mu_coefficient(w) # optional - coxeter3 + sage: w.mu_coefficient(w) 0 - sage: v.mu_coefficient(w) # optional - coxeter3 + sage: v.mu_coefficient(w) 1 """ cdef CoxGroupElement vv = CoxGroupElement(self._parent_group, v) @@ -1130,16 +1128,17 @@ cdef class CoxGroupElement: cdef CoxNbr y = self.group.extendContext(vv.word) return ZZ(self.group.mu(x,y)) + cdef LFlags_to_list(CoxGroup parent, LFlags f) noexcept: """ Return the right descent set of this element. EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import * # optional - coxeter3 - sage: W = CoxGroup(['A',5]) # optional - coxeter3 - sage: w = W([1,2,1]) # optional - coxeter3 - sage: w.right_descents() # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import * + sage: W = CoxGroup(['A',5]) + sage: w = W([1,2,1]) + sage: w.right_descents() [1, 2] """ cdef Generator s @@ -1151,6 +1150,7 @@ cdef LFlags_to_list(CoxGroup parent, LFlags f) noexcept: f1 = f1 & (f1-1) return l + class CoxGroupIterator(): def __init__(self, group): """ @@ -1164,10 +1164,10 @@ class CoxGroupIterator(): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupIterator # optional - coxeter3 - sage: W = CoxGroup(['A', 2]) # optional - coxeter3 - sage: it = CoxGroupIterator(W) # optional - coxeter3 - sage: [next(it) for i in range(W.order())] # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupIterator + sage: W = CoxGroup(['A', 2]) + sage: it = CoxGroupIterator(W) + sage: [next(it) for i in range(W.order())] [[], [1], [2], [1, 2], [2, 1], [1, 2, 1]] """ self.group = group @@ -1181,10 +1181,10 @@ class CoxGroupIterator(): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupIterator # optional - coxeter3 - sage: W = CoxGroup(['A', 2]) # optional - coxeter3 - sage: it = iter(W) # optional - coxeter3 - sage: it is iter(it) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupIterator + sage: W = CoxGroup(['A', 2]) + sage: it = iter(W) + sage: it is iter(it) True """ return self @@ -1195,10 +1195,10 @@ class CoxGroupIterator(): EXAMPLES:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupIterator # optional - coxeter3 - sage: W = CoxGroup(['A', 2]) # optional - coxeter3 - sage: it = CoxGroupIterator(W) # optional - coxeter3 - sage: next(it) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupIterator + sage: W = CoxGroup(['A', 2]) + sage: it = CoxGroupIterator(W) + sage: next(it) [] """ if self.n >= self.order: @@ -1217,8 +1217,8 @@ def get_CoxGroup(cartan_type): """ TESTS:: - sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupIterator # optional - coxeter3 - sage: W = CoxGroup(['A', 2]) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter import get_CoxGroup as CoxGroup, CoxGroupIterator + sage: W = CoxGroup(['A', 2]) """ from sage.combinat.root_system.cartan_type import CartanType cartan_type = CartanType(cartan_type) diff --git a/src/sage/libs/coxeter3/coxeter_group.py b/src/sage/libs/coxeter3/coxeter_group.py index bb5a3bc024a..fd5f93ad506 100644 --- a/src/sage/libs/coxeter3/coxeter_group.py +++ b/src/sage/libs/coxeter3/coxeter_group.py @@ -1,14 +1,15 @@ # sage_setup: distribution = sagemath-coxeter3 +# sage.doctest: optional - coxeter3 """ Coxeter Groups implemented with Coxeter3 """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2009-2013 Mike Hansen # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.libs.coxeter3.coxeter import get_CoxGroup, CoxGroupElement from sage.misc.cachefunc import cached_method @@ -31,10 +32,10 @@ def __classcall__(cls, cartan_type, *args, **options): """ TESTS:: - sage: from sage.libs.coxeter3.coxeter_group import CoxeterGroup # optional - coxeter3 - sage: CoxeterGroup(['B',2]) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter_group import CoxeterGroup + sage: CoxeterGroup(['B',2]) Coxeter group of type ['B', 2] implemented by Coxeter3 - sage: CoxeterGroup(CartanType(['B', 3]).relabel({1: 3, 2: 2, 3: 1})) # optional - coxeter3 + sage: CoxeterGroup(CartanType(['B', 3]).relabel({1: 3, 2: 2, 3: 1})) Coxeter group of type ['B', 3] relabelled by {1: 3, 2: 2, 3: 1} implemented by Coxeter3 """ @@ -46,15 +47,15 @@ def __init__(self, cartan_type): """ TESTS:: - sage: from sage.libs.coxeter3.coxeter_group import CoxeterGroup # optional - coxeter3 - sage: CoxeterGroup(['A',2]) # optional - coxeter3 + sage: from sage.libs.coxeter3.coxeter_group import CoxeterGroup + sage: CoxeterGroup(['A',2]) Coxeter group of type ['A', 2] implemented by Coxeter3 As degrees and codegrees are not implemented, they are skipped in the testsuite:: sage: to_skip = ['_test_degrees', '_test_codegrees'] - sage: TestSuite(CoxeterGroup(['A',2])).run(skip=to_skip) # optional - coxeter3 + sage: TestSuite(CoxeterGroup(['A',2])).run(skip=to_skip) """ category = CoxeterGroups() if cartan_type.is_finite(): @@ -67,9 +68,9 @@ def _repr_(self): """ EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3'); W # optional - coxeter3 # indirect doctest + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3'); W # indirect doctest Coxeter group of type ['A', 3] implemented by Coxeter3 - sage: W = CoxeterGroup(['A', 3, 1], implementation='coxeter3'); W # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3, 1], implementation='coxeter3'); W Coxeter group of type ['A', 3, 1] implemented by Coxeter3 """ return "Coxeter group of type %s implemented by Coxeter3" % (self.cartan_type()) @@ -78,8 +79,8 @@ def __iter__(self): """ EXAMPLES:: - sage: W = CoxeterGroup(['A', 2], implementation='coxeter3') # optional - coxeter3 - sage: list(W) # optional - coxeter3 + sage: W = CoxeterGroup(['A', 2], implementation='coxeter3') + sage: list(W) [[], [1], [2], [1, 2], [2, 1], [1, 2, 1]] """ for x in self._coxgroup: @@ -91,8 +92,8 @@ def cartan_type(self): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W.cartan_type() # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W.cartan_type() ['A', 3] """ return self._cartan_type @@ -103,11 +104,11 @@ def index_set(self): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W.index_set() # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W.index_set() (1, 2, 3) - sage: C = CoxeterGroup(['A', 3,1], implementation='coxeter3') # optional - coxeter3 - sage: C.index_set() # optional - coxeter3 + sage: C = CoxeterGroup(['A', 3,1], implementation='coxeter3') + sage: C.index_set() (0, 1, 2, 3) """ return self.cartan_type().index_set() @@ -118,8 +119,8 @@ def bruhat_interval(self, u, v): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W.bruhat_interval([1],[3,1,2,3]) # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W.bruhat_interval([1],[3,1,2,3]) [[1], [1, 2], [1, 3], [1, 2, 3], [1, 3, 2], [1, 2, 3, 2]] """ u, v = self(u), self(v) @@ -131,8 +132,8 @@ def cardinality(self): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W.cardinality() # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W.cardinality() 24 """ return self._coxgroup.order() @@ -143,8 +144,8 @@ def one(self): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W.one() # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W.one() [] """ @@ -156,9 +157,9 @@ def simple_reflections(self): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: s = W.simple_reflections() # optional - coxeter3 - sage: s[2]*s[1]*s[2] # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: s = W.simple_reflections() + sage: s[2]*s[1]*s[2] [1, 2, 1] """ from sage.sets.family import Family @@ -172,10 +173,10 @@ def from_reduced_word(self, w): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W.from_reduced_word([1, 3]) # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W.from_reduced_word([1, 3]) [1, 3] - sage: W.from_reduced_word([3, 1]) # optional - coxeter3 + sage: W.from_reduced_word([3, 1]) [1, 3] """ return self.element_class(self, w) @@ -186,8 +187,8 @@ def rank(self): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W.rank() # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W.rank() 3 """ return self._coxgroup.rank() @@ -198,8 +199,8 @@ def is_finite(self): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W.is_finite() # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W.is_finite() True """ return self._coxgroup.is_finite() @@ -211,10 +212,10 @@ def length(self, x): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W.length(W([1,2])) # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W.length(W([1,2])) 2 - sage: W.length(W([1,1])) # optional - coxeter3 + sage: W.length(W([1,1])) 0 """ @@ -230,12 +231,12 @@ def coxeter_matrix(self): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: m = W.coxeter_matrix(); m # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: m = W.coxeter_matrix(); m [1 3 2] [3 1 3] [2 3 1] - sage: m.index_set() == W.index_set() # optional - coxeter3 + sage: m.index_set() == W.index_set() True """ @@ -247,11 +248,11 @@ def root_system(self): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: R = W.root_system(); R # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: R = W.root_system(); R Root system of type ['A', 3] - sage: alpha = R.root_space().basis() # optional - coxeter3 - sage: alpha[2] + alpha[3] # optional - coxeter3 + sage: alpha = R.root_space().basis() + sage: alpha[2] + alpha[3] alpha[2] + alpha[3] """ return self.cartan_type().root_system() @@ -262,8 +263,8 @@ def _an_element_(self): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W._an_element_() # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W._an_element_() [] """ @@ -275,8 +276,8 @@ def m(self, i, j): TESTS:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W.m(1, 1) # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W.m(1, 1) doctest:warning...: DeprecationWarning: the .m(i, j) method has been deprecated; use .coxeter_matrix()[i,j] instead. See https://github.com/sagemath/sage/issues/30237 for details. @@ -303,13 +304,13 @@ def kazhdan_lusztig_polynomial(self, u, v, constant_term_one=True): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W.kazhdan_lusztig_polynomial([], [1,2, 1]) # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W.kazhdan_lusztig_polynomial([], [1,2, 1]) 1 - sage: W.kazhdan_lusztig_polynomial([1],[3,2]) # optional - coxeter3 + sage: W.kazhdan_lusztig_polynomial([1],[3,2]) 0 - sage: W = CoxeterGroup(['A',3],implementation='coxeter3') # optional - coxeter3 - sage: W.kazhdan_lusztig_polynomial([2],[2,1,3,2]) # optional - coxeter3 + sage: W = CoxeterGroup(['A',3],implementation='coxeter3') + sage: W.kazhdan_lusztig_polynomial([2],[2,1,3,2]) q + 1 .. NOTE:: @@ -325,7 +326,7 @@ def kazhdan_lusztig_polynomial(self, u, v, constant_term_one=True): In particular, `P_{u,u}=1`:: - sage: all(W.kazhdan_lusztig_polynomial(u,u) == 1 for u in W) # optional - coxeter3 + sage: all(W.kazhdan_lusztig_polynomial(u,u) == 1 for u in W) True This convention differs from Theorem 2.7 in [LT1998]_ by: @@ -336,20 +337,20 @@ def kazhdan_lusztig_polynomial(self, u, v, constant_term_one=True): To access the Leclerc-Thibon convention use:: - sage: W = CoxeterGroup(['A',3],implementation='coxeter3') # optional - coxeter3 - sage: W.kazhdan_lusztig_polynomial([2],[2,1,3,2],constant_term_one=False) # optional - coxeter3 + sage: W = CoxeterGroup(['A',3],implementation='coxeter3') + sage: W.kazhdan_lusztig_polynomial([2],[2,1,3,2],constant_term_one=False) q^3 + q TESTS: We check that Coxeter3 and Sage's implementation give the same results:: - sage: C = CoxeterGroup(['B', 3], implementation='coxeter3') # optional - coxeter3 + sage: C = CoxeterGroup(['B', 3], implementation='coxeter3') sage: W = WeylGroup("B3",prefix="s") sage: [s1,s2,s3] = W.simple_reflections() sage: R. = LaurentPolynomialRing(QQ) sage: KL = KazhdanLusztigPolynomial(W,q) - sage: all(KL.P(1,w) == C.kazhdan_lusztig_polynomial([],w.reduced_word()) for w in W) # optional - coxeter3 # long (15s) + sage: all(KL.P(1,w) == C.kazhdan_lusztig_polynomial([],w.reduced_word()) for w in W) # long (15s) True """ u, v = self(u), self(v) @@ -384,30 +385,30 @@ def parabolic_kazhdan_lusztig_polynomial(self, u, v, J, constant_term_one=True): EXAMPLES:: - sage: W = CoxeterGroup(['A',3], implementation='coxeter3') # optional - coxeter3 - sage: W.parabolic_kazhdan_lusztig_polynomial([],[3,2],[1,3]) # optional - coxeter3 + sage: W = CoxeterGroup(['A',3], implementation='coxeter3') + sage: W.parabolic_kazhdan_lusztig_polynomial([],[3,2],[1,3]) 0 - sage: W.parabolic_kazhdan_lusztig_polynomial([2],[2,1,3,2],[1,3]) # optional - coxeter3 + sage: W.parabolic_kazhdan_lusztig_polynomial([2],[2,1,3,2],[1,3]) q - sage: C = CoxeterGroup(['A',3,1], implementation='coxeter3') # optional - coxeter3 - sage: C.parabolic_kazhdan_lusztig_polynomial([],[1],[0]) # optional - coxeter3 + sage: C = CoxeterGroup(['A',3,1], implementation='coxeter3') + sage: C.parabolic_kazhdan_lusztig_polynomial([],[1],[0]) 1 - sage: C.parabolic_kazhdan_lusztig_polynomial([],[1,2,1],[0]) # optional - coxeter3 + sage: C.parabolic_kazhdan_lusztig_polynomial([],[1,2,1],[0]) 1 - sage: C.parabolic_kazhdan_lusztig_polynomial([],[0,1,0,1,2,1],[0]) # optional - coxeter3 + sage: C.parabolic_kazhdan_lusztig_polynomial([],[0,1,0,1,2,1],[0]) q sage: w=[1, 2, 1, 3, 0, 2, 1, 0, 3, 0, 2] sage: v=[1, 2, 1, 3, 0, 1, 2, 1, 0, 3, 0, 2, 1, 0, 3, 0, 2] - sage: C.parabolic_kazhdan_lusztig_polynomial(w,v,[1,3]) # optional - coxeter3 + sage: C.parabolic_kazhdan_lusztig_polynomial(w,v,[1,3]) q^2 + q - sage: C.parabolic_kazhdan_lusztig_polynomial(w,v,[1,3],constant_term_one=False) # optional - coxeter3 + sage: C.parabolic_kazhdan_lusztig_polynomial(w,v,[1,3],constant_term_one=False) q^4 + q^2 TESTS:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: type(W.parabolic_kazhdan_lusztig_polynomial([2],[],[1])) # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: type(W.parabolic_kazhdan_lusztig_polynomial([2],[],[1])) """ u = self(u) @@ -431,19 +432,19 @@ def __init__(self, parent, x): """ TESTS:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W([2,1,2]) # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W([2,1,2]) [1, 2, 1] Check that :trac:`32266` is fixed:: - sage: A3 = CoxeterGroup('A3', implementation='coxeter3') # optional - coxeter3 - sage: s1,s2,s3 = A3.simple_reflections() # optional - coxeter3 - sage: s1*s3 # optional - coxeter3 + sage: A3 = CoxeterGroup('A3', implementation='coxeter3') + sage: s1,s2,s3 = A3.simple_reflections() + sage: s1*s3 [1, 3] - sage: s3*s1 # optional - coxeter3 + sage: s3*s1 [1, 3] - sage: s3*s1 == s1*s3 # optional - coxeter3 + sage: s3*s1 == s1*s3 True """ if not isinstance(x, CoxGroupElement): @@ -457,9 +458,9 @@ def __iter__(self): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: w = W([1,2,1]) # optional - coxeter3 - sage: list(iter(w)) # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: w = W([1,2,1]) + sage: list(iter(w)) [1, 2, 1] """ return iter(self.value) @@ -470,9 +471,9 @@ def coatoms(self): EXAMPLES:: - sage: W = CoxeterGroup(['B', 3], implementation='coxeter3') # optional - coxeter3 - sage: w = W([1,2,3]) # optional - coxeter3 - sage: w.coatoms() # optional - coxeter3 + sage: W = CoxeterGroup(['B', 3], implementation='coxeter3') + sage: w = W([1,2,3]) + sage: w.coatoms() [[2, 3], [3, 1], [1, 2]] """ W = self.parent() @@ -484,20 +485,20 @@ def _richcmp_(self, other, op): EXAMPLES:: - sage: W = CoxeterGroup(['B', 3], implementation='coxeter3') # optional - coxeter3 - sage: w = W([1,2,3]) # optional - coxeter3 - sage: v = W([3,1,2]) # optional - coxeter3 - sage: v < w # optional - coxeter3 + sage: W = CoxeterGroup(['B', 3], implementation='coxeter3') + sage: w = W([1,2,3]) + sage: v = W([3,1,2]) + sage: v < w False - sage: w < v # optional - coxeter3 + sage: w < v True Some tests for equality:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W([1,2,1]) == W([2,1,2]) # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W([1,2,1]) == W([2,1,2]) True - sage: W([1,2,1]) == W([2,1]) # optional - coxeter3 + sage: W([1,2,1]) == W([2,1]) False """ return richcmp(list(self), list(other), op) @@ -508,9 +509,9 @@ def reduced_word(self): EXAMPLES:: - sage: W = CoxeterGroup(['B', 3], implementation='coxeter3') # optional - coxeter3 - sage: w = W([1,2,3]) # optional - coxeter3 - sage: w.reduced_word() # optional - coxeter3 + sage: W = CoxeterGroup(['B', 3], implementation='coxeter3') + sage: w = W([1,2,3]) + sage: w.reduced_word() [1, 2, 3] """ return list(self) @@ -521,9 +522,9 @@ def __invert__(self): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: w = W([1,2,3]) # optional - coxeter3 - sage: ~w # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: w = W([1,2,3]) + sage: ~w [3, 2, 1] """ return self.__class__(self.parent(), ~self.value) @@ -534,11 +535,11 @@ def __getitem__(self, i): """ EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: w0 = W([1,2,1]) # optional - coxeter3 - sage: w0[0] # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: w0 = W([1,2,1]) + sage: w0[0] 1 - sage: w0[1] # optional - coxeter3 + sage: w0[1] 2 """ @@ -549,13 +550,13 @@ def _mul_(self, y): """ EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: s = W.gens() # optional - coxeter3 - sage: s[1]._mul_(s[1]) # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: s = W.gens() + sage: s[1]._mul_(s[1]) [] - sage: s[1]*s[2]*s[1] # optional - coxeter3 + sage: s[1]*s[2]*s[1] [1, 2, 1] - sage: s[2]*s[1]*s[2] # optional - coxeter3 + sage: s[2]*s[1]*s[2] [1, 2, 1] """ return self.__class__(self.parent(), self.value * y.value) @@ -564,11 +565,11 @@ def __len__(self): """ EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: w = W([1,2,1]) # optional - coxeter3 - sage: w.length() # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: w = W([1,2,1]) + sage: w.length() 3 - sage: len(w) # optional - coxeter3 + sage: len(w) 3 """ return len(self.value) @@ -581,8 +582,8 @@ def bruhat_le(self, v): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W([]).bruhat_le([1,2,1]) # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W([]).bruhat_le([1,2,1]) True """ v = self.parent()(v) @@ -594,18 +595,17 @@ def poincare_polynomial(self): EXAMPLES:: - sage: W = CoxeterGroup(['A', 2], implementation='coxeter3') # optional - coxeter3 - sage: W.long_element().poincare_polynomial() # optional - coxeter3 + sage: W = CoxeterGroup(['A', 2], implementation='coxeter3') + sage: W.long_element().poincare_polynomial() t^3 + 2*t^2 + 2*t + 1 - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: W([2,1,3,2]).poincare_polynomial() # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: W([2,1,3,2]).poincare_polynomial() t^4 + 4*t^3 + 5*t^2 + 3*t + 1 - sage: W([1,2,3,2,1]).poincare_polynomial() # optional - coxeter3 + sage: W([1,2,3,2,1]).poincare_polynomial() t^5 + 4*t^4 + 6*t^3 + 5*t^2 + 3*t + 1 - - sage: rw = sage.combinat.permutation.from_reduced_word # optional - coxeter3 - sage: p = [w.poincare_polynomial() for w in W] # optional - coxeter3 - sage: [rw(w.reduced_word()) for i,w in enumerate(W) if p[i] != p[i].reverse()] # optional - coxeter3 + sage: rw = sage.combinat.permutation.from_reduced_word + sage: p = [w.poincare_polynomial() for w in W] + sage: [rw(w.reduced_word()) for i,w in enumerate(W) if p[i] != p[i].reverse()] [[3, 4, 1, 2], [4, 2, 3, 1]] """ return self.value.poincare_polynomial() @@ -616,10 +616,10 @@ def has_right_descent(self, i): EXAMPLES:: - sage: W = CoxeterGroup(['A', 4], implementation='coxeter3') # optional - coxeter3 - sage: W([1,2]).has_right_descent(1) # optional - coxeter3 + sage: W = CoxeterGroup(['A', 4], implementation='coxeter3') + sage: W([1,2]).has_right_descent(1) False - sage: W([1,2]).has_right_descent(2) # optional - coxeter3 + sage: W([1,2]).has_right_descent(2) True """ return i in self.value.right_descents() @@ -630,10 +630,10 @@ def has_left_descent(self, i): EXAMPLES:: - sage: W = CoxeterGroup(['A', 4], implementation='coxeter3') # optional - coxeter3 - sage: W([1,2]).has_left_descent(1) # optional - coxeter3 + sage: W = CoxeterGroup(['A', 4], implementation='coxeter3') + sage: W([1,2]).has_left_descent(1) True - sage: W([1,2]).has_left_descent(2) # optional - coxeter3 + sage: W([1,2]).has_left_descent(2) False """ return i in self.value.left_descents() @@ -648,15 +648,15 @@ def action(self, v): EXAMPLES:: - sage: W = CoxeterGroup(['B', 3], implementation='coxeter3') # optional - coxeter3 - sage: R = W.root_system().root_space() # optional - coxeter3 - sage: v = R.an_element(); v # optional - coxeter3 + sage: W = CoxeterGroup(['B', 3], implementation='coxeter3') + sage: R = W.root_system().root_space() + sage: v = R.an_element(); v 2*alpha[1] + 2*alpha[2] + 3*alpha[3] - sage: w = W([1,2,3]) # optional - coxeter3 - sage: w.action(v) # optional - coxeter3 + sage: w = W([1,2,3]) + sage: w.action(v) -alpha[1] + alpha[2] + alpha[3] """ - #TODO: Find a better way to do this + # TODO: Find a better way to do this W = self.parent().root_system().root_space().weyl_group() w = W.from_reduced_word(list(self)) return w.action(v) @@ -675,14 +675,14 @@ def action_on_rational_function(self, f): EXAMPLES:: - sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') # optional - coxeter3 - sage: S = PolynomialRing(QQ, 'x,y,z').fraction_field() # optional - coxeter3 - sage: x,y,z = S.gens() # optional - coxeter3 - sage: W([1]).action_on_rational_function(x+y+z) # optional - coxeter3 + sage: W = CoxeterGroup(['A', 3], implementation='coxeter3') + sage: S = PolynomialRing(QQ, 'x,y,z').fraction_field() + sage: x,y,z = S.gens() + sage: W([1]).action_on_rational_function(x+y+z) (x^2*y + x*z + 1)/x - sage: W([2]).action_on_rational_function(x+y+z) # optional - coxeter3 + sage: W([2]).action_on_rational_function(x+y+z) (x*y^2 + y^2*z + 1)/y - sage: W([3]).action_on_rational_function(x+y+z) # optional - coxeter3 + sage: W([3]).action_on_rational_function(x+y+z) (y*z^2 + x*z + 1)/z """ Q = f.parent() @@ -693,7 +693,9 @@ def action_on_rational_function(self, f): n = W.rank() if Q.ngens() != n: - raise ValueError("the number of generators for the polynomial ring must be the same as the rank of the root system") + raise ValueError("the number of generators for the polynomial " + "ring must be the same as the rank of the " + "root system") basis_elements = [alpha[i] for i in W.index_set()] basis_to_order = {s: i for i, s in enumerate(W.index_set())} @@ -704,7 +706,7 @@ def action_on_rational_function(self, f): exponents = poly.exponents() for exponent in exponents: - #Construct something in the root lattice from the exponent vector + # Construct something in the root lattice from the exponent vector exponent = sum(e*b for e, b in zip(exponent, basis_elements)) exponent = self.action(exponent) diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index e522bf5bc03..1f0f451a2c2 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -553,7 +553,7 @@ cdef class GapElement(RingElement): INPUT: - - ``mut`` - (boolean) whether to return an mutable copy + - ``mut`` - (boolean) whether to return a mutable copy EXAMPLES:: @@ -1778,7 +1778,7 @@ cdef class GapElement_FiniteField(GapElement): OUTPUT: - An Sage finite field element. The isomorphism is chosen such + A Sage finite field element. The isomorphism is chosen such that the Gap ``PrimitiveRoot()`` maps to the Sage :meth:`~sage.rings.finite_rings.finite_field_prime_modn.multiplicative_generator`. diff --git a/src/sage/libs/ntl/ntl_GF2E.pyx b/src/sage/libs/ntl/ntl_GF2E.pyx index 2e4fec38020..fa941804293 100644 --- a/src/sage/libs/ntl/ntl_GF2E.pyx +++ b/src/sage/libs/ntl/ntl_GF2E.pyx @@ -54,7 +54,7 @@ def ntl_GF2E_random(ntl_GF2EContext_class ctx): INPUT: - - ``ctx`` -- the GF2E context for which an random element should be created + - ``ctx`` -- the GF2E context for which a random element should be created EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_GF2X.pyx b/src/sage/libs/ntl/ntl_GF2X.pyx index f6781a68c7b..5e6ef736763 100644 --- a/src/sage/libs/ntl/ntl_GF2X.pyx +++ b/src/sage/libs/ntl/ntl_GF2X.pyx @@ -507,7 +507,7 @@ cdef class ntl_GF2X(): def hex(ntl_GF2X self): r""" - Return an hexadecimal representation of this element. + Return a hexadecimal representation of this element. It is the same as setting \code{ntl.GF2XHexOutput(True)} and representing this element afterwards. However it should be faster and diff --git a/src/sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi b/src/sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi index 22d15b71b45..36c87c75efa 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi +++ b/src/sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi @@ -332,7 +332,7 @@ cdef inline int celement_pow(ZZ_pEX_c* res, ZZ_pEX_c* x, long e, ZZ_pEX_c *modul sage: (x+1)^(-2) 1/(x^2 + 2*x + 1) sage: f = x+(a+1) - sage: f**50 == sum(binomial(50,i)*(a+1)**i*x**(50-i) for i in range(51)) + sage: f**50 == sum(binomial(50,i)*(a+1)**i*x**(50-i) for i in range(51)) # needs sage.symbolic True TESTS: diff --git a/src/sage/libs/singular/decl.pxd b/src/sage/libs/singular/decl.pxd index aa6c5515432..e36216d6395 100644 --- a/src/sage/libs/singular/decl.pxd +++ b/src/sage/libs/singular/decl.pxd @@ -1052,7 +1052,7 @@ cdef extern from "singular/polys/sbuckets.h": #assumes length <= 0 || pLength(p) == length void sBucketClearMerge(sBucket *bucket, poly **p, int *length) - #add contents of sBucket into polynomial an clear bucket + #add contents of sBucket into polynomial and clear bucket #(can handle repeated monomials) void sBucketClearAdd(sBucket *bucket, poly **p, int *length) diff --git a/src/sage/manifolds/differentiable/manifold.py b/src/sage/manifolds/differentiable/manifold.py index 3a7820e01ec..4b5a793f762 100644 --- a/src/sage/manifolds/differentiable/manifold.py +++ b/src/sage/manifolds/differentiable/manifold.py @@ -814,7 +814,7 @@ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None): sage: U.default_chart() is X.restrict(U) True - An point in ``U``:: + A point in ``U``:: sage: p = U.an_element(); p Point on the 2-dimensional differentiable manifold M diff --git a/src/sage/manifolds/topological_submanifold.py b/src/sage/manifolds/topological_submanifold.py index 314a6a16a1b..9b722907152 100644 --- a/src/sage/manifolds/topological_submanifold.py +++ b/src/sage/manifolds/topological_submanifold.py @@ -70,7 +70,7 @@ class TopologicalSubmanifold(TopologicalManifold): a topological embedding `\phi` from `N` to `M` (i.e. `\phi` is an homeomorphism onto its image). - In the case where `\phi` is only an topological immersion (i.e. is only + In the case where `\phi` is only a topological immersion (i.e. is only locally an embedding), one says that `N` is an *immersed submanifold*. The map `\phi` can also depend on one or multiple parameters. diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 4acd46db4de..0c2aa9eda4b 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -216,10 +216,10 @@ cdef class Matrix(Matrix1): from sage.matrix.constructor import matrix if self.is_sparse(): return matrix({ij: self[ij].subs(*args, **kwds) for ij in self.nonzero_positions()}, - nrows=self._nrows, ncols=self._ncols, sparse=True) + nrows=self._nrows, ncols=self._ncols, sparse=True) else: return matrix([a.subs(*args, **kwds) for a in self.list()], - nrows=self._nrows, ncols=self._ncols, sparse=False) + nrows=self._nrows, ncols=self._ncols, sparse=False) def solve_left(self, B, check=True): """ @@ -3183,14 +3183,12 @@ cdef class Matrix(Matrix1): """ # Validate assertions - # if not self.is_square(): raise ValueError("self must be a square matrix") from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing # Extract parameters - # cdef Matrix M = self n = M._ncols R = M._base_ring @@ -3199,7 +3197,6 @@ cdef class Matrix(Matrix1): # Corner cases # N.B. We already tested for M to be square, hence we do not need to # test for 0 x n or m x 0 matrices. - # if n == 0: return S.one() @@ -3215,7 +3212,6 @@ cdef class Matrix(Matrix1): # # N.B. The documentation is still 1-based, although the code, after # having been ported from Magma to Sage, is 0-based. - # from sage.matrix.constructor import matrix F = [R.zero()] * n @@ -3226,18 +3222,15 @@ cdef class Matrix(Matrix1): for t in range(1,n): # Set a(1, t) to be M(<=t, t) - # for i in range(t+1): a.set_unsafe(0, i, M.get_unsafe(i, t)) # Set A[1, t] to be the (t)th entry in a[1, t] - # A[0] = M.get_unsafe(t, t) for p in range(1, t): # Set a(p, t) to the product of M[<=t, <=t] * a(p-1, t) - # for i in range(t+1): s = R.zero() for j in range(t+1): @@ -3245,11 +3238,9 @@ cdef class Matrix(Matrix1): a.set_unsafe(p, i, s) # Set A[p, t] to be the (t)th entry in a[p, t] - # A[p] = a.get_unsafe(p, t) # Set A[t, t] to be M[t, <=t] * a(p-1, t) - # s = R.zero() for j in range(t+1): s = s + M.get_unsafe(t, j) * a.get_unsafe(t-1, j) @@ -3262,7 +3253,7 @@ cdef class Matrix(Matrix1): F[p] = s - A[p] X = S.gen(0) - f = X ** n + S(list(reversed(F))) + f = X**n + S(list(reversed(F))) return f @@ -3634,7 +3625,7 @@ cdef class Matrix(Matrix1): # using the rows of a matrix.) Also see Cohen's first GTM, # Algorithm 2.2.9. - cdef Py_ssize_t i, m, n, + cdef Py_ssize_t i, m, n n = self._nrows cdef Matrix c @@ -18607,8 +18598,8 @@ def _matrix_power_symbolic(A, n): sage: A = matrix(ZZ, [[1,-1], [-1,1]]) sage: A^(2*n+1) # needs sage.symbolic - [ 1/2*2^(2*n + 1) -1/2*2^(2*n + 1)] - [-1/2*2^(2*n + 1) 1/2*2^(2*n + 1)] + [ 1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1) -1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1)] + [-1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1) 1/2*2^(2*n + 1) + 1/2*kronecker_delta(0, 2*n + 1)] Check if :trac:`23215` is fixed:: @@ -18618,12 +18609,25 @@ def _matrix_power_symbolic(A, n): -1/2*I*(a + I*b)^k + 1/2*I*(a - I*b)^k, 1/2*I*(a + I*b)^k - 1/2*I*(a - I*b)^k, 1/2*(a + I*b)^k + 1/2*(a - I*b)^k] + + Check if :trac:`36838` is fixed:Checking symbolic power of + nilpotent matrix:: + + sage: A = matrix([[0,1],[0,0]]); A + [0 1] + [0 0] + sage: n = var('n'); n + n + sage: B = A^n; B + [ kronecker_delta(0, n) n*kronecker_delta(1, n)] + [ 0 kronecker_delta(0, n)] """ from sage.rings.qqbar import AlgebraicNumber from sage.matrix.constructor import matrix from sage.functions.other import binomial from sage.symbolic.ring import SR from sage.rings.qqbar import QQbar + from sage.functions.generalized import kronecker_delta got_SR = A.base_ring() == SR @@ -18656,8 +18660,17 @@ def _matrix_power_symbolic(A, n): # D^i(f) / i! with f = x^n and D = differentiation wrt x if hasattr(mk, 'radical_expression'): mk = mk.radical_expression() - vk = [(binomial(n, i) * mk**(n-i)).simplify_full() - for i in range(nk)] + + + # When the variable "mk" is equal to zero, it is advisable to employ the Kronecker delta function + # instead of utilizing the numerical value zero. This choice is made to encompass scenarios where + # the power of zero is also equal to zero. + if mk: + vk = [(binomial(n, i) * mk._pow_(n-i)).simplify_full() + for i in range(nk)] + else: + vk = [(binomial(n, i).simplify_full() * kronecker_delta(n,i)) + for i in range(nk)] # Form block Mk and insert it in M Mk = matrix(SR, [[SR.zero()]*i + vk[:nk-i] for i in range(nk)]) diff --git a/src/sage/matrix/matrix_cdv.pyx b/src/sage/matrix/matrix_cdv.pyx index 6faf51eb6ad..73ae9d3552d 100644 --- a/src/sage/matrix/matrix_cdv.pyx +++ b/src/sage/matrix/matrix_cdv.pyx @@ -22,7 +22,7 @@ from sage.rings.infinity import Infinity # We assume that H is square cpdef hessenbergize_cdvf(Matrix_generic_dense H) noexcept: r""" - Replace `H` with an Hessenberg form of it. + Replace `H` with a Hessenberg form of it. .. NOTE:: diff --git a/src/sage/matrix/matrix_integer_dense_hnf.py b/src/sage/matrix/matrix_integer_dense_hnf.py index a899ae9f6e0..30db173966f 100644 --- a/src/sage/matrix/matrix_integer_dense_hnf.py +++ b/src/sage/matrix/matrix_integer_dense_hnf.py @@ -236,8 +236,8 @@ def double_det(A, b, c, proof): INPUT: - A -- an (n-1) x n matrix - - b -- an 1 x n matrix - - c -- an 1 x n matrix + - b -- a 1 x n matrix + - c -- a 1 x n matrix - proof -- whether or not to compute the det modulo enough times to provably compute the determinant. diff --git a/src/sage/matroids/lean_matrix.pyx b/src/sage/matroids/lean_matrix.pyx index 740864af9ce..fa1d95c9bf6 100644 --- a/src/sage/matroids/lean_matrix.pyx +++ b/src/sage/matroids/lean_matrix.pyx @@ -2903,7 +2903,7 @@ cdef class PlusMinusOneMatrix(LeanMatrix): cdef LeanMatrix stack(self, LeanMatrix M) noexcept: """ - Warning: assumes ``M`` is an PlusMinusOneMatrix instance of right + Warning: assumes ``M`` is a PlusMinusOneMatrix instance of right dimensions! """ cdef PlusMinusOneMatrix A @@ -3360,7 +3360,7 @@ cdef class RationalMatrix(LeanMatrix): cdef LeanMatrix stack(self, LeanMatrix M) noexcept: """ - Warning: assumes ``M`` is an RationalMatrix instance of right + Warning: assumes ``M`` is a RationalMatrix instance of right dimensions! """ cdef RationalMatrix A diff --git a/src/sage/matroids/set_system.pyx b/src/sage/matroids/set_system.pyx index 1c943ed6203..ad24e104925 100644 --- a/src/sage/matroids/set_system.pyx +++ b/src/sage/matroids/set_system.pyx @@ -591,7 +591,7 @@ cdef class SetSystem: cpdef _heuristic_partition(self, SetSystem P=None, EP=None) noexcept: """ - Return an heuristic ordered partition into singletons of the ground + Return a heuristic ordered partition into singletons of the ground set of the hypergraph whose edges are the subsets in this SetSystem. This partition obtained as follows: make an equitable diff --git a/src/sage/misc/abstract_method.py b/src/sage/misc/abstract_method.py index 7d8ca8edb4c..6179c5a2b8f 100644 --- a/src/sage/misc/abstract_method.py +++ b/src/sage/misc/abstract_method.py @@ -48,7 +48,7 @@ def abstract_method(f=None, optional=False): sage: A.my_method - The current policy is that a ``NotImplementedError`` is raised + The current policy is that a :class:`NotImplementedError` is raised when accessing the method through an instance, even before the method is called:: @@ -193,7 +193,7 @@ def _sage_src_lines_(self): sage: src[0] 'def version():\n' sage: lines - 19 + 18 """ from sage.misc.sageinspect import sage_getsourcelines return sage_getsourcelines(self._f) diff --git a/src/sage/misc/banner.py b/src/sage/misc/banner.py index a428de42005..9d231926705 100644 --- a/src/sage/misc/banner.py +++ b/src/sage/misc/banner.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" SageMath version and banner info """ @@ -58,14 +57,14 @@ def banner_text(full=True): if not full: return version() - bars = u"─" * 68 + bars = "─" * 68 s = [] a = s.append - a(u'┌' + bars + u'┐') - a(u"\n│ %-66s │\n" % version()) + a('┌' + bars + '┐') + a("\n│ %-66s │\n" % version()) python_version = sys.version_info[:3] - a(u"│ %-66s │\n" % 'Using Python {}.{}.{}. Type "help()" for help.'.format(*python_version)) - a(u'└' + bars + u'┘') + a("│ %-66s │\n" % 'Using Python {}.{}.{}. Type "help()" for help.'.format(*python_version)) + a('└' + bars + '┘') pre = version_dict()['prerelease'] try: import sage.all @@ -75,15 +74,15 @@ def banner_text(full=True): if pre or not have_sage_all: red_in = '\033[31m' red_out = '\033[0m' - bars2 = bars.replace(u'─', u'━') + bars2 = bars.replace('─', '━') a('\n') - a(red_in + u'┏' + bars2 + u'┓' + '\n') + a(red_in + '┏' + bars2 + '┓' + '\n') if pre: - a(u"┃ %-66s ┃\n" % 'Warning: this is a prerelease version, and it may be unstable.') + a("┃ %-66s ┃\n" % 'Warning: this is a prerelease version, and it may be unstable.') if not have_sage_all: - a(u"┃ %-66s ┃\n" % 'Warning: sage.all is not available; this is a limited REPL.') - a(u'┗' + bars2 + u'┛' + red_out) - return u''.join(s) + a("┃ %-66s ┃\n" % 'Warning: sage.all is not available; this is a limited REPL.') + a('┗' + bars2 + '┛' + red_out) + return ''.join(s) def banner(): diff --git a/src/sage/misc/call.py b/src/sage/misc/call.py index 966ee34514b..979497b43f9 100644 --- a/src/sage/misc/call.py +++ b/src/sage/misc/call.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Attribute and method calling """ diff --git a/src/sage/misc/converting_dict.py b/src/sage/misc/converting_dict.py index 39f66c9295a..0cd7a47916e 100644 --- a/src/sage/misc/converting_dict.py +++ b/src/sage/misc/converting_dict.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Converting Dictionary @@ -26,7 +25,7 @@ This is used e.g. in the result of a variety, to allow access to the result no matter how a generator is identified:: - sage: # needs sage.rings.number_field + sage: # needs sage.libs.singular sage.rings.number_field sage: K. = QQ[] sage: I = ideal([x^2 + 2*y - 5, x + y + 3]) sage: V = sorted(I.variety(AA), key=str) diff --git a/src/sage/misc/cython.py b/src/sage/misc/cython.py index 2af3bc65943..781e02b3191 100644 --- a/src/sage/misc/cython.py +++ b/src/sage/misc/cython.py @@ -370,7 +370,7 @@ def cython(filename, verbose=0, compile_message=False, try: with open(name + ".lis") as f: cython_messages = f.read() - except IOError: + except OSError: cython_messages = "Error compiling Cython file" except CompileError: raise RuntimeError(cython_messages.strip()) diff --git a/src/sage/misc/edit_module.py b/src/sage/misc/edit_module.py index 9b03e7237a0..82496752609 100644 --- a/src/sage/misc/edit_module.py +++ b/src/sage/misc/edit_module.py @@ -133,7 +133,7 @@ def template_fields(template): """ dict = {} dummy = None - while not(dummy): + while not dummy: try: dummy = template.substitute(dict) except KeyError as inst: @@ -168,10 +168,10 @@ def set_edit_template(template_string): """ global edit_template - if not(isinstance(template_string, Template)): + if not isinstance(template_string, Template): template_string = Template(template_string) fields = set(template_fields(template_string)) - if not(fields <= set(['file', 'line']) and ('file' in fields)): + if not (fields <= set(['file', 'line']) and ('file' in fields)): raise ValueError("Only ${file} and ${line} are allowed as template variables, and ${file} must occur.") edit_template = template_string @@ -253,7 +253,7 @@ def edit(obj, editor=None, bg=None): if editor: set_editor(editor) - elif not(edit_template): + elif not edit_template: try: ED = os.environ['EDITOR'] EDITOR = ED.split() @@ -263,7 +263,7 @@ def edit(obj, editor=None, bg=None): except (ValueError, KeyError, IndexError): raise ValueError("Use set_edit_template() to set a default") - if not(edit_template): + if not edit_template: raise ValueError("Use set_edit_template() to set a default") filename, lineno = file_and_line(obj) diff --git a/src/sage/misc/element_with_label.py b/src/sage/misc/element_with_label.py index 831b012e31a..e7ae38264be 100644 --- a/src/sage/misc/element_with_label.py +++ b/src/sage/misc/element_with_label.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Elements with labels. @@ -170,4 +169,4 @@ def __ne__(self, other): sage: a != x False """ - return not(self == other) + return not (self == other) diff --git a/src/sage/misc/explain_pickle.py b/src/sage/misc/explain_pickle.py index 2fb34a2234e..a0c6323270c 100644 --- a/src/sage/misc/explain_pickle.py +++ b/src/sage/misc/explain_pickle.py @@ -461,8 +461,8 @@ def run_pickle(self, p): sage: sib(pe.run_pickle('T\5\0\0\0hello.')) # py2 {atomic:'hello'} """ - for (op, arg, pos) in genops(p): - assert(not(self.stopped)) + for op, arg, pos in genops(p): + assert not self.stopped try: handler = getattr(self, op.name) except AttributeError: @@ -472,8 +472,8 @@ def run_pickle(self, p): else: handler(arg) - assert(self.stopped) - assert(len(self.stack) == 1) + assert self.stopped + assert len(self.stack) == 1 return self.stack[0] def check_value(self, v): @@ -493,7 +493,7 @@ def check_value(self, v): AssertionError sage: pe.check_value(sib(7)) """ - assert(isinstance(v, (SageInputExpression, PickleObject))) + assert isinstance(v, (SageInputExpression, PickleObject)) def push(self, v): r""" @@ -2442,13 +2442,13 @@ def unpickle_build(obj, state): slots = None if state is not None: - assert(isinstance(state, dict)) + assert isinstance(state, dict) d = obj.__dict__ for k, v in state.items(): d[k] = v if slots is not None: - assert(isinstance(slots, dict)) + assert isinstance(slots, dict) for k, v in slots.items(): setattr(obj, k, v) @@ -2635,11 +2635,11 @@ def pers_load(s): if cpickle_ok: cpickle_repr = repr(cpickle_res) - assert(current_repr == generic_repr == cpickle_repr) + assert current_repr == generic_repr == cpickle_repr print("result: " + current_repr) else: - assert(current_repr == generic_repr) + assert current_repr == generic_repr print("result: " + current_repr + " (cPickle raised an exception!)") diff --git a/src/sage/misc/functional.py b/src/sage/misc/functional.py index 03697f08b7c..7a2bb8c0803 100644 --- a/src/sage/misc/functional.py +++ b/src/sage/misc/functional.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Functional notation diff --git a/src/sage/misc/latex.py b/src/sage/misc/latex.py index df469ca8189..f409dacbddc 100644 --- a/src/sage/misc/latex.py +++ b/src/sage/misc/latex.py @@ -33,10 +33,9 @@ from tempfile import TemporaryDirectory from sage.misc.cachefunc import cached_function, cached_method +from sage.misc.lazy_attribute import lazy_attribute from sage.structure.sage_object import SageObject -from sage.misc.lazy_import import lazy_import -lazy_import('sage.misc.html', ('MathJax', 'MathJaxExpr'), deprecation=31536) COMMON_HEADER = r'''\usepackage{amsmath} \usepackage{amssymb} @@ -66,111 +65,6 @@ ''') -@cached_function -def have_latex() -> bool: - """ - Return ``True`` if this computer has the program ``latex``. - - If this computer does not have LaTeX installed, you may obtain it - from http://ctan.org/. - - EXAMPLES:: - - sage: from sage.misc.latex import have_latex - sage: have_latex() # random - True - """ - from .superseded import deprecation - deprecation(32650, 'the function have_latex() is replaced by: ' - 'from sage.features.latex import latex;latex().is_present()') - from sage.features.latex import latex - return latex().is_present() - - -@cached_function -def have_pdflatex() -> bool: - """ - Return ``True`` if this computer has the program ``pdflatex``. - - If this computer does not have pdflatex installed, you may obtain it - from http://ctan.org/. - - EXAMPLES:: - - sage: from sage.misc.latex import have_pdflatex - sage: have_pdflatex() # random - True - """ - from .superseded import deprecation - deprecation(32650, 'the function have_pdflatex() is replaced by: ' - 'from sage.features.latex import pdflatex;pdflatex().is_present()') - from sage.features.latex import pdflatex - return pdflatex().is_present() - - -@cached_function -def have_xelatex() -> bool: - """ - Return ``True`` if this computer has the program ``xelatex``. - - If this computer does not have xelatex installed, you may obtain it - from http://ctan.org/. - - EXAMPLES:: - - sage: from sage.misc.latex import have_xelatex - sage: have_xelatex() # random - True - """ - from .superseded import deprecation - deprecation(32650, 'the function have_xelatex() is replaced by: ' - 'from sage.features.latex import xelatex;xelatex().is_present()') - from sage.features.latex import xelatex - return xelatex().is_present() - - -@cached_function -def have_dvipng() -> bool: - """ - Return ``True`` if this computer has the program ``dvipng``. - - If this computer does not have dvipng installed, you may obtain it - from http://sourceforge.net/projects/dvipng/ - - EXAMPLES:: - - sage: from sage.misc.latex import have_dvipng - sage: have_dvipng() # random - True - """ - from .superseded import deprecation - deprecation(32650, 'the function have_dvipng() is replaced by: ' - 'from sage.features.dvipng import dvipng;dvipng().is_present()') - from sage.features.dvipng import dvipng - return dvipng().is_present() - -@cached_function -def have_convert() -> bool: - """ - Return ``True`` if this computer has the program ``convert``. - - If this computer does not have convert installed, you may obtain it - (along with the rest of the ImageMagick suite) from - http://www.imagemagick.org - - EXAMPLES:: - - sage: from sage.misc.latex import have_convert - sage: have_convert() # random - True - """ - from .superseded import deprecation - deprecation(32650, 'the function have_convert() is replaced by: ' - 'from sage.features.imagemagick import imagemagick;imagemagick().is_present()') - from sage.features.imagemagick import ImageMagick - return ImageMagick().is_present() - - def list_function(x): r""" Returns the LaTeX code for a list ``x``. @@ -207,7 +101,7 @@ def tuple_function(x, combine_all=False): - ``x`` -- a tuple - - ``combine_all`` -- boolean (Default: ``False``) If ``combine_all`` is + - ``combine_all`` -- boolean (default: ``False``) If ``combine_all`` is ``True``, then it does not return a tuple and instead returns a string with all the elements separated by a single space. It does not collapse tuples which are inside tuples. @@ -315,11 +209,9 @@ def str_function(x): INPUT: - - ``x`` -- a string. - - OUTPUT: + - ``x`` -- a string - A string + OUTPUT: A string EXAMPLES:: @@ -436,10 +328,10 @@ class LatexExpr(str): Normally, objects of this class are created by a :func:`latex` call. It is also possible to generate :class:`LatexExpr` directly from a string, which must contain valid LaTeX code for typesetting in math mode (without dollar - signs). In the Sage notebook, use - :func:`~sage.repl.rich_output.pretty_print.pretty_print` or the "Typeset" - checkbox to actually see the typeset LaTeX code; alternatively, from - either the command-line or the notebook, use the :func:`view` function. + signs). In the Jupyter notebook, use + :func:`~sage.repl.rich_output.pretty_print.pretty_print` to actually see + the typeset LaTeX code; alternatively, from either the command-line or the + notebook, use the :func:`view` function. INPUT: @@ -583,6 +475,30 @@ def has_latex_attr(x) -> bool: return hasattr(x, '_latex_') and not isinstance(x, type) +@cached_function +def default_engine(): + """ + Return the default latex engine and the official name of the engine. + + This is determined by availability of the popular engines on the user's + system. It is assumed that at least latex is available. + + EXAMPLES:: + + sage: from sage.misc.latex import default_engine + sage: default_engine() # random + ('lualatex', 'LuaLaTeX') + """ + from sage.features.latex import pdflatex, xelatex, lualatex + if lualatex().is_present(): + return 'lualatex', 'LuaLaTeX' + if xelatex().is_present(): + return 'xelatex', 'XeLaTeX' + if pdflatex().is_present(): + return 'pdflatex', 'pdfLaTeX' + return 'latex', 'LaTeX' + + class _Latex_prefs_object(SageObject): """ An object that holds LaTeX global preferences. @@ -598,23 +514,38 @@ def __init__(self, bb=False, delimiters=["(", ")"], sage: latex_prefs = _Latex_prefs_object() sage: TestSuite(latex_prefs).run(skip ="_test_pickling") """ - self._option = {} - self._option["blackboard_bold"] = bb - self._option["matrix_delimiters"] = list(delimiters) - self._option["vector_delimiters"] = list(delimiters) - self._option["matrix_column_alignment"] = matrix_column_alignment - self._option["macros"] = "" - self._option["preamble"] = "" - self._option["engine"] = "pdflatex" - self._option["engine_name"] = "LaTeX" + self.__option = {} + self.__option["blackboard_bold"] = bb + self.__option["matrix_delimiters"] = list(delimiters) + self.__option["vector_delimiters"] = list(delimiters) + self.__option["matrix_column_alignment"] = matrix_column_alignment + self.__option["macros"] = "" + self.__option["preamble"] = "" + + @lazy_attribute + def _option(self): + """ + This attribute contains the preferences list. + EXAMPLES:: + + sage: from sage.misc.latex import _Latex_prefs_object + sage: _Latex_prefs_object()._option # random + {'blackboard_bold': False, + 'matrix_delimiters': ['(', ')'], + 'vector_delimiters': ['(', ')'], + 'matrix_column_alignment': 'r', + 'macros': '', + 'preamble': '', + 'engine': 'lualatex', + 'engine_name': 'LuaLaTeX'} + """ + self.__option["engine"] = default_engine()[0] + self.__option["engine_name"] = default_engine()[1] + return self.__option -_Latex_prefs = _Latex_prefs_object() -############################################################## -# The Latex class is used to make slides and LaTeX output in -# the Sage Notebook -######################################### +_Latex_prefs = _Latex_prefs_object() def latex_extra_preamble(): @@ -664,25 +595,25 @@ def latex_extra_preamble(): def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_in_background=False): """ This runs LaTeX on the TeX file "filename.tex". It produces files - "filename.dvi" (or "filename.pdf"` if engine is either ``pdflatex`` - or ``xelatex``) and if ``png`` is ``True``, "filename.png". If ``png`` - is ``True`` and dvipng cannot convert the dvi file to png (because of - postscript specials or other issues), then dvips is called, and the - PS file is converted to a png file. + ``filename.dvi`` (or ``filename.pdf``` if ``engine`` is either ``'pdflatex'``, + ``'xelatex'``, or ``'lualatex'``) and if ``png`` is ``True``, ``filename.png``. + If ``png`` is ``True`` and ``dvipng`` cannot convert the dvi file to png + (because of postscript specials or other issues), then ``dvips`` is called, and + the PS file is converted to a png file. INPUT: - - ``filename`` -- string: file to process, including full path + - ``filename`` -- string; file to process, including full path - - ``debug`` -- bool (optional, default ``False``): whether to print + - ``debug`` -- bool (optional, default ``False``); whether to print verbose debugging output - - ``density`` -- integer (optional, default 150): how big output + - ``density`` -- integer (optional, default 150); how big output image is. - ``engine`` -- string: latex engine to use. - - ``png`` -- bool (optional, default ``False``): whether to produce a + - ``png`` -- bool (optional, default ``False``); whether to produce a png file. - ``do_in_background`` -- bool (optional, default ``False``). Unused, @@ -690,23 +621,23 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i OUTPUT: - A string which could be a string starting with 'Error' (if - there was a problem), or it could be 'pdf' or 'dvi'. If - engine is latex or ``None``, then a dvi file is created, but if there - appear to be problems with it (because of PS special commands, for - example), then a pdf file is created instead. The function - returns 'dvi' or 'pdf' to indicate which type of file is created. - (Detecting problems requires that dvipng be installed; if it is - not, then the dvi file is not checked for problems and 'dvi' is - returned.) If engine is pdflatex or xelatex and there are no errors, then - 'pdf' is returned. + A string which could be a string starting with ``'Error'`` (if there was a + problem), or it could be ``'pdf'`` or ``'dvi'``. If ``engine`` is + ``'latex'`` or ``None``, then a dvi file is created, but if there appear to + be problems with it (because of PS special commands, for example), then a + pdf file is created instead. The function returns ``'dvi'`` or ``'pdf'`` + to indicate which type of file is created. (Detecting problems requires + that ``dvipng`` be installed; if it is not, then the dvi file is not checked + for problems and ``'dvi'`` is returned.) If ``engine`` is ``'pdflatex'``, + ``'xelatex'`` or ``'lualatex'`` and there are no errors, then ``'pdf'`` is + returned. .. WARNING:: If ``png`` is ``True``, then when using latex (the default), you - must have 'dvipng' (or 'dvips' and 'convert') installed on your + must have ``dvipng`` (or ``dvips`` and ``convert``) installed on your operating system, or this command will not work. When using - pdflatex or xelatex, you must have 'convert' installed. + ``pdflatex``, ``xelatex`` or ``lualatex``, you must have ``convert`` installed. EXAMPLES:: @@ -740,6 +671,12 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i command = "xelatex" suffix = "pdf" return_suffix = "pdf" + elif engine == "lualatex": + from sage.features.latex import lualatex + lualatex().require() + command = "lualatex" + suffix = "pdf" + return_suffix = "pdf" else: raise ValueError("Unsupported LaTeX engine.") @@ -758,10 +695,8 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i print("Go to http://sourceforge.net/projects/dvipng/ and") print("http://www.imagemagick.org to download these programs.") return "Error" - # if png output + pdflatex, check to see if convert is installed. - elif engine == "pdflatex": - ImageMagick().require() - elif engine == "xelatex": + # if png output + [pdf|xe|lua]latex, check to see if convert is installed. + elif engine in ["pdflatex", "xelatex", "lualatex"]: ImageMagick().require() # check_validity: check to see if the dvi file is okay by trying # to convert to a png file. if this fails, return_suffix will be @@ -814,7 +749,7 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i def subpcall(x): return not call(x, stdout=redirect, stderr=redirect, cwd=base) - if engine == "pdflatex" or engine == "xelatex": + if engine in ['pdflatex', 'xelatex', 'lualatex']: if debug: print(lt) if png: @@ -871,12 +806,17 @@ def subpcall(x): try: with open(base + '/' + filename + '.log') as f: print(f.read()) - except IOError: + except OSError: pass return "Error latexing slide." return return_suffix +# ------------------------------------------------------- +# The Latex class is used to make slides and LaTeX output +# ------------------------------------------------------- + + class LatexCall: r""" Typeset Sage objects via a ``__call__`` method to this class, @@ -981,7 +921,7 @@ class Latex(LatexCall): sage: LatexExpr(r"y \neq") + latex(x^20 + 1) # needs sage.symbolic y \neq x^{20} + 1 """ - def __init__(self, debug=False, slide=False, density=150, pdflatex=None, engine=None): + def __init__(self, debug=False, slide=False, density=150, engine=None): """ Initialize the latex builder. @@ -993,7 +933,6 @@ def __init__(self, debug=False, slide=False, density=150, pdflatex=None, engine= """ self.__debug = debug self.__slide = slide - self.__pdflatex = pdflatex self.__engine = engine self.__density = density @@ -1046,41 +985,36 @@ def _latex_preparse(self, s, locals): s = s[:i] + k + t[j + 1:] def eval(self, x, globals, strip=False, filename=None, debug=None, - density=None, pdflatex=None, engine=None, locals={}): + density=None, engine=None, locals={}): r""" Compile the formatted tex given by ``x`` as a png and writes the output file to the directory given by ``filename``. INPUT: - - ``globals`` -- a globals dictionary + - ``globals`` -- a globals dictionary - - ``x`` -- string to evaluate. + - ``x`` -- string to evaluate - - ``strip`` -- ignored + - ``strip`` -- ignored - - ``filename`` -- output filename + - ``filename`` -- output filename - - ``debug`` -- whether to print verbose debugging - output + - ``debug`` -- whether to print verbose debugging output - - ``density`` -- how big output image is. + - ``density`` -- how big output image is - - ``pdflatex`` -- whether to use pdflatex. This is deprecated. Use - ``engine`` option instead. + - ``engine`` -- latex engine to use. Currently ``'latex'``, + ``'pdflatex'``, ``'xelatex'`` and ``'lualatex'`` are supported - - ``engine`` -- latex engine to use. Currently latex, pdflatex, and - xelatex are supported. - - - ``locals`` - extra local variables used when - evaluating Sage code in ``x``. + - ``locals`` - extra local variables used when evaluating Sage code in ``x`` .. WARNING:: - When using latex (the default), you must have 'dvipng' (or - 'dvips' and 'convert') installed on your operating system, - or this command will not work. When using pdflatex or xelatex, you - must have 'convert' installed. + When using ``'latex'`` (the default), you must have ``dvipng`` (or + ``dvips`` and ``convert``) installed on your operating system, or + this command will not work. When using ``'pdflatex'``, ``'xelatex'`` + or ``'lualatex'``, you must have ``convert`` installed. OUTPUT: @@ -1151,7 +1085,7 @@ def eval(self, x, globals, strip=False, filename=None, debug=None, def blackboard_bold(self, t=None): r"""nodetex Controls whether Sage uses blackboard bold or ordinary bold - face for typesetting ZZ, RR, etc. + face for typesetting ``ZZ``, ``RR``, etc. INPUT: @@ -1207,18 +1141,18 @@ def matrix_delimiters(self, left=None, right=None): Good choices for ``left`` and ``right`` are any delimiters which LaTeX understands and knows how to resize; some examples are: - - parentheses: '(', ')' - - brackets: '[', ']' - - braces: '\\{', '\\}' - - vertical lines: '|' - - angle brackets: '\\langle', '\\rangle' + - parentheses: ``'('``, ``')'`` + - brackets: ``'['``, ``']'`` + - braces: ``'\\{'``, ``'\\}'`` + - vertical lines: ``'|'`` + - angle brackets: ``'\\langle'``, ``'\\rangle'`` .. NOTE:: - Putting aside aesthetics, you may combine these in any way - imaginable; for example, you could set ``left`` to be a - right-hand bracket ']' and ``right`` to be a right-hand - brace '\\}', and it will be typeset correctly. + Putting aside aesthetics, you may combine these in any way + imaginable; for example, you could set ``left`` to be a right-hand + bracket ``']'`` and ``right`` to be a right-hand brace ``'\\}'``, + and it will be typeset correctly. EXAMPLES:: @@ -1228,12 +1162,12 @@ def matrix_delimiters(self, left=None, right=None): \left(\begin{array}{r} 17 \end{array}\right) - sage: latex.matrix_delimiters("[", "]") + sage: latex.matrix_delimiters('[', ']') sage: latex(a) \left[\begin{array}{r} 17 \end{array}\right] - sage: latex.matrix_delimiters(left="\\{") + sage: latex.matrix_delimiters(left='\\{') sage: latex(a) \left\{\begin{array}{r} 17 @@ -1243,7 +1177,7 @@ def matrix_delimiters(self, left=None, right=None): Restore defaults:: - sage: latex.matrix_delimiters("(", ")") + sage: latex.matrix_delimiters('(', ')') """ if left is None and right is None: return _Latex_prefs._option['matrix_delimiters'] @@ -1269,18 +1203,18 @@ def vector_delimiters(self, left=None, right=None): Good choices for ``left`` and ``right`` are any delimiters which LaTeX understands and knows how to resize; some examples are: - - parentheses: '(', ')' - - brackets: '[', ']' - - braces: '\\{', '\\}' - - vertical lines: '|' - - angle brackets: '\\langle', '\\rangle' + - parentheses: ``'('``, ``')'`` + - brackets: ``'['``, ``']'`` + - braces: ``'\\{'``, ``'\\}'`` + - vertical lines: ``'|'`` + - angle brackets: ``'\\langle'``, ``'\\rangle'`` .. NOTE:: - Putting aside aesthetics, you may combine these in any way - imaginable; for example, you could set ``left`` to be a - right-hand bracket ']' and ``right`` to be a right-hand - brace '\\}', and it will be typeset correctly. + Putting aside aesthetics, you may combine these in any way + imaginable; for example, you could set ``left`` to be a right-hand + bracket ``']'`` and ``right`` to be a right-hand brace ``'\\}'``, and it + will be typeset correctly. EXAMPLES:: @@ -1288,10 +1222,10 @@ def vector_delimiters(self, left=None, right=None): sage: a = vector(QQ, [1,2,3]) sage: latex(a) \left(1,\,2,\,3\right) - sage: latex.vector_delimiters("[", "]") + sage: latex.vector_delimiters('[', ']') sage: latex(a) \left[1,\,2,\,3\right] - sage: latex.vector_delimiters(right="\\}") + sage: latex.vector_delimiters(right='\\}') sage: latex(a) \left[1,\,2,\,3\right\} sage: latex.vector_delimiters() @@ -1299,7 +1233,7 @@ def vector_delimiters(self, left=None, right=None): Restore defaults:: - sage: latex.vector_delimiters("(", ")") + sage: latex.vector_delimiters('(', ')') """ if left is None and right is None: return _Latex_prefs._option['vector_delimiters'] @@ -1387,7 +1321,7 @@ def check_file(self, file_name, more_info=""): - ``file_name`` -- a string - - ``more_info`` -- a string (default: "") + - ``more_info`` -- a string (default: ``""``) Emit a warning if the local LaTeX installation does not include ``file_name``. The string ``more_info`` is appended @@ -1417,7 +1351,7 @@ def check_file(self, file_name, more_info=""): def extra_macros(self, macros=None): r"""nodetex - String containing extra LaTeX macros to use with %latex and %html. + String containing extra LaTeX macros to use with ``%latex`` and ``%html``. INPUT: @@ -1500,7 +1434,7 @@ def extra_preamble(self, s=None): def add_to_preamble(self, s): r"""nodetex Append to the string ``s`` of extra LaTeX macros, for use with - %latex. + ``%latex``. EXAMPLES:: @@ -1523,7 +1457,7 @@ def add_to_preamble(self, s): sage: latex.extra_preamble() '\\DeclareMathOperator{\\Ext}{Ext}\\usepackage{xypic}' - Now one can put various xypic diagrams into a %latex cell, such as + Now one can put various xypic diagrams into a ``%latex`` cell, such as :: @@ -1576,7 +1510,7 @@ def engine(self, e=None): INPUT: - - ``e`` -- 'latex', 'pdflatex', 'xelatex' or ``None`` + - ``e`` -- ``'latex'``, ``'pdflatex'``, ``'xelatex'``, ``'lualatex'`` or ``None`` If ``e`` is ``None``, return the current engine. @@ -1590,14 +1524,14 @@ def engine(self, e=None): EXAMPLES:: - sage: latex.engine() - 'pdflatex' + sage: latex.engine() # random + 'lualatex' sage: latex.engine("latex") sage: latex.engine() 'latex' - sage: latex.engine("xelatex") + sage: latex.engine("pdflatex") sage: latex.engine() - 'xelatex' + 'pdflatex' """ if e is None: return _Latex_prefs._option["engine"] @@ -1611,8 +1545,12 @@ def engine(self, e=None): elif e == "xelatex": _Latex_prefs._option["engine"] = e _Latex_prefs._option["engine_name"] = "XeLaTeX" + elif e == "lualatex": + _Latex_prefs._option["engine"] = e + _Latex_prefs._option["engine_name"] = "LuaLaTeX" else: - raise ValueError("%s is not a supported LaTeX engine. Use latex, pdflatex, or xelatex" % e) + raise ValueError("%s is not a supported LaTeX engine. Use latex, pdflatex, xelatex, or lualatex" % e) + # Note: latex used to be a separate function, which by default was # only loaded in command-line mode: in the old notebook, @@ -1621,13 +1559,10 @@ def engine(self, e=None): # function. This has been changed around so that the contents of the # old latex function are now in Latex.__call__; thus the following # assignment. - - latex = Latex() # Ensure that latex appear in the sphinx doc as a function # so that the link :func:`latex` is correctly set up. latex.__doc__ = Latex.__call__.__doc__ -######################################### def _latex_file_(objects, title='SAGE', debug=False, @@ -1640,22 +1575,22 @@ def _latex_file_(objects, title='SAGE', debug=False, INPUT: - - ``objects`` -- list (or object) + - ``objects`` -- list (or object) - - ``title`` -- string (default: 'Sage'): title for the document + - ``title`` -- string (default: 'Sage'); title for the document - - ``math_left`` -- string (default: '\\['), left delimiter for math mode + - ``math_left`` -- string (default: '\\['), left delimiter for math mode - - ``math_right`` -- string (default: '\\]'), right delimiter for math mode + - ``math_right`` -- string (default: '\\]'), right delimiter for math mode - - ``debug`` -- bool (default: False): print verbose output + - ``debug`` -- bool (default: False); print verbose output - - ``sep`` -- string (default: ''): separator between math objects + - ``sep`` -- string (default: ``''``); separator between math objects - - ``tiny`` -- bool (default: False): use 'tiny' font. + - ``tiny`` -- bool (default: False); use 'tiny' font. - - ``extra_preamble`` -- string (default: ''): extra LaTeX commands, - inserted before "\\begin{document}" + - ``extra_preamble`` -- string (default: ``''``); extra LaTeX commands, + inserted before ``"\\begin{document}"`` This creates a string intended to be a LaTeX file containing the LaTeX representations of objects. It contains the following: @@ -1674,7 +1609,7 @@ def _latex_file_(objects, title='SAGE', debug=False, Then if ``objects`` contains more than one element, for each remaining element: - - the string ``sep``: you can use this, for example, to add + - the string ``sep``; you can use this, for example, to add vertical space between objects with ``sep='\\vspace{15mm}'``, or to add a horizontal line between objects with ``sep='\\hrule'``, or to insert a page break between objects @@ -1682,7 +1617,7 @@ def _latex_file_(objects, title='SAGE', debug=False, - the LaTeX representation of the element - The string ends with '\\end{document}'. + The string ends with ``'\\end{document}'``. EXAMPLES:: @@ -1757,7 +1692,7 @@ def _latex_file_(objects, title='SAGE', debug=False, def view(objects, title='Sage', debug=False, sep='', tiny=False, - pdflatex=None, engine=None, viewer=None, tightpage=True, margin=None, + engine=None, viewer=None, tightpage=True, margin=None, mode='inline', combine_all=False, **kwds): r"""nodetex Compute a latex representation of each object in objects, compile, @@ -1766,50 +1701,49 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False, INPUT: - - ``objects`` -- list (or object) + - ``objects`` -- list (or object) - - ``title`` -- string (default: ``'Sage'``): title for the + - ``title`` -- string (default: ``'Sage'``); title for the document - - ``debug`` -- bool (default: ``False``): print verbose + - ``debug`` -- bool (default: ``False``); print verbose output - - ``sep`` -- string (default: ''): separator between + - ``sep`` -- string (default: ``''``); separator between math objects - - ``tiny`` -- bool (default: ``False``): use tiny font. - - - ``pdflatex`` -- bool (default: ``False``): use pdflatex. This is - deprecated. Use ``'engine'`` option instead. + - ``tiny`` -- bool (default: ``False``); use tiny font. - - ``engine`` -- string or ``None`` (default: ``None``). Can take the + - ``engine`` -- string or ``None`` (default: ``None``); can take the following values: - - ``None`` -- the value defined in the LaTeX global preferences - ``latex.engine()`` is used. + - ``None`` -- the value defined in the LaTeX global preferences + ``latex.engine()`` is used. - - ``'pdflatex'`` -- compilation does tex -> pdf + - ``'pdflatex'`` -- compilation does ``tex`` -> ``pdf`` - - ``'xelatex'`` -- compilation does tex -> pdf + - ``'xelatex'`` -- compilation does ``tex`` -> ``pdf`` - - ``'latex'`` -- compilation first tries tex -> dvi -> png and if an - error occurs then tries dvi -> ps -> pdf. This is slower than - ``'pdflatex'`` and known to be broken when overfull hbox are detected. + - ``'lualatex'`` -- compilation does ``tex`` -> ``pdf`` - - ``viewer`` -- string or ``None`` (default: ``None``): specify a viewer + - ``'latex'`` -- compilation first tries ``tex`` -> ``dvi`` -> ``png`` and if an + error occurs then tries ``dvi`` -> ``ps`` -> ``pdf``. This is slower than + ``'pdflatex'`` and known to be broken when overfull hboxes are detected. + + - ``viewer`` -- string or ``None`` (default: ``None``); specify a viewer to use; currently the only options are ``None`` and ``'pdf'``. - - ``tightpage`` -- bool (default: ``True``): use the LaTeX package - 'preview' with the 'tightpage' option. + - ``tightpage`` -- bool (default: ``True``); use the LaTeX package + ``preview`` with the 'tightpage' option. - - ``margin`` -- float or ``None`` (default: ``None``): adds a margin + - ``margin`` -- float or ``None`` (default: ``None``); adds a margin of ``margin`` mm; has no affect if the option ``tightpage`` is ``False``. - - ``mode`` -- string (default: ``'inline'``): ``'display'`` for + - ``mode`` -- string (default: ``'inline'``); ``'display'`` for displaymath or ``'inline'`` for inline math - - ``combine_all`` -- bool (default: ``False``): If ``combine_all`` is + - ``combine_all`` -- bool (default: ``False``); if ``combine_all`` is ``True`` and the input is a tuple, then it does not return a tuple and instead returns a string with all the elements separated by a single space. @@ -1829,20 +1763,17 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False, adds a horizontal line between objects, and ``sep='\\newpage'`` inserts a page break between objects. - If ``pdflatex`` is ``True``, then the latex engine is set to - pdflatex. - - If the ``engine`` is either ``pdflatex`` or ``xelatex``, it produces - a pdf file. Otherwise, it produces a dvi file, and if the program dvipng is - installed, it checks the dvi file by trying to convert it to a png - file. If this conversion fails, the dvi file probably contains - some postscript special commands or it has other issues which - might make displaying it a problem; in this case, the file is - converted to a pdf file, which is then displayed. + If the ``engine`` is either ``'pdflatex'``, ``'xelatex'``, or ``'lualatex'``, + it produces a pdf file. Otherwise, it produces a dvi file, and if the program + ``dvipng`` is installed, it checks the dvi file by trying to convert it to a + png file. If this conversion fails, the dvi file probably contains some + postscript special commands or it has other issues which might make + displaying it a problem; in this case, the file is converted to a pdf file, + which is then displayed. Setting ``viewer`` to ``'pdf'`` forces the use of a separate viewer, even in notebook mode. This also sets the latex engine to be - ``pdflatex`` if the current engine is latex. + ``pdflatex`` if the current engine is ``latex``. Setting the option ``tightpage`` to ``True`` (this is the default setting) tells LaTeX to use the package 'preview' with the 'tightpage' option. @@ -1921,7 +1852,7 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False, s = _latex_file_(objects, title=title, sep=sep, tiny=tiny, debug=debug, **latex_options) if engine is None: engine = _Latex_prefs._option["engine"] - if pdflatex or (viewer == "pdf" and engine == "latex"): + if viewer == "pdf" and engine == "latex": engine = "pdflatex" # command line or notebook with viewer @@ -1970,42 +1901,37 @@ def run_viewer(): def png(x, filename, density=150, debug=False, - do_in_background=False, tiny=False, pdflatex=True, engine='pdflatex'): + do_in_background=False, tiny=False, engine=None): """ Create a png image representation of ``x`` and save to the given filename. INPUT: - - ``x`` -- object to be displayed - - - ``filename`` -- file in which to save the image + - ``x`` -- object to be displayed - - ``density`` -- integer (default: 150) + - ``filename`` -- file in which to save the image - - ``debug`` -- bool (default: ``False``): print verbose - output + - ``density`` -- integer (default: 150) - - ``do_in_background`` -- bool (default: ``False``): Unused, - kept for backwards compatibility + - ``debug`` -- bool (default: ``False``); print verbose output - - ``tiny`` -- bool (default: ``False``): use 'tiny' font + - ``do_in_background`` -- bool (default: ``False``); Unused, kept for + backwards compatibility - - ``pdflatex`` -- bool (default: ``True``): use pdflatex. This option is - deprecated. Use ``engine`` option instead. See below. + - ``tiny`` -- bool (default: ``False``); use tiny font - - ``engine`` -- (default: ``'pdflatex'``) ``'latex'``, ``'pdflatex'``, - or ``'xelatex'`` + - ``engine`` -- (default: ``None``) ``'latex'``, ``'pdflatex'``, + ``'xelatex'`` or ``'lualatex'`` EXAMPLES:: + sage: # optional - imagemagick latex, needs sage.plot sage: from sage.misc.latex import png sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: # random # optional - imagemagick latex, needs sage.plot + sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: # random ....: png(ZZ[x], f.name) """ - if not pdflatex: - engine = "latex" import sage.plot.all if sage.plot.graphics.is_Graphics(x): x.save(filename) @@ -2014,6 +1940,8 @@ def png(x, filename, density=150, debug=False, s = _latex_file_([x], math_left='$\\displaystyle', math_right='$', title='', debug=debug, tiny=tiny, extra_preamble='\\textheight=2\\textheight') + if engine is None: + engine = _Latex_prefs._option["engine"] # path name for permanent png output abs_path_to_png = os.path.abspath(filename) # temporary directory to store stuff @@ -2076,13 +2004,11 @@ def repr_lincomb(symbols, coeffs): INPUT: - - ``symbols`` -- list of symbols + - ``symbols`` -- list of symbols - - ``coeffs`` -- list of coefficients of the symbols + - ``coeffs`` -- list of coefficients of the symbols - OUTPUT: - - A string + OUTPUT: A string EXAMPLES:: @@ -2213,9 +2139,7 @@ def latex_varify(a, is_fname=False): - ``a`` -- string - OUTPUT: - - A string + OUTPUT: A string EXAMPLES:: @@ -2260,7 +2184,7 @@ def latex_variable_name(x, is_fname=False): 2. If the variable name is suffixed by a number, we put the number in the subscript. - 3. If the variable name contains an '_' we start the subscript at + 3. If the variable name contains an ``'_'`` we start the subscript at the underscore. Note that #3 trumps rule #2. 4. If a component of the variable is a Greek letter, escape it @@ -2467,7 +2391,7 @@ def _repr_(self): make sure that you have the most recent version of the TeX package pstricks installed. Run 'latex.add_to_preamble("\\usepackage{pstricks}")' and try viewing it again. Call 'view' with the option `engine='latex'` --- the default behavior is to use pdflatex, which does not work with +-- the default behavior is to use lualatex, which does not work with pstricks. From the command line, this should pop open a nice window with a picture of forces acting on a mass on a pendulum.""" diff --git a/src/sage/misc/latex_standalone.py b/src/sage/misc/latex_standalone.py index d1d9d77d864..c24b076d805 100644 --- a/src/sage/misc/latex_standalone.py +++ b/src/sage/misc/latex_standalone.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Standalone LaTeX Document class and TikzPicture diff --git a/src/sage/misc/lazy_attribute.pyx b/src/sage/misc/lazy_attribute.pyx index 1f07870b8ec..74c3756a004 100644 --- a/src/sage/misc/lazy_attribute.pyx +++ b/src/sage/misc/lazy_attribute.pyx @@ -77,7 +77,7 @@ cdef class _lazy_attribute(): def _sage_src_lines_(self): r""" - Returns the source code location for the wrapped function. + Return the source code location for the wrapped function. EXAMPLES:: @@ -87,15 +87,14 @@ cdef class _lazy_attribute(): sage: src[0] 'def banner():\n' sage: lines - 89 + 88 """ from sage.misc.sageinspect import sage_getsourcelines return sage_getsourcelines(self.f) - def __get__(self, a, cls): """ - Implements the attribute access protocol. + Implement the attribute access protocol. EXAMPLES:: @@ -143,6 +142,7 @@ cdef class _lazy_attribute(): raise return result + class lazy_attribute(_lazy_attribute): r""" A lazy attribute for an object is like a usual attribute, except @@ -509,7 +509,7 @@ class lazy_attribute(_lazy_attribute): class lazy_class_attribute(lazy_attribute): """ - A lazy class attribute for an class is like a usual class attribute, + A lazy class attribute for a class is like a usual class attribute, except that, instead of being computed when the class is constructed, it is computed on the fly the first time it is accessed, either through the class itself or trough on of its objects. diff --git a/src/sage/misc/mrange.py b/src/sage/misc/mrange.py index d69b82128f1..1c93c811b2e 100644 --- a/src/sage/misc/mrange.py +++ b/src/sage/misc/mrange.py @@ -336,8 +336,8 @@ def __len__(self): """ Return the cardinality of this iterator as an int. - Raises a ``TypeError`` if the cardinality does not fit into a Python - int. + This raises a :class:`TypeError` if the cardinality does not fit + into a Python int. EXAMPLES:: diff --git a/src/sage/misc/package.py b/src/sage/misc/package.py index cbc36ea65b9..d64c53ac3e8 100644 --- a/src/sage/misc/package.py +++ b/src/sage/misc/package.py @@ -152,7 +152,7 @@ def spkg_type(name): return None try: f = open(os.path.join(SAGE_PKGS, name, "type")) - except IOError: + except OSError: # Probably an empty directory => ignore return None diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 3749a4f2a91..7d0e14cf799 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -615,7 +615,7 @@ def handle_file(root, file): if package in ordinary_packages: pass elif ((missing_all_files := distributions_per_directives - package_distributions_per_all_files[package]) - and not(missing_all_files == set(['']) and len(distributions_per_directives) < 2)): + and not (missing_all_files == set(['']) and len(distributions_per_directives) < 2)): s = '' if len(missing_all_files) == 1 else 's' print(f'{package}: missing file{s} ' + ', '.join(_all_filename(distribution) for distribution in missing_all_files)) diff --git a/src/sage/misc/random_testing.py b/src/sage/misc/random_testing.py index 917d8789b4d..9dfb866bbc4 100644 --- a/src/sage/misc/random_testing.py +++ b/src/sage/misc/random_testing.py @@ -184,7 +184,7 @@ def test_add_commutes(trials, verbose=False): b = QQ.random_element() if verbose: print("a == {}, b == {} ...".format(a, b)) - assert(a + b == b + a) + assert a + b == b + a if verbose: print("Passes!") @@ -258,6 +258,6 @@ def test_add_is_mul(trials, verbose=False): b = QQ.random_element() if verbose: print("a == {}, b == {} ...".format(a, b)) - assert(a + b == a * b) + assert a + b == a * b if verbose: print("Passes!") diff --git a/src/sage/misc/replace_dot_all.py b/src/sage/misc/replace_dot_all.py index 3415ea83058..4f872f2691b 100644 --- a/src/sage/misc/replace_dot_all.py +++ b/src/sage/misc/replace_dot_all.py @@ -298,7 +298,7 @@ def process_line(location, line, replacements, row_index, verbose=False): sage: from sage.misc.replace_dot_all import * sage: location = os.path.join(sage.env.SAGE_SRC, 'sage/plot/arc.py') sage: replacements = find_replacements(location, package_regex='sage[.]plot[.]all', verbose=True); replacements - [[476, 24, 'from sage.plot.graphics import Graphics']] + [[477, 24, 'from sage.plot.graphics import Graphics']] sage: with open(location, "r") as file: ....: lines = file.readlines() sage: row_index, col_number, *_ = replacements[0] diff --git a/src/sage/misc/sage_input.py b/src/sage/misc/sage_input.py index 00e8d96ee9e..be38a27d683 100644 --- a/src/sage/misc/sage_input.py +++ b/src/sage/misc/sage_input.py @@ -3475,11 +3475,11 @@ def verify_same(a, b): """ from sage.structure.element import is_Element if is_Element(a): - assert(a.parent() == b.parent()) + assert a.parent() == b.parent() else: - assert(type(a) is type(b)) + assert type(a) is type(b) if isinstance(a, (RealIntervalFieldElement, ComplexIntervalFieldElement)): - assert(a.endpoints() == b.endpoints()), "Expected %s == %s" % (a, b) + assert a.endpoints() == b.endpoints(), "Expected %s == %s" % (a, b) return if not (a == b): diff --git a/src/sage/misc/sage_timeit.py b/src/sage/misc/sage_timeit.py index 2f9c255543b..89c813e563b 100644 --- a/src/sage/misc/sage_timeit.py +++ b/src/sage/misc/sage_timeit.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Accurate timing information for Sage commands @@ -90,9 +89,9 @@ def __repr__(self): 1 loop, best of 2: 3.14 ns per loop """ if self.stats[0] > 1: - s = u"%d loops, best of %d: %.*g %s per loop" % self.stats + s = "%d loops, best of %d: %.*g %s per loop" % self.stats else: - s = u"%d loop, best of %d: %.*g %s per loop" % self.stats + s = "%d loop, best of %d: %.*g %s per loop" % self.stats if isinstance(s, str): return s @@ -217,7 +216,7 @@ def sage_timeit(stmt, globals_dict=None, preparse=None, number=0, repeat=3, prec if stmt == "": return '' - units = [u"s", u"ms", u"μs", u"ns"] + units = ["s", "ms", "μs", "ns"] scaling = [1, 1e3, 1e6, 1e9] timer = timeit_.Timer() diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py index 4d7c3f9c19c..9dd1defedea 100644 --- a/src/sage/misc/sageinspect.py +++ b/src/sage/misc/sageinspect.py @@ -2256,7 +2256,7 @@ class ParentMethods: if B is None: raise AttributeError except AttributeError: - raise IOError("could not get source code") + raise OSError("could not get source code") return sage_getsourcelines(B) # M should just be the top-most module. # Hence, normally it is just 'sage' @@ -2269,14 +2269,14 @@ class ParentMethods: if B is None: raise AttributeError except AttributeError: - raise IOError("could not get source code") + raise OSError("could not get source code") return sage_getsourcelines(B) lines, base_lineno = sage_getsourcelines(M) # the rest of the function is copied from # inspect.findsource if not lines: - raise IOError('could not get source code') + raise OSError('could not get source code') if inspect.ismodule(obj): return lines, base_lineno @@ -2301,7 +2301,7 @@ class ParentMethods: candidates.sort() return inspect.getblock(lines[candidates[0][1]:]), candidates[0][1]+base_lineno else: - raise IOError('could not find class definition') + raise OSError('could not find class definition') if inspect.ismethod(obj): obj = obj.__func__ @@ -2313,7 +2313,7 @@ class ParentMethods: obj = obj.f_code if inspect.iscode(obj): if not hasattr(obj, 'co_firstlineno'): - raise IOError('could not find function definition') + raise OSError('could not find function definition') pat = re.compile(r'^(\s*def\s)|(.*(? 0: # Indefinite if D.is_square(): b = D.sqrt() - c = ZZ(0) + c = ZZ.zero() # -b/2 < a <= b/2 for a in xsrange((-b/2).floor() + 1, (b/2).floor() + 1): if not primitive_only or (gcd([a, b, c]) == 1): diff --git a/src/sage/quadratic_forms/genera/genus.py b/src/sage/quadratic_forms/genera/genus.py index d9c298f5f0a..8946683a988 100644 --- a/src/sage/quadratic_forms/genera/genus.py +++ b/src/sage/quadratic_forms/genera/genus.py @@ -1202,7 +1202,7 @@ def two_adic_symbol(A, val): return [[s[0]+m0] + s[1:] for s in sym + two_adic_symbol(A, val)] -class Genus_Symbol_p_adic_ring(): +class Genus_Symbol_p_adic_ring: r""" Local genus symbol over a `p`-adic ring. @@ -2132,7 +2132,7 @@ def direct_sum(self, other): def excess(self): r""" - Returns the `p`-excess of the quadratic form whose Hessian + Return the `p`-excess of the quadratic form whose Hessian matrix is the symmetric matrix `A`. When `p = 2`, the `p`-excess is called the oddity. @@ -2242,7 +2242,7 @@ def norm(self): sage: G = Genus(matrix(ZZ,2,[0, 1, 1, 0])) sage: G.local_symbol(2).norm() 2 - """ + """ if self.rank() == 0: return ZZ(0) p = self.prime() @@ -2321,7 +2321,7 @@ def compartments(self): return canonical_2_adic_compartments(symbol) -class GenusSymbol_global_ring(): +class GenusSymbol_global_ring: r""" This represents a collection of local genus symbols (at primes) and signature information which represent the genus of a diff --git a/src/sage/quadratic_forms/qfsolve.py b/src/sage/quadratic_forms/qfsolve.py index 85116e43f9e..ff91830874c 100644 --- a/src/sage/quadratic_forms/qfsolve.py +++ b/src/sage/quadratic_forms/qfsolve.py @@ -213,7 +213,7 @@ def solve(self, c=0): if not c: x = qfsolve(M) if isinstance(x, Integer): - raise ArithmeticError("no solution found (local obstruction at {})".format(x)) + raise ArithmeticError(f"no solution found (local obstruction at {x})") return x # If c != 0, define a new quadratic form Q = self - c*z^2 @@ -228,7 +228,7 @@ def solve(self, c=0): x = qfsolve(N) # Raise an error if qfsolve() doesn't find a solution if isinstance(x, Integer): - raise ArithmeticError("no solution found (local obstruction at {})".format(x)) + raise ArithmeticError(f"no solution found (local obstruction at {x})") # Let z be the last term of x, and remove z from x z = x[-1] diff --git a/src/sage/quadratic_forms/quadratic_form.py b/src/sage/quadratic_forms/quadratic_form.py index 3db01b9fe2f..c78e7badeb4 100644 --- a/src/sage/quadratic_forms/quadratic_form.py +++ b/src/sage/quadratic_forms/quadratic_form.py @@ -305,200 +305,200 @@ class QuadraticForm(SageObject): # Routines to compute the p-adic local normal form lazy_import("sage.quadratic_forms.quadratic_form__local_normal_form", [ - "find_entry_with_minimal_scale_at_prime", - "local_normal_form", - "jordan_blocks_by_scale_and_unimodular", - "jordan_blocks_in_unimodular_list_by_scale_power" - ]) + "find_entry_with_minimal_scale_at_prime", + "local_normal_form", + "jordan_blocks_by_scale_and_unimodular", + "jordan_blocks_in_unimodular_list_by_scale_power" + ]) # Routines to perform elementary variable substitutions from sage.quadratic_forms.quadratic_form__variable_substitutions import \ - swap_variables, \ - multiply_variable, \ - divide_variable, \ - scale_by_factor, \ - extract_variables, \ - elementary_substitution, \ - add_symmetric + swap_variables, \ + multiply_variable, \ + divide_variable, \ + scale_by_factor, \ + extract_variables, \ + elementary_substitution, \ + add_symmetric # Routines to compute p-adic field invariants from sage.quadratic_forms.quadratic_form__local_field_invariants import \ - rational_diagonal_form, \ - _rational_diagonal_form_and_transformation, \ - signature_vector, \ - signature, \ - hasse_invariant, \ - hasse_invariant__OMeara, \ - is_hyperbolic, \ - is_anisotropic, \ - is_isotropic, \ - anisotropic_primes, \ - compute_definiteness, \ - compute_definiteness_string_by_determinants, \ - is_positive_definite, \ - is_negative_definite, \ - is_indefinite, \ - is_definite + rational_diagonal_form, \ + _rational_diagonal_form_and_transformation, \ + signature_vector, \ + signature, \ + hasse_invariant, \ + hasse_invariant__OMeara, \ + is_hyperbolic, \ + is_anisotropic, \ + is_isotropic, \ + anisotropic_primes, \ + compute_definiteness, \ + compute_definiteness_string_by_determinants, \ + is_positive_definite, \ + is_negative_definite, \ + is_indefinite, \ + is_definite # Routines to compute local densities by the reduction procedure from sage.quadratic_forms.quadratic_form__local_density_congruence import \ - count_modp_solutions__by_Gauss_sum, \ - local_good_density_congruence_odd, \ - local_good_density_congruence_even, \ - local_good_density_congruence, \ - local_zero_density_congruence, \ - local_badI_density_congruence, \ - local_badII_density_congruence, \ - local_bad_density_congruence, \ - local_density_congruence, \ - local_primitive_density_congruence + count_modp_solutions__by_Gauss_sum, \ + local_good_density_congruence_odd, \ + local_good_density_congruence_even, \ + local_good_density_congruence, \ + local_zero_density_congruence, \ + local_badI_density_congruence, \ + local_badII_density_congruence, \ + local_bad_density_congruence, \ + local_density_congruence, \ + local_primitive_density_congruence # Routines to compute local densities by counting solutions of various types from sage.quadratic_forms.quadratic_form__count_local_2 import \ - count_congruence_solutions_as_vector, \ - count_congruence_solutions, \ - count_congruence_solutions__good_type, \ - count_congruence_solutions__zero_type, \ - count_congruence_solutions__bad_type, \ - count_congruence_solutions__bad_type_I, \ - count_congruence_solutions__bad_type_II + count_congruence_solutions_as_vector, \ + count_congruence_solutions, \ + count_congruence_solutions__good_type, \ + count_congruence_solutions__zero_type, \ + count_congruence_solutions__bad_type, \ + count_congruence_solutions__bad_type_I, \ + count_congruence_solutions__bad_type_II # Routines to be called by the user to compute local densities lazy_import("sage.quadratic_forms.quadratic_form__local_density_interfaces", [ - "local_density", - "local_primitive_density" - ]) + "local_density", + "local_primitive_density" + ]) # Routines for computing with ternary forms from sage.quadratic_forms.quadratic_form__ternary_Tornaria import \ - disc, \ - content, \ - adjoint, \ - antiadjoint, \ - is_adjoint, \ - reciprocal, \ - omega, \ - delta, \ - level__Tornaria, \ - discrec, \ - hasse_conductor, \ - clifford_invariant, \ - clifford_conductor, \ - basiclemma, \ - basiclemmavec, \ - xi, \ - xi_rec, \ - lll, \ - representation_number_list, \ - representation_vector_list, \ - is_zero, \ - is_zero_nonsingular, \ - is_zero_singular + disc, \ + content, \ + adjoint, \ + antiadjoint, \ + is_adjoint, \ + reciprocal, \ + omega, \ + delta, \ + level__Tornaria, \ + discrec, \ + hasse_conductor, \ + clifford_invariant, \ + clifford_conductor, \ + basiclemma, \ + basiclemmavec, \ + xi, \ + xi_rec, \ + lll, \ + representation_number_list, \ + representation_vector_list, \ + is_zero, \ + is_zero_nonsingular, \ + is_zero_singular # Routines to compute the theta function from sage.quadratic_forms.quadratic_form__theta import \ - theta_series, \ - theta_series_degree_2, \ - theta_by_pari, \ - theta_by_cholesky + theta_series, \ + theta_series_degree_2, \ + theta_by_pari, \ + theta_by_cholesky # Routines to compute the product of all local densities lazy_import("sage.quadratic_forms.quadratic_form__siegel_product", [ - "siegel_product" - ]) + "siegel_product" + ]) # Routines to compute p-neighbors from sage.quadratic_forms.quadratic_form__neighbors import \ - find_primitive_p_divisible_vector__random, \ - find_primitive_p_divisible_vector__next, \ - find_p_neighbor_from_vec, \ - neighbor_iteration, \ - orbits_lines_mod_p + find_primitive_p_divisible_vector__random, \ + find_primitive_p_divisible_vector__next, \ + find_p_neighbor_from_vec, \ + neighbor_iteration, \ + orbits_lines_mod_p # Routines to reduce a given quadratic form from sage.quadratic_forms.quadratic_form__reduction_theory import \ - reduced_binary_form1, \ - reduced_ternary_form__Dickson, \ - reduced_binary_form, \ - minkowski_reduction, \ - minkowski_reduction_for_4vars__SP + reduced_binary_form1, \ + reduced_ternary_form__Dickson, \ + reduced_binary_form, \ + minkowski_reduction, \ + minkowski_reduction_for_4vars__SP # Wrappers for Conway-Sloane genus routines (in ./genera/) lazy_import("sage.quadratic_forms.quadratic_form__genus", [ - "global_genus_symbol", - "local_genus_symbol", - "CS_genus_symbol_list" - ]) + "global_genus_symbol", + "local_genus_symbol", + "CS_genus_symbol_list" + ]) # Routines to compute local masses for ZZ. lazy_import("sage.quadratic_forms.quadratic_form__mass", [ - "shimura_mass__maximal", - "GHY_mass__maximal" - ]) + "shimura_mass__maximal", + "GHY_mass__maximal" + ]) lazy_import("sage.quadratic_forms.quadratic_form__mass__Siegel_densities", [ - "mass__by_Siegel_densities", - "Pall_mass_density_at_odd_prime", - "Watson_mass_at_2", - "Kitaoka_mass_at_2", - "mass_at_two_by_counting_mod_power" - ]) + "mass__by_Siegel_densities", + "Pall_mass_density_at_odd_prime", + "Watson_mass_at_2", + "Kitaoka_mass_at_2", + "mass_at_two_by_counting_mod_power" + ]) lazy_import("sage.quadratic_forms.quadratic_form__mass__Conway_Sloane_masses", [ - "parity", - "is_even", - "is_odd", - "conway_species_list_at_odd_prime", - "conway_species_list_at_2", - "conway_octane_of_this_unimodular_Jordan_block_at_2", - "conway_diagonal_factor", - "conway_cross_product_doubled_power", - "conway_type_factor", - "conway_p_mass", - "conway_standard_p_mass", - "conway_standard_mass", - "conway_mass" -# conway_generic_mass, \ -# conway_p_mass_adjustment - ]) + "parity", + "is_even", + "is_odd", + "conway_species_list_at_odd_prime", + "conway_species_list_at_2", + "conway_octane_of_this_unimodular_Jordan_block_at_2", + "conway_diagonal_factor", + "conway_cross_product_doubled_power", + "conway_type_factor", + "conway_p_mass", + "conway_standard_p_mass", + "conway_standard_mass", + "conway_mass" + # conway_generic_mass, \ + # conway_p_mass_adjustment + ]) # Routines to check local representability of numbers lazy_import("sage.quadratic_forms.quadratic_form__local_representation_conditions", [ - "local_representation_conditions", - "is_locally_universal_at_prime", - "is_locally_universal_at_all_primes", - "is_locally_universal_at_all_places", - "is_locally_represented_number_at_place", - "is_locally_represented_number" - ]) + "local_representation_conditions", + "is_locally_universal_at_prime", + "is_locally_universal_at_all_primes", + "is_locally_universal_at_all_places", + "is_locally_represented_number_at_place", + "is_locally_represented_number" + ]) # Routines to make a split local covering of the given quadratic form. from sage.quadratic_forms.quadratic_form__split_local_covering import \ - cholesky_decomposition, \ - vectors_by_length, \ - complementary_subform_to_vector, \ - split_local_cover + cholesky_decomposition, \ + vectors_by_length, \ + complementary_subform_to_vector, \ + split_local_cover # Routines to make automorphisms of the given quadratic form. lazy_import("sage.quadratic_forms.quadratic_form__automorphisms", [ - "basis_of_short_vectors", - "short_vector_list_up_to_length", - "short_primitive_vector_list_up_to_length", - "_compute_automorphisms", - "automorphism_group", - "automorphisms", - "number_of_automorphisms", - "set_number_of_automorphisms" - ]) + "basis_of_short_vectors", + "short_vector_list_up_to_length", + "short_primitive_vector_list_up_to_length", + "_compute_automorphisms", + "automorphism_group", + "automorphisms", + "number_of_automorphisms", + "set_number_of_automorphisms" + ]) # Routines to test the local and global equivalence/isometry of two quadratic forms. from sage.quadratic_forms.quadratic_form__equivalence_testing import \ - is_globally_equivalent_to, \ - is_locally_equivalent_to, \ - has_equivalent_Jordan_decomposition_at_prime, \ - is_rationally_isometric + is_globally_equivalent_to, \ + is_locally_equivalent_to, \ + has_equivalent_Jordan_decomposition_at_prime, \ + is_rationally_isometric # Routines for solving equations of the form Q(x) = c. lazy_import("sage.quadratic_forms.qfsolve", [ - "solve" - ]) + "solve" + ]) # Genus lazy_import("sage.quadratic_forms.genera.genus", @@ -617,7 +617,7 @@ def __init__(self, R, n=None, entries=None, unsafe_initialization=False, number_ # Verify the size of the matrix is an integer >= 0 n = ZZ(n) if n < 0: - raise ValueError("the size must be a non-negative integer, not {}".format(n)) + raise ValueError(f"the size must be a non-negative integer, not {n}") # Store the relevant variables N = n * (n + 1) // 2 @@ -738,7 +738,7 @@ def _repr_(self): if (i > j): out_str += "* " else: - out_str += str(self[i,j]) + " " + out_str += str(self[i, j]) + " " out_str += "]" return out_str @@ -762,7 +762,7 @@ def _latex_(self): if (i > j): out_str += " * & " else: - out_str += str(self[i,j]) + " & " + out_str += str(self[i, j]) + " & " # if i < (n-1): # out_str += "\\" out_str += "\\end{array} \\right]" @@ -1051,7 +1051,7 @@ def __call__(self, v): if is_Matrix(v): # Check that v has the correct number of rows if v.nrows() != n: - raise TypeError("the matrix must have {} rows".format(n)) + raise TypeError(f"the matrix must have {n} rows") # Create the new quadratic form m = v.ncols() @@ -1061,7 +1061,7 @@ def __call__(self, v): elif (is_Vector(v) or isinstance(v, (list, tuple))): # Check the vector/tuple/list has the correct length if not (len(v) == n): - raise TypeError("your vector needs to have length {}".format(n)) + raise TypeError(f"your vector needs to have length {n}") # TO DO: Check that the elements can be coerced into the base ring of Q -- on first elt. if len(v) > 0: @@ -1291,7 +1291,7 @@ def gcd(self): raise TypeError("the given quadratic form must be defined over ZZ") return GCD(self.coefficients()) - def polynomial(self,names='x'): + def polynomial(self, names='x'): r""" Return the quadratic form as a polynomial in `n` variables. @@ -1335,7 +1335,7 @@ def polynomial(self,names='x'): M = matrix(B, n) for i in range(n): for j in range(i, n): - M[i,j] = self[i,j] + M[i, j] = self[i, j] try: R = PolynomialRing(self.base_ring(), names, n) except Exception: @@ -1379,17 +1379,16 @@ def from_polynomial(poly): raise ValueError('polynomial has monomials of degree != 2') base = R.base_ring() vs = R.gens() - coeffs = [] - for i, v in enumerate(vs): - for w in vs[i:]: - coeffs.append(poly.monomial_coefficient(v*w)) + coeffs = [poly.monomial_coefficient(v * w) + for i, v in enumerate(vs) for w in vs[i:]] return QuadraticForm(base, len(vs), coeffs) - def is_primitive(self): + def is_primitive(self) -> bool: """ - Determines if the given integer-valued form is primitive - (i.e. not an integer (`> 1`) multiple of another integer-valued - quadratic form). + Determine if the given integer-valued form is primitive. + + This means not an integer (`> 1`) multiple of another integer-valued + quadratic form. EXAMPLES:: @@ -1399,9 +1398,8 @@ def is_primitive(self): sage: Q = QuadraticForm(ZZ, 2, [2,4,8]) sage: Q.is_primitive() False - """ - return (self.gcd() == 1) + return self.gcd() == 1 def primitive(self): r""" @@ -1630,9 +1628,9 @@ def level(self): for i in range(self.dim()): for j in range(i, self.dim()): if (i == j): - inv_denoms += [denominator(mat_inv[i,j] / 2)] + inv_denoms += [denominator(mat_inv[i, j] / 2)] else: - inv_denoms += [denominator(mat_inv[i,j])] + inv_denoms += [denominator(mat_inv[i, j])] lvl = LCM(inv_denoms) lvl = Ideal(self.base_ring()(lvl)).gen() ############################################################## diff --git a/src/sage/quadratic_forms/quadratic_form__automorphisms.py b/src/sage/quadratic_forms/quadratic_form__automorphisms.py index 175f447bbea..4b6e3594f83 100644 --- a/src/sage/quadratic_forms/quadratic_form__automorphisms.py +++ b/src/sage/quadratic_forms/quadratic_form__automorphisms.py @@ -78,10 +78,8 @@ def basis_of_short_vectors(self, show_lengths=False): vector_list_by_length[l].append(vector([-x for x in v])) # Make a matrix from the column vectors (in order of ascending length). - sorted_list = [] - for i in range(len(vector_list_by_length)): - for v in vector_list_by_length[i]: - sorted_list.append(v) + sorted_list = [v for i in range(len(vector_list_by_length)) + for v in vector_list_by_length[i]] sorted_matrix = Matrix(sorted_list).transpose() # Determine a basis of vectors of minimal length @@ -205,7 +203,7 @@ def short_vector_list_up_to_length(self, len_bound, up_to_sign_flag=False): parilens = pari(r"(M,v) -> vector(#v, i, (v[i]~ * M * v[i])\2)")(self, parilist) # Sort the vectors into lists by their length - vec_sorted_list = [list() for i in range(len_bound)] + vec_sorted_list = [[] for i in range(len_bound)] for i in range(len(parilist)): length = int(parilens[i]) # In certain trivial cases, PARI can sometimes return longer diff --git a/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py b/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py index 148fcbd21f2..2bd4df8f890 100644 --- a/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py +++ b/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py @@ -442,9 +442,9 @@ def is_rationally_isometric(self, other, return_matrix=False): sage: V.is_rationally_isometric(W) Traceback (most recent call last): ... - NotImplementedError: This only tests regular forms + NotImplementedError: this only tests regular forms - Forms must have the same base ring otherwise a `TypeError` is raised:: + Forms must have the same base ring otherwise a :class:`TypeError` is raised:: sage: # needs sage.rings.number_field sage: K1. = QuadraticField(5) @@ -491,7 +491,7 @@ def is_rationally_isometric(self, other, return_matrix=False): True """ if self.Gram_det() == 0 or other.Gram_det() == 0: - raise NotImplementedError("This only tests regular forms") + raise NotImplementedError("this only tests regular forms") if self.base_ring() != other.base_ring(): raise TypeError("forms must have the same base ring.") diff --git a/src/sage/quadratic_forms/quadratic_form__genus.py b/src/sage/quadratic_forms/quadratic_form__genus.py index 8727645b453..52468e9889a 100644 --- a/src/sage/quadratic_forms/quadratic_form__genus.py +++ b/src/sage/quadratic_forms/quadratic_form__genus.py @@ -133,10 +133,8 @@ def CS_genus_symbol_list(self, force_recomputation=False): pass # Otherwise recompute and cache the list - list_of_CS_genus_symbols = [] - - for p in prime_divisors(2 * self.det()): - list_of_CS_genus_symbols.append(self.local_genus_symbol(p)) + list_of_CS_genus_symbols = [self.local_genus_symbol(p) + for p in prime_divisors(2 * self.det())] self.__CS_genus_symbol_list = list_of_CS_genus_symbols return list_of_CS_genus_symbols 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 888f4ae2832..c337d2994a0 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py +++ b/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py @@ -17,7 +17,7 @@ from sage.rings.rational_field import QQ -class QuadraticFormLocalRepresentationConditions(): +class QuadraticFormLocalRepresentationConditions: """ A class for dealing with the local conditions of a quadratic form, and checking local representability of numbers. diff --git a/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py b/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py index a99eb439e0f..9133a84b76f 100644 --- a/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py +++ b/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py @@ -197,8 +197,8 @@ def Watson_mass_at_2(self): s_max = max(scale_list) # Step 1: Compute dictionaries of the diagonal block and 2x2 block for each scale - diag_dict = dict((i, Null_Form) for i in range(s_min - 2, s_max + 4)) # Initialize with the zero form - dim2_dict = dict((i, Null_Form) for i in range(s_min, s_max + 4)) # Initialize with the zero form + diag_dict = {i: Null_Form for i in range(s_min - 2, s_max + 4)} # Initialize with the zero form + dim2_dict = {i: Null_Form for i in range(s_min, s_max + 4)} # Initialize with the zero form for s, L in Jordan_Blocks: i = 0 while i < L.dim() - 1 and L[i, i + 1] == 0: # Find where the 2x2 blocks start @@ -210,8 +210,8 @@ def Watson_mass_at_2(self): diag_dict[s] = L # Step 2: Compute three dictionaries of invariants (for n_j, m_j, nu_j) - n_dict = dict((j, 0) for j in range(s_min + 1, s_max + 2)) - m_dict = dict((j, 0) for j in range(s_min, s_max + 4)) + n_dict = {j: 0 for j in range(s_min + 1, s_max + 2)} + m_dict = {j: 0 for j in range(s_min, s_max + 4)} for s, L in Jordan_Blocks: n_dict[s + 1] = L.dim() if diag_dict[s].dim() == 0: @@ -219,8 +219,8 @@ def Watson_mass_at_2(self): else: m_dict[s + 1] = ZZ(L.dim() - 1) // ZZ(2) - nu_dict = dict((j, n_dict[j + 1] - 2 * m_dict[j + 1]) - for j in range(s_min, s_max + 1)) + nu_dict = {j: n_dict[j + 1] - 2 * m_dict[j + 1] + for j in range(s_min, s_max + 1)} nu_dict[s_max + 1] = 0 # Step 3: Compute the e_j dictionary @@ -280,8 +280,8 @@ def Kitaoka_mass_at_2(self): s_max = max(scale_list) # Step 1: Compute dictionaries of the diagonal block and 2x2 block for each scale - diag_dict = dict((i, Null_Form) for i in range(s_min - 2, s_max + 4)) # Initialize with the zero form - dim2_dict = dict((i, Null_Form) for i in range(s_min, s_max + 4)) # Initialize with the zero form + diag_dict = {i: Null_Form for i in range(s_min - 2, s_max + 4)} # Initialize with the zero form + dim2_dict = {i: Null_Form for i in range(s_min, s_max + 4)} # Initialize with the zero form for s, L in Jordan_Blocks: i = 0 while i < L.dim() - 1 and L[i, i + 1] == 0: # Find where the 2x2 blocks start diff --git a/src/sage/quadratic_forms/ternary_qf.py b/src/sage/quadratic_forms/ternary_qf.py index 2f3a57fa713..2808c04548f 100644 --- a/src/sage/quadratic_forms/ternary_qf.py +++ b/src/sage/quadratic_forms/ternary_qf.py @@ -921,7 +921,7 @@ def find_p_neighbor_from_vec(self, p, v, mat=False): Test that it works with (0, 0, 1):: - sage: Q.find_p_neighbor_from_vec(3, (0,0,1)) + sage: Q.find_p_neighbor_from_vec(3, (0,0,1)) # needs sage.libs.pari Ternary quadratic form with integer coefficients: [1 3 3] [-2 0 -1] diff --git a/src/sage/rings/asymptotic/asymptotic_expansion_generators.py b/src/sage/rings/asymptotic/asymptotic_expansion_generators.py index 9a27c9d61eb..61d8238332d 100644 --- a/src/sage/rings/asymptotic/asymptotic_expansion_generators.py +++ b/src/sage/rings/asymptotic/asymptotic_expansion_generators.py @@ -604,7 +604,7 @@ def SingularityAnalysis(var, zeta=1, alpha=0, beta=0, delta=0, precision=None, normalized=True): r""" Return the asymptotic expansion of the coefficients of - an power series with specified pole and logarithmic singularity. + a power series with specified pole and logarithmic singularity. More precisely, this extracts the `n`-th coefficient diff --git a/src/sage/rings/asymptotic/growth_group_cartesian.py b/src/sage/rings/asymptotic/growth_group_cartesian.py index 447c25fa64d..6613c5bdf32 100644 --- a/src/sage/rings/asymptotic/growth_group_cartesian.py +++ b/src/sage/rings/asymptotic/growth_group_cartesian.py @@ -1193,7 +1193,7 @@ def __invert__(self): OUTPUT: - An growth element. + A growth element. .. NOTE:: diff --git a/src/sage/rings/bernoulli_mod_p.pyx b/src/sage/rings/bernoulli_mod_p.pyx index e9bf4fbf358..ee73d6ad209 100644 --- a/src/sage/rings/bernoulli_mod_p.pyx +++ b/src/sage/rings/bernoulli_mod_p.pyx @@ -23,6 +23,8 @@ AUTHOR: # https://www.gnu.org/licenses/ # **************************************************************************** +from sage.arith.misc import is_prime, primitive_root + cimport sage.rings.fast_arith import sage.rings.fast_arith cdef sage.rings.fast_arith.arith_int arith_int @@ -135,12 +137,12 @@ def bernoulli_mod_p(int p): if p <= 2: raise ValueError("p (=%s) must be a prime >= 3" % p) - if not sage.arith.all.is_prime(p): + if not is_prime(p): raise ValueError("p (=%s) must be a prime" % p) cdef int g, gSqr, gInv, gInvSqr, isOdd - g = sage.arith.all.primitive_root(p) + g = primitive_root(p) gInv = arith_int.c_inverse_mod_int(g, p) gSqr = (( g) * g) % p gInvSqr = (( gInv) * gInv) % p @@ -303,7 +305,7 @@ def bernoulli_mod_p_single(long p, long k): if p <= 2: raise ValueError("p (=%s) must be a prime >= 3" % p) - if not sage.arith.all.is_prime(p): + if not is_prime(p): raise ValueError("p (=%s) must be a prime" % p) cdef long x = bernmm_bern_modp(p, k) diff --git a/src/sage/rings/cfinite_sequence.py b/src/sage/rings/cfinite_sequence.py index 4d9353e57b8..48d585384f6 100644 --- a/src/sage/rings/cfinite_sequence.py +++ b/src/sage/rings/cfinite_sequence.py @@ -89,9 +89,8 @@ from numbers import Integral -from sage.categories.fields import Fields +from sage.categories.rings import Rings from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass -from sage.rings.ring import CommutativeRing from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -100,6 +99,7 @@ from sage.rings.power_series_ring import PowerSeriesRing from sage.rings.fraction_field import FractionField from sage.structure.element import FieldElement, parent +from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation from sage.interfaces.gp import Gp @@ -110,7 +110,7 @@ def CFiniteSequences(base_ring, names=None, category=None): r""" - Return the ring of C-Finite sequences. + Return the commutative ring of C-Finite sequences. The ring is defined over a base ring (`\ZZ` or `\QQ` ) and each element is represented by its ordinary generating function (ogf) @@ -154,15 +154,15 @@ def CFiniteSequences(base_ring, names=None, category=None): elif len(names) > 1: raise NotImplementedError("Multidimensional o.g.f. not implemented.") if category is None: - category = Fields() - if not (base_ring in (QQ, ZZ)): + category = Rings().Commutative() + if base_ring not in [QQ, ZZ]: raise ValueError("O.g.f. base not rational.") polynomial_ring = PolynomialRing(base_ring, names) return CFiniteSequences_generic(polynomial_ring, category) class CFiniteSequence(FieldElement, - metaclass=InheritComparisonClasscallMetaclass): + metaclass=InheritComparisonClasscallMetaclass): r""" Create a C-finite sequence given its ordinary generating function. @@ -174,7 +174,7 @@ class CFiniteSequence(FieldElement, OUTPUT: - - A CFiniteSequence object + A CFiniteSequence object EXAMPLES:: @@ -247,7 +247,7 @@ class CFiniteSequence(FieldElement, @staticmethod def __classcall_private__(cls, ogf): r""" - Ensures that elements created by :class:`CFiniteSequence` have the same + Ensure that elements created by :class:`CFiniteSequence` have the same parent than the ones created by the parent itself and follow the category framework (they should be instance of :class:`CFiniteSequences` automatic element class). @@ -299,9 +299,8 @@ def __classcall_private__(cls, ogf): sage: f4.parent() The ring of C-Finite sequences in y over Rational Field """ - br = ogf.base_ring() - if not (br in (QQ, ZZ)): + if br not in [QQ, ZZ]: br = QQ # if the base ring of the o.g.f is not QQ, we force it to QQ and see if the o.g.f converts nicely # trying to figure out the ogf variables @@ -388,7 +387,6 @@ def __init__(self, parent, ogf): # determine start values (may be different from _get_item_ values) alen = max(self._deg, num.degree() + 1) R = LaurentSeriesRing(br, parent.variable_name(), default_prec=alen) - rem = num % den if den != 1: self._a = R(num / den).list() else: @@ -400,7 +398,7 @@ def __init__(self, parent, ogf): self._ogf = ogf - def _repr_(self): + def _repr_(self) -> str: """ Return textual definition of sequence. @@ -414,10 +412,8 @@ def _repr_(self): if self._deg == 0: if self.ogf() == 0: return 'Constant infinite sequence 0.' - else: - return 'Finite sequence ' + str(self._a) + ', offset = ' + str(self._off) - else: - return 'C-finite sequence, generated by ' + str(self.ogf()) + return 'Finite sequence ' + str(self._a) + ', offset = ' + str(self._off) + return 'C-finite sequence, generated by ' + str(self.ogf()) def __hash__(self): r""" @@ -656,7 +652,8 @@ def __getitem__(self, key): if isinstance(key, slice): m = max(key.start, key.stop) return [self[ii] for ii in range(*key.indices(m + 1))] - elif isinstance(key, Integral): + + if isinstance(key, Integral): n = key - self._off if n < 0: return 0 @@ -679,8 +676,8 @@ def __getitem__(self, key): den = P((den * nden).list()[::2]) n //= 2 return wp + num[0] / den[0] - else: - raise TypeError("invalid argument type") + + raise TypeError("invalid argument type") def ogf(self): """ @@ -726,14 +723,14 @@ def denominator(self): """ return self.ogf().denominator() - def recurrence_repr(self): + def recurrence_repr(self) -> str: """ Return a string with the recurrence representation of the C-finite sequence. OUTPUT: - - A string + A string EXAMPLES:: @@ -892,7 +889,7 @@ def closed_form(self, n='n'): return expr -class CFiniteSequences_generic(CommutativeRing, UniqueRepresentation): +class CFiniteSequences_generic(Parent, UniqueRepresentation): r""" The class representing the ring of C-Finite Sequences @@ -912,13 +909,13 @@ class CFiniteSequences_generic(CommutativeRing, UniqueRepresentation): def __init__(self, polynomial_ring, category): r""" - Create the ring of CFiniteSequences over ``base_ring`` + Create the ring of CFiniteSequences over ``base_ring``. INPUT: - ``base_ring`` -- the base ring for the o.g.f (either ``QQ`` or ``ZZ``) - ``names`` -- an iterable of variables (should contain only one variable) - - ``category`` -- the category of the ring (default: ``Fields()``) + - ``category`` -- the category of the ring (default: ``Rings().Commutative()``) TESTS:: @@ -940,11 +937,14 @@ def __init__(self, polynomial_ring, category): base_ring = polynomial_ring.base_ring() self._polynomial_ring = polynomial_ring self._fraction_field = FractionField(self._polynomial_ring) - CommutativeRing.__init__(self, base_ring, self._polynomial_ring.gens(), category) + if category is None: + category = Rings().Commutative() + Parent.__init__(self, base_ring, names=self._polynomial_ring.gens(), + category=category) def _repr_(self): r""" - Return the string representation of ``self`` + Return the string representation of ``self``. EXAMPLES:: @@ -956,7 +956,7 @@ def _repr_(self): def _element_constructor_(self, ogf): r""" - Construct a C-Finite Sequence + Construct a C-Finite Sequence. INPUT: @@ -986,9 +986,9 @@ def _element_constructor_(self, ogf): ogf = self.fraction_field()(ogf) return self.element_class(self, ogf) - def ngens(self): + def ngens(self) -> int: r""" - Return the number of generators of ``self`` + Return the number of generators of ``self``. EXAMPLES:: @@ -1026,6 +1026,18 @@ def gen(self, i=0): raise ValueError("{} has only one generator (i=0)".format(self)) return self.polynomial_ring().gen() + def gens(self) -> tuple: + """ + Return the generators of ``self``. + + EXAMPLES:: + + sage: C. = CFiniteSequences(QQ) + sage: C.gens() + (x,) + """ + return (self.gen(0),) + def an_element(self): r""" Return an element of C-Finite Sequences. @@ -1043,7 +1055,7 @@ def an_element(self): x = self.gen() return self((2 - x) / (1 - x - x**2)) - def __contains__(self, x): + def __contains__(self, x) -> bool: """ Return ``True`` if x is an element of ``CFiniteSequences`` or canonically coerces to this ring. @@ -1194,7 +1206,7 @@ def guess(self, sequence, algorithm='sage'): sage: r = C.guess([1,2,3,4,5]) Traceback (most recent call last): ... - ValueError: Sequence too short for guessing. + ValueError: sequence too short for guessing With Berlekamp-Massey, if an odd number of values is given, the last one is dropped. So with an odd number of values the result may not generate the last value:: @@ -1205,10 +1217,11 @@ def guess(self, sequence, algorithm='sage'): [1, 2, 4, 8, 16] """ S = self.polynomial_ring() + if algorithm == 'bm': from sage.matrix.berlekamp_massey import berlekamp_massey if len(sequence) < 2: - raise ValueError('Sequence too short for guessing.') + raise ValueError('sequence too short for guessing') R = PowerSeriesRing(QQ, 'x') if len(sequence) % 2: sequence.pop() @@ -1217,10 +1230,11 @@ def guess(self, sequence, algorithm='sage'): numerator = R(S(sequence) * denominator, prec=l).truncate() return CFiniteSequence(numerator / denominator) - elif algorithm == 'pari': + + if algorithm == 'pari': global _gp if len(sequence) < 6: - raise ValueError('Sequence too short for guessing.') + raise ValueError('sequence too short for guessing') if _gp is None: _gp = Gp() _gp("ggf(v)=local(l,m,p,q,B);l=length(v);B=floor(l/2);\ @@ -1236,37 +1250,35 @@ def guess(self, sequence, algorithm='sage'): den = S(sage_eval(_gp.eval("Vec(denominator(gf))"))[::-1]) if num == 0: return 0 - else: - return CFiniteSequence(num / den) - else: - from sage.matrix.constructor import matrix - from sage.arith.misc import integer_ceil as ceil - from numpy import trim_zeros - seq = sequence[:] - while seq and sequence[-1] == 0: - seq.pop() - l = len(seq) - if l == 0: - return 0 - if l < 6: - raise ValueError('Sequence too short for guessing.') - - hl = ceil(ZZ(l) / 2) - A = matrix([sequence[k: k + hl] for k in range(hl)]) - K = A.kernel() - if K.dimension() == 0: - return 0 - R = PolynomialRing(QQ, 'x') - den = R(trim_zeros(K.basis()[-1].list()[::-1])) - if den == 1: - return 0 - offset = next((i for i, x in enumerate(sequence) if x), None) - S = PowerSeriesRing(QQ, 'x', default_prec=l - offset) - num = S(R(sequence) * den).truncate(ZZ(l) // 2 + 1) - if num == 0 or sequence != S(num / den).list(): - return 0 - else: - return CFiniteSequence(num / den) + return CFiniteSequence(num / den) + + from sage.matrix.constructor import matrix + from sage.arith.misc import integer_ceil as ceil + from numpy import trim_zeros + seq = sequence[:] + while seq and sequence[-1] == 0: + seq.pop() + l = len(seq) + if l == 0: + return 0 + if l < 6: + raise ValueError('sequence too short for guessing') + + hl = ceil(ZZ(l) / 2) + A = matrix([sequence[k: k + hl] for k in range(hl)]) + K = A.kernel() + if K.dimension() == 0: + return 0 + R = PolynomialRing(QQ, 'x') + den = R(trim_zeros(K.basis()[-1].list()[::-1])) + if den == 1: + return 0 + offset = next((i for i, x in enumerate(sequence) if x), None) + S = PowerSeriesRing(QQ, 'x', default_prec=l - offset) + num = S(R(sequence) * den).truncate(ZZ(l) // 2 + 1) + if num == 0 or sequence != S(num / den).list(): + return 0 + return CFiniteSequence(num / den) r""" diff --git a/src/sage/rings/complex_interval.pyx b/src/sage/rings/complex_interval.pyx index e804964f501..4b9e7f2aefa 100644 --- a/src/sage/rings/complex_interval.pyx +++ b/src/sage/rings/complex_interval.pyx @@ -290,7 +290,7 @@ cdef class ComplexIntervalFieldElement(FieldElement): Exact and nearly exact points are still visible:: - sage: # needs sage.plot + sage: # needs sage.plot sage.symbolic sage: plot(CIF(pi, 1), color='red') + plot(CIF(1, e), color='purple') + plot(CIF(-1, -1)) Graphics object consisting of 6 graphics primitives diff --git a/src/sage/rings/continued_fraction.py b/src/sage/rings/continued_fraction.py index a813816ac50..0021dc2745d 100644 --- a/src/sage/rings/continued_fraction.py +++ b/src/sage/rings/continued_fraction.py @@ -208,12 +208,20 @@ import numbers import sage.rings.abc + +from sage.misc.lazy_import import lazy_import from sage.rings.infinity import Infinity from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.structure.richcmp import rich_to_bool, richcmp_method from sage.structure.sage_object import SageObject +lazy_import('sage.combinat.words.abstract_word', 'Word_class') +lazy_import('sage.combinat.words.finite_word', 'FiniteWord_class') +lazy_import('sage.combinat.words.infinite_word', 'InfiniteWord_class') +lazy_import('sage.combinat.words.word', 'Word') + + ZZ_0 = Integer(0) ZZ_1 = Integer(1) ZZ_m1 = Integer(-1) @@ -2490,7 +2498,10 @@ def continued_fraction_list(x, type="std", partial_convergents=False, cf = None - from sage.rings.real_mpfr import RealLiteral + try: + from sage.rings.real_mpfr import RealLiteral + except ImportError: + RealLiteral = () if isinstance(x, RealLiteral): from sage.rings.real_mpfi import RealIntervalField x = RealIntervalField(x.prec())(x) @@ -2661,7 +2672,6 @@ def continued_fraction(x, value=None): pass # input for finite or ultimately periodic partial quotient expansion - from sage.combinat.words.finite_word import FiniteWord_class if isinstance(x, FiniteWord_class): x = list(x) @@ -2675,12 +2685,10 @@ def continued_fraction(x, value=None): return ContinuedFraction_periodic(x1, x2) # input for infinite partial quotient expansion - from sage.combinat.words.infinite_word import InfiniteWord_class from sage.misc.lazy_list import lazy_list_generic if isinstance(x, (lazy_list_generic, InfiniteWord_class)): return ContinuedFraction_infinite(x, value) - from sage.combinat.words.abstract_word import Word_class if isinstance(x, Word_class): raise ValueError("word with unknown length cannot be converted " "to continued fractions") diff --git a/src/sage/rings/derivation.py b/src/sage/rings/derivation.py index 2cd1bc1b1aa..d7d4fe6ebdf 100644 --- a/src/sage/rings/derivation.py +++ b/src/sage/rings/derivation.py @@ -1,7 +1,7 @@ r""" Derivations -Let `A` be a ring and `B` be an bimodule over `A`. +Let `A` be a ring and `B` be a bimodule over `A`. A derivation `d : A \to B` is an additive map that satisfies the Leibniz rule @@ -281,7 +281,7 @@ def __init__(self, domain, codomain, twist=None): if twist is not None: if not (isinstance(twist, Map) and twist.category_for().is_subcategory(Rings())): - raise TypeError("the twisting homomorphism must be an homomorphism of rings") + raise TypeError("the twisting homomorphism must be a homomorphism of rings") if twist.domain() is not domain: map = twist.domain().coerce_map_from(domain) if map is None: @@ -1249,7 +1249,7 @@ def precompose(self, morphism): sage: D.precompose(D) Traceback (most recent call last): ... - TypeError: you must give an homomorphism of rings + TypeError: you must give a homomorphism of rings TESTS:: @@ -1266,7 +1266,7 @@ def precompose(self, morphism): else: raise TypeError("the given ring does not coerce to the domain of the derivation") elif not (isinstance(morphism, Map) and morphism.category_for().is_subcategory(Rings())): - raise TypeError("you must give an homomorphism of rings") + raise TypeError("you must give a homomorphism of rings") M = RingDerivationModule(morphism.domain(), parent.defining_morphism() * morphism) arg = [ ] for x in M.dual_basis(): @@ -1316,7 +1316,7 @@ def postcompose(self, morphism): sage: Dx.precompose(Dy) Traceback (most recent call last): ... - TypeError: you must give an homomorphism of rings + TypeError: you must give a homomorphism of rings """ parent = self.parent() @@ -1326,7 +1326,7 @@ def postcompose(self, morphism): else: raise TypeError("the codomain of the derivation does not coerce to the given ring") elif not (isinstance(morphism, Map) and morphism.category_for().is_subcategory(Rings())): - raise TypeError("you must give an homomorphism of rings") + raise TypeError("you must give a homomorphism of rings") M = RingDerivationModule(parent.domain(), morphism * parent.defining_morphism()) arg = [ ] for x in M.dual_basis(): @@ -2281,7 +2281,7 @@ def precompose(self, morphism): else: raise TypeError("the given ring does not coerce to the domain of the derivation") elif not (isinstance(morphism, Map) and morphism.category_for().is_subcategory(Rings())): - raise TypeError("you must give an homomorphism of rings") + raise TypeError("you must give a homomorphism of rings") M = RingDerivationModule(morphism.domain(), parent.defining_morphism() * morphism, parent.twisting_morphism() * morphism) return M(self._scalar) @@ -2324,7 +2324,7 @@ def postcompose(self, morphism): else: raise TypeError("the codomain of the derivation does not coerce to the given ring") elif not (isinstance(morphism, Map) and morphism.category_for().is_subcategory(Rings())): - raise TypeError("you must give an homomorphism of rings") + raise TypeError("you must give a homomorphism of rings") M = RingDerivationModule(parent.domain(), morphism * parent.defining_morphism(), morphism * parent.twisting_morphism()) return M(morphism(self._scalar)) diff --git a/src/sage/rings/finite_rings/element_base.pyx b/src/sage/rings/finite_rings/element_base.pyx index 8af0867a9f5..ab029287ba6 100755 --- a/src/sage/rings/finite_rings/element_base.pyx +++ b/src/sage/rings/finite_rings/element_base.pyx @@ -586,8 +586,8 @@ cdef class FinitePolyExtElement(FiniteRingElement): Finite Field in a of size 19^2 sage: b = a**20 sage: p = FinitePolyExtElement.charpoly(b, "x", algorithm="pari") - sage: q = FinitePolyExtElement.charpoly(b, "x", algorithm="matrix") # needs sage.modules - sage: q == p # needs sage.modules + sage: q = FinitePolyExtElement.charpoly(b, "x", algorithm="matrix") # needs sage.modules + sage: q == p # needs sage.modules True sage: p x^2 + 15*x + 4 diff --git a/src/sage/rings/finite_rings/element_givaro.pyx b/src/sage/rings/finite_rings/element_givaro.pyx index 7619ec7185f..a4727e3311d 100644 --- a/src/sage/rings/finite_rings/element_givaro.pyx +++ b/src/sage/rings/finite_rings/element_givaro.pyx @@ -56,10 +56,11 @@ from cysignals.signals cimport sig_on, sig_off from cypari2.paridecl cimport * +import sage.arith.misc + from sage.misc.randstate cimport current_randstate from sage.rings.finite_rings.element_pari_ffelt cimport FiniteFieldElement_pari_ffelt from sage.structure.richcmp cimport richcmp -import sage.arith.all from cypari2.gen cimport Gen from cypari2.stack cimport clear_stack @@ -414,9 +415,6 @@ cdef class Cache_givaro(Cache_base): # Reduce to pari e = e.__pari__() - elif isinstance(e, sage.libs.gap.element.GapElement_FiniteField): - return e.sage(ring=self.parent) - elif isinstance(e, GapElement): from sage.libs.gap.libgap import libgap return libgap(e).sage(ring=self.parent) @@ -434,6 +432,13 @@ cdef class Cache_givaro(Cache_base): return ret else: + try: + from sage.libs.gap.element import GapElement_FiniteField + except ImportError: + pass + else: + if isinstance(e, GapElement_FiniteField): + return e.sage(ring=self.parent) raise TypeError("unable to coerce %r" % type(e)) cdef GEN t @@ -524,7 +529,7 @@ cdef class Cache_givaro(Cache_base): INPUT: - - ``n`` -- integer representation of an finite field element + - ``n`` -- integer representation of a finite field element OUTPUT: @@ -1568,7 +1573,7 @@ cdef class FiniteField_givaroElement(FinitePolyExtElement): raise ArithmeticError("Multiplicative order of 0 not defined.") n = (self._cache).order_c() - 1 order = Integer(1) - for p, e in sage.arith.all.factor(n): + for p, e in sage.arith.misc.factor(n): # Determine the power of p that divides the order. a = self**(n / (p**e)) while a != 1: diff --git a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx index 60d275ea5ae..bb490c163a8 100644 --- a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx +++ b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx @@ -274,7 +274,6 @@ cdef class Cache_ntl_gf2e(Cache_base): cdef FiniteField_ntl_gf2eElement x cdef FiniteField_ntl_gf2eElement g cdef Py_ssize_t i - from sage.libs.gap.element import GapElement_FiniteField if is_IntegerMod(e): e = e.lift() @@ -334,14 +333,18 @@ cdef class Cache_ntl_gf2e(Cache_base): # Reduce to pari e = e.__pari__() - elif isinstance(e, GapElement_FiniteField): - return e.sage(ring=self._parent) - elif isinstance(e, GapElement): from sage.libs.gap.libgap import libgap return libgap(e).sage(ring=self._parent) else: + try: + from sage.libs.gap.element import GapElement_FiniteField + except ImportError: + pass + else: + if isinstance(e, GapElement_FiniteField): + return e.sage(ring=self._parent) raise TypeError("unable to coerce %r" % type(e)) cdef GEN t diff --git a/src/sage/rings/finite_rings/element_pari_ffelt.pyx b/src/sage/rings/finite_rings/element_pari_ffelt.pyx index ca262f6f668..4f37f6c3043 100644 --- a/src/sage/rings/finite_rings/element_pari_ffelt.pyx +++ b/src/sage/rings/finite_rings/element_pari_ffelt.pyx @@ -611,6 +611,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): EXAMPLES:: + sage: # needs sage.modules sage: k. = GF(2^20, impl='pari_ffelt') sage: e = k.random_element() sage: f = loads(dumps(e)) diff --git a/src/sage/rings/finite_rings/finite_field_givaro.py b/src/sage/rings/finite_rings/finite_field_givaro.py index 2dd96beeb34..9f6abdb40b4 100644 --- a/src/sage/rings/finite_rings/finite_field_givaro.py +++ b/src/sage/rings/finite_rings/finite_field_givaro.py @@ -462,7 +462,7 @@ def int_to_log(self, n): INPUT: - - ``n`` -- integer representation of an finite field element + - ``n`` -- integer representation of a finite field element OUTPUT: diff --git a/src/sage/rings/finite_rings/galois_group.py b/src/sage/rings/finite_rings/galois_group.py index 293803f1e98..f11b72bc681 100644 --- a/src/sage/rings/finite_rings/galois_group.py +++ b/src/sage/rings/finite_rings/galois_group.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.modules sage.rings.finite_rings r""" Galois groups of Finite Fields """ @@ -109,7 +110,7 @@ def _element_constructor_(self, x, check=True): Frob^2 sage: G(G.gens()[0]) Frob - sage: G([(1,3,2)]) + sage: G([(1,3,2)]) # needs sage.libs.gap Frob^2 sage: G(k.hom(k.gen()^3, k)) Frob diff --git a/src/sage/rings/finite_rings/residue_field.pyx b/src/sage/rings/finite_rings/residue_field.pyx index e84b303769a..b79416eb1d7 100644 --- a/src/sage/rings/finite_rings/residue_field.pyx +++ b/src/sage/rings/finite_rings/residue_field.pyx @@ -128,7 +128,7 @@ First over a small non-prime field:: Residue field in ubar of Fractional ideal (47, 517/55860*u^5 + 235/3724*u^4 + 9829/13965*u^3 + 54106/13965*u^2 + 64517/27930*u + 755696/13965) - sage: I.groebner_basis() + sage: I.groebner_basis() # needs sage.libs.singular [X + (-19*ubar^2 - 5*ubar - 17)*Y] And now over a large prime field:: @@ -144,11 +144,11 @@ And now over a large prime field:: 4398046511119 sage: S. = PolynomialRing(Rf, order='lex') sage: I = ideal([2*X - Y^2, Y + Z]) - sage: I.groebner_basis() + sage: I.groebner_basis() # needs sage.libs.singular [X + 2199023255559*Z^2, Y + Z] sage: S. = PolynomialRing(Rf, order='deglex') sage: I = ideal([2*X - Y^2, Y + Z]) - sage: I.groebner_basis() + sage: I.groebner_basis() # needs sage.libs.singular [Z^2 + 4398046511117*X, Y + Z] """ diff --git a/src/sage/rings/finite_rings/residue_field_pari_ffelt.pyx b/src/sage/rings/finite_rings/residue_field_pari_ffelt.pyx index f21a3b8d9bb..e9962c3ccde 100644 --- a/src/sage/rings/finite_rings/residue_field_pari_ffelt.pyx +++ b/src/sage/rings/finite_rings/residue_field_pari_ffelt.pyx @@ -118,7 +118,7 @@ class ResidueFiniteField_pari_ffelt(ResidueField_generic, FiniteField_pari_ffelt sage: R. = GF(5)[]; P = R.ideal(4*t^12 + 3*t^11 + 4*t^10 + t^9 + t^8 + 3*t^7 + 2*t^6 + 3*t^4 + t^3 + 3*t^2 + 2) sage: k. = P.residue_field() - sage: V = k.vector_space(map=False); v = V([1,2,3,4,5,6,7,8,9,0,1,2]); k(v) # indirect doctest # needs sage.modules + sage: V = k.vector_space(map=False); v = V([1,2,3,4,5,6,7,8,9,0,1,2]); k(v) # indirect doctest # needs sage.modules 2*a^11 + a^10 + 4*a^8 + 3*a^7 + 2*a^6 + a^5 + 4*a^3 + 3*a^2 + 2*a + 1 """ try: diff --git a/src/sage/rings/function_field/function_field_rational.py b/src/sage/rings/function_field/function_field_rational.py index e763a673a15..226d87d084c 100644 --- a/src/sage/rings/function_field/function_field_rational.py +++ b/src/sage/rings/function_field/function_field_rational.py @@ -138,7 +138,7 @@ def __init__(self, constant_field, names, category=None): sage: K. = FunctionField(CC); K # needs sage.rings.real_mpfr Rational function field in t over Complex Field with 53 bits of precision - sage: TestSuite(K).run() # long time (5s) # needs sage.rings.real_mpfr + sage: TestSuite(K).run() # long time (5s) # needs sage.rings.real_mpfr sage: FunctionField(QQ[I], 'alpha') # needs sage.rings.number_field Rational function field in alpha over diff --git a/src/sage/rings/generic.py b/src/sage/rings/generic.py index 83f923cee5c..99bf690bef6 100644 --- a/src/sage/rings/generic.py +++ b/src/sage/rings/generic.py @@ -20,6 +20,7 @@ class ProductTree: (the famous *Fast* Fourier Transform) can be implemented as follows using the :meth:`remainders` method of this class:: + sage: # needs sage.rings.finite_rings sage: from sage.rings.generic import ProductTree sage: F = GF(65537) sage: a = F(1111) @@ -62,6 +63,7 @@ class ProductTree: :: + sage: # needs sage.libs.pari sage: vs = prime_range(100) sage: tree = ProductTree(vs) sage: tree.root().factor() @@ -71,7 +73,7 @@ class ProductTree: We can access the individual layers of the tree:: - sage: tree.layers + sage: tree.layers # needs sage.libs.pari [(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97), (6, 35, 143, 323, 667, 1147, 1763, 2491, 3599, 4757, 5767, 7387, 97), (210, 46189, 765049, 4391633, 17120443, 42600829, 97), @@ -87,8 +89,8 @@ def __init__(self, leaves): EXAMPLES:: sage: from sage.rings.generic import ProductTree - sage: vs = prime_range(100) - sage: tree = ProductTree(vs) + sage: vs = prime_range(100) # needs sage.libs.pari + sage: tree = ProductTree(vs) # needs sage.libs.pari """ V = tuple(leaves) self.layers = [V] @@ -182,6 +184,7 @@ def remainders(self, x): EXAMPLES:: + sage: # needs sage.libs.pari sage: from sage.rings.generic import ProductTree sage: vs = prime_range(100) sage: tree = ProductTree(vs) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index c990c200e57..415b0ff7d80 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -4076,7 +4076,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): """ if self.is_zero(): raise ArithmeticError("support of 0 not defined") - return sage.arith.all.prime_factors(self) + from sage.arith.misc import prime_factors + + return prime_factors(self) def coprime_integers(self, m): """ @@ -7539,7 +7541,7 @@ def _check_global_dummy_Integer(): # It operates on the following principles: # # - The pool starts out empty. -# - When an new integer is needed, one from the pool is returned +# - When a new integer is needed, one from the pool is returned # if available, otherwise a new Integer object is created # - When an integer is collected, it will add it to the pool # if there is room, otherwise it will be deallocated. diff --git a/src/sage/rings/localization.py b/src/sage/rings/localization.py index 20c090da681..ea7534349fa 100644 --- a/src/sage/rings/localization.py +++ b/src/sage/rings/localization.py @@ -584,7 +584,7 @@ class Localization(IntegralDomain, UniqueRepresentation): Accordingly, this class is inherited from :class:`IntegralDomain` and can only be used in that context. Furthermore, the base ring should support :meth:`sage.structure.element.CommutativeRingElement.divides` and the exact division operator `//` (:meth:`sage.structure.element.Element.__floordiv__`) in order to guarantee - an successful application. + a successful application. INPUT: diff --git a/src/sage/rings/morphism.pyx b/src/sage/rings/morphism.pyx index a9cb8eda29e..c65f75a248c 100644 --- a/src/sage/rings/morphism.pyx +++ b/src/sage/rings/morphism.pyx @@ -1255,7 +1255,7 @@ cdef class RingHomomorphism(RingMap): Ideals in quotient rings over ``QQbar`` do not support reduction yet, so the graph is constructed in the ambient ring instead:: - sage: # needs sage.rings.number_field + sage: # needs sage.libs.singular sage.rings.number_field sage: A. = QQbar['z,w'].quotient('z*w - 1') sage: B. = QQbar['x,y'].quotient('2*x^2 + y^2 - 1') sage: f = A.hom([QQbar(2).sqrt()*x + QQbar(I)*y, @@ -1447,7 +1447,7 @@ cdef class RingHomomorphism(RingMap): An isomorphism between the algebraic torus and the circle over a number field:: - sage: # needs sage.rings.number_field + sage: # needs sage.libs.singular sage.rings.number_field sage: K. = QuadraticField(-1) sage: A. = K['z,w'].quotient('z*w - 1') sage: B. = K['x,y'].quotient('x^2 + y^2 - 1') diff --git a/src/sage/rings/multi_power_series_ring.py b/src/sage/rings/multi_power_series_ring.py index 3d96666e222..8ceaa9c5154 100644 --- a/src/sage/rings/multi_power_series_ring.py +++ b/src/sage/rings/multi_power_series_ring.py @@ -204,24 +204,29 @@ # http://www.gnu.org/licenses/ #***************************************************************************** +import sage.misc.latex as latex -from sage.rings.ring import CommutativeRing -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.infinity import infinity +from sage.rings.multi_power_series_ring_element import MPowerSeries from sage.rings.polynomial.polynomial_ring import is_PolynomialRing +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing from sage.rings.polynomial.term_order import TermOrder from sage.rings.power_series_ring import PowerSeriesRing, PowerSeriesRing_generic, is_PowerSeriesRing - -from sage.rings.infinity import infinity -import sage.misc.latex as latex +from sage.rings.ring import CommutativeRing from sage.structure.nonexact import Nonexact -from sage.rings.multi_power_series_ring_element import MPowerSeries from sage.categories.commutative_rings import CommutativeRings _CommutativeRings = CommutativeRings() + from sage.categories.integral_domains import IntegralDomains _IntegralDomains = IntegralDomains() +try: + from sage.rings.laurent_series_ring import LaurentSeriesRing +except ImportError: + LaurentSeriesRing = () + def is_MPowerSeriesRing(x): """ @@ -731,8 +736,8 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): return False if all(v == 0 for v in im_gens): return True - from .laurent_series_ring import is_LaurentSeriesRing - if is_MPowerSeriesRing(codomain) or is_PowerSeriesRing(codomain) or is_LaurentSeriesRing(codomain): + + if is_MPowerSeriesRing(codomain) or is_PowerSeriesRing(codomain) or isinstance(codomain, LaurentSeriesRing): try: B = all(v.valuation() > 0 or v.is_nilpotent() for v in im_gens) except NotImplementedError: diff --git a/src/sage/rings/number_field/S_unit_solver.py b/src/sage/rings/number_field/S_unit_solver.py index 68ca166f6df..4b6b201375f 100644 --- a/src/sage/rings/number_field/S_unit_solver.py +++ b/src/sage/rings/number_field/S_unit_solver.py @@ -1071,7 +1071,7 @@ def reduction_step_complex_case(place, B0, list_of_gens, torsion_gen, c13): A = A.transpose() - # Note that l is the an lower bound on the square of the magnitude of the shortest non-zero vector in the lattice generated by A + # Note that l is the lower bound on the square of the magnitude of the shortest non-zero vector in the lattice generated by A l = minimal_vector(A, zero_vector(ZZ,n+1)) # Checking hypotheses of Lemma 5.3 in our paper: diff --git a/src/sage/rings/number_field/bdd_height.py b/src/sage/rings/number_field/bdd_height.py index 0681aaef58e..2b3d18a6578 100644 --- a/src/sage/rings/number_field/bdd_height.py +++ b/src/sage/rings/number_field/bdd_height.py @@ -531,7 +531,7 @@ def packet_height(n, pair, u): possible_norm_set.add(m * class_group_rep_norms[n]) bdd_ideals = bdd_norm_pr_ideal_gens(K, possible_norm_set) - # Stores it in form of an dictionary and gives lambda(g)_approx for key g + # Stores it in form of a dictionary and gives lambda(g)_approx for key g for norm in possible_norm_set: gens = bdd_ideals[norm] for g in gens: diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 77048cd3b79..6e6d0fc36e4 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -82,7 +82,6 @@ import sage.libs.ntl.all as ntl -import sage.interfaces.gap import sage.rings.complex_mpfr from sage.rings.polynomial.polynomial_element import Polynomial @@ -92,14 +91,14 @@ import sage.rings.real_double import sage.rings.real_lazy -from sage.rings.finite_rings.integer_mod import mod - - +from sage.arith.misc import euler_phi, factor, gcd, next_prime from sage.misc.fast_methods import WithEqualityById from sage.misc.functional import is_odd, lift from sage.misc.lazy_import import lazy_import from sage.misc.misc_c import prod +from sage.misc.sage_eval import sage_eval from sage.rings.infinity import Infinity +from sage.rings.finite_rings.integer_mod import mod from sage.categories.number_fields import NumberFields import sage.rings.ring @@ -204,7 +203,6 @@ def proof_flag(t): from sage.misc.latex import latex -import sage.arith.all as arith import sage.rings.infinity as infinity from sage.rings.rational import Rational from sage.rings.integer import Integer @@ -1311,7 +1309,7 @@ class NumberField_generic(WithEqualityById, number_field_base.NumberField): This example was suggested on sage-nt; see :trac:`18942`:: sage: G = DirichletGroup(80) # needs sage.modular - sage: for chi in G: # long time # needs sage.modular + sage: for chi in G: # long time # needs sage.modular ....: D = ModularSymbols(chi, 2, -1).cuspidal_subspace().new_subspace().decomposition() ....: for f in D: ....: elt = f.q_eigenform(10, 'alpha')[3] @@ -1942,7 +1940,7 @@ def _convert_from_str(self, x): sage: k('theta25^3 + (1/3)*theta25') -1/3*theta25 - 1 """ - w = sage.misc.all.sage_eval(x, locals=self.gens_dict()) + w = sage_eval(x, locals=self.gens_dict()) if not (is_Element(w) and w.parent() is self): return self(w) else: @@ -3319,6 +3317,7 @@ def conductor(self, check_abelian=True): EXAMPLES:: + sage: # needs sage.groups sage: K = CyclotomicField(27) sage: k = K.subfields(9)[0][0] sage: k.conductor() @@ -3389,6 +3388,7 @@ def dirichlet_group(self): EXAMPLES:: + sage: # needs sage.groups sage.modular sage: x = polygen(QQ, 'x') sage: K. = NumberField(x^3 + x^2 - 36*x - 4) sage: K.conductor() @@ -3398,15 +3398,16 @@ def dirichlet_group(self): Dirichlet character modulo 109 of conductor 109 mapping 6 |--> zeta3, Dirichlet character modulo 109 of conductor 109 mapping 6 |--> -zeta3 - 1] + sage: # needs sage.modular sage: K = CyclotomicField(44) sage: L = K.subfields(5)[0][0] - sage: X = L.dirichlet_group() # optional - gap_package_polycyclic - sage: X # optional - gap_package_polycyclic + sage: X = L.dirichlet_group(); X # optional - gap_package_polycyclic [Dirichlet character modulo 11 of conductor 1 mapping 2 |--> 1, Dirichlet character modulo 11 of conductor 11 mapping 2 |--> zeta5, Dirichlet character modulo 11 of conductor 11 mapping 2 |--> zeta5^2, Dirichlet character modulo 11 of conductor 11 mapping 2 |--> zeta5^3, - Dirichlet character modulo 11 of conductor 11 mapping 2 |--> -zeta5^3 - zeta5^2 - zeta5 - 1] + Dirichlet character modulo 11 of conductor 11 + mapping 2 |--> -zeta5^3 - zeta5^2 - zeta5 - 1] sage: X[4]^2 # optional - gap_package_polycyclic Dirichlet character modulo 11 of conductor 11 mapping 2 |--> zeta5^3 sage: X[4]^2 in X # optional - gap_package_polycyclic @@ -3964,10 +3965,8 @@ def primes_of_bounded_norm(self, B): from sage.rings.fast_arith import prime_range if self is QQ: - # return arith.primes(B+1) return prime_range(B + 1, algorithm="pari_isprime") else: - # P = [pp for p in arith.primes(B+1) for pp in self.primes_above(p)] P = (pp for p in prime_range(B + 1, algorithm="pari_isprime") for pp in self.primes_above(p)) P = [p for p in P if p.norm() <= B] @@ -4018,11 +4017,9 @@ def primes_of_bounded_norm_iter(self, B): from sage.rings.fast_arith import prime_range if self is QQ: - # for p in arith.primes(B+1): for p in prime_range(B + 1, algorithm="pari_isprime"): yield p else: - # for p in arith.primes(B+1): for p in prime_range(B + 1, algorithm="pari_isprime"): for pp in self.primes_above(p): if pp.norm() <= B: @@ -4135,7 +4132,7 @@ def completely_split_primes(self, B=200): from sage.rings.fast_arith import prime_range from sage.rings.finite_rings.finite_field_constructor import GF from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - from sage.arith.misc import factor + split_primes = [] for p in prime_range(B): Fp = GF(p) @@ -4532,7 +4529,8 @@ def _gap_init_(self): """ if not self.is_absolute(): raise NotImplementedError("Currently, only simple algebraic extensions are implemented in gap") - G = sage.interfaces.gap.gap + from sage.interfaces.gap import gap as G + q = self.polynomial() if q.variable_name() != 'E': return 'CallFuncList(function() local %s,E; %s:=Indeterminate(%s,"%s"); E:=AlgebraicExtension(%s,%s,"%s"); return E; end,[])' % (q.variable_name(), q.variable_name(), G(self.base_ring()).name(), q.variable_name(), G(self.base_ring()).name(), repr(self.polynomial()), str(self.gen())) @@ -4610,6 +4608,7 @@ def class_group(self, proof=None, names='c'): Class groups of Hecke polynomials tend to be very small:: + sage: # needs sage.modular sage: f = ModularForms(97, 2).T(2).charpoly() sage: f.factor() (x - 3) * (x^3 + 4*x^2 + 3*x - 1) * (x^4 - 3*x^3 - x^2 + 6*x - 1) @@ -5982,7 +5981,7 @@ def decomposition_type(self, p): sage: R. = ZZ[] sage: K. = NumberField(x^20 + 3*x^18 + 15*x^16 + 28*x^14 + 237*x^12 + 579*x^10 ....: + 1114*x^8 + 1470*x^6 + 2304*x^4 + 1296*x^2 + 729) - sage: K.is_galois() + sage: K.is_galois() # needs sage.groups True sage: K.discriminant().factor() 2^20 * 3^10 * 53^10 @@ -6149,6 +6148,7 @@ def is_galois(self): EXAMPLES:: + sage: # needs sage.groups sage: x = polygen(QQ, 'x') sage: NumberField(x^2 + 1, 'i').is_galois() True @@ -6175,6 +6175,7 @@ def is_abelian(self): EXAMPLES:: + sage: # needs sage.groups sage: x = polygen(QQ, 'x') sage: NumberField(x^2 + 1, 'i').is_abelian() True @@ -6235,6 +6236,7 @@ def galois_group(self, type=None, algorithm='pari', names=None, gc_numbering=Non EXAMPLES:: + sage: # needs sage.groups sage: x = polygen(QQ, 'x') sage: k. = NumberField(x^2 - 14) # a Galois extension sage: G = k.galois_group(); G @@ -6246,13 +6248,14 @@ def galois_group(self, type=None, algorithm='pari', names=None, gc_numbering=Non sage: G.artin_symbol(k.primes_above(3)[0]) (1,2) - sage: k. = NumberField(x^3 - x + 1) # not Galois + sage: # needs sage.groups + sage: k. = NumberField(x^3 - x + 1) # not Galois sage: G = k.galois_group(names='c'); G Galois group 3T2 (S3) with order 6 of x^3 - x + 1 sage: G.gen(0) (1,2,3)(4,5,6) - sage: NumberField(x^3 + 2*x + 1, 'a').galois_group(algorithm='magma') # optional - magma + sage: NumberField(x^3 + 2*x + 1, 'a').galois_group(algorithm='magma') # optional - magma, needs sage.groups Galois group Transitive group number 2 of degree 3 of the Number Field in a with defining polynomial x^3 + 2*x + 1 @@ -6261,6 +6264,7 @@ def galois_group(self, type=None, algorithm='pari', names=None, gc_numbering=Non :: + sage: # needs sage.groups sage: K. = NumberField(x^3 - 2) sage: L. = K.galois_closure(); L Number Field in b1 with defining polynomial x^6 + 108 @@ -6286,6 +6290,7 @@ def galois_group(self, type=None, algorithm='pari', names=None, gc_numbering=Non change in the future, so it's better to explicitly call :meth:`absolute_field` if that is the desired behavior:: + sage: # needs sage.groups sage: x = polygen(QQ) sage: K. = NumberField(x^2 + 1) sage: R. = PolynomialRing(K) @@ -6300,6 +6305,7 @@ def galois_group(self, type=None, algorithm='pari', names=None, gc_numbering=Non We check that the changes in :trac:`28782` won't break code that used v1 Galois groups:: + sage: # needs sage.groups sage: G = NumberField(x^3 - 2, 'a').galois_group(type="pari") ...DeprecationWarning: the different Galois types have been merged into one class See https://github.com/sagemath/sage/issues/28782 for details. @@ -7429,6 +7435,7 @@ def S_unit_solutions(self, S=[], prec=106, include_exponents=False, include_boun EXAMPLES:: + sage: # needs sage.rings.padics sage: x = polygen(QQ, 'x') sage: K. = NumberField(x^2 + x + 1) sage: S = K.primes_above(3) @@ -7437,7 +7444,8 @@ def S_unit_solutions(self, S=[], prec=106, include_exponents=False, include_boun You can get the exponent vectors:: - sage: K.S_unit_solutions(S, include_exponents=True) # random, due to ordering + sage: # needs sage.rings.padics + sage: K.S_unit_solutions(S, include_exponents=True) # random, due to ordering [((2, 1), (4, 0), xi + 2, -xi - 1), ((5, -1), (4, -1), 1/3*xi + 2/3, -1/3*xi + 1/3), ((5, 0), (1, 0), -xi, xi + 1), @@ -7445,6 +7453,7 @@ def S_unit_solutions(self, S=[], prec=106, include_exponents=False, include_boun And the computed bound:: + sage: # needs sage.rings.padics sage: solutions, bound = K.S_unit_solutions(S, prec=100, include_bound=True) sage: bound 7 @@ -7547,7 +7556,7 @@ def zeta(self, n=2, all=False): # First check if the degree of K is compatible # with an inclusion QQ(\zeta_n) -> K. - if sage.arith.all.euler_phi(n).divides(K.absolute_degree()): + if euler_phi(n).divides(K.absolute_degree()): w, zeta_w = self.pari_nf().nfrootsof1() w = w.sage() zeta_w = K(zeta_w) @@ -7788,17 +7797,17 @@ def valuation(self, prime): sage: x = polygen(QQ, 'x') sage: K. = NumberField(x^2 + 1) - sage: K.valuation(2) + sage: K.valuation(2) # needs sage.rings.padics 2-adic valuation It can also be unramified in ``R``:: - sage: K.valuation(3) + sage: K.valuation(3) # needs sage.rings.padics 3-adic valuation A ``prime`` that factors into pairwise distinct factors, results in an error:: - sage: K.valuation(5) + sage: K.valuation(5) # needs sage.rings.padics Traceback (most recent call last): ... ValueError: The valuation Gauss valuation induced by 5-adic valuation does not @@ -7807,12 +7816,12 @@ def valuation(self, prime): The valuation can also be selected by giving a valuation on the base ring that extends uniquely:: - sage: CyclotomicField(5).valuation(ZZ.valuation(5)) + sage: CyclotomicField(5).valuation(ZZ.valuation(5)) # needs sage.rings.padics 5-adic valuation When the extension is not unique, this does not work:: - sage: K.valuation(ZZ.valuation(5)) + sage: K.valuation(ZZ.valuation(5)) # needs sage.rings.padics Traceback (most recent call last): ... ValueError: The valuation Gauss valuation induced by 5-adic valuation does not @@ -7823,6 +7832,7 @@ def valuation(self, prime): `G` to infinity. This lets us specify which extension of the 5-adic valuation we care about in the above example:: + sage: # needs sage.rings.padics sage: R. = QQ[] sage: G5 = GaussValuation(R, QQ.valuation(5)) sage: v = K.valuation(G5.augmentation(x + 2, infinity)) @@ -7833,6 +7843,7 @@ def valuation(self, prime): Note that you get the same valuation, even if you write down the pseudo-valuation differently:: + sage: # needs sage.rings.padics sage: ww = K.valuation(G5.augmentation(x + 3, infinity)) sage: w is ww True @@ -7843,6 +7854,7 @@ def valuation(self, prime): completion, i.e., if it is not possible to write down one of the factors within the number field:: + sage: # needs sage.rings.padics sage: v = G5.augmentation(x + 3, 1) sage: K.valuation(v) [ 5-adic valuation, v(x + 3) = 1 ]-adic valuation @@ -7850,7 +7862,7 @@ def valuation(self, prime): Finally, ``prime`` can also be a fractional ideal of a number field if it singles out an extension of a `p`-adic valuation of the base field:: - sage: K.valuation(K.fractional_ideal(a + 1)) + sage: K.valuation(K.fractional_ideal(a + 1)) # needs sage.rings.padics 2-adic valuation .. SEEALSO:: @@ -9123,6 +9135,7 @@ def _galois_closure_and_embedding(self, names=None): For medium-sized Galois groups of fields with small discriminants, this computation is feasible:: + sage: # needs sage.groups sage: x = polygen(QQ, 'x') sage: K. = NumberField(x^6 + 4*x^2 + 2) sage: K.galois_group().order() @@ -9170,6 +9183,7 @@ def galois_closure(self, names=None, map=False): EXAMPLES:: + sage: # needs sage.groups sage: x = polygen(QQ, 'x') sage: K. = NumberField(x^4 - 2) sage: M = K.galois_closure('b'); M @@ -9181,12 +9195,14 @@ def galois_closure(self, names=None, map=False): :: + sage: # needs sage.groups sage: phi = K.embeddings(L)[0] sage: phi(K.0) 1/120*a2^5 + 19/60*a2 sage: phi(K.0).minpoly() x^4 - 2 + sage: # needs sage.groups sage: L, phi = K.galois_closure('b', map=True) sage: L Number Field in b with defining polynomial x^8 + 28*x^4 + 2500 @@ -9198,6 +9214,7 @@ def galois_closure(self, names=None, map=False): A cyclotomic field is already Galois:: + sage: # needs sage.groups sage: K. = NumberField(cyclotomic_polynomial(23)) sage: L. = K.galois_closure() sage: L @@ -9209,6 +9226,7 @@ def galois_closure(self, names=None, map=False): Let's make sure we're renaming correctly:: + sage: # needs sage.groups sage: K. = NumberField(x^4 - 2) sage: L, phi = K.galois_closure('cc', map=True) sage: L @@ -9293,6 +9311,7 @@ def embeddings(self, K): EXAMPLES:: + sage: # needs sage.groups sage: x = polygen(QQ, 'x') sage: K. = NumberField(x^3 - 2) sage: L. = K.galois_closure(); L @@ -10942,6 +10961,7 @@ def _gap_init_(self): TESTS:: + sage: # needs sage.libs.gap sage: K = CyclotomicField(8) sage: gap(K) # indirect doctest CF(8) @@ -10955,13 +10975,15 @@ def _gap_init_(self): a genuine representation of cyclotomic fields in the GAP interface -- see :trac:`5618`. :: + sage: # needs sage.groups sage: H = AlternatingGroup(4) sage: g = H((1,4,3)) sage: K = H.subgroup([g]) sage: z = CyclotomicField(3).an_element(); z zeta3 sage: c = K.character([1,z,z**2]); c - Character of Subgroup generated by [(1,4,3)] of (Alternating group of order 4!/2 as a permutation group) + Character of Subgroup generated by [(1,4,3)] of + (Alternating group of order 4!/2 as a permutation group) sage: c(g^2); z^2 zeta3 -zeta3 - 1 @@ -10974,10 +10996,11 @@ def _libgap_(self): TESTS:: + sage: # needs sage.libs.gap sage: K = CyclotomicField(8) - sage: K._libgap_() # needs sage.libs.gap + sage: K._libgap_() CF(8) - sage: libgap(K) # indirect doctest # needs sage.libs.gap + sage: libgap(K) # indirect doctest CF(8) """ from sage.libs.gap.libgap import libgap @@ -11610,7 +11633,7 @@ def embeddings(self, K): # zeta not defined return super().embeddings(K) else: - X = (m for m in range(n) if arith.gcd(m, n) == 1) + X = (m for m in range(n) if gcd(m, n) == 1) v = [self.hom([z**i], check=False) for i in X] else: v = [] @@ -11781,7 +11804,7 @@ def next_split_prime(self, p=2): """ n = self._n() while True: - p = arith.next_prime(p) + p = next_prime(p) if p % n == 1: return p @@ -11855,7 +11878,7 @@ def _multiplicative_order_table(self): zeta = self.zeta(n) # todo: this desperately needs to be optimized!!! for i in range(n): - t[x.polynomial()] = n // arith.GCD(m, n) # multiplicative_order of (zeta_n)**m + t[x.polynomial()] = n // gcd(m, n) # multiplicative_order of (zeta_n)**m x *= zeta m += 1 self.__multiplicative_order_table = t @@ -12278,7 +12301,7 @@ def hilbert_class_field_defining_polynomial(self, name='x'): Note that this polynomial is not the actual Hilbert class polynomial: see ``hilbert_class_polynomial``:: - sage: K.hilbert_class_polynomial() + sage: K.hilbert_class_polynomial() # needs sage.schemes x^3 + 3491750*x^2 - 5151296875*x + 12771880859375 :: @@ -12331,11 +12354,11 @@ def hilbert_class_polynomial(self, name='x'): EXAMPLES:: sage: K. = QuadraticField(-3) - sage: K.hilbert_class_polynomial() + sage: K.hilbert_class_polynomial() # needs sage.schemes x sage: K. = QuadraticField(-31) - sage: K.hilbert_class_polynomial(name='z') + sage: K.hilbert_class_polynomial(name='z') # needs sage.schemes z^3 + 39491307*z^2 - 58682638134*z + 1566028350940383 """ D = self.discriminant() @@ -12711,7 +12734,7 @@ def _splitting_classes_gens_(K, m, d): sage: from sage.rings.number_field.number_field import _splitting_classes_gens_ sage: K = CyclotomicField(101) sage: L = K.subfields(20)[0][0] - sage: L.conductor() + sage: L.conductor() # needs sage.groups 101 sage: _splitting_classes_gens_(L,101,20) # needs sage.libs.gap # optional - gap_package_polycyclic [95] @@ -12728,7 +12751,7 @@ def _splitting_classes_gens_(K, m, d): sage: L Number Field in zeta44_0 with defining polynomial x^5 - 2*x^4 - 16*x^3 + 24*x^2 + 48*x - 32 with zeta44_0 = 3.837971894457990? - sage: L.conductor() + sage: L.conductor() # needs sage.groups 11 sage: _splitting_classes_gens_(L,11,5) # needs sage.libs.gap # optional - gap_package_polycyclic [10] @@ -12748,7 +12771,7 @@ def map_Zmstar_to_Zm(h): Hgens = [] H = Zmstar.subgroup([]) p = 0 - Horder = arith.euler_phi(m) / d + Horder = euler_phi(m) / d for g in Zmstar: if H.order() == Horder: break diff --git a/src/sage/rings/number_field/totallyreal_rel.py b/src/sage/rings/number_field/totallyreal_rel.py index 47ee18456f7..9b416d2ad02 100644 --- a/src/sage/rings/number_field/totallyreal_rel.py +++ b/src/sage/rings/number_field/totallyreal_rel.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.geometry.polyhedron sage.libs.linbox sage.modules sage.rings.number_field r""" Enumeration of totally real fields: relative extensions diff --git a/src/sage/rings/padics/padic_extension_leaves.py b/src/sage/rings/padics/padic_extension_leaves.py index ef0ed071a2c..d63dc734097 100644 --- a/src/sage/rings/padics/padic_extension_leaves.py +++ b/src/sage/rings/padics/padic_extension_leaves.py @@ -303,7 +303,7 @@ class UnramifiedExtensionRingFixedMod(UnramifiedExtensionGeneric, pAdicFixedModR TESTS:: sage: R. = ZqFM(27,1000) # needs sage.libs.flint - sage: TestSuite(R).run(skip='_test_log',max_runs=4) # long time # needs sage.libs.flint + sage: TestSuite(R).run(skip='_test_log',max_runs=4) # long time # needs sage.libs.flint """ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, implementation='FLINT'): """ diff --git a/src/sage/rings/padics/padic_generic_element.pyx b/src/sage/rings/padics/padic_generic_element.pyx index 88797ddf4ed..ffafe15313c 100644 --- a/src/sage/rings/padics/padic_generic_element.pyx +++ b/src/sage/rings/padics/padic_generic_element.pyx @@ -3830,7 +3830,7 @@ cdef class pAdicGenericElement(LocalGenericElement): In its simplest form, computes the inverse of ``p``-th root of this element. - This is an helper function used in :meth:`nth_root` + This is a helper function used in :meth:`nth_root` and :meth:`primitive_root_of_unity`. INPUT: diff --git a/src/sage/rings/padics/padic_valuation.py b/src/sage/rings/padics/padic_valuation.py index cb0207c10d4..d1590d0391f 100644 --- a/src/sage/rings/padics/padic_valuation.py +++ b/src/sage/rings/padics/padic_valuation.py @@ -1360,7 +1360,7 @@ class pAdicFromLimitValuation(FiniteExtensionFromLimitValuation, pAdicValuation_ TESTS:: - sage: TestSuite(v).run(skip='_test_shift') # long time # needs sage.rings.number_field + sage: TestSuite(v).run(skip='_test_shift') # long time # needs sage.rings.number_field The ``_test_shift`` test fails because the parent of the shift is incorrect, see :trac:`23971`:: diff --git a/src/sage/rings/polynomial/complex_roots.py b/src/sage/rings/polynomial/complex_roots.py index cbbd42c8ccf..4c66eeca40c 100644 --- a/src/sage/rings/polynomial/complex_roots.py +++ b/src/sage/rings/polynomial/complex_roots.py @@ -21,7 +21,11 @@ sage: x = polygen(ZZ) sage: (x^5 - x - 1).roots(ring=CIF) - [(1.167303978261419?, 1), (-0.764884433600585? - 0.352471546031727?*I, 1), (-0.764884433600585? + 0.352471546031727?*I, 1), (0.181232444469876? - 1.083954101317711?*I, 1), (0.181232444469876? + 1.083954101317711?*I, 1)] + [(1.167303978261419?, 1), + (-0.764884433600585? - 0.352471546031727?*I, 1), + (-0.764884433600585? + 0.352471546031727?*I, 1), + (0.181232444469876? - 1.083954101317711?*I, 1), + (0.181232444469876? + 1.083954101317711?*I, 1)] """ #***************************************************************************** @@ -61,9 +65,13 @@ def interval_roots(p, rts, prec): sage: rts = [CC.zeta(3)^i for i in range(0, 3)] sage: from sage.rings.polynomial.complex_roots import interval_roots sage: interval_roots(p, rts, 53) - [1, -0.500000000000000? + 0.866025403784439?*I, -0.500000000000000? - 0.866025403784439?*I] + [1, -0.500000000000000? + 0.866025403784439?*I, + -0.500000000000000? - 0.866025403784439?*I] sage: interval_roots(p, rts, 200) - [1, -0.500000000000000000000000000000000000000000000000000000000000? + 0.866025403784438646763723170752936183471402626905190314027904?*I, -0.500000000000000000000000000000000000000000000000000000000000? - 0.866025403784438646763723170752936183471402626905190314027904?*I] + [1, -0.500000000000000000000000000000000000000000000000000000000000? + + 0.866025403784438646763723170752936183471402626905190314027904?*I, + -0.500000000000000000000000000000000000000000000000000000000000? + - 0.866025403784438646763723170752936183471402626905190314027904?*I] """ CIF = ComplexIntervalField(prec) @@ -172,15 +180,19 @@ def complex_roots(p, skip_squarefree=False, retval='interval', min_prec=0): sage: from sage.rings.polynomial.complex_roots import complex_roots sage: x = polygen(ZZ) sage: complex_roots(x^5 - x - 1) - [(1.167303978261419?, 1), (-0.764884433600585? - 0.352471546031727?*I, 1), (-0.764884433600585? + 0.352471546031727?*I, 1), (0.181232444469876? - 1.083954101317711?*I, 1), (0.181232444469876? + 1.083954101317711?*I, 1)] - sage: v=complex_roots(x^2 + 27*x + 181) + [(1.167303978261419?, 1), + (-0.764884433600585? - 0.352471546031727?*I, 1), + (-0.764884433600585? + 0.352471546031727?*I, 1), + (0.181232444469876? - 1.083954101317711?*I, 1), + (0.181232444469876? + 1.083954101317711?*I, 1)] + sage: v = complex_roots(x^2 + 27*x + 181) Unfortunately due to numerical noise there can be a small imaginary part to each root depending on CPU, compiler, etc, and that affects the printing order. So we verify the real part of each root and check that the imaginary part is small in both cases:: - sage: v # random + sage: v # random [(-14.61803398874990?..., 1), (-12.3819660112501...? + 0.?e-27*I, 1)] sage: sorted((v[0][0].real(),v[1][0].real())) [-14.61803398874989?, -12.3819660112501...?] @@ -227,11 +239,16 @@ def complex_roots(p, skip_squarefree=False, retval='interval', min_prec=0): ....: if tiny(x.imag()): return x.real() ....: if tiny(x.real()): return CIF(0, x.imag()) sage: rts = complex_roots(p); type(rts[0][0]), sorted(map(smash, rts)) - (, [-1.618033988749895?, -0.618033988749895?*I, 1.618033988749895?*I, 0.618033988749895?]) + (, + [-1.618033988749895?, -0.618033988749895?*I, + 1.618033988749895?*I, 0.618033988749895?]) sage: rts = complex_roots(p, retval='algebraic'); type(rts[0][0]), sorted(map(smash, rts)) - (, [-1.618033988749895?, -0.618033988749895?*I, 1.618033988749895?*I, 0.618033988749895?]) + (, + [-1.618033988749895?, -0.618033988749895?*I, + 1.618033988749895?*I, 0.618033988749895?]) sage: rts = complex_roots(p, retval='algebraic_real'); type(rts[0][0]), rts - (, [(-1.618033988749895?, 1), (0.618033988749895?, 1)]) + (, + [(-1.618033988749895?, 1), (0.618033988749895?, 1)]) TESTS: diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index d4e2b115e39..f5c1b0e480c 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -2075,8 +2075,9 @@ def factor(self, proof=None): Check that we can factor over the algebraic field (:trac:`25390`):: - sage: R. = PolynomialRing(QQbar) # needs sage.rings.number_field - sage: factor(x^2 + y^2) # needs sage.rings.number_field + sage: # needs sage.libs.singular sage.rings.number_field + sage: R. = PolynomialRing(QQbar) + sage: factor(x^2 + y^2) (x + (-1*I)*y) * (x + 1*I*y) Check that the global proof flag for polynomials is honored:: @@ -2123,7 +2124,7 @@ def factor(self, proof=None): sage: R. = PolynomialRing(CC,1) # needs sage.rings.real_mpfr sage: f = z^4 - 6*z + 3 # needs sage.rings.real_mpfr - sage: f.factor() # needs sage.rings.real_mpfr + sage: f.factor() # needs sage.libs.pari sage.rings.real_mpfr (z - 1.60443920904349) * (z - 0.511399619393097) * (z + 1.05791941421830 - 1.59281852704435*I) * (z + 1.05791941421830 + 1.59281852704435*I) @@ -2252,7 +2253,7 @@ def quo_rem(self, right): ((2*b + 1)*y, (2*b + 1)*y + (-a^2 + 3)*z + a) sage: R. = Qp(5)[] # needs sage.rings.padics - sage: x.quo_rem(y) # needs sage.rings.padics + sage: x.quo_rem(y) # needs sage.libs.singular sage.rings.padics Traceback (most recent call last): ... TypeError: no conversion of this ring to a Singular ring defined @@ -2265,7 +2266,7 @@ def quo_rem(self, right): sage: R. = QQbar[] # needs sage.rings.number_field sage: f = y*x^2 + x + 1 # needs sage.rings.number_field - sage: f.quo_rem(x) # needs sage.rings.number_field + sage: f.quo_rem(x) # needs sage.libs.singular sage.rings.number_field (x*y + 1, 1) """ R = self.parent() @@ -2326,7 +2327,7 @@ def resultant(self, other, variable=None): Check that :trac:`15061` is fixed:: sage: R. = AA[] # needs sage.rings.number_field - sage: (x^2 + 1).resultant(x^2 - y) # needs sage.rings.number_field + sage: (x^2 + 1).resultant(x^2 - y) # needs sage.libs.singular sage.rings.number_field y^2 + 2*y + 1 Test for :trac:`2693`:: @@ -2334,7 +2335,7 @@ def resultant(self, other, variable=None): sage: R. = RR[] sage: p = x + y sage: q = x*y - sage: p.resultant(q) # needs sage.modules + sage: p.resultant(q) # needs sage.libs.singular sage.modules -y^2 Check that this method works over QQbar (:trac:`25351`):: @@ -2343,9 +2344,9 @@ def resultant(self, other, variable=None): sage: P. = QQbar[] sage: a = x + y sage: b = x^3 - y^3 - sage: a.resultant(b) + sage: a.resultant(b) # needs sage.libs.singular sage.modules (-2)*y^3 - sage: a.resultant(b, y) + sage: a.resultant(b, y) # needs sage.libs.singular sage.modules 2*x^3 """ R = self.parent() @@ -2375,7 +2376,7 @@ def subresultants(self, other, variable=None): EXAMPLES:: - sage: # needs sage.rings.number_field + sage: # needs sage.libs.singular sage.rings.number_field sage: R. = QQbar[] sage: p = (y^2 + 6)*(x - 1) - y*(x^2 + 1) sage: q = (x^2 + 6)*(y - 1) - x*(y^2 + 1) @@ -2413,9 +2414,9 @@ def reduce(self, I): sage: f3 = -x^2 + y^2 sage: F = Ideal([f1, f2, f3]) sage: g = x*y - 3*x*y^2 - sage: g.reduce(F) + sage: g.reduce(F) # needs sage.libs.singular (-6)*y^2 + 2*y - sage: g.reduce(F.gens()) + sage: g.reduce(F.gens()) # needs sage.libs.singular (-6)*y^2 + 2*y :: diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 561136bac6d..f519400c3c3 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -3197,7 +3197,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): INPUT: - ``as_ETuples`` -- (default: ``True``) if ``True`` returns the - result as an list of ETuples, otherwise returns a list of tuples + result as a list of ETuples, otherwise returns a list of tuples EXAMPLES:: diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 44946845b83..dc3bfdc2459 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -41,10 +41,11 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: R. = ZZ['x,y']; R Multivariate Polynomial Ring in x, y over Integer Ring - sage: class CR(CommutativeRing): + sage: cat = Rings().Commutative() + sage: class CR(Parent): ....: def __init__(self): - ....: CommutativeRing.__init__(self,self) - ....: def __call__(self,x): + ....: Parent.__init__(self, self, category=cat) + ....: def __call__(self, x): ....: return None sage: cr = CR() sage: cr.is_commutative() @@ -668,7 +669,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): def repr_long(self): """ - Return structured string representation of self. + Return structured string representation of ``self``. EXAMPLES:: @@ -758,7 +759,6 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): Order: Graded Reverse Lexicographical Variables: T, W - sage: # optional - magma sage: magma(PolynomialRing(GF(7),4, 'x')) Polynomial ring of rank 4 over GF(7) @@ -797,7 +797,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): EXAMPLES:: - sage: # needs sage.rings.number_field + sage: # needs sage.libs.gap sage.rings.number_field sage: F = CyclotomicField(8) sage: P. = F[] sage: gap(P) # indirect doctest @@ -868,12 +868,12 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): def gen(self, n=0): if n < 0 or n >= self._ngens: - raise ValueError("Generator not defined.") + raise ValueError("generator not defined") return self._gens[int(n)] def variable_names_recursive(self, depth=sage.rings.infinity.infinity): r""" - Returns the list of variable names of this and its base rings, as if + Return the list of variable names of this and its base rings, as if it were a single multi-variate polynomial. EXAMPLES:: @@ -883,7 +883,6 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): ('x', 'y', 'z', 'w') sage: R.variable_names_recursive(3) ('y', 'z', 'w') - """ if depth <= 0: all = () @@ -901,7 +900,8 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): def _mpoly_base_ring(self, vars=None): """ - Returns the base ring if this is viewed as a polynomial ring over vars. + Return the base ring if this is viewed as a polynomial ring over vars. + See also MPolynomial._mpoly_dict_recursive. """ if vars is None: @@ -1015,10 +1015,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): if not comb: return (d,) monomial = [comb[0]] - res = [] - for j in range(n - 2): - res.append(comb[j + 1] - comb[j] - 1) - monomial += res + monomial.extend(comb[j + 1] - comb[j] - 1 for j in range(n - 2)) monomial.append(n + d - 1 - comb[-1] - 1) return tuple(monomial) @@ -1234,7 +1231,6 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): True sage: R.random_element().parent() == R True - """ k = self.base_ring() n = self.ngens() @@ -1243,7 +1239,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): # Note that 'terms' could be None while 'total' is a # nonnegative integer, so the comparison 'terms > total' could - # fail in Python 3. + # fail if terms and terms > total: terms = total @@ -1526,13 +1522,14 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): def macaulay_resultant(self, *args, **kwds): r""" - This is an implementation of the Macaulay resultant. It computes - the resultant of universal polynomials as well as polynomials - with constant coefficients. This is a project done in - sage days 55. It's based on the implementation in Maple by - Manfred Minimair, which in turn is based on the references listed below: - It calculates the Macaulay resultant for a list of polynomials, - up to sign! + Return the Macaulay resultant. + + This computes the resultant of universal polynomials as well as + polynomials with constant coefficients. This is a project done + in sage days 55. It is based on the implementation in Maple by + Manfred Minimair, which in turn is based on the references + listed below. It calculates the Macaulay resultant for a list + of polynomials, up to sign! REFERENCES: @@ -1562,6 +1559,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): - the Macaulay resultant, an element of the base ring of ``self`` .. TODO:: + Working with sparse matrices should usually give faster results, but with the current implementation it actually works slower. There should be a way to improve performance with regards to this. @@ -1684,7 +1682,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): else: flist = args - if len(flist) <= 0: + if len(flist) == 0: raise TypeError('input list should contain at least 1 polynomial') if not all(f.is_homogeneous() for f in flist): raise TypeError('resultant for non-homogeneous polynomials is not supported') diff --git a/src/sage/rings/polynomial/ore_function_element.py b/src/sage/rings/polynomial/ore_function_element.py index 3afaff91a10..a9574c6d4cb 100644 --- a/src/sage/rings/polynomial/ore_function_element.py +++ b/src/sage/rings/polynomial/ore_function_element.py @@ -76,6 +76,7 @@ def _repr_(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] @@ -85,6 +86,7 @@ def _repr_(self): TESTS:: + sage: # needs sage.rings.finite_rings sage: f = 1/x^3; f x^(-3) sage: f * x^5 @@ -139,6 +141,7 @@ def __hash__(self): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] @@ -156,12 +159,12 @@ def _richcmp_(self, other, op): TESTS:: + sage: # needs sage.rings.function_field sage: R. = QQ[] sage: sigma = R.hom([t+1]) sage: der = R.derivation(1, twist=sigma) sage: S. = R['delta', der] sage: K = S.fraction_field() - sage: P = K.random_element() sage: Q = K.random_element() sage: D = K.random_element() @@ -197,18 +200,19 @@ def left_denominator(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: s = x + a sage: t = x^2 + a*x + a^2 - sage: f = s^(-1) * t sage: f.left_denominator() x + a In the example below, a simplification occurs:: + sage: # needs sage.rings.finite_rings sage: u = S.random_element(degree=2) sage: g = (u*s)^(-1) * (u*t) sage: g.left_denominator() @@ -222,13 +226,13 @@ def left_denominator(self): sage: S. = R['x', sigma] sage: s = (x + z)^2 sage: t = (x + z) * (x^2 + z^2) - sage: f = s^(-1) * t - sage: f.left_denominator() + sage: f = s^(-1) * t # needs sage.rings.function_field + sage: f.left_denominator() # needs sage.rings.function_field x^2 + (z^2 + z)*x + z^2 However, the following always holds true:: - sage: f == f.left_denominator()^(-1) * f.right_numerator() + sage: f == f.left_denominator()^(-1) * f.right_numerator() # needs sage.rings.function_field True .. SEEALSO:: @@ -258,18 +262,19 @@ def right_numerator(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: s = x + a sage: t = x^2 + a*x + a^2 - sage: f = s^(-1) * t sage: f.right_numerator() x^2 + a*x + a^2 In the example below, a simplification occurs:: + sage: # needs sage.rings.finite_rings sage: u = S.random_element(degree=2) sage: g = (u*s)^(-1) * (u*t) sage: g.right_numerator() @@ -286,15 +291,15 @@ def _reverse_fraction(self): r""" Return the pair `(s,t)` if this element reads `t s^{-1}`. - This is an helper function. Do not call it directly. + This is a helper function. Do not call it directly. TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(11^3) sage: Frob = k.frobenius_endomorphism() sage: der = k.derivation(a+1, twist=Frob) sage: S. = k['x', der] - sage: P = S.random_element(degree=5) sage: Q = S.random_element(degree=5) sage: f = P / Q @@ -330,18 +335,19 @@ def right_denominator(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: s = x + a sage: t = x^2 + a*x + a^2 - sage: f = t/s sage: f.right_denominator() x + a In the example below, a simplification occurs:: + sage: # needs sage.rings.finite_rings sage: u = S.random_element(degree=2) sage: g = (t*u) / (s*u) sage: g.right_denominator() @@ -356,11 +362,12 @@ def right_denominator(self): sage: R. = GF(11)[] sage: sigma = R.hom([z^2]) sage: S. = R['x', sigma] - sage: f = (x + z) / (x - z) - sage: f.right_denominator() + sage: f = (x + z) / (x - z) # needs sage.rings.function_field + sage: f.right_denominator() # needs sage.rings.function_field Traceback (most recent call last): ... - NotImplementedError: inversion of the twisting morphism Ring endomorphism of Fraction Field of Univariate Polynomial Ring in z over Finite Field of size 11 + NotImplementedError: inversion of the twisting morphism Ring endomorphism + of Fraction Field of Univariate Polynomial Ring in z over Finite Field of size 11 Defn: z |--> z^2 """ return self._reverse_fraction()[1] @@ -384,18 +391,19 @@ def left_numerator(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: s = x + a sage: t = x^2 + a*x + a^2 - sage: f = t/s sage: f.left_numerator() x^2 + a*x + a^2 In the example below, a simplification occurs:: + sage: # needs sage.rings.finite_rings sage: u = S.random_element(degree=2) sage: g = (t*u) / (s*u) sage: g.left_numerator() @@ -430,12 +438,12 @@ def _add_(self, other): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^2) sage: Frob = k.frobenius_endomorphism() sage: der = k.derivation(a, twist=Frob) sage: S. = k['x', der] sage: K = S.fraction_field() - sage: f = K.random_element() sage: g = K.random_element() sage: h = K.random_element() @@ -458,12 +466,12 @@ def _sub_(self, other): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^2) sage: Frob = k.frobenius_endomorphism() sage: der = k.derivation(a, twist=Frob) sage: S. = k['x', der] sage: K = S.fraction_field() - sage: f = K.random_element() sage: g = K.random_element() sage: h = K.random_element() @@ -480,12 +488,12 @@ def _neg_(self): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^2) sage: Frob = k.frobenius_endomorphism() sage: der = k.derivation(a, twist=Frob) sage: S. = k['x', der] sage: K = S.fraction_field() - sage: f = K.random_element() sage: g = -f sage: (f+g).is_zero() @@ -503,12 +511,12 @@ def _mul_(self, other): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^2) sage: Frob = k.frobenius_endomorphism() sage: der = k.derivation(a, twist=Frob) sage: S. = k['x', der] sage: K = S.fraction_field() - sage: f = K.random_element() sage: g = K.random_element() sage: h = K.random_element() @@ -538,18 +546,17 @@ def _div_(self, other): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^2) sage: Frob = k.frobenius_endomorphism() sage: der = k.derivation(a, twist=Frob) sage: S. = k['x', der] sage: K = S.fraction_field() - sage: f = K.random_element() sage: g = K.random_element() sage: h = K.random_element() sage: g == 0 or h == 0 or f / (g / h) == f*h / g True - sage: 0/f 0 sage: f/0 @@ -559,7 +566,7 @@ def _div_(self, other): We check that :trac:`32109` is fixed:: - sage: K(0)/K(0) + sage: K(0)/K(0) # needs sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: cannot divide by zero @@ -579,17 +586,16 @@ def __invert__(self): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^2) sage: Frob = k.frobenius_endomorphism() sage: der = k.derivation(a, twist=Frob) sage: S. = k['x', der] sage: K = S.fraction_field() - sage: f = K.random_element() sage: g = ~f sage: f * g 1 - sage: ~K(0) Traceback (most recent call last): ... @@ -629,23 +635,24 @@ def hilbert_shift(self, s, var=None): When the twisting morphism is not trivial, the output lies in a different Ore polynomial ring:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: K = S.fraction_field() - sage: f = (x-a)^(-2) sage: g = f.hilbert_shift(a); g x^(-2) - sage: g.parent() - Ore Function Field in x over Finite Field in a of size 5^3 twisted by a |--> a^5 and a*([a |--> a^5] - id) + Ore Function Field in x over Finite Field in a of size 5^3 + twisted by a |--> a^5 and a*([a |--> a^5] - id) sage: g.parent() is S False This behavior ensures that the Hilbert shift by a fixed element - defines an homomorphism of fields:: + defines a homomorphism of fields:: + sage: # needs sage.rings.finite_rings sage: U = K.random_element(degree=5) sage: V = K.random_element(degree=5) sage: s = k.random_element() @@ -669,17 +676,17 @@ class ConstantOreFunctionSection(Map): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: from sage.rings.polynomial.ore_polynomial_element import ConstantOrePolynomialSection sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: K = S.fraction_field() - sage: iota = K.coerce_map_from(k) - sage: sigma = iota.section() - sage: sigma + sage: sigma = iota.section(); sigma Generic map: - From: Ore Function Field in x over Finite Field in a of size 5^3 twisted by a |--> a^5 + From: Ore Function Field in x over Finite Field in a of size 5^3 + twisted by a |--> a^5 To: Finite Field in a of size 5^3 """ def _call_(self, x): @@ -693,14 +700,12 @@ def _call_(self, x): sage: F = R.fraction_field() sage: sigma = R.hom([t^2]) sage: S. = R['x', sigma] - sage: P = S._random_nonzero_element() - sage: f = (t*P) / P - sage: F(f) + sage: f = (t*P) / P # needs sage.rings.function_field + sage: F(f) # needs sage.rings.function_field t - - sage: g = x / (x+t) - sage: F(g) + sage: g = x / (x+t) # needs sage.rings.function_field + sage: F(g) # needs sage.rings.function_field Traceback (most recent call last): ... TypeError: not a constant function @@ -727,9 +732,8 @@ def __init__(self, domain, codomain): sage: R. = QQ[] sage: sigma = R.hom([t+1]) sage: S. = R['x',sigma] - sage: K = S.fraction_field() - - sage: K.coerce_map_from(K.base_ring()) # indirect doctest + sage: K = S.fraction_field() # needs sage.rings.function_field + sage: K.coerce_map_from(K.base_ring()) # indirect doctest # needs sage.rings.function_field Ore Function base injection morphism: From: Fraction Field of Univariate Polynomial Ring in t over Rational Field To: Ore Function Field in x over Fraction Field of Univariate Polynomial Ring in t over Rational Field twisted by t |--> t + 1 @@ -746,6 +750,7 @@ def an_element(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x',Frob] @@ -766,6 +771,7 @@ def _call_(self, x): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x',Frob] @@ -789,6 +795,7 @@ def section(self): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x',Frob] @@ -796,7 +803,8 @@ def section(self): sage: m = K.coerce_map_from(k) sage: m.section() Generic map: - From: Ore Function Field in x over Finite Field in t of size 5^3 twisted by t |--> t^5 + From: Ore Function Field in x over Finite Field in t of size 5^3 + twisted by t |--> t^5 To: Finite Field in t of size 5^3 """ return ConstantOreFunctionSection(self.codomain(), self.domain()) @@ -812,12 +820,12 @@ class OreFunction_with_large_center(OreFunction): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: K = S.fraction_field() sage: f = K.random_element() - sage: from sage.rings.polynomial.ore_function_element import OreFunction_with_large_center sage: isinstance(f, OreFunction_with_large_center) True @@ -835,11 +843,11 @@ def reduced_trace(self, var=None): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: K = S.fraction_field() - sage: a = 1 / (x^2 + t) sage: tr = a.reduced_trace(); tr 3/(z^2 + 2) @@ -847,6 +855,7 @@ def reduced_trace(self, var=None): The reduced trace lies in the center of `S`, which is the fraction field of a univariate polynomial ring in the variable `z = x^3` over `GF(5)`:: + sage: # needs sage.rings.finite_rings sage: tr.parent() Fraction Field of Univariate Polynomial Ring in z over Finite Field of size 5 sage: tr.parent() is K.center() @@ -854,7 +863,7 @@ def reduced_trace(self, var=None): We can use explicit conversion to view ``tr`` as a Ore function:: - sage: K(tr) + sage: K(tr) # needs sage.rings.finite_rings (x^6 + 2)^(-1) * 3 By default, the name of the central variable is usually ``z`` (see @@ -862,13 +871,14 @@ def reduced_trace(self, var=None): for more details about this). However, the user can specify a different variable name if desired:: - sage: a.reduced_trace(var='u') + sage: a.reduced_trace(var='u') # needs sage.rings.finite_rings 3/(u^2 + 2) TESTS: We check that the reduced trace is additive:: + sage: # needs sage.rings.finite_rings sage: a = K.random_element(degree=5) sage: b = K.random_element(degree=7) sage: a.reduced_trace() + b.reduced_trace() == (a+b).reduced_trace() @@ -876,7 +886,7 @@ def reduced_trace(self, var=None): :: - sage: (a*b).reduced_trace() == (b*a).reduced_trace() + sage: (a*b).reduced_trace() == (b*a).reduced_trace() # needs sage.rings.finite_rings True """ ring = self.parent()._ring @@ -896,11 +906,11 @@ def reduced_norm(self, var=None): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: K = S.fraction_field() - sage: a = (x + t) / (x^2 + t^2) sage: N = a.reduced_norm(); N (z + 2)/(z^2 + 4) @@ -908,6 +918,7 @@ def reduced_norm(self, var=None): The reduced norm lies in the center of `S`, which is the fraction field of a univariate polynomial ring in the variable `z = x^3` over `GF(5)`. :: + sage: # needs sage.rings.finite_rings sage: N.parent() Fraction Field of Univariate Polynomial Ring in z over Finite Field of size 5 sage: N.parent() is K.center() @@ -915,7 +926,7 @@ def reduced_norm(self, var=None): We can use explicit conversion to view ``N`` as a skew polynomial:: - sage: K(N) + sage: K(N) # needs sage.rings.finite_rings (x^6 + 4)^(-1) * (x^3 + 2) By default, the name of the central variable is usually ``z`` (see @@ -923,13 +934,14 @@ def reduced_norm(self, var=None): for more details about this). However, the user can specify a different variable name if desired:: - sage: a.reduced_norm(var='u') + sage: a.reduced_norm(var='u') # needs sage.rings.finite_rings (u + 2)/(u^2 + 4) TESTS: We check that the reduced norm is a multiplicative map:: + sage: # needs sage.rings.finite_rings sage: a = K.random_element() sage: b = K.random_element() sage: a.reduced_norm() * b.reduced_norm() == (a*b).reduced_norm() diff --git a/src/sage/rings/polynomial/ore_function_field.py b/src/sage/rings/polynomial/ore_function_field.py index 5a50e7c22b0..6fd7d5ffc5a 100644 --- a/src/sage/rings/polynomial/ore_function_field.py +++ b/src/sage/rings/polynomial/ore_function_field.py @@ -12,7 +12,8 @@ sage: A. = R['d', der] sage: K = A.fraction_field() sage: K - Ore Function Field in d over Fraction Field of Univariate Polynomial Ring in t over Rational Field twisted by d/dt + Ore Function Field in d over Fraction Field of Univariate Polynomial Ring in t + over Rational Field twisted by d/dt The simplest way to build elements in `K` is to use the division operator over Ore polynomial rings:: @@ -57,6 +58,7 @@ the latter assumption is not fulfilled (or actually if Sage cannot invert the twisting morphism), computing the left numerator and the right denominator fails:: + sage: # needs sage.rings.function_field sage: sigma = R.hom([t^2]) sage: S. = R['x', sigma] sage: F = S.fraction_field() @@ -66,13 +68,15 @@ sage: f.left_numerator() Traceback (most recent call last): ... - NotImplementedError: inversion of the twisting morphism Ring endomorphism of Fraction Field of Univariate Polynomial Ring in t over Rational Field + NotImplementedError: inversion of the twisting morphism + Ring endomorphism of Fraction Field of Univariate Polynomial Ring in t over Rational Field Defn: t |--> t^2 On a related note, fractions are systematically simplified when the twisting morphism is bijective but they are not otherwise. As an example, compare the two following computations:: + sage: # needs sage.rings.function_field sage: P = d^2 + t*d + 1 sage: Q = d + t^2 sage: D = d^3 + t^2 + 1 @@ -83,6 +87,7 @@ sage: g (d^2 + t*d + 1)^(-1) * (d + t^2) + sage: # needs sage.rings.function_field sage: P = x^2 + t*x + 1 sage: Q = x + t^2 sage: D = x^3 + t^2 + 1 @@ -91,7 +96,8 @@ (x^2 + t*x + 1)^(-1) * (x + t^2) sage: g = (D*P)^(-1) * (D*Q) sage: g - (x^5 + t^8*x^4 + x^3 + (t^2 + 1)*x^2 + (t^3 + t)*x + t^2 + 1)^(-1) * (x^4 + t^16*x^3 + (t^2 + 1)*x + t^4 + t^2) + (x^5 + t^8*x^4 + x^3 + (t^2 + 1)*x^2 + (t^3 + t)*x + t^2 + 1)^(-1) + * (x^4 + t^16*x^3 + (t^2 + 1)*x + t^4 + t^2) sage: f == g True @@ -99,6 +105,7 @@ Basic arithmetical operations are available:: + sage: # needs sage.rings.function_field sage: f = 1 / d sage: g = 1 / (d + t) sage: u = f + g; u @@ -115,6 +122,7 @@ Of course, multiplication remains noncommutative:: + sage: # needs sage.rings.function_field sage: g * f (d^2 + t*d + 1)^(-1) sage: g^(-1) * f @@ -171,6 +179,7 @@ def __init__(self, ring, category=None): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(11^3) sage: Frob = k.frobenius_endomorphism() sage: der = k.derivation(a, twist=Frob) @@ -201,11 +210,11 @@ def _element_constructor_(self, *args, **kwds): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: K = S.fraction_field() - sage: f = K(x^2 + a, x + a^2) # indirect doctest sage: f (x + a^2)^(-1) * (x^2 + a) @@ -218,6 +227,7 @@ def _coerce_map_from_base_ring(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(11^2) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] @@ -225,7 +235,8 @@ def _coerce_map_from_base_ring(self): sage: K.coerce_map_from(k) # indirect doctest Ore Function base injection morphism: From: Finite Field in t of size 11^2 - To: Ore Function Field in x over Finite Field in t of size 11^2 twisted by t |--> t^11 + To: Ore Function Field in x over Finite Field in t of size 11^2 + twisted by t |--> t^11 """ return OreFunctionBaseringInjection(self.base_ring(), self) @@ -261,12 +272,12 @@ def _repr_(self): sage: R. = QQ[] sage: sigma = R.hom([t+1]) sage: S. = OrePolynomialRing(R, sigma) - sage: S.fraction_field() + sage: S.fraction_field() # needs sage.rings.function_field Ore Function Field in x over Fraction Field of Univariate Polynomial Ring in t over Rational Field twisted by t |--> t + 1 sage: der = R.derivation() sage: T. = OrePolynomialRing(R, der) - sage: T.fraction_field() + sage: T.fraction_field() # needs sage.rings.function_field Ore Function Field in d over Fraction Field of Univariate Polynomial Ring in t over Rational Field twisted by d/dt """ s = "Ore Function Field in %s over %s twisted by " % (self.variable_name(), self.base_ring()) @@ -286,6 +297,7 @@ def _latex_(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] @@ -321,13 +333,13 @@ def change_var(self, var): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: R. = OrePolynomialRing(k,Frob) sage: K = R.fraction_field() sage: K Ore Function Field in x over Finite Field in t of size 5^3 twisted by t |--> t^5 - sage: Ky = K.change_var('y'); Ky Ore Function Field in y over Finite Field in t of size 5^3 twisted by t |--> t^5 sage: Ky is K.change_var('y') @@ -344,13 +356,14 @@ def characteristic(self): sage: R. = QQ[] sage: sigma = R.hom([t+1]) sage: S = R['x',sigma] - sage: S.fraction_field().characteristic() + sage: S.fraction_field().characteristic() # needs sage.rings.function_field 0 + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S = k['y',Frob] - sage: S.fraction_field().characteristic() + sage: S.fraction_field().characteristic() # needs sage.rings.function_field 5 """ return self.base_ring().characteristic() @@ -369,9 +382,10 @@ def twisting_morphism(self, n=1): sage: R. = QQ[] sage: sigma = R.hom([t+1]) sage: S. = R['x', sigma] - sage: K = S.fraction_field() - sage: K.twisting_morphism() - Ring endomorphism of Fraction Field of Univariate Polynomial Ring in t over Rational Field + sage: K = S.fraction_field() # needs sage.rings.function_field + sage: K.twisting_morphism() # needs sage.rings.function_field + Ring endomorphism of + Fraction Field of Univariate Polynomial Ring in t over Rational Field Defn: t |--> t + 1 When the Ore polynomial ring is only twisted by a derivation, this @@ -379,8 +393,8 @@ def twisting_morphism(self, n=1): sage: der = R.derivation() sage: A. = R['x', der] - sage: F = A.fraction_field() - sage: F.twisting_morphism() + sage: F = A.fraction_field() # needs sage.rings.function_field + sage: F.twisting_morphism() # needs sage.rings.function_field .. SEEALSO:: @@ -404,6 +418,7 @@ def twisting_derivation(self): sage: F.twisting_derivation() d/dt + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] @@ -428,6 +443,7 @@ def gen(self, n=0): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^4) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] @@ -446,11 +462,11 @@ def gens_dict(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: R. = ZZ[] sage: sigma = R.hom([t+1]) sage: S. = OrePolynomialRing(R, sigma) sage: K = S.fraction_field() - sage: K.gens_dict() {'x': x} """ @@ -462,6 +478,7 @@ def is_finite(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: k.is_finite() True @@ -480,6 +497,7 @@ def is_exact(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] @@ -487,6 +505,7 @@ def is_exact(self): sage: K.is_exact() True + sage: # needs sage.rings.padics sage: k. = Qq(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] @@ -508,6 +527,7 @@ def is_sparse(self): EXAMPLES:: + sage: # needs sage.rings.function_field sage.rings.real_mpfr sage: R. = RR[] sage: sigma = R.hom([t+1]) sage: S. = R['x', sigma] @@ -524,6 +544,7 @@ def ngens(self): EXAMPLES:: + sage: # needs sage.rings.function_field sage.rings.real_mpfr sage: R. = RR[] sage: sigma = R.hom([t+1]) sage: S. = R['x',sigma] @@ -550,19 +571,24 @@ def random_element(self, degree=2, monic=False, *args, **kwds): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: K = S.fraction_field() - sage: K.random_element() # random - (x^2 + (2*t^2 + t + 1)*x + 2*t^2 + 2*t + 3)^(-1) * ((2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2) + (x^2 + (2*t^2 + t + 1)*x + 2*t^2 + 2*t + 3)^(-1) + * ((2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2) sage: K.random_element(monic=True) # random - (x^2 + (4*t^2 + 3*t + 4)*x + 4*t^2 + t)^(-1) * (x^2 + (2*t^2 + t + 3)*x + 3*t^2 + t + 2) + (x^2 + (4*t^2 + 3*t + 4)*x + 4*t^2 + t)^(-1) + * (x^2 + (2*t^2 + t + 3)*x + 3*t^2 + t + 2) sage: K.random_element(degree=3) # random - (x^3 + (2*t^2 + 3)*x^2 + (2*t^2 + 4)*x + t + 3)^(-1) * ((t + 4)*x^3 + (4*t^2 + 2*t + 2)*x^2 + (2*t^2 + 3*t + 3)*x + 3*t^2 + 3*t + 1) + (x^3 + (2*t^2 + 3)*x^2 + (2*t^2 + 4)*x + t + 3)^(-1) + * ((t + 4)*x^3 + (4*t^2 + 2*t + 2)*x^2 + (2*t^2 + 3*t + 3)*x + 3*t^2 + 3*t + 1) sage: K.random_element(degree=[2,5]) # random - (x^2 + (4*t^2 + 2*t + 2)*x + 4*t^2 + t + 2)^(-1) * ((3*t^2 + t + 1)*x^5 + (2*t^2 + 2*t)*x^4 + (t^2 + 2*t + 4)*x^3 + (3*t^2 + 2*t)*x^2 + (t^2 + t + 4)*x) + (x^2 + (4*t^2 + 2*t + 2)*x + 4*t^2 + t + 2)^(-1) + * ((3*t^2 + t + 1)*x^5 + (2*t^2 + 2*t)*x^4 + (t^2 + 2*t + 4)*x^3 + + (3*t^2 + 2*t)*x^2 + (t^2 + t + 4)*x) """ if isinstance(degree, list): degdenom, degnum = degree @@ -579,13 +605,13 @@ def is_commutative(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: K = S.fraction_field() sage: K.is_commutative() False - sage: T. = k['y', Frob^3] sage: L = T.fraction_field() sage: L.is_commutative() @@ -599,11 +625,11 @@ def is_field(self, proof=False): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: K = S.fraction_field() - sage: S.is_field() False sage: K.is_field() @@ -613,6 +639,7 @@ def is_field(self, proof=False): We check that :trac:`31470` is fixed:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: S. = k['x', k.frobenius_endomorphism()] sage: K = S.fraction_field() @@ -632,12 +659,14 @@ def fraction_field(self): sage: R. = QQ[] sage: der = R.derivation() sage: A. = R['d', der] - sage: K = A.fraction_field() - - sage: K - Ore Function Field in d over Fraction Field of Univariate Polynomial Ring in t over Rational Field twisted by d/dt + sage: K = A.fraction_field(); K + Ore Function Field in d + over Fraction Field of Univariate Polynomial Ring in t over Rational Field + twisted by d/dt sage: K.fraction_field() - Ore Function Field in d over Fraction Field of Univariate Polynomial Ring in t over Rational Field twisted by d/dt + Ore Function Field in d + over Fraction Field of Univariate Polynomial Ring in t over Rational Field + twisted by d/dt sage: K.fraction_field() is K True """ @@ -658,6 +687,7 @@ def __init__(self, embed): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: S. = OrePolynomialRing(k, k.frobenius_endomorphism()) sage: K = S.fraction_field() @@ -676,6 +706,7 @@ def _call_(self, x): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) sage: K = S.fraction_field() @@ -706,13 +737,13 @@ def _richcmp_(self, right, op): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) sage: K = S.fraction_field() sage: Z = K.center() sage: iota = K.coerce_map_from(Z) sage: sigma = iota.section() - sage: s = loads(dumps(sigma)) sage: s == sigma True @@ -735,6 +766,7 @@ def __init__(self, domain, codomain, ringembed): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) sage: K = S.fraction_field() @@ -753,6 +785,7 @@ def _repr_(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) sage: K = S.fraction_field() @@ -771,12 +804,12 @@ def _call_(self, x): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) sage: K = S.fraction_field() sage: Z. = K.center() sage: iota = K.coerce_map_from(Z) - sage: iota(1/(z+1)) (x^3 + 1)^(-1) """ @@ -790,12 +823,12 @@ def _richcmp_(self, right, op): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) sage: K = S.fraction_field() sage: Z = K.center() sage: iota = K.coerce_map_from(Z) - sage: i = loads(dumps(iota)) sage: i == iota True @@ -812,6 +845,7 @@ def section(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) sage: K = S.fraction_field() @@ -834,6 +868,7 @@ def __init__(self, ring, category=None): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] @@ -874,31 +909,32 @@ def center(self, name=None, names=None, default=False): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x',Frob] sage: K = S.fraction_field() - sage: Z = K.center(); Z Fraction Field of Univariate Polynomial Ring in z over Finite Field of size 5 We can pass in another variable name:: - sage: K.center(name='y') + sage: K.center(name='y') # needs sage.rings.finite_rings Fraction Field of Univariate Polynomial Ring in y over Finite Field of size 5 or use the bracket notation:: - sage: Zy. = K.center(); Zy + sage: Zy. = K.center(); Zy # needs sage.rings.finite_rings Fraction Field of Univariate Polynomial Ring in y over Finite Field of size 5 A coercion map from the center to the Ore function field is set:: - sage: K.has_coerce_map_from(Zy) + sage: K.has_coerce_map_from(Zy) # needs sage.rings.finite_rings True and pushout works:: + sage: # needs sage.rings.finite_rings sage: x.parent() Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 sage: y.parent() @@ -910,9 +946,9 @@ def center(self, name=None, names=None, default=False): A conversion map in the reverse direction is also set:: + sage: # needs sage.rings.finite_rings sage: Zy(x^(-6) + 2) (2*y^2 + 1)/y^2 - sage: Zy(1/x^2) Traceback (most recent call last): ... @@ -925,11 +961,11 @@ def center(self, name=None, names=None, default=False): However, a variable name is given the first time this method is called, the given name become the default for the next calls:: + sage: # needs sage.rings.finite_rings sage: k. = GF(11^3) sage: phi = k.frobenius_endomorphism() sage: S. = k['X', phi] sage: K = S.fraction_field() - sage: C. = K.center() # first call sage: C Fraction Field of Univariate Polynomial Ring in u over Finite Field of size 11 @@ -939,6 +975,7 @@ def center(self, name=None, names=None, default=False): We can update the default variable name by passing in the argument ``default=True``:: + sage: # needs sage.rings.finite_rings sage: D. = K.center(default=True) sage: D Fraction Field of Univariate Polynomial Ring in v over Finite Field of size 11 diff --git a/src/sage/rings/polynomial/ore_polynomial_element.pyx b/src/sage/rings/polynomial/ore_polynomial_element.pyx index 53c14bbc23f..637ba30aa0c 100644 --- a/src/sage/rings/polynomial/ore_polynomial_element.pyx +++ b/src/sage/rings/polynomial/ore_polynomial_element.pyx @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.combinat r""" Univariate Ore polynomials @@ -639,7 +640,6 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: # needs sage.rings.finite_rings sage: R. = GF(11)[] sage: der = R.derivation() sage: S. = R['x', der] @@ -667,6 +667,7 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x',Frob] @@ -680,7 +681,7 @@ cdef class OrePolynomial(AlgebraElement): Divisibility by `0` does not make sense:: - sage: c.is_left_divisible_by(S(0)) + sage: c.is_left_divisible_by(S(0)) # needs sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: division by zero is not valid @@ -2196,7 +2197,7 @@ cdef void lmul_gen(list A, Morphism m, d) noexcept: replace it by the list of coefficients of ``X*P`` (where ``X`` is the variable in the Ore polynomial ring). - This is an helper function. + This is a helper function. INPUT: @@ -2683,7 +2684,7 @@ cdef class OrePolynomial_generic_dense(OrePolynomial): Return the list of coefficients of the product of this Ore polynomial by that whose coefficients are given by ``A``. - This is an helper function. + This is a helper function. """ cdef list BA = [self.base_ring().zero()] * (len(self._coeffs) + len(A) - 1) cdef Morphism m = self._parent._morphism @@ -2921,7 +2922,7 @@ cdef class OrePolynomial_generic_dense(OrePolynomial): False This behavior ensures that the Hilbert shift by a fixed element - defines an homomorphism of rings:: + defines a homomorphism of rings:: sage: # needs sage.rings.finite_rings sage: U = S.random_element(degree=5) diff --git a/src/sage/rings/polynomial/ore_polynomial_ring.py b/src/sage/rings/polynomial/ore_polynomial_ring.py index 88db16fd111..c5f32f35a1b 100644 --- a/src/sage/rings/polynomial/ore_polynomial_ring.py +++ b/src/sage/rings/polynomial/ore_polynomial_ring.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.combinat r""" Univariate Ore polynomial rings @@ -79,10 +80,10 @@ class OrePolynomialRing(UniqueRepresentation, Algebra): We create the Ore ring `\GF{5^3}[x, \text{Frob}]` where Frob is the Frobenius endomorphism:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() - sage: S = OrePolynomialRing(k, Frob, 'x') - sage: S + sage: S = OrePolynomialRing(k, Frob, 'x'); S Ore Polynomial Ring in x over Finite Field in a of size 5^3 twisted by a |--> a^5 In particular, observe that it is not needed to create and pass in @@ -90,8 +91,8 @@ class OrePolynomialRing(UniqueRepresentation, Algebra): As a shortcut, we can use the square brackets notation as follow:: - sage: T. = k['x', Frob] - sage: T + sage: # needs sage.rings.finite_rings + sage: T. = k['x', Frob]; T Ore Polynomial Ring in x over Finite Field in a of size 5^3 twisted by a |--> a^5 sage: T is S True @@ -100,22 +101,23 @@ class OrePolynomialRing(UniqueRepresentation, Algebra): in the right hand side. Indeed, the following fails (it is interpreted by Sage as a classical polynomial ring with variable name ``Frob``):: - sage: T. = k[Frob] + sage: T. = k[Frob] # needs sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: variable name 'Frobenius endomorphism a |--> a^5 on Finite Field in a of size 5^3' is not alphanumeric + ValueError: variable name 'Frobenius endomorphism a |--> a^5 on + Finite Field in a of size 5^3' is not alphanumeric Note moreover that, similarly to the classical case, using the brackets notation also sets the variable:: - sage: x.parent() is S + sage: x.parent() is S # needs sage.rings.finite_rings True We are now ready to carry on computations in the Ore ring:: - sage: x*a + sage: x*a # needs sage.rings.finite_rings (2*a^2 + 4*a + 4)*x - sage: Frob(a)*x + sage: Frob(a)*x # needs sage.rings.finite_rings (2*a^2 + 4*a + 4)*x .. RUBRIC:: The case of a twisting derivation @@ -123,22 +125,23 @@ class OrePolynomialRing(UniqueRepresentation, Algebra): We can similarly create the Ore ring of differential operators over `\QQ[t]`, namely `\QQ[t][d, \frac{d}{dt}]`:: + sage: # needs sage.rings.finite_rings sage: R. = QQ[] sage: der = R.derivation(); der d/dt - sage: A = OrePolynomialRing(R, der, 'd') - sage: A - Ore Polynomial Ring in d over Univariate Polynomial Ring in t over Rational Field twisted by d/dt + sage: A = OrePolynomialRing(R, der, 'd'); A + Ore Polynomial Ring in d over Univariate Polynomial Ring in t + over Rational Field twisted by d/dt Again, the brackets notation is available:: - sage: B. = R['d', der] - sage: A is B + sage: B. = R['d', der] # needs sage.rings.finite_rings + sage: A is B # needs sage.rings.finite_rings True and computations can be carried out:: - sage: d*t + sage: d*t # needs sage.rings.finite_rings t*d + 1 .. RUBRIC:: The combined case @@ -147,15 +150,14 @@ class OrePolynomialRing(UniqueRepresentation, Algebra): `\sigma` and a twisting `\sigma`-derivation can be created as well as follows:: + sage: # needs sage.rings.padics sage: F. = Qq(3^2) sage: sigma = F.frobenius_endomorphism(); sigma Frobenius endomorphism on 3-adic Unramified Extension Field in u defined by x^2 + 2*x + 2 lifting u |--> u^3 on the residue field sage: der = F.derivation(3, twist=sigma); der (3 + O(3^21))*([Frob] - id) - - sage: M. = F['X', der] - sage: M + sage: M. = F['X', der]; M Ore Polynomial Ring in X over 3-adic Unramified Extension Field in u defined by x^2 + 2*x + 2 twisted by Frob and (3 + O(3^21))*([Frob] - id) @@ -163,7 +165,7 @@ class OrePolynomialRing(UniqueRepresentation, Algebra): it already contains in it the datum of the twisting endomorphism. Actually, passing in both twisting maps results in an error:: - sage: F['X', sigma, der] + sage: F['X', sigma, der] # needs sage.rings.padics Traceback (most recent call last): ... ValueError: variable name 'Frobenius endomorphism ...' is not alphanumeric @@ -201,6 +203,7 @@ class OrePolynomialRing(UniqueRepresentation, Algebra): In Sage, there is exactly one Ore polynomial ring for each quadruple (base ring, twisting morphism, twisting derivation, name of the variable):: + sage: # needs sage.rings.finite_rings sage: k. = GF(7^3) sage: Frob = k.frobenius_endomorphism() sage: S = k['x', Frob] @@ -210,45 +213,45 @@ class OrePolynomialRing(UniqueRepresentation, Algebra): Rings with different variables names are different:: - sage: S is k['y', Frob] + sage: S is k['y', Frob] # needs sage.rings.finite_rings False Similarly, varying the twisting morphisms yields to different Ore rings (expect when the morphism coincide):: - sage: S is k['x', Frob^2] + sage: S is k['x', Frob^2] # needs sage.rings.finite_rings False - sage: S is k['x', Frob^3] + sage: S is k['x', Frob^3] # needs sage.rings.finite_rings False - sage: S is k['x', Frob^4] + sage: S is k['x', Frob^4] # needs sage.rings.finite_rings True TESTS: You must specify a variable name:: - sage: SkewPolynomialRing(k, Frob) + sage: SkewPolynomialRing(k, Frob) # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: you must specify the name of the variable Multivariate Ore polynomial rings are not supported:: - sage: S = OrePolynomialRing(k, Frob,names=['x','y']) + sage: S = OrePolynomialRing(k, Frob,names=['x','y']) # needs sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: multivariate Ore polynomials rings not supported Sparse Ore polynomial rings are not implemented:: - sage: S = SkewPolynomialRing(k, Frob, names='x', sparse=True) + sage: S = SkewPolynomialRing(k, Frob, names='x', sparse=True) # needs sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: sparse Ore polynomial rings are not implemented Saving and loading of polynomial rings works:: - sage: loads(dumps(S)) is S + sage: loads(dumps(S)) is S # needs sage.rings.finite_rings True .. TODO:: @@ -294,6 +297,7 @@ def __classcall_private__(cls, base_ring, twist=None, names=None, sparse=False, In certain situations (e.g. when the twisting morphism is the Frobenius over a finite field), even more specialized classes are used:: + sage: # needs sage.rings.finite_rings sage: k. = GF(7^5) sage: Frob = k.frobenius_endomorphism(2) sage: S. = SkewPolynomialRing(k, Frob) @@ -304,6 +308,7 @@ def __classcall_private__(cls, base_ring, twist=None, names=None, sparse=False, `None` ot the identity, a regular `PolynomialRing` is created, unless specified otherwise:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^2) sage: Frob = k.frobenius_endomorphism(2) sage: Frob.is_identity() @@ -424,12 +429,12 @@ def __reduce__(self): r""" TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(11^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: loads(dumps(S)) is S True - sage: der = k.derivation(a, twist=Frob) sage: T. = k['y', der] sage: loads(dumps(T)) is T @@ -457,7 +462,7 @@ def _element_constructor_(self, a=None, check=True, construct=False, **kwds): OUTPUT: - An zero-degree Ore polynomial in ``self``, equal to ``a``. + A zero-degree Ore polynomial in ``self``, equal to ``a``. EXAMPLES:: @@ -561,7 +566,7 @@ def _coerce_map_from_(self, P): True sage: S.has_coerce_map_from(ZZ) True - sage: S.has_coerce_map_from(GF(5^3)) + sage: S.has_coerce_map_from(GF(5^3)) # needs sage.rings.finite_rings False sage: S.coerce_map_from(ZZ) @@ -625,6 +630,7 @@ def _latex_(self) -> str: EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] @@ -658,6 +664,7 @@ def change_var(self, var): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: R. = OrePolynomialRing(k,Frob); R @@ -685,6 +692,7 @@ def characteristic(self): sage: R['x',sigma].characteristic() 0 + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: k['y',Frob].characteristic() @@ -720,6 +728,7 @@ def twisting_morphism(self, n=1): If ``n`` in negative, Sage tries to compute the inverse of the twisting morphism:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: T. = k['y',Frob] @@ -735,7 +744,8 @@ def twisting_morphism(self, n=1): sage: T.twisting_morphism(-1) Traceback (most recent call last): ... - NotImplementedError: inverse not implemented for morphisms of Fraction Field of Univariate Polynomial Ring in t over Rational Field + NotImplementedError: inverse not implemented for morphisms of + Fraction Field of Univariate Polynomial Ring in t over Rational Field When the Ore polynomial ring is only twisted by a derivation, this method returns nothing:: @@ -743,12 +753,14 @@ def twisting_morphism(self, n=1): sage: der = R.derivation() sage: A. = R['x', der] sage: A - Ore Polynomial Ring in x over Univariate Polynomial Ring in t over Rational Field twisted by d/dt + Ore Polynomial Ring in x over Univariate Polynomial Ring in t + over Rational Field twisted by d/dt sage: A.twisting_morphism() Here is an example where the twisting morphism is automatically inferred from the derivation:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: der = k.derivation(1, twist=Frob) @@ -785,6 +797,7 @@ def twisting_derivation(self): sage: A.twisting_derivation() d/dt + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] @@ -811,7 +824,8 @@ def gen(self, n=0): sage: R. = QQ[] sage: sigma = R.hom([t+1]) sage: S. = R['x',sigma]; S - Ore Polynomial Ring in x over Univariate Polynomial Ring in t over Rational Field twisted by t |--> t + 1 + Ore Polynomial Ring in x over Univariate Polynomial Ring in t + over Rational Field twisted by t |--> t + 1 sage: y = S.gen(); y x sage: y == x @@ -861,6 +875,7 @@ def is_finite(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: k.is_finite() True @@ -879,6 +894,7 @@ def is_exact(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] @@ -886,9 +902,8 @@ def is_exact(self): True sage: S.base_ring().is_exact() True - sage: R. = k[[]] - sage: sigma = R.hom([u+u^2]) + sage: sigma = R.hom([u + u^2]) sage: T. = R['y', sigma] sage: T.is_exact() False @@ -955,6 +970,7 @@ def random_element(self, degree=(-1, 2), monic=False, *args, **kwds): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] @@ -965,6 +981,7 @@ def random_element(self, degree=(-1, 2), monic=False, *args, **kwds): Use ``degree`` to obtain polynomials of higher degree:: + sage: # needs sage.rings.finite_rings sage: p = S.random_element(degree=5) # random (t^2 + 3*t)*x^5 + (4*t + 4)*x^3 + (4*t^2 + 4*t)*x^2 + (2*t^2 + 1)*x + 3 sage: p.degree() == 5 @@ -974,7 +991,7 @@ def random_element(self, degree=(-1, 2), monic=False, *args, **kwds): integer will be chosen between the first and second element of the tuple as the degree, both inclusive:: - sage: S.random_element(degree=(2,7)) # random + sage: S.random_element(degree=(2,7)) # random # needs sage.rings.finite_rings (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 @@ -983,14 +1000,14 @@ def random_element(self, degree=(-1, 2), monic=False, *args, **kwds): If the first tuple element is greater than the second, a ``ValueError`` is raised:: - sage: S.random_element(degree=(5,4)) + sage: S.random_element(degree=(5,4)) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: first degree argument must be less or equal to the second There is no monic polynomial of negative degree:: - sage: S.random_element(degree=-1, monic=True) + sage: S.random_element(degree=-1, monic=True) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: there is no monic polynomial with negative degree @@ -1040,6 +1057,7 @@ def random_irreducible(self, degree=2, monic=True, *args, **kwds): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x',Frob] @@ -1068,12 +1086,12 @@ def is_commutative(self) -> bool: EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: S.is_commutative() False - sage: T. = k['y', Frob^3] sage: T.is_commutative() True @@ -1083,7 +1101,6 @@ def is_commutative(self) -> bool: sage: A. = R['d', der] sage: A.is_commutative() False - sage: B. = R['b', 5*der] sage: B.is_commutative() True @@ -1097,6 +1114,7 @@ def is_field(self, proof=False) -> bool: EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] @@ -1107,6 +1125,7 @@ def is_field(self, proof=False) -> bool: We check that :trac:`31470` is fixed:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: S. = k['x', k.frobenius_endomorphism()] sage: zero_matrix(S, 2).row(0) @@ -1121,12 +1140,12 @@ def fraction_field(self): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x', Frob] sage: K = S.fraction_field(); K Ore Function Field in x over Finite Field in a of size 5^3 twisted by a |--> a^5 - sage: f = 1/(x + a); f (x + a)^(-1) sage: f.parent() is K @@ -1138,8 +1157,8 @@ def fraction_field(self): sage: der = R.derivation() sage: A. = R['d', der] sage: A.fraction_field() - Ore Function Field in d over Fraction Field of Univariate Polynomial Ring in t over Rational Field twisted by d/dt - + Ore Function Field in d over Fraction Field of Univariate Polynomial Ring in t + over Rational Field twisted by d/dt sage: f = t/d; f (d - 1/t)^(-1) * t sage: f*d @@ -1171,6 +1190,7 @@ def _pushout_(self, other): TESTS:: + sage: # needs sage.rings.finite_rings sage: from sage.categories.pushout import pushout sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 94d6aac82b5..de438cb122e 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -5451,6 +5451,8 @@ cdef class Polynomial(CommutativePolynomial): if self.degree() <= 1: return R.fraction_field() + from sage.rings.number_field.number_field import is_NumberField, NumberField + if is_IntegerRing(R): from sage.rings.number_field.number_field import NumberField return NumberField(self, names) @@ -6926,7 +6928,7 @@ cdef class Polynomial(CommutativePolynomial): sage: S. = PolynomialRing(R,'y') sage: p = ((1/b^2*d^2+1/a)*x*y^2+a*b/c*y+e+x^2) sage: q = -4*c^2*y^3+1 - sage: p.resultant(q) # needs sage.libs.pari + sage: p.resultant(q) # needs sage.libs.pari sage.modules (16*c^4)*x^6 + (48*c^4)*e*x^4 + (1/(b^6)*d^6 + 3/(a*b^4)*d^4 + (-12*a^3*b*c + 3)/(a^2*b^2)*d^2 + (-12*a^3*b*c + 1)/(a^3))*x^3 + (48*c^4)*e^2*x^2 + ((-12*a*c)/b*d^2*e + (-12*b*c)*e)*x + (16*c^4)*e^3 + (4*a^3*b^3)/c @@ -6938,7 +6940,7 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = PolynomialRing(CDF) sage: f = R(1 - I*x + (0.5)*x^2 + (1.7)*x^3) sage: g = f.derivative() - sage: f.resultant(g) + sage: f.resultant(g) # needs sage.modules 133.92599999999996 + 37.56999999999999*I """ variable = self.variable_name() @@ -7730,7 +7732,7 @@ cdef class Polynomial(CommutativePolynomial): sage: f = x^3 - 1 sage: f.roots() [(1, 1)] - sage: f.roots(ring=CC) # ... - low order bits slightly different on ppc # needs sage.rings.real_mpfr + sage: f.roots(ring=CC) # ... - low order bits slightly different on ppc # needs sage.rings.real_mpfr [(1.00000000000000, 1), (-0.500000000000000 - 0.86602540378443...*I, 1), (-0.500000000000000 + 0.86602540378443...*I, 1)] @@ -8151,11 +8153,11 @@ cdef class Polynomial(CommutativePolynomial): sage: x = polygen(QQ) sage: p = x + bigc - sage: p.roots(ring=RR, algorithm='numpy') # needs numpy + sage: p.roots(ring=RR, algorithm='numpy') # needs numpy sage.rings.real_mpfr Traceback (most recent call last): ... LinAlgError: Array must not contain infs or NaNs - sage: p.roots(ring=RR, algorithm='pari') # needs sage.libs.pari + sage: p.roots(ring=RR, algorithm='pari') # needs sage.libs.pari sage.rings.real_mpfr [(-3.50746621104340e451, 1)] sage: p.roots(ring=AA) # needs sage.rings.number_field [(-3.5074662110434039?e451, 1)] diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index 0468efd8c68..0713a334afb 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -41,6 +41,7 @@ from . import polynomial_element import sage.rings.rational_field +from sage.arith.misc import crt from sage.rings.ring import Field, IntegralDomain, CommutativeRing from sage.misc.cachefunc import cached_method @@ -1275,7 +1276,7 @@ def random_element(self, *args, **kwds): EXAMPLES:: - sage: # needs sage.rings.finite_rings + sage: # needs sage.modules sage.rings.finite_rings sage: F1. = GF(2^7) sage: P1. = F1[] sage: F2 = F1.extension(x^2 + x + 1, 'u') @@ -1539,7 +1540,7 @@ def S_class_group(self, S, proof=True): for ideal_gen in clgp_gen.gens(): rel_ideal_gen = back_to_rel(phi(ideal_gen)) prod_ideal_gen = [0]*i + [rel_ideal_gen.lift()] + [0]*(n - i - 1) - poly_ideal_gen = self(sage.arith.all.crt(prod_ideal_gen, moduli)) + poly_ideal_gen = self(crt(prod_ideal_gen, moduli)) ideal_gens.append(poly_ideal_gen) clgp_gens.append((tuple(ideal_gens), gen_order)) @@ -1755,7 +1756,7 @@ def S_units(self, S, proof=True): mul_order = unit.multiplicative_order() rel_unit = back_to_rel(phi(unit)) prod_unit = [1]*i + [rel_unit.lift()] + [1]*(n - i - 1) - poly_unit = self(sage.arith.all.crt(prod_unit, moduli)) + poly_unit = self(crt(prod_unit, moduli)) units.append((poly_unit, mul_order)) return units @@ -1897,7 +1898,7 @@ def selmer_generators(self, S, m, proof=True): for gen in component_selmer_groups[isos[i][1]]: rel_gen = back_to_rel(phi(gen)) prod_gen = [1]*i + [rel_gen.lift()] + [1]*(n - i - 1) - poly_gen = self(sage.arith.all.crt(prod_gen, moduli)) + poly_gen = self(crt(prod_gen, moduli)) gens.append(poly_gen) return gens diff --git a/src/sage/rings/polynomial/polynomial_rational_flint.pyx b/src/sage/rings/polynomial/polynomial_rational_flint.pyx index d99f0d3b98c..4b752edc8b0 100644 --- a/src/sage/rings/polynomial/polynomial_rational_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_rational_flint.pyx @@ -2109,7 +2109,7 @@ cdef class Polynomial_rational_flint(Polynomial): EXAMPLES:: - sage: # needs sage.libs.pari + sage: # needs sage.groups sage.libs.pari sage: R. = QQ[] sage: f = x^4 - 17*x^3 - 2*x + 1 sage: G = f.galois_group(); G @@ -2130,7 +2130,7 @@ cdef class Polynomial_rational_flint(Polynomial): sage: f = x^4 - 17*x^3 - 2*x + 1 sage: G = f.galois_group(pari_group=True); G PARI group [24, -1, 5, "S4"] of degree 4 - sage: PermutationGroup(G) + sage: PermutationGroup(G) # needs sage.groups Transitive group number 5 of degree 4 You can use KASH or GAP to compute Galois groups as well. The advantage is diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index 8801ed6709c..858df388caf 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -703,7 +703,7 @@ def _coerce_map_from_base_ring(self): To: Univariate Polynomial Ring in x over Rational Field sage: R.coerce_map_from(GF(7)) """ - from .polynomial_element import PolynomialBaseringInjection + from sage.rings.polynomial.polynomial_element import PolynomialBaseringInjection return PolynomialBaseringInjection(self.base_ring(), self) diff --git a/src/sage/rings/polynomial/skew_polynomial_element.pyx b/src/sage/rings/polynomial/skew_polynomial_element.pyx index 3ea7f87bddf..b103ac37508 100644 --- a/src/sage/rings/polynomial/skew_polynomial_element.pyx +++ b/src/sage/rings/polynomial/skew_polynomial_element.pyx @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.combinat r""" Univariate skew polynomials @@ -90,6 +91,7 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x',Frob] @@ -152,6 +154,7 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x',Frob] @@ -161,18 +164,17 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): x^5 + (2*t^2 + 4)*x^4 + (t^2 + 2)*x^3 + 2*x^2 + (4*t^2 + 2)*x + 2*t^2 + 4*t + 4 sage: b == a * a * a * a * a True - sage: modulus = x^3 + t*x^2 + (t+3)*x - 2 sage: br = a.right_power_mod(5, modulus); br (t + 1)*x^2 + (2*t^2 + t + 1)*x + 2*t^2 + 4*t + 2 sage: br == b % modulus True - sage: a.right_power_mod(100, modulus) (2*t^2 + 3)*x^2 + (t^2 + 4*t + 2)*x + t^2 + 2*t + 1 Negative exponents are supported: + sage: # needs sage.rings.finite_rings sage: a^(-5) (x^5 + (2*t^2 + 4)*x^4 + (t^2 + 2)*x^3 + 2*x^2 + (4*t^2 + 2)*x + 2*t^2 + 4*t + 4)^(-1) sage: b * a^(-5) @@ -180,7 +182,7 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): However, they cannot be combined with modulus:: - sage: a.right_power_mod(-10, modulus) + sage: a.right_power_mod(-10, modulus) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: modulus cannot be combined with negative exponent @@ -245,6 +247,7 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x',Frob] @@ -317,6 +320,7 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: T. = k['x',Frob] @@ -341,6 +345,7 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: T. = k['x',Frob] @@ -403,10 +408,12 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): sage: b = a.conjugate(-1) Traceback (most recent call last): ... - NotImplementedError: inverse not implemented for morphisms of Fraction Field of Univariate Polynomial Ring in t over Rational Field + NotImplementedError: inverse not implemented for morphisms of + Fraction Field of Univariate Polynomial Ring in t over Rational Field Here is a working example:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: T. = k['y',Frob] @@ -441,6 +448,7 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x',Frob] @@ -566,6 +574,7 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x',Frob] @@ -602,6 +611,7 @@ cdef class SkewPolynomial_generic_dense(OrePolynomial_generic_dense): TESTS:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S. = k['x',Frob] diff --git a/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx b/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx index 99b3b7e64c9..1a176288395 100644 --- a/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx +++ b/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.combinat sage.rings.finite_rings r""" Univariate dense skew polynomials over finite fields diff --git a/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx b/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx index 968c45c8453..367ff8713ba 100644 --- a/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx +++ b/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx @@ -1,4 +1,4 @@ -# sage.doctest: needs sage.rings.finite_rings +# sage.doctest: needs sage.combinat sage.rings.finite_rings r""" Univariate dense skew polynomials over a field with a finite order automorphism diff --git a/src/sage/rings/polynomial/skew_polynomial_ring.py b/src/sage/rings/polynomial/skew_polynomial_ring.py index 2ae48556880..9d3ea67ee46 100644 --- a/src/sage/rings/polynomial/skew_polynomial_ring.py +++ b/src/sage/rings/polynomial/skew_polynomial_ring.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.combinat r""" Univariate skew polynomial rings @@ -438,8 +439,6 @@ def _richcmp_(self, right, op): sage: Z = S.center() sage: iota = S.convert_map_from(Z) sage: sigma = iota.section() - - sage: # needs sage.rings.finite_rings sage: s = loads(dumps(sigma)) sage: s == sigma True @@ -517,8 +516,7 @@ def _call_(self, x): sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) sage: Z. = S.center() sage: iota = S.convert_map_from(Z) - - sage: iota(z) # needs sage.rings.finite_rings + sage: iota(z) x^3 """ k = self._codomain.base_ring() @@ -539,8 +537,6 @@ def _richcmp_(self, right, op): sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) sage: Z = S.center() sage: iota = S.convert_map_from(Z) - - sage: # needs sage.rings.finite_rings sage: i = loads(dumps(iota)) sage: i == iota True @@ -596,8 +592,7 @@ def __init__(self, base_ring, morphism, derivation, name, sparse, category=None) Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 sage: S.category() Category of algebras over Finite Field in t of size 5^3 - - sage: TestSuite(S).run() # needs sage.rings.finite_rings + sage: TestSuite(S).run() We check that a call to the method :meth:`sage.rings.polynomial.skew_polynomial_finite_order.SkewPolynomial_finite_order.is_central` diff --git a/src/sage/rings/polynomial/toy_d_basis.py b/src/sage/rings/polynomial/toy_d_basis.py index 00209396614..ec783625140 100644 --- a/src/sage/rings/polynomial/toy_d_basis.py +++ b/src/sage/rings/polynomial/toy_d_basis.py @@ -88,7 +88,7 @@ However, when we compute the Groebner basis of I (defined over `\ZZ`), we note that there is a certain integer in the ideal which is not 1:: - sage: gb = d_basis(I); gb + sage: gb = d_basis(I); gb # needs sage.libs.singular [z ..., y ..., x ..., 282687803443] Now for each prime `p` dividing this integer 282687803443, the Groebner @@ -98,19 +98,19 @@ sage: factor(282687803443) 101 * 103 * 27173681 - sage: I.change_ring(P.change_ring(GF(101))).groebner_basis() + sage: I.change_ring(P.change_ring(GF(101))).groebner_basis() # needs sage.libs.singular [z - 33, y + 48, x + 19] - sage: I.change_ring(P.change_ring(GF(103))).groebner_basis() + sage: I.change_ring(P.change_ring(GF(103))).groebner_basis() # needs sage.libs.singular [z - 18, y + 8, x + 39] - sage: I.change_ring(P.change_ring(GF(27173681))).groebner_basis() # needs sage.rings.finite_rings + sage: I.change_ring(P.change_ring(GF(27173681))).groebner_basis() # needs sage.libs.singular sage.rings.finite_rings [z + 10380032, y + 3186055, x - 536027] Of course, modulo any other prime the Groebner basis is trivial so there are no other solutions. For example:: - sage: I.change_ring(P.change_ring(GF(3))).groebner_basis() + sage: I.change_ring(P.change_ring(GF(3))).groebner_basis() # needs sage.libs.singular [1] AUTHOR: diff --git a/src/sage/rings/power_series_mpoly.pyx b/src/sage/rings/power_series_mpoly.pyx index d11eec97269..2846d563a97 100644 --- a/src/sage/rings/power_series_mpoly.pyx +++ b/src/sage/rings/power_series_mpoly.pyx @@ -7,6 +7,12 @@ from sage.rings.polynomial.multi_polynomial_ring_base import is_MPolynomialRing from sage.rings import power_series_poly +try: + from sage.libs.pari.all import PariError +except ImportError: + PariError = () + + cdef class PowerSeries_mpoly(PowerSeries): def __init__(self, parent, f=0, prec=infinity, int check=1, is_gen=0): diff --git a/src/sage/rings/power_series_poly.pyx b/src/sage/rings/power_series_poly.pyx index c651fe03d02..8f2a86efba9 100644 --- a/src/sage/rings/power_series_poly.pyx +++ b/src/sage/rings/power_series_poly.pyx @@ -7,7 +7,12 @@ The class ``PowerSeries_poly`` provides additional methods for univariate power from sage.rings.power_series_ring_element cimport PowerSeries from sage.structure.element cimport Element from sage.rings.infinity import infinity -from sage.libs.pari.all import pari_gen, PariError + +try: + from sage.libs.pari.all import pari_gen, PariError +except ImportError: + pari_gen = () + PariError = () cdef class PowerSeries_poly(PowerSeries): diff --git a/src/sage/rings/power_series_ring.py b/src/sage/rings/power_series_ring.py index 0349bfbe373..739525a9974 100644 --- a/src/sage/rings/power_series_ring.py +++ b/src/sage/rings/power_series_ring.py @@ -152,7 +152,6 @@ from sage.rings.polynomial.multi_polynomial_ring_base import is_MPolynomialRing from sage.rings.polynomial.polynomial_ring import is_PolynomialRing from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.power_series_pari import PowerSeries_pari from sage.structure.category_object import normalize_names from sage.structure.element import Expression, parent from sage.structure.nonexact import Nonexact @@ -168,6 +167,13 @@ from sage.categories.complete_discrete_valuation import CompleteDiscreteValuationRings +try: + from .laurent_series_ring import LaurentSeriesRing + from .laurent_series_ring_element import LaurentSeries +except ImportError: + LaurentSeriesRing = () + LaurentSeries = () + def PowerSeriesRing(base_ring, name=None, arg2=None, names=None, sparse=False, default_prec=None, order='negdeglex', @@ -537,11 +543,11 @@ def __init__(self, base_ring, name=None, default_prec=None, sparse=False, ValueError: default_prec (= -5) must be non-negative """ - from sage.rings.finite_rings.finite_field_pari_ffelt import ( - FiniteField_pari_ffelt, - ) - if implementation is None: + try: + from sage.rings.finite_rings.finite_field_pari_ffelt import FiniteField_pari_ffelt + except ImportError: + FiniteField_pari_ffelt = () if isinstance(base_ring, FiniteField_pari_ffelt): implementation = 'pari' else: @@ -571,6 +577,7 @@ def __init__(self, base_ring, name=None, default_prec=None, sparse=False, assert is_MPolynomialRing(self.__mpoly_ring) self.Element = power_series_mpoly.PowerSeries_mpoly elif implementation == 'pari': + from .power_series_pari import PowerSeries_pari self.Element = PowerSeries_pari else: raise ValueError('unknown power series implementation: %r' % implementation) @@ -579,7 +586,7 @@ def __init__(self, base_ring, name=None, default_prec=None, sparse=False, category=getattr(self, '_default_category', _CommutativeRings)) Nonexact.__init__(self, default_prec) - if self.Element is PowerSeries_pari: + if implementation == 'pari': self.__generator = self.element_class(self, R.gen().__pari__()) else: self.__generator = self.element_class(self, R.gen(), is_gen=True) @@ -805,7 +812,7 @@ def _element_constructor_(self, f, prec=infinity, check=True): if prec >= f.prec(): return f f = f.truncate(prec) - elif isinstance(f, laurent_series_ring_element.LaurentSeries) and f.parent().power_series_ring() is self: + elif isinstance(f, LaurentSeries) and f.parent().power_series_ring() is self: return self(f.power_series(), prec, check=check) elif isinstance(f, MagmaElement) and str(f.Type()) == 'RngSerPowElt': v = sage_eval(f.Eltseq()) @@ -953,9 +960,8 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): return True # this is allowed. if base_map is None and not codomain.has_coerce_map_from(self.base_ring()): return False - from .laurent_series_ring import is_LaurentSeriesRing v = im_gens[0] - if is_PowerSeriesRing(codomain) or is_LaurentSeriesRing(codomain): + if is_PowerSeriesRing(codomain) or isinstance(codomain, LaurentSeriesRing): try: return v.valuation() > 0 or v.is_nilpotent() except NotImplementedError: @@ -1270,8 +1276,10 @@ def laurent_series_ring(self): try: return self.__laurent_series_ring except AttributeError: - self.__laurent_series_ring = laurent_series_ring.LaurentSeriesRing( - self.base_ring(), self.variable_name(), default_prec=self.default_prec(), sparse=self.is_sparse()) + from .laurent_series_ring import LaurentSeriesRing + + self.__laurent_series_ring = LaurentSeriesRing( + self.base_ring(), self.variable_name(), default_prec=self.default_prec(), sparse=self.is_sparse()) return self.__laurent_series_ring diff --git a/src/sage/rings/puiseux_series_ring_element.pyx b/src/sage/rings/puiseux_series_ring_element.pyx index 39edce35bc9..3f50fb45e2e 100644 --- a/src/sage/rings/puiseux_series_ring_element.pyx +++ b/src/sage/rings/puiseux_series_ring_element.pyx @@ -106,7 +106,6 @@ from sage.arith.functions import lcm from sage.arith.misc import gcd from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ -from sage.rings.complex_mpfr import ComplexField from sage.rings.infinity import infinity from sage.rings.laurent_series_ring_element cimport LaurentSeries from sage.structure.element cimport (Element, AlgebraElement) @@ -308,6 +307,7 @@ cdef class PuiseuxSeries(AlgebraElement): if isinstance(x, int): x = ZZ(x) elif isinstance(x, float): + from sage.rings.complex_mpfr import ComplexField x = ComplexField()(x) t = x.nth_root(self._e) p = self._l.__u.polynomial() diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 5fc675ffd83..9c286af01ec 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -1525,7 +1525,7 @@ def _factor_univariate_polynomial(self, f): (12) * (x - 0.5773502691896258?) * (x + 0.5773502691896258?) sage: AA._factor_univariate_polynomial(12*x^2 + 4) (12) * (x^2 + 0.3333333333333334?) - sage: AA._factor_univariate_polynomial(EllipticCurve('11a1').change_ring(AA).division_polynomial(5)) # needs sage.schemes + sage: AA._factor_univariate_polynomial(EllipticCurve('11a1').change_ring(AA).division_polynomial(5)) # needs sage.schemes (5) * (x - 16.00000000000000?) * (x - 5.000000000000000?) * (x - 1.959674775249769?) * (x + 2.959674775249769?) * (x^2 - 2.854101966249685?*x + 15.47213595499958?) * (x^2 + 1.909830056250526?*x + 1.660606461254312?) * (x^2 + 3.854101966249685?*x + 6.527864045000421?) * (x^2 + 13.09016994374948?*x + 93.33939353874569?) """ @@ -2901,7 +2901,7 @@ def cmp_elements_with_same_minpoly(a, b, p): Compare the algebraic elements ``a`` and ``b`` knowing that they have the same minimal polynomial ``p``. - This is an helper function for comparison of algebraic elements (i.e. the + This is a helper function for comparison of algebraic elements (i.e. the methods :meth:`AlgebraicNumber._richcmp_` and :meth:`AlgebraicReal._richcmp_`). diff --git a/src/sage/rings/qqbar_decorators.py b/src/sage/rings/qqbar_decorators.py index c0505b11e8b..e1e3b908c8c 100644 --- a/src/sage/rings/qqbar_decorators.py +++ b/src/sage/rings/qqbar_decorators.py @@ -58,6 +58,7 @@ def wrapper(*args, **kwds): Check that :trac:`29468` is fixed:: + sage: # needs sage.libs.singular sage: J = QQbar['x,y'].ideal('x^2 - y') sage: type(J.groebner_basis()) diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 150e4a523bd..b970456ed9f 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -65,30 +65,41 @@ from cysignals.signals cimport sig_on, sig_off import operator import fractions +import sage.rings.rational_field + from sage.arith.long cimport integer_check_long_py +from sage.categories.morphism cimport Morphism +from sage.categories.map cimport Map from sage.cpython.string cimport char_to_str, str_to_bytes - +from sage.libs.gmp.pylong cimport mpz_set_pylong +from sage.rings.integer cimport Integer, smallInteger +from sage.rings.integer_ring import ZZ +from sage.structure.coerce cimport coercion_model, is_numpy_type +from sage.structure.element cimport Element +from sage.structure.parent cimport Parent from sage.structure.richcmp cimport rich_to_bool_sgn -import sage.rings.rational_field -cimport sage.rings.integer as integer -from sage.rings.integer cimport Integer -from sage.rings.integer_ring import ZZ +RealNumber_classes = () -from sage.structure.coerce cimport is_numpy_type +def _register_real_number_class(cls): + r""" + Register ``cls``. -from sage.libs.gmp.pylong cimport mpz_set_pylong + This is called by ``sage.rings.real_mpfr``, to avoid a cyclic import. + """ + global RealNumber_classes + RealNumber_classes += (cls,) -from sage.structure.coerce cimport coercion_model -from sage.structure.element cimport Element -from sage.structure.parent cimport Parent -from sage.categories.morphism cimport Morphism -from sage.categories.map cimport Map + +RealDouble_classes = (float,) +try: + from sage.rings.real_double import RealDoubleElement + RealDouble_classes += (RealDoubleElement,) +except ImportError: + pass -import sage.rings.real_mpfr -import sage.rings.real_double from libc.stdint cimport uint64_t from sage.libs.gmp.binop cimport mpq_add_z, mpq_mul_z, mpq_div_zz @@ -349,7 +360,7 @@ cpdef rational_power_parts(a, Rational b, factor_limit=10**5) noexcept: c = integer_rational_power(a, b) if c is not None: - return c, integer.smallInteger(1) + return c, smallInteger(1) numer, denom = b.numerator(), b.denominator() if a < factor_limit*factor_limit: @@ -357,7 +368,7 @@ cpdef rational_power_parts(a, Rational b, factor_limit=10**5) noexcept: else: from sage.rings.factorint import factor_trial_division f = factor_trial_division(a, factor_limit) - c = integer.smallInteger(1) + c = smallInteger(1) # The sign is not handled by the loop below. We don't want to # simplify (-1)^(2/3) to 1 (see Issue #15605), so we always move # the sign over to d. Note that the case (-1)^2 is already @@ -367,7 +378,7 @@ cpdef rational_power_parts(a, Rational b, factor_limit=10**5) noexcept: d = c else: # d = -1 - d = integer.smallInteger(-1) + d = smallInteger(-1) for p, e in f: c *= p**((e // denom)*numer) d *= p**(e % denom) @@ -1454,7 +1465,7 @@ cdef class Rational(sage.structure.element.FieldElement): True sage: e.norm() 3/5 - sage: 7.is_norm(K) + sage: 7.is_norm(K) # needs sage.groups Traceback (most recent call last): ... NotImplementedError: is_norm is not implemented unconditionally @@ -2755,7 +2766,7 @@ cdef class Rational(sage.structure.element.FieldElement): sage: (-1/6).sign() -1 """ - return integer.smallInteger(mpq_sgn(self.value)) + return smallInteger(mpq_sgn(self.value)) def mod_ui(Rational self, unsigned long int n): """ @@ -3107,7 +3118,9 @@ cdef class Rational(sage.structure.element.FieldElement): """ if self.is_zero(): raise ArithmeticError("Support of 0 not defined.") - return sage.arith.all.prime_factors(self) + from sage.arith.misc import prime_factors + + return prime_factors(self) def log(self, m=None, prec=None): r""" diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index 341c0d536d0..8e54c459651 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -18,9 +18,9 @@ sage: RealField(9).pi() # needs sage.rings.real_mpfr 3.1 - sage: QQ(RealField(9).pi()) # needs sage.rings.real_mpfr + sage: QQ(RealField(9).pi()) # needs sage.rings.real_interval_field sage.rings.real_mpfr 22/7 - sage: QQ(RealField().pi()) # needs sage.rings.real_mpfr + sage: QQ(RealField().pi()) # needs sage.rings.real_interval_field sage.rings.real_mpfr 245850922/78256779 sage: QQ(35) 35 diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index 19c9501bcf8..ba0b77150ad 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -50,6 +50,7 @@ from sage.cpython.python_debug cimport if_Py_TRACE_REFS_then_PyObject_INIT import math +import sage.arith.misc import sage.rings.integer import sage.rings.rational @@ -1955,7 +1956,7 @@ cdef class RealDoubleElement(FieldElement): sage: r.algebraic_dependency(5) # needs sage.libs.pari x^2 - 2 """ - return sage.arith.all.algdep(self,n) + return sage.arith.misc.algdep(self,n) algdep = algebraic_dependency @@ -2079,7 +2080,7 @@ else: # It operates on the following principles: # # - The pool starts out empty. -# - When an new element is needed, one from the pool is returned +# - When a new element is needed, one from the pool is returned # if available, otherwise a new RealDoubleElement object is created # - When an element is collected, it will add it to the pool # if there is room, otherwise it will be deallocated. diff --git a/src/sage/rings/real_field.py b/src/sage/rings/real_field.py index 6f424b90fc8..7b8e17eb5b9 100644 --- a/src/sage/rings/real_field.py +++ b/src/sage/rings/real_field.py @@ -35,11 +35,11 @@ def create_RealField(prec=53, type="MPFR", rnd="RNDN", sci_not=0): sage: from sage.rings.real_field import create_RealField sage: create_RealField(30) Real Field with 30 bits of precision - sage: create_RealField(20, 'RDF') # ignores precision + sage: create_RealField(20, 'RDF') # ignores precision Real Double Field - sage: create_RealField(60, 'Interval') + sage: create_RealField(60, 'Interval') # needs sage.rings.real_interval_field Real Interval Field with 60 bits of precision - sage: create_RealField(40, 'RLF') # ignores precision + sage: create_RealField(40, 'RLF') # ignores precision # needs sage.rings.real_interval_field Real Lazy Field """ if type == "RDF": diff --git a/src/sage/rings/real_lazy.pyx b/src/sage/rings/real_lazy.pyx index e765cdfe801..a426a922d6d 100644 --- a/src/sage/rings/real_lazy.pyx +++ b/src/sage/rings/real_lazy.pyx @@ -1,4 +1,4 @@ -# sage.doctest: needs sage.rings.real_mpfr +# sage.doctest: needs sage.rings.real_interval_field sage.rings.real_mpfr """ Lazy real and complex numbers @@ -50,12 +50,16 @@ from sage.rings.integer import Integer cdef QQ, RR, CC, RealField, ComplexField from sage.rings.rational_field import QQ -try: - from sage.rings.real_mpfr import RR, RealField - from sage.rings.complex_mpfr import ComplexField - from sage.rings.cc import CC -except ImportError: - pass +cdef late_import(): + global RR, CC, RealField, ComplexField + if CC is not None: + return + try: + from sage.rings.real_mpfr import RR, RealField + from sage.rings.complex_mpfr import ComplexField + from sage.rings.cc import CC + except ImportError: + pass cdef _QQx = None @@ -1611,6 +1615,9 @@ cdef class LazyAlgebraic(LazyFieldElement): if self._poly.degree() == 2: c, b, a = self._poly.list() self._quadratic_disc = b*b - 4*a*c + + late_import() + if isinstance(parent, RealLazyField_class): if not self._poly.number_of_real_roots(): raise ValueError("%s has no real roots" % self._poly) diff --git a/src/sage/rings/real_mpfi.pyx b/src/sage/rings/real_mpfi.pyx index 58e3d8de737..47c24f7261b 100644 --- a/src/sage/rings/real_mpfi.pyx +++ b/src/sage/rings/real_mpfi.pyx @@ -258,6 +258,8 @@ from cpython.object cimport Py_EQ, Py_NE, Py_LT, Py_LE, Py_GT, Py_GE from cysignals.signals cimport sig_on, sig_off +import sage.arith.misc + from sage.libs.gmp.mpz cimport * from sage.libs.mpfr cimport * from sage.libs.mpfi cimport * @@ -5035,7 +5037,7 @@ cdef class RealIntervalFieldElement(RingElement): known_bits = -self.relative_diameter().log2() - return sage.arith.all.algdep(self.center(), n, known_bits=known_bits) + return sage.arith.misc.algdep(self.center(), n, known_bits=known_bits) def factorial(self): """ diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index ba6a1bda129..a91b58d3268 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -117,49 +117,43 @@ Make sure we don't have a new field for every new literal:: # https://www.gnu.org/licenses/ # ***************************************************************************** -import math # for log -import sys +import math # for log +import operator import re +import sys from cpython.object cimport Py_NE, Py_EQ from cysignals.signals cimport sig_on, sig_off +import sage.arith.misc +import sage.misc.weak_dict +import sage.rings.abc +import sage.rings.infinity +import sage.rings.rational_field + +from sage.arith.constants cimport M_LN2_LN10 +from sage.arith.long cimport is_small_python_int +from sage.arith.numerical_approx cimport digits_to_bits +from sage.categories.map cimport Map +from sage.cpython.string cimport char_to_str, str_to_bytes from sage.ext.stdsage cimport PY_NEW -from sage.libs.gmp.pylong cimport mpz_set_pylong from sage.libs.gmp.mpz cimport * +from sage.libs.gmp.pylong cimport mpz_set_pylong from sage.libs.mpfr cimport * +from sage.libs.mpmath.utils cimport mpfr_to_mpfval from sage.misc.randstate cimport randstate, current_randstate -from sage.cpython.string cimport char_to_str, str_to_bytes from sage.misc.superseded import deprecation_cython as deprecation - -from sage.structure.element cimport Element -from sage.structure.element cimport have_same_parent -from sage.structure.richcmp cimport rich_to_bool_sgn -cdef bin_op -from sage.structure.element import bin_op - -import sage.misc.weak_dict - -import operator - -from sage.libs.mpmath.utils cimport mpfr_to_mpfval - from sage.rings.integer cimport Integer from sage.rings.rational cimport Rational - -from sage.categories.map cimport Map - from sage.rings.real_double cimport RealDoubleElement - -import sage.rings.abc -import sage.rings.rational_field - -import sage.rings.infinity from sage.rings.ring import Ring +from sage.structure.element cimport Element +from sage.structure.element cimport have_same_parent +from sage.structure.parent_gens cimport ParentWithGens +from sage.structure.richcmp cimport rich_to_bool_sgn -from sage.arith.numerical_approx cimport digits_to_bits -from sage.arith.constants cimport M_LN2_LN10 -from sage.arith.long cimport is_small_python_int +cdef bin_op +from sage.structure.element import bin_op try: from cypari2 import Gen @@ -1284,6 +1278,7 @@ cdef class RealField_class(sage.rings.abc.RealField): TESTS:: + sage: # needs sage.libs.pari sage: k = RealField(100) sage: R. = k[] sage: k._factor_univariate_polynomial( x ) @@ -5324,7 +5319,7 @@ cdef class RealNumber(sage.structure.element.RingElement): sage: r.algebraic_dependency(5) x^2 - 2 """ - return sage.arith.all.algdep(self,n) + return sage.arith.misc.algdep(self,n) algdep = algebraic_dependency @@ -6013,6 +6008,11 @@ cdef class int_toRR(Map): return y +# Hook into Rational +from sage.rings.rational import _register_real_number_class +_register_real_number_class(RealNumber) + + # Support Python's numbers abstract base class import numbers numbers.Real.register(RealNumber) diff --git a/src/sage/rings/ring_extension.pyx b/src/sage/rings/ring_extension.pyx index 0388689a3e2..12892b91287 100644 --- a/src/sage/rings/ring_extension.pyx +++ b/src/sage/rings/ring_extension.pyx @@ -1786,7 +1786,7 @@ cdef class RingExtension_generic(CommutativeAlgebra): r""" Return the defining morphism of the fraction field of this extension. - This is an helper function. + This is a helper function. INPUT: diff --git a/src/sage/rings/tate_algebra.py b/src/sage/rings/tate_algebra.py index 839d0e05b18..2905efdb7a8 100644 --- a/src/sage/rings/tate_algebra.py +++ b/src/sage/rings/tate_algebra.py @@ -27,9 +27,9 @@ :func:`sage.rings.tate_algebra.TateAlgebra`:: sage: K = Qp(2, 5, print_mode='digits') - sage: A. = TateAlgebra(K) - sage: A - Tate Algebra in x (val >= 0), y (val >= 0) over 2-adic Field with capped relative precision 5 + sage: A. = TateAlgebra(K); A + Tate Algebra in x (val >= 0), y (val >= 0) + over 2-adic Field with capped relative precision 5 As we observe, the default value for the log radii of convergence is `0` (the series then converge on the closed unit disc). @@ -37,13 +37,15 @@ We can specify different log radii using the following syntax:: sage: B. = TateAlgebra(K, log_radii=[1,2]); B - Tate Algebra in u (val >= -1), v (val >= -2) over 2-adic Field with capped relative precision 5 + Tate Algebra in u (val >= -1), v (val >= -2) + over 2-adic Field with capped relative precision 5 Note that if we pass in the ring of integers of `p`-adic field, the same Tate algebra is returned:: sage: A1. = TateAlgebra(K.integer_ring()); A1 - Tate Algebra in x (val >= 0), y (val >= 0) over 2-adic Field with capped relative precision 5 + Tate Algebra in x (val >= 0), y (val >= 0) + over 2-adic Field with capped relative precision 5 sage: A is A1 True @@ -51,9 +53,9 @@ of a Tate algebra, that is the subring consisting of series bounded by `1` on the domain of convergence:: - sage: Ao = A.integer_ring() - sage: Ao - Integer ring of the Tate Algebra in x (val >= 0), y (val >= 0) over 2-adic Field with capped relative precision 5 + sage: Ao = A.integer_ring(); Ao + Integer ring of the Tate Algebra in x (val >= 0), y (val >= 0) + over 2-adic Field with capped relative precision 5 Now we can build elements:: @@ -67,7 +69,8 @@ sage: f + g ...00001*x^3*y + ...00101 + ...000010*x*y^3 + ...000010*x*y + ...0000100*x^2*y^2 sage: f * g - ...00101*x^3*y + ...000010*x^4*y^4 + ...001010*x*y + ...0000100*x^5*y^3 + ...0000100*x^2*y^4 + ...00001000*x^3*y^3 + ...00101*x^3*y + ...000010*x^4*y^4 + ...001010*x*y + + ...0000100*x^5*y^3 + ...0000100*x^2*y^4 + ...00001000*x^3*y^3 An element in the integer ring is invertible if and only if its reduction modulo `p` is a nonzero constant. In our example, @@ -193,7 +196,8 @@ class TateAlgebraFactory(UniqueFactory): sage: R = Zp(2, 10, print_mode='digits'); R 2-adic Ring with capped relative precision 10 sage: A. = TateAlgebra(R, order='lex'); A - Tate Algebra in x (val >= 0), y (val >= 0) over 2-adic Field with capped relative precision 10 + Tate Algebra in x (val >= 0), y (val >= 0) + over 2-adic Field with capped relative precision 10 We observe that the result is the Tate algebra over the fraction field of `R` and not `R` itself:: @@ -207,7 +211,8 @@ class TateAlgebraFactory(UniqueFactory): we must use the method :meth:`integer_ring`:: sage: Ao = A.integer_ring(); Ao - Integer ring of the Tate Algebra in x (val >= 0), y (val >= 0) over 2-adic Field with capped relative precision 10 + Integer ring of the Tate Algebra in x (val >= 0), y (val >= 0) + over 2-adic Field with capped relative precision 10 sage: Ao.base_ring() 2-adic Ring with capped relative precision 10 sage: Ao.base_ring() is R @@ -847,15 +852,19 @@ def _pushout_(self, R): sage: A. = TateAlgebra(R, log_radii=[1,2]) sage: A1 = pushout(A, R1); A1 - Tate Algebra in u (val >= -1), v (val >= -2) over 2-adic Unramified Extension Field in a defined by x^2 + x + 1 + Tate Algebra in u (val >= -1), v (val >= -2) + over 2-adic Unramified Extension Field in a defined by x^2 + x + 1 sage: A2 = pushout(A, R2); A2 - Tate Algebra in u (val >= -2), v (val >= -4) over 2-adic Eisenstein Extension Field in pi defined by x^2 - 2 + Tate Algebra in u (val >= -2), v (val >= -4) + over 2-adic Eisenstein Extension Field in pi defined by x^2 - 2 sage: Ao = A.integer_ring() sage: pushout(Ao, R1) - Integer ring of the Tate Algebra in u (val >= -1), v (val >= -2) over 2-adic Unramified Extension Field in a defined by x^2 + x + 1 + Integer ring of the Tate Algebra in u (val >= -1), v (val >= -2) + over 2-adic Unramified Extension Field in a defined by x^2 + x + 1 sage: pushout(Ao, R2.fraction_field()) - Tate Algebra in u (val >= -2), v (val >= -4) over 2-adic Eisenstein Extension Field in pi defined by x^2 - 2 + Tate Algebra in u (val >= -2), v (val >= -4) + over 2-adic Eisenstein Extension Field in pi defined by x^2 - 2 TESTS:: @@ -1243,20 +1252,23 @@ def random_element(self, degree=2, terms=5, integral=False, prec=None): sage: R = Zp(2, prec=10, print_mode="digits") sage: A. = TateAlgebra(R) sage: A.random_element() # random - (...00101000.01)*y + ...1111011111*x^2 + ...0010010001*x*y + ...110000011 + ...010100100*y^2 + (...00101000.01)*y + ...1111011111*x^2 + ...0010010001*x*y + + ...110000011 + ...010100100*y^2 sage: A.random_element(degree=5, terms=3) # random (...0101100.01)*x^2*y + (...01000011.11)*y^2 + ...00111011*x*y sage: A.random_element(integral=True) # random - ...0001111101*x + ...1101110101 + ...00010010110*y + ...101110001100*x*y + ...000001100100*y^2 + ...0001111101*x + ...1101110101 + ...00010010110*y + + ...101110001100*x*y + ...000001100100*y^2 Note that if we are already working on the ring of integers, specifying ``integral=False`` has no effect:: sage: Ao = A.integer_ring() sage: f = Ao.random_element(integral=False); f # random - ...1100111011*x^2 + ...1110100101*x + ...1100001101*y + ...1110110001 + ...01011010110*y^2 + ...1100111011*x^2 + ...1110100101*x + ...1100001101*y + + ...1110110001 + ...01011010110*y^2 sage: f in Ao True @@ -1265,7 +1277,9 @@ def random_element(self, degree=2, terms=5, integral=False, prec=None): sage: B. = TateAlgebra(R, log_radii=[-1,-2]) sage: B.random_element(integral=True) # random - (...1111111.001)*x*y + (...111000101.1)*x + (...11010111.01)*y^2 + ...0010011011*y + ...0010100011000 + (...1111111.001)*x*y + (...111000101.1)*x + (...11010111.01)*y^2 + + ...0010011011*y + ...0010100011000 + """ if integral or self._integral: polring = self._polynomial_ring.change_ring(self._field.integer_ring()) diff --git a/src/sage/rings/valuation/gauss_valuation.py b/src/sage/rings/valuation/gauss_valuation.py index 759d2a4e03e..a69977ae4b3 100644 --- a/src/sage/rings/valuation/gauss_valuation.py +++ b/src/sage/rings/valuation/gauss_valuation.py @@ -788,7 +788,7 @@ def simplify(self, f, error=None, force=False, size_heuristic_bound=32, effectiv def lower_bound(self, f): r""" - Return an lower bound of this valuation at ``f``. + Return a lower bound of this valuation at ``f``. Use this method to get an approximation of the valuation of ``f`` when speed is more important than accuracy. diff --git a/src/sage/rings/valuation/mapped_valuation.py b/src/sage/rings/valuation/mapped_valuation.py index d5b3248ef1d..2c4aa42799d 100644 --- a/src/sage/rings/valuation/mapped_valuation.py +++ b/src/sage/rings/valuation/mapped_valuation.py @@ -560,7 +560,7 @@ def simplify(self, x, error=None, force=False): def lower_bound(self, x): r""" - Return an lower bound of this valuation at ``x``. + Return a lower bound of this valuation at ``x``. Use this method to get an approximation of the valuation of ``x`` when speed is more important than accuracy. diff --git a/src/sage/rings/valuation/valuation.py b/src/sage/rings/valuation/valuation.py index 62c5dac33d7..0121f6a6b25 100644 --- a/src/sage/rings/valuation/valuation.py +++ b/src/sage/rings/valuation/valuation.py @@ -481,7 +481,7 @@ def mac_lane_approximants(self, G, assume_squarefree=False, require_final_EF=Tru [ Gauss valuation induced by (x + 1)-adic valuation, v(y) = 7/2 ], [ Gauss valuation induced by (x + 1)-adic valuation, v(y^13 + y^12 + y^10 + y^7 + y^6 + y^3 + 1) = 1 ]] sage: v0 = valuations.FunctionFieldValuation(K, GaussValuation(K._ring, valuations.TrivialValuation(k)).augmentation(x^3+x^2+1,1)) - sage: v0.mac_lane_approximants(F, assume_squarefree=True) # assumes squarefree for speed # needs sage.rings.function_field + sage: v0.mac_lane_approximants(F, assume_squarefree=True) # assumes squarefree for speed [[ Gauss valuation induced by (x^3 + x^2 + 1)-adic valuation, v(y + x^3 + x^2 + x) = 2, v(y^2 + (x^6 + x^4 + 1)*y + x^14 + x^10 + x^9 + x^8 + x^5 + x^4 + x^3 + x^2 + x) = 5 ], [ Gauss valuation induced by (x^3 + x^2 + 1)-adic valuation, v(y^2 + (x^2 + x)*y + 1) = 1 ], [ Gauss valuation induced by (x^3 + x^2 + 1)-adic valuation, v(y^3 + (x + 1)*y^2 + (x + 1)*y + x^2 + x + 1) = 1 ], diff --git a/src/sage/sandpiles/sandpile.py b/src/sage/sandpiles/sandpile.py index b15323532b7..430532461f2 100644 --- a/src/sage/sandpiles/sandpile.py +++ b/src/sage/sandpiles/sandpile.py @@ -3223,7 +3223,7 @@ def __neg__(self): # recurrent addition or multiplication on the right by an integer def __mul__(self, other): r""" - If ``other`` is an configuration, the recurrent element equivalent + If ``other`` is a configuration, the recurrent element equivalent to the sum. If ``other`` is an integer, the sum of configuration with itself ``other`` times. diff --git a/src/sage/schemes/affine/affine_space.py b/src/sage/schemes/affine/affine_space.py index ef1ae326a43..fdf38862068 100644 --- a/src/sage/schemes/affine/affine_space.py +++ b/src/sage/schemes/affine/affine_space.py @@ -270,10 +270,10 @@ def rational_points(self, F=None): if F is None: if not isinstance(self.base_ring(), FiniteField): raise TypeError("base ring (= %s) must be a finite field" % self.base_ring()) - return [P for P in self] + return list(self) elif not isinstance(F, FiniteField): raise TypeError("second argument (= %s) must be a finite field" % F) - return [P for P in self.base_extend(F)] + return list(self.base_extend(F)) def __eq__(self, right): """ @@ -1226,7 +1226,7 @@ def translation(self, p, q=None): if q is not None: v = [cp - cq for cp, cq in zip(p, q)] else: - v = [cp for cp in p] + v = list(p) return self._morphism(self.Hom(self), [x - c for x, c in zip(gens, v)]) diff --git a/src/sage/schemes/curves/affine_curve.py b/src/sage/schemes/curves/affine_curve.py index e1032861b2f..d5d97e5e044 100644 --- a/src/sage/schemes/curves/affine_curve.py +++ b/src/sage/schemes/curves/affine_curve.py @@ -684,13 +684,13 @@ def tangents(self, P, factor=True): if t > 0: fact.append(vars[0]) # divide T by that power of vars[0] - T = self.ambient_space().coordinate_ring()(dict([((v[0] - t, v[1]), h) for (v, h) in T.dict().items()])) + T = self.ambient_space().coordinate_ring()({(v[0] - t, v[1]): h for (v, h) in T.dict().items()}) t = min([e[1] for e in T.exponents()]) # vars[1] divides T if t > 0: fact.append(vars[1]) # divide T by that power of vars[1] - T = self.ambient_space().coordinate_ring()(dict([((v[0], v[1] - t), h) for (v, h) in T.dict().items()])) + T = self.ambient_space().coordinate_ring()({(v[0], v[1] - t): h for (v, h) in T.dict().items()}) # T is homogeneous in var[0], var[1] if nonconstant, so dehomogenize if T not in self.base_ring(): if T.degree(vars[0]) > 0: @@ -1032,7 +1032,7 @@ def projection(self, indices, AS=None): C = AA2.curve(G) except (TypeError, ValueError): C = AA2.subscheme(G) - return tuple([psi, C]) + return (psi, C) def plane_projection(self, AP=None): r""" @@ -1397,7 +1397,7 @@ def blowup(self, P=None): homvars.insert(i, 1) coords = [(p_A.gens()[0] - P[i])*homvars[j] + P[j] for j in range(n)] proj_maps.append(H(coords)) - return tuple([tuple(patches), tuple(t_maps), tuple(proj_maps)]) + return (tuple(patches), tuple(t_maps), tuple(proj_maps)) def resolution_of_singularities(self, extend=False): r""" @@ -1688,7 +1688,7 @@ def extension(self): patches = [res[i][0] for i in range(len(res))] t_maps = [tuple(res[i][1]) for i in range(len(res))] p_maps = [res[i][2] for i in range(len(res))] - return tuple([tuple(patches), tuple(t_maps), tuple(p_maps)]) + return (tuple(patches), tuple(t_maps), tuple(p_maps)) def tangent_line(self, p): """ @@ -2600,7 +2600,7 @@ def places_at_infinity(self): sage: C.places_at_infinity() [Place (1/x, 1/x*z^2)] """ - return list(set(p for f in self._coordinate_functions if f for p in f.poles())) + return list({p for f in self._coordinate_functions if f for p in f.poles()}) def places_on(self, point): """ diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py index 7c82026b3c1..9480d761f61 100644 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -495,7 +495,7 @@ def projection(self, P=None, PS=None): phi = K(l) G = [phi(f) for f in J.gens()] C = PP2.curve(G) - return tuple([psi, C]) + return (psi, C) def plane_projection(self, PP=None): r""" @@ -577,7 +577,7 @@ def plane_projection(self, PP=None): psi = K(phi.defining_polynomials()) H = Hom(self, L[1].ambient_space()) phi = H([psi(L[0].defining_polynomials()[i]) for i in range(len(L[0].defining_polynomials()))]) - return tuple([phi, C]) + return (phi, C) class ProjectivePlaneCurve(ProjectiveCurve): @@ -1104,7 +1104,7 @@ def quadratic_transform(self): T = [] for item in G.dict().items(): tup = tuple([item[0][i] - degs[i] for i in range(len(L))]) - T.append(tuple([tup, item[1]])) + T.append((tup, item[1])) G = R(dict(T)) H = Hom(self, PP.curve(G)) phi = H(coords) diff --git a/src/sage/schemes/curves/zariski_vankampen.py b/src/sage/schemes/curves/zariski_vankampen.py index 0940825b9a5..fa30e97085b 100644 --- a/src/sage/schemes/curves/zariski_vankampen.py +++ b/src/sage/schemes/curves/zariski_vankampen.py @@ -68,7 +68,7 @@ from sage.rings.real_mpfr import RealField # from sage.sets.set import Set -roots_interval_cache = dict() +roots_interval_cache = {} def braid_from_piecewise(strands): @@ -793,7 +793,7 @@ def populate_roots_interval_cache(inputs): @parallel -def braid_in_segment(glist, x0, x1, precision=dict()): +def braid_in_segment(glist, x0, x1, precision={}): """ Return the braid formed by the `y` roots of ``f`` when `x` moves from ``x0`` to ``x1``. @@ -1711,7 +1711,7 @@ def fundamental_group_arrangement(flist, simplified=True, projective=False, puis f = prod(flist1) if len(flist1) == 0: bm = [] - dic = dict() + dic = {} else: bm, dic = braid_monodromy(f, flist1) g = fundamental_group_from_braid_mon(bm, degree=d, simplified=False, projective=projective, puiseux=puiseux) @@ -1721,7 +1721,7 @@ def fundamental_group_arrangement(flist, simplified=True, projective=False, puis hom = g.hom(codomain=g, im_gens=list(g.gens()), check=False) g1 = hom.codomain() if len(flist) == 0: - return (g1, dict()) + return (g1, {}) dic1 = {} for i in range(len(flist1)): L = [j1 for j1 in dic.keys() if dic[j1] == i] diff --git a/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py b/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py index 82504873715..f2d753baf8f 100644 --- a/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py +++ b/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py @@ -921,7 +921,7 @@ def _initialize_fat_vertical(self, s0, max_upper_target): L = floor((max_upper_target - self._epsilon) / self._p) + 1 if s0 not in self._vertical_fat_s: (m0, m1), (M0, M1) = self._vertical_matrix_reduction(s0) - D0, D1 = map(lambda y: matrix(self._Zq, [y]), [m0, m1]) + D0, D1 = (matrix(self._Zq, [y]) for y in [m0, m1]) targets = [0] * (2 * L) for l in reversed(range(L)): targets[2 * l] = max_upper_target - self._p * (L - l) @@ -1268,7 +1268,7 @@ def _denominator(): f = x ** self._delta - lc L = f.splitting_field("a") roots = [r for r, _ in f.change_ring(L).roots()] - roots_dict = dict([(r, i) for i, r in enumerate(roots)]) + roots_dict = {r: i for i, r in enumerate(roots)} rootsfrob = [L.frobenius_endomorphism(self._Fq.degree())(r) for r in roots] m = zero_matrix(len(roots)) for i, r in enumerate(roots): diff --git a/src/sage/schemes/elliptic_curves/BSD.py b/src/sage/schemes/elliptic_curves/BSD.py index 85130f0a5f9..bf3f302b978 100644 --- a/src/sage/schemes/elliptic_curves/BSD.py +++ b/src/sage/schemes/elliptic_curves/BSD.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- "Birch and Swinnerton-Dyer formulas" from sage.arith.misc import prime_divisors diff --git a/src/sage/schemes/elliptic_curves/Qcurves.py b/src/sage/schemes/elliptic_curves/Qcurves.py index 45fb5c51293..c7d3da73691 100644 --- a/src/sage/schemes/elliptic_curves/Qcurves.py +++ b/src/sage/schemes/elliptic_curves/Qcurves.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Testing whether elliptic curves over number fields are `\QQ`-curves diff --git a/src/sage/schemes/elliptic_curves/cm.py b/src/sage/schemes/elliptic_curves/cm.py index 03acc69e732..58bed0a67a4 100644 --- a/src/sage/schemes/elliptic_curves/cm.py +++ b/src/sage/schemes/elliptic_curves/cm.py @@ -973,7 +973,7 @@ def is_cm_j_invariant(j, algorithm='CremonaSutherland', method=None): if j in ZZ: j = ZZ(j) - table = dict([(jj,(d,f)) for d,f,jj in cm_j_invariants_and_orders(QQ)]) + table = {jj: (d,f) for d,f,jj in cm_j_invariants_and_orders(QQ)} if j in table: return True, table[j] return False, None diff --git a/src/sage/schemes/elliptic_curves/ec_database.py b/src/sage/schemes/elliptic_curves/ec_database.py index 043c287ec7e..f66ee2d1d31 100644 --- a/src/sage/schemes/elliptic_curves/ec_database.py +++ b/src/sage/schemes/elliptic_curves/ec_database.py @@ -136,7 +136,7 @@ def rank(self, rank, tors=0, n=10, labels=False): data = os.path.join(ELLCURVE_DATA_DIR, 'rank%s' % rank) try: f = open(data) - except IOError: + except OSError: return [] v = [] tors = int(tors) diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index 59bf8882f1f..68e9c3fc79d 100644 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Isogenies @@ -1953,7 +1952,7 @@ def __sort_kernel_list(self): """ a1, a2, a3, a4, _ = self._domain.a_invariants() - self.__kernel_mod_sign = dict() + self.__kernel_mod_sign = {} v = w = 0 for Q in self.__kernel_list: @@ -3464,6 +3463,15 @@ def compute_isogeny_stark(E1, E2, ell): sage: E2 = phi.codomain() sage: compute_isogeny_stark(E, E2, 2) x + + TESTS: + + Check for :issue:`21883`:: + + sage: E1 = EllipticCurve([0,1]) + sage: E2 = EllipticCurve([0,-27]) + sage: E1.isogeny(None, E2, degree=3) + Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 27 over Rational Field """ K = E1.base_field() R, x = PolynomialRing(K, 'x').objgen() @@ -3477,8 +3485,8 @@ def compute_isogeny_stark(E1, E2, ell): for i in range(2*ell + 1): pe1 += wp1[2*i] * Z**i pe2 += wp2[2*i] * Z**i - pe1 = pe1.add_bigoh(2*ell+2) - pe2 = pe2.add_bigoh(2*ell+2) + pe1 = pe1.add_bigoh(2*ell+3) + pe2 = pe2.add_bigoh(2*ell+3) n = 1 q = [R.one(), R.zero()] diff --git a/src/sage/schemes/elliptic_curves/ell_generic.py b/src/sage/schemes/elliptic_curves/ell_generic.py index 5b569ae54e3..57003863b1b 100644 --- a/src/sage/schemes/elliptic_curves/ell_generic.py +++ b/src/sage/schemes/elliptic_curves/ell_generic.py @@ -169,7 +169,7 @@ def __init__(self, K, ainvs): - (x**3 + a2*x**2*z + a4*x*z**2 + a6*z**3) plane_curve.ProjectivePlaneCurve.__init__(self, PP, f) - self.__divpolys = (dict(), dict(), dict()) + self.__divpolys = ({}, {}, {}) # See #1975: we deliberately set the class to # EllipticCurvePoint_finite_field for finite rings, so that we @@ -1732,7 +1732,7 @@ def division_polynomial_0(self, n, x=None): x = polygen(self.base_ring()) else: # For other inputs, we use a temporary cache. - cache = dict() + cache = {} b2, b4, b6, b8 = self.b_invariants() @@ -2119,7 +2119,7 @@ def _multiple_x_numerator(self, n, x=None): try: cache = self.__mulxnums except AttributeError: - cache = self.__mulxnums = dict() + cache = self.__mulxnums = {} try: return cache[n] except KeyError: @@ -2216,7 +2216,7 @@ def _multiple_x_denominator(self, n, x=None): try: cache = self.__mulxdens except AttributeError: - cache = self.__mulxdens = dict() + cache = self.__mulxdens = {} try: return cache[n] except KeyError: diff --git a/src/sage/schemes/elliptic_curves/ell_local_data.py b/src/sage/schemes/elliptic_curves/ell_local_data.py index 11a0e9db661..a71bc7fd25f 100644 --- a/src/sage/schemes/elliptic_curves/ell_local_data.py +++ b/src/sage/schemes/elliptic_curves/ell_local_data.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Local data for elliptic curves over number fields @@ -1199,7 +1198,7 @@ def check_prime(K, P): raise TypeError("%s is not a number field" % (K,)) if is_NumberFieldFractionalIdeal(P) or P in K: - # if P is an ideal, making sure it is an fractional ideal of K + # if P is an ideal, making sure it is a fractional ideal of K P = K.fractional_ideal(P) if P.is_prime(): return P diff --git a/src/sage/schemes/elliptic_curves/ell_modular_symbols.py b/src/sage/schemes/elliptic_curves/ell_modular_symbols.py index 243df1d23f0..055c7eaec45 100644 --- a/src/sage/schemes/elliptic_curves/ell_modular_symbols.py +++ b/src/sage/schemes/elliptic_curves/ell_modular_symbols.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Modular symbols attached to elliptic curves over `\QQ` diff --git a/src/sage/schemes/elliptic_curves/ell_number_field.py b/src/sage/schemes/elliptic_curves/ell_number_field.py index 8e2993b3375..5e7a5731ea8 100644 --- a/src/sage/schemes/elliptic_curves/ell_number_field.py +++ b/src/sage/schemes/elliptic_curves/ell_number_field.py @@ -672,9 +672,8 @@ def global_integral_model(self): """ K = self.base_field() ai = self.a_invariants() - Ps = set(ff[0] - for a in ai if not a.is_integral() - for ff in a.denominator_ideal().factor()) + Ps = {ff[0] for a in ai if not a.is_integral() + for ff in a.denominator_ideal().factor()} for P in Ps: pi = K.uniformizer(P, 'positive') e = min((ai[i].valuation(P)/[1,2,3,4,6][i]) @@ -2919,6 +2918,18 @@ class number is only `3` is that the class also contains three sage: E = EllipticCurve([a+1, 1, 1, 0, 0]) sage: C = E.isogeny_class(); len(C) # long time 4 + + Check that :issue:`36780` is fixed:: + + sage: L5. = NumberField(x^2-5) + sage: F = EllipticCurve(L5,[0,-4325477943600 *r5-4195572876000]) + sage: F.isogeny_class().matrix() + [ 1 25 75 3 5 15] + [25 1 3 75 5 15] + [75 3 1 25 15 5] + [ 3 75 25 1 15 5] + [ 5 5 15 15 1 3] + [15 15 5 5 3 1] """ try: return self._isoclass @@ -3283,10 +3294,10 @@ def reducible_primes(self, algorithm='Billerey', max_l=None, For curves without CM the list returned is exactly the finite set of primes `\ell` for which the mod-`\ell` Galois representation is reducible. For curves with CM this set is - infinite; we return a finite list of primes `\ell` such that - every curve isogenous to this curve can be obtained by a - finite sequence of isogenies of degree one of the primes in - the list. + infinite; we return a (not necessarily minimal) finite list + of primes `\ell` such that every curve isogenous to this curve + can be obtained by a finite sequence of isogenies of degree one + of the primes in the list. INPUT: @@ -3328,7 +3339,7 @@ def reducible_primes(self, algorithm='Billerey', max_l=None, sage: rho.reducible_primes() # CM curves always return [0] [0] sage: E.reducible_primes() - [2] + [2, 5] sage: E = EllipticCurve_from_j(K(0)) # CM but NOT over K sage: rho = E.galois_representation() sage: rho.reducible_primes() # long time diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index d35790a13f3..1bf84e9a766 100644 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Points on elliptic curves @@ -1457,7 +1456,7 @@ def _miller_(self, Q, n): - ``Q`` -- a nonzero point on self.curve(). - - ``n`` -- an nonzero integer. If `n<0` then return `Q` + - ``n`` -- a nonzero integer. If `n<0` then return `Q` evaluated at `1/(v_{nP}*f_{n,P})` (used in the ate pairing). OUTPUT: diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 27e52973afd..130eaec9e37 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Elliptic curves over the rational numbers @@ -1559,10 +1558,11 @@ def analytic_rank(self, algorithm="pari", leading_coefficient=False): return self.analytic_rank_upper_bound() elif algorithm == 'all': if leading_coefficient: - S = set([self.analytic_rank('pari', True)]) + S = {self.analytic_rank('pari', True)} else: - S = set([self.analytic_rank('pari'), - self.analytic_rank('rubinstein'), self.analytic_rank('sympow')]) + S = {self.analytic_rank('pari'), + self.analytic_rank('rubinstein'), + self.analytic_rank('sympow')} if len(S) != 1: raise RuntimeError("Bug in analytic_rank; algorithms don't agree! (E=%s)" % self) return list(S)[0] @@ -5347,10 +5347,10 @@ def _shortest_paths(self): # Take logs here since shortest path minimizes the *sum* of the weights -- not the product. M = M.parent()([a.log() if a else 0 for a in M.list()]) G = Graph(M, format='weighted_adjacency_matrix') - G.set_vertices(dict([(v,isocls[v]) for v in G.vertices(sort=False)])) + G.set_vertices({v: isocls[v] for v in G.vertices(sort=False)}) v = G.shortest_path_lengths(0, by_weight=True) # Now exponentiate and round to get degrees of isogenies - v = dict([(i, j.exp().round() if j else 0) for i,j in v.items()]) + v = {i: j.exp().round() if j else 0 for i,j in v.items()} return isocls.curves, v def _multiple_of_degree_of_isogeny_to_optimal_curve(self): @@ -6179,7 +6179,7 @@ def point_preprocessing(free,tor): subgroup of index 2. """ r = len(free) - newfree = [Q for Q in free] # copy + newfree = list(free) # copy tor_egg = [T for T in tor if not T.is_on_identity_component()] free_id = [P.is_on_identity_component() for P in free] if any(tor_egg): @@ -6207,7 +6207,7 @@ def point_preprocessing(free,tor): int_points = [P for P in tors_points if not P.is_zero()] int_points = [P for P in int_points if P[0].is_integral()] if not both_signs: - xlist = set([P[0] for P in int_points]) + xlist = {P[0] for P in int_points} int_points = [self.lift_x(x) for x in xlist] int_points.sort() if verbose: @@ -6800,8 +6800,8 @@ def S_integral_x_coords_with_abs_bounded_by(abs_bound): alpha = [(log_ab/R(log(p,e))).floor() for p in S] if all(alpha_i <= 1 for alpha_i in alpha): # so alpha_i must be 0 to satisfy that denominator is a square int_abs_bound = abs_bound.floor() - return set(x for x in range(-int_abs_bound, int_abs_bound) - if E.is_x_coord(x)) + return {x for x in range(-int_abs_bound, int_abs_bound) + if E.is_x_coord(x)} else: xs = [] alpha_max_even = [y - y % 2 for y in alpha] @@ -6849,7 +6849,7 @@ def S_integral_x_coords_with_abs_bounded_by(abs_bound): int_points = [P for P in tors_points if not P.is_zero()] int_points = [P for P in int_points if P[0].is_S_integral(S)] if not both_signs: - xlist = set([P[0] for P in int_points]) + xlist = {P[0] for P in int_points} int_points = [E.lift_x(x) for x in xlist] int_points.sort() if verbose: diff --git a/src/sage/schemes/elliptic_curves/ell_tate_curve.py b/src/sage/schemes/elliptic_curves/ell_tate_curve.py index 7b616671e24..6f8d861db93 100644 --- a/src/sage/schemes/elliptic_curves/ell_tate_curve.py +++ b/src/sage/schemes/elliptic_curves/ell_tate_curve.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Tate's parametrisation of `p`-adic curves with multiplicative reduction diff --git a/src/sage/schemes/elliptic_curves/ell_torsion.py b/src/sage/schemes/elliptic_curves/ell_torsion.py index 9a39ead60e5..62b75c79fea 100644 --- a/src/sage/schemes/elliptic_curves/ell_torsion.py +++ b/src/sage/schemes/elliptic_curves/ell_torsion.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Torsion subgroups of elliptic curves over number fields (including `\QQ`) diff --git a/src/sage/schemes/elliptic_curves/ell_wp.py b/src/sage/schemes/elliptic_curves/ell_wp.py index 8785976dec3..b7dd052a701 100644 --- a/src/sage/schemes/elliptic_curves/ell_wp.py +++ b/src/sage/schemes/elliptic_curves/ell_wp.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Weierstrass `\wp`-function for elliptic curves diff --git a/src/sage/schemes/elliptic_curves/formal_group.py b/src/sage/schemes/elliptic_curves/formal_group.py index dbd2db5f778..a7dcb48d36c 100644 --- a/src/sage/schemes/elliptic_curves/formal_group.py +++ b/src/sage/schemes/elliptic_curves/formal_group.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Formal groups of elliptic curves diff --git a/src/sage/schemes/elliptic_curves/gal_reps.py b/src/sage/schemes/elliptic_curves/gal_reps.py index c28b4f76d2c..9543215ee24 100644 --- a/src/sage/schemes/elliptic_curves/gal_reps.py +++ b/src/sage/schemes/elliptic_curves/gal_reps.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Galois representations attached to elliptic curves diff --git a/src/sage/schemes/elliptic_curves/gal_reps_number_field.py b/src/sage/schemes/elliptic_curves/gal_reps_number_field.py index 48f742a6cd0..33ada435181 100644 --- a/src/sage/schemes/elliptic_curves/gal_reps_number_field.py +++ b/src/sage/schemes/elliptic_curves/gal_reps_number_field.py @@ -740,10 +740,11 @@ def _exceptionals(E, L, patience=1000): def _over_numberfield(E): r""" - Return `E`, defined over a ``NumberField`` object. + Return `E`, defined over an absolute ``NumberField``. This is necessary since if `E` is defined over `\QQ`, then we - cannot use Sage commands available for number fields. + cannot use Sage commands available for number fields, and if the + base field is relative then other problems result. INPUT: @@ -751,26 +752,27 @@ def _over_numberfield(E): OUTPUT: - - If `E` is defined over a NumberField, returns E. + - If `E` is defined over an absolute number field, returns `E`. - - If `E` is defined over QQ, returns E defined over the NumberField QQ. + - If `E` is defined over a relative number field, returns `E` defined over the absolute base field. + + - If `E` is defined over `\QQ`, returns `E` defined over the number field `\QQ`. EXAMPLES:: sage: E = EllipticCurve([1, 2]) sage: sage.schemes.elliptic_curves.gal_reps_number_field._over_numberfield(E) Elliptic Curve defined by y^2 = x^3 + x + 2 over Number Field in a with defining polynomial x - """ + """ K = E.base_field() if K == QQ: - x = QQ['x'].gen() - K = NumberField(x, 'a') - E = E.change_ring(K) - - return E - + from sage.rings.polynomial.polynomial_ring import polygen + K = NumberField(polygen(QQ), 'a') + else: + K = K.absolute_field('a') + return E.change_ring(K) def deg_one_primes_iter(K, principal_only=False): r""" @@ -858,7 +860,7 @@ def _semistable_reducible_primes(E, verbose=False): deg_one_primes = deg_one_primes_iter(K, principal_only=True) - bad_primes = set([]) # This will store the output. + bad_primes = set() # This will store the output. # We find two primes (of distinct residue characteristics) which are # of degree 1, unramified in K/Q, and at which E has good reduction. @@ -1096,7 +1098,7 @@ def _possible_normalizers(E, SA): W = W + V.span([splitting_vector]) - bad_primes = set([]) + bad_primes = set() for i in traces_list: for p in i.prime_factors(): diff --git a/src/sage/schemes/elliptic_curves/heegner.py b/src/sage/schemes/elliptic_curves/heegner.py index a377c02d5cb..1b5536cc515 100644 --- a/src/sage/schemes/elliptic_curves/heegner.py +++ b/src/sage/schemes/elliptic_curves/heegner.py @@ -844,7 +844,7 @@ def kolyvagin_generators(self): # so we just find a generator. for sigma in self: if sigma.order() == self.cardinality(): - return tuple([sigma]) + return (sigma,) raise NotImplementedError @@ -2568,7 +2568,7 @@ def betas(self): N = self.level() R = Integers(4*N) m = 2*N - return tuple(sorted( set([a % m for a in R(D).sqrt(all=True)]) )) + return tuple(sorted( {a % m for a in R(D).sqrt(all=True)} )) @cached_method def points(self, beta=None): @@ -3776,7 +3776,7 @@ def _square_roots_mod_2N_of_D_mod_4N(self): N = self.__E.conductor() R = Integers(4*N) m = 2*N - return sorted( set([a % m for a in R(self.discriminant()).sqrt(all=True)]) ) + return sorted( {a % m for a in R(self.discriminant()).sqrt(all=True)} ) def _trace_numerical_conductor_1(self, prec=53): """ diff --git a/src/sage/schemes/elliptic_curves/height.py b/src/sage/schemes/elliptic_curves/height.py index 30709dccf96..78736209ee5 100644 --- a/src/sage/schemes/elliptic_curves/height.py +++ b/src/sage/schemes/elliptic_curves/height.py @@ -155,7 +155,7 @@ def is_empty(self): def __add__(left, right): r""" - If both left an right are unions of intervals, take their union, + If both left and right are unions of intervals, take their union, otherwise treat the non-union of intervals as a scalar and shift. EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/isogeny_class.py b/src/sage/schemes/elliptic_curves/isogeny_class.py index ed05e1760fa..1109fd9b93b 100644 --- a/src/sage/schemes/elliptic_curves/isogeny_class.py +++ b/src/sage/schemes/elliptic_curves/isogeny_class.py @@ -410,7 +410,7 @@ def graph(self): M = self.matrix(fill=False) n = len(self) G = Graph(M, format='weighted_adjacency_matrix') - D = dict([(v,self.curves[v]) for v in G.vertices(sort=False)]) + D = {v: self.curves[v] for v in G.vertices(sort=False)} G.set_vertices(D) if self._qfmat: # i.e. self.E.has_rational_cm(): for i in range(n): @@ -424,7 +424,7 @@ def graph(self): n = M.nrows() # = M.ncols() G = Graph(M, format='weighted_adjacency_matrix') N = self.matrix(fill=True) - D = dict([(v,self.curves[v]) for v in G.vertices(sort=False)]) + D = {v: self.curves[v] for v in G.vertices(sort=False)} # The maximum degree classifies the shape of the isogeny # graph, though the number of vertices is often enough. # This only holds over Q, so this code will need to change @@ -876,17 +876,17 @@ def add_tup(t): else: key_function = lambda E: flatten([list(ai) for ai in E.ainvs()]) - self.curves = sorted(curves,key=key_function) - perm = dict([(ind, self.curves.index(Ei)) - for ind, Ei in enumerate(curves)]) + self.curves = sorted(curves, key=key_function) + perm = {ind: self.curves.index(Ei) + for ind, Ei in enumerate(curves)} if verbose: print("Sorting permutation = %s" % perm) mat = MatrixSpace(ZZ, ncurves)(0) self._maps = [[0] * ncurves for _ in range(ncurves)] - for i,j,l,phi in tuples: + for i, j, l, phi in tuples: if phi != 0: - mat[perm[i],perm[j]] = l + mat[perm[i], perm[j]] = l self._maps[perm[i]][perm[j]] = phi self._mat = fill_isogeny_matrix(mat) if verbose: @@ -1109,7 +1109,7 @@ def _compute(self): curves.append(Edash) ijl_triples.append((i,j,l,phi)) if l_list is None: - l_list = [d for d in set([ZZ(f.degree()) for f in isogs])] + l_list = list({ZZ(f.degree()) for f in isogs}) i += 1 self.curves = tuple(curves) ncurves = len(curves) @@ -1135,7 +1135,8 @@ def isogeny_degrees_cm(E, verbose=False): A finite list of primes `\ell` such that every curve isogenous to this curve can be obtained by a finite sequence of isogenies of - degree one of the primes in the list. + degree one of the primes in the list. This list is not + necessarily minimal. ALGORITHM: @@ -1188,8 +1189,20 @@ def isogeny_degrees_cm(E, verbose=False): downward split primes: {2, 3} downward inert primes: {5} primes generating the class group: [2] - Complete set of primes: {2, 3, 5} - [2, 3, 5] + Set of primes before filtering: {2, 3, 5} + List of primes after filtering: [2, 3] + [2, 3] + + TESTS: + + Check that :issue:`36780` is fixed:: + + sage: L5. = NumberField(x^2-5) + sage: E = EllipticCurve(L5,[0,-4325477943600 *r5-4195572876000]) + sage: from sage.schemes.elliptic_curves.isogeny_class import isogeny_degrees_cm + sage: isogeny_degrees_cm(E) + [3, 5] + """ if not E.has_cm(): raise ValueError("possible_isogeny_degrees_cm(E) requires E to be an elliptic curve with CM") @@ -1205,6 +1218,11 @@ def isogeny_degrees_cm(E, verbose=False): n = E.base_field().absolute_degree() if not E.has_rational_cm(): n *= 2 + # For discriminants with extra units there's an extra factor in the class number formula: + if d == -4: + n *= 2 + if d == -3: + n *= 3 divs = n.divisors() data = pari(d).quadclassunit() @@ -1232,7 +1250,7 @@ def isogeny_degrees_cm(E, verbose=False): # of the order O of discriminant d. The latter case can only # happen when l^2 divides d. - # Compute the ramified primes + # (a) ramified primes ram_l = d.odd_part().prime_factors() @@ -1247,25 +1265,22 @@ def isogeny_degrees_cm(E, verbose=False): else: - # Find the "upward" primes (index divided by l): + # "Upward" primes (index divided by l): L1 = Set([l for l in ram_l if d.valuation(l) > 1]) L += L1 if verbose: print("upward primes: %s" % L1) - # Find the "downward" primes (index multiplied by l, class - # number multiplied by l-kronecker_symbol(d,l)): - - # (a) ramified primes; the suborder has class number l*h, so l - # must divide n/2h: + # "Downward" ramified primes; index multiplied by l, class + # number multiplied by l, so l must divide n/2h: L1 = Set([l for l in ram_l if l.divides(n_over_2h)]) L += L1 if verbose: print("downward ramified primes: %s" % L1) - # (b) split primes; the suborder has class number (l-1)*h, so + # (b) Downward split primes; the suborder has class number (l-1)*h, so # l-1 must divide n/2h: L1 = Set([lm1+1 for lm1 in divs @@ -1274,7 +1289,7 @@ def isogeny_degrees_cm(E, verbose=False): if verbose: print("downward split primes: %s" % L1) - # (c) inert primes; the suborder has class number (l+1)*h, so + # (c) Downward inert primes; the suborder has class number (l+1)*h, so # l+1 must divide n/2h: L1 = Set([lp1-1 for lp1 in divs @@ -1283,10 +1298,9 @@ def isogeny_degrees_cm(E, verbose=False): if verbose: print("downward inert primes: %s" % L1) - # Now find primes represented by each form of discriminant d. - # In the rational CM case, we use all forms associated to - # generators of the class group, otherwise only forms of order - # 2: + # Horizontal primes (rational CM only): same order, degrees are + # all integers represented by some binary quadratic form of + # discriminant d, so we find a prime represented by each form. if E.has_rational_cm(): from sage.quadratic_forms.binary_qf import BinaryQF @@ -1300,10 +1314,14 @@ def isogeny_degrees_cm(E, verbose=False): # Return sorted list if verbose: - print("Complete set of primes: %s" % L) - - return sorted(L) + print("Set of primes before filtering: %s" % L) + # This filter will quickly eliminate most false entries in the set + from .gal_reps_number_field import Frobenius_filter + L = Frobenius_filter(E, sorted(L)) + if verbose: + print("List of primes after filtering: %s" % L) + return L def possible_isogeny_degrees(E, algorithm='Billerey', max_l=None, num_l=None, exact=True, verbose=False): @@ -1434,8 +1452,9 @@ def possible_isogeny_degrees(E, algorithm='Billerey', max_l=None, downward split primes: {2, 3} downward inert primes: {5} primes generating the class group: [2] - Complete set of primes: {2, 3, 5} - [2, 3, 5] + Set of primes before filtering: {2, 3, 5} + List of primes after filtering: [2, 3] + [2, 3] """ if E.has_cm(): return isogeny_degrees_cm(E, verbose) diff --git a/src/sage/schemes/elliptic_curves/jacobian.py b/src/sage/schemes/elliptic_curves/jacobian.py index 1a33c7e4726..23151109453 100644 --- a/src/sage/schemes/elliptic_curves/jacobian.py +++ b/src/sage/schemes/elliptic_curves/jacobian.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Construct elliptic curves as Jacobians diff --git a/src/sage/schemes/elliptic_curves/kraus.py b/src/sage/schemes/elliptic_curves/kraus.py index 8565cc5e3be..92a74f4e718 100644 --- a/src/sage/schemes/elliptic_curves/kraus.py +++ b/src/sage/schemes/elliptic_curves/kraus.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Global and semi-global minimal models for elliptic curves over number fields diff --git a/src/sage/schemes/elliptic_curves/lseries_ell.py b/src/sage/schemes/elliptic_curves/lseries_ell.py index 6e1dfa18c52..f3f1533f7d0 100644 --- a/src/sage/schemes/elliptic_curves/lseries_ell.py +++ b/src/sage/schemes/elliptic_curves/lseries_ell.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ `L`-series for elliptic curves diff --git a/src/sage/schemes/elliptic_curves/mod_poly.py b/src/sage/schemes/elliptic_curves/mod_poly.py index 21926e14c8e..2482bb0da5a 100644 --- a/src/sage/schemes/elliptic_curves/mod_poly.py +++ b/src/sage/schemes/elliptic_curves/mod_poly.py @@ -22,7 +22,7 @@ _db = ClassicalModularPolynomialDatabase() _cache_bound = 100 -_cache = dict() +_cache = {} def classical_modular_polynomial(l, j=None): diff --git a/src/sage/schemes/elliptic_curves/mod_sym_num.pyx b/src/sage/schemes/elliptic_curves/mod_sym_num.pyx index 33e509dca96..7cf14a0028b 100644 --- a/src/sage/schemes/elliptic_curves/mod_sym_num.pyx +++ b/src/sage/schemes/elliptic_curves/mod_sym_num.pyx @@ -1315,7 +1315,7 @@ cdef class ModularSymbolNumerical: if self._ans is NULL or self._ans_num is NULL: if self._ans is not NULL: sig_free(self._ans) if self._ans_num is not NULL: sig_free(self._ans_num) - raise MemoryError("Memory error with an coefficients.") + raise MemoryError("Memory error with coefficients.") verbose(" not enough precomputed coefficients, " "adding %s"%(T - self._lans), level=3) diff --git a/src/sage/schemes/elliptic_curves/modular_parametrization.py b/src/sage/schemes/elliptic_curves/modular_parametrization.py index 501c17cd571..2ed663e31cb 100644 --- a/src/sage/schemes/elliptic_curves/modular_parametrization.py +++ b/src/sage/schemes/elliptic_curves/modular_parametrization.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Modular parametrization of elliptic curves over `\QQ` diff --git a/src/sage/schemes/elliptic_curves/saturation.py b/src/sage/schemes/elliptic_curves/saturation.py index 095b5b1be12..5e4c66ad78a 100644 --- a/src/sage/schemes/elliptic_curves/saturation.py +++ b/src/sage/schemes/elliptic_curves/saturation.py @@ -128,10 +128,10 @@ def __init__(self, E, verbose=False): else: self._Kpol = K.defining_polynomial() self._D = self._Kpol.discriminant() - self._reductions = dict() - self._lincombs = dict() + self._reductions = {} + self._lincombs = {} self._torsion_gens = [t.element() for t in E.torsion_subgroup().gens()] - self._reductions = dict() + self._reductions = {} # This will hold a dictionary with keys (q,aq) with q prime # and aq a root of K's defining polynomial mod q, and values # (n,gens) where n is the cardinality of the reduction of E @@ -198,7 +198,7 @@ def add_reductions(self, q): """ if q in self._reductions: return - self._reductions[q] = redmodq = dict() + self._reductions[q] = redmodq = {} if q.divides(self._N) or q.divides(self._D): return from sage.schemes.elliptic_curves.constructor import EllipticCurve diff --git a/src/sage/schemes/elliptic_curves/sha_tate.py b/src/sage/schemes/elliptic_curves/sha_tate.py index 33818051b8f..b5a7b48bf0a 100644 --- a/src/sage/schemes/elliptic_curves/sha_tate.py +++ b/src/sage/schemes/elliptic_curves/sha_tate.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Tate-Shafarevich group @@ -1065,7 +1064,7 @@ def bound_kolyvagin(self, D=0, regulator=None, if not ignore_nonsurj_hypothesis: for p in E.galois_representation().non_surjective(): B.append(p) - B = sorted(set(int(x) for x in B)) + B = sorted({int(x) for x in B}) return B, n def bound_kato(self): diff --git a/src/sage/schemes/generic/algebraic_scheme.py b/src/sage/schemes/generic/algebraic_scheme.py index 0648ad2a9f4..2b3c61b5017 100644 --- a/src/sage/schemes/generic/algebraic_scheme.py +++ b/src/sage/schemes/generic/algebraic_scheme.py @@ -371,7 +371,7 @@ def embedding_morphism(self): or neighborhood of a point then the embedding is the embedding into the original scheme. - * A ``NotImplementedError`` is raised if the construction of + * A :class:`NotImplementedError` is raised if the construction of the embedding morphism is not implemented yet. EXAMPLES:: @@ -465,9 +465,8 @@ def embedding_center(self): OUTPUT: - A point of ``self``. Raises ``AttributeError`` if there is no - distinguished point, depending on how ``self`` was - constructed. + A point of ``self``. This raises :class:`AttributeError` if there + is no distinguished point, depending on how ``self`` was constructed. EXAMPLES:: @@ -1133,7 +1132,7 @@ def normalize_defining_polynomials(self): mult = lcm([c.denominator() for c in P.coefficients()]) P = mult*P # stores the common factor from all coefficients - div = gcd([_ for _ in P.coefficients()]) + div = gcd(list(P.coefficients())) poly_ring = P.parent() # need to coerce, since division might change base ring P = poly_ring((BR.one()/div)*P) normalized_polys.append(P) diff --git a/src/sage/schemes/generic/ambient_space.py b/src/sage/schemes/generic/ambient_space.py index d22ea07d149..09d26860af0 100644 --- a/src/sage/schemes/generic/ambient_space.py +++ b/src/sage/schemes/generic/ambient_space.py @@ -219,8 +219,8 @@ def base_extend(self, R): .. NOTE:: - A ``ValueError`` is raised if there is no such natural map. If - you need to drop this condition, use ``self.change_ring(R)``. + A :class:`ValueError` is raised if there is no such natural map. + If you need to drop this condition, use ``self.change_ring(R)``. EXAMPLES:: diff --git a/src/sage/schemes/generic/homset.py b/src/sage/schemes/generic/homset.py index 60e840619ac..a9a0f0735df 100644 --- a/src/sage/schemes/generic/homset.py +++ b/src/sage/schemes/generic/homset.py @@ -175,7 +175,7 @@ def create_key_and_extra_args(self, X, Y, category=None, base=None, if not category: from sage.categories.schemes import Schemes category = Schemes(base_spec) - key = tuple([id(X), id(Y), category, as_point_homset]) + key = (id(X), id(Y), category, as_point_homset) extra = {'X':X, 'Y':Y, 'base_ring':base_ring, 'check':check} return key, extra @@ -313,7 +313,7 @@ def natural_map(self): OUTPUT: A :class:`SchemeMorphism` if there is a natural map from - domain to codomain. Otherwise, a ``NotImplementedError`` is + domain to codomain. Otherwise, a :class:`NotImplementedError` is raised. EXAMPLES:: diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index da188ac63b3..88e7e6a61c2 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -498,7 +498,7 @@ def coordinate_ring(self): OUTPUT: The global coordinate ring of this scheme, if - defined. Otherwise raise a ``ValueError``. + defined. Otherwise this raises a :class:`ValueError`. EXAMPLES:: diff --git a/src/sage/schemes/generic/spec.py b/src/sage/schemes/generic/spec.py index c9a07313bb3..92453a86bf4 100644 --- a/src/sage/schemes/generic/spec.py +++ b/src/sage/schemes/generic/spec.py @@ -54,7 +54,7 @@ def Spec(R, S=None): sage: A is B True - A ``TypeError`` is raised if the input is not a commutative ring:: + A :class:`TypeError` is raised if the input is not a commutative ring:: sage: Spec(5) Traceback (most recent call last): diff --git a/src/sage/schemes/hyperelliptic_curves/invariants.py b/src/sage/schemes/hyperelliptic_curves/invariants.py index 05bffb5c113..a0101f60a3c 100644 --- a/src/sage/schemes/hyperelliptic_curves/invariants.py +++ b/src/sage/schemes/hyperelliptic_curves/invariants.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Compute invariants of quintics and sextics via 'Ueberschiebung' diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py b/src/sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py index 8d8d89896db..2ceb709b646 100644 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Some functions regarding geometric endomorphism rings of Jacobians of hyperelliptic curves. diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py b/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py index 1d3b0fd2763..2e91a96e02a 100644 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py @@ -41,7 +41,7 @@ class HyperellipticJacobian_generic(Jacobian_generic): sage: D == D + J(0) True - An more extended example, demonstrating arithmetic in J(QQ) and + A more extended example, demonstrating arithmetic in J(QQ) and J(K) for a number field K/QQ. :: diff --git a/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py b/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py index f8c8f847350..fb3b8bd8d4b 100644 --- a/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +++ b/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py @@ -1683,7 +1683,7 @@ def matrix_of_frobenius(Q, p, M, trace=None, compute_exact_forms=False): F1_coeffs = transpose_list(F1.coeffs()) F1_modp_coeffs = F1_coeffs[int((M-2)*p):] # make a copy, because reduce_all will destroy the coefficients: - F1_modp_coeffs = [[cell for cell in row] for row in F1_modp_coeffs] + F1_modp_coeffs = [list(row) for row in F1_modp_coeffs] F1_modp_offset = offset - (M-2)*p F1_modp_reduced = reduce_all(Q, p, F1_modp_coeffs, F1_modp_offset) diff --git a/src/sage/schemes/jacobians/abstract_jacobian.py b/src/sage/schemes/jacobians/abstract_jacobian.py index 8fece57a242..9ab2ef283ae 100644 --- a/src/sage/schemes/jacobians/abstract_jacobian.py +++ b/src/sage/schemes/jacobians/abstract_jacobian.py @@ -177,7 +177,7 @@ def _point(self): OUTPUT: - This method always raises a ``NotImplementedError``; it is + This method always raises a :class:`NotImplementedError`; it is only abstract. EXAMPLES:: diff --git a/src/sage/schemes/plane_conics/con_field.py b/src/sage/schemes/plane_conics/con_field.py index 97bd54408ac..26bea07db90 100644 --- a/src/sage/schemes/plane_conics/con_field.py +++ b/src/sage/schemes/plane_conics/con_field.py @@ -1050,7 +1050,7 @@ def rational_point(self, algorithm='default', read_cache=True): r""" Return a point on ``self`` defined over the base field. - Raises ``ValueError`` if no rational point exists. + This raises a :class:`ValueError` if no rational point exists. See ``self.has_rational_point`` for the algorithm used and for the use of the parameters ``algorithm`` and ``read_cache``. @@ -1202,7 +1202,8 @@ def singular_point(self): sage: Conic(GF(2), [1,1,1,1,1,1]).singular_point() (1 : 1 : 1) - ``ValueError`` is raised if the conic has no rational singular point + :class:`ValueError` is raised if the conic has no rational + singular point :: diff --git a/src/sage/schemes/plane_conics/con_rational_function_field.py b/src/sage/schemes/plane_conics/con_rational_function_field.py index 581102b5c5b..a5dcfb9bf1b 100644 --- a/src/sage/schemes/plane_conics/con_rational_function_field.py +++ b/src/sage/schemes/plane_conics/con_rational_function_field.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Projective plane conics over a rational function field diff --git a/src/sage/schemes/plane_conics/constructor.py b/src/sage/schemes/plane_conics/constructor.py index 20bc5630ac1..7bb681a4268 100644 --- a/src/sage/schemes/plane_conics/constructor.py +++ b/src/sage/schemes/plane_conics/constructor.py @@ -92,7 +92,7 @@ def Conic(base_field, F=None, names=None, unique=True): - ``unique`` -- Used only if ``F`` is a list of points in the plane. If the conic through the points is not unique, then - raise ``ValueError`` if and only if ``unique`` is True + raise :class:`ValueError` if and only if ``unique`` is ``True`` OUTPUT: diff --git a/src/sage/schemes/product_projective/point.py b/src/sage/schemes/product_projective/point.py index 70cc344806f..6de7cf74d7d 100644 --- a/src/sage/schemes/product_projective/point.py +++ b/src/sage/schemes/product_projective/point.py @@ -368,8 +368,8 @@ def scale_by(self, t): r""" Scale the coordinates of the point by ``t``, done componentwise. - A ``TypeError`` occurs if the point is not in the base ring of the - codomain after scaling. + A :class:`TypeError` occurs if the point is not in the base ring + of the codomain after scaling. INPUT: diff --git a/src/sage/schemes/product_projective/rational_point.py b/src/sage/schemes/product_projective/rational_point.py index c9a2cf6b25f..a4488647063 100644 --- a/src/sage/schemes/product_projective/rational_point.py +++ b/src/sage/schemes/product_projective/rational_point.py @@ -393,7 +393,7 @@ def good_primes(B): of the ambient space. """ - M = dict() # stores optimal list of primes, corresponding to list size + M = {} # stores optimal list of primes, corresponding to list size small_primes = sufficient_primes(B) max_length = len(small_primes) M[max_length] = small_primes diff --git a/src/sage/schemes/product_projective/space.py b/src/sage/schemes/product_projective/space.py index 0293e666cd6..3fee46cc15a 100644 --- a/src/sage/schemes/product_projective/space.py +++ b/src/sage/schemes/product_projective/space.py @@ -624,7 +624,7 @@ def _degree(self, polynomial): - ``polynomial`` -- a polynomial in the coordinate_ring OUTPUT: A tuple of integers, one for each projective space component. A - ``ValueError`` is raised if the polynomial is not multihomogeneous. + :class:`ValueError` is raised if the polynomial is not multihomogeneous. EXAMPLES:: @@ -694,7 +694,7 @@ def _point_homset(self, *args, **kwds): def _validate(self, polynomials): r""" If ``polynomials`` is a tuple of valid polynomial functions on this space, - return ``polynomials``, otherwise raise a ``TypeError``. + return ``polynomials``, otherwise raise a :class:`TypeError`. Since this is a product of projective spaces, the polynomials must be multi-homogeneous. diff --git a/src/sage/schemes/projective/proj_bdd_height.py b/src/sage/schemes/projective/proj_bdd_height.py index 744313fc77f..86100cf832a 100644 --- a/src/sage/schemes/projective/proj_bdd_height.py +++ b/src/sage/schemes/projective/proj_bdd_height.py @@ -78,9 +78,9 @@ def ZZ_points_of_bounded_height(PS, dim, bound): [] """ if bound < 1: - return iter(set([])) + return iter(set()) - points_of_bounded_height = set([]) + points_of_bounded_height = set() for t in itertools.product(range(-bound, bound+1), repeat=dim+1): if gcd(t) == 1: @@ -133,10 +133,10 @@ def QQ_points_of_bounded_height(PS, dim, bound, normalize=False): [] """ if bound < 1: - return iter(set([])) + return iter(set()) unit_tuples = list(itertools.product([-1, 1], repeat=dim)) - points_of_bounded_height = set([]) + points_of_bounded_height = set() increasing_tuples = itertools.combinations_with_replacement(range(floor(bound + 1)), dim + 1) for t in increasing_tuples: if gcd(t) == 1: @@ -190,12 +190,12 @@ def IQ_points_of_bounded_height(PS, K, dim, bound): class_group_ideal_norms = [i.norm() for i in class_group_ideals] class_number = len(class_group_ideals) - possible_norm_set = set([]) + possible_norm_set = set() for i in range(class_number): for k in range(1, floor(bound + 1)): possible_norm_set.add(k*class_group_ideal_norms[i]) - coordinate_space = dict() + coordinate_space = {} coordinate_space[0] = [K(0)] for m in possible_norm_set: coordinate_space[m] = K.elements_of_norm(m) @@ -212,7 +212,7 @@ def IQ_points_of_bounded_height(PS, K, dim, bound): if x in a: a_coordinates.append(x) - points_in_class_a = set([]) + points_in_class_a = set() t = len(a_coordinates) - 1 increasing_tuples = itertools.combinations_with_replacement(range(t + 1), dim + 1) for index_tuple in increasing_tuples: @@ -345,12 +345,12 @@ def points_of_bounded_height(PS, K, dim, bound, prec=53): fundamental_units = lll_fund_units fund_unit_logs = list(map(log_embed, fundamental_units)) - possible_norm_set = set([]) + possible_norm_set = set() for i in range(class_number): for k in range(1, floor(bound + 1)): possible_norm_set.add(k*class_group_ideal_norms[i]) - principal_ideal_gens = dict() + principal_ideal_gens = {} negative_norm_units = K.elements_of_norm(-1) if len(negative_norm_units) == 0: for m in possible_norm_set: @@ -359,7 +359,7 @@ def points_of_bounded_height(PS, K, dim, bound, prec=53): for m in possible_norm_set: principal_ideal_gens[m] = K.elements_of_norm(m) - pr_ideal_gen_logs = dict() + pr_ideal_gen_logs = {} for key in principal_ideal_gens: for y in principal_ideal_gens[key]: pr_ideal_gen_logs[y] = log_embed(y) @@ -398,11 +398,11 @@ def points_of_bounded_height(PS, K, dim, bound, prec=53): T_it = T.inverse().transpose() unit_polytope = Polyhedron([v*T_it for v in vertices]) - coordinate_space = dict() + coordinate_space = {} coordinate_space[0] = [[K(0), log_embed(0)]] int_points = unit_polytope.integral_points() - units_with_logs = dict() + units_with_logs = {} for n in int_points: new_unit = 1 for j in range(r): @@ -444,7 +444,7 @@ def points_of_bounded_height(PS, K, dim, bound, prec=53): a_coordinates.append(pair) t = len(a_coordinates) - 1 - points_in_class_a = set([]) + points_in_class_a = set() increasing_tuples = itertools.combinations_with_replacement(range(t + 1), dim + 1) log_arch_height_bound = logB + log_a_norm for index_tuple in increasing_tuples: diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 2983b03796e..fe408bd1d42 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Morphisms on projective schemes @@ -735,9 +734,9 @@ def as_dynamical_system(self): def scale_by(self, t): """ - Scales each coordinate by a factor of ``t``. + Scale each coordinate by a factor of ``t``. - A ``TypeError`` occurs if the point is not in the coordinate ring + A :class:`TypeError` occurs if the point is not in the coordinate ring of the parent after scaling. INPUT: diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index e22e0a858b1..55bd5354976 100644 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -488,11 +488,11 @@ def _matrix_times_point_(self, mat, dom): X = mat * vector(list(self)) return dom.codomain()(list(X)) - def scale_by(self,t): + def scale_by(self, t): """ Scale the coordinates of the point by ``t``. - A ``TypeError`` occurs if the point is not in the + A :class:`TypeError` occurs if the point is not in the base_ring of the codomain after scaling. INPUT: diff --git a/src/sage/schemes/projective/projective_rational_point.py b/src/sage/schemes/projective/projective_rational_point.py index cc99ba389ac..6e08612f88b 100644 --- a/src/sage/schemes/projective/projective_rational_point.py +++ b/src/sage/schemes/projective/projective_rational_point.py @@ -412,7 +412,7 @@ def good_primes(B): where alpha is product of all primes, and P_max is largest prime in list. """ - M = dict() # stores optimal list of primes, corresponding to list size + M = {} # stores optimal list of primes, corresponding to list size small_primes = sufficient_primes(B) max_length = len(small_primes) M[max_length] = small_primes diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index c1402654a87..5c55a62106e 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -180,7 +180,7 @@ def ProjectiveSpace(n, R=None, names=None): sage: ProjectiveSpace(5) Projective Space of dimension 5 over Integer Ring - There is also an projective space associated each polynomial ring. + There is also a projective space associated each polynomial ring. :: @@ -1951,7 +1951,7 @@ def hyperplane_transformation_matrix(self, plane_1, plane_2): base_list = [list(s) for s in source_points] elif len(source_points) == N + 1: Ms = matrix(base_list + [point.change_ring(self.base_ring())]) - if not any([m == 0 for m in Ms.minors(N + 1)]): + if not any(m == 0 for m in Ms.minors(N + 1)): source_points.append(self(point)) break if len(source_points) != N+2: @@ -2371,10 +2371,10 @@ def rational_points(self, F=None): (b + 1 : 1), (b + 2 : 1), (b : 1)] """ if F is None: - return [P for P in self] + return list(self) elif not isinstance(F, FiniteField): raise TypeError("second argument (= %s) must be a finite field" % F) - return [P for P in self.base_extend(F)] + return list(self.base_extend(F)) def rational_points_dictionary(self): r""" diff --git a/src/sage/schemes/riemann_surfaces/riemann_surface.py b/src/sage/schemes/riemann_surfaces/riemann_surface.py index b7e3f1ac8f6..a7760fa7101 100644 --- a/src/sage/schemes/riemann_surfaces/riemann_surface.py +++ b/src/sage/schemes/riemann_surfaces/riemann_surface.py @@ -1688,10 +1688,10 @@ def direction(center, neighbour): # that entry, and the corresponding cycle. (also, forms it # into a loop) if P[i][j] != 0: - acycles[i] += [(P[i][j], [x for x in cycles[j]] + [cycles[j][0]])] + acycles[i] += [(P[i][j], list(cycles[j]) + [cycles[j][0]])] if P[self.genus + i][j] != 0: bcycles[i] += [ - (P[self.genus + i][j], [x for x in cycles[j]] + [cycles[j][0]]) + (P[self.genus + i][j], list(cycles[j]) + [cycles[j][0]]) ] return acycles + bcycles @@ -2326,7 +2326,7 @@ def normalize_pairs(L): integral_dict = self._integral_dict else: fcd = [fast_callable(omega, domain=self._CC) for omega in differentials] - integral_dict = dict() + integral_dict = {} if integration_method == "heuristic": line_int = lambda edge: self.simple_vector_line_integral(edge, fcd) diff --git a/src/sage/schemes/toric/chow_group.py b/src/sage/schemes/toric/chow_group.py index dac091a4f6f..9b612ece0eb 100644 --- a/src/sage/schemes/toric/chow_group.py +++ b/src/sage/schemes/toric/chow_group.py @@ -1,5 +1,4 @@ # sage.doctest: needs sage.geometry.polyhedron sage.graphs -# -*- coding: utf-8 -*- r""" The Chow group of a toric variety @@ -553,7 +552,7 @@ def create_key_and_extra_args(self, toric_variety, base_ring=ZZ, check=True): if base_ring not in [ZZ, QQ]: raise ValueError('base ring must be either ZZ or QQ') - key = tuple([toric_variety, base_ring]) + key = (toric_variety, base_ring) extra = {'check': check} return key, extra diff --git a/src/sage/schemes/toric/library.py b/src/sage/schemes/toric/library.py index d70a3e95d5d..c09c404d64a 100644 --- a/src/sage/schemes/toric/library.py +++ b/src/sage/schemes/toric/library.py @@ -868,7 +868,7 @@ def Cube_nonpolyhedral(self, names='z+', base_ring=QQ): .. NOTE:: - * This is an example of an non-polyhedral fan. + * This is an example of a non-polyhedral fan. * Its Chow group has torsion: `A_2(X)=\ZZ^5 \oplus \ZZ_2` diff --git a/src/sage/schemes/toric/points.py b/src/sage/schemes/toric/points.py index 4a40aa82ef7..20507e5c0af 100644 --- a/src/sage/schemes/toric/points.py +++ b/src/sage/schemes/toric/points.py @@ -96,7 +96,7 @@ def __iter__(self): rays = self.fan().rays() + self.fan().virtual_rays() n = len(rays) if n == 0: - yield tuple() + yield () else: R = self.ring p = [R.one() for k in range(n)] @@ -242,7 +242,7 @@ def _Chow_group_torsion(self): ((1, 2, 4), (1, 4, 2)) """ if self.fan.is_smooth(): - return tuple() + return () image = self.rays().column_matrix().image() torsion = image.saturation().quotient(image) result = set() @@ -539,7 +539,7 @@ def _Chow_group_torsion_generators(self): ((1, 2, 4),) """ if self.fan.is_smooth(): - return tuple() + return () image = self.rays().column_matrix().image() torsion = image.saturation().quotient(image) result = set() diff --git a/src/sage/schemes/toric/sheaf/constructor.py b/src/sage/schemes/toric/sheaf/constructor.py index 52f00d99815..72ed52a0115 100644 --- a/src/sage/schemes/toric/sheaf/constructor.py +++ b/src/sage/schemes/toric/sheaf/constructor.py @@ -40,7 +40,7 @@ def TangentBundle(X): raise ValueError('not a toric variety') fan = X.fan() - filtrations = dict() + filtrations = {} from sage.modules.filtered_vector_space import FilteredVectorSpace for i, ray in enumerate(fan.rays()): F = FilteredVectorSpace(fan.rays(), {0: range(fan.nrays()), 1: [i]}) diff --git a/src/sage/schemes/toric/sheaf/klyachko.py b/src/sage/schemes/toric/sheaf/klyachko.py index 08cea1487f9..4325e77f186 100644 --- a/src/sage/schemes/toric/sheaf/klyachko.py +++ b/src/sage/schemes/toric/sheaf/klyachko.py @@ -685,7 +685,7 @@ def cohomology(self, degree=None, weight=None, dim=False): C = self.cohomology_complex(weight) space_dim = self._variety.dimension() C_homology = C.homology() - HH = dict() + HH = {} for d in range(space_dim+1): try: HH[d] = C_homology[d] diff --git a/src/sage/schemes/toric/toric_subscheme.py b/src/sage/schemes/toric/toric_subscheme.py index 6b3645d0e4a..3d481846b88 100644 --- a/src/sage/schemes/toric/toric_subscheme.py +++ b/src/sage/schemes/toric/toric_subscheme.py @@ -220,7 +220,7 @@ def affine_patch(self, i): try: return self._affine_patches[i] except AttributeError: - self._affine_patches = dict() + self._affine_patches = {} except KeyError: pass ambient_patch = self.ambient_space().affine_patch(i) @@ -315,9 +315,9 @@ def affine_algebraic_patch(self, cone=None, names=None): R, I, dualcone = ambient._semigroup_ring(cone, names) # inhomogenize the Cox homogeneous polynomial with respect to the given cone - inhomogenize = dict( (ambient.coordinate_ring().gen(i), 1) - for i in range(0,fan.nrays()) - if i not in cone.ambient_ray_indices() ) + inhomogenize = {ambient.coordinate_ring().gen(i): 1 + for i in range(fan.nrays()) + if i not in cone.ambient_ray_indices()} polynomials = [p.subs(inhomogenize) for p in self.defining_polynomials()] # map the monomial x^{D_m} to m, see reference. @@ -402,7 +402,7 @@ def _best_affine_patch(self, point): # that it is numerically stable to dehomogenize, see the # corresponding method for projective varieties. point = list(point) - zeros = set(i for i, coord in enumerate(point) if coord == 0) + zeros = {i for i, coord in enumerate(point) if coord == 0} for cone_idx, cone in enumerate(self.ambient_space().fan().generating_cones()): if zeros.issubset(cone.ambient_ray_indices()): return cone_idx @@ -410,7 +410,7 @@ def _best_affine_patch(self, point): def neighborhood(self, point): r""" - Return an toric algebraic scheme isomorphic to neighborhood of + Return a toric algebraic scheme isomorphic to neighborhood of the ``point``. INPUT: @@ -677,8 +677,8 @@ def is_nondegenerate(self): SR = SR.change_ring(R) def restrict(cone): - patch = dict() - divide = dict() + patch = {} + divide = {} for i in cone.ambient_ray_indices(): patch[R.gen(i)] = R.zero() # restrict to torus orbit # divide out highest power of R.gen(i) diff --git a/src/sage/schemes/toric/variety.py b/src/sage/schemes/toric/variety.py index 3635e7abbd4..9b06bd0223c 100644 --- a/src/sage/schemes/toric/variety.py +++ b/src/sage/schemes/toric/variety.py @@ -1,5 +1,4 @@ # sage.doctest: needs sage.geometry.polyhedron sage.graphs -# -*- coding: utf-8 -*- r""" Toric varieties @@ -709,9 +708,9 @@ def _check_satisfies_equations(self, coordinates): if coordinate not in base_field: raise TypeError("coordinate %s is not an element of %s" % (coordinate, base_field)) - zero_positions = set(position - for position, coordinate in enumerate(coordinates) - if coordinate == 0) + zero_positions = {position + for position, coordinate in enumerate(coordinates) + if coordinate == 0} if not zero_positions: return True for i in range(n - self._torus_factor_dim, n): @@ -2731,7 +2730,7 @@ def orbit_closure(self, cone): star_rays = set() for star_cone in cone.star_generators(): star_rays.update(star_cone.rays()) - ray_map = dict( (ray, self._orbit_closure_projection(cone, ray)) for ray in star_rays) + ray_map = {ray: self._orbit_closure_projection(cone, ray) for ray in star_rays} from sage.schemes.toric.morphism import SchemeMorphism_orbit_closure_toric_variety orbit_closure._embedding_morphism = \ SchemeMorphism_orbit_closure_toric_variety(orbit_closure.Hom(self), cone, ray_map) diff --git a/src/sage/schemes/toric/weierstrass.py b/src/sage/schemes/toric/weierstrass.py index 137dfd3e042..b727e586141 100644 --- a/src/sage/schemes/toric/weierstrass.py +++ b/src/sage/schemes/toric/weierstrass.py @@ -281,7 +281,7 @@ def Newton_polytope_vars_coeffs(polynomial, variables): """ R = polynomial.parent() var_indices = [R.gens().index(x) for x in variables] - result = dict() + result = {} for c, m in polynomial: e = m.exponents()[0] v = tuple([e[i] for i in var_indices]) @@ -596,7 +596,7 @@ def index(monomial): return tuple(0 for i in indices) e = monomial.exponents()[0] return tuple(e[i] for i in indices) - coeffs = dict() + coeffs = {} for c, m in polynomial: i = index(m) coeffs[i] = c*m + coeffs.pop(i, R.zero()) @@ -992,7 +992,7 @@ def _check_polynomial_P2_112(polynomial, variables): _check_homogeneity(polynomial, variables, (1, 0, 1, -2), 0) _check_homogeneity(polynomial, variables, (0, 1, 0, 1), 2) elif len(variables) == 2: - variables = tuple([variables[0], variables[1], None, None]) + variables = (variables[0], variables[1], None, None) else: raise ValueError(f'need two or four variables, got {variables}') return variables diff --git a/src/sage/schemes/toric/weierstrass_covering.py b/src/sage/schemes/toric/weierstrass_covering.py index cc9caeeae4d..128c30d33a8 100644 --- a/src/sage/schemes/toric/weierstrass_covering.py +++ b/src/sage/schemes/toric/weierstrass_covering.py @@ -255,9 +255,9 @@ def homogenize(inhomog, degree): result = vector(ZZ, result) result.set_immutable() return result - X_dict = dict((homogenize(e, 2), v) for e, v in X.dict().items()) - Y_dict = dict((homogenize(e, 3), v) for e, v in Y.dict().items()) - Z_dict = dict((homogenize(e, 1), v) for e, v in Z.dict().items()) + X_dict = {homogenize(e, 2): v for e, v in X.dict().items()} + Y_dict = {homogenize(e, 3): v for e, v in Y.dict().items()} + Z_dict = {homogenize(e, 1): v for e, v in Z.dict().items()} # shift to non-negative exponents if necessary min_deg = [0] * R.ngens() for var in variables: @@ -267,9 +267,9 @@ def homogenize(inhomog, degree): min_Z = min([e[i] for e in Z_dict]) if Z_dict else 0 min_deg[i] = min(min_X / 2, min_Y / 3, min_Z) min_deg = vector(min_deg) - X_dict = dict((tuple(e - 2 * min_deg), v) for e, v in X_dict.items()) - Y_dict = dict((tuple(e - 3 * min_deg), v) for e, v in Y_dict.items()) - Z_dict = dict((tuple(e - 1 * min_deg), v) for e, v in Z_dict.items()) + X_dict = {tuple(e - 2 * min_deg): v for e, v in X_dict.items()} + Y_dict = {tuple(e - 3 * min_deg): v for e, v in Y_dict.items()} + Z_dict = {tuple(e - 1 * min_deg): v for e, v in Z_dict.items()} return (R(X_dict), R(Y_dict), R(Z_dict)) diff --git a/src/sage/sets/real_set.py b/src/sage/sets/real_set.py index 45394cba23c..2b431284e4d 100644 --- a/src/sage/sets/real_set.py +++ b/src/sage/sets/real_set.py @@ -1860,7 +1860,7 @@ def open_closed(lower, upper, **kwds): @staticmethod def closed_open(lower, upper, **kwds): r""" - Construct an half-open interval + Construct a half-open interval INPUT: @@ -1872,7 +1872,7 @@ def closed_open(lower, upper, **kwds): OUTPUT: A new :class:`RealSet` that is closed at the lower bound and - open an the upper bound. + open at the upper bound. EXAMPLES:: diff --git a/src/sage/sets/recursively_enumerated_set.pyx b/src/sage/sets/recursively_enumerated_set.pyx index d79e104704f..66720d924e5 100644 --- a/src/sage/sets/recursively_enumerated_set.pyx +++ b/src/sage/sets/recursively_enumerated_set.pyx @@ -960,7 +960,7 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): sage: R.to_digraph() # needs sage.graphs Looped multi-digraph on 10 vertices - Digraph of an recursively enumerated set with a symmetric structure of + Digraph of a recursively enumerated set with a symmetric structure of infinite cardinality using ``max_depth`` argument:: sage: succ = lambda a: [(a[0]-1,a[1]), (a[0],a[1]-1), (a[0]+1,a[1]), (a[0],a[1]+1)] @@ -976,7 +976,7 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): sage: C.to_digraph() # needs sage.graphs Looped multi-digraph on 25 vertices - Digraph of an recursively enumerated set with a graded structure:: + Digraph of a recursively enumerated set with a graded structure:: sage: f = lambda a: [a+1, a+I] sage: C = RecursivelyEnumeratedSet([0], f, structure='graded') diff --git a/src/sage/symbolic/expression_conversion_sympy.py b/src/sage/symbolic/expression_conversion_sympy.py index 4a3b1556ce1..c2c1b3e2634 100644 --- a/src/sage/symbolic/expression_conversion_sympy.py +++ b/src/sage/symbolic/expression_conversion_sympy.py @@ -129,7 +129,6 @@ def symbol(self, ex): """ EXAMPLES:: - sage: sage: from sage.symbolic.expression_conversions import SympyConverter sage: s = SympyConverter() sage: s.symbol(x) @@ -144,7 +143,6 @@ def relation(self, ex, op): """ EXAMPLES:: - sage: sage: import operator sage: from sage.symbolic.expression_conversions import SympyConverter sage: s = SympyConverter() diff --git a/src/sage/tests/gap_packages.py b/src/sage/tests/gap_packages.py index cf02fa5cf6e..249d1b03d23 100644 --- a/src/sage/tests/gap_packages.py +++ b/src/sage/tests/gap_packages.py @@ -103,8 +103,8 @@ def all_installed_packages(ignore_dot_gap=False, gap=None): EXAMPLES:: sage: from sage.tests.gap_packages import all_installed_packages - sage: all_installed_packages() - (...'gapdoc'...) + sage: [p.lower() for p in all_installed_packages()] + [...'gapdoc'...] sage: all_installed_packages(ignore_dot_gap=True) == all_installed_packages(gap=gap, ignore_dot_gap=True) True """ diff --git a/src/sage/topology/simplicial_complex_examples.py b/src/sage/topology/simplicial_complex_examples.py index 304ea7ec8aa..2b1af7cbbe4 100644 --- a/src/sage/topology/simplicial_complex_examples.py +++ b/src/sage/topology/simplicial_complex_examples.py @@ -1423,7 +1423,6 @@ def RandomTwoSphere(n): EXAMPLES:: - sage: sage: G = simplicial_complexes.RandomTwoSphere(6); G Simplicial complex with vertex set (0, 1, 2, 3, 4, 5) and 8 facets sage: G.homology() # needs sage.modules diff --git a/src/sage/topology/simplicial_set.py b/src/sage/topology/simplicial_set.py index e33465f1153..9b707a62916 100644 --- a/src/sage/topology/simplicial_set.py +++ b/src/sage/topology/simplicial_set.py @@ -2382,7 +2382,6 @@ def coproduct(self, *others): sage: Y = S2.unset_base_point() sage: Z = K.unset_base_point() - sage: sage: S2.coproduct(K).is_pointed() True sage: S2.coproduct(K) diff --git a/src/sage/typeset/ascii_art.py b/src/sage/typeset/ascii_art.py index 032b79322da..395245c0df5 100644 --- a/src/sage/typeset/ascii_art.py +++ b/src/sage/typeset/ascii_art.py @@ -4,7 +4,7 @@ This file contains: -- :class:`AsciiArt` an simple implementation of an ASCII art object, +- :class:`AsciiArt` a simple implementation of an ASCII art object, - :func:`ascii_art` a function to get the ASCII art representation of any object in Sage, diff --git a/src/sage/version.py b/src/sage/version.py index 30dfeeace6a..ae557017ab3 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '10.3.beta3' -date = '2023-12-18' -banner = 'SageMath version 10.3.beta3, Release Date: 2023-12-18' +version = '10.3.beta4' +date = '2023-12-26' +banner = 'SageMath version 10.3.beta4, Release Date: 2023-12-26' diff --git a/src/sage_docbuild/conf.py b/src/sage_docbuild/conf.py index 8602016d042..0ab862c7a13 100644 --- a/src/sage_docbuild/conf.py +++ b/src/sage_docbuild/conf.py @@ -198,6 +198,10 @@ def sphinx_plot(graphics, **kwds): # for a list of supported languages. #language = None +# The LaTeX engine to build the docs. +# https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-latex_engine +latex_engine = 'lualatex' + # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' @@ -502,182 +506,6 @@ def set_intersphinx_mappings(app, config): \usepackage{mathrsfs} \usepackage{iftex} -% Only declare unicode characters when compiling with pdftex; E.g. japanese -% tutorial does not use pdftex -\ifPDFTeX - \DeclareUnicodeCharacter{01CE}{\capitalcaron a} - \DeclareUnicodeCharacter{0428}{cyrillic Sha} - \DeclareUnicodeCharacter{250C}{+} - \DeclareUnicodeCharacter{2510}{+} - \DeclareUnicodeCharacter{2514}{+} - \DeclareUnicodeCharacter{2518}{+} - \DeclareUnicodeCharacter{253C}{+} - - \DeclareUnicodeCharacter{03B1}{\ensuremath{\alpha}} - \DeclareUnicodeCharacter{03B2}{\ensuremath{\beta}} - \DeclareUnicodeCharacter{03B3}{\ensuremath{\gamma}} - \DeclareUnicodeCharacter{0393}{\ensuremath{\Gamma}} - \DeclareUnicodeCharacter{03B4}{\ensuremath{\delta}} - \DeclareUnicodeCharacter{0394}{\ensuremath{\Delta}} - \DeclareUnicodeCharacter{03B5}{\ensuremath{\varepsilon}} - \DeclareUnicodeCharacter{03B6}{\ensuremath{\zeta}} - \DeclareUnicodeCharacter{03B7}{\ensuremath{\eta}} - \DeclareUnicodeCharacter{03B8}{\ensuremath{\vartheta}} - \DeclareUnicodeCharacter{0398}{\ensuremath{\Theta}} - \DeclareUnicodeCharacter{03BA}{\ensuremath{\kappa}} - \DeclareUnicodeCharacter{03BB}{\ensuremath{\lambda}} - \DeclareUnicodeCharacter{039B}{\ensuremath{\Lambda}} - \DeclareUnicodeCharacter{00B5}{\ensuremath{\mu}} % micron sign - \DeclareUnicodeCharacter{03BC}{\ensuremath{\mu}} - \DeclareUnicodeCharacter{03BD}{\ensuremath{\nu}} - \DeclareUnicodeCharacter{03BE}{\ensuremath{\xi}} - \DeclareUnicodeCharacter{039E}{\ensuremath{\Xi}} - \DeclareUnicodeCharacter{03B9}{\ensuremath{\iota}} - \DeclareUnicodeCharacter{03C0}{\ensuremath{\pi}} - \DeclareUnicodeCharacter{03A0}{\ensuremath{\Pi}} - \DeclareUnicodeCharacter{03C1}{\ensuremath{\rho}} - \DeclareUnicodeCharacter{03C3}{\ensuremath{\sigma}} - \DeclareUnicodeCharacter{03A3}{\ensuremath{\Sigma}} - \DeclareUnicodeCharacter{03C4}{\ensuremath{\tau}} - \DeclareUnicodeCharacter{03C6}{\ensuremath{\varphi}} - \DeclareUnicodeCharacter{03A6}{\ensuremath{\Phi}} - \DeclareUnicodeCharacter{03C7}{\ensuremath{\chi}} - \DeclareUnicodeCharacter{03C8}{\ensuremath{\psi}} - \DeclareUnicodeCharacter{03A8}{\ensuremath{\Psi}} - \DeclareUnicodeCharacter{03C9}{\ensuremath{\omega}} - \DeclareUnicodeCharacter{03A9}{\ensuremath{\Omega}} - \DeclareUnicodeCharacter{03C5}{\ensuremath{\upsilon}} - \DeclareUnicodeCharacter{03A5}{\ensuremath{\Upsilon}} - \DeclareUnicodeCharacter{2113}{\ell} - - \DeclareUnicodeCharacter{2148}{\ensuremath{\id}} - \DeclareUnicodeCharacter{2202}{\ensuremath{\partial}} - \DeclareUnicodeCharacter{2205}{\ensuremath{\emptyset}} - \DeclareUnicodeCharacter{2208}{\ensuremath{\in}} - \DeclareUnicodeCharacter{2209}{\ensuremath{\notin}} - \DeclareUnicodeCharacter{2211}{\ensuremath{\sum}} - \DeclareUnicodeCharacter{221A}{\ensuremath{\sqrt{}}} - \DeclareUnicodeCharacter{221E}{\ensuremath{\infty}} - \DeclareUnicodeCharacter{2227}{\ensuremath{\wedge}} - \DeclareUnicodeCharacter{2228}{\ensuremath{\vee}} - \DeclareUnicodeCharacter{2229}{\ensuremath{\cap}} - \DeclareUnicodeCharacter{222A}{\ensuremath{\cup}} - \DeclareUnicodeCharacter{222B}{\ensuremath{\int}} - \DeclareUnicodeCharacter{2248}{\ensuremath{\approx}} - \DeclareUnicodeCharacter{2260}{\ensuremath{\neq}} - \DeclareUnicodeCharacter{2264}{\ensuremath{\leq}} - \DeclareUnicodeCharacter{2265}{\ensuremath{\geq}} - \DeclareUnicodeCharacter{2293}{\ensuremath{\sqcap}} - \DeclareUnicodeCharacter{2294}{\ensuremath{\sqcup}} - \DeclareUnicodeCharacter{22C0}{\ensuremath{\bigwedge}} - \DeclareUnicodeCharacter{22C1}{\ensuremath{\bigvee}} - \DeclareUnicodeCharacter{22C2}{\ensuremath{\bigcap}} - \DeclareUnicodeCharacter{22C3}{\ensuremath{\bigcup}} - \DeclareUnicodeCharacter{2323}{\ensuremath{\smile}} % cup product - \DeclareUnicodeCharacter{00B1}{\ensuremath{\pm}} - \DeclareUnicodeCharacter{2A02}{\ensuremath{\bigotimes}} - \DeclareUnicodeCharacter{2295}{\ensuremath{\oplus}} - \DeclareUnicodeCharacter{2297}{\ensuremath{\otimes}} - \DeclareUnicodeCharacter{2A01}{\ensuremath{\oplus}} - \DeclareUnicodeCharacter{00BD}{\ensuremath{\nicefrac{1}{2}}} - \DeclareUnicodeCharacter{00D7}{\ensuremath{\times}} - \DeclareUnicodeCharacter{00B7}{\ensuremath{\cdot}} - \DeclareUnicodeCharacter{230A}{\ensuremath{\lfloor}} - \DeclareUnicodeCharacter{230B}{\ensuremath{\rfloor}} - \DeclareUnicodeCharacter{2308}{\ensuremath{\lceil}} - \DeclareUnicodeCharacter{2309}{\ensuremath{\rceil}} - \DeclareUnicodeCharacter{22C5}{\ensuremath{\cdot}} - \DeclareUnicodeCharacter{2227}{\ensuremath{\wedge}} - \DeclareUnicodeCharacter{22C0}{\ensuremath{\bigwedge}} - \DeclareUnicodeCharacter{2192}{\ensuremath{\to}} - \DeclareUnicodeCharacter{21A6}{\ensuremath{\mapsto}} - \DeclareUnicodeCharacter{2102}{\ensuremath{\mathbb{C}}} - \DeclareUnicodeCharacter{211A}{\ensuremath{\mathbb{Q}}} - \DeclareUnicodeCharacter{211D}{\ensuremath{\mathbb{R}}} - \DeclareUnicodeCharacter{2124}{\ensuremath{\mathbb{Z}}} - \DeclareUnicodeCharacter{2202}{\ensuremath{\partial}} - - \DeclareUnicodeCharacter{2070}{\ensuremath{{}^0}} - \DeclareUnicodeCharacter{00B9}{\ensuremath{{}^1}} - \DeclareUnicodeCharacter{00B2}{\ensuremath{{}^2}} - \DeclareUnicodeCharacter{00B3}{\ensuremath{{}^3}} - \DeclareUnicodeCharacter{2074}{\ensuremath{{}^4}} - \DeclareUnicodeCharacter{2075}{\ensuremath{{}^5}} - \DeclareUnicodeCharacter{2076}{\ensuremath{{}^6}} - \DeclareUnicodeCharacter{2077}{\ensuremath{{}^7}} - \DeclareUnicodeCharacter{2078}{\ensuremath{{}^8}} - \DeclareUnicodeCharacter{2079}{\ensuremath{{}^9}} - \DeclareUnicodeCharacter{207A}{\ensuremath{{}^+}} - \DeclareUnicodeCharacter{207B}{\ensuremath{{}^-}} - \DeclareUnicodeCharacter{141F}{\ensuremath{{}^/}} - \DeclareUnicodeCharacter{2080}{\ensuremath{{}_0}} - \DeclareUnicodeCharacter{2081}{\ensuremath{{}_1}} - \DeclareUnicodeCharacter{2082}{\ensuremath{{}_2}} - \DeclareUnicodeCharacter{2083}{\ensuremath{{}_3}} - \DeclareUnicodeCharacter{2084}{\ensuremath{{}_4}} - \DeclareUnicodeCharacter{2085}{\ensuremath{{}_5}} - \DeclareUnicodeCharacter{2086}{\ensuremath{{}_6}} - \DeclareUnicodeCharacter{2087}{\ensuremath{{}_7}} - \DeclareUnicodeCharacter{2088}{\ensuremath{{}_8}} - \DeclareUnicodeCharacter{2089}{\ensuremath{{}_9}} - \DeclareUnicodeCharacter{208A}{\ensuremath{{}_+}} - \DeclareUnicodeCharacter{208B}{\ensuremath{{}_-}} - \DeclareUnicodeCharacter{1D62}{\ensuremath{{}_i}} - \DeclareUnicodeCharacter{2C7C}{\ensuremath{{}_j}} - - \newcommand{\sageMexSymbol}[1] - {{\fontencoding{OMX}\fontfamily{cmex}\selectfont\raisebox{0.75em}{\symbol{#1}}}} - \DeclareUnicodeCharacter{239B}{\sageMexSymbol{"30}} % parenlefttp - \DeclareUnicodeCharacter{239C}{\sageMexSymbol{"42}} % parenleftex - \DeclareUnicodeCharacter{239D}{\sageMexSymbol{"40}} % parenleftbt - \DeclareUnicodeCharacter{239E}{\sageMexSymbol{"31}} % parenrighttp - \DeclareUnicodeCharacter{239F}{\sageMexSymbol{"43}} % parenrightex - \DeclareUnicodeCharacter{23A0}{\sageMexSymbol{"41}} % parenrightbt - \DeclareUnicodeCharacter{23A1}{\sageMexSymbol{"32}} % bracketlefttp - \DeclareUnicodeCharacter{23A2}{\sageMexSymbol{"36}} % bracketleftex - \DeclareUnicodeCharacter{23A3}{\sageMexSymbol{"34}} % bracketleftbt - \DeclareUnicodeCharacter{23A4}{\sageMexSymbol{"33}} % bracketrighttp - \DeclareUnicodeCharacter{23A5}{\sageMexSymbol{"37}} % bracketrightex - \DeclareUnicodeCharacter{23A6}{\sageMexSymbol{"35}} % bracketrightbt - - \DeclareUnicodeCharacter{23A7}{\sageMexSymbol{"38}} % curly brace left top - \DeclareUnicodeCharacter{23A8}{\sageMexSymbol{"3C}} % curly brace left middle - \DeclareUnicodeCharacter{23A9}{\sageMexSymbol{"3A}} % curly brace left bottom - \DeclareUnicodeCharacter{23AA}{\sageMexSymbol{"3E}} % curly brace extension - \DeclareUnicodeCharacter{23AB}{\sageMexSymbol{"39}} % curly brace right top - \DeclareUnicodeCharacter{23AC}{\sageMexSymbol{"3D}} % curly brace right middle - \DeclareUnicodeCharacter{23AD}{\sageMexSymbol{"3B}} % curly brace right bottom - \DeclareUnicodeCharacter{23B0}{\{} % 2-line curly brace left top half (not in cmex) - \DeclareUnicodeCharacter{23B1}{\}} % 2-line curly brace right top half (not in cmex) - - \DeclareUnicodeCharacter{2320}{\ensuremath{\int}} % top half integral - \DeclareUnicodeCharacter{2321}{\ensuremath{\int}} % bottom half integral - \DeclareUnicodeCharacter{23AE}{\ensuremath{\|}} % integral extenison - - % Box drawings light - \DeclareUnicodeCharacter{2500}{-} % h - \DeclareUnicodeCharacter{2502}{|} % v - \DeclareUnicodeCharacter{250C}{+} % dr - \DeclareUnicodeCharacter{2510}{+} % dl - \DeclareUnicodeCharacter{2514}{+} % ur - \DeclareUnicodeCharacter{2518}{+} % ul - \DeclareUnicodeCharacter{251C}{+} % vr - \DeclareUnicodeCharacter{2524}{+} % vl - \DeclareUnicodeCharacter{252C}{+} % dh - \DeclareUnicodeCharacter{2534}{+} % uh - \DeclareUnicodeCharacter{253C}{+} % vh - \DeclareUnicodeCharacter{2571}{/} % upper right to lower left - \DeclareUnicodeCharacter{2572}{\ensuremath{\setminus}} % upper left to lower right - \DeclareUnicodeCharacter{2573}{X} % diagonal cross - - \DeclareUnicodeCharacter{25CF}{\ensuremath{\bullet}} % medium black circle - \DeclareUnicodeCharacter{26AC}{\ensuremath{\circ}} % medium small white circle - \DeclareUnicodeCharacter{256D}{+} - \DeclareUnicodeCharacter{256E}{+} - \DeclareUnicodeCharacter{256F}{+} - \DeclareUnicodeCharacter{2570}{+} -\fi - \let\textLaTeX\LaTeX \AtBeginDocument{\renewcommand*{\LaTeX}{\hbox{\textLaTeX}}} diff --git a/tox.ini b/tox.ini index 4415cab94c2..eac4cdce808 100644 --- a/tox.ini +++ b/tox.ini @@ -500,7 +500,6 @@ setenv = ### ### "local" envs ### - homebrew: SYSTEM=homebrew local: SHARED_CACHE_DIR={toxworkdir}/Caches local: SETENV=: local: SETENV_CONFIGURE=: @@ -509,6 +508,7 @@ setenv = local-sudo: __SUDO=--sudo local-root: CONFIG_CONFIGURE_ARGS_ROOT=--enable-build-as-root # brew caches downloaded files in ${HOME}/Library/Caches. We share it between different toxenvs. + homebrew: SYSTEM=homebrew local-homebrew: HOMEBREW={envdir}/homebrew local-{homebrew-usrlocal,nohomebrew}: HOMEBREW=/usr/local # local-macos-nohomebrew: "best effort" isolation to avoid using a homebrew installation in /usr/local @@ -521,6 +521,16 @@ setenv = local-{homebrew-nokegonly,nohomebrew}: BOOTSTRAP=ACLOCAL_PATH="$HOMEBREW/opt/gettext/share/aclocal:$ACLOCAL_PATH" PATH="$HOMEBREW/opt/gettext/bin/:$HOMEBREW/bin:$PATH" ./bootstrap local-homebrew-!nokegonly: SETENV=. .homebrew-build-env local-homebrew: IGNORE_MISSING_SYSTEM_PACKAGES=no + # macports + macports: SYSTEM=macports + local-macports: MP_PREFIX={envdir}/macports + local-macports-optlocal: MP_PREFIX=/opt/local + local-macports-optlocal: SUDO=sudo + local-macports-optlocal: __SUDO=--sudo + local-macports: PATH={env:MP_PREFIX}/bin:/usr/bin:/bin:/usr/sbin:/sbin + local-macports: CPATH={env:MP_PREFIX}/include + local-macports: LIBRARY_PATH={env:MP_PREFIX}/lib + local-macports: SETENV=eval $(build/bin/sage-print-system-package-command {env:SYSTEM} setup-build-env) # conda local-conda: CONDA_PREFIX={envdir}/conda local-conda: PATH={env:CONDA_PREFIX}/bin:/usr/bin:/bin:/usr/sbin:/sbin @@ -568,6 +578,8 @@ setenv = homebrew-{python3.9,python3.10,python3.11,python3.12}: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python={env:HOMEBREW}/opt/python@{env:PYTHON_MAJOR}.{env:PYTHON_MINOR}/bin/python3 # Installers from https://www.python.org/downloads/macos/ (must manually download and install) macos-python3_pythonorg: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=/Library/Frameworks/Python.framework/Versions/{env:PYTHON_MAJOR}.{env:PYTHON_MINOR}/bin/python3 + # MacPorts + macports-{python3.8,python3.9,python3.10,python3.11,python3.12}: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python={env:MP_PREFIX}/bin/python{env:PYTHON_MAJOR}.{env:PYTHON_MINOR} # https://github.com/pypa/manylinux manylinux-standard: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=/opt/python/cp{env:PYTHON_MAJOR}{env:PYTHON_MINOR}-cp{env:PYTHON_MAJOR}{env:PYTHON_MINOR}/bin/python3 conda: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=python3 @@ -613,7 +625,15 @@ setenv = macos-nohomebrew: FREETYPE_CONFIGURE=--without-harfbuzz macos-nohomebrew: PILLOW_BUILD_EXT=--disable-platform-guessing --disable-jpeg2000 --disable-imagequant --disable-tiff --disable-lcms --disable-webp --disable-webpmux --disable-xcb macos-nohomebrew: ZLIB_ROOT={env:MACOS_SDK}/usr - macos: MACOS_SDK=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk + macports: CONFIG_CONFIGURE_ARGS_2=--with-system-gcc=force CC="$CONFIGURED_CC" CXX="$CONFIGURED_CXX" + macports: CONFIGURED_CC=gcc -isysroot {env:MACOS_SDK} + macports: CONFIGURED_CXX=g++ -isysroot {env:MACOS_SDK} + macports-clang_13: CONFIGURED_CC=clang-mp-13 -isysroot {env:MACOS_SDK} + macports-clang_13: CONFIGURED_CXX=clang-mp-13 -isysroot {env:MACOS_SDK} + # + # macOS SDK/deployment target settings + # + {macos,macports}: MACOS_SDK=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk # python3 from XCode 12 has MACOSX_DEPLOYMENT_TARGET=10.14.6. Selecting a lower target would cause /usr/bin/python3 to be rejected by configure. macos-10.14: MACOS_SDK=/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk macos-10.14: MACOSX_DEPLOYMENT_TARGET=10.14.6 @@ -688,6 +708,12 @@ commands = homebrew: bash -c 'if [ ! -x {env:HOMEBREW}/bin/brew ]; then mkdir -p {env:HOMEBREW} && cd {env:HOMEBREW} && curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 ; fi' homebrew: bash -c 'case "{env:SKIP_SYSTEM_PKG_INSTALL:}" in 1|y*|Y*);; *) export PATH="build/bin:$PATH" && PACKAGES=$(sage-get-system-packages homebrew $(sage-package list {env:SAGE_PACKAGE_LIST_ARGS}) {env:ALL_EXTRA_SAGE_PACKAGES}); {env:HOMEBREW}/bin/brew install $PACKAGES; {env:HOMEBREW}/bin/brew upgrade $PACKAGES;; esac' # + # local-macports + # + # https://guide.macports.org/#installing.macports.source.multiple + local-macports: bash -c 'if [ ! -x "{env:MP_PREFIX}/bin/port" ]; then (mkdir -p {envdir}/macports-src && cd {envdir}/macports-src && curl -L https://distfiles.macports.org/MacPorts/MacPorts-2.7.2.tar.gz | tar xz --strip 1 && ./configure --prefix="{env:MP_PREFIX}" --with-applications-dir=$MP_PREFIX/Applications --with-no-root-privileges --without-startupitems && make && {env:SUDO:} make install); fi' + local-macports: bash -c 'case "{env:SKIP_SYSTEM_PKG_INSTALL:}" in 1|y*|Y*);; *) {env:SUDO:} port selfupdate && {env:SUDO:} port upgrade outdated && PACKAGES=$(build/bin/sage-get-system-packages {env:SYSTEM} $(PATH=build/bin:$PATH build/bin/sage-package list {env:SAGE_PACKAGE_LIST_ARGS}) {env:ALL_EXTRA_SAGE_PACKAGES}); eval $(build/bin/sage-print-system-package-command {env:SYSTEM} {env:__SUDO:} --yes --no-install-recommends install $PACKAGES) || [ "$IGNORE_MISSING_SYSTEM_PACKAGES" = yes ] && echo "(ignoring errors)" ;; esac' + # # local-conda # # https://docs.anaconda.com/anaconda/install/silent-mode/