diff --git a/build/pkgs/sagemath_standard_no_symbolics/SPKG.rst b/build/pkgs/sagemath_standard_no_symbolics/SPKG.rst new file mode 120000 index 00000000000..b4545b4bda6 --- /dev/null +++ b/build/pkgs/sagemath_standard_no_symbolics/SPKG.rst @@ -0,0 +1 @@ +src/README.rst \ No newline at end of file diff --git a/build/pkgs/sagemath_standard_no_symbolics/bootstrap b/build/pkgs/sagemath_standard_no_symbolics/bootstrap new file mode 120000 index 00000000000..40542346a4e --- /dev/null +++ b/build/pkgs/sagemath_standard_no_symbolics/bootstrap @@ -0,0 +1 @@ +../sagelib/bootstrap \ No newline at end of file diff --git a/build/pkgs/sagemath_standard_no_symbolics/dependencies b/build/pkgs/sagemath_standard_no_symbolics/dependencies new file mode 100644 index 00000000000..193d6021572 --- /dev/null +++ b/build/pkgs/sagemath_standard_no_symbolics/dependencies @@ -0,0 +1,9 @@ +FORCE $(SCRIPTS) arb boost_cropped $(BLAS) brial cliquer cypari cysignals cython eclib ecm flint fplll fpylll libgd gap givaro glpk gmpy2 gsl iml jinja2 jupyter_core lcalc lrcalc_python libbraiding libhomfly libpng linbox m4ri m4rie memory_allocator mpc mpfi mpfr $(MP_LIBRARY) ntl numpy pari pip pkgconfig planarity ppl pplpy primesieve primecount primecountpy pycygwin $(PYTHON) requests rw sage_conf singular symmetrica $(PCFILES) | $(PYTHON_TOOLCHAIN) sage_setup + +---------- +All lines of this file are ignored except the first. + +The above are the *build-time* dependencies of the Sage library. These are, +on the one hand, programs needed for the build/install process of the +Sage library (e.g. CYTHON, JINJA2), and on the other hand all +dependencies for Cython files (e.g. PARI, NTL, MP_LIBRARY). diff --git a/build/pkgs/sagemath_standard_no_symbolics/dependencies_check b/build/pkgs/sagemath_standard_no_symbolics/dependencies_check new file mode 100644 index 00000000000..053148f8486 --- /dev/null +++ b/build/pkgs/sagemath_standard_no_symbolics/dependencies_check @@ -0,0 +1 @@ +tox diff --git a/build/pkgs/sagemath_standard_no_symbolics/install-requires.txt b/build/pkgs/sagemath_standard_no_symbolics/install-requires.txt new file mode 100644 index 00000000000..168c71a3540 --- /dev/null +++ b/build/pkgs/sagemath_standard_no_symbolics/install-requires.txt @@ -0,0 +1 @@ +sagemath-standard-no-symbolics diff --git a/build/pkgs/sagemath_standard_no_symbolics/package-version.txt b/build/pkgs/sagemath_standard_no_symbolics/package-version.txt new file mode 120000 index 00000000000..cf10fe4b4e4 --- /dev/null +++ b/build/pkgs/sagemath_standard_no_symbolics/package-version.txt @@ -0,0 +1 @@ +../sagelib/package-version.txt \ No newline at end of file diff --git a/build/pkgs/sagemath_standard_no_symbolics/spkg-install b/build/pkgs/sagemath_standard_no_symbolics/spkg-install new file mode 120000 index 00000000000..e60fac9ffa1 --- /dev/null +++ b/build/pkgs/sagemath_standard_no_symbolics/spkg-install @@ -0,0 +1 @@ +../sagemath_objects/spkg-install \ No newline at end of file diff --git a/build/pkgs/sagemath_standard_no_symbolics/spkg-src b/build/pkgs/sagemath_standard_no_symbolics/spkg-src new file mode 100755 index 00000000000..e0527d500e9 --- /dev/null +++ b/build/pkgs/sagemath_standard_no_symbolics/spkg-src @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# +# Script to prepare an sdist tarball. +# This script is not used during build. +# +# HOW TO MAKE THE TARBALL: +# ./sage --sh build/pkgs/sagemath_standard_no_symbolics/spkg-src + +if [ -z "$SAGE_ROOT" ] ; then + echo >&2 "Error - SAGE_ROOT undefined ... exiting" + echo >&2 "Maybe run 'sage -sh'?" + exit 1 +fi + +# Exit on failure +set -e + +cd build/pkgs/sagemath_standard_no_symbolics + +cd src +python3 -u setup.py --no-user-cfg sdist --dist-dir "$SAGE_DISTFILES" diff --git a/build/pkgs/sagemath_standard_no_symbolics/src b/build/pkgs/sagemath_standard_no_symbolics/src new file mode 120000 index 00000000000..6a31af2c005 --- /dev/null +++ b/build/pkgs/sagemath_standard_no_symbolics/src @@ -0,0 +1 @@ +../../../pkgs/sagemath-standard-no-symbolics \ No newline at end of file diff --git a/build/pkgs/sagemath_standard_no_symbolics/type b/build/pkgs/sagemath_standard_no_symbolics/type new file mode 100644 index 00000000000..9839eb20815 --- /dev/null +++ b/build/pkgs/sagemath_standard_no_symbolics/type @@ -0,0 +1 @@ +experimental diff --git a/pkgs/sagemath-categories/tox.ini b/pkgs/sagemath-categories/tox.ini index a240b091e30..bc5213f1730 100644 --- a/pkgs/sagemath-categories/tox.ini +++ b/pkgs/sagemath-categories/tox.ini @@ -1,23 +1,23 @@ # To build and test in the tox environment: # -# ./sage -sh -c '(cd pkgs/sagemath-categories && tox -v -v -v -e sagepython)' +# make SAGE_WHEELS=yes sagemath_categories-build-deps && ./sage -sh -c '(cd pkgs/sagemath-categories && SAGE_NUM_THREADS=8 tox -v -v -v -e sagepython-sagewheels-nopypi-norequirements)' # -# To test interactively: +# After this, to test interactively: # -# pkgs/sagemath-categories/.tox/sagepython/bin/python +# pkgs/sagemath-categories/.tox/sagepython-sagewheels-nopypi-norequirements/bin/sage # [tox] envlist = - sagepython-norequirements + sagepython-sagewheels-nopypi-norequirements -[testenv] -deps = - !norequirements: -rrequirements.txt - # tox 3.x does not handle extras when using --installpkg. https://github.com/tox-dev/tox/issues/1576 - sagemath-repl - -extras = test +requires = + # Auto-provision a modern tox. + # [pkgenv] added in 4.2 - https://tox.wiki/en/latest/upgrading.html#packaging-configuration-and-inheritance + tox>=4.2 +[pkgenv] +# Environment in which to build the sdist. +# https://tox.wiki/en/latest/upgrading.html#packaging-environments passenv = # Variables set by .homebrew-build-env CPATH @@ -32,36 +32,73 @@ passenv = sagewheels: SAGE_SPKG_WHEELS setenv = - # Sage scripts such as sage-runtests like to use $HOME/.sage - HOME={envdir} # We supply pip options by environment variables so that they # apply both to the installation of the dependencies and of the package sagewheels: PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} nopypi: PIP_NO_INDEX=true +[testenv] +deps = + !norequirements: -rrequirements.txt + +extras = test + +passenv = {[pkgenv]passenv} + +setenv = {[pkgenv]setenv} + # Sage scripts such as sage-runtests like to use $HOME/.sage + HOME={envdir} + allowlist_externals = bash commands = - # Beware of the treacherous non-src layout. "./sage/" shadows the install sage package. + # Beware of the treacherous non-src layout. "./sage/" shadows the installed sage package. {envpython} -c 'import sys; "" in sys.path and sys.path.remove(""); import sage.cpython.builtin_types, sage.cpython.cython_metaclass, sage.cpython.debug, sage.structure.all, sage.categories.all' # Test that importing sage.categories.all initializes categories {envpython} -c 'import sys; "" in sys.path and sys.path.remove(""); from sage.categories.all import *; SimplicialComplexes(); FunctionFields()' - bash -c 'cd {temp_dir} && SAGE_SRC=$(python -c "from sage.env import SAGE_SRC; print(SAGE_SRC)") && sage-runtests --initial --environment=sage.all__sagemath_categories --optional=sage $SAGE_SRC/sage/structure || echo "(lots of doctest failures are expected)"' + bash -c 'cd $(python -c "import sys; \"\" in sys.path and sys.path.remove(\"\"); from sage.env import SAGE_LIB; print(SAGE_LIB)") \ + && sage-runtests -p --initial --environment=sage.all__sagemath_categories --optional=sage sage/structure || echo "(lots of doctest failures are expected)"' + +[testenv:.tox] +# Allow access to PyPI for auto-provisioning a suitable tox version +passenv = +setenv = PIP_NO_INDEX=false + +[testenv:.pkg-sagepython] +# Environment in which to build the sdist. +# inherits from [pkgenv] - https://tox.wiki/en/latest/upgrading.html#packaging-environments +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:.pkg-sagepython-sagewheels-nopypi] +passenv = {[pkgenv]passenv} + SAGE_VENV + SAGE_SPKG_WHEELS + +setenv = {[pkgenv]setenv} + PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} + PIP_NO_INDEX=true + +basepython = {env:SAGE_VENV}/bin/python3 [testenv:sagepython] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython [testenv:sagepython-sagewheels-nopypi] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython-sagewheels-nopypi [testenv:sagepython-sagewheels-nopypi-norequirements] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython-sagewheels-nopypi [testenv:sagepython-sagewheels] -basepython = {env:SAGE_VENV}/bin/python3 +basepython = {env:SAGE_VENV}/bin/python +package_env = .pkg-sagepython [testenv:sagepython-norequirements] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython diff --git a/pkgs/sagemath-environment/tox.ini b/pkgs/sagemath-environment/tox.ini index 46077bd8e27..65bcdc902e0 100644 --- a/pkgs/sagemath-environment/tox.ini +++ b/pkgs/sagemath-environment/tox.ini @@ -1,22 +1,28 @@ # To build and test in the tox environment: # -# ./sage -sh -c '(cd pkgs/sagemath-environment && tox -v -v -e sagepython)' +# ./sage -sh -c '(cd pkgs/sagemath-environment && tox -v -v -e sagepython-norequirements)' # # To test interactively: # -# pkgs/sagemath-environment/.tox/sagepython/bin/python +# pkgs/sagemath-environment/.tox/sagepython-norequirements/bin/python # [tox] envlist = sagepython-norequirements -isolated_build = True - -[testenv] -deps = - !norequirements: -rrequirements.txt +requires = + # Auto-provision a modern tox. + # [pkgenv] added in 4.2 - https://tox.wiki/en/latest/upgrading.html#packaging-configuration-and-inheritance + tox>=4.2 +[pkgenv] +# Environment in which to build the sdist. +# https://tox.wiki/en/latest/upgrading.html#packaging-environments passenv = + # Variables set by .homebrew-build-env + CPATH + LIBRARY_PATH + PKG_CONFIG_PATH # Parallel build SAGE_NUM_THREADS SAGE_NUM_THREADS_PARALLEL @@ -26,13 +32,23 @@ passenv = sagewheels: SAGE_SPKG_WHEELS setenv = - # Sage scripts such as sage-runtests like to use $HOME/.sage - HOME={envdir} # We supply pip options by environment variables so that they # apply both to the installation of the dependencies and of the package sagewheels: PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} nopypi: PIP_NO_INDEX=true +[testenv] +deps = + !norequirements: -rrequirements.txt + +extras = test + +passenv = {[pkgenv]passenv} + +setenv = {[pkgenv]setenv} + # Sage scripts such as sage-runtests like to use $HOME/.sage + HOME={envdir} + allowlist_externals = bash @@ -40,17 +56,43 @@ commands = # Beware of the treacherous non-src layout. "./sage/" shadows the installed sage package. {envpython} -c 'import sys; "" in sys.path and sys.path.remove(""); from sage.features.all import all_features; print(sorted(all_features(), key=lambda x: x.name)); import sage.misc.package' +[testenv:.tox] +# Allow access to PyPI for auto-provisioning a suitable tox version +passenv = +setenv = PIP_NO_INDEX=false + +[testenv:.pkg-sagepython] +# Environment in which to build the sdist. +# inherits from [pkgenv] - https://tox.wiki/en/latest/upgrading.html#packaging-environments +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:.pkg-sagepython-sagewheels-nopypi] +passenv = {[pkgenv]passenv} + SAGE_VENV + SAGE_SPKG_WHEELS + +setenv = {[pkgenv]setenv} + PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} + PIP_NO_INDEX=true + +basepython = {env:SAGE_VENV}/bin/python3 + [testenv:sagepython] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython [testenv:sagepython-sagewheels-nopypi] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython-sagewheels-nopypi [testenv:sagepython-sagewheels-nopypi-norequirements] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython-sagewheels-nopypi [testenv:sagepython-sagewheels] -basepython = {env:SAGE_VENV}/bin/python3 +basepython = {env:SAGE_VENV}/bin/python +package_env = .pkg-sagepython [testenv:sagepython-norequirements] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython diff --git a/pkgs/sagemath-objects/tox.ini b/pkgs/sagemath-objects/tox.ini index e34531467e5..e5bf1e6dac7 100644 --- a/pkgs/sagemath-objects/tox.ini +++ b/pkgs/sagemath-objects/tox.ini @@ -1,21 +1,23 @@ # To build and test in the tox environment: # -# ./sage -sh -c '(cd pkgs/sagemath-objects && tox -v -v -e sagepython)' +# ./sage -sh -c '(cd pkgs/sagemath-objects && SAGE_NUM_THREADS=8 tox -v -v -e sagepython-norequirements)' # -# To test interactively: +# After this, to test interactively: # -# pkgs/sagemath-objects/.tox/sagepython/bin/python +# pkgs/sagemath-objects/.tox/sagepython-norequirements/bin/python # [tox] envlist = sagepython-norequirements -[testenv] -deps = - !norequirements: -rrequirements.txt - -extras = test +requires = + # Auto-provision a modern tox. + # [pkgenv] added in 4.2 - https://tox.wiki/en/latest/upgrading.html#packaging-configuration-and-inheritance + tox>=4.2 +[pkgenv] +# Environment in which to build the sdist. +# https://tox.wiki/en/latest/upgrading.html#packaging-environments passenv = # Variables set by .homebrew-build-env CPATH @@ -30,13 +32,23 @@ passenv = sagewheels: SAGE_SPKG_WHEELS setenv = - # Sage scripts such as sage-runtests like to use $HOME/.sage - HOME={envdir} # We supply pip options by environment variables so that they # apply both to the installation of the dependencies and of the package sagewheels: PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} nopypi: PIP_NO_INDEX=true +[testenv] +deps = + !norequirements: -rrequirements.txt + +extras = test + +passenv = {[pkgenv]passenv} + +setenv = {[pkgenv]setenv} + # Sage scripts such as sage-runtests like to use $HOME/.sage + HOME={envdir} + allowlist_externals = bash @@ -48,17 +60,43 @@ commands = #bash -c 'cd {temp_dir} && SAGE_SRC=$(python -c "from sage.env import SAGE_SRC; print(SAGE_SRC)") && sage-runtests --environment=sage.all__sagemath_objects --initial --optional=sage $SAGE_SRC/sage/structure || echo "(lots of doctest failures are expected)"' +[testenv:.tox] +# Allow access to PyPI for auto-provisioning a suitable tox version +passenv = +setenv = PIP_NO_INDEX=false + +[testenv:.pkg-sagepython] +# Environment in which to build the sdist. +# inherits from [pkgenv] - https://tox.wiki/en/latest/upgrading.html#packaging-environments +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:.pkg-sagepython-sagewheels-nopypi] +passenv = {[pkgenv]passenv} + SAGE_VENV + SAGE_SPKG_WHEELS + +setenv = {[pkgenv]setenv} + PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} + PIP_NO_INDEX=true + +basepython = {env:SAGE_VENV}/bin/python3 + [testenv:sagepython] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython [testenv:sagepython-sagewheels-nopypi] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython-sagewheels-nopypi [testenv:sagepython-sagewheels-nopypi-norequirements] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython-sagewheels-nopypi [testenv:sagepython-sagewheels] -basepython = {env:SAGE_VENV}/bin/python3 +basepython = {env:SAGE_VENV}/bin/python +package_env = .pkg-sagepython [testenv:sagepython-norequirements] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython diff --git a/pkgs/sagemath-repl/tox.ini b/pkgs/sagemath-repl/tox.ini index 084016ce768..1637788be39 100644 --- a/pkgs/sagemath-repl/tox.ini +++ b/pkgs/sagemath-repl/tox.ini @@ -1,21 +1,23 @@ # To build and test in the tox environment: # -# ./sage -sh -c '(cd pkgs/sagemath-repl && tox -v -v -e sagepython)' +# make SAGE_WHEELS=yes sagemath_repl-build-deps && ./sage -sh -c '(cd pkgs/sagemath-repl && SAGE_NUM_THREADS=8 tox -v -v -e sagepython-sagewheels-nopypi-norequirements)' # -# To test interactively: +# After this, to test interactively: # -# pkgs/sagemath-repl/.tox/sagepython/bin/python +# pkgs/sagemath-repl/.tox/sagepython-sagewheels-nopypi-norequirements/bin/python # [tox] envlist = - sagepython-norequirements + sagepython-sagewheels-nopypi-norequirements -isolated_build = True - -[testenv] -deps = - !norequirements: -rrequirements.txt +requires = + # Auto-provision a modern tox. + # [pkgenv] added in 4.2 - https://tox.wiki/en/latest/upgrading.html#packaging-configuration-and-inheritance + tox>=4.2 +[pkgenv] +# Environment in which to build the sdist. +# https://tox.wiki/en/latest/upgrading.html#packaging-environments passenv = # Variables set by .homebrew-build-env CPATH @@ -30,13 +32,23 @@ passenv = sagewheels: SAGE_SPKG_WHEELS setenv = - # Sage scripts such as sage-runtests like to use $HOME/.sage - HOME={envdir} # We supply pip options by environment variables so that they # apply both to the installation of the dependencies and of the package sagewheels: PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} nopypi: PIP_NO_INDEX=true +[testenv] +deps = + !norequirements: -rrequirements.txt + +extras = test + +passenv = {[pkgenv]passenv} + +setenv = {[pkgenv]setenv} + # Sage scripts such as sage-runtests like to use $HOME/.sage + HOME={envdir} + allowlist_externals = bash @@ -44,19 +56,45 @@ commands = # Beware of the treacherous non-src layout. "./sage/" shadows the installed sage package. {envpython} -c 'import sys; "" in sys.path and sys.path.remove(""); import sage.repl.all; import sage.doctest.all' - bash -c 'cd bin && SAGE_SRC=$({envpython} -c "from sage.env import SAGE_SRC; print(SAGE_SRC)") && sage-runtests --environment=sage.all__sagemath_repl --initial --optional=sage $SAGE_SRC/sage/repl $SAGE_SRC/sage/doctest $SAGE_SRC/sage/misc/sage_input.py $SAGE_SRC/sage/misc/sage_eval.py || echo "(lots of doctest failures are expected)"' + bash -c 'cd $({envpython} -c "import sys; \"\" in sys.path and sys.path.remove(\"\"); from sage.env import SAGE_LIB; print(SAGE_LIB)") && sage-runtests -p --environment=sage.all__sagemath_repl --initial --optional=sage sage/repl sage/doctest sage/misc/sage_input.py sage/misc/sage_eval.py || echo "(lots of doctest failures are expected)"' + +[testenv:.tox] +# Allow access to PyPI for auto-provisioning a suitable tox version +passenv = +setenv = PIP_NO_INDEX=false + +[testenv:.pkg-sagepython] +# Environment in which to build the sdist. +# inherits from [pkgenv] - https://tox.wiki/en/latest/upgrading.html#packaging-environments +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:.pkg-sagepython-sagewheels-nopypi] +passenv = {[pkgenv]passenv} + SAGE_VENV + SAGE_SPKG_WHEELS + +setenv = {[pkgenv]setenv} + PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} + PIP_NO_INDEX=true + +basepython = {env:SAGE_VENV}/bin/python3 [testenv:sagepython] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython [testenv:sagepython-sagewheels-nopypi] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython-sagewheels-nopypi [testenv:sagepython-sagewheels-nopypi-norequirements] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython-sagewheels-nopypi [testenv:sagepython-sagewheels] -basepython = {env:SAGE_VENV}/bin/python3 +basepython = {env:SAGE_VENV}/bin/python +package_env = .pkg-sagepython [testenv:sagepython-norequirements] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython diff --git a/pkgs/sagemath-standard-no-symbolics/MANIFEST.in.m4 b/pkgs/sagemath-standard-no-symbolics/MANIFEST.in.m4 new file mode 100644 index 00000000000..05f172a8c92 --- /dev/null +++ b/pkgs/sagemath-standard-no-symbolics/MANIFEST.in.m4 @@ -0,0 +1,32 @@ +dnl MANIFEST.in is generated from this file by SAGE_ROOT/bootstrap via m4. + +dnl Include all from sagemath-categories (via m4 include) +include(`../sagelib/src/MANIFEST.in') + +exclude *.m4 +include requirements.txt + +global-include all__sagemath_standard_no_symbolics.py + +prune sage/symbolic +prune sage/functions +prune sage/manifolds +prune sage/lfunctions +prune sage/geometry/riemannian_manifolds +prune sage/geometry/hyperbolic_space +prune sage/dynamics/complex_dynamics +prune sage/rings/asymptotic + +exclude sage/calculus/calculus.* +exclude sage/calculus/var.* + +exclude sage/modules/vector_*symbol*.* +exclude sage/matrix/matrix_symbolic_*.* +exclude sage/groups/misc_gps/argument_groups.* +exclude sage/groups/misc_gps/imaginary_groups.* + +prune sage/libs/pynac +exclude sage/libs/ecl.p* +exclude sage/libs/giac.p* + +exclude sage/interfaces/maxima*.p* diff --git a/pkgs/sagemath-standard-no-symbolics/README.rst b/pkgs/sagemath-standard-no-symbolics/README.rst new file mode 100644 index 00000000000..f8ad2583442 --- /dev/null +++ b/pkgs/sagemath-standard-no-symbolics/README.rst @@ -0,0 +1,25 @@ +====================================================================================== + Sage: Open Source Mathematics Software: Sage library without the symbolics subsystem +====================================================================================== + +About SageMath +-------------- + + "Creating a Viable Open Source Alternative to + Magma, Maple, Mathematica, and MATLAB" + + Copyright (C) 2005-2022 The Sage Development Team + + https://www.sagemath.org + +SageMath fully supports all major Linux distributions, recent versions of macOS, and Windows (using Cygwin or Windows Subsystem for Linux). + +The traditional and recommended way to install SageMath is from source via Sage-the-distribution (https://www.sagemath.org/download-source.html). Sage-the-distribution first builds a large number of open source packages from source (unless it finds suitable versions installed in the system) and then installs the Sage Library (sagelib, implemented in Python and Cython). + + +About this experimental pip-installable source distribution +----------------------------------------------------------- + +This pip-installable source distribution `sagemath-standard-no-symbolics` is an experimental subset distribution of the Sage library. + +Its main purpose is as a technical tool for the modularization project (https://trac.sagemath.org/ticket/29705), to test that large parts of the Sage library are independent of the symbolics subsystem. diff --git a/pkgs/sagemath-standard-no-symbolics/VERSION.txt b/pkgs/sagemath-standard-no-symbolics/VERSION.txt new file mode 120000 index 00000000000..43f4773d7de --- /dev/null +++ b/pkgs/sagemath-standard-no-symbolics/VERSION.txt @@ -0,0 +1 @@ +../../src/VERSION.txt \ No newline at end of file diff --git a/pkgs/sagemath-standard-no-symbolics/bin b/pkgs/sagemath-standard-no-symbolics/bin new file mode 120000 index 00000000000..2f8b9b30ee7 --- /dev/null +++ b/pkgs/sagemath-standard-no-symbolics/bin @@ -0,0 +1 @@ +../../src/bin \ No newline at end of file diff --git a/pkgs/sagemath-standard-no-symbolics/pyproject.toml.m4 b/pkgs/sagemath-standard-no-symbolics/pyproject.toml.m4 new file mode 120000 index 00000000000..21eac63af37 --- /dev/null +++ b/pkgs/sagemath-standard-no-symbolics/pyproject.toml.m4 @@ -0,0 +1 @@ +../sagemath-standard/pyproject.toml.m4 \ No newline at end of file diff --git a/pkgs/sagemath-standard-no-symbolics/requirements.txt.m4 b/pkgs/sagemath-standard-no-symbolics/requirements.txt.m4 new file mode 120000 index 00000000000..625ede57362 --- /dev/null +++ b/pkgs/sagemath-standard-no-symbolics/requirements.txt.m4 @@ -0,0 +1 @@ +../sagemath-standard/requirements.txt.m4 \ No newline at end of file diff --git a/pkgs/sagemath-standard-no-symbolics/sage b/pkgs/sagemath-standard-no-symbolics/sage new file mode 120000 index 00000000000..e0da5daa6f2 --- /dev/null +++ b/pkgs/sagemath-standard-no-symbolics/sage @@ -0,0 +1 @@ +../../src/sage \ No newline at end of file diff --git a/pkgs/sagemath-standard-no-symbolics/setup.cfg.m4 b/pkgs/sagemath-standard-no-symbolics/setup.cfg.m4 new file mode 100644 index 00000000000..2b917d9d400 --- /dev/null +++ b/pkgs/sagemath-standard-no-symbolics/setup.cfg.m4 @@ -0,0 +1,158 @@ +# -*- conf-unix -*- +[metadata] +name = sagemath-standard-no-symbolics +version = file: VERSION.txt +description = Sage: Open Source Mathematics Software: Sage library without the symbolics subsystem +long_description = file: README.rst +long_description_content_type = text/x-rst +license = GNU General Public License (GPL) v2 or later +license_files = LICENSE.txt +author = The Sage Developers +author_email = sage-support@googlegroups.com +url = https://www.sagemath.org + +classifiers = + Development Status :: 6 - Mature + Intended Audience :: Education + Intended Audience :: Science/Research + License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+) + Operating System :: POSIX + Operating System :: MacOS :: MacOS X + Programming Language :: Python :: 3 :: Only + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 + Programming Language :: Python :: 3.11 + Programming Language :: Python :: Implementation :: CPython + Topic :: Scientific/Engineering :: Mathematics + +[options] +python_requires = >=3.8, <3.12 +install_requires = + esyscmd(`sage-get-system-packages install-requires \ + sage_conf \ + six \ + | sed "2,\$s/^/ /;"')dnl' +dnl From build/pkgs/sagelib/dependencies + esyscmd(`sage-get-system-packages install-requires \ + cypari \ + cysignals \ + cython \ + gmpy2 \ + jinja2 \ + jupyter_core \ + lrcalc_python \ + memory_allocator \ + numpy \ + pkgconfig \ + pplpy \ + primecountpy \ + requests \ + | sed "2,\$s/^/ /;"')dnl' +dnl From Makefile.in: SAGERUNTIME + esyscmd(`sage-get-system-packages install-requires \ + ipython \ + pexpect \ + | sed "2,\$s/^/ /;"')dnl' +dnl From Makefile.in: DOC_DEPENDENCIES + esyscmd(`sage-get-system-packages install-requires \ + sphinx \ + networkx \ + scipy \ + sympy \ + matplotlib \ + pillow \ + mpmath \ + ipykernel \ + jupyter_client \ + ipywidgets \ + | sed "2,\$s/^/ /;"')dnl' +dnl Other Python packages that are standard spkg, used in doctests + esyscmd(`sage-get-system-packages install-requires \ + fpylll \ + | sed "2,\$s/^/ /;"')dnl' +dnl pycryptosat # Sage distribution installs it as part of cryptominisat. According to its README on https://pypi.org/project/pycryptosat/: "The pycryptosat python package compiles while compiling CryptoMiniSat. It cannot be compiled on its own, it must be compiled at the same time as CryptoMiniSat." +dnl Packages with important upper version bounds + esyscmd(`sage-get-system-packages install-requires \ + ptyprocess \ + | sed "2,\$s/^/ /;"')dnl' + +scripts = + # The sage script + bin/sage + # Other scripts that should be in the path also for OS packaging of sage: + bin/sage-eval + # Included because it is useful for doctesting/coverage testing user scripts too: + bin/sage-runtests + bin/sage-fixdoctests + bin/sage-coverage + # The following is deprecated but might still be used in user package install scripts + bin/sage-cython + # Helper scripts invoked by sage script + # (they would actually belong to something like libexec) + bin/sage-cachegrind + bin/sage-callgrind + bin/sage-massif + bin/sage-omega + bin/sage-valgrind + bin/sage-venv-config + bin/sage-version.sh + bin/sage-cleaner + # Only makes sense in sage-the-distribution. TODO: Move to another installation script. + bin/sage-list-packages + # Uncategorized scripts in alphabetical order + bin/sage-env + # sage-env-config -- installed by sage_conf + # sage-env-config.in -- not to be installed + bin/sage-grep + bin/sage-grepdoc + bin/sage-inline-fortran + bin/sage-ipynb2rst + bin/sage-ipython + bin/sage-notebook + bin/sage-num-threads.py + bin/sage-preparse + bin/sage-python + bin/sage-rebase.bat + bin/sage-rebase.sh + bin/sage-rebaseall.bat + bin/sage-rebaseall.sh + bin/sage-run + bin/sage-run-cython + bin/sage-startuptime.py + bin/sage-update-version + +[options.package_data] + +sage.libs.gap = + sage.gaprc + +sage.doctest = + tests/* + +sage.repl.rich_output = + example* + +sage = + ext_data/* + ext_data/kenzo/* + ext_data/singular/* + ext_data/singular/function_field/* + ext_data/images/* + ext_data/doctest/* + ext_data/doctest/invalid/* + ext_data/gap/* + ext_data/gap/joyner/* + ext_data/mwrank/* + ext_data/notebook-ipython/* + ext_data/nbconvert/* + ext_data/graphs/* + ext_data/pari/* + ext_data/pari/dokchitser/* + ext_data/pari/buzzard/* + ext_data/pari/simon/* + ext_data/magma/* + ext_data/magma/latex/* + ext_data/magma/sage/* + ext_data/valgrind/* + ext_data/threejs/* diff --git a/pkgs/sagemath-standard-no-symbolics/setup.py b/pkgs/sagemath-standard-no-symbolics/setup.py new file mode 120000 index 00000000000..e1f81d537ae --- /dev/null +++ b/pkgs/sagemath-standard-no-symbolics/setup.py @@ -0,0 +1 @@ +../sagemath-standard/setup.py \ No newline at end of file diff --git a/pkgs/sagemath-standard-no-symbolics/tox.ini b/pkgs/sagemath-standard-no-symbolics/tox.ini new file mode 120000 index 00000000000..f3bd09cc088 --- /dev/null +++ b/pkgs/sagemath-standard-no-symbolics/tox.ini @@ -0,0 +1 @@ +../sagemath-standard/tox.ini \ No newline at end of file diff --git a/pkgs/sagemath-standard/tox.ini b/pkgs/sagemath-standard/tox.ini index 305eddd7586..f63b107e2ed 100644 --- a/pkgs/sagemath-standard/tox.ini +++ b/pkgs/sagemath-standard/tox.ini @@ -1,7 +1,3 @@ -# First install tox: -# -# ./sage -i tox -# # All tests require an installation of the non-Python components of the Sage distribution # in SAGE_LOCAL. # @@ -67,14 +63,14 @@ envlist = # sagepython-sagewheels-pipenv -[testenv] -deps = - pipenv: pipenv - !pipenv-!norequirements: -rrequirements.txt - ## Needed for fpylll - norequirements: Cython - norequirements: cysignals +requires = + # Auto-provision a modern tox. + # [pkgenv] added in 4.2 - https://tox.wiki/en/latest/upgrading.html#packaging-configuration-and-inheritance + tox>=4.2 +[pkgenv] +# Environment in which to build the sdist. +# https://tox.wiki/en/latest/upgrading.html#packaging-environments passenv = # Variables set by .homebrew-build-env CPATH @@ -82,14 +78,13 @@ passenv = PKG_CONFIG_PATH # Parallel build SAGE_NUM_THREADS + SAGE_NUM_THREADS_PARALLEL # SAGE_VENV only for referring to the basepython or finding the wheels sagepython, sagewheels: SAGE_VENV # Location of the wheels sagewheels: SAGE_SPKG_WHEELS setenv = - # Sage scripts such as sage-runtests like to use $HOME/.sage - HOME={envdir} # We supply pip options by environment variables so that they # apply both to the installation of the dependencies and of the package sagewheels: PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} @@ -103,23 +98,28 @@ setenv = # so we cannot isolate it in the tox environment. pipenv: PIPENV_SKIP_LOCK=true +[testenv] +deps = + pipenv: pipenv + !pipenv-!norequirements: -rrequirements.txt + ## Needed for fpylll + norequirements: Cython + norequirements: cysignals + sitepackages = sitepackages: True !sitepackages: False -allowlist_externals = - bash +extras = test -skip_install = - pipenv: True - !pipenv: False +passenv = {[pkgenv]passenv} -commands_pre = - # Use Pipenv to install according to Pipfile into the virtual environment created by tox. - # https://pipenv-searchable.readthedocs.io/advanced.html#tox-automation-project - pipenv-!dist: pipenv install -v -v -v - # Same, but use $SAGE_ROOT/Pipfile - pipenv-dist: bash -c '(cd ../../../.. && pipenv install -v -v -v)' +setenv = {[pkgenv]setenv} + # Sage scripts such as sage-runtests like to use $HOME/.sage + HOME={envdir} + +allowlist_externals = + bash commands = # Beware of the treacherous non-src layout. "./sage/" shadows the installed sage package. @@ -128,25 +128,53 @@ commands = # We check that the "sage" script invokes the correct Python. sage -c 'import sys; print("sys.path =", sys.path); import sage.all; print(sage.all.__file__)' - sage -t -p --all + sage -t -p --initial --installed + +[testenv:.tox] +# Allow access to PyPI for auto-provisioning a suitable tox version +passenv = +setenv = PIP_NO_INDEX=false + +[testenv:.pkg-sagepython] +# Environment in which to build the sdist. +# inherits from [pkgenv] - https://tox.wiki/en/latest/upgrading.html#packaging-environments +basepython = {env:SAGE_VENV}/bin/python3 + +[testenv:.pkg-sagepython-sagewheels-nopypi] +passenv = {[pkgenv]passenv} + SAGE_VENV + SAGE_SPKG_WHEELS + +setenv = {[pkgenv]setenv} + PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} + PIP_NO_INDEX=true + +basepython = {env:SAGE_VENV}/bin/python3 [testenv:sagepython] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython [testenv:sagepython-sagewheels-nopypi] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython-sagewheels-nopypi [testenv:sagepython-sagewheels-nopypi-norequirements] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython-sagewheels-nopypi [testenv:sagepython-sagewheels] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython [testenv:sagepython-sagewheels-pipenv-dist] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython [testenv:sagepython-sagewheels-norequirements] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython [testenv:sagepython-sagewheels-pipenv] basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython diff --git a/src/bin/sage-eval b/src/bin/sage-eval index 875c98a785b..664e1051742 100755 --- a/src/bin/sage-eval +++ b/src/bin/sage-eval @@ -2,7 +2,10 @@ import sys from sage.all import * -from sage.calculus.predefined import x +try: + from sage.calculus.predefined import x +except ImportError: + pass from sage.repl.preparse import preparse if len(sys.argv) > 1: diff --git a/src/doc/en/developer/packaging_sage_library.rst b/src/doc/en/developer/packaging_sage_library.rst index 229c3dc01d7..03eab612a1d 100644 --- a/src/doc/en/developer/packaging_sage_library.rst +++ b/src/doc/en/developer/packaging_sage_library.rst @@ -591,16 +591,14 @@ distribution to be tested (and its Python dependencies). Let's try it out first with the entire Sage library, represented by the distribution **sagemath-standard**. Note that after Sage has been -built normally, a set of wheels for all installed Python packages is -available in ``SAGE_VENV/var/lib/sage/wheels/``:: +built normally, a set of wheels for most installed Python distribution +packages is available in ``SAGE_VENV/var/lib/sage/wheels/``:: $ ls venv/var/lib/sage/wheels Babel-2.9.1-py2.py3-none-any.whl Cython-0.29.24-cp39-cp39-macosx_11_0_x86_64.whl Jinja2-2.11.2-py2.py3-none-any.whl ... - sage_conf-9.5b6-py3-none-any.whl - ... scipy-1.7.2-cp39-cp39-macosx_11_0_x86_64.whl setuptools-58.2.0-py3-none-any.whl ... @@ -608,6 +606,22 @@ available in ``SAGE_VENV/var/lib/sage/wheels/``:: widgetsnbextension-3.5.1-py2.py3-none-any.whl zipp-3.5.0-py3-none-any.whl +However, in a build of Sage with the default configuration +``configure --enable-editable``, there will be no wheels for the +distributions ``sage_*`` and ``sagemath-*``. + +To create these wheels, use the command ``make wheels``:: + + $ make wheels + ... + $ ls venv/var/lib/sage/wheels/sage* + ... + sage_conf-10.0b2-py3-none-any.whl + ... + +(You can also use ``./configure --enable-wheels`` to ensure that +these wheels are always available and up to date.) + Note in particular the wheel for **sage-conf**, which provides configuration variable settings and the connection to the non-Python packages installed in ``SAGE_LOCAL``. @@ -648,7 +662,7 @@ without depending on optional packages, but without the packages Again we can run the test with ``tox`` in a separate virtual environment:: - $ ./bootstrap && ./sage -sh -c '(cd pkgs/sagemath-standard-no-symbolics && SAGE_NUM_THREADS=16 tox -v -v -v -e sagepython-sagewheels-nopypi)' + $ ./bootstrap && make wheels && ./sage -sh -c '(cd pkgs/sagemath-standard-no-symbolics && SAGE_NUM_THREADS=16 tox -v -v -v -e sagepython-sagewheels-nopypi-norequirements)' Some small distributions, for example the ones providing the two lowest levels, `sagemath-objects `_ diff --git a/src/doc/en/reference/rings/index.rst b/src/doc/en/reference/rings/index.rst index d43d1be4003..52847e952b4 100644 --- a/src/doc/en/reference/rings/index.rst +++ b/src/doc/en/reference/rings/index.rst @@ -8,6 +8,7 @@ Base Classes for Rings, Algebras and Fields :maxdepth: 1 sage/rings/ring + sage/rings/abc Ideals ------ diff --git a/src/doc/en/reference/rings_standard/index.rst b/src/doc/en/reference/rings_standard/index.rst index 4bb5338609f..97bf2b8ea35 100644 --- a/src/doc/en/reference/rings_standard/index.rst +++ b/src/doc/en/reference/rings_standard/index.rst @@ -12,6 +12,8 @@ Integers sage/rings/bernmm sage/rings/bernoulli_mod_p sage/rings/factorint + sage/rings/factorint_flint + sage/rings/factorint_pari sage/rings/fast_arith sage/rings/sum_of_squares sage/arith/functions diff --git a/src/sage/algebras/quantum_clifford.py b/src/sage/algebras/quantum_clifford.py index 1e57682f255..5079283e8ec 100644 --- a/src/sage/algebras/quantum_clifford.py +++ b/src/sage/algebras/quantum_clifford.py @@ -27,7 +27,7 @@ from sage.rings.fraction_field import FractionField from sage.sets.finite_enumerated_set import FiniteEnumeratedSet from itertools import product -from sage.misc.misc import powerset +from sage.combinat.subset import powerset class QuantumCliffordAlgebra(CombinatorialFreeModule): r""" diff --git a/src/sage/all.py b/src/sage/all.py index 288039a72f4..f3433d56961 100644 --- a/src/sage/all.py +++ b/src/sage/all.py @@ -85,7 +85,6 @@ from sage.arith.all import * from sage.matrix.all import * -from sage.symbolic.all import * from sage.modules.all import * from sage.monoids.all import * from sage.algebras.all import * @@ -101,9 +100,6 @@ from sage.probability.all import * from sage.interfaces.all import * -from sage.functions.all import * -from sage.calculus.all import * - lazy_import('sage.tests', 'all', as_='tests', deprecation=27337) from sage.cpython.all import * @@ -116,11 +112,8 @@ from sage.coding.all import * from sage.combinat.all import * -from sage.lfunctions.all import * - from sage.geometry.all import * from sage.geometry.triangulation.all import * -from sage.geometry.riemannian_manifolds.all import * from sage.dynamics.all import * @@ -158,8 +151,6 @@ from sage.knots.all import * -from sage.manifolds.all import * - from cysignals.alarm import alarm, cancel_alarm # Lazily import interacts (#15335) @@ -171,6 +162,16 @@ from sage.rings.qqbar import _init_qqbar _init_qqbar() +try: + from sage.symbolic.all import * + from sage.functions.all import * + from sage.calculus.all import * + from sage.manifolds.all import * + from sage.lfunctions.all import * + from sage.geometry.riemannian_manifolds.all import * +except ImportError: + pass + ########################################################### #### WARNING: # DO *not* import numpy / matplotlib / networkx here!! diff --git a/src/sage/all_cmdline.py b/src/sage/all_cmdline.py index 197d34ebc90..836a649d747 100644 --- a/src/sage/all_cmdline.py +++ b/src/sage/all_cmdline.py @@ -15,7 +15,11 @@ sage_mode = 'cmdline' from sage.all import * -from sage.calculus.predefined import x + +try: + from sage.calculus.predefined import x +except ImportError: + pass from sage.misc.lazy_import import lazy_import diff --git a/src/sage/arith/all.py b/src/sage/arith/all.py index c93e9f05bc9..b826b6557d0 100644 --- a/src/sage/arith/all.py +++ b/src/sage/arith/all.py @@ -24,6 +24,10 @@ dedekind_sum, prime_factors, prime_range, valuation) +# These will be overridden by sage.functions.all +from .misc import (integer_ceil as ceil, + integer_floor as floor) + lazy_import('sage.arith.misc', ('Sigma', 'Moebius', 'Euler_Phi'), deprecation=30322) from .functions import lcm diff --git a/src/sage/arith/functions.pyx b/src/sage/arith/functions.pyx index 2fe15bbb974..58a1fc91bd9 100644 --- a/src/sage/arith/functions.pyx +++ b/src/sage/arith/functions.pyx @@ -39,17 +39,17 @@ def lcm(a, b=None): EXAMPLES:: - sage: lcm(97,100) + sage: lcm(97, 100) 9700 - sage: LCM(97,100) + sage: LCM(97, 100) 9700 - sage: LCM(0,2) + sage: LCM(0, 2) 0 - sage: LCM(-3,-5) + sage: LCM(-3, -5) 15 sage: LCM([1,2,3,4,5]) 60 - sage: v = LCM(range(1,10000)) # *very* fast! + sage: v = LCM(range(1, 10000)) # *very* fast! sage: len(str(v)) 4349 @@ -72,25 +72,25 @@ def lcm(a, b=None): Make sure we try `\QQ` and not merely `\ZZ` (:trac:`13014`):: - sage: bool(lcm(2/5, 3/7) == lcm(SR(2/5), SR(3/7))) + sage: bool(lcm(2/5, 3/7) == lcm(SR(2/5), SR(3/7))) # optional - sage.symbolic True Make sure that the lcm of Expressions stays symbolic:: sage: parent(lcm(2, 4)) Integer Ring - sage: parent(lcm(SR(2), 4)) + sage: parent(lcm(SR(2), 4)) # optional - sage.symbolic Symbolic Ring - sage: parent(lcm(2, SR(4))) + sage: parent(lcm(2, SR(4))) # optional - sage.symbolic Symbolic Ring - sage: parent(lcm(SR(2), SR(4))) + sage: parent(lcm(SR(2), SR(4))) # optional - sage.symbolic Symbolic Ring Verify that objects without lcm methods but which can't be coerced to `\ZZ` or `\QQ` raise an error:: - sage: F. = FreeMonoid(2) - sage: lcm(x,y) + sage: F. = FreeMonoid(2) # optional - sage.groups + sage: lcm(x,y) # optional - sage.groups Traceback (most recent call last): ... TypeError: unable to find lcm of x and y diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index 9c671105c5a..2e975bc7ffd 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -20,7 +20,6 @@ import math from collections.abc import Iterable -from sage.misc.misc import powerset from sage.misc.misc_c import prod from sage.structure.element import parent @@ -82,26 +81,26 @@ def algdep(z, degree, known_bits=None, use_bits=None, known_digits=None, EXAMPLES:: - sage: algdep(1.888888888888888, 1) + sage: algdep(1.888888888888888, 1) # optional - sage.libs.pari 9*x - 17 - sage: algdep(0.12121212121212,1) + sage: algdep(0.12121212121212, 1) # optional - sage.libs.pari 33*x - 4 - sage: algdep(sqrt(2),2) + sage: algdep(sqrt(2), 2) # optional - sage.libs.pari sage.symbolic x^2 - 2 This example involves a complex number:: - sage: z = (1/2)*(1 + RDF(sqrt(3)) *CC.0); z + sage: z = (1/2) * (1 + RDF(sqrt(3)) * CC.0); z # optional - sage.symbolic 0.500000000000000 + 0.866025403784439*I - sage: algdep(z, 6) + sage: algdep(z, 6) # optional - sage.symbolic x^2 - x + 1 This example involves a `p`-adic number:: - sage: K = Qp(3, print_mode = 'series') - sage: a = K(7/19); a + sage: K = Qp(3, print_mode='series') # optional - sage.rings.padics + sage: a = K(7/19); a # optional - sage.rings.padics 1 + 2*3 + 3^2 + 3^3 + 2*3^4 + 2*3^5 + 3^8 + 2*3^9 + 3^11 + 3^12 + 2*3^15 + 2*3^16 + 3^17 + 2*3^19 + O(3^20) - sage: algdep(a, 1) + sage: algdep(a, 1) # optional - sage.rings.padics 19*x - 7 These examples show the importance of proper precision control. We @@ -109,82 +108,82 @@ def algdep(z, degree, known_bits=None, use_bits=None, known_digits=None, 33'rd bit:: sage: z = sqrt(RealField(200)(2)) + (1/2)^33 - sage: p = algdep(z, 4); p + sage: p = algdep(z, 4); p # optional - sage.libs.pari 227004321085*x^4 - 216947902586*x^3 - 99411220986*x^2 + 82234881648*x - 211871195088 - sage: factor(p) + sage: factor(p) # optional - sage.libs.pari 227004321085*x^4 - 216947902586*x^3 - 99411220986*x^2 + 82234881648*x - 211871195088 - sage: algdep(z, 4, known_bits=32) + sage: algdep(z, 4, known_bits=32) # optional - sage.libs.pari x^2 - 2 - sage: algdep(z, 4, known_digits=10) + sage: algdep(z, 4, known_digits=10) # optional - sage.libs.pari x^2 - 2 - sage: algdep(z, 4, use_bits=25) + sage: algdep(z, 4, use_bits=25) # optional - sage.libs.pari x^2 - 2 - sage: algdep(z, 4, use_digits=8) + sage: algdep(z, 4, use_digits=8) # optional - sage.libs.pari x^2 - 2 Using the ``height_bound`` and ``proof`` parameters, we can see that `pi` is not the root of an integer polynomial of degree at most 5 and coefficients bounded above by 10:: - sage: algdep(pi.n(), 5, height_bound=10, proof=True) is None + sage: algdep(pi.n(), 5, height_bound=10, proof=True) is None # optional - sage.libs.pari sage.symbolic True For stronger results, we need more precision:: - sage: algdep(pi.n(), 5, height_bound=100, proof=True) is None + sage: algdep(pi.n(), 5, height_bound=100, proof=True) is None # optional - sage.libs.pari sage.symbolic Traceback (most recent call last): ... ValueError: insufficient precision for non-existence proof - sage: algdep(pi.n(200), 5, height_bound=100, proof=True) is None + sage: algdep(pi.n(200), 5, height_bound=100, proof=True) is None # optional - sage.libs.pari sage.symbolic True - sage: algdep(pi.n(), 10, height_bound=10, proof=True) is None + sage: algdep(pi.n(), 10, height_bound=10, proof=True) is None # optional - sage.libs.pari sage.symbolic Traceback (most recent call last): ... ValueError: insufficient precision for non-existence proof - sage: algdep(pi.n(200), 10, height_bound=10, proof=True) is None + sage: algdep(pi.n(200), 10, height_bound=10, proof=True) is None # optional - sage.libs.pari sage.symbolic True We can also use ``proof=True`` to get positive results:: - sage: a = sqrt(2) + sqrt(3) + sqrt(5) - sage: algdep(a.n(), 8, height_bound=1000, proof=True) + sage: a = sqrt(2) + sqrt(3) + sqrt(5) # optional - sage.libs.pari sage.symbolic + sage: algdep(a.n(), 8, height_bound=1000, proof=True) # optional - sage.libs.pari sage.symbolic Traceback (most recent call last): ... ValueError: insufficient precision for uniqueness proof - sage: f = algdep(a.n(1000), 8, height_bound=1000, proof=True); f + sage: f = algdep(a.n(1000), 8, height_bound=1000, proof=True); f # optional - sage.libs.pari sage.symbolic x^8 - 40*x^6 + 352*x^4 - 960*x^2 + 576 - sage: f(a).expand() + sage: f(a).expand() # optional - sage.libs.pari sage.symbolic 0 TESTS:: - sage: algdep(complex("1+2j"), 4) + sage: algdep(complex("1+2j"), 4) # optional - sage.libs.pari x^2 - 2*x + 5 We get an irreducible polynomial even if PARI returns a reducible one:: sage: z = CDF(1, RR(3).sqrt())/2 - sage: pari(z).algdep(5) + sage: pari(z).algdep(5) # optional - sage.libs.pari x^5 + x^2 - sage: algdep(z, 5) + sage: algdep(z, 5) # optional - sage.libs.pari x^2 - x + 1 Check that cases where a constant polynomial might look better get handled correctly:: - sage: z=CC(-1)**(1/3) - sage: algdep(z,1) + sage: z = CC(-1)**(1/3) + sage: algdep(z, 1) # optional - sage.libs.pari x Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8, float64 - sage: algdep(float64(1.888888888888888), int8(1)) + sage: from numpy import int8, float64 # optional - numpy + sage: algdep(float64(1.888888888888888), int8(1)) # optional - numpy sage.libs.pari 9*x - 17 sage: from gmpy2 import mpz, mpfr - sage: algdep(mpfr(1.888888888888888), mpz(1)) + sage: algdep(mpfr(1.888888888888888), mpz(1)) # optional - sage.libs.pari 9*x - 17 """ if proof and not height_bound: @@ -303,47 +302,54 @@ def bernoulli(n, algorithm='default', num_threads=1): EXAMPLES:: - sage: bernoulli(12) + sage: bernoulli(12) # optional - sage.libs.flint -691/2730 - sage: bernoulli(50) + sage: bernoulli(50) # optional - sage.libs.flint 495057205241079648212477525/66 We demonstrate each of the alternative algorithms:: - sage: bernoulli(12, algorithm='arb') + sage: bernoulli(12, algorithm='arb') # optional - sage.libs.flint -691/2730 - sage: bernoulli(12, algorithm='flint') + sage: bernoulli(12, algorithm='flint') # optional - sage.libs.flint -691/2730 - sage: bernoulli(12, algorithm='gap') + sage: bernoulli(12, algorithm='gap') # optional - sage.libs.gap -691/2730 - sage: bernoulli(12, algorithm='gp') + sage: bernoulli(12, algorithm='gp') # optional - sage.libs.pari -691/2730 sage: bernoulli(12, algorithm='magma') # optional - magma -691/2730 - sage: bernoulli(12, algorithm='pari') + sage: bernoulli(12, algorithm='pari') # optional - sage.libs.pari -691/2730 - sage: bernoulli(12, algorithm='bernmm') + sage: bernoulli(12, algorithm='bernmm') # optional - sage.libs.ntl -691/2730 - sage: bernoulli(12, algorithm='bernmm', num_threads=4) + sage: bernoulli(12, algorithm='bernmm', num_threads=4) # optional - sage.libs.ntl -691/2730 TESTS:: - sage: algs = ['arb', 'gap', 'gp', 'pari', 'bernmm', 'flint'] + sage: algs = [] + sage: algs += ['arb'] # optional - sage.libs.flint + sage: algs += ['gap'] # optional - sage.libs.gap + sage: algs += ['gp', 'pari'] # optional - sage.libs.pari + sage: algs += ['bernmm'] # optional - sage.libs.ntl + sage: algs += ['flint'] # optional - sage.libs.flint sage: test_list = [ZZ.random_element(2, 2255) for _ in range(500)] sage: vals = [[bernoulli(i, algorithm=j) for j in algs] for i in test_list] # long time (up to 21s on sage.math, 2011) - sage: all(len(set(x))==1 for x in vals) # long time (depends on previous line) + sage: all(len(set(x)) == 1 for x in vals) # long time (depends on previous line) True - sage: algs = ['gp', 'pari', 'bernmm'] + sage: algs = [] + sage: algs += ['gp', 'pari'] # optional - sage.libs.pari + sage: algs += ['bernmm'] # optional - sage.libs.ntl sage: test_list = [ZZ.random_element(2256, 5000) for _ in range(500)] sage: vals = [[bernoulli(i, algorithm=j) for j in algs] for i in test_list] # long time (up to 30s on sage.math, 2011) sage: all(len(set(x))==1 for x in vals) # long time (depends on previous line) True - sage: from numpy import int8 - sage: bernoulli(int8(12)) + sage: from numpy import int8 # optional - numpy + sage: bernoulli(int8(12)) # optional - numpy sage.libs.flint -691/2730 sage: from gmpy2 import mpz - sage: bernoulli(mpz(12)) + sage: bernoulli(mpz(12)) # optional - sage.libs.flint -691/2730 AUTHOR: @@ -433,8 +439,8 @@ def factorial(n, algorithm='gmp'): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: factorial(int8(4)) + sage: from numpy import int8 # optional - numpy + sage: factorial(int8(4)) # optional - numpy 24 sage: from gmpy2 import mpz sage: factorial(mpz(4)) @@ -519,7 +525,7 @@ def is_prime(n): sage: a = 2**2048 + 981 sage: is_prime(a) # not tested - takes ~ 1min sage: proof.arithmetic(False) - sage: is_prime(a) # instantaneous! + sage: is_prime(a) # instantaneous! # optional - sage.libs.pari True sage: proof.arithmetic(True) @@ -543,8 +549,9 @@ def is_prime(n): However, number fields redefine ``.is_prime()`` in an incompatible fashion (cf. :trac:`32340`) and we should not warn:: - sage: K. = NumberField(x^2+1) - sage: is_prime(1+i) + sage: x = polygen(ZZ, 'x') + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: is_prime(1 + i) # optional - sage.rings.number_field True """ try: @@ -585,19 +592,19 @@ def is_pseudoprime(n): EXAMPLES:: - sage: is_pseudoprime(389) + sage: is_pseudoprime(389) # optional - sage.libs.pari True - sage: is_pseudoprime(2000) + sage: is_pseudoprime(2000) # optional - sage.libs.pari False - sage: is_pseudoprime(2) + sage: is_pseudoprime(2) # optional - sage.libs.pari True - sage: is_pseudoprime(-1) + sage: is_pseudoprime(-1) # optional - sage.libs.pari False sage: factor(-6) -1 * 2 * 3 - sage: is_pseudoprime(1) + sage: is_pseudoprime(1) # optional - sage.libs.pari False - sage: is_pseudoprime(-2) + sage: is_pseudoprime(-2) # optional - sage.libs.pari False """ return ZZ(n).is_pseudoprime() @@ -620,51 +627,51 @@ def is_prime_power(n, get_data=False): EXAMPLES:: - sage: is_prime_power(389) + sage: is_prime_power(389) # optional - sage.libs.pari True - sage: is_prime_power(2000) + sage: is_prime_power(2000) # optional - sage.libs.pari False - sage: is_prime_power(2) + sage: is_prime_power(2) # optional - sage.libs.pari True - sage: is_prime_power(1024) + sage: is_prime_power(1024) # optional - sage.libs.pari True - sage: is_prime_power(1024, get_data=True) + sage: is_prime_power(1024, get_data=True) # optional - sage.libs.pari (2, 10) The same results can be obtained with:: - sage: 389.is_prime_power() + sage: 389.is_prime_power() # optional - sage.libs.pari True - sage: 2000.is_prime_power() + sage: 2000.is_prime_power() # optional - sage.libs.pari False - sage: 2.is_prime_power() + sage: 2.is_prime_power() # optional - sage.libs.pari True - sage: 1024.is_prime_power() + sage: 1024.is_prime_power() # optional - sage.libs.pari True - sage: 1024.is_prime_power(get_data=True) + sage: 1024.is_prime_power(get_data=True) # optional - sage.libs.pari (2, 10) TESTS:: - sage: is_prime_power(-1) + sage: is_prime_power(-1) # optional - sage.libs.pari False - sage: is_prime_power(1) + sage: is_prime_power(1) # optional - sage.libs.pari False - sage: is_prime_power(QQ(997^100)) + sage: is_prime_power(QQ(997^100)) # optional - sage.libs.pari True - sage: is_prime_power(1/2197) + sage: is_prime_power(1/2197) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: no conversion of this rational to integer - sage: is_prime_power("foo") + sage: is_prime_power("foo") # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: unable to convert 'foo' to an integer sage: from gmpy2 import mpz - sage: is_prime_power(mpz(389)) + sage: is_prime_power(mpz(389)) # optional - sage.libs.pari True - sage: from numpy import int16 - sage: is_prime_power(int16(389)) + sage: from numpy import int16 # optional - numpy + sage: is_prime_power(int16(389)) # optional - numpy sage.libs.pari True """ return ZZ(n).is_prime_power(get_data=get_data) @@ -687,39 +694,39 @@ def is_pseudoprime_power(n, get_data=False): EXAMPLES:: - sage: is_pseudoprime_power(389) + sage: is_pseudoprime_power(389) # optional - sage.libs.pari True - sage: is_pseudoprime_power(2000) + sage: is_pseudoprime_power(2000) # optional - sage.libs.pari False - sage: is_pseudoprime_power(2) + sage: is_pseudoprime_power(2) # optional - sage.libs.pari True - sage: is_pseudoprime_power(1024) + sage: is_pseudoprime_power(1024) # optional - sage.libs.pari True - sage: is_pseudoprime_power(-1) + sage: is_pseudoprime_power(-1) # optional - sage.libs.pari False - sage: is_pseudoprime_power(1) + sage: is_pseudoprime_power(1) # optional - sage.libs.pari False - sage: is_pseudoprime_power(997^100) + sage: is_pseudoprime_power(997^100) # optional - sage.libs.pari True Use of the get_data keyword:: - sage: is_pseudoprime_power(3^1024, get_data=True) + sage: is_pseudoprime_power(3^1024, get_data=True) # optional - sage.libs.pari (3, 1024) - sage: is_pseudoprime_power(2^256, get_data=True) + sage: is_pseudoprime_power(2^256, get_data=True) # optional - sage.libs.pari (2, 256) - sage: is_pseudoprime_power(31, get_data=True) + sage: is_pseudoprime_power(31, get_data=True) # optional - sage.libs.pari (31, 1) - sage: is_pseudoprime_power(15, get_data=True) + sage: is_pseudoprime_power(15, get_data=True) # optional - sage.libs.pari (15, 0) Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: is_pseudoprime_power(int16(1024)) + sage: from numpy import int16 # optional - numpy + sage: is_pseudoprime_power(int16(1024)) # optional - numpy sage.libs.pari True sage: from gmpy2 import mpz - sage: is_pseudoprime_power(mpz(1024)) + sage: is_pseudoprime_power(mpz(1024)) # optional - sage.libs.pari True """ return ZZ(n).is_prime_power(proof=False, get_data=get_data) @@ -783,8 +790,8 @@ def valuation(m, *args, **kwds): Traceback (most recent call last): ... ValueError: You can only compute the valuation with respect to a integer larger than 1. - sage: from numpy import int16 - sage: valuation(int16(512), int16(2)) + sage: from numpy import int16 # optional - numpy + sage: valuation(int16(512), int16(2)) # optional - numpy 9 sage: from gmpy2 import mpz sage: valuation(mpz(512), mpz(2)) @@ -821,49 +828,49 @@ def prime_powers(start, stop=None): EXAMPLES:: - sage: prime_powers(20) + sage: prime_powers(20) # optional - sage.libs.pari [2, 3, 4, 5, 7, 8, 9, 11, 13, 16, 17, 19] - sage: len(prime_powers(1000)) + sage: len(prime_powers(1000)) # optional - sage.libs.pari 193 - sage: len(prime_range(1000)) + sage: len(prime_range(1000)) # optional - sage.libs.pari 168 - sage: a = [z for z in range(95,1234) if is_prime_power(z)] - sage: b = prime_powers(95,1234) - sage: len(b) + sage: a = [z for z in range(95, 1234) if is_prime_power(z)] # optional - sage.libs.pari + sage: b = prime_powers(95, 1234) # optional - sage.libs.pari + sage: len(b) # optional - sage.libs.pari 194 - sage: len(a) + sage: len(a) # optional - sage.libs.pari 194 - sage: a[:10] + sage: a[:10] # optional - sage.libs.pari [97, 101, 103, 107, 109, 113, 121, 125, 127, 128] - sage: b[:10] + sage: b[:10] # optional - sage.libs.pari [97, 101, 103, 107, 109, 113, 121, 125, 127, 128] - sage: a == b + sage: a == b # optional - sage.libs.pari True - sage: prime_powers(100) == [i for i in range(100) if is_prime_power(i)] + sage: prime_powers(100) == [i for i in range(100) if is_prime_power(i)] # optional - sage.libs.pari True - sage: prime_powers(10,7) + sage: prime_powers(10, 7) # optional - sage.libs.pari [] - sage: prime_powers(-5) + sage: prime_powers(-5) # optional - sage.libs.pari [] - sage: prime_powers(-1,3) + sage: prime_powers(-1, 3) # optional - sage.libs.pari [2] TESTS: Check that output are always Sage integers (:trac:`922`):: - sage: v = prime_powers(10) - sage: type(v[0]) + sage: v = prime_powers(10) # optional - sage.libs.pari + sage: type(v[0]) # optional - sage.libs.pari - sage: prime_powers(0,1) + sage: prime_powers(0, 1) # optional - sage.libs.pari [] - sage: prime_powers(2) + sage: prime_powers(2) # optional - sage.libs.pari [] - sage: prime_powers(3) + sage: prime_powers(3) # optional - sage.libs.pari [2] sage: prime_powers("foo") @@ -878,18 +885,18 @@ def prime_powers(start, stop=None): Check that long input are accepted (:trac:`17852`):: - sage: prime_powers(6l) + sage: prime_powers(6l) # optional - sage.libs.pari [2, 3, 4, 5] - sage: prime_powers(6l,10l) + sage: prime_powers(6l, 10l) # optional - sage.libs.pari [7, 8, 9] Check numpy and gmpy2 support:: - sage: from numpy import int8 - sage: prime_powers(int8(20)) + sage: from numpy import int8 # optional - numpy + sage: prime_powers(int8(20)) # optional - numpy sage.libs.pari [2, 3, 4, 5, 7, 8, 9, 11, 13, 16, 17, 19] sage: from gmpy2 import mpz - sage: prime_powers(mpz(20)) + sage: prime_powers(mpz(20)) # optional - sage.libs.pari [2, 3, 4, 5, 7, 8, 9, 11, 13, 16, 17, 19] """ start = ZZ(start) @@ -931,11 +938,11 @@ def primes_first_n(n, leave_pari=False): EXAMPLES:: - sage: primes_first_n(10) + sage: primes_first_n(10) # optional - sage.libs.pari [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] - sage: len(primes_first_n(1000)) + sage: len(primes_first_n(1000)) # optional - sage.libs.pari 1000 - sage: primes_first_n(0) + sage: primes_first_n(0) # optional - sage.libs.pari [] """ if n < 0: @@ -973,13 +980,13 @@ def eratosthenes(n): [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47] sage: len(eratosthenes(100)) 25 - sage: eratosthenes(213) == prime_range(213) + sage: eratosthenes(213) == prime_range(213) # optional - sage.libs.pari True TESTS:: - sage: from numpy import int8 - sage: eratosthenes(int8(3)) + sage: from numpy import int8 # optional - numpy + sage: eratosthenes(int8(3)) # optional - numpy [2, 3] sage: from gmpy2 import mpz sage: eratosthenes(mpz(3)) @@ -1046,41 +1053,41 @@ def primes(start=2, stop=None, proof=None): EXAMPLES:: - sage: for p in primes(5,10): + sage: for p in primes(5, 10): # optional - sage.libs.pari ....: print(p) 5 7 - sage: list(primes(13)) + sage: list(primes(13)) # optional - sage.libs.pari [2, 3, 5, 7, 11] - sage: list(primes(10000000000, 10000000100)) + sage: list(primes(10000000000, 10000000100)) # optional - sage.libs.pari [10000000019, 10000000033, 10000000061, 10000000069, 10000000097] - sage: max(primes(10^100, 10^100+10^4, proof=False)) + sage: max(primes(10^100, 10^100+10^4, proof=False)) # optional - sage.libs.pari 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009631 - sage: next(p for p in primes(10^20, infinity) if is_prime(2*p+1)) + sage: next(p for p in primes(10^20, infinity) if is_prime(2*p+1)) # optional - sage.libs.pari 100000000000000001243 TESTS:: - sage: for a in range(-10, 50): + sage: for a in range(-10, 50): # optional - sage.libs.pari ....: for b in range(-10, 50): ....: assert list(primes(a,b)) == list(filter(is_prime, range(a,b))) - sage: sum(primes(-10, 9973, proof=False)) == sum(filter(is_prime, range(-10, 9973))) + sage: sum(primes(-10, 9973, proof=False)) == sum(filter(is_prime, range(-10, 9973))) # optional - sage.libs.pari True - sage: for p in primes(10, infinity): + sage: for p in primes(10, infinity): # optional - sage.libs.pari ....: if p > 20: break ....: print(p) 11 13 17 19 - sage: next(p for p in primes(10,oo)) # checks alternate infinity notation + sage: next(p for p in primes(10,oo)) # checks alternate infinity notation # optional - sage.libs.pari 11 - sage: from numpy import int8 - sage: list(primes(int8(13))) + sage: from numpy import int8 # optional - numpy + sage: list(primes(int8(13))) # optional - numpy sage.libs.pari [2, 3, 5, 7, 11] sage: from gmpy2 import mpz - sage: list(primes(mpz(13))) + sage: list(primes(mpz(13))) # optional - sage.libs.pari [2, 3, 5, 7, 11] """ from sage.rings.infinity import infinity @@ -1120,40 +1127,40 @@ def next_prime_power(n): EXAMPLES:: - sage: next_prime_power(1) + sage: next_prime_power(1) # optional - sage.libs.pari 2 - sage: next_prime_power(2) + sage: next_prime_power(2) # optional - sage.libs.pari 3 - sage: next_prime_power(10) + sage: next_prime_power(10) # optional - sage.libs.pari 11 - sage: next_prime_power(7) + sage: next_prime_power(7) # optional - sage.libs.pari 8 - sage: next_prime_power(99) + sage: next_prime_power(99) # optional - sage.libs.pari 101 The same results can be obtained with:: - sage: 1.next_prime_power() + sage: 1.next_prime_power() # optional - sage.libs.pari 2 - sage: 2.next_prime_power() + sage: 2.next_prime_power() # optional - sage.libs.pari 3 - sage: 10.next_prime_power() + sage: 10.next_prime_power() # optional - sage.libs.pari 11 Note that `2` is the smallest prime power:: - sage: next_prime_power(-10) + sage: next_prime_power(-10) # optional - sage.libs.pari 2 - sage: next_prime_power(0) + sage: next_prime_power(0) # optional - sage.libs.pari 2 TESTS:: - sage: from numpy import int8 - sage: next_prime_power(int8(10)) + sage: from numpy import int8 # optional - numpy + sage: next_prime_power(int8(10)) # optional - numpy sage.libs.pari 11 sage: from gmpy2 import mpz - sage: next_prime_power(mpz(10)) + sage: next_prime_power(mpz(10)) # optional - sage.libs.pari 11 """ return ZZ(n).next_prime_power() @@ -1171,22 +1178,22 @@ def next_probable_prime(n): EXAMPLES:: - sage: next_probable_prime(-100) + sage: next_probable_prime(-100) # optional - sage.libs.pari 2 - sage: next_probable_prime(19) + sage: next_probable_prime(19) # optional - sage.libs.pari 23 - sage: next_probable_prime(int(999999999)) + sage: next_probable_prime(int(999999999)) # optional - sage.libs.pari 1000000007 - sage: next_probable_prime(2^768) + sage: next_probable_prime(2^768) # optional - sage.libs.pari 1552518092300708935148979488462502555256886017116696611139052038026050952686376886330878408828646477950487730697131073206171580044114814391444287275041181139204454976020849905550265285631598444825262999193716468750892846853816058039 TESTS:: - sage: from numpy import int8 - sage: next_probable_prime(int8(19)) + sage: from numpy import int8 # optional - numpy + sage: next_probable_prime(int8(19)) # optional - numpy sage.libs.pari 23 sage: from gmpy2 import mpz - sage: next_probable_prime(mpz(19)) + sage: next_probable_prime(mpz(19)) # optional - sage.libs.pari 23 """ return ZZ(n).next_probable_prime() @@ -1210,33 +1217,33 @@ def next_prime(n, proof=None): EXAMPLES:: - sage: next_prime(-100) + sage: next_prime(-100) # optional - sage.libs.pari 2 - sage: next_prime(1) + sage: next_prime(1) # optional - sage.libs.pari 2 - sage: next_prime(2) + sage: next_prime(2) # optional - sage.libs.pari 3 - sage: next_prime(3) + sage: next_prime(3) # optional - sage.libs.pari 5 - sage: next_prime(4) + sage: next_prime(4) # optional - sage.libs.pari 5 Notice that the next_prime(5) is not 5 but 7. :: - sage: next_prime(5) + sage: next_prime(5) # optional - sage.libs.pari 7 - sage: next_prime(2004) + sage: next_prime(2004) # optional - sage.libs.pari 2011 TESTS:: - sage: from numpy import int8 - sage: next_prime(int8(3)) + sage: from numpy import int8 # optional - numpy + sage: next_prime(int8(3)) # optional - numpy sage.libs.pari 5 sage: from gmpy2 import mpz - sage: next_probable_prime(mpz(3)) + sage: next_probable_prime(mpz(3)) # optional - sage.libs.pari 5 """ return ZZ(n).next_prime(proof) @@ -1249,38 +1256,38 @@ def previous_prime(n): EXAMPLES:: - sage: previous_prime(10) + sage: previous_prime(10) # optional - sage.libs.pari 7 - sage: previous_prime(7) + sage: previous_prime(7) # optional - sage.libs.pari 5 - sage: previous_prime(8) + sage: previous_prime(8) # optional - sage.libs.pari 7 - sage: previous_prime(7) + sage: previous_prime(7) # optional - sage.libs.pari 5 - sage: previous_prime(5) + sage: previous_prime(5) # optional - sage.libs.pari 3 - sage: previous_prime(3) + sage: previous_prime(3) # optional - sage.libs.pari 2 - sage: previous_prime(2) + sage: previous_prime(2) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no previous prime - sage: previous_prime(1) + sage: previous_prime(1) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no previous prime - sage: previous_prime(-20) + sage: previous_prime(-20) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no previous prime TESTS:: - sage: from numpy import int8 - sage: previous_prime(int8(7)) + sage: from numpy import int8 # optional - numpy + sage: previous_prime(int8(7)) # optional - numpy sage.libs.pari 5 sage: from gmpy2 import mpz - sage: previous_prime(mpz(7)) + sage: previous_prime(mpz(7)) # optional - sage.libs.pari 5 """ n = ZZ(n) - 1 @@ -1315,52 +1322,52 @@ def previous_prime_power(n): EXAMPLES:: - sage: previous_prime_power(3) + sage: previous_prime_power(3) # optional - sage.libs.pari 2 - sage: previous_prime_power(10) + sage: previous_prime_power(10) # optional - sage.libs.pari 9 - sage: previous_prime_power(7) + sage: previous_prime_power(7) # optional - sage.libs.pari 5 - sage: previous_prime_power(127) + sage: previous_prime_power(127) # optional - sage.libs.pari 125 The same results can be obtained with:: - sage: 3.previous_prime_power() + sage: 3.previous_prime_power() # optional - sage.libs.pari 2 - sage: 10.previous_prime_power() + sage: 10.previous_prime_power() # optional - sage.libs.pari 9 - sage: 7.previous_prime_power() + sage: 7.previous_prime_power() # optional - sage.libs.pari 5 - sage: 127.previous_prime_power() + sage: 127.previous_prime_power() # optional - sage.libs.pari 125 Input less than or equal to `2` raises errors:: - sage: previous_prime_power(2) + sage: previous_prime_power(2) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no prime power less than 2 - sage: previous_prime_power(-10) + sage: previous_prime_power(-10) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no prime power less than 2 :: - sage: n = previous_prime_power(2^16 - 1) - sage: while is_prime(n): + sage: n = previous_prime_power(2^16 - 1) # optional - sage.libs.pari + sage: while is_prime(n): # optional - sage.libs.pari ....: n = previous_prime_power(n) - sage: factor(n) + sage: factor(n) # optional - sage.libs.pari 251^2 TESTS:: - sage: from numpy import int8 - sage: previous_prime_power(int8(10)) + sage: from numpy import int8 # optional - numpy + sage: previous_prime_power(int8(10)) # optional - numpy sage.libs.pari 9 sage: from gmpy2 import mpz - sage: previous_prime_power(mpz(10)) + sage: previous_prime_power(mpz(10)) # optional - sage.libs.pari 9 """ return ZZ(n).previous_prime_power() @@ -1388,42 +1395,42 @@ def random_prime(n, proof=None, lbound=2): EXAMPLES:: - sage: p = random_prime(100000) - sage: p.is_prime() + sage: p = random_prime(100000) # optional - sage.libs.pari + sage: p.is_prime() # optional - sage.libs.pari True - sage: p <= 100000 + sage: p <= 100000 # optional - sage.libs.pari True - sage: random_prime(2) + sage: random_prime(2) # optional - sage.libs.pari 2 Here we generate a random prime between 100 and 200:: - sage: p = random_prime(200, lbound=100) - sage: p.is_prime() + sage: p = random_prime(200, lbound=100) # optional - sage.libs.pari + sage: p.is_prime() # optional - sage.libs.pari True - sage: 100 <= p <= 200 + sage: 100 <= p <= 200 # optional - sage.libs.pari True If all we care about is finding a pseudo prime, then we can pass in ``proof=False`` :: - sage: p = random_prime(200, proof=False, lbound=100) - sage: p.is_pseudoprime() + sage: p = random_prime(200, proof=False, lbound=100) # optional - sage.libs.pari + sage: p.is_pseudoprime() # optional - sage.libs.pari True - sage: 100 <= p <= 200 + sage: 100 <= p <= 200 # optional - sage.libs.pari True TESTS:: - sage: type(random_prime(2)) + sage: type(random_prime(2)) # optional - sage.libs.pari - sage: type(random_prime(100)) + sage: type(random_prime(100)) # optional - sage.libs.pari - sage: random_prime(1, lbound=-2) #caused Sage hang #10112 + sage: random_prime(1, lbound=-2) #caused Sage hang #10112 # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: n must be greater than or equal to 2 - sage: random_prime(126, lbound=114) + sage: random_prime(126, lbound=114) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: there are no primes between 114 and 126 (inclusive) @@ -1515,22 +1522,22 @@ def divisors(n): This function works whenever one has unique factorization:: - sage: K. = QuadraticField(7) - sage: divisors(K.ideal(7)) + sage: K. = QuadraticField(7) # optional - sage.rings.number_field + sage: divisors(K.ideal(7)) # optional - sage.rings.number_field [Fractional ideal (1), Fractional ideal (a), Fractional ideal (7)] - sage: divisors(K.ideal(3)) + sage: divisors(K.ideal(3)) # optional - sage.rings.number_field [Fractional ideal (1), Fractional ideal (3), - Fractional ideal (a - 2), Fractional ideal (a + 2)] - sage: divisors(K.ideal(35)) + Fractional ideal (a - 2), Fractional ideal (a + 2)] + sage: divisors(K.ideal(35)) # optional - sage.rings.number_field [Fractional ideal (1), Fractional ideal (5), Fractional ideal (a), - Fractional ideal (7), Fractional ideal (5*a), Fractional ideal (35)] + Fractional ideal (7), Fractional ideal (5*a), Fractional ideal (35)] TESTS:: sage: divisors(int(300)) [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 25, 30, 50, 60, 75, 100, 150, 300] - sage: import numpy - sage: divisors(numpy.int8(100)) + sage: import numpy # optional - numpy + sage: divisors(numpy.int8(100)) # optional - numpy [1, 2, 4, 5, 10, 20, 25, 50, 100] sage: import gmpy2 sage: divisors(gmpy2.mpz(100)) @@ -1592,13 +1599,13 @@ class Sigma: :: - sage: P = plot(sigma, 1, 100) + sage: P = plot(sigma, 1, 100) # optional - sage.plot This method also works with k-th powers. :: - sage: P = plot(sigma, 1, 100, k=2) + sage: P = plot(sigma, 1, 100, k=2) # optional - sage.plot AUTHORS: @@ -1610,21 +1617,21 @@ class Sigma: sage: sigma(100,4) 106811523 - sage: sigma(factorial(100),3).mod(144169) + sage: sigma(factorial(100), 3).mod(144169) # optional - sage.libs.pari 3672 - sage: sigma(factorial(150),12).mod(691) + sage: sigma(factorial(150), 12).mod(691) # optional - sage.libs.pari 176 - sage: RR(sigma(factorial(133),20)) + sage: RR(sigma(factorial(133),20)) # optional - sage.libs.pari 2.80414775675747e4523 - sage: sigma(factorial(100),0) + sage: sigma(factorial(100),0) # optional - sage.libs.pari 39001250856960000 - sage: sigma(factorial(41),1) + sage: sigma(factorial(41),1) # optional - sage.libs.pari 229199532273029988767733858700732906511758707916800 - sage: from numpy import int8 - sage: sigma(int8(100),int8(4)) + sage: from numpy import int8 # optional - numpy + sage: sigma(int8(100), int8(4)) # optional - numpy sage.libs.pari 106811523 sage: from gmpy2 import mpz - sage: sigma(mpz(100),mpz(4)) + sage: sigma(mpz(100), mpz(4)) # optional - sage.libs.pari 106811523 """ def __repr__(self): @@ -1648,9 +1655,9 @@ def __call__(self, n, k=1): sage: from sage.arith.misc import Sigma sage: q = Sigma() - sage: q(10) + sage: q(10) # optional - sage.libs.pari 18 - sage: q(10,2) + sage: q(10,2) # optional - sage.libs.pari 130 """ n = ZZ(n) @@ -1692,8 +1699,8 @@ def plot(self, xmin=1, xmax=50, k=1, pointsize=30, rgbcolor=(0,0,1), join=True, EXAMPLES:: sage: from sage.arith.misc import Sigma - sage: p = Sigma().plot() - sage: p.ymax() + sage: p = Sigma().plot() # optional - sage.libs.pari sage.plot + sage: p.ymax() # optional - sage.libs.pari sage.plot 124.0 """ v = [(n, sigma(n, k)) for n in range(xmin, xmax + 1)] @@ -1783,33 +1790,33 @@ def gcd(a, b=None, **kwargs): Make sure we try QQ and not merely ZZ (:trac:`13014`):: - sage: bool(gcd(2/5, 3/7) == gcd(SR(2/5), SR(3/7))) + sage: bool(gcd(2/5, 3/7) == gcd(SR(2/5), SR(3/7))) # optional - sage.symbolic True Make sure that the gcd of Expressions stays symbolic:: sage: parent(gcd(2, 4)) Integer Ring - sage: parent(gcd(SR(2), 4)) + sage: parent(gcd(SR(2), 4)) # optional - sage.symbolic Symbolic Ring - sage: parent(gcd(2, SR(4))) + sage: parent(gcd(2, SR(4))) # optional - sage.symbolic Symbolic Ring - sage: parent(gcd(SR(2), SR(4))) + sage: parent(gcd(SR(2), SR(4))) # optional - sage.symbolic Symbolic Ring Verify that objects without gcd methods but which cannot be coerced to ZZ or QQ raise an error:: - sage: F. = FreeMonoid(2) - sage: gcd(a,b) + sage: F. = FreeMonoid(2) # optional - sage.groups + sage: gcd(a, b) # optional - sage.groups Traceback (most recent call last): ... TypeError: unable to call gcd with a Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: GCD(int8(97),int8(100)) + sage: from numpy import int8 # optional - numpy + sage: GCD(int8(97), int8(100)) # optional - numpy 1 sage: from gmpy2 import mpq, mpz sage: GCD(mpq(2/3), mpq(4/5)) @@ -1908,8 +1915,8 @@ def xlcm(m, n): TESTS:: - sage: from numpy import int16 - sage: xlcm(int16(120), int16(36)) + sage: from numpy import int16 # optional - numpy + sage: xlcm(int16(120), int16(36)) # optional - numpy (360, 40, 9) sage: from gmpy2 import mpz sage: xlcm(mpz(120), mpz(36)) @@ -1974,15 +1981,15 @@ def xgcd(a, b): sage: xgcd(x^3 - 1, x^2 - 1) (x - 1, 1, -x) - sage: K. = NumberField(x^2-3) - sage: g.xgcd(g+2) + sage: K. = NumberField(x^2 - 3) # optional - sage.rings.number_field + sage: g.xgcd(g + 2) # optional - sage.rings.number_field (1, 1/3*g, 0) - sage: R. = K[] - sage: S. = R.fraction_field()[] - sage: xgcd(y^2, a*y+b) + sage: R. = K[] # optional - sage.rings.number_field + sage: S. = R.fraction_field()[] # optional - sage.rings.number_field + sage: xgcd(y^2, a*y + b) # optional - sage.rings.number_field (1, a^2/b^2, ((-a)/b^2)*y + 1/b) - sage: xgcd((b+g)*y^2, (a+g)*y+b) + sage: xgcd((b+g)*y^2, (a+g)*y + b) # optional - sage.rings.number_field (1, (a^2 + (2*g)*a + 3)/(b^3 + g*b^2), ((-a + (-g))/b^2)*y + 1/b) Here is an example of a xgcd for two polynomials over the integers, where the linear @@ -1998,10 +2005,10 @@ def xgcd(a, b): Tests with numpy and gmpy2 types:: - sage: from numpy import int8 - sage: xgcd(4,int8(8)) + sage: from numpy import int8 # optional - numpy + sage: xgcd(4, int8(8)) # optional - numpy (4, 1, 0) - sage: xgcd(int8(4),int8(8)) + sage: xgcd(int8(4), int8(8)) # optional - numpy (4, 1, 0) sage: from gmpy2 import mpz sage: xgcd(mpz(4), mpz(8)) @@ -2013,10 +2020,10 @@ def xgcd(a, b): We check that :trac:`3330` has been fixed:: - sage: R. = NumberField(x^2-3,'g').extension(x^2-7,'h')[] - sage: h = R.base_ring().gen() - sage: S. = R.fraction_field()[] - sage: xgcd(y^2, a*h*y+b) + sage: R. = NumberField(x^2 - 3, 'g').extension(x^2 - 7, 'h')[] # optional - sage.rings.number_field + sage: h = R.base_ring().gen() # optional - sage.rings.number_field + sage: S. = R.fraction_field()[] # optional - sage.rings.number_field + sage: xgcd(y^2, a*h*y + b) # optional - sage.rings.number_field (1, 7*a^2/b^2, (((-h)*a)/b^2)*y + 1/b) """ try: @@ -2131,20 +2138,20 @@ def inverse_mod(a, m): :: - sage: inverse_mod(7,1) + sage: inverse_mod(7, 1) 0 - sage: inverse_mod(5,14) + sage: inverse_mod(5, 14) 3 - sage: inverse_mod(3,-5) + sage: inverse_mod(3, -5) 2 Tests with numpy and mpz numbers:: - sage: from numpy import int8 - sage: inverse_mod(int8(5),int8(14)) + sage: from numpy import int8 # optional - numpy + sage: inverse_mod(int8(5), int8(14)) # optional - numpy 3 sage: from gmpy2 import mpz - sage: inverse_mod(mpz(5),mpz(14)) + sage: inverse_mod(mpz(5), mpz(14)) 3 """ try: @@ -2221,13 +2228,13 @@ def power_mod(a, n, m): EXAMPLES:: - sage: power_mod(2,388,389) + sage: power_mod(2, 388, 389) 1 - sage: power_mod(2,390,391) + sage: power_mod(2, 390, 391) 285 - sage: power_mod(2,-1,7) + sage: power_mod(2, -1, 7) 4 - sage: power_mod(11,1,7) + sage: power_mod(11, 1, 7) 4 This function works for fairly general rings:: @@ -2235,7 +2242,7 @@ def power_mod(a, n, m): sage: R. = ZZ[] sage: power_mod(3*x, 10, 7) 4*x^10 - sage: power_mod(-3*x^2+4, 7, 2*x^3-5) + sage: power_mod(-3*x^2 + 4, 7, 2*x^3 - 5) x^14 + x^8 + x^6 + x^3 + 962509*x^2 - 791910*x - 698281 TESTS:: @@ -2249,11 +2256,11 @@ def power_mod(a, n, m): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int32 - sage: power_mod(int32(2),int32(390),int32(391)) + sage: from numpy import int32 # optional - numpy + sage: power_mod(int32(2), int32(390), int32(391)) # optional - numpy 285 sage: from gmpy2 import mpz - sage: power_mod(mpz(2),mpz(390),mpz(391)) + sage: power_mod(mpz(2), mpz(390), mpz(391)) mpz(285) """ if not m: @@ -2372,8 +2379,8 @@ def rational_reconstruction(a, m, algorithm='fast'): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int32 - sage: rational_reconstruction(int32(3), int32(292393)) + sage: from numpy import int32 # optional - numpy + sage: rational_reconstruction(int32(3), int32(292393)) # optional - numpy 3 sage: from gmpy2 import mpz sage: rational_reconstruction(mpz(3), mpz(292393)) @@ -2407,16 +2414,16 @@ def mqrr_rational_reconstruction(u, m, T): EXAMPLES:: - sage: mqrr_rational_reconstruction(21,3100,13) + sage: mqrr_rational_reconstruction(21, 3100, 13) (21, 1) Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: mqrr_rational_reconstruction(int16(21),int16(3100),int16(13)) + sage: from numpy import int16 # optional - numpy + sage: mqrr_rational_reconstruction(int16(21), int16(3100), int16(13)) # optional - numpy (21, 1) sage: from gmpy2 import mpz - sage: mqrr_rational_reconstruction(mpz(21),mpz(3100),mpz(13)) + sage: mqrr_rational_reconstruction(mpz(21), mpz(3100), mpz(13)) (21, 1) """ u = py_scalar_to_element(u) @@ -2480,8 +2487,8 @@ def trial_division(n, bound=None): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: trial_division(int8(91)) + sage: from numpy import int8 # optional - numpy + sage: trial_division(int8(91)) # optional - numpy 7 sage: from gmpy2 import mpz sage: trial_division(mpz(91)) @@ -2512,10 +2519,10 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): EXAMPLES:: - sage: f(n)=n^2 - sage: is_prime(f(3)) + sage: f(n) = n^2 # optional - sage.symbolic + sage: is_prime(f(3)) # optional - sage.symbolic False - sage: factor(f(3)) + sage: factor(f(3)) # optional - sage.symbolic 9 INPUT: @@ -2578,7 +2585,7 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): -1 sage: f.value() -20 - sage: factor( -next_prime(10^2) * next_prime(10^7) ) + sage: factor(-next_prime(10^2) * next_prime(10^7)) # optional - sage.libs.pari -1 * 101 * 10000019 :: @@ -2606,7 +2613,7 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): 1 sage: factor(-1) -1 - sage: factor(2^(2^7)+1) + sage: factor(2^(2^7) +1) # optional - sage.libs.pari 59649589127497217 * 5704689200685129054721 Sage calls PARI's factor, which has proof False by default. @@ -2616,42 +2623,42 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): :: - sage: factor(3^89-1, proof=False) + sage: factor(3^89 - 1, proof=False) # optional - sage.libs.pari 2 * 179 * 1611479891519807 * 5042939439565996049162197 :: - sage: factor(2^197 + 1) # long time (2s) + sage: factor(2^197 + 1) # long time (2s) # optional - sage.libs.pari 3 * 197002597249 * 1348959352853811313 * 251951573867253012259144010843 Any object which has a factor method can be factored like this:: - sage: K. = QuadraticField(-1) - sage: factor(122 - 454*i) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: factor(122 - 454*i) # optional - sage.rings.number_field (-i) * (-i - 2)^3 * (i + 1)^3 * (-2*i + 3) * (i + 4) To access the data in a factorization:: - sage: f = factor(420); f + sage: f = factor(420); f # optional - sage.libs.pari 2^2 * 3 * 5 * 7 - sage: [x for x in f] + sage: [x for x in f] # optional - sage.libs.pari [(2, 2), (3, 1), (5, 1), (7, 1)] - sage: [p for p,e in f] + sage: [p for p,e in f] # optional - sage.libs.pari [2, 3, 5, 7] - sage: [e for p,e in f] + sage: [e for p,e in f] # optional - sage.libs.pari [2, 1, 1, 1] - sage: [p^e for p,e in f] + sage: [p^e for p,e in f] # optional - sage.libs.pari [4, 3, 5, 7] We can factor Python, numpy and gmpy2 numbers:: sage: factor(math.pi) 3.141592653589793 - sage: import numpy - sage: factor(numpy.int8(30)) + sage: import numpy # optional - numpy + sage: factor(numpy.int8(30)) # optional - numpy sage.libs.pari 2 * 3 * 5 sage: import gmpy2 - sage: factor(gmpy2.mpz(30)) + sage: factor(gmpy2.mpz(30)) # optional - sage.libs.pari 2 * 3 * 5 TESTS:: @@ -2703,14 +2710,14 @@ def radical(n, *args, **kwds): Traceback (most recent call last): ... ArithmeticError: radical of 0 is not defined - sage: K. = QuadraticField(-1) - sage: radical(K(2)) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: radical(K(2)) # optional - sage.rings.number_field i + 1 Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: radical(int8(50)) + sage: from numpy import int8 # optional - numpy + sage: radical(int8(50)) # optional - numpy 10 sage: from gmpy2 import mpz sage: radical(mpz(50)) @@ -2763,13 +2770,13 @@ def prime_divisors(n): For polynomials we get all irreducible factors:: sage: R. = PolynomialRing(QQ) - sage: prime_divisors(x^12 - 1) + sage: prime_divisors(x^12 - 1) # optional - sage.libs.pari [x - 1, x + 1, x^2 - x + 1, x^2 + 1, x^2 + x + 1, x^4 - x^2 + 1] Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: prime_divisors(int8(-100)) + sage: from numpy import int8 # optional - numpy + sage: prime_divisors(int8(-100)) # optional - numpy [2, 5] sage: from gmpy2 import mpz sage: prime_divisors(mpz(-100)) @@ -2801,8 +2808,8 @@ def odd_part(n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: odd_part(int8(5)) + sage: from numpy import int8 # optional - numpy + sage: odd_part(int8(5)) # optional - numpy 5 sage: from gmpy2 import mpz sage: odd_part(mpz(5)) @@ -2845,8 +2852,8 @@ def prime_to_m_part(n, m): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: prime_to_m_part(int16(240), int16(2)) + sage: from numpy import int16 # optional - numpy + sage: prime_to_m_part(int16(240), int16(2)) # optional - numpy 15 sage: from gmpy2 import mpz sage: prime_to_m_part(mpz(240), mpz(2)) @@ -2901,8 +2908,8 @@ def is_square(n, root=False): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: is_square(int8(4)) + sage: from numpy import int8 # optional - numpy + sage: is_square(int8(4)) # optional - numpy True sage: from gmpy2 import mpz sage: is_square(mpz(4)) @@ -2940,47 +2947,47 @@ def is_squarefree(n): EXAMPLES:: - sage: is_squarefree(100) + sage: is_squarefree(100) # optional - sage.libs.pari False - sage: is_squarefree(101) + sage: is_squarefree(101) # optional - sage.libs.pari True sage: R = ZZ['x'] sage: x = R.gen() - sage: is_squarefree((x^2+x+1) * (x-2)) + sage: is_squarefree((x^2+x+1) * (x-2)) # optional - sage.libs.pari True - sage: is_squarefree((x-1)**2 * (x-3)) + sage: is_squarefree((x-1)**2 * (x-3)) # optional - sage.libs.pari False - sage: O = ZZ[sqrt(-1)] - sage: I = O.gen(1) - sage: is_squarefree(I+1) + sage: O = ZZ[sqrt(-1)] # optional - sage.rings.number_field sage.symbolic + sage: I = O.gen(1) # optional - sage.rings.number_field sage.symbolic + sage: is_squarefree(I + 1) # optional - sage.rings.number_field sage.symbolic True - sage: is_squarefree(O(2)) + sage: is_squarefree(O(2)) # optional - sage.rings.number_field sage.symbolic False - sage: O(2).factor() + sage: O(2).factor() # optional - sage.rings.number_field sage.symbolic (-I) * (I + 1)^2 This method fails on domains which are not Unique Factorization Domains:: - sage: O = ZZ[sqrt(-5)] - sage: a = O.gen(1) - sage: is_squarefree(a - 3) + sage: O = ZZ[sqrt(-5)] # optional - sage.rings.number_field sage.symbolic + sage: a = O.gen(1) # optional - sage.rings.number_field sage.symbolic + sage: is_squarefree(a - 3) # optional - sage.rings.number_field sage.symbolic Traceback (most recent call last): ... ArithmeticError: non-principal ideal in factorization Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: is_squarefree(int8(100)) + sage: from numpy import int8 # optional - numpy + sage: is_squarefree(int8(100)) # optional - numpy sage.libs.pari False - sage: is_squarefree(int8(101)) + sage: is_squarefree(int8(101)) # optional - numpy sage.libs.pari True sage: from gmpy2 import mpz - sage: is_squarefree(mpz(100)) + sage: is_squarefree(mpz(100)) # optional - sage.libs.pari False - sage: is_squarefree(mpz(101)) + sage: is_squarefree(mpz(101)) # optional - sage.libs.pari True """ e = py_scalar_to_element(n) @@ -3017,11 +3024,11 @@ class Euler_Phi: 1 sage: euler_phi(2) 1 - sage: euler_phi(3) + sage: euler_phi(3) # optional - sage.libs.pari 2 - sage: euler_phi(12) + sage: euler_phi(12) # optional - sage.libs.pari 4 - sage: euler_phi(37) + sage: euler_phi(37) # optional - sage.libs.pari 36 Notice that euler_phi is defined to be 0 on negative numbers and @@ -3040,7 +3047,7 @@ class Euler_Phi: :: - sage: euler_phi(21) + sage: euler_phi(21) # optional - sage.libs.pari 12 sage: [i for i in range(21) if gcd(21,i) == 1] [1, 2, 4, 5, 8, 10, 11, 13, 16, 17, 19, 20] @@ -3050,22 +3057,22 @@ class Euler_Phi: :: - sage: len([i for i in range(21) if gcd(21,i) == 1]) == euler_phi(21) + sage: len([i for i in range(21) if gcd(21,i) == 1]) == euler_phi(21) # optional - sage.libs.pari True The phi function also has a special plotting method. :: - sage: P = plot(euler_phi, -3, 71) + sage: P = plot(euler_phi, -3, 71) # optional - sage.libs.pari sage.plot Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: euler_phi(int8(37)) + sage: from numpy import int8 # optional - numpy + sage: euler_phi(int8(37)) # optional - numpy sage.libs.pari sage.plot 36 sage: from gmpy2 import mpz - sage: euler_phi(mpz(37)) + sage: euler_phi(mpz(37)) # optional - sage.libs.pari sage.plot 36 AUTHORS: @@ -3093,9 +3100,9 @@ def __call__(self, n): EXAMPLES:: sage: from sage.arith.misc import Euler_Phi - sage: Euler_Phi()(10) + sage: Euler_Phi()(10) # optional - sage.libs.pari 4 - sage: Euler_Phi()(720) + sage: Euler_Phi()(720) # optional - sage.libs.pari 192 """ if n <= 0: @@ -3129,8 +3136,8 @@ def plot(self, xmin=1, xmax=50, pointsize=30, rgbcolor=(0, 0, 1), EXAMPLES:: sage: from sage.arith.misc import Euler_Phi - sage: p = Euler_Phi().plot() - sage: p.ymax() + sage: p = Euler_Phi().plot() # optional - sage.plot + sage: p.ymax() # optional - sage.plot 46.0 """ v = [(n, euler_phi(n)) for n in range(xmin, xmax + 1)] @@ -3186,7 +3193,7 @@ def carmichael_lambda(n): The Carmichael function of the first ten primes:: - sage: list(map(carmichael_lambda, primes_first_n(10))) + sage: list(map(carmichael_lambda, primes_first_n(10))) # optional - sage.libs.pari [1, 2, 4, 6, 10, 12, 16, 18, 22, 28] Cases where the Carmichael function is equivalent to the Euler phi @@ -3194,19 +3201,19 @@ def carmichael_lambda(n): sage: carmichael_lambda(2) == euler_phi(2) True - sage: carmichael_lambda(4) == euler_phi(4) + sage: carmichael_lambda(4) == euler_phi(4) # optional - sage.libs.pari True sage: p = random_prime(1000, lbound=3, proof=True) sage: k = randint(1, 1000) - sage: carmichael_lambda(p^k) == euler_phi(p^k) + sage: carmichael_lambda(p^k) == euler_phi(p^k) # optional - sage.libs.pari True A case where `\lambda(n) \neq \varphi(n)`:: sage: k = randint(3, 1000) - sage: carmichael_lambda(2^k) == 2^(k - 2) + sage: carmichael_lambda(2^k) == 2^(k - 2) # optional - sage.libs.pari True - sage: carmichael_lambda(2^k) == 2^(k - 2) == euler_phi(2^k) + sage: carmichael_lambda(2^k) == 2^(k - 2) == euler_phi(2^k) # optional - sage.libs.pari False Verifying the current implementation of the Carmichael function using @@ -3216,7 +3223,7 @@ def carmichael_lambda(n): sage: from sage.arith.misc import carmichael_lambda sage: n = randint(1, 500) - sage: c = carmichael_lambda(n) + sage: c = carmichael_lambda(n) # optional - sage.libs.pari sage: def coprime(n): ....: return [i for i in range(n) if gcd(i, n) == 1] sage: def znpower(n, k): @@ -3231,7 +3238,7 @@ def carmichael_lambda(n): ....: T = [L[i] == ones[i] for i in range(len(L))] ....: if all(T): ....: return k - sage: c == my_carmichael(n) + sage: c == my_carmichael(n) # optional - sage.libs.pari True Carmichael's theorem states that `a^{\lambda(n)} \equiv 1 \pmod{n}` @@ -3240,12 +3247,12 @@ def carmichael_lambda(n): sage: from sage.arith.misc import carmichael_lambda sage: n = randint(2, 1000) - sage: c = carmichael_lambda(n) + sage: c = carmichael_lambda(n) # optional - sage.libs.pari sage: ZnZ = IntegerModRing(n) sage: M = ZnZ.list_of_elements_of_multiplicative_group() sage: ones = [1] * len(M) - sage: P = [power_mod(a, c, n) for a in M] - sage: P == ones + sage: P = [power_mod(a, c, n) for a in M] # optional - sage.libs.pari + sage: P == ones # optional - sage.libs.pari True TESTS: @@ -3265,7 +3272,7 @@ def carmichael_lambda(n): Bug reported in :trac:`8283`:: sage: from sage.arith.misc import carmichael_lambda - sage: type(carmichael_lambda(16)) + sage: type(carmichael_lambda(16)) # optional - sage.libs.pari REFERENCES: @@ -3346,50 +3353,55 @@ def crt(a, b, m=None, n=None): Note that this also works for polynomial rings:: - sage: K. = NumberField(x^3 - 7) - sage: R. = K[] - sage: f = y^2 + 3 - sage: g = y^3 - 5 - sage: CRT(1,3,f,g) + sage: x = polygen(ZZ, 'x') + sage: K. = NumberField(x^3 - 7) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: f = y^2 + 3 # optional - sage.rings.number_field + sage: g = y^3 - 5 # optional - sage.rings.number_field + sage: CRT(1, 3, f, g) # optional - sage.rings.number_field -3/26*y^4 + 5/26*y^3 + 15/26*y + 53/26 - sage: CRT(1,a,f,g) + sage: CRT(1, a, f, g) # optional - sage.rings.number_field (-3/52*a + 3/52)*y^4 + (5/52*a - 5/52)*y^3 + (15/52*a - 15/52)*y + 27/52*a + 25/52 You can also do this for any number of moduli:: - sage: K. = NumberField(x^3 - 7) - sage: R. = K[] - sage: CRT([], []) + sage: K. = NumberField(x^3 - 7) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: CRT([], []) # optional - sage.rings.number_field 0 - sage: CRT([a], [x]) + sage: CRT([a], [x]) # optional - sage.rings.number_field a - sage: f = x^2 + 3 - sage: g = x^3 - 5 - sage: h = x^5 + x^2 - 9 - sage: k = CRT([1, a, 3], [f, g, h]); k - (127/26988*a - 5807/386828)*x^9 + (45/8996*a - 33677/1160484)*x^8 + (2/173*a - 6/173)*x^7 + (133/6747*a - 5373/96707)*x^6 + (-6/2249*a + 18584/290121)*x^5 + (-277/8996*a + 38847/386828)*x^4 + (-135/4498*a + 42673/193414)*x^3 + (-1005/8996*a + 470245/1160484)*x^2 + (-1215/8996*a + 141165/386828)*x + 621/8996*a + 836445/386828 - sage: k.mod(f) + sage: f = x^2 + 3 # optional - sage.rings.number_field + sage: g = x^3 - 5 # optional - sage.rings.number_field + sage: h = x^5 + x^2 - 9 # optional - sage.rings.number_field + sage: k = CRT([1, a, 3], [f, g, h]); k # optional - sage.rings.number_field + (127/26988*a - 5807/386828)*x^9 + (45/8996*a - 33677/1160484)*x^8 + + (2/173*a - 6/173)*x^7 + (133/6747*a - 5373/96707)*x^6 + + (-6/2249*a + 18584/290121)*x^5 + (-277/8996*a + 38847/386828)*x^4 + + (-135/4498*a + 42673/193414)*x^3 + (-1005/8996*a + 470245/1160484)*x^2 + + (-1215/8996*a + 141165/386828)*x + 621/8996*a + 836445/386828 + sage: k.mod(f) # optional - sage.rings.number_field 1 - sage: k.mod(g) + sage: k.mod(g) # optional - sage.rings.number_field a - sage: k.mod(h) + sage: k.mod(h) # optional - sage.rings.number_field 3 If the moduli are not coprime, a solution may not exist:: - sage: crt(4,8,8,12) + sage: crt(4, 8, 8, 12) 20 - sage: crt(4,6,8,12) + sage: crt(4, 6, 8, 12) Traceback (most recent call last): ... ValueError: no solution to crt problem since gcd(8,12) does not divide 4-6 sage: x = polygen(QQ) - sage: crt(2,3,x-1,x+1) + sage: crt(2, 3, x - 1, x + 1) -1/2*x + 5/2 - sage: crt(2,x,x^2-1,x^2+1) + sage: crt(2, x, x^2 - 1, x^2 + 1) -1/2*x^3 + x^2 + 1/2*x + 1 - sage: crt(2,x,x^2-1,x^3-1) + sage: crt(2, x, x^2 - 1, x^3 - 1) Traceback (most recent call last): ... ValueError: no solution to crt problem since gcd(x^2 - 1,x^3 - 1) does not divide 2-x @@ -3399,13 +3411,13 @@ def crt(a, b, m=None, n=None): crt also work with numpy and gmpy2 numbers:: - sage: import numpy - sage: crt(numpy.int8(2), numpy.int8(3), numpy.int8(7), numpy.int8(11)) + sage: import numpy # optional - numpy + sage: crt(numpy.int8(2), numpy.int8(3), numpy.int8(7), numpy.int8(11)) # optional - numpy 58 sage: from gmpy2 import mpz sage: crt(mpz(2), mpz(3), mpz(7), mpz(11)) 58 - sage: crt(mpz(2), 3, mpz(7), numpy.int8(11)) + sage: crt(mpz(2), 3, mpz(7), numpy.int8(11)) # optional - numpy 58 """ if isinstance(a, list): @@ -3492,8 +3504,8 @@ def CRT_list(values, moduli): sage: CRT([32r,2r,2r],[60r,90r,150r]) 452 - sage: from numpy import int8 - sage: CRT_list([int8(2),int8(3),int8(2)], [int8(3),int8(5),int8(7)]) + sage: from numpy import int8 # optional - numpy + sage: CRT_list([int8(2), int8(3), int8(2)], [int8(3), int8(5), int8(7)]) # optional - numpy 23 sage: from gmpy2 import mpz sage: CRT_list([mpz(2),mpz(3),mpz(2)], [mpz(3),mpz(5),mpz(7)]) @@ -3597,7 +3609,7 @@ def CRT_vectors(X, moduli): sage: CRT_vectors([[3,5,7],[3,5,11]], [2,3]) [3, 5, 5] - sage: CRT_vectors([vector(ZZ, [2,3,1]), Sequence([1,7,8],ZZ)], [8,9]) + sage: CRT_vectors([vector(ZZ, [2,3,1]), Sequence([1,7,8], ZZ)], [8,9]) # optional - sage.modules [10, 43, 17] """ # First find the CRT basis: @@ -3639,15 +3651,15 @@ def binomial(x, m, **kwds): EXAMPLES:: sage: from sage.arith.misc import binomial - sage: binomial(5,2) + sage: binomial(5, 2) 10 - sage: binomial(2,0) + sage: binomial(2, 0) 1 - sage: binomial(1/2, 0) + sage: binomial(1/2, 0) # optional - sage.libs.pari 1 - sage: binomial(3,-1) + sage: binomial(3, -1) 0 - sage: binomial(20,10) + sage: binomial(20, 10) 184756 sage: binomial(-2, 5) -6 @@ -3655,11 +3667,11 @@ def binomial(x, m, **kwds): 0 sage: binomial(RealField()('2.5'), 2) 1.87500000000000 - sage: n=var('n'); binomial(n,2) + sage: n = var('n'); binomial(n, 2) # optional - sage.symbolic 1/2*(n - 1)*n - sage: n=var('n'); binomial(n,n) + sage: n = var('n'); binomial(n, n) # optional - sage.symbolic 1 - sage: n=var('n'); binomial(n,n-1) + sage: n = var('n'); binomial(n, n - 1) # optional - sage.symbolic n sage: binomial(2^100, 2^100) 1 @@ -3667,7 +3679,7 @@ def binomial(x, m, **kwds): sage: x = polygen(ZZ) sage: binomial(x, 3) 1/6*x^3 - 1/2*x^2 + 1/3*x - sage: binomial(x, x-3) + sage: binomial(x, x - 3) 1/6*x^3 - 1/2*x^2 + 1/3*x If `x \in \ZZ`, there is an optional 'algorithm' parameter, which @@ -3688,21 +3700,21 @@ def binomial(x, m, **kwds): We test conversion of arguments to Integers -- see :trac:`6870`:: - sage: binomial(1/2,1/1) + sage: binomial(1/2, 1/1) 1/2 - sage: binomial(10^20+1/1,10^20) + sage: binomial(10^20 + 1/1, 10^20) 100000000000000000001 - sage: binomial(SR(10**7),10**7) + sage: binomial(SR(10**7), 10**7) # optional - sage.symbolic 1 - sage: binomial(3/2,SR(1/1)) + sage: binomial(3/2, SR(1/1)) # optional - sage.symbolic 3/2 Some floating point cases -- see :trac:`7562`, :trac:`9633`, and :trac:`12448`:: - sage: binomial(1.,3) + sage: binomial(1., 3) 0.000000000000000 - sage: binomial(-2.,3) + sage: binomial(-2., 3) -4.00000000000000 sage: binomial(0.5r, 5) 0.02734375 @@ -3759,8 +3771,8 @@ def binomial(x, m, **kwds): ... TypeError: either m or x-m must be an integer - sage: k, i = var('k,i') - sage: binomial(k,i) + sage: k, i = var('k,i') # optional - sage.symbolic + sage: binomial(k,i) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: either m or x-m must be an integer @@ -3797,15 +3809,15 @@ def binomial(x, m, **kwds): :func:`~sage.functions.other.binomial` from the module :mod:`sage.functions.other`:: - sage: from sage.functions.other import binomial - sage: binomial(k, i) + sage: from sage.functions.other import binomial # optional - sage.symbolic + sage: binomial(k, i) # optional - sage.symbolic binomial(k, i) binomial support numpy and gmpy2 parameters:: sage: from sage.arith.misc import binomial - sage: import numpy - sage: binomial(numpy.int32(20), numpy.int32(10)) + sage: import numpy # optional - numpy + sage: binomial(numpy.int32(20), numpy.int32(10)) # optional - numpy 184756 sage: import gmpy2 sage: binomial(gmpy2.mpz(20), gmpy2.mpz(10)) @@ -3886,17 +3898,17 @@ def multinomial(*ks): 618970023101454657175683075 sage: multinomial([2^30, 2, 1]) 618970023101454657175683075 - sage: multinomial(Composition([1, 3])) + sage: multinomial(Composition([1, 3])) # optional - sage.combinat 4 - sage: multinomial(Partition([4, 2])) + sage: multinomial(Partition([4, 2])) # optional - sage.combinat 15 TESTS: Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: multinomial(int8(3), int8(2)) + sage: from numpy import int8 # optional - numpy + sage: multinomial(int8(3), int8(2)) # optional - numpy 10 sage: from gmpy2 import mpz sage: multinomial(mpz(3), mpz(2)) @@ -3952,8 +3964,8 @@ def binomial_coefficients(n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: sorted(binomial_coefficients(int8(3)).items()) + sage: from numpy import int8 # optional - numpy + sage: sorted(binomial_coefficients(int8(3)).items()) # optional - numpy [((0, 3), 1), ((1, 2), 3), ((2, 1), 3), ((3, 0), 1)] sage: from gmpy2 import mpz sage: sorted(binomial_coefficients(mpz(3)).items()) @@ -4029,8 +4041,8 @@ def multinomial_coefficients(m, n): {(): 1} sage: multinomial_coefficients(0, 3) {} - sage: from numpy import int8 - sage: sorted(multinomial_coefficients(int8(2), int8(5)).items()) + sage: from numpy import int8 # optional - numpy + sage: sorted(multinomial_coefficients(int8(2), int8(5)).items()) # optional - numpy [((0, 5), 1), ((1, 4), 5), ((2, 3), 10), ((3, 2), 10), ((4, 1), 5), ((5, 0), 1)] sage: from gmpy2 import mpz sage: sorted(multinomial_coefficients(mpz(2), mpz(5)).items()) @@ -4118,8 +4130,8 @@ def kronecker_symbol(x,y): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: kronecker_symbol(int8(13),int8(21)) + sage: from numpy import int8 # optional - numpy + sage: kronecker_symbol(int8(13),int8(21)) # optional - numpy -1 sage: from gmpy2 import mpz sage: kronecker_symbol(mpz(13),mpz(21)) @@ -4170,8 +4182,8 @@ def legendre_symbol(x, p): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: legendre_symbol(int8(2),int8(3)) + sage: from numpy import int8 # optional - numpy + sage: legendre_symbol(int8(2), int8(3)) # optional - numpy -1 sage: from gmpy2 import mpz sage: legendre_symbol(mpz(2),mpz(3)) @@ -4226,8 +4238,8 @@ def jacobi_symbol(a, b): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: jacobi_symbol(int16(10),int16(777)) + sage: from numpy import int16 # optional - numpy + sage: jacobi_symbol(int16(10), int16(777)) # optional - numpy -1 sage: from gmpy2 import mpz sage: jacobi_symbol(mpz(10),mpz(777)) @@ -4262,15 +4274,15 @@ def primitive_root(n, check=True): EXAMPLES:: - sage: primitive_root(23) + sage: primitive_root(23) # optional - sage.libs.pari 5 - sage: primitive_root(-46) + sage: primitive_root(-46) # optional - sage.libs.pari 5 - sage: primitive_root(25) + sage: primitive_root(25) # optional - sage.libs.pari 2 - sage: print([primitive_root(p) for p in primes(100)]) + sage: print([primitive_root(p) for p in primes(100)]) # optional - sage.libs.pari [1, 2, 2, 3, 2, 2, 3, 2, 5, 2, 3, 2, 6, 3, 5, 2, 2, 2, 2, 7, 5, 3, 2, 3, 5] - sage: primitive_root(8) + sage: primitive_root(8) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root @@ -4286,57 +4298,57 @@ def primitive_root(n, check=True): :: sage: n = 10^50 + 151 # a prime - sage: primitive_root(n) + sage: primitive_root(n) # optional - sage.libs.pari 11 - sage: primitive_root(n, check=False) + sage: primitive_root(n, check=False) # optional - sage.libs.pari 11 TESTS: Various special cases:: - sage: primitive_root(-1) + sage: primitive_root(-1) # optional - sage.libs.pari 0 - sage: primitive_root(0) + sage: primitive_root(0) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root - sage: primitive_root(1) + sage: primitive_root(1) # optional - sage.libs.pari 0 - sage: primitive_root(2) + sage: primitive_root(2) # optional - sage.libs.pari 1 - sage: primitive_root(3) + sage: primitive_root(3) # optional - sage.libs.pari 2 - sage: primitive_root(4) + sage: primitive_root(4) # optional - sage.libs.pari 3 We test that various numbers without primitive roots give an error - see :trac:`10836`:: - sage: primitive_root(15) + sage: primitive_root(15) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root - sage: primitive_root(16) + sage: primitive_root(16) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root - sage: primitive_root(1729) + sage: primitive_root(1729) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root - sage: primitive_root(4*7^8) + sage: primitive_root(4*7^8) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: primitive_root(int8(-46)) + sage: from numpy import int8 # optional - numpy + sage: primitive_root(int8(-46)) # optional - numpy sage.libs.pari 5 sage: from gmpy2 import mpz - sage: primitive_root(mpz(-46)) + sage: primitive_root(mpz(-46)) # optional - sage.libs.pari 5 """ from sage.libs.pari.all import pari @@ -4372,29 +4384,29 @@ def nth_prime(n): EXAMPLES:: - sage: nth_prime(3) + sage: nth_prime(3) # optional - sage.libs.pari 5 - sage: nth_prime(10) + sage: nth_prime(10) # optional - sage.libs.pari 29 - sage: nth_prime(10^7) + sage: nth_prime(10^7) # optional - sage.libs.pari 179424673 :: - sage: nth_prime(0) + sage: nth_prime(0) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: nth prime meaningless for non-positive n (=0) TESTS:: - sage: all(prime_pi(nth_prime(j)) == j for j in range(1, 1000, 10)) + sage: all(prime_pi(nth_prime(j)) == j for j in range(1, 1000, 10)) # optional - sage.libs.pari True - sage: from numpy import int8 - sage: nth_prime(int8(10)) + sage: from numpy import int8 # optional - numpy + sage: nth_prime(int8(10)) # optional - numpy sage.libs.pari 29 sage: from gmpy2 import mpz - sage: nth_prime(mpz(10)) + sage: nth_prime(mpz(10)) # optional - sage.libs.pari 29 """ if n <= 0: @@ -4425,8 +4437,8 @@ def quadratic_residues(n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: quadratic_residues(int8(11)) + sage: from numpy import int8 # optional - numpy + sage: quadratic_residues(int8(11)) # optional - numpy [0, 1, 3, 4, 5, 9] sage: from gmpy2 import mpz sage: quadratic_residues(mpz(11)) @@ -4460,39 +4472,39 @@ class Moebius: EXAMPLES:: - sage: moebius(-5) + sage: moebius(-5) # optional - sage.libs.pari -1 - sage: moebius(9) + sage: moebius(9) # optional - sage.libs.pari 0 - sage: moebius(12) + sage: moebius(12) # optional - sage.libs.pari 0 - sage: moebius(-35) + sage: moebius(-35) # optional - sage.libs.pari 1 - sage: moebius(-1) + sage: moebius(-1) # optional - sage.libs.pari 1 - sage: moebius(7) + sage: moebius(7) # optional - sage.libs.pari -1 :: - sage: moebius(0) # potentially nonstandard! + sage: moebius(0) # potentially nonstandard! # optional - sage.libs.pari 0 The moebius function even makes sense for non-integer inputs. :: - sage: x = GF(7)['x'].0 - sage: moebius(x+2) + sage: x = GF(7)['x'].0 # optional - sage.libs.pari + sage: moebius(x + 2) # optional - sage.libs.pari -1 Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: moebius(int8(-5)) + sage: from numpy import int8 # optional - numpy + sage: moebius(int8(-5)) # optional - numpy sage.libs.pari -1 sage: from gmpy2 import mpz - sage: moebius(mpz(-5)) + sage: moebius(mpz(-5)) # optional - sage.libs.pari -1 """ def __call__(self, n): @@ -4500,7 +4512,7 @@ def __call__(self, n): EXAMPLES:: sage: from sage.arith.misc import Moebius - sage: Moebius().__call__(7) + sage: Moebius().__call__(7) # optional - sage.libs.pari -1 """ n = py_scalar_to_element(n) @@ -4558,8 +4570,8 @@ def plot(self, xmin=0, xmax=50, pointsize=30, rgbcolor=(0,0,1), join=True, EXAMPLES:: sage: from sage.arith.misc import Moebius - sage: p = Moebius().plot() - sage: p.ymax() + sage: p = Moebius().plot() # optional - sage.plot + sage: p.ymax() # optional - sage.plot 1.0 """ values = self.range(xmin, xmax + 1) @@ -4581,12 +4593,12 @@ def range(self, start, stop=None, step=None): EXAMPLES:: - sage: v = moebius.range(-10,10); v + sage: v = moebius.range(-10, 10); v # optional - sage.libs.pari [1, 0, 0, -1, 1, -1, 0, -1, -1, 1, 0, 1, -1, -1, 0, -1, 1, -1, 0, 0] - sage: v == [moebius(n) for n in range(-10,10)] + sage: v == [moebius(n) for n in range(-10, 10)] # optional - sage.libs.pari True - sage: v = moebius.range(-1000, 2000, 4) - sage: v == [moebius(n) for n in range(-1000,2000, 4)] + sage: v = moebius.range(-1000, 2000, 4) # optional - sage.libs.pari + sage: v == [moebius(n) for n in range(-1000, 2000, 4)] # optional - sage.libs.pari True """ if stop is None: @@ -4650,14 +4662,15 @@ def continuant(v, n=None): sage: q = continuant([1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10]) sage: p/q 517656/190435 - sage: continued_fraction([2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10]).convergent(14) + sage: F = continued_fraction([2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10]) + sage: F.convergent(14) # optional - sage.libs.pari 517656/190435 - sage: x = PolynomialRing(RationalField(),'x',5).gens() + sage: x = PolynomialRing(RationalField(), 'x', 5).gens() sage: continuant(x) x0*x1*x2*x3*x4 + x0*x1*x2 + x0*x1*x4 + x0*x3*x4 + x2*x3*x4 + x0 + x2 + x4 sage: continuant(x, 3) x0*x1*x2 + x0 + x2 - sage: continuant(x,2) + sage: continuant(x, 2) x0*x1 + 1 We verify the identity @@ -4669,7 +4682,7 @@ def continuant(v, n=None): for `n = 6` using polynomial arithmetic:: sage: z = QQ['z'].0 - sage: continuant((z,z,z,z,z,z,z,z,z,z,z,z,z,z,z),6) + sage: continuant((z,z,z,z,z,z,z,z,z,z,z,z,z,z,z), 6) z^6 + 5*z^4 + 6*z^2 + 1 sage: continuant(9) @@ -4679,11 +4692,11 @@ def continuant(v, n=None): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: continuant([int8(1),int8(2),int8(3)]) + sage: from numpy import int8 # optional - numpy + sage: continuant([int8(1), int8(2), int8(3)]) # optional - numpy 10 sage: from gmpy2 import mpz - sage: continuant([mpz(1),mpz(2),mpz(3)]) + sage: continuant([mpz(1), mpz(2), mpz(3)]) mpz(10) AUTHORS: @@ -4717,18 +4730,18 @@ def number_of_divisors(n): EXAMPLES:: - sage: number_of_divisors(100) + sage: number_of_divisors(100) # optional - sage.libs.pari 9 - sage: number_of_divisors(-720) + sage: number_of_divisors(-720) # optional - sage.libs.pari 30 Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: number_of_divisors(int8(100)) + sage: from numpy import int8 # optional - numpy + sage: number_of_divisors(int8(100)) # optional - numpy sage.libs.pari 9 sage: from gmpy2 import mpz - sage: number_of_divisors(mpz(100)) + sage: number_of_divisors(mpz(100)) # optional - sage.libs.pari 9 """ m = ZZ(n) @@ -4766,33 +4779,33 @@ def hilbert_symbol(a, b, p, algorithm="pari"): EXAMPLES:: - sage: hilbert_symbol (-1, -1, -1, algorithm='all') + sage: hilbert_symbol(-1, -1, -1, algorithm='all') # optional - sage.libs.pari -1 - sage: hilbert_symbol (2,3, 5, algorithm='all') + sage: hilbert_symbol(2, 3, 5, algorithm='all') # optional - sage.libs.pari 1 - sage: hilbert_symbol (4, 3, 5, algorithm='all') + sage: hilbert_symbol(4, 3, 5, algorithm='all') # optional - sage.libs.pari 1 - sage: hilbert_symbol (0, 3, 5, algorithm='all') + sage: hilbert_symbol(0, 3, 5, algorithm='all') # optional - sage.libs.pari 0 - sage: hilbert_symbol (-1, -1, 2, algorithm='all') + sage: hilbert_symbol(-1, -1, 2, algorithm='all') # optional - sage.libs.pari -1 - sage: hilbert_symbol (1, -1, 2, algorithm='all') + sage: hilbert_symbol(1, -1, 2, algorithm='all') # optional - sage.libs.pari 1 - sage: hilbert_symbol (3, -1, 2, algorithm='all') + sage: hilbert_symbol(3, -1, 2, algorithm='all') # optional - sage.libs.pari -1 - sage: hilbert_symbol(QQ(-1)/QQ(4), -1, 2) == -1 + sage: hilbert_symbol(QQ(-1)/QQ(4), -1, 2) == -1 # optional - sage.libs.pari True - sage: hilbert_symbol(QQ(-1)/QQ(4), -1, 3) == 1 + sage: hilbert_symbol(QQ(-1)/QQ(4), -1, 3) == 1 # optional - sage.libs.pari True Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: hilbert_symbol(int8(2),int8(3),int8(5),algorithm='all') + sage: from numpy import int8 # optional - numpy + sage: hilbert_symbol(int8(2), int8(3), int8(5), algorithm='all') # optional - numpy sage.libs.pari 1 sage: from gmpy2 import mpz - sage: hilbert_symbol(mpz(2),mpz(3),mpz(5),algorithm='all') + sage: hilbert_symbol(mpz(2), mpz(3), mpz(5), algorithm='all') # optional - sage.libs.pari 1 AUTHORS: @@ -4871,22 +4884,22 @@ def hilbert_conductor(a, b): EXAMPLES:: - sage: hilbert_conductor(-1, -1) + sage: hilbert_conductor(-1, -1) # optional - sage.libs.pari 2 - sage: hilbert_conductor(-1, -11) + sage: hilbert_conductor(-1, -11) # optional - sage.libs.pari 11 - sage: hilbert_conductor(-2, -5) + sage: hilbert_conductor(-2, -5) # optional - sage.libs.pari 5 - sage: hilbert_conductor(-3, -17) + sage: hilbert_conductor(-3, -17) # optional - sage.libs.pari 17 Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: hilbert_conductor(int8(-3), int8(-17)) + sage: from numpy import int8 # optional - numpy + sage: hilbert_conductor(int8(-3), int8(-17)) # optional - numpy sage.libs.pari 17 sage: from gmpy2 import mpz - sage: hilbert_conductor(mpz(-3), mpz(-17)) + sage: hilbert_conductor(mpz(-3), mpz(-17)) # optional - sage.libs.pari 17 AUTHOR: @@ -4914,19 +4927,19 @@ def hilbert_conductor_inverse(d): EXAMPLES:: - sage: hilbert_conductor_inverse(2) + sage: hilbert_conductor_inverse(2) # optional - sage.libs.pari (-1, -1) - sage: hilbert_conductor_inverse(3) + sage: hilbert_conductor_inverse(3) # optional - sage.libs.pari (-1, -3) - sage: hilbert_conductor_inverse(6) + sage: hilbert_conductor_inverse(6) # optional - sage.libs.pari (-1, 3) - sage: hilbert_conductor_inverse(30) + sage: hilbert_conductor_inverse(30) # optional - sage.libs.pari (-3, -10) - sage: hilbert_conductor_inverse(4) + sage: hilbert_conductor_inverse(4) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: d needs to be squarefree - sage: hilbert_conductor_inverse(-1) + sage: hilbert_conductor_inverse(-1) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: d needs to be positive @@ -4937,18 +4950,18 @@ def hilbert_conductor_inverse(d): TESTS:: - sage: for i in range(100): + sage: for i in range(100): # optional - sage.libs.pari ....: d = ZZ.random_element(2**32).squarefree_part() ....: if hilbert_conductor(*hilbert_conductor_inverse(d)) != d: ....: print("hilbert_conductor_inverse failed for d = {}".format(d)) Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: hilbert_conductor_inverse(int8(30)) + sage: from numpy import int8 # optional - numpy + sage: hilbert_conductor_inverse(int8(30)) # optional - numpy sage.libs.pari (-3, -10) sage: from gmpy2 import mpz - sage: hilbert_conductor_inverse(mpz(30)) + sage: hilbert_conductor_inverse(mpz(30)) # optional - sage.libs.pari (-3, -10) """ Z = ZZ @@ -5024,25 +5037,25 @@ def falling_factorial(x, a): sage: falling_factorial(10, 3) 720 - sage: falling_factorial(10, RR('3.0')) + sage: falling_factorial(10, RR('3.0')) # optional - sage.symbolic 720.000000000000 - sage: falling_factorial(10, RR('3.3')) + sage: falling_factorial(10, RR('3.3')) # optional - sage.symbolic 1310.11633396601 sage: falling_factorial(10, 10) 3628800 sage: factorial(10) 3628800 - sage: a = falling_factorial(1+I, I); a + sage: a = falling_factorial(1 + I, I); a # optional - sage.symbolic gamma(I + 2) - sage: CC(a) + sage: CC(a) # optional - sage.symbolic 0.652965496420167 + 0.343065839816545*I - sage: falling_factorial(1+I, 4) + sage: falling_factorial(1 + I, 4) 4*I + 2 sage: falling_factorial(I, 4) -10 sage: M = MatrixSpace(ZZ, 4, 4) - sage: A = M([1,0,1,0,1,0,1,0,1,0,10,10,1,0,1,1]) + sage: A = M([1,0,1,0, 1,0,1,0, 1,0,10,10, 1,0,1,1]) sage: falling_factorial(A, 2) # A(A - I) [ 1 0 10 10] [ 1 0 10 10] @@ -5057,13 +5070,13 @@ def falling_factorial(x, a): Check that :trac:`14858` is fixed:: - sage: falling_factorial(-4, SR(2)) + sage: falling_factorial(-4, SR(2)) # optional - sage.symbolic 20 Check that :trac:`16770` is fixed:: - sage: d = var('d') - sage: parent(falling_factorial(d, 0)) + sage: d = var('d') # optional - sage.symbolic + sage: parent(falling_factorial(d, 0)) # optional - sage.symbolic Symbolic Ring Check that :trac:`20075` is fixed:: @@ -5073,8 +5086,8 @@ def falling_factorial(x, a): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: falling_factorial(int8(10), int8(3)) + sage: from numpy import int8 # optional - numpy + sage: falling_factorial(int8(10), int8(3)) # optional - numpy 720 sage: from gmpy2 import mpz sage: falling_factorial(mpz(10), mpz(3)) @@ -5149,7 +5162,7 @@ def rising_factorial(x, a): Check that :trac:`14858` is fixed:: - sage: bool(rising_factorial(-4, 2) == + sage: bool(rising_factorial(-4, 2) == # optional - sage.symbolic ....: rising_factorial(-4, SR(2)) == ....: rising_factorial(SR(-4), SR(2))) True @@ -5167,8 +5180,8 @@ def rising_factorial(x, a): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: rising_factorial(int8(10), int8(3)) + sage: from numpy import int8 # optional - numpy + sage: rising_factorial(int8(10), int8(3)) # optional - numpy 1320 sage: from gmpy2 import mpz sage: rising_factorial(mpz(10), mpz(3)) @@ -5197,15 +5210,15 @@ def integer_ceil(x): sage: integer_ceil(5.4) 6 - sage: integer_ceil(x) + sage: integer_ceil(x) # optional - sage.symbolic Traceback (most recent call last): ... NotImplementedError: computation of ceil of x not implemented Tests with numpy and gmpy2 numbers:: - sage: from numpy import float32 - sage: integer_ceil(float32(5.4)) + sage: from numpy import float32 # optional - numpy + sage: integer_ceil(float32(5.4)) # optional - numpy 6 sage: from gmpy2 import mpfr sage: integer_ceil(mpfr(5.4)) @@ -5243,15 +5256,15 @@ def integer_floor(x): sage: integer_floor(RDF(-5/2)) -3 - sage: integer_floor(x) + sage: integer_floor(x) # optional - sage.symbolic Traceback (most recent call last): ... NotImplementedError: computation of floor of x not implemented Tests with numpy and gmpy2 numbers:: - sage: from numpy import float32 - sage: integer_floor(float32(5.4)) + sage: from numpy import float32 # optional - numpy + sage: integer_floor(float32(5.4)) # optional - numpy 5 sage: from gmpy2 import mpfr sage: integer_floor(mpfr(5.4)) @@ -5307,11 +5320,11 @@ def two_squares(n): ValueError: 21 is not a sum of 2 squares sage: two_squares(21^2) (0, 21) - sage: a,b = two_squares(100000000000000000129); a,b + sage: a, b = two_squares(100000000000000000129); a, b # optional - sage.libs.pari (4418521500, 8970878873) - sage: a^2 + b^2 + sage: a^2 + b^2 # optional - sage.libs.pari 100000000000000000129 - sage: two_squares(2^222+1) + sage: two_squares(2^222 + 1) # optional - sage.libs.pari (253801659504708621991421712450521, 2583712713213354898490304645018692) sage: two_squares(0) (0, 0) @@ -5322,17 +5335,17 @@ def two_squares(n): TESTS:: - sage: for _ in range(100): + sage: for _ in range(100): # optional - sage.libs.pari ....: a = ZZ.random_element(2**16, 2**20) ....: b = ZZ.random_element(2**16, 2**20) ....: n = a**2 + b**2 - ....: aa,bb = two_squares(n) + ....: aa, bb = two_squares(n) ....: assert aa**2 + bb**2 == n Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: two_squares(int16(389)) + sage: from numpy import int16 # optional - numpy + sage: two_squares(int16(389)) # optional - numpy (10, 17) sage: from gmpy2 import mpz sage: two_squares(mpz(389)) @@ -5429,11 +5442,11 @@ def three_squares(n): (3, 24, 49) sage: three_squares(7^100) (0, 0, 1798465042647412146620280340569649349251249) - sage: three_squares(11^111-1) + sage: three_squares(11^111 - 1) # optional - sage.libs.pari (616274160655975340150706442680, 901582938385735143295060746161, 6270382387635744140394001363065311967964099981788593947233) - sage: three_squares(7 * 2^41) + sage: three_squares(7 * 2^41) # optional - sage.libs.pari (1048576, 2097152, 3145728) - sage: three_squares(7 * 2^42) + sage: three_squares(7 * 2^42) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: 30786325577728 is not a sum of 3 squares @@ -5446,18 +5459,18 @@ def three_squares(n): TESTS:: - sage: for _ in range(100): + sage: for _ in range(100): # optional - sage.libs.pari ....: a = ZZ.random_element(2**16, 2**20) ....: b = ZZ.random_element(2**16, 2**20) ....: c = ZZ.random_element(2**16, 2**20) ....: n = a**2 + b**2 + c**2 - ....: aa,bb,cc = three_squares(n) + ....: aa, bb, cc = three_squares(n) ....: assert aa**2 + bb**2 + cc**2 == n Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: three_squares(int16(389)) + sage: from numpy import int16 # optional - numpy + sage: three_squares(int16(389)) # optional - numpy (1, 8, 18) sage: from gmpy2 import mpz sage: three_squares(mpz(389)) @@ -5573,23 +5586,23 @@ def four_squares(n): (0, 0, 3, 11) sage: four_squares(1101011011004) (90, 102, 1220, 1049290) - sage: four_squares(10^100-1) + sage: four_squares(10^100 - 1) # optional - sage.libs.pari (155024616290, 2612183768627, 14142135623730950488016887, 99999999999999999999999999999999999999999999999999) - sage: for i in range(2^129, 2^129+10000): # long time + sage: for i in range(2^129, 2^129+10000): # long time # optional - sage.libs.pari ....: S = four_squares(i) ....: assert sum(x^2 for x in S) == i TESTS:: - sage: for _ in range(100): - ....: n = ZZ.random_element(2**32,2**34) - ....: aa,bb,cc,dd = four_squares(n) + sage: for _ in range(100): # optional - sage.libs.pari + ....: n = ZZ.random_element(2**32, 2**34) + ....: aa, bb, cc, dd = four_squares(n) ....: assert aa**2 + bb**2 + cc**2 + dd**2 == n Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: four_squares(int16(389)) + sage: from numpy import int16 # optional - numpy + sage: four_squares(int16(389)) # optional - numpy (0, 1, 8, 18) sage: from gmpy2 import mpz sage: four_squares(mpz(389)) @@ -5650,7 +5663,7 @@ def sum_of_k_squares(k, n): (1, 2, 5, 98) sage: sum_of_k_squares(5, 9634) (0, 1, 2, 5, 98) - sage: sum_of_k_squares(6, 11^1111-1) + sage: sum_of_k_squares(6, 11^1111 - 1) # optional - sage.libs.pari (19215400822645944253860920437586326284, 37204645194585992174252915693267578306, 3473654819477394665857484221256136567800161086815834297092488779216863122, 5860191799617673633547572610351797996721850737768032876360978911074629287841061578270832330322236796556721252602860754789786937515870682024273948, 20457423294558182494001919812379023992538802203730791019728543439765347851316366537094696896669915675685581905102118246887673397020172285247862426612188418787649371716686651256443143210952163970564228423098202682066311189439731080552623884051737264415984619097656479060977602722566383385989, 311628095411678159849237738619458396497534696043580912225334269371611836910345930320700816649653412141574887113710604828156159177769285115652741014638785285820578943010943846225597311231847997461959204894255074229895666356909071243390280307709880906261008237873840245959883405303580405277298513108957483306488193844321589356441983980532251051786704380984788999660195252373574924026139168936921591652831237741973242604363696352878914129671292072201700073286987126265965322808664802662993006926302359371379531571194266134916767573373504566621665949840469229781956838744551367172353) sage: sum_of_k_squares(7, 0) (0, 0, 0, 0, 0, 0, 0) @@ -5683,8 +5696,8 @@ def sum_of_k_squares(k, n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: sum_of_k_squares(int16(2), int16(9634)) + sage: from numpy import int16 # optional - numpy + sage: sum_of_k_squares(int16(2), int16(9634)) # optional - numpy (15, 97) sage: from gmpy2 import mpz sage: sum_of_k_squares(mpz(2), mpz(9634)) @@ -5755,8 +5768,8 @@ def subfactorial(n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: subfactorial(int8(8)) + sage: from numpy import int8 # optional - numpy + sage: subfactorial(int8(8)) # optional - numpy 14833 sage: from gmpy2 import mpz sage: subfactorial(mpz(8)) @@ -5796,10 +5809,10 @@ def is_power_of_two(n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: is_power_of_two(int8(16)) + sage: from numpy import int8 # optional - numpy + sage: is_power_of_two(int8(16)) # optional - numpy True - sage: is_power_of_two(int8(24)) + sage: is_power_of_two(int8(24)) # optional - numpy False sage: from gmpy2 import mpz sage: is_power_of_two(mpz(16)) @@ -5816,7 +5829,7 @@ def differences(lis, n=1): EXAMPLES:: - sage: differences(prime_range(50)) + sage: differences(prime_range(50)) # optional - sage.libs.pari [1, 2, 2, 4, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4] sage: differences([i^2 for i in range(1,11)]) [3, 5, 7, 9, 11, 13, 15, 17, 19] @@ -5824,16 +5837,16 @@ def differences(lis, n=1): [10, 22, 40, 64, 94, 130, 172, 220, 274, 334, 400, 472, 550, 634, 724, 820, 922, 1030, 1144] sage: differences([i^3 - i^2 for i in range(1,21)], 2) [10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 70, 76, 82, 88, 94, 100, 106, 112] - sage: differences([p - i^2 for i, p in enumerate(prime_range(50))], 3) + sage: differences([p - i^2 for i, p in enumerate(prime_range(50))], 3) # optional - sage.libs.pari [-1, 2, -4, 4, -4, 4, 0, -6, 8, -6, 0, 4] Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: differences([int8(1),int8(4),int8(6),int8(19)]) + sage: from numpy import int8 # optional - numpy + sage: differences([int8(1), int8(4), int8(6), int8(19)]) # optional - numpy [3, 2, 13] sage: from gmpy2 import mpz - sage: differences([mpz(1),mpz(4),mpz(6),mpz(19)]) + sage: differences([mpz(1), mpz(4), mpz(6), mpz(19)]) [mpz(3), mpz(2), mpz(13)] AUTHORS: @@ -5975,8 +5988,8 @@ def fundamental_discriminant(D): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: fundamental_discriminant(int8(102)) + sage: from numpy import int8 # optional - numpy + sage: fundamental_discriminant(int8(102)) # optional - numpy 408 sage: from gmpy2 import mpz sage: fundamental_discriminant(mpz(102)) @@ -6033,13 +6046,15 @@ def squarefree_divisors(x): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: list(squarefree_divisors(int8(12))) + sage: from numpy import int8 # optional - numpy + sage: list(squarefree_divisors(int8(12))) # optional - numpy [1, 2, 3, 6] sage: from gmpy2 import mpz sage: list(squarefree_divisors(mpz(12))) [1, 2, 3, 6] """ + from sage.combinat.subset import powerset + for a in powerset(prime_divisors(x)): yield prod(a, ZZ.one()) @@ -6084,7 +6099,7 @@ def dedekind_sum(p, q, algorithm='default'): Several small values:: - sage: for q in range(10): print([dedekind_sum(p,q) for p in range(q+1)]) + sage: for q in range(10): print([dedekind_sum(p,q) for p in range(q+1)]) # optional - sage.libs.flint [0] [0, 0] [0, 0, 0] @@ -6098,44 +6113,44 @@ def dedekind_sum(p, q, algorithm='default'): Check relations for restricted arguments:: - sage: q = 23; dedekind_sum(1, q); (q-1)*(q-2)/(12*q) + sage: q = 23; dedekind_sum(1, q); (q-1)*(q-2)/(12*q) # optional - sage.libs.flint 77/46 77/46 sage: p, q = 100, 723 # must be coprime - sage: dedekind_sum(p, q) + dedekind_sum(q, p) + sage: dedekind_sum(p, q) + dedekind_sum(q, p) # optional - sage.libs.flint 31583/86760 - sage: -1/4 + (p/q + q/p + 1/(p*q))/12 + sage: -1/4 + (p/q + q/p + 1/(p*q))/12 # optional - sage.libs.flint 31583/86760 We check that evaluation works with large input:: - sage: dedekind_sum(3^54 - 1, 2^93 + 1) + sage: dedekind_sum(3^54 - 1, 2^93 + 1) # optional - sage.libs.flint 459340694971839990630374299870/29710560942849126597578981379 - sage: dedekind_sum(3^54 - 1, 2^93 + 1, algorithm='pari') + sage: dedekind_sum(3^54 - 1, 2^93 + 1, algorithm='pari') # optional - sage.libs.pari 459340694971839990630374299870/29710560942849126597578981379 We check consistency of the results:: - sage: dedekind_sum(5, 7, algorithm='default') + sage: dedekind_sum(5, 7, algorithm='default') # optional - sage.libs.flint -1/14 - sage: dedekind_sum(5, 7, algorithm='flint') + sage: dedekind_sum(5, 7, algorithm='flint') # optional - sage.libs.flint -1/14 - sage: dedekind_sum(5, 7, algorithm='pari') + sage: dedekind_sum(5, 7, algorithm='pari') # optional - sage.libs.pari -1/14 - sage: dedekind_sum(6, 8, algorithm='default') + sage: dedekind_sum(6, 8, algorithm='default') # optional - sage.libs.flint -1/8 - sage: dedekind_sum(6, 8, algorithm='flint') + sage: dedekind_sum(6, 8, algorithm='flint') # optional - sage.libs.flint -1/8 - sage: dedekind_sum(6, 8, algorithm='pari') + sage: dedekind_sum(6, 8, algorithm='pari') # optional - sage.libs.pari -1/8 Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: dedekind_sum(int8(5), int8(7), algorithm='default') + sage: from numpy import int8 # optional - numpy + sage: dedekind_sum(int8(5), int8(7), algorithm='default') # optional - numpy sage.libs.flint -1/14 sage: from gmpy2 import mpz - sage: dedekind_sum(mpz(5), mpz(7), algorithm='default') + sage: dedekind_sum(mpz(5), mpz(7), algorithm='default') # optional - sage.libs.flint -1/14 REFERENCES: @@ -6194,45 +6209,45 @@ def gauss_sum(char_value, finite_field): EXAMPLES:: sage: from sage.arith.misc import gauss_sum - sage: F = GF(5); q = 5 - sage: zq = UniversalCyclotomicField().zeta(q-1) - sage: L = [gauss_sum(zq**i,F) for i in range(5)]; L + sage: F = GF(5); q = 5 # optional - sage.libs.pari + sage: zq = UniversalCyclotomicField().zeta(q - 1) # optional - sage.libs.pari + sage: L = [gauss_sum(zq**i, F) for i in range(5)]; L # optional - sage.libs.pari [-1, E(20)^4 + E(20)^13 - E(20)^16 - E(20)^17, E(5) - E(5)^2 - E(5)^3 + E(5)^4, E(20)^4 - E(20)^13 - E(20)^16 + E(20)^17, -1] - sage: [g*g.conjugate() for g in L] + sage: [g*g.conjugate() for g in L] # optional - sage.libs.pari [1, 5, 5, 5, 1] - sage: F = GF(11**2); q = 11**2 - sage: zq = UniversalCyclotomicField().zeta(q-1) - sage: g = gauss_sum(zq**4,F) - sage: g*g.conjugate() + sage: F = GF(11**2); q = 11**2 # optional - sage.libs.pari + sage: zq = UniversalCyclotomicField().zeta(q - 1) # optional - sage.libs.pari + sage: g = gauss_sum(zq**4, F) # optional - sage.libs.pari + sage: g*g.conjugate() # optional - sage.libs.pari 121 TESTS:: - sage: F = GF(11); q = 11 - sage: zq = UniversalCyclotomicField().zeta(q-1) - sage: gauss_sum(zq**2,F).n(60) + sage: F = GF(11); q = 11 # optional - sage.libs.pari sage.rings.number_field + sage: zq = UniversalCyclotomicField().zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field + sage: gauss_sum(zq**2, F).n(60) # optional - sage.libs.pari sage.rings.number_field 2.6361055643248352 + 2.0126965627574471*I - sage: zq = QQbar.zeta(q-1) - sage: gauss_sum(zq**2,F) + sage: zq = QQbar.zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field + sage: gauss_sum(zq**2, F) # optional - sage.libs.pari sage.rings.number_field 2.636105564324836? + 2.012696562757447?*I - sage: zq = ComplexField(60).zeta(q-1) - sage: gauss_sum(zq**2,F) + sage: zq = ComplexField(60).zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field + sage: gauss_sum(zq**2, F) # optional - sage.libs.pari sage.rings.number_field 2.6361055643248352 + 2.0126965627574471*I - sage: F = GF(7); q = 7 - sage: zq = QQbar.zeta(q-1) - sage: D = DirichletGroup(7, QQbar) - sage: all(D[i].gauss_sum()==gauss_sum(zq**i,F) for i in range(6)) + sage: F = GF(7); q = 7 # optional - sage.libs.pari sage.rings.number_field + sage: zq = QQbar.zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field + sage: D = DirichletGroup(7, QQbar) # optional - sage.libs.pari sage.rings.number_field + sage: all(D[i].gauss_sum() == gauss_sum(zq**i, F) for i in range(6)) # optional - sage.libs.pari sage.rings.number_field True - sage: gauss_sum(1,QQ) + sage: gauss_sum(1, QQ) Traceback (most recent call last): ... ValueError: second input must be a finite field diff --git a/src/sage/arith/multi_modular.pyx b/src/sage/arith/multi_modular.pyx index 766c9923404..17505583fca 100644 --- a/src/sage/arith/multi_modular.pyx +++ b/src/sage/arith/multi_modular.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - primecountpy """ Utility classes for multi-modular algorithms """ diff --git a/src/sage/calculus/all.py b/src/sage/calculus/all.py index bc93e3f62a7..caaaa30e1fb 100644 --- a/src/sage/calculus/all.py +++ b/src/sage/calculus/all.py @@ -1,34 +1,12 @@ +from .all__sagemath_standard_no_symbolics import * from .calculus import maxima as maxima_calculus from .calculus import (laplace, inverse_laplace, limit, lim) -from .integration import numerical_integral, monte_carlo_integral -integral_numerical = numerical_integral - -from .interpolation import spline, Spline - -from .functional import (diff, derivative, - expand, - taylor, simplify) - -from .functions import (wronskian,jacobian) - -from .ode import ode_solver, ode_system - -from .desolvers import (desolve, desolve_laplace, desolve_system, - eulers_method, eulers_method_2x2, - eulers_method_2x2_plot, desolve_rk4, desolve_system_rk4, - desolve_odeint, desolve_mintides, desolve_tides_mpfr) - +from .functional import expand, simplify from .var import (var, function, clear_vars) -from .transforms.all import * - -# We lazy_import the following modules since they import numpy which slows down sage startup -from sage.misc.lazy_import import lazy_import -lazy_import("sage.calculus.riemann",["Riemann_Map"]) -lazy_import("sage.calculus.interpolators",["polygon_spline","complex_cubic_spline"]) from sage.modules.free_module_element import vector from sage.matrix.constructor import matrix diff --git a/src/sage/calculus/all__sagemath_standard_no_symbolics.py b/src/sage/calculus/all__sagemath_standard_no_symbolics.py new file mode 100644 index 00000000000..a43c67fad32 --- /dev/null +++ b/src/sage/calculus/all__sagemath_standard_no_symbolics.py @@ -0,0 +1,22 @@ +from .integration import numerical_integral, monte_carlo_integral +integral_numerical = numerical_integral + +from .interpolation import spline, Spline + +from .functional import diff, derivative, taylor + +from .functions import wronskian, jacobian + +from .ode import ode_solver, ode_system + +from .desolvers import (desolve, desolve_laplace, desolve_system, + eulers_method, eulers_method_2x2, + eulers_method_2x2_plot, desolve_rk4, desolve_system_rk4, + desolve_odeint, desolve_mintides, desolve_tides_mpfr) + +from .transforms.all import * + +# We lazy_import the following modules since they import numpy which slows down sage startup +from sage.misc.lazy_import import lazy_import +lazy_import("sage.calculus.riemann",["Riemann_Map"]) +lazy_import("sage.calculus.interpolators",["polygon_spline","complex_cubic_spline"]) diff --git a/src/sage/calculus/riemann.pyx b/src/sage/calculus/riemann.pyx index 4dc18b964f2..b7969a8c4c2 100644 --- a/src/sage/calculus/riemann.pyx +++ b/src/sage/calculus/riemann.pyx @@ -1190,10 +1190,11 @@ cpdef complex_to_spiderweb(np.ndarray[COMPLEX_T, ndim = 2] z_values, EXAMPLES:: sage: from sage.calculus.riemann import complex_to_spiderweb - sage: import numpy - sage: zval = numpy.array([[0, 1, 1000],[.2+.3j,1,-.3j],[0,0,0]],dtype = numpy.complex128) - sage: deriv = numpy.array([[.1]],dtype = numpy.float64) - sage: complex_to_spiderweb(zval, deriv,deriv, 4,4,[0,0,0],1,False,0.001) + sage: import numpy # optional - numpy + sage: zval = numpy.array([[0,1,1000], [.2+.3j,1,-.3j], [0,0,0]], # optional - numpy + ....: dtype=numpy.complex128) + sage: deriv = numpy.array([[.1]],dtype = numpy.float64) # optional - numpy + sage: complex_to_spiderweb(zval, deriv, deriv, 4, 4, [0,0,0], 1, False, 0.001) # optional - numpy array([[[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]], @@ -1206,7 +1207,7 @@ cpdef complex_to_spiderweb(np.ndarray[COMPLEX_T, ndim = 2] z_values, [1., 1., 1.], [1., 1., 1.]]]) - sage: complex_to_spiderweb(zval, deriv,deriv, 4,4,[0,0,0],1,True,0.001) + sage: complex_to_spiderweb(zval, deriv, deriv, 4, 4, [0,0,0], 1, True, 0.001) # optional - numpy array([[[1. , 1. , 1. ], [1. , 0.05558355, 0.05558355], [0.17301243, 0. , 0. ]], @@ -1280,13 +1281,13 @@ cpdef complex_to_rgb(np.ndarray[COMPLEX_T, ndim = 2] z_values): EXAMPLES:: sage: from sage.calculus.riemann import complex_to_rgb - sage: import numpy - sage: complex_to_rgb(numpy.array([[0, 1, 1000]], dtype = numpy.complex128)) + sage: import numpy # optional - numpy + sage: complex_to_rgb(numpy.array([[0, 1, 1000]], dtype=numpy.complex128)) # optional - numpy array([[[1. , 1. , 1. ], [1. , 0.05558355, 0.05558355], [0.17301243, 0. , 0. ]]]) - sage: complex_to_rgb(numpy.array([[0, 1j, 1000j]], dtype = numpy.complex128)) + sage: complex_to_rgb(numpy.array([[0, 1j, 1000j]], dtype=numpy.complex128)) # optional - numpy array([[[1. , 1. , 1. ], [0.52779177, 1. , 0.05558355], [0.08650622, 0.17301243, 0. ]]]) diff --git a/src/sage/calculus/test_sympy.py b/src/sage/calculus/test_sympy.py index 927e6ee4fb6..a1db950bf10 100644 --- a/src/sage/calculus/test_sympy.py +++ b/src/sage/calculus/test_sympy.py @@ -102,98 +102,98 @@ And here are some actual tests of sympy:: - sage: from sympy import Symbol, cos, sympify, pprint - sage: from sympy.abc import x + sage: from sympy import Symbol, cos, sympify, pprint # optional - sympy + sage: from sympy.abc import x # optional - sympy :: - sage: e = (1/cos(x)^3)._sympy_(); e + sage: e = (1/cos(x)^3)._sympy_(); e # optional - sympy cos(x)**(-3) - sage: f = e.series(x, 0, int(10)); f + sage: f = e.series(x, 0, int(10)); f # optional - sympy 1 + 3*x**2/2 + 11*x**4/8 + 241*x**6/240 + 8651*x**8/13440 + O(x**10) And the pretty-printer. Since unicode characters are not working on some architectures, we disable it:: - sage: from sympy.printing import pprint_use_unicode - sage: prev_use = pprint_use_unicode(False) - sage: pprint(e) + sage: from sympy.printing import pprint_use_unicode # optional - sympy + sage: prev_use = pprint_use_unicode(False) # optional - sympy + sage: pprint(e) # optional - sympy 1 ------- 3 cos (x) - sage: pprint(f) + sage: pprint(f) # optional - sympy 2 4 6 8 3*x 11*x 241*x 8651*x / 10\ 1 + ---- + ----- + ------ + ------- + O\x / 2 8 240 13440 - sage: pprint_use_unicode(prev_use) + sage: pprint_use_unicode(prev_use) # optional - sympy False And the functionality to convert from sympy format to Sage format:: - sage: e._sage_() + sage: e._sage_() # optional - sympy cos(x)^(-3) - sage: e._sage_().taylor(x._sage_(), 0, 8) + sage: e._sage_().taylor(x._sage_(), 0, 8) # optional - sympy 8651/13440*x^8 + 241/240*x^6 + 11/8*x^4 + 3/2*x^2 + 1 - sage: f._sage_() + sage: f._sage_() # optional - sympy 8651/13440*x^8 + 241/240*x^6 + 11/8*x^4 + 3/2*x^2 + Order(x^10) + 1 Mixing SymPy with Sage:: - sage: import sympy - sage: var("x")._sympy_() + var("y")._sympy_() + sage: import sympy # optional - sympy + sage: var("x")._sympy_() + var("y")._sympy_() # optional - sympy x + y - sage: o = var("omega") - sage: s = sympy.Symbol("x") - sage: t1 = s + o - sage: t2 = o + s - sage: type(t1) + sage: o = var("omega") # optional - sympy + sage: s = sympy.Symbol("x") # optional - sympy + sage: t1 = s + o # optional - sympy + sage: t2 = o + s # optional - sympy + sage: type(t1) # optional - sympy - sage: type(t2) + sage: type(t2) # optional - sympy - sage: t1, t2 + sage: t1, t2 # optional - sympy (omega + x, omega + x) - sage: e=sympy.sin(var("y"))+sage.all.cos(sympy.Symbol("x")) - sage: type(e) + sage: e = sympy.sin(var("y"))+sage.all.cos(sympy.Symbol("x")) # optional - sympy + sage: type(e) # optional - sympy - sage: e + sage: e # optional - sympy sin(y) + cos(x) - sage: e=e._sage_() - sage: type(e) + sage: e=e._sage_() # optional - sympy + sage: type(e) # optional - sympy - sage: e + sage: e # optional - sympy cos(x) + sin(y) - sage: e = sage.all.cos(var("y")**3)**4+var("x")**2 - sage: e = e._sympy_() - sage: e + sage: e = sage.all.cos(var("y")**3)**4+var("x")**2 # optional - sympy + sage: e = e._sympy_() # optional - sympy + sage: e # optional - sympy x**2 + cos(y**3)**4 :: - sage: a = sympy.Matrix([1, 2, 3]) - sage: a[1] + sage: a = sympy.Matrix([1, 2, 3]) # optional - sympy + sage: a[1] # optional - sympy 2 :: - sage: sympify(1.5) + sage: sympify(1.5) # optional - sympy 1.50000000000000 - sage: sympify(2) + sage: sympify(2) # optional - sympy 2 - sage: sympify(-2) + sage: sympify(-2) # optional - sympy -2 TESTS: This was fixed in Sympy, see :trac:`14437`:: - sage: from sympy import Function, Symbol, rsolve - sage: u = Function('u') - sage: n = Symbol('n', integer=True) - sage: f = u(n+2) - u(n+1) + u(n)/4 - sage: expand(2**n * rsolve(f,u(n))) + sage: from sympy import Function, Symbol, rsolve # optional - sympy + sage: u = Function('u') # optional - sympy + sage: n = Symbol('n', integer=True) # optional - sympy + sage: f = u(n+2) - u(n+1) + u(n)/4 # optional - sympy + sage: expand(2**n * rsolve(f,u(n))) # optional - sympy 2*C1*n + C0 """ diff --git a/src/sage/categories/action.pyx b/src/sage/categories/action.pyx index 0c82d6cfe08..b90d97e0f02 100644 --- a/src/sage/categories/action.pyx +++ b/src/sage/categories/action.pyx @@ -21,7 +21,8 @@ A group action `G \times S \rightarrow S` is a functor from `G` to Sets. sage: import gc sage: _ = gc.collect() sage: A - ) failed: RuntimeError: This action acted on a set that became garbage collected> + ) failed: + RuntimeError: This action acted on a set that became garbage collected> To avoid garbage collection of the underlying set, it is sufficient to create a strong reference to it before the action is created. @@ -265,15 +266,17 @@ cdef class Action(Functor): sage: R = (ZZ['x'])['y'] sage: A = R.get_action(P,operator.mul,True) sage: A # indirect doctest - Right scalar multiplication by Univariate Polynomial Ring in x over - Rational Field on Univariate Polynomial Ring in y over Univariate - Polynomial Ring in x over Integer Ring + Right scalar multiplication + by Univariate Polynomial Ring in x over Rational Field + on Univariate Polynomial Ring in y over + Univariate Polynomial Ring in x over Integer Ring In this example, the underlying set is the ring ``R``. This is the same as the left domain, which is different from the codomain of the action:: sage: A.codomain() - Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + Univariate Polynomial Ring in y + over Univariate Polynomial Ring in x over Rational Field sage: A.codomain() == R False sage: A.left_domain() is R @@ -294,7 +297,8 @@ cdef class Action(Functor): sage: import gc sage: _ = gc.collect() sage: A - ) failed: RuntimeError: This action acted on a set that became garbage collected> + ) failed: + RuntimeError: This action acted on a set that became garbage collected> """ S = self.US() if S is None: @@ -329,24 +333,28 @@ cdef class InverseAction(Action): EXAMPLES:: - sage: V = QQ^3 - sage: v = V((1, 2, 3)) + sage: V = QQ^3 # optional - sage.modules + sage: v = V((1, 2, 3)) # optional - sage.modules sage: cm = get_coercion_model() - sage: a = cm.get_action(V, QQ, operator.mul) - sage: a - Right scalar multiplication by Rational Field on Vector space of dimension 3 over Rational Field - sage: ~a - Right inverse action by Rational Field on Vector space of dimension 3 over Rational Field - sage: (~a)(v, 1/3) + sage: a = cm.get_action(V, QQ, operator.mul) # optional - sage.modules + sage: a # optional - sage.modules + Right scalar multiplication by Rational Field + on Vector space of dimension 3 over Rational Field + sage: ~a # optional - sage.modules + Right inverse action by Rational Field + on Vector space of dimension 3 over Rational Field + sage: (~a)(v, 1/3) # optional - sage.modules (3, 6, 9) - sage: b = cm.get_action(QQ, V, operator.mul) - sage: b - Left scalar multiplication by Rational Field on Vector space of dimension 3 over Rational Field - sage: ~b - Left inverse action by Rational Field on Vector space of dimension 3 over Rational Field - sage: (~b)(1/3, v) + sage: b = cm.get_action(QQ, V, operator.mul) # optional - sage.modules + sage: b # optional - sage.modules + Left scalar multiplication by Rational Field + on Vector space of dimension 3 over Rational Field + sage: ~b # optional - sage.modules + Left inverse action by Rational Field + on Vector space of dimension 3 over Rational Field + sage: (~b)(1/3, v) # optional - sage.modules (3, 6, 9) sage: c = cm.get_action(ZZ, list, operator.mul) @@ -390,11 +398,11 @@ cdef class InverseAction(Action): Check that this action can be pickled (:trac:`29031`):: - sage: V = QQ^3 - sage: v = V((1, 2, 3)) - sage: cm = get_coercion_model() - sage: a = cm.get_action(V, QQ, operator.mul) - sage: loads(dumps(~a)) is not None + sage: V = QQ^3 # optional - sage.modules + sage: v = V((1, 2, 3)) # optional - sage.modules + sage: cm = get_coercion_model() # optional - sage.modules + sage: a = cm.get_action(V, QQ, operator.mul) # optional - sage.modules + sage: loads(dumps(~a)) is not None # optional - sage.modules True """ return (type(self), (self._action,)) @@ -434,8 +442,9 @@ cdef class PrecomposedAction(Action): sage: c,x = v[0] sage: y = x.modular_symbol_rep() sage: coercion_model.get_action(QQ, parent(y), op=operator.mul) - Left scalar multiplication by Rational Field on Abelian Group of all Formal Finite Sums over Rational Field - with precomposition on right by Coercion map: + Left scalar multiplication by Rational Field + on Abelian Group of all Formal Finite Sums over Rational Field + with precomposition on right by Coercion map: From: Abelian Group of all Formal Finite Sums over Integer Ring To: Abelian Group of all Formal Finite Sums over Rational Field """ @@ -542,8 +551,8 @@ cdef class ActionEndomorphism(Morphism): sage: A = ZZ['x'].get_action(QQ, self_on_left=False, op=operator.mul) sage: A - Left scalar multiplication by Rational Field on Univariate Polynomial - Ring in x over Integer Ring + Left scalar multiplication by Rational Field + on Univariate Polynomial Ring in x over Integer Ring sage: A(1/2) Action of 1/2 on Univariate Polynomial Ring in x over Integer Ring under Left scalar multiplication by Rational Field on Univariate diff --git a/src/sage/categories/additive_magmas.py b/src/sage/categories/additive_magmas.py index 8d2c46d0771..52c97ce71e3 100644 --- a/src/sage/categories/additive_magmas.py +++ b/src/sage/categories/additive_magmas.py @@ -33,7 +33,10 @@ class AdditiveMagmas(Category_singleton): sage: AdditiveMagmas().super_categories() [Category of sets] sage: AdditiveMagmas().all_super_categories() - [Category of additive magmas, Category of sets, Category of sets with partial maps, Category of objects] + [Category of additive magmas, + Category of sets, + Category of sets with partial maps, + Category of objects] The following axioms are defined by this category:: @@ -45,11 +48,11 @@ class AdditiveMagmas(Category_singleton): Category of additive commutative additive magmas sage: AdditiveMagmas().AdditiveUnital().AdditiveInverse() Category of additive inverse additive unital additive magmas - sage: AdditiveMagmas().AdditiveAssociative().AdditiveCommutative() + sage: C = AdditiveMagmas().AdditiveAssociative().AdditiveCommutative(); C Category of commutative additive semigroups - sage: AdditiveMagmas().AdditiveAssociative().AdditiveCommutative().AdditiveUnital() + sage: C.AdditiveUnital() Category of commutative additive monoids - sage: AdditiveMagmas().AdditiveAssociative().AdditiveCommutative().AdditiveUnital().AdditiveInverse() + sage: C.AdditiveUnital().AdditiveInverse() Category of commutative additive groups TESTS:: @@ -112,9 +115,10 @@ def AdditiveCommutative(self): sage: AdditiveMagmas().AdditiveCommutative() Category of additive commutative additive magmas - sage: AdditiveMagmas().AdditiveAssociative().AdditiveUnital().AdditiveCommutative() + sage: C = AdditiveMagmas().AdditiveAssociative().AdditiveUnital() + sage: C.AdditiveCommutative() Category of commutative additive monoids - sage: _ is CommutativeAdditiveMonoids() + sage: C.AdditiveCommutative() is CommutativeAdditiveMonoids() True TESTS:: @@ -279,7 +283,7 @@ def addition_table(self, names='letters', elements=None): elements as lowercase ASCII letters. :: sage: R = IntegerModRing(5) - sage: R.addition_table() + sage: R.addition_table() # optional - sage.modules + a b c d e +---------- a| a b c d e @@ -294,8 +298,7 @@ def addition_table(self, names='letters', elements=None): ``digits`` will include leading zeros as padding. :: sage: R = IntegerModRing(11) - sage: P = R.addition_table(names='elements') - sage: P + sage: P = R.addition_table(names='elements'); P # optional - sage.modules + 0 1 2 3 4 5 6 7 8 9 10 +--------------------------------- 0| 0 1 2 3 4 5 6 7 8 9 10 @@ -310,8 +313,7 @@ def addition_table(self, names='letters', elements=None): 9| 9 10 0 1 2 3 4 5 6 7 8 10| 10 0 1 2 3 4 5 6 7 8 9 - sage: T = R.addition_table(names='digits') - sage: T + sage: T = R.addition_table(names='digits'); T # optional - sage.modules + 00 01 02 03 04 05 06 07 08 09 10 +--------------------------------- 00| 00 01 02 03 04 05 06 07 08 09 10 @@ -331,7 +333,7 @@ def addition_table(self, names='letters', elements=None): sage: S = IntegerModRing(7) sage: elts = [0, 3, 6, 2, 5, 1, 4] - sage: S.addition_table(elements=elts) + sage: S.addition_table(elements=elts) # optional - sage.modules + a b c d e f g +-------------- a| a b c d e f g @@ -351,8 +353,8 @@ def addition_table(self, names='letters', elements=None): representation. :: sage: T = IntegerModRing(12) - sage: elts=[0, 3, 6, 9] - sage: T.addition_table(names='elements', elements=elts) + sage: elts = [0, 3, 6, 9] + sage: T.addition_table(names='elements', elements=elts) # optional - sage.modules + 0 3 6 9 +-------- 0| 0 3 6 9 @@ -366,15 +368,15 @@ def addition_table(self, names='letters', elements=None): comprehensive documentation. :: sage: R = IntegerModRing(3) - sage: T = R.addition_table() - sage: T.column_keys() + sage: T = R.addition_table() # optional - sage.modules + sage: T.column_keys() # optional - sage.modules (0, 1, 2) - sage: sorted(T.translation().items()) + sage: sorted(T.translation().items()) # optional - sage.modules [('a', 0), ('b', 1), ('c', 2)] - sage: T.change_names(['x', 'y', 'z']) - sage: sorted(T.translation().items()) + sage: T.change_names(['x', 'y', 'z']) # optional - sage.modules + sage: sorted(T.translation().items()) # optional - sage.modules [('x', 0), ('y', 1), ('z', 2)] - sage: T + sage: T # optional - sage.modules + x y z +------ x| x y z @@ -471,16 +473,16 @@ def _add_(self, right): r""" EXAMPLES:: - sage: G5=GF(5); G8=GF(4,'x'); GG = G5.cartesian_product(G8) - sage: e = GG((G5(1),G8.primitive_element())); e + sage: G5 = GF(5); G8 = GF(4, 'x'); GG = G5.cartesian_product(G8) # optional - sage.rings.finite_rings + sage: e = GG((G5(1), G8.primitive_element())); e # optional - sage.rings.finite_rings (1, x) - sage: e+e + sage: e + e # optional - sage.rings.finite_rings (2, 0) - sage: e = groups.misc.AdditiveCyclic(8) - sage: x = e.cartesian_product(e)((e(1),e(2))) - sage: x + sage: e = groups.misc.AdditiveCyclic(8) # optional - sage.rings.finite_rings + sage: x = e.cartesian_product(e)((e(1), e(2))) # optional - sage.rings.finite_rings + sage: x # optional - sage.rings.finite_rings (1, 2) - sage: 4*x + sage: 4 * x # optional - sage.rings.finite_rings (4, 0) """ return self.parent()._cartesian_product_of_elements( @@ -497,7 +499,8 @@ def extra_super_categories(self): [Category of magmatic algebras with basis over Rational Field] sage: AdditiveMagmas().Algebras(QQ).super_categories() - [Category of magmatic algebras with basis over Rational Field, Category of set algebras over Rational Field] + [Category of magmatic algebras with basis over Rational Field, + Category of set algebras over Rational Field] """ from sage.categories.magmatic_algebras import MagmaticAlgebras return [MagmaticAlgebras(self.base_ring()).WithBasis()] @@ -516,9 +519,10 @@ def algebra_generators(self): EXAMPLES:: sage: S = CommutativeAdditiveSemigroups().example(); S - An example of a commutative semigroup: the free commutative semigroup generated by ('a', 'b', 'c', 'd') - sage: A = S.algebra(QQ) - sage: A.algebra_generators() + An example of a commutative semigroup: + the free commutative semigroup generated by ('a', 'b', 'c', 'd') + sage: A = S.algebra(QQ) # optional - sage.modules + sage: A.algebra_generators() # optional - sage.modules Family (B[a], B[b], B[c], B[d]) .. TODO:: @@ -541,10 +545,11 @@ def product_on_basis(self, g1, g2): EXAMPLES:: sage: S = CommutativeAdditiveSemigroups().example(); S - An example of a commutative semigroup: the free commutative semigroup generated by ('a', 'b', 'c', 'd') - sage: A = S.algebra(QQ) - sage: a,b,c,d = A.algebra_generators() - sage: a * d * b + An example of a commutative semigroup: + the free commutative semigroup generated by ('a', 'b', 'c', 'd') + sage: A = S.algebra(QQ) # optional - sage.modules + sage: a, b, c, d = A.algebra_generators() # optional - sage.modules + sage: a * d * b # optional - sage.modules B[a + b + d] .. TODO:: @@ -580,10 +585,11 @@ def extra_super_categories(self): EXAMPLES:: - sage: AdditiveMagmas().AdditiveCommutative().Algebras(QQ).extra_super_categories() + sage: C = AdditiveMagmas().AdditiveCommutative().Algebras(QQ) + sage: C.extra_super_categories() [Category of commutative magmas] - sage: AdditiveMagmas().AdditiveCommutative().Algebras(QQ).super_categories() + sage: C.super_categories() [Category of additive magma algebras over Rational Field, Category of commutative magmas] """ @@ -718,10 +724,10 @@ def is_empty(self): EXAMPLES:: - sage: A = AdditiveAbelianGroup([3,3]) - sage: A in AdditiveMagmas() + sage: A = AdditiveAbelianGroup([3, 3]) # optional - sage.groups + sage: A in AdditiveMagmas() # optional - sage.groups True - sage: A.is_empty() + sage: A.is_empty() # optional - sage.groups False sage: B = CommutativeAdditiveMonoids().example() @@ -733,7 +739,7 @@ def is_empty(self): We check that the method ``is_empty`` is inherited from this category in both examples above:: - sage: A.is_empty.__module__ + sage: A.is_empty.__module__ # optional - sage.groups 'sage.categories.additive_magmas' sage: B.is_empty.__module__ 'sage.categories.additive_magmas' @@ -801,17 +807,17 @@ def _sub_(left, right): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a','b']) - sage: a,b = F.basis() - sage: a - b + sage: F = CombinatorialFreeModule(QQ, ['a', 'b']) # optional - sage.modules + sage: a, b = F.basis() # optional - sage.modules + sage: a - b # optional - sage.modules B['a'] - B['b'] TESTS: Check that :trac:`18275` is fixed:: - sage: C = GF(5).cartesian_product(GF(5)) - sage: C.one() - C.one() + sage: C = GF(5).cartesian_product(GF(5)) # optional - sage.rings.finite_rings + sage: C.one() - C.one() # optional - sage.rings.finite_rings (0, 0) """ return left + (-right) @@ -827,21 +833,21 @@ def __neg__(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a','b']) - sage: a,b = F.basis() - sage: - b + sage: F = CombinatorialFreeModule(QQ, ['a', 'b']) # optional - sage.modules + sage: a, b = F.basis() # optional - sage.modules + sage: -b # optional - sage.modules -B['b'] TESTS:: - sage: F = CombinatorialFreeModule(ZZ, ['a','b']) - sage: a,b = F.gens() - sage: FF = cartesian_product((F,F)) - sage: x = cartesian_product([a,2*a-3*b]) ; x + sage: F = CombinatorialFreeModule(ZZ, ['a', 'b']) # optional - sage.modules + sage: a, b = F.gens() # optional - sage.modules + sage: FF = cartesian_product((F, F)) # optional - sage.modules + sage: x = cartesian_product([a, 2*a-3*b]); x # optional - sage.modules B[(0, 'a')] + 2*B[(1, 'a')] - 3*B[(1, 'b')] - sage: x.parent() is FF + sage: x.parent() is FF # optional - sage.modules True - sage: -x + sage: -x # optional - sage.modules -B[(0, 'a')] - 2*B[(1, 'a')] + 3*B[(1, 'b')] """ return self._neg_() @@ -911,14 +917,15 @@ def _neg_(self): EXAMPLES:: - sage: x = cartesian_product((GF(7)(2),17)) ; x + sage: x = cartesian_product((GF(7)(2), 17)); x # optional - sage.rings.finite_rings (2, 17) - sage: -x + sage: -x # optional - sage.rings.finite_rings (5, -17) TESTS:: - sage: x.parent() in AdditiveMagmas().AdditiveUnital().AdditiveInverse().CartesianProducts() + sage: C = AdditiveMagmas().AdditiveUnital().AdditiveInverse().CartesianProducts() + sage: x.parent() in C # optional - sage.rings.finite_rings True """ return self.parent()._cartesian_product_of_elements( @@ -947,7 +954,7 @@ def zero(self): EXAMPLES:: - sage: GF(8,'x').cartesian_product(GF(5)).zero() + sage: GF(8, 'x').cartesian_product(GF(5)).zero() # optional - sage.rings.finite_rings (0, 0) """ return self._cartesian_product_of_elements( @@ -964,7 +971,8 @@ def extra_super_categories(self): [Category of unital magmas] sage: C.super_categories() - [Category of unital algebras with basis over Rational Field, Category of additive magma algebras over Rational Field] + [Category of unital algebras with basis over Rational Field, + Category of additive magma algebras over Rational Field] """ from sage.categories.magmas import Magmas return [Magmas().Unital()] @@ -982,13 +990,14 @@ def one_basis(self): EXAMPLES:: sage: S = CommutativeAdditiveMonoids().example(); S - An example of a commutative monoid: the free commutative monoid generated by ('a', 'b', 'c', 'd') - sage: A = S.algebra(ZZ) - sage: A.one_basis() + An example of a commutative monoid: + the free commutative monoid generated by ('a', 'b', 'c', 'd') + sage: A = S.algebra(ZZ) # optional - sage.modules + sage: A.one_basis() # optional - sage.modules 0 - sage: A.one() + sage: A.one() # optional - sage.modules B[0] - sage: A(3) + sage: A(3) # optional - sage.modules 3*B[0] """ return self.basis().keys().zero() @@ -1007,17 +1016,17 @@ def zero(self): EXAMPLES:: - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat The subset algebra of {1, 2, 3} over Rational Field - sage: A.zero.__module__ + sage: A.zero.__module__ # optional - sage.combinat 'sage.categories.additive_magmas' - sage: A.zero() + sage: A.zero() # optional - sage.combinat 0 TESTS:: - sage: A.zero() is A.a_realization().zero() + sage: A.zero() is A.a_realization().zero() # optional - sage.combinat True - sage: A._test_zero() + sage: A._test_zero() # optional - sage.combinat """ return self.a_realization().zero() diff --git a/src/sage/categories/additive_semigroups.py b/src/sage/categories/additive_semigroups.py index 0527867154b..667e27eb1e9 100644 --- a/src/sage/categories/additive_semigroups.py +++ b/src/sage/categories/additive_semigroups.py @@ -150,9 +150,10 @@ def algebra_generators(self): EXAMPLES:: sage: S = CommutativeAdditiveSemigroups().example(); S - An example of a commutative semigroup: the free commutative semigroup generated by ('a', 'b', 'c', 'd') - sage: A = S.algebra(QQ) - sage: A.algebra_generators() + An example of a commutative semigroup: + the free commutative semigroup generated by ('a', 'b', 'c', 'd') + sage: A = S.algebra(QQ) # optional - sage.modules + sage: A.algebra_generators() # optional - sage.modules Family (B[a], B[b], B[c], B[d]) """ return self.basis().keys().additive_semigroup_generators().map(self.monomial) @@ -169,10 +170,11 @@ def product_on_basis(self, g1, g2): EXAMPLES:: sage: S = CommutativeAdditiveSemigroups().example(); S - An example of a commutative semigroup: the free commutative semigroup generated by ('a', 'b', 'c', 'd') - sage: A = S.algebra(QQ) - sage: a,b,c,d = A.algebra_generators() - sage: b * d * c + An example of a commutative semigroup: + the free commutative semigroup generated by ('a', 'b', 'c', 'd') + sage: A = S.algebra(QQ) # optional - sage.modules + sage: a, b, c, d = A.algebra_generators() # optional - sage.modules + sage: b * d * c # optional - sage.modules B[b + c + d] """ return self.monomial(g1 + g2) diff --git a/src/sage/categories/affine_weyl_groups.py b/src/sage/categories/affine_weyl_groups.py index 6bc26562b8e..3df85b07415 100644 --- a/src/sage/categories/affine_weyl_groups.py +++ b/src/sage/categories/affine_weyl_groups.py @@ -34,9 +34,9 @@ class AffineWeylGroups(Category_singleton): sage: C.example() NotImplemented - sage: W = WeylGroup(["A",4,1]); W + sage: W = WeylGroup(["A", 4, 1]); W # optional - sage.combinat sage.groups Weyl Group of type ['A', 4, 1] (as a matrix group acting on the root space) - sage: W.category() + sage: W.category() # optional - sage.combinat sage.groups Category of irreducible affine weyl groups TESTS:: @@ -81,8 +81,8 @@ def special_node(self): EXAMPLES:: - sage: W = WeylGroup(['A',3,1]) - sage: W.special_node() + sage: W = WeylGroup(['A', 3, 1]) # optional - sage.combinat sage.groups + sage: W.special_node() # optional - sage.combinat sage.groups 0 """ return self.cartan_type().special_node() @@ -95,8 +95,9 @@ def affine_grassmannian_elements_of_given_length(self, k): EXAMPLES:: - sage: W = WeylGroup(['A',3,1]) - sage: [x.reduced_word() for x in W.affine_grassmannian_elements_of_given_length(3)] + sage: W = WeylGroup(['A', 3, 1]) # optional - sage.combinat sage.groups + sage: [x.reduced_word() # optional - sage.combinat sage.groups + ....: for x in W.affine_grassmannian_elements_of_given_length(3)] [[2, 1, 0], [3, 1, 0], [2, 3, 0]] .. SEEALSO:: @@ -136,14 +137,14 @@ def is_affine_grassmannian(self): EXAMPLES:: - sage: W = WeylGroup(['A',3,1]) - sage: w = W.from_reduced_word([2,1,0]) - sage: w.is_affine_grassmannian() + sage: W = WeylGroup(['A', 3, 1]) # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([2,1,0]) # optional - sage.combinat sage.groups + sage: w.is_affine_grassmannian() # optional - sage.combinat sage.groups True - sage: w = W.from_reduced_word([2,0]) - sage: w.is_affine_grassmannian() + sage: w = W.from_reduced_word([2,0]) # optional - sage.combinat sage.groups + sage: w.is_affine_grassmannian() # optional - sage.combinat sage.groups False - sage: W.one().is_affine_grassmannian() + sage: W.one().is_affine_grassmannian() # optional - sage.combinat sage.groups True """ D = self.descents() @@ -168,17 +169,17 @@ def affine_grassmannian_to_core(self): EXAMPLES:: - sage: W = WeylGroup(['A',2,1]) - sage: w = W.from_reduced_word([0,2,1,0]) - sage: la = w.affine_grassmannian_to_core(); la + sage: W = WeylGroup(['A', 2, 1]) # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([0,2,1,0]) # optional - sage.combinat sage.groups + sage: la = w.affine_grassmannian_to_core(); la # optional - sage.combinat sage.groups [4, 2] - sage: type(la) + sage: type(la) # optional - sage.combinat sage.groups - sage: la.to_grassmannian() == w + sage: la.to_grassmannian() == w # optional - sage.combinat sage.groups True - sage: w = W.from_reduced_word([0,2,1]) - sage: w.affine_grassmannian_to_core() + sage: w = W.from_reduced_word([0,2,1]) # optional - sage.combinat sage.groups + sage: w.affine_grassmannian_to_core() # optional - sage.combinat sage.groups Traceback (most recent call last): ... ValueError: this only works on type 'A' affine Grassmannian elements @@ -214,11 +215,11 @@ def affine_grassmannian_to_partition(self): EXAMPLES:: sage: k = 2 - sage: W = WeylGroup(['A',k,1]) - sage: w = W.from_reduced_word([0,2,1,0]) - sage: la = w.affine_grassmannian_to_partition(); la + sage: W = WeylGroup(['A', k, 1]) # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([0,2,1,0]) # optional - sage.combinat sage.groups + sage: la = w.affine_grassmannian_to_partition(); la # optional - sage.combinat sage.groups [2, 2] - sage: la.from_kbounded_to_grassmannian(k) == w + sage: la.from_kbounded_to_grassmannian(k) == w # optional - sage.combinat sage.groups True """ return self.affine_grassmannian_to_core().to_bounded_partition() diff --git a/src/sage/categories/algebra_functor.py b/src/sage/categories/algebra_functor.py index d2c64474d8e..9142a9b6e38 100644 --- a/src/sage/categories/algebra_functor.py +++ b/src/sage/categories/algebra_functor.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.groups r""" Group algebras and beyond: the Algebra functorial construction diff --git a/src/sage/categories/algebra_ideals.py b/src/sage/categories/algebra_ideals.py index 2beecea2ee4..3bea4f66f91 100644 --- a/src/sage/categories/algebra_ideals.py +++ b/src/sage/categories/algebra_ideals.py @@ -79,9 +79,10 @@ def super_categories(self): EXAMPLES:: sage: AlgebraIdeals(QQ['x']).super_categories() - [Category of algebra modules over Univariate Polynomial Ring in x over Rational Field] - sage: C = AlgebraIdeals(FreeAlgebra(QQ,2,'a,b')) - sage: C.super_categories() + [Category of algebra modules + over Univariate Polynomial Ring in x over Rational Field] + sage: C = AlgebraIdeals(FreeAlgebra(QQ, 2, 'a,b')) # optional - sage.combinat sage.modules + sage: C.super_categories() # optional - sage.combinat sage.modules [] """ diff --git a/src/sage/categories/algebra_modules.py b/src/sage/categories/algebra_modules.py index 46698060095..086b834f955 100644 --- a/src/sage/categories/algebra_modules.py +++ b/src/sage/categories/algebra_modules.py @@ -39,7 +39,7 @@ def __init__(self, A): sage: AlgebraModules(QQ['a']) Category of algebra modules over Univariate Polynomial Ring in a over Rational Field sage: AlgebraModules(QQ['a,b']) # todo: not implemented (QQ['a,b'] should be in Algebras(QQ)) - sage: AlgebraModules(FreeAlgebra(QQ,2,'a,b')) + sage: AlgebraModules(FreeAlgebra(QQ, 2, 'a,b')) # optional - sage.combinat sage.modules Traceback (most recent call last): ... TypeError: A (=Free Algebra on 2 generators (a, b) over Rational Field) must be a commutative algebra diff --git a/src/sage/categories/algebras.py b/src/sage/categories/algebras.py index 253d64a2819..3b808b5d1b7 100644 --- a/src/sage/categories/algebras.py +++ b/src/sage/categories/algebras.py @@ -68,7 +68,7 @@ def __contains__(self, x): sage: QQ['x'] in Algebras(QQ) True - sage: QQ^3 in Algebras(QQ) + sage: QQ^3 in Algebras(QQ) # optional - sage.modules False sage: QQ['x'] in Algebras(CDF) False @@ -154,15 +154,15 @@ def _div_(self, y): EXAMPLES:: - sage: C = AlgebrasWithBasis(QQ).example() - sage: x = C(2); x + sage: C = AlgebrasWithBasis(QQ).example() # optional - sage.combinat + sage: x = C(2); x # optional - sage.combinat 2*B[word: ] - sage: y = C.algebra_generators().first(); y + sage: y = C.algebra_generators().first(); y # optional - sage.combinat B[word: a] - sage: y._div_(x) + sage: y._div_(x) # optional - sage.combinat 1/2*B[word: a] - sage: x._div_(y) + sage: x._div_(y) # optional - sage.combinat Traceback (most recent call last): ... ValueError: cannot invert self (= B[word: a]) diff --git a/src/sage/categories/algebras_with_basis.py b/src/sage/categories/algebras_with_basis.py index d2296873b59..e7762b50f24 100644 --- a/src/sage/categories/algebras_with_basis.py +++ b/src/sage/categories/algebras_with_basis.py @@ -33,35 +33,37 @@ class AlgebrasWithBasis(CategoryWithAxiom_over_base_ring): We construct a typical parent in this category, and do some computations with it:: - sage: A = C.example(); A - An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field + sage: A = C.example(); A # optional - sage.combinat + An example of an algebra with basis: + the free algebra on the generators ('a', 'b', 'c') over Rational Field - sage: A.category() + sage: A.category() # optional - sage.combinat Category of algebras with basis over Rational Field - sage: A.one_basis() + sage: A.one_basis() # optional - sage.combinat word: - sage: A.one() + sage: A.one() # optional - sage.combinat B[word: ] - sage: A.base_ring() + sage: A.base_ring() # optional - sage.combinat Rational Field - sage: A.basis().keys() + sage: A.basis().keys() # optional - sage.combinat Finite words over {'a', 'b', 'c'} - sage: (a,b,c) = A.algebra_generators() - sage: a^3, b^2 + sage: (a,b,c) = A.algebra_generators() # optional - sage.combinat + sage: a^3, b^2 # optional - sage.combinat (B[word: aaa], B[word: bb]) - sage: a*c*b + sage: a * c * b # optional - sage.combinat B[word: acb] - sage: A.product + sage: A.product # optional - sage.combinat - sage: A.product(a*b,b) + An example of an algebra with basis: + the free algebra on the generators ('a', 'b', 'c') over Rational Field> + sage: A.product(a * b, b) # optional - sage.combinat B[word: abb] - sage: TestSuite(A).run(verbose=True) + sage: TestSuite(A).run(verbose=True) # optional - sage.combinat running ._test_additive_associativity() . . . pass running ._test_an_element() . . . pass running ._test_associativity() . . . pass @@ -91,9 +93,9 @@ class AlgebrasWithBasis(CategoryWithAxiom_over_base_ring): running ._test_prod() . . . pass running ._test_some_elements() . . . pass running ._test_zero() . . . pass - sage: A.__class__ + sage: A.__class__ # optional - sage.combinat - sage: A.element_class + sage: A.element_class # optional - sage.combinat Please see the source code of `A` (with ``A??``) for how to @@ -110,13 +112,15 @@ def example(self, alphabet=('a','b','c')): EXAMPLES:: - sage: AlgebrasWithBasis(QQ).example() - An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field + sage: AlgebrasWithBasis(QQ).example() # optional - sage.combinat + An example of an algebra with basis: + the free algebra on the generators ('a', 'b', 'c') over Rational Field An other set of generators can be specified as optional argument:: - sage: AlgebrasWithBasis(QQ).example((1,2,3)) - An example of an algebra with basis: the free algebra on the generators (1, 2, 3) over Rational Field + sage: AlgebrasWithBasis(QQ).example((1,2,3)) # optional - sage.combinat + An example of an algebra with basis: + the free algebra on the generators (1, 2, 3) over Rational Field """ from sage.categories.examples.algebras_with_basis import Example return Example(self.base_ring(), alphabet) @@ -143,12 +147,12 @@ def hochschild_complex(self, M): EXAMPLES:: sage: R. = QQ[] - sage: A = algebras.DifferentialWeyl(R) - sage: H = A.hochschild_complex(A) + sage: A = algebras.DifferentialWeyl(R) # optional - sage.combinat + sage: H = A.hochschild_complex(A) # optional - sage.combinat - sage: SGA = SymmetricGroupAlgebra(QQ, 3) - sage: T = SGA.trivial_representation() - sage: H = SGA.hochschild_complex(T) + sage: SGA = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat + sage: T = SGA.trivial_representation() # optional - sage.combinat + sage: H = SGA.hochschild_complex(T) # optional - sage.combinat """ from sage.homology.hochschild_complex import HochschildComplex return HochschildComplex(self, M) @@ -176,14 +180,14 @@ def __invert__(self): EXAMPLES:: - sage: C = AlgebrasWithBasis(QQ).example() - sage: x = C(2); x + sage: C = AlgebrasWithBasis(QQ).example() # optional - sage.combinat + sage: x = C(2); x # optional - sage.combinat 2*B[word: ] - sage: ~x + sage: ~x # optional - sage.combinat 1/2*B[word: ] - sage: a = C.algebra_generators().first(); a + sage: a = C.algebra_generators().first(); a # optional - sage.combinat B[word: a] - sage: ~a + sage: ~a # optional - sage.combinat Traceback (most recent call last): ... ValueError: cannot invert self (= B[word: a]) @@ -237,18 +241,20 @@ def one_from_cartesian_product_of_one_basis(self): EXAMPLES:: - sage: A = AlgebrasWithBasis(QQ).example(); A - An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field - sage: A.one_basis() + sage: A = AlgebrasWithBasis(QQ).example(); A # optional - sage.combinat + An example of an algebra with basis: the free algebra + on the generators ('a', 'b', 'c') over Rational Field + sage: A.one_basis() # optional - sage.combinat word: - sage: B = cartesian_product((A, A, A)) - sage: B.one_from_cartesian_product_of_one_basis() + sage: B = cartesian_product((A, A, A)) # optional - sage.combinat + sage: B.one_from_cartesian_product_of_one_basis() # optional - sage.combinat B[(0, word: )] + B[(1, word: )] + B[(2, word: )] - sage: B.one() + sage: B.one() # optional - sage.combinat B[(0, word: )] + B[(1, word: )] + B[(2, word: )] - sage: cartesian_product([SymmetricGroupAlgebra(QQ, 3), SymmetricGroupAlgebra(QQ, 4)]).one() + sage: cartesian_product([SymmetricGroupAlgebra(QQ, 3), # optional - sage.combinat + ....: 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)) ) @@ -258,10 +264,11 @@ def one(self): """ TESTS:: - sage: A = AlgebrasWithBasis(QQ).example(); A - An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field - sage: B = cartesian_product((A, A, A)) - sage: B.one() + sage: A = AlgebrasWithBasis(QQ).example(); A # optional - sage.combinat + An example of an algebra with basis: the free algebra + on the generators ('a', 'b', 'c') over Rational Field + sage: B = cartesian_product((A, A, A)) # optional - sage.combinat + sage: B.one() # optional - sage.combinat B[(0, word: )] + B[(1, word: )] + B[(2, word: )] """ if all(hasattr(module, "one_basis") for module in self._sets): @@ -310,14 +317,15 @@ def one_basis(self): EXAMPLES:: - sage: A = AlgebrasWithBasis(QQ).example(); A - An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field - sage: A.one_basis() + sage: A = AlgebrasWithBasis(QQ).example(); A # optional - sage.combinat + An example of an algebra with basis: the free algebra + on the generators ('a', 'b', 'c') over Rational Field + sage: A.one_basis() # optional - sage.combinat word: - sage: B = tensor((A, A, A)) - sage: B.one_basis() + sage: B = tensor((A, A, A)) # optional - sage.combinat + sage: B.one_basis() # optional - sage.combinat (word: , word: , word: ) - sage: B.one() + sage: B.one() # optional - sage.combinat B[word: ] # B[word: ] # B[word: ] """ # FIXME: this method should be conditionally defined, @@ -335,23 +343,25 @@ def product_on_basis(self, t1, t2): EXAMPLES:: - sage: A = AlgebrasWithBasis(QQ).example(); A - An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field - sage: (a,b,c) = A.algebra_generators() + sage: A = AlgebrasWithBasis(QQ).example(); A # optional - sage.combinat + An example of an algebra with basis: the free algebra + on the generators ('a', 'b', 'c') over Rational Field + sage: (a,b,c) = A.algebra_generators() # optional - sage.combinat - sage: x = tensor( (a, b, c) ); x + sage: x = tensor((a, b, c)); x # optional - sage.combinat B[word: a] # B[word: b] # B[word: c] - sage: y = tensor( (c, b, a) ); y + sage: y = tensor((c, b, a)); y # optional - sage.combinat B[word: c] # B[word: b] # B[word: a] - sage: x*y + sage: x * y # optional - sage.combinat B[word: ac] # B[word: bb] # B[word: ca] - sage: x = tensor( ((a+2*b), c) ) ; x + sage: x = tensor(((a + 2*b), c)); x # optional - sage.combinat B[word: a] # B[word: c] + 2*B[word: b] # B[word: c] - sage: y = tensor( (c, a) ) + 1; y + sage: y = tensor((c, a)) + 1; y # optional - sage.combinat B[word: ] # B[word: ] + B[word: c] # B[word: a] - sage: x*y - B[word: a] # B[word: c] + B[word: ac] # B[word: ca] + 2*B[word: b] # B[word: c] + 2*B[word: bc] # B[word: ca] + sage: x * y # optional - sage.combinat + B[word: a] # B[word: c] + B[word: ac] # B[word: ca] + + 2*B[word: b] # B[word: c] + 2*B[word: bc] # B[word: ca] TODO: optimize this implementation! diff --git a/src/sage/categories/bialgebras.py b/src/sage/categories/bialgebras.py index 441d924c964..fa6a7a1a507 100644 --- a/src/sage/categories/bialgebras.py +++ b/src/sage/categories/bialgebras.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat r""" Bialgebras """ diff --git a/src/sage/categories/bialgebras_with_basis.py b/src/sage/categories/bialgebras_with_basis.py index 831bab3f068..067d0b35b8e 100644 --- a/src/sage/categories/bialgebras_with_basis.py +++ b/src/sage/categories/bialgebras_with_basis.py @@ -92,32 +92,33 @@ def convolution_product(self, *maps): with the projection ``Proj2`` on the Hopf algebra of non-commutative symmetric functions:: - sage: R = NonCommutativeSymmetricFunctions(QQ).ribbon() - sage: T = R.convolution_product([Id, Id]) - sage: [T(R(comp)) for comp in Compositions(3)] + sage: R = NonCommutativeSymmetricFunctions(QQ).ribbon() # optional - sage.combinat + sage: T = R.convolution_product([Id, Id]) # optional - sage.combinat + sage: [T(R(comp)) for comp in Compositions(3)] # optional - sage.combinat [4*R[1, 1, 1] + R[1, 2] + R[2, 1], 2*R[1, 1, 1] + 4*R[1, 2] + 2*R[2, 1] + 2*R[3], 2*R[1, 1, 1] + 2*R[1, 2] + 4*R[2, 1] + 2*R[3], R[1, 2] + R[2, 1] + 4*R[3]] - sage: T = R.convolution_product(Proj2, Id) - sage: [T(R([i])) for i in range(1, 5)] + sage: T = R.convolution_product(Proj2, Id) # optional - sage.combinat + sage: [T(R([i])) for i in range(1, 5)] # optional - sage.combinat [0, R[2], R[2, 1] + R[3], R[2, 2] + R[4]] Compute the convolution product of no maps on the Hopf algebra of symmetric functions in non-commuting variables. This is the composition of the counit with the unit:: - sage: m = SymmetricFunctionsNonCommutingVariables(QQ).m() - sage: T = m.convolution_product() - sage: [T(m(lam)) for lam in SetPartitions(0).list() + SetPartitions(2).list()] + sage: m = SymmetricFunctionsNonCommutingVariables(QQ).m() # optional - sage.combinat + sage: T = m.convolution_product() # optional - sage.combinat + sage: [T(m(lam)) # optional - sage.combinat + ....: for lam in SetPartitions(0).list() + SetPartitions(2).list()] [m{}, 0, 0] Compute the convolution product of the projection ``Proj2`` with the identity on the Hopf algebra of symmetric functions in non-commuting variables:: - sage: T = m.convolution_product(Proj2, Id) - sage: [T(m(lam)) for lam in SetPartitions(3)] + sage: T = m.convolution_product(Proj2, Id) # optional - sage.combinat + sage: [T(m(lam)) for lam in SetPartitions(3)] # optional - sage.combinat [0, m{{1, 2}, {3}} + m{{1, 2, 3}}, m{{1, 2}, {3}} + m{{1, 2, 3}}, @@ -127,12 +128,15 @@ def convolution_product(self, *maps): Compute the convolution product of the antipode with itself and the identity map on group algebra of the symmetric group:: - sage: G = SymmetricGroup(3) - sage: QG = GroupAlgebra(G, QQ) - sage: x = QG.sum_of_terms([(p,p.number_of_peaks() + p.number_of_inversions()) for p in Permutations(3)]); x + sage: G = SymmetricGroup(3) # optional - sage.groups sage.combinat + sage: QG = GroupAlgebra(G, QQ) # optional - sage.groups sage.combinat + sage: x = QG.sum_of_terms( # optional - sage.groups sage.combinat + ....: [(p, p.number_of_peaks() + p.number_of_inversions()) + ....: for p in Permutations(3)] + ....: ); x 2*[1, 3, 2] + [2, 1, 3] + 3*[2, 3, 1] + 2*[3, 1, 2] + 3*[3, 2, 1] - sage: T = QG.convolution_product(Antipode, Antipode, Id) - sage: T(x) + sage: T = QG.convolution_product(Antipode, Antipode, Id) # optional - sage.groups sage.combinat + sage: T(x) # optional - sage.groups sage.combinat 2*[1, 3, 2] + [2, 1, 3] + 2*[2, 3, 1] + 3*[3, 1, 2] + 3*[3, 2, 1] """ onbasis = lambda x: self.term(x).convolution_product(*maps) @@ -168,31 +172,32 @@ def adams_operator(self, n): EXAMPLES:: - sage: h = SymmetricFunctions(QQ).h() - sage: h[5].adams_operator(2) + sage: h = SymmetricFunctions(QQ).h() # optional - sage.combinat + sage: h[5].adams_operator(2) # optional - sage.combinat 2*h[3, 2] + 2*h[4, 1] + 2*h[5] - sage: h[5].plethysm(2*h[1]) + sage: h[5].plethysm(2*h[1]) # optional - sage.combinat 2*h[3, 2] + 2*h[4, 1] + 2*h[5] - sage: h([]).adams_operator(0) + sage: h([]).adams_operator(0) # optional - sage.combinat h[] - sage: h([]).adams_operator(1) + sage: h([]).adams_operator(1) # optional - sage.combinat h[] - sage: h[3,2].adams_operator(0) + sage: h[3,2].adams_operator(0) # optional - sage.combinat 0 - sage: h[3,2].adams_operator(1) + sage: h[3,2].adams_operator(1) # optional - sage.combinat h[3, 2] :: - sage: S = NonCommutativeSymmetricFunctions(QQ).S() - sage: S[4].adams_operator(5) - 5*S[1, 1, 1, 1] + 10*S[1, 1, 2] + 10*S[1, 2, 1] + 10*S[1, 3] + 10*S[2, 1, 1] + 10*S[2, 2] + 10*S[3, 1] + 5*S[4] + sage: S = NonCommutativeSymmetricFunctions(QQ).S() # optional - sage.combinat + sage: S[4].adams_operator(5) # optional - sage.combinat + 5*S[1, 1, 1, 1] + 10*S[1, 1, 2] + 10*S[1, 2, 1] + + 10*S[1, 3] + 10*S[2, 1, 1] + 10*S[2, 2] + 10*S[3, 1] + 5*S[4] :: - sage: m = SymmetricFunctionsNonCommutingVariables(QQ).m() - sage: m[[1,3],[2]].adams_operator(-2) + sage: m = SymmetricFunctionsNonCommutingVariables(QQ).m() # optional - sage.combinat + sage: m[[1,3],[2]].adams_operator(-2) # optional - sage.combinat 3*m{{1}, {2, 3}} + 3*m{{1, 2}, {3}} + 6*m{{1, 2, 3}} - 2*m{{1, 3}, {2}} """ if n < 0: @@ -254,18 +259,18 @@ def convolution_product(self, *maps): sage: Id = lambda x: x sage: Antipode = lambda x: x.antipode() - sage: s = SymmetricFunctions(QQ).schur() - sage: s[3].convolution_product(Id, Id) + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: s[3].convolution_product(Id, Id) # optional - sage.combinat 2*s[2, 1] + 4*s[3] - sage: s[3,2].convolution_product(Id) == s[3,2] + sage: s[3,2].convolution_product(Id) == s[3,2] # optional - sage.combinat True The method accepts multiple arguments, or a single argument consisting of a list of maps:: - sage: s[3,2].convolution_product(Id, Id) + sage: s[3,2].convolution_product(Id, Id) # optional - sage.combinat 2*s[2, 1, 1, 1] + 6*s[2, 2, 1] + 6*s[3, 1, 1] + 12*s[3, 2] + 6*s[4, 1] + 2*s[5] - sage: s[3,2].convolution_product([Id, Id]) + sage: s[3,2].convolution_product([Id, Id]) # optional - sage.combinat 2*s[2, 1, 1, 1] + 6*s[2, 2, 1] + 6*s[3, 1, 1] + 12*s[3, 2] + 6*s[4, 1] + 2*s[5] We test the defining property of the antipode morphism; namely, @@ -273,28 +278,31 @@ def convolution_product(self, *maps): convolution algebra whose identity element is the composition of the counit and unit:: - sage: s[3,2].convolution_product() == s[3,2].convolution_product(Antipode, Id) == s[3,2].convolution_product(Id, Antipode) + sage: (s[3,2].convolution_product() # optional - sage.combinat + ....: == s[3,2].convolution_product(Antipode, Id) + ....: == s[3,2].convolution_product(Id, Antipode)) True :: - sage: Psi = NonCommutativeSymmetricFunctions(QQ).Psi() - sage: Psi[2,1].convolution_product(Id, Id, Id) + sage: Psi = NonCommutativeSymmetricFunctions(QQ).Psi() # optional - sage.combinat + sage: Psi[2,1].convolution_product(Id, Id, Id) # optional - sage.combinat 3*Psi[1, 2] + 6*Psi[2, 1] - sage: (Psi[5,1] - Psi[1,5]).convolution_product(Id, Id, Id) + sage: (Psi[5,1] - Psi[1,5]).convolution_product(Id, Id, Id) # optional - sage.combinat -3*Psi[1, 5] + 3*Psi[5, 1] :: - sage: G = SymmetricGroup(3) - sage: QG = GroupAlgebra(G,QQ) - sage: x = QG.sum_of_terms([(p,p.length()) for p in Permutations(3)]); x + sage: G = SymmetricGroup(3) # optional - sage.combinat + sage: QG = GroupAlgebra(G, QQ) # optional - sage.combinat + sage: x = QG.sum_of_terms([(p, p.length()) # optional - sage.combinat + ....: for p in Permutations(3)]); x [1, 3, 2] + [2, 1, 3] + 2*[2, 3, 1] + 2*[3, 1, 2] + 3*[3, 2, 1] - sage: x.convolution_product(Id, Id) + sage: x.convolution_product(Id, Id) # optional - sage.combinat 5*[1, 2, 3] + 2*[2, 3, 1] + 2*[3, 1, 2] - sage: x.convolution_product(Id, Id, Id) + sage: x.convolution_product(Id, Id, Id) # optional - sage.combinat 4*[1, 2, 3] + [1, 3, 2] + [2, 1, 3] + 3*[3, 2, 1] - sage: x.convolution_product([Id]*6) + sage: x.convolution_product([Id] * 6) # optional - sage.combinat 9*[1, 2, 3] TESTS:: @@ -304,57 +312,60 @@ def convolution_product(self, *maps): :: - sage: h = SymmetricFunctions(QQ).h() - sage: h[5].convolution_product([Id, Id]) + sage: h = SymmetricFunctions(QQ).h() # optional - sage.combinat + sage: h[5].convolution_product([Id, Id]) # optional - sage.combinat 2*h[3, 2] + 2*h[4, 1] + 2*h[5] - sage: h.one().convolution_product([Id, Antipode]) + sage: h.one().convolution_product([Id, Antipode]) # optional - sage.combinat h[] - sage: h[3,2].convolution_product([Id, Antipode]) + sage: h[3,2].convolution_product([Id, Antipode]) # optional - sage.combinat 0 - sage: h.one().convolution_product([Id, Antipode]) == h.one().convolution_product() + sage: (h.one().convolution_product([Id, Antipode]) # optional - sage.combinat + ....: == h.one().convolution_product()) True :: - sage: S = NonCommutativeSymmetricFunctions(QQ).S() - sage: S[4].convolution_product([Id]*5) + sage: S = NonCommutativeSymmetricFunctions(QQ).S() # optional - sage.combinat + sage: S[4].convolution_product([Id] * 5) # optional - sage.combinat 5*S[1, 1, 1, 1] + 10*S[1, 1, 2] + 10*S[1, 2, 1] + 10*S[1, 3] + 10*S[2, 1, 1] + 10*S[2, 2] + 10*S[3, 1] + 5*S[4] :: - sage: m = SymmetricFunctionsNonCommutingVariables(QQ).m() - sage: m[[1,3],[2]].convolution_product([Antipode, Antipode]) + sage: m = SymmetricFunctionsNonCommutingVariables(QQ).m() # optional - sage.combinat + sage: m[[1,3],[2]].convolution_product([Antipode, Antipode]) # optional - sage.combinat 3*m{{1}, {2, 3}} + 3*m{{1, 2}, {3}} + 6*m{{1, 2, 3}} - 2*m{{1, 3}, {2}} - sage: m[[]].convolution_product([]) + sage: m[[]].convolution_product([]) # optional - sage.combinat m{} - sage: m[[1,3],[2]].convolution_product([]) + sage: m[[1,3],[2]].convolution_product([]) # optional - sage.combinat 0 :: - sage: QS = SymmetricGroupAlgebra(QQ, 5) - sage: x = QS.sum_of_terms(zip(Permutations(5)[3:6],[1,2,3])); x + sage: QS = SymmetricGroupAlgebra(QQ, 5) # optional - sage.combinat + sage: x = QS.sum_of_terms(zip(Permutations(5)[3:6], [1,2,3])); x # optional - sage.combinat [1, 2, 4, 5, 3] + 2*[1, 2, 5, 3, 4] + 3*[1, 2, 5, 4, 3] - sage: x.convolution_product([Antipode, Id]) + sage: x.convolution_product([Antipode, Id]) # optional - sage.combinat 6*[1, 2, 3, 4, 5] - sage: x.convolution_product(Id, Antipode, Antipode, Antipode) + sage: x.convolution_product(Id, Antipode, Antipode, Antipode) # optional - sage.combinat 3*[1, 2, 3, 4, 5] + [1, 2, 4, 5, 3] + 2*[1, 2, 5, 3, 4] :: - sage: G = SymmetricGroup(3) - sage: QG = GroupAlgebra(G,QQ) - sage: x = QG.sum_of_terms([(p,p.length()) for p in Permutations(3)]); x + sage: G = SymmetricGroup(3) # optional - sage.combinat + sage: QG = GroupAlgebra(G, QQ) # optional - sage.combinat + sage: x = QG.sum_of_terms([(p, p.length()) # optional - sage.combinat + ....: for p in Permutations(3)]); x [1, 3, 2] + [2, 1, 3] + 2*[2, 3, 1] + 2*[3, 1, 2] + 3*[3, 2, 1] - sage: x.convolution_product(Antipode, Id) + sage: x.convolution_product(Antipode, Id) # optional - sage.combinat 9*[1, 2, 3] - sage: x.convolution_product([Id, Antipode, Antipode, Antipode]) + sage: x.convolution_product([Id, Antipode, Antipode, Antipode]) # optional - sage.combinat 5*[1, 2, 3] + 2*[2, 3, 1] + 2*[3, 1, 2] :: - sage: s[3,2].counit().parent() == s[3,2].convolution_product().parent() + sage: (s[3,2].counit().parent() # optional - sage.combinat + ....: == s[3,2].convolution_product().parent()) False """ # Be flexible on how the maps are entered: accept a list/tuple of diff --git a/src/sage/categories/category.py b/src/sage/categories/category.py index fe5e22cffd9..83e88ef748a 100644 --- a/src/sage/categories/category.py +++ b/src/sage/categories/category.py @@ -22,48 +22,49 @@ sage: Sets() Category of sets - sage: GSets(AbelianGroup([2,4,9])) + sage: GSets(AbelianGroup([2, 4, 9])) # optional - sage.groups Category of G-sets for Multiplicative Abelian group isomorphic to C2 x C4 x C9 sage: Semigroups() Category of semigroups - sage: VectorSpaces(FiniteField(11)) + sage: VectorSpaces(FiniteField(11)) # optional - sage.rings.finite_rings Category of vector spaces over Finite Field of size 11 sage: Ideals(IntegerRing()) Category of ring ideals in Integer Ring Let's request the category of some objects:: - sage: V = VectorSpace(RationalField(), 3) - sage: V.category() + sage: V = VectorSpace(RationalField(), 3) # optional - sage.modules + sage: V.category() # optional - sage.modules Category of finite dimensional vector spaces with basis over (number fields and quotient fields and metric spaces) - sage: G = SymmetricGroup(9) - sage: G.category() - Join of Category of finite enumerated permutation groups and - Category of finite weyl groups and - Category of well generated finite irreducible complex reflection groups + sage: G = SymmetricGroup(9) # optional - sage.groups + sage: G.category() # optional - sage.groups + Join of + Category of finite enumerated permutation groups and + Category of finite weyl groups and + Category of well generated finite irreducible complex reflection groups - sage: P = PerfectMatchings(3) - sage: P.category() + sage: P = PerfectMatchings(3) # optional - sage.combinat sage.graphs + sage: P.category() # optional - sage.combinat sage.graphs Category of finite enumerated sets Let's check some memberships:: - sage: V in VectorSpaces(QQ) + sage: V in VectorSpaces(QQ) # optional - sage.modules True - sage: V in VectorSpaces(FiniteField(11)) + sage: V in VectorSpaces(FiniteField(11)) # optional - sage.modules sage.rings.finite_rings False - sage: G in Monoids() + sage: G in Monoids() # optional - sage.groups True - sage: P in Rings() + sage: P in Rings() # optional - sage.combinat sage.graphs False For parametrized categories one can use the following shorthand:: - sage: V in VectorSpaces + sage: V in VectorSpaces # optional - sage.modules True - sage: G in VectorSpaces + sage: G in VectorSpaces # optional - sage.groups False A parent ``P`` is in a category ``C`` if ``P.category()`` is a subcategory of @@ -83,11 +84,11 @@ True By default, the category of an element `x` of a parent `P` is the category - of all objects of `P` (this is dubious an may be deprecated):: + of all objects of `P` (this is dubious and may be deprecated):: - sage: V = VectorSpace(RationalField(), 3) - sage: v = V.gen(1) - sage: v.category() + sage: V = VectorSpace(RationalField(), 3) # optional - sage.modules + sage: v = V.gen(1) # optional - sage.modules + sage: v.category() # optional - sage.modules Category of elements of Vector space of dimension 3 over Rational Field """ @@ -308,7 +309,8 @@ class inheritance from ``C.parent_class``. sage: Ds().parent_class.__bases__ (, ) sage: Ds().parent_class.mro() - [, , , , <... 'object'>] + [, , + , , <... 'object'>] Note that two categories in the same class need not have the same ``super_categories``. For example, ``Algebras(QQ)`` has @@ -325,7 +327,7 @@ class inheritance from ``C.parent_class``. On the other hand, identical hierarchies of classes are, preferably, built only once (e.g. for categories over a base ring):: - sage: Algebras(GF(5)).parent_class is Algebras(GF(7)).parent_class + sage: Algebras(GF(5)).parent_class is Algebras(GF(7)).parent_class # optional - sage.rings.finite_rings True sage: F = FractionField(ZZ['t']) sage: Coalgebras(F).parent_class is Coalgebras(FractionField(F['x'])).parent_class @@ -565,9 +567,11 @@ def an_instance(cls): sage: Algebras.an_instance() Category of algebras over Rational Field sage: Bimodules.an_instance() - Category of bimodules over Rational Field on the left and Real Field with 53 bits of precision on the right + Category of bimodules over Rational Field on the left + and Real Field with 53 bits of precision on the right sage: AlgebraIdeals.an_instance() - Category of algebra ideals in Univariate Polynomial Ring in x over Rational Field + Category of algebra ideals + in Univariate Polynomial Ring in x over Rational Field """ return cls() @@ -724,15 +728,15 @@ def __classcontains__(cls, x): This method makes it easy to test if an object is, say, a vector space, without having to specify the base ring:: - sage: F = FreeModule(QQ,3) - sage: F in VectorSpaces + sage: F = FreeModule(QQ, 3) # optional - sage.modules + sage: F in VectorSpaces # optional - sage.modules True - sage: F = FreeModule(ZZ,3) - sage: F in VectorSpaces + sage: F = FreeModule(ZZ, 3) # optional - sage.modules + sage: F in VectorSpaces # optional - sage.modules False - sage: F in Algebras + sage: F in Algebras # optional - sage.modules False TESTS: @@ -798,14 +802,14 @@ def category_graph(self): EXAMPLES:: sage: C = Algebras(QQ) - sage: G = C.category_graph() - sage: G.is_directed_acyclic() + sage: G = C.category_graph() # optional - sage.graphs + sage: G.is_directed_acyclic() # optional - sage.graphs True The girth of a directed acyclic graph is infinite, however, the girth of the underlying undirected graph is 4 in this case:: - sage: Graph(G).girth() + sage: Graph(G).girth() # optional - sage.graphs 4 """ return category_graph([self]) @@ -928,8 +932,8 @@ def _set_of_super_categories(self): TESTS:: - sage: C = HopfAlgebrasWithBasis(GF(7)) - sage: C._set_of_super_categories == frozenset(C._all_super_categories_proper) + sage: C = HopfAlgebrasWithBasis(GF(7)) # optional - sage.rings.finite_rings + sage: C._set_of_super_categories == set(C._all_super_categories_proper) # optional - sage.rings.finite_rings True """ return frozenset(self._all_super_categories_proper) @@ -1669,7 +1673,7 @@ def parent_class(self): the category of algebras over a finite field versus algebras over a non-field:: - sage: Algebras(GF(7)).parent_class is Algebras(GF(5)).parent_class + sage: Algebras(GF(7)).parent_class is Algebras(GF(5)).parent_class # optional - sage.rings.finite_rings True sage: Algebras(QQ).parent_class is Algebras(ZZ).parent_class False @@ -1714,7 +1718,7 @@ def element_class(self): category of algebras over a field versus algebras over a non-field:: - sage: Algebras(GF(5)).element_class is Algebras(GF(3)).element_class + sage: Algebras(GF(5)).element_class is Algebras(GF(3)).element_class # optional - sage.rings.finite_rings True sage: Algebras(QQ).element_class is Algebras(ZZ).element_class False @@ -1788,9 +1792,9 @@ def is_subcategory(self, c): :: - sage: M3 = VectorSpaces(FiniteField(3)) - sage: M9 = VectorSpaces(FiniteField(9, 'a')) - sage: M3.is_subcategory(M9) + sage: M3 = VectorSpaces(FiniteField(3)) # optional - sage.rings.finite_rings sage.modules + sage: M9 = VectorSpaces(FiniteField(9, 'a')) # optional - sage.rings.finite_rings sage.modules + sage: M3.is_subcategory(M9) # optional - sage.rings.finite_rings sage.modules False Join categories are properly handled:: @@ -1801,16 +1805,16 @@ def is_subcategory(self, c): :: - sage: V3 = VectorSpaces(FiniteField(3)) + sage: V3 = VectorSpaces(FiniteField(3)) # optional - sage.rings.finite_rings sage: POSet = PartiallyOrderedSets() - sage: PoV3 = Category.join((V3, POSet)) - sage: A3 = AlgebrasWithBasis(FiniteField(3)) - sage: PoA3 = Category.join((A3, POSet)) - sage: PoA3.is_subcategory(PoV3) + sage: PoV3 = Category.join((V3, POSet)) # optional - sage.rings.finite_rings + sage: A3 = AlgebrasWithBasis(FiniteField(3)) # optional - sage.rings.finite_rings + sage: PoA3 = Category.join((A3, POSet)) # optional - sage.rings.finite_rings + sage: PoA3.is_subcategory(PoV3) # optional - sage.rings.finite_rings True - sage: PoV3.is_subcategory(PoV3) + sage: PoV3.is_subcategory(PoV3) # optional - sage.rings.finite_rings True - sage: PoV3.is_subcategory(PoA3) + sage: PoV3.is_subcategory(PoA3) # optional - sage.rings.finite_rings False """ if c is self: @@ -1852,7 +1856,8 @@ def or_subcategory(self, category=None, join=False): sage: Monoids().or_subcategory(EnumeratedSets()) Traceback (most recent call last): ... - ValueError: Subcategory of `Category of monoids` required; got `Category of enumerated sets` + ValueError: Subcategory of `Category of monoids` required; + got `Category of enumerated sets` Otherwise, the two categories are joined together:: @@ -2077,7 +2082,8 @@ def _with_axiom(self, axiom): sage: Magmas().Finite().Commutative().super_categories() [Category of commutative magmas, Category of finite sets] - sage: Algebras(QQ).WithBasis().Commutative() is Algebras(QQ).Commutative().WithBasis() + sage: C = Algebras(QQ).WithBasis().Commutative() + sage: C is Algebras(QQ).Commutative().WithBasis() True When ``axiom`` is not defined for ``self``, ``self`` is returned:: @@ -2252,7 +2258,9 @@ def _sort(categories): Category of commutative magmas, Category of finite sets, Category of facade sets) - sage: Category._sort(Category._flatten_categories([Sets().Finite(), Algebras(QQ).WithBasis(), Semigroups().Finite(), Sets().Facade(),Algebras(QQ).Commutative(), Algebras(QQ).Graded().WithBasis()], sage.categories.category.JoinCategory)) + sage: Category._sort(Category._flatten_categories([Sets().Finite(), Algebras(QQ).WithBasis(), Semigroups().Finite(), + ....: Sets().Facade(), Algebras(QQ).Commutative(), Algebras(QQ).Graded().WithBasis()], + ....: sage.categories.category.JoinCategory)) (Category of algebras with basis over Rational Field, Category of algebras with basis over Rational Field, Category of graded algebras over Rational Field, @@ -2597,7 +2605,7 @@ def category_sample(): EXAMPLES:: sage: from sage.categories.category import category_sample - sage: sorted(category_sample(), key=str) + sage: sorted(category_sample(), key=str) # optional - sage.groups [Category of G-sets for Symmetric group of order 8! as a permutation group, Category of Hecke modules over Rational Field, Category of Lie algebras over Rational Field, @@ -2636,14 +2644,14 @@ def category_graph(categories=None): EXAMPLES:: - sage: G = sage.categories.category.category_graph(categories = [Groups()]) - sage: G.vertices(sort=True) + sage: G = sage.categories.category.category_graph(categories=[Groups()]) # optional - sage.graphs + sage: G.vertices(sort=True) # optional - sage.graphs ['groups', 'inverse unital magmas', 'magmas', 'monoids', 'objects', 'semigroups', 'sets', 'sets with partial maps', 'unital magmas'] - sage: G.plot() + sage: G.plot() # optional - sage.graphs sage.plot Graphics object consisting of 20 graphics primitives - sage: sage.categories.category.category_graph().plot() + sage: sage.categories.category.category_graph().plot() # optional - sage.graphs sage.plot Graphics object consisting of ... graphics primitives """ from sage import graphs @@ -2691,15 +2699,15 @@ class CategoryWithParameters(Category): EXAMPLES:: - sage: C1 = Algebras(GF(5)) - sage: C2 = Algebras(GF(3)) + sage: C1 = Algebras(GF(5)) # optional - sage.rings.finite_rings + sage: C2 = Algebras(GF(3)) # optional - sage.rings.finite_rings sage: C3 = Algebras(ZZ) sage: from sage.categories.category import CategoryWithParameters - sage: isinstance(C1, CategoryWithParameters) + sage: isinstance(C1, CategoryWithParameters) # optional - sage.rings.finite_rings True - sage: C1.parent_class is C2.parent_class + sage: C1.parent_class is C2.parent_class # optional - sage.rings.finite_rings True - sage: C1.parent_class is C3.parent_class + sage: C1.parent_class is C3.parent_class # optional - sage.rings.finite_rings False .. automethod:: Category._make_named_class @@ -2744,7 +2752,7 @@ def _make_named_class(self, name, method_provider, cache=False, **options): The categories of bimodules over the fields ``CC`` or ``RR`` provide the same methods to their parents and elements:: - sage: Bimodules(ZZ,RR).parent_class is Bimodules(ZZ,RDF).parent_class #indirect doctest + sage: Bimodules(ZZ,RR).parent_class is Bimodules(ZZ,RDF).parent_class # indirect doctest True sage: Bimodules(CC,ZZ).element_class is Bimodules(RR,ZZ).element_class True @@ -2918,12 +2926,12 @@ class JoinCategory(CategoryWithParameters): the underlying implementation is the same for all finite fields, we have:: - sage: G = SymmetricGroup(10) - sage: A3 = G.algebra(GF(3)) - sage: A5 = G.algebra(GF(5)) - sage: type(A3.category()) + sage: G = SymmetricGroup(10) # optional - sage.groups sage.rings.finite_rings + sage: A3 = G.algebra(GF(3)) # optional - sage.groups sage.rings.finite_rings + sage: A5 = G.algebra(GF(5)) # optional - sage.groups sage.rings.finite_rings + sage: type(A3.category()) # optional - sage.groups sage.rings.finite_rings - sage: type(A3) is type(A5) + sage: type(A3) is type(A5) # optional - sage.groups sage.rings.finite_rings True .. automethod:: Category._repr_object_names diff --git a/src/sage/categories/category_types.py b/src/sage/categories/category_types.py index 4469a57a996..ef0fb9472bb 100644 --- a/src/sage/categories/category_types.py +++ b/src/sage/categories/category_types.py @@ -72,14 +72,14 @@ def _call_(self, x): """ EXAMPLES:: - sage: V = VectorSpace(QQ,3) - sage: x = V.0 - sage: C = x.category() - sage: C + sage: V = VectorSpace(QQ, 3) # optional - sage.modules + sage: x = V.0 # optional - sage.modules + sage: C = x.category() # optional - sage.modules + sage: C # optional - sage.modules Category of elements of Vector space of dimension 3 over Rational Field - sage: w = C([1,2,3]); w # indirect doctest + sage: w = C([1, 2, 3]); w # indirect doctest # optional - sage.modules (1, 2, 3) - sage: w.category() + sage: w.category() # optional - sage.modules Category of elements of Vector space of dimension 3 over Rational Field """ return self.__object(x) @@ -129,9 +129,9 @@ def _latex_(self): r""" EXAMPLES:: - sage: V = VectorSpace(QQ,3) - sage: x = V.0 - sage: latex(x.category()) # indirect doctest + sage: V = VectorSpace(QQ, 3) # optional - sage.modules + sage: x = V.0 # optional - sage.modules + sage: latex(x.category()) # indirect doctest # optional - sage.modules \mathbf{Elt}_{\Bold{Q}^{3}} """ return "\\mathbf{Elt}_{%s}"%latex(self.__object) @@ -153,11 +153,11 @@ class Category_over_base(CategoryWithParameters): EXAMPLES:: - sage: Algebras(GF(2)).element_class is Algebras(GF(3)).element_class + sage: Algebras(GF(2)).element_class is Algebras(GF(3)).element_class # optional - sage.rings.finite_rings True - sage: C = GF(2).category() - sage: Algebras(GF(2)).parent_class is Algebras(C).parent_class + sage: C = GF(2).category() # optional - sage.rings.finite_rings + sage: Algebras(GF(2)).parent_class is Algebras(C).parent_class # optional - sage.rings.finite_rings True sage: C = ZZ.category() @@ -278,7 +278,7 @@ def _repr_object_names(self): 'algebras over Rational Field' sage: Algebras(Fields())._repr_object_names() 'algebras over fields' - sage: Algebras(GF(2).category())._repr_object_names() + sage: Algebras(GF(2).category())._repr_object_names() # optional - sage.rings.finite_rings 'algebras over (finite enumerated fields and subquotients of monoids and quotients of semigroups)' """ base = self.__base @@ -338,9 +338,9 @@ def __init__(self, base, name=None): EXAMPLES:: - sage: C = Algebras(GF(2)); C + sage: C = Algebras(GF(2)); C # optional - sage.rings.finite_rings Category of algebras over Finite Field of size 2 - sage: TestSuite(C).run() + sage: TestSuite(C).run() # optional - sage.rings.finite_rings """ from sage.categories.rings import Rings if not (base in Rings() or @@ -355,8 +355,8 @@ def base_ring(self): EXAMPLES:: - sage: C = Algebras(GF(2)) - sage: C.base_ring() + sage: C = Algebras(GF(2)) # optional - sage.rings.finite_rings + sage: C.base_ring() # optional - sage.rings.finite_rings Finite Field of size 2 """ return self.base() @@ -399,11 +399,11 @@ def _subcategory_hook_(self, C): sage: VectorSpaces(QQ)._subcategory_hook_(VectorSpaces(QQ) & Rings()) Unknown - sage: Sym = SymmetricFunctions(QQ) - sage: from sage.combinat.sf.sfa import SymmetricFunctionsBases - sage: Modules(QQ)._subcategory_hook_(SymmetricFunctionsBases(Sym)) + sage: Sym = SymmetricFunctions(QQ) # optional - sage.combinat + sage: from sage.combinat.sf.sfa import SymmetricFunctionsBases # optional - sage.combinat + sage: Modules(QQ)._subcategory_hook_(SymmetricFunctionsBases(Sym)) # optional - sage.combinat Unknown - sage: SymmetricFunctionsBases(Sym).is_subcategory(Modules(QQ)) + sage: SymmetricFunctionsBases(Sym).is_subcategory(Modules(QQ)) # optional - sage.combinat True Case 1: the two bases are categories; then the base of ``C`` @@ -411,7 +411,7 @@ def _subcategory_hook_(self, C): sage: VectorSpaces(Fields())._subcategory_hook_(Algebras(Fields())) True - sage: VectorSpaces(Fields())._subcategory_hook_(Algebras(Fields().Finite())) # todo: not implemented + sage: VectorSpaces(Fields())._subcategory_hook_(Algebras(Fields().Finite())) # todo: not implemented True sage: VectorSpaces(Fields().Finite())._subcategory_hook_(Algebras(Fields())) False @@ -419,7 +419,7 @@ def _subcategory_hook_(self, C): Case 2: the base of ``self`` is a category; then the base of ``C`` shall be a parent in this category:: - sage: VectorSpaces(Fields())._subcategory_hook_(Algebras(QQ)) # todo: not implemented + sage: VectorSpaces(Fields())._subcategory_hook_(Algebras(QQ)) # todo: not implemented True sage: VectorSpaces(Fields().Finite())._subcategory_hook_(Algebras(QQ)) False @@ -430,15 +430,17 @@ def _subcategory_hook_(self, C): True sage: VectorSpaces(CC)._subcategory_hook_(Algebras(QQ)) # base ring in different categories False - sage: VectorSpaces(GF(2))._subcategory_hook_(Algebras(GF(3))) # base ring in the same category + sage: VectorSpaces(GF(2))._subcategory_hook_(Algebras(GF(3))) # base ring in the same category # optional - sage.rings.finite_rings False Note; we need both previous tests since the distinction is made respectively using the parent class or the base ring:: - sage: issubclass(Algebras(QQ).parent_class, VectorSpaces(CC).parent_class) + sage: issubclass(Algebras(QQ).parent_class, # optional - sage.modules + ....: VectorSpaces(CC).parent_class) False - sage: issubclass(Algebras(GF(2)).parent_class, VectorSpaces(GF(3)).parent_class) + sage: issubclass(Algebras(GF(2)).parent_class, # optional - sage.modules sage.rings.finite_rings + ....: VectorSpaces(GF(3)).parent_class) True Check that :trac:`16618` is fixed: this `_subcategory_hook_` diff --git a/src/sage/categories/category_with_axiom.py b/src/sage/categories/category_with_axiom.py index 1c92e587456..a304ff996cd 100644 --- a/src/sage/categories/category_with_axiom.py +++ b/src/sage/categories/category_with_axiom.py @@ -182,7 +182,8 @@ class ``Semigroups.Infinite`` inheriting from :class:`CategoryWithAxiom`. :trac:`15648`), one should pass the option ``as_name`` to :class:`~sage.misc.lazy_import.LazyImport`:: - Finite = LazyImport('sage.categories.finite_groups', 'FiniteGroups', as_name='Finite') + Finite = LazyImport('sage.categories.finite_groups', 'FiniteGroups', + as_name='Finite') in order to prevent ``Groups.Finite`` to keep on reimporting ``FiniteGroups``. @@ -1730,7 +1731,8 @@ def base_category_class_and_axiom(cls): (, 'Finite') sage: base_category_class_and_axiom(FiniteDimensionalHopfAlgebrasWithBasis) - (, 'FiniteDimensional') + (, + 'FiniteDimensional') sage: base_category_class_and_axiom(HopfAlgebrasWithBasis) (, 'WithBasis') @@ -1742,7 +1744,9 @@ def base_category_class_and_axiom(cls): sage: base_category_class_and_axiom(FacadeSemigroups) Traceback (most recent call last): ... - AssertionError: Missing (lazy import) link for to for axiom Facade? + AssertionError: Missing (lazy import) link + for + to for axiom Facade? sage: Semigroups.Facade = FacadeSemigroups sage: base_category_class_and_axiom(FacadeSemigroups) @@ -1760,7 +1764,8 @@ def base_category_class_and_axiom(cls): sage: base_category_class_and_axiom(Sets.Infinite) Traceback (most recent call last): ... - TypeError: Could not retrieve the base category class and axiom for . + TypeError: Could not retrieve the base category class and axiom + for . ... """ if "." in cls.__name__: @@ -1812,7 +1817,8 @@ def axiom_of_nested_class(cls, nested_cls): sage: from sage.categories.category_with_axiom import TestObjects, axiom_of_nested_class sage: axiom_of_nested_class(TestObjects, TestObjects.FiniteDimensional) 'FiniteDimensional' - sage: axiom_of_nested_class(TestObjects.FiniteDimensional, TestObjects.FiniteDimensional.Finite) + sage: axiom_of_nested_class(TestObjects.FiniteDimensional, + ....: TestObjects.FiniteDimensional.Finite) 'Finite' sage: axiom_of_nested_class(Sets, FiniteSets) 'Finite' @@ -2456,9 +2462,9 @@ def axioms(self): sage: C.axioms() frozenset({'Finite'}) - sage: C = Modules(GF(5)).FiniteDimensional(); C + sage: C = Modules(GF(5)).FiniteDimensional(); C # optional - sage.rings.finite_rings Category of finite dimensional vector spaces over Finite Field of size 5 - sage: sorted(C.axioms()) + sage: sorted(C.axioms()) # optional - sage.rings.finite_rings ['AdditiveAssociative', 'AdditiveCommutative', 'AdditiveInverse', 'AdditiveUnital', 'Finite', 'FiniteDimensional'] @@ -2466,7 +2472,7 @@ def axioms(self): ['AdditiveAssociative', 'AdditiveCommutative', 'AdditiveInverse', 'AdditiveUnital', 'Associative', 'Distributive', 'FiniteDimensional', 'Unital', 'WithBasis'] - sage: sorted(FiniteMonoids().Algebras(GF(3)).axioms()) + sage: sorted(FiniteMonoids().Algebras(GF(3)).axioms()) # optional - sage.rings.finite_rings ['AdditiveAssociative', 'AdditiveCommutative', 'AdditiveInverse', 'AdditiveUnital', 'Associative', 'Distributive', 'Finite', 'FiniteDimensional', 'Unital', 'WithBasis'] @@ -2543,7 +2549,8 @@ class CategoryWithAxiom_singleton(Category_singleton, CategoryWithAxiom):#, Cate sage: isinstance(C, Category_over_base_ring) # todo: not implemented True sage: C.FiniteDimensional() - Category of finite dimensional connected test objects over base ring over Ring of integers modulo 2 + Category of finite dimensional connected test objects + over base ring over Ring of integers modulo 2 sage: C.Connected() Category of connected test objects over base ring over Ring of integers modulo 2 """ @@ -2790,7 +2797,8 @@ def super_categories(self): Category of unital test objects over base ring over Rational Field sage: TestObjectsOverBaseRing.FiniteDimensional.Unital.an_instance() Category of finite dimensional unital test objects over base ring over Rational Field - sage: TestSuite(TestObjectsOverBaseRing(QQ).FiniteDimensional().Unital().Commutative()).run() + sage: C = TestObjectsOverBaseRing(QQ).FiniteDimensional().Unital().Commutative() + sage: TestSuite(C).run() """ return [TestObjects()] diff --git a/src/sage/categories/chain_complexes.py b/src/sage/categories/chain_complexes.py index b1d8c578e60..8ce3e6145bc 100644 --- a/src/sage/categories/chain_complexes.py +++ b/src/sage/categories/chain_complexes.py @@ -67,27 +67,27 @@ def homology(self, n=None): EXAMPLES:: - sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) - sage: C.homology(0) + sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) # optional - sage.modules + sage: C.homology(0) # optional - sage.modules Z x Z - sage: C.homology(1) + sage: C.homology(1) # optional - sage.modules Z x C3 - sage: C.homology(2) + sage: C.homology(2) # optional - sage.modules 0 :: - sage: A. = GradedCommutativeAlgebra(QQ, degrees=(2, 2, 3)) - sage: C = A.cdg_algebra({z: x*y}) - sage: C.homology(0) + sage: A. = GradedCommutativeAlgebra(QQ, degrees=(2, 2, 3)) # optional - sage.combinat sage.modules + sage: C = A.cdg_algebra({z: x*y}) # optional - sage.combinat sage.modules + sage: C.homology(0) # optional - sage.combinat sage.modules Free module generated by {[1]} over Rational Field - sage: C.homology(1) + sage: C.homology(1) # optional - sage.combinat sage.modules Free module generated by {} over Rational Field - sage: C.homology(2) + sage: C.homology(2) # optional - sage.combinat sage.modules Free module generated by {[x], [y]} over Rational Field - sage: C.homology(3) + sage: C.homology(3) # optional - sage.combinat sage.modules Free module generated by {} over Rational Field - sage: C.homology(4) + sage: C.homology(4) # optional - sage.combinat sage.modules Free module generated by {[x^2], [y^2]} over Rational Field """ @@ -99,17 +99,18 @@ def differential(self, *args, **kwargs): EXAMPLES:: - sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) - sage: C.differential(0) + sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) # optional - sage.modules + sage: C.differential(0) # optional - sage.modules [3 0 0] [0 0 0] :: - sage: A. = GradedCommutativeAlgebra(QQ, degrees=(2, 2, 3)) - sage: C = A.cdg_algebra({z: x*y}) - sage: C.differential() - Differential of Commutative Differential Graded Algebra with generators ('x', 'y', 'z') in degrees (2, 2, 3) over Rational Field + sage: A. = GradedCommutativeAlgebra(QQ, degrees=(2, 2, 3)) # optional - sage.combinat sage.modules + sage: C = A.cdg_algebra({z: x*y}) # optional - sage.combinat sage.modules + sage: C.differential() # optional - sage.combinat sage.modules + Differential of Commutative Differential Graded Algebra with + generators ('x', 'y', 'z') in degrees (2, 2, 3) over Rational Field Defn: x --> 0 y --> 0 z --> x*y @@ -123,10 +124,10 @@ def lift_from_homology(self, x): EXAMPLES:: - sage: E3 = EuclideanSpace(3) # optional - sage.symbolic - sage: C = E3.de_rham_complex() # optional - sage.symbolic - sage: one = C.homology().one() # optional - sage.symbolic - sage: C.lift_from_homology(one) # optional - sage.symbolic + sage: E3 = EuclideanSpace(3) # optional - sage.symbolic + sage: C = E3.de_rham_complex() # optional - sage.symbolic + sage: one = C.homology().one() # optional - sage.symbolic + sage: C.lift_from_homology(one) # optional - sage.symbolic Mixed differential form one on the Euclidean space E^3 """ @@ -143,10 +144,10 @@ def reduce_to_homology(self, x, n=None): EXAMPLES:: - sage: E3 = EuclideanSpace(3) # optional - sage.symbolic - sage: C = E3.de_rham_complex() # optional - sage.symbolic - sage: one = C.one() # optional - sage.symbolic - sage: C.reduce_to_homology(one) # optional - sage.symbolic + sage: E3 = EuclideanSpace(3) # optional - sage.symbolic + sage: C = E3.de_rham_complex() # optional - sage.symbolic + sage: one = C.one() # optional - sage.symbolic + sage: C.reduce_to_homology(one) # optional - sage.symbolic [one] """ try: @@ -168,35 +169,35 @@ class HomologyFunctor(Functor): EXAMPLES:: - sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) - sage: H = HomologyFunctor(ChainComplexes(ZZ), 1) - sage: H(C) + sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) # optional - sage.modules + sage: H = HomologyFunctor(ChainComplexes(ZZ), 1) # optional - sage.modules + sage: H(C) # optional - sage.modules Z x C3 :: - sage: A. = GradedCommutativeAlgebra(QQ, degrees=(2, 2, 3)) - sage: C = A.cdg_algebra({z: x*y}) - sage: H = HomologyFunctor(ChainComplexes(QQ), 2) - sage: H(C) + sage: A. = GradedCommutativeAlgebra(QQ, degrees=(2, 2, 3)) # optional - sage.combinat sage.modules + sage: C = A.cdg_algebra({z: x*y}) # optional - sage.combinat sage.modules + sage: H = HomologyFunctor(ChainComplexes(QQ), 2) # optional - sage.combinat sage.modules + sage: H(C) # optional - sage.combinat sage.modules Free module generated by {[x], [y]} over Rational Field Applying to a chain map:: - sage: S = simplicial_complexes.Sphere(1); S + sage: S = simplicial_complexes.Sphere(1); S # optional - sage.graphs Minimal triangulation of the 1-sphere - sage: C = S.chain_complex() - sage: C.differential() + sage: C = S.chain_complex() # optional - sage.graphs sage.modules + sage: C.differential() # optional - sage.graphs sage.modules {0: [], 1: [-1 -1 0] [ 1 0 -1] [ 0 1 1], 2: []} - sage: f = {0:zero_matrix(ZZ,3,3),1:zero_matrix(ZZ,3,3)} - sage: G = Hom(C,C) - sage: x = G(f) - sage: H = HomologyFunctor(ChainComplexes(ZZ), 1) - sage: H(C) + sage: f = {0: zero_matrix(ZZ,3,3), 1: zero_matrix(ZZ,3,3)} # optional - sage.modules + sage: G = Hom(C, C) # optional - sage.graphs sage.modules + sage: x = G(f) # optional - sage.graphs sage.modules + sage: H = HomologyFunctor(ChainComplexes(ZZ), 1) # optional - sage.graphs sage.modules + sage: H(C) # optional - sage.graphs sage.modules Z - sage: H(x) + sage: H(x) # optional - sage.graphs sage.modules Generic morphism: From: Z To: Z @@ -225,9 +226,9 @@ def _apply_functor(self, x): TESTS:: - sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) - sage: H = HomologyFunctor(ChainComplexes(ZZ), 1) - sage: H._apply_functor(C) + sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) # optional - sage.modules + sage: H = HomologyFunctor(ChainComplexes(ZZ), 1) # optional - sage.modules + sage: H._apply_functor(C) # optional - sage.modules Z x C3 """ @@ -239,15 +240,15 @@ def _apply_functor_to_morphism(self, f): TESTS:: - sage: E3 = EuclideanSpace(3) # optional - sage.symbolic - sage: C = E3.de_rham_complex() # optional - sage.symbolic - sage: id = Hom(C, C).identity() # optional - sage.symbolic - sage: H = HomologyFunctor(ChainComplexes(SR)) # optional - sage.symbolic - sage: id_star = H(id); id_star # optional - sage.symbolic + sage: E3 = EuclideanSpace(3) # optional - sage.symbolic + sage: C = E3.de_rham_complex() # optional - sage.symbolic + sage: id = Hom(C, C).identity() # optional - sage.symbolic + sage: H = HomologyFunctor(ChainComplexes(SR)) # optional - sage.symbolic + sage: id_star = H(id); id_star # optional - sage.symbolic Generic endomorphism of De Rham cohomology ring on the Euclidean space E^3 - sage: one = H(C).one() # optional - sage.symbolic - sage: id_star(one) # optional - sage.symbolic + sage: one = H(C).one() # optional - sage.symbolic + sage: id_star(one) # optional - sage.symbolic [one] """ from .morphism import SetMorphism diff --git a/src/sage/categories/classical_crystals.py b/src/sage/categories/classical_crystals.py index 581b094f6d8..744b1cb6e44 100644 --- a/src/sage/categories/classical_crystals.py +++ b/src/sage/categories/classical_crystals.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.graphs, sage.combinat r""" Classical Crystals """ diff --git a/src/sage/categories/coalgebras.py b/src/sage/categories/coalgebras.py index ecbf5d15baf..870315dc644 100644 --- a/src/sage/categories/coalgebras.py +++ b/src/sage/categories/coalgebras.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat r""" Coalgebras """ diff --git a/src/sage/categories/coalgebras_with_basis.py b/src/sage/categories/coalgebras_with_basis.py index 5518804d649..844f5e5a294 100644 --- a/src/sage/categories/coalgebras_with_basis.py +++ b/src/sage/categories/coalgebras_with_basis.py @@ -61,10 +61,12 @@ def coproduct_on_basis(self, i): EXAMPLES:: - sage: A = HopfAlgebrasWithBasis(QQ).example(); A - An example of Hopf algebra with basis: the group algebra of the Dihedral group of order 6 as a permutation group over Rational Field - sage: (a, b) = A._group.gens() - sage: A.coproduct_on_basis(a) + sage: A = HopfAlgebrasWithBasis(QQ).example(); A # optional - sage.groups sage.modules + An example of Hopf algebra with basis: + the group algebra of the Dihedral group of order 6 + as a permutation group over Rational Field + sage: (a, b) = A._group.gens() # optional - sage.groups sage.modules + sage: A.coproduct_on_basis(a) # optional - sage.groups sage.modules B[(1,2,3)] # B[(1,2,3)] """ @@ -79,12 +81,14 @@ def coproduct(self): EXAMPLES:: - sage: A = HopfAlgebrasWithBasis(QQ).example(); A - An example of Hopf algebra with basis: the group algebra of the Dihedral group of order 6 as a permutation group over Rational Field - sage: [a,b] = A.algebra_generators() - sage: a, A.coproduct(a) + sage: A = HopfAlgebrasWithBasis(QQ).example(); A # optional - sage.groups sage.modules + An example of Hopf algebra with basis: + the group algebra of the Dihedral group of order 6 + as a permutation group over Rational Field + sage: a, b = A.algebra_generators() # optional - sage.groups sage.modules + sage: a, A.coproduct(a) # optional - sage.groups sage.modules (B[(1,2,3)], B[(1,2,3)] # B[(1,2,3)]) - sage: b, A.coproduct(b) + sage: b, A.coproduct(b) # optional - sage.groups sage.modules (B[(1,3)], B[(1,3)] # B[(1,3)]) """ @@ -111,10 +115,12 @@ def counit_on_basis(self, i): EXAMPLES:: - sage: A = HopfAlgebrasWithBasis(QQ).example(); A - An example of Hopf algebra with basis: the group algebra of the Dihedral group of order 6 as a permutation group over Rational Field - sage: (a, b) = A._group.gens() - sage: A.counit_on_basis(a) + sage: A = HopfAlgebrasWithBasis(QQ).example(); A # optional - sage.groups sage.modules + An example of Hopf algebra with basis: + the group algebra of the Dihedral group of order 6 + as a permutation group over Rational Field + sage: (a, b) = A._group.gens() # optional - sage.groups sage.modules + sage: A.counit_on_basis(a) # optional - sage.groups sage.modules 1 """ @@ -127,12 +133,14 @@ def counit(self): EXAMPLES:: - sage: A = HopfAlgebrasWithBasis(QQ).example(); A - An example of Hopf algebra with basis: the group algebra of the Dihedral group of order 6 as a permutation group over Rational Field - sage: [a,b] = A.algebra_generators() - sage: a, A.counit(a) + sage: A = HopfAlgebrasWithBasis(QQ).example(); A # optional - sage.groups sage.modules + An example of Hopf algebra with basis: + the group algebra of the Dihedral group of order 6 + as a permutation group over Rational Field + sage: a, b = A.algebra_generators() # optional - sage.groups sage.modules + sage: a, A.counit(a) # optional - sage.groups sage.modules (B[(1,2,3)], 1) - sage: b, A.counit(b) + sage: b, A.counit(b) # optional - sage.groups sage.modules (B[(1,3)], 1) """ @@ -152,29 +160,29 @@ def coproduct_iterated(self, n=1): EXAMPLES:: - sage: Psi = NonCommutativeSymmetricFunctions(QQ).Psi() - sage: Psi[2,2].coproduct_iterated(0) + sage: Psi = NonCommutativeSymmetricFunctions(QQ).Psi() # optional - sage.combinat + sage: Psi[2,2].coproduct_iterated(0) # optional - sage.combinat Psi[2, 2] - sage: Psi[2,2].coproduct_iterated(2) + sage: Psi[2,2].coproduct_iterated(2) # optional - sage.combinat Psi[] # Psi[] # Psi[2, 2] + 2*Psi[] # Psi[2] # Psi[2] + Psi[] # Psi[2, 2] # Psi[] + 2*Psi[2] # Psi[] # Psi[2] + 2*Psi[2] # Psi[2] # Psi[] + Psi[2, 2] # Psi[] # Psi[] TESTS:: - sage: p = SymmetricFunctions(QQ).p() - sage: p[5,2,2].coproduct_iterated() + sage: p = SymmetricFunctions(QQ).p() # optional - sage.combinat + sage: p[5,2,2].coproduct_iterated() # optional - sage.combinat p[] # p[5, 2, 2] + 2*p[2] # p[5, 2] + p[2, 2] # p[5] + p[5] # p[2, 2] + 2*p[5, 2] # p[2] + p[5, 2, 2] # p[] - sage: p([]).coproduct_iterated(3) + sage: p([]).coproduct_iterated(3) # optional - sage.combinat p[] # p[] # p[] # p[] :: - sage: Psi = NonCommutativeSymmetricFunctions(QQ).Psi() - sage: Psi[2,2].coproduct_iterated(0) + sage: Psi = NonCommutativeSymmetricFunctions(QQ).Psi() # optional - sage.combinat + sage: Psi[2,2].coproduct_iterated(0) # optional - sage.combinat Psi[2, 2] - sage: Psi[2,2].coproduct_iterated(3) + sage: Psi[2,2].coproduct_iterated(3) # optional - sage.combinat Psi[] # Psi[] # Psi[] # Psi[2, 2] + 2*Psi[] # Psi[] # Psi[2] # Psi[2] + Psi[] # Psi[] # Psi[2, 2] # Psi[] + 2*Psi[] # Psi[2] # Psi[] # Psi[2] + 2*Psi[] # Psi[2] # Psi[2] # Psi[] + Psi[] # Psi[2, 2] # Psi[] # Psi[] @@ -183,14 +191,14 @@ def coproduct_iterated(self, n=1): :: - sage: m = SymmetricFunctionsNonCommutingVariables(QQ).m() - sage: m[[1,3],[2]].coproduct_iterated(2) + sage: m = SymmetricFunctionsNonCommutingVariables(QQ).m() # optional - sage.combinat + sage: m[[1,3],[2]].coproduct_iterated(2) # optional - sage.combinat m{} # m{} # m{{1, 3}, {2}} + m{} # m{{1}} # m{{1, 2}} + m{} # m{{1, 2}} # m{{1}} + m{} # m{{1, 3}, {2}} # m{} + m{{1}} # m{} # m{{1, 2}} + m{{1}} # m{{1, 2}} # m{} + m{{1, 2}} # m{} # m{{1}} + m{{1, 2}} # m{{1}} # m{} + m{{1, 3}, {2}} # m{} # m{} - sage: m[[]].coproduct_iterated(3), m[[1,3],[2]].coproduct_iterated(0) + sage: m[[]].coproduct_iterated(3), m[[1,3],[2]].coproduct_iterated(0) # optional - sage.combinat (m{} # m{} # m{} # m{}, m{{1, 3}, {2}}) """ if n < 0: diff --git a/src/sage/categories/commutative_additive_groups.py b/src/sage/categories/commutative_additive_groups.py index c1383022833..9300f4d6db5 100644 --- a/src/sage/categories/commutative_additive_groups.py +++ b/src/sage/categories/commutative_additive_groups.py @@ -79,10 +79,11 @@ def additive_order(self): sage: G((0,1)).additive_order() +Infinity - sage: K = GF(9) - sage: H = cartesian_product([cartesian_product([Zmod(2),Zmod(9)]), K]) - sage: z = H(((1,2), K.gen())) - sage: z.additive_order() + sage: K = GF(9) # optional - sage.rings.finite_rings + sage: H = cartesian_product([ # optional - sage.rings.finite_rings + ....: cartesian_product([Zmod(2), Zmod(9)]), K]) + sage: z = H(((1,2), K.gen())) # optional - sage.rings.finite_rings + sage: z.additive_order() # optional - sage.rings.finite_rings 18 """ from sage.rings.infinity import Infinity diff --git a/src/sage/categories/commutative_algebra_ideals.py b/src/sage/categories/commutative_algebra_ideals.py index 15824e09644..e0835848e91 100644 --- a/src/sage/categories/commutative_algebra_ideals.py +++ b/src/sage/categories/commutative_algebra_ideals.py @@ -24,14 +24,16 @@ class CommutativeAlgebraIdeals(Category_ideal): sage: C = CommutativeAlgebraIdeals(QQ['x']) sage: C - Category of commutative algebra ideals in Univariate Polynomial Ring in x over Rational Field + Category of commutative algebra ideals in + Univariate Polynomial Ring in x over Rational Field """ def __init__(self, A): """ EXAMPLES:: sage: CommutativeAlgebraIdeals(ZZ['x']) - Category of commutative algebra ideals in Univariate Polynomial Ring in x over Integer Ring + Category of commutative algebra ideals in + Univariate Polynomial Ring in x over Integer Ring sage: CommutativeAlgebraIdeals(ZZ) Traceback (most recent call last): @@ -43,7 +45,7 @@ def __init__(self, A): ... TypeError: A (=Ring of integers modulo 4) must be a commutative algebra - sage: CommutativeAlgebraIdeals(Partitions(4)) + sage: CommutativeAlgebraIdeals(Partitions(4)) # optional - sage.combinat sage.modules Traceback (most recent call last): ... TypeError: A (=Partitions of the integer 4) must be a commutative algebra diff --git a/src/sage/categories/commutative_algebras.py b/src/sage/categories/commutative_algebras.py index cff24e1298a..bdff573db87 100644 --- a/src/sage/categories/commutative_algebras.py +++ b/src/sage/categories/commutative_algebras.py @@ -22,8 +22,8 @@ class CommutativeAlgebras(CategoryWithAxiom_over_base_ring): EXAMPLES:: - sage: M = CommutativeAlgebras(GF(19)) - sage: M + sage: M = CommutativeAlgebras(GF(19)) # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings Category of commutative algebras over Finite Field of size 19 sage: CommutativeAlgebras(QQ).super_categories() [Category of algebras over Rational Field, Category of commutative rings] @@ -53,7 +53,7 @@ def __contains__(self, A): True sage: QQ['a,b'] in CommutativeAlgebras(QQ) True - sage: FreeAlgebra(QQ,2,'a,b') in CommutativeAlgebras(QQ) + sage: FreeAlgebra(QQ, 2, 'a,b') in CommutativeAlgebras(QQ) # optional - sage.combinat False TODO: get rid of this method once all commutative algebras in @@ -80,12 +80,12 @@ def extra_super_categories(self): TESTS:: - sage: X = algebras.Shuffle(QQ, 'ab') - sage: Y = algebras.Shuffle(QQ, 'bc') - sage: X in Algebras(QQ).Commutative() + sage: X = algebras.Shuffle(QQ, 'ab') # optional - sage.combinat + sage: Y = algebras.Shuffle(QQ, 'bc') # optional - sage.combinat + sage: X in Algebras(QQ).Commutative() # optional - sage.combinat True - sage: T = tensor([X, Y]) - sage: T in CommutativeRings() + sage: T = tensor([X, Y]) # optional - sage.combinat + sage: T in CommutativeRings() # optional - sage.combinat True """ return [CommutativeRings()] diff --git a/src/sage/categories/commutative_ring_ideals.py b/src/sage/categories/commutative_ring_ideals.py index 115b79afb80..837f1edf944 100644 --- a/src/sage/categories/commutative_ring_ideals.py +++ b/src/sage/categories/commutative_ring_ideals.py @@ -35,7 +35,7 @@ def __init__(self, R): TESTS:: - sage: CommutativeRingIdeals(Partitions(4)) + sage: CommutativeRingIdeals(Partitions(4)) # optional - sage.combinat Traceback (most recent call last): ... TypeError: R (=Partitions of the integer 4) must be a commutative ring diff --git a/src/sage/categories/commutative_rings.py b/src/sage/categories/commutative_rings.py index 71e08a5070d..6219c1070bb 100644 --- a/src/sage/categories/commutative_rings.py +++ b/src/sage/categories/commutative_rings.py @@ -35,14 +35,14 @@ class CommutativeRings(CategoryWithAxiom): sage: QQ['x,y,z'] in CommutativeRings() True - sage: GroupAlgebra(DihedralGroup(3), QQ) in CommutativeRings() + sage: GroupAlgebra(DihedralGroup(3), QQ) in CommutativeRings() # optional - sage.groups sage.modules False - sage: MatrixSpace(QQ,2,2) in CommutativeRings() + sage: MatrixSpace(QQ, 2, 2) in CommutativeRings() # optional - sage.modules False GroupAlgebra should be fixed:: - sage: GroupAlgebra(CyclicPermutationGroup(3), QQ) in CommutativeRings() # todo: not implemented + sage: GroupAlgebra(CyclicPermutationGroup(3), QQ) in CommutativeRings() # todo: not implemented # optional - sage.groups sage.modules True """ @@ -110,92 +110,98 @@ def over(self, base=None, gen=None, gens=None, name=None, names=None): We construct an extension of finite fields:: - sage: F = GF(5^2) - sage: k = GF(5^4) - sage: z4 = k.gen() + sage: F = GF(5^2) # optional - sage.rings.finite_rings + sage: k = GF(5^4) # optional - sage.rings.finite_rings + sage: z4 = k.gen() # optional - sage.rings.finite_rings - sage: K = k.over(F) - sage: K - Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base + sage: K = k.over(F) # optional - sage.rings.finite_rings + sage: K # optional - sage.rings.finite_rings + Field in z4 with defining polynomial + x^2 + (4*z2 + 3)*x + z2 over its base If not explicitly given, the default generator of the top ring (here k) is used and the same name is kept:: - sage: K.gen() + sage: K.gen() # optional - sage.rings.finite_rings z4 - sage: K(z4) + sage: K(z4) # optional - sage.rings.finite_rings z4 However, it is possible to specify another generator and/or another name. For example:: - sage: Ka = k.over(F, name='a') - sage: Ka - Field in a with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base - sage: Ka.gen() + sage: Ka = k.over(F, name='a') # optional - sage.rings.finite_rings + sage: Ka # optional - sage.rings.finite_rings + Field in a with defining polynomial + x^2 + (4*z2 + 3)*x + z2 over its base + sage: Ka.gen() # optional - sage.rings.finite_rings a - sage: Ka(z4) + sage: Ka(z4) # optional - sage.rings.finite_rings a - sage: Kb = k.over(F, gen=-z4+1, name='b') - sage: Kb + sage: Kb = k.over(F, gen=-z4+1, name='b') # optional - sage.rings.finite_rings + sage: Kb # optional - sage.rings.finite_rings Field in b with defining polynomial x^2 + z2*x + 4 over its base - sage: Kb.gen() + sage: Kb.gen() # optional - sage.rings.finite_rings b - sage: Kb(-z4+1) + sage: Kb(-z4+1) # optional - sage.rings.finite_rings b Note that the shortcut ``K.`` is also available:: - sage: KKa. = k.over(F) - sage: KKa is Ka + sage: KKa. = k.over(F) # optional - sage.rings.finite_rings + sage: KKa is Ka # optional - sage.rings.finite_rings True Building an extension on top of another extension is allowed:: - sage: L = GF(5^12).over(K) - sage: L - Field in z12 with defining polynomial x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base - sage: L.base_ring() - Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base + sage: L = GF(5^12).over(K) # optional - sage.rings.finite_rings + sage: L # optional - sage.rings.finite_rings + Field in z12 with defining polynomial + x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base + sage: L.base_ring() # optional - sage.rings.finite_rings + Field in z4 with defining polynomial + x^2 + (4*z2 + 3)*x + z2 over its base The successive bases of an extension are accessible via the method :meth:`sage.rings.ring_extension.RingExtension_generic.bases`:: - sage: L.bases() - [Field in z12 with defining polynomial x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base, - Field in z4 with defining polynomial x^2 + (4*z2 + 3)*x + z2 over its base, + sage: L.bases() # optional - sage.rings.finite_rings + [Field in z12 with defining polynomial + x^3 + (1 + (4*z2 + 2)*z4)*x^2 + (2 + 2*z4)*x - z4 over its base, + Field in z4 with defining polynomial + x^2 + (4*z2 + 3)*x + z2 over its base, Finite Field in z2 of size 5^2] When ``base`` is omitted, the canonical base of the ring is used:: sage: S. = QQ[] - sage: E = S.over() - sage: E + sage: E = S.over() # optional - sage.modules + sage: E # optional - sage.modules Univariate Polynomial Ring in x over Rational Field over its base - sage: E.base_ring() + sage: E.base_ring() # optional - sage.modules Rational Field Here is an example where ``base`` is a defining morphism:: - sage: k. = QQ.extension(x^2 - 2) - sage: l. = QQ.extension(x^4 - 2) - sage: f = k.hom([b^2]) - sage: L = l.over(f) - sage: L + sage: k. = QQ.extension(x^2 - 2) # optional - sage.rings.number_field + sage: l. = QQ.extension(x^4 - 2) # optional - sage.rings.number_field + sage: f = k.hom([b^2]) # optional - sage.rings.number_field + sage: L = l.over(f) # optional - sage.rings.number_field + sage: L # optional - sage.rings.number_field Field in b with defining polynomial x^2 - a over its base - sage: L.base_ring() + sage: L.base_ring() # optional - sage.rings.number_field Number Field in a with defining polynomial x^2 - 2 Similarly, one can create a tower of extensions:: - sage: K = k.over() - sage: L = l.over(Hom(K,l)(f)) - sage: L + sage: K = k.over() # optional - sage.rings.number_field + sage: L = l.over(Hom(K, l)(f)) # optional - sage.rings.number_field + sage: L # optional - sage.rings.number_field Field in b with defining polynomial x^2 - a over its base - sage: L.base_ring() + sage: L.base_ring() # optional - sage.rings.number_field Field in a with defining polynomial x^2 - 2 over its base - sage: L.bases() + sage: L.bases() # optional - sage.rings.number_field [Field in b with defining polynomial x^2 - a over its base, Field in a with defining polynomial x^2 - 2 over its base, Rational Field] @@ -221,7 +227,8 @@ class Finite(CategoryWithAxiom): EXAMPLES:: - sage: cartesian_product([Zmod(34), GF(5)]) in Rings().Commutative().Finite() + sage: cartesian_product([Zmod(34), # optional - sage.rings.finite_rings + ....: GF(5)]) in Rings().Commutative().Finite() True """ class ParentMethods: @@ -278,34 +285,34 @@ def cyclotomic_cosets(self, q, cosets=None): cyclic, the set of squares is a particular case of cyclotomic coset:: - sage: K = GF(25,'z') - sage: a = K.multiplicative_generator() - sage: K.cyclotomic_cosets(a**2,cosets=[1]) + sage: K = GF(25, 'z') # optional - sage.rings.finite_rings + sage: a = K.multiplicative_generator() # optional - sage.rings.finite_rings + sage: K.cyclotomic_cosets(a**2, cosets=[1]) # optional - sage.rings.finite_rings [[1, 2, 3, 4, z + 1, z + 3, 2*z + 1, 2*z + 2, 3*z + 3, 3*z + 4, 4*z + 2, 4*z + 4]] - sage: sorted(b for b in K if not b.is_zero() and b.is_square()) + sage: sorted(b for b in K if not b.is_zero() and b.is_square()) # optional - sage.rings.finite_rings [1, 2, 3, 4, z + 1, z + 3, 2*z + 1, 2*z + 2, 3*z + 3, 3*z + 4, 4*z + 2, 4*z + 4] We compute some examples of minimal polynomials:: - sage: K = GF(27,'z') - sage: a = K.multiplicative_generator() - sage: R. = PolynomialRing(K, 'X') - sage: a.minimal_polynomial('X') + sage: K = GF(27, 'z') # optional - sage.rings.finite_rings + sage: a = K.multiplicative_generator() # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(K, 'X') # optional - sage.rings.finite_rings + sage: a.minimal_polynomial('X') # optional - sage.rings.finite_rings X^3 + 2*X + 1 - sage: cyc3 = Zmod(26).cyclotomic_cosets(3,cosets=[1]); cyc3 + sage: cyc3 = Zmod(26).cyclotomic_cosets(3, cosets=[1]); cyc3 # optional - sage.rings.finite_rings [[1, 3, 9]] - sage: prod(X - a**i for i in cyc3[0]) + sage: prod(X - a**i for i in cyc3[0]) # optional - sage.rings.finite_rings X^3 + 2*X + 1 - sage: (a**7).minimal_polynomial('X') + sage: (a**7).minimal_polynomial('X') # optional - sage.rings.finite_rings X^3 + X^2 + 2*X + 1 - sage: cyc7 = Zmod(26).cyclotomic_cosets(3,cosets=[7]); cyc7 + sage: cyc7 = Zmod(26).cyclotomic_cosets(3, cosets=[7]); cyc7 # optional - sage.rings.finite_rings [[7, 11, 21]] - sage: prod(X - a**i for i in cyc7[0]) + sage: prod(X - a**i for i in cyc7[0]) # optional - sage.rings.finite_rings X^3 + X^2 + 2*X + 1 Cyclotomic cosets of fields are useful in combinatorial design @@ -314,26 +321,26 @@ def cyclotomic_cosets(self, q, cosets=None): :mod:`~sage.combinat.designs.difference_family`). This is illustrated on the following examples:: - sage: K = GF(5) - sage: a = K.multiplicative_generator() - sage: H = K.cyclotomic_cosets(a**2, cosets=[1,2]); H + sage: K = GF(5) # optional - sage.rings.finite_rings + sage: a = K.multiplicative_generator() # optional - sage.rings.finite_rings + sage: H = K.cyclotomic_cosets(a**2, cosets=[1, 2]); H # optional - sage.rings.finite_rings [[1, 4], [2, 3]] - sage: sorted(x-y for D in H for x in D for y in D if x != y) + sage: sorted(x - y for D in H for x in D for y in D if x != y) # optional - sage.rings.finite_rings [1, 2, 3, 4] - sage: K = GF(37) - sage: a = K.multiplicative_generator() - sage: H = K.cyclotomic_cosets(a**4, cosets=[1]); H + sage: K = GF(37) # optional - sage.rings.finite_rings + sage: a = K.multiplicative_generator() # optional - sage.rings.finite_rings + sage: H = K.cyclotomic_cosets(a**4, cosets=[1]); H # optional - sage.rings.finite_rings [[1, 7, 9, 10, 12, 16, 26, 33, 34]] - sage: sorted(x-y for D in H for x in D for y in D if x != y) + sage: sorted(x - y for D in H for x in D for y in D if x != y) # optional - sage.rings.finite_rings [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, ..., 33, 34, 34, 35, 35, 36, 36] The method ``cyclotomic_cosets`` works on any finite commutative ring:: - sage: R = cartesian_product([GF(7), Zmod(14)]) - sage: a = R((3,5)) - sage: R.cyclotomic_cosets((3,5), [(1,1)]) + sage: R = cartesian_product([GF(7), Zmod(14)]) # optional - sage.rings.finite_rings + sage: a = R((3,5)) # optional - sage.rings.finite_rings + sage: R.cyclotomic_cosets((3,5), [(1,1)]) # optional - sage.rings.finite_rings [[(1, 1), (2, 11), (3, 5), (4, 9), (5, 3), (6, 13)]] """ q = self(q) @@ -373,7 +380,8 @@ def extra_super_categories(self): sage: CommutativeRings().Commutative().CartesianProducts().extra_super_categories() [Category of commutative rings] - sage: cartesian_product([ZZ, Zmod(34), QQ, GF(5)]) in CommutativeRings() + sage: cartesian_product([ZZ, Zmod(34), # optional - sage.rings.finite_rings + ....: QQ, GF(5)]) in CommutativeRings() True """ return [CommutativeRings()] diff --git a/src/sage/categories/complete_discrete_valuation.py b/src/sage/categories/complete_discrete_valuation.py index e7bc01ddd28..71c7ec57015 100644 --- a/src/sage/categories/complete_discrete_valuation.py +++ b/src/sage/categories/complete_discrete_valuation.py @@ -22,13 +22,13 @@ class CompleteDiscreteValuationRings(Category_singleton): EXAMPLES:: - sage: Zp(7) in CompleteDiscreteValuationRings() + sage: Zp(7) in CompleteDiscreteValuationRings() # optional - sage.rings.padics True sage: QQ in CompleteDiscreteValuationRings() False sage: QQ[['u']] in CompleteDiscreteValuationRings() True - sage: Qp(7) in CompleteDiscreteValuationRings() + sage: Qp(7) in CompleteDiscreteValuationRings() # optional - sage.rings.padics False sage: TestSuite(CompleteDiscreteValuationRings()).run() """ @@ -49,10 +49,10 @@ def valuation(self): EXAMPLES:: - sage: R = Zp(7) - sage: x = R(7); x + sage: R = Zp(7) # optional - sage.rings.padics + sage: x = R(7); x # optional - sage.rings.padics 7 + O(7^21) - sage: x.valuation() + sage: x.valuation() # optional - sage.rings.padics 1 """ @@ -63,32 +63,32 @@ def denominator(self): EXAMPLES:: - sage: K = Qp(7) - sage: x = K(1/21) - sage: x.denominator() + sage: K = Qp(7) # optional - sage.rings.padics + sage: x = K(1/21) # optional - sage.rings.padics + sage: x.denominator() # optional - sage.rings.padics 7 + O(7^21) - sage: x = K(7) - sage: x.denominator() + sage: x = K(7) # optional - sage.rings.padics + sage: x.denominator() # optional - sage.rings.padics 1 + O(7^20) Note that the denominator lives in the ring of integers:: - sage: x.denominator().parent() + sage: x.denominator().parent() # optional - sage.rings.padics 7-adic Ring with capped relative precision 20 When the denominator is indistinguishable from 0 and the precision on the input is `O(p^n)`, the return value is `1` if `n` is nonnegative and `p^(-n)` otherwise:: - sage: x = K(0,5); x + sage: x = K(0, 5); x # optional - sage.rings.padics O(7^5) - sage: x.denominator() + sage: x.denominator() # optional - sage.rings.padics 1 + O(7^20) - sage: x = K(0,-5); x + sage: x = K(0, -5); x # optional - sage.rings.padics O(7^-5) - sage: x.denominator() + sage: x.denominator() # optional - sage.rings.padics 7^5 + O(7^25) """ return self.parent()(1) @@ -101,26 +101,26 @@ def numerator(self): EXAMPLES:: - sage: K = Qp(7, 5) - sage: x = K(1/21) - sage: x.numerator() + sage: K = Qp(7, 5) # optional - sage.rings.padics + sage: x = K(1/21) # optional - sage.rings.padics + sage: x.numerator() # optional - sage.rings.padics 5 + 4*7 + 4*7^2 + 4*7^3 + 4*7^4 + O(7^5) - sage: x == x.numerator() / x.denominator() + sage: x == x.numerator() / x.denominator() # optional - sage.rings.padics True Note that the numerator lives in the ring of integers:: - sage: x.numerator().parent() + sage: x.numerator().parent() # optional - sage.rings.padics 7-adic Ring with capped relative precision 5 TESTS:: - sage: x = K(0,-5); x + sage: x = K(0, -5); x # optional - sage.rings.padics O(7^-5) - sage: x.numerator() + sage: x.numerator() # optional - sage.rings.padics O(7^0) - sage: x.denominator() + sage: x.denominator() # optional - sage.rings.padics 7^5 + O(7^10) """ return self @@ -146,21 +146,22 @@ def lift_to_precision(self, absprec=None): EXAMPLES:: - sage: R = ZpCA(17) - sage: R(-1,2).lift_to_precision(10) + sage: R = ZpCA(17) # optional - sage.rings.padics + sage: R(-1, 2).lift_to_precision(10) # optional - sage.rings.padics 16 + 16*17 + O(17^10) - sage: R(1,15).lift_to_precision(10) + sage: R(1, 15).lift_to_precision(10) # optional - sage.rings.padics 1 + O(17^15) - sage: R(1,15).lift_to_precision(30) + sage: R(1, 15).lift_to_precision(30) # optional - sage.rings.padics Traceback (most recent call last): ... PrecisionError: precision higher than allowed by the precision cap - sage: R(-1,2).lift_to_precision().precision_absolute() == R.precision_cap() + sage: (R(-1, 2).lift_to_precision().precision_absolute() # optional - sage.rings.padics + ....: == R.precision_cap()) True - sage: R = Zp(5); c = R(17,3); c.lift_to_precision(8) + sage: R = Zp(5); c = R(17, 3); c.lift_to_precision(8) # optional - sage.rings.padics 2 + 3*5 + O(5^8) - sage: c.lift_to_precision().precision_relative() == R.precision_cap() + sage: c.lift_to_precision().precision_relative() == R.precision_cap() # optional - sage.rings.padics True """ @@ -171,13 +172,13 @@ class CompleteDiscreteValuationFields(Category_singleton): EXAMPLES:: - sage: Zp(7) in CompleteDiscreteValuationFields() + sage: Zp(7) in CompleteDiscreteValuationFields() # optional - sage.rings.padics False sage: QQ in CompleteDiscreteValuationFields() False - sage: LaurentSeriesRing(QQ,'u') in CompleteDiscreteValuationFields() + sage: LaurentSeriesRing(QQ, 'u') in CompleteDiscreteValuationFields() True - sage: Qp(7) in CompleteDiscreteValuationFields() + sage: Qp(7) in CompleteDiscreteValuationFields() # optional - sage.rings.padics True sage: TestSuite(CompleteDiscreteValuationFields()).run() """ @@ -199,10 +200,10 @@ def valuation(self): EXAMPLES:: - sage: K = Qp(7) - sage: x = K(7); x + sage: K = Qp(7) # optional - sage.rings.padics + sage: x = K(7); x # optional - sage.rings.padics 7 + O(7^21) - sage: x.valuation() + sage: x.valuation() # optional - sage.rings.padics 1 """ @@ -213,32 +214,32 @@ def denominator(self): EXAMPLES:: - sage: K = Qp(7) - sage: x = K(1/21) - sage: x.denominator() + sage: K = Qp(7) # optional - sage.rings.padics + sage: x = K(1/21) # optional - sage.rings.padics + sage: x.denominator() # optional - sage.rings.padics 7 + O(7^21) - sage: x = K(7) - sage: x.denominator() + sage: x = K(7) # optional - sage.rings.padics + sage: x.denominator() # optional - sage.rings.padics 1 + O(7^20) Note that the denominator lives in the ring of integers:: - sage: x.denominator().parent() + sage: x.denominator().parent() # optional - sage.rings.padics 7-adic Ring with capped relative precision 20 When the denominator is indistinguishable from 0 and the precision on the input is `O(p^n)`, the return value is `1` if `n` is nonnegative and `p^(-n)` otherwise:: - sage: x = K(0,5); x + sage: x = K(0, 5); x # optional - sage.rings.padics O(7^5) - sage: x.denominator() + sage: x.denominator() # optional - sage.rings.padics 1 + O(7^20) - sage: x = K(0,-5); x + sage: x = K(0, -5); x # optional - sage.rings.padics O(7^-5) - sage: x.denominator() + sage: x.denominator() # optional - sage.rings.padics 7^5 + O(7^25) """ val = self.valuation() @@ -256,26 +257,26 @@ def numerator(self): EXAMPLES:: - sage: K = Qp(7, 5) - sage: x = K(1/21) - sage: x.numerator() + sage: K = Qp(7, 5) # optional - sage.rings.padics + sage: x = K(1/21) # optional - sage.rings.padics + sage: x.numerator() # optional - sage.rings.padics 5 + 4*7 + 4*7^2 + 4*7^3 + 4*7^4 + O(7^5) - sage: x == x.numerator() / x.denominator() + sage: x == x.numerator() / x.denominator() # optional - sage.rings.padics True Note that the numerator lives in the ring of integers:: - sage: x.numerator().parent() + sage: x.numerator().parent() # optional - sage.rings.padics 7-adic Ring with capped relative precision 5 TESTS:: - sage: x = K(0,-5); x + sage: x = K(0, -5); x # optional - sage.rings.padics O(7^-5) - sage: x.numerator() + sage: x.numerator() # optional - sage.rings.padics O(7^0) - sage: x.denominator() + sage: x.denominator() # optional - sage.rings.padics 7^5 + O(7^10) """ R = self.parent().integer_ring() diff --git a/src/sage/categories/complex_reflection_groups.py b/src/sage/categories/complex_reflection_groups.py index 5b23c448a96..e55b16eb6a0 100644 --- a/src/sage/categories/complex_reflection_groups.py +++ b/src/sage/categories/complex_reflection_groups.py @@ -64,18 +64,18 @@ class ComplexReflectionGroups(Category_singleton): An example of a reflection group:: - sage: W = ComplexReflectionGroups().example(); W + sage: W = ComplexReflectionGroups().example(); W # optional - sage.combinat sage.groups 5-colored permutations of size 3 ``W`` is in the category of complex reflection groups:: - sage: W in ComplexReflectionGroups() + sage: W in ComplexReflectionGroups() # optional - sage.combinat sage.groups True TESTS:: - sage: TestSuite(W).run() - sage: TestSuite(ComplexReflectionGroups()).run() + sage: TestSuite(W).run() # optional - sage.combinat sage.groups + sage: TestSuite(ComplexReflectionGroups()).run() # optional - sage.combinat sage.groups """ @cached_method @@ -115,7 +115,7 @@ def example(self): EXAMPLES:: sage: from sage.categories.complex_reflection_groups import ComplexReflectionGroups - sage: ComplexReflectionGroups().example() + sage: ComplexReflectionGroups().example() # optional - sage.combinat sage.groups 5-colored permutations of size 3 """ from sage.combinat.colored_permutations import ColoredPermutations @@ -133,9 +133,9 @@ def rank(self): EXAMPLES:: - sage: W = CoxeterGroups().example(); W + sage: W = CoxeterGroups().example(); W # optional - sage.groups The symmetric group on {0, ..., 3} - sage: W.rank() + sage: W.rank() # optional - sage.groups 3 """ diff --git a/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py b/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py index b75cbcb3e5d..3bbe54cefc0 100644 --- a/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py +++ b/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.groups r""" Common category for Generalized Coxeter Groups or Complex Reflection Groups """ diff --git a/src/sage/categories/covariant_functorial_construction.py b/src/sage/categories/covariant_functorial_construction.py index ad402bfe09d..90a1c42b1cc 100644 --- a/src/sage/categories/covariant_functorial_construction.py +++ b/src/sage/categories/covariant_functorial_construction.py @@ -134,9 +134,10 @@ def category_from_parents(self, parents): EXAMPLES:: - sage: E = CombinatorialFreeModule(QQ, ["a", "b", "c"]) - sage: tensor.category_from_parents((E, E, E)) - Category of tensor products of finite dimensional vector spaces with basis over Rational Field + sage: E = CombinatorialFreeModule(QQ, ["a", "b", "c"]) # optional - sage.modules + sage: tensor.category_from_parents((E, E, E)) # optional - sage.modules + Category of tensor products of + finite dimensional vector spaces with basis over Rational Field """ from sage.structure.parent import Parent assert all(isinstance(parent, Parent) for parent in parents) @@ -213,8 +214,8 @@ def __call__(self, args, **kwargs): EXAMPLES:: - sage: E = CombinatorialFreeModule(QQ, ["a", "b", "c"]); E.rename("E") - sage: tensor((E, E, E)) + sage: E = CombinatorialFreeModule(QQ, ["a", "b", "c"]); E.rename("E") # optional - sage.modules + sage: tensor((E, E, E)) # optional - sage.modules E # E # E """ args = tuple(args) # a bit brute force; let's see if this becomes a bottleneck later @@ -399,10 +400,12 @@ def category_of(cls, category, *args): EXAMPLES:: - sage: sage.categories.tensor.TensorProductsCategory.category_of(ModulesWithBasis(QQ)) + sage: C = sage.categories.tensor.TensorProductsCategory + sage: C.category_of(ModulesWithBasis(QQ)) Category of tensor products of vector spaces with basis over Rational Field - sage: sage.categories.algebra_functor.AlgebrasCategory.category_of(FiniteMonoids(), QQ) + sage: C = sage.categories.algebra_functor.AlgebrasCategory + sage: C.category_of(FiniteMonoids(), QQ) Join of Category of finite dimensional algebras with basis over Rational Field and Category of monoid algebras over Rational Field and Category of finite set algebras over Rational Field @@ -540,7 +543,8 @@ def default_super_categories(cls, category, *args): Bialgebras are both algebras and coalgebras:: sage: Bialgebras(QQ).super_categories() - [Category of algebras over Rational Field, Category of coalgebras over Rational Field] + [Category of algebras over Rational Field, + Category of coalgebras over Rational Field] Hence tensor products of bialgebras are tensor products of algebras and tensor products of coalgebras:: @@ -551,8 +555,10 @@ def default_super_categories(cls, category, *args): Here is how :meth:`default_super_categories` was called internally:: - sage: sage.categories.tensor.TensorProductsCategory.default_super_categories(Bialgebras(QQ)) - Join of Category of tensor products of algebras over Rational Field and Category of tensor products of coalgebras over Rational Field + sage: C = sage.categories.tensor.TensorProductsCategory + sage: C.default_super_categories(Bialgebras(QQ)) + Join of Category of tensor products of algebras over Rational Field + and Category of tensor products of coalgebras over Rational Field We now show a similar example, with the ``Algebra`` functor which takes a parameter `\QQ`:: @@ -570,7 +576,8 @@ def default_super_categories(cls, category, *args): Here is how :meth:`default_super_categories` was called internally:: - sage: sage.categories.algebra_functor.AlgebrasCategory.default_super_categories(FiniteMonoids(), QQ) + sage: C = sage.categories.algebra_functor.AlgebrasCategory + sage: C.default_super_categories(FiniteMonoids(), QQ) Join of Category of finite dimensional algebras with basis over Rational Field and Category of monoid algebras over Rational Field and Category of finite set algebras over Rational Field @@ -609,7 +616,8 @@ def is_construction_defined_by_base(self): sage: Bialgebras(QQ).Graded().is_construction_defined_by_base() Traceback (most recent call last): ... - AttributeError: 'JoinCategory_with_category' object has no attribute 'is_construction_defined_by_base' + AttributeError: 'JoinCategory_with_category' object has + no attribute 'is_construction_defined_by_base' """ base = self.base_category() f = self._functor_category diff --git a/src/sage/categories/coxeter_group_algebras.py b/src/sage/categories/coxeter_group_algebras.py index c8a3d935f05..623b1078e60 100644 --- a/src/sage/categories/coxeter_group_algebras.py +++ b/src/sage/categories/coxeter_group_algebras.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat, sage.groups r""" Coxeter Group Algebras """ diff --git a/src/sage/categories/coxeter_groups.py b/src/sage/categories/coxeter_groups.py index 98fe35a0ab3..95c31d20695 100644 --- a/src/sage/categories/coxeter_groups.py +++ b/src/sage/categories/coxeter_groups.py @@ -53,21 +53,21 @@ class CoxeterGroups(Category_singleton): Here are some further examples:: - sage: FiniteCoxeterGroups().example() + sage: FiniteCoxeterGroups().example() # optional - sage.combinat sage.groups The 5-th dihedral group of order 10 - sage: FiniteWeylGroups().example() + sage: FiniteWeylGroups().example() # optional - sage.combinat sage.groups The symmetric group on {0, ..., 3} - sage: WeylGroup(["B", 3]) + sage: WeylGroup(["B", 3]) # optional - sage.combinat sage.groups Weyl Group of type ['B', 3] (as a matrix group acting on the ambient space) - sage: S4 = SymmetricGroup(4); S4 + sage: S4 = SymmetricGroup(4); S4 # optional - sage.groups Symmetric group of order 4! as a permutation group - sage: S4 in CoxeterGroups().Finite() + sage: S4 in CoxeterGroups().Finite() # optional - sage.groups True Those will eventually be also in this category:: - sage: DihedralGroup(5) + sage: DihedralGroup(5) # optional - sage.groups Dihedral group of order 10 as a permutation group .. TODO:: add a demo of usual computations on Coxeter groups. @@ -97,7 +97,7 @@ class CoxeterGroups(Category_singleton): TESTS:: sage: W = CoxeterGroups().example() - sage: TestSuite(W).run() + sage: TestSuite(W).run() # optional - sage.combinat """ def super_categories(self): @@ -136,8 +136,8 @@ def coxeter_matrix(self): EXAMPLES:: - sage: G = WeylGroup(['A',3]) - sage: G.coxeter_matrix() + sage: G = WeylGroup(['A', 3]) # optional - sage.combinat sage.groups + sage: G.coxeter_matrix() # optional - sage.combinat sage.groups [1 3 2] [3 1 3] [2 3 1] @@ -150,14 +150,14 @@ def index_set(self): EXAMPLES:: - sage: W = CoxeterGroup([[1,3],[3,1]]) - sage: W.index_set() + sage: W = CoxeterGroup([[1,3],[3,1]]) # optional - sage.combinat sage.groups + sage: W.index_set() # optional - sage.combinat sage.groups (1, 2) - sage: W = CoxeterGroup([[1,3],[3,1]], index_set=['x', 'y']) - sage: W.index_set() + sage: W = CoxeterGroup([[1,3],[3,1]], index_set=['x', 'y']) # optional - sage.combinat sage.groups + sage: W.index_set() # optional - sage.combinat sage.groups ('x', 'y') - sage: W = CoxeterGroup(['H',3]) - sage: W.index_set() + sage: W = CoxeterGroup(['H', 3]) # optional - sage.combinat sage.groups + sage: W.index_set() # optional - sage.combinat sage.groups (1, 2, 3) """ return self.coxeter_matrix().index_set() @@ -168,18 +168,18 @@ def coxeter_diagram(self): EXAMPLES:: - sage: W = CoxeterGroup(['H',3], implementation="reflection") - sage: G = W.coxeter_diagram(); G + sage: W = CoxeterGroup(['H', 3], implementation="reflection") # optional - sage.combinat sage.groups + sage: G = W.coxeter_diagram(); G # optional - sage.combinat sage.groups sage.graphs Graph on 3 vertices - sage: G.edges(sort=True) + sage: G.edges(sort=True) # optional - sage.combinat sage.groups sage.graphs [(1, 2, 3), (2, 3, 5)] - sage: CoxeterGroup(G) is W + sage: CoxeterGroup(G) is W # optional - sage.combinat sage.groups sage.graphs True - sage: G = Graph([(0, 1, 3), (1, 2, oo)]) - sage: W = CoxeterGroup(G) - sage: W.coxeter_diagram() == G + sage: G = Graph([(0, 1, 3), (1, 2, oo)]) # optional - sage.combinat sage.groups sage.graphs + sage: W = CoxeterGroup(G) # optional - sage.combinat sage.groups sage.graphs + sage: W.coxeter_diagram() == G # optional - sage.combinat sage.groups sage.graphs True - sage: CoxeterGroup(W.coxeter_diagram()) is W + sage: CoxeterGroup(W.coxeter_diagram()) is W # optional - sage.combinat sage.groups sage.graphs True """ return self.coxeter_matrix().coxeter_graph() @@ -190,8 +190,8 @@ def coxeter_type(self): EXAMPLES:: - sage: W = CoxeterGroup(['H',3]) - sage: W.coxeter_type() + sage: W = CoxeterGroup(['H', 3]) # optional - sage.combinat sage.groups + sage: W.coxeter_type() # optional - sage.combinat sage.groups Coxeter type of ['H', 3] """ return self.coxeter_matrix().coxeter_type() @@ -203,12 +203,12 @@ def braid_relations(self): EXAMPLES:: - sage: W = WeylGroup(["A",2]) - sage: W.braid_relations() + sage: W = WeylGroup(["A", 2]) # optional - sage.combinat sage.groups + sage: W.braid_relations() # optional - sage.combinat sage.groups [[[1, 2, 1], [2, 1, 2]]] - sage: W = WeylGroup(["B",3]) - sage: W.braid_relations() + sage: W = WeylGroup(["B", 3]) # optional - sage.combinat sage.groups + sage: W.braid_relations() # optional - sage.combinat sage.groups [[[1, 2, 1], [2, 1, 2]], [[1, 3], [3, 1]], [[2, 3, 2, 3], [3, 2, 3, 2]]] """ rels = [] @@ -228,16 +228,16 @@ def braid_group_as_finitely_presented_group(self): EXAMPLES:: - sage: W = CoxeterGroup(['A',2]) - sage: W.braid_group_as_finitely_presented_group() + sage: W = CoxeterGroup(['A', 2]) # optional - sage.combinat sage.groups + sage: W.braid_group_as_finitely_presented_group() # optional - sage.combinat sage.groups Finitely presented group < S1, S2 | S1*S2*S1*S2^-1*S1^-1*S2^-1 > - sage: W = WeylGroup(['B',2]) - sage: W.braid_group_as_finitely_presented_group() + sage: W = WeylGroup(['B', 2]) # optional - sage.combinat sage.groups + sage: W.braid_group_as_finitely_presented_group() # optional - sage.combinat sage.groups Finitely presented group < S1, S2 | (S1*S2)^2*(S1^-1*S2^-1)^2 > sage: W = ReflectionGroup(['B',3], index_set=["AA","BB","5"]) # optional - gap3 - sage: W.braid_group_as_finitely_presented_group() # optional - gap3 + sage: W.braid_group_as_finitely_presented_group() # optional - gap3 Finitely presented group < SAA, SBB, S5 | (SAA*SBB)^2*(SAA^-1*SBB^-1)^2, SAA*S5*SAA^-1*S5^-1, SBB*S5*SBB*S5^-1*SBB^-1*S5^-1 > @@ -279,10 +279,10 @@ def braid_orbit(self, word): sage: word = w.reduced_word(); word [0, 1, 2, 1] - sage: sorted(W.braid_orbit(word)) + sage: sorted(W.braid_orbit(word)) # optional - sage.combinat sage.groups [[0, 1, 2, 1], [0, 2, 1, 2], [2, 0, 1, 2]] - sage: sorted(W.braid_orbit([2,1,1,2,1])) + sage: sorted(W.braid_orbit([2,1,1,2,1])) # optional - sage.combinat sage.groups [[1, 2, 1, 1, 2], [2, 1, 1, 2, 1], [2, 1, 2, 1, 2], [2, 2, 1, 2, 2]] sage: W = ReflectionGroup(['A',3], index_set=["AA","BB","5"]) # optional - gap3 @@ -354,17 +354,17 @@ def __iter__(self): (2, 1, 2), (2, 1, 2, 1)] - sage: W = WeylGroup(["A",2,1]) - sage: g = iter(W) - sage: next(g) + sage: W = WeylGroup(["A", 2, 1]) # optional - sage.combinat sage.groups + sage: g = iter(W) # optional - sage.combinat sage.groups + sage: next(g) # optional - sage.combinat sage.groups [1 0 0] [0 1 0] [0 0 1] - sage: next(g) + sage: next(g) # optional - sage.combinat sage.groups [-1 1 1] [ 0 1 0] [ 0 0 1] - sage: next(g) + sage: next(g) # optional - sage.combinat sage.groups [ 1 0 0] [ 1 -1 1] [ 0 0 1] @@ -377,19 +377,19 @@ def _element_constructor_(self, x, **args): EXAMPLES:: - sage: W1 = WeylGroup("G2",prefix="s") - sage: W2 = CoxeterGroup("G2") - sage: W3 = CoxeterGroup("G2", implementation="permutation") - sage: W1(W2.an_element()) + sage: W1 = WeylGroup("G2", prefix="s") # optional - sage.combinat sage.groups + sage: W2 = CoxeterGroup("G2") # optional - sage.combinat sage.groups + sage: W3 = CoxeterGroup("G2", implementation="permutation") # optional - sage.combinat sage.groups + sage: W1(W2.an_element()) # optional - sage.combinat sage.groups s1*s2 - sage: W2(W1.an_element()) + sage: W2(W1.an_element()) # optional - sage.combinat sage.groups [ 2 -a] [ a -1] - sage: W1(W3.an_element()) + sage: W1(W3.an_element()) # optional - sage.combinat sage.groups s1*s2 - sage: s1,s2 = W1.simple_reflections() - sage: W = CoxeterGroup("A1") - sage: W(s1*s2) + sage: s1, s2 = W1.simple_reflections() # optional - sage.combinat sage.groups + sage: W = CoxeterGroup("A1") # optional - sage.combinat sage.groups + sage: W(s1 * s2) # optional - sage.combinat sage.groups Traceback (most recent call last): ... ValueError: inconsistent number of rows: should be 1 but got 3 @@ -419,7 +419,7 @@ def weak_order_ideal(self, predicate, side="right", category=None): EXAMPLES:: sage: D6 = FiniteCoxeterGroups().example(5) - sage: I = D6.weak_order_ideal(predicate = lambda w: w.length() <= 3) + sage: I = D6.weak_order_ideal(predicate=lambda w: w.length() <= 3) sage: I.cardinality() 7 sage: list(I) @@ -511,17 +511,17 @@ def coxeter_element(self): EXAMPLES:: - sage: CoxeterGroup(['A', 4]).coxeter_element().reduced_word() + sage: CoxeterGroup(['A', 4]).coxeter_element().reduced_word() # optional - sage.combinat sage.groups [1, 2, 3, 4] - sage: CoxeterGroup(['B', 4]).coxeter_element().reduced_word() + sage: CoxeterGroup(['B', 4]).coxeter_element().reduced_word() # optional - sage.combinat sage.groups [1, 2, 3, 4] - sage: CoxeterGroup(['D', 4]).coxeter_element().reduced_word() + sage: CoxeterGroup(['D', 4]).coxeter_element().reduced_word() # optional - sage.combinat sage.groups [1, 2, 4, 3] - sage: CoxeterGroup(['F', 4]).coxeter_element().reduced_word() + sage: CoxeterGroup(['F', 4]).coxeter_element().reduced_word() # optional - sage.combinat sage.groups [1, 2, 3, 4] - sage: CoxeterGroup(['E', 8]).coxeter_element().reduced_word() + sage: CoxeterGroup(['E', 8]).coxeter_element().reduced_word() # optional - sage.combinat sage.groups [1, 3, 2, 4, 5, 6, 7, 8] - sage: CoxeterGroup(['H', 3]).coxeter_element().reduced_word() + sage: CoxeterGroup(['H', 3]).coxeter_element().reduced_word() # optional - sage.combinat sage.groups [1, 2, 3] This method is also used for well generated finite complex @@ -545,9 +545,9 @@ def coxeter_element(self): TESTS:: - sage: WeylGroup(['A', 4]).coxeter_element().reduced_word() + sage: WeylGroup(['A', 4]).coxeter_element().reduced_word() # optional - sage.combinat sage.groups [1, 2, 3, 4] - sage: SymmetricGroup(3).coxeter_element() + sage: SymmetricGroup(3).coxeter_element() # optional - sage.combinat sage.groups (1,3,2) """ return self.prod(self.simple_reflections()) @@ -575,24 +575,24 @@ class is not unique and we only obtain one such class. TESTS:: - sage: W = SymmetricGroup(3) - sage: sorted(W.standard_coxeter_elements()) + sage: W = SymmetricGroup(3) # optional - sage.combinat sage.groups + sage: sorted(W.standard_coxeter_elements()) # optional - sage.combinat sage.groups [(1,2,3), (1,3,2)] - sage: W = Permutations(3) - sage: sorted(W.standard_coxeter_elements()) + sage: W = Permutations(3) # optional - sage.combinat sage.groups + sage: sorted(W.standard_coxeter_elements()) # optional - sage.combinat sage.groups [[2, 3, 1], [3, 1, 2]] - sage: W = CoxeterGroup(['D',3]) - sage: sorted(W.standard_coxeter_elements()) + sage: W = CoxeterGroup(['D', 3]) # optional - sage.combinat sage.groups + sage: sorted(W.standard_coxeter_elements()) # optional - sage.combinat sage.groups [ [-1 1 1] [ 0 -1 1] [ 0 1 -1] [ 1 -1 -1] [-1 0 1] [ 1 -1 0] [ 0 0 -1] [ 1 -1 0] [-1 1 0], [ 0 -1 0], [ 1 0 -1], [ 1 0 -1] ] - sage: W = ColoredPermutations(3,2) - sage: len(W.standard_coxeter_elements()) + sage: W = ColoredPermutations(3,2) # optional - sage.combinat sage.groups + sage: len(W.standard_coxeter_elements()) # optional - sage.combinat sage.groups 2 """ if not self.is_irreducible() or not self.is_well_generated(): @@ -642,8 +642,9 @@ def fully_commutative_elements(self): EXAMPLES:: - sage: CoxeterGroup(['A', 3]).fully_commutative_elements() - Fully commutative elements of Finite Coxeter group over Integer Ring with Coxeter matrix: + sage: CoxeterGroup(['A', 3]).fully_commutative_elements() # optional - sage.combinat sage.groups + Fully commutative elements of + Finite Coxeter group over Integer Ring with Coxeter matrix: [1 3 2] [3 1 3] [2 3 1] @@ -689,7 +690,7 @@ def simple_projection(self, i, side='right', length_increasing=True): sage: sigma (1, 2, 3, 0) sage: u0 = W.simple_projection(0) - sage: d0 = W.simple_projection(0,length_increasing=False) + sage: d0 = W.simple_projection(0, length_increasing=False) sage: sigma.length() 3 sage: pi=sigma*s[0] @@ -738,9 +739,9 @@ def kazhdan_lusztig_cells(self, side='left'): representation of elements in the output cells but not the method used for the cell computation:: - sage: W = CoxeterGroup('A2') - sage: KL_cells = W.kazhdan_lusztig_cells(side='right') - sage: set([tuple(sorted(C, key=lambda w: w.reduced_word())) + sage: W = CoxeterGroup('A2') # optional - sage.combinat sage.groups + sage: KL_cells = W.kazhdan_lusztig_cells(side='right') # optional - sage.combinat sage.groups + sage: set([tuple(sorted(C, key=lambda w: w.reduced_word())) # optional - sage.combinat sage.groups ....: for C in KL_cells]) {( [-1 1] [ 0 -1] @@ -758,11 +759,11 @@ def kazhdan_lusztig_cells(self, side='left'): [ 1 0] [-1 1] [ 1 -1], [-1 0] )} - sage: len(KL_cells) + sage: len(KL_cells) # optional - sage.combinat sage.groups 4 - sage: W = CoxeterGroup('A2', implementation='permutation') - sage: len(W.kazhdan_lusztig_cells(side='right')) + sage: W = CoxeterGroup('A2', implementation='permutation') # optional - sage.combinat sage.groups + sage: len(W.kazhdan_lusztig_cells(side='right')) # optional - sage.combinat sage.groups 4 We compute the left cells in the Coxeter group of type `A_3` @@ -792,11 +793,12 @@ def kazhdan_lusztig_cells(self, side='left'): Computing the two sided cells in `B_3`:: - sage: W = CoxeterGroup('B3', implementation='coxeter3') # optional - coxeter3 - sage: b3_cells = W.kazhdan_lusztig_cells('two-sided') # optional - coxeter3 - sage: len(b3_cells) # optional - coxeter3 + sage: W = CoxeterGroup('B3', implementation='coxeter3') # optional - coxeter3 + sage: b3_cells = W.kazhdan_lusztig_cells('two-sided') # optional - coxeter3 + sage: len(b3_cells) # optional - coxeter3 6 - sage: set([tuple(sorted(C)) for C in W.kazhdan_lusztig_cells()]) # optional - coxeter3 + sage: set([tuple(sorted(C)) # optional - coxeter3 + ....: for C in W.kazhdan_lusztig_cells()]) {([],), ([1], [1, 2, 3, 2, 1], [2, 1], [2, 3, 2, 1], [3, 2, 1]), ([1, 2], [1, 2, 3, 2], [2], [2, 3, 2], [3, 2]), @@ -825,8 +827,8 @@ def kazhdan_lusztig_cells(self, side='left'): TESTS:: - sage: W = CoxeterGroup(['A', 2, 1]) - sage: W.kazhdan_lusztig_cells() + sage: W = CoxeterGroup(['A', 2, 1]) # optional - sage.combinat sage.groups + sage: W.kazhdan_lusztig_cells() # optional - sage.combinat sage.groups Traceback (most recent call last): ... ValueError: the Coxeter group must be finite to compute Kazhdan--Lusztig cells @@ -887,7 +889,9 @@ def simple_projections(self, side='right', length_increasing=True): sage: sigma = W.an_element(); sigma (1, 2, 3, 0) sage: pi = W.simple_projections(); pi - Finite family {0: at ...>, 1: at ...>, 2: ...>} + Finite family {0: at ...>, + 1: at ...>, + 2: ...>} sage: pi[1](sigma) (1, 3, 2, 0) sage: W.simple_projection(1)(sigma) @@ -907,9 +911,11 @@ def sign_representation(self, base_ring=None, side="twosided"): EXAMPLES:: - sage: W = WeylGroup(["A", 1, 1]) - sage: W.sign_representation() - Sign representation of Weyl Group of type ['A', 1, 1] (as a matrix group acting on the root space) over Integer Ring + sage: W = WeylGroup(["A", 1, 1]) # optional - sage.combinat sage.groups + sage: W.sign_representation() # optional - sage.combinat sage.groups + Sign representation of + Weyl Group of type ['A', 1, 1] (as a matrix group acting on the root space) + over Integer Ring """ if base_ring is None: @@ -933,18 +939,18 @@ def demazure_product(self, Q): EXAMPLES:: - sage: W = WeylGroup(['A',2]) - sage: w = W.demazure_product([2,2,1]) - sage: w.reduced_word() + sage: W = WeylGroup(['A', 2]) # optional - sage.combinat sage.groups + sage: w = W.demazure_product([2,2,1]) # optional - sage.combinat sage.groups + sage: w.reduced_word() # optional - sage.combinat sage.groups [2, 1] - sage: w = W.demazure_product([2,1,2,1,2]) - sage: w.reduced_word() + sage: w = W.demazure_product([2,1,2,1,2]) # optional - sage.combinat sage.groups + sage: w.reduced_word() # optional - sage.combinat sage.groups [1, 2, 1] - sage: W = WeylGroup(['B',2]) - sage: w = W.demazure_product([2,1,2,1,2]) - sage: w.reduced_word() + sage: W = WeylGroup(['B', 2]) # optional - sage.combinat sage.groups + sage: w = W.demazure_product([2,1,2,1,2]) # optional - sage.combinat sage.groups + sage: w.reduced_word() # optional - sage.combinat sage.groups [2, 1, 2, 1] """ return self.one().apply_demazure_product(Q) @@ -955,16 +961,16 @@ def bruhat_interval(self, x, y): EXAMPLES:: - sage: W = WeylGroup("A3", prefix="s") - sage: [s1,s2,s3] = W.simple_reflections() - sage: W.bruhat_interval(s2,s1*s3*s2*s1*s3) + sage: W = WeylGroup("A3", prefix="s") # optional - sage.combinat sage.groups + sage: s1, s2, s3 = W.simple_reflections() # optional - sage.combinat sage.groups + sage: W.bruhat_interval(s2, s1*s3*s2*s1*s3) # optional - sage.combinat sage.groups [s1*s2*s3*s2*s1, s2*s3*s2*s1, s3*s1*s2*s1, s1*s2*s3*s1, s1*s2*s3*s2, s3*s2*s1, s2*s3*s1, s2*s3*s2, s1*s2*s1, s3*s1*s2, s1*s2*s3, s2*s1, s3*s2, s2*s3, s1*s2, s2] - sage: W = WeylGroup(['A',2,1], prefix="s") - sage: [s0,s1,s2] = W.simple_reflections() - sage: W.bruhat_interval(1,s0*s1*s2) + sage: W = WeylGroup(['A', 2, 1], prefix="s") # optional - sage.combinat sage.groups + sage: s0, s1, s2 = W.simple_reflections() # optional - sage.combinat sage.groups + sage: W.bruhat_interval(1, s0*s1*s2) # optional - sage.combinat sage.groups [s0*s1*s2, s1*s2, s0*s2, s0*s1, s2, s1, s0, 1] """ if x == 1: @@ -994,19 +1000,19 @@ def bruhat_interval_poset(self, x, y, facade=False): EXAMPLES:: - sage: W = WeylGroup("A3", prefix="s") - sage: s1,s2,s3 = W.simple_reflections() - sage: W.bruhat_interval_poset(s2, s1*s3*s2*s1*s3) + sage: W = WeylGroup("A3", prefix="s") # optional - sage.combinat sage.groups + sage: s1, s2, s3 = W.simple_reflections() # optional - sage.combinat sage.groups + sage: W.bruhat_interval_poset(s2, s1*s3*s2*s1*s3) # optional - sage.combinat sage.groups Finite poset containing 16 elements - sage: W = WeylGroup(['A',2,1], prefix="s") - sage: s0,s1,s2 = W.simple_reflections() - sage: W.bruhat_interval_poset(1, s0*s1*s2) + sage: W = WeylGroup(['A', 2, 1], prefix="s") # optional - sage.combinat sage.groups + sage: s0, s1, s2 = W.simple_reflections() # optional - sage.combinat sage.groups + sage: W.bruhat_interval_poset(1, s0*s1*s2) # optional - sage.combinat sage.groups Finite poset containing 8 elements TESTS:: - sage: W.bruhat_interval_poset(s0*s1*s2, s0*s1*s2) + sage: W.bruhat_interval_poset(s0*s1*s2, s0*s1*s2) # optional - sage.combinat sage.groups Finite poset containing 1 elements """ if x == 1: @@ -1061,27 +1067,27 @@ def bruhat_graph(self, x=None, y=None, edge_labels=False): EXAMPLES:: - sage: W = CoxeterGroup(['H',3]) - sage: G = W.bruhat_graph(); G + sage: W = CoxeterGroup(['H', 3]) # optional - sage.combinat sage.groups sage.graphs + sage: G = W.bruhat_graph(); G # optional - sage.combinat sage.groups sage.graphs Digraph on 120 vertices - sage: W = CoxeterGroup(['A',2,1]) - sage: s1, s2, s3 = W.simple_reflections() - sage: W.bruhat_graph(s1, s1*s3*s2*s3) + sage: W = CoxeterGroup(['A', 2, 1]) # optional - sage.combinat sage.groups sage.graphs + sage: s1, s2, s3 = W.simple_reflections() # optional - sage.combinat sage.groups sage.graphs + sage: W.bruhat_graph(s1, s1*s3*s2*s3) # optional - sage.combinat sage.groups sage.graphs Digraph on 6 vertices - sage: W.bruhat_graph(s1, s3*s2*s3) + sage: W.bruhat_graph(s1, s3*s2*s3) # optional - sage.combinat sage.groups sage.graphs Digraph on 0 vertices - sage: W = WeylGroup("A3", prefix="s") - sage: s1, s2, s3 = W.simple_reflections() - sage: G = W.bruhat_graph(s1*s3, s1*s2*s3*s2*s1); G + sage: W = WeylGroup("A3", prefix="s") # optional - sage.combinat sage.groups sage.graphs + sage: s1, s2, s3 = W.simple_reflections() # optional - sage.combinat sage.groups sage.graphs + sage: G = W.bruhat_graph(s1*s3, s1*s2*s3*s2*s1); G # optional - sage.combinat sage.groups sage.graphs Digraph on 10 vertices Check that the graph has the correct number of edges (see :trac:`17744`):: - sage: len(G.edges(sort=False)) + sage: len(G.edges(sort=False)) # optional - sage.combinat sage.groups sage.graphs 16 """ if x is None or x == 1: @@ -1129,8 +1135,8 @@ def canonical_representation(self): EXAMPLES:: - sage: W = WeylGroup("A3") - sage: W.canonical_representation() + sage: W = WeylGroup("A3") # optional - sage.combinat sage.groups + sage: W.canonical_representation() # optional - sage.combinat sage.groups Finite Coxeter group over Integer Ring with Coxeter matrix: [1 3 2] [3 1 3] @@ -1146,16 +1152,16 @@ def elements_of_length(self, n): EXAMPLES:: - sage: A = AffinePermutationGroup(['A',2,1]) - sage: [len(list(A.elements_of_length(i))) for i in [0..5]] + sage: A = AffinePermutationGroup(['A', 2, 1]) # optional - sage.combinat sage.groups + sage: [len(list(A.elements_of_length(i))) for i in [0..5]] # optional - sage.combinat sage.groups [1, 3, 6, 9, 12, 15] - sage: W = CoxeterGroup(['H',3]) - sage: [len(list(W.elements_of_length(i))) for i in range(4)] + sage: W = CoxeterGroup(['H', 3]) # optional - sage.combinat sage.groups + sage: [len(list(W.elements_of_length(i))) for i in range(4)] # optional - sage.combinat sage.groups [1, 3, 5, 7] - sage: W = CoxeterGroup(['A',2]) - sage: [len(list(W.elements_of_length(i))) for i in range(6)] + sage: W = CoxeterGroup(['A', 2]) # optional - sage.combinat sage.groups + sage: [len(list(W.elements_of_length(i))) for i in range(6)] # optional - sage.combinat sage.groups [1, 2, 2, 1, 0, 0] """ I = self.weak_order_ideal(ConstantFunction(True), side='right') @@ -1173,18 +1179,18 @@ def random_element_of_length(self, n): EXAMPLES:: - sage: A = AffinePermutationGroup(['A', 7, 1]) - sage: p = A.random_element_of_length(10) - sage: p in A + sage: A = AffinePermutationGroup(['A', 7, 1]) # optional - sage.combinat sage.groups + sage: p = A.random_element_of_length(10) # optional - sage.combinat sage.groups + sage: p in A # optional - sage.combinat sage.groups True - sage: p.length() == 10 + sage: p.length() == 10 # optional - sage.combinat sage.groups True - sage: W = CoxeterGroup(['A', 4]) - sage: p = W.random_element_of_length(5) - sage: p in W + sage: W = CoxeterGroup(['A', 4]) # optional - sage.combinat sage.groups + sage: p = W.random_element_of_length(5) # optional - sage.combinat sage.groups + sage: p in W # optional - sage.combinat sage.groups True - sage: p.length() == 5 + sage: p.length() == 5 # optional - sage.combinat sage.groups True """ from sage.misc.prandom import randint @@ -1236,14 +1242,14 @@ def _test_has_descent(self, **options): sage: W = CoxeterGroups().example() sage: W._test_has_descent() - sage: W = Permutations(4) - sage: W._test_has_descent() - sage: sage.combinat.permutation.Permutations.options.mult = "r2l" - sage: W._test_has_descent() - sage: sage.combinat.permutation.Permutations.options._reset() + sage: W = Permutations(4) # optional - sage.combinat sage.groups + sage: W._test_has_descent() # optional - sage.combinat sage.groups + sage: sage.combinat.permutation.Permutations.options.mult = "r2l" # optional - sage.combinat sage.groups + sage: W._test_has_descent() # optional - sage.combinat sage.groups + sage: sage.combinat.permutation.Permutations.options._reset() # optional - sage.combinat sage.groups - sage: W = SignedPermutations(3) - sage: W._test_has_descent() + sage: W = SignedPermutations(3) # optional - sage.combinat sage.groups + sage: W._test_has_descent() # optional - sage.combinat sage.groups """ tester = self._tester(**options) s = self.simple_reflections() @@ -1300,21 +1306,21 @@ def _test_coxeter_relations(self, **options): TESTS:: - sage: A = AffinePermutationGroup(['A',7,1]) - sage: A._test_coxeter_relations() + sage: A = AffinePermutationGroup(['A', 7, 1]) # optional - sage.combinat sage.groups + sage: A._test_coxeter_relations() # optional - sage.combinat sage.groups - sage: cm = CartanMatrix([[2,-5,0],[-2,2,-1],[0,-1,2]]) - sage: W = WeylGroup(cm) - sage: W._test_coxeter_relations() + sage: cm = CartanMatrix([[2,-5,0], [-2,2,-1], [0,-1,2]]) # optional - sage.combinat sage.groups + sage: W = WeylGroup(cm) # optional - sage.combinat sage.groups + sage: W._test_coxeter_relations() # optional - sage.combinat sage.groups - sage: W = Permutations(4) - sage: W._test_coxeter_relations() - sage: sage.combinat.permutation.Permutations.options.mult = "r2l" - sage: W._test_coxeter_relations() - sage: sage.combinat.permutation.Permutations.options._reset() + sage: W = Permutations(4) # optional - sage.combinat sage.groups + sage: W._test_coxeter_relations() # optional - sage.combinat sage.groups + sage: sage.combinat.permutation.Permutations.options.mult = "r2l" # optional - sage.combinat sage.groups + sage: W._test_coxeter_relations() # optional - sage.combinat sage.groups + sage: sage.combinat.permutation.Permutations.options._reset() # optional - sage.combinat sage.groups - sage: W = SignedPermutations(3) - sage: W._test_coxeter_relations() + sage: W = SignedPermutations(3) # optional - sage.combinat sage.groups + sage: W._test_coxeter_relations() # optional - sage.combinat sage.groups """ tester = self._tester(**options) s = self.simple_reflections() @@ -1347,7 +1353,7 @@ def has_descent(self, i, side='right', positive=False): sage: w = s[0] * s[1] * s[2] sage: w.has_descent(2) True - sage: [ w.has_descent(i) for i in [0,1,2] ] + sage: [ w.has_descent(i) for i in [0,1,2] ] [False, False, True] sage: [ w.has_descent(i, side='left') for i in [0,1,2] ] [True, False, False] @@ -1600,17 +1606,18 @@ def reduced_words(self): sage: W = CoxeterGroups().example() sage: s = W.simple_reflections() sage: w = s[0] * s[2] - sage: sorted(w.reduced_words()) + sage: sorted(w.reduced_words()) # optional - sage.combinat [[0, 2], [2, 0]] - sage: W = WeylGroup(['E',6]) - sage: w = W.from_reduced_word([2,3,4,2]) - sage: sorted(w.reduced_words()) + sage: W = WeylGroup(['E', 6]) # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([2,3,4,2]) # optional - sage.combinat sage.groups + sage: sorted(w.reduced_words()) # optional - sage.combinat sage.groups [[2, 3, 4, 2], [3, 2, 4, 2], [3, 4, 2, 4]] - sage: W = ReflectionGroup(['A',3], index_set=["AA","BB","5"]) # optional - gap3 - sage: w = W.long_element() # optional - gap3 - sage: w.reduced_words() # optional - gap3 + sage: W = ReflectionGroup(['A',3], # optional - gap3 + ....: index_set=["AA","BB","5"]) + sage: w = W.long_element() # optional - gap3 + sage: w.reduced_words() # optional - gap3 [['BB', '5', 'AA', 'BB', '5', 'AA'], ['5', 'BB', '5', 'AA', 'BB', '5'], ['BB', 'AA', 'BB', '5', 'BB', 'AA'], @@ -1693,32 +1700,32 @@ def reduced_word_graph(self): EXAMPLES:: - sage: W = WeylGroup(['A',3], prefix='s') - sage: w0 = W.long_element() - sage: G = w0.reduced_word_graph() - sage: G.num_verts() + sage: W = WeylGroup(['A', 3], prefix='s') # optional - sage.combinat sage.groups + sage: w0 = W.long_element() # optional - sage.combinat sage.groups + sage: G = w0.reduced_word_graph() # optional - sage.combinat sage.groups sage.graphs + sage: G.num_verts() # optional - sage.combinat sage.groups sage.graphs 16 - sage: len(w0.reduced_words()) + sage: len(w0.reduced_words()) # optional - sage.combinat sage.groups sage.graphs 16 - sage: G.num_edges() + sage: G.num_edges() # optional - sage.combinat sage.groups sage.graphs 18 - sage: len([e for e in G.edges(sort=False) if e[2] == 2]) + sage: len([e for e in G.edges(sort=False) if e[2] == 2]) # optional - sage.combinat sage.groups sage.graphs 10 - sage: len([e for e in G.edges(sort=False) if e[2] == 3]) + sage: len([e for e in G.edges(sort=False) if e[2] == 3]) # optional - sage.combinat sage.groups sage.graphs 8 TESTS:: - sage: p = Permutation([3,2,4,1]) - sage: pp = WeylGroup(['A',3]).from_reduced_word(p.reduced_word()) - sage: pp.reduced_word_graph() + sage: p = Permutation([3,2,4,1]) # optional - sage.combinat + sage: pp = WeylGroup(['A',3]).from_reduced_word(p.reduced_word()) # optional - sage.combinat sage.groups + sage: pp.reduced_word_graph() # optional - sage.combinat sage.groups sage.graphs Graph on 3 vertices - sage: w1 = W.one() - sage: G = w1.reduced_word_graph() - sage: G.num_verts() + sage: w1 = W.one() # optional - sage.combinat sage.groups + sage: G = w1.reduced_word_graph() # optional - sage.combinat sage.groups sage.graphs + sage: G.num_verts() # optional - sage.combinat sage.groups sage.graphs 1 - sage: G.num_edges() + sage: G.num_edges() # optional - sage.combinat sage.groups sage.graphs 0 .. SEEALSO:: @@ -1814,14 +1821,14 @@ def reflection_length(self): EXAMPLES:: - sage: W = WeylGroup(['A',3]) - sage: s = W.simple_reflections() - sage: (s[1]*s[2]*s[3]).reflection_length() + sage: W = WeylGroup(['A', 3]) # optional - sage.combinat sage.groups + sage: s = W.simple_reflections() # optional - sage.combinat sage.groups + sage: (s[1]*s[2]*s[3]).reflection_length() # optional - sage.combinat sage.groups 3 - sage: W = SymmetricGroup(4) - sage: s = W.simple_reflections() - sage: (s[3]*s[2]*s[3]).reflection_length() + sage: W = SymmetricGroup(4) # optional - sage.combinat sage.groups + sage: s = W.simple_reflections() # optional - sage.combinat sage.groups + sage: (s[3]*s[2]*s[3]).reflection_length() # optional - sage.combinat sage.groups 1 """ @@ -1844,14 +1851,14 @@ def absolute_length(self): EXAMPLES:: - sage: W = WeylGroup(["A", 3]) - sage: s = W.simple_reflections() - sage: (s[1]*s[2]*s[3]).absolute_length() + sage: W = WeylGroup(["A", 3]) # optional - sage.combinat sage.groups + sage: s = W.simple_reflections() # optional - sage.combinat sage.groups + sage: (s[1]*s[2]*s[3]).absolute_length() # optional - sage.combinat sage.groups 3 - sage: W = SymmetricGroup(4) - sage: s = W.simple_reflections() - sage: (s[3]*s[2]*s[1]).absolute_length() + sage: W = SymmetricGroup(4) # optional - sage.combinat sage.groups + sage: s = W.simple_reflections() # optional - sage.combinat sage.groups + sage: (s[3]*s[2]*s[1]).absolute_length() # optional - sage.combinat sage.groups 3 """ M = self.canonical_matrix() @@ -1876,40 +1883,45 @@ def absolute_le(self, other): EXAMPLES:: - sage: W = WeylGroup(["A", 3]) - sage: s = W.simple_reflections() - sage: w0 = s[1] - sage: w1 = s[1]*s[2]*s[3] - sage: w0.absolute_le(w1) + sage: W = WeylGroup(["A", 3]) # optional - sage.combinat sage.groups + sage: s = W.simple_reflections() # optional - sage.combinat sage.groups + sage: w0 = s[1] # optional - sage.combinat sage.groups + sage: w1 = s[1]*s[2]*s[3] # optional - sage.combinat sage.groups + sage: w0.absolute_le(w1) # optional - sage.combinat sage.groups True - sage: w1.absolute_le(w0) + sage: w1.absolute_le(w0) # optional - sage.combinat sage.groups False - sage: w1.absolute_le(w1) + sage: w1.absolute_le(w1) # optional - sage.combinat sage.groups True TESTS: Check that this is independent of the implementation of the group, see :trac:`34799`:: - sage: W1 = WeylGroup(['A',2]) - sage: W2 = Permutations(3) + sage: W1 = WeylGroup(['A', 2]) # optional - sage.combinat sage.groups + sage: W2 = Permutations(3) # optional - sage.combinat sage.groups sage: P = lambda pi: W2(list(pi.to_permutation())) - sage: d1 = set((P(w1), P(w2)) for w1 in W1 for w2 in W1 if w1.absolute_le(w2)) - sage: d2 = set((w1, w2) for w1 in W2 for w2 in W2 if w1.absolute_le(w2)) - sage: d1 == d2 + sage: d1 = set((P(w1), P(w2)) for w1 in W1 for w2 in W1 # optional - sage.combinat sage.groups + ....: if w1.absolute_le(w2)) + sage: d2 = set((w1, w2) for w1 in W2 for w2 in W2 # optional - sage.combinat sage.groups + ....: if w1.absolute_le(w2)) + sage: d1 == d2 # optional - sage.combinat sage.groups True - sage: sage.combinat.permutation.Permutations.options.mult = "r2l" - sage: d3 = set((w1, w2) for w1 in W2 for w2 in W2 if w1.absolute_le(w2)) - sage: d1 == d3 + sage: sage.combinat.permutation.Permutations.options.mult = "r2l" # optional - sage.combinat sage.groups + sage: d3 = set((w1, w2) # optional - sage.combinat sage.groups + ....: for w1 in W2 for w2 in W2 if w1.absolute_le(w2)) + sage: d1 == d3 # optional - sage.combinat sage.groups True - sage: sage.combinat.permutation.Permutations.options._reset() - - sage: W1 = WeylGroup(['B',2]) - sage: W2 = SignedPermutations(2) - sage: P = lambda pi: W2(list(pi.to_permutation())) - sage: d1 = set((P(w1), P(w2)) for w1 in W1 for w2 in W1 if w1.absolute_le(w2)) - sage: d2 = set((w1, w2) for w1 in W2 for w2 in W2 if w1.absolute_le(w2)) - sage: d1 == d2 + sage: sage.combinat.permutation.Permutations.options._reset() # optional - sage.combinat sage.groups + + sage: W1 = WeylGroup(['B', 2]) # optional - sage.combinat sage.groups + sage: W2 = SignedPermutations(2) # optional - sage.combinat sage.groups + sage: P = lambda pi: W2(list(pi.to_permutation())) # optional - sage.combinat sage.groups + sage: d1 = set((P(w1), P(w2)) # optional - sage.combinat sage.groups + ....: for w1 in W1 for w2 in W1 if w1.absolute_le(w2)) + sage: d2 = set((w1, w2) # optional - sage.combinat sage.groups + ....: for w1 in W2 for w2 in W2 if w1.absolute_le(w2)) + sage: d1 == d2 # optional - sage.combinat sage.groups True """ if self == other: @@ -1928,11 +1940,11 @@ def absolute_covers(self): EXAMPLES:: - sage: W = WeylGroup(["A", 3]) - sage: s = W.simple_reflections() - sage: w0 = s[1] - sage: w1 = s[1]*s[2]*s[3] - sage: w0.absolute_covers() + sage: W = WeylGroup(["A", 3]) # optional - sage.combinat sage.groups + sage: s = W.simple_reflections() # optional - sage.combinat sage.groups + sage: w0 = s[1] # optional - sage.combinat sage.groups + sage: w1 = s[1]*s[2]*s[3] # optional - sage.combinat sage.groups + sage: w0.absolute_covers() # optional - sage.combinat sage.groups [ [0 0 1 0] [0 1 0 0] [0 1 0 0] [0 0 0 1] [0 1 0 0] [1 0 0 0] [1 0 0 0] [0 0 1 0] [1 0 0 0] [0 0 0 1] @@ -1956,9 +1968,9 @@ def canonical_matrix(self): EXAMPLES:: - sage: W = WeylGroup(["A", 3]) - sage: s = W.simple_reflections() - sage: (s[1]*s[2]*s[3]).canonical_matrix() + sage: W = WeylGroup(["A", 3]) # optional - sage.combinat sage.groups + sage: s = W.simple_reflections() # optional - sage.combinat sage.groups + sage: (s[1]*s[2]*s[3]).canonical_matrix() # optional - sage.combinat sage.groups [ 0 0 -1] [ 1 0 -1] [ 0 1 -1] @@ -1988,11 +2000,11 @@ def coset_representative(self, index_set, side='right'): [2, 3] sage: w.coset_representative([1,2]).reduced_word() [2, 3] - sage: w.coset_representative([1,3] ).reduced_word() + sage: w.coset_representative([1,3] ).reduced_word() [2] - sage: w.coset_representative([2,3] ).reduced_word() + sage: w.coset_representative([2,3] ).reduced_word() [2, 1] - sage: w.coset_representative([1,2,3] ).reduced_word() + sage: w.coset_representative([1,2,3] ).reduced_word() [] sage: w.coset_representative([], side='left').reduced_word() [2, 3, 1] @@ -2039,15 +2051,15 @@ def apply_simple_projection(self, i, side='right', length_increasing=True): (1, 2, 3, 0) sage: w.apply_simple_projection(2, length_increasing=False) (1, 2, 0, 3) - sage: W = WeylGroup(['C',4],prefix="s") - sage: v = W.from_reduced_word([1,2,3,4,3,1]) - sage: v + sage: W = WeylGroup(['C', 4], prefix="s") # optional - sage.combinat sage.groups + sage: v = W.from_reduced_word([1,2,3,4,3,1]) # optional - sage.combinat sage.groups + sage: v # optional - sage.combinat sage.groups s1*s2*s3*s4*s3*s1 - sage: v.apply_simple_projection(2) + sage: v.apply_simple_projection(2) # optional - sage.combinat sage.groups s1*s2*s3*s4*s3*s1*s2 - sage: v.apply_simple_projection(2, side='left') + sage: v.apply_simple_projection(2, side='left') # optional - sage.combinat sage.groups s1*s2*s3*s4*s3*s1 - sage: v.apply_simple_projection(1, length_increasing = False) + sage: v.apply_simple_projection(1, length_increasing=False) # optional - sage.combinat sage.groups s1*s2*s3*s4*s3 """ @@ -2075,44 +2087,50 @@ def binary_factorizations(self, predicate=ConstantFunction(True)): We construct the set of all factorizations of the maximal element of the group:: - sage: W = WeylGroup(['A',3]) - sage: s = W.simple_reflections() - sage: w0 = W.from_reduced_word([1,2,3,1,2,1]) - sage: w0.binary_factorizations().cardinality() + sage: W = WeylGroup(['A', 3]) # optional - sage.combinat sage.groups + sage: s = W.simple_reflections() # optional - sage.combinat sage.groups + sage: w0 = W.from_reduced_word([1,2,3,1,2,1]) # optional - sage.combinat sage.groups + sage: w0.binary_factorizations().cardinality() # optional - sage.combinat sage.groups 24 The same number of factorizations, by bounded length:: - sage: [w0.binary_factorizations(lambda u: u.length() <= l).cardinality() for l in [-1,0,1,2,3,4,5,6]] + sage: [w0.binary_factorizations( # optional - sage.combinat sage.groups + ....: lambda u: u.length() <= l + ....: ).cardinality() + ....: for l in [-1,0,1,2,3,4,5,6]] [0, 1, 4, 9, 15, 20, 23, 24] The number of factorizations of the elements just below the maximal element:: - sage: [(s[i]*w0).binary_factorizations().cardinality() for i in [1,2,3]] + sage: [(s[i]*w0).binary_factorizations().cardinality() # optional - sage.combinat sage.groups + ....: for i in [1,2,3]] [12, 12, 12] - sage: w0.binary_factorizations(lambda u: False).cardinality() + sage: w0.binary_factorizations(lambda u: False).cardinality() # optional - sage.combinat sage.groups 0 TESTS:: - sage: w0.binary_factorizations().category() + sage: w0.binary_factorizations().category() # optional - sage.combinat sage.groups Category of finite enumerated sets Check that this is independent of the implementation of the group, see :trac:`34799`:: - sage: W1 = WeylGroup(['A',3]) - sage: W2 = Permutations(4) - sage: P = lambda pi: W2(list(pi.to_permutation())) - sage: d1 = {P(pi): set((P(w[0]), P(w[1])) for w in pi.binary_factorizations()) for pi in W1} - sage: d2 = {pi: set(pi.binary_factorizations()) for pi in W2} - sage: d1 == d2 + sage: W1 = WeylGroup(['A', 3]) # optional - sage.combinat sage.groups + sage: W2 = Permutations(4) # optional - sage.combinat sage.groups + sage: P = lambda pi: W2(list(pi.to_permutation())) # optional - sage.combinat sage.groups + sage: d1 = {P(pi): set((P(w[0]), P(w[1])) # optional - sage.combinat sage.groups + ....: for w in pi.binary_factorizations()) + ....: for pi in W1} + sage: d2 = {pi: set(pi.binary_factorizations()) for pi in W2} # optional - sage.combinat sage.groups + sage: d1 == d2 # optional - sage.combinat sage.groups True - sage: sage.combinat.permutation.Permutations.options.mult = "r2l" - sage: d3 = {pi: set(pi.binary_factorizations()) for pi in W2} - sage: d1 == d3 + sage: sage.combinat.permutation.Permutations.options.mult = "r2l" # optional - sage.combinat sage.groups + sage: d3 = {pi: set(pi.binary_factorizations()) for pi in W2} # optional - sage.combinat sage.groups + sage: d1 == d3 # optional - sage.combinat sage.groups True - sage: sage.combinat.permutation.Permutations.options._reset() + sage: sage.combinat.permutation.Permutations.options._reset() # optional - sage.combinat sage.groups """ from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest W = self.parent() @@ -2142,35 +2160,38 @@ def bruhat_lower_covers(self): EXAMPLES:: - sage: W = WeylGroup(["A",3]) - sage: w = W.from_reduced_word([3,2,3]) - sage: print([v.reduced_word() for v in w.bruhat_lower_covers()]) + sage: W = WeylGroup(["A", 3]) # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([3,2,3]) # optional - sage.combinat sage.groups + sage: print([v.reduced_word() for v in w.bruhat_lower_covers()]) # optional - sage.combinat sage.groups [[3, 2], [2, 3]] - sage: W = WeylGroup(["A",3]) - sage: print([v.reduced_word() for v in W.simple_reflection(1).bruhat_lower_covers()]) + sage: W = WeylGroup(["A", 3]) # optional - sage.combinat sage.groups + sage: print([v.reduced_word() # optional - sage.combinat sage.groups + ....: for v in W.simple_reflection(1).bruhat_lower_covers()]) [[]] - sage: print([v.reduced_word() for v in W.one().bruhat_lower_covers()]) + sage: print([v.reduced_word() # optional - sage.combinat sage.groups + ....: for v in W.one().bruhat_lower_covers()]) [] - sage: W = WeylGroup(["B",4,1]) - sage: w = W.from_reduced_word([0,2]) - sage: print([v.reduced_word() for v in w.bruhat_lower_covers()]) + sage: W = WeylGroup(["B", 4, 1]) # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([0,2]) # optional - sage.combinat sage.groups + sage: print([v.reduced_word() for v in w.bruhat_lower_covers()]) # optional - sage.combinat sage.groups [[2], [0]] - sage: W = WeylGroup("A3",prefix="s",implementation="permutation") - sage: [s1,s2,s3]=W.simple_reflections() - sage: (s1*s2*s3*s1).bruhat_lower_covers() + sage: W = WeylGroup("A3", prefix="s", implementation="permutation") # optional - sage.combinat sage.groups + sage: s1, s2, s3 = W.simple_reflections() # optional - sage.combinat sage.groups + sage: (s1*s2*s3*s1).bruhat_lower_covers() # optional - sage.combinat sage.groups [s2*s1*s3, s1*s2*s1, s1*s2*s3] We now show how to construct the Bruhat poset:: - sage: W = WeylGroup(["A",3]) - sage: covers = tuple([u, v] for v in W for u in v.bruhat_lower_covers() ) - sage: P = Poset((W, covers), cover_relations = True) - sage: P.show() + sage: W = WeylGroup(["A", 3]) # optional - sage.combinat sage.groups + sage: covers = tuple([u, v] # optional - sage.combinat sage.groups + ....: for v in W for u in v.bruhat_lower_covers()) + sage: P = Poset((W, covers), cover_relations = True) # optional - sage.combinat sage.groups sage.graphs + sage: P.show() # optional - sage.combinat sage.groups sage.graphs Alternatively, one can just use:: - sage: P = W.bruhat_poset() + sage: P = W.bruhat_poset() # optional - sage.combinat sage.groups sage.graphs The algorithm is taken from Stembridge's 'coxeter/weyl' package for Maple. """ @@ -2193,21 +2214,21 @@ def bruhat_upper_covers(self): EXAMPLES:: - sage: W = WeylGroup(['A',3,1], prefix="s") - sage: w = W.from_reduced_word([1,2,1]) - sage: w.bruhat_upper_covers() + sage: W = WeylGroup(['A', 3, 1], prefix="s") # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([1,2,1]) # optional - sage.combinat sage.groups + sage: w.bruhat_upper_covers() # optional - sage.combinat sage.groups [s1*s2*s1*s0, s1*s2*s0*s1, s0*s1*s2*s1, s3*s1*s2*s1, s2*s3*s1*s2, s1*s2*s3*s1] - sage: W = WeylGroup(['A',3]) - sage: w = W.long_element() - sage: w.bruhat_upper_covers() + sage: W = WeylGroup(['A', 3]) # optional - sage.combinat sage.groups + sage: w = W.long_element() # optional - sage.combinat sage.groups + sage: w.bruhat_upper_covers() # optional - sage.combinat sage.groups [] - sage: W = WeylGroup(['A',3]) - sage: w = W.from_reduced_word([1,2,1]) - sage: S = [v for v in W if w in v.bruhat_lower_covers()] - sage: C = w.bruhat_upper_covers() - sage: set(S) == set(C) + sage: W = WeylGroup(['A', 3]) # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([1,2,1]) # optional - sage.combinat sage.groups + sage: S = [v for v in W if w in v.bruhat_lower_covers()] # optional - sage.combinat sage.groups + sage: C = w.bruhat_upper_covers() # optional - sage.combinat sage.groups + sage: set(S) == set(C) # optional - sage.combinat sage.groups True """ Covers = set() @@ -2231,17 +2252,17 @@ def bruhat_lower_covers_reflections(self): EXAMPLES:: - sage: W = WeylGroup(['A',3], prefix="s") - sage: w = W.from_reduced_word([3,1,2,1]) - sage: w.bruhat_lower_covers_reflections() + sage: W = WeylGroup(['A', 3], prefix="s") # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([3,1,2,1]) # optional - sage.combinat sage.groups + sage: w.bruhat_lower_covers_reflections() # optional - sage.combinat sage.groups [(s1*s2*s1, s1*s2*s3*s2*s1), (s3*s2*s1, s2), (s3*s1*s2, s1)] TESTS: Check bug discovered in :trac:`32669` is fixed:: - sage: W = CoxeterGroup(['A',3], implementation='permutation') - sage: W.w0.bruhat_lower_covers_reflections() + sage: W = CoxeterGroup(['A', 3], implementation='permutation') # optional - sage.combinat sage.groups + sage: W.w0.bruhat_lower_covers_reflections() # optional - sage.combinat sage.groups [((1,3,7,9)(2,11,6,10)(4,8,5,12), (2,5)(3,9)(4,6)(8,11)(10,12)), ((1,11)(3,10)(4,9)(5,7)(6,12), (1,4)(2,8)(3,5)(7,10)(9,11)), ((1,9,7,3)(2,10,6,11)(4,12,5,8), (1,7)(2,4)(5,6)(8,10)(11,12))] @@ -2264,11 +2285,11 @@ def lower_cover_reflections(self, side='right'): EXAMPLES:: - sage: W = WeylGroup(['A',3],prefix="s") - sage: w = W.from_reduced_word([3,1,2,1]) - sage: w.lower_cover_reflections() + sage: W = WeylGroup(['A', 3],prefix="s") # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([3,1,2,1]) # optional - sage.combinat sage.groups + sage: w.lower_cover_reflections() # optional - sage.combinat sage.groups [s1*s2*s3*s2*s1, s2, s1] - sage: w.lower_cover_reflections(side='left') + sage: w.lower_cover_reflections(side='left') # optional - sage.combinat sage.groups [s2*s3*s2, s3, s1] """ @@ -2287,10 +2308,11 @@ def bruhat_upper_covers_reflections(self): EXAMPLES:: - sage: W = WeylGroup(['A',4], prefix="s") - sage: w = W.from_reduced_word([3,1,2,1]) - sage: w.bruhat_upper_covers_reflections() - [(s1*s2*s3*s2*s1, s3), (s2*s3*s1*s2*s1, s2*s3*s2), (s3*s4*s1*s2*s1, s4), (s4*s3*s1*s2*s1, s1*s2*s3*s4*s3*s2*s1)] + sage: W = WeylGroup(['A', 4], prefix="s") # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([3,1,2,1]) # optional - sage.combinat sage.groups + sage: w.bruhat_upper_covers_reflections() # optional - sage.combinat sage.groups + [(s1*s2*s3*s2*s1, s3), (s2*s3*s1*s2*s1, s2*s3*s2), + (s3*s4*s1*s2*s1, s4), (s4*s3*s1*s2*s1, s1*s2*s3*s4*s3*s2*s1)] """ Covers = set() for i in self.parent().index_set(): @@ -2310,11 +2332,11 @@ def cover_reflections(self, side='right'): EXAMPLES:: - sage: W = WeylGroup(['A',4], prefix="s") - sage: w = W.from_reduced_word([3,1,2,1]) - sage: w.cover_reflections() + sage: W = WeylGroup(['A', 4], prefix="s") # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([3,1,2,1]) # optional - sage.combinat sage.groups + sage: w.cover_reflections() # optional - sage.combinat sage.groups [s3, s2*s3*s2, s4, s1*s2*s3*s4*s3*s2*s1] - sage: w.cover_reflections(side='left') + sage: w.cover_reflections(side='left') # optional - sage.combinat sage.groups [s4, s2, s1*s2*s1, s3*s4*s3] """ @@ -2335,19 +2357,19 @@ def bruhat_le(self, other): EXAMPLES:: - sage: W = WeylGroup(["A",3]) - sage: u = W.from_reduced_word([1,2,1]) - sage: v = W.from_reduced_word([1,2,3,2,1]) - sage: u.bruhat_le(u) + sage: W = WeylGroup(["A", 3]) # optional - sage.combinat sage.groups + sage: u = W.from_reduced_word([1,2,1]) # optional - sage.combinat sage.groups + sage: v = W.from_reduced_word([1,2,3,2,1]) # optional - sage.combinat sage.groups + sage: u.bruhat_le(u) # optional - sage.combinat sage.groups True - sage: u.bruhat_le(v) + sage: u.bruhat_le(v) # optional - sage.combinat sage.groups True - sage: v.bruhat_le(u) + sage: v.bruhat_le(u) # optional - sage.combinat sage.groups False - sage: v.bruhat_le(v) + sage: v.bruhat_le(v) # optional - sage.combinat sage.groups True - sage: s = W.simple_reflections() - sage: s[1].bruhat_le(W.one()) + sage: s = W.simple_reflections() # optional - sage.combinat sage.groups + sage: s[1].bruhat_le(W.one()) # optional - sage.combinat sage.groups False The implementation uses the equivalent condition that any @@ -2368,19 +2390,21 @@ def bruhat_le(self, other): We now run consistency tests with permutations and :meth:`bruhat_lower_covers`:: - sage: W = WeylGroup(["A",3]) - sage: P4 = Permutations(4) + sage: W = WeylGroup(["A", 3]) # optional - sage.combinat sage.groups + sage: P4 = Permutations(4) # optional - sage.combinat sage.groups sage: def P4toW(w): return W.from_reduced_word(w.reduced_word()) - sage: for u in P4: + sage: for u in P4: # optional - sage.combinat sage.groups ....: for v in P4: ....: assert u.bruhat_lequal(v) == P4toW(u).bruhat_le(P4toW(v)) - sage: W = WeylGroup(["B",3]) - sage: P = W.bruhat_poset() # This is built from bruhat_lower_covers - sage: Q = Poset((W, attrcall("bruhat_le"))) # long time (10s) - sage: all( u.bruhat_le(v) == P.is_lequal(u,v) for u in W for v in W ) # long time (7s) + sage: W = WeylGroup(["B", 3]) # optional - sage.combinat sage.groups + sage: P = W.bruhat_poset() # This is built from bruhat_lower_covers # optional - sage.combinat sage.groups sage.graphs + sage: Q = Poset((W, attrcall("bruhat_le"))) # long time (10s) # optional - sage.combinat sage.groups sage.graphs + sage: all(u.bruhat_le(v) == P.is_lequal(u,v) # long time (7s) # optional - sage.combinat sage.groups sage.graphs + ....: for u in W for v in W) True - sage: all( P.is_lequal(u,v) == Q.is_lequal(u,v) for u in W for v in W) # long time (9s) + sage: all(P.is_lequal(u,v) == Q.is_lequal(u,v) # long time (9s) # optional - sage.combinat sage.groups sage.graphs + ....: for u in W for v in W) True """ if not have_same_parent(self, other): @@ -2409,21 +2433,21 @@ def weak_le(self, other, side='right'): EXAMPLES:: - sage: W = WeylGroup(["A",3]) - sage: u = W.from_reduced_word([1,2]) - sage: v = W.from_reduced_word([1,2,3,2]) - sage: u.weak_le(u) + sage: W = WeylGroup(["A", 3]) # optional - sage.combinat sage.groups + sage: u = W.from_reduced_word([1,2]) # optional - sage.combinat sage.groups + sage: v = W.from_reduced_word([1,2,3,2]) # optional - sage.combinat sage.groups + sage: u.weak_le(u) # optional - sage.combinat sage.groups True - sage: u.weak_le(v) + sage: u.weak_le(v) # optional - sage.combinat sage.groups True - sage: v.weak_le(u) + sage: v.weak_le(u) # optional - sage.combinat sage.groups False - sage: v.weak_le(v) + sage: v.weak_le(v) # optional - sage.combinat sage.groups True Comparison for left weak order is achieved with the option ``side``:: - sage: u.weak_le(v, side='left') + sage: u.weak_le(v, side='left') # optional - sage.combinat sage.groups False The implementation uses the equivalent condition that any @@ -2439,10 +2463,10 @@ def weak_le(self, other, side='right'): We now run consistency tests with permutations:: - sage: W = WeylGroup(["A",3]) - sage: P4 = Permutations(4) - sage: def P4toW(w): return W.from_reduced_word(w.reduced_word()) - sage: for u in P4: # long time (5s on sage.math, 2011) + sage: W = WeylGroup(["A", 3]) # optional - sage.combinat sage.groups + sage: P4 = Permutations(4) # optional - sage.combinat sage.groups + sage: def P4toW(w): return W.from_reduced_word(w.reduced_word()) # optional - sage.combinat sage.groups + sage: for u in P4: # long time (5s on sage.math, 2011) # optional - sage.combinat sage.groups ....: for v in P4: ....: assert u.permutohedron_lequal(v) == P4toW(u).weak_le(P4toW(v)) ....: assert u.permutohedron_lequal(v, side='left') == P4toW(u).weak_le(P4toW(v), side='left') @@ -2475,29 +2499,29 @@ def weak_covers(self, side='right', index_set=None, positive=False): EXAMPLES:: - sage: W = WeylGroup(['A',3]) - sage: w = W.from_reduced_word([3,2,1]) - sage: [x.reduced_word() for x in w.weak_covers()] + sage: W = WeylGroup(['A', 3]) # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([3,2,1]) # optional - sage.combinat sage.groups + sage: [x.reduced_word() for x in w.weak_covers()] # optional - sage.combinat sage.groups [[3, 2]] To obtain instead elements that cover self, set ``positive=True``:: - sage: [x.reduced_word() for x in w.weak_covers(positive=True)] + sage: [x.reduced_word() for x in w.weak_covers(positive=True)] # optional - sage.combinat sage.groups [[3, 1, 2, 1], [2, 3, 2, 1]] To obtain covers for left weak order, set the option side to 'left':: - sage: [x.reduced_word() for x in w.weak_covers(side='left')] + sage: [x.reduced_word() for x in w.weak_covers(side='left')] # optional - sage.combinat sage.groups [[2, 1]] - sage: w = W.from_reduced_word([3,2,3,1]) - sage: [x.reduced_word() for x in w.weak_covers()] + sage: w = W.from_reduced_word([3,2,3,1]) # optional - sage.combinat sage.groups + sage: [x.reduced_word() for x in w.weak_covers()] # optional - sage.combinat sage.groups [[2, 3, 2], [3, 2, 1]] - sage: [x.reduced_word() for x in w.weak_covers(side='left')] + sage: [x.reduced_word() for x in w.weak_covers(side='left')] # optional - sage.combinat sage.groups [[3, 2, 1], [2, 3, 1]] Covers w.r.t. a parabolic subgroup are obtained with the option ``index_set``:: - sage: [x.reduced_word() for x in w.weak_covers(index_set = [1,2])] + sage: [x.reduced_word() for x in w.weak_covers(index_set=[1,2])] # optional - sage.combinat sage.groups [[2, 3, 2]] """ return [self.apply_simple_reflection(i, side=side) @@ -2580,16 +2604,20 @@ def is_coxeter_sortable(self, c, sorting_word=None): [2, 0, 1, 2, 0] sage: w.is_coxeter_sortable(c) True - sage: W = CoxeterGroup(['A',3]) - sage: c = W.from_reduced_word([1,2,3]) - sage: len([w for w in W if w.is_coxeter_sortable(c)]) # number of c-sortable elements in A_3 (Catalan number) + + sage: W = CoxeterGroup(['A', 3]) # optional - sage.combinat sage.groups + sage: c = W.from_reduced_word([1,2,3]) # optional - sage.combinat sage.groups + + Number of `c`-sortable elements in `A_3` (Catalan number):: + + sage: len([w for w in W if w.is_coxeter_sortable(c)]) # optional - sage.combinat sage.groups 14 TESTS:: - sage: W = SymmetricGroup(3) - sage: c = Permutation((1,2,3)) - sage: sorted(w for w in W if w.is_coxeter_sortable(c)) + sage: W = SymmetricGroup(3) # optional - sage.combinat sage.groups + sage: c = Permutation((1,2,3)) # optional - sage.combinat sage.groups + sage: sorted(w for w in W if w.is_coxeter_sortable(c)) # optional - sage.combinat sage.groups [(), (2,3), (1,2), (1,3,2), (1,3)] """ if hasattr(c, "reduced_word"): @@ -2640,15 +2668,15 @@ def apply_demazure_product(self, element, side='right', EXAMPLES:: - sage: W = WeylGroup(['C',4],prefix="s") - sage: v = W.from_reduced_word([1,2,3,4,3,1]) - sage: v.apply_demazure_product([1,3,4,3,3]) + sage: W = WeylGroup(['C', 4], prefix="s") # optional - sage.combinat sage.groups + sage: v = W.from_reduced_word([1,2,3,4,3,1]) # optional - sage.combinat sage.groups + sage: v.apply_demazure_product([1,3,4,3,3]) # optional - sage.combinat sage.groups s4*s1*s2*s3*s4*s3*s1 - sage: v.apply_demazure_product([1,3,4,3],side='left') + sage: v.apply_demazure_product([1,3,4,3], side='left') # optional - sage.combinat sage.groups s3*s4*s1*s2*s3*s4*s2*s3*s1 - sage: v.apply_demazure_product((1,3,4,3),side='left') + sage: v.apply_demazure_product((1,3,4,3), side='left') # optional - sage.combinat sage.groups s3*s4*s1*s2*s3*s4*s2*s3*s1 - sage: v.apply_demazure_product(v) + sage: v.apply_demazure_product(v) # optional - sage.combinat sage.groups s2*s3*s4*s1*s2*s3*s4*s2*s3*s2*s1 """ @@ -2683,14 +2711,14 @@ def min_demazure_product_greater(self, element): EXAMPLES:: - sage: W = WeylGroup(['A',4],prefix="s") - sage: v = W.from_reduced_word([2,3,4,1,2]) - sage: u = W.from_reduced_word([2,3,2,1]) - sage: v.min_demazure_product_greater(u) + sage: W = WeylGroup(['A', 4], prefix="s") # optional - sage.combinat sage.groups + sage: v = W.from_reduced_word([2,3,4,1,2]) # optional - sage.combinat sage.groups + sage: u = W.from_reduced_word([2,3,2,1]) # optional - sage.combinat sage.groups + sage: v.min_demazure_product_greater(u) # optional - sage.combinat sage.groups s4*s2 - sage: v.min_demazure_product_greater([2,3,2,1]) + sage: v.min_demazure_product_greater([2,3,2,1]) # optional - sage.combinat sage.groups s4*s2 - sage: v.min_demazure_product_greater((2,3,2,1)) + sage: v.min_demazure_product_greater((2,3,2,1)) # optional - sage.combinat sage.groups s4*s2 """ @@ -2730,14 +2758,14 @@ def deodhar_factor_element(self, w, index_set): EXAMPLES:: - sage: W = WeylGroup(['A',5],prefix="s") - sage: v = W.from_reduced_word([5]) - sage: w = W.from_reduced_word([4,5,2,3,1,2]) - sage: v.deodhar_factor_element(w,[1,3,4]) + sage: W = WeylGroup(['A', 5], prefix="s") # optional - sage.combinat sage.groups + sage: v = W.from_reduced_word([5]) # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([4,5,2,3,1,2]) # optional - sage.combinat sage.groups + sage: v.deodhar_factor_element(w, [1,3,4]) # optional - sage.combinat sage.groups s3*s1 - sage: W = WeylGroup(['C',2]) - sage: w = W.from_reduced_word([2,1]) - sage: w.deodhar_factor_element(W.from_reduced_word([2]),[1]) + sage: W = WeylGroup(['C', 2]) # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([2,1]) # optional - sage.combinat sage.groups + sage: w.deodhar_factor_element(W.from_reduced_word([2]),[1]) # optional - sage.combinat sage.groups Traceback (most recent call last): ... ValueError: [2, 1] is not of minimum length in its coset for the parabolic subgroup with index set [1] @@ -2785,10 +2813,10 @@ def deodhar_lift_up(self, w, index_set): EXAMPLES:: - sage: W = WeylGroup(['A',3],prefix="s") - sage: v = W.from_reduced_word([1,2,3]) - sage: w = W.from_reduced_word([1,3,2]) - sage: v.deodhar_lift_up(w, [3]) + sage: W = WeylGroup(['A', 3], prefix="s") # optional - sage.combinat sage.groups + sage: v = W.from_reduced_word([1,2,3]) # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([1,3,2]) # optional - sage.combinat sage.groups + sage: v.deodhar_lift_up(w, [3]) # optional - sage.combinat sage.groups s1*s2*s3*s2 """ vmin = self.coset_representative(index_set) @@ -2819,10 +2847,10 @@ def deodhar_lift_down(self, w, index_set): EXAMPLES:: - sage: W = WeylGroup(['A',3],prefix="s") - sage: v = W.from_reduced_word([1,2,3,2]) - sage: w = W.from_reduced_word([3,2]) - sage: v.deodhar_lift_down(w, [3]) + sage: W = WeylGroup(['A', 3], prefix="s") # optional - sage.combinat sage.groups + sage: v = W.from_reduced_word([1,2,3,2]) # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([3,2]) # optional - sage.combinat sage.groups + sage: v.deodhar_lift_down(w, [3]) # optional - sage.combinat sage.groups s2*s3*s2 """ @@ -2842,9 +2870,9 @@ def inversions_as_reflections(self): EXAMPLES:: - sage: W = WeylGroup(['A',3], prefix="s") - sage: w = W.from_reduced_word([3,1,2,1]) - sage: w.inversions_as_reflections() + sage: W = WeylGroup(['A', 3], prefix="s") # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([3,1,2,1]) # optional - sage.combinat sage.groups + sage: w.inversions_as_reflections() # optional - sage.combinat sage.groups [s1, s1*s2*s1, s2, s1*s2*s3*s2*s1] """ i = self.first_descent() @@ -2859,9 +2887,9 @@ def left_inversions_as_reflections(self): EXAMPLES:: - sage: W = WeylGroup(['A',3], prefix="s") - sage: w = W.from_reduced_word([3,1,2,1]) - sage: w.left_inversions_as_reflections() + sage: W = WeylGroup(['A', 3], prefix="s") # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([3,1,2,1]) # optional - sage.combinat sage.groups + sage: w.left_inversions_as_reflections() # optional - sage.combinat sage.groups [s1, s3, s1*s2*s3*s2*s1, s2*s3*s2] """ return self.inverse().inversions_as_reflections() @@ -2872,31 +2900,31 @@ def lower_covers(self, side='right', index_set=None): INPUT: - - side -- 'left' or 'right' (default: 'right') - - index_set -- a list of indices or ``None`` + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) + - ``index_set`` -- a list of indices or ``None`` OUTPUT: a list EXAMPLES:: - sage: W = WeylGroup(['A',3]) - sage: w = W.from_reduced_word([3,2,1]) - sage: [x.reduced_word() for x in w.lower_covers()] + sage: W = WeylGroup(['A', 3]) # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([3,2,1]) # optional - sage.combinat sage.groups + sage: [x.reduced_word() for x in w.lower_covers()] # optional - sage.combinat sage.groups [[3, 2]] To obtain covers for left weak order, set the option side to 'left':: - sage: [x.reduced_word() for x in w.lower_covers(side='left')] + sage: [x.reduced_word() for x in w.lower_covers(side='left')] # optional - sage.combinat sage.groups [[2, 1]] - sage: w = W.from_reduced_word([3,2,3,1]) - sage: [x.reduced_word() for x in w.lower_covers()] + sage: w = W.from_reduced_word([3,2,3,1]) # optional - sage.combinat sage.groups + sage: [x.reduced_word() for x in w.lower_covers()] # optional - sage.combinat sage.groups [[2, 3, 2], [3, 2, 1]] Covers w.r.t. a parabolic subgroup are obtained with the option ``index_set``:: - sage: [x.reduced_word() for x in w.lower_covers(index_set = [1,2])] + sage: [x.reduced_word() for x in w.lower_covers(index_set=[1,2])] # optional - sage.combinat sage.groups [[2, 3, 2]] - sage: [x.reduced_word() for x in w.lower_covers(side='left')] + sage: [x.reduced_word() for x in w.lower_covers(side='left')] # optional - sage.combinat sage.groups [[3, 2, 1], [2, 3, 1]] """ return self.weak_covers(side=side, index_set=index_set, @@ -2908,28 +2936,29 @@ def upper_covers(self, side='right', index_set=None): INPUT: - - side -- 'left' or 'right' (default: 'right') - - index_set -- a list of indices or None + - ``side`` -- ``'left'`` or ``'right'`` (default: ``'right'``) + - ``index_set`` -- a list of indices or ``None`` OUTPUT: a list EXAMPLES:: - sage: W = WeylGroup(['A',3]) - sage: w = W.from_reduced_word([2,3]) - sage: [x.reduced_word() for x in w.upper_covers()] + sage: W = WeylGroup(['A', 3]) # optional - sage.combinat sage.groups + sage: w = W.from_reduced_word([2,3]) # optional - sage.combinat sage.groups + sage: [x.reduced_word() for x in w.upper_covers()] # optional - sage.combinat sage.groups [[2, 3, 1], [2, 3, 2]] To obtain covers for left weak order, set the option ``side`` to 'left':: - sage: [x.reduced_word() for x in w.upper_covers(side='left')] + sage: [x.reduced_word() for x in w.upper_covers(side='left')] # optional - sage.combinat sage.groups [[1, 2, 3], [2, 3, 2]] Covers w.r.t. a parabolic subgroup are obtained with the option ``index_set``:: - sage: [x.reduced_word() for x in w.upper_covers(index_set = [1])] + sage: [x.reduced_word() for x in w.upper_covers(index_set=[1])] # optional - sage.combinat sage.groups [[2, 3, 1]] - sage: [x.reduced_word() for x in w.upper_covers(side='left', index_set = [1])] + sage: [x.reduced_word() # optional - sage.combinat sage.groups + ....: for x in w.upper_covers(side='left', index_set=[1])] [[1, 2, 3]] """ return self.weak_covers(side=side, index_set=index_set, @@ -2972,9 +3001,9 @@ def kazhdan_lusztig_cell(self, side='left'): choice of implementation affects the representation of elements in the output cell but not the method used for the cell computation:: - sage: W = CoxeterGroup('A3', implementation='permutation') - sage: s1,s2,s3 = W.simple_reflections() - sage: s1.kazhdan_lusztig_cell() + sage: W = CoxeterGroup('A3', implementation='permutation') # optional - sage.combinat sage.groups + sage: s1, s2, s3 = W.simple_reflections() # optional - sage.combinat sage.groups + sage: s1.kazhdan_lusztig_cell() # optional - sage.combinat sage.groups {(1,2,3,12)(4,5,10,11)(6,7,8,9), (1,2,10)(3,6,5)(4,7,8)(9,12,11), (1,7)(2,4)(5,6)(8,10)(11,12)} diff --git a/src/sage/categories/crystals.py b/src/sage/categories/crystals.py index f74340cf25d..3ceb16529d6 100644 --- a/src/sage/categories/crystals.py +++ b/src/sage/categories/crystals.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.graphs sage.combinat r""" Crystals diff --git a/src/sage/categories/discrete_valuation.py b/src/sage/categories/discrete_valuation.py index 5b68f8b6c12..42829732859 100644 --- a/src/sage/categories/discrete_valuation.py +++ b/src/sage/categories/discrete_valuation.py @@ -20,7 +20,7 @@ class DiscreteValuationRings(Category_singleton): EXAMPLES:: - sage: GF(7)[['x']] in DiscreteValuationRings() + sage: GF(7)[['x']] in DiscreteValuationRings() # optional - sage.rings.finite_rings True sage: TestSuite(DiscreteValuationRings()).run() """ @@ -41,7 +41,7 @@ def uniformizer(self): EXAMPLES:: - sage: Zp(5).uniformizer() + sage: Zp(5).uniformizer() # optional - sage.rings.padics 5 + O(5^21) sage: K. = QQ[[]] @@ -56,7 +56,7 @@ def residue_field(self): EXAMPLES:: - sage: Zp(5).residue_field() + sage: Zp(5).residue_field() # optional - sage.rings.padics Finite Field of size 5 sage: K. = QQ[[]] @@ -70,38 +70,38 @@ def _matrix_charpoly(self, M, var): EXAMPLES:: - sage: R. = PowerSeriesRing(GF(5)) - sage: M = matrix(4, 4, [ (t^(i+j)).add_bigoh(10) - ....: for i in range(4) for j in range(4) ]) - sage: M + sage: R. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: M = matrix(4, 4, [(t^(i+j)).add_bigoh(10) # optional - sage.rings.finite_rings + ....: for i in range(4) for j in range(4)]) + sage: M # optional - sage.rings.finite_rings [ 1 + O(t^10) t + O(t^10) t^2 + O(t^10) t^3 + O(t^10)] [ t + O(t^10) t^2 + O(t^10) t^3 + O(t^10) t^4 + O(t^10)] [t^2 + O(t^10) t^3 + O(t^10) t^4 + O(t^10) t^5 + O(t^10)] [t^3 + O(t^10) t^4 + O(t^10) t^5 + O(t^10) t^6 + O(t^10)] - sage: M.charpoly() # indirect doctest + sage: M.charpoly() # indirect doctest # optional - sage.rings.finite_rings x^4 + (4 + 4*t^2 + 4*t^4 + 4*t^6 + O(t^10))*x^3 Note that this function uses a Hessenberg-like algorithm that performs divisions. Hence, truncations may show up even if the input matrix is exact:: - sage: M = matrix(3, 3, [ 1, t, t^2, 1+t, t^2, t^3, t^2, t^3, t^4 ]) - sage: M + sage: M = matrix(3, 3, [ 1, t, t^2, 1+t, t^2, t^3, t^2, t^3, t^4 ]) # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings [ 1 t t^2] [1 + t t^2 t^3] [ t^2 t^3 t^4] - sage: M.charpoly() + sage: M.charpoly() # optional - sage.rings.finite_rings x^3 + (4 + 4*t^2 + 4*t^4 + O(t^25))*x^2 + (4*t + O(t^24))*x Another example over the p-adics:: - sage: R = Zp(5, print_mode="digits", prec=5) - sage: M = matrix(R, 3, 3, range(9)) - sage: M + sage: R = Zp(5, print_mode="digits", prec=5) # optional - sage.rings.padics + sage: M = matrix(R, 3, 3, range(9)) # optional - sage.rings.padics + sage: M # optional - sage.rings.padics [ 0 ...00001 ...00002] [ ...00003 ...00004 ...000010] [ ...00011 ...00012 ...00013] - sage: M.charpoly() + sage: M.charpoly() # optional - sage.rings.padics ...00001*x^3 + ...44423*x^2 + ...44412*x + ...00000 """ return M._charpoly_hessenberg(var) @@ -114,8 +114,8 @@ def valuation(self): EXAMPLES:: - sage: x = Zp(5)(50) - sage: x.valuation() + sage: x = Zp(5)(50) # optional - sage.rings.padics + sage: x.valuation() # optional - sage.rings.padics 2 """ @@ -125,10 +125,10 @@ def euclidean_degree(self): TESTS:: - sage: R. = GF(5)[[]] - sage: (q^3).euclidean_degree() + sage: R. = GF(5)[[]] # optional - sage.rings.finite_rings + sage: (q^3).euclidean_degree() # optional - sage.rings.finite_rings 3 - sage: R(0).euclidean_degree() + sage: R(0).euclidean_degree() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: Euclidean degree of the zero element not defined @@ -145,12 +145,12 @@ def quo_rem(self, other): TESTS:: - sage: R. = GF(5)[[]] - sage: (q^2 + q).quo_rem(q) + sage: R. = GF(5)[[]] # optional - sage.rings.finite_rings + sage: (q^2 + q).quo_rem(q) # optional - sage.rings.finite_rings (1 + q, 0) - sage: (q + 1).quo_rem(q^2) + sage: (q + 1).quo_rem(q^2) # optional - sage.rings.finite_rings (0, 1 + q) - sage: q.quo_rem(0) + sage: q.quo_rem(0) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: Euclidean division by the zero element not defined @@ -170,12 +170,12 @@ def is_unit(self): EXAMPLES:: - sage: x = Zp(5)(50) - sage: x.is_unit() + sage: x = Zp(5)(50) # optional - sage.rings.padics + sage: x.is_unit() # optional - sage.rings.padics False - sage: x = Zp(7)(50) - sage: x.is_unit() + sage: x = Zp(7)(50) # optional - sage.rings.padics + sage: x.is_unit() # optional - sage.rings.padics True """ return self.valuation() == 0 @@ -213,7 +213,7 @@ class DiscreteValuationFields(Category_singleton): EXAMPLES:: - sage: Qp(7) in DiscreteValuationFields() + sage: Qp(7) in DiscreteValuationFields() # optional - sage.rings.padics True sage: TestSuite(DiscreteValuationFields()).run() """ @@ -235,7 +235,7 @@ def uniformizer(self): EXAMPLES:: - sage: Qp(5).uniformizer() + sage: Qp(5).uniformizer() # optional - sage.rings.padics 5 + O(5^21) """ @@ -247,7 +247,7 @@ def residue_field(self): EXAMPLES:: - sage: Qp(5).residue_field() + sage: Qp(5).residue_field() # optional - sage.rings.padics Finite Field of size 5 sage: K. = LaurentSeriesRing(QQ) @@ -261,17 +261,17 @@ def _matrix_hessenbergize(self, H): EXAMPLES:: - sage: R. = PowerSeriesRing(GF(5)) - sage: K = R.fraction_field() - sage: H = matrix(K, 4, 4, [ (t^(i+j)).add_bigoh(10) - ....: for i in range(4) for j in range(4) ]) - sage: H + sage: R. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: K = R.fraction_field() # optional - sage.rings.finite_rings + sage: H = matrix(K, 4, 4, [(t^(i+j)).add_bigoh(10) # optional - sage.rings.finite_rings + ....: for i in range(4) for j in range(4)]) + sage: H # optional - sage.rings.finite_rings [ 1 + O(t^10) t + O(t^10) t^2 + O(t^10) t^3 + O(t^10)] [ t + O(t^10) t^2 + O(t^10) t^3 + O(t^10) t^4 + O(t^10)] [t^2 + O(t^10) t^3 + O(t^10) t^4 + O(t^10) t^5 + O(t^10)] [t^3 + O(t^10) t^4 + O(t^10) t^5 + O(t^10) t^6 + O(t^10)] - sage: H.hessenbergize() - sage: H + sage: H.hessenbergize() # optional - sage.rings.finite_rings + sage: H # optional - sage.rings.finite_rings [ 1 + O(t^10) t + t^3 + t^5 + O(t^10) t^2 + O(t^10) t^3 + O(t^10)] [ t + O(t^10) t^2 + t^4 + t^6 + O(t^10) t^3 + O(t^10) t^4 + O(t^10)] [ O(t^10) O(t^10) O(t^10) O(t^10)] @@ -279,14 +279,14 @@ def _matrix_hessenbergize(self, H): Another example over the p-adics:: - sage: K = Qp(5, print_mode="digits", prec=5) - sage: H = matrix(K, 3, 3, range(9)) - sage: H + sage: K = Qp(5, print_mode="digits", prec=5) # optional - sage.rings.padics + sage: H = matrix(K, 3, 3, range(9)) # optional - sage.rings.padics + sage: H # optional - sage.rings.padics [ 0 ...00001 ...00002] [ ...00003 ...00004 ...000010] [ ...00011 ...00012 ...00013] - sage: H.hessenbergize() - sage: H + sage: H.hessenbergize() # optional - sage.rings.padics + sage: H # optional - sage.rings.padics [ 0 ...00010 ...00002] [ ...00003 ...00024 ...000010] [ ...00000 ...44440 ...44443] @@ -302,7 +302,7 @@ def valuation(self): EXAMPLES:: - sage: x = Qp(5)(50) - sage: x.valuation() + sage: x = Qp(5)(50) # optional - sage.rings.padics + sage: x.valuation() # optional - sage.rings.padics 2 """ diff --git a/src/sage/categories/domains.py b/src/sage/categories/domains.py index c40f95ba880..02062390a02 100644 --- a/src/sage/categories/domains.py +++ b/src/sage/categories/domains.py @@ -59,21 +59,21 @@ def _test_zero_divisors(self, **options): not have them in theory. For such inexact rings, these tests are not performed:: - sage: R = ZpFM(5); R + sage: R = ZpFM(5); R # optional - sage.rings.padics 5-adic Ring of fixed modulus 5^20 - sage: R.is_exact() + sage: R.is_exact() # optional - sage.rings.padics False - sage: a = R(5^19) - sage: a.is_zero() + sage: a = R(5^19) # optional - sage.rings.padics + sage: a.is_zero() # optional - sage.rings.padics False - sage: (a*a).is_zero() + sage: (a * a).is_zero() # optional - sage.rings.padics True - sage: R._test_zero_divisors() + sage: R._test_zero_divisors() # optional - sage.rings.padics EXAMPLES:: sage: ZZ._test_zero_divisors() - sage: ZpFM(5)._test_zero_divisors() + sage: ZpFM(5)._test_zero_divisors() # optional - sage.rings.padics """ if not self.is_exact(): diff --git a/src/sage/categories/drinfeld_modules.py b/src/sage/categories/drinfeld_modules.py index 4a4f193bf1c..2ae9eb54173 100644 --- a/src/sage/categories/drinfeld_modules.py +++ b/src/sage/categories/drinfeld_modules.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings r""" Drinfeld modules over a base diff --git a/src/sage/categories/enumerated_sets.py b/src/sage/categories/enumerated_sets.py index 1097a04412a..b58cb646aba 100644 --- a/src/sage/categories/enumerated_sets.py +++ b/src/sage/categories/enumerated_sets.py @@ -85,7 +85,8 @@ class EnumeratedSets(CategoryWithAxiom): sage: EnumeratedSets().super_categories() [Category of sets] sage: EnumeratedSets().all_super_categories() - [Category of enumerated sets, Category of sets, Category of sets with partial maps, Category of objects] + [Category of enumerated sets, Category of sets, + Category of sets with partial maps, Category of objects] TESTS:: @@ -277,33 +278,33 @@ def iterator_range(self, start=None, stop=None, step=None): EXAMPLES:: - sage: P = Partitions() - sage: list(P.iterator_range(stop=5)) + sage: P = Partitions() # optional - sage.combinat + sage: list(P.iterator_range(stop=5)) # optional - sage.combinat [[], [1], [2], [1, 1], [3]] - sage: list(P.iterator_range(0, 5)) + sage: list(P.iterator_range(0, 5)) # optional - sage.combinat [[], [1], [2], [1, 1], [3]] - sage: list(P.iterator_range(3, 5)) + sage: list(P.iterator_range(3, 5)) # optional - sage.combinat [[1, 1], [3]] - sage: list(P.iterator_range(3, 10)) + sage: list(P.iterator_range(3, 10)) # optional - sage.combinat [[1, 1], [3], [2, 1], [1, 1, 1], [4], [3, 1], [2, 2]] - sage: list(P.iterator_range(3, 10, 2)) + sage: list(P.iterator_range(3, 10, 2)) # optional - sage.combinat [[1, 1], [2, 1], [4], [2, 2]] - sage: it = P.iterator_range(3) - sage: [next(it) for x in range(10)] + sage: it = P.iterator_range(3) # optional - sage.combinat + sage: [next(it) for x in range(10)] # optional - sage.combinat [[1, 1], [3], [2, 1], [1, 1, 1], [4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1], [5]] - sage: it = P.iterator_range(3, step=2) - sage: [next(it) for x in range(5)] + sage: it = P.iterator_range(3, step=2) # optional - sage.combinat + sage: [next(it) for x in range(5)] # optional - sage.combinat [[1, 1], [2, 1], [4], [2, 2], [1, 1, 1, 1]] - sage: next(P.iterator_range(stop=-3)) + sage: next(P.iterator_range(stop=-3)) # optional - sage.combinat Traceback (most recent call last): ... NotImplementedError: cannot list an infinite set - sage: next(P.iterator_range(start=-3)) + sage: next(P.iterator_range(start=-3)) # optional - sage.combinat Traceback (most recent call last): ... NotImplementedError: cannot list an infinite set @@ -356,26 +357,26 @@ def unrank_range(self, start=None, stop=None, step=None): EXAMPLES:: - sage: P = Partitions() - sage: P.unrank_range(stop=5) + sage: P = Partitions() # optional - sage.combinat + sage: P.unrank_range(stop=5) # optional - sage.combinat [[], [1], [2], [1, 1], [3]] - sage: P.unrank_range(0, 5) + sage: P.unrank_range(0, 5) # optional - sage.combinat [[], [1], [2], [1, 1], [3]] - sage: P.unrank_range(3, 5) + sage: P.unrank_range(3, 5) # optional - sage.combinat [[1, 1], [3]] - sage: P.unrank_range(3, 10) + sage: P.unrank_range(3, 10) # optional - sage.combinat [[1, 1], [3], [2, 1], [1, 1, 1], [4], [3, 1], [2, 2]] - sage: P.unrank_range(3, 10, 2) + sage: P.unrank_range(3, 10, 2) # optional - sage.combinat [[1, 1], [2, 1], [4], [2, 2]] - sage: P.unrank_range(3) + sage: P.unrank_range(3) # optional - sage.combinat Traceback (most recent call last): ... NotImplementedError: cannot list an infinite set - sage: P.unrank_range(stop=-3) + sage: P.unrank_range(stop=-3) # optional - sage.combinat Traceback (most recent call last): ... NotImplementedError: cannot list an infinite set - sage: P.unrank_range(start=-3) + sage: P.unrank_range(start=-3) # optional - sage.combinat Traceback (most recent call last): ... NotImplementedError: cannot list an infinite set @@ -409,24 +410,24 @@ def __getitem__(self, i): EXAMPLES:: - sage: P = Partitions() - sage: P[:5] + sage: P = Partitions() # optional - sage.combinat + sage: P[:5] # optional - sage.combinat [[], [1], [2], [1, 1], [3]] - sage: P[0:5] + sage: P[0:5] # optional - sage.combinat [[], [1], [2], [1, 1], [3]] - sage: P[3:5] + sage: P[3:5] # optional - sage.combinat [[1, 1], [3]] - sage: P[3:10] + sage: P[3:10] # optional - sage.combinat [[1, 1], [3], [2, 1], [1, 1, 1], [4], [3, 1], [2, 2]] - sage: P[3:10:2] + sage: P[3:10:2] # optional - sage.combinat [[1, 1], [2, 1], [4], [2, 2]] - sage: P[3:] + sage: P[3:] # optional - sage.combinat Traceback (most recent call last): ... NotImplementedError: cannot list an infinite set - sage: P[3] + sage: P[3] # optional - sage.combinat [1, 1] - sage: P[-1] + sage: P[-1] # optional - sage.combinat Traceback (most recent call last): ... NotImplementedError: cannot list an infinite set @@ -467,9 +468,9 @@ def __len__(self): EXAMPLES:: - sage: len(GF(5)) + sage: len(GF(5)) # optional - sage.libs.pari 5 - sage: len(MatrixSpace(GF(2), 3, 3)) + sage: len(MatrixSpace(GF(2), 3, 3)) # optional - sage.libs.pari sage.modules 512 """ from sage.rings.infinity import Infinity @@ -494,7 +495,7 @@ def tuple(self): EXAMPLES:: - sage: (GF(3)^2).tuple() + sage: (GF(3)^2).tuple() # optional - sage.libs.pari ((0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2), (2, 2)) sage: R = Integers(11) sage: l = R.tuple(); l @@ -575,7 +576,7 @@ def list(self): EXAMPLES:: - sage: (GF(3)^2).list() + sage: (GF(3)^2).list() # optional - sage.libs.pari [(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2), (2, 2)] sage: R = Integers(11) sage: R.list() @@ -603,7 +604,7 @@ def _list_from_iterator(self): Trying to list an infinite vector space raises an error instead of running forever (see :trac:`10470`):: - sage: (QQ^2).list() # indirect test + sage: (QQ^2).list() # indirect test # optional - sage.modules Traceback (most recent call last): ... AttributeError: 'FreeModule_ambient_field_with_category' object has no attribute 'list' @@ -958,16 +959,16 @@ def map(self, f, name=None, *, is_injective=True): EXAMPLES:: - sage: R = Compositions(4).map(attrcall('partial_sums')); R + sage: R = Compositions(4).map(attrcall('partial_sums')); R # optional - sage.combinat Image of Compositions of 4 by The map *.partial_sums() from Compositions of 4 - sage: R.cardinality() + sage: R.cardinality() # optional - sage.combinat 8 - sage: R.list() + sage: R.list() # optional - sage.combinat [[1, 2, 3, 4], [1, 2, 4], [1, 3, 4], [1, 4], [2, 3, 4], [2, 4], [3, 4], [4]] - sage: [r for r in R] + sage: [r for r in R] # optional - sage.combinat [[1, 2, 3, 4], [1, 2, 4], [1, 3, 4], [1, 4], [2, 3, 4], [2, 4], [3, 4], [4]] - sage: R.category() + sage: R.category() # optional - sage.combinat Category of finite enumerated subobjects of sets .. WARNING:: @@ -975,20 +976,20 @@ def map(self, f, name=None, *, is_injective=True): If the function is not injective, then there may be repeated elements:: - sage: P = Compositions(4) - sage: P.list() + sage: P = Compositions(4) # optional - sage.combinat + sage: P.list() # optional - sage.combinat [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1], [4]] - sage: P.map(attrcall('major_index')).list() + sage: P.map(attrcall('major_index')).list() # optional - sage.combinat [6, 3, 4, 1, 5, 2, 3, 0] Pass ``is_injective=False`` to get a correct result in this case:: - sage: P.map(attrcall('major_index'), is_injective=False).list() + sage: P.map(attrcall('major_index'), is_injective=False).list() # optional - sage.combinat [6, 3, 4, 1, 5, 2, 0] TESTS:: - sage: TestSuite(R).run(skip=['_test_an_element', + sage: TestSuite(R).run(skip=['_test_an_element', # optional - sage.combinat ....: '_test_enumerated_set_contains', ....: '_test_some_elements']) """ diff --git a/src/sage/categories/examples/algebras_with_basis.py b/src/sage/categories/examples/algebras_with_basis.py index f1d05839e2a..ccbc3a3a9c0 100644 --- a/src/sage/categories/examples/algebras_with_basis.py +++ b/src/sage/categories/examples/algebras_with_basis.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat r""" Examples of algebras with basis """ diff --git a/src/sage/categories/examples/crystals.py b/src/sage/categories/examples/crystals.py index 02121cd3c02..c38117b3b70 100644 --- a/src/sage/categories/examples/crystals.py +++ b/src/sage/categories/examples/crystals.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.graphs r""" Example of a crystal """ diff --git a/src/sage/categories/examples/filtered_modules_with_basis.py b/src/sage/categories/examples/filtered_modules_with_basis.py index 0b5e9b475eb..3cf9db3f57c 100644 --- a/src/sage/categories/examples/filtered_modules_with_basis.py +++ b/src/sage/categories/examples/filtered_modules_with_basis.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.combinat r""" Examples of filtered modules with basis """ diff --git a/src/sage/categories/examples/finite_coxeter_groups.py b/src/sage/categories/examples/finite_coxeter_groups.py index c7937688ef8..57ada2a0c2b 100644 --- a/src/sage/categories/examples/finite_coxeter_groups.py +++ b/src/sage/categories/examples/finite_coxeter_groups.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.groups r""" Examples of finite Coxeter groups """ diff --git a/src/sage/categories/examples/finite_dimensional_algebras_with_basis.py b/src/sage/categories/examples/finite_dimensional_algebras_with_basis.py index f51b66c49dd..ac18f69b6ec 100644 --- a/src/sage/categories/examples/finite_dimensional_algebras_with_basis.py +++ b/src/sage/categories/examples/finite_dimensional_algebras_with_basis.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules r""" Example of a finite dimensional algebra with basis """ diff --git a/src/sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py b/src/sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py index a975d902e14..db28f48dff7 100644 --- a/src/sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +++ b/src/sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules r""" Examples of a finite dimensional Lie algebra with basis """ diff --git a/src/sage/categories/examples/finite_semigroups.py b/src/sage/categories/examples/finite_semigroups.py index e21a9713815..bf00b415b58 100644 --- a/src/sage/categories/examples/finite_semigroups.py +++ b/src/sage/categories/examples/finite_semigroups.py @@ -25,7 +25,8 @@ class LeftRegularBand(UniqueRepresentation, Parent): EXAMPLES:: sage: S = FiniteSemigroups().example(); S - An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd') + An example of a finite semigroup: + the left regular band generated by ('a', 'b', 'c', 'd') This is the semigroup generated by:: @@ -69,9 +70,9 @@ class LeftRegularBand(UniqueRepresentation, Parent): Now, let us look at the structure of the semigroup:: sage: S = FiniteSemigroups().example(alphabet = ('a','b','c')) - sage: S.cayley_graph(side="left", simple=True).plot() + sage: S.cayley_graph(side="left", simple=True).plot() # optional - sage.graphs Graphics object consisting of 60 graphics primitives - sage: S.j_transversal_of_idempotents() # random (arbitrary choice) + sage: S.j_transversal_of_idempotents() # random (arbitrary choice) # optional - sage.graphs ['acb', 'ac', 'ab', 'bc', 'a', 'c', 'b'] We conclude by running systematic tests on this semigroup:: diff --git a/src/sage/categories/examples/finite_weyl_groups.py b/src/sage/categories/examples/finite_weyl_groups.py index 535d5101101..b4d6c05a233 100644 --- a/src/sage/categories/examples/finite_weyl_groups.py +++ b/src/sage/categories/examples/finite_weyl_groups.py @@ -59,7 +59,7 @@ class SymmetricGroup(UniqueRepresentation, Parent): 24 sage: S.long_element() (3, 2, 1, 0) - sage: S.cayley_graph(side = "left").plot() + sage: S.cayley_graph(side="left").plot() # optional - sage.graphs sage.plot Graphics object consisting of 120 graphics primitives Alternatively, one could have implemented @@ -69,7 +69,7 @@ class SymmetricGroup(UniqueRepresentation, Parent): TESTS:: - sage: TestSuite(S).run() + sage: TestSuite(S).run() # optional - sage.combinat """ def __init__(self, n=4): @@ -135,7 +135,7 @@ def cartan_type(self): EXAMPLES:: - sage: FiniteWeylGroups().example().cartan_type() + sage: FiniteWeylGroups().example().cartan_type() # optional - sage.combinat ['A', 3] relabelled by {1: 0, 2: 1, 3: 2} """ from sage.combinat.root_system.cartan_type import CartanType diff --git a/src/sage/categories/examples/graded_connected_hopf_algebras_with_basis.py b/src/sage/categories/examples/graded_connected_hopf_algebras_with_basis.py index b67e01a4b02..2d2a0f71f4b 100644 --- a/src/sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +++ b/src/sage/categories/examples/graded_connected_hopf_algebras_with_basis.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules r""" Examples of graded connected Hopf algebras with basis """ diff --git a/src/sage/categories/examples/graded_modules_with_basis.py b/src/sage/categories/examples/graded_modules_with_basis.py index 0be39623fa3..86aa957c404 100644 --- a/src/sage/categories/examples/graded_modules_with_basis.py +++ b/src/sage/categories/examples/graded_modules_with_basis.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.combinat r""" Examples of graded modules with basis """ diff --git a/src/sage/categories/examples/hopf_algebras_with_basis.py b/src/sage/categories/examples/hopf_algebras_with_basis.py index 35b61f3c085..265ab46836f 100644 --- a/src/sage/categories/examples/hopf_algebras_with_basis.py +++ b/src/sage/categories/examples/hopf_algebras_with_basis.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules r""" Examples of Hopf algebras with basis """ diff --git a/src/sage/categories/examples/lie_algebras.py b/src/sage/categories/examples/lie_algebras.py index 135a665cfa3..81c7f8457ab 100644 --- a/src/sage/categories/examples/lie_algebras.py +++ b/src/sage/categories/examples/lie_algebras.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules r""" Examples of a Lie algebra """ @@ -68,11 +69,11 @@ def __classcall_private__(cls, gens): EXAMPLES:: - sage: S3 = SymmetricGroupAlgebra(QQ, 3) - sage: L1 = LieAlgebras(QQ).example() - sage: gens = list(S3.algebra_generators()) - sage: L2 = LieAlgebras(QQ).example(gens) - sage: L1 is L2 + sage: S3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat + sage: L1 = LieAlgebras(QQ).example() # optional - sage.combinat + sage: gens = list(S3.algebra_generators()) # optional - sage.combinat + sage: L2 = LieAlgebras(QQ).example(gens) # optional - sage.combinat + sage: L1 is L2 # optional - sage.combinat True """ return super().__classcall__(cls, tuple(gens)) @@ -81,8 +82,8 @@ def __init__(self, gens): """ EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: TestSuite(L).run() + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat + sage: TestSuite(L).run() # optional - sage.combinat """ if not gens: raise ValueError("need at least one generator") @@ -95,7 +96,7 @@ def _repr_(self): """ EXAMPLES:: - sage: LieAlgebras(QQ).example() + sage: LieAlgebras(QQ).example() # optional - sage.combinat sage.groups An example of a Lie algebra: the Lie algebra from the associative algebra Symmetric group algebra of order 3 over Rational Field generated by ([2, 1, 3], [2, 3, 1]) @@ -110,10 +111,10 @@ def _element_constructor_(self, value): EXAMPLES:: - sage: S3 = SymmetricGroupAlgebra(ZZ, 3) - sage: gens = S3.algebra_generators() - sage: L = LieAlgebras(QQ).example() - sage: L(3*gens[0] + gens[1]) + sage: S3 = SymmetricGroupAlgebra(ZZ, 3) # optional - sage.combinat sage.groups + sage: gens = S3.algebra_generators() # optional - sage.combinat sage.groups + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.groups + sage: L(3*gens[0] + gens[1]) # optional - sage.combinat sage.groups 3*[2, 1, 3] + [2, 3, 1] """ return self.element_class(self, self._A(value)) @@ -124,8 +125,8 @@ def zero(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: L.zero() + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.groups + sage: L.zero() # optional - sage.combinat sage.groups 0 """ return self.element_class(self, self._A.zero()) @@ -136,8 +137,8 @@ def lie_algebra_generators(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: L.lie_algebra_generators() + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.groups + sage: L.lie_algebra_generators() # optional - sage.combinat sage.groups Family ([2, 1, 3], [2, 3, 1]) """ return Family([self.element_class(self, g) for g in self._gens]) @@ -157,17 +158,17 @@ def __eq__(self, rhs): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: x,y = L.lie_algebra_generators() - sage: x == x + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.groups + sage: x, y = L.lie_algebra_generators() # optional - sage.combinat sage.groups + sage: x == x # optional - sage.combinat sage.groups True - sage: x.bracket(y) == -y.bracket(x) + sage: x.bracket(y) == -y.bracket(x) # optional - sage.combinat sage.groups True - sage: x == y + sage: x == y # optional - sage.combinat sage.groups False - sage: x.bracket(x) == L.zero() + sage: x.bracket(x) == L.zero() # optional - sage.combinat sage.groups True - sage: x.bracket(x) == 0 + sage: x.bracket(x) == 0 # optional - sage.combinat sage.groups True """ if not isinstance(rhs, LieAlgebraFromAssociative.Element): @@ -180,15 +181,15 @@ def __ne__(self, rhs): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: x,y = L.lie_algebra_generators() - sage: x != y + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.groups + sage: x, y = L.lie_algebra_generators() # optional - sage.combinat sage.groups + sage: x != y # optional - sage.combinat sage.groups True - sage: x != 0 + sage: x != 0 # optional - sage.combinat sage.groups True - sage: x != x + sage: x != x # optional - sage.combinat sage.groups False - sage: x.bracket(y) != -y.bracket(x) + sage: x.bracket(y) != -y.bracket(x) # optional - sage.combinat sage.groups False """ return not self.__eq__(rhs) @@ -199,10 +200,10 @@ def __bool__(self) -> bool: EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: bool(sum(L.lie_algebra_generators())) + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.groups + sage: bool(sum(L.lie_algebra_generators())) # optional - sage.combinat sage.groups True - sage: bool(L.zero()) + sage: bool(L.zero()) # optional - sage.combinat sage.groups False """ return bool(self.value) @@ -213,9 +214,9 @@ def _add_(self, rhs): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: x,y = L.lie_algebra_generators() - sage: x + y + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.groups + sage: x, y = L.lie_algebra_generators() # optional - sage.combinat sage.groups + sage: x + y # optional - sage.combinat sage.groups [2, 1, 3] + [2, 3, 1] """ return self.__class__(self.parent(), self.value + rhs.value) @@ -226,9 +227,9 @@ def _sub_(self, rhs): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: x,y = L.lie_algebra_generators() - sage: x - y + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.groups + sage: x, y = L.lie_algebra_generators() # optional - sage.combinat sage.groups + sage: x - y # optional - sage.combinat sage.groups [2, 1, 3] - [2, 3, 1] """ return self.__class__(self.parent(), self.value - rhs.value) @@ -239,9 +240,9 @@ def _acted_upon_(self, scalar, self_on_left=False): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: x,y = L.lie_algebra_generators() - sage: 3 * x + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.groups + sage: x, y = L.lie_algebra_generators() # optional - sage.combinat sage.groups + sage: 3 * x # optional - sage.combinat sage.groups 3*[2, 1, 3] """ # This was copied, but IDK if it still applies: @@ -265,9 +266,9 @@ def __truediv__(self, x, self_on_left=False): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: x,y = L.lie_algebra_generators() - sage: y / 4 + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.groups + sage: x, y = L.lie_algebra_generators() # optional - sage.combinat sage.groups + sage: y / 4 # optional - sage.combinat sage.groups 1/4*[2, 3, 1] """ if self_on_left: @@ -280,9 +281,9 @@ def __neg__(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: x,y = L.lie_algebra_generators() - sage: -x + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.groups + sage: x, y = L.lie_algebra_generators() # optional - sage.combinat sage.groups + sage: -x # optional - sage.combinat sage.groups -[2, 1, 3] """ return self.__class__(self.parent(), -self.value) @@ -313,15 +314,15 @@ def _bracket_(self, rhs): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: x,y = L.lie_algebra_generators() - sage: elt = 2*x - y - sage: elt.bracket(elt) + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.groups + sage: x,y = L.lie_algebra_generators() # optional - sage.combinat sage.groups + sage: elt = 2*x - y # optional - sage.combinat sage.groups + sage: elt.bracket(elt) # optional - sage.combinat sage.groups 0 - sage: elt.bracket(x) + sage: elt.bracket(x) # optional - sage.combinat sage.groups -[1, 3, 2] + [3, 2, 1] - sage: elt2 = x.bracket(y) + x - sage: elt.bracket(elt2) + sage: elt2 = x.bracket(y) + x # optional - sage.combinat sage.groups + sage: elt.bracket(elt2) # optional - sage.combinat sage.groups -2*[2, 1, 3] + 4*[2, 3, 1] - 4*[3, 1, 2] + 2*[3, 2, 1] """ return self.__class__(self.parent(), self.value * rhs.value - rhs.value * self.value) diff --git a/src/sage/categories/examples/lie_algebras_with_basis.py b/src/sage/categories/examples/lie_algebras_with_basis.py index 484e0eee918..e69711ddf03 100644 --- a/src/sage/categories/examples/lie_algebras_with_basis.py +++ b/src/sage/categories/examples/lie_algebras_with_basis.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules r""" Examples of a Lie algebra with basis """ diff --git a/src/sage/categories/examples/sets_cat.py b/src/sage/categories/examples/sets_cat.py index 19b1ef29ade..6f358929a72 100644 --- a/src/sage/categories/examples/sets_cat.py +++ b/src/sage/categories/examples/sets_cat.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.pari """ Examples of sets """ diff --git a/src/sage/categories/examples/with_realizations.py b/src/sage/categories/examples/with_realizations.py index 7bc940dd289..627bd2a07c3 100644 --- a/src/sage/categories/examples/with_realizations.py +++ b/src/sage/categories/examples/with_realizations.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.modules r""" Examples of parents endowed with multiple realizations """ diff --git a/src/sage/categories/fields.py b/src/sage/categories/fields.py index 4bbbd08ae95..28a93a314b5 100644 --- a/src/sage/categories/fields.py +++ b/src/sage/categories/fields.py @@ -38,7 +38,7 @@ class Fields(CategoryWithAxiom): sage: K(IntegerRing()) Rational Field - sage: K(PolynomialRing(GF(3), 'x')) + sage: K(PolynomialRing(GF(3), 'x')) # optional - sage.rings.finite_rings Fraction Field of Univariate Polynomial Ring in x over Finite Field of size 3 sage: K(RealField()) @@ -64,7 +64,7 @@ def __contains__(self, x): """ EXAMPLES:: - sage: GF(4, "a") in Fields() + sage: GF(4, "a") in Fields() # optional - sage.rings.finite_rings True sage: QQ in Fields() True @@ -81,15 +81,15 @@ def __contains__(self, x): Caveat: this should eventually be fixed:: - sage: gap.Rationals in Fields() + sage: gap.Rationals in Fields() # optional - sage.libs.gap False typically by implementing the method :meth:`category` appropriately for Gap objects:: - sage: GR = gap.Rationals - sage: GR.category = lambda : Fields() - sage: GR in Fields() + sage: GR = gap.Rationals # optional - sage.libs.gap + sage: GR.category = lambda: Fields() # optional - sage.libs.gap + sage: GR in Fields() # optional - sage.libs.gap True The following tests against a memory leak fixed in :trac:`13370`. In order @@ -101,7 +101,7 @@ def __contains__(self, x): sage: _ = gc.collect() sage: permstore = [X for X in gc.get_objects() if isinstance(X, sage.rings.finite_rings.integer_mod_ring.IntegerModRing_generic)] sage: n = len(permstore) - sage: for i in prime_range(100): + sage: for i in prime_range(100): # optional - sage.libs.pari ....: R = ZZ.quotient(i) ....: t = R in Fields() @@ -140,16 +140,16 @@ def _contains_helper(cls): TESTS:: sage: P. = QQ[] - sage: Q = P.quotient(x^2+2) - sage: Q.category() + sage: Q = P.quotient(x^2 + 2) # optional - sage.libs.pari + sage: Q.category() # optional - sage.libs.pari Category of commutative no zero divisors quotients of algebras over (number fields and quotient fields and metric spaces) sage: F = Fields() - sage: F._contains_helper(Q) + sage: F._contains_helper(Q) # optional - sage.libs.pari False - sage: Q in F # This changes the category! + sage: Q in F # This changes the category! # optional - sage.libs.pari True - sage: F._contains_helper(Q) + sage: F._contains_helper(Q) # optional - sage.libs.pari True """ @@ -169,7 +169,7 @@ def _call_(self, x): sage: K(IntegerRing()) # indirect doctest Rational Field - sage: K(PolynomialRing(GF(3), 'x')) # indirect doctest + sage: K(PolynomialRing(GF(3), 'x')) # indirect doctest # optional - sage.rings.finite_rings Fraction Field of Univariate Polynomial Ring in x over Finite Field of size 3 sage: K(RealField()) @@ -207,11 +207,11 @@ def is_integrally_closed(self): sage: QQ.is_integrally_closed() True - sage: QQbar.is_integrally_closed() + sage: QQbar.is_integrally_closed() # optional - sage.rings.number_field True - sage: Z5 = GF(5); Z5 + sage: Z5 = GF(5); Z5 # optional - sage.rings.finite_rings Finite Field of size 5 - sage: Z5.is_integrally_closed() + sage: Z5.is_integrally_closed() # optional - sage.rings.finite_rings True """ return True @@ -231,13 +231,15 @@ def _gcd_univariate_polynomial(self, a, b): EXAMPLES:: - sage: R. = QQbar[] - sage: QQbar._gcd_univariate_polynomial(2*x, 2*x^2) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: QQbar._gcd_univariate_polynomial(2*x, 2*x^2) # optional - sage.rings.number_field x TESTS:: - sage: for A in (RR, CC, QQbar): + sage: fields = [RR, CC] + sage: fields.append(QQbar) # optional - sage.rings.number_field + sage: for A in fields: ....: g = A._gcd_univariate_polynomial ....: R. = A[] ....: z = R.zero() @@ -330,7 +332,9 @@ def _xgcd_univariate_polynomial(self, a, b): TESTS:: - sage: for A in (RR, CC, QQbar): + sage: fields = [RR, CC] + sage: fields.append(QQbar) # optional - sage.rings.number_field + sage: for A in fields: ....: g = A._xgcd_univariate_polynomial ....: R. = A[] ....: z, h = R(0), R(1/2) @@ -388,9 +392,9 @@ def is_perfect(self): sage: QQ.is_perfect() True - sage: GF(2).is_perfect() + sage: GF(2).is_perfect() # optional - sage.rings.finite_rings True - sage: FunctionField(GF(2), 'x').is_perfect() + sage: FunctionField(GF(2), 'x').is_perfect() # optional - sage.rings.finite_rings False """ @@ -464,11 +468,11 @@ def _squarefree_decomposition_univariate_polynomial(self, f): sage: p = 37 * (x-2/3)^2 sage: p.squarefree_decomposition() (37) * (x - 2/3)^2 - sage: x = polygen(GF(3)) - sage: x.squarefree_decomposition() + sage: x = polygen(GF(3)) # optional - sage.rings.finite_rings + sage: x.squarefree_decomposition() # optional - sage.rings.finite_rings x - sage: f = QQbar['x'](1) - sage: f.squarefree_decomposition() + sage: f = QQbar['x'](1) # optional - sage.rings.number_field + sage: f.squarefree_decomposition() # optional - sage.rings.number_field 1 """ from sage.structure.factorization import Factorization @@ -525,10 +529,10 @@ def vector_space(self, *args, **kwds): EXAMPLES:: - sage: K. = Qq(125) # optional - sage.rings.padics - sage: V, fr, to = K.vector_space() # optional - sage.rings.padics - sage: v = V([1, 2, 3]) # optional - sage.rings.padics - sage: fr(v, 7) # optional - sage.rings.padics + sage: K. = Qq(125) # optional - sage.rings.padics + sage: V, fr, to = K.vector_space() # optional - sage.rings.padics + sage: v = V([1, 2, 3]) # optional - sage.rings.padics + sage: fr(v, 7) # optional - sage.rings.padics (3*a^2 + 2*a + 1) + O(5^7) """ return self.free_module(*args, **kwds) @@ -601,12 +605,13 @@ def gcd(self,other): EXAMPLES:: - sage: K = GF(5) - sage: K(2).gcd(K(1)) + sage: K = GF(5) # optional - sage.rings.finite_rings + sage: K(2).gcd(K(1)) # optional - sage.rings.finite_rings 1 - sage: K(0).gcd(K(0)) + sage: K(0).gcd(K(0)) # optional - sage.rings.finite_rings 0 - sage: all(x.gcd(y) == (0 if x == 0 and y == 0 else 1) for x in K for y in K) + sage: all(x.gcd(y) == (0 if x == 0 and y == 0 else 1) # optional - sage.rings.finite_rings + ....: for x in K for y in K) True For field of characteristic zero, the gcd of integers is considered @@ -658,9 +663,9 @@ def lcm(self, other): EXAMPLES:: - sage: GF(2)(1).lcm(GF(2)(0)) + sage: GF(2)(1).lcm(GF(2)(0)) # optional - sage.rings.finite_rings 0 - sage: GF(2)(1).lcm(GF(2)(1)) + sage: GF(2)(1).lcm(GF(2)(1)) # optional - sage.rings.finite_rings 1 For field of characteristic zero, the lcm of integers is considered @@ -721,14 +726,14 @@ def xgcd(self, other): EXAMPLES:: - sage: K = GF(5) - sage: K(2).xgcd(K(1)) + sage: K = GF(5) # optional - sage.rings.finite_rings + sage: K(2).xgcd(K(1)) # optional - sage.rings.finite_rings (1, 3, 0) - sage: K(0).xgcd(K(4)) + sage: K(0).xgcd(K(4)) # optional - sage.rings.finite_rings (1, 0, 4) - sage: K(1).xgcd(K(1)) + sage: K(1).xgcd(K(1)) # optional - sage.rings.finite_rings (1, 1, 0) - sage: GF(5)(0).xgcd(GF(5)(0)) + sage: GF(5)(0).xgcd(GF(5)(0)) # optional - sage.rings.finite_rings (0, 0, 0) The xgcd of non-zero floating point numbers will be a triple of @@ -772,8 +777,8 @@ def factor(self): EXAMPLES:: - sage: x = GF(7)(5) - sage: x.factor() + sage: x = GF(7)(5) # optional - sage.rings.finite_rings + sage: x.factor() # optional - sage.rings.finite_rings 5 sage: RR(0).factor() Traceback (most recent call last): @@ -791,7 +796,8 @@ def inverse_of_unit(self): EXAMPLES:: - sage: NumberField(x^7+2,'a')(2).inverse_of_unit() + sage: x = polygen(ZZ, 'x') + sage: NumberField(x^7+2, 'a')(2).inverse_of_unit() # optional - sage.rings.number_field 1/2 Trying to invert the zero element typically raises a diff --git a/src/sage/categories/filtered_hopf_algebras_with_basis.py b/src/sage/categories/filtered_hopf_algebras_with_basis.py index 08888c78313..ca2dc9ac513 100644 --- a/src/sage/categories/filtered_hopf_algebras_with_basis.py +++ b/src/sage/categories/filtered_hopf_algebras_with_basis.py @@ -88,14 +88,14 @@ def antipode_on_basis(self, index): TESTS:: - sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() - sage: H.monomial(0).antipode() # indirect doctest + sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() # optional - sage.combinat + sage: H.monomial(0).antipode() # indirect doctest # optional - sage.combinat P0 - sage: H.monomial(1).antipode() # indirect doctest + sage: H.monomial(1).antipode() # indirect doctest # optional - sage.combinat -P1 - sage: H.monomial(2).antipode() # indirect doctest + sage: H.monomial(2).antipode() # indirect doctest # optional - sage.combinat P2 - sage: H.monomial(3).antipode() # indirect doctest + sage: H.monomial(3).antipode() # indirect doctest # optional - sage.combinat -P3 """ if self.monomial(index) == self.one(): @@ -116,15 +116,15 @@ def antipode(self, elem): TESTS:: - sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() - sage: H.antipode(H.monomial(14)) + sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() # optional - sage.combinat + sage: H.antipode(H.monomial(14)) # optional - sage.combinat P14 - sage: H.monomial(0).antipode() + sage: H.monomial(0).antipode() # optional - sage.combinat P0 - sage: H.monomial(2).antipode() + sage: H.monomial(2).antipode() # optional - sage.combinat P2 - sage: (2*H.monomial(1) + 3*H.monomial(4)).antipode() + sage: (2*H.monomial(1) + 3*H.monomial(4)).antipode() # optional - sage.combinat -2*P1 + 3*P4 """ return self.linear_combination( diff --git a/src/sage/categories/filtered_modules_with_basis.py b/src/sage/categories/filtered_modules_with_basis.py index 336c1c326c8..7a9b2684f79 100644 --- a/src/sage/categories/filtered_modules_with_basis.py +++ b/src/sage/categories/filtered_modules_with_basis.py @@ -200,8 +200,10 @@ def homogeneous_component_basis(self, d): sage: A = GradedModulesWithBasis(ZZ).example() sage: A.homogeneous_component_basis(4) - Lazy family (Term map from Partitions to An example of a graded module with basis: - the free module on partitions over Integer Ring(i))_{i in Partitions of the integer 4} + Lazy family (Term map + from Partitions + to An example of a graded module with basis: the free module + on partitions over Integer Ring(i))_{i in Partitions of the integer 4} sage: cat = GradedModulesWithBasis(ZZ) sage: C = CombinatorialFreeModule(ZZ, ['a', 'b'], category=cat) @@ -316,12 +318,12 @@ def to_graded_conversion(self): EXAMPLES:: - sage: A = Modules(QQ).WithBasis().Filtered().example() - sage: p = -2 * A.an_element(); p + sage: A = Modules(QQ).WithBasis().Filtered().example() # optional - sage.combinat + sage: p = -2 * A.an_element(); p # optional - sage.combinat -4*P[] - 4*P[1] - 6*P[2] - sage: q = A.to_graded_conversion()(p); q + sage: q = A.to_graded_conversion()(p); q # optional - sage.combinat -4*Bbar[[]] - 4*Bbar[[1]] - 6*Bbar[[2]] - sage: q.parent() is A.graded_algebra() + sage: q.parent() is A.graded_algebra() # optional - sage.combinat True """ base_one = self.base_ring().one() @@ -344,14 +346,14 @@ def from_graded_conversion(self): EXAMPLES:: - sage: A = Modules(QQ).WithBasis().Filtered().example() - sage: p = -2 * A.an_element(); p + sage: A = Modules(QQ).WithBasis().Filtered().example() # optional - sage.combinat + sage: p = -2 * A.an_element(); p # optional - sage.combinat -4*P[] - 4*P[1] - 6*P[2] - sage: q = A.to_graded_conversion()(p); q + sage: q = A.to_graded_conversion()(p); q # optional - sage.combinat -4*Bbar[[]] - 4*Bbar[[1]] - 6*Bbar[[2]] - sage: A.from_graded_conversion()(q) == p + sage: A.from_graded_conversion()(q) == p # optional - sage.combinat True - sage: q.parent() is A.graded_algebra() + sage: q.parent() is A.graded_algebra() # optional - sage.combinat True """ base_one = self.base_ring().one() @@ -376,14 +378,14 @@ def projection(self, i): EXAMPLES:: - sage: A = Modules(ZZ).WithBasis().Filtered().example() - sage: p = -2 * A.an_element(); p + sage: A = Modules(ZZ).WithBasis().Filtered().example() # optional - sage.combinat + sage: p = -2 * A.an_element(); p # optional - sage.combinat -4*P[] - 4*P[1] - 6*P[2] - sage: q = A.projection(2)(p); q + sage: q = A.projection(2)(p); q # optional - sage.combinat -6*Bbar[[2]] - sage: q.parent() is A.graded_algebra() + sage: q.parent() is A.graded_algebra() # optional - sage.combinat True - sage: A.projection(3)(p) + sage: A.projection(3)(p) # optional - sage.combinat 0 """ base_zero = self.base_ring().zero() @@ -437,50 +439,55 @@ def induced_graded_map(self, other, f): We start with the free `\QQ`-module with basis the set of all partitions:: - sage: A = Modules(QQ).WithBasis().Filtered().example(); A + sage: A = Modules(QQ).WithBasis().Filtered().example(); A # optional - sage.combinat An example of a filtered module with basis: the free module on partitions over Rational Field - sage: M = A.indices(); M + sage: M = A.indices(); M # optional - sage.combinat Partitions - sage: p1, p2, p21, p321 = [A.basis()[Partition(i)] for i in [[1], [2], [2,1], [3,2,1]]] + sage: p1, p2, p21, p321 = [A.basis()[Partition(i)] # optional - sage.combinat + ....: for i in [[1], [2], [2,1], [3,2,1]]] Let us define a map from ``A`` to itself which acts on the basis by sending every partition `\lambda` to the sum of the conjugates of all partitions `\mu` for which `\lambda / \mu` is a horizontal strip:: - sage: def map_on_basis(lam): - ....: return A.sum_of_monomials([Partition(mu).conjugate() for k in range(sum(lam) + 1) - ....: for mu in lam.remove_horizontal_border_strip(k)]) - sage: f = A.module_morphism(on_basis=map_on_basis, + sage: def map_on_basis(lam): # optional - sage.combinat + ....: def mus(k): + ....: return lam.remove_horizontal_border_strip(k) + ....: return A.sum_of_monomials([Partition(mu).conjugate() + ....: for k in range(sum(lam) + 1) + ....: for mu in mus(k)]) + sage: f = A.module_morphism(on_basis=map_on_basis, # optional - sage.combinat ....: codomain=A) - sage: f(p1) + sage: f(p1) # optional - sage.combinat P[] + P[1] - sage: f(p2) + sage: f(p2) # optional - sage.combinat P[] + P[1] + P[1, 1] - sage: f(p21) + sage: f(p21) # optional - sage.combinat P[1] + P[1, 1] + P[2] + P[2, 1] - sage: f(p21 - p1) + sage: f(p21 - p1) # optional - sage.combinat -P[] + P[1, 1] + P[2] + P[2, 1] - sage: f(p321) + sage: f(p321) # optional - sage.combinat P[2, 1] + P[2, 1, 1] + P[2, 2] + P[2, 2, 1] + P[3, 1] + P[3, 1, 1] + P[3, 2] + P[3, 2, 1] We now compute `\operatorname{gr} f` :: - sage: grA = A.graded_algebra(); grA + sage: grA = A.graded_algebra(); grA # optional - sage.combinat Graded Module of An example of a filtered module with basis: the free module on partitions over Rational Field - sage: pp1, pp2, pp21, pp321 = [A.to_graded_conversion()(i) for i in [p1, p2, p21, p321]] - sage: pp2 + 4 * pp21 + sage: pp1, pp2, pp21, pp321 = [A.to_graded_conversion()(i) # optional - sage.combinat + ....: for i in [p1, p2, p21, p321]] + sage: pp2 + 4 * pp21 # optional - sage.combinat Bbar[[2]] + 4*Bbar[[2, 1]] - sage: grf = A.induced_graded_map(A, f); grf - Generic endomorphism of Graded Module of An example of a - filtered module with basis: - the free module on partitions over Rational Field - sage: grf(pp1) + sage: grf = A.induced_graded_map(A, f); grf # optional - sage.combinat + Generic endomorphism of Graded Module of + An example of a filtered module with basis: + the free module on partitions over Rational Field + sage: grf(pp1) # optional - sage.combinat Bbar[[1]] - sage: grf(pp2 + 4 * pp21) + sage: grf(pp2 + 4 * pp21) # optional - sage.combinat Bbar[[1, 1]] + 4*Bbar[[2, 1]] **Example 2.** @@ -490,45 +497,48 @@ def induced_graded_map(self, other, f): `f` will lead into a graded algebra already, namely into the algebra of symmetric functions:: - sage: h = SymmetricFunctions(QQ).h() - sage: def map_on_basis(lam): # redefining map_on_basis - ....: return h.sum_of_monomials([Partition(mu).conjugate() for k in range(sum(lam) + 1) - ....: for mu in lam.remove_horizontal_border_strip(k)]) - sage: f = A.module_morphism(on_basis=map_on_basis, + sage: h = SymmetricFunctions(QQ).h() # optional - sage.combinat + sage: def map_on_basis(lam): # redefining map_on_basis # optional - sage.combinat + ....: def mus(k): + ....: return lam.remove_horizontal_border_strip(k) + ....: return h.sum_of_monomials([Partition(mu).conjugate() + ....: for k in range(sum(lam) + 1) + ....: for mu in mus(k)]) + sage: f = A.module_morphism(on_basis=map_on_basis, # optional - sage.combinat ....: codomain=h) # redefining f - sage: f(p1) + sage: f(p1) # optional - sage.combinat h[] + h[1] - sage: f(p2) + sage: f(p2) # optional - sage.combinat h[] + h[1] + h[1, 1] - sage: f(A.zero()) + sage: f(A.zero()) # optional - sage.combinat 0 - sage: f(p2 - 3*p1) + sage: f(p2 - 3*p1) # optional - sage.combinat -2*h[] - 2*h[1] + h[1, 1] The algebra ``h`` of symmetric functions in the `h`-basis is already graded, so its associated graded algebra is implemented as itself:: - sage: grh = h.graded_algebra(); grh is h + sage: grh = h.graded_algebra(); grh is h # optional - sage.combinat True - sage: grf = A.induced_graded_map(h, f); grf + sage: grf = A.induced_graded_map(h, f); grf # optional - sage.combinat Generic morphism: From: Graded Module of An example of a filtered module with basis: the free module on partitions over Rational Field To: Symmetric Functions over Rational Field in the homogeneous basis - sage: grf(pp1) + sage: grf(pp1) # optional - sage.combinat h[1] - sage: grf(pp2) + sage: grf(pp2) # optional - sage.combinat h[1, 1] - sage: grf(pp321) + sage: grf(pp321) # optional - sage.combinat h[3, 2, 1] - sage: grf(pp2 - 3*pp1) + sage: grf(pp2 - 3*pp1) # optional - sage.combinat -3*h[1] + h[1, 1] - sage: grf(pp21) + sage: grf(pp21) # optional - sage.combinat h[2, 1] - sage: grf(grA.zero()) + sage: grf(grA.zero()) # optional - sage.combinat 0 **Example 3.** @@ -537,42 +547,45 @@ def induced_graded_map(self, other, f): have one as the domain instead. Our new ``f`` will go from ``h`` to ``A``:: - sage: def map_on_basis(lam): # redefining map_on_basis - ....: return A.sum_of_monomials([Partition(mu).conjugate() for k in range(sum(lam) + 1) - ....: for mu in lam.remove_horizontal_border_strip(k)]) - sage: f = h.module_morphism(on_basis=map_on_basis, + sage: def map_on_basis(lam): # redefining map_on_basis # optional - sage.combinat + ....: def mus(k): + ....: return lam.remove_horizontal_border_strip(k) + ....: return A.sum_of_monomials([Partition(mu).conjugate() + ....: for k in range(sum(lam) + 1) + ....: for mu in mus(k)]) + sage: f = h.module_morphism(on_basis=map_on_basis, # optional - sage.combinat ....: codomain=A) # redefining f - sage: f(h[1]) + sage: f(h[1]) # optional - sage.combinat P[] + P[1] - sage: f(h[2]) + sage: f(h[2]) # optional - sage.combinat P[] + P[1] + P[1, 1] - sage: f(h[1, 1]) + sage: f(h[1, 1]) # optional - sage.combinat P[1] + P[2] - sage: f(h[2, 2]) + sage: f(h[2, 2]) # optional - sage.combinat P[1, 1] + P[2, 1] + P[2, 2] - sage: f(h[3, 2, 1]) + sage: f(h[3, 2, 1]) # optional - sage.combinat P[2, 1] + P[2, 1, 1] + P[2, 2] + P[2, 2, 1] + P[3, 1] + P[3, 1, 1] + P[3, 2] + P[3, 2, 1] - sage: f(h.one()) + sage: f(h.one()) # optional - sage.combinat P[] - sage: grf = h.induced_graded_map(A, f); grf + sage: grf = h.induced_graded_map(A, f); grf # optional - sage.combinat Generic morphism: From: Symmetric Functions over Rational Field in the homogeneous basis To: Graded Module of An example of a filtered module with basis: the free module on partitions over Rational Field - sage: grf(h[1]) + sage: grf(h[1]) # optional - sage.combinat Bbar[[1]] - sage: grf(h[2]) + sage: grf(h[2]) # optional - sage.combinat Bbar[[1, 1]] - sage: grf(h[1, 1]) + sage: grf(h[1, 1]) # optional - sage.combinat Bbar[[2]] - sage: grf(h[2, 2]) + sage: grf(h[2, 2]) # optional - sage.combinat Bbar[[2, 2]] - sage: grf(h[3, 2, 1]) + sage: grf(h[3, 2, 1]) # optional - sage.combinat Bbar[[3, 2, 1]] - sage: grf(h.one()) + sage: grf(h.one()) # optional - sage.combinat Bbar[[]] **Example 4.** @@ -580,33 +593,36 @@ def induced_graded_map(self, other, f): The construct `\operatorname{gr} f` also makes sense when `f` is a filtration-preserving map between graded modules. :: - sage: def map_on_basis(lam): # redefining map_on_basis - ....: return h.sum_of_monomials([Partition(mu).conjugate() for k in range(sum(lam) + 1) - ....: for mu in lam.remove_horizontal_border_strip(k)]) - sage: f = h.module_morphism(on_basis=map_on_basis, + sage: def map_on_basis(lam): # redefining map_on_basis # optional - sage.combinat + ....: def mus(k): + ....: return lam.remove_horizontal_border_strip(k) + ....: return h.sum_of_monomials([Partition(mu).conjugate() + ....: for k in range(sum(lam) + 1) + ....: for mu in mus(k)]) + sage: f = h.module_morphism(on_basis=map_on_basis, # optional - sage.combinat ....: codomain=h) # redefining f - sage: f(h[1]) + sage: f(h[1]) # optional - sage.combinat h[] + h[1] - sage: f(h[2]) + sage: f(h[2]) # optional - sage.combinat h[] + h[1] + h[1, 1] - sage: f(h[1, 1]) + sage: f(h[1, 1]) # optional - sage.combinat h[1] + h[2] - sage: f(h[2, 1]) + sage: f(h[2, 1]) # optional - sage.combinat h[1] + h[1, 1] + h[2] + h[2, 1] - sage: f(h.one()) + sage: f(h.one()) # optional - sage.combinat h[] - sage: grf = h.induced_graded_map(h, f); grf - Generic endomorphism of Symmetric Functions over Rational - Field in the homogeneous basis - sage: grf(h[1]) + sage: grf = h.induced_graded_map(h, f); grf # optional - sage.combinat + Generic endomorphism of + Symmetric Functions over Rational Field in the homogeneous basis + sage: grf(h[1]) # optional - sage.combinat h[1] - sage: grf(h[2]) + sage: grf(h[2]) # optional - sage.combinat h[1, 1] - sage: grf(h[1, 1]) + sage: grf(h[1, 1]) # optional - sage.combinat h[2] - sage: grf(h[2, 1]) + sage: grf(h[2, 1]) # optional - sage.combinat h[2, 1] - sage: grf(h.one()) + sage: grf(h.one()) # optional - sage.combinat h[] """ grA = self.graded_algebra() @@ -643,26 +659,26 @@ def is_homogeneous(self): EXAMPLES:: - sage: A = ModulesWithBasis(ZZ).Filtered().example() - sage: x = A(Partition((3,2,1))) - sage: y = A(Partition((4,4,1))) - sage: z = A(Partition((2,2,2))) - sage: (3*x).is_homogeneous() + sage: A = ModulesWithBasis(ZZ).Filtered().example() # optional - sage.combinat + sage: x = A(Partition((3,2,1))) # optional - sage.combinat + sage: y = A(Partition((4,4,1))) # optional - sage.combinat + sage: z = A(Partition((2,2,2))) # optional - sage.combinat + sage: (3*x).is_homogeneous() # optional - sage.combinat True - sage: (x - y).is_homogeneous() + sage: (x - y).is_homogeneous() # optional - sage.combinat False - sage: (x+2*z).is_homogeneous() + sage: (x+2*z).is_homogeneous() # optional - sage.combinat True Here is an example with a graded algebra:: - sage: S = NonCommutativeSymmetricFunctions(QQ).S() - sage: (x, y) = (S[2], S[3]) - sage: (3*x).is_homogeneous() + sage: S = NonCommutativeSymmetricFunctions(QQ).S() # optional - sage.combinat + sage: (x, y) = (S[2], S[3]) # optional - sage.combinat + sage: (3*x).is_homogeneous() # optional - sage.combinat True - sage: (x^3 - y^2).is_homogeneous() + sage: (x^3 - y^2).is_homogeneous() # optional - sage.combinat True - sage: ((x + y)^2).is_homogeneous() + sage: ((x + y)^2).is_homogeneous() # optional - sage.combinat False Let us now test a filtered algebra (but remember that the @@ -701,10 +717,10 @@ def degree_on_basis(self, m): EXAMPLES:: - sage: A = GradedModulesWithBasis(QQ).example() - sage: A.degree_on_basis(Partition((2,1))) + sage: A = GradedModulesWithBasis(QQ).example() # optional - sage.combinat sage.modules + sage: A.degree_on_basis(Partition((2,1))) # optional - sage.combinat sage.modules 3 - sage: A.degree_on_basis(Partition((4,2,1,1,1,1))) + sage: A.degree_on_basis(Partition((4,2,1,1,1,1))) # optional - sage.combinat sage.modules 10 """ @@ -722,28 +738,28 @@ def homogeneous_degree(self): EXAMPLES:: - sage: A = ModulesWithBasis(ZZ).Filtered().example() - sage: x = A(Partition((3,2,1))) - sage: y = A(Partition((4,4,1))) - sage: z = A(Partition((2,2,2))) - sage: x.degree() + sage: A = ModulesWithBasis(ZZ).Filtered().example() # optional - sage.combinat sage.modules + sage: x = A(Partition((3,2,1))) # optional - sage.combinat sage.modules + sage: y = A(Partition((4,4,1))) # optional - sage.combinat sage.modules + sage: z = A(Partition((2,2,2))) # optional - sage.combinat sage.modules + sage: x.degree() # optional - sage.combinat sage.modules 6 - sage: (x + 2*z).degree() + sage: (x + 2*z).degree() # optional - sage.combinat sage.modules 6 - sage: (y - x).degree() + sage: (y - x).degree() # optional - sage.combinat sage.modules Traceback (most recent call last): ... ValueError: element is not homogeneous An example in a graded algebra:: - sage: S = NonCommutativeSymmetricFunctions(QQ).S() - sage: (x, y) = (S[2], S[3]) - sage: x.homogeneous_degree() + sage: S = NonCommutativeSymmetricFunctions(QQ).S() # optional - sage.combinat sage.modules + sage: (x, y) = (S[2], S[3]) # optional - sage.combinat sage.modules + sage: x.homogeneous_degree() # optional - sage.combinat sage.modules 2 - sage: (x^3 + 4*y^2).homogeneous_degree() + sage: (x^3 + 4*y^2).homogeneous_degree() # optional - sage.combinat sage.modules 6 - sage: ((1 + x)^3).homogeneous_degree() + sage: ((1 + x)^3).homogeneous_degree() # optional - sage.combinat sage.modules Traceback (most recent call last): ... ValueError: element is not homogeneous @@ -765,8 +781,8 @@ def homogeneous_degree(self): TESTS:: - sage: S = NonCommutativeSymmetricFunctions(QQ).S() - sage: S.zero().degree() + sage: S = NonCommutativeSymmetricFunctions(QQ).S() # optional - sage.combinat sage.modules + sage: S.zero().degree() # optional - sage.combinat sage.modules Traceback (most recent call last): ... ValueError: the zero element does not have a well-defined degree @@ -793,28 +809,28 @@ def maximal_degree(self): EXAMPLES:: - sage: A = ModulesWithBasis(ZZ).Filtered().example() - sage: x = A(Partition((3,2,1))) - sage: y = A(Partition((4,4,1))) - sage: z = A(Partition((2,2,2))) - sage: x.maximal_degree() + sage: A = ModulesWithBasis(ZZ).Filtered().example() # optional - sage.combinat + sage: x = A(Partition((3,2,1))) # optional - sage.combinat + sage: y = A(Partition((4,4,1))) # optional - sage.combinat + sage: z = A(Partition((2,2,2))) # optional - sage.combinat + sage: x.maximal_degree() # optional - sage.combinat 6 - sage: (x + 2*z).maximal_degree() + sage: (x + 2*z).maximal_degree() # optional - sage.combinat 6 - sage: (y - x).maximal_degree() + sage: (y - x).maximal_degree() # optional - sage.combinat 9 - sage: (3*z).maximal_degree() + sage: (3*z).maximal_degree() # optional - sage.combinat 6 Now, we test this on a graded algebra:: - sage: S = NonCommutativeSymmetricFunctions(QQ).S() - sage: (x, y) = (S[2], S[3]) - sage: x.maximal_degree() + sage: S = NonCommutativeSymmetricFunctions(QQ).S() # optional - sage.combinat + sage: (x, y) = (S[2], S[3]) # optional - sage.combinat + sage: x.maximal_degree() # optional - sage.combinat 2 - sage: (x^3 + 4*y^2).maximal_degree() + sage: (x^3 + 4*y^2).maximal_degree() # optional - sage.combinat 6 - sage: ((1 + x)^3).maximal_degree() + sage: ((1 + x)^3).maximal_degree() # optional - sage.combinat 6 Let us now test a filtered algebra:: @@ -836,8 +852,8 @@ def maximal_degree(self): TESTS:: - sage: S = NonCommutativeSymmetricFunctions(QQ).S() - sage: S.zero().degree() + sage: S = NonCommutativeSymmetricFunctions(QQ).S() # optional - sage.combinat + sage: S.zero().degree() # optional - sage.combinat Traceback (most recent call last): ... ValueError: the zero element does not have a well-defined degree @@ -998,16 +1014,16 @@ def degree_on_basis(self, m): EXAMPLES:: - sage: E. = ExteriorAlgebra(QQ) - sage: S = E.submodule([x + y, x*y - y*z, y]) - sage: B = S.basis() - sage: [B[0].lift(), B[1].lift(), B[2].lift()] + sage: E. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: S = E.submodule([x + y, x*y - y*z, y]) # optional - sage.combinat sage.modules + sage: B = S.basis() # optional - sage.combinat sage.modules + sage: [B[0].lift(), B[1].lift(), B[2].lift()] # optional - sage.combinat sage.modules [x, y, x*y - y*z] - sage: S.degree_on_basis(0) + sage: S.degree_on_basis(0) # optional - sage.combinat sage.modules 1 - sage: S.degree_on_basis(1) + sage: S.degree_on_basis(1) # optional - sage.combinat sage.modules 1 - sage: S.degree_on_basis(2) + sage: S.degree_on_basis(2) # optional - sage.combinat sage.modules 2 """ return self.basis()[m].lift().degree() @@ -1019,29 +1035,29 @@ def degree(self): EXAMPLES:: - sage: E. = ExteriorAlgebra(QQ) - sage: S = E.submodule([x + y, x*y - y*z, y]) - sage: B = S.basis() - sage: [B[0].lift(), B[1].lift(), B[2].lift()] + sage: E. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: S = E.submodule([x + y, x*y - y*z, y]) # optional - sage.combinat sage.modules + sage: B = S.basis() # optional - sage.combinat sage.modules + sage: [B[0].lift(), B[1].lift(), B[2].lift()] # optional - sage.combinat sage.modules [x, y, x*y - y*z] - sage: B[0].degree() + sage: B[0].degree() # optional - sage.combinat sage.modules 1 - sage: B[1].degree() + sage: B[1].degree() # optional - sage.combinat sage.modules 1 - sage: (B[0] + 3*B[1]).degree() + sage: (B[0] + 3*B[1]).degree() # optional - sage.combinat sage.modules 1 The degree of inhomogeneous elements is not defined (following the behavior of the exterior algebra):: - sage: (B[0] + B[2]).degree() + sage: (B[0] + B[2]).degree() # optional - sage.combinat sage.modules Traceback (most recent call last): ... ValueError: element is not homogeneous We can still get the maximal degree:: - sage: (B[0] + B[2]).maximal_degree() + sage: (B[0] + B[2]).maximal_degree() # optional - sage.combinat sage.modules 2 """ return self.lift().degree() @@ -1059,14 +1075,14 @@ def maximal_degree(self): EXAMPLES:: - sage: E. = ExteriorAlgebra(QQ) - sage: F = E.submodule([x + 1, x*y - 1]) - sage: B = F.basis() - sage: [B[0].lift(), B[1].lift()] + sage: E. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: F = E.submodule([x + 1, x*y - 1]) # optional - sage.combinat sage.modules + sage: B = F.basis() # optional - sage.combinat sage.modules + sage: [B[0].lift(), B[1].lift()] # optional - sage.combinat sage.modules [-x*y + 1, x*y + x] - sage: B[0].maximal_degree() + sage: B[0].maximal_degree() # optional - sage.combinat sage.modules 2 - sage: B[1].maximal_degree() + sage: B[1].maximal_degree() # optional - sage.combinat sage.modules 2 """ return self.lift().maximal_degree() diff --git a/src/sage/categories/finite_complex_reflection_groups.py b/src/sage/categories/finite_complex_reflection_groups.py index 8648f89dbc4..f4ab8a943ce 100644 --- a/src/sage/categories/finite_complex_reflection_groups.py +++ b/src/sage/categories/finite_complex_reflection_groups.py @@ -56,7 +56,7 @@ class FiniteComplexReflectionGroups(CategoryWithAxiom): sage: W = ComplexReflectionGroups().Finite().example(); W # optional - gap3 Reducible real reflection group of rank 4 and type A2 x B2 - sage: W.reflections() # optional - gap3 + sage: W.reflections() # optional - gap3 Finite family {1: (1,8)(2,5)(9,12), 2: (1,5)(2,9)(8,12), 3: (3,10)(4,7)(11,14), 4: (3,6)(4,11)(10,13), 5: (1,9)(2,8)(5,12), 6: (4,14)(6,13)(7,11), @@ -64,7 +64,7 @@ class FiniteComplexReflectionGroups(CategoryWithAxiom): ``W`` is in the category of complex reflection groups:: - sage: W in ComplexReflectionGroups().Finite() # optional - gap3 + sage: W in ComplexReflectionGroups().Finite() # optional - gap3 True """ def example(self): @@ -104,14 +104,14 @@ def WellGenerated(self): Here is an example of a finite well-generated complex reflection group:: - sage: W = C.example(); W # optional - gap3 + sage: W = C.example(); W # optional - gap3 Reducible complex reflection group of rank 4 and type A2 x G(3,1,2) All finite Coxeter groups are well generated:: sage: CoxeterGroups().Finite().is_subcategory(C) True - sage: SymmetricGroup(3) in C + sage: SymmetricGroup(3) in C # optional - sage.groups True .. NOTE:: @@ -124,8 +124,9 @@ def WellGenerated(self): TESTS:: - sage: TestSuite(W).run() # optional - gap3 - sage: TestSuite(ComplexReflectionGroups().Finite().WellGenerated()).run() # optional - gap3 + sage: TestSuite(W).run() # optional - gap3 + sage: C = ComplexReflectionGroups().Finite().WellGenerated() + sage: TestSuite(C).run() # optional - gap3 sage: CoxeterGroups().Finite().WellGenerated.__module__ 'sage.categories.finite_complex_reflection_groups' @@ -148,12 +149,12 @@ def degrees(self): EXAMPLES:: - sage: W = ColoredPermutations(1,4) - sage: W.degrees() + sage: W = ColoredPermutations(1,4) # optional - sage.combinat sage.groups + sage: W.degrees() # optional - sage.combinat sage.groups (2, 3, 4) - sage: W = ColoredPermutations(3,3) - sage: W.degrees() + sage: W = ColoredPermutations(3,3) # optional - sage.combinat sage.groups + sage: W.degrees() # optional - sage.combinat sage.groups (3, 6, 9) sage: W = ReflectionGroup(31) # optional - gap3 @@ -170,12 +171,12 @@ def codegrees(self): EXAMPLES:: - sage: W = ColoredPermutations(1,4) - sage: W.codegrees() + sage: W = ColoredPermutations(1,4) # optional - sage.combinat sage.groups + sage: W.codegrees() # optional - sage.combinat sage.groups (2, 1, 0) - sage: W = ColoredPermutations(3,3) - sage: W.codegrees() + sage: W = ColoredPermutations(3,3) # optional - sage.combinat sage.groups + sage: W.codegrees() # optional - sage.combinat sage.groups (6, 3, 0) sage: W = ReflectionGroup(31) # optional - gap3 @@ -198,27 +199,27 @@ def _test_degrees(self, **options): Reducible real reflection group of rank 4 and type A2 x B2 sage: W._test_degrees() # optional - gap3 - sage: W = SymmetricGroup(5) - sage: W._test_degrees() + sage: W = SymmetricGroup(5) # optional - sage.groups + sage: W._test_degrees() # optional - sage.groups We now break the implementation of W.degrees and check that this is caught:: - sage: W.degrees = lambda: (1/1,5) - sage: W._test_degrees() + sage: W.degrees = lambda: (1/1,5) # optional - sage.groups + sage: W._test_degrees() # optional - sage.groups Traceback (most recent call last): ... AssertionError: the degrees should be integers - sage: W.degrees = lambda: (1,2,3) - sage: W._test_degrees() + sage: W.degrees = lambda: (1,2,3) # optional - sage.groups + sage: W._test_degrees() # optional - sage.groups Traceback (most recent call last): ... AssertionError: the degrees should be larger than 2 We restore W to its normal state:: - sage: del W.degrees - sage: W._test_degrees() + sage: del W.degrees # optional - sage.groups + sage: W._test_degrees() # optional - sage.groups See the documentation for :class:`TestSuite` for more information. """ @@ -253,27 +254,27 @@ def _test_codegrees(self, **options): Reducible real reflection group of rank 4 and type A2 x B2 sage: W._test_codegrees() # optional - gap3 - sage: W = SymmetricGroup(5) - sage: W._test_codegrees() + sage: W = SymmetricGroup(5) # optional - sage.groups + sage: W._test_codegrees() # optional - sage.groups We now break the implementation of W.degrees and check that this is caught:: - sage: W.codegrees = lambda: (1/1,5) - sage: W._test_codegrees() + sage: W.codegrees = lambda: (1/1,5) # optional - sage.groups + sage: W._test_codegrees() # optional - sage.groups Traceback (most recent call last): ... AssertionError: the codegrees should be integers - sage: W.codegrees = lambda: (2,1,-1) - sage: W._test_codegrees() + sage: W.codegrees = lambda: (2,1,-1) # optional - sage.groups + sage: W._test_codegrees() # optional - sage.groups Traceback (most recent call last): ... AssertionError: the codegrees should be nonnegative We restore W to its normal state:: - sage: del W.codegrees - sage: W._test_codegrees() + sage: del W.codegrees # optional - sage.groups + sage: W._test_codegrees() # optional - sage.groups See the documentation for :class:`TestSuite` for more information. """ @@ -310,14 +311,14 @@ def number_of_reflection_hyperplanes(self): EXAMPLES:: - sage: W = ColoredPermutations(1,3) - sage: W.number_of_reflection_hyperplanes() + sage: W = ColoredPermutations(1,3) # optional - sage.combinat sage.groups + sage: W.number_of_reflection_hyperplanes() # optional - sage.combinat sage.groups 3 - sage: W = ColoredPermutations(2,3) - sage: W.number_of_reflection_hyperplanes() + sage: W = ColoredPermutations(2,3) # optional - sage.combinat sage.groups + sage: W.number_of_reflection_hyperplanes() # optional - sage.combinat sage.groups 9 - sage: W = ColoredPermutations(4,3) - sage: W.number_of_reflection_hyperplanes() + sage: W = ColoredPermutations(4,3) # optional - sage.combinat sage.groups + sage: W.number_of_reflection_hyperplanes() # optional - sage.combinat sage.groups 15 sage: W = ReflectionGroup((4,2,3)) # optional - gap3 sage: W.number_of_reflection_hyperplanes() # optional - gap3 @@ -341,20 +342,21 @@ def number_of_reflections(self): EXAMPLES:: - sage: [SymmetricGroup(i).number_of_reflections() for i in range(int(8))] + sage: [SymmetricGroup(i).number_of_reflections() # optional - sage.groups + ....: for i in range(int(8))] [0, 0, 1, 3, 6, 10, 15, 21] - sage: W = ColoredPermutations(1,3) - sage: W.number_of_reflections() + sage: W = ColoredPermutations(1,3) # optional - sage.combinat sage.groups + sage: W.number_of_reflections() # optional - sage.combinat sage.groups 3 - sage: W = ColoredPermutations(2,3) - sage: W.number_of_reflections() + sage: W = ColoredPermutations(2,3) # optional - sage.combinat sage.groups + sage: W.number_of_reflections() # optional - sage.combinat sage.groups 9 - sage: W = ColoredPermutations(4,3) - sage: W.number_of_reflections() + sage: W = ColoredPermutations(4,3) # optional - sage.combinat sage.groups + sage: W.number_of_reflections() # optional - sage.combinat sage.groups 21 - sage: W = ReflectionGroup((4,2,3)) # optional - gap3 - sage: W.number_of_reflections() # optional - gap3 + sage: W = ReflectionGroup((4,2,3)) # optional - gap3 # optional - sage.combinat sage.groups + sage: W.number_of_reflections() # optional - gap3 # optional - sage.combinat sage.groups 15 """ from sage.rings.integer_ring import ZZ @@ -375,17 +377,17 @@ def rank(self): EXAMPLES:: - sage: W = ColoredPermutations(1,3) - sage: W.rank() + sage: W = ColoredPermutations(1,3) # optional - sage.combinat sage.groups + sage: W.rank() # optional - sage.combinat sage.groups 2 - sage: W = ColoredPermutations(2,3) - sage: W.rank() + sage: W = ColoredPermutations(2,3) # optional - sage.combinat sage.groups + sage: W.rank() # optional - sage.combinat sage.groups 3 - sage: W = ColoredPermutations(4,3) - sage: W.rank() + sage: W = ColoredPermutations(4,3) # optional - sage.combinat sage.groups + sage: W.rank() # optional - sage.combinat sage.groups 3 - sage: W = ReflectionGroup((4,2,3)) # optional - gap3 - sage: W.rank() # optional - gap3 + sage: W = ReflectionGroup((4,2,3)) # optional - gap3 # optional - sage.combinat sage.groups + sage: W.rank() # optional - gap3 # optional - sage.combinat sage.groups 3 """ return len(self.degrees()) @@ -399,17 +401,17 @@ def cardinality(self): EXAMPLES:: - sage: W = ColoredPermutations(1,3) - sage: W.cardinality() + sage: W = ColoredPermutations(1,3) # optional - sage.combinat sage.groups + sage: W.cardinality() # optional - sage.combinat sage.groups 6 - sage: W = ColoredPermutations(2,3) - sage: W.cardinality() + sage: W = ColoredPermutations(2,3) # optional - sage.combinat sage.groups + sage: W.cardinality() # optional - sage.combinat sage.groups 48 - sage: W = ColoredPermutations(4,3) - sage: W.cardinality() + sage: W = ColoredPermutations(4,3) # optional - sage.combinat sage.groups + sage: W.cardinality() # optional - sage.combinat sage.groups 384 - sage: W = ReflectionGroup((4,2,3)) # optional - gap3 - sage: W.cardinality() # optional - gap3 + sage: W = ReflectionGroup((4,2,3)) # optional - gap3 # optional - sage.combinat sage.groups + sage: W.cardinality() # optional - gap3 # optional - sage.combinat sage.groups 192 """ from sage.rings.integer_ring import ZZ @@ -437,20 +439,20 @@ def is_well_generated(self): EXAMPLES:: - sage: W = ColoredPermutations(1,3) - sage: W.is_well_generated() + sage: W = ColoredPermutations(1,3) # optional - sage.combinat sage.groups + sage: W.is_well_generated() # optional - sage.combinat sage.groups True - sage: W = ColoredPermutations(4,3) - sage: W.is_well_generated() + sage: W = ColoredPermutations(4,3) # optional - sage.combinat sage.groups + sage: W.is_well_generated() # optional - sage.combinat sage.groups True - sage: W = ReflectionGroup((4,2,3)) # optional - gap3 - sage: W.is_well_generated() # optional - gap3 + sage: W = ReflectionGroup((4,2,3)) # optional - gap3 # optional - sage.combinat sage.groups + sage: W.is_well_generated() # optional - gap3 # optional - sage.combinat sage.groups False - sage: W = ReflectionGroup((4,4,3)) # optional - gap3 - sage: W.is_well_generated() # optional - gap3 + sage: W = ReflectionGroup((4,4,3)) # optional - gap3 # optional - sage.combinat sage.groups + sage: W.is_well_generated() # optional - gap3 # optional - sage.combinat sage.groups True """ return self.number_of_simple_reflections() == self.rank() @@ -472,12 +474,12 @@ def is_real(self): EXAMPLES:: - sage: W = ColoredPermutations(1,3) - sage: W.is_real() + sage: W = ColoredPermutations(1,3) # optional - sage.combinat sage.groups + sage: W.is_real() # optional - sage.combinat sage.groups True - sage: W = ColoredPermutations(4,3) - sage: W.is_real() + sage: W = ColoredPermutations(4,3) # optional - sage.combinat sage.groups + sage: W.is_real() # optional - sage.combinat sage.groups False .. TODO:: @@ -501,24 +503,24 @@ def base_change_matrix(self): EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: W.base_change_matrix() # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) # optional - gap3 + sage: W.base_change_matrix() # optional - gap3 [1 0] [0 1] - sage: W = ReflectionGroup(23) # optional - gap3 - sage: W.base_change_matrix() # optional - gap3 + sage: W = ReflectionGroup(23) # optional - gap3 + sage: W.base_change_matrix() # optional - gap3 [1 0 0] [0 1 0] [0 0 1] - sage: W = ReflectionGroup((3,1,2)) # optional - gap3 - sage: W.base_change_matrix() # optional - gap3 + sage: W = ReflectionGroup((3,1,2)) # optional - gap3 + sage: W.base_change_matrix() # optional - gap3 [1 0] [1 1] - sage: W = ReflectionGroup((4,2,2)) # optional - gap3 - sage: W.base_change_matrix() # optional - gap3 + sage: W = ReflectionGroup((4,2,2)) # optional - gap3 + sage: W.base_change_matrix() # optional - gap3 [ 1 0] [E(4) 1] """ @@ -542,8 +544,8 @@ def to_matrix(self): [0 1], [ 0 -1], [ 1 1], [ 1 0], [-1 -1], [-1 0] ] - sage: W = ColoredPermutations(1,3) - sage: [t.to_matrix() for t in W] + sage: W = ColoredPermutations(1,3) # optional - sage.combinat sage.groups + sage: [t.to_matrix() for t in W] # optional - sage.combinat sage.groups [ [1 0 0] [1 0 0] [0 1 0] [0 0 1] [0 1 0] [0 0 1] [0 1 0] [0 0 1] [1 0 0] [1 0 0] [0 0 1] [0 1 0] @@ -553,8 +555,8 @@ def to_matrix(self): A different representation is given by the colored permutations:: - sage: W = ColoredPermutations(3, 1) - sage: [t.to_matrix() for t in W] + sage: W = ColoredPermutations(3, 1) # optional - sage.combinat sage.groups + sage: [t.to_matrix() for t in W] # optional - sage.combinat sage.groups [[1], [zeta3], [-zeta3 - 1]] """ @@ -580,9 +582,9 @@ def character_value(self): EXAMPLES:: - sage: W = ColoredPermutations(1,3); W + sage: W = ColoredPermutations(1,3); W # optional - sage.combinat sage.groups 1-colored permutations of size 3 - sage: [t.character_value() for t in W] + sage: [t.character_value() for t in W] # optional - sage.combinat sage.groups [3, 1, 1, 0, 0, 1] Note that this could be a different (faithful) @@ -594,14 +596,14 @@ def character_value(self): sage: [t.character_value() for t in W] # optional - gap3 [2, 0, 0, -1, -1, 0] - sage: W = ColoredPermutations(2,2); W + sage: W = ColoredPermutations(2,2); W # optional - sage.combinat sage.groups 2-colored permutations of size 2 - sage: [t.character_value() for t in W] + sage: [t.character_value() for t in W] # optional - sage.combinat sage.groups [2, 0, 0, -2, 0, 0, 0, 0] - sage: W = ColoredPermutations(3,1); W + sage: W = ColoredPermutations(3,1); W # optional - sage.combinat sage.groups 3-colored permutations of size 1 - sage: [t.character_value() for t in W] + sage: [t.character_value() for t in W] # optional - sage.combinat sage.groups [1, zeta3, -zeta3 - 1] """ return self.to_matrix().trace() @@ -622,20 +624,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)) # optional - gap3 + sage: sorted([t.reflection_length() for t in W]) # optional - gap3 [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)) # optional - gap3 + sage: sorted([t.reflection_length() for t in W]) # optional - gap3 [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)) # optional - gap3 + sage: sorted([t.reflection_length() for t in W]) # optional - gap3 [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)) # optional - gap3 + sage: sorted([t.reflection_length() for t in W]) # optional - gap3 [0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] """ W = self.parent() @@ -655,7 +657,8 @@ def example(self): EXAMPLES:: sage: from sage.categories.complex_reflection_groups import ComplexReflectionGroups - sage: ComplexReflectionGroups().Finite().Irreducible().example() # optional - gap3 + sage: C = ComplexReflectionGroups().Finite().Irreducible() + sage: C.example() # optional - gap3 Irreducible complex reflection group of rank 3 and type G(4,2,3) """ from sage.combinat.root_system.reflection_group_real import ReflectionGroup @@ -733,23 +736,26 @@ def absolute_order_ideal(self, gens=None, EXAMPLES:: - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: sorted( w.reduced_word() for w in W.absolute_order_ideal() ) # optional - gap3 + sage: sorted(w.reduced_word() # optional - gap3 + ....: for w in W.absolute_order_ideal()) [[], [1], [1, 2], [1, 2, 1], [2]] - sage: sorted( w.reduced_word() for w in W.absolute_order_ideal(W.from_reduced_word([2,1])) ) # optional - gap3 + sage: sorted(w.reduced_word() # optional - gap3 + ....: for w in W.absolute_order_ideal(W.from_reduced_word([2,1]))) [[], [1], [1, 2, 1], [2], [2, 1]] - sage: sorted( w.reduced_word() for w in W.absolute_order_ideal(W.from_reduced_word([2])) ) # optional - gap3 + sage: sorted(w.reduced_word() # optional - gap3 + ....: for w in W.absolute_order_ideal(W.from_reduced_word([2]))) [[], [2]] - sage: W = CoxeterGroup(['A', 3]) - sage: len(list(W.absolute_order_ideal())) + sage: W = CoxeterGroup(['A', 3]) # optional - sage.combinat sage.groups + sage: len(list(W.absolute_order_ideal())) # optional - sage.combinat sage.groups 14 - sage: W = CoxeterGroup(['A', 2]) - sage: for (w, l) in W.absolute_order_ideal(return_lengths=True): + sage: W = CoxeterGroup(['A', 2]) # optional - sage.combinat sage.groups + sage: for (w, l) in W.absolute_order_ideal(return_lengths=True): # optional - sage.combinat sage.groups ....: print(w.reduced_word(), l) [1, 2] 2 [1, 2, 1] 1 @@ -793,9 +799,10 @@ def elements_below_coxeter_element(self, c=None): TESTS:: - sage: W = CoxeterGroup(['A', 3]) - sage: len(list(W.elements_below_coxeter_element())) - doctest:...: DeprecationWarning: The method elements_below_coxeter_element is deprecated. Please use absolute_order_ideal instead. + sage: W = CoxeterGroup(['A', 3]) # optional - sage.combinat sage.groups + sage: len(list(W.elements_below_coxeter_element())) # optional - sage.combinat sage.groups + doctest:...: DeprecationWarning: The method elements_below_coxeter_element + is deprecated. Please use absolute_order_ideal instead. See https://github.com/sagemath/sage/issues/27924 for details. 14 """ @@ -835,23 +842,28 @@ def noncrossing_partition_lattice(self, c=None, L=None, EXAMPLES:: - sage: W = SymmetricGroup(4) - sage: W.noncrossing_partition_lattice() + sage: W = SymmetricGroup(4) # optional - sage.combinat sage.groups + sage: W.noncrossing_partition_lattice() # optional - sage.combinat sage.groups Finite lattice containing 14 elements - sage: W = WeylGroup(['G', 2]) - sage: W.noncrossing_partition_lattice() + sage: W = WeylGroup(['G', 2]) # optional - sage.combinat sage.groups + sage: W.noncrossing_partition_lattice() # optional - sage.combinat sage.groups Finite lattice containing 8 elements - sage: W = ReflectionGroup((1,1,3)) # optional - gap3 + sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: sorted( w.reduced_word() for w in W.noncrossing_partition_lattice() ) # optional - gap3 + sage: sorted(w.reduced_word() # optional - gap3 + ....: for w in W.noncrossing_partition_lattice()) [[], [1], [1, 2], [1, 2, 1], [2]] - sage: sorted( w.reduced_word() for w in W.noncrossing_partition_lattice(W.from_reduced_word([2,1])) ) # optional - gap3 + sage: c21 = W.from_reduced_word([2,1]) # optional - gap3 + sage: sorted(w.reduced_word() # optional - gap3 + ....: for w in W.noncrossing_partition_lattice(c21)) [[], [1], [1, 2, 1], [2], [2, 1]] - sage: sorted( w.reduced_word() for w in W.noncrossing_partition_lattice(W.from_reduced_word([2])) ) # optional - gap3 + sage: c2 = W.from_reduced_word([2]) # optional - gap3 + sage: sorted(w.reduced_word() # optional - gap3 + ....: for w in W.noncrossing_partition_lattice(c2)) [[], [2]] """ from sage.combinat.posets.posets import Poset @@ -899,8 +911,9 @@ def generalized_noncrossing_partitions(self, m, c=None, positive=False): sage: W = ReflectionGroup((1,1,3)) # optional - gap3 + sage: chains = W.generalized_noncrossing_partitions(2) # optional - gap3 sage: sorted([w.reduced_word() for w in chain] # optional - gap3 - ....: for chain in W.generalized_noncrossing_partitions(2)) + ....: for chain in chains) [[[], [], [1, 2]], [[], [1], [2]], [[], [1, 2], []], @@ -914,8 +927,10 @@ def generalized_noncrossing_partitions(self, m, c=None, positive=False): [[2], [], [1, 2, 1]], [[2], [1, 2, 1], []]] + sage: chains = W.generalized_noncrossing_partitions(2, # optional - gap3 + ....: positive=True) sage: sorted([w.reduced_word() for w in chain] # optional - gap3 - ....: for chain in W.generalized_noncrossing_partitions(2, positive=True)) + ....: for chain in chains) [[[], [1, 2], []], [[], [1, 2, 1], [1]], [[1], [2], []], @@ -987,14 +1002,14 @@ def absolute_poset(self, in_unitary_group=False): TESTS:: - sage: W1 = CoxeterGroup(['A',2]) - sage: W2 = WeylGroup(['A',2]) - sage: W3 = SymmetricGroup(3) - sage: W1.absolute_poset() + sage: W1 = CoxeterGroup(['A', 2]) # optional - sage.combinat sage.groups + sage: W2 = WeylGroup(['A', 2]) # optional - sage.combinat sage.groups + sage: W3 = SymmetricGroup(3) # optional - sage.combinat sage.groups + sage: W1.absolute_poset() # optional - sage.combinat sage.groups Finite poset containing 6 elements - sage: W2.absolute_poset() + sage: W2.absolute_poset() # optional - sage.combinat sage.groups Finite poset containing 6 elements - sage: W3.absolute_poset() + sage: W3.absolute_poset() # optional - sage.combinat sage.groups Finite poset containing 6 elements """ return self.noncrossing_partition_lattice(L=tuple(self), in_unitary_group=in_unitary_group) @@ -1008,7 +1023,8 @@ def example(self): EXAMPLES:: sage: from sage.categories.complex_reflection_groups import ComplexReflectionGroups - sage: ComplexReflectionGroups().Finite().WellGenerated().example() # optional - gap3 + sage: C = ComplexReflectionGroups().Finite().WellGenerated() + sage: C.example() # optional - gap3 Reducible complex reflection group of rank 4 and type A2 x G(3,1,2) """ from sage.combinat.root_system.reflection_group_real import ReflectionGroup @@ -1062,12 +1078,15 @@ def coxeter_elements(self): EXAMPLES:: sage: W = ReflectionGroup((1,1,3)) # optional - gap3 - sage: sorted(c.reduced_word() for c in W.coxeter_elements()) # optional - gap3 + sage: sorted(c.reduced_word() # optional - gap3 + ....: for c in W.coxeter_elements()) [[1, 2], [2, 1]] sage: W = ReflectionGroup((1,1,4)) # optional - gap3 - sage: sorted(c.reduced_word() for c in W.coxeter_elements()) # optional - gap3 - [[1, 2, 1, 3, 2], [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 1, 3, 2, 1], [3, 2, 1]] + sage: sorted(c.reduced_word() # optional - gap3 + ....: for c in W.coxeter_elements()) + [[1, 2, 1, 3, 2], [1, 2, 3], [1, 3, 2], + [2, 1, 3], [2, 1, 3, 2, 1], [3, 2, 1]] """ return self.coxeter_element().conjugacy_class() @@ -1084,7 +1103,8 @@ def example(self): EXAMPLES:: sage: from sage.categories.complex_reflection_groups import ComplexReflectionGroups - sage: ComplexReflectionGroups().Finite().WellGenerated().Irreducible().example() + sage: C = ComplexReflectionGroups().Finite().WellGenerated().Irreducible() + sage: C.example() # optional - sage.combinat sage.groups 4-colored permutations of size 3 """ from sage.combinat.colored_permutations import ColoredPermutations @@ -1109,12 +1129,12 @@ def coxeter_number(self): EXAMPLES:: - sage: W = ColoredPermutations(1,3) - sage: W.coxeter_number() + sage: W = ColoredPermutations(1,3) # optional - sage.combinat sage.groups + sage: W.coxeter_number() # optional - sage.combinat sage.groups 3 - sage: W = ColoredPermutations(4,3) - sage: W.coxeter_number() + sage: W = ColoredPermutations(4,3) # optional - sage.combinat sage.groups + sage: W.coxeter_number() # optional - sage.combinat sage.groups 12 sage: W = ReflectionGroup((4,4,3)) # optional - gap3 @@ -1130,20 +1150,20 @@ def number_of_reflections_of_full_support(self): EXAMPLES:: - sage: W = Permutations(4) - sage: W.number_of_reflections_of_full_support() + sage: W = Permutations(4) # optional - sage.combinat sage.groups + sage: W.number_of_reflections_of_full_support() # optional - sage.combinat sage.groups 1 - sage: W = ColoredPermutations(1,4) - sage: W.number_of_reflections_of_full_support() + sage: W = ColoredPermutations(1,4) # optional - sage.combinat sage.groups + sage: W.number_of_reflections_of_full_support() # optional - sage.combinat sage.groups 1 - sage: W = CoxeterGroup("B3") - sage: W.number_of_reflections_of_full_support() + sage: W = CoxeterGroup("B3") # optional - sage.combinat sage.groups + sage: W.number_of_reflections_of_full_support() # optional - sage.combinat sage.groups 3 - sage: W = ColoredPermutations(3,3) - sage: W.number_of_reflections_of_full_support() + sage: W = ColoredPermutations(3,3) # optional - sage.combinat sage.groups + sage: W.number_of_reflections_of_full_support() # optional - sage.combinat sage.groups 3 """ n = self.rank() @@ -1175,18 +1195,18 @@ def rational_catalan_number(self, p, polynomial=False): EXAMPLES:: - sage: W = ColoredPermutations(1,3) - sage: [W.rational_catalan_number(p) for p in [5,7,8]] + sage: W = ColoredPermutations(1,3) # optional - sage.combinat sage.groups + sage: [W.rational_catalan_number(p) for p in [5,7,8]] # optional - sage.combinat sage.groups [7, 12, 15] - sage: W = ColoredPermutations(2,2) - sage: [W.rational_catalan_number(p) for p in [7,9,11]] + sage: W = ColoredPermutations(2,2) # optional - sage.combinat sage.groups + sage: [W.rational_catalan_number(p) for p in [7,9,11]] # optional - sage.combinat sage.groups [10, 15, 21] TESTS:: - sage: W = ColoredPermutations(1,4) - sage: W.rational_catalan_number(3, polynomial=True) + sage: W = ColoredPermutations(1,4) # optional - sage.combinat sage.groups + sage: W.rational_catalan_number(3, polynomial=True) # optional - sage.combinat sage.groups q^6 + q^4 + q^3 + q^2 + 1 """ from sage.arith.misc import GCD as gcd @@ -1243,37 +1263,37 @@ def fuss_catalan_number(self, m, positive=False, EXAMPLES:: - sage: W = ColoredPermutations(1,3) - sage: [W.fuss_catalan_number(i) for i in [1,2,3]] + sage: W = ColoredPermutations(1,3) # optional - sage.combinat sage.groups + sage: [W.fuss_catalan_number(i) for i in [1,2,3]] # optional - sage.combinat sage.groups [5, 12, 22] - sage: W = ColoredPermutations(1,4) - sage: [W.fuss_catalan_number(i) for i in [1,2,3]] + sage: W = ColoredPermutations(1,4) # optional - sage.combinat sage.groups + sage: [W.fuss_catalan_number(i) for i in [1,2,3]] # optional - sage.combinat sage.groups [14, 55, 140] - sage: W = ColoredPermutations(1,5) - sage: [W.fuss_catalan_number(i) for i in [1,2,3]] + sage: W = ColoredPermutations(1,5) # optional - sage.combinat sage.groups + sage: [W.fuss_catalan_number(i) for i in [1,2,3]] # optional - sage.combinat sage.groups [42, 273, 969] - sage: W = ColoredPermutations(2,2) - sage: [W.fuss_catalan_number(i) for i in [1,2,3]] + sage: W = ColoredPermutations(2,2) # optional - sage.combinat sage.groups + sage: [W.fuss_catalan_number(i) for i in [1,2,3]] # optional - sage.combinat sage.groups [6, 15, 28] - sage: W = ColoredPermutations(2,3) - sage: [W.fuss_catalan_number(i) for i in [1,2,3]] + sage: W = ColoredPermutations(2,3) # optional - sage.combinat sage.groups + sage: [W.fuss_catalan_number(i) for i in [1,2,3]] # optional - sage.combinat sage.groups [20, 84, 220] - sage: W = ColoredPermutations(2,4) - sage: [W.fuss_catalan_number(i) for i in [1,2,3]] + sage: W = ColoredPermutations(2,4) # optional - sage.combinat sage.groups + sage: [W.fuss_catalan_number(i) for i in [1,2,3]] # optional - sage.combinat sage.groups [70, 495, 1820] TESTS:: - sage: W = ColoredPermutations(2,4) - sage: W.fuss_catalan_number(2,positive=True) + sage: W = ColoredPermutations(2,4) # optional - sage.combinat sage.groups + sage: W.fuss_catalan_number(2, positive=True) # optional - sage.combinat sage.groups 330 - sage: W = ColoredPermutations(2,2) - sage: W.fuss_catalan_number(2,polynomial=True) + sage: W = ColoredPermutations(2,2) # optional - sage.combinat sage.groups + sage: W.fuss_catalan_number(2, polynomial=True) # optional - sage.combinat sage.groups q^16 + q^14 + 2*q^12 + 2*q^10 + 3*q^8 + 2*q^6 + 2*q^4 + q^2 + 1 """ @@ -1317,22 +1337,25 @@ def catalan_number(self, positive=False, polynomial=False): EXAMPLES:: - sage: [ColoredPermutations(1,n).catalan_number() for n in [3,4,5]] + sage: [ColoredPermutations(1,n).catalan_number() # optional - sage.combinat sage.groups + ....: for n in [3,4,5]] [5, 14, 42] - sage: [ColoredPermutations(2,n).catalan_number() for n in [3,4,5]] + sage: [ColoredPermutations(2,n).catalan_number() # optional - sage.combinat sage.groups + ....: for n in [3,4,5]] [20, 70, 252] - sage: [ReflectionGroup((2,2,n)).catalan_number() for n in [3,4,5]] # optional - gap3 + sage: [ReflectionGroup((2,2,n)).catalan_number() # optional - gap3 + ....: for n in [3,4,5]] [14, 50, 182] TESTS:: - sage: W = ColoredPermutations(3,6) - sage: W.catalan_number(positive=True) + sage: W = ColoredPermutations(3,6) # optional - sage.combinat sage.groups + sage: W.catalan_number(positive=True) # optional - sage.combinat sage.groups 462 - sage: W = ColoredPermutations(2,2) - sage: W.catalan_number(polynomial=True) + sage: W = ColoredPermutations(2,2) # optional - sage.combinat sage.groups + sage: W.catalan_number(polynomial=True) # optional - sage.combinat sage.groups q^8 + q^6 + 2*q^4 + q^2 + 1 """ return self.fuss_catalan_number(1, positive=positive, diff --git a/src/sage/categories/finite_coxeter_groups.py b/src/sage/categories/finite_coxeter_groups.py index 270341c2262..0ec68ca2b99 100644 --- a/src/sage/categories/finite_coxeter_groups.py +++ b/src/sage/categories/finite_coxeter_groups.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.groups r""" Finite Coxeter Groups """ diff --git a/src/sage/categories/finite_crystals.py b/src/sage/categories/finite_crystals.py index 072df1f9c53..f920da8b877 100644 --- a/src/sage/categories/finite_crystals.py +++ b/src/sage/categories/finite_crystals.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.graphs r""" Finite Crystals """ diff --git a/src/sage/categories/finite_dimensional_algebras_with_basis.py b/src/sage/categories/finite_dimensional_algebras_with_basis.py index 542cf09d425..ec4a65b8db1 100644 --- a/src/sage/categories/finite_dimensional_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_algebras_with_basis.py @@ -90,29 +90,29 @@ def radical_basis(self): We construct the group algebra of the Klein Four-Group over the rationals:: - sage: A = KleinFourGroup().algebra(QQ) + sage: A = KleinFourGroup().algebra(QQ) # optional - sage.groups sage.modules This algebra belongs to the category of finite dimensional algebras over the rationals:: - sage: A in Algebras(QQ).FiniteDimensional().WithBasis() + sage: A in Algebras(QQ).FiniteDimensional().WithBasis() # optional - sage.groups sage.modules True Since the field has characteristic `0`, Maschke's Theorem tells us that the group algebra is semisimple. So its radical is the zero ideal:: - sage: A in Algebras(QQ).Semisimple() + sage: A in Algebras(QQ).Semisimple() # optional - sage.groups sage.modules True - sage: A.radical_basis() + sage: A.radical_basis() # optional - sage.groups sage.modules () Let's work instead over a field of characteristic `2`:: - sage: A = KleinFourGroup().algebra(GF(2)) - sage: A in Algebras(GF(2)).Semisimple() + sage: A = KleinFourGroup().algebra(GF(2)) # optional - sage.groups sage.rings.finite_rings sage.modules + sage: A in Algebras(GF(2)).Semisimple() # optional - sage.groups sage.rings.finite_rings sage.modules False - sage: A.radical_basis() + sage: A.radical_basis() # optional - sage.groups sage.rings.finite_rings sage.modules (() + (1,2)(3,4), (3,4) + (1,2)(3,4), (1,2) + (1,2)(3,4)) We now implement the algebra `A = K[x] / (x^p-1)`, where `K` @@ -120,7 +120,7 @@ def radical_basis(self): radical; alas, we currently need to wrap `A` to make it a proper :class:`ModulesWithBasis`:: - sage: class AnAlgebra(CombinatorialFreeModule): + sage: class AnAlgebra(CombinatorialFreeModule): # optional - sage.modules ....: def __init__(self, F): ....: R. = PolynomialRing(F) ....: I = R.ideal(x**F.characteristic()-F.one()) @@ -132,24 +132,24 @@ def radical_basis(self): ....: return self.basis()[self.base_ring().one()] ....: def product_on_basis(self, w1, w2): ....: return self.from_vector(vector(w1*w2)) - sage: AnAlgebra(GF(3)).radical_basis() + sage: AnAlgebra(GF(3)).radical_basis() # optional - sage.rings.finite_rings sage.modules (B[1] + 2*B[xbar^2], B[xbar] + 2*B[xbar^2]) - sage: AnAlgebra(GF(16,'a')).radical_basis() + sage: AnAlgebra(GF(16,'a')).radical_basis() # optional - sage.rings.finite_rings sage.modules (B[1] + B[xbar],) - sage: AnAlgebra(GF(49,'a')).radical_basis() + sage: AnAlgebra(GF(49,'a')).radical_basis() # optional - sage.rings.finite_rings sage.modules (B[1] + 6*B[xbar^6], B[xbar] + 6*B[xbar^6], B[xbar^2] + 6*B[xbar^6], B[xbar^3] + 6*B[xbar^6], B[xbar^4] + 6*B[xbar^6], B[xbar^5] + 6*B[xbar^6]) TESTS:: - sage: A = KleinFourGroup().algebra(GF(2)) - sage: A.radical_basis() + sage: A = KleinFourGroup().algebra(GF(2)) # optional - sage.groups sage.rings.finite_rings sage.modules + sage: A.radical_basis() # optional - sage.groups sage.rings.finite_rings sage.modules (() + (1,2)(3,4), (3,4) + (1,2)(3,4), (1,2) + (1,2)(3,4)) - sage: A = KleinFourGroup().algebra(QQ, category=Monoids()) - sage: A.radical_basis.__module__ + sage: A = KleinFourGroup().algebra(QQ, category=Monoids()) # optional - sage.groups sage.modules + sage: A.radical_basis.__module__ # optional - sage.groups sage.modules 'sage.categories.finite_dimensional_algebras_with_basis' - sage: A.radical_basis() + sage: A.radical_basis() # optional - sage.groups sage.modules () """ F = self.base_ring() @@ -292,10 +292,10 @@ def semisimple_quotient(self): descent algebra of the symmetric group is of dimension the number of partitions of `n`:: - sage: [ DescentAlgebra(QQ,n).B().semisimple_quotient().dimension() + sage: [ DescentAlgebra(QQ,n).B().semisimple_quotient().dimension() # optional - sage.combinat ....: for n in range(6) ] [1, 1, 2, 3, 5, 7] - sage: [Partitions(n).cardinality() for n in range(10)] + sage: [Partitions(n).cardinality() for n in range(10)] # optional - sage.combinat [1, 1, 2, 3, 5, 7, 11, 15, 22, 30] .. TODO:: @@ -365,7 +365,8 @@ def center(self): The center of a semisimple algebra is semisimple:: - sage: DihedralGroup(6).algebra(QQ).center() in Algebras(QQ).Semisimple() + sage: A = DihedralGroup(6).algebra(QQ) # optional - sage.groups sage.modules + sage: A.center() in Algebras(QQ).Semisimple() # optional - sage.groups sage.modules True .. TODO:: @@ -473,7 +474,7 @@ def orthogonal_idempotents_central_mod_radical(self): An example of a finite dimensional algebra with basis: the path algebra of the Kronecker quiver (containing the arrows a:x->y and b:x->y) over Rational Field - sage: A.orthogonal_idempotents_central_mod_radical() + sage: A.orthogonal_idempotents_central_mod_radical() # optional - sage.rings.number_field (x, y) :: @@ -496,7 +497,8 @@ def orthogonal_idempotents_central_mod_radical(self): True sage: all(e*e == e for e in idempotents) True - sage: all(e*f == 0 and f*e == 0 for e in idempotents for f in idempotents if e != f) + sage: all(e*f == 0 and f*e == 0 + ....: for e in idempotents for f in idempotents if e != f) True This is best tested with:: @@ -645,8 +647,8 @@ def cartan_invariants_matrix(self): in characteristic zero, the Cartan invariants matrix is the identity:: - sage: A3 = SymmetricGroup(3).algebra(QQ) - sage: A3.cartan_invariants_matrix() + sage: A3 = SymmetricGroup(3).algebra(QQ) # optional - sage.groups sage.modules + sage: A3.cartan_invariants_matrix() # optional - sage.groups sage.modules [1 0 0] [0 1 0] [0 0 1] @@ -655,7 +657,7 @@ def cartan_invariants_matrix(self): matrix counts the number of paths between two vertices:: sage: A = Algebras(QQ).FiniteDimensional().WithBasis().example() - sage: A.cartan_invariants_matrix() + sage: A.cartan_invariants_matrix() # optional - sage.modules sage.rings.number_field [1 2] [0 1] @@ -663,8 +665,8 @@ def cartan_invariants_matrix(self): sage: Z12 = Monoids().Finite().example(); Z12 An example of a finite multiplicative monoid: the integers modulo 12 - sage: A = Z12.algebra(QQ) - sage: A.cartan_invariants_matrix() + sage: A = Z12.algebra(QQ) # optional - sage.modules + sage: A.cartan_invariants_matrix() # optional - sage.modules [1 0 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0 0] [0 0 2 0 0 0 0 0 0] @@ -677,9 +679,9 @@ def cartan_invariants_matrix(self): With the algebra of the `0`-Hecke monoid:: - sage: from sage.monoids.hecke_monoid import HeckeMonoid - sage: A = HeckeMonoid(SymmetricGroup(4)).algebra(QQ) - sage: A.cartan_invariants_matrix() + sage: from sage.monoids.hecke_monoid import HeckeMonoid # optional - sage.groups sage.modules + sage: A = HeckeMonoid(SymmetricGroup(4)).algebra(QQ) # optional - sage.groups sage.modules + sage: A.cartan_invariants_matrix() # optional - sage.groups sage.modules [1 0 0 0 0 0 0 0] [0 2 1 0 1 1 0 0] [0 1 1 0 1 0 0 0] @@ -739,10 +741,10 @@ def isotypic_projective_modules(self, side='left'): An example of a finite dimensional algebra with basis: the path algebra of the Kronecker quiver (containing the arrows a:x->y and b:x->y) over Rational Field - sage: Q = A.isotypic_projective_modules(side="left"); Q + sage: Q = A.isotypic_projective_modules(side="left"); Q # optional - sage.rings.number_field [Free module generated by {0} over Rational Field, Free module generated by {0, 1, 2} over Rational Field] - sage: [[x.lift() for x in Qi.basis()] + sage: [[x.lift() for x in Qi.basis()] # optional - sage.rings.number_field ....: for Qi in Q] [[x], [y, a, b]] @@ -750,7 +752,7 @@ def isotypic_projective_modules(self, side='left'): We check that the sum of the dimensions of the isotypic projective modules is the dimension of ``self``:: - sage: sum([Qi.dimension() for Qi in Q]) == A.dimension() + sage: sum([Qi.dimension() for Qi in Q]) == A.dimension() # optional - sage.rings.number_field True .. SEEALSO:: @@ -782,19 +784,19 @@ def peirce_summand(self, ei, ej): EXAMPLES:: sage: A = Algebras(QQ).FiniteDimensional().WithBasis().example() - sage: idemp = A.orthogonal_idempotents_central_mod_radical() - sage: A.peirce_summand(idemp[0], idemp[1]) + sage: idemp = A.orthogonal_idempotents_central_mod_radical() # optional - sage.rings.number_field + sage: A.peirce_summand(idemp[0], idemp[1]) # optional - sage.rings.number_field Free module generated by {0, 1} over Rational Field - sage: A.peirce_summand(idemp[1], idemp[0]) + sage: A.peirce_summand(idemp[1], idemp[0]) # optional - sage.rings.number_field Free module generated by {} over Rational Field We recover the `2\times2` block of `\QQ[S_4]` corresponding to the unique simple module of dimension `2` of the symmetric group `S_4`:: - sage: A4 = SymmetricGroup(4).algebra(QQ) - sage: e = A4.central_orthogonal_idempotents()[2] - sage: A4.peirce_summand(e, e) + sage: A4 = SymmetricGroup(4).algebra(QQ) # optional - sage.groups + sage: e = A4.central_orthogonal_idempotents()[2] # optional - sage.groups sage.rings.number_field + sage: A4.peirce_summand(e, e) # optional - sage.groups sage.rings.number_field Free module generated by {0, 1, 2, 3} over Rational Field TESTS: @@ -802,11 +804,11 @@ def peirce_summand(self, ei, ej): We check each idempotent belong to its own Peirce summand (see :trac:`24687`):: - sage: from sage.monoids.hecke_monoid import HeckeMonoid - sage: M = HeckeMonoid(SymmetricGroup(4)) - sage: A = M.algebra(QQ) - sage: Idms = A.orthogonal_idempotents_central_mod_radical() - sage: all(A.peirce_summand(e, e).retract(e) + sage: from sage.monoids.hecke_monoid import HeckeMonoid # optional - sage.groups + sage: M = HeckeMonoid(SymmetricGroup(4)) # optional - sage.groups + sage: A = M.algebra(QQ) # optional - sage.groups + sage: Idms = A.orthogonal_idempotents_central_mod_radical() # optional - sage.groups sage.rings.number_field + sage: all(A.peirce_summand(e, e).retract(e) # optional - sage.groups sage.rings.number_field ....: in A.peirce_summand(e, e) for e in Idms) True """ @@ -863,14 +865,14 @@ def peirce_decomposition(self, idempotents=None, check=True): An example of a finite dimensional algebra with basis: the path algebra of the Kronecker quiver (containing the arrows a:x->y and b:x->y) over Rational Field - sage: A.orthogonal_idempotents_central_mod_radical() + sage: A.orthogonal_idempotents_central_mod_radical() # optional - sage.groups (x, y) - sage: decomposition = A.peirce_decomposition(); decomposition + sage: decomposition = A.peirce_decomposition(); decomposition # optional - sage.groups sage.modules sage.rings.number_field [[Free module generated by {0} over Rational Field, Free module generated by {0, 1} over Rational Field], [Free module generated by {} over Rational Field, Free module generated by {0} over Rational Field]] - sage: [ [[x.lift() for x in decomposition[i][j].basis()] + sage: [ [[x.lift() for x in decomposition[i][j].basis()] # optional - sage.groups sage.modules sage.rings.number_field ....: for j in range(2)] ....: for i in range(2)] [[[x], [a, b]], @@ -879,9 +881,9 @@ def peirce_decomposition(self, idempotents=None, check=True): We recover that the group algebra of the symmetric group `S_4` is a block matrix algebra:: - sage: A = SymmetricGroup(4).algebra(QQ) - sage: decomposition = A.peirce_decomposition() # long time - sage: [[decomposition[i][j].dimension() # long time (4s) + sage: A = SymmetricGroup(4).algebra(QQ) # optional - sage.groups sage.modules + sage: decomposition = A.peirce_decomposition() # long time # optional - sage.groups sage.modules sage.rings.number_field + sage: [[decomposition[i][j].dimension() # long time (4s) # optional - sage.groups sage.modules sage.rings.number_field ....: for j in range(len(decomposition))] ....: for i in range(len(decomposition))] [[9, 0, 0, 0, 0], @@ -894,7 +896,7 @@ def peirce_decomposition(self, idempotents=None, check=True): dimension of the corresponding simple module of `S_4`. The latter are given by:: - sage: [p.standard_tableaux().cardinality() for p in Partitions(4)] + sage: [p.standard_tableaux().cardinality() for p in Partitions(4)] # optional - sage.combinat [1, 3, 2, 3, 1] """ if idempotents is None: @@ -926,9 +928,9 @@ def is_identity_decomposition_into_orthogonal_idempotents(self, l): sage: A.is_identity_decomposition_into_orthogonal_idempotents([A.one()]) True - sage: A.is_identity_decomposition_into_orthogonal_idempotents([x,y]) + sage: A.is_identity_decomposition_into_orthogonal_idempotents([x, y]) True - sage: A.is_identity_decomposition_into_orthogonal_idempotents([x+a, y-a]) + sage: A.is_identity_decomposition_into_orthogonal_idempotents([x + a, y - a]) True Here the idempotents do not sum up to `1`:: @@ -938,15 +940,15 @@ def is_identity_decomposition_into_orthogonal_idempotents(self, l): Here `1+x` and `-x` are neither idempotent nor orthogonal:: - sage: A.is_identity_decomposition_into_orthogonal_idempotents([1+x,-x]) + sage: A.is_identity_decomposition_into_orthogonal_idempotents([1 + x, -x]) False With the algebra of the `0`-Hecke monoid:: - sage: from sage.monoids.hecke_monoid import HeckeMonoid - sage: A = HeckeMonoid(SymmetricGroup(4)).algebra(QQ) - sage: idempotents = A.orthogonal_idempotents_central_mod_radical() - sage: A.is_identity_decomposition_into_orthogonal_idempotents(idempotents) + sage: from sage.monoids.hecke_monoid import HeckeMonoid # optional - sage.groups + sage: A = HeckeMonoid(SymmetricGroup(4)).algebra(QQ) # optional - sage.groups sage.modules + sage: idempotents = A.orthogonal_idempotents_central_mod_radical() # optional - sage.groups sage.modules sage.rings.number_field + sage: A.is_identity_decomposition_into_orthogonal_idempotents(idempotents) # optional - sage.groups sage.modules sage.rings.number_field True Here are some more counterexamples: @@ -971,40 +973,40 @@ def is_identity_decomposition_into_orthogonal_idempotents(self, l): ....: def product_on_basis(self, w1, w2): ....: return self.from_vector(vector(w1*w2)) sage: R. = PolynomialRing(QQ) - sage: A = PQAlgebra(QQ, x**3 - x**2 + x + 1); y = A.x() - sage: a, b = y, 1-y - sage: A.is_identity_decomposition_into_orthogonal_idempotents((a, b)) + sage: A = PQAlgebra(QQ, x**3 - x**2 + x + 1); y = A.x() # optional - sage.libs.pari + sage: a, b = y, 1 - y # optional - sage.libs.pari + sage: A.is_identity_decomposition_into_orthogonal_idempotents((a, b)) # optional - sage.libs.pari False For comparison:: - sage: A = PQAlgebra(QQ, x**2 - x); y = A.x() - sage: a, b = y, 1-y - sage: A.is_identity_decomposition_into_orthogonal_idempotents((a, b)) + sage: A = PQAlgebra(QQ, x**2 - x); y = A.x() # optional - sage.libs.pari + sage: a, b = y, 1-y # optional - sage.libs.pari + sage: A.is_identity_decomposition_into_orthogonal_idempotents((a, b)) # optional - sage.libs.pari True - sage: A.is_identity_decomposition_into_orthogonal_idempotents((a, A.zero(), b)) + sage: A.is_identity_decomposition_into_orthogonal_idempotents((a, A.zero(), b)) # optional - sage.libs.pari True - sage: A = PQAlgebra(QQ, x**3 - x**2 + x - 1); y = A.x() - sage: a = (y**2 + 1) / 2 - sage: b = 1 - a - sage: A.is_identity_decomposition_into_orthogonal_idempotents((a, b)) + sage: A = PQAlgebra(QQ, x**3 - x**2 + x - 1); y = A.x() # optional - sage.libs.pari + sage: a = (y**2 + 1) / 2 # optional - sage.libs.pari + sage: b = 1 - a # optional - sage.libs.pari + sage: A.is_identity_decomposition_into_orthogonal_idempotents((a, b)) # optional - sage.libs.pari True 2. Some idempotents summing to 1 but not orthogonal:: - sage: R. = PolynomialRing(GF(2)) - sage: A = PQAlgebra(GF(2), x) - sage: a = A.one() - sage: A.is_identity_decomposition_into_orthogonal_idempotents((a,)) + sage: R. = PolynomialRing(GF(2)) # optional - sage.rings.finite_rings + sage: A = PQAlgebra(GF(2), x) # optional - sage.rings.finite_rings + sage: a = A.one() # optional - sage.rings.finite_rings + sage: A.is_identity_decomposition_into_orthogonal_idempotents((a,)) # optional - sage.rings.finite_rings True - sage: A.is_identity_decomposition_into_orthogonal_idempotents((a, a, a)) + sage: A.is_identity_decomposition_into_orthogonal_idempotents((a, a, a)) # optional - sage.rings.finite_rings False 3. Some orthogonal idempotents not summing to the identity:: - sage: A.is_identity_decomposition_into_orthogonal_idempotents((a,a)) + sage: A.is_identity_decomposition_into_orthogonal_idempotents((a,a)) # optional - sage.rings.finite_rings False - sage: A.is_identity_decomposition_into_orthogonal_idempotents(()) + sage: A.is_identity_decomposition_into_orthogonal_idempotents(()) # optional - sage.rings.finite_rings False """ return (self.sum(l) == self.one() @@ -1019,11 +1021,11 @@ def is_commutative(self): EXAMPLES:: - sage: S4 = SymmetricGroupAlgebra(QQ, 4) - sage: S4.is_commutative() + sage: S4 = SymmetricGroupAlgebra(QQ, 4) # optional - sage.groups sage.modules + sage: S4.is_commutative() # optional - sage.groups sage.modules False - sage: S2 = SymmetricGroupAlgebra(QQ, 2) - sage: S2.is_commutative() + sage: S2 = SymmetricGroupAlgebra(QQ, 2) # optional - sage.groups sage.modules + sage: S2.is_commutative() # optional - sage.groups sage.modules True """ B = list(self.basis()) @@ -1047,23 +1049,23 @@ def to_matrix(self, base_ring=None, action=operator.mul, side='left'): EXAMPLES:: - sage: QS3 = SymmetricGroupAlgebra(QQ, 3) - sage: a = QS3([2,1,3]) - sage: a.to_matrix(side='left') + sage: QS3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: a = QS3([2,1,3]) # optional - sage.groups sage.modules + sage: a.to_matrix(side='left') # optional - sage.groups sage.modules [0 0 1 0 0 0] [0 0 0 0 1 0] [1 0 0 0 0 0] [0 0 0 0 0 1] [0 1 0 0 0 0] [0 0 0 1 0 0] - sage: a.to_matrix(side='right') + sage: a.to_matrix(side='right') # optional - sage.groups sage.modules [0 0 1 0 0 0] [0 0 0 1 0 0] [1 0 0 0 0 0] [0 1 0 0 0 0] [0 0 0 0 0 1] [0 0 0 0 1 0] - sage: a.to_matrix(base_ring=RDF, side="left") + sage: a.to_matrix(base_ring=RDF, side="left") # optional - sage.groups sage.modules [0.0 0.0 1.0 0.0 0.0 0.0] [0.0 0.0 0.0 0.0 1.0 0.0] [1.0 0.0 0.0 0.0 0.0 0.0] @@ -1100,47 +1102,47 @@ def __invert__(self): EXAMPLES:: - sage: QS3 = SymmetricGroupAlgebra(QQ, 3) - sage: P = Permutation - sage: a = 3 * QS3(P([1,2,3])) + QS3(P([1,3,2])) + QS3(P([2,1,3])) - sage: b = ~a; b + sage: QS3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: P = Permutation # optional - sage.groups sage.modules + sage: a = 3 * QS3(P([1,2,3])) + QS3(P([1,3,2])) + QS3(P([2,1,3])) # optional - sage.groups sage.modules + sage: b = ~a; b # optional - sage.groups sage.modules 9/20*[1, 2, 3] - 7/40*[1, 3, 2] - 7/40*[2, 1, 3] + 3/40*[2, 3, 1] + 3/40*[3, 1, 2] - 1/20*[3, 2, 1] - sage: a * b + sage: a * b # optional - sage.groups sage.modules [1, 2, 3] - sage: ~b == a + sage: ~b == a # optional - sage.groups sage.modules True - sage: a = 3 * QS3.one() - sage: b = ~a - sage: b * a == QS3.one() + sage: a = 3 * QS3.one() # optional - sage.groups sage.modules + sage: b = ~a # optional - sage.groups sage.modules + sage: b * a == QS3.one() # optional - sage.groups sage.modules True - sage: b == 1/3 * QS3.one() + sage: b == 1/3 * QS3.one() # optional - sage.groups sage.modules True - sage: ~b == a + sage: ~b == a # optional - sage.groups sage.modules True sage: R. = QQ[] - sage: RS3 = SymmetricGroupAlgebra(R, 3) - sage: a = RS3(P([1,2,3])) - RS3(P([1,3,2])) + RS3(P([2,1,3])); ~a + sage: RS3 = SymmetricGroupAlgebra(R, 3) # optional - sage.groups sage.modules + sage: a = RS3(P([1,2,3])) - RS3(P([1,3,2])) + RS3(P([2,1,3])); ~a # optional - sage.groups sage.modules -1/2*[1, 3, 2] + 1/2*[2, 1, 3] + 1/2*[2, 3, 1] + 1/2*[3, 1, 2] Some examples on elements that do not have an inverse:: - sage: c = 2 * QS3(P([1,2,3])) + QS3(P([1,3,2])) + QS3(P([2,1,3])) - sage: ~c + sage: c = 2 * QS3(P([1,2,3])) + QS3(P([1,3,2])) + QS3(P([2,1,3])) # optional - sage.groups sage.modules + sage: ~c # optional - sage.groups sage.modules Traceback (most recent call last): ... ValueError: cannot invert self (= 2*[1, 2, 3] + [1, 3, 2] + [2, 1, 3]) - sage: ZS3 = SymmetricGroupAlgebra(ZZ, 3) - sage: aZ = 3 * ZS3(P([1,2,3])) + ZS3(P([1,3,2])) + ZS3(P([2,1,3])) - sage: ~aZ + sage: ZS3 = SymmetricGroupAlgebra(ZZ, 3) # optional - sage.groups sage.modules + sage: aZ = 3 * ZS3(P([1,2,3])) + ZS3(P([1,3,2])) + ZS3(P([2,1,3])) # optional - sage.groups sage.modules + sage: ~aZ # optional - sage.groups sage.modules Traceback (most recent call last): ... ValueError: cannot invert self (= 3*[1, 2, 3] + [1, 3, 2] + [2, 1, 3]) - sage: x = 2 * ZS3.one() - sage: ~x + sage: x = 2 * ZS3.one() # optional - sage.groups sage.modules + sage: ~x # optional - sage.groups sage.modules Traceback (most recent call last): ... ValueError: cannot invert self (= 2*[1, 2, 3]) @@ -1149,9 +1151,9 @@ def __invert__(self): An algebra that does not define ``one_basis()``:: - sage: I = DescentAlgebra(QQ, 3).I() - sage: a = 3 * I.one() - sage: ~a == 1/3 * I.one() + sage: I = DescentAlgebra(QQ, 3).I() # optional - sage.combinat sage.modules + sage: a = 3 * I.one() # optional - sage.combinat sage.modules + sage: ~a == 1/3 * I.one() # optional - sage.combinat sage.modules True """ alg = self.parent() @@ -1239,8 +1241,8 @@ def _test_cellular(self, **options): EXAMPLES:: - sage: S = SymmetricGroupAlgebra(QQ, 3) - sage: S._test_cellular() + sage: S = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: S._test_cellular() # optional - sage.combinat sage.modules """ tester = self._tester(**options) cell_basis = self.cellular_basis() @@ -1273,8 +1275,8 @@ def cell_poset(self): EXAMPLES:: - sage: S = SymmetricGroupAlgebra(QQ, 4) - sage: S.cell_poset() + sage: S = SymmetricGroupAlgebra(QQ, 4) # optional - sage.groups sage.modules + sage: S.cell_poset() # optional - sage.groups sage.modules Finite poset containing 5 elements """ @@ -1288,8 +1290,8 @@ def cell_module_indices(self, mu): EXAMPLES:: - sage: S = SymmetricGroupAlgebra(QQ, 3) - sage: S.cell_module_indices([2,1]) + sage: S = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: S.cell_module_indices([2,1]) # optional - sage.groups sage.modules Standard tableaux of shape [2, 1] """ @@ -1301,8 +1303,8 @@ def _to_cellular_element(self, i): EXAMPLES:: - sage: S = SymmetricGroupAlgebra(QQ, 3) - sage: S._to_cellular_element # no implementation currently uses this + sage: S = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: S._to_cellular_element # no implementation currently uses this # optional - sage.groups sage.modules NotImplemented """ @@ -1314,13 +1316,12 @@ def _from_cellular_index(self, x): EXAMPLES:: - sage: S = SymmetricGroupAlgebra(QQ, 3) - sage: mu = Partition([2,1]) - sage: s = StandardTableau([[1,2],[3]]) - sage: t = StandardTableau([[1,3],[2]]) - sage: S._from_cellular_index((mu, s, t)) - 1/4*[1, 3, 2] - 1/4*[2, 3, 1] + 1/4*[3, 1, 2] - - 1/4*[3, 2, 1] + sage: S = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat sage.groups sage.modules + sage: mu = Partition([2,1]) # optional - sage.combinat sage.groups sage.modules + sage: s = StandardTableau([[1,2],[3]]) # optional - sage.combinat sage.groups sage.modules + sage: t = StandardTableau([[1,3],[2]]) # optional - sage.combinat sage.groups sage.modules + sage: S._from_cellular_index((mu, s, t)) # optional - sage.combinat sage.groups sage.modules + 1/4*[1, 3, 2] - 1/4*[2, 3, 1] + 1/4*[3, 1, 2] - 1/4*[3, 2, 1] """ def cellular_involution(self, x): @@ -1329,8 +1330,8 @@ def cellular_involution(self, x): EXAMPLES:: - sage: S = SymmetricGroupAlgebra(QQ, 3) - sage: for b in S.basis(): b, S.cellular_involution(b) + sage: S = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: for b in S.basis(): b, S.cellular_involution(b) # optional - sage.groups sage.modules ([1, 2, 3], [1, 2, 3]) ([1, 3, 2], 49/48*[1, 3, 2] + 7/48*[2, 3, 1] - 7/48*[3, 1, 2] - 1/48*[3, 2, 1]) @@ -1356,8 +1357,8 @@ def cells(self): EXAMPLES:: - sage: S = SymmetricGroupAlgebra(QQ, 3) - sage: dict(S.cells()) + sage: S = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: dict(S.cells()) # optional - sage.groups sage.modules {[1, 1, 1]: Standard tableaux of shape [1, 1, 1], [2, 1]: Standard tableaux of shape [2, 1], [3]: Standard tableaux of shape [3]} @@ -1371,8 +1372,8 @@ def cellular_basis(self): EXAMPLES:: - sage: S = SymmetricGroupAlgebra(QQ, 3) - sage: S.cellular_basis() + sage: S = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: S.cellular_basis() # optional - sage.groups sage.modules Cellular basis of Symmetric group algebra of order 3 over Rational Field """ @@ -1385,8 +1386,8 @@ def cell_module(self, mu, **kwds): EXAMPLES:: - sage: S = SymmetricGroupAlgebra(QQ, 3) - sage: S.cell_module(Partition([2,1])) + sage: S = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: S.cell_module(Partition([2,1])) # optional - sage.combinat sage.groups sage.modules Cell module indexed by [2, 1] of Cellular basis of Symmetric group algebra of order 3 over Rational Field """ @@ -1404,8 +1405,8 @@ def simple_module_parameterization(self): EXAMPLES:: - sage: S = SymmetricGroupAlgebra(QQ, 4) - sage: S.simple_module_parameterization() + sage: S = SymmetricGroupAlgebra(QQ, 4) # optional - sage.groups sage.modules + sage: S.simple_module_parameterization() # optional - sage.groups sage.modules ([4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]) """ return tuple([mu for mu in self.cell_poset() @@ -1418,12 +1419,12 @@ def cellular_involution(self): EXAMPLES:: - sage: S = SymmetricGroupAlgebra(QQ, 4) - sage: elt = S([3,1,2,4]) - sage: ci = elt.cellular_involution(); ci + sage: S = SymmetricGroupAlgebra(QQ, 4) # optional - sage.groups sage.modules + sage: elt = S([3,1,2,4]) # optional - sage.groups sage.modules + sage: ci = elt.cellular_involution(); ci # optional - sage.groups sage.modules 7/48*[1, 3, 2, 4] + 49/48*[2, 3, 1, 4] - 1/48*[3, 1, 2, 4] - 7/48*[3, 2, 1, 4] - sage: ci.cellular_involution() + sage: ci.cellular_involution() # optional - sage.groups sage.modules [3, 1, 2, 4] """ return self.parent().cellular_involution(self) @@ -1455,10 +1456,10 @@ def cell_poset(self): EXAMPLES:: - sage: S2 = SymmetricGroupAlgebra(QQ, 2) - sage: S3 = SymmetricGroupAlgebra(QQ, 3) - sage: T = S2.tensor(S3) - sage: T.cell_poset() + sage: S2 = SymmetricGroupAlgebra(QQ, 2) # optional - sage.groups sage.modules + sage: S3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: T = S2.tensor(S3) # optional - sage.groups sage.modules + sage: T.cell_poset() # optional - sage.combinat sage.graphs sage.groups sage.modules Finite poset containing 6 elements """ ret = self._sets[0].cell_poset() @@ -1475,10 +1476,10 @@ def cell_module_indices(self, mu): EXAMPLES:: - sage: S2 = SymmetricGroupAlgebra(QQ, 2) - sage: S3 = SymmetricGroupAlgebra(QQ, 3) - sage: T = S2.tensor(S3) - sage: T.cell_module_indices(([1,1], [2,1])) + sage: S2 = SymmetricGroupAlgebra(QQ, 2) # optional - sage.groups sage.modules + sage: S3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: T = S2.tensor(S3) # optional - sage.groups sage.modules + sage: T.cell_module_indices(([1,1], [2,1])) # optional - sage.groups sage.modules The Cartesian product of (Standard tableaux of shape [1, 1], Standard tableaux of shape [2, 1]) """ @@ -1494,10 +1495,10 @@ def cellular_involution(self): EXAMPLES:: - sage: S2 = SymmetricGroupAlgebra(QQ, 2) - sage: S3 = SymmetricGroupAlgebra(QQ, 3) - sage: T = S2.tensor(S3) - sage: for b in T.basis(): b, T.cellular_involution(b) + sage: S2 = SymmetricGroupAlgebra(QQ, 2) # optional - sage.groups sage.modules + sage: S3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: T = S2.tensor(S3) # optional - sage.groups sage.modules + sage: for b in T.basis(): b, T.cellular_involution(b) # optional - sage.groups sage.modules ([1, 2] # [1, 2, 3], [1, 2] # [1, 2, 3]) ([1, 2] # [1, 3, 2], 49/48*[1, 2] # [1, 3, 2] + 7/48*[1, 2] # [2, 3, 1] @@ -1547,10 +1548,10 @@ def _to_cellular_element(self, i): EXAMPLES:: - sage: S2 = SymmetricGroupAlgebra(QQ, 2) - sage: S3 = SymmetricGroupAlgebra(QQ, 3) - sage: T = S2.tensor(S3) - sage: all(T(T._to_cellular_element(k)).leading_support() == k + sage: S2 = SymmetricGroupAlgebra(QQ, 2) # optional - sage.groups sage.modules + sage: S3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: T = S2.tensor(S3) # optional - sage.groups sage.modules + sage: all(T(T._to_cellular_element(k)).leading_support() == k # optional - sage.groups sage.modules ....: for k in T.basis().keys()) True """ @@ -1583,11 +1584,11 @@ def _from_cellular_index(self, x): EXAMPLES:: - sage: S2 = SymmetricGroupAlgebra(QQ, 2) - sage: S3 = SymmetricGroupAlgebra(QQ, 3) - sage: T = S2.tensor(S3) - sage: C = T.cellular_basis() - sage: all(C(T._from_cellular_index(k)).leading_support() == k + sage: S2 = SymmetricGroupAlgebra(QQ, 2) # optional - sage.groups sage.modules + sage: S3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: T = S2.tensor(S3) # optional - sage.groups sage.modules + sage: C = T.cellular_basis() # optional - sage.groups sage.modules + sage: all(C(T._from_cellular_index(k)).leading_support() == k # optional - sage.groups sage.modules ....: for k in C.basis().keys()) True """ diff --git a/src/sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py b/src/sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py index 4bbdf0807b1..e10e30a5846 100644 --- a/src/sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py @@ -55,12 +55,12 @@ def _test_grading(self, **options): sage: C = LieAlgebras(QQ).WithBasis().Graded() sage: C = C.FiniteDimensional().Stratified().Nilpotent() - sage: L = LieAlgebra(QQ, {('x','y'): {'z': 1}}, + sage: L = LieAlgebra(QQ, {('x','y'): {'z': 1}}, # optional - sage.combinat sage.modules ....: nilpotent=True, category=C) - sage: L._test_grading() - sage: L = LieAlgebra(QQ, {('x','y'): {'x': 1}}, + sage: L._test_grading() # optional - sage.combinat sage.modules + sage: L = LieAlgebra(QQ, {('x','y'): {'x': 1}}, # optional - sage.combinat sage.modules ....: nilpotent=True, category=C) - sage: L._test_grading() + sage: L._test_grading() # optional - sage.combinat sage.modules Traceback (most recent call last): ... AssertionError: Lie bracket [x, y] has degree 1, not degree 2 @@ -96,9 +96,9 @@ def homogeneous_component_as_submodule(self, d): sage: C = LieAlgebras(QQ).WithBasis().Graded() sage: C = C.FiniteDimensional().Stratified().Nilpotent() - sage: L = LieAlgebra(QQ, {('x','y'): {'z': 1}}, + sage: L = LieAlgebra(QQ, {('x','y'): {'z': 1}}, # optional - sage.combinat sage.modules ....: nilpotent=True, category=C) - sage: L.homogeneous_component_as_submodule(2) + sage: L.homogeneous_component_as_submodule(2) # optional - sage.combinat sage.modules Sparse vector space of degree 3 and dimension 1 over Rational Field Basis matrix: [0 0 1] @@ -147,12 +147,12 @@ def _test_generated_by_degree_one(self, **options): sage: C = LieAlgebras(QQ).WithBasis().Graded() sage: C = C.FiniteDimensional().Stratified().Nilpotent() sage: sc = {('x','y'): {'z': 1}} - sage: L. = LieAlgebra(QQ, sc, nilpotent=True, category=C) - sage: L._test_generated_by_degree_one() + sage: L. = LieAlgebra(QQ, sc, nilpotent=True, category=C) # optional - sage.combinat sage.modules + sage: L._test_generated_by_degree_one() # optional - sage.combinat sage.modules sage: sc = {('x','y'): {'z': 1}, ('a','b'): {'c':1}, ('z','c'): {'m':1}} - sage: L. = LieAlgebra(QQ, sc, nilpotent=True, category=C) - sage: L._test_generated_by_degree_one() + sage: L. = LieAlgebra(QQ, sc, nilpotent=True, category=C) # optional - sage.combinat sage.modules + sage: L._test_generated_by_degree_one() # optional - sage.combinat sage.modules Traceback (most recent call last): ... AssertionError: [a, b, x, y] does not generate Nilpotent Lie algebra @@ -199,16 +199,16 @@ def degree_on_basis(self, m): sage: C = LieAlgebras(QQ).WithBasis().Graded() sage: C = C.FiniteDimensional().Stratified().Nilpotent() sage: sc = {('X','Y'): {'Z': 1}} - sage: L. = LieAlgebra(QQ, sc, nilpotent=True, category=C) - sage: L.degree_on_basis(X.leading_support()) + sage: L. = LieAlgebra(QQ, sc, nilpotent=True, category=C) # optional - sage.combinat sage.modules + sage: L.degree_on_basis(X.leading_support()) # optional - sage.combinat sage.modules 1 - sage: X.degree() + sage: X.degree() # optional - sage.combinat sage.modules 1 - sage: Y.degree() + sage: Y.degree() # optional - sage.combinat sage.modules 1 - sage: L[X, Y] + sage: L[X, Y] # optional - sage.combinat sage.modules Z - sage: Z.degree() + sage: Z.degree() # optional - sage.combinat sage.modules 2 """ if not hasattr(self, '_basis_degrees'): diff --git a/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py b/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py index 487924b5748..3637ea46298 100644 --- a/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py @@ -46,13 +46,13 @@ def example(self, n=3): EXAMPLES:: sage: C = LieAlgebras(QQ).FiniteDimensional().WithBasis() - sage: C.example() + sage: C.example() # optional - sage.modules An example of a finite dimensional Lie algebra with basis: the 3-dimensional abelian Lie algebra over Rational Field Other dimensions can be specified as an optional argument:: - sage: C.example(5) + sage: C.example(5) # optional - sage.modules An example of a finite dimensional Lie algebra with basis: the 5-dimensional abelian Lie algebra over Rational Field """ @@ -70,27 +70,29 @@ def _construct_UEA(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: UEA = L._construct_UEA(); UEA + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.modules sage.combinat + sage: UEA = L._construct_UEA(); UEA # optional - sage.modules sage.combinat Noncommutative Multivariate Polynomial Ring in b0, b1, b2 over Rational Field, nc-relations: {} - sage: UEA.relations(add_commutative=True) + sage: UEA.relations(add_commutative=True) # optional - sage.modules sage.combinat {b1*b0: b0*b1, b2*b0: b0*b2, b2*b1: b1*b2} :: - sage: L. = LieAlgebra(QQ, {('x','y'):{'z':1}, ('y','z'):{'x':1}, ('z','x'):{'y':1}}) - sage: UEA = L._construct_UEA(); UEA + sage: L. = LieAlgebra(QQ, {('x','y'): {'z':1}, # optional - sage.modules sage.combinat + ....: ('y','z'): {'x':1}, + ....: ('z','x'):{'y':1}}) + sage: UEA = L._construct_UEA(); UEA # optional - sage.modules sage.combinat Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {...} - sage: sorted(UEA.relations().items(), key=str) + sage: sorted(UEA.relations().items(), key=str) # optional - sage.modules sage.combinat [(y*x, x*y - z), (z*x, x*z + y), (z*y, y*z - x)] Singular's ``nc_algebra`` does not work over `\ZZ/6\ZZ`, so we fallback to the PBW basis in this case:: - sage: L = lie_algebras.pwitt(Zmod(6), 6) - sage: L._construct_UEA() + sage: L = lie_algebras.pwitt(Zmod(6), 6) # optional - sage.modules sage.combinat + sage: L._construct_UEA() # optional - sage.modules sage.combinat Universal enveloping algebra of The 6-Witt Lie algebra over Ring of integers modulo 6 in the Poincare-Birkhoff-Witt basis @@ -147,8 +149,8 @@ def _basis_ordering(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L._basis_ordering + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.modules sage.combinat + sage: L._basis_ordering # optional - sage.modules sage.combinat (0, 1, 2) """ return tuple(self.basis().keys()) @@ -161,10 +163,10 @@ def _basis_key_inverse(self): EXAMPLES:: - sage: G = SymmetricGroup(3) - sage: S = GroupAlgebra(G, QQ) - sage: L = LieAlgebra(associative=S) - sage: [L._basis_key_inverse[k] for k in L._basis_ordering] + sage: G = SymmetricGroup(3) # optional - sage.groups + sage: S = GroupAlgebra(G, QQ) # optional - sage.groups sage.modules + sage: L = LieAlgebra(associative=S) # optional - sage.groups sage.modules + sage: [L._basis_key_inverse[k] for k in L._basis_ordering] # optional - sage.groups sage.modules [0, 1, 2, 3, 4, 5] """ return {k: i for i,k in enumerate(self._basis_ordering)} @@ -175,33 +177,34 @@ def _basis_key(self, x): TESTS:: - sage: L = lie_algebras.three_dimensional_by_rank(QQ, 3, names=['E','F','H']) - sage: PBW = L.pbw_basis() - sage: PBW._basis_key('E') < PBW._basis_key('H') + sage: L = lie_algebras.three_dimensional_by_rank(QQ, 3, # optional - sage.groups sage.modules + ....: names=['E','F','H']) + sage: PBW = L.pbw_basis() # optional - sage.groups sage.modules + sage: PBW._basis_key('E') < PBW._basis_key('H') # optional - sage.groups sage.modules True :: - sage: L = lie_algebras.sl(QQ, 2) - sage: def neg_key(x): + sage: L = lie_algebras.sl(QQ, 2) # optional - sage.groups sage.modules + sage: def neg_key(x): # optional - sage.groups sage.modules ....: return -L.basis().keys().index(x) - sage: PBW = L.pbw_basis(basis_key=neg_key) - sage: prod(PBW.gens()) # indirect doctest + sage: PBW = L.pbw_basis(basis_key=neg_key) # optional - sage.groups sage.modules + sage: prod(PBW.gens()) # indirect doctest # optional - sage.groups sage.modules PBW[-alpha[1]]*PBW[alphacheck[1]]*PBW[alpha[1]] - 4*PBW[-alpha[1]]*PBW[alpha[1]] + PBW[alphacheck[1]]^2 - 2*PBW[alphacheck[1]] Check that :trac:`23266` is fixed:: - sage: sl2 = lie_algebras.sl(QQ, 2, 'matrix') - sage: sl2.indices() + sage: sl2 = lie_algebras.sl(QQ, 2, 'matrix') # optional - sage.groups sage.modules + sage: sl2.indices() # optional - sage.groups sage.modules {'e1', 'f1', 'h1'} - sage: type(sl2.basis().keys()) + sage: type(sl2.basis().keys()) # optional - sage.groups sage.modules - sage: Usl2 = sl2.pbw_basis() - sage: Usl2._basis_key(2) + sage: Usl2 = sl2.pbw_basis() # optional - sage.groups sage.modules + sage: Usl2._basis_key(2) # optional - sage.groups sage.modules 2 - sage: Usl2._basis_key(3) + sage: Usl2._basis_key(3) # optional - sage.groups sage.modules Traceback (most recent call last): ... KeyError: 3 @@ -214,8 +217,8 @@ def _dense_free_module(self, R=None): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L._dense_free_module() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.modules + sage: L._dense_free_module() # optional - sage.modules Vector space of dimension 3 over Rational Field """ if R is None: @@ -237,10 +240,10 @@ def from_vector(self, v, order=None): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: u = L.from_vector(vector(QQ, (1, 0, 0))); u + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.modules + sage: u = L.from_vector(vector(QQ, (1, 0, 0))); u # optional - sage.modules (1, 0, 0) - sage: parent(u) is L + sage: parent(u) is L # optional - sage.modules True """ if order is None: @@ -260,17 +263,17 @@ def killing_matrix(self, x, y): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: a,b,c = L.lie_algebra_generators() - sage: L.killing_matrix(a, b) + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.modules + sage: a, b, c = L.lie_algebra_generators() # optional - sage.modules + sage: L.killing_matrix(a, b) # optional - sage.modules [0 0 0] [0 0 0] [0 0 0] :: - sage: L. = LieAlgebra(QQ, {('x','y'):{'x':1}}) - sage: L.killing_matrix(y, x) + sage: L. = LieAlgebra(QQ, {('x','y'): {'x':1}}) # optional - sage.combinat sage.modules + sage: L.killing_matrix(y, x) # optional - sage.combinat sage.modules [ 0 -1] [ 0 0] """ @@ -291,9 +294,9 @@ def killing_form(self, x, y): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: a,b,c = L.lie_algebra_generators() - sage: L.killing_form(a, b) + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: a, b, c = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: L.killing_form(a, b) # optional - sage.combinat sage.modules 0 """ return self.killing_matrix(x, y).trace() @@ -309,16 +312,16 @@ def killing_form_matrix(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.killing_form_matrix() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.modules + sage: L.killing_form_matrix() # optional - sage.modules [0 0 0] [0 0 0] [0 0 0] - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example(0) - sage: m = L.killing_form_matrix(); m + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example(0) # optional - sage.modules + sage: m = L.killing_form_matrix(); m # optional - sage.modules [] - sage: parent(m) + sage: parent(m) # optional - sage.modules Full MatrixSpace of 0 by 0 dense matrices over Rational Field """ from sage.matrix.constructor import matrix @@ -347,18 +350,18 @@ def structure_coefficients(self, include_zeros=False): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.structure_coefficients() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.modules + sage: L.structure_coefficients() # optional - sage.modules Finite family {} - sage: L.structure_coefficients(True) + sage: L.structure_coefficients(True) # optional - sage.modules Finite family {(0, 1): (0, 0, 0), (0, 2): (0, 0, 0), (1, 2): (0, 0, 0)} :: - sage: G = SymmetricGroup(3) - sage: S = GroupAlgebra(G, QQ) - sage: L = LieAlgebra(associative=S) - sage: L.structure_coefficients() + sage: G = SymmetricGroup(3) # optional - sage.groups + sage: S = GroupAlgebra(G, QQ) # optional - sage.groups sage.modules + sage: L = LieAlgebra(associative=S) # optional - sage.groups sage.modules sage.combinat + sage: L.structure_coefficients() # optional - sage.groups sage.modules sage.combinat Finite family {((2,3), (1,2)): (1,2,3) - (1,3,2), ((2,3), (1,3)): -(1,2,3) + (1,3,2), ((1,2,3), (2,3)): -(1,2) + (1,3), @@ -401,23 +404,23 @@ def centralizer_basis(self, S): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: a,b,c = L.lie_algebra_generators() - sage: L.centralizer_basis([a + b, 2*a + c]) + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.modules + sage: a, b, c = L.lie_algebra_generators() # optional - sage.modules + sage: L.centralizer_basis([a + b, 2*a + c]) # optional - sage.modules [(1, 0, 0), (0, 1, 0), (0, 0, 1)] - sage: H = lie_algebras.Heisenberg(QQ, 2) - sage: H.centralizer_basis(H) + sage: H = lie_algebras.Heisenberg(QQ, 2) # optional - sage.combinat sage.modules + sage: H.centralizer_basis(H) # optional - sage.combinat sage.modules [z] - sage: D = DescentAlgebra(QQ, 4).D() - sage: L = LieAlgebra(associative=D) - sage: L.centralizer_basis(L) + sage: D = DescentAlgebra(QQ, 4).D() # optional - sage.combinat sage.modules + sage: L = LieAlgebra(associative=D) # optional - sage.combinat sage.modules + sage: L.centralizer_basis(L) # optional - sage.combinat sage.modules [D{}, D{1} + D{1, 2} + D{2, 3} + D{3}, D{1, 2, 3} + D{1, 3} + D{2}] - sage: D.center_basis() + sage: D.center_basis() # optional - sage.combinat sage.modules (D{}, D{1} + D{1, 2} + D{2, 3} + D{3}, D{1, 2, 3} + D{1, 3} + D{2}) @@ -465,12 +468,12 @@ def centralizer(self, S): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: a,b,c = L.lie_algebra_generators() - sage: S = L.centralizer([a + b, 2*a + c]); S + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.modules + sage: a, b, c = L.lie_algebra_generators() # optional - sage.modules + sage: S = L.centralizer([a + b, 2*a + c]); S # optional - sage.modules An example of a finite dimensional Lie algebra with basis: the 3-dimensional abelian Lie algebra over Rational Field - sage: S.basis_matrix() + sage: S.basis_matrix() # optional - sage.modules [1 0 0] [0 1 0] [0 0 1] @@ -483,11 +486,11 @@ def center(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: Z = L.center(); Z + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.modules + sage: Z = L.center(); Z # optional - sage.modules An example of a finite dimensional Lie algebra with basis: the 3-dimensional abelian Lie algebra over Rational Field - sage: Z.basis_matrix() + sage: Z.basis_matrix() # optional - sage.modules [1 0 0] [0 1 0] [0 0 1] @@ -514,8 +517,8 @@ def derivations_basis(self): We construct the derivations of the Heisenberg Lie algebra:: - sage: H = lie_algebras.Heisenberg(QQ, 1) - sage: H.derivations_basis() + sage: H = lie_algebras.Heisenberg(QQ, 1) # optional - sage.combinat sage.modules + sage: H.derivations_basis() # optional - sage.combinat sage.modules ( [1 0 0] [0 1 0] [0 0 0] [0 0 0] [0 0 0] [0 0 0] [0 0 0] [0 0 0] [1 0 0] [0 1 0] [0 0 0] [0 0 0] @@ -524,8 +527,8 @@ def derivations_basis(self): We construct the derivations of `\mathfrak{sl}_2`:: - sage: sl2 = lie_algebras.sl(QQ, 2) - sage: sl2.derivations_basis() + sage: sl2 = lie_algebras.sl(QQ, 2) # optional - sage.combinat sage.modules + sage: sl2.derivations_basis() # optional - sage.combinat sage.modules ( [ 1 0 0] [ 0 1 0] [ 0 0 0] [ 0 0 0] [ 0 0 -1/2] [ 1 0 0] @@ -534,9 +537,9 @@ def derivations_basis(self): We verify these are derivations:: - sage: D = [sl2.module_morphism(matrix=M, codomain=sl2) + sage: D = [sl2.module_morphism(matrix=M, codomain=sl2) # optional - sage.combinat sage.modules ....: for M in sl2.derivations_basis()] - sage: all(d(a.bracket(b)) == d(a).bracket(b) + a.bracket(d(b)) + sage: all(d(a.bracket(b)) == d(a).bracket(b) + a.bracket(d(b)) # optional - sage.combinat sage.modules ....: for a in sl2.basis() for b in sl2.basis() for d in D) True @@ -578,8 +581,8 @@ def inner_derivations_basis(self): EXAMPLES:: - sage: H = lie_algebras.Heisenberg(QQ, 1) - sage: H.inner_derivations_basis() + sage: H = lie_algebras.Heisenberg(QQ, 1) # optional - sage.combinat sage.modules + sage: H.inner_derivations_basis() # optional - sage.combinat sage.modules ( [0 0 0] [0 0 0] [0 0 0] [0 0 0] @@ -606,24 +609,24 @@ def subalgebra(self, *gens, **kwds): EXAMPLES:: - sage: H = lie_algebras.Heisenberg(QQ, 2) - sage: p1,p2,q1,q2,z = H.basis() - sage: S = H.subalgebra([p1, q1]) - sage: S.basis().list() + sage: H = lie_algebras.Heisenberg(QQ, 2) # optional - sage.combinat sage.modules + sage: p1,p2,q1,q2,z = H.basis() # optional - sage.combinat sage.modules + sage: S = H.subalgebra([p1, q1]) # optional - sage.combinat sage.modules + sage: S.basis().list() # optional - sage.combinat sage.modules [p1, q1, z] - sage: S.basis_matrix() + sage: S.basis_matrix() # optional - sage.combinat sage.modules [1 0 0 0 0] [0 0 1 0 0] [0 0 0 0 1] Passing an extra category to a subalgebra:: - sage: L = LieAlgebra(QQ, 3, step=2) - sage: x,y,z = L.homogeneous_component_basis(1) - sage: C = LieAlgebras(QQ).FiniteDimensional().WithBasis() - sage: C = C.Subobjects().Graded().Stratified() - sage: S = L.subalgebra([x, y], category=C) - sage: S.homogeneous_component_basis(2).list() + sage: L = LieAlgebra(QQ, 3, step=2) # optional - sage.combinat sage.modules + sage: x,y,z = L.homogeneous_component_basis(1) # optional - sage.combinat sage.modules + sage: C = LieAlgebras(QQ).FiniteDimensional().WithBasis() # optional - sage.combinat sage.modules + sage: C = C.Subobjects().Graded().Stratified() # optional - sage.combinat sage.modules + sage: S = L.subalgebra([x, y], category=C) # optional - sage.combinat sage.modules + sage: S.homogeneous_component_basis(2).list() # optional - sage.combinat sage.modules [X_12] """ from sage.algebras.lie_algebras.subalgebra import LieSubalgebra_finite_dimensional_with_basis @@ -645,21 +648,21 @@ def ideal(self, *gens, **kwds): EXAMPLES:: - sage: H = lie_algebras.Heisenberg(QQ, 2) - sage: p1,p2,q1,q2,z = H.basis() - sage: I = H.ideal([p1-p2, q1-q2]) - sage: I.basis().list() + sage: H = lie_algebras.Heisenberg(QQ, 2) # optional - sage.combinat sage.modules + sage: p1,p2,q1,q2,z = H.basis() # optional - sage.combinat sage.modules + sage: I = H.ideal([p1-p2, q1-q2]) # optional - sage.combinat sage.modules + sage: I.basis().list() # optional - sage.combinat sage.modules [-p1 + p2, -q1 + q2, z] - sage: I.reduce(p1 + p2 + q1 + q2 + z) + sage: I.reduce(p1 + p2 + q1 + q2 + z) # optional - sage.combinat sage.modules 2*p1 + 2*q1 Passing an extra category to an ideal:: - sage: L. = LieAlgebra(QQ, abelian=True) - sage: C = LieAlgebras(QQ).FiniteDimensional().WithBasis() - sage: C = C.Subobjects().Graded().Stratified() - sage: I = L.ideal(x, y, category=C) - sage: I.homogeneous_component_basis(1).list() + sage: L. = LieAlgebra(QQ, abelian=True) # optional - sage.combinat sage.modules + sage: C = LieAlgebras(QQ).FiniteDimensional().WithBasis() # optional - sage.combinat sage.modules + sage: C = C.Subobjects().Graded().Stratified() # optional - sage.combinat sage.modules + sage: I = L.ideal(x, y, category=C) # optional - sage.combinat sage.modules + sage: I.homogeneous_component_basis(1).list() # optional - sage.combinat sage.modules [x, y] """ from sage.algebras.lie_algebras.subalgebra import LieSubalgebra_finite_dimensional_with_basis @@ -676,18 +679,18 @@ def is_ideal(self, A): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: a, b, c = L.lie_algebra_generators() - sage: I = L.ideal([2*a - c, b + c]) - sage: I.is_ideal(L) + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: a, b, c = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: I = L.ideal([2*a - c, b + c]) # optional - sage.combinat sage.modules + sage: I.is_ideal(L) # optional - sage.combinat sage.modules True - sage: L. = LieAlgebra(QQ, {('x','y'):{'x':1}}) - sage: L.is_ideal(L) + sage: L. = LieAlgebra(QQ, {('x','y'):{'x':1}}) # optional - sage.combinat sage.modules + sage: L.is_ideal(L) # optional - sage.combinat sage.modules True - sage: F = LieAlgebra(QQ, 'F', representation='polynomial') - sage: L.is_ideal(F) + sage: F = LieAlgebra(QQ, 'F', representation='polynomial') # optional - sage.combinat sage.modules + sage: L.is_ideal(F) # optional - sage.combinat sage.modules Traceback (most recent call last): ... NotImplementedError: A must be a finite dimensional Lie algebra @@ -728,26 +731,27 @@ def quotient(self, I, names=None, category=None): The Engel Lie algebra as a quotient of the free nilpotent Lie algebra of step 3 with 2 generators:: - sage: L. = LieAlgebra(QQ, 2, step=3) - sage: E = L.quotient(U); E - Lie algebra quotient L/I of dimension 4 over Rational Field where - L: Free Nilpotent Lie algebra on 5 generators (X, Y, Z, W, U) over Rational Field - I: Ideal (U) - sage: E.basis().list() - [X, Y, Z, W] - sage: E(X).bracket(E(Y)) - Z - sage: Y.bracket(Z) - -U - sage: E(Y).bracket(E(Z)) - 0 - sage: E(U) - 0 + sage: L. = LieAlgebra(QQ, 2, step=3) # optional - sage.combinat sage.modules + sage: E = L.quotient(U); E # optional - sage.combinat sage.modules + Lie algebra quotient L/I of dimension 4 over Rational Field where + L: Free Nilpotent Lie algebra on 5 generators (X, Y, Z, W, U) + over Rational Field + I: Ideal (U) + sage: E.basis().list() # optional - sage.combinat sage.modules + [X, Y, Z, W] + sage: E(X).bracket(E(Y)) # optional - sage.combinat sage.modules + Z + sage: Y.bracket(Z) # optional - sage.combinat sage.modules + -U + sage: E(Y).bracket(E(Z)) # optional - sage.combinat sage.modules + 0 + sage: E(U) # optional - sage.combinat sage.modules + 0 Quotients when the base ring is not a field are not implemented:: - sage: L = lie_algebras.Heisenberg(ZZ, 1) - sage: L.quotient(L.an_element()) + sage: L = lie_algebras.Heisenberg(ZZ, 1) # optional - sage.combinat sage.modules + sage: L.quotient(L.an_element()) # optional - sage.combinat sage.modules Traceback (most recent call last): ... NotImplementedError: quotients over non-fields not implemented @@ -769,44 +773,46 @@ def product_space(self, L, submodule=False): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: a,b,c = L.lie_algebra_generators() - sage: X = L.subalgebra([a, b+c]) - sage: L.product_space(X) + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: a,b,c = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: X = L.subalgebra([a, b+c]) # optional - sage.combinat sage.modules + sage: L.product_space(X) # optional - sage.combinat sage.modules An example of a finite dimensional Lie algebra with basis: the 0-dimensional abelian Lie algebra over Rational Field - with basis matrix: - [] - sage: Y = L.subalgebra([a, 2*b-c]) - sage: X.product_space(Y) + with basis matrix: [] + sage: Y = L.subalgebra([a, 2*b-c]) # optional - sage.combinat sage.modules + sage: X.product_space(Y) # optional - sage.combinat sage.modules An example of a finite dimensional Lie algebra with basis: - the 0-dimensional abelian Lie algebra over Rational - Field with basis matrix: - [] + the 0-dimensional abelian Lie algebra over Rational Field + with basis matrix: [] :: - sage: H = lie_algebras.Heisenberg(ZZ, 4) - sage: Hp = H.product_space(H, submodule=True).basis() - sage: [H.from_vector(v) for v in Hp] + sage: H = lie_algebras.Heisenberg(ZZ, 4) # optional - sage.combinat sage.modules + sage: Hp = H.product_space(H, submodule=True).basis() # optional - sage.combinat sage.modules + sage: [H.from_vector(v) for v in Hp] # optional - sage.combinat sage.modules [z] :: - sage: L. = LieAlgebra(QQ, {('x','y'):{'x':1}}) - sage: Lp = L.product_space(L) # todo: not implemented - #17416 - sage: Lp # todo: not implemented - #17416 - Subalgebra generated of Lie algebra on 2 generators (x, y) over Rational Field with basis: - (x,) - sage: Lp.product_space(L) # todo: not implemented - #17416 - Subalgebra generated of Lie algebra on 2 generators (x, y) over Rational Field with basis: - (x,) - sage: L.product_space(Lp) # todo: not implemented - #17416 - Subalgebra generated of Lie algebra on 2 generators (x, y) over Rational Field with basis: - (x,) - sage: Lp.product_space(Lp) # todo: not implemented - #17416 - Subalgebra generated of Lie algebra on 2 generators (x, y) over Rational Field with basis: - () + sage: L. = LieAlgebra(QQ, {('x','y'):{'x':1}}) # optional - sage.combinat sage.modules + sage: Lp = L.product_space(L) # todo: not implemented - #17416 # optional - sage.combinat sage.modules + sage: Lp # todo: not implemented - #17416 # optional - sage.combinat sage.modules + Subalgebra generated of + Lie algebra on 2 generators (x, y) over Rational Field + with basis: (x,) + sage: Lp.product_space(L) # todo: not implemented - #17416 # optional - sage.combinat sage.modules + Subalgebra generated of + Lie algebra on 2 generators (x, y) over Rational Field + with basis: (x,) + sage: L.product_space(Lp) # todo: not implemented - #17416 # optional - sage.combinat sage.modules + Subalgebra generated of + Lie algebra on 2 generators (x, y) over Rational Field + with basis: (x,) + sage: Lp.product_space(Lp) # todo: not implemented - #17416 # optional - sage.combinat sage.modules + Subalgebra generated of + Lie algebra on 2 generators (x, y) over Rational Field + with basis: () """ from sage.matrix.constructor import matrix @@ -843,8 +849,8 @@ def derived_subalgebra(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.derived_subalgebra() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: L.derived_subalgebra() # optional - sage.combinat sage.modules An example of a finite dimensional Lie algebra with basis: the 0-dimensional abelian Lie algebra over Rational Field with basis matrix: @@ -852,10 +858,10 @@ def derived_subalgebra(self): If ``self`` is semisimple, then the derived subalgebra is ``self``:: - sage: sl3 = LieAlgebra(QQ, cartan_type=['A',2]) - sage: sl3.derived_subalgebra() + sage: sl3 = LieAlgebra(QQ, cartan_type=['A', 2]) # optional - sage.combinat sage.modules + sage: sl3.derived_subalgebra() # optional - sage.combinat sage.modules Lie algebra of ['A', 2] in the Chevalley basis - sage: sl3 is sl3.derived_subalgebra() + sage: sl3 is sl3.derived_subalgebra() # optional - sage.combinat sage.modules True """ @@ -894,24 +900,25 @@ def derived_series(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.derived_series() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: L.derived_series() # optional - sage.combinat sage.modules (An example of a finite dimensional Lie algebra with basis: the 3-dimensional abelian Lie algebra over Rational Field, An example of a finite dimensional Lie algebra with basis: the 0-dimensional abelian Lie algebra over Rational Field - with basis matrix: - []) + with basis matrix: []) :: - sage: L. = LieAlgebra(QQ, {('x','y'):{'x':1}}) - sage: L.derived_series() # todo: not implemented - #17416 + sage: L. = LieAlgebra(QQ, {('x','y'): {'x':1}}) # optional - sage.combinat sage.modules + sage: L.derived_series() # todo: not implemented - #17416 # optional - sage.combinat sage.modules (Lie algebra on 2 generators (x, y) over Rational Field, - Subalgebra generated of Lie algebra on 2 generators (x, y) over Rational Field with basis: - (x,), - Subalgebra generated of Lie algebra on 2 generators (x, y) over Rational Field with basis: - ()) + Subalgebra generated of + Lie algebra on 2 generators (x, y) over Rational Field + with basis: (x,), + Subalgebra generated of + Lie algebra on 2 generators (x, y) over Rational Field + with basis: ()) """ L = [self] while L[-1].dimension() > 0: @@ -952,31 +959,30 @@ def lower_central_series(self, submodule=False): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.derived_series() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: L.derived_series() # optional - sage.combinat sage.modules (An example of a finite dimensional Lie algebra with basis: - the 3-dimensional abelian Lie algebra over Rational Field, + the 3-dimensional abelian Lie algebra over Rational Field, An example of a finite dimensional Lie algebra with basis: - the 0-dimensional abelian Lie algebra over Rational Field - with basis matrix: - []) + the 0-dimensional abelian Lie algebra over Rational Field + with basis matrix: []) The lower central series as submodules:: - sage: L. = LieAlgebra(QQ, {('x','y'):{'x':1}}) - sage: L.lower_central_series(submodule=True) + sage: L. = LieAlgebra(QQ, {('x','y'): {'x':1}}) # optional - sage.combinat sage.modules + sage: L.lower_central_series(submodule=True) # optional - sage.combinat sage.modules (Sparse vector space of dimension 2 over Rational Field, - Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [1 0]) + Vector space of degree 2 and dimension 1 over Rational Field + Basis matrix: [1 0]) :: - sage: L. = LieAlgebra(QQ, {('x','y'):{'x':1}}) - sage: L.lower_central_series() # todo: not implemented - #17416 + sage: L. = LieAlgebra(QQ, {('x','y'): {'x':1}}) # optional - sage.combinat sage.modules + sage: L.lower_central_series() # todo: not implemented - #17416 # optional - sage.combinat sage.modules (Lie algebra on 2 generators (x, y) over Rational Field, - Subalgebra generated of Lie algebra on 2 generators (x, y) over Rational Field with basis: - (x,)) + Subalgebra generated of + Lie algebra on 2 generators (x, y) over Rational Field + with basis: (x,)) """ if submodule: L = [self.module()] @@ -995,14 +1001,14 @@ def is_abelian(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.is_abelian() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: L.is_abelian() # optional - sage.combinat sage.modules True :: - sage: L. = LieAlgebra(QQ, {('x','y'): {'x':1}}) - sage: L.is_abelian() + sage: L. = LieAlgebra(QQ, {('x','y'): {'x':1}}) # optional - sage.combinat sage.modules + sage: L.is_abelian() # optional - sage.combinat sage.modules False """ return len(self.structure_coefficients()) == 0 @@ -1018,14 +1024,14 @@ def is_solvable(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.is_solvable() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: L.is_solvable() # optional - sage.combinat sage.modules True :: - sage: L. = LieAlgebra(QQ, {('x','y'):{'x':1}}) - sage: L.is_solvable() # todo: not implemented - #17416 + sage: L. = LieAlgebra(QQ, {('x','y'): {'x':1}}) # optional - sage.combinat sage.modules + sage: L.is_solvable() # todo: not implemented - #17416 # optional - sage.combinat sage.modules False """ return not self.derived_series()[-1].dimension() @@ -1039,8 +1045,8 @@ def is_nilpotent(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.is_nilpotent() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: L.is_nilpotent() # optional - sage.combinat sage.modules True """ return not self.lower_central_series()[-1].dimension() @@ -1055,8 +1061,8 @@ def is_semisimple(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.is_semisimple() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: L.is_semisimple() # optional - sage.combinat sage.modules False """ return not self.killing_form_matrix().is_singular() @@ -1101,24 +1107,24 @@ def chevalley_eilenberg_complex(self, M=None, dual=False, sparse=True, ncpus=Non EXAMPLES:: - sage: L = lie_algebras.sl(ZZ, 2) - sage: C = L.chevalley_eilenberg_complex(); C + sage: L = lie_algebras.sl(ZZ, 2) # optional - sage.combinat sage.modules + sage: C = L.chevalley_eilenberg_complex(); C # optional - sage.combinat sage.modules Chain complex with at most 4 nonzero terms over Integer Ring - sage: ascii_art(C) + sage: ascii_art(C) # optional - sage.combinat sage.modules [ 2 0 0] [0] [ 0 -1 0] [0] [0 0 0] [ 0 0 2] [0] 0 <-- C_0 <-------- C_1 <----------- C_2 <---- C_3 <-- 0 - sage: L = LieAlgebra(QQ, cartan_type=['C',2]) - sage: C = L.chevalley_eilenberg_complex() # long time - sage: [C.free_module_rank(i) for i in range(11)] # long time + sage: L = LieAlgebra(QQ, cartan_type=['C',2]) # optional - sage.combinat sage.modules + sage: C = L.chevalley_eilenberg_complex() # long time # optional - sage.combinat sage.modules + sage: [C.free_module_rank(i) for i in range(11)] # long time # optional - sage.combinat sage.modules [1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1] - sage: g = lie_algebras.sl(QQ,2) - sage: E,F,H = g.basis() - sage: n = g.subalgebra([F,H]) - sage: ascii_art(n.chevalley_eilenberg_complex()) + sage: g = lie_algebras.sl(QQ, 2) # optional - sage.combinat sage.modules + sage: E, F, H = g.basis() # optional - sage.combinat sage.modules + sage: n = g.subalgebra([F, H]) # optional - sage.combinat sage.modules + sage: ascii_art(n.chevalley_eilenberg_complex()) # optional - sage.combinat sage.modules [0] [0 0] [2] 0 <-- C_0 <------ C_1 <---- C_2 <-- 0 @@ -1269,15 +1275,15 @@ def homology(self, deg=None, M=None, sparse=True, ncpus=None): EXAMPLES:: - sage: L = lie_algebras.cross_product(QQ) - sage: L.homology() + sage: L = lie_algebras.cross_product(QQ) # optional - sage.combinat sage.modules + sage: L.homology() # optional - sage.combinat sage.modules {0: Vector space of dimension 1 over Rational Field, 1: Vector space of dimension 0 over Rational Field, 2: Vector space of dimension 0 over Rational Field, 3: Vector space of dimension 1 over Rational Field} - sage: L = lie_algebras.pwitt(GF(5), 5) - sage: L.homology() + sage: L = lie_algebras.pwitt(GF(5), 5) # optional - sage.combinat sage.libs.pari sage.modules + sage: L.homology() # optional - sage.combinat sage.libs.pari sage.modules {0: Vector space of dimension 1 over Finite Field of size 5, 1: Vector space of dimension 0 over Finite Field of size 5, 2: Vector space of dimension 1 over Finite Field of size 5, @@ -1285,9 +1291,9 @@ def homology(self, deg=None, M=None, sparse=True, ncpus=None): 4: Vector space of dimension 0 over Finite Field of size 5, 5: Vector space of dimension 1 over Finite Field of size 5} - sage: d = {('x', 'y'): {'y': 2}} - sage: L. = LieAlgebra(ZZ, d) - sage: L.homology() + sage: d = {('x', 'y'): {'y': 2}} # optional - sage.combinat sage.modules + sage: L. = LieAlgebra(ZZ, d) # optional - sage.combinat sage.modules + sage: L.homology() # optional - sage.combinat sage.modules {0: Z, 1: Z x C2, 2: 0} .. SEEALSO:: @@ -1334,8 +1340,8 @@ def cohomology(self, deg=None, M=None, sparse=True, ncpus=None): EXAMPLES:: - sage: L = lie_algebras.so(QQ, 4) - sage: L.cohomology() + sage: L = lie_algebras.so(QQ, 4) # optional - sage.combinat sage.modules + sage: L.cohomology() # optional - sage.combinat sage.modules {0: Vector space of dimension 1 over Rational Field, 1: Vector space of dimension 0 over Rational Field, 2: Vector space of dimension 0 over Rational Field, @@ -1344,8 +1350,8 @@ def cohomology(self, deg=None, M=None, sparse=True, ncpus=None): 5: Vector space of dimension 0 over Rational Field, 6: Vector space of dimension 1 over Rational Field} - sage: L = lie_algebras.Heisenberg(QQ, 2) - sage: L.cohomology() + sage: L = lie_algebras.Heisenberg(QQ, 2) # optional - sage.combinat sage.modules + sage: L.cohomology() # optional - sage.combinat sage.modules {0: Vector space of dimension 1 over Rational Field, 1: Vector space of dimension 4 over Rational Field, 2: Vector space of dimension 5 over Rational Field, @@ -1353,9 +1359,9 @@ def cohomology(self, deg=None, M=None, sparse=True, ncpus=None): 4: Vector space of dimension 4 over Rational Field, 5: Vector space of dimension 1 over Rational Field} - sage: d = {('x', 'y'): {'y': 2}} - sage: L. = LieAlgebra(ZZ, d) - sage: L.cohomology() + sage: d = {('x', 'y'): {'y': 2}} # optional - sage.combinat sage.modules + sage: L. = LieAlgebra(ZZ, d) # optional - sage.combinat sage.modules + sage: L.cohomology() # optional - sage.combinat sage.modules {0: Z, 1: Z, 2: C2} .. SEEALSO:: @@ -1376,13 +1382,13 @@ def as_finite_dimensional_algebra(self): EXAMPLES:: - sage: L = lie_algebras.cross_product(QQ) - sage: x,y,z = L.basis() - sage: F = L.as_finite_dimensional_algebra() - sage: X,Y,Z = F.basis() - sage: x.bracket(y) + sage: L = lie_algebras.cross_product(QQ) # optional - sage.combinat sage.modules + sage: x, y, z = L.basis() # optional - sage.combinat sage.modules + sage: F = L.as_finite_dimensional_algebra() # optional - sage.combinat sage.modules + sage: X, Y, Z = F.basis() # optional - sage.combinat sage.modules + sage: x.bracket(y) # optional - sage.combinat sage.modules Z - sage: X * Y + sage: X * Y # optional - sage.combinat sage.modules Z """ from sage.matrix.constructor import matrix @@ -1436,9 +1442,10 @@ def morphism(self, on_generators, codomain=None, base_map=None, check=True): A quotient type Lie algebra morphism :: - sage: L. = LieAlgebra(QQ, {('X','Y'): {'Z':1}, ('X','Z'): {'W':1}}) - sage: K. = LieAlgebra(QQ, abelian=True) - sage: L.morphism({X: A, Y: B}) + sage: L. = LieAlgebra(QQ, {('X','Y'): {'Z': 1}, # optional - sage.combinat sage.modules + ....: ('X','Z'): {'W': 1}}) + sage: K. = LieAlgebra(QQ, abelian=True) # optional - sage.combinat sage.modules + sage: L.morphism({X: A, Y: B}) # optional - sage.combinat sage.modules Lie algebra morphism: From: Lie algebra on 4 generators (X, Y, Z, W) over Rational Field To: Abelian Lie algebra on 2 generators (A, B) over Rational Field @@ -1450,7 +1457,7 @@ def morphism(self, on_generators, codomain=None, base_map=None, check=True): The reverse map `A \mapsto X`, `B \mapsto Y` does not define a Lie algebra morphism, since `[A,B] = 0`, but `[X,Y] \neq 0`:: - sage: K.morphism({A:X, B: Y}) + sage: K.morphism({A:X, B: Y}) # optional - sage.combinat sage.modules Traceback (most recent call last): ... ValueError: this does not define a Lie algebra morphism; @@ -1460,15 +1467,16 @@ def morphism(self, on_generators, codomain=None, base_map=None, check=True): on the coefficients, even though it's not a Lie algebra morphism (since it isn't linear):: - sage: R. = ZZ[] - sage: K. = NumberField(x^2 + 1) - sage: cc = K.hom([-i]) - sage: L. = LieAlgebra(K, {('X','Y'): {'Z':1}, ('X','Z'): {'W':1}}) - sage: M. = LieAlgebra(K, abelian=True) - sage: phi = L.morphism({X: A, Y: B}, base_map=cc) - sage: phi(X) + sage: R. = ZZ[] # optional - sage.combinat sage.modules + sage: K. = NumberField(x^2 + 1) # optional - sage.combinat sage.modules sage.rings.number_fields + sage: cc = K.hom([-i]) # optional - sage.combinat sage.modules sage.rings.number_fields + sage: L. = LieAlgebra(K, {('X','Y'): {'Z': 1}, # optional - sage.combinat sage.modules sage.rings.number_fields + ....: ('X','Z'): {'W': 1}}) + sage: M. = LieAlgebra(K, abelian=True) # optional - sage.combinat sage.modules sage.rings.number_fields + sage: phi = L.morphism({X: A, Y: B}, base_map=cc) # optional - sage.combinat sage.modules sage.rings.number_fields + sage: phi(X) # optional - sage.combinat sage.modules sage.rings.number_fields A - sage: phi(i*X) + sage: phi(i*X) # optional - sage.combinat sage.modules sage.rings.number_fields -i*A """ from sage.algebras.lie_algebras.morphism import LieAlgebraMorphism_from_generators @@ -1497,13 +1505,13 @@ def universal_polynomials(self): EXAMPLES:: - sage: L. = LieAlgebra(QQ, {('x','y'): {'x':1}}) - sage: L.universal_polynomials() + sage: L. = LieAlgebra(QQ, {('x','y'): {'x':1}}) # optional - sage.combinat sage.modules + sage: L.universal_polynomials() # optional - sage.combinat sage.modules Finite family {('x', 'x', 'y'): X01*X10 - X00*X11 + X00, ('y', 'x', 'y'): X10} - sage: L = LieAlgebra(QQ, cartan_type=['A',1]) - sage: list(L.universal_polynomials()) + sage: L = LieAlgebra(QQ, cartan_type=['A',1]) # optional - sage.combinat sage.modules + sage: list(L.universal_polynomials()) # optional - sage.combinat sage.modules [-2*X01*X10 + 2*X00*X11 - 2*X00, -2*X02*X10 + 2*X00*X12 + X01, -2*X02*X11 + 2*X01*X12 - 2*X02, @@ -1514,13 +1522,13 @@ def universal_polynomials(self): -2*X12*X20 + 2*X10*X22 + X21, -2*X12*X21 + 2*X11*X22 - 2*X22] - sage: L = LieAlgebra(QQ, cartan_type=['B',2]) - sage: al = RootSystem(['B',2]).root_lattice().simple_roots() - sage: k = list(L.basis().keys())[0] - sage: UP = L.universal_polynomials() # long time - sage: len(UP) # long time + sage: L = LieAlgebra(QQ, cartan_type=['B', 2]) # optional - sage.combinat sage.modules + sage: al = RootSystem(['B', 2]).root_lattice().simple_roots() # optional - sage.combinat sage.modules + sage: k = list(L.basis().keys())[0] # optional - sage.combinat sage.modules + sage: UP = L.universal_polynomials() # long time # optional - sage.combinat sage.modules + sage: len(UP) # long time # optional - sage.combinat sage.modules 450 - sage: UP[al[2],al[1],-al[1]] # long time + sage: UP[al[2], al[1], -al[1]] # long time # optional - sage.combinat sage.modules X0_7*X4_1 - X0_1*X4_7 - 2*X0_7*X5_1 + 2*X0_1*X5_7 + X2_7*X7_1 - X2_1*X7_7 - X3_7*X8_1 + X3_1*X8_7 + X0_4 """ @@ -1574,12 +1582,12 @@ def universal_commutative_algebra(self): EXAMPLES:: - sage: L. = LieAlgebra(QQ, {('x','y'): {'x':1}}) - sage: A = L.universal_commutative_algebra() - sage: a,b,c,d = A.gens() - sage: (a,b,c,d) + sage: L. = LieAlgebra(QQ, {('x','y'): {'x':1}}) # optional - sage.combinat sage.modules + sage: A = L.universal_commutative_algebra() # optional - sage.combinat sage.modules + sage: a, b, c, d = A.gens() # optional - sage.combinat sage.modules + sage: a, b, c, d # optional - sage.combinat sage.modules (X00bar, X01bar, 0, X11bar) - sage: a*d - a + sage: a*d - a # optional - sage.combinat sage.modules 0 """ P = list(self.universal_polynomials()) @@ -1593,31 +1601,31 @@ def adjoint_matrix(self, sparse=False): # In #11111 (more or less) by using matr EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.an_element().adjoint_matrix() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: L.an_element().adjoint_matrix() # optional - sage.combinat sage.modules [0 0 0] [0 0 0] [0 0 0] - sage: L.an_element().adjoint_matrix(sparse=True).is_sparse() + sage: L.an_element().adjoint_matrix(sparse=True).is_sparse() # optional - sage.combinat sage.modules True :: - sage: L. = LieAlgebra(QQ, {('x','y'):{'x':1}}) - sage: x.adjoint_matrix() + sage: L. = LieAlgebra(QQ, {('x','y'): {'x':1}}) # optional - sage.combinat sage.modules + sage: x.adjoint_matrix() # optional - sage.combinat sage.modules [0 1] [0 0] - sage: y.adjoint_matrix() + sage: y.adjoint_matrix() # optional - sage.combinat sage.modules [-1 0] [ 0 0] We verify that this forms a representation:: - sage: sl3 = lie_algebras.sl(QQ, 3) - sage: e1, e2 = sl3.e(1), sl3.e(2) - sage: e12 = e1.bracket(e2) - sage: E1, E2 = e1.adjoint_matrix(), e2.adjoint_matrix() - sage: E1 * E2 - E2 * E1 == e12.adjoint_matrix() + sage: sl3 = lie_algebras.sl(QQ, 3) # optional - sage.combinat sage.modules + sage: e1, e2 = sl3.e(1), sl3.e(2) # optional - sage.combinat sage.modules + sage: e12 = e1.bracket(e2) # optional - sage.combinat sage.modules + sage: E1, E2 = e1.adjoint_matrix(), e2.adjoint_matrix() # optional - sage.combinat sage.modules + sage: E1 * E2 - E2 * E1 == e12.adjoint_matrix() # optional - sage.combinat sage.modules True """ from sage.matrix.constructor import matrix @@ -1640,16 +1648,16 @@ def to_vector(self, order=None, sparse=False): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.an_element().to_vector() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: L.an_element().to_vector() # optional - sage.combinat sage.modules (0, 0, 0) - sage: L.an_element().to_vector(sparse=True) + sage: L.an_element().to_vector(sparse=True) # optional - sage.combinat sage.modules (0, 0, 0) - sage: D = DescentAlgebra(QQ, 4).D() - sage: L = LieAlgebra(associative=D) - sage: L.an_element().to_vector() + sage: D = DescentAlgebra(QQ, 4).D() # optional - sage.combinat sage.modules + sage: L = LieAlgebra(associative=D) # optional - sage.combinat sage.modules + sage: L.an_element().to_vector() # optional - sage.combinat sage.modules (1, 1, 1, 1, 1, 1, 1, 1) TESTS: @@ -1657,13 +1665,13 @@ def to_vector(self, order=None, sparse=False): Check that the error raised agrees with the one from ``monomial_coefficients()`` (see :trac:`25007`):: - sage: L = lie_algebras.sp(QQ, 4, representation='matrix') - sage: x = L.an_element() - sage: x.monomial_coefficients() + sage: L = lie_algebras.sp(QQ, 4, representation='matrix') # optional - sage.combinat sage.modules + sage: x = L.an_element() # optional - sage.combinat sage.modules + sage: x.monomial_coefficients() # optional - sage.combinat sage.modules Traceback (most recent call last): ... NotImplementedError: the basis is not defined - sage: x.to_vector() + sage: x.to_vector() # optional - sage.combinat sage.modules Traceback (most recent call last): ... NotImplementedError: the basis is not defined @@ -1697,10 +1705,11 @@ def ambient(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: a, b, c = L.lie_algebra_generators() - sage: S = L.subalgebra([2*a+b, b + c]) - sage: S.ambient() == L + sage: C = LieAlgebras(QQ).FiniteDimensional().WithBasis() + sage: L = C.example() # optional - sage.combinat sage.modules + sage: a, b, c = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: S = L.subalgebra([2*a + b, b + c]) # optional - sage.combinat sage.modules + sage: S.ambient() == L # optional - sage.combinat sage.modules True """ @@ -1711,10 +1720,11 @@ def basis_matrix(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: a, b, c = L.lie_algebra_generators() - sage: S = L.subalgebra([2*a+b, b + c]) - sage: S.basis_matrix() + sage: C = LieAlgebras(QQ).FiniteDimensional().WithBasis() + sage: L = C.example() # optional - sage.combinat sage.modules + sage: a, b, c = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: S = L.subalgebra([2*a + b, b + c]) # optional - sage.combinat sage.modules + sage: S.basis_matrix() # optional - sage.combinat sage.modules [ 1 0 -1/2] [ 0 1 1] """ diff --git a/src/sage/categories/finite_dimensional_modules_with_basis.py b/src/sage/categories/finite_dimensional_modules_with_basis.py index 0ebca2f2dde..573aec237a1 100644 --- a/src/sage/categories/finite_dimensional_modules_with_basis.py +++ b/src/sage/categories/finite_dimensional_modules_with_basis.py @@ -46,8 +46,8 @@ def gens(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, ['a', 'b', 'c']) - sage: F.gens() + sage: F = CombinatorialFreeModule(ZZ, ['a', 'b', 'c']) # optional - sage.modules + sage: F.gens() # optional - sage.modules (B['a'], B['b'], B['c']) """ return tuple(self.basis()) @@ -91,35 +91,35 @@ def annihilator(self, S, action=operator.mul, side='right', category=None): EXAMPLES:: - sage: F = FiniteDimensionalAlgebrasWithBasis(QQ).example(); F + sage: F = FiniteDimensionalAlgebrasWithBasis(QQ).example(); F # optional - sage.modules An example of a finite dimensional algebra with basis: the path algebra of the Kronecker quiver (containing the arrows a:x->y and b:x->y) over Rational Field - sage: x,y,a,b = F.basis() - sage: A = F.annihilator([a + 3*b + 2*y]); A + sage: x, y, a, b = F.basis() # optional - sage.modules + sage: A = F.annihilator([a + 3*b + 2*y]); A # optional - sage.modules Free module generated by {0} over Rational Field - sage: [b.lift() for b in A.basis()] + sage: [b.lift() for b in A.basis()] # optional - sage.modules [-1/2*a - 3/2*b + x] The category can be used to specify other properties of this subspace, like that this is a subalgebra:: - sage: center = F.annihilator(F.basis(), F.bracket, + sage: center = F.annihilator(F.basis(), F.bracket, # optional - sage.modules ....: category=Algebras(QQ).Subobjects()) - sage: (e,) = center.basis() - sage: e.lift() + sage: (e,) = center.basis() # optional - sage.modules + sage: e.lift() # optional - sage.modules x + y - sage: e * e == e + sage: e * e == e # optional - sage.modules True Taking annihilator is order reversing for inclusion:: - sage: A = F.annihilator([]); A .rename("A") - sage: Ax = F.annihilator([x]); Ax .rename("Ax") - sage: Ay = F.annihilator([y]); Ay .rename("Ay") - sage: Axy = F.annihilator([x,y]); Axy.rename("Axy") - sage: P = Poset(([A, Ax, Ay, Axy], attrcall("is_submodule"))) - sage: sorted(P.cover_relations(), key=str) + sage: A = F.annihilator([]); A .rename("A") # optional - sage.modules + sage: Ax = F.annihilator([x]); Ax .rename("Ax") # optional - sage.modules + sage: Ay = F.annihilator([y]); Ay .rename("Ay") # optional - sage.modules + sage: Axy = F.annihilator([x,y]); Axy.rename("Axy") # optional - sage.modules + sage: P = Poset(([A, Ax, Ay, Axy], attrcall("is_submodule"))) # optional - sage.combinat sage.graphs sage.modules + sage: sorted(P.cover_relations(), key=str) # optional - sage.combinat sage.graphs sage.modules [[Ax, A], [Axy, Ax], [Axy, Ay], [Ay, A]] """ return self.submodule(self.annihilator_basis(S, action, side), @@ -204,7 +204,8 @@ def annihilator_basis(self, S, action=operator.mul, side='right'): compute the orthogonal of a subspace:: sage: x,y,a,b = F.basis() - sage: def scalar(u,v): return vector([sum(u[i]*v[i] for i in F.basis().keys())]) + sage: def scalar(u,v): + ....: return vector([sum(u[i]*v[i] for i in F.basis().keys())]) sage: F.annihilator_basis([x+y, a+b], scalar) (x - y, a - b) @@ -251,13 +252,13 @@ def _dense_free_module(self, base_ring=None): EXAMPLES:: - sage: C = CombinatorialFreeModule(QQ['x'], ['a','b','c']); C + sage: C = CombinatorialFreeModule(QQ['x'], ['a','b','c']); C # optional - sage.modules Free module generated by {'a', 'b', 'c'} over Univariate Polynomial Ring in x over Rational Field - sage: C._dense_free_module() + sage: C._dense_free_module() # optional - sage.modules Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - sage: C._dense_free_module(QQ['x,y']) + sage: C._dense_free_module(QQ['x,y']) # optional - sage.modules Ambient free module of rank 3 over the integral domain Multivariate Polynomial Ring in x, y over Rational Field """ @@ -272,11 +273,11 @@ def from_vector(self, vector, order=None, coerce=True): EXAMPLES:: - sage: p_mult = matrix([[0,0,0],[0,0,-1],[0,0,0]]) - sage: q_mult = matrix([[0,0,1],[0,0,0],[0,0,0]]) - sage: A = algebras.FiniteDimensional(QQ, [p_mult, q_mult, matrix(QQ,3,3)], - ....: 'p,q,z') - sage: A.from_vector(vector([1,0,2])) + sage: p_mult = matrix([[0,0,0], [0,0,-1], [0,0,0]]) # optional - sage.modules + sage: q_mult = matrix([[0,0,1], [0,0,0], [0,0,0]]) # optional - sage.modules + sage: A = algebras.FiniteDimensional( # optional - sage.combinat sage.modules + ....: QQ, [p_mult, q_mult, matrix(QQ, 3, 3)], 'p,q,z') + sage: A.from_vector(vector([1,0,2])) # optional - sage.combinat sage.modules p + 2*z """ if order is None: @@ -312,42 +313,42 @@ def echelon_form(self, elements, row_reduced=False, order=None): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x") - sage: x = X.basis() - sage: V = X.echelon_form([x[0]-x[1], x[0]-x[2],x[1]-x[2]]); V + sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x") # optional - sage.modules + sage: x = X.basis() # optional - sage.modules + sage: V = X.echelon_form([x[0]-x[1], x[0]-x[2], x[1]-x[2]]); V # optional - sage.modules [x[0] - x[2], x[1] - x[2]] - sage: matrix(list(map(vector, V))) + sage: matrix(list(map(vector, V))) # optional - sage.modules [ 1 0 -1] [ 0 1 -1] :: - sage: F = CombinatorialFreeModule(ZZ, [1,2,3,4]) - sage: B = F.basis() - sage: elements = [B[1]-17*B[2]+6*B[3], B[1]-17*B[2]+B[4]] - sage: F.echelon_form(elements) + sage: F = CombinatorialFreeModule(ZZ, [1,2,3,4]) # optional - sage.modules + sage: B = F.basis() # optional - sage.modules + sage: elements = [B[1]-17*B[2]+6*B[3], B[1]-17*B[2]+B[4]] # optional - sage.modules + sage: F.echelon_form(elements) # optional - sage.modules [B[1] - 17*B[2] + B[4], 6*B[3] - B[4]] :: - sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) - sage: a,b,c = F.basis() - sage: F.echelon_form([8*a+b+10*c, -3*a+b-c, a-b-c]) + sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) # optional - sage.modules + sage: a,b,c = F.basis() # optional - sage.modules + sage: F.echelon_form([8*a+b+10*c, -3*a+b-c, a-b-c]) # optional - sage.modules [B['a'] + B['c'], B['b'] + 2*B['c']] :: sage: R. = QQ[] - sage: C = CombinatorialFreeModule(R, range(3), prefix='x') - sage: x = C.basis() - sage: C.echelon_form([x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]]) + sage: C = CombinatorialFreeModule(R, range(3), prefix='x') # optional - sage.modules + sage: x = C.basis() # optional - sage.modules + sage: C.echelon_form([x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]]) # optional - sage.modules [x[0] - x[2], x[1] - x[2]] :: - sage: M = MatrixSpace(QQ, 3, 3) - sage: A = M([[0, 0, 2], [0, 0, 0], [0, 0, 0]]) - sage: M.echelon_form([A, A]) + sage: M = MatrixSpace(QQ, 3, 3) # optional - sage.modules + sage: A = M([[0, 0, 2], [0, 0, 0], [0, 0, 0]]) # optional - sage.modules + sage: M.echelon_form([A, A]) # optional - sage.modules [ [0 0 1] [0 0 0] @@ -358,8 +359,8 @@ def echelon_form(self, elements, row_reduced=False, order=None): We convert the input elements to ``self``:: - sage: E. = ExteriorAlgebra(QQ) - sage: E.echelon_form([1, x + 2]) + sage: E. = ExteriorAlgebra(QQ) # optional - sage.modules sage.combinat + sage: E.echelon_form([1, x + 2]) # optional - sage.modules sage.combinat [1, x] """ # Make sure elements consists of elements of ``self`` @@ -410,35 +411,37 @@ def invariant_module(self, S, action=operator.mul, action_on_basis=None, We build the invariant module of the permutation representation of the symmetric group:: - sage: G = SymmetricGroup(3); G.rename('S3') - sage: M = FreeModule(ZZ, [1,2,3], prefix='M'); M.rename('M') + sage: G = SymmetricGroup(3); G.rename('S3') # optional - sage.groups sage.modules + sage: M = FreeModule(ZZ, [1,2,3], prefix='M'); M.rename('M') # optional - sage.groups sage.modules sage: action = lambda g, x: M.term(g(x)) - sage: I = M.invariant_module(G, action_on_basis=action); I + sage: I = M.invariant_module(G, action_on_basis=action); I # optional - sage.groups sage.modules (S3)-invariant submodule of M - sage: I.basis() + sage: I.basis() # optional - sage.groups sage.modules Finite family {0: B[0]} - sage: [I.lift(b) for b in I.basis()] + sage: [I.lift(b) for b in I.basis()] # optional - sage.groups sage.modules [M[1] + M[2] + M[3]] - sage: G.rename(); M.rename() # reset the names + sage: G.rename(); M.rename() # reset the names # optional - sage.groups sage.modules We can construct the invariant module of any module that has an action of ``S``. In this example, we consider the dihedral group `G = D_4` and the subgroup `H < G` of all rotations. We construct the `H`-invariant module of the group algebra `\QQ[G]`:: - sage: G = groups.permutation.Dihedral(4) - sage: H = G.subgroup(G.gen(0)) - sage: H - Subgroup generated by [(1,2,3,4)] of (Dihedral group of order 8 as a permutation group) - sage: H.cardinality() + sage: G = groups.permutation.Dihedral(4) # optional - sage.groups + sage: H = G.subgroup(G.gen(0)) # optional - sage.groups + sage: H # optional - sage.groups + Subgroup generated by [(1,2,3,4)] + of (Dihedral group of order 8 as a permutation group) + sage: H.cardinality() # optional - sage.groups 4 - sage: A = G.algebra(QQ) - sage: I = A.invariant_module(H) - sage: [I.lift(b) for b in I.basis()] + sage: A = G.algebra(QQ) # optional - sage.groups sage.modules + sage: I = A.invariant_module(H) # optional - sage.groups sage.modules + sage: [I.lift(b) for b in I.basis()] # optional - sage.groups sage.modules [() + (1,2,3,4) + (1,3)(2,4) + (1,4,3,2), (2,4) + (1,2)(3,4) + (1,3) + (1,4)(2,3)] - sage: all(h * I.lift(b) == I.lift(b) for b in I.basis() for h in H) + sage: all(h * I.lift(b) == I.lift(b) # optional - sage.groups sage.modules + ....: for b in I.basis() for h in H) True """ if action_on_basis is not None: @@ -480,12 +483,13 @@ def twisted_invariant_module(self, G, chi, EXAMPLES:: - sage: M = CombinatorialFreeModule(QQ, [1,2,3]) - sage: G = SymmetricGroup(3) - sage: def action(g,x): return(M.term(g(x))) # permute coordinates - sage: T = M.twisted_invariant_module(G, [2,0,-1], action_on_basis=action) + sage: M = CombinatorialFreeModule(QQ, [1,2,3]) # optional - sage.groups sage.modules + sage: G = SymmetricGroup(3) # optional - sage.groups + sage: def action(g,x): return(M.term(g(x))) # permute coordinates + sage: T = M.twisted_invariant_module(G, [2,0,-1], # optional - sage.groups sage.modules + ....: action_on_basis=action) sage: import __main__; __main__.action = action - sage: TestSuite(T).run() + sage: TestSuite(T).run() # optional - sage.groups sage.modules """ if action_on_basis is not None: @@ -514,12 +518,12 @@ def dense_coefficient_list(self, order=None): EXAMPLES:: - sage: v = vector([0, -1, -3]) - sage: v.dense_coefficient_list() + sage: v = vector([0, -1, -3]) # optional - sage.modules + sage: v.dense_coefficient_list() # optional - sage.modules [0, -1, -3] - sage: v.dense_coefficient_list([2,1,0]) + sage: v.dense_coefficient_list([2,1,0]) # optional - sage.modules [-3, -1, 0] - sage: sorted(v.coefficients()) + sage: sorted(v.coefficients()) # optional - sage.modules [-3, -1] """ if order is None: @@ -535,11 +539,11 @@ def _vector_(self, order=None): EXAMPLES:: - sage: v = vector([0, -1, -3]) - sage: v._vector_() + sage: v = vector([0, -1, -3]) # optional - sage.modules + sage: v._vector_() # optional - sage.modules (0, -1, -3) - sage: C = CombinatorialFreeModule(QQ['x'], ['a','b','c']) - sage: C.an_element()._vector_() + sage: C = CombinatorialFreeModule(QQ['x'], ['a','b','c']) # optional - sage.modules + sage: C.an_element()._vector_() # optional - sage.modules (2, 2, 3) """ if order is None: @@ -577,30 +581,31 @@ def matrix(self, base_ring=None, side="left"): EXAMPLES:: - sage: X = CombinatorialFreeModule(ZZ, [1,2]); x = X.basis() - sage: Y = CombinatorialFreeModule(ZZ, [3,4]); y = Y.basis() - sage: phi = X.module_morphism(on_basis = {1: y[3] + 3*y[4], 2: 2*y[3] + 5*y[4]}.__getitem__, - ....: codomain = Y) - sage: phi.matrix() + sage: X = CombinatorialFreeModule(ZZ, [1,2]); x = X.basis() # optional - sage.modules + sage: Y = CombinatorialFreeModule(ZZ, [3,4]); y = Y.basis() # optional - sage.modules + sage: phi = X.module_morphism(on_basis={1: y[3] + 3*y[4], # optional - sage.modules + ....: 2: 2*y[3] + 5*y[4]}.__getitem__, + ....: codomain=Y) + sage: phi.matrix() # optional - sage.modules [1 2] [3 5] - sage: phi.matrix(side="right") + sage: phi.matrix(side="right") # optional - sage.modules [1 3] [2 5] - sage: phi.matrix().parent() + sage: phi.matrix().parent() # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: phi.matrix(QQ).parent() + sage: phi.matrix(QQ).parent() # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field The resulting matrix is immutable:: - sage: phi.matrix().is_mutable() + sage: phi.matrix().is_mutable() # optional - sage.modules False The zero morphism has a zero matrix:: - sage: Hom(X,Y).zero().matrix() + sage: Hom(X, Y).zero().matrix() # optional - sage.modules [0 0] [0 0] @@ -609,10 +614,11 @@ def matrix(self, base_ring=None, side="left"): Add support for morphisms where the codomain has a different base ring than the domain:: - sage: Y = CombinatorialFreeModule(QQ, [3,4]); y = Y.basis() - sage: phi = X.module_morphism(on_basis = {1: y[3] + 3*y[4], 2: 2*y[3] + 5/2*y[4]}.__getitem__, - ....: codomain = Y) - sage: phi.matrix().parent() # todo: not implemented + sage: Y = CombinatorialFreeModule(QQ, [3,4]); y = Y.basis() # optional - sage.modules + sage: phi = X.module_morphism(on_basis={1: y[3] + 3*y[4], # optional - sage.modules + ....: 2: 2*y[3] + 5/2*y[4]}.__getitem__, + ....: codomain=Y) + sage: phi.matrix().parent() # todo: not implemented # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field This currently does not work because, in this case, @@ -620,20 +626,20 @@ def matrix(self, base_ring=None, side="left"): additive groups (i.e. the intersection of the categories of modules over `\ZZ` and over `\QQ`):: - sage: phi.parent().homset_category() + sage: phi.parent().homset_category() # optional - sage.modules Category of commutative additive semigroups - sage: phi.parent().homset_category() # todo: not implemented + sage: phi.parent().homset_category() # todo: not implemented # optional - sage.modules Category of finite dimensional modules with basis over Integer Ring TESTS: Check that :trac:`23216` is fixed:: - sage: X = CombinatorialFreeModule(QQ, []) - sage: Y = CombinatorialFreeModule(QQ, [1,2,3]) - sage: Hom(X,Y).zero().matrix() + sage: X = CombinatorialFreeModule(QQ, []) # optional - sage.modules + sage: Y = CombinatorialFreeModule(QQ, [1,2,3]) # optional - sage.modules + sage: Hom(X, Y).zero().matrix() # optional - sage.modules [] - sage: Hom(X,Y).zero().matrix().parent() + sage: Hom(X, Y).zero().matrix().parent() # optional - sage.modules Full MatrixSpace of 3 by 0 dense matrices over Rational Field """ if base_ring is None: @@ -663,41 +669,41 @@ def __invert__(self): EXAMPLES:: sage: category = FiniteDimensionalModulesWithBasis(ZZ) - sage: X = CombinatorialFreeModule(ZZ, [1,2], category = category); X.rename("X"); x = X.basis() - sage: Y = CombinatorialFreeModule(ZZ, [3,4], category = category); Y.rename("Y"); y = Y.basis() - sage: phi = X.module_morphism(on_basis = {1: y[3] + 3*y[4], 2: 2*y[3] + 5*y[4]}.__getitem__, - ....: codomain = Y, category = category) - sage: psi = ~phi - sage: psi + sage: X = CombinatorialFreeModule(ZZ, [1,2], category=category); X.rename("X"); x = X.basis() # optional - sage.modules + sage: Y = CombinatorialFreeModule(ZZ, [3,4], category=category); Y.rename("Y"); y = Y.basis() # optional - sage.modules + sage: phi = X.module_morphism(on_basis={1: y[3] + 3*y[4], 2: 2*y[3] + 5*y[4]}.__getitem__, # optional - sage.modules + ....: codomain=Y, category=category) + sage: psi = ~phi # optional - sage.modules + sage: psi # optional - sage.modules Generic morphism: From: Y To: X - sage: psi.parent() + sage: psi.parent() # optional - sage.modules Set of Morphisms from Y to X in Category of finite dimensional modules with basis over Integer Ring - sage: psi(y[3]) + sage: psi(y[3]) # optional - sage.modules -5*B[1] + 3*B[2] - sage: psi(y[4]) + sage: psi(y[4]) # optional - sage.modules 2*B[1] - B[2] - sage: psi.matrix() + sage: psi.matrix() # optional - sage.modules [-5 2] [ 3 -1] - sage: psi(phi(x[1])), psi(phi(x[2])) + sage: psi(phi(x[1])), psi(phi(x[2])) # optional - sage.modules (B[1], B[2]) - sage: phi(psi(y[3])), phi(psi(y[4])) + sage: phi(psi(y[3])), phi(psi(y[4])) # optional - sage.modules (B[3], B[4]) We check that this function complains if the morphism is not invertible:: - sage: phi = X.module_morphism(on_basis = {1: y[3] + y[4], 2: y[3] + y[4]}.__getitem__, - ....: codomain = Y, category = category) - sage: ~phi + sage: phi = X.module_morphism(on_basis={1: y[3] + y[4], 2: y[3] + y[4]}.__getitem__, # optional - sage.modules + ....: codomain=Y, category=category) + sage: ~phi # optional - sage.modules Traceback (most recent call last): ... RuntimeError: morphism is not invertible - sage: phi = X.module_morphism(on_basis = {1: y[3] + y[4], 2: y[3] + 5*y[4]}.__getitem__, - ....: codomain = Y, category = category) - sage: ~phi + sage: phi = X.module_morphism(on_basis={1: y[3] + y[4], 2: y[3] + 5*y[4]}.__getitem__, # optional - sage.modules + ....: codomain=Y, category=category) + sage: ~phi # optional - sage.modules Traceback (most recent call last): ... RuntimeError: morphism is not invertible @@ -717,9 +723,9 @@ def kernel_basis(self): EXAMPLES:: - sage: SGA = SymmetricGroupAlgebra(QQ, 3) - sage: f = SGA.module_morphism(lambda x: SGA(x**2), codomain=SGA) - sage: f.kernel_basis() + sage: SGA = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: f = SGA.module_morphism(lambda x: SGA(x**2), codomain=SGA) # optional - sage.groups sage.modules + sage: f.kernel_basis() # optional - sage.groups sage.modules ([1, 2, 3] - [3, 2, 1], [1, 3, 2] - [3, 2, 1], [2, 1, 3] - [3, 2, 1]) """ return tuple(map( self.domain().from_vector, @@ -731,12 +737,12 @@ def kernel(self): EXAMPLES:: - sage: SGA = SymmetricGroupAlgebra(QQ, 3) - sage: f = SGA.module_morphism(lambda x: SGA(x**2), codomain=SGA) - sage: K = f.kernel() - sage: K + sage: SGA = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: f = SGA.module_morphism(lambda x: SGA(x**2), codomain=SGA) # optional - sage.groups sage.modules + sage: K = f.kernel() # optional - sage.groups sage.modules + sage: K # optional - sage.groups sage.modules Free module generated by {0, 1, 2} over Rational Field - sage: K.ambient() + sage: K.ambient() # optional - sage.groups sage.modules Symmetric group algebra of order 3 over Rational Field """ D = self.domain() @@ -749,9 +755,9 @@ def image_basis(self): EXAMPLES:: - sage: SGA = SymmetricGroupAlgebra(QQ, 3) - sage: f = SGA.module_morphism(lambda x: SGA(x**2), codomain=SGA) - sage: f.image_basis() + sage: SGA = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: f = SGA.module_morphism(lambda x: SGA(x**2), codomain=SGA) # optional - sage.groups sage.modules + sage: f.image_basis() # optional - sage.groups sage.modules ([1, 2, 3], [2, 3, 1], [3, 1, 2]) """ C = self.codomain() @@ -763,9 +769,9 @@ def image(self): EXAMPLES:: - sage: SGA = SymmetricGroupAlgebra(QQ, 3) - sage: f = SGA.module_morphism(lambda x: SGA(x**2), codomain=SGA) - sage: f.image() + sage: SGA = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups sage.modules + sage: f = SGA.module_morphism(lambda x: SGA(x**2), codomain=SGA) # optional - sage.groups sage.modules + sage: f.image() # optional - sage.groups sage.modules Free module generated by {0, 1, 2} over Rational Field """ C = self.codomain() @@ -781,10 +787,12 @@ def extra_super_categories(self): EXAMPLES:: - sage: ModulesWithBasis(ZZ).FiniteDimensional().TensorProducts().extra_super_categories() + sage: C = ModulesWithBasis(ZZ).FiniteDimensional().TensorProducts() + sage: C.extra_super_categories() [Category of finite dimensional modules with basis over Integer Ring] - sage: ModulesWithBasis(ZZ).FiniteDimensional().TensorProducts().FiniteDimensional() - Category of tensor products of finite dimensional modules with basis over Integer Ring + sage: C.FiniteDimensional() + Category of tensor products of + finite dimensional modules with basis over Integer Ring """ return [self.base_category()] diff --git a/src/sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py b/src/sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py index fe0ad9f3d21..d294ec75fae 100644 --- a/src/sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py @@ -60,16 +60,17 @@ def _test_nilpotency(self, **options): EXAMPLES:: - sage: L = LieAlgebra(QQ, {('X','Y'): {'Z': 1}}, nilpotent=True) - sage: L._test_nilpotency() - sage: L = LieAlgebra(QQ, {('X','Y'): {'Z': 1}}, - ....: nilpotent=True, step = 3) - sage: L._test_nilpotency() + sage: L = LieAlgebra(QQ, {('X','Y'): {'Z': 1}}, nilpotent=True) # optional - sage.combinat sage.modules + sage: L._test_nilpotency() # optional - sage.combinat sage.modules + sage: L = LieAlgebra(QQ, {('X','Y'): {'Z': 1}}, # optional - sage.combinat sage.modules + ....: nilpotent=True, step=3) + sage: L._test_nilpotency() # optional - sage.combinat sage.modules Traceback (most recent call last): ... - AssertionError: claimed nilpotency step 3 does not match the actual nilpotency step 2 - sage: L = LieAlgebra(QQ, {('X','Y'): {'X': 1}}, nilpotent=True) - sage: L._test_nilpotency() + AssertionError: claimed nilpotency step 3 + does not match the actual nilpotency step 2 + sage: L = LieAlgebra(QQ, {('X','Y'): {'X': 1}}, nilpotent=True) # optional - sage.combinat sage.modules + sage: L._test_nilpotency() # optional - sage.combinat sage.modules Traceback (most recent call last): ... AssertionError: final term of lower central series is non-zero @@ -100,28 +101,29 @@ def lie_group(self, name='G', **kwds): We define the Heisenberg group:: - sage: L = lie_algebras.Heisenberg(QQ, 1) - sage: G = L.lie_group('G'); G # optional - sage.symbolic + sage: L = lie_algebras.Heisenberg(QQ, 1) # optional - sage.combinat sage.modules + sage: G = L.lie_group('G'); G # optional - sage.combinat sage.modules sage.symbolic Lie group G of Heisenberg algebra of rank 1 over Rational Field We test multiplying elements of the group:: - sage: p,q,z = L.basis() # optional - sage.symbolic - sage: g = G.exp(p); g # optional - sage.symbolic + sage: p, q, z = L.basis() # optional - sage.combinat sage.modules sage.symbolic + sage: g = G.exp(p); g # optional - sage.combinat sage.modules sage.symbolic exp(p1) - sage: h = G.exp(q); h # optional - sage.symbolic + sage: h = G.exp(q); h # optional - sage.combinat sage.modules sage.symbolic exp(q1) - sage: g*h # optional - sage.symbolic + sage: g * h # optional - sage.combinat sage.modules sage.symbolic exp(p1 + q1 + 1/2*z) We extend an element of the Lie algebra to a left-invariant vector field:: - sage: X = G.left_invariant_extension(2*p + 3*q, name='X'); X # optional - sage.symbolic - Vector field X on the Lie group G of Heisenberg algebra of rank 1 over Rational Field - sage: X.at(G.one()).display() # optional - sage.symbolic + sage: X = G.left_invariant_extension(2*p + 3*q, name='X'); X # optional - sage.combinat sage.modules sage.symbolic + Vector field X on the Lie group G of + Heisenberg algebra of rank 1 over Rational Field + sage: X.at(G.one()).display() # optional - sage.combinat sage.modules sage.symbolic X = 2 ∂/∂x_0 + 3 ∂/∂x_1 - sage: X.display() # optional - sage.symbolic + sage: X.display() # optional - sage.combinat sage.modules sage.symbolic X = 2 ∂/∂x_0 + 3 ∂/∂x_1 + (3/2*x_0 - x_1) ∂/∂x_2 .. SEEALSO:: @@ -137,11 +139,11 @@ def step(self): EXAMPLES:: - sage: L = LieAlgebra(QQ, {('X','Y'): {'Z': 1}}, nilpotent=True) - sage: L.step() + sage: L = LieAlgebra(QQ, {('X','Y'): {'Z': 1}}, nilpotent=True) # optional - sage.combinat sage.modules + sage: L.step() # optional - sage.combinat sage.modules 2 - sage: sc = {('X','Y'): {'Z': 1}, ('X','Z'): {'W': 1}} - sage: LieAlgebra(QQ, sc, nilpotent=True).step() + sage: sc = {('X','Y'): {'Z': 1}, ('X','Z'): {'W': 1}} # optional - sage.combinat sage.modules + sage: LieAlgebra(QQ, sc, nilpotent=True).step() # optional - sage.combinat sage.modules 3 """ if not hasattr(self, '_step'): @@ -154,8 +156,8 @@ def is_nilpotent(self): EXAMPLES:: - sage: L = LieAlgebra(QQ, {('x','y'): {'z': 1}}, nilpotent=True) - sage: L.is_nilpotent() + sage: L = LieAlgebra(QQ, {('x','y'): {'z': 1}}, nilpotent=True) # optional - sage.combinat sage.modules + sage: L.is_nilpotent() # optional - sage.combinat sage.modules True """ return True diff --git a/src/sage/categories/finite_dimensional_semisimple_algebras_with_basis.py b/src/sage/categories/finite_dimensional_semisimple_algebras_with_basis.py index 59ab6a9a8ad..56303fc5eb0 100644 --- a/src/sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_semisimple_algebras_with_basis.py @@ -49,13 +49,13 @@ def radical_basis(self, **keywords): EXAMPLES:: - sage: A = SymmetricGroup(4).algebra(QQ) - sage: A.radical_basis() + sage: A = SymmetricGroup(4).algebra(QQ) # optional - sage.groups sage.modules + sage: A.radical_basis() # optional - sage.groups sage.modules () TESTS:: - sage: A.radical_basis.__module__ + sage: A.radical_basis.__module__ # optional - sage.groups sage.modules 'sage.categories.finite_dimensional_semisimple_algebras_with_basis' """ return () @@ -81,25 +81,25 @@ def central_orthogonal_idempotents(self): acts on `V_i` as multiplication by the `i`-th power of a cube root of unity:: - sage: R = CyclotomicField(3) - sage: A3 = AlternatingGroup(3).algebra(R) - sage: idempotents = A3.central_orthogonal_idempotents() - sage: idempotents + sage: R = CyclotomicField(3) # optional - sage.rings.number_field + sage: A3 = AlternatingGroup(3).algebra(R) # optional - sage.rings.number_field sage.groups + sage: idempotents = A3.central_orthogonal_idempotents() # optional - sage.rings.number_field sage.groups + sage: idempotents # optional - sage.rings.number_field sage.groups (1/3*() + 1/3*(1,2,3) + 1/3*(1,3,2), 1/3*() - (1/3*zeta3+1/3)*(1,2,3) - (-1/3*zeta3)*(1,3,2), 1/3*() - (-1/3*zeta3)*(1,2,3) - (1/3*zeta3+1/3)*(1,3,2)) - sage: A3.is_identity_decomposition_into_orthogonal_idempotents(idempotents) + sage: A3.is_identity_decomposition_into_orthogonal_idempotents(idempotents) # optional - sage.rings.number_field sage.groups True For the semisimple quotient of a quiver algebra, we recover the vertices of the quiver:: - sage: A = FiniteDimensionalAlgebrasWithBasis(QQ).example(); A + sage: A = FiniteDimensionalAlgebrasWithBasis(QQ).example(); A # optional - sage.combinat An example of a finite dimensional algebra with basis: the path algebra of the Kronecker quiver (containing the arrows a:x->y and b:x->y) over Rational Field - sage: Aquo = A.semisimple_quotient() - sage: Aquo.central_orthogonal_idempotents() + sage: Aquo = A.semisimple_quotient() # optional - sage.combinat + sage: Aquo.central_orthogonal_idempotents() # optional - sage.combinat (B['x'], B['y']) """ return tuple([x.lift() @@ -157,8 +157,8 @@ def _orthogonal_decomposition(self, generators=None): center of the algebra of the symmetric group `S_4`:: - sage: Z4 = SymmetricGroup(4).algebra(QQ).center() - sage: Z4._orthogonal_decomposition() + sage: Z4 = SymmetricGroup(4).algebra(QQ).center() # optional - sage.groups sage.modules + sage: Z4._orthogonal_decomposition() # optional - sage.groups sage.modules (B[0] + B[1] + B[2] + B[3] + B[4], B[0] + 1/3*B[1] - 1/3*B[2] - 1/3*B[4], B[0] + B[2] - 1/2*B[3], @@ -219,10 +219,10 @@ def central_orthogonal_idempotents(self): EXAMPLES:: - sage: A4 = SymmetricGroup(4).algebra(QQ) - sage: Z4 = A4.center() - sage: idempotents = Z4.central_orthogonal_idempotents() - sage: idempotents + sage: A4 = SymmetricGroup(4).algebra(QQ) # optional - sage.groups sage.modules + sage: Z4 = A4.center() # optional - sage.groups sage.modules + sage: idempotents = Z4.central_orthogonal_idempotents() # optional - sage.groups sage.modules + sage: idempotents # optional - sage.groups sage.modules (1/24*B[0] + 1/24*B[1] + 1/24*B[2] + 1/24*B[3] + 1/24*B[4], 3/8*B[0] + 1/8*B[1] - 1/8*B[2] - 1/8*B[4], 1/6*B[0] + 1/6*B[2] - 1/12*B[3], @@ -233,7 +233,7 @@ def central_orthogonal_idempotents(self): recognize among them the sum and alternating sum of all permutations:: - sage: [e.lift() for e in idempotents] + sage: [e.lift() for e in idempotents] # optional - sage.groups sage.modules [1/24*() + 1/24*(3,4) + 1/24*(2,3) + 1/24*(2,3,4) + 1/24*(2,4,3) + 1/24*(2,4) + 1/24*(1,2) + 1/24*(1,2)(3,4) + 1/24*(1,2,3) + 1/24*(1,2,3,4) + 1/24*(1,2,4,3) + 1/24*(1,2,4) + 1/24*(1,3,2) @@ -251,7 +251,7 @@ def central_orthogonal_idempotents(self): We check that they indeed form a decomposition of the identity of `Z_4` into orthogonal idempotents:: - sage: Z4.is_identity_decomposition_into_orthogonal_idempotents(idempotents) + sage: Z4.is_identity_decomposition_into_orthogonal_idempotents(idempotents) # optional - sage.groups sage.modules True """ return tuple([(e.leading_coefficient()/(e*e).leading_coefficient())*e diff --git a/src/sage/categories/finite_enumerated_sets.py b/src/sage/categories/finite_enumerated_sets.py index 4a872cf2fbf..4d90a3cd3f9 100644 --- a/src/sage/categories/finite_enumerated_sets.py +++ b/src/sage/categories/finite_enumerated_sets.py @@ -59,9 +59,9 @@ def _call_(self, X): EXAMPLES:: - sage: FiniteEnumeratedSets()(GF(3)) + sage: FiniteEnumeratedSets()(GF(3)) # optional - sage.rings.finite_rings Finite Field of size 3 - sage: Partitions(3) + sage: Partitions(3) # optional - sage.combinat Partitions of the integer 3 For now, lists, tuples, sets, Sets are coerced into finite @@ -86,9 +86,9 @@ def __len__(self): EXAMPLES:: - sage: len(GF(5)) + sage: len(GF(5)) # optional - sage.rings.finite_rings 5 - sage: len(MatrixSpace(GF(2), 3, 3)) + sage: len(MatrixSpace(GF(2), 3, 3)) # optional - sage.rings.finite_rings sage.modules 512 """ return int(self.cardinality()) @@ -590,17 +590,17 @@ class ParentMethods: inherit various methods from `Sets.CartesianProducts` and not from :class:`EnumeratedSets.Finite`:: - sage: C = cartesian_product([Partitions(10), Permutations(20)]) - sage: C in EnumeratedSets().Finite() + sage: C = cartesian_product([Partitions(10), Permutations(20)]) # optional - sage.combinat + sage: C in EnumeratedSets().Finite() # optional - sage.combinat True - sage: C.random_element.__module__ + sage: C.random_element.__module__ # optional - sage.combinat 'sage.categories.sets_cat' - sage: C.cardinality.__module__ + sage: C.cardinality.__module__ # optional - sage.combinat 'sage.categories.sets_cat' - sage: C.__iter__.__module__ + sage: C.__iter__.__module__ # optional - sage.combinat 'sage.categories.sets_cat' """ random_element = raw_getattr(Sets.CartesianProducts.ParentMethods, "random_element") @@ -613,8 +613,9 @@ def last(self): EXAMPLES:: - sage: C = cartesian_product([Zmod(42), Partitions(10), IntegerRange(5)]) - sage: C.last() + sage: C = cartesian_product([Zmod(42), Partitions(10), # optional - sage.combinat + ....: IntegerRange(5)]) + sage: C.last() # optional - sage.combinat (41, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 4) """ return self._cartesian_product_of_elements( @@ -635,13 +636,13 @@ def rank(self, x): EXAMPLES:: - sage: C = cartesian_product([GF(2), GF(11), GF(7)]) - sage: C.rank(C((1,2,5))) + sage: C = cartesian_product([GF(2), GF(11), GF(7)]) # optional - sage.rings.finite_rings + sage: C.rank(C((1,2,5))) # optional - sage.rings.finite_rings 96 - sage: C.rank(C((0,0,0))) + sage: C.rank(C((0,0,0))) # optional - sage.rings.finite_rings 0 - sage: for c in C: print(C.rank(c)) + sage: for c in C: print(C.rank(c)) # optional - sage.rings.finite_rings 0 1 2 @@ -656,12 +657,12 @@ def rank(self, x): sage: F1 = FiniteEnumeratedSet('abcdefgh') sage: F2 = IntegerRange(250) - sage: F3 = Partitions(20) - sage: C = cartesian_product([F1, F2, F3]) - sage: c = C(('a', 86, [7,5,4,4])) - sage: C.rank(c) + sage: F3 = Partitions(20) # optional - sage.combinat + sage: C = cartesian_product([F1, F2, F3]) # optional - sage.combinat + sage: c = C(('a', 86, [7,5,4,4])) # optional - sage.combinat + sage: C.rank(c) # optional - sage.combinat 54213 - sage: C.unrank(54213) + sage: C.unrank(54213) # optional - sage.combinat ('a', 86, [7, 5, 4, 4]) """ from builtins import zip @@ -691,18 +692,18 @@ def unrank(self, i): EXAMPLES:: - sage: C = cartesian_product([GF(3), GF(11), GF(7), GF(5)]) - sage: c = C.unrank(123); c + sage: C = cartesian_product([GF(3), GF(11), GF(7), GF(5)]) # optional - sage.rings.finite_rings + sage: c = C.unrank(123); c # optional - sage.rings.finite_rings (0, 3, 3, 3) - sage: C.rank(c) + sage: C.rank(c) # optional - sage.rings.finite_rings 123 - sage: c = C.unrank(857); c + sage: c = C.unrank(857); c # optional - sage.rings.finite_rings (2, 2, 3, 2) - sage: C.rank(c) + sage: C.rank(c) # optional - sage.rings.finite_rings 857 - sage: C.unrank(2500) + sage: C.unrank(2500) # optional - sage.rings.finite_rings Traceback (most recent call last): ... IndexError: index i (=2) is greater than the cardinality diff --git a/src/sage/categories/finite_fields.py b/src/sage/categories/finite_fields.py index 25a93c8b960..b685a249780 100644 --- a/src/sage/categories/finite_fields.py +++ b/src/sage/categories/finite_fields.py @@ -34,7 +34,7 @@ class FiniteFields(CategoryWithAxiom): Some examples of membership testing and coercion:: - sage: FiniteField(17) in K + sage: FiniteField(17) in K # optional - sage.rings.finite_rings True sage: RationalField() in K False @@ -67,7 +67,7 @@ def __contains__(self, x): """ EXAMPLES:: - sage: GF(4, "a") in FiniteFields() + sage: GF(4, "a") in FiniteFields() # optional - sage.rings.finite_rings True sage: QQ in FiniteFields() False @@ -82,7 +82,7 @@ def _call_(self, x): """ EXAMPLES:: - sage: FiniteFields()(GF(4, "a")) + sage: FiniteFields()(GF(4, "a")) # optional - sage.rings.finite_rings Finite Field in a of size 2^2 sage: FiniteFields()(RationalField()) # indirect doctest Traceback (most recent call last): diff --git a/src/sage/categories/finite_groups.py b/src/sage/categories/finite_groups.py index 42415233567..1d0e7d72357 100644 --- a/src/sage/categories/finite_groups.py +++ b/src/sage/categories/finite_groups.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.groups r""" Finite groups """ diff --git a/src/sage/categories/finite_lattice_posets.py b/src/sage/categories/finite_lattice_posets.py index 4b7f0fb9b28..1bb0de98fad 100644 --- a/src/sage/categories/finite_lattice_posets.py +++ b/src/sage/categories/finite_lattice_posets.py @@ -49,8 +49,8 @@ def join_irreducibles(self): EXAMPLES:: - sage: L = LatticePoset({0:[1,2],1:[3],2:[3,4],3:[5],4:[5]}) - sage: L.join_irreducibles() + sage: L = LatticePoset({0:[1,2],1:[3],2:[3,4],3:[5],4:[5]}) # optional - sage.combinat sage.graphs + sage: L.join_irreducibles() # optional - sage.combinat sage.graphs [1, 2, 4] .. SEEALSO:: @@ -71,8 +71,8 @@ def join_irreducibles_poset(self): EXAMPLES:: - sage: L = LatticePoset({0:[1,2,3],1:[4],2:[4],3:[4]}) - sage: L.join_irreducibles_poset() + sage: L = LatticePoset({0:[1,2,3],1:[4],2:[4],3:[4]}) # optional - sage.combinat sage.graphs + sage: L.join_irreducibles_poset() # optional - sage.combinat sage.graphs Finite poset containing 3 elements .. SEEALSO:: @@ -92,8 +92,8 @@ def meet_irreducibles(self): EXAMPLES:: - sage: L = LatticePoset({0:[1,2],1:[3],2:[3,4],3:[5],4:[5]}) - sage: L.meet_irreducibles() + sage: L = LatticePoset({0:[1,2],1:[3],2:[3,4],3:[5],4:[5]}) # optional - sage.combinat sage.graphs + sage: L.meet_irreducibles() # optional - sage.combinat sage.graphs [1, 3, 4] .. SEEALSO:: @@ -114,8 +114,8 @@ def meet_irreducibles_poset(self): EXAMPLES:: - sage: L = LatticePoset({0:[1,2,3],1:[4],2:[4],3:[4]}) - sage: L.join_irreducibles_poset() + sage: L = LatticePoset({0:[1,2,3],1:[4],2:[4],3:[4]}) # optional - sage.combinat sage.graphs + sage: L.join_irreducibles_poset() # optional - sage.combinat sage.graphs Finite poset containing 3 elements .. SEEALSO:: @@ -143,20 +143,20 @@ def irreducibles_poset(self): EXAMPLES:: - sage: L = LatticePoset({1: [2, 3, 4], 2: [5, 6], 3: [5], + sage: L = LatticePoset({1: [2, 3, 4], 2: [5, 6], 3: [5], # optional - sage.combinat sage.graphs ....: 4: [6], 5: [9, 7], 6: [9, 8], 7: [10], ....: 8: [10], 9: [10], 10: [11]}) - sage: L_ = L.irreducibles_poset() - sage: sorted(L_) + sage: L_ = L.irreducibles_poset() # optional - sage.combinat sage.graphs + sage: sorted(L_) # optional - sage.combinat sage.graphs [2, 3, 4, 7, 8, 9, 10, 11] - sage: L_.completion_by_cuts().is_isomorphic(L) + sage: L_.completion_by_cuts().is_isomorphic(L) # optional - sage.combinat sage.graphs True TESTS:: - sage: LatticePoset().irreducibles_poset() + sage: LatticePoset().irreducibles_poset() # optional - sage.combinat sage.graphs Finite poset containing 0 elements - sage: posets.ChainPoset(1).irreducibles_poset() + sage: posets.ChainPoset(1).irreducibles_poset() # optional - sage.combinat sage.graphs Finite poset containing 1 elements """ if self.cardinality() == 1: @@ -191,35 +191,36 @@ def is_lattice_morphism(self, f, codomain): lattice of divisors of `60`, and check that the map `b \mapsto 5 \prod_{x\in b} x` is a morphism of lattices:: - sage: D = LatticePoset((divisors(60), attrcall("divides"))) - sage: B = LatticePoset((Subsets([2,2,3]), attrcall("issubset"))) - sage: def f(b): return D(5*prod(b)) - sage: B.is_lattice_morphism(f, D) + sage: D = LatticePoset((divisors(60), attrcall("divides"))) # optional - sage.combinat sage.graphs + sage: B = LatticePoset((Subsets([2,2,3]), attrcall("issubset"))) # optional - sage.combinat sage.graphs + sage: def f(b): return D(5*prod(b)) # optional - sage.combinat sage.graphs + sage: B.is_lattice_morphism(f, D) # optional - sage.combinat sage.graphs True We construct the boolean lattice `B_2`:: - sage: B = posets.BooleanLattice(2) - sage: B.cover_relations() + sage: B = posets.BooleanLattice(2) # optional - sage.combinat sage.graphs + sage: B.cover_relations() # optional - sage.combinat sage.graphs [[0, 1], [0, 2], [1, 3], [2, 3]] And the same lattice with new top and bottom elements numbered respectively `-1` and `3`:: - sage: L = LatticePoset(DiGraph({-1:[0], 0:[1,2], 1:[3], 2:[3],3:[4]})) - sage: L.cover_relations() + sage: G = DiGraph({-1:[0], 0:[1,2], 1:[3], 2:[3], 3:[4]}) # optional - sage.graphs + sage: L = LatticePoset(G) # optional - sage.combinat sage.graphs + sage: L.cover_relations() # optional - sage.combinat sage.graphs [[-1, 0], [0, 1], [0, 2], [1, 3], [2, 3], [3, 4]] - sage: f = { B(0): L(0), B(1): L(1), B(2): L(2), B(3): L(3) }.__getitem__ - sage: B.is_lattice_morphism(f, L) + sage: f = {B(0): L(0), B(1): L(1), B(2): L(2), B(3): L(3)}.__getitem__ # optional - sage.combinat sage.graphs + sage: B.is_lattice_morphism(f, L) # optional - sage.combinat sage.graphs True - sage: f = { B(0): L(-1),B(1): L(1), B(2): L(2), B(3): L(3) }.__getitem__ - sage: B.is_lattice_morphism(f, L) + sage: f = {B(0): L(-1),B(1): L(1), B(2): L(2), B(3): L(3)}.__getitem__ # optional - sage.combinat sage.graphs + sage: B.is_lattice_morphism(f, L) # optional - sage.combinat sage.graphs False - sage: f = { B(0): L(0), B(1): L(1), B(2): L(2), B(3): L(4) }.__getitem__ - sage: B.is_lattice_morphism(f, L) + sage: f = {B(0): L(0), B(1): L(1), B(2): L(2), B(3): L(4)}.__getitem__ # optional - sage.combinat sage.graphs + sage: B.is_lattice_morphism(f, L) # optional - sage.combinat sage.graphs False .. SEEALSO:: diff --git a/src/sage/categories/finite_monoids.py b/src/sage/categories/finite_monoids.py index fdf1db47a71..9531b671249 100644 --- a/src/sage/categories/finite_monoids.py +++ b/src/sage/categories/finite_monoids.py @@ -72,9 +72,9 @@ def nerve(self): The nerve (classifying space) of the cyclic group of order 2 is infinite-dimensional real projective space. :: - sage: Sigma2 = groups.permutation.Cyclic(2) - sage: BSigma2 = Sigma2.nerve() - sage: BSigma2.cohomology(4, base_ring=GF(2)) + sage: Sigma2 = groups.permutation.Cyclic(2) # optional - sage.groups + sage: BSigma2 = Sigma2.nerve() # optional - sage.groups + sage: BSigma2.cohomology(4, base_ring=GF(2)) # optional - sage.groups sage.modules sage.rings.finite_rings Vector space of dimension 1 over Finite Field of size 2 The `k`-simplices of the nerve are named after the chains @@ -83,45 +83,45 @@ def nerve(self): element) and ``(1,2)`` in Sage. So the 1-cells and 2-cells in `B\Sigma_2` are:: - sage: BSigma2.n_cells(1) + sage: BSigma2.n_cells(1) # optional - sage.groups [(1,2)] - sage: BSigma2.n_cells(2) + sage: BSigma2.n_cells(2) # optional - sage.groups [(1,2) * (1,2)] Another construction of the group, with different names for its elements:: - sage: C2 = groups.misc.MultiplicativeAbelian([2]) - sage: BC2 = C2.nerve() - sage: BC2.n_cells(0) + sage: C2 = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: BC2 = C2.nerve() # optional - sage.groups + sage: BC2.n_cells(0) # optional - sage.groups [1] - sage: BC2.n_cells(1) + sage: BC2.n_cells(1) # optional - sage.groups [f] - sage: BC2.n_cells(2) + sage: BC2.n_cells(2) # optional - sage.groups [f * f] With mod `p` coefficients, `B \Sigma_p` should have its first nonvanishing homology group in dimension `p`:: - sage: Sigma3 = groups.permutation.Symmetric(3) - sage: BSigma3 = Sigma3.nerve() - sage: BSigma3.homology(range(4), base_ring=GF(3)) + sage: Sigma3 = groups.permutation.Symmetric(3) # optional - sage.groups + sage: BSigma3 = Sigma3.nerve() # optional - sage.groups + sage: BSigma3.homology(range(4), base_ring=GF(3)) # optional - sage.groups sage.rings.finite_rings {0: Vector space of dimension 0 over Finite Field of size 3, - 1: Vector space of dimension 0 over Finite Field of size 3, - 2: Vector space of dimension 0 over Finite Field of size 3, - 3: Vector space of dimension 1 over Finite Field of size 3} + 1: Vector space of dimension 0 over Finite Field of size 3, + 2: Vector space of dimension 0 over Finite Field of size 3, + 3: Vector space of dimension 1 over Finite Field of size 3} Note that we can construct the `n`-skeleton for `B\Sigma_2` for relatively large values of `n`, while for `B\Sigma_3`, the complexes get large pretty quickly:: - sage: Sigma2.nerve().n_skeleton(14) + sage: Sigma2.nerve().n_skeleton(14) # optional - sage.groups Simplicial set with 15 non-degenerate simplices - sage: BSigma3 = Sigma3.nerve() - sage: BSigma3.n_skeleton(3) + sage: BSigma3 = Sigma3.nerve() # optional - sage.groups + sage: BSigma3.n_skeleton(3) # optional - sage.groups Simplicial set with 156 non-degenerate simplices - sage: BSigma3.n_skeleton(4) + sage: BSigma3.n_skeleton(4) # optional - sage.groups Simplicial set with 781 non-degenerate simplices Finally, note that the classifying space of the order `p` @@ -129,33 +129,33 @@ def nerve(self): on `p` letters, and its first homology group appears earlier:: - sage: C3 = groups.misc.MultiplicativeAbelian([3]) - sage: list(C3) + sage: C3 = groups.misc.MultiplicativeAbelian([3]) # optional - sage.groups + sage: list(C3) # optional - sage.groups [1, f, f^2] - sage: BC3 = C3.nerve() - sage: BC3.n_cells(1) + sage: BC3 = C3.nerve() # optional - sage.groups + sage: BC3.n_cells(1) # optional - sage.groups [f, f^2] - sage: BC3.n_cells(2) + sage: BC3.n_cells(2) # optional - sage.groups [f * f, f * f^2, f^2 * f, f^2 * f^2] - sage: len(BSigma3.n_cells(2)) + sage: len(BSigma3.n_cells(2)) # optional - sage.groups 25 - sage: len(BC3.n_cells(3)) + sage: len(BC3.n_cells(3)) # optional - sage.groups 8 - sage: len(BSigma3.n_cells(3)) + sage: len(BSigma3.n_cells(3)) # optional - sage.groups 125 - sage: BC3.homology(range(4), base_ring=GF(3)) + sage: BC3.homology(range(4), base_ring=GF(3)) # optional - sage.groups sage.rings.finite_rings {0: Vector space of dimension 0 over Finite Field of size 3, 1: Vector space of dimension 1 over Finite Field of size 3, 2: Vector space of dimension 1 over Finite Field of size 3, 3: Vector space of dimension 1 over Finite Field of size 3} - sage: BC5 = groups.permutation.Cyclic(5).nerve() - sage: BC5.homology(range(4), base_ring=GF(5)) + sage: BC5 = groups.permutation.Cyclic(5).nerve() # optional - sage.groups + sage: BC5.homology(range(4), base_ring=GF(5)) # optional - sage.groups sage.rings.finite_rings {0: Vector space of dimension 0 over Finite Field of size 5, - 1: Vector space of dimension 1 over Finite Field of size 5, - 2: Vector space of dimension 1 over Finite Field of size 5, - 3: Vector space of dimension 1 over Finite Field of size 5} + 1: Vector space of dimension 1 over Finite Field of size 5, + 2: Vector space of dimension 1 over Finite Field of size 5, + 3: Vector space of dimension 1 over Finite Field of size 5} """ from sage.topology.simplicial_set_examples import Nerve return Nerve(self) @@ -179,20 +179,20 @@ def rhodes_radical_congruence(self, base_ring=None): EXAMPLES:: sage: M = Monoids().Finite().example() - sage: M.rhodes_radical_congruence() + sage: M.rhodes_radical_congruence() # optional - sage.groups sage.modules [(0, 6), (2, 8), (4, 10)] - sage: from sage.monoids.hecke_monoid import HeckeMonoid - sage: H3 = HeckeMonoid(SymmetricGroup(3)) - sage: H3.repr_element_method(style="reduced") - sage: H3.rhodes_radical_congruence() + sage: from sage.monoids.hecke_monoid import HeckeMonoid # optional - sage.groups sage.modules + sage: H3 = HeckeMonoid(SymmetricGroup(3)) # optional - sage.groups sage.modules + sage: H3.repr_element_method(style="reduced") # optional - sage.groups sage.modules + sage: H3.rhodes_radical_congruence() # optional - sage.groups sage.modules [([1, 2], [2, 1]), ([1, 2], [1, 2, 1]), ([2, 1], [1, 2, 1])] By Maschke's theorem, every group algebra over `\QQ` is semisimple hence the Rhodes radical of a group must be trivial:: - sage: SymmetricGroup(3).rhodes_radical_congruence() + sage: SymmetricGroup(3).rhodes_radical_congruence() # optional - sage.groups sage.modules [] - sage: DihedralGroup(10).rhodes_radical_congruence() + sage: DihedralGroup(10).rhodes_radical_congruence() # optional - sage.groups sage.modules [] REFERENCES: diff --git a/src/sage/categories/finite_permutation_groups.py b/src/sage/categories/finite_permutation_groups.py index 59c00471e3f..e081d2d4f63 100644 --- a/src/sage/categories/finite_permutation_groups.py +++ b/src/sage/categories/finite_permutation_groups.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.groups r""" Finite Permutation Groups """ diff --git a/src/sage/categories/finite_posets.py b/src/sage/categories/finite_posets.py index b5422adfd4e..263033a2c9b 100644 --- a/src/sage/categories/finite_posets.py +++ b/src/sage/categories/finite_posets.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.graphs r""" Finite posets diff --git a/src/sage/categories/finite_semigroups.py b/src/sage/categories/finite_semigroups.py index a7f9b9a20a1..e9c31e1ad62 100644 --- a/src/sage/categories/finite_semigroups.py +++ b/src/sage/categories/finite_semigroups.py @@ -51,7 +51,8 @@ class FiniteSemigroups(CategoryWithAxiom): sage: sorted(C.axioms()) ['Associative', 'Finite'] sage: C.example() - An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd') + An example of a finite semigroup: + the left regular band generated by ('a', 'b', 'c', 'd') TESTS:: @@ -86,8 +87,9 @@ def j_classes(self): EXAMPLES:: sage: S = FiniteSemigroups().example(alphabet=('a','b', 'c')) - sage: sorted(map(sorted, S.j_classes())) - [['a'], ['ab', 'ba'], ['abc', 'acb', 'bac', 'bca', 'cab', 'cba'], ['ac', 'ca'], ['b'], ['bc', 'cb'], ['c']] + sage: sorted(map(sorted, S.j_classes())) # optional - sage.graphs + [['a'], ['ab', 'ba'], ['abc', 'acb', 'bac', 'bca', 'cab', 'cba'], + ['ac', 'ca'], ['b'], ['bc', 'cb'], ['c']] """ return self.cayley_graph(side="twosided", simple=True).strongly_connected_components() @@ -103,8 +105,9 @@ def j_classes_of_idempotents(self): EXAMPLES:: sage: S = FiniteSemigroups().example(alphabet=('a','b', 'c')) - sage: sorted(map(sorted, S.j_classes_of_idempotents())) - [['a'], ['ab', 'ba'], ['abc', 'acb', 'bac', 'bca', 'cab', 'cba'], ['ac', 'ca'], ['b'], ['bc', 'cb'], ['c']] + sage: sorted(map(sorted, S.j_classes_of_idempotents())) # optional - sage.graphs + [['a'], ['ab', 'ba'], ['abc', 'acb', 'bac', 'bca', 'cab', 'cba'], + ['ac', 'ca'], ['b'], ['bc', 'cb'], ['c']] """ return [l for l in ([x for x in cl if attrcall('is_idempotent')(x)] for cl in self.j_classes()) if len(l) > 0] @@ -120,7 +123,7 @@ def j_transversal_of_idempotents(self): The chosen elements depend on the order of each `J`-class, and that order is random when using Python 3. :: - sage: sorted(S.j_transversal_of_idempotents()) # random + sage: sorted(S.j_transversal_of_idempotents()) # random # optional - sage.graphs ['a', 'ab', 'abc', 'ac', 'b', 'c', 'cb'] """ def first_idempotent(l): diff --git a/src/sage/categories/finite_weyl_groups.py b/src/sage/categories/finite_weyl_groups.py index 4420827c833..1d1d0250c23 100644 --- a/src/sage/categories/finite_weyl_groups.py +++ b/src/sage/categories/finite_weyl_groups.py @@ -27,7 +27,7 @@ class FiniteWeylGroups(CategoryWithAxiom): TESTS:: sage: W = FiniteWeylGroups().example() - sage: TestSuite(W).run() + sage: TestSuite(W).run() # optional - sage.combinat """ class ParentMethods: diff --git a/src/sage/categories/finitely_generated_lambda_bracket_algebras.py b/src/sage/categories/finitely_generated_lambda_bracket_algebras.py index 8877491e33e..85315805fad 100644 --- a/src/sage/categories/finitely_generated_lambda_bracket_algebras.py +++ b/src/sage/categories/finitely_generated_lambda_bracket_algebras.py @@ -27,7 +27,7 @@ class FinitelyGeneratedLambdaBracketAlgebras(CategoryWithAxiom_over_base_ring): EXAMPLES:: sage: from sage.categories.lambda_bracket_algebras import LambdaBracketAlgebras - sage: LambdaBracketAlgebras(QQbar).FinitelyGenerated() + sage: LambdaBracketAlgebras(QQbar).FinitelyGenerated() # optional - sage.rings.number_field Category of finitely generated lambda bracket algebras over Algebraic Field """ _base_category_class_and_axiom = (LambdaBracketAlgebras, "FinitelyGeneratedAsLambdaBracketAlgebra") @@ -38,12 +38,12 @@ def ngens(self): EXAMPLES:: - sage: Vir = lie_conformal_algebras.Virasoro(QQ) - sage: Vir.ngens() + sage: Vir = lie_conformal_algebras.Virasoro(QQ) # optional - sage.combinat sage.modules + sage: Vir.ngens() # optional - sage.combinat sage.modules 2 - sage: V = lie_conformal_algebras.Affine(QQ, 'A2') - sage: V.ngens() + sage: V = lie_conformal_algebras.Affine(QQ, 'A2') # optional - sage.combinat sage.modules + sage: V.ngens() # optional - sage.combinat sage.modules 9 """ return len(self.gens()) @@ -54,12 +54,12 @@ def gen(self,i): EXAMPLES:: - sage: V = lie_conformal_algebras.Affine(QQ, 'A1') - sage: V.gens() + sage: V = lie_conformal_algebras.Affine(QQ, 'A1') # optional - sage.combinat sage.modules + sage: V.gens() # optional - sage.combinat sage.modules (B[alpha[1]], B[alphacheck[1]], B[-alpha[1]], B['K']) - sage: V.gen(0) + sage: V.gen(0) # optional - sage.combinat sage.modules B[alpha[1]] - sage: V.1 + sage: V.1 # optional - sage.combinat sage.modules B[alphacheck[1]] """ return self.gens()[i] @@ -73,10 +73,11 @@ def some_elements(self): EXAMPLES:: - sage: V = lie_conformal_algebras.Affine(QQ, 'A1', names=('e', 'h', 'f')) - sage: V.some_elements() + sage: V = lie_conformal_algebras.Affine(QQ, 'A1', # optional - sage.combinat sage.modules + ....: names=('e', 'h', 'f')) + sage: V.some_elements() # optional - sage.combinat sage.modules [e, h, f, K, ...] - sage: all(v.parent() is V for v in V.some_elements()) + sage: all(v.parent() is V for v in V.some_elements()) # optional - sage.combinat sage.modules True """ S = list(self.gens()) @@ -91,8 +92,9 @@ class Graded(GradedModulesCategory): EXAMPLES:: - sage: LieConformalAlgebras(QQbar).FinitelyGenerated().Graded() - Category of H-graded finitely generated lie conformal algebras over Algebraic Field + sage: LieConformalAlgebras(QQbar).FinitelyGenerated().Graded() # optional - sage.rings.number_field + Category of H-graded finitely generated lie conformal algebras + over Algebraic Field """ def _repr_object_names(self): """ @@ -100,7 +102,7 @@ def _repr_object_names(self): EXAMPLES:: - sage: LieConformalAlgebras(QQbar).WithBasis().FinitelyGenerated().Graded() + sage: LieConformalAlgebras(QQbar).WithBasis().FinitelyGenerated().Graded() # optional - sage.rings.number_field Category of H-graded finitely generated Lie conformal algebras with basis over Algebraic Field """ return "H-graded {}".format(self.base_category()._repr_object_names()) diff --git a/src/sage/categories/finitely_generated_lie_conformal_algebras.py b/src/sage/categories/finitely_generated_lie_conformal_algebras.py index 464d1eb7d03..96433749aa4 100644 --- a/src/sage/categories/finitely_generated_lie_conformal_algebras.py +++ b/src/sage/categories/finitely_generated_lie_conformal_algebras.py @@ -27,7 +27,7 @@ class FinitelyGeneratedLieConformalAlgebras(CategoryWithAxiom_over_base_ring): EXAMPLES:: - sage: LieConformalAlgebras(QQbar).FinitelyGenerated() + sage: LieConformalAlgebras(QQbar).FinitelyGenerated() # optional - sage.rings.number_field Category of finitely generated lie conformal algebras over Algebraic Field """ _base_category_class_and_axiom = (LieConformalAlgebras, "FinitelyGeneratedAsLambdaBracketAlgebra") @@ -43,10 +43,11 @@ def some_elements(self): EXAMPLES:: - sage: V = lie_conformal_algebras.Affine(QQ, 'A1', names=('e', 'h', 'f')) - sage: V.some_elements() + sage: V = lie_conformal_algebras.Affine(QQ, 'A1', # optional - sage.combinat sage.modules + ....: names=('e', 'h', 'f')) + sage: V.some_elements() # optional - sage.combinat sage.modules [e, h, f, K, ...] - sage: all(v.parent() is V for v in V.some_elements()) + sage: all(v.parent() is V for v in V.some_elements()) # optional - sage.combinat sage.modules True """ S = list(self.gens()) @@ -61,8 +62,9 @@ class Super(SuperModulesCategory): EXAMPLES:: - sage: LieConformalAlgebras(AA).FinitelyGenerated().Super() - Category of super finitely generated lie conformal algebras over Algebraic Real Field + sage: LieConformalAlgebras(AA).FinitelyGenerated().Super() # optional - sage.rings.number_field + Category of super finitely generated lie conformal algebras + over Algebraic Real Field """ class Graded(GradedModulesCategory): """ @@ -70,8 +72,9 @@ class Graded(GradedModulesCategory): EXAMPLES:: - sage: LieConformalAlgebras(QQbar).FinitelyGenerated().Super().Graded() - Category of H-graded super finitely generated lie conformal algebras over Algebraic Field + sage: LieConformalAlgebras(QQbar).FinitelyGenerated().Super().Graded() # optional - sage.rings.number_field + Category of H-graded super finitely generated lie conformal algebras + over Algebraic Field """ def _repr_object_names(self): """ @@ -79,9 +82,10 @@ def _repr_object_names(self): EXAMPLES:: - sage: C = LieConformalAlgebras(QQbar).FinitelyGenerated() - sage: C.Super().Graded() - Category of H-graded super finitely generated lie conformal algebras over Algebraic Field + sage: C = LieConformalAlgebras(QQbar).FinitelyGenerated() # optional - sage.rings.number_field + sage: C.Super().Graded() # optional - sage.rings.number_field + Category of H-graded super finitely generated + lie conformal algebras over Algebraic Field """ return "H-graded {}".format(self.base_category()._repr_object_names()) @@ -91,8 +95,9 @@ class Graded(GradedModulesCategory): EXAMPLES:: - sage: LieConformalAlgebras(QQbar).FinitelyGenerated().Graded() - Category of H-graded finitely generated lie conformal algebras over Algebraic Field + sage: LieConformalAlgebras(QQbar).FinitelyGenerated().Graded() # optional - sage.rings.number_field + Category of H-graded finitely generated lie conformal algebras + over Algebraic Field """ def _repr_object_names(self): """ @@ -100,7 +105,8 @@ def _repr_object_names(self): EXAMPLES:: - sage: LieConformalAlgebras(QQbar).WithBasis().FinitelyGenerated().Graded() - Category of H-graded finitely generated Lie conformal algebras with basis over Algebraic Field + sage: LieConformalAlgebras(QQbar).WithBasis().FinitelyGenerated().Graded() # optional - sage.rings.number_field + Category of H-graded finitely generated Lie conformal algebras with basis + over Algebraic Field """ return "H-graded {}".format(self.base_category()._repr_object_names()) diff --git a/src/sage/categories/functor.pyx b/src/sage/categories/functor.pyx index a0e8b42e1bf..58ff4cb21bf 100644 --- a/src/sage/categories/functor.pyx +++ b/src/sage/categories/functor.pyx @@ -112,12 +112,12 @@ cdef class Functor(SageObject): this behaviour. Here we illustrate the default:: sage: from sage.categories.functor import Functor - sage: F = Functor(Rings(),Fields()) + sage: F = Functor(Rings(), Fields()) sage: F Functor from Category of rings to Category of fields sage: F(ZZ) Rational Field - sage: F(GF(2)) + sage: F(GF(2)) # optional - sage.rings.finite_rings Finite Field of size 2 Functors are not only about the objects of a category, but also about @@ -128,7 +128,7 @@ cdef class Functor(SageObject): sage: R1. = ZZ[] sage: R2. = QQ[] - sage: f = R1.hom([a+b],R2) + sage: f = R1.hom([a + b], R2) sage: f Ring morphism: From: Univariate Polynomial Ring in x over Integer Ring @@ -150,8 +150,10 @@ cdef class Functor(SageObject): Poly[t] sage: F(f) Ring morphism: - From: Univariate Polynomial Ring in t over Univariate Polynomial Ring in x over Integer Ring - To: Univariate Polynomial Ring in t over Multivariate Polynomial Ring in a, b over Rational Field + From: Univariate Polynomial Ring in t + over Univariate Polynomial Ring in x over Integer Ring + To: Univariate Polynomial Ring in t + over Multivariate Polynomial Ring in a, b over Rational Field Defn: Induced from base ring by Ring morphism: From: Univariate Polynomial Ring in x over Integer Ring @@ -159,7 +161,8 @@ cdef class Functor(SageObject): Defn: x |--> a + b sage: p = R1['t']('(-x^2 + x)*t^2 + (x^2 - x)*t - 4*x^2 - x + 1') sage: F(f)(p) - (-a^2 - 2*a*b - b^2 + a + b)*t^2 + (a^2 + 2*a*b + b^2 - a - b)*t - 4*a^2 - 8*a*b - 4*b^2 - a - b + 1 + (-a^2 - 2*a*b - b^2 + a + b)*t^2 + (a^2 + 2*a*b + b^2 - a - b)*t + - 4*a^2 - 8*a*b - 4*b^2 - a - b + 1 """ def __init__(self, domain, codomain): @@ -167,12 +170,12 @@ cdef class Functor(SageObject): TESTS:: sage: from sage.categories.functor import Functor - sage: F = Functor(Rings(),Fields()) + sage: F = Functor(Rings(), Fields()) sage: F Functor from Category of rings to Category of fields sage: F(ZZ) Rational Field - sage: F(GF(2)) + sage: F(GF(2)) # optional - sage.rings.finite_rings Finite Field of size 2 """ @@ -228,7 +231,7 @@ cdef class Functor(SageObject): TESTS:: sage: from sage.categories.functor import Functor - sage: F = Functor(FiniteFields(),Fields()) + sage: F = Functor(FiniteFields(), Fields()) sage: F._apply_functor(ZZ) Rational Field @@ -248,20 +251,22 @@ cdef class Functor(SageObject): TESTS:: sage: from sage.categories.functor import Functor - sage: F = Functor(Rings(),Fields()) - sage: k. = GF(25) - sage: f = k.hom([-a-4]) - sage: R. = k[] - sage: fR = R.hom(f,R) - sage: fF = F(fR) # indirect doctest - sage: fF - Ring endomorphism of Fraction Field of Univariate Polynomial Ring in t over Finite Field in a of size 5^2 + sage: F = Functor(Rings(), Fields()) + sage: k. = GF(25) # optional - sage.rings.finite_rings + sage: f = k.hom([-a - 4]) # optional - sage.rings.finite_rings + sage: R. = k[] # optional - sage.rings.finite_rings + sage: fR = R.hom(f, R) # optional - sage.rings.finite_rings + sage: fF = F(fR) # indirect doctest # optional - sage.rings.finite_rings + sage: fF # optional - sage.rings.finite_rings + Ring endomorphism of Fraction Field of + Univariate Polynomial Ring in t over Finite Field in a of size 5^2 Defn: Induced from base ring by - Ring endomorphism of Univariate Polynomial Ring in t over Finite Field in a of size 5^2 + Ring endomorphism of Univariate Polynomial Ring in t + over Finite Field in a of size 5^2 Defn: Induced from base ring by Ring endomorphism of Finite Field in a of size 5^2 Defn: a |--> 4*a + 1 - sage: fF((a^2+a)*t^2/(a*t - a^2)) + sage: fF((a^2+a)*t^2/(a*t - a^2)) # optional - sage.rings.finite_rings ((4*a + 2)*t^2)/(t + a + 4) """ @@ -334,13 +339,13 @@ cdef class Functor(SageObject): Functor from Category of rings to Category of fields sage: F(ZZ) Rational Field - sage: F(GF(2)) + sage: F(GF(2)) # optional - sage.rings.finite_rings Finite Field of size 2 Two subclasses:: - sage: F1 = ForgetfulFunctor(FiniteFields(),Fields()) - sage: F1(GF(5)) #indirect doctest + sage: F1 = ForgetfulFunctor(FiniteFields(), Fields()) + sage: F1(GF(5)) # indirect doctest # optional - sage.rings.finite_rings Finite Field of size 5 sage: F1(ZZ) Traceback (most recent call last): @@ -352,7 +357,8 @@ cdef class Functor(SageObject): sage: F2(ZZ['x','y']) Traceback (most recent call last): ... - TypeError: x (=Multivariate Polynomial Ring in x, y over Integer Ring) is not in Category of fields + TypeError: x (=Multivariate Polynomial Ring in x, y over Integer Ring) + is not in Category of fields The last example shows that it is tested whether the result of applying the functor lies in the functor's codomain. Note that @@ -360,20 +366,22 @@ cdef class Functor(SageObject): which was fixed in :trac:`8807`:: sage: class IllFunctor(Functor): - ....: def __init__(self, m,n): + ....: def __init__(self, m, n): ....: self._m = m ....: self._n = n - ....: Functor.__init__(self,Rings(),Rings()) + ....: Functor.__init__(self, Rings(), Rings()) ....: def _apply_functor(self, R): - ....: return MatrixSpace(R,self._m,self._n) - sage: F = IllFunctor(2,2) - sage: F(QQ) + ....: return MatrixSpace(R, self._m, self._n) + sage: F = IllFunctor(2, 2) + sage: F(QQ) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: F = IllFunctor(2,3) - sage: F(QQ) + sage: F = IllFunctor(2, 3) + sage: F(QQ) # optional - sage.modules Traceback (most recent call last): ... - TypeError: Functor from Category of rings to Category of rings is ill-defined, since it sends x (=Rational Field) to something that is not in Category of rings. + TypeError: Functor from Category of rings to Category of rings + is ill-defined, since it sends x (=Rational Field) to something + that is not in Category of rings. """ from sage.categories.morphism import is_Morphism @@ -390,7 +398,7 @@ cdef class Functor(SageObject): EXAMPLES:: - sage: F = ForgetfulFunctor(FiniteFields(),Fields()) + sage: F = ForgetfulFunctor(FiniteFields(), Fields()) sage: F.domain() Category of finite enumerated fields @@ -403,7 +411,7 @@ cdef class Functor(SageObject): EXAMPLES:: - sage: F = ForgetfulFunctor(FiniteFields(),Fields()) + sage: F = ForgetfulFunctor(FiniteFields(), Fields()) sage: F.codomain() Category of fields @@ -456,10 +464,12 @@ class ForgetfulFunctor_generic(Functor): EXAMPLES:: - sage: F = ForgetfulFunctor(FiniteFields(),Fields()) #indirect doctest + sage: F = ForgetfulFunctor(FiniteFields(), Fields()) # indirect doctest sage: F - The forgetful functor from Category of finite enumerated fields to Category of fields - sage: F(GF(3)) + The forgetful functor + from Category of finite enumerated fields + to Category of fields + sage: F(GF(3)) # optional - sage.rings.finite_rings Finite Field of size 3 """ @@ -477,9 +487,10 @@ class ForgetfulFunctor_generic(Functor): """ TESTS:: - sage: F = ForgetfulFunctor(FiniteFields(),Fields()) - sage: F #indirect doctest - The forgetful functor from Category of finite enumerated fields to Category of fields + sage: F = ForgetfulFunctor(FiniteFields(), Fields()) + sage: F # indirect doctest + The forgetful functor from Category of finite enumerated fields + to Category of fields """ return "The forgetful functor from %s to %s" % (self.domain(), @@ -497,7 +508,7 @@ class ForgetfulFunctor_generic(Functor): TESTS:: - sage: F1 = ForgetfulFunctor(FiniteFields(),Fields()) + sage: F1 = ForgetfulFunctor(FiniteFields(), Fields()) This is to test against a bug occurring in a previous version (see :trac:`8800`):: @@ -524,7 +535,7 @@ class ForgetfulFunctor_generic(Functor): EXAMPLES:: - sage: F1 = ForgetfulFunctor(FiniteFields(),Fields()) + sage: F1 = ForgetfulFunctor(FiniteFields(), Fields()) sage: F1 != F1 False sage: F1 != QQ @@ -665,14 +676,17 @@ def ForgetfulFunctor(domain, codomain): sage: abgrps = CommutativeAdditiveGroups() sage: F = ForgetfulFunctor(rings, abgrps) sage: F - The forgetful functor from Category of rings to Category of commutative additive groups + The forgetful functor + from Category of rings + to Category of commutative additive groups It would be a mistake to call it in opposite order:: sage: F = ForgetfulFunctor(abgrps, rings) Traceback (most recent call last): ... - ValueError: Forgetful functor not supported for domain Category of commutative additive groups + ValueError: Forgetful functor not supported for domain + Category of commutative additive groups If both categories are equal, the forgetful functor is the same as the identity functor:: diff --git a/src/sage/categories/g_sets.py b/src/sage/categories/g_sets.py index b9447203e42..0f8004ddbf0 100644 --- a/src/sage/categories/g_sets.py +++ b/src/sage/categories/g_sets.py @@ -23,8 +23,8 @@ class GSets(Category): EXAMPLES:: - sage: S = SymmetricGroup(3) - sage: GSets(S) + sage: S = SymmetricGroup(3) # optional - sage.groups + sage: GSets(S) # optional - sage.groups Category of G-sets for Symmetric group of order 3! as a permutation group TODO: should this derive from Category_over_base? @@ -33,8 +33,8 @@ def __init__(self, G): """ TESTS:: - sage: S8 = SymmetricGroup(8) - sage: TestSuite(GSets(S8)).run() + sage: S8 = SymmetricGroup(8) # optional - sage.groups + sage: TestSuite(GSets(S8)).run() # optional - sage.groups """ Category.__init__(self) self.__G = G @@ -43,7 +43,7 @@ def _repr_object_names(self): """ EXAMPLES:: - sage: GSets(SymmetricGroup(8)) # indirect doctests + sage: GSets(SymmetricGroup(8)) # indirect doctests # optional - sage.groups Category of G-sets for Symmetric group of order 8! as a permutation group """ return "G-sets for %s"%self.__G @@ -55,7 +55,7 @@ def super_categories(self): """ EXAMPLES:: - sage: GSets(SymmetricGroup(8)).super_categories() + sage: GSets(SymmetricGroup(8)).super_categories() # optional - sage.groups [Category of sets] """ return [Sets()] @@ -67,7 +67,7 @@ def an_instance(cls): EXAMPLES:: - sage: GSets.an_instance() # indirect doctest + sage: GSets.an_instance() # indirect doctest # optional - sage.groups Category of G-sets for Symmetric group of order 8! as a permutation group """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup diff --git a/src/sage/categories/graded_algebras.py b/src/sage/categories/graded_algebras.py index 54ce5775c9e..efa1a501192 100644 --- a/src/sage/categories/graded_algebras.py +++ b/src/sage/categories/graded_algebras.py @@ -39,8 +39,8 @@ def graded_algebra(self): EXAMPLES:: - sage: m = SymmetricFunctions(QQ).m() - sage: m.graded_algebra() is m + sage: m = SymmetricFunctions(QQ).m() # optional - sage.combinat + sage: m.graded_algebra() is m # optional - sage.combinat True """ return self diff --git a/src/sage/categories/graded_algebras_with_basis.py b/src/sage/categories/graded_algebras_with_basis.py index b4df3c3c260..52d80b78b4e 100644 --- a/src/sage/categories/graded_algebras_with_basis.py +++ b/src/sage/categories/graded_algebras_with_basis.py @@ -46,8 +46,8 @@ def graded_algebra(self): EXAMPLES:: - sage: m = SymmetricFunctions(QQ).m() - sage: m.graded_algebra() is m + sage: m = SymmetricFunctions(QQ).m() # optional - sage.combinat + sage: m.graded_algebra() is m # optional - sage.combinat sage.modules True TESTS: @@ -57,21 +57,21 @@ def graded_algebra(self): and :meth:`projection` (which form the interface of the associated graded algebra) work correctly here:: - sage: to_gr = m.to_graded_conversion() - sage: from_gr = m.from_graded_conversion() - sage: m[2] == to_gr(m[2]) == from_gr(m[2]) + sage: to_gr = m.to_graded_conversion() # optional - sage.combinat sage.modules + sage: from_gr = m.from_graded_conversion() # optional - sage.combinat sage.modules + sage: m[2] == to_gr(m[2]) == from_gr(m[2]) # optional - sage.combinat sage.modules True - sage: u = 3*m[1] - (1/2)*m[3] - sage: u == to_gr(u) == from_gr(u) + sage: u = 3*m[1] - (1/2)*m[3] # optional - sage.combinat sage.modules + sage: u == to_gr(u) == from_gr(u) # optional - sage.combinat sage.modules True - sage: m.zero() == to_gr(m.zero()) == from_gr(m.zero()) + sage: m.zero() == to_gr(m.zero()) == from_gr(m.zero()) # optional - sage.combinat sage.modules True - sage: p2 = m.projection(2) - sage: p2(m[2] - 4*m[1,1] + 3*m[1] - 2*m[[]]) + sage: p2 = m.projection(2) # optional - sage.combinat sage.modules + sage: p2(m[2] - 4*m[1,1] + 3*m[1] - 2*m[[]]) # optional - sage.combinat sage.modules -4*m[1, 1] + m[2] - sage: p2(4*m[1]) + sage: p2(4*m[1]) # optional - sage.combinat sage.modules 0 - sage: p2(m.zero()) == m.zero() + sage: p2(m.zero()) == m.zero() # optional - sage.combinat sage.modules True """ return self @@ -111,13 +111,13 @@ def free_graded_module(self, generator_degrees, names=None): EXAMPLES:: - sage: Q = QuadraticForm(QQ, 3, [1,2,3,4,5,6]) - sage: Cl = CliffordAlgebra(Q) - sage: M = Cl.free_graded_module((0, 2, 3)) - sage: M.gens() + sage: Q = QuadraticForm(QQ, 3, [1,2,3,4,5,6]) # optional - sage.modules + sage: Cl = CliffordAlgebra(Q) # optional - sage.combinat sage.modules + sage: M = Cl.free_graded_module((0, 2, 3)) # optional - sage.combinat sage.modules + sage: M.gens() # optional - sage.combinat sage.modules (g[0], g[2], g[3]) - sage: N. = Cl.free_graded_module((1, 2)) - sage: N.generators() + sage: N. = Cl.free_graded_module((1, 2)) # optional - sage.combinat sage.modules + sage: N.generators() # optional - sage.combinat sage.modules (xy, z) """ try: @@ -134,10 +134,10 @@ def formal_series_ring(self): EXAMPLES:: - sage: NCSF = NonCommutativeSymmetricFunctions(QQ) - sage: S = NCSF.Complete() - sage: L = S.formal_series_ring() - sage: L + sage: NCSF = NonCommutativeSymmetricFunctions(QQ) # optional - sage.combinat + sage: S = NCSF.Complete() # optional - sage.combinat + sage: L = S.formal_series_ring() # optional - sage.combinat + sage: L # optional - sage.combinat Lazy completion of Non-Commutative Symmetric Functions over the Rational Field in the Complete basis """ @@ -185,13 +185,13 @@ def one_basis(self): EXAMPLES:: - sage: A. = ExteriorAlgebra(QQ) - sage: A.one_basis() + sage: A. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: A.one_basis() # optional - sage.combinat sage.modules 0 - sage: B = tensor((A, A, A)) - sage: B.one_basis() + sage: B = tensor((A, A, A)) # optional - sage.combinat sage.modules + sage: B.one_basis() # optional - sage.combinat sage.modules (0, 0, 0) - sage: B.one() + sage: B.one() # optional - sage.combinat sage.modules 1 # 1 # 1 """ # FIXME: this method should be conditionally defined, @@ -211,10 +211,10 @@ def product_on_basis(self, t0, t1): Test the sign in the super tensor product:: - sage: A = SteenrodAlgebra(3) - sage: x = A.Q(0) - sage: y = x.coproduct() - sage: y^2 + sage: A = SteenrodAlgebra(3) # optional - sage.combinat sage.modules + sage: x = A.Q(0) # optional - sage.combinat sage.modules + sage: y = x.coproduct() # optional - sage.combinat sage.modules + sage: y^2 # optional - sage.combinat sage.modules 0 TODO: optimize this implementation! diff --git a/src/sage/categories/graded_hopf_algebras_with_basis.py b/src/sage/categories/graded_hopf_algebras_with_basis.py index d806597ae0c..204ab23013e 100644 --- a/src/sage/categories/graded_hopf_algebras_with_basis.py +++ b/src/sage/categories/graded_hopf_algebras_with_basis.py @@ -44,7 +44,7 @@ def example(self): TESTS:: - sage: GradedHopfAlgebrasWithBasis(QQ).example() + sage: GradedHopfAlgebrasWithBasis(QQ).example() # optional - sage.modules An example of a graded connected Hopf algebra with basis over Rational Field """ from sage.categories.examples.graded_connected_hopf_algebras_with_basis import \ @@ -85,7 +85,7 @@ def example(self): TESTS:: - sage: GradedHopfAlgebrasWithBasis(QQ).Connected().example() + sage: GradedHopfAlgebrasWithBasis(QQ).Connected().example() # optional - sage.modules An example of a graded connected Hopf algebra with basis over Rational Field """ from sage.categories.examples.graded_connected_hopf_algebras_with_basis import \ @@ -114,10 +114,10 @@ def counit_on_basis(self, i): EXAMPLES:: - sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() - sage: H.monomial(4).counit() # indirect doctest + sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() # optional - sage.modules + sage: H.monomial(4).counit() # indirect doctest # optional - sage.modules 0 - sage: H.monomial(0).counit() # indirect doctest + sage: H.monomial(0).counit() # indirect doctest # optional - sage.modules 1 """ if i == self.one_basis(): @@ -144,14 +144,14 @@ def antipode_on_basis(self, index): TESTS:: - sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() - sage: H.monomial(0).antipode() # indirect doctest + sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() # optional - sage.modules + sage: H.monomial(0).antipode() # indirect doctest # optional - sage.modules P0 - sage: H.monomial(1).antipode() # indirect doctest + sage: H.monomial(1).antipode() # indirect doctest # optional - sage.modules -P1 - sage: H.monomial(2).antipode() # indirect doctest + sage: H.monomial(2).antipode() # indirect doctest # optional - sage.modules P2 - sage: H.monomial(3).antipode() # indirect doctest + sage: H.monomial(3).antipode() # indirect doctest # optional - sage.modules -P3 """ if self.monomial(index) == self.one(): diff --git a/src/sage/categories/graded_lie_conformal_algebras.py b/src/sage/categories/graded_lie_conformal_algebras.py index 66950ecce53..2650492898d 100644 --- a/src/sage/categories/graded_lie_conformal_algebras.py +++ b/src/sage/categories/graded_lie_conformal_algebras.py @@ -31,11 +31,11 @@ def Super(self, base_ring=None): EXAMPLES:: - sage: C = LieConformalAlgebras(QQbar) - sage: C.Graded().Super() is C.Super().Graded() + sage: C = LieConformalAlgebras(QQbar) # optional - sage.rings.number_field + sage: C.Graded().Super() is C.Super().Graded() # optional - sage.rings.number_field True - sage: Cp = C.WithBasis() - sage: Cp.Graded().Super() is Cp.Super().Graded() + sage: Cp = C.WithBasis() # optional - sage.rings.number_field + sage: Cp.Graded().Super() is Cp.Super().Graded() # optional - sage.rings.number_field True """ return self.base_category().Super(base_ring).Graded() @@ -46,10 +46,10 @@ def _repr_object_names(self): EXAMPLES:: - sage: LieConformalAlgebras(QQbar).Graded() + sage: LieConformalAlgebras(QQbar).Graded() # optional - sage.rings.number_field Category of H-graded Lie conformal algebras over Algebraic Field - sage: LieConformalAlgebras(QQbar).WithBasis().FinitelyGenerated().Graded() + sage: LieConformalAlgebras(QQbar).WithBasis().FinitelyGenerated().Graded() # optional - sage.rings.number_field Category of H-graded finitely generated Lie conformal algebras with basis over Algebraic Field """ return "H-graded {}".format(self.base_category()._repr_object_names()) @@ -60,7 +60,7 @@ class GradedLieConformalAlgebras(GradedLieConformalAlgebrasCategory): EXAMPLES:: - sage: C = LieConformalAlgebras(QQbar).Graded(); C + sage: C = LieConformalAlgebras(QQbar).Graded(); C # optional - sage.rings.number_field Category of H-graded Lie conformal algebras over Algebraic Field sage: CS = LieConformalAlgebras(QQ).Graded().Super(); CS diff --git a/src/sage/categories/graded_modules_with_basis.py b/src/sage/categories/graded_modules_with_basis.py index 1868147bedb..b1185e20352 100644 --- a/src/sage/categories/graded_modules_with_basis.py +++ b/src/sage/categories/graded_modules_with_basis.py @@ -46,17 +46,18 @@ def degree_negation(self, element): EXAMPLES:: - sage: E. = ExteriorAlgebra(QQ) - sage: E.degree_negation((1 + a) * (1 + b)) + sage: E. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: E.degree_negation((1 + a) * (1 + b)) # optional - sage.combinat sage.modules a*b - a - b + 1 - sage: E.degree_negation(E.zero()) + sage: E.degree_negation(E.zero()) # optional - sage.combinat sage.modules 0 - sage: P = GradedModulesWithBasis(ZZ).example(); P - An example of a graded module with basis: the free module on partitions over Integer Ring - sage: pbp = lambda x: P.basis()[Partition(list(x))] - sage: p = pbp([3,1]) - 2 * pbp([2]) + 4 * pbp([1]) - sage: P.degree_negation(p) + sage: P = GradedModulesWithBasis(ZZ).example(); P # optional - sage.combinat sage.modules + An example of a graded module with basis: + the free module on partitions over Integer Ring + sage: pbp = lambda x: P.basis()[Partition(list(x))] # optional - sage.combinat sage.modules + sage: p = pbp([3,1]) - 2 * pbp([2]) + 4 * pbp([1]) # optional - sage.combinat sage.modules + sage: P.degree_negation(p) # optional - sage.combinat sage.modules -4*P[1] - 2*P[2] + P[3, 1] """ base_one = self.base_ring().one() @@ -114,56 +115,63 @@ def submodule(self, gens, check=True, already_echelonized=False, A graded submodule of a graded module generated by homogeneous elements is naturally graded:: - sage: E. = ExteriorAlgebra(QQ) - sage: S = E.submodule([x + y, x*y - y*z]) - sage: S.category() - Join of Category of graded vector spaces with basis over Rational Field - and Category of subobjects of filtered modules with basis over Rational Field - and Category of finite dimensional vector spaces with basis over Rational Field - sage: S.basis()[0].degree() + sage: E. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: S = E.submodule([x + y, x*y - y*z]) # optional - sage.combinat sage.modules + sage: S.category() # optional - sage.combinat sage.modules + Join of + Category of graded vector spaces with basis over Rational Field and + Category of subobjects of filtered modules with basis over Rational Field and + Category of finite dimensional vector spaces with basis over Rational Field + sage: S.basis()[0].degree() # optional - sage.combinat sage.modules 1 - sage: S.basis()[1].degree() + sage: S.basis()[1].degree() # optional - sage.combinat sage.modules 2 We check on the echelonized basis:: - sage: Sp = E.submodule([1, x + y + 5, x*y - y*z + x + y - 2]) - sage: Sp.category() - Join of Category of graded vector spaces with basis over Rational Field - and Category of subobjects of filtered modules with basis over Rational Field - and Category of finite dimensional vector spaces with basis over Rational Field + sage: Sp = E.submodule([1, x + y + 5, x*y - y*z + x + y - 2]) # optional - sage.combinat sage.modules + sage: Sp.category() # optional - sage.combinat sage.modules + Join of + Category of graded vector spaces with basis over Rational Field and + Category of subobjects of filtered modules with basis over Rational Field and + Category of finite dimensional vector spaces with basis over Rational Field If it is generated by inhomogeneous elements, then it is filtered by default:: - sage: F = E.submodule([x + y*z, x*z + y*x]) - sage: F.category() - Join of Category of subobjects of filtered modules with basis over Rational Field - and Category of filtered vector spaces with basis over Rational Field - and Category of finite dimensional vector spaces with basis over Rational Field + sage: F = E.submodule([x + y*z, x*z + y*x]) # optional - sage.combinat sage.modules + sage: F.category() # optional - sage.combinat sage.modules + Join of + Category of subobjects of filtered modules with basis over Rational Field and + Category of filtered vector spaces with basis over Rational Field and + Category of finite dimensional vector spaces with basis over Rational Field If ``category`` is specified, then it does not give any extra structure to the submodule (we can think of this as applying the forgetful functor):: - sage: SM = E.submodule([x + y, x*y - y*z], category=ModulesWithBasis(QQ)) - sage: SM.category() - Join of Category of finite dimensional vector spaces with basis over Rational Field - and Category of subobjects of sets - sage: FM = E.submodule([x + 1, x*y - x*y*z], category=ModulesWithBasis(QQ)) - sage: FM.category() - Join of Category of finite dimensional vector spaces with basis over Rational Field - and Category of subobjects of sets + sage: SM = E.submodule([x + y, x*y - y*z], # optional - sage.combinat sage.modules + ....: category=ModulesWithBasis(QQ)) + sage: SM.category() # optional - sage.combinat sage.modules + Join of + Category of finite dimensional vector spaces with basis over Rational Field and + Category of subobjects of sets + sage: FM = E.submodule([x + 1, x*y - x*y*z], # optional - sage.combinat sage.modules + ....: category=ModulesWithBasis(QQ)) + sage: FM.category() # optional - sage.combinat sage.modules + Join of + Category of finite dimensional vector spaces with basis over Rational Field and + Category of subobjects of sets If we have specified that this is a graded submodule of a graded module, then the echelonized elements must be homogeneous:: sage: Cat = ModulesWithBasis(QQ).Graded().Subobjects() - sage: E.submodule([x + y, x*y - 1], category=Cat) + sage: E.submodule([x + y, x*y - 1], category=Cat) # optional - sage.combinat sage.modules Traceback (most recent call last): ... ValueError: all of the generators must be homogeneous - sage: E.submodule([x + y, x*y - x - y], category=Cat) + sage: E.submodule([x + y, x*y - x - y], category=Cat) # optional - sage.combinat sage.modules Free module generated by {0, 1} over Rational Field """ # Make sure gens consists of elements of ``self`` @@ -215,13 +223,14 @@ def quotient_module(self, submodule, check=True, already_echelonized=False, cate EXAMPLES:: - sage: E. = ExteriorAlgebra(QQ) - sage: S = E.submodule([x + y, x*y - y*z, y]) - sage: Q = E.quotient_module(S) - sage: Q.category() - Join of Category of quotients of graded modules with basis over Rational Field - and Category of graded vector spaces with basis over Rational Field - and Category of finite dimensional vector spaces with basis over Rational Field + sage: E. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: S = E.submodule([x + y, x*y - y*z, y]) # optional - sage.combinat sage.modules + sage: Q = E.quotient_module(S) # optional - sage.combinat sage.modules + sage: Q.category() # optional - sage.combinat sage.modules + Join of + Category of quotients of graded modules with basis over Rational Field and + Category of graded vector spaces with basis over Rational Field and + Category of finite dimensional vector spaces with basis over Rational Field .. SEEALSO:: @@ -258,17 +267,18 @@ def degree_negation(self): EXAMPLES:: - sage: E. = ExteriorAlgebra(QQ) - sage: ((1 + a) * (1 + b)).degree_negation() + sage: E. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: ((1 + a) * (1 + b)).degree_negation() # optional - sage.combinat sage.modules a*b - a - b + 1 - sage: E.zero().degree_negation() + sage: E.zero().degree_negation() # optional - sage.combinat sage.modules 0 - sage: P = GradedModulesWithBasis(ZZ).example(); P - An example of a graded module with basis: the free module on partitions over Integer Ring - sage: pbp = lambda x: P.basis()[Partition(list(x))] - sage: p = pbp([3,1]) - 2 * pbp([2]) + 4 * pbp([1]) - sage: p.degree_negation() + sage: P = GradedModulesWithBasis(ZZ).example(); P # optional - sage.combinat sage.modules + An example of a graded module with basis: + the free module on partitions over Integer Ring + sage: pbp = lambda x: P.basis()[Partition(list(x))] # optional - sage.combinat sage.modules + sage: p = pbp([3,1]) - 2 * pbp([2]) + 4 * pbp([1]) # optional - sage.combinat sage.modules + sage: p.degree_negation() # optional - sage.combinat sage.modules -4*P[1] - 2*P[2] + P[3, 1] """ return self.parent().degree_negation(self) @@ -282,13 +292,13 @@ def degree_on_basis(self, m): EXAMPLES:: - sage: E. = ExteriorAlgebra(QQ) - sage: S = E.submodule([x + y, x*y - y*z, y]) - sage: Q = E.quotient_module(S) - sage: B = Q.basis() - sage: [B[i].lift() for i in Q.indices()] + sage: E. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: S = E.submodule([x + y, x*y - y*z, y]) # optional - sage.combinat sage.modules + sage: Q = E.quotient_module(S) # optional - sage.combinat sage.modules + sage: B = Q.basis() # optional - sage.combinat sage.modules + sage: [B[i].lift() for i in Q.indices()] # optional - sage.combinat sage.modules [1, z, x*z, y*z, x*y*z] - sage: [Q.degree_on_basis(i) for i in Q.indices()] + sage: [Q.degree_on_basis(i) for i in Q.indices()] # optional - sage.combinat sage.modules [0, 1, 2, 2, 3] """ return self.basis()[m].lift().degree() @@ -300,13 +310,13 @@ def degree(self): EXAMPLES:: - sage: E. = ExteriorAlgebra(QQ) - sage: S = E.submodule([x + y, x*y - y*z, y]) - sage: Q = E.quotient_module(S) - sage: B = Q.basis() - sage: [B[i].lift() for i in Q.indices()] + sage: E. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: S = E.submodule([x + y, x*y - y*z, y]) # optional - sage.combinat sage.modules + sage: Q = E.quotient_module(S) # optional - sage.combinat sage.modules + sage: B = Q.basis() # optional - sage.combinat sage.modules + sage: [B[i].lift() for i in Q.indices()] # optional - sage.combinat sage.modules [1, z, x*z, y*z, x*y*z] - sage: [B[i].degree() for i in Q.indices()] + sage: [B[i].degree() for i in Q.indices()] # optional - sage.combinat sage.modules [0, 1, 2, 2, 3] """ return self.lift().degree() diff --git a/src/sage/categories/group_algebras.py b/src/sage/categories/group_algebras.py index 0df6bf44165..46e36fd47cf 100644 --- a/src/sage/categories/group_algebras.py +++ b/src/sage/categories/group_algebras.py @@ -50,15 +50,16 @@ class GroupAlgebras(AlgebrasCategory): Here is how to create the group algebra of a group `G`:: - sage: G = DihedralGroup(5) - sage: QG = G.algebra(QQ); QG - Algebra of Dihedral group of order 10 as a permutation group over Rational Field + sage: G = DihedralGroup(5) # optional - sage.groups + sage: QG = G.algebra(QQ); QG # optional - sage.groups sage.modules + Algebra of + Dihedral group of order 10 as a permutation group over Rational Field and an example of computation:: - sage: g = G.an_element(); g + sage: g = G.an_element(); g # optional - sage.groups sage.modules (1,4)(2,3) - sage: (QG.term(g) + 1)**3 + sage: (QG.term(g) + 1)**3 # optional - sage.groups sage.modules 4*() + 4*(1,4)(2,3) .. TODO:: @@ -68,14 +69,14 @@ class GroupAlgebras(AlgebrasCategory): TESTS:: - sage: A = GroupAlgebras(QQ).example(GL(3, GF(11))) - sage: A.one_basis() + sage: A = GroupAlgebras(QQ).example(GL(3, GF(11))) # optional - sage.groups sage.modules sage.rings.finite_rings + sage: A.one_basis() # optional - sage.groups sage.modules sage.rings.finite_rings [1 0 0] [0 1 0] [0 0 1] - sage: A = SymmetricGroupAlgebra(QQ,4) - sage: x = Permutation([4,3,2,1]) - sage: A.product_on_basis(x,x) + sage: A = SymmetricGroupAlgebra(QQ, 4) # optional - sage.groups sage.modules sage.combinat + sage: x = Permutation([4,3,2,1]) # optional - sage.groups sage.modules sage.combinat + sage: A.product_on_basis(x, x) # optional - sage.groups sage.modules sage.combinat [1, 2, 3, 4] sage: C = GroupAlgebras(ZZ) @@ -104,13 +105,15 @@ def example(self, G=None): EXAMPLES:: - sage: GroupAlgebras(QQ['x']).example() - Algebra of Dihedral group of order 8 as a permutation group over Univariate Polynomial Ring in x over Rational Field + sage: GroupAlgebras(QQ['x']).example() # optional - sage.groups sage.modules + Algebra of Dihedral group of order 8 as a permutation group + over Univariate Polynomial Ring in x over Rational Field An other group can be specified as optional argument:: - sage: GroupAlgebras(QQ).example(AlternatingGroup(4)) - Algebra of Alternating group of order 4!/2 as a permutation group over Rational Field + sage: GroupAlgebras(QQ).example(AlternatingGroup(4)) # optional - sage.groups sage.modules + Algebra of + Alternating group of order 4!/2 as a permutation group over Rational Field """ from sage.groups.perm_gps.permgroup_named import DihedralGroup if G is None: @@ -124,19 +127,19 @@ def __init_extra__(self): EXAMPLES:: - sage: A = GroupAlgebra(SymmetricGroup(4), QQ) - sage: B = GroupAlgebra(SymmetricGroup(3), ZZ) - sage: A.has_coerce_map_from(B) + sage: A = GroupAlgebra(SymmetricGroup(4), QQ) # optional - sage.groups sage.modules + sage: B = GroupAlgebra(SymmetricGroup(3), ZZ) # optional - sage.groups sage.modules + sage: A.has_coerce_map_from(B) # optional - sage.groups sage.modules True - sage: B.has_coerce_map_from(A) + sage: B.has_coerce_map_from(A) # optional - sage.groups sage.modules False - sage: A.has_coerce_map_from(ZZ) + sage: A.has_coerce_map_from(ZZ) # optional - sage.groups sage.modules True - sage: A.has_coerce_map_from(CC) + sage: A.has_coerce_map_from(CC) # optional - sage.groups sage.modules False - sage: A.has_coerce_map_from(SymmetricGroup(5)) + sage: A.has_coerce_map_from(SymmetricGroup(5)) # optional - sage.groups sage.modules False - sage: A.has_coerce_map_from(SymmetricGroup(2)) + sage: A.has_coerce_map_from(SymmetricGroup(2)) # optional - sage.groups sage.modules True """ if not self.base_ring().has_coerce_map_from(self.group()): @@ -152,8 +155,8 @@ def _latex_(self): EXAMPLES:: - sage: A = GroupAlgebra(KleinFourGroup(), ZZ) - sage: latex(A) # indirect doctest + sage: A = GroupAlgebra(KleinFourGroup(), ZZ) # optional - sage.groups sage.modules + sage: latex(A) # indirect doctest # optional - sage.groups sage.modules \Bold{Z}[\langle (3,4), (1,2) \rangle] """ from sage.misc.latex import latex @@ -165,9 +168,9 @@ def group(self): EXAMPLES:: - sage: GroupAlgebras(QQ).example(GL(3, GF(11))).group() + sage: GroupAlgebras(QQ).example(GL(3, GF(11))).group() # optional - sage.groups sage.modules sage.rings.finite_rings General Linear Group of degree 3 over Finite Field of size 11 - sage: SymmetricGroup(10).algebra(QQ).group() + sage: SymmetricGroup(10).algebra(QQ).group() # optional - sage.groups sage.modules Symmetric group of order 10! as a permutation group """ return self.basis().keys() @@ -195,7 +198,7 @@ def center_basis(self): EXAMPLES:: - sage: SymmetricGroup(3).algebra(QQ).center_basis() + sage: SymmetricGroup(3).algebra(QQ).center_basis() # optional - sage.groups sage.modules ((), (2,3) + (1,2) + (1,3), (1,2,3) + (1,3,2)) .. SEEALSO:: @@ -217,15 +220,16 @@ def coproduct_on_basis(self, g): EXAMPLES:: - sage: A = CyclicPermutationGroup(6).algebra(ZZ); A - Algebra of Cyclic group of order 6 as a permutation group over Integer Ring - sage: g = CyclicPermutationGroup(6).an_element(); g + sage: A = CyclicPermutationGroup(6).algebra(ZZ); A # optional - sage.groups sage.modules + Algebra of + Cyclic group of order 6 as a permutation group over Integer Ring + sage: g = CyclicPermutationGroup(6).an_element(); g # optional - sage.groups sage.modules (1,2,3,4,5,6) - sage: A.coproduct_on_basis(g) + sage: A.coproduct_on_basis(g) # optional - sage.groups sage.modules (1,2,3,4,5,6) # (1,2,3,4,5,6) - sage: a = A.an_element(); a + sage: a = A.an_element(); a # optional - sage.groups sage.modules () + 3*(1,2,3,4,5,6) + 3*(1,3,5)(2,4,6) - sage: a.coproduct() + sage: a.coproduct() # optional - sage.groups sage.modules () # () + 3*(1,2,3,4,5,6) # (1,2,3,4,5,6) + 3*(1,3,5)(2,4,6) # (1,3,5)(2,4,6) """ from sage.categories.tensor import tensor @@ -242,15 +246,16 @@ def antipode_on_basis(self,g): EXAMPLES:: - sage: A = CyclicPermutationGroup(6).algebra(ZZ); A - Algebra of Cyclic group of order 6 as a permutation group over Integer Ring - sage: g = CyclicPermutationGroup(6).an_element();g + sage: A = CyclicPermutationGroup(6).algebra(ZZ); A # optional - sage.groups sage.modules + Algebra of + Cyclic group of order 6 as a permutation group over Integer Ring + sage: g = CyclicPermutationGroup(6).an_element(); g # optional - sage.groups sage.modules (1,2,3,4,5,6) - sage: A.antipode_on_basis(g) + sage: A.antipode_on_basis(g) # optional - sage.groups sage.modules (1,6,5,4,3,2) - sage: a = A.an_element(); a + sage: a = A.an_element(); a # optional - sage.groups sage.modules () + 3*(1,2,3,4,5,6) + 3*(1,3,5)(2,4,6) - sage: a.antipode() + sage: a.antipode() # optional - sage.groups sage.modules () + 3*(1,5,3)(2,6,4) + 3*(1,6,5,4,3,2) """ return self.term(~g) @@ -265,11 +270,12 @@ def counit_on_basis(self,g): EXAMPLES:: - sage: A = CyclicPermutationGroup(6).algebra(ZZ);A - Algebra of Cyclic group of order 6 as a permutation group over Integer Ring - sage: g = CyclicPermutationGroup(6).an_element();g + sage: A = CyclicPermutationGroup(6).algebra(ZZ); A # optional - sage.groups sage.modules + Algebra of + Cyclic group of order 6 as a permutation group over Integer Ring + sage: g = CyclicPermutationGroup(6).an_element(); g # optional - sage.groups sage.modules (1,2,3,4,5,6) - sage: A.counit_on_basis(g) + sage: A.counit_on_basis(g) # optional - sage.groups sage.modules 1 """ return self.base_ring().one() @@ -284,11 +290,12 @@ def counit(self,x): EXAMPLES:: - sage: A = CyclicPermutationGroup(6).algebra(ZZ); A - Algebra of Cyclic group of order 6 as a permutation group over Integer Ring - sage: a = A.an_element(); a + sage: A = CyclicPermutationGroup(6).algebra(ZZ); A # optional - sage.groups sage.modules + Algebra of + Cyclic group of order 6 as a permutation group over Integer Ring + sage: a = A.an_element(); a # optional - sage.groups sage.modules () + 3*(1,2,3,4,5,6) + 3*(1,3,5)(2,4,6) - sage: a.counit() + sage: a.counit() # optional - sage.groups sage.modules 7 """ return self.base_ring().sum(x.coefficients()) @@ -305,17 +312,19 @@ def is_integral_domain(self, proof=True): EXAMPLES:: - sage: GroupAlgebra(SymmetricGroup(2)).is_integral_domain() + sage: S2 = SymmetricGroup(2) # optional - sage.groups + sage: GroupAlgebra(S2).is_integral_domain() # optional - sage.groups sage.modules False - sage: GroupAlgebra(SymmetricGroup(1)).is_integral_domain() + sage: S1 = SymmetricGroup(1) + sage: GroupAlgebra(S1).is_integral_domain() # optional - sage.groups sage.modules True - sage: GroupAlgebra(SymmetricGroup(1), IntegerModRing(4)).is_integral_domain() + sage: GroupAlgebra(S1, IntegerModRing(4)).is_integral_domain() # optional - sage.groups sage.modules False - sage: GroupAlgebra(AbelianGroup(1)).is_integral_domain() + sage: GroupAlgebra(AbelianGroup(1)).is_integral_domain() # optional - sage.groups sage.modules True - sage: GroupAlgebra(AbelianGroup(2, [0,2])).is_integral_domain() + sage: GroupAlgebra(AbelianGroup(2, [0,2])).is_integral_domain() # optional - sage.groups sage.modules False - sage: GroupAlgebra(GL(2, ZZ)).is_integral_domain() # not implemented + sage: GroupAlgebra(GL(2, ZZ)).is_integral_domain() # not implemented # optional - sage.groups sage.modules False """ from sage.sets.set import Set @@ -385,22 +394,24 @@ def central_form(self): EXAMPLES:: - sage: QS3 = SymmetricGroup(3).algebra(QQ) - sage: A = QS3([2,3,1]) + QS3([3,1,2]) - sage: A.central_form() + sage: QS3 = SymmetricGroup(3).algebra(QQ) # optional - sage.groups sage.modules + sage: A = QS3([2,3,1]) + QS3([3,1,2]) # optional - sage.groups sage.modules + sage: A.central_form() # optional - sage.groups sage.modules B[(1,2,3)] - sage: QS4 = SymmetricGroup(4).algebra(QQ) - sage: B = sum(len(s.cycle_type())*QS4(s) for s in Permutations(4)) - sage: B.central_form() + sage: QS4 = SymmetricGroup(4).algebra(QQ) # optional - sage.groups sage.modules + sage: B = sum(len(s.cycle_type()) * QS4(s) for s in Permutations(4)) # optional - sage.groups sage.modules + sage: B.central_form() # optional - sage.groups sage.modules 4*B[()] + 3*B[(1,2)] + 2*B[(1,2)(3,4)] + 2*B[(1,2,3)] + B[(1,2,3,4)] The following test fails due to a bug involving combinatorial free modules and the coercion system (see :trac:`28544`):: - sage: QG = GroupAlgebras(QQ).example(PermutationGroup([[(1,2,3),(4,5)],[(3,4)]])) - sage: s = sum(i for i in QG.basis()) - sage: s.central_form() # not tested - B[()] + B[(4,5)] + B[(3,4,5)] + B[(2,3)(4,5)] + B[(2,3,4,5)] + B[(1,2)(3,4,5)] + B[(1,2,3,4,5)] + sage: G = PermutationGroup([[(1,2,3),(4,5)], [(3,4)]]) # optional - sage.groups sage.modules + sage: QG = GroupAlgebras(QQ).example(G) # optional - sage.groups sage.modules + sage: s = sum(i for i in QG.basis()) # optional - sage.groups sage.modules + sage: s.central_form() # not tested # optional - sage.groups sage.modules + B[()] + B[(4,5)] + B[(3,4,5)] + B[(2,3)(4,5)] + + B[(2,3,4,5)] + B[(1,2)(3,4,5)] + B[(1,2,3,4,5)] .. SEEALSO:: diff --git a/src/sage/categories/groupoid.py b/src/sage/categories/groupoid.py index 4c6e3ae6042..9eee3750655 100644 --- a/src/sage/categories/groupoid.py +++ b/src/sage/categories/groupoid.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.groups r""" Groupoid """ diff --git a/src/sage/categories/groups.py b/src/sage/categories/groups.py index 97d57799f8c..569cfc0d36d 100644 --- a/src/sage/categories/groups.py +++ b/src/sage/categories/groups.py @@ -42,7 +42,7 @@ def example(self): """ EXAMPLES:: - sage: Groups().example() + sage: Groups().example() # optional - sage.groups General Linear Group of degree 4 over Rational Field """ from sage.rings.rational_field import QQ @@ -69,13 +69,13 @@ def free(index_set=None, names=None, **kwds): EXAMPLES:: - sage: Groups.free(index_set=ZZ) + sage: Groups.free(index_set=ZZ) # optional - sage.groups Free group indexed by Integer Ring - sage: Groups().free(ZZ) + sage: Groups().free(ZZ) # optional - sage.groups Free group indexed by Integer Ring - sage: Groups().free(5) + sage: Groups().free(5) # optional - sage.groups Free Group on generators {x0, x1, x2, x3, x4} - sage: F. = Groups().free(); F + sage: F. = Groups().free(); F # optional - sage.groups Free Group on generators {x, y, z} """ from sage.rings.integer_ring import ZZ @@ -99,8 +99,8 @@ def group_generators(self): EXAMPLES:: - sage: A = AlternatingGroup(4) - sage: A.group_generators() + sage: A = AlternatingGroup(4) # optional - sage.groups + sage: A.group_generators() # optional - sage.groups Family ((2,3,4), (1,2,3)) """ from sage.sets.family import Family @@ -120,11 +120,11 @@ def monoid_generators(self): EXAMPLES:: - sage: A = AlternatingGroup(4) - sage: A.monoid_generators() + sage: A = AlternatingGroup(4) # optional - sage.groups + sage: A.monoid_generators() # optional - sage.groups Family ((2,3,4), (1,2,3)) - sage: F. = FreeGroup() - sage: F.monoid_generators() + sage: F. = FreeGroup() # optional - sage.groups + sage: F.monoid_generators() # optional - sage.groups Family (x, y, x^-1, y^-1) """ G = self.group_generators() @@ -142,8 +142,8 @@ def _test_inverse(self, **options): EXAMPLES:: - sage: G = SymmetricGroup(3) - sage: G._test_inverse() + sage: G = SymmetricGroup(3) # optional - sage.groups + sage: G._test_inverse() # optional - sage.groups """ tester = self._tester(**options) for x in tester.some_elements(): @@ -156,11 +156,13 @@ def semidirect_product(self, N, mapping, check=True): EXAMPLES:: - sage: G = Groups().example() - sage: G.semidirect_product(G,Morphism(G,G)) + sage: G = Groups().example() # optional - sage.groups + sage: G.semidirect_product(G, Morphism(G, G)) # optional - sage.groups Traceback (most recent call last): ... - NotImplementedError: semidirect product of General Linear Group of degree 4 over Rational Field and General Linear Group of degree 4 over Rational Field not yet implemented + NotImplementedError: semidirect product of General Linear Group of degree 4 + over Rational Field and General Linear Group of degree 4 over Rational Field + not yet implemented """ raise NotImplementedError("semidirect product of %s and %s not yet implemented" % (self, N)) @@ -176,11 +178,12 @@ def holomorph(self): EXAMPLES:: - sage: G = Groups().example() - sage: G.holomorph() + sage: G = Groups().example() # optional - sage.groups + sage: G.holomorph() # optional - sage.groups Traceback (most recent call last): ... - NotImplementedError: holomorph of General Linear Group of degree 4 over Rational Field not yet implemented + NotImplementedError: holomorph of General Linear Group of degree 4 + over Rational Field not yet implemented """ raise NotImplementedError("holomorph of %s not yet implemented"%self) @@ -243,11 +246,11 @@ def cayley_table(self, names='letters', elements=None): Permutation groups, matrix groups and abelian groups can all compute their multiplication tables. :: - sage: G = DiCyclicGroup(3) - sage: T = G.cayley_table() - sage: T.column_keys() + sage: G = DiCyclicGroup(3) # optional - sage.groups + sage: T = G.cayley_table() # optional - sage.groups + sage: T.column_keys() # optional - sage.groups ((), (5,6,7), ..., (1,4,2,3)(5,7)) - sage: T + sage: T # optional - sage.groups * a b c d e f g h i j k l +------------------------ a| a b c d e f g h i j k l @@ -265,8 +268,8 @@ def cayley_table(self, names='letters', elements=None): :: - sage: M = SL(2, 2) - sage: M.cayley_table() + sage: M = SL(2, 2) # optional - sage.groups + sage: M.cayley_table() # optional - sage.groups * a b c d e f +------------ a| a b c d e f @@ -279,8 +282,8 @@ def cayley_table(self, names='letters', elements=None): :: - sage: A = AbelianGroup([2, 3]) - sage: A.cayley_table() + sage: A = AbelianGroup([2, 3]) # optional - sage.groups + sage: A.cayley_table() # optional - sage.groups * a b c d e f +------------ a| a b c d e f @@ -298,8 +301,8 @@ def cayley_table(self, names='letters', elements=None): you can choose to just use the string representations of the elements themselves. :: - sage: C = CyclicPermutationGroup(11) - sage: C.cayley_table(names='digits') + sage: C = CyclicPermutationGroup(11) # optional - sage.groups + sage: C.cayley_table(names='digits') # optional - sage.groups * 00 01 02 03 04 05 06 07 08 09 10 +--------------------------------- 00| 00 01 02 03 04 05 06 07 08 09 10 @@ -316,9 +319,9 @@ def cayley_table(self, names='letters', elements=None): :: - sage: G = QuaternionGroup() - sage: names = ['1', 'I', '-1', '-I', 'J', '-K', '-J', 'K'] - sage: G.cayley_table(names=names) + sage: G = QuaternionGroup() # optional - sage.groups + sage: names = ['1', 'I', '-1', '-I', 'J', '-K', '-J', 'K'] # optional - sage.groups + sage: G.cayley_table(names=names) # optional - sage.groups * 1 I -1 -I J -K -J K +------------------------ 1| 1 I -1 -I J -K -J K @@ -332,8 +335,8 @@ def cayley_table(self, names='letters', elements=None): :: - sage: A = AbelianGroup([2,2]) - sage: A.cayley_table(names='elements') + sage: A = AbelianGroup([2, 2]) # optional - sage.groups + sage: A.cayley_table(names='elements') # optional - sage.groups * 1 f1 f0 f0*f1 +------------------------ 1| 1 f1 f0 f0*f1 @@ -345,10 +348,10 @@ def cayley_table(self, names='letters', elements=None): routine behaves similarly, but changes an existing table "in-place." :: - sage: G = AlternatingGroup(3) - sage: T = G.cayley_table() - sage: T.change_names('digits') - sage: T + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: T = G.cayley_table() # optional - sage.groups + sage: T.change_names('digits') # optional - sage.groups + sage: T # optional - sage.groups * 0 1 2 +------ 0| 0 1 2 @@ -360,11 +363,11 @@ def cayley_table(self, names='letters', elements=None): Elements will be coerced into the group as part of setting up the table. :: - sage: G = SL(2,ZZ) - sage: G + sage: G = SL(2,ZZ) # optional - sage.groups + sage: G # optional - sage.groups Special Linear Group of degree 2 over Integer Ring - sage: identity = matrix(ZZ, [[1,0], [0,1]]) - sage: G.cayley_table(elements=[identity, -identity]) + sage: identity = matrix(ZZ, [[1,0], [0,1]]) # optional - sage.groups + sage: G.cayley_table(elements=[identity, -identity]) # optional - sage.groups * a b +---- a| a b @@ -381,11 +384,11 @@ class provides even greater flexibility, including changing confirms that they form a closed subset in the group. :: - sage: from sage.matrix.operation_table import OperationTable - sage: G = DiCyclicGroup(3) - sage: commutator = lambda x, y: x*y*x^-1*y^-1 - sage: T = OperationTable(G, commutator) - sage: T + sage: from sage.matrix.operation_table import OperationTable # optional - sage.groups + sage: G = DiCyclicGroup(3) # optional - sage.groups + sage: commutator = lambda x, y: x*y*x^-1*y^-1 # optional - sage.groups + sage: T = OperationTable(G, commutator) # optional - sage.groups + sage: T # optional - sage.groups . a b c d e f g h i j k l +------------------------ a| a a a a a a a a a a a a @@ -401,12 +404,12 @@ class provides even greater flexibility, including changing k| a b c a b c b a c b a c l| a b c a b c c b a c b a - sage: trans = T.translation() - sage: comm = [trans['a'], trans['b'], trans['c']] - sage: comm + sage: trans = T.translation() # optional - sage.groups + sage: comm = [trans['a'], trans['b'], trans['c']] # optional - sage.groups + sage: comm # optional - sage.groups [(), (5,6,7), (5,7,6)] - sage: P = G.cayley_table(elements=comm) - sage: P + sage: P = G.cayley_table(elements=comm) # optional - sage.groups + sage: P # optional - sage.groups * a b c +------ a| a b c @@ -437,9 +440,9 @@ def conjugacy_class(self, g): EXAMPLES:: - sage: A = AbelianGroup([2,2]) - sage: c = A.conjugacy_class(A.an_element()) - sage: type(c) + sage: A = AbelianGroup([2, 2]) # optional - sage.groups + sage: c = A.conjugacy_class(A.an_element()) # optional - sage.groups + sage: type(c) # optional - sage.groups """ from sage.groups.conjugacy_classes import ConjugacyClass @@ -452,29 +455,32 @@ def conjugacy_class(self): EXAMPLES:: - sage: D = DihedralGroup(5) - sage: g = D((1,3,5,2,4)) - sage: g.conjugacy_class() - Conjugacy class of (1,3,5,2,4) in Dihedral group of order 10 as a permutation group + sage: D = DihedralGroup(5) # optional - sage.groups + sage: g = D((1,3,5,2,4)) # optional - sage.groups + sage: g.conjugacy_class() # optional - sage.groups + Conjugacy class of (1,3,5,2,4) + in Dihedral group of order 10 as a permutation group - sage: H = MatrixGroup([matrix(GF(5),2,[1,2, -1, 1]), matrix(GF(5),2, [1,1, 0,1])]) - sage: h = H(matrix(GF(5),2,[1,2, -1, 1])) - sage: h.conjugacy_class() + sage: H = MatrixGroup([matrix(GF(5), 2, [1,2, -1,1]), # optional - sage.groups sage.rings.finite_rings sage.modules + ....: matrix(GF(5), 2, [1,1, 0,1])]) + sage: h = H(matrix(GF(5), 2, [1,2, -1,1])) # optional - sage.groups sage.rings.finite_rings sage.modules + sage: h.conjugacy_class() # optional - sage.groups sage.rings.finite_rings sage.modules Conjugacy class of [1 2] - [4 1] in Matrix group over Finite Field of size 5 with 2 generators ( + [4 1] + in Matrix group over Finite Field of size 5 with 2 generators ( [1 2] [1 1] [4 1], [0 1] ) - sage: G = SL(2, GF(2)) - sage: g = G.gens()[0] - sage: g.conjugacy_class() + sage: G = SL(2, GF(2)) # optional - sage.groups sage.rings.finite_rings sage.modules + sage: g = G.gens()[0] # optional - sage.groups sage.rings.finite_rings sage.modules + sage: g.conjugacy_class() # optional - sage.groups sage.rings.finite_rings sage.modules Conjugacy class of [1 1] [0 1] in Special Linear Group of degree 2 over Finite Field of size 2 - sage: G = SL(2, QQ) - sage: g = G([[1,1],[0,1]]) - sage: g.conjugacy_class() + sage: G = SL(2, QQ) # optional - sage.groups sage.modules + sage: g = G([[1,1], [0,1]]) # optional - sage.groups sage.modules + sage: g.conjugacy_class() # optional - sage.groups sage.modules Conjugacy class of [1 1] [0 1] in Special Linear Group of degree 2 over Rational Field """ @@ -505,13 +511,13 @@ def free(index_set=None, names=None, **kwds): EXAMPLES:: - sage: Groups.Commutative.free(index_set=ZZ) + sage: Groups.Commutative.free(index_set=ZZ) # optional - sage.groups Free abelian group indexed by Integer Ring - sage: Groups().Commutative().free(ZZ) + sage: Groups().Commutative().free(ZZ) # optional - sage.groups Free abelian group indexed by Integer Ring - sage: Groups().Commutative().free(5) + sage: Groups().Commutative().free(5) # optional - sage.groups Multiplicative Abelian group isomorphic to Z x Z x Z x Z x Z - sage: F. = Groups().Commutative().free(); F + sage: F. = Groups().Commutative().free(); F # optional - sage.groups Multiplicative Abelian group isomorphic to Z x Z x Z """ from sage.rings.integer_ring import ZZ @@ -568,11 +574,11 @@ def group_generators(self): EXAMPLES:: - sage: C5 = CyclicPermutationGroup(5) - sage: C4 = CyclicPermutationGroup(4) - sage: S4 = SymmetricGroup(3) - sage: C = cartesian_product([C5, C4, S4]) - sage: C.group_generators() + sage: C5 = CyclicPermutationGroup(5) # optional - sage.groups + sage: C4 = CyclicPermutationGroup(4) # optional - sage.groups + sage: S4 = SymmetricGroup(3) # optional - sage.groups + sage: C = cartesian_product([C5, C4, S4]) # optional - sage.groups + sage: C.group_generators() # optional - sage.groups Family (((1,2,3,4,5), (), ()), ((), (1,2,3,4), ()), ((), (), (1,2)), @@ -580,16 +586,16 @@ def group_generators(self): We check the other portion of :trac:`16718` is fixed:: - sage: len(C.j_classes()) + sage: len(C.j_classes()) # optional - sage.groups 1 An example with an infinitely generated group (a better output is needed):: - sage: G = Groups.free([1,2]) - sage: H = Groups.free(ZZ) - sage: C = cartesian_product([G, H]) - sage: C.monoid_generators() + sage: G = Groups.free([1,2]) # optional - sage.groups + sage: H = Groups.free(ZZ) # optional - sage.groups + sage: C = cartesian_product([G, H]) # optional - sage.groups + sage: C.monoid_generators() # optional - sage.groups Lazy family (gen(i))_{i in The Cartesian product of (...)} """ F = self.cartesian_factors() @@ -622,13 +628,13 @@ def order(self): EXAMPLES:: - sage: C = cartesian_product([SymmetricGroup(10), SL(2,GF(3))]) - sage: C.order() + sage: C = cartesian_product([SymmetricGroup(10), SL(2, GF(3))]) # optional - sage.groups sage.rings.finite_rings + sage: C.order() # optional - sage.groups sage.rings.finite_rings 87091200 TESTS:: - sage: C.order.__module__ + sage: C.order.__module__ # optional - sage.groups sage.rings.finite_rings 'sage.categories.groups' .. TODO:: diff --git a/src/sage/categories/hecke_modules.py b/src/sage/categories/hecke_modules.py index 6b593d4fb3a..9372e88c54b 100644 --- a/src/sage/categories/hecke_modules.py +++ b/src/sage/categories/hecke_modules.py @@ -46,7 +46,7 @@ class HeckeModules(Category_module): sage: HeckeModules(IntegerRing()) Category of Hecke modules over Integer Ring - sage: HeckeModules(FiniteField(5)) + sage: HeckeModules(FiniteField(5)) # optional - sage.rings.finite_rings Category of Hecke modules over Finite Field of size 5 The base ring doesn't have to be a principal ideal domain:: @@ -64,7 +64,7 @@ def __init__(self, R): sage: TestSuite(HeckeModules(ZZ)).run() - sage: HeckeModules(Partitions(3)).run() + sage: HeckeModules(Partitions(3)).run() # optional - sage.combinat Traceback (most recent call last): ... TypeError: R (=Partitions of the integer 3) must be a commutative ring @@ -123,7 +123,10 @@ def _Hom_(self, Y, category): sage: M = ModularForms(Gamma0(7), 4) sage: H = M._Hom_(M, category = HeckeModules(QQ)); H - Set of Morphisms from Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(7) of weight 4 over Rational Field to Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(7) of weight 4 over Rational Field in Category of Hecke modules over Rational Field + Set of Morphisms + from Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(7) of weight 4 over Rational Field + to Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(7) of weight 4 over Rational Field + in Category of Hecke modules over Rational Field sage: H.__class__ sage: TestSuite(H).run(skip=["_test_elements", "_test_an_element", "_test_elements_eq", @@ -142,7 +145,8 @@ def _Hom_(self, Y, category): sage: H = M._Hom_(M, category = HeckeModules(GF(5))); H Traceback (most recent call last): ... - TypeError: Category of Hecke modules over Finite Field of size 5 is not a subcategory of Category of Hecke modules over Rational Field + TypeError: Category of Hecke modules over Finite Field of size 5 + is not a subcategory of Category of Hecke modules over Rational Field """ # TODO: double check that it's the correct HeckeModules category below: if category is not None and not category.is_subcategory(HeckeModules(self.base_ring())): diff --git a/src/sage/categories/highest_weight_crystals.py b/src/sage/categories/highest_weight_crystals.py index b8afdee2117..226d310eb35 100644 --- a/src/sage/categories/highest_weight_crystals.py +++ b/src/sage/categories/highest_weight_crystals.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.graphs, sage.combinat r""" Highest Weight Crystals """ @@ -128,7 +129,8 @@ def highest_weight_vectors(self): :: sage: C = crystals.Letters(['A',2]) - sage: T = crystals.TensorProduct(C,C,C,generators=[[C(2),C(1),C(1)],[C(1),C(2),C(1)]]) + sage: T = crystals.TensorProduct(C, C, C, generators=[[C(2),C(1),C(1)], + ....: [C(1),C(2),C(1)]]) sage: T.highest_weight_vectors() ([2, 1, 1], [1, 2, 1]) """ @@ -174,7 +176,8 @@ def lowest_weight_vectors(self): :: sage: C = crystals.Letters(['A',2]) - sage: T = crystals.TensorProduct(C,C,C,generators=[[C(2),C(1),C(1)],[C(1),C(2),C(1)]]) + sage: T = crystals.TensorProduct(C, C, C,generators=[[C(2),C(1),C(1)], + ....: [C(1),C(2),C(1)]]) sage: T.lowest_weight_vectors() ([3, 2, 3], [3, 3, 2]) """ diff --git a/src/sage/categories/homset.py b/src/sage/categories/homset.py index 88b162c5845..6554c895ff4 100644 --- a/src/sage/categories/homset.py +++ b/src/sage/categories/homset.py @@ -11,26 +11,26 @@ In the following, the :class:`Hom` object is indeed cached:: - sage: K = GF(17) - sage: H = Hom(ZZ, K) - sage: H + sage: K = GF(17) # optional - sage.rings.finite_rings + sage: H = Hom(ZZ, K) # optional - sage.rings.finite_rings + sage: H # optional - sage.rings.finite_rings Set of Homomorphisms from Integer Ring to Finite Field of size 17 - sage: H is Hom(ZZ, K) + sage: H is Hom(ZZ, K) # optional - sage.rings.finite_rings True Nonetheless, garbage collection occurs when the original references are overwritten:: - sage: for p in prime_range(200): + sage: for p in prime_range(200): # optional - sage.rings.finite_rings ....: K = GF(p) ....: H = Hom(ZZ, K) sage: import gc sage: _ = gc.collect() - sage: from sage.rings.finite_rings.finite_field_prime_modn import FiniteField_prime_modn as FF - sage: L = [x for x in gc.get_objects() if isinstance(x, FF)] - sage: len(L) + sage: from sage.rings.finite_rings.finite_field_prime_modn import FiniteField_prime_modn as FF # optional - sage.rings.finite_rings + sage: L = [x for x in gc.get_objects() if isinstance(x, FF)] # optional - sage.rings.finite_rings + sage: len(L) # optional - sage.rings.finite_rings 1 - sage: L + sage: L # optional - sage.rings.finite_rings [Finite Field of size 199] AUTHORS: @@ -104,34 +104,43 @@ def Hom(X, Y, category=None, check=True): EXAMPLES:: - sage: V = VectorSpace(QQ,3) - sage: Hom(V, V) + sage: V = VectorSpace(QQ, 3) # optional - sage.modules + sage: Hom(V, V) # optional - sage.modules Set of Morphisms (Linear Transformations) from Vector space of dimension 3 over Rational Field to Vector space of dimension 3 over Rational Field - sage: G = AlternatingGroup(3) - sage: Hom(G, G) - Set of Morphisms from Alternating group of order 3!/2 as a permutation group to Alternating group of order 3!/2 as a permutation group in Category of finite enumerated permutation groups - sage: Hom(ZZ, QQ, Sets()) + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: Hom(G, G) # optional - sage.groups + Set of Morphisms + from Alternating group of order 3!/2 as a permutation group + to Alternating group of order 3!/2 as a permutation group + in Category of finite enumerated permutation groups + sage: Hom(ZZ, QQ, Sets()) # optional - sage.groups Set of Morphisms from Integer Ring to Rational Field in Category of sets - sage: Hom(FreeModule(ZZ,1), FreeModule(QQ,1)) - Set of Morphisms from Ambient free module of rank 1 over the principal ideal domain Integer Ring to Vector space of dimension 1 over Rational Field in Category of commutative additive groups - sage: Hom(FreeModule(QQ,1), FreeModule(ZZ,1)) - Set of Morphisms from Vector space of dimension 1 over Rational Field to Ambient free module of rank 1 over the principal ideal domain Integer Ring in Category of commutative additive groups + sage: Hom(FreeModule(ZZ, 1), FreeModule(QQ, 1)) # optional - sage.modules + Set of Morphisms + from Ambient free module of rank 1 over the principal ideal domain Integer Ring + to Vector space of dimension 1 over Rational Field + in Category of commutative additive groups + sage: Hom(FreeModule(QQ, 1), FreeModule(ZZ, 1)) # optional - sage.modules + Set of Morphisms + from Vector space of dimension 1 over Rational Field + to Ambient free module of rank 1 over the principal ideal domain Integer Ring + in Category of commutative additive groups Here, we test against a memory leak that has been fixed at :trac:`11521` by using a weak cache:: - sage: for p in prime_range(10^3): + sage: for p in prime_range(10^3): # optional - sage.rings.finite_rings ....: K = GF(p) ....: a = K(0) sage: import gc sage: gc.collect() # random 624 - sage: from sage.rings.finite_rings.finite_field_prime_modn import FiniteField_prime_modn as FF - sage: L = [x for x in gc.get_objects() if isinstance(x, FF)] - sage: len(L), L[0] + sage: from sage.rings.finite_rings.finite_field_prime_modn import FiniteField_prime_modn as FF # optional - sage.rings.finite_rings + sage: L = [x for x in gc.get_objects() if isinstance(x, FF)] # optional - sage.rings.finite_rings + sage: len(L), L[0] # optional - sage.rings.finite_rings (1, Finite Field of size 997) To illustrate the choice of the category, we consider the @@ -139,13 +148,13 @@ def Hom(X, Y, category=None, check=True): sage: X = ZZ; X Integer Ring - sage: Y = SymmetricGroup(3); Y + sage: Y = SymmetricGroup(3); Y # optional - sage.groups Symmetric group of order 3! as a permutation group By default, the smallest category containing both ``X`` and ``Y``, is used:: - sage: Hom(X, Y) + sage: Hom(X, Y) # optional - sage.groups Set of Morphisms from Integer Ring to Symmetric group of order 3! as a permutation group in Category of enumerated monoids @@ -153,10 +162,13 @@ def Hom(X, Y, category=None, check=True): Otherwise, if ``category`` is specified, then ``category`` is used, after checking that ``X`` and ``Y`` are indeed in ``category``:: - sage: Hom(X, Y, Magmas()) - Set of Morphisms from Integer Ring to Symmetric group of order 3! as a permutation group in Category of magmas + sage: Hom(X, Y, Magmas()) # optional - sage.groups + Set of Morphisms + from Integer Ring + to Symmetric group of order 3! as a permutation group + in Category of magmas - sage: Hom(X, Y, Groups()) + sage: Hom(X, Y, Groups()) # optional - sage.groups Traceback (most recent call last): ... ValueError: Integer Ring is not in Category of groups @@ -183,10 +195,10 @@ def Hom(X, Y, category=None, check=True): Homset are unique parents:: - sage: k = GF(5) - sage: H1 = Hom(k,k) - sage: H2 = Hom(k,k) - sage: H1 is H2 + sage: k = GF(5) # optional - sage.rings.finite_rings + sage: H1 = Hom(k, k) # optional - sage.rings.finite_rings + sage: H2 = Hom(k, k) # optional - sage.rings.finite_rings + sage: H1 is H2 # optional - sage.rings.finite_rings True Moreover, if no category is provided, then the result is identical @@ -231,16 +243,16 @@ def Hom(X, Y, category=None, check=True): Variation on the theme:: - sage: U1 = FreeModule(ZZ,2) - sage: U2 = FreeModule(ZZ,2,inner_product_matrix=matrix([[1,0],[0,-1]])) - sage: U1 == U2, U1 is U2 + sage: U1 = FreeModule(ZZ, 2) # optional - sage.modules + sage: U2 = FreeModule(ZZ, 2, inner_product_matrix=matrix([[1,0], [0,-1]])) # optional - sage.modules + sage: U1 == U2, U1 is U2 # optional - sage.modules (False, False) - sage: V = ZZ^3 - sage: H1 = Hom(U1, V); H2 = Hom(U2, V) - sage: H1 == H2, H1 is H2 + sage: V = ZZ^3 # optional - sage.modules + sage: H1 = Hom(U1, V); H2 = Hom(U2, V) # optional - sage.modules + sage: H1 == H2, H1 is H2 # optional - sage.modules (False, False) - sage: H1 = Hom(V, U1); H2 = Hom(V, U2) - sage: H1 == H2, H1 is H2 + sage: H1 = Hom(V, U1); H2 = Hom(V, U2) # optional - sage.modules + sage: H1 == H2, H1 is H2 # optional - sage.modules (False, False) Since :trac:`11900`, the meet of the categories of the given arguments is @@ -249,12 +261,18 @@ def Hom(X, Y, category=None, check=True): sage: PA = Parent(category=Algebras(QQ)) sage: PJ = Parent(category=Rings() & Modules(QQ)) - sage: Hom(PA,PJ) - Set of Homomorphisms from to - sage: Hom(PA,PJ).category() - Category of homsets of unital magmas and right modules over Rational Field and left modules over Rational Field - sage: Hom(PA,PJ, Rngs()) - Set of Morphisms from to in Category of rngs + sage: Hom(PA, PJ) + Set of Homomorphisms + from + to + sage: Hom(PA, PJ).category() + Category of homsets of + unital magmas and right modules over Rational Field + and left modules over Rational Field + sage: Hom(PA, PJ, Rngs()) + Set of Morphisms + from + to in Category of rngs .. TODO:: @@ -280,17 +298,17 @@ def Hom(X, Y, category=None, check=True): Checks that the domain and codomain are in the specified category. Case of a non parent:: - sage: S = SimplicialComplex([[1,2], [1,4]]); S.rename("S") - sage: Hom(S, S, SimplicialComplexes()) + sage: S = SimplicialComplex([[1,2], [1,4]]); S.rename("S") # optional - sage.graphs + sage: Hom(S, S, SimplicialComplexes()) # optional - sage.graphs Set of Morphisms from S to S in Category of finite simplicial complexes - sage: Hom(Set(), S, Sets()) + sage: Hom(Set(), S, Sets()) # optional - sage.graphs Set of Morphisms from {} to S in Category of sets - sage: Hom(S, Set(), Sets()) + sage: Hom(S, Set(), Sets()) # optional - sage.graphs Set of Morphisms from S to {} in Category of sets - sage: H = Hom(S, S, ChainComplexes(QQ)) + sage: H = Hom(S, S, ChainComplexes(QQ)) # optional - sage.graphs Traceback (most recent call last): ... ValueError: S is not in Category of chain complexes over Rational Field @@ -303,11 +321,11 @@ def Hom(X, Y, category=None, check=True): ....: def super_categories(self): return [Objects()] ....: def __contains__(self, X): return True sage: C = PermissiveCategory(); C.rename("Permissive category") - sage: S.category().is_subcategory(C) + sage: S.category().is_subcategory(C) # optional - sage.graphs False - sage: S in C + sage: S in C # optional - sage.graphs True - sage: Hom(S, S, C) + sage: Hom(S, S, C) # optional - sage.graphs Set of Morphisms from S to S in Permissive category With ``check=False``, uninitialized parents, as can appear upon @@ -331,16 +349,16 @@ def Hom(X, Y, category=None, check=True): uninitialized parent:: sage: P. = QQ['x,y'] - sage: Q = P.quotient([x^2-1,y^2-1]) - sage: q = Q.an_element() - sage: explain_pickle(dumps(Q)) + sage: Q = P.quotient([x^2-1, y^2-1]) # optional - sage.libs.singular + sage: q = Q.an_element() # optional - sage.libs.singular + sage: explain_pickle(dumps(Q)) # optional - sage.libs.singular pg_... ... = pg_dynamic_class('QuotientRing_generic_with_category', (pg_QuotientRing_generic, pg_getattr(..., 'parent_class')), None, None, pg_QuotientRing_generic) si... = unpickle_newobj(..., ()) ... si... = pg_unpickle_MPolynomialRing_libsingular(..., ('x', 'y'), ...) si... = ... pg_Hom(si..., si..., ...) ... - sage: Q == loads(dumps(Q)) + sage: Q == loads(dumps(Q)) # optional - sage.libs.singular True Check that the ``_Hom_`` method of the ``category`` input is used:: @@ -486,21 +504,24 @@ def End(X, category=None): EXAMPLES:: - sage: V = VectorSpace(QQ, 3) - sage: End(V) - Set of Morphisms (Linear Transformations) from - Vector space of dimension 3 over Rational Field to - Vector space of dimension 3 over Rational Field + sage: V = VectorSpace(QQ, 3) # optional - sage.modules + sage: End(V) # optional - sage.modules + Set of Morphisms (Linear Transformations) + from Vector space of dimension 3 over Rational Field + to Vector space of dimension 3 over Rational Field :: - sage: G = AlternatingGroup(3) - sage: S = End(G); S - Set of Morphisms from Alternating group of order 3!/2 as a permutation group to Alternating group of order 3!/2 as a permutation group in Category of finite enumerated permutation groups + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: S = End(G); S # optional - sage.groups + Set of Morphisms + from Alternating group of order 3!/2 as a permutation group + to Alternating group of order 3!/2 as a permutation group + in Category of finite enumerated permutation groups sage: from sage.categories.homset import is_Endset - sage: is_Endset(S) + sage: is_Endset(S) # optional - sage.groups True - sage: S.domain() + sage: S.domain() # optional - sage.groups Alternating group of order 3!/2 as a permutation group To avoid creating superfluous categories, a homset in a category @@ -512,13 +533,13 @@ def End(X, category=None): groups currently implement nothing more than unital magmas about their homsets, we have:: - sage: G = GL(3,3) - sage: G.category() + sage: G = GL(3, 3) # optional - sage.groups + sage: G.category() # optional - sage.groups Category of finite groups - sage: H = Hom(G,G) - sage: H.homset_category() + sage: H = Hom(G, G) # optional - sage.groups + sage: H.homset_category() # optional - sage.groups Category of finite groups - sage: H.category() + sage: H.category() # optional - sage.groups Category of endsets of unital magmas Similarly, a ring morphism just needs to preserve addition, @@ -557,8 +578,8 @@ class Homset(Set_generic): EXAMPLES:: - sage: H = Hom(QQ^2, QQ^3) - sage: loads(H.dumps()) is H + sage: H = Hom(QQ^2, QQ^3) # optional - sage.modules + sage: loads(H.dumps()) is H # optional - sage.modules True Homsets of unique parents are unique as well:: @@ -571,10 +592,11 @@ class Homset(Set_generic): Conversely, homsets of non-unique parents are non-unique:: - sage: H = End(ProductProjectiveSpaces(QQ, [1, 1])) - sage: loads(dumps(ProductProjectiveSpaces(QQ, [1, 1]))) is ProductProjectiveSpaces(QQ, [1, 1]) + sage: P11 = ProductProjectiveSpaces(QQ, [1, 1]) + sage: H = End(P11) + sage: loads(dumps(P11)) is ProductProjectiveSpaces(QQ, [1, 1]) False - sage: loads(dumps(ProductProjectiveSpaces(QQ, [1, 1]))) == ProductProjectiveSpaces(QQ, [1, 1]) + sage: loads(dumps(P11)) == ProductProjectiveSpaces(QQ, [1, 1]) True sage: loads(dumps(H)) is H False @@ -621,12 +643,12 @@ def __init__(self, X, Y, category=None, base=None, check=True): sage: Hom(R, R, category=Sets()).base_ring() sage: Hom(R, R, category=Modules(QQ)).base_ring() Rational Field - sage: Hom(QQ^3, QQ^3, category=Modules(QQ)).base_ring() + sage: Hom(QQ^3, QQ^3, category=Modules(QQ)).base_ring() # optional - sage.modules Rational Field For whatever it's worth, the ``base`` arguments takes precedence:: - sage: MyHomset(ZZ^3, ZZ^3, base = QQ).base_ring() + sage: MyHomset(ZZ^3, ZZ^3, base=QQ).base_ring() # optional - sage.modules Rational Field """ self._domain = X @@ -679,8 +701,8 @@ def __reduce__(self): EXAMPLES:: - sage: H = Hom(QQ^2, QQ^3) - sage: H.__reduce__() + sage: H = Hom(QQ^2, QQ^3) # optional - sage.modules + sage: H.__reduce__() # optional - sage.modules (, (Vector space of dimension 2 over Rational Field, Vector space of dimension 3 over Rational Field, @@ -690,18 +712,18 @@ def __reduce__(self): TESTS:: - sage: loads(H.dumps()) is H + sage: loads(H.dumps()) is H # optional - sage.modules True Homsets of non-unique parents are non-unique as well:: - sage: G = PermutationGroup([[(1,2,3),(4,5)],[(3,4)]]) - sage: G is loads(dumps(G)) + sage: G = PermutationGroup([[(1, 2, 3), (4, 5)], [(3, 4)]]) # optional - sage.groups + sage: G is loads(dumps(G)) # optional - sage.groups False - sage: H = Hom(G,G) - sage: H is loads(dumps(H)) + sage: H = Hom(G, G) # optional - sage.groups + sage: H is loads(dumps(H)) # optional - sage.groups False - sage: H == loads(dumps(H)) + sage: H == loads(dumps(H)) # optional - sage.groups True """ return Hom, (self._domain, self._codomain, self.__category, False) @@ -710,7 +732,7 @@ def _repr_(self): """ TESTS:: - sage: Hom(ZZ^2, QQ, category=Sets())._repr_() + sage: Hom(ZZ^2, QQ, category=Sets())._repr_() # optional - sage.modules 'Set of Morphisms from Ambient free module of rank 2 over the principal ideal domain Integer Ring to Rational Field in Category of sets' """ return "Set of Morphisms from {} to {} in {}".format(self._domain, @@ -727,10 +749,10 @@ def __hash__(self): sage: hash(Hom(QQ, ZZ)) == hash((QQ, ZZ, QQ)) True - sage: E = EllipticCurve('37a') # optional - sage.symbolic - sage: H = E(0).parent(); H # optional - sage.symbolic + sage: E = EllipticCurve('37a') # optional - sage.symbolic + sage: H = E(0).parent(); H # optional - sage.symbolic Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field - sage: hash(H) == hash((H.domain(), H.codomain(), H.base())) + sage: hash(H) == hash((H.domain(), H.codomain(), H.base())) # optional - sage.symbolic True """ return hash((self._domain, self._codomain, self.base())) @@ -751,8 +773,8 @@ def homset_category(self): EXAMPLES:: - sage: H = Hom(AlternatingGroup(4), AlternatingGroup(7)) - sage: H.homset_category() + sage: H = Hom(AlternatingGroup(4), AlternatingGroup(7)) # optional - sage.groups + sage: H.homset_category() # optional - sage.groups Category of finite enumerated permutation groups """ return self.__category @@ -763,9 +785,9 @@ def _element_constructor_(self, x, check=None, **options): EXAMPLES:: - sage: H = Hom(SymmetricGroup(4), SymmetricGroup(7)) - sage: phi = Hom(SymmetricGroup(5), SymmetricGroup(6)).natural_map() - sage: phi + sage: H = Hom(SymmetricGroup(4), SymmetricGroup(7)) # optional - sage.groups + sage: phi = Hom(SymmetricGroup(5), SymmetricGroup(6)).natural_map() # optional - sage.groups + sage: phi # optional - sage.groups Coercion morphism: From: Symmetric group of order 5! as a permutation group To: Symmetric group of order 6! as a permutation group @@ -777,7 +799,7 @@ def _element_constructor_(self, x, check=None, **options): collection, if there is a strong reference to its domain (which is the case here):: - sage: H(phi) + sage: H(phi) # optional - sage.groups Composite map: From: Symmetric group of order 4! as a permutation group To: Symmetric group of order 7! as a permutation group @@ -798,7 +820,7 @@ def _element_constructor_(self, x, check=None, **options): Also note that making a copy of the resulting map will automatically make strengthened copies of the composed maps:: - sage: copy(H(phi)) + sage: copy(H(phi)) # optional - sage.groups Composite map: From: Symmetric group of order 4! as a permutation group To: Symmetric group of order 7! as a permutation group @@ -825,7 +847,7 @@ def _element_constructor_(self, x, check=None, **options): (2, 3, 4) sage: H = Hom(Set([1,2,3]), Set([1,2,3])) - sage: f = H( lambda x: 4-x ) + sage: f = H(lambda x: 4 - x) sage: f.parent() Set of Morphisms from {1, 2, 3} to {1, 2, 3} in Category of finite enumerated sets sage: f(1), f(2), f(3) # todo: not implemented @@ -884,24 +906,24 @@ def _element_constructor_(self, x, check=None, **options): TESTS:: - sage: G. = FreeGroup() - sage: H = Hom(G, G) - sage: H(H.identity()) + sage: G. = FreeGroup() # optional - sage.groups + sage: H = Hom(G, G) # optional - sage.groups + sage: H(H.identity()) # optional - sage.groups Identity endomorphism of Free Group on generators {x, y, z} - sage: H() + sage: H() # optional - sage.groups Traceback (most recent call last): ... TypeError: unable to convert 0 to an element of Set of Morphisms from Free Group on generators {x, y, z} to Free Group on generators {x, y, z} in Category of infinite groups - sage: H("whatever") + sage: H("whatever") # optional - sage.groups Traceback (most recent call last): ... TypeError: unable to convert 'whatever' to an element of Set of Morphisms from Free Group on generators {x, y, z} to Free Group on generators {x, y, z} in Category of infinite groups - sage: HH = Hom(H, H) - sage: HH(HH.identity(), foo="bar") + sage: HH = Hom(H, H) # optional - sage.groups + sage: HH(HH.identity(), foo="bar") # optional - sage.groups Traceback (most recent call last): ... NotImplementedError: no keywords are implemented for @@ -982,41 +1004,41 @@ class of ``C`` will be inherited by *all* subcategories of this point this is the simplest one to create (gosh):: sage: cat = Groups().Finite().Commutative() - sage: C3 = PermutationGroup([(1,2,3)]) - sage: C3._refine_category_(cat) - sage: C2 = PermutationGroup([(1,2)]) - sage: C2._refine_category_(cat) - sage: H = Hom(C3, C2, cat) - sage: H.homset_category() + sage: C3 = PermutationGroup([(1,2,3)]) # optional - sage.groups + sage: C3._refine_category_(cat) # optional - sage.groups + sage: C2 = PermutationGroup([(1,2)]) # optional - sage.groups + sage: C2._refine_category_(cat) # optional - sage.groups + sage: H = Hom(C3, C2, cat) # optional - sage.groups + sage: H.homset_category() # optional - sage.groups Category of finite commutative groups - sage: H.category() + sage: H.category() # optional - sage.groups Category of homsets of unital magmas - sage: cls = H._abstract_element_class; cls + sage: cls = H._abstract_element_class; cls # optional - sage.groups - sage: cls.__bases__ == (H.category().element_class, H.homset_category().morphism_class) + sage: cls.__bases__ == (H.category().element_class, H.homset_category().morphism_class) # optional - sage.groups True A morphism of finite commutative semigroups is also a morphism of semigroups, of magmas, ...; it thus inherits code from all those categories:: - sage: issubclass(cls, Semigroups().Finite().morphism_class) + sage: issubclass(cls, Semigroups().Finite().morphism_class) # optional - sage.groups True - sage: issubclass(cls, Semigroups().morphism_class) + sage: issubclass(cls, Semigroups().morphism_class) # optional - sage.groups True - sage: issubclass(cls, Magmas().Commutative().morphism_class) + sage: issubclass(cls, Magmas().Commutative().morphism_class) # optional - sage.groups True - sage: issubclass(cls, Magmas().morphism_class) + sage: issubclass(cls, Magmas().morphism_class) # optional - sage.groups True - sage: issubclass(cls, Sets().morphism_class) + sage: issubclass(cls, Sets().morphism_class) # optional - sage.groups True Recall that FiniteMonoids() is a full subcategory of ``Monoids()``, but not of ``FiniteSemigroups()``. Thus:: - sage: issubclass(cls, Monoids().Finite().Homsets().element_class) + sage: issubclass(cls, Monoids().Finite().Homsets().element_class) # optional - sage.groups True - sage: issubclass(cls, Semigroups().Finite().Homsets().element_class) + sage: issubclass(cls, Semigroups().Finite().Homsets().element_class) # optional - sage.groups False """ class_name = "%s._abstract_element_class"%self.__class__.__name__ @@ -1117,11 +1139,13 @@ def natural_map(self): Coercion morphism: From: Univariate Polynomial Ring in t over Integer Ring To: Univariate Polynomial Ring in t over Rational Field - sage: H = Hom(QQ['t'],GF(3)['t']) - sage: H.natural_map() + sage: H = Hom(QQ['t'], GF(3)['t']) # optional - sage.rings.finite_rings + sage: H.natural_map() # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: natural coercion morphism from Univariate Polynomial Ring in t over Rational Field to Univariate Polynomial Ring in t over Finite Field of size 3 not defined + TypeError: natural coercion morphism + from Univariate Polynomial Ring in t over Rational Field + to Univariate Polynomial Ring in t over Finite Field of size 3 not defined """ return morphism.FormalCoercionMorphism(self) # good default in many cases @@ -1162,9 +1186,10 @@ def one(self): EXAMPLES:: - sage: K = GaussianIntegers() - sage: End(K).one() - Identity endomorphism of Gaussian Integers in Number Field in I with defining polynomial x^2 + 1 with I = 1*I + sage: K = GaussianIntegers() # optional - sage.rings.number_field + sage: End(K).one() # optional - sage.rings.number_field + Identity endomorphism of Gaussian Integers in Number Field in I + with defining polynomial x^2 + 1 with I = 1*I """ return self.identity() @@ -1205,21 +1230,21 @@ def reversed(self): EXAMPLES:: - sage: H = Hom(ZZ^2, ZZ^3); H + sage: H = Hom(ZZ^2, ZZ^3); H # optional - sage.modules Set of Morphisms from Ambient free module of rank 2 over the principal ideal domain Integer Ring to Ambient free module of rank 3 over the principal ideal domain Integer Ring in Category of finite dimensional modules with basis over (euclidean domains and infinite enumerated sets and metric spaces) - sage: type(H) + sage: type(H) # optional - sage.modules - sage: H.reversed() + sage: H.reversed() # optional - sage.modules Set of Morphisms from Ambient free module of rank 3 over the principal ideal domain Integer Ring to Ambient free module of rank 2 over the principal ideal domain Integer Ring in Category of finite dimensional modules with basis over (euclidean domains and infinite enumerated sets and metric spaces) - sage: type(H.reversed()) + sage: type(H.reversed()) # optional - sage.modules """ return Hom(self.codomain(), self.domain(), diff --git a/src/sage/categories/hopf_algebras.py b/src/sage/categories/hopf_algebras.py index 84858c7c5bf..ecff3fd58cc 100644 --- a/src/sage/categories/hopf_algebras.py +++ b/src/sage/categories/hopf_algebras.py @@ -67,17 +67,18 @@ def antipode(self): EXAMPLES:: - sage: A = HopfAlgebrasWithBasis(QQ).example(); A - An example of Hopf algebra with basis: the group algebra of the Dihedral group of order 6 as a permutation group over Rational Field - sage: [a,b] = A.algebra_generators() - sage: a, a.antipode() + sage: A = HopfAlgebrasWithBasis(QQ).example(); A # optional - sage.groups + An example of Hopf algebra with basis: the group algebra of the + Dihedral group of order 6 as a permutation group over Rational Field + sage: [a,b] = A.algebra_generators() # optional - sage.groups + sage: a, a.antipode() # optional - sage.groups (B[(1,2,3)], B[(1,3,2)]) - sage: b, b.antipode() + sage: b, b.antipode() # optional - sage.groups (B[(1,3)], B[(1,3)]) TESTS:: - sage: all(x.antipode() * x == A.one() for x in A.basis()) + sage: all(x.antipode() * x == A.one() for x in A.basis()) # optional - sage.groups True """ return self.parent().antipode(self) @@ -135,9 +136,9 @@ def antipode(self): EXAMPLES:: - sage: A = SteenrodAlgebra(3) - sage: a = A.an_element() - sage: a, a.antipode() + sage: A = SteenrodAlgebra(3) # optional - sage.combinat sage.modules + sage: a = A.an_element() # optional - sage.combinat sage.modules + sage: a, a.antipode() # optional - sage.combinat sage.modules (2 Q_1 Q_3 P(2,1), Q_1 Q_3 P(2,1)) """ return self.parent().antipode(self) @@ -204,11 +205,11 @@ def antipode_by_coercion(self, x): EXAMPLES:: - sage: N = NonCommutativeSymmetricFunctions(QQ) - sage: R = N.ribbon() - sage: R.antipode_by_coercion.__module__ + sage: N = NonCommutativeSymmetricFunctions(QQ) # optional - sage.combinat + sage: R = N.ribbon() # optional - sage.combinat + sage: R.antipode_by_coercion.__module__ # optional - sage.combinat 'sage.categories.hopf_algebras' - sage: R.antipode_by_coercion(R[1,3,1]) + sage: R.antipode_by_coercion(R[1,3,1]) # optional - sage.combinat -R[2, 1, 2] """ R = self.realization_of().a_realization() diff --git a/src/sage/categories/hopf_algebras_with_basis.py b/src/sage/categories/hopf_algebras_with_basis.py index 79a0b69ce14..ea401896ca0 100644 --- a/src/sage/categories/hopf_algebras_with_basis.py +++ b/src/sage/categories/hopf_algebras_with_basis.py @@ -33,43 +33,44 @@ class HopfAlgebrasWithBasis(CategoryWithAxiom_over_base_ring): We now show how to use a simple Hopf algebra, namely the group algebra of the dihedral group (see also AlgebrasWithBasis):: - sage: A = C.example(); A - An example of Hopf algebra with basis: the group algebra of the Dihedral group of order 6 as a permutation group over Rational Field - sage: A.__custom_name = "A" - sage: A.category() + sage: A = C.example(); A # optional - sage.groups + An example of Hopf algebra with basis: the group algebra of the + Dihedral group of order 6 as a permutation group over Rational Field + sage: A.__custom_name = "A" # optional - sage.groups + sage: A.category() # optional - sage.groups Category of finite dimensional hopf algebras with basis over Rational Field - sage: A.one_basis() + sage: A.one_basis() # optional - sage.groups () - sage: A.one() + sage: A.one() # optional - sage.groups B[()] - sage: A.base_ring() + sage: A.base_ring() # optional - sage.groups Rational Field - sage: A.basis().keys() + sage: A.basis().keys() # optional - sage.groups Dihedral group of order 6 as a permutation group - sage: [a,b] = A.algebra_generators() - sage: a, b + sage: [a,b] = A.algebra_generators() # optional - sage.groups + sage: a, b # optional - sage.groups (B[(1,2,3)], B[(1,3)]) - sage: a^3, b^2 + sage: a^3, b^2 # optional - sage.groups (B[()], B[()]) - sage: a*b + sage: a*b # optional - sage.groups B[(1,2)] - sage: A.product # todo: not quite ... + sage: A.product # todo: not quite ... # optional - sage.groups - sage: A.product(b,b) + sage: A.product(b, b) # optional - sage.groups B[()] - sage: A.zero().coproduct() + sage: A.zero().coproduct() # optional - sage.groups 0 - sage: A.zero().coproduct().parent() + sage: A.zero().coproduct().parent() # optional - sage.groups A # A - sage: a.coproduct() + sage: a.coproduct() # optional - sage.groups B[(1,2,3)] # B[(1,2,3)] - sage: TestSuite(A).run(verbose=True) + sage: TestSuite(A).run(verbose=True) # optional - sage.groups running ._test_additive_associativity() . . . pass running ._test_an_element() . . . pass running ._test_antipode() . . . pass @@ -100,32 +101,35 @@ class HopfAlgebrasWithBasis(CategoryWithAxiom_over_base_ring): running ._test_prod() . . . pass running ._test_some_elements() . . . pass running ._test_zero() . . . pass - sage: A.__class__ + sage: A.__class__ # optional - sage.groups - sage: A.element_class + sage: A.element_class # optional - sage.groups Let us look at the code for implementing A:: - sage: A?? # todo: not implemented + sage: A?? # todo: not implemented # optional - sage.groups TESTS:: - sage: TestSuite(A).run() - sage: TestSuite(C).run() + sage: TestSuite(A).run() # optional - sage.groups + sage: TestSuite(C).run() # optional - sage.groups """ def example(self, G=None): """ Returns an example of algebra with basis:: - sage: HopfAlgebrasWithBasis(QQ['x']).example() - An example of Hopf algebra with basis: the group algebra of the Dihedral group of order 6 as a permutation group over Univariate Polynomial Ring in x over Rational Field + sage: HopfAlgebrasWithBasis(QQ['x']).example() # optional - sage.groups + An example of Hopf algebra with basis: the group algebra of the + Dihedral group of order 6 as a permutation group + over Univariate Polynomial Ring in x over Rational Field An other group can be specified as optional argument:: - sage: HopfAlgebrasWithBasis(QQ).example(SymmetricGroup(4)) - An example of Hopf algebra with basis: the group algebra of the Symmetric group of order 4! as a permutation group over Rational Field + sage: HopfAlgebrasWithBasis(QQ).example(SymmetricGroup(4)) # optional - sage.groups + An example of Hopf algebra with basis: the group algebra of the + Symmetric group of order 4! as a permutation group over Rational Field """ from sage.categories.examples.hopf_algebras_with_basis import MyGroupAlgebra from sage.groups.perm_gps.permgroup_named import DihedralGroup @@ -175,12 +179,12 @@ def antipode_on_basis(self, x): EXAMPLES:: - sage: A = HopfAlgebrasWithBasis(QQ).example() - sage: W = A.basis().keys(); W + sage: A = HopfAlgebrasWithBasis(QQ).example() # optional - sage.groups + sage: W = A.basis().keys(); W # optional - sage.groups Dihedral group of order 6 as a permutation group - sage: w = W.gen(0); w + sage: w = W.gen(0); w # optional - sage.groups (1,2,3) - sage: A.antipode_on_basis(w) + sage: A.antipode_on_basis(w) # optional - sage.groups B[(1,3,2)] """ @@ -196,18 +200,19 @@ def antipode(self): EXAMPLES:: - sage: A = HopfAlgebrasWithBasis(ZZ).example(); A - An example of Hopf algebra with basis: the group algebra of the Dihedral group of order 6 as a permutation group over Integer Ring - sage: A = HopfAlgebrasWithBasis(QQ).example() - sage: [a,b] = A.algebra_generators() - sage: a, A.antipode(a) + sage: A = HopfAlgebrasWithBasis(ZZ).example(); A # optional - sage.groups + An example of Hopf algebra with basis: the group algebra of the + Dihedral group of order 6 as a permutation group over Integer Ring + sage: A = HopfAlgebrasWithBasis(QQ).example() # optional - sage.groups + sage: [a,b] = A.algebra_generators() # optional - sage.groups + sage: a, A.antipode(a) # optional - sage.groups (B[(1,2,3)], B[(1,3,2)]) - sage: b, A.antipode(b) + sage: b, A.antipode(b) # optional - sage.groups (B[(1,3)], B[(1,3)]) TESTS:: - sage: all(A.antipode(x) * x == A.one() for x in A.basis()) + sage: all(A.antipode(x) * x == A.one() for x in A.basis()) # optional - sage.groups True """ if self.antipode_on_basis is not NotImplemented: @@ -239,13 +244,13 @@ def _test_antipode(self, **options): TESTS:: - sage: R = NonCommutativeSymmetricFunctions(QQ).ribbon() - sage: R._test_antipode() + sage: R = NonCommutativeSymmetricFunctions(QQ).ribbon() # optional - sage.combinat + sage: R._test_antipode() # optional - sage.combinat :: - sage: s = SymmetricFunctions(QQ).schur() - sage: s._test_antipode() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: s._test_antipode() # optional - sage.combinat """ tester = self._tester(**options) diff --git a/src/sage/categories/integral_domains.py b/src/sage/categories/integral_domains.py index 2d5d7730693..ca910a16e60 100644 --- a/src/sage/categories/integral_domains.py +++ b/src/sage/categories/integral_domains.py @@ -45,7 +45,7 @@ def __contains__(self, x): """ EXAMPLES:: - sage: GF(4, "a") in IntegralDomains() + sage: GF(4, "a") in IntegralDomains() # optional - sage.rings.finite_rings True sage: QQ in IntegralDomains() True @@ -108,10 +108,10 @@ def is_integral_domain(self, proof=True): sage: Parent(QQ, category=IntegralDomains()).is_integral_domain() True - sage: L. = LazyLaurentSeriesRing(QQ) - sage: L.is_integral_domain() + sage: L. = LazyLaurentSeriesRing(QQ) # optional - sage.combinat + sage: L.is_integral_domain() # optional - sage.combinat True - sage: L.is_integral_domain(proof=True) + sage: L.is_integral_domain(proof=True) # optional - sage.combinat True """ return True @@ -129,7 +129,7 @@ def _test_fraction_field(self, **options): tester = self._tester(**options) try: fraction_field = self.fraction_field() - except AttributeError: + except (AttributeError, ImportError): # some integral domains do not implement fraction_field() yet if self in Fields(): raise diff --git a/src/sage/categories/kac_moody_algebras.py b/src/sage/categories/kac_moody_algebras.py index cd7af55333d..040387a3325 100644 --- a/src/sage/categories/kac_moody_algebras.py +++ b/src/sage/categories/kac_moody_algebras.py @@ -43,12 +43,12 @@ def example(self, n=2): EXAMPLES:: sage: from sage.categories.kac_moody_algebras import KacMoodyAlgebras - sage: KacMoodyAlgebras(QQ).example() + sage: KacMoodyAlgebras(QQ).example() # optional - sage.combinat sage.modules Lie algebra of ['A', 2] in the Chevalley basis We can specify the rank of the example:: - sage: KacMoodyAlgebras(QQ).example(4) + sage: KacMoodyAlgebras(QQ).example(4) # optional - sage.combinat sage.modules Lie algebra of ['A', 4] in the Chevalley basis """ from sage.algebras.lie_algebras.classical_lie_algebra import LieAlgebraChevalleyBasis @@ -61,8 +61,8 @@ def cartan_type(self): EXAMPLES:: - sage: L = LieAlgebra(QQ, cartan_type=['A', 2]) - sage: L.cartan_type() + sage: L = LieAlgebra(QQ, cartan_type=['A', 2]) # optional - sage.combinat sage.modules + sage: L.cartan_type() # optional - sage.combinat sage.modules ['A', 2] """ return self._cartan_type @@ -73,8 +73,8 @@ def weyl_group(self): EXAMPLES:: - sage: L = LieAlgebra(QQ, cartan_type=['A', 2]) - sage: L.weyl_group() + sage: L = LieAlgebra(QQ, cartan_type=['A', 2]) # optional - sage.combinat sage.modules + sage: L.weyl_group() # optional - sage.combinat sage.modules Weyl Group of type ['A', 2] (as a matrix group acting on the ambient space) """ from sage.combinat.root_system.weyl_group import WeylGroup diff --git a/src/sage/categories/lambda_bracket_algebras.py b/src/sage/categories/lambda_bracket_algebras.py index 531cfb826b1..8818c0a918a 100644 --- a/src/sage/categories/lambda_bracket_algebras.py +++ b/src/sage/categories/lambda_bracket_algebras.py @@ -45,9 +45,10 @@ def __classcall_private__(cls, R, check=True): EXAMPLES:: - sage: LieConformalAlgebras(QuaternionAlgebra(2)) + sage: LieConformalAlgebras(QuaternionAlgebra(2)) # optional - sage.combinat sage.modules Traceback (most recent call last): - ValueError: base must be a commutative ring got Quaternion Algebra (-1, -1) with base ring Rational Field + ValueError: base must be a commutative ring + got Quaternion Algebra (-1, -1) with base ring Rational Field sage: LieConformalAlgebras(ZZ) Category of Lie conformal algebras over Integer Ring """ @@ -117,8 +118,8 @@ def ideal(self, *gens, **kwds): EXAMPLES:: - sage: Vir = lie_conformal_algebras.Virasoro(QQ) - sage: Vir.ideal() + sage: Vir = lie_conformal_algebras.Virasoro(QQ) # optional - sage.combinat sage.modules + sage: Vir.ideal() # optional - sage.combinat sage.modules Traceback (most recent call last): ... NotImplementedError: ideals of Lie Conformal algebras are not implemented yet @@ -136,21 +137,21 @@ def bracket(self, rhs): The brackets of the Virasoro Lie conformal algebra:: - sage: Vir = lie_conformal_algebras.Virasoro(QQ); L = Vir.0 - sage: L.bracket(L) + sage: Vir = lie_conformal_algebras.Virasoro(QQ); L = Vir.0 # optional - sage.combinat sage.modules + sage: L.bracket(L) # optional - sage.combinat sage.modules {0: TL, 1: 2*L, 3: 1/2*C} - sage: L.bracket(L.T()) + sage: L.bracket(L.T()) # optional - sage.combinat sage.modules {0: 2*T^(2)L, 1: 3*TL, 2: 4*L, 4: 2*C} Now with a current algebra:: - sage: V = lie_conformal_algebras.Affine(QQ, 'A1') - sage: V.gens() + sage: V = lie_conformal_algebras.Affine(QQ, 'A1') # optional - sage.combinat sage.modules + sage: V.gens() # optional - sage.combinat sage.modules (B[alpha[1]], B[alphacheck[1]], B[-alpha[1]], B['K']) - sage: E = V.0; H = V.1; F = V.2; - sage: H.bracket(H) + sage: E = V.0; H = V.1; F = V.2 # optional - sage.combinat sage.modules + sage: H.bracket(H) # optional - sage.combinat sage.modules {1: 2*B['K']} - sage: E.bracket(F) + sage: E.bracket(F) # optional - sage.combinat sage.modules {0: B[alphacheck[1]], 1: B['K']} """ return self._bracket_(rhs) @@ -169,21 +170,21 @@ def _bracket_(self, rhs): The brackets of the Virasoro Lie conformal Algebra:: - sage: Vir = lie_conformal_algebras.Virasoro(QQ); L = Vir.0 - sage: L._bracket_(L) + sage: Vir = lie_conformal_algebras.Virasoro(QQ); L = Vir.0 # optional - sage.combinat sage.modules + sage: L._bracket_(L) # optional - sage.combinat sage.modules {0: TL, 1: 2*L, 3: 1/2*C} - sage: L._bracket_(L.T()) + sage: L._bracket_(L.T()) # optional - sage.combinat sage.modules {0: 2*T^(2)L, 1: 3*TL, 2: 4*L, 4: 2*C} Now with a current algebra:: - sage: V = lie_conformal_algebras.Affine(QQ, 'A1') - sage: V.gens() + sage: V = lie_conformal_algebras.Affine(QQ, 'A1') # optional - sage.combinat sage.modules + sage: V.gens() # optional - sage.combinat sage.modules (B[alpha[1]], B[alphacheck[1]], B[-alpha[1]], B['K']) - sage: E = V.0; H = V.1; F = V.2; - sage: H._bracket_(H) + sage: E = V.0; H = V.1; F = V.2 # optional - sage.combinat sage.modules + sage: H._bracket_(H) # optional - sage.combinat sage.modules {1: 2*B['K']} - sage: E._bracket_(F) + sage: E._bracket_(F) # optional - sage.combinat sage.modules {0: B[alphacheck[1]], 1: B['K']} """ @@ -194,16 +195,16 @@ def nproduct(self, rhs, n): EXAMPLES:: - sage: Vir = lie_conformal_algebras.Virasoro(QQ); L = Vir.0 - sage: L.nproduct(L, 3) + sage: Vir = lie_conformal_algebras.Virasoro(QQ); L = Vir.0 # optional - sage.combinat sage.modules + sage: L.nproduct(L, 3) # optional - sage.combinat sage.modules 1/2*C - sage: L.nproduct(L.T(), 0) + sage: L.nproduct(L.T(), 0) # optional - sage.combinat sage.modules 2*T^(2)L - sage: V = lie_conformal_algebras.Affine(QQ, 'A1') - sage: E = V.0; H = V.1; F = V.2; - sage: E.nproduct(H, 0) == - 2*E + sage: V = lie_conformal_algebras.Affine(QQ, 'A1') # optional - sage.combinat sage.modules + sage: E = V.0; H = V.1; F = V.2 # optional - sage.combinat sage.modules + sage: E.nproduct(H, 0) == - 2*E # optional - sage.combinat sage.modules True - sage: E.nproduct(F, 1) + sage: E.nproduct(F, 1) # optional - sage.combinat sage.modules B['K'] """ return self._nproduct_(rhs,n) @@ -219,16 +220,16 @@ def _nproduct_(self, rhs, n): EXAMPLES:: - sage: Vir = lie_conformal_algebras.Virasoro(QQ); L = Vir.0 - sage: L._nproduct_(L,3) + sage: Vir = lie_conformal_algebras.Virasoro(QQ); L = Vir.0 # optional - sage.combinat sage.modules + sage: L._nproduct_(L, 3) # optional - sage.combinat sage.modules 1/2*C - sage: L._nproduct_(L.T(),0) + sage: L._nproduct_(L.T(), 0) # optional - sage.combinat sage.modules 2*T^(2)L - sage: V = lie_conformal_algebras.Affine(QQ, 'A1') - sage: E = V.0; H = V.1; F = V.2; - sage: E._nproduct_(H,0) == - 2*E + sage: V = lie_conformal_algebras.Affine(QQ, 'A1') # optional - sage.combinat sage.modules + sage: E = V.0; H = V.1; F = V.2 # optional - sage.combinat sage.modules + sage: E._nproduct_(H, 0) == - 2*E # optional - sage.combinat sage.modules True - sage: E._nproduct_(F,1) + sage: E._nproduct_(F, 1) # optional - sage.combinat sage.modules B['K'] """ if n >= 0: @@ -253,14 +254,14 @@ def T(self, n=1): EXAMPLES:: - sage: Vir = lie_conformal_algebras.Virasoro(QQ) - sage: Vir.inject_variables() + sage: Vir = lie_conformal_algebras.Virasoro(QQ) # optional - sage.combinat sage.modules + sage: Vir.inject_variables() # optional - sage.combinat sage.modules Defining L, C - sage: L.T() + sage: L.T() # optional - sage.combinat sage.modules TL - sage: L.T(3) + sage: L.T(3) # optional - sage.combinat sage.modules 6*T^(3)L - sage: C.T() + sage: C.T() # optional - sage.combinat sage.modules 0 """ diff --git a/src/sage/categories/lambda_bracket_algebras_with_basis.py b/src/sage/categories/lambda_bracket_algebras_with_basis.py index 9b48ba34615..bb0e30908b4 100644 --- a/src/sage/categories/lambda_bracket_algebras_with_basis.py +++ b/src/sage/categories/lambda_bracket_algebras_with_basis.py @@ -25,7 +25,7 @@ class LambdaBracketAlgebrasWithBasis(CategoryWithAxiom_over_base_ring): EXAMPLES:: - sage: LieConformalAlgebras(QQbar).WithBasis() + sage: LieConformalAlgebras(QQbar).WithBasis() # optional - sage.rings.number_field Category of Lie conformal algebras with basis over Algebraic Field """ class ElementMethods: @@ -36,14 +36,14 @@ def index(self): EXAMPLES:: - sage: V = lie_conformal_algebras.NeveuSchwarz(QQ) - sage: V.inject_variables() + sage: V = lie_conformal_algebras.NeveuSchwarz(QQ) # optional - sage.combinat sage.modules + sage: V.inject_variables() # optional - sage.combinat sage.modules Defining L, G, C - sage: G.T(3).index() + sage: G.T(3).index() # optional - sage.combinat sage.modules ('G', 3) - sage: v = V.an_element(); v + sage: v = V.an_element(); v # optional - sage.combinat sage.modules L + G + C - sage: v.index() + sage: v.index() # optional - sage.combinat sage.modules Traceback (most recent call last): ... ValueError: index can only be computed for monomials, got L + G + C @@ -63,10 +63,14 @@ class FinitelyGeneratedAsLambdaBracketAlgebra(CategoryWithAxiom_over_base_ring): EXAMPLES:: - sage: C = LieConformalAlgebras(QQbar) - sage: C.WithBasis().FinitelyGenerated() - Category of finitely generated Lie conformal algebras with basis over Algebraic Field - sage: C.WithBasis().FinitelyGenerated() is C.FinitelyGenerated().WithBasis() + sage: C = LieConformalAlgebras(QQbar) # optional - sage.rings.number_field + sage: C1 = C.WithBasis().FinitelyGenerated(); C1 # optional - sage.rings.number_field + Category of finitely generated Lie conformal algebras with basis + over Algebraic Field + sage: C2 = C.FinitelyGenerated().WithBasis(); C2 # optional - sage.rings.number_field + Category of finitely generated Lie conformal algebras with basis + over Algebraic Field + sage: C1 is C2 # optional - sage.rings.number_field True """ class Graded(GradedModulesCategory): @@ -76,8 +80,10 @@ class Graded(GradedModulesCategory): EXAMPLES:: - sage: LieConformalAlgebras(QQbar).WithBasis().FinitelyGenerated().Graded() - Category of H-graded finitely generated Lie conformal algebras with basis over Algebraic Field + sage: C = LieConformalAlgebras(QQbar) # optional - sage.rings.number_field + sage: C.WithBasis().FinitelyGenerated().Graded() # optional - sage.rings.number_field + Category of H-graded finitely generated Lie conformal algebras + with basis over Algebraic Field """ class ParentMethods: @@ -88,8 +94,8 @@ def degree_on_basis(self, m): EXAMPLES:: - sage: V = lie_conformal_algebras.Virasoro(QQ) - sage: V.degree_on_basis(('L',2)) + sage: V = lie_conformal_algebras.Virasoro(QQ) # optional - sage.combinat sage.modules + sage: V.degree_on_basis(('L', 2)) # optional - sage.combinat sage.modules 4 """ if m[0] in self._central_elements: diff --git a/src/sage/categories/lattice_posets.py b/src/sage/categories/lattice_posets.py index d29635f078e..3872ca9b51f 100644 --- a/src/sage/categories/lattice_posets.py +++ b/src/sage/categories/lattice_posets.py @@ -66,8 +66,8 @@ def meet(self, x, y): EXAMPLES:: - sage: D = LatticePoset((divisors(30), attrcall("divides"))) - sage: D.meet( D(6), D(15) ) + sage: D = LatticePoset((divisors(30), attrcall("divides"))) # optional - sage.combinat + sage: D.meet( D(6), D(15) ) # optional - sage.combinat 3 """ @@ -82,7 +82,7 @@ def join(self, x, y): EXAMPLES:: - sage: D = LatticePoset((divisors(60), attrcall("divides"))) - sage: D.join( D(6), D(10) ) + sage: D = LatticePoset((divisors(60), attrcall("divides"))) # optional - sage.combinat + sage: D.join( D(6), D(10) ) # optional - sage.combinat 30 """ diff --git a/src/sage/categories/lie_algebras.py b/src/sage/categories/lie_algebras.py index 269ca3dabbe..04597de0308 100644 --- a/src/sage/categories/lie_algebras.py +++ b/src/sage/categories/lie_algebras.py @@ -45,24 +45,24 @@ class LieAlgebras(Category_over_base_ring): We construct a typical parent in this category, and do some computations with it:: - sage: A = C.example(); A + sage: A = C.example(); A # optional - sage.groups sage.modules An example of a Lie algebra: the Lie algebra from the associative algebra Symmetric group algebra of order 3 over Rational Field generated by ([2, 1, 3], [2, 3, 1]) - sage: A.category() + sage: A.category() # optional - sage.groups sage.modules Category of Lie algebras over Rational Field - sage: A.base_ring() + sage: A.base_ring() # optional - sage.groups sage.modules Rational Field - sage: a,b = A.lie_algebra_generators() - sage: a.bracket(b) + sage: a, b = A.lie_algebra_generators() # optional - sage.groups sage.modules + sage: a.bracket(b) # optional - sage.groups sage.modules -[1, 3, 2] + [3, 2, 1] - sage: b.bracket(2*a + b) + sage: b.bracket(2*a + b) # optional - sage.groups sage.modules 2*[1, 3, 2] - 2*[3, 2, 1] - sage: A.bracket(a, b) + sage: A.bracket(a, b) # optional - sage.groups sage.modules -[1, 3, 2] + [3, 2, 1] Please see the source code of `A` (with ``A??``) for how to @@ -70,9 +70,9 @@ class LieAlgebras(Category_over_base_ring): TESTS:: - sage: C = LieAlgebras(QQ) - sage: TestSuite(C).run() - sage: TestSuite(C.example()).run() + sage: C = LieAlgebras(QQ) # optional - sage.combinat sage.modules + sage: TestSuite(C).run() # optional - sage.combinat sage.modules + sage: TestSuite(C.example()).run() # optional - sage.combinat sage.modules .. TODO:: @@ -151,15 +151,15 @@ def example(self, gens=None): EXAMPLES:: - sage: LieAlgebras(QQ).example() + sage: LieAlgebras(QQ).example() # optional - sage.groups sage.modules An example of a Lie algebra: the Lie algebra from the associative algebra Symmetric group algebra of order 3 over Rational Field generated by ([2, 1, 3], [2, 3, 1]) Another set of generators can be specified as an optional argument:: - sage: F. = FreeAlgebra(QQ) - sage: LieAlgebras(QQ).example(F.gens()) + sage: F. = FreeAlgebra(QQ) # optional - sage.combinat sage.modules + sage: LieAlgebras(QQ).example(F.gens()) # optional - sage.combinat sage.modules An example of a Lie algebra: the Lie algebra from the associative algebra Free Algebra on 3 generators (x, y, z) over Rational Field generated by (x, y, z) @@ -189,11 +189,14 @@ def extra_super_categories(self): [Category of finite sets] sage: LieAlgebras(ZZ).FiniteDimensional().extra_super_categories() [] - sage: LieAlgebras(GF(5)).FiniteDimensional().is_subcategory(Sets().Finite()) + sage: C = LieAlgebras(GF(5)).FiniteDimensional() # optional - sage.rings.finite_rings + sage: C.is_subcategory(Sets().Finite()) # optional - sage.rings.finite_rings True - sage: LieAlgebras(ZZ).FiniteDimensional().is_subcategory(Sets().Finite()) + sage: C = LieAlgebras(ZZ).FiniteDimensional() + sage: C.is_subcategory(Sets().Finite()) False - sage: LieAlgebras(GF(5)).WithBasis().FiniteDimensional().is_subcategory(Sets().Finite()) + sage: C = LieAlgebras(GF(5)).WithBasis().FiniteDimensional() # optional - sage.rings.finite_rings + sage: C.is_subcategory(Sets().Finite()) # optional - sage.rings.finite_rings True """ if self.base_ring() in Sets().Finite(): @@ -206,8 +209,8 @@ class Nilpotent(CategoryWithAxiom_over_base_ring): TESTS:: - sage: C = LieAlgebras(QQ).Nilpotent() - sage: TestSuite(C).run() + sage: C = LieAlgebras(QQ).Nilpotent() # optional - sage.combinat sage.modules + sage: TestSuite(C).run() # optional - sage.combinat sage.modules """ class ParentMethods: @abstract_method @@ -217,8 +220,8 @@ def step(self): EXAMPLES:: - sage: h = lie_algebras.Heisenberg(ZZ, oo) - sage: h.step() + sage: h = lie_algebras.Heisenberg(ZZ, oo) # optional - sage.combinat sage.modules + sage: h.step() # optional - sage.combinat sage.modules 2 """ @@ -228,8 +231,8 @@ def is_nilpotent(self): EXAMPLES:: - sage: h = lie_algebras.Heisenberg(ZZ, oo) - sage: h.is_nilpotent() + sage: h = lie_algebras.Heisenberg(ZZ, oo) # optional - sage.combinat sage.modules + sage: h.is_nilpotent() # optional - sage.combinat sage.modules True """ return True @@ -254,30 +257,30 @@ def bracket(self, lhs, rhs): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: x,y = L.lie_algebra_generators() - sage: L.bracket(x, x + y) + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.modules + sage: x, y = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: L.bracket(x, x + y) # optional - sage.combinat sage.modules -[1, 3, 2] + [3, 2, 1] - sage: L.bracket(x, 0) + sage: L.bracket(x, 0) # optional - sage.combinat sage.modules 0 - sage: L.bracket(0, x) + sage: L.bracket(0, x) # optional - sage.combinat sage.modules 0 Constructing the product space:: - sage: L = lie_algebras.Heisenberg(QQ, 1) - sage: Z = L.bracket(L, L); Z + sage: L = lie_algebras.Heisenberg(QQ, 1) # optional - sage.combinat sage.modules + sage: Z = L.bracket(L, L); Z # optional - sage.combinat sage.modules Ideal (z) of Heisenberg algebra of rank 1 over Rational Field - sage: L.bracket(L, Z) + sage: L.bracket(L, Z) # optional - sage.combinat sage.modules Ideal () of Heisenberg algebra of rank 1 over Rational Field Constructing ideals:: - sage: p,q,z = L.basis(); (p,q,z) + sage: p, q, z = L.basis(); p, q, z # optional - sage.combinat sage.modules (p1, q1, z) - sage: L.bracket(3*p, L) + sage: L.bracket(3*p, L) # optional - sage.combinat sage.modules Ideal (3*p1) of Heisenberg algebra of rank 1 over Rational Field - sage: L.bracket(L, q+p) + sage: L.bracket(L, q + p) # optional - sage.combinat sage.modules Ideal (p1 + q1) of Heisenberg algebra of rank 1 over Rational Field """ if lhs in LieAlgebras: @@ -297,15 +300,15 @@ def universal_enveloping_algebra(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.universal_enveloping_algebra() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: L.universal_enveloping_algebra() # optional - sage.combinat sage.modules Noncommutative Multivariate Polynomial Ring in b0, b1, b2 over Rational Field, nc-relations: {} :: - sage: L = LieAlgebra(QQ, 3, 'x', abelian=True) - sage: L.universal_enveloping_algebra() + sage: L = LieAlgebra(QQ, 3, 'x', abelian=True) # optional - sage.combinat sage.modules + sage: L.universal_enveloping_algebra() # optional - sage.combinat sage.modules Multivariate Polynomial Ring in x0, x1, x2 over Rational Field .. SEEALSO:: @@ -330,15 +333,15 @@ def _construct_UEA(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L._construct_UEA() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: L._construct_UEA() # optional - sage.combinat sage.modules Noncommutative Multivariate Polynomial Ring in b0, b1, b2 over Rational Field, nc-relations: {} :: - sage: L = LieAlgebra(QQ, 3, 'x', abelian=True) - sage: L.universal_enveloping_algebra() # indirect doctest + sage: L = LieAlgebra(QQ, 3, 'x', abelian=True) # optional - sage.combinat sage.modules + sage: L.universal_enveloping_algebra() # indirect doctest # optional - sage.combinat sage.modules Multivariate Polynomial Ring in x0, x1, x2 over Rational Field """ @@ -394,8 +397,8 @@ def module(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.module() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: L.module() # optional - sage.combinat sage.modules Vector space of dimension 3 over Rational Field """ @@ -410,10 +413,10 @@ def from_vector(self, v, order=None, coerce=False): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: u = L.from_vector(vector(QQ, (1, 0, 0))); u + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: u = L.from_vector(vector(QQ, (1, 0, 0))); u # optional - sage.combinat sage.modules (1, 0, 0) - sage: parent(u) is L + sage: parent(u) is L # optional - sage.combinat sage.modules True """ @@ -430,11 +433,11 @@ def lift(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: a, b, c = L.lie_algebra_generators() - sage: lifted = L.lift(2*a + b - c); lifted + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: a, b, c = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: lifted = L.lift(2*a + b - c); lifted # optional - sage.combinat sage.modules 2*b0 + b1 - b2 - sage: lifted.parent() is L.universal_enveloping_algebra() + sage: lifted.parent() is L.universal_enveloping_algebra() # optional - sage.combinat sage.modules True """ M = LiftMorphism(self, self._construct_UEA()) @@ -447,9 +450,9 @@ def subalgebra(self, gens, names=None, index_set=None, category=None): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: a, b, c = L.lie_algebra_generators() - sage: L.subalgebra([2*a - c, b + c]) + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: a, b, c = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: L.subalgebra([2*a - c, b + c]) # optional - sage.combinat sage.modules An example of a finite dimensional Lie algebra with basis: the 2-dimensional abelian Lie algebra over Rational Field with basis matrix: @@ -458,9 +461,9 @@ def subalgebra(self, gens, names=None, index_set=None, category=None): :: - sage: L = LieAlgebras(QQ).example() - sage: x,y = L.lie_algebra_generators() - sage: L.subalgebra([x + y]) + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.modules + sage: x,y = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: L.subalgebra([x + y]) # optional - sage.combinat sage.modules Traceback (most recent call last): ... NotImplementedError: subalgebras not yet implemented: see #17416 @@ -475,9 +478,9 @@ def ideal(self, *gens, **kwds): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: a, b, c = L.lie_algebra_generators() - sage: L.ideal([2*a - c, b + c]) + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: a, b, c = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: L.ideal([2*a - c, b + c]) # optional - sage.combinat sage.modules An example of a finite dimensional Lie algebra with basis: the 2-dimensional abelian Lie algebra over Rational Field with basis matrix: @@ -486,9 +489,9 @@ def ideal(self, *gens, **kwds): :: - sage: L = LieAlgebras(QQ).example() - sage: x,y = L.lie_algebra_generators() - sage: L.ideal([x + y]) + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.modules + sage: x, y = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: L.ideal([x + y]) # optional - sage.combinat sage.modules Traceback (most recent call last): ... NotImplementedError: ideals not yet implemented: see #16824 @@ -508,8 +511,8 @@ def is_ideal(self, A): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: L.is_ideal(L) + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.modules + sage: L.is_ideal(L) # optional - sage.combinat sage.modules True """ if A == self: @@ -525,9 +528,9 @@ def killing_form(self, x, y): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: a, b, c = L.lie_algebra_generators() - sage: L.killing_form(a, b+c) + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: a, b, c = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: L.killing_form(a, b + c) # optional - sage.combinat sage.modules 0 """ @@ -540,21 +543,21 @@ def is_abelian(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: L.is_abelian() + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.modules + sage: L.is_abelian() # optional - sage.combinat sage.modules False - sage: R = QQ['x,y'] - sage: L = LieAlgebras(QQ).example(R.gens()) - sage: L.is_abelian() + sage: R = QQ['x,y'] # optional - sage.combinat sage.modules + sage: L = LieAlgebras(QQ).example(R.gens()) # optional - sage.combinat sage.modules + sage: L.is_abelian() # optional - sage.combinat sage.modules True :: - sage: L. = LieAlgebra(QQ,1) # todo: not implemented - #16823 - sage: L.is_abelian() # todo: not implemented - #16823 + sage: L. = LieAlgebra(QQ, 1) # todo: not implemented - #16823 # optional - sage.combinat sage.modules + sage: L.is_abelian() # todo: not implemented - #16823 # optional - sage.combinat sage.modules True - sage: L. = LieAlgebra(QQ,2) # todo: not implemented - #16823 - sage: L.is_abelian() # todo: not implemented - #16823 + sage: L. = LieAlgebra(QQ, 2) # todo: not implemented - #16823 # optional - sage.combinat sage.modules + sage: L.is_abelian() # todo: not implemented - #16823 # optional - sage.combinat sage.modules False """ G = self.lie_algebra_generators() @@ -570,14 +573,14 @@ def is_commutative(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: L.is_commutative() + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.modules + sage: L.is_commutative() # optional - sage.combinat sage.modules False :: - sage: L. = LieAlgebra(QQ, 1) # todo: not implemented - #16823 - sage: L.is_commutative() # todo: not implemented - #16823 + sage: L. = LieAlgebra(QQ, 1) # todo: not implemented - #16823 # optional - sage.combinat sage.modules + sage: L.is_commutative() # todo: not implemented - #16823 # optional - sage.combinat sage.modules True """ return self.is_abelian() @@ -589,8 +592,8 @@ def is_solvable(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.is_solvable() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: L.is_solvable() # optional - sage.combinat sage.modules True """ @@ -601,8 +604,8 @@ def is_nilpotent(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.is_nilpotent() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: L.is_nilpotent() # optional - sage.combinat sage.modules True """ @@ -627,37 +630,40 @@ def bch(self, X, Y, prec=None): The BCH formula for the generators of a free nilpotent Lie algebra of step 4:: - sage: L = LieAlgebra(QQ, 2, step=4) - sage: L.inject_variables() + sage: L = LieAlgebra(QQ, 2, step=4) # optional - sage.combinat sage.modules + sage: L.inject_variables() # optional - sage.combinat sage.modules Defining X_1, X_2, X_12, X_112, X_122, X_1112, X_1122, X_1222 - sage: L.bch(X_1, X_2) + sage: L.bch(X_1, X_2) # optional - sage.combinat sage.modules X_1 + X_2 + 1/2*X_12 + 1/12*X_112 + 1/12*X_122 + 1/24*X_1122 An example of the BCH formula in a quotient:: - sage: Q = L.quotient(X_112 + X_122) - sage: x, y = Q.basis().list()[:2] - sage: Q.bch(x, y) + sage: Q = L.quotient(X_112 + X_122) # optional - sage.combinat sage.modules + sage: x, y = Q.basis().list()[:2] # optional - sage.combinat sage.modules + sage: Q.bch(x, y) # optional - sage.combinat sage.modules X_1 + X_2 + 1/2*X_12 - 1/24*X_1112 The BCH formula for a non-nilpotent Lie algebra requires the precision to be explicitly stated:: - sage: L. = LieAlgebra(QQ) - sage: L.bch(X, Y) + sage: L. = LieAlgebra(QQ) # optional - sage.combinat sage.modules + sage: L.bch(X, Y) # optional - sage.combinat sage.modules Traceback (most recent call last): ... - ValueError: the Lie algebra is not known to be nilpotent, so you must specify the precision - sage: L.bch(X, Y, 4) - X + 1/12*[X, [X, Y]] + 1/24*[X, [[X, Y], Y]] + 1/2*[X, Y] + 1/12*[[X, Y], Y] + Y + ValueError: the Lie algebra is not known to be nilpotent, + so you must specify the precision + sage: L.bch(X, Y, 4) # optional - sage.combinat sage.modules + X + 1/12*[X, [X, Y]] + 1/24*[X, [[X, Y], Y]] + + 1/2*[X, Y] + 1/12*[[X, Y], Y] + Y The BCH formula requires a coercion from the rationals:: - sage: L. = LieAlgebra(ZZ, 2, step=2) - sage: L.bch(X, Y) + sage: L. = LieAlgebra(ZZ, 2, step=2) # optional - sage.combinat sage.modules + sage: L.bch(X, Y) # optional - sage.combinat sage.modules Traceback (most recent call last): ... - TypeError: the BCH formula is not well defined since Integer Ring has no coercion from Rational Field + TypeError: the BCH formula is not well defined + since Integer Ring has no coercion from Rational Field """ if self not in LieAlgebras.Nilpotent and prec is None: raise ValueError("the Lie algebra is not known to be nilpotent," @@ -682,8 +688,8 @@ def lie_group(self, name='G', **kwds): EXAMPLES:: - sage: L = lie_algebras.Heisenberg(QQ, 1) - sage: G = L.lie_group('G'); G # optional - sage.symbolic + sage: L = lie_algebras.Heisenberg(QQ, 1) # optional - sage.combinat sage.modules + sage: G = L.lie_group('G'); G # optional - sage.combinat sage.modules sage.symbolic Lie group G of Heisenberg algebra of rank 1 over Rational Field """ @@ -701,15 +707,15 @@ def _test_jacobi_identity(self, **options): By default, this method runs the tests only on the elements returned by ``self.some_elements()``:: - sage: L = LieAlgebras(QQ).example() - sage: L._test_jacobi_identity() + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.modules + sage: L._test_jacobi_identity() # optional - sage.combinat sage.modules However, the elements tested can be customized with the ``elements`` keyword argument:: - sage: L = LieAlgebras(QQ).example() - sage: x,y = L.lie_algebra_generators() - sage: L._test_jacobi_identity(elements=[x+y, x, 2*y, x.bracket(y)]) + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.modules + sage: x,y = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: L._test_jacobi_identity(elements=[x + y, x, 2*y, x.bracket(y)]) # optional - sage.combinat sage.modules See the documentation for :class:`TestSuite` for more information. """ @@ -740,15 +746,15 @@ def _test_antisymmetry(self, **options): By default, this method runs the tests only on the elements returned by ``self.some_elements()``:: - sage: L = LieAlgebras(QQ).example() - sage: L._test_antisymmetry() + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.modules + sage: L._test_antisymmetry() # optional - sage.combinat sage.modules However, the elements tested can be customized with the ``elements`` keyword argument:: - sage: L = LieAlgebras(QQ).example() - sage: x,y = L.lie_algebra_generators() - sage: L._test_antisymmetry(elements=[x+y, x, 2*y, x.bracket(y)]) + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.modules + sage: x,y = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: L._test_antisymmetry(elements=[x + y, x, 2*y, x.bracket(y)]) # optional - sage.combinat sage.modules See the documentation for :class:`TestSuite` for more information. """ @@ -769,27 +775,27 @@ def _test_distributivity(self, **options): TESTS:: - sage: L = LieAlgebras(QQ).example() - sage: L._test_distributivity() + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.modules + sage: L._test_distributivity() # optional - sage.combinat sage.modules EXAMPLES: By default, this method runs the tests only on the elements returned by ``self.some_elements()``:: - sage: L = LieAlgebra(QQ, 3, 'x,y,z', representation="polynomial") - sage: L.some_elements() + sage: L = LieAlgebra(QQ, 3, 'x,y,z', representation="polynomial") # optional - sage.combinat sage.modules + sage: L.some_elements() # optional - sage.combinat sage.modules [x + y + z] - sage: L._test_distributivity() + sage: L._test_distributivity() # optional - sage.combinat sage.modules However, the elements tested can be customized with the ``elements`` keyword argument:: - sage: L = LieAlgebra(QQ, cartan_type=['A', 2]) # todo: not implemented - #16821 - sage: h1 = L.gen(0) # todo: not implemented - #16821 - sage: h2 = L.gen(1) # todo: not implemented - #16821 - sage: e2 = L.gen(3) # todo: not implemented - #16821 - sage: L._test_distributivity(elements=[h1, h2, e2]) # todo: not implemented - #16821 + sage: L = LieAlgebra(QQ, cartan_type=['A', 2]) # todo: not implemented - #16821 # optional - sage.combinat sage.modules + sage: h1 = L.gen(0) # todo: not implemented - #16821 # optional - sage.combinat sage.modules + sage: h2 = L.gen(1) # todo: not implemented - #16821 # optional - sage.combinat sage.modules + sage: e2 = L.gen(3) # todo: not implemented - #16821 # optional - sage.combinat sage.modules + sage: L._test_distributivity(elements=[h1, h2, e2]) # todo: not implemented - #16821 # optional - sage.combinat sage.modules See the documentation for :class:`TestSuite` for more information. """ @@ -812,11 +818,11 @@ def bracket(self, rhs): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: x,y = L.lie_algebra_generators() - sage: x.bracket(y) + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.modules + sage: x,y = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: x.bracket(y) # optional - sage.combinat sage.modules -[1, 3, 2] + [3, 2, 1] - sage: x.bracket(0) + sage: x.bracket(0) # optional - sage.combinat sage.modules 0 """ return self._bracket_(rhs) @@ -831,13 +837,13 @@ def _bracket_(self, y): EXAMPLES:: - sage: L = LieAlgebras(QQ).example() - sage: x,y = L.lie_algebra_generators() - sage: x._bracket_(y) + sage: L = LieAlgebras(QQ).example() # optional - sage.combinat sage.modules + sage: x,y = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: x._bracket_(y) # optional - sage.combinat sage.modules -[1, 3, 2] + [3, 2, 1] - sage: y._bracket_(x) + sage: y._bracket_(x) # optional - sage.combinat sage.modules [1, 3, 2] - [3, 2, 1] - sage: x._bracket_(x) + sage: x._bracket_(x) # optional - sage.combinat sage.modules 0 """ @@ -853,10 +859,10 @@ def to_vector(self, order=None): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: u = L((1, 0, 0)).to_vector(); u + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: u = L((1, 0, 0)).to_vector(); u # optional - sage.combinat sage.modules (1, 0, 0) - sage: parent(u) + sage: parent(u) # optional - sage.combinat sage.modules Vector space of dimension 3 over Rational Field """ @@ -868,16 +874,16 @@ def lift(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: a, b, c = L.lie_algebra_generators() - sage: elt = 3*a + b - c - sage: elt.lift() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: a, b, c = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: elt = 3*a + b - c # optional - sage.combinat sage.modules + sage: elt.lift() # optional - sage.combinat sage.modules 3*b0 + b1 - b2 :: - sage: L. = LieAlgebra(QQ, abelian=True) - sage: x.lift() + sage: L. = LieAlgebra(QQ, abelian=True) # optional - sage.combinat sage.modules + sage: x.lift() # optional - sage.combinat sage.modules x """ @@ -887,9 +893,9 @@ def killing_form(self, x): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: a, b, c = L.lie_algebra_generators() - sage: a.killing_form(b) + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: a, b, c = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: a.killing_form(b) # optional - sage.combinat sage.modules 0 """ return self.parent().killing_form(self, x) @@ -906,24 +912,26 @@ def exp(self, lie_group=None): EXAMPLES:: - sage: L. = LieAlgebra(QQ, 2, step=2) - sage: g = (X + Y + Z).exp(); g # optional - sage.symbolic + sage: L. = LieAlgebra(QQ, 2, step=2) # optional - sage.combinat sage.modules + sage: g = (X + Y + Z).exp(); g # optional - sage.combinat sage.modules sage.symbolic exp(X + Y + Z) - sage: h = X.exp(); h # optional - sage.symbolic + sage: h = X.exp(); h # optional - sage.combinat sage.modules sage.symbolic exp(X) - sage: g.parent() # optional - sage.symbolic - Lie group G of Free Nilpotent Lie algebra on 3 generators (X, Y, Z) over Rational Field - sage: g.parent() is h.parent() # optional - sage.symbolic + sage: g.parent() # optional - sage.combinat sage.modules sage.symbolic + Lie group G of Free Nilpotent Lie algebra on 3 generators (X, Y, Z) + over Rational Field + sage: g.parent() is h.parent() # optional - sage.combinat sage.modules sage.symbolic True The Lie group can be specified explicitly:: - sage: H = L.lie_group('H') # optional - sage.symbolic - sage: k = Z.exp(lie_group=H); k # optional - sage.symbolic + sage: H = L.lie_group('H') # optional - sage.combinat sage.modules sage.symbolic + sage: k = Z.exp(lie_group=H); k # optional - sage.combinat sage.modules sage.symbolic exp(Z) - sage: k.parent() # optional - sage.symbolic - Lie group H of Free Nilpotent Lie algebra on 3 generators (X, Y, Z) over Rational Field - sage: g.parent() == k.parent() # optional - sage.symbolic + sage: k.parent() # optional - sage.combinat sage.modules sage.symbolic + Lie group H of Free Nilpotent Lie algebra on 3 generators (X, Y, Z) + over Rational Field + sage: g.parent() == k.parent() # optional - sage.combinat sage.modules sage.symbolic False """ if lie_group is None: @@ -941,13 +949,13 @@ def __init__(self, domain, codomain): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: f = L.lift + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: f = L.lift # optional - sage.combinat sage.modules We skip the category test since this is currently not an element of a homspace:: - sage: TestSuite(f).run(skip="_test_category") + sage: TestSuite(f).run(skip="_test_category") # optional - sage.combinat sage.modules """ Morphism.__init__(self, Hom(domain, codomain)) @@ -957,9 +965,9 @@ def _call_(self, x): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: a, b, c = L.lie_algebra_generators() - sage: L.lift(3*a + b - c) + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat sage.modules + sage: a, b, c = L.lie_algebra_generators() # optional - sage.combinat sage.modules + sage: L.lift(3*a + b - c) # optional - sage.combinat sage.modules 3*b0 + b1 - b2 """ return x.lift() diff --git a/src/sage/categories/lie_algebras_with_basis.py b/src/sage/categories/lie_algebras_with_basis.py index 71916e3d6ad..4f6cf394651 100644 --- a/src/sage/categories/lie_algebras_with_basis.py +++ b/src/sage/categories/lie_algebras_with_basis.py @@ -34,13 +34,13 @@ def example(self, gens=None): EXAMPLES:: - sage: LieAlgebras(QQ).WithBasis().example() + sage: LieAlgebras(QQ).WithBasis().example() # optional - sage.combinat An example of a Lie algebra: the abelian Lie algebra on the generators indexed by Partitions over Rational Field Another set of generators can be specified as an optional argument:: - sage: LieAlgebras(QQ).WithBasis().example(Compositions()) + sage: LieAlgebras(QQ).WithBasis().example(Compositions()) # optional - sage.combinat An example of a Lie algebra: the abelian Lie algebra on the generators indexed by Compositions of non-negative integers over Rational Field @@ -64,8 +64,8 @@ def _basis_key(self, x): TESTS:: - sage: L = LieAlgebras(QQ).WithBasis().example() - sage: L._basis_key(Partition([3,1])) + sage: L = LieAlgebras(QQ).WithBasis().example() # optional - sage.combinat + sage: L._basis_key(Partition([3,1])) # optional - sage.combinat [3, 1] """ return x @@ -79,8 +79,8 @@ def bracket_on_basis(self, x, y): EXAMPLES:: - sage: L = LieAlgebras(QQ).WithBasis().example() - sage: L.bracket_on_basis(Partition([3,1]), Partition([2,2,1,1])) + sage: L = LieAlgebras(QQ).WithBasis().example() # optional - sage.combinat + sage: L.bracket_on_basis(Partition([3,1]), Partition([2,2,1,1])) # optional - sage.combinat 0 """ @@ -95,8 +95,8 @@ def module(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).WithBasis().example() - sage: L.module() + sage: L = LieAlgebras(QQ).WithBasis().example() # optional - sage.combinat + sage: L.module() # optional - sage.combinat Free module generated by Partitions over Rational Field """ from sage.combinat.free_module import CombinatorialFreeModule @@ -119,10 +119,10 @@ def from_vector(self, v, order=None, coerce=False): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: u = L.from_vector(vector(QQ, (1, 0, 0))); u + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat + sage: u = L.from_vector(vector(QQ, (1, 0, 0))); u # optional - sage.combinat (1, 0, 0) - sage: parent(u) is L + sage: parent(u) is L # optional - sage.combinat True """ B = self.basis() @@ -135,14 +135,14 @@ def dimension(self): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.dimension() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.combinat + sage: L.dimension() # optional - sage.combinat 3 :: - sage: L = LieAlgebra(QQ, 'x,y', {('x','y'): {'x':1}}) - sage: L.dimension() + sage: L = LieAlgebra(QQ, 'x,y', {('x','y'): {'x':1}}) # optional - sage.combinat sage.modules + sage: L.dimension() # optional - sage.combinat sage.modules 2 """ return self.basis().cardinality() @@ -154,8 +154,8 @@ def pbw_basis(self, basis_key=None, **kwds): EXAMPLES:: - sage: L = lie_algebras.sl(QQ, 2) - sage: PBW = L.pbw_basis() + sage: L = lie_algebras.sl(QQ, 2) # optional - sage.combinat sage.modules + sage: PBW = L.pbw_basis() # optional - sage.combinat sage.modules """ from sage.algebras.lie_algebras.poincare_birkhoff_witt \ import PoincareBirkhoffWittBasis @@ -173,11 +173,11 @@ def _bracket_(self, y): EXAMPLES:: - sage: L = LieAlgebras(QQ).WithBasis().example() - sage: G = L.lie_algebra_generators() - sage: x = G[Partition([4,3,3,1])] - sage: y = G[Partition([6,1])] - sage: x.bracket(y) + sage: L = LieAlgebras(QQ).WithBasis().example() # optional - sage.combinat + sage: G = L.lie_algebra_generators() # optional - sage.combinat + sage: x = G[Partition([4,3,3,1])] # optional - sage.combinat + sage: y = G[Partition([6,1])] # optional - sage.combinat + sage: x.bracket(y) # optional - sage.combinat 0 """ P = self.parent() @@ -206,8 +206,8 @@ def to_vector(self, order=None): EXAMPLES:: - sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() - sage: L.an_element().to_vector() + sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # optional - sage.modules + sage: L.an_element().to_vector() # optional - sage.modules (0, 0, 0) .. TODO:: @@ -224,15 +224,15 @@ def lift(self): EXAMPLES:: - sage: S = SymmetricGroup(3).algebra(QQ) - sage: L = LieAlgebra(associative=S) - sage: x = L.gen(3) - sage: y = L.gen(1) - sage: x.lift() + sage: S = SymmetricGroup(3).algebra(QQ) # optional - sage.groups + sage: L = LieAlgebra(associative=S) # optional - sage.groups + sage: x = L.gen(3) # optional - sage.groups + sage: y = L.gen(1) # optional - sage.groups + sage: x.lift() # optional - sage.groups b3 - sage: y.lift() + sage: y.lift() # optional - sage.groups b1 - sage: x * y + sage: x * y # optional - sage.groups b1*b3 + b4 - b5 """ P = self.parent() diff --git a/src/sage/categories/lie_conformal_algebras.py b/src/sage/categories/lie_conformal_algebras.py index 54e3956c283..4e59d4758b0 100644 --- a/src/sage/categories/lie_conformal_algebras.py +++ b/src/sage/categories/lie_conformal_algebras.py @@ -152,15 +152,16 @@ class LieConformalAlgebras(Category_over_base_ring): Some subcategories:: - sage: LieConformalAlgebras(QQbar).FinitelyGenerated().WithBasis() - Category of finitely generated Lie conformal algebras with basis over Algebraic Field + sage: LieConformalAlgebras(QQbar).FinitelyGenerated().WithBasis() # optional - sage.rings.number_field + Category of finitely generated Lie conformal algebras with basis + over Algebraic Field In addition we support functorial constructions ``Graded`` and ``Super``. These functors commute:: - sage: LieConformalAlgebras(AA).Graded().Super() + sage: CGS = LieConformalAlgebras(AA).Graded().Super(); CGS # optional - sage.rings.number_field Category of H-graded super Lie conformal algebras over Algebraic Real Field - sage: LieConformalAlgebras(AA).Graded().Super() is LieConformalAlgebras(AA).Super().Graded() + sage: CGS is LieConformalAlgebras(AA).Super().Graded() # optional - sage.rings.number_field True That is, we only consider gradings on super Lie conformal algebras @@ -168,9 +169,10 @@ class LieConformalAlgebras(Category_over_base_ring): The base ring needs to be a commutative ring:: - sage: LieConformalAlgebras(QuaternionAlgebra(2)) + sage: LieConformalAlgebras(QuaternionAlgebra(2)) # optional - sage.combinat sage.modules Traceback (most recent call last): - ValueError: base must be a commutative ring got Quaternion Algebra (-1, -1) with base ring Rational Field + ValueError: base must be a commutative ring + got Quaternion Algebra (-1, -1) with base ring Rational Field """ @cached_method def super_categories(self): @@ -219,7 +221,7 @@ def example(self): EXAMPLES:: - sage: LieConformalAlgebras(QQ).example() + sage: LieConformalAlgebras(QQ).example() # optional - sage.combinat sage.modules The Virasoro Lie conformal algebra over Rational Field """ from sage.algebras.lie_conformal_algebras.virasoro_lie_conformal_algebra\ @@ -252,27 +254,27 @@ def _test_jacobi(self, **options): By default, this method tests only the elements returned by ``self.some_elements()``:: - sage: V = lie_conformal_algebras.Affine(QQ, 'B2') - sage: V._test_jacobi() # long time (6 seconds) + sage: V = lie_conformal_algebras.Affine(QQ, 'B2') # optional - sage.combinat sage.modules + sage: V._test_jacobi() # long time (6 seconds) # optional - sage.combinat sage.modules It works for super Lie conformal algebras too:: - sage: V = lie_conformal_algebras.NeveuSchwarz(QQ) - sage: V._test_jacobi() + sage: V = lie_conformal_algebras.NeveuSchwarz(QQ) # optional - sage.combinat sage.modules + sage: V._test_jacobi() # optional - sage.combinat sage.modules We can use specific elements by passing the ``elements`` keyword argument:: - sage: V = lie_conformal_algebras.Affine(QQ, 'A1', names=('e', 'h', 'f')) - sage: V.inject_variables() + sage: V = lie_conformal_algebras.Affine(QQ, 'A1', names=('e', 'h', 'f')) # optional - sage.combinat sage.modules + sage: V.inject_variables() # optional - sage.combinat sage.modules Defining e, h, f, K - sage: V._test_jacobi(elements=(e, 2*f+h, 3*h)) + sage: V._test_jacobi(elements=(e, 2*f+h, 3*h)) # optional - sage.combinat sage.modules TESTS:: sage: wrongdict = {('a', 'a'): {0: {('b', 0): 1}}, ('b', 'a'): {0: {('a', 0): 1}}} - sage: V = LieConformalAlgebra(QQ, wrongdict, names=('a', 'b'), parity=(1, 0)) - sage: V._test_jacobi() + sage: V = LieConformalAlgebra(QQ, wrongdict, names=('a', 'b'), parity=(1, 0)) # optional - sage.combinat sage.modules + sage: V._test_jacobi() # optional - sage.combinat sage.modules Traceback (most recent call last): ... AssertionError: {(0, 0): -3*a} != {} @@ -323,10 +325,10 @@ def is_even_odd(self): EXAMPLES:: - sage: R = lie_conformal_algebras.NeveuSchwarz(QQ); - sage: R.inject_variables() + sage: R = lie_conformal_algebras.NeveuSchwarz(QQ) # optional - sage.combinat sage.modules + sage: R.inject_variables() # optional - sage.combinat sage.modules Defining L, G, C - sage: G.is_even_odd() + sage: G.is_even_odd() # optional - sage.combinat sage.modules 1 """ return 0 diff --git a/src/sage/categories/lie_conformal_algebras_with_basis.py b/src/sage/categories/lie_conformal_algebras_with_basis.py index 50f67d2a970..6f31b6b4cca 100644 --- a/src/sage/categories/lie_conformal_algebras_with_basis.py +++ b/src/sage/categories/lie_conformal_algebras_with_basis.py @@ -27,7 +27,7 @@ class LieConformalAlgebrasWithBasis(CategoryWithAxiom_over_base_ring): EXAMPLES:: - sage: LieConformalAlgebras(QQbar).WithBasis() + sage: LieConformalAlgebras(QQbar).WithBasis() # optional - sage.rings.number_field Category of Lie conformal algebras with basis over Algebraic Field """ class Super(SuperModulesCategory): @@ -36,8 +36,9 @@ class Super(SuperModulesCategory): EXAMPLES:: - sage: LieConformalAlgebras(AA).WithBasis().Super() - Category of super Lie conformal algebras with basis over Algebraic Real Field + sage: LieConformalAlgebras(AA).WithBasis().Super() # optional - sage.rings.number_field + Category of super Lie conformal algebras with basis + over Algebraic Real Field """ class ParentMethods: @@ -52,9 +53,9 @@ def _even_odd_on_basis(self, m): EXAMPLES:: - sage: V = lie_conformal_algebras.NeveuSchwarz(QQ) - sage: B = V._indices - sage: V._even_odd_on_basis(B(('G',1))) + sage: V = lie_conformal_algebras.NeveuSchwarz(QQ) # optional - sage.combinat sage.modules + sage: B = V._indices # optional - sage.combinat sage.modules + sage: V._even_odd_on_basis(B(('G', 1))) # optional - sage.combinat sage.modules 1 """ return self._parity[self.monomial((m[0],0))] @@ -65,8 +66,9 @@ class Graded(GradedLieConformalAlgebrasCategory): EXAMPLES:: - sage: LieConformalAlgebras(QQbar).WithBasis().Super().Graded() - Category of H-graded super Lie conformal algebras with basis over Algebraic Field + sage: LieConformalAlgebras(QQbar).WithBasis().Super().Graded() # optional - sage.rings.number_field + Category of H-graded super Lie conformal algebras with basis + over Algebraic Field """ class Graded(GradedLieConformalAlgebrasCategory): @@ -75,7 +77,7 @@ class Graded(GradedLieConformalAlgebrasCategory): EXAMPLES:: - sage: LieConformalAlgebras(QQbar).WithBasis().Graded() + sage: LieConformalAlgebras(QQbar).WithBasis().Graded() # optional - sage.rings.number_field Category of H-graded Lie conformal algebras with basis over Algebraic Field """ @@ -86,10 +88,11 @@ class FinitelyGeneratedAsLambdaBracketAlgebra(CategoryWithAxiom_over_base_ring): EXAMPLES:: - sage: C = LieConformalAlgebras(QQbar) - sage: C.WithBasis().FinitelyGenerated() - Category of finitely generated Lie conformal algebras with basis over Algebraic Field - sage: C.WithBasis().FinitelyGenerated() is C.FinitelyGenerated().WithBasis() + sage: C = LieConformalAlgebras(QQbar) # optional - sage.rings.number_field + sage: CWF = C.WithBasis().FinitelyGenerated(); CWF # optional - sage.rings.number_field + Category of finitely generated Lie conformal algebras with basis + over Algebraic Field + sage: CWF is C.FinitelyGenerated().WithBasis() # optional - sage.rings.number_field True """ class Super(SuperModulesCategory): @@ -99,8 +102,9 @@ class Super(SuperModulesCategory): EXAMPLES:: - sage: LieConformalAlgebras(AA).WithBasis().FinitelyGenerated().Super() - Category of super finitely generated Lie conformal algebras with basis over Algebraic Real Field + sage: LieConformalAlgebras(AA).WithBasis().FinitelyGenerated().Super() # optional - sage.rings.number_field + Category of super finitely generated Lie conformal algebras with basis + over Algebraic Real Field """ class Graded(GradedModulesCategory): """ @@ -109,10 +113,11 @@ class Graded(GradedModulesCategory): EXAMPLES:: - sage: C = LieConformalAlgebras(QQbar).WithBasis().FinitelyGenerated() - sage: C.Graded().Super() - Category of H-graded super finitely generated Lie conformal algebras with basis over Algebraic Field - sage: C.Graded().Super() is C.Super().Graded() + sage: C = LieConformalAlgebras(QQbar).WithBasis().FinitelyGenerated() # optional - sage.rings.number_field + sage: C.Graded().Super() # optional - sage.rings.number_field + Category of H-graded super finitely generated Lie conformal algebras + with basis over Algebraic Field + sage: C.Graded().Super() is C.Super().Graded() # optional - sage.rings.number_field True """ def _repr_object_names(self): @@ -121,8 +126,8 @@ def _repr_object_names(self): EXAMPLES:: - sage: C = LieConformalAlgebras(QQbar).WithBasis().FinitelyGenerated() - sage: C.Super().Graded() + sage: C = LieConformalAlgebras(QQbar).WithBasis().FinitelyGenerated() # optional - sage.rings.number_field + sage: C.Super().Graded() # optional - sage.rings.number_field Category of H-graded super finitely generated Lie conformal algebras with basis over Algebraic Field """ return "H-graded {}".format(self.base_category()._repr_object_names()) @@ -134,6 +139,7 @@ class Graded(GradedLieConformalAlgebrasCategory): EXAMPLES:: - sage: LieConformalAlgebras(QQbar).WithBasis().FinitelyGenerated().Graded() - Category of H-graded finitely generated Lie conformal algebras with basis over Algebraic Field + sage: LieConformalAlgebras(QQbar).WithBasis().FinitelyGenerated().Graded() # optional - sage.rings.number_field + Category of H-graded finitely generated Lie conformal algebras with basis + over Algebraic Field """ diff --git a/src/sage/categories/loop_crystals.py b/src/sage/categories/loop_crystals.py index 415d8c308f7..b7dbd37a3c6 100644 --- a/src/sage/categories/loop_crystals.py +++ b/src/sage/categories/loop_crystals.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.graphs sage.combinat r""" Loop Crystals """ @@ -390,11 +391,17 @@ def R_matrix(self, K): sage: K2 = crystals.KirillovReshetikhin(['A',2,1],2,1) sage: T1 = crystals.TensorProduct(K1,K2) sage: T2 = crystals.TensorProduct(K2,K1) - sage: T1.digraph().is_isomorphic(T2.digraph(), edge_labels=True, certificate=True) #todo: not implemented (see #10904 and #10549) - (True, {[[[1]], [[2], [3]]]: [[[1], [3]], [[2]]], [[[3]], [[2], [3]]]: [[[2], [3]], [[3]]], - [[[3]], [[1], [3]]]: [[[1], [3]], [[3]]], [[[1]], [[1], [3]]]: [[[1], [3]], [[1]]], [[[1]], - [[1], [2]]]: [[[1], [2]], [[1]]], [[[2]], [[1], [2]]]: [[[1], [2]], [[2]]], [[[3]], - [[1], [2]]]: [[[2], [3]], [[1]]], [[[2]], [[1], [3]]]: [[[1], [2]], [[3]]], [[[2]], [[2], [3]]]: [[[2], [3]], [[2]]]}) + sage: T1.digraph().is_isomorphic(T2.digraph(), edge_labels=True, # todo: not implemented (see #10904 and #10549) + ....: certificate=True) + (True, {[[[1]], [[2], [3]]]: [[[1], [3]], [[2]]], + [[[3]], [[2], [3]]]: [[[2], [3]], [[3]]], + [[[3]], [[1], [3]]]: [[[1], [3]], [[3]]], + [[[1]], [[1], [3]]]: [[[1], [3]], [[1]]], [[[1]], + [[1], [2]]]: [[[1], [2]], [[1]]], + [[[2]], [[1], [2]]]: [[[1], [2]], [[2]]], [[[3]], + [[1], [2]]]: [[[2], [3]], [[1]]], + [[[2]], [[1], [3]]]: [[[1], [2]], [[3]]], + [[[2]], [[2], [3]]]: [[[2], [3]], [[2]]]}) """ from sage.combinat.crystals.tensor_product import TensorProductOfCrystals T1 = TensorProductOfCrystals(self, K) @@ -514,7 +521,7 @@ def is_perfect(self, ell=None): sage: K.is_perfect() True - sage: K = crystals.KirillovReshetikhin(['E',6,1], 1,3) + sage: K = crystals.KirillovReshetikhin(['E',6,1], 1, 3) sage: K.is_perfect() True @@ -523,7 +530,7 @@ def is_perfect(self, ell=None): Check that this works correctly for `B^{n,s}` of type `A_{2n}^{(2)\dagger}` (:trac:`24364`):: - sage: K = crystals.KirillovReshetikhin(CartanType(['A',6,2]).dual(), 3,1) + sage: K = crystals.KirillovReshetikhin(CartanType(['A',6,2]).dual(), 3, 1) sage: K.is_perfect() True sage: K.is_perfect(1) @@ -835,7 +842,8 @@ def one_dimensional_configuration_sum(self, q=None, group_components=True): sage: R = RootSystem(['A',2,1]) sage: La = R.weight_space().basis() sage: LS = crystals.ProjectedLevelZeroLSPaths(2*La[1]) - sage: LS.one_dimensional_configuration_sum() == T.one_dimensional_configuration_sum() # long time + sage: (LS.one_dimensional_configuration_sum() # long time + ....: == T.one_dimensional_configuration_sum()) True TESTS:: diff --git a/src/sage/categories/magmas.py b/src/sage/categories/magmas.py index 33dc2bb973a..e80088548a9 100644 --- a/src/sage/categories/magmas.py +++ b/src/sage/categories/magmas.py @@ -296,11 +296,13 @@ def Distributive(self): sage: Magmas().Distributive() Traceback (most recent call last): ... - ValueError: The distributive axiom only makes sense on a magma which is simultaneously an additive magma + ValueError: The distributive axiom only makes sense on a magma + which is simultaneously an additive magma sage: Semigroups().Distributive() Traceback (most recent call last): ... - ValueError: The distributive axiom only makes sense on a magma which is simultaneously an additive magma + ValueError: The distributive axiom only makes sense on a magma + which is simultaneously an additive magma TESTS:: @@ -331,7 +333,8 @@ def JTrivial(self): sage: Magmas().JTrivial() Category of j trivial magmas - sage: (Semigroups().RTrivial() & Semigroups().LTrivial()) is Semigroups().JTrivial() + sage: C = Semigroups().RTrivial() & Semigroups().LTrivial() + sage: C is Semigroups().JTrivial() True """ return self._with_axiom('JTrivial') @@ -349,19 +352,22 @@ def extra_super_categories(self): """ EXAMPLES:: - sage: Magmas().Commutative().Algebras(QQ).extra_super_categories() + sage: MCA = Magmas().Commutative().Algebras(QQ) + sage: MCA.extra_super_categories() [Category of commutative magmas] This implements the fact that the algebra of a commutative magma is commutative:: - sage: Magmas().Commutative().Algebras(QQ).super_categories() - [Category of magma algebras over Rational Field, Category of commutative magmas] + sage: MCA.super_categories() + [Category of magma algebras over Rational Field, + Category of commutative magmas] In particular, commutative monoid algebras are commutative algebras:: - sage: Monoids().Commutative().Algebras(QQ).is_subcategory(Algebras(QQ).Commutative()) + sage: MoCA = Monoids().Commutative().Algebras(QQ) + sage: MoCA.is_subcategory(Algebras(QQ).Commutative()) True """ from sage.categories.magmatic_algebras import MagmaticAlgebras @@ -377,11 +383,11 @@ def is_field(self, proof=True): EXAMPLES:: - sage: SymmetricGroup(1).algebra(QQ).is_field() + sage: SymmetricGroup(1).algebra(QQ).is_field() # optional - sage.groups True - sage: SymmetricGroup(1).algebra(ZZ).is_field() + sage: SymmetricGroup(1).algebra(ZZ).is_field() # optional - sage.groups False - sage: SymmetricGroup(2).algebra(QQ).is_field() + sage: SymmetricGroup(2).algebra(QQ).is_field() # optional - sage.groups False """ if not self.base_ring().is_field(proof): @@ -397,7 +403,7 @@ def is_commutative(self): EXAMPLES:: - sage: Parent(QQ,category=CommutativeRings()).is_commutative() + sage: Parent(QQ, category=CommutativeRings()).is_commutative() True """ return True @@ -408,20 +414,22 @@ def extra_super_categories(self): """ EXAMPLES:: - sage: Magmas().Commutative().Algebras(QQ).extra_super_categories() + sage: MCA = Magmas().Commutative().Algebras(QQ) + sage: MCA.extra_super_categories() [Category of commutative magmas] This implements the fact that the algebra of a commutative magma is commutative:: - sage: Magmas().Commutative().Algebras(QQ).super_categories() + sage: MCA.super_categories() [Category of magma algebras over Rational Field, Category of commutative magmas] In particular, commutative monoid algebras are commutative algebras:: - sage: Monoids().Commutative().Algebras(QQ).is_subcategory(Algebras(QQ).Commutative()) + sage: MoCA = Monoids().Commutative().Algebras(QQ) + sage: MoCA.is_subcategory(Algebras(QQ).Commutative()) True """ return [Magmas().Commutative()] @@ -480,7 +488,8 @@ def one(self): EXAMPLES:: sage: M = Monoids().example(); M - An example of a monoid: the free monoid generated by ('a', 'b', 'c', 'd') + An example of a monoid: + the free monoid generated by ('a', 'b', 'c', 'd') sage: M.one() '' """ @@ -531,8 +540,8 @@ def is_empty(self): EXAMPLES:: - sage: S = SymmetricGroup(2) - sage: S.is_empty() + sage: S = SymmetricGroup(2) # optional - sage.groups + sage: S.is_empty() # optional - sage.groups False sage: M = Monoids().example() @@ -541,7 +550,7 @@ def is_empty(self): TESTS:: - sage: S.is_empty.__module__ + sage: S.is_empty.__module__ # optional - sage.groups 'sage.categories.magmas' sage: M.is_empty.__module__ 'sage.categories.magmas' @@ -656,21 +665,21 @@ def __invert__(self): EXAMPLES:: - sage: C = cartesian_product([QQ, ZZ, RR, GF(5)]) - sage: c = C([2,-1,2,2]); c + sage: C = cartesian_product([QQ, ZZ, RR, GF(5)]) # optional - sage.rings.finite_rings + sage: c = C([2,-1,2,2]); c # optional - sage.rings.finite_rings (2, -1, 2.00000000000000, 2) - sage: ~c + sage: ~c # optional - sage.rings.finite_rings (1/2, -1, 0.500000000000000, 3) This fails as soon as one of the entries is not invertible:: - sage: ~C([0,2,2,2]) + sage: ~C([0,2,2,2]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: rational division by zero - sage: ~C([2,2,2,2]) + sage: ~C([2,2,2,2]) # optional - sage.rings.finite_rings (1/2, 1/2, 0.500000000000000, 3) """ # variant without coercion: @@ -684,20 +693,22 @@ def extra_super_categories(self): """ EXAMPLES:: - sage: Magmas().Commutative().Algebras(QQ).extra_super_categories() + sage: MCA = Magmas().Commutative().Algebras(QQ) + sage: MCA.extra_super_categories() [Category of commutative magmas] This implements the fact that the algebra of a commutative magma is commutative:: - sage: Magmas().Commutative().Algebras(QQ).super_categories() + sage: MCA.super_categories() [Category of magma algebras over Rational Field, Category of commutative magmas] In particular, commutative monoid algebras are commutative algebras:: - sage: Monoids().Commutative().Algebras(QQ).is_subcategory(Algebras(QQ).Commutative()) + sage: MoCA = Monoids().Commutative().Algebras(QQ) + sage: MoCA.is_subcategory(Algebras(QQ).Commutative()) True """ return [Magmas().Unital()] @@ -713,11 +724,11 @@ def one(self): EXAMPLES:: - sage: from sage.combinat.root_system.extended_affine_weyl_group import ExtendedAffineWeylGroup - sage: PvW0 = ExtendedAffineWeylGroup(['A',2,1]).PvW0() - sage: PvW0 in Magmas().Unital().Realizations() + sage: from sage.combinat.root_system.extended_affine_weyl_group import ExtendedAffineWeylGroup # optional - sage.combinat sage.groups + sage: PvW0 = ExtendedAffineWeylGroup(['A',2,1]).PvW0() # optional - sage.combinat sage.groups + sage: PvW0 in Magmas().Unital().Realizations() # optional - sage.combinat sage.groups True - sage: PvW0.one() + sage: PvW0.one() # optional - sage.combinat sage.groups 1 """ return self(self.realization_of().a_realization().one()) @@ -758,7 +769,8 @@ def product(self, x, y): Currently, ``S.product`` is just a bound method:: sage: bin - + When Sage will support multivariate morphisms, it will be possible, and in fact recommended, to enrich ``S.product`` @@ -872,8 +884,8 @@ def multiplication_table(self, names='letters', elements=None): The default is to represent elements as lowercase ASCII letters. :: - sage: G = CyclicPermutationGroup(5) - sage: G.multiplication_table() + sage: G = CyclicPermutationGroup(5) # optional - sage.groups + sage: G.multiplication_table() # optional - sage.groups * a b c d e +---------- a| a b c d e @@ -890,10 +902,10 @@ def multiplication_table(self, names='letters', elements=None): sage: from sage.categories.examples.finite_semigroups import LeftRegularBand sage: L = LeftRegularBand(('a', 'b')) - sage: T = L.multiplication_table(names='digits') - sage: T.column_keys() + sage: T = L.multiplication_table(names='digits') # optional - sage.matrix + sage: T.column_keys() # optional - sage.matrix ('a', 'ab', 'b', 'ba') - sage: T + sage: T # optional - sage.matrix * 0 1 2 3 +-------- 0| 0 1 1 1 @@ -906,7 +918,7 @@ def multiplication_table(self, names='letters', elements=None): sage: L = LeftRegularBand(('a', 'b', 'c')) sage: elts = sorted(L.list()) - sage: L.multiplication_table(elements=elts) + sage: L.multiplication_table(elements=elts) # optional - sage.matrix * a b c d e f g h i j k l m n o +------------------------------ a| a b c d e b b c c c d d e e e @@ -935,7 +947,7 @@ def multiplication_table(self, names='letters', elements=None): sage: L = LeftRegularBand(('a','b','c')) sage: elts=['a', 'c', 'ac', 'ca'] - sage: L.multiplication_table(names='elements', elements=elts) + sage: L.multiplication_table(names='elements', elements=elts) # optional - sage.matrix * 'a' 'c' 'ac' 'ca' +-------------------- 'a'| 'a' 'ac' 'ac' 'ac' @@ -948,16 +960,16 @@ def multiplication_table(self, names='letters', elements=None): :class:`~sage.matrix.operation_table.OperationTable` for more comprehensive documentation. :: - sage: G = AlternatingGroup(3) - sage: T = G.multiplication_table() - sage: T.column_keys() + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: T = G.multiplication_table() # optional - sage.groups sage.matrix + sage: T.column_keys() # optional - sage.groups sage.matrix ((), (1,2,3), (1,3,2)) - sage: T.translation() + sage: T.translation() # optional - sage.groups sage.matrix {'a': (), 'b': (1,2,3), 'c': (1,3,2)} - sage: T.change_names(['x', 'y', 'z']) - sage: T.translation() + sage: T.change_names(['x', 'y', 'z']) # optional - sage.groups sage.matrix + sage: T.translation() # optional - sage.groups sage.matrix {'x': (), 'y': (1,2,3), 'z': (1,3,2)} - sage: T + sage: T # optional - sage.groups sage.matrix * x y z +------ x| x y z @@ -999,7 +1011,8 @@ def is_idempotent(self): EXAMPLES:: sage: S = Semigroups().example("free"); S - An example of a semigroup: the free semigroup generated by ('a', 'b', 'c', 'd') + An example of a semigroup: + the free semigroup generated by ('a', 'b', 'c', 'd') sage: a = S('a') sage: a^2 'aa' @@ -1071,12 +1084,12 @@ def product(self, left, right): sage: x * x (1/4, 1, 1) - sage: A = SymmetricGroupAlgebra(QQ, 3) - sage: x = cartesian_product([A([1,3,2]), A([2,3,1])]) - sage: y = cartesian_product([A([1,3,2]), A([2,3,1])]) - sage: cartesian_product([A,A]).product(x,y) + sage: A = SymmetricGroupAlgebra(QQ, 3) # optional - sage.groups + sage: x = cartesian_product([A([1,3,2]), A([2,3,1])]) # optional - sage.groups + sage: y = cartesian_product([A([1,3,2]), A([2,3,1])]) # optional - sage.groups + sage: cartesian_product([A,A]).product(x,y) # optional - sage.groups B[(0, [1, 2, 3])] + B[(1, [3, 1, 2])] - sage: x*y + sage: x*y # optional - sage.groups B[(0, [1, 2, 3])] + B[(1, [3, 1, 2])] """ prods = ((a * b) for a, b in zip(left.cartesian_factors(), @@ -1125,9 +1138,9 @@ def product(self, x, y): Here is a more elaborate example involving a sub algebra:: - sage: Z = SymmetricGroup(5).algebra(QQ).center() - sage: B = Z.basis() - sage: B[3] * B[2] + sage: Z = SymmetricGroup(5).algebra(QQ).center() # optional - sage.groups + sage: B = Z.basis() # optional - sage.groups + sage: B[3] * B[2] # optional - sage.groups 4*B[2] + 6*B[3] + 5*B[6] """ assert x in self @@ -1149,15 +1162,18 @@ def product_by_coercion(self, left, right): EXAMPLES:: - sage: Out = Sets().WithRealizations().example().Out(); Out - The subset algebra of {1, 2, 3} over Rational Field in the Out basis - sage: Out.product - - sage: Out.product.__module__ + sage: Out = Sets().WithRealizations().example().Out(); Out # optional - sage.combinat sage.modules + The subset algebra of {1, 2, 3} over Rational Field + in the Out basis + sage: Out.product # optional - sage.combinat sage.modules + + sage: Out.product.__module__ # optional - sage.combinat sage.modules 'sage.categories.magmas' - sage: x = Out.an_element() - sage: y = Out.an_element() - sage: Out.product(x, y) + sage: x = Out.an_element() # optional - sage.combinat sage.modules + sage: y = Out.an_element() # optional - sage.combinat sage.modules + sage: Out.product(x, y) # optional - sage.combinat sage.modules Out[{}] + 4*Out[{1}] + 9*Out[{2}] + Out[{1, 2}] """ diff --git a/src/sage/categories/magmatic_algebras.py b/src/sage/categories/magmatic_algebras.py index ef82ba4319b..171f564534e 100644 --- a/src/sage/categories/magmatic_algebras.py +++ b/src/sage/categories/magmatic_algebras.py @@ -40,7 +40,8 @@ class MagmaticAlgebras(Category_over_base_ring): sage: C = MagmaticAlgebras(ZZ); C Category of magmatic algebras over Integer Ring sage: C.super_categories() - [Category of additive commutative additive associative additive unital distributive magmas and additive magmas, + [Category of additive commutative additive associative additive + unital distributive magmas and additive magmas, Category of modules over Integer Ring] TESTS:: @@ -54,11 +55,14 @@ def super_categories(self): EXAMPLES:: sage: from sage.categories.magmatic_algebras import MagmaticAlgebras - sage: MagmaticAlgebras(ZZ).super_categories() - [Category of additive commutative additive associative additive unital distributive magmas and additive magmas, Category of modules over Integer Ring] + sage: MA = MagmaticAlgebras(ZZ) + sage: MA.super_categories() + [Category of additive commutative additive associative additive + unital distributive magmas and additive magmas, + Category of modules over Integer Ring] sage: from sage.categories.additive_semigroups import AdditiveSemigroups - sage: MagmaticAlgebras(ZZ).is_subcategory((AdditiveSemigroups() & Magmas()).Distributive()) + sage: MA.is_subcategory((AdditiveSemigroups() & Magmas()).Distributive()) True """ @@ -106,9 +110,10 @@ def algebra_generators(self): EXAMPLES:: - sage: F = AlgebrasWithBasis(QQ).example(); F - An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field - sage: F.algebra_generators() + sage: F = AlgebrasWithBasis(QQ).example(); F # optional - sage.combinat sage.modules + An example of an algebra with basis: + the free algebra on the generators ('a', 'b', 'c') over Rational Field + sage: F.algebra_generators() # optional - sage.combinat sage.modules Family (B[word: a], B[word: b], B[word: c]) """ @@ -131,16 +136,18 @@ def algebra_generators(self): EXAMPLES:: - sage: D4 = DescentAlgebra(QQ, 4).B() - sage: D4.algebra_generators() + sage: D4 = DescentAlgebra(QQ, 4).B() # optional - sage.combinat sage.modules + sage: D4.algebra_generators() # optional - sage.combinat sage.modules Lazy family (...)_{i in Compositions of 4} sage: R. = ZZ[] - sage: P = PartitionAlgebra(1, x, R) - sage: P.algebra_generators() - Lazy family (Term map from Partition diagrams of order 1 to - Partition Algebra of rank 1 with parameter x over Univariate Polynomial Ring in x - over Integer Ring(i))_{i in Partition diagrams of order 1} + sage: P = PartitionAlgebra(1, x, R) # optional - sage.combinat sage.modules + sage: P.algebra_generators() # optional - sage.combinat sage.modules + Lazy family (Term map + from Partition diagrams of order 1 + to Partition Algebra of rank 1 with parameter x + over Univariate Polynomial Ring in x + over Integer Ring(i))_{i in Partition diagrams of order 1} """ return self.basis() @@ -162,9 +169,9 @@ def product_on_basis(self, i, j): EXAMPLES:: - sage: A = AlgebrasWithBasis(QQ).example() - sage: Word = A.basis().keys() - sage: A.product_on_basis(Word("abc"),Word("cba")) + sage: A = AlgebrasWithBasis(QQ).example() # optional - sage.combinat sage.modules + sage: Word = A.basis().keys() # optional - sage.combinat sage.modules + sage: A.product_on_basis(Word("abc"), Word("cba")) # optional - sage.combinat sage.modules B[word: abccba] """ @@ -183,9 +190,9 @@ def product(self): EXAMPLES:: - sage: A = AlgebrasWithBasis(QQ).example() - sage: a, b, c = A.algebra_generators() - sage: A.product(a + 2*b, 3*c) + sage: A = AlgebrasWithBasis(QQ).example() # optional - sage.combinat sage.modules + sage: a, b, c = A.algebra_generators() # optional - sage.combinat sage.modules + sage: A.product(a + 2*b, 3*c) # optional - sage.combinat sage.modules 3*B[word: ac] + 6*B[word: bc] """ if self.product_on_basis is not NotImplemented: @@ -205,10 +212,11 @@ def _product_from_product_on_basis_multiply( self, left, right ): EXAMPLES:: - sage: A = AlgebrasWithBasis(QQ).example(); A - An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field - sage: (a,b,c) = A.algebra_generators() - sage: A._product_from_product_on_basis_multiply(a*b + 2*c, a - b) + sage: A = AlgebrasWithBasis(QQ).example(); A # optional - sage.combinat sage.modules + An example of an algebra with basis: + the free algebra on the generators ('a', 'b', 'c') over Rational Field + sage: a, b, c = A.algebra_generators() # optional - sage.combinat sage.modules + sage: A._product_from_product_on_basis_multiply(a*b + 2*c, a - b) # optional - sage.combinat sage.modules B[word: aba] - B[word: abb] + 2*B[word: ca] - 2*B[word: cb] """ @@ -239,17 +247,17 @@ def derivations_basis(self): We construct the Heisenberg Lie algebra as a multiplicative algebra:: - sage: p_mult = matrix([[0,0,0],[0,0,-1],[0,0,0]]) - sage: q_mult = matrix([[0,0,1],[0,0,0],[0,0,0]]) - sage: A = algebras.FiniteDimensional(QQ, - ....: [p_mult,q_mult,matrix(QQ,3,3)], 'p,q,z') - sage: A.inject_variables() + sage: p_mult = matrix([[0,0,0], [0,0,-1], [0,0,0]]) # optional - sage.combinat sage.modules + sage: q_mult = matrix([[0,0,1], [0,0,0], [0,0,0]]) # optional - sage.combinat sage.modules + sage: A = algebras.FiniteDimensional(QQ, # optional - sage.combinat sage.modules + ....: [p_mult, q_mult, matrix(QQ, 3, 3)], 'p,q,z') + sage: A.inject_variables() # optional - sage.combinat sage.modules Defining p, q, z - sage: p*q + sage: p * q # optional - sage.combinat sage.modules z - sage: q*p + sage: q * p # optional - sage.combinat sage.modules -z - sage: A.derivations_basis() + sage: A.derivations_basis() # optional - sage.combinat sage.modules ( [1 0 0] [0 1 0] [0 0 0] [0 0 0] [0 0 0] [0 0 0] [0 0 0] [0 0 0] [1 0 0] [0 1 0] [0 0 0] [0 0 0] @@ -259,15 +267,16 @@ def derivations_basis(self): We construct another example using the exterior algebra and verify we obtain a derivation:: - sage: A = algebras.Exterior(QQ, 1) - sage: A.derivations_basis() + sage: A = algebras.Exterior(QQ, 1) # optional - sage.combinat sage.modules + sage: A.derivations_basis() # optional - sage.combinat sage.modules ( [0 0] [0 1] ) - sage: D = A.module_morphism(matrix=A.derivations_basis()[0], codomain=A) - sage: one, e = A.basis() - sage: all(D(a*b) == D(a) * b + a * D(b) + sage: D = A.module_morphism(matrix=A.derivations_basis()[0], # optional - sage.combinat sage.modules + ....: codomain=A) + sage: one, e = A.basis() # optional - sage.combinat sage.modules + sage: all(D(a*b) == D(a) * b + a * D(b) # optional - sage.combinat sage.modules ....: for a in A.basis() for b in A.basis()) True diff --git a/src/sage/categories/map.pyx b/src/sage/categories/map.pyx index 5a7445913bb..39d37acc2ae 100644 --- a/src/sage/categories/map.pyx +++ b/src/sage/categories/map.pyx @@ -115,7 +115,7 @@ cdef class Map(Element): Using domain and codomain:: - sage: Map(QQ['x'], SymmetricGroup(6)) + sage: Map(QQ['x'], SymmetricGroup(6)) # optional - sage.groups Generic map: From: Univariate Polynomial Ring in x over Rational Field To: Symmetric group of order 6! as a permutation group @@ -196,34 +196,44 @@ cdef class Map(Element): EXAMPLES:: - sage: Q = QuadraticField(-5) - sage: phi = CDF._internal_convert_map_from(Q) - sage: print(phi.parent()) - Set of field embeddings from Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I to Complex Double Field + sage: Q = QuadraticField(-5) # optional - sage.rings.number_field + sage: phi = CDF._internal_convert_map_from(Q) # optional - sage.rings.number_field + sage: print(phi.parent()) # optional - sage.rings.number_field + Set of field embeddings + from Number Field in a with defining polynomial x^2 + 5 + with a = 2.236067977499790?*I + to Complex Double Field We now demonstrate that the reference to the coercion map `\phi` does not prevent `Q` from being garbage collected:: sage: import gc - sage: del Q + sage: del Q # optional - sage.rings.number_field sage: _ = gc.collect() - sage: phi.parent() + sage: phi.parent() # optional - sage.rings.number_field Traceback (most recent call last): ... - ValueError: This map is in an invalid state, the domain has been garbage collected + ValueError: This map is in an invalid state, + the domain has been garbage collected You can still obtain copies of the maps used by the coercion system with strong references:: - sage: Q = QuadraticField(-5) - sage: phi = CDF.convert_map_from(Q) - sage: print(phi.parent()) - Set of field embeddings from Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I to Complex Double Field + sage: Q = QuadraticField(-5) # optional - sage.rings.number_field + sage: phi = CDF.convert_map_from(Q) # optional - sage.rings.number_field + sage: print(phi.parent()) # optional - sage.rings.number_field + Set of field embeddings + from Number Field in a with defining polynomial x^2 + 5 + with a = 2.236067977499790?*I + to Complex Double Field sage: import gc - sage: del Q + sage: del Q # optional - sage.rings.number_field sage: _ = gc.collect() - sage: phi.parent() - Set of field embeddings from Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I to Complex Double Field + sage: phi.parent() # optional - sage.rings.number_field + Set of field embeddings + from Number Field in a with defining polynomial x^2 + 5 + with a = 2.236067977499790?*I + to Complex Double Field """ if self._parent is None: D = self.domain() @@ -250,28 +260,31 @@ cdef class Map(Element): EXAMPLES:: - sage: Q = QuadraticField(-5) - sage: phi = CDF._internal_convert_map_from(Q) + sage: Q = QuadraticField(-5) # optional - sage.rings.number_field + sage: phi = CDF._internal_convert_map_from(Q) # optional - sage.rings.number_field By :trac:`14711`, maps used in the coercion and conversion system use *weak* references to domain and codomain, in contrast to other maps:: - sage: phi.domain + sage: phi.domain # optional - sage.rings.number_field - sage: phi._make_strong_references() - sage: print(phi.domain) - The constant function (...) -> Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I + sage: phi._make_strong_references() # optional - sage.rings.number_field + sage: print(phi.domain) # optional - sage.rings.number_field + The constant function (...) -> Number Field in a + with defining polynomial x^2 + 5 with a = 2.236067977499790?*I Now, as there is a strong reference, `Q` cannot be garbage collected:: sage: import gc sage: _ = gc.collect() - sage: C = Q.__class__.__base__ - sage: numberQuadFields = len([x for x in gc.get_objects() if isinstance(x, C)]) - sage: del Q, x + sage: C = Q.__class__.__base__ # optional - sage.rings.number_field + sage: numberQuadFields = len([x for x in gc.get_objects() # optional - sage.rings.number_field + ....: if isinstance(x, C)]) + sage: del Q, x # optional - sage.rings.number_field sage: _ = gc.collect() - sage: numberQuadFields == len([x for x in gc.get_objects() if isinstance(x, C)]) + sage: numberQuadFields == len([x for x in gc.get_objects() # optional - sage.rings.number_field + ....: if isinstance(x, C)]) True However, if we now make the references weak again, the number field can @@ -279,11 +292,12 @@ cdef class Map(Element): invalid. This is why :meth:`_make_weak_references` should only be used if one really knows what one is doing:: - sage: phi._make_weak_references() + sage: phi._make_weak_references() # optional - sage.rings.number_field sage: _ = gc.collect() - sage: numberQuadFields == len([x for x in gc.get_objects() if isinstance(x, C)]) + 1 + sage: numberQuadFields == len([x for x in gc.get_objects() # optional - sage.rings.number_field + ....: if isinstance(x, C)]) + 1 True - sage: phi + sage: phi # optional - sage.rings.number_field Defunct map """ if not isinstance(self.domain, ConstantFunction): @@ -311,28 +325,31 @@ cdef class Map(Element): EXAMPLES:: - sage: Q = QuadraticField(-5) - sage: phi = CDF._internal_convert_map_from(Q) + sage: Q = QuadraticField(-5) # optional - sage.rings.number_field + sage: phi = CDF._internal_convert_map_from(Q) # optional - sage.rings.number_field By :trac:`14711`, maps used in the coercion and conversion system use *weak* references to domain and codomain, in contrast to other maps:: - sage: phi.domain + sage: phi.domain # optional - sage.rings.number_field - sage: phi._make_strong_references() - sage: print(phi.domain) - The constant function (...) -> Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I + sage: phi._make_strong_references() # optional - sage.rings.number_field + sage: print(phi.domain) # optional - sage.rings.number_field + The constant function (...) -> Number Field in a + with defining polynomial x^2 + 5 with a = 2.236067977499790?*I Now, as there is a strong reference, `Q` cannot be garbage collected:: sage: import gc sage: _ = gc.collect() - sage: C = Q.__class__.__base__ - sage: numberQuadFields = len([x for x in gc.get_objects() if isinstance(x, C)]) - sage: del Q, x + sage: C = Q.__class__.__base__ # optional - sage.rings.number_field + sage: numberQuadFields = len([x for x in gc.get_objects() # optional - sage.rings.number_field + ....: if isinstance(x, C)]) + sage: del Q, x # optional - sage.rings.number_field sage: _ = gc.collect() - sage: numberQuadFields == len([x for x in gc.get_objects() if isinstance(x, C)]) + sage: numberQuadFields == len([x for x in gc.get_objects() # optional - sage.rings.number_field + ....: if isinstance(x, C)]) True However, if we now make the references weak again, the number field can @@ -340,17 +357,18 @@ cdef class Map(Element): invalid. This is why :meth:`_make_weak_references` should only be used if one really knows what one is doing:: - sage: phi._make_weak_references() + sage: phi._make_weak_references() # optional - sage.rings.number_field sage: _ = gc.collect() - sage: numberQuadFields == len([x for x in gc.get_objects() if isinstance(x, C)]) + 1 + sage: numberQuadFields == len([x for x in gc.get_objects() # optional - sage.rings.number_field + ....: if isinstance(x, C)]) + 1 True - sage: phi + sage: phi # optional - sage.rings.number_field Defunct map - sage: phi._make_strong_references() + sage: phi._make_strong_references() # optional - sage.rings.number_field Traceback (most recent call last): ... RuntimeError: The domain of this map became garbage collected - sage: phi.parent() + sage: phi.parent() # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: This map is in an invalid state, the domain has been garbage collected @@ -544,16 +562,16 @@ cdef class Map(Element): TESTS:: - sage: Q = QuadraticField(-5) - sage: phi = CDF._internal_coerce_map_from(Q); phi + sage: Q = QuadraticField(-5) # optional - sage.rings.number_field + sage: phi = CDF._internal_coerce_map_from(Q); phi # optional - sage.rings.number_field (map internal to coercion system -- copy before use) Composite map: From: Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I To: Complex Double Field - sage: del Q + sage: del Q # optional - sage.rings.number_field sage: import gc sage: _ = gc.collect() - sage: phi + sage: phi # optional - sage.rings.number_field Defunct map """ D = self.domain() @@ -704,7 +722,8 @@ cdef class Map(Element): sage: f(1/2) Traceback (most recent call last): ... - TypeError: 1/2 fails to convert into the map's domain Integer Ring, but a `pushforward` method is not properly implemented + TypeError: 1/2 fails to convert into the map's domain Integer Ring, + but a `pushforward` method is not properly implemented We test that the default call method really works as described above (that was fixed in :trac:`10496`):: @@ -746,11 +765,11 @@ cdef class Map(Element): ``pushforward`` fails, ``_call_`` is tried after conversion:: sage: g = FOO(QQ, ZZ) - sage: g(SR(3)) # optional - sage.symbolic + sage: g(SR(3)) # optional - sage.symbolic pushforward Symbolic Ring _call_ Rational Field 3 - sage: g(SR(3), exponent=2) # optional - sage.symbolic + sage: g(SR(3), exponent=2) # optional - sage.symbolic pushforward Symbolic Ring _call_with_args Rational Field 9 @@ -761,7 +780,8 @@ cdef class Map(Element): sage: h(2/3) Traceback (most recent call last): ... - TypeError: 2/3 fails to convert into the map's domain Integer Ring, but a `pushforward` method is not properly implemented + TypeError: 2/3 fails to convert into the map's domain Integer Ring, + but a `pushforward` method is not properly implemented """ P = parent(x) cdef Parent D = self.domain() @@ -1122,7 +1142,8 @@ cdef class Map(Element): sage: mor.extend_domain(ZZ['x']) Traceback (most recent call last): ... - TypeError: No coercion from Univariate Polynomial Ring in x over Integer Ring to Real Double Field + TypeError: No coercion from Univariate Polynomial Ring in x over Integer Ring + to Real Double Field """ D = self.domain() if D is None: @@ -1162,7 +1183,7 @@ cdef class Map(Element): Native morphism: From: Rational Field To: Real Double Field - sage: mor.extend_codomain(GF(7)) + sage: mor.extend_codomain(GF(7)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: No coercion from Rational Field to Finite Field of size 7 @@ -1217,14 +1238,14 @@ cdef class Map(Element): ... TypeError: self must be an endomorphism - sage: K. = NumberField(x^4 - 5*x + 5) - sage: C5. = CyclotomicField(5) - sage: tau = K.hom([z - z^2]); tau + sage: K. = NumberField(x^4 - 5*x + 5) # optional - sage.rings.number_field + sage: C5. = CyclotomicField(5) # optional - sage.rings.number_field + sage: tau = K.hom([z - z^2]); tau # optional - sage.rings.number_field Ring morphism: From: Number Field in a with defining polynomial x^4 - 5*x + 5 To: Cyclotomic Field of order 5 and degree 4 Defn: a |--> -z^2 + z - sage: tau^-1 + sage: tau^-1 # optional - sage.rings.number_field Ring morphism: From: Cyclotomic Field of order 5 and degree 4 To: Number Field in a with defining polynomial x^4 - 5*x + 5 @@ -1851,24 +1872,26 @@ cdef class FormalCompositeMap(Map): EXAMPLES:: - sage: V1 = QQ^2 - sage: V2 = QQ^3 - sage: phi1 = (QQ^1).hom(Matrix([[1, 1]]), V1) - sage: phi2 = V1.hom(Matrix([[1, 2, 3], [4, 5, 6]]), V2) + sage: V1 = QQ^2 # optional - sage.modules + sage: V2 = QQ^3 # optional - sage.modules + sage: phi1 = (QQ^1).hom(Matrix([[1, 1]]), V1) # optional - sage.modules + sage: phi2 = V1.hom(Matrix([[1, 2, 3], [4, 5, 6]]), V2) # optional - sage.modules If both constituents are injective, the composition is injective:: sage: from sage.categories.map import FormalCompositeMap - sage: c1 = FormalCompositeMap(Hom(QQ^1, V2, phi1.category_for()), phi1, phi2) - sage: c1.is_injective() + sage: c1 = FormalCompositeMap(Hom(QQ^1, V2, phi1.category_for()), # optional - sage.modules + ....: phi1, phi2) + sage: c1.is_injective() # optional - sage.modules True If it cannot be determined whether the composition is injective, an error is raised:: - sage: psi1 = V2.hom(Matrix([[1, 2], [3, 4], [5, 6]]), V1) - sage: c2 = FormalCompositeMap(Hom(V1, V1, phi2.category_for()), phi2, psi1) - sage: c2.is_injective() + sage: psi1 = V2.hom(Matrix([[1, 2], [3, 4], [5, 6]]), V1) # optional - sage.modules + sage: c2 = FormalCompositeMap(Hom(V1, V1, phi2.category_for()), # optional - sage.modules + ....: phi2, psi1) + sage: c2.is_injective() # optional - sage.modules Traceback (most recent call last): ... NotImplementedError: not enough information to deduce injectivity @@ -1876,17 +1899,18 @@ cdef class FormalCompositeMap(Map): If the first map is surjective and the second map is not injective, then the composition is not injective:: - sage: psi2 = V1.hom([[1], [1]], QQ^1) - sage: c3 = FormalCompositeMap(Hom(V2, QQ^1, phi2.category_for()), psi2, psi1) - sage: c3.is_injective() + sage: psi2 = V1.hom([[1], [1]], QQ^1) # optional - sage.modules + sage: c3 = FormalCompositeMap(Hom(V2, QQ^1, phi2.category_for()), # optional - sage.modules + ....: psi2, psi1) + sage: c3.is_injective() # optional - sage.modules False TESTS: Check that :trac:`23205` has been resolved:: - sage: f = QQ.hom(QQbar)*ZZ.hom(QQ) - sage: f.is_injective() + sage: f = QQ.hom(QQbar) * ZZ.hom(QQ) # optional - sage.rings.number_field + sage: f.is_injective() # optional - sage.rings.number_field True """ @@ -1923,33 +1947,38 @@ cdef class FormalCompositeMap(Map): EXAMPLES:: sage: from sage.categories.map import FormalCompositeMap - sage: V3 = QQ^3 - sage: V2 = QQ^2 - sage: V1 = QQ^1 + sage: V3 = QQ^3 # optional - sage.modules + sage: V2 = QQ^2 # optional - sage.modules + sage: V1 = QQ^1 # optional - sage.modules If both maps are surjective, the composition is surjective:: - sage: phi32 = V3.hom(Matrix([[1, 2], [3, 4], [5, 6]]), V2) - sage: phi21 = V2.hom(Matrix([[1], [1]]), V1) - sage: c_phi = FormalCompositeMap(Hom(V3, V1, phi32.category_for()), phi32, phi21) - sage: c_phi.is_surjective() + sage: phi32 = V3.hom(Matrix([[1, 2], [3, 4], [5, 6]]), V2) # optional - sage.modules + sage: phi21 = V2.hom(Matrix([[1], [1]]), V1) # optional - sage.modules + sage: c_phi = FormalCompositeMap(Hom(V3, V1, phi32.category_for()), # optional - sage.modules + ....: phi32, phi21) + sage: c_phi.is_surjective() # optional - sage.modules True If the second map is not surjective, the composition is not surjective:: - sage: FormalCompositeMap(Hom(V3, V1, phi32.category_for()), phi32, V2.hom(Matrix([[0], [0]]), V1)).is_surjective() + sage: FormalCompositeMap(Hom(V3, V1, phi32.category_for()), # optional - sage.modules + ....: phi32, + ....: V2.hom(Matrix([[0], [0]]), V1)).is_surjective() False If the second map is an isomorphism and the first map is not surjective, then the composition is not surjective:: - sage: FormalCompositeMap(Hom(V2, V1, phi32.category_for()), V2.hom(Matrix([[0], [0]]), V1), V1.hom(Matrix([[1]]), V1)).is_surjective() + sage: FormalCompositeMap(Hom(V2, V1, phi32.category_for()), # optional - sage.modules + ....: V2.hom(Matrix([[0], [0]]), V1), + ....: V1.hom(Matrix([[1]]), V1)).is_surjective() False Otherwise, surjectivity of the composition cannot be determined:: - sage: FormalCompositeMap(Hom(V2, V1, phi32.category_for()), + sage: FormalCompositeMap(Hom(V2, V1, phi32.category_for()), # optional - sage.modules ....: V2.hom(Matrix([[1, 1], [1, 1]]), V2), ....: V2.hom(Matrix([[1], [1]]), V1)).is_surjective() Traceback (most recent call last): @@ -1991,8 +2020,8 @@ cdef class FormalCompositeMap(Map): EXAMPLES:: sage: f = QQ.coerce_map_from(ZZ) - sage: g = MatrixSpace(QQ, 2, 2).coerce_map_from(QQ) - sage: list((g*f).domains()) + sage: g = MatrixSpace(QQ, 2, 2).coerce_map_from(QQ) # optional - sage.modules + sage: list((g * f).domains()) # optional - sage.modules [Integer Ring, Rational Field] """ for f in self.__list: @@ -2026,9 +2055,9 @@ cdef class FormalCompositeMap(Map): of :class:`sage.rings.polynomial.polynomial_element.Polynomial` before (see comment there):: - sage: k = GF(47) - sage: R. = PolynomialRing(k) - sage: R.coerce_map_from(ZZ).section() + sage: k = GF(47) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(k) # optional - sage.rings.finite_rings + sage: R.coerce_map_from(ZZ).section() # optional - sage.rings.finite_rings Composite map: From: Univariate Polynomial Ring in x over Finite Field of size 47 To: Integer Ring @@ -2039,9 +2068,9 @@ cdef class FormalCompositeMap(Map): Lifting map: From: Finite Field of size 47 To: Integer Ring - sage: ZZ(R(45)) # indirect doctest + sage: ZZ(R(45)) # indirect doctest # optional - sage.rings.finite_rings 45 - sage: ZZ(3*x + 45) # indirect doctest + sage: ZZ(3*x + 45) # indirect doctest # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: not a constant polynomial diff --git a/src/sage/categories/modules.py b/src/sage/categories/modules.py index cb878f1c6f2..81f6df6f51f 100644 --- a/src/sage/categories/modules.py +++ b/src/sage/categories/modules.py @@ -72,10 +72,12 @@ class Modules(Category_module): Category of modules over Ring of integers modulo 9 sage: Modules(Integers(9)).super_categories() - [Category of bimodules over Ring of integers modulo 9 on the left and Ring of integers modulo 9 on the right] + [Category of bimodules over Ring of integers modulo 9 on the left + and Ring of integers modulo 9 on the right] sage: Modules(ZZ).super_categories() - [Category of bimodules over Integer Ring on the left and Integer Ring on the right] + [Category of bimodules over Integer Ring on the left + and Integer Ring on the right] sage: Modules == RingModules True @@ -162,7 +164,8 @@ def super_categories(self): EXAMPLES:: sage: Modules(ZZ).super_categories() - [Category of bimodules over Integer Ring on the left and Integer Ring on the right] + [Category of bimodules over Integer Ring on the left + and Integer Ring on the right] Nota bene:: @@ -204,7 +207,8 @@ def base_ring(self): EXAMPLES:: sage: C = Modules(QQ) & Semigroups(); C - Join of Category of semigroups and Category of vector spaces over Rational Field + Join of Category of semigroups + and Category of vector spaces over Rational Field sage: C.base_ring() Rational Field sage: C.base_ring.__module__ @@ -217,16 +221,16 @@ def base_ring(self): sage: C.base_ring.__module__ 'sage.categories.modules' - sage: C = DescentAlgebra(QQ,3).B().category() - sage: C.base_ring.__module__ + sage: C = DescentAlgebra(QQ,3).B().category() # optional - sage.combinat sage.modules + sage: C.base_ring.__module__ # optional - sage.combinat sage.modules 'sage.categories.modules' - sage: C.base_ring() + sage: C.base_ring() # optional - sage.combinat sage.modules Rational Field - sage: C = QuasiSymmetricFunctions(QQ).F().category() - sage: C.base_ring.__module__ + sage: C = QuasiSymmetricFunctions(QQ).F().category() # optional - sage.combinat sage.modules + sage: C.base_ring.__module__ # optional - sage.combinat sage.modules 'sage.categories.modules' - sage: C.base_ring() + sage: C.base_ring() # optional - sage.combinat sage.modules Rational Field """ for C in self.super_categories(): @@ -361,10 +365,11 @@ def FinitelyPresented(self): sage: Modules(ZZ).FinitelyPresented() Category of finitely presented modules over Integer Ring - sage: A = SteenrodAlgebra(2) - sage: from sage.modules.fp_graded.module import FPModule - sage: FPModule(A, [0, 1], [[Sq(2), Sq(1)]]).category() - Category of finitely presented graded modules over mod 2 Steenrod algebra, milnor basis + sage: A = SteenrodAlgebra(2) # optional - sage.combinat sage.modules + sage: from sage.modules.fp_graded.module import FPModule # optional - sage.combinat sage.modules + sage: FPModule(A, [0, 1], [[Sq(2), Sq(1)]]).category() # optional - sage.combinat sage.modules + Category of finitely presented graded modules + over mod 2 Steenrod algebra, milnor basis TESTS:: @@ -516,7 +521,7 @@ def extra_super_categories(self): [Category of finite sets] sage: Modules(ZZ).FiniteDimensional().extra_super_categories() [] - sage: Modules(GF(5)).FiniteDimensional().is_subcategory(Sets().Finite()) + sage: Modules(GF(5)).FiniteDimensional().is_subcategory(Sets().Finite()) # optional - sage.rings.finite_rings True sage: Modules(ZZ).FiniteDimensional().is_subcategory(Sets().Finite()) False @@ -547,7 +552,8 @@ def extra_super_categories(self): sage: Modules(ZZ).FiniteDimensional().TensorProducts().extra_super_categories() [Category of finite dimensional modules over Integer Ring] sage: Modules(QQ).FiniteDimensional().TensorProducts().FiniteDimensional() - Category of tensor products of finite dimensional vector spaces over Rational Field + Category of tensor products of finite dimensional vector spaces + over Rational Field """ return [self.base_category()] @@ -565,7 +571,7 @@ def extra_super_categories(self): [Category of finite sets] sage: Modules(ZZ).FiniteDimensional().extra_super_categories() [] - sage: Modules(GF(5)).FiniteDimensional().is_subcategory(Sets().Finite()) + sage: Modules(GF(5)).FiniteDimensional().is_subcategory(Sets().Finite()) # optional - sage.rings.finite_rings True sage: Modules(ZZ).FiniteDimensional().is_subcategory(Sets().Finite()) False @@ -612,9 +618,9 @@ def linear_combination(self, iter_of_elements_coeff, factor_on_left=True): EXAMPLES:: - sage: m = matrix([[0,1],[1,1]]) - sage: J. = JordanAlgebra(m) - sage: J.linear_combination(((a+b, 1), (-2*b + c, -1))) + sage: m = matrix([[0,1], [1,1]]) # optional - sage.modules + sage: J. = JordanAlgebra(m) # optional - sage.combinat sage.modules + sage: J.linear_combination(((a+b, 1), (-2*b + c, -1))) # optional - sage.combinat sage.modules 1 + (3, -1) """ if factor_on_left: @@ -631,8 +637,8 @@ def tensor_square(self): EXAMPLES:: - sage: A = HopfAlgebrasWithBasis(QQ).example() - sage: A.tensor_square() + sage: A = HopfAlgebrasWithBasis(QQ).example() # optional - sage.groups sage.modules + sage: A.tensor_square() # optional - sage.groups sage.modules An example of Hopf algebra with basis: the group algebra of the Dihedral group of order 6 as a permutation group over Rational Field # An example @@ -661,12 +667,14 @@ def module_morphism(self, *, function, category=None, codomain, **keywords): EXAMPLES:: - sage: V = FiniteRankFreeModule(QQ, 2) - sage: e = V.basis('e'); e - Basis (e_0,e_1) on the 2-dimensional vector space over the Rational Field - sage: neg = V.module_morphism(function=operator.neg, codomain=V); neg - Generic endomorphism of 2-dimensional vector space over the Rational Field - sage: neg(e[0]) + sage: V = FiniteRankFreeModule(QQ, 2) # optional - sage.modules + sage: e = V.basis('e'); e # optional - sage.modules + Basis (e_0,e_1) on the + 2-dimensional vector space over the Rational Field + sage: neg = V.module_morphism(function=operator.neg, codomain=V); neg # optional - sage.modules + Generic endomorphism of + 2-dimensional vector space over the Rational Field + sage: neg(e[0]) # optional - sage.modules Element -e_0 of the 2-dimensional vector space over the Rational Field """ @@ -698,11 +706,12 @@ def quotient(self, submodule, check=True, **kwds): EXAMPLES:: - sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) - sage: TA = TensorAlgebra(C) - sage: TA.quotient + sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) # optional - sage.modules + sage: TA = TensorAlgebra(C) # optional - sage.modules + sage: TA.quotient # optional - sage.modules + Tensor Algebra of Free module generated by {'a', 'b', 'c'} + over Rational Field> """ return self.quotient_module(submodule, check=check, **kwds) @@ -748,21 +757,21 @@ def base_ring(self): EXAMPLES:: - sage: E = CombinatorialFreeModule(ZZ, [1,2,3]) - sage: F = CombinatorialFreeModule(ZZ, [2,3,4]) - sage: H = Hom(E, F) - sage: H.base_ring() + sage: E = CombinatorialFreeModule(ZZ, [1,2,3]) # optional - sage.modules + sage: F = CombinatorialFreeModule(ZZ, [2,3,4]) # optional - sage.modules + sage: H = Hom(E, F) # optional - sage.modules + sage: H.base_ring() # optional - sage.modules Integer Ring This ``base_ring`` method is actually overridden by :meth:`sage.structure.category_object.CategoryObject.base_ring`:: - sage: H.base_ring.__module__ + sage: H.base_ring.__module__ # optional - sage.modules Here we call it directly:: - sage: method = H.category().parent_class.base_ring - sage: method.__get__(H)() + sage: method = H.category().parent_class.base_ring # optional - sage.modules + sage: method.__get__(H)() # optional - sage.modules Integer Ring """ return self.domain().base_ring() @@ -772,24 +781,24 @@ def zero(self): """ EXAMPLES:: - sage: E = CombinatorialFreeModule(ZZ, [1,2,3]) - sage: F = CombinatorialFreeModule(ZZ, [2,3,4]) - sage: H = Hom(E, F) - sage: f = H.zero() - sage: f + sage: E = CombinatorialFreeModule(ZZ, [1,2,3]) # optional - sage.modules + sage: F = CombinatorialFreeModule(ZZ, [2,3,4]) # optional - sage.modules + sage: H = Hom(E, F) # optional - sage.modules + sage: f = H.zero() # optional - sage.modules + sage: f # optional - sage.modules Generic morphism: From: Free module generated by {1, 2, 3} over Integer Ring To: Free module generated by {2, 3, 4} over Integer Ring - sage: f(E.monomial(2)) + sage: f(E.monomial(2)) # optional - sage.modules 0 - sage: f(E.monomial(3)) == F.zero() + sage: f(E.monomial(3)) == F.zero() # optional - sage.modules True TESTS: We check that ``H.zero()`` is picklable:: - sage: loads(dumps(f.parent().zero())) + sage: loads(dumps(f.parent().zero())) # optional - sage.modules Generic morphism: From: Free module generated by {1, 2, 3} over Integer Ring To: Free module generated by {2, 3, 4} over Integer Ring @@ -813,7 +822,7 @@ def extra_super_categories(self): sage: Modules(ZZ).Endsets().extra_super_categories() [Category of magmatic algebras over Integer Ring] - sage: End(ZZ^3) in Algebras(ZZ) + sage: End(ZZ^3) in Algebras(ZZ) # optional - sage.modules True """ from .magmatic_algebras import MagmaticAlgebras @@ -852,38 +861,46 @@ def __init_extra__(self): EXAMPLES:: - sage: E = CombinatorialFreeModule(ZZ, [1,2,3]) - sage: F = CombinatorialFreeModule(ZZ, [2,3,4]) - sage: C = cartesian_product([E, F]); C + sage: E = CombinatorialFreeModule(ZZ, [1,2,3]) # optional - sage.modules + sage: F = CombinatorialFreeModule(ZZ, [2,3,4]) # optional - sage.modules + sage: C = cartesian_product([E, F]); C # optional - sage.modules Free module generated by {1, 2, 3} over Integer Ring (+) Free module generated by {2, 3, 4} over Integer Ring - sage: C.base_ring() + sage: C.base_ring() # optional - sage.modules Integer Ring Check that :trac:`29225` is fixed:: - sage: M = cartesian_product((ZZ^2, ZZ^3)); M - The Cartesian product of (Ambient free module of rank 2 over the principal ideal domain Integer Ring, Ambient free module of rank 3 over the principal ideal domain Integer Ring) - sage: M.category() - Category of Cartesian products of modules with basis over (euclidean domains and infinite enumerated sets and metric spaces) - sage: M.base_ring() + sage: M = cartesian_product((ZZ^2, ZZ^3)); M # optional - sage.modules + The Cartesian product of + (Ambient free module of rank 2 over the principal ideal domain Integer Ring, + Ambient free module of rank 3 over the principal ideal domain Integer Ring) + sage: M.category() # optional - sage.modules + Category of Cartesian products of modules with basis + over (euclidean domains and infinite enumerated sets and metric spaces) + sage: M.base_ring() # optional - sage.modules Integer Ring - sage: A = cartesian_product((QQ^2, QQ['x'])); A - The Cartesian product of (Vector space of dimension 2 over Rational Field, Univariate Polynomial Ring in x over Rational Field) - sage: A.category() - Category of Cartesian products of vector spaces over (number fields and quotient fields and metric spaces) - sage: A.base_ring() + sage: A = cartesian_product((QQ^2, QQ['x'])); A # optional - sage.modules + The Cartesian product of + (Vector space of dimension 2 over Rational Field, + Univariate Polynomial Ring in x over Rational Field) + sage: A.category() # optional - sage.modules + Category of Cartesian products of vector spaces + over (number fields and quotient fields and metric spaces) + sage: A.base_ring() # optional - sage.modules Rational Field This currently only works if all factors have the same base ring:: - sage: B = cartesian_product((ZZ['x'], QQ^3)); B - The Cartesian product of (Univariate Polynomial Ring in x over Integer Ring, Vector space of dimension 3 over Rational Field) - sage: B.category() + sage: B = cartesian_product((ZZ['x'], QQ^3)); B # optional - sage.modules + The Cartesian product of + (Univariate Polynomial Ring in x over Integer Ring, + Vector space of dimension 3 over Rational Field) + sage: B.category() # optional - sage.modules Category of Cartesian products of commutative additive groups - sage: B.base_ring() + sage: B.base_ring() # optional - sage.modules """ factors = self._sets if factors: @@ -899,10 +916,12 @@ def _lmul_(self, x): EXAMPLES:: - sage: A = FreeModule(ZZ, 2) - sage: B = cartesian_product([A, A]); B - The Cartesian product of (Ambient free module of rank 2 over the principal ideal domain Integer Ring, Ambient free module of rank 2 over the principal ideal domain Integer Ring) - sage: 5*B(([1, 2], [3, 4])) + sage: A = FreeModule(ZZ, 2) # optional - sage.modules + sage: B = cartesian_product([A, A]); B # optional - sage.modules + The Cartesian product of + (Ambient free module of rank 2 over the principal ideal domain Integer Ring, + Ambient free module of rank 2 over the principal ideal domain Integer Ring) + sage: 5*B(([1, 2], [3, 4])) # optional - sage.modules ((5, 10), (15, 20)) """ return self.parent()._cartesian_product_of_elements( @@ -934,9 +953,9 @@ def construction(self): EXAMPLES:: - sage: A = algebras.Free(QQ,2) - sage: T = A.tensor(A) - sage: T.construction() + sage: A = algebras.Free(QQ, 2) # optional - sage.combinat sage.modules + sage: T = A.tensor(A) # optional - sage.combinat sage.modules + sage: T.construction() # optional - sage.combinat sage.modules (The tensor functorial construction, (Free Algebra on 2 generators (None0, None1) over Rational Field, Free Algebra on 2 generators (None0, None1) over Rational Field)) @@ -957,20 +976,20 @@ def tensor_factors(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, [1,2]) - sage: F.rename("F") - sage: G = CombinatorialFreeModule(ZZ, [3,4]) - sage: G.rename("G") - sage: T = tensor([F, G]); T + sage: F = CombinatorialFreeModule(ZZ, [1,2]) # optional - sage.modules + sage: F.rename("F") # optional - sage.modules + sage: G = CombinatorialFreeModule(ZZ, [3,4]) # optional - sage.modules + sage: G.rename("G") # optional - sage.modules + sage: T = tensor([F, G]); T # optional - sage.modules F # G - sage: T.tensor_factors() + sage: T.tensor_factors() # optional - sage.modules (F, G) TESTS:: - sage: M = CombinatorialFreeModule(ZZ, ((1, 1), (1, 2), (2, 1), (2, 2)), - ....: category=ModulesWithBasis(ZZ).FiniteDimensional().TensorProducts()) - sage: M.construction() + sage: Cat = ModulesWithBasis(ZZ).FiniteDimensional().TensorProducts() # optional - sage.modules + sage: M = CombinatorialFreeModule(ZZ, ((1, 1), (1, 2), (2, 1), (2, 2)), category=Cat) # optional - sage.modules + sage: M.construction() # optional - sage.modules doctest:warning... DeprecationWarning: implementations of Modules().TensorProducts() now must define the method tensor_factors See https://github.com/sagemath/sage/issues/34393 for details. diff --git a/src/sage/categories/modules_with_basis.py b/src/sage/categories/modules_with_basis.py index 99b57ff8c8e..9f31917cf22 100644 --- a/src/sage/categories/modules_with_basis.py +++ b/src/sage/categories/modules_with_basis.py @@ -66,22 +66,23 @@ class ModulesWithBasis(CategoryWithAxiom_over_base_ring): Let `X` and `Y` be two modules with basis. We can build `Hom(X,Y)`:: - sage: X = CombinatorialFreeModule(QQ, [1,2]); X.__custom_name = "X" - sage: Y = CombinatorialFreeModule(QQ, [3,4]); Y.__custom_name = "Y" - sage: H = Hom(X, Y); H - Set of Morphisms from X to Y in Category of finite dimensional vector spaces with basis over Rational Field + sage: X = CombinatorialFreeModule(QQ, [1,2]); X.__custom_name = "X" # optional - sage.modules + sage: Y = CombinatorialFreeModule(QQ, [3,4]); Y.__custom_name = "Y" # optional - sage.modules + sage: H = Hom(X, Y); H # optional - sage.modules + Set of Morphisms from X to Y + in Category of finite dimensional vector spaces with basis over Rational Field The simplest morphism is the zero map:: - sage: H.zero() # todo: move this test into module once we have an example + sage: H.zero() # todo: move this test into module once we have an example # optional - sage.modules Generic morphism: From: X To: Y which we can apply to elements of `X`:: - sage: x = X.monomial(1) + 3 * X.monomial(2) - sage: H.zero()(x) + sage: x = X.monomial(1) + 3 * X.monomial(2) # optional - sage.modules + sage: H.zero()(x) # optional - sage.modules 0 EXAMPLES: @@ -89,17 +90,17 @@ class ModulesWithBasis(CategoryWithAxiom_over_base_ring): We now construct a more interesting morphism by extending a function by linearity:: - sage: phi = H(on_basis = lambda i: Y.monomial(i+2)); phi + sage: phi = H(on_basis=lambda i: Y.monomial(i + 2)); phi # optional - sage.modules Generic morphism: From: X To: Y - sage: phi(x) + sage: phi(x) # optional - sage.modules B[3] + 3*B[4] We can retrieve the function acting on indices of the basis:: - sage: f = phi.on_basis() - sage: f(1), f(2) + sage: f = phi.on_basis() # optional - sage.modules + sage: f(1), f(2) # optional - sage.modules (B[3], B[4]) `Hom(X,Y)` has a natural module structure (except for the zero, @@ -108,14 +109,14 @@ class ModulesWithBasis(CategoryWithAxiom_over_base_ring): basis; but see :class:`FiniteDimensionalModulesWithBasis` and :class:`GradedModulesWithBasis`:: - sage: H in ModulesWithBasis(QQ), H in Modules(QQ) + sage: H in ModulesWithBasis(QQ), H in Modules(QQ) # optional - sage.modules (False, True) Some more playing around with categories and higher order homsets:: - sage: H.category() + sage: H.category() # optional - sage.modules Category of homsets of modules with basis over Rational Field - sage: Hom(H, H).category() + sage: Hom(H, H).category() # optional - sage.modules Category of endsets of homsets of modules with basis over Rational Field .. TODO:: ``End(X)`` is an algebra. @@ -128,10 +129,10 @@ class ModulesWithBasis(CategoryWithAxiom_over_base_ring): TESTS:: - sage: f = H.zero().on_basis() - sage: f(1) + sage: f = H.zero().on_basis() # optional - sage.modules + sage: f(1) # optional - sage.modules 0 - sage: f(2) + sage: f(2) # optional - sage.modules 0 sage: TestSuite(ModulesWithBasis(ZZ)).run() @@ -151,20 +152,20 @@ def _call_(self, x): ``x`` is returned unchanged if it is already in this category:: - sage: CZ(CombinatorialFreeModule(ZZ, ('a','b','c'))) + sage: CZ(CombinatorialFreeModule(ZZ, ('a', 'b', 'c'))) # optional - sage.modules Free module generated by {'a', 'b', 'c'} over Integer Ring - sage: CZ(ZZ^3) + sage: CZ(ZZ^3) # optional - sage.modules Ambient free module of rank 3 over the principal ideal domain Integer Ring If needed (and possible) the base ring is changed appropriately:: - sage: CQ(ZZ^3) # indirect doctest + sage: CQ(ZZ^3) # indirect doctest # optional - sage.modules Vector space of dimension 3 over Rational Field If ``x`` itself is not a module with basis, but there is a canonical one associated to it, the latter is returned:: - sage: CQ(AbelianVariety(Gamma0(37))) # indirect doctest + sage: CQ(AbelianVariety(Gamma0(37))) # indirect doctest # optional - sage.modules Vector space of dimension 4 over Rational Field """ try: @@ -209,14 +210,14 @@ def basis(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) - sage: F.basis() + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules + sage: F.basis() # optional - sage.modules Finite family {'a': B['a'], 'b': B['b'], 'c': B['c']} :: - sage: QS3 = SymmetricGroupAlgebra(QQ,3) - sage: list(QS3.basis()) + sage: QS3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.group sage.modules + sage: list(QS3.basis()) # optional - sage.group sage.modules [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] """ from sage.sets.family import Family @@ -297,14 +298,16 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, :: - sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") - sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename("Y") - sage: phi = X.module_morphism(lambda i: Y.monomial(i) + 2*Y.monomial(i+1), codomain = Y) - sage: x = X.basis(); y = Y.basis() - sage: phi(x[1] + x[3]) + sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") # optional - sage.modules + sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename("Y") # optional - sage.modules + sage: def f(i): + ....: return Y.monomial(i) + 2*Y.monomial(i+1) + sage: phi = X.module_morphism(f, codomain=Y) # optional - sage.modules + sage: x = X.basis(); y = Y.basis() # optional - sage.modules + sage: phi(x[1] + x[3]) # optional - sage.modules B[1] + 2*B[2] + B[3] + 2*B[4] - sage: phi + sage: phi # optional - sage.modules Generic morphism: From: X To: Y @@ -315,101 +318,105 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, ``CommutativeAdditiveMonoids()`` that contains both the domain and the codomain:: - sage: phi.category_for() - Category of finite dimensional vector spaces with basis over Rational Field + sage: phi.category_for() # optional - sage.modules + Category of finite dimensional vector spaces with basis + over Rational Field With the ``zero`` argument, one can define affine morphisms:: - sage: phi = X.module_morphism(lambda i: Y.monomial(i) + 2*Y.monomial(i+1), - ....: codomain = Y, zero = 10*y[1]) - sage: phi(x[1] + x[3]) + sage: def f(i): + ....: return Y.monomial(i) + 2*Y.monomial(i+1) + sage: phi = X.module_morphism(f, codomain=Y, zero=10*y[1]) # optional - sage.modules + sage: phi(x[1] + x[3]) # optional - sage.modules 11*B[1] + 2*B[2] + B[3] + 2*B[4] In this special case, the default category is ``Sets()``:: - sage: phi.category_for() + sage: phi.category_for() # optional - sage.modules Category of sets One can construct morphisms with the base ring as codomain:: - sage: X = CombinatorialFreeModule(ZZ,[1,-1]) - sage: phi = X.module_morphism( on_basis=lambda i: i, codomain=ZZ ) - sage: phi( 2 * X.monomial(1) + 3 * X.monomial(-1) ) + sage: X = CombinatorialFreeModule(ZZ, [1, -1]) # optional - sage.modules + sage: phi = X.module_morphism(on_basis=lambda i: i, codomain=ZZ) # optional - sage.modules + sage: phi(2 * X.monomial(1) + 3 * X.monomial(-1)) # optional - sage.modules -1 - sage: phi.category_for() + sage: phi.category_for() # optional - sage.modules Category of commutative additive semigroups - sage: phi.category_for() # todo: not implemented (ZZ is currently not in Modules(ZZ)) + sage: phi.category_for() # todo: not implemented (ZZ is currently not in Modules(ZZ)) # optional - sage.modules Category of modules over Integer Ring Or more generally any ring admitting a coercion map from the base ring:: - sage: phi = X.module_morphism(on_basis=lambda i: i, codomain=RR ) - sage: phi( 2 * X.monomial(1) + 3 * X.monomial(-1) ) + sage: phi = X.module_morphism(on_basis=lambda i: i, codomain=RR) # optional - sage.modules + sage: phi(2 * X.monomial(1) + 3 * X.monomial(-1)) # optional - sage.modules -1.00000000000000 - sage: phi.category_for() + sage: phi.category_for() # optional - sage.modules Category of commutative additive semigroups - sage: phi.category_for() # todo: not implemented (RR is currently not in Modules(ZZ)) + sage: phi.category_for() # todo: not implemented (RR is currently not in Modules(ZZ)) # optional - sage.modules Category of modules over Integer Ring - sage: phi = X.module_morphism(on_basis=lambda i: i, codomain=Zmod(4) ) - sage: phi( 2 * X.monomial(1) + 3 * X.monomial(-1) ) + sage: phi = X.module_morphism(on_basis=lambda i: i, codomain=Zmod(4)) # optional - sage.modules + sage: phi(2 * X.monomial(1) + 3 * X.monomial(-1)) # optional - sage.modules 3 - sage: phi = Y.module_morphism(on_basis=lambda i: i, codomain=Zmod(4) ) + sage: phi = Y.module_morphism(on_basis=lambda i: i, codomain=Zmod(4)) # optional - sage.modules Traceback (most recent call last): ... - ValueError: codomain(=Ring of integers modulo 4) should be a module over the base ring of the domain(=Y) + ValueError: codomain(=Ring of integers modulo 4) should be a module + over the base ring of the domain(=Y) On can also define module morphisms between free modules over different base rings; here we implement the natural map from `X = \RR^2` to `Y = \CC`:: - sage: X = CombinatorialFreeModule(RR,['x','y']) - sage: Y = CombinatorialFreeModule(CC,['z']) - sage: x = X.monomial('x') - sage: y = X.monomial('y') - sage: z = Y.monomial('z') - sage: def on_basis( a ): + sage: X = CombinatorialFreeModule(RR, ['x', 'y']) # optional - sage.modules + sage: Y = CombinatorialFreeModule(CC, ['z']) # optional - sage.modules + sage: x = X.monomial('x') # optional - sage.modules + sage: y = X.monomial('y') # optional - sage.modules + sage: z = Y.monomial('z') # optional - sage.modules + sage: def on_basis(a): # optional - sage.modules ....: if a == 'x': ....: return CC(1) * z ....: elif a == 'y': ....: return CC(I) * z - sage: phi = X.module_morphism( on_basis=on_basis, codomain=Y ) - sage: v = 3 * x + 2 * y; v + sage: phi = X.module_morphism(on_basis=on_basis, codomain=Y) # optional - sage.modules + sage: v = 3 * x + 2 * y; v # optional - sage.modules 3.00000000000000*B['x'] + 2.00000000000000*B['y'] - sage: phi(v) + sage: phi(v) # optional - sage.modules (3.00000000000000+2.00000000000000*I)*B['z'] - sage: phi.category_for() + sage: phi.category_for() # optional - sage.modules Category of commutative additive semigroups - sage: phi.category_for() # todo: not implemented (CC is currently not in Modules(RR)!) + sage: phi.category_for() # todo: not implemented (CC is currently not in Modules(RR)!) # optional - sage.modules Category of vector spaces over Real Field with 53 bits of precision - sage: Y = CombinatorialFreeModule(CC['q'],['z']) - sage: z = Y.monomial('z') - sage: phi = X.module_morphism( on_basis=on_basis, codomain=Y ) - sage: phi(v) + sage: Y = CombinatorialFreeModule(CC['q'], ['z']) # optional - sage.modules + sage: z = Y.monomial('z') # optional - sage.modules + sage: phi = X.module_morphism(on_basis=on_basis, codomain=Y) # optional - sage.modules + sage: phi(v) # optional - sage.modules (3.00000000000000+2.00000000000000*I)*B['z'] Of course, there should be a coercion between the respective base rings of the domain and the codomain for this to be meaningful:: - sage: Y = CombinatorialFreeModule(QQ,['z']) - sage: phi = X.module_morphism( on_basis=on_basis, codomain=Y ) + sage: Y = CombinatorialFreeModule(QQ, ['z']) # optional - sage.modules + sage: phi = X.module_morphism(on_basis=on_basis, codomain=Y) # optional - sage.modules Traceback (most recent call last): ... ValueError: codomain(=Free module generated by {'z'} over Rational Field) - should be a module over the base ring of the - domain(=Free module generated by {'x', 'y'} over Real Field with 53 bits of precision) + should be a module over the base ring of the domain(=Free module + generated by {'x', 'y'} over Real Field with 53 bits of precision) - sage: Y = CombinatorialFreeModule(RR['q'],['z']) - sage: phi = Y.module_morphism( on_basis=on_basis, codomain=X ) + sage: Y = CombinatorialFreeModule(RR['q'], ['z']) # optional - sage.modules + sage: phi = Y.module_morphism(on_basis=on_basis, codomain=X) # optional - sage.modules Traceback (most recent call last): ... - ValueError: codomain(=Free module generated by {'x', 'y'} over Real Field with 53 bits of precision) - should be a module over the base ring of the - domain(=Free module generated by {'z'} over Univariate Polynomial Ring in q over Real Field with 53 bits of precision) + ValueError: codomain(=Free module generated by {'x', 'y'} + over Real Field with 53 bits of precision) should be a module over + the base ring of the domain(=Free module generated by {'z'} over + Univariate Polynomial Ring in q over Real Field with 53 bits of precision) With the ``diagonal=d`` argument, this constructs the @@ -422,11 +429,11 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, This assumes that the respective bases `x` and `y` of `X` and `Y` have the same index set `I`:: - sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X") - sage: from sage.arith.misc import factorial - sage: phi = X.module_morphism(diagonal=factorial, codomain=X) - sage: x = X.basis() - sage: phi(x[1]), phi(x[2]), phi(x[3]) + sage: X = CombinatorialFreeModule(ZZ, [1, 2, 3]); X.rename("X") # optional - sage.modules + sage: from sage.arith.misc import factorial # optional - sage.modules + sage: phi = X.module_morphism(diagonal=factorial, codomain=X) # optional - sage.modules + sage: x = X.basis() # optional - sage.modules + sage: phi(x[1]), phi(x[2]), phi(x[3]) # optional - sage.modules (B[1], 2*B[2], 6*B[3]) See also: :class:`sage.modules.with_basis.morphism.DiagonalModuleMorphism`. @@ -435,13 +442,15 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, morphism whose matrix in the distinguished basis of `X` and `Y` is `m`:: - sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X"); x = X.basis() - sage: Y = CombinatorialFreeModule(ZZ, [3,4]); Y.rename("Y"); y = Y.basis() - sage: m = matrix([[0,1,2],[3,5,0]]) - sage: phi = X.module_morphism(matrix=m, codomain=Y) - sage: phi(x[1]) + sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X") # optional - sage.modules + sage: x = X.basis() # optional - sage.modules + sage: Y = CombinatorialFreeModule(ZZ, [3,4]); Y.rename("Y") # optional - sage.modules + sage: y = Y.basis() # optional - sage.modules + sage: m = matrix([[0,1,2], [3,5,0]]) # optional - sage.modules + sage: phi = X.module_morphism(matrix=m, codomain=Y) # optional - sage.modules + sage: phi(x[1]) # optional - sage.modules 3*B[4] - sage: phi(x[2]) + sage: phi(x[2]) # optional - sage.modules B[3] + 5*B[4] @@ -454,35 +463,36 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, preimages and to invert the morphism:: sage: I = list(range(1, 200)) - sage: X = CombinatorialFreeModule(QQ, I); X.rename("X"); x = X.basis() - sage: Y = CombinatorialFreeModule(QQ, I); Y.rename("Y"); y = Y.basis() - sage: f = Y.sum_of_monomials * divisors - sage: phi = X.module_morphism(f, triangular="upper", codomain = Y) - sage: phi(x[2]) + sage: X = CombinatorialFreeModule(QQ, I); X.rename("X"); x = X.basis() # optional - sage.modules + sage: Y = CombinatorialFreeModule(QQ, I); Y.rename("Y"); y = Y.basis() # optional - sage.modules + sage: f = Y.sum_of_monomials * divisors # optional - sage.modules + sage: phi = X.module_morphism(f, triangular="upper", codomain=Y) # optional - sage.modules + sage: phi(x[2]) # optional - sage.modules B[1] + B[2] - sage: phi(x[6]) + sage: phi(x[6]) # optional - sage.modules B[1] + B[2] + B[3] + B[6] - sage: phi(x[30]) + sage: phi(x[30]) # optional - sage.modules B[1] + B[2] + B[3] + B[5] + B[6] + B[10] + B[15] + B[30] - sage: phi.preimage(y[2]) + sage: phi.preimage(y[2]) # optional - sage.modules -B[1] + B[2] - sage: phi.preimage(y[6]) + sage: phi.preimage(y[6]) # optional - sage.modules B[1] - B[2] - B[3] + B[6] - sage: phi.preimage(y[30]) + sage: phi.preimage(y[30]) # optional - sage.modules -B[1] + B[2] + B[3] + B[5] - B[6] - B[10] - B[15] + B[30] - sage: (phi^-1)(y[30]) + sage: (phi^-1)(y[30]) # optional - sage.modules -B[1] + B[2] + B[3] + B[5] - B[6] - B[10] - B[15] + B[30] Since :trac:`8678`, one can also define a triangular morphism from a function:: - sage: X = CombinatorialFreeModule(QQ, [0,1,2,3,4]); x = X.basis() - sage: from sage.modules.with_basis.morphism import TriangularModuleMorphismFromFunction - sage: def f(x): return x + X.term(0, sum(x.coefficients())) - sage: phi = X.module_morphism(function=f, codomain=X, triangular="upper") - sage: phi(x[2] + 3*x[4]) + sage: X = CombinatorialFreeModule(QQ, [0,1,2,3,4]); x = X.basis() # optional - sage.modules + sage: from sage.modules.with_basis.morphism import TriangularModuleMorphismFromFunction # optional - sage.modules + sage: def f(x): return x + X.term(0, sum(x.coefficients())) # optional - sage.modules + sage: phi = X.module_morphism(function=f, codomain=X, # optional - sage.modules + ....: triangular="upper") + sage: phi(x[2] + 3*x[4]) # optional - sage.modules 4*B[0] + B[2] + 3*B[4] - sage: phi.preimage(_) + sage: phi.preimage(_) # optional - sage.modules B[2] + 3*B[4] For details and further optional arguments, see @@ -505,8 +515,8 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, TESTS:: - sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X") - sage: phi = X.module_morphism(codomain=X) + sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X") # optional - sage.modules + sage: phi = X.module_morphism(codomain=X) # optional - sage.modules Traceback (most recent call last): ... ValueError: module_morphism() takes exactly one option @@ -514,8 +524,9 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, :: - sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X") - sage: phi = X.module_morphism(diagonal=factorial, matrix=matrix(), codomain=X) + sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X") # optional - sage.modules + sage: phi = X.module_morphism(diagonal=factorial, matrix=matrix(), # optional - sage.modules + ....: codomain=X) Traceback (most recent call last): ... ValueError: module_morphism() takes exactly one option @@ -523,16 +534,16 @@ def module_morphism(self, on_basis=None, matrix=None, function=None, :: - sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X") - sage: phi = X.module_morphism(matrix=factorial, codomain=X) + sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X") # optional - sage.modules + sage: phi = X.module_morphism(matrix=factorial, codomain=X) # optional - sage.modules Traceback (most recent call last): ... ValueError: matrix (=...factorial...) should be a matrix :: - sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X") - sage: phi = X.module_morphism(diagonal=3, codomain=X) + sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename("X") # optional - sage.modules + sage: phi = X.module_morphism(diagonal=3, codomain=X) # optional - sage.modules Traceback (most recent call last): ... ValueError: diagonal (=3) should be a function @@ -571,20 +582,20 @@ def _repr_(self): """ EXAMPLES:: - sage: class FooBar(CombinatorialFreeModule): pass - sage: C = FooBar(QQ, (1,2,3)); C # indirect doctest + sage: class FooBar(CombinatorialFreeModule): pass # optional - sage.modules + sage: C = FooBar(QQ, (1,2,3)); C # indirect doctest # optional - sage.modules Free module generated by {1, 2, 3} over Rational Field - sage: C._name = "foobar"; C + sage: C._name = "foobar"; C # optional - sage.modules foobar over Rational Field - sage: C.rename("barfoo"); C + sage: C.rename("barfoo"); C # optional - sage.modules barfoo sage: class FooBar(Parent): - ....: def basis(self): return Family({1:"foo", 2:"bar"}) + ....: def basis(self): return Family({1: "foo", 2: "bar"}) ....: def base_ring(self): return QQ - sage: FooBar(category = ModulesWithBasis(QQ)) + sage: FooBar(category=ModulesWithBasis(QQ)) Free module generated by [1, 2] over Rational Field """ if hasattr(self, "_name"): @@ -608,26 +619,28 @@ def _compute_support_order(self, elements, support_order=None): A finite dimensional module:: - sage: V = CombinatorialFreeModule(QQ, range(10), prefix='x') - sage: B = V.basis() - sage: elts = [B[0] - 2*B[3], B[5] + 2*B[0], B[2], B[3], B[1] + B[2] + B[8]] - sage: V._compute_support_order(elts) + sage: V = CombinatorialFreeModule(QQ, range(10), prefix='x') # optional - sage.modules + sage: B = V.basis() # optional - sage.modules + sage: elts = [B[0] - 2*B[3], B[5] + 2*B[0], # optional - sage.modules + ....: B[2], B[3], B[1] + B[2] + B[8]] + sage: V._compute_support_order(elts) # optional - sage.modules (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) - sage: V._compute_support_order(elts, [1,2,0,4,3,5,9,8,7,6]) + sage: V._compute_support_order(elts, [1,2,0,4,3,5,9,8,7,6]) # optional - sage.modules (1, 2, 0, 4, 3, 5, 9, 8, 7, 6) - sage: V._compute_support_order(elts, lambda x: -x) + sage: V._compute_support_order(elts, lambda x: -x) # optional - sage.modules (8, 5, 3, 2, 1, 0) An infinite dimensional module:: - sage: V = CombinatorialFreeModule(QQ, ZZ, prefix='z') - sage: B = V.basis() - sage: elts = [B[0] - 2*B[3], B[5] + 2*B[0], B[2], B[3], B[1] + B[2] + B[8]] - sage: V._compute_support_order(elts) + sage: V = CombinatorialFreeModule(QQ, ZZ, prefix='z') # optional - sage.modules + sage: B = V.basis() # optional - sage.modules + sage: elts = [B[0] - 2*B[3], B[5] + 2*B[0], # optional - sage.modules + ....: B[2], B[3], B[1] + B[2] + B[8]] + sage: V._compute_support_order(elts) # optional - sage.modules (0, 1, 2, 3, 5, 8) - sage: V._compute_support_order(elts, [1,2,0,4,3,5,9,8,7,6]) + sage: V._compute_support_order(elts, [1,2,0,4,3,5,9,8,7,6]) # optional - sage.modules (1, 2, 0, 4, 3, 5, 9, 8, 7, 6) - sage: V._compute_support_order(elts, lambda x: -x) + sage: V._compute_support_order(elts, lambda x: -x) # optional - sage.modules (8, 5, 3, 2, 1, 0) """ if support_order is None: @@ -672,17 +685,17 @@ def echelon_form(self, elements, row_reduced=False, order=None): EXAMPLES:: sage: R. = QQ[] - sage: C = CombinatorialFreeModule(R, ZZ, prefix='z') - sage: z = C.basis() - sage: C.echelon_form([z[0] - z[1], 2*z[1] - 2*z[2], z[0] - z[2]]) + sage: C = CombinatorialFreeModule(R, ZZ, prefix='z') # optional - sage.modules + sage: z = C.basis() # optional - sage.modules + sage: C.echelon_form([z[0] - z[1], 2*z[1] - 2*z[2], z[0] - z[2]]) # optional - sage.modules [z[0] - z[2], z[1] - z[2]] TESTS: We convert the input elements to ``self``:: - sage: s = SymmetricFunctions(QQ).s() - sage: s.echelon_form([1, s[1] + 5]) + sage: s = SymmetricFunctions(QQ).s() # optional - sage.combinat sage.modules + sage: s.echelon_form([1, s[1] + 5]) # optional - sage.combinat sage.modules [s[], s[1]] """ # Make sure elements consists of elements of ``self`` @@ -751,21 +764,21 @@ def submodule(self, gens, check=True, already_echelonized=False, `x_0, x_1, x_2`. The submodule is spanned by `y_0 = x_0 - x_1` and `y_1 - x_1 - x_2`, and its basis elements are indexed by `0` and `1`:: - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x") - sage: x = X.basis() - sage: gens = [x[0] - x[1], x[1] - x[2]]; gens + sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x") # optional - sage.modules + sage: x = X.basis() # optional - sage.modules + sage: gens = [x[0] - x[1], x[1] - x[2]]; gens # optional - sage.modules [x[0] - x[1], x[1] - x[2]] - sage: Y = X.submodule(gens, already_echelonized=True) - sage: Y.print_options(prefix='y'); Y + sage: Y = X.submodule(gens, already_echelonized=True) # optional - sage.modules + sage: Y.print_options(prefix='y'); Y # optional - sage.modules Free module generated by {0, 1} over Rational Field - sage: y = Y.basis() - sage: y[1] + sage: y = Y.basis() # optional - sage.modules + sage: y[1] # optional - sage.modules y[1] - sage: y[1].lift() + sage: y[1].lift() # optional - sage.modules x[1] - x[2] - sage: Y.retract(x[0]-x[2]) + sage: Y.retract(x[0] - x[2]) # optional - sage.modules y[0] + y[1] - sage: Y.retract(x[0]) + sage: Y.retract(x[0]) # optional - sage.modules Traceback (most recent call last): ... ValueError: x[0] is not in the image @@ -773,23 +786,23 @@ def submodule(self, gens, check=True, already_echelonized=False, By using a family to specify a basis of the submodule, we obtain a submodule whose index set coincides with the index set of the family:: - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x") - sage: x = X.basis() - sage: gens = Family({1 : x[0] - x[1], 3: x[1] - x[2]}); gens + sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x") # optional - sage.modules + sage: x = X.basis() # optional - sage.modules + sage: gens = Family({1: x[0] - x[1], 3: x[1] - x[2]}); gens # optional - sage.modules Finite family {1: x[0] - x[1], 3: x[1] - x[2]} - sage: Y = X.submodule(gens, already_echelonized=True) - sage: Y.print_options(prefix='y'); Y + sage: Y = X.submodule(gens, already_echelonized=True) # optional - sage.modules + sage: Y.print_options(prefix='y'); Y # optional - sage.modules Free module generated by {1, 3} over Rational Field - sage: y = Y.basis() - sage: y[1] + sage: y = Y.basis() # optional - sage.modules + sage: y[1] # optional - sage.modules y[1] - sage: y[1].lift() + sage: y[1].lift() # optional - sage.modules x[0] - x[1] - sage: y[3].lift() + sage: y[3].lift() # optional - sage.modules x[1] - x[2] - sage: Y.retract(x[0]-x[2]) + sage: Y.retract(x[0] - x[2]) # optional - sage.modules y[1] + y[3] - sage: Y.retract(x[0]) + sage: Y.retract(x[0]) # optional - sage.modules Traceback (most recent call last): ... ValueError: x[0] is not in the image @@ -797,55 +810,56 @@ def submodule(self, gens, check=True, already_echelonized=False, It is not necessary that the generators of the submodule form a basis (an explicit basis will be computed):: - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x") - sage: x = X.basis() - sage: gens = [x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]]; gens + sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x") # optional - sage.modules + sage: x = X.basis() # optional - sage.modules + sage: gens = [x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]]; gens # optional - sage.modules [x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]] - sage: Y = X.submodule(gens, already_echelonized=False) - sage: Y.print_options(prefix='y') - sage: Y + sage: Y = X.submodule(gens, already_echelonized=False) # optional - sage.modules + sage: Y.print_options(prefix='y') # optional - sage.modules + sage: Y # optional - sage.modules Free module generated by {0, 1} over Rational Field - sage: [b.lift() for b in Y.basis()] + sage: [b.lift() for b in Y.basis()] # optional - sage.modules [x[0] - x[2], x[1] - x[2]] We now implement by hand the center of the algebra of the symmetric group `S_3`:: - sage: S3 = SymmetricGroup(3) - sage: S3A = S3.algebra(QQ) - sage: basis = S3A.annihilator_basis(S3A.algebra_generators(), S3A.bracket) - sage: basis + sage: S3 = SymmetricGroup(3) # optional - sage.groups sage.modules + sage: S3A = S3.algebra(QQ) # optional - sage.groups sage.modules + sage: basis = S3A.annihilator_basis(S3A.algebra_generators(), # optional - sage.groups sage.modules + ....: S3A.bracket) + sage: basis # optional - sage.groups sage.modules ((), (1,2,3) + (1,3,2), (2,3) + (1,2) + (1,3)) - sage: center = S3A.submodule(basis, - ....: category=AlgebrasWithBasis(QQ).Subobjects(), - ....: already_echelonized=True) - sage: center + sage: center = S3A.submodule(basis, # optional - sage.groups sage.modules + ....: category=AlgebrasWithBasis(QQ).Subobjects(), + ....: already_echelonized=True) + sage: center # optional - sage.groups sage.modules Free module generated by {0, 1, 2} over Rational Field - sage: center in Algebras + sage: center in Algebras # optional - sage.groups sage.modules True - sage: center.print_options(prefix='c') - sage: c = center.basis() - sage: c[1].lift() + sage: center.print_options(prefix='c') # optional - sage.groups sage.modules + sage: c = center.basis() # optional - sage.groups sage.modules + sage: c[1].lift() # optional - sage.groups sage.modules (1,2,3) + (1,3,2) - sage: c[0]^2 + sage: c[0]^2 # optional - sage.groups sage.modules c[0] - sage: e = 1/6*(c[0]+c[1]+c[2]) - sage: e.is_idempotent() + sage: e = 1/6 * (c[0]+c[1]+c[2]) # optional - sage.groups sage.modules + sage: e.is_idempotent() # optional - sage.groups sage.modules True Of course, this center is best constructed using:: - sage: center = S3A.center() + sage: center = S3A.center() # optional - sage.groups sage.modules We can also automatically construct a basis such that the lift morphism is (lower) unitriangular:: sage: R. = QQ[] - sage: C = CombinatorialFreeModule(R, range(3), prefix='x') - sage: x = C.basis() - sage: gens = [x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]] - sage: Y = C.submodule(gens, unitriangular=True) - sage: Y.lift.matrix() + sage: C = CombinatorialFreeModule(R, range(3), prefix='x') # optional - sage.modules + sage: x = C.basis() # optional - sage.modules + sage: gens = [x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]] # optional - sage.modules + sage: Y = C.submodule(gens, unitriangular=True) # optional - sage.modules + sage: Y.lift.matrix() # optional - sage.modules [ 1 0] [ 0 1] [-1 -1] @@ -853,17 +867,17 @@ def submodule(self, gens, check=True, already_echelonized=False, We now construct a (finite-dimensional) submodule of an infinite dimensional free module:: - sage: C = CombinatorialFreeModule(QQ, ZZ, prefix='z') - sage: z = C.basis() - sage: gens = [z[0] - z[1], 2*z[1] - 2*z[2], z[0] - z[2]] - sage: Y = C.submodule(gens) - sage: [Y.lift(b) for b in Y.basis()] + sage: C = CombinatorialFreeModule(QQ, ZZ, prefix='z') # optional - sage.modules + sage: z = C.basis() # optional - sage.modules + sage: gens = [z[0] - z[1], 2*z[1] - 2*z[2], z[0] - z[2]] # optional - sage.modules + sage: Y = C.submodule(gens) # optional - sage.modules + sage: [Y.lift(b) for b in Y.basis()] # optional - sage.modules [z[0] - z[2], z[1] - z[2]] TESTS:: - sage: TestSuite(Y).run() - sage: TestSuite(center).run() + sage: TestSuite(Y).run() # optional - sage.modules + sage: TestSuite(center).run() # optional - sage.groups sage.modules """ # Make sure gens consists of elements of ``self`` from sage.sets.family import Family, AbstractFamily @@ -906,24 +920,25 @@ def quotient_module(self, submodule, check=True, already_echelonized=False, cate EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x") - sage: x = X.basis() - sage: Y = X.quotient_module([x[0]-x[1], x[1]-x[2]], already_echelonized=True) - sage: Y.print_options(prefix='y'); Y + sage: X = CombinatorialFreeModule(QQ, range(3), prefix="x") # optional - sage.modules + sage: x = X.basis() # optional - sage.modules + sage: Y = X.quotient_module([x[0] - x[1], x[1] - x[2]], # optional - sage.modules + ....: already_echelonized=True) + sage: Y.print_options(prefix='y'); Y # optional - sage.modules Free module generated by {2} over Rational Field - sage: y = Y.basis() - sage: y[2] + sage: y = Y.basis() # optional - sage.modules + sage: y[2] # optional - sage.modules y[2] - sage: y[2].lift() + sage: y[2].lift() # optional - sage.modules x[2] - sage: Y.retract(x[0]+2*x[1]) + sage: Y.retract(x[0] + 2*x[1]) # optional - sage.modules 3*y[2] sage: R. = QQ[] - sage: C = CombinatorialFreeModule(R, range(3), prefix='x') - sage: x = C.basis() - sage: gens = [x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]] - sage: Y = C.quotient_module(gens) + sage: C = CombinatorialFreeModule(R, range(3), prefix='x') # optional - sage.modules + sage: x = C.basis() # optional - sage.modules + sage: gens = [x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]] # optional - sage.modules + sage: Y = C.quotient_module(gens) # optional - sage.modules .. SEEALSO:: @@ -945,10 +960,10 @@ def tensor(*parents, **kwargs): EXAMPLES:: sage: C = AlgebrasWithBasis(QQ) - sage: A = C.example(); A.rename("A") - sage: A.tensor(A,A) + sage: A = C.example(); A.rename("A") # optional - sage.combinat sage.modules + sage: A.tensor(A, A) # optional - sage.combinat sage.modules A # A # A - sage: A.rename(None) + sage: A.rename(None) # optional - sage.combinat sage.modules """ constructor = kwargs.pop('constructor', tensor) cat = constructor.category_from_parents(parents) @@ -960,24 +975,24 @@ def cardinality(self): EXAMPLES:: - sage: S = SymmetricGroupAlgebra(QQ, 4) - sage: S.cardinality() + sage: S = SymmetricGroupAlgebra(QQ, 4) # optional - sage.groups sage.modules + sage: S.cardinality() # optional - sage.groups sage.modules +Infinity - sage: S = SymmetricGroupAlgebra(GF(2), 4) # not tested -- MRO bug trac #15475 - sage: S.cardinality() # not tested -- MRO bug trac #15475 + sage: S = SymmetricGroupAlgebra(GF(2), 4) # not tested -- MRO bug trac #15475 # optional - sage.groups sage.rings.finite_rings sage.modules + sage: S.cardinality() # not tested -- MRO bug trac #15475 # optional - sage.groups sage.rings.finite_rings sage.modules 16777216 - sage: S.cardinality().factor() # not tested -- MRO bug trac #15475 + sage: S.cardinality().factor() # not tested -- MRO bug trac #15475 # optional - sage.groups sage.rings.finite_rings sage.modules 2^24 - sage: E. = ExteriorAlgebra(QQ) - sage: E.cardinality() + sage: E. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: E.cardinality() # optional - sage.combinat sage.modules +Infinity - sage: E. = ExteriorAlgebra(GF(3)) - sage: E.cardinality() + sage: E. = ExteriorAlgebra(GF(3)) # optional - sage.combinat sage.rings.finite_rings sage.modules + sage: E.cardinality() # optional - sage.combinat sage.rings.finite_rings sage.modules 81 - sage: s = SymmetricFunctions(GF(2)).s() - sage: s.cardinality() + sage: s = SymmetricFunctions(GF(2)).s() # optional - sage.combinat sage.rings.finite_rings sage.modules + sage: s.cardinality() # optional - sage.combinat sage.rings.finite_rings sage.modules +Infinity """ from sage.rings.infinity import Infinity @@ -994,11 +1009,11 @@ def is_finite(self): EXAMPLES:: - sage: GroupAlgebra(SymmetricGroup(2), IntegerModRing(10)).is_finite() + sage: GroupAlgebra(SymmetricGroup(2), IntegerModRing(10)).is_finite() # optional - sage.groups sage.modules True - sage: GroupAlgebra(SymmetricGroup(2)).is_finite() + sage: GroupAlgebra(SymmetricGroup(2)).is_finite() # optional - sage.groups sage.modules False - sage: GroupAlgebra(AbelianGroup(1), IntegerModRing(10)).is_finite() + sage: GroupAlgebra(AbelianGroup(1), IntegerModRing(10)).is_finite() # optional - sage.groups sage.modules False """ return (self.base_ring().is_finite() and self.group().is_finite()) @@ -1013,14 +1028,15 @@ def monomial(self, i): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) - sage: F.monomial('a') + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules + sage: F.monomial('a') # optional - sage.modules B['a'] ``F.monomial`` is in fact (almost) a map:: - sage: F.monomial - Term map from {'a', 'b', 'c'} to Free module generated by {'a', 'b', 'c'} over Rational Field + sage: F.monomial # optional - sage.modules + Term map from {'a', 'b', 'c'} + to Free module generated by {'a', 'b', 'c'} over Rational Field """ return self.basis()[i] @@ -1029,8 +1045,8 @@ def _sum_of_monomials(self, indices): TESTS:: sage: R. = QQ[] - sage: W = DifferentialWeylAlgebra(R) - sage: W._sum_of_monomials([((1,0), (1,0)), ((0,0), (0,1))]) + sage: W = DifferentialWeylAlgebra(R) # optional - sage.combinat sage.modules + sage: W._sum_of_monomials([((1,0), (1,0)), ((0,0), (0,1))]) # optional - sage.combinat sage.modules dy + x*dx """ # This is the generic implementation. When implementing a @@ -1051,16 +1067,16 @@ def sum_of_monomials(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) - sage: F.sum_of_monomials(['a', 'b']) + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules + sage: F.sum_of_monomials(['a', 'b']) # optional - sage.modules B['a'] + B['b'] - sage: F.sum_of_monomials(['a', 'b', 'a']) + sage: F.sum_of_monomials(['a', 'b', 'a']) # optional - sage.modules 2*B['a'] + B['b'] ``F.sum_of_monomials`` is in fact (almost) a map:: - sage: F.sum_of_monomials + sage: F.sum_of_monomials # optional - sage.modules A map to Free module generated by {'a', 'b', 'c'} over Rational Field """ # domain = iterables of basis indices of self. @@ -1070,10 +1086,10 @@ def monomial_or_zero_if_none(self, i): """ EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) - sage: F.monomial_or_zero_if_none('a') + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules + sage: F.monomial_or_zero_if_none('a') # optional - sage.modules B['a'] - sage: F.monomial_or_zero_if_none(None) + sage: F.monomial_or_zero_if_none(None) # optional - sage.modules 0 """ if i is None: @@ -1095,9 +1111,9 @@ def term(self, index, coeff=None): EXAMPLES:: - sage: m = matrix([[0,1],[1,1]]) - sage: J. = JordanAlgebra(m) - sage: J.term(1, -2) + sage: m = matrix([[0,1], [1,1]]) # optional - sage.modules + sage: J. = JordanAlgebra(m) # optional - sage.combinat sage.modules + sage: J.term(1, -2) # optional - sage.combinat sage.modules 0 + (-2, 0) Design: should this do coercion on the coefficient ring? @@ -1121,9 +1137,9 @@ def sum_of_terms(self, terms): EXAMPLES:: - sage: m = matrix([[0,1],[1,1]]) - sage: J. = JordanAlgebra(m) - sage: J.sum_of_terms([(0, 2), (2, -3)]) + sage: m = matrix([[0,1], [1,1]]) # optional - sage.modules + sage: J. = JordanAlgebra(m) # optional - sage.combinat sage.modules + sage: J.sum_of_terms([(0, 2), (2, -3)]) # optional - sage.combinat sage.modules 2 + (0, -3) """ return self.sum(self.term(index, coeff) for (index, coeff) in terms) @@ -1150,21 +1166,21 @@ def _apply_module_morphism(self, x, on_basis, codomain=False): EXAMPLES:: - sage: s = SymmetricFunctions(QQ).schur() - sage: a = s([3]) + s([2,1]) + s([1,1,1]) - sage: b = 2*a - sage: f = lambda part: Integer( len(part) ) - sage: s._apply_module_morphism(a, f) #1+2+3 + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: a = s([3]) + s([2,1]) + s([1,1,1]) # optional - sage.combinat sage.modules + sage: b = 2*a # optional - sage.combinat sage.modules + sage: f = lambda part: Integer(len(part)) # optional - sage.combinat sage.modules + sage: s._apply_module_morphism(a, f) #1+2+3 # optional - sage.combinat sage.modules 6 - sage: s._apply_module_morphism(b, f) #2*(1+2+3) + sage: s._apply_module_morphism(b, f) #2*(1+2+3) # optional - sage.combinat sage.modules 12 - sage: s._apply_module_morphism(s(0), f) + sage: s._apply_module_morphism(s(0), f) # optional - sage.combinat sage.modules 0 - sage: s._apply_module_morphism(s(1), f) + sage: s._apply_module_morphism(s(1), f) # optional - sage.combinat sage.modules 0 - sage: s._apply_module_morphism(s(1), lambda part: len(part), ZZ) + sage: s._apply_module_morphism(s(1), lambda part: len(part), ZZ) # optional - sage.combinat sage.modules 0 - sage: s._apply_module_morphism(s(1), lambda part: len(part)) + sage: s._apply_module_morphism(s(1), lambda part: len(part)) # optional - sage.combinat sage.modules Traceback (most recent call last): ... ValueError: codomain could not be determined @@ -1206,9 +1222,9 @@ def _apply_module_endomorphism(self, x, on_basis): EXAMPLES:: - sage: s = SymmetricFunctions(QQ).schur() - sage: f = lambda part: 2*s(part.conjugate()) - sage: s._apply_module_endomorphism( s([2,1]) + s([1,1,1]), f) + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: f = lambda part: 2 * s(part.conjugate()) # optional - sage.combinat sage.modules + sage: s._apply_module_endomorphism(s([2,1]) + s([1,1,1]), f) # optional - sage.combinat sage.modules 2*s[2, 1] + 2*s[3] """ mc = x.monomial_coefficients(copy=False) @@ -1221,8 +1237,8 @@ def dimension(self): EXAMPLES:: - sage: A. = algebras.DifferentialWeyl(QQ) - sage: A.dimension() + sage: A. = algebras.DifferentialWeyl(QQ) # optional - sage.combinat sage.modules + sage: A.dimension() # optional - sage.combinat sage.modules +Infinity """ try: @@ -1242,17 +1258,17 @@ def _from_dict(self, d, coerce=True, remove_zeros=True): EXAMPLES:: - sage: A. = algebras.DifferentialWeyl(QQ) - sage: K = A.basis().keys() - sage: d = {K[0]: 3, K[12]: -4/3} - sage: A._from_dict(d) + sage: A. = algebras.DifferentialWeyl(QQ) # optional - sage.combinat sage.modules + sage: K = A.basis().keys() # optional - sage.combinat sage.modules + sage: d = {K[0]: 3, K[12]: -4/3} # optional - sage.combinat sage.modules + sage: A._from_dict(d) # optional - sage.combinat sage.modules -4/3*dx^2 + 3 sage: R. = QQ[] - sage: d = {K[0]: y, K[12]: -4/3} - sage: A._from_dict(d, coerce=False) + sage: d = {K[0]: y, K[12]: -4/3} # optional - sage.combinat sage.modules + sage: A._from_dict(d, coerce=False) # optional - sage.combinat sage.modules -4/3*dx^2 + y - sage: A._from_dict(d, coerce=True) + sage: A._from_dict(d, coerce=True) # optional - sage.combinat sage.modules Traceback (most recent call last): ... TypeError: not a constant polynomial @@ -1291,21 +1307,21 @@ def random_element(self, n=2): EXAMPLES:: - sage: x = DihedralGroup(6).algebra(QQ).random_element() - sage: x.parent() is DihedralGroup(6).algebra(QQ) + sage: x = DihedralGroup(6).algebra(QQ).random_element() # optional - sage.groups sage.modules + sage: x.parent() is DihedralGroup(6).algebra(QQ) # optional - sage.groups sage.modules True Note, this result can depend on the PRNG state in libgap in a way that depends on which packages are loaded, so we must re-seed GAP to ensure a consistent result for this example:: - sage: libgap.set_seed(0) + sage: libgap.set_seed(0) # optional - sage.libs.gap 0 - sage: m = SU(2, 13).algebra(QQ).random_element(1) - sage: m.parent() is SU(2, 13).algebra(QQ) + sage: m = SU(2, 13).algebra(QQ).random_element(1) # optional - sage.groups sage.modules + sage: m.parent() is SU(2, 13).algebra(QQ) # optional - sage.groups sage.modules True - sage: p = CombinatorialFreeModule(ZZ, Partitions(4)).random_element() - sage: p.parent() is CombinatorialFreeModule(ZZ, Partitions(4)) + sage: p = CombinatorialFreeModule(ZZ, Partitions(4)).random_element() # optional - sage.combinat sage.modules + sage: p.parent() is CombinatorialFreeModule(ZZ, Partitions(4)) # optional - sage.combinat sage.modules True TESTS: @@ -1315,17 +1331,16 @@ def random_element(self, n=2): coerce the base ring's zero into the algebra, and that we can find a random element in a trivial module:: - sage: class Foo(CombinatorialFreeModule): + sage: class Foo(CombinatorialFreeModule): # optional - sage.modules ....: def _element_constructor_(self,x): ....: if x in self: ....: return x ....: else: ....: raise ValueError - sage: from sage.categories.magmatic_algebras \ - ....: import MagmaticAlgebras + sage: from sage.categories.magmatic_algebras import MagmaticAlgebras sage: C = MagmaticAlgebras(QQ).WithBasis().Unital() - sage: F = Foo(QQ, tuple(), category=C) - sage: F.random_element() == F.zero() + sage: F = Foo(QQ, tuple(), category=C) # optional - sage.modules + sage: F.random_element() == F.zero() # optional - sage.modules True """ @@ -1365,25 +1380,25 @@ def monomial_coefficients(self, copy=True): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) - sage: B = F.basis() - sage: f = B['a'] + 3*B['c'] - sage: d = f.monomial_coefficients() - sage: d['a'] + sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) # optional - sage.modules + sage: B = F.basis() # optional - sage.modules + sage: f = B['a'] + 3*B['c'] # optional - sage.modules + sage: d = f.monomial_coefficients() # optional - sage.modules + sage: d['a'] # optional - sage.modules 1 - sage: d['c'] + sage: d['c'] # optional - sage.modules 3 TESTS: We check that we make a copy of the coefficient dictionary:: - sage: F = CombinatorialFreeModule(ZZ, ['a','b','c']) - sage: B = F.basis() - sage: f = B['a'] + 3*B['c'] - sage: d = f.monomial_coefficients() - sage: d['a'] = 5 - sage: f + sage: F = CombinatorialFreeModule(ZZ, ['a','b','c']) # optional - sage.modules + sage: B = F.basis() # optional - sage.modules + sage: f = B['a'] + 3*B['c'] # optional - sage.modules + sage: d = f.monomial_coefficients() # optional - sage.modules + sage: d['a'] = 5 # optional - sage.modules + sage: f # optional - sage.modules B['a'] + 3*B['c'] """ @@ -1393,10 +1408,10 @@ def __getitem__(self, m): EXAMPLES:: - sage: W. = DifferentialWeylAlgebra(QQ) - sage: x[((0,0,0),(0,0,0))] + sage: W. = DifferentialWeylAlgebra(QQ) # optional - sage.combinat sage.modules + sage: x[((0,0,0), (0,0,0))] # optional - sage.combinat sage.modules 0 - sage: x[((1,0,0),(0,0,0))] + sage: x[((1,0,0), (0,0,0))] # optional - sage.combinat sage.modules 1 """ res = self.monomial_coefficients(copy=False).get(m) @@ -1422,19 +1437,19 @@ def coefficient(self, m): EXAMPLES:: - sage: s = CombinatorialFreeModule(QQ, Partitions()) - sage: z = s([4]) - 2*s([2,1]) + s([1,1,1]) + s([1]) - sage: z.coefficient([4]) + sage: s = CombinatorialFreeModule(QQ, Partitions()) # optional - sage.combinat sage.modules + sage: z = s([4]) - 2*s([2,1]) + s([1,1,1]) + s([1]) # optional - sage.combinat sage.modules + sage: z.coefficient([4]) # optional - sage.combinat sage.modules 1 - sage: z.coefficient([2,1]) + sage: z.coefficient([2,1]) # optional - sage.combinat sage.modules -2 - sage: z.coefficient(Partition([2,1])) + sage: z.coefficient(Partition([2,1])) # optional - sage.combinat sage.modules -2 - sage: z.coefficient([1,2]) + sage: z.coefficient([1,2]) # optional - sage.combinat sage.modules Traceback (most recent call last): ... AssertionError: [1, 2] should be an element of Partitions - sage: z.coefficient(Composition([2,1])) + sage: z.coefficient(Composition([2,1])) # optional - sage.combinat sage.modules Traceback (most recent call last): ... AssertionError: [2, 1] should be an element of Partitions @@ -1442,12 +1457,12 @@ def coefficient(self, m): Test that ``coefficient`` also works for those parents that do not have an ``element_class``:: - sage: H = pAdicWeightSpace(3) - sage: F = CombinatorialFreeModule(QQ, H) - sage: hasattr(H, "element_class") + sage: H = pAdicWeightSpace(3) # optional - sage.modules sage.rings.padics + sage: F = CombinatorialFreeModule(QQ, H) # optional - sage.modules sage.rings.padics + sage: hasattr(H, "element_class") # optional - sage.modules sage.rings.padics False - sage: h = H.an_element() - sage: (2*F.monomial(h)).coefficient(h) + sage: h = H.an_element() # optional - sage.modules sage.rings.padics + sage: (2*F.monomial(h)).coefficient(h) # optional - sage.modules sage.rings.padics 2 """ # NT: coefficient_fast should be the default, just with appropriate assertions @@ -1465,22 +1480,22 @@ def is_zero(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) - sage: B = F.basis() - sage: f = B['a'] - 3*B['c'] - sage: f.is_zero() + sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) # optional - sage.modules + sage: B = F.basis() # optional - sage.modules + sage: f = B['a'] - 3*B['c'] # optional - sage.modules + sage: f.is_zero() # optional - sage.modules False - sage: F.zero().is_zero() + sage: F.zero().is_zero() # optional - sage.modules True :: - sage: s = SymmetricFunctions(QQ).schur() - sage: s([2,1]).is_zero() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: s([2,1]).is_zero() # optional - sage.combinat sage.modules False - sage: s(0).is_zero() + sage: s(0).is_zero() # optional - sage.combinat sage.modules True - sage: (s([2,1]) - s([2,1])).is_zero() + sage: (s([2,1]) - s([2,1])).is_zero() # optional - sage.combinat sage.modules True """ zero = self.parent().base_ring().zero() @@ -1493,17 +1508,17 @@ def __len__(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) - sage: B = F.basis() - sage: f = B['a'] - 3*B['c'] - sage: len(f) + sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) # optional - sage.modules + sage: B = F.basis() # optional - sage.modules + sage: f = B['a'] - 3*B['c'] # optional - sage.modules + sage: len(f) # optional - sage.modules 2 :: - sage: s = SymmetricFunctions(QQ).schur() - sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) - sage: len(z) + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) # optional - sage.combinat sage.modules + sage: len(z) # optional - sage.combinat sage.modules 4 """ return len(self.support()) @@ -1515,17 +1530,17 @@ def length(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) - sage: B = F.basis() - sage: f = B['a'] - 3*B['c'] - sage: f.length() + sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) # optional - sage.modules + sage: B = F.basis() # optional - sage.modules + sage: f = B['a'] - 3*B['c'] # optional - sage.modules + sage: f.length() # optional - sage.modules 2 :: - sage: s = SymmetricFunctions(QQ).schur() - sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) - sage: z.length() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) # optional - sage.combinat sage.modules + sage: z.length() # optional - sage.combinat sage.modules 4 """ return len(self) @@ -1540,17 +1555,17 @@ def support(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) - sage: B = F.basis() - sage: f = B['a'] - 3*B['c'] - sage: sorted(f.support()) + sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) # optional - sage.modules + sage: B = F.basis() # optional - sage.modules + sage: f = B['a'] - 3*B['c'] # optional - sage.modules + sage: sorted(f.support()) # optional - sage.modules ['a', 'c'] :: - sage: s = SymmetricFunctions(QQ).schur() - sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) - sage: sorted(z.support()) + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) # optional - sage.combinat sage.modules + sage: sorted(z.support()) # optional - sage.combinat sage.modules [[1], [1, 1, 1], [2, 1], [4]] """ try: @@ -1578,13 +1593,13 @@ def monomials(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) - sage: B = F.basis() - sage: f = B['a'] + 2*B['c'] - sage: f.monomials() + sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) # optional - sage.modules + sage: B = F.basis() # optional - sage.modules + sage: f = B['a'] + 2*B['c'] # optional - sage.modules + sage: f.monomials() # optional - sage.modules [B['a'], B['c']] - sage: (F.zero()).monomials() + sage: (F.zero()).monomials() # optional - sage.modules [] """ P = self.parent() @@ -1599,10 +1614,10 @@ def terms(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) - sage: B = F.basis() - sage: f = B['a'] + 2*B['c'] - sage: f.terms() + sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) # optional - sage.modules + sage: B = F.basis() # optional - sage.modules + sage: f = B['a'] + 2*B['c'] # optional - sage.modules + sage: f.terms() # optional - sage.modules [B['a'], 2*B['c']] """ P = self.parent() @@ -1627,20 +1642,20 @@ def coefficients(self, sort=True): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) - sage: B = F.basis() - sage: f = B['a'] - 3*B['c'] - sage: f.coefficients() + sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) # optional - sage.modules + sage: B = F.basis() # optional - sage.modules + sage: f = B['a'] - 3*B['c'] # optional - sage.modules + sage: f.coefficients() # optional - sage.modules [1, -3] - sage: f = B['c'] - 3*B['a'] - sage: f.coefficients() + sage: f = B['c'] - 3*B['a'] # optional - sage.modules + sage: f.coefficients() # optional - sage.modules [-3, 1] :: - sage: s = SymmetricFunctions(QQ).schur() - sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) - sage: z.coefficients() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) # optional - sage.combinat sage.modules + sage: z.coefficients() # optional - sage.combinat sage.modules [1, 1, 1, 1] """ zero = self.parent().base_ring().zero() @@ -1659,15 +1674,15 @@ def support_of_term(self): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1,2,3,4]); X.rename("X") - sage: X.monomial(2).support_of_term() + sage: X = CombinatorialFreeModule(QQ, [1,2,3,4]); X.rename("X") # optional - sage.modules + sage: X.monomial(2).support_of_term() # optional - sage.modules 2 - sage: X.term(3, 2).support_of_term() + sage: X.term(3, 2).support_of_term() # optional - sage.modules 3 An exception is raised if ``self`` has more than one term:: - sage: (X.monomial(2) + X.monomial(3)).support_of_term() + sage: (X.monomial(2) + X.monomial(3)).support_of_term() # optional - sage.modules Traceback (most recent call last): ... ValueError: B[2] + B[3] is not a single term @@ -1689,18 +1704,18 @@ def leading_support(self, *args, **kwds): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]) - sage: X.rename("X"); x = X.basis() - sage: x = 3*X.monomial(1) + 2*X.monomial(2) + 4*X.monomial(3) - sage: x.leading_support() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]) # optional - sage.modules + sage: X.rename("X"); x = X.basis() # optional - sage.modules + sage: x = 3*X.monomial(1) + 2*X.monomial(2) + 4*X.monomial(3) # optional - sage.modules + sage: x.leading_support() # optional - sage.modules 3 - sage: def key(x): return -x - sage: x.leading_support(key=key) + sage: def key(x): return -x # optional - sage.modules + sage: x.leading_support(key=key) # optional - sage.modules 1 - sage: s = SymmetricFunctions(QQ).schur() - sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] - sage: f.leading_support() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # optional - sage.combinat sage.modules + sage: f.leading_support() # optional - sage.combinat sage.modules [3] """ return max(self.support(), *args, **kwds) @@ -1724,17 +1739,17 @@ def leading_item(self, *args, **kwds): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() - sage: x = 3*X.monomial(1) + 2*X.monomial(2) + 4*X.monomial(3) - sage: x.leading_item() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") # optional - sage.modules + sage: x = 3*X.monomial(1) + 2*X.monomial(2) + 4*X.monomial(3) # optional - sage.modules + sage: x.leading_item() # optional - sage.modules (3, 4) - sage: def key(x): return -x - sage: x.leading_item(key=key) + sage: def key(x): return -x # optional - sage.modules + sage: x.leading_item(key=key) # optional - sage.modules (1, 3) - sage: s = SymmetricFunctions(QQ).schur() - sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] - sage: f.leading_item() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # optional - sage.combinat sage.modules + sage: f.leading_item() # optional - sage.combinat sage.modules ([3], -5) """ k = self.leading_support(*args, **kwds) @@ -1753,17 +1768,17 @@ def leading_monomial(self, *args, **kwds): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() - sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) - sage: x.leading_monomial() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") # optional - sage.modules + sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) # optional - sage.modules + sage: x.leading_monomial() # optional - sage.modules B[3] - sage: def key(x): return -x - sage: x.leading_monomial(key=key) + sage: def key(x): return -x # optional - sage.modules + sage: x.leading_monomial(key=key) # optional - sage.modules B[1] - sage: s = SymmetricFunctions(QQ).schur() - sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] - sage: f.leading_monomial() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # optional - sage.combinat sage.modules + sage: f.leading_monomial() # optional - sage.combinat sage.modules s[3] """ return self.parent().monomial(self.leading_support(*args, **kwds)) @@ -1781,17 +1796,17 @@ def leading_coefficient(self, *args, **kwds): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") - sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) - sage: x.leading_coefficient() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") # optional - sage.modules + sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) # optional - sage.modules + sage: x.leading_coefficient() # optional - sage.modules 1 - sage: def key(x): return -x - sage: x.leading_coefficient(key=key) + sage: def key(x): return -x # optional - sage.modules + sage: x.leading_coefficient(key=key) # optional - sage.modules 3 - sage: s = SymmetricFunctions(QQ).schur() - sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] - sage: f.leading_coefficient() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # optional - sage.combinat sage.modules + sage: f.leading_coefficient() # optional - sage.combinat sage.modules -5 """ return self.leading_item(*args, **kwds)[1] @@ -1809,17 +1824,17 @@ def leading_term(self, *args, **kwds): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() - sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) - sage: x.leading_term() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") # optional - sage.modules + sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) # optional - sage.modules + sage: x.leading_term() # optional - sage.modules B[3] - sage: def key(x): return -x - sage: x.leading_term(key=key) + sage: def key(x): return -x # optional - sage.modules + sage: x.leading_term(key=key) # optional - sage.modules 3*B[1] - sage: s = SymmetricFunctions(QQ).schur() - sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] - sage: f.leading_term() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # optional - sage.combinat sage.modules + sage: f.leading_term() # optional - sage.combinat sage.modules -5*s[3] """ return self.parent().term(*self.leading_item(*args, **kwds)) @@ -1835,18 +1850,18 @@ def trailing_support(self, *args, **kwds): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() - sage: x = 3*X.monomial(1) + 2*X.monomial(2) + 4*X.monomial(3) - sage: x.trailing_support() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") # optional - sage.modules + sage: x = 3*X.monomial(1) + 2*X.monomial(2) + 4*X.monomial(3) # optional - sage.modules + sage: x.trailing_support() # optional - sage.modules 1 - sage: def key(x): return -x - sage: x.trailing_support(key=key) + sage: def key(x): return -x # optional - sage.modules + sage: x.trailing_support(key=key) # optional - sage.modules 3 - sage: s = SymmetricFunctions(QQ).schur() - sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] - sage: f.trailing_support() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # optional - sage.combinat sage.modules + sage: f.trailing_support() # optional - sage.combinat sage.modules [1] """ return min(self.support(), *args, **kwds) @@ -1865,17 +1880,17 @@ def trailing_item(self, *args, **kwds): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() - sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) - sage: x.trailing_item() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") # optional - sage.modules + sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) # optional - sage.modules + sage: x.trailing_item() # optional - sage.modules (1, 3) - sage: def key(x): return -x - sage: x.trailing_item(key=key) + sage: def key(x): return -x # optional - sage.modules + sage: x.trailing_item(key=key) # optional - sage.modules (3, 1) - sage: s = SymmetricFunctions(QQ).schur() - sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] - sage: f.trailing_item() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # optional - sage.combinat sage.modules + sage: f.trailing_item() # optional - sage.combinat sage.modules ([1], 2) """ k = self.trailing_support(*args, **kwds) @@ -1894,17 +1909,17 @@ def trailing_monomial(self, *args, **kwds): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() - sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) - sage: x.trailing_monomial() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") # optional - sage.modules + sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) # optional - sage.modules + sage: x.trailing_monomial() # optional - sage.modules B[1] - sage: def key(x): return -x - sage: x.trailing_monomial(key=key) + sage: def key(x): return -x # optional - sage.modules + sage: x.trailing_monomial(key=key) # optional - sage.modules B[3] - sage: s = SymmetricFunctions(QQ).schur() - sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] - sage: f.trailing_monomial() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # optional - sage.combinat sage.modules + sage: f.trailing_monomial() # optional - sage.combinat sage.modules s[1] """ return self.parent().monomial(self.trailing_support(*args, **kwds)) @@ -1922,17 +1937,17 @@ def trailing_coefficient(self, *args, **kwds): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() - sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) - sage: x.trailing_coefficient() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") # optional - sage.modules + sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) # optional - sage.modules + sage: x.trailing_coefficient() # optional - sage.modules 3 - sage: def key(x): return -x - sage: x.trailing_coefficient(key=key) + sage: def key(x): return -x # optional - sage.modules + sage: x.trailing_coefficient(key=key) # optional - sage.modules 1 - sage: s = SymmetricFunctions(QQ).schur() - sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] - sage: f.trailing_coefficient() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # optional - sage.combinat sage.modules + sage: f.trailing_coefficient() # optional - sage.combinat sage.modules 2 """ return self.trailing_item(*args, **kwds)[1] @@ -1950,17 +1965,17 @@ def trailing_term(self, *args, **kwds): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X"); x = X.basis() - sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) - sage: x.trailing_term() + sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename("X") # optional - sage.modules + sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3) # optional - sage.modules + sage: x.trailing_term() # optional - sage.modules 3*B[1] - sage: def key(x): return -x - sage: x.trailing_term(key=key) + sage: def key(x): return -x # optional - sage.modules + sage: x.trailing_term(key=key) # optional - sage.modules B[3] - sage: s = SymmetricFunctions(QQ).schur() - sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] - sage: f.trailing_term() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # optional - sage.combinat sage.modules + sage: f.trailing_term() # optional - sage.combinat sage.modules 2*s[1] """ return self.parent().term(*self.trailing_item(*args, **kwds)) @@ -1979,24 +1994,24 @@ def map_coefficients(self, f): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) - sage: B = F.basis() - sage: f = B['a'] - 3*B['c'] - sage: f.map_coefficients(lambda x: x+5) + sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) # optional - sage.modules + sage: B = F.basis() # optional - sage.modules + sage: f = B['a'] - 3*B['c'] # optional - sage.modules + sage: f.map_coefficients(lambda x: x + 5) # optional - sage.modules 6*B['a'] + 2*B['c'] Killed coefficients are handled properly:: - sage: f.map_coefficients(lambda x: 0) + sage: f.map_coefficients(lambda x: 0) # optional - sage.modules 0 - sage: list(f.map_coefficients(lambda x: 0)) + sage: list(f.map_coefficients(lambda x: 0)) # optional - sage.modules [] :: - sage: s = SymmetricFunctions(QQ).schur() - sage: a = s([2,1])+2*s([3,2]) - sage: a.map_coefficients(lambda x: x*2) + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: a = s([2,1]) + 2*s([3,2]) # optional - sage.combinat sage.modules + sage: a.map_coefficients(lambda x: x * 2) # optional - sage.combinat sage.modules 2*s[2, 1] + 4*s[3, 2] """ return self.parent().sum_of_terms( (m, f(c)) for m,c in self ) @@ -2015,30 +2030,30 @@ def map_support(self, f): EXAMPLES:: - sage: B = CombinatorialFreeModule(ZZ, [-1, 0, 1]) - sage: x = B.an_element(); x + sage: B = CombinatorialFreeModule(ZZ, [-1, 0, 1]) # optional - sage.modules + sage: x = B.an_element(); x # optional - sage.modules 2*B[-1] + 2*B[0] + 3*B[1] - sage: x.map_support(lambda i: -i) + sage: x.map_support(lambda i: -i) # optional - sage.modules 3*B[-1] + 2*B[0] + 2*B[1] ``f`` needs not be injective:: - sage: x.map_support(lambda i: 1) + sage: x.map_support(lambda i: 1) # optional - sage.modules 7*B[1] - sage: s = SymmetricFunctions(QQ).schur() - sage: a = s([2,1])+2*s([3,2]) - sage: a.map_support(lambda x: x.conjugate()) + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: a = s([2,1]) + 2*s([3,2]) # optional - sage.combinat sage.modules + sage: a.map_support(lambda x: x.conjugate()) # optional - sage.combinat sage.modules s[2, 1] + 2*s[2, 2, 1] TESTS:: - sage: B.zero() # This actually failed at some point!!! See #8890 + sage: B.zero() # This actually failed at some point!!! See #8890 # optional - sage.modules 0 - sage: y = B.zero().map_support(lambda i: i/0); y + sage: y = B.zero().map_support(lambda i: i/0); y # optional - sage.modules 0 - sage: y.parent() is B + sage: y.parent() is B # optional - sage.modules True """ return self.parent().sum_of_terms( (f(m), c) for m,c in self ) @@ -2057,22 +2072,22 @@ def map_support_skip_none(self, f): EXAMPLES:: - sage: B = CombinatorialFreeModule(ZZ, [-1, 0, 1]) - sage: x = B.an_element(); x + sage: B = CombinatorialFreeModule(ZZ, [-1, 0, 1]) # optional - sage.modules + sage: x = B.an_element(); x # optional - sage.modules 2*B[-1] + 2*B[0] + 3*B[1] - sage: x.map_support_skip_none(lambda i: -i if i else None) + sage: x.map_support_skip_none(lambda i: -i if i else None) # optional - sage.modules 3*B[-1] + 2*B[1] ``f`` needs not be injective:: - sage: x.map_support_skip_none(lambda i: 1 if i else None) + sage: x.map_support_skip_none(lambda i: 1 if i else None) # optional - sage.modules 5*B[1] TESTS:: - sage: y = x.map_support_skip_none(lambda i: None); y + sage: y = x.map_support_skip_none(lambda i: None); y # optional - sage.modules 0 - sage: y.parent() is B + sage: y.parent() is B # optional - sage.modules True """ return self.parent().sum_of_terms( (fm,c) for (fm,c) in ((f(m), c) for m,c in self) if fm is not None) @@ -2092,21 +2107,21 @@ def map_item(self, f): EXAMPLES:: - sage: B = CombinatorialFreeModule(ZZ, [-1, 0, 1]) - sage: x = B.an_element(); x + sage: B = CombinatorialFreeModule(ZZ, [-1, 0, 1]) # optional - sage.modules + sage: x = B.an_element(); x # optional - sage.modules 2*B[-1] + 2*B[0] + 3*B[1] - sage: x.map_item(lambda i, c: (-i, 2*c)) + sage: x.map_item(lambda i, c: (-i, 2*c)) # optional - sage.modules 6*B[-1] + 4*B[0] + 4*B[1] ``f`` needs not be injective:: - sage: x.map_item(lambda i, c: (1, 2*c)) + sage: x.map_item(lambda i, c: (1, 2*c)) # optional - sage.modules 14*B[1] - sage: s = SymmetricFunctions(QQ).schur() - sage: f = lambda m,c: (m.conjugate(), 2*c) - sage: a = s([2,1]) + s([1,1,1]) - sage: a.map_item(f) + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat sage.modules + sage: f = lambda m, c: (m.conjugate(), 2 * c) # optional - sage.combinat sage.modules + sage: a = s([2,1]) + s([1,1,1]) # optional - sage.combinat sage.modules + sage: a.map_item(f) # optional - sage.combinat sage.modules 2*s[2, 1] + 2*s[3] """ return self.parent().sum_of_terms( f(m,c) for m,c in self ) @@ -2119,9 +2134,9 @@ def tensor(*elements): EXAMPLES:: sage: C = AlgebrasWithBasis(QQ) - sage: A = C.example() - sage: (a,b,c) = A.algebra_generators() - sage: a.tensor(b, c) + sage: A = C.example() # optional - sage.combinat sage.modules + sage: a, b, c = A.algebra_generators() # optional - sage.combinat sage.modules + sage: a.tensor(b, c) # optional - sage.combinat sage.modules B[word: a] # B[word: b] # B[word: c] FIXME: is this a policy that we want to enforce on all parents? @@ -2151,47 +2166,50 @@ def __call_on_basis__(self, **options): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") - sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename("Y") - sage: H = Hom(X, Y) - sage: x = X.basis() + sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") # optional - sage.modules + sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename("Y") # optional - sage.modules + sage: H = Hom(X, Y) # optional - sage.modules + sage: x = X.basis() # optional - sage.modules - sage: phi = H(on_basis = lambda i: Y.monomial(i) + 2*Y.monomial(i+1)) # indirect doctest - sage: phi + sage: def on_basis(i): + ....: return Y.monomial(i) + 2*Y.monomial(i + 1) + sage: phi = H(on_basis=on_basis) # indirect doctest # optional - sage.modules + sage: phi # optional - sage.modules Generic morphism: From: X To: Y - sage: phi(x[1] + x[3]) + sage: phi(x[1] + x[3]) # optional - sage.modules B[1] + 2*B[2] + B[3] + 2*B[4] Diagonal functions can be constructed using the ``diagonal`` option:: - sage: X = CombinatorialFreeModule(QQ, [1,2,3,4]); X.rename("X") - sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4], key="Y"); Y.rename("Y") - sage: H = Hom(X, Y) - sage: x = X.basis() - sage: phi = H(diagonal = lambda x: x^2) - sage: phi(x[1] + x[2] + x[3]) + sage: X = CombinatorialFreeModule(QQ, [1,2,3,4]); X.rename("X") # optional - sage.modules + sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4], # optional - sage.modules + ....: key="Y"); Y.rename("Y") + sage: H = Hom(X, Y) # optional - sage.modules + sage: x = X.basis() # optional - sage.modules + sage: phi = H(diagonal=lambda x: x^2) # optional - sage.modules + sage: phi(x[1] + x[2] + x[3]) # optional - sage.modules B[1] + 4*B[2] + 9*B[3] TESTS: As for usual homsets, the argument can be a Python function:: - sage: phi = H(lambda x: Y.zero()) - sage: phi + sage: phi = H(lambda x: Y.zero()) # optional - sage.modules + sage: phi # optional - sage.modules Generic morphism: From: X To: Y - sage: phi(x[1] + x[3]) + sage: phi(x[1] + x[3]) # optional - sage.modules 0 We check that the homset category is properly set up:: - sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") - sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename("Y") - sage: H = Hom(X, Y) - sage: H.zero().category_for() + sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") # optional - sage.modules + sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename("Y") # optional - sage.modules + sage: H = Hom(X, Y) # optional - sage.modules + sage: H.zero().category_for() # optional - sage.modules Category of finite dimensional vector spaces with basis over Rational Field """ return self.domain().module_morphism(codomain=self.codomain(), @@ -2210,20 +2228,20 @@ def on_basis(self): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") - sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename("Y") - sage: H = Hom(X, Y) - sage: x = X.basis() + sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") # optional - sage.modules + sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename("Y") # optional - sage.modules + sage: H = Hom(X, Y) # optional - sage.modules + sage: x = X.basis() # optional - sage.modules - sage: f = H(lambda x: Y.zero()).on_basis() - sage: f(2) + sage: f = H(lambda x: Y.zero()).on_basis() # optional - sage.modules + sage: f(2) # optional - sage.modules 0 - sage: f = lambda i: Y.monomial(i) + 2*Y.monomial(i+1) - sage: g = H(on_basis = f).on_basis() - sage: g(2) + sage: f = lambda i: Y.monomial(i) + 2*Y.monomial(i+1) # optional - sage.modules + sage: g = H(on_basis=f).on_basis() # optional - sage.modules + sage: g(2) # optional - sage.modules B[2] + 2*B[3] - sage: g == f + sage: g == f # optional - sage.modules True """ return self._on_basis @@ -2238,9 +2256,9 @@ def _on_basis(self, i): EXAMPLES:: - sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") - sage: phi = End(X)(lambda x: 2*x) - sage: phi._on_basis(3) + sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename("X") # optional - sage.modules + sage: phi = End(X)(lambda x: 2*x) # optional - sage.modules + sage: phi._on_basis(3) # optional - sage.modules 2*B[3] """ return self(self.domain().monomial(i)) @@ -2270,15 +2288,20 @@ def _an_element_(self): """ EXAMPLES:: - sage: A = AlgebrasWithBasis(QQ).example(); A - An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field - sage: B = HopfAlgebrasWithBasis(QQ).example(); B - An example of Hopf algebra with basis: the group algebra of the Dihedral group of order 6 as a permutation group over Rational Field - sage: A.an_element() + sage: A = AlgebrasWithBasis(QQ).example(); A # optional - sage.combinat sage.modules + An example of an algebra with basis: + the free algebra on the generators ('a', 'b', 'c') + over Rational Field + sage: B = HopfAlgebrasWithBasis(QQ).example(); B # optional - sage.combinat sage.modules + An example of Hopf algebra with basis: + the group algebra of the Dihedral group of order 6 + as a permutation group over Rational Field + sage: A.an_element() # optional - sage.combinat sage.modules B[word: ] + 2*B[word: a] + 3*B[word: b] + B[word: bab] - sage: B.an_element() + sage: B.an_element() # optional - sage.combinat sage.modules B[()] + B[(1,2)] + 3*B[(1,2,3)] + 2*B[(1,3,2)] - sage: cartesian_product((A, B, A)).an_element() # indirect doctest + sage: ABA = cartesian_product((A, B, A)) # optional - sage.combinat sage.modules + sage: ABA.an_element() # indirect doctest # optional - sage.combinat sage.modules 2*B[(0, word: )] + 2*B[(0, word: a)] + 3*B[(0, word: b)] """ from .cartesian_product import cartesian_product @@ -2341,8 +2364,10 @@ def apply_multilinear_morphism(self, f, codomain=None): We start with simple (admittedly not so interesting) examples, with two modules `A` and `B`:: - sage: A = CombinatorialFreeModule(ZZ, [1,2], prefix="A"); A.rename("A") - sage: B = CombinatorialFreeModule(ZZ, [3,4], prefix="B"); B.rename("B") + sage: A = CombinatorialFreeModule(ZZ, [1,2], prefix="A") # optional - sage.modules + sage: A.rename("A") # optional - sage.modules + sage: B = CombinatorialFreeModule(ZZ, [3,4], prefix="B") # optional - sage.modules + sage: B.rename("B") # optional - sage.modules and `f` the bilinear morphism `(a,b) \mapsto b \otimes a` from `A \times B` to `B \otimes A`:: @@ -2353,23 +2378,23 @@ def apply_multilinear_morphism(self, f, codomain=None): Now, calling applying `f` on `a \otimes b` returns the same as `f(a,b)`:: - sage: a = A.monomial(1) + 2 * A.monomial(2); a + sage: a = A.monomial(1) + 2 * A.monomial(2); a # optional - sage.modules A[1] + 2*A[2] - sage: b = B.monomial(3) - 2 * B.monomial(4); b + sage: b = B.monomial(3) - 2 * B.monomial(4); b # optional - sage.modules B[3] - 2*B[4] - sage: f(a,b) + sage: f(a, b) # optional - sage.modules B[3] # A[1] + 2*B[3] # A[2] - 2*B[4] # A[1] - 4*B[4] # A[2] - sage: tensor([a,b]).apply_multilinear_morphism(f) + sage: tensor([a, b]).apply_multilinear_morphism(f) # optional - sage.modules B[3] # A[1] + 2*B[3] # A[2] - 2*B[4] # A[1] - 4*B[4] # A[2] `f` may be a bilinear morphism to any module over the base ring of `A` and `B`. Here the codomain is `\ZZ`:: - sage: def f(a,b): + sage: def f(a, b): ....: return sum(a.coefficients(), 0) * sum(b.coefficients(), 0) - sage: f(a,b) + sage: f(a, b) # optional - sage.modules -3 - sage: tensor([a,b]).apply_multilinear_morphism(f) + sage: tensor([a, b]).apply_multilinear_morphism(f) # optional - sage.modules -3 Mind the `0` in the sums above; otherwise `f` would @@ -2377,12 +2402,12 @@ def apply_multilinear_morphism(self, f, codomain=None): sage: def f(a,b): ....: return sum(a.coefficients()) * sum(b.coefficients()) - sage: type(f(A.zero(), B.zero())) + sage: type(f(A.zero(), B.zero())) # optional - sage.modules <... 'int'> Which would be wrong and break this method:: - sage: tensor([a,b]).apply_multilinear_morphism(f) + sage: tensor([a, b]).apply_multilinear_morphism(f) # optional - sage.modules Traceback (most recent call last): ... AttributeError: 'int' object has no attribute 'parent' @@ -2390,12 +2415,14 @@ def apply_multilinear_morphism(self, f, codomain=None): Here we consider an example where the codomain is a module with basis with a different base ring:: - sage: C = CombinatorialFreeModule(QQ, [(1,3),(2,4)], prefix="C"); C.rename("C") - sage: def f(a,b): - ....: return C.sum_of_terms( [((1,3), QQ(a[1]*b[3])), ((2,4), QQ(a[2]*b[4]))] ) - sage: f(a,b) + sage: C = CombinatorialFreeModule(QQ, [(1,3),(2,4)], prefix="C") # optional - sage.modules + sage: C.rename("C") # optional - sage.modules + sage: def f(a, b): + ....: return C.sum_of_terms([((1,3), QQ(a[1]*b[3])), + ....: ((2,4), QQ(a[2]*b[4]))]) + sage: f(a,b) # optional - sage.modules C[(1, 3)] - 4*C[(2, 4)] - sage: tensor([a,b]).apply_multilinear_morphism(f) + sage: tensor([a, b]).apply_multilinear_morphism(f) # optional - sage.modules C[(1, 3)] - 4*C[(2, 4)] We conclude with a real life application, where we @@ -2403,14 +2430,14 @@ def apply_multilinear_morphism(self, f, codomain=None): Symmetric functions on the Schur basis satisfies its defining formula:: - sage: Sym = SymmetricFunctions(QQ) - sage: s = Sym.schur() - sage: def f(a,b): return a*b.antipode() - sage: x = 4*s.an_element(); x + sage: Sym = SymmetricFunctions(QQ) # optional - sage.combinat sage.modules + sage: s = Sym.schur() # optional - sage.combinat sage.modules + sage: def f(a, b): return a * b.antipode() # optional - sage.combinat sage.modules + sage: x = 4 * s.an_element(); x # optional - sage.combinat sage.modules 8*s[] + 8*s[1] + 12*s[2] - sage: x.coproduct().apply_multilinear_morphism(f) + sage: x.coproduct().apply_multilinear_morphism(f) # optional - sage.combinat sage.modules 8*s[] - sage: x.coproduct().apply_multilinear_morphism(f) == x.counit() + sage: x.coproduct().apply_multilinear_morphism(f) == x.counit() # optional - sage.combinat sage.modules True We recover the constant term of `x`, as desired. @@ -2445,6 +2472,7 @@ def extra_super_categories(self): sage: ModulesWithBasis(ZZ).DualObjects().extra_super_categories() [Category of modules over Integer Ring] sage: ModulesWithBasis(QQ).DualObjects().super_categories() - [Category of duals of vector spaces over Rational Field, Category of duals of modules with basis over Rational Field] + [Category of duals of vector spaces over Rational Field, + Category of duals of modules with basis over Rational Field] """ return [Modules(self.base_category().base_ring())] diff --git a/src/sage/categories/monoids.py b/src/sage/categories/monoids.py index dc548a72e66..386b1b133f1 100644 --- a/src/sage/categories/monoids.py +++ b/src/sage/categories/monoids.py @@ -69,7 +69,7 @@ class Monoids(CategoryWithAxiom): Check for :trac:`31212`:: sage: R = IntegerModRing(15) - sage: R.submonoid([R.one()]).list() + sage: R.submonoid([R.one()]).list() # optional - sage.groups [1] """ _base_category_class_and_axiom = (Semigroups, "Unital") @@ -98,11 +98,11 @@ def free(index_set=None, names=None, **kwds): EXAMPLES:: - sage: Monoids.free(index_set=ZZ) + sage: Monoids.free(index_set=ZZ) # optional - sage.groups Free monoid indexed by Integer Ring - sage: Monoids().free(ZZ) + sage: Monoids().free(ZZ) # optional - sage.groups Free monoid indexed by Integer Ring - sage: F. = Monoids().free(); F + sage: F. = Monoids().free(); F # optional - sage.groups Free monoid indexed by {'x', 'y', 'z'} """ if names is not None: @@ -130,8 +130,8 @@ def semigroup_generators(self): EXAMPLES:: - sage: M = Monoids().free([1,2,3]) - sage: M.semigroup_generators() + sage: M = Monoids().free([1,2,3]) # optional - sage.groups + sage: M.semigroup_generators() # optional - sage.groups Family (1, F[1], F[2], F[3]) """ G = self.monoid_generators() @@ -212,22 +212,22 @@ def submonoid(self, generators, category=None): EXAMPLES:: sage: R = IntegerModRing(15) - sage: M = R.submonoid([R(3),R(5)]); M + sage: M = R.submonoid([R(3), R(5)]); M # optional - sage.groups A submonoid of (Ring of integers modulo 15) with 2 generators - sage: M.list() + sage: M.list() # optional - sage.groups [1, 3, 5, 9, 0, 10, 12, 6] Not the presence of the unit, unlike in:: - sage: S = R.subsemigroup([R(3),R(5)]); S + sage: S = R.subsemigroup([R(3), R(5)]); S # optional - sage.groups A subsemigroup of (Ring of integers modulo 15) with 2 generators - sage: S.list() + sage: S.list() # optional - sage.groups [3, 5, 9, 0, 10, 12, 6] This method is really a shorthand for subsemigroup:: - sage: M2 = R.subsemigroup([R(3),R(5)], one=R.one()) - sage: M2 is M + sage: M2 = R.subsemigroup([R(3), R(5)], one=R.one()) # optional - sage.groups + sage: M2 is M # optional - sage.groups True """ return self.subsemigroup(generators, one=self.one()) @@ -245,11 +245,11 @@ def _div_(left, right): EXAMPLES:: - sage: G = FreeGroup(2) - sage: x0, x1 = G.group_generators() - sage: c1 = cartesian_product([x0, x1]) - sage: c2 = cartesian_product([x1, x0]) - sage: c1._div_(c2) + sage: G = FreeGroup(2) # optional - sage.groups + sage: x0, x1 = G.group_generators() # optional - sage.groups + sage: c1 = cartesian_product([x0, x1]) # optional - sage.groups + sage: c2 = cartesian_product([x1, x0]) # optional - sage.groups + sage: c1._div_(c2) # optional - sage.groups (x0*x1^-1, x1*x0^-1) With this default implementation, division will fail as @@ -267,7 +267,7 @@ def _div_(left, right): TESTS:: - sage: c1._div_.__module__ + sage: c1._div_.__module__ # optional - sage.groups 'sage.categories.monoids' """ return left * ~right @@ -336,8 +336,8 @@ def powers(self, n): EXAMPLES:: - sage: A = Matrix([[1, 1], [-1, 0]]) - sage: A.powers(6) + sage: A = Matrix([[1, 1], [-1, 0]]) # optional - sage.modules + sage: A.powers(6) # optional - sage.modules [ [1 0] [ 1 1] [ 0 1] [-1 0] [-1 -1] [ 0 -1] [0 1], [-1 0], [-1 -1], [ 0 -1], [ 1 0], [ 1 1] @@ -363,8 +363,8 @@ def __invert__(self): EXAMPLES:: - sage: A = Matrix([[1, 0], [1, 1]]) - sage: ~A + sage: A = Matrix([[1, 0], [1, 1]]) # optional - sage.modules + sage: ~A # optional - sage.modules [ 1 0] [-1 1] """ @@ -379,7 +379,7 @@ def inverse(self): EXAMPLES:: - sage: AA(sqrt(~2)).inverse() + sage: AA(sqrt(~2)).inverse() # optional - sage.symbolic sage.rings.number_field 1.414213562373095? """ # Nota Bene: Element classes should implement ``__invert__`` only. @@ -412,11 +412,11 @@ def free(index_set=None, names=None, **kwds): EXAMPLES:: - sage: Monoids.Commutative.free(index_set=ZZ) + sage: Monoids.Commutative.free(index_set=ZZ) # optional - sage.groups Free abelian monoid indexed by Integer Ring - sage: Monoids().Commutative().free(ZZ) + sage: Monoids().Commutative().free(ZZ) # optional - sage.groups Free abelian monoid indexed by Integer Ring - sage: F. = Monoids().Commutative().free(); F + sage: F. = Monoids().Commutative().free(); F # optional - sage.groups Free abelian monoid indexed by {'x', 'y', 'z'} """ if names is not None: @@ -447,18 +447,18 @@ def one(self): EXAMPLES:: - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field - sage: A.one.__module__ + sage: A.one.__module__ # optional - sage.combinat sage.modules 'sage.categories.monoids' - sage: A.one() + sage: A.one() # optional - sage.combinat sage.modules F[{}] TESTS:: - sage: A.one() is A.a_realization().one() + sage: A.one() is A.a_realization().one() # optional - sage.combinat sage.modules True - sage: A._test_one() + sage: A._test_one() # optional - sage.combinat sage.modules """ return self.a_realization().one() @@ -510,12 +510,12 @@ def one_basis(self): EXAMPLES:: - sage: A = Monoids().example().algebra(ZZ) - sage: A.one_basis() + sage: A = Monoids().example().algebra(ZZ) # optional - sage.modules + sage: A.one_basis() # optional - sage.modules '' - sage: A.one() + sage: A.one() # optional - sage.modules B[''] - sage: A(3) + sage: A(3) # optional - sage.modules 3*B[''] """ return self.basis().keys().one() @@ -542,7 +542,7 @@ def algebra_generators(self): the free monoid generated by ('a', 'b', 'c', 'd') sage: M.monoid_generators() Finite family {'a': 'a', 'b': 'b', 'c': 'c', 'd': 'd'} - sage: M.algebra(ZZ).algebra_generators() + sage: M.algebra(ZZ).algebra_generators() # optional - sage.modules Finite family {'a': B['a'], 'b': B['b'], 'c': B['c'], 'd': B['d']} sage: Z12 = Monoids().Finite().example(); Z12 @@ -555,17 +555,18 @@ def algebra_generators(self): has no attribute 'monoid_generators' sage: Z12.semigroup_generators() Family (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) - sage: Z12.algebra(QQ).algebra_generators() + sage: Z12.algebra(QQ).algebra_generators() # optional - sage.modules Family (B[0], B[1], B[2], B[3], B[4], B[5], B[6], B[7], B[8], B[9], B[10], B[11]) - sage: GroupAlgebras(QQ).example(AlternatingGroup(10)).algebra_generators() + sage: A10 = AlternatingGroup(10) # optional - sage.groups + sage: GroupAlgebras(QQ).example(A10).algebra_generators() # optional - sage.groups sage.modules Family ((8,9,10), (1,2,3,4,5,6,7,8,9)) - sage: A = DihedralGroup(3).algebra(QQ); A + sage: A = DihedralGroup(3).algebra(QQ); A # optional - sage.groups sage.modules Algebra of Dihedral group of order 6 as a permutation group over Rational Field - sage: A.algebra_generators() + sage: A.algebra_generators() # optional - sage.groups sage.modules Family ((1,2,3), (1,3)) """ monoid = self.basis().keys() @@ -583,14 +584,15 @@ def is_central(self): EXAMPLES:: - sage: SG4 = SymmetricGroupAlgebra(ZZ,4) - sage: SG4(1).is_central() + sage: SG4 = SymmetricGroupAlgebra(ZZ,4) # optional - sage.groups sage.modules + sage: SG4(1).is_central() # optional - sage.groups sage.modules True - sage: SG4(Permutation([1,3,2,4])).is_central() + sage: SG4(Permutation([1,3,2,4])).is_central() # optional - sage.groups sage.modules False - sage: A = GroupAlgebras(QQ).example(); A - Algebra of Dihedral group of order 8 as a permutation group over Rational Field - sage: sum(i for i in A.basis()).is_central() + sage: A = GroupAlgebras(QQ).example(); A # optional - sage.groups sage.modules + Algebra of Dihedral group of order 8 + as a permutation group over Rational Field + sage: sum(i for i in A.basis()).is_central() # optional - sage.groups sage.modules True """ return all(i * self == self * i @@ -628,19 +630,19 @@ def monoid_generators(self): EXAMPLES:: - sage: M = Monoids.free([1,2,3]) - sage: N = Monoids.free(['a','b']) - sage: C = cartesian_product([M, N]) - sage: C.monoid_generators() + sage: M = Monoids.free([1, 2, 3]) # optional - sage.groups + sage: N = Monoids.free(['a', 'b']) # optional - sage.groups + sage: C = cartesian_product([M, N]) # optional - sage.groups + sage: C.monoid_generators() # optional - sage.groups Family ((F[1], 1), (F[2], 1), (F[3], 1), (1, F['a']), (1, F['b'])) An example with an infinitely generated group (a better output is needed):: - sage: N = Monoids.free(ZZ) - sage: C = cartesian_product([M, N]) - sage: C.monoid_generators() + sage: N = Monoids.free(ZZ) # optional - sage.groups + sage: C = cartesian_product([M, N]) # optional - sage.groups + sage: C.monoid_generators() # optional - sage.groups Lazy family (gen(i))_{i in The Cartesian product of (...)} """ F = self.cartesian_factors() @@ -677,10 +679,10 @@ def multiplicative_order(self): EXAMPLES:: - sage: G1 = SymmetricGroup(3) - sage: G2 = SL(2,3) - sage: G = cartesian_product([G1,G2]) - sage: G((G1.gen(0), G2.gen(1))).multiplicative_order() + sage: G1 = SymmetricGroup(3) # optional - sage.groups sage.modules + sage: G2 = SL(2, 3) # optional - sage.groups sage.modules + sage: G = cartesian_product([G1, G2]) # optional - sage.groups sage.modules + sage: G((G1.gen(0), G2.gen(1))).multiplicative_order() # optional - sage.groups sage.modules 12 """ from sage.rings.infinity import Infinity @@ -697,10 +699,10 @@ def __invert__(self): EXAMPLES:: - sage: a1 = Permutation((4,2,1,3)) - sage: a2 = SL(2,3)([2,1,1,1]) - sage: h = cartesian_product([a1,a2]) - sage: ~h + sage: a1 = Permutation((4,2,1,3)) # optional - sage.groups sage.modules + sage: a2 = SL(2, 3)([2,1,1,1]) # optional - sage.groups sage.modules + sage: h = cartesian_product([a1, a2]) # optional - sage.groups sage.modules + sage: ~h # optional - sage.groups sage.modules ([2, 4, 1, 3], [1 2] [2 2]) """ diff --git a/src/sage/categories/morphism.pyx b/src/sage/categories/morphism.pyx index 031b41218e3..514140b2333 100644 --- a/src/sage/categories/morphism.pyx +++ b/src/sage/categories/morphism.pyx @@ -69,25 +69,25 @@ cdef class Morphism(Map): EXAMPLES:: sage: R. = ZZ[] - sage: f = R.hom([t+1]) + sage: f = R.hom([t + 1]) sage: f # indirect doctest Ring endomorphism of Univariate Polynomial Ring in t over Integer Ring Defn: t |--> t + 1 TESTS:: - sage: K = CyclotomicField(12) - sage: L = CyclotomicField(132) - sage: phi = L._internal_coerce_map_from(K); phi + sage: K = CyclotomicField(12) # optional - sage.rings.number_field + sage: L = CyclotomicField(132) # optional - sage.rings.number_field + sage: phi = L._internal_coerce_map_from(K); phi # optional - sage.rings.number_field (map internal to coercion system -- copy before use) Generic morphism: From: Cyclotomic Field of order 12 and degree 4 To: Cyclotomic Field of order 132 and degree 40 - sage: del K + sage: del K # optional - sage.rings.number_field sage: import gc sage: _ = gc.collect() - sage: phi + sage: phi # optional - sage.rings.number_field Defunct morphism """ D = self.domain() @@ -182,10 +182,10 @@ cdef class Morphism(Map): and left modules over (euclidean domains and infinite enumerated sets and metric spaces) - sage: K = CyclotomicField(12) - sage: L = CyclotomicField(132) - sage: phi = L._internal_coerce_map_from(K) - sage: phi.category() + sage: K = CyclotomicField(12) # optional - sage.rings.number_field + sage: L = CyclotomicField(132) # optional - sage.rings.number_field + sage: phi = L._internal_coerce_map_from(K) # optional - sage.rings.number_field + sage: phi.category() # optional - sage.rings.number_field Category of homsets of number fields """ # Should it be Category of elements of ...? @@ -202,10 +202,10 @@ cdef class Morphism(Map): sage: f.is_endomorphism() True - sage: K = CyclotomicField(12) - sage: L = CyclotomicField(132) - sage: phi = L._internal_coerce_map_from(K) - sage: phi.is_endomorphism() + sage: K = CyclotomicField(12) # optional - sage.rings.number_field + sage: L = CyclotomicField(132) # optional - sage.rings.number_field + sage: phi = L._internal_coerce_map_from(K) # optional - sage.rings.number_field + sage: phi.is_endomorphism() # optional - sage.rings.number_field False """ return self.parent().is_endomorphism_set() @@ -260,7 +260,9 @@ cdef class Morphism(Map): sage: x^2 + y Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for +: 'Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Polynomial Ring in y over Integer Ring' + TypeError: unsupported operand parent(s) for +: + 'Univariate Polynomial Ring in x over Integer Ring' and + 'Univariate Polynomial Ring in y over Integer Ring' Let us declare a coercion from `\ZZ[x]` to `\ZZ[z]`:: @@ -284,7 +286,9 @@ cdef class Morphism(Map): sage: phi.register_as_coercion() Traceback (most recent call last): ... - AssertionError: coercion from Univariate Polynomial Ring in x over Integer Ring to Univariate Polynomial Ring in z over Integer Ring already registered or discovered + AssertionError: coercion from Univariate Polynomial Ring in x over Integer Ring + to Univariate Polynomial Ring in z over Integer Ring + already registered or discovered """ self._codomain.register_coercion(self) @@ -300,14 +304,14 @@ cdef class Morphism(Map): Let us declare a conversion from the symmetric group to `\ZZ` through the sign map:: - sage: S = SymmetricGroup(4) - sage: phi = Hom(S, ZZ)(lambda x: ZZ(x.sign())) - sage: x = S.an_element(); x + sage: S = SymmetricGroup(4) # optional - sage.groups + sage: phi = Hom(S, ZZ)(lambda x: ZZ(x.sign())) # optional - sage.groups + sage: x = S.an_element(); x # optional - sage.groups (2,3,4) - sage: phi(x) + sage: phi(x) # optional - sage.groups 1 - sage: phi.register_as_conversion() - sage: ZZ(x) + sage: phi.register_as_conversion() # optional - sage.groups + sage: ZZ(x) # optional - sage.groups 1 """ self._codomain.register_conversion(self) @@ -347,26 +351,27 @@ cdef class Morphism(Map): TESTS:: sage: from sage.categories.morphism import SetMorphism - sage: E = End(Partitions(5)) - sage: f = E.identity() - sage: g = SetMorphism(E, lambda x:x) - sage: f == g + sage: E = End(Partitions(5)) # optional - sage.combinat + sage: f = E.identity() # optional - sage.combinat + sage: g = SetMorphism(E, lambda x: x) # optional - sage.combinat + sage: f == g # optional - sage.combinat Traceback (most recent call last): ... - NotImplementedError: unable to compare morphisms of type <... 'sage.categories.morphism.IdentityMorphism'> and <... 'sage.categories.morphism.SetMorphism'> with domain Partitions of the integer 5 + NotImplementedError: unable to compare morphisms of type <... 'sage.categories.morphism.IdentityMorphism'> + and <... 'sage.categories.morphism.SetMorphism'> with domain Partitions of the integer 5 We check that :trac:`28617` is fixed:: - sage: FF = GF(2^20) - sage: f = FF.frobenius_endomorphism() - sage: f == FF.frobenius_endomorphism() + sage: FF = GF(2^20) # optional - sage.libs.combinat + sage: f = FF.frobenius_endomorphism() # optional - sage.libs.combinat + sage: f == FF.frobenius_endomorphism() # optional - sage.libs.combinat True and that :trac:`29632` is fixed:: - sage: R. = QuadraticField(-1)[] - sage: f = R.hom(R.gens(), R) - sage: f.is_identity() + sage: R. = QuadraticField(-1)[] # optional - sage.rings.number_field + sage: f = R.hom(R.gens(), R) # optional - sage.rings.number_field + sage: f.is_identity() # optional - sage.rings.number_field True """ if self is other: @@ -502,17 +507,17 @@ cdef class IdentityMorphism(Morphism): EXAMPLES:: - sage: E = End(Partitions(5)) - sage: E.identity().is_identity() + sage: E = End(Partitions(5)) # optional - sage.combinat + sage: E.identity().is_identity() # optional - sage.combinat True Check that :trac:`15478` is fixed:: - sage: K. = GF(4) - sage: phi = End(K)([z^2]) - sage: R. = K[] - sage: psi = End(R)(phi) - sage: psi.is_identity() + sage: K. = GF(4) # optional - sage.rings.finite_rings + sage: phi = End(K)([z^2]) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: psi = End(R)(phi) # optional - sage.rings.finite_rings + sage: psi.is_identity() # optional - sage.rings.finite_rings False """ return True diff --git a/src/sage/categories/number_fields.py b/src/sage/categories/number_fields.py index 8386ea03912..f3610cd8b7f 100644 --- a/src/sage/categories/number_fields.py +++ b/src/sage/categories/number_fields.py @@ -42,16 +42,16 @@ class NumberFields(Category_singleton): course also in this category:: sage: x = PolynomialRing(RationalField(), 'x').gen() - sage: K = NumberField(x - 1, 'a'); K + sage: K = NumberField(x - 1, 'a'); K # optional - sage.rings.number_field Number Field in a with defining polynomial x - 1 - sage: K in C + sage: K in C # optional - sage.rings.number_field True Number fields all lie in this category, regardless of the name of the variable:: - sage: K = NumberField(x^2 + 1, 'a') - sage: K in C + sage: K = NumberField(x^2 + 1, 'a') # optional - sage.rings.number_field + sage: K in C # optional - sage.rings.number_field True TESTS:: @@ -75,11 +75,11 @@ def __contains__(self, x): EXAMPLES:: sage: x = polygen(QQ, 'x') - sage: NumberField(x^2 + 1, 'a') in NumberFields() + sage: NumberField(x^2 + 1, 'a') in NumberFields() # optional - sage.rings.number_field True - sage: QuadraticField(-97, 'theta') in NumberFields() + sage: QuadraticField(-97, 'theta') in NumberFields() # optional - sage.rings.number_field True - sage: CyclotomicField(97) in NumberFields() + sage: CyclotomicField(97) in NumberFields() # optional - sage.rings.number_field True Note that the rational numbers QQ are a number field:: @@ -105,10 +105,10 @@ def _call_(self, x): sage: C(QQ) Rational Field - sage: C(NumberField(x^2 + 1, 'a')) + sage: C(NumberField(x^2 + 1, 'a')) # optional - sage.rings.number_field Number Field in a with defining polynomial x^2 + 1 - sage: C(UnitGroup(NumberField(x^2 + 1, 'a'))) # indirect doctest + sage: C(UnitGroup(NumberField(x^2 + 1, 'a'))) # indirect doctest # optional - sage.rings.number_field Number Field in a with defining polynomial x^2 + 1 sage: C(ZZ) @@ -151,34 +151,35 @@ def zeta_function(self, prec=53, EXAMPLES:: - sage: K. = NumberField(ZZ['x'].0^2+ZZ['x'].0-1) - sage: Z = K.zeta_function(); Z # optional - sage.symbolic - PARI zeta function associated to Number Field in a with defining polynomial x^2 + x - 1 - sage: Z(-1) # optional - sage.symbolic + sage: K. = NumberField(ZZ['x'].0^2 + ZZ['x'].0 - 1) # optional - sage.rings.number_field + sage: Z = K.zeta_function(); Z # optional - sage.rings.number_field sage.symbolic + PARI zeta function associated to Number Field in a + with defining polynomial x^2 + x - 1 + sage: Z(-1) # optional - sage.rings.number_field sage.symbolic 0.0333333333333333 - sage: x = polygen(QQ, 'x') # optional - sage.symbolic - sage: L. = NumberField([x^2 - 5, x^2 + 3, x^2 + 1]) # optional - sage.symbolic - sage: Z = L.zeta_function() # optional - sage.symbolic - sage: Z(5) # optional - sage.symbolic + sage: x = polygen(QQ, 'x') + sage: L. = NumberField([x^2 - 5, x^2 + 3, x^2 + 1]) # optional - sage.rings.number_field + sage: Z = L.zeta_function() # optional - sage.rings.number_field sage.symbolic + sage: Z(5) # optional - sage.rings.number_field sage.symbolic 1.00199015670185 Using the algorithm "pari":: - sage: K. = NumberField(ZZ['x'].0^2+ZZ['x'].0-1) # optional - sage.symbolic - sage: Z = K.zeta_function(algorithm="pari") # optional - sage.symbolic - sage: Z(-1) # optional - sage.symbolic + sage: K. = NumberField(ZZ['x'].0^2 + ZZ['x'].0 - 1) # optional - sage.rings.number_field + sage: Z = K.zeta_function(algorithm="pari") # optional - sage.rings.number_field sage.symbolic + sage: Z(-1) # optional - sage.rings.number_field sage.symbolic 0.0333333333333333 - sage: x = polygen(QQ, 'x') # optional - sage.symbolic - sage: L. = NumberField([x^2 - 5, x^2 + 3, x^2 + 1]) # optional - sage.symbolic - sage: Z = L.zeta_function(algorithm="pari") # optional - sage.symbolic - sage: Z(5) # optional - sage.symbolic + sage: x = polygen(QQ, 'x') + sage: L. = NumberField([x^2 - 5, x^2 + 3, x^2 + 1]) # optional - sage.rings.number_field + sage: Z = L.zeta_function(algorithm="pari") # optional - sage.rings.number_field sage.symbolic + sage: Z(5) # optional - sage.rings.number_field sage.symbolic 1.00199015670185 TESTS:: - sage: QQ.zeta_function() # optional - sage.symbolic + sage: QQ.zeta_function() # optional - sage.symbolic PARI zeta function associated to Rational Field """ if algorithm == 'gp': @@ -222,8 +223,9 @@ def _test_absolute_disc(self, **options): EXAMPLES:: - sage: S = NumberField(x**3-x-1, 'a') - sage: S._test_absolute_disc() + sage: x = polygen(ZZ, 'x') + sage: S = NumberField(x**3 - x - 1, 'a') # optional - sage.rings.number_field + sage: S._test_absolute_disc() # optional - sage.rings.number_field """ from sage.rings.integer import Integer tester = self._tester(**options) diff --git a/src/sage/categories/polyhedra.py b/src/sage/categories/polyhedra.py index 20e43bff108..7bfb89bd2ae 100644 --- a/src/sage/categories/polyhedra.py +++ b/src/sage/categories/polyhedra.py @@ -26,10 +26,10 @@ class PolyhedralSets(Category_over_base_ring): sage: TestSuite(PolyhedralSets(RDF)).run() - sage: P = Polyhedron() - sage: P.parent().category().element_class + sage: P = Polyhedron() # optional - sage.geometry.polyhedron + sage: P.parent().category().element_class # optional - sage.geometry.polyhedron - sage: P.parent().category().element_class.mro() + sage: P.parent().category().element_class.mro() # optional - sage.geometry.polyhedron [, , , @@ -45,7 +45,7 @@ class PolyhedralSets(Category_over_base_ring): , , ] - sage: isinstance(P, P.parent().category().element_class) + sage: isinstance(P, P.parent().category().element_class) # optional - sage.geometry.polyhedron True """ @@ -53,7 +53,7 @@ def __init__(self, R): """ TESTS:: - sage: PolyhedralSets(AA) + sage: PolyhedralSets(AA) # optional - sage.rings.number_field Category of polyhedral sets over Algebraic Real Field """ Category_over_base_ring.__init__(self, R) diff --git a/src/sage/categories/poor_man_map.py b/src/sage/categories/poor_man_map.py index d0fca4b658d..6912c4878cf 100644 --- a/src/sage/categories/poor_man_map.py +++ b/src/sage/categories/poor_man_map.py @@ -39,7 +39,7 @@ class PoorManMap(sage.structure.sage_object.SageObject): EXAMPLES:: sage: from sage.categories.poor_man_map import PoorManMap - sage: f = PoorManMap(factorial, domain = (1, 2, 3), codomain = (1, 2, 6)) + sage: f = PoorManMap(factorial, domain=(1, 2, 3), codomain=(1, 2, 6)) sage: f A map from (1, 2, 3) to (1, 2, 6) sage: f(3) @@ -48,12 +48,12 @@ class PoorManMap(sage.structure.sage_object.SageObject): The composition of several functions can be created by passing in a tuple of functions:: - sage: i = PoorManMap((factorial, sqrt), domain= (1, 4, 9), codomain = (1, 2, 6)) + sage: i = PoorManMap((factorial, sqrt), domain=(1, 4, 9), codomain=(1, 2, 6)) However, the same effect can also be achieved by just composing maps:: - sage: g = PoorManMap(factorial, domain = (1, 2, 3), codomain = (1, 2, 6)) - sage: h = PoorManMap(sqrt, domain = (1, 4, 9), codomain = (1, 2, 3)) + sage: g = PoorManMap(factorial, domain=(1, 2, 3), codomain=(1, 2, 6)) + sage: h = PoorManMap(sqrt, domain=(1, 4, 9), codomain=(1, 2, 3)) sage: i == g*h True @@ -63,8 +63,8 @@ def __init__(self, function, domain=None, codomain=None, name=None): TESTS:: sage: from sage.categories.poor_man_map import PoorManMap - sage: f = PoorManMap(factorial, domain = (1, 2, 3), codomain = (1, 2, 6)) - sage: g = PoorManMap(sqrt, domain = (1, 4, 9), codomain = (1, 2, 6)) + sage: f = PoorManMap(factorial, domain=(1, 2, 3), codomain=(1, 2, 6)) + sage: g = PoorManMap(sqrt, domain=(1, 4, 9), codomain=(1, 2, 6)) sage: TestSuite(f).run() sage: TestSuite(f*g).run() @@ -85,11 +85,11 @@ def _repr_(self): sage: from sage.categories.poor_man_map import PoorManMap sage: PoorManMap(lambda x: x+2) # indirect doctest A map - sage: PoorManMap(lambda x: x+2, domain = (1,2,3)) + sage: PoorManMap(lambda x: x+2, domain=(1,2,3)) A map from (1, 2, 3) - sage: PoorManMap(lambda x: x+2, domain = (1,2,3)) + sage: PoorManMap(lambda x: x+2, domain=(1,2,3)) A map from (1, 2, 3) - sage: PoorManMap(lambda x: x+2, codomain = (3,4,5)) + sage: PoorManMap(lambda x: x+2, codomain=(3,4,5)) A map to (3, 4, 5) """ @@ -104,7 +104,7 @@ def domain(self): EXAMPLES:: sage: from sage.categories.poor_man_map import PoorManMap - sage: PoorManMap(lambda x: x+1, domain = (1,2,3), codomain = (2,3,4)).domain() + sage: PoorManMap(lambda x: x+1, domain=(1,2,3), codomain=(2,3,4)).domain() (1, 2, 3) """ return self._domain @@ -116,7 +116,7 @@ def codomain(self): EXAMPLES:: sage: from sage.categories.poor_man_map import PoorManMap - sage: PoorManMap(lambda x: x+1, domain = (1,2,3), codomain = (2,3,4)).codomain() + sage: PoorManMap(lambda x: x+1, domain=(1,2,3), codomain=(2,3,4)).codomain() (2, 3, 4) """ return self._codomain @@ -128,12 +128,12 @@ def __eq__(self, other): EXAMPLES:: sage: from sage.categories.poor_man_map import PoorManMap - sage: f = PoorManMap(factorial, domain = (1,2,3), codomain = (1,2,6)) - sage: g = PoorManMap(factorial, domain = (1,2,3), codomain = (1,2,6)) - sage: h1 = PoorManMap(factorial, domain = (1,2,3), codomain = (1,2,6,8)) - sage: h2 = PoorManMap(factorial, domain = (1,2,3), codomain = (1,2,6,8)) - sage: h3 = PoorManMap(factorial, domain = (1,2,3,4), codomain = (1,2,6)) - sage: h4 = PoorManMap(lambda x: x, domain = (1,2,3), codomain = (1,2,6)) + sage: f = PoorManMap(factorial, domain=(1,2,3), codomain=(1,2,6)) + sage: g = PoorManMap(factorial, domain=(1,2,3), codomain=(1,2,6)) + sage: h1 = PoorManMap(factorial, domain=(1,2,3), codomain=(1,2,6,8)) + sage: h2 = PoorManMap(factorial, domain=(1,2,3), codomain=(1,2,6,8)) + sage: h3 = PoorManMap(factorial, domain=(1,2,3,4), codomain=(1,2,6)) + sage: h4 = PoorManMap(lambda x: x, domain=(1,2,3), codomain=(1,2,6)) sage: f == g, f == h1, f == h2, f == h3, f == h4, f == 1, 1 == f (True, False, False, False, False, False, False) @@ -153,12 +153,12 @@ def __ne__(self, other): EXAMPLES:: sage: from sage.categories.poor_man_map import PoorManMap - sage: f = PoorManMap(factorial, domain = (1,2,3), codomain = (1,2,6)) - sage: g = PoorManMap(factorial, domain = (1,2,3), codomain = (1,2,6)) - sage: h1 = PoorManMap(factorial, domain = (1,2,3), codomain = (1,2,6,8)) - sage: h2 = PoorManMap(factorial, domain = (1,2,3), codomain = (1,2,6,8)) - sage: h3 = PoorManMap(factorial, domain = (1,2,3,4), codomain = (1,2,6)) - sage: h4 = PoorManMap(lambda x: x, domain = (1,2,3), codomain = (1,2,6)) + sage: f = PoorManMap(factorial, domain=(1,2,3), codomain=(1,2,6)) + sage: g = PoorManMap(factorial, domain=(1,2,3), codomain=(1,2,6)) + sage: h1 = PoorManMap(factorial, domain=(1,2,3), codomain=(1,2,6,8)) + sage: h2 = PoorManMap(factorial, domain=(1,2,3), codomain=(1,2,6,8)) + sage: h3 = PoorManMap(factorial, domain=(1,2,3,4), codomain=(1,2,6)) + sage: h4 = PoorManMap(lambda x: x, domain=(1,2,3), codomain=(1,2,6)) sage: f != g, f != h1, f != h2, f != h3, f != h4, f != 1, 1 != f (False, True, True, True, True, True, True) @@ -172,8 +172,8 @@ def __hash__(self): TESTS:: sage: from sage.categories.poor_man_map import PoorManMap - sage: f = PoorManMap(factorial, domain = (1,2,3), codomain = (1,2,6)) - sage: g = PoorManMap(factorial, domain = (1,2,3), codomain = (1,2,6)) + sage: f = PoorManMap(factorial, domain=(1,2,3), codomain=(1,2,6)) + sage: g = PoorManMap(factorial, domain=(1,2,3), codomain=(1,2,6)) sage: hash(f) == hash(g) True @@ -194,8 +194,8 @@ def __mul__(self, other): EXAMPLES:: sage: from sage.categories.poor_man_map import PoorManMap - sage: f = PoorManMap(lambda x: x+1, domain = (1,2,3), codomain = (2,3,4)) - sage: g = PoorManMap(lambda x: -x, domain = (2,3,4), codomain = (-2,-3,-4)) + sage: f = PoorManMap(lambda x: x+1, domain=(1,2,3), codomain=(2,3,4)) + sage: g = PoorManMap(lambda x: -x, domain=(2,3,4), codomain=(-2,-3,-4)) sage: g*f A map from (1, 2, 3) to (-2, -3, -4) @@ -208,8 +208,8 @@ def __mul__(self, other): But it is detected here:: - sage: g = PoorManMap(factorial, domain = ZZ, codomain = ZZ) - sage: h = PoorManMap(sqrt, domain = RR, codomain = CC) + sage: g = PoorManMap(factorial, domain=ZZ, codomain=ZZ) + sage: h = PoorManMap(sqrt, domain=RR, codomain=CC) sage: g*h Traceback (most recent call last): ... @@ -248,11 +248,11 @@ def __call__(self, *args): EXAMPLES:: sage: from sage.categories.poor_man_map import PoorManMap - sage: f = PoorManMap(lambda x: x+1, domain = (1,2,3), codomain = (2,3,4)) + sage: f = PoorManMap(lambda x: x+1, domain=(1,2,3), codomain=(2,3,4)) sage: f(2) 3 - sage: g = PoorManMap(lambda x: -x, domain = (2,3,4), codomain = (-2,-3,-4)) + sage: g = PoorManMap(lambda x: -x, domain=(2,3,4), codomain=(-2,-3,-4)) sage: (g*f)(2) -3 @@ -266,8 +266,8 @@ def _sympy_(self): EXAMPLES:: sage: from sage.categories.poor_man_map import PoorManMap - sage: h = PoorManMap(sin, domain=RR, codomain=RR) - sage: h._sympy_() + sage: h = PoorManMap(sin, domain=RR, codomain=RR) # optional - sage.symbolic + sage: h._sympy_() # optional - sage.symbolic sin """ from sympy import Lambda, sympify diff --git a/src/sage/categories/posets.py b/src/sage/categories/posets.py index b1a2ba1942d..24a83e02dbd 100644 --- a/src/sage/categories/posets.py +++ b/src/sage/categories/posets.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.graphs, sage.combinat r""" Posets """ @@ -112,7 +113,8 @@ def example(self, choice=None): An example of a poset: sets ordered by inclusion sage: Posets().example("facade") - An example of a facade poset: the positive integers ordered by divisibility + An example of a facade poset: + the positive integers ordered by divisibility """ from sage.categories.examples.posets import FiniteSetsOrderedByInclusion, PositiveIntegersOrderedByDivisibilityFacade if choice == "facade": @@ -457,7 +459,8 @@ def is_order_ideal(self, o): EXAMPLES:: - sage: P = Poset((divisors(12), attrcall("divides")), facade=True, linear_extension=True) + sage: P = Poset((divisors(12), attrcall("divides")), + ....: facade=True, linear_extension=True) sage: sorted(P.list()) [1, 2, 3, 4, 6, 12] sage: P.is_order_ideal([1, 3]) @@ -483,7 +486,8 @@ def is_order_filter(self, o): EXAMPLES:: - sage: P = Poset((divisors(12), attrcall("divides")), facade=True, linear_extension=True) + sage: P = Poset((divisors(12), attrcall("divides")), + ....: facade=True, linear_extension=True) sage: sorted(P.list()) [1, 2, 3, 4, 6, 12] sage: P.is_order_filter([4, 12]) @@ -527,7 +531,8 @@ def is_chain_of_poset(self, o, ordered=False): EXAMPLES:: - sage: P = Poset((divisors(12), attrcall("divides")), facade=True, linear_extension=True) + sage: P = Poset((divisors(12), attrcall("divides")), + ....: facade=True, linear_extension=True) sage: sorted(P.list()) [1, 2, 3, 4, 6, 12] sage: P.is_chain_of_poset([1, 3]) @@ -575,11 +580,16 @@ def is_chain_of_poset(self, o, ordered=False): sage: from sage.categories.examples.posets import FiniteSetsOrderedByInclusion sage: R = FiniteSetsOrderedByInclusion() - sage: R.is_chain_of_poset([R(set([3, 1, 2])), R(set([1, 4])), R(set([4, 5]))]) + sage: R.is_chain_of_poset([R(set([3, 1, 2])), + ....: R(set([1, 4])), + ....: R(set([4, 5]))]) False - sage: R.is_chain_of_poset([R(set([3, 1, 2])), R(set([1, 2])), R(set([1]))], ordered=True) + sage: R.is_chain_of_poset([R(set([3, 1, 2])), + ....: R(set([1, 2])), + ....: R(set([1]))], ordered=True) False - sage: R.is_chain_of_poset([R(set([3, 1, 2])), R(set([1, 2])), R(set([1]))]) + sage: R.is_chain_of_poset([R(set([3, 1, 2])), + ....: R(set([1, 2])), R(set([1]))]) True sage: from sage.categories.examples.posets import PositiveIntegersOrderedByDivisibilityFacade @@ -632,7 +642,8 @@ def is_antichain_of_poset(self, o): EXAMPLES:: - sage: P = Poset((divisors(12), attrcall("divides")), facade=True, linear_extension=True) + sage: P = Poset((divisors(12), attrcall("divides")), + ....: facade=True, linear_extension=True) sage: sorted(P.list()) [1, 2, 3, 4, 6, 12] sage: P.is_antichain_of_poset([1, 3]) @@ -653,9 +664,11 @@ def is_antichain_of_poset(self, o): False sage: P.is_antichain_of_poset([6, 4]) True - sage: P.is_antichain_of_poset(i for i in divisors(12) if (2 < i and i < 6)) + sage: P.is_antichain_of_poset(i for i in divisors(12) + ....: if (2 < i and i < 6)) True - sage: P.is_antichain_of_poset(i for i in divisors(12) if (2 <= i and i < 6)) + sage: P.is_antichain_of_poset(i for i in divisors(12) + ....: if (2 <= i and i < 6)) False sage: Q = Poset({2: [3, 1], 3: [4], 1: [4]}) @@ -680,9 +693,11 @@ def is_antichain_of_poset(self, o): sage: from sage.categories.examples.posets import FiniteSetsOrderedByInclusion sage: R = FiniteSetsOrderedByInclusion() - sage: R.is_antichain_of_poset([R(set([3, 1, 2])), R(set([1, 4])), R(set([4, 5]))]) + sage: R.is_antichain_of_poset([R(set([3, 1, 2])), + ....: R(set([1, 4])), R(set([4, 5]))]) True - sage: R.is_antichain_of_poset([R(set([3, 1, 2, 4])), R(set([1, 4])), R(set([4, 5]))]) + sage: R.is_antichain_of_poset([R(set([3, 1, 2, 4])), + ....: R(set([1, 4])), R(set([4, 5]))]) False """ return all(not self.lt(x,y) for x in o for y in o) diff --git a/src/sage/categories/primer.py b/src/sage/categories/primer.py index 7ecc75e711a..84ab37f34b7 100644 --- a/src/sage/categories/primer.py +++ b/src/sage/categories/primer.py @@ -75,15 +75,15 @@ Similar objects should behave similarly:: - sage: Permutations(5).cardinality() + sage: Permutations(5).cardinality() # optional - sage.combinat 120 - sage: GL(2,2).cardinality() + sage: GL(2,2).cardinality() # optional - sage.groups 6 - sage: A = random_matrix(ZZ,6,3,x=7) - sage: L = LatticePolytope(A.rows()) - sage: L.npoints() # oops! # random + sage: A = random_matrix(ZZ, 6, 3, x=7) # optional - sage.modules + sage: L = LatticePolytope(A.rows()) # optional - sage.geometry.polyhedron + sage: L.npoints() # oops! # random # optional - sage.geometry.polyhedron 37 - How to ensure robustness? @@ -98,8 +98,9 @@ :: - sage: m = random_matrix(QQ, 4, algorithm='echelonizable', rank=3, upper_bound=60) - sage: m^8 == m*m*m*m*m*m*m*m == ((m^2)^2)^2 + sage: m = random_matrix(QQ, 4, algorithm='echelonizable', # optional - sage.modules + ....: rank=3, upper_bound=60) + sage: m^8 == m*m*m*m*m*m*m*m == ((m^2)^2)^2 # optional - sage.modules True We want to implement binary powering only once, as *generic* code @@ -130,7 +131,7 @@ That's our bookshelf! And it's used in many places:: - sage: GL(2,ZZ) in Monoids() + sage: GL(2, ZZ) in Monoids() # optional - sage.modules True sage: NN in Monoids() True @@ -168,20 +169,20 @@ Each set in Sage knows which bookshelf of generic algorithms it can use, that is to which category it belongs:: - sage: G = GL(2,ZZ) - sage: G.category() + sage: G = GL(2, ZZ) # optional - sage.modules + sage: G.category() # optional - sage.modules Category of infinite groups In fact a group is a semigroup, and Sage knows about this:: sage: Groups().is_subcategory(Semigroups()) True - sage: G in Semigroups() + sage: G in Semigroups() # optional - sage.modules True Altogether, our group gets algorithms from a bunch of bookshelves:: - sage: G.categories() + sage: G.categories() # optional - sage.modules [Category of infinite groups, Category of groups, Category of monoids, ..., Category of magmas, @@ -189,19 +190,19 @@ Those can be viewed graphically:: - sage: g = Groups().category_graph() - sage: g.set_latex_options(format="dot2tex") - sage: view(g) # not tested + sage: g = Groups().category_graph() # optional - sage.modules sage.graphs + sage: g.set_latex_options(format="dot2tex") # optional - sage.modules sage.graphs + sage: view(g) # not tested # optional - sage.modules sage.graphs sage.plot In case ``dot2tex`` is not available, you can use instead:: - sage: g.show(vertex_shape=None, figsize=20) + sage: g.show(vertex_shape=None, figsize=20) # optional - sage.modules sage.graphs sage.plot Here is an overview of all categories in Sage:: - sage: g = sage.categories.category.category_graph() - sage: g.set_latex_options(format="dot2tex") - sage: view(g) # not tested + sage: g = sage.categories.category.category_graph() # optional - sage.modules sage.graphs + sage: g.set_latex_options(format="dot2tex") # optional - sage.modules sage.graphs + sage: view(g) # not tested # optional - sage.modules sage.graphs sage.plot Wrap-up: generic algorithms in Sage are organized in a hierarchy of bookshelves modelled upon the usual hierarchy of categories provided @@ -370,9 +371,9 @@ Category of sets with partial maps, Category of objects] - sage: g = EuclideanDomains().category_graph() - sage: g.set_latex_options(format="dot2tex") - sage: view(g) # not tested + sage: g = EuclideanDomains().category_graph() # optional - sage.graphs + sage: g.set_latex_options(format="dot2tex") # optional - sage.graphs + sage: view(g) # not tested # optional - sage.graphs sage.plot A bit of help from computer science =================================== @@ -406,11 +407,11 @@ class implements: sage: i.factor() 2^2 * 3 - sage: x = var('x') # optional - sage.symbolic - sage: p = 6*x^2 + 12*x + 6 # optional - sage.symbolic - sage: type(p) # optional - sage.symbolic + sage: x = var('x') # optional - sage.symbolic + sage: p = 6*x^2 + 12*x + 6 # optional - sage.symbolic + sage: type(p) # optional - sage.symbolic - sage: p.factor() # optional - sage.symbolic + sage: p.factor() # optional - sage.symbolic 6*(x + 1)^2 sage: R. = PolynomialRing(QQ, sparse=True) @@ -466,9 +467,9 @@ class implements: hierarchy of categories (bookshelves). Here is for example a piece of the hierarchy of classes for an element of a group of permutations:: - sage: P = Permutations(4) - sage: m = P.an_element() - sage: for cls in m.__class__.mro(): print(cls) + sage: P = Permutations(4) # optional - sage.combinat + sage: m = P.an_element() # optional - sage.combinat + sage: for cls in m.__class__.mro(): print(cls) # optional - sage.combinat @@ -486,9 +487,9 @@ class implements: The full hierarchy is best viewed graphically:: - sage: g = class_graph(m.__class__) - sage: g.set_latex_options(format="dot2tex") - sage: view(g) # not tested + sage: g = class_graph(m.__class__) # optional - sage.combinat sage.graphs + sage: g.set_latex_options(format="dot2tex") # optional - sage.combinat sage.graphs + sage: view(g) # not tested # optional - sage.combinat sage.graphs sage.plot Parallel hierarchy of classes for parents ----------------------------------------- @@ -522,13 +523,13 @@ class implements: modelled by instances of some (hierarchy of) classes. For example, our group `G` is an instance of the following class:: - sage: G = GL(2,ZZ) - sage: type(G) + sage: G = GL(2, ZZ) # optional - sage.modules + sage: type(G) # optional - sage.modules Here is a piece of the hierarchy of classes above it:: - sage: for cls in G.__class__.mro(): print(cls) + sage: for cls in G.__class__.mro(): print(cls) # optional - sage.modules ... @@ -540,10 +541,10 @@ class implements: categories and parallel to that we had seen for the elements. This is best viewed graphically:: - sage: g = class_graph(m.__class__) - sage: g.relabel(lambda x: x.replace("_",r"\_")) - sage: g.set_latex_options(format="dot2tex") - sage: view(g) # not tested + sage: g = class_graph(m.__class__) # optional - sage.modules sage.graphs + sage: g.relabel(lambda x: x.replace("_",r"\_")) # optional - sage.modules sage.graphs + sage: g.set_latex_options(format="dot2tex") # optional - sage.modules sage.graphs + sage: view(g) # not tested # optional - sage.modules sage.graphs sage.plot .. NOTE:: @@ -724,7 +725,7 @@ class SubcategoryMethods: Note that categories themselves are naturally modelled by instances because they can have operations of their own. An important one is:: - sage: Groups().example() + sage: Groups().example() # optional - sage.modules General Linear Group of degree 4 over Rational Field which gives an example of object of the category. Besides illustrating @@ -1017,16 +1018,17 @@ class SubcategoryMethods: example, permutation groups are by default in the category of finite permutation groups (no surprise):: - sage: P = PermutationGroup([[(1,2,3)]]); P + sage: P = PermutationGroup([[(1,2,3)]]); P # optional - sage.combinat Permutation Group with generators [(1,2,3)] - sage: P.category() + sage: P.category() # optional - sage.combinat Category of finite enumerated permutation groups In this case, the group is commutative, so we can specify this:: - sage: P = PermutationGroup([[(1,2,3)]], category=PermutationGroups().Finite().Commutative()); P + sage: P = PermutationGroup([[(1,2,3)]], # optional - sage.combinat + ....: category=PermutationGroups().Finite().Commutative()); P Permutation Group with generators [(1,2,3)] - sage: P.category() + sage: P.category() # optional - sage.combinat Category of finite enumerated commutative permutation groups This feature can even be used, typically in experimental code, to add @@ -1041,18 +1043,18 @@ class SubcategoryMethods: ....: class ElementMethods: ....: def bar(self): print("bar") - sage: P = PermutationGroup([[(1,2,3)]], category=Foos()) - sage: P.foo() + sage: P = PermutationGroup([[(1,2,3)]], category=Foos()) # optional - sage.combinat + sage: P.foo() # optional - sage.combinat foo - sage: p = P.an_element() - sage: p.bar() + sage: p = P.an_element() # optional - sage.combinat + sage: p.bar() # optional - sage.combinat bar In the long run, it would be thinkable to use this idiom to implement forgetful functors; for example the above group could be constructed as a plain set with:: - sage: P = PermutationGroup([[(1,2,3)]], category=Sets()) # todo: not implemented + sage: P = PermutationGroup([[(1,2,3)]], category=Sets()) # todo: not implemented # optional - sage.combinat At this stage though, this is still to be explored for robustness and practicality. For now, most parents that accept a category argument @@ -1100,9 +1102,9 @@ class SubcategoryMethods: Let for example `A` and `B` be two parents, and let us construct the Cartesian product `A \times B \times B`:: - sage: A = AlgebrasWithBasis(QQ).example(); A.rename("A") - sage: B = HopfAlgebrasWithBasis(QQ).example(); B.rename("B") - sage: C = cartesian_product([A, B, B]); C + sage: A = AlgebrasWithBasis(QQ).example(); A.rename("A") # optional - sage.combinat sage.modules + sage: B = HopfAlgebrasWithBasis(QQ).example(); B.rename("B") # optional - sage.combinat sage.modules + sage: C = cartesian_product([A, B, B]); C # optional - sage.combinat sage.modules A (+) B (+) B In which category should this new parent be? Since `A` and `B` are @@ -1111,14 +1113,14 @@ class SubcategoryMethods: are monoids, `A \times B \times B` is naturally endowed with a monoid structure for pointwise multiplication:: - sage: C in Monoids() + sage: C in Monoids() # optional - sage.combinat sage.modules True the unit being the Cartesian product of the units of the operands:: - sage: C.one() + sage: C.one() # optional - sage.combinat sage.modules B[(0, word: )] + B[(1, ())] + B[(2, ())] - sage: cartesian_product([A.one(), B.one(), B.one()]) + sage: cartesian_product([A.one(), B.one(), B.one()]) # optional - sage.combinat sage.modules B[(0, word: )] + B[(1, ())] + B[(2, ())] The pointwise product can be implemented generically for all magmas @@ -1126,7 +1128,7 @@ class SubcategoryMethods: constructed as Cartesian products. It's thus implemented in the :class:`Magmas` category:: - sage: C.product.__module__ + sage: C.product.__module__ # optional - sage.combinat sage.modules 'sage.categories.magmas' More specifically, keeping on using nested classes to structure the @@ -1158,7 +1160,7 @@ class naming and introspection. Sage currently works around the Let us now look at the categories of ``C``:: - sage: C.categories() + sage: C.categories() # optional - sage.combinat sage.modules [Category of finite dimensional Cartesian products of algebras with basis over Rational Field, ... Category of Cartesian products of algebras over Rational Field, ... Category of Cartesian products of semigroups, Category of semigroups, ... @@ -1369,13 +1371,14 @@ class naming and introspection. Sage currently works around the sage: C = (Magmas() & AdditiveMagmas()).Distributive(); C Category of distributive magmas and additive magmas - sage: C.Associative().AdditiveAssociative().AdditiveCommutative().AdditiveUnital().AdditiveInverse() + sage: CAA = C.Associative().AdditiveAssociative() + sage: CAA.AdditiveCommutative().AdditiveUnital().AdditiveInverse() Category of rngs - sage: C.Associative().AdditiveAssociative().AdditiveCommutative().AdditiveUnital().Unital() + sage: CAA.AdditiveCommutative().AdditiveUnital().Unital() Category of semirings - sage: C.Associative().AdditiveAssociative().AdditiveCommutative().AdditiveUnital().AdditiveInverse().Unital() + sage: CAA.AdditiveCommutative().AdditiveUnital().AdditiveInverse().Unital() Category of rings sage: Rings().Division() @@ -1389,9 +1392,9 @@ class naming and introspection. Sage currently works around the or for more advanced categories:: - sage: g = HopfAlgebras(QQ).WithBasis().Graded().Connected().category_graph() - sage: g.set_latex_options(format="dot2tex") - sage: view(g) # not tested + sage: g = HopfAlgebras(QQ).WithBasis().Graded().Connected().category_graph() # optional - sage.graphs + sage: g.set_latex_options(format="dot2tex") # optional - sage.graphs + sage: view(g) # not tested # optional - sage.graphs sage.plot Difference between axioms and regressive covariant functorial constructions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1413,7 +1416,7 @@ class naming and introspection. Sage currently works around the A finite dimensional algebra is also a finite dimensional module:: - sage: Algebras(QQ).FiniteDimensional().is_subcategory( Modules(QQ).FiniteDimensional() ) + sage: Algebras(QQ).FiniteDimensional().is_subcategory(Modules(QQ).FiniteDimensional()) True Similarly a graded algebra is also a graded module:: diff --git a/src/sage/categories/principal_ideal_domains.py b/src/sage/categories/principal_ideal_domains.py index 2821fdf0ef6..fa8b2632cc1 100644 --- a/src/sage/categories/principal_ideal_domains.py +++ b/src/sage/categories/principal_ideal_domains.py @@ -70,22 +70,22 @@ def _test_gcd_vs_xgcd(self, **options): sage: ZZ._test_gcd_vs_xgcd() sage: QQ._test_gcd_vs_xgcd() sage: QQ['x']._test_gcd_vs_xgcd() - sage: QQbar['x']._test_gcd_vs_xgcd() + sage: QQbar['x']._test_gcd_vs_xgcd() # optional - sage.rings.number_field sage: RR._test_gcd_vs_xgcd() sage: RR['x']._test_gcd_vs_xgcd() A slightly more involved example of polynomial ring with a non UFD base ring:: - sage: K = QuadraticField(5) - sage: O = K.maximal_order() - sage: O in UniqueFactorizationDomains() + sage: K = QuadraticField(5) # optional - sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.rings.number_field + sage: O in UniqueFactorizationDomains() # optional - sage.rings.number_field False - sage: R = PolynomialRing(O, 'x') - sage: F = R.fraction_field() - sage: F in PrincipalIdealDomains() + sage: R = PolynomialRing(O, 'x') # optional - sage.rings.number_field + sage: F = R.fraction_field() # optional - sage.rings.number_field + sage: F in PrincipalIdealDomains() # optional - sage.rings.number_field True - sage: F._test_gcd_vs_xgcd() + sage: F._test_gcd_vs_xgcd() # optional - sage.rings.number_field """ tester = self._tester(**options) elts = list(tester.some_elements()) diff --git a/src/sage/categories/pushout.py b/src/sage/categories/pushout.py index 71c20a6d82b..69b936bb3ff 100644 --- a/src/sage/categories/pushout.py +++ b/src/sage/categories/pushout.py @@ -107,17 +107,20 @@ class ConstructionFunctor(Functor): sage: P. = ZZ[] sage: F = P.construction()[0]; F MPoly[x,y] - sage: A. = GF(5)[] - sage: f = A.hom([a+b,a-b],A) - sage: F(A) - Multivariate Polynomial Ring in x, y over Multivariate Polynomial Ring in a, b over Finite Field of size 5 - sage: F(f) - Ring endomorphism of Multivariate Polynomial Ring in x, y over Multivariate Polynomial Ring in a, b over Finite Field of size 5 + sage: A. = GF(5)[] # optional - sage.rings.finite_rings + sage: f = A.hom([a + b, a - b], A) # optional - sage.rings.finite_rings + sage: F(A) # optional - sage.rings.finite_rings + Multivariate Polynomial Ring in x, y + over Multivariate Polynomial Ring in a, b over Finite Field of size 5 + sage: F(f) # optional - sage.rings.finite_rings + Ring endomorphism of Multivariate Polynomial Ring in x, y + over Multivariate Polynomial Ring in a, b over Finite Field of size 5 Defn: Induced from base ring by - Ring endomorphism of Multivariate Polynomial Ring in a, b over Finite Field of size 5 + Ring endomorphism of Multivariate Polynomial Ring in a, b + over Finite Field of size 5 Defn: a |--> a + b b |--> a - b - sage: F(f)(F(A)(x)*a) + sage: F(f)(F(A)(x)*a) # optional - sage.rings.finite_rings (a + b)*x """ @@ -430,22 +433,27 @@ class CompositeConstructionFunctor(ConstructionFunctor): EXAMPLES:: sage: from sage.categories.pushout import CompositeConstructionFunctor - sage: F = CompositeConstructionFunctor(QQ.construction()[0],ZZ['x'].construction()[0],QQ.construction()[0],ZZ['y'].construction()[0]) + sage: F = CompositeConstructionFunctor(QQ.construction()[0], ZZ['x'].construction()[0], + ....: QQ.construction()[0], ZZ['y'].construction()[0]) sage: F Poly[y](FractionField(Poly[x](FractionField(...)))) sage: F == loads(dumps(F)) True sage: F == CompositeConstructionFunctor(*F.all) True - sage: F(GF(2)['t']) - Univariate Polynomial Ring in y over Fraction Field of Univariate Polynomial Ring in x over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 2 (using GF2X) + sage: F(GF(2)['t']) # optional - sage.rings.finite_rings + Univariate Polynomial Ring in y + over Fraction Field of Univariate Polynomial Ring in x + over Fraction Field of Univariate Polynomial Ring in t + over Finite Field of size 2 (using GF2X) """ def __init__(self, *args): """ TESTS:: sage: from sage.categories.pushout import CompositeConstructionFunctor - sage: F = CompositeConstructionFunctor(QQ.construction()[0],ZZ['x'].construction()[0],QQ.construction()[0],ZZ['y'].construction()[0]) + sage: F = CompositeConstructionFunctor(QQ.construction()[0], ZZ['x'].construction()[0], + ....: QQ.construction()[0], ZZ['y'].construction()[0]) sage: F Poly[y](FractionField(Poly[x](FractionField(...)))) sage: F == CompositeConstructionFunctor(*F.all) @@ -587,7 +595,10 @@ def expand(self): EXAMPLES:: sage: from sage.categories.pushout import CompositeConstructionFunctor - sage: F = CompositeConstructionFunctor(QQ.construction()[0],ZZ['x'].construction()[0],QQ.construction()[0],ZZ['y'].construction()[0]) + sage: F = CompositeConstructionFunctor(QQ.construction()[0], + ....: ZZ['x'].construction()[0], + ....: QQ.construction()[0], + ....: ZZ['y'].construction()[0]) sage: F Poly[y](FractionField(Poly[x](FractionField(...)))) sage: prod(F.expand()) == F @@ -801,32 +812,32 @@ class PolynomialFunctor(ConstructionFunctor): EXAMPLES:: sage: P = ZZ['t'].construction()[0] - sage: P(GF(3)) + sage: P(GF(3)) # optional - sage.rings.finite_rings Univariate Polynomial Ring in t over Finite Field of size 3 - sage: P == loads(dumps(P)) + sage: P == loads(dumps(P)) # optional - sage.rings.finite_rings True - sage: R. = GF(5)[] - sage: f = R.hom([x+2*y,3*x-y],R) - sage: P(f)((x+y)*P(R).0) + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: f = R.hom([x + 2*y, 3*x - y], R) # optional - sage.rings.finite_rings + sage: P(f)((x+y) * P(R).0) # optional - sage.rings.finite_rings (-x + y)*t By :trac:`9944`, the construction functor distinguishes sparse and dense polynomial rings. Before, the following example failed:: - sage: R. = PolynomialRing(GF(5), sparse=True) - sage: F,B = R.construction() - sage: F(B) is R + sage: R. = PolynomialRing(GF(5), sparse=True) # optional - sage.rings.finite_rings + sage: F, B = R.construction() # optional - sage.rings.finite_rings + sage: F(B) is R # optional - sage.rings.finite_rings True sage: S. = PolynomialRing(ZZ) - sage: R.has_coerce_map_from(S) + sage: R.has_coerce_map_from(S) # optional - sage.rings.finite_rings False - sage: S.has_coerce_map_from(R) + sage: S.has_coerce_map_from(R) # optional - sage.rings.finite_rings False - sage: S.0 + R.0 + sage: S.0 + R.0 # optional - sage.rings.finite_rings 2*x - sage: (S.0 + R.0).parent() + sage: (S.0 + R.0).parent() # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 5 - sage: (S.0 + R.0).parent().is_sparse() + sage: (S.0 + R.0).parent().is_sparse() # optional - sage.rings.finite_rings False """ @@ -838,7 +849,7 @@ def __init__(self, var, multi_variate=False, sparse=False, implementation=None): sage: from sage.categories.pushout import PolynomialFunctor sage: P = PolynomialFunctor('x') - sage: P(GF(3)) + sage: P(GF(3)) # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 3 There is an optional parameter ``multi_variate``, but @@ -865,7 +876,7 @@ def _apply_functor(self, R): TESTS:: sage: P = ZZ['x'].construction()[0] - sage: P(GF(3)) # indirect doctest + sage: P(GF(3)) # indirect doctest # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 3 """ @@ -882,7 +893,7 @@ def _apply_functor_to_morphism(self, f): TESTS:: sage: P = ZZ['x'].construction()[0] - sage: P(ZZ.hom(GF(3))) # indirect doctest + sage: P(ZZ.hom(GF(3))) # indirect doctest # optional - sage.rings.finite_rings Ring morphism: From: Univariate Polynomial Ring in x over Integer Ring To: Univariate Polynomial Ring in x over Finite Field of size 3 @@ -992,17 +1003,19 @@ class MultiPolynomialFunctor(ConstructionFunctor): sage: P. = ZZ[] sage: F = P.construction()[0]; F MPoly[x,y] - sage: A. = GF(5)[] - sage: F(A) - Multivariate Polynomial Ring in x, y over Multivariate Polynomial Ring in a, b over Finite Field of size 5 - sage: f = A.hom([a+b,a-b],A) - sage: F(f) - Ring endomorphism of Multivariate Polynomial Ring in x, y over Multivariate Polynomial Ring in a, b over Finite Field of size 5 + sage: A. = GF(5)[] # optional - sage.rings.finite_rings + sage: F(A) # optional - sage.rings.finite_rings + Multivariate Polynomial Ring in x, y + over Multivariate Polynomial Ring in a, b over Finite Field of size 5 + sage: f = A.hom([a+b, a-b], A) # optional - sage.rings.finite_rings + sage: F(f) # optional - sage.rings.finite_rings + Ring endomorphism of Multivariate Polynomial Ring in x, y + over Multivariate Polynomial Ring in a, b over Finite Field of size 5 Defn: Induced from base ring by Ring endomorphism of Multivariate Polynomial Ring in a, b over Finite Field of size 5 Defn: a |--> a + b b |--> a - b - sage: F(f)(F(A)(x)*a) + sage: F(f)(F(A)(x)*a) # optional - sage.rings.finite_rings (a + b)*x """ @@ -1153,10 +1166,12 @@ def expand(self): sage: x + s Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for +: 'Multivariate Polynomial Ring in x, y, z over Integer Ring' and 'Multivariate Polynomial Ring in y, s over Rational Field' + TypeError: unsupported operand parent(s) for +: + 'Multivariate Polynomial Ring in x, y, z over Integer Ring' and + 'Multivariate Polynomial Ring in y, s over Rational Field' sage: R = PolynomialRing(ZZ, 'x', 50) - sage: S = PolynomialRing(GF(5), 'x', 20) - sage: R.gen(0) + S.gen(0) + sage: S = PolynomialRing(GF(5), 'x', 20) # optional - sage.rings.finite_rings + sage: R.gen(0) + S.gen(0) # optional - sage.rings.finite_rings 2*x0 """ if len(self.vars) <= 1: @@ -1203,7 +1218,7 @@ class InfinitePolynomialFunctor(ConstructionFunctor): sage: B. = PolynomialRing(QQ, order='lex') sage: B.construction() (MPoly[x,y,a_3,a_1], Rational Field) - sage: A.construction()[0]*B.construction()[0] + sage: A.construction()[0] * B.construction()[0] InfPoly{[a,b], "lex", "dense"}(MPoly[x,y](...)) Apparently the variables `a_1,a_3` of the polynomial ring are merged with the variables @@ -1211,7 +1226,8 @@ class InfinitePolynomialFunctor(ConstructionFunctor): However, if the polynomial ring was given a different ordering, merging would not be allowed, resulting in a name conflict:: - sage: A.construction()[0]*PolynomialRing(QQ,names=['x','y','a_3','a_1']).construction()[0] + sage: R = PolynomialRing(QQ, names=['x','y','a_3','a_1']) + sage: A.construction()[0] * R.construction()[0] Traceback (most recent call last): ... CoercionException: Incompatible term orders lex, degrevlex @@ -1219,25 +1235,30 @@ class InfinitePolynomialFunctor(ConstructionFunctor): In an infinite polynomial ring with generator `a_\ast`, the variable `a_3` will always be greater than the variable `a_1`. Hence, the orders are incompatible in the next example as well:: - sage: A.construction()[0]*PolynomialRing(QQ,names=['x','y','a_1','a_3'], order='lex').construction()[0] + sage: R = PolynomialRing(QQ, names=['x','y','a_1','a_3'], order='lex') + sage: A.construction()[0] * R.construction()[0] Traceback (most recent call last): ... - CoercionException: Overlapping variables (('a', 'b'),['a_1', 'a_3']) are incompatible + CoercionException: Overlapping variables (('a', 'b'),['a_1', 'a_3']) + are incompatible Another requirement is that after merging the order of the remaining variables must be unique. This is not the case in the following example, since it is not clear whether the variables `x,y` should be greater or smaller than the variables `b_\ast`:: - sage: A.construction()[0]*PolynomialRing(QQ,names=['a_3','a_1','x','y'], order='lex').construction()[0] + sage: R = PolynomialRing(QQ, names=['a_3','a_1','x','y'], order='lex') + sage: A.construction()[0] * R.construction()[0] Traceback (most recent call last): ... - CoercionException: Overlapping variables (('a', 'b'),['a_3', 'a_1']) are incompatible + CoercionException: Overlapping variables (('a', 'b'),['a_3', 'a_1']) + are incompatible Since the construction functors are actually used to construct infinite polynomial rings, the following result is no surprise:: sage: C. = InfinitePolynomialRing(B); C - Infinite polynomial ring in a, b over Multivariate Polynomial Ring in x, y over Rational Field + Infinite polynomial ring in a, b + over Multivariate Polynomial Ring in x, y over Rational Field There is also an overlap in the next example:: @@ -1472,8 +1493,8 @@ def merge(self, other): EXAMPLES:: - sage: X. = InfinitePolynomialRing(QQ,implementation='sparse') - sage: Y. = InfinitePolynomialRing(QQ,order='degrevlex') + sage: X. = InfinitePolynomialRing(QQ, implementation='sparse') + sage: Y. = InfinitePolynomialRing(QQ, order='degrevlex') sage: X.construction() [InfPoly{[x,y], "lex", "sparse"}, Rational Field] sage: Y.construction() @@ -1525,11 +1546,13 @@ def expand(self): EXAMPLES:: - sage: F = InfinitePolynomialRing(QQ, ['x','y'],order='degrevlex').construction()[0]; F + sage: A = InfinitePolynomialRing(QQ, ['x','y'], order='degrevlex') + sage: F = A.construction()[0]; F InfPoly{[x,y], "degrevlex", "dense"} sage: F.expand() [InfPoly{[y], "degrevlex", "dense"}, InfPoly{[x], "degrevlex", "dense"}] - sage: F = InfinitePolynomialRing(QQ, ['x','y','z'],order='degrevlex').construction()[0]; F + sage: A = InfinitePolynomialRing(QQ, ['x','y','z'], order='degrevlex') + sage: F = A.construction()[0]; F InfPoly{[x,y,z], "degrevlex", "dense"} sage: F.expand() [InfPoly{[z], "degrevlex", "dense"}, @@ -1551,23 +1574,27 @@ class MatrixFunctor(ConstructionFunctor): EXAMPLES:: - sage: MS = MatrixSpace(ZZ,2, 3) - sage: F = MS.construction()[0]; F + sage: MS = MatrixSpace(ZZ, 2, 3) # optional - sage.modules + sage: F = MS.construction()[0]; F # optional - sage.modules MatrixFunctor - sage: MS = MatrixSpace(ZZ,2) - sage: F = MS.construction()[0]; F + sage: MS = MatrixSpace(ZZ, 2) # optional - sage.modules + sage: F = MS.construction()[0]; F # optional - sage.modules MatrixFunctor - sage: P. = QQ[] - sage: R = F(P); R - Full MatrixSpace of 2 by 2 dense matrices over Multivariate Polynomial Ring in x, y over Rational Field - sage: f = P.hom([x+y,x-y],P); F(f) - Ring endomorphism of Full MatrixSpace of 2 by 2 dense matrices over Multivariate Polynomial Ring in x, y over Rational Field + sage: P. = QQ[] # optional - sage.modules + sage: R = F(P); R # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices + over Multivariate Polynomial Ring in x, y over Rational Field + sage: f = P.hom([x+y, x-y], P); F(f) # optional - sage.modules + Ring endomorphism + of Full MatrixSpace of 2 by 2 dense matrices + over Multivariate Polynomial Ring in x, y over Rational Field Defn: Induced from base ring by - Ring endomorphism of Multivariate Polynomial Ring in x, y over Rational Field + Ring endomorphism + of Multivariate Polynomial Ring in x, y over Rational Field Defn: x |--> x + y y |--> x - y - sage: M = R([x,y,x*y,x+y]) - sage: F(f)(M) + sage: M = R([x, y, x*y, x + y]) # optional - sage.modules + sage: F(f)(M) # optional - sage.modules [ x + y x - y] [x^2 - y^2 2*x] @@ -1579,21 +1606,21 @@ def __init__(self, nrows, ncols, is_sparse=False): TESTS:: sage: from sage.categories.pushout import MatrixFunctor - sage: F = MatrixFunctor(2,3) - sage: F == MatrixSpace(ZZ,2,3).construction()[0] + sage: F = MatrixFunctor(2, 3) # optional - sage.modules + sage: F == MatrixSpace(ZZ, 2, 3).construction()[0] # optional - sage.modules True - sage: F.codomain() + sage: F.codomain() # optional - sage.modules Category of commutative additive groups - sage: R = MatrixSpace(ZZ,2,2).construction()[0] - sage: R.codomain() + sage: R = MatrixSpace(ZZ, 2, 2).construction()[0] # optional - sage.modules + sage: R.codomain() # optional - sage.modules Category of rings - sage: F(ZZ) + sage: F(ZZ) # optional - sage.modules Full MatrixSpace of 2 by 3 dense matrices over Integer Ring - sage: F(ZZ) in F.codomain() + sage: F(ZZ) in F.codomain() # optional - sage.modules True - sage: R(GF(2)) + sage: R(GF(2)) # optional - sage.rings.finite_rings sage.modules Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 2 - sage: R(GF(2)) in R.codomain() + sage: R(GF(2)) in R.codomain() # optional - sage.rings.finite_rings sage.modules True """ if nrows == ncols: @@ -1613,10 +1640,10 @@ def _apply_functor(self, R): The following is a test against a bug discussed at :trac:`8800`:: - sage: F = MatrixSpace(ZZ,2,3).construction()[0] - sage: F(RR) # indirect doctest + sage: F = MatrixSpace(ZZ, 2, 3).construction()[0] # optional - sage.modules + sage: F(RR) # indirect doctest # optional - sage.modules Full MatrixSpace of 2 by 3 dense matrices over Real Field with 53 bits of precision - sage: F(RR) in F.codomain() + sage: F(RR) in F.codomain() # optional - sage.modules True """ @@ -1627,10 +1654,10 @@ def __eq__(self, other): """ TESTS:: - sage: F = MatrixSpace(ZZ,2,3).construction()[0] - sage: F == loads(dumps(F)) + sage: F = MatrixSpace(ZZ, 2, 3).construction()[0] # optional - sage.modules + sage: F == loads(dumps(F)) # optional - sage.modules True - sage: F == MatrixSpace(ZZ,2,2).construction()[0] + sage: F == MatrixSpace(ZZ, 2, 2).construction()[0] # optional - sage.modules False """ if isinstance(other, MatrixFunctor): @@ -1643,10 +1670,10 @@ def __ne__(self, other): EXAMPLES:: - sage: F = MatrixSpace(ZZ,2,3).construction()[0] - sage: F != loads(dumps(F)) + sage: F = MatrixSpace(ZZ, 2, 3).construction()[0] # optional - sage.modules + sage: F != loads(dumps(F)) # optional - sage.modules False - sage: F != MatrixSpace(ZZ,2,2).construction()[0] + sage: F != MatrixSpace(ZZ, 2, 2).construction()[0] # optional - sage.modules True """ return not (self == other) @@ -1661,20 +1688,20 @@ def merge(self, other): EXAMPLES:: - sage: F1 = MatrixSpace(ZZ,2,2).construction()[0] - sage: F2 = MatrixSpace(ZZ,2,3).construction()[0] - sage: F3 = MatrixSpace(ZZ,2,2,sparse=True).construction()[0] - sage: F1.merge(F2) - sage: F1.merge(F3) + sage: F1 = MatrixSpace(ZZ, 2, 2).construction()[0] # optional - sage.modules + sage: F2 = MatrixSpace(ZZ, 2, 3).construction()[0] # optional - sage.modules + sage: F3 = MatrixSpace(ZZ, 2, 2, sparse=True).construction()[0] # optional - sage.modules + sage: F1.merge(F2) # optional - sage.modules + sage: F1.merge(F3) # optional - sage.modules MatrixFunctor - sage: F13 = F1.merge(F3) - sage: F13.is_sparse + sage: F13 = F1.merge(F3) # optional - sage.modules + sage: F13.is_sparse # optional - sage.modules False - sage: F1.is_sparse + sage: F1.is_sparse # optional - sage.modules False - sage: F3.is_sparse + sage: F3.is_sparse # optional - sage.modules True - sage: F3.merge(F3).is_sparse + sage: F3.merge(F3).is_sparse # optional - sage.modules True """ @@ -1698,16 +1725,18 @@ class LaurentPolynomialFunctor(ConstructionFunctor): Univariate Laurent Polynomial Ring in t over Rational Field sage: K. = LaurentPolynomialRing(ZZ) sage: F(K) - Univariate Laurent Polynomial Ring in t over Univariate Laurent Polynomial Ring in x over Integer Ring + Univariate Laurent Polynomial Ring in t + over Univariate Laurent Polynomial Ring in x over Integer Ring sage: P. = ZZ[] - sage: f = P.hom([x+2*y,3*x-y],P) + sage: f = P.hom([x + 2*y, 3*x - y],P) sage: F(f) - Ring endomorphism of Univariate Laurent Polynomial Ring in t over Multivariate Polynomial Ring in x, y over Integer Ring + Ring endomorphism of Univariate Laurent Polynomial Ring in t + over Multivariate Polynomial Ring in x, y over Integer Ring Defn: Induced from base ring by Ring endomorphism of Multivariate Polynomial Ring in x, y over Integer Ring Defn: x |--> x + 2*y y |--> 3*x - y - sage: F(f)(x*F(P).gen()^-2+y*F(P).gen()^3) + sage: F(f)(x*F(P).gen()^-2 + y*F(P).gen()^3) (x + 2*y)*t^-2 + (3*x - y)*t^3 """ @@ -1824,10 +1853,11 @@ def merge(self, other): sage: F2 = LaurentPolynomialFunctor('t', multi_variate=True) sage: F1.merge(F2) LaurentPolynomialFunctor - sage: F1.merge(F2)(LaurentPolynomialRing(GF(2),'a')) + sage: F1.merge(F2)(LaurentPolynomialRing(GF(2), 'a')) # optional - sage.rings.finite_rings Multivariate Laurent Polynomial Ring in a, t over Finite Field of size 2 - sage: F1.merge(F1)(LaurentPolynomialRing(GF(2),'a')) - Univariate Laurent Polynomial Ring in t over Univariate Laurent Polynomial Ring in a over Finite Field of size 2 + sage: F1.merge(F1)(LaurentPolynomialRing(GF(2), 'a')) # optional - sage.rings.finite_rings + Univariate Laurent Polynomial Ring in t over + Univariate Laurent Polynomial Ring in a over Finite Field of size 2 """ if self == other or isinstance(other, PolynomialFunctor) and self.var == other.var: @@ -1842,11 +1872,12 @@ class VectorFunctor(ConstructionFunctor): EXAMPLES:: - sage: F = (ZZ^3).construction()[0] - sage: F + sage: F = (ZZ^3).construction()[0] # optional - sage.modules + sage: F # optional - sage.modules VectorFunctor - sage: F(GF(2)['t']) - Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in t over Finite Field of size 2 (using GF2X) + sage: F(GF(2)['t']) # optional - sage.rings.finite_rings sage.modules + Ambient free module of rank 3 + over the principal ideal domain Univariate Polynomial Ring in t over Finite Field of size 2 (using GF2X) """ rank = 10 # ranking of functor, not rank of module. # This coincides with the rank of the matrix construction functor, but this is OK since they cannot both be applied in any order @@ -1866,21 +1897,21 @@ def __init__(self, n=None, is_sparse=False, inner_product_matrix=None, *, TESTS:: sage: from sage.categories.pushout import VectorFunctor - sage: F1 = VectorFunctor(3, inner_product_matrix = Matrix(3,3,range(9))) - sage: F1.domain() + sage: F1 = VectorFunctor(3, inner_product_matrix=Matrix(3, 3, range(9))) # optional - sage.modules + sage: F1.domain() # optional - sage.modules Category of commutative rings - sage: F1.codomain() + sage: F1.codomain() # optional - sage.modules Category of commutative additive groups - sage: M1 = F1(ZZ) - sage: M1.is_sparse() + sage: M1 = F1(ZZ) # optional - sage.modules + sage: M1.is_sparse() # optional - sage.modules False - sage: v = M1([3, 2, 1]) - sage: v*Matrix(3,3,range(9))*v.column() + sage: v = M1([3, 2, 1]) # optional - sage.modules + sage: v * Matrix(3, 3, range(9)) * v.column() # optional - sage.modules (96) - sage: v.inner_product(v) + sage: v.inner_product(v) # optional - sage.modules 96 sage: F2 = VectorFunctor(3, is_sparse=True) - sage: M2 = F2(QQ); M2; M2.is_sparse() + sage: M2 = F2(QQ); M2; M2.is_sparse() # optional - sage.modules Sparse vector space of dimension 3 over Rational Field True @@ -1908,28 +1939,28 @@ def _apply_functor(self, R): TESTS:: sage: from sage.categories.pushout import VectorFunctor, pushout - sage: F1 = VectorFunctor(3, inner_product_matrix = Matrix(3,3,range(9))) - sage: M1 = F1(ZZ) # indirect doctest - sage: M1.is_sparse() + sage: F1 = VectorFunctor(3, inner_product_matrix=Matrix(3, 3, range(9))) # optional - sage.modules + sage: M1 = F1(ZZ) # indirect doctest # optional - sage.modules + sage: M1.is_sparse() # optional - sage.modules False - sage: v = M1([3, 2, 1]) - sage: v*Matrix(3,3,range(9))*v.column() + sage: v = M1([3, 2, 1]) # optional - sage.modules + sage: v * Matrix(3, 3, range(9)) * v.column() # optional - sage.modules (96) - sage: v.inner_product(v) + sage: v.inner_product(v) # optional - sage.modules 96 - sage: F2 = VectorFunctor(3, is_sparse=True) - sage: M2 = F2(QQ); M2; M2.is_sparse() + sage: F2 = VectorFunctor(3, is_sparse=True) # optional - sage.modules + sage: M2 = F2(QQ); M2; M2.is_sparse() # optional - sage.modules Sparse vector space of dimension 3 over Rational Field True - sage: v = M2([3, 2, 1]) - sage: v.inner_product(v) + sage: v = M2([3, 2, 1]) # optional - sage.modules + sage: v.inner_product(v) # optional - sage.modules 14 - sage: M = FreeModule(ZZ, 4, with_basis=None, name='M') - sage: latex(M) + sage: M = FreeModule(ZZ, 4, with_basis=None, name='M') # optional - sage.modules + sage: latex(M) # optional - sage.modules M - sage: M_QQ = pushout(M, QQ) - sage: latex(M_QQ) + sage: M_QQ = pushout(M, QQ) # optional - sage.modules + sage: latex(M_QQ) # optional - sage.modules M \otimes \Bold{Q} """ @@ -1957,10 +1988,10 @@ def _apply_functor_to_morphism(self, f): TESTS:: - sage: F = (ZZ^3).construction()[0] + sage: F = (ZZ^3).construction()[0] # optional - sage.modules sage: P. = ZZ[] - sage: f = P.hom([x+2*y,3*x-y],P) - sage: F(f) # indirect doctest + sage: f = P.hom([x + 2*y, 3*x - y], P) + sage: F(f) # indirect doctest # optional - sage.modules Traceback (most recent call last): ... NotImplementedError: Cannot create induced morphisms of free modules yet @@ -1975,13 +2006,13 @@ def __eq__(self, other): TESTS:: sage: from sage.categories.pushout import VectorFunctor - sage: F1 = VectorFunctor(3, inner_product_matrix = Matrix(3,3,range(9))) - sage: F2 = (ZZ^3).construction()[0] - sage: F1 == F2 + sage: F1 = VectorFunctor(3, inner_product_matrix=Matrix(3, 3, range(9))) # optional - sage.modules + sage: F2 = (ZZ^3).construction()[0] # optional - sage.modules + sage: F1 == F2 # optional - sage.modules False - sage: F1(QQ) == F2(QQ) + sage: F1(QQ) == F2(QQ) # optional - sage.modules False - sage: F1 == loads(dumps(F1)) + sage: F1 == loads(dumps(F1)) # optional - sage.modules True """ if isinstance(other, VectorFunctor): @@ -2000,13 +2031,13 @@ def __ne__(self, other): EXAMPLES:: sage: from sage.categories.pushout import VectorFunctor - sage: F1 = VectorFunctor(3, inner_product_matrix = Matrix(3,3,range(9))) - sage: F2 = (ZZ^3).construction()[0] - sage: F1 != F2 + sage: F1 = VectorFunctor(3, inner_product_matrix=Matrix(3, 3, range(9))) # optional - sage.modules + sage: F2 = (ZZ^3).construction()[0] # optional - sage.modules + sage: F1 != F2 # optional - sage.modules True - sage: F1(QQ) != F2(QQ) + sage: F1(QQ) != F2(QQ) # optional - sage.modules True - sage: F1 != loads(dumps(F1)) + sage: F1 != loads(dumps(F1)) # optional - sage.modules False """ return not (self == other) @@ -2022,19 +2053,19 @@ def merge(self, other): Two modules without explicitly given inner product allow coercion:: - sage: M1 = QQ^3 + sage: M1 = QQ^3 # optional - sage.modules sage: P. = ZZ[] - sage: M2 = FreeModule(P,3) - sage: M1([1,1/2,1/3]) + M2([t,t^2+t,3]) # indirect doctest + sage: M2 = FreeModule(P, 3) # optional - sage.modules + sage: M1([1,1/2,1/3]) + M2([t,t^2+t,3]) # indirect doctest # optional - sage.modules (t + 1, t^2 + t + 1/2, 10/3) If only one summand has an explicit inner product, the result will be provided with it:: - sage: M3 = FreeModule(P,3, inner_product_matrix = Matrix(3,3,range(9))) - sage: M1([1,1/2,1/3]) + M3([t,t^2+t,3]) + sage: M3 = FreeModule(P, 3, inner_product_matrix=Matrix(3, 3, range(9))) # optional - sage.modules + sage: M1([1,1/2,1/3]) + M3([t,t^2+t,3]) # optional - sage.modules (t + 1, t^2 + t + 1/2, 10/3) - sage: (M1([1,1/2,1/3]) + M3([t,t^2+t,3])).parent().inner_product_matrix() + sage: (M1([1,1/2,1/3]) + M3([t,t^2+t,3])).parent().inner_product_matrix() # optional - sage.modules [0 1 2] [3 4 5] [6 7 8] @@ -2045,19 +2076,22 @@ def merge(self, other): inner product was *explicitly* requested for ``M4``. It is therefore not possible to coerce with a different inner product:: - sage: M4 = FreeModule(QQ,3, inner_product_matrix = Matrix(3,3,1)) - sage: M4 == M1 + sage: M4 = FreeModule(QQ, 3, inner_product_matrix=Matrix(3, 3, 1)) # optional - sage.modules + sage: M4 == M1 # optional - sage.modules True - sage: M4.inner_product_matrix() == M1.inner_product_matrix() + sage: M4.inner_product_matrix() == M1.inner_product_matrix() # optional - sage.modules True - sage: M4([1,1/2,1/3]) + M3([t,t^2+t,3]) # indirect doctest + sage: M4([1,1/2,1/3]) + M3([t,t^2+t,3]) # indirect doctest # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for +: 'Ambient quadratic space of dimension 3 over Rational Field + TypeError: unsupported operand parent(s) for +: + 'Ambient quadratic space of dimension 3 over Rational Field Inner product matrix: [1 0 0] [0 1 0] - [0 0 1]' and 'Ambient free quadratic module of rank 3 over the integral domain Univariate Polynomial Ring in t over Integer Ring + [0 0 1]' and + 'Ambient free quadratic module of rank 3 over the integral domain + Univariate Polynomial Ring in t over Integer Ring Inner product matrix: [0 1 2] [3 4 5] @@ -2066,14 +2100,17 @@ def merge(self, other): Names are removed when they conflict:: sage: from sage.categories.pushout import VectorFunctor, pushout - sage: M_ZZx = FreeModule(ZZ['x'], 4, with_basis=None, name='M_ZZx') - sage: N_ZZx = FreeModule(ZZ['x'], 4, with_basis=None, name='N_ZZx') - sage: pushout(M_ZZx, QQ) - Rank-4 free module M_ZZx_base_ext over the Univariate Polynomial Ring in x over Rational Field - sage: pushout(M_ZZx, N_ZZx) - Rank-4 free module over the Univariate Polynomial Ring in x over Integer Ring - sage: pushout(pushout(M_ZZx, N_ZZx), QQ) - Rank-4 free module over the Univariate Polynomial Ring in x over Rational Field + sage: M_ZZx = FreeModule(ZZ['x'], 4, with_basis=None, name='M_ZZx') # optional - sage.modules + sage: N_ZZx = FreeModule(ZZ['x'], 4, with_basis=None, name='N_ZZx') # optional - sage.modules + sage: pushout(M_ZZx, QQ) # optional - sage.modules + Rank-4 free module M_ZZx_base_ext + over the Univariate Polynomial Ring in x over Rational Field + sage: pushout(M_ZZx, N_ZZx) # optional - sage.modules + Rank-4 free module + over the Univariate Polynomial Ring in x over Integer Ring + sage: pushout(pushout(M_ZZx, N_ZZx), QQ) # optional - sage.modules + Rank-4 free module + over the Univariate Polynomial Ring in x over Rational Field """ if not isinstance(other, VectorFunctor): return None @@ -2143,14 +2180,14 @@ class SubspaceFunctor(ConstructionFunctor): EXAMPLES:: - sage: M = ZZ^3 - sage: S = M.submodule([(1,2,3),(4,5,6)]); S + sage: M = ZZ^3 # optional - sage.modules + sage: S = M.submodule([(1,2,3), (4,5,6)]); S # optional - sage.modules Free module of degree 3 and rank 2 over Integer Ring Echelon basis matrix: [1 2 3] [0 3 6] - sage: F = S.construction()[0] - sage: F(GF(2)^3) + sage: F = S.construction()[0] # optional - sage.modules + sage: F(GF(2)^3) # optional - sage.rings.finite_rings sage.modules Vector space of degree 3 and dimension 2 over Finite Field of size 2 User basis matrix: [1 0 1] @@ -2172,9 +2209,9 @@ def __init__(self, basis): TESTS:: sage: from sage.categories.pushout import SubspaceFunctor - sage: M = ZZ^3 - sage: F = SubspaceFunctor([M([1,2,3]),M([4,5,6])]) - sage: F(GF(5)^3) + sage: M = ZZ^3 # optional - sage.modules + sage: F = SubspaceFunctor([M([1,2,3]), M([4,5,6])]) # optional - sage.modules + sage: F(GF(5)^3) # optional - sage.rings.finite_rings sage.modules Vector space of degree 3 and dimension 2 over Finite Field of size 5 User basis matrix: [1 2 3] @@ -2194,14 +2231,14 @@ def _apply_functor(self, ambient): TESTS:: - sage: M = ZZ^3 - sage: S = M.submodule([(1,2,3),(4,5,6)]); S + sage: M = ZZ^3 # optional - sage.modules + sage: S = M.submodule([(1,2,3), (4,5,6)]); S # optional - sage.modules Free module of degree 3 and rank 2 over Integer Ring Echelon basis matrix: [1 2 3] [0 3 6] - sage: F = S.construction()[0] - sage: F(GF(2)^3) # indirect doctest + sage: F = S.construction()[0] # optional - sage.modules + sage: F(GF(2)^3) # indirect doctest # optional - sage.rings.finite_rings sage.modules Vector space of degree 3 and dimension 2 over Finite Field of size 2 User basis matrix: [1 0 1] @@ -2215,10 +2252,10 @@ def _apply_functor_to_morphism(self, f): TESTS:: - sage: F = (ZZ^3).span([(1,2,3),(4,5,6)]).construction()[0] - sage: P. = ZZ[] - sage: f = P.hom([x+2*y,3*x-y],P) - sage: F(f) # indirect doctest + sage: F = (ZZ^3).span([(1,2,3), (4,5,6)]).construction()[0] # optional - sage.modules + sage: P. = ZZ[] # optional - sage.modules + sage: f = P.hom([x + 2*y, 3*x - y],P) # optional - sage.modules + sage: F(f) # indirect doctest # optional - sage.modules Traceback (most recent call last): ... NotImplementedError: Cannot create morphisms of free sub-modules yet @@ -2229,32 +2266,32 @@ def __eq__(self, other): """ TESTS:: - sage: F1 = (GF(5)^3).span([(1,2,3),(4,5,6)]).construction()[0] - sage: F2 = (ZZ^3).span([(1,2,3),(4,5,6)]).construction()[0] - sage: F3 = (QQ^3).span([(1,2,3),(4,5,6)]).construction()[0] - sage: F4 = (ZZ^3).span([(1,0,-1),(0,1,2)]).construction()[0] - sage: F1 == loads(dumps(F1)) + sage: F1 = (GF(5)^3).span([(1,2,3),(4,5,6)]).construction()[0] # optional - sage.modules sage.rings.finite_rings + sage: F2 = (ZZ^3).span([(1,2,3),(4,5,6)]).construction()[0] # optional - sage.modules + sage: F3 = (QQ^3).span([(1,2,3),(4,5,6)]).construction()[0] # optional - sage.modules + sage: F4 = (ZZ^3).span([(1,0,-1),(0,1,2)]).construction()[0] # optional - sage.modules + sage: F1 == loads(dumps(F1)) # optional - sage.modules sage.rings.finite_rings True The ``span`` method automatically transforms the given basis into echelon form. The bases look like that:: - sage: F1.basis + sage: F1.basis # optional - sage.modules sage.rings.finite_rings [ (1, 0, 4), (0, 1, 2) ] - sage: F2.basis + sage: F2.basis # optional - sage.modules [ (1, 2, 3), (0, 3, 6) ] - sage: F3.basis + sage: F3.basis # optional - sage.modules [ (1, 0, -1), (0, 1, 2) ] - sage: F4.basis + sage: F4.basis # optional - sage.modules [ (1, 0, -1), (0, 1, 2) @@ -2264,18 +2301,18 @@ def __eq__(self, other): The basis of ``F2`` is modulo 5 different from the other bases. So, we have:: - sage: F1 != F2 != F3 + sage: F1 != F2 != F3 # optional - sage.modules sage.rings.finite_rings True The bases of ``F1``, ``F3`` and ``F4`` are the same modulo 5; however, there is no coercion from ``QQ^3`` to ``GF(5)^3``. Therefore, we have:: - sage: F1 == F3 + sage: F1 == F3 # optional - sage.modules sage.rings.finite_rings False But there are coercions from ``ZZ^3`` to ``QQ^3`` and ``GF(5)^3``, thus:: - sage: F1 == F4 == F3 + sage: F1 == F4 == F3 # optional - sage.modules sage.rings.finite_rings True """ @@ -2301,8 +2338,8 @@ def __ne__(self, other): EXAMPLES:: - sage: F1 = (GF(5)^3).span([(1,2,3),(4,5,6)]).construction()[0] - sage: F1 != loads(dumps(F1)) + sage: F1 = (GF(5)^3).span([(1,2,3),(4,5,6)]).construction()[0] # optional - sage.modules sage.rings.finite_rings + sage: F1 != loads(dumps(F1)) # optional - sage.modules sage.rings.finite_rings False """ return not (self == other) @@ -2315,17 +2352,18 @@ def merge(self, other): EXAMPLES:: - sage: M = GF(5)^3 - sage: S1 = M.submodule([(1,2,3),(4,5,6)]) - sage: S2 = M.submodule([(2,2,3)]) - sage: F1 = S1.construction()[0] - sage: F2 = S2.construction()[0] - sage: F1.merge(F2) + sage: M = GF(5)^3 # optional - sage.modules sage.rings.finite_rings + sage: S1 = M.submodule([(1,2,3),(4,5,6)]) # optional - sage.modules sage.rings.finite_rings + sage: S2 = M.submodule([(2,2,3)]) # optional - sage.modules sage.rings.finite_rings + sage: F1 = S1.construction()[0] # optional - sage.modules sage.rings.finite_rings + sage: F2 = S2.construction()[0] # optional - sage.modules sage.rings.finite_rings + sage: F1.merge(F2) # optional - sage.modules sage.rings.finite_rings SubspaceFunctor - sage: F1.merge(F2)(GF(5)^3) == S1+S2 + sage: F1.merge(F2)(GF(5)^3) == S1 + S2 # optional - sage.modules sage.rings.finite_rings True - sage: F1.merge(F2)(GF(5)['t']^3) - Free module of degree 3 and rank 3 over Univariate Polynomial Ring in t over Finite Field of size 5 + sage: F1.merge(F2)(GF(5)['t']^3) # optional - sage.modules sage.rings.finite_rings + Free module of degree 3 and rank 3 + over Univariate Polynomial Ring in t over Finite Field of size 5 User basis matrix: [1 0 0] [0 1 0] @@ -2334,12 +2372,13 @@ def merge(self, other): TESTS:: sage: P. = ZZ[] - sage: S1 = (ZZ^3).submodule([(1,2,3),(4,5,6)]) - sage: S2 = (Frac(P)^3).submodule([(t,t^2,t^3+1),(4*t,0,1)]) - sage: v = S1([0,3,6]) + S2([2,0,1/(2*t)]); v # indirect doctest + sage: S1 = (ZZ^3).submodule([(1,2,3), (4,5,6)]) # optional - sage.modules + sage: S2 = (Frac(P)^3).submodule([(t,t^2,t^3+1), (4*t,0,1)]) # optional - sage.modules + sage: v = S1([0,3,6]) + S2([2,0,1/(2*t)]); v # indirect doctest # optional - sage.modules (2, 3, (-12*t - 1)/(-2*t)) - sage: v.parent() - Vector space of degree 3 and dimension 3 over Fraction Field of Univariate Polynomial Ring in t over Integer Ring + sage: v.parent() # optional - sage.modules + Vector space of degree 3 and dimension 3 + over Fraction Field of Univariate Polynomial Ring in t over Integer Ring User basis matrix: [1 0 0] [0 1 0] @@ -2384,14 +2423,15 @@ class FractionField(ConstructionFunctor): Category of integral domains sage: F.codomain() Category of fields - sage: F(GF(5)) is GF(5) + sage: F(GF(5)) is GF(5) # optional - sage.rings.finite_rings True sage: F(ZZ['t']) Fraction Field of Univariate Polynomial Ring in t over Integer Ring sage: P. = QQ[] sage: f = P.hom([x+2*y,3*x-y],P) sage: F(f) - Ring endomorphism of Fraction Field of Multivariate Polynomial Ring in x, y over Rational Field + Ring endomorphism of + Fraction Field of Multivariate Polynomial Ring in x, y over Rational Field Defn: x |--> x + 2*y y |--> 3*x - y sage: F(f)(1/x) @@ -2424,8 +2464,9 @@ def _apply_functor(self, R): TESTS:: sage: F = QQ.construction()[0] - sage: F(GF(5)['t']) # indirect doctest - Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 + sage: F(GF(5)['t']) # indirect doctest # optional - sage.rings.finite_rings + Fraction Field of Univariate Polynomial Ring in t + over Finite Field of size 5 """ return R.fraction_field() @@ -2436,15 +2477,15 @@ class CompletionFunctor(ConstructionFunctor): EXAMPLES:: - sage: R = Zp(5) - sage: R + sage: R = Zp(5) # optional - sage.rings.padics + sage: R # optional - sage.rings.padics 5-adic Ring with capped relative precision 20 - sage: F1 = R.construction()[0] - sage: F1 + sage: F1 = R.construction()[0] # optional - sage.rings.padics + sage: F1 # optional - sage.rings.padics Completion[5, prec=20] - sage: F1(ZZ) is R + sage: F1(ZZ) is R # optional - sage.rings.padics True - sage: F1(QQ) + sage: F1(QQ) # optional - sage.rings.padics 5-adic Field with capped relative precision 20 sage: F2 = RR.construction()[0] sage: F2 @@ -2456,16 +2497,16 @@ class CompletionFunctor(ConstructionFunctor): sage: Px Power Series Ring in x over Integer Ring sage: F3 = Px.construction()[0] - sage: F3(GF(3)['x']) + sage: F3(GF(3)['x']) # optional - sage.rings.finite_rings Power Series Ring in x over Finite Field of size 3 TESTS:: - sage: R1. = Zp(5,prec=20)[] - sage: R2 = Qp(5,prec=40) - sage: R2(1) + a + sage: R1. = Zp(5, prec=20)[] # optional - sage.rings.padics + sage: R2 = Qp(5, prec=40) # optional - sage.rings.padics + sage: R2(1) + a # optional - sage.rings.padics (1 + O(5^20))*a + 1 + O(5^40) - sage: 1/2 + a + sage: 1/2 + a # optional - sage.rings.padics (1 + O(5^20))*a + 3 + 2*5 + 2*5^2 + 2*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + 2*5^7 + 2*5^8 + 2*5^9 + 2*5^10 + 2*5^11 + 2*5^12 + 2*5^13 + 2*5^14 + 2*5^15 + 2*5^16 + 2*5^17 + 2*5^18 + 2*5^19 + O(5^20) """ @@ -2496,14 +2537,14 @@ def __init__(self, p, prec, extras=None): TESTS:: sage: from sage.categories.pushout import CompletionFunctor - sage: F1 = CompletionFunctor(5,100) - sage: F1(QQ) + sage: F1 = CompletionFunctor(5, 100) # optional - sage.rings.padics + sage: F1(QQ) # optional - sage.rings.padics 5-adic Field with capped relative precision 100 - sage: F1(ZZ) + sage: F1(ZZ) # optional - sage.rings.padics 5-adic Ring with capped relative precision 100 - sage: F1.type is None + sage: F1.type is None # optional - sage.rings.padics True - sage: sorted(F1.extras.items()) + sage: sorted(F1.extras.items()) # optional - sage.rings.padics [] sage: F2 = RR.construction()[0] sage: F2 @@ -2535,7 +2576,7 @@ def _repr_(self): """ TESTS:: - sage: Zp(7).construction() # indirect doctest + sage: Zp(7).construction() # indirect doctest # optional - sage.rings.padics (Completion[7, prec=20], Integer Ring) sage: RR.construction() # indirect doctest @@ -2549,11 +2590,11 @@ def _apply_functor(self, R): TESTS:: - sage: R = Zp(5) - sage: F1 = R.construction()[0] - sage: F1(ZZ) is R # indirect doctest + sage: R = Zp(5) # optional - sage.rings.padics + sage: F1 = R.construction()[0] # optional - sage.rings.padics + sage: F1(ZZ) is R # indirect doctest # optional - sage.rings.padics True - sage: F1(QQ) + sage: F1(QQ) # optional - sage.rings.padics 5-adic Field with capped relative precision 20 """ @@ -2592,19 +2633,19 @@ def __eq__(self, other): TESTS:: - sage: R1 = Zp(5,prec=30) - sage: R2 = Zp(5,prec=40) - sage: F1 = R1.construction()[0] - sage: F2 = R2.construction()[0] - sage: F1 == loads(dumps(F1)) # indirect doctest + sage: R1 = Zp(5, prec=30) # optional - sage.rings.padics + sage: R2 = Zp(5, prec=40) # optional - sage.rings.padics + sage: F1 = R1.construction()[0] # optional - sage.rings.padics + sage: F2 = R2.construction()[0] # optional - sage.rings.padics + sage: F1 == loads(dumps(F1)) # indirect doctest # optional - sage.rings.padics True - sage: F1 == F2 + sage: F1 == F2 # optional - sage.rings.padics True - sage: F1(QQ) == F2(QQ) + sage: F1(QQ) == F2(QQ) # optional - sage.rings.padics False - sage: R3 = Zp(7) - sage: F3 = R3.construction()[0] - sage: F1 == F3 + sage: R3 = Zp(7) # optional - sage.rings.padics + sage: F3 = R3.construction()[0] # optional - sage.rings.padics + sage: F1 == F3 # optional - sage.rings.padics False """ if isinstance(other, CompletionFunctor): @@ -2617,19 +2658,19 @@ def __ne__(self, other): EXAMPLES:: - sage: R1 = Zp(5,prec=30) - sage: R2 = Zp(5,prec=40) - sage: F1 = R1.construction()[0] - sage: F2 = R2.construction()[0] - sage: F1 != loads(dumps(F1)) # indirect doctest + sage: R1 = Zp(5, prec=30) # optional - sage.rings.padics + sage: R2 = Zp(5, prec=40) # optional - sage.rings.padics + sage: F1 = R1.construction()[0] # optional - sage.rings.padics + sage: F2 = R2.construction()[0] # optional - sage.rings.padics + sage: F1 != loads(dumps(F1)) # indirect doctest # optional - sage.rings.padics False - sage: F1 != F2 + sage: F1 != F2 # optional - sage.rings.padics False - sage: F1(QQ) != F2(QQ) + sage: F1(QQ) != F2(QQ) # optional - sage.rings.padics True - sage: R3 = Zp(7) - sage: F3 = R3.construction()[0] - sage: F1 != F3 + sage: R3 = Zp(7) # optional - sage.rings.padics + sage: F3 = R3.construction()[0] # optional - sage.rings.padics + sage: F1 != F3 # optional - sage.rings.padics True """ return not (self == other) @@ -2647,15 +2688,15 @@ def merge(self, other): EXAMPLES:: - sage: R1. = Zp(5,prec=20)[] - sage: R2 = Qp(5,prec=40) - sage: R2(1)+a # indirect doctest + sage: R1. = Zp(5, prec=20)[] # optional - sage.rings.padics + sage: R2 = Qp(5, prec=40) # optional - sage.rings.padics + sage: R2(1) + a # indirect doctest # optional - sage.rings.padics (1 + O(5^20))*a + 1 + O(5^40) - sage: R3 = RealField(30) - sage: R4 = RealField(50) - sage: R3(1) + R4(1) # indirect doctest + sage: R3 = RealField(30) # optional - sage.rings.padics + sage: R4 = RealField(50) # optional - sage.rings.padics + sage: R3(1) + R4(1) # indirect doctest # optional - sage.rings.padics 2.0000000 - sage: (R3(1) + R4(1)).parent() + sage: (R3(1) + R4(1)).parent() # optional - sage.rings.padics Real Field with 30 bits of precision TESTS: @@ -2665,22 +2706,23 @@ def merge(self, other): sage: RIF(1) > RR(1) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for >: 'Real Interval Field with 53 bits of precision' and 'Real Field with 53 bits of precision' + TypeError: unsupported operand parent(s) for >: + 'Real Interval Field with 53 bits of precision' and 'Real Field with 53 bits of precision' We check that various pushouts work:: sage: R0 = RealIntervalField(30) sage: R1 = RealIntervalField(30, sci_not=True) sage: R2 = RealIntervalField(53) - sage: R3 = RealIntervalField(53, sci_not = True) + sage: R3 = RealIntervalField(53, sci_not=True) sage: R4 = RealIntervalField(90) - sage: R5 = RealIntervalField(90, sci_not = True) + sage: R5 = RealIntervalField(90, sci_not=True) sage: R6 = RealField(30) sage: R7 = RealField(30, sci_not=True) - sage: R8 = RealField(53, rnd = 'RNDD') - sage: R9 = RealField(53, sci_not = True, rnd = 'RNDZ') - sage: R10 = RealField(53, sci_not = True) - sage: R11 = RealField(90, sci_not = True, rnd = 'RNDZ') + sage: R8 = RealField(53, rnd='RNDD') + sage: R9 = RealField(53, sci_not=True, rnd='RNDZ') + sage: R10 = RealField(53, sci_not=True) + sage: R11 = RealField(90, sci_not=True, rnd='RNDZ') sage: Rlist = [R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11] sage: from sage.categories.pushout import pushout sage: pushouts = [R0,R0,R0,R1,R0,R1,R0,R1,R0,R1,R1,R1,R1,R1,R1,R1,R1,R1,R1,R1,R1,R1,R1,R1,R0,R1,R2,R2,R2,R3,R0,R1,R2,R3,R3,R3,R1,R1,R3,R3,R3,R3,R1,R1,R3,R3,R3,R3,R0,R1,R2,R3,R4,R4,R0,R1,R2,R3,R3,R5,R1,R1,R3,R3,R5,R5,R1,R1,R3,R3,R3,R5,R0,R1,R0,R1,R0,R1,R6,R6,R6,R7,R7,R7,R1,R1,R1,R1,R1,R1,R7,R7,R7,R7,R7,R7,R0,R1,R2,R3,R2,R3,R6,R7,R8,R9,R10,R9,R1,R1,R3,R3,R3,R3,R7,R7,R9,R9,R10,R9,R1,R1,R3,R3,R3,R3,R7,R7,R10,R10,R10,R10,R1,R1,R3,R3,R5,R5,R7,R7,R9,R9,R10,R11] @@ -2689,18 +2731,20 @@ def merge(self, other): :: - sage: P0 = ZpFM(5, 10) - sage: P1 = ZpFM(5, 20) - sage: P2 = ZpCR(5, 10) - sage: P3 = ZpCR(5, 20) - sage: P4 = ZpCA(5, 10) - sage: P5 = ZpCA(5, 20) - sage: P6 = Qp(5, 10) - sage: P7 = Qp(5, 20) - sage: Plist = [P2,P3,P4,P5,P6,P7] + sage: P0 = ZpFM(5, 10) # optional - sage.rings.padics + sage: P1 = ZpFM(5, 20) # optional - sage.rings.padics + sage: P2 = ZpCR(5, 10) # optional - sage.rings.padics + sage: P3 = ZpCR(5, 20) # optional - sage.rings.padics + sage: P4 = ZpCA(5, 10) # optional - sage.rings.padics + sage: P5 = ZpCA(5, 20) # optional - sage.rings.padics + sage: P6 = Qp(5, 10) # optional - sage.rings.padics + sage: P7 = Qp(5, 20) # optional - sage.rings.padics + sage: Plist = [P2,P3,P4,P5,P6,P7] # optional - sage.rings.padics sage: from sage.categories.pushout import pushout - sage: pushouts = [P2,P3,P4,P5,P6,P7,P3,P3,P5,P5,P7,P7,P4,P5,P4,P5,P6,P7,P5,P5,P5,P5,P7,P7,P6,P7,P6,P7,P6,P7,P7,P7,P7,P7,P7,P7] - sage: all(P is Q for P, Q in zip(pushouts, [pushout(a, b) for a in Plist for b in Plist])) + sage: pushouts = [P2,P3,P4,P5,P6,P7,P3,P3,P5,P5,P7,P7,P4,P5,P4,P5,P6,P7, # optional - sage.rings.padics + ....: P5,P5,P5,P5,P7,P7,P6,P7,P6,P7,P6,P7,P7,P7,P7,P7,P7,P7] + sage: all(P is Q # optional - sage.rings.padics + ....: for P, Q in zip(pushouts, [pushout(a, b) for a in Plist for b in Plist])) True """ if self == other: # both are Completion functors with the same p @@ -2742,9 +2786,9 @@ def commutes(self, other): EXAMPLES:: - sage: F1 = Zp(5).construction()[0] + sage: F1 = Zp(5).construction()[0] # optional - sage.rings.padics sage: F2 = QQ.construction()[0] - sage: F1.commutes(F2) + sage: F1.commutes(F2) # optional - sage.rings.padics True TESTS: @@ -2771,10 +2815,12 @@ def commutes(self, other): Ambiguous base extension error raised):: sage: from sage.categories.pushout import pushout - sage: pushout(Qp(7),RLF) + sage: pushout(Qp(7), RLF) # optional - sage.rings.padics Traceback (most recent call last): ... - CoercionException: Don't know how to apply Completion[+Infinity, prec=+Infinity] to 7-adic Ring with capped relative precision 20 + CoercionException: Don't know how to + apply Completion[+Infinity, prec=+Infinity] + to 7-adic Ring with capped relative precision 20 """ return isinstance(other, FractionField) @@ -2792,17 +2838,19 @@ class QuotientFunctor(ConstructionFunctor): EXAMPLES:: sage: P. = ZZ[] - sage: Q = P.quo([x^2+y^2]*P) - sage: F = Q.construction()[0] - sage: F(QQ['x','y']) - Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) - sage: F(QQ['x','y']) == QQ['x','y'].quo([x^2+y^2]*QQ['x','y']) + sage: Q = P.quo([x^2 + y^2] * P) # optional - sage.rings.finite_rings + sage: F = Q.construction()[0] # optional - sage.rings.finite_rings + sage: F(QQ['x','y']) # optional - sage.rings.finite_rings + Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x^2 + y^2) + sage: F(QQ['x','y']) == QQ['x','y'].quo([x^2 + y^2] * QQ['x','y']) # optional - sage.rings.finite_rings True - sage: F(QQ['x','y','z']) + sage: F(QQ['x','y','z']) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - CoercionException: Cannot apply this quotient functor to Multivariate Polynomial Ring in x, y, z over Rational Field - sage: F(QQ['y','z']) + CoercionException: Cannot apply this quotient functor to + Multivariate Polynomial Ring in x, y, z over Rational Field + sage: F(QQ['y','z']) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: Could not find a mapping of the passed element to this ring. @@ -2831,21 +2879,25 @@ def __init__(self, I, names=None, as_field=False, domain=None, sage: from sage.categories.pushout import QuotientFunctor sage: P. = ZZ[] - sage: F = QuotientFunctor([5+t^2]*P) - sage: F(P) - Univariate Quotient Polynomial Ring in tbar over Integer Ring with modulus t^2 + 5 - sage: F(QQ['t']) - Univariate Quotient Polynomial Ring in tbar over Rational Field with modulus t^2 + 5 - sage: F = QuotientFunctor([5+t^2]*P,names='s') - sage: F(P) - Univariate Quotient Polynomial Ring in s over Integer Ring with modulus t^2 + 5 - sage: F(QQ['t']) - Univariate Quotient Polynomial Ring in s over Rational Field with modulus t^2 + 5 - sage: F = QuotientFunctor([5]*ZZ,as_field=True) - sage: F(ZZ) + sage: F = QuotientFunctor([5 + t^2] * P) + sage: F(P) # optional - sage.rings.finite_rings + Univariate Quotient Polynomial Ring in tbar + over Integer Ring with modulus t^2 + 5 + sage: F(QQ['t']) # optional - sage.rings.finite_rings + Univariate Quotient Polynomial Ring in tbar + over Rational Field with modulus t^2 + 5 + sage: F = QuotientFunctor([5 + t^2] * P, names='s') + sage: F(P) # optional - sage.rings.finite_rings + Univariate Quotient Polynomial Ring in s + over Integer Ring with modulus t^2 + 5 + sage: F(QQ['t']) # optional - sage.rings.finite_rings + Univariate Quotient Polynomial Ring in s + over Rational Field with modulus t^2 + 5 + sage: F = QuotientFunctor([5] * ZZ, as_field=True) + sage: F(ZZ) # optional - sage.rings.finite_rings Finite Field of size 5 - sage: F = QuotientFunctor([5]*ZZ) - sage: F(ZZ) + sage: F = QuotientFunctor([5] * ZZ) + sage: F(ZZ) # optional - sage.rings.finite_rings Ring of integers modulo 5 """ @@ -2872,11 +2924,12 @@ def _apply_functor(self, R): TESTS:: sage: P. = ZZ[] - sage: Q = P.quo([2+x^2,3*x+y^2]) - sage: F = Q.construction()[0]; F + sage: Q = P.quo([2 + x^2, 3*x + y^2]) # optional - sage.rings.finite_rings + sage: F = Q.construction()[0]; F # optional - sage.rings.finite_rings QuotientFunctor - sage: F(QQ['x','y']) # indirect doctest - Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + 2, y^2 + 3*x) + sage: F(QQ['x','y']) # indirect doctest # optional - sage.rings.finite_rings + Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x^2 + 2, y^2 + 3*x) Note that the ``quo()`` method of a field used to return the integer zero. That strange behaviour was removed in github @@ -2919,14 +2972,14 @@ def __eq__(self, other): TESTS:: sage: P. = QQ[] - sage: F = P.quo([(x^2+1)^2*(x^2-3),(x^2+1)^2*(x^5+3)]).construction()[0] - sage: F == loads(dumps(F)) + sage: F = P.quo([(x^2+1)^2*(x^2-3),(x^2+1)^2*(x^5+3)]).construction()[0] # optional - sage.rings.finite_rings + sage: F == loads(dumps(F)) # optional - sage.rings.finite_rings True sage: P2. = QQ[] - sage: F == P2.quo([(x^2+1)^2*(x^2-3),(x^2+1)^2*(x^5+3)]).construction()[0] + sage: F == P2.quo([(x^2+1)^2*(x^2-3),(x^2+1)^2*(x^5+3)]).construction()[0] # optional - sage.rings.finite_rings False sage: P3. = ZZ[] - sage: F == P3.quo([(x^2+1)^2*(x^2-3),(x^2+1)^2*(x^5+3)]).construction()[0] + sage: F == P3.quo([(x^2+1)^2*(x^2-3),(x^2+1)^2*(x^5+3)]).construction()[0] # optional - sage.rings.finite_rings True """ if not isinstance(other, QuotientFunctor): @@ -2944,14 +2997,14 @@ def __ne__(self, other): EXAMPLES:: sage: P. = QQ[] - sage: F = P.quo([(x^2+1)^2*(x^2-3),(x^2+1)^2*(x^5+3)]).construction()[0] - sage: F != loads(dumps(F)) + sage: F = P.quo([(x^2+1)^2*(x^2-3),(x^2+1)^2*(x^5+3)]).construction()[0] # optional - sage.rings.finite_rings + sage: F != loads(dumps(F)) # optional - sage.rings.finite_rings False sage: P2. = QQ[] - sage: F != P2.quo([(x^2+1)^2*(x^2-3),(x^2+1)^2*(x^5+3)]).construction()[0] + sage: F != P2.quo([(x^2+1)^2*(x^2-3),(x^2+1)^2*(x^5+3)]).construction()[0] # optional - sage.rings.finite_rings True sage: P3. = ZZ[] - sage: F != P3.quo([(x^2+1)^2*(x^2-3),(x^2+1)^2*(x^5+3)]).construction()[0] + sage: F != P3.quo([(x^2+1)^2*(x^2-3),(x^2+1)^2*(x^5+3)]).construction()[0] # optional - sage.rings.finite_rings False """ return not (self == other) @@ -2970,15 +3023,16 @@ def merge(self, other): EXAMPLES:: sage: P. = QQ[] - sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) - sage: Q2 = P.quo([(x^2+1)^2*(x^5+3)]) + sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) # optional - sage.rings.finite_rings + sage: Q2 = P.quo([(x^2+1)^2*(x^5+3)]) # optional - sage.rings.finite_rings sage: from sage.categories.pushout import pushout - sage: pushout(Q1,Q2) # indirect doctest - Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^4 + 2*x^2 + 1 + sage: pushout(Q1,Q2) # indirect doctest # optional - sage.rings.finite_rings + Univariate Quotient Polynomial Ring in xbar over Rational Field + with modulus x^4 + 2*x^2 + 1 The following was fixed in :trac:`8800`:: - sage: pushout(GF(5), Integers(5)) + sage: pushout(GF(5), Integers(5)) # optional - sage.rings.finite_rings Finite Field of size 5 """ @@ -3038,65 +3092,72 @@ class AlgebraicExtensionFunctor(ConstructionFunctor): EXAMPLES:: sage: x = polygen(QQ, 'x') - sage: K. = NumberField(x^3 + x^2 + 1) - sage: F = K.construction()[0] - sage: F(ZZ['t']) - Univariate Quotient Polynomial Ring in a over Univariate Polynomial Ring in t over Integer Ring with modulus a^3 + a^2 + 1 + sage: K. = NumberField(x^3 + x^2 + 1) # optional - sage.rings.number_field + sage: F = K.construction()[0] # optional - sage.rings.number_field + sage: F(ZZ['t']) # optional - sage.rings.number_field + Univariate Quotient Polynomial Ring in a + over Univariate Polynomial Ring in t over Integer Ring + with modulus a^3 + a^2 + 1 Note that, even if a field is algebraically closed, the algebraic extension will be constructed as the quotient of a univariate polynomial ring:: - sage: F(CC) - Univariate Quotient Polynomial Ring in a over Complex Field with 53 bits of precision with modulus a^3 + a^2 + 1.00000000000000 - sage: F(RR) - Univariate Quotient Polynomial Ring in a over Real Field with 53 bits of precision with modulus a^3 + a^2 + 1.00000000000000 + sage: F(CC) # optional - sage.rings.number_field + Univariate Quotient Polynomial Ring in a + over Complex Field with 53 bits of precision + with modulus a^3 + a^2 + 1.00000000000000 + sage: F(RR) # optional - sage.rings.number_field + Univariate Quotient Polynomial Ring in a + over Real Field with 53 bits of precision + with modulus a^3 + a^2 + 1.00000000000000 Note that the construction functor of a number field applied to the integers returns an order (not necessarily maximal) of that field, similar to the behaviour of ``ZZ.extension(...)``:: - sage: F(ZZ) + sage: F(ZZ) # optional - sage.rings.number_field Order in Number Field in a with defining polynomial x^3 + x^2 + 1 This also holds for non-absolute number fields:: sage: x = polygen(QQ, 'x') - sage: K. = NumberField([x^3 + x^2 + 1, x^2 + x + 1]) - sage: F = K.construction()[0] - sage: O = F(ZZ); O - Relative Order in Number Field in a with defining polynomial x^3 + x^2 + 1 over its base field - sage: O.ambient() is K + sage: K. = NumberField([x^3 + x^2 + 1, x^2 + x + 1]) # optional - sage.rings.number_field + sage: F = K.construction()[0] # optional - sage.rings.number_field + sage: O = F(ZZ); O # optional - sage.rings.number_field + Relative Order in Number Field in a + with defining polynomial x^3 + x^2 + 1 over its base field + sage: O.ambient() is K # optional - sage.rings.number_field True Special cases are made for cyclotomic fields and residue fields:: - sage: C = CyclotomicField(8) - sage: F,R = C.construction() - sage: F + sage: C = CyclotomicField(8) # optional - sage.rings.number_field + sage: F, R = C.construction() # optional - sage.rings.number_field + sage: F # optional - sage.rings.number_field AlgebraicExtensionFunctor - sage: R + sage: R # optional - sage.rings.number_field Rational Field - sage: F(R) + sage: F(R) # optional - sage.rings.number_field Cyclotomic Field of order 8 and degree 4 - sage: F(ZZ) + sage: F(ZZ) # optional - sage.rings.number_field Maximal Order in Cyclotomic Field of order 8 and degree 4 :: - sage: K. = CyclotomicField(7) - sage: P = K.factor(17)[0][0] - sage: k = K.residue_field(P) - sage: F, R = k.construction() - sage: F + sage: K. = CyclotomicField(7) # optional - sage.rings.number_field + sage: P = K.factor(17)[0][0] # optional - sage.rings.number_field + sage: k = K.residue_field(P) # optional - sage.rings.number_field + sage: F, R = k.construction() # optional - sage.rings.number_field + sage: F # optional - sage.rings.number_field AlgebraicExtensionFunctor - sage: R + sage: R # optional - sage.rings.number_field Cyclotomic Field of order 7 and degree 6 - sage: F(R) is k + sage: F(R) is k # optional - sage.rings.number_field True - sage: F(ZZ) + sage: F(ZZ) # optional - sage.rings.number_field Residue field of Integers modulo 17 - sage: F(CyclotomicField(49)) + sage: F(CyclotomicField(49)) # optional - sage.rings.number_field Residue field in zbar of Fractional ideal (17) """ @@ -3158,23 +3219,25 @@ def __init__(self, polys, names, embeddings=None, structures=None, sage: from sage.categories.pushout import AlgebraicExtensionFunctor sage: P. = ZZ[] - sage: F1 = AlgebraicExtensionFunctor([x^3 - x^2 + 1], ['a'], [None]) - sage: F2 = AlgebraicExtensionFunctor([x^3 - x^2 + 1], ['a'], [0]) - sage: F1==F2 + sage: F1 = AlgebraicExtensionFunctor([x^3 - x^2 + 1], ['a'], [None]) # optional - sage.rings.number_field + sage: F2 = AlgebraicExtensionFunctor([x^3 - x^2 + 1], ['a'], [0]) # optional - sage.rings.number_field + sage: F1 == F2 # optional - sage.rings.number_field False - sage: F1(QQ) + sage: F1(QQ) # optional - sage.rings.number_field Number Field in a with defining polynomial x^3 - x^2 + 1 - sage: F1(QQ).coerce_embedding() - sage: phi = F2(QQ).coerce_embedding().__copy__(); phi + sage: F1(QQ).coerce_embedding() # optional - sage.rings.number_field + sage: phi = F2(QQ).coerce_embedding().__copy__(); phi # optional - sage.rings.number_field Generic morphism: - From: Number Field in a with defining polynomial x^3 - x^2 + 1 with a = -0.7548776662466928? + From: Number Field in a with defining polynomial x^3 - x^2 + 1 + with a = -0.7548776662466928? To: Real Lazy Field Defn: a -> -0.7548776662466928? - sage: F1(QQ)==F2(QQ) + sage: F1(QQ) == F2(QQ) # optional - sage.rings.number_field False - sage: F1(GF(5)) - Univariate Quotient Polynomial Ring in a over Finite Field of size 5 with modulus a^3 + 4*a^2 + 1 - sage: F2(GF(5)) + sage: F1(GF(5)) # optional - sage.rings.finite_rings sage.rings.number_field + Univariate Quotient Polynomial Ring in a over Finite Field of size 5 + with modulus a^3 + 4*a^2 + 1 + sage: F2(GF(5)) # optional - sage.rings.finite_rings sage.rings.number_field Traceback (most recent call last): ... NotImplementedError: ring extension with prescribed embedding is not implemented @@ -3183,38 +3246,38 @@ def __init__(self, polys, names, embeddings=None, structures=None, integers, an order (not necessarily maximal) of that field is returned, similar to the behaviour of ``ZZ.extension``:: - sage: F1(ZZ) + sage: F1(ZZ) # optional - sage.rings.number_field Order in Number Field in a with defining polynomial x^3 - x^2 + 1 The cyclotomic fields form a special case of number fields with prescribed embeddings:: - sage: C = CyclotomicField(8) - sage: F,R = C.construction() - sage: F + sage: C = CyclotomicField(8) # optional - sage.rings.number_field + sage: F, R = C.construction() # optional - sage.rings.number_field + sage: F # optional - sage.rings.number_field AlgebraicExtensionFunctor - sage: R + sage: R # optional - sage.rings.number_field Rational Field - sage: F(R) + sage: F(R) # optional - sage.rings.number_field Cyclotomic Field of order 8 and degree 4 - sage: F(ZZ) + sage: F(ZZ) # optional - sage.rings.number_field Maximal Order in Cyclotomic Field of order 8 and degree 4 The data stored in this construction includes structural morphisms of number fields (see :trac:`20826`):: sage: R. = ZZ[] - sage: K. = NumberField(x^2 - 3) - sage: L0. = K.change_names() - sage: L0.structure() + sage: K. = NumberField(x^2 - 3) # optional - sage.rings.number_field + sage: L0. = K.change_names() # optional - sage.rings.number_field + sage: L0.structure() # optional - sage.rings.number_field (Isomorphism given by variable name change map: From: Number Field in b with defining polynomial x^2 - 3 To: Number Field in a with defining polynomial x^2 - 3, Isomorphism given by variable name change map: From: Number Field in a with defining polynomial x^2 - 3 To: Number Field in b with defining polynomial x^2 - 3) - sage: L1 = (b*x).parent().base_ring() - sage: L1 is L0 + sage: L1 = (b*x).parent().base_ring() # optional - sage.rings.number_field + sage: L1 is L0 # optional - sage.rings.number_field True """ Functor.__init__(self, Rings(), Rings()) @@ -3258,21 +3321,24 @@ def _apply_functor(self, R): TESTS:: sage: x = polygen(QQ, 'x') - sage: K. = NumberField(x^3 + x^2 + 1) - sage: F = K.construction()[0] - sage: F(ZZ) # indirect doctest + sage: K. = NumberField(x^3 + x^2 + 1) # optional - sage.rings.number_field + sage: F = K.construction()[0] # optional - sage.rings.number_field + sage: F(ZZ) # indirect doctest # optional - sage.rings.number_field Order in Number Field in a with defining polynomial x^3 + x^2 + 1 - sage: F(ZZ['t']) # indirect doctest - Univariate Quotient Polynomial Ring in a over Univariate Polynomial Ring in t over Integer Ring with modulus a^3 + a^2 + 1 - sage: F(RR) # indirect doctest - Univariate Quotient Polynomial Ring in a over Real Field with 53 bits of precision with modulus a^3 + a^2 + 1.00000000000000 + sage: F(ZZ['t']) # indirect doctest # optional - sage.rings.number_field + Univariate Quotient Polynomial Ring in a over + Univariate Polynomial Ring in t over Integer Ring with modulus a^3 + a^2 + 1 + sage: F(RR) # indirect doctest # optional - sage.rings.number_field + Univariate Quotient Polynomial Ring in a over + Real Field with 53 bits of precision with modulus a^3 + a^2 + 1.00000000000000 Check that :trac:`13538` is fixed:: - sage: K = Qp(3,3) - sage: R. = K[] - sage: AEF = sage.categories.pushout.AlgebraicExtensionFunctor([a^2-3], ['a'], [None]) - sage: AEF(K) + sage: from sage.categories.pushout import AlgebraicExtensionFunctor + sage: K = Qp(3, 3) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: AEF = AlgebraicExtensionFunctor([a^2 - 3], ['a'], [None]) # optional - sage.rings.padics + sage: AEF(K) # optional - sage.rings.padics 3-adic Eisenstein Extension Field in a defined by a^2 - 3 """ @@ -3303,19 +3369,19 @@ def __eq__(self, other): TESTS:: sage: x = polygen(QQ, 'x') - sage: K. = NumberField(x^3 + x^2 + 1) - sage: F = K.construction()[0] - sage: F == loads(dumps(F)) + sage: K. = NumberField(x^3 + x^2 + 1) # optional - sage.rings.number_field + sage: F = K.construction()[0] # optional - sage.rings.number_field + sage: F == loads(dumps(F)) # optional - sage.rings.number_field True - sage: K2. = NumberField(x^3 + x^2 + 1, latex_names='a') - sage: F2 = K2.construction()[0] - sage: F2 == F + sage: K2. = NumberField(x^3 + x^2 + 1, latex_names='a') # optional - sage.rings.number_field + sage: F2 = K2.construction()[0] # optional - sage.rings.number_field + sage: F2 == F # optional - sage.rings.number_field True - sage: K3. = NumberField(x^3 + x^2 + 1, latex_names='alpha') - sage: F3 = K3.construction()[0] - sage: F3 == F + sage: K3. = NumberField(x^3 + x^2 + 1, latex_names='alpha') # optional - sage.rings.number_field + sage: F3 = K3.construction()[0] # optional - sage.rings.number_field + sage: F3 == F # optional - sage.rings.number_field False """ if not isinstance(other, AlgebraicExtensionFunctor): @@ -3334,9 +3400,9 @@ def __ne__(self, other): EXAMPLES:: sage: x = polygen(QQ, 'x') - sage: K. = NumberField(x^3 + x^2 + 1) - sage: F = K.construction()[0] - sage: F != loads(dumps(F)) + sage: K. = NumberField(x^3 + x^2 + 1) # optional - sage.rings.number_field + sage: F = K.construction()[0] # optional - sage.rings.number_field + sage: F != loads(dumps(F)) # optional - sage.rings.number_field False """ return not (self == other) @@ -3380,36 +3446,39 @@ def merge(self, other): The following demonstrate coercions for finite fields using Conway or pseudo-Conway polynomials:: - sage: k = GF(3^2, prefix='z'); a = k.gen() - sage: l = GF(3^3, prefix='z'); b = l.gen() - sage: a + b # indirect doctest + sage: k = GF(3^2, prefix='z'); a = k.gen() # optional - sage.rings.finite_rings + sage: l = GF(3^3, prefix='z'); b = l.gen() # optional - sage.rings.finite_rings + sage: a + b # indirect doctest # optional - sage.rings.finite_rings z6^5 + 2*z6^4 + 2*z6^3 + z6^2 + 2*z6 + 1 Note that embeddings are compatible in lattices of such finite fields:: - sage: m = GF(3^5, prefix='z'); c = m.gen() - sage: (a+b)+c == a+(b+c) # indirect doctest + sage: m = GF(3^5, prefix='z'); c = m.gen() # optional - sage.rings.finite_rings + sage: (a + b) + c == a + (b + c) # indirect doctest # optional - sage.rings.finite_rings True sage: from sage.categories.pushout import pushout - sage: n = pushout(k, l) - sage: o = pushout(l, m) - sage: q = pushout(n, o) - sage: q(o(b)) == q(n(b)) # indirect doctest + sage: n = pushout(k, l) # optional - sage.rings.finite_rings + sage: o = pushout(l, m) # optional - sage.rings.finite_rings + sage: q = pushout(n, o) # optional - sage.rings.finite_rings + sage: q(o(b)) == q(n(b)) # indirect doctest # optional - sage.rings.finite_rings True Coercion is also available for number fields:: - sage: P. = QQ[] - sage: L. = NumberField(x^8-x^4+1, embedding=CDF.0) - sage: M1. = NumberField(x^2+x+1, embedding=b^4-1) - sage: M2. = NumberField(x^2+1, embedding=-b^6) - sage: M1.coerce_map_from(M2) - sage: M2.coerce_map_from(M1) - sage: c1+c2; parent(c1+c2) #indirect doctest + sage: P. = QQ[] # optional - sage.rings.number_field + sage: L. = NumberField(x^8 - x^4 + 1, embedding=CDF.0) # optional - sage.rings.number_field + sage: M1. = NumberField(x^2 + x + 1, embedding=b^4 - 1) # optional - sage.rings.number_field + sage: M2. = NumberField(x^2 + 1, embedding=-b^6) # optional - sage.rings.number_field + sage: M1.coerce_map_from(M2) # optional - sage.rings.number_field + sage: M2.coerce_map_from(M1) # optional - sage.rings.number_field + sage: c1 + c2; parent(c1 + c2) #indirect doctest # optional - sage.rings.number_field -b^6 + b^4 - 1 - Number Field in b with defining polynomial x^8 - x^4 + 1 with b = -0.2588190451025208? + 0.9659258262890683?*I - sage: pushout(M1['x'],M2['x']) - Univariate Polynomial Ring in x over Number Field in b with defining polynomial x^8 - x^4 + 1 with b = -0.2588190451025208? + 0.9659258262890683?*I + Number Field in b with defining polynomial x^8 - x^4 + 1 + with b = -0.2588190451025208? + 0.9659258262890683?*I + sage: pushout(M1['x'], M2['x']) # optional - sage.rings.number_field + Univariate Polynomial Ring in x + over Number Field in b with defining polynomial x^8 - x^4 + 1 + with b = -0.2588190451025208? + 0.9659258262890683?*I In the previous example, the number field ``L`` becomes the pushout of ``M1`` and ``M2`` since both are provided with an embedding into @@ -3419,14 +3488,16 @@ def merge(self, other): sage: cbrt2 = CDF(2)^(1/3) sage: zeta3 = CDF.zeta(3) - sage: K. = NumberField(x^3-2, embedding=cbrt2 * zeta3) - sage: L. = NumberField(x^6-2, embedding=1.1) - sage: L.coerce_map_from(K) - sage: K.coerce_map_from(L) - sage: pushout(K,L) + sage: K. = NumberField(x^3 - 2, embedding=cbrt2 * zeta3) # optional - sage.rings.number_field + sage: L. = NumberField(x^6 - 2, embedding=1.1) # optional - sage.rings.number_field + sage: L.coerce_map_from(K) # optional - sage.rings.number_field + sage: K.coerce_map_from(L) # optional - sage.rings.number_field + sage: pushout(K, L) # optional - sage.rings.number_field Traceback (most recent call last): ... - CoercionException: ('Ambiguous Base Extension', Number Field in a with defining polynomial x^3 - 2 with a = -0.6299605249474365? + 1.091123635971722?*I, Number Field in b with defining polynomial x^6 - 2 with b = 1.122462048309373?) + CoercionException: ('Ambiguous Base Extension', Number Field in a with + defining polynomial x^3 - 2 with a = -0.6299605249474365? + 1.091123635971722?*I, + Number Field in b with defining polynomial x^6 - 2 with b = 1.122462048309373?) """ if isinstance(other, AlgebraicClosureFunctor): @@ -3496,10 +3567,10 @@ def __mul__(self, other): TESTS:: sage: P. = QQ[] - sage: K. = NumberField(x^3-5,embedding=0) - sage: L. = K.extension(x^2+a) - sage: F,R = L.construction() - sage: prod(F.expand())(R) == L #indirect doctest + sage: K. = NumberField(x^3 - 5, embedding=0) # optional - sage.rings.number_field + sage: L. = K.extension(x^2 + a) # optional - sage.rings.number_field + sage: F, R = L.construction() # optional - sage.rings.number_field + sage: prod(F.expand())(R) == L #indirect doctest # optional - sage.rings.number_field True """ @@ -3528,18 +3599,18 @@ def expand(self): EXAMPLES:: sage: P. = QQ[] - sage: K. = NumberField(x^3-5,embedding=0) - sage: L. = K.extension(x^2+a) - sage: F,R = L.construction() - sage: prod(F.expand())(R) == L + sage: K. = NumberField(x^3 - 5, embedding=0) # optional - sage.rings.number_field + sage: L. = K.extension(x^2 + a) # optional - sage.rings.number_field + sage: F, R = L.construction() # optional - sage.rings.number_field + sage: prod(F.expand())(R) == L # optional - sage.rings.number_field True - sage: K = NumberField([x^2-2, x^2-3],'a') - sage: F, R = K.construction() - sage: F + sage: K = NumberField([x^2 - 2, x^2 - 3],'a') # optional - sage.rings.number_field + sage: F, R = K.construction() # optional - sage.rings.number_field + sage: F # optional - sage.rings.number_field AlgebraicExtensionFunctor - sage: L = F.expand(); L + sage: L = F.expand(); L # optional - sage.rings.number_field [AlgebraicExtensionFunctor, AlgebraicExtensionFunctor] - sage: L[-1](QQ) + sage: L[-1](QQ) # optional - sage.rings.number_field Number Field in a1 with defining polynomial x^2 - 3 """ n = len(self.polys) @@ -3559,11 +3630,11 @@ class AlgebraicClosureFunctor(ConstructionFunctor): EXAMPLES:: sage: F = CDF.construction()[0] - sage: F(QQ) + sage: F(QQ) # optional - sage.rings.number_field Algebraic Field sage: F(RR) Complex Field with 53 bits of precision - sage: F(F(QQ)) is F(QQ) + sage: F(F(QQ)) is F(QQ) # optional - sage.rings.number_field True """ @@ -3575,7 +3646,7 @@ def __init__(self): sage: from sage.categories.pushout import AlgebraicClosureFunctor sage: F = AlgebraicClosureFunctor() - sage: F(QQ) + sage: F(QQ) # optional - sage.rings.number_field Algebraic Field sage: F(RR) Complex Field with 53 bits of precision @@ -3592,7 +3663,7 @@ def _apply_functor(self, R): TESTS:: sage: F = CDF.construction()[0] - sage: F(QQ) # indirect doctest + sage: F(QQ) # indirect doctest # optional - sage.rings.number_field Algebraic Field """ try: @@ -3612,10 +3683,10 @@ def merge(self, other): TESTS:: sage: x = polygen(QQ, 'x') - sage: K. = NumberField(x^3+x^2+1) - sage: CDF.construction()[0].merge(K.construction()[0]) is None + sage: K. = NumberField(x^3 + x^2 + 1) # optional - sage.rings.number_field + sage: CDF.construction()[0].merge(K.construction()[0]) is None # optional - sage.rings.number_field True - sage: CDF.construction()[0].merge(CDF.construction()[0]) + sage: CDF.construction()[0].merge(CDF.construction()[0]) # optional - sage.rings.number_field AlgebraicClosureFunctor """ @@ -3638,7 +3709,8 @@ def __init__(self, gens, domain): EXAMPLES:: sage: from sage.categories.pushout import PermutationGroupFunctor - sage: PF = PermutationGroupFunctor([PermutationGroupElement([(1,2)])], [1,2]); PF + sage: PF = PermutationGroupFunctor([PermutationGroupElement([(1,2)])], # optional - sage.groups + ....: [1,2]); PF PermutationGroupFunctor[(1,2)] """ Functor.__init__(self, Groups(), Groups()) @@ -3649,9 +3721,9 @@ def _repr_(self): """ EXAMPLES:: - sage: P1 = PermutationGroup([[(1,2)]]) - sage: PF, P = P1.construction() - sage: PF + sage: P1 = PermutationGroup([[(1,2)]]) # optional - sage.groups + sage: PF, P = P1.construction() # optional - sage.groups + sage: PF # optional - sage.groups PermutationGroupFunctor[(1,2)] """ return "PermutationGroupFunctor%s" % list(self.gens()) @@ -3660,9 +3732,9 @@ def __call__(self, R): """ EXAMPLES:: - sage: P1 = PermutationGroup([[(1,2)]]) - sage: PF, P = P1.construction() - sage: PF(P) + sage: P1 = PermutationGroup([[(1,2)]]) # optional - sage.groups + sage: PF, P = P1.construction() # optional - sage.groups + sage: PF(P) # optional - sage.groups Permutation Group with generators [(1,2)] """ from sage.groups.perm_gps.permgroup import PermutationGroup @@ -3673,9 +3745,9 @@ def gens(self): """ EXAMPLES:: - sage: P1 = PermutationGroup([[(1,2)]]) - sage: PF, P = P1.construction() - sage: PF.gens() + sage: P1 = PermutationGroup([[(1,2)]]) # optional - sage.groups + sage: PF, P = P1.construction() # optional - sage.groups + sage: PF.gens() # optional - sage.groups ((1,2),) """ return self._gens @@ -3686,11 +3758,11 @@ def merge(self, other): EXAMPLES:: - sage: P1 = PermutationGroup([[(1,2)]]) - sage: PF1, P = P1.construction() - sage: P2 = PermutationGroup([[(1,3)]]) - sage: PF2, P = P2.construction() - sage: PF1.merge(PF2) + sage: P1 = PermutationGroup([[(1,2)]]) # optional - sage.groups + sage: PF1, P = P1.construction() # optional - sage.groups + sage: P2 = PermutationGroup([[(1,3)]]) # optional - sage.groups + sage: PF2, P = P2.construction() # optional - sage.groups + sage: PF1.merge(PF2) # optional - sage.groups PermutationGroupFunctor[(1,2), (1,3)] """ if self.__class__ != other.__class__: @@ -3736,13 +3808,13 @@ class EquivariantSubobjectConstructionFunctor(ConstructionFunctor): column (index 1); the order of the extra element 2 in a permutation determines whether it is a symmetry or an antisymmetry:: - sage: GSym01 = PermutationGroup([[(0,1),(2,),(3,)]]); GSym01 + sage: GSym01 = PermutationGroup([[(0,1),(2,),(3,)]]); GSym01 # optional - sage.groups Permutation Group with generators [(0,1)] - sage: GASym01 = PermutationGroup([[(0,1),(2,3)]]); GASym01 + sage: GASym01 = PermutationGroup([[(0,1),(2,3)]]); GASym01 # optional - sage.groups Permutation Group with generators [(0,1)(2,3)] sage: from sage.categories.action import Action sage: from sage.structure.element import Matrix - sage: class TensorIndexAction(Action): + sage: class TensorIndexAction(Action): # optional - sage.modules ....: def _act_(self, g, x): ....: if isinstance(x, Matrix): ....: if g(0) == 1: @@ -3753,39 +3825,40 @@ class EquivariantSubobjectConstructionFunctor(ConstructionFunctor): ....: else: ....: return x ....: raise NotImplementedError - sage: M = matrix([[1, 2], [3, 4]]); M + sage: M = matrix([[1, 2], [3, 4]]); M # optional - sage.modules [1 2] [3 4] - sage: GSym01_action = TensorIndexAction(GSym01, M.parent()) - sage: GASym01_action = TensorIndexAction(GASym01, M.parent()) - sage: GSym01_action.act(GSym01.0, M) + sage: GSym01_action = TensorIndexAction(GSym01, M.parent()) # optional - sage.groups sage.modules + sage: GASym01_action = TensorIndexAction(GASym01, M.parent()) # optional - sage.groups sage.modules + sage: GSym01_action.act(GSym01.0, M) # optional - sage.groups sage.modules [1 3] [2 4] - sage: GASym01_action.act(GASym01.0, M) + sage: GASym01_action.act(GASym01.0, M) # optional - sage.groups sage.modules [-1 -3] [-2 -4] - sage: Sym01 = M.parent().invariant_module(GSym01, action=GSym01_action); Sym01 + sage: Sym01 = M.parent().invariant_module(GSym01, action=GSym01_action); Sym01 # optional - sage.groups sage.modules (Permutation Group with generators [(0,1)])-invariant submodule of Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: list(Sym01.basis()) + sage: list(Sym01.basis()) # optional - sage.groups sage.modules [B[0], B[1], B[2]] - sage: list(Sym01.basis().map(Sym01.lift)) + sage: list(Sym01.basis().map(Sym01.lift)) # optional - sage.groups sage.modules [ [1 0] [0 1] [0 0] [0 0], [1 0], [0 1] ] - sage: ASym01 = M.parent().invariant_module(GASym01, action=GASym01_action); ASym01 + sage: ASym01 = M.parent().invariant_module(GASym01, action=GASym01_action) # optional - sage.groups sage.modules + sage: ASym01 # optional - sage.groups sage.modules (Permutation Group with generators [(0,1)(2,3)])-invariant submodule of Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: list(ASym01.basis()) + sage: list(ASym01.basis()) # optional - sage.groups sage.modules [B[0]] - sage: list(ASym01.basis().map(ASym01.lift)) + sage: list(ASym01.basis().map(ASym01.lift)) # optional - sage.groups sage.modules [ [ 0 1] [-1 0] ] sage: from sage.categories.pushout import pushout - sage: pushout(Sym01, QQ) + sage: pushout(Sym01, QQ) # optional - sage.groups sage.modules (Permutation Group with generators [(0,1)])-invariant submodule of Full MatrixSpace of 2 by 2 dense matrices over Rational Field """ @@ -3794,12 +3867,12 @@ def __init__(self, S, action=operator.mul, side='left', """ EXAMPLES:: - sage: G = SymmetricGroup(3); G.rename('S3') - sage: M = FreeModule(ZZ, [1,2,3], prefix='M'); M.rename('M') - sage: action = lambda g, x: M.term(g(x)) - sage: I = M.invariant_module(G, action_on_basis=action); I + sage: G = SymmetricGroup(3); G.rename('S3') # optional - sage.groups sage.modules + sage: M = FreeModule(ZZ, [1,2,3], prefix='M'); M.rename('M') # optional - sage.groups sage.modules + sage: action = lambda g, x: M.term(g(x)) # optional - sage.groups sage.modules + sage: I = M.invariant_module(G, action_on_basis=action); I # optional - sage.groups sage.modules (S3)-invariant submodule of M - sage: I.construction() + sage: I.construction() # optional - sage.groups sage.modules (EquivariantSubobjectConstructionFunctor, Representation of S3 indexed by {1, 2, 3} over Integer Ring) """ @@ -3818,13 +3891,13 @@ def _apply_functor(self, X): TESTS:: sage: from sage.categories.pushout import EquivariantSubobjectConstructionFunctor - sage: M2 = MatrixSpace(QQ, 2); M2 + sage: M2 = MatrixSpace(QQ, 2); M2 # optional - sage.groups sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: F = EquivariantSubobjectConstructionFunctor(M2, - ....: operator.mul, 'left', - ....: operator.mul, 'right'); F + sage: F = EquivariantSubobjectConstructionFunctor(M2, # optional - sage.groups sage.modules + ....: operator.mul, 'left', + ....: operator.mul, 'right'); F EquivariantSubobjectConstructionFunctor - sage: F(M2) + sage: F(M2) # optional - sage.groups sage.modules Traceback (most recent call last): ... NotImplementedError: non-trivial other_action= is not implemented @@ -3843,24 +3916,24 @@ class BlackBoxConstructionFunctor(ConstructionFunctor): EXAMPLES:: sage: from sage.categories.pushout import BlackBoxConstructionFunctor - sage: FG = BlackBoxConstructionFunctor(gap) - sage: FS = BlackBoxConstructionFunctor(singular) - sage: FG + sage: FG = BlackBoxConstructionFunctor(gap) # optional - sage.libs.gap + sage: FS = BlackBoxConstructionFunctor(singular) # optional - sage.libs.singular + sage: FG # optional - sage.libs.gap BlackBoxConstructionFunctor - sage: FG(ZZ) + sage: FG(ZZ) # optional - sage.libs.gap Integers - sage: FG(ZZ).parent() + sage: FG(ZZ).parent() # optional - sage.libs.gap Gap - sage: FS(QQ['t']) + sage: FS(QQ['t']) # optional - sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names t // block 2 : ordering C - sage: FG == FS + sage: FG == FS # optional - sage.libs.gap sage.libs.singular False - sage: FG == loads(dumps(FG)) + sage: FG == loads(dumps(FG)) # optional - sage.libs.gap True """ rank = 100 @@ -3870,11 +3943,11 @@ def __init__(self, box): TESTS:: sage: from sage.categories.pushout import BlackBoxConstructionFunctor - sage: FG = BlackBoxConstructionFunctor(gap) - sage: FM = BlackBoxConstructionFunctor(maxima) # optional - sage.symbolic - sage: FM == FG # optional - sage.symbolic + sage: FG = BlackBoxConstructionFunctor(gap) # optional - sage.libs.gap + sage: FM = BlackBoxConstructionFunctor(maxima) # optional - sage.symbolic + sage: FM == FG # optional - sage.symbolic False - sage: FM == loads(dumps(FM)) # optional - sage.symbolic + sage: FM == loads(dumps(FM)) # optional - sage.symbolic True """ ConstructionFunctor.__init__(self, Objects(), Objects()) @@ -3891,7 +3964,7 @@ def _apply_functor(self, R): sage: from sage.categories.pushout import BlackBoxConstructionFunctor sage: f = lambda x: x^2 sage: F = BlackBoxConstructionFunctor(f) - sage: F(ZZ) # indirect doctest + sage: F(ZZ) # indirect doctest # optional - sage.modules Ambient free module of rank 2 over the principal ideal domain Integer Ring """ @@ -3902,11 +3975,11 @@ def __eq__(self, other): TESTS:: sage: from sage.categories.pushout import BlackBoxConstructionFunctor - sage: FG = BlackBoxConstructionFunctor(gap) - sage: FM = BlackBoxConstructionFunctor(maxima) # optional - sage.symbolic - sage: FM == FG # indirect doctest # optional - sage.symbolic + sage: FG = BlackBoxConstructionFunctor(gap) # optional - sage.libs.gap + sage: FM = BlackBoxConstructionFunctor(maxima) # optional - sage.symbolic + sage: FM == FG # indirect doctest # optional - sage.symbolic False - sage: FM == loads(dumps(FM)) # optional - sage.symbolic + sage: FM == loads(dumps(FM)) # optional - sage.symbolic True """ if not isinstance(other, BlackBoxConstructionFunctor): @@ -3921,11 +3994,11 @@ def __ne__(self, other): EXAMPLES:: sage: from sage.categories.pushout import BlackBoxConstructionFunctor - sage: FG = BlackBoxConstructionFunctor(gap) - sage: FM = BlackBoxConstructionFunctor(maxima) # optional - sage.symbolic - sage: FM != FG # indirect doctest # optional - sage.symbolic + sage: FG = BlackBoxConstructionFunctor(gap) # optional - sage.libs.gap + sage: FM = BlackBoxConstructionFunctor(maxima) # optional - sage.symbolic + sage: FM != FG # indirect doctest # optional - sage.symbolic True - sage: FM != loads(dumps(FM)) # optional - sage.symbolic + sage: FM != loads(dumps(FM)) # optional - sage.symbolic False """ return not (self == other) @@ -3984,16 +4057,19 @@ def pushout(R, S): which give us `Frac(Poly_x(Complete_7(Frac(\ZZ))))`:: sage: from sage.categories.pushout import pushout - sage: pushout(Qp(7), Frac(ZZ['x'])) - Fraction Field of Univariate Polynomial Ring in x over 7-adic Field with capped relative precision 20 + sage: pushout(Qp(7), Frac(ZZ['x'])) # optional - sage.rings.padics + Fraction Field of Univariate Polynomial Ring in x + over 7-adic Field with capped relative precision 20 Note we get the same thing with :: - sage: pushout(Zp(7), Frac(QQ['x'])) - Fraction Field of Univariate Polynomial Ring in x over 7-adic Field with capped relative precision 20 - sage: pushout(Zp(7)['x'], Frac(QQ['x'])) - Fraction Field of Univariate Polynomial Ring in x over 7-adic Field with capped relative precision 20 + sage: pushout(Zp(7), Frac(QQ['x'])) # optional - sage.rings.padics + Fraction Field of Univariate Polynomial Ring in x + over 7-adic Field with capped relative precision 20 + sage: pushout(Zp(7)['x'], Frac(QQ['x'])) # optional - sage.rings.padics + Fraction Field of Univariate Polynomial Ring in x + over 7-adic Field with capped relative precision 20 Note that polynomial variable ordering must be unambiguously determined. :: @@ -4001,49 +4077,57 @@ def pushout(R, S): sage: pushout(ZZ['x,y,z'], QQ['w,z,t']) Traceback (most recent call last): ... - CoercionException: ('Ambiguous Base Extension', Multivariate Polynomial Ring in x, y, z over Integer Ring, Multivariate Polynomial Ring in w, z, t over Rational Field) + CoercionException: ('Ambiguous Base Extension', + Multivariate Polynomial Ring in x, y, z over Integer Ring, + Multivariate Polynomial Ring in w, z, t over Rational Field) sage: pushout(ZZ['x,y,z'], QQ['w,x,z,t']) Multivariate Polynomial Ring in w, x, y, z, t over Rational Field Some other examples:: - sage: pushout(Zp(7)['y'], Frac(QQ['t'])['x,y,z']) - Multivariate Polynomial Ring in x, y, z over Fraction Field of Univariate Polynomial Ring in t over 7-adic Field with capped relative precision 20 + sage: pushout(Zp(7)['y'], Frac(QQ['t'])['x,y,z']) # optional - sage.rings.padics + Multivariate Polynomial Ring in x, y, z + over Fraction Field of Univariate Polynomial Ring in t + over 7-adic Field with capped relative precision 20 sage: pushout(ZZ['x,y,z'], Frac(ZZ['x'])['y']) - Multivariate Polynomial Ring in y, z over Fraction Field of Univariate Polynomial Ring in x over Integer Ring - sage: pushout(MatrixSpace(RDF, 2, 2), Frac(ZZ['x'])) - Full MatrixSpace of 2 by 2 dense matrices over Fraction Field of Univariate Polynomial Ring in x over Real Double Field - sage: pushout(ZZ, MatrixSpace(ZZ[['x']], 3, 3)) - Full MatrixSpace of 3 by 3 dense matrices over Power Series Ring in x over Integer Ring + Multivariate Polynomial Ring in y, z + over Fraction Field of Univariate Polynomial Ring in x over Integer Ring + sage: pushout(MatrixSpace(RDF, 2, 2), Frac(ZZ['x'])) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices + over Fraction Field of Univariate Polynomial Ring in x over Real Double Field + sage: pushout(ZZ, MatrixSpace(ZZ[['x']], 3, 3)) # optional - sage.modules + Full MatrixSpace of 3 by 3 dense matrices + over Power Series Ring in x over Integer Ring sage: pushout(QQ['x,y'], ZZ[['x']]) - Univariate Polynomial Ring in y over Power Series Ring in x over Rational Field + Univariate Polynomial Ring in y + over Power Series Ring in x over Rational Field sage: pushout(Frac(ZZ['x']), QQ[['x']]) Laurent Series Ring in x over Rational Field - A construction with ``coercion_reversed = True`` (currently only + A construction with ``coercion_reversed=True`` (currently only the :class:`SubspaceFunctor` construction) is only applied if it leads to a valid coercion:: - sage: A = ZZ^2 - sage: V = span([[1, 2]], QQ) - sage: P = sage.categories.pushout.pushout(A, V) - sage: P + sage: A = ZZ^2 # optional - sage.modules + sage: V = span([[1, 2]], QQ) # optional - sage.modules + sage: P = sage.categories.pushout.pushout(A, V) # optional - sage.modules + sage: P # optional - sage.modules Vector space of dimension 2 over Rational Field - sage: P.has_coerce_map_from(A) + sage: P.has_coerce_map_from(A) # optional - sage.modules True - sage: V = (QQ^3).span([[1, 2, 3/4]]) - sage: A = ZZ^3 - sage: pushout(A, V) + sage: V = (QQ^3).span([[1, 2, 3/4]]) # optional - sage.modules + sage: A = ZZ^3 # optional - sage.modules + sage: pushout(A, V) # optional - sage.modules Vector space of dimension 3 over Rational Field - sage: B = A.span([[0, 0, 2/3]]) - sage: pushout(B, V) + sage: B = A.span([[0, 0, 2/3]]) # optional - sage.modules + sage: pushout(B, V) # optional - sage.modules Vector space of degree 3 and dimension 2 over Rational Field User basis matrix: [1 2 0] [0 0 1] - Some more tests with ``coercion_reversed = True``:: + Some more tests with ``coercion_reversed=True``:: sage: from sage.categories.pushout import ConstructionFunctor sage: class EvenPolynomialRing(type(QQ['x'])): @@ -4082,10 +4166,14 @@ def pushout(R, S): sage: pushout(EvenPolynomialRing(QQ, 'x'), EvenPolynomialRing(RR, 'x')) Even Power Univariate Polynomial Ring in x over Real Field with 53 bits of precision - sage: pushout(EvenPolynomialRing(QQ, 'x')^2, RR^2) - Ambient free module of rank 2 over the principal ideal domain Even Power Univariate Polynomial Ring in x over Real Field with 53 bits of precision - sage: pushout(EvenPolynomialRing(QQ, 'x')^2, RR['x']^2) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Real Field with 53 bits of precision + sage: pushout(EvenPolynomialRing(QQ, 'x')^2, RR^2) # optional - sage.modules + Ambient free module of rank 2 + over the principal ideal domain Even Power Univariate Polynomial Ring in x + over Real Field with 53 bits of precision + sage: pushout(EvenPolynomialRing(QQ, 'x')^2, RR['x']^2) # optional - sage.modules + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x + over Real Field with 53 bits of precision Some more tests related to univariate/multivariate constructions. We consider a generalization of polynomial rings, @@ -4153,7 +4241,8 @@ def pushout(R, S): sage: pushout(GP_ZZ(ZZ), GP_ZZ(QQ)) Generalized Polynomial Ring in X^(Integer Ring) over Rational Field sage: pushout(GP_ZZ(ZZ['t']), GP_ZZ(QQ)) - Generalized Polynomial Ring in X^(Integer Ring) over Univariate Polynomial Ring in t over Rational Field + Generalized Polynomial Ring in X^(Integer Ring) + over Univariate Polynomial Ring in t over Rational Field sage: pushout(GP_ZZ(ZZ['a,b']), GP_ZZ(ZZ['b,c'])) Generalized Polynomial Ring in X^(Integer Ring) over Multivariate Polynomial Ring in a, b, c over Integer Ring @@ -4197,14 +4286,17 @@ def pushout(R, S): ... CoercionException: ('Ambiguous Base Extension', ...) sage: pushout(GP_ZZt(ZZ['a,b']), GP_QQ(ZZ['b,c'])) - Generalized Polynomial Ring in X^(Univariate Polynomial Ring in t over Rational Field) + Generalized Polynomial Ring + in X^(Univariate Polynomial Ring in t over Rational Field) over Multivariate Polynomial Ring in a, b, c over Integer Ring Some tests with Cartesian products:: sage: from sage.sets.cartesian_product import CartesianProduct - sage: A = CartesianProduct((ZZ['x'], QQ['y'], QQ['z']), Sets().CartesianProducts()) - sage: B = CartesianProduct((ZZ['x'], ZZ['y'], ZZ['t']['z']), Sets().CartesianProducts()) + sage: A = CartesianProduct((ZZ['x'], QQ['y'], QQ['z']), + ....: Sets().CartesianProducts()) + sage: B = CartesianProduct((ZZ['x'], ZZ['y'], ZZ['t']['z']), + ....: Sets().CartesianProducts()) sage: A.construction() (The cartesian_product functorial construction, (Univariate Polynomial Ring in x over Integer Ring, @@ -4214,7 +4306,8 @@ def pushout(R, S): The Cartesian product of (Univariate Polynomial Ring in x over Integer Ring, Univariate Polynomial Ring in y over Rational Field, - Univariate Polynomial Ring in z over Univariate Polynomial Ring in t over Rational Field) + Univariate Polynomial Ring in z over + Univariate Polynomial Ring in t over Rational Field) sage: pushout(ZZ, cartesian_product([ZZ, QQ])) Traceback (most recent call last): ... @@ -4226,10 +4319,12 @@ def pushout(R, S): sage: from sage.sets.cartesian_product import CartesianProduct sage: class CartesianProductPoly(CartesianProduct): ....: def __init__(self, polynomial_rings): - ....: sort = sorted(polynomial_rings, key=lambda P: P.variable_name()) + ....: sort = sorted(polynomial_rings, + ....: key=lambda P: P.variable_name()) ....: super().__init__(sort, Sets().CartesianProducts()) ....: def vars(self): - ....: return tuple(P.variable_name() for P in self.cartesian_factors()) + ....: return tuple(P.variable_name() + ....: for P in self.cartesian_factors()) ....: def _pushout_(self, other): ....: if isinstance(other, CartesianProductPoly): ....: s_vars = self.vars() @@ -4263,7 +4358,7 @@ def pushout(R, S): (Univariate Polynomial Ring in x over Integer Ring, Univariate Polynomial Ring in y over Integer Ring, Univariate Polynomial Ring in z over Integer Ring) - sage: pushout(CartesianProductPoly((QQ['a,b']['x'], QQ['y'])), # optional - sage.symbolic + sage: pushout(CartesianProductPoly((QQ['a,b']['x'], QQ['y'])), # optional - sage.symbolic ....: CartesianProductPoly((ZZ['b,c']['x'], SR['z']))) The Cartesian product of (Univariate Polynomial Ring in x over @@ -4476,14 +4571,16 @@ def pushout_lattice(R, S): EXAMPLES:: sage: from sage.categories.pushout import pushout_lattice - sage: A, B = pushout_lattice(Qp(7), Frac(ZZ['x'])) - sage: A.codomain() - Fraction Field of Univariate Polynomial Ring in x over 7-adic Field with capped relative precision 20 - sage: A.codomain() is B.codomain() + sage: A, B = pushout_lattice(Qp(7), Frac(ZZ['x'])) # optional - sage.rings.padics + sage: A.codomain() # optional - sage.rings.padics + Fraction Field of Univariate Polynomial Ring in x + over 7-adic Field with capped relative precision 20 + sage: A.codomain() is B.codomain() # optional - sage.rings.padics True - sage: A, B = pushout_lattice(ZZ, MatrixSpace(ZZ[['x']], 3, 3)) - sage: B - Identity endomorphism of Full MatrixSpace of 3 by 3 dense matrices over Power Series Ring in x over Integer Ring + sage: A, B = pushout_lattice(ZZ, MatrixSpace(ZZ[['x']], 3, 3)) # optional - sage.modules + sage: B # optional - sage.modules + Identity endomorphism of Full MatrixSpace of 3 by 3 dense matrices + over Power Series Ring in x over Integer Ring AUTHOR: @@ -4652,8 +4749,13 @@ def construction_tower(R): EXAMPLES:: sage: from sage.categories.pushout import construction_tower - sage: construction_tower(MatrixSpace(FractionField(QQ['t']),2)) - [(None, Full MatrixSpace of 2 by 2 dense matrices over Fraction Field of Univariate Polynomial Ring in t over Rational Field), (MatrixFunctor, Fraction Field of Univariate Polynomial Ring in t over Rational Field), (FractionField, Univariate Polynomial Ring in t over Rational Field), (Poly[t], Rational Field), (FractionField, Integer Ring)] + sage: construction_tower(MatrixSpace(FractionField(QQ['t']), 2)) # optional - sage.modules + [(None, Full MatrixSpace of 2 by 2 dense matrices over Fraction Field + of Univariate Polynomial Ring in t over Rational Field), + (MatrixFunctor, Fraction Field + of Univariate Polynomial Ring in t over Rational Field), + (FractionField, Univariate Polynomial Ring in t over Rational Field), + (Poly[t], Rational Field), (FractionField, Integer Ring)] """ tower = [(None, R)] @@ -4691,7 +4793,8 @@ def expand_tower(tower): (FractionField, Integer Ring)] sage: expand_tower(construction_tower(QQ['x,y,z'])) [(None, Multivariate Polynomial Ring in x, y, z over Rational Field), - (MPoly[z], Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field), + (MPoly[z], Univariate Polynomial Ring in y + over Univariate Polynomial Ring in x over Rational Field), (MPoly[y], Univariate Polynomial Ring in x over Rational Field), (MPoly[x], Rational Field), (FractionField, Integer Ring)] diff --git a/src/sage/categories/quantum_group_representations.py b/src/sage/categories/quantum_group_representations.py index 125f06c03fa..08219858ca5 100644 --- a/src/sage/categories/quantum_group_representations.py +++ b/src/sage/categories/quantum_group_representations.py @@ -38,7 +38,7 @@ def super_categories(self): sage: from sage.categories.quantum_group_representations import QuantumGroupRepresentations sage: QuantumGroupRepresentations(ZZ['q'].fraction_field()).super_categories() [Category of vector spaces over - Fraction Field of Univariate Polynomial Ring in q over Integer Ring] + Fraction Field of Univariate Polynomial Ring in q over Integer Ring] """ return [Modules(self.base_ring())] @@ -51,7 +51,7 @@ def example(self): sage: from sage.categories.quantum_group_representations import QuantumGroupRepresentations sage: Cat = QuantumGroupRepresentations(ZZ['q'].fraction_field()) - sage: Cat.example() + sage: Cat.example() # optional - sage.combinat sage.modules V((2, 1, 0)) """ from sage.algebras.quantum_groups.representations import AdjointRepresentation @@ -79,7 +79,7 @@ def extra_super_categories(self): sage: Cat = QuantumGroupRepresentations(ZZ['q'].fraction_field()) sage: Cat.WithBasis().TensorProducts().extra_super_categories() [Category of quantum group representations with basis over - Fraction Field of Univariate Polynomial Ring in q over Integer Ring] + Fraction Field of Univariate Polynomial Ring in q over Integer Ring] """ return [self.base_category()] @@ -96,34 +96,34 @@ def e_on_basis(self, i, b): EXAMPLES:: - sage: from sage.algebras.quantum_groups.representations import \ - ....: MinusculeRepresentation, AdjointRepresentation + sage: from sage.algebras.quantum_groups.representations import ( # optional - sage.combinat sage.modules + ....: MinusculeRepresentation, AdjointRepresentation) sage: R = ZZ['q'].fraction_field() - sage: CM = crystals.Tableaux(['D',4], shape=[1]) - sage: VM = MinusculeRepresentation(R, CM) - sage: CA = crystals.Tableaux(['D',4], shape=[1,1]) - sage: VA = AdjointRepresentation(R, CA) - sage: v = tensor([VM.an_element(), VA.an_element()]); v + sage: CM = crystals.Tableaux(['D',4], shape=[1]) # optional - sage.combinat sage.modules + sage: VM = MinusculeRepresentation(R, CM) # optional - sage.combinat sage.modules + sage: CA = crystals.Tableaux(['D',4], shape=[1,1]) # optional - sage.combinat sage.modules + sage: VA = AdjointRepresentation(R, CA) # optional - sage.combinat sage.modules + sage: v = tensor([VM.an_element(), VA.an_element()]); v # optional - sage.combinat sage.modules 4*B[[[1]]] # B[[[1], [2]]] + 4*B[[[1]]] # B[[[1], [3]]] + 6*B[[[1]]] # B[[[2], [3]]] + 4*B[[[2]]] # B[[[1], [2]]] + 4*B[[[2]]] # B[[[1], [3]]] + 6*B[[[2]]] # B[[[2], [3]]] + 6*B[[[3]]] # B[[[1], [2]]] + 6*B[[[3]]] # B[[[1], [3]]] + 9*B[[[3]]] # B[[[2], [3]]] - sage: v.e(1) # indirect doctest + sage: v.e(1) # indirect doctest # optional - sage.combinat sage.modules 4*B[[[1]]] # B[[[1], [2]]] + ((4*q+6)/q)*B[[[1]]] # B[[[1], [3]]] + 6*B[[[1]]] # B[[[2], [3]]] + 6*q*B[[[2]]] # B[[[1], [3]]] + 9*B[[[3]]] # B[[[1], [3]]] - sage: v.e(2) # indirect doctest + sage: v.e(2) # indirect doctest # optional - sage.combinat sage.modules 4*B[[[1]]] # B[[[1], [2]]] + ((6*q+4)/q)*B[[[2]]] # B[[[1], [2]]] + 6*B[[[2]]] # B[[[1], [3]]] + 9*B[[[2]]] # B[[[2], [3]]] + 6*q*B[[[3]]] # B[[[1], [2]]] - sage: v.e(3) # indirect doctest + sage: v.e(3) # indirect doctest # optional - sage.combinat sage.modules 0 - sage: v.e(4) # indirect doctest + sage: v.e(4) # indirect doctest # optional - sage.combinat sage.modules 0 """ K_elt = [self._sets[k].K_on_basis(i, elt, -1) for k,elt in enumerate(b)] @@ -146,38 +146,38 @@ def f_on_basis(self, i, b): EXAMPLES:: - sage: from sage.algebras.quantum_groups.representations import \ - ....: MinusculeRepresentation, AdjointRepresentation + sage: from sage.algebras.quantum_groups.representations import ( # optional - sage.combinat sage.modules + ....: MinusculeRepresentation, AdjointRepresentation) sage: R = ZZ['q'].fraction_field() - sage: KM = crystals.KirillovReshetikhin(['B',3,1], 3,1) - sage: VM = MinusculeRepresentation(R, KM) - sage: KA = crystals.KirillovReshetikhin(['B',3,1], 2,1) - sage: VA = AdjointRepresentation(R, KA) - sage: v = tensor([VM.an_element(), VA.an_element()]); v + sage: KM = crystals.KirillovReshetikhin(['B',3,1], 3,1) # optional - sage.combinat sage.modules + sage: VM = MinusculeRepresentation(R, KM) # optional - sage.combinat sage.modules + sage: KA = crystals.KirillovReshetikhin(['B',3,1], 2,1) # optional - sage.combinat sage.modules + sage: VA = AdjointRepresentation(R, KA) # optional - sage.combinat sage.modules + sage: v = tensor([VM.an_element(), VA.an_element()]); v # optional - sage.combinat sage.modules 4*B[[+++, []]] # B[[]] + 4*B[[+++, []]] # B[[[1], [2]]] + 6*B[[+++, []]] # B[[[1], [3]]] + 4*B[[++-, []]] # B[[]] + 4*B[[++-, []]] # B[[[1], [2]]] + 6*B[[++-, []]] # B[[[1], [3]]] + 6*B[[+-+, []]] # B[[]] + 6*B[[+-+, []]] # B[[[1], [2]]] + 9*B[[+-+, []]] # B[[[1], [3]]] - sage: v.f(0) # indirect doctest + sage: v.f(0) # indirect doctest # optional - sage.combinat sage.modules ((4*q^4+4)/q^2)*B[[+++, []]] # B[[[1], [2]]] + ((4*q^4+4)/q^2)*B[[++-, []]] # B[[[1], [2]]] + ((6*q^4+6)/q^2)*B[[+-+, []]] # B[[[1], [2]]] - sage: v.f(1) # indirect doctest + sage: v.f(1) # indirect doctest # optional - sage.combinat sage.modules 6*B[[+++, []]] # B[[[2], [3]]] + 6*B[[++-, []]] # B[[[2], [3]]] + 9*B[[+-+, []]] # B[[[2], [3]]] + 6*B[[-++, []]] # B[[]] + 6*B[[-++, []]] # B[[[1], [2]]] + 9*q^2*B[[-++, []]] # B[[[1], [3]]] - sage: v.f(2) # indirect doctest + sage: v.f(2) # indirect doctest # optional - sage.combinat sage.modules 4*B[[+++, []]] # B[[[1], [3]]] + 4*B[[++-, []]] # B[[[1], [3]]] + 4*B[[+-+, []]] # B[[]] + 4*q^2*B[[+-+, []]] # B[[[1], [2]]] + ((6*q^2+6)/q^2)*B[[+-+, []]] # B[[[1], [3]]] - sage: v.f(3) # indirect doctest + sage: v.f(3) # indirect doctest # optional - sage.combinat sage.modules 6*B[[+++, []]] # B[[[1], [0]]] + 4*B[[++-, []]] # B[[]] + 4*B[[++-, []]] # B[[[1], [2]]] @@ -209,22 +209,22 @@ def K_on_basis(self, i, b, power=1): EXAMPLES:: - sage: from sage.algebras.quantum_groups.representations import \ - ....: MinusculeRepresentation, AdjointRepresentation + sage: from sage.algebras.quantum_groups.representations import ( # optional - sage.combinat sage.modules + ....: MinusculeRepresentation, AdjointRepresentation) sage: R = ZZ['q'].fraction_field() - sage: CM = crystals.Tableaux(['A',2], shape=[1]) - sage: VM = MinusculeRepresentation(R, CM) - sage: CA = crystals.Tableaux(['A',2], shape=[2,1]) - sage: VA = AdjointRepresentation(R, CA) - sage: v = tensor([sum(VM.basis()), VA.module_generator()]); v + sage: CM = crystals.Tableaux(['A',2], shape=[1]) # optional - sage.combinat sage.modules + sage: VM = MinusculeRepresentation(R, CM) # optional - sage.combinat sage.modules + sage: CA = crystals.Tableaux(['A',2], shape=[2,1]) # optional - sage.combinat sage.modules + sage: VA = AdjointRepresentation(R, CA) # optional - sage.combinat sage.modules + sage: v = tensor([sum(VM.basis()), VA.module_generator()]); v # optional - sage.combinat sage.modules B[[[1]]] # B[[[1, 1], [2]]] + B[[[2]]] # B[[[1, 1], [2]]] + B[[[3]]] # B[[[1, 1], [2]]] - sage: v.K(1) # indirect doctest + sage: v.K(1) # indirect doctest # optional - sage.combinat sage.modules q^2*B[[[1]]] # B[[[1, 1], [2]]] + B[[[2]]] # B[[[1, 1], [2]]] + q*B[[[3]]] # B[[[1, 1], [2]]] - sage: v.K(2, -1) # indirect doctest + sage: v.K(2, -1) # indirect doctest # optional - sage.combinat sage.modules 1/q*B[[[1]]] # B[[[1, 1], [2]]] + 1/q^2*B[[[2]]] # B[[[1, 1], [2]]] + B[[[3]]] # B[[[1, 1], [2]]] @@ -241,24 +241,24 @@ def tensor(*factors): EXAMPLES:: - sage: from sage.algebras.quantum_groups.representations import \ - ....: MinusculeRepresentation, AdjointRepresentation + sage: from sage.algebras.quantum_groups.representations import ( # optional - sage.combinat sage.modules + ....: MinusculeRepresentation, AdjointRepresentation) sage: R = ZZ['q'].fraction_field() - sage: CM = crystals.Tableaux(['D',4], shape=[1]) - sage: CA = crystals.Tableaux(['D',4], shape=[1,1]) - sage: V = MinusculeRepresentation(R, CM) - sage: V.tensor(V, V) + sage: CM = crystals.Tableaux(['D',4], shape=[1]) # optional - sage.combinat sage.modules + sage: CA = crystals.Tableaux(['D',4], shape=[1,1]) # optional - sage.combinat sage.modules + sage: V = MinusculeRepresentation(R, CM) # optional - sage.combinat sage.modules + sage: V.tensor(V, V) # optional - sage.combinat sage.modules V((1, 0, 0, 0)) # V((1, 0, 0, 0)) # V((1, 0, 0, 0)) - sage: A = MinusculeRepresentation(R, CA) - sage: V.tensor(A) + sage: A = MinusculeRepresentation(R, CA) # optional - sage.combinat sage.modules + sage: V.tensor(A) # optional - sage.combinat sage.modules V((1, 0, 0, 0)) # V((1, 1, 0, 0)) - sage: B = crystals.Tableaux(['A',2], shape=[1]) - sage: W = MinusculeRepresentation(R, B) - sage: tensor([W,V]) + sage: B = crystals.Tableaux(['A',2], shape=[1]) # optional - sage.combinat sage.modules + sage: W = MinusculeRepresentation(R, B) # optional - sage.combinat sage.modules + sage: tensor([W,V]) # optional - sage.combinat sage.modules Traceback (most recent call last): ... ValueError: all factors must be of the same Cartan type - sage: tensor([V,A,W]) + sage: tensor([V,A,W]) # optional - sage.combinat sage.modules Traceback (most recent call last): ... ValueError: all factors must be of the same Cartan type @@ -279,15 +279,15 @@ def e(self, i): EXAMPLES:: - sage: from sage.algebras.quantum_groups.representations import AdjointRepresentation - sage: C = crystals.Tableaux(['G',2], shape=[1,1]) - sage: R = ZZ['q'].fraction_field() - sage: V = AdjointRepresentation(R, C) - sage: v = V.an_element(); v + sage: from sage.algebras.quantum_groups.representations import AdjointRepresentation # optional - sage.combinat sage.modules + sage: C = crystals.Tableaux(['G',2], shape=[1,1]) # optional - sage.combinat sage.modules + sage: R = ZZ['q'].fraction_field() # optional - sage.combinat sage.modules + sage: V = AdjointRepresentation(R, C) # optional - sage.combinat sage.modules + sage: v = V.an_element(); v # optional - sage.combinat sage.modules 2*B[[[1], [2]]] + 2*B[[[1], [3]]] + 3*B[[[2], [3]]] - sage: v.e(1) + sage: v.e(1) # optional - sage.combinat sage.modules ((3*q^4+3*q^2+3)/q^2)*B[[[1], [3]]] - sage: v.e(2) + sage: v.e(2) # optional - sage.combinat sage.modules 2*B[[[1], [2]]] """ F = self.parent() @@ -305,21 +305,21 @@ def f(self, i): EXAMPLES:: - sage: from sage.algebras.quantum_groups.representations import AdjointRepresentation - sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,1) - sage: R = ZZ['q'].fraction_field() - sage: V = AdjointRepresentation(R, K) - sage: v = V.an_element(); v + sage: from sage.algebras.quantum_groups.representations import AdjointRepresentation # optional - sage.combinat sage.modules + sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,1) # optional - sage.combinat sage.modules + sage: R = ZZ['q'].fraction_field() # optional - sage.combinat sage.modules + sage: V = AdjointRepresentation(R, K) # optional - sage.combinat sage.modules + sage: v = V.an_element(); v # optional - sage.combinat sage.modules 2*B[[]] + 2*B[[[1], [2]]] + 3*B[[[1], [3]]] - sage: v.f(0) + sage: v.f(0) # optional - sage.combinat sage.modules ((2*q^2+2)/q)*B[[[1], [2]]] - sage: v.f(1) + sage: v.f(1) # optional - sage.combinat sage.modules 3*B[[[2], [3]]] - sage: v.f(2) + sage: v.f(2) # optional - sage.combinat sage.modules 2*B[[[1], [3]]] - sage: v.f(3) + sage: v.f(3) # optional - sage.combinat sage.modules 3*B[[[1], [4]]] - sage: v.f(4) + sage: v.f(4) # optional - sage.combinat sage.modules 3*B[[[1], [-4]]] """ F = self.parent() @@ -338,19 +338,19 @@ def K(self, i, power=1): EXAMPLES:: - sage: from sage.algebras.quantum_groups.representations import AdjointRepresentation - sage: K = crystals.KirillovReshetikhin(['D',4,2], 1,1) - sage: R = ZZ['q'].fraction_field() - sage: V = AdjointRepresentation(R, K) - sage: v = V.an_element(); v + sage: from sage.algebras.quantum_groups.representations import AdjointRepresentation # optional - sage.combinat sage.modules + sage: K = crystals.KirillovReshetikhin(['D',4,2], 1,1) # optional - sage.combinat sage.modules + sage: R = ZZ['q'].fraction_field() # optional - sage.combinat sage.modules + sage: V = AdjointRepresentation(R, K) # optional - sage.combinat sage.modules + sage: v = V.an_element(); v # optional - sage.combinat sage.modules 2*B[[]] + 2*B[[[1]]] + 3*B[[[2]]] - sage: v.K(0) + sage: v.K(0) # optional - sage.combinat sage.modules 2*B[[]] + 2/q^2*B[[[1]]] + 3*B[[[2]]] - sage: v.K(1) + sage: v.K(1) # optional - sage.combinat sage.modules 2*B[[]] + 2*q^2*B[[[1]]] + 3/q^2*B[[[2]]] - sage: v.K(1, 2) + sage: v.K(1, 2) # optional - sage.combinat sage.modules 2*B[[]] + 2*q^4*B[[[1]]] + 3/q^4*B[[[2]]] - sage: v.K(1, -1) + sage: v.K(1, -1) # optional - sage.combinat sage.modules 2*B[[]] + 2/q^2*B[[[1]]] + 3*q^2*B[[[2]]] """ F = self.parent() @@ -388,12 +388,12 @@ def cartan_type(self): EXAMPLES:: - sage: from sage.algebras.quantum_groups.representations import MinusculeRepresentation - sage: C = crystals.Tableaux(['C',2], shape=[1]) - sage: R = ZZ['q'].fraction_field() - sage: V = MinusculeRepresentation(R, C) - sage: T = tensor([V,V]) - sage: T.cartan_type() + sage: from sage.algebras.quantum_groups.representations import MinusculeRepresentation # optional - sage.combinat sage.modules + sage: C = crystals.Tableaux(['C',2], shape=[1]) # optional - sage.combinat sage.modules + sage: R = ZZ['q'].fraction_field() # optional - sage.combinat sage.modules + sage: V = MinusculeRepresentation(R, C) # optional - sage.combinat sage.modules + sage: T = tensor([V,V]) # optional - sage.combinat sage.modules + sage: T.cartan_type() # optional - sage.combinat sage.modules ['C', 2] """ return self._sets[0].cartan_type() @@ -407,18 +407,18 @@ def _test_representation(self, tester=None, **options): EXAMPLES:: - sage: from sage.algebras.quantum_groups.representations import \ - ....: MinusculeRepresentation, AdjointRepresentation - sage: C = crystals.Tableaux(['G',2], shape=[1,1]) - sage: R = ZZ['q'].fraction_field() - sage: V = AdjointRepresentation(R, C) - sage: V._test_representation() + sage: from sage.algebras.quantum_groups.representations import ( # optional - sage.combinat sage.modules + ....: MinusculeRepresentation, AdjointRepresentation) + sage: C = crystals.Tableaux(['G',2], shape=[1,1]) # optional - sage.combinat sage.modules + sage: R = ZZ['q'].fraction_field() # optional - sage.combinat sage.modules + sage: V = AdjointRepresentation(R, C) # optional - sage.combinat sage.modules + sage: V._test_representation() # optional - sage.combinat sage.modules We verify that ``C`` does not define a minuscule representation:: - sage: M = MinusculeRepresentation(R, C) - sage: M._test_representation() + sage: M = MinusculeRepresentation(R, C) # optional - sage.combinat sage.modules + sage: M._test_representation() # optional - sage.combinat sage.modules Traceback (most recent call last): ... AssertionError: [e,f] = (K-K^-1)/(q_i-q_i^-1) -- i: 1 j: 1 @@ -489,11 +489,11 @@ def cartan_type(self): EXAMPLES:: - sage: from sage.algebras.quantum_groups.representations import MinusculeRepresentation - sage: C = crystals.Tableaux(['C',4], shape=[1]) - sage: R = ZZ['q'].fraction_field() - sage: V = MinusculeRepresentation(R, C) - sage: V.cartan_type() + sage: from sage.algebras.quantum_groups.representations import MinusculeRepresentation # optional - sage.combinat sage.modules + sage: C = crystals.Tableaux(['C',4], shape=[1]) # optional - sage.combinat sage.modules + sage: R = ZZ['q'].fraction_field() # optional - sage.combinat sage.modules + sage: V = MinusculeRepresentation(R, C) # optional - sage.combinat sage.modules + sage: V.cartan_type() # optional - sage.combinat sage.modules ['C', 4] """ @@ -504,11 +504,11 @@ def index_set(self): EXAMPLES:: - sage: from sage.algebras.quantum_groups.representations import MinusculeRepresentation - sage: C = crystals.Tableaux(['C',4], shape=[1]) - sage: R = ZZ['q'].fraction_field() - sage: V = MinusculeRepresentation(R, C) - sage: V.index_set() + sage: from sage.algebras.quantum_groups.representations import MinusculeRepresentation # optional - sage.combinat sage.modules + sage: C = crystals.Tableaux(['C',4], shape=[1]) # optional - sage.combinat sage.modules + sage: R = ZZ['q'].fraction_field() # optional - sage.combinat sage.modules + sage: V = MinusculeRepresentation(R, C) # optional - sage.combinat sage.modules + sage: V.index_set() # optional - sage.combinat sage.modules (1, 2, 3, 4) """ return self.cartan_type().index_set() @@ -519,11 +519,11 @@ def q(self): EXAMPLES:: - sage: from sage.algebras.quantum_groups.representations import MinusculeRepresentation - sage: C = crystals.Tableaux(['C',4], shape=[1]) - sage: R = ZZ['q'].fraction_field() - sage: V = MinusculeRepresentation(R, C) - sage: V.q() + sage: from sage.algebras.quantum_groups.representations import MinusculeRepresentation # optional - sage.combinat sage.modules + sage: C = crystals.Tableaux(['C',4], shape=[1]) # optional - sage.combinat sage.modules + sage: R = ZZ['q'].fraction_field() # optional - sage.combinat sage.modules + sage: V = MinusculeRepresentation(R, C) # optional - sage.combinat sage.modules + sage: V.q() # optional - sage.combinat sage.modules q """ return self._q diff --git a/src/sage/categories/quotient_fields.py b/src/sage/categories/quotient_fields.py index 02780268c8f..c62c79ee11f 100644 --- a/src/sage/categories/quotient_fields.py +++ b/src/sage/categories/quotient_fields.py @@ -75,17 +75,17 @@ def gcd(self, other): sage: R. = QQ['x'] sage: p = (1+x)^3*(1+2*x^2)/(1-x^5) sage: q = (1+x)^2*(1+3*x^2)/(1-x^4) - sage: factor(p) + sage: factor(p) # optional - sage.libs.pari (-2) * (x - 1)^-1 * (x + 1)^3 * (x^2 + 1/2) * (x^4 + x^3 + x^2 + x + 1)^-1 - sage: factor(q) + sage: factor(q) # optional - sage.libs.pari (-3) * (x - 1)^-1 * (x + 1) * (x^2 + 1)^-1 * (x^2 + 1/3) - sage: gcd(p,q) + sage: gcd(p, q) (x + 1)/(x^7 + x^5 - x^2 - 1) - sage: factor(gcd(p,q)) + sage: factor(gcd(p, q)) # optional - sage.libs.pari (x - 1)^-1 * (x + 1) * (x^2 + 1)^-1 * (x^4 + x^3 + x^2 + x + 1)^-1 - sage: factor(gcd(p,1+x)) + sage: factor(gcd(p, 1 + x)) # optional - sage.libs.pari (x - 1)^-1 * (x + 1) * (x^4 + x^3 + x^2 + x + 1)^-1 - sage: factor(gcd(1+x,q)) + sage: factor(gcd(1 + x, q)) # optional - sage.libs.pari (x - 1)^-1 * (x + 1) * (x^2 + 1)^-1 TESTS: @@ -93,22 +93,25 @@ def gcd(self, other): The following tests that the fraction field returns a correct gcd even if the base ring does not provide lcm and gcd:: - sage: R = ZZ.extension(x^2+1, names='i') - sage: i = R.1 - sage: gcd(5, 3 + 4*i) + sage: R = ZZ.extension(x^2 + 1, names='i') # optional - sage.rings.number_field + sage: i = R.1 # optional - sage.rings.number_field + sage: gcd(5, 3 + 4*i) # optional - sage.rings.number_field -i - 2 - sage: P. = R[] - sage: gcd(t, i) + sage: P. = R[] # optional - sage.rings.number_field + sage: gcd(t, i) # optional - sage.rings.number_field Traceback (most recent call last): ... - NotImplementedError: Gaussian Integers in Number Field in i with defining polynomial x^2 + 1 does not provide a gcd implementation for univariate polynomials - sage: q = t/(t+1); q.parent() - Fraction Field of Univariate Polynomial Ring in t over Gaussian Integers in Number Field in i with defining polynomial x^2 + 1 - sage: gcd(q, q) + NotImplementedError: Gaussian Integers in Number Field in i with + defining polynomial x^2 + 1 does not provide a gcd implementation + for univariate polynomials + sage: q = t/(t + 1); q.parent() # optional - sage.rings.number_field + Fraction Field of Univariate Polynomial Ring in t over Gaussian + Integers in Number Field in i with defining polynomial x^2 + 1 + sage: gcd(q, q) # optional - sage.rings.number_field 1 - sage: q.gcd(0) + sage: q.gcd(0) # optional - sage.rings.number_field 1 - sage: (q*0).gcd(0) + sage: (q*0).gcd(0) # optional - sage.rings.number_field 0 """ P = self.parent() @@ -177,15 +180,15 @@ def lcm(self, other): sage: R. = QQ[] sage: p = (1+x)^3*(1+2*x^2)/(1-x^5) sage: q = (1+x)^2*(1+3*x^2)/(1-x^4) - sage: factor(p) + sage: factor(p) # optional - sage.libs.pari (-2) * (x - 1)^-1 * (x + 1)^3 * (x^2 + 1/2) * (x^4 + x^3 + x^2 + x + 1)^-1 - sage: factor(q) + sage: factor(q) # optional - sage.libs.pari (-3) * (x - 1)^-1 * (x + 1) * (x^2 + 1)^-1 * (x^2 + 1/3) - sage: factor(lcm(p,q)) + sage: factor(lcm(p, q)) # optional - sage.libs.pari (x - 1)^-1 * (x + 1)^3 * (x^2 + 1/3) * (x^2 + 1/2) - sage: factor(lcm(p,1+x)) + sage: factor(lcm(p, 1 + x)) # optional - sage.libs.pari (x + 1)^3 * (x^2 + 1/2) - sage: factor(lcm(1+x,q)) + sage: factor(lcm(1 + x, q)) # optional - sage.libs.pari (x + 1) * (x^2 + 1/3) TESTS: @@ -193,20 +196,23 @@ def lcm(self, other): The following tests that the fraction field returns a correct lcm even if the base ring does not provide lcm and gcd:: - sage: R = ZZ.extension(x^2+1, names='i') - sage: i = R.1 - sage: P. = R[] - sage: lcm(t, i) + sage: R = ZZ.extension(x^2+1, names='i') # optional - sage.rings.number_field + sage: i = R.1 # optional - sage.rings.number_field + sage: P. = R[] # optional - sage.rings.number_field + sage: lcm(t, i) # optional - sage.rings.number_field Traceback (most recent call last): ... - NotImplementedError: Gaussian Integers in Number Field in i with defining polynomial x^2 + 1 does not provide a gcd implementation for univariate polynomials - sage: q = t/(t+1); q.parent() - Fraction Field of Univariate Polynomial Ring in t over Gaussian Integers in Number Field in i with defining polynomial x^2 + 1 - sage: lcm(q, q) + NotImplementedError: Gaussian Integers in Number Field in i with + defining polynomial x^2 + 1 does not provide a gcd implementation + for univariate polynomials + sage: q = t/(t + 1); q.parent() # optional - sage.rings.number_field + Fraction Field of Univariate Polynomial Ring in t over Gaussian + Integers in Number Field in i with defining polynomial x^2 + 1 + sage: lcm(q, q) # optional - sage.rings.number_field 1 - sage: q.lcm(0) + sage: q.lcm(0) # optional - sage.rings.number_field 0 - sage: (q*0).lcm(0) + sage: (q*0).lcm(0) # optional - sage.rings.number_field 0 Check that it is possible to take lcm of a rational and an integer @@ -266,11 +272,11 @@ def xgcd(self, other): sage: R. = QQ['x'] sage: p = (1+x)^3*(1+2*x^2)/(1-x^5) sage: q = (1+x)^2*(1+3*x^2)/(1-x^4) - sage: factor(p) + sage: factor(p) # optional - sage.libs.pari (-2) * (x - 1)^-1 * (x + 1)^3 * (x^2 + 1/2) * (x^4 + x^3 + x^2 + x + 1)^-1 - sage: factor(q) + sage: factor(q) # optional - sage.libs.pari (-3) * (x - 1)^-1 * (x + 1) * (x^2 + 1)^-1 * (x^2 + 1/3) - sage: g,s,t = xgcd(p,q) + sage: g, s, t = xgcd(p, q) sage: g (x + 1)/(x^7 + x^5 - x^2 - 1) sage: g == s*p + t*q @@ -278,21 +284,21 @@ def xgcd(self, other): An example without a well defined gcd or xgcd on its base ring:: - sage: K = QuadraticField(5) - sage: O = K.maximal_order() - sage: R = PolynomialRing(O, 'x') - sage: F = R.fraction_field() - sage: x = F.gen(0) - sage: x.gcd(x+1) + sage: K = QuadraticField(5) # optional - sage.rings.number_field + sage: O = K.maximal_order() # optional - sage.rings.number_field + sage: R = PolynomialRing(O, 'x') # optional - sage.rings.number_field + sage: F = R.fraction_field() # optional - sage.rings.number_field + sage: x = F.gen(0) # optional - sage.rings.number_field + sage: x.gcd(x+1) # optional - sage.rings.number_field 1 - sage: x.xgcd(x+1) + sage: x.xgcd(x+1) # optional - sage.rings.number_field (1, 1/x, 0) - sage: zero = F.zero() - sage: zero.gcd(x) + sage: zero = F.zero() # optional - sage.rings.number_field + sage: zero.gcd(x) # optional - sage.rings.number_field 1 - sage: zero.xgcd(x) + sage: zero.xgcd(x) # optional - sage.rings.number_field (1, 0, 1/x) - sage: zero.xgcd(zero) + sage: zero.xgcd(zero) # optional - sage.rings.number_field (0, 0, 0) """ P = self.parent() @@ -340,14 +346,14 @@ def factor(self, *args, **kwds): sage: K. = QQ[] sage: f = (x^3+x)/(x-3) - sage: f.factor() + sage: f.factor() # optional - sage.libs.pari (x - 3)^-1 * x * (x^2 + 1) Here is an example to show that :trac:`7868` has been resolved:: - sage: R. = GF(2)[] - sage: f = x*y/(x+y) - sage: f.factor() + sage: R. = GF(2)[] # optional - sage.rings.finite_rings + sage: f = x*y/(x+y) # optional - sage.rings.finite_rings + sage: f.factor() # optional - sage.rings.finite_rings (x + y)^-1 * y * x """ return (self.numerator().factor(*args, **kwds) / @@ -380,36 +386,38 @@ def partial_fraction_decomposition(self, decompose_powers=True): sage: S. = QQ[] sage: q = 1/(t+1) + 2/(t+2) + 3/(t-3); q (6*t^2 + 4*t - 6)/(t^3 - 7*t - 6) - sage: whole, parts = q.partial_fraction_decomposition(); parts + sage: whole, parts = q.partial_fraction_decomposition(); parts # optional - sage.libs.pari [3/(t - 3), 1/(t + 1), 2/(t + 2)] - sage: sum(parts) == q + sage: sum(parts) == q # optional - sage.libs.pari True - sage: q = 1/(t^3+1) + 2/(t^2+2) + 3/(t-3)^5 - sage: whole, parts = q.partial_fraction_decomposition(); parts - [1/3/(t + 1), 3/(t^5 - 15*t^4 + 90*t^3 - 270*t^2 + 405*t - 243), (-1/3*t + 2/3)/(t^2 - t + 1), 2/(t^2 + 2)] - sage: sum(parts) == q + sage: q = 1/(t^3+1) + 2/(t^2+2) + 3/(t-3)^5 # optional - sage.libs.pari + sage: whole, parts = q.partial_fraction_decomposition(); parts # optional - sage.libs.pari + [1/3/(t + 1), 3/(t^5 - 15*t^4 + 90*t^3 - 270*t^2 + 405*t - 243), + (-1/3*t + 2/3)/(t^2 - t + 1), 2/(t^2 + 2)] + sage: sum(parts) == q # optional - sage.libs.pari True - sage: q = 2*t / (t + 3)^2 - sage: q.partial_fraction_decomposition() + sage: q = 2*t / (t + 3)^2 # optional - sage.libs.pari + sage: q.partial_fraction_decomposition() # optional - sage.libs.pari (0, [2/(t + 3), -6/(t^2 + 6*t + 9)]) - sage: for p in q.partial_fraction_decomposition()[1]: print(p.factor()) + sage: for p in q.partial_fraction_decomposition()[1]: # optional - sage.libs.pari + ....: print(p.factor()) (2) * (t + 3)^-1 (-6) * (t + 3)^-2 - sage: q.partial_fraction_decomposition(decompose_powers=False) + sage: q.partial_fraction_decomposition(decompose_powers=False) # optional - sage.libs.pari (0, [2*t/(t^2 + 6*t + 9)]) We can decompose over a given algebraic extension:: - sage: R. = QQ[sqrt(2)][] - sage: r = 1/(x^4+1) - sage: r.partial_fraction_decomposition() + sage: R. = QQ[sqrt(2)][] # optional - sage.rings.number_field + sage: r = 1/(x^4+1) # optional - sage.rings.number_field + sage: r.partial_fraction_decomposition() # optional - sage.rings.number_field (0, [(-1/4*sqrt2*x + 1/2)/(x^2 - sqrt2*x + 1), (1/4*sqrt2*x + 1/2)/(x^2 + sqrt2*x + 1)]) - sage: R. = QQ[I][] # of QQ[sqrt(-1)] - sage: r = 1/(x^4+1) - sage: r.partial_fraction_decomposition() + sage: R. = QQ[I][] # of QQ[sqrt(-1)] # optional - sage.rings.number_field + sage: r = 1/(x^4+1) # optional - sage.rings.number_field + sage: r.partial_fraction_decomposition() # optional - sage.rings.number_field (0, [(-1/2*I)/(x^2 - I), 1/2*I/(x^2 + I)]) We can also ask Sage to find the least extension where the @@ -417,12 +425,12 @@ def partial_fraction_decomposition(self, decompose_powers=True): sage: R. = QQ[] sage: r = 1/(x^4+2) - sage: N = r.denominator().splitting_field('a') - sage: N + sage: N = r.denominator().splitting_field('a') # optional - sage.rings.number_field + sage: N # optional - sage.rings.number_field Number Field in a with defining polynomial x^8 - 8*x^6 + 28*x^4 + 16*x^2 + 36 - sage: R1.=N[] - sage: r1 = 1/(x1^4+2) - sage: r1.partial_fraction_decomposition() + sage: R1. = N[] # optional - sage.rings.number_field + sage: r1 = 1/(x1^4+2) # optional - sage.rings.number_field + sage: r1.partial_fraction_decomposition() # optional - sage.rings.number_field (0, [(-1/224*a^6 + 13/448*a^4 - 5/56*a^2 - 25/224)/(x1 - 1/28*a^6 + 13/56*a^4 - 5/7*a^2 - 25/28), (1/224*a^6 - 13/448*a^4 + 5/56*a^2 + 25/224)/(x1 + 1/28*a^6 - 13/56*a^4 + 5/7*a^2 + 25/28), @@ -431,9 +439,9 @@ def partial_fraction_decomposition(self, decompose_powers=True): Or we may work directly over an algebraically closed field:: - sage: R. = QQbar[] - sage: r = 1/(x^4+1) - sage: r.partial_fraction_decomposition() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: r = 1/(x^4+1) # optional - sage.rings.number_field + sage: r.partial_fraction_decomposition() # optional - sage.rings.number_field (0, [(-0.1767766952966369? - 0.1767766952966369?*I)/(x - 0.7071067811865475? - 0.7071067811865475?*I), (-0.1767766952966369? + 0.1767766952966369?*I)/(x - 0.7071067811865475? + 0.7071067811865475?*I), @@ -445,7 +453,7 @@ def partial_fraction_decomposition(self, decompose_powers=True): sage: R. = RealField(20)[] sage: q = 1/(x^2 + x + 2)^2 + 1/(x-1); q (x^4 + 2.0000*x^3 + 5.0000*x^2 + 5.0000*x + 3.0000)/(x^5 + x^4 + 3.0000*x^3 - x^2 - 4.0000) - sage: whole, parts = q.partial_fraction_decomposition(); parts + sage: whole, parts = q.partial_fraction_decomposition(); parts # optional - sage.rings.number_field [1.0000/(x - 1.0000), 1.0000/(x^4 + 2.0000*x^3 + 5.0000*x^2 + 4.0000*x + 4.0000)] sage: sum(parts) (x^4 + 2.0000*x^3 + 5.0000*x^2 + 5.0000*x + 3.0000)/(x^5 + x^4 + 3.0000*x^3 - x^2 - 4.0000) @@ -456,23 +464,23 @@ def partial_fraction_decomposition(self, decompose_powers=True): sage: R. = ZZ[] sage: q = x^2/(x-1) - sage: q.partial_fraction_decomposition() + sage: q.partial_fraction_decomposition() # optional - sage.libs.pari (x + 1, [1/(x - 1)]) sage: q = x^10/(x-1)^5 - sage: whole, parts = q.partial_fraction_decomposition() - sage: whole + sum(parts) == q + sage: whole, parts = q.partial_fraction_decomposition() # optional - sage.libs.pari + sage: whole + sum(parts) == q # optional - sage.libs.pari True And also over finite fields (see :trac:`6052`, :trac:`9945`):: - sage: R. = GF(2)[] - sage: q = (x+1)/(x^3+x+1) - sage: q.partial_fraction_decomposition() + sage: R. = GF(2)[] # optional - sage.rings.finite_rings + sage: q = (x+1)/(x^3+x+1) # optional - sage.rings.finite_rings + sage: q.partial_fraction_decomposition() # optional - sage.rings.finite_rings (0, [(x + 1)/(x^3 + x + 1)]) - sage: R. = GF(11)[] - sage: q = x + 1 + 1/(x+1) + x^2/(x^3 + 2*x + 9) - sage: q.partial_fraction_decomposition() + sage: R. = GF(11)[] # optional - sage.rings.finite_rings + sage: q = x + 1 + 1/(x+1) + x^2/(x^3 + 2*x + 9) # optional - sage.rings.finite_rings + sage: q.partial_fraction_decomposition() # optional - sage.rings.finite_rings (x + 1, [1/(x + 1), x^2/(x^3 + 2*x + 9)]) And even the rationals:: diff --git a/src/sage/categories/realizations.py b/src/sage/categories/realizations.py index bbe9a8e8ad4..0207b66a4be 100644 --- a/src/sage/categories/realizations.py +++ b/src/sage/categories/realizations.py @@ -66,19 +66,23 @@ def Realizations(self): The category of realizations of some algebra:: sage: Algebras(QQ).Realizations() - Join of Category of algebras over Rational Field and Category of realizations of unital magmas + Join of Category of algebras over Rational Field + and Category of realizations of unital magmas The category of realizations of a given algebra:: - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field - sage: A.Realizations() - Category of realizations of The subset algebra of {1, 2, 3} over Rational Field + sage: A.Realizations() # optional - sage.combinat sage.modules + Category of realizations of + The subset algebra of {1, 2, 3} over Rational Field sage: C = GradedHopfAlgebrasWithBasis(QQ).Realizations(); C - Join of Category of graded hopf algebras with basis over Rational Field and Category of realizations of hopf algebras over Rational Field + Join of Category of graded hopf algebras with basis over Rational Field + and Category of realizations of hopf algebras over Rational Field sage: C.super_categories() - [Category of graded hopf algebras with basis over Rational Field, Category of realizations of hopf algebras over Rational Field] + [Category of graded hopf algebras with basis over Rational Field, + Category of realizations of hopf algebras over Rational Field] sage: TestSuite(C).run() @@ -91,7 +95,7 @@ def Realizations(self): Add an optional argument to allow for:: - sage: Realizations(A, category = Blahs()) # todo: not implemented + sage: Realizations(A, category=Blahs()) # todo: not implemented """ if isinstance(self, Category): return RealizationsCategory.category_of(self) @@ -112,7 +116,7 @@ class Category_realization_of_parent(Category_over_base, BindableClass): EXAMPLES:: - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field The role of this base class is to implement some technical goodies, like @@ -120,8 +124,9 @@ class Category_realization_of_parent(Category_over_base, BindableClass): implemented as a nested class in ``A`` (see the :mod:`code of the example `):: - sage: C = A.Realizations(); C - Category of realizations of The subset algebra of {1, 2, 3} over Rational Field + sage: C = A.Realizations(); C # optional - sage.combinat sage.modules + Category of realizations of + The subset algebra of {1, 2, 3} over Rational Field as well as the name for that category. """ @@ -130,15 +135,16 @@ def __init__(self, parent_with_realization): TESTS:: sage: from sage.categories.realizations import Category_realization_of_parent - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field - sage: C = A.Realizations(); C - Category of realizations of The subset algebra of {1, 2, 3} over Rational Field - sage: isinstance(C, Category_realization_of_parent) + sage: C = A.Realizations(); C # optional - sage.combinat sage.modules + Category of realizations of + The subset algebra of {1, 2, 3} over Rational Field + sage: isinstance(C, Category_realization_of_parent) # optional - sage.combinat sage.modules True - sage: C.parent_with_realization + sage: C.parent_with_realization # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field - sage: TestSuite(C).run(skip=["_test_category_over_bases"]) + sage: TestSuite(C).run(skip=["_test_category_over_bases"]) # optional - sage.combinat sage.modules .. TODO:: @@ -161,8 +167,8 @@ def _get_name(self): sage: from sage.categories.realizations import Category_realization_of_parent sage: class MultiplicativeBasesOnPrimitiveElements(Category_realization_of_parent): ....: def super_categories(self): return [Objects()] - sage: Sym = SymmetricFunctions(QQ); Sym.rename("Sym") - sage: MultiplicativeBasesOnPrimitiveElements(Sym)._get_name() + sage: Sym = SymmetricFunctions(QQ); Sym.rename("Sym") # optional - sage.combinat + sage: MultiplicativeBasesOnPrimitiveElements(Sym)._get_name() # optional - sage.combinat 'multiplicative bases on primitive elements' """ import re @@ -179,10 +185,10 @@ def _repr_object_names(self): sage: from sage.categories.realizations import Category_realization_of_parent sage: class MultiplicativeBasesOnPrimitiveElements(Category_realization_of_parent): ....: def super_categories(self): return [Objects()] - sage: Sym = SymmetricFunctions(QQ); Sym.rename("Sym") - sage: C = MultiplicativeBasesOnPrimitiveElements(Sym); C + sage: Sym = SymmetricFunctions(QQ); Sym.rename("Sym") # optional - sage.combinat + sage: C = MultiplicativeBasesOnPrimitiveElements(Sym); C # optional - sage.combinat Category of multiplicative bases on primitive elements of Sym - sage: C._repr_object_names() + sage: C._repr_object_names() # optional - sage.combinat 'multiplicative bases on primitive elements of Sym' """ return "{} of {}".format(self._get_name(), self.base()) diff --git a/src/sage/categories/regular_crystals.py b/src/sage/categories/regular_crystals.py index f5412fe6ab1..afad9e78c22 100644 --- a/src/sage/categories/regular_crystals.py +++ b/src/sage/categories/regular_crystals.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.graphs r""" Regular Crystals """ @@ -133,21 +134,21 @@ def is_isomorphism(self): EXAMPLES:: - sage: La = RootSystem(['A',2,1]).weight_space(extended=True).fundamental_weights() + sage: A21 = RootSystem(['A',2,1]) + sage: La = A21.weight_space(extended=True).fundamental_weights() sage: B = crystals.LSPaths(La[0]) - sage: La = RootSystem(['A',2,1]).weight_lattice(extended=True).fundamental_weights() + sage: La = A21.weight_lattice(extended=True).fundamental_weights() sage: C = crystals.GeneralizedYoungWalls(2, La[0]) sage: H = Hom(B, C) sage: from sage.categories.highest_weight_crystals import HighestWeightCrystalMorphism sage: class Psi(HighestWeightCrystalMorphism): ....: def is_strict(self): ....: return True - sage: psi = Psi(H, C.module_generators) - sage: psi + sage: psi = Psi(H, C.module_generators); psi ['A', 2, 1] Crystal morphism: From: The crystal of LS paths of type ['A', 2, 1] and weight Lambda[0] - To: Highest weight crystal of generalized Young walls of Cartan type ['A', 2, 1] - and highest weight Lambda[0] + To: Highest weight crystal of generalized Young walls + of Cartan type ['A', 2, 1] and highest weight Lambda[0] Defn: (Lambda[0],) |--> [] sage: psi.is_isomorphism() True @@ -184,25 +185,28 @@ def demazure_operator(self, element, reduced_word): EXAMPLES:: sage: T = crystals.Tableaux(['A',2], shape=[2,1]) - sage: C = CombinatorialFreeModule(QQ,T) + sage: C = CombinatorialFreeModule(QQ, T) sage: t = T.highest_weight_vector() sage: b = 2*C(t) sage: T.demazure_operator(b,[1,2,1]) - 2*B[[[1, 1], [2]]] + 2*B[[[1, 2], [2]]] + 2*B[[[1, 3], [2]]] + 2*B[[[1, 1], [3]]] - + 2*B[[[1, 2], [3]]] + 2*B[[[1, 3], [3]]] + 2*B[[[2, 2], [3]]] + 2*B[[[2, 3], [3]]] + 2*B[[[1, 1], [2]]] + 2*B[[[1, 2], [2]]] + 2*B[[[1, 3], [2]]] + + 2*B[[[1, 1], [3]]] + 2*B[[[1, 2], [3]]] + 2*B[[[1, 3], [3]]] + + 2*B[[[2, 2], [3]]] + 2*B[[[2, 3], [3]]] The Demazure operator is idempotent:: - sage: T = crystals.Tableaux("A1",shape=[4]) - sage: C = CombinatorialFreeModule(QQ,T) + sage: T = crystals.Tableaux("A1", shape=[4]) + sage: C = CombinatorialFreeModule(QQ, T) sage: b = C(T.module_generators[0]); b B[[[1, 1, 1, 1]]] sage: e = T.demazure_operator(b,[1]); e - B[[[1, 1, 1, 1]]] + B[[[1, 1, 1, 2]]] + B[[[1, 1, 2, 2]]] + B[[[1, 2, 2, 2]]] + B[[[2, 2, 2, 2]]] + B[[[1, 1, 1, 1]]] + B[[[1, 1, 1, 2]]] + B[[[1, 1, 2, 2]]] + + B[[[1, 2, 2, 2]]] + B[[[2, 2, 2, 2]]] sage: e == T.demazure_operator(e,[1]) True - sage: all(T.demazure_operator(T.demazure_operator(C(t),[1]),[1]) == T.demazure_operator(C(t),[1]) for t in T) + sage: all(T.demazure_operator(T.demazure_operator(C(t),[1]),[1]) + ....: == T.demazure_operator(C(t),[1]) for t in T) True """ M = element.parent() diff --git a/src/sage/categories/regular_supercrystals.py b/src/sage/categories/regular_supercrystals.py index 2ed4531c673..9fd6f5c8a83 100644 --- a/src/sage/categories/regular_supercrystals.py +++ b/src/sage/categories/regular_supercrystals.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.graphs r""" Regular Supercrystals """ @@ -107,7 +108,7 @@ def epsilon(self, i): EXAMPLES:: - sage: C = crystals.Tableaux(['A',[1,2]], shape = [2,1]) + sage: C = crystals.Tableaux(['A',[1,2]], shape=[2,1]) sage: c = C.an_element(); c [[-2, -2], [-1]] sage: c.epsilon(2) @@ -132,7 +133,7 @@ def phi(self, i): EXAMPLES:: - sage: C = crystals.Tableaux(['A',[1,2]], shape = [2,1]) + sage: C = crystals.Tableaux(['A',[1,2]], shape=[2,1]) sage: c = C.an_element(); c [[-2, -2], [-1]] sage: c.phi(1) diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 50dba914250..07ffd95d02b 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -67,16 +67,16 @@ def is_injective(self) -> bool: EXAMPLES:: sage: R. = QQ[] - sage: R.hom([x, y^2], R).is_injective() + sage: R.hom([x, y^2], R).is_injective() # optional - sage.libs.singular True - sage: R.hom([x, x^2], R).is_injective() + sage: R.hom([x, x^2], R).is_injective() # optional - sage.libs.singular False - sage: S. = R.quotient(x^3*y) - sage: R.hom([v, u], S).is_injective() + sage: S. = R.quotient(x^3*y) # optional - sage.libs.singular + sage: R.hom([v, u], S).is_injective() # optional - sage.libs.singular False - sage: S.hom([-u, v], S).is_injective() + sage: S.hom([-u, v], S).is_injective() # optional - sage.libs.singular True - sage: S.cover().is_injective() + sage: S.cover().is_injective() # optional - sage.libs.singular False If the domain is a field, the homomorphism is injective:: @@ -102,12 +102,12 @@ def is_injective(self) -> bool: characteristic can not be injective:: sage: R. = ZZ[] - sage: f = R.hom([GF(3)(1)]); f + sage: f = R.hom([GF(3)(1)]); f # optional - sage.rings.finite_rings Ring morphism: From: Univariate Polynomial Ring in x over Integer Ring To: Finite Field of size 3 Defn: x |--> 1 - sage: f.is_injective() + sage: f.is_injective() # optional - sage.rings.finite_rings False A morphism whose domain is an order in a number field is injective if @@ -120,18 +120,20 @@ def is_injective(self) -> bool: To: Rational function field in x over Rational Field Defn: Conversion via FractionFieldElement_1poly_field map: From: Integer Ring - To: Fraction Field of Univariate Polynomial Ring in x over Rational Field + To: Fraction Field of Univariate Polynomial Ring in x + over Rational Field then Isomorphism: - From: Fraction Field of Univariate Polynomial Ring in x over Rational Field + From: Fraction Field of Univariate Polynomial Ring in x + over Rational Field To: Rational function field in x over Rational Field sage: f.is_injective() True A coercion to the fraction field is injective:: - sage: R = ZpFM(3) - sage: R.fraction_field().coerce_map_from(R).is_injective() + sage: R = ZpFM(3) # optional - sage.rings.padics + sage: R.fraction_field().coerce_map_from(R).is_injective() # optional - sage.rings.padics True """ @@ -212,23 +214,24 @@ def extend_to_fraction_field(self): EXAMPLES:: sage: S. = QQ[] - sage: f = S.hom([x+1]); f + sage: f = S.hom([x + 1]); f Ring endomorphism of Univariate Polynomial Ring in x over Rational Field Defn: x |--> x + 1 sage: g = f.extend_to_fraction_field(); g - Ring endomorphism of Fraction Field of Univariate Polynomial Ring in x over Rational Field + Ring endomorphism of Fraction Field of Univariate Polynomial Ring in x + over Rational Field Defn: x |--> x + 1 - sage: g(x) + sage: g(x) # optional - sage.libs.singular x + 1 - sage: g(1/x) + sage: g(1/x) # optional - sage.libs.singular 1/(x + 1) If this morphism is not injective, it does not extend to the fraction field and an error is raised:: - sage: f = GF(5).coerce_map_from(ZZ) - sage: f.extend_to_fraction_field() + sage: f = GF(5).coerce_map_from(ZZ) # optional - sage.rings.finite_rings + sage: f.extend_to_fraction_field() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: the morphism is not injective @@ -236,9 +239,10 @@ def extend_to_fraction_field(self): TESTS:: sage: A. = RR[] - sage: phi = A.hom([x+1]) - sage: phi.extend_to_fraction_field() - Ring endomorphism of Fraction Field of Univariate Polynomial Ring in x over Real Field with 53 bits of precision + sage: phi = A.hom([x + 1]) + sage: phi.extend_to_fraction_field() # optional - sage.libs.singular + Ring endomorphism of Fraction Field of + Univariate Polynomial Ring in x over Real Field with 53 bits of precision Defn: x |--> x + 1.00000000000000 """ from sage.rings.morphism import RingHomomorphism_from_fraction_field @@ -332,10 +336,10 @@ def is_zero(self) -> bool: sage: R. = ZZ[] sage: R.quo(1).is_zero() True - sage: R. = GF(101)[] - sage: R.quo(77).is_zero() + sage: R. = GF(101)[] # optional - sage.rings.finite_rings + sage: R.quo(77).is_zero() # optional - sage.rings.finite_rings True - sage: R.quo(x^2+1).is_zero() + sage: R.quo(x^2 + 1).is_zero() # optional - sage.rings.finite_rings False """ return self.one() == self.zero() @@ -350,18 +354,20 @@ def bracket(self, x, y): EXAMPLES:: - sage: F = AlgebrasWithBasis(QQ).example() - sage: F - An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field - sage: a,b,c = F.algebra_generators() - sage: F.bracket(a,b) + sage: F = AlgebrasWithBasis(QQ).example() # optional - sage.combinat sage.modules + sage: F # optional - sage.combinat sage.modules + An example of an algebra with basis: + the free algebra on the generators ('a', 'b', 'c') over Rational Field + sage: a, b, c = F.algebra_generators() # optional - sage.combinat sage.modules + sage: F.bracket(a, b) # optional - sage.combinat sage.modules B[word: ab] - B[word: ba] This measures the default of commutation between `x` and `y`. `F` endowed with the bracket operation is a Lie algebra; in particular, it satisfies Jacobi's identity:: - sage: F.bracket( F.bracket(a,b), c) + F.bracket(F.bracket(b,c),a) + F.bracket(F.bracket(c,a),b) + sage: (F.bracket(F.bracket(a,b), c) + F.bracket(F.bracket(b,c), a) # optional - sage.combinat sage.modules + ....: + F.bracket(F.bracket(c,a), b)) 0 """ return x * y - y * x @@ -386,20 +392,20 @@ def _Hom_(self, Y, category): EXAMPLES:: - sage: H = QQ._Hom_(QQ, category = Rings()); H + sage: H = QQ._Hom_(QQ, category=Rings()); H Set of Homomorphisms from Rational Field to Rational Field sage: H.__class__ TESTS:: - sage: Hom(QQ, QQ, category = Rings()).__class__ + sage: Hom(QQ, QQ, category=Rings()).__class__ - sage: Hom(CyclotomicField(3), QQ, category = Rings()).__class__ + sage: Hom(CyclotomicField(3), QQ, category=Rings()).__class__ # optional - sage.rings.number_field - sage: TestSuite(Hom(QQ, QQ, category = Rings())).run() # indirect doctest + sage: TestSuite(Hom(QQ, QQ, category=Rings())).run() # indirect doctest """ if category is not None and not category.is_subcategory(Rings()): raise TypeError(f"{category} is not a subcategory of Rings()") @@ -439,12 +445,12 @@ def _mul_(self, x, switch_sides=False): from the base class of rings. This is the case, e.g., for matrix algebras:: - sage: MS = MatrixSpace(QQ,2,2) - sage: isinstance(MS,Ring) + sage: MS = MatrixSpace(QQ, 2, 2) # optional - sage.modules + sage: isinstance(MS, Ring) # optional - sage.modules False - sage: MS in Rings() + sage: MS in Rings() # optional - sage.modules True - sage: MS*2 # indirect doctest + sage: MS * 2 # indirect doctest # optional - sage.modules Left Ideal ( [2 0] @@ -455,7 +461,7 @@ def _mul_(self, x, switch_sides=False): In the next example, the ring and the other factor switch sides in the product:: - sage: [MS.2]*MS + sage: [MS.2] * MS # optional - sage.modules Right Ideal ( [0 0] @@ -501,12 +507,12 @@ def __pow__(self, n): EXAMPLES:: - sage: QQ^5 + sage: QQ^5 # optional - sage.modules Vector space of dimension 5 over Rational Field - sage: Integers(20)^1000 + sage: Integers(20)^1000 # optional - sage.modules Ambient free module of rank 1000 over Ring of integers modulo 20 - sage: QQ^(2,3) + sage: QQ^(2, 3) # optional - sage.modules Full MatrixSpace of 2 by 3 dense matrices over Rational Field """ if isinstance(n, tuple): @@ -531,18 +537,18 @@ def ideal_monoid(self): EXAMPLES:: - sage: MS = MatrixSpace(QQ,2,2) - sage: isinstance(MS,Ring) + sage: MS = MatrixSpace(QQ, 2, 2) # optional - sage.modules + sage: isinstance(MS, Ring) # optional - sage.modules False - sage: MS in Rings() + sage: MS in Rings() # optional - sage.modules True - sage: MS.ideal_monoid() + sage: MS.ideal_monoid() # optional - sage.modules Monoid of ideals of Full MatrixSpace of 2 by 2 dense matrices over Rational Field Note that the monoid is cached:: - sage: MS.ideal_monoid() is MS.ideal_monoid() + sage: MS.ideal_monoid() is MS.ideal_monoid() # optional - sage.modules True """ try: @@ -560,11 +566,11 @@ def characteristic(self): sage: QQ.characteristic() 0 - sage: GF(19).characteristic() + sage: GF(19).characteristic() # optional - sage.rings.finite_rings 19 sage: Integers(8).characteristic() 8 - sage: Zp(5).characteristic() + sage: Zp(5).characteristic() # optional - sage.rings.padics 0 """ from sage.rings.infinity import infinity @@ -619,19 +625,19 @@ def ideal(self, *args, **kwds): EXAMPLES:: - sage: MS = MatrixSpace(QQ,2,2) - sage: isinstance(MS,Ring) + sage: MS = MatrixSpace(QQ, 2, 2) # optional - sage.modules + sage: isinstance(MS, Ring) # optional - sage.modules False - sage: MS in Rings() + sage: MS in Rings() # optional - sage.modules True - sage: MS.ideal(2) + sage: MS.ideal(2) # optional - sage.modules Twosided Ideal ( [2 0] [0 2] ) of Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: MS.ideal([MS.0,MS.1],side='right') + sage: MS.ideal([MS.0, MS.1], side='right') # optional - sage.modules Right Ideal ( [1 0] @@ -733,8 +739,8 @@ def _ideal_class_(self, n=0): EXAMPLES:: - sage: MS = MatrixSpace(QQ,2,2) - sage: MS._ideal_class_() + sage: MS = MatrixSpace(QQ, 2, 2) # optional - sage.modules + sage: MS._ideal_class_() # optional - sage.modules We do not know of a commutative ring in Sage that does not inherit @@ -782,28 +788,34 @@ def quotient(self, I, names=None, **kwds): So, we need a bit of effort to make the following example work with the category framework:: - sage: F. = FreeAlgebra(QQ) - sage: from sage.rings.noncommutative_ideals import Ideal_nc + sage: F. = FreeAlgebra(QQ) # optional - sage.combinat sage.modules + sage: from sage.rings.noncommutative_ideals import Ideal_nc # optional - sage.combinat sage.modules sage: from itertools import product - sage: class PowerIdeal(Ideal_nc): + sage: class PowerIdeal(Ideal_nc): # optional - sage.combinat sage.modules ....: def __init__(self, R, n): ....: self._power = n - ....: Ideal_nc.__init__(self, R, [R.prod(m) for m in product(R.gens(), repeat=n)]) + ....: Ideal_nc.__init__(self, R, [R.prod(m) + ....: for m in product(R.gens(), repeat=n)]) ....: def reduce(self, x): ....: R = self.ring() - ....: return add([c*R(m) for m,c in x if len(m) < self._power], R(0)) - sage: I = PowerIdeal(F,3) - sage: Q = Rings().parent_class.quotient(F, I); Q - Quotient of Free Algebra on 3 generators (x, y, z) over Rational Field by the ideal (x^3, x^2*y, x^2*z, x*y*x, x*y^2, x*y*z, x*z*x, x*z*y, x*z^2, y*x^2, y*x*y, y*x*z, y^2*x, y^3, y^2*z, y*z*x, y*z*y, y*z^2, z*x^2, z*x*y, z*x*z, z*y*x, z*y^2, z*y*z, z^2*x, z^2*y, z^3) - sage: Q.0 + ....: return add([c*R(m) for m, c in x + ....: if len(m) < self._power], R(0)) + sage: I = PowerIdeal(F, 3) # optional - sage.combinat sage.modules + sage: Q = Rings().parent_class.quotient(F, I); Q # optional - sage.combinat sage.modules + Quotient of Free Algebra on 3 generators (x, y, z) over Rational Field + by the ideal (x^3, x^2*y, x^2*z, x*y*x, x*y^2, x*y*z, x*z*x, + x*z*y, x*z^2, y*x^2, y*x*y, y*x*z, y^2*x, y^3, + y^2*z, y*z*x, y*z*y, y*z^2, z*x^2, z*x*y, z*x*z, + z*y*x, z*y^2, z*y*z, z^2*x, z^2*y, z^3) + sage: Q.0 # optional - sage.combinat sage.modules xbar - sage: Q.1 + sage: Q.1 # optional - sage.combinat sage.modules ybar - sage: Q.2 + sage: Q.2 # optional - sage.combinat sage.modules zbar - sage: Q.0*Q.1 + sage: Q.0*Q.1 # optional - sage.combinat sage.modules xbar*ybar - sage: Q.0*Q.1*Q.0 + sage: Q.0*Q.1*Q.0 # optional - sage.combinat sage.modules 0 An example with polynomial rings:: @@ -814,13 +826,14 @@ def quotient(self, I, names=None, **kwds): sage: S.gens() (a,) - sage: R. = PolynomialRing(QQ,2) - sage: S. = R.quotient((x^2, y)) - sage: S - Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2, y) - sage: S.gens() + sage: R. = PolynomialRing(QQ, 2) + sage: S. = R.quotient((x^2, y)) # optional - sage.libs.singular + sage: S # optional - sage.libs.singular + Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x^2, y) + sage: S.gens() # optional - sage.libs.singular (a, 0) - sage: a == b + sage: a == b # optional - sage.libs.singular False """ from sage.rings.quotient_ring import QuotientRing @@ -836,8 +849,8 @@ def quo(self, I, names=None, **kwds): EXAMPLES:: - sage: MS = MatrixSpace(QQ,2) - sage: I = MS*MS.gens()*MS + sage: MS = MatrixSpace(QQ, 2) # optional - sage.modules + sage: I = MS * MS.gens() * MS # optional - sage.modules ``MS`` is not an instance of :class:`~sage.rings.ring.Ring`. @@ -845,12 +858,13 @@ def quo(self, I, names=None, **kwds): category of rings. The quotient method is inherited from there:: - sage: isinstance(MS,sage.rings.ring.Ring) + sage: isinstance(MS, sage.rings.ring.Ring) # optional - sage.modules False - sage: isinstance(MS,Rings().parent_class) + sage: isinstance(MS, Rings().parent_class) # optional - sage.modules True - sage: MS.quo(I,names = ['a','b','c','d']) - Quotient of Full MatrixSpace of 2 by 2 dense matrices over Rational Field by the ideal + sage: MS.quo(I, names=['a','b','c','d']) # optional - sage.modules + Quotient of Full MatrixSpace of 2 by 2 dense matrices + over Rational Field by the ideal ( [1 0] [0 0], @@ -867,13 +881,14 @@ def quo(self, I, names=None, **kwds): A test with a subclass of :class:`~sage.rings.ring.Ring`:: - sage: R. = PolynomialRing(QQ,2) - sage: S. = R.quo((x^2, y)) - sage: S - Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2, y) - sage: S.gens() + sage: R. = PolynomialRing(QQ, 2) # optional - sage.libs.singular + sage: S. = R.quo((x^2, y)) # optional - sage.libs.singular + sage: S # optional - sage.libs.singular + Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x^2, y) + sage: S.gens() # optional - sage.libs.singular (a, 0) - sage: a == b + sage: a == b # optional - sage.libs.singular False """ return self.quotient(I, names=names, **kwds) @@ -903,19 +918,20 @@ def quotient_ring(self, I, names=None, **kwds): EXAMPLES:: - sage: MS = MatrixSpace(QQ,2) - sage: I = MS*MS.gens()*MS + sage: MS = MatrixSpace(QQ, 2) # optional - sage.modules + sage: I = MS * MS.gens() * MS # optional - sage.modules ``MS`` is not an instance of :class:`~sage.rings.ring.Ring`, but it is an instance of the parent class of the category of rings. The quotient method is inherited from there:: - sage: isinstance(MS,sage.rings.ring.Ring) + sage: isinstance(MS, sage.rings.ring.Ring) # optional - sage.modules False - sage: isinstance(MS,Rings().parent_class) + sage: isinstance(MS, Rings().parent_class) # optional - sage.modules True - sage: MS.quotient_ring(I,names = ['a','b','c','d']) - Quotient of Full MatrixSpace of 2 by 2 dense matrices over Rational Field by the ideal + sage: MS.quotient_ring(I, names=['a','b','c','d']) # optional - sage.modules + Quotient of Full MatrixSpace of 2 by 2 dense matrices + over Rational Field by the ideal ( [1 0] [0 0], @@ -938,13 +954,14 @@ def quotient_ring(self, I, names=None, **kwds): sage: S.gens() (a,) - sage: R. = PolynomialRing(QQ,2) - sage: S. = R.quotient_ring((x^2, y)) - sage: S - Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2, y) - sage: S.gens() + sage: R. = PolynomialRing(QQ,2) # optional - sage.libs.singular + sage: S. = R.quotient_ring((x^2, y)) # optional - sage.libs.singular + sage: S # optional - sage.libs.singular + Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x^2, y) + sage: S.gens() # optional - sage.libs.singular (a, 0) - sage: a == b + sage: a == b # optional - sage.libs.singular False """ return self.quotient(I, names=names, **kwds) @@ -957,9 +974,9 @@ def __truediv__(self, I): EXAMPLES:: - sage: MS = MatrixSpace(QQ,2) - sage: I = MS*MS.gens()*MS - sage: MS/I + sage: MS = MatrixSpace(QQ, 2) # optional - sage.modules + sage: I = MS * MS.gens() * MS # optional - sage.modules + sage: MS/I # optional - sage.modules Traceback (most recent call last): ... TypeError: use self.quotient(I) to construct the quotient ring @@ -996,24 +1013,28 @@ def __getitem__(self, arg): Univariate Polynomial Ring in x over Integer Ring sage: QQ['x'] Univariate Polynomial Ring in x over Rational Field - sage: GF(17)['abc'] + sage: GF(17)['abc'] # optional - sage.rings.finite_rings Univariate Polynomial Ring in abc over Finite Field of size 17 - sage: GF(17)['a,b,c'] + sage: GF(17)['a,b,c'] # optional - sage.rings.finite_rings Multivariate Polynomial Ring in a, b, c over Finite Field of size 17 - sage: GF(17)['a']['b'] - Univariate Polynomial Ring in b over Univariate Polynomial Ring in a over Finite Field of size 17 + sage: GF(17)['a']['b'] # optional - sage.rings.finite_rings + Univariate Polynomial Ring in b over + Univariate Polynomial Ring in a over Finite Field of size 17 We can create Ore polynomial rings:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: k['x', Frob] - Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: k['x', Frob] # optional - sage.rings.finite_rings + Ore Polynomial Ring in x over Finite Field in t of size 5^3 + twisted by t |--> t^5 sage: R. = QQ[] - sage: der = R.derivation() - sage: R['d', der] - Ore Polynomial Ring in d over Univariate Polynomial Ring in t over Rational Field twisted by d/dt + sage: der = R.derivation() # optional - sage.modules + sage: R['d', der] # optional - sage.modules + Ore Polynomial Ring in d + over Univariate Polynomial Ring in t over Rational Field + twisted by d/dt We can also create power series rings by using double brackets:: @@ -1050,32 +1071,38 @@ def __getitem__(self, arg): :: - sage: QQ[sqrt(2)] # optional - sage.symbolic - Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? - sage: QQ[sqrt(2)].coerce_embedding() # optional - sage.symbolic + sage: QQ[sqrt(2)] # optional - sage.symbolic sage.rings.number_field + Number Field in sqrt2 with defining polynomial x^2 - 2 + with sqrt2 = 1.414213562373095? + sage: QQ[sqrt(2)].coerce_embedding() # optional - sage.symbolic sage.rings.number_field Generic morphism: - From: Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? + From: Number Field in sqrt2 with defining polynomial x^2 - 2 + with sqrt2 = 1.414213562373095? To: Real Lazy Field Defn: sqrt2 -> 1.414213562373095? :: - sage: QQ[sqrt(2), sqrt(3)] # optional - sage.symbolic - Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field + sage: QQ[sqrt(2), sqrt(3)] # optional - sage.symbolic sage.rings.number_field + Number Field in sqrt2 + with defining polynomial x^2 - 2 over its base field and orders in number fields:: - sage: ZZ[I] - Order in Number Field in I0 with defining polynomial x^2 + 1 with I0 = 1*I - sage: ZZ[sqrt(5)] # optional - sage.symbolic - Order in Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? - sage: ZZ[sqrt(2) + sqrt(3)] # optional - sage.symbolic - Order in Number Field in a with defining polynomial x^4 - 10*x^2 + 1 with a = 3.146264369941973? + sage: ZZ[I] # optional - sage.symbolic sage.rings.number_field + Order in Number Field in I0 + with defining polynomial x^2 + 1 with I0 = 1*I + sage: ZZ[sqrt(5)] # optional - sage.symbolic sage.rings.number_field + Order in Number Field in sqrt5 + with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? + sage: ZZ[sqrt(2) + sqrt(3)] # optional - sage.symbolic sage.rings.number_field + Order in Number Field in a + with defining polynomial x^4 - 10*x^2 + 1 with a = 3.146264369941973? Embeddings are found for simple extensions (when that makes sense):: - sage: QQi. = QuadraticField(-1, 'i') - sage: QQ[i].coerce_embedding() + sage: QQi. = QuadraticField(-1, 'i') # optional - sage.symbolic sage.rings.number_field + sage: QQ[i].coerce_embedding() # optional - sage.symbolic sage.rings.number_field Generic morphism: From: Number Field in i with defining polynomial x^2 + 1 with i = 1*I To: Complex Lazy Field @@ -1111,25 +1138,28 @@ def __getitem__(self, arg): Extension towers are built as follows and use distinct generator names:: - sage: K = QQ[2^(1/3), 2^(1/2), 3^(1/3)] - sage: K - Number Field in a with defining polynomial x^3 - 2 over its base field - sage: K.base_field() - Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field - sage: K.base_field().base_field() + sage: K = QQ[2^(1/3), 2^(1/2), 3^(1/3)] # optional - sage.symbolic sage.rings.number_field + sage: K # optional - sage.symbolic sage.rings.number_field + Number Field in a with defining polynomial x^3 - 2 + over its base field + sage: K.base_field() # optional - sage.symbolic sage.rings.number_field + Number Field in sqrt2 with defining polynomial x^2 - 2 + over its base field + sage: K.base_field().base_field() # optional - sage.symbolic sage.rings.number_field Number Field in b with defining polynomial x^3 - 3 Embeddings:: - sage: a = 10^100; expr = (2*a + sqrt(2))/(2*a^2-1) # optional - sage.symbolic - sage: QQ[expr].coerce_embedding() is None # optional - sage.symbolic + sage: a = 10^100; expr = (2*a + sqrt(2))/(2*a^2-1) # optional - sage.symbolic sage.rings.number_field + sage: QQ[expr].coerce_embedding() is None # optional - sage.symbolic sage.rings.number_field False - sage: QQ[sqrt(5)].gen() > 0 # optional - sage.symbolic + sage: QQ[sqrt(5)].gen() > 0 # optional - sage.symbolic sage.rings.number_field True - sage: expr = sqrt(2) + I*(cos(pi/4, hold=True) - sqrt(2)/2) # optional - sage.symbolic - sage: QQ[expr].coerce_embedding() # optional - sage.symbolic + sage: expr = sqrt(2) + I*(cos(pi/4, hold=True) - sqrt(2)/2) # optional - sage.symbolic sage.rings.number_field + sage: QQ[expr].coerce_embedding() # optional - sage.symbolic sage.rings.number_field Generic morphism: - From: Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? + From: Number Field in a with defining polynomial x^2 - 2 + with a = 1.414213562373095? To: Real Lazy Field Defn: a -> 1.414213562373095? """ @@ -1251,17 +1281,17 @@ def free_module(self, base=None, basis=None, map=True): EXAMPLES:: sage: R. = QQ[[]] - sage: V, from_V, to_V = R.free_module(R) - sage: v = to_V(1+x); v + sage: V, from_V, to_V = R.free_module(R) # optional - sage.modules + sage: v = to_V(1 + x); v # optional - sage.modules (1 + x) - sage: from_V(v) + sage: from_V(v) # optional - sage.modules 1 + x - sage: W, from_W, to_W = R.free_module(R, basis=(1-x)) - sage: W is V + sage: W, from_W, to_W = R.free_module(R, basis=(1 - x)) # optional - sage.modules + sage: W is V # optional - sage.modules True - sage: w = to_W(1+x); w + sage: w = to_W(1 + x); w # optional - sage.modules (1 - x^2) - sage: from_W(w) + sage: from_W(w) # optional - sage.modules 1 + x + O(x^20) """ if base is None: @@ -1303,12 +1333,12 @@ def is_unit(self) -> bool: EXAMPLES:: - sage: MS = MatrixSpace(ZZ, 2) - sage: MS.one().is_unit() + sage: MS = MatrixSpace(ZZ, 2) # optional - sage.modules + sage: MS.one().is_unit() # optional - sage.modules True - sage: MS.zero().is_unit() + sage: MS.zero().is_unit() # optional - sage.modules False - sage: MS([1,2,3,4]).is_unit() + sage: MS([1,2,3,4]).is_unit() # optional - sage.modules False """ if self.is_one() or (-self).is_one(): @@ -1328,8 +1358,8 @@ def inverse_of_unit(self): EXAMPLES:: sage: R. = ZZ[] - sage: S = R.quo(x^2 + x + 1) - sage: S(1).inverse_of_unit() + sage: S = R.quo(x^2 + x + 1) # optional - sage.libs.pari + sage: S(1).inverse_of_unit() # optional - sage.libs.pari 1 This method fails when the element is not a unit:: @@ -1401,9 +1431,9 @@ def _gen_names(elts): EXAMPLES:: sage: from sage.categories.rings import _gen_names - sage: list(_gen_names([sqrt(5)])) # optional - sage.symbolic + sage: list(_gen_names([sqrt(5)])) # optional - sage.symbolic ['sqrt5'] - sage: list(_gen_names([sqrt(-17), 2^(1/3)])) # optional - sage.symbolic + sage: list(_gen_names([sqrt(-17), 2^(1/3)])) # optional - sage.symbolic ['a', 'b'] sage: list(_gen_names((1..27)))[-1] 'aa' diff --git a/src/sage/categories/semigroups.py b/src/sage/categories/semigroups.py index 10e2617e1ab..45bf6ed7305 100644 --- a/src/sage/categories/semigroups.py +++ b/src/sage/categories/semigroups.py @@ -196,30 +196,37 @@ def cayley_graph(self, side="right", simple=False, elements=None, We start with the (right) Cayley graphs of some classical groups:: - sage: D4 = DihedralGroup(4); D4 + sage: D4 = DihedralGroup(4); D4 # optional - sage.groups Dihedral group of order 8 as a permutation group - sage: G = D4.cayley_graph() - sage: show(G, color_by_label=True, edge_labels=True) - sage: A5 = AlternatingGroup(5); A5 + sage: G = D4.cayley_graph() # optional - sage.groups sage.graphs + sage: show(G, color_by_label=True, edge_labels=True) # optional - sage.groups sage.graphs sage.plot + sage: A5 = AlternatingGroup(5); A5 # optional - sage.groups Alternating group of order 5!/2 as a permutation group - sage: G = A5.cayley_graph() - sage: G.show3d(color_by_label=True, edge_size=0.01, edge_size2=0.02, vertex_size=0.03) - sage: G.show3d(vertex_size=0.03, edge_size=0.01, edge_size2=0.02, vertex_colors={(1,1,1):G.vertices(sort=True)}, bgcolor=(0,0,0), color_by_label=True, xres=700, yres=700, iterations=200) # long time (less than a minute) - sage: G.num_edges() + sage: G = A5.cayley_graph() # optional - sage.groups sage.graphs + sage: G.show3d(color_by_label=True, edge_size=0.01, # optional - sage.groups sage.graphs sage.plot + ....: edge_size2=0.02, vertex_size=0.03) + sage: G.show3d(vertex_size=0.03, # long time (less than a minute) # optional - sage.groups sage.graphs sage.plot + ....: edge_size=0.01, edge_size2=0.02, + ....: vertex_colors={(1,1,1): G.vertices(sort=True)}, + ....: bgcolor=(0,0,0), color_by_label=True, + ....: xres=700, yres=700, iterations=200) + sage: G.num_edges() # optional - sage.groups sage.graphs 120 - sage: w = WeylGroup(['A',3]) - sage: d = w.cayley_graph(); d + sage: w = WeylGroup(['A', 3]) # optional - sage.combinat sage.groups + sage: d = w.cayley_graph(); d # optional - sage.combinat sage.groups sage.graphs Digraph on 24 vertices - sage: d.show3d(color_by_label=True, edge_size=0.01, vertex_size=0.03) + sage: d.show3d(color_by_label=True, edge_size=0.01, vertex_size=0.03) # optional - sage.combinat sage.groups sage.graphs sage.plot Alternative generators may be specified:: - sage: G = A5.cayley_graph(generators=[A5.gens()[0]]) - sage: G.num_edges() + sage: G = A5.cayley_graph(generators=[A5.gens()[0]]) # optional - sage.groups sage.graphs + sage: G.num_edges() # optional - sage.groups sage.graphs 60 - sage: g = PermutationGroup([(i+1,j+1) for i in range(5) for j in range(5) if j!=i]) - sage: g.cayley_graph(generators=[(1,2),(2,3)]) + sage: g = PermutationGroup([(i + 1, j + 1) # optional - sage.groups sage.graphs + ....: for i in range(5) + ....: for j in range(5) if j != i]) + sage: g.cayley_graph(generators=[(1,2), (2,3)]) # optional - sage.groups sage.graphs Digraph on 120 vertices If ``elements`` is specified, then only the subgraph @@ -228,57 +235,61 @@ def cayley_graph(self, side="right", simple=False, elements=None, the elements of length at most 3:: sage: M = Monoids().example(); M - An example of a monoid: the free monoid generated by ('a', 'b', 'c', 'd') - sage: elements = [ M.prod(w) for w in sum((list(Words(M.semigroup_generators(),k)) for k in range(4)),[]) ] - sage: G = M.cayley_graph(elements = elements) - sage: G.num_verts(), G.num_edges() + An example of a monoid: + the free monoid generated by ('a', 'b', 'c', 'd') + sage: elements = [M.prod(w) # optional - sage.combinat + ....: for w in sum((list(Words(M.semigroup_generators(), k)) + ....: for k in range(4)), [])] + sage: G = M.cayley_graph(elements=elements) # optional - sage.combinat sage.graphs + sage: G.num_verts(), G.num_edges() # optional - sage.combinat sage.graphs (85, 84) - sage: G.show3d(color_by_label=True, edge_size=0.001, vertex_size=0.01) + sage: G.show3d(color_by_label=True, edge_size=0.001, vertex_size=0.01) # optional - sage.combinat sage.graphs sage.plot We now illustrate the ``side`` and ``simple`` options on a semigroup:: - sage: S = FiniteSemigroups().example(alphabet=('a','b')) - sage: g = S.cayley_graph(simple=True) - sage: g.vertices(sort=True) + sage: S = FiniteSemigroups().example(alphabet=('a', 'b')) + sage: g = S.cayley_graph(simple=True) # optional - sage.graphs + sage: g.vertices(sort=True) # optional - sage.graphs ['a', 'ab', 'b', 'ba'] - sage: g.edges(sort=True) + sage: g.edges(sort=True) # optional - sage.graphs [('a', 'ab', None), ('b', 'ba', None)] :: - sage: g = S.cayley_graph(side="left", simple=True) - sage: g.vertices(sort=True) + sage: g = S.cayley_graph(side="left", simple=True) # optional - sage.graphs + sage: g.vertices(sort=True) # optional - sage.graphs ['a', 'ab', 'b', 'ba'] - sage: g.edges(sort=True) + sage: g.edges(sort=True) # optional - sage.graphs [('a', 'ba', None), ('ab', 'ba', None), ('b', 'ab', None), ('ba', 'ab', None)] :: - sage: g = S.cayley_graph(side="twosided", simple=True) - sage: g.vertices(sort=True) + sage: g = S.cayley_graph(side="twosided", simple=True) # optional - sage.graphs + sage: g.vertices(sort=True) # optional - sage.graphs ['a', 'ab', 'b', 'ba'] - sage: g.edges(sort=True) + sage: g.edges(sort=True) # optional - sage.graphs [('a', 'ab', None), ('a', 'ba', None), ('ab', 'ba', None), ('b', 'ab', None), ('b', 'ba', None), ('ba', 'ab', None)] :: - sage: g = S.cayley_graph(side="twosided") - sage: g.vertices(sort=True) + sage: g = S.cayley_graph(side="twosided") # optional - sage.graphs + sage: g.vertices(sort=True) # optional - sage.graphs ['a', 'ab', 'b', 'ba'] - sage: g.edges(sort=True) + sage: g.edges(sort=True) # optional - sage.graphs [('a', 'a', (0, 'left')), ('a', 'a', (0, 'right')), ('a', 'ab', (1, 'right')), ('a', 'ba', (1, 'left')), ('ab', 'ab', (0, 'left')), ('ab', 'ab', (0, 'right')), ('ab', 'ab', (1, 'right')), ('ab', 'ba', (1, 'left')), ('b', 'ab', (0, 'left')), ('b', 'b', (1, 'left')), ('b', 'b', (1, 'right')), ('b', 'ba', (0, 'right')), ('ba', 'ab', (0, 'left')), ('ba', 'ba', (0, 'right')), ('ba', 'ba', (1, 'left')), ('ba', 'ba', (1, 'right'))] :: - sage: s1 = SymmetricGroup(1); s = s1.cayley_graph(); s.vertices(sort=False) + sage: s1 = SymmetricGroup(1); s = s1.cayley_graph() # optional - sage.groups sage.graphs + sage: s.vertices(sort=False) # optional - sage.groups sage.graphs [()] TESTS:: - sage: SymmetricGroup(2).cayley_graph(side="both") + sage: SymmetricGroup(2).cayley_graph(side="both") # optional - sage.groups sage.graphs Traceback (most recent call last): ... ValueError: option 'side' must be 'left', 'right' or 'twosided' @@ -375,51 +386,52 @@ def subsemigroup(self, generators, one=None, category=None): EXAMPLES:: sage: R = IntegerModRing(15) - sage: M = R.subsemigroup([R(3),R(5)]); M + sage: M = R.subsemigroup([R(3), R(5)]); M # optional - sage.groups A subsemigroup of (Ring of integers modulo 15) with 2 generators - sage: M.list() + sage: M.list() # optional - sage.groups [3, 5, 9, 0, 10, 12, 6] By default, `M` is just in the category of subsemigroups:: - sage: M in Semigroups().Subobjects() + sage: M in Semigroups().Subobjects() # optional - sage.groups True In the following example, we specify that `M` is a submonoid of the finite monoid `R` (it shares the same unit), and a group by itself:: - sage: M = R.subsemigroup([R(-1)], + sage: M = R.subsemigroup([R(-1)], # optional - sage.groups ....: category=Monoids().Finite().Subobjects() & Groups()); M A submonoid of (Ring of integers modulo 15) with 1 generators - sage: M.list() + sage: M.list() # optional - sage.groups [1, 14] - sage: M.one() + sage: M.one() # optional - sage.groups 1 - In the following example `M` is a group; however its unit + In the following example, `M` is a group; however, its unit does not coincide with that of `R`, so `M` is only a subsemigroup, and we need to specify its unit explicitly:: - sage: M = R.subsemigroup([R(5)], + sage: M = R.subsemigroup([R(5)], # optional - sage.groups ....: category=Semigroups().Finite().Subobjects() & Groups()); M Traceback (most recent call last): ... - ValueError: For a monoid which is just a subsemigroup, the unit should be specified + ValueError: For a monoid which is just a subsemigroup, + the unit should be specified - sage: M = R.subsemigroup([R(5)], one=R(10), + sage: M = R.subsemigroup([R(5)], one=R(10), # optional - sage.groups ....: category=Semigroups().Finite().Subobjects() & Groups()); M A subsemigroup of (Ring of integers modulo 15) with 1 generators - sage: M in Groups() + sage: M in Groups() # optional - sage.groups True - sage: M.list() + sage: M.list() # optional - sage.groups [10, 5] - sage: M.one() + sage: M.one() # optional - sage.groups 10 TESTS:: - sage: TestSuite(M).run() + sage: TestSuite(M).run() # optional - sage.groups Failure in _test_inverse: Traceback (most recent call last): ... @@ -449,8 +461,8 @@ def trivial_representation(self, base_ring=None, side="twosided"): EXAMPLES:: - sage: G = groups.permutation.Dihedral(4) - sage: G.trivial_representation() + sage: G = groups.permutation.Dihedral(4) # optional - sage.groups + sage: G.trivial_representation() # optional - sage.groups Trivial representation of Dihedral group of order 8 as a permutation group over Integer Ring """ @@ -469,8 +481,8 @@ def regular_representation(self, base_ring=None, side="left"): EXAMPLES:: - sage: G = groups.permutation.Dihedral(4) - sage: G.regular_representation() + sage: G = groups.permutation.Dihedral(4) # optional - sage.groups + sage: G.regular_representation() # optional - sage.groups Left Regular Representation of Dihedral group of order 8 as a permutation group over Integer Ring """ @@ -880,7 +892,7 @@ def algebra_generators(self): the left regular band generated by ('a', 'b', 'c', 'd') sage: M.semigroup_generators() Family ('a', 'b', 'c', 'd') - sage: M.algebra(ZZ).algebra_generators() + sage: M.algebra(ZZ).algebra_generators() # optional - sage.modules Family (B['a'], B['b'], B['c'], B['d']) """ return self.basis().keys().semigroup_generators().map(self.monomial) @@ -895,12 +907,12 @@ def gens(self): EXAMPLES:: - sage: a, b = SL2Z.algebra(ZZ).gens(); a, b + sage: a, b = SL2Z.algebra(ZZ).gens(); a, b # optional - sage.groups sage.modules ([ 0 -1] [ 1 0], [1 1] [0 1]) - sage: 2*a + b + sage: 2*a + b # optional - sage.groups sage.modules 2*[ 0 -1] [ 1 0] + @@ -915,9 +927,9 @@ def ngens(self): EXAMPLES:: - sage: SL2Z.algebra(ZZ).ngens() + sage: SL2Z.algebra(ZZ).ngens() # optional - sage.groups sage.modules 2 - sage: DihedralGroup(4).algebra(RR).ngens() + sage: DihedralGroup(4).algebra(RR).ngens() # optional - sage.groups sage.modules 2 """ return self.basis().keys().ngens() @@ -928,8 +940,8 @@ def gen(self, i=0): EXAMPLES:: - sage: A = GL(3, GF(7)).algebra(ZZ) - sage: A.gen(0) + sage: A = GL(3, GF(7)).algebra(ZZ) # optional - sage.groups sage.libs.pari sage.modules + sage: A.gen(0) # optional - sage.groups sage.libs.pari sage.modules [3 0 0] [0 1 0] [0 0 1] @@ -948,10 +960,11 @@ def product_on_basis(self, g1, g2): EXAMPLES:: sage: S = FiniteSemigroups().example(); S - An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd') - sage: A = S.algebra(QQ) - sage: a,b,c,d = A.algebra_generators() - sage: a * b + b * d * c * d + An example of a finite semigroup: + the left regular band generated by ('a', 'b', 'c', 'd') + sage: A = S.algebra(QQ) # optional - sage.modules + sage: a, b, c, d = A.algebra_generators() # optional - sage.modules + sage: a * b + b * d * c * d # optional - sage.modules B['ab'] + B['bdc'] """ return self.monomial(g1 * g2) @@ -966,10 +979,10 @@ def trivial_representation(self, side="twosided"): EXAMPLES:: - sage: G = groups.permutation.Dihedral(4) - sage: A = G.algebra(QQ) - sage: V = A.trivial_representation() - sage: V == G.trivial_representation(QQ) + sage: G = groups.permutation.Dihedral(4) # optional - sage.groups + sage: A = G.algebra(QQ) # optional - sage.groups sage.modules + sage: V = A.trivial_representation() # optional - sage.groups sage.modules + sage: V == G.trivial_representation(QQ) # optional - sage.groups sage.modules True """ S = self.basis().keys() @@ -986,10 +999,10 @@ def regular_representation(self, side="left"): EXAMPLES:: - sage: G = groups.permutation.Dihedral(4) - sage: A = G.algebra(QQ) - sage: V = A.regular_representation() - sage: V == G.regular_representation(QQ) + sage: G = groups.permutation.Dihedral(4) # optional - sage.groups + sage: A = G.algebra(QQ) # optional - sage.groups sage.modules + sage: V = A.regular_representation() # optional - sage.groups sage.modules + sage: V == G.regular_representation(QQ) # optional - sage.groups sage.modules True """ S = self.basis().keys() diff --git a/src/sage/categories/semisimple_algebras.py b/src/sage/categories/semisimple_algebras.py index be7a581c798..9be6bb8d571 100644 --- a/src/sage/categories/semisimple_algebras.py +++ b/src/sage/categories/semisimple_algebras.py @@ -37,15 +37,15 @@ class SemisimpleAlgebras(Category_over_base_ring): Typically, finite group algebras are semisimple:: - sage: DihedralGroup(5).algebra(QQ) in SemisimpleAlgebras + sage: DihedralGroup(5).algebra(QQ) in SemisimpleAlgebras # optional - sage.groups True Unless the characteristic of the field divides the order of the group:: - sage: DihedralGroup(5).algebra(IntegerModRing(5)) in SemisimpleAlgebras + sage: DihedralGroup(5).algebra(IntegerModRing(5)) in SemisimpleAlgebras # optional - sage.groups False - sage: DihedralGroup(5).algebra(IntegerModRing(7)) in SemisimpleAlgebras + sage: DihedralGroup(5).algebra(IntegerModRing(7)) in SemisimpleAlgebras # optional - sage.groups True .. SEEALSO:: :wikipedia:`Semisimple_algebra` @@ -96,13 +96,13 @@ def radical_basis(self, **keywords): EXAMPLES:: - sage: A = SymmetricGroup(4).algebra(QQ) - sage: A.radical_basis() + sage: A = SymmetricGroup(4).algebra(QQ) # optional - sage.groups + sage: A.radical_basis() # optional - sage.groups () TESTS:: - sage: A.radical_basis.__module__ + sage: A.radical_basis.__module__ # optional - sage.groups 'sage.categories.finite_dimensional_semisimple_algebras_with_basis' """ return () diff --git a/src/sage/categories/sets_cat.py b/src/sage/categories/sets_cat.py index bc3c55e9029..069ebc5337c 100644 --- a/src/sage/categories/sets_cat.py +++ b/src/sage/categories/sets_cat.py @@ -147,7 +147,7 @@ class Sets(Category_singleton): We run some generic checks on P:: - sage: TestSuite(P).run(verbose=True) + sage: TestSuite(P).run(verbose=True) # optional - sage.libs.pari running ._test_an_element() . . . pass running ._test_cardinality() . . . pass running ._test_category() . . . pass @@ -867,11 +867,11 @@ def Facade(self): 1. as plain integers:: - sage: P = Poset((divisors(12), attrcall("divides")), facade=True) + sage: P = Poset((divisors(12), attrcall("divides")), facade=True) # optional - sage.graphs sage.combinat 2. as integers, modified to be aware that their parent is `P`:: - sage: Q = Poset((divisors(12), attrcall("divides")), facade=False) + sage: Q = Poset((divisors(12), attrcall("divides")), facade=False) # optional - sage.graphs sage.combinat The advantage of option 1. is that one needs not do conversions back and forth between `P` and `\ZZ`. The @@ -885,23 +885,23 @@ def Facade(self): To raise this ambiguity, one needs to explicitly specify the underlying poset as in `2 <_P 3`:: - sage: P = Posets().example("facade") - sage: P.lt(2,3) + sage: P = Posets().example("facade") # optional - sage.graphs sage.combinat + sage: P.lt(2,3) # optional - sage.graphs sage.combinat False On the other hand, with option 2. and once constructed, the elements know unambiguously how to compare themselves:: - sage: Q(2) < Q(3) + sage: Q(2) < Q(3) # optional - sage.graphs sage.combinat False - sage: Q(2) < Q(6) + sage: Q(2) < Q(6) # optional - sage.graphs sage.combinat True Beware that ``P(2)`` is still the integer `2`. Therefore ``P(2) < P(3)`` still compares `2` and `3` as integers!:: - sage: P(2) < P(3) + sage: P(2) < P(3) # optional - sage.graphs sage.combinat True In short `P` being a facade parent is one of the programmatic @@ -970,17 +970,19 @@ def _element_constructor_(self): sage: S(17) # indirect doctest 17 - sage: A = FreeModule(QQ, 3) - sage: A.element_class + sage: A = FreeModule(QQ, 3) # optional - sage.modules + sage: A.element_class # optional - sage.modules - sage: A._element_constructor_ - + sage: A._element_constructor_ # optional - sage.modules + - sage: B = SymmetricGroup(3).algebra(ZZ) - sage: B.element_class + sage: B = SymmetricGroup(3).algebra(ZZ) # optional - sage.groups sage.modules + sage: B.element_class # optional - sage.groups sage.modules <...SymmetricGroupAlgebra_n_with_category.element_class'> - sage: B._element_constructor_ - + sage: B._element_constructor_ # optional - sage.groups sage.modules + """ if hasattr(self, "element_class"): return self._element_constructor_from_element_class @@ -1190,12 +1192,12 @@ def _test_elements_eq_reflexive(self, **options): We try a non-reflexive equality:: sage: P = Sets().example("wrapper") - sage: P._test_elements_eq_reflexive() + sage: P._test_elements_eq_reflexive() # optional - sage.libs.pari sage: eq = P.element_class.__eq__ sage: P.element_class.__eq__ = (lambda x, y: ....: False if eq(x, P(47)) and eq(y, P(47)) else eq(x, y)) - sage: P._test_elements_eq_reflexive() + sage: P._test_elements_eq_reflexive() # optional - sage.libs.pari Traceback (most recent call last): ... AssertionError: 47 != 47 @@ -1226,7 +1228,7 @@ def _test_elements_eq_symmetric(self, **options): We test a non symmetric equality:: sage: P = Sets().example("wrapper") - sage: P._test_elements_eq_symmetric() + sage: P._test_elements_eq_symmetric() # optional - sage.libs.pari sage: eq = P.element_class.__eq__ sage: def non_sym_eq(x, y): @@ -1234,7 +1236,7 @@ def _test_elements_eq_symmetric(self, **options): ....: elif eq(x, P(47)) and eq(y, P(53)): return True ....: else: return eq(x, y) sage: P.element_class.__eq__ = non_sym_eq - sage: P._test_elements_eq_symmetric() + sage: P._test_elements_eq_symmetric() # optional - sage.libs.pari Traceback (most recent call last): ... AssertionError: non symmetric equality: 47 == 53 but 53 != 47 @@ -1267,9 +1269,9 @@ def _test_elements_eq_transitive(self, **options): We test a non transitive equality:: - sage: R = Zp(3) - sage: test = raw_getattr(Sets().ParentMethods, "_test_elements_eq_transitive") - sage: test(R, elements=[R(3,2),R(3,1),R(0)]) + sage: R = Zp(3) # optional - sage.rings.padics + sage: test = raw_getattr(Sets().ParentMethods, "_test_elements_eq_transitive") # optional - sage.rings.padics + sage: test(R, elements=[R(3,2), R(3,1), R(0)]) # optional - sage.rings.padics Traceback (most recent call last): ... AssertionError: non transitive equality: @@ -1316,12 +1318,12 @@ def _test_elements_neq(self, **options): We try a broken inequality:: sage: P = Sets().example("wrapper") - sage: P._test_elements_neq() + sage: P._test_elements_neq() # optional - sage.libs.pari sage: ne = P.element_class.__ne__ sage: eq = P.element_class.__eq__ sage: P.element_class.__ne__ = lambda x, y: False - sage: P._test_elements_neq() + sage: P._test_elements_neq() # optional - sage.libs.pari Traceback (most recent call last): ... AssertionError: __eq__ and __ne__ inconsistency: @@ -1560,20 +1562,21 @@ def cartesian_product(*parents, **kwargs): EXAMPLES:: sage: C = AlgebrasWithBasis(QQ) - sage: A = C.example(); A.rename("A") - sage: A.cartesian_product(A,A) + sage: A = C.example(); A.rename("A") # optional - sage.combinat sage.modules + sage: A.cartesian_product(A, A) # optional - sage.combinat sage.modules A (+) A (+) A - sage: ZZ.cartesian_product(GF(2), FiniteEnumeratedSet([1,2,3])) - The Cartesian product of (Integer Ring, Finite Field of size 2, {1, 2, 3}) + sage: ZZ.cartesian_product(GF(2), FiniteEnumeratedSet([1,2,3])) # optional - sage.rings.finite_rings + The Cartesian product of (Integer Ring, + Finite Field of size 2, {1, 2, 3}) - sage: C = ZZ.cartesian_product(A); C + sage: C = ZZ.cartesian_product(A); C # optional - sage.combinat sage.modules The Cartesian product of (Integer Ring, A) TESTS:: - sage: type(C) + sage: type(C) # optional - sage.combinat sage.modules - sage: C.category() + sage: C.category() # optional - sage.combinat sage.modules Join of Category of rings and ... and Category of Cartesian products of commutative additive groups @@ -1626,21 +1629,21 @@ def algebra(self, base_ring, category=None, **kwds): If `S` is a :class:`group `, the result is its group algebra `KS`:: - sage: S = DihedralGroup(4); S - Dihedral group of order 8 as a permutation group - sage: A = S.algebra(QQ); A + sage: S = DihedralGroup(4); S # optional - sage.groups + Dihedral group of order 8 as a permutation group + sage: A = S.algebra(QQ); A # optional - sage.groups sage.modules Algebra of Dihedral group of order 8 as a permutation group - over Rational Field - sage: A.category() + over Rational Field + sage: A.category() # optional - sage.groups sage.modules Category of finite group algebras over Rational Field - sage: a = A.an_element(); a + sage: a = A.an_element(); a # optional - sage.groups sage.modules () + (1,3) + 2*(1,3)(2,4) + 3*(1,4,3,2) This space is endowed with an algebra structure, obtained by extending by bilinearity the multiplication of `G` to a multiplication on `RG`:: - sage: a * a + sage: a * a # optional - sage.groups sage.modules 6*() + 4*(2,4) + 3*(1,2)(3,4) + 12*(1,2,3,4) + 2*(1,3) + 13*(1,3)(2,4) + 6*(1,4,3,2) + 3*(1,4)(2,3) @@ -1648,11 +1651,13 @@ def algebra(self, base_ring, category=None, **kwds): monoid algebra `KS`:: sage: S = Monoids().example(); S - An example of a monoid: the free monoid generated by ('a', 'b', 'c', 'd') - sage: A = S.algebra(QQ); A - Algebra of An example of a monoid: the free monoid generated by ('a', 'b', 'c', 'd') - over Rational Field - sage: A.category() + An example of a monoid: + the free monoid generated by ('a', 'b', 'c', 'd') + sage: A = S.algebra(QQ); A # optional - sage.modules + Algebra of + An example of a monoid: the free monoid generated by ('a', 'b', 'c', 'd') + over Rational Field + sage: A.category() # optional - sage.modules Category of monoid algebras over Rational Field Similarly, we can construct algebras for additive magmas, @@ -1662,17 +1667,17 @@ def algebra(self, base_ring, category=None, **kwds): here we build the algebra of the additive group `GF_3`:: sage: from sage.categories.additive_groups import AdditiveGroups - sage: S = GF(7) - sage: A = S.algebra(QQ, category=AdditiveGroups()); A + sage: S = GF(7) # optional - sage.rings.finite_rings + sage: A = S.algebra(QQ, category=AdditiveGroups()); A # optional - sage.rings.finite_rings sage.modules Algebra of Finite Field of size 7 over Rational Field - sage: A.category() + sage: A.category() # optional - sage.rings.finite_rings sage.modules Category of finite dimensional additive group algebras over Rational Field - sage: a = A(S(1)) - sage: a + sage: a = A(S(1)) # optional - sage.rings.finite_rings sage.modules + sage: a # optional - sage.rings.finite_rings sage.modules 1 - sage: 1 + a * a * a + sage: 1 + a * a * a # optional - sage.rings.finite_rings sage.modules 0 + 3 Note that the ``category`` keyword needs to be fed with @@ -1717,29 +1722,29 @@ def _sympy_(self): sage: F = FiniteEnumeratedSets().example(); F An example of a finite enumerated set: {1,2,3} - sage: sF = F._sympy_(); sF + sage: sF = F._sympy_(); sF # optional - sympy SageSet(An example of a finite enumerated set: {1,2,3}) - sage: sF.is_finite_set + sage: sF.is_finite_set # optional - sympy True - sage: bool(sF) + sage: bool(sF) # optional - sympy True - sage: len(sF) + sage: len(sF) # optional - sympy 3 - sage: list(sF) + sage: list(sF) # optional - sympy [1, 2, 3] - sage: from sympy import FiniteSet - sage: FiniteSet.fromiter(sF) # random - this output format is sympy >= 1.9 + sage: from sympy import FiniteSet # optional - sympy + sage: FiniteSet.fromiter(sF) # random - this output is sympy >= 1.9 # optional - sympy FiniteSet(1, 2, 3) - sage: RR._sympy_().is_finite_set + sage: RR._sympy_().is_finite_set # optional - sympy False sage: F = Family([1, 2]) sage: F is Family([1, 2]) False - sage: sF = F._sympy_(); sF + sage: sF = F._sympy_(); sF # optional - sympy SageSet(Family (1, 2)) - sage: sF._sage_() is F + sage: sF._sage_() is F # optional - sympy True """ from sage.interfaces.sympy_wrapper import SageSet @@ -1764,9 +1769,9 @@ def cartesian_product(*elements): EXAMPLES:: sage: C = AlgebrasWithBasis(QQ) - sage: A = C.example() - sage: (a,b,c) = A.algebra_generators() - sage: a.cartesian_product(b, c) + sage: A = C.example() # optional - sage.combinat sage.modules + sage: a, b, c = A.algebra_generators() # optional - sage.combinat sage.modules + sage: a.cartesian_product(b, c) # optional - sage.combinat sage.modules B[(0, word: a)] + B[(1, word: b)] + B[(2, word: c)] FIXME: is this a policy that we want to enforce on all parents? @@ -1800,22 +1805,22 @@ def __invert__(self): We now try to inverse a couple of morphisms defined by a matrix:: - sage: H = End(QQ^2) - sage: phi = H(matrix([[1,1],[0,1]])); phi + sage: H = End(QQ^2) # optional - sage.modules + sage: phi = H(matrix([[1,1], [0,1]])); phi # optional - sage.modules Vector space morphism represented by the matrix: [1 1] [0 1] Domain: Vector space of dimension 2 over Rational Field Codomain: Vector space of dimension 2 over Rational Field - sage: ~phi + sage: ~phi # optional - sage.modules Vector space morphism represented by the matrix: [ 1 -1] [ 0 1] Domain: Vector space of dimension 2 over Rational Field Codomain: Vector space of dimension 2 over Rational Field - sage: phi = H(matrix([[1,1],[1,1]])) - sage: ~phi + sage: phi = H(matrix([[1,1], [1,1]])) # optional - sage.modules + sage: ~phi # optional - sage.modules Traceback (most recent call last): ... ZeroDivisionError: matrix morphism not invertible @@ -1832,11 +1837,11 @@ def is_injective(self): EXAMPLES:: - sage: f = ZZ.hom(GF(3)); f + sage: f = ZZ.hom(GF(3)); f # optional - sage.rings.finite_rings Natural morphism: From: Integer Ring To: Finite Field of size 3 - sage: f.is_injective() + sage: f.is_injective() # optional - sage.rings.finite_rings False """ if self.domain().cardinality() <= 1: @@ -1851,11 +1856,11 @@ def image(self, domain_subset=None): EXAMPLES:: - sage: P = Partitions(6) - sage: H = Hom(P, ZZ) - sage: f = H(ZZ.sum) - sage: X = f.image() - sage: list(X) + sage: P = Partitions(6) # optional - sage.combinat + sage: H = Hom(P, ZZ) # optional - sage.combinat + sage: f = H(ZZ.sum) # optional - sage.combinat + sage: X = f.image() # optional - sage.combinat + sage: list(X) # optional - sage.combinat [6] """ D = self.domain() @@ -2006,7 +2011,8 @@ def lift(self, x): sage: S = Semigroups().Subquotients().example() sage: s = S.an_element() sage: s, s.parent() - (42, An example of a (sub)quotient semigroup: a quotient of the left zero semigroup) + (42, An example of a (sub)quotient semigroup: + a quotient of the left zero semigroup) sage: S.lift(s), S.lift(s).parent() (42, An example of a semigroup: the left zero semigroup) sage: s.lift(), s.lift().parent() @@ -2041,7 +2047,8 @@ def retract(self, x): sage: s, s.parent() (42, An example of a semigroup: the left zero semigroup) sage: S.retract(s), S.retract(s).parent() - (42, An example of a (sub)quotient semigroup: a quotient of the left zero semigroup) + (42, An example of a (sub)quotient semigroup: + a quotient of the left zero semigroup) """ class ElementMethods: @@ -2055,7 +2062,8 @@ def lift(self): sage: S = Semigroups().Subquotients().example() sage: s = S.an_element() sage: s, s.parent() - (42, An example of a (sub)quotient semigroup: a quotient of the left zero semigroup) + (42, An example of a (sub)quotient semigroup: + a quotient of the left zero semigroup) sage: S.lift(s), S.lift(s).parent() (42, An example of a semigroup: the left zero semigroup) sage: s.lift(), s.lift().parent() @@ -2132,7 +2140,7 @@ def _repr_(self): EXAMPLES:: sage: from sage.categories.examples.semigroups import IncompleteSubquotientSemigroup - sage: S = IncompleteSubquotientSemigroup(category = Semigroups().Subobjects()) + sage: S = IncompleteSubquotientSemigroup(category=Semigroups().Subobjects()) sage: S._repr_() 'A subobject of An example of a semigroup: the left zero semigroup' """ @@ -2231,7 +2239,7 @@ def __iter__(self): Sets are intrinsically unordered:: - sage: for x,y in cartesian_product([Set([1,2]), Set(['a','b'])]): # random + sage: for x,y in cartesian_product([Set([1,2]), Set(['a','b'])]): # random ....: print((x, y)) (1, 'b') (1, 'a') @@ -2251,18 +2259,18 @@ def __iter__(self): sage: C.__iter__.__module__ 'sage.categories.sets_cat' - sage: F22 = GF(2).cartesian_product(GF(2)) - sage: list(F22) + sage: F22 = GF(2).cartesian_product(GF(2)) # optional - sage.rings.finite_rings + sage: list(F22) # optional - sage.rings.finite_rings [(0, 0), (0, 1), (1, 0), (1, 1)] - sage: C = cartesian_product([Permutations(10)]*4) - sage: it = iter(C) - sage: next(it) + sage: C = cartesian_product([Permutations(10)]*4) # optional - sage.combinat + sage: it = iter(C) # optional - sage.combinat + sage: next(it) # optional - sage.combinat ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) - sage: next(it) + sage: next(it) # optional - sage.combinat ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], @@ -2271,8 +2279,8 @@ def __iter__(self): When all factors (except possibly the first factor) are known to be finite, it uses the lexicographic order:: - sage: it = iter(cartesian_product([ZZ, GF(2)])) - sage: [next(it) for _ in range(10)] + sage: it = iter(cartesian_product([ZZ, GF(2)])) # optional - sage.rings.finite_rings + sage: [next(it) for _ in range(10)] # optional - sage.rings.finite_rings [(0, 0), (0, 1), (1, 0), (1, 1), (-1, 0), (-1, 1), @@ -2292,8 +2300,8 @@ def __iter__(self): An example with the first factor finite, the second infinite:: - sage: it = iter(cartesian_product([GF(2), ZZ])) - sage: [next(it) for _ in range(11)] + sage: it = iter(cartesian_product([GF(2), ZZ])) # optional - sage.rings.finite_rings + sage: [next(it) for _ in range(11)] # optional - sage.rings.finite_rings [(0, 0), (1, 0), (0, 1), (1, 1), (0, -1), @@ -2378,8 +2386,8 @@ def is_finite(self): EXAMPLES:: sage: E = FiniteEnumeratedSet([1,2,3]) - sage: C = cartesian_product([E, SymmetricGroup(4)]) - sage: C.is_finite() + sage: C = cartesian_product([E, SymmetricGroup(4)]) # optional - sage.groups + sage: C.is_finite() # optional - sage.groups True sage: cartesian_product([ZZ,ZZ]).is_finite() @@ -2406,8 +2414,8 @@ def cardinality(self): EXAMPLES:: sage: E = FiniteEnumeratedSet([1,2,3]) - sage: C = cartesian_product([E,SymmetricGroup(4)]) - sage: C.cardinality() + sage: C = cartesian_product([E, SymmetricGroup(4)]) # optional - sage.groups + sage: C.cardinality() # optional - sage.groups 72 sage: E = FiniteEnumeratedSet([]) @@ -2419,9 +2427,9 @@ def cardinality(self): sage: C.cardinality() +Infinity - sage: cartesian_product([GF(5), Permutations(10)]).cardinality() + sage: cartesian_product([GF(5), Permutations(10)]).cardinality() # optional - sage.rings.finite_rings sage.combinat 18144000 - sage: cartesian_product([GF(71)]*20).cardinality() == 71**20 + sage: cartesian_product([GF(71)]*20).cardinality() == 71**20 # optional - sage.rings.finite_rings True """ f = self.cartesian_factors() @@ -2452,8 +2460,8 @@ def random_element(self, *args): EXAMPLES:: - sage: C = cartesian_product([Permutations(10)]*5) - sage: C.random_element() # random + sage: C = cartesian_product([Permutations(10)]*5) # optional - sage.combinat + sage: C.random_element() # random # optional - sage.combinat ([2, 9, 4, 7, 1, 8, 6, 10, 5, 3], [8, 6, 5, 7, 1, 4, 9, 3, 10, 2], [5, 10, 3, 8, 2, 9, 1, 4, 7, 6], @@ -2562,9 +2570,9 @@ def _sympy_(self): EXAMPLES:: sage: ZZ3 = cartesian_product([ZZ, ZZ, ZZ]) - sage: sZZ3 = ZZ3._sympy_(); sZZ3 + sage: sZZ3 = ZZ3._sympy_(); sZZ3 # optional - sympy ProductSet(Integers, Integers, Integers) - sage: (1, 2, 3) in sZZ3 + sage: (1, 2, 3) in sZZ3 # optional - sympy True """ from sympy import ProductSet @@ -2585,13 +2593,14 @@ def cartesian_projection(self, i): EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.__custom_name = "F" - sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.__custom_name = "G" - sage: S = cartesian_product([F, G]) - sage: x = S.monomial((0,4)) + 2 * S.monomial((0,5)) + 3 * S.monomial((1,6)) - sage: x.cartesian_projection(0) + sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename("F") # optional - sage.modules + sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename("G") # optional - sage.modules + sage: S = cartesian_product([F, G]) # optional - sage.modules + sage: x = (S.monomial((0,4)) + 2 * S.monomial((0,5)) # optional - sage.modules + ....: + 3 * S.monomial((1,6))) + sage: x.cartesian_projection(0) # optional - sage.modules B[4] + 2*B[5] - sage: x.cartesian_projection(1) + sage: x.cartesian_projection(1) # optional - sage.modules 3*B[6] """ return self.parent().cartesian_projection(i)(self) @@ -2602,18 +2611,20 @@ def cartesian_factors(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.__custom_name = "F" - sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.__custom_name = "G" - sage: H = CombinatorialFreeModule(ZZ, [4,7]); H.__custom_name = "H" - sage: S = cartesian_product([F, G, H]) - sage: x = S.monomial((0,4)) + 2 * S.monomial((0,5)) + 3 * S.monomial((1,6)) + 4 * S.monomial((2,4)) + 5 * S.monomial((2,7)) - sage: x.cartesian_factors() + sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename("F") # optional - sage.modules + sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename("G") # optional - sage.modules + sage: H = CombinatorialFreeModule(ZZ, [4,7]); H.rename("H") # optional - sage.modules + sage: S = cartesian_product([F, G, H]) # optional - sage.modules + sage: x = (S.monomial((0,4)) + 2 * S.monomial((0,5)) # optional - sage.modules + ....: + 3 * S.monomial((1,6)) + 4 * S.monomial((2,4)) + ....: + 5 * S.monomial((2,7))) + sage: x.cartesian_factors() # optional - sage.modules (B[4] + 2*B[5], 3*B[6], 4*B[4] + 5*B[7]) - sage: [s.parent() for s in x.cartesian_factors()] + sage: [s.parent() for s in x.cartesian_factors()] # optional - sage.modules [F, G, H] - sage: S.zero().cartesian_factors() + sage: S.zero().cartesian_factors() # optional - sage.modules (0, 0, 0) - sage: [s.parent() for s in S.zero().cartesian_factors()] + sage: [s.parent() for s in S.zero().cartesian_factors()] # optional - sage.modules [F, G, H] """ # TODO: optimize @@ -2633,7 +2644,7 @@ def extra_super_categories(self): sage: Sets().Algebras(QQ).extra_super_categories() [Category of vector spaces with basis over Rational Field] - sage: Sets().example().algebra(ZZ).categories() + sage: Sets().example().algebra(ZZ).categories() # optional - sage.groups sage.modules [Category of set algebras over Integer Ring, Category of modules with basis over Integer Ring, ... @@ -2650,20 +2661,20 @@ def construction(self): EXAMPLES:: - sage: A = GroupAlgebra(KleinFourGroup(), QQ) - sage: F, arg = A.construction(); F, arg + sage: A = GroupAlgebra(KleinFourGroup(), QQ) # optional - sage.groups sage.modules + sage: F, arg = A.construction(); F, arg # optional - sage.groups sage.modules (GroupAlgebraFunctor, Rational Field) - sage: F(arg) is A + sage: F(arg) is A # optional - sage.groups sage.modules True This also works for structures such as monoid algebras (see :trac:`27937`):: - sage: A = FreeAbelianMonoid('x,y').algebra(QQ) - sage: F, arg = A.construction(); F, arg + sage: A = FreeAbelianMonoid('x,y').algebra(QQ) # optional - sage.groups sage.modules + sage: F, arg = A.construction(); F, arg # optional - sage.groups sage.modules (The algebra functorial construction, Free abelian monoid on 2 generators (x, y)) - sage: F(arg) is A + sage: F(arg) is A # optional - sage.groups sage.modules True """ from sage.categories.algebra_functor import ( @@ -2681,14 +2692,14 @@ def _repr_(self): EXAMPLES:: - sage: A = Groups().example().algebra(QQ); A + sage: A = Groups().example().algebra(QQ); A # optional - sage.groups sage.modules Algebra of General Linear Group of degree 4 over Rational Field over Rational Field - sage: A._name = "foo" - sage: A + sage: A._name = "foo" # optional - sage.groups sage.modules + sage: A # optional - sage.groups sage.modules foo over Rational Field - sage: A = KleinFourGroup().algebra(ZZ) - sage: A + sage: A = KleinFourGroup().algebra(ZZ) # optional - sage.groups sage.modules + sage: A # optional - sage.groups sage.modules Algebra of The Klein 4 group of order 4, as a permutation group over Integer Ring """ @@ -2720,10 +2731,10 @@ def example(self, base_ring=None, set=None): EXAMPLES:: - sage: Sets().WithRealizations().example() + sage: Sets().WithRealizations().example() # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field - sage: Sets().WithRealizations().example(ZZ, Set([1,2])) + sage: Sets().WithRealizations().example(ZZ, Set([1,2])) # optional - sage.combinat sage.modules The subset algebra of {1, 2} over Integer Ring """ from sage.rings.rational_field import QQ @@ -2749,8 +2760,8 @@ def _test_with_realizations(self, **options): EXAMPLES:: - sage: A = Sets().WithRealizations().example() - sage: A._test_with_realizations() + sage: A = Sets().WithRealizations().example() # optional - sage.combinat sage.modules + sage: A._test_with_realizations() # optional - sage.combinat sage.modules See the documentation for :class:`TestSuite` for more information. @@ -2780,13 +2791,15 @@ def _register_realization(self, realization): """ EXAMPLES:: - sage: A = Sets().WithRealizations().example(QQ['x']); A - The subset algebra of {1, 2, 3} over Univariate Polynomial Ring in x over Rational Field - sage: class ANewRealizationOfA(CombinatorialFreeModule): + sage: A = Sets().WithRealizations().example(QQ['x']); A # optional - sage.combinat sage.modules + The subset algebra of {1, 2, 3} + over Univariate Polynomial Ring in x over Rational Field + sage: class ANewRealizationOfA(CombinatorialFreeModule): # optional - sage.combinat sage.modules ....: pass - sage: category = A.Realizations() & Algebras(QQ[x]).WithBasis() - sage: R = ANewRealizationOfA(A.base_ring(), A.F().basis().keys(), category = category) - sage: R in A.realizations() # indirect doctest + sage: category = A.Realizations() & Algebras(QQ[x]).WithBasis() # optional - sage.combinat sage.modules + sage: R = ANewRealizationOfA(A.base_ring(), A.F().basis().keys(), # optional - sage.combinat sage.modules + ....: category=category) + sage: R in A.realizations() # indirect doctest # optional - sage.combinat sage.modules True Note: the test above uses ``QQ[x]`` to not interfer @@ -2814,82 +2827,102 @@ def inject_shorthands(self, shorthands=None, verbose=True): it is convenient to define shorthands for the various realizations, but cumbersome to do it by hand:: - sage: S = SymmetricFunctions(ZZ); S + sage: S = SymmetricFunctions(ZZ); S # optional - sage.combinat Symmetric Functions over Integer Ring - sage: s = S.s(); s + sage: s = S.s(); s # optional - sage.combinat Symmetric Functions over Integer Ring in the Schur basis - sage: e = S.e(); e + sage: e = S.e(); e # optional - sage.combinat Symmetric Functions over Integer Ring in the elementary basis This method automates the process:: - sage: S.inject_shorthands() - Defining e as shorthand for Symmetric Functions over Integer Ring in the elementary basis - Defining f as shorthand for Symmetric Functions over Integer Ring in the forgotten basis - Defining h as shorthand for Symmetric Functions over Integer Ring in the homogeneous basis - Defining m as shorthand for Symmetric Functions over Integer Ring in the monomial basis - Defining p as shorthand for Symmetric Functions over Integer Ring in the powersum basis - Defining s as shorthand for Symmetric Functions over Integer Ring in the Schur basis - sage: s[1] + e[2] * p[1,1] + 2*h[3] + m[2,1] - s[1] - 2*s[1, 1, 1] + s[1, 1, 1, 1] + s[2, 1] + 2*s[2, 1, 1] + s[2, 2] + 2*s[3] + s[3, 1] - - sage: e + sage: S.inject_shorthands() # optional - sage.combinat + Defining e as shorthand for + Symmetric Functions over Integer Ring in the elementary basis + Defining f as shorthand for + Symmetric Functions over Integer Ring in the forgotten basis + Defining h as shorthand for + Symmetric Functions over Integer Ring in the homogeneous basis + Defining m as shorthand for + Symmetric Functions over Integer Ring in the monomial basis + Defining p as shorthand for + Symmetric Functions over Integer Ring in the powersum basis + Defining s as shorthand for + Symmetric Functions over Integer Ring in the Schur basis + sage: s[1] + e[2] * p[1,1] + 2*h[3] + m[2,1] # optional - sage.combinat + s[1] - 2*s[1, 1, 1] + s[1, 1, 1, 1] + s[2, 1] + + 2*s[2, 1, 1] + s[2, 2] + 2*s[3] + s[3, 1] + + sage: e # optional - sage.combinat Symmetric Functions over Integer Ring in the elementary basis - sage: p + sage: p # optional - sage.combinat Symmetric Functions over Integer Ring in the powersum basis - sage: s + sage: s # optional - sage.combinat Symmetric Functions over Integer Ring in the Schur basis Sometimes, like for symmetric functions, one can request for all shorthands to be defined, including less common ones:: - sage: S.inject_shorthands("all") - Defining e as shorthand for Symmetric Functions over Integer Ring in the elementary basis - Defining f as shorthand for Symmetric Functions over Integer Ring in the forgotten basis - Defining h as shorthand for Symmetric Functions over Integer Ring in the homogeneous basis - Defining ht as shorthand for Symmetric Functions over Integer Ring in the induced trivial symmetric group character basis - Defining m as shorthand for Symmetric Functions over Integer Ring in the monomial basis - Defining o as shorthand for Symmetric Functions over Integer Ring in the orthogonal basis - Defining p as shorthand for Symmetric Functions over Integer Ring in the powersum basis - Defining s as shorthand for Symmetric Functions over Integer Ring in the Schur basis - Defining sp as shorthand for Symmetric Functions over Integer Ring in the symplectic basis - Defining st as shorthand for Symmetric Functions over Integer Ring in the irreducible symmetric group character basis - Defining w as shorthand for Symmetric Functions over Integer Ring in the Witt basis + sage: S.inject_shorthands("all") # optional - sage.combinat + Defining e as shorthand for + Symmetric Functions over Integer Ring in the elementary basis + Defining f as shorthand for + Symmetric Functions over Integer Ring in the forgotten basis + Defining h as shorthand for + Symmetric Functions over Integer Ring in the homogeneous basis + Defining ht as shorthand for + Symmetric Functions over Integer Ring in the + induced trivial symmetric group character basis + Defining m as shorthand for + Symmetric Functions over Integer Ring in the monomial basis + Defining o as shorthand for + Symmetric Functions over Integer Ring in the orthogonal basis + Defining p as shorthand for + Symmetric Functions over Integer Ring in the powersum basis + Defining s as shorthand for + Symmetric Functions over Integer Ring in the Schur basis + Defining sp as shorthand for + Symmetric Functions over Integer Ring in the symplectic basis + Defining st as shorthand for + Symmetric Functions over Integer Ring in the + irreducible symmetric group character basis + Defining w as shorthand for + Symmetric Functions over Integer Ring in the Witt basis The messages can be silenced by setting ``verbose=False``:: - sage: Q = QuasiSymmetricFunctions(ZZ) - sage: Q.inject_shorthands(verbose=False) + sage: Q = QuasiSymmetricFunctions(ZZ) # optional - sage.combinat + sage: Q.inject_shorthands(verbose=False) # optional - sage.combinat - sage: F[1,2,1] + 5*M[1,3] + F[2]^2 + sage: F[1,2,1] + 5*M[1,3] + F[2]^2 # optional - sage.combinat 5*F[1, 1, 1, 1] - 5*F[1, 1, 2] - 3*F[1, 2, 1] + 6*F[1, 3] + 2*F[2, 2] + F[3, 1] + F[4] - sage: F + sage: F # optional - sage.combinat Quasisymmetric functions over the Integer Ring in the Fundamental basis - sage: M + sage: M # optional - sage.combinat Quasisymmetric functions over the Integer Ring in the Monomial basis One can also just import a subset of the shorthands:: - sage: SQ = SymmetricFunctions(QQ) - sage: SQ.inject_shorthands(['p', 's'], verbose=False) - sage: p + sage: SQ = SymmetricFunctions(QQ) # optional - sage.combinat + sage: SQ.inject_shorthands(['p', 's'], verbose=False) # optional - sage.combinat + sage: p # optional - sage.combinat Symmetric Functions over Rational Field in the powersum basis - sage: s + sage: s # optional - sage.combinat Symmetric Functions over Rational Field in the Schur basis Note that ``e`` is left unchanged:: - sage: e + sage: e # optional - sage.combinat Symmetric Functions over Integer Ring in the elementary basis TESTS:: - sage: e == S.e(), h == S.h(), m == S.m(), p == SQ.p(), s == SQ.s() + sage: e == S.e(), h == S.h(), m == S.m(), p == SQ.p(), s == SQ.s() # optional - sage.combinat (True, True, True, True, True) """ from sage.misc.misc import inject_variable @@ -2912,10 +2945,11 @@ def a_realization(self): EXAMPLES:: - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field - sage: A.a_realization() - The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis + sage: A.a_realization() # optional - sage.combinat sage.modules + The subset algebra of {1, 2, 3} over Rational Field + in the Fundamental basis """ def realizations(self): @@ -2925,10 +2959,12 @@ def realizations(self): EXAMPLES:: - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field - sage: A.realizations() - [The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis, The subset algebra of {1, 2, 3} over Rational Field in the In basis, The subset algebra of {1, 2, 3} over Rational Field in the Out basis] + sage: A.realizations() # optional - sage.combinat sage.modules + [The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis, + The subset algebra of {1, 2, 3} over Rational Field in the In basis, + The subset algebra of {1, 2, 3} over Rational Field in the Out basis] .. NOTE:: @@ -2945,20 +2981,22 @@ def facade_for(self): EXAMPLES:: - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field - sage: A.facade_for() - [The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis, The subset algebra of {1, 2, 3} over Rational Field in the In basis, The subset algebra of {1, 2, 3} over Rational Field in the Out basis] + sage: A.facade_for() # optional - sage.combinat sage.modules + [The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis, + The subset algebra of {1, 2, 3} over Rational Field in the In basis, + The subset algebra of {1, 2, 3} over Rational Field in the Out basis] - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field - sage: f = A.F().an_element(); f + sage: f = A.F().an_element(); f # optional - sage.combinat sage.modules F[{}] + 2*F[{1}] + 3*F[{2}] + F[{1, 2}] - sage: i = A.In().an_element(); i + sage: i = A.In().an_element(); i # optional - sage.combinat sage.modules In[{}] + 2*In[{1}] + 3*In[{2}] + In[{1, 2}] - sage: o = A.Out().an_element(); o + sage: o = A.Out().an_element(); o # optional - sage.combinat sage.modules Out[{}] + 2*Out[{1}] + 3*Out[{2}] + Out[{1, 2}] - sage: f in A, i in A, o in A + sage: f in A, i in A, o in A # optional - sage.combinat sage.modules (True, True, True) """ return self.realizations() @@ -2970,9 +3008,9 @@ def super_categories(self): """ EXAMPLES:: - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field - sage: A.Realizations().super_categories() + sage: A.Realizations().super_categories() # optional - sage.combinat sage.modules [Category of realizations of sets] """ return [Sets().Realizations()] @@ -2983,9 +3021,9 @@ def _an_element_(self): EXAMPLES:: - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field - sage: A.an_element() # indirect doctest + sage: A.an_element() # indirect doctest # optional - sage.combinat sage.modules F[{}] + 2*F[{1}] + 3*F[{2}] + F[{1, 2}] TESTS: @@ -2993,9 +3031,9 @@ def _an_element_(self): Check that we are consistent no matter which basis is created first:: - sage: M = posets.BooleanLattice(4).moebius_algebra(QQ) - sage: I = M.I() - sage: M._an_element_() + sage: M = posets.BooleanLattice(4).moebius_algebra(QQ) # optional - sage.combinat sage.graphs sage.modules + sage: I = M.I() # optional - sage.combinat sage.graphs sage.modules + sage: M._an_element_() # optional - sage.combinat sage.graphs sage.modules 2*E[0] + 2*E[1] + 3*E[2] """ return self.a_realization().an_element() @@ -3008,19 +3046,19 @@ def __contains__(self, x): EXAMPLES:: - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field - sage: A.an_element() in A + sage: A.an_element() in A # optional - sage.combinat sage.modules True - sage: A.In().an_element() in A + sage: A.In().an_element() in A # optional - sage.combinat sage.modules True - sage: A.F().an_element() in A + sage: A.F().an_element() in A # optional - sage.combinat sage.modules True - sage: A.Out().an_element() in A + sage: A.Out().an_element() in A # optional - sage.combinat sage.modules True - sage: 1 in A + sage: 1 in A # optional - sage.combinat sage.modules True - sage: QQ['x'].an_element() in A + sage: QQ['x'].an_element() in A # optional - sage.combinat sage.modules False """ return any(x in realization for realization in self.realizations()) @@ -3035,8 +3073,8 @@ def __init_extra__(self): TESTS:: - sage: A = Sets().WithRealizations().example() - sage: A.realizations() # indirect doctest + sage: A = Sets().WithRealizations().example() # optional - sage.combinat sage.modules + sage: A.realizations() # indirect doctest # optional - sage.combinat sage.modules [The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis, The subset algebra of {1, 2, 3} over Rational Field in the In basis, The subset algebra of {1, 2, 3} over Rational Field in the Out basis] @@ -3050,11 +3088,11 @@ def realization_of(self): EXAMPLES:: - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field - sage: In = A.In(); In + sage: In = A.In(); In # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field in the In basis - sage: In.realization_of() + sage: In.realization_of() # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field """ for category in self.categories(): @@ -3070,11 +3108,11 @@ def _realization_name(self): EXAMPLES:: - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field - sage: In = A.In(); In + sage: In = A.In(); In # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field in the In basis - sage: In._realization_name() + sage: In._realization_name() # optional - sage.combinat sage.modules 'In' """ # The __base__ gets rid of the with_category @@ -3085,9 +3123,9 @@ def _repr_(self): """ EXAMPLES:: - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field - sage: In = A.In(); In + sage: In = A.In(); In # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field in the In basis In the example above, :meth:`repr` was overridden by @@ -3099,8 +3137,9 @@ def _repr_(self): sage: from sage.categories.realizations import Realizations sage: class Blah(Parent): ....: pass - sage: P = Blah(category = Sets.WithRealizations.ParentMethods.Realizations(A)) - sage: P # indirect doctest + sage: C = Sets.WithRealizations.ParentMethods.Realizations(A) # optional - sage.combinat sage.modules + sage: P = Blah(category=C) # optional - sage.combinat sage.modules + sage: P # indirect doctest # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field in the realization Blah """ return "{} in the realization {}".format(self.realization_of(), self._realization_name()) diff --git a/src/sage/categories/sets_with_grading.py b/src/sage/categories/sets_with_grading.py index 5d01bfab999..a9cc219e06e 100644 --- a/src/sage/categories/sets_with_grading.py +++ b/src/sage/categories/sets_with_grading.py @@ -161,9 +161,9 @@ def subset(self, *args, **options): EXAMPLES:: - sage: W = WeightedIntegerVectors([3,2,1]); W + sage: W = WeightedIntegerVectors([3,2,1]); W # optional - sage.combinat Integer vectors weighted by [3, 2, 1] - sage: W.subset(4) + sage: W.subset(4) # optional - sage.combinat Integer vectors of 4 weighted by [3, 2, 1] """ @@ -213,7 +213,7 @@ def generating_series(self): sage: N.generating_series() 1/(-z + 1) - sage: Permutations().generating_series() + sage: Permutations().generating_series() # optional - sage.combinat 1 + z + 2*z^2 + 6*z^3 + 24*z^4 + 120*z^5 + 720*z^6 + O(z^7) .. TODO:: diff --git a/src/sage/categories/simplicial_complexes.py b/src/sage/categories/simplicial_complexes.py index 0e35d866239..87c266858d8 100644 --- a/src/sage/categories/simplicial_complexes.py +++ b/src/sage/categories/simplicial_complexes.py @@ -67,8 +67,8 @@ def dimension(self): EXAMPLES:: - sage: S = SimplicialComplex([[1,3,4], [1,2],[2,5],[4,5]]) - sage: S.dimension() + sage: S = SimplicialComplex([[1,3,4], [1,2],[2,5],[4,5]]) # optional - sage.graphs + sage: S.dimension() # optional - sage.graphs 2 """ return max(c.dimension() for c in self.facets()) @@ -81,8 +81,8 @@ def facets(self): EXAMPLES:: - sage: S = SimplicialComplex([[1,3,4], [1,2],[2,5],[4,5]]) - sage: sorted(S.facets()) + sage: S = SimplicialComplex([[1,3,4], [1,2],[2,5],[4,5]]) # optional - sage.graphs + sage: sorted(S.facets()) # optional - sage.graphs [(1, 2), (1, 3, 4), (2, 5), (4, 5)] """ @@ -93,8 +93,8 @@ def faces(self): EXAMPLES:: - sage: S = SimplicialComplex([[1,3,4], [1,2],[2,5],[4,5]]) - sage: S.faces() + sage: S = SimplicialComplex([[1,3,4], [1,2],[2,5],[4,5]]) # optional - sage.graphs + sage: S.faces() # optional - sage.graphs {-1: {()}, 0: {(1,), (2,), (3,), (4,), (5,)}, 1: {(1, 2), (1, 3), (1, 4), (2, 5), (3, 4), (4, 5)}, diff --git a/src/sage/categories/simplicial_sets.py b/src/sage/categories/simplicial_sets.py index bcc7150186d..952053b907d 100644 --- a/src/sage/categories/simplicial_sets.py +++ b/src/sage/categories/simplicial_sets.py @@ -71,10 +71,10 @@ def is_finite(self): EXAMPLES:: - sage: simplicial_sets.Torus().is_finite() + sage: simplicial_sets.Torus().is_finite() # optional - sage.graphs True - sage: C5 = groups.misc.MultiplicativeAbelian([5]) - sage: simplicial_sets.ClassifyingSpace(C5).is_finite() + sage: C5 = groups.misc.MultiplicativeAbelian([5]) # optional - sage.graphs sage.groups + sage: simplicial_sets.ClassifyingSpace(C5).is_finite() # optional - sage.graphs sage.groups False """ return SimplicialSets.Finite() in self.categories() @@ -86,15 +86,15 @@ def is_pointed(self): EXAMPLES:: - sage: from sage.topology.simplicial_set import AbstractSimplex, SimplicialSet - sage: v = AbstractSimplex(0) - sage: w = AbstractSimplex(0) - sage: e = AbstractSimplex(1) - sage: X = SimplicialSet({e: (v, w)}) - sage: Y = SimplicialSet({e: (v, w)}, base_point=w) - sage: X.is_pointed() + sage: from sage.topology.simplicial_set import AbstractSimplex, SimplicialSet # optional - sage.graphs + sage: v = AbstractSimplex(0) # optional - sage.graphs + sage: w = AbstractSimplex(0) # optional - sage.graphs + sage: e = AbstractSimplex(1) # optional - sage.graphs + sage: X = SimplicialSet({e: (v, w)}) # optional - sage.graphs + sage: Y = SimplicialSet({e: (v, w)}, base_point=w) # optional - sage.graphs + sage: X.is_pointed() # optional - sage.graphs False - sage: Y.is_pointed() + sage: Y.is_pointed() # optional - sage.graphs True """ return SimplicialSets.Pointed() in self.categories() @@ -110,29 +110,29 @@ def set_base_point(self, point): EXAMPLES:: - sage: from sage.topology.simplicial_set import AbstractSimplex, SimplicialSet - sage: v = AbstractSimplex(0, name='v_0') - sage: w = AbstractSimplex(0, name='w_0') - sage: e = AbstractSimplex(1) - sage: X = SimplicialSet({e: (v, w)}) - sage: Y = SimplicialSet({e: (v, w)}, base_point=w) - sage: Y.base_point() + sage: from sage.topology.simplicial_set import AbstractSimplex, SimplicialSet # optional - sage.graphs + sage: v = AbstractSimplex(0, name='v_0') # optional - sage.graphs + sage: w = AbstractSimplex(0, name='w_0') # optional - sage.graphs + sage: e = AbstractSimplex(1) # optional - sage.graphs + sage: X = SimplicialSet({e: (v, w)}) # optional - sage.graphs + sage: Y = SimplicialSet({e: (v, w)}, base_point=w) # optional - sage.graphs + sage: Y.base_point() # optional - sage.graphs w_0 - sage: X_star = X.set_base_point(w) - sage: X_star.base_point() + sage: X_star = X.set_base_point(w) # optional - sage.graphs + sage: X_star.base_point() # optional - sage.graphs w_0 - sage: Y_star = Y.set_base_point(v) - sage: Y_star.base_point() + sage: Y_star = Y.set_base_point(v) # optional - sage.graphs + sage: Y_star.base_point() # optional - sage.graphs v_0 TESTS:: - sage: X.set_base_point(e) + sage: X.set_base_point(e) # optional - sage.graphs Traceback (most recent call last): ... ValueError: the "point" is not a zero-simplex - sage: pt = AbstractSimplex(0) - sage: X.set_base_point(pt) + sage: pt = AbstractSimplex(0) # optional - sage.graphs + sage: X.set_base_point(pt) # optional - sage.graphs Traceback (most recent call last): ... ValueError: the point is not a simplex in this simplicial set @@ -154,8 +154,8 @@ def one(self): EXAMPLES:: - sage: T = simplicial_sets.Torus() - sage: Hom(T, T).identity() + sage: T = simplicial_sets.Torus() # optional - sage.graphs + sage: Hom(T, T).identity() # optional - sage.graphs Simplicial set endomorphism of Torus Defn: Identity map """ @@ -197,13 +197,13 @@ def base_point(self): EXAMPLES:: - sage: from sage.topology.simplicial_set import AbstractSimplex, SimplicialSet - sage: v = AbstractSimplex(0, name='*') - sage: e = AbstractSimplex(1) - sage: S1 = SimplicialSet({e: (v, v)}, base_point=v) - sage: S1.is_pointed() + sage: from sage.topology.simplicial_set import AbstractSimplex, SimplicialSet # optional - sage.graphs + sage: v = AbstractSimplex(0, name='*') # optional - sage.graphs + sage: e = AbstractSimplex(1) # optional - sage.graphs + sage: S1 = SimplicialSet({e: (v, v)}, base_point=v) # optional - sage.graphs + sage: S1.is_pointed() # optional - sage.graphs True - sage: S1.base_point() + sage: S1.base_point() # optional - sage.graphs * """ return self._basepoint @@ -226,26 +226,26 @@ def base_point_map(self, domain=None): EXAMPLES:: - sage: T = simplicial_sets.Torus() - sage: f = T.base_point_map(); f + sage: T = simplicial_sets.Torus() # optional - sage.graphs + sage: f = T.base_point_map(); f # optional - sage.graphs Simplicial set morphism: From: Point To: Torus Defn: Constant map at (v_0, v_0) - sage: S3 = simplicial_sets.Sphere(3) - sage: g = S3.base_point_map() - sage: f.domain() == g.domain() + sage: S3 = simplicial_sets.Sphere(3) # optional - sage.graphs + sage: g = S3.base_point_map() # optional - sage.graphs + sage: f.domain() == g.domain() # optional - sage.graphs True - sage: RP3 = simplicial_sets.RealProjectiveSpace(3) - sage: temp = simplicial_sets.Simplex(0) - sage: pt = temp.set_base_point(temp.n_cells(0)[0]) - sage: h = RP3.base_point_map(domain=pt) - sage: f.domain() == h.domain() + sage: RP3 = simplicial_sets.RealProjectiveSpace(3) # optional - sage.graphs + sage: temp = simplicial_sets.Simplex(0) # optional - sage.graphs + sage: pt = temp.set_base_point(temp.n_cells(0)[0]) # optional - sage.graphs + sage: h = RP3.base_point_map(domain=pt) # optional - sage.graphs + sage: f.domain() == h.domain() # optional - sage.graphs False - sage: C5 = groups.misc.MultiplicativeAbelian([5]) - sage: BC5 = simplicial_sets.ClassifyingSpace(C5) - sage: BC5.base_point_map() + sage: C5 = groups.misc.MultiplicativeAbelian([5]) # optional - sage.graphs sage.groups + sage: BC5 = simplicial_sets.ClassifyingSpace(C5) # optional - sage.graphs sage.groups + sage: BC5.base_point_map() # optional - sage.graphs sage.groups Simplicial set morphism: From: Point To: Classifying space of Multiplicative Abelian group isomorphic to C5 @@ -285,49 +285,49 @@ def fundamental_group(self, simplify=True): EXAMPLES:: - sage: S1 = simplicial_sets.Sphere(1) - sage: eight = S1.wedge(S1) - sage: eight.fundamental_group() # free group on 2 generators + sage: S1 = simplicial_sets.Sphere(1) # optional - sage.graphs + sage: eight = S1.wedge(S1) # optional - sage.graphs + sage: eight.fundamental_group() # free group on 2 generators # optional - sage.graphs sage.groups Finitely presented group < e0, e1 | > The fundamental group of a disjoint union of course depends on the choice of base point:: - sage: T = simplicial_sets.Torus() - sage: K = simplicial_sets.KleinBottle() - sage: X = T.disjoint_union(K) + sage: T = simplicial_sets.Torus() # optional - sage.graphs + sage: K = simplicial_sets.KleinBottle() # optional - sage.graphs + sage: X = T.disjoint_union(K) # optional - sage.graphs - sage: X_0 = X.set_base_point(X.n_cells(0)[0]) - sage: X_0.fundamental_group().is_abelian() + sage: X_0 = X.set_base_point(X.n_cells(0)[0]) # optional - sage.graphs + sage: X_0.fundamental_group().is_abelian() # optional - sage.graphs sage.groups True - sage: X_1 = X.set_base_point(X.n_cells(0)[1]) - sage: X_1.fundamental_group().is_abelian() + sage: X_1 = X.set_base_point(X.n_cells(0)[1]) # optional - sage.graphs + sage: X_1.fundamental_group().is_abelian() # optional - sage.graphs sage.groups False - sage: RP3 = simplicial_sets.RealProjectiveSpace(3) - sage: RP3.fundamental_group() + sage: RP3 = simplicial_sets.RealProjectiveSpace(3) # optional - sage.graphs + sage: RP3.fundamental_group() # optional - sage.graphs sage.groups Finitely presented group < e | e^2 > Compute the fundamental group of some classifying spaces:: - sage: C5 = groups.misc.MultiplicativeAbelian([5]) - sage: BC5 = C5.nerve() - sage: BC5.fundamental_group() + sage: C5 = groups.misc.MultiplicativeAbelian([5]) # optional - sage.graphs sage.groups + sage: BC5 = C5.nerve() # optional - sage.graphs sage.groups + sage: BC5.fundamental_group() # optional - sage.graphs sage.groups Finitely presented group < e0 | e0^5 > - sage: Sigma3 = groups.permutation.Symmetric(3) - sage: BSigma3 = Sigma3.nerve() - sage: pi = BSigma3.fundamental_group(); pi + sage: Sigma3 = groups.permutation.Symmetric(3) # optional - sage.graphs sage.groups + sage: BSigma3 = Sigma3.nerve() # optional - sage.graphs sage.groups + sage: pi = BSigma3.fundamental_group(); pi # optional - sage.graphs sage.groups Finitely presented group < e1, e2 | e2^2, e1^3, (e2*e1)^2 > - sage: pi.order() + sage: pi.order() # optional - sage.graphs sage.groups 6 - sage: pi.is_abelian() + sage: pi.is_abelian() # optional - sage.graphs sage.groups False The sphere has a trivial fundamental group:: - sage: S2 = simplicial_sets.Sphere(2) - sage: S2.fundamental_group() + sage: S2 = simplicial_sets.Sphere(2) # optional - sage.graphs + sage: S2.fundamental_group() # optional - sage.graphs sage.groups Finitely presented group < | > """ # Import this here to prevent importing libgap upon startup. @@ -347,10 +347,10 @@ def _universal_cover_dict(self): TESTS:: - sage: RP2 = simplicial_sets.RealProjectiveSpace(2) - sage: RP2._universal_cover_dict() + sage: RP2 = simplicial_sets.RealProjectiveSpace(2) # optional - sage.groups + sage: RP2._universal_cover_dict() # optional - sage.groups (Finitely presented group < e | e^2 >, {f: e}) - sage: RP2.nondegenerate_simplices() + sage: RP2.nondegenerate_simplices() # optional - sage.groups [1, f, f * f] """ from sage.groups.free_group import FreeGroup @@ -393,14 +393,14 @@ def universal_cover_map(self): EXAMPLES:: - sage: RP2 = simplicial_sets.RealProjectiveSpace(2) - sage: phi = RP2.universal_cover_map() - sage: phi + sage: RP2 = simplicial_sets.RealProjectiveSpace(2) # optional - sage.groups + sage: phi = RP2.universal_cover_map(); phi # optional - sage.groups Simplicial set morphism: From: Simplicial set with 6 non-degenerate simplices To: RP^2 - Defn: [(1, 1), (1, e), (f, 1), (f, e), (f * f, 1), (f * f, e)] --> [1, 1, f, f, f * f, f * f] - sage: phi.domain().face_data() + Defn: [(1, 1), (1, e), (f, 1), (f, e), (f * f, 1), (f * f, e)] + --> [1, 1, f, f, f * f, f * f] + sage: phi.domain().face_data() # optional - sage.groups {(1, 1): None, (1, e): None, (f, 1): ((1, e), (1, 1)), @@ -432,18 +432,20 @@ def covering_map(self, character): EXAMPLES:: sage: S1 = simplicial_sets.Sphere(1) - sage: W = S1.wedge(S1) - sage: G = CyclicPermutationGroup(3) - sage: a, b = W.n_cells(1) - sage: C = W.covering_map({a : G.gen(0), b : G.one()}) - sage: C + sage: W = S1.wedge(S1) # optional - sage.graphs + sage: G = CyclicPermutationGroup(3) # optional - sage.groups + sage: a, b = W.n_cells(1) # optional - sage.graphs + sage: C = W.covering_map({a : G.gen(0), b : G.one()}); C # optional - sage.graphs sage.groups Simplicial set morphism: From: Simplicial set with 9 non-degenerate simplices To: Wedge: (S^1 v S^1) - Defn: [(*, ()), (*, (1,2,3)), (*, (1,3,2)), (sigma_1, ()), (sigma_1, ()), (sigma_1, (1,2,3)), (sigma_1, (1,2,3)), (sigma_1, (1,3,2)), (sigma_1, (1,3,2))] --> [*, *, *, sigma_1, sigma_1, sigma_1, sigma_1, sigma_1, sigma_1] - sage: C.domain() + Defn: [(*, ()), (*, (1,2,3)), (*, (1,3,2)), (sigma_1, ()), + (sigma_1, ()), (sigma_1, (1,2,3)), (sigma_1, (1,2,3)), + (sigma_1, (1,3,2)), (sigma_1, (1,3,2))] + --> [*, *, *, sigma_1, sigma_1, sigma_1, sigma_1, sigma_1, sigma_1] + sage: C.domain() # optional - sage.graphs sage.groups Simplicial set with 9 non-degenerate simplices - sage: C.domain().face_data() + sage: C.domain().face_data() # optional - sage.graphs sage.groups {(*, ()): None, (*, (1,2,3)): None, (*, (1,3,2)): None, @@ -517,11 +519,11 @@ def cover(self, character): EXAMPLES:: sage: S1 = simplicial_sets.Sphere(1) - sage: W = S1.wedge(S1) - sage: G = CyclicPermutationGroup(3) - sage: (a, b) = W.n_cells(1) - sage: C = W.cover({a : G.gen(0), b : G.gen(0)^2}) - sage: C.face_data() + sage: W = S1.wedge(S1) # optional - sage.graphs + sage: G = CyclicPermutationGroup(3) # optional - sage.groups + sage: (a, b) = W.n_cells(1) # optional - sage.graphs + sage: C = W.cover({a : G.gen(0), b : G.gen(0)^2}) # optional - sage.graphs sage.groups + sage: C.face_data() # optional - sage.graphs sage.groups {(*, ()): None, (*, (1,2,3)): None, (*, (1,3,2)): None, @@ -531,9 +533,9 @@ def cover(self, character): (sigma_1, (1,2,3)): ((*, ()), (*, (1,2,3))), (sigma_1, (1,3,2)): ((*, ()), (*, (1,3,2))), (sigma_1, (1,3,2)): ((*, (1,2,3)), (*, (1,3,2)))} - sage: C.homology(1) + sage: C.homology(1) # optional - sage.graphs sage.groups sage.modules Z x Z x Z x Z - sage: C.fundamental_group() + sage: C.fundamental_group() # optional - sage.graphs sage.groups Finitely presented group < e0, e1, e2, e3 | > """ return self.covering_map(character).domain() @@ -546,11 +548,10 @@ def universal_cover(self): EXAMPLES:: - sage: RP3 = simplicial_sets.RealProjectiveSpace(3) - sage: C = RP3.universal_cover() - sage: C + sage: RP3 = simplicial_sets.RealProjectiveSpace(3) # optional - sage.groups + sage: C = RP3.universal_cover(); C # optional - sage.groups Simplicial set with 8 non-degenerate simplices - sage: C.face_data() + sage: C.face_data() # optional - sage.groups {(1, 1): None, (1, e): None, (f, 1): ((1, e), (1, 1)), @@ -578,26 +579,26 @@ def is_simply_connected(self): EXAMPLES:: - sage: T = simplicial_sets.Torus() - sage: T.is_simply_connected() + sage: T = simplicial_sets.Torus() # optional - sage.graphs + sage: T.is_simply_connected() # optional - sage.graphs False - sage: T.suspension().is_simply_connected() + sage: T.suspension().is_simply_connected() # optional - sage.graphs True - sage: simplicial_sets.KleinBottle().is_simply_connected() + sage: simplicial_sets.KleinBottle().is_simply_connected() # optional - sage.graphs False - sage: S2 = simplicial_sets.Sphere(2) - sage: S3 = simplicial_sets.Sphere(3) - sage: (S2.wedge(S3)).is_simply_connected() + sage: S2 = simplicial_sets.Sphere(2) # optional - sage.graphs + sage: S3 = simplicial_sets.Sphere(3) # optional - sage.graphs + sage: (S2.wedge(S3)).is_simply_connected() # optional - sage.graphs True - sage: X = S2.disjoint_union(S3) - sage: X = X.set_base_point(X.n_cells(0)[0]) - sage: X.is_simply_connected() + sage: X = S2.disjoint_union(S3) # optional - sage.graphs + sage: X = X.set_base_point(X.n_cells(0)[0]) # optional - sage.graphs + sage: X.is_simply_connected() # optional - sage.graphs False - sage: C3 = groups.misc.MultiplicativeAbelian([3]) - sage: BC3 = simplicial_sets.ClassifyingSpace(C3) - sage: BC3.is_simply_connected() + sage: C3 = groups.misc.MultiplicativeAbelian([3]) # optional - sage.graphs sage.groups + sage: BC3 = simplicial_sets.ClassifyingSpace(C3) # optional - sage.graphs sage.groups + sage: BC3.is_simply_connected() # optional - sage.graphs sage.groups False """ if not self.is_connected(): @@ -641,21 +642,21 @@ def connectivity(self, max_dim=None): EXAMPLES:: - sage: simplicial_sets.Sphere(3).connectivity() + sage: simplicial_sets.Sphere(3).connectivity() # optional - sage.graphs 2 - sage: simplicial_sets.Sphere(0).connectivity() + sage: simplicial_sets.Sphere(0).connectivity() # optional - sage.graphs -1 - sage: K = simplicial_sets.Simplex(4) - sage: K = K.set_base_point(K.n_cells(0)[0]) - sage: K.connectivity() + sage: K = simplicial_sets.Simplex(4) # optional - sage.graphs + sage: K = K.set_base_point(K.n_cells(0)[0]) # optional - sage.graphs + sage: K.connectivity() # optional - sage.graphs +Infinity - sage: X = simplicial_sets.Torus().suspension(2) - sage: X.connectivity() + sage: X = simplicial_sets.Torus().suspension(2) # optional - sage.graphs + sage: X.connectivity() # optional - sage.graphs 2 - sage: C2 = groups.misc.MultiplicativeAbelian([2]) - sage: BC2 = simplicial_sets.ClassifyingSpace(C2) - sage: BC2.connectivity() + sage: C2 = groups.misc.MultiplicativeAbelian([2]) # optional - sage.graphs sage.groups + sage: BC2 = simplicial_sets.ClassifyingSpace(C2) # optional - sage.graphs sage.groups + sage: BC2.connectivity() # optional - sage.graphs sage.groups 0 """ if not self.is_connected(): @@ -689,17 +690,17 @@ def unset_base_point(self): EXAMPLES:: - sage: from sage.topology.simplicial_set import AbstractSimplex, SimplicialSet - sage: v = AbstractSimplex(0, name='v_0') - sage: w = AbstractSimplex(0, name='w_0') - sage: e = AbstractSimplex(1) - sage: Y = SimplicialSet({e: (v, w)}, base_point=w) - sage: Y.is_pointed() + sage: from sage.topology.simplicial_set import AbstractSimplex, SimplicialSet # optional - sage.graphs + sage: v = AbstractSimplex(0, name='v_0') # optional - sage.graphs + sage: w = AbstractSimplex(0, name='w_0') # optional - sage.graphs + sage: e = AbstractSimplex(1) # optional - sage.graphs + sage: Y = SimplicialSet({e: (v, w)}, base_point=w) # optional - sage.graphs + sage: Y.is_pointed() # optional - sage.graphs True - sage: Y.base_point() + sage: Y.base_point() # optional - sage.graphs w_0 - sage: Z = Y.unset_base_point() - sage: Z.is_pointed() + sage: Z = Y.unset_base_point() # optional - sage.graphs + sage: Z.is_pointed() # optional - sage.graphs False """ from sage.topology.simplicial_set import SimplicialSet @@ -718,14 +719,14 @@ def fat_wedge(self, n): EXAMPLES:: - sage: S1 = simplicial_sets.Sphere(1) - sage: S1.fat_wedge(0) + sage: S1 = simplicial_sets.Sphere(1) # optional - sage.graphs + sage: S1.fat_wedge(0) # optional - sage.graphs Point - sage: S1.fat_wedge(1) + sage: S1.fat_wedge(1) # optional - sage.graphs S^1 - sage: S1.fat_wedge(2).fundamental_group() + sage: S1.fat_wedge(2).fundamental_group() # optional - sage.graphs sage.groups Finitely presented group < e0, e1 | > - sage: S1.fat_wedge(4).homology() + sage: S1.fat_wedge(4).homology() # optional - sage.graphs sage.modules {0: 0, 1: Z x Z x Z x Z, 2: Z^6, 3: Z x Z x Z x Z} """ from sage.topology.simplicial_set_examples import Point @@ -745,18 +746,18 @@ def smash_product(self, *others): EXAMPLES:: - sage: S1 = simplicial_sets.Sphere(1) - sage: RP2 = simplicial_sets.RealProjectiveSpace(2) - sage: X = S1.smash_product(RP2) - sage: X.homology(base_ring=GF(2)) + sage: S1 = simplicial_sets.Sphere(1) # optional - sage.graphs + sage: RP2 = simplicial_sets.RealProjectiveSpace(2) # optional - sage.graphs + sage: X = S1.smash_product(RP2) # optional - sage.graphs + sage: X.homology(base_ring=GF(2)) # optional - sage.graphs sage.modules {0: Vector space of dimension 0 over Finite Field of size 2, 1: Vector space of dimension 0 over Finite Field of size 2, 2: Vector space of dimension 1 over Finite Field of size 2, 3: Vector space of dimension 1 over Finite Field of size 2} - sage: T = S1.product(S1) - sage: X = T.smash_product(S1) - sage: X.homology(reduced=False) + sage: T = S1.product(S1) # optional - sage.graphs + sage: X = T.smash_product(S1) # optional - sage.graphs + sage: X.homology(reduced=False) # optional - sage.graphs sage.modules {0: Z, 1: 0, 2: Z x Z, 3: Z} """ from sage.topology.simplicial_set_constructions import SmashProductOfSimplicialSets_finite diff --git a/src/sage/categories/super_algebras.py b/src/sage/categories/super_algebras.py index 77fe3a8982b..cad158f689a 100644 --- a/src/sage/categories/super_algebras.py +++ b/src/sage/categories/super_algebras.py @@ -76,22 +76,22 @@ def tensor(*parents, **kwargs): EXAMPLES:: - sage: A. = ExteriorAlgebra(ZZ); A.rename("A") - sage: T = A.tensor(A,A); T + sage: A. = ExteriorAlgebra(ZZ); A.rename("A") # optional - sage.combinat sage.modules + sage: T = A.tensor(A,A); T # optional - sage.combinat sage.modules A # A # A - sage: T in Algebras(ZZ).Graded().SignedTensorProducts() + sage: T in Algebras(ZZ).Graded().SignedTensorProducts() # optional - sage.combinat sage.modules True - sage: T in Algebras(ZZ).Graded().TensorProducts() + sage: T in Algebras(ZZ).Graded().TensorProducts() # optional - sage.combinat sage.modules False - sage: A.rename(None) + sage: A.rename(None) # optional - sage.combinat sage.modules This also works when the other elements do not have a signed tensor product (:trac:`31266`):: - sage: a = SteenrodAlgebra(3).an_element() - sage: M = CombinatorialFreeModule(GF(3), ['s', 't', 'u']) - sage: s = M.basis()['s'] - sage: tensor([a, s]) + sage: a = SteenrodAlgebra(3).an_element() # optional - sage.modules + sage: M = CombinatorialFreeModule(GF(3), ['s', 't', 'u']) # optional - sage.modules sage.rings.finite_rings + sage: s = M.basis()['s'] # optional - sage.modules sage.rings.finite_rings + sage: tensor([a, s]) # optional - sage.modules sage.rings.finite_rings 2*Q_1 Q_3 P(2,1) # B['s'] """ constructor = kwargs.pop('constructor', tensor_signed) diff --git a/src/sage/categories/super_algebras_with_basis.py b/src/sage/categories/super_algebras_with_basis.py index 2cee5d8ad87..affa3386377 100644 --- a/src/sage/categories/super_algebras_with_basis.py +++ b/src/sage/categories/super_algebras_with_basis.py @@ -52,8 +52,8 @@ def graded_algebra(self): EXAMPLES:: - sage: W. = algebras.DifferentialWeyl(QQ) - sage: W.graded_algebra() + sage: W. = algebras.DifferentialWeyl(QQ) # optional - sage.combinat sage.modules + sage: W.graded_algebra() # optional - sage.combinat sage.modules Graded Algebra of Differential Weyl algebra of polynomials in x, y over Rational Field """ @@ -76,27 +76,27 @@ def supercommutator(self, x): EXAMPLES:: - sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) - sage: Cl. = CliffordAlgebra(Q) - sage: a = x*y - z - sage: b = x - y + y*z - sage: a.supercommutator(b) + sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6]) # optional - sage.modules + sage: Cl. = CliffordAlgebra(Q) # optional - sage.combinat sage.modules + sage: a = x*y - z # optional - sage.combinat sage.modules + sage: b = x - y + y*z # optional - sage.combinat sage.modules + sage: a.supercommutator(b) # optional - sage.combinat sage.modules -5*x*y + 8*x*z - 2*y*z - 6*x + 12*y - 5*z - sage: a.supercommutator(Cl.one()) + sage: a.supercommutator(Cl.one()) # optional - sage.combinat sage.modules 0 - sage: Cl.one().supercommutator(a) + sage: Cl.one().supercommutator(a) # optional - sage.combinat sage.modules 0 - sage: Cl.zero().supercommutator(a) + sage: Cl.zero().supercommutator(a) # optional - sage.combinat sage.modules 0 - sage: a.supercommutator(Cl.zero()) + sage: a.supercommutator(Cl.zero()) # optional - sage.combinat sage.modules 0 - sage: Q = QuadraticForm(ZZ, 2, [-1,1,-3]) - sage: Cl. = CliffordAlgebra(Q) - sage: [a.supercommutator(b) for a in Cl.basis() for b in Cl.basis()] + sage: Q = QuadraticForm(ZZ, 2, [-1,1,-3]) # optional - sage.modules + sage: Cl. = CliffordAlgebra(Q) # optional - sage.combinat sage.modules + sage: [a.supercommutator(b) for a in Cl.basis() for b in Cl.basis()] # optional - sage.combinat sage.modules [0, 0, 0, 0, 0, -2, 1, -x - 2*y, 0, 1, -6, 6*x + y, 0, x + 2*y, -6*x - y, 0] - sage: [a*b-b*a for a in Cl.basis() for b in Cl.basis()] + sage: [a*b-b*a for a in Cl.basis() for b in Cl.basis()] # optional - sage.combinat sage.modules [0, 0, 0, 0, 0, 0, 2*x*y - 1, -x - 2*y, 0, -2*x*y + 1, 0, 6*x + y, 0, x + 2*y, -6*x - y, 0] @@ -104,8 +104,8 @@ def supercommutator(self, x): supercommutators work as well. We verify the exterior algebra is supercommutative:: - sage: E. = ExteriorAlgebra(QQ) - sage: all(b1.supercommutator(b2) == 0 + sage: E. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: all(b1.supercommutator(b2) == 0 # optional - sage.combinat sage.modules ....: for b1 in E.basis() for b2 in E.basis()) True """ diff --git a/src/sage/categories/super_hopf_algebras_with_basis.py b/src/sage/categories/super_hopf_algebras_with_basis.py index 4fd09867b45..e8974390ba5 100644 --- a/src/sage/categories/super_hopf_algebras_with_basis.py +++ b/src/sage/categories/super_hopf_algebras_with_basis.py @@ -42,15 +42,15 @@ def antipode(self): EXAMPLES:: - sage: A = SteenrodAlgebra(7) - sage: a = A.an_element() - sage: a, A.antipode(a) + sage: A = SteenrodAlgebra(7) # optional - sage.combinat sage.modules + sage: a = A.an_element() # optional - sage.combinat sage.modules + sage: a, A.antipode(a) # optional - sage.combinat sage.modules (6 Q_1 Q_3 P(2,1), Q_1 Q_3 P(2,1)) TESTS:: - sage: E. = ExteriorAlgebra(QQ) - sage: [b.antipode() for b in E.basis()] + sage: E. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: [b.antipode() for b in E.basis()] # optional - sage.combinat sage.modules [1, -x, -y, x*y] """ if self.antipode_on_basis is not NotImplemented: @@ -88,8 +88,8 @@ def _test_antipode(self, **options): TESTS:: - sage: A = SteenrodAlgebra(7) - sage: A._test_antipode() # long time + sage: A = SteenrodAlgebra(7) # optional - sage.combinat sage.modules + sage: A._test_antipode() # long time # optional - sage.combinat sage.modules """ tester = self._tester(**options) diff --git a/src/sage/categories/super_lie_conformal_algebras.py b/src/sage/categories/super_lie_conformal_algebras.py index 849a0fbdb13..82a11f5f2cc 100644 --- a/src/sage/categories/super_lie_conformal_algebras.py +++ b/src/sage/categories/super_lie_conformal_algebras.py @@ -27,16 +27,16 @@ class SuperLieConformalAlgebras(SuperModulesCategory): EXAMPLES:: - sage: LieConformalAlgebras(AA).Super() + sage: LieConformalAlgebras(AA).Super() # optional - sage.rings.number_field Category of super Lie conformal algebras over Algebraic Real Field Notice that we can force to have a *purely even* super Lie conformal algebra:: - sage: bosondict = {('a','a'):{1:{('K',0):1}}} - sage: R = LieConformalAlgebra(QQ,bosondict,names=('a',), + sage: bosondict = {('a','a'): {1:{('K',0):1}}} + sage: R = LieConformalAlgebra(QQ, bosondict, names=('a',), # optional - sage.combinat sage.modules ....: central_elements=('K',), super=True) - sage: [g.is_even_odd() for g in R.gens()] + sage: [g.is_even_odd() for g in R.gens()] # optional - sage.combinat sage.modules [0, 0] """ def extra_super_categories(self): @@ -57,7 +57,7 @@ def example(self): EXAMPLES:: - sage: LieConformalAlgebras(QQ).Super().example() + sage: LieConformalAlgebras(QQ).Super().example() # optional - sage.combinat sage.modules The Neveu-Schwarz super Lie conformal algebra over Rational Field """ from sage.algebras.lie_conformal_algebras.neveu_schwarz_lie_conformal_algebra\ @@ -79,32 +79,33 @@ def _test_jacobi(self, **options): By default, this method tests only the elements returned by ``self.some_elements()``:: - sage: V = lie_conformal_algebras.Affine(QQ, 'B2') - sage: V._test_jacobi() # long time (6 seconds) + sage: V = lie_conformal_algebras.Affine(QQ, 'B2') # optional - sage.combinat sage.modules + sage: V._test_jacobi() # long time (6 seconds) # optional - sage.combinat sage.modules It works for super Lie conformal algebras too:: - sage: V = lie_conformal_algebras.NeveuSchwarz(QQ) - sage: V._test_jacobi() + sage: V = lie_conformal_algebras.NeveuSchwarz(QQ) # optional - sage.combinat sage.modules + sage: V._test_jacobi() # optional - sage.combinat sage.modules We can use specific elements by passing the ``elements`` keyword argument:: - sage: V = lie_conformal_algebras.Affine(QQ, 'A1', names=('e', 'h', 'f')) - sage: V.inject_variables() + sage: V = lie_conformal_algebras.Affine(QQ, 'A1', # optional - sage.combinat sage.modules + ....: names=('e', 'h', 'f')) + sage: V.inject_variables() # optional - sage.combinat sage.modules Defining e, h, f, K - sage: V._test_jacobi(elements=(e, 2*f+h, 3*h)) + sage: V._test_jacobi(elements=(e, 2*f + h, 3*h)) # optional - sage.combinat sage.modules TESTS:: - sage: wrongdict = {('a', 'a'): {0: {('b', 0): 1}}, ('b', 'a'): {0: {('a', 0): 1}}} - sage: V = LieConformalAlgebra(QQ, wrongdict, names=('a', 'b'), parity=(1, 0)) - sage: V._test_jacobi() + sage: wrongdict = {('a', 'a'): {0: {('b', 0): 1}}, + ....: ('b', 'a'): {0: {('a', 0): 1}}} + sage: V = LieConformalAlgebra(QQ, wrongdict, # optional - sage.combinat sage.modules + ....: names=('a', 'b'), parity=(1, 0)) + sage: V._test_jacobi() # optional - sage.combinat sage.modules Traceback (most recent call last): ... - AssertionError: {(0, 0): -3*a} != {} - - {(0, 0): -3*a} - + {} + AssertionError: {(0, 0): -3*a} != {} - {(0, 0): -3*a} + {} """ tester = self._tester(**options) S = tester.some_elements() @@ -162,10 +163,10 @@ def is_even_odd(self): EXAMPLES:: - sage: R = lie_conformal_algebras.NeveuSchwarz(QQ); - sage: R.inject_variables() + sage: R = lie_conformal_algebras.NeveuSchwarz(QQ) # optional - sage.combinat sage.modules + sage: R.inject_variables() # optional - sage.combinat sage.modules Defining L, G, C - sage: G.is_even_odd() + sage: G.is_even_odd() # optional - sage.combinat sage.modules 1 """ @@ -175,7 +176,7 @@ class Graded(GradedModulesCategory): EXAMPLES:: - sage: LieConformalAlgebras(AA).Super().Graded() + sage: LieConformalAlgebras(AA).Super().Graded() # optional - sage.rings.number_field Category of H-graded super Lie conformal algebras over Algebraic Real Field """ def _repr_object_names(self): @@ -184,7 +185,7 @@ def _repr_object_names(self): EXAMPLES:: - sage: LieConformalAlgebras(QQbar).Graded() + sage: LieConformalAlgebras(QQbar).Graded() # optional - sage.rings.number_field Category of H-graded Lie conformal algebras over Algebraic Field """ return "H-graded {}".format(self.base_category()._repr_object_names()) diff --git a/src/sage/categories/super_modules.py b/src/sage/categories/super_modules.py index 091b808408e..2efd5f6e7e2 100644 --- a/src/sage/categories/super_modules.py +++ b/src/sage/categories/super_modules.py @@ -45,7 +45,7 @@ def default_super_categories(cls, category, *args): EXAMPLES:: - sage: HopfAlgebras(ZZ).WithBasis().FiniteDimensional().Super() # indirect doctest + sage: HopfAlgebras(ZZ).WithBasis().FiniteDimensional().Super() # indirect doctest Category of finite dimensional super hopf algebras with basis over Integer Ring """ axioms = axiom_whitelist.intersection(category.axioms()) @@ -183,11 +183,11 @@ def is_even_odd(self): EXAMPLES:: sage: cat = Algebras(QQ).WithBasis().Super() - sage: C = CombinatorialFreeModule(QQ, Partitions(), category=cat) - sage: C.degree_on_basis = sum - sage: C.basis()[2,2,1].is_even_odd() + sage: C = CombinatorialFreeModule(QQ, Partitions(), category=cat) # optional - sage.combinat sage.modules + sage: C.degree_on_basis = sum # optional - sage.combinat sage.modules + sage: C.basis()[2,2,1].is_even_odd() # optional - sage.combinat sage.modules 1 - sage: C.basis()[2,2].is_even_odd() + sage: C.basis()[2,2].is_even_odd() # optional - sage.combinat sage.modules 0 """ return self.degree() % 2 @@ -199,11 +199,11 @@ def is_even(self): EXAMPLES:: sage: cat = Algebras(QQ).WithBasis().Super() - sage: C = CombinatorialFreeModule(QQ, Partitions(), category=cat) - sage: C.degree_on_basis = sum - sage: C.basis()[2,2,1].is_even() + sage: C = CombinatorialFreeModule(QQ, Partitions(), category=cat) # optional - sage.combinat sage.modules + sage: C.degree_on_basis = sum # optional - sage.combinat sage.modules + sage: C.basis()[2,2,1].is_even() # optional - sage.combinat sage.modules False - sage: C.basis()[2,2].is_even() + sage: C.basis()[2,2].is_even() # optional - sage.combinat sage.modules True """ return self.is_even_odd() == 0 @@ -215,11 +215,11 @@ def is_odd(self): EXAMPLES:: sage: cat = Algebras(QQ).WithBasis().Super() - sage: C = CombinatorialFreeModule(QQ, Partitions(), category=cat) - sage: C.degree_on_basis = sum - sage: C.basis()[2,2,1].is_odd() + sage: C = CombinatorialFreeModule(QQ, Partitions(), category=cat) # optional - sage.combinat sage.modules + sage: C.degree_on_basis = sum # optional - sage.combinat sage.modules + sage: C.basis()[2,2,1].is_odd() # optional - sage.combinat sage.modules True - sage: C.basis()[2,2].is_odd() + sage: C.basis()[2,2].is_odd() # optional - sage.combinat sage.modules False """ return self.is_even_odd() == 1 diff --git a/src/sage/categories/super_modules_with_basis.py b/src/sage/categories/super_modules_with_basis.py index 7317d42f95c..dff6b54fbe2 100644 --- a/src/sage/categories/super_modules_with_basis.py +++ b/src/sage/categories/super_modules_with_basis.py @@ -53,11 +53,11 @@ def _even_odd_on_basis(self, m): EXAMPLES:: - sage: Q = QuadraticForm(QQ, 2, [1,2,3]) - sage: C. = CliffordAlgebra(Q) - sage: C._even_odd_on_basis((0,)) + sage: Q = QuadraticForm(QQ, 2, [1,2,3]) # optional - sage.modules + sage: C. = CliffordAlgebra(Q) # optional - sage.combinat sage.modules + sage: C._even_odd_on_basis((0,)) # optional - sage.combinat sage.modules 1 - sage: C._even_odd_on_basis((0,1)) + sage: C._even_odd_on_basis((0,1)) # optional - sage.combinat sage.modules 0 """ return self.degree_on_basis(m) % 2 @@ -70,27 +70,27 @@ def is_super_homogeneous(self): EXAMPLES:: - sage: Q = QuadraticForm(QQ, 2, [1,2,3]) - sage: C. = CliffordAlgebra(Q) - sage: a = x + y - sage: a.is_super_homogeneous() + sage: Q = QuadraticForm(QQ, 2, [1,2,3]) # optional - sage.modules + sage: C. = CliffordAlgebra(Q) # optional - sage.combinat sage.modules + sage: a = x + y # optional - sage.combinat sage.modules + sage: a.is_super_homogeneous() # optional - sage.combinat sage.modules True - sage: a = x*y + 4 - sage: a.is_super_homogeneous() + sage: a = x*y + 4 # optional - sage.combinat sage.modules + sage: a.is_super_homogeneous() # optional - sage.combinat sage.modules True - sage: a = x*y + x - 3*y + 4 - sage: a.is_super_homogeneous() + sage: a = x*y + x - 3*y + 4 # optional - sage.combinat sage.modules + sage: a.is_super_homogeneous() # optional - sage.combinat sage.modules False The exterior algebra has a `\ZZ` grading, which induces the `\ZZ / 2\ZZ` grading. However the definition of homogeneous elements differs because of the different gradings:: - sage: E. = ExteriorAlgebra(QQ) - sage: a = x*y + 4 - sage: a.is_super_homogeneous() + sage: E. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: a = x*y + 4 # optional - sage.combinat sage.modules + sage: a.is_super_homogeneous() # optional - sage.combinat sage.modules True - sage: a.is_homogeneous() + sage: a.is_homogeneous() # optional - sage.combinat sage.modules False """ even_odd = self.parent()._even_odd_on_basis @@ -110,22 +110,22 @@ def is_even_odd(self): EXAMPLES:: - sage: Q = QuadraticForm(QQ, 2, [1,2,3]) - sage: C. = CliffordAlgebra(Q) - sage: a = x + y - sage: a.is_even_odd() + sage: Q = QuadraticForm(QQ, 2, [1,2,3]) # optional - sage.modules + sage: C. = CliffordAlgebra(Q) # optional - sage.combinat sage.modules + sage: a = x + y # optional - sage.combinat sage.modules + sage: a.is_even_odd() # optional - sage.combinat sage.modules 1 - sage: a = x*y + 4 - sage: a.is_even_odd() + sage: a = x*y + 4 # optional - sage.combinat sage.modules + sage: a.is_even_odd() # optional - sage.combinat sage.modules 0 - sage: a = x + 4 - sage: a.is_even_odd() + sage: a = x + 4 # optional - sage.combinat sage.modules + sage: a.is_even_odd() # optional - sage.combinat sage.modules Traceback (most recent call last): ... ValueError: element is not homogeneous - sage: E. = ExteriorAlgebra(QQ) - sage: (x*y).is_even_odd() + sage: E. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: (x*y).is_even_odd() # optional - sage.combinat sage.modules 0 """ if not self.support(): @@ -140,18 +140,18 @@ def even_component(self): EXAMPLES:: - sage: Q = QuadraticForm(QQ, 2, [1,2,3]) - sage: C. = CliffordAlgebra(Q) - sage: a = x*y + x - 3*y + 4 - sage: a.even_component() + sage: Q = QuadraticForm(QQ, 2, [1,2,3]) # optional - sage.modules + sage: C. = CliffordAlgebra(Q) # optional - sage.combinat sage.modules + sage: a = x*y + x - 3*y + 4 # optional - sage.combinat sage.modules + sage: a.even_component() # optional - sage.combinat sage.modules x*y + 4 TESTS: Check that this really return ``A.zero()`` and not a plain ``0``:: - sage: a = x + y - sage: a.even_component().parent() is C + sage: a = x + y # optional - sage.combinat sage.modules + sage: a.even_component().parent() is C # optional - sage.combinat sage.modules True """ even_odd = self.parent()._even_odd_on_basis @@ -165,18 +165,18 @@ def odd_component(self): EXAMPLES:: - sage: Q = QuadraticForm(QQ, 2, [1,2,3]) - sage: C. = CliffordAlgebra(Q) - sage: a = x*y + x - 3*y + 4 - sage: a.odd_component() + sage: Q = QuadraticForm(QQ, 2, [1,2,3]) # optional - sage.modules + sage: C. = CliffordAlgebra(Q) # optional - sage.combinat sage.modules + sage: a = x*y + x - 3*y + 4 # optional - sage.combinat sage.modules + sage: a.odd_component() # optional - sage.combinat sage.modules x - 3*y TESTS: Check that this really return ``A.zero()`` and not a plain ``0``:: - sage: a = x*y - sage: a.odd_component().parent() is C + sage: a = x*y # optional - sage.combinat sage.modules + sage: a.odd_component().parent() is C # optional - sage.combinat sage.modules True """ even_odd = self.parent()._even_odd_on_basis diff --git a/src/sage/categories/supercommutative_algebras.py b/src/sage/categories/supercommutative_algebras.py index 4cd44e849c9..9cb2f609a8c 100644 --- a/src/sage/categories/supercommutative_algebras.py +++ b/src/sage/categories/supercommutative_algebras.py @@ -73,15 +73,15 @@ def _test_supercommutativity(self, **options): By default, this method tests only the elements returned by ``self.some_elements()``:: - sage: E. = ExteriorAlgebra(QQ) - sage: E._test_supercommutativity() + sage: E. = ExteriorAlgebra(QQ) # optional - sage.combinat sage.modules + sage: E._test_supercommutativity() # optional - sage.combinat sage.modules However, the elements tested can be customized with the ``elements`` keyword argument, but the elements must be homogeneous:: - sage: E._test_supercommutativity(elements=[x+y, x*y-3*y*z, x*y*z]) - sage: E._test_supercommutativity(elements=[x+x*y]) + sage: E._test_supercommutativity(elements=[x+y, x*y-3*y*z, x*y*z]) # optional - sage.combinat sage.modules + sage: E._test_supercommutativity(elements=[x+x*y]) # optional - sage.combinat sage.modules Traceback (most recent call last): ... ValueError: element is not homogeneous diff --git a/src/sage/categories/supercrystals.py b/src/sage/categories/supercrystals.py index 1e15c935599..a68c1d7c591 100644 --- a/src/sage/categories/supercrystals.py +++ b/src/sage/categories/supercrystals.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.graphs sage.combinat r""" Supercrystals """ @@ -42,11 +43,13 @@ def tensor(self, *crystals, **options): sage: B = crystals.Letters(['A',[1,2]]) sage: C = crystals.Tableaux(['A',[1,2]], shape = [2,1]) sage: T = C.tensor(B); T - Full tensor product of the crystals [Crystal of BKK tableaux of shape [2, 1] of gl(2|3), - The crystal of letters for type ['A', [1, 2]]] + Full tensor product of the crystals + [Crystal of BKK tableaux of shape [2, 1] of gl(2|3), + The crystal of letters for type ['A', [1, 2]]] sage: S = B.tensor(C); S - Full tensor product of the crystals [The crystal of letters for type ['A', [1, 2]], - Crystal of BKK tableaux of shape [2, 1] of gl(2|3)] + Full tensor product of the crystals + [The crystal of letters for type ['A', [1, 2]], + Crystal of BKK tableaux of shape [2, 1] of gl(2|3)] sage: G = T.digraph() sage: H = S.digraph() sage: G.is_isomorphic(H, edge_labels= True) diff --git a/src/sage/categories/triangular_kac_moody_algebras.py b/src/sage/categories/triangular_kac_moody_algebras.py index 95c7881043f..434ff22c1c7 100644 --- a/src/sage/categories/triangular_kac_moody_algebras.py +++ b/src/sage/categories/triangular_kac_moody_algebras.py @@ -60,10 +60,10 @@ def _part_on_basis(self, m): EXAMPLES:: - sage: L = lie_algebras.so(QQ, 5) - sage: L.f() + sage: L = lie_algebras.so(QQ, 5) # optional - sage.combinat sage.modules + sage: L.f() # optional - sage.combinat sage.modules Finite family {1: E[-alpha[1]], 2: E[-alpha[2]]} - sage: L.f(1) + sage: L.f(1) # optional - sage.combinat sage.modules E[-alpha[1]] """ deg = self.degree_on_basis(m) @@ -100,8 +100,8 @@ def _part_generators(self, positive=False): EXAMPLES:: - sage: L = LieAlgebra(QQ, cartan_type=['E',6]) - sage: list(L._part_generators(False)) + sage: L = LieAlgebra(QQ, cartan_type=['E', 6]) # optional - sage.combinat sage.modules + sage: list(L._part_generators(False)) # optional - sage.combinat sage.modules [E[-alpha[1]], E[-alpha[2]], E[-alpha[3]], E[-alpha[4]], E[-alpha[5]], E[-alpha[6]]] """ @@ -128,10 +128,10 @@ def e(self, i=None): EXAMPLES:: - sage: L = lie_algebras.so(QQ, 5) - sage: L.e() + sage: L = lie_algebras.so(QQ, 5) # optional - sage.combinat sage.modules + sage: L.e() # optional - sage.combinat sage.modules Finite family {1: E[alpha[1]], 2: E[alpha[2]]} - sage: L.e(1) + sage: L.e(1) # optional - sage.combinat sage.modules E[alpha[1]] """ E = self._part_generators(True) @@ -150,10 +150,10 @@ def f(self, i=None): EXAMPLES:: - sage: L = lie_algebras.so(QQ, 5) - sage: L.f() + sage: L = lie_algebras.so(QQ, 5) # optional - sage.combinat sage.modules + sage: L.f() # optional - sage.combinat sage.modules Finite family {1: E[-alpha[1]], 2: E[-alpha[2]]} - sage: L.f(1) + sage: L.f(1) # optional - sage.combinat sage.modules E[-alpha[1]] """ F = self._part_generators(False) @@ -168,8 +168,8 @@ def _negative_half_index_set(self): EXAMPLES:: - sage: L = lie_algebras.so(QQ, 5) - sage: L._negative_half_index_set() + sage: L = lie_algebras.so(QQ, 5) # optional - sage.combinat sage.modules + sage: L._negative_half_index_set() # optional - sage.combinat sage.modules [-alpha[2], -alpha[1], -alpha[1] - alpha[2], -alpha[1] - 2*alpha[2]] """ @@ -186,15 +186,15 @@ def _weight_action(self, m, wt): EXAMPLES:: - sage: L = lie_algebras.sp(QQ, 6) - sage: La = L.cartan_type().root_system().weight_space().fundamental_weights() - sage: mu = La[1] - 3/5*La[2] - sage: ac = L.cartan_type().root_system().coroot_lattice().simple_roots() - sage: L._weight_action(ac[1], mu) + sage: L = lie_algebras.sp(QQ, 6) # optional - sage.combinat sage.modules + sage: La = L.cartan_type().root_system().weight_space().fundamental_weights() # optional - sage.combinat sage.modules + sage: mu = La[1] - 3/5*La[2] # optional - sage.combinat sage.modules + sage: ac = L.cartan_type().root_system().coroot_lattice().simple_roots() # optional - sage.combinat sage.modules + sage: L._weight_action(ac[1], mu) # optional - sage.combinat sage.modules 1 - sage: L._weight_action(ac[2], mu) + sage: L._weight_action(ac[2], mu) # optional - sage.combinat sage.modules -3/5 - sage: L._weight_action(ac[3], mu) + sage: L._weight_action(ac[3], mu) # optional - sage.combinat sage.modules 0 """ @@ -210,11 +210,11 @@ def verma_module(self, la, basis_key=None, **kwds): EXAMPLES:: - sage: L = lie_algebras.sl(QQ, 3) - sage: P = L.cartan_type().root_system().weight_lattice() - sage: La = P.fundamental_weights() - sage: M = L.verma_module(La[1]+La[2]) - sage: M + sage: L = lie_algebras.sl(QQ, 3) # optional - sage.combinat sage.modules + sage: P = L.cartan_type().root_system().weight_lattice() # optional - sage.combinat sage.modules + sage: La = P.fundamental_weights() # optional - sage.combinat sage.modules + sage: M = L.verma_module(La[1] + La[2]) # optional - sage.combinat sage.modules + sage: M # optional - sage.combinat sage.modules Verma module with highest weight Lambda[1] + Lambda[2] of Lie algebra of ['A', 2] in the Chevalley basis """ @@ -234,18 +234,18 @@ def part(self): EXAMPLES:: - sage: L = LieAlgebra(QQ, cartan_type="F4") - sage: L.inject_variables() + sage: L = LieAlgebra(QQ, cartan_type="F4") # optional - sage.combinat sage.modules + sage: L.inject_variables() # optional - sage.combinat sage.modules Defining e1, e2, e3, e4, f1, f2, f3, f4, h1, h2, h3, h4 - sage: e1.part() + sage: e1.part() # optional - sage.combinat sage.modules 1 - sage: f4.part() + sage: f4.part() # optional - sage.combinat sage.modules -1 - sage: (h2 + h3).part() + sage: (h2 + h3).part() # optional - sage.combinat sage.modules 0 - sage: (f1.bracket(f2) + 4*f4).part() + sage: (f1.bracket(f2) + 4*f4).part() # optional - sage.combinat sage.modules -1 - sage: (e1 + f1).part() + sage: (e1 + f1).part() # optional - sage.combinat sage.modules Traceback (most recent call last): ... ValueError: element is not in one part diff --git a/src/sage/categories/unique_factorization_domains.py b/src/sage/categories/unique_factorization_domains.py index 280320474d8..f3d6b565316 100644 --- a/src/sage/categories/unique_factorization_domains.py +++ b/src/sage/categories/unique_factorization_domains.py @@ -65,7 +65,7 @@ def __contains__(self, x): """ EXAMPLES:: - sage: GF(4, "a") in UniqueFactorizationDomains() + sage: GF(4, "a") in UniqueFactorizationDomains() # optional - sage.rings.finite_rings True sage: QQ in UniqueFactorizationDomains() True @@ -123,7 +123,8 @@ def is_unique_factorization_domain(self, proof=True): EXAMPLES:: - sage: Parent(QQ,category=UniqueFactorizationDomains()).is_unique_factorization_domain() + sage: UFD = UniqueFactorizationDomains() + sage: Parent(QQ, category=UFD).is_unique_factorization_domain() True """ @@ -154,16 +155,17 @@ def _gcd_univariate_polynomial(self, f, g): sage: q = (-x^2 - 4*x - 5)*T^2 + (6*x^2 + x + 1)*T + 2*x^2 - x sage: quo,rem=p.pseudo_quo_rem(q); quo,rem ((3*x^4 + 13*x^3 + 19*x^2 + 5*x)*T + 18*x^4 + 12*x^3 + 16*x^2 + 16*x, - (-113*x^6 - 106*x^5 - 133*x^4 - 101*x^3 - 42*x^2 - 41*x)*T - 34*x^6 + 13*x^5 + 54*x^4 + 126*x^3 + 134*x^2 - 5*x - 50) + (-113*x^6 - 106*x^5 - 133*x^4 - 101*x^3 - 42*x^2 - 41*x)*T + - 34*x^6 + 13*x^5 + 54*x^4 + 126*x^3 + 134*x^2 - 5*x - 50) sage: (-x^2 - 4*x - 5)^(3-2+1) * p == quo*q + rem True Check that :trac:`23620` has been resolved:: - sage: R. = ZpFM(2)[] - sage: f = 2*x + 2 - sage: g = 4*x + 2 - sage: f.gcd(g).parent() is R + sage: R. = ZpFM(2)[] # optional - sage.rings.padics + sage: f = 2*x + 2 # optional - sage.rings.padics + sage: g = 4*x + 2 # optional - sage.rings.padics + sage: f.gcd(g).parent() is R # optional - sage.rings.padics True """ diff --git a/src/sage/categories/unital_algebras.py b/src/sage/categories/unital_algebras.py index d245b4de8c1..388a6e940a7 100644 --- a/src/sage/categories/unital_algebras.py +++ b/src/sage/categories/unital_algebras.py @@ -61,9 +61,10 @@ def from_base_ring(self, r): EXAMPLES:: - sage: A = AlgebrasWithBasis(QQ).example(); A - An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field - sage: A.from_base_ring(1) + sage: A = AlgebrasWithBasis(QQ).example(); A # optional - sage.combinat sage.modules + An example of an algebra with basis: + the free algebra on the generators ('a', 'b', 'c') over Rational Field + sage: A.from_base_ring(1) # optional - sage.combinat sage.modules B[word: ] """ return self.one()._lmul_(r) @@ -75,16 +76,18 @@ def __init_extra__(self): EXAMPLES:: - sage: A = AlgebrasWithBasis(QQ).example(); A - An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field + sage: A = AlgebrasWithBasis(QQ).example(); A # optional - sage.combinat sage.modules + An example of an algebra with basis: + the free algebra on the generators ('a', 'b', 'c') over Rational Field sage: coercion_model = sage.structure.element.get_coercion_model() - sage: coercion_model.discover_coercion(QQ, A) + sage: coercion_model.discover_coercion(QQ, A) # optional - sage.combinat sage.modules ((map internal to coercion system -- copy before use) Generic morphism: From: Rational Field - To: An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field, + To: An example of an algebra with basis: + the free algebra on the generators ('a', 'b', 'c') over Rational Field, None) - sage: A(1) # indirect doctest + sage: A(1) # indirect doctest # optional - sage.combinat sage.modules B[word: ] TESTS: @@ -92,16 +95,15 @@ def __init_extra__(self): Ensure that :trac:`28328` is fixed and that non-associative algebras are supported:: - sage: class Foo(CombinatorialFreeModule): + sage: class Foo(CombinatorialFreeModule): # optional - sage.modules ....: def one(self): ....: return self.monomial(0) - sage: from sage.categories.magmatic_algebras \ - ....: import MagmaticAlgebras + sage: from sage.categories.magmatic_algebras import MagmaticAlgebras sage: C = MagmaticAlgebras(QQ).WithBasis().Unital() - sage: F = Foo(QQ,(1,),category=C) - sage: F(0) + sage: F = Foo(QQ, (1,), category=C) # optional - sage.modules + sage: F(0) # optional - sage.modules 0 - sage: F(3) + sage: F(3) # optional - sage.modules 3*B[0] sage: class Bar(Parent): @@ -183,8 +185,8 @@ def _coerce_map_from_base_ring(self): Check that :trac:`29312` is fixed:: - sage: F. = FreeAlgebra(QQ, implementation='letterplace') - sage: F._coerce_map_from_base_ring() + sage: F. = FreeAlgebra(QQ, implementation='letterplace') # optional - sage.combinat sage.modules + sage: F._coerce_map_from_base_ring() # optional - sage.combinat sage.modules Generic morphism: From: Rational Field To: Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field @@ -274,12 +276,12 @@ def one_basis(self): EXAMPLES:: - sage: A = AlgebrasWithBasis(QQ).example() - sage: A.one_basis() + sage: A = AlgebrasWithBasis(QQ).example() # optional - sage.combinat sage.modules + sage: A.one_basis() # optional - sage.combinat sage.modules word: - sage: A.one() + sage: A.one() # optional - sage.combinat sage.modules B[word: ] - sage: A.from_base_ring(4) + sage: A.from_base_ring(4) # optional - sage.combinat sage.modules 4*B[word: ] """ @@ -295,33 +297,33 @@ def one_from_one_basis(self): EXAMPLES:: - sage: A = AlgebrasWithBasis(QQ).example() - sage: A.one_basis() + sage: A = AlgebrasWithBasis(QQ).example() # optional - sage.combinat sage.modules + sage: A.one_basis() # optional - sage.combinat sage.modules word: - sage: A.one_from_one_basis() + sage: A.one_from_one_basis() # optional - sage.combinat sage.modules B[word: ] - sage: A.one() + sage: A.one() # optional - sage.combinat sage.modules B[word: ] TESTS: Try to check that :trac:`5843` Heisenbug is fixed:: - sage: A = AlgebrasWithBasis(QQ).example() - sage: B = AlgebrasWithBasis(QQ).example(('a', 'c')) - sage: A == B + sage: A = AlgebrasWithBasis(QQ).example() # optional - sage.combinat sage.modules + sage: B = AlgebrasWithBasis(QQ).example(('a', 'c')) # optional - sage.combinat sage.modules + sage: A == B # optional - sage.combinat sage.modules False - sage: Aone = A.one_from_one_basis - sage: Bone = B.one_from_one_basis - sage: Aone is Bone + sage: Aone = A.one_from_one_basis # optional - sage.combinat sage.modules + sage: Bone = B.one_from_one_basis # optional - sage.combinat sage.modules + sage: Aone is Bone # optional - sage.combinat sage.modules False Even if called in the wrong order, they should returns their respective one:: - sage: Bone().parent() is B + sage: Bone().parent() is B # optional - sage.combinat sage.modules True - sage: Aone().parent() is A + sage: Aone().parent() is A # optional - sage.combinat sage.modules True """ return self.monomial(self.one_basis()) #. @@ -333,10 +335,10 @@ def one(self): EXAMPLES:: - sage: A = AlgebrasWithBasis(QQ).example() - sage: A.one_basis() + sage: A = AlgebrasWithBasis(QQ).example() # optional - sage.combinat sage.modules + sage: A.one_basis() # optional - sage.combinat sage.modules word: - sage: A.one() + sage: A.one() # optional - sage.combinat sage.modules B[word: ] """ if self.one_basis is NotImplemented: @@ -348,8 +350,8 @@ def from_base_ring(self): """ TESTS:: - sage: A = AlgebrasWithBasis(QQ).example() - sage: A.from_base_ring(3) + sage: A = AlgebrasWithBasis(QQ).example() # optional - sage.combinat sage.modules + sage: A.from_base_ring(3) # optional - sage.combinat sage.modules 3*B[word: ] """ if self.one_basis is NotImplemented: @@ -366,12 +368,12 @@ def from_base_ring_from_one_basis(self, r): EXAMPLES:: - sage: A = AlgebrasWithBasis(QQ).example() - sage: A.from_base_ring_from_one_basis(3) + sage: A = AlgebrasWithBasis(QQ).example() # optional - sage.combinat sage.modules + sage: A.from_base_ring_from_one_basis(3) # optional - sage.combinat sage.modules 3*B[word: ] - sage: A.from_base_ring(3) + sage: A.from_base_ring(3) # optional - sage.combinat sage.modules 3*B[word: ] - sage: A(3) + sage: A(3) # optional - sage.combinat sage.modules 3*B[word: ] """ return self.term(self.one_basis(), r) diff --git a/src/sage/categories/vector_spaces.py b/src/sage/categories/vector_spaces.py index 66534879b5a..508b0fc1f61 100644 --- a/src/sage/categories/vector_spaces.py +++ b/src/sage/categories/vector_spaces.py @@ -82,8 +82,8 @@ def __init__(self, K): TESTS:: - sage: C = QQ^10 # vector space - sage: TestSuite(C).run() + sage: C = QQ^10 # vector space # optional - sage.modules + sage: TestSuite(C).run() # optional - sage.modules sage: TestSuite(VectorSpaces(QQ)).run() """ Category_module.__init__(self, K) @@ -94,15 +94,15 @@ def _call_(self, x): EXAMPLES:: - sage: VectorSpaces(QQ)(ZZ^3) + sage: VectorSpaces(QQ)(ZZ^3) # optional - sage.modules Vector space of dimension 3 over Rational Field TESTS: Check whether :trac:`30174` is fixed:: - sage: Q3 = FiniteRankFreeModule(QQ, 3) - sage: Modules(QQ)(Q3) is Q3 + sage: Q3 = FiniteRankFreeModule(QQ, 3) # optional - sage.modules + sage: Modules(QQ)(Q3) is Q3 # optional - sage.modules True """ @@ -162,15 +162,15 @@ def dimension(self): EXAMPLES:: - sage: M = FreeModule(FiniteField(19), 100) - sage: W = M.submodule([M.gen(50)]) - sage: W.dimension() + sage: M = FreeModule(FiniteField(19), 100) # optional - sage.modules sage.rings.finite_rings + sage: W = M.submodule([M.gen(50)]) # optional - sage.modules sage.rings.finite_rings + sage: W.dimension() # optional - sage.modules sage.rings.finite_rings 1 - sage: M = FiniteRankFreeModule(QQ, 3) - sage: M.dimension() + sage: M = FiniteRankFreeModule(QQ, 3) # optional - sage.modules + sage: M.dimension() # optional - sage.modules 3 - sage: M.tensor_module(1,2).dimension() + sage: M.tensor_module(1, 2).dimension() # optional - sage.modules 27 """ @@ -253,7 +253,7 @@ def example(self, base_ring=None): EXAMPLES:: - sage: Modules(QQ).WithBasis().Graded().example() + sage: Modules(QQ).WithBasis().Graded().example() # optional - sage.combinat sage.modules An example of a graded module with basis: the free module on partitions over Rational Field """ @@ -274,7 +274,7 @@ def example(self, base_ring=None): EXAMPLES:: - sage: Modules(QQ).WithBasis().Graded().example() + sage: Modules(QQ).WithBasis().Graded().example() # optional - sage.combinat sage.modules An example of a graded module with basis: the free module on partitions over Rational Field """ diff --git a/src/sage/categories/weyl_groups.py b/src/sage/categories/weyl_groups.py index ed094d6554d..70f8879353e 100644 --- a/src/sage/categories/weyl_groups.py +++ b/src/sage/categories/weyl_groups.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat sage.groups r""" Weyl Groups """ @@ -182,13 +183,15 @@ def bruhat_cone(self, x, y, side='upper', backend='cdd'): sage: x = W.from_reduced_word([1]) sage: y = W.w0 sage: W.bruhat_cone(x, y) - A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex and 2 rays + A 2-dimensional polyhedron in QQ^3 + defined as the convex hull of 1 vertex and 2 rays sage: W = WeylGroup(['E',6]) sage: x = W.one() sage: y = W.w0 sage: W.bruhat_cone(x, y, side='lower') - A 6-dimensional polyhedron in QQ^8 defined as the convex hull of 1 vertex and 6 rays + A 6-dimensional polyhedron in QQ^8 + defined as the convex hull of 1 vertex and 6 rays TESTS:: @@ -242,7 +245,9 @@ def quantum_bruhat_graph(self, index_set=()): sage: W = WeylGroup(['A',3], prefix="s") sage: g = W.quantum_bruhat_graph((1,3)) sage: g - Parabolic Quantum Bruhat Graph of Weyl Group of type ['A', 3] (as a matrix group acting on the ambient space) for nodes (1, 3): Digraph on 6 vertices + Parabolic Quantum Bruhat Graph of Weyl Group of type ['A', 3] + (as a matrix group acting on the ambient space) + for nodes (1, 3): Digraph on 6 vertices sage: g.vertices(sort=True) [s2*s3*s1*s2, s3*s1*s2, s1*s2, s3*s2, s2, 1] sage: g.edges(sort=True) @@ -385,14 +390,16 @@ def left_pieri_factorizations(self, max_length=None): 3 sage: W.from_reduced_word([1,2]).left_pieri_factorizations().cardinality() 2 - sage: [W.from_reduced_word([1,2]).left_pieri_factorizations(max_length=i).cardinality() for i in [-1, 0, 1, 2]] + sage: [W.from_reduced_word([1,2]).left_pieri_factorizations(max_length=i).cardinality() + ....: for i in [-1, 0, 1, 2]] [0, 1, 2, 2] sage: W = WeylGroup(['C',4,1]) sage: w = W.from_reduced_word([0,3,2,1,0]) sage: w.left_pieri_factorizations().cardinality() 7 - sage: [(u.reduced_word(),v.reduced_word()) for (u,v) in w.left_pieri_factorizations()] + sage: [(u.reduced_word(),v.reduced_word()) + ....: for (u,v) in w.left_pieri_factorizations()] [([], [3, 2, 0, 1, 0]), ([0], [3, 2, 1, 0]), ([3], [2, 0, 1, 0]), @@ -460,9 +467,11 @@ def stanley_symmetric_function_as_polynomial(self, max_length=None): 2*x1^3 + x1*x2 sage: W.from_reduced_word([1,2,1,0]).stanley_symmetric_function_as_polynomial() 3*x1^4 + 2*x1^2*x2 + x2^2 + x1*x3 - sage: W.from_reduced_word([1,2,3,1,2,1,0]).stanley_symmetric_function_as_polynomial() # long time + sage: x = W.from_reduced_word([1,2,3,1,2,1,0]) + sage: x.stanley_symmetric_function_as_polynomial() # long time 22*x1^7 + 11*x1^5*x2 + 5*x1^3*x2^2 + 3*x1^4*x3 + 2*x1*x2^3 + x1^2*x2*x3 - sage: W.from_reduced_word([3,1,2,0,3,1,0]).stanley_symmetric_function_as_polynomial() # long time + sage: y = W.from_reduced_word([3,1,2,0,3,1,0]) + sage: y.stanley_symmetric_function_as_polynomial() # long time 8*x1^7 + 4*x1^5*x2 + 2*x1^3*x2^2 + x1*x2^3 sage: W = WeylGroup(['C',3,1]) @@ -516,10 +525,12 @@ def stanley_symmetric_function(self): sage: W = WeylGroup(['A', 3, 1]) sage: W.from_reduced_word([3,1,2,0,3,1,0]).stanley_symmetric_function() - 8*m[1, 1, 1, 1, 1, 1, 1] + 4*m[2, 1, 1, 1, 1, 1] + 2*m[2, 2, 1, 1, 1] + m[2, 2, 2, 1] + 8*m[1, 1, 1, 1, 1, 1, 1] + 4*m[2, 1, 1, 1, 1, 1] + + 2*m[2, 2, 1, 1, 1] + m[2, 2, 2, 1] sage: A = AffinePermutationGroup(['A',3,1]) sage: A.from_reduced_word([3,1,2,0,3,1,0]).stanley_symmetric_function() - 8*m[1, 1, 1, 1, 1, 1, 1] + 4*m[2, 1, 1, 1, 1, 1] + 2*m[2, 2, 1, 1, 1] + m[2, 2, 2, 1] + 8*m[1, 1, 1, 1, 1, 1, 1] + 4*m[2, 1, 1, 1, 1, 1] + + 2*m[2, 2, 1, 1, 1] + m[2, 2, 2, 1] sage: W = WeylGroup(['C',3,1]) sage: W.from_reduced_word([0,2,1,0]).stanley_symmetric_function() @@ -537,10 +548,11 @@ def stanley_symmetric_function(self): sage: A = AffinePermutationGroup(['A',4,1]) sage: a = A([-2,0,1,4,12]) sage: a.stanley_symmetric_function() - 6*m[1, 1, 1, 1, 1, 1, 1, 1] + 5*m[2, 1, 1, 1, 1, 1, 1] + 4*m[2, 2, 1, 1, 1, 1] - + 3*m[2, 2, 2, 1, 1] + 2*m[2, 2, 2, 2] + 4*m[3, 1, 1, 1, 1, 1] + 3*m[3, 2, 1, 1, 1] - + 2*m[3, 2, 2, 1] + 2*m[3, 3, 1, 1] + m[3, 3, 2] + 3*m[4, 1, 1, 1, 1] + 2*m[4, 2, 1, 1] - + m[4, 2, 2] + m[4, 3, 1] + 6*m[1, 1, 1, 1, 1, 1, 1, 1] + 5*m[2, 1, 1, 1, 1, 1, 1] + + 4*m[2, 2, 1, 1, 1, 1] + 3*m[2, 2, 2, 1, 1] + 2*m[2, 2, 2, 2] + + 4*m[3, 1, 1, 1, 1, 1] + 3*m[3, 2, 1, 1, 1] + 2*m[3, 2, 2, 1] + + 2*m[3, 3, 1, 1] + m[3, 3, 2] + 3*m[4, 1, 1, 1, 1] + + 2*m[4, 2, 1, 1] + m[4, 2, 2] + m[4, 3, 1] One more example (:trac:`14095`):: @@ -807,7 +819,8 @@ def quantum_bruhat_successors(self, index_set=None, roots=False, quantum_only=Fa sage: w.quantum_bruhat_successors([1,3]) Traceback (most recent call last): ... - ValueError: s2*s3 is not of minimum length in its coset of the parabolic subgroup generated by the reflections (1, 3) + ValueError: s2*s3 is not of minimum length in its coset + of the parabolic subgroup generated by the reflections (1, 3) """ W = self.parent() if not W.cartan_type().is_finite(): diff --git a/src/sage/categories/with_realizations.py b/src/sage/categories/with_realizations.py index 7f59b92d72b..dd463186a2a 100644 --- a/src/sage/categories/with_realizations.py +++ b/src/sage/categories/with_realizations.py @@ -69,45 +69,46 @@ def WithRealizations(self): represented. Consider for example an algebra `A` which admits several natural bases:: - sage: A = Sets().WithRealizations().example(); A + sage: A = Sets().WithRealizations().example(); A # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field For each such basis `B` one implements a parent `P_B` which realizes `A` with its elements represented by expanding them on the basis `B`:: - sage: A.F() + sage: A.F() # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis - sage: A.Out() + sage: A.Out() # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field in the Out basis - sage: A.In() + sage: A.In() # optional - sage.combinat sage.modules The subset algebra of {1, 2, 3} over Rational Field in the In basis - sage: A.an_element() + sage: A.an_element() # optional - sage.combinat sage.modules F[{}] + 2*F[{1}] + 3*F[{2}] + F[{1, 2}] If `B` and `B'` are two bases, then the change of basis from `B` to `B'` is implemented by a canonical coercion between `P_B` and `P_{B'}`:: - sage: F = A.F(); In = A.In(); Out = A.Out() - sage: i = In.an_element(); i + sage: F = A.F(); In = A.In(); Out = A.Out() # optional - sage.combinat sage.modules + sage: i = In.an_element(); i # optional - sage.combinat sage.modules In[{}] + 2*In[{1}] + 3*In[{2}] + In[{1, 2}] - sage: F(i) + sage: F(i) # optional - sage.combinat sage.modules 7*F[{}] + 3*F[{1}] + 4*F[{2}] + F[{1, 2}] - sage: F.coerce_map_from(Out) + sage: F.coerce_map_from(Out) # optional - sage.combinat sage.modules Generic morphism: From: The subset algebra of {1, 2, 3} over Rational Field in the Out basis To: The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis allowing for mixed arithmetic:: - sage: (1 + Out.from_set(1)) * In.from_set(2,3) - Out[{}] + 2*Out[{1}] + 2*Out[{2}] + 2*Out[{3}] + 2*Out[{1, 2}] + 2*Out[{1, 3}] + 4*Out[{2, 3}] + 4*Out[{1, 2, 3}] + sage: (1 + Out.from_set(1)) * In.from_set(2,3) # optional - sage.combinat sage.modules + Out[{}] + 2*Out[{1}] + 2*Out[{2}] + 2*Out[{3}] + 2*Out[{1, 2}] + + 2*Out[{1, 3}] + 4*Out[{2, 3}] + 4*Out[{1, 2, 3}] In our example, there are three realizations:: - sage: A.realizations() + sage: A.realizations() # optional - sage.combinat sage.modules [The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis, The subset algebra of {1, 2, 3} over Rational Field in the In basis, The subset algebra of {1, 2, 3} over Rational Field in the Out basis] @@ -115,10 +116,13 @@ def WithRealizations(self): Instead of manually defining the shorthands ``F``, ``In``, and ``Out``, as above one can just do:: - sage: A.inject_shorthands() - Defining F as shorthand for The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis - Defining In as shorthand for The subset algebra of {1, 2, 3} over Rational Field in the In basis - Defining Out as shorthand for The subset algebra of {1, 2, 3} over Rational Field in the Out basis + sage: A.inject_shorthands() # optional - sage.combinat sage.modules + Defining F as shorthand for + The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis + Defining In as shorthand for + The subset algebra of {1, 2, 3} over Rational Field in the In basis + Defining Out as shorthand for + The subset algebra of {1, 2, 3} over Rational Field in the Out basis .. RUBRIC:: Rationale @@ -138,26 +142,28 @@ def WithRealizations(self): We now illustrate this second point by defining the polynomial ring with coefficients in `A`:: - sage: P = A['x']; P - Univariate Polynomial Ring in x over The subset algebra of {1, 2, 3} over Rational Field - sage: x = P.gen() + sage: P = A['x']; P # optional - sage.combinat sage.modules + Univariate Polynomial Ring in x over + The subset algebra of {1, 2, 3} over Rational Field + sage: x = P.gen() # optional - sage.combinat sage.modules In the following examples, the coefficients turn out to be all represented in the `F` basis:: - sage: P.one() + sage: P.one() # optional - sage.combinat sage.modules F[{}] - sage: (P.an_element() + 1)^2 + sage: (P.an_element() + 1)^2 # optional - sage.combinat sage.modules F[{}]*x^2 + 2*F[{}]*x + F[{}] However we can create a polynomial with mixed coefficients, and compute with it:: - sage: p = P([1, In[{1}], Out[{2}] ]); p + sage: p = P([1, In[{1}], Out[{2}] ]); p # optional - sage.combinat sage.modules Out[{2}]*x^2 + In[{1}]*x + F[{}] - sage: p^2 + sage: p^2 # optional - sage.combinat sage.modules Out[{2}]*x^4 - + (-8*In[{}] + 4*In[{1}] + 8*In[{2}] + 4*In[{3}] - 4*In[{1, 2}] - 2*In[{1, 3}] - 4*In[{2, 3}] + 2*In[{1, 2, 3}])*x^3 + + (-8*In[{}] + 4*In[{1}] + 8*In[{2}] + 4*In[{3}] + - 4*In[{1, 2}] - 2*In[{1, 3}] - 4*In[{2, 3}] + 2*In[{1, 2, 3}])*x^3 + (F[{}] + 3*F[{1}] + 2*F[{2}] - 2*F[{1, 2}] - 2*F[{2, 3}] + 2*F[{1, 2, 3}])*x^2 + (2*F[{}] + 2*F[{1}])*x + F[{}] @@ -169,16 +175,21 @@ def WithRealizations(self): One can easily coerce all coefficient to a given basis with:: - sage: p.map_coefficients(In) - (-4*In[{}] + 2*In[{1}] + 4*In[{2}] + 2*In[{3}] - 2*In[{1, 2}] - In[{1, 3}] - 2*In[{2, 3}] + In[{1, 2, 3}])*x^2 + In[{1}]*x + In[{}] + sage: p.map_coefficients(In) # optional - sage.combinat sage.modules + (-4*In[{}] + 2*In[{1}] + 4*In[{2}] + 2*In[{3}] + - 2*In[{1, 2}] - In[{1, 3}] - 2*In[{2, 3}] + In[{1, 2, 3}])*x^2 + + In[{1}]*x + In[{}] Alas, the natural notation for constructing such polynomials does not yet work:: - sage: In[{1}] * x + sage: In[{1}] * x # optional - sage.combinat sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'The subset algebra of {1, 2, 3} over Rational Field in the In basis' and 'Univariate Polynomial Ring in x over The subset algebra of {1, 2, 3} over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'The subset algebra of {1, 2, 3} over Rational Field in the In basis' + and 'Univariate Polynomial Ring in x over + The subset algebra of {1, 2, 3} over Rational Field' .. RUBRIC:: The category of realizations of `A` @@ -186,17 +197,18 @@ def WithRealizations(self): is a category (whose class inherits from :class:`~sage.categories.realizations.Category_realization_of_parent`):: - sage: A.Realizations() - Category of realizations of The subset algebra of {1, 2, 3} over Rational Field + sage: A.Realizations() # optional - sage.combinat sage.modules + Category of realizations of + The subset algebra of {1, 2, 3} over Rational Field The various parent realizing `A` belong to this category:: - sage: A.F() in A.Realizations() + sage: A.F() in A.Realizations() # optional - sage.combinat sage.modules True `A` itself is in the category of algebras with realizations:: - sage: A in Algebras(QQ).WithRealizations() + sage: A in Algebras(QQ).WithRealizations() # optional - sage.combinat sage.modules True The (mostly technical) ``WithRealizations`` categories are the @@ -216,12 +228,12 @@ def WithRealizations(self): On our example, this simply means that `A` is automatically in the category of rings with realizations (covariance):: - sage: A in Rings().WithRealizations() + sage: A in Rings().WithRealizations() # optional - sage.combinat sage.modules True and in the category of algebras (regressiveness):: - sage: A in Algebras(QQ) + sage: A in Algebras(QQ) # optional - sage.combinat sage.modules True .. NOTE:: diff --git a/src/sage/coding/code_bounds.py b/src/sage/coding/code_bounds.py index 8e1ce61cedb..71a75902080 100644 --- a/src/sage/coding/code_bounds.py +++ b/src/sage/coding/code_bounds.py @@ -445,7 +445,7 @@ def griesmer_upper_bound(n,q,d,algorithm=None): else: # To compute the bound, we keep summing up the terms on the RHS # until we start violating the inequality. - from sage.functions.other import ceil + from sage.arith.misc import integer_ceil as ceil den = 1 s = 0 k = 0 diff --git a/src/sage/coding/grs_code.py b/src/sage/coding/grs_code.py index d86c61c254e..d8614b01323 100644 --- a/src/sage/coding/grs_code.py +++ b/src/sage/coding/grs_code.py @@ -64,9 +64,6 @@ from sage.misc.functional import symbolic_sum from sage.misc.misc_c import prod -from sage.functions.other import binomial -from sage.symbolic.ring import SR - from .linear_code import AbstractLinearCode from .encoder import Encoder from .decoder import Decoder, DecodingError @@ -516,7 +513,7 @@ def weight_distribution(self): sage: F = GF(11) sage: n, k = 10, 5 sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k) - sage: C.weight_distribution() + sage: C.weight_distribution() # optional - sage.symbolic [1, 0, 0, 0, 0, 0, 2100, 6000, 29250, 61500, 62200] TESTS: @@ -525,13 +522,16 @@ def weight_distribution(self): sage: F = GF(7) sage: C = codes.GeneralizedReedSolomonCode(F.list(), 3) - sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time + sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time # optional - sage.symbolic True sage: F = GF(8) sage: C = codes.GeneralizedReedSolomonCode(F.list(), 3) - sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time + sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time # optional - sage.symbolic True """ + from sage.symbolic.ring import SR + from sage.functions.other import binomial + d = self.minimum_distance() n = self.length() q = self.base_ring().order() diff --git a/src/sage/coding/guruswami_sudan/gs_decoder.py b/src/sage/coding/guruswami_sudan/gs_decoder.py index 830d49238dc..db1a745f574 100644 --- a/src/sage/coding/guruswami_sudan/gs_decoder.py +++ b/src/sage/coding/guruswami_sudan/gs_decoder.py @@ -24,6 +24,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** +from sage.arith.misc import integer_floor as floor from sage.coding.grs_code import GeneralizedReedSolomonCode from sage.rings.integer_ring import ZZ from sage.coding.decoder import Decoder @@ -31,9 +32,10 @@ from sage.coding.guruswami_sudan.utils import (johnson_radius, gilt, solve_degree2_to_integer_range) -from sage.functions.other import floor +from sage.misc.lazy_import import lazy_import from sage.misc.functional import sqrt + def n_k_params(C, n_k): r""" Internal helper function for the GRSGuruswamiSudanDecoder class for allowing to diff --git a/src/sage/coding/guruswami_sudan/utils.py b/src/sage/coding/guruswami_sudan/utils.py index d53637d933f..aaf0e70e8af 100644 --- a/src/sage/coding/guruswami_sudan/utils.py +++ b/src/sage/coding/guruswami_sudan/utils.py @@ -19,7 +19,8 @@ #***************************************************************************** -from sage.functions.other import floor +from sage.arith.misc import integer_floor as floor +from sage.misc.lazy_import import lazy_import from sage.misc.functional import sqrt from sage.rings.integer_ring import ZZ from sage.rings.integer import Integer diff --git a/src/sage/combinat/all.py b/src/sage/combinat/all.py index 2206ea2873a..0f43e6bbcfe 100644 --- a/src/sage/combinat/all.py +++ b/src/sage/combinat/all.py @@ -218,7 +218,7 @@ lazy_import('sage.combinat.multiset_partition_into_sets_ordered', ['OrderedMultisetPartitionIntoSets', 'OrderedMultisetPartitionsIntoSets']) -from .subset import Subsets +from .subset import Subsets, subsets, powerset, uniq from .necklace import Necklaces lazy_import('sage.combinat.dyck_word', ('DyckWords', 'DyckWord')) lazy_import('sage.combinat.nu_dyck_word', ('NuDyckWords', 'NuDyckWord')) diff --git a/src/sage/combinat/backtrack.py b/src/sage/combinat/backtrack.py index 565b3efa973..777e511531f 100644 --- a/src/sage/combinat/backtrack.py +++ b/src/sage/combinat/backtrack.py @@ -63,7 +63,7 @@ def __iter__(self): sage: from sage.combinat.permutation import PatternAvoider sage: p = PatternAvoider(Permutations(4), [[1,3,2]]) - sage: len(list(p)) + sage: len(list(p)) # optional - sage.combinat 14 """ # Initialize the stack of generators with the initial data. diff --git a/src/sage/combinat/binary_recurrence_sequences.py b/src/sage/combinat/binary_recurrence_sequences.py index 8c244342712..9c7aacc1d55 100644 --- a/src/sage/combinat/binary_recurrence_sequences.py +++ b/src/sage/combinat/binary_recurrence_sequences.py @@ -67,7 +67,8 @@ from sage.rings.integer import Integer from sage.arith.functions import lcm from sage.arith.misc import is_prime, next_prime, next_prime_power, legendre_symbol -from sage.functions.log import log +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.log", "log") from sage.misc.functional import sqrt diff --git a/src/sage/combinat/blob_algebra.py b/src/sage/combinat/blob_algebra.py index 95899fd66a6..657c70a5c0e 100644 --- a/src/sage/combinat/blob_algebra.py +++ b/src/sage/combinat/blob_algebra.py @@ -23,7 +23,7 @@ from sage.structure.richcmp import richcmp #from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass from sage.misc.cachefunc import cached_method -from sage.misc.misc import powerset +from sage.combinat.subset import powerset from sage.arith.misc import binomial from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.categories.algebras import Algebras diff --git a/src/sage/combinat/cartesian_product.py b/src/sage/combinat/cartesian_product.py index b15185685c7..7ab49439557 100644 --- a/src/sage/combinat/cartesian_product.py +++ b/src/sage/combinat/cartesian_product.py @@ -51,27 +51,27 @@ class for ``cartesian_product``; sage: F1 = ['a', 'b'] sage: F2 = [1, 2, 3, 4] - sage: F3 = Permutations(3) + sage: F3 = Permutations(3) # optional - sage.combinat sage: from sage.combinat.cartesian_product import CartesianProduct_iters - sage: C = CartesianProduct_iters(F1, F2, F3) - sage: c = cartesian_product([F1, F2, F3]) + sage: C = CartesianProduct_iters(F1, F2, F3) # optional - sage.combinat + sage: c = cartesian_product([F1, F2, F3]) # optional - sage.combinat - sage: type(C.an_element()) + sage: type(C.an_element()) # optional - sage.combinat - sage: type(c.an_element()) + sage: type(c.an_element()) # optional - sage.combinat - sage: l = ['a', 1, Permutation([3,2,1])] - sage: l in C + sage: l = ['a', 1, Permutation([3,2,1])] # optional - sage.combinat + sage: l in C # optional - sage.combinat True - sage: l in c + sage: l in c # optional - sage.combinat False - sage: elt = c(l) - sage: elt + sage: elt = c(l) # optional - sage.combinat + sage: elt # optional - sage.combinat ('a', 1, [3, 2, 1]) - sage: elt in c + sage: elt in c # optional - sage.combinat True - sage: elt.parent() is c + sage: elt.parent() is c # optional - sage.combinat True """ diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index 195ff344e50..993112644d0 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -64,18 +64,12 @@ **Implemented in other modules (listed for completeness):** -The ``sage.arith.all`` module contains the following +The package :mod:`sage.arith` contains the following combinatorial functions: -- binomial the binomial coefficient (wrapped from PARI) +- :func:`binomial` the binomial coefficient (wrapped from PARI) -- factorial (wrapped from PARI) - -- partition (from the Python Cookbook) Generator of the list of - all the partitions of the integer `n`. - -- :func:`number_of_partitions` (wrapped from PARI) the - *number* of partitions: +- :func:`factorial` (wrapped from PARI) - :func:`falling_factorial` Definition: for integer `a \ge 0` we have `x(x-1) \cdots (x-a+1)`. In all @@ -87,7 +81,12 @@ other cases we use the GAMMA-function: `\frac {\Gamma(x+a)} {\Gamma(x)}`. -- gaussian_binomial the gaussian binomial +From other modules: + +- :func:`number_of_partitions` (wrapped from PARI) the + *number* of partitions: + +- :func:`sage.combinat.q_analogues.gaussian_binomial` the Gaussian binomial .. MATH:: @@ -174,8 +173,6 @@ from sage.rings.infinity import infinity from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.libs.pari.all import pari -from sage.misc.prandom import randint from sage.misc.misc_c import prod from sage.misc.cachefunc import cached_function from sage.structure.sage_object import SageObject @@ -187,7 +184,10 @@ from sage.misc.classcall_metaclass import ClasscallMetaclass from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass from sage.structure.element import Element + lazy_import('sage.interfaces.maxima_lib', 'maxima') +lazy_import('sage.libs.pari.all', 'pari') +lazy_import('sage.misc.prandom', 'randint') def bell_number(n, algorithm='flint', **options) -> Integer: @@ -319,17 +319,17 @@ def bell_number(n, algorithm='flint', **options) -> Integer: EXAMPLES:: - sage: bell_number(10) + sage: bell_number(10) # optional - sage.libs.flint 115975 - sage: bell_number(2) + sage: bell_number(2) # optional - sage.libs.flint 2 - sage: bell_number(-10) + sage: bell_number(-10) # optional - sage.libs.flint Traceback (most recent call last): ... ArithmeticError: Bell numbers not defined for negative indices - sage: bell_number(1) + sage: bell_number(1) # optional - sage.libs.flint 1 - sage: bell_number(1/3) + sage: bell_number(1/3) # optional - sage.libs.flint Traceback (most recent call last): ... TypeError: no conversion of this rational to integer @@ -339,17 +339,17 @@ def bell_number(n, algorithm='flint', **options) -> Integer: first time, we deem the precision too low, we use our guess to (temporarily) raise mpmath's precision and the Bell number is recomputed. :: - sage: k = bell_number(30, 'mpmath'); k + sage: k = bell_number(30, 'mpmath'); k # optional - mpmath 846749014511809332450147 - sage: k == bell_number(30) + sage: k == bell_number(30) # optional - mpmath sage.libs.flint True If you knows what precision is necessary before computing the Bell number, you can use the ``prec`` option:: - sage: k2 = bell_number(30, 'mpmath', prec=30); k2 + sage: k2 = bell_number(30, 'mpmath', prec=30); k2 # optional - mpmath 846749014511809332450147 - sage: k == k2 + sage: k == k2 # optional - mpmath True .. WARNING:: @@ -357,18 +357,19 @@ def bell_number(n, algorithm='flint', **options) -> Integer: Running mpmath with the precision set too low can result in incorrect results:: - sage: k = bell_number(30, 'mpmath', prec=15); k + sage: k = bell_number(30, 'mpmath', prec=15); k # optional - mpmath 846749014511809388871680 - sage: k == bell_number(30) + sage: k == bell_number(30) # optional - mpmath False TESTS:: - sage: all(bell_number(n) == bell_number(n,'dobinski') for n in range(100)) + sage: all(bell_number(n) == bell_number(n,'dobinski') for n in range(100)) # optional - sage.libs.flint True - sage: all(bell_number(n) == bell_number(n,'gap') for n in range(100)) + sage: all(bell_number(n) == bell_number(n,'gap') for n in range(100)) # optional - sage.libs.flint sage.libs.gap True - sage: all(bell_number(n) == bell_number(n,'mpmath', prec=500) for n in range(200, 220)) + sage: all(bell_number(n) == bell_number(n,'mpmath', prec=500) # optional - mpmath sage.libs.flint + ....: for n in range(200, 220)) True AUTHORS: @@ -547,12 +548,12 @@ def euler_number(n, algorithm='flint') -> Integer: EXAMPLES:: - sage: [euler_number(i) for i in range(10)] + sage: [euler_number(i) for i in range(10)] # optional - sage.libs.flint [1, 0, -1, 0, 5, 0, -61, 0, 1385, 0] sage: x = PowerSeriesRing(QQ, 'x').gen().O(10) - sage: 2/(exp(x)+exp(-x)) + sage: 2/(exp(x)+exp(-x)) # optional - sage.symbolic 1 - 1/2*x^2 + 5/24*x^4 - 61/720*x^6 + 277/8064*x^8 + O(x^10) - sage: [euler_number(i)/factorial(i) for i in range(11)] + sage: [euler_number(i)/factorial(i) for i in range(11)] # optional - sage.libs.flint [1, 0, -1/2, 0, 5/24, 0, -61/720, 0, 277/8064, 0, -50521/3628800] sage: euler_number(-1) Traceback (most recent call last): @@ -561,7 +562,7 @@ def euler_number(n, algorithm='flint') -> Integer: TESTS:: - sage: euler_number(6, 'maxima') + sage: euler_number(6, 'maxima') # optional - sage.symbolic -61 REFERENCES: @@ -705,21 +706,21 @@ def fibonacci(n, algorithm="pari") -> Integer: EXAMPLES:: - sage: fibonacci(10) + sage: fibonacci(10) # optional - sage.libs.pari 55 - sage: fibonacci(10, algorithm='gap') + sage: fibonacci(10, algorithm='gap') # optional - sage.libs.gap 55 :: - sage: fibonacci(-100) + sage: fibonacci(-100) # optional - sage.libs.pari -354224848179261915075 - sage: fibonacci(100) + sage: fibonacci(100) # optional - sage.libs.pari 354224848179261915075 :: - sage: fibonacci(0) + sage: fibonacci(0) # optional - sage.libs.pari 0 sage: fibonacci(1/2) Traceback (most recent call last): @@ -758,17 +759,17 @@ def lucas_number1(n, P, Q): EXAMPLES:: - sage: lucas_number1(5,1,-1) + sage: lucas_number1(5,1,-1) # optional - sage.libs.gap 5 - sage: lucas_number1(6,1,-1) + sage: lucas_number1(6,1,-1) # optional - sage.libs.gap 8 - sage: lucas_number1(7,1,-1) + sage: lucas_number1(7,1,-1) # optional - sage.libs.gap 13 - sage: lucas_number1(7,1,-2) + sage: lucas_number1(7,1,-2) # optional - sage.libs.gap 43 - sage: lucas_number1(5,2,3/5) + sage: lucas_number1(5,2,3/5) # optional - sage.libs.gap 229/25 - sage: lucas_number1(5,2,1.5) + sage: lucas_number1(5,2,1.5) # optional - sage.libs.gap 1/4 There was a conjecture that the sequence `L_n` defined by @@ -776,8 +777,9 @@ def lucas_number1(n, P, Q): `L_2=3`, has the property that `n` prime implies that `L_n` is prime. :: - sage: lucas = lambda n : Integer((5/2)*lucas_number1(n,1,-1)+(1/2)*lucas_number2(n,1,-1)) - sage: [[lucas(n),is_prime(lucas(n)),n+1,is_prime(n+1)] for n in range(15)] + sage: def lucas(n): + ....: return Integer((5/2)*lucas_number1(n,1,-1) + (1/2)*lucas_number2(n,1,-1)) + sage: [[lucas(n), is_prime(lucas(n)), n+1, is_prime(n+1)] for n in range(15)] # optional - sage.libs.gap [[1, False, 1, False], [3, True, 2, True], [4, False, 3, True], @@ -825,26 +827,26 @@ def lucas_number2(n, P, Q): EXAMPLES:: - sage: [lucas_number2(i,1,-1) for i in range(10)] + sage: [lucas_number2(i,1,-1) for i in range(10)] # optional - sage.libs.gap [2, 1, 3, 4, 7, 11, 18, 29, 47, 76] - sage: [fibonacci(i-1)+fibonacci(i+1) for i in range(10)] + sage: [fibonacci(i-1)+fibonacci(i+1) for i in range(10)] # optional - sage.libs.pari [2, 1, 3, 4, 7, 11, 18, 29, 47, 76] :: - sage: n = lucas_number2(5,2,3); n + sage: n = lucas_number2(5,2,3); n # optional - sage.libs.gap 2 - sage: type(n) + sage: type(n) # optional - sage.libs.gap - sage: n = lucas_number2(5,2,-3/9); n + sage: n = lucas_number2(5,2,-3/9); n # optional - sage.libs.gap 418/9 - sage: type(n) + sage: type(n) # optional - sage.libs.gap The case `P=1`, `Q=-1` is the Lucas sequence in Brualdi's Introductory Combinatorics, 4th ed., Prentice-Hall, 2004:: - sage: [lucas_number2(n,1,-1) for n in range(10)] + sage: [lucas_number2(n,1,-1) for n in range(10)] # optional - sage.libs.gap [2, 1, 3, 4, 7, 11, 18, 29, 47, 76] """ n = ZZ(n) @@ -873,20 +875,20 @@ def stirling_number1(n, k, algorithm="gap") -> Integer: EXAMPLES:: - sage: stirling_number1(3,2) + sage: stirling_number1(3,2) # optional - sage.libs.gap 3 - sage: stirling_number1(5,2) + sage: stirling_number1(5,2) # optional - sage.libs.gap 50 - sage: 9*stirling_number1(9,5)+stirling_number1(9,4) + sage: 9*stirling_number1(9,5) + stirling_number1(9,4) # optional - sage.libs.gap 269325 - sage: stirling_number1(10,5) + sage: stirling_number1(10,5) # optional - sage.libs.gap 269325 Indeed, `S_1(n,k) = S_1(n-1,k-1) + (n-1)S_1(n-1,k)`. TESTS:: - sage: stirling_number1(10,5, algorithm='flint') + sage: stirling_number1(10,5, algorithm='flint') # optional - sage.libs.flint 269325 sage: s_sage = stirling_number1(50,3, algorithm="mutta") @@ -975,20 +977,17 @@ def stirling_number2(n, k, algorithm=None) -> Integer: 13707767141249454929449108424328432845001327479099713037876832759323918134840537229737624018908470350134593241314462032607787062188356702932169472820344473069479621239187226765307960899083230982112046605340713218483809366970996051181537181362810003701997334445181840924364501502386001705718466534614548056445414149016614254231944272872440803657763210998284198037504154374028831561296154209804833852506425742041757849726214683321363035774104866182331315066421119788248419742922490386531970053376982090046434022248364782970506521655684518998083846899028416459701847828711541840099891244700173707021989771147674432503879702222276268661726508226951587152781439224383339847027542755222936463527771486827849728880 sage: stirling_number2(500,31) 5832088795102666690960147007601603328246123996896731854823915012140005028360632199516298102446004084519955789799364757997824296415814582277055514048635928623579397278336292312275467402957402880590492241647229295113001728653772550743446401631832152281610081188041624848850056657889275564834450136561842528589000245319433225808712628826136700651842562516991245851618481622296716433577650218003181535097954294609857923077238362717189185577756446945178490324413383417876364657995818830270448350765700419876347023578011403646501685001538551891100379932684279287699677429566813471166558163301352211170677774072447414719380996777162087158124939742564291760392354506347716119002497998082844612434332155632097581510486912 - sage: n = stirling_number2(20,11) - sage: n + sage: n = stirling_number2(20,11); n 1900842429486 sage: type(n) - sage: n = stirling_number2(20,11,algorithm='gap') - sage: n + sage: n = stirling_number2(20, 11, algorithm='gap'); n # optional - sage.libs.gap 1900842429486 - sage: type(n) + sage: type(n) # optional - sage.libs.gap - sage: n = stirling_number2(20,11,algorithm='flint') - sage: n + sage: n = stirling_number2(20, 11, algorithm='flint'); n # optional - sage.libs.flint 1900842429486 - sage: type(n) + sage: type(n) # optional - sage.libs.flint Sage's implementation splitting the computation of the Stirling @@ -997,7 +996,7 @@ def stirling_number2(n, k, algorithm=None) -> Integer: For `n<200`:: - sage: for n in Subsets(range(100,200), 5).random_element(): + sage: for n in Subsets(range(100,200), 5).random_element(): # optional - sage.libs.flint sage.libs.gap ....: for k in Subsets(range(n), 5).random_element(): ....: s_sage = stirling_number2(n,k) ....: s_flint = stirling_number2(n,k, algorithm = "flint") @@ -1007,7 +1006,7 @@ def stirling_number2(n, k, algorithm=None) -> Integer: For `n\geq 200`:: - sage: for n in Subsets(range(200,300), 5).random_element(): + sage: for n in Subsets(range(200,300), 5).random_element(): # optional - sage.libs.flint sage.libs.gap ....: for k in Subsets(range(n), 5).random_element(): ....: s_sage = stirling_number2(n,k) ....: s_flint = stirling_number2(n,k, algorithm = "flint") @@ -1015,10 +1014,10 @@ def stirling_number2(n, k, algorithm=None) -> Integer: ....: if not (s_sage == s_flint and s_sage == s_gap): ....: print("Error with n<200") - sage: stirling_number2(20,3, algorithm="maxima") + sage: stirling_number2(20, 3, algorithm="maxima") # optional - sage.symbolic 580606446 - sage: s_sage = stirling_number2(5,3, algorithm="namba") + sage: s_sage = stirling_number2(5, 3, algorithm="namba") Traceback (most recent call last): ... ValueError: unknown algorithm: namba @@ -1174,11 +1173,11 @@ def __init__(self, l, copy=True): Test indirectly that we copy the input (see :trac:`18184`):: - sage: L = IntegerListsLex(element_class=Partition) - sage: x = [3, 2, 1] - sage: P = L(x) - sage: x[0] = 5 - sage: list(P) + sage: L = IntegerListsLex(element_class=Partition) # optional - sage.combinat + sage: x = [3, 2, 1] # optional - sage.combinat + sage: P = L(x) # optional - sage.combinat + sage: x[0] = 5 # optional - sage.combinat + sage: list(P) # optional - sage.combinat [3, 2, 1] """ if copy: @@ -1513,12 +1512,12 @@ class CombinatorialElement(CombinatorialObject, Element, EXAMPLES:: sage: from sage.combinat.combinat import CombinatorialElement - sage: e = CombinatorialElement(Partitions(6), [3,2,1]) - sage: e == loads(dumps(e)) + sage: e = CombinatorialElement(Partitions(6), [3,2,1]) # optional - sage.combinat + sage: e == loads(dumps(e)) # optional - sage.combinat True - sage: parent(e) + sage: parent(e) # optional - sage.combinat Partitions of the integer 6 - sage: list(e) + sage: list(e) # optional - sage.combinat [3, 2, 1] Check classcalls:: @@ -1616,7 +1615,7 @@ def is_finite(self) -> bool: EXAMPLES:: - sage: Partitions(5).is_finite() + sage: Partitions(5).is_finite() # optional - sage.combinat True sage: Permutations().is_finite() False @@ -1650,7 +1649,7 @@ def __str__(self) -> str: EXAMPLES:: - sage: str(Partitions(5)) + sage: str(Partitions(5)) # optional - sage.combinat 'Partitions of the integer 5' """ return repr(self) @@ -1659,7 +1658,7 @@ def _repr_(self) -> str: """ EXAMPLES:: - sage: repr(Partitions(5)) # indirect doctest + sage: repr(Partitions(5)) # indirect doctest # optional - sage.combinat 'Partitions of the integer 5' """ if hasattr(self, '_name') and self._name: @@ -1682,7 +1681,7 @@ def __contains__(self, x) -> bool: EXAMPLES:: sage: C = CombinatorialClass() - sage: x in C + sage: x in C # optional - sage.symbolic Traceback (most recent call last): ... NotImplementedError @@ -1697,11 +1696,11 @@ def __eq__(self, other): EXAMPLES:: - sage: p5 = Partitions(5) - sage: p6 = Partitions(6) - sage: repr(p5) == repr(p6) + sage: p5 = Partitions(5) # optional - sage.combinat + sage: p6 = Partitions(6) # optional - sage.combinat + sage: repr(p5) == repr(p6) # optional - sage.combinat False - sage: p5 == p6 + sage: p5 == p6 # optional - sage.combinat False """ return repr(self) == repr(other) @@ -1712,9 +1711,9 @@ def __ne__(self, other): EXAMPLES:: - sage: p5 = Partitions(5) - sage: p6 = Partitions(6) - sage: p5 != p6 + sage: p5 = Partitions(5) # optional - sage.combinat + sage: p6 = Partitions(6) # optional - sage.combinat + sage: p5 != p6 # optional - sage.combinat True """ return not (self == other) @@ -1766,14 +1765,14 @@ def __call__(self, x): EXAMPLES:: - sage: p5 = Partitions(5) - sage: a = [2,2,1] - sage: type(a) + sage: p5 = Partitions(5) # optional - sage.combinat + sage: a = [2,2,1] # optional - sage.combinat + sage: type(a) # optional - sage.combinat - sage: a = p5(a) - sage: type(a) + sage: a = p5(a) # optional - sage.combinat + sage: type(a) # optional - sage.combinat - sage: p5([2,1]) + sage: p5([2,1]) # optional - sage.combinat Traceback (most recent call last): ... ValueError: [2, 1] is not an element of Partitions of the integer 5 @@ -1795,8 +1794,8 @@ def element_class(self): TESTS:: - sage: P5 = Partitions(5) - sage: P5.element_class + sage: P5 = Partitions(5) # optional - sage.combinat + sage: P5.element_class # optional - sage.combinat """ # assert not isinstance(self, Parent) # Raises an alert if we override the proper definition from Parent @@ -1811,9 +1810,9 @@ def _element_constructor_(self, x): TESTS:: - sage: P5 = Partitions(5) - sage: p = P5([3,2]) # indirect doctest - sage: type(p) + sage: P5 = Partitions(5) # optional - sage.combinat + sage: p = P5([3,2]) # indirect doctest # optional - sage.combinat + sage: type(p) # optional - sage.combinat """ # assert not isinstance(self, Parent) # Raises an alert if we override the proper definition from Parent @@ -1829,7 +1828,7 @@ def __list_from_iterator(self): sage: class C(CombinatorialClass): ....: def __iter__(self): ....: return iter([1,2,3]) - sage: C().list() #indirect doctest + sage: C().list() #indirect doctest [1, 2, 3] """ return [x for x in self] @@ -1949,8 +1948,8 @@ def __iter__(self): EXAMPLES:: - sage: p5 = Partitions(5) - sage: [i for i in p5] + sage: p5 = Partitions(5) # optional - sage.combinat + sage: [i for i in p5] # optional - sage.combinat [[5], [4, 1], [3, 2], [3, 1, 1], [2, 2, 1], [2, 1, 1, 1], [1, 1, 1, 1, 1]] sage: C = CombinatorialClass() sage: iter(C) @@ -2117,7 +2116,7 @@ def filter(self, f, name=None): sage: from sage.combinat.combinat import Permutations_CC sage: P = Permutations_CC(3).filter(lambda x: x.avoids([1,2])) - sage: P.list() + sage: P.list() # optional - sage.combinat [[3, 2, 1]] """ return FilteredCombinatorialClass(self, f, name=name) @@ -2151,7 +2150,8 @@ class by `f`, as a combinatorial class. EXAMPLES:: sage: R = Permutations(3).map(attrcall('reduced_word')); R - Image of Standard permutations of 3 by The map *.reduced_word() from Standard permutations of 3 + Image of Standard permutations of 3 by + The map *.reduced_word() from Standard permutations of 3 sage: R.cardinality() 6 sage: R.list() @@ -2161,15 +2161,15 @@ class by `f`, as a combinatorial class. If the function is not injective, then there may be repeated elements:: - sage: P = Partitions(4) - sage: P.list() + sage: P = Partitions(4) # optional - sage.combinat + sage: P.list() # optional - sage.combinat [[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]] - sage: P.map(len).list() + sage: P.map(len).list() # optional - sage.combinat [1, 2, 2, 3, 4] Use ``is_injective=False`` to get a correct result in this case:: - sage: P.map(len, is_injective=False).list() + sage: P.map(len, is_injective=False).list() # optional - sage.combinat [1, 2, 3, 4] TESTS:: @@ -2225,9 +2225,9 @@ def __contains__(self, x) -> bool: False sage: [4,3,2,1] in P False - sage: Permutation([1,2,3]) in P + sage: Permutation([1,2,3]) in P # optional - sage.combinat False - sage: Permutation([3,2,1]) in P + sage: Permutation([3,2,1]) in P # optional - sage.combinat True """ return x in self.combinatorial_class and self.f(x) @@ -2238,7 +2238,7 @@ def cardinality(self) -> Integer: sage: from sage.combinat.combinat import Permutations_CC sage: P = Permutations_CC(3).filter(lambda x: x.avoids([1,2])) - sage: P.cardinality() + sage: P.cardinality() # optional - sage.combinat 1 """ c = 0 @@ -2252,7 +2252,7 @@ def __iter__(self) -> Iterator: sage: from sage.combinat.combinat import Permutations_CC sage: P = Permutations_CC(3).filter(lambda x: x.avoids([1,2])) - sage: list(P) + sage: list(P) # optional - sage.combinat [[3, 2, 1]] """ for x in self.combinatorial_class: @@ -2481,13 +2481,13 @@ class MapCombinatorialClass(ImageSubobject, CombinatorialClass): EXAMPLES:: - sage: R = SymmetricGroup(10).map(attrcall('reduced_word')) - sage: R.an_element() + sage: R = SymmetricGroup(10).map(attrcall('reduced_word')) # optional - sage.groups + sage: R.an_element() # optional - sage.groups [9, 8, 7, 6, 5, 4, 3, 2] - sage: R.cardinality() + sage: R.cardinality() # optional - sage.groups 3628800 - sage: i = iter(R) - sage: next(i), next(i), next(i) + sage: i = iter(R) # optional - sage.groups + sage: next(i), next(i), next(i) # optional - sage.groups ([], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1]) """ @@ -2495,7 +2495,7 @@ def __init__(self, cc, f, name=None, *, is_injective=True): """ TESTS:: - sage: Partitions(3).map(attrcall('conjugate')) + sage: Partitions(3).map(attrcall('conjugate')) # optional - sage.combinat Image of Partitions of the integer 3 by The map *.conjugate() from Partitions of the integer 3 """ @@ -2625,9 +2625,9 @@ def tuples(S, k, algorithm='itertools'): :: - sage: K. = GF(4, 'a') - sage: mset = [x for x in K if x != 0] - sage: tuples(mset, 2) + sage: K. = GF(4, 'a') # optional - sage.rings.finite_rings + sage: mset = [x for x in K if x != 0] # optional - sage.rings.finite_rings + sage: tuples(mset, 2) # optional - sage.rings.finite_rings [(a, a), (a, a + 1), (a, 1), (a + 1, a), (a + 1, a + 1), (a + 1, 1), (1, a), (1, a + 1), (1, 1)] @@ -2711,16 +2711,16 @@ def number_of_tuples(S, k, algorithm='naive') -> Integer: sage: S = [1,2,3,4,5] sage: number_of_tuples(S,2) 25 - sage: number_of_tuples(S,2, algorithm="gap") + sage: number_of_tuples(S,2, algorithm="gap") # optional - sage.libs.gap 25 sage: S = [1,1,2,3,4,5] sage: number_of_tuples(S,2) 25 - sage: number_of_tuples(S,2, algorithm="gap") + sage: number_of_tuples(S,2, algorithm="gap") # optional - sage.libs.gap 25 sage: number_of_tuples(S,0) 1 - sage: number_of_tuples(S,0, algorithm="gap") + sage: number_of_tuples(S,0, algorithm="gap") # optional - sage.libs.gap 1 """ if algorithm == 'naive': @@ -2772,7 +2772,7 @@ def unordered_tuples(S, k, algorithm='itertools'): We check that this agrees with GAP:: - sage: unordered_tuples(S, 3, algorithm='gap') + sage: unordered_tuples(S, 3, algorithm='gap') # optional - sage.libs.gap [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)] We check the result on strings:: @@ -2780,13 +2780,13 @@ def unordered_tuples(S, k, algorithm='itertools'): sage: S = ["a","b","c"] sage: unordered_tuples(S, 2) [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')] - sage: unordered_tuples(S, 2, algorithm='gap') + sage: unordered_tuples(S, 2, algorithm='gap') # optional - sage.libs.gap [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')] Lastly we check on a multiset:: sage: S = [1,1,2] - sage: unordered_tuples(S, 3) == unordered_tuples(S, 3, 'gap') + sage: unordered_tuples(S, 3) == unordered_tuples(S, 3, 'gap') # optional - sage.libs.gap True sage: unordered_tuples(S, 3) [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)] @@ -2827,16 +2827,16 @@ def number_of_unordered_tuples(S, k, algorithm='naive') -> Integer: sage: S = [1,2,3,4,5] sage: number_of_unordered_tuples(S,2) 15 - sage: number_of_unordered_tuples(S,2, algorithm="gap") + sage: number_of_unordered_tuples(S,2, algorithm="gap") # optional - sage.libs.gap 15 sage: S = [1,1,2,3,4,5] sage: number_of_unordered_tuples(S,2) 15 - sage: number_of_unordered_tuples(S,2, algorithm="gap") + sage: number_of_unordered_tuples(S,2, algorithm="gap") # optional - sage.libs.gap 15 sage: number_of_unordered_tuples(S,0) 1 - sage: number_of_unordered_tuples(S,0, algorithm="gap") + sage: number_of_unordered_tuples(S,0, algorithm="gap") # optional - sage.libs.gap 1 """ if algorithm == 'naive': @@ -2892,7 +2892,7 @@ def unshuffle_iterator(a, one=1) -> Iterator: [(((), (3, 1)), 3/2), (((3,), (1,)), 3/2), (((1,), (3,)), -3/2), (((3, 1), ()), 3/2)] """ - from sage.misc.misc import powerset + from sage.combinat.subset import powerset n = len(a) for I in powerset(range(n)): sorted_I = tuple(sorted(I)) @@ -2936,19 +2936,19 @@ def bell_polynomial(n: Integer, k: Integer): EXAMPLES:: - sage: bell_polynomial(6,2) + sage: bell_polynomial(6,2) # optional - sage.combinat 10*x2^2 + 15*x1*x3 + 6*x0*x4 - sage: bell_polynomial(6,3) + sage: bell_polynomial(6,3) # optional - sage.combinat 15*x1^3 + 60*x0*x1*x2 + 15*x0^2*x3 TESTS: Check that :trac:`18338` is fixed:: - sage: bell_polynomial(0,0).parent() + sage: bell_polynomial(0,0).parent() # optional - sage.combinat Multivariate Polynomial Ring in x over Integer Ring - sage: for n in (0..4): + sage: for n in (0..4): # optional - sage.combinat ....: print([bell_polynomial(n,k).coefficients() for k in (0..n)]) [[1]] [[], [1]] @@ -2999,13 +2999,12 @@ def fibonacci_sequence(start, stop=None, algorithm=None) -> Iterator: EXAMPLES:: - sage: fibs = [i for i in fibonacci_sequence(10, 20)] - sage: fibs + sage: fibs = [i for i in fibonacci_sequence(10, 20)]; fibs # optional - sage.libs.pari [55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181] :: - sage: sum([i for i in fibonacci_sequence(100, 110)]) + sage: sum([i for i in fibonacci_sequence(100, 110)]) # optional - sage.libs.pari 69919376923075308730013 .. SEEALSO:: @@ -3039,26 +3038,25 @@ def fibonacci_xrange(start, stop=None, algorithm='pari') -> Iterator: EXAMPLES:: - sage: fibs_in_some_range = [i for i in fibonacci_xrange(10^7, 10^8)] - sage: len(fibs_in_some_range) + sage: fibs_in_some_range = [i for i in fibonacci_xrange(10^7, 10^8)] # optional - sage.libs.pari + sage: len(fibs_in_some_range) # optional - sage.libs.pari 4 - sage: fibs_in_some_range + sage: fibs_in_some_range # optional - sage.libs.pari [14930352, 24157817, 39088169, 63245986] :: - sage: fibs = [i for i in fibonacci_xrange(10, 100)] - sage: fibs + sage: fibs = [i for i in fibonacci_xrange(10, 100)]; fibs # optional - sage.libs.pari [13, 21, 34, 55, 89] :: - sage: list(fibonacci_xrange(13, 34)) + sage: list(fibonacci_xrange(13, 34)) # optional - sage.libs.pari [13, 21] A solution to the second Project Euler problem:: - sage: sum([i for i in fibonacci_xrange(10^6) if is_even(i)]) + sage: sum([i for i in fibonacci_xrange(10^6) if is_even(i)]) # optional - sage.libs.pari 1089154 .. SEEALSO:: @@ -3116,30 +3114,30 @@ def bernoulli_polynomial(x, n: Integer): EXAMPLES:: sage: y = QQ['y'].0 - sage: bernoulli_polynomial(y, 5) + sage: bernoulli_polynomial(y, 5) # optional - sage.libs.flint y^5 - 5/2*y^4 + 5/3*y^3 - 1/6*y - sage: bernoulli_polynomial(y, 5)(12) + sage: bernoulli_polynomial(y, 5)(12) # optional - sage.libs.flint 199870 - sage: bernoulli_polynomial(12, 5) + sage: bernoulli_polynomial(12, 5) # optional - sage.libs.flint 199870 - sage: bernoulli_polynomial(y^2 + 1, 5) + sage: bernoulli_polynomial(y^2 + 1, 5) # optional - sage.libs.flint y^10 + 5/2*y^8 + 5/3*y^6 - 1/6*y^2 sage: P. = ZZ[] - sage: p = bernoulli_polynomial(t, 6) - sage: p.parent() + sage: p = bernoulli_polynomial(t, 6) # optional - sage.libs.flint + sage: p.parent() # optional - sage.libs.flint Univariate Polynomial Ring in t over Rational Field We verify an instance of the formula which is the origin of the Bernoulli polynomials (and numbers):: sage: power_sum = sum(k^4 for k in range(10)) - sage: 5*power_sum == bernoulli_polynomial(10, 5) - bernoulli(5) + sage: 5*power_sum == bernoulli_polynomial(10, 5) - bernoulli(5) # optional - sage.libs.flint True TESTS:: sage: x = polygen(QQ, 'x') - sage: bernoulli_polynomial(x, 0).parent() + sage: bernoulli_polynomial(x, 0).parent() # optional - sage.libs.flint Univariate Polynomial Ring in x over Rational Field REFERENCES: diff --git a/src/sage/combinat/combinat_cython.pxd b/src/sage/combinat/combinat_cython.pxd index c27be7b0bed..40cae00a781 100644 --- a/src/sage/combinat/combinat_cython.pxd +++ b/src/sage/combinat/combinat_cython.pxd @@ -2,7 +2,4 @@ from sage.libs.gmp.all cimport mpz_t cdef mpz_stirling_s2(mpz_t s, unsigned long n, unsigned long k) -cdef list from_word(list w, list base_set) - cdef list convert(Py_ssize_t* f, Py_ssize_t n) - diff --git a/src/sage/combinat/combinat_cython.pyx b/src/sage/combinat/combinat_cython.pyx index 3d8e8042311..d645dc8a7dd 100644 --- a/src/sage/combinat/combinat_cython.pyx +++ b/src/sage/combinat/combinat_cython.pyx @@ -16,12 +16,16 @@ AUTHORS: Lyndon words, and perfect matchings """ -cimport cython - from cysignals.memory cimport check_allocarray, sig_free from sage.libs.gmp.all cimport * from sage.rings.integer cimport Integer +from sage.misc.lazy_import import LazyImport + +set_partition_iterator = LazyImport('sage.combinat.set_partition_iterator', 'set_partition_iterator', deprecation=35564) +set_partition_iterator_blocks = LazyImport('sage.combinat.set_partition_iterator', 'set_partition_iterator_blocks', deprecation=35564) +linear_extension_iterator = LazyImport('sage.combinat.posets.linear_extension_iterator', 'linear_extension_iterator', deprecation=35564) + cdef void mpz_addmul_alt(mpz_t s, mpz_t t, mpz_t u, unsigned long parity): """ @@ -199,133 +203,6 @@ def lyndon_word_iterator(Py_ssize_t n, Py_ssize_t k): while a[i] == n - 1: i -= 1 -##################################################################### -## Set partition iterators - -@cython.wraparound(False) -@cython.boundscheck(False) -cdef list from_word(list w, list base_set): - cdef list sp = [] - cdef Py_ssize_t i - cdef Py_ssize_t b - for i in range(len(w)): - b = (w[i]) - x = base_set[i] - if len(sp) <= b: - sp.append([x]) - else: - sp[b].append(x) - return sp - -@cython.wraparound(False) -@cython.boundscheck(False) -def set_partition_iterator(base_set): - """ - A fast iterator for the set partitions of the base set, which - returns lists of lists instead of set partitions types. - - EXAMPLES:: - - sage: from sage.combinat.combinat_cython import set_partition_iterator - sage: list(set_partition_iterator([1,-1,x])) - [[[1, -1, x]], - [[1, -1], [x]], - [[1, x], [-1]], - [[1], [-1, x]], - [[1], [-1], [x]]] - """ - cdef list base = list(base_set) - - # Knuth, TAOCP 4A 7.2.1.5, Algorithm H - cdef Py_ssize_t N = len(base) - # H1: initialize - cdef list a = [0] * N - if N <= 1: - yield from_word(a, base) - return - - cdef list b = [1] * N - cdef Py_ssize_t j - cdef Py_ssize_t last = N - 1 - while True: - # H2: visit - yield from_word(a, base) - if a[last] == b[last]: - # H4: find j - j = N - 2 - while a[j] == b[j]: - j -= 1 - # H5: increase a_j - if j == 0: - break - a[j] += 1 - # H6: zero out a_{j+1},...,a_{n-1} - b[last] = b[j] + int(a[j] == b[j]) - j += 1 - while j < N - 1: - a[j] = 0 - b[j] = b[last] - j += 1 - a[last] = 0 - else: - # H3: increase a_{n-1} - a[last] += 1 - -@cython.wraparound(False) -@cython.boundscheck(False) -def _set_partition_block_gen(Py_ssize_t n, Py_ssize_t k, list a): - r""" - Recursively generate set partitions of ``n`` with fixed block - size ``k`` using Algorithm 4.23 from [Rus2003]_. - ``a`` is a list of size ``n``. - - EXAMPLES:: - - sage: from sage.combinat.combinat_cython import _set_partition_block_gen - sage: a = list(range(3)) - sage: for p in _set_partition_block_gen(3, 2, a): - ....: print(p) - [0, 1, 0] - [0, 1, 1] - [0, 0, 1] - """ - cdef Py_ssize_t i - if n == k: - yield a - return - - for i in range(k): - a[n-1] = i - for P in _set_partition_block_gen(n-1, k, a): - yield P - a[n-1] = n-1 - if k > 1: - a[n-1] = k-1 - for P in _set_partition_block_gen(n-1, k-1, a): - yield P - a[n-1] = n-1 - -@cython.wraparound(False) -@cython.boundscheck(False) -def set_partition_iterator_blocks(base_set, Py_ssize_t k): - """ - A fast iterator for the set partitions of the base set into the - specified number of blocks, which returns lists of lists - instead of set partitions types. - - EXAMPLES:: - - sage: from sage.combinat.combinat_cython import set_partition_iterator_blocks - sage: list(set_partition_iterator_blocks([1,-1,x], 2)) - [[[1, x], [-1]], [[1], [-1, x]], [[1, -1], [x]]] - """ - cdef list base = list(base_set) - cdef Py_ssize_t n = len(base) - cdef list a = list(range(n)) - # TODO: implement _set_partition_block_gen as an iterative algorithm - for P in _set_partition_block_gen(n, k, a): - yield from_word( P, base) - ## Perfect matchings iterator def perfect_matchings_iterator(Py_ssize_t n): @@ -410,292 +287,6 @@ cdef list convert(Py_ssize_t* f, Py_ssize_t n): ret.append((i, f[i])) return ret -##################################################################### -## Linear extension iterator - -from copy import copy -def _linear_extension_prepare(D): - r""" - The preprocessing routine in Figure 7 of "Generating Linear - Extensions Fast" by Preusse and Ruskey. - - INPUT: - - - ``D``, the Hasse diagram of a poset - - OUTPUT: - - - a triple ``(le, a, b)``, where ``le`` is the first linear - extension, and ``a`` and ``b`` are lists such that ``a[i]`` and - ``b[i]`` are minimal elements of ``D`` after removing ``a[:i]`` - and ``b[:i]``. - - TESTS:: - - sage: from sage.combinat.combinat_cython import _linear_extension_prepare - sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram - sage: _linear_extension_prepare(D) - ([0, 1, 2, 3, 4], [1, 3], [2, 4]) - - """ - dag_copy = copy(D) # this copy is destroyed during preparation - le = [] - a = [] - b = [] - - # the preprocessing routine found in Figure 7 of - # "Generating Linear Extensions Fast" by - # Pruesse and Ruskey - while dag_copy.num_verts() != 0: - # find all the minimal elements of dag_copy - minimal_elements = dag_copy.sources() - if not minimal_elements: - raise ValueError("the digraph must be acyclic to have linear extensions") - elif len(minimal_elements) == 1: - le.append(minimal_elements[0]) - dag_copy.delete_vertex(minimal_elements[0]) - else: - ap = minimal_elements[0] - bp = minimal_elements[1] - a.append(ap) - b.append(bp) - le.append(ap) - le.append(bp) - dag_copy.delete_vertex(ap) - dag_copy.delete_vertex(bp) - - return (le, a, b) - -@cython.wraparound(False) -@cython.boundscheck(False) -cdef void _linear_extension_switch(list _le, list _a, list _b, list _is_plus, Py_ssize_t i): - """ - This implements the ``Switch`` procedure described on page 7 - of "Generating Linear Extensions Fast" by Pruesse and Ruskey. - - If ``i == -1``, then the sign is changed. Otherwise, then - ``_a[i]`` and ``_b[i]`` are transposed. - - """ - cdef Py_ssize_t a_index, b_index - if i == -1: - _is_plus[0] = not _is_plus[0] - else: - a = _a[i] - b = _b[i] - a_index = _le.index(a) - b_index = _le.index(b) - _le[a_index] = b - _le[b_index] = a - _b[i] = a - _a[i] = b - -@cython.wraparound(False) -@cython.boundscheck(False) -cdef bint _linear_extension_right_a(_D, list _le, list _a, list _b, Py_ssize_t i): - """ - Return ``True`` if and only if ``_a[i]`` is incomparable with the - element to its right in ``_le`` and the element to the right is - not ``_b[i]``. - - This is the ``Right`` function described on page 8 of - "Generating Linear Extensions Fast" by Pruesse and Ruskey. - - :: - - sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram # not tested - sage: _linear_extension_right_a(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 0) # not tested - False - sage: _linear_extension_right_a(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 1) # not tested - False - - """ - cdef Py_ssize_t yindex - x = _a[i] - yindex = _le.index(x) + 1 - if yindex >= len(_le): - return False - y = _le[yindex] - return y != _b[i] and _D.are_incomparable(x, y) - -@cython.wraparound(False) -@cython.boundscheck(False) -cdef bint _linear_extension_right_b(_D, list _le, list _a, list _b, Py_ssize_t i): - """ - Return True if and only if ``_b[i]`` is incomparable with the - elements to its right in ``_le``. - - This is the ``Right`` function described on page 8 of - "Generating Linear Extensions Fast" by Pruesse and Ruskey. - - :: - - sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram # not tested - sage: _linear_extension_right_b(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 0) # not tested - False - sage: _linear_extension_right_b(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 1) # not tested - False - - """ - cdef Py_ssize_t yindex - x = _b[i] - yindex = _le.index(x) + 1 - if yindex >= len(_le): - return False - y = _le[yindex] - return _D.are_incomparable(x, y) - -@cython.wraparound(False) -@cython.boundscheck(False) -def _linear_extension_gen(_D, list _le, list _a, list _b, list _is_plus, Py_ssize_t i): - """ - This a Python version of the GenLE routine found in Figure 8 - of "Generating Linear Extensions Fast" by Pruesse and Ruskey. - - TESTS:: - - sage: from sage.combinat.combinat_cython import _linear_extension_prepare, _linear_extension_gen - sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram - sage: le, a, b = _linear_extension_prepare(D) - sage: [e for e in _linear_extension_gen(D, le, a, b, [True], len(a)-1)] - [[0, 2, 1, 3, 4]] - - """ - cdef int mra, mrb, mla - cdef Py_ssize_t index, index1 - cdef bint typical - if i == -1: - return - - for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): - yield e - mrb = 0 - typical = False - while _linear_extension_right_b(_D, _le, _a, _b, i): - mrb += 1 - # move_right - index = _le.index(_b[i]) - index1 = index + 1 - _le[index] = _le[index1] - _le[index1] = _b[i] - if _is_plus[0]: - yield _le[:] - - for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): - yield e - mra = 0 - while _linear_extension_right_a(_D, _le, _a, _b, i): - typical = True - mra += 1 - # move_right - index = _le.index(_a[i]) - index1 = index+1 - _le[index] = _le[index1] - _le[index1] = _a[i] - if _is_plus[0]: - yield _le[:] - - for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): - yield e - - if typical: - _linear_extension_switch(_le, _a, _b, _is_plus, i-1) - if _is_plus[0]: - yield _le[:] - - for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): - yield e - if mrb % 2 == 1: - mla = mra - 1 - else: - mla = mra + 1 - for _ in range(mla): - # move_left - index = _le.index(_a[i]) - index1 = index-1 - _le[index] = _le[index1] - _le[index1] = _a[i] - if _is_plus[0]: - yield _le[:] - - for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): - yield e - - if typical and (mrb % 2 == 1): - # move_left - index = _le.index(_a[i]) - index1 = index-1 - _le[index] = _le[index1] - _le[index1] = _a[i] - if _is_plus[0]: - yield _le[:] - else: - _linear_extension_switch(_le, _a, _b, _is_plus, i-1) - if _is_plus[0]: - yield _le[:] - for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): - yield e - for _ in range(mrb): - # move_left - index = _le.index(_b[i]) - index1 = index-1 - _le[index] = _le[index1] - _le[index1] = _b[i] - if _is_plus[0]: - yield _le[:] - - for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): - yield e - - -def linear_extension_iterator(D): - """ - Iterate over the linear extensions of the poset. - - The list ``_le`` keeps track of the current linear extensions. The - boolean variable ``is_plus`` keeps track of the "sign". - - INPUT: - - - ``D``, the Hasse diagram of a poset. - - .. WARNING:: - - It is assumed that ``D`` is not modified while the linear - extensions are generated. - - EXAMPLES:: - - sage: from sage.combinat.combinat_cython import linear_extension_iterator - sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram - sage: list(linear_extension_iterator(D)) - [[0, 1, 2, 3, 4], - [0, 2, 1, 3, 4], - [0, 2, 1, 4, 3], - [0, 2, 4, 1, 3], - [0, 1, 2, 4, 3]] - - sage: D = posets.BooleanLattice(3)._hasse_diagram - sage: len(list(linear_extension_iterator(D))) - 48 - - sage: D = posets.AntichainPoset(9)._hasse_diagram - sage: len(list(linear_extension_iterator(D))) == factorial(9) # long time - True - """ - _le, _a, _b = _linear_extension_prepare(D) - _max_pair = len(_a) - 1 - _is_plus = [True] # this is modified by _linear_extension_switch - - yield _le[:] - for e in _linear_extension_gen(D, _le, _a, _b, _is_plus, _max_pair): - yield e - _linear_extension_switch(_le, _a, _b, _is_plus, _max_pair) - if _is_plus[0]: - yield _le[:] - for e in _linear_extension_gen(D, _le, _a, _b, _is_plus, _max_pair): - yield e - ##################################################################### ## Set partition composition @@ -711,7 +302,7 @@ def set_partition_composition(tuple sp1, tuple sp2): sage: sp1 = ((1,-2),(2,-1)) sage: sp2 = ((1,-2),(2,-1)) sage: p, c = set_partition_composition(sp1, sp2) - sage: (SetPartition(p), c) == (SetPartition([[1,-1],[2,-2]]), 0) + sage: (SetPartition(p), c) == (SetPartition([[1,-1],[2,-2]]), 0) # optional - sage.combinat True """ cdef int num_loops = 0 # The number of loops removed diff --git a/src/sage/combinat/combination.py b/src/sage/combinat/combination.py index 42e727c6877..fc8b044d89d 100644 --- a/src/sage/combinat/combination.py +++ b/src/sage/combinat/combination.py @@ -148,15 +148,15 @@ class of combinations of ``mset`` of size ``k``. It is possible to take combinations of Sage objects:: - sage: Combinations([vector([1,1]), vector([2,2]), vector([3,3])], 2).list() + sage: Combinations([vector([1,1]), vector([2,2]), vector([3,3])], 2).list() # optional - sage.modules [[(1, 1), (2, 2)], [(1, 1), (3, 3)], [(2, 2), (3, 3)]] TESTS: We check that the code works even for non mutable objects:: - sage: l = [vector((0,0)), vector((0,1))] - sage: Combinations(l).list() + sage: l = [vector((0,0)), vector((0,1))] # optional - sage.modules + sage: Combinations(l).list() # optional - sage.modules [[], [(0, 0)], [(0, 1)], [(0, 0), (0, 1)]] """ # Check to see if everything in mset is unique @@ -269,7 +269,7 @@ def cardinality(self): sage: Combinations([1,2,3]).cardinality() 8 - sage: Combinations(['a','a','b']).cardinality() + sage: Combinations(['a','a','b']).cardinality() # optional - sage.libs.gap 6 """ c = 0 @@ -431,7 +431,7 @@ def cardinality(self): EXAMPLES:: sage: mset = [1,1,2,3,4,4,5] - sage: Combinations(mset,2).cardinality() + sage: Combinations(mset,2).cardinality() # optional - sage.libs.gap 12 """ from sage.libs.gap.libgap import libgap diff --git a/src/sage/combinat/combinatorial_map.py b/src/sage/combinat/combinatorial_map.py index 01d552498ee..0ff4ffe34bc 100644 --- a/src/sage/combinat/combinatorial_map.py +++ b/src/sage/combinat/combinatorial_map.py @@ -302,9 +302,9 @@ def __call__(self, *args, **kwds): sage: p = Permutation([1,3,2,4]) sage: cm = type(p).left_tableau; cm Combinatorial map: Robinson-Schensted insertion tableau - sage: cm(p) + sage: cm(p) # optional - sage.combinat [[1, 2, 4], [3]] - sage: cm(Permutation([4,3,2,1])) + sage: cm(Permutation([4,3,2,1])) # optional - sage.combinat [[1], [2], [3], [4]] """ if self._inst is not None: diff --git a/src/sage/combinat/composition.py b/src/sage/combinat/composition.py index d030152605b..3b6d51a1b6e 100644 --- a/src/sage/combinat/composition.py +++ b/src/sage/combinat/composition.py @@ -172,18 +172,18 @@ def _ascii_art_(self): """ TESTS:: - sage: ascii_art(Compositions(4).list()) + sage: ascii_art(Compositions(4).list()) # optional - sage.combinat [ * ] [ * ** * * ] [ * * ** *** * ** * ] [ *, * , * , * , **, ** , ***, **** ] - sage: Partitions.options(diagram_str='#', convention="French") - sage: ascii_art(Compositions(4).list()) + sage: Partitions.options(diagram_str='#', convention="French") # optional - sage.combinat + sage: ascii_art(Compositions(4).list()) # optional - sage.combinat [ # ] [ # # # ## ] [ # # ## # # ## ### ] [ #, ##, #, ###, #, ##, #, #### ] - sage: Partitions.options._reset() + sage: Partitions.options._reset() # optional - sage.combinat """ from sage.typeset.ascii_art import ascii_art return ascii_art(self.to_skew_partition()) @@ -192,20 +192,20 @@ def _unicode_art_(self): """ TESTS:: - sage: unicode_art(Compositions(4).list()) + sage: unicode_art(Compositions(4).list()) # optional - sage.combinat ⎡ ┌┐ ⎤ ⎢ ├┤ ┌┬┐ ┌┐ ┌┐ ⎥ ⎢ ├┤ ├┼┘ ┌┼┤ ┌┬┬┐ ├┤ ┌┬┐ ┌┐ ⎥ ⎢ ├┤ ├┤ ├┼┘ ├┼┴┘ ┌┼┤ ┌┼┼┘ ┌┬┼┤ ┌┬┬┬┐ ⎥ ⎣ └┘, └┘ , └┘ , └┘ , └┴┘, └┴┘ , └┴┴┘, └┴┴┴┘ ⎦ - sage: Partitions.options(diagram_str='#', convention="French") - sage: unicode_art(Compositions(4).list()) + sage: Partitions.options(diagram_str='#', convention="French") # optional - sage.combinat + sage: unicode_art(Compositions(4).list()) # optional - sage.combinat ⎡ ┌┐ ⎤ ⎢ ├┤ ┌┐ ┌┐ ┌┬┐ ⎥ ⎢ ├┤ ├┤ ├┼┐ ┌┐ └┼┤ ┌┬┐ ┌┬┬┐ ⎥ ⎢ ├┤ ├┼┐ └┼┤ ├┼┬┐ ├┤ └┼┼┐ └┴┼┤ ┌┬┬┬┐ ⎥ ⎣ └┘, └┴┘, └┘, └┴┴┘, └┘, └┴┘, └┘, └┴┴┴┘ ⎦ - sage: Partitions.options._reset() + sage: Partitions.options._reset() # optional - sage.combinat """ from sage.typeset.unicode_art import unicode_art return unicode_art(self.to_skew_partition()) @@ -254,7 +254,7 @@ def conjugate(self) -> Composition: The ribbon shape of the conjugate of `I` is the conjugate of the ribbon shape of `I`:: - sage: all( I.conjugate().to_skew_partition() + sage: all( I.conjugate().to_skew_partition() # optional - sage.combinat ....: == I.to_skew_partition().conjugate() ....: for I in Compositions(4) ) True @@ -1178,11 +1178,11 @@ def to_partition(self): EXAMPLES:: - sage: Composition([2,1,3]).to_partition() + sage: Composition([2,1,3]).to_partition() # optional - sage.combinat [3, 2, 1] - sage: Composition([4,2,2]).to_partition() + sage: Composition([4,2,2]).to_partition() # optional - sage.combinat [4, 2, 2] - sage: Composition([]).to_partition() + sage: Composition([]).to_partition() # optional - sage.combinat [] """ from sage.combinat.partition import Partition @@ -1202,15 +1202,15 @@ def to_skew_partition(self, overlap=1): EXAMPLES:: - sage: Composition([3,4,1]).to_skew_partition() + sage: Composition([3,4,1]).to_skew_partition() # optional - sage.combinat [6, 6, 3] / [5, 2] - sage: Composition([3,4,1]).to_skew_partition(overlap=0) + sage: Composition([3,4,1]).to_skew_partition(overlap=0) # optional - sage.combinat [8, 7, 3] / [7, 3] - sage: Composition([]).to_skew_partition() + sage: Composition([]).to_skew_partition() # optional - sage.combinat [] / [] - sage: Composition([1,2]).to_skew_partition() + sage: Composition([1,2]).to_skew_partition() # optional - sage.combinat [2, 1] / [] - sage: Composition([2,1]).to_skew_partition() + sage: Composition([2,1]).to_skew_partition() # optional - sage.combinat [2, 2] / [1] """ from sage.combinat.skew_partition import SkewPartition @@ -1264,38 +1264,46 @@ def shuffle_product(self, other, overlap=False): sage: alph = Composition([2,2]) sage: beta = Composition([1,1,3]) - sage: S = alph.shuffle_product(beta); S + sage: S = alph.shuffle_product(beta); S # optional - sage.combinat Shuffle product of [2, 2] and [1, 1, 3] - sage: S.list() - [[2, 2, 1, 1, 3], [2, 1, 2, 1, 3], [2, 1, 1, 2, 3], [2, 1, 1, 3, 2], [1, 2, 2, 1, 3], [1, 2, 1, 2, 3], [1, 2, 1, 3, 2], [1, 1, 2, 2, 3], [1, 1, 2, 3, 2], [1, 1, 3, 2, 2]] + sage: S.list() # optional - sage.combinat + [[2, 2, 1, 1, 3], [2, 1, 2, 1, 3], [2, 1, 1, 2, 3], [2, 1, 1, 3, 2], + [1, 2, 2, 1, 3], [1, 2, 1, 2, 3], [1, 2, 1, 3, 2], [1, 1, 2, 2, 3], + [1, 1, 2, 3, 2], [1, 1, 3, 2, 2]] The *overlapping* shuffle product of `[2,2]` and `[1,1,3]`:: sage: alph = Composition([2,2]) sage: beta = Composition([1,1,3]) - sage: O = alph.shuffle_product(beta, overlap=True); O + sage: O = alph.shuffle_product(beta, overlap=True); O # optional - sage.combinat Overlapping shuffle product of [2, 2] and [1, 1, 3] - sage: O.list() - [[2, 2, 1, 1, 3], [2, 1, 2, 1, 3], [2, 1, 1, 2, 3], [2, 1, 1, 3, 2], [1, 2, 2, 1, 3], [1, 2, 1, 2, 3], [1, 2, 1, 3, 2], [1, 1, 2, 2, 3], [1, 1, 2, 3, 2], [1, 1, 3, 2, 2], [3, 2, 1, 3], [2, 3, 1, 3], [3, 1, 2, 3], [2, 1, 3, 3], [3, 1, 3, 2], [2, 1, 1, 5], [1, 3, 2, 3], [1, 2, 3, 3], [1, 3, 3, 2], [1, 2, 1, 5], [1, 1, 5, 2], [1, 1, 2, 5], [3, 3, 3], [3, 1, 5], [1, 3, 5]] + sage: O.list() # optional - sage.combinat + [[2, 2, 1, 1, 3], [2, 1, 2, 1, 3], [2, 1, 1, 2, 3], [2, 1, 1, 3, 2], + [1, 2, 2, 1, 3], [1, 2, 1, 2, 3], [1, 2, 1, 3, 2], [1, 1, 2, 2, 3], + [1, 1, 2, 3, 2], [1, 1, 3, 2, 2], + [3, 2, 1, 3], [2, 3, 1, 3], [3, 1, 2, 3], [2, 1, 3, 3], [3, 1, 3, 2], + [2, 1, 1, 5], [1, 3, 2, 3], [1, 2, 3, 3], [1, 3, 3, 2], [1, 2, 1, 5], + [1, 1, 5, 2], [1, 1, 2, 5], + [3, 3, 3], [3, 1, 5], [1, 3, 5]] Note that the shuffle product of two compositions can include the same composition more than once since a composition can be a shuffle of two compositions in several ways. For example:: sage: w1 = Composition([1]) - sage: S = w1.shuffle_product(w1); S + sage: S = w1.shuffle_product(w1); S # optional - sage.combinat Shuffle product of [1] and [1] - sage: S.list() + sage: S.list() # optional - sage.combinat [[1, 1], [1, 1]] - sage: O = w1.shuffle_product(w1, overlap=True); O + sage: O = w1.shuffle_product(w1, overlap=True); O # optional - sage.combinat Overlapping shuffle product of [1] and [1] - sage: O.list() + sage: O.list() # optional - sage.combinat [[1, 1], [1, 1], [2]] TESTS:: sage: empty = Composition([]) - sage: empty.shuffle_product(empty).list() + sage: empty.shuffle_product(empty).list() # optional - sage.combinat [[]] """ if overlap: @@ -1392,11 +1400,10 @@ def specht_module(self, base_ring=None): EXAMPLES:: - sage: SM = Composition([1,2,2]).specht_module(QQ) - sage: SM + sage: SM = Composition([1,2,2]).specht_module(QQ); SM # optional - sage.combinat sage.modules Specht module of [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)] over Rational Field - sage: s = SymmetricFunctions(QQ).s() - sage: s(SM.frobenius_image()) + sage: s = SymmetricFunctions(QQ).s() # optional - sage.combinat sage.modules + sage: s(SM.frobenius_image()) # optional - sage.combinat sage.modules s[2, 2, 1] """ from sage.combinat.specht_module import SpechtModule @@ -1421,9 +1428,9 @@ def specht_module_dimension(self, base_ring=None): EXAMPLES:: - sage: Composition([1,2,2]).specht_module_dimension() + sage: Composition([1,2,2]).specht_module_dimension() # optional - sage.combinat sage.modules 5 - sage: Composition([1,2,2]).specht_module_dimension(GF(2)) + sage: Composition([1,2,2]).specht_module_dimension(GF(2)) # optional - sage.combinat sage.modules sage.rings.finite_rings 5 """ from sage.combinat.specht_module import specht_module_rank diff --git a/src/sage/combinat/designs/block_design.py b/src/sage/combinat/designs/block_design.py index 608a06581e1..3f926aa4793 100644 --- a/src/sage/combinat/designs/block_design.py +++ b/src/sage/combinat/designs/block_design.py @@ -401,19 +401,19 @@ def q3_minus_one_matrix(K): sage: from sage.combinat.designs.block_design import q3_minus_one_matrix sage: m = q3_minus_one_matrix(GF(3)) - sage: m.multiplicative_order() == 3**3 - 1 + sage: m.multiplicative_order() == 3**3 - 1 # optional - sage.symbolic True - sage: m = q3_minus_one_matrix(GF(4,'a')) - sage: m.multiplicative_order() == 4**3 - 1 + sage: m = q3_minus_one_matrix(GF(4, 'a')) + sage: m.multiplicative_order() == 4**3 - 1 # optional - sage.symbolic True sage: m = q3_minus_one_matrix(GF(5)) - sage: m.multiplicative_order() == 5**3 - 1 + sage: m.multiplicative_order() == 5**3 - 1 # optional - sage.symbolic True - sage: m = q3_minus_one_matrix(GF(9,'a')) - sage: m.multiplicative_order() == 9**3 - 1 + sage: m = q3_minus_one_matrix(GF(9, 'a')) + sage: m.multiplicative_order() == 9**3 - 1 # optional - sage.symbolic True """ q = K.cardinality() diff --git a/src/sage/combinat/diagram.py b/src/sage/combinat/diagram.py index 2da21bbe3e0..763441213bf 100644 --- a/src/sage/combinat/diagram.py +++ b/src/sage/combinat/diagram.py @@ -615,7 +615,7 @@ def __iter__(self): """ from sage.sets.non_negative_integers import NonNegativeIntegers from sage.categories.cartesian_product import cartesian_product - from sage.misc.misc import subsets + from sage.combinat.subset import subsets # the product of positive integers automatically implements an # an enumeration which allows us to get out of the first column N = NonNegativeIntegers() diff --git a/src/sage/combinat/diagram_algebras.py b/src/sage/combinat/diagram_algebras.py index bd281fdbb77..9f272a5178d 100644 --- a/src/sage/combinat/diagram_algebras.py +++ b/src/sage/combinat/diagram_algebras.py @@ -31,9 +31,10 @@ from sage.structure.unique_representation import UniqueRepresentation from sage.combinat.combinat import bell_number, catalan_number from sage.structure.global_options import GlobalOptions -from sage.combinat.combinat_cython import (set_partition_iterator, perfect_matchings_iterator, +from sage.combinat.combinat_cython import (perfect_matchings_iterator, set_partition_composition) from sage.combinat.set_partition import SetPartitions, AbstractSetPartition +from sage.combinat.set_partition_iterator import set_partition_iterator from sage.combinat.symmetric_group_algebra import SymmetricGroupAlgebra_n from sage.combinat.permutation import Permutations from sage.graphs.graph import Graph @@ -231,7 +232,7 @@ def planar_partitions_rec(X): if len(X) > 1: yield ([X[0]], [X[1]]) return - from sage.misc.misc import powerset + from sage.combinat.subset import powerset from itertools import product for S in powerset(range(len(X)-1)): if not S: @@ -2053,9 +2054,9 @@ def order(self): EXAMPLES:: - sage: q = var('q') - sage: PA = PartitionAlgebra(2, q) - sage: PA.order() + sage: q = var('q') # optional - sage.symbolic + sage: PA = PartitionAlgebra(2, q) # optional - sage.symbolic + sage: PA.order() # optional - sage.symbolic 2 """ return self._k @@ -2412,12 +2413,13 @@ class PartitionAlgebra(DiagramBasis, UnitDiagramMixin): :: - sage: q = var('q') - sage: PA = PartitionAlgebra(2, q); PA + sage: q = var('q') # optional - sage.symbolic + sage: PA = PartitionAlgebra(2, q); PA # optional - sage.symbolic Partition Algebra of rank 2 with parameter q over Symbolic Ring - sage: PA([[1,2],[-2,-1]])^2 == q*PA([[1,2],[-2,-1]]) + sage: PA([[1,2],[-2,-1]])^2 == q*PA([[1,2],[-2,-1]]) # optional - sage.symbolic True - sage: (PA([[2, -2], [1, -1]]) - 2*PA([[-2, -1], [1, 2]]))^2 == (4*q-4)*PA([[1, 2], [-2, -1]]) + PA([[2, -2], [1, -1]]) + sage: ((PA([[2, -2], [1, -1]]) - 2*PA([[-2, -1], [1, 2]]))^2 # optional - sage.symbolic + ....: == (4*q-4)*PA([[1, 2], [-2, -1]]) + PA([[2, -2], [1, -1]])) True The identity element of the partition algebra is the set @@ -2445,21 +2447,22 @@ class PartitionAlgebra(DiagramBasis, UnitDiagramMixin): sage: PA = PartitionAlgebra(2, 5, base_ring=ZZ, prefix='B') sage: PA Partition Algebra of rank 2 with parameter 5 over Integer Ring - sage: (PA([[2, -2], [1, -1]]) - 2*PA([[-2, -1], [1, 2]]))^2 == 16*PA([[-2, -1], [1, 2]]) + PA([[2, -2], [1, -1]]) + sage: ((PA([[2, -2], [1, -1]]) - 2*PA([[-2, -1], [1, 2]]))^2 + ....: == 16*PA([[-2, -1], [1, 2]]) + PA([[2, -2], [1, -1]])) True Symmetric group algebra elements and elements from other subalgebras of the partition algebra (e.g., ``BrauerAlgebra`` and ``TemperleyLiebAlgebra``) can also be coerced into the partition algebra:: - sage: S = SymmetricGroupAlgebra(SR, 2) - sage: B = BrauerAlgebra(2, x, SR) - sage: A = PartitionAlgebra(2, x, SR) - sage: S([2,1])*A([[1,-1],[2,-2]]) + sage: S = SymmetricGroupAlgebra(SR, 2) # optional - sage.symbolic + sage: B = BrauerAlgebra(2, x, SR) # optional - sage.symbolic + sage: A = PartitionAlgebra(2, x, SR) # optional - sage.symbolic + sage: S([2,1]) * A([[1,-1],[2,-2]]) # optional - sage.symbolic P{{-2, 1}, {-1, 2}} - sage: B([[-1,-2],[2,1]]) * A([[1],[-1],[2,-2]]) + sage: B([[-1,-2],[2,1]]) * A([[1],[-1],[2,-2]]) # optional - sage.symbolic P{{-2}, {-1}, {1, 2}} - sage: A([[1],[-1],[2,-2]]) * B([[-1,-2],[2,1]]) + sage: A([[1],[-1],[2,-2]]) * B([[-1,-2],[2,1]]) # optional - sage.symbolic P{{-2, -1}, {1}, {2}} The same is true if the elements come from a subalgebra of a partition @@ -2470,7 +2473,7 @@ class PartitionAlgebra(DiagramBasis, UnitDiagramMixin): sage: S = SymmetricGroupAlgebra(ZZ, 2) sage: B = BrauerAlgebra(2, q, ZZ[q]) sage: A = PartitionAlgebra(3, q, R) - sage: S([2,1])*A([[1,-1],[2,-3],[3,-2]]) + sage: S([2,1]) * A([[1,-1],[2,-3],[3,-2]]) P{{-3, 1}, {-2, 3}, {-1, 2}} sage: A(B([[-1,-2],[2,1]])) P{{-3, 3}, {-2, -1}, {1, 2}} diff --git a/src/sage/combinat/finite_state_machine_generators.py b/src/sage/combinat/finite_state_machine_generators.py index ed5cca2588b..545596db163 100644 --- a/src/sage/combinat/finite_state_machine_generators.py +++ b/src/sage/combinat/finite_state_machine_generators.py @@ -1079,15 +1079,15 @@ def _parse_recursion_equation_(self, equation, base, function, var, EXAMPLES:: - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: transducers._parse_recursion_equation_( + sage: transducers._parse_recursion_equation_( # optional - sage.symbolic ....: f(8*n + 7) == f(2*n + 3) + 5, ....: 2, f, n) RecursionRule(K=3, r=7, k=1, s=3, t=[5]) - sage: transducers._parse_recursion_equation_( + sage: transducers._parse_recursion_equation_( # optional - sage.symbolic ....: f(42) == 5, ....: 2, f, n) {42: [5]} @@ -1096,14 +1096,14 @@ def _parse_recursion_equation_(self, equation, base, function, var, The following tests check that the equations are well-formed:: - sage: transducers._parse_recursion_equation_(f(4*n + 1), 2, f, n) + sage: transducers._parse_recursion_equation_(f(4*n + 1), 2, f, n) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: f(4*n + 1) is not an equation with ==. :: - sage: transducers._parse_recursion_equation_(f(n) + 1 == f(2*n), + sage: transducers._parse_recursion_equation_(f(n) + 1 == f(2*n), # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1111,7 +1111,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n, 5) == 3, + sage: transducers._parse_recursion_equation_(f(2*n, 5) == 3, # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1119,7 +1119,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(1/n) == f(n) + 3, + sage: transducers._parse_recursion_equation_(f(1/n) == f(n) + 3, # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1127,7 +1127,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(n^2 + 5) == 3, + sage: transducers._parse_recursion_equation_(f(n^2 + 5) == 3, # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1135,7 +1135,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(3*n + 5) == f(n) + 7, + sage: transducers._parse_recursion_equation_(f(3*n + 5) == f(n) + 7, # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1143,7 +1143,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(n + 5) == f(n) + 7, + sage: transducers._parse_recursion_equation_(f(n + 5) == f(n) + 7, # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1151,7 +1151,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_( + sage: transducers._parse_recursion_equation_( # optional - sage.symbolic ....: f(2*n + 1) == f(n + 1) + f(n) + 2, ....: 2, f, n) Traceback (most recent call last): @@ -1161,7 +1161,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == sin(n) + 2, + sage: transducers._parse_recursion_equation_(f(2*n + 1) == sin(n) + 2, # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1170,7 +1170,8 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(n) + n + 2, + sage: transducers._parse_recursion_equation_( # optional - sage.symbolic + ....: f(2*n + 1) == f(n) + n + 2, ....: 2, f, n) Traceback (most recent call last): ... @@ -1178,7 +1179,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == sin(n), + sage: transducers._parse_recursion_equation_(f(2*n + 1) == sin(n), # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1186,7 +1187,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(n, 2), + sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(n, 2), # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1194,7 +1195,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(1/n), + sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(1/n), # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1202,7 +1203,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(n^2 + 5), + sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(n^2 + 5), # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1210,7 +1211,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(3*n + 5), + sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(3*n + 5), # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1218,7 +1219,8 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == f((1/2)*n + 5), + sage: transducers._parse_recursion_equation_( # optional - sage.symbolic + ....: f(2*n + 1) == f((1/2)*n + 5), ....: QQ(2), f, n) Traceback (most recent call last): ... @@ -1226,7 +1228,7 @@ def _parse_recursion_equation_(self, equation, base, function, var, :: - sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(2*n + 5), + sage: transducers._parse_recursion_equation_(f(2*n + 1) == f(2*n + 5), # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1432,17 +1434,17 @@ def Recursion(self, recursions, base, function=None, var=None, - The following example computes the Hamming weight of the ternary expansion of integers. :: - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(3*n + 1) == f(n) + 1, ....: f(3*n + 2) == f(n) + 1, ....: f(3*n) == f(n), ....: f(0) == 0], ....: 3, f, n) - sage: T.transitions() + sage: T.transitions() # optional - sage.symbolic [Transition from (0, 0) to (0, 0): 0|-, Transition from (0, 0) to (0, 0): 1|1, Transition from (0, 0) to (0, 0): 2|1] @@ -1450,13 +1452,13 @@ def Recursion(self, recursions, base, function=None, var=None, To illustrate what this transducer does, we consider the example of `n=601`:: - sage: ternary_expansion = 601.digits(base=3) - sage: ternary_expansion + sage: ternary_expansion = 601.digits(base=3) # optional - sage.symbolic + sage: ternary_expansion # optional - sage.symbolic [1, 2, 0, 1, 1, 2] - sage: weight_sequence = T(ternary_expansion) - sage: weight_sequence + sage: weight_sequence = T(ternary_expansion) # optional - sage.symbolic + sage: weight_sequence # optional - sage.symbolic [1, 1, 1, 1, 1] - sage: sum(weight_sequence) + sage: sum(weight_sequence) # optional - sage.symbolic 5 Note that the digit zero does not show up in the output because @@ -1466,24 +1468,24 @@ def Recursion(self, recursions, base, function=None, var=None, - The following example computes the Hamming weight of the non-adjacent form, cf. the :wikipedia:`Non-adjacent_form`. :: - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(4*n + 1) == f(n) + 1, ....: f(4*n - 1) == f(n) + 1, ....: f(2*n) == f(n), ....: f(0) == 0], ....: 2, f, n) - sage: T.transitions() + sage: T.transitions() # optional - sage.symbolic [Transition from (0, 0) to (0, 0): 0|-, Transition from (0, 0) to (1, 1): 1|-, Transition from (1, 1) to (0, 0): 0|1, Transition from (1, 1) to (1, 0): 1|1, Transition from (1, 0) to (1, 1): 0|-, Transition from (1, 0) to (1, 0): 1|-] - sage: [(s.label(), s.final_word_out) + sage: [(s.label(), s.final_word_out) # optional - sage.symbolic ....: for s in T.iter_final_states()] [((0, 0), []), ((1, 1), [1]), @@ -1533,11 +1535,11 @@ def Recursion(self, recursions, base, function=None, var=None, the point of view of this method---is a contradicting recursion. We override this by the parameter ``is_zero``. :: - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: function('f w') + sage: function('f w') # optional - sage.symbolic (f, w) - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(2*n) == f(n) + w(0), ....: f(4*n + 1) == f(n) + w(1, 0), ....: f(4*n - 1) == f(n) + w(-1, 0), @@ -1545,14 +1547,14 @@ def Recursion(self, recursions, base, function=None, var=None, ....: 2, f, n, ....: word_function=w, ....: is_zero=lambda x: sum(x).is_zero()) - sage: T.transitions() + sage: T.transitions() # optional - sage.symbolic [Transition from (0, 0) to (0, 0): 0|0, Transition from (0, 0) to (1, 1): 1|-, Transition from (1, 1) to (0, 0): 0|1,0, Transition from (1, 1) to (1, 0): 1|-1,0, Transition from (1, 0) to (1, 1): 0|-, Transition from (1, 0) to (1, 0): 1|0] - sage: for s in T.iter_states(): + sage: for s in T.iter_states(): # optional - sage.symbolic ....: print("{} {}".format(s, s.final_word_out)) (0, 0) [] (1, 1) [1, 0] @@ -1580,16 +1582,16 @@ def Recursion(self, recursions, base, function=None, var=None, - Here is an artificial example where some of the `s` are negative:: - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(2*n + 1) == f(n-1) + 1, ....: f(2*n) == f(n), ....: f(1) == 1, ....: f(0) == 0], 2, f, n) - sage: T.transitions() + sage: T.transitions() # optional - sage.symbolic [Transition from (0, 0) to (0, 0): 0|-, Transition from (0, 0) to (1, 1): 1|-, Transition from (1, 1) to (-1, 1): 0|1, @@ -1600,7 +1602,7 @@ def Recursion(self, recursions, base, function=None, var=None, Transition from (-1, 2) to (0, 0): 1|1, Transition from (1, 2) to (-1, 2): 0|1, Transition from (1, 2) to (1, 2): 1|1] - sage: [(s.label(), s.final_word_out) + sage: [(s.label(), s.final_word_out) # optional - sage.symbolic ....: for s in T.iter_final_states()] [((0, 0), []), ((1, 1), [1]), @@ -1611,7 +1613,7 @@ def Recursion(self, recursions, base, function=None, var=None, - Abelian complexity of the paperfolding sequence (cf. [HKP2015]_, Example 2.8):: - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(4*n) == f(2*n), ....: f(4*n+2) == f(2*n+1)+1, ....: f(16*n+1) == f(8*n+1), @@ -1621,7 +1623,7 @@ def Recursion(self, recursions, base, function=None, var=None, ....: f(1) == 2, f(0) == 0] ....: + [f(16*n+jj) == f(2*n+1)+2 for jj in [3,7,9,13]], ....: 2, f, n) - sage: T.transitions() + sage: T.transitions() # optional - sage.symbolic [Transition from (0, 0) to (0, 1): 0|-, Transition from (0, 0) to (1, 1): 1|-, Transition from (0, 1) to (0, 1): 0|-, @@ -1642,7 +1644,7 @@ def Recursion(self, recursions, base, function=None, var=None, Transition from (7, 3) to (2, 1): 1|1, Transition from (2, 1) to (1, 1): 0|1, Transition from (2, 1) to (2, 1): 1|-] - sage: for s in T.iter_states(): + sage: for s in T.iter_states(): # optional - sage.symbolic ....: print("{} {}".format(s, s.final_word_out)) (0, 0) [] (0, 1) [] @@ -1654,52 +1656,52 @@ def Recursion(self, recursions, base, function=None, var=None, (3, 3) [2, 2] (7, 3) [2, 2] (2, 1) [1, 2] - sage: list(sum(T(n.bits())) for n in srange(1, 21)) + sage: list(sum(T(n.bits())) for n in srange(1, 21)) # optional - sage.symbolic [2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, 4, 3, 4, 5, 6, 5] - We now demonstrate the use of the ``output_rings`` parameter. If no ``output_rings`` are specified, the output labels are converted into ``ZZ``:: - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(2*n + 1) == f(n) + 1, ....: f(2*n) == f(n), ....: f(0) == 2], ....: 2, f, n) - sage: for t in T.transitions(): + sage: for t in T.transitions(): # optional - sage.symbolic ....: print([x.parent() for x in t.word_out]) [] [Integer Ring] - sage: [x.parent() for x in T.states()[0].final_word_out] + sage: [x.parent() for x in T.states()[0].final_word_out] # optional - sage.symbolic [Integer Ring] In contrast, if ``output_rings`` is set to the empty list, the results are not converted:: - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(2*n + 1) == f(n) + 1, ....: f(2*n) == f(n), ....: f(0) == 2], ....: 2, f, n, output_rings=[]) - sage: for t in T.transitions(): + sage: for t in T.transitions(): # optional - sage.symbolic ....: print([x.parent() for x in t.word_out]) [] [Symbolic Ring] - sage: [x.parent() for x in T.states()[0].final_word_out] + sage: [x.parent() for x in T.states()[0].final_word_out] # optional - sage.symbolic [Symbolic Ring] Finally, we use a somewhat questionable conversion:: - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.rings.finite_rings sage.symbolic ....: f(2*n + 1) == f(n) + 1, ....: f(2*n) == f(n), ....: f(0) == 0], ....: 2, f, n, output_rings=[GF(5)]) - sage: for t in T.transitions(): + sage: for t in T.transitions(): # optional - sage.rings.finite_rings sage.symbolic ....: print([x.parent() for x in t.word_out]) [] [Finite Field of size 5] @@ -1726,11 +1728,11 @@ def Recursion(self, recursions, base, function=None, var=None, The following tests fail due to missing or superfluous recursions or initial conditions. :: - sage: var('n') + sage: var('n') # optional - sage.symbolic n - sage: function('f') + sage: function('f') # optional - sage.symbolic f - sage: transducers.Recursion([f(2*n) == f(n)], + sage: transducers.Recursion([f(2*n) == f(n)], # optional - sage.symbolic ....: 2, f, n) Traceback (most recent call last): ... @@ -1739,9 +1741,9 @@ def Recursion(self, recursions, base, function=None, var=None, :: - sage: transducers.Recursion([f(2*n + 1) == f(n), + sage: transducers.Recursion([f(2*n + 1) == f(n), # optional - sage.symbolic ....: f(4*n) == f(2*n) + 1, - ....: f(2*n) == f(n) +1], + ....: f(2*n) == f(n) + 1], ....: 2, f, n) Traceback (most recent call last): ... @@ -1749,7 +1751,7 @@ def Recursion(self, recursions, base, function=None, var=None, :: - sage: transducers.Recursion([f(2*n + 1) == f(n) + 1, + sage: transducers.Recursion([f(2*n + 1) == f(n) + 1, # optional - sage.symbolic ....: f(2*n) == f(n), ....: f(0) == 0, ....: f(42) == 42], 2, f, n) @@ -1759,7 +1761,7 @@ def Recursion(self, recursions, base, function=None, var=None, :: - sage: transducers.Recursion([f(2*n + 1) == f(n) + 1, + sage: transducers.Recursion([f(2*n + 1) == f(n) + 1, # optional - sage.symbolic ....: f(2*n) == f(n - 2) + 4, ....: f(0) == 0], 2, f, n) Traceback (most recent call last): @@ -1769,7 +1771,7 @@ def Recursion(self, recursions, base, function=None, var=None, Here is an example of a transducer with a conflicting rule (it cannot hold for `n = 0`):: - sage: T = transducers.Recursion([ + sage: T = transducers.Recursion([ # optional - sage.symbolic ....: f(2*n + 1) == f(n - 1), ....: f(2*n) == f(n) + 1, ....: f(1) == 1, diff --git a/src/sage/combinat/free_module.py b/src/sage/combinat/free_module.py index 746b0079b9e..4887720d1c1 100644 --- a/src/sage/combinat/free_module.py +++ b/src/sage/combinat/free_module.py @@ -151,7 +151,7 @@ class CombinatorialFreeModule(UniqueRepresentation, Module, IndexedGenerators): The constructed module is in the category of modules with basis over the base ring:: - sage: CombinatorialFreeModule(QQ, Partitions()).category() + sage: CombinatorialFreeModule(QQ, Partitions()).category() # optional - sage.combinat Category of vector spaces with basis over Rational Field If furthermore the index set is finite (i.e. in the category @@ -160,7 +160,7 @@ class CombinatorialFreeModule(UniqueRepresentation, Module, IndexedGenerators): sage: CombinatorialFreeModule(QQ, [1,2,3,4]).category() Category of finite dimensional vector spaces with basis over Rational Field - sage: CombinatorialFreeModule(QQ, Partitions(3), + sage: CombinatorialFreeModule(QQ, Partitions(3), # optional - sage.combinat ....: category=Algebras(QQ).WithBasis()).category() Category of finite dimensional algebras with basis over Rational Field @@ -252,11 +252,11 @@ class CombinatorialFreeModule(UniqueRepresentation, Module, IndexedGenerators): TESTS:: - sage: XQ = SchubertPolynomialRing(QQ) - sage: XZ = SchubertPolynomialRing(ZZ) - sage: XQ == XZ + sage: XQ = SchubertPolynomialRing(QQ) # optional - sage.combinat + sage: XZ = SchubertPolynomialRing(ZZ) # optional - sage.combinat + sage: XQ == XZ # optional - sage.combinat False - sage: XQ == XQ + sage: XQ == XQ # optional - sage.combinat True We check that issue :trac:`28681` is fixed:: @@ -288,16 +288,16 @@ def __classcall_private__(cls, base_ring, basis_keys=None, category=None, We check that the category is properly straightened:: sage: F = CombinatorialFreeModule(QQ, ['a','b']) - sage: F1 = CombinatorialFreeModule(QQ, ['a','b'], category = ModulesWithBasis(QQ)) - sage: F2 = CombinatorialFreeModule(QQ, ['a','b'], category = [ModulesWithBasis(QQ)]) - sage: F3 = CombinatorialFreeModule(QQ, ['a','b'], category = (ModulesWithBasis(QQ),)) - sage: F4 = CombinatorialFreeModule(QQ, ['a','b'], category = (ModulesWithBasis(QQ),CommutativeAdditiveSemigroups())) - sage: F5 = CombinatorialFreeModule(QQ, ['a','b'], category = (ModulesWithBasis(QQ),Category.join((LeftModules(QQ), RightModules(QQ))))) + sage: F1 = CombinatorialFreeModule(QQ, ['a','b'], category=ModulesWithBasis(QQ)) + sage: F2 = CombinatorialFreeModule(QQ, ['a','b'], category=[ModulesWithBasis(QQ)]) + sage: F3 = CombinatorialFreeModule(QQ, ['a','b'], category=(ModulesWithBasis(QQ),)) + sage: F4 = CombinatorialFreeModule(QQ, ['a','b'], category=(ModulesWithBasis(QQ),CommutativeAdditiveSemigroups())) + sage: F5 = CombinatorialFreeModule(QQ, ['a','b'], category=(ModulesWithBasis(QQ),Category.join((LeftModules(QQ), RightModules(QQ))))) sage: F6 = CombinatorialFreeModule(QQ, ['a','b'], category=ModulesWithBasis(QQ).FiniteDimensional()) sage: F1 is F, F2 is F, F3 is F, F4 is F, F5 is F, F6 is F (True, True, True, True, True, True) - sage: G = CombinatorialFreeModule(QQ, ['a','b'], category = AlgebrasWithBasis(QQ)) + sage: G = CombinatorialFreeModule(QQ, ['a','b'], category=AlgebrasWithBasis(QQ)) sage: F is G False """ @@ -347,21 +347,21 @@ def element_class(self): EXAMPLES:: - sage: A = Algebras(QQ).WithBasis().example(); A + sage: A = Algebras(QQ).WithBasis().example(); A # optional - sage.combinat An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field - sage: A.element_class.mro() + sage: A.element_class.mro() # optional - sage.combinat [, , ...] - sage: a,b,c = A.algebra_generators() - sage: a * b + sage: a,b,c = A.algebra_generators() # optional - sage.combinat + sage: a * b # optional - sage.combinat B[word: ab] TESTS:: - sage: A.__class__.element_class.__module__ + sage: A.__class__.element_class.__module__ # optional - sage.combinat 'sage.combinat.free_module' """ return self.__make_element_class__(self.Element, @@ -385,12 +385,13 @@ def __init__(self, R, basis_keys=None, element_class=None, category=None, sage: F.category() Category of finite dimensional algebras with basis over Rational Field - sage: F = CombinatorialFreeModule(GF(3), ['a','b','c'], - ....: category=(Modules(GF(3)).WithBasis(), Semigroups())) - sage: F.category() - Join of Category of finite semigroups and Category of finite dimensional vector spaces with basis over Finite Field of size 3 + sage: F = CombinatorialFreeModule(GF(3), ['a','b','c'], # optional - sage.rings.finite_rings + ....: category=(Modules(GF(3)).WithBasis(), Semigroups())) + sage: F.category() # optional - sage.rings.finite_rings + Join of Category of finite semigroups + and Category of finite dimensional vector spaces with basis over Finite Field of size 3 - sage: F = CombinatorialFreeModule(QQ, ['a','b','c'], category = FiniteDimensionalModulesWithBasis(QQ)) + sage: F = CombinatorialFreeModule(QQ, ['a','b','c'], category=FiniteDimensionalModulesWithBasis(QQ)) sage: F.basis() Finite family {'a': B['a'], 'b': B['b'], 'c': B['c']} sage: F.category() @@ -518,8 +519,8 @@ def _ascii_art_term(self, m): TESTS:: - sage: R = NonCommutativeSymmetricFunctions(QQ).R() - sage: ascii_art(R.one()) # indirect doctest + sage: R = NonCommutativeSymmetricFunctions(QQ).R() # optional - sage.combinat + sage: ascii_art(R.one()) # indirect doctest # optional - sage.combinat 1 """ try: @@ -535,8 +536,8 @@ def _unicode_art_term(self, m): TESTS:: - sage: R = NonCommutativeSymmetricFunctions(QQ).R() - sage: unicode_art(R.one()) # indirect doctest + sage: R = NonCommutativeSymmetricFunctions(QQ).R() # optional - sage.combinat + sage: unicode_art(R.one()) # indirect doctest # optional - sage.combinat 1 """ try: @@ -620,26 +621,26 @@ def _element_constructor_(self, x): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ,["a", "b"]) + sage: F = CombinatorialFreeModule(QQ, ["a", "b"]) sage: F(F.monomial("a")) # indirect doctest B['a'] Do not rely on the following feature which may be removed in the future:: - sage: QS3 = SymmetricGroupAlgebra(QQ,3) - sage: QS3([2,3,1]) # indirect doctest + sage: QS3 = SymmetricGroupAlgebra(QQ,3) # optional - sage.combinat + sage: QS3([2,3,1]) # indirect doctest # optional - sage.combinat [2, 3, 1] instead, use:: - sage: P = QS3.basis().keys() - sage: QS3.monomial(P([2,3,1])) # indirect doctest + sage: P = QS3.basis().keys() # optional - sage.combinat + sage: QS3.monomial(P([2,3,1])) # indirect doctest # optional - sage.combinat [2, 3, 1] or:: - sage: B = QS3.basis() - sage: B[P([2,3,1])] + sage: B = QS3.basis() # optional - sage.combinat + sage: B[P([2,3,1])] # optional - sage.combinat [2, 3, 1] TODO: The symmetric group algebra (and in general, @@ -691,17 +692,17 @@ def _element_constructor_(self, x): Here is a real life example illustrating that this yielded mathematically wrong results:: - sage: S = SymmetricFunctions(QQ) - sage: s = S.s(); p = S.p() - sage: ss = tensor([s,s]); pp = tensor([p,p]) - sage: a = tensor((s[2],s[2])) + sage: S = SymmetricFunctions(QQ) # optional - sage.combinat + sage: s = S.s(); p = S.p() # optional - sage.combinat + sage: ss = tensor([s,s]); pp = tensor([p,p]) # optional - sage.combinat + sage: a = tensor((s[2],s[2])) # optional - sage.combinat The following originally used to yield ``p[[2]] # p[[2]]``, and if there was no natural coercion between ``s`` and ``p``, this would raise a ``NotImplementedError``. Since :trac:`15305`, this takes the coercion between ``s`` and ``p`` and lifts it to the tensor product. :: - sage: pp(a) + sage: pp(a) # optional - sage.combinat 1/4*p[1, 1] # p[1, 1] + 1/4*p[1, 1] # p[2] + 1/4*p[2] # p[1, 1] + 1/4*p[2] # p[2] General extensions of the ground ring should probably be reintroduced @@ -715,8 +716,8 @@ def _element_constructor_(self, x): Conversion from the ground ring is implemented for algebras:: - sage: QS3 = SymmetricGroupAlgebra(QQ,3) - sage: QS3(2) + sage: QS3 = SymmetricGroupAlgebra(QQ,3) # optional - sage.combinat + sage: QS3(2) # optional - sage.combinat 2*[1, 2, 3] """ R = self.base_ring() @@ -797,8 +798,8 @@ def _first_ngens(self, n): sage: C._first_ngens(3) (B[0], B[1], B[-1]) - sage: R. = FreeAlgebra(QQ, 2) - sage: x,y + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat + sage: x,y # optional - sage.combinat (x, y) """ try: @@ -834,13 +835,13 @@ def _coerce_map_from_(self, R): sage: C.has_coerce_map_from(CQ) False - sage: CF2 = CombinatorialFreeModule(GF(2), Set([1,2])) - sage: CF2.has_coerce_map_from(C) + sage: CF2 = CombinatorialFreeModule(GF(2), Set([1,2])) # optional - sage.rings.finite_rings + sage: CF2.has_coerce_map_from(C) # optional - sage.rings.finite_rings True - sage: c = C.monomial(1) - sage: CF2(2*c) + sage: c = C.monomial(1) # optional - sage.rings.finite_rings + sage: CF2(2*c) # optional - sage.rings.finite_rings 0 - sage: CF2(3*c) + sage: CF2(3*c) # optional - sage.rings.finite_rings B[1] """ if isinstance(R, CombinatorialFreeModule): @@ -876,8 +877,8 @@ def dimension(self): :: - sage: s = SymmetricFunctions(QQ).schur() - sage: s.dimension() + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: s.dimension() # optional - sage.combinat +Infinity """ return self._indices.cardinality() @@ -892,11 +893,11 @@ def is_exact(self): EXAMPLES:: - sage: GroupAlgebra(GL(3, GF(7))).is_exact() + sage: GroupAlgebra(GL(3, GF(7))).is_exact() # optional - sage.groups sage.rings.finite_rings True - sage: GroupAlgebra(GL(3, GF(7)), RR).is_exact() + sage: GroupAlgebra(GL(3, GF(7)), RR).is_exact() # optional - sage.groups sage.rings.finite_rings False - sage: GroupAlgebra(GL(3, pAdicRing(7))).is_exact() # not implemented correctly (not my fault)! + sage: GroupAlgebra(GL(3, pAdicRing(7))).is_exact() # not implemented correctly (not my fault)! # optional - sage.groups sage.rings.padics False """ # The index set may not have a check for exactness @@ -926,11 +927,11 @@ def set_order(self, order): EXAMPLES:: - sage: QS2 = SymmetricGroupAlgebra(QQ,2) - sage: b = list(QS2.basis().keys()) - sage: b.reverse() - sage: QS2.set_order(b) - sage: QS2.get_order() + sage: QS2 = SymmetricGroupAlgebra(QQ,2) # optional - sage.combinat + sage: b = list(QS2.basis().keys()) # optional - sage.combinat + sage: b.reverse() # optional - sage.combinat + sage: QS2.set_order(b) # optional - sage.combinat + sage: QS2.get_order() # optional - sage.combinat [[2, 1], [1, 2]] """ self._order = order @@ -944,8 +945,8 @@ def get_order(self): EXAMPLES:: - sage: QS2 = SymmetricGroupAlgebra(QQ,2) - sage: QS2.get_order() # note: order changed on 2009-03-13 + sage: QS2 = SymmetricGroupAlgebra(QQ,2) # optional - sage.combinat + sage: QS2.get_order() # note: order changed on 2009-03-13 # optional - sage.combinat [[2, 1], [1, 2]] """ if self._order is None: @@ -1001,11 +1002,11 @@ def from_vector(self, vector, order=None, coerce=True): EXAMPLES:: - sage: QS3 = SymmetricGroupAlgebra(QQ, 3) - sage: b = QS3.from_vector(vector((2, 0, 0, 0, 0, 4))); b + sage: QS3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat + sage: b = QS3.from_vector(vector((2, 0, 0, 0, 0, 4))); b # optional - sage.combinat 2*[1, 2, 3] + 4*[3, 2, 1] - sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) - sage: a == b + sage: a = 2*QS3([1,2,3]) + 4*QS3([3,2,1]) # optional - sage.combinat + sage: a == b # optional - sage.combinat True """ if order is None: @@ -1057,7 +1058,7 @@ def linear_combination(self, iter_of_elements_coeff, factor_on_left=True): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ,[1,2]) + sage: F = CombinatorialFreeModule(QQ, [1,2]) sage: f = F.an_element(); f 2*B[1] + 2*B[2] sage: F.linear_combination( (f,i) for i in range(5) ) @@ -1132,8 +1133,8 @@ def _sum_of_monomials(self, indices): sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) sage: F._sum_of_monomials(['a', 'b', 'b']) B['a'] + 2*B['b'] - sage: F = CombinatorialFreeModule(GF(3), ['a', 'b', 'c']) - sage: F._sum_of_monomials(['a', 'b', 'b', 'b']) + sage: F = CombinatorialFreeModule(GF(3), ['a', 'b', 'c']) # optional - sage.rings.finite_rings + sage: F._sum_of_monomials(['a', 'b', 'b', 'b']) # optional - sage.rings.finite_rings B['a'] """ R = self.base_ring() @@ -1208,26 +1209,26 @@ def _from_dict(self, d, coerce=False, remove_zeros=True): EXAMPLES:: - sage: e = SymmetricFunctions(QQ).elementary() - sage: s = SymmetricFunctions(QQ).schur() - sage: a = e([2,1]) + e([1,1,1]); a + sage: e = SymmetricFunctions(QQ).elementary() # optional - sage.combinat + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: a = e([2,1]) + e([1,1,1]); a # optional - sage.combinat e[1, 1, 1] + e[2, 1] - sage: s._from_dict(a.monomial_coefficients()) + sage: s._from_dict(a.monomial_coefficients()) # optional - sage.combinat s[1, 1, 1] + s[2, 1] If the optional argument ``coerce`` is ``True``, then the coefficients are coerced into the base ring of ``self``:: - sage: part = Partition([2,1]) - sage: d = {part:1} - sage: a = s._from_dict(d,coerce=True); a + sage: part = Partition([2,1]) # optional - sage.combinat + sage: d = {part: 1} # optional - sage.combinat + sage: a = s._from_dict(d, coerce=True); a # optional - sage.combinat s[2, 1] - sage: a.coefficient(part).parent() + sage: a.coefficient(part).parent() # optional - sage.combinat Rational Field With ``remove_zeros=True``, zero coefficients are removed:: - sage: s._from_dict({part:0}) + sage: s._from_dict({part: 0}) # optional - sage.combinat 0 .. WARNING:: @@ -1236,7 +1237,7 @@ def _from_dict(self, d, coerce=False, remove_zeros=True): coefficient of the dictionary is zero. Otherwise, this may lead to illegal results:: - sage: list(s._from_dict({part:0}, remove_zeros=False)) + sage: list(s._from_dict({part: 0}, remove_zeros=False)) # optional - sage.combinat [([2, 1], 0)] """ assert isinstance(d, dict) @@ -1262,7 +1263,8 @@ class CombinatorialFreeModule_Tensor(CombinatorialFreeModule): F # G sage: T.category() - Category of tensor products of finite dimensional modules with basis over Integer Ring + Category of tensor products of + finite dimensional modules with basis over Integer Ring sage: T.construction() # todo: not implemented [tensor, ] @@ -1275,7 +1277,8 @@ class CombinatorialFreeModule_Tensor(CombinatorialFreeModule): The basis of T is indexed by tuples of basis indices of F and G:: sage: T.basis().keys() - Image of Cartesian product of {1, 2}, {3, 4} by The map from Cartesian product of {1, 2}, {3, 4} + Image of Cartesian product of {1, 2}, {3, 4} + by The map from Cartesian product of {1, 2}, {3, 4} sage: T.basis().keys().list() [(1, 3), (1, 4), (2, 3), (2, 4)] @@ -1424,9 +1427,9 @@ def _ascii_art_(self, term): """ TESTS:: - sage: R = NonCommutativeSymmetricFunctions(QQ).R() - sage: Partitions.options(diagram_str="#", convention="french") - sage: s = ascii_art(tensor((R[1,2], R[3,1,2]))); s + sage: R = NonCommutativeSymmetricFunctions(QQ).R() # optional - sage.combinat + sage: Partitions.options(diagram_str="#", convention="french") # optional - sage.combinat + sage: s = ascii_art(tensor((R[1,2], R[3,1,2]))); s # optional - sage.combinat R # R # ### ## # @@ -1434,7 +1437,7 @@ def _ascii_art_(self, term): Check that the breakpoints are correct (:trac:`29202`):: - sage: s._breakpoints + sage: s._breakpoints # optional - sage.combinat [6] """ if hasattr(self, "_print_options"): @@ -1453,9 +1456,9 @@ def _unicode_art_(self, term): """ TESTS:: - sage: R = NonCommutativeSymmetricFunctions(QQ).R() - sage: Partitions.options(diagram_str="#", convention="french") - sage: s = unicode_art(tensor((R[1,2], R[3,1,2]))); s + sage: R = NonCommutativeSymmetricFunctions(QQ).R() # optional - sage.combinat + sage: Partitions.options(diagram_str="#", convention="french") # optional - sage.combinat + sage: s = unicode_art(tensor((R[1,2], R[3,1,2]))); s # optional - sage.combinat R ⊗ R ┌┐ ┌┬┬┐ ├┼┐ └┴┼┤ @@ -1464,7 +1467,7 @@ def _unicode_art_(self, term): Check that the breakpoints are correct (:trac:`29202`):: - sage: s._breakpoints + sage: s._breakpoints # optional - sage.combinat [7] """ if hasattr(self, "_print_options"): @@ -1548,22 +1551,26 @@ def tensor_constructor(self, modules): sage: G = CombinatorialFreeModule(ZZ, [3,4]); G.rename("G") sage: H = CombinatorialFreeModule(ZZ, [5,6]); H.rename("H") - sage: f = F.monomial(1) + 2 * F.monomial(2) - sage: g = 2*G.monomial(3) + G.monomial(4) - sage: h = H.monomial(5) + H.monomial(6) - sage: FG = tensor([F, G ]) + sage: f = F.monomial(1) + 2*F.monomial(2) + sage: g = 2*G.monomial(3) + G.monomial(4) + sage: h = H.monomial(5) + H.monomial(6) + sage: FG = tensor([F, G]) sage: phi_fg = FG.tensor_constructor((F, G)) - sage: phi_fg(f,g) + sage: phi_fg(f, g) 2*B[1] # B[3] + B[1] # B[4] + 4*B[2] # B[3] + 2*B[2] # B[4] sage: FGH = tensor([F, G, H]) sage: phi_fgh = FGH.tensor_constructor((F, G, H)) sage: phi_fgh(f, g, h) - 2*B[1] # B[3] # B[5] + 2*B[1] # B[3] # B[6] + B[1] # B[4] # B[5] + B[1] # B[4] # B[6] + 4*B[2] # B[3] # B[5] + 4*B[2] # B[3] # B[6] + 2*B[2] # B[4] # B[5] + 2*B[2] # B[4] # B[6] + 2*B[1] # B[3] # B[5] + 2*B[1] # B[3] # B[6] + B[1] # B[4] # B[5] + + B[1] # B[4] # B[6] + 4*B[2] # B[3] # B[5] + 4*B[2] # B[3] # B[6] + + 2*B[2] # B[4] # B[5] + 2*B[2] # B[4] # B[6] sage: phi_fg_h = FGH.tensor_constructor((FG, H)) sage: phi_fg_h(phi_fg(f, g), h) - 2*B[1] # B[3] # B[5] + 2*B[1] # B[3] # B[6] + B[1] # B[4] # B[5] + B[1] # B[4] # B[6] + 4*B[2] # B[3] # B[5] + 4*B[2] # B[3] # B[6] + 2*B[2] # B[4] # B[5] + 2*B[2] # B[4] # B[6] + 2*B[1] # B[3] # B[5] + 2*B[1] # B[3] # B[6] + B[1] # B[4] # B[5] + + B[1] # B[4] # B[6] + 4*B[2] # B[3] # B[5] + 4*B[2] # B[3] # B[6] + + 2*B[2] # B[4] # B[5] + 2*B[2] # B[4] # B[6] """ assert(module in ModulesWithBasis(self.base_ring()) for module in modules) assert(tensor(modules) == self) @@ -1727,7 +1734,9 @@ class CombinatorialFreeModule_CartesianProduct(CombinatorialFreeModule): sage: S F (+) G sage: S.basis() - Lazy family (Term map from Disjoint union of Family ({4, 5}, {4, 6}) to F (+) G(i))_{i in Disjoint union of Family ({4, 5}, {4, 6})} + Lazy family (Term map + from Disjoint union of Family ({4, 5}, {4, 6}) + to F (+) G(i))_{i in Disjoint union of Family ({4, 5}, {4, 6})} Note that the indices of the basis elements of F and G intersect non trivially. This is handled by forcing the union to be disjoint:: @@ -1737,19 +1746,19 @@ class CombinatorialFreeModule_CartesianProduct(CombinatorialFreeModule): We now compute the Cartesian product of elements of free modules:: - sage: f = F.monomial(4) + 2 * F.monomial(5) - sage: g = 2*G.monomial(4) + G.monomial(6) - sage: h = H.monomial(4) + H.monomial(7) - sage: cartesian_product([f,g]) + sage: f = F.monomial(4) + 2*F.monomial(5) + sage: g = 2*G.monomial(4) + G.monomial(6) + sage: h = H.monomial(4) + H.monomial(7) + sage: cartesian_product([f, g]) B[(0, 4)] + 2*B[(0, 5)] + 2*B[(1, 4)] + B[(1, 6)] - sage: cartesian_product([f,g,h]) + sage: cartesian_product([f, g, h]) B[(0, 4)] + 2*B[(0, 5)] + 2*B[(1, 4)] + B[(1, 6)] + B[(2, 4)] + B[(2, 7)] - sage: cartesian_product([f,g,h]).parent() + sage: cartesian_product([f, g, h]).parent() F (+) G (+) H TODO: choose an appropriate semantic for Cartesian products of Cartesian products (associativity?):: - sage: S = cartesian_product([cartesian_product([F, G]), H]) # todo: not implemented + sage: S = cartesian_product([cartesian_product([F, G]), H]) # todo: not implemented F (+) G (+) H """ @@ -1881,8 +1890,8 @@ def _cartesian_product_of_elements(self, elements): sage: F = CombinatorialFreeModule(ZZ, [4,5]); F.rename("F") sage: G = CombinatorialFreeModule(ZZ, [4,6]); G.rename("G") sage: S = cartesian_product([F, G]) - sage: f = F.monomial(4) + 2 * F.monomial(5) - sage: g = 2*G.monomial(4) + G.monomial(6) + sage: f = F.monomial(4) + 2*F.monomial(5) + sage: g = 2*G.monomial(4) + G.monomial(6) sage: S._cartesian_product_of_elements([f, g]) B[(0, 4)] + 2*B[(0, 5)] + 2*B[(1, 4)] + B[(1, 6)] sage: S._cartesian_product_of_elements([f, g]).parent() == S diff --git a/src/sage/combinat/integer_vector.py b/src/sage/combinat/integer_vector.py index 9f01bfd787d..503f802847a 100644 --- a/src/sage/combinat/integer_vector.py +++ b/src/sage/combinat/integer_vector.py @@ -92,11 +92,11 @@ def is_gale_ryser(r,s): EXAMPLES:: sage: from sage.combinat.integer_vector import is_gale_ryser - sage: is_gale_ryser([4,2,2],[3,3,1,1]) + sage: is_gale_ryser([4,2,2], [3,3,1,1]) # optional - sage.combinat True - sage: is_gale_ryser([4,2,1,1],[3,3,1,1]) + sage: is_gale_ryser([4,2,1,1], [3,3,1,1]) # optional - sage.combinat True - sage: is_gale_ryser([3,2,1,1],[3,3,1,1]) + sage: is_gale_ryser([3,2,1,1], [3,3,1,1]) # optional - sage.combinat False REMARK: In the literature, what we are calling a @@ -207,14 +207,14 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", sage: from sage.combinat.integer_vector import gale_ryser_theorem sage: p1 = [2,2,1] sage: p2 = [2,2,1] - sage: print(gale_ryser_theorem(p1, p2)) # not tested + sage: print(gale_ryser_theorem(p1, p2)) # not tested # optional - sage.combinat [1 1 0] [1 0 1] [0 1 0] - sage: A = gale_ryser_theorem(p1, p2) - sage: rs = [sum(x) for x in A.rows()] - sage: cs = [sum(x) for x in A.columns()] - sage: p1 == rs; p2 == cs + sage: A = gale_ryser_theorem(p1, p2) # optional - sage.combinat + sage: rs = [sum(x) for x in A.rows()] # optional - sage.combinat + sage: cs = [sum(x) for x in A.columns()] # optional - sage.combinat + sage: p1 == rs; p2 == cs # optional - sage.combinat True True @@ -224,27 +224,27 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", sage: from sage.combinat.integer_vector import gale_ryser_theorem sage: p1 = [3,3,1,1] sage: p2 = [3,3,1,1] - sage: gale_ryser_theorem(p1, p2, algorithm = "ryser") + sage: gale_ryser_theorem(p1, p2, algorithm="ryser") # optional - sage.combinat [1 1 1 0] [1 1 0 1] [1 0 0 0] [0 1 0 0] sage: p1 = [4,2,2] sage: p2 = [3,3,1,1] - sage: gale_ryser_theorem(p1, p2, algorithm = "ryser") + sage: gale_ryser_theorem(p1, p2, algorithm="ryser") # optional - sage.combinat [1 1 1 1] [1 1 0 0] [1 1 0 0] sage: p1 = [4,2,2,0] sage: p2 = [3,3,1,1,0,0] - sage: gale_ryser_theorem(p1, p2, algorithm = "ryser") + sage: gale_ryser_theorem(p1, p2, algorithm="ryser") # optional - sage.combinat [1 1 1 1 0 0] [1 1 0 0 0 0] [1 1 0 0 0 0] [0 0 0 0 0 0] sage: p1 = [3,3,2,1] sage: p2 = [3,2,2,1,1] - sage: print(gale_ryser_theorem(p1, p2, algorithm="gale")) # not tested + sage: print(gale_ryser_theorem(p1, p2, algorithm="gale")) # not tested # optional - sage.combinat [1 1 1 0 0] [1 1 0 0 1] [1 0 1 0 0] @@ -253,7 +253,7 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", With `0` in the sequences, and with unordered inputs:: sage: from sage.combinat.integer_vector import gale_ryser_theorem - sage: gale_ryser_theorem([3,3,0,1,1,0], [3,1,3,1,0], algorithm="ryser") + sage: gale_ryser_theorem([3,3,0,1,1,0], [3,1,3,1,0], algorithm="ryser") # optional - sage.combinat [1 1 1 0 0] [1 0 1 1 0] [0 0 0 0 0] @@ -261,7 +261,7 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", [0 0 1 0 0] [0 0 0 0 0] sage: p1 = [3,1,1,1,1]; p2 = [3,2,2,0] - sage: gale_ryser_theorem(p1, p2, algorithm="ryser") + sage: gale_ryser_theorem(p1, p2, algorithm="ryser") # optional - sage.combinat [1 1 1 0] [1 0 0 0] [1 0 0 0] @@ -288,17 +288,17 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", ....: print("Algorithm %s failed with this input:" % algorithm) ....: print(s1, s2) - sage: for algorithm in ["gale", "ryser"]: # long time + sage: for algorithm in ["gale", "ryser"]: # long time # optional - sage.combinat ....: for i in range(50): ....: test_algorithm(algorithm, 3, 10) Null matrix:: - sage: gale_ryser_theorem([0,0,0],[0,0,0,0], algorithm="gale") + sage: gale_ryser_theorem([0,0,0],[0,0,0,0], algorithm="gale") # optional - sage.combinat [0 0 0 0] [0 0 0 0] [0 0 0 0] - sage: gale_ryser_theorem([0,0,0],[0,0,0,0], algorithm="ryser") + sage: gale_ryser_theorem([0,0,0],[0,0,0,0], algorithm="ryser") # optional - sage.combinat [0 0 0 0] [0 0 0 0] [0 0 0 0] @@ -595,7 +595,7 @@ class IntegerVectors(Parent, metaclass=ClasscallMetaclass): Note that trailing zeros are ignored so that ``[3, 0]`` does not show up in the following list (since ``[3]`` does):: - sage: IntegerVectors(3, max_length=2).list() + sage: IntegerVectors(3, max_length=2).list() # optional - sage.combinat [[3], [2, 1], [1, 2], [0, 3]] If ``n`` and ``k`` are both specified, then it returns the class @@ -614,9 +614,9 @@ class IntegerVectors(Parent, metaclass=ClasscallMetaclass): Further examples:: - sage: IntegerVectors(-1, 0, min_part = 1).list() + sage: IntegerVectors(-1, 0, min_part=1).list() [] - sage: IntegerVectors(-1, 2, min_part = 1).list() + sage: IntegerVectors(-1, 2, min_part=1).list() [] sage: IntegerVectors(0, 0, min_part=1).list() [[]] @@ -667,9 +667,9 @@ class IntegerVectors(Parent, metaclass=ClasscallMetaclass): An example showing the same output by using IntegerListsLex:: - sage: IntegerVectors(4, max_length=2).list() + sage: IntegerVectors(4, max_length=2).list() # optional - sage.combinat [[4], [3, 1], [2, 2], [1, 3], [0, 4]] - sage: list(IntegerListsLex(4, max_length=2)) + sage: list(IntegerListsLex(4, max_length=2)) # optional - sage.combinat [[4], [3, 1], [2, 2], [1, 3], [0, 4]] .. SEEALSO:: @@ -1392,12 +1392,12 @@ def __contains__(self, x): """ TESTS:: - sage: [3,2,2,1] in IntegerVectors(8,4, min_part = 1) + sage: [3,2,2,1] in IntegerVectors(8, 4, min_part=1) # optional - sage.combinat True - sage: [3,2,2,1] in IntegerVectors(8,4, min_part = 2) + sage: [3,2,2,1] in IntegerVectors(8, 4, min_part=2) # optional - sage.combinat False - sage: [0,3,0,1,2] in IntegerVectors(6, max_length=3) + sage: [0,3,0,1,2] in IntegerVectors(6, max_length=3) # optional - sage.combinat False """ if isinstance(x, IntegerVector) and x.parent() is self: @@ -1421,17 +1421,17 @@ def cardinality(self): EXAMPLES:: - sage: IntegerVectors(3, 3, min_part=1).cardinality() + sage: IntegerVectors(3, 3, min_part=1).cardinality() # optional - sage.combinat 1 - sage: IntegerVectors(5, 3, min_part=1).cardinality() + sage: IntegerVectors(5, 3, min_part=1).cardinality() # optional - sage.combinat 6 - sage: IntegerVectors(13, 4, max_part=4).cardinality() + sage: IntegerVectors(13, 4, max_part=4).cardinality() # optional - sage.combinat 20 - sage: IntegerVectors(k=4, max_part=3).cardinality() + sage: IntegerVectors(k=4, max_part=3).cardinality() # optional - sage.combinat 256 - sage: IntegerVectors(k=3, min_part=2, max_part=4).cardinality() + sage: IntegerVectors(k=3, min_part=2, max_part=4).cardinality() # optional - sage.combinat 27 - sage: IntegerVectors(13, 4, min_part=2, max_part=4).cardinality() + sage: IntegerVectors(13, 4, min_part=2, max_part=4).cardinality() # optional - sage.combinat 16 """ if self.k is None: @@ -1465,9 +1465,9 @@ def __iter__(self): """ EXAMPLES:: - sage: IntegerVectors(-1, 0, min_part = 1).list() + sage: IntegerVectors(-1, 0, min_part=1).list() [] - sage: IntegerVectors(-1, 2, min_part = 1).list() + sage: IntegerVectors(-1, 2, min_part=1).list() [] sage: IntegerVectors(0, 0, min_part=1).list() [[]] @@ -1512,7 +1512,7 @@ def __iter__(self): sage: all(map(lambda x: x.cardinality() == len(x.list()), iv)) True sage: essai = [[1,1,1], [2,5,6], [6,5,2]] - sage: iv = [ IntegerVectors(x[0], x[1], max_part = x[2]-1) for x in essai ] + sage: iv = [ IntegerVectors(x[0], x[1], max_part=x[2]-1) for x in essai ] sage: all(map(lambda x: x.cardinality() == len(x.list()), iv)) True """ diff --git a/src/sage/combinat/k_regular_sequence.py b/src/sage/combinat/k_regular_sequence.py index 1ec99957aa8..1007ea80467 100644 --- a/src/sage/combinat/k_regular_sequence.py +++ b/src/sage/combinat/k_regular_sequence.py @@ -2181,8 +2181,8 @@ def parameters(self, M, m, coeffs, initial_values, offset=0, inhomogeneities={}) """ from collections import namedtuple + from sage.arith.misc import integer_ceil as ceil, integer_floor as floor from sage.arith.srange import srange - from sage.functions.other import ceil, floor coefficient_ring = self.coefficient_ring k = self.k @@ -2614,7 +2614,6 @@ def shifted_inhomogeneities(self, recurrence_rules): :meth:`kRegularSequenceSpace.from_recurrence` """ from sage.arith.srange import srange - from sage.functions.other import floor k = self.k M = recurrence_rules.M @@ -2623,8 +2622,8 @@ def shifted_inhomogeneities(self, recurrence_rules): uu = recurrence_rules.uu inhomogeneities = recurrence_rules.inhomogeneities - lower = floor(ll/k**M) - upper = floor((k**(M-1) - k**m + uu)/k**M) + 1 + lower = ll//k**M + upper = (k**(M-1) - k**m + uu) // k**M + 1 return {i: inhomogeneities[i].subsequence(1, {b: 1 for b in srange(lower, upper + 1)}, minimize=False) @@ -2841,7 +2840,6 @@ def matrix(self, recurrence_rules, rem, correct_offset=True): from itertools import chain from sage.arith.srange import srange - from sage.functions.other import floor from sage.matrix.constructor import Matrix from sage.matrix.special import block_matrix, block_diagonal_matrix, zero_matrix from sage.modules.free_module_element import vector @@ -2885,8 +2883,8 @@ def entry(i, kk): if not all(S.is_trivial_zero() for S in inhomogeneities.values()): shifted_inhomogeneities = self.shifted_inhomogeneities(recurrence_rules) - lower = floor(ll/k**M) - upper = floor((k**(M-1) - k**m + uu)/k**M) + 1 + lower = ll // k**M + upper = (k**(M-1) - k**m + uu) // k**M + 1 def wanted_inhomogeneity(row): j, d = ind[row] diff --git a/src/sage/combinat/k_tableau.py b/src/sage/combinat/k_tableau.py index 5fb1d56b82c..8ca1d0f98de 100644 --- a/src/sage/combinat/k_tableau.py +++ b/src/sage/combinat/k_tableau.py @@ -40,7 +40,8 @@ from sage.combinat.root_system.weyl_group import WeylGroup from sage.combinat.core import Core from sage.rings.integer_ring import ZZ -from sage.functions.generalized import sgn +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.generalized", "sgn") from sage.misc.flatten import flatten from sage.combinat.skew_partition import SkewPartition from sage.combinat.tableau import Tableaux diff --git a/src/sage/combinat/parallelogram_polyomino.py b/src/sage/combinat/parallelogram_polyomino.py index 56378c527e2..095e57e5ca8 100644 --- a/src/sage/combinat/parallelogram_polyomino.py +++ b/src/sage/combinat/parallelogram_polyomino.py @@ -39,7 +39,8 @@ from sage.matrix.constructor import matrix from sage.combinat.combinat import catalan_number from sage.combinat.combinatorial_map import combinatorial_map -from sage.functions.trig import cos, sin +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.trig", ["cos", "sin"]) from sage.misc.functional import sqrt from sage.misc.lazy_import import lazy_import diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 4dac3bf8bf3..71d2ed14554 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -289,7 +289,8 @@ from sage.structure.global_options import GlobalOptions from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation -from sage.symbolic.ring import var +from sage.misc.lazy_import import lazy_import +lazy_import("sage.symbolic.ring", "var") from sage.misc.lazy_import import lazy_import lazy_import('sage.combinat.skew_partition', 'SkewPartition') diff --git a/src/sage/combinat/partition_algebra.py b/src/sage/combinat/partition_algebra.py index 9136b682c59..b413394b379 100644 --- a/src/sage/combinat/partition_algebra.py +++ b/src/sage/combinat/partition_algebra.py @@ -15,15 +15,15 @@ # # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.arith.misc import binomial, factorial +from sage.arith.misc import binomial, factorial, integer_ceil as ceil from sage.categories.algebras_with_basis import AlgebrasWithBasis from sage.combinat.combinat import catalan_number from sage.combinat.free_module import CombinatorialFreeModule from sage.combinat.permutation import Permutations from sage.combinat.set_partition import SetPartition, SetPartitions, SetPartitions_set from sage.combinat.subset import Subsets -from sage.functions.all import ceil from sage.graphs.graph import Graph +from sage.misc.lazy_import import lazy_import from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.sets.set import Set, Set_generic diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index 9593055e9ed..35df9e94296 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -242,6 +242,7 @@ from __future__ import annotations from typing import Iterator import itertools +import operator from sage.arith.misc import factorial, multinomial from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets @@ -256,16 +257,10 @@ from sage.combinat.permutation_cython import (left_action_product, right_action_product, left_action_same_n, right_action_same_n, map_to_list, next_perm) -from sage.combinat.rsk import RSK, RSK_inverse from sage.combinat.tools import transitive_ideal -from sage.graphs.digraph import DiGraph -from sage.groups.perm_gps.permgroup_element import PermutationGroupElement -from sage.groups.perm_gps.permgroup_named import SymmetricGroup -from sage.libs.gap.libgap import libgap -from sage.matrix.matrix_space import MatrixSpace from sage.misc.cachefunc import cached_method from sage.misc.decorators import rename_keyword -from sage.misc.prandom import sample +from sage.misc.lazy_import import lazy_import from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -274,7 +269,18 @@ from sage.structure.parent import Parent from sage.structure.element import Element, get_coercion_model from sage.structure.unique_representation import UniqueRepresentation -import operator + +lazy_import('sage.combinat.rsk', ['RSK', 'RSK_inverse']) +lazy_import('sage.combinat.tableau', 'Tableau') +lazy_import('sage.combinat.words.finite_word', 'evaluation_dict') +lazy_import('sage.graphs.digraph', 'DiGraph') +lazy_import('sage.groups.cactus_group', 'CactusGroup') +lazy_import('sage.groups.perm_gps.permgroup_element', 'PermutationGroupElement') +lazy_import('sage.groups.perm_gps.permgroup_named', 'SymmetricGroup') +lazy_import('sage.libs.gap.libgap', 'libgap') +lazy_import('sage.matrix.matrix_space', 'MatrixSpace') +lazy_import('sage.misc.prandom', 'sample') + class Permutation(CombinatorialElement): r""" @@ -390,8 +396,8 @@ class Permutation(CombinatorialElement): We construct a :class:`Permutation` from a :class:`PermutationGroupElement`:: - sage: g = PermutationGroupElement([2,1,3]) - sage: Permutation(g) + sage: g = PermutationGroupElement([2,1,3]) # optional - sage.groups + sage: Permutation(g) # optional - sage.groups [2, 1, 3] From a pair of tableaux of the same shape. This uses the inverse @@ -399,15 +405,15 @@ class Permutation(CombinatorialElement): sage: p = [[1, 4, 7], [2, 5], [3], [6]] sage: q = [[1, 2, 5], [3, 6], [4], [7]] - sage: P = Tableau(p) - sage: Q = Tableau(q) - sage: Permutation( (p, q) ) + sage: P = Tableau(p) # optional - sage.combinat + sage: Q = Tableau(q) # optional - sage.combinat + sage: Permutation( (p, q) ) # optional - sage.combinat [3, 6, 5, 2, 7, 4, 1] - sage: Permutation( [p, q] ) + sage: Permutation( [p, q] ) # optional - sage.combinat [3, 6, 5, 2, 7, 4, 1] - sage: Permutation( (P, Q) ) + sage: Permutation( (P, Q) ) # optional - sage.combinat [3, 6, 5, 2, 7, 4, 1] - sage: Permutation( [P, Q] ) + sage: Permutation( [P, Q] ) # optional - sage.combinat [3, 6, 5, 2, 7, 4, 1] TESTS:: @@ -423,9 +429,9 @@ class Permutation(CombinatorialElement): From a pair of empty tableaux :: - sage: Permutation( ([], []) ) + sage: Permutation( ([], []) ) # optional - sage.combinat [] - sage: Permutation( [[], []] ) + sage: Permutation( [[], []] ) # optional - sage.combinat [] """ @staticmethod @@ -441,7 +447,6 @@ def __classcall_private__(cls, l, check=True): sage: P.parent() Standard permutations """ - import sage.combinat.tableau as tableau if isinstance(l, Permutation): return l elif isinstance(l, PermutationGroupElement): @@ -461,11 +466,11 @@ def __classcall_private__(cls, l, check=True): #if l is a pair of standard tableaux or a pair of lists elif isinstance(l, (tuple, list)) and len(l) == 2 and \ - all(isinstance(x, tableau.Tableau) for x in l): + all(isinstance(x, Tableau) for x in l): return RSK_inverse(*l, output='permutation') elif isinstance(l, (tuple, list)) and len(l) == 2 and \ all(isinstance(x, list) for x in l): - P,Q = [tableau.Tableau(_) for _ in l] + P,Q = [Tableau(_) for _ in l] return RSK_inverse(P, Q, 'permutation') # if it's a tuple or nonempty list of tuples, also assume cycle # notation @@ -697,11 +702,11 @@ def _gap_(self, gap): EXAMPLES:: - sage: gap(Permutation([1,2,3])) + sage: gap(Permutation([1,2,3])) # optional - sage.libs.gap () - sage: gap(Permutation((1,2,3))) + sage: gap(Permutation((1,2,3))) # optional - sage.libs.gap (1,2,3) - sage: type(_) + sage: type(_) # optional - sage.libs.gap """ return self.to_permutation_group_element()._gap_(gap) @@ -865,12 +870,11 @@ def to_tableau_by_shape(self, shape): EXAMPLES:: - sage: Permutation([3,4,1,2,5]).to_tableau_by_shape([3,2]) + sage: T = Permutation([3,4,1,2,5]).to_tableau_by_shape([3,2]); T # optional - sage.combinat [[1, 2, 5], [3, 4]] - sage: Permutation([3,4,1,2,5]).to_tableau_by_shape([3,2]).reading_word_permutation() + sage: T.reading_word_permutation() # optional - sage.combinat [3, 4, 1, 2, 5] """ - import sage.combinat.tableau as tableau if sum(shape) != len(self): raise ValueError("the size of the partition must be the size of self") @@ -879,7 +883,7 @@ def to_tableau_by_shape(self, shape): for i in reversed(shape): t = [w[:i]] + t w = w[i:] - return tableau.Tableau(t) + return Tableau(t) def to_cycles(self, singletons=True, use_min=True): """ @@ -1137,9 +1141,9 @@ def to_permutation_group_element(self): EXAMPLES:: - sage: Permutation([2,1,4,3]).to_permutation_group_element() + sage: Permutation([2,1,4,3]).to_permutation_group_element() # optional - sage.groups (1,2)(3,4) - sage: Permutation([1,2,3]).to_permutation_group_element() + sage: Permutation([1,2,3]).to_permutation_group_element() # optional - sage.groups () """ grp = SymmetricGroup(len(self)) @@ -1188,14 +1192,14 @@ def to_matrix(self): EXAMPLES:: - sage: Permutation([1,2,3]).to_matrix() + sage: Permutation([1,2,3]).to_matrix() # optional - sage.modules [1 0 0] [0 1 0] [0 0 1] Alternatively:: - sage: matrix(Permutation([1,3,2])) + sage: matrix(Permutation([1,3,2])) # optional - sage.modules [1 0 0] [0 0 1] [0 1 0] @@ -1208,16 +1212,16 @@ def to_matrix(self): sage: Permutations.options.mult='r2l' sage: p = Permutation([2,1,3]) sage: q = Permutation([3,1,2]) - sage: (p*q).to_matrix() + sage: (p*q).to_matrix() # optional - sage.modules [0 0 1] [0 1 0] [1 0 0] - sage: p.to_matrix()*q.to_matrix() + sage: p.to_matrix()*q.to_matrix() # optional - sage.modules [0 0 1] [0 1 0] [1 0 0] sage: Permutations.options.mult='l2r' - sage: (p*q).to_matrix() + sage: (p*q).to_matrix() # optional - sage.modules [1 0 0] [0 0 1] [0 1 0] @@ -1238,11 +1242,11 @@ def to_alternating_sign_matrix(self): EXAMPLES:: - sage: m = Permutation([1,2,3]).to_alternating_sign_matrix(); m + sage: m = Permutation([1,2,3]).to_alternating_sign_matrix(); m # optional - sage.combinat sage.modules [1 0 0] [0 1 0] [0 0 1] - sage: parent(m) + sage: parent(m) # optional - sage.combinat sage.modules Alternating sign matrices of size 3 """ from sage.combinat.alternating_sign_matrix import AlternatingSignMatrix @@ -1252,12 +1256,12 @@ def __mul__(self, rp): """ TESTS:: - sage: SGA = SymmetricGroupAlgebra(QQ, 3) - sage: SM = SGA.specht_module([2,1]) - sage: p213 = Permutations(3)([2,1,3]) - sage: p213 * SGA.an_element() + sage: SGA = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: SM = SGA.specht_module([2,1]) # optional - sage.combinat sage.modules + sage: p213 = Permutations(3)([2,1,3]) # optional - sage.combinat sage.modules + sage: p213 * SGA.an_element() # optional - sage.combinat sage.modules 3*[1, 2, 3] + [1, 3, 2] + [2, 1, 3] + 2*[3, 1, 2] - sage: p213 * SM.an_element() + sage: p213 * SM.an_element() # optional - sage.combinat sage.modules 2*B[0] - 4*B[1] """ if not isinstance(rp, Permutation) and isinstance(rp, Element): @@ -1297,8 +1301,8 @@ def __rmul__(self, lp) -> Permutation: [3, 2, 1] sage: Permutations.options.mult='l2r' - sage: SGA = SymmetricGroupAlgebra(QQ, 3) - sage: SGA.an_element() * Permutations(3)(p213) + sage: SGA = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: SGA.an_element() * Permutations(3)(p213) # optional - sage.combinat sage.modules 3*[1, 2, 3] + [2, 1, 3] + 2*[2, 3, 1] + [3, 2, 1] """ if not isinstance(lp, Permutation) and isinstance(lp, Element): @@ -1678,18 +1682,19 @@ def to_digraph(self) -> DiGraph: EXAMPLES:: - sage: d = Permutation([3, 1, 2]).to_digraph() - sage: d.edges(sort=True, labels=False) + sage: d = Permutation([3, 1, 2]).to_digraph() # optional - sage.graphs + sage: d.edges(sort=True, labels=False) # optional - sage.graphs [(1, 3), (2, 1), (3, 2)] sage: P = Permutations(range(1, 10)) - sage: d = Permutation(P.random_element()).to_digraph() - sage: all(c.is_cycle() for c in d.strongly_connected_components_subgraphs()) + sage: d = Permutation(P.random_element()).to_digraph() # optional - sage.graphs + sage: all(c.is_cycle() # optional - sage.graphs + ....: for c in d.strongly_connected_components_subgraphs()) True TESTS:: - sage: d = Permutation([1]).to_digraph() - sage: d.edges(sort=True, labels=False) + sage: d = Permutation([1]).to_digraph() # optional - sage.graphs + sage: d.edges(sort=True, labels=False) # optional - sage.graphs [(1, 1)] """ return DiGraph([self, enumerate(self, start=1)], @@ -1720,14 +1725,16 @@ def show(self, representation="cycles", orientation="landscape", **args): EXAMPLES:: - sage: Permutations(20).random_element().show(representation = "cycles") - sage: Permutations(20).random_element().show(representation = "chord-diagram") - sage: Permutations(20).random_element().show(representation = "braid") - sage: Permutations(20).random_element().show(representation = "braid", orientation='portrait') + sage: P20 = Permutations(20) + sage: P20.random_element().show(representation="cycles") # optional - sage.graphs + sage: P20.random_element().show(representation="chord-diagram") # optional - sage.graphs + sage: P20.random_element().show(representation="braid") # optional - sage.plot + sage: P20.random_element().show(representation="braid", # optional - sage.plot + ....: orientation='portrait') TESTS:: - sage: Permutations(20).random_element().show(representation = "modern_art") + sage: P20.random_element().show(representation="modern_art") Traceback (most recent call last): ... ValueError: The value of 'representation' must be equal to 'cycles', 'chord-diagram' or 'braid' @@ -1906,7 +1913,7 @@ def absolute_length(self) -> Integer: EXAMPLES:: - sage: Permutation([4,2,3,1]).absolute_length() + sage: Permutation([4,2,3,1]).absolute_length() # optional - sage.combinat 1 """ return self.size() - len(self.cycle_type()) @@ -2215,7 +2222,8 @@ def longest_increasing_subsequence_length(self) -> Integer: sage: Permutation([2,3,1,4]).longest_increasing_subsequence_length() 3 - sage: all(i.longest_increasing_subsequence_length() == len(RSK(i)[0][0]) for i in Permutations(5)) + sage: all(i.longest_increasing_subsequence_length() == len(RSK(i)[0][0]) # optional - sage.combinat + ....: for i in Permutations(5)) True sage: Permutation([]).longest_increasing_subsequence_length() 0 @@ -2246,9 +2254,9 @@ def longest_increasing_subsequences(self): EXAMPLES:: - sage: Permutation([2,3,4,1]).longest_increasing_subsequences() + sage: Permutation([2,3,4,1]).longest_increasing_subsequences() # optional - sage.graphs [[2, 3, 4]] - sage: Permutation([5, 7, 1, 2, 6, 4, 3]).longest_increasing_subsequences() + sage: Permutation([5, 7, 1, 2, 6, 4, 3]).longest_increasing_subsequences() # optional - sage.graphs [[1, 2, 6], [1, 2, 4], [1, 2, 3]] .. NOTE:: @@ -2306,16 +2314,17 @@ def longest_increasing_subsequences_number(self): The algorithm is similar to :meth:`longest_increasing_subsequences`. Namely, the longest increasing subsequences are encoded as increasing sequences in a ranked poset from a smallest to a largest element. Their - number can be obtained via dynamic programming : for each `v` in the poset + number can be obtained via dynamic programming: for each `v` in the poset we compute the number of paths from a smallest element to `v`. EXAMPLES:: - sage: sum(p.longest_increasing_subsequences_number() for p in Permutations(8)) + sage: sum(p.longest_increasing_subsequences_number() + ....: for p in Permutations(8)) 120770 sage: p = Permutations(50).random_element() - sage: (len(p.longest_increasing_subsequences()) == + sage: (len(p.longest_increasing_subsequences()) == # optional - sage.graphs ....: p.longest_increasing_subsequences_number()) True """ @@ -2354,7 +2363,7 @@ def cycle_type(self): EXAMPLES:: - sage: Permutation([3,1,2,4]).cycle_type() + sage: Permutation([3,1,2,4]).cycle_type() # optional - sage.combinat [3, 1] """ cycle_type = [len(c) for c in self.to_cycles()] @@ -2412,9 +2421,9 @@ def forget_cycles(self): results as a poset under the Bruhat order:: sage: l = [p.forget_cycles().inverse() for p in l] - sage: B = Poset([l, lambda x,y: x.bruhat_lequal(y)]) + sage: B = Poset([l, lambda x,y: x.bruhat_lequal(y)]) # optional - sage.combinat sage.graphs sage: R. = QQ[] - sage: sum(q^B.rank_function()(x) for x in B) + sage: sum(q^B.rank_function()(x) for x in B) # optional - sage.combinat sage.graphs q^5 + 2*q^4 + 3*q^3 + 3*q^2 + 2*q + 1 We check the statement in [CC2013]_ that the posets @@ -2422,8 +2431,8 @@ def forget_cycles(self): sage: l2 = [p for p in P if [len(t) for t in p.to_cycles()] == [1,3,1,1]] sage: l2 = [p.forget_cycles().inverse() for p in l2] - sage: B2 = Poset([l2, lambda x,y: x.bruhat_lequal(y)]) - sage: B.is_isomorphic(B2) + sage: B2 = Poset([l2, lambda x,y: x.bruhat_lequal(y)]) # optional - sage.combinat sage.graphs + sage: B.is_isomorphic(B2) # optional - sage.combinat sage.graphs True .. SEEALSO:: @@ -2734,7 +2743,7 @@ def destandardize(self, weight, ordered_alphabet=None): - ``weight`` -- list or tuple of nonnegative integers that sum to `n` if ``self`` is a permutation in `S_n`. - - ``ordered_alphabet`` -- (default: None) a list or tuple specifying the ordered alphabet the + - ``ordered_alphabet`` -- (default: ``None``) a list or tuple specifying the ordered alphabet the destandardized word is over OUTPUT: word over the ``ordered_alphabet`` which standardizes to ``self`` @@ -2749,7 +2758,7 @@ def destandardize(self, weight, ordered_alphabet=None): EXAMPLES:: sage: p = Permutation([1,2,5,3,6,4]) - sage: p.destandardize([3,1,2]) + sage: p.destandardize([3,1,2]) # optional - sage.combinat word: 113132 sage: p = Permutation([2,1,3]) sage: p.destandardize([2,1]) @@ -2760,7 +2769,7 @@ def destandardize(self, weight, ordered_alphabet=None): TESTS:: sage: p = Permutation([4,1,2,3,5,6]) - sage: p.destandardize([2,1,3], ordered_alphabet = [1,'a',3]) + sage: p.destandardize([2,1,3], ordered_alphabet = [1,'a',3]) # optional - sage.combinat word: 311a33 sage: p.destandardize([2,1,3], ordered_alphabet = [1,'a']) Traceback (most recent call last): @@ -3019,9 +3028,9 @@ def rothe_diagram(self): EXAMPLES:: sage: p = Permutation([4,2,1,3]) - sage: D = p.rothe_diagram(); D + sage: D = p.rothe_diagram(); D # optional - sage.combinat [(0, 0), (0, 1), (0, 2), (1, 0)] - sage: D.pp() + sage: D.pp() # optional - sage.combinat O O O . O . . . . . . . @@ -3038,7 +3047,7 @@ def number_of_reduced_words(self): EXAMPLES:: sage: p = Permutation([6,4,2,5,1,8,3,7]) - sage: len(p.reduced_words()) == p.number_of_reduced_words() + sage: len(p.reduced_words()) == p.number_of_reduced_words() # optional - sage.combinat True """ Tx = self.rothe_diagram().peelable_tableaux() @@ -4221,8 +4230,10 @@ def right_permutohedron_interval_iterator(self, other): EXAMPLES:: - sage: Permutation([2, 1, 4, 5, 3]).right_permutohedron_interval(Permutation([2, 5, 4, 1, 3])) # indirect doctest - [[2, 4, 5, 1, 3], [2, 4, 1, 5, 3], [2, 1, 4, 5, 3], [2, 1, 5, 4, 3], [2, 5, 1, 4, 3], [2, 5, 4, 1, 3]] + sage: p = Permutation([2, 1, 4, 5, 3]); q = Permutation([2, 5, 4, 1, 3]) + sage: p.right_permutohedron_interval(q) # indirect doctest # optional - sage.graphs + [[2, 4, 5, 1, 3], [2, 4, 1, 5, 3], [2, 1, 4, 5, 3], + [2, 1, 5, 4, 3], [2, 5, 1, 4, 3], [2, 5, 4, 1, 3]] """ if len(self) != len(other): raise ValueError("len({}) and len({}) must be equal".format(self, other)) @@ -4246,24 +4257,28 @@ def right_permutohedron_interval(self, other): EXAMPLES:: - sage: Permutation([2, 1, 4, 5, 3]).right_permutohedron_interval(Permutation([2, 5, 4, 1, 3])) - [[2, 4, 5, 1, 3], [2, 4, 1, 5, 3], [2, 1, 4, 5, 3], [2, 1, 5, 4, 3], [2, 5, 1, 4, 3], [2, 5, 4, 1, 3]] + sage: p = Permutation([2, 1, 4, 5, 3]); q = Permutation([2, 5, 4, 1, 3]) + sage: p.right_permutohedron_interval(q) # optional - sage.graphs + [[2, 4, 5, 1, 3], [2, 4, 1, 5, 3], [2, 1, 4, 5, 3], + [2, 1, 5, 4, 3], [2, 5, 1, 4, 3], [2, 5, 4, 1, 3]] TESTS:: - sage: Permutation([]).right_permutohedron_interval(Permutation([])) + sage: Permutation([]).right_permutohedron_interval(Permutation([])) # optional - sage.graphs [[]] - sage: Permutation([3, 1, 2]).right_permutohedron_interval(Permutation([3, 1, 2])) + sage: Permutation([3, 1, 2]).right_permutohedron_interval(Permutation([3, 1, 2])) # optional - sage.graphs [[3, 1, 2]] - sage: Permutation([1, 3, 2, 4]).right_permutohedron_interval(Permutation([3, 4, 2, 1])) - [[3, 1, 4, 2], [3, 4, 1, 2], [3, 4, 2, 1], [1, 3, 4, 2], [1, 3, 2, 4], [3, 2, 4, 1], [3, 2, 1, 4], [3, 1, 2, 4]] - sage: Permutation([2, 1, 4, 5, 3]).right_permutohedron_interval(Permutation([2, 5, 4, 1, 3])) - [[2, 4, 5, 1, 3], [2, 4, 1, 5, 3], [2, 1, 4, 5, 3], [2, 1, 5, 4, 3], [2, 5, 1, 4, 3], [2, 5, 4, 1, 3]] - sage: Permutation([2, 5, 4, 1, 3]).right_permutohedron_interval(Permutation([2, 1, 4, 5, 3])) + sage: Permutation([1, 3, 2, 4]).right_permutohedron_interval(Permutation([3, 4, 2, 1])) # optional - sage.graphs + [[3, 1, 4, 2], [3, 4, 1, 2], [3, 4, 2, 1], [1, 3, 4, 2], + [1, 3, 2, 4], [3, 2, 4, 1], [3, 2, 1, 4], [3, 1, 2, 4]] + sage: Permutation([2, 1, 4, 5, 3]).right_permutohedron_interval(Permutation([2, 5, 4, 1, 3])) # optional - sage.graphs + [[2, 4, 5, 1, 3], [2, 4, 1, 5, 3], [2, 1, 4, 5, 3], + [2, 1, 5, 4, 3], [2, 5, 1, 4, 3], [2, 5, 4, 1, 3]] + sage: Permutation([2, 5, 4, 1, 3]).right_permutohedron_interval(Permutation([2, 1, 4, 5, 3])) # optional - sage.graphs Traceback (most recent call last): ... ValueError: [2, 5, 4, 1, 3] must be lower or equal than [2, 1, 4, 5, 3] for the right permutohedron order - sage: Permutation([2, 4, 1, 3]).right_permutohedron_interval(Permutation([2, 1, 4, 5, 3])) + sage: Permutation([2, 4, 1, 3]).right_permutohedron_interval(Permutation([2, 1, 4, 5, 3])) # optional - sage.graphs Traceback (most recent call last): ... ValueError: len([2, 4, 1, 3]) and len([2, 1, 4, 5, 3]) must be equal @@ -4502,7 +4517,7 @@ def has_pattern(self, patt) -> bool: EXAMPLES:: - sage: Permutation([3,5,1,4,6,2]).has_pattern([1,3,2]) + sage: Permutation([3,5,1,4,6,2]).has_pattern([1,3,2]) # optional - sage.combinat True """ p = self @@ -4522,11 +4537,11 @@ def avoids(self, patt) -> bool: EXAMPLES:: - sage: Permutation([6,2,5,4,3,1]).avoids([4,2,3,1]) + sage: Permutation([6,2,5,4,3,1]).avoids([4,2,3,1]) # optional - sage.combinat False - sage: Permutation([6,1,2,5,4,3]).avoids([4,2,3,1]) + sage: Permutation([6,1,2,5,4,3]).avoids([4,2,3,1]) # optional - sage.combinat True - sage: Permutation([6,1,2,5,4,3]).avoids([3,4,1,2]) + sage: Permutation([6,1,2,5,4,3]).avoids([3,4,1,2]) # optional - sage.combinat True """ return not self.has_pattern(patt) @@ -4538,7 +4553,7 @@ def pattern_positions(self, patt) -> list: EXAMPLES:: - sage: Permutation([3,5,1,4,6,2]).pattern_positions([1,3,2]) + sage: Permutation([3,5,1,4,6,2]).pattern_positions([1,3,2]) # optional - sage.combinat [[0, 1, 3], [2, 3, 5], [2, 4, 5]] """ p = self @@ -4563,7 +4578,7 @@ def simion_schmidt(self, avoid=[1,2,3]): sage: P = Permutations(6) sage: p = P([4,5,1,6,3,2]) sage: pl = [ [1,2,3], [1,3,2], [3,1,2], [3,2,1] ] - sage: for q in pl: + sage: for q in pl: # optional - sage.combinat ....: s = p.simion_schmidt(q) ....: print("{} {}".format(s, s.has_pattern(q))) [4, 6, 1, 5, 3, 2] False @@ -4647,20 +4662,23 @@ def permutation_poset(self): EXAMPLES:: - sage: Permutation([3,1,5,4,2]).permutation_poset().cover_relations() + sage: Permutation([3,1,5,4,2]).permutation_poset().cover_relations() # optional - sage.combinat sage.graphs [[(2, 1), (5, 2)], [(2, 1), (3, 5)], [(2, 1), (4, 4)], [(1, 3), (3, 5)], [(1, 3), (4, 4)]] - sage: Permutation([]).permutation_poset().cover_relations() + sage: Permutation([]).permutation_poset().cover_relations() # optional - sage.combinat sage.graphs [] - sage: Permutation([1,3,2]).permutation_poset().cover_relations() + sage: Permutation([1,3,2]).permutation_poset().cover_relations() # optional - sage.combinat sage.graphs [[(1, 1), (2, 3)], [(1, 1), (3, 2)]] - sage: Permutation([1,2]).permutation_poset().cover_relations() + sage: Permutation([1,2]).permutation_poset().cover_relations() # optional - sage.combinat sage.graphs [[(1, 1), (2, 2)]] - sage: P = Permutation([1,5,2,4,3]) - sage: P.permutation_poset().greene_shape() == P.RS_partition() # This should hold for any P. + sage: P = Permutation([1,5,2,4,3]) # optional - sage.combinat sage.graphs + + This should hold for any `P`:: + + sage: P.permutation_poset().greene_shape() == P.RS_partition() # optional - sage.combinat sage.graphs True """ from sage.combinat.posets.posets import Poset @@ -4732,7 +4750,7 @@ def robinson_schensted(self): EXAMPLES:: - sage: Permutation([6,2,3,1,7,5,4]).robinson_schensted() + sage: Permutation([6,2,3,1,7,5,4]).robinson_schensted() # optional - sage.combinat [[[1, 3, 4], [2, 5], [6, 7]], [[1, 3, 5], [2, 6], [4, 7]]] """ return RSK(self, check_standard=True) @@ -4764,7 +4782,7 @@ def left_tableau(self): EXAMPLES:: - sage: Permutation([1,4,3,2]).left_tableau() + sage: Permutation([1,4,3,2]).left_tableau() # optional - sage.combinat [[1, 2], [3], [4]] """ return RSK(self, check_standard=True)[0] @@ -4777,7 +4795,7 @@ def right_tableau(self): EXAMPLES:: - sage: Permutation([1,4,3,2]).right_tableau() + sage: Permutation([1,4,3,2]).right_tableau() # optional - sage.combinat [[1, 2], [3], [4]] """ return RSK(self, check_standard=True)[1] @@ -4788,17 +4806,17 @@ def increasing_tree(self, compare=min): EXAMPLES:: - sage: Permutation([1,4,3,2]).increasing_tree() + sage: Permutation([1,4,3,2]).increasing_tree() # optional - sage.combinat 1[., 2[3[4[., .], .], .]] - sage: Permutation([4,1,3,2]).increasing_tree() + sage: Permutation([4,1,3,2]).increasing_tree() # optional - sage.combinat 1[4[., .], 2[3[., .], .]] By passing the option ``compare=max`` one can have the decreasing tree instead:: - sage: Permutation([2,3,4,1]).increasing_tree(max) + sage: Permutation([2,3,4,1]).increasing_tree(max) # optional - sage.combinat 4[3[2[., .], .], 1[., .]] - sage: Permutation([2,3,1,4]).increasing_tree(max) + sage: Permutation([2,3,1,4]).increasing_tree(max) # optional - sage.combinat 4[3[2[., .], 1[., .]], .] """ from sage.combinat.binary_tree import LabelledBinaryTree as LBT @@ -4819,17 +4837,17 @@ def increasing_tree_shape(self, compare=min): EXAMPLES:: - sage: Permutation([1,4,3,2]).increasing_tree_shape() + sage: Permutation([1,4,3,2]).increasing_tree_shape() # optional - sage.combinat [., [[[., .], .], .]] - sage: Permutation([4,1,3,2]).increasing_tree_shape() + sage: Permutation([4,1,3,2]).increasing_tree_shape() # optional - sage.combinat [[., .], [[., .], .]] By passing the option ``compare=max`` one can have the decreasing tree instead:: - sage: Permutation([2,3,4,1]).increasing_tree_shape(max) + sage: Permutation([2,3,4,1]).increasing_tree_shape(max) # optional - sage.combinat [[[., .], .], [., .]] - sage: Permutation([2,3,1,4]).increasing_tree_shape(max) + sage: Permutation([2,3,1,4]).increasing_tree_shape(max) # optional - sage.combinat [[[., .], [., .]], .] """ return self.increasing_tree(compare).shape() @@ -4855,22 +4873,22 @@ def binary_search_tree(self, left_to_right=True): EXAMPLES:: - sage: Permutation([1,4,3,2]).binary_search_tree() + sage: Permutation([1,4,3,2]).binary_search_tree() # optional - sage.combinat 1[., 4[3[2[., .], .], .]] - sage: Permutation([4,1,3,2]).binary_search_tree() + sage: Permutation([4,1,3,2]).binary_search_tree() # optional - sage.combinat 4[1[., 3[2[., .], .]], .] By passing the option ``left_to_right=False`` one can have the insertion going from right to left:: - sage: Permutation([1,4,3,2]).binary_search_tree(False) + sage: Permutation([1,4,3,2]).binary_search_tree(False) # optional - sage.combinat 2[1[., .], 3[., 4[., .]]] - sage: Permutation([4,1,3,2]).binary_search_tree(False) + sage: Permutation([4,1,3,2]).binary_search_tree(False) # optional - sage.combinat 2[1[., .], 3[., 4[., .]]] TESTS:: - sage: Permutation([]).binary_search_tree() + sage: Permutation([]).binary_search_tree() # optional - sage.combinat . """ from sage.combinat.binary_tree import LabelledBinaryTree as LBT @@ -4891,17 +4909,17 @@ def binary_search_tree_shape(self, left_to_right=True): EXAMPLES:: - sage: Permutation([1,4,3,2]).binary_search_tree_shape() + sage: Permutation([1,4,3,2]).binary_search_tree_shape() # optional - sage.combinat [., [[[., .], .], .]] - sage: Permutation([4,1,3,2]).binary_search_tree_shape() + sage: Permutation([4,1,3,2]).binary_search_tree_shape() # optional - sage.combinat [[., [[., .], .]], .] By passing the option ``left_to_right=False`` one can have the insertion going from right to left:: - sage: Permutation([1,4,3,2]).binary_search_tree_shape(False) + sage: Permutation([1,4,3,2]).binary_search_tree_shape(False) # optional - sage.combinat [[., .], [., [., .]]] - sage: Permutation([4,1,3,2]).binary_search_tree_shape(False) + sage: Permutation([4,1,3,2]).binary_search_tree_shape(False) # optional - sage.combinat [[., .], [., [., .]]] """ from sage.combinat.binary_tree import binary_search_tree_shape @@ -4948,7 +4966,7 @@ def sylvester_class(self, left_to_right=False): The sylvester class of a permutation in `S_5`:: sage: p = Permutation([3, 5, 1, 2, 4]) - sage: sorted(p.sylvester_class()) + sage: sorted(p.sylvester_class()) # optional - sage.combinat [[1, 3, 2, 5, 4], [1, 3, 5, 2, 4], [1, 5, 3, 2, 4], @@ -4960,20 +4978,20 @@ def sylvester_class(self, left_to_right=False): The sylvester class of a permutation `p` contains `p`:: - sage: all( p in p.sylvester_class() for p in Permutations(4) ) + sage: all(p in p.sylvester_class() for p in Permutations(4)) # optional - sage.combinat True Small cases:: - sage: list(Permutation([]).sylvester_class()) + sage: list(Permutation([]).sylvester_class()) # optional - sage.combinat [[]] - sage: list(Permutation([1]).sylvester_class()) + sage: list(Permutation([1]).sylvester_class()) # optional - sage.combinat [[1]] The sylvester classes in `S_3`:: - sage: [sorted(p.sylvester_class()) for p in Permutations(3)] + sage: [sorted(p.sylvester_class()) for p in Permutations(3)] # optional - sage.combinat [[[1, 2, 3]], [[1, 3, 2], [3, 1, 2]], [[2, 1, 3]], @@ -4983,7 +5001,8 @@ def sylvester_class(self, left_to_right=False): The left sylvester classes in `S_3`:: - sage: [sorted(p.sylvester_class(left_to_right=True)) for p in Permutations(3)] + sage: [sorted(p.sylvester_class(left_to_right=True)) # optional - sage.combinat + ....: for p in Permutations(3)] [[[1, 2, 3]], [[1, 3, 2]], [[2, 1, 3], [2, 3, 1]], @@ -4994,7 +5013,7 @@ def sylvester_class(self, left_to_right=False): A left sylvester class in `S_5`:: sage: p = Permutation([4, 2, 1, 5, 3]) - sage: sorted(p.sylvester_class(left_to_right=True)) + sage: sorted(p.sylvester_class(left_to_right=True)) # optional - sage.combinat [[4, 2, 1, 3, 5], [4, 2, 1, 5, 3], [4, 2, 3, 1, 5], @@ -5017,7 +5036,7 @@ def RS_partition(self): EXAMPLES:: - sage: Permutation([1,4,3,2]).RS_partition() + sage: Permutation([1,4,3,2]).RS_partition() # optional - sage.combinat [2, 1, 1] """ return RSK(self)[1].shape() @@ -5239,15 +5258,16 @@ def hyperoctahedral_double_coset_type(self): EXAMPLES:: - sage: Permutation([3, 4, 6, 1, 5, 7, 2, 8]).hyperoctahedral_double_coset_type() + sage: p = Permutation([3, 4, 6, 1, 5, 7, 2, 8]) + sage: p.hyperoctahedral_double_coset_type() # optional - sage.combinat [3, 1] - sage: all(p.hyperoctahedral_double_coset_type() == + sage: all(p.hyperoctahedral_double_coset_type() == # optional - sage.combinat ....: p.inverse().hyperoctahedral_double_coset_type() ....: for p in Permutations(4)) True - sage: Permutation([]).hyperoctahedral_double_coset_type() + sage: Permutation([]).hyperoctahedral_double_coset_type() # optional - sage.combinat [] - sage: Permutation([3,1,2]).hyperoctahedral_double_coset_type() + sage: Permutation([3,1,2]).hyperoctahedral_double_coset_type() # optional - sage.combinat Traceback (most recent call last): ... ValueError: [3, 1, 2] is a permutation of odd size and has no coset-type @@ -5324,21 +5344,23 @@ def shifted_shuffle(self, other): EXAMPLES:: - sage: Permutation([]).shifted_shuffle(Permutation([])) + sage: Permutation([]).shifted_shuffle(Permutation([])) # optional - sage.graphs [[]] - sage: Permutation([1, 2, 3]).shifted_shuffle(Permutation([1])) + sage: Permutation([1, 2, 3]).shifted_shuffle(Permutation([1])) # optional - sage.graphs [[4, 1, 2, 3], [1, 2, 3, 4], [1, 2, 4, 3], [1, 4, 2, 3]] - sage: Permutation([1, 2]).shifted_shuffle(Permutation([2, 1])) - [[4, 1, 3, 2], [4, 3, 1, 2], [1, 4, 3, 2], [1, 4, 2, 3], [1, 2, 4, 3], [4, 1, 2, 3]] - sage: Permutation([1]).shifted_shuffle([1]) + sage: Permutation([1, 2]).shifted_shuffle(Permutation([2, 1])) # optional - sage.graphs + [[4, 1, 3, 2], [4, 3, 1, 2], [1, 4, 3, 2], + [1, 4, 2, 3], [1, 2, 4, 3], [4, 1, 2, 3]] + sage: Permutation([1]).shifted_shuffle([1]) # optional - sage.graphs [[2, 1], [1, 2]] - sage: len(Permutation([3, 1, 5, 4, 2]).shifted_shuffle(Permutation([2, 1, 4, 3]))) + sage: p = Permutation([3, 1, 5, 4, 2]) + sage: len(p.shifted_shuffle(Permutation([2, 1, 4, 3]))) # optional - sage.graphs 126 The shifted shuffle product is associative. We can test this on an admittedly toy example:: - sage: all( all( all( sorted(flatten([abs.shifted_shuffle(c) + sage: all( all( all( sorted(flatten([abs.shifted_shuffle(c) # optional - sage.graphs ....: for abs in a.shifted_shuffle(b)])) ....: == sorted(flatten([a.shifted_shuffle(bcs) ....: for bcs in b.shifted_shuffle(c)])) @@ -5351,7 +5373,7 @@ def shifted_shuffle(self, other): permutations as the ``shifted_shuffle`` method on words (but is faster):: - sage: all( all( sorted(p1.shifted_shuffle(p2)) + sage: all( all( sorted(p1.shifted_shuffle(p2)) # optional - sage.graphs ....: == sorted([Permutation(p) for p in ....: Word(p1).shifted_shuffle(Word(p2))]) ....: for p2 in Permutations(3) ) @@ -5368,9 +5390,9 @@ def _tableau_contribution(T): EXAMPLES:: - sage: T = Tableau([[1,1,1],[2]]) + sage: T = Tableau([[1,1,1],[2]]) # optional - sage.combinat sage: from sage.combinat.permutation import _tableau_contribution - sage: _tableau_contribution(T) + sage: _tableau_contribution(T) # optional - sage.combinat 3 """ from sage.combinat.tableau import StandardTableaux @@ -5460,7 +5482,7 @@ class Permutations(UniqueRepresentation, Parent): sage: p = Permutations(['c', 'a', 't'], 2); p Permutations of the set ['c', 'a', 't'] of length 2 - sage: p.list() + sage: p.list() # optional - sage.libs.gap [['c', 'a'], ['c', 't'], ['a', 'c'], ['a', 't'], ['t', 'c'], ['t', 'a']] :: @@ -5474,27 +5496,29 @@ class Permutations(UniqueRepresentation, Parent): sage: p = Permutations([1,1,2], 2); p Permutations of the multi-set [1, 1, 2] of length 2 - sage: p.list() + sage: p.list() # optional - sage.libs.gap [[1, 1], [1, 2], [2, 1]] :: sage: p = Permutations(descents=([1], 4)); p Standard permutations of 4 with descents [1] - sage: p.list() + sage: p.list() # optional - sage.graphs [[2, 4, 1, 3], [3, 4, 1, 2], [1, 4, 2, 3], [1, 3, 2, 4], [2, 3, 1, 4]] :: sage: p = Permutations(bruhat_smaller=[1,3,2,4]); p - Standard permutations that are less than or equal to [1, 3, 2, 4] in the Bruhat order + Standard permutations that are less than or equal + to [1, 3, 2, 4] in the Bruhat order sage: p.list() [[1, 2, 3, 4], [1, 3, 2, 4]] :: sage: p = Permutations(bruhat_greater=[4,2,3,1]); p - Standard permutations that are greater than or equal to [4, 2, 3, 1] in the Bruhat order + Standard permutations that are greater than or equal + to [4, 2, 3, 1] in the Bruhat order sage: p.list() [[4, 2, 3, 1], [4, 3, 2, 1]] @@ -5502,28 +5526,28 @@ class Permutations(UniqueRepresentation, Parent): sage: p = Permutations(recoils_finer=[2,1]); p Standard permutations whose recoils composition is finer than [2, 1] - sage: p.list() + sage: p.list() # optional - sage.graphs [[3, 1, 2], [1, 2, 3], [1, 3, 2]] :: sage: p = Permutations(recoils_fatter=[2,1]); p Standard permutations whose recoils composition is fatter than [2, 1] - sage: p.list() + sage: p.list() # optional - sage.graphs [[3, 1, 2], [3, 2, 1], [1, 3, 2]] :: sage: p = Permutations(recoils=[2,1]); p Standard permutations whose recoils composition is [2, 1] - sage: p.list() + sage: p.list() # optional - sage.graphs [[3, 1, 2], [1, 3, 2]] :: sage: p = Permutations(4, avoiding=[1,3,2]); p Standard permutations of 4 avoiding [[1, 3, 2]] - sage: p.list() + sage: p.list() # optional - sage.combinat [[4, 1, 2, 3], [4, 2, 1, 3], [4, 2, 3, 1], @@ -5543,9 +5567,9 @@ class Permutations(UniqueRepresentation, Parent): sage: p = Permutations(5, avoiding=[[3,4,1,2], [4,2,3,1]]); p Standard permutations of 5 avoiding [[3, 4, 1, 2], [4, 2, 3, 1]] - sage: p.cardinality() + sage: p.cardinality() # optional - sage.combinat 88 - sage: p.random_element().parent() is p + sage: p.random_element().parent() is p # optional - sage.combinat True """ @staticmethod @@ -5892,14 +5916,14 @@ class Permutations_mset(Permutations): [2, 2, 1, 1, 2], [2, 2, 1, 2, 1], [2, 2, 2, 1, 1]] - sage: MS = MatrixSpace(GF(2),2,2) - sage: A = MS([1,0,1,1]) - sage: rows = A.rows() - sage: rows[0].set_immutable() - sage: rows[1].set_immutable() - sage: P = Permutations_mset(rows); P + sage: MS = MatrixSpace(GF(2), 2, 2) # optional - sage.modules sage.rings.finite_rings + sage: A = MS([1,0,1,1]) # optional - sage.modules sage.rings.finite_rings + sage: rows = A.rows() # optional - sage.modules sage.rings.finite_rings + sage: rows[0].set_immutable() # optional - sage.modules sage.rings.finite_rings + sage: rows[1].set_immutable() # optional - sage.modules sage.rings.finite_rings + sage: P = Permutations_mset(rows); P # optional - sage.modules sage.rings.finite_rings Permutations of the multi-set [(1, 0), (1, 1)] - sage: sorted(P) + sage: sorted(P) # optional - sage.modules sage.rings.finite_rings [[(1, 0), (1, 1)], [(1, 1), (1, 0)]] """ @staticmethod @@ -6409,7 +6433,7 @@ def __init__(self, mset, k): TESTS:: sage: P = Permutations([1,2,2],2) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.libs.gap """ Permutations_mset.__init__(self, mset) self._k = k @@ -6442,7 +6466,7 @@ def _repr_(self): """ TESTS:: - sage: Permutations([1,2,2],2) + sage: Permutations([1,2,2], 2) Permutations of the multi-set [1, 2, 2] of length 2 """ return "Permutations of the multi-set %s of length %s" % (list(self.mset), self._k) @@ -6453,7 +6477,7 @@ def cardinality(self): EXAMPLES:: - sage: Permutations([1,2,2],2).cardinality() + sage: Permutations([1,2,2], 2).cardinality() # optional - sage.libs.gap 3 """ return ZZ.sum(1 for z in self) @@ -6462,7 +6486,7 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations([1,2,2],2).list() + sage: Permutations([1,2,2], 2).list() # optional - sage.libs.gap [[1, 2], [2, 1], [2, 2]] """ mset = self.mset @@ -6571,7 +6595,7 @@ class Arrangements(Permutations): EXAMPLES:: sage: mset = [1,1,2,3,4,4,5] - sage: Arrangements(mset,2).list() + sage: Arrangements(mset, 2).list() # optional - sage.libs.gap [[1, 1], [1, 2], [1, 3], @@ -6594,11 +6618,11 @@ class Arrangements(Permutations): [5, 2], [5, 3], [5, 4]] - sage: Arrangements(mset,2).cardinality() + sage: Arrangements(mset, 2).cardinality() # optional - sage.libs.gap 22 - sage: Arrangements( ["c","a","t"], 2 ).list() + sage: Arrangements( ["c","a","t"], 2 ).list() # optional - sage.libs.gap [['c', 'a'], ['c', 't'], ['a', 'c'], ['a', 't'], ['t', 'c'], ['t', 'a']] - sage: Arrangements( ["c","a","t"], 3 ).list() + sage: Arrangements( ["c","a","t"], 3 ).list() # optional - sage.libs.gap [['c', 'a', 't'], ['c', 't', 'a'], ['a', 'c', 't'], @@ -6630,7 +6654,7 @@ def cardinality(self): EXAMPLES:: sage: A = Arrangements([1,1,2,3,4,4,5], 2) - sage: A.cardinality() + sage: A.cardinality() # optional - sage.libs.gap 22 """ one = ZZ.one() @@ -6796,21 +6820,21 @@ def _element_constructor_(self, x, check=True): sage: P([2,3,1]) [2, 3, 1, 4, 5] - sage: G = SymmetricGroup(4) + sage: G = SymmetricGroup(4) # optional - sage.groups sage: P = Permutations(4) - sage: x = G([4,3,1,2]); x + sage: x = G([4,3,1,2]); x # optional - sage.groups (1,4,2,3) - sage: P(x) + sage: P(x) # optional - sage.groups [4, 3, 1, 2] - sage: G(P(x)) + sage: G(P(x)) # optional - sage.groups (1,4,2,3) - sage: P = PermutationGroup([[(1,3,5),(2,4)],[(1,3)]]) - sage: x = P([(3,5),(2,4)]); x + sage: P = PermutationGroup([[(1,3,5),(2,4)],[(1,3)]]) # optional - sage.groups + sage: x = P([(3,5),(2,4)]); x # optional - sage.groups (2,4)(3,5) - sage: Permutations(6)(SymmetricGroup(6)(x)) + sage: Permutations(6)(SymmetricGroup(6)(x)) # optional - sage.groups [1, 4, 5, 2, 3, 6] - sage: Permutations(6)(x) # known bug + sage: Permutations(6)(x) # known bug # optional - sage.groups [1, 4, 5, 2, 3, 6] """ if len(x) < self.n: @@ -6901,20 +6925,20 @@ def _coerce_map_from_(self, G): EXAMPLES:: sage: P = Permutations(6) - sage: P.has_coerce_map_from(SymmetricGroup(6)) + sage: P.has_coerce_map_from(SymmetricGroup(6)) # optional - sage.groups True - sage: P.has_coerce_map_from(SymmetricGroup(5)) + sage: P.has_coerce_map_from(SymmetricGroup(5)) # optional - sage.groups True - sage: P.has_coerce_map_from(SymmetricGroup(7)) + sage: P.has_coerce_map_from(SymmetricGroup(7)) # optional - sage.groups False sage: P.has_coerce_map_from(Permutations(5)) True sage: P.has_coerce_map_from(Permutations(7)) False - sage: P.has_coerce_map_from(groups.misc.Cactus(5)) + sage: P.has_coerce_map_from(groups.misc.Cactus(5)) # optional - sage.groups True - sage: P.has_coerce_map_from(groups.misc.Cactus(7)) + sage: P.has_coerce_map_from(groups.misc.Cactus(7)) # optional - sage.groups False """ if isinstance(G, SymmetricGroup): @@ -6924,7 +6948,6 @@ def _coerce_map_from_(self, G): return self._from_permutation_group_element if isinstance(G, StandardPermutations_n) and G.n <= self.n: return True - from sage.groups.cactus_group import CactusGroup if isinstance(G, CactusGroup) and G.n() <= self.n: return self._from_cactus_group_element return super()._coerce_map_from_(G) @@ -6936,9 +6959,9 @@ def _from_permutation_group_element(self, x): TESTS:: sage: P = Permutations(4) - sage: G = SymmetricGroup(4) - sage: x = G([4,3,1,2]) - sage: P._from_permutation_group_element(x) + sage: G = SymmetricGroup(4) # optional - sage.groups + sage: x = G([4,3,1,2]) # optional - sage.groups + sage: P._from_permutation_group_element(x) # optional - sage.groups [4, 3, 1, 2] """ return self(x.domain()) @@ -6949,11 +6972,11 @@ def _from_cactus_group_element(self, x): EXAMPLES:: - sage: J3 = groups.misc.Cactus(3) - sage: s12,s13,s23 = J3.gens() - sage: elt = s12 * s23 * s13 - sage: P5 = Permutations(5) - sage: P5._from_cactus_group_element(elt) + sage: J3 = groups.misc.Cactus(3) # optional - sage.groups + sage: s12,s13,s23 = J3.gens() # optional - sage.groups + sage: elt = s12 * s23 * s13 # optional - sage.groups + sage: P5 = Permutations(5) # optional - sage.groups + sage: P5._from_cactus_group_element(elt) # optional - sage.groups [1, 3, 2, 4, 5] """ return self(x.to_permutation()) @@ -6965,12 +6988,11 @@ def as_permutation_group(self): EXAMPLES:: sage: P = Permutations(4) - sage: PG = P.as_permutation_group() - sage: PG + sage: PG = P.as_permutation_group(); PG # optional - sage.groups Symmetric group of order 4! as a permutation group - sage: G = SymmetricGroup(4) - sage: PG is G + sage: G = SymmetricGroup(4) # optional - sage.groups + sage: PG is G # optional - sage.groups True """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -7119,7 +7141,7 @@ def element_in_conjugacy_classes(self, nu): EXAMPLES:: sage: PP = Permutations(5) - sage: PP.element_in_conjugacy_classes([2,2]) + sage: PP.element_in_conjugacy_classes([2,2]) # optional - sage.combinat [2, 1, 4, 3, 5] """ from sage.combinat.partition import Partition @@ -7151,7 +7173,7 @@ def conjugacy_classes_representatives(self): EXAMPLES:: sage: G = Permutations(5) - sage: G.conjugacy_classes_representatives() + sage: G.conjugacy_classes_representatives() # optional - sage.combinat [[1, 2, 3, 4, 5], [2, 1, 3, 4, 5], [2, 1, 4, 3, 5], @@ -7165,10 +7187,10 @@ def conjugacy_classes_representatives(self): Check some border cases:: sage: S = Permutations(0) - sage: S.conjugacy_classes_representatives() + sage: S.conjugacy_classes_representatives() # optional - sage.combinat [[]] sage: S = Permutations(1) - sage: S.conjugacy_classes_representatives() + sage: S.conjugacy_classes_representatives() # optional - sage.combinat [[1]] """ from sage.combinat.partition import Partitions_n @@ -7182,7 +7204,7 @@ def conjugacy_classes_iterator(self): EXAMPLES:: sage: G = Permutations(4) - sage: list(G.conjugacy_classes_iterator()) == G.conjugacy_classes() + sage: list(G.conjugacy_classes_iterator()) == G.conjugacy_classes() # optional - sage.combinat True """ from sage.combinat.partition import Partitions_n @@ -7197,7 +7219,7 @@ def conjugacy_classes(self): EXAMPLES:: sage: G = Permutations(4) - sage: G.conjugacy_classes() + sage: G.conjugacy_classes() # optional - sage.combinat [Conjugacy class of cycle type [1, 1, 1, 1] in Standard permutations of 4, Conjugacy class of cycle type [2, 1, 1] in Standard permutations of 4, Conjugacy class of cycle type [2, 2] in Standard permutations of 4, @@ -7218,9 +7240,9 @@ def conjugacy_class(self, g): sage: G = Permutations(5) sage: g = G([2,3,4,1,5]) - sage: G.conjugacy_class(g) + sage: G.conjugacy_class(g) # optional - sage.combinat Conjugacy class of cycle type [4, 1] in Standard permutations of 5 - sage: G.conjugacy_class(Partition([2, 1, 1, 1])) + sage: G.conjugacy_class(Partition([2, 1, 1, 1])) # optional - sage.combinat Conjugacy class of cycle type [2, 1, 1, 1] in Standard permutations of 5 """ from sage.groups.perm_gps.symgp_conjugacy_class import PermutationsConjugacyClass @@ -7238,15 +7260,16 @@ def algebra(self, base_ring, category=None): EXAMPLES:: sage: P = Permutations(4) - sage: A = P.algebra(QQ); A + sage: A = P.algebra(QQ); A # optional - sage.combinat sage.modules Symmetric group algebra of order 4 over Rational Field - sage: A.category() + sage: A.category() # optional - sage.combinat sage.modules Join of Category of coxeter group algebras over Rational Field and Category of finite group algebras over Rational Field - and Category of finite dimensional cellular algebras with basis over Rational Field - sage: A = P.algebra(QQ, category=Monoids()) - sage: A.category() + and Category of finite dimensional cellular algebras + with basis over Rational Field + sage: A = P.algebra(QQ, category=Monoids()) # optional - sage.combinat sage.modules + sage: A.category() # optional - sage.combinat sage.modules Category of finite dimensional cellular monoid algebras over Rational Field """ from sage.combinat.symmetric_group_algebra import SymmetricGroupAlgebra @@ -7275,9 +7298,9 @@ def cartan_type(self): EXAMPLES:: - sage: A = SymmetricGroup([2,3,7]); A.cartan_type() + sage: A = SymmetricGroup([2,3,7]); A.cartan_type() # optional - sage.combinat sage.groups ['A', 2] - sage: A = SymmetricGroup([]); A.cartan_type() + sage: A = SymmetricGroup([]); A.cartan_type() # optional - sage.combinat sage.groups ['A', 0] """ from sage.combinat.root_system.cartan_type import CartanType @@ -7542,8 +7565,8 @@ def from_permutation_group_element(pge, parent=None): EXAMPLES:: sage: import sage.combinat.permutation as permutation - sage: pge = PermutationGroupElement([(1,2),(3,4)]) - sage: permutation.from_permutation_group_element(pge) + sage: pge = PermutationGroupElement([(1,2),(3,4)]) # optional - sage.groups + sage: permutation.from_permutation_group_element(pge) # optional - sage.groups [2, 1, 4, 3] """ if not isinstance(pge, PermutationGroupElement): @@ -7852,25 +7875,26 @@ def bistochastic_as_sum_of_permutations(M, check = True): sage: L.append((6,Permutation([5, 3, 4, 1, 2]))) sage: L.append((3,Permutation([3, 1, 4, 2, 5]))) sage: L.append((2,Permutation([1, 4, 2, 3, 5]))) - sage: M = sum([c * p.to_matrix() for (c,p) in L]) - sage: decomp = bistochastic_as_sum_of_permutations(M) - sage: print(decomp) - 2*B[[1, 4, 2, 3, 5]] + 3*B[[3, 1, 4, 2, 5]] + 9*B[[4, 1, 3, 5, 2]] + 6*B[[5, 3, 4, 1, 2]] + sage: M = sum([c * p.to_matrix() for (c,p) in L]) # optional - sage.modules + sage: decomp = bistochastic_as_sum_of_permutations(M) # optional - sage.graphs sage.modules + sage: print(decomp) # optional - sage.graphs sage.modules + 2*B[[1, 4, 2, 3, 5]] + 3*B[[3, 1, 4, 2, 5]] + + 9*B[[4, 1, 3, 5, 2]] + 6*B[[5, 3, 4, 1, 2]] An exception is raised when the matrix is not positive and bistochastic:: - sage: M = Matrix([[2,3],[2,2]]) - sage: decomp = bistochastic_as_sum_of_permutations(M) + sage: M = Matrix([[2,3],[2,2]]) # optional - sage.modules + sage: decomp = bistochastic_as_sum_of_permutations(M) # optional - sage.graphs sage.modules Traceback (most recent call last): ... ValueError: The matrix is not bistochastic - sage: bistochastic_as_sum_of_permutations(Matrix(GF(7), 2, [2,1,1,2])) + sage: bistochastic_as_sum_of_permutations(Matrix(GF(7), 2, [2,1,1,2])) # optional - sage.graphs sage.modules sage.rings.finite_rings Traceback (most recent call last): ... ValueError: The base ring of the matrix must have a coercion map to RR - sage: bistochastic_as_sum_of_permutations(Matrix(ZZ, 2, [2,-1,-1,2])) + sage: bistochastic_as_sum_of_permutations(Matrix(ZZ, 2, [2,-1,-1,2])) # optional - sage.graphs sage.modules Traceback (most recent call last): ... ValueError: The matrix should have nonnegative entries @@ -7937,12 +7961,12 @@ def bounded_affine_permutation(A): EXAMPLES:: sage: from sage.combinat.permutation import bounded_affine_permutation - sage: A = Matrix(ZZ, [[1,0,0,0], [0,1,0,0]]) - sage: bounded_affine_permutation(A) + sage: A = Matrix(ZZ, [[1,0,0,0], [0,1,0,0]]) # optional - sage.modules + sage: bounded_affine_permutation(A) # optional - sage.modules [5, 6, 3, 4] - sage: A = Matrix(ZZ, [[0,1,0,1,0], [0,0,1,1,0]]) - sage: bounded_affine_permutation(A) + sage: A = Matrix(ZZ, [[0,1,0,1,0], [0,0,1,1,0]]) # optional - sage.modules + sage: bounded_affine_permutation(A) # optional - sage.modules [1, 4, 7, 8, 5] REFERENCES: @@ -8002,7 +8026,7 @@ def __init__(self, d, n): TESTS:: sage: P = Permutations(descents=([1,0,2], 5)) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.graphs """ StandardPermutations_n_abstract.__init__(self, n) self._d = d @@ -8038,14 +8062,15 @@ def cardinality(self): sage: Permutations(descents=([1,4], 6)).cardinality() 40 - sage: P = lambda D, n: Permutations(descents=(D, n+1)) - sage: all(P(D, n).cardinality() == len(P(D, n).list()) + sage: def P(D, n): + ....: return Permutations(descents=(D, n + 1)) + sage: all(P(D, n).cardinality() == len(P(D, n).list()) # optional - sage.graphs ....: for n in range(5) for D in subsets(range(n))) True - sage: n = 20; + sage: n = 20 sage: D = [6, 8, 10, 11, 12, 13, 14, 15, 17, 19] - sage: P(D, n).cardinality() + sage: P(D, n).cardinality() # optional - sage.graphs 125291047596 """ @@ -8104,7 +8129,7 @@ def __iter__(self): EXAMPLES:: - sage: Permutations(descents=([2,0],5)).list() + sage: Permutations(descents=([2,0],5)).list() # optional - sage.graphs [[5, 2, 4, 1, 3], [5, 3, 4, 1, 2], [4, 3, 5, 1, 2], @@ -8133,7 +8158,7 @@ def descents_composition_list(dc): EXAMPLES:: sage: import sage.combinat.permutation as permutation - sage: permutation.descents_composition_list([1,2,2]) + sage: permutation.descents_composition_list([1,2,2]) # optional - sage.graphs [[5, 2, 4, 1, 3], [5, 3, 4, 1, 2], [4, 3, 5, 1, 2], @@ -8226,7 +8251,7 @@ def __init__(self, recoils): TESTS:: sage: P = Permutations(recoils_finer=[2,2]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.graphs """ Permutations.__init__(self, category=FiniteEnumeratedSets()) self.recoils = recoils @@ -8247,7 +8272,7 @@ def __iter__(self): EXAMPLES:: - sage: Permutations(recoils_finer=[2,2]).list() + sage: Permutations(recoils_finer=[2,2]).list() # optional - sage.graphs [[3, 1, 4, 2], [3, 4, 1, 2], [1, 3, 4, 2], @@ -8294,7 +8319,7 @@ def __init__(self, recoils): TESTS:: sage: P = Permutations(recoils_fatter=[2,2]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.graphs """ Permutations.__init__(self, category=FiniteEnumeratedSets()) self.recoils = recoils @@ -8315,7 +8340,7 @@ def __iter__(self): EXAMPLES:: - sage: Permutations(recoils_fatter=[2,2]).list() + sage: Permutations(recoils_fatter=[2,2]).list() # optional - sage.graphs [[4, 3, 2, 1], [3, 2, 1, 4], [3, 2, 4, 1], @@ -8369,7 +8394,7 @@ def __init__(self, recoils): TESTS:: sage: P = Permutations(recoils=[2,2]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.graphs """ Permutations.__init__(self, category=FiniteEnumeratedSets()) self.recoils = recoils @@ -8390,7 +8415,7 @@ def __iter__(self): EXAMPLES:: - sage: Permutations(recoils=[2,2]).list() + sage: Permutations(recoils=[2,2]).list() # optional - sage.graphs [[3, 1, 4, 2], [3, 4, 1, 2], [1, 3, 4, 2], [1, 3, 2, 4], [3, 1, 2, 4]] """ recoils = self.recoils @@ -8682,8 +8707,6 @@ def permutohedron_lequal(p1, p2, side="right"): ############ # Patterns # ############ -from sage.combinat.words.finite_word import evaluation_dict - def to_standard(p, key=None): r""" @@ -8698,15 +8721,15 @@ def to_standard(p, key=None): EXAMPLES:: sage: import sage.combinat.permutation as permutation - sage: permutation.to_standard([4,2,7]) + sage: permutation.to_standard([4,2,7]) # optional - sage.combinat [2, 1, 3] - sage: permutation.to_standard([1,2,3]) + sage: permutation.to_standard([1,2,3]) # optional - sage.combinat [1, 2, 3] - sage: permutation.to_standard([]) + sage: permutation.to_standard([]) # optional - sage.combinat [] - sage: permutation.to_standard([1,2,3], key=lambda x: -x) + sage: permutation.to_standard([1,2,3], key=lambda x: -x) # optional - sage.combinat [3, 2, 1] - sage: permutation.to_standard([5,8,2,5], key=lambda x: -x) + sage: permutation.to_standard([5,8,2,5], key=lambda x: -x) # optional - sage.combinat [2, 1, 4, 3] TESTS: @@ -8714,7 +8737,7 @@ def to_standard(p, key=None): Does not mutate the list:: sage: a = [1,2,4] - sage: permutation.to_standard(a) + sage: permutation.to_standard(a) # optional - sage.combinat [1, 2, 3] sage: a [1, 2, 4] @@ -8733,8 +8756,8 @@ def to_standard(p, key=None): ....: i += 1 ....: c[smallest_index] = biggest ....: return Permutations()(s) - sage: p = list(Words(100, 1000).random_element()) - sage: std(p) == permutation.to_standard(p) + sage: p = list(Words(100, 1000).random_element()) # optional - sage.combinat + sage: std(p) == permutation.to_standard(p) # optional - sage.combinat True """ ev_dict = evaluation_dict(p) @@ -8764,14 +8787,14 @@ class CyclicPermutations(Permutations_mset): EXAMPLES:: - sage: CyclicPermutations(range(4)).list() + sage: CyclicPermutations(range(4)).list() # optional - sage.combinat [[0, 1, 2, 3], [0, 1, 3, 2], [0, 2, 1, 3], [0, 2, 3, 1], [0, 3, 1, 2], [0, 3, 2, 1]] - sage: CyclicPermutations([1,1,1]).list() + sage: CyclicPermutations([1,1,1]).list() # optional - sage.combinat [[1, 1, 1]] """ @staticmethod @@ -8806,16 +8829,16 @@ def __iter__(self, distinct=False): """ EXAMPLES:: - sage: CyclicPermutations(range(4)).list() # indirect doctest + sage: CyclicPermutations(range(4)).list() # indirect doctest # optional - sage.combinat [[0, 1, 2, 3], [0, 1, 3, 2], [0, 2, 1, 3], [0, 2, 3, 1], [0, 3, 1, 2], [0, 3, 2, 1]] - sage: CyclicPermutations([1,1,1]).list() + sage: CyclicPermutations([1,1,1]).list() # optional - sage.combinat [[1, 1, 1]] - sage: CyclicPermutations([1,1,1]).list(distinct=True) + sage: CyclicPermutations([1,1,1]).list(distinct=True) # optional - sage.combinat [[1, 1, 1], [1, 1, 1]] """ if distinct: @@ -8836,7 +8859,7 @@ def list(self, distinct=False): """ EXAMPLES:: - sage: CyclicPermutations(range(4)).list() + sage: CyclicPermutations(range(4)).list() # optional - sage.combinat [[0, 1, 2, 3], [0, 1, 3, 2], [0, 2, 1, 3], @@ -8857,7 +8880,7 @@ class CyclicPermutationsOfPartition(Permutations): EXAMPLES:: - sage: CyclicPermutationsOfPartition([[1,2,3,4],[5,6,7]]).list() + sage: CyclicPermutationsOfPartition([[1,2,3,4],[5,6,7]]).list() # optional - sage.combinat [[[1, 2, 3, 4], [5, 6, 7]], [[1, 2, 4, 3], [5, 6, 7]], [[1, 3, 2, 4], [5, 6, 7]], @@ -8873,7 +8896,7 @@ class CyclicPermutationsOfPartition(Permutations): :: - sage: CyclicPermutationsOfPartition([[1,2,3,4],[4,4,4]]).list() + sage: CyclicPermutationsOfPartition([[1,2,3,4],[4,4,4]]).list() # optional - sage.combinat [[[1, 2, 3, 4], [4, 4, 4]], [[1, 2, 4, 3], [4, 4, 4]], [[1, 3, 2, 4], [4, 4, 4]], @@ -8883,12 +8906,12 @@ class CyclicPermutationsOfPartition(Permutations): :: - sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list() + sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list() # optional - sage.combinat [[[1, 2, 3], [4, 4, 4]], [[1, 3, 2], [4, 4, 4]]] :: - sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list(distinct=True) + sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list(distinct=True) # optional - sage.combinat [[[1, 2, 3], [4, 4, 4]], [[1, 3, 2], [4, 4, 4]], [[1, 2, 3], [4, 4, 4]], @@ -8916,7 +8939,7 @@ def __init__(self, partition): sage: CP = CyclicPermutationsOfPartition([[1,2,3,4],[5,6,7]]) sage: CP Cyclic permutations of partition [[1, 2, 3, 4], [5, 6, 7]] - sage: TestSuite(CP).run() + sage: TestSuite(CP).run() # optional - sage.combinat """ self.partition = partition Permutations.__init__(self, category=FiniteEnumeratedSets()) @@ -8933,8 +8956,8 @@ def check(self): EXAMPLES:: sage: CP = CyclicPermutationsOfPartition([[1,2,3,4],[5,6,7]]) - sage: elt = CP[0] - sage: elt.check() + sage: elt = CP[0] # optional - sage.combinat + sage: elt.check() # optional - sage.combinat """ if [sorted(_) for _ in self] != [sorted(_) for _ in self.parent().partition]: raise ValueError("Invalid cyclic permutation of the partition" % self.parent().partition) @@ -8957,7 +8980,8 @@ def __iter__(self, distinct=False): EXAMPLES:: - sage: CyclicPermutationsOfPartition([[1,2,3,4],[5,6,7]]).list() # indirect doctest + sage: CyclicPermutationsOfPartition([[1,2,3,4], # indirect doctest # optional - sage.combinat + ....: [5,6,7]]).list() [[[1, 2, 3, 4], [5, 6, 7]], [[1, 2, 4, 3], [5, 6, 7]], [[1, 3, 2, 4], [5, 6, 7]], @@ -8973,7 +8997,7 @@ def __iter__(self, distinct=False): :: - sage: CyclicPermutationsOfPartition([[1,2,3,4],[4,4,4]]).list() + sage: CyclicPermutationsOfPartition([[1,2,3,4],[4,4,4]]).list() # optional - sage.combinat [[[1, 2, 3, 4], [4, 4, 4]], [[1, 2, 4, 3], [4, 4, 4]], [[1, 3, 2, 4], [4, 4, 4]], @@ -8983,12 +9007,12 @@ def __iter__(self, distinct=False): :: - sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list() + sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list() # optional - sage.combinat [[[1, 2, 3], [4, 4, 4]], [[1, 3, 2], [4, 4, 4]]] :: - sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list(distinct=True) + sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list(distinct=True) # optional - sage.combinat [[[1, 2, 3], [4, 4, 4]], [[1, 3, 2], [4, 4, 4]], [[1, 2, 3], [4, 4, 4]], @@ -9008,9 +9032,9 @@ def list(self, distinct=False): """ EXAMPLES:: - sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list() + sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list() # optional - sage.combinat [[[1, 2, 3], [4, 4, 4]], [[1, 3, 2], [4, 4, 4]]] - sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list(distinct=True) + sage: CyclicPermutationsOfPartition([[1,2,3],[4,4,4]]).list(distinct=True) # optional - sage.combinat [[[1, 2, 3], [4, 4, 4]], [[1, 3, 2], [4, 4, 4]], [[1, 2, 3], [4, 4, 4]], @@ -9046,7 +9070,7 @@ def __init__(self, a): TESTS:: sage: P = Permutations(avoiding=[[2,1,3],[1,2,3]]) - sage: TestSuite(P).run(max_runs=25) + sage: TestSuite(P).run(max_runs=25) # optional - sage.combinat """ Permutations.__init__(self, category=InfiniteEnumeratedSets()) self._a = a @@ -9076,13 +9100,13 @@ def __contains__(self, x): """ TESTS:: - sage: [1,3,2] in Permutations(avoiding=[1,3,2]) + sage: [1,3,2] in Permutations(avoiding=[1,3,2]) # optional - sage.combinat False - sage: [1,3,2] in Permutations(avoiding=[[1,3,2]]) + sage: [1,3,2] in Permutations(avoiding=[[1,3,2]]) # optional - sage.combinat False - sage: [2,1,3] in Permutations(avoiding=[[1,3,2],[1,2,3]]) + sage: [2,1,3] in Permutations(avoiding=[[1,3,2],[1,2,3]]) # optional - sage.combinat True - sage: [2,1,3] in Permutations(avoiding=[]) + sage: [2,1,3] in Permutations(avoiding=[]) # optional - sage.combinat True """ if not super().__contains__(x): @@ -9097,7 +9121,7 @@ def __iter__(self): TESTS:: sage: it = iter(Permutations(avoiding=[[2,1,3],[1,2,3]])) - sage: [next(it) for i in range(10)] + sage: [next(it) for i in range(10)] # optional - sage.combinat [[], [1], [1, 2], @@ -9142,7 +9166,7 @@ def __init__(self, n, a): EXAMPLES:: sage: P = Permutations(3, avoiding=[[2,1,3],[1,2,3]]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat sage: type(P) """ @@ -9183,13 +9207,13 @@ def __contains__(self, x): """ TESTS:: - sage: [1,3,2] in Permutations(3, avoiding=[1,3,2]) + sage: [1,3,2] in Permutations(3, avoiding=[1,3,2]) # optional - sage.combinat False - sage: [1,3,2] in Permutations(3, avoiding=[[1,3,2]]) + sage: [1,3,2] in Permutations(3, avoiding=[[1,3,2]]) # optional - sage.combinat False - sage: [2,1,3] in Permutations(3, avoiding=[[1,3,2],[1,2,3]]) + sage: [2,1,3] in Permutations(3, avoiding=[[1,3,2],[1,2,3]]) # optional - sage.combinat True - sage: [2,1,3] in Permutations(3, avoiding=[]) + sage: [2,1,3] in Permutations(3, avoiding=[]) # optional - sage.combinat True """ if not super().__contains__(x): @@ -9210,9 +9234,9 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[[2, 1, 3],[1,2,3]]).list() + sage: Permutations(3, avoiding=[[2, 1, 3],[1,2,3]]).list() # optional - sage.combinat [[1, 3, 2], [3, 1, 2], [2, 3, 1], [3, 2, 1]] - sage: Permutations(0, avoiding=[[2, 1, 3],[1,2,3]]).list() + sage: Permutations(0, avoiding=[[2, 1, 3],[1,2,3]]).list() # optional - sage.combinat [[]] """ if self.n > 0: @@ -9226,7 +9250,7 @@ def cardinality(self): EXAMPLES:: sage: P = Permutations(3, avoiding=[[2, 1, 3],[1,2,3]]) - sage: P.cardinality() + sage: P.cardinality() # optional - sage.combinat 4 """ one = ZZ.one() @@ -9239,7 +9263,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[1, 2]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([1, 2]),)) @@ -9247,7 +9271,7 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[1,2]).list() + sage: Permutations(3, avoiding=[1,2]).list() # optional - sage.combinat [[3, 2, 1]] """ yield self.element_class(self, range(self.n, 0, -1), check=False) @@ -9259,7 +9283,7 @@ def cardinality(self): EXAMPLES:: sage: P = Permutations(3, avoiding=[1, 2]) - sage: P.cardinality() + sage: P.cardinality() # optional - sage.combinat 1 """ return ZZ.one() @@ -9271,7 +9295,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[2, 1]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([2, 1]),)) @@ -9279,7 +9303,7 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[2,1]).list() + sage: Permutations(3, avoiding=[2,1]).list() # optional - sage.combinat [[1, 2, 3]] """ yield self.element_class(self, range(1, self.n+1), check=False) @@ -9291,7 +9315,7 @@ def cardinality(self): EXAMPLES:: sage: P = Permutations(3, avoiding=[2, 1]) - sage: P.cardinality() + sage: P.cardinality() # optional - sage.combinat 1 """ return ZZ.one() @@ -9303,7 +9327,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[1, 3, 2]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([1, 3, 2]),)) @@ -9313,7 +9337,7 @@ def cardinality(self): sage: Permutations(5, avoiding=[1, 3, 2]).cardinality() 42 - sage: len( Permutations(5, avoiding=[1, 3, 2]).list() ) + sage: len( Permutations(5, avoiding=[1, 3, 2]).list() ) # optional - sage.combinat 42 """ return catalan_number(self.n) @@ -9322,9 +9346,9 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[1,3,2]).list() # indirect doctest + sage: Permutations(3, avoiding=[1,3,2]).list() # indirect doctest # optional - sage.combinat [[1, 2, 3], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] - sage: Permutations(4, avoiding=[1,3,2]).list() + sage: Permutations(4, avoiding=[1,3,2]).list() # optional - sage.combinat [[4, 1, 2, 3], [4, 2, 1, 3], [4, 2, 3, 1], @@ -9380,7 +9404,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[2, 1, 3]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([1, 2, 3]),)) @@ -9388,9 +9412,9 @@ def cardinality(self) -> Integer: """ EXAMPLES:: - sage: Permutations(5, avoiding=[1, 2, 3]).cardinality() + sage: Permutations(5, avoiding=[1, 2, 3]).cardinality() # optional - sage.combinat 42 - sage: len( Permutations(5, avoiding=[1, 2, 3]).list() ) + sage: len( Permutations(5, avoiding=[1, 2, 3]).list() ) # optional - sage.combinat 42 """ return catalan_number(self.n) @@ -9399,11 +9423,11 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[1, 2, 3]).list() # indirect doctest + sage: Permutations(3, avoiding=[1, 2, 3]).list() # indirect doctest # optional - sage.combinat [[1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] - sage: Permutations(2, avoiding=[1, 2, 3]).list() + sage: Permutations(2, avoiding=[1, 2, 3]).list() # optional - sage.combinat [[1, 2], [2, 1]] - sage: Permutations(3, avoiding=[1, 2, 3]).list() + sage: Permutations(3, avoiding=[1, 2, 3]).list() # optional - sage.combinat [[1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] """ if self.n == 0: @@ -9452,7 +9476,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[3, 2, 1]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([3, 2, 1]),)) @@ -9460,9 +9484,9 @@ def cardinality(self): """ EXAMPLES:: - sage: Permutations(5, avoiding=[3, 2, 1]).cardinality() + sage: Permutations(5, avoiding=[3, 2, 1]).cardinality() # optional - sage.combinat 42 - sage: len( Permutations(5, avoiding=[3, 2, 1]).list() ) + sage: len( Permutations(5, avoiding=[3, 2, 1]).list() ) # optional - sage.combinat 42 """ return catalan_number(self.n) @@ -9471,7 +9495,7 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[3, 2, 1]).list() #indirect doctest + sage: Permutations(3, avoiding=[3, 2, 1]).list() # indirect doctest # optional - sage.combinat [[2, 3, 1], [3, 1, 2], [1, 3, 2], [2, 1, 3], [1, 2, 3]] """ for p in StandardPermutations_avoiding_123(self.n): @@ -9484,7 +9508,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[2, 3, 1]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([2, 3, 1]),)) @@ -9492,9 +9516,9 @@ def cardinality(self): """ EXAMPLES:: - sage: Permutations(5, avoiding=[2, 3, 1]).cardinality() + sage: Permutations(5, avoiding=[2, 3, 1]).cardinality() # optional - sage.combinat 42 - sage: len( Permutations(5, avoiding=[2, 3, 1]).list() ) + sage: len( Permutations(5, avoiding=[2, 3, 1]).list() ) # optional - sage.combinat 42 """ return catalan_number(self.n) @@ -9503,7 +9527,7 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[2, 3, 1]).list() + sage: Permutations(3, avoiding=[2, 3, 1]).list() # optional - sage.combinat [[3, 2, 1], [3, 1, 2], [1, 3, 2], [2, 1, 3], [1, 2, 3]] """ for p in StandardPermutations_avoiding_132(self.n): @@ -9516,7 +9540,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[3, 1, 2]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([3, 1, 2]),)) @@ -9526,7 +9550,7 @@ def cardinality(self): sage: Permutations(5, avoiding=[3, 1, 2]).cardinality() 42 - sage: len( Permutations(5, avoiding=[3, 1, 2]).list() ) + sage: len( Permutations(5, avoiding=[3, 1, 2]).list() ) # optional - sage.combinat 42 """ return catalan_number(self.n) @@ -9535,7 +9559,7 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[3, 1, 2]).list() + sage: Permutations(3, avoiding=[3, 1, 2]).list() # optional - sage.combinat [[3, 2, 1], [2, 3, 1], [2, 1, 3], [1, 3, 2], [1, 2, 3]] """ for p in StandardPermutations_avoiding_132(self.n): @@ -9548,7 +9572,7 @@ def __init__(self, n): TESTS:: sage: P = Permutations(3, avoiding=[2, 1, 3]) - sage: TestSuite(P).run() + sage: TestSuite(P).run() # optional - sage.combinat """ super().__init__(n, (Permutations()([2, 1, 3]),)) @@ -9558,7 +9582,7 @@ def cardinality(self): sage: Permutations(5, avoiding=[2, 1, 3]).cardinality() 42 - sage: len( Permutations(5, avoiding=[2, 1, 3]).list() ) + sage: len( Permutations(5, avoiding=[2, 1, 3]).list() ) # optional - sage.combinat 42 """ return catalan_number(self.n) @@ -9567,7 +9591,7 @@ def __iter__(self): """ EXAMPLES:: - sage: Permutations(3, avoiding=[2, 1, 3]).list() + sage: Permutations(3, avoiding=[2, 1, 3]).list() # optional - sage.combinat [[1, 2, 3], [1, 3, 2], [3, 1, 2], [2, 3, 1], [3, 2, 1]] """ for p in StandardPermutations_avoiding_132(self.n): @@ -9596,7 +9620,7 @@ def _rec(self, obj, state): sage: from sage.combinat.permutation import PatternAvoider sage: P = Permutations(4) sage: p = PatternAvoider(P, [[1,2]]) - sage: list(p._rec([1], 2)) + sage: list(p._rec([1], 2)) # optional - sage.combinat [([2, 1], 3, False)] """ i = state diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index 7e1f1c6e4c6..e2c1fb46ff3 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -126,7 +126,7 @@ def linear_extensions(self): sage: list(H.linear_extensions()) [[0, 1, 2, 3], [0, 2, 1, 3]] """ - from sage.combinat.combinat_cython import linear_extension_iterator + from sage.combinat.posets.linear_extension_iterator import linear_extension_iterator return linear_extension_iterator(self) def greedy_linear_extensions_iterator(self): diff --git a/src/sage/combinat/posets/linear_extension_iterator.pyx b/src/sage/combinat/posets/linear_extension_iterator.pyx new file mode 100644 index 00000000000..21437e91005 --- /dev/null +++ b/src/sage/combinat/posets/linear_extension_iterator.pyx @@ -0,0 +1,287 @@ +r""" +Fast linear extension iterator +""" +cimport cython + +from copy import copy +def _linear_extension_prepare(D): + r""" + The preprocessing routine in Figure 7 of "Generating Linear + Extensions Fast" by Preusse and Ruskey. + + INPUT: + + - ``D``, the Hasse diagram of a poset + + OUTPUT: + + - a triple ``(le, a, b)``, where ``le`` is the first linear + extension, and ``a`` and ``b`` are lists such that ``a[i]`` and + ``b[i]`` are minimal elements of ``D`` after removing ``a[:i]`` + and ``b[:i]``. + + TESTS:: + + sage: from sage.combinat.posets.linear_extension_iterator import _linear_extension_prepare + sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram + sage: _linear_extension_prepare(D) + ([0, 1, 2, 3, 4], [1, 3], [2, 4]) + + """ + dag_copy = copy(D) # this copy is destroyed during preparation + le = [] + a = [] + b = [] + + # the preprocessing routine found in Figure 7 of + # "Generating Linear Extensions Fast" by + # Pruesse and Ruskey + while dag_copy.num_verts() != 0: + # find all the minimal elements of dag_copy + minimal_elements = dag_copy.sources() + if not minimal_elements: + raise ValueError("the digraph must be acyclic to have linear extensions") + elif len(minimal_elements) == 1: + le.append(minimal_elements[0]) + dag_copy.delete_vertex(minimal_elements[0]) + else: + ap = minimal_elements[0] + bp = minimal_elements[1] + a.append(ap) + b.append(bp) + le.append(ap) + le.append(bp) + dag_copy.delete_vertex(ap) + dag_copy.delete_vertex(bp) + + return (le, a, b) + +@cython.wraparound(False) +@cython.boundscheck(False) +cdef void _linear_extension_switch(list _le, list _a, list _b, list _is_plus, Py_ssize_t i): + """ + This implements the ``Switch`` procedure described on page 7 + of "Generating Linear Extensions Fast" by Pruesse and Ruskey. + + If ``i == -1``, then the sign is changed. Otherwise, then + ``_a[i]`` and ``_b[i]`` are transposed. + + """ + cdef Py_ssize_t a_index, b_index + if i == -1: + _is_plus[0] = not _is_plus[0] + else: + a = _a[i] + b = _b[i] + a_index = _le.index(a) + b_index = _le.index(b) + _le[a_index] = b + _le[b_index] = a + _b[i] = a + _a[i] = b + +@cython.wraparound(False) +@cython.boundscheck(False) +cdef bint _linear_extension_right_a(_D, list _le, list _a, list _b, Py_ssize_t i): + """ + Return ``True`` if and only if ``_a[i]`` is incomparable with the + element to its right in ``_le`` and the element to the right is + not ``_b[i]``. + + This is the ``Right`` function described on page 8 of + "Generating Linear Extensions Fast" by Pruesse and Ruskey. + + :: + + sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram # not tested + sage: _linear_extension_right_a(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 0) # not tested + False + sage: _linear_extension_right_a(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 1) # not tested + False + + """ + cdef Py_ssize_t yindex + x = _a[i] + yindex = _le.index(x) + 1 + if yindex >= len(_le): + return False + y = _le[yindex] + return y != _b[i] and _D.are_incomparable(x, y) + +@cython.wraparound(False) +@cython.boundscheck(False) +cdef bint _linear_extension_right_b(_D, list _le, list _a, list _b, Py_ssize_t i): + """ + Return True if and only if ``_b[i]`` is incomparable with the + elements to its right in ``_le``. + + This is the ``Right`` function described on page 8 of + "Generating Linear Extensions Fast" by Pruesse and Ruskey. + + :: + + sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram # not tested + sage: _linear_extension_right_b(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 0) # not tested + False + sage: _linear_extension_right_b(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 1) # not tested + False + + """ + cdef Py_ssize_t yindex + x = _b[i] + yindex = _le.index(x) + 1 + if yindex >= len(_le): + return False + y = _le[yindex] + return _D.are_incomparable(x, y) + +@cython.wraparound(False) +@cython.boundscheck(False) +def _linear_extension_gen(_D, list _le, list _a, list _b, list _is_plus, Py_ssize_t i): + """ + This a Python version of the GenLE routine found in Figure 8 + of "Generating Linear Extensions Fast" by Pruesse and Ruskey. + + TESTS:: + + sage: from sage.combinat.posets.linear_extension_iterator import _linear_extension_prepare, _linear_extension_gen + sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram + sage: le, a, b = _linear_extension_prepare(D) + sage: [e for e in _linear_extension_gen(D, le, a, b, [True], len(a)-1)] + [[0, 2, 1, 3, 4]] + + """ + cdef int mra, mrb, mla + cdef Py_ssize_t index, index1 + cdef bint typical + if i == -1: + return + + for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): + yield e + mrb = 0 + typical = False + while _linear_extension_right_b(_D, _le, _a, _b, i): + mrb += 1 + # move_right + index = _le.index(_b[i]) + index1 = index + 1 + _le[index] = _le[index1] + _le[index1] = _b[i] + if _is_plus[0]: + yield _le[:] + + for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): + yield e + mra = 0 + while _linear_extension_right_a(_D, _le, _a, _b, i): + typical = True + mra += 1 + # move_right + index = _le.index(_a[i]) + index1 = index+1 + _le[index] = _le[index1] + _le[index1] = _a[i] + if _is_plus[0]: + yield _le[:] + + for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): + yield e + + if typical: + _linear_extension_switch(_le, _a, _b, _is_plus, i-1) + if _is_plus[0]: + yield _le[:] + + for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): + yield e + if mrb % 2 == 1: + mla = mra - 1 + else: + mla = mra + 1 + for _ in range(mla): + # move_left + index = _le.index(_a[i]) + index1 = index-1 + _le[index] = _le[index1] + _le[index1] = _a[i] + if _is_plus[0]: + yield _le[:] + + for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): + yield e + + if typical and (mrb % 2 == 1): + # move_left + index = _le.index(_a[i]) + index1 = index-1 + _le[index] = _le[index1] + _le[index1] = _a[i] + if _is_plus[0]: + yield _le[:] + else: + _linear_extension_switch(_le, _a, _b, _is_plus, i-1) + if _is_plus[0]: + yield _le[:] + for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): + yield e + for _ in range(mrb): + # move_left + index = _le.index(_b[i]) + index1 = index-1 + _le[index] = _le[index1] + _le[index1] = _b[i] + if _is_plus[0]: + yield _le[:] + + for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): + yield e + + +def linear_extension_iterator(D): + """ + Iterate over the linear extensions of the poset. + + The list ``_le`` keeps track of the current linear extensions. The + boolean variable ``is_plus`` keeps track of the "sign". + + INPUT: + + - ``D``, the Hasse diagram of a poset. + + .. WARNING:: + + It is assumed that ``D`` is not modified while the linear + extensions are generated. + + EXAMPLES:: + + sage: from sage.combinat.posets.linear_extension_iterator import linear_extension_iterator + sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram + sage: list(linear_extension_iterator(D)) + [[0, 1, 2, 3, 4], + [0, 2, 1, 3, 4], + [0, 2, 1, 4, 3], + [0, 2, 4, 1, 3], + [0, 1, 2, 4, 3]] + + sage: D = posets.BooleanLattice(3)._hasse_diagram + sage: len(list(linear_extension_iterator(D))) + 48 + + sage: D = posets.AntichainPoset(9)._hasse_diagram + sage: len(list(linear_extension_iterator(D))) == factorial(9) # long time + True + """ + _le, _a, _b = _linear_extension_prepare(D) + _max_pair = len(_a) - 1 + _is_plus = [True] # this is modified by _linear_extension_switch + + yield _le[:] + for e in _linear_extension_gen(D, _le, _a, _b, _is_plus, _max_pair): + yield e + _linear_extension_switch(_le, _a, _b, _is_plus, _max_pair) + if _is_plus[0]: + yield _le[:] + for e in _linear_extension_gen(D, _le, _a, _b, _is_plus, _max_pair): + yield e diff --git a/src/sage/combinat/posets/linear_extensions.py b/src/sage/combinat/posets/linear_extensions.py index e14be386228..84471d31e45 100644 --- a/src/sage/combinat/posets/linear_extensions.py +++ b/src/sage/combinat/posets/linear_extensions.py @@ -667,7 +667,7 @@ def __iter__(self): sage: list(L) [[1, 2, 3, 4], [2, 1, 3, 4], [2, 1, 4, 3], [1, 4, 2, 3], [1, 2, 4, 3]] """ - from sage.combinat.combinat_cython import linear_extension_iterator + from sage.combinat.posets.linear_extension_iterator import linear_extension_iterator vertex_to_element = self._poset._vertex_to_element for lin_ext in linear_extension_iterator(self._poset._hasse_diagram): yield self._element_constructor_([vertex_to_element(_) for _ in lin_ext]) diff --git a/src/sage/combinat/posets/poset_examples.py b/src/sage/combinat/posets/poset_examples.py index 41748b6d11a..60b54d6713b 100644 --- a/src/sage/combinat/posets/poset_examples.py +++ b/src/sage/combinat/posets/poset_examples.py @@ -1886,7 +1886,7 @@ def _random_lattice(n, p): meet for `e, m` for all `m \in M`. We do that by keeping track of meet matrix and list of maximal elements. """ - from sage.functions.other import floor + from sage.arith.misc import integer_floor as floor from sage.misc.functional import sqrt from sage.misc.prandom import random diff --git a/src/sage/combinat/ranker.py b/src/sage/combinat/ranker.py index bcb5c967dcb..6d7fb2998a2 100644 --- a/src/sage/combinat/ranker.py +++ b/src/sage/combinat/ranker.py @@ -207,7 +207,7 @@ def unrank(L, i): Enumerated sets:: - sage: unrank(GF(7), 2) + sage: unrank(GF(7), 2) # optional - sage.rings.finite_rings 2 sage: unrank(IntegerModRing(29), 10) 10 diff --git a/src/sage/combinat/root_system/cartan_matrix.py b/src/sage/combinat/root_system/cartan_matrix.py index 3a26227b4f1..77f175f0364 100644 --- a/src/sage/combinat/root_system/cartan_matrix.py +++ b/src/sage/combinat/root_system/cartan_matrix.py @@ -32,7 +32,7 @@ from sage.matrix.matrix_space import MatrixSpace from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass from sage.misc.classcall_metaclass import typecall -from sage.misc.misc import powerset +from sage.combinat.subset import powerset from sage.matrix.matrix_integer_sparse import Matrix_integer_sparse from sage.rings.integer_ring import ZZ from sage.combinat.root_system.cartan_type import CartanType, CartanType_abstract diff --git a/src/sage/combinat/root_system/coxeter_type.py b/src/sage/combinat/root_system/coxeter_type.py index 39fa6ca0d01..40b27e4afd5 100644 --- a/src/sage/combinat/root_system/coxeter_type.py +++ b/src/sage/combinat/root_system/coxeter_type.py @@ -24,7 +24,8 @@ import sage.rings.abc from sage.matrix.args import SparseEntry from sage.matrix.constructor import Matrix -from sage.symbolic.ring import SR +from sage.misc.lazy_import import lazy_import +lazy_import("sage.symbolic.ring", "SR") from sage.structure.unique_representation import UniqueRepresentation from sage.structure.sage_object import SageObject diff --git a/src/sage/combinat/set_partition.py b/src/sage/combinat/set_partition.py index 6edf7d963da..e309600ac1c 100644 --- a/src/sage/combinat/set_partition.py +++ b/src/sage/combinat/set_partition.py @@ -40,19 +40,21 @@ from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass +from sage.misc.lazy_import import lazy_import from sage.rings.infinity import infinity from sage.rings.integer import Integer from sage.combinat.combinatorial_map import combinatorial_map -from sage.combinat.combinat_cython import (set_partition_iterator, - set_partition_iterator_blocks) +from sage.combinat.set_partition_iterator import (set_partition_iterator, + set_partition_iterator_blocks) from sage.combinat.partition import Partition, Partitions from sage.combinat.combinat import bell_number, stirling_number2 as stirling2 from sage.combinat.permutation import Permutation from sage.arith.misc import factorial from sage.misc.prandom import random, randint, sample -from sage.probability.probability_distribution import GeneralDiscreteDistribution from sage.sets.disjoint_set import DisjointSet -from sage.combinat.posets.hasse_diagram import HasseDiagram + +lazy_import('sage.combinat.posets.hasse_diagram', 'HasseDiagram') +lazy_import('sage.probability.probability_distribution', 'GeneralDiscreteDistribution') class AbstractSetPartition(ClonableArray, diff --git a/src/sage/combinat/set_partition_iterator.pyx b/src/sage/combinat/set_partition_iterator.pyx new file mode 100644 index 00000000000..9b83127d61a --- /dev/null +++ b/src/sage/combinat/set_partition_iterator.pyx @@ -0,0 +1,129 @@ +r""" +Fast set partition iterators +""" +cimport cython + + +@cython.wraparound(False) +@cython.boundscheck(False) +cdef list from_word(list w, list base_set): + cdef list sp = [] + cdef Py_ssize_t i + cdef Py_ssize_t b + for i in range(len(w)): + b = (w[i]) + x = base_set[i] + if len(sp) <= b: + sp.append([x]) + else: + sp[b].append(x) + return sp + +@cython.wraparound(False) +@cython.boundscheck(False) +def set_partition_iterator(base_set): + """ + A fast iterator for the set partitions of the base set, which + returns lists of lists instead of set partitions types. + + EXAMPLES:: + + sage: from sage.combinat.set_partition_iterator import set_partition_iterator + sage: list(set_partition_iterator([1,-1,x])) # optional - sage.symbolic + [[[1, -1, x]], + [[1, -1], [x]], + [[1, x], [-1]], + [[1], [-1, x]], + [[1], [-1], [x]]] + """ + cdef list base = list(base_set) + + # Knuth, TAOCP 4A 7.2.1.5, Algorithm H + cdef Py_ssize_t N = len(base) + # H1: initialize + cdef list a = [0] * N + if N <= 1: + yield from_word(a, base) + return + + cdef list b = [1] * N + cdef Py_ssize_t j + cdef Py_ssize_t last = N - 1 + while True: + # H2: visit + yield from_word(a, base) + if a[last] == b[last]: + # H4: find j + j = N - 2 + while a[j] == b[j]: + j -= 1 + # H5: increase a_j + if j == 0: + break + a[j] += 1 + # H6: zero out a_{j+1},...,a_{n-1} + b[last] = b[j] + int(a[j] == b[j]) + j += 1 + while j < N - 1: + a[j] = 0 + b[j] = b[last] + j += 1 + a[last] = 0 + else: + # H3: increase a_{n-1} + a[last] += 1 + +@cython.wraparound(False) +@cython.boundscheck(False) +def _set_partition_block_gen(Py_ssize_t n, Py_ssize_t k, list a): + r""" + Recursively generate set partitions of ``n`` with fixed block + size ``k`` using Algorithm 4.23 from [Rus2003]_. + ``a`` is a list of size ``n``. + + EXAMPLES:: + + sage: from sage.combinat.set_partition_iterator import _set_partition_block_gen + sage: a = list(range(3)) + sage: for p in _set_partition_block_gen(3, 2, a): + ....: print(p) + [0, 1, 0] + [0, 1, 1] + [0, 0, 1] + """ + cdef Py_ssize_t i + if n == k: + yield a + return + + for i in range(k): + a[n-1] = i + for P in _set_partition_block_gen(n-1, k, a): + yield P + a[n-1] = n-1 + if k > 1: + a[n-1] = k-1 + for P in _set_partition_block_gen(n-1, k-1, a): + yield P + a[n-1] = n-1 + +@cython.wraparound(False) +@cython.boundscheck(False) +def set_partition_iterator_blocks(base_set, Py_ssize_t k): + """ + A fast iterator for the set partitions of the base set into the + specified number of blocks, which returns lists of lists + instead of set partitions types. + + EXAMPLES:: + + sage: from sage.combinat.set_partition_iterator import set_partition_iterator_blocks + sage: list(set_partition_iterator_blocks([1,-1,x], 2)) # optional - sage.symbolic + [[[1, x], [-1]], [[1], [-1, x]], [[1, -1], [x]]] + """ + cdef list base = list(base_set) + cdef Py_ssize_t n = len(base) + cdef list a = list(range(n)) + # TODO: implement _set_partition_block_gen as an iterative algorithm + for P in _set_partition_block_gen(n, k, a): + yield from_word( P, base) diff --git a/src/sage/combinat/sine_gordon.py b/src/sage/combinat/sine_gordon.py index e98c393ea08..40b26d066c2 100644 --- a/src/sage/combinat/sine_gordon.py +++ b/src/sage/combinat/sine_gordon.py @@ -46,14 +46,14 @@ from sage.rings.integer_ring import ZZ from sage.rings.real_mpfr import RR from sage.rings.semirings.non_negative_integer_semiring import NN -from sage.functions.trig import cos, sin from sage.misc.lazy_import import lazy_import -from sage.symbolic.constants import pi, I -from sage.functions.log import exp -from sage.functions.other import ceil +lazy_import("sage.functions.trig", ["cos", "sin"]) +lazy_import("sage.symbolic.constants", ["pi", "I"]) +lazy_import("sage.functions.log", "exp") +lazy_import("sage.functions.other", "ceil") from sage.misc.flatten import flatten -from sage.symbolic.ring import SR -from sage.functions.other import real_part, imag_part +lazy_import("sage.symbolic.ring", "SR") +lazy_import("sage.functions.other", ["real_part", "imag_part"]) from sage.misc.cachefunc import cached_method lazy_import("sage.plot.plot", "parametric_plot") lazy_import("sage.plot.graphics", "Graphics") diff --git a/src/sage/combinat/sloane_functions.py b/src/sage/combinat/sloane_functions.py index ba937db12ff..7c62279adac 100644 --- a/src/sage/combinat/sloane_functions.py +++ b/src/sage/combinat/sloane_functions.py @@ -129,7 +129,8 @@ from sage.structure.sage_object import SageObject from sage.arith.srange import srange from sage.rings.integer_ring import ZZ -from sage.functions.all import prime_pi +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.all", "prime_pi") from sage.rings.integer import Integer as Integer_class # You may have to import more here when defining new sequences import sage.arith.all as arith diff --git a/src/sage/combinat/subset.py b/src/sage/combinat/subset.py index c27b1eb04ed..6c21f7b6975 100644 --- a/src/sage/combinat/subset.py +++ b/src/sage/combinat/subset.py @@ -1,7 +1,7 @@ r""" Subsets -The set of subsets of a finite set. The set can be given as a list or a Set +The set of subsets of a finite set. The set can be given as a list or a :class:`Set` or else as an integer `n` which encodes the set `\{1,2,...,n\}`. See :class:`Subsets` for more information and examples. @@ -39,7 +39,6 @@ from sage.sets.set import Set, Set_object_enumerated from sage.arith.misc import binomial -from sage.misc.misc import _stable_uniq as uniq from sage.rings.integer_ring import ZZ from sage.rings.integer import Integer from . import combination @@ -186,11 +185,11 @@ class Subsets_s(Parent): {1, 2, 3}, {1, 2, 4}, {1, 3, 4}, {2, 3, 4}, {1, 2, 3, 4}] - sage: S = Subsets(Subsets(Subsets(GF(3)))); S + sage: S = Subsets(Subsets(Subsets(GF(3)))); S # optional - sage.rings.finite_rings Subsets of Subsets of Subsets of Finite Field of size 3 - sage: S.cardinality() + sage: S.cardinality() # optional - sage.rings.finite_rings 115792089237316195423570985008687907853269984665640564039457584007913129639936 - sage: S.unrank(3149254230) # random + sage: S.unrank(3149254230) # random # optional - sage.rings.finite_rings {{{1}, {0, 2}}, {{0, 1, 2}, {0, 1}, {1}, {1, 2}}, {{2}, {1, 2}, {0, 1, 2}, {0, 2}, {1}, {}}, {{1, 2}, {0}}, @@ -248,7 +247,7 @@ def underlying_set(self): EXAMPLES:: - sage: Subsets(GF(13)).underlying_set() + sage: Subsets(GF(13)).underlying_set() # optional - sage.rings.finite_rings {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} """ return self.element_class(self._s) @@ -550,10 +549,10 @@ def lattice(self): EXAMPLES:: sage: X = Subsets([7,8,9]) - sage: X.lattice() + sage: X.lattice() # optional - sage.combinat sage.graphs Finite lattice containing 8 elements sage: Y = Subsets(0) - sage: Y.lattice() + sage: Y.lattice() # optional - sage.combinat sage.graphs Finite lattice containing 1 elements """ @@ -874,8 +873,8 @@ def an_element(self): def dict_to_list(d): r""" - Return a list whose elements are the elements of i of d repeated with - multiplicity d[i]. + Return a list whose elements are the elements of ``i`` of ``d`` repeated with + multiplicity ``d[i]``. EXAMPLES:: @@ -1168,7 +1167,7 @@ def _element_constructor_(self,X): class SubMultiset_sk(SubMultiset_s): """ - The combinatorial class of the subsets of size k of a multiset s. Note + The combinatorial class of the subsets of size ``k`` of a multiset ``s``. Note that each subset is represented by a list of the elements rather than a set since we can have multiplicities (no multiset data structure yet in sage). @@ -1291,7 +1290,7 @@ def __contains__(self, s): def random_element(self): r""" - Return a random submultiset of given length + Return a random submultiset of given length. EXAMPLES:: @@ -1471,3 +1470,93 @@ def _element_constructor_(self, x): [(), (0,), (1,), (2,), (0, 1), (0, 2), (1, 2), (0, 1, 2)] """ return self.element_class(sorted(set(x))) + + +def powerset(X): + r""" + Iterator over the *list* of all subsets of the iterable ``X``, in no + particular order. Each list appears exactly once, up to order. + + INPUT: + + - ``X`` - an iterable + + OUTPUT: iterator of lists + + EXAMPLES:: + + sage: list(powerset([1,2,3])) + [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]] + sage: [z for z in powerset([0,[1,2]])] + [[], [0], [[1, 2]], [0, [1, 2]]] + + Iterating over the power set of an infinite set is also allowed:: + + sage: i = 0 + sage: L = [] + sage: for x in powerset(ZZ): + ....: if i > 10: + ....: break + ....: else: + ....: i += 1 + ....: L.append(x) + sage: print(" ".join(str(x) for x in L)) + [] [0] [1] [0, 1] [-1] [0, -1] [1, -1] [0, 1, -1] [2] [0, 2] [1, 2] + + You may also use subsets as an alias for powerset:: + + sage: subsets([1,2,3]) + + sage: list(subsets([1,2,3])) + [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]] + + The reason we return lists instead of sets is that the elements of + sets must be hashable and many structures on which one wants the + powerset consist of non-hashable objects. + + AUTHORS: + + - William Stein + + - Nils Bruin (2006-12-19): rewrite to work for not-necessarily + finite objects X. + """ + yield [] + pairs = [] + power2 = 1 + for x in X: + pairs.append((power2, x)) + next_power2 = power2 << 1 + for w in range(power2, next_power2): + yield [x for m, x in pairs if m & w] + power2 = next_power2 + + +subsets = powerset + + +def uniq(L): + """ + Iterate over the elements of ``L``, yielding every element at most + once: keep only the first occurrence of any item. + + The items must be hashable. + + INPUT: + + - ``L`` -- iterable + + EXAMPLES:: + + sage: L = [1, 1, 8, -5, 3, -5, 'a', 'x', 'a'] + sage: it = uniq(L); it + + sage: list(it) + [1, 8, -5, 3, 'a', 'x'] + """ + seen = set() + for x in L: + if x in seen: + continue + yield x + seen.add(x) diff --git a/src/sage/combinat/subsets_hereditary.py b/src/sage/combinat/subsets_hereditary.py index 5a1347c5218..68fe53e98ea 100644 --- a/src/sage/combinat/subsets_hereditary.py +++ b/src/sage/combinat/subsets_hereditary.py @@ -57,13 +57,14 @@ def subsets_with_hereditary_property(f,X,max_obstruction_size=None,ncpus=1): Sets whose elements all have the same remainder mod 2:: sage: from sage.combinat.subsets_hereditary import subsets_with_hereditary_property - sage: f = lambda x: (not x) or all(xx%2 == x[0]%2 for xx in x) - sage: list(subsets_with_hereditary_property(f,range(4))) + sage: def f(x): + ....: return (not x) or all(xx % 2 == x[0] % 2 for xx in x) + sage: list(subsets_with_hereditary_property(f, range(4))) [[], [0], [1], [2], [3], [0, 2], [1, 3]] Same, on two threads:: - sage: sorted(subsets_with_hereditary_property(f,range(4),ncpus=2)) + sage: sorted(subsets_with_hereditary_property(f, range(4), ncpus=2)) [[], [0], [0, 2], [1], [1, 3], [2], [3]] One can use this function to compute the independent sets of a graph. We @@ -71,33 +72,35 @@ def subsets_with_hereditary_property(f,X,max_obstruction_size=None,ncpus=1): have size 2. We can thus set ``max_obstruction_size=2``, which reduces the number of calls to `f` from 91 to 56:: - sage: num_calls=0 + sage: num_calls = 0 sage: g = graphs.PetersenGraph() sage: def is_independent_set(S): ....: global num_calls - ....: num_calls+=1 - ....: return g.subgraph(S).size()==0 - sage: l1=list(subsets_with_hereditary_property(is_independent_set, g.vertices(sort=False))) + ....: num_calls += 1 + ....: return g.subgraph(S).size() == 0 + sage: l1 = list(subsets_with_hereditary_property(is_independent_set, + ....: g.vertices(sort=False))) sage: num_calls 91 - sage: num_calls=0 - sage: l2=list(subsets_with_hereditary_property(is_independent_set, g.vertices(sort=False), max_obstruction_size=2)) + sage: num_calls = 0 + sage: l2 = list(subsets_with_hereditary_property(is_independent_set, + ....: g.vertices(sort=False), + ....: max_obstruction_size=2)) sage: num_calls 56 - sage: l1==l2 + sage: l1 == l2 True TESTS:: - sage: list(subsets_with_hereditary_property(lambda x:False,range(4))) + sage: list(subsets_with_hereditary_property(lambda x: False, range(4))) [] - sage: list(subsets_with_hereditary_property(lambda x:len(x)<1,range(4))) + sage: list(subsets_with_hereditary_property(lambda x: len(x)<1, range(4))) [[]] - sage: list(subsets_with_hereditary_property(lambda x:True,range(2))) + sage: list(subsets_with_hereditary_property(lambda x: True, range(2))) [[], [0], [1], [0, 1]] """ from sage.data_structures.bitset import Bitset - from sage.parallel.decorate import parallel # About the implementation: # # 1) We work on X={0,...,n-1} but remember X to return correctly @@ -155,6 +158,7 @@ def explore_neighbors(s): return if ncpus != 1: + from sage.parallel.decorate import parallel explore_neighbors_paral = parallel(ncpus=ncpus)(explore_neighbors) # All sets of size 0, then size 1, then ... diff --git a/src/sage/combinat/symmetric_group_representations.py b/src/sage/combinat/symmetric_group_representations.py index 8a6b58ae87c..f9e1fb03821 100644 --- a/src/sage/combinat/symmetric_group_representations.py +++ b/src/sage/combinat/symmetric_group_representations.py @@ -28,7 +28,8 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.symbolic.ring import SR +from sage.misc.lazy_import import lazy_import +lazy_import("sage.symbolic.ring", "SR") from sage.misc.functional import sqrt from sage.combinat.partition import Partition, Partitions from sage.combinat.permutation import Permutation, Permutations, from_cycles diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 0b327db6c06..1f716fa26b3 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -100,7 +100,7 @@ from sage.combinat.posets.posets import Poset from sage.groups.perm_gps.permgroup import PermutationGroup from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass -from sage.misc.misc import powerset +from sage.combinat.subset import powerset from sage.misc.misc_c import prod from sage.misc.persist import register_unpickle_override from sage.rings.finite_rings.integer_mod_ring import IntegerModRing diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index 9c42e379cd4..d771d3301a7 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -540,9 +540,9 @@ def FibonacciWord(self, alphabet=(0, 1), construction_method="recursive"): :: - sage: words.FibonacciWord([0,1], 'function') + sage: words.FibonacciWord([0,1], 'function') # optional - sage.symbolic word: 0100101001001010010100100101001001010010... - sage: words.FibonacciWord('ab', 'function') + sage: words.FibonacciWord('ab', 'function') # optional - sage.symbolic word: abaababaabaababaababaabaababaabaababaaba... TESTS:: @@ -1155,7 +1155,7 @@ def LowerMechanicalWord(self, alpha, rho=0, alphabet=None): if not 0 <= alpha <= 1: raise ValueError("parameter alpha (=%s) must be in [0,1]" % alpha) - from sage.functions.other import floor + from sage.arith.misc import integer_floor as floor from sage.combinat.words.alphabet import build_alphabet if alphabet is None or alphabet in ((0, 1), [0, 1]): alphabet = build_alphabet([0, 1]) @@ -1215,8 +1215,9 @@ def UpperMechanicalWord(self, alpha, rho=0, alphabet=None): if not 0 <= alpha <= 1: raise ValueError("parameter alpha (=%s) must be in [0,1]" % alpha) - from sage.functions.other import ceil + from sage.arith.misc import integer_ceil as ceil from sage.combinat.words.alphabet import build_alphabet + if alphabet is None or alphabet in ((0, 1), [0, 1]): alphabet = build_alphabet([0, 1]) s = lambda n: ceil(alpha*(n+1) + rho) - ceil(alpha*n + rho) diff --git a/src/sage/cpython/debug.pyx b/src/sage/cpython/debug.pyx index e00f31ac94e..f86166ca825 100644 --- a/src/sage/cpython/debug.pyx +++ b/src/sage/cpython/debug.pyx @@ -101,7 +101,7 @@ def getattr_debug(obj, name, default=_no_default): found '__doc__' in dict of got ... 'str'>) returning ... 'str'>) - sage: _ = getattr_debug(gp(1), "log") + sage: _ = getattr_debug(gp(1), "log") # optional - sage.libs.pari getattr_debug(obj=1, name='log'): type(obj) = object has __dict__ slot () diff --git a/src/sage/cpython/getattr.pyx b/src/sage/cpython/getattr.pyx index 0eabdfd36ab..525ea5aa934 100644 --- a/src/sage/cpython/getattr.pyx +++ b/src/sage/cpython/getattr.pyx @@ -54,7 +54,8 @@ cdef class AttributeErrorMessage: Traceback (most recent call last): ... AttributeError: 'sage.rings.integer.Integer' object has no attribute 'bla' - sage: QQ[x].gen().bla + sage: x = polygen(ZZ, 'x') + sage: QQ[x].gen().bla # optional - sage.libs.flint Traceback (most recent call last): ... AttributeError: 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint' object has no attribute 'bla' @@ -83,7 +84,7 @@ cdef class AttributeErrorMessage: ....: except AttributeError as exc: ....: ElementError2 = exc sage: ElementError - AttributeError('sage.symbolic.expression.Expression' object has no attribute '__bla'...) + AttributeError('sage.rings.polynomial...' object has no attribute '__bla'...) sage: ElementError2.args[0] is ElementError.args[0] True sage: isinstance(ElementError.args[0], sage.cpython.getattr.AttributeErrorMessage) @@ -406,13 +407,13 @@ def dir_with_other_class(self, *cls): Check that objects without dicts are well handled:: - sage: cython("cdef class A:\n cdef public int a") # optional - sage.misc.cython - sage: cython("cdef class B:\n cdef public int b") # optional - sage.misc.cython - sage: x = A() # optional - sage.misc.cython - sage: x.a = 1 # optional - sage.misc.cython - sage: hasattr(x,'__dict__') # optional - sage.misc.cython + sage: cython("cdef class A:\n cdef public int a") # optional - sage.misc.cython + sage: cython("cdef class B:\n cdef public int b") # optional - sage.misc.cython + sage: x = A() # optional - sage.misc.cython + sage: x.a = 1 # optional - sage.misc.cython + sage: hasattr(x,'__dict__') # optional - sage.misc.cython False - sage: dir_with_other_class(x, B) # optional - sage.misc.cython + sage: dir_with_other_class(x, B) # optional - sage.misc.cython [..., 'a', 'b'] TESTS: diff --git a/src/sage/data_structures/bitset.pyx b/src/sage/data_structures/bitset.pyx index 29bbeeb0d1c..32e821fc828 100644 --- a/src/sage/data_structures/bitset.pyx +++ b/src/sage/data_structures/bitset.pyx @@ -204,38 +204,38 @@ cdef class FrozenBitset: the number of elements currently in the bitset, while the capacity is the number of elements that the bitset can hold. :: - sage: p = primes_first_n(10); p + sage: p = primes_first_n(10); p # optional - sage.libs.pari [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] - sage: tuple(p) + sage: tuple(p) # optional - sage.libs.pari (2, 3, 5, 7, 11, 13, 17, 19, 23, 29) - sage: F = FrozenBitset(p); F; FrozenBitset(tuple(p)) + sage: F = FrozenBitset(p); F; FrozenBitset(tuple(p)) # optional - sage.libs.pari 001101010001010001010001000001 001101010001010001010001000001 Recover the primes from the bitset:: - sage: for b in F: + sage: for b in F: # optional - sage.libs.pari ....: print(b) 2 3 ... 29 - sage: list(F) + sage: list(F) # optional - sage.libs.pari [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] Query the bitset:: - sage: len(F) + sage: len(F) # optional - sage.libs.pari 10 - sage: len(list(F)) + sage: len(list(F)) # optional - sage.libs.pari 10 - sage: F.capacity() + sage: F.capacity() # optional - sage.libs.pari 30 - sage: s = str(F); len(s) + sage: s = str(F); len(s) # optional - sage.libs.pari 30 - sage: 2 in F + sage: 2 in F # optional - sage.libs.pari True - sage: 1 in F + sage: 1 in F # optional - sage.libs.pari False A random iterable, with all duplicate elements removed:: diff --git a/src/sage/data_structures/blas_dict.pyx b/src/sage/data_structures/blas_dict.pyx index df6bf29641e..fb247f150a9 100644 --- a/src/sage/data_structures/blas_dict.pyx +++ b/src/sage/data_structures/blas_dict.pyx @@ -371,7 +371,7 @@ cpdef dict sum_of_monomials(monomials, scalar): {'a': 2, 'b': 3} sage: blas.sum_of_monomials(['a', 'a', 'b', 'b', 'b'], 2) {'a': 4, 'b': 6} - sage: blas.sum_of_monomials(['a', 'a', 'b', 'b', 'b'], GF(3).one()) + sage: blas.sum_of_monomials(['a', 'a', 'b', 'b', 'b'], GF(3).one()) # optional - sage.rings.finite_rings {'a': 2} """ cdef dict result = {} @@ -398,7 +398,8 @@ cpdef dict sum_of_terms(index_coeff_pairs): {'a': 1, 'b': 3} sage: blas.sum_of_terms([('a', 5), ('b', 3), ('a', -5)]) {'b': 3} - sage: blas.sum_of_terms([('a', 5), ('b', GF(2).one()), ('a', -5), ('b', GF(2).one())]) + sage: blas.sum_of_terms([('a', 5), ('b', GF(2).one()), # optional - sage.rings.finite_rings + ....: ('a', -5), ('b', GF(2).one())]) {} """ cdef dict result = {} @@ -434,7 +435,7 @@ cpdef dict convert_remove_zeroes(dict D, R): sage: from sage.data_structures.blas_dict import convert_remove_zeroes sage: d = {1: -2, 2: -4, 3: -3} - sage: convert_remove_zeroes(d, GF(2)) + sage: convert_remove_zeroes(d, GF(2)) # optional - sage.rings.finite_rings {3: 1} """ cdef list for_removal = [] diff --git a/src/sage/data_structures/stream.py b/src/sage/data_structures/stream.py index 4bffa84bfc9..b11a27318f5 100644 --- a/src/sage/data_structures/stream.py +++ b/src/sage/data_structures/stream.py @@ -99,10 +99,12 @@ from sage.arith.misc import divisors from sage.misc.misc_c import prod from sage.misc.lazy_attribute import lazy_attribute +from sage.misc.lazy_import import lazy_import from sage.combinat.integer_vector_weighted import iterator_fast as wt_int_vec_iter -from sage.combinat.sf.sfa import _variables_recursive, _raise_variables from sage.categories.hopf_algebras_with_basis import HopfAlgebrasWithBasis +lazy_import('sage.combinat.sf.sfa', ['_variables_recursive', '_raise_variables']) + class Stream(): """ diff --git a/src/sage/databases/cubic_hecke_db.py b/src/sage/databases/cubic_hecke_db.py index 99e96a9b816..52f5f7cc142 100644 --- a/src/sage/databases/cubic_hecke_db.py +++ b/src/sage/databases/cubic_hecke_db.py @@ -1494,10 +1494,10 @@ def read_markov(bas_ele, variables, num_strands=4): EXAMPLES:: sage: from sage.databases.cubic_hecke_db import read_markov - sage: from sympy import var - sage: u, v, w, s = var('u, v, w, s') - sage: variables = (u, v, w, s) - sage: read_markov('U2', variables, num_strands=3) + sage: from sympy import var # optional - sympy + sage: u, v, w, s = var('u, v, w, s') # optional - sympy + sage: variables = (u, v, w, s) # optional - sympy + sage: read_markov('U2', variables, num_strands=3) # optional - sympy [0, s, 1/s, s, 1/s, 0, 0, 0, 0, -s*v, s, s, -s*u/w, -v/s, 1/s, 0, 0, 0, 0, 1/s, -u/(s*w), -v/s, 0, 0] """ diff --git a/src/sage/databases/jones.py b/src/sage/databases/jones.py index 6f6318d0c2d..5afcaaa3f6b 100644 --- a/src/sage/databases/jones.py +++ b/src/sage/databases/jones.py @@ -71,7 +71,7 @@ from sage.rings.number_field.number_field import NumberField from sage.rings.rational_field import RationalField from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.misc.misc import powerset +from sage.combinat.subset import powerset from sage.env import SAGE_SHARE from sage.misc.persist import load, save diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index fe58e2bde3e..b21c44656b5 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -131,10 +131,10 @@ def init_sage(controller=None): Check that SymPy equation pretty printer is limited in doctest mode to default width (80 chars):: - sage: from sympy import sympify # optional - sage.symbolic - sage: from sympy.printing.pretty.pretty import PrettyPrinter # optional - sage.symbolic - sage: s = sympify('+x^'.join(str(i) for i in range(30))) # optional - sage.symbolic - sage: print(PrettyPrinter(settings={'wrap_line': True}).doprint(s)) # optional - sage.symbolic + sage: from sympy import sympify # optional - sympy + sage: from sympy.printing.pretty.pretty import PrettyPrinter # optional - sympy + sage: s = sympify('+x^'.join(str(i) for i in range(30))) # optional - sympy + sage: print(PrettyPrinter(settings={'wrap_line': True}).doprint(s)) # optional - sympy 29 28 27 26 25 24 23 22 21 20 19 18 17 x + x + x + x + x + x + x + x + x + x + x + x + x + @@ -514,7 +514,8 @@ def __init__(self, *args, **kwds): sage: from sage.doctest.forker import SageDocTestRunner sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() sage: import doctest, sys, os - sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) + sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, + ....: optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: DTR """ @@ -557,7 +558,8 @@ def _run(self, test, compileflags, out): sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() sage: from sage.env import SAGE_SRC sage: import doctest, sys, os - sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) + sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, + ....: optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: filename = os.path.join(SAGE_SRC,'sage','doctest','forker.py') sage: FDS = FileDocTestSource(filename,DD) sage: doctests, extras = FDS.create_doctests(globals()) @@ -831,7 +833,8 @@ def run(self, test, compileflags=0, out=None, clear_globs=True): sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() sage: from sage.env import SAGE_SRC sage: import doctest, sys, os - sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) + sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, + ....: optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: filename = os.path.join(SAGE_SRC,'sage','doctest','forker.py') sage: FDS = FileDocTestSource(filename,DD) sage: doctests, extras = FDS.create_doctests(globals()) @@ -891,7 +894,8 @@ def summarize(self, verbose=None): sage: from sage.doctest.forker import SageDocTestRunner sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() sage: import doctest, sys, os - sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) + sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, + ....: optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: DTR._name2ft['sage.doctest.forker'] = (1,120) sage: results = DTR.summarize() ********************************************************************** @@ -975,7 +979,8 @@ def update_digests(self, example): sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() sage: from sage.env import SAGE_SRC sage: import doctest, sys, os, hashlib - sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) + sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, + ....: optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: filename = os.path.join(SAGE_SRC,'sage','doctest','forker.py') sage: FDS = FileDocTestSource(filename,DD) sage: doctests, extras = FDS.create_doctests(globals()) @@ -1037,7 +1042,8 @@ def compile_and_execute(self, example, compiler, globs): sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() sage: from sage.env import SAGE_SRC sage: import doctest, sys, os, hashlib - sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) + sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, + ....: optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: DTR.running_doctest_digest = hashlib.md5() sage: filename = os.path.join(SAGE_SRC,'sage','doctest','forker.py') sage: FDS = FileDocTestSource(filename,DD) @@ -1047,7 +1053,9 @@ def compile_and_execute(self, example, compiler, globs): sage: doctests, extras = FDS.create_doctests(globs) sage: ex0 = doctests[0].examples[0] sage: flags = 32768 if sys.version_info.minor < 8 else 524288 - sage: compiler = lambda ex: compile(ex.source, '', 'single', flags, 1) + sage: def compiler(ex): + ....: return compile(ex.source, '', + ....: 'single', flags, 1) sage: DTR.compile_and_execute(ex0, compiler, globs) 1764 sage: globs['doctest_var'] @@ -1060,7 +1068,9 @@ def compile_and_execute(self, example, compiler, globs): Now we can execute some more doctests to see the dependencies. :: sage: ex1 = doctests[0].examples[1] - sage: compiler = lambda ex:compile(ex.source, '', 'single', flags, 1) + sage: def compiler(ex): + ....: return compile(ex.source, '', + ....: 'single', flags, 1) sage: DTR.compile_and_execute(ex1, compiler, globs) sage: sorted(list(globs.set)) ['R', 'a'] @@ -1072,7 +1082,9 @@ def compile_and_execute(self, example, compiler, globs): :: sage: ex2 = doctests[0].examples[2] - sage: compiler = lambda ex:compile(ex.source, '', 'single', flags, 1) + sage: def compiler(ex): + ....: return compile(ex.source, '', + ....: 'single', flags, 1) sage: DTR.compile_and_execute(ex2, compiler, globs) a + 42 sage: list(globs.set) @@ -1131,7 +1143,8 @@ def _failure_header(self, test, example, message='Failed example:'): sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() sage: from sage.env import SAGE_SRC sage: import doctest, sys, os - sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) + sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, + ....: optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: filename = os.path.join(SAGE_SRC,'sage','doctest','forker.py') sage: FDS = FileDocTestSource(filename,DD) sage: doctests, extras = FDS.create_doctests(globals()) @@ -1202,7 +1215,8 @@ def report_start(self, out, test, example): sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() sage: from sage.env import SAGE_SRC sage: import doctest, sys, os - sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=True, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) + sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=True, sage_options=DD, + ....: optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: filename = os.path.join(SAGE_SRC,'sage','doctest','forker.py') sage: FDS = FileDocTestSource(filename,DD) sage: doctests, extras = FDS.create_doctests(globals()) @@ -1256,7 +1270,8 @@ def report_success(self, out, test, example, got, *, check_duration=0): sage: from sage.misc.misc import walltime sage: from sage.env import SAGE_SRC sage: import doctest, sys, os - sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=True, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) + sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=True, sage_options=DD, + ....: optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: filename = os.path.join(SAGE_SRC,'sage','doctest','forker.py') sage: FDS = FileDocTestSource(filename,DD) sage: doctests, extras = FDS.create_doctests(globals()) @@ -1297,7 +1312,8 @@ def report_failure(self, out, test, example, got, globs): sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() sage: from sage.env import SAGE_SRC sage: import doctest, sys, os - sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=True, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) + sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=True, sage_options=DD, + ....: optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: filename = os.path.join(SAGE_SRC,'sage','doctest','forker.py') sage: FDS = FileDocTestSource(filename,DD) sage: doctests, extras = FDS.create_doctests(globals()) @@ -1430,13 +1446,15 @@ def report_overtime(self, out, test, example, got, *, check_duration=0): sage: from sage.misc.misc import walltime sage: from sage.env import SAGE_SRC sage: import doctest, sys, os - sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=True, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) + sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=True, sage_options=DD, + ....: optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: filename = os.path.join(SAGE_SRC,'sage','doctest','forker.py') sage: FDS = FileDocTestSource(filename,DD) sage: doctests, extras = FDS.create_doctests(globals()) sage: ex = doctests[0].examples[0] sage: ex.walltime = 1.23 - sage: DTR.report_overtime(sys.stdout.write, doctests[0], ex, 'BAD ANSWER\n', check_duration=2.34) + sage: DTR.report_overtime(sys.stdout.write, doctests[0], ex, 'BAD ANSWER\n', + ....: check_duration=2.34) ********************************************************************** File ".../sage/doctest/forker.py", line 11, in sage.doctest.forker Warning, slow doctest: @@ -1554,7 +1572,8 @@ def update_results(self, D): sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() sage: from sage.env import SAGE_SRC sage: import doctest, sys, os - sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) + sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, + ....: optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: filename = os.path.join(SAGE_SRC,'sage','doctest','forker.py') sage: FDS = FileDocTestSource(filename,DD) sage: doctests, extras = FDS.create_doctests(globals()) @@ -1563,11 +1582,12 @@ def update_results(self, D): sage: DTR.run(doctests[0]) TestResults(failed=0, attempted=4) sage: T.stop().annotate(DTR) - sage: D = DictAsObject({'cputime':[],'walltime':[],'err':None}) + sage: D = DictAsObject({'cputime': [], 'walltime': [], 'err': None}) sage: DTR.update_results(D) 0 sage: sorted(list(D.items())) - [('cputime', [...]), ('err', None), ('failures', 0), ('tests', 4), ('walltime', [...]), ('walltime_skips', 0)] + [('cputime', [...]), ('err', None), ('failures', 0), + ('tests', 4), ('walltime', [...]), ('walltime_skips', 0)] """ for key in ["cputime", "walltime"]: if key not in D: @@ -2112,7 +2132,7 @@ def run(self): TESTS:: - sage: run_doctests(sage.symbolic.units) # indirect doctest # optional - sage.symbolic + sage: run_doctests(sage.symbolic.units) # indirect doctest # optional - sage.symbolic Running doctests with ID ... Doctesting 1 file. sage -t .../sage/symbolic/units.py diff --git a/src/sage/dynamics/all.py b/src/sage/dynamics/all.py index e5c553a3d54..20ca3b9d723 100644 --- a/src/sage/dynamics/all.py +++ b/src/sage/dynamics/all.py @@ -23,7 +23,8 @@ from sage.misc.lazy_import import lazy_import from sage.dynamics.arithmetic_dynamics.all import * -from sage.dynamics.complex_dynamics.all import * +lazy_import('sage.dynamics.complex_dynamics.mandel_julia', + ["mandelbrot_plot", "external_ray", "kneading_sequence", "julia_plot"]) from sage.dynamics.cellular_automata.all import * # Discrete dynamical systems diff --git a/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py b/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py index 735e0800a6f..6acb184ae7f 100644 --- a/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +++ b/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py @@ -22,9 +22,13 @@ # https://www.gnu.org/licenses/ # **************************************************************************** +from copy import copy + +from sage.arith.misc import GCD as gcd from sage.functions.hyperbolic import cosh from sage.matrix.constructor import matrix from sage.matrix.matrix_space import MatrixSpace +from sage.misc.lazy_import import lazy_import from sage.rings.cc import CC from sage.rings.complex_mpfr import ComplexField from sage.rings.finite_rings.integer_mod_ring import Zmod diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx b/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx index 40574bf6ea6..df7ec7cfeab 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx @@ -22,7 +22,7 @@ AUTHORS: from sage.arith.functions cimport LCM_list from sage.rings.finite_rings.finite_field_constructor import GF from sage.sets.set import Set -from sage.misc.misc import subsets +from sage.combinat.subset import subsets cpdef _fast_possible_periods(self, return_points=False): r""" diff --git a/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py b/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py index 442bb514561..93e3cd10968 100644 --- a/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py +++ b/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py @@ -25,7 +25,8 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.calculus.functions import jacobian +from sage.misc.lazy_import import lazy_import +lazy_import("sage.calculus.functions", "jacobian") from sage.categories.fields import Fields from sage.categories.commutative_rings import CommutativeRings from sage.categories.number_fields import NumberFields diff --git a/src/sage/env.py b/src/sage/env.py index f4899639a6d..e2baa8f297f 100644 --- a/src/sage/env.py +++ b/src/sage/env.py @@ -353,18 +353,18 @@ def cython_aliases(required_modules=None, EXAMPLES:: sage: from sage.env import cython_aliases - sage: cython_aliases() + sage: cython_aliases() # optional - sage.misc.cython {...} - sage: sorted(cython_aliases().keys()) + sage: sorted(cython_aliases().keys()) # optional - sage.misc.cython ['ARB_LIBRARY', 'CBLAS_CFLAGS', ..., 'ZLIB_LIBRARIES'] - sage: cython_aliases(required_modules=('module-that-is-assumed-to-not-exist')) + sage: cython_aliases(required_modules=('module-that-is-assumed-to-not-exist')) # optional - sage.misc.cython Traceback (most recent call last): ... PackageNotFoundError: ... - sage: cython_aliases(required_modules=(), optional_modules=('module-that-is-assumed-to-not-exist')) + sage: cython_aliases(required_modules=(), optional_modules=('module-that-is-assumed-to-not-exist')) # optional - sage.misc.cython {...} TESTS: @@ -372,7 +372,7 @@ def cython_aliases(required_modules=None, We can use ``cython.parallel`` regardless of whether OpenMP is supported. This will run in parallel, if OpenMP is supported:: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: #distutils: extra_compile_args = OPENMP_CFLAGS ....: #distutils: extra_link_args = OPENMP_CFLAGS diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index d21bddd5deb..cc65b1f994a 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -42,41 +42,41 @@ You can specify a particular domain for the evaluation using sage: fc_wilk_zz = fast_callable(wilk, vars=[x], domain=ZZ) -The meaning of domain=D is that each intermediate and final result -is converted to type D. For instance, the previous example of -``sin(x) + 3*x^2`` with domain=D would be equivalent to +The meaning of ``domain=D`` is that each intermediate and final result +is converted to type ``D``. For instance, the previous example of +``sin(x) + 3*x^2`` with ``domain=D`` would be equivalent to ``D(D(sin(D(x))) + D(D(3)*D(D(x)^2)))``. (This example also demonstrates the one exception to the general rule: if an exponent is an -integral constant, then it is not wrapped with D().) +integral constant, then it is not wrapped with ``D()``.) At first glance, this seems like a very bad idea if you want to compute quickly. And it is a bad idea, for types where we don't have a special interpreter. It's not too bad of a slowdown, though. To mitigate the costs, we check whether the value already has -the correct parent before we call D. +the correct parent before we call ``D``. -We don't yet have a special interpreter with domain ZZ, so we can see +We don't yet have a special interpreter with domain ``ZZ``, so we can see how that compares to the generic fc_wilk example above:: sage: timeit('fc_wilk_zz(30)') # random, long time 625 loops, best of 3: 15.4 us per loop -However, for other types, using domain=D will get a large speedup, +However, for other types, using ``domain=D`` will get a large speedup, because we have special-purpose interpreters for those types. One -example is RDF. Since with domain=RDF we know that every single +example is ``RDF``. Since with ``domain=RDF`` we know that every single operation will be floating-point, we can just execute the floating-point operations directly and skip all the Python object -creations that you would get from actually using RDF objects:: +creations that you would get from actually using ``RDF`` objects:: sage: fc_wilk_rdf = fast_callable(wilk, vars=[x], domain=RDF) sage: timeit('fc_wilk_rdf(30.0)') # random, long time 625 loops, best of 3: 7 us per loop -The domain does not need to be a Sage type; for instance, domain=float -also works. (We actually use the same fast interpreter for domain=float -and domain=RDF; the only difference is that when domain=RDF is used, -the return value is an RDF element, and when domain=float is used, -the return value is a Python float.) :: +The domain does not need to be a Sage type; for instance, ``domain=float`` +also works. (We actually use the same fast interpreter for ``domain=float`` +and ``domain=RDF``; the only difference is that when ``domain=RDF`` is used, +the return value is an ``RDF`` element, and when ``domain=float`` is used, +the return value is a Python :class:`float`.) :: sage: fc_wilk_float = fast_callable(wilk, vars=[x], domain=float) sage: timeit('fc_wilk_float(30.0)') # random, long time @@ -94,7 +94,6 @@ For ``CC``:: sage: timeit('fc_wilk_cc(30.0)') # random, long time 625 loops, best of 3: 23 us per loop - And support for ``CDF``:: sage: fc_wilk_cdf = fast_callable(wilk, vars=[x], domain=CDF) @@ -314,24 +313,24 @@ from sage.structure.element cimport Expression as Expression_abc def fast_callable(x, domain=None, vars=None, expect_one_var=False): r""" - Given an expression x, compile it into a form that can be quickly - evaluated, given values for the variables in x. + Given an expression ``x``, compile it into a form that can be quickly + evaluated, given values for the variables in ``x``. - Currently, x can be an expression object, an element of SR, or a + Currently, ``x`` can be an expression object, an element of ``SR``, or a (univariate or multivariate) polynomial; this list will probably be extended soon. - By default, x is evaluated the same way that a Python function - would evaluate it -- addition maps to PyNumber_Add, etc. However, - you can specify domain=D where D is some Sage parent or Python + By default, ``x`` is evaluated the same way that a Python function + would evaluate it -- addition maps to ``PyNumber_Add``, etc. However, + you can specify ``domain=D`` where ``D`` is some Sage parent or Python type; in this case, all arithmetic is done in that domain. If we - have a special-purpose interpreter for that parent (like RDF or float), - domain=... will trigger the use of that interpreter. + have a special-purpose interpreter for that parent (like ``RDF`` or :class:`float`), + ``domain=...`` will trigger the use of that interpreter. - If vars is None and x is a polynomial, then we will use the - generators of parent(x) as the variables; otherwise, vars must be - specified (unless x is a symbolic expression with only one variable, - and expect_one_var is True, in which case we will use that variable). + If ``vars`` is ``None`` and ``x`` is a polynomial, then we will use the + generators of parent(x) as the variables; otherwise, ``vars`` must be + specified (unless ``x`` is a symbolic expression with only one variable, + and ``expect_one_var`` is ``True``, in which case we will use that variable). EXAMPLES:: @@ -344,11 +343,11 @@ def fast_callable(x, domain=None, vars=None, sage: f(2.0) 12.9092974268257 - We have special fast interpreters for domain=float and domain=RDF. + We have special fast interpreters for ``domain=float`` and ``domain=RDF``. (Actually it's the same interpreter; only the return type varies.) Note that the float interpreter is not actually more accurate than - the RDF interpreter; elements of RDF just don't display all - their digits. We have special fast interpreter for domain=CDF:: + the ``RDF`` interpreter; elements of ``RDF`` just don't display all + their digits. We have special fast interpreter for ``domain=CDF``:: sage: f_float = fast_callable(expr, vars=[x], domain=float) sage: f_float(2) @@ -395,7 +394,7 @@ def fast_callable(x, domain=None, vars=None, sage: fc(5, 7) 0.5514266812416906 - Check that fast_callable also works for symbolic functions with evaluation + Check that :func:`fast_callable` also works for symbolic functions with evaluation functions:: sage: def evalf_func(self, x, y, parent): return parent(x*y) if parent is not None else x*y @@ -505,7 +504,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.all.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 @@ -536,13 +536,14 @@ def function_name(fn): except AttributeError: return "{%r}" % fn + cdef class ExpressionTreeBuilder: r""" A class with helper methods for building Expressions. - An instance of this class is passed to _fast_callable_ methods; + An instance of this class is passed to :meth:`_fast_callable_` methods; you can also instantiate it yourself to create your own expressions - for fast_callable, bypassing _fast_callable_. + for :func:`fast_callable`, bypassing :meth:`_fast_callable_`. EXAMPLES:: @@ -558,17 +559,18 @@ cdef class ExpressionTreeBuilder: def __init__(self, vars, domain=None): r""" - Initialize an instance of ExpressionTreeBuilder. Takes - a list or tuple of variable names to use, and also an optional - domain. If a domain is given, then creating an ExpressionConstant - node with the __call__, make, or constant methods will convert + Initialize an instance of :class:`ExpressionTreeBuilder`. + + Takes a list or tuple of variable names to use, and also an optional + ``domain``. If a ``domain`` is given, then creating an :class:`ExpressionConstant` + node with the :meth:`__call__`, make, or constant methods will convert the value into the given domain. Note that this is the only effect of the domain parameter. It is quite possible to use different domains for - ExpressionTreeBuilder and for fast_callable; in that case, + :class:`ExpressionTreeBuilder` and for :func:`fast_callable`; in that case, constants will be converted twice (once when building the - Expression, and once when generating code). + :class:`Expression`, and once when generating code). EXAMPLES:: @@ -593,10 +595,11 @@ cdef class ExpressionTreeBuilder: def __call__(self, x): r""" - Try to convert the given value to an Expression. If it is already - an Expression, just return it. If it has a _fast_callable_ - method, then call the method with self as an argument. Otherwise, - use self.constant() to turn it into a constant. + Try to convert the given value to an :class:`Expression`. + + If it is already an Expression, just return it. If it has a :meth:`_fast_callable_` + method, then call the method with ``self`` as an argument. Otherwise, + use ``self.constant()`` to turn it into a constant. EXAMPLES:: @@ -645,7 +648,7 @@ cdef class ExpressionTreeBuilder: def constant(self, c): r""" - Turn the argument into an ExpressionConstant, converting it to + Turn the argument into an :class:`ExpressionConstant`, converting it to our domain if we have one. EXAMPLES:: @@ -664,7 +667,7 @@ cdef class ExpressionTreeBuilder: def var(self, v): r""" - Turn the argument into an ExpressionVariable. Look it up in + Turn the argument into an :class:`ExpressionVariable`. Look it up in the list of variables. (Variables are matched by name.) EXAMPLES:: @@ -718,10 +721,10 @@ cdef class ExpressionTreeBuilder: Construct a call node, given a function and a list of arguments. The arguments will be converted to Expressions using - ExpressionTreeBuilder.__call__. + :meth:`ExpressionTreeBuilder.__call__`. - As a special case, notices if the function is operator.pow and - the second argument is integral, and constructs an ExpressionIPow + As a special case, notices if the function is :func:`operator.pow` and + the second argument is integral, and constructs an :class:`ExpressionIPow` instead. EXAMPLES:: @@ -764,6 +767,7 @@ cdef class ExpressionTreeBuilder: self(iftrue), self(iffalse)) + # Cache these values, to make expression building a tiny bit faster # (by skipping the hash-table lookup in the operator module). cdef op_add = operator.add @@ -781,14 +785,15 @@ cdef op_neg = operator.neg cdef op_abs = operator.abs cdef op_inv = operator.inv + cdef class Expression: r""" - Represent an expression for fast_callable. + Represent an expression for :func:`fast_callable`. Supports the standard Python arithmetic operators; if arithmetic is attempted between an Expression and a non-Expression, the non-Expression is converted to an expression (using the - __call__ method of the Expression's ExpressionTreeBuilder). + :meth:`__call__` method of the Expression's :class:`ExpressionTreeBuilder`). EXAMPLES:: @@ -956,7 +961,7 @@ cdef class Expression: Compute a power expression from two Expressions. If the second Expression is a constant integer, then return - an ExpressionIPow instead of an ExpressionCall. + an :class:`ExpressionIPow` instead of an :class:`ExpressionCall`. EXAMPLES:: @@ -1079,7 +1084,7 @@ cdef class ExpressionConstant(Expression): def __init__(self, etb, c): r""" - Initialize an ExpressionConstant. + Initialize an :class:`ExpressionConstant`. EXAMPLES:: @@ -1101,7 +1106,7 @@ cdef class ExpressionConstant(Expression): def value(self): r""" - Return the constant value of an ExpressionConstant. + Return the constant value of an :class:`ExpressionConstant`. EXAMPLES:: @@ -1114,7 +1119,7 @@ cdef class ExpressionConstant(Expression): def __repr__(self): r""" - Give a string representing this ExpressionConstant. + Give a string representing this :class:`ExpressionConstant`. (We use the repr of its value.) EXAMPLES:: @@ -1166,7 +1171,7 @@ cdef class ExpressionVariable(Expression): def variable_index(self): r""" - Return the variable index of an ExpressionVariable. + Return the variable index of an :class:`ExpressionVariable`. EXAMPLES:: @@ -1179,7 +1184,7 @@ cdef class ExpressionVariable(Expression): def __repr__(self): r""" - Give a string representing this ExpressionVariable. + Give a string representing this :class:`ExpressionVariable`. EXAMPLES:: @@ -1198,6 +1203,7 @@ cdef class ExpressionVariable(Expression): # from the original expression when we have an Expression. return "v_%d" % self._variable_index + cdef class ExpressionCall(Expression): r""" An Expression that represents a function call. @@ -1214,7 +1220,7 @@ cdef class ExpressionCall(Expression): def __init__(self, etb, fn, args): r""" - Initialize an ExpressionCall. + Initialize an :class:`ExpressionCall`. EXAMPLES:: @@ -1238,7 +1244,7 @@ cdef class ExpressionCall(Expression): def function(self): r""" - Return the function from this ExpressionCall. + Return the function from this :class:`ExpressionCall`. EXAMPLES:: @@ -1251,7 +1257,7 @@ cdef class ExpressionCall(Expression): def arguments(self): r""" - Return the arguments from this ExpressionCall. + Return the arguments from this :class:`ExpressionCall`. EXAMPLES:: @@ -1264,7 +1270,7 @@ cdef class ExpressionCall(Expression): def __repr__(self): r""" - Give a string representing this ExpressionCall. + Give a string representing this :class:`ExpressionCall`. EXAMPLES:: @@ -1327,7 +1333,7 @@ cdef class ExpressionIPow(Expression): def base(self): r""" - Return the base from this ExpressionIPow. + Return the base from this :class:`ExpressionIPow`. EXAMPLES:: @@ -1340,7 +1346,7 @@ cdef class ExpressionIPow(Expression): def exponent(self): r""" - Return the exponent from this ExpressionIPow. + Return the exponent from this :class:`ExpressionIPow`. EXAMPLES:: @@ -1353,7 +1359,7 @@ cdef class ExpressionIPow(Expression): def __repr__(self): r""" - Give a string representing this ExpressionIPow. + Give a string representing this :class:`ExpressionIPow`. EXAMPLES:: @@ -1374,6 +1380,7 @@ cdef class ExpressionIPow(Expression): """ return 'ipow(%s, %d)' % (repr(self._base), self._exponent) + cdef class ExpressionChoice(Expression): r""" A conditional expression. @@ -1394,7 +1401,7 @@ cdef class ExpressionChoice(Expression): def __init__(self, etb, cond, iftrue, iffalse): r""" - Initialize an ExpressionChoice. + Initialize an :class:`ExpressionChoice`. EXAMPLES:: @@ -1421,7 +1428,7 @@ cdef class ExpressionChoice(Expression): def condition(self): r""" - Return the condition of an ExpressionChoice. + Return the condition of an :class:`ExpressionChoice`. EXAMPLES:: @@ -1435,7 +1442,7 @@ cdef class ExpressionChoice(Expression): def if_true(self): r""" - Return the true branch of an ExpressionChoice. + Return the true branch of an :class:`ExpressionChoice`. EXAMPLES:: @@ -1449,7 +1456,7 @@ cdef class ExpressionChoice(Expression): def if_false(self): r""" - Return the false branch of an ExpressionChoice. + Return the false branch of an :class:`ExpressionChoice`. EXAMPLES:: @@ -1463,7 +1470,7 @@ cdef class ExpressionChoice(Expression): def __repr__(self): r""" - Give a string representation for this ExpressionChoice. + Give a string representation for this :class:`ExpressionChoice`. (Based on the syntax for Python conditional expressions.) EXAMPLES:: @@ -1483,10 +1490,12 @@ cdef class ExpressionChoice(Expression): repr(self._cond), repr(self._iffalse)) + cpdef _expression_binop_helper(s, o, op): r""" - Make an Expression for (s op o). Either s or o (or both) must already - be an expression. + Make an :class:`Expression` for (``s`` ``op`` ``o``). + + Either ``s`` or ``o`` (or both) must already be an :class:`Expression`. EXAMPLES:: @@ -1496,7 +1505,7 @@ cpdef _expression_binop_helper(s, o, op): sage: etb = ExpressionTreeBuilder(vars=(x,y)) sage: x = etb(x) - Now x is an Expression, but y is not. Still, all the following + Now ``x`` is an :class:`Expression`, but ``y`` is not. Still, all the following cases work:: sage: _expression_binop_helper(x, x, operator.add) @@ -1537,9 +1546,10 @@ cpdef _expression_binop_helper(s, o, op): class IntegerPowerFunction(): r""" - This class represents the function x^n for an arbitrary integral - power n. That is, IntegerPowerFunction(2) is the squaring function; - IntegerPowerFunction(-1) is the reciprocal function. + This class represents the function `x^n` for an arbitrary integral power `n`. + + That is, ``IntegerPowerFunction(2)`` is the squaring function; + ``IntegerPowerFunction(-1)`` is the reciprocal function. EXAMPLES:: @@ -1566,7 +1576,7 @@ class IntegerPowerFunction(): def __init__(self, n): r""" - Initialize an IntegerPowerFunction. + Initialize an :class:`IntegerPowerFunction`. EXAMPLES:: @@ -1583,7 +1593,7 @@ class IntegerPowerFunction(): def __repr__(self): r""" - Return a string representing this IntegerPowerFunction. + Return a string representing this :class:`IntegerPowerFunction`. EXAMPLES:: @@ -1605,7 +1615,7 @@ class IntegerPowerFunction(): def __call__(self, x): r""" - Call this IntegerPowerFunction, to compute a power of its argument. + Call this :class:`IntegerPowerFunction`, to compute a power of its argument. EXAMPLES:: @@ -1618,6 +1628,7 @@ class IntegerPowerFunction(): """ return x**self.exponent + cdef dict builtin_functions = None cpdef dict get_builtin_functions(): r""" @@ -1633,11 +1644,13 @@ cpdef dict get_builtin_functions(): sage: from sage.ext.fast_callable import get_builtin_functions sage: builtins = get_builtin_functions() - sage: sorted(set(builtins.values())) - ['abs', 'acos', 'acosh', 'add', 'asin', 'asinh', 'atan', 'atanh', 'ceil', 'cos', 'cosh', 'cot', 'csc', 'div', 'exp', 'floor', 'floordiv', 'inv', 'log', 'mul', 'neg', 'pow', 'sec', 'sin', 'sinh', 'sqrt', 'sub', 'tan', 'tanh'] - sage: builtins[sin] + sage: sorted(set(builtins.values())) # optional - sage.symbolic + ['abs', 'acos', 'acosh', 'add', 'asin', 'asinh', 'atan', 'atanh', 'ceil', + 'cos', 'cosh', 'cot', 'csc', 'div', 'exp', 'floor', 'floordiv', 'inv', 'log', + 'mul', 'neg', 'pow', 'sec', 'sin', 'sinh', 'sqrt', 'sub', 'tan', 'tanh'] + sage: builtins[sin] # optional - sage.symbolic 'sin' - sage: builtins[ln] + sage: builtins[ln] # optional - sage.symbolic 'log' """ # We delay building builtin_functions to break a circular import @@ -1658,47 +1671,53 @@ cpdef dict get_builtin_functions(): op_pow: 'pow', } - # not handled: atan2, log2, log10 - import sage.functions.all as func_all - for fn in ('sqrt', 'ceil', 'floor', - 'sin', 'cos', 'tan', 'sec', 'csc', 'cot', - 'asin', 'acos', 'atan', 'sinh', 'cosh', 'tanh', - 'asinh', 'acosh', 'atanh', 'exp', 'log'): - builtin_functions[getattr(func_all, fn)] = fn - builtin_functions[func_all.abs_symbolic] = 'abs' - builtin_functions[func_all.ln] = 'log' + try: + import sage.functions.all as func_all + except ImportError: + pass + else: + # not handled: atan2, log2, log10 + for fn in ('sqrt', 'ceil', 'floor', + 'sin', 'cos', 'tan', 'sec', 'csc', 'cot', + 'asin', 'acos', 'atan', 'sinh', 'cosh', 'tanh', + 'asinh', 'acosh', 'atanh', 'exp', 'log'): + builtin_functions[getattr(func_all, fn)] = fn + builtin_functions[func_all.abs_symbolic] = 'abs' + builtin_functions[func_all.ln] = 'log' return builtin_functions + cdef class InstructionStream # forward declaration + cpdef generate_code(Expression expr, InstructionStream stream): r""" - Generate code from an Expression tree; write the result into an - InstructionStream. + Generate code from an :class:`Expression` tree; write the result into an + :class:`InstructionStream`. - In fast_callable, first we create an Expression, either directly - with an ExpressionTreeBuilder or with _fast_callable_ methods. - Then we optimize the Expression in tree form. (Unfortunately, + In :func:`fast_callable`, first we create an :class:`Expression`, either directly + with an :class:`ExpressionTreeBuilder` or with :meth:`_fast_callable_` methods. + Then we optimize the :class:`Expression` in tree form. (Unfortunately, this step is currently missing -- we do no optimizations.) - Then we linearize the Expression into a sequence of instructions, - by walking the Expression and sending the corresponding stack - instructions to an InstructionStream. + Then we linearize the :class:`Expression` into a sequence of instructions, + by walking the :class:`Expression` and sending the corresponding stack + instructions to an :class:`InstructionStream`. EXAMPLES:: sage: from sage.ext.fast_callable import ExpressionTreeBuilder, generate_code, InstructionStream sage: etb = ExpressionTreeBuilder('x') sage: x = etb.var('x') - sage: expr = ((x+pi)*(x+1)) + sage: expr = (x+pi) * (x+1) # optional - sage.symbolic sage: from sage.ext.interpreters.wrapper_py import metadata, Wrapper_py sage: instr_stream = InstructionStream(metadata, 1) - sage: generate_code(expr, instr_stream) + sage: generate_code(expr, instr_stream) # optional - sage.symbolic sage: instr_stream.instr('return') sage: v = Wrapper_py(instr_stream.get_current()) sage: type(v) - sage: v(7) + sage: v(7) # optional - sage.symbolic 8*pi + 56 TESTS:: @@ -1708,33 +1727,33 @@ cpdef generate_code(Expression expr, InstructionStream stream): sage: def my_sqrt(x): ....: if x < 0: raise ValueError("sqrt of negative number") ....: return sqrt(x, extend=False) - sage: fc = fast_callable(expr, domain=RealField(130)) - sage: fc(0) + sage: fc = fast_callable(expr, domain=RealField(130)) # optional - sage.symbolic + sage: fc(0) # optional - sage.symbolic 3.1415926535897932384626433832795028842 - sage: fc(1) + sage: fc(1) # optional - sage.symbolic 8.2831853071795864769252867665590057684 - sage: fc = fast_callable(expr, domain=RDF) - sage: fc(0) + sage: fc = fast_callable(expr, domain=RDF) # optional - sage.symbolic + sage: fc(0) # optional - sage.symbolic 3.141592653589793 - sage: fc(1) + sage: fc(1) # optional - sage.symbolic 8.283185307179586 - sage: fc.op_list() + sage: fc.op_list() # optional - sage.symbolic [('load_arg', 0), ('load_const', pi), 'add', ('load_arg', 0), ('load_const', 1), 'add', 'mul', 'return'] - sage: fc = fast_callable(etb.call(sin, x) + etb.call(sqrt, x), domain=RDF) - sage: fc(1) + sage: fc = fast_callable(etb.call(sin, x) + etb.call(sqrt, x), domain=RDF) # optional - sage.symbolic + sage: fc(1) # optional - sage.symbolic 1.8414709848078965 - sage: fc.op_list() + sage: fc.op_list() # optional - sage.symbolic [('load_arg', 0), 'sin', ('load_arg', 0), 'sqrt', 'add', 'return'] - sage: fc = fast_callable(etb.call(sin, x) + etb.call(sqrt, x)) - sage: fc(1) + sage: fc = fast_callable(etb.call(sin, x) + etb.call(sqrt, x)) # optional - sage.symbolic + sage: fc(1) # optional - sage.symbolic sin(1) + 1 - sage: fc.op_list() + sage: fc.op_list() # optional - sage.symbolic [('load_arg', 0), ('py_call', sin, 1), ('load_arg', 0), ('py_call', , 1), 'add', 'return'] sage: fc = fast_callable(etb.call(my_sin, x), domain=RDF) - sage: fc(3) + sage: fc(3) # optional - sage.symbolic 0.1411200080598672 sage: fc = fast_callable(etb.call(my_sin, x), domain=RealField(100)) - sage: fc(3) + sage: fc(3) # optional - sage.symbolic 0.14112000805986722210074480281 sage: fc.op_list() [('load_arg', 0), ('py_call', , 1), 'return'] @@ -1785,10 +1804,10 @@ cpdef generate_code(Expression expr, InstructionStream stream): TypeError: no conversion of this rational to integer sage: fc(6) 2 - sage: fc = fast_callable(etb.call(sin, x), domain=ZZ) - sage: fc(0) + sage: fc = fast_callable(etb.call(sin, x), domain=ZZ) # optional - sage.symbolic + sage: fc(0) # optional - sage.symbolic 0 - sage: fc(3) + sage: fc(3) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: unable to convert sin(3) to an integer @@ -1796,7 +1815,7 @@ cpdef generate_code(Expression expr, InstructionStream stream): :: sage: fc = fast_callable(etb(x)^100) - sage: fc(pi) + sage: fc(pi) # optional - sage.symbolic pi^100 sage: fc = fast_callable(etb(x)^100, domain=ZZ) sage: fc(2) @@ -1908,14 +1927,16 @@ cpdef generate_code(Expression expr, InstructionStream stream): else: raise ValueError("Unhandled expression kind %s in generate_code" % type(expr)) + cdef class InterpreterMetadata # forward declaration + cdef class InstructionStream: r""" - An InstructionStream takes a sequence of instructions (passed in by + An :class:`InstructionStream` takes a sequence of instructions (passed in by a series of method calls) and computes the data structures needed by the interpreter. This is the stage where we switch from operating - on Expression trees to a linear representation. If we had a peephole + on :classL`Expression` trees to a linear representation. If we had a peephole optimizer (we don't) it would go here. Currently, this class is not very general; it only works for @@ -1925,7 +1946,7 @@ cdef class InstructionStream: a description of the memory chunks involved and the instruction stream can handle any interpreter. - Once you're done adding instructions, you call get_current() to retrieve + Once you're done adding instructions, you call :meth:`get_current` to retrieve the information needed by the interpreter (as a Python dictionary). """ @@ -1943,16 +1964,16 @@ cdef class InstructionStream: def __init__(self, metadata, n_args, domain=None): r""" - Initialize an InstructionStream. + Initialize an :class:`InstructionStream`. INPUT: - - metadata -- The metadata_by_opname from a wrapper module + - ``metadata`` -- The ``metadata_by_opname`` from a wrapper module - - n_args -- The number of arguments accessible by the generated code + - ``n_args`` -- The number of arguments accessible by the generated code (this is just passed to the wrapper class) - - domain -- The domain of interpretation (this is just passed to the + - ``domain`` -- The domain of interpretation (this is just passed to the wrapper class) EXAMPLES:: @@ -1989,7 +2010,7 @@ cdef class InstructionStream: def load_const(self, c): r""" - Add a 'load_const' instruction to this InstructionStream. + Add a ``'load_const'`` instruction to this :class:`InstructionStream`. EXAMPLES:: @@ -2014,7 +2035,7 @@ cdef class InstructionStream: def load_arg(self, n): r""" - Add a 'load_arg' instruction to this InstructionStream. + Add a ``'load_arg'`` instruction to this :class:`InstructionStream`. EXAMPLES:: @@ -2032,7 +2053,7 @@ cdef class InstructionStream: cpdef bint has_instr(self, opname): r""" - Check whether this InstructionStream knows how to generate code + Check whether this :class:`InstructionStream` knows how to generate code for a given instruction. EXAMPLES:: @@ -2051,12 +2072,12 @@ cdef class InstructionStream: def instr(self, opname, *args): r""" - Generate code in this InstructionStream for the given instruction + Generate code in this :class:`InstructionStream` for the given instruction and arguments. - The opname is used to look up a CompilerInstrSpec; the - CompilerInstrSpec describes how to interpret the arguments. - (This is documented in the class docstring for CompilerInstrSpec.) + The opname is used to look up a :class:`CompilerInstrSpec`; the + :class:`CompilerInstrSpec` describes how to interpret the arguments. + (This is documented in the class docstring for :class:`CompilerInstrSpec`.) EXAMPLES:: @@ -2064,15 +2085,15 @@ cdef class InstructionStream: sage: from sage.ext.fast_callable import InstructionStream sage: instr_stream = InstructionStream(metadata, 1) sage: instr_stream.instr('load_arg', 0) - sage: instr_stream.instr('sin') + sage: instr_stream.instr('sin') # optional - sage.symbolic sage: instr_stream.instr('py_call', math.sin, 1) - sage: instr_stream.instr('abs') + sage: instr_stream.instr('abs') # optional - sage.symbolic sage: instr_stream.instr('factorial') Traceback (most recent call last): ... KeyError: 'factorial' sage: instr_stream.instr('return') - sage: instr_stream.current_op_list() + sage: instr_stream.current_op_list() # optional - sage.symbolic [('load_arg', 0), 'sin', ('py_call', , 1), 'abs', 'return'] """ self.instr0(opname, args) @@ -2130,8 +2151,7 @@ cdef class InstructionStream: def get_metadata(self): r""" - Return the interpreter metadata being used by the current - InstructionStream. + Return the interpreter metadata being used by the current :class:`InstructionStream`. The code generator sometimes uses this to decide which code to generate. @@ -2150,7 +2170,7 @@ cdef class InstructionStream: def current_op_list(self): r""" Return the list of instructions that have been added to this - InstructionStream so far. + :class:`InstructionStream` so far. It's OK to call this, then add more instructions. @@ -2170,11 +2190,11 @@ cdef class InstructionStream: def get_current(self): r""" - Return the current state of the InstructionStream, as a dictionary + Return the current state of the :class:`InstructionStream`, as a dictionary suitable for passing to a wrapper class. NOTE: The dictionary includes internal data structures of the - InstructionStream; you must not modify it. + :class:`InstructionStream`; you must not modify it. EXAMPLES:: @@ -2213,17 +2233,18 @@ cdef class InstructionStream: cdef class InterpreterMetadata(): r""" - The interpreter metadata for a fast_callable interpreter. Currently - consists of a dictionary mapping instruction names to - (CompilerInstrSpec, opcode) pairs, a list mapping opcodes to - (instruction name, CompilerInstrSpec) pairs, and a range of exponents - for which the ipow instruction can be used. This range can be - False (if the ipow instruction should never be used), a pair of - two integers (a,b), if ipow should be used for a<=n<=b, or True, - if ipow should always be used. When ipow cannot be used, then - we fall back on calling IntegerPowerFunction. - - See the class docstring for CompilerInstrSpec for more information. + The interpreter metadata for a :func:`fast_callable` interpreter. + + Currently consists of a dictionary mapping instruction names to + (:class:`CompilerInstrSpec`, opcode) pairs, a list mapping opcodes to + (instruction name, :class:`CompilerInstrSpec`) pairs, and a range of exponents + for which the ``'ipow'`` instruction can be used. This range can be + ``False`` (if the ``'ipow'`` instruction should never be used), a pair of + two integers ``(a, b)``, if ``'ipow'`` should be used for a<=n<=b, or ``True``, + if ``'ipow'`` should always be used. When ``'ipow'`` cannot be used, then + we fall back on calling :class:`IntegerPowerFunction`. + + See the class docstring for :class:`CompilerInstrSpec` for more information. NOTE: You must not modify the metadata. """ @@ -2253,25 +2274,25 @@ cdef class InterpreterMetadata(): class CompilerInstrSpec(): r""" - Describe a single instruction to the fast_callable code generator. + Describe a single instruction to the :func:`fast_callable` code generator. An instruction has a number of stack inputs, a number of stack outputs, and a parameter list describing extra arguments that - must be passed to the InstructionStream.instr method (that end up + must be passed to the :meth:`InstructionStream.instr` method (that end up as extra words in the code). The parameter list is a list of strings. Each string is one of the following: - - 'args' - The instruction argument refers to an input argument of the + - ``'args'`` - The instruction argument refers to an input argument of the wrapper class; it is just appended to the code. - - 'constants', 'py_constants' - The instruction argument is a value; the + - ``'constants'``, ``'py_constants'`` - The instruction argument is a value; the value is added to the corresponding list (if it's not already there) and the index is appended to the code. - - 'n_inputs', 'n_outputs' - The instruction actually takes a variable - number of inputs or outputs (the n_inputs and n_outputs attributes of + - ``'n_inputs'``, ``'n_outputs'`` - The instruction actually takes a variable + number of inputs or outputs (the ``n_inputs`` and ``n_outputs`` attributes of this instruction are ignored). The instruction argument specifies the number of inputs or outputs (respectively); it is just appended to the code. @@ -2279,7 +2300,7 @@ class CompilerInstrSpec(): def __init__(self, n_inputs, n_outputs, parameters): r""" - Initialize a CompilerInstrSpec. + Initialize a :class:`CompilerInstrSpec`. EXAMPLES:: @@ -2293,7 +2314,7 @@ class CompilerInstrSpec(): def __repr__(self): r""" - Give a string representation for this CompilerInstrSpec. + Give a string representation for this :class:`CompilerInstrSpec`. EXAMPLES:: @@ -2308,10 +2329,11 @@ class CompilerInstrSpec(): """ return "CompilerInstrSpec(%d, %d, %s)" % (self.n_inputs, self.n_outputs, self.parameters) + def op_list(args, metadata): r""" - Given a dictionary with the result of calling get_current on an - InstructionStream, and the corresponding interpreter metadata, + Given a dictionary with the result of calling :meth:`get_current` on an + :class:`InstructionStream`, and the corresponding interpreter metadata, return a list of the instructions, in a simple somewhat human-readable format. @@ -2321,8 +2343,8 @@ def op_list(args, metadata): screen.) There's probably no reason to call this directly; if you - have a wrapper object, call op_list on it; if you have an - InstructionStream object, call current_op_list on it. + have a wrapper object, call :func:`op_list` on it; if you have an + :class:`InstructionStream` object, call :meth:`current_op_list` on it. EXAMPLES:: @@ -2360,8 +2382,9 @@ def op_list(args, metadata): cdef class Wrapper: r""" - The parent class for all fast_callable wrappers. Implements shared - behavior (currently only debugging). + The parent class for all :func:`fast_callable` wrappers. + + Implements shared behavior (currently only debugging). """ def __init__(self, args, metadata): @@ -2373,20 +2396,20 @@ cdef class Wrapper: sage: from sage.ext.fast_callable import ExpressionTreeBuilder, generate_code, InstructionStream sage: etb = ExpressionTreeBuilder('x') sage: x = etb.var('x') - sage: expr = ((x+pi)*(x+1)) + sage: expr = (x+pi) * (x+1) # optional - sage.symbolic sage: from sage.ext.interpreters.wrapper_py import metadata, Wrapper_py sage: instr_stream = InstructionStream(metadata, 1) - sage: generate_code(expr, instr_stream) + sage: generate_code(expr, instr_stream) # optional - sage.symbolic sage: instr_stream.instr('return') sage: v = Wrapper_py(instr_stream.get_current()) - sage: v.get_orig_args() + sage: v.get_orig_args() # optional - sage.symbolic {'args': 1, 'code': [0, 0, 1, 0, 4, 0, 0, 1, 1, 4, 6, 2], 'constants': [pi, 1], 'domain': None, 'py_constants': [], 'stack': 3} - sage: v.op_list() + sage: v.op_list() # optional - sage.symbolic [('load_arg', 0), ('load_const', pi), 'add', ('load_arg', 0), ('load_const', 1), 'add', 'mul', 'return'] """ @@ -2399,14 +2422,13 @@ cdef class Wrapper: def get_orig_args(self): r""" - Get the original arguments used when initializing this - wrapper. + Get the original arguments used when initializing this wrapper. (Probably only useful when writing doctests.) EXAMPLES:: - sage: fast_callable(sin(x)/x, vars=[x], domain=RDF).get_orig_args() + sage: fast_callable(sin(x)/x, vars=[x], domain=RDF).get_orig_args() # optional - sage.symbolic {'args': 1, 'code': [0, 0, 16, 0, 0, 8, 2], 'constants': [], @@ -2422,7 +2444,7 @@ cdef class Wrapper: EXAMPLES:: - sage: fast_callable(cos(x)*x, vars=[x], domain=RDF).op_list() + sage: fast_callable(cos(x) * x, vars=[x], domain=RDF).op_list() # optional - sage.symbolic [('load_arg', 0), ('load_arg', 0), 'cos', 'mul', 'return'] """ return op_list(self._orig_args, self._metadata) @@ -2438,9 +2460,9 @@ cdef class Wrapper: EXAMPLES:: - sage: fast_callable(abs(sin(x)), vars=[x], domain=RDF).python_calls() + sage: fast_callable(abs(sin(x)), vars=[x], domain=RDF).python_calls() # optional - sage.symbolic [] - sage: fast_callable(abs(sin(factorial(x))), vars=[x]).python_calls() + sage: fast_callable(abs(sin(factorial(x))), vars=[x]).python_calls() # optional - sage.symbolic [factorial, sin] """ ops = self.op_list() @@ -2460,15 +2482,15 @@ class FastCallableFloatWrapper: faster form with :func:`fast_callable`. That function takes a ``domain`` parameter that forces the end (and all intermediate) results of evaluation to a specific type. Though usually always - want the end result to be of type ``float``, correctly choosing + want the end result to be of type :class:`float`, correctly choosing the ``domain`` presents some problems: - * ``float`` is a bad choice because it's common for real + * :class:`float` is a bad choice because it's common for real functions to have complex terms in them. Moreover precision issues can produce terms like ``1.0 + 1e-12*I`` that are hard to avoid if calling ``real()`` on everything is infeasible. - * ``complex`` has essentially the same problem as ``float``. + * :class:`complex` has essentially the same problem as :class:`float`. There are several symbolic functions like :func:`min_symbolic`, :func:`max_symbolic`, and :func:`floor` that are unable to operate on complex numbers. @@ -2482,7 +2504,7 @@ class FastCallableFloatWrapper: min/max), and supports :func:`floor`. However, most numerical functions cannot handle complex numbers, so using ``CDF`` would require us to wrap every evaluation in a - ``CDF``-to-``float`` conversion routine. That would slow + ``CDF``-to-:class:`float` conversion routine. That would slow things down less than a domain of ``None`` would, but is unattractive mainly because of how invasive it would be to "fix" the output everywhere. @@ -2501,8 +2523,8 @@ class FastCallableFloatWrapper: :func:`fast_callable`. Whenever we need to support intermediate complex terms in a numerical routine, we can set ``domain=CDF`` while creating its fast-callable incarnation, and then wrap the - result in this class. The ``__call__`` method of this class then - ensures that the ``CDF`` output is converted to a ``float`` if + result in this class. The :meth:`__call__` method of this class then + ensures that the ``CDF`` output is converted to a :class:`float` if its imaginary part is within an acceptable tolerance. EXAMPLES: @@ -2524,7 +2546,7 @@ class FastCallableFloatWrapper: """ def __init__(self, ff, imag_tol): r""" - Construct a ``FastCallableFloatWrapper``. + Construct a :class:`FastCallableFloatWrapper`. INPUT: @@ -2537,9 +2559,9 @@ class FastCallableFloatWrapper: OUTPUT: - An instance of ``FastCallableFloatWrapper`` that can be - called just like ``ff``, but that always returns a ``float`` - if no error is raised. A ``ValueError`` is raised if the + An instance of :class:`FastCallableFloatWrapper` that can be + called just like ``ff``, but that always returns a :class:`float` + if no error is raised. A :class:`ValueError` is raised if the imaginary part of the result exceeds ``imag_tol``. EXAMPLES: @@ -2566,13 +2588,11 @@ class FastCallableFloatWrapper: def __call__(self, *args): r""" - Evaluate the underlying fast-callable and convert the result to - ``float``. + Evaluate the underlying fast-callable and convert the result to :class:`float`. TESTS: - Evaluation either returns a ``float``, or raises a - ``ValueError``:: + Evaluation either returns a :class:`float`, or raises a :class:`ValueError`:: sage: from sage.ext.fast_callable import FastCallableFloatWrapper sage: f = x diff --git a/src/sage/features/kenzo.py b/src/sage/features/kenzo.py index 655602427b8..aae1c780344 100644 --- a/src/sage/features/kenzo.py +++ b/src/sage/features/kenzo.py @@ -48,7 +48,10 @@ def _is_present(self): sage: Kenzo()._is_present() # optional - kenzo FeatureTestResult('kenzo', True) """ - from sage.libs.ecl import ecl_eval + try: + from sage.libs.ecl import ecl_eval + except ImportError: + return FeatureTestResult(self, False, reason="Unable import sage.libs.ecl") # Redirection of ECL and Maxima stdout to /dev/null # This is also done in the Maxima library, but we # also do it here for redundancy. diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index 7e545404de2..27faca1d3fa 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -134,6 +134,53 @@ def __init__(self): [PythonModule('sage.groups.perm_gps.permgroup')]) +class sage__libs__flint(JoinFeature): + r""" + A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.flint` + and other modules depending on FLINT and arb. + + EXAMPLES:: + + sage: from sage.features.sagemath import sage__libs__flint + sage: sage__libs__flint().is_present() # optional - sage.libs.flint + FeatureTestResult('sage.libs.flint', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__libs__flint + sage: isinstance(sage__libs__flint(), sage__libs__flint) + True + """ + JoinFeature.__init__(self, 'sage.libs.flint', + [PythonModule('sage.libs.flint.flint'), + PythonModule('sage.libs.arb.arith')]) + + +class sage__libs__ntl(JoinFeature): + r""" + A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.ntl` + and other modules depending on NTL and arb. + + EXAMPLES:: + + sage: from sage.features.sagemath import sage__libs__ntl + sage: sage__libs__ntl().is_present() # optional - sage.libs.ntl + FeatureTestResult('sage.libs.ntl', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__libs__ntl + sage: isinstance(sage__libs__ntl(), sage__libs__ntl) + True + """ + JoinFeature.__init__(self, 'sage.libs.ntl', + [PythonModule('sage.libs.ntl.convert')]) + + class sage__libs__pari(JoinFeature): r""" A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.pari`. @@ -290,6 +337,28 @@ def __init__(self): [PythonModule('sage.rings.padics.factory')]) +class sage__rings__polynomial__pbori(JoinFeature): + r""" + A :class:`sage.features.Feature` describing the presence of :mod:`sage.rings.polynomial.pbori`. + + EXAMPLES:: + + sage: from sage.features.sagemath import sage__rings__polynomial__pbori + sage: sage__rings__polynomial__pbori().is_present() # optional - sage.rings.polynomial.pbori + FeatureTestResult('sage.rings.polynomial.pbori', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__rings__polynomial__pbori + sage: isinstance(sage__rings__polynomial__pbori(), sage__rings__polynomial__pbori) + True + """ + JoinFeature.__init__(self, 'sage.rings.polynomial.pbori', + [PythonModule('sage.rings.polynomial.pbori.pbori')]) + + class sage__rings__real_double(PythonModule): r""" A :class:`~sage.features.Feature` describing the presence of :mod:`sage.rings.real_double`. @@ -382,6 +451,8 @@ def all_features(): sage__geometry__polyhedron(), sage__graphs(), sage__groups(), + sage__libs__flint(), + sage__libs__ntl(), sage__libs__pari(), sage__modules(), sage__plot(), @@ -389,6 +460,7 @@ def all_features(): sage__rings__function_field(), sage__rings__number_field(), sage__rings__padics(), + sage__rings__polynomial__pbori(), sage__rings__real_double(), sage__rings__real_mpfr(), sage__symbolic()] diff --git a/src/sage/features/standard.py b/src/sage/features/standard.py index f48f47f2614..54d1f804cef 100644 --- a/src/sage/features/standard.py +++ b/src/sage/features/standard.py @@ -30,6 +30,7 @@ def all_features(): JoinFeature('pplpy', (PythonModule('ppl'),), spkg='pplpy'), PythonModule('primecountpy', spkg='primecountpy'), PythonModule('ptyprocess', spkg='ptyprocess'), + PythonModule('pyparsing', spkg='pyparsing'), PythonModule('requests', spkg='requests'), PythonModule('scipy', spkg='scipy'), PythonModule('sympy', spkg='sympy')] diff --git a/src/sage/functions/gamma.py b/src/sage/functions/gamma.py index e93e518b0b9..aba008a38a4 100644 --- a/src/sage/functions/gamma.py +++ b/src/sage/functions/gamma.py @@ -150,10 +150,10 @@ def __init__(self): Check that the implementations roughly agrees (note there might be difference of several ulp on more complicated entries):: - sage: import mpmath - sage: float(gamma(10.)) == gamma(10.r) == float(gamma(mpmath.mpf(10))) + sage: import mpmath # optional - mpmath + sage: float(gamma(10.)) == gamma(10.r) == float(gamma(mpmath.mpf(10))) # optional - mpmath True - sage: float(gamma(8.5)) == gamma(8.5r) == float(gamma(mpmath.mpf(8.5))) + sage: float(gamma(8.5)) == gamma(8.5r) == float(gamma(mpmath.mpf(8.5))) # optional - mpmath True Check that ``QQbar`` half integers work with the ``pi`` formula:: diff --git a/src/sage/functions/hyperbolic.py b/src/sage/functions/hyperbolic.py index 9a362b8882f..6f58a2ce75c 100644 --- a/src/sage/functions/hyperbolic.py +++ b/src/sage/functions/hyperbolic.py @@ -65,7 +65,7 @@ def __init__(self): sage: latex(sinh(x)) \sinh\left(x\right) - sage: sinh(x)._sympy_() + sage: sinh(x)._sympy_() # optional - sympy sinh(x) To prevent automatic evaluation, use the ``hold`` parameter:: @@ -102,7 +102,7 @@ def __init__(self): sage: latex(cosh(x)) \cosh\left(x\right) - sage: cosh(x)._sympy_() + sage: cosh(x)._sympy_() # optional - sympy cosh(x) To prevent automatic evaluation, use the ``hold`` parameter:: @@ -164,7 +164,7 @@ def __init__(self): sage: latex(tanh(x)) \tanh\left(x\right) - sage: tanh(x)._sympy_() + sage: tanh(x)._sympy_() # optional - sympy tanh(x) Check that real/imaginary parts are correct (:trac:`20098`):: @@ -222,7 +222,7 @@ def __init__(self): -1/sinh(x)^2 sage: latex(coth(x)) \coth\left(x\right) - sage: coth(x)._sympy_() + sage: coth(x)._sympy_() # optional - sympy coth(x) """ GinacFunction.__init__(self, "coth", latex_name=r"\coth") @@ -231,9 +231,9 @@ def _eval_numpy_(self, x): """ EXAMPLES:: - sage: import numpy - sage: a = numpy.arange(2, 5) - sage: coth(a) + sage: import numpy # optional - numpy + sage: a = numpy.arange(2, 5) # optional - numpy + sage: coth(a) # optional - numpy array([1.03731472, 1.00496982, 1.00067115]) """ return 1.0 / tanh(x) @@ -276,7 +276,7 @@ def __init__(self): -sech(x)*tanh(x) sage: latex(sech(x)) \operatorname{sech}\left(x\right) - sage: sech(x)._sympy_() + sage: sech(x)._sympy_() # optional - sympy sech(x) """ GinacFunction.__init__(self, "sech", latex_name=r"\operatorname{sech}",) @@ -285,9 +285,9 @@ def _eval_numpy_(self, x): """ EXAMPLES:: - sage: import numpy - sage: a = numpy.arange(2, 5) - sage: sech(a) + sage: import numpy # optional - numpy + sage: a = numpy.arange(2, 5) # optional - numpy + sage: sech(a) # optional - numpy array([0.26580223, 0.09932793, 0.03661899]) """ return 1.0 / cosh(x) @@ -328,7 +328,7 @@ def __init__(self): -coth(x)*csch(x) sage: latex(csch(x)) \operatorname{csch}\left(x\right) - sage: csch(x)._sympy_() + sage: csch(x)._sympy_() # optional - sympy csch(x) """ GinacFunction.__init__(self, "csch", latex_name=r"\operatorname{csch}") @@ -337,9 +337,9 @@ def _eval_numpy_(self, x): """ EXAMPLES:: - sage: import numpy - sage: a = numpy.arange(2, 5) - sage: csch(a) + sage: import numpy # optional - numpy + sage: a = numpy.arange(2, 5) # optional - numpy + sage: csch(a) # optional - numpy array([0.27572056, 0.09982157, 0.03664357]) """ return 1.0 / sinh(x) @@ -403,7 +403,7 @@ def __init__(self): arcsinh sage: latex(asinh(x)) \operatorname{arsinh}\left(x\right) - sage: asinh(x)._sympy_() + sage: asinh(x)._sympy_() # optional - sympy asinh(x) """ GinacFunction.__init__(self, "arcsinh", @@ -489,7 +489,7 @@ def __init__(self): arccosh sage: latex(acosh(x)) \operatorname{arcosh}\left(x\right) - sage: acosh(x)._sympy_() + sage: acosh(x)._sympy_() # optional - sympy acosh(x) """ GinacFunction.__init__(self, "arccosh", @@ -549,7 +549,7 @@ def __init__(self): arctanh sage: latex(atanh(x)) \operatorname{artanh}\left(x\right) - sage: atanh(x)._sympy_() + sage: atanh(x)._sympy_() # optional - sympy atanh(x) """ GinacFunction.__init__(self, "arctanh", @@ -593,7 +593,7 @@ def __init__(self): sage: latex(acoth(x)) \operatorname{arcoth}\left(x\right) - sage: acoth(x)._sympy_() + sage: acoth(x)._sympy_() # optional - sympy acoth(x) Check that :trac:`23636` is fixed:: @@ -611,9 +611,9 @@ def _eval_numpy_(self, x): """ EXAMPLES:: - sage: import numpy - sage: a = numpy.arange(2,5) - sage: acoth(a) + sage: import numpy # optional - numpy + sage: a = numpy.arange(2,5) # optional - numpy + sage: acoth(a) # optional - numpy array([0.54930614, 0.34657359, 0.25541281]) """ return arctanh(1.0 / x) @@ -644,7 +644,7 @@ def __init__(self): -1/(sqrt(-x^2 + 1)*x) sage: latex(asech(x)) \operatorname{arsech}\left(x\right) - sage: asech(x)._sympy_() + sage: asech(x)._sympy_() # optional - sympy asech(x) """ GinacFunction.__init__(self, "arcsech", @@ -657,9 +657,9 @@ def _eval_numpy_(self, x): """ EXAMPLES:: - sage: import numpy - sage: a = numpy.linspace(0,1,3) - sage: asech(a) + sage: import numpy # optional - numpy + sage: a = numpy.linspace(0,1,3) # optional - numpy + sage: asech(a) # optional - numpy doctest:...: RuntimeWarning: divide by zero encountered in ...divide array([ inf, 1.3169579, 0. ]) """ @@ -698,7 +698,7 @@ def __init__(self): sage: acsch(float(0.1)) 2.99822295029797 - sage: acsch(x)._sympy_() + sage: acsch(x)._sympy_() # optional - sympy acsch(x) """ GinacFunction.__init__(self, "arccsch", @@ -711,9 +711,9 @@ def _eval_numpy_(self, x): """ EXAMPLES:: - sage: import numpy - sage: a = numpy.linspace(0,1,3) - sage: acsch(a) + sage: import numpy # optional - numpy + sage: a = numpy.linspace(0,1,3) # optional - numpy + sage: acsch(a) # optional - numpy doctest:...: RuntimeWarning: divide by zero encountered in ...divide array([ inf, 1.44363548, 0.88137359]) """ diff --git a/src/sage/functions/jacobi.py b/src/sage/functions/jacobi.py index 6fe3b2ade89..3e751bd7f71 100644 --- a/src/sage/functions/jacobi.py +++ b/src/sage/functions/jacobi.py @@ -208,70 +208,70 @@ def _eval_(self, x, m): Check that the simplifications are correct:: - sage: from mpmath import almosteq - sage: almosteq(n(jacobi_nd(8, 0, hold=True)), n(jacobi_nd(8, 0))) + sage: from mpmath import almosteq # optional - mpmath + sage: almosteq(n(jacobi_nd(8, 0, hold=True)), n(jacobi_nd(8, 0))) # optional - mpmath True - sage: almosteq(n(jacobi_nd(1, 1, hold=True)), n(jacobi_nd(1, 1))) + sage: almosteq(n(jacobi_nd(1, 1, hold=True)), n(jacobi_nd(1, 1))) # optional - mpmath True - sage: almosteq(n(jacobi_nd(0, -5, hold=True)), n(jacobi_nd(0, -5))) + sage: almosteq(n(jacobi_nd(0, -5, hold=True)), n(jacobi_nd(0, -5))) # optional - mpmath True - sage: almosteq(n(jacobi_ns(-4, 0, hold=True)), n(jacobi_ns(-4, 0))) + sage: almosteq(n(jacobi_ns(-4, 0, hold=True)), n(jacobi_ns(-4, 0))) # optional - mpmath True - sage: almosteq(n(jacobi_ns(-2, 1, hold=True)), n(jacobi_ns(-2, 1))) + sage: almosteq(n(jacobi_ns(-2, 1, hold=True)), n(jacobi_ns(-2, 1))) # optional - mpmath True - sage: almosteq(n(jacobi_nc(2, 0, hold=True)), n(jacobi_nc(2, 0))) + sage: almosteq(n(jacobi_nc(2, 0, hold=True)), n(jacobi_nc(2, 0))) # optional - mpmath True - sage: almosteq(n(jacobi_nc(1, 1, hold=True)), n(jacobi_nc(1, 1))) + sage: almosteq(n(jacobi_nc(1, 1, hold=True)), n(jacobi_nc(1, 1))) # optional - mpmath True - sage: almosteq(n(jacobi_nc(0, 0, hold=True)), n(jacobi_nc(0, 0))) + sage: almosteq(n(jacobi_nc(0, 0, hold=True)), n(jacobi_nc(0, 0))) # optional - mpmath True - sage: almosteq(n(jacobi_dn(-10, 0, hold=True)), n(jacobi_dn(-10, 0))) + sage: almosteq(n(jacobi_dn(-10, 0, hold=True)), n(jacobi_dn(-10, 0))) # optional - mpmath True - sage: almosteq(n(jacobi_dn(-1, 1, hold=True)), n(jacobi_dn(-1, 1))) + sage: almosteq(n(jacobi_dn(-1, 1, hold=True)), n(jacobi_dn(-1, 1))) # optional - mpmath True - sage: almosteq(n(jacobi_dn(0, 3, hold=True)), n(jacobi_dn(0, 3))) + sage: almosteq(n(jacobi_dn(0, 3, hold=True)), n(jacobi_dn(0, 3))) # optional - mpmath True - sage: almosteq(n(jacobi_ds(2, 0, hold=True)), n(jacobi_ds(2, 0))) + sage: almosteq(n(jacobi_ds(2, 0, hold=True)), n(jacobi_ds(2, 0))) # optional - mpmath True - sage: almosteq(n(jacobi_dc(-1, 0, hold=True)), n(jacobi_dc(-1, 0))) + sage: almosteq(n(jacobi_dc(-1, 0, hold=True)), n(jacobi_dc(-1, 0))) # optional - mpmath True - sage: almosteq(n(jacobi_dc(-8, 1, hold=True)), n(jacobi_dc(-8, 1))) + sage: almosteq(n(jacobi_dc(-8, 1, hold=True)), n(jacobi_dc(-8, 1))) # optional - mpmath True - sage: almosteq(n(jacobi_dc(0, -10, hold=True)), n(jacobi_dc(0, -10))) + sage: almosteq(n(jacobi_dc(0, -10, hold=True)), n(jacobi_dc(0, -10))) # optional - mpmath True - sage: almosteq(n(jacobi_sn(-7, 0, hold=True)), n(jacobi_sn(-7, 0))) + sage: almosteq(n(jacobi_sn(-7, 0, hold=True)), n(jacobi_sn(-7, 0))) # optional - mpmath True - sage: almosteq(n(jacobi_sn(-3, 1, hold=True)), n(jacobi_sn(-3, 1))) + sage: almosteq(n(jacobi_sn(-3, 1, hold=True)), n(jacobi_sn(-3, 1))) # optional - mpmath True - sage: almosteq(n(jacobi_sn(0, -6, hold=True)), n(jacobi_sn(0, -6))) + sage: almosteq(n(jacobi_sn(0, -6, hold=True)), n(jacobi_sn(0, -6))) # optional - mpmath True - sage: almosteq(n(jacobi_sd(4, 0, hold=True)), n(jacobi_sd(4, 0))) + sage: almosteq(n(jacobi_sd(4, 0, hold=True)), n(jacobi_sd(4, 0))) # optional - mpmath True - sage: almosteq(n(jacobi_sd(0, 1, hold=True)), n(jacobi_sd(0, 1))) + sage: almosteq(n(jacobi_sd(0, 1, hold=True)), n(jacobi_sd(0, 1))) # optional - mpmath True - sage: almosteq(n(jacobi_sd(0, 3, hold=True)), n(jacobi_sd(0, 3))) + sage: almosteq(n(jacobi_sd(0, 3, hold=True)), n(jacobi_sd(0, 3))) # optional - mpmath True - sage: almosteq(n(jacobi_sc(-9, 0, hold=True)), n(jacobi_sc(-9, 0))) + sage: almosteq(n(jacobi_sc(-9, 0, hold=True)), n(jacobi_sc(-9, 0))) # optional - mpmath True - sage: almosteq(n(jacobi_sc(0, 1, hold=True)), n(jacobi_sc(0, 1))) + sage: almosteq(n(jacobi_sc(0, 1, hold=True)), n(jacobi_sc(0, 1))) # optional - mpmath True - sage: almosteq(n(jacobi_sc(0, -10, hold=True)), n(jacobi_sc(0, -10))) + sage: almosteq(n(jacobi_sc(0, -10, hold=True)), n(jacobi_sc(0, -10))) # optional - mpmath True - sage: almosteq(n(jacobi_cn(-2, 0, hold=True)), n(jacobi_cn(-2, 0))) + sage: almosteq(n(jacobi_cn(-2, 0, hold=True)), n(jacobi_cn(-2, 0))) # optional - mpmath True - sage: almosteq(n(jacobi_cn(6, 1, hold=True)), n(jacobi_cn(6, 1))) + sage: almosteq(n(jacobi_cn(6, 1, hold=True)), n(jacobi_cn(6, 1))) # optional - mpmath True - sage: almosteq(n(jacobi_cn(0, -10, hold=True)), n(jacobi_cn(0, -10))) + sage: almosteq(n(jacobi_cn(0, -10, hold=True)), n(jacobi_cn(0, -10))) # optional - mpmath True - sage: almosteq(n(jacobi_cd(9, 0, hold=True)), n(jacobi_cd(9, 0))) + sage: almosteq(n(jacobi_cd(9, 0, hold=True)), n(jacobi_cd(9, 0))) # optional - mpmath True - sage: almosteq(n(jacobi_cd(-8, 1, hold=True)), n(jacobi_cd(-8, 1))) + sage: almosteq(n(jacobi_cd(-8, 1, hold=True)), n(jacobi_cd(-8, 1))) # optional - mpmath True - sage: almosteq(n(jacobi_cd(0, 1, hold=True)), n(jacobi_cd(0, 1))) + sage: almosteq(n(jacobi_cd(0, 1, hold=True)), n(jacobi_cd(0, 1))) # optional - mpmath True - sage: almosteq(n(jacobi_cs(-9, 0, hold=True)), n(jacobi_cs(-9, 0))) + sage: almosteq(n(jacobi_cs(-9, 0, hold=True)), n(jacobi_cs(-9, 0))) # optional - mpmath True - sage: almosteq(n(jacobi_cs(-6, 1, hold=True)), n(jacobi_cs(-6, 1))) + sage: almosteq(n(jacobi_cs(-6, 1, hold=True)), n(jacobi_cs(-6, 1))) # optional - mpmath True """ if self.kind == 'nd': @@ -371,16 +371,16 @@ def _derivative_(self, x, m, diff_param): sn, cn, and dn are analytic for all real ``x``, so we can check that the derivatives are correct by computing the series:: - sage: from mpmath import almosteq + sage: from mpmath import almosteq # optional - mpmath sage: a = 0.9327542442482303 sage: b = 0.7402326293643771 - sage: almosteq(jacobi_sn(x, b).series(x, 10).subs(x=a), + sage: almosteq(jacobi_sn(x, b).series(x, 10).subs(x=a), # optional - mpmath ....: jacobi_sn(a, b), abs_eps=0.01) True - sage: almosteq(jacobi_cn(x, b).series(x, 10).subs(x=a), + sage: almosteq(jacobi_cn(x, b).series(x, 10).subs(x=a), # optional - mpmath ....: jacobi_cn(a, b), abs_eps=0.01) True - sage: almosteq(jacobi_dn(x, b).series(x, 10).subs(x=a), + sage: almosteq(jacobi_dn(x, b).series(x, 10).subs(x=a), # optional - mpmath ....: jacobi_dn(a, b), abs_eps=0.01) True """ @@ -560,77 +560,77 @@ def _eval_(self, x, m): Check that the simplifications are correct:: - sage: from mpmath import almosteq - sage: almosteq(n(inverse_jacobi_cd(1, -8, hold=True)), + sage: from mpmath import almosteq # optional - mpmath + sage: almosteq(n(inverse_jacobi_cd(1, -8, hold=True)), # optional - mpmath ....: n(inverse_jacobi_cd(1, -8))) True - sage: almosteq(n(inverse_jacobi_cn(0, -5, hold=True)), + sage: almosteq(n(inverse_jacobi_cn(0, -5, hold=True)), # optional - mpmath ....: n(inverse_jacobi_cn(0, -5))) True - sage: almosteq(n(inverse_jacobi_cn(1, -8, hold=True)), + sage: almosteq(n(inverse_jacobi_cn(1, -8, hold=True)), # optional - mpmath ....: n(inverse_jacobi_cn(1, -8))) True - sage: almosteq(n(inverse_jacobi_cs(7, 1, hold=True)), + sage: almosteq(n(inverse_jacobi_cs(7, 1, hold=True)), # optional - mpmath ....: n(inverse_jacobi_cs(7, 1))) True - sage: almosteq(n(inverse_jacobi_dc(3, 0, hold=True)), + sage: almosteq(n(inverse_jacobi_dc(3, 0, hold=True)), # optional - mpmath ....: n(inverse_jacobi_dc(3, 0))) True - sage: almosteq(n(inverse_jacobi_dc(1, 7, hold=True)), + sage: almosteq(n(inverse_jacobi_dc(1, 7, hold=True)), # optional - mpmath ....: n(inverse_jacobi_dc(1, 7))) True - sage: almosteq(n(inverse_jacobi_dn(1, -1, hold=True)), + sage: almosteq(n(inverse_jacobi_dn(1, -1, hold=True)), # optional - mpmath ....: n(inverse_jacobi_dn(1, -1))) True - sage: almosteq(n(inverse_jacobi_ds(7, 0, hold=True)), + sage: almosteq(n(inverse_jacobi_ds(7, 0, hold=True)), # optional - mpmath ....: n(inverse_jacobi_ds(7, 0))) True - sage: almosteq(n(inverse_jacobi_ds(5, 1, hold=True)), + sage: almosteq(n(inverse_jacobi_ds(5, 1, hold=True)), # optional - mpmath ....: n(inverse_jacobi_ds(5, 1))) True - sage: almosteq(n(inverse_jacobi_nc(-2, 0, hold=True)), + sage: almosteq(n(inverse_jacobi_nc(-2, 0, hold=True)), # optional - mpmath ....: n(inverse_jacobi_nc(-2, 0))) True - sage: almosteq(n(inverse_jacobi_nc(-1, 1, hold=True)), + sage: almosteq(n(inverse_jacobi_nc(-1, 1, hold=True)), # optional - mpmath ....: n(inverse_jacobi_nc(-1, 1))) True - sage: almosteq(n(inverse_jacobi_nc(1, 4, hold=True)), + sage: almosteq(n(inverse_jacobi_nc(1, 4, hold=True)), # optional - mpmath ....: n(inverse_jacobi_nc(1, 4))) True - sage: almosteq(n(inverse_jacobi_nd(9, 1, hold=True)), + sage: almosteq(n(inverse_jacobi_nd(9, 1, hold=True)), # optional - mpmath ....: n(inverse_jacobi_nd(9, 1))) True - sage: almosteq(n(inverse_jacobi_nd(1, -9, hold=True)), + sage: almosteq(n(inverse_jacobi_nd(1, -9, hold=True)), # optional - mpmath ....: n(inverse_jacobi_nd(1, -9))) True - sage: almosteq(n(inverse_jacobi_ns(-6, 0, hold=True)), + sage: almosteq(n(inverse_jacobi_ns(-6, 0, hold=True)), # optional - mpmath ....: n(inverse_jacobi_ns(-6, 0))) True - sage: almosteq(n(inverse_jacobi_ns(6, 1, hold=True)), + sage: almosteq(n(inverse_jacobi_ns(6, 1, hold=True)), # optional - mpmath ....: n(inverse_jacobi_ns(6, 1))) True - sage: almosteq(n(inverse_jacobi_sc(9, 0, hold=True)), + sage: almosteq(n(inverse_jacobi_sc(9, 0, hold=True)), # optional - mpmath ....: n(inverse_jacobi_sc(9, 0))) True - sage: almosteq(n(inverse_jacobi_sc(8, 1, hold=True)), + sage: almosteq(n(inverse_jacobi_sc(8, 1, hold=True)), # optional - mpmath ....: n(inverse_jacobi_sc(8, 1))) True - sage: almosteq(n(inverse_jacobi_sc(0, -8, hold=True)), + sage: almosteq(n(inverse_jacobi_sc(0, -8, hold=True)), # optional - mpmath ....: n(inverse_jacobi_sc(0, -8))) True - sage: almosteq(n(inverse_jacobi_sd(-1, 0, hold=True)), + sage: almosteq(n(inverse_jacobi_sd(-1, 0, hold=True)), # optional - mpmath ....: n(inverse_jacobi_sd(-1, 0))) True - sage: almosteq(n(inverse_jacobi_sd(-2, 1, hold=True)), + sage: almosteq(n(inverse_jacobi_sd(-2, 1, hold=True)), # optional - mpmath ....: n(inverse_jacobi_sd(-2, 1))) True - sage: almosteq(n(inverse_jacobi_sd(0, -2, hold=True)), + sage: almosteq(n(inverse_jacobi_sd(0, -2, hold=True)), # optional - mpmath ....: n(inverse_jacobi_sd(0, -2))) True - sage: almosteq(n(inverse_jacobi_sn(0, 0, hold=True)), + sage: almosteq(n(inverse_jacobi_sn(0, 0, hold=True)), # optional - mpmath ....: n(inverse_jacobi_sn(0, 0))) True - sage: almosteq(n(inverse_jacobi_sn(0, 6, hold=True)), + sage: almosteq(n(inverse_jacobi_sn(0, 6, hold=True)), # optional - mpmath ....: n(inverse_jacobi_sn(0, 6))) True """ @@ -726,55 +726,55 @@ def _derivative_(self, x, m, diff_param): Check that ``dy/dx * dx/dy == 1``, where ``y = jacobi_pq(x, m)`` and ``x = inverse_jacobi_pq(y, m)``:: - sage: from mpmath import almosteq + sage: from mpmath import almosteq # optional - mpmath sage: a = 0.130103220857094 sage: b = 0.437176765041986 sage: m = var('m') - sage: almosteq(abs((diff(jacobi_cd(x, m), x) * + sage: almosteq(abs((diff(jacobi_cd(x, m), x) * # optional - mpmath ....: diff(inverse_jacobi_cd(x, m), x).subs(x=jacobi_cd(x, m))).subs(x=a, m=b)), ....: 1, abs_eps=1e-14) True - sage: almosteq(abs((diff(jacobi_cn(x, m), x) * + sage: almosteq(abs((diff(jacobi_cn(x, m), x) * # optional - mpmath ....: diff(inverse_jacobi_cn(x, m), x).subs(x=jacobi_cn(x, m))).subs(x=a, m=b)), ....: 1, abs_eps=1e-14) True - sage: almosteq(abs((diff(jacobi_cs(x, m), x) * + sage: almosteq(abs((diff(jacobi_cs(x, m), x) * # optional - mpmath ....: diff(inverse_jacobi_cs(x, m), x).subs(x=jacobi_cs(x, m))).subs(x=a, m=b)), ....: 1, abs_eps=1e-14) True - sage: almosteq(abs((diff(jacobi_dc(x, m), x) * + sage: almosteq(abs((diff(jacobi_dc(x, m), x) * # optional - mpmath ....: diff(inverse_jacobi_dc(x, m), x).subs(x=jacobi_dc(x, m))).subs(x=a, m=b)), ....: 1, abs_eps=1e-14) True - sage: almosteq(abs((diff(jacobi_dn(x, m), x) * + sage: almosteq(abs((diff(jacobi_dn(x, m), x) * # optional - mpmath ....: diff(inverse_jacobi_dn(x, m), x).subs(x=jacobi_dn(x, m))).subs(x=a, m=b)), ....: 1, abs_eps=1e-14) True - sage: almosteq(abs((diff(jacobi_ds(x, m), x) * + sage: almosteq(abs((diff(jacobi_ds(x, m), x) * # optional - mpmath ....: diff(inverse_jacobi_ds(x, m), x).subs(x=jacobi_ds(x, m))).subs(x=a, m=b)), ....: 1, abs_eps=1e-14) True - sage: almosteq(abs((diff(jacobi_nc(x, m), x) * + sage: almosteq(abs((diff(jacobi_nc(x, m), x) * # optional - mpmath ....: diff(inverse_jacobi_nc(x, m), x).subs(x=jacobi_nc(x, m))).subs(x=a, m=b)), ....: 1, abs_eps=1e-14) True - sage: almosteq(abs((diff(jacobi_nd(x, m), x) * + sage: almosteq(abs((diff(jacobi_nd(x, m), x) * # optional - mpmath ....: diff(inverse_jacobi_nd(x, m), x).subs(x=jacobi_nd(x, m))).subs(x=a, m=b)), ....: 1, abs_eps=1e-14) True - sage: almosteq(abs((diff(jacobi_ns(x, m), x) * + sage: almosteq(abs((diff(jacobi_ns(x, m), x) * # optional - mpmath ....: diff(inverse_jacobi_ns(x, m), x).subs(x=jacobi_ns(x, m))).subs(x=a, m=b)), ....: 1, abs_eps=1e-14) True - sage: almosteq(abs((diff(jacobi_sc(x, m), x) * + sage: almosteq(abs((diff(jacobi_sc(x, m), x) * # optional - mpmath ....: diff(inverse_jacobi_sc(x, m), x).subs(x=jacobi_sc(x, m))).subs(x=a, m=b)), ....: 1, abs_eps=1e-14) True - sage: almosteq(abs((diff(jacobi_sd(x, m), x) * + sage: almosteq(abs((diff(jacobi_sd(x, m), x) * # optional - mpmath ....: diff(inverse_jacobi_sd(x, m), x).subs(x=jacobi_sd(x, m))).subs(x=a, m=b)), ....: 1, abs_eps=1e-14) True - sage: almosteq(abs((diff(jacobi_sn(x, m), x) * + sage: almosteq(abs((diff(jacobi_sn(x, m), x) * # optional - mpmath ....: diff(inverse_jacobi_sn(x, m), x).subs(x=jacobi_sn(x, m))).subs(x=a, m=b)), ....: 1, abs_eps=1e-14) True @@ -1143,129 +1143,129 @@ def inverse_jacobi_f(kind, x, m): TESTS:: - sage: from mpmath import ellipfun, chop + sage: from mpmath import ellipfun, chop # optional - mpmath sage: from sage.functions.jacobi import inverse_jacobi_f - sage: chop(ellipfun('sn', inverse_jacobi_f('sn', 0.6, 0), 0)) + sage: chop(ellipfun('sn', inverse_jacobi_f('sn', 0.6, 0), 0)) # optional - mpmath mpf('0.59999999999999998') - sage: chop(ellipfun('sn', inverse_jacobi_f('sn', 0.6, 1), 1)) + sage: chop(ellipfun('sn', inverse_jacobi_f('sn', 0.6, 1), 1)) # optional - mpmath mpf('0.59999999999999998') - sage: chop(ellipfun('sn', inverse_jacobi_f('sn', 0, -3), -3)) + sage: chop(ellipfun('sn', inverse_jacobi_f('sn', 0, -3), -3)) # optional - mpmath mpf('0.0') - sage: chop(ellipfun('sn', inverse_jacobi_f('sn', -1, 4), 4)) + sage: chop(ellipfun('sn', inverse_jacobi_f('sn', -1, 4), 4)) # optional - mpmath mpf('-1.0') - sage: chop(ellipfun('sn', inverse_jacobi_f('sn', 0.3, 4), 4)) + sage: chop(ellipfun('sn', inverse_jacobi_f('sn', 0.3, 4), 4)) # optional - mpmath mpf('0.29999999999999999') - sage: chop(ellipfun('sn', inverse_jacobi_f('sn', 0.8, 4), 4)) + sage: chop(ellipfun('sn', inverse_jacobi_f('sn', 0.8, 4), 4)) # optional - mpmath mpf('0.80000000000000004') - sage: chop(ellipfun('ns', inverse_jacobi_f('ns', 0.8, 0), 0)) + sage: chop(ellipfun('ns', inverse_jacobi_f('ns', 0.8, 0), 0)) # optional - mpmath mpf('0.80000000000000004') - sage: chop(ellipfun('ns', inverse_jacobi_f('ns', -0.7, 1), 1)) + sage: chop(ellipfun('ns', inverse_jacobi_f('ns', -0.7, 1), 1)) # optional - mpmath mpf('-0.69999999999999996') - sage: chop(ellipfun('ns', inverse_jacobi_f('ns', 0.01, 2), 2)) + sage: chop(ellipfun('ns', inverse_jacobi_f('ns', 0.01, 2), 2)) # optional - mpmath mpf('0.01') - sage: chop(ellipfun('ns', inverse_jacobi_f('ns', 0, 2), 2)) + sage: chop(ellipfun('ns', inverse_jacobi_f('ns', 0, 2), 2)) # optional - mpmath mpf('0.0') - sage: chop(ellipfun('ns', inverse_jacobi_f('ns', -10, 6), 6)) + sage: chop(ellipfun('ns', inverse_jacobi_f('ns', -10, 6), 6)) # optional - mpmath mpf('-10.0') - sage: chop(ellipfun('cn', inverse_jacobi_f('cn', -10, 0), 0)) + sage: chop(ellipfun('cn', inverse_jacobi_f('cn', -10, 0), 0)) # optional - mpmath mpf('-9.9999999999999982') - sage: chop(ellipfun('cn', inverse_jacobi_f('cn', 50, 1), 1)) + sage: chop(ellipfun('cn', inverse_jacobi_f('cn', 50, 1), 1)) # optional - mpmath mpf('50.000000000000071') - sage: chop(ellipfun('cn', inverse_jacobi_f('cn', 1, 5), 5)) + sage: chop(ellipfun('cn', inverse_jacobi_f('cn', 1, 5), 5)) # optional - mpmath mpf('1.0') - sage: chop(ellipfun('cn', inverse_jacobi_f('cn', 0.5, -5), -5)) + sage: chop(ellipfun('cn', inverse_jacobi_f('cn', 0.5, -5), -5)) # optional - mpmath mpf('0.5') - sage: chop(ellipfun('cn', inverse_jacobi_f('cn', -0.75, -15), -15)) + sage: chop(ellipfun('cn', inverse_jacobi_f('cn', -0.75, -15), -15)) # optional - mpmath mpf('-0.75000000000000022') - sage: chop(ellipfun('cn', inverse_jacobi_f('cn', 10, 0.8), 0.8)) + sage: chop(ellipfun('cn', inverse_jacobi_f('cn', 10, 0.8), 0.8)) # optional - mpmath mpf('9.9999999999999982') - sage: chop(ellipfun('cn', inverse_jacobi_f('cn', -2, 0.9), 0.9)) + sage: chop(ellipfun('cn', inverse_jacobi_f('cn', -2, 0.9), 0.9)) # optional - mpmath mpf('-2.0') - sage: chop(ellipfun('nc', inverse_jacobi_f('nc', -4, 0), 0)) + sage: chop(ellipfun('nc', inverse_jacobi_f('nc', -4, 0), 0)) # optional - mpmath mpf('-3.9999999999999987') - sage: chop(ellipfun('nc', inverse_jacobi_f('nc', 7, 1), 1)) + sage: chop(ellipfun('nc', inverse_jacobi_f('nc', 7, 1), 1)) # optional - mpmath mpf('7.0000000000000009') - sage: chop(ellipfun('nc', inverse_jacobi_f('nc', 7, 3), 3)) + sage: chop(ellipfun('nc', inverse_jacobi_f('nc', 7, 3), 3)) # optional - mpmath mpf('7.0') - sage: chop(ellipfun('nc', inverse_jacobi_f('nc', 0, 2), 2)) + sage: chop(ellipfun('nc', inverse_jacobi_f('nc', 0, 2), 2)) # optional - mpmath mpf('0.0') - sage: chop(ellipfun('nc', inverse_jacobi_f('nc', -18, -4), -4)) + sage: chop(ellipfun('nc', inverse_jacobi_f('nc', -18, -4), -4)) # optional - mpmath mpf('-17.999999999999925') - sage: chop(ellipfun('dn', inverse_jacobi_f('dn', -0.3, 1), 1)) + sage: chop(ellipfun('dn', inverse_jacobi_f('dn', -0.3, 1), 1)) # optional - mpmath mpf('-0.29999999999999999') - sage: chop(ellipfun('dn', inverse_jacobi_f('dn', 1, -1), -1)) + sage: chop(ellipfun('dn', inverse_jacobi_f('dn', 1, -1), -1)) # optional - mpmath mpf('1.0') - sage: chop(ellipfun('dn', inverse_jacobi_f('dn', 0.8, 0.5), 0.5)) + sage: chop(ellipfun('dn', inverse_jacobi_f('dn', 0.8, 0.5), 0.5)) # optional - mpmath mpf('0.80000000000000004') - sage: chop(ellipfun('dn', inverse_jacobi_f('dn', 5, -4), -4)) + sage: chop(ellipfun('dn', inverse_jacobi_f('dn', 5, -4), -4)) # optional - mpmath mpf('5.0') - sage: chop(ellipfun('dn', inverse_jacobi_f('dn', 0.4, 0.5), 0.5)) + sage: chop(ellipfun('dn', inverse_jacobi_f('dn', 0.4, 0.5), 0.5)) # optional - mpmath mpf('0.40000000000000002') - sage: chop(ellipfun('dn', inverse_jacobi_f('dn', -0.4, 0.5), 0.5)) + sage: chop(ellipfun('dn', inverse_jacobi_f('dn', -0.4, 0.5), 0.5)) # optional - mpmath mpf('-0.40000000000000002') - sage: chop(ellipfun('dn', inverse_jacobi_f('dn', -0.9, 0.5), 0.5)) + sage: chop(ellipfun('dn', inverse_jacobi_f('dn', -0.9, 0.5), 0.5)) # optional - mpmath mpf('-0.90000000000000002') - sage: chop(ellipfun('dn', inverse_jacobi_f('dn', -1.9, 0.2), 0.2)) + sage: chop(ellipfun('dn', inverse_jacobi_f('dn', -1.9, 0.2), 0.2)) # optional - mpmath mpf('-1.8999999999999999') - sage: chop(ellipfun('nd', inverse_jacobi_f('nd', -1.9, 1), 1)) + sage: chop(ellipfun('nd', inverse_jacobi_f('nd', -1.9, 1), 1)) # optional - mpmath mpf('-1.8999999999999999') - sage: chop(ellipfun('nd', inverse_jacobi_f('nd', 1, -1), -1)) + sage: chop(ellipfun('nd', inverse_jacobi_f('nd', 1, -1), -1)) # optional - mpmath mpf('1.0') - sage: chop(ellipfun('nd', inverse_jacobi_f('nd', 11, -6), -6)) + sage: chop(ellipfun('nd', inverse_jacobi_f('nd', 11, -6), -6)) # optional - mpmath mpf('11.0') - sage: chop(ellipfun('nd', inverse_jacobi_f('nd', 0, 8), 8)) + sage: chop(ellipfun('nd', inverse_jacobi_f('nd', 0, 8), 8)) # optional - mpmath mpf('0.0') - sage: chop(ellipfun('nd', inverse_jacobi_f('nd', -3, 0.8), 0.8)) + sage: chop(ellipfun('nd', inverse_jacobi_f('nd', -3, 0.8), 0.8)) # optional - mpmath mpf('-2.9999999999999996') - sage: chop(ellipfun('sc', inverse_jacobi_f('sc', -3, 0), 0)) + sage: chop(ellipfun('sc', inverse_jacobi_f('sc', -3, 0), 0)) # optional - mpmath mpf('-3.0') - sage: chop(ellipfun('sc', inverse_jacobi_f('sc', 2, 1), 1)) + sage: chop(ellipfun('sc', inverse_jacobi_f('sc', 2, 1), 1)) # optional - mpmath mpf('2.0') - sage: chop(ellipfun('sc', inverse_jacobi_f('sc', 0, 9), 9)) + sage: chop(ellipfun('sc', inverse_jacobi_f('sc', 0, 9), 9)) # optional - mpmath mpf('0.0') - sage: chop(ellipfun('sc', inverse_jacobi_f('sc', -7, 3), 3)) + sage: chop(ellipfun('sc', inverse_jacobi_f('sc', -7, 3), 3)) # optional - mpmath mpf('-7.0') - sage: chop(ellipfun('cs', inverse_jacobi_f('cs', -7, 0), 0)) + sage: chop(ellipfun('cs', inverse_jacobi_f('cs', -7, 0), 0)) # optional - mpmath mpf('-6.9999999999999991') - sage: chop(ellipfun('cs', inverse_jacobi_f('cs', 8, 1), 1)) + sage: chop(ellipfun('cs', inverse_jacobi_f('cs', 8, 1), 1)) # optional - mpmath mpf('8.0') - sage: chop(ellipfun('cs', inverse_jacobi_f('cs', 2, 6), 6)) + sage: chop(ellipfun('cs', inverse_jacobi_f('cs', 2, 6), 6)) # optional - mpmath mpf('2.0') - sage: chop(ellipfun('cs', inverse_jacobi_f('cs', 0, 4), 4)) + sage: chop(ellipfun('cs', inverse_jacobi_f('cs', 0, 4), 4)) # optional - mpmath mpf('0.0') - sage: chop(ellipfun('cs', inverse_jacobi_f('cs', -6, 8), 8)) + sage: chop(ellipfun('cs', inverse_jacobi_f('cs', -6, 8), 8)) # optional - mpmath mpf('-6.0000000000000018') - sage: chop(ellipfun('cd', inverse_jacobi_f('cd', -6, 0), 0)) + sage: chop(ellipfun('cd', inverse_jacobi_f('cd', -6, 0), 0)) # optional - mpmath mpf('-6.0000000000000009') - sage: chop(ellipfun('cd', inverse_jacobi_f('cd', 1, 3), 3)) + sage: chop(ellipfun('cd', inverse_jacobi_f('cd', 1, 3), 3)) # optional - mpmath mpf('1.0') - sage: chop(ellipfun('cd', inverse_jacobi_f('cd', 6, 8), 8)) + sage: chop(ellipfun('cd', inverse_jacobi_f('cd', 6, 8), 8)) # optional - mpmath mpf('6.0000000000000027') - sage: chop(ellipfun('dc', inverse_jacobi_f('dc', 5, 0), 0)) + sage: chop(ellipfun('dc', inverse_jacobi_f('dc', 5, 0), 0)) # optional - mpmath mpf('5.0000000000000018') - sage: chop(ellipfun('dc', inverse_jacobi_f('dc', -4, 2), 2)) + sage: chop(ellipfun('dc', inverse_jacobi_f('dc', -4, 2), 2)) # optional - mpmath mpf('-4.0000000000000018') - sage: chop(ellipfun('sd', inverse_jacobi_f('sd', -4, 0), 0)) + sage: chop(ellipfun('sd', inverse_jacobi_f('sd', -4, 0), 0)) # optional - mpmath mpf('-3.9999999999999991') - sage: chop(ellipfun('sd', inverse_jacobi_f('sd', 7, 1), 1)) + sage: chop(ellipfun('sd', inverse_jacobi_f('sd', 7, 1), 1)) # optional - mpmath mpf('7.0') - sage: chop(ellipfun('sd', inverse_jacobi_f('sd', 0, 9), 9)) + sage: chop(ellipfun('sd', inverse_jacobi_f('sd', 0, 9), 9)) # optional - mpmath mpf('0.0') - sage: chop(ellipfun('sd', inverse_jacobi_f('sd', 8, 0.8), 0.8)) + sage: chop(ellipfun('sd', inverse_jacobi_f('sd', 8, 0.8), 0.8)) # optional - mpmath mpf('7.9999999999999991') - sage: chop(ellipfun('ds', inverse_jacobi_f('ds', 4, 0.25), 0.25)) + sage: chop(ellipfun('ds', inverse_jacobi_f('ds', 4, 0.25), 0.25)) # optional - mpmath mpf('4.0') """ from mpmath import mp @@ -1611,19 +1611,19 @@ def jacobi_am_f(x, m): TESTS:: - sage: from mpmath import ellipf + sage: from mpmath import ellipf # optional - mpmath sage: from sage.functions.jacobi import jacobi_am_f - sage: ellipf(jacobi_am_f(0.5, 1), 1) + sage: ellipf(jacobi_am_f(0.5, 1), 1) # optional - mpmath mpf('0.5') - sage: ellipf(jacobi_am(3, 0.3), 0.3) + sage: ellipf(jacobi_am(3, 0.3), 0.3) # optional - mpmath mpf('3.0') - sage: ellipf(jacobi_am_f(2, -0.5), -0.5) + sage: ellipf(jacobi_am_f(2, -0.5), -0.5) # optional - mpmath mpf('2.0') - sage: jacobi_am_f(2, -0.5) + sage: jacobi_am_f(2, -0.5) # optional - mpmath mpf('2.2680930777934176') - sage: jacobi_am_f(-2, -0.5) + sage: jacobi_am_f(-2, -0.5) # optional - mpmath mpf('-2.2680930777934176') - sage: jacobi_am_f(-3, 2) + sage: jacobi_am_f(-3, 2) # optional - mpmath mpf('0.36067407399586108') """ from mpmath import mp diff --git a/src/sage/functions/orthogonal_polys.py b/src/sage/functions/orthogonal_polys.py index 7398c763971..9f5f1cc51fc 100644 --- a/src/sage/functions/orthogonal_polys.py +++ b/src/sage/functions/orthogonal_polys.py @@ -898,18 +898,18 @@ def _eval_numpy_(self, n, x): EXAMPLES:: - sage: import numpy - sage: z = numpy.array([1,2]) - sage: z2 = numpy.array([[1,2],[1,2]]) - sage: z3 = numpy.array([1,2,3.]) - sage: chebyshev_T(1,z) + sage: import numpy # optional - numpy + sage: z = numpy.array([1,2]) # optional - numpy + sage: z2 = numpy.array([[1,2],[1,2]]) # optional - numpy + sage: z3 = numpy.array([1,2,3.]) # optional - numpy + sage: chebyshev_T(1,z) # optional - numpy array([1., 2.]) - sage: chebyshev_T(1,z2) + sage: chebyshev_T(1,z2) # optional - numpy array([[1., 2.], [1., 2.]]) - sage: chebyshev_T(1,z3) + sage: chebyshev_T(1,z3) # optional - numpy array([1., 2., 3.]) - sage: chebyshev_T(z,0.1) + sage: chebyshev_T(z,0.1) # optional - numpy array([ 0.1 , -0.98]) """ from scipy.special import eval_chebyt @@ -1185,18 +1185,18 @@ def _eval_numpy_(self, n, x): EXAMPLES:: - sage: import numpy - sage: z = numpy.array([1,2]) - sage: z2 = numpy.array([[1,2],[1,2]]) - sage: z3 = numpy.array([1,2,3.]) - sage: chebyshev_U(1,z) + sage: import numpy # optional - numpy + sage: z = numpy.array([1,2]) # optional - numpy + sage: z2 = numpy.array([[1,2],[1,2]]) # optional - numpy + sage: z3 = numpy.array([1,2,3.]) # optional - numpy + sage: chebyshev_U(1,z) # optional - numpy array([2., 4.]) - sage: chebyshev_U(1,z2) + sage: chebyshev_U(1,z2) # optional - numpy array([[2., 4.], [2., 4.]]) - sage: chebyshev_U(1,z3) + sage: chebyshev_U(1,z3) # optional - numpy array([2., 4., 6.]) - sage: chebyshev_U(z,0.1) + sage: chebyshev_U(z,0.1) # optional - numpy array([ 0.2 , -0.96]) """ from scipy.special import eval_chebyu @@ -2297,12 +2297,12 @@ class Func_ultraspherical(GinacFunction): Numerical evaluation with the mpmath library:: - sage: from mpmath import gegenbauer as gegenbauer_mp - sage: from mpmath import mp - sage: mp.pretty = True; mp.dps=25 - sage: gegenbauer_mp(-7,0.5,0.3) + sage: from mpmath import gegenbauer as gegenbauer_mp # optional - mpmath + sage: from mpmath import mp # optional - mpmath + sage: mp.pretty = True; mp.dps=25 # optional - mpmath + sage: gegenbauer_mp(-7,0.5,0.3) # optional - mpmath 0.1291811875 - sage: gegenbauer_mp(2+3j, -0.75, -1000j) + sage: gegenbauer_mp(2+3j, -0.75, -1000j) # optional - mpmath (-5038991.358609026523401901 + 9414549.285447104177860806j) TESTS: diff --git a/src/sage/functions/other.py b/src/sage/functions/other.py index 3e2570e889e..925bfa24abb 100644 --- a/src/sage/functions/other.py +++ b/src/sage/functions/other.py @@ -381,14 +381,14 @@ def __init__(self): sage: latex(ceil(x)) \left \lceil x \right \rceil - sage: ceil(x)._sympy_() + sage: ceil(x)._sympy_() # optional - sympy ceiling(x) :: - sage: import numpy - sage: a = numpy.linspace(0,2,6) - sage: ceil(a) + sage: import numpy # optional - numpy + sage: a = numpy.linspace(0,2,6) # optional - numpy + sage: ceil(a) # optional - numpy array([0., 1., 1., 2., 2., 2.]) Test pickling:: @@ -550,11 +550,11 @@ def __init__(self): :: - sage: import numpy - sage: a = numpy.linspace(0,2,6) - sage: floor(a) + sage: import numpy # optional - numpy + sage: a = numpy.linspace(0,2,6) # optional - numpy + sage: floor(a) # optional - numpy array([0., 0., 0., 1., 1., 2.]) - sage: floor(x)._sympy_() + sage: floor(x)._sympy_() # optional - sympy floor(x) Test pickling:: diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index faa6a73cc7e..df5d77660b8 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -191,10 +191,10 @@ class SphericalHarmonic(BuiltinFunction): sage: spherical_harmonic(1, 1, x, y) -1/4*sqrt(3)*sqrt(2)*e^(I*y)*sin(x)/sqrt(pi) - sage: from sympy import Ynm - sage: Ynm(1, 1, x, y).expand(func=True) + sage: from sympy import Ynm # optional - sympy + sage: Ynm(1, 1, x, y).expand(func=True) # optional - sympy -sqrt(6)*exp(I*y)*sin(x)/(4*sqrt(pi)) - sage: spherical_harmonic(1, 1, x, y) - Ynm(1, 1, x, y) + sage: spherical_harmonic(1, 1, x, y) - Ynm(1, 1, x, y) # optional - sympy 0 It also agrees with SciPy's spherical harmonics:: diff --git a/src/sage/functions/transcendental.py b/src/sage/functions/transcendental.py index 2511d47f13e..b7fdb331a7b 100644 --- a/src/sage/functions/transcendental.py +++ b/src/sage/functions/transcendental.py @@ -348,7 +348,7 @@ def __init__(self): zetaderiv(n, x) sage: zetaderiv(1, 4).n() -0.0689112658961254 - sage: import mpmath; mpmath.diff(lambda x: mpmath.zeta(x), 4) + sage: import mpmath; mpmath.diff(lambda x: mpmath.zeta(x), 4) # optional - mpmath mpf('-0.068911265896125382') TESTS:: diff --git a/src/sage/functions/trig.py b/src/sage/functions/trig.py index 16aeeae43ab..2941866fb24 100644 --- a/src/sage/functions/trig.py +++ b/src/sage/functions/trig.py @@ -336,9 +336,9 @@ def _eval_numpy_(self, x): """ EXAMPLES:: - sage: import numpy - sage: a = numpy.arange(2, 5) - sage: cot(a) + sage: import numpy # optional - numpy + sage: a = numpy.arange(2, 5) # optional - numpy + sage: cot(a) # optional - numpy array([-0.45765755, -7.01525255, 0.86369115]) """ return 1.0 / tan(x) @@ -406,9 +406,9 @@ def _eval_numpy_(self, x): """ EXAMPLES:: - sage: import numpy - sage: a = numpy.arange(2, 5) - sage: sec(a) + sage: import numpy # optional - numpy + sage: a = numpy.arange(2, 5) # optional - numpy + sage: sec(a) # optional - numpy array([-2.40299796, -1.01010867, -1.52988566]) """ return 1 / cos(x) @@ -476,9 +476,9 @@ def _eval_numpy_(self, x): """ EXAMPLES:: - sage: import numpy - sage: a = numpy.arange(2, 5) - sage: csc(a) + sage: import numpy # optional - numpy + sage: a = numpy.arange(2, 5) # optional - numpy + sage: csc(a) # optional - numpy array([ 1.09975017, 7.0861674 , -1.32134871]) """ return 1 / sin(x) @@ -745,9 +745,9 @@ def _eval_numpy_(self, x): """ EXAMPLES:: - sage: import numpy - sage: a = numpy.arange(2, 5) - sage: arccot(a) + sage: import numpy # optional - numpy + sage: a = numpy.arange(2, 5) # optional - numpy + sage: arccot(a) # optional - numpy array([0.46364761, 0.32175055, 0.24497866]) """ return math.pi / 2 - arctan(x) @@ -805,9 +805,9 @@ def _eval_numpy_(self, x): """ EXAMPLES:: - sage: import numpy - sage: a = numpy.arange(2, 5) - sage: arccsc(a) + sage: import numpy # optional - numpy + sage: a = numpy.arange(2, 5) # optional - numpy + sage: arccsc(a) # optional - numpy array([0.52359878, 0.33983691, 0.25268026]) """ return arcsin(1.0 / x) @@ -867,9 +867,9 @@ def _eval_numpy_(self, x): """ EXAMPLES:: - sage: import numpy - sage: a = numpy.arange(2, 5) - sage: arcsec(a) + sage: import numpy # optional - numpy + sage: a = numpy.arange(2, 5) # optional - numpy + sage: arcsec(a) # optional - numpy array([1.04719755, 1.23095942, 1.31811607]) """ return arccos(1.0 / x) @@ -943,16 +943,16 @@ def __init__(self): The function also works with numpy arrays as input:: - sage: import numpy - sage: a = numpy.linspace(1, 3, 3) - sage: b = numpy.linspace(3, 6, 3) - sage: atan2(a, b) + sage: import numpy # optional - numpy + sage: a = numpy.linspace(1, 3, 3) # optional - numpy + sage: b = numpy.linspace(3, 6, 3) # optional - numpy + sage: atan2(a, b) # optional - numpy array([0.32175055, 0.41822433, 0.46364761]) - sage: atan2(1,a) + sage: atan2(1,a) # optional - numpy array([0.78539816, 0.46364761, 0.32175055]) - sage: atan2(a, 1) + sage: atan2(a, 1) # optional - numpy array([0.78539816, 1.10714872, 1.24904577]) TESTS:: diff --git a/src/sage/game_theory/cooperative_game.py b/src/sage/game_theory/cooperative_game.py index 0cb18189191..b95ba0f655a 100644 --- a/src/sage/game_theory/cooperative_game.py +++ b/src/sage/game_theory/cooperative_game.py @@ -21,7 +21,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** from itertools import permutations, combinations -from sage.misc.misc import powerset +from sage.combinat.subset import powerset from sage.rings.integer import Integer from sage.structure.sage_object import SageObject diff --git a/src/sage/game_theory/normal_form_game.py b/src/sage/game_theory/normal_form_game.py index 5068c8e10e3..cd6e371eeb2 100644 --- a/src/sage/game_theory/normal_form_game.py +++ b/src/sage/game_theory/normal_form_game.py @@ -635,7 +635,7 @@ from itertools import product from .parser import Parser from sage.misc.latex import latex -from sage.misc.misc import powerset +from sage.combinat.subset import powerset from sage.rings.rational_field import QQ from sage.structure.sage_object import SageObject from sage.matrix.constructor import matrix diff --git a/src/sage/games/all.py b/src/sage/games/all.py index e3e31bcf03e..6cf915addde 100644 --- a/src/sage/games/all.py +++ b/src/sage/games/all.py @@ -1,2 +1,4 @@ -from .sudoku import Sudoku, sudoku -from .hexad import Minimog +from sage.misc.lazy_import import lazy_import + +lazy_import('sage.games.sudoku', ['Sudoku', 'sudoku']) +lazy_import('sage.games.hexad', ['Minimog']) diff --git a/src/sage/geometry/abc.pxd b/src/sage/geometry/abc.pxd new file mode 100644 index 00000000000..c55c90a25ea --- /dev/null +++ b/src/sage/geometry/abc.pxd @@ -0,0 +1,5 @@ +from sage.structure.parent cimport Parent + + +cdef class HyperbolicSpace(Parent): + pass diff --git a/src/sage/geometry/abc.pyx b/src/sage/geometry/abc.pyx index 4db85b7ace8..359be297d45 100644 --- a/src/sage/geometry/abc.pyx +++ b/src/sage/geometry/abc.pyx @@ -79,3 +79,26 @@ class Polyhedron: """ pass + + +cdef class HyperbolicSpace(Parent): + r""" + Abstract base class for :class:`~sage.geometry.hyperbolic_space.hyperbolic_model.HyperbolicModel` + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: import sage.geometry.abc + sage: H = HyperbolicPlane() # optional - sage.symbolic + sage: isinstance(H, sage.geometry.abc.HyperbolicSpace) # optional - sage.symbolic + True + + By design, there is a unique direct subclass:: + + sage: len(sage.geometry.abc.HyperbolicSpace.__subclasses__()) <= 1 + True + """ + + pass diff --git a/src/sage/geometry/all.py b/src/sage/geometry/all.py index 3b7dcf756d8..07a4b30cc44 100644 --- a/src/sage/geometry/all.py +++ b/src/sage/geometry/all.py @@ -1,7 +1,8 @@ +from sage.misc.lazy_import import lazy_import + from .polyhedron.all import * -from .hyperbolic_space.all import * +lazy_import('sage.geometry.hyperbolic_space.hyperbolic_interface', 'HyperbolicPlane') from .polyhedral_complex import PolyhedralComplex -from sage.misc.lazy_import import lazy_import lazy_import('sage.geometry.cone', ['Cone', 'random_cone']) lazy_import('sage.geometry', 'cone_catalog', 'cones') diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index 1d9b1b4f080..2b796e3de1a 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -129,31 +129,31 @@ You can work with subcones that form faces of other cones:: - sage: face = four_rays.faces(dim=2)[0] - sage: face + sage: face = four_rays.faces(dim=2)[0] # optional - sage.graphs + sage: face # optional - sage.graphs 2-d face of 3-d cone in 3-d lattice N - sage: face.rays() + sage: face.rays() # optional - sage.graphs N(-1, -1, 1), N(-1, 1, 1) in 3-d lattice N - sage: face.ambient_ray_indices() + sage: face.ambient_ray_indices() # optional - sage.graphs (2, 3) - sage: four_rays.rays(face.ambient_ray_indices()) + sage: four_rays.rays(face.ambient_ray_indices()) # optional - sage.graphs N(-1, -1, 1), N(-1, 1, 1) in 3-d lattice N If you need to know inclusion relations between faces, you can use :: - sage: L = four_rays.face_lattice() - sage: [len(s) for s in L.level_sets()] + sage: L = four_rays.face_lattice() # optional - sage.graphs + sage: [len(s) for s in L.level_sets()] # optional - sage.graphs [1, 4, 4, 1] - sage: face = L.level_sets()[2][0] - sage: face.rays() + sage: face = L.level_sets()[2][0] # optional - sage.graphs + sage: face.rays() # optional - sage.graphs N(1, 1, 1), N(1, -1, 1) in 3-d lattice N - sage: L.hasse_diagram().neighbors_in(face) + sage: L.hasse_diagram().neighbors_in(face) # optional - sage.graphs [1-d face of 3-d cone in 3-d lattice N, 1-d face of 3-d cone in 3-d lattice N] @@ -572,9 +572,9 @@ def _ambient_space_point(body, data): (1, 1/3) sage: _ambient_space_point(c, vector(QQ,[1,1/3])) (1, 1/3) - sage: _ambient_space_point(c, [1/2,1/sqrt(3)]) + sage: _ambient_space_point(c, [1/2, 1/sqrt(3)]) # optional - sage.symbolic sage.rings.number_field (1/2, 0.5773502691896258?) - sage: _ambient_space_point(c, vector(AA,[1/2,1/sqrt(3)])) + sage: _ambient_space_point(c, vector(AA, [1/2, 1/sqrt(3)])) # optional - sage.symbolic sage.rings.number_field (1/2, 0.5773502691896258?) sage: _ambient_space_point(c, [1,1,3]) Traceback (most recent call last): @@ -592,9 +592,9 @@ def _ambient_space_point(body, data): sage: from sage.geometry.cone import _ambient_space_point sage: c = Cone([(1,0), (0,1)]) - sage: _ambient_space_point(c, [1, pi]) + sage: _ambient_space_point(c, [1, pi]) # optional - sage.symbolic sage.rings.number_field (1.00000000000000, 3.14159265358979) - sage: _ambient_space_point(c, vector(SR,[1, pi])) + sage: _ambient_space_point(c, vector(SR,[1, pi])) # optional - sage.symbolic sage.rings.number_field (1.00000000000000, 3.14159265358979) """ @@ -1005,7 +1005,7 @@ def ambient_vector_space(self, base_field=None): sage: c = Cone([(1,0)]) sage: c.ambient_vector_space() Vector space of dimension 2 over Rational Field - sage: c.ambient_vector_space(AA) + sage: c.ambient_vector_space(AA) # optional - sage.rings.number_field Vector space of dimension 2 over Algebraic Real Field """ return self.lattice().vector_space(base_field=base_field) @@ -1098,7 +1098,7 @@ def plot(self, **options): EXAMPLES:: sage: quadrant = Cone([(1,0), (0,1)]) - sage: quadrant.plot() # optional - sage.plot + sage: quadrant.plot() # optional - sage.plot Graphics object consisting of 9 graphics primitives """ tp = ToricPlotter(options, self.lattice().degree(), self.rays()) @@ -1601,7 +1601,7 @@ def __getstate__(self): TESTS:: sage: C = Cone([(1,0)]) - sage: C.face_lattice() + sage: C.face_lattice() # optional - sage.graphs sage.combinat Finite lattice containing 2 elements with distinguished linear extension sage: C._test_pickling() sage: C2 = loads(dumps(C)); C2 @@ -1674,17 +1674,17 @@ def _contains(self, point, region='whole cone'): We can test vectors with irrational components:: sage: c = Cone([(1,0), (0,1)]) - sage: c._contains((1,sqrt(2))) + sage: c._contains((1, sqrt(2))) # optional - sage.symbolic True - sage: c._contains(vector(SR, [1,pi])) + sage: c._contains(vector(SR, [1, pi])) # optional - sage.symbolic True Ensure that complex vectors are not contained in a real cone:: sage: c = Cone([(1,0), (0,1)]) - sage: c._contains((1,I)) + sage: c._contains((1,I)) # optional - sage.symbolic False - sage: c._contains(vector(QQbar,[1,I])) + sage: c._contains(vector(QQbar, [1,I])) # optional - sage.symbolic False And we refuse to coerce elements of another lattice into ours:: @@ -1971,7 +1971,7 @@ def _latex_(self): sage: quadrant = Cone([(1,0), (0,1)]) sage: quadrant._latex_() '\\sigma^{2}' - sage: quadrant.facets()[0]._latex_() + sage: quadrant.facets()[0]._latex_() # optional - sage.graphs '\\sigma^{1} \\subset \\sigma^{2}' """ if self.ambient() is self: @@ -1995,7 +1995,7 @@ def _repr_(self): '2-d cone in 2-d lattice N' sage: quadrant 2-d cone in 2-d lattice N - sage: quadrant.facets()[0] + sage: quadrant.facets()[0] # optional - sage.graphs 1-d face of 2-d cone in 2-d lattice N """ result = "%d-d" % self.dim() @@ -2051,7 +2051,7 @@ def _sort_faces(self, faces): sage: octant = Cone(identity_matrix(3).columns()) sage: # indirect doctest - sage: for i, face in enumerate(octant.faces(1)): + sage: for i, face in enumerate(octant.faces(1)): # optional - sage.graphs ....: if face.ray(0) != octant.ray(i): ....: print("Wrong order!") """ @@ -2096,12 +2096,12 @@ def adjacent(self): EXAMPLES:: sage: octant = Cone([(1,0,0), (0,1,0), (0,0,1)]) - sage: octant.adjacent() + sage: octant.adjacent() # optional - sage.graphs () - sage: one_face = octant.faces(1)[0] - sage: len(one_face.adjacent()) + sage: one_face = octant.faces(1)[0] # optional - sage.graphs + sage: len(one_face.adjacent()) # optional - sage.graphs 2 - sage: one_face.adjacent()[1] + sage: one_face.adjacent()[1] # optional - sage.graphs 1-d face of 3-d cone in 3-d lattice N Things are a little bit subtle with fans, as we illustrate below. @@ -2111,7 +2111,7 @@ def adjacent(self): sage: fan = Fan(cones=[(0,1), (1,2)], ....: rays=[(1,0), (0,1), (-1,0)]) sage: cone = fan.generating_cone(0) - sage: len(cone.adjacent()) + sage: len(cone.adjacent()) # optional - sage.graphs 1 The second generating cone is adjacent to this one. Now we create the @@ -2120,7 +2120,7 @@ def adjacent(self): sage: fan = Fan(cones=[(0,1), (1,2)], ....: rays=[(1,0,0), (0,1,0), (-1,0,0)]) sage: cone = fan.generating_cone(0) - sage: len(cone.adjacent()) + sage: len(cone.adjacent()) # optional - sage.graphs 1 The result is as before, since we still have:: @@ -2133,7 +2133,7 @@ def adjacent(self): sage: fan = Fan(cones=[(0,1), (1,2), (3,)], ....: rays=[(1,0,0), (0,1,0), (-1,0,0), (0,0,1)]) sage: cone = fan.generating_cone(0) - sage: len(cone.adjacent()) + sage: len(cone.adjacent()) # optional - sage.graphs 0 Since now ``cone`` has smaller dimension than ``fan``, it and its @@ -2176,12 +2176,12 @@ def ambient(self): 3-d cone in 3-d lattice N sage: cone.ambient() is cone True - sage: face = cone.faces(1)[0] - sage: face + sage: face = cone.faces(1)[0] # optional - sage.graphs + sage: face # optional - sage.graphs 1-d face of 3-d cone in 3-d lattice N - sage: face.ambient() + sage: face.ambient() # optional - sage.graphs 3-d cone in 3-d lattice N - sage: face.ambient() is cone + sage: face.ambient() is cone # optional - sage.graphs True """ return self._ambient @@ -2199,7 +2199,7 @@ def ambient_ray_indices(self): sage: quadrant = Cone([(1,0), (0,1)]) sage: quadrant.ambient_ray_indices() (0, 1) - sage: quadrant.facets()[1].ambient_ray_indices() + sage: quadrant.facets()[1].ambient_ray_indices() # optional - sage.graphs (1,) """ return self._ambient_ray_indices @@ -2232,15 +2232,15 @@ def contains(self, *args): True sage: c.contains((-1,0)) False - sage: c.contains(c.dual_lattice()(1,0)) #random output (warning) + sage: c.contains(c.dual_lattice()(1,0)) # random output (warning) False sage: c.contains(c.dual_lattice()(1,0)) False sage: c.contains(1) False - sage: c.contains(1/2, sqrt(3)) + sage: c.contains(1/2, sqrt(3)) # optional - sage.symbolic True - sage: c.contains(-1/2, sqrt(3)) + sage: c.contains(-1/2, sqrt(3)) # optional - sage.symbolic False """ point = flatten(args) @@ -2369,7 +2369,7 @@ def embed(self, cone): 1-d cone in 3-d lattice N sage: ray.ambient_ray_indices() (0,) - sage: ray.adjacent() + sage: ray.adjacent() # optional - sage.graphs () sage: ray.ambient() 1-d cone in 3-d lattice N @@ -2377,22 +2377,22 @@ def embed(self, cone): If we want to operate with this ray as a face of the cone, we need to embed it first:: - sage: e_ray = c.embed(ray) - sage: e_ray + sage: e_ray = c.embed(ray) # optional - sage.graphs + sage: e_ray # optional - sage.graphs 1-d face of 3-d cone in 3-d lattice N - sage: e_ray.rays() + sage: e_ray.rays() # optional - sage.graphs N(0, -1, 1) in 3-d lattice N - sage: e_ray is ray + sage: e_ray is ray # optional - sage.graphs False - sage: e_ray.is_equivalent(ray) + sage: e_ray.is_equivalent(ray) # optional - sage.graphs True - sage: e_ray.ambient_ray_indices() + sage: e_ray.ambient_ray_indices() # optional - sage.graphs (3,) - sage: e_ray.adjacent() + sage: e_ray.adjacent() # optional - sage.graphs (1-d face of 3-d cone in 3-d lattice N, 1-d face of 3-d cone in 3-d lattice N) - sage: e_ray.ambient() + sage: e_ray.ambient() # optional - sage.graphs 3-d cone in 3-d lattice N Not every cone can be embedded into a fixed ambient cone:: @@ -2402,7 +2402,7 @@ def embed(self, cone): ... ValueError: 1-d cone in 3-d lattice N is not a face of 3-d cone in 3-d lattice N! - sage: c.embed(Cone([(1,0,1), (-1,0,1)])) + sage: c.embed(Cone([(1,0,1), (-1,0,1)])) # optional - sage.graphs Traceback (most recent call last): ... ValueError: 2-d cone in 3-d lattice N is not a face @@ -2447,13 +2447,13 @@ def face_lattice(self): Let's take a look at the face lattice of the first quadrant:: sage: quadrant = Cone([(1,0), (0,1)]) - sage: L = quadrant.face_lattice() - sage: L + sage: L = quadrant.face_lattice() # optional - sage.graphs sage.combinat + sage: L # optional - sage.graphs sage.combinat Finite lattice containing 4 elements with distinguished linear extension To see all faces arranged by dimension, you can do this:: - sage: for level in L.level_sets(): print(level) + sage: for level in L.level_sets(): print(level) # optional - sage.graphs sage.combinat [0-d face of 2-d cone in 2-d lattice N] [1-d face of 2-d cone in 2-d lattice N, 1-d face of 2-d cone in 2-d lattice N] @@ -2461,15 +2461,15 @@ def face_lattice(self): For a particular face you can look at its actual rays... :: - sage: face = L.level_sets()[1][0] - sage: face.rays() + sage: face = L.level_sets()[1][0] # optional - sage.graphs sage.combinat + sage: face.rays() # optional - sage.graphs sage.combinat N(1, 0) in 2-d lattice N ... or you can see the index of the ray of the original cone that corresponds to the above one:: - sage: face.ambient_ray_indices() + sage: face.ambient_ray_indices() # optional - sage.graphs sage.combinat (0,) sage: quadrant.ray(0) N(1, 0) @@ -2477,34 +2477,34 @@ def face_lattice(self): An alternative to extracting faces from the face lattice is to use :meth:`faces` method:: - sage: face is quadrant.faces(dim=1)[0] + sage: face is quadrant.faces(dim=1)[0] # optional - sage.graphs sage.combinat True The advantage of working with the face lattice directly is that you can (relatively easily) get faces that are related to the given one:: - sage: face = L.level_sets()[1][0] - sage: D = L.hasse_diagram() - sage: sorted(D.neighbors(face)) + sage: face = L.level_sets()[1][0] # optional - sage.graphs sage.combinat + sage: D = L.hasse_diagram() # optional - sage.graphs sage.combinat + sage: sorted(D.neighbors(face)) # optional - sage.graphs sage.combinat [0-d face of 2-d cone in 2-d lattice N, 2-d cone in 2-d lattice N] However, you can achieve some of this functionality using :meth:`facets`, :meth:`facet_of`, and :meth:`adjacent` methods:: - sage: face = quadrant.faces(1)[0] - sage: face + sage: face = quadrant.faces(1)[0] # optional - sage.graphs + sage: face # optional - sage.graphs 1-d face of 2-d cone in 2-d lattice N - sage: face.rays() + sage: face.rays() # optional - sage.graphs N(1, 0) in 2-d lattice N - sage: face.facets() + sage: face.facets() # optional - sage.graphs (0-d face of 2-d cone in 2-d lattice N,) - sage: face.facet_of() + sage: face.facet_of() # optional - sage.graphs (2-d cone in 2-d lattice N,) - sage: face.adjacent() + sage: face.adjacent() # optional - sage.graphs (1-d face of 2-d cone in 2-d lattice N,) - sage: face.adjacent()[0].rays() + sage: face.adjacent()[0].rays() # optional - sage.graphs N(0, 1) in 2-d lattice N @@ -2513,20 +2513,20 @@ def face_lattice(self): sage: supercone = Cone([(1,2,3,4), (5,6,7,8), ....: (1,2,4,8), (1,3,9,7)]) - sage: supercone.face_lattice() + sage: supercone.face_lattice() # optional - sage.graphs sage.combinat Finite lattice containing 16 elements with distinguished linear extension - sage: supercone.face_lattice().top() + sage: supercone.face_lattice().top() # optional - sage.graphs sage.combinat 4-d cone in 4-d lattice N - sage: cone = supercone.facets()[0] - sage: cone + sage: cone = supercone.facets()[0] # optional - sage.graphs sage.combinat + sage: cone # optional - sage.graphs sage.combinat 3-d face of 4-d cone in 4-d lattice N - sage: cone.face_lattice() + sage: cone.face_lattice() # optional - sage.graphs sage.combinat Finite poset containing 8 elements with distinguished linear extension - sage: cone.face_lattice().bottom() + sage: cone.face_lattice().bottom() # optional - sage.graphs sage.combinat 0-d face of 4-d cone in 4-d lattice N - sage: cone.face_lattice().top() + sage: cone.face_lattice().top() # optional - sage.graphs sage.combinat 3-d face of 4-d cone in 4-d lattice N - sage: cone.face_lattice().top() == cone + sage: cone.face_lattice().top() == cone # optional - sage.graphs sage.combinat True TESTS:: @@ -2542,19 +2542,19 @@ def face_lattice(self): to have non identical face lattices, even if the faces themselves are equal (see :trac:`10998`):: - sage: C1.face_lattice() is C2.face_lattice() + sage: C1.face_lattice() is C2.face_lattice() # optional - sage.graphs sage.combinat False - sage: C1.facets()[0] + sage: C1.facets()[0] # optional - sage.graphs 0-d face of 1-d cone in 2-d lattice N - sage: C2.facets()[0] + sage: C2.facets()[0] # optional - sage.graphs 0-d face of 1-d cone in 2-d lattice N - sage: C1.facets()[0].ambient() is C1 + sage: C1.facets()[0].ambient() is C1 # optional - sage.graphs True - sage: C2.facets()[0].ambient() is C1 + sage: C2.facets()[0].ambient() is C1 # optional - sage.graphs False - sage: C2.facets()[0].ambient() is C2 + sage: C2.facets()[0].ambient() is C2 # optional - sage.graphs True """ if "_face_lattice" not in self.__dict__: @@ -2680,50 +2680,50 @@ def faces(self, dim=None, codim=None): Let's take a look at the faces of the first quadrant:: sage: quadrant = Cone([(1,0), (0,1)]) - sage: quadrant.faces() + sage: quadrant.faces() # optional - sage.graphs ((0-d face of 2-d cone in 2-d lattice N,), (1-d face of 2-d cone in 2-d lattice N, 1-d face of 2-d cone in 2-d lattice N), (2-d cone in 2-d lattice N,)) - sage: quadrant.faces(dim=1) + sage: quadrant.faces(dim=1) # optional - sage.graphs (1-d face of 2-d cone in 2-d lattice N, 1-d face of 2-d cone in 2-d lattice N) - sage: face = quadrant.faces(dim=1)[0] + sage: face = quadrant.faces(dim=1)[0] # optional - sage.graphs Now you can look at the actual rays of this face... :: - sage: face.rays() + sage: face.rays() # optional - sage.graphs N(1, 0) in 2-d lattice N ... or you can see indices of the rays of the original cone that correspond to the above ray:: - sage: face.ambient_ray_indices() + sage: face.ambient_ray_indices() # optional - sage.graphs (0,) sage: quadrant.ray(0) N(1, 0) Note that it is OK to ask for faces of too small or high dimension:: - sage: quadrant.faces(-1) + sage: quadrant.faces(-1) # optional - sage.graphs () - sage: quadrant.faces(3) + sage: quadrant.faces(3) # optional - sage.graphs () In the case of non-strictly convex cones even faces of small non-negative dimension may be missing:: sage: halfplane = Cone([(1,0), (0,1), (-1,0)]) - sage: halfplane.faces(0) + sage: halfplane.faces(0) # optional - sage.graphs () - sage: halfplane.faces() + sage: halfplane.faces() # optional - sage.graphs ((1-d face of 2-d cone in 2-d lattice N,), (2-d cone in 2-d lattice N,)) - sage: plane = Cone([(1,0), (0,1), (-1,-1)]) - sage: plane.faces(1) + sage: plane = Cone([(1,0), (0,1), (-1,-1)]) # optional - sage.graphs + sage: plane.faces(1) # optional - sage.graphs () - sage: plane.faces() + sage: plane.faces() # optional - sage.graphs ((2-d cone in 2-d lattice N,),) TESTS: @@ -2732,7 +2732,7 @@ def faces(self, dim=None, codim=None): dimension of the ambient space work as expected (see :trac:`9188`):: sage: c = Cone([(1,1,1,3),(1,-1,1,3),(-1,-1,1,3)]) - sage: c.faces() + sage: c.faces() # optional - sage.graphs ((0-d face of 3-d cone in 4-d lattice N,), (1-d face of 3-d cone in 4-d lattice N, 1-d face of 3-d cone in 4-d lattice N, @@ -2747,14 +2747,14 @@ def faces(self, dim=None, codim=None): sage: cone = toric_varieties.dP8().fan().generating_cone(0); cone # optional - palp 2-d cone of Rational polyhedral fan in 2-d lattice N - sage: for f in cone.facets(): print(f.rays()) # optional - palp + sage: for f in cone.facets(): print(f.rays()) # optional - palp sage.graphs N(1, 1) in 2-d lattice N N(0, 1) in 2-d lattice N - sage: len(cone.faces()) # optional - palp + sage: len(cone.faces()) # optional - palp sage.graphs 3 - sage: for f in cone.facets(): print(f.rays()) # optional - palp + sage: for f in cone.facets(): print(f.rays()) # optional - palp sage.graphs N(1, 1) in 2-d lattice N N(0, 1) @@ -2901,25 +2901,25 @@ def facet_of(self): EXAMPLES:: sage: octant = Cone([(1,0,0), (0,1,0), (0,0,1)]) - sage: octant.facet_of() + sage: octant.facet_of() # optional - sage.graphs () - sage: one_face = octant.faces(1)[0] - sage: len(one_face.facet_of()) + sage: one_face = octant.faces(1)[0] # optional - sage.graphs + sage: len(one_face.facet_of()) # optional - sage.graphs 2 - sage: one_face.facet_of()[1] + sage: one_face.facet_of()[1] # optional - sage.graphs 2-d face of 3-d cone in 3-d lattice N While fan is the top element of its own cone lattice, which is a variant of a face lattice, we do not refer to cones as its facets:: sage: fan = Fan([octant]) - sage: fan.generating_cone(0).facet_of() + sage: fan.generating_cone(0).facet_of() # optional - sage.graphs () Subcones of generating cones work as before:: - sage: one_cone = fan(1)[0] - sage: len(one_cone.facet_of()) + sage: one_cone = fan(1)[0] # optional - sage.graphs + sage: len(one_cone.facet_of()) # optional - sage.graphs 2 """ L = self._ambient._face_lattice_function() @@ -2938,7 +2938,7 @@ def facets(self): EXAMPLES:: sage: quadrant = Cone([(1,0), (0,1)]) - sage: quadrant.facets() + sage: quadrant.facets() # optional - sage.graphs (1-d face of 2-d cone in 2-d lattice N, 1-d face of 2-d cone in 2-d lattice N) """ @@ -3257,19 +3257,19 @@ def is_isomorphic(self, other): We check that :trac:`18613` is fixed:: sage: K = cones.trivial(0) - sage: K.is_isomorphic(K) + sage: K.is_isomorphic(K) # optional - sage.graphs True sage: K = cones.trivial(1) - sage: K.is_isomorphic(K) + sage: K.is_isomorphic(K) # optional - sage.graphs True sage: K = cones.trivial(2) - sage: K.is_isomorphic(K) + sage: K.is_isomorphic(K) # optional - sage.graphs True A random (strictly convex) cone is isomorphic to itself:: sage: K = random_cone(max_ambient_dim=6, strictly_convex=True) - sage: K.is_isomorphic(K) + sage: K.is_isomorphic(K) # optional - sage.graphs True """ if self.is_strictly_convex() and other.is_strictly_convex(): @@ -3484,7 +3484,7 @@ def plot(self, **options): EXAMPLES:: sage: quadrant = Cone([(1,0), (0,1)]) - sage: quadrant.plot() # optional - sage.plot + sage: quadrant.plot() # optional - sage.plot Graphics object consisting of 9 graphics primitives """ # What to do with 3-d cones in 5-d? Use some projection method? @@ -3754,7 +3754,7 @@ def solid_restriction(self): the original:: sage: K = random_cone(max_ambient_dim=6) - sage: len(K.solid_restriction().facets()) == len(K.facets()) + sage: len(K.solid_restriction().facets()) == len(K.facets()) # optional - sage.graphs True """ if self.is_solid(): @@ -3915,17 +3915,17 @@ def sublattice_quotient(self, *args, **kwds): EXAMPLES:: - sage: C2_Z2 = Cone([(1,0),(1,2)]) # C^2/Z_2 - sage: c1, c2 = C2_Z2.facets() - sage: c2.sublattice_quotient() + sage: C2_Z2 = Cone([(1,0), (1,2)]) # C^2/Z_2 + sage: c1, c2 = C2_Z2.facets() # optional - sage.graphs + sage: c2.sublattice_quotient() # optional - sage.graphs 1-d lattice, quotient of 2-d lattice N by Sublattice sage: N = C2_Z2.lattice() sage: n = N(1,1) - sage: n_bar = c2.sublattice_quotient(n); n_bar + sage: n_bar = c2.sublattice_quotient(n); n_bar # optional - sage.graphs N[1, 1] - sage: n_bar.lift() + sage: n_bar.lift() # optional - sage.graphs N(1, 1) - sage: vector(n_bar) + sage: vector(n_bar) # optional - sage.graphs (-1) """ if "_sublattice_quotient" not in self.__dict__: @@ -3967,11 +3967,11 @@ def sublattice_complement(self, *args, **kwds): EXAMPLES:: - sage: C2_Z2 = Cone([(1,0),(1,2)]) # C^2/Z_2 - sage: c1, c2 = C2_Z2.facets() - sage: c2.sublattice() + sage: C2_Z2 = Cone([(1,0), (1,2)]) # C^2/Z_2 + sage: c1, c2 = C2_Z2.facets() # optional - sage.graphs + sage: c2.sublattice() # optional - sage.graphs Sublattice - sage: c2.sublattice_complement() + sage: c2.sublattice_complement() # optional - sage.graphs Sublattice A more complicated example:: @@ -4197,30 +4197,30 @@ def relative_orthogonal_quotient(self, supercone): EXAMPLES:: - sage: rho = Cone([(1,1,1,3),(1,-1,1,3),(-1,-1,1,3),(-1,1,1,3)]) + sage: rho = Cone([(1,1,1,3), (1,-1,1,3), (-1,-1,1,3), (-1,1,1,3)]) sage: rho.orthogonal_sublattice() Sublattice - sage: sigma = rho.facets()[1] - sage: sigma.orthogonal_sublattice() + sage: sigma = rho.facets()[1] # optional - sage.graphs + sage: sigma.orthogonal_sublattice() # optional - sage.graphs Sublattice - sage: sigma.is_face_of(rho) + sage: sigma.is_face_of(rho) # optional - sage.graphs True - sage: Q = sigma.relative_orthogonal_quotient(rho); Q + sage: Q = sigma.relative_orthogonal_quotient(rho); Q # optional - sage.graphs 1-d lattice, quotient of Sublattice by Sublattice - sage: Q.gens() + sage: Q.gens() # optional - sage.graphs (M[0, 1, 1, 0],) Different codimension:: sage: rho = Cone([[1,-1,1,3],[-1,-1,1,3]]) - sage: sigma = rho.facets()[0] - sage: sigma.orthogonal_sublattice() + sage: sigma = rho.facets()[0] # optional - sage.graphs + sage: sigma.orthogonal_sublattice() # optional - sage.graphs Sublattice - sage: rho.orthogonal_sublattice() + sage: rho.orthogonal_sublattice() # optional - sage.graphs Sublattice - sage: sigma.relative_orthogonal_quotient(rho).gens() + sage: sigma.relative_orthogonal_quotient(rho).gens() # optional - sage.graphs (M[-1, 0, -2, 1],) Sign choice in the codimension one case:: @@ -4280,7 +4280,7 @@ def semigroup_generators(self): We start with a simple case of a non-smooth 2-dimensional cone:: - sage: Cone([ (1,0), (1,2) ]).semigroup_generators() + sage: Cone([(1,0), (1,2)]).semigroup_generators() N(1, 1), N(1, 0), N(1, 2) @@ -4294,19 +4294,19 @@ def semigroup_generators(self): GAP's toric package thinks this is challenging:: - sage: cone = Cone([[1,2,3,4],[0,1,0,7],[3,1,0,2],[0,0,1,0]]).dual() - sage: len( cone.semigroup_generators() ) + sage: cone = Cone([[1,2,3,4], [0,1,0,7], [3,1,0,2], [0,0,1,0]]).dual() + sage: len(cone.semigroup_generators()) 2806 The cone need not be strictly convex:: - sage: halfplane = Cone([(1,0),(2,1),(-1,0)]) + sage: halfplane = Cone([(1,0), (2,1), (-1,0)]) sage: sorted(halfplane.semigroup_generators()) [N(-1, 0), N(0, 1), N(1, 0)] - sage: line = Cone([(1,1,1),(-1,-1,-1)]) + sage: line = Cone([(1,1,1), (-1,-1,-1)]) sage: sorted(line.semigroup_generators()) [N(-1, -1, -1), N(1, 1, 1)] - sage: wedge = Cone([ (1,0,0), (1,2,0), (0,0,1), (0,0,-1) ]) + sage: wedge = Cone([(1,0,0), (1,2,0), (0,0,1), (0,0,-1)]) sage: sorted(wedge.semigroup_generators()) [N(0, 0, -1), N(0, 0, 1), N(1, 0, 0), N(1, 1, 0), N(1, 2, 0)] @@ -4324,14 +4324,14 @@ def semigroup_generators(self): sage: A.elementary_divisors() [1, 1, 1, 0] sage: cone3d = Cone([(3,0,-1), (1,-1,0), (0,1,0), (0,0,1)]) - sage: rays = ( A*vector(v) for v in cone3d.rays() ) + sage: rays = (A*vector(v) for v in cone3d.rays()) sage: gens = Cone(rays).semigroup_generators(); sorted(gens) [N(-2, -1, 0, 17), N(0, 1, -2, 0), N(1, -1, 1, 15), N(3, -4, 5, 45), N(3, 0, 1, -2)] - sage: set(map(tuple,gens)) == set( tuple(A*r) for r in cone3d.semigroup_generators() ) + sage: set(map(tuple,gens)) == set(tuple(A*r) for r in cone3d.semigroup_generators()) True TESTS:: @@ -4425,7 +4425,7 @@ def Hilbert_basis(self): We start with a simple case of a non-smooth 2-dimensional cone:: - sage: Cone([ (1,0), (1,2) ]).Hilbert_basis() + sage: Cone([(1,0), (1,2)]).Hilbert_basis() N(1, 0), N(1, 2), N(1, 1) @@ -4433,14 +4433,14 @@ def Hilbert_basis(self): Two more complicated example from GAP/toric:: - sage: Cone([[1,0],[3,4]]).dual().Hilbert_basis() + sage: Cone([[1,0], [3,4]]).dual().Hilbert_basis() M(0, 1), M(4, -3), M(1, 0), M(2, -1), M(3, -2) in 2-d lattice M - sage: cone = Cone([[1,2,3,4],[0,1,0,7],[3,1,0,2],[0,0,1,0]]).dual() + sage: cone = Cone([[1,2,3,4], [0,1,0,7], [3,1,0,2], [0,0,1,0]]).dual() sage: cone.Hilbert_basis() # long time M(10, -7, 0, 1), M(-5, 21, 0, -3), @@ -4475,7 +4475,7 @@ def Hilbert_basis(self): Not a strictly convex cone:: - sage: wedge = Cone([ (1,0,0), (1,2,0), (0,0,1), (0,0,-1) ]) + sage: wedge = Cone([(1,0,0), (1,2,0), (0,0,1), (0,0,-1)]) sage: sorted(wedge.semigroup_generators()) [N(0, 0, -1), N(0, 0, 1), N(1, 0, 0), N(1, 1, 0), N(1, 2, 0)] sage: wedge.Hilbert_basis() @@ -4573,7 +4573,7 @@ def Hilbert_coefficients(self, point, solver=None, verbose=0, EXAMPLES:: - sage: cone = Cone([(1,0),(0,1)]) + sage: cone = Cone([(1,0), (0,1)]) sage: cone.rays() N(1, 0), N(0, 1) @@ -4584,19 +4584,19 @@ def Hilbert_coefficients(self, point, solver=None, verbose=0, A more complicated example:: sage: N = ToricLattice(2) - sage: cone = Cone([N(1,0),N(1,2)]) + sage: cone = Cone([N(1,0), N(1,2)]) sage: cone.Hilbert_basis() N(1, 0), N(1, 2), N(1, 1) in 2-d lattice N - sage: cone.Hilbert_coefficients( N(1,1) ) + sage: cone.Hilbert_coefficients(N(1,1)) (0, 0, 1) The cone need not be strictly convex:: sage: N = ToricLattice(3) - sage: cone = Cone([N(1,0,0),N(1,2,0),N(0,0,1),N(0,0,-1)]) + sage: cone = Cone([N(1,0,0), N(1,2,0), N(0,0,1), N(0,0,-1)]) sage: cone.Hilbert_basis() N(1, 2, 0), N(1, 0, 0), @@ -4604,7 +4604,7 @@ def Hilbert_coefficients(self, point, solver=None, verbose=0, N(0, 0, -1), N(1, 1, 0) in 3-d lattice N - sage: cone.Hilbert_coefficients( N(1,1,3) ) + sage: cone.Hilbert_coefficients(N(1,1,3)) (0, 0, 3, 0, 1) """ point = self.lattice()(point) @@ -4663,7 +4663,7 @@ def is_solid(self): A closed convex cone is solid if and only if its dual is strictly convex:: - sage: K = random_cone(max_ambient_dim = 8) + sage: K = random_cone(max_ambient_dim=8) sage: K.is_solid() == K.dual().is_strictly_convex() True """ @@ -4710,7 +4710,7 @@ def is_proper(self): Likewise, a half-space contains at least one line, so it is not proper:: - sage: halfspace = Cone([(1,0),(0,1),(-1,0)]) + sage: halfspace = Cone([(1,0), (0,1), (-1,0)]) sage: halfspace.is_proper() False @@ -4746,14 +4746,14 @@ def is_full_space(self): The right half-space contains a vector subspace, but it is still not equal to the entire space:: - sage: K = Cone([(1,0),(-1,0),(0,1)]) + sage: K = Cone([(1,0), (-1,0), (0,1)]) sage: K.is_full_space() False However, if we allow conic combinations of both axes, then the resulting cone is the entire two-dimensional space:: - sage: K = Cone([(1,0),(-1,0),(0,1),(0,-1)]) + sage: K = Cone([(1,0), (-1,0), (0,1), (0,-1)]) sage: K.is_full_space() True @@ -4817,7 +4817,7 @@ def lineality(self): The lineality of a cone should be an integer between zero and the dimension of the ambient space, inclusive:: - sage: K = random_cone(max_ambient_dim = 8) + sage: K = random_cone(max_ambient_dim=8) sage: l = K.lineality() sage: l in ZZ True @@ -4826,7 +4826,7 @@ def lineality(self): A strictly convex cone should have lineality zero:: - sage: K = random_cone(max_ambient_dim = 8, strictly_convex = True) + sage: K = random_cone(max_ambient_dim=8, strictly_convex=True) sage: K.lineality() 0 """ @@ -4904,7 +4904,7 @@ def discrete_complementarity_set(self): When a cone is the entire space, its dual is the trivial cone, so the only discrete complementarity set for it is empty:: - sage: K = Cone([(1,0),(-1,0),(0,1),(0,-1)]) + sage: K = Cone([(1,0), (-1,0), (0,1), (0,-1)]) sage: K.is_full_space() True sage: K.discrete_complementarity_set() @@ -4923,7 +4923,7 @@ def discrete_complementarity_set(self): sage: K = random_cone(max_ambient_dim=6) sage: dcs_dual = K.dual().discrete_complementarity_set() - sage: expected = tuple( (x,s) for (s,x) in dcs_dual ) + sage: expected = tuple((x,s) for (s,x) in dcs_dual) sage: actual = K.discrete_complementarity_set() sage: sorted(actual) == sorted(expected) True @@ -4933,7 +4933,7 @@ def discrete_complementarity_set(self): sage: K = random_cone(max_ambient_dim=6) sage: dcs = K.discrete_complementarity_set() - sage: sum( (s*x).abs() for (x,s) in dcs ) + sage: sum((s*x).abs() for (x,s) in dcs) 0 """ # Return an immutable tuple instead of a mutable list because @@ -5042,7 +5042,7 @@ def lyapunov_like_basis(self): sage: K = random_cone(max_ambient_dim=8) sage: LL = K.lyapunov_like_basis() - sage: all( L.is_lyapunov_like_on(K) for L in LL ) + sage: all(L.is_lyapunov_like_on(K) for L in LL) True The Lyapunov-like transformations on a cone and its dual are @@ -5053,8 +5053,8 @@ def lyapunov_like_basis(self): sage: LL1 = K.lyapunov_like_basis() sage: LL2 = (L.transpose() for L in K.dual().lyapunov_like_basis()) sage: V = VectorSpace(K.lattice().base_field(), K.lattice_dim()^2) - sage: LL1_vecs = ( V(m.list()) for m in LL1 ) - sage: LL2_vecs = ( V(m.list()) for m in LL2 ) + sage: LL1_vecs = (V(m.list()) for m in LL1) + sage: LL2_vecs = (V(m.list()) for m in LL2) sage: V.span(LL1_vecs) == V.span(LL2_vecs) True @@ -5065,9 +5065,9 @@ def lyapunov_like_basis(self): sage: LL = K.lyapunov_like_basis() sage: W = VectorSpace(K.lattice().base_field(), K.lattice_dim()**2) sage: LL_W = W.span( W(m.list()) for m in LL ) - sage: brackets = ( W((L1*L2 - L2*L1).list()) for L1 in LL - ....: for L2 in LL ) - sage: all( b in LL_W for b in brackets ) + sage: brackets = (W((L1*L2 - L2*L1).list()) for L1 in LL + ....: for L2 in LL) + sage: all(b in LL_W for b in brackets) True """ # Matrices are not vectors in Sage, so we have to convert them @@ -5149,7 +5149,7 @@ def lyapunov_rank(self): [Or2017]_:: sage: Q5 = VectorSpace(QQ, 5) - sage: gs = Q5.basis() + [ -r for r in Q5.basis() ] + sage: gs = Q5.basis() + [-r for r in Q5.basis()] sage: K = Cone(gs) sage: K.lyapunov_rank() 25 @@ -5229,7 +5229,7 @@ def lyapunov_rank(self): sage: K1 = random_cone(max_ambient_dim=8) sage: n = K1.lattice_dim() sage: A = random_matrix(QQ, n, algorithm='unimodular') - sage: K2 = Cone( ( A*r for r in K1 ), lattice=K1.lattice()) + sage: K2 = Cone((A*r for r in K1), lattice=K1.lattice()) sage: K1.lyapunov_rank() == K2.lyapunov_rank() True @@ -5286,7 +5286,7 @@ def lyapunov_rank(self): sage: K = random_cone(max_ambient_dim=8) sage: L = ToricLattice(K.lattice_dim() + 1) - sage: K = Cone([ r.list() + [0] for r in K ], lattice=L) + sage: K = Cone([r.list() + [0] for r in K], lattice=L) sage: K.lyapunov_rank() >= K.lattice_dim() True """ @@ -5360,14 +5360,14 @@ def random_element(self, ring=ZZ): components nonnegative:: sage: K = cones.nonnegative_orthant(3) - sage: all( x >= 0 for x in K.random_element() ) + sage: all(x >= 0 for x in K.random_element()) True - sage: all( x >= 0 for x in K.random_element(ring=QQ) ) + sage: all(x >= 0 for x in K.random_element(ring=QQ)) True If ``ring`` is not ``ZZ`` or ``QQ``, an error is raised:: - sage: K = Cone([(1,0),(0,1)]) + sage: K = Cone([(1,0), (0,1)]) sage: K.random_element(ring=RR) Traceback (most recent call last): ... @@ -5516,7 +5516,7 @@ def positive_operators_gens(self, K2=None): sage: K.positive_operators_gens() [[1]] - sage: K = Cone([(1,0),(0,1)]) + sage: K = Cone([(1,0), (0,1)]) sage: K.positive_operators_gens() [ [1 0] [0 1] [0 0] [0 0] @@ -5546,13 +5546,13 @@ def positive_operators_gens(self, K2=None): Every operator is positive on the ambient vector space:: - sage: K = Cone([(1,),(-1,)]) + sage: K = Cone([(1,), (-1,)]) sage: K.is_full_space() True sage: K.positive_operators_gens() [[1], [-1]] - sage: K = Cone([(1,0),(-1,0),(0,1),(0,-1)]) + sage: K = Cone([(1,0), (-1,0), (0,1), (0,-1)]) sage: K.is_full_space() True sage: K.positive_operators_gens() @@ -5564,7 +5564,7 @@ def positive_operators_gens(self, K2=None): A non-obvious application is to find the positive operators on the right half-plane [Or2018b]_:: - sage: K = Cone([(1,0),(0,1),(0,-1)]) + sage: K = Cone([(1,0), (0,1), (0,-1)]) sage: K.positive_operators_gens() [ [1 0] [0 0] [ 0 0] [0 0] [ 0 0] @@ -5580,7 +5580,7 @@ def positive_operators_gens(self, K2=None): sage: K2 = random_cone(max_ambient_dim=3) sage: pi_gens = K1.positive_operators_gens(K2) sage: L = ToricLattice(K1.lattice_dim() * K2.lattice_dim()) - sage: pi_cone = Cone(( g.list() for g in pi_gens ), + sage: pi_cone = Cone((g.list() for g in pi_gens), ....: lattice=L, ....: check=False) sage: P = matrix(K2.lattice_dim(), @@ -5596,16 +5596,16 @@ def positive_operators_gens(self, K2=None): sage: K = random_cone(max_ambient_dim=3) sage: pi_gens = K.positive_operators_gens() sage: L = ToricLattice(K.lattice_dim()**2) - sage: pi_cone = Cone(( g.list() for g in pi_gens ), + sage: pi_cone = Cone((g.list() for g in pi_gens), ....: lattice=L, ....: check=False) sage: actual = pi_cone.dual().linear_subspace() - sage: U1 = [ vector((s.tensor_product(x)).list()) - ....: for x in K.lines() - ....: for s in K.dual() ] - sage: U2 = [ vector((s.tensor_product(x)).list()) - ....: for x in K - ....: for s in K.dual().lines() ] + sage: U1 = [vector((s.tensor_product(x)).list()) + ....: for x in K.lines() + ....: for s in K.dual()] + sage: U2 = [vector((s.tensor_product(x)).list()) + ....: for x in K + ....: for s in K.dual().lines()] sage: expected = pi_cone.lattice().vector_space().span(U1+U2) sage: actual == expected True @@ -5667,7 +5667,7 @@ def positive_operators_gens(self, K2=None): sage: pi_cone.dim() == n^2 True - sage: K = Cone([(1,0),(0,1),(0,-1)]) + sage: K = Cone([(1,0), (0,1), (0,-1)]) sage: pi_gens = K.positive_operators_gens() sage: pi_cone = Cone((g.list() for g in pi_gens), ....: check=False) @@ -5712,7 +5712,7 @@ def positive_operators_gens(self, K2=None): sage: pi_cone.lineality() == n^2 True - sage: K = Cone([(1,0),(0,1),(0,-1)]) + sage: K = Cone([(1,0), (0,1), (0,-1)]) sage: pi_gens = K.positive_operators_gens() sage: pi_cone = Cone((g.list() for g in pi_gens), check=False) sage: pi_cone.lineality() == 2 @@ -5735,17 +5735,17 @@ def positive_operators_gens(self, K2=None): sage: K = random_cone(max_ambient_dim=3) sage: L = ToricLattice(K.lattice_dim()**2) - sage: p = SymmetricGroup(K.lattice_dim()).random_element().matrix() - sage: pK = Cone(( p*k for k in K ), K.lattice(), check=False) - sage: pi_gens = pK.positive_operators_gens() - sage: actual = Cone((g.list() for g in pi_gens), + sage: p = SymmetricGroup(K.lattice_dim()).random_element().matrix() # optional - sage.groups + sage: pK = Cone((p*k for k in K), K.lattice(), check=False) # optional - sage.groups + sage: pi_gens = pK.positive_operators_gens() # optional - sage.groups + sage: actual = Cone((g.list() for g in pi_gens), # optional - sage.groups ....: lattice=L, ....: check=False) sage: pi_gens = K.positive_operators_gens() - sage: expected = Cone(((p*g*p.inverse()).list() for g in pi_gens), + sage: expected = Cone(((p*g*p.inverse()).list() for g in pi_gens), # optional - sage.groups ....: lattice=L, ....: check=False) - sage: actual.is_equivalent(expected) + sage: actual.is_equivalent(expected) # optional - sage.groups True An operator is positive from one cone to another if and only if @@ -5813,16 +5813,16 @@ def positive_operators_gens(self, K2=None): sage: L = ToricLattice(m*n) sage: M1 = MatrixSpace(F, m, m) sage: M2 = MatrixSpace(F, n, n) - sage: tps = ( M2(s.list()).tensor_product(M1(x.list())) - ....: for x in K1.dual().lyapunov_like_basis() - ....: for s in K2.lyapunov_like_basis() ) + sage: tps = (M2(s.list()).tensor_product(M1(x.list())) + ....: for x in K1.dual().lyapunov_like_basis() + ....: for s in K2.lyapunov_like_basis()) sage: W = VectorSpace(F, (m**2)*(n**2)) - sage: expected = span(F, ( W(x.list()) for x in tps )) + sage: expected = span(F, (W(x.list()) for x in tps)) sage: pi_cone = Cone((g.list() for g in pi_gens), ....: lattice=L, ....: check=False) sage: LL_pi = pi_cone.lyapunov_like_basis() - sage: actual = span(F, ( W(x.list()) for x in LL_pi )) + sage: actual = span(F, (W(x.list()) for x in LL_pi)) sage: actual == expected True """ @@ -5922,11 +5922,11 @@ def cross_positive_operators_gens(self): [0 1] [0 0] [1 0] [-1 0] [0 0] [ 0 0] [0 0], [1 0], [0 0], [ 0 0], [0 1], [ 0 -1] ] - sage: K = Cone([(1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1)]) - sage: all( c[i][j] >= 0 for c in K.cross_positive_operators_gens() - ....: for i in range(c.nrows()) - ....: for j in range(c.ncols()) - ....: if i != j ) + sage: K = Cone([(1,0,0,0), (0,1,0,0), (0,0,1,0), (0,0,0,1)]) + sage: all(c[i][j] >= 0 for c in K.cross_positive_operators_gens() + ....: for i in range(c.nrows()) + ....: for j in range(c.ncols()) + ....: if i != j) True The trivial cone in a trivial space has no cross-positive @@ -5939,13 +5939,13 @@ def cross_positive_operators_gens(self): Every operator is a cross-positive operator on the ambient vector space:: - sage: K = Cone([(1,),(-1,)]) + sage: K = Cone([(1,), (-1,)]) sage: K.is_full_space() True sage: K.cross_positive_operators_gens() [[1], [-1]] - sage: K = Cone([(1,0),(-1,0),(0,1),(0,-1)]) + sage: K = Cone([(1,0), (-1,0), (0,1), (0,-1)]) sage: K.is_full_space() True sage: K.cross_positive_operators_gens() @@ -5957,7 +5957,7 @@ def cross_positive_operators_gens(self): A non-obvious application is to find the cross-positive operators on the right half-plane [Or2018b]_:: - sage: K = Cone([(1,0),(0,1),(0,-1)]) + sage: K = Cone([(1,0), (0,1), (0,-1)]) sage: K.cross_positive_operators_gens() [ [1 0] [-1 0] [0 0] [ 0 0] [0 0] [ 0 0] @@ -5967,13 +5967,13 @@ def cross_positive_operators_gens(self): Cross-positive operators on a subspace are Lyapunov-like and vice-versa:: - sage: K = Cone([(1,0),(-1,0),(0,1),(0,-1)]) + sage: K = Cone([(1,0), (-1,0), (0,1), (0,-1)]) sage: K.is_full_space() True - sage: lls = span( vector(l.list()) - ....: for l in K.lyapunov_like_basis() ) - sage: cs = span( vector(c.list()) - ....: for c in K.cross_positive_operators_gens() ) + sage: lls = span(vector(l.list()) + ....: for l in K.lyapunov_like_basis()) + sage: cs = span(vector(c.list()) + ....: for c in K.cross_positive_operators_gens()) sage: cs == lls True @@ -5984,7 +5984,7 @@ def cross_positive_operators_gens(self): sage: K = random_cone(max_ambient_dim=3) sage: cp_gens = K.cross_positive_operators_gens() - sage: all( L.is_cross_positive_on(K) for L in cp_gens ) + sage: all(L.is_cross_positive_on(K) for L in cp_gens) True The lineality space of the cone of cross-positive operators is @@ -5994,10 +5994,10 @@ def cross_positive_operators_gens(self): sage: L = ToricLattice(K.lattice_dim()**2) sage: cp_gens = K.cross_positive_operators_gens() sage: cp_cone = Cone((g.list() for g in cp_gens), - ....: lattice=L, - ....: check=False) - sage: ll_basis = ( vector(l.list()) - ....: for l in K.lyapunov_like_basis() ) + ....: lattice=L, + ....: check=False) + sage: ll_basis = (vector(l.list()) + ....: for l in K.lyapunov_like_basis()) sage: lls = L.vector_space().span(ll_basis) sage: cp_cone.linear_subspace() == lls True @@ -6058,17 +6058,17 @@ def cross_positive_operators_gens(self): sage: K = random_cone(max_ambient_dim=3) sage: L = ToricLattice(K.lattice_dim()**2) - sage: p = SymmetricGroup(K.lattice_dim()).random_element().matrix() - sage: pK = Cone(( p*k for k in K ), K.lattice(), check=False) - sage: cp_gens = pK.cross_positive_operators_gens() - sage: actual = Cone((g.list() for g in cp_gens), + sage: p = SymmetricGroup(K.lattice_dim()).random_element().matrix() # optional - sage.groups + sage: pK = Cone((p*k for k in K), K.lattice(), check=False) # optional - sage.groups + sage: cp_gens = pK.cross_positive_operators_gens() # optional - sage.groups + sage: actual = Cone((g.list() for g in cp_gens), # optional - sage.groups ....: lattice=L, ....: check=False) sage: cp_gens = K.cross_positive_operators_gens() - sage: expected = Cone(((p*g*p.inverse()).list() for g in cp_gens), + sage: expected = Cone(((p*g*p.inverse()).list() for g in cp_gens), # optional - sage.groups ....: lattice=L, ....: check=False) - sage: actual.is_equivalent(expected) + sage: actual.is_equivalent(expected) # optional - sage.groups True An operator is cross-positive on a cone if and only if its @@ -6173,7 +6173,7 @@ def Z_operators_gens(self): sage: K = random_cone(max_ambient_dim=3) sage: Z_gens = K.Z_operators_gens() - sage: all( L.is_Z_operator_on(K) for L in Z_gens ) + sage: all(L.is_Z_operator_on(K) for L in Z_gens) True """ return [ -cp for cp in self.cross_positive_operators_gens() ] @@ -6477,7 +6477,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, It is an error to request a non-strictly-convex trivial cone:: - sage: L = ToricLattice(0,"L") + sage: L = ToricLattice(0, "L") sage: random_cone(lattice=L, strictly_convex=False) Traceback (most recent call last): ... @@ -6493,7 +6493,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, But fine to ask for a strictly convex trivial cone:: - sage: L = ToricLattice(0,"L") + sage: L = ToricLattice(0, "L") sage: random_cone(lattice=L, strictly_convex=True) 0-d cone in 0-d lattice L diff --git a/src/sage/geometry/fan.py b/src/sage/geometry/fan.py index cd8041262a4..a3e03717da9 100644 --- a/src/sage/geometry/fan.py +++ b/src/sage/geometry/fan.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.graphs sage.combinat r""" Rational polyhedral fans @@ -503,12 +503,12 @@ def Fan(cones, rays=None, lattice=None, check=True, normalize=True, sage: fan = Fan([c1, c2], allow_arrangement=True) sage: fan.ngenerating_cones() 7 - sage: fan.plot() # optional - sage.plot + sage: fan.plot() # optional - sage.plot Graphics3d Object Cones of different dimension:: - sage: c1 = Cone([(1,0),(0,1)]) + sage: c1 = Cone([(1,0), (0,1)]) sage: c2 = Cone([(2,1)]) sage: c3 = Cone([(-1,-2)]) sage: fan = Fan([c1, c2, c3], allow_arrangement=True) @@ -523,7 +523,7 @@ def Fan(cones, rays=None, lattice=None, check=True, normalize=True, sage: c3 = Cone([[0, 1, 1], [1, 0, 1], [0, -1, 1], [-1, 0, 1]]) sage: c1 = Cone([[0, 0, 1]]) sage: fan1 = Fan([c1, c3], allow_arrangement=True) - sage: fan1.plot() # optional - sage.plot + sage: fan1.plot() # optional - sage.plot Graphics3d Object A 3-d cone and two 2-d cones:: @@ -1615,7 +1615,7 @@ def support_contains(self, *args): True sage: f.support_contains((-1,0)) False - sage: f.support_contains(f.lattice().dual()(1,0)) #random output (warning) + sage: f.support_contains(f.lattice().dual()(1,0)) # random output (warning) False sage: f.support_contains(f.lattice().dual()(1,0)) False @@ -1623,9 +1623,9 @@ def support_contains(self, *args): False sage: f.support_contains(0) # 0 converts to the origin in the lattice True - sage: f.support_contains(1/2, sqrt(3)) + sage: f.support_contains(1/2, sqrt(3)) # optional - sage.symbolic True - sage: f.support_contains(-1/2, sqrt(3)) + sage: f.support_contains(-1/2, sqrt(3)) # optional - sage.symbolic False """ if len(args) == 1: @@ -1666,10 +1666,10 @@ def cartesian_product(self, other, lattice=None): EXAMPLES:: sage: K = ToricLattice(1, 'K') - sage: fan1 = Fan([[0],[1]],[(1,),(-1,)], lattice=K) + sage: fan1 = Fan([[0],[1]], [(1,),(-1,)], lattice=K) sage: L = ToricLattice(2, 'L') - sage: fan2 = Fan(rays=[(1,0),(0,1),(-1,-1)], - ....: cones=[[0,1],[1,2],[2,0]], lattice=L) + sage: fan2 = Fan(rays=[(1,0), (0,1), (-1,-1)], + ....: cones=[[0,1], [1,2], [2,0]], lattice=L) sage: fan1.cartesian_product(fan2) Rational polyhedral fan in 3-d lattice K+L sage: _.ngenerating_cones() @@ -1731,14 +1731,14 @@ def common_refinement(self, other): Refining a fan with itself gives itself:: - sage: F0 = Fan2d([(1,0),(0,1),(-1,0),(0,-1)]) + sage: F0 = Fan2d([(1,0), (0,1), (-1,0), (0,-1)]) sage: F0.common_refinement(F0) == F0 True A more complex example with complete fans:: - sage: F1 = Fan([[0],[1]],[(1,),(-1,)]) - sage: F2 = Fan2d([(1,0),(1,1),(0,1),(-1,0),(0,-1)]) + sage: F1 = Fan([[0],[1]], [(1,),(-1,)]) + sage: F2 = Fan2d([(1,0), (1,1), (0,1), (-1,0), (0,-1)]) sage: F3 = F2.cartesian_product(F1) sage: F4 = F1.cartesian_product(F2) sage: FF = F3.common_refinement(F4) @@ -1751,8 +1751,8 @@ def common_refinement(self, other): An example with two non-complete fans with the same support:: - sage: F5 = Fan2d([(1,0),(1,2),(0,1)]) - sage: F6 = Fan2d([(1,0),(2,1),(0,1)]) + sage: F5 = Fan2d([(1,0), (1,2), (0,1)]) + sage: F6 = Fan2d([(1,0), (2,1), (0,1)]) sage: F5.common_refinement(F6).ngenerating_cones() 3 @@ -1995,7 +1995,7 @@ def cone_containing(self, *points): TESTS:: sage: fan = Fan(cones=[(0,1,2,3), (0,1,4)], - ....: rays=[(1,1,1), (1,-1,1), (1,-1,-1), (1,1,-1), (0,0,1)]) + ....: rays=[(1,1,1), (1,-1,1), (1,-1,-1), (1,1,-1), (0,0,1)]) sage: fan.cone_containing(0).rays() N(1, 1, 1) in 3-d lattice N @@ -2508,18 +2508,18 @@ def vertex_graph(self): EXAMPLES:: - sage: dP8 = toric_varieties.dP8() # optional - palp sage.graphs - sage: g = dP8.fan().vertex_graph(); g # optional - palp sage.graphs + sage: dP8 = toric_varieties.dP8() # optional - palp sage.graphs + sage: g = dP8.fan().vertex_graph(); g # optional - palp sage.graphs Graph on 4 vertices - sage: set(dP8.fan(1)) == set(g.vertices(sort=False)) # optional - palp sage.graphs + sage: set(dP8.fan(1)) == set(g.vertices(sort=False)) # optional - palp sage.graphs True sage: g.edge_labels() # all edge labels the same since every cone is smooth # optional - palp sage.graphs [(1, 0), (1, 0), (1, 0), (1, 0)] - sage: g = toric_varieties.Cube_deformation(10).fan().vertex_graph() # optional - sage.graphs - sage: g.automorphism_group().order() # optional - sage.graphs sage.groups + sage: g = toric_varieties.Cube_deformation(10).fan().vertex_graph() # optional - sage.graphs + sage: g.automorphism_group().order() # optional - sage.graphs sage.groups 48 - sage: g.automorphism_group(edge_labels=True).order() # optional - sage.graphs sage.groups + sage: g.automorphism_group(edge_labels=True).order() # optional - sage.graphs sage.groups 4 """ from sage.geometry.cone import classify_cone_2d @@ -2680,7 +2680,7 @@ def is_isomorphic(self, other): sage: rays = ((1, 1), (0, 1), (-1, -1), (1, 0)) sage: cones = [(0,1), (1,2), (2,3), (3,0)] sage: fan1 = Fan(cones, rays) - sage: m = matrix([[-2,3],[1,-1]]) + sage: m = matrix([[-2,3], [1,-1]]) sage: fan2 = Fan(cones, [vector(r)*m for r in rays]) sage: fan1.is_isomorphic(fan2) True @@ -2782,7 +2782,7 @@ def isomorphism(self, other): sage: rays = ((1, 1), (0, 1), (-1, -1), (3, 1)) sage: cones = [(0,1), (1,2), (2,3), (3,0)] sage: fan1 = Fan(cones, rays) - sage: m = matrix([[-2,3],[1,-1]]) + sage: m = matrix([[-2,3], [1,-1]]) sage: fan2 = Fan(cones, [vector(r)*m for r in rays]) sage: fan1.isomorphism(fan2) @@ -3173,7 +3173,8 @@ def primitive_collections(self): EXAMPLES:: - sage: fan = Fan([[0,1,3],[3,4],[2,0],[1,2,4]], [(-3, -2, 1), (0, 0, 1), (3, -2, 1), (-1, -1, 1), (1, -1, 1)]) + sage: fan = Fan([[0,1,3], [3,4], [2,0], [1,2,4]], + ....: [(-3, -2, 1), (0, 0, 1), (3, -2, 1), (-1, -1, 1), (1, -1, 1)]) sage: fan.primitive_collections() [frozenset({0, 4}), frozenset({2, 3}), @@ -3233,9 +3234,11 @@ def Stanley_Reisner_ideal(self, ring): EXAMPLES:: - sage: fan = Fan([[0,1,3],[3,4],[2,0],[1,2,4]], [(-3, -2, 1), (0, 0, 1), (3, -2, 1), (-1, -1, 1), (1, -1, 1)]) - sage: fan.Stanley_Reisner_ideal( PolynomialRing(QQ,5,'A, B, C, D, E') ) - Ideal (A*E, C*D, A*B*C, B*D*E) of Multivariate Polynomial Ring in A, B, C, D, E over Rational Field + sage: fan = Fan([[0,1,3], [3,4], [2,0], [1,2,4]], + ....: [(-3, -2, 1), (0, 0, 1), (3, -2, 1), (-1, -1, 1), (1, -1, 1)]) + sage: fan.Stanley_Reisner_ideal(PolynomialRing(QQ, 5, 'A, B, C, D, E')) + Ideal (A*E, C*D, A*B*C, B*D*E) of + Multivariate Polynomial Ring in A, B, C, D, E over Rational Field """ generators_indices = self.primitive_collections() SR = ring.ideal([ prod([ ring.gen(i) for i in sr]) for sr in generators_indices ]) @@ -3257,9 +3260,11 @@ def linear_equivalence_ideal(self, ring): EXAMPLES:: - sage: fan = Fan([[0,1,3],[3,4],[2,0],[1,2,4]], [(-3, -2, 1), (0, 0, 1), (3, -2, 1), (-1, -1, 1), (1, -1, 1)]) - sage: fan.linear_equivalence_ideal( PolynomialRing(QQ,5,'A, B, C, D, E') ) - Ideal (-3*A + 3*C - D + E, -2*A - 2*C - D - E, A + B + C + D + E) of Multivariate Polynomial Ring in A, B, C, D, E over Rational Field + sage: fan = Fan([[0,1,3],[3,4],[2,0],[1,2,4]], + ....: [(-3, -2, 1), (0, 0, 1), (3, -2, 1), (-1, -1, 1), (1, -1, 1)]) + sage: fan.linear_equivalence_ideal(PolynomialRing(QQ, 5, 'A, B, C, D, E')) + Ideal (-3*A + 3*C - D + E, -2*A - 2*C - D - E, A + B + C + D + E) of + Multivariate Polynomial Ring in A, B, C, D, E over Rational Field """ gens = [] for d in range(0,self.dim()): @@ -3300,7 +3305,8 @@ def oriented_boundary(self, cone): sage: fan = toric_varieties.P(3).fan() # optional - palp sage: cone = fan(2)[0] # optional - palp sage: bdry = fan.oriented_boundary(cone); bdry # optional - palp - -1-d cone of Rational polyhedral fan in 3-d lattice N + 1-d cone of Rational polyhedral fan in 3-d lattice N + -1-d cone of Rational polyhedral fan in 3-d lattice N + + 1-d cone of Rational polyhedral fan in 3-d lattice N sage: bdry[0] # optional - palp (-1, 1-d cone of Rational polyhedral fan in 3-d lattice N) sage: bdry[1] # optional - palp @@ -3482,22 +3488,23 @@ def complex(self, base_ring=ZZ, extended=False): EXAMPLES:: - sage: fan = toric_varieties.P(3).fan() # optional - palp - sage: K_normal = fan.complex(); K_normal # optional - palp + sage: fan = toric_varieties.P(3).fan() # optional - palp + sage: K_normal = fan.complex(); K_normal # optional - palp Chain complex with at most 4 nonzero terms over Integer Ring - sage: K_normal.homology() # optional - palp + sage: K_normal.homology() # optional - palp {0: Z, 1: 0, 2: 0, 3: 0} - sage: K_extended = fan.complex(extended=True); K_extended # optional - palp + sage: K_extended = fan.complex(extended=True); K_extended # optional - palp Chain complex with at most 5 nonzero terms over Integer Ring - sage: K_extended.homology() # optional - palp + sage: K_extended.homology() # optional - palp {-1: 0, 0: 0, 1: 0, 2: 0, 3: 0} Homology computations are much faster over `\QQ` if you do not care about the torsion coefficients:: - sage: toric_varieties.P2_123().fan().complex(extended=True, base_ring=QQ) # optional - palp + sage: toric_varieties.P2_123().fan().complex(extended=True, # optional - palp + ....: base_ring=QQ) Chain complex with at most 4 nonzero terms over Rational Field - sage: _.homology() # optional - palp + sage: _.homology() # optional - palp {-1: Vector space of dimension 0 over Rational Field, 0: Vector space of dimension 0 over Rational Field, 1: Vector space of dimension 0 over Rational Field, @@ -3525,15 +3532,15 @@ def complex(self, base_ring=ZZ, extended=False): Things get more complicated for non-complete fans:: sage: fan = Fan([Cone([(1,1,1)]), - ....: Cone([(1,0,0),(0,1,0)]), - ....: Cone([(-1,0,0),(0,-1,0),(0,0,-1)])]) + ....: Cone([(1,0,0), (0,1,0)]), + ....: Cone([(-1,0,0), (0,-1,0), (0,0,-1)])]) sage: fan.complex().homology() {0: 0, 1: 0, 2: Z x Z, 3: 0} - sage: fan = Fan([Cone([(1,0,0),(0,1,0)]), - ....: Cone([(-1,0,0),(0,-1,0),(0,0,-1)])]) + sage: fan = Fan([Cone([(1,0,0), (0,1,0)]), + ....: Cone([(-1,0,0), (0,-1,0), (0,0,-1)])]) sage: fan.complex().homology() {0: 0, 1: 0, 2: Z, 3: 0} - sage: fan = Fan([Cone([(-1,0,0),(0,-1,0),(0,0,-1)])]) + sage: fan = Fan([Cone([(-1,0,0), (0,-1,0), (0,0,-1)])]) sage: fan.complex().homology() {0: 0, 1: 0, 2: 0, 3: 0} """ diff --git a/src/sage/geometry/fan_isomorphism.py b/src/sage/geometry/fan_isomorphism.py index c3997f75b5d..0eb3b13d21c 100644 --- a/src/sage/geometry/fan_isomorphism.py +++ b/src/sage/geometry/fan_isomorphism.py @@ -216,7 +216,7 @@ def find_isomorphism(fan1, fan2, check=False): sage: fan2 = Fan(cones, [vector(r)*m for r in rays]) sage: from sage.geometry.fan_isomorphism import find_isomorphism - sage: find_isomorphism(fan1, fan2, check=True) + sage: find_isomorphism(fan1, fan2, check=True) # optional - sage.graphs Fan morphism defined by the matrix [-2 3] [ 1 -1] diff --git a/src/sage/geometry/fan_morphism.py b/src/sage/geometry/fan_morphism.py index e94e2cce8c0..cb8105f42fc 100644 --- a/src/sage/geometry/fan_morphism.py +++ b/src/sage/geometry/fan_morphism.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.graphs, sage.combinat r""" Morphisms between toric lattices compatible with fans @@ -360,7 +361,7 @@ def _RISGIS(self): sage: normal = NormalFan(diamond) sage: N = face.lattice() sage: fm = FanMorphism(identity_matrix(2), - ....: normal, face, subdivide=True) + ....: normal, face, subdivide=True) sage: fm._RISGIS() (frozenset({2}), frozenset({3}), @@ -774,7 +775,7 @@ def _support_error(self): sage: quadrant = Fan([quadrant]) sage: quadrant_bl = quadrant.subdivide([(1,1)]) sage: fm = FanMorphism(identity_matrix(2), - ....: quadrant, quadrant_bl, check=False) + ....: quadrant, quadrant_bl, check=False) Now we report that the morphism is invalid:: @@ -861,8 +862,8 @@ def _validate(self): TESTS:: - sage: trivialfan2 = Fan([],[],lattice=ToricLattice(2)) - sage: trivialfan3 = Fan([],[],lattice=ToricLattice(3)) + sage: trivialfan2 = Fan([], [], lattice=ToricLattice(2)) + sage: trivialfan3 = Fan([], [], lattice=ToricLattice(3)) sage: FanMorphism(zero_matrix(2,3), trivialfan2, trivialfan3) Fan morphism defined by the matrix [0 0 0] @@ -983,7 +984,7 @@ def image_cone(self, cone): sage: normal = NormalFan(diamond) sage: N = face.lattice() sage: fm = FanMorphism(identity_matrix(2), - ....: normal, face, subdivide=True) + ....: normal, face, subdivide=True) sage: fm.image_cone(Cone([(1,0)])) 1-d cone of Rational polyhedral fan in 2-d lattice N sage: fm.image_cone(Cone([(1,1)])) @@ -1855,8 +1856,8 @@ def factor(self): sage: phi_i.codomain_fan() is phi.codomain_fan() # optional - palp True - sage: trivialfan2 = Fan([],[],lattice=ToricLattice(2)) - sage: trivialfan3 = Fan([],[],lattice=ToricLattice(3)) + sage: trivialfan2 = Fan([], [], lattice=ToricLattice(2)) + sage: trivialfan3 = Fan([], [], lattice=ToricLattice(3)) sage: f = FanMorphism(zero_matrix(2,3), trivialfan2, trivialfan3) sage: [phi.matrix().dimensions() for phi in f.factor()] [(0, 3), (0, 0), (2, 0)] diff --git a/src/sage/geometry/hasse_diagram.py b/src/sage/geometry/hasse_diagram.py index eeed5f560d9..f40560f30fe 100644 --- a/src/sage/geometry/hasse_diagram.py +++ b/src/sage/geometry/hasse_diagram.py @@ -104,11 +104,9 @@ def lattice_from_incidences(atom_to_coatoms, coatom_to_atoms, and we can compute the lattice as :: sage: from sage.geometry.cone import lattice_from_incidences - sage: L = lattice_from_incidences( - ....: atom_to_coatoms, coatom_to_atoms) - sage: L + sage: L = lattice_from_incidences(atom_to_coatoms, coatom_to_atoms); L # optional - sage.graphs Finite lattice containing 8 elements with distinguished linear extension - sage: for level in L.level_sets(): print(level) + sage: for level in L.level_sets(): print(level) # optional - sage.graphs [((), (0, 1, 2))] [((0,), (0, 1)), ((1,), (0, 2)), ((2,), (1, 2))] [((0, 1), (0,)), ((0, 2), (1,)), ((1, 2), (2,))] diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_interface.py b/src/sage/geometry/hyperbolic_space/hyperbolic_interface.py index 38f6f4266af..d1f6d3cce44 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_interface.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_interface.py @@ -52,6 +52,8 @@ # https://www.gnu.org/licenses/ # ********************************************************************** +import sage.geometry.abc + from sage.structure.unique_representation import UniqueRepresentation from sage.structure.parent import Parent from sage.categories.sets_cat import Sets @@ -76,7 +78,7 @@ def HyperbolicSpace(n): raise NotImplementedError("currently only implemented in dimension 2") -class HyperbolicPlane(Parent, UniqueRepresentation): +class HyperbolicPlane(sage.geometry.abc.HyperbolicSpace, UniqueRepresentation): r""" The hyperbolic plane `\mathbb{H}^2`. diff --git a/src/sage/geometry/hyperplane_arrangement/arrangement.py b/src/sage/geometry/hyperplane_arrangement/arrangement.py index b740ef79956..a9bdc1c83e4 100644 --- a/src/sage/geometry/hyperplane_arrangement/arrangement.py +++ b/src/sage/geometry/hyperplane_arrangement/arrangement.py @@ -60,41 +60,42 @@ The default base field is `\QQ`, the rational numbers. Finite fields are also supported:: - sage: H. = HyperplaneArrangements(GF(5)) # optional - sage.libs.pari - sage: a = H([(1,2,3), 4], [(5,6,7), 8]); a # optional - sage.libs.pari + sage: H. = HyperplaneArrangements(GF(5)) # optional - sage.rings.finite_rings + sage: a = H([(1,2,3), 4], [(5,6,7), 8]); a # optional - sage.rings.finite_rings Arrangement Number fields are also possible:: - sage: x = var('x') - sage: NF. = NumberField(x**4 - 5*x**2 + 5, embedding=1.90) # optional - sage.rings.number_field - sage: H. = HyperplaneArrangements(NF) # optional - sage.rings.number_field - sage: A = H([[(-a**3 + 3*a, -a**2 + 4), 1], [(a**3 - 4*a, -1), 1], # optional - sage.rings.number_field + sage: x = polygen(QQ, 'x') + sage: NF. = NumberField(x**4 - 5*x**2 + 5, embedding=1.90) # optional - sage.rings.number_field + sage: H. = HyperplaneArrangements(NF) # optional - sage.rings.number_field + sage: A = H([[(-a**3 + 3*a, -a**2 + 4), 1], [(a**3 - 4*a, -1), 1], # optional - sage.rings.number_field ....: [(0, 2*a**2 - 6), 1], [(-a**3 + 4*a, -1), 1], ....: [(a**3 - 3*a, -a**2 + 4), 1]]) - sage: A # optional - sage.rings.number_field + sage: A # optional - sage.rings.number_field Arrangement of 5 hyperplanes of dimension 2 and rank 2 - sage: A.base_ring() # optional - sage.rings.number_field - Number Field in a with defining polynomial x^4 - 5*x^2 + 5 with a = 1.902113032590308? + sage: A.base_ring() # optional - sage.rings.number_field + Number Field in a with defining polynomial x^4 - 5*x^2 + 5 + with a = 1.902113032590308? Notation (iii): a list or tuple of hyperplanes:: - sage: H. = HyperplaneArrangements(GF(5)) # optional - sage.libs.pari - sage: k = [x+i for i in range(4)]; k # optional - sage.libs.pari + sage: H. = HyperplaneArrangements(GF(5)) # optional - sage.rings.finite_rings + sage: k = [x+i for i in range(4)]; k # optional - sage.rings.finite_rings [Hyperplane x + 0*y + 0*z + 0, Hyperplane x + 0*y + 0*z + 1, Hyperplane x + 0*y + 0*z + 2, Hyperplane x + 0*y + 0*z + 3] - sage: H(k) # optional - sage.libs.pari + sage: H(k) # optional - sage.rings.finite_rings Arrangement Notation (iv): using the library of arrangements:: - sage: hyperplane_arrangements.braid(4) + sage: hyperplane_arrangements.braid(4) # optional - sage.graphs Arrangement of 6 hyperplanes of dimension 4 and rank 3 - sage: hyperplane_arrangements.semiorder(3) + sage: hyperplane_arrangements.semiorder(3) # optional - sage.combinat Arrangement of 6 hyperplanes of dimension 3 and rank 2 - sage: hyperplane_arrangements.graphical(graphs.PetersenGraph()) + sage: hyperplane_arrangements.graphical(graphs.PetersenGraph()) # optional - sage.graphs Arrangement of 15 hyperplanes of dimension 10 and rank 9 - sage: hyperplane_arrangements.Ish(5) + sage: hyperplane_arrangements.Ish(5) # optional - sage.combinat Arrangement of 20 hyperplanes of dimension 5 and rank 4 Notation (v): from the bounding hyperplanes of a polyhedron:: @@ -106,23 +107,23 @@ New arrangements from old:: - sage: a = hyperplane_arrangements.braid(3) - sage: b = a.add_hyperplane([4, 1, 2, 3]) - sage: b + sage: a = hyperplane_arrangements.braid(3) # optional - sage.graphs + sage: b = a.add_hyperplane([4, 1, 2, 3]) # optional - sage.graphs + sage: b # optional - sage.graphs Arrangement - sage: c = b.deletion([4, 1, 2, 3]) - sage: a == c + sage: c = b.deletion([4, 1, 2, 3]) # optional - sage.graphs + sage: a == c # optional - sage.graphs True - sage: a = hyperplane_arrangements.braid(3) - sage: b = a.union(hyperplane_arrangements.semiorder(3)) - sage: b == a | hyperplane_arrangements.semiorder(3) # alternate syntax + sage: a = hyperplane_arrangements.braid(3) # optional - sage.graphs sage.combinat + sage: b = a.union(hyperplane_arrangements.semiorder(3)) # optional - sage.graphs sage.combinat + sage: b == a | hyperplane_arrangements.semiorder(3) # alternate syntax # optional - sage.graphs sage.combinat True - sage: b == hyperplane_arrangements.Catalan(3) + sage: b == hyperplane_arrangements.Catalan(3) # optional - sage.graphs sage.combinat True - - sage: a + sage: a # optional - sage.graphs sage.combinat Arrangement + sage: a = hyperplane_arrangements.coordinate(4) sage: h = a.hyperplanes()[0] sage: b = a.restriction(h) @@ -138,24 +139,24 @@ normal space (actually, it is a bit more complicated over finite fields):: - sage: a = hyperplane_arrangements.braid(4); a + sage: a = hyperplane_arrangements.braid(4); a # optional - sage.graphs Arrangement of 6 hyperplanes of dimension 4 and rank 3 - sage: a.is_essential() + sage: a.is_essential() # optional - sage.graphs False - sage: a.rank() < a.dimension() # double-check + sage: a.rank() < a.dimension() # double-check # optional - sage.graphs True - sage: a.essentialization() + sage: a.essentialization() # optional - sage.graphs Arrangement of 6 hyperplanes of dimension 3 and rank 3 The connected components of the complement of the hyperplanes of an arrangement in `\RR^n` are called the *regions* of the arrangement:: - sage: a = hyperplane_arrangements.semiorder(3) - sage: b = a.essentialization(); b + sage: a = hyperplane_arrangements.semiorder(3) # optional - sage.combinat + sage: b = a.essentialization(); b # optional - sage.combinat Arrangement of 6 hyperplanes of dimension 2 and rank 2 - sage: b.n_regions() + sage: b.n_regions() # optional - sage.combinat 19 - sage: b.regions() + sage: b.regions() # optional - sage.combinat (A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 6 vertices, A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices, A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices, @@ -183,9 +184,9 @@ A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices, A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices, A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices) - sage: b.n_bounded_regions() + sage: b.n_bounded_regions() # optional - sage.combinat 7 - sage: a.unbounded_regions() + sage: a.unbounded_regions() # optional - sage.combinat (A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex, 2 rays, 1 line, A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 3 vertices, 1 ray, 1 line, A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex, 2 rays, 1 line, @@ -202,13 +203,13 @@ The distance between regions is defined as the number of hyperplanes separating them. For example:: - sage: r1 = b.regions()[0] - sage: r2 = b.regions()[1] - sage: b.distance_between_regions(r1, r2) + sage: r1 = b.regions()[0] # optional - sage.combinat + sage: r2 = b.regions()[1] # optional - sage.combinat + sage: b.distance_between_regions(r1, r2) # optional - sage.combinat 1 - sage: [hyp for hyp in b if b.is_separating_hyperplane(r1, r2, hyp)] + sage: [hyp for hyp in b if b.is_separating_hyperplane(r1, r2, hyp)] # optional - sage.combinat [Hyperplane 2*t1 + t2 + 1] - sage: b.distance_enumerator(r1) # generating function for distances from r1 + sage: b.distance_enumerator(r1) # generating function for distances from r1 # optional - sage.combinat 6*x^3 + 6*x^2 + 6*x + 1 .. NOTE:: @@ -222,11 +223,11 @@ ordered by reverse inclusion. It includes the ambient space of the arrangement (as the intersection over the empty set):: - sage: a = hyperplane_arrangements.braid(3) - sage: p = a.intersection_poset() - sage: p.is_ranked() + sage: a = hyperplane_arrangements.braid(3) # optional - sage.graphs + sage: p = a.intersection_poset() # optional - sage.graphs + sage: p.is_ranked() # optional - sage.graphs True - sage: p.order_polytope() + sage: p.order_polytope() # optional - sage.graphs A 5-dimensional polyhedron in ZZ^5 defined as the convex hull of 10 vertices The characteristic polynomial is a basic invariant of a hyperplane @@ -262,12 +263,12 @@ Miscellaneous methods (see documentation for an explanation):: sage: a = hyperplane_arrangements.semiorder(3) - sage: a.has_good_reduction(5) + sage: a.has_good_reduction(5) # optional - sage.rings.finite_rings True - sage: b = a.change_ring(GF(5)) # optional - sage.libs.pari + sage: b = a.change_ring(GF(5)) # optional - sage.rings.finite_rings sage: pa = a.intersection_poset() - sage: pb = b.intersection_poset() # optional - sage.libs.pari - sage: pa.is_isomorphic(pb) # optional - sage.libs.pari + sage: pb = b.intersection_poset() # optional - sage.rings.finite_rings + sage: pa.is_isomorphic(pb) # optional - sage.rings.finite_rings True sage: a.face_vector() (0, 12, 30, 19) @@ -393,13 +394,13 @@ def __init__(self, parent, hyperplanes, check=True, backend=None): It is possible to specify a backend for polyhedral computations:: - sage: R. = QuadraticField(5) # optional - sage.rings.number_field - sage: H = HyperplaneArrangements(R, names='xyz') # optional - sage.rings.number_field - sage: x, y, z = H.gens() # optional - sage.rings.number_field - sage: A = H(sqrt5*x + 2*y + 3*z, backend='normaliz') # optional - sage.rings.number_field - sage: A.backend() # optional - sage.rings.number_field + sage: R. = QuadraticField(5) # optional - sage.rings.number_field + sage: H = HyperplaneArrangements(R, names='xyz') # optional - sage.rings.number_field + sage: x, y, z = H.gens() # optional - sage.rings.number_field + sage: A = H(sqrt5*x + 2*y + 3*z, backend='normaliz') # optional - sage.rings.number_field + sage: A.backend() # optional - sage.rings.number_field 'normaliz' - sage: A.regions()[0].backend() # optional - pynormaliz # optional - sage.rings.number_field + sage: A.regions()[0].backend() # optional - pynormaliz sage.rings.number_field 'normaliz' """ super().__init__(parent) @@ -423,8 +424,8 @@ def _first_ngens(self, n): EXAMPLES:: - sage: a. = hyperplane_arrangements.braid(3) # indirect doctest - sage: (x, y) == a._first_ngens(2) + sage: a. = hyperplane_arrangements.braid(3) # indirect doctest # optional - sage.graphs + sage: (x, y) == a._first_ngens(2) # optional - sage.graphs True """ return self.parent()._first_ngens(n) @@ -569,14 +570,14 @@ def rank(self): sage: A.rank() 2 - sage: B = hyperplane_arrangements.braid(3) - sage: B.hyperplanes() + sage: B = hyperplane_arrangements.braid(3) # optional - sage.graphs + sage: B.hyperplanes() # optional - sage.graphs (Hyperplane 0*t0 + t1 - t2 + 0, Hyperplane t0 - t1 + 0*t2 + 0, Hyperplane t0 + 0*t1 - t2 + 0) - sage: B.dimension() + sage: B.dimension() # optional - sage.graphs 3 - sage: B.rank() + sage: B.rank() # optional - sage.graphs 2 sage: p = polytopes.simplex(5, project=True) @@ -688,7 +689,7 @@ def plot(self, **kwds): EXAMPLES:: sage: L. = HyperplaneArrangements(QQ) - sage: L(x, y, x+y-2).plot() # optional - sage.plot + sage: L(x, y, x+y-2).plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives """ from sage.geometry.hyperplane_arrangement.plot import plot @@ -719,20 +720,20 @@ def cone(self, variable='t'): EXAMPLES:: - sage: a. = hyperplane_arrangements.semiorder(3) - sage: b = a.cone() - sage: a.characteristic_polynomial().factor() + sage: a. = hyperplane_arrangements.semiorder(3) # optional - sage.combinat + sage: b = a.cone() # optional - sage.combinat + sage: a.characteristic_polynomial().factor() # optional - sage.combinat x * (x^2 - 6*x + 12) - sage: b.characteristic_polynomial().factor() + sage: b.characteristic_polynomial().factor() # optional - sage.combinat (x - 1) * x * (x^2 - 6*x + 12) - sage: a.hyperplanes() + sage: a.hyperplanes() # optional - sage.combinat (Hyperplane 0*x + y - z - 1, Hyperplane 0*x + y - z + 1, Hyperplane x - y + 0*z - 1, Hyperplane x - y + 0*z + 1, Hyperplane x + 0*y - z - 1, Hyperplane x + 0*y - z + 1) - sage: b.hyperplanes() + sage: b.hyperplanes() # optional - sage.combinat (Hyperplane -t + 0*x + y - z + 0, Hyperplane -t + x - y + 0*z + 0, Hyperplane -t + x + 0*y - z + 0, @@ -780,21 +781,21 @@ def intersection_poset(self, element_label="int"): of hyperplanes of the arrangement. :: sage: A = hyperplane_arrangements.coordinate(2) - sage: L = A.intersection_poset(); L + sage: L = A.intersection_poset(); L # optional - sage.combinat Finite poset containing 4 elements - sage: sorted(L) + sage: sorted(L) # optional - sage.combinat [0, 1, 2, 3] - sage: L.level_sets() + sage: L.level_sets() # optional - sage.combinat [[0], [1, 2], [3]] :: - sage: A = hyperplane_arrangements.semiorder(3) - sage: L = A.intersection_poset(); L + sage: A = hyperplane_arrangements.semiorder(3) # optional - sage.combinat + sage: L = A.intersection_poset(); L # optional - sage.combinat Finite poset containing 19 elements - sage: sorted(L) + sage: sorted(L) # optional - sage.combinat [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18] - sage: [sorted(level_set) for level_set in L.level_sets()] + sage: [sorted(level_set) for level_set in L.level_sets()] # optional - sage.combinat [[0], [1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]] By passing the argument ``element_label="subset"``, each element of the @@ -802,9 +803,9 @@ def intersection_poset(self, element_label="int"): whose intersection is said element. The index of a hyperplane is its index in ``self.hyperplanes()``. :: - sage: A = hyperplane_arrangements.semiorder(3) - sage: L = A.intersection_poset(element_label='subset') - sage: [sorted(level, key=sorted) for level in L.level_sets()] + sage: A = hyperplane_arrangements.semiorder(3) # optional - sage.combinat + sage: L = A.intersection_poset(element_label='subset') # optional - sage.combinat + sage: [sorted(level, key=sorted) for level in L.level_sets()] # optional - sage.combinat [[{}], [{0}, {1}, {2}, {3}, {4}, {5}], [{0, 2}, {0, 3}, {0, 4}, {0, 5}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {2, 4}, {2, 5}, {3, 4}, {3, 5}]] @@ -812,31 +813,32 @@ def intersection_poset(self, element_label="int"): :: sage: H. = HyperplaneArrangements(QQ) - sage: A = H((y , (y-1) , (y+1) , (x - y) , (x + y))) - sage: L = A.intersection_poset(element_label='subset') - sage: sorted(L, key=sorted) + sage: A = H((y, y-1, y+1, x-y, x+y)) + sage: L = A.intersection_poset(element_label='subset') # optional - sage.combinat + sage: sorted(L, key=sorted) # optional - sage.combinat [{}, {0}, {0, 3}, {0, 4}, {1}, {1, 3, 4}, {2}, {2, 3}, {2, 4}, {3}, {4}] One can instead use affine subspaces as elements, which is what is used to compute the poset in the first place:: sage: A = hyperplane_arrangements.coordinate(2) - sage: L = A.intersection_poset(element_label='subspace'); L + sage: L = A.intersection_poset(element_label='subspace'); L # optional - sage.combinat Finite poset containing 4 elements - sage: sorted(L, key=lambda S: (S.dimension(), S.linear_part().basis_matrix())) + sage: sorted(L, key=lambda S: (S.dimension(), # optional - sage.combinat + ....: S.linear_part().basis_matrix())) [Affine space p + W where: p = (0, 0) W = Vector space of degree 2 and dimension 0 over Rational Field - Basis matrix: - [], Affine space p + W where: + Basis matrix: [], + Affine space p + W where: p = (0, 0) W = Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [0 1], Affine space p + W where: + Basis matrix: [0 1], + Affine space p + W where: p = (0, 0) W = Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [1 0], Affine space p + W where: + Basis matrix: [1 0], + Affine space p + W where: p = (0, 0) W = Vector space of dimension 2 over Rational Field] """ @@ -903,7 +905,7 @@ def _slow_characteristic_polynomial(self): EXAMPLES:: sage: a = hyperplane_arrangements.coordinate(2) - sage: a._slow_characteristic_polynomial() + sage: a._slow_characteristic_polynomial() # optional - sage.combinat x^2 - 2*x + 1 """ from sage.rings.polynomial.polynomial_ring import polygen @@ -1016,9 +1018,9 @@ def deletion(self, hyperplanes): Checks that deletion preserves the backend:: - sage: H = HyperplaneArrangements(QQ,names='xyz') + sage: H = HyperplaneArrangements(QQ, names='xyz') sage: x,y,z = H.gens() - sage: h1,h2 = [1*x+2*y+3*z,3*x+2*y+1*z] + sage: h1,h2 = [1*x+2*y+3*z, 3*x+2*y+1*z] sage: A = H(h1,h2,backend='normaliz') sage: A.deletion(h2).backend() 'normaliz' @@ -1048,20 +1050,20 @@ def restriction(self, hyperplane): EXAMPLES:: - sage: A. = hyperplane_arrangements.braid(4); A + sage: A. = hyperplane_arrangements.braid(4); A # optional - sage.graphs Arrangement of 6 hyperplanes of dimension 4 and rank 3 - sage: H = A[0]; H + sage: H = A[0]; H # optional - sage.graphs Hyperplane 0*u + 0*x + y - z + 0 - sage: R = A.restriction(H); R + sage: R = A.restriction(H); R # optional - sage.graphs Arrangement - sage: D = A.deletion(H); D + sage: D = A.deletion(H); D # optional - sage.graphs Arrangement of 5 hyperplanes of dimension 4 and rank 3 - sage: ca = A.characteristic_polynomial() - sage: cr = R.characteristic_polynomial() - sage: cd = D.characteristic_polynomial() - sage: ca + sage: ca = A.characteristic_polynomial() # optional - sage.graphs + sage: cr = R.characteristic_polynomial() # optional - sage.graphs + sage: cd = D.characteristic_polynomial() # optional - sage.graphs + sage: ca # optional - sage.graphs x^4 - 6*x^3 + 11*x^2 - 6*x - sage: cd - cr + sage: cd - cr # optional - sage.graphs x^4 - 6*x^3 + 11*x^2 - 6*x .. SEEALSO:: @@ -1072,9 +1074,9 @@ def restriction(self, hyperplane): Checks that restriction preserves the backend:: - sage: H = HyperplaneArrangements(QQ,names='xyz') + sage: H = HyperplaneArrangements(QQ, names='xyz') sage: x,y,z = H.gens() - sage: h1,h2 = [1*x+2*y+3*z,3*x+2*y+1*z] + sage: h1,h2 = [1*x+2*y+3*z, 3*x+2*y+1*z] sage: A = H(h1, h2, backend='normaliz') sage: A.restriction(h2).backend() 'normaliz' @@ -1128,16 +1130,16 @@ def change_ring(self, base_ring): sage: H. = HyperplaneArrangements(QQ) sage: A = H([(1,1), 0], [(2,3), -1]) - sage: A.change_ring(FiniteField(2)) # optional - sage.libs.pari + sage: A.change_ring(FiniteField(2)) # optional - sage.rings.finite_rings Arrangement TESTS: Checks that changing the ring preserves the backend:: - sage: H = HyperplaneArrangements(QQ,names='xyz') + sage: H = HyperplaneArrangements(QQ, names='xyz') sage: x,y,z = H.gens() - sage: h1,h2 = [1*x+2*y+3*z,3*x+2*y+1*z] + sage: h1, h2 = [1*x+2*y+3*z, 3*x+2*y+1*z] sage: A = H(h1, h2, backend='normaliz') sage: A.change_ring(RDF).backend() 'normaliz' @@ -1156,16 +1158,16 @@ def n_regions(self): EXAMPLES:: - sage: A = hyperplane_arrangements.semiorder(3) - sage: A.n_regions() + sage: A = hyperplane_arrangements.semiorder(3) # optional - sage.combinat + sage: A.n_regions() # optional - sage.combinat 19 TESTS:: sage: H. = HyperplaneArrangements(QQ) sage: A = H([(1,1), 0], [(2,3), -1], [(4,5), 3]) - sage: B = A.change_ring(FiniteField(7)) # optional - sage.libs.pari - sage: B.n_regions() # optional - sage.libs.pari + sage: B = A.change_ring(FiniteField(7)) # optional - sage.rings.finite_rings + sage: B.n_regions() # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: base field must have characteristic zero @@ -1207,16 +1209,16 @@ def n_bounded_regions(self): EXAMPLES:: - sage: A = hyperplane_arrangements.semiorder(3) - sage: A.n_bounded_regions() + sage: A = hyperplane_arrangements.semiorder(3) # optional - sage.combinat + sage: A.n_bounded_regions() # optional - sage.combinat 7 TESTS:: sage: H. = HyperplaneArrangements(QQ) sage: A = H([(1,1),0], [(2,3),-1], [(4,5),3]) - sage: B = A.change_ring(FiniteField(7)) # optional - sage.libs.pari - sage: B.n_bounded_regions() # optional - sage.libs.pari + sage: B = A.change_ring(FiniteField(7)) # optional - sage.rings.finite_rings + sage: B.n_bounded_regions() # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: base field must have characteristic zero @@ -1246,15 +1248,15 @@ def has_good_reduction(self, p): EXAMPLES:: - sage: a = hyperplane_arrangements.semiorder(3) - sage: a.has_good_reduction(5) # optional - sage.libs.pari + sage: a = hyperplane_arrangements.semiorder(3) # optional - sage.combinat + sage: a.has_good_reduction(5) # optional - sage.combinat sage.rings.finite_rings True - sage: a.has_good_reduction(3) # optional - sage.libs.pari + sage: a.has_good_reduction(3) # optional - sage.combinat sage.rings.finite_rings False - sage: b = a.change_ring(GF(3)) # optional - sage.libs.pari - sage: a.characteristic_polynomial() + sage: b = a.change_ring(GF(3)) # optional - sage.combinat sage.rings.finite_rings + sage: a.characteristic_polynomial() # optional - sage.combinat sage.rings.finite_rings x^3 - 6*x^2 + 12*x - sage: b.characteristic_polynomial() # not equal to that for a # optional - sage.libs.pari + sage: b.characteristic_polynomial() # not equal to that for a # optional - sage.combinat sage.rings.finite_rings x^3 - 6*x^2 + 10*x """ if self.base_ring() != QQ: @@ -1277,11 +1279,11 @@ def is_linear(self): EXAMPLES:: - sage: a = hyperplane_arrangements.semiorder(3) - sage: a.is_linear() + sage: a = hyperplane_arrangements.semiorder(3) # optional - sage.combinat + sage: a.is_linear() # optional - sage.combinat False - sage: b = hyperplane_arrangements.braid(3) - sage: b.is_linear() + sage: b = hyperplane_arrangements.braid(3) # optional - sage.graphs + sage: b.is_linear() # optional - sage.graphs True sage: H. = HyperplaneArrangements(QQ) @@ -1343,8 +1345,8 @@ def is_central(self, certificate=False): EXAMPLES:: - sage: a = hyperplane_arrangements.braid(2) - sage: a.is_central() + sage: a = hyperplane_arrangements.braid(2) # optional - sage.graphs + sage: a.is_central() # optional - sage.graphs True The Catalan arrangement in dimension 3 is not central:: @@ -1355,11 +1357,11 @@ def is_central(self, certificate=False): The empty arrangement in dimension 5 is central:: - sage: H = HyperplaneArrangements(QQ,names=tuple(['x'+str(i) for i in range(7)])) + sage: H = HyperplaneArrangements(QQ, names=tuple(['x'+str(i) for i in range(7)])) sage: c = H() sage: c.is_central(certificate=True) - (True, A 7-dimensional polyhedron in QQ^7 defined as the convex - hull of 1 vertex and 7 lines) + (True, A 7-dimensional polyhedron in QQ^7 defined + as the convex hull of 1 vertex and 7 lines) """ R = self.base_ring() # If there are no hyperplanes in the arrangement, @@ -1419,15 +1421,15 @@ def center(self): The Shi arrangement in dimension 3 has an empty center:: - sage: A = hyperplane_arrangements.Shi(3) - sage: A.center() + sage: A = hyperplane_arrangements.Shi(3) # optional - sage.combinat + sage: A.center() # optional - sage.combinat The empty polyhedron in QQ^3 The Braid arrangement in dimension 3 has a center that is neither empty nor full-dimensional:: - sage: A = hyperplane_arrangements.braid(3) - sage: A.center() + sage: A = hyperplane_arrangements.braid(3) # optional - sage.combinat + sage: A.center() # optional - sage.combinat A 1-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex and 1 line """ return self.is_central(certificate=True)[1] @@ -1448,16 +1450,16 @@ def is_simplicial(self): EXAMPLES:: sage: H. = HyperplaneArrangements(QQ) - sage: A = H([[0,1,1,1],[0,1,2,3]]) + sage: A = H([[0,1,1,1], [0,1,2,3]]) sage: A.is_simplicial() True - sage: A = H([[0,1,1,1],[0,1,2,3],[0,1,3,2]]) + sage: A = H([[0,1,1,1], [0,1,2,3], [0,1,3,2]]) sage: A.is_simplicial() True - sage: A = H([[0,1,1,1],[0,1,2,3],[0,1,3,2],[0,2,1,3]]) + sage: A = H([[0,1,1,1], [0,1,2,3], [0,1,3,2], [0,2,1,3]]) sage: A.is_simplicial() False - sage: hyperplane_arrangements.braid(3).is_simplicial() + sage: hyperplane_arrangements.braid(3).is_simplicial() # optional - sage.graphs True """ # if the arr is not essential, grab the essential version and check there. @@ -1483,10 +1485,10 @@ def essentialization(self): EXAMPLES:: - sage: a = hyperplane_arrangements.braid(3) - sage: a.is_essential() + sage: a = hyperplane_arrangements.braid(3) # optional - sage.graphs + sage: a.is_essential() # optional - sage.graphs False - sage: a.essentialization() + sage: a.essentialization() # optional - sage.graphs Arrangement sage: H. = HyperplaneArrangements(QQ) @@ -1499,13 +1501,13 @@ def essentialization(self): Hyperplane arrangements in 1-dimensional linear space over Rational Field with coordinate x - sage: H. = HyperplaneArrangements(GF(2)) # optional - sage.libs.pari - sage: C = H([(1,1),1], [(1,1),0]) # optional - sage.libs.pari - sage: C.essentialization() # optional - sage.libs.pari + sage: H. = HyperplaneArrangements(GF(2)) # optional - sage.rings.finite_rings + sage: C = H([(1,1),1], [(1,1),0]) # optional - sage.rings.finite_rings + sage: C.essentialization() # optional - sage.rings.finite_rings Arrangement - sage: h = hyperplane_arrangements.semiorder(4) - sage: h.essentialization() + sage: h = hyperplane_arrangements.semiorder(4) # optional - sage.combinat + sage: h.essentialization() # optional - sage.combinat Arrangement of 12 hyperplanes of dimension 3 and rank 3 TESTS:: @@ -1591,9 +1593,9 @@ def sign_vector(self, p): TESTS:: - sage: H. = HyperplaneArrangements(GF(3)) # optional - sage.libs.pari - sage: A = H(x, y) # optional - sage.libs.pari - sage: A.sign_vector([1, 2]) # optional - sage.libs.pari + sage: H. = HyperplaneArrangements(GF(3)) # optional - sage.rings.finite_rings + sage: A = H(x, y) # optional - sage.rings.finite_rings + sage: A.sign_vector([1, 2]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: characteristic must be zero @@ -1620,8 +1622,8 @@ def face_vector(self): EXAMPLES:: - sage: A = hyperplane_arrangements.Shi(3) - sage: A.face_vector() + sage: A = hyperplane_arrangements.Shi(3) # optional - sage.combinat + sage: A.face_vector() # optional - sage.combinat (0, 6, 21, 16) """ m = self.whitney_data()[0] @@ -1660,7 +1662,7 @@ def _parallel_hyperplanes(self): (Hyperplane x + 2*y + 0, (1, 2), 0), (Hyperplane 2*x + 4*y + 1, (1, 2), 1/2)) - sage: hyperplane_arrangements.Shi(3)._parallel_hyperplanes() + sage: hyperplane_arrangements.Shi(3)._parallel_hyperplanes() # optional - sage.combinat (((Hyperplane 0*t0 + t1 - t2 - 1, (0, 1, -1), -1), (Hyperplane 0*t0 + t1 - t2 + 0, (0, 1, -1), 0)), ((Hyperplane t0 - t1 + 0*t2 - 1, (1, -1, 0), -1), @@ -1703,21 +1705,21 @@ def vertices(self, exclude_sandwiched=False): EXAMPLES:: - sage: A = hyperplane_arrangements.Shi(3).essentialization() - sage: A.dimension() + sage: A = hyperplane_arrangements.Shi(3).essentialization() # optional - sage.combinat + sage: A.dimension() # optional - sage.combinat 2 - sage: A.face_vector() + sage: A.face_vector() # optional - sage.combinat (6, 21, 16) - sage: A.vertices() + sage: A.vertices() # optional - sage.combinat ((-2/3, 1/3), (-1/3, -1/3), (0, -1), (0, 0), (1/3, -2/3), (2/3, -1/3)) - sage: point2d(A.vertices(), size=20) + A.plot() # optional - sage.plot + sage: point2d(A.vertices(), size=20) + A.plot() # optional - sage.combinat sage.plot Graphics object consisting of 7 graphics primitives sage: H. = HyperplaneArrangements(QQ) sage: chessboard = [] sage: N = 8 - sage: for x0 in range(N+1): - ....: for y0 in range(N+1): + sage: for x0 in range(N + 1): + ....: for y0 in range(N + 1): ....: chessboard.extend([x-x0, y-y0]) sage: chessboard = H(chessboard) sage: len(chessboard.vertices()) @@ -1780,8 +1782,8 @@ def _make_region(self, hyperplanes): Checks that it creates the regions with the appropriate backend:: - sage: h = H(x,backend='normaliz') # optional - pynormaliz - sage: h._make_region([x, 1-x, y, 1-y]).backend() # optional - pynormaliz + sage: h = H(x,backend='normaliz') # optional - pynormaliz + sage: h._make_region([x, 1-x, y, 1-y]).backend() # optional - pynormaliz 'normaliz' """ ieqs = [h.dense_coefficient_list() for h in hyperplanes] @@ -1806,23 +1808,29 @@ def regions(self): EXAMPLES:: - sage: a = hyperplane_arrangements.braid(2) - sage: a.regions() - (A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex, 1 ray, 1 line, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex, 1 ray, 1 line) + sage: a = hyperplane_arrangements.braid(2) # optional - sage.graphs + sage: a.regions() # optional - sage.graphs + (A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex, 1 ray, 1 line, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex, 1 ray, 1 line) sage: H. = HyperplaneArrangements(QQ) sage: A = H(x, y+1) sage: A.regions() - (A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays) + (A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 2 rays, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 2 rays, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 2 rays, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 2 rays) sage: chessboard = [] sage: N = 8 - sage: for x0 in range(N+1): - ....: for y0 in range(N+1): + sage: for x0 in range(N + 1): + ....: for y0 in range(N + 1): ....: chessboard.extend([x-x0, y-y0]) sage: chessboard = H(chessboard) sage: len(chessboard.bounded_regions()) # long time, 359 ms on a Core i7 @@ -1855,20 +1863,21 @@ def regions(self): It is possible to specify the backend:: - sage: K. = CyclotomicField(9) - sage: L. = NumberField((q+q**(-1)).minpoly(),embedding = AA(q+q**-1)) - sage: norms = [[1,1/3*(-2*r9**2-r9+1),0], - ....: [1,-r9**2-r9,0], - ....: [1,-r9**2+1,0], - ....: [1,-r9**2,0], - ....: [1,r9**2-4,-r9**2+3]] - sage: H. = HyperplaneArrangements(L) - sage: A = H(backend='normaliz') - sage: for v in norms: + sage: K. = CyclotomicField(9) # optional - sage.rings.number_field + sage: L. = NumberField((q + q**(-1)).minpoly(), # optional - sage.rings.number_field + ....: embedding=AA(q + q**-1)) + sage: norms = [[1, 1/3*(-2*r9**2-r9+1), 0], # optional - sage.rings.number_field + ....: [1, -r9**2 - r9, 0], + ....: [1, -r9**2 + 1, 0], + ....: [1, -r9**2, 0], + ....: [1, r9**2 - 4, -r9**2+3]] + sage: H. = HyperplaneArrangements(L) # optional - sage.rings.number_field + sage: A = H(backend='normaliz') # optional - sage.rings.number_field + sage: for v in norms: # optional - sage.rings.number_field ....: a,b,c = v ....: A = A.add_hyperplane(a*x + b*y + c*z) - sage: R = A.regions() # optional - pynormaliz - sage: R[0].backend() # optional - pynormaliz + sage: R = A.regions() # optional - pynormaliz sage.rings.number_field + sage: R[0].backend() # optional - pynormaliz sage.rings.number_field 'normaliz' TESTS:: @@ -1876,7 +1885,8 @@ def regions(self): sage: K. = HyperplaneArrangements(QQ) sage: A = K() sage: A.regions() - (A 5-dimensional polyhedron in QQ^5 defined as the convex hull of 1 vertex and 5 lines,) + (A 5-dimensional polyhedron in QQ^5 + defined as the convex hull of 1 vertex and 5 lines,) """ if self.base_ring().characteristic() != 0: raise ValueError('base field must have characteristic zero') @@ -1976,24 +1986,24 @@ def poset_of_regions(self, B=None, numbered_labels=True): EXAMPLES:: sage: H. = HyperplaneArrangements(QQ) - sage: A = H([[0,1,1,1],[0,1,2,3]]) - sage: A.poset_of_regions() + sage: A = H([[0,1,1,1], [0,1,2,3]]) + sage: A.poset_of_regions() # optional - sage.combinat Finite poset containing 4 elements - sage: A = hyperplane_arrangements.braid(3) - sage: A.poset_of_regions() + sage: A = hyperplane_arrangements.braid(3) # optional - sage.combinat sage.graphs + sage: A.poset_of_regions() # optional - sage.combinat sage.graphs Finite poset containing 6 elements - sage: A.poset_of_regions(numbered_labels=False) + sage: A.poset_of_regions(numbered_labels=False) # optional - sage.combinat sage.graphs Finite poset containing 6 elements - sage: A = hyperplane_arrangements.braid(4) - sage: A.poset_of_regions() + sage: A = hyperplane_arrangements.braid(4) # optional - sage.combinat sage.graphs + sage: A.poset_of_regions() # optional - sage.combinat sage.graphs Finite poset containing 24 elements sage: H. = HyperplaneArrangements(QQ) - sage: A = H([[0,1,1,1],[0,1,2,3],[0,1,3,2],[0,2,1,3]]) - sage: R = A.regions() - sage: base_region = R[3] - sage: A.poset_of_regions(B=base_region) + sage: A = H([[0,1,1,1], [0,1,2,3], [0,1,3,2], [0,2,1,3]]) + sage: R = A.regions() # optional - sage.combinat + sage: base_region = R[3] # optional - sage.combinat + sage: A.poset_of_regions(B=base_region) # optional - sage.combinat Finite poset containing 14 elements """ from sage.combinat.posets.posets import Poset @@ -2098,109 +2108,87 @@ def closed_faces(self, labelled=True): EXAMPLES:: - sage: a = hyperplane_arrangements.braid(2) - sage: a.hyperplanes() + sage: a = hyperplane_arrangements.braid(2) # optional - sage.graphs + sage: a.hyperplanes() # optional - sage.graphs (Hyperplane t0 - t1 + 0,) - sage: a.closed_faces() - (((0,), - A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line), - ((1,), - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex, 1 ray, 1 line), - ((-1,), - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex, 1 ray, 1 line)) - sage: a.closed_faces(labelled=False) - (A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex, 1 ray, 1 line, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex, 1 ray, 1 line) - sage: [(v, F, F.representative_point()) for v, F in a.closed_faces()] - [((0,), - A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line, - (0, 0)), - ((1,), - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex, 1 ray, 1 line, - (0, -1)), - ((-1,), - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex, 1 ray, 1 line, - (-1, 0))] + sage: a.closed_faces() # optional - sage.graphs + (((0,), A 1-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 1 line), + ((1,), A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex, 1 ray, 1 line), + ((-1,), A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex, 1 ray, 1 line)) + sage: a.closed_faces(labelled=False) # optional - sage.graphs + (A 1-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 1 line, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex, 1 ray, 1 line, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex, 1 ray, 1 line) + sage: [(v, F, F.representative_point()) for v, F in a.closed_faces()] # optional - sage.graphs + [((0,), A 1-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 1 line, (0, 0)), + ((1,), A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex, 1 ray, 1 line, (0, -1)), + ((-1,), A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex, 1 ray, 1 line, (-1, 0))] sage: H. = HyperplaneArrangements(QQ) sage: a = H(x, y+1) sage: a.hyperplanes() (Hyperplane 0*x + y + 1, Hyperplane x + 0*y + 0) sage: [(v, F, F.representative_point()) for v, F in a.closed_faces()] - [((0, 0), - A 0-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex, - (0, -1)), - ((0, 1), - A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 ray, - (1, -1)), - ((0, -1), - A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 ray, - (-1, -1)), - ((1, 0), - A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 ray, - (0, 0)), - ((1, 1), - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays, - (1, 0)), - ((1, -1), - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays, - (-1, 0)), - ((-1, 0), - A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 ray, - (0, -2)), - ((-1, 1), - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays, - (1, -2)), - ((-1, -1), - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays, - (-1, -2))] - - sage: a = hyperplane_arrangements.braid(3) - sage: a.hyperplanes() + [((0, 0), A 0-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex, (0, -1)), + ((0, 1), A 1-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 1 ray, (1, -1)), + ((0, -1), A 1-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 1 ray, (-1, -1)), + ((1, 0), A 1-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 1 ray, (0, 0)), + ((1, 1), A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 2 rays, (1, 0)), + ((1, -1), A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 2 rays, (-1, 0)), + ((-1, 0), A 1-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 1 ray, (0, -2)), + ((-1, 1), A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 2 rays, (1, -2)), + ((-1, -1), A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 2 rays, (-1, -2))] + + sage: a = hyperplane_arrangements.braid(3) # optional - sage.graphs + sage: a.hyperplanes() # optional - sage.graphs (Hyperplane 0*t0 + t1 - t2 + 0, Hyperplane t0 - t1 + 0*t2 + 0, Hyperplane t0 + 0*t1 - t2 + 0) - sage: [(v, F, F.representative_point()) for v, F in a.closed_faces()] - [((0, 0, 0), - A 1-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex and 1 line, - (0, 0, 0)), - ((0, 1, 1), - A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex, 1 ray, 1 line, - (0, -1, -1)), - ((0, -1, -1), - A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex, 1 ray, 1 line, - (-1, 0, 0)), - ((1, 0, 1), - A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex, 1 ray, 1 line, - (1, 1, 0)), - ((1, 1, 1), - A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex, 2 rays, 1 line, - (0, -1, -2)), - ((1, -1, 0), - A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex, 1 ray, 1 line, - (-1, 0, -1)), - ((1, -1, 1), - A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex, 2 rays, 1 line, - (1, 2, 0)), - ((1, -1, -1), - A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex, 2 rays, 1 line, - (-2, 0, -1)), - ((-1, 0, -1), - A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex, 1 ray, 1 line, - (0, 0, 1)), - ((-1, 1, 0), - A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex, 1 ray, 1 line, - (1, 0, 1)), - ((-1, 1, 1), - A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex, 2 rays, 1 line, - (0, -2, -1)), - ((-1, 1, -1), - A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex, 2 rays, 1 line, - (1, 0, 2)), - ((-1, -1, -1), - A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex, 2 rays, 1 line, - (-1, 0, 1))] + sage: [(v, F, F.representative_point()) for v, F in a.closed_faces()] # optional - sage.graphs + [((0, 0, 0), A 1-dimensional polyhedron in QQ^3 defined + as the convex hull of 1 vertex and 1 line, (0, 0, 0)), + ((0, 1, 1), A 2-dimensional polyhedron in QQ^3 defined + as the convex hull of 1 vertex, 1 ray, 1 line, (0, -1, -1)), + ((0, -1, -1), A 2-dimensional polyhedron in QQ^3 defined + as the convex hull of 1 vertex, 1 ray, 1 line, (-1, 0, 0)), + ((1, 0, 1), A 2-dimensional polyhedron in QQ^3 defined + as the convex hull of 1 vertex, 1 ray, 1 line, (1, 1, 0)), + ((1, 1, 1), A 3-dimensional polyhedron in QQ^3 defined + as the convex hull of 1 vertex, 2 rays, 1 line, (0, -1, -2)), + ((1, -1, 0), A 2-dimensional polyhedron in QQ^3 defined + as the convex hull of 1 vertex, 1 ray, 1 line, (-1, 0, -1)), + ((1, -1, 1), A 3-dimensional polyhedron in QQ^3 defined + as the convex hull of 1 vertex, 2 rays, 1 line, (1, 2, 0)), + ((1, -1, -1), A 3-dimensional polyhedron in QQ^3 defined + as the convex hull of 1 vertex, 2 rays, 1 line, (-2, 0, -1)), + ((-1, 0, -1), A 2-dimensional polyhedron in QQ^3 defined + as the convex hull of 1 vertex, 1 ray, 1 line, (0, 0, 1)), + ((-1, 1, 0), A 2-dimensional polyhedron in QQ^3 defined + as the convex hull of 1 vertex, 1 ray, 1 line, (1, 0, 1)), + ((-1, 1, 1), A 3-dimensional polyhedron in QQ^3 defined + as the convex hull of 1 vertex, 2 rays, 1 line, (0, -2, -1)), + ((-1, 1, -1), A 3-dimensional polyhedron in QQ^3 defined + as the convex hull of 1 vertex, 2 rays, 1 line, (1, 0, 2)), + ((-1, -1, -1), A 3-dimensional polyhedron in QQ^3 defined + as the convex hull of 1 vertex, 2 rays, 1 line, (-1, 0, 1))] Let us check that the number of closed faces with a given dimension computed using ``self.closed_faces()`` equals the one @@ -2212,10 +2200,10 @@ def closed_faces(self, labelled=True): ....: LHS = Qx.sum(x ** F[1].dim() for F in a.closed_faces()) ....: return LHS == RHS sage: a = hyperplane_arrangements.Catalan(2) - sage: test_number(a) + sage: test_number(a) # optional - sage.combinat True - sage: a = hyperplane_arrangements.Shi(3) - sage: test_number(a) # long time + sage: a = hyperplane_arrangements.Shi(3) # optional - sage.combinat + sage: test_number(a) # long time # optional - sage.combinat True TESTS: @@ -2350,27 +2338,27 @@ def face_product(self, F, G, normalize=True): EXAMPLES:: - sage: a = hyperplane_arrangements.braid(3) - sage: a.hyperplanes() + sage: a = hyperplane_arrangements.braid(3) # optional - sage.graphs + sage: a.hyperplanes() # optional - sage.graphs (Hyperplane 0*t0 + t1 - t2 + 0, Hyperplane t0 - t1 + 0*t2 + 0, Hyperplane t0 + 0*t1 - t2 + 0) - sage: faces = {F0: F1 for F0, F1 in a.closed_faces()} - sage: xGyEz = faces[(0, 1, 1)] # closed face x >= y = z - sage: xGyEz.representative_point() + sage: faces = {F0: F1 for F0, F1 in a.closed_faces()} # optional - sage.graphs + sage: xGyEz = faces[(0, 1, 1)] # closed face x >= y = z # optional - sage.graphs + sage: xGyEz.representative_point() # optional - sage.graphs (0, -1, -1) - sage: xGyEz = faces[(0, 1, 1)] # closed face x >= y = z - sage: xGyEz.representative_point() + sage: xGyEz = faces[(0, 1, 1)] # closed face x >= y = z # optional - sage.graphs + sage: xGyEz.representative_point() # optional - sage.graphs (0, -1, -1) - sage: yGxGz = faces[(1, -1, 1)] # closed face y >= x >= z - sage: xGyGz = faces[(1, 1, 1)] # closed face x >= y >= z - sage: a.face_product(xGyEz, yGxGz) == xGyGz + sage: yGxGz = faces[(1, -1, 1)] # closed face y >= x >= z # optional - sage.graphs + sage: xGyGz = faces[(1, 1, 1)] # closed face x >= y >= z # optional - sage.graphs + sage: a.face_product(xGyEz, yGxGz) == xGyGz # optional - sage.graphs True - sage: a.face_product(yGxGz, xGyEz) == yGxGz + sage: a.face_product(yGxGz, xGyEz) == yGxGz # optional - sage.graphs True - sage: xEzGy = faces[(-1, 1, 0)] # closed face x = z >= y - sage: xGzGy = faces[(-1, 1, 1)] # closed face x >= z >= y - sage: a.face_product(xEzGy, yGxGz) == xGzGy + sage: xEzGy = faces[(-1, 1, 0)] # closed face x = z >= y # optional - sage.graphs + sage: xGzGy = faces[(-1, 1, 1)] # closed face x >= z >= y # optional - sage.graphs + sage: a.face_product(xEzGy, yGxGz) == xGzGy # optional - sage.graphs True """ f = F.representative_point() @@ -2445,8 +2433,8 @@ def face_semigroup_algebra(self, field=None, names='e'): EXAMPLES:: - sage: a = hyperplane_arrangements.braid(3) - sage: [(i, F[0]) for i, F in enumerate(a.closed_faces())] + sage: a = hyperplane_arrangements.braid(3) # optional - sage.graphs + sage: [(i, F[0]) for i, F in enumerate(a.closed_faces())] # optional - sage.graphs [(0, (0, 0, 0)), (1, (0, 1, 1)), (2, (0, -1, -1)), @@ -2460,44 +2448,44 @@ def face_semigroup_algebra(self, field=None, names='e'): (10, (-1, 1, 1)), (11, (-1, 1, -1)), (12, (-1, -1, -1))] - sage: U = a.face_semigroup_algebra(); U + sage: U = a.face_semigroup_algebra(); U # optional - sage.graphs Finite-dimensional algebra of degree 13 over Rational Field - sage: e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12 = U.basis() - sage: e0 * e1 + sage: e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12 = U.basis() # optional - sage.graphs + sage: e0 * e1 # optional - sage.graphs e1 - sage: e0 * e5 + sage: e0 * e5 # optional - sage.graphs e5 - sage: e5 * e0 + sage: e5 * e0 # optional - sage.graphs e5 - sage: e3 * e2 + sage: e3 * e2 # optional - sage.graphs e6 - sage: e7 * e12 + sage: e7 * e12 # optional - sage.graphs e7 - sage: e3 * e12 + sage: e3 * e12 # optional - sage.graphs e6 - sage: e4 * e8 + sage: e4 * e8 # optional - sage.graphs e4 - sage: e8 * e4 + sage: e8 * e4 # optional - sage.graphs e11 - sage: e8 * e1 + sage: e8 * e1 # optional - sage.graphs e11 - sage: e5 * e12 + sage: e5 * e12 # optional - sage.graphs e7 - sage: (e3 + 2*e4) * (e1 - e7) + sage: (e3 + 2*e4) * (e1 - e7) # optional - sage.graphs e4 - e6 - sage: U3 = a.face_semigroup_algebra(field=GF(3)); U3 # optional - sage.libs.pari + sage: U3 = a.face_semigroup_algebra(field=GF(3)); U3 # optional - sage.graphs sage.rings.finite_rings Finite-dimensional algebra of degree 13 over Finite Field of size 3 TESTS: The ``names`` keyword works:: - sage: a = hyperplane_arrangements.braid(3) - sage: U = a.face_semigroup_algebra(names='x'); U + sage: a = hyperplane_arrangements.braid(3) # optional - sage.graphs + sage: U = a.face_semigroup_algebra(names='x'); U # optional - sage.graphs Finite-dimensional algebra of degree 13 over Rational Field - sage: e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12 = U.basis() - sage: e0 * e1 + sage: e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12 = U.basis() # optional - sage.graphs + sage: e0 * e1 # optional - sage.graphs x1 """ if field is None: @@ -2551,13 +2539,14 @@ def region_containing_point(self, p): sage: H. = HyperplaneArrangements(QQ) sage: A = H([(1,0), 0], [(0,1), 1], [(0,1), -1], [(1,-1), 0], [(1,1), 0]) sage: A.region_containing_point([1,2]) - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 2 rays + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 2 vertices and 2 rays TESTS:: sage: A = H([(1,1),0], [(2,3),-1], [(4,5),3]) - sage: B = A.change_ring(FiniteField(7)) # optional - sage.libs.pari - sage: B.region_containing_point((1,2)) # optional - sage.libs.pari + sage: B = A.change_ring(FiniteField(7)) # optional - sage.rings.finite_rings + sage: B.region_containing_point((1,2)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: base field must have characteristic zero @@ -2595,8 +2584,8 @@ def _bounded_region_indices(self): EXAMPLES:: - sage: a = hyperplane_arrangements.semiorder(3) - sage: a._bounded_region_indices() + sage: a = hyperplane_arrangements.semiorder(3) # optional - sage.combinat + sage: a._bounded_region_indices() # optional - sage.combinat (2, 7, 8, 9, 10, 11, 16) """ from sage.geometry.polyhedron.constructor import Polyhedron @@ -2631,18 +2620,25 @@ def bounded_regions(self): EXAMPLES:: - sage: A = hyperplane_arrangements.semiorder(3) - sage: A.bounded_regions() - (A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 3 vertices and 1 line, - A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 3 vertices and 1 line, - A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 3 vertices and 1 line, - A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 6 vertices and 1 line, - A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 3 vertices and 1 line, - A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 3 vertices and 1 line, - A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 3 vertices and 1 line) - sage: A.bounded_regions()[0].is_compact() # the regions are only *relatively* bounded + sage: A = hyperplane_arrangements.semiorder(3) # optional - sage.combinat + sage: A.bounded_regions() # optional - sage.combinat + (A 3-dimensional polyhedron in QQ^3 defined + as the convex hull of 3 vertices and 1 line, + A 3-dimensional polyhedron in QQ^3 defined + as the convex hull of 3 vertices and 1 line, + A 3-dimensional polyhedron in QQ^3 defined + as the convex hull of 3 vertices and 1 line, + A 3-dimensional polyhedron in QQ^3 defined + as the convex hull of 6 vertices and 1 line, + A 3-dimensional polyhedron in QQ^3 defined + as the convex hull of 3 vertices and 1 line, + A 3-dimensional polyhedron in QQ^3 defined + as the convex hull of 3 vertices and 1 line, + A 3-dimensional polyhedron in QQ^3 defined + as the convex hull of 3 vertices and 1 line) + sage: A.bounded_regions()[0].is_compact() # the regions are only *relatively* bounded # optional - sage.combinat False - sage: A.is_essential() + sage: A.is_essential() # optional - sage.combinat False """ return tuple(self.regions()[i] for i in self._bounded_region_indices()) @@ -2663,23 +2659,35 @@ def unbounded_regions(self): EXAMPLES:: - sage: A = hyperplane_arrangements.semiorder(3) - sage: B = A.essentialization() - sage: B.n_regions() - B.n_bounded_regions() + sage: A = hyperplane_arrangements.semiorder(3) # optional - sage.combinat + sage: B = A.essentialization() # optional - sage.combinat + sage: B.n_regions() - B.n_bounded_regions() # optional - sage.combinat 12 - sage: B.unbounded_regions() - (A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices and 1 ray, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices and 1 ray, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices and 1 ray, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices and 1 ray, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices and 1 ray, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices and 1 ray, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays, - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays) + sage: B.unbounded_regions() # optional - sage.combinat + (A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 3 vertices and 1 ray, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 3 vertices and 1 ray, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 2 rays, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 3 vertices and 1 ray, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 2 rays, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 3 vertices and 1 ray, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 2 rays, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 3 vertices and 1 ray, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 2 rays, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 3 vertices and 1 ray, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 2 rays, + A 2-dimensional polyhedron in QQ^2 defined + as the convex hull of 1 vertex and 2 rays) """ s = set(range(self.n_regions())).difference(set(self._bounded_region_indices())) return tuple(self.regions()[i] for i in s) @@ -2703,8 +2711,8 @@ def whitney_data(self): EXAMPLES:: - sage: A = hyperplane_arrangements.Shi(3) - sage: A.whitney_data() + sage: A = hyperplane_arrangements.Shi(3) # optional - sage.combinat + sage: A.whitney_data() # optional - sage.combinat ( [ 1 -6 9] [ 1 6 6] [ 0 6 -15] [ 0 6 15] @@ -2753,12 +2761,12 @@ def doubly_indexed_whitney_number(self, i, j, kind=1): EXAMPLES:: - sage: A = hyperplane_arrangements.Shi(3) - sage: A.doubly_indexed_whitney_number(0, 2) + sage: A = hyperplane_arrangements.Shi(3) # optional - sage.combinat + sage: A.doubly_indexed_whitney_number(0, 2) # optional - sage.combinat 9 - sage: A.whitney_number(2) + sage: A.whitney_number(2) # optional - sage.combinat 9 - sage: A.doubly_indexed_whitney_number(1, 2) + sage: A.doubly_indexed_whitney_number(1, 2) # optional - sage.combinat -15 REFERENCES: @@ -2803,20 +2811,20 @@ def whitney_number(self, k, kind=1): EXAMPLES:: - sage: A = hyperplane_arrangements.Shi(3) - sage: A.whitney_number(0) + sage: A = hyperplane_arrangements.Shi(3) # optional - sage.combinat + sage: A.whitney_number(0) # optional - sage.combinat 1 - sage: A.whitney_number(1) + sage: A.whitney_number(1) # optional - sage.combinat -6 - sage: A.whitney_number(2) + sage: A.whitney_number(2) # optional - sage.combinat 9 - sage: A.characteristic_polynomial() + sage: A.characteristic_polynomial() # optional - sage.combinat x^3 - 6*x^2 + 9*x - sage: A.whitney_number(1,kind=2) + sage: A.whitney_number(1, kind=2) # optional - sage.combinat 6 - sage: p = A.intersection_poset() - sage: r = p.rank_function() - sage: len([i for i in p if r(i) == 1]) + sage: p = A.intersection_poset() # optional - sage.combinat + sage: r = p.rank_function() # optional - sage.combinat + sage: len([i for i in p if r(i) == 1]) # optional - sage.combinat 6 """ if k >= 0 and k <= self.dimension(): @@ -2996,7 +3004,7 @@ def matroid(self): We check the lattice of flats is isomorphic to the intersection lattice:: - sage: f = sum([list(M.flats(i)) for i in range(M.rank()+1)], []) + sage: f = sum([list(M.flats(i)) for i in range(M.rank() + 1)], []) sage: PF = Poset([f, lambda x, y: x < y]) # optional - sage.combinat sage: PF.is_isomorphic(A.intersection_poset()) # optional - sage.combinat True @@ -3088,13 +3096,13 @@ def minimal_generated_number(self): Check that :trac:`26705` is fixed:: - sage: w = WeylGroup(['A',4]).from_reduced_word([3,4,2,1]) - sage: I = w.inversion_arrangement() - sage: I + sage: w = WeylGroup(['A', 4]).from_reduced_word([3, 4, 2, 1]) # optional - sage.combinat sage.groups + sage: I = w.inversion_arrangement() # optional - sage.combinat sage.groups + sage: I # optional - sage.combinat sage.groups Arrangement - sage: I.minimal_generated_number() + sage: I.minimal_generated_number() # optional - sage.combinat sage.groups 0 - sage: I.is_formal() + sage: I.is_formal() # optional - sage.combinat sage.groups True """ V = VectorSpace(self.base_ring(), self.dimension()) @@ -3176,9 +3184,9 @@ def derivation_module_free_chain(self): EXAMPLES:: - sage: W = WeylGroup(['A',3], prefix='s') - sage: A = W.long_element().inversion_arrangement() - sage: for M in A.derivation_module_free_chain(): print("%s\n"%M) + sage: W = WeylGroup(['A',3], prefix='s') # optional - sage.combinat sage.groups + sage: A = W.long_element().inversion_arrangement() # optional - sage.combinat sage.groups + sage: for M in A.derivation_module_free_chain(): print("%s\n"%M) # optional - sage.combinat sage.groups [ 1 0 0] [ 0 1 0] [ 0 0 a3] @@ -3252,8 +3260,8 @@ def is_free(self, algorithm="singular"): For type `A` arrangements, chordality is equivalent to freeness. We verify that in type `A_3`:: - sage: W = WeylGroup(['A',3], prefix='s') - sage: for x in W: + sage: W = WeylGroup(['A', 3], prefix='s') # optional - sage.combinat sage.groups + sage: for x in W: # optional - sage.combinat sage.groups ....: A = x.inversion_arrangement() ....: assert A.matroid().is_chordal() == A.is_free() @@ -3261,8 +3269,8 @@ def is_free(self, algorithm="singular"): We check that the algorithms agree:: - sage: W = WeylGroup(['B',3], prefix='s') - sage: for x in W: # long time + sage: W = WeylGroup(['B', 3], prefix='s') # optional - sage.combinat sage.groups + sage: for x in W: # long time # optional - sage.combinat sage.groups ....: A = x.inversion_arrangement() ....: assert (A.is_free(algorithm="BC") ....: == A.is_free(algorithm="singular")) @@ -3321,19 +3329,19 @@ def derivation_module_basis(self, algorithm="singular"): EXAMPLES:: - sage: W = WeylGroup(['A',2], prefix='s') - sage: A = W.long_element().inversion_arrangement() - sage: A.derivation_module_basis() + sage: W = WeylGroup(['A', 2], prefix='s') # optional - sage.combinat sage.groups + sage: A = W.long_element().inversion_arrangement() # optional - sage.combinat sage.groups + sage: A.derivation_module_basis() # optional - sage.combinat sage.groups [(a1, a2), (0, a1*a2 + a2^2)] TESTS: We check the algorithms produce a basis with the same exponents:: - sage: W = WeylGroup(['A',2], prefix='s') - sage: exponents = lambda B: sorted([max(x.degree() for x in b) - ....: for b in B]) - sage: for x in W: # long time + sage: W = WeylGroup(['A', 2], prefix='s') # optional - sage.combinat sage.groups + sage: def exponents(B): # optional - sage.combinat sage.groups + ....: return sorted([max(x.degree() for x in b) for b in B]) + sage: for x in W: # long time # optional - sage.combinat sage.groups ....: A = x.inversion_arrangement() ....: B = A.derivation_module_basis(algorithm="singular") ....: Bp = A.derivation_module_basis(algorithm="BC") @@ -3665,7 +3673,8 @@ def gen(self, i): EXAMPLES:: sage: L. = HyperplaneArrangements(QQ); L - Hyperplane arrangements in 3-dimensional linear space over Rational Field with coordinates x, y, z + Hyperplane arrangements in + 3-dimensional linear space over Rational Field with coordinates x, y, z sage: L.gen(0) Hyperplane x + 0*y + 0*z + 0 """ diff --git a/src/sage/geometry/hyperplane_arrangement/check_freeness.py b/src/sage/geometry/hyperplane_arrangement/check_freeness.py index 30f963612ec..e99c8ee9b39 100644 --- a/src/sage/geometry/hyperplane_arrangement/check_freeness.py +++ b/src/sage/geometry/hyperplane_arrangement/check_freeness.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.singular r""" Helper Functions For Freeness Of Hyperplane Arrangements diff --git a/src/sage/geometry/hyperplane_arrangement/hyperplane.py b/src/sage/geometry/hyperplane_arrangement/hyperplane.py index c431291a3a6..8284022d3d8 100644 --- a/src/sage/geometry/hyperplane_arrangement/hyperplane.py +++ b/src/sage/geometry/hyperplane_arrangement/hyperplane.py @@ -26,7 +26,7 @@ (3, 2, -5) sage: h.constant_term() -7 - sage: h.change_ring(GF(3)) + sage: h.change_ring(GF(3)) # optional - sage.rings.finite_rings Hyperplane 0*x + 2*y + z + 2 sage: h.point() (21/38, 7/19, -35/38) @@ -238,9 +238,9 @@ def _normal_pivot(self): sage: (x + 3/2*y - 2*z)._normal_pivot() 2 - sage: H. = HyperplaneArrangements(GF(5)) - sage: V = H.ambient_space() - sage: (x + 3*y - 4*z)._normal_pivot() + sage: H. = HyperplaneArrangements(GF(5)) # optional - sage.rings.finite_rings + sage: V = H.ambient_space() # optional - sage.rings.finite_rings + sage: (x + 3*y - 4*z)._normal_pivot() # optional - sage.rings.finite_rings 1 """ try: @@ -397,16 +397,16 @@ def point(self): sage: h.point() in h True - sage: H. = HyperplaneArrangements(GF(3)) - sage: h = 2*x + y + z + 1 - sage: h.point() + sage: H. = HyperplaneArrangements(GF(3)) # optional - sage.rings.finite_rings + sage: h = 2*x + y + z + 1 # optional - sage.rings.finite_rings + sage: h.point() # optional - sage.rings.finite_rings (1, 0, 0) - sage: h.point().base_ring() + sage: h.point().base_ring() # optional - sage.rings.finite_rings Finite Field of size 3 - sage: H. = HyperplaneArrangements(GF(3)) - sage: h = x + y + z + 1 - sage: h.point() + sage: H. = HyperplaneArrangements(GF(3)) # optional - sage.rings.finite_rings + sage: h = x + y + z + 1 # optional - sage.rings.finite_rings + sage: h.point() # optional - sage.rings.finite_rings (2, 0, 0) """ P = self.parent() @@ -552,21 +552,21 @@ def primitive(self, signed=True): Check that :trac:`30078` is fixed:: - sage: R. = QuadraticField(2) - sage: H. = HyperplaneArrangements(base_ring=R) - sage: B = H([1,1,0], [2,2,0], [sqrt2,sqrt2,0]) - sage: B + sage: R. = QuadraticField(2) # optional - sage.rings.number_field + sage: H. = HyperplaneArrangements(base_ring=R) # optional - sage.rings.number_field + sage: B = H([1,1,0], [2,2,0], [sqrt2,sqrt2,0]) # optional - sage.rings.number_field + sage: B # optional - sage.rings.number_field Arrangement Check that :trac:`30749` is fixed:: - sage: tau = (1+AA(5).sqrt()) / 2 - sage: ncn = [[2*tau+1,2*tau,tau],[2*tau+2,2*tau+1,tau+1]] - sage: ncn += [[tau+1,tau+1,tau],[2*tau,2*tau,tau],[tau+1,tau+1,1]] - sage: ncn += [[1,1,1],[1,1,0],[0,1,0],[1,0,0],[tau+1,tau,tau]] - sage: H = HyperplaneArrangements(AA,names='xyz') - sage: A = H([[0]+v for v in ncn]) - sage: A.n_regions() + sage: tau = (1+AA(5).sqrt()) / 2 # optional - sage.rings.number_field + sage: ncn = [[2*tau+1,2*tau,tau],[2*tau+2,2*tau+1,tau+1]] # optional - sage.rings.number_field + sage: ncn += [[tau+1,tau+1,tau],[2*tau,2*tau,tau],[tau+1,tau+1,1]] # optional - sage.rings.number_field + sage: ncn += [[1,1,1],[1,1,0],[0,1,0],[1,0,0],[tau+1,tau,tau]] # optional - sage.rings.number_field + sage: H = HyperplaneArrangements(AA,names='xyz') # optional - sage.rings.number_field + sage: A = H([[0]+v for v in ncn]) # optional - sage.rings.number_field + sage: A.n_regions() # optional - sage.rings.number_field 60 """ from sage.rings.rational_field import QQ @@ -638,7 +638,7 @@ def plot(self, **kwds): EXAMPLES:: sage: L. = HyperplaneArrangements(QQ) - sage: (x+y-2).plot() # optional - sage.plot + sage: (x + y - 2).plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives """ from sage.geometry.hyperplane_arrangement.plot import plot_hyperplane diff --git a/src/sage/geometry/hyperplane_arrangement/library.py b/src/sage/geometry/hyperplane_arrangement/library.py index 37da03eda7c..4dc33701b56 100644 --- a/src/sage/geometry/hyperplane_arrangement/library.py +++ b/src/sage/geometry/hyperplane_arrangement/library.py @@ -90,7 +90,7 @@ def braid(self, n, K=QQ, names=None): EXAMPLES:: - sage: hyperplane_arrangements.braid(4) + sage: hyperplane_arrangements.braid(4) # optional - sage.graphs Arrangement of 6 hyperplanes of dimension 4 and rank 3 """ x = polygen(QQ, 'x') @@ -124,18 +124,18 @@ def bigraphical(self, G, A=None, K=QQ, names=None): EXAMPLES:: - sage: G = graphs.CycleGraph(4) - sage: G.edges(sort=True) + sage: G = graphs.CycleGraph(4) # optional - sage.graphs + sage: G.edges(sort=True) # optional - sage.graphs [(0, 1, None), (0, 3, None), (1, 2, None), (2, 3, None)] - sage: G.edges(sort=True, labels=False) + sage: G.edges(sort=True, labels=False) # optional - sage.graphs [(0, 1), (0, 3), (1, 2), (2, 3)] - sage: A = {0:{1:1, 3:2}, 1:{0:3, 2:0}, 2:{1:2, 3:1}, 3:{2:0, 0:2}} - sage: HA = hyperplane_arrangements.bigraphical(G, A) - sage: HA.n_regions() + sage: A = {0:{1:1, 3:2}, 1:{0:3, 2:0}, 2:{1:2, 3:1}, 3:{2:0, 0:2}} # optional - sage.graphs + sage: HA = hyperplane_arrangements.bigraphical(G, A) # optional - sage.graphs + sage: HA.n_regions() # optional - sage.graphs 63 - sage: hyperplane_arrangements.bigraphical(G, 'generic').n_regions() + sage: hyperplane_arrangements.bigraphical(G, 'generic').n_regions() # optional - sage.graphs 65 - sage: hyperplane_arrangements.bigraphical(G).n_regions() + sage: hyperplane_arrangements.bigraphical(G).n_regions() # optional - sage.graphs 59 REFERENCES: @@ -253,11 +253,11 @@ def G_semiorder(self, G, K=QQ, names=None): EXAMPLES:: - sage: G = graphs.CompleteGraph(5) - sage: hyperplane_arrangements.G_semiorder(G) + sage: G = graphs.CompleteGraph(5) # optional - sage.graphs + sage: hyperplane_arrangements.G_semiorder(G) # optional - sage.graphs Arrangement of 20 hyperplanes of dimension 5 and rank 4 - sage: g = graphs.HouseGraph() - sage: hyperplane_arrangements.G_semiorder(g) + sage: g = graphs.HouseGraph() # optional - sage.graphs + sage: hyperplane_arrangements.G_semiorder(g) # optional - sage.graphs Arrangement of 12 hyperplanes of dimension 5 and rank 4 """ n = G.num_verts() @@ -291,13 +291,13 @@ def G_Shi(self, G, K=QQ, names=None): EXAMPLES:: - sage: G = graphs.CompleteGraph(5) - sage: hyperplane_arrangements.G_Shi(G) + sage: G = graphs.CompleteGraph(5) # optional - sage.graphs + sage: hyperplane_arrangements.G_Shi(G) # optional - sage.graphs Arrangement of 20 hyperplanes of dimension 5 and rank 4 - sage: g = graphs.HouseGraph() - sage: hyperplane_arrangements.G_Shi(g) + sage: g = graphs.HouseGraph() # optional - sage.graphs + sage: hyperplane_arrangements.G_Shi(g) # optional - sage.graphs Arrangement of 12 hyperplanes of dimension 5 and rank 4 - sage: a = hyperplane_arrangements.G_Shi(graphs.WheelGraph(4)); a + sage: a = hyperplane_arrangements.G_Shi(graphs.WheelGraph(4)); a # optional - sage.graphs Arrangement of 12 hyperplanes of dimension 4 and rank 3 """ n = G.num_verts() @@ -333,20 +333,20 @@ def graphical(self, G, K=QQ, names=None): EXAMPLES:: - sage: G = graphs.CompleteGraph(5) - sage: hyperplane_arrangements.graphical(G) + sage: G = graphs.CompleteGraph(5) # optional - sage.graphs + sage: hyperplane_arrangements.graphical(G) # optional - sage.graphs Arrangement of 10 hyperplanes of dimension 5 and rank 4 - sage: g = graphs.HouseGraph() - sage: hyperplane_arrangements.graphical(g) + sage: g = graphs.HouseGraph() # optional - sage.graphs + sage: hyperplane_arrangements.graphical(g) # optional - sage.graphs Arrangement of 6 hyperplanes of dimension 5 and rank 4 TESTS:: - sage: h = hyperplane_arrangements.graphical(g) - sage: h.characteristic_polynomial() + sage: h = hyperplane_arrangements.graphical(g) # optional - sage.graphs + sage: h.characteristic_polynomial() # optional - sage.graphs x^5 - 6*x^4 + 14*x^3 - 15*x^2 + 6*x - sage: h.characteristic_polynomial.clear_cache() # long time - sage: h.characteristic_polynomial() # long time + sage: h.characteristic_polynomial.clear_cache() # long time # optional - sage.graphs + sage: h.characteristic_polynomial() # long time # optional - sage.graphs x^5 - 6*x^4 + 14*x^3 - 15*x^2 + 6*x """ n = G.num_verts() @@ -388,18 +388,18 @@ def Ish(self, n, K=QQ, names=None): EXAMPLES:: - sage: a = hyperplane_arrangements.Ish(3); a + sage: a = hyperplane_arrangements.Ish(3); a # optional - sage.combinat Arrangement of 6 hyperplanes of dimension 3 and rank 2 - sage: a.characteristic_polynomial() + sage: a.characteristic_polynomial() # optional - sage.combinat x^3 - 6*x^2 + 9*x - sage: b = hyperplane_arrangements.Shi(3) - sage: b.characteristic_polynomial() + sage: b = hyperplane_arrangements.Shi(3) # optional - sage.combinat + sage: b.characteristic_polynomial() # optional - sage.combinat x^3 - 6*x^2 + 9*x TESTS:: - sage: a.characteristic_polynomial.clear_cache() # long time - sage: a.characteristic_polynomial() # long time + sage: a.characteristic_polynomial.clear_cache() # long time # optional - sage.combinat + sage: a.characteristic_polynomial() # long time # optional - sage.combinat x^3 - 6*x^2 + 9*x REFERENCES: @@ -486,16 +486,16 @@ def semiorder(self, n, K=QQ, names=None): EXAMPLES:: - sage: hyperplane_arrangements.semiorder(4) + sage: hyperplane_arrangements.semiorder(4) # optional - sage.combinat Arrangement of 12 hyperplanes of dimension 4 and rank 3 TESTS:: - sage: h = hyperplane_arrangements.semiorder(5) - sage: h.characteristic_polynomial() + sage: h = hyperplane_arrangements.semiorder(5) # optional - sage.combinat + sage: h.characteristic_polynomial() # optional - sage.combinat x^5 - 20*x^4 + 180*x^3 - 790*x^2 + 1380*x - sage: h.characteristic_polynomial.clear_cache() # long time - sage: h.characteristic_polynomial() # long time + sage: h.characteristic_polynomial.clear_cache() # long time # optional - sage.combinat + sage: h.characteristic_polynomial() # long time # optional - sage.combinat x^5 - 20*x^4 + 180*x^3 - 790*x^2 + 1380*x """ H = make_parent(K, n, names) @@ -547,29 +547,29 @@ def Shi(self, data, K=QQ, names=None, m=1): EXAMPLES:: - sage: hyperplane_arrangements.Shi(4) + sage: hyperplane_arrangements.Shi(4) # optional - sage.combinat Arrangement of 12 hyperplanes of dimension 4 and rank 3 - sage: hyperplane_arrangements.Shi("A3") + sage: hyperplane_arrangements.Shi("A3") # optional - sage.combinat Arrangement of 12 hyperplanes of dimension 4 and rank 3 - sage: hyperplane_arrangements.Shi("A3",m=2) + sage: hyperplane_arrangements.Shi("A3", m=2) # optional - sage.combinat Arrangement of 24 hyperplanes of dimension 4 and rank 3 - sage: hyperplane_arrangements.Shi("B4") + sage: hyperplane_arrangements.Shi("B4") # optional - sage.combinat Arrangement of 32 hyperplanes of dimension 4 and rank 4 - sage: hyperplane_arrangements.Shi("B4",m=3) + sage: hyperplane_arrangements.Shi("B4", m=3) # optional - sage.combinat Arrangement of 96 hyperplanes of dimension 4 and rank 4 - sage: hyperplane_arrangements.Shi("C3") + sage: hyperplane_arrangements.Shi("C3") # optional - sage.combinat Arrangement of 18 hyperplanes of dimension 3 and rank 3 - sage: hyperplane_arrangements.Shi("D4",m=3) + sage: hyperplane_arrangements.Shi("D4", m=3) # optional - sage.combinat Arrangement of 72 hyperplanes of dimension 4 and rank 4 - sage: hyperplane_arrangements.Shi("E6") + sage: hyperplane_arrangements.Shi("E6") # optional - sage.combinat Arrangement of 72 hyperplanes of dimension 8 and rank 6 - sage: hyperplane_arrangements.Shi("E6",m=2) + sage: hyperplane_arrangements.Shi("E6", m=2) # optional - sage.combinat Arrangement of 144 hyperplanes of dimension 8 and rank 6 If the Cartan type is not crystallographic, the Shi arrangement is not defined:: - sage: hyperplane_arrangements.Shi("H4") + sage: hyperplane_arrangements.Shi("H4") # optional - sage.combinat Traceback (most recent call last): ... NotImplementedError: Shi arrangements are not defined for non crystallographic Cartan types @@ -577,36 +577,36 @@ def Shi(self, data, K=QQ, names=None, m=1): The characteristic polynomial is pre-computed using the results of [Ath1996]_:: - sage: hyperplane_arrangements.Shi("A3").characteristic_polynomial() + sage: hyperplane_arrangements.Shi("A3").characteristic_polynomial() # optional - sage.combinat x^4 - 12*x^3 + 48*x^2 - 64*x - sage: hyperplane_arrangements.Shi("A3",m=2).characteristic_polynomial() + sage: hyperplane_arrangements.Shi("A3", m=2).characteristic_polynomial() # optional - sage.combinat x^4 - 24*x^3 + 192*x^2 - 512*x - sage: hyperplane_arrangements.Shi("C3").characteristic_polynomial() + sage: hyperplane_arrangements.Shi("C3").characteristic_polynomial() # optional - sage.combinat x^3 - 18*x^2 + 108*x - 216 - sage: hyperplane_arrangements.Shi("E6").characteristic_polynomial() + sage: hyperplane_arrangements.Shi("E6").characteristic_polynomial() # optional - sage.combinat x^8 - 72*x^7 + 2160*x^6 - 34560*x^5 + 311040*x^4 - 1492992*x^3 + 2985984*x^2 - sage: hyperplane_arrangements.Shi("B4",m=3).characteristic_polynomial() + sage: hyperplane_arrangements.Shi("B4", m=3).characteristic_polynomial() # optional - sage.combinat x^4 - 96*x^3 + 3456*x^2 - 55296*x + 331776 TESTS:: - sage: h = hyperplane_arrangements.Shi(4) - sage: h.characteristic_polynomial() + sage: h = hyperplane_arrangements.Shi(4) # optional - sage.combinat + sage: h.characteristic_polynomial() # optional - sage.combinat x^4 - 12*x^3 + 48*x^2 - 64*x - sage: h.characteristic_polynomial.clear_cache() # long time - sage: h.characteristic_polynomial() # long time + sage: h.characteristic_polynomial.clear_cache() # long time # optional - sage.combinat + sage: h.characteristic_polynomial() # long time # optional - sage.combinat x^4 - 12*x^3 + 48*x^2 - 64*x - sage: h = hyperplane_arrangements.Shi("A3",m=2) - sage: h.characteristic_polynomial() + sage: h = hyperplane_arrangements.Shi("A3", m=2) # optional - sage.combinat + sage: h.characteristic_polynomial() # optional - sage.combinat x^4 - 24*x^3 + 192*x^2 - 512*x - sage: h.characteristic_polynomial.clear_cache() - sage: h.characteristic_polynomial() + sage: h.characteristic_polynomial.clear_cache() # optional - sage.combinat + sage: h.characteristic_polynomial() # optional - sage.combinat x^4 - 24*x^3 + 192*x^2 - 512*x - sage: h = hyperplane_arrangements.Shi("B3",m=3) - sage: h.characteristic_polynomial() + sage: h = hyperplane_arrangements.Shi("B3", m=3) # optional - sage.combinat + sage: h.characteristic_polynomial() # optional - sage.combinat x^3 - 54*x^2 + 972*x - 5832 - sage: h.characteristic_polynomial.clear_cache() - sage: h.characteristic_polynomial() + sage: h.characteristic_polynomial.clear_cache() # optional - sage.combinat + sage: h.characteristic_polynomial() # optional - sage.combinat x^3 - 54*x^2 + 972*x - 5832 """ if data in NN: diff --git a/src/sage/geometry/hyperplane_arrangement/plot.py b/src/sage/geometry/hyperplane_arrangement/plot.py index 05176797415..97d1d05a5a9 100644 --- a/src/sage/geometry/hyperplane_arrangement/plot.py +++ b/src/sage/geometry/hyperplane_arrangement/plot.py @@ -56,25 +56,26 @@ sage: H3. = HyperplaneArrangements(QQ) sage: A = H3([(1,0,0), 0], [(0,0,1), 5]) - sage: A.plot(hyperplane_opacities=0.5, hyperplane_labels=True, hyperplane_legend=False) # optional - sage.plot + sage: A.plot(hyperplane_opacities=0.5, hyperplane_labels=True, # optional - sage.plot + ....: hyperplane_legend=False) Graphics3d Object sage: c = H3([(1,0,0),0], [(0,0,1),5]) - sage: c.plot(ranges=10) # optional - sage.plot + sage: c.plot(ranges=10) # optional - sage.plot Graphics3d Object - sage: c.plot(ranges=[[9.5,10], [-3,3]]) # optional - sage.plot + sage: c.plot(ranges=[[9.5,10], [-3,3]]) # optional - sage.plot Graphics3d Object - sage: c.plot(ranges=[[[9.5,10], [-3,3]], [[-6,6], [-5,5]]]) # optional - sage.plot + sage: c.plot(ranges=[[[9.5,10], [-3,3]], [[-6,6], [-5,5]]]) # optional - sage.plot Graphics3d Object sage: H2. = HyperplaneArrangements(QQ) sage: h = H2([(1,1),0], [(1,-1),0], [(0,1),2]) - sage: h.plot(ranges=20) # optional - sage.plot + sage: h.plot(ranges=20) # optional - sage.plot Graphics object consisting of 3 graphics primitives - sage: h.plot(ranges=[-1, 10]) # optional - sage.plot + sage: h.plot(ranges=[-1, 10]) # optional - sage.plot Graphics object consisting of 3 graphics primitives - sage: h.plot(ranges=[[-1, 1], [-5, 5], [-1, 10]]) # optional - sage.plot + sage: h.plot(ranges=[[-1, 1], [-5, 5], [-1, 10]]) # optional - sage.plot Graphics object consisting of 3 graphics primitives sage: a = hyperplane_arrangements.coordinate(3) @@ -83,24 +84,24 @@ sage: opts['label_offsets'] = [(0,2,2), (2,0,2), (2,2,0)] sage: opts['hyperplane_legend'] = False sage: opts['hyperplane_opacities'] = 0.7 - sage: a.plot(**opts) # optional - sage.plot + sage: a.plot(**opts) # optional - sage.plot Graphics3d Object sage: opts['hyperplane_labels'] = 'short' - sage: a.plot(**opts) # optional - sage.plot + sage: a.plot(**opts) # optional - sage.plot Graphics3d Object sage: H. = HyperplaneArrangements(QQ) sage: pts = H(3*u+4, 2*u+5, 7*u+1) - sage: pts.plot(hyperplane_colors=['yellow','black','blue']) # optional - sage.plot + sage: pts.plot(hyperplane_colors=['yellow','black','blue']) # optional - sage.plot Graphics object consisting of 3 graphics primitives - sage: pts.plot(point_sizes=[50,100,200], hyperplane_colors='blue') # optional - sage.plot + sage: pts.plot(point_sizes=[50,100,200], hyperplane_colors='blue') # optional - sage.plot Graphics object consisting of 3 graphics primitives sage: H. = HyperplaneArrangements(QQ) sage: a = H(x, y+1, y+2) - sage: a.plot(hyperplane_labels=True,label_colors='blue',label_fontsize=18) # optional - sage.plot + sage: a.plot(hyperplane_labels=True, label_colors='blue', label_fontsize=18) # optional - sage.plot Graphics3d Object - sage: a.plot(hyperplane_labels=True,label_colors=['red','green','black']) # optional - sage.plot + sage: a.plot(hyperplane_labels=True, label_colors=['red','green','black']) # optional - sage.plot Graphics3d Object """ from copy import copy @@ -114,7 +115,6 @@ lazy_import("sage.plot.text", "text") lazy_import("sage.plot.point", "point") lazy_import("sage.plot.plot", "parametric_plot") -from sage.symbolic.ring import SR def plot(hyperplane_arrangement, **kwds): @@ -144,8 +144,8 @@ def plot(hyperplane_arrangement, **kwds): EXAMPLES:: - sage: B = hyperplane_arrangements.semiorder(4) - sage: B.plot() # optional - sage.plot + sage: B = hyperplane_arrangements.semiorder(4) # optional - sage.combinat + sage: B.plot() # optional - sage.combinat sage.plot Displaying the essentialization. Graphics3d Object """ @@ -330,33 +330,34 @@ def plot_hyperplane(hyperplane, **kwds): sage: H1. = HyperplaneArrangements(QQ) sage: a = 3*x + 4 - sage: a.plot() # indirect doctest # optional - sage.plot + sage: a.plot() # indirect doctest # optional - sage.plot Graphics object consisting of 3 graphics primitives - sage: a.plot(point_size=100,hyperplane_label='hello') # optional - sage.plot + sage: a.plot(point_size=100, hyperplane_label='hello') # optional - sage.plot Graphics object consisting of 3 graphics primitives sage: H2. = HyperplaneArrangements(QQ) sage: b = 3*x + 4*y + 5 - sage: b.plot() # optional - sage.plot + sage: b.plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives - sage: b.plot(ranges=(1,5),label_offset=(2,-1)) # optional - sage.plot + sage: b.plot(ranges=(1,5), label_offset=(2,-1)) # optional - sage.plot Graphics object consisting of 2 graphics primitives - sage: opts = {'hyperplane_label':True, 'label_color':'green', - ....: 'label_fontsize':24, 'label_offset':(0,1.5)} - sage: b.plot(**opts) # optional - sage.plot + sage: opts = {'hyperplane_label': True, 'label_color': 'green', + ....: 'label_fontsize': 24, 'label_offset': (0,1.5)} + sage: b.plot(**opts) # optional - sage.plot Graphics object consisting of 2 graphics primitives sage: H3. = HyperplaneArrangements(QQ) sage: c = 2*x + 3*y + 4*z + 5 - sage: c.plot() # optional - sage.plot + sage: c.plot() # optional - sage.plot Graphics3d Object - sage: c.plot(label_offset=(1,0,1), color='green', label_color='red', frame=False) # optional - sage.plot + sage: c.plot(label_offset=(1,0,1), color='green', label_color='red', # optional - sage.plot + ....: frame=False) Graphics3d Object sage: d = -3*x + 2*y + 2*z + 3 - sage: d.plot(opacity=0.8) # optional - sage.plot + sage: d.plot(opacity=0.8) # optional - sage.plot Graphics3d Object sage: e = 4*x + 2*z + 3 - sage: e.plot(ranges=[[-1,1],[0,8]], label_offset=(2,2,1), aspect_ratio=1) # optional - sage.plot + sage: e.plot(ranges=[[-1,1],[0,8]], label_offset=(2,2,1), aspect_ratio=1) # optional - sage.plot Graphics3d Object """ if hyperplane.base_ring().characteristic(): @@ -420,6 +421,7 @@ def plot_hyperplane(hyperplane, **kwds): elif hyperplane.dimension() == 1: # a line in the plane pnt = hyperplane.point() w = hyperplane.linear_part().matrix() + from sage.symbolic.ring import SR t = SR.var('t') if ranges_set: if isinstance(ranges, (list, tuple)): @@ -440,6 +442,7 @@ def plot_hyperplane(hyperplane, **kwds): elif hyperplane.dimension() == 2: # a plane in 3-space pnt = hyperplane.point() w = hyperplane.linear_part().matrix() + from sage.symbolic.ring import SR s, t = SR.var('s t') if ranges_set: if isinstance(ranges, (list, tuple)): @@ -484,22 +487,22 @@ def legend_3d(hyperplane_arrangement, hyperplane_colors, length): EXAMPLES:: - sage: a = hyperplane_arrangements.semiorder(3) + sage: a = hyperplane_arrangements.semiorder(3) # optional - sage.combinat sage: from sage.geometry.hyperplane_arrangement.plot import legend_3d - sage: legend_3d(a, list(colors.values())[:6],length='long') + sage: legend_3d(a, list(colors.values())[:6], length='long') # optional - sage.combinat sage.plot Graphics object consisting of 6 graphics primitives - sage: b = hyperplane_arrangements.semiorder(4) - sage: c = b.essentialization() - sage: legend_3d(c, list(colors.values())[:12], length='long') + sage: b = hyperplane_arrangements.semiorder(4) # optional - sage.combinat + sage: c = b.essentialization() # optional - sage.combinat + sage: legend_3d(c, list(colors.values())[:12], length='long') # optional - sage.combinat sage.plot Graphics object consisting of 12 graphics primitives - sage: legend_3d(c, list(colors.values())[:12], length='short') + sage: legend_3d(c, list(colors.values())[:12], length='short') # optional - sage.plot Graphics object consisting of 12 graphics primitives - sage: p = legend_3d(c, list(colors.values())[:12], length='short') - sage: p.set_legend_options(ncol=4) - sage: type(p) + sage: p = legend_3d(c, list(colors.values())[:12], length='short') # optional - sage.plot + sage: p.set_legend_options(ncol=4) # optional - sage.plot + sage: type(p) # optional - sage.plot """ if hyperplane_arrangement.dimension() != 3: diff --git a/src/sage/geometry/integral_points.pxi b/src/sage/geometry/integral_points.pxi index e5ddce891a1..dae34bc99af 100644 --- a/src/sage/geometry/integral_points.pxi +++ b/src/sage/geometry/integral_points.pxi @@ -474,8 +474,8 @@ cpdef rectangular_box_points(list box_min, list box_max, Long ints and non-integral polyhedra are explicitly allowed:: - sage: polytope = Polyhedron([[1], [10*pi.n()]], base_ring=RDF) - sage: len( rectangular_box_points([-100], [100], polytope) ) + sage: polytope = Polyhedron([[1], [10*pi.n()]], base_ring=RDF) # optional - sage.symbolic + sage: len(rectangular_box_points([-100], [100], polytope)) # optional - sage.symbolic 31 sage: halfplane = Polyhedron(ieqs=[(-1,1,0)]) @@ -488,15 +488,15 @@ cpdef rectangular_box_points(list box_min, list box_max, Using a PPL polyhedron:: - sage: from ppl import Variable, Generator_System, C_Polyhedron, point - sage: gs = Generator_System() - sage: x = Variable(0); y = Variable(1); z = Variable(2) - sage: gs.insert(point(0*x + 1*y + 0*z)) - sage: gs.insert(point(0*x + 1*y + 3*z)) - sage: gs.insert(point(3*x + 1*y + 0*z)) - sage: gs.insert(point(3*x + 1*y + 3*z)) - sage: poly = C_Polyhedron(gs) - sage: rectangular_box_points([0]*3, [3]*3, poly) + sage: from ppl import Variable, Generator_System, C_Polyhedron, point # optional - pplpy + sage: gs = Generator_System() # optional - pplpy + sage: x = Variable(0); y = Variable(1); z = Variable(2) # optional - pplpy + sage: gs.insert(point(0*x + 1*y + 0*z)) # optional - pplpy + sage: gs.insert(point(0*x + 1*y + 3*z)) # optional - pplpy + sage: gs.insert(point(3*x + 1*y + 0*z)) # optional - pplpy + sage: gs.insert(point(3*x + 1*y + 3*z)) # optional - pplpy + sage: poly = C_Polyhedron(gs) # optional - pplpy + sage: rectangular_box_points([0]*3, [3]*3, poly) # optional - pplpy ((0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 1, 3), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 1, 3), (2, 1, 0), (2, 1, 1), (2, 1, 2), (2, 1, 3), (3, 1, 0), (3, 1, 1), (3, 1, 2), (3, 1, 3)) @@ -739,7 +739,7 @@ cdef class Inequality_generic: EXAMPLES:: sage: from sage.geometry.integral_points import Inequality_generic - sage: Inequality_generic([2*pi,sqrt(3),7/2], -5.5) + sage: Inequality_generic([2 * pi, sqrt(3), 7/2], -5.5) # optional - sage.symbolic generic: (2*pi, sqrt(3), 7/2) x + -5.50000000000000 >= 0 """ @@ -761,7 +761,7 @@ cdef class Inequality_generic: EXAMPLES:: sage: from sage.geometry.integral_points import Inequality_generic - sage: Inequality_generic([2*pi,sqrt(3),7/2], -5.5) + sage: Inequality_generic([2 * pi, sqrt(3), 7/2], -5.5) # optional - sage.symbolic generic: (2*pi, sqrt(3), 7/2) x + -5.50000000000000 >= 0 """ self.A = A @@ -1131,16 +1131,16 @@ cdef class InequalityCollection: EXAMPLES:: - sage: from ppl import Variable, Generator_System, C_Polyhedron, point - sage: gs = Generator_System() - sage: x = Variable(0); y = Variable(1); z = Variable(2) - sage: gs.insert(point(0*x + 0*y + 1*z)) - sage: gs.insert(point(0*x + 3*y + 1*z)) - sage: gs.insert(point(3*x + 0*y + 1*z)) - sage: gs.insert(point(3*x + 3*y + 1*z)) - sage: poly = C_Polyhedron(gs) - sage: from sage.geometry.integral_points import InequalityCollection - sage: InequalityCollection(poly, [0,2,1], [0]*3, [3]*3 ) + sage: from ppl import Variable, Generator_System, C_Polyhedron, point # optional - pplpy + sage: gs = Generator_System() # optional - pplpy + sage: x = Variable(0); y = Variable(1); z = Variable(2) # optional - pplpy + sage: gs.insert(point(0*x + 0*y + 1*z)) # optional - pplpy + sage: gs.insert(point(0*x + 3*y + 1*z)) # optional - pplpy + sage: gs.insert(point(3*x + 0*y + 1*z)) # optional - pplpy + sage: gs.insert(point(3*x + 3*y + 1*z)) # optional - pplpy + sage: poly = C_Polyhedron(gs) # optional - pplpy + sage: from sage.geometry.integral_points import InequalityCollection # optional - pplpy + sage: InequalityCollection(poly, [0,2,1], [0]*3, [3]*3 ) # optional - pplpy The collection of inequalities integer: (0, 1, 0) x + -1 >= 0 integer: (0, -1, 0) x + 1 >= 0 @@ -1191,8 +1191,8 @@ cdef class InequalityCollection: Check that :trac:`21037` is fixed:: sage: P = Polyhedron(vertices=((0, 0), (17,3))) - sage: P += 1/1000*polytopes.regular_polygon(5) # optional - sage.rings.number_field - sage: P.integral_points() # optional - sage.rings.number_field + sage: P += 1/1000*polytopes.regular_polygon(5) # optional - sage.rings.number_field + sage: P.integral_points() # optional - sage.rings.number_field ((0, 0), (17, 3)) """ cdef list A diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 778e7934d3f..9ec62336eeb 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -295,7 +295,7 @@ def LatticePolytope(data, compute_vertices=True, n=0, lattice=None): sage: p.points() Empty collection in 3-d lattice M - sage: p.faces() + sage: p.faces() # optional - sage.graphs ((-1-d lattice polytope in 3-d lattice M,),) """ if isinstance(data, LatticePolytopeClass): @@ -765,15 +765,15 @@ def _compute_facets(self): sage: p = LatticePolytope([], lattice=ToricLattice(3).dual()); p -1-d lattice polytope in 3-d lattice M - sage: a = p.faces()[0][0] + sage: a = p.faces()[0][0] # optional - sage.graphs sage: p = LatticePolytope([], lattice=ToricLattice(3).dual()); p -1-d lattice polytope in 3-d lattice M - sage: a = p.faces()[0][0]; a + sage: a = p.faces()[0][0]; a # optional - sage.graphs -1-d lattice polytope in 3-d lattice M - sage: a.facet_normals() + sage: a.facet_normals() # optional - sage.graphs Empty collection in 3-d lattice N - sage: a + sage: a # optional - sage.graphs -1-d lattice polytope in 3-d lattice M """ assert not hasattr(self, "_facet_normals") @@ -1335,7 +1335,7 @@ def _sort_faces(self, faces): sage: o = lattice_polytope.cross_polytope(3) sage: # indirect doctest - sage: for i, face in enumerate(o.faces(0)): + sage: for i, face in enumerate(o.faces(0)): # optional - sage.graphs ....: if face.vertex(0) != o.vertex(i): ....: print("Wrong order!") """ @@ -1380,10 +1380,10 @@ def adjacent(self): EXAMPLES:: sage: o = lattice_polytope.cross_polytope(3) - sage: o.adjacent() + sage: o.adjacent() # optional - sage.graphs () - sage: face = o.faces(1)[0] - sage: face.adjacent() + sage: face = o.faces(1)[0] # optional - sage.graphs + sage: face.adjacent() # optional - sage.graphs (1-d face of 3-d reflexive polytope in 3-d lattice M, 1-d face of 3-d reflexive polytope in 3-d lattice M, 1-d face of 3-d reflexive polytope in 3-d lattice M, @@ -1505,12 +1505,12 @@ def ambient(self): 3-d reflexive polytope in 3-d lattice M sage: o.ambient() is o True - sage: face = o.faces(1)[0] - sage: face + sage: face = o.faces(1)[0] # optional - sage.graphs + sage: face # optional - sage.graphs 1-d face of 3-d reflexive polytope in 3-d lattice M - sage: face.ambient() + sage: face.ambient() # optional - sage.graphs 3-d reflexive polytope in 3-d lattice M - sage: face.ambient() is o + sage: face.ambient() is o # optional - sage.graphs True """ return self._ambient @@ -1533,14 +1533,14 @@ def ambient_facet_indices(self): But each of its other faces is contained in one or more facets:: - sage: face = o.faces(1)[0] - sage: face.ambient_facet_indices() + sage: face = o.faces(1)[0] # optional - sage.graphs + sage: face.ambient_facet_indices() # optional - sage.graphs (4, 5) - sage: face.vertices() + sage: face.vertices() # optional - sage.graphs M(1, 0, 0), M(0, 1, 0) in 3-d lattice M - sage: o.facets()[face.ambient_facet_indices()[0]].vertices() + sage: o.facets()[face.ambient_facet_indices()[0]].vertices() # optional - sage.graphs M(1, 0, 0), M(0, 1, 0), M(0, 0, -1) @@ -1561,10 +1561,10 @@ def ambient_point_indices(self): EXAMPLES:: sage: cube = lattice_polytope.cross_polytope(3).polar() - sage: face = cube.facets()[0] - sage: face.ambient_point_indices() # optional - palp + sage: face = cube.facets()[0] # optional - sage.graphs + sage: face.ambient_point_indices() # optional - palp sage.graphs (4, 5, 6, 7, 8, 9, 10, 11, 12) - sage: cube.points(face.ambient_point_indices()) == face.points() # optional - palp + sage: cube.points(face.ambient_point_indices()) == face.points() # optional - palp sage.graphs True """ if self._ambient is self: @@ -1587,10 +1587,10 @@ def ambient_ordered_point_indices(self): EXAMPLES:: sage: cube = lattice_polytope.cross_polytope(3).polar() - sage: face = cube.facets()[0] - sage: face.ambient_ordered_point_indices() # optional - palp + sage: face = cube.facets()[0] # optional - sage.graphs + sage: face.ambient_ordered_point_indices() # optional - palp sage.graphs (5, 8, 4, 9, 10, 11, 6, 12, 7) - sage: cube.points(face.ambient_ordered_point_indices()) # optional - palp + sage: cube.points(face.ambient_ordered_point_indices()) # optional - palp sage.graphs N(-1, -1, -1), N(-1, -1, 0), N(-1, -1, 1), @@ -1621,8 +1621,8 @@ def ambient_vertex_indices(self): sage: o = lattice_polytope.cross_polytope(3) sage: o.ambient_vertex_indices() (0, 1, 2, 3, 4, 5) - sage: face = o.faces(1)[0] - sage: face.ambient_vertex_indices() + sage: face = o.faces(1)[0] # optional - sage.graphs + sage: face.ambient_vertex_indices() # optional - sage.graphs (0, 1) """ return self._ambient_vertex_indices @@ -1657,13 +1657,13 @@ def boundary_point_indices(self): For an edge the boundary is formed by the end points:: - sage: face = square.edges()[0] - sage: face.points() + sage: face = square.edges()[0] # optional - sage.graphs + sage: face.points() # optional - sage.graphs N(-1, -1), N(-1, 1), N(-1, 0) in 2-d lattice N - sage: face.boundary_point_indices() + sage: face.boundary_point_indices() # optional - sage.graphs (0, 1) """ return tuple(i @@ -1696,8 +1696,8 @@ def boundary_points(self): For an edge the boundary is formed by the end points:: - sage: face = square.edges()[0] - sage: face.boundary_points() + sage: face = square.edges()[0] # optional - sage.graphs + sage: face.boundary_points() # optional - sage.graphs N(-1, -1), N(-1, 1) in 2-d lattice N @@ -1794,7 +1794,7 @@ def distances(self, point=None): sage: o.distances([1,2,3/2]) (-3/2, 5/2, 11/2, 3/2, -1/2, -7/2, 1/2, 7/2) - sage: o.distances([1,2,sqrt(2)]) + sage: o.distances([1,2,sqrt(2)]) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: unable to convert sqrt(2) to an element of Rational Field @@ -1842,15 +1842,15 @@ def dual(self): EXAMPLES:: sage: o = lattice_polytope.cross_polytope(4) - sage: e = o.edges()[0]; e + sage: e = o.edges()[0]; e # optional - sage.graphs 1-d face of 4-d reflexive polytope in 4-d lattice M - sage: ed = e.dual(); ed + sage: ed = e.dual(); ed # optional - sage.graphs 2-d face of 4-d reflexive polytope in 4-d lattice N - sage: ed.ambient() is e.ambient().polar() + sage: ed.ambient() is e.ambient().polar() # optional - sage.graphs True - sage: e.ambient_vertex_indices() == ed.ambient_facet_indices() + sage: e.ambient_vertex_indices() == ed.ambient_facet_indices() # optional - sage.graphs True - sage: e.ambient_facet_indices() == ed.ambient_vertex_indices() + sage: e.ambient_facet_indices() == ed.ambient_vertex_indices() # optional - sage.graphs True """ for f in self._ambient.polar().faces(codim=self.dim() + 1): @@ -1893,11 +1893,11 @@ def edges(self): EXAMPLES:: sage: o = lattice_polytope.cross_polytope(3) - sage: o.edges() + sage: o.edges() # optional - sage.graphs (1-d face of 3-d reflexive polytope in 3-d lattice M, ... 1-d face of 3-d reflexive polytope in 3-d lattice M) - sage: len(o.edges()) + sage: len(o.edges()) # optional - sage.graphs 12 """ return self.faces(dim=1) @@ -1920,13 +1920,12 @@ def face_lattice(self): Let's take a look at the face lattice of a square:: sage: square = LatticePolytope([(0,0), (1,0), (1,1), (0,1)]) - sage: L = square.face_lattice() - sage: L + sage: L = square.face_lattice(); L # optional - sage.graphs Finite lattice containing 10 elements with distinguished linear extension To see all faces arranged by dimension, you can do this:: - sage: for level in L.level_sets(): print(level) + sage: for level in L.level_sets(): print(level) # optional - sage.graphs [-1-d face of 2-d lattice polytope in 2-d lattice M] [0-d face of 2-d lattice polytope in 2-d lattice M, 0-d face of 2-d lattice polytope in 2-d lattice M, @@ -1940,31 +1939,31 @@ def face_lattice(self): For a particular face you can look at its actual vertices... :: - sage: face = L.level_sets()[1][0] - sage: face.vertices() + sage: face = L.level_sets()[1][0] # optional - sage.graphs + sage: face.vertices() # optional - sage.graphs M(0, 0) in 2-d lattice M ... or you can see the index of the vertex of the original polytope that corresponds to the above one:: - sage: face.ambient_vertex_indices() + sage: face.ambient_vertex_indices() # optional - sage.graphs (0,) - sage: square.vertex(0) + sage: square.vertex(0) # optional - sage.graphs M(0, 0) An alternative to extracting faces from the face lattice is to use :meth:`faces` method:: - sage: face is square.faces(dim=0)[0] + sage: face is square.faces(dim=0)[0] # optional - sage.graphs True The advantage of working with the face lattice directly is that you can (relatively easily) get faces that are related to the given one:: - sage: face = L.level_sets()[1][0] - sage: D = L.hasse_diagram() - sage: sorted(D.neighbors(face)) + sage: face = L.level_sets()[1][0] # optional - sage.graphs + sage: D = L.hasse_diagram() # optional - sage.graphs + sage: sorted(D.neighbors(face)) # optional - sage.graphs [-1-d face of 2-d lattice polytope in 2-d lattice M, 1-d face of 2-d lattice polytope in 2-d lattice M, 1-d face of 2-d lattice polytope in 2-d lattice M] @@ -1972,21 +1971,21 @@ def face_lattice(self): However, you can achieve some of this functionality using :meth:`facets`, :meth:`facet_of`, and :meth:`adjacent` methods:: - sage: face = square.faces(0)[0] - sage: face + sage: face = square.faces(0)[0] # optional - sage.graphs + sage: face # optional - sage.graphs 0-d face of 2-d lattice polytope in 2-d lattice M - sage: face.vertices() + sage: face.vertices() # optional - sage.graphs M(0, 0) in 2-d lattice M - sage: face.facets() + sage: face.facets() # optional - sage.graphs (-1-d face of 2-d lattice polytope in 2-d lattice M,) - sage: face.facet_of() + sage: face.facet_of() # optional - sage.graphs (1-d face of 2-d lattice polytope in 2-d lattice M, 1-d face of 2-d lattice polytope in 2-d lattice M) - sage: face.adjacent() + sage: face.adjacent() # optional - sage.graphs (0-d face of 2-d lattice polytope in 2-d lattice M, 0-d face of 2-d lattice polytope in 2-d lattice M) - sage: face.adjacent()[0].vertices() + sage: face.adjacent()[0].vertices() # optional - sage.graphs M(1, 0) in 2-d lattice M @@ -1995,20 +1994,20 @@ def face_lattice(self): sage: superp = LatticePolytope([(1,2,3,4), (5,6,7,8), ....: (1,2,4,8), (1,3,9,7)]) - sage: superp.face_lattice() + sage: superp.face_lattice() # optional - sage.graphs Finite lattice containing 16 elements with distinguished linear extension - sage: superp.face_lattice().top() + sage: superp.face_lattice().top() # optional - sage.graphs 3-d lattice polytope in 4-d lattice M - sage: p = superp.facets()[0] - sage: p + sage: p = superp.facets()[0] # optional - sage.graphs + sage: p # optional - sage.graphs 2-d face of 3-d lattice polytope in 4-d lattice M - sage: p.face_lattice() + sage: p.face_lattice() # optional - sage.graphs Finite poset containing 8 elements with distinguished linear extension - sage: p.face_lattice().bottom() + sage: p.face_lattice().bottom() # optional - sage.graphs -1-d face of 3-d lattice polytope in 4-d lattice M - sage: p.face_lattice().top() + sage: p.face_lattice().top() # optional - sage.graphs 2-d face of 3-d lattice polytope in 4-d lattice M - sage: p.face_lattice().top() is p + sage: p.face_lattice().top() is p # optional - sage.graphs True """ if self._ambient is self: @@ -2098,7 +2097,7 @@ def faces(self, dim=None, codim=None): Let's take a look at the faces of a square:: sage: square = LatticePolytope([(0,0), (1,0), (1,1), (0,1)]) - sage: square.faces() + sage: square.faces() # optional - sage.graphs ((-1-d face of 2-d lattice polytope in 2-d lattice M,), (0-d face of 2-d lattice polytope in 2-d lattice M, 0-d face of 2-d lattice polytope in 2-d lattice M, @@ -2112,7 +2111,7 @@ def faces(self, dim=None, codim=None): Its faces of dimension one (i.e., edges):: - sage: square.faces(dim=1) + sage: square.faces(dim=1) # optional - sage.graphs (1-d face of 2-d lattice polytope in 2-d lattice M, 1-d face of 2-d lattice polytope in 2-d lattice M, 1-d face of 2-d lattice polytope in 2-d lattice M, @@ -2120,16 +2119,16 @@ def faces(self, dim=None, codim=None): Its faces of codimension one are the same (also edges):: - sage: square.faces(codim=1) is square.faces(dim=1) + sage: square.faces(codim=1) is square.faces(dim=1) # optional - sage.graphs True Let's pick a particular face:: - sage: face = square.faces(dim=1)[0] + sage: face = square.faces(dim=1)[0] # optional - sage.graphs Now you can look at the actual vertices of this face... :: - sage: face.vertices() + sage: face.vertices() # optional - sage.graphs M(0, 0), M(0, 1) in 2-d lattice M @@ -2137,9 +2136,9 @@ def faces(self, dim=None, codim=None): ... or you can see indices of the vertices of the original polytope that correspond to the above ones:: - sage: face.ambient_vertex_indices() + sage: face.ambient_vertex_indices() # optional - sage.graphs (0, 3) - sage: square.vertices(face.ambient_vertex_indices()) + sage: square.vertices(face.ambient_vertex_indices()) # optional - sage.graphs M(0, 0), M(0, 1) in 2-d lattice M @@ -2365,12 +2364,12 @@ def facet_of(self): EXAMPLES:: sage: square = LatticePolytope([(0,0), (1,0), (1,1), (0,1)]) - sage: square.facet_of() + sage: square.facet_of() # optional - sage.graphs () - sage: face = square.faces(0)[0] - sage: len(face.facet_of()) + sage: face = square.faces(0)[0] # optional - sage.graphs + sage: len(face.facet_of()) # optional - sage.graphs 2 - sage: face.facet_of()[1] + sage: face.facet_of()[1] # optional - sage.graphs 1-d face of 2-d lattice polytope in 2-d lattice M """ L = self._ambient.face_lattice() @@ -2388,11 +2387,11 @@ def facets(self): EXAMPLES:: sage: o = lattice_polytope.cross_polytope(3) - sage: o.facets() + sage: o.facets() # optional - sage.graphs (2-d face of 3-d reflexive polytope in 3-d lattice M, ... 2-d face of 3-d reflexive polytope in 3-d lattice M) - sage: len(o.facets()) + sage: len(o.facets()) # optional - sage.graphs 8 """ return self.faces(codim=1) @@ -2420,14 +2419,14 @@ def incidence_matrix(self): [0 1 1 0] [1 1 0 0] [1 0 0 1] - sage: o.faces(1)[0].incidence_matrix() + sage: o.faces(1)[0].incidence_matrix() # optional - sage.graphs [1 0] [0 1] sage: o = lattice_polytope.cross_polytope(4) sage: o.incidence_matrix().column(3).nonzero_positions() [3, 4, 5, 6] - sage: o.facets()[3].ambient_vertex_indices() + sage: o.facets()[3].ambient_vertex_indices() # optional - sage.graphs (3, 4, 5, 6) TESTS:: @@ -2532,7 +2531,7 @@ def interior_point_indices(self): The origin is the only interior point of this square:: sage: square = lattice_polytope.cross_polytope(2).polar() - sage: square.points() # optional - palp + sage: square.points() # optional - palp N( 1, 1), N( 1, -1), N(-1, -1), @@ -2543,18 +2542,18 @@ def interior_point_indices(self): N( 0, 1), N( 1, 0) in 2-d lattice N - sage: square.interior_point_indices() # optional - palp + sage: square.interior_point_indices() # optional - palp (6,) Its edges also have a single interior point each:: - sage: face = square.edges()[0] - sage: face.points() + sage: face = square.edges()[0] # optional - sage.graphs + sage: face.points() # optional - sage.graphs N(-1, -1), N(-1, 1), N(-1, 0) in 2-d lattice N - sage: face.interior_point_indices() + sage: face.interior_point_indices() # optional - sage.graphs (2,) """ return tuple(i @@ -2574,14 +2573,14 @@ def interior_points(self): The origin is the only interior point of this square:: sage: square = lattice_polytope.cross_polytope(2).polar() - sage: square.interior_points() # optional - palp + sage: square.interior_points() # optional - palp N(0, 0) in 2-d lattice N Its edges also have a single interior point each:: - sage: face = square.edges()[0] - sage: face.interior_points() + sage: face = square.edges()[0] # optional - sage.graphs + sage: face.interior_points() # optional - sage.graphs N(-1, 0) in 2-d lattice N """ @@ -2667,7 +2666,7 @@ def ambient_vector_space(self, base_field=None): sage: p = LatticePolytope([(1,0)]) sage: p.ambient_vector_space() Vector space of dimension 2 over Rational Field - sage: p.ambient_vector_space(AA) + sage: p.ambient_vector_space(AA) # optional - sage.rings.number_field Vector space of dimension 2 over Algebraic Real Field """ return self.lattice().vector_space(base_field=base_field) @@ -2763,7 +2762,7 @@ def nef_partitions(self, keep_symmetric=False, keep_products=True, But they can be obtained from ``nef.x`` for all nef-partitions at once. Partitions will be exactly the same:: - sage: p.nef_partitions(hodge_numbers=True) # long time (2s on sage.math, 2011) # optional - palp + sage: p.nef_partitions(hodge_numbers=True) # long time (2s on sage.math, 2011) # optional - palp [ Nef-partition {0, 1, 4, 5} ⊔ {2, 3, 6, 7} (direct product), Nef-partition {0, 1, 2, 4} ⊔ {3, 5, 6, 7}, @@ -3055,13 +3054,13 @@ def _palp_modified_normal_form(self, permutation=False): M(-1, 0), M( 0, -1) in 2-d lattice M - sage: o._palp_modified_normal_form() + sage: o._palp_modified_normal_form() # optional - sage.graphs M( 1, 0), M( 0, 1), M( 0, -1), M(-1, 0) in 2-d lattice M - sage: o._palp_modified_normal_form(permutation=True) + sage: o._palp_modified_normal_form(permutation=True) # optional - sage.graphs (M( 1, 0), M( 0, 1), M( 0, -1), @@ -3108,13 +3107,13 @@ def _palp_native_normal_form(self, permutation=False): M(-1, 0), M( 0, -1) in 2-d lattice M - sage: o._palp_native_normal_form() + sage: o._palp_native_normal_form() # optional - sage.groups M( 1, 0), M( 0, 1), M( 0, -1), M(-1, 0) in 2-d lattice M - sage: o._palp_native_normal_form(permutation=True) + sage: o._palp_native_normal_form(permutation=True) # optional - sage.groups (M( 1, 0), M( 0, 1), M( 0, -1), @@ -3159,8 +3158,8 @@ def _palp_PM_max(self, check=False): sage: o = lattice_polytope.cross_polytope(2) sage: PM = o.vertex_facet_pairing_matrix() - sage: PM_max = PM.permutation_normal_form() - sage: PM_max == o._palp_PM_max() + sage: PM_max = PM.permutation_normal_form() # optional - sage.graphs + sage: PM_max == o._palp_PM_max() # optional - sage.graphs True sage: P2 = ReflexivePolytope(2, 0) sage: PM_max, permutations = P2._palp_PM_max(check=True) @@ -3565,28 +3564,30 @@ def plot3d(self, EXAMPLES: The default plot of a cube:: sage: c = lattice_polytope.cross_polytope(3).polar() - sage: c.plot3d() # optional - palp sage.plot + sage: c.plot3d() # optional - palp sage.plot Graphics3d Object Plot without facets and points, shown without the frame:: - sage: c.plot3d(show_facets=false, show_points=false).show(frame=False) # optional - palp sage.plot + sage: c.plot3d(show_facets=false, # optional - palp sage.plot + ....: show_points=false).show(frame=False) Plot with facets of different colors:: - sage: c.plot3d(facet_colors=rainbow(c.nfacets(), 'rgbtuple')) # optional - palp sage.plot + sage: c.plot3d(facet_colors=rainbow(c.nfacets(), 'rgbtuple')) # optional - palp sage.plot Graphics3d Object It is also possible to plot lower dimensional polytops in 3D (let's also change labels of vertices):: - sage: lattice_polytope.cross_polytope(2).plot3d(vlabels=["A", "B", "C", "D"]) # optional - palp sage.plot + sage: c2 = lattice_polytope.cross_polytope(2) + sage: c2.plot3d(vlabels=["A", "B", "C", "D"]) # optional - palp sage.plot Graphics3d Object TESTS:: sage: p = LatticePolytope([[0,0,0],[0,1,1],[1,0,1],[1,1,0]]) - sage: p.plot3d() # optional - palp sage.plot + sage: p.plot3d() # optional - palp sage.plot Graphics3d Object """ dim = self.dim() @@ -3971,9 +3972,9 @@ def skeleton(self): EXAMPLES:: sage: d = lattice_polytope.cross_polytope(2) - sage: g = d.skeleton(); g # optional - palp + sage: g = d.skeleton(); g # optional - palp sage.graphs Graph on 4 vertices - sage: g.edges(sort=True) # optional - palp + sage: g.edges(sort=True) # optional - palp sage.graphs [(0, 1, None), (0, 3, None), (1, 2, None), (2, 3, None)] """ skeleton = Graph() @@ -3993,34 +3994,37 @@ def skeleton_points(self, k=1): sage: o = lattice_polytope.cross_polytope(3) sage: c = o.polar() - sage: c.skeleton_points() # optional - palp + sage: c.skeleton_points() # optional - palp sage.graphs [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 15, 19, 21, 22, 23, 25, 26] The default was 1-skeleton:: - sage: c.skeleton_points(k=1) # optional - palp + sage: c.skeleton_points(k=1) # optional - palp sage.graphs [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 15, 19, 21, 22, 23, 25, 26] 0-skeleton just lists all vertices:: - sage: c.skeleton_points(k=0) # optional - palp + sage: c.skeleton_points(k=0) # optional - palp sage.graphs [0, 1, 2, 3, 4, 5, 6, 7] 2-skeleton lists all points except for the origin (point #17):: - sage: c.skeleton_points(k=2) # optional - palp - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26] + sage: c.skeleton_points(k=2) # optional - palp sage.graphs + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 18, 19, 20, 21, 22, 23, 24, 25, 26] 3-skeleton includes all points:: - sage: c.skeleton_points(k=3) # optional - palp - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26] + sage: c.skeleton_points(k=3) # optional - palp sage.graphs + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26] It is OK to compute higher dimensional skeletons - you will get the list of all points:: - sage: c.skeleton_points(k=100) # optional - palp - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26] + sage: c.skeleton_points(k=100) # optional - palp sage.graphs + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26] """ if k >= self.dim(): return list(range(self.npoints())) @@ -4074,7 +4078,7 @@ def traverse_boundary(self): EXAMPLES:: sage: p = lattice_polytope.cross_polytope(2).polar() - sage: p.traverse_boundary() + sage: p.traverse_boundary() # optional - sage.graphs [3, 0, 1, 2] """ if self.dim() != 2: @@ -4740,13 +4744,13 @@ def hodge_numbers(self): nef-partitions:: sage: p = lattice_polytope.cross_polytope(5) - sage: np = p.nef_partitions()[0] # long time (4s on sage.math, 2011) # optional - palp - sage: np.hodge_numbers() # long time # optional - palp + sage: np = p.nef_partitions()[0] # long time (4s on sage.math, 2011) # optional - palp + sage: np.hodge_numbers() # long time # optional - palp Traceback (most recent call last): ... NotImplementedError: use nef_partitions(hodge_numbers=True)! - sage: np = p.nef_partitions(hodge_numbers=True)[0] # long time (13s on sage.math, 2011) # optional - palp - sage: np.hodge_numbers() # long time # optional - palp + sage: np = p.nef_partitions(hodge_numbers=True)[0] # long time (13s on sage.math, 2011) # optional - palp + sage: np.hodge_numbers() # long time # optional - palp (19, 19) """ try: @@ -5092,25 +5096,26 @@ def _palp(command, polytopes, reduce_dimension=False): TESTS:: sage: o = lattice_polytope.cross_polytope(3) - sage: result_name = lattice_polytope._palp("poly.x -f", [o]) # optional - palp - sage: f = open(result_name) # optional - palp - sage: f.readlines() # optional - palp + sage: result_name = lattice_polytope._palp("poly.x -f", [o]) # optional - palp + sage: f = open(result_name) # optional - palp + sage: f.readlines() # optional - palp ['M:7 6 N:27 8 Pic:17 Cor:0\n'] - sage: f.close() # optional - palp - sage: os.remove(result_name) # optional - palp + sage: f.close() # optional - palp + sage: os.remove(result_name) # optional - palp sage: p = LatticePolytope([(1,0,0), (0,1,0), (-1,0,0), (0,-1,0)]) - sage: lattice_polytope._palp("poly.x -f", [p]) # optional - palp + sage: lattice_polytope._palp("poly.x -f", [p]) # optional - palp Traceback (most recent call last): ... ValueError: Cannot run PALP for a 2-dimensional polytope in a 3-dimensional space! - sage: result_name = lattice_polytope._palp("poly.x -f", [p], reduce_dimension=True) # optional - palp - sage: f = open(result_name) # optional - palp - sage: f.readlines() # optional - palp + sage: result_name = lattice_polytope._palp("poly.x -f", [p], # optional - palp + ....: reduce_dimension=True) + sage: f = open(result_name) # optional - palp + sage: f.readlines() # optional - palp ['M:5 4 F:4\n'] - sage: f.close() # optional - palp - sage: os.remove(result_name) # optional - palp + sage: f.close() # optional - palp + sage: os.remove(result_name) # optional - palp """ if _palp_dimension is not None: dot = command.find(".") @@ -5181,9 +5186,9 @@ def _palp_canonical_order(V, PM_max, permutations): sage: L = lattice_polytope.cross_polytope(2) sage: V = L.vertices() - sage: PM_max, permutations = L._palp_PM_max(check=True) # optional - sage.groups + sage: PM_max, permutations = L._palp_PM_max(check=True) # optional - sage.groups sage: from sage.geometry.lattice_polytope import _palp_canonical_order - sage: _palp_canonical_order(V, PM_max, permutations) # optional - sage.groups + sage: _palp_canonical_order(V, PM_max, permutations) # optional - sage.groups (M( 1, 0), M( 0, 1), M( 0, -1), @@ -5236,9 +5241,9 @@ def _palp_convert_permutation(permutation): EXAMPLES:: sage: from sage.geometry.lattice_polytope import _palp_convert_permutation - sage: _palp_convert_permutation('1023') # optional - sage.groups + sage: _palp_convert_permutation('1023') # optional - sage.groups (1,2) - sage: _palp_convert_permutation('0123456789bac') # optional - sage.groups + sage: _palp_convert_permutation('0123456789bac') # optional - sage.groups (11,12) """ def from_palp_index(i): @@ -5670,8 +5675,8 @@ def positive_integer_relations(points): EXAMPLES: This is a 3-dimensional reflexive polytope:: sage: p = LatticePolytope([(1,0,0), (0,1,0), - ....: (-1,-1,0), (0,0,1), (-1,0,-1)]) - sage: p.points() # optional - palp + ....: (-1,-1,0), (0,0,1), (-1,0,-1)]) + sage: p.points() # optional - palp M( 1, 0, 0), M( 0, 1, 0), M(-1, -1, 0), @@ -5683,7 +5688,7 @@ def positive_integer_relations(points): We can compute linear relations between its points in the following way:: - sage: p.points().matrix().kernel().echelonized_basis_matrix() # optional - palp + sage: p.points().matrix().kernel().echelonized_basis_matrix() # optional - palp [ 1 0 0 1 1 0] [ 0 1 1 -1 -1 0] [ 0 0 0 0 0 1] @@ -5692,7 +5697,8 @@ def positive_integer_relations(points): numbers. This function transforms them in such a way, that all coefficients are non-negative integers:: - sage: lattice_polytope.positive_integer_relations(p.points().column_matrix()) # optional - palp + sage: points = p.points().column_matrix() + sage: lattice_polytope.positive_integer_relations(points) # optional - palp [1 0 0 1 1 0] [1 1 1 0 0 0] [0 0 0 0 0 1] diff --git a/src/sage/geometry/polyhedral_complex.py b/src/sage/geometry/polyhedral_complex.py index 629a4f9ba2a..cff7b73c94e 100644 --- a/src/sage/geometry/polyhedral_complex.py +++ b/src/sage/geometry/polyhedral_complex.py @@ -117,7 +117,7 @@ from sage.rings.integer_ring import ZZ from sage.graphs.graph import Graph from sage.combinat.posets.posets import Poset -from sage.misc.misc import powerset +from sage.combinat.subset import powerset class PolyhedralComplex(GenericCellComplex): diff --git a/src/sage/geometry/polyhedron/backend_cdd_rdf.py b/src/sage/geometry/polyhedron/backend_cdd_rdf.py index 7aa60657fea..ed3f6cac169 100644 --- a/src/sage/geometry/polyhedron/backend_cdd_rdf.py +++ b/src/sage/geometry/polyhedron/backend_cdd_rdf.py @@ -1,3 +1,5 @@ +# sage.doctest: optional - sage.rings.real_double + r""" The cdd backend for polyhedral computations, floating point version """ diff --git a/src/sage/geometry/polyhedron/backend_normaliz.py b/src/sage/geometry/polyhedron/backend_normaliz.py index 8499e3704d0..ce389f090a2 100644 --- a/src/sage/geometry/polyhedron/backend_normaliz.py +++ b/src/sage/geometry/polyhedron/backend_normaliz.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - pynormaliz """ The Normaliz backend for polyhedral computations @@ -89,72 +90,74 @@ class Polyhedron_normaliz(Polyhedron_base_number_field): EXAMPLES:: - sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], rays=[(1,1)], # optional - pynormaliz - ....: lines=[], backend='normaliz') - sage: TestSuite(p).run() # optional - pynormaliz + sage: p = Polyhedron(vertices=[(0,0), (1,0), (0,1)], + ....: rays=[(1,1)], lines=[], + ....: backend='normaliz') + sage: TestSuite(p).run() Two ways to get the full space:: - sage: Polyhedron(eqns=[[0, 0, 0]], backend='normaliz') # optional - pynormaliz + sage: Polyhedron(eqns=[[0, 0, 0]], backend='normaliz') A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 lines - sage: Polyhedron(ieqs=[[0, 0, 0]], backend='normaliz') # optional - pynormaliz + sage: Polyhedron(ieqs=[[0, 0, 0]], backend='normaliz') A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 lines A lower-dimensional affine cone; we test that there are no mysterious inequalities coming in from the homogenization:: - sage: P = Polyhedron(vertices=[(1, 1)], rays=[(0, 1)], # optional - pynormaliz + sage: P = Polyhedron(vertices=[(1, 1)], rays=[(0, 1)], ....: backend='normaliz') - sage: P.n_inequalities() # optional - pynormaliz + sage: P.n_inequalities() 1 - sage: P.equations() # optional - pynormaliz + sage: P.equations() (An equation (1, 0) x - 1 == 0,) The empty polyhedron:: - sage: P=Polyhedron(ieqs=[[-2, 1, 1], [-3, -1, -1], [-4, 1, -2]], # optional - pynormaliz - ....: backend='normaliz') - sage: P # optional - pynormaliz + sage: P = Polyhedron(ieqs=[[-2, 1, 1], [-3, -1, -1], [-4, 1, -2]], + ....: backend='normaliz') + sage: P The empty polyhedron in QQ^2 - sage: P.Vrepresentation() # optional - pynormaliz + sage: P.Vrepresentation() () - sage: P.Hrepresentation() # optional - pynormaliz + sage: P.Hrepresentation() (An equation -1 == 0,) TESTS: Tests copied from various methods in :mod:`sage.geometry.polyhedron.base`:: - sage: p = Polyhedron(vertices = [[1,0,0], [0,1,0], [0,0,1]], # optional - pynormaliz + sage: p = Polyhedron(vertices=[[1,0,0], [0,1,0], [0,0,1]], ....: backend='normaliz') - sage: p.n_equations() # optional - pynormaliz + sage: p.n_equations() 1 - sage: p.n_inequalities() # optional - pynormaliz + sage: p.n_inequalities() 3 - sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in range(6)], # optional - pynormaliz + sage: p = Polyhedron(vertices=[[t,t^2,t^3] for t in range(6)], ....: backend='normaliz') - sage: p.n_facets() # optional - pynormaliz + sage: p.n_facets() 8 - sage: p = Polyhedron(vertices = [[1,0],[0,1],[1,1]], rays=[[1,1]], # optional - pynormaliz + sage: p = Polyhedron(vertices=[[1,0], [0,1], [1,1]], rays=[[1,1]], ....: backend='normaliz') - sage: p.n_vertices() # optional - pynormaliz + sage: p.n_vertices() 2 - sage: p = Polyhedron(vertices = [[1,0],[0,1]], rays=[[1,1]], # optional - pynormaliz + sage: p = Polyhedron(vertices=[[1,0], [0,1]], rays=[[1,1]], ....: backend='normaliz') - sage: p.n_rays() # optional - pynormaliz + sage: p.n_rays() 1 - sage: p = Polyhedron(vertices = [[0,0]], rays=[[0,1],[0,-1]], # optional - pynormaliz + sage: p = Polyhedron(vertices=[[0,0]], rays=[[0,1], [0,-1]], ....: backend='normaliz') - sage: p.n_lines() # optional - pynormaliz + sage: p.n_lines() 1 Algebraic polyhedra:: - sage: P = Polyhedron(vertices=[[1], [sqrt(2)]], backend='normaliz', verbose=True) # optional - pynormaliz # optional - sage.rings.number_field + sage: P = Polyhedron(vertices=[[1], [sqrt(2)]], # optional - sage.rings.number_field sage.symbolic + ....: backend='normaliz', verbose=True) # ----8<---- Equivalent Normaliz input file ----8<---- amb_space 1 number_field min_poly (a^2 - 2) embedding [1.414213562373095 +/- 2.99e-16] @@ -165,16 +168,23 @@ class Polyhedron_normaliz(Polyhedron_base_number_field): (a) 1 # ----8<-------------------8<-------------------8<---- # Calling PyNormaliz.NmzCone(cone=[], number_field=['a^2 - 2', 'a', '[1.414213562373095 +/- 2.99e-16]'], subspace=[], vertices=[[1, 1], [[[0, 1], [1, 1]], 1]]) - sage: P # optional - pynormaliz # optional - sage.rings.number_field - A 1-dimensional polyhedron in (Symbolic Ring)^1 defined as the convex hull of 2 vertices - sage: P.vertices() # optional - pynormaliz # optional - sage.rings.number_field + sage: P # optional - sage.rings.number_field sage.symbolic + A 1-dimensional polyhedron in (Symbolic Ring)^1 defined as + the convex hull of 2 vertices + sage: P.vertices() # optional - sage.rings.number_field sage.symbolic (A vertex at (1), A vertex at (sqrt(2))) - sage: P = polytopes.icosahedron(exact=True, backend='normaliz') # optional - pynormaliz # optional - sage.rings.number_field - sage: P # optional - pynormaliz # optional - sage.rings.number_field - A 3-dimensional polyhedron in (Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?)^3 defined as the convex hull of 12 vertices - - sage: x = polygen(ZZ); P = Polyhedron(vertices=[[sqrt(2)], [AA.polynomial_root(x^3-2, RIF(0,3))]], backend='normaliz', verbose=True) # optional - pynormaliz # optional - sage.rings.number_field + sage: P = polytopes.icosahedron(exact=True, # optional - sage.rings.number_field + ....: backend='normaliz'); P + A 3-dimensional polyhedron in + (Number Field in sqrt5 with defining polynomial x^2 - 5 + with sqrt5 = 2.236067977499790?)^3 + defined as the convex hull of 12 vertices + + sage: x = polygen(ZZ) + sage: P = Polyhedron(vertices=[[sqrt(2)], # optional - sage.rings.number_field sage.symbolic + ....: [AA.polynomial_root(x^3 - 2, RIF(0,3))]], + ....: backend='normaliz', verbose=True) # ----8<---- Equivalent Normaliz input file ----8<---- amb_space 1 number_field min_poly (a^6 - 2) embedding [1.122462048309373 +/- 5.38e-16] @@ -185,9 +195,10 @@ class Polyhedron_normaliz(Polyhedron_base_number_field): (a^2) 1 # ----8<-------------------8<-------------------8<---- # Calling PyNormaliz.NmzCone(cone=[], number_field=['a^6 - 2', 'a', '[1.122462048309373 +/- 5.38e-16]'], subspace=[], vertices=[[[[0, 1], [0, 1], [0, 1], [1, 1], [0, 1], [0, 1]], 1], [[[0, 1], [0, 1], [1, 1], [0, 1], [0, 1], [0, 1]], 1]]) - sage: P # optional - pynormaliz # optional - sage.rings.number_field - A 1-dimensional polyhedron in (Symbolic Ring)^1 defined as the convex hull of 2 vertices - sage: P.vertices() # optional - pynormaliz # optional - sage.rings.number_field + sage: P # optional - sage.rings.number_field sage.symbolic + A 1-dimensional polyhedron in (Symbolic Ring)^1 defined as + the convex hull of 2 vertices + sage: P.vertices() # optional - sage.rings.number_field sage.symbolic (A vertex at (2^(1/3)), A vertex at (sqrt(2))) """ @@ -200,14 +211,14 @@ def __init__(self, parent, Vrep, Hrep, normaliz_cone=None, normaliz_data=None, i TESTS:: - sage: p = Polyhedron(backend='normaliz') # optional - pynormaliz - sage: TestSuite(p).run() # optional - pynormaliz - sage: p = Polyhedron(vertices=[(1, 1)], rays=[(0, 1)], # optional - pynormaliz + sage: p = Polyhedron(backend='normaliz') + sage: TestSuite(p).run() + sage: p = Polyhedron(vertices=[(1, 1)], rays=[(0, 1)], ....: backend='normaliz') - sage: TestSuite(p).run() # optional - pynormaliz - sage: p = Polyhedron(vertices=[(-1,-1), (1,0), (1,1), (0,1)], # optional - pynormaliz + sage: TestSuite(p).run() + sage: p = Polyhedron(vertices=[(-1,-1), (1,0), (1,1), (0,1)], ....: backend='normaliz') - sage: TestSuite(p).run() # optional - pynormaliz + sage: TestSuite(p).run() """ if normaliz_cone: if Hrep is not None or Vrep is not None or normaliz_data is not None: @@ -230,29 +241,30 @@ def _nmz_result(self, normaliz_cone, property): TESTS:: - sage: p = Polyhedron(vertices=[(0, 0), (1, 0), (0, 1)], rays=[(1,1)], # optional - pynormaliz + sage: p = Polyhedron(vertices=[(0, 0), (1, 0), (0, 1)], rays=[(1,1)], ....: lines=[], backend='normaliz') - sage: p._nmz_result(p._normaliz_cone, 'EquivariantXyzzyModuleSeries') # optional - pynormaliz + sage: p._nmz_result(p._normaliz_cone, 'EquivariantXyzzyModuleSeries') Traceback (most recent call last): ... NormalizError: Some error in the normaliz input data detected: Unknown ConeProperty... - sage: x = polygen(QQ, 'x') # optional - sage.rings.number_field - sage: K. = NumberField(x^3 - 3, embedding=AA(3)**(1/3)) # optional - sage.rings.number_field - sage: p = Polyhedron(vertices=[(0, 0), (1, 1), (a, 3), (-1, a**2)], # optional - pynormaliz # optional - sage.rings.number_field + sage: x = polygen(QQ, 'x') # optional - sage.rings.number_field + sage: K. = NumberField(x^3 - 3, embedding=AA(3)**(1/3)) # optional - sage.rings.number_field + sage: p = Polyhedron(vertices=[(0, 0), (1, 1), (a, 3), (-1, a**2)], # optional - sage.rings.number_field ....: rays=[(-1,-a)], backend='normaliz') - sage: sorted(p._nmz_result(p._normaliz_cone, 'VerticesOfPolyhedron')) # optional - pynormaliz # optional - sage.rings.number_field + sage: sorted(p._nmz_result(p._normaliz_cone, 'VerticesOfPolyhedron')) # optional - sage.rings.number_field [[-1, a^2, 1], [1, 1, 1], [a, 3, 1]] - sage: triangulation_generators = p._nmz_result(p._normaliz_cone, 'Triangulation')[1] # optional - pynormaliz # optional - sage.rings.number_field - sage: sorted(triangulation_generators) # optional - pynormaliz # optional - sage.rings.number_field + sage: triangulation_generators = p._nmz_result(p._normaliz_cone, # optional - sage.rings.number_field + ....: 'Triangulation')[1] + sage: sorted(triangulation_generators) # optional - sage.rings.number_field [[-a^2, -3, 0], [-1, a^2, 1], [0, 0, 1], [1, 1, 1], [a, 3, 1]] - sage: p._nmz_result(p._normaliz_cone, 'AffineDim') == 2 # optional - pynormaliz # optional - sage.rings.number_field + sage: p._nmz_result(p._normaliz_cone, 'AffineDim') == 2 # optional - sage.rings.number_field True - sage: p._nmz_result(p._normaliz_cone, 'EmbeddingDim') == 3 # optional - pynormaliz # optional - sage.rings.number_field + sage: p._nmz_result(p._normaliz_cone, 'EmbeddingDim') == 3 # optional - sage.rings.number_field True - sage: p._nmz_result(p._normaliz_cone, 'ExtremeRays') # optional - pynormaliz # optional - sage.rings.number_field + sage: p._nmz_result(p._normaliz_cone, 'ExtremeRays') # optional - sage.rings.number_field [[-1/3*a^2, -1, 0]] - sage: p._nmz_result(p._normaliz_cone, 'MaximalSubspace') # optional - pynormaliz # optional - sage.rings.number_field + sage: p._nmz_result(p._normaliz_cone, 'MaximalSubspace') # optional - sage.rings.number_field [] """ def rational_handler(list): @@ -272,9 +284,9 @@ def _init_from_normaliz_cone(self, normaliz_cone, internal_base_ring): TESTS:: - sage: p = Polyhedron(backend='normaliz') # optional - pynormaliz - sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_normaliz # optional - pynormaliz - sage: Polyhedron_normaliz._init_from_Hrepresentation(p, [], []) # indirect doctest # optional - pynormaliz + sage: p = Polyhedron(backend='normaliz') + sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_normaliz + sage: Polyhedron_normaliz._init_from_Hrepresentation(p, [], []) # indirect doctest """ if internal_base_ring is None: internal_base_ring = QQ @@ -297,7 +309,7 @@ def _convert_to_pynormaliz(x): TESTS:: - sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: K. = QuadraticField(2) # optional - sage.rings.number_field sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_normaliz as Pn sage: Pn._convert_to_pynormaliz(17) 17 @@ -309,19 +321,21 @@ def _convert_to_pynormaliz(x): [[28, 5]] sage: Pn._convert_to_pynormaliz(28901824309821093821093812093810928309183091832091/5234573685674784567853456543456456786543456765) [[28901824309821093821093812093810928309183091832091, 5234573685674784567853456543456456786543456765]] - sage: Pn._convert_to_pynormaliz(7 + sqrt2) # optional - sage.rings.number_field + sage: Pn._convert_to_pynormaliz(7 + sqrt2) # optional - sage.rings.number_field [[7, 1], [1, 1]] - sage: Pn._convert_to_pynormaliz(7/2 + sqrt2) # optional - sage.rings.number_field + sage: Pn._convert_to_pynormaliz(7/2 + sqrt2) # optional - sage.rings.number_field [[7, 2], [1, 1]] sage: Pn._convert_to_pynormaliz([[1, 2], (3, 4)]) [[1, 2], [3, 4]] Check that :trac:`29836` is fixed:: - sage: P = polytopes.simplex(backend='normaliz') # optional - pynormaliz - sage: K. = QuadraticField(2) # optional - pynormaliz # optional - sage.rings.number_field - sage: P.dilation(sqrt2) # optional - pynormaliz # optional - sage.rings.number_field - A 3-dimensional polyhedron in (Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.41...)^4 defined as the convex hull of 4 vertices + sage: P = polytopes.simplex(backend='normaliz') + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: P.dilation(sqrt2) # optional - sage.rings.number_field + A 3-dimensional polyhedron in + (Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.41...)^4 + defined as the convex hull of 4 vertices """ def _QQ_pair(x): x = QQ(x) @@ -345,24 +359,25 @@ def _init_from_normaliz_data(self, data, internal_base_ring=None, verbose=False) TESTS:: - sage: p = Polyhedron(backend='normaliz', ambient_dim=2) # optional - pynormaliz - sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_QQ_normaliz # optional - pynormaliz - sage: data = {'inhom_inequalities': [[-1, 2, 0], [0, 0, 1], [2, -1, 0]]} # optional - pynormaliz - sage: Polyhedron_QQ_normaliz._init_from_normaliz_data(p, data) # optional - pynormaliz - sage: p.inequalities_list() # optional - pynormaliz + sage: p = Polyhedron(backend='normaliz', ambient_dim=2) + sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_QQ_normaliz + sage: data = {'inhom_inequalities': [[-1, 2, 0], [0, 0, 1], [2, -1, 0]]} + sage: Polyhedron_QQ_normaliz._init_from_normaliz_data(p, data) + sage: p.inequalities_list() [[0, -1, 2], [0, 2, -1]] - sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_normaliz # optional - pynormaliz - sage: from sage.rings.qqbar import AA # optional - pynormaliz # optional - sage.rings.number_field - sage: from sage.rings.number_field.number_field import QuadraticField # optional - pynormaliz # optional - sage.rings.number_field - sage: data = {'number_field': ['a^2 - 2', 'a', '[1.4 +/- 0.1]'], # optional - pynormaliz + sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_normaliz + sage: from sage.rings.qqbar import AA # optional - sage.rings.number_field + sage: from sage.rings.number_field.number_field import QuadraticField # optional - sage.rings.number_field + sage: data = {'number_field': ['a^2 - 2', 'a', '[1.4 +/- 0.1]'], ....: 'inhom_inequalities': [[-1, 2, 0], [0, 0, 1], [2, -1, 0]]} - sage: from sage.geometry.polyhedron.parent import Polyhedra_normaliz # optional - pynormaliz - sage: parent = Polyhedra_normaliz(AA, 2, 'normaliz') # optional - pynormaliz # optional - sage.rings.number_field - sage: Polyhedron_normaliz(parent, None, None, normaliz_data=data, # indirect doctest, optional - pynormaliz # optional - sage.rings.number_field + sage: from sage.geometry.polyhedron.parent import Polyhedra_normaliz + sage: parent = Polyhedra_normaliz(AA, 2, 'normaliz') # optional - sage.rings.number_field + sage: Polyhedron_normaliz(parent, None, None, # indirect doctest, optional - sage.rings.number_field + ....: normaliz_data=data, ....: internal_base_ring=QuadraticField(2)) A 2-dimensional polyhedron in AA^2 defined as the convex hull of 1 vertex and 2 rays - sage: _.inequalities_list() # optional - pynormaliz # optional - sage.rings.number_field + sage: _.inequalities_list() # optional - sage.rings.number_field [[0, -1/2, 1], [0, 2, -1]] """ if internal_base_ring is None: @@ -376,11 +391,11 @@ def _cone_from_normaliz_data(self, data, verbose=False): EXAMPLES:: - sage: p = Polyhedron(backend='normaliz', ambient_dim=2) # optional - pynormaliz - sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_QQ_normaliz # optional - pynormaliz - sage: data = {'inhom_inequalities': [[-1, 2, 0], [0, 0, 1], [2, -1, 0]]} # optional - pynormaliz - sage: cone = Polyhedron_QQ_normaliz._cone_from_normaliz_data(p, data) # optional - pynormaliz - sage: p._nmz_result(cone,'SupportHyperplanes') # optional - pynormaliz + sage: p = Polyhedron(backend='normaliz', ambient_dim=2) + sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_QQ_normaliz + sage: data = {'inhom_inequalities': [[-1, 2, 0], [0, 0, 1], [2, -1, 0]]} + sage: cone = Polyhedron_QQ_normaliz._cone_from_normaliz_data(p, data) + sage: p._nmz_result(cone,'SupportHyperplanes') [[-1, 2, 0], [0, 0, 1], [2, -1, 0]] """ if verbose: @@ -417,10 +432,10 @@ def _is_zero(self, x): EXAMPLES:: - sage: p = Polyhedron([(sqrt(3),sqrt(2))], base_ring=AA) # optional - sage.rings.number_field - sage: p._is_zero(0) # optional - sage.rings.number_field + sage: p = Polyhedron([(sqrt(3),sqrt(2))], base_ring=AA) # optional - sage.rings.number_field sage.symbolic + sage: p._is_zero(0) # optional - sage.rings.number_field sage.symbolic True - sage: p._is_zero(1/100000) # optional - sage.rings.number_field + sage: p._is_zero(1/100000) # optional - sage.rings.number_field sage.symbolic False """ return x == 0 @@ -439,10 +454,10 @@ def _is_nonneg(self, x): EXAMPLES:: - sage: p = Polyhedron([(sqrt(3),sqrt(2))], base_ring=AA) # optional - sage.rings.number_field - sage: p._is_nonneg(1) # optional - sage.rings.number_field + sage: p = Polyhedron([(sqrt(3),sqrt(2))], base_ring=AA) # optional - sage.rings.number_field sage.symbolic + sage: p._is_nonneg(1) # optional - sage.rings.number_field sage.symbolic True - sage: p._is_nonneg(-1/100000) # optional - sage.rings.number_field + sage: p._is_nonneg(-1/100000) # optional - sage.rings.number_field sage.symbolic False """ return x >= 0 @@ -461,10 +476,10 @@ def _is_positive(self, x): EXAMPLES:: - sage: p = Polyhedron([(sqrt(3),sqrt(2))], base_ring=AA) # optional - sage.rings.number_field - sage: p._is_positive(1) # optional - sage.rings.number_field + sage: p = Polyhedron([(sqrt(3),sqrt(2))], base_ring=AA) # optional - sage.rings.number_field sage.symbolic + sage: p._is_positive(1) # optional - sage.rings.number_field sage.symbolic True - sage: p._is_positive(0) # optional - sage.rings.number_field + sage: p._is_positive(0) # optional - sage.rings.number_field sage.symbolic False """ return x > 0 @@ -492,9 +507,9 @@ def _init_from_Vrepresentation(self, vertices, rays, lines, minimize=True, verbo EXAMPLES:: - sage: p = Polyhedron(backend='normaliz') # optional - pynormaliz - sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_normaliz # optional - pynormaliz - sage: Polyhedron_normaliz._init_from_Vrepresentation(p, [], [], []) # optional - pynormaliz + sage: p = Polyhedron(backend='normaliz') + sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_normaliz + sage: Polyhedron_normaliz._init_from_Vrepresentation(p, [], [], []) """ def vert_ray_line_QQ(vertices, rays, lines): @@ -565,27 +580,30 @@ def _init_from_Hrepresentation(self, ieqs, eqns, minimize=True, verbose=False): EXAMPLES:: - sage: p = Polyhedron(backend='normaliz') # optional - pynormaliz - sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_normaliz # optional - pynormaliz - sage: Polyhedron_normaliz._init_from_Hrepresentation(p, [], []) # optional - pynormaliz + sage: p = Polyhedron(backend='normaliz') + sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_normaliz + sage: Polyhedron_normaliz._init_from_Hrepresentation(p, [], []) TESTS:: - sage: K. = QuadraticField(2) # optional - sage.rings.number_field - sage: p = Polyhedron(ieqs=[(1, a, 0)], backend='normaliz') # optional - pynormaliz # optional - sage.rings.number_field - sage: p & p == p # optional - pynormaliz # optional - sage.rings.number_field + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: p = Polyhedron(ieqs=[(1, a, 0)], backend='normaliz') # optional - sage.rings.number_field + sage: p & p == p # optional - sage.rings.number_field True Check that :trac:`30248` is fixed, that maps as input works:: - sage: q = Polyhedron(backend='normaliz', base_ring=AA, # optional - pynormaliz # optional - sage.rings.number_field + sage: q = Polyhedron(backend='normaliz', base_ring=AA, # optional - sage.rings.number_field ....: rays=[(0, 0, 1), (0, 1, -1), (1, 0, -1)]) - sage: make_new_Hrep = lambda h: tuple(x if i == 0 else -1*x for i, x in enumerate(h._vector)) - sage: new_inequalities = map(make_new_Hrep, q.inequality_generator()) # optional - pynormaliz # optional - sage.rings.number_field - sage: new_equations = map(make_new_Hrep, q.equation_generator()) # optional - pynormaliz # optional - sage.rings.number_field - sage: parent = q.parent() # optional - pynormaliz # optional - sage.rings.number_field - sage: new_q = parent.element_class(parent,None,[new_inequalities,new_equations]) # optional - pynormaliz # optional - sage.rings.number_field - sage: new_q # optional - pynormaliz # optional - sage.rings.number_field + sage: def make_new_Hrep(h): + ....: return tuple(x if i == 0 else -1*x + ....: for i, x in enumerate(h._vector)) + sage: new_inequalities = map(make_new_Hrep, q.inequality_generator()) # optional - sage.rings.number_field + sage: new_equations = map(make_new_Hrep, q.equation_generator()) # optional - sage.rings.number_field + sage: parent = q.parent() # optional - sage.rings.number_field + sage: new_q = parent.element_class(parent, None, # optional - sage.rings.number_field + ....: [new_inequalities, new_equations]) + sage: new_q # optional - sage.rings.number_field A 3-dimensional polyhedron in AA^3 defined as the convex hull of 1 vertex and 3 rays """ @@ -669,28 +687,29 @@ def _cone_from_Vrepresentation_and_Hrepresentation(self, vertices, rays, lines, EXAMPLES:: - sage: P = polytopes.hypercube(4,backend='normaliz') * Polyhedron(rays=[[0,1]]) * Polyhedron(lines=[[1,0]]) # optional - pynormaliz - sage: P # optional - pynormaliz + sage: P = (polytopes.hypercube(4, backend='normaliz') + ....: * Polyhedron(rays=[[0,1]]) + ....: * Polyhedron(lines=[[1,0]])); P A 6-dimensional polyhedron in ZZ^8 defined as the convex hull of 16 vertices, 1 ray, 1 line - sage: cone = P._cone_from_Vrepresentation_and_Hrepresentation( # optional - pynormaliz + sage: cone = P._cone_from_Vrepresentation_and_Hrepresentation( ....: P.vertices(), P.rays(), P.lines(), ....: P.inequalities(), P.equations()) - sage: import PyNormaliz # optional - pynormaliz - sage: PyNormaliz.NmzIsComputed(cone, "VerticesOfPolyhedron") # optional - pynormaliz + sage: import PyNormaliz + sage: PyNormaliz.NmzIsComputed(cone, "VerticesOfPolyhedron") True - sage: PyNormaliz.NmzIsComputed(cone, "ExtremeRays") # optional - pynormaliz + sage: PyNormaliz.NmzIsComputed(cone, "ExtremeRays") True - sage: PyNormaliz.NmzIsComputed(cone, "MaximalSubspace") # optional - pynormaliz + sage: PyNormaliz.NmzIsComputed(cone, "MaximalSubspace") True - sage: PyNormaliz.NmzIsComputed(cone, "SupportHyperplanes") # optional - pynormaliz + sage: PyNormaliz.NmzIsComputed(cone, "SupportHyperplanes") True - sage: PyNormaliz.NmzIsComputed(cone, "Equations") # optional - pynormaliz + sage: PyNormaliz.NmzIsComputed(cone, "Equations") False All values must be specified:: - sage: cone = P._cone_from_Vrepresentation_and_Hrepresentation( # optional - pynormaliz + sage: cone = P._cone_from_Vrepresentation_and_Hrepresentation( ....: P.vertices(), None, P.lines(), ....: P.inequalities(), P.equations()) Traceback (most recent call last): @@ -699,8 +718,8 @@ def _cone_from_Vrepresentation_and_Hrepresentation(self, vertices, rays, lines, This method cannot be used for the empty cone:: - sage: P = Polyhedron(backend='normaliz') # optional - pynormaliz - sage: cone = P._cone_from_Vrepresentation_and_Hrepresentation( # optional - pynormaliz + sage: P = Polyhedron(backend='normaliz') + sage: cone = P._cone_from_Vrepresentation_and_Hrepresentation( ....: P.vertices(), P.rays(), P.lines(), ....: P.inequalities(), P.equations()) Traceback (most recent call last): @@ -713,32 +732,39 @@ def _cone_from_Vrepresentation_and_Hrepresentation(self, vertices, rays, lines, ....: cone = P._cone_from_Vrepresentation_and_Hrepresentation(P.vertices(),P.rays(),P.lines(),P.inequalities(),P.equations()) ....: cone2 = P._normaliz_cone ....: args = ['Equations','VerticesOfPolyhedron','ExtremeRays','SupportHyperplanes','MaximalSubspace'] - ....: return all(P._nmz_result(cone,arg) == P._nmz_result(cone2,arg) for arg in args) - sage: test_poly(polytopes.simplex(backend='normaliz')) # optional - pynormaliz + ....: return all(P._nmz_result(cone,arg) == P._nmz_result(cone2, arg) + ....: for arg in args) + sage: test_poly(polytopes.simplex(backend='normaliz')) True - sage: test_poly(polytopes.dodecahedron(backend='normaliz')) # optional - pynormaliz # optional - sage.rings.number_field + sage: test_poly(polytopes.dodecahedron(backend='normaliz')) # optional - sage.rings.number_field True - sage: test_poly(Polyhedron(vertices=[[1,0],[0,1]],rays=[[1,1]], backend='normaliz')) # optional - pynormaliz + sage: test_poly(Polyhedron(vertices=[[1,0], [0,1]], rays=[[1,1]], + ....: backend='normaliz')) True - sage: test_poly(Polyhedron(vertices=[[-1,0],[1,0]],lines=[[0,1]], backend='normaliz')) # optional - pynormaliz + sage: test_poly(Polyhedron(vertices=[[-1,0], [1,0]], lines=[[0,1]], + ....: backend='normaliz')) True - sage: test_poly(Polyhedron(rays=[[1,0,0],[0,1,0]], backend='normaliz')) # optional - pynormaliz + sage: test_poly(Polyhedron(rays=[[1,0,0],[0,1,0]], + ....: backend='normaliz')) True - sage: test_poly(Polyhedron(vertices=[[1,0,0],[0,1,0]], rays=[[1,0,0],[0,1,0]], backend='normaliz')) # optional - pynormaliz + sage: test_poly(Polyhedron(vertices=[[1,0,0], [0,1,0]], rays=[[1,0,0], [0,1,0]], + ....: backend='normaliz')) True - sage: test_poly(Polyhedron(vertices=[[0,0,0],[0,1,1],[1,0,1],[-1,-1,1]],rays=[[0,0,1]], backend='normaliz')) # optional - pynormaliz + sage: test_poly(Polyhedron(vertices=[[0,0,0], [0,1,1], [1,0,1], [-1,-1,1]], + ....: rays=[[0,0,1]], + ....: backend='normaliz')) True Old input format will give a meaningful error message:: - sage: cone = P._cone_from_Vrepresentation_and_Hrepresentation( # optional - pynormaliz + sage: cone = P._cone_from_Vrepresentation_and_Hrepresentation( ....: P.vertices(), P.rays(), ....: P.inequalities(), P.equations()) Traceback (most recent call last): ... ValueError: the specification of this method has changed; please specify the lines as well - sage: cone = P._cone_from_Vrepresentation_and_Hrepresentation( # optional - pynormaliz + sage: cone = P._cone_from_Vrepresentation_and_Hrepresentation( ....: P.vertices(), P.rays(), ....: P.inequalities(), P.equations(), True) Traceback (most recent call last): @@ -747,11 +773,12 @@ def _cone_from_Vrepresentation_and_Hrepresentation(self, vertices, rays, lines, Check that :trac:`30891` is fixed:: - sage: p = Polyhedron(vertices=[(-3,-3), (3,0), (3,3), (0,3)], backend='normaliz') # optional - pynormaliz - sage: q = loads(p.dumps()) # optional - pynormaliz - sage: q.volume() # optional - pynormaliz + sage: p = Polyhedron(vertices=[(-3,-3), (3,0), (3,3), (0,3)], + ....: backend='normaliz') + sage: q = loads(p.dumps()) + sage: q.volume() 18 - sage: q.ehrhart_series() # optional - pynormaliz + sage: q.ehrhart_series() (13*t^2 + 22*t + 1)/(-t^3 + 3*t^2 - 3*t + 1) """ if eqns in (True, False, None): @@ -856,21 +883,21 @@ def _test_far_facet_condition(self, tester=None, **options): TESTS:: - sage: P = Polyhedron(rays=[[1,1]], backend='normaliz') # optional - pynormaliz - sage: P._test_far_facet_condition() # optional - pynormaliz + sage: P = Polyhedron(rays=[[1,1]], backend='normaliz') + sage: P._test_far_facet_condition() - sage: P = Polyhedron(vertices=[[1,0], [0,1]], # optional - pynormaliz + sage: P = Polyhedron(vertices=[[1,0], [0,1]], ....: rays=[[1,1]], backend='normaliz') - sage: P._test_far_facet_condition() # optional - pynormaliz + sage: P._test_far_facet_condition() - sage: P = Polyhedron(rays=[[1,1,0]], # optional - pynormaliz + sage: P = Polyhedron(rays=[[1,1,0]], ....: lines=[[0,0,1]], backend='normaliz') - sage: P._test_far_facet_condition() # optional - pynormaliz + sage: P._test_far_facet_condition() - sage: P = Polyhedron(vertices=[[1,0,0], [0,1,0]], # optional - pynormaliz + sage: P = Polyhedron(vertices=[[1,0,0], [0,1,0]], ....: rays=[[1,1,0]], ....: lines=[[0,0,1]], backend='normaliz') - sage: P._test_far_facet_condition() # optional - pynormaliz + sage: P._test_far_facet_condition() """ if tester is None: tester = self._tester(**options) @@ -897,13 +924,13 @@ def _init_Vrepresentation_from_normaliz(self): EXAMPLES:: - sage: p = Polyhedron(vertices=[(0,1/2),(2,0),(4,5/6)], # indirect doctest # optional - pynormaliz + sage: p = Polyhedron(vertices=[(0,1/2), (2,0), (4,5/6)], # indirect doctest ....: backend='normaliz') - sage: p.Hrepresentation() # optional - pynormaliz + sage: p.Hrepresentation() (An inequality (-5, 12) x + 10 >= 0, An inequality (1, -12) x + 6 >= 0, An inequality (1, 4) x - 2 >= 0) - sage: p.Vrepresentation() # optional - pynormaliz + sage: p.Vrepresentation() (A vertex at (0, 1/2), A vertex at (2, 0), A vertex at (4, 5/6)) """ self._Vrepresentation = [] @@ -928,13 +955,13 @@ def _init_Hrepresentation_from_normaliz(self): EXAMPLES:: - sage: p = Polyhedron(vertices=[(0,1/2), (2,0), (4,5/6)], # indirect doctest # optional - pynormaliz + sage: p = Polyhedron(vertices=[(0,1/2), (2,0), (4,5/6)], # indirect doctest ....: backend='normaliz') - sage: p.Hrepresentation() # optional - pynormaliz + sage: p.Hrepresentation() (An inequality (-5, 12) x + 10 >= 0, An inequality (1, -12) x + 6 >= 0, An inequality (1, 4) x - 2 >= 0) - sage: p.Vrepresentation() # optional - pynormaliz + sage: p.Vrepresentation() (A vertex at (0, 1/2), A vertex at (2, 0), A vertex at (4, 5/6)) """ self._Hrepresentation = [] @@ -956,15 +983,15 @@ def _init_empty_polyhedron(self): TESTS:: - sage: empty = Polyhedron(backend='normaliz'); empty # optional - pynormaliz + sage: empty = Polyhedron(backend='normaliz'); empty The empty polyhedron in ZZ^0 - sage: empty.Vrepresentation() # optional - pynormaliz + sage: empty.Vrepresentation() () - sage: empty.Hrepresentation() # optional - pynormaliz + sage: empty.Hrepresentation() (An equation -1 == 0,) - sage: Polyhedron(vertices = [], backend='normaliz') # optional - pynormaliz + sage: Polyhedron(vertices=[], backend='normaliz') The empty polyhedron in ZZ^0 - sage: Polyhedron(backend='normaliz')._init_empty_polyhedron() # optional - pynormaliz + sage: Polyhedron(backend='normaliz')._init_empty_polyhedron() """ super()._init_empty_polyhedron() # Can't seem to set up an empty _normaliz_cone. @@ -979,9 +1006,9 @@ def _from_normaliz_cone(cls, parent, normaliz_cone, internal_base_ring=None): TESTS:: - sage: P=Polyhedron(ieqs=[[1, 0, 2], [3, 0, -2], [3, 2, -2]], # optional - pynormaliz + sage: P=Polyhedron(ieqs=[[1, 0, 2], [3, 0, -2], [3, 2, -2]], ....: backend='normaliz') - sage: PI = P.integral_hull() # indirect doctest; optional - pynormaliz + sage: PI = P.integral_hull() # indirect doctest """ return cls(parent, None, None, normaliz_cone=normaliz_cone, internal_base_ring=internal_base_ring) @@ -995,7 +1022,7 @@ def _number_field_triple(internal_base_ring): sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_normaliz as Pn sage: Pn._number_field_triple(QQ) is None True - sage: Pn._number_field_triple(QuadraticField(5)) # optional - sage.rings.number_field + sage: Pn._number_field_triple(QuadraticField(5)) # optional - sage.rings.number_field ['a^2 - 5', 'a', '[2.236067977499789 +/- 8.06e-16]'] """ R = internal_base_ring @@ -1022,11 +1049,11 @@ def _make_normaliz_cone(data, verbose=False): TESTS:: - sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_normaliz # optional - pynormaliz - sage: data = {'inhom_inequalities': [[-1, 2, 0], [0, 0, 1], [2, -1, 0]]} # optional - pynormaliz - sage: nmz_cone = Polyhedron_normaliz._make_normaliz_cone(data,verbose=False) # optional - pynormaliz - sage: from PyNormaliz import NmzResult # optional - pynormaliz - sage: NmzResult(nmz_cone, "ExtremeRays") # optional - pynormaliz + sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_normaliz + sage: data = {'inhom_inequalities': [[-1, 2, 0], [0, 0, 1], [2, -1, 0]]} + sage: nmz_cone = Polyhedron_normaliz._make_normaliz_cone(data,verbose=False) + sage: from PyNormaliz import NmzResult + sage: NmzResult(nmz_cone, "ExtremeRays") [[1, 2, 0], [2, 1, 0]] """ if verbose: @@ -1047,14 +1074,14 @@ def _get_nmzcone_data(self): The empty polyhedron:: - sage: P = Polyhedron(backend='normaliz') # optional - pynormaliz - sage: P._get_nmzcone_data() # optional - pynormaliz + sage: P = Polyhedron(backend='normaliz') + sage: P._get_nmzcone_data() {} Another simple example:: - sage: C = Polyhedron(backend='normaliz', rays=[[1, 2], [2, 1]]) # optional - pynormaliz - sage: C._get_nmzcone_data() # optional - pynormaliz + sage: C = Polyhedron(backend='normaliz', rays=[[1, 2], [2, 1]]) + sage: C._get_nmzcone_data() {'cone': [[1, 2], [2, 1]], 'inhom_equations': [], 'inhom_inequalities': [[-1, 2, 0], [0, 0, 1], [2, -1, 0]], @@ -1093,7 +1120,7 @@ def _normaliz_format(self, data, file_output=None): EXAMPLES:: - sage: P = Polyhedron(vertices=[[0, 0], [0, 1], [1, 0]], # indirect doctest; optional - pynormaliz + sage: P = Polyhedron(vertices=[[0, 0], [0, 1], [1, 0]], # indirect doctest ....: backend='normaliz', verbose=True) # ----8<---- Equivalent Normaliz input file ----8<---- amb_space 2 @@ -1148,9 +1175,9 @@ def __copy__(self): TESTS:: - sage: P = polytopes.cube(backend='normaliz') # optional - pynormaliz - sage: Q = copy(P) # optional - pynormaliz - sage: P._normaliz_cone is Q._normaliz_cone # optional - pynormaliz + sage: P = polytopes.cube(backend='normaliz') + sage: Q = copy(P) + sage: P._normaliz_cone is Q._normaliz_cone False """ other = super().__copy__() @@ -1167,8 +1194,8 @@ def __getstate__(self): TESTS:: - sage: P = polytopes.simplex(backend='normaliz') # optional - pynormaliz - sage: P.__getstate__() # optional - pynormaliz + sage: P = polytopes.simplex(backend='normaliz') + sage: P.__getstate__() (Polyhedra in ZZ^4, {'_Hrepresentation': (An inequality (0, 0, 0, 1) x + 0 >= 0, An inequality (0, 0, 1, 0) x + 0 >= 0, @@ -1209,52 +1236,53 @@ def __setstate__(self, state): TESTS:: - sage: P = polytopes.permutahedron(4, backend='normaliz') # optional - pynormaliz - sage: P.volume(measure='induced_lattice', engine='normaliz') # optional - pynormaliz + sage: P = polytopes.permutahedron(4, backend='normaliz') + sage: P.volume(measure='induced_lattice', engine='normaliz') 96 - sage: P.volume.clear_cache() # optional - pynormaliz - sage: P1 = loads(dumps(P)) # indirect doctest # optional - pynormaliz - sage: P1.volume(measure='induced_lattice', engine='normaliz') # optional - pynormaliz + sage: P.volume.clear_cache() + sage: P1 = loads(dumps(P)) # indirect doctest + sage: P1.volume(measure='induced_lattice', engine='normaliz') 96 Test that the obtained cone is valid:: - sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_normaliz # optional - pynormaliz - sage: P = polytopes.permutahedron(4, backend='normaliz') # optional - pynormaliz - sage: P1 = loads(dumps(P)) # optional - pynormaliz - sage: P2 = Polyhedron_normaliz(P1.parent(), None, None, P1._normaliz_cone) # optional - pynormaliz - sage: P2 == P # optional - pynormaliz + sage: from sage.geometry.polyhedron.backend_normaliz import Polyhedron_normaliz + sage: P = polytopes.permutahedron(4, backend='normaliz') + sage: P1 = loads(dumps(P)) + sage: P2 = Polyhedron_normaliz(P1.parent(), None, None, P1._normaliz_cone) + sage: P2 == P True - sage: P = Polyhedron(lines=[[1,0], [0,1]], backend='normaliz') # optional - pynormaliz - sage: P1 = loads(dumps(P)) # optional - pynormaliz - sage: P2 = Polyhedron_normaliz(P1.parent(), None, None, P1._normaliz_cone) # optional - pynormaliz - sage: P2 == P # optional - pynormaliz + sage: P = Polyhedron(lines=[[1,0], [0,1]], backend='normaliz') + sage: P1 = loads(dumps(P)) + sage: P2 = Polyhedron_normaliz(P1.parent(), None, None, P1._normaliz_cone) + sage: P2 == P True - sage: P = Polyhedron(backend='normaliz') # optional - pynormaliz - sage: P1 = loads(dumps(P)) # optional - pynormaliz - sage: P2 = Polyhedron_normaliz(P1.parent(), None, None, P1._normaliz_cone) # optional - pynormaliz - sage: P2 == P # optional - pynormaliz + sage: P = Polyhedron(backend='normaliz') + sage: P1 = loads(dumps(P)) + sage: P2 = Polyhedron_normaliz(P1.parent(), None, None, P1._normaliz_cone) + sage: P2 == P True - sage: P = polytopes.permutahedron(4, backend='normaliz') * Polyhedron(lines=[[1]], backend='normaliz') # optional - pynormaliz - sage: P1 = loads(dumps(P)) # optional - pynormaliz - sage: P2 = Polyhedron_normaliz(P1.parent(), None, None, P1._normaliz_cone) # optional - pynormaliz - sage: P2 == P # optional - pynormaliz + sage: P = polytopes.permutahedron(4, backend='normaliz') * Polyhedron(lines=[[1]], backend='normaliz') + sage: P1 = loads(dumps(P)) + sage: P2 = Polyhedron_normaliz(P1.parent(), None, None, P1._normaliz_cone) + sage: P2 == P True - sage: P = polytopes.dodecahedron(backend='normaliz') # optional - pynormaliz # optional - sage.rings.number_field - sage: P1 = loads(dumps(P)) # optional - pynormaliz # optional - sage.rings.number_field - sage: P2 = Polyhedron_normaliz(P1.parent(), None, None, P1._normaliz_cone, internal_base_ring=P1._internal_base_ring) # optional - pynormaliz # optional - sage.rings.number_field - sage: P == P2 # optional - pynormaliz # optional - sage.rings.number_field + sage: P = polytopes.dodecahedron(backend='normaliz') # optional - sage.rings.number_field + sage: P1 = loads(dumps(P)) # optional - sage.rings.number_field + sage: P2 = Polyhedron_normaliz(P1.parent(), None, None, P1._normaliz_cone, # optional - sage.rings.number_field + ....: internal_base_ring=P1._internal_base_ring) + sage: P == P2 # optional - sage.rings.number_field True Test that :trac:`31820` is fixed:: - sage: P = polytopes.cube(backend='normaliz') # optional - pynormaliz - sage: v = P.Vrepresentation()[0] # optional - pynormaliz - sage: v1 = loads(v.dumps()) # optional - pynormaliz + sage: P = polytopes.cube(backend='normaliz') + sage: v = P.Vrepresentation()[0] + sage: v1 = loads(v.dumps()) """ if "_pickle_vertices" in state[1]: vertices = state[1].pop("_pickle_vertices") @@ -1294,29 +1322,31 @@ def integral_hull(self): Unbounded example from Normaliz manual, "a dull polyhedron":: - sage: P = Polyhedron(ieqs=[[1, 0, 2], [3, 0, -2], [3, 2, -2]], # optional - pynormaliz - ....: backend='normaliz') - sage: PI = P.integral_hull() # optional - pynormaliz - sage: P.plot(color='yellow') + PI.plot(color='green') # optional - pynormaliz # optional - sage.plot + sage: P = Polyhedron(ieqs=[[1, 0, 2], [3, 0, -2], [3, 2, -2]], + ....: backend='normaliz') + sage: PI = P.integral_hull() + sage: P.plot(color='yellow') + PI.plot(color='green') # optional - sage.plot Graphics object consisting of 10 graphics primitives - sage: PI.Vrepresentation() # optional - pynormaliz - (A vertex at (-1, 0), A vertex at (0, 1), A ray in the direction (1, 0)) + sage: PI.Vrepresentation() + (A vertex at (-1, 0), + A vertex at (0, 1), + A ray in the direction (1, 0)) Nonpointed case:: - sage: P = Polyhedron(vertices=[[1/2, 1/3]], rays=[[1, 1]], # optional - pynormaliz - ....: lines=[[-1, 1]], backend='normaliz') - sage: PI = P.integral_hull() # optional - pynormaliz - sage: PI.Vrepresentation() # optional - pynormaliz + sage: P = Polyhedron(vertices=[[1/2, 1/3]], rays=[[1, 1]], + ....: lines=[[-1, 1]], backend='normaliz') + sage: PI = P.integral_hull() + sage: PI.Vrepresentation() (A vertex at (1, 0), A ray in the direction (1, 0), A line in the direction (1, -1)) Empty polyhedron:: - sage: P = Polyhedron(backend='normaliz') # optional - pynormaliz - sage: PI = P.integral_hull() # optional - pynormaliz - sage: PI.Vrepresentation() # optional - pynormaliz + sage: P = Polyhedron(backend='normaliz') + sage: PI = P.integral_hull() + sage: PI.Vrepresentation() () """ if self.is_empty(): @@ -1341,14 +1371,14 @@ def _h_star_vector_normaliz(self): The `h^*`-vector of a unimodular simplex is 1:: - sage: s3 = polytopes.simplex(3,backend='normaliz') # optional - pynormaliz - sage: s3._h_star_vector_normaliz() # optional - pynormaliz + sage: s3 = polytopes.simplex(3, backend='normaliz') + sage: s3._h_star_vector_normaliz() [1] The `h^*`-vector of the `0/1`-cube is [1,4,1]:: - sage: cube = polytopes.cube(intervals='zero_one', backend='normaliz') # optional - pynormaliz - sage: cube.h_star_vector() # optional - pynormaliz + sage: cube = polytopes.cube(intervals='zero_one', backend='normaliz') + sage: cube.h_star_vector() [1, 4, 1] TESTS: @@ -1356,9 +1386,9 @@ def _h_star_vector_normaliz(self): Check that :trac:`33847` is fixed:: sage: L = [[1, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0], [1, 0, 1, 0, 0, 0], - ....: [1, 0, 0, 1, 0, 0], [1, 0, 0, 0, 1, 0], [1, 0, 0, 1, 2, 3]] - sage: P = Polyhedron(vertices=L,backend='normaliz') # optional - pynormaliz - sage: P.h_star_vector() # optional - pynormaliz + ....: [1, 0, 0, 1, 0, 0], [1, 0, 0, 0, 1, 0], [1, 0, 0, 1, 2, 3]] + sage: P = Polyhedron(vertices=L, backend='normaliz') + sage: P.h_star_vector() [1, 0, 2] """ return self.ehrhart_series().numerator().list() @@ -1395,57 +1425,57 @@ def _volume_normaliz(self, measure='euclidean'): For normaliz, the default is the euclidean volume in the ambient space and the result is a float:: - sage: s = polytopes.simplex(3,backend='normaliz') # optional - pynormaliz - sage: s._volume_normaliz() # optional - pynormaliz + sage: s = polytopes.simplex(3, backend='normaliz') + sage: s._volume_normaliz() 0.3333333333333333 One other possibility is to compute the scaled volume where a unimodular simplex has volume 1:: - sage: s._volume_normaliz(measure='induced_lattice') # optional - pynormaliz + sage: s._volume_normaliz(measure='induced_lattice') 1 sage: v = [[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]] - sage: cube = Polyhedron(vertices=v,backend='normaliz') # optional - pynormaliz - sage: cube._volume_normaliz() # optional - pynormaliz + sage: cube = Polyhedron(vertices=v, backend='normaliz') + sage: cube._volume_normaliz() 1.0 - sage: cube._volume_normaliz(measure='induced_lattice') # optional - pynormaliz + sage: cube._volume_normaliz(measure='induced_lattice') 6 Or one can calculate the ambient volume, which is the above multiplied by the volume of the unimodular simplex (or zero if not full-dimensional):: - sage: cube._volume_normaliz(measure='ambient') # optional - pynormaliz + sage: cube._volume_normaliz(measure='ambient') 1 - sage: s._volume_normaliz(measure='ambient') # optional - pynormaliz + sage: s._volume_normaliz(measure='ambient') 0 TESTS: Check that :trac:`28872` is fixed:: - sage: P = polytopes.dodecahedron(backend='normaliz') # optional - pynormaliz # optional - sage.rings.number_field - sage: P.volume(measure='induced_lattice') # optional - pynormaliz # optional - sage.rings.number_field + sage: P = polytopes.dodecahedron(backend='normaliz') # optional - sage.rings.number_field + sage: P.volume(measure='induced_lattice') # optional - sage.rings.number_field -1056*sqrt5 + 2400 Some sanity checks that the ambient volume works correctly:: - sage: (2*cube)._volume_normaliz(measure='ambient') # optional - pynormaliz + sage: (2*cube)._volume_normaliz(measure='ambient') 8 - sage: (1/2*cube)._volume_normaliz(measure='ambient') # optional - pynormaliz + sage: (1/2*cube)._volume_normaliz(measure='ambient') 1/8 - sage: s._volume_normaliz(measure='ambient') # optional - pynormaliz + sage: s._volume_normaliz(measure='ambient') 0 - sage: P = polytopes.regular_polygon(3, backend='normaliz') # optional - pynormaliz # optional - sage.rings.number_field - sage: P._volume_normaliz('ambient') == P.volume(engine='internal') # optional - pynormaliz # optional - sage.rings.number_field + sage: P = polytopes.regular_polygon(3, backend='normaliz') # optional - sage.rings.number_field + sage: P._volume_normaliz('ambient') == P.volume(engine='internal') # optional - sage.rings.number_field True - sage: P = polytopes.dodecahedron(backend='normaliz') # optional - pynormaliz # optional - sage.rings.number_field - sage: P._volume_normaliz('ambient') == P.volume(engine='internal') # optional - pynormaliz # optional - sage.rings.number_field + sage: P = polytopes.dodecahedron(backend='normaliz') # optional - sage.rings.number_field + sage: P._volume_normaliz('ambient') == P.volume(engine='internal') # optional - sage.rings.number_field True - sage: P = Polyhedron(rays=[[1]], backend='normaliz') # optional - pynormaliz - sage: P.volume() # optional - pynormaliz + sage: P = Polyhedron(rays=[[1]], backend='normaliz') + sage: P.volume() +Infinity """ cone = self._normaliz_cone @@ -1489,26 +1519,26 @@ def _triangulate_normaliz(self): EXAMPLES:: - sage: P = Polyhedron(vertices=[[0,0,1],[1,0,1],[0,1,1],[1,1,1]],backend='normaliz') # optional - pynormaliz - sage: P._triangulate_normaliz() # optional - pynormaliz + sage: P = Polyhedron(vertices=[[0,0,1], [1,0,1], [0,1,1], [1,1,1]], backend='normaliz') + sage: P._triangulate_normaliz() [(0, 1, 2), (1, 2, 3)] - sage: C1 = Polyhedron(rays=[[0,0,1],[1,0,1],[0,1,1],[1,1,1]],backend='normaliz') # optional - pynormaliz - sage: C1._triangulate_normaliz() # optional - pynormaliz + sage: C1 = Polyhedron(rays=[[0,0,1], [1,0,1], [0,1,1], [1,1,1]], backend='normaliz') + sage: C1._triangulate_normaliz() [(0, 1, 2), (1, 2, 3)] - sage: C2 = Polyhedron(rays=[[1,0,1],[0,0,1],[0,1,1],[1,1,10/9]],backend='normaliz') # optional - pynormaliz - sage: C2._triangulate_normaliz() # optional - pynormaliz + sage: C2 = Polyhedron(rays=[[1,0,1], [0,0,1], [0,1,1], [1,1,10/9]], backend='normaliz') + sage: C2._triangulate_normaliz() [(0, 1, 2), (1, 2, 3)] Works only for cones and compact polyhedra:: - sage: P = polytopes.cube(backend='normaliz') # optional - pynormaliz - sage: Q = Polyhedron(rays=[[0,1]], backend='normaliz') # optional - pynormaliz - sage: R = Polyhedron(lines=[[0,1]], backend='normaliz') # optional - pynormaliz - sage: (P*Q)._triangulate_normaliz() # optional - pynormaliz + sage: P = polytopes.cube(backend='normaliz') + sage: Q = Polyhedron(rays=[[0,1]], backend='normaliz') + sage: R = Polyhedron(lines=[[0,1]], backend='normaliz') + sage: (P*Q)._triangulate_normaliz() Traceback (most recent call last): ... NotImplementedError: triangulation of non-compact polyhedra that are not cones is not supported - sage: (P*R)._triangulate_normaliz() # optional - pynormaliz + sage: (P*R)._triangulate_normaliz() Traceback (most recent call last): ... NotImplementedError: triangulation of non-compact not pointed polyhedron is not supported @@ -1517,8 +1547,8 @@ def _triangulate_normaliz(self): Check that :trac:`30531` is fixed:: - sage: P = polytopes.cube(backend='normaliz')*AA(2).sqrt() # optional - pynormaliz - sage: P._triangulate_normaliz() # optional - pynormaliz + sage: P = polytopes.cube(backend='normaliz')*AA(2).sqrt() + sage: P._triangulate_normaliz() [(0, 1, 2, 4), (1, 2, 4, 3), (1, 3, 4, 5), @@ -1528,8 +1558,9 @@ def _triangulate_normaliz(self): :: - sage: C1 = Polyhedron(rays=[[0,0,1],[1,0,AA(2).sqrt()],[0,1,1],[1,1,1]], backend='normaliz') # optional - pynormaliz - sage: C1._triangulate_normaliz() # optional - pynormaliz + sage: C1 = Polyhedron(rays=[[0,0,1], [1,0,AA(2).sqrt()], [0,1,1], [1,1,1]], + ....: backend='normaliz') + sage: C1._triangulate_normaliz() [(0, 1, 3), (0, 3, 2)] """ if self.lines(): @@ -1605,10 +1636,10 @@ class Polyhedron_QQ_normaliz(Polyhedron_normaliz, Polyhedron_QQ): EXAMPLES:: - sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], # optional - pynormaliz + sage: p = Polyhedron(vertices=[(0,0), (1,0), (0,1)], ....: rays=[(1,1)], lines=[], ....: backend='normaliz', base_ring=QQ) - sage: TestSuite(p).run() # optional - pynormaliz + sage: TestSuite(p).run() """ @cached_method(do_pickle=True) @@ -1630,34 +1661,37 @@ def ehrhart_series(self, variable='t'): EXAMPLES:: - sage: S = Polyhedron(vertices=[[0,1],[1,0]], backend='normaliz') # optional - pynormaliz - sage: ES = S.ehrhart_series() # optional - pynormaliz - sage: ES.numerator() # optional - pynormaliz + sage: S = Polyhedron(vertices=[[0,1], [1,0]], backend='normaliz') + sage: ES = S.ehrhart_series() + sage: ES.numerator() 1 - sage: ES.denominator().factor() # optional - pynormaliz + sage: ES.denominator().factor() (t - 1)^2 - sage: C = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]],backend='normaliz') # optional - pynormaliz - sage: ES = C.ehrhart_series() # optional - pynormaliz - sage: ES.numerator() # optional - pynormaliz + sage: C = Polyhedron(vertices=[[0,0,0], [0,0,1], [0,1,0], [0,1,1], + ....: [1,0,0], [1,0,1], [1,1,0], [1,1,1]], + ....: backend='normaliz') + sage: ES = C.ehrhart_series() + sage: ES.numerator() t^2 + 4*t + 1 - sage: ES.denominator().factor() # optional - pynormaliz + sage: ES.denominator().factor() (t - 1)^4 The following example is from the Normaliz manual contained in the file ``rational.in``:: - sage: rat_poly = Polyhedron(vertices=[[1/2,1/2],[-1/3,-1/3],[1/4,-1/2]],backend='normaliz') # optional - pynormaliz - sage: ES = rat_poly.ehrhart_series() # optional - pynormaliz - sage: ES.numerator() # optional - pynormaliz + sage: rat_poly = Polyhedron(vertices=[[1/2,1/2], [-1/3,-1/3], [1/4,-1/2]], + ....: backend='normaliz') + sage: ES = rat_poly.ehrhart_series() + sage: ES.numerator() 2*t^6 + 3*t^5 + 4*t^4 + 3*t^3 + t^2 + t + 1 - sage: ES.denominator().factor() # optional - pynormaliz + sage: ES.denominator().factor() (-1) * (t + 1)^2 * (t - 1)^3 * (t^2 + 1) * (t^2 + t + 1) The polyhedron should be compact:: - sage: C = Polyhedron(backend='normaliz',rays=[[1,2],[2,1]]) # optional - pynormaliz - sage: C.ehrhart_series() # optional - pynormaliz + sage: C = Polyhedron(rays=[[1,2], [2,1]], backend='normaliz') + sage: C.ehrhart_series() Traceback (most recent call last): ... NotImplementedError: Ehrhart series can only be computed for compact polyhedron @@ -1670,8 +1704,8 @@ def ehrhart_series(self, variable='t'): Check that the Ehrhart series is pickled:: - sage: new_poly = loads(dumps(rat_poly)) # optional - pynormaliz - sage: new_poly.ehrhart_series.is_in_cache() # optional - pynormaliz + sage: new_poly = loads(dumps(rat_poly)) + sage: new_poly.ehrhart_series.is_in_cache() True """ if self.is_empty(): @@ -1720,29 +1754,31 @@ def _ehrhart_quasipolynomial_normaliz(self, variable='t'): EXAMPLES:: - sage: C = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]],backend='normaliz') # optional - pynormaliz - sage: C._ehrhart_quasipolynomial_normaliz() # optional - pynormaliz + sage: C = Polyhedron(vertices=[[0,0,0], [0,0,1], [0,1,0], [0,1,1], + ....: [1,0,0], [1,0,1], [1,1,0], [1,1,1]], + ....: backend='normaliz') + sage: C._ehrhart_quasipolynomial_normaliz() t^3 + 3*t^2 + 3*t + 1 - sage: P = Polyhedron(vertices=[[0,0],[3/2,0],[0,3/2],[1,1]],backend='normaliz') # optional - pynormaliz - sage: P._ehrhart_quasipolynomial_normaliz() # optional - pynormaliz + sage: P = Polyhedron(vertices=[[0,0], [3/2,0], [0,3/2], [1,1]], backend='normaliz') + sage: P._ehrhart_quasipolynomial_normaliz() (3/2*t^2 + 2*t + 1, 3/2*t^2 + 2*t + 1/2) - sage: P._ehrhart_quasipolynomial_normaliz('x') # optional - pynormaliz + sage: P._ehrhart_quasipolynomial_normaliz('x') (3/2*x^2 + 2*x + 1, 3/2*x^2 + 2*x + 1/2) The quasipolynomial evaluated at ``i`` counts the integral points in the ``i``-th dilate:: - sage: Q = Polyhedron(vertices = [[-1/3],[2/3]],backend='normaliz') # optional - pynormaliz - sage: p0,p1,p2 = Q._ehrhart_quasipolynomial_normaliz() # optional - pynormaliz - sage: r0 = [p0(i) for i in range(15)] # optional - pynormaliz - sage: r1 = [p1(i) for i in range(15)] # optional - pynormaliz - sage: r2 = [p2(i) for i in range(15)] # optional - pynormaliz - sage: result = [None]*15 # optional - pynormaliz - sage: result[::3] = r0[::3] # optional - pynormaliz - sage: result[1::3] = r1[1::3] # optional - pynormaliz - sage: result[2::3] = r2[2::3] # optional - pynormaliz - sage: result == [(i*Q).integral_points_count() for i in range(15)] # optional - pynormaliz + sage: Q = Polyhedron(vertices=[[-1/3], [2/3]], backend='normaliz') + sage: p0,p1,p2 = Q._ehrhart_quasipolynomial_normaliz() + sage: r0 = [p0(i) for i in range(15)] + sage: r1 = [p1(i) for i in range(15)] + sage: r2 = [p2(i) for i in range(15)] + sage: result = [None]*15 + sage: result[::3] = r0[::3] + sage: result[1::3] = r1[1::3] + sage: result[2::3] = r2[2::3] + sage: result == [(i*Q).integral_points_count() for i in range(15)] True @@ -1791,32 +1827,33 @@ def hilbert_series(self, grading, variable='t'): EXAMPLES:: - sage: C = Polyhedron(backend='normaliz',rays=[[0,0,1],[0,1,1],[1,0,1],[1,1,1]]) # optional - pynormaliz - sage: HS = C.hilbert_series([1,1,1]) # optional - pynormaliz - sage: HS.numerator() # optional - pynormaliz + sage: C = Polyhedron(backend='normaliz', + ....: rays=[[0,0,1], [0,1,1], [1,0,1], [1,1,1]]) + sage: HS = C.hilbert_series([1,1,1]) + sage: HS.numerator() t^2 + 1 - sage: HS.denominator().factor() # optional - pynormaliz + sage: HS.denominator().factor() (-1) * (t + 1) * (t - 1)^3 * (t^2 + t + 1) By changing the grading, you can get the Ehrhart series of the square lifted at height 1:: - sage: C.hilbert_series([0,0,1]) # optional - pynormaliz + sage: C.hilbert_series([0,0,1]) (t + 1)/(-t^3 + 3*t^2 - 3*t + 1) Here is an example ``2cone.in`` from the Normaliz manual:: - sage: C = Polyhedron(backend='normaliz',rays=[[1,3],[2,1]]) # optional - pynormaliz - sage: HS = C.hilbert_series([1,1]) # optional - pynormaliz - sage: HS.numerator() # optional - pynormaliz + sage: C = Polyhedron(backend='normaliz', rays=[[1,3], [2,1]]) + sage: HS = C.hilbert_series([1,1]) + sage: HS.numerator() t^5 + t^4 + t^3 + t^2 + 1 - sage: HS.denominator().factor() # optional - pynormaliz + sage: HS.denominator().factor() (t + 1) * (t - 1)^2 * (t^2 + 1) * (t^2 + t + 1) - sage: HS = C.hilbert_series([1,2]) # optional - pynormaliz - sage: HS.numerator() # optional - pynormaliz + sage: HS = C.hilbert_series([1,2]) + sage: HS.numerator() t^8 + t^6 + t^5 + t^3 + 1 - sage: HS.denominator().factor() # optional - pynormaliz + sage: HS.denominator().factor() (t + 1) * (t - 1)^2 * (t^2 + 1) * (t^6 + t^5 + t^4 + t^3 + t^2 + t + 1) Here is the magic square example form the Normaliz manual:: @@ -1828,9 +1865,10 @@ def hilbert_series(self, grading, variable='t'): ....: [0,1,1,0, 0, 0,-1, 0, 0,-1], ....: [0,0,1,1, 0,-1, 0, 0, 0,-1], ....: [0,1,1,0, 0,-1, 0,-1, 0, 0]] - sage: magic_square = Polyhedron(eqns=eq,backend='normaliz') & Polyhedron(rays=identity_matrix(9).rows()) # optional - pynormaliz + sage: magic_square = (Polyhedron(eqns=eq, backend='normaliz') + ....: & Polyhedron(rays=identity_matrix(9).rows())) sage: grading = [1,1,1,0,0,0,0,0,0] - sage: magic_square.hilbert_series(grading) # optional - pynormaliz + sage: magic_square.hilbert_series(grading) (t^6 + 2*t^3 + 1)/(-t^9 + 3*t^6 - 3*t^3 + 1) .. SEEALSO:: @@ -1841,8 +1879,8 @@ def hilbert_series(self, grading, variable='t'): Check that the Hilbert series is pickled:: - sage: new_magic = loads(dumps(magic_square)) # optional - pynormaliz - sage: new_magic.hilbert_series.is_in_cache(grading) # optional - pynormaliz + sage: new_magic = loads(dumps(magic_square)) + sage: new_magic.hilbert_series.is_in_cache(grading) True """ if self.is_empty(): @@ -1885,29 +1923,29 @@ def integral_points(self, threshold=10000): EXAMPLES:: - sage: Polyhedron(vertices=[(-1,-1), (1,0), (1,1), (0,1)], # optional - pynormaliz + sage: Polyhedron(vertices=[(-1,-1), (1,0), (1,1), (0,1)], ....: backend='normaliz').integral_points() ((-1, -1), (0, 0), (0, 1), (1, 0), (1, 1)) - sage: simplex = Polyhedron([(1,2,3), (2,3,7), (-2,-3,-11)], # optional - pynormaliz + sage: simplex = Polyhedron([(1,2,3), (2,3,7), (-2,-3,-11)], ....: backend='normaliz') - sage: simplex.integral_points() # optional - pynormaliz + sage: simplex.integral_points() ((-2, -3, -11), (0, 0, -2), (1, 2, 3), (2, 3, 7)) The polyhedron need not be full-dimensional:: - sage: simplex = Polyhedron([(1,2,3,5), (2,3,7,5), (-2,-3,-11,5)], # optional - pynormaliz + sage: simplex = Polyhedron([(1,2,3,5), (2,3,7,5), (-2,-3,-11,5)], ....: backend='normaliz') - sage: simplex.integral_points() # optional - pynormaliz + sage: simplex.integral_points() ((-2, -3, -11, 5), (0, 0, -2, 5), (1, 2, 3, 5), (2, 3, 7, 5)) - sage: point = Polyhedron([(2,3,7)], # optional - pynormaliz + sage: point = Polyhedron([(2,3,7)], ....: backend='normaliz') - sage: point.integral_points() # optional - pynormaliz + sage: point.integral_points() ((2, 3, 7),) - sage: empty = Polyhedron(backend='normaliz') # optional - pynormaliz - sage: empty.integral_points() # optional - pynormaliz + sage: empty = Polyhedron(backend='normaliz') + sage: empty.integral_points() () Here is a simplex where the naive algorithm of running over @@ -1915,9 +1953,9 @@ def integral_points(self, threshold=10000): enough:: sage: v = [(1,0,7,-1), (-2,-2,4,-3), (-1,-1,-1,4), (2,9,0,-5), (-2,-1,5,1)] - sage: simplex = Polyhedron(v, backend='normaliz'); simplex # optional - pynormaliz + sage: simplex = Polyhedron(v, backend='normaliz'); simplex A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices - sage: len(simplex.integral_points()) # optional - pynormaliz + sage: len(simplex.integral_points()) 49 A rather thin polytope for which the bounding box method would @@ -1925,27 +1963,27 @@ def integral_points(self, threshold=10000): polytope, so the other backends use the bounding box method):: sage: P = Polyhedron(vertices=((0, 0), (178933,37121))) + 1/1000*polytopes.hypercube(2) - sage: P = Polyhedron(vertices=P.vertices_list(), # optional - pynormaliz + sage: P = Polyhedron(vertices=P.vertices_list(), ....: backend='normaliz') - sage: len(P.integral_points()) # optional - pynormaliz + sage: len(P.integral_points()) 434 Finally, the 3-d reflexive polytope number 4078:: sage: v = [(1,0,0), (0,1,0), (0,0,1), (0,0,-1), (0,-2,1), ....: (-1,2,-1), (-1,2,-2), (-1,1,-2), (-1,-1,2), (-1,-3,2)] - sage: P = Polyhedron(v, backend='normaliz') # optional - pynormaliz - sage: pts1 = P.integral_points() # optional - pynormaliz - sage: all(P.contains(p) for p in pts1) # optional - pynormaliz + sage: P = Polyhedron(v, backend='normaliz') + sage: pts1 = P.integral_points() + sage: all(P.contains(p) for p in pts1) True - sage: pts2 = LatticePolytope(v).points() # optional - palp - sage: for p in pts1: p.set_immutable() # optional - pynormaliz - sage: set(pts1) == set(pts2) # optional - palp # optional - pynormaliz + sage: pts2 = LatticePolytope(v).points() # optional - palp + sage: for p in pts1: p.set_immutable() + sage: set(pts1) == set(pts2) # optional - palp True - sage: timeit('Polyhedron(v, backend='normaliz').integral_points()') # not tested - random + sage: timeit('Polyhedron(v, backend='normaliz').integral_points()') # not tested - random 625 loops, best of 3: 1.41 ms per loop - sage: timeit('LatticePolytope(v).points()') # not tested - random + sage: timeit('LatticePolytope(v).points()') # not tested - random 25 loops, best of 3: 17.2 ms per loop TESTS: @@ -1954,32 +1992,32 @@ def integral_points(self, threshold=10000): Empty polyhedron in 1 dimension:: - sage: P = Polyhedron(ambient_dim=1, backend='normaliz') # optional - pynormaliz - sage: P.integral_points() # optional - pynormaliz + sage: P = Polyhedron(ambient_dim=1, backend='normaliz') + sage: P.integral_points() () Empty polyhedron in 0 dimensions:: - sage: P = Polyhedron(ambient_dim=0, backend='normaliz') # optional - pynormaliz - sage: P.integral_points() # optional - pynormaliz + sage: P = Polyhedron(ambient_dim=0, backend='normaliz') + sage: P.integral_points() () Single point in 1 dimension:: - sage: P = Polyhedron([[3]], backend='normaliz') # optional - pynormaliz - sage: P.integral_points() # optional - pynormaliz + sage: P = Polyhedron([[3]], backend='normaliz') + sage: P.integral_points() ((3),) Single non-integral point in 1 dimension:: - sage: P = Polyhedron([[1/2]], backend='normaliz') # optional - pynormaliz - sage: P.integral_points() # optional - pynormaliz + sage: P = Polyhedron([[1/2]], backend='normaliz') + sage: P.integral_points() () Single point in 0 dimensions:: - sage: P = Polyhedron([[]], backend='normaliz') # optional - pynormaliz - sage: P.integral_points() # optional - pynormaliz + sage: P = Polyhedron([[]], backend='normaliz') + sage: P.integral_points() ((),) A polytope with no integral points (:trac:`22938`):: @@ -1988,12 +2026,12 @@ def integral_points(self, threshold=10000): ....: [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, -1], ....: [-1, -1, -1, -1], [1, 1, 0, 0], [1, 0, 1, 0], ....: [1, 0, 0, 1]] - sage: P = Polyhedron(ieqs=ieqs, backend='normaliz') # optional - pynormaliz - sage: P.bounding_box() # optional - pynormaliz + sage: P = Polyhedron(ieqs=ieqs, backend='normaliz') + sage: P.bounding_box() ((-3/4, -1/2, -1/4), (-1/2, -1/4, 0)) - sage: P.bounding_box(integral_hull=True) # optional - pynormaliz + sage: P.bounding_box(integral_hull=True) (None, None) - sage: P.integral_points() # optional - pynormaliz + sage: P.integral_points() () Check the polytopes from :trac:`22984`:: @@ -2025,8 +2063,8 @@ def integral_points(self, threshold=10000): ....: [4, 0, 0, 0, 0, 0, 1, 0, 0], ....: [2, 0, 0, 0, 0, 0, 0, 1, 0], ....: [1, 0, 0, 0, 0, 0, 0, 0, 1]] - sage: P = Polyhedron(ieqs=ieqs, backend='normaliz') # optional - pynormaliz - sage: P.integral_points() # optional - pynormaliz + sage: P = Polyhedron(ieqs=ieqs, backend='normaliz') + sage: P.integral_points() ((-2, -2, -4, -5, -4, -3, -2, -1), (-2, -2, -4, -5, -4, -3, -2, 0), (-1, -2, -3, -4, -3, -2, -2, -1), @@ -2047,8 +2085,8 @@ def integral_points(self, threshold=10000): ....: [4, 0, 0, 0, 0, 0, 1, 0, 0], ....: [2, 0, 0, 0, 0, 0, 0, 1, 0], ....: [1, 0, 0, 0, 0, 0, 0, 0, 1]] - sage: P = Polyhedron(ieqs=ieqs, backend='normaliz') # optional - pynormaliz - sage: P.integral_points() # optional - pynormaliz + sage: P = Polyhedron(ieqs=ieqs, backend='normaliz') + sage: P.integral_points() ((-3, -4, -6, -8, -6, -4, -2, -1), (-3, -4, -6, -8, -6, -4, -2, 0), (-2, -2, -4, -5, -4, -3, -2, -1), @@ -2110,20 +2148,20 @@ def integral_points_generators(self): Normaliz gives a nonnegative integer basis of the lineality space:: - sage: P = Polyhedron(backend='normaliz',lines=[[2,2]]) # optional - pynormaliz - sage: P.integral_points_generators() # optional - pynormaliz + sage: P = Polyhedron(backend='normaliz', lines=[[2,2]]) + sage: P.integral_points_generators() (((0, 0),), (), ((1, 1),)) A recession cone generated by two rays:: - sage: C = Polyhedron(backend='normaliz',rays=[[1,2],[2,1]]) # optional - pynormaliz - sage: C.integral_points_generators() # optional - pynormaliz + sage: C = Polyhedron(backend='normaliz', rays=[[1,2], [2,1]]) + sage: C.integral_points_generators() (((0, 0),), ((1, 1), (1, 2), (2, 1)), ()) Empty polyhedron:: - sage: P = Polyhedron(backend='normaliz') # optional - pynormaliz - sage: P.integral_points_generators() # optional - pynormaliz + sage: P = Polyhedron(backend='normaliz') + sage: P.integral_points_generators() ((), (), ()) """ # Trivial cases: polyhedron with 0 vertices @@ -2200,16 +2238,16 @@ class functions. is equal to 1 = `\chi_{trivial}` (Prop 6.1 [Stap2011]_). Here is the computation for the 3-dimensional standard simplex:: - sage: S = polytopes.simplex(3, backend = 'normaliz'); S # optional - pynormaliz + sage: S = polytopes.simplex(3, backend='normaliz'); S A 3-dimensional polyhedron in ZZ^4 defined as the convex hull of 4 vertices - sage: G = S.restricted_automorphism_group(output = 'permutation'); # optional - pynormaliz - sage: G.is_isomorphic(SymmetricGroup(4)) # optional - pynormaliz + sage: G = S.restricted_automorphism_group(output='permutation') # optional - sage.groups + sage: G.is_isomorphic(SymmetricGroup(4)) # optional - sage.groups True - sage: len(G) # optional - pynormaliz + sage: len(G) # optional - sage.groups 24 - sage: Hstar = S._Hstar_function_normaliz(G); Hstar # optional - pynormaliz + sage: Hstar = S._Hstar_function_normaliz(G); Hstar # optional - sage.groups chi_4 - sage: G.character_table() # optional - pynormaliz + sage: G.character_table() # optional - sage.groups [ 1 -1 1 1 -1] [ 3 -1 0 -1 1] [ 2 0 -1 2 0] @@ -2221,36 +2259,37 @@ class functions. `\pm(0,0,1),\pm(1,0,1), \pm(0,1,1), \pm(1,1,1)` and let G = `\Zmod{2}` act on P as follows:: - sage: P = Polyhedron(vertices=[[0,0,1],[0,0,-1],[1,0,1],[-1,0,-1],[0,1,1], # optional - pynormaliz - ....: [0,-1,-1],[1,1,1],[-1,-1,-1]], + sage: P = Polyhedron(vertices=[[0,0,1], [0,0,-1], [1,0,1], [-1,0,-1], + ....: [0,1,1], [0,-1,-1], [1,1,1], [-1,-1,-1]], ....: backend='normaliz') - sage: K = P.restricted_automorphism_group(output = 'permutation') # optional - pynormaliz - sage: G = K.subgroup(gens = [K([(0,2),(1,3),(4,6),(5,7)])]) # optional - pynormaliz - sage: conj_reps = G.conjugacy_classes_representatives() # optional - pynormaliz - sage: Dict = P.permutations_to_matrices(conj_reps, acting_group = G) # optional - pynormaliz - sage: list(Dict.keys())[0] # optional - pynormaliz + sage: K = P.restricted_automorphism_group(output='permutation') # optional - sage.groups + sage: G = K.subgroup(gens=[K([(0,2),(1,3),(4,6),(5,7)])]) # optional - sage.groups + sage: conj_reps = G.conjugacy_classes_representatives() # optional - sage.groups + sage: Dict = P.permutations_to_matrices(conj_reps, acting_group=G) # optional - sage.groups + sage: list(Dict.keys())[0] # optional - sage.groups (0,2)(1,3)(4,6)(5,7) - sage: list(Dict.values())[0] # optional - pynormaliz + sage: list(Dict.values())[0] # optional - sage.groups [-1 0 1 0] [ 0 1 0 0] [ 0 0 1 0] [ 0 0 0 1] - sage: len(G) # optional - pynormaliz + sage: len(G) # optional - sage.groups 2 - sage: G.character_table() # optional - pynormaliz + sage: G.character_table() # optional - sage.groups [ 1 1] [ 1 -1] Then we calculate the rational function `H^*(t)`:: - sage: Hst = P._Hstar_function_normaliz(G); Hst # optional - pynormaliz - (chi_0*t^4 + (3*chi_0 + 3*chi_1)*t^3 + (8*chi_0 + 2*chi_1)*t^2 + (3*chi_0 + 3*chi_1)*t + chi_0)/(t + 1) + sage: Hst = P._Hstar_function_normaliz(G); Hst # optional - sage.groups + (chi_0*t^4 + (3*chi_0 + 3*chi_1)*t^3 + + (8*chi_0 + 2*chi_1)*t^2 + (3*chi_0 + 3*chi_1)*t + chi_0)/(t + 1) To see the exact as written in [Stap2011]_, we can format it as ``'Hstar_as_lin_comb'``. The first coordinate is the coefficient of the trivial character; the second is the coefficient of the sign character:: - sage: lin = P._Hstar_function_normaliz(G,output = 'Hstar_as_lin_comb'); lin # optional - pynormaliz + sage: lin = P._Hstar_function_normaliz(G, output='Hstar_as_lin_comb'); lin # optional - sage.groups ((t^4 + 3*t^3 + 8*t^2 + 3*t + 1)/(t + 1), (3*t^3 + 2*t^2 + 3*t)/(t + 1)) """ from sage.groups.conjugacy_classes import ConjugacyClassGAP @@ -2359,15 +2398,16 @@ def _Hstar_as_rat_fct(self, initial_Hstar): The expression of `H^*` as a polynomial in `t` for a 3-dimensional simplex is computed as follows:: - sage: simplex = Polyhedron(vertices=[[0,0,0],[1,0,0],[0,1,0],[0,0,1]],backend='normaliz') # optional - pynormaliz - sage: Hstar = simplex.Hstar_function(); Hstar # optional - pynormaliz # indirect doctest + sage: simplex = Polyhedron(vertices=[[0,0,0], [1,0,0], + ....: [0,1,0], [0,0,1]], backend='normaliz') + sage: Hstar = simplex.Hstar_function(); Hstar # indirect doctest # optional - sage.rings.number_field chi_4 The polynomial is `\chi_4 \cdot t^0`. We can see which irreducible representation `\chi_4` corresponds to by looking at the character table:: - sage: G = simplex.restricted_automorphism_group(output='permutation') # optional - pynormaliz - sage: char = G.character_table();char # optional - pynormaliz + sage: G = simplex.restricted_automorphism_group(output='permutation') # optional - sage.groups + sage: char = G.character_table(); char # optional - sage.groups [ 1 -1 1 1 -1] [ 3 -1 0 -1 1] [ 2 0 -1 2 0] @@ -2379,15 +2419,16 @@ def _Hstar_as_rat_fct(self, initial_Hstar): As another example, we can look at `H^*(t)` for the `\pm 1` square:: - sage: square = Polyhedron(vertices = [[1,1],[-1,1],[-1,-1],[1,-1]], backend ='normaliz') # optional - pynormaliz - sage: Hstar = square.Hstar_function() ; Hstar # optional - pynormaliz + sage: square = Polyhedron(vertices=[[1,1], [-1,1], [-1,-1], [1,-1]], + ....: backend='normaliz') + sage: Hstar = square.Hstar_function(); Hstar # optional - sage.rings.number_field chi_0*t^2 + (2*chi_0 + chi_2 + chi_3 + chi_4)*t + chi_0 Plugging in the values from the first column of the character table below yields the `h^*`-polynomial of the square, `t^2+6t+1`:: - sage: G = square.restricted_automorphism_group(output='permutation') # optional - pynormaliz - sage: G.character_table() # optional - pynormaliz + sage: G = square.restricted_automorphism_group(output='permutation') # optional - sage.groups + sage: G.character_table() # optional - sage.groups [ 1 1 1 1 1] [ 1 -1 -1 1 1] [ 1 -1 1 -1 1] @@ -2434,28 +2475,30 @@ class functions of the acting group. A character `\rho` is effective if The `H^*` series of the two-dimensional permutahedron under the action of the symmetric group is effective:: - sage: p3 = polytopes.permutahedron(3, backend = 'normaliz') # optional - pynormaliz - sage: G = p3.restricted_automorphism_group(output='permutation') # optional - pynormaliz - sage: reflection12 = G([(0,2),(1,4),(3,5)]) # optional - pynormaliz - sage: reflection23 = G([(0,1),(2,3),(4,5)]) # optional - pynormaliz - sage: S3 = G.subgroup(gens=[reflection12, reflection23]) # optional - pynormaliz - sage: S3.is_isomorphic(SymmetricGroup(3)) # optional - pynormaliz + sage: p3 = polytopes.permutahedron(3, backend='normaliz') + sage: G = p3.restricted_automorphism_group(output='permutation') # optional - sage.groups + sage: reflection12 = G([(0,2),(1,4),(3,5)]) # optional - sage.groups + sage: reflection23 = G([(0,1),(2,3),(4,5)]) # optional - sage.groups + sage: S3 = G.subgroup(gens=[reflection12, reflection23]) # optional - sage.groups + sage: S3.is_isomorphic(SymmetricGroup(3)) # optional - sage.groups True - sage: [Hstar, Hlin] = [p3.Hstar_function(S3), p3.Hstar_function(S3, output = 'Hstar_as_lin_comb')] # optional - pynormaliz - sage: p3._is_effective_normaliz(Hstar,Hlin) # optional - pynormaliz + sage: Hstar = p3.Hstar_function(S3) # optional - sage.groups sage.rings.number_field + sage: Hlin = p3.Hstar_function(S3, output='Hstar_as_lin_comb') # optional - sage.groups sage.rings.number_field + sage: p3._is_effective_normaliz(Hstar, Hlin) # optional - sage.groups sage.rings.number_field True If the `H^*`-series is not polynomial, then it is not effective:: - sage: P = Polyhedron(vertices=[[0,0,1],[0,0,-1],[1,0,1],[-1,0,-1],[0,1,1], # optional - pynormaliz - ....: [0,-1,-1],[1,1,1],[-1,-1,-1]], + sage: P = Polyhedron(vertices=[[0,0,1], [0,0,-1], [1,0,1], [-1,0,-1], + ....: [0,1,1], [0,-1,-1], [1,1,1], [-1,-1,-1]], ....: backend='normaliz') - sage: G = P.restricted_automorphism_group(output = 'permutation') # optional - pynormaliz - sage: H = G.subgroup(gens = [G([(0,2),(1,3),(4,6),(5,7)])]) # optional - pynormaliz - sage: Hstar = P.Hstar_function(H); Hstar # optional - pynormaliz - (chi_0*t^4 + (3*chi_0 + 3*chi_1)*t^3 + (8*chi_0 + 2*chi_1)*t^2 + (3*chi_0 + 3*chi_1)*t + chi_0)/(t + 1) - sage: Hstar_lin = P.Hstar_function(H, output = 'Hstar_as_lin_comb') # optional - pynormaliz - sage: P._is_effective_normaliz(Hstar, Hstar_lin) # optional - pynormaliz + sage: G = P.restricted_automorphism_group(output='permutation') # optional - sage.groups + sage: H = G.subgroup(gens = [G([(0,2),(1,3),(4,6),(5,7)])]) # optional - sage.groups + sage: Hstar = P.Hstar_function(H); Hstar # optional - sage.groups sage.rings.number_field + (chi_0*t^4 + (3*chi_0 + 3*chi_1)*t^3 + + (8*chi_0 + 2*chi_1)*t^2 + (3*chi_0 + 3*chi_1)*t + chi_0)/(t + 1) + sage: Hstar_lin = P.Hstar_function(H, output='Hstar_as_lin_comb') # optional - sage.groups sage.rings.number_field + sage: P._is_effective_normaliz(Hstar, Hstar_lin) # optional - sage.groups sage.rings.number_field False """ if not Hstar.denominator().is_unit(): @@ -2480,9 +2523,9 @@ class Polyhedron_ZZ_normaliz(Polyhedron_QQ_normaliz, Polyhedron_ZZ): EXAMPLES:: - sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], # optional - pynormaliz + sage: p = Polyhedron(vertices=[(0,0), (1,0), (0,1)], ....: rays=[(1,1)], lines=[], ....: backend='normaliz', base_ring=ZZ) - sage: TestSuite(p).run() # optional - pynormaliz + sage: TestSuite(p).run() """ pass diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 3d4a65b3df0..ff5be490df5 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -124,8 +124,8 @@ class Polyhedron_base(Polyhedron_base7): :: - sage: p=polytopes.flow_polytope(digraphs.DeBruijn(3,2)) # optional - sage.graphs - sage: TestSuite(p).run() # optional - sage.graphs + sage: p = polytopes.flow_polytope(digraphs.DeBruijn(3,2)) # optional - sage.graphs + sage: TestSuite(p).run() # optional - sage.graphs :: @@ -135,13 +135,14 @@ class Polyhedron_base(Polyhedron_base7): :: - sage: P = polytopes.permutahedron(3) * Polyhedron(rays=[[0,0,1],[0,1,1],[1,2,3]]) # optional - sage.combinat - sage: TestSuite(P).run() # optional - sage.combinat + sage: P3 = polytopes.permutahedron(3) + sage: P = P3 * Polyhedron(rays=[[0,0,1], [0,1,1], [1,2,3]]) # optional - sage.combinat + sage: TestSuite(P).run() # optional - sage.combinat :: - sage: P = polytopes.permutahedron(3)*Polyhedron(rays=[[0,0,1],[0,1,1]], lines=[[1,0,0]]) # optional - sage.combinat - sage: TestSuite(P).run() # optional - sage.combinat + sage: P = P3 * Polyhedron(rays=[[0,0,1], [0,1,1]], lines=[[1,0,0]]) # optional - sage.combinat + sage: TestSuite(P).run() # optional - sage.combinat :: @@ -317,16 +318,16 @@ def boundary_complex(self): The boundary complex of the octahedron:: sage: oc = polytopes.octahedron() - sage: sc_oc = oc.boundary_complex() - sage: fl_oc = oc.face_lattice() # optional - sage.combinat - sage: fl_sc = sc_oc.face_poset() # optional - sage.combinat - sage: [len(x) for x in fl_oc.level_sets()] # optional - sage.combinat + sage: sc_oc = oc.boundary_complex() # optional - sage.graphs + sage: fl_oc = oc.face_lattice() # optional - sage.combinat sage.graphs + sage: fl_sc = sc_oc.face_poset() # optional - sage.combinat sage.graphs + sage: [len(x) for x in fl_oc.level_sets()] # optional - sage.combinat sage.graphs [1, 6, 12, 8, 1] - sage: [len(x) for x in fl_sc.level_sets()] # optional - sage.combinat + sage: [len(x) for x in fl_sc.level_sets()] # optional - sage.combinat sage.graphs [6, 12, 8] - sage: sc_oc.euler_characteristic() + sage: sc_oc.euler_characteristic() # optional - sage.graphs 2 - sage: sc_oc.homology() + sage: sc_oc.homology() # optional - sage.graphs {0: 0, 1: 0, 2: Z} The polyhedron should be simplicial:: @@ -463,7 +464,7 @@ def is_inscribed(self, certificate=False): EXAMPLES:: - sage: q = Polyhedron(vertices = [[1,1,1,1],[-1,-1,1,1],[1,-1,-1,1], + sage: q = Polyhedron(vertices=[[1,1,1,1],[-1,-1,1,1],[1,-1,-1,1], ....: [-1,1,-1,1],[1,1,1,-1],[-1,-1,1,-1], ....: [1,-1,-1,-1],[-1,1,-1,-1],[0,0,10/13,-24/13], ....: [0,0,-10/13,-24/13]]) @@ -555,7 +556,7 @@ def is_inscribed(self, certificate=False): sage: V = P.Vrepresentation() sage: H = P.Hrepresentation() sage: parent = P.parent() - sage: for V1 in Permutations(V): # optional - sage.combinat + sage: for V1 in Permutations(V): # optional - sage.combinat ....: P1 = parent._element_constructor_( ....: [V1, [], []], [H, []], Vrep_minimal=True, Hrep_minimal=True) ....: assert P1.is_inscribed() @@ -623,7 +624,7 @@ def hyperplane_arrangement(self): EXAMPLES:: sage: p = polytopes.hypercube(2) - sage: p.hyperplane_arrangement() # optional - sage.combinat + sage: p.hyperplane_arrangement() # optional - sage.combinat Arrangement <-t0 + 1 | -t1 + 1 | t1 + 1 | t0 + 1> """ names = tuple('t' + str(i) for i in range(self.ambient_dim())) @@ -657,7 +658,7 @@ def normal_fan(self, direction='inner'): EXAMPLES:: - sage: S = Polyhedron(vertices = [[0, 0], [1, 0], [0, 1]]) + sage: S = Polyhedron(vertices=[[0, 0], [1, 0], [0, 1]]) sage: S.normal_fan() Rational polyhedral fan in 2-d lattice N @@ -667,25 +668,27 @@ def normal_fan(self, direction='inner'): Currently, it is only possible to get the normal fan of a bounded rational polytope:: - sage: P = Polyhedron(rays = [[1, 0], [0, 1]]) + sage: P = Polyhedron(rays=[[1, 0], [0, 1]]) sage: P.normal_fan() Traceback (most recent call last): ... NotImplementedError: the normal fan is only supported for polytopes (compact polyhedra). - sage: Q = Polyhedron(vertices = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]) + sage: Q = Polyhedron(vertices=[[1, 0, 0], [0, 1, 0], [0, 0, 1]]) sage: Q.normal_fan() Traceback (most recent call last): ... ValueError: the normal fan is only defined for full-dimensional polytopes - sage: R = Polyhedron(vertices=[[0, 0], [AA(sqrt(2)), 0], [0, AA(sqrt(2))]]) # optional - sage.rings.number_field - sage: R.normal_fan() # optional - sage.rings.number_field + sage: R = Polyhedron(vertices=[[0, 0], # optional - sage.rings.number_field sage.symbolic + ....: [AA(sqrt(2)), 0], + ....: [0, AA(sqrt(2))]]) + sage: R.normal_fan() # optional - sage.rings.number_field sage.symbolic Traceback (most recent call last): ... NotImplementedError: normal fan handles only polytopes over the rationals - sage: P = Polyhedron(vertices=[[0,0],[2,0],[0,2],[2,1],[1,2]]) + sage: P = Polyhedron(vertices=[[0,0], [2,0], [0,2], [2,1], [1,2]]) sage: P.normal_fan(direction=None) Traceback (most recent call last): ... @@ -746,13 +749,14 @@ def face_fan(self): The polytope should contain the origin in the interior:: - sage: P = Polyhedron(vertices = [[1/2, 1], [1, 1/2]]) + sage: P = Polyhedron(vertices=[[1/2, 1], [1, 1/2]]) sage: P.face_fan() Traceback (most recent call last): ... - ValueError: face fans are defined only for polytopes containing the origin as an interior point! + ValueError: face fans are defined only for polytopes + containing the origin as an interior point! - sage: Q = Polyhedron(vertices = [[-1, 1/2], [1, -1/2]]) + sage: Q = Polyhedron(vertices=[[-1, 1/2], [1, -1/2]]) sage: Q.contains([0,0]) True sage: FF = Q.face_fan(); FF @@ -760,8 +764,8 @@ def face_fan(self): The polytope has to have rational coordinates:: - sage: S = polytopes.dodecahedron() # optional - sage.rings.number_field - sage: S.face_fan() # optional - sage.rings.number_field + sage: S = polytopes.dodecahedron() # optional - sage.rings.number_field + sage: S.face_fan() # optional - sage.rings.number_field Traceback (most recent call last): ... NotImplementedError: face fan handles only polytopes over the rationals @@ -852,8 +856,8 @@ def barycentric_subdivision(self, subdivision_frac=None): sage: P.barycentric_subdivision() A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 6 vertices - sage: P = polytopes.regular_polygon(4, base_ring=QQ) # optional - sage.rings.number_field - sage: P.barycentric_subdivision() # optional - sage.rings.number_field + sage: P = polytopes.regular_polygon(4, base_ring=QQ) # optional - sage.rings.number_field + sage: P.barycentric_subdivision() # optional - sage.rings.number_field A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 8 vertices @@ -965,17 +969,19 @@ def permutations_to_matrices(self, conj_class_reps, acting_group=None, additiona `\pm 1` 2-dimensional square. The permutations are written in terms of the vertices of the square:: - sage: square = Polyhedron(vertices=[[1,1],[-1,1],[-1,-1],[1,-1]], backend='normaliz') # optional - pynormaliz - sage: square.vertices() # optional - pynormaliz + sage: square = Polyhedron(vertices=[[1,1], [-1,1], # optional - pynormaliz + ....: [-1,-1], [1,-1]], + ....: backend='normaliz') + sage: square.vertices() # optional - pynormaliz (A vertex at (-1, -1), - A vertex at (-1, 1), - A vertex at (1, -1), - A vertex at (1, 1)) - sage: aut_square = square.restricted_automorphism_group(output='permutation') # optional - pynormaliz # optional - sage.groups - sage: conj_reps = aut_square.conjugacy_classes_representatives() # optional - pynormaliz # optional - sage.groups - sage: gens_dict = square.permutations_to_matrices(conj_reps); # optional - pynormaliz # optional - sage.groups - sage: rotation_180 = aut_square([(0,3),(1,2)]) # optional - pynormaliz # optional - sage.groups - sage: rotation_180, gens_dict[rotation_180] # optional - pynormaliz # optional - sage.groups + A vertex at (-1, 1), + A vertex at (1, -1), + A vertex at (1, 1)) + sage: aut_square = square.restricted_automorphism_group(output='permutation') # optional - pynormaliz sage.groups + sage: conj_reps = aut_square.conjugacy_classes_representatives() # optional - pynormaliz sage.groups + sage: gens_dict = square.permutations_to_matrices(conj_reps) # optional - pynormaliz sage.groups + sage: rotation_180 = aut_square([(0,3),(1,2)]) # optional - pynormaliz sage.groups + sage: rotation_180, gens_dict[rotation_180] # optional - pynormaliz sage.groups ( [-1 0 0] [ 0 -1 0] @@ -985,11 +991,12 @@ def permutations_to_matrices(self, conj_class_reps, acting_group=None, additiona This example tests the functionality for additional elements:: sage: C = polytopes.cross_polytope(2) - sage: G = C.restricted_automorphism_group(output='permutation') # optional - sage.groups # optional - sage.rings.real_mpfr - sage: conj_reps = G.conjugacy_classes_representatives() # optional - sage.groups # optional - sage.rings.real_mpfr - sage: add_elt = G([(0, 2, 3, 1)]) # optional - sage.groups # optional - sage.rings.real_mpfr - sage: dict = C.permutations_to_matrices(conj_reps,additional_elts = [add_elt]) # optional - sage.groups # optional - sage.rings.real_mpfr - sage: dict[add_elt] # optional - sage.groups # optional - sage.rings.real_mpfr + sage: G = C.restricted_automorphism_group(output='permutation') # optional - sage.groups sage.rings.real_mpfr + sage: conj_reps = G.conjugacy_classes_representatives() # optional - sage.groups sage.rings.real_mpfr + sage: add_elt = G([(0, 2, 3, 1)]) # optional - sage.groups sage.rings.real_mpfr + sage: dict = C.permutations_to_matrices(conj_reps, # optional - sage.groups sage.rings.real_mpfr + ....: additional_elts=[add_elt]) + sage: dict[add_elt] # optional - sage.groups sage.rings.real_mpfr [ 0 1 0] [-1 0 0] [ 0 0 1] @@ -1048,16 +1055,17 @@ def bounding_box(self, integral=False, integral_hull=False): EXAMPLES:: - sage: Polyhedron([ (1/3,2/3), (2/3, 1/3) ]).bounding_box() + sage: Polyhedron([(1/3,2/3), (2/3, 1/3)]).bounding_box() ((1/3, 1/3), (2/3, 2/3)) - sage: Polyhedron([ (1/3,2/3), (2/3, 1/3) ]).bounding_box(integral=True) + sage: Polyhedron([(1/3,2/3), (2/3, 1/3)]).bounding_box(integral=True) ((0, 0), (1, 1)) - sage: Polyhedron([ (1/3,2/3), (2/3, 1/3) ]).bounding_box(integral_hull=True) + sage: Polyhedron([(1/3,2/3), (2/3, 1/3)]).bounding_box(integral_hull=True) (None, None) - sage: Polyhedron([ (1/3,2/3), (3/3, 4/3) ]).bounding_box(integral_hull=True) + sage: Polyhedron([(1/3,2/3), (3/3, 4/3)]).bounding_box(integral_hull=True) ((1, 1), (1, 1)) - sage: polytopes.buckyball(exact=False).bounding_box() # optional - sage.groups - ((-0.8090169944, -0.8090169944, -0.8090169944), (0.8090169944, 0.8090169944, 0.8090169944)) + sage: polytopes.buckyball(exact=False).bounding_box() # optional - sage.groups + ((-0.8090169944, -0.8090169944, -0.8090169944), + (0.8090169944, 0.8090169944, 0.8090169944)) TESTS:: @@ -1148,25 +1156,25 @@ def _polymake_init_(self): Algebraic polyhedron:: - sage: P = polytopes.dodecahedron(); P # optional - sage.rings.number_field + sage: P = polytopes.dodecahedron(); P # optional - sage.rings.number_field A 3-dimensional polyhedron in (Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?)^3 defined as the convex hull of 20 vertices - sage: print("There may be a recompilation warning"); PP = polymake(P); PP # optional - jupymake # optional - sage.rings.number_field - There may be a recompilation warning... + sage: print("Maybe recompile warning"); PP = polymake(P); PP # optional - jupymake sage.rings.number_field + Maybe recompile warning... Polytope>[...] - sage: sorted(PP.VERTICES[:], key=repr)[0] # optional - jupymake # optional - sage.rings.number_field + sage: sorted(PP.VERTICES[:], key=repr)[0] # optional - jupymake sage.rings.number_field 1 -1+1r5 -4+2r5 0 Floating-point polyhedron:: - sage: P = polytopes.dodecahedron(exact=False); P # optional - sage.groups + sage: P = polytopes.dodecahedron(exact=False); P # optional - sage.groups A 3-dimensional polyhedron in RDF^3 defined as the convex hull of 20 vertices - sage: print("There may be a recompilation warning"); PP = polymake(P); PP # optional - jupymake # optional - sage.groups + sage: print("Maybe recompile warning"); PP = polymake(P); PP # optional - jupymake sage.groups There may be a recompilation warning... Polytope[...] - sage: sorted(PP.VERTICES[:], key=repr)[0] # optional - jupymake # optional - sage.groups + sage: sorted(PP.VERTICES[:], key=repr)[0] # optional - jupymake sage.groups 1 -0.472135955 0 -1.236067978 """ diff --git a/src/sage/geometry/polyhedron/base2.py b/src/sage/geometry/polyhedron/base2.py index ab83971f35f..41ec3ad203d 100644 --- a/src/sage/geometry/polyhedron/base2.py +++ b/src/sage/geometry/polyhedron/base2.py @@ -143,8 +143,9 @@ def lattice_polytope(self, envelope=False): First, a polyhedron with integral vertices:: sage: P = Polyhedron(vertices=[(1, 0), (0, 1), (-1, 0), (0, -1)]) - sage: lp = P.lattice_polytope() - sage: lp # optional - palp + sage: lp = P.lattice_polytope(); lp + 2-d reflexive polytope... in 2-d lattice M + sage: lp # optional - palp polytopes_db 2-d reflexive polytope #3 in 2-d lattice M sage: lp.vertices() M(-1, 0), @@ -163,7 +164,7 @@ def lattice_polytope(self, envelope=False): to add the argument "envelope=True" to compute an enveloping lattice polytope. sage: lp = P.lattice_polytope(True) - sage: lp # optional - palp + sage: lp # optional - palp polytopes_db 2-d reflexive polytope #5 in 2-d lattice M sage: lp.vertices() M(-1, 0), diff --git a/src/sage/geometry/polyhedron/base4.py b/src/sage/geometry/polyhedron/base4.py index 30da8c35733..6b309553123 100644 --- a/src/sage/geometry/polyhedron/base4.py +++ b/src/sage/geometry/polyhedron/base4.py @@ -1225,7 +1225,7 @@ def is_self_dual(self): True sage: polytopes.cube().is_self_dual() False - sage: polytopes.hypersimplex(5,2).is_self_dual() + sage: polytopes.hypersimplex(5,2).is_self_dual() # optional - sage.combinat False sage: P = Polyhedron(vertices=[[1/2, 1/3]], rays=[[1, 1]]).is_self_dual() Traceback (most recent call last): diff --git a/src/sage/geometry/polyhedron/base5.py b/src/sage/geometry/polyhedron/base5.py index 311ff1c59fe..decd2fb05a4 100644 --- a/src/sage/geometry/polyhedron/base5.py +++ b/src/sage/geometry/polyhedron/base5.py @@ -164,8 +164,8 @@ def polar(self, in_affine_span=False): EXAMPLES:: - sage: p = Polyhedron(vertices = [[0,0,1],[0,1,0],[1,0,0],[0,0,0],[1,1,1]], base_ring=QQ) - sage: p + sage: p = Polyhedron(vertices=[[0,0,1], [0,1,0], [1,0,0], [0,0,0], [1,1,1]], + ....: base_ring=QQ); p A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 5 vertices sage: p.polar() A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 6 vertices @@ -324,7 +324,7 @@ def _test_pyramid(self, tester=None, **options): TESTS: - sage: polytopes.regular_polygon(4)._test_pyramid() # optional - sage.rings.number_field + sage: polytopes.regular_polygon(4)._test_pyramid() # optional - sage.rings.number_field """ if tester is None: tester = self._tester(**options) @@ -393,8 +393,7 @@ def bipyramid(self): sage: cross_poly_4d = octahedron.bipyramid() sage: cross_poly_4d.n_vertices() 8 - sage: q = [list(v) for v in cross_poly_4d.vertex_generator()] - sage: q + sage: q = [list(v) for v in cross_poly_4d.vertex_generator()]; q [[-1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], @@ -639,11 +638,9 @@ def lawrence_polytope(self): sage: L = P.lawrence_polytope(); L A 9-dimensional polyhedron in ZZ^9 defined as the convex hull of 12 vertices sage: V = P.vertices_list() - sage: i = 0 - sage: for v in V: + sage: for i, v in enumerate(V): ....: v = v + i*[0] ....: P = P.lawrence_extension(v) - ....: i = i + 1 sage: P == L True @@ -699,14 +696,17 @@ def minkowski_sum(self, other): A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 13 vertices sage: four_cube = polytopes.hypercube(4) - sage: four_simplex = Polyhedron(vertices = [[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]]) + sage: four_simplex = Polyhedron(vertices=[[0, 0, 0, 1], [0, 0, 1, 0], + ....: [0, 1, 0, 0], [1, 0, 0, 0]]) sage: four_cube + four_simplex A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 36 vertices sage: four_cube.minkowski_sum(four_simplex) == four_cube + four_simplex True - sage: poly_spam = Polyhedron([[3,4,5,2],[1,0,0,1],[0,0,0,0],[0,4,3,2],[-3,-3,-3,-3]], base_ring=ZZ) - sage: poly_eggs = Polyhedron([[5,4,5,4],[-4,5,-4,5],[4,-5,4,-5],[0,0,0,0]], base_ring=QQ) + sage: poly_spam = Polyhedron([[3,4,5,2], [1,0,0,1], [0,0,0,0], + ....: [0,4,3,2], [-3,-3,-3,-3]], base_ring=ZZ) + sage: poly_eggs = Polyhedron([[5,4,5,4], [-4,5,-4,5], + ....: [4,-5,4,-5], [0,0,0,0]], base_ring=QQ) sage: poly_spam + poly_spam + poly_eggs A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 12 vertices """ @@ -771,7 +771,7 @@ def minkowski_difference(self, other): The polyhedra need not be full-dimensional:: - sage: X2 = Polyhedron(vertices=[(-1,-1,0),(1,-1,0),(-1,1,0),(1,1,0)]) + sage: X2 = Polyhedron(vertices=[(-1,-1,0), (1,-1,0), (-1,1,0), (1,1,0)]) sage: Y2 = Polyhedron(vertices=[(0,0,0), (0,1,0), (1,0,0)]) / 2 sage: (X2+Y2)-Y2 == X2 True @@ -782,7 +782,8 @@ def minkowski_difference(self, other): :: sage: four_cube = polytopes.hypercube(4) - sage: four_simplex = Polyhedron(vertices = [[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]]) + sage: four_simplex = Polyhedron(vertices=[[0, 0, 0, 1], [0, 0, 1, 0], + ....: [0, 1, 0, 0], [1, 0, 0, 0]]) sage: four_cube - four_simplex A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 16 vertices sage: four_cube.minkowski_difference(four_simplex) == four_cube - four_simplex @@ -790,8 +791,10 @@ def minkowski_difference(self, other): Coercion of the base ring works:: - sage: poly_spam = Polyhedron([[3,4,5,2],[1,0,0,1],[0,0,0,0],[0,4,3,2],[-3,-3,-3,-3]], base_ring=ZZ) - sage: poly_eggs = Polyhedron([[5,4,5,4],[-4,5,-4,5],[4,-5,4,-5],[0,0,0,0]], base_ring=QQ) / 100 + sage: poly_spam = Polyhedron([[3,4,5,2], [1,0,0,1], [0,0,0,0], + ....: [0,4,3,2], [-3,-3,-3,-3]], base_ring=ZZ) + sage: poly_eggs = Polyhedron([[5,4,5,4], [-4,5,-4,5], + ....: [4,-5,4,-5], [0,0,0,0]], base_ring=QQ) / 100 sage: poly_spam - poly_eggs A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 5 vertices @@ -867,7 +870,7 @@ def __sub__(self, other): sage: (X-v)+v == X True - sage: Y = Polyhedron(vertices=[(1/2,0),(0,1/2)]) + sage: Y = Polyhedron(vertices=[(1/2,0), (0,1/2)]) sage: (X-Y).Vrepresentation() (A vertex at (1/2, -1), A vertex at (1/2, 1/2), A vertex at (-1, 1/2), A vertex at (-1, -1)) @@ -893,8 +896,8 @@ def product(self, other): EXAMPLES:: - sage: P1 = Polyhedron([[0],[1]], base_ring=ZZ) - sage: P2 = Polyhedron([[0],[1]], base_ring=QQ) + sage: P1 = Polyhedron([[0], [1]], base_ring=ZZ) + sage: P2 = Polyhedron([[0], [1]], base_ring=QQ) sage: P1.product(P2) A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices @@ -1054,7 +1057,7 @@ def join(self, other): sage: C = polytopes.hypercube(5) sage: S = Polyhedron([[1]]) - sage: C.join(S).is_combinatorially_isomorphic(C.pyramid()) # optional - sage.graphs + sage: C.join(S).is_combinatorially_isomorphic(C.pyramid()) # optional - sage.graphs True sage: P = polytopes.simplex(backend='cdd') @@ -1155,11 +1158,11 @@ def subdirect_sum(self, other): EXAMPLES:: - sage: P1 = Polyhedron([[1],[2]], base_ring=ZZ) - sage: P2 = Polyhedron([[3],[4]], base_ring=QQ) - sage: sds = P1.subdirect_sum(P2);sds - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 - vertices + sage: P1 = Polyhedron([[1], [2]], base_ring=ZZ) + sage: P2 = Polyhedron([[3], [4]], base_ring=QQ) + sage: sds = P1.subdirect_sum(P2); sds + A 2-dimensional polyhedron in QQ^2 + defined as the convex hull of 4 vertices sage: sds.vertices() (A vertex at (0, 3), A vertex at (0, 4), @@ -1220,8 +1223,8 @@ def direct_sum(self, other): EXAMPLES:: - sage: P1 = Polyhedron([[1],[2]], base_ring=ZZ) - sage: P2 = Polyhedron([[3],[4]], base_ring=QQ) + sage: P1 = Polyhedron([[1], [2]], base_ring=ZZ) + sage: P2 = Polyhedron([[3], [4]], base_ring=QQ) sage: ds = P1.direct_sum(P2);ds A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices sage: ds.vertices() @@ -1297,8 +1300,8 @@ def convex_hull(self, other): sage: a_simplex = polytopes.simplex(3, project=True) sage: verts = a_simplex.vertices() - sage: verts = [[x[0]*3/5+x[1]*4/5, -x[0]*4/5+x[1]*3/5, x[2]] for x in verts] - sage: another_simplex = Polyhedron(vertices = verts) + sage: verts = [[x[0]*3/5 + x[1]*4/5, -x[0]*4/5 + x[1]*3/5, x[2]] for x in verts] + sage: another_simplex = Polyhedron(vertices=verts) sage: simplex_union = a_simplex.convex_hull(another_simplex) sage: simplex_union.n_vertices() 7 @@ -1352,10 +1355,10 @@ def intersection(self, other): Check that :trac:`19012` is fixed:: - sage: K. = QuadraticField(5) # optional - sage.rings.number_field - sage: P = Polyhedron([[0, 0], [0, a], [1, 1]]) # optional - sage.rings.number_field - sage: Q = Polyhedron(ieqs=[[-1, a, 1]]) # optional - sage.rings.number_field - sage: P.intersection(Q) # optional - sage.rings.number_field + sage: K. = QuadraticField(5) # optional - sage.rings.number_field + sage: P = Polyhedron([[0, 0], [0, a], [1, 1]]) # optional - sage.rings.number_field + sage: Q = Polyhedron(ieqs=[[-1, a, 1]]) # optional - sage.rings.number_field + sage: P.intersection(Q) # optional - sage.rings.number_field A 2-dimensional polyhedron in (Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790?)^2 defined as the convex hull of 4 vertices @@ -1462,15 +1465,15 @@ def translation(self, displacement): EXAMPLES:: - sage: P = Polyhedron([[0,0],[1,0],[0,1]], base_ring=ZZ) + sage: P = Polyhedron([[0,0], [1,0], [0,1]], base_ring=ZZ) sage: P.translation([2,1]) A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices - sage: P.translation( vector(QQ,[2,1]) ) + sage: P.translation(vector(QQ, [2,1])) A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices TESTS:: - sage: P = Polyhedron([[0,0],[1,0],[0,1]], base_ring=ZZ, backend='field') + sage: P = Polyhedron([[0,0], [1,0], [0,1]], base_ring=ZZ, backend='field') sage: P.translation([2,1]).backend() 'field' @@ -1507,7 +1510,7 @@ def _translation_double_description(self, displacement): EXAMPLES:: - sage: P = Polyhedron([[0,0],[1,0],[0,1]], base_ring=ZZ) + sage: P = Polyhedron([[0,0], [1,0], [0,1]], base_ring=ZZ) sage: Vrep, Hrep, parent = P._translation_double_description([2,1]) sage: [tuple(x) for x in Vrep], [tuple(x) for x in Hrep], parent ([((2, 1), (2, 2), (3, 1)), (), ()], @@ -1547,7 +1550,7 @@ def dilation(self, scalar): EXAMPLES:: - sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,6)]) + sage: p = Polyhedron(vertices=[[t,t^2,t^3] for t in srange(2,6)]) sage: next(p.vertex_generator()) A vertex at (2, 4, 8) sage: p2 = p.dilation(2) @@ -1704,35 +1707,43 @@ def linear_transformation(self, linear_transf, new_base_ring=None): EXAMPLES:: sage: b3 = polytopes.Birkhoff_polytope(3) - sage: proj_mat=matrix([[0,1,0,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,0],[0,0,0,0,0,1,0,0,0],[0,0,0,0,0,0,0,1,0]]) + sage: proj_mat = matrix([[0,1,0,0,0,0,0,0,0], [0,0,0,1,0,0,0,0,0], + ....: [0,0,0,0,0,1,0,0,0], [0,0,0,0,0,0,0,1,0]]) sage: b3_proj = proj_mat * b3; b3_proj A 3-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices - sage: square = polytopes.regular_polygon(4) # optional - sage.rings.number_field - sage: square.vertices_list() # optional - sage.rings.number_field + sage: square = polytopes.regular_polygon(4) # optional - sage.rings.number_field + sage: square.vertices_list() # optional - sage.rings.number_field [[0, -1], [1, 0], [-1, 0], [0, 1]] - sage: transf = matrix([[1,1],[0,1]]) # optional - sage.rings.number_field - sage: sheared = transf * square # optional - sage.rings.number_field - sage: sheared.vertices_list() # optional - sage.rings.number_field + sage: transf = matrix([[1,1], [0,1]]) # optional - sage.rings.number_field + sage: sheared = transf * square # optional - sage.rings.number_field + sage: sheared.vertices_list() # optional - sage.rings.number_field [[-1, -1], [1, 0], [-1, 0], [1, 1]] - sage: sheared == square.linear_transformation(transf) # optional - sage.rings.number_field + sage: sheared == square.linear_transformation(transf) # optional - sage.rings.number_field True Specifying the new base ring may avoid coercion failure:: - sage: K. = QuadraticField(2) # optional - sage.rings.number_field - sage: L. = QuadraticField(3) # optional - sage.rings.number_field - sage: P = polytopes.cube()*sqrt2 # optional - sage.rings.number_field - sage: M = matrix([[sqrt3, 0, 0], [0, sqrt3, 0], [0, 0, 1]]) # optional - sage.rings.number_field - sage: P.linear_transformation(M, new_base_ring=K.composite_fields(L)[0]) # optional - sage.rings.number_field - A 3-dimensional polyhedron in (Number Field in sqrt2sqrt3 with defining polynomial x^4 - 10*x^2 + 1 with sqrt2sqrt3 = 0.3178372451957823?)^3 defined as the convex hull of 8 vertices + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: L. = QuadraticField(3) # optional - sage.rings.number_field + sage: P = polytopes.cube()*sqrt2 # optional - sage.rings.number_field + sage: M = matrix([[sqrt3, 0, 0], [0, sqrt3, 0], [0, 0, 1]]) # optional - sage.rings.number_field + sage: P.linear_transformation(M, new_base_ring=K.composite_fields(L)[0]) # optional - sage.rings.number_field + A 3-dimensional polyhedron in + (Number Field in sqrt2sqrt3 with defining polynomial x^4 - 10*x^2 + 1 + with sqrt2sqrt3 = 0.3178372451957823?)^3 + defined as the convex hull of 8 vertices Linear transformation without specified new base ring fails in this case:: - sage: M*P # optional - sage.rings.number_field + sage: M*P # optional - sage.rings.number_field Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 3 by 3 dense matrices over Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878?' and 'Full MatrixSpace of 3 by 8 dense matrices over Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095?' + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 3 by 3 dense matrices over Number Field in sqrt3 + with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878?' and + 'Full MatrixSpace of 3 by 8 dense matrices over Number Field in sqrt2 + with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095?' TESTS: @@ -1749,7 +1760,7 @@ def linear_transformation(self, linear_transf, new_base_ring=None): A 3-dimensional polyhedron in RDF^4 defined as the convex hull of 5 vertices sage: (1/1 * proj_mat) * b3 A 3-dimensional polyhedron in QQ^4 defined as the convex hull of 5 vertices - sage: (AA(2).sqrt() * proj_mat) * b3 # optional - sage.rings.number_field + sage: (AA(2).sqrt() * proj_mat) * b3 # optional - sage.rings.number_field A 3-dimensional polyhedron in AA^4 defined as the convex hull of 5 vertices Check that zero-matrices act correctly:: @@ -1763,13 +1774,17 @@ def linear_transformation(self, linear_transf, new_base_ring=None): sage: Matrix([[0 for _ in range(8)]]) * b3 Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 1 by 8 dense matrices over Integer Ring' and 'Full MatrixSpace of 9 by 6 dense matrices over Integer Ring' + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 1 by 8 dense matrices over Integer Ring' and + 'Full MatrixSpace of 9 by 6 dense matrices over Integer Ring' sage: Matrix(ZZ, []) * b3 A 0-dimensional polyhedron in ZZ^0 defined as the convex hull of 1 vertex sage: Matrix(ZZ, [[],[]]) * b3 Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 0 dense matrices over Integer Ring' and 'Full MatrixSpace of 9 by 6 dense matrices over Integer Ring' + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 0 dense matrices over Integer Ring' and + 'Full MatrixSpace of 9 by 6 dense matrices over Integer Ring' Check that the precomputed double description is correct:: @@ -1944,7 +1959,7 @@ def face_truncation(self, face, linear_coefficients=None, cut_frac=None): A vertex at (-1, -1/3, -1), A vertex at (-1/3, -1, -1), A vertex at (-1, -1, -1/3)) - sage: vertex_trunc2 = Cube.face_truncation(Cube.faces(0)[0],cut_frac=1/2) + sage: vertex_trunc2 = Cube.face_truncation(Cube.faces(0)[0], cut_frac=1/2) sage: vertex_trunc2.f_vector() (1, 10, 15, 7, 1) sage: tuple(f.ambient_V_indices() for f in vertex_trunc2.faces(2)) @@ -1966,7 +1981,7 @@ def face_truncation(self, face, linear_coefficients=None, cut_frac=None): A vertex at (-1, 0, -1), A vertex at (0, -1, -1), A vertex at (-1, -1, 0)) - sage: vertex_trunc3 = Cube.face_truncation(Cube.faces(0)[0],cut_frac=0.3) + sage: vertex_trunc3 = Cube.face_truncation(Cube.faces(0)[0], cut_frac=0.3) sage: vertex_trunc3.vertices() (A vertex at (-1.0, -1.0, 1.0), A vertex at (-1.0, 1.0, -1.0), @@ -1999,7 +2014,7 @@ def face_truncation(self, face, linear_coefficients=None, cut_frac=None): A vertex at (-1/3, 1, 1), A vertex at (-1/3, 1, -1), A vertex at (-1/3, -1, -1)) - sage: face_trunc.face_lattice().is_isomorphic(Cube.face_lattice()) # optional - sage.combinat + sage: face_trunc.face_lattice().is_isomorphic(Cube.face_lattice()) # optional - sage.combinat sage.graphs True TESTS: @@ -2093,20 +2108,20 @@ def stack(self, face, position=None): ... ValueError: cannot stack onto a vertex - sage: stacked_square_half = cube.stack(square_face,position=1/2) + sage: stacked_square_half = cube.stack(square_face, position=1/2) sage: stacked_square_half.f_vector() (1, 9, 16, 9, 1) - sage: stacked_square_large = cube.stack(square_face,position=10) + sage: stacked_square_large = cube.stack(square_face, position=10) - sage: hexaprism = polytopes.regular_polygon(6).prism() # optional - sage.rings.number_field - sage: hexaprism.f_vector() # optional - sage.rings.number_field + sage: hexaprism = polytopes.regular_polygon(6).prism() # optional - sage.rings.number_field + sage: hexaprism.f_vector() # optional - sage.rings.number_field (1, 12, 18, 8, 1) - sage: square_face = hexaprism.faces(2)[2] # optional - sage.rings.number_field - sage: stacked_hexaprism = hexaprism.stack(square_face) # optional - sage.rings.number_field - sage: stacked_hexaprism.f_vector() # optional - sage.rings.number_field + sage: square_face = hexaprism.faces(2)[2] # optional - sage.rings.number_field + sage: stacked_hexaprism = hexaprism.stack(square_face) # optional - sage.rings.number_field + sage: stacked_hexaprism.f_vector() # optional - sage.rings.number_field (1, 13, 22, 11, 1) - sage: hexaprism.stack(square_face,position=4) # optional - sage.rings.number_field + sage: hexaprism.stack(square_face, position=4) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: the chosen position is too large @@ -2128,7 +2143,7 @@ def stack(self, face, position=None): It is possible to stack on unbounded faces:: - sage: Q = Polyhedron(vertices=[[0,1],[1,0]],rays=[[1,1]]) + sage: Q = Polyhedron(vertices=[[0,1], [1,0]], rays=[[1,1]]) sage: E = Q.faces(1) sage: Q.stack(E[0],1/2).Vrepresentation() (A vertex at (0, 1), @@ -2226,17 +2241,17 @@ def wedge(self, face, width=1): EXAMPLES:: - sage: P_4 = polytopes.regular_polygon(4) # optional - sage.rings.number_field - sage: W1 = P_4.wedge(P_4.faces(1)[0]); W1 # optional - sage.rings.number_field + sage: P_4 = polytopes.regular_polygon(4) # optional - sage.rings.number_field + sage: W1 = P_4.wedge(P_4.faces(1)[0]); W1 # optional - sage.rings.number_field A 3-dimensional polyhedron in AA^3 defined as the convex hull of 6 vertices - sage: triangular_prism = polytopes.regular_polygon(3).prism() # optional - sage.rings.number_field - sage: W1.is_combinatorially_isomorphic(triangular_prism) # optional - sage.graphs # optional - sage.rings.number_field + sage: triangular_prism = polytopes.regular_polygon(3).prism() # optional - sage.rings.number_field + sage: W1.is_combinatorially_isomorphic(triangular_prism) # optional - sage.graphs sage.rings.number_field True - sage: Q = polytopes.hypersimplex(4,2) # optional - sage.combinat - sage: W2 = Q.wedge(Q.faces(2)[7]); W2 # optional - sage.combinat + sage: Q = polytopes.hypersimplex(4,2) # optional - sage.combinat + sage: W2 = Q.wedge(Q.faces(2)[7]); W2 # optional - sage.combinat A 4-dimensional polyhedron in QQ^5 defined as the convex hull of 9 vertices - sage: W2.vertices() # optional - sage.combinat + sage: W2.vertices() # optional - sage.combinat (A vertex at (1, 1, 0, 0, 1), A vertex at (1, 1, 0, 0, -1), A vertex at (1, 0, 1, 0, 1), @@ -2247,9 +2262,9 @@ def wedge(self, face, width=1): A vertex at (0, 1, 1, 0, 0), A vertex at (0, 1, 0, 1, 0)) - sage: W3 = Q.wedge(Q.faces(1)[11]); W3 # optional - sage.combinat + sage: W3 = Q.wedge(Q.faces(1)[11]); W3 # optional - sage.combinat A 4-dimensional polyhedron in QQ^5 defined as the convex hull of 10 vertices - sage: W3.vertices() # optional - sage.combinat + sage: W3.vertices() # optional - sage.combinat (A vertex at (1, 1, 0, 0, -2), A vertex at (1, 1, 0, 0, 2), A vertex at (1, 0, 1, 0, -2), @@ -2262,9 +2277,9 @@ def wedge(self, face, width=1): A vertex at (0, 1, 1, 0, -1)) sage: C_3_7 = polytopes.cyclic_polytope(3,7) - sage: P_6 = polytopes.regular_polygon(6) # optional - sage.rings.number_field - sage: W4 = P_6.wedge(P_6.faces(1)[0]) # optional - sage.rings.number_field - sage: W4.is_combinatorially_isomorphic(C_3_7.polar()) # optional - sage.graphs # optional - sage.rings.number_field + sage: P_6 = polytopes.regular_polygon(6) # optional - sage.rings.number_field + sage: W4 = P_6.wedge(P_6.faces(1)[0]) # optional - sage.rings.number_field + sage: W4.is_combinatorially_isomorphic(C_3_7.polar()) # optional - sage.graphs sage.rings.number_field True REFERENCES: @@ -2348,10 +2363,10 @@ def face_split(self, face): EXAMPLES:: - sage: pentagon = polytopes.regular_polygon(5) # optional - sage.rings.number_field - sage: f = pentagon.faces(1)[0] # optional - sage.rings.number_field - sage: fsplit_pentagon = pentagon.face_split(f) # optional - sage.rings.number_field - sage: fsplit_pentagon.f_vector() # optional - sage.rings.number_field + sage: pentagon = polytopes.regular_polygon(5) # optional - sage.rings.number_field + sage: f = pentagon.faces(1)[0] # optional - sage.rings.number_field + sage: fsplit_pentagon = pentagon.face_split(f) # optional - sage.rings.number_field + sage: fsplit_pentagon.f_vector() # optional - sage.rings.number_field (1, 7, 14, 9, 1) TESTS: @@ -2435,7 +2450,7 @@ def _test_lawrence(self, tester=None, **options): Check that :trac:`28725` is fixed:: - sage: polytopes.regular_polygon(3)._test_lawrence() # optional - sage.rings.number_field + sage: polytopes.regular_polygon(3)._test_lawrence() # optional - sage.rings.number_field Check that :trac:`30293` is fixed:: @@ -2544,10 +2559,10 @@ def one_point_suspension(self, vertex): sage: ops_cube.f_vector() (1, 9, 24, 24, 9, 1) - sage: pentagon = polytopes.regular_polygon(5) # optional - sage.rings.number_field - sage: v = pentagon.vertices()[0] # optional - sage.rings.number_field - sage: ops_pentagon = pentagon.one_point_suspension(v) # optional - sage.rings.number_field - sage: ops_pentagon.f_vector() # optional - sage.rings.number_field + sage: pentagon = polytopes.regular_polygon(5) # optional - sage.rings.number_field + sage: v = pentagon.vertices()[0] # optional - sage.rings.number_field + sage: ops_pentagon = pentagon.one_point_suspension(v) # optional - sage.rings.number_field + sage: ops_pentagon.f_vector() # optional - sage.rings.number_field (1, 6, 12, 8, 1) It works with a polyhedral face as well:: @@ -2567,7 +2582,9 @@ def one_point_suspension(self, vertex): sage: cube.one_point_suspension(e) Traceback (most recent call last): ... - TypeError: the vertex A 1-dimensional face of a Polyhedron in ZZ^3 defined as the convex hull of 2 vertices should be a Vertex or PolyhedronFace of dimension 0 + TypeError: the vertex + A 1-dimensional face of a Polyhedron in ZZ^3 defined as the convex hull of 2 vertices + should be a Vertex or PolyhedronFace of dimension 0 """ from sage.geometry.polyhedron.representation import Vertex from sage.geometry.polyhedron.face import PolyhedronFace diff --git a/src/sage/geometry/polyhedron/base6.py b/src/sage/geometry/polyhedron/base6.py index 35571185548..e125b5228a0 100644 --- a/src/sage/geometry/polyhedron/base6.py +++ b/src/sage/geometry/polyhedron/base6.py @@ -45,9 +45,9 @@ class Polyhedron_base6(Polyhedron_base5): sage: from sage.geometry.polyhedron.base6 import Polyhedron_base6 sage: P = polytopes.cube() - sage: Polyhedron_base6.plot(P) # optional - sage.plot + sage: Polyhedron_base6.plot(P) # optional - sage.plot Graphics3d Object - sage: print(Polyhedron_base6.tikz(P, output_type='TikzPicture')) # optional - sage.plot + sage: print(Polyhedron_base6.tikz(P, output_type='TikzPicture')) # optional - sage.plot \RequirePackage{luatex85} \documentclass[tikz]{standalone} \begin{document} @@ -130,7 +130,7 @@ class Polyhedron_base6(Polyhedron_base5): \end{document} sage: Q = polytopes.hypercube(4) - sage: Polyhedron_base6.show(Q) # optional - sage.plot + sage: Polyhedron_base6.show(Q) # optional - sage.plot sage: Polyhedron_base6.schlegel_projection(Q) The projection of a polyhedron into 3 dimensions @@ -194,82 +194,84 @@ def plot(self, By default, the wireframe is rendered in blue and the fill in green:: - sage: square.plot() # optional - sage.plot + sage: square.plot() # optional - sage.plot Graphics object consisting of 6 graphics primitives - sage: point.plot() # optional - sage.plot + sage: point.plot() # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: line.plot() # optional - sage.plot + sage: line.plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives - sage: cube.plot() # optional - sage.plot + sage: cube.plot() # optional - sage.plot Graphics3d Object - sage: hypercube.plot() # optional - sage.plot + sage: hypercube.plot() # optional - sage.plot Graphics3d Object Draw the lines in red and nothing else:: - sage: square.plot(point=False, line='red', polygon=False) # optional - sage.plot + sage: square.plot(point=False, line='red', polygon=False) # optional - sage.plot Graphics object consisting of 4 graphics primitives - sage: point.plot(point=False, line='red', polygon=False) # optional - sage.plot + sage: point.plot(point=False, line='red', polygon=False) # optional - sage.plot Graphics object consisting of 0 graphics primitives - sage: line.plot(point=False, line='red', polygon=False) # optional - sage.plot + sage: line.plot(point=False, line='red', polygon=False) # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: cube.plot(point=False, line='red', polygon=False) # optional - sage.plot + sage: cube.plot(point=False, line='red', polygon=False) # optional - sage.plot Graphics3d Object - sage: hypercube.plot(point=False, line='red', polygon=False) # optional - sage.plot + sage: hypercube.plot(point=False, line='red', polygon=False) # optional - sage.plot Graphics3d Object Draw points in red, no lines, and a blue polygon:: - sage: square.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot + sage: square.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot Graphics object consisting of 2 graphics primitives - sage: point.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot + sage: point.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: line.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot + sage: line.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: cube.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot + sage: cube.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot Graphics3d Object - sage: hypercube.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot + sage: hypercube.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot Graphics3d Object If we instead use the ``fill`` and ``wireframe`` options, the coloring depends on the dimension of the object:: - sage: square.plot(fill='green', wireframe='red') # optional - sage.plot + sage: square.plot(fill='green', wireframe='red') # optional - sage.plot Graphics object consisting of 6 graphics primitives - sage: point.plot(fill='green', wireframe='red') # optional - sage.plot + sage: point.plot(fill='green', wireframe='red') # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: line.plot(fill='green', wireframe='red') # optional - sage.plot + sage: line.plot(fill='green', wireframe='red') # optional - sage.plot Graphics object consisting of 2 graphics primitives - sage: cube.plot(fill='green', wireframe='red') # optional - sage.plot + sage: cube.plot(fill='green', wireframe='red') # optional - sage.plot Graphics3d Object - sage: hypercube.plot(fill='green', wireframe='red') # optional - sage.plot + sage: hypercube.plot(fill='green', wireframe='red') # optional - sage.plot Graphics3d Object It is possible to draw polyhedra up to dimension 4, no matter what the ambient dimension is:: sage: hcube = polytopes.hypercube(5) - sage: facet = hcube.facets()[0].as_polyhedron();facet + sage: facet = hcube.facets()[0].as_polyhedron(); facet A 4-dimensional polyhedron in ZZ^5 defined as the convex hull of 16 vertices - sage: facet.plot() # optional - sage.plot + sage: facet.plot() # optional - sage.plot Graphics3d Object For a 3d plot, we may draw the polygons with rainbow colors, using any of the following ways:: - sage: cube.plot(polygon='rainbow') # optional - sage.plot + sage: cube.plot(polygon='rainbow') # optional - sage.plot Graphics3d Object - sage: cube.plot(polygon={'color':'rainbow'}) # optional - sage.plot + sage: cube.plot(polygon={'color':'rainbow'}) # optional - sage.plot Graphics3d Object - sage: cube.plot(fill='rainbow') # optional - sage.plot + sage: cube.plot(fill='rainbow') # optional - sage.plot Graphics3d Object For a 3d plot, the size of a point, the thickness of a line and the width of an arrow are controlled by the respective parameters:: sage: prism = Polyhedron(vertices=[[0,0,0],[1,0,0],[0,1,0]], rays=[[0,0,1]]) - sage: prism.plot(size=20, thickness=30, width=1) # optional - sage.plot + sage: prism.plot(size=20, thickness=30, width=1) # optional - sage.plot Graphics3d Object - sage: prism.plot(point={'size':20, 'color':'black'}, line={'thickness':30, 'width':1, 'color':'black'}, polygon='rainbow') # optional - sage.plot + sage: prism.plot(point={'size':20, 'color':'black'}, # optional - sage.plot + ....: line={'thickness':30, 'width':1, 'color':'black'}, + ....: polygon='rainbow') Graphics3d Object TESTS:: @@ -470,7 +472,7 @@ def show(self, **kwds): EXAMPLES:: sage: square = polytopes.hypercube(2) - sage: square.show(point='red') # optional - sage.plot + sage: square.show(point='red') # optional - sage.plot """ self.plot(**kwds).show() @@ -545,8 +547,8 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, EXAMPLES:: sage: co = polytopes.cuboctahedron() - sage: Img = co.tikz([0, 0, 1], 0, output_type='TikzPicture') # optional - sage.plot - sage: Img # optional - sage.plot + sage: Img = co.tikz([0, 0, 1], 0, output_type='TikzPicture') # optional - sage.plot + sage: Img # optional - sage.plot \documentclass[tikz]{standalone} \begin{document} \begin{tikzpicture}% @@ -563,7 +565,7 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, %% \end{tikzpicture} \end{document} - sage: print('\n'.join(Img.content().splitlines()[12:21])) # optional - sage.plot + sage: print('\n'.join(Img.content().splitlines()[12:21])) # optional - sage.plot %% with the command: ._tikz_3d_in_3d and parameters: %% view = [0, 0, 1] %% angle = 0 @@ -573,7 +575,7 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, %% opacity = 0.8 %% vertex_color = green %% axis = False - sage: print('\n'.join(Img.content().splitlines()[22:26])) # optional - sage.plot + sage: print('\n'.join(Img.content().splitlines()[22:26])) # optional - sage.plot %% Coordinate of the vertices: %% \coordinate (-1.00000, -1.00000, 0.00000) at (-1.00000, -1.00000, 0.00000); @@ -582,8 +584,8 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, When output type is a :class:`sage.misc.latex_standalone.TikzPicture`:: sage: co = polytopes.cuboctahedron() - sage: t = co.tikz([674, 108, -731], 112, output_type='TikzPicture') # optional - sage.plot - sage: t # optional - sage.plot + sage: t = co.tikz([674, 108, -731], 112, output_type='TikzPicture') # optional - sage.plot + sage: t # optional - sage.plot \documentclass[tikz]{standalone} \begin{document} \begin{tikzpicture}% @@ -600,7 +602,7 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, %% \end{tikzpicture} \end{document} - sage: path_to_file = t.pdf() # not tested # optional - sage.plot + sage: path_to_file = t.pdf() # not tested # optional - sage.plot """ return self.projection().tikz(view, angle, scale, @@ -692,8 +694,8 @@ def gale_transform(self): Check that :trac:`29073` is fixed:: - sage: P = polytopes.icosahedron(exact=False) # optional - sage.groups - sage: sum(P.gale_transform()).norm() < 1e-15 # optional - sage.groups + sage: P = polytopes.icosahedron(exact=False) # optional - sage.groups + sage: sum(P.gale_transform()).norm() < 1e-15 # optional - sage.groups True """ if not self.is_compact(): @@ -784,8 +786,8 @@ def render_solid(self, **kwds): EXAMPLES:: sage: p = polytopes.hypercube(3) - sage: p_solid = p.render_solid(opacity=.7) # optional - sage.plot - sage: type(p_solid) # optional - sage.plot + sage: p_solid = p.render_solid(opacity=.7) # optional - sage.plot + sage: type(p_solid) # optional - sage.plot """ proj = self.projection() @@ -803,8 +805,8 @@ def render_wireframe(self, **kwds): EXAMPLES:: sage: p = Polyhedron([[1,2,],[1,1],[0,0]]) - sage: p_wireframe = p.render_wireframe() # optional - sage.plot - sage: p_wireframe._objects # optional - sage.plot + sage: p_wireframe = p.render_wireframe() # optional - sage.plot + sage: p_wireframe._objects # optional - sage.plot [Line defined by 2 points, Line defined by 2 points, Line defined by 2 points] """ proj = self.projection() @@ -853,30 +855,30 @@ def schlegel_projection(self, facet=None, position=None): sage: tfcube.facets()[-1] A 3-dimensional face of a Polyhedron in QQ^4 defined as the convex hull of 8 vertices sage: sp = tfcube.schlegel_projection(tfcube.facets()[-1]) - sage: sp.plot() # optional - sage.plot + sage: sp.plot() # optional - sage.plot Graphics3d Object The same truncated cube but see inside the tetrahedral facet:: sage: tfcube.facets()[4] A 3-dimensional face of a Polyhedron in QQ^4 defined as the convex hull of 4 vertices - sage: sp = tfcube.schlegel_projection(tfcube.facets()[4]) # optional - sage.symbolic - sage: sp.plot() # optional - sage.plot # optional - sage.symbolic + sage: sp = tfcube.schlegel_projection(tfcube.facets()[4]) # optional - sage.symbolic + sage: sp.plot() # optional - sage.plot sage.symbolic Graphics3d Object A different values of ``position`` changes the projection:: - sage: sp = tfcube.schlegel_projection(tfcube.facets()[4], 1/2) # optional - sage.symbolic - sage: sp.plot() # optional - sage.plot # optional - sage.symbolic + sage: sp = tfcube.schlegel_projection(tfcube.facets()[4], 1/2) # optional - sage.symbolic + sage: sp.plot() # optional - sage.plot sage.symbolic Graphics3d Object - sage: sp = tfcube.schlegel_projection(tfcube.facets()[4], 4) # optional - sage.symbolic - sage: sp.plot() # optional - sage.plot # optional - sage.symbolic + sage: sp = tfcube.schlegel_projection(tfcube.facets()[4], 4) # optional - sage.symbolic + sage: sp.plot() # optional - sage.plot sage.symbolic Graphics3d Object A value which is too large give a projection point that sees more than one facet resulting in a error:: - sage: sp = tfcube.schlegel_projection(tfcube.facets()[4],5) + sage: sp = tfcube.schlegel_projection(tfcube.facets()[4], 5) Traceback (most recent call last): ... ValueError: the chosen position is too large @@ -936,10 +938,11 @@ def _affine_hull_projection(self, *, Check that :trac:`24047` is fixed:: - sage: P1 = Polyhedron(vertices=([[-1, 1], [0, -1], [0, 0], [-1, -1]])) + sage: P1 = Polyhedron(vertices=[[-1, 1], [0, -1], [0, 0], [-1, -1]]) sage: P2 = Polyhedron(vertices=[[1, 1], [1, -1], [0, -1], [0, 0]]) sage: P = P1.intersection(P2) - sage: A, b = P.affine_hull_projection(as_affine_map=True, orthonormal=True, extend=True) # optional - sage.rings.number_field + sage: A, b = P.affine_hull_projection(as_affine_map=True, # optional - sage.rings.number_field + ....: orthonormal=True, extend=True) sage: Polyhedron([(2,3,4)]).affine_hull_projection() A 0-dimensional polyhedron in ZZ^0 defined as the convex hull of 1 vertex @@ -950,27 +953,26 @@ def _affine_hull_projection(self, *, 'field' sage: P = Polyhedron(vertices=[[0,0], [1,0]], backend='field') - sage: P.affine_hull_projection(orthogonal=True, orthonormal=True, extend=True).backend() # optional - sage.rings.number_field + sage: P.affine_hull_projection(orthogonal=True, orthonormal=True, # optional - sage.rings.number_field + ....: extend=True).backend() 'field' Check that :trac:`29116` is fixed:: - sage: V =[ - ....: [1, 0, -1, 0, 0], - ....: [1, 0, 0, -1, 0], - ....: [1, 0, 0, 0, -1], - ....: [1, 0, 0, +1, 0], - ....: [1, 0, 0, 0, +1], - ....: [1, +1, 0, 0, 0] - ....: ] + sage: V = [[1, 0, -1, 0, 0], + ....: [1, 0, 0, -1, 0], + ....: [1, 0, 0, 0, -1], + ....: [1, 0, 0, +1, 0], + ....: [1, 0, 0, 0, +1], + ....: [1, +1, 0, 0, 0]] sage: P = Polyhedron(V) sage: P.affine_hull_projection() A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 6 vertices - sage: P.affine_hull_projection(orthonormal=True) # optional - sage.symbolic + sage: P.affine_hull_projection(orthonormal=True) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: the base ring needs to be extended; try with "extend=True" - sage: P.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field + sage: P.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field A 4-dimensional polyhedron in AA^4 defined as the convex hull of 6 vertices """ result = AffineHullProjectionData() @@ -1176,7 +1178,7 @@ def affine_hull_projection(self, The resulting affine hulls depend on the parameter ``orthogonal`` and ``orthonormal``:: - sage: L = Polyhedron([[1,0],[0,1]]); L + sage: L = Polyhedron([[1,0], [0,1]]); L A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices sage: A = L.affine_hull_projection(); A A 1-dimensional polyhedron in ZZ^1 defined as the convex hull of 2 vertices @@ -1186,13 +1188,13 @@ def affine_hull_projection(self, A 1-dimensional polyhedron in QQ^1 defined as the convex hull of 2 vertices sage: A.vertices() (A vertex at (0), A vertex at (2)) - sage: A = L.affine_hull_projection(orthonormal=True) # optional - sage.rings.number_field + sage: A = L.affine_hull_projection(orthonormal=True) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: the base ring needs to be extended; try with "extend=True" - sage: A = L.affine_hull_projection(orthonormal=True, extend=True); A # optional - sage.rings.number_field + sage: A = L.affine_hull_projection(orthonormal=True, extend=True); A # optional - sage.rings.number_field A 1-dimensional polyhedron in AA^1 defined as the convex hull of 2 vertices - sage: A.vertices() # optional - sage.rings.number_field + sage: A.vertices() # optional - sage.rings.number_field (A vertex at (1.414213562373095?), A vertex at (0.?e-18)) More generally:: @@ -1218,9 +1220,9 @@ def affine_hull_projection(self, A vertex at (2, 0, 0), A vertex at (1, 3/2, 0), A vertex at (1, 1/2, 4/3)) - sage: A = S.affine_hull_projection(orthonormal=True, extend=True); A # optional - sage.rings.number_field + sage: A = S.affine_hull_projection(orthonormal=True, extend=True); A # optional - sage.rings.number_field A 3-dimensional polyhedron in AA^3 defined as the convex hull of 4 vertices - sage: A.vertices() # optional - sage.rings.number_field + sage: A.vertices() # optional - sage.rings.number_field (A vertex at (0.7071067811865475?, 0.4082482904638630?, 1.154700538379252?), A vertex at (0.7071067811865475?, 1.224744871391589?, 0.?e-18), A vertex at (1.414213562373095?, 0.?e-18, 0.?e-18), @@ -1229,81 +1231,102 @@ def affine_hull_projection(self, With the parameter ``minimal`` one can get a minimal base ring:: sage: s = polytopes.simplex(3) - sage: s_AA = s.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field - sage: s_AA.base_ring() # optional - sage.rings.number_field + sage: s_AA = s.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field + sage: s_AA.base_ring() # optional - sage.rings.number_field Algebraic Real Field - sage: s_full = s.affine_hull_projection(orthonormal=True, extend=True, minimal=True) # optional - sage.rings.number_field - sage: s_full.base_ring() # optional - sage.rings.number_field - Number Field in a with defining polynomial y^4 - 4*y^2 + 1 with a = 0.5176380902050415? + sage: s_full = s.affine_hull_projection(orthonormal=True, extend=True, # optional - sage.rings.number_field + ....: minimal=True) + sage: s_full.base_ring() # optional - sage.rings.number_field + Number Field in a with defining polynomial y^4 - 4*y^2 + 1 + with a = 0.5176380902050415? More examples with the ``orthonormal`` parameter:: - sage: P = polytopes.permutahedron(3); P # optional - sage.combinat # optional - sage.rings.number_field + sage: P = polytopes.permutahedron(3); P # optional - sage.combinat sage.rings.number_field A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 6 vertices - sage: set([F.as_polyhedron().affine_hull_projection(orthonormal=True, extend=True).volume() for F in P.affine_hull_projection().faces(1)]) == {1, sqrt(AA(2))} # optional - sage.combinat # optional - sage.rings.number_field + sage: set([F.as_polyhedron().affine_hull_projection( # optional - sage.combinat sage.rings.number_field + ....: orthonormal=True, extend=True).volume() + ....: for F in P.affine_hull_projection().faces(1)]) == {1, sqrt(AA(2))} True - sage: set([F.as_polyhedron().affine_hull_projection(orthonormal=True, extend=True).volume() for F in P.affine_hull_projection(orthonormal=True, extend=True).faces(1)]) == {sqrt(AA(2))} # optional - sage.combinat # optional - sage.rings.number_field + sage: set([F.as_polyhedron().affine_hull_projection( # optional - sage.combinat sage.rings.number_field + ....: orthonormal=True, extend=True).volume() + ....: for F in P.affine_hull_projection( + ....: orthonormal=True, extend=True).faces(1)]) == {sqrt(AA(2))} True - sage: D = polytopes.dodecahedron() # optional - sage.rings.number_field - sage: F = D.faces(2)[0].as_polyhedron() # optional - sage.rings.number_field - sage: F.affine_hull_projection(orthogonal=True) # optional - sage.rings.number_field - A 2-dimensional polyhedron in (Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?)^2 defined as the convex hull of 5 vertices - sage: F.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field + sage: D = polytopes.dodecahedron() # optional - sage.rings.number_field + sage: F = D.faces(2)[0].as_polyhedron() # optional - sage.rings.number_field + sage: F.affine_hull_projection(orthogonal=True) # optional - sage.rings.number_field + A 2-dimensional polyhedron in + (Number Field in sqrt5 with defining polynomial x^2 - 5 + with sqrt5 = 2.236067977499790?)^2 + defined as the convex hull of 5 vertices + sage: F.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field A 2-dimensional polyhedron in AA^2 defined as the convex hull of 5 vertices - sage: K. = QuadraticField(2) # optional - sage.rings.number_field - sage: P = Polyhedron([2*[K.zero()],2*[sqrt2]]); P # optional - sage.rings.number_field - A 1-dimensional polyhedron in (Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095?)^2 defined as the convex hull of 2 vertices - sage: P.vertices() # optional - sage.rings.number_field + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: P = Polyhedron([2*[K.zero()],2*[sqrt2]]); P # optional - sage.rings.number_field + A 1-dimensional polyhedron in + (Number Field in sqrt2 with defining polynomial x^2 - 2 + with sqrt2 = 1.414213562373095?)^2 + defined as the convex hull of 2 vertices + sage: P.vertices() # optional - sage.rings.number_field (A vertex at (0, 0), A vertex at (sqrt2, sqrt2)) - sage: A = P.affine_hull_projection(orthonormal=True); A # optional - sage.rings.number_field - A 1-dimensional polyhedron in (Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095?)^1 defined as the convex hull of 2 vertices - sage: A.vertices() # optional - sage.rings.number_field + sage: A = P.affine_hull_projection(orthonormal=True); A # optional - sage.rings.number_field + A 1-dimensional polyhedron in + (Number Field in sqrt2 with defining polynomial x^2 - 2 + with sqrt2 = 1.414213562373095?)^1 + defined as the convex hull of 2 vertices + sage: A.vertices() # optional - sage.rings.number_field (A vertex at (0), A vertex at (2)) - sage: K. = QuadraticField(3) # optional - sage.rings.number_field - sage: P = Polyhedron([2*[K.zero()],2*[sqrt3]]); P # optional - sage.rings.number_field - A 1-dimensional polyhedron in (Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878?)^2 defined as the convex hull of 2 vertices - sage: P.vertices() # optional - sage.rings.number_field + sage: K. = QuadraticField(3) # optional - sage.rings.number_field + sage: P = Polyhedron([2*[K.zero()], 2*[sqrt3]]); P # optional - sage.rings.number_field + A 1-dimensional polyhedron in + (Number Field in sqrt3 with defining polynomial x^2 - 3 + with sqrt3 = 1.732050807568878?)^2 + defined as the convex hull of 2 vertices + sage: P.vertices() # optional - sage.rings.number_field (A vertex at (0, 0), A vertex at (sqrt3, sqrt3)) - sage: A = P.affine_hull_projection(orthonormal=True) # optional - sage.rings.number_field + sage: A = P.affine_hull_projection(orthonormal=True) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: the base ring needs to be extended; try with "extend=True" - sage: A = P.affine_hull_projection(orthonormal=True, extend=True); A # optional - sage.rings.number_field + sage: A = P.affine_hull_projection(orthonormal=True, extend=True); A # optional - sage.rings.number_field A 1-dimensional polyhedron in AA^1 defined as the convex hull of 2 vertices - sage: A.vertices() # optional - sage.rings.number_field + sage: A.vertices() # optional - sage.rings.number_field (A vertex at (0), A vertex at (2.449489742783178?)) - sage: sqrt(6).n() # optional - sage.rings.number_field + sage: sqrt(6).n() # optional - sage.rings.number_field 2.44948974278318 The affine hull is combinatorially equivalent to the input:: - sage: P.is_combinatorially_isomorphic(P.affine_hull_projection()) # optional - sage.rings.number_field + sage: P.is_combinatorially_isomorphic(P.affine_hull_projection()) # optional - sage.rings.number_field True - sage: P.is_combinatorially_isomorphic(P.affine_hull_projection(orthogonal=True)) # optional - sage.rings.number_field + sage: P.is_combinatorially_isomorphic(P.affine_hull_projection( # optional - sage.rings.number_field + ....: orthogonal=True)) True - sage: P.is_combinatorially_isomorphic(P.affine_hull_projection(orthonormal=True, extend=True)) # optional - sage.rings.number_field + sage: P.is_combinatorially_isomorphic(P.affine_hull_projection( # optional - sage.rings.number_field + ....: orthonormal=True, extend=True)) True The ``orthonormal=True`` parameter preserves volumes; it provides an isometric copy of the polyhedron:: - sage: Pentagon = polytopes.dodecahedron().faces(2)[0].as_polyhedron() # optional - sage.rings.number_field - sage: P = Pentagon.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field - sage: _, c= P.is_inscribed(certificate=True) # optional - sage.rings.number_field - sage: c # optional - sage.rings.number_field + sage: Pentagon = polytopes.dodecahedron().faces(2)[0].as_polyhedron() # optional - sage.rings.number_field + sage: P = Pentagon.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field + sage: _, c= P.is_inscribed(certificate=True) # optional - sage.rings.number_field + sage: c # optional - sage.rings.number_field (0.4721359549995794?, 0.6498393924658126?) - sage: circumradius = (c-vector(P.vertices()[0])).norm() # optional - sage.rings.number_field - sage: p = polytopes.regular_polygon(5) # optional - sage.rings.number_field - sage: p.volume() # optional - sage.rings.number_field + sage: circumradius = (c - vector(P.vertices()[0])).norm() # optional - sage.rings.number_field + sage: p = polytopes.regular_polygon(5) # optional - sage.rings.number_field + sage: p.volume() # optional - sage.rings.number_field 2.377641290737884? - sage: P.volume() # optional - sage.rings.number_field + sage: P.volume() # optional - sage.rings.number_field 1.53406271079097? - sage: p.volume()*circumradius^2 # optional - sage.rings.number_field + sage: p.volume()*circumradius^2 # optional - sage.rings.number_field 1.534062710790965? - sage: P.volume() == p.volume()*circumradius^2 # optional - sage.rings.number_field + sage: P.volume() == p.volume()*circumradius^2 # optional - sage.rings.number_field True One can also use ``orthogonal`` parameter to calculate volumes; @@ -1311,28 +1334,31 @@ def affine_hull_projection(self, by the square root of the determinant of the linear part of the affine transformation times its transpose:: - sage: Pentagon = polytopes.dodecahedron().faces(2)[0].as_polyhedron() # optional - sage.rings.number_field - sage: Pnormal = Pentagon.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field - sage: Pgonal = Pentagon.affine_hull_projection(orthogonal=True) # optional - sage.rings.number_field - sage: A, b = Pentagon.affine_hull_projection(orthogonal=True, as_affine_map=True) # optional - sage.rings.number_field - sage: Adet = (A.matrix().transpose()*A.matrix()).det() # optional - sage.rings.number_field - sage: Pnormal.volume() # optional - sage.rings.number_field + sage: Pentagon = polytopes.dodecahedron().faces(2)[0].as_polyhedron() # optional - sage.rings.number_field + sage: Pnormal = Pentagon.affine_hull_projection(orthonormal=True, # optional - sage.rings.number_field + ....: extend=True) + sage: Pgonal = Pentagon.affine_hull_projection(orthogonal=True) # optional - sage.rings.number_field + sage: A, b = Pentagon.affine_hull_projection(orthogonal=True, # optional - sage.rings.number_field + ....: as_affine_map=True) + sage: Adet = (A.matrix().transpose()*A.matrix()).det() # optional - sage.rings.number_field + sage: Pnormal.volume() # optional - sage.rings.number_field 1.53406271079097? - sage: Pgonal.volume()/Adet.sqrt(extend=True) # optional - sage.rings.number_field + sage: Pgonal.volume()/Adet.sqrt(extend=True) # optional - sage.rings.number_field -80*(55*sqrt(5) - 123)/sqrt(-6368*sqrt(5) + 14240) - sage: Pgonal.volume()/AA(Adet).sqrt().n(digits=20) # optional - sage.rings.number_field + sage: Pgonal.volume()/AA(Adet).sqrt().n(digits=20) # optional - sage.rings.number_field 1.5340627107909646813 - sage: AA(Pgonal.volume()^2) == (Pnormal.volume()^2)*AA(Adet) # optional - sage.rings.number_field + sage: AA(Pgonal.volume()^2) == (Pnormal.volume()^2)*AA(Adet) # optional - sage.rings.number_field True Another example with ``as_affine_map=True``:: - sage: P = polytopes.permutahedron(4) # optional - sage.combinat # optional - sage.rings.number_field - sage: A, b = P.affine_hull_projection(orthonormal=True, as_affine_map=True, extend=True) # optional - sage.combinat # optional - sage.rings.number_field - sage: Q = P.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.combinat # optional - sage.rings.number_field - sage: Q.center() # optional - sage.combinat # optional - sage.rings.number_field + sage: P = polytopes.permutahedron(4) # optional - sage.combinat sage.rings.number_field + sage: Q = P.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.combinat sage.rings.number_field + sage: A, b = P.affine_hull_projection(orthonormal=True, extend=True, # optional - sage.combinat sage.rings.number_field + ....: as_affine_map=True) + sage: Q.center() # optional - sage.combinat sage.rings.number_field (0.7071067811865475?, 1.224744871391589?, 1.732050807568878?) - sage: A(P.center()) + b == Q.center() # optional - sage.combinat # optional - sage.rings.number_field + sage: A(P.center()) + b == Q.center() # optional - sage.combinat sage.rings.number_field True For unbounded, non full-dimensional polyhedra, the ``orthogonal=True`` and ``orthonormal=True`` @@ -1347,11 +1373,13 @@ def affine_hull_projection(self, sage: P.affine_hull_projection(orthogonal=True) Traceback (most recent call last): ... - NotImplementedError: "orthogonal=True" and "orthonormal=True" work only for compact polyhedra + NotImplementedError: "orthogonal=True" and "orthonormal=True" + work only for compact polyhedra sage: P.affine_hull_projection(orthonormal=True) Traceback (most recent call last): ... - NotImplementedError: "orthogonal=True" and "orthonormal=True" work only for compact polyhedra + NotImplementedError: "orthogonal=True" and "orthonormal=True" + work only for compact polyhedra Setting ``as_affine_map`` to ``True`` without ``orthogonal`` or ``orthonormal`` set to ``True``:: @@ -1387,12 +1415,12 @@ def affine_hull_projection(self, ....: as_polyhedron=True, ....: as_affine_map=True); data AffineHullProjectionData(image=A 2-dimensional polyhedron in QQ^2 - defined as the convex hull of 3 vertices, + defined as the convex hull of 3 vertices, projection_linear_map=Vector space morphism represented by the matrix: [ -1 -1/2] [ 1 -1/2] [ 0 1] - Domain: Vector space of dimension 3 over Rational Field + Domain: Vector space of dimension 3 over Rational Field Codomain: Vector space of dimension 2 over Rational Field, projection_translation=(1, 1/2), section_linear_map=None, @@ -1402,42 +1430,47 @@ def affine_hull_projection(self, sage: data = S.affine_hull_projection(orthogonal=True, return_all_data=True); data AffineHullProjectionData(image=A 2-dimensional polyhedron in QQ^2 - defined as the convex hull of 3 vertices, + defined as the convex hull of 3 vertices, projection_linear_map=Vector space morphism represented by the matrix: [ -1 -1/2] [ 1 -1/2] [ 0 1] - Domain: Vector space of dimension 3 over Rational Field + Domain: Vector space of dimension 3 over Rational Field Codomain: Vector space of dimension 2 over Rational Field, projection_translation=(1, 1/2), section_linear_map=Vector space morphism represented by the matrix: [-1/2 1/2 0] [-1/3 -1/3 2/3] - Domain: Vector space of dimension 2 over Rational Field - Codomain: Vector space of dimension 3 over Rational Field, section_translation=(1, 0, 0)) + Domain: Vector space of dimension 2 over Rational Field + Codomain: Vector space of dimension 3 over Rational Field, + section_translation=(1, 0, 0)) The section map is a right inverse of the projection map:: - sage: data.image.linear_transformation(data.section_linear_map.matrix().transpose()) + data.section_translation == S + sage: mat = data.section_linear_map.matrix().transpose() + sage: data.image.linear_transformation(mat) + data.section_translation == S True Same without ``orthogonal=True``:: sage: data = S.affine_hull_projection(return_all_data=True); data AffineHullProjectionData(image=A 2-dimensional polyhedron in ZZ^2 - defined as the convex hull of 3 vertices, + defined as the convex hull of 3 vertices, projection_linear_map=Vector space morphism represented by the matrix: [1 0] [0 1] [0 0] - Domain: Vector space of dimension 3 over Rational Field - Codomain: Vector space of dimension 2 over Rational Field, projection_translation=(0, 0), + Domain: Vector space of dimension 3 over Rational Field + Codomain: Vector space of dimension 2 over Rational Field, + projection_translation=(0, 0), section_linear_map=Vector space morphism represented by the matrix: [ 1 0 -1] [ 0 1 -1] - Domain: Vector space of dimension 2 over Rational Field - Codomain: Vector space of dimension 3 over Rational Field, section_translation=(0, 0, 1)) - sage: data.image.linear_transformation(data.section_linear_map.matrix().transpose()) + data.section_translation == S + Domain: Vector space of dimension 2 over Rational Field + Codomain: Vector space of dimension 3 over Rational Field, + section_translation=(0, 0, 1)) + sage: mat = data.section_linear_map.matrix().transpose() + sage: data.image.linear_transformation(mat) + data.section_translation == S True :: @@ -1473,8 +1506,8 @@ def _test_affine_hull_projection(self, tester=None, verbose=False, **options): TESTS:: - sage: D = polytopes.dodecahedron() # optional - sage.rings.number_field - sage: D.facets()[0].as_polyhedron()._test_affine_hull_projection() # optional - sage.rings.number_field + sage: D = polytopes.dodecahedron() # optional - sage.rings.number_field + sage: D.facets()[0].as_polyhedron()._test_affine_hull_projection() # optional - sage.rings.number_field """ if tester is None: tester = self._tester(**options) @@ -1564,42 +1597,48 @@ def affine_hull_manifold(self, name=None, latex_name=None, start_index=0, ambien sage: triangle = Polyhedron([(1, 0, 0), (0, 1, 0), (0, 0, 1)]); triangle A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 3 vertices - sage: A = triangle.affine_hull_manifold(name='A'); A # optional - sage.symbolic + sage: A = triangle.affine_hull_manifold(name='A'); A # optional - sage.symbolic 2-dimensional Riemannian submanifold A embedded in the Euclidean space E^3 - sage: A.embedding().display() # optional - sage.symbolic + sage: A.embedding().display() # optional - sage.symbolic A → E^3 (x0, x1) ↦ (x, y, z) = (t0 + x0, t0 + x1, t0 - x0 - x1 + 1) - sage: A.embedding().inverse().display() # optional - sage.symbolic + sage: A.embedding().inverse().display() # optional - sage.symbolic E^3 → A (x, y, z) ↦ (x0, x1) = (x, y) - sage: A.adapted_chart() # optional - sage.symbolic + sage: A.adapted_chart() # optional - sage.symbolic [Chart (E^3, (x0_E3, x1_E3, t0_E3))] - sage: A.normal().display() # optional - sage.symbolic + sage: A.normal().display() # optional - sage.symbolic n = 1/3*sqrt(3) e_x + 1/3*sqrt(3) e_y + 1/3*sqrt(3) e_z - sage: A.induced_metric() # Need to call this before volume_form # optional - sage.symbolic - Riemannian metric gamma on the 2-dimensional Riemannian submanifold A embedded in the Euclidean space E^3 - sage: A.volume_form() # optional - sage.symbolic - 2-form eps_gamma on the 2-dimensional Riemannian submanifold A embedded in the Euclidean space E^3 + sage: A.induced_metric() # Need to call this before volume_form # optional - sage.symbolic + Riemannian metric gamma on the + 2-dimensional Riemannian submanifold A embedded in the Euclidean space E^3 + sage: A.volume_form() # optional - sage.symbolic + 2-form eps_gamma on the + 2-dimensional Riemannian submanifold A embedded in the Euclidean space E^3 Orthogonal version:: - sage: A = triangle.affine_hull_manifold(name='A', orthogonal=True); A # optional - sage.symbolic + sage: A = triangle.affine_hull_manifold(name='A', orthogonal=True); A # optional - sage.symbolic 2-dimensional Riemannian submanifold A embedded in the Euclidean space E^3 - sage: A.embedding().display() # optional - sage.symbolic + sage: A.embedding().display() # optional - sage.symbolic A → E^3 - (x0, x1) ↦ (x, y, z) = (t0 - 1/2*x0 - 1/3*x1 + 1, t0 + 1/2*x0 - 1/3*x1, t0 + 2/3*x1) - sage: A.embedding().inverse().display() # optional - sage.symbolic + (x0, x1) ↦ (x, y, z) = (t0 - 1/2*x0 - 1/3*x1 + 1, + t0 + 1/2*x0 - 1/3*x1, t0 + 2/3*x1) + sage: A.embedding().inverse().display() # optional - sage.symbolic E^3 → A (x, y, z) ↦ (x0, x1) = (-x + y + 1, -1/2*x - 1/2*y + z + 1/2) Arrangement of affine hull of facets:: - sage: D = polytopes.dodecahedron() # optional - sage.rings.number_field - sage: E3 = EuclideanSpace(3) # optional - sage.rings.number_field # optional - sage.symbolic - sage: submanifolds = [ # long time # optional - sage.rings.number_field # optional - sage.symbolic - ....: F.as_polyhedron().affine_hull_manifold(name=f'F{i}', orthogonal=True, ambient_space=E3) + sage: D = polytopes.dodecahedron() # optional - sage.rings.number_field + sage: E3 = EuclideanSpace(3) # optional - sage.rings.number_field sage.symbolic + sage: submanifolds = [ # long time # optional - sage.rings.number_field sage.symbolic + ....: F.as_polyhedron().affine_hull_manifold(name=f'F{i}', + ....: orthogonal=True, ambient_space=E3) ....: for i, F in enumerate(D.facets())] - sage: sum(FM.plot({}, srange(-2, 2, 0.1), srange(-2, 2, 0.1), opacity=0.2) # not tested # long time # optional - sage.symbolic # optional - sage.plot # optional - sage.rings.number_field + sage: sum(FM.plot({}, # not tested # long time # optional - sage.symbolic sage.plot sage.rings.number_field + ....: srange(-2, 2, 0.1), srange(-2, 2, 0.1), + ....: opacity=0.2) ....: for FM in submanifolds) + D.plot() Graphics3d Object @@ -1607,7 +1646,7 @@ def affine_hull_manifold(self, name=None, latex_name=None, start_index=0, ambien sage: cube = polytopes.cube(); cube A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices - sage: cube.affine_hull_manifold() # optional - sage.symbolic + sage: cube.affine_hull_manifold() # optional - sage.symbolic Euclidean space E^3 """ diff --git a/src/sage/geometry/polyhedron/base7.py b/src/sage/geometry/polyhedron/base7.py index 3465f22875d..ce632e1655d 100644 --- a/src/sage/geometry/polyhedron/base7.py +++ b/src/sage/geometry/polyhedron/base7.py @@ -44,15 +44,15 @@ class Polyhedron_base7(Polyhedron_base6): TESTS:: sage: from sage.geometry.polyhedron.base7 import Polyhedron_base7 - sage: P = polytopes.associahedron(['A', 3]) # optional - sage.combinat - sage: Polyhedron_base7.centroid(P) # optional - sage.combinat + sage: P = polytopes.associahedron(['A', 3]) # optional - sage.combinat + sage: Polyhedron_base7.centroid(P) # optional - sage.combinat (81/632, 36/79, 81/632) - sage: Polyhedron_base7.triangulate(P) # optional - sage.combinat + sage: Polyhedron_base7.triangulate(P) # optional - sage.combinat (<0,1,2,13>, <0,1,7,13>, <0,2,5,13>, <0,6,7,12>, <0,6,8,13>, <0,6,12,13>, <0,7,12,13>, <1,2,7,12>, <1,2,12,13>, <1,7,12,13>, <2,3,7,12>, <2,3,12,13>, <3,4,7,12>, <3,11,12,13>, <6,8,9,12>, <6,8,12,13>, <6,9,10,12>, <8,9,12,13>) - sage: Polyhedron_base7.volume(P, measure='induced') # optional - sage.combinat + sage: Polyhedron_base7.volume(P, measure='induced') # optional - sage.combinat 79/3 """ @cached_method(do_pickle=True) @@ -91,12 +91,12 @@ def centroid(self, engine='auto', **kwds): sage: P.centroid() (1/4, 0, 0) - sage: P = polytopes.associahedron(['A', 2]) # optional - sage.combinat - sage: P.centroid() # optional - sage.combinat + sage: P = polytopes.associahedron(['A', 2]) # optional - sage.combinat + sage: P.centroid() # optional - sage.combinat (2/21, 2/21) - sage: P = polytopes.permutahedron(4, backend='normaliz') # optional - pynormaliz - sage: P.centroid() # optional - pynormaliz + sage: P = polytopes.permutahedron(4, backend='normaliz') # optional - pynormaliz + sage: P.centroid() # optional - pynormaliz (5/2, 5/2, 5/2, 5/2) The method is not implemented for unbounded polyhedra:: @@ -226,12 +226,12 @@ def triangulate(self, engine='auto', connected=True, fine=False, regular=None, s sage: cube = polytopes.hypercube(3) sage: triangulation = cube.triangulate( - ....: engine='internal') # to make doctest independent of TOPCOM + ....: engine='internal') # to make doctest independent of TOPCOM sage: triangulation (<0,1,2,7>, <0,1,5,7>, <0,2,3,7>, <0,3,4,7>, <0,4,5,7>, <1,5,6,7>) sage: simplex_indices = triangulation[0]; simplex_indices (0, 1, 2, 7) - sage: simplex_vertices = [ cube.Vrepresentation(i) for i in simplex_indices ] + sage: simplex_vertices = [cube.Vrepresentation(i) for i in simplex_indices] sage: simplex_vertices [A vertex at (1, -1, -1), A vertex at (1, 1, -1), @@ -243,11 +243,14 @@ def triangulate(self, engine='auto', connected=True, fine=False, regular=None, s It is possible to use ``'normaliz'`` as an engine. For this, the polyhedron should have the backend set to normaliz:: - sage: P = Polyhedron(vertices=[[0,0,1],[1,0,1],[0,1,1],[1,1,1]],backend='normaliz') # optional - pynormaliz - sage: P.triangulate(engine='normaliz') # optional - pynormaliz + sage: P = Polyhedron(vertices=[[0,0,1], [1,0,1], # optional - pynormaliz + ....: [0,1,1], [1,1,1]], + ....: backend='normaliz') + sage: P.triangulate(engine='normaliz') # optional - pynormaliz (<0,1,2>, <1,2,3>) - sage: P = Polyhedron(vertices=[[0,0,1],[1,0,1],[0,1,1],[1,1,1]]) + sage: P = Polyhedron(vertices=[[0,0,1], [1,0,1], + ....: [0,1,1], [1,1,1]]) sage: P.triangulate(engine='normaliz') Traceback (most recent call last): ... @@ -255,17 +258,23 @@ def triangulate(self, engine='auto', connected=True, fine=False, regular=None, s The normaliz engine can triangulate pointed cones:: - sage: C1 = Polyhedron(rays=[[0,0,1],[1,0,1],[0,1,1],[1,1,1]],backend='normaliz') # optional - pynormaliz - sage: C1.triangulate(engine='normaliz') # optional - pynormaliz + sage: C1 = Polyhedron(rays=[[0,0,1], [1,0,1], # optional - pynormaliz + ....: [0,1,1], [1,1,1]], + ....: backend='normaliz') + sage: C1.triangulate(engine='normaliz') # optional - pynormaliz (<0,1,2>, <1,2,3>) - sage: C2 = Polyhedron(rays=[[1,0,1],[0,0,1],[0,1,1],[1,1,10/9]],backend='normaliz') # optional - pynormaliz - sage: C2.triangulate(engine='normaliz') # optional - pynormaliz + sage: C2 = Polyhedron(rays=[[1,0,1], [0,0,1], # optional - pynormaliz + ....: [0,1,1], [1,1,10/9]], + ....: backend='normaliz') + sage: C2.triangulate(engine='normaliz') # optional - pynormaliz (<0,1,2>, <1,2,3>) They can also be affine cones:: - sage: K = Polyhedron(vertices=[[1,1,1]],rays=[[1,0,0],[0,1,0],[1,1,-1],[1,1,1]], backend='normaliz') # optional - pynormaliz - sage: K.triangulate(engine='normaliz') # optional - pynormaliz + sage: K = Polyhedron(vertices=[[1,1,1]], # optional - pynormaliz + ....: rays=[[1,0,0], [0,1,0], [1,1,-1], [1,1,1]], + ....: backend='normaliz') + sage: K.triangulate(engine='normaliz') # optional - pynormaliz (<0,1,2>, <0,1,3>) """ if self.lines(): @@ -309,11 +318,11 @@ def _volume_lrs(self, verbose=False): EXAMPLES:: - sage: polytopes.hypercube(3)._volume_lrs() # optional - lrslib + sage: polytopes.hypercube(3)._volume_lrs() # optional - lrslib 8 - sage: (polytopes.hypercube(3)*2)._volume_lrs() # optional - lrslib + sage: (polytopes.hypercube(3)*2)._volume_lrs() # optional - lrslib 64 - sage: polytopes.twenty_four_cell()._volume_lrs() # optional - lrslib + sage: polytopes.twenty_four_cell()._volume_lrs() # optional - lrslib 2 REFERENCES: @@ -380,35 +389,35 @@ def _volume_latte(self, verbose=False, algorithm='triangulate', **kwargs): EXAMPLES:: - sage: polytopes.hypercube(3)._volume_latte() # optional - latte_int + sage: polytopes.hypercube(3)._volume_latte() # optional - latte_int 8 - sage: (polytopes.hypercube(3)*2)._volume_latte() # optional - latte_int + sage: (polytopes.hypercube(3)*2)._volume_latte() # optional - latte_int 64 - sage: polytopes.twenty_four_cell()._volume_latte() # optional - latte_int + sage: polytopes.twenty_four_cell()._volume_latte() # optional - latte_int 2 - sage: polytopes.cuboctahedron()._volume_latte() # optional - latte_int + sage: polytopes.cuboctahedron()._volume_latte() # optional - latte_int 20/3 TESTS: Testing triangulate algorithm:: - sage: polytopes.cuboctahedron()._volume_latte(algorithm='triangulate') # optional - latte_int + sage: polytopes.cuboctahedron()._volume_latte(algorithm='triangulate') # optional - latte_int 20/3 Testing cone decomposition algorithm:: - sage: polytopes.cuboctahedron()._volume_latte(algorithm='cone-decompose') # optional - latte_int + sage: polytopes.cuboctahedron()._volume_latte(algorithm='cone-decompose') # optional - latte_int 20/3 Testing raw output:: - sage: polytopes.cuboctahedron()._volume_latte(raw_output=True) # optional - latte_int + sage: polytopes.cuboctahedron()._volume_latte(raw_output=True) # optional - latte_int '20/3' Testing inexact rings:: - sage: P = Polyhedron(vertices=[[0,0],[1,0],[0,1]],base_ring=RDF) + sage: P = Polyhedron(vertices=[[0,0], [1,0], [0,1]],base_ring=RDF) sage: P.volume(engine='latte') Traceback (most recent call last): ... @@ -444,7 +453,7 @@ def _volume_normaliz(self, measure='induced'): TESTS:: - sage: P = Polyhedron(vertices=[[0,0],[1,0],[0,1],[1,1]]) + sage: P = Polyhedron(vertices=[[0,0], [1,0], [0,1], [1,1]]) sage: P._volume_normaliz() Traceback (most recent call last): ... @@ -497,21 +506,21 @@ def volume(self, measure='ambient', engine='auto', **kwds): (which requires a rational polytope):: sage: I3 = polytopes.hypercube(3) - sage: I3.volume(engine='lrs') # optional - lrslib + sage: I3.volume(engine='lrs') # optional - lrslib 8 sage: C24 = polytopes.twenty_four_cell() - sage: C24.volume(engine='lrs') # optional - lrslib + sage: C24.volume(engine='lrs') # optional - lrslib 2 If the base ring is exact, the answer is exact:: - sage: P5 = polytopes.regular_polygon(5) # optional - sage.rings.number_field - sage: P5.volume() # optional - sage.rings.number_field + sage: P5 = polytopes.regular_polygon(5) # optional - sage.rings.number_field + sage: P5.volume() # optional - sage.rings.number_field 2.377641290737884? - sage: polytopes.icosahedron().volume() # optional - sage.rings.number_field + sage: polytopes.icosahedron().volume() # optional - sage.rings.number_field 5/12*sqrt5 + 5/4 - sage: numerical_approx(_) # abs tol 1e9 # optional - sage.rings.number_field + sage: numerical_approx(_) # abs tol 1e9 # optional - sage.rings.number_field 2.18169499062491 When considering lower-dimensional polytopes, we can ask for the @@ -524,83 +533,92 @@ def volume(self, measure='ambient', engine='auto', **kwds): sage: P = Polyhedron([[0, 0], [1, 1]]) sage: P.volume() 0 - sage: P.volume(measure='induced') # optional - sage.rings.number_field + sage: P.volume(measure='induced') # optional - sage.rings.number_field 1.414213562373095? - sage: P.volume(measure='induced_rational') # optional -- latte_int + sage: P.volume(measure='induced_rational') # optional - latte_int 1 - sage: S = polytopes.regular_polygon(6); S # optional - sage.rings.number_field + sage: S = polytopes.regular_polygon(6); S # optional - sage.rings.number_field A 2-dimensional polyhedron in AA^2 defined as the convex hull of 6 vertices - sage: edge = S.faces(1)[4].as_polyhedron() # optional - sage.rings.number_field - sage: edge.vertices() # optional - sage.rings.number_field + sage: edge = S.faces(1)[4].as_polyhedron() # optional - sage.rings.number_field + sage: edge.vertices() # optional - sage.rings.number_field (A vertex at (0.866025403784439?, 1/2), A vertex at (0, 1)) - sage: edge.volume() # optional - sage.rings.number_field + sage: edge.volume() # optional - sage.rings.number_field 0 - sage: edge.volume(measure='induced') # optional - sage.rings.number_field + sage: edge.volume(measure='induced') # optional - sage.rings.number_field 1 - sage: P = Polyhedron(backend='normaliz',vertices=[[1,0,0],[0,0,1],[-1,1,1],[-1,2,0]]) # optional - pynormaliz - sage: P.volume() # optional - pynormaliz + sage: P = Polyhedron(backend='normaliz', # optional - pynormaliz + ....: vertices=[[1,0,0], [0,0,1], + ....: [-1,1,1], [-1,2,0]]) + sage: P.volume() # optional - pynormaliz 0 - sage: P.volume(measure='induced') # optional - pynormaliz # optional - sage.rings.number_field + sage: P.volume(measure='induced') # optional - pynormaliz sage.rings.number_field 2.598076211353316? - sage: P.volume(measure='induced',engine='normaliz') # optional - pynormaliz + sage: P.volume(measure='induced', engine='normaliz') # optional - pynormaliz 2.598076211353316 - sage: P.volume(measure='induced_rational') # optional - pynormaliz, latte_int + sage: P.volume(measure='induced_rational') # optional - pynormaliz latte_int 3/2 - sage: P.volume(measure='induced_rational',engine='normaliz') # optional - pynormaliz + sage: P.volume(measure='induced_rational', # optional - pynormaliz + ....: engine='normaliz') 3/2 - sage: P.volume(measure='induced_lattice') # optional - pynormaliz + sage: P.volume(measure='induced_lattice') # optional - pynormaliz 3 The same polytope without normaliz backend:: - sage: P = Polyhedron(vertices=[[1,0,0],[0,0,1],[-1,1,1],[-1,2,0]]) - sage: P.volume(measure='induced_lattice',engine='latte') # optional - latte_int + sage: P = Polyhedron(vertices=[[1,0,0], [0,0,1], [-1,1,1], [-1,2,0]]) + sage: P.volume(measure='induced_lattice', engine='latte') # optional - latte_int 3 - sage: Dexact = polytopes.dodecahedron() # optional - sage.rings.number_field # optional - sage.groups - sage: v = Dexact.faces(2)[0].as_polyhedron().volume(measure='induced', engine='internal'); v # optional - sage.rings.number_field # optional - sage.groups + sage: Dexact = polytopes.dodecahedron() # optional - sage.rings.number_field sage.groups + sage: F0 = Dexact.faces(2)[0].as_polyhedron() + sage: v = F0.volume(measure='induced', engine='internal'); v # optional - sage.rings.number_field sage.groups 1.53406271079097? - sage: v = Dexact.faces(2)[4].as_polyhedron().volume(measure='induced', engine='internal'); v # optional - sage.rings.number_field # optional - sage.groups + sage: F4 = Dexact.faces(2)[4].as_polyhedron() + sage: v = F4.volume(measure='induced', engine='internal'); v # optional - sage.rings.number_field sage.groups 1.53406271079097? - sage: RDF(v) # abs tol 1e-9 # optional - sage.rings.number_field # optional - sage.groups + sage: RDF(v) # abs tol 1e-9 # optional - sage.rings.number_field sage.groups 1.53406271079044 - sage: Dinexact = polytopes.dodecahedron(exact=False) # optional - sage.groups - sage: w = Dinexact.faces(2)[2].as_polyhedron().volume(measure='induced', engine='internal'); RDF(w) # abs tol 1e-9 # optional - sage.groups + sage: Dinexact = polytopes.dodecahedron(exact=False) # optional - sage.groups + sage: F2 = Dinexact.faces(2)[2].as_polyhedron() + sage: w = F2.volume(measure='induced', engine='internal') # optional - sage.groups + sage: RDF(w) # abs tol 1e-9 1.5340627082974878 - sage: [polytopes.simplex(d).volume(measure='induced') for d in range(1,5)] == [sqrt(d+1)/factorial(d) for d in range(1,5)] # optional - sage.rings.number_field + sage: all(polytopes.simplex(d).volume(measure='induced') # optional - sage.rings.number_field sage.symbolic + ....: == sqrt(d+1)/factorial(d) + ....: for d in range(1,5)) True sage: I = Polyhedron([[-3, 0], [0, 9]]) - sage: I.volume(measure='induced') # optional - sage.rings.number_field + sage: I.volume(measure='induced') # optional - sage.rings.number_field 9.48683298050514? - sage: I.volume(measure='induced_rational') # optional -- latte_int + sage: I.volume(measure='induced_rational') # optional - latte_int 3 sage: T = Polyhedron([[3, 0, 0], [0, 4, 0], [0, 0, 5]]) - sage: T.volume(measure='induced') # optional - sage.rings.number_field + sage: T.volume(measure='induced') # optional - sage.rings.number_field 13.86542462386205? - sage: T.volume(measure='induced_rational') # optional -- latte_int + sage: T.volume(measure='induced_rational') # optional - latte_int 1/2 sage: Q = Polyhedron(vertices=[(0, 0, 1, 1), (0, 1, 1, 0), (1, 1, 0, 0)]) sage: Q.volume(measure='induced') 1 - sage: Q.volume(measure='induced_rational') # optional -- latte_int + sage: Q.volume(measure='induced_rational') # optional - latte_int 1/2 The volume of a full-dimensional unbounded polyhedron is infinity:: - sage: P = Polyhedron(vertices = [[1, 0], [0, 1]], rays = [[1, 1]]) + sage: P = Polyhedron(vertices=[[1, 0], [0, 1]], rays=[[1, 1]]) sage: P.volume() +Infinity The volume of a non full-dimensional unbounded polyhedron depends on the measure used:: - sage: P = Polyhedron(ieqs = [[1,1,1],[-1,-1,-1],[3,1,0]]); P + sage: P = Polyhedron(ieqs = [[1,1,1], [-1,-1,-1], [3,1,0]]); P A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 ray sage: P.volume() 0 @@ -608,9 +626,9 @@ def volume(self, measure='ambient', engine='auto', **kwds): +Infinity sage: P.volume(measure='ambient') 0 - sage: P.volume(measure='induced_rational') # optional - pynormaliz + sage: P.volume(measure='induced_rational') # optional - pynormaliz +Infinity - sage: P.volume(measure='induced_rational',engine='latte') # optional - latte_int + sage: P.volume(measure='induced_rational',engine='latte') # optional - latte_int +Infinity The volume in `0`-dimensional space is taken by counting measure:: @@ -638,7 +656,7 @@ def volume(self, measure='ambient', engine='auto', **kwds): Induced volumes work with lrs (:trac:`33410`):: sage: P = Polyhedron([[0, 0], [1, 1]]) - sage: P.volume(measure='induced', engine='lrs') # optional - lrslib + sage: P.volume(measure='induced', engine='lrs') # optional - lrslib 1.414213562373095? """ from sage.features import FeatureNotPresentError @@ -776,7 +794,7 @@ def integrate(self, function, measure='ambient', **kwds): sage: P = polytopes.cube() sage: x, y, z = polygens(QQ, 'x, y, z') - sage: P.integrate(x^2*y^2*z^2) # optional - latte_int + sage: P.integrate(x^2*y^2*z^2) # optional - latte_int 8/27 If the polyhedron has floating point coordinates, an inexact result can @@ -784,41 +802,45 @@ def integrate(self, function, measure='ambient', **kwds): sage: P = 1.4142*polytopes.cube() sage: P_QQ = Polyhedron(vertices=[[QQ(vi) for vi in v] for v in P.vertex_generator()]) - sage: RDF(P_QQ.integrate(x^2*y^2*z^2)) # optional - latte_int + sage: RDF(P_QQ.integrate(x^2*y^2*z^2)) # optional - latte_int 6.703841212195228 Integral over a non full-dimensional polytope:: sage: x, y = polygens(QQ, 'x, y') - sage: P = Polyhedron(vertices=[[0,0],[1,1]]) - sage: P.integrate(x*y) # optional - latte_int + sage: P = Polyhedron(vertices=[[0,0], [1,1]]) + sage: P.integrate(x*y) # optional - latte_int 0 - sage: ixy = P.integrate(x*y, measure='induced'); ixy # optional - latte_int + sage: ixy = P.integrate(x*y, measure='induced'); ixy # optional - latte_int 0.4714045207910317? - sage: ixy.parent() # optional - latte_int + sage: ixy.parent() # optional - latte_int Algebraic Real Field Convert to a symbolic expression:: - sage: ixy.radical_expression() # optional - latte_int + sage: ixy.radical_expression() # optional - latte_int 1/3*sqrt(2) Another non full-dimensional polytope integration:: sage: R. = QQ[] sage: P = polytopes.simplex(2) - sage: V = AA(P.volume(measure='induced')); V.radical_expression() # optional - sage.rings.number_field sage.symbolic + sage: V = AA(P.volume(measure='induced')) # optional - sage.rings.number_field + sage: V.radical_expression() # optional - sage.rings.number_field sage.symbolic 1/2*sqrt(3) - sage: P.integrate(R(1), measure='induced') == V # optional - latte_int # optional - sage.rings.number_field sage.symbolic + sage: P.integrate(R(1), measure='induced') == V # optional - latte_int sage.rings.number_field sage.symbolic True Computing the mass center:: - sage: (P.integrate(x, measure='induced') / V).radical_expression() # optional - latte_int + sage: (P.integrate(x, measure='induced') # optional - latte_int sage.rings.number_field sage.symbolic + ....: / V).radical_expression() 1/3 - sage: (P.integrate(y, measure='induced') / V).radical_expression() # optional - latte_int + sage: (P.integrate(y, measure='induced') # optional - latte_int sage.rings.number_field sage.symbolic + ....: / V).radical_expression() 1/3 - sage: (P.integrate(z, measure='induced') / V).radical_expression() # optional - latte_int + sage: (P.integrate(z, measure='induced') # optional - latte_int sage.rings.number_field sage.symbolic + ....: / V).radical_expression() 1/3 TESTS: @@ -827,28 +849,28 @@ def integrate(self, function, measure='ambient', **kwds): sage: P = polytopes.octahedron() sage: x, y, z = polygens(QQ, 'x, y, z') - sage: P.integrate(2*x^2*y^4*z^6+z^2) # optional - latte_int + sage: P.integrate(2*x^2*y^4*z^6 + z^2) # optional - latte_int 630632/4729725 Testing a polytope with non-rational vertices:: - sage: P = polytopes.icosahedron() # optional - sage.rings.number_field - sage: P.integrate(x^2*y^2*z^2) # optional - latte_int # optional - sage.rings.number_field + sage: P = polytopes.icosahedron() # optional - sage.rings.number_field + sage: P.integrate(x^2*y^2*z^2) # optional - latte_int sage.rings.number_field Traceback (most recent call last): ... TypeError: the base ring must be ZZ, QQ, or RDF Testing a univariate polynomial:: - sage: P = Polyhedron(vertices=[[0],[1]]) + sage: P = Polyhedron(vertices=[[0], [1]]) sage: x = polygen(QQ, 'x') - sage: P.integrate(x) # optional - latte_int + sage: P.integrate(x) # optional - latte_int 1/2 Testing a polytope with floating point coordinates:: - sage: P = Polyhedron(vertices = [[0, 0], [1, 0], [1.1, 1.1], [0, 1]]) - sage: P.integrate('[[1,[2,2]]]') # optional - latte_int + sage: P = Polyhedron(vertices=[[0, 0], [1, 0], [1.1, 1.1], [0, 1]]) + sage: P.integrate('[[1,[2,2]]]') # optional - latte_int Traceback (most recent call last): ... TypeError: LattE integrale cannot be applied over inexact rings @@ -945,7 +967,7 @@ def _integrate_latte_(self, polynomial, **kwds): sage: P = polytopes.cube() sage: x, y, z = polygens(QQ, 'x, y, z') - sage: P._integrate_latte_(x^2 + y^2*z^2) # optional - latte_int + sage: P._integrate_latte_(x^2 + y^2*z^2) # optional - latte_int 32/9 :: diff --git a/src/sage/geometry/polyhedron/base_QQ.py b/src/sage/geometry/polyhedron/base_QQ.py index 0c1cec7fedf..d279aa5ea7f 100644 --- a/src/sage/geometry/polyhedron/base_QQ.py +++ b/src/sage/geometry/polyhedron/base_QQ.py @@ -97,13 +97,13 @@ def integral_points_count(self, verbose=False, use_Hrepresentation=False, INPUT: - - ``verbose`` (boolean; ``False`` by default) -- whether to display + - ``verbose`` -- (boolean; ``False`` by default) whether to display verbose output. - - ``use_Hrepresentation`` - (boolean; ``False`` by default) -- whether + - ``use_Hrepresentation`` -- (boolean; ``False`` by default) -- whether to send the H or V representation to LattE - - ``preprocess`` - (boolean; ``True`` by default) -- whether, if the integral hull + - ``preprocess`` -- (boolean; ``True`` by default) whether, if the integral hull is known to lie in a coordinate hyperplane, to tighten bounds to reduce dimension .. SEEALSO:: @@ -115,13 +115,13 @@ def integral_points_count(self, verbose=False, use_Hrepresentation=False, sage: P = polytopes.cube() sage: P.integral_points_count() 27 - sage: P.integral_points_count(explicit_enumeration_threshold=0) # optional - latte_int + sage: P.integral_points_count(explicit_enumeration_threshold=0) # optional - latte_int 27 We enlarge the polyhedron to force the use of the generating function methods implemented in LattE integrale, rather than explicit enumeration:: - sage: (1000000000*P).integral_points_count(verbose=True) # optional - latte_int + sage: (1000000000*P).integral_points_count(verbose=True) # optional - latte_int This is LattE integrale... ... Total time:... @@ -132,7 +132,7 @@ def integral_points_count(self, verbose=False, use_Hrepresentation=False, sage: Q = P*(8/9) sage: Q.integral_points_count() 1 - sage: Q.integral_points_count(explicit_enumeration_threshold=0) # optional - latte_int + sage: Q.integral_points_count(explicit_enumeration_threshold=0) # optional - latte_int 1 Unbounded polyhedra (with or without lattice points) are not supported:: @@ -243,12 +243,12 @@ def ehrhart_polynomial(self, engine=None, variable='t', verbose=False, is computed using LattE Integrale (optional) * ``'latte'``; use LattE integrale program (optional) * ``'normaliz'``; use Normaliz program (optional package pynormaliz). - The backend of ``self`` must be set to 'normaliz'. + The backend of ``self`` must be set to ``'normaliz'``. - - ``variable`` -- string (default: 't'); The variable in which the - Ehrhart polynomial should be expressed. + - ``variable`` -- string (default: ``'t'``); The variable in which the + Ehrhart polynomial should be expressed. - - When the ``engine`` is 'latte', the additional input values are: + - When the ``engine`` is ``'latte'``, the additional input values are: * ``verbose`` - boolean (default: ``False``); If ``True``, print the whole output of the LattE command. @@ -259,9 +259,9 @@ def ehrhart_polynomial(self, engine=None, variable='t', verbose=False, * ``dual`` - boolean; triangulate and signed-decompose in the dual space - * ``irrational_primal`` - boolean; triangulate in the dual space, + * ``irrational_primal`` -- boolean; triangulate in the dual space, signed-decompose in the primal space using irrationalization. - * ``irrational_all_primal`` - boolean; triangulate and signed-decompose + * ``irrational_all_primal`` -- boolean; triangulate and signed-decompose in the primal space using irrationalization. * ``maxdet`` -- integer; decompose down to an index (determinant) of ``maxdet`` instead of index 1 (unimodular cones). @@ -270,8 +270,8 @@ def ehrhart_polynomial(self, engine=None, variable='t', verbose=False, * ``compute_vertex_cones`` -- string; either 'cdd' or 'lrs' or '4ti2' * ``smith_form`` -- string; either 'ilio' or 'lidia' * ``dualization`` -- string; either 'cdd' or '4ti2' - * ``triangulation`` - string; 'cddlib', '4ti2' or 'topcom' - * ``triangulation_max_height`` - integer; use a uniform distribution + * ``triangulation`` -- string; 'cddlib', '4ti2' or 'topcom' + * ``triangulation_max_height`` -- integer; use a uniform distribution of height from 1 to this number OUTPUT: @@ -287,54 +287,58 @@ def ehrhart_polynomial(self, engine=None, variable='t', verbose=False, To start, we find the Ehrhart polynomial of a three-dimensional ``simplex``, first using ``engine='latte'``. Leaving the engine - unspecified sets the ``engine`` to 'latte' by default:: + unspecified sets the ``engine`` to ``'latte'`` by default:: sage: simplex = Polyhedron(vertices=[(0,0,0),(3,3,3),(-3,2,1),(1,-1,-2)]) sage: simplex = simplex.change_ring(QQ) - sage: poly = simplex.ehrhart_polynomial(engine='latte') # optional - latte_int - sage: poly # optional - latte_int + sage: poly = simplex.ehrhart_polynomial(engine='latte') # optional - latte_int + sage: poly # optional - latte_int 7/2*t^3 + 2*t^2 - 1/2*t + 1 - sage: poly(1) # optional - latte_int + sage: poly(1) # optional - latte_int 6 - sage: len(simplex.integral_points()) # optional - latte_int + sage: len(simplex.integral_points()) # optional - latte_int 6 - sage: poly(2) # optional - latte_int + sage: poly(2) # optional - latte_int 36 - sage: len((2*simplex).integral_points()) # optional - latte_int + sage: len((2*simplex).integral_points()) # optional - latte_int 36 Now we find the same Ehrhart polynomial, this time using ``engine='normaliz'``. To use the Normaliz engine, the ``simplex`` must be defined with ``backend='normaliz'``:: - sage: simplex = Polyhedron(vertices=[(0,0,0),(3,3,3),(-3,2,1),(1,-1,-2)], backend='normaliz') # optional - pynormaliz - sage: simplex = simplex.change_ring(QQ) # optional - pynormaliz - sage: poly = simplex.ehrhart_polynomial(engine = 'normaliz') # optional - pynormaliz - sage: poly # optional - pynormaliz + sage: simplex = Polyhedron(vertices=[(0,0,0), (3,3,3), # optional - pynormaliz + ....: (-3,2,1), (1,-1,-2)], + ....: backend='normaliz') + sage: simplex = simplex.change_ring(QQ) # optional - pynormaliz + sage: poly = simplex.ehrhart_polynomial(engine='normaliz') # optional - pynormaliz + sage: poly # optional - pynormaliz 7/2*t^3 + 2*t^2 - 1/2*t + 1 If the ``engine='normaliz'``, the backend should be ``'normaliz'``, otherwise it returns an error:: - sage: simplex = Polyhedron(vertices=[(0,0,0),(3,3,3),(-3,2,1),(1,-1,-2)]) + sage: simplex = Polyhedron(vertices=[(0,0,0), (3,3,3), + ....: (-3,2,1), (1,-1,-2)]) sage: simplex = simplex.change_ring(QQ) - sage: simplex.ehrhart_polynomial(engine='normaliz') # optional - pynormaliz + sage: simplex.ehrhart_polynomial(engine='normaliz') # optional - pynormaliz Traceback (most recent call last): ... TypeError: The backend of the polyhedron should be 'normaliz' The polyhedron should be compact:: - sage: C = Polyhedron(backend='normaliz',rays=[[1,2],[2,1]]) # optional - pynormaliz - sage: C = C.change_ring(QQ) # optional - pynormaliz - sage: C.ehrhart_polynomial() # optional - pynormaliz + sage: C = Polyhedron(rays=[[1,2], [2,1]], # optional - pynormaliz + ....: backend='normaliz') + sage: C = C.change_ring(QQ) # optional - pynormaliz + sage: C.ehrhart_polynomial() # optional - pynormaliz Traceback (most recent call last): ... ValueError: Ehrhart polynomial only defined for compact polyhedra The polyhedron should have integral vertices:: - sage: L = Polyhedron(vertices = [[0],[1/2]]) + sage: L = Polyhedron(vertices=[[0], [1/2]]) sage: L.ehrhart_polynomial() Traceback (most recent call last): ... @@ -344,11 +348,11 @@ def ehrhart_polynomial(self, engine=None, variable='t', verbose=False, The cache of the Ehrhart polynomial is being pickled:: - sage: P = polytopes.cube().change_ring(QQ) # optional - latte_int - sage: P.ehrhart_polynomial() # optional - latte_int + sage: P = polytopes.cube().change_ring(QQ) # optional - latte_int + sage: P.ehrhart_polynomial() # optional - latte_int 8*t^3 + 12*t^2 + 6*t + 1 - sage: Q = loads(dumps(P)) # optional - latte_int - sage: Q.ehrhart_polynomial.is_in_cache() # optional - latte_int + sage: Q = loads(dumps(P)) # optional - latte_int + sage: Q.ehrhart_polynomial.is_in_cache() # optional - latte_int True """ # check if ``self`` is compact and has vertices in ZZ @@ -404,7 +408,7 @@ def ehrhart_quasipolynomial(self, variable='t', engine=None, verbose=False, INPUT: - - ``variable`` -- string (default: 't'); The variable in which the + - ``variable`` -- string (default: ``'t'``); The variable in which the Ehrhart polynomial should be expressed. - ``engine`` -- string; The backend to use. Allowed values are: @@ -425,21 +429,21 @@ def ehrhart_quasipolynomial(self, variable='t', engine=None, verbose=False, consult `the LattE documentation `__: - * ``dual`` - boolean; triangulate and signed-decompose in the dual + * ``dual`` -- boolean; triangulate and signed-decompose in the dual space - * ``irrational_primal`` - boolean; triangulate in the dual space, + * ``irrational_primal`` -- boolean; triangulate in the dual space, signed-decompose in the primal space using irrationalization. - * ``irrational_all_primal`` - boolean; triangulate and signed-decompose + * ``irrational_all_primal`` -- boolean; triangulate and signed-decompose in the primal space using irrationalization. * ``maxdet`` -- integer; decompose down to an index (determinant) of ``maxdet`` instead of index 1 (unimodular cones). * ``no_decomposition`` -- boolean; do not signed-decompose simplicial cones. - * ``compute_vertex_cones`` -- string; either 'cdd' or 'lrs' or '4ti2' - * ``smith_form`` -- string; either 'ilio' or 'lidia' - * ``dualization`` -- string; either 'cdd' or '4ti2' - * ``triangulation`` - string; 'cddlib', '4ti2' or 'topcom' - * ``triangulation_max_height`` - integer; use a uniform distribution of + * ``compute_vertex_cones`` -- string; either ``'cdd'`` or ``'lrs'`` or ``'4ti2'`` + * ``smith_form`` -- string; either ``'ilio'`` or ``'lidia'`` + * ``dualization`` -- string; either ``'cdd'`` or ``'4ti2'`` + * ``triangulation`` - string; ``'cddlib'``, ``'4ti2'`` or ``'topcom'`` + * ``triangulation_max_height`` -- integer; use a uniform distribution of height from 1 to this number OUTPUT: @@ -466,10 +470,10 @@ def ehrhart_quasipolynomial(self, variable='t', engine=None, verbose=False, the dilated line segment. Note that it is necessary to set the backend of the polytope to 'normaliz':: - sage: line_seg = Polyhedron(vertices=[[0],[1/2]],backend='normaliz') # optional - pynormaliz - sage: line_seg # optional - pynormaliz + sage: line_seg = Polyhedron(vertices=[[0], [1/2]], # optional - pynormaliz + ....: backend='normaliz'); line_seg A 1-dimensional polyhedron in QQ^1 defined as the convex hull of 2 vertices - sage: line_seg.ehrhart_quasipolynomial() # optional - pynormaliz + sage: line_seg.ehrhart_quasipolynomial() # optional - pynormaliz (1/2*t + 1, 1/2*t + 1/2) For a more exciting example, let us look at the subpolytope of the @@ -477,34 +481,33 @@ def ehrhart_quasipolynomial(self, variable='t', engine=None, verbose=False, across the hyperplane `x_1 = x_4`:: sage: verts = [[3/2, 3, 4, 3/2], - ....: [3/2, 4, 3, 3/2], - ....: [5/2, 1, 4, 5/2], - ....: [5/2, 4, 1, 5/2], - ....: [7/2, 1, 2, 7/2], - ....: [7/2, 2, 1, 7/2]] - sage: subpoly = Polyhedron(vertices=verts, backend='normaliz') # optional - pynormaliz - sage: eq = subpoly.ehrhart_quasipolynomial() # optional - pynormaliz - sage: eq # optional - pynormaliz + ....: [3/2, 4, 3, 3/2], + ....: [5/2, 1, 4, 5/2], + ....: [5/2, 4, 1, 5/2], + ....: [7/2, 1, 2, 7/2], + ....: [7/2, 2, 1, 7/2]] + sage: subpoly = Polyhedron(vertices=verts, # optional - pynormaliz + ....: backend='normaliz') + sage: eq = subpoly.ehrhart_quasipolynomial(); eq # optional - pynormaliz (4*t^2 + 3*t + 1, 4*t^2 + 2*t) - sage: eq = subpoly.ehrhart_quasipolynomial() # optional - pynormaliz - sage: eq # optional - pynormaliz + sage: eq = subpoly.ehrhart_quasipolynomial(); eq # optional - pynormaliz (4*t^2 + 3*t + 1, 4*t^2 + 2*t) - sage: even_ep = eq[0] # optional - pynormaliz - sage: odd_ep = eq[1] # optional - pynormaliz - sage: even_ep(2) # optional - pynormaliz + sage: even_ep = eq[0] # optional - pynormaliz + sage: odd_ep = eq[1] # optional - pynormaliz + sage: even_ep(2) # optional - pynormaliz 23 - sage: ts = 2*subpoly # optional - pynormaliz - sage: ts.integral_points_count() # optional - pynormaliz latte_int + sage: ts = 2*subpoly # optional - pynormaliz + sage: ts.integral_points_count() # optional - pynormaliz latte_int 23 - sage: odd_ep(1) # optional - pynormaliz + sage: odd_ep(1) # optional - pynormaliz 6 - sage: subpoly.integral_points_count() # optional - pynormaliz latte_int + sage: subpoly.integral_points_count() # optional - pynormaliz latte_int 6 A polytope with rational nonintegral vertices must have ``backend='normaliz'``:: - sage: line_seg = Polyhedron(vertices=[[0],[1/2]]) + sage: line_seg = Polyhedron(vertices=[[0], [1/2]]) sage: line_seg.ehrhart_quasipolynomial() Traceback (most recent call last): ... @@ -512,8 +515,9 @@ def ehrhart_quasipolynomial(self, variable='t', engine=None, verbose=False, The polyhedron should be compact:: - sage: C = Polyhedron(backend='normaliz',rays=[[1/2,2],[2,1]]) # optional - pynormaliz - sage: C.ehrhart_quasipolynomial() # optional - pynormaliz + sage: C = Polyhedron(rays=[[1/2,2], [2,1]], # optional - pynormaliz + ....: backend='normaliz') + sage: C.ehrhart_quasipolynomial() # optional - pynormaliz Traceback (most recent call last): ... ValueError: Ehrhart quasipolynomial only defined for compact polyhedra @@ -521,12 +525,14 @@ def ehrhart_quasipolynomial(self, variable='t', engine=None, verbose=False, If the polytope happens to be a lattice polytope, the Ehrhart polynomial is returned:: - sage: simplex = Polyhedron(vertices=[(0,0,0),(3,3,3),(-3,2,1),(1,-1,-2)], backend='normaliz') # optional - pynormaliz - sage: simplex = simplex.change_ring(QQ) # optional - pynormaliz - sage: poly = simplex.ehrhart_quasipolynomial(engine='normaliz') # optional - pynormaliz - sage: poly # optional - pynormaliz + sage: simplex = Polyhedron(vertices=[(0,0,0), (3,3,3), # optional - pynormaliz + ....: (-3,2,1), (1,-1,-2)], + ....: backend='normaliz') + sage: simplex = simplex.change_ring(QQ) # optional - pynormaliz + sage: poly = simplex.ehrhart_quasipolynomial( # optional - pynormaliz + ....: engine='normaliz'); poly 7/2*t^3 + 2*t^2 - 1/2*t + 1 - sage: simplex.ehrhart_polynomial() # optional - pynormaliz latte_int + sage: simplex.ehrhart_polynomial() # optional - pynormaliz latte_int 7/2*t^3 + 2*t^2 - 1/2*t + 1 TESTS: @@ -582,7 +588,7 @@ def _ehrhart_quasipolynomial_normaliz(self, variable='t'): INPUT: - - ``variable`` -- string (default: 't'); The variable in which the + - ``variable`` -- string (default: ``'t'``); The variable in which the Ehrhart polynomial is expressed. OUTPUT: @@ -596,31 +602,31 @@ def _ehrhart_quasipolynomial_normaliz(self, variable='t'): reflection across the hyperplane `x_1 = x_4`:: sage: verts = [[3/2, 3, 4, 3/2], - ....: [3/2, 4, 3, 3/2], - ....: [5/2, 1, 4, 5/2], - ....: [5/2, 4, 1, 5/2], - ....: [7/2, 1, 2, 7/2], - ....: [7/2, 2, 1, 7/2]] - sage: subpoly = Polyhedron(vertices=verts, backend='normaliz') # optional - pynormaliz - sage: eq = subpoly._ehrhart_quasipolynomial_normaliz() # optional - pynormaliz - sage: eq # optional - pynormaliz + ....: [3/2, 4, 3, 3/2], + ....: [5/2, 1, 4, 5/2], + ....: [5/2, 4, 1, 5/2], + ....: [7/2, 1, 2, 7/2], + ....: [7/2, 2, 1, 7/2]] + sage: subpoly = Polyhedron(vertices=verts, # optional - pynormaliz + ....: backend='normaliz') + sage: eq = subpoly._ehrhart_quasipolynomial_normaliz(); eq # optional - pynormaliz (4*t^2 + 3*t + 1, 4*t^2 + 2*t) - sage: even_ep = eq[0] # optional - pynormaliz - sage: odd_ep = eq[1] # optional - pynormaliz - sage: even_ep(2) # optional - pynormaliz + sage: even_ep = eq[0] # optional - pynormaliz + sage: odd_ep = eq[1] # optional - pynormaliz + sage: even_ep(2) # optional - pynormaliz 23 - sage: ts = 2*subpoly # optional - pynormaliz - sage: ts.integral_points_count() # optional - pynormaliz latte_int + sage: ts = 2*subpoly # optional - pynormaliz + sage: ts.integral_points_count() # optional - pynormaliz latte_int 23 - sage: odd_ep(1) # optional - pynormaliz + sage: odd_ep(1) # optional - pynormaliz 6 - sage: subpoly.integral_points_count() # optional - pynormaliz latte_int + sage: subpoly.integral_points_count() # optional - pynormaliz latte_int 6 TESTS:: sage: line_seg = Polyhedron(vertices=[[0],[1/2]]) - sage: line_seg._ehrhart_quasipolynomial_normaliz() # optional - pynormaliz + sage: line_seg._ehrhart_quasipolynomial_normaliz() # optional - pynormaliz Traceback (most recent call last): ... TypeError: The backend of the polyhedron should be 'normaliz' @@ -645,20 +651,20 @@ def _ehrhart_polynomial_latte(self, verbose=False, dual=None, INPUT: - - ``verbose`` - boolean (default: ``False``); if ``True``, print the + - ``verbose`` -- boolean (default: ``False``); if ``True``, print the whole output of the LattE command. The following options are passed to the LattE command, for details you should consult `the LattE documentation `__: - - ``dual`` - boolean; triangulate and signed-decompose in the dual + - ``dual`` -- boolean; triangulate and signed-decompose in the dual space - - ``irrational_primal`` - boolean; triangulate in the dual space, + - ``irrational_primal`` -- boolean; triangulate in the dual space, signed-decompose in the primal space using irrationalization. - - ``irrational_all_primal`` - boolean; triangulate and signed-decompose + - ``irrational_all_primal`` -- boolean; triangulate and signed-decompose in the primal space using irrationalization. - ``maxdet`` -- integer; decompose down to an index (determinant) of @@ -666,15 +672,15 @@ def _ehrhart_polynomial_latte(self, verbose=False, dual=None, - ``no_decomposition`` -- boolean; do not signed-decompose simplicial cones. - - ``compute_vertex_cones`` -- string; either 'cdd' or 'lrs' or '4ti2' + - ``compute_vertex_cones`` -- string; either ``'cdd'`` or ``'lrs'`` or ``'4ti2'`` - - ``smith_form`` -- string; either 'ilio' or 'lidia' + - ``smith_form`` -- string; either ``'ilio'`` or ``'lidia'`` - - ``dualization`` -- string; either 'cdd' or '4ti2' + - ``dualization`` -- string; either ``'cdd'`` or ``'4ti2'`` - - ``triangulation`` - string; 'cddlib', '4ti2' or 'topcom' + - ``triangulation`` -- string; ``'cddlib'``, ``'4ti2'`` or ``'topcom'`` - - ``triangulation_max_height`` - integer; use a uniform distribution of + - ``triangulation_max_height`` -- integer; use a uniform distribution of height from 1 to this number .. NOTE:: @@ -698,31 +704,30 @@ def _ehrhart_polynomial_latte(self, verbose=False, dual=None, EXAMPLES:: - sage: P = Polyhedron(vertices=[(0,0,0),(3,3,3),(-3,2,1),(1,-1,-2)]) - sage: p = P._ehrhart_polynomial_latte() # optional - latte_int - sage: p # optional - latte_int + sage: P = Polyhedron(vertices=[(0,0,0), (3,3,3), (-3,2,1), (1,-1,-2)]) + sage: p = P._ehrhart_polynomial_latte(); p # optional - latte_int 7/2*t^3 + 2*t^2 - 1/2*t + 1 - sage: p(1) # optional - latte_int + sage: p(1) # optional - latte_int 6 - sage: len(P.integral_points()) # optional - latte_int + sage: len(P.integral_points()) # optional - latte_int 6 - sage: p(2) # optional - latte_int + sage: p(2) # optional - latte_int 36 - sage: len((2*P).integral_points()) # optional - latte_int + sage: len((2*P).integral_points()) # optional - latte_int 36 The unit hypercubes:: sage: from itertools import product sage: def hypercube(d): - ....: return Polyhedron(vertices=list(product([0,1],repeat=d))) - sage: hypercube(3)._ehrhart_polynomial_latte() # optional - latte_int + ....: return Polyhedron(vertices=list(product([0,1], repeat=d))) + sage: hypercube(3)._ehrhart_polynomial_latte() # optional - latte_int t^3 + 3*t^2 + 3*t + 1 - sage: hypercube(4)._ehrhart_polynomial_latte() # optional - latte_int + sage: hypercube(4)._ehrhart_polynomial_latte() # optional - latte_int t^4 + 4*t^3 + 6*t^2 + 4*t + 1 - sage: hypercube(5)._ehrhart_polynomial_latte() # optional - latte_int + sage: hypercube(5)._ehrhart_polynomial_latte() # optional - latte_int t^5 + 5*t^4 + 10*t^3 + 10*t^2 + 5*t + 1 - sage: hypercube(6)._ehrhart_polynomial_latte() # optional - latte_int + sage: hypercube(6)._ehrhart_polynomial_latte() # optional - latte_int t^6 + 6*t^5 + 15*t^4 + 20*t^3 + 15*t^2 + 6*t + 1 TESTS: @@ -822,50 +827,55 @@ def fixed_subpolytope(self, vertex_permutation): The fixed subpolytopes of the cube can be obtained as follows:: - sage: Cube = polytopes.cube(backend = 'normaliz') # optional - pynormaliz - sage: AG = Cube.restricted_automorphism_group(output='permutation') # optional - pynormaliz - sage: reprs = AG.conjugacy_classes_representatives() # optional - pynormaliz + sage: Cube = polytopes.cube(backend = 'normaliz') # optional - pynormaliz + sage: AG = Cube.restricted_automorphism_group( # optional - pynormaliz + ....: output='permutation') + sage: reprs = AG.conjugacy_classes_representatives() # optional - pynormaliz The fixed subpolytope of the identity element of the group is the entire cube:: - sage: reprs[0] # optional - pynormaliz + sage: reprs[0] # optional - pynormaliz () - sage: Cube.fixed_subpolytope(vertex_permutation = reprs[0]) # optional - pynormaliz + sage: Cube.fixed_subpolytope(vertex_permutation=reprs[0]) # optional - pynormaliz A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices - sage: _.vertices() # optional - pynormaliz + sage: _.vertices() # optional - pynormaliz (A vertex at (-1, -1, -1), - A vertex at (-1, -1, 1), - A vertex at (-1, 1, -1), - A vertex at (-1, 1, 1), - A vertex at (1, -1, -1), - A vertex at (1, -1, 1), - A vertex at (1, 1, -1), - A vertex at (1, 1, 1)) + A vertex at (-1, -1, 1), + A vertex at (-1, 1, -1), + A vertex at (-1, 1, 1), + A vertex at (1, -1, -1), + A vertex at (1, -1, 1), + A vertex at (1, 1, -1), + A vertex at (1, 1, 1)) You can obtain non-trivial examples:: - sage: fsp = Cube.fixed_subpolytope(AG([(0,1),(2,3),(4,5),(6,7)]));fsp # optional - pynormaliz + sage: G = AG([(0,1),(2,3),(4,5),(6,7)]) # optional - pynormaliz + sage: fsp = Cube.fixed_subpolytope(G); fsp # optional - pynormaliz A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices - sage: fsp.vertices() # optional - pynormaliz + sage: fsp.vertices() # optional - pynormaliz (A vertex at (-1, -1, 0), - A vertex at (-1, 1, 0), - A vertex at (1, -1, 0), - A vertex at (1, 1, 0)) + A vertex at (-1, 1, 0), + A vertex at (1, -1, 0), + A vertex at (1, 1, 0)) - The next example shows that fixed_subpolytope works for rational polytopes:: + The next example shows that :meth:`fixed_subpolytope` works for rational polytopes:: - sage: P = Polyhedron(vertices=[[0],[1/2]], backend='normaliz') # optional - pynormaliz - sage: P.vertices() # optional - pynormaliz + sage: P = Polyhedron(vertices=[[0], [1/2]], # optional - pynormaliz + ....: backend='normaliz') + sage: P.vertices() # optional - pynormaliz (A vertex at (0), A vertex at (1/2)) - sage: G = P.restricted_automorphism_group(output='permutation');G # optional - pynormaliz + sage: G = P.restricted_automorphism_group( # optional - pynormaliz + ....: output='permutation'); G Permutation Group with generators [(0,1)] - sage: len(G) # optional - pynormaliz + sage: len(G) # optional - pynormaliz 2 - sage: fixed_set = P.fixed_subpolytope(G.gens()[0]); fixed_set # optional - pynormaliz + sage: fixed_set = P.fixed_subpolytope(G.gens()[0]) # optional - pynormaliz + sage: fixed_set # optional - pynormaliz A 0-dimensional polyhedron in QQ^1 defined as the convex hull of 1 vertex - sage: fixed_set.vertices_list() # optional - pynormaliz + sage: fixed_set.vertices_list() # optional - pynormaliz [[1/4]] """ if self.is_empty(): @@ -911,7 +921,7 @@ def fixed_subpolytopes(self, conj_class_reps): INPUT: - ``conj_class_reps`` -- a list of representatives of the conjugacy - classes of the subgroup of the ``restricted_automorphism_group`` of + classes of the subgroup of the :meth:`restricted_automorphism_group` of the polytope. Each element is written as a permutation of the vertices of the polytope. @@ -929,22 +939,23 @@ def fixed_subpolytopes(self, conj_class_reps): Here is an example for the square:: - sage: p = polytopes.hypercube(2, backend = 'normaliz'); p # optional - pynormaliz + sage: p = polytopes.hypercube(2, backend='normaliz'); p # optional - pynormaliz A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices - sage: aut_p = p.restricted_automorphism_group(output='permutation') # optional - pynormaliz # optional - sage.groups - sage: aut_p.order() # optional - pynormaliz # optional - sage.groups + sage: aut_p = p.restricted_automorphism_group( # optional - pynormaliz sage.groups + ....: output='permutation') + sage: aut_p.order() # optional - pynormaliz sage.groups 8 - sage: conj_list = aut_p.conjugacy_classes_representatives(); # optional - pynormaliz # optional - sage.groups - sage: fixedpolytopes_dictionary = p.fixed_subpolytopes(conj_list) # optional - pynormaliz # optional - sage.groups - sage: fixedpolytopes_dictionary[aut_p([(0,3),(1,2)])] # optional - pynormaliz # optional - sage.groups + sage: conj_list = aut_p.conjugacy_classes_representatives() # optional - pynormaliz sage.groups + sage: fixedpolytopes_dict = p.fixed_subpolytopes(conj_list) # optional - pynormaliz sage.groups + sage: fixedpolytopes_dict[aut_p([(0,3),(1,2)])] # optional - pynormaliz sage.groups A 0-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex TESTS:: sage: P = Polyhedron(vertices=[[1, 1]], rays=[[1, 1]]) - sage: aut_P = P.restricted_automorphism_group(output='permutation') # optional - sage.groups - sage: conj_list = aut_P.conjugacy_classes_representatives() # optional - sage.groups - sage: P.fixed_subpolytopes(conj_list) # optional - sage.groups + sage: aut_P = P.restricted_automorphism_group(output='permutation') # optional - sage.groups + sage: conj_list = aut_P.conjugacy_classes_representatives() # optional - sage.groups + sage: P.fixed_subpolytopes(conj_list) # optional - sage.groups Traceback (most recent call last): ... NotImplementedError: unbounded polyhedra are not supported @@ -976,24 +987,24 @@ def Hstar_function(self, acting_group=None, output=None): - ``acting_group`` -- (default=None) a permgroup object. A subgroup of the polytope's ``restricted_automorphism_group``. If ``None``, it is set to the full ``restricted_automorphism_group`` of the - polytope. The acting group should always use output='permutation'. + polytope. The acting group should always use ``output='permutation'``. - ``output`` -- string. an output option. The allowed values are: - * ``None`` (default): returns the rational function `H^*(t)`. `H^*` - is a rational function in `t` with coefficients in the ring of - class functions. - * ``'e_series_list'``: Returns a list of the ehrhart_series for the - fixed_subpolytopes of each conjugacy class representative. - * ``'determinant_vec'``: Returns a list of the determinants - of `Id-\rho*t` for each conjugacy class representative. - * ``'Hstar_as_lin_comb'``: Returns a vector of the coefficients - of the irreducible representations in the expression of `H^*`. - * ``'prod_det_es'``: Returns a vector of the product of - determinants and the Ehrhart series. - * ``'complete'``: Returns a list with Hstar, - Hstar_as_lin_comb, character table of the acting group, and - whether Hstar is effective. + * ``None`` (default): returns the rational function `H^*(t)`. `H^*` + is a rational function in `t` with coefficients in the ring of + class functions. + * ``'e_series_list'``: Returns a list of the ehrhart_series for the + fixed_subpolytopes of each conjugacy class representative. + * ``'determinant_vec'``: Returns a list of the determinants + of `Id-\rho*t` for each conjugacy class representative. + * ``'Hstar_as_lin_comb'``: Returns a vector of the coefficients + of the irreducible representations in the expression of `H^*`. + * ``'prod_det_es'``: Returns a vector of the product of + determinants and the Ehrhart series. + * ``'complete'``: Returns a list with ``Hstar``, + ``Hstar_as_lin_comb``, character table of the acting group, and + whether ``Hstar`` is effective. OUTPUT: @@ -1006,18 +1017,19 @@ class functions. EXAMPLES: The `H^*`-polynomial of the standard (`d-1`)-dimensional simplex - `S = conv(e_1, \dots, e_d)` under its ``restricted_automorphism_group`` + `S = conv(e_1, \dots, e_d)` under its :meth:`restricted_automorphism_group` is equal to 1 = `\chi_{trivial}` (Prop 6.1 [Stap2011]_). Here is the computation for the 3-dimensional standard simplex:: - sage: S = polytopes.simplex(3, backend = 'normaliz'); S # optional - pynormaliz + sage: S = polytopes.simplex(3, backend='normaliz'); S # optional - pynormaliz A 3-dimensional polyhedron in ZZ^4 defined as the convex hull of 4 vertices - sage: G = S.restricted_automorphism_group(output = 'permutation') # optional - pynormaliz - sage: G.is_isomorphic(SymmetricGroup(4)) # optional - pynormaliz + sage: G = S.restricted_automorphism_group( # optional - pynormaliz + ....: output='permutation') + sage: G.is_isomorphic(SymmetricGroup(4)) # optional - pynormaliz True - sage: Hstar = S._Hstar_function_normaliz(G); Hstar # optional - pynormaliz + sage: Hstar = S._Hstar_function_normaliz(G); Hstar # optional - pynormaliz chi_4 - sage: G.character_table() # optional - pynormaliz + sage: G.character_table() # optional - pynormaliz [ 1 -1 1 1 -1] [ 3 -1 0 -1 1] [ 2 0 -1 2 0] @@ -1029,37 +1041,43 @@ class functions. `\pm(0,0,1),\pm(1,0,1), \pm(0,1,1), \pm(1,1,1)` and let G = `\Zmod{2}` act on P as follows:: - sage: P = Polyhedron(vertices=[[0,0,1],[0,0,-1],[1,0,1],[-1,0,-1],[0,1,1], # optional - pynormaliz - ....: [0,-1,-1],[1,1,1],[-1,-1,-1]], + sage: P = Polyhedron(vertices=[[0,0,1], [0,0,-1], [1,0,1], # optional - pynormaliz + ....: [-1,0,-1], [0,1,1], + ....: [0,-1,-1], [1,1,1], [-1,-1,-1]], ....: backend='normaliz') - sage: K = P.restricted_automorphism_group(output = 'permutation') # optional - pynormaliz - sage: G = K.subgroup(gens = [K([(0,2),(1,3),(4,6),(5,7)])]) # optional - pynormaliz - sage: conj_reps = G.conjugacy_classes_representatives() # optional - pynormaliz - sage: Dict = P.permutations_to_matrices(conj_reps, acting_group = G) # optional - pynormaliz - sage: list(Dict.keys())[0] # optional - pynormaliz + sage: K = P.restricted_automorphism_group( # optional - pynormaliz + ....: output='permutation') + sage: G = K.subgroup(gens=[K([(0,2),(1,3),(4,6),(5,7)])]) # optional - pynormaliz + sage: conj_reps = G.conjugacy_classes_representatives() # optional - pynormaliz + sage: Dict = P.permutations_to_matrices(conj_reps, # optional - pynormaliz + ....: acting_group=G) + sage: list(Dict.keys())[0] # optional - pynormaliz (0,2)(1,3)(4,6)(5,7) - sage: list(Dict.values())[0] # optional - pynormaliz + sage: list(Dict.values())[0] # optional - pynormaliz [-1 0 1 0] [ 0 1 0 0] [ 0 0 1 0] [ 0 0 0 1] - sage: len(G) # optional - pynormaliz + sage: len(G) # optional - pynormaliz 2 - sage: G.character_table() # optional - pynormaliz + sage: G.character_table() # optional - pynormaliz [ 1 1] [ 1 -1] Then we calculate the rational function `H^*(t)`:: - sage: Hst = P._Hstar_function_normaliz(G); Hst # optional - pynormaliz - (chi_0*t^4 + (3*chi_0 + 3*chi_1)*t^3 + (8*chi_0 + 2*chi_1)*t^2 + (3*chi_0 + 3*chi_1)*t + chi_0)/(t + 1) + sage: Hst = P._Hstar_function_normaliz(G); Hst # optional - pynormaliz + (chi_0*t^4 + (3*chi_0 + 3*chi_1)*t^3 + + (8*chi_0 + 2*chi_1)*t^2 + (3*chi_0 + 3*chi_1)*t + chi_0)/(t + 1) To see the exact as written in [Stap2011]_, we can format it as ``'Hstar_as_lin_comb'``. The first coordinate is the coefficient of the trivial character; the second is the coefficient of the sign character:: - sage: lin = P._Hstar_function_normaliz(G,output = 'Hstar_as_lin_comb'); lin # optional - pynormaliz - ((t^4 + 3*t^3 + 8*t^2 + 3*t + 1)/(t + 1), (3*t^3 + 2*t^2 + 3*t)/(t + 1)) + sage: lin = P._Hstar_function_normaliz( # optional - pynormaliz + ....: G, output='Hstar_as_lin_comb'); lin + ((t^4 + 3*t^3 + 8*t^2 + 3*t + 1)/(t + 1), + (3*t^3 + 2*t^2 + 3*t)/(t + 1)) """ if self.is_empty(): raise NotImplementedError('empty polyhedra are not supported') @@ -1079,26 +1097,26 @@ def _Hstar_function_normaliz(self, acting_group=None, output=None): INPUT: - ``acting_group`` -- (default=None) a permgroup object. A subgroup of - `self`'s ``restricted_automorphism_group`` output as a permutation. + ``self``'s ``restricted_automorphism_group`` output as a permutation. If ``None``, it is set to the full ``restricted_automorphism_group`` - of `self`. The acting group should always use output='permutation'. + of ``self``. The acting group should always use ``output='permutation'``. - ``output`` -- string. an output option. The allowed values are: - * ``None`` (default): returns the rational function `H^*(t)`. `H^*` - is a rational function in `t` with coefficients in the ring of - class functions. - * ``'e_series_list'``: Returns a list of the ehrhart_series - for the fixed_subpolytopes of each conjugacy class representative. - * ``'determinant_vec'``: Returns a list of the determinants - of `Id-\rho*t` for each conjugacy class representative. - * ``'Hstar_as_lin_comb'``: Returns a vector of the coefficients - of the irreducible representations in the expression of `H^*`. - * ``'prod_det_es'``: Returns a vector of the product of - determinants and the Ehrhart series. - * ``'complete'``: Returns a list with Hstar, - Hstar_as_lin_comb, character table of the acting group, and - whether Hstar is effective. + * ``None`` (default): Returns the rational function `H^*(t)`. `H^*` + is a rational function in `t` with coefficients in the ring of + class functions. + * ``'e_series_list'``: Returns a list of the ehrhart_series + for the fixed_subpolytopes of each conjugacy class representative. + * ``'determinant_vec'``: Returns a list of the determinants + of `Id-\rho*t` for each conjugacy class representative. + * ``'Hstar_as_lin_comb'``: Returns a vector of the coefficients + of the irreducible representations in the expression of `H^*`. + * ``'prod_det_es'``: Returns a vector of the product of + determinants and the Ehrhart series. + * ``'complete'``: Returns a list with ``Hstar``, + ``Hstar_as_lin_comb``, character table of the acting group, and + whether ``Hstar`` is effective. OUTPUT: @@ -1122,7 +1140,7 @@ def is_effective(self, Hstar, Hstar_as_lin_comb): Test for the effectiveness of the ``Hstar`` series of this polytope. The ``Hstar`` series of the polytope is determined by the action of a - subgroup of the polytope's ``restricted_automorphism_group``. The + subgroup of the polytope's :meth:`restricted_automorphism_group`. The ``Hstar`` series is effective if it is a polynomial in `t` and the coefficient of each `t^i` is an effective character in the ring of class functions of the acting group. A character `\rho` is effective if @@ -1152,28 +1170,35 @@ class functions of the acting group. A character `\rho` is effective if The `H^*` series of the two-dimensional permutahedron under the action of the symmetric group is effective:: - sage: p3 = polytopes.permutahedron(3, backend = 'normaliz') # optional - pynormaliz - sage: G = p3.restricted_automorphism_group(output='permutation') # optional - pynormaliz - sage: reflection12 = G([(0,2),(1,4),(3,5)]) # optional - pynormaliz - sage: reflection23 = G([(0,1),(2,3),(4,5)]) # optional - pynormaliz - sage: S3 = G.subgroup(gens=[reflection12, reflection23]) # optional - pynormaliz - sage: S3.is_isomorphic(SymmetricGroup(3)) # optional - pynormaliz + sage: p3 = polytopes.permutahedron(3, backend='normaliz') # optional - pynormaliz + sage: G = p3.restricted_automorphism_group( # optional - pynormaliz + ....: output='permutation') + sage: reflection12 = G([(0,2),(1,4),(3,5)]) # optional - pynormaliz + sage: reflection23 = G([(0,1),(2,3),(4,5)]) # optional - pynormaliz + sage: S3 = G.subgroup(gens=[reflection12, reflection23]) # optional - pynormaliz + sage: S3.is_isomorphic(SymmetricGroup(3)) # optional - pynormaliz True - sage: [Hstar, Hlin] = [p3.Hstar_function(S3), p3.Hstar_function(S3, output = 'Hstar_as_lin_comb')] # optional - pynormaliz - sage: p3.is_effective(Hstar,Hlin) # optional - pynormaliz + sage: Hstar = p3.Hstar_function(S3) # optional - pynormaliz + sage: Hlin = p3.Hstar_function(S3, # optional - pynormaliz + ....: output='Hstar_as_lin_comb')] + sage: p3.is_effective(Hstar, Hlin) # optional - pynormaliz True If the `H^*`-series is not polynomial, then it is not effective:: - sage: P = Polyhedron(vertices=[[0,0,1],[0,0,-1],[1,0,1],[-1,0,-1],[0,1,1], # optional - pynormaliz - ....: [0,-1,-1],[1,1,1],[-1,-1,-1]], + sage: P = Polyhedron(vertices=[[0,0,1], [0,0,-1], [1,0,1], # optional - pynormaliz + ....: [-1,0,-1], [0,1,1], + ....: [0,-1,-1], [1,1,1], [-1,-1,-1]], ....: backend='normaliz') - sage: G = P.restricted_automorphism_group(output = 'permutation') # optional - pynormaliz - sage: H = G.subgroup(gens = [G([(0,2),(1,3),(4,6),(5,7)])]) # optional - pynormaliz - sage: Hstar = P.Hstar_function(H); Hstar # optional - pynormaliz - (chi_0*t^4 + (3*chi_0 + 3*chi_1)*t^3 + (8*chi_0 + 2*chi_1)*t^2 + (3*chi_0 + 3*chi_1)*t + chi_0)/(t + 1) - sage: Hstar_lin = P.Hstar_function(H, output = 'Hstar_as_lin_comb') # optional - pynormaliz - sage: P.is_effective(Hstar, Hstar_lin) # optional - pynormaliz + sage: G = P.restricted_automorphism_group( # optional - pynormaliz + ....: output='permutation') + sage: H = G.subgroup(gens=[G([(0,2),(1,3),(4,6),(5,7)])]) # optional - pynormaliz + sage: Hstar = P.Hstar_function(H); Hstar # optional - pynormaliz + (chi_0*t^4 + (3*chi_0 + 3*chi_1)*t^3 + + (8*chi_0 + 2*chi_1)*t^2 + (3*chi_0 + 3*chi_1)*t + chi_0)/(t + 1) + sage: Hstar_lin = P.Hstar_function(H, # optional - pynormaliz + ....: output='Hstar_as_lin_comb') + sage: P.is_effective(Hstar, Hstar_lin) # optional - pynormaliz False """ if self.is_empty(): @@ -1190,7 +1215,7 @@ def _is_effective_normaliz(self, Hstar, Hstar_as_lin_comb): Test for the effectiveness of the ``Hstar`` series of this polytope. The ``Hstar`` series of the polytope is determined by the action of a - subgroup of the polytope's ``restricted_automorphism_group``. The + subgroup of the polytope's :meth:`restricted_automorphism_group`. The ``Hstar`` series is effective if it is a polynomial in `t` and the coefficient of each `t^i` is an effective character in the ring of class functions of the acting group. A character `\rho` is effective if @@ -1213,10 +1238,12 @@ class functions of the acting group. A character `\rho` is effective if TESTS:: - sage: p1 = Polyhedron(vertices = [[0],[1/2]]); - sage: p2 = Polyhedron(vertices = [[0],[1/2]], backend='normaliz') # optional - pynormaliz - sage: [Hstar,Hstarlin] = [p2.Hstar_function(),p2.Hstar_function(output='Hstar_as_lin_comb')] # optional - pynormaliz - sage: p1._is_effective_normaliz(Hstar,Hstarlin) # optional - pynormaliz + sage: p1 = Polyhedron(vertices=[[0], [1/2]]) + sage: p2 = Polyhedron(vertices=[[0], [1/2]], # optional - pynormaliz + ....: backend='normaliz') + sage: Hstar = p2.Hstar_function() # optional - pynormaliz + sage: Hstarlin = p2.Hstar_function(output='Hstar_as_lin_comb')] # optional - pynormaliz + sage: p1._is_effective_normaliz(Hstar, Hstarlin) # optional - pynormaliz Traceback (most recent call last): ... TypeError: the backend of the polyhedron should be 'normaliz' diff --git a/src/sage/geometry/polyhedron/base_RDF.py b/src/sage/geometry/polyhedron/base_RDF.py index b97323c280f..fe75503edf2 100644 --- a/src/sage/geometry/polyhedron/base_RDF.py +++ b/src/sage/geometry/polyhedron/base_RDF.py @@ -1,3 +1,5 @@ +# sage.doctest: optional - sage.rings.real_double + """ Base class for polyhedra over ``RDF`` """ diff --git a/src/sage/geometry/polyhedron/base_number_field.py b/src/sage/geometry/polyhedron/base_number_field.py index c802207303f..40b9017dc53 100644 --- a/src/sage/geometry/polyhedron/base_number_field.py +++ b/src/sage/geometry/polyhedron/base_number_field.py @@ -32,9 +32,9 @@ def _number_field_elements_from_algebraics_list_of_lists_of_lists(listss, **kwds EXAMPLES:: - sage: rt2 = AA(sqrt(2)); rt2 # optional - sage.rings.number_field + sage: rt2 = AA(sqrt(2)); rt2 # optional - sage.rings.number_field 1.414213562373095? - sage: rt3 = AA(sqrt(3)); rt3 # optional - sage.rings.number_field + sage: rt3 = AA(sqrt(3)); rt3 # optional - sage.rings.number_field 1.732050807568878? sage: from sage.geometry.polyhedron.base_number_field import _number_field_elements_from_algebraics_list_of_lists_of_lists sage: K, results, hom = _number_field_elements_from_algebraics_list_of_lists_of_lists([[[rt2], [1]], [[rt3]], [[1], []]]); results # optional - sage.rings.number_field @@ -58,39 +58,41 @@ def _compute_data_lists_and_internal_base_ring(self, data_lists, convert_QQ, con EXAMPLES:: - sage: p = Polyhedron(vertices=[(0,1/2),(2,0),(4,5/6)], # optional - pynormaliz + sage: p = Polyhedron(vertices=[(0,1/2), (2,0), (4,5/6)], # optional - pynormaliz ....: base_ring=AA, backend='normaliz') - sage: def convert_QQ(ieqs, eqs): # optional - pynormaliz - ....: return [ [ 1000*x for x in ieq ] for ieq in ieqs], \ - ....: [ [ 1000*x for x in eq ] for eq in eqs] - sage: def convert_NF(ieqs, eqs): # optional - pynormaliz + sage: def convert_QQ(ieqs, eqs): # optional - pynormaliz + ....: return [[1000*x for x in ieq] for ieq in ieqs], \ + ....: [[1000*x for x in eq] for eq in eqs] + sage: def convert_NF(ieqs, eqs): # optional - pynormaliz ....: return ieqs, eqs - sage: p._compute_data_lists_and_internal_base_ring([[[1]], [[1/2]]], # optional - pynormaliz - ....: convert_QQ, convert_NF) + sage: p._compute_data_lists_and_internal_base_ring( # optional - pynormaliz + ....: [[[1]], [[1/2]]], convert_QQ, convert_NF) (([[1000]], [[500]]), Rational Field) - sage: p._compute_data_lists_and_internal_base_ring([[[AA(1)]], [[1/2]]], # optional - pynormaliz - ....: convert_QQ, convert_NF) + sage: p._compute_data_lists_and_internal_base_ring( # optional - pynormaliz + ....: [[[AA(1)]], [[1/2]]], convert_QQ, convert_NF) (([[1000]], [[500]]), Rational Field) - sage: p._compute_data_lists_and_internal_base_ring([[[AA(sqrt(2))]], [[1/2]]], # optional - pynormaliz # optional - sage.rings.number_field - ....: convert_QQ, convert_NF) + sage: p._compute_data_lists_and_internal_base_ring( # optional - pynormaliz sage.rings.number_field + ....: [[[AA(sqrt(2))]], [[1/2]]], convert_QQ, convert_NF) ([[[a]], [[1/2]]], Number Field in a with defining polynomial y^2 - 2 with a = 1.414213562373095?) TESTS:: - sage: K. = QuadraticField(-5) # optional - sage.rings.number_field - sage: p = Polyhedron(vertices=[(a,1/2),(2,0),(4,5/6)], # indirect doctest # optional - pynormaliz # optional - sage.rings.number_field - ....: base_ring=K, backend='normaliz') + sage: K. = QuadraticField(-5) # optional - sage.rings.number_field + sage: p = Polyhedron(base_ring=K, # indirect doctest # optional - pynormaliz sage.rings.number_field + ....: backend='normaliz', + ....: vertices=[(a,1/2), (2,0), (4,5/6)]) Traceback (most recent call last): ... ValueError: invalid base ring: Number Field in a ... is not real embedded Checks that :trac:`30248` is fixed:: - sage: q = Polyhedron(backend='normaliz', base_ring=AA, # indirect doctest # optional - pynormaliz # optional - sage.rings.number_field + sage: q = Polyhedron(base_ring=AA, # indirect doctest # optional - pynormaliz sage.rings.number_field + ....: backend='normaliz', ....: rays=[(0, 0, 1), (0, 1, -1), (1, 0, -1)]); q A 3-dimensional polyhedron in AA^3 defined as the convex hull of 1 vertex and 3 rays - sage: -q # optional - pynormaliz # optional - sage.rings.number_field + sage: -q # optional - pynormaliz sage.rings.number_field A 3-dimensional polyhedron in AA^3 defined as the convex hull of 1 vertex and 3 rays """ from sage.categories.number_fields import NumberFields diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd index 494213512ff..bdd49225ff2 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd @@ -42,12 +42,24 @@ cdef class CombinatorialPolyhedron(SageObject): cdef tuple far_face_tuple(self) cdef int _algorithm_to_dual(self, algorithm) except -2 + # Methods to initialize the combinatorial polyhedron. + cdef _init_from_polyhedron(self, data) + cdef _init_from_lattice_polytope(self, data) + cdef _init_from_cone(self, data) + cdef _init_facet_names(self, facets) + cdef _init_from_incidence_matrix(self, data) + cdef _init_from_list_of_facets(self, data) + cdef _init_from_ListOfFaces(self, ListOfFaces facets, ListOfFaces Vrep) + cdef _initialize_far_face(self) + cdef _init_as_trivial_polyhedron(self, int dimension) + # Methods to obtain a different combinatorial polyhedron. cpdef CombinatorialPolyhedron dual(self) cpdef CombinatorialPolyhedron pyramid(self, new_vertex=*, new_facet=*) cdef FaceIterator _face_iter(self, bint dual, int dimension) cdef int _compute_f_vector(self, size_t num_threads, size_t parallelization_depth, int dual) except -1 + cdef int _persist_f_vector(self, size_t* input_f_vector, bint input_is_reversed) except -1 cdef inline int _compute_edges(self, dual) except -1: return self._compute_edges_or_ridges(dual, True) @@ -57,7 +69,7 @@ cdef class CombinatorialPolyhedron(SageObject): cdef int _compute_edges_or_ridges(self, int dual, bint do_edges) except -1 cdef size_t _compute_edges_or_ridges_with_iterator( - self, FaceIterator face_iter, const bint do_atom_rep, const bint do_f_vector, + self, FaceIterator face_iter, const bint do_atom_rep, ListOfPairs edges, size_t* f_vector) except -1 cdef int _compute_face_lattice_incidences(self) except -1 diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index a415bc44671..4461d14bda7 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -49,14 +49,14 @@ Obtaining edges and ridges:: Vertex-graph and facet-graph:: - sage: C.vertex_graph() # optional - sage.graphs + sage: C.vertex_graph() # optional - sage.graphs Graph on 16 vertices - sage: C.facet_graph() # optional - sage.graphs + sage: C.facet_graph() # optional - sage.graphs Graph on 8 vertices Face lattice:: - sage: C.face_lattice() # optional - sage.combinat + sage: C.face_lattice() # optional - sage.combinat Finite lattice containing 82 elements Face iterator:: @@ -329,7 +329,7 @@ cdef class CombinatorialPolyhedron(SageObject): Traceback (most recent call last): ... ValueError: the combinatorial polyhedron was not initialized - sage: C.face_lattice() # optional - sage.combinat + sage: C.face_lattice() # optional - sage.combinat Traceback (most recent call last): ... ValueError: the combinatorial polyhedron was not initialized @@ -360,66 +360,92 @@ cdef class CombinatorialPolyhedron(SageObject): sage: TestSuite(sage.geometry.polyhedron.combinatorial_polyhedron.base.CombinatorialPolyhedron).run() """ - data_modified = None + self._equations = () + self._far_face_tuple = () if isinstance(data, Polyhedron_base): - # input is ``Polyhedron`` - Vrep = data.Vrepresentation() - facets = tuple(inequality for inequality in data.Hrepresentation()) - self._dimension = data.dimension() - - if not data.is_compact(): - self._bounded = False - far_face = tuple(i for i in range(data.n_Vrepresentation()) if not data.Vrepresentation()[i].is_vertex()) - else: - self._bounded = True - - P = data - data = data.incidence_matrix() - - # Delete equations - if P.n_equations(): - data_modified = data.delete_columns([e.index() for e in P.equations()]) - else: - data_modified = data - elif isinstance(data, LatticePolytopeClass): - # input is ``LatticePolytope`` - self._bounded = True - Vrep = data.vertices() - self._n_Vrepresentation = len(Vrep) - facets = tuple(data.facet_normals()) - self._n_Hrepresentation = len(facets) - data = data.incidence_matrix() - elif isinstance(data, ConvexRationalPolyhedralCone): - # input is ``Cone`` - self._bounded = False - Vrep = tuple(data.rays()) + (data.lattice().zero(),) - self._n_Vrepresentation = len(Vrep) - facets = tuple(data.facet_normals()) - self._n_Hrepresentation = len(facets) - far_face = tuple(i for i in range(len(Vrep) - 1)) - self._dimension = data.dim() - from sage.matrix.constructor import matrix - from sage.rings.integer_ring import ZZ - data = matrix(ZZ, data.incidence_matrix().rows() - + [[ZZ.one() for _ in range(len(facets))]]) - else: - # Input is different from ``Polyhedron`` and ``LatticePolytope``. - if unbounded and not far_face: + self._init_from_polyhedron(data) + return + if isinstance(data, LatticePolytopeClass): + self._init_from_lattice_polytope(data) + return + if isinstance(data, ConvexRationalPolyhedralCone): + self._init_from_cone(data) + return + + self._bounded = not unbounded + if unbounded: + if not far_face: raise ValueError("must specify far face for unbounded polyhedron") - - self._bounded = not unbounded + self._far_face_tuple = tuple(far_face) if Vrep: - # store vertices names self._Vrep = tuple(Vrep) - Vinv = {v: i for i,v in enumerate(self._Vrep)} + + self._init_facet_names(facets) + + if data == [] or data == (): + self._init_as_trivial_polyhedron(-1) + elif isinstance(data, Matrix): + self._init_from_incidence_matrix(data) + elif isinstance(data, numbers.Integral): + self._init_as_trivial_polyhedron(data) + elif (isinstance(data, (tuple, list)) and + len(data) == 2 and + isinstance(data[0], ListOfFaces) and + isinstance(data[1], ListOfFaces)): + self._init_from_ListOfFaces(data[0], data[1]) + + else: + self._init_from_list_of_facets(data) + + cdef _init_from_polyhedron(self, data): + r''' + Initialize from :class:`~sage.geometry.polyhedron.parent.Polyhedron_base`. + ''' + self._Vrep = data.Vrepresentation() + self._facet_names = data.inequalities() + self._equations = data.equations() + self._dimension = data.dimension() + + if not data.is_compact(): + self._bounded = False + self._far_face_tuple = tuple(i for i in range(data.n_Vrepresentation()) if not data.Vrepresentation()[i].is_vertex()) else: - self._Vrep = None - Vinv = None + self._bounded = True - if facets: - # store facets names and compute equations + return self._init_from_incidence_matrix(data.incidence_matrix()) + + cdef _init_from_lattice_polytope(self, data): + r''' + Initialize from :class:`~sage.geometry.lattice_polytope.LatticePolytopeClass`. + ''' + self._bounded = True + self._Vrep = tuple(data.vertices()) + self._facet_names = tuple(data.facet_normals()) + self._dimension = data.dimension() + return self._init_from_incidence_matrix(data.incidence_matrix()) + + cdef _init_from_cone(self, data): + r''' + Initialize from :class:`~sage.geometry.cone.ConvexRationalPolyhedralCone`. + ''' + self._bounded = False + self._Vrep = tuple(data.rays()) + (data.lattice().zero(),) + self._facet_names = tuple(data.facet_normals()) + self._far_face_tuple = tuple(i for i in range(len(self._Vrep) - 1)) + self._dimension = data.dim() + from sage.matrix.constructor import matrix + from sage.rings.integer_ring import ZZ + incidence_matrix = matrix(ZZ, data.incidence_matrix().rows() + + [[ZZ.one() for _ in range(len(data.facet_normals()))]]) + return self._init_from_incidence_matrix(incidence_matrix) + + cdef _init_facet_names(self, facets): + ''' + Store facet names and compute equations. + ''' + if facets is not None: facets = tuple(facets) test = [1] * len(facets) # 0 if that facet is an equation @@ -436,127 +462,129 @@ cdef class CombinatorialPolyhedron(SageObject): else: self._facet_names = None - if data == [] or data == (): - # Handling the empty polyhedron. - data = -1 - - if isinstance(data, Matrix): - # Input is incidence-matrix or was converted to it. - self._n_Hrepresentation = data.ncols() - self._n_Vrepresentation = data.nrows() - - if not isinstance(data, Matrix_dense): - from sage.rings.integer_ring import ZZ - from sage.matrix.constructor import matrix - data = matrix(ZZ, data, sparse=False) - assert isinstance(data, Matrix_dense), "conversion to ``Matrix_dense`` didn't work" + cdef _init_from_incidence_matrix(self, data): + """ + Initialize from an incidence matrix. + """ + # Input is incidence-matrix or was converted to it. + self._n_Hrepresentation = data.ncols() + self._n_Vrepresentation = data.nrows() - # Store the incidence matrix. - if not data.is_immutable(): - data = data.__copy__() - data.set_immutable() - self.incidence_matrix.set_cache(data) + if not isinstance(data, Matrix_dense): + from sage.rings.integer_ring import ZZ + from sage.matrix.constructor import matrix + data = matrix(ZZ, data, sparse=False) + assert isinstance(data, Matrix_dense), "conversion to ``Matrix_dense`` didn't work" + # Store the incidence matrix. + if not data.is_immutable(): + data = data.__copy__() + data.set_immutable() + self.incidence_matrix.set_cache(data) - if data_modified is None: - # Delete equations. - data_modified = data.delete_columns([i for i in range(data.ncols()) if all(data[j,i] for j in range(data.nrows()))], check=False) - # Initializing the facets in their Bit-representation. - self._bitrep_facets = incidence_matrix_to_bit_rep_of_facets(data_modified) + # Delete equations. + data = data.delete_columns( + [i for i in range(data.ncols()) + if all(data[j,i] for j in range(data.nrows()))], + check=False) - # Initializing the Vrep as their Bit-representation. - self._bitrep_Vrep = incidence_matrix_to_bit_rep_of_Vrep(data_modified) + # Initializing the facets in their Bit-representation. + self._bitrep_facets = incidence_matrix_to_bit_rep_of_facets(data) - self._n_facets = self.bitrep_facets().n_faces() + # Initializing the Vrep as their Bit-representation. + self._bitrep_Vrep = incidence_matrix_to_bit_rep_of_Vrep(data) - # Initialize far_face if unbounded. - if not self._bounded: - face_init(self._far_face, self.bitrep_facets().n_atoms(), self._n_facets) - Vrep_list_to_bit_rep(tuple(far_face), self._far_face) + self._n_facets = self.bitrep_facets().n_faces() - elif isinstance(data, numbers.Integral): - # To construct a trivial polyhedron, equal to its affine hull, - # one can give an Integer as Input. - if data < -1: - raise ValueError("any polyhedron must have dimension at least -1") - self._dimension = data - - if self._dimension == 0: - self._n_facets = 1 - self._n_Vrepresentation = 1 - else: - self._n_facets = 0 - self._n_Vrepresentation = 0 + self._initialize_far_face() - # Initializing the facets in their Bit-representation. - self._bitrep_facets = facets_tuple_to_bit_rep_of_facets((), 0) + cdef _init_from_list_of_facets(self, data): + """ + Initialize from a list of facets. - # Initializing the Vrep as their Bit-representation. - self._bitrep_Vrep = facets_tuple_to_bit_rep_of_Vrep((), 0) + Tuple and iterator work as well. - elif isinstance(data, (tuple, list)) and len(data) == 2 and isinstance(data[0], ListOfFaces) and isinstance(data[1], ListOfFaces): - # Initialize self from two ``ListOfFaces``. - self._bitrep_facets = data[0] - self._bitrep_Vrep = data[1] + The facets are given by its ``[vertices, rays, lines]``. + """ + if is_iterator(data): + data = tuple(data) - self._n_Hrepresentation = self._bitrep_facets.n_faces() - self._n_Vrepresentation = self._bitrep_Vrep.n_faces() - self._n_facets = self._n_Hrepresentation + if self._Vrep is None: + # Get the names of the Vrep. + Vrep = sorted(set.union(*map(set, data))) + n_Vrepresentation = len(Vrep) + if Vrep != range(len(Vrep)): + self._Vrep = tuple(Vrep) + Vinv = {v: i for i,v in enumerate(self._Vrep)} + else: + # Assuming the user gave as correct names for the vertices + # and labeled them instead by `0,...,n`. + n_Vrepresentation = len(self._Vrep) - # Initialize far_face if unbounded. - if not self._bounded: - face_init(self._far_face, self.bitrep_facets().n_atoms(), self._n_facets) - Vrep_list_to_bit_rep(tuple(far_face), self._far_face) + self._n_Vrepresentation = n_Vrepresentation + # Relabel the Vrep to be `0,...,n`. + if self._Vrep is not None: + def f(v): + return Vinv[v] else: - # Input is a "list" of facets. - # The facets given by its ``[vertices, rays, lines]``. - # Actually at least tuple, list, iterator will work. - if is_iterator(data): - data = tuple(data) - - if self._Vrep is None: - # Get the names of the Vrep. - Vrep = sorted(set.union(*map(set, data))) - n_Vrepresentation = len(Vrep) - if Vrep != range(len(Vrep)): - self._Vrep = tuple(Vrep) - Vinv = {v: i for i,v in enumerate(self._Vrep)} - else: - # Assuming the user gave as correct names for the vertices - # and labeled them instead by `0,...,n`. - n_Vrepresentation = len(self._Vrep) + def f(v): + return int(v) + facets = tuple(tuple(f(i) for i in j) for j in data) - self._n_Vrepresentation = n_Vrepresentation + self._n_facets = len(facets) + self._n_Hrepresentation = len(facets) - # Relabel the Vrep to be `0,...,n`. - if self._Vrep is not None: - def f(v): - return Vinv[v] - else: - def f(v): - return int(v) - facets = tuple(tuple(f(i) for i in j) for j in data) + # Initializing the facets in their Bit-representation. + self._bitrep_facets = facets_tuple_to_bit_rep_of_facets(facets, n_Vrepresentation) - self._n_facets = len(facets) - self._n_Hrepresentation = len(facets) + # Initializing the Vrep as their Bit-representation. + self._bitrep_Vrep = facets_tuple_to_bit_rep_of_Vrep(facets, n_Vrepresentation) - # Initializing the facets in their Bit-representation. - self._bitrep_facets = facets_tuple_to_bit_rep_of_facets(facets, n_Vrepresentation) + self._initialize_far_face() - # Initializing the Vrep as their Bit-representation. - self._bitrep_Vrep = facets_tuple_to_bit_rep_of_Vrep(facets, n_Vrepresentation) + cdef _init_from_ListOfFaces(self, ListOfFaces facets, ListOfFaces Vrep): + """ + Initialize self from two ``ListOfFaces``. + """ + self._bitrep_facets = facets + self._bitrep_Vrep = Vrep - # Initialize far_face if unbounded. - if not self._bounded: - face_init(self._far_face, self.bitrep_facets().n_atoms(), self._n_facets) - Vrep_list_to_bit_rep(tuple(far_face), self._far_face) + self._n_Hrepresentation = self._bitrep_facets.n_faces() + self._n_Vrepresentation = self._bitrep_Vrep.n_faces() + self._n_facets = self._n_Hrepresentation + self._initialize_far_face() + + cdef _initialize_far_face(self): + """ + Initialize far_face if unbounded. + """ if not self._bounded: - self._far_face_tuple = tuple(far_face) + face_init(self._far_face, self.bitrep_facets().n_atoms(), self._n_facets) + Vrep_list_to_bit_rep(tuple(self._far_face_tuple), self._far_face) + + cdef _init_as_trivial_polyhedron(self, int dimension): + """ + Initialize polyhedron equal to its affine hull. + """ + if dimension < -1: + raise ValueError("any polyhedron must have dimension at least -1") + self._dimension = dimension + + if self._dimension == 0: + self._n_facets = 1 + self._n_Vrepresentation = 1 else: - self._far_face_tuple = () + self._n_facets = 0 + self._n_Vrepresentation = 0 + + # Initializing the facets in their Bit-representation. + self._bitrep_facets = facets_tuple_to_bit_rep_of_facets((), 0) + + # Initializing the Vrep as their Bit-representation. + self._bitrep_Vrep = facets_tuple_to_bit_rep_of_Vrep((), 0) def __dealloc__(self): """ @@ -613,16 +641,16 @@ cdef class CombinatorialPolyhedron(SageObject): TESTS:: - sage: P = polytopes.permutahedron(4) # optional - sage.combinat - sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat - sage: C1 = loads(C.dumps()) # optional - sage.combinat - sage: it = C.face_generator() # optional - sage.combinat - sage: it1 = C1.face_generator() # optional - sage.combinat - sage: tup = tuple((face.ambient_Vrepresentation(), # optional - sage.combinat + sage: P = polytopes.permutahedron(4) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: C1 = loads(C.dumps()) # optional - sage.combinat + sage: it = C.face_generator() # optional - sage.combinat + sage: it1 = C1.face_generator() # optional - sage.combinat + sage: tup = tuple((face.ambient_Vrepresentation(), # optional - sage.combinat ....: face.ambient_Hrepresentation()) for face in it) - sage: tup1 = tuple((face.ambient_Vrepresentation(), # optional - sage.combinat + sage: tup1 = tuple((face.ambient_Vrepresentation(), # optional - sage.combinat ....: face.ambient_Hrepresentation()) for face in it1) - sage: tup == tup1 # optional - sage.combinat + sage: tup == tup1 # optional - sage.combinat True sage: P = polytopes.cyclic_polytope(4,10) @@ -720,9 +748,9 @@ cdef class CombinatorialPolyhedron(SageObject): EXAMPLES:: - sage: P = polytopes.permutahedron(3) # optional - sage.combinat - sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat - sage: C.Hrepresentation() # optional - sage.combinat + sage: P = polytopes.permutahedron(3) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: C.Hrepresentation() # optional - sage.combinat (An inequality (1, 1, 0) x - 3 >= 0, An inequality (-1, -1, 0) x + 5 >= 0, An inequality (0, 1, 0) x - 1 >= 0, @@ -1077,10 +1105,10 @@ cdef class CombinatorialPolyhedron(SageObject): :: - sage: P = polytopes.permutahedron(5, backend='field') # optional - sage.combinat - sage: C = P.combinatorial_polyhedron() # optional - sage.combinat - sage: C.incidence_matrix.clear_cache() # optional - sage.combinat - sage: C.incidence_matrix() == P.incidence_matrix() # optional - sage.combinat + sage: P = polytopes.permutahedron(5, backend='field') # optional - sage.combinat + sage: C = P.combinatorial_polyhedron() # optional - sage.combinat + sage: C.incidence_matrix.clear_cache() # optional - sage.combinat + sage: C.incidence_matrix() == P.incidence_matrix() # optional - sage.combinat True The incidence matrix is consistent with @@ -1257,15 +1285,14 @@ cdef class CombinatorialPolyhedron(SageObject): sage: P = polytopes.cyclic_polytope(3,5) sage: C = CombinatorialPolyhedron(P) - sage: C.vertex_graph() + sage: G = C.vertex_graph(); G # optional - sage.graphs Graph on 5 vertices - sage: G = C.vertex_graph() - sage: sorted(G.degree()) + sage: sorted(G.degree()) # optional - sage.graphs [3, 3, 4, 4, 4] sage: P = Polyhedron(rays=[[1]]) sage: C = CombinatorialPolyhedron(P) - sage: C.graph() + sage: C.graph() # optional - sage.graphs Graph on 1 vertex """ vertices = self.vertices(names=names) @@ -1366,11 +1393,11 @@ cdef class CombinatorialPolyhedron(SageObject): EXAMPLES:: - sage: P = polytopes.permutahedron(2) # optional - sage.combinat - sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat - sage: C.ridges() # optional - sage.combinat + sage: P = polytopes.permutahedron(2) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: C.ridges() # optional - sage.combinat ((An inequality (1, 0) x - 1 >= 0, An inequality (-1, 0) x + 2 >= 0),) - sage: C.ridges(add_equations=True) # optional - sage.combinat + sage: C.ridges(add_equations=True) # optional - sage.combinat (((An inequality (1, 0) x - 1 >= 0, An equation (1, 1) x - 3 == 0), (An inequality (-1, 0) x + 2 >= 0, An equation (1, 1) x - 3 == 0)),) @@ -1539,25 +1566,25 @@ cdef class CombinatorialPolyhedron(SageObject): sage: P = polytopes.cyclic_polytope(4,6) sage: C = CombinatorialPolyhedron(P) - sage: C.facet_graph() + sage: C.facet_graph() # optional - sage.graphs Graph on 9 vertices TESTS:: sage: P = Polyhedron(ieqs=[[1,-1,0],[1,1,0]]) - sage: CombinatorialPolyhedron(P).facet_graph() + sage: CombinatorialPolyhedron(P).facet_graph() # optional - sage.graphs Graph on 2 vertices Checking that :trac:`28604` is fixed:: sage: C = CombinatorialPolyhedron(polytopes.cube()); C A 3-dimensional combinatorial polyhedron with 6 facets - sage: C.facet_graph(names=False) + sage: C.facet_graph(names=False) # optional - sage.graphs Graph on 6 vertices - sage: C = CombinatorialPolyhedron(polytopes.hypersimplex(5,2)); C + sage: C = CombinatorialPolyhedron(polytopes.hypersimplex(5,2)); C # optional - sage.combinat A 4-dimensional combinatorial polyhedron with 10 facets - sage: C.facet_graph() + sage: C.facet_graph() # optional - sage.graphs sage.combinat Graph on 10 vertices """ face_iter = self.face_iter(self.dimension() - 1, algorithm='primal') @@ -1595,7 +1622,7 @@ cdef class CombinatorialPolyhedron(SageObject): sage: P = polytopes.hypercube(2).pyramid() sage: C = CombinatorialPolyhedron(P) - sage: G = C.vertex_facet_graph(); G + sage: G = C.vertex_facet_graph(); G # optional - sage.graphs Digraph on 10 vertices sage: C.Vrepresentation() (A vertex at (0, -1, -1), @@ -1603,7 +1630,7 @@ cdef class CombinatorialPolyhedron(SageObject): A vertex at (0, 1, -1), A vertex at (0, 1, 1), A vertex at (1, 0, 0)) - sage: sorted(G.neighbors_out(C.Vrepresentation()[4])) + sage: sorted(G.neighbors_out(C.Vrepresentation()[4])) # optional - sage.graphs [An inequality (-1, -1, 0) x + 1 >= 0, An inequality (-1, 0, -1) x + 1 >= 0, An inequality (-1, 0, 1) x + 1 >= 0, @@ -1616,7 +1643,7 @@ cdef class CombinatorialPolyhedron(SageObject): with a string 'H' or 'V':: sage: C = CombinatorialPolyhedron(P.incidence_matrix()) - sage: C.vertex_facet_graph().vertices(sort=True) + sage: C.vertex_facet_graph().vertices(sort=True) # optional - sage.graphs [('H', 0), ('H', 1), ('H', 2), @@ -1630,18 +1657,18 @@ cdef class CombinatorialPolyhedron(SageObject): If ``names`` is ``False`` then the vertices of the graph are given by integers:: - sage: C.vertex_facet_graph(names=False).vertices(sort=True) + sage: C.vertex_facet_graph(names=False).vertices(sort=True) # optional - sage.graphs [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] TESTS: Test that :trac:`29898` is fixed:: - sage: Polyhedron().vertex_facet_graph() + sage: Polyhedron().vertex_facet_graph() # optional - sage.graphs Digraph on 0 vertices - sage: Polyhedron([[0]]).vertex_facet_graph() + sage: Polyhedron([[0]]).vertex_facet_graph() # optional - sage.graphs Digraph on 1 vertex - sage: Polyhedron([[0]]).vertex_facet_graph(False) + sage: Polyhedron([[0]]).vertex_facet_graph(False) # optional - sage.graphs Digraph on 1 vertex """ from sage.graphs.digraph import DiGraph @@ -1710,9 +1737,9 @@ cdef class CombinatorialPolyhedron(SageObject): EXAMPLES:: - sage: P = polytopes.permutahedron(5) # optional - sage.combinat - sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat - sage: C.f_vector() # optional - sage.combinat + sage: P = polytopes.permutahedron(5) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: C.f_vector() # optional - sage.combinat (1, 120, 240, 150, 30, 1) sage: P = polytopes.cyclic_polytope(6,10) @@ -1722,9 +1749,9 @@ cdef class CombinatorialPolyhedron(SageObject): Using two threads:: - sage: P = polytopes.permutahedron(5) # optional - sage.combinat - sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat - sage: C.f_vector(num_threads=2) # optional - sage.combinat + sage: P = polytopes.permutahedron(5) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: C.f_vector(num_threads=2) # optional - sage.combinat (1, 120, 240, 150, 30, 1) TESTS:: @@ -1782,7 +1809,7 @@ cdef class CombinatorialPolyhedron(SageObject): Obtain the entire flag-f-vector:: sage: C = polytopes.hypercube(4).combinatorial_polyhedron() - sage: C.flag_f_vector() # optional - sage.combinat + sage: C.flag_f_vector() # optional - sage.combinat {(-1,): 1, (0,): 16, (0, 1): 64, @@ -1803,38 +1830,38 @@ cdef class CombinatorialPolyhedron(SageObject): Specify an entry:: - sage: C.flag_f_vector(0,3) # optional - sage.combinat + sage: C.flag_f_vector(0,3) # optional - sage.combinat 64 - sage: C.flag_f_vector(2) # optional - sage.combinat + sage: C.flag_f_vector(2) # optional - sage.combinat 24 Leading ``-1`` and trailing entry of dimension are allowed:: - sage: C.flag_f_vector(-1,0,3) # optional - sage.combinat + sage: C.flag_f_vector(-1,0,3) # optional - sage.combinat 64 - sage: C.flag_f_vector(-1,0,3,4) # optional - sage.combinat + sage: C.flag_f_vector(-1,0,3,4) # optional - sage.combinat 64 One can get the number of trivial faces:: - sage: C.flag_f_vector(-1) # optional - sage.combinat + sage: C.flag_f_vector(-1) # optional - sage.combinat 1 - sage: C.flag_f_vector(4) # optional - sage.combinat + sage: C.flag_f_vector(4) # optional - sage.combinat 1 Polyhedra with lines, have ``0`` entries accordingly:: sage: C = (Polyhedron(lines=[[1]]) * polytopes.hypercube(2)).combinatorial_polyhedron() - sage: C.flag_f_vector() # optional - sage.combinat + sage: C.flag_f_vector() # optional - sage.combinat {(-1,): 1, (0, 1): 0, (0, 2): 0, (0,): 0, (1, 2): 8, (1,): 4, (2,): 4, 3: 1} If the arguments are not stricly increasing or out of range, a key error is raised:: - sage: C.flag_f_vector(-1,0,3,5) # optional - sage.combinat + sage: C.flag_f_vector(-1,0,3,5) # optional - sage.combinat Traceback (most recent call last): ... KeyError: (0, 3, 5) - sage: C.flag_f_vector(-1,3,0) # optional - sage.combinat + sage: C.flag_f_vector(-1,3,0) # optional - sage.combinat Traceback (most recent call last): ... KeyError: (3, 0) @@ -1862,7 +1889,7 @@ cdef class CombinatorialPolyhedron(SageObject): TESTS:: sage: C = CombinatorialPolyhedron(3) - sage: C._flag_f_vector() # optional - sage.combinat + sage: C._flag_f_vector() # optional - sage.combinat {(-1,): 1, (0, 1): 0, (0, 2): 0, (0,): 0, (1, 2): 0, (1,): 0, (2,): 0, 3: 1} """ poly = self.face_lattice().flag_f_polynomial() @@ -2060,8 +2087,8 @@ cdef class CombinatorialPolyhedron(SageObject): sage: CombinatorialPolyhedron(cyclic).simpliciality() 3 - sage: hypersimplex = polytopes.hypersimplex(5,2) - sage: CombinatorialPolyhedron(hypersimplex).simpliciality() + sage: hypersimplex = polytopes.hypersimplex(5,2) # optional - sage.combinat + sage: CombinatorialPolyhedron(hypersimplex).simpliciality() # optional - sage.combinat 2 sage: cross = polytopes.cross_polytope(4) @@ -2168,16 +2195,16 @@ cdef class CombinatorialPolyhedron(SageObject): EXAMPLES:: - sage: hyper4 = polytopes.hypersimplex(4,2) - sage: CombinatorialPolyhedron(hyper4).simplicity() + sage: hyper4 = polytopes.hypersimplex(4,2) # optional - sage.combinat + sage: CombinatorialPolyhedron(hyper4).simplicity() # optional - sage.combinat 1 - sage: hyper5 = polytopes.hypersimplex(5,2) - sage: CombinatorialPolyhedron(hyper5).simplicity() + sage: hyper5 = polytopes.hypersimplex(5,2) # optional - sage.combinat + sage: CombinatorialPolyhedron(hyper5).simplicity() # optional - sage.combinat 2 - sage: hyper6 = polytopes.hypersimplex(6,2) - sage: CombinatorialPolyhedron(hyper6).simplicity() + sage: hyper6 = polytopes.hypersimplex(6,2) # optional - sage.combinat + sage: CombinatorialPolyhedron(hyper6).simplicity() # optional - sage.combinat 3 sage: P = polytopes.simplex(3) @@ -2605,15 +2632,15 @@ cdef class CombinatorialPolyhedron(SageObject): EXAMPLES:: - sage: P = polytopes.permutahedron(4) # optional - sage.combinat - sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat - sage: C.join_of_Vrep(0,1) # optional - sage.combinat + sage: P = polytopes.permutahedron(4) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: C.join_of_Vrep(0,1) # optional - sage.combinat A 1-dimensional face of a 3-dimensional combinatorial polyhedron - sage: C.join_of_Vrep(0,11).ambient_V_indices() # optional - sage.combinat + sage: C.join_of_Vrep(0,11).ambient_V_indices() # optional - sage.combinat (0, 1, 10, 11, 12, 13) - sage: C.join_of_Vrep(8).ambient_V_indices() # optional - sage.combinat + sage: C.join_of_Vrep(8).ambient_V_indices() # optional - sage.combinat (8,) - sage: C.join_of_Vrep().ambient_V_indices() # optional - sage.combinat + sage: C.join_of_Vrep().ambient_V_indices() # optional - sage.combinat () """ return self.face_generator().join_of_Vrep(*indices) @@ -2628,19 +2655,19 @@ cdef class CombinatorialPolyhedron(SageObject): EXAMPLES:: - sage: P = polytopes.dodecahedron() # optional - sage.rings.number_field - sage: C = CombinatorialPolyhedron(P) # optional - sage.rings.number_field - sage: C.meet_of_Hrep(0) # optional - sage.rings.number_field + sage: P = polytopes.dodecahedron() # optional - sage.rings.number_field + sage: C = CombinatorialPolyhedron(P) # optional - sage.rings.number_field + sage: C.meet_of_Hrep(0) # optional - sage.rings.number_field A 2-dimensional face of a 3-dimensional combinatorial polyhedron - sage: C.meet_of_Hrep(0).ambient_H_indices() # optional - sage.rings.number_field + sage: C.meet_of_Hrep(0).ambient_H_indices() # optional - sage.rings.number_field (0,) - sage: C.meet_of_Hrep(0,1).ambient_H_indices() # optional - sage.rings.number_field + sage: C.meet_of_Hrep(0,1).ambient_H_indices() # optional - sage.rings.number_field (0, 1) - sage: C.meet_of_Hrep(0,2).ambient_H_indices() # optional - sage.rings.number_field + sage: C.meet_of_Hrep(0,2).ambient_H_indices() # optional - sage.rings.number_field (0, 2) - sage: C.meet_of_Hrep(0,2,3).ambient_H_indices() # optional - sage.rings.number_field + sage: C.meet_of_Hrep(0,2,3).ambient_H_indices() # optional - sage.rings.number_field (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) - sage: C.meet_of_Hrep().ambient_H_indices() # optional - sage.rings.number_field + sage: C.meet_of_Hrep().ambient_H_indices() # optional - sage.rings.number_field () """ return self.face_generator().meet_of_Hrep(*indices) @@ -2671,38 +2698,38 @@ cdef class CombinatorialPolyhedron(SageObject): EXAMPLES:: - sage: P = polytopes.permutahedron(5) # optional - sage.combinat - sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat - sage: it = C.face_generator(dimension=2) # optional - sage.combinat - sage: face = next(it); face # optional - sage.combinat + sage: P = polytopes.permutahedron(5) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: it = C.face_generator(dimension=2) # optional - sage.combinat + sage: face = next(it); face # optional - sage.combinat A 2-dimensional face of a 4-dimensional combinatorial polyhedron - sage: face.ambient_Vrepresentation() # optional - sage.combinat + sage: face.ambient_Vrepresentation() # optional - sage.combinat (A vertex at (1, 3, 2, 5, 4), A vertex at (2, 3, 1, 5, 4), A vertex at (3, 1, 2, 5, 4), A vertex at (3, 2, 1, 5, 4), A vertex at (2, 1, 3, 5, 4), A vertex at (1, 2, 3, 5, 4)) - sage: face = next(it); face # optional - sage.combinat + sage: face = next(it); face # optional - sage.combinat A 2-dimensional face of a 4-dimensional combinatorial polyhedron - sage: face.ambient_Vrepresentation() # optional - sage.combinat + sage: face.ambient_Vrepresentation() # optional - sage.combinat (A vertex at (2, 1, 4, 5, 3), A vertex at (3, 2, 4, 5, 1), A vertex at (3, 1, 4, 5, 2), A vertex at (1, 3, 4, 5, 2), A vertex at (1, 2, 4, 5, 3), A vertex at (2, 3, 4, 5, 1)) - sage: face.ambient_Hrepresentation() # optional - sage.combinat + sage: face.ambient_Hrepresentation() # optional - sage.combinat (An inequality (0, 0, -1, -1, 0) x + 9 >= 0, An inequality (0, 0, 0, -1, 0) x + 5 >= 0, An equation (1, 1, 1, 1, 1) x - 15 == 0) - sage: face.ambient_H_indices() # optional - sage.combinat + sage: face.ambient_H_indices() # optional - sage.combinat (25, 29, 30) - sage: face = next(it); face # optional - sage.combinat + sage: face = next(it); face # optional - sage.combinat A 2-dimensional face of a 4-dimensional combinatorial polyhedron - sage: face.ambient_H_indices() # optional - sage.combinat + sage: face.ambient_H_indices() # optional - sage.combinat (24, 29, 30) - sage: face.ambient_V_indices() # optional - sage.combinat + sage: face.ambient_V_indices() # optional - sage.combinat (32, 89, 90, 94) sage: C = CombinatorialPolyhedron([[0,1,2],[0,1,3],[0,2,3],[1,2,3]]) @@ -2814,31 +2841,31 @@ cdef class CombinatorialPolyhedron(SageObject): sage: P = Polyhedron(rays=[[1,0],[0,1]]) sage: C = CombinatorialPolyhedron(P) - sage: C.face_lattice() + sage: C.face_lattice() # optional - sage.combinat Finite lattice containing 5 elements sage: P = Polyhedron(rays=[[1,0,0], [-1,0,0], [0,-1,0], [0,1,0]]) sage: C = CombinatorialPolyhedron(P) sage: P1 = Polyhedron(rays=[[1,0], [-1,0]]) sage: C1 = CombinatorialPolyhedron(P1) - sage: C.face_lattice().is_isomorphic(C1.face_lattice()) + sage: C.face_lattice().is_isomorphic(C1.face_lattice()) # optional - sage.combinat True - sage: P = polytopes.permutahedron(5) # optional - sage.combinat - sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat - sage: C.face_lattice() # optional - sage.combinat + sage: P = polytopes.permutahedron(5) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: C.face_lattice() # optional - sage.combinat Finite lattice containing 542 elements TESTS:: sage: P = polytopes.cyclic_polytope(4,10) sage: C = CombinatorialPolyhedron(P) - sage: C.face_lattice().is_isomorphic(P.face_lattice()) + sage: C.face_lattice().is_isomorphic(P.face_lattice()) # optional - sage.combinat True - sage: P = polytopes.permutahedron(4) # optional - sage.combinat - sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat - sage: C.face_lattice().is_isomorphic(P.face_lattice()) # optional - sage.combinat + sage: P = polytopes.permutahedron(4) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: C.face_lattice().is_isomorphic(P.face_lattice()) # optional - sage.combinat True """ from sage.combinat.posets.lattices import FiniteLatticePoset @@ -2870,18 +2897,18 @@ cdef class CombinatorialPolyhedron(SageObject): sage: P = polytopes.regular_polygon(4).pyramid() # optional - sage.rings.number_field sage: C = CombinatorialPolyhedron(P) # optional - sage.rings.number_field - sage: D = C.hasse_diagram(); D # optional - sage.graphs # optional - sage.rings.number_field + sage: D = C.hasse_diagram(); D # optional - sage.graphs sage.rings.number_field Digraph on 20 vertices - sage: D.average_degree() # optional - sage.graphs # optional - sage.rings.number_field + sage: D.average_degree() # optional - sage.graphs sage.rings.number_field 21/5 - sage: D.relabel(C.face_by_face_lattice_index) # optional - sage.graphs # optional - sage.rings.number_field - sage: dim_0_vert = D.vertices(sort=True)[1:6]; dim_0_vert # optional - sage.graphs # optional - sage.rings.number_field + sage: D.relabel(C.face_by_face_lattice_index) # optional - sage.graphs sage.rings.number_field + sage: dim_0_vert = D.vertices(sort=True)[1:6]; dim_0_vert # optional - sage.graphs sage.rings.number_field [A 0-dimensional face of a 3-dimensional combinatorial polyhedron, A 0-dimensional face of a 3-dimensional combinatorial polyhedron, A 0-dimensional face of a 3-dimensional combinatorial polyhedron, A 0-dimensional face of a 3-dimensional combinatorial polyhedron, A 0-dimensional face of a 3-dimensional combinatorial polyhedron] - sage: sorted(D.out_degree(vertices=dim_0_vert)) # optional - sage.graphs # optional - sage.rings.number_field + sage: sorted(D.out_degree(vertices=dim_0_vert)) # optional - sage.graphs sage.rings.number_field [3, 3, 3, 3, 4] """ if not self._face_lattice_incidences: @@ -2910,12 +2937,12 @@ cdef class CombinatorialPolyhedron(SageObject): sage: P = polytopes.cube() sage: C = CombinatorialPolyhedron(P) - sage: F = C.face_lattice() # optional - sage.combinat + sage: F = C.face_lattice() # optional - sage.combinat sage: def f(i): ....: return (i, C._face_lattice_dimension(i)) ....: - sage: G = F.relabel(f) # optional - sage.combinat - sage: set(G._elements) # optional - sage.combinat + sage: G = F.relabel(f) # optional - sage.combinat + sage: set(G._elements) # optional - sage.combinat {(0, -1), (1, 0), (2, 0), @@ -2966,13 +2993,13 @@ cdef class CombinatorialPolyhedron(SageObject): sage: P = polytopes.cube() sage: C = CombinatorialPolyhedron(P) - sage: F = C.face_lattice() # optional - sage.combinat - sage: F # optional - sage.combinat + sage: F = C.face_lattice() # optional - sage.combinat + sage: F # optional - sage.combinat Finite lattice containing 28 elements - sage: G = F.relabel(C.face_by_face_lattice_index) # optional - sage.combinat - sage: G.level_sets()[0] # optional - sage.combinat + sage: G = F.relabel(C.face_by_face_lattice_index) # optional - sage.combinat + sage: G.level_sets()[0] # optional - sage.combinat [A -1-dimensional face of a 3-dimensional combinatorial polyhedron] - sage: G.level_sets()[3] # optional - sage.combinat + sage: G.level_sets()[3] # optional - sage.combinat [A 2-dimensional face of a 3-dimensional combinatorial polyhedron, A 2-dimensional face of a 3-dimensional combinatorial polyhedron, A 2-dimensional face of a 3-dimensional combinatorial polyhedron, @@ -2982,9 +3009,9 @@ cdef class CombinatorialPolyhedron(SageObject): sage: P = Polyhedron(rays=[[0,1], [1,0]]) sage: C = CombinatorialPolyhedron(P) - sage: F = C.face_lattice() # optional - sage.combinat - sage: G = F.relabel(C.face_by_face_lattice_index) # optional - sage.combinat - sage: G._elements # optional - sage.combinat + sage: F = C.face_lattice() # optional - sage.combinat + sage: G = F.relabel(C.face_by_face_lattice_index) # optional - sage.combinat + sage: G._elements # optional - sage.combinat (A -1-dimensional face of a 2-dimensional combinatorial polyhedron, A 0-dimensional face of a 2-dimensional combinatorial polyhedron, A 1-dimensional face of a 2-dimensional combinatorial polyhedron, @@ -2992,8 +3019,8 @@ cdef class CombinatorialPolyhedron(SageObject): A 2-dimensional face of a 2-dimensional combinatorial polyhedron) sage: def f(i): return C.face_by_face_lattice_index(i).ambient_V_indices() - sage: G = F.relabel(f) # optional - sage.combinat - sage: G._elements # optional - sage.combinat + sage: G = F.relabel(f) # optional - sage.combinat + sage: G._elements # optional - sage.combinat ((), (0,), (0, 1), (0, 2), (0, 1, 2)) """ self._record_all_faces() # Initialize ``_all_faces``, if not done yet. @@ -3038,13 +3065,13 @@ cdef class CombinatorialPolyhedron(SageObject): sage: [face.ambient_V_indices() for face in chain] [(15,), (6, 15), (5, 6, 14, 15), (0, 5, 6, 7, 8, 9, 14, 15)] - sage: P = polytopes.permutahedron(4) # optional - sage.combinat - sage: C = P.combinatorial_polyhedron() # optional - sage.combinat - sage: chain = C.a_maximal_chain(); chain # optional - sage.combinat + sage: P = polytopes.permutahedron(4) # optional - sage.combinat + sage: C = P.combinatorial_polyhedron() # optional - sage.combinat + sage: chain = C.a_maximal_chain(); chain # optional - sage.combinat [A 0-dimensional face of a 3-dimensional combinatorial polyhedron, A 1-dimensional face of a 3-dimensional combinatorial polyhedron, A 2-dimensional face of a 3-dimensional combinatorial polyhedron] - sage: [face.ambient_V_indices() for face in chain] # optional - sage.combinat + sage: [face.ambient_V_indices() for face in chain] # optional - sage.combinat [(16,), (15, 16), (8, 9, 14, 15, 16, 17)] sage: P = Polyhedron(rays=[[1,0]], lines=[[0,1]]) @@ -3340,7 +3367,7 @@ cdef class CombinatorialPolyhedron(SageObject): sage: D.f_vector() (1, 6, 12, 8, 1) sage: D1 = P.polar().combinatorial_polyhedron() - sage: D1.face_lattice().is_isomorphic(D.face_lattice()) # optional - sage.combinat + sage: D1.face_lattice().is_isomorphic(D.face_lattice()) # optional - sage.combinat True Polar is an alias to be consistent with :class:`~sage.geometry.polyhedron.base.Polyhedron_base`:: @@ -3390,7 +3417,7 @@ cdef class CombinatorialPolyhedron(SageObject): sage: C1 = C.pyramid() sage: P1 = P.pyramid() sage: C2 = P1.combinatorial_polyhedron() - sage: C2.vertex_facet_graph().is_isomorphic(C1.vertex_facet_graph()) # optional - sage.combinat + sage: C2.vertex_facet_graph().is_isomorphic(C1.vertex_facet_graph()) # optional - sage.combinat True One can specify a name for the new vertex:: @@ -3409,10 +3436,10 @@ cdef class CombinatorialPolyhedron(SageObject): One can specify a name for the new facets:: - sage: P = polytopes.regular_polygon(4) # optional - sage.rings.number_field - sage: C = P.combinatorial_polyhedron() # optional - sage.rings.number_field - sage: C1 = C.pyramid(new_facet='base') # optional - sage.rings.number_field - sage: C1.Hrepresentation() # optional - sage.rings.number_field + sage: P = polytopes.regular_polygon(4) # optional - sage.rings.number_field + sage: C = P.combinatorial_polyhedron() # optional - sage.rings.number_field + sage: C1 = C.pyramid(new_facet='base') # optional - sage.rings.number_field + sage: C1.Hrepresentation() # optional - sage.rings.number_field (An inequality (-1/2, 1/2) x + 1/2 >= 0, An inequality (-1/2, -1/2) x + 1/2 >= 0, An inequality (1/2, 0.50000000000000000?) x + 1/2 >= 0, @@ -3495,24 +3522,26 @@ cdef class CombinatorialPolyhedron(SageObject): parallel_f_vector(structs, num_threads, parallelization_depth, f_vector) - # Copy ``f_vector``. - if dual: - if dim > 1 and f_vector[1] < self.n_facets(): - # The input seemed to be wrong. - raise ValueError("not all facets are joins of vertices") + self._persist_f_vector(f_vector, dual) - # We have computed the ``f_vector`` of the dual. - # Reverse it: - self._f_vector = \ - tuple(smallInteger(f_vector[dim+1-i]) for i in range(dim+2)) + cdef int _persist_f_vector(self, size_t* input_f_vector, bint input_is_reversed) except -1: + cdef int dim = self.dimension() + if input_is_reversed: + f_vector = \ + tuple(smallInteger(input_f_vector[dim + 1 - i]) for i in range(dim + 2)) else: - if self.is_bounded() and dim > 1 \ - and f_vector[1] < self.n_Vrepresentation() - len(self.far_face_tuple()): - # The input seemed to be wrong. + f_vector = \ + tuple(smallInteger(input_f_vector[i]) for i in range(dim + 2)) + + # Sanity checks. + if dim > 1: + if f_vector[-2] < self.n_facets(): + raise ValueError("not all facets are joins of vertices") + if self.is_bounded() and f_vector[1] < self.n_Vrepresentation(): raise ValueError("not all vertices are intersections of facets") - self._f_vector = tuple(smallInteger(f_vector[i]) for i in range(dim+2)) + self._f_vector = f_vector cdef int _compute_edges_or_ridges(self, int dual, bint do_edges) except -1: r""" @@ -3533,33 +3562,9 @@ cdef class CombinatorialPolyhedron(SageObject): # Determine whether to use dual mode or not. if not self.is_bounded(): dual = 0 - else: - if self.is_simple(): - per_face_primal = self.n_Vrepresentation() * self.n_facets() - else: - per_face_primal = self.n_Vrepresentation() * self.n_facets() ** 2 - - if self.is_simplicial(): - per_face_dual = self.n_Vrepresentation() * self.n_facets() - else: - per_face_dual = self.n_Vrepresentation() ** 2 * self.n_facets() - - from sage.arith.misc import binomial - estimate_n_faces = self.dimension() * binomial(min(self.n_facets(), self.n_Vrepresentation()), - self.dimension() // 2) - - # Note that the runtime per face already computes the coatoms of the next level, i.e. - # the runtime for each facet suffices to compute all ridges in primal, - # the runtime for each vertex suffices to compute all edges in dual. - if do_edges: - estimate_primal = estimate_n_faces * per_face_primal - estimate_dual = self.n_Vrepresentation() * per_face_dual - else: - estimate_primal = self.n_facets() * per_face_primal - estimate_dual = estimate_n_faces * per_face_dual - - dual = int(estimate_dual < estimate_primal) + algorithm = self.choose_algorithm_to_compute_edges_or_ridges("edges" if do_edges else "ridges") + dual = self._algorithm_to_dual(algorithm) cdef FaceIterator face_iter cdef int dim = self.dimension() @@ -3567,7 +3572,6 @@ cdef class CombinatorialPolyhedron(SageObject): cdef ListOfPairs edges = ListOfPairs() cdef int output_dim_init = 1 if do_edges else dim - 2 - cdef bint do_f_vector = False cdef size_t* f_vector = NULL try: @@ -3584,41 +3588,19 @@ cdef class CombinatorialPolyhedron(SageObject): if not self._f_vector and ((dual ^ do_edges)): # While doing edges in non-dual mode or ridges in dual-mode # one might as well do the f-vector. - do_f_vector = True - # Initialize ``f_vector``. f_vector = check_calloc((dim + 2), sizeof(size_t)) f_vector[0] = 1 f_vector[dim + 1] = 1 face_iter = self._face_iter(dual, -2) else: - do_f_vector = False face_iter = self._face_iter(dual, output_dim_init) - self._compute_edges_or_ridges_with_iterator(face_iter, (dual ^ do_edges), do_f_vector, + self._compute_edges_or_ridges_with_iterator(face_iter, (dual ^ do_edges), edges, f_vector) - # Success, copy the data to ``CombinatorialPolyhedron``. - - # Copy ``f_vector``. - if do_f_vector: - if dual: - if dim > 1 and f_vector[1] < self.n_facets(): - # The input seemed to be wrong. - raise ValueError("not all facets are joins of vertices") - - # We have computed the ``f_vector`` of the dual. - # Reverse it: - self._f_vector = \ - tuple(smallInteger(f_vector[dim+1-i]) for i in range(dim+2)) - - else: - if self.is_bounded() and dim > 1 \ - and f_vector[1] < self.n_Vrepresentation() - len(self.far_face_tuple()): - # The input seemed to be wrong. - raise ValueError("not all vertices are intersections of facets") - - self._f_vector = tuple(smallInteger(f_vector[i]) for i in range(dim+2)) + # Success, persist the data. + if f_vector is not NULL: + self._persist_f_vector(f_vector, dual) - # Copy the edge or ridges. if do_edges: self._edges = edges else: @@ -3631,14 +3613,95 @@ cdef class CombinatorialPolyhedron(SageObject): elif not do_edges and self._ridges is None: raise ValueError('could not determine ridges') + def choose_algorithm_to_compute_edges_or_ridges(self, edges_or_ridges): + """ + Use some heuristics to pick primal or dual algorithm for + computation of edges resp. ridges. + + We estimate how long it takes to compute a face using the primal + and the dual algorithm. This may differ significantly, so that e.g. + visiting all faces with the primal algorithm is faster than using + the dual algorithm to just visit vertices and edges. + + We guess the number of edges and ridges and do a wild estimate on + the total number of faces. + + INPUT: + + - ``edges_or_ridges`` -- string; one of: + * ``'edges'`` + * ``'ridges'`` + + OUTPUT: + + Either ``'primal'`` or ``'dual'``. + + EXAMPLES:: + + sage: C = polytopes.permutahedron(5).combinatorial_polyhedron() + sage: C.choose_algorithm_to_compute_edges_or_ridges("edges") + 'primal' + sage: C.choose_algorithm_to_compute_edges_or_ridges("ridges") + 'primal' + + :: + + sage: C = polytopes.cross_polytope(5).combinatorial_polyhedron() + sage: C.choose_algorithm_to_compute_edges_or_ridges("edges") + 'dual' + sage: C.choose_algorithm_to_compute_edges_or_ridges("ridges") + 'dual' + + + :: + + sage: C = polytopes.Birkhoff_polytope(5).combinatorial_polyhedron() + sage: C.choose_algorithm_to_compute_edges_or_ridges("edges") + 'dual' + sage: C.choose_algorithm_to_compute_edges_or_ridges("ridges") + 'primal' + sage: C.choose_algorithm_to_compute_edges_or_ridges("something_else") + Traceback (most recent call last): + ... + ValueError: unknown computation goal something_else + """ + if self.is_simple(): + per_face_primal = self.n_Vrepresentation() * self.n_facets() + else: + per_face_primal = self.n_Vrepresentation() * self.n_facets() ** 2 + + if self.is_simplicial(): + per_face_dual = self.n_Vrepresentation() * self.n_facets() + else: + per_face_dual = self.n_Vrepresentation() ** 2 * self.n_facets() + + from sage.arith.misc import binomial + estimate_n_faces = self.dimension() * binomial(min(self.n_facets(), self.n_Vrepresentation()), + self.dimension() // 2) + + # Note that the runtime per face already computes the coatoms of the next level, i.e. + # the runtime for each facet suffices to compute all ridges in primal, + # the runtime for each vertex suffices to compute all edges in dual. + if edges_or_ridges == "edges": + estimate_primal = estimate_n_faces * per_face_primal + estimate_dual = self.n_Vrepresentation() * per_face_dual + elif edges_or_ridges == "ridges": + estimate_primal = self.n_facets() * per_face_primal + estimate_dual = estimate_n_faces * per_face_dual + else: + raise ValueError(f"unknown computation goal {edges_or_ridges}") + + return 'dual' if (estimate_dual < estimate_primal) else 'primal' + cdef size_t _compute_edges_or_ridges_with_iterator( - self, FaceIterator face_iter, const bint do_atom_rep, const bint do_f_vector, + self, FaceIterator face_iter, const bint do_atom_rep, ListOfPairs edges, size_t* f_vector) except -1: r""" See :meth:`CombinatorialPolyhedron._compute_edges`. """ cdef size_t a, b # facets of an edge cdef int dim = self.dimension() + cdef bint do_f_vector = f_vector is not NULL # The dimension in which to record the edges or ridges. cdef output_dimension = 1 if do_atom_rep else dim - 2 @@ -3744,7 +3807,7 @@ cdef class CombinatorialPolyhedron(SageObject): dimension_one += 1 dimension_two = dimension_one - 1 - # Success, copy the data to ``CombinatorialPolyhedron``. + # Success, persist the data. self._face_lattice_incidences = incidences def _record_all_faces(self): @@ -3761,15 +3824,17 @@ cdef class CombinatorialPolyhedron(SageObject): TESTS:: - sage: P = polytopes.permutahedron(4) # optional - sage.combinat - sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat - sage: it = C.face_generator() # optional - sage.combinat - sage: tup = tuple((face.ambient_Vrepresentation(), # optional - sage.combinat + sage: P = polytopes.permutahedron(4) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: it = C.face_generator() # optional - sage.combinat + sage: tup = tuple((face.ambient_Vrepresentation(), # optional - sage.combinat ....: face.ambient_Hrepresentation()) for face in it) - sage: rg = range(1,sum(C.f_vector()) - 1) # optional - sage.combinat - sage: tup2 = tuple((C.face_by_face_lattice_index(i).ambient_Vrepresentation(), # optional - sage.combinat - ....: C.face_by_face_lattice_index(i).ambient_Hrepresentation()) for i in rg) - sage: sorted(tup) == sorted(tup2) # optional - sage.combinat + sage: rg = range(1,sum(C.f_vector()) - 1) # optional - sage.combinat + sage: tup2 = tuple( # optional - sage.combinat + ....: (C.face_by_face_lattice_index(i).ambient_Vrepresentation(), + ....: C.face_by_face_lattice_index(i).ambient_Hrepresentation()) + ....: for i in rg) + sage: sorted(tup) == sorted(tup2) # optional - sage.combinat True sage: P = polytopes.cyclic_polytope(4,10) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx index b1f529c412d..e499afcbc1c 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx @@ -100,7 +100,7 @@ cdef class CombinatorialFace(SageObject): sage: F = C.face_lattice() # optional - sage.combinat sage: F._elements[3] # optional - sage.combinat 34 - sage: C.face_by_face_lattice_index(29) + sage: C.face_by_face_lattice_index(29) # optional - sage.combinat A 1-dimensional face of a 5-dimensional combinatorial polyhedron Obtain the dimension of a combinatorial face:: diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx index a1c4152bf42..5b822e51f6b 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx @@ -100,7 +100,8 @@ cdef class PolyhedronFaceLattice: sage: P = polytopes.Birkhoff_polytope(3) sage: C = CombinatorialPolyhedron(P) - sage: C.face_lattice() # indirect doctests + sage: C._record_all_faces() # indirect doctests + sage: C.face_lattice() # optional - sage.combinat Finite lattice containing 50 elements ALGORITHM: @@ -215,7 +216,7 @@ cdef class PolyhedronFaceLattice: sage: P = polytopes.cube() sage: C = CombinatorialPolyhedron(P) sage: C._record_all_faces() # indirect doctests - sage: C.face_lattice() + sage: C.face_lattice() # optional - sage.combinat Finite lattice containing 28 elements sage: TestSuite(sage.geometry.polyhedron.combinatorial_polyhedron.polyhedron_face_lattice.PolyhedronFaceLattice).run() diff --git a/src/sage/geometry/polyhedron/constructor.py b/src/sage/geometry/polyhedron/constructor.py index 0a8cc1854ac..4e291e689dd 100644 --- a/src/sage/geometry/polyhedron/constructor.py +++ b/src/sage/geometry/polyhedron/constructor.py @@ -176,8 +176,8 @@ exact way to work with roots in Sage is the :mod:`Algebraic Real Field ` :: - sage: triangle = Polyhedron([(0,0), (1,0), (1/2, sqrt(3)/2)], base_ring=AA) # optional - sage.rings.number_field # optional - sage.symbolic - sage: triangle.Hrepresentation() # optional - sage.rings.number_field # optional - sage.symbolic + sage: triangle = Polyhedron([(0,0), (1,0), (1/2, sqrt(3)/2)], base_ring=AA) # optional - sage.rings.number_field sage.symbolic + sage: triangle.Hrepresentation() # optional - sage.rings.number_field sage.symbolic (An inequality (-1, -0.5773502691896258?) x + 1 >= 0, An inequality (1, -0.5773502691896258?) x + 0 >= 0, An inequality (0, 1.154700538379252?) x + 0 >= 0) @@ -186,21 +186,23 @@ symbolic ring element and, therefore, the polyhedron defined over the symbolic ring. This is currently not supported as SR is not exact:: - sage: Polyhedron([(0,0), (1,0), (1/2, sqrt(3)/2)]) # optional - sage.symbolic + sage: Polyhedron([(0,0), (1,0), (1/2, sqrt(3)/2)]) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: no default backend for computations with Symbolic Ring - sage: SR.is_exact() # optional - sage.symbolic + sage: SR.is_exact() # optional - sage.symbolic False Even faster than all algebraic real numbers (the field ``AA``) is to take the smallest extension field. For the equilateral triangle, that would be:: - sage: K. = NumberField(x^2 - 3, embedding=AA(3)**(1/2)) # optional - sage.rings.number_field - sage: Polyhedron([(0,0), (1,0), (1/2, sqrt3/2)]) # optional - sage.rings.number_field - A 2-dimensional polyhedron in (Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878?)^2 defined as the convex hull of 3 vertices + sage: K. = NumberField(x^2 - 3, embedding=AA(3)**(1/2)) # optional - sage.rings.number_field + sage: Polyhedron([(0,0), (1,0), (1/2, sqrt3/2)]) # optional - sage.rings.number_field + A 2-dimensional polyhedron in + (Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878?)^2 + defined as the convex hull of 3 vertices .. WARNING:: @@ -217,7 +219,7 @@ A 0-dimensional polyhedron in RDF^2 defined as the convex hull of 1 vertex sage: Polyhedron(vertices = [[1.12345678901234, 2.123456789012345]]) A 0-dimensional polyhedron in RDF^2 defined as the convex hull of 1 vertex - sage: Polyhedron(vertices = [[1.123456789012345, 2.123456789012345]]) # optional - sage.rings.real_mpfr + sage: Polyhedron(vertices = [[1.123456789012345, 2.123456789012345]]) # optional - sage.rings.real_mpfr Traceback (most recent call last): ... ValueError: the only allowed inexact ring is 'RDF' with backend 'cdd' @@ -449,25 +451,25 @@ def Polyhedron(vertices=None, rays=None, lines=None, by the cyclic shifts of `(0, \pm 1, \pm (1+\sqrt(5))/2)`, cf. :wikipedia:`Regular_icosahedron`. It needs a number field:: - sage: R0. = QQ[] # optional - sage.rings.number_field - sage: R1. = NumberField(r0^2-5, embedding=AA(5)**(1/2)) # optional - sage.rings.number_field - sage: gold = (1+r1)/2 # optional - sage.rings.number_field - sage: v = [[0, 1, gold], [0, 1, -gold], [0, -1, gold], [0, -1, -gold]] # optional - sage.rings.number_field - sage: pp = Permutation((1, 2, 3)) # optional - sage.combinat # optional - sage.rings.number_field - sage: icosah = Polyhedron( # optional - sage.combinat # optional - sage.rings.number_field + sage: R0. = QQ[] # optional - sage.rings.number_field + sage: R1. = NumberField(r0^2-5, embedding=AA(5)**(1/2)) # optional - sage.rings.number_field + sage: gold = (1+r1)/2 # optional - sage.rings.number_field + sage: v = [[0, 1, gold], [0, 1, -gold], [0, -1, gold], [0, -1, -gold]] # optional - sage.rings.number_field + sage: pp = Permutation((1, 2, 3)) # optional - sage.combinat sage.rings.number_field + sage: icosah = Polyhedron( # optional - sage.combinat sage.rings.number_field ....: [(pp^2).action(w) for w in v] + [pp.action(w) for w in v] + v, ....: base_ring=R1) - sage: len(icosah.faces(2)) # optional - sage.combinat # optional - sage.rings.number_field + sage: len(icosah.faces(2)) # optional - sage.combinat sage.rings.number_field 20 When the input contains elements of a Number Field, they require an embedding:: - sage: K = NumberField(x^2-2,'s') # optional - sage.rings.number_field - sage: s = K.0 # optional - sage.rings.number_field - sage: L = NumberField(x^3-2,'t') # optional - sage.rings.number_field - sage: t = L.0 # optional - sage.rings.number_field - sage: P = Polyhedron(vertices = [[0,s],[t,0]]) # optional - sage.rings.number_field + sage: K = NumberField(x^2 - 2,'s') # optional - sage.rings.number_field + sage: s = K.0 # optional - sage.rings.number_field + sage: L = NumberField(x^3 - 2,'t') # optional - sage.rings.number_field + sage: t = L.0 # optional - sage.rings.number_field + sage: P = Polyhedron(vertices=[[0,s], [t,0]]) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: invalid base ring @@ -504,12 +506,12 @@ def Polyhedron(vertices=None, rays=None, lines=None, sage: Polyhedron(o, base_ring=QQ) A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices - sage: H. = HyperplaneArrangements(QQ) # optional - sage.combinat - sage: h = x + y - 1; h # optional - sage.combinat + sage: H. = HyperplaneArrangements(QQ) # optional - sage.combinat + sage: h = x + y - 1; h # optional - sage.combinat Hyperplane x + y - 1 - sage: Polyhedron(h, base_ring=ZZ) # optional - sage.combinat + sage: Polyhedron(h, base_ring=ZZ) # optional - sage.combinat A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex and 1 line - sage: Polyhedron(h) # optional - sage.combinat + sage: Polyhedron(h) # optional - sage.combinat A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line .. NOTE:: @@ -563,7 +565,7 @@ def Polyhedron(vertices=None, rays=None, lines=None, Check that input with too many bits of precision returns an error (see :trac:`22552`):: - sage: Polyhedron(vertices=[(8.3319544851638732, 7.0567045956967727), # optional - sage.rings.real_mpfr + sage: Polyhedron(vertices=[(8.3319544851638732, 7.0567045956967727), # optional - sage.rings.real_mpfr ....: (6.4876921900819049, 4.8435898415984129)]) Traceback (most recent call last): ... @@ -571,11 +573,11 @@ def Polyhedron(vertices=None, rays=None, lines=None, Check that setting ``base_ring`` to a ``RealField`` returns an error (see :trac:`22552`):: - sage: Polyhedron(vertices=[(8.3, 7.0), (6.4, 4.8)], base_ring=RealField(40)) # optional - sage.rings.real_mpfr + sage: Polyhedron(vertices=[(8.3, 7.0), (6.4, 4.8)], base_ring=RealField(40)) # optional - sage.rings.real_mpfr Traceback (most recent call last): ... ValueError: no default backend for computations with Real Field with 40 bits of precision - sage: Polyhedron(vertices=[(8.3, 7.0), (6.4, 4.8)], base_ring=RealField(53)) # optional - sage.rings.real_mpfr + sage: Polyhedron(vertices=[(8.3, 7.0), (6.4, 4.8)], base_ring=RealField(53)) # optional - sage.rings.real_mpfr Traceback (most recent call last): ... ValueError: no default backend for computations with Real Field with 53 bits of precision diff --git a/src/sage/geometry/polyhedron/face.py b/src/sage/geometry/polyhedron/face.py index 2166f016ba8..437e296ceb9 100644 --- a/src/sage/geometry/polyhedron/face.py +++ b/src/sage/geometry/polyhedron/face.py @@ -35,7 +35,7 @@ or :meth:`~sage.geometry.polyhedron.base.face_lattice` to get the whole face lattice as a poset:: - sage: P.face_lattice() # optional - sage.combinat + sage: P.face_lattice() # optional - sage.combinat Finite lattice containing 28 elements The faces are printed in shorthand notation where each integer is the @@ -404,7 +404,7 @@ def ambient_Hrepresentation(self, index=None): EXAMPLES:: sage: square = polytopes.hypercube(2) - sage: for face in square.face_lattice(): # optional - sage.combinat + sage: for face in square.face_lattice(): # optional - sage.combinat ....: print(face.ambient_Hrepresentation()) (An inequality (-1, 0) x + 1 >= 0, An inequality (0, -1) x + 1 >= 0, An inequality (1, 0) x + 1 >= 0, An inequality (0, 1) x + 1 >= 0) @@ -445,7 +445,7 @@ def ambient_Vrepresentation(self, index=None): EXAMPLES:: sage: square = polytopes.hypercube(2) - sage: for fl in square.face_lattice(): # optional - sage.combinat + sage: for fl in square.face_lattice(): # optional - sage.combinat ....: print(fl.ambient_Vrepresentation()) () (A vertex at (1, -1),) @@ -478,15 +478,14 @@ def n_ambient_Hrepresentation(self): EXAMPLES:: sage: p = polytopes.cross_polytope(4) - sage: face = p.face_lattice()[5] # optional - sage.combinat - sage: face # optional - sage.combinat + sage: face = p.face_lattice()[5]; face # optional - sage.combinat A 1-dimensional face of a Polyhedron in ZZ^4 defined as the convex hull of 2 vertices - sage: face.ambient_Hrepresentation() # optional - sage.combinat + sage: face.ambient_Hrepresentation() # optional - sage.combinat (An inequality (1, -1, 1, -1) x + 1 >= 0, An inequality (1, 1, 1, 1) x + 1 >= 0, An inequality (1, 1, 1, -1) x + 1 >= 0, An inequality (1, -1, 1, 1) x + 1 >= 0) - sage: face.n_ambient_Hrepresentation() # optional - sage.combinat + sage: face.n_ambient_Hrepresentation() # optional - sage.combinat 4 """ return len(self.ambient_Hrepresentation()) @@ -505,12 +504,11 @@ def n_ambient_Vrepresentation(self): EXAMPLES:: sage: p = polytopes.cross_polytope(4) - sage: face = p.face_lattice()[5] # optional - sage.combinat - sage: face # optional - sage.combinat + sage: face = p.face_lattice()[5]; face # optional - sage.combinat A 1-dimensional face of a Polyhedron in ZZ^4 defined as the convex hull of 2 vertices - sage: face.ambient_Vrepresentation() # optional - sage.combinat + sage: face.ambient_Vrepresentation() # optional - sage.combinat (A vertex at (-1, 0, 0, 0), A vertex at (0, 0, -1, 0)) - sage: face.n_ambient_Vrepresentation() # optional - sage.combinat + sage: face.n_ambient_Vrepresentation() # optional - sage.combinat 2 """ return len(self.ambient_Vrepresentation()) @@ -595,8 +593,8 @@ def dim(self): EXAMPLES:: - sage: fl = polytopes.dodecahedron().face_lattice() # optional - sage.combinat # optional - sage.rings.number_field - sage: sorted([ x.dim() for x in fl ]) # optional - sage.combinat # optional - sage.rings.number_field + sage: fl = polytopes.dodecahedron().face_lattice() # optional - sage.combinat sage.rings.number_field + sage: sorted(x.dim() for x in fl) # optional - sage.combinat sage.rings.number_field [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3] @@ -605,7 +603,7 @@ def dim(self): Check that :trac:`28650` is fixed:: - sage: P = Polyhedron(vertices=[[1,0]], rays=[[1,0],[0,1]]) + sage: P = Polyhedron(vertices=[[1,0]], rays=[[1,0], [0,1]]) sage: P.faces(2) (A 2-dimensional face of a Polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays,) """ @@ -679,8 +677,7 @@ def polyhedron(self): sage: P = polytopes.cross_polytope(3); P A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 6 vertices - sage: face = P.facets()[3] - sage: face + sage: face = P.facets()[3]; face A 2-dimensional face of a Polyhedron in ZZ^3 defined as the convex hull of 3 vertices sage: face.polyhedron() A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 6 vertices @@ -704,10 +701,11 @@ def ambient_vector_space(self, base_field=None): sage: half_plane = Polyhedron(ieqs=[(0,1,0)]) sage: line = half_plane.faces(1)[0]; line - A 1-dimensional face of a Polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line + A 1-dimensional face of a + Polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line sage: line.ambient_vector_space() Vector space of dimension 2 over Rational Field - sage: line.ambient_vector_space(AA) # optional - sage.rings.number_field + sage: line.ambient_vector_space(AA) # optional - sage.rings.number_field Vector space of dimension 2 over Algebraic Real Field """ return self.polyhedron().ambient_vector_space(base_field=base_field) @@ -716,15 +714,14 @@ def is_relatively_open(self): r""" Return whether ``self`` is relatively open. - OUTPUT: - - Boolean. + OUTPUT: Boolean. EXAMPLES:: sage: half_plane = Polyhedron(ieqs=[(0,1,0)]) sage: line = half_plane.faces(1)[0]; line - A 1-dimensional face of a Polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line + A 1-dimensional face of a + Polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line sage: line.is_relatively_open() True """ @@ -734,15 +731,14 @@ def is_compact(self): r""" Return whether ``self`` is compact. - OUTPUT: - - Boolean. + OUTPUT: Boolean. EXAMPLES:: sage: half_plane = Polyhedron(ieqs=[(0,1,0)]) sage: line = half_plane.faces(1)[0]; line - A 1-dimensional face of a Polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line + A 1-dimensional face of a + Polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line sage: line.is_compact() False """ @@ -762,9 +758,9 @@ def as_polyhedron(self, **kwds): sage: P = polytopes.cross_polytope(3); P A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 6 vertices - sage: face = P.faces(2)[3] - sage: face - A 2-dimensional face of a Polyhedron in ZZ^3 defined as the convex hull of 3 vertices + sage: face = P.faces(2)[3]; face + A 2-dimensional face of a + Polyhedron in ZZ^3 defined as the convex hull of 3 vertices sage: face.as_polyhedron() A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 3 vertices @@ -791,9 +787,9 @@ def _some_elements_(self): sage: P = polytopes.cross_polytope(3); P A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 6 vertices - sage: face = P.faces(2)[3] - sage: face - A 2-dimensional face of a Polyhedron in ZZ^3 defined as the convex hull of 3 vertices + sage: face = P.faces(2)[3]; face + A 2-dimensional face of a + Polyhedron in ZZ^3 defined as the convex hull of 3 vertices sage: face.as_polyhedron().vertices() (A vertex at (0, -1, 0), A vertex at (0, 0, -1), A vertex at (1, 0, 0)) sage: face.an_element() # indirect doctest @@ -815,7 +811,8 @@ def contains(self, point): sage: half_plane = Polyhedron(ieqs=[(0,1,0)]) sage: line = half_plane.faces(1)[0]; line - A 1-dimensional face of a Polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line + A 1-dimensional face of a + Polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line sage: line.contains([0, 1]) True @@ -864,7 +861,7 @@ def normal_cone(self, direction='outer'): EXAMPLES:: - sage: p = Polyhedron(vertices = [[1,2],[2,1],[-2,2],[-2,-2],[2,-2]]) + sage: p = Polyhedron(vertices=[[1,2], [2,1], [-2,2], [-2,-2], [2,-2]]) sage: for v in p.face_generator(0): ....: vect = v.vertices()[0].vector() ....: nc = v.normal_cone().rays_list() @@ -894,11 +891,14 @@ def normal_cone(self, direction='outer'): sage: f2 = p.faces(1)[0] sage: f3 = p.faces(2)[0] sage: f1.normal_cone() - A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 1 vertex, 2 rays, 1 line + A 3-dimensional polyhedron in ZZ^3 defined as + the convex hull of 1 vertex, 2 rays, 1 line sage: f2.normal_cone() - A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 1 vertex, 1 ray, 1 line + A 2-dimensional polyhedron in ZZ^3 defined as + the convex hull of 1 vertex, 1 ray, 1 line sage: f3.normal_cone() - A 1-dimensional polyhedron in ZZ^3 defined as the convex hull of 1 vertex and 1 line + A 1-dimensional polyhedron in ZZ^3 defined as + the convex hull of 1 vertex and 1 line Normal cones are only defined for non-empty faces:: @@ -941,8 +941,8 @@ def affine_tangent_cone(self): sage: half_plane_in_space = Polyhedron(ieqs=[(0,1,0,0)], eqns=[(0,0,0,1)]) sage: line = half_plane_in_space.faces(1)[0]; line - A 1-dimensional face - of a Polyhedron in QQ^3 defined as the convex hull of 1 vertex and 1 line + A 1-dimensional face of a + Polyhedron in QQ^3 defined as the convex hull of 1 vertex and 1 line sage: T_line = line.affine_tangent_cone() sage: T_line == half_plane_in_space True @@ -954,9 +954,9 @@ def affine_tangent_cone(self): sage: T_edge = edge.affine_tangent_cone() sage: T_edge.Vrepresentation() (A line in the direction (0, 1, 0), - A ray in the direction (0, 0, 1), - A vertex at (1, 0, -1), - A ray in the direction (-1, 0, 0)) + A ray in the direction (0, 0, 1), + A vertex at (1, 0, -1), + A ray in the direction (-1, 0, 0)) TESTS: @@ -1034,9 +1034,9 @@ def combinatorial_face_to_polyhedral_face(polyhedron, combinatorial_face): INPUT: - ``polyhedron`` -- a polyhedron containing ``combinatorial_face`` - - ``combinatorial_face`` -- a ``CombinatorialFace`` + - ``combinatorial_face`` -- a :class:`CombinatorialFace` - OUTPUT: a ``PolyhedronFace``. + OUTPUT: a :class:`PolyhedronFace`. EXAMPLES:: @@ -1059,9 +1059,9 @@ def combinatorial_face_to_polyhedral_face(polyhedron, combinatorial_face): 0 sage: polytopes.simplex(backend='cdd').equations()[0].index() 4 - sage: polytopes.simplex(backend='normaliz').equations()[0].index() # optional - pynormaliz + sage: polytopes.simplex(backend='normaliz').equations()[0].index() # optional - pynormaliz 4 - sage: polytopes.simplex(backend='polymake').equations()[0].index() # optional - jupymake + sage: polytopes.simplex(backend='polymake').equations()[0].index() # optional - jupymake 4 """ V_indices = combinatorial_face.ambient_V_indices() diff --git a/src/sage/geometry/polyhedron/library.py b/src/sage/geometry/polyhedron/library.py index f621f9329ff..7664b0eced7 100644 --- a/src/sage/geometry/polyhedron/library.py +++ b/src/sage/geometry/polyhedron/library.py @@ -117,7 +117,7 @@ def zero_sum_projection(d, base_ring=None): Exact computation in :class:`AA `:: - sage: zero_sum_projection(3, base_ring=AA) # optional - sage.rings.number_field + sage: zero_sum_projection(3, base_ring=AA) # optional - sage.rings.number_field [ 0.7071067811865475? -0.7071067811865475? 0] [ 0.4082482904638630? 0.4082482904638630? -0.8164965809277260?] @@ -171,17 +171,17 @@ def project_points(*points, **kwds): Check that it is (almost) an isometry:: - sage: V = list(map(vector, IntegerVectors(n=5, length=3))) # optional - sage.combinat - sage: P = project_points(*V) # optional - sage.combinat - sage: for i in range(21): # optional - sage.combinat + sage: V = list(map(vector, IntegerVectors(n=5, length=3))) # optional - sage.combinat + sage: P = project_points(*V) # optional - sage.combinat + sage: for i in range(21): # optional - sage.combinat ....: for j in range(21): ....: assert abs((V[i]-V[j]).norm() - (P[i]-P[j]).norm()) < 0.00001 Example with exact computation:: - sage: V = [ vector(v) for v in IntegerVectors(n=4, length=2) ] # optional - sage.combinat - sage: P = project_points(*V, base_ring=AA) # optional - sage.combinat sage.rings.number_field - sage: for i in range(len(V)): # optional - sage.combinat sage.rings.number_field + sage: V = [ vector(v) for v in IntegerVectors(n=4, length=2) ] # optional - sage.combinat + sage: P = project_points(*V, base_ring=AA) # optional - sage.combinat sage.rings.number_field + sage: for i in range(len(V)): # optional - sage.combinat sage.rings.number_field ....: for j in range(len(V)): ....: assert (V[i]-V[j]).norm() == (P[i]-P[j]).norm() @@ -412,7 +412,7 @@ def gale_transform_to_primal(vectors, base_ring=None, backend=None): (-55, 0, 0), (0, -55, 0), (0, 0, -55)] - sage: gale_transform_to_primal(p, backend='normaliz') # optional - pynormaliz + sage: gale_transform_to_primal(p, backend='normaliz') # optional - pynormaliz [(16, -35, 54), (24, 10, 31), (-15, 50, -60), @@ -515,15 +515,15 @@ def regular_polygon(self, n, exact=True, base_ring=None, backend=None): EXAMPLES:: - sage: octagon = polytopes.regular_polygon(8) # optional - sage.rings.number_field - sage: octagon # optional - sage.rings.number_field + sage: octagon = polytopes.regular_polygon(8) # optional - sage.rings.number_field + sage: octagon # optional - sage.rings.number_field A 2-dimensional polyhedron in AA^2 defined as the convex hull of 8 vertices - sage: octagon.n_vertices() # optional - sage.rings.number_field + sage: octagon.n_vertices() # optional - sage.rings.number_field 8 - sage: v = octagon.volume() # optional - sage.rings.number_field - sage: v # optional - sage.rings.number_field + sage: v = octagon.volume() # optional - sage.rings.number_field + sage: v # optional - sage.rings.number_field 2.828427124746190? - sage: v == 2*QQbar(2).sqrt() # optional - sage.rings.number_field + sage: v == 2*QQbar(2).sqrt() # optional - sage.rings.number_field True Its non exact version:: @@ -537,14 +537,14 @@ def regular_polygon(self, n, exact=True, base_ring=None, backend=None): TESTS:: - sage: octagon = polytopes.regular_polygon(8, backend='normaliz') # optional - pynormaliz # optional - sage.rings.number_field - sage: octagon # optional - pynormaliz # optional - sage.rings.number_field + sage: octagon = polytopes.regular_polygon(8, backend='normaliz') # optional - pynormaliz sage.rings.number_field + sage: octagon # optional - pynormaliz sage.rings.number_field A 2-dimensional polyhedron in AA^2 defined as the convex hull of 8 vertices - sage: octagon.n_vertices() # optional - pynormaliz # optional - sage.rings.number_field + sage: octagon.n_vertices() # optional - pynormaliz sage.rings.number_field 8 - sage: octagon.volume() # optional - pynormaliz # optional - sage.rings.number_field + sage: octagon.volume() # optional - pynormaliz sage.rings.number_field 2*a - sage: TestSuite(octagon).run() # long time # optional - sage.rings.number_field + sage: TestSuite(octagon).run() # long time # optional - sage.rings.number_field sage: TestSuite(polytopes.regular_polygon(5, exact=False)).run() """ n = ZZ(n) @@ -609,8 +609,8 @@ def Birkhoff_polytope(self, n, backend=None): TESTS:: - sage: b4norm = polytopes.Birkhoff_polytope(4,backend='normaliz') # optional - pynormaliz - sage: TestSuite(b4norm).run() # optional - pynormaliz + sage: b4norm = polytopes.Birkhoff_polytope(4,backend='normaliz') # optional - pynormaliz + sage: TestSuite(b4norm).run() # optional - pynormaliz sage: TestSuite(polytopes.Birkhoff_polytope(3)).run() """ from itertools import permutations @@ -678,14 +678,14 @@ def simplex(self, dim=3, project=False, base_ring=None, backend=None): Computation in algebraic reals:: - sage: s3 = polytopes.simplex(3, project=True, base_ring=AA) # optional - sage.rings.number_field - sage: s3.volume() == sqrt(3+1) / factorial(3) # optional - sage.rings.number_field + sage: s3 = polytopes.simplex(3, project=True, base_ring=AA) # optional - sage.rings.number_field + sage: s3.volume() == sqrt(3+1) / factorial(3) # optional - sage.rings.number_field True TESTS:: - sage: s6norm = polytopes.simplex(6,backend='normaliz') # optional - pynormaliz - sage: TestSuite(s6norm).run() # optional - pynormaliz + sage: s6norm = polytopes.simplex(6,backend='normaliz') # optional - pynormaliz + sage: TestSuite(s6norm).run() # optional - pynormaliz sage: TestSuite(polytopes.simplex(5)).run() """ verts = list((ZZ**(dim + 1)).basis()) @@ -716,47 +716,47 @@ def icosahedron(self, exact=True, base_ring=None, backend=None): EXAMPLES:: - sage: ico = polytopes.icosahedron() # optional - sage.rings.number_field - sage: ico.f_vector() # optional - sage.rings.number_field + sage: ico = polytopes.icosahedron() # optional - sage.rings.number_field + sage: ico.f_vector() # optional - sage.rings.number_field (1, 12, 30, 20, 1) - sage: ico.volume() # optional - sage.rings.number_field + sage: ico.volume() # optional - sage.rings.number_field 5/12*sqrt5 + 5/4 Its non exact version:: - sage: ico = polytopes.icosahedron(exact=False) # optional - sage.groups - sage: ico.base_ring() # optional - sage.groups + sage: ico = polytopes.icosahedron(exact=False) # optional - sage.groups + sage: ico.base_ring() # optional - sage.groups Real Double Field - sage: ico.volume() # known bug (trac 18214) # optional - sage.groups + sage: ico.volume() # known bug (trac 18214) # optional - sage.groups 2.181694990... A version using `AA `:: - sage: ico = polytopes.icosahedron(base_ring=AA) # long time # optional - sage.rings.number_field # optional - sage.groups - sage: ico.base_ring() # long time # optional - sage.rings.number_field # optional - sage.groups + sage: ico = polytopes.icosahedron(base_ring=AA) # long time # optional - sage.rings.number_field sage.groups + sage: ico.base_ring() # long time # optional - sage.rings.number_field sage.groups Algebraic Real Field - sage: ico.volume() # long time # optional - sage.rings.number_field # optional - sage.groups + sage: ico.volume() # long time # optional - sage.rings.number_field sage.groups 2.181694990624913? Note that if base ring is provided it must contain the square root of `5`. Otherwise you will get an error:: - sage: polytopes.icosahedron(base_ring=QQ) # optional - sage.symbolic + sage: polytopes.icosahedron(base_ring=QQ) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: unable to convert 1/4*sqrt(5) + 1/4 to a rational TESTS:: - sage: ico = polytopes.icosahedron(backend='normaliz') # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.groups - sage: ico.f_vector() # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.groups + sage: ico = polytopes.icosahedron(backend='normaliz') # optional - pynormaliz sage.rings.number_field sage.groups + sage: ico.f_vector() # optional - pynormaliz sage.rings.number_field sage.groups (1, 12, 30, 20, 1) - sage: ico.volume() # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.groups + sage: ico.volume() # optional - pynormaliz sage.rings.number_field sage.groups 5/12*sqrt5 + 5/4 - sage: TestSuite(ico).run() # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.groups + sage: TestSuite(ico).run() # optional - pynormaliz sage.rings.number_field sage.groups - sage: ico = polytopes.icosahedron(exact=False) # optional - sage.groups - sage: TestSuite(ico).run(skip="_test_lawrence") # optional - sage.groups + sage: ico = polytopes.icosahedron(exact=False) # optional - sage.groups + sage: TestSuite(ico).run(skip="_test_lawrence") # optional - sage.groups """ if base_ring is None and exact: @@ -798,31 +798,31 @@ def dodecahedron(self, exact=True, base_ring=None, backend=None): EXAMPLES:: - sage: d12 = polytopes.dodecahedron() # optional - sage.rings.number_field # optional - sage.groups - sage: d12.f_vector() # optional - sage.rings.number_field # optional - sage.groups + sage: d12 = polytopes.dodecahedron() # optional - sage.rings.number_field sage.groups + sage: d12.f_vector() # optional - sage.rings.number_field sage.groups (1, 20, 30, 12, 1) - sage: d12.volume() # optional - sage.rings.number_field # optional - sage.groups + sage: d12.volume() # optional - sage.rings.number_field sage.groups -176*sqrt5 + 400 - sage: numerical_approx(_) # optional - sage.rings.number_field # optional - sage.groups + sage: numerical_approx(_) # optional - sage.rings.number_field sage.groups 6.45203596003699 - sage: d12 = polytopes.dodecahedron(exact=False) # optional - sage.groups - sage: d12.base_ring() # optional - sage.groups + sage: d12 = polytopes.dodecahedron(exact=False) # optional - sage.groups + sage: d12.base_ring() # optional - sage.groups Real Double Field Here is an error with a field that does not contain `\sqrt(5)`:: - sage: polytopes.dodecahedron(base_ring=QQ) # optional - sage.symbolic # optional - sage.groups + sage: polytopes.dodecahedron(base_ring=QQ) # optional - sage.symbolic sage.groups Traceback (most recent call last): ... TypeError: unable to convert 1/4*sqrt(5) + 1/4 to a rational TESTS:: - sage: d12 = polytopes.dodecahedron(backend='normaliz') # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.groups - sage: d12.f_vector() # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.groups + sage: d12 = polytopes.dodecahedron(backend='normaliz') # optional - pynormaliz sage.rings.number_field sage.groups + sage: d12.f_vector() # optional - pynormaliz sage.rings.number_field sage.groups (1, 20, 30, 12, 1) - sage: TestSuite(d12).run() # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.groups + sage: TestSuite(d12).run() # optional - pynormaliz sage.rings.number_field sage.groups """ return self.icosahedron(exact=exact, base_ring=base_ring, backend=backend).polar() @@ -847,17 +847,17 @@ def small_rhombicuboctahedron(self, exact=True, base_ring=None, backend=None): EXAMPLES:: - sage: sr = polytopes.small_rhombicuboctahedron() # optional - sage.rings.number_field - sage: sr.f_vector() # optional - sage.rings.number_field + sage: sr = polytopes.small_rhombicuboctahedron() # optional - sage.rings.number_field + sage: sr.f_vector() # optional - sage.rings.number_field (1, 24, 48, 26, 1) - sage: sr.volume() # optional - sage.rings.number_field + sage: sr.volume() # optional - sage.rings.number_field 80/3*sqrt2 + 32 The faces are `8` equilateral triangles and `18` squares:: - sage: sum(1 for f in sr.facets() if len(f.vertices()) == 3) # optional - sage.rings.number_field + sage: sum(1 for f in sr.facets() if len(f.vertices()) == 3) # optional - sage.rings.number_field 8 - sage: sum(1 for f in sr.facets() if len(f.vertices()) == 4) # optional - sage.rings.number_field + sage: sum(1 for f in sr.facets() if len(f.vertices()) == 4) # optional - sage.rings.number_field 18 Its non exact version:: @@ -871,12 +871,12 @@ def small_rhombicuboctahedron(self, exact=True, base_ring=None, backend=None): TESTS:: - sage: sr = polytopes.small_rhombicuboctahedron(backend='normaliz') # optional - sage.rings.number_field pynormaliz - sage: sr.f_vector() # optional - sage.rings.number_field pynormaliz + sage: sr = polytopes.small_rhombicuboctahedron(backend='normaliz') # optional - sage.rings.number_field pynormaliz + sage: sr.f_vector() # optional - sage.rings.number_field pynormaliz (1, 24, 48, 26, 1) - sage: sr.volume() # optional - sage.rings.number_field pynormaliz + sage: sr.volume() # optional - sage.rings.number_field pynormaliz 80/3*sqrt2 + 32 - sage: TestSuite(sr).run() # long time # optional - sage.rings.number_field pynormaliz + sage: TestSuite(sr).run() # long time # optional - sage.rings.number_field pynormaliz """ if base_ring is None and exact: from sage.rings.number_field.number_field import QuadraticField @@ -918,8 +918,8 @@ def great_rhombicuboctahedron(self, exact=True, base_ring=None, backend=None): EXAMPLES:: - sage: gr = polytopes.great_rhombicuboctahedron() # long time ~ 3sec # optional - sage.rings.number_field - sage: gr.f_vector() # long time # optional - sage.rings.number_field + sage: gr = polytopes.great_rhombicuboctahedron() # long time ~ 3sec # optional - sage.rings.number_field + sage: gr.f_vector() # long time # optional - sage.rings.number_field (1, 48, 72, 26, 1) A faster implementation is obtained by setting ``exact=False``:: @@ -1040,8 +1040,8 @@ def cuboctahedron(self, backend=None): TESTS:: - sage: co_norm = polytopes.cuboctahedron(backend='normaliz') # optional - pynormaliz - sage: TestSuite(co_norm).run() # optional - pynormaliz + sage: co_norm = polytopes.cuboctahedron(backend='normaliz') # optional - pynormaliz + sage: TestSuite(co_norm).run() # optional - pynormaliz """ v = [[0, -1, -1], [0, 1, -1], [0, -1, 1], [0, 1, 1], [-1, -1, 0], [1, -1, 0], [-1, 1, 0], [1, 1, 0], @@ -1072,28 +1072,28 @@ def truncated_cube(self, exact=True, base_ring=None, backend=None): EXAMPLES:: - sage: co = polytopes.truncated_cube() # optional - sage.rings.number_field - sage: co.f_vector() # optional - sage.rings.number_field + sage: co = polytopes.truncated_cube() # optional - sage.rings.number_field + sage: co.f_vector() # optional - sage.rings.number_field (1, 24, 36, 14, 1) Its facets are 8 triangles and 6 octogons:: - sage: sum(1 for f in co.facets() if len(f.vertices()) == 3) # optional - sage.rings.number_field + sage: sum(1 for f in co.facets() if len(f.vertices()) == 3) # optional - sage.rings.number_field 8 - sage: sum(1 for f in co.facets() if len(f.vertices()) == 8) # optional - sage.rings.number_field + sage: sum(1 for f in co.facets() if len(f.vertices()) == 8) # optional - sage.rings.number_field 6 Some more computation:: - sage: co.volume() # optional - sage.rings.number_field + sage: co.volume() # optional - sage.rings.number_field 56/3*sqrt2 - 56/3 TESTS:: - sage: co = polytopes.truncated_cube(backend='normaliz') # optional - pynormaliz # optional - sage.rings.number_field - sage: co.f_vector() # optional - pynormaliz # optional - sage.rings.number_field + sage: co = polytopes.truncated_cube(backend='normaliz') # optional - pynormaliz sage.rings.number_field + sage: co.f_vector() # optional - pynormaliz sage.rings.number_field (1, 24, 36, 14, 1) - sage: TestSuite(co).run() # optional - pynormaliz # optional - sage.rings.number_field + sage: TestSuite(co).run() # optional - pynormaliz sage.rings.number_field """ if base_ring is None and exact: @@ -1150,8 +1150,8 @@ def tetrahedron(self, backend=None): TESTS:: - sage: t_norm = polytopes.tetrahedron(backend='normaliz') # optional - pynormaliz - sage: TestSuite(t_norm).run() # optional - pynormaliz + sage: t_norm = polytopes.tetrahedron(backend='normaliz') # optional - pynormaliz + sage: TestSuite(t_norm).run() # optional - pynormaliz """ v = [[0, 0, 0], [1, 0, 1], [1, 1, 0], [0, 1, 1]] return Polyhedron(vertices=v, base_ring=ZZ, backend=backend) @@ -1192,8 +1192,8 @@ def truncated_tetrahedron(self, backend=None): TESTS:: - sage: tt_norm = polytopes.truncated_tetrahedron(backend='normaliz') # optional - pynormaliz - sage: TestSuite(tt_norm).run() # optional - pynormaliz + sage: tt_norm = polytopes.truncated_tetrahedron(backend='normaliz') # optional - pynormaliz + sage: TestSuite(tt_norm).run() # optional - pynormaliz """ v = [(3,1,1), (1,3,1), (1,1,3), (-3,-1,1), (-1,-3,1), (-1,-1,3), @@ -1218,22 +1218,22 @@ def truncated_octahedron(self, backend=None): EXAMPLES:: - sage: co = polytopes.truncated_octahedron() # optional - sage.combinat - sage: co.f_vector() # optional - sage.combinat + sage: co = polytopes.truncated_octahedron() # optional - sage.combinat + sage: co.f_vector() # optional - sage.combinat (1, 24, 36, 14, 1) Its facets are 6 squares and 8 hexagons:: - sage: sum(1 for f in co.facets() if len(f.vertices()) == 4) # optional - sage.combinat + sage: sum(1 for f in co.facets() if len(f.vertices()) == 4) # optional - sage.combinat 6 - sage: sum(1 for f in co.facets() if len(f.vertices()) == 6) # optional - sage.combinat + sage: sum(1 for f in co.facets() if len(f.vertices()) == 6) # optional - sage.combinat 8 Some more computation:: - sage: co.volume() # optional - sage.combinat + sage: co.volume() # optional - sage.combinat 32 - sage: co.ehrhart_polynomial() # optional - latte_int # optional - sage.combinat + sage: co.ehrhart_polynomial() # optional - latte_int sage.combinat 32*t^3 + 18*t^2 + 6*t + 1 TESTS:: @@ -1280,8 +1280,8 @@ def octahedron(self, backend=None): TESTS:: - sage: o_norm = polytopes.octahedron(backend='normaliz') # optional - pynormaliz - sage: TestSuite(o_norm).run() # optional - pynormaliz + sage: o_norm = polytopes.octahedron(backend='normaliz') # optional - pynormaliz + sage: TestSuite(o_norm).run() # optional - pynormaliz """ v = [[0, 0, -1], [0, 0, 1], [1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0]] @@ -1313,14 +1313,14 @@ def snub_cube(self, exact=False, base_ring=None, backend=None, verbose=False): EXAMPLES:: - sage: sc_inexact = polytopes.snub_cube(exact=False); sc_inexact # optional - sage.groups + sage: sc_inexact = polytopes.snub_cube(exact=False); sc_inexact # optional - sage.groups A 3-dimensional polyhedron in RDF^3 defined as the convex hull of 24 vertices - sage: sc_inexact.f_vector() # optional - sage.groups + sage: sc_inexact.f_vector() # optional - sage.groups (1, 24, 60, 38, 1) - sage: sc_exact = polytopes.snub_cube(exact=True) # long time # optional - sage.groups sage.rings.number_field - sage: sc_exact.f_vector() # long time # optional - sage.groups sage.rings.number_field + sage: sc_exact = polytopes.snub_cube(exact=True) # long time # optional - sage.groups sage.rings.number_field + sage: sc_exact.f_vector() # long time # optional - sage.groups sage.rings.number_field (1, 24, 60, 38, 1) - sage: sorted(sc_exact.vertices()) # long time # optional - sage.groups sage.rings.number_field + sage: sorted(sc_exact.vertices()) # long time # optional - sage.groups sage.rings.number_field [A vertex at (-1, -z, -z^2), A vertex at (-1, -z^2, z), A vertex at (-1, z^2, -z), @@ -1345,13 +1345,13 @@ def snub_cube(self, exact=False, base_ring=None, backend=None, verbose=False): A vertex at (1, -z^2, -z), A vertex at (1, z^2, z), A vertex at (1, z, -z^2)] - sage: sc_exact.is_combinatorially_isomorphic(sc_inexact) # long time # optional - sage.groups sage.rings.number_field + sage: sc_exact.is_combinatorially_isomorphic(sc_inexact) # long time # optional - sage.groups sage.rings.number_field True TESTS:: - sage: sc = polytopes.snub_cube(exact=True, backend='normaliz') # optional - pynormaliz sage.groups sage.rings.number_field - sage: sc.f_vector() # optional - pynormaliz sage.groups sage.rings.number_field + sage: sc = polytopes.snub_cube(exact=True, backend='normaliz') # optional - pynormaliz sage.groups sage.rings.number_field + sage: sc.f_vector() # optional - pynormaliz sage.groups sage.rings.number_field (1, 24, 60, 38, 1) """ @@ -1416,34 +1416,36 @@ def buckyball(self, exact=True, base_ring=None, backend=None): EXAMPLES:: - sage: bb = polytopes.buckyball() # long time - 6secs # optional - sage.groups # optional - sage.rings.number_field - sage: bb.f_vector() # long time # optional - sage.groups # optional - sage.rings.number_field + sage: bb = polytopes.buckyball() # long time - 6secs # optional - sage.groups sage.rings.number_field + sage: bb.f_vector() # long time # optional - sage.groups sage.rings.number_field (1, 60, 90, 32, 1) - sage: bb.base_ring() # long time # optional - sage.groups # optional - sage.rings.number_field - Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? + sage: bb.base_ring() # long time # optional - sage.groups sage.rings.number_field + Number Field in sqrt5 with defining polynomial x^2 - 5 + with sqrt5 = 2.236067977499790? A much faster implementation using floating point approximations:: - sage: bb = polytopes.buckyball(exact=False) # optional - sage.groups - sage: bb.f_vector() # optional - sage.groups + sage: bb = polytopes.buckyball(exact=False) # optional - sage.groups + sage: bb.f_vector() # optional - sage.groups (1, 60, 90, 32, 1) - sage: bb.base_ring() # optional - sage.groups + sage: bb.base_ring() # optional - sage.groups Real Double Field Its facets are 5 regular pentagons and 6 regular hexagons:: - sage: sum(1 for f in bb.facets() if len(f.vertices()) == 5) # optional - sage.groups + sage: sum(1 for f in bb.facets() if len(f.vertices()) == 5) # optional - sage.groups 12 - sage: sum(1 for f in bb.facets() if len(f.vertices()) == 6) # optional - sage.groups + sage: sum(1 for f in bb.facets() if len(f.vertices()) == 6) # optional - sage.groups 20 TESTS:: - sage: bb = polytopes.buckyball(backend='normaliz') # optional - sage.groups # optional - sage.rings.number_field # optional - pynormaliz - sage: bb.f_vector() # optional - sage.groups # optional - sage.rings.number_field # optional - pynormaliz + sage: bb = polytopes.buckyball(backend='normaliz') # optional - pynormaliz sage.groups sage.rings.number_field + sage: bb.f_vector() # optional - pynormaliz sage.groups sage.rings.number_field (1, 60, 90, 32, 1) - sage: bb.base_ring() # optional - sage.groups # optional - sage.rings.number_field # optional - pynormaliz - Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? + sage: bb.base_ring() # optional - pynormaliz sage.groups sage.rings.number_field + Number Field in sqrt5 with defining polynomial x^2 - 5 + with sqrt5 = 2.236067977499790? """ return self.icosahedron(exact=exact, base_ring=base_ring, backend=backend).truncation() @@ -1465,25 +1467,26 @@ def icosidodecahedron(self, exact=True, backend=None): EXAMPLES:: - sage: id = polytopes.icosidodecahedron() # optional - sage.rings.number_field # optional - sage.groups - sage: id.f_vector() # optional - sage.rings.number_field # optional - sage.groups + sage: id = polytopes.icosidodecahedron() # optional - sage.rings.number_field sage.groups + sage: id.f_vector() # optional - sage.rings.number_field sage.groups (1, 30, 60, 32, 1) TESTS:: - sage: id = polytopes.icosidodecahedron(exact=False); id # optional - sage.rings.number_field # optional - sage.groups + sage: id = polytopes.icosidodecahedron(exact=False); id # optional - sage.rings.number_field sage.groups A 3-dimensional polyhedron in RDF^3 defined as the convex hull of 30 vertices - sage: TestSuite(id).run(skip=["_test_is_combinatorially_isomorphic", # optional - sage.rings.number_field # optional - sage.groups + sage: TestSuite(id).run(skip=["_test_is_combinatorially_isomorphic", # optional - sage.rings.number_field sage.groups ....: "_test_product", ....: "_test_pyramid", ....: "_test_lawrence"]) - sage: id = polytopes.icosidodecahedron(backend='normaliz') # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.groups - sage: id.f_vector() # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.groups + sage: id = polytopes.icosidodecahedron(backend='normaliz') # optional - pynormaliz sage.rings.number_field sage.groups + sage: id.f_vector() # optional - pynormaliz sage.rings.number_field sage.groups (1, 30, 60, 32, 1) - sage: id.base_ring() # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.groups - Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? - sage: TestSuite(id).run() # long time # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.groups + sage: id.base_ring() # optional - pynormaliz sage.rings.number_field sage.groups + Number Field in sqrt5 with defining polynomial x^2 - 5 + with sqrt5 = 2.236067977499790? + sage: TestSuite(id).run() # long time # optional - pynormaliz sage.rings.number_field sage.groups """ from sage.rings.number_field.number_field import QuadraticField from itertools import product @@ -1530,10 +1533,11 @@ def icosidodecahedron_V2(self, exact=True, base_ring=None, backend=None): EXAMPLES:: sage: id = polytopes.icosidodecahedron_V2() # long time - 6secs - sage: id.f_vector() # long time + sage: id.f_vector() # long time (1, 30, 60, 32, 1) - sage: id.base_ring() # long time - Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? + sage: id.base_ring() # long time + Number Field in sqrt5 with defining polynomial x^2 - 5 + with sqrt5 = 2.236067977499790? A much faster implementation using floating point approximations:: @@ -1552,12 +1556,13 @@ def icosidodecahedron_V2(self, exact=True, base_ring=None, backend=None): TESTS:: - sage: id = polytopes.icosidodecahedron_V2(backend='normaliz') # optional - pynormaliz - sage: id.f_vector() # optional - pynormaliz + sage: id = polytopes.icosidodecahedron_V2(backend='normaliz') # optional - pynormaliz + sage: id.f_vector() # optional - pynormaliz (1, 30, 60, 32, 1) - sage: id.base_ring() # optional - pynormaliz - Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? - sage: TestSuite(id).run() # optional - pynormaliz, long time + sage: id.base_ring() # optional - pynormaliz + Number Field in sqrt5 with defining polynomial x^2 - 5 + with sqrt5 = 2.236067977499790? + sage: TestSuite(id).run() # long time # optional - pynormaliz """ if base_ring is None and exact: from sage.rings.number_field.number_field import QuadraticField @@ -1600,24 +1605,25 @@ def truncated_dodecahedron(self, exact=True, base_ring=None, backend=None): EXAMPLES:: - sage: td = polytopes.truncated_dodecahedron() # optional - sage.rings.number_field - sage: td.f_vector() # optional - sage.rings.number_field + sage: td = polytopes.truncated_dodecahedron() # optional - sage.rings.number_field + sage: td.f_vector() # optional - sage.rings.number_field (1, 60, 90, 32, 1) - sage: td.base_ring() # optional - sage.rings.number_field - Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? + sage: td.base_ring() # optional - sage.rings.number_field + Number Field in sqrt5 with defining polynomial x^2 - 5 + with sqrt5 = 2.236067977499790? Its facets are 20 triangles and 12 regular decagons:: - sage: sum(1 for f in td.facets() if len(f.vertices()) == 3) # optional - sage.rings.number_field + sage: sum(1 for f in td.facets() if len(f.vertices()) == 3) # optional - sage.rings.number_field 20 - sage: sum(1 for f in td.facets() if len(f.vertices()) == 10) # optional - sage.rings.number_field + sage: sum(1 for f in td.facets() if len(f.vertices()) == 10) # optional - sage.rings.number_field 12 The faster implementation using floating point approximations does not fully work unfortunately, see https://github.com/cddlib/cddlib/pull/7 for a detailed discussion of this case:: - sage: td = polytopes.truncated_dodecahedron(exact=False) # random + sage: td = polytopes.truncated_dodecahedron(exact=False) # random doctest:warning ... UserWarning: This polyhedron data is numerically complicated; cdd @@ -1633,11 +1639,12 @@ def truncated_dodecahedron(self, exact=True, base_ring=None, backend=None): TESTS:: - sage: td = polytopes.truncated_dodecahedron(backend='normaliz') # optional - pynormaliz # optional - sage.rings.number_field - sage: td.f_vector() # optional - pynormaliz # optional - sage.rings.number_field + sage: td = polytopes.truncated_dodecahedron(backend='normaliz') # optional - pynormaliz sage.rings.number_field + sage: td.f_vector() # optional - pynormaliz sage.rings.number_field (1, 60, 90, 32, 1) - sage: td.base_ring() # optional - pynormaliz # optional - sage.rings.number_field - Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? + sage: td.base_ring() # optional - pynormaliz sage.rings.number_field + Number Field in sqrt5 with defining polynomial x^2 - 5 + with sqrt5 = 2.236067977499790? """ if base_ring is None and exact: @@ -1736,8 +1743,8 @@ def Kirkman_icosahedron(self, backend=None): TESTS:: - sage: ki_norm = polytopes.Kirkman_icosahedron(backend='normaliz') # optional - pynormaliz - sage: TestSuite(ki_norm).run() # optional - pynormaliz + sage: ki_norm = polytopes.Kirkman_icosahedron(backend='normaliz') # optional - pynormaliz + sage: TestSuite(ki_norm).run() # optional - pynormaliz """ vertices = [[9, 6, 6], [-9, 6, 6], [9, -6, 6], [9, 6, -6], [-9, -6, 6], [-9, 6, -6], [9, -6, -6], [-9, -6, -6], @@ -1769,10 +1776,11 @@ def rhombicosidodecahedron(self, exact=True, base_ring=None, backend=None): EXAMPLES:: sage: rid = polytopes.rhombicosidodecahedron() # long time - 6secs - sage: rid.f_vector() # long time + sage: rid.f_vector() # long time (1, 60, 120, 62, 1) - sage: rid.base_ring() # long time - Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? + sage: rid.base_ring() # long time + Number Field in sqrt5 with defining polynomial x^2 - 5 + with sqrt5 = 2.236067977499790? A much faster implementation using floating point approximations:: @@ -1793,11 +1801,12 @@ def rhombicosidodecahedron(self, exact=True, base_ring=None, backend=None): TESTS:: - sage: rid = polytopes.rhombicosidodecahedron(backend='normaliz') # optional - pynormaliz - sage: rid.f_vector() # optional - pynormaliz + sage: rid = polytopes.rhombicosidodecahedron(backend='normaliz') # optional - pynormaliz + sage: rid.f_vector() # optional - pynormaliz (1, 60, 120, 62, 1) - sage: rid.base_ring() # optional - pynormaliz - Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? + sage: rid.base_ring() # optional - pynormaliz + Number Field in sqrt5 with defining polynomial x^2 - 5 + with sqrt5 = 2.236067977499790? """ if base_ring is None and exact: @@ -1845,11 +1854,12 @@ def truncated_icosidodecahedron(self, exact=True, base_ring=None, backend=None): EXAMPLES:: - sage: ti = polytopes.truncated_icosidodecahedron() # long time - sage: ti.f_vector() # long time + sage: ti = polytopes.truncated_icosidodecahedron() # long time + sage: ti.f_vector() # long time (1, 120, 180, 62, 1) - sage: ti.base_ring() # long time - Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? + sage: ti.base_ring() # long time + Number Field in sqrt5 with defining polynomial x^2 - 5 + with sqrt5 = 2.236067977499790? The implementation using floating point approximations is much faster:: @@ -1924,17 +1934,20 @@ def snub_dodecahedron(self, base_ring=None, backend=None, verbose=False): Only the backend using the optional normaliz package can construct the snub dodecahedron in reasonable time:: - sage: sd = polytopes.snub_dodecahedron(base_ring=AA, backend='normaliz') # optional - pynormaliz, long time - sage: sd.f_vector() # optional - pynormaliz, long time + sage: sd = polytopes.snub_dodecahedron(base_ring=AA, # optional - pynormaliz, long time + ....: backend='normaliz') + sage: sd.f_vector() # optional - pynormaliz, long time (1, 60, 150, 92, 1) - sage: sd.base_ring() # optional - pynormaliz, long time + sage: sd.base_ring() # optional - pynormaliz, long time Algebraic Real Field Its facets are 80 triangles and 12 pentagons:: - sage: sum(1 for f in sd.facets() if len(f.vertices()) == 3) # optional - pynormaliz, long time + sage: sum(1 for f in sd.facets() # optional - pynormaliz, long time + ....: if len(f.vertices()) == 3) 80 - sage: sum(1 for f in sd.facets() if len(f.vertices()) == 5) # optional - pynormaliz, long time + sage: sum(1 for f in sd.facets() # optional - pynormaliz, long time + ....: if len(f.vertices()) == 5) 12 TESTS: @@ -2009,8 +2022,8 @@ def twenty_four_cell(self, backend=None): TESTS:: - sage: tfcell = polytopes.twenty_four_cell(backend='normaliz') # optional - pynormaliz - sage: TestSuite(tfcell).run() # optional - pynormaliz + sage: tfcell = polytopes.twenty_four_cell(backend='normaliz') # optional - pynormaliz + sage: TestSuite(tfcell).run() # optional - pynormaliz """ q12 = QQ((1, 2)) verts = list(itertools.product([q12, -q12], repeat=4)) @@ -2042,7 +2055,7 @@ def runcitruncated_six_hundred_cell(self, exact=True, backend=None): EXAMPLES:: - sage: polytopes.runcitruncated_six_hundred_cell(backend='normaliz') # not tested - very long time + sage: polytopes.runcitruncated_six_hundred_cell(backend='normaliz') # not tested - very long time A 4-dimensional polyhedron in AA^4 defined as the convex hull of 7200 vertices """ @@ -2071,7 +2084,8 @@ def cantitruncated_six_hundred_cell(self, exact=True, backend=None): EXAMPLES:: - sage: polytopes.cantitruncated_six_hundred_cell(exact=True,backend='normaliz') # not tested - very long time + sage: polytopes.cantitruncated_six_hundred_cell(exact=True, # not tested - very long time + ....: backend='normaliz') A 4-dimensional polyhedron in AA^4 defined as the convex hull of 7200 vertices """ return self.generalized_permutahedron(['H', 4], point=[1, 1, 1, 0], exact=exact, backend=backend, regular=True) @@ -2099,7 +2113,8 @@ def bitruncated_six_hundred_cell(self, exact=True, backend=None): EXAMPLES:: - sage: polytopes.runcinated_six_hundred_cell(exact=True,backend='normaliz') # not tested - very long time + sage: polytopes.runcinated_six_hundred_cell(exact=True, # not tested - very long time + ....: backend='normaliz') A 4-dimensional polyhedron in AA^4 defined as the convex hull of 3600 vertices """ return self.generalized_permutahedron(['H', 4], point=[0, 1, 1, 0], exact=exact, backend=backend, regular=True) @@ -2127,7 +2142,7 @@ def cantellated_six_hundred_cell(self, exact=False, backend=None): EXAMPLES:: - sage: polytopes.cantellated_six_hundred_cell() # not tested - very long time + sage: polytopes.cantellated_six_hundred_cell() # not tested - very long time doctest:warning ... UserWarning: This polyhedron data is numerically complicated; cdd @@ -2139,7 +2154,8 @@ def cantellated_six_hundred_cell(self, exact=False, backend=None): It is possible to use the backend ``'normaliz'`` to get an exact representation:: - sage: polytopes.cantellated_six_hundred_cell(exact=True,backend='normaliz') # not tested - long time + sage: polytopes.cantellated_six_hundred_cell(exact=True, # not tested - long time + ....: backend='normaliz') A 4-dimensional polyhedron in AA^4 defined as the convex hull of 3600 vertices """ return self.generalized_permutahedron(['H', 4], point=[1, 0, 1, 0], exact=exact, backend=backend, regular=True) @@ -2166,7 +2182,7 @@ def truncated_six_hundred_cell(self, exact=False, backend=None): EXAMPLES:: - sage: polytopes.truncated_six_hundred_cell() # not tested - long time + sage: polytopes.truncated_six_hundred_cell() # not tested - long time A 4-dimensional polyhedron in RDF^4 defined as the convex hull of 1440 vertices It is possible to use the backend ``'normaliz'`` to get an exact @@ -2200,7 +2216,7 @@ def rectified_six_hundred_cell(self, exact=True, backend=None): EXAMPLES:: - sage: polytopes.rectified_six_hundred_cell(backend='normaliz') # not tested - long time ~14sec + sage: polytopes.rectified_six_hundred_cell(backend='normaliz') # not tested - long time ~14sec A 4-dimensional polyhedron in AA^4 defined as the convex hull of 720 vertices """ return self.generalized_permutahedron(['H', 4], point=[0, 1, 0, 0], exact=exact, backend=backend, regular=True) @@ -2226,22 +2242,22 @@ def six_hundred_cell(self, exact=False, backend=None): EXAMPLES:: - sage: p600 = polytopes.six_hundred_cell() # optional - sage.groups - sage: p600 # optional - sage.groups + sage: p600 = polytopes.six_hundred_cell(); p600 # optional - sage.groups A 4-dimensional polyhedron in RDF^4 defined as the convex hull of 120 vertices - sage: p600.f_vector() # long time ~2sec # optional - sage.groups + sage: p600.f_vector() # long time ~2sec # optional - sage.groups (1, 120, 720, 1200, 600, 1) Computation with exact coordinates is currently too long to be useful:: - sage: p600 = polytopes.six_hundred_cell(exact=True) # not tested - very long time # optional - sage.groups - sage: len(list(p600.bounded_edges())) # not tested - very long time # optional - sage.groups + sage: p600 = polytopes.six_hundred_cell(exact=True) # not tested - very long time, optional - sage.groups + sage: len(list(p600.bounded_edges())) # not tested - very long time, optional - sage.groups 720 TESTS:: - sage: p600 = polytopes.six_hundred_cell(exact=True, backend='normaliz') # optional - pynormaliz # optional - sage.groups # optional - sage.rings.number_field - sage: len(list(p600.bounded_edges())) # optional - pynormaliz, long time # optional - sage.groups # optional - sage.rings.number_field + sage: p600 = polytopes.six_hundred_cell(exact=True, # optional - pynormaliz sage.groups sage.rings.number_field + ....: backend='normaliz') + sage: len(list(p600.bounded_edges())) # long time # optional - pynormaliz sage.groups sage.rings.number_field 720 """ if exact: @@ -2297,8 +2313,8 @@ def grand_antiprism(self, exact=True, backend=None, verbose=False): Computation with the backend ``'normaliz'`` is instantaneous:: - sage: gap_norm = polytopes.grand_antiprism(backend='normaliz') # optional - pynormaliz # optional - sage.rings.number_field - sage: gap_norm # optional - pynormaliz # optional - sage.rings.number_field + sage: gap_norm = polytopes.grand_antiprism(backend='normaliz') # optional - pynormaliz sage.rings.number_field + sage: gap_norm # optional - pynormaliz sage.rings.number_field A 4-dimensional polyhedron in (Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?)^4 defined as the convex hull of 100 vertices @@ -2454,21 +2470,21 @@ def hypersimplex(self, dim, k, project=False, backend=None): EXAMPLES:: - sage: h_4_2 = polytopes.hypersimplex(4, 2) - sage: h_4_2 + sage: h_4_2 = polytopes.hypersimplex(4, 2) # optional - sage.combinat + sage: h_4_2 # optional - sage.combinat A 3-dimensional polyhedron in ZZ^4 defined as the convex hull of 6 vertices - sage: h_4_2.f_vector() + sage: h_4_2.f_vector() # optional - sage.combinat (1, 6, 12, 8, 1) - sage: h_4_2.ehrhart_polynomial() # optional - latte_int + sage: h_4_2.ehrhart_polynomial() # optional - latte_int sage.combinat 2/3*t^3 + 2*t^2 + 7/3*t + 1 - sage: TestSuite(h_4_2).run() + sage: TestSuite(h_4_2).run() # optional - sage.combinat - sage: h_7_3 = polytopes.hypersimplex(7, 3, project=True) - sage: h_7_3 + sage: h_7_3 = polytopes.hypersimplex(7, 3, project=True) # optional - sage.combinat + sage: h_7_3 # optional - sage.combinat A 6-dimensional polyhedron in RDF^6 defined as the convex hull of 35 vertices - sage: h_7_3.f_vector() + sage: h_7_3.f_vector() # optional - sage.combinat (1, 35, 210, 350, 245, 84, 14, 1) - sage: TestSuite(h_7_3).run(skip=["_test_pyramid", "_test_lawrence"]) + sage: TestSuite(h_7_3).run(skip=["_test_pyramid", "_test_lawrence"]) # optional - sage.combinat """ verts = Permutations([0] * (dim - k) + [1] * k).list() if project: @@ -2516,7 +2532,7 @@ def permutahedron(self, n, project=False, backend=None): A 3-dimensional polyhedron in RDF^3 defined as the convex hull of 24 vertices sage: perm4.plot() # optional - sage.plot Graphics3d Object - sage: perm4.graph().is_isomorphic(graphs.BubbleSortGraph(4)) # optional - sage.graphs + sage: perm4.graph().is_isomorphic(graphs.BubbleSortGraph(4)) # optional - sage.graphs True As both Hrepresentation an Vrepresentation are known, the permutahedron can be set @@ -2594,32 +2610,35 @@ def generalized_permutahedron(self, coxeter_type, point=None, exact=True, regula EXAMPLES:: - sage: perm_a3 = polytopes.generalized_permutahedron(['A',3]); perm_a3 # optional - sage.combinat + sage: perm_a3 = polytopes.generalized_permutahedron(['A',3]); perm_a3 # optional - sage.combinat A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 24 vertices You can put the starting point along the hyperplane of the first generator:: - sage: perm_a3_011 = polytopes.generalized_permutahedron(['A',3],[0,1,1]); perm_a3_011 # optional - sage.combinat + sage: perm_a3_011 = polytopes.generalized_permutahedron(['A',3], [0,1,1]) # optional - sage.combinat + sage: perm_a3_011 A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 12 vertices - sage: perm_a3_110 = polytopes.generalized_permutahedron(['A',3],[1,1,0]); perm_a3_110 # optional - sage.combinat + sage: perm_a3_110 = polytopes.generalized_permutahedron(['A',3], [1,1,0]) # optional - sage.combinat + sage: perm_a3_110 A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 12 vertices - sage: perm_a3_110.is_combinatorially_isomorphic(perm_a3_011) # optional - sage.combinat + sage: perm_a3_110.is_combinatorially_isomorphic(perm_a3_011) # optional - sage.combinat True - sage: perm_a3_101 = polytopes.generalized_permutahedron(['A',3],[1,0,1]); perm_a3_101 # optional - sage.combinat + sage: perm_a3_101 = polytopes.generalized_permutahedron(['A',3], [1,0,1]) # optional - sage.combinat + sage: perm_a3_101 A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 12 vertices - sage: perm_a3_110.is_combinatorially_isomorphic(perm_a3_101) # optional - sage.combinat + sage: perm_a3_110.is_combinatorially_isomorphic(perm_a3_101) # optional - sage.combinat False - sage: perm_a3_011.f_vector() # optional - sage.combinat + sage: perm_a3_011.f_vector() # optional - sage.combinat (1, 12, 18, 8, 1) - sage: perm_a3_101.f_vector() # optional - sage.combinat + sage: perm_a3_101.f_vector() # optional - sage.combinat (1, 12, 24, 14, 1) The usual output does not necessarily give a polyhedron with isometric vertex figures:: - sage: perm_a2 = polytopes.generalized_permutahedron(['A',2]) # optional - sage.combinat - sage: perm_a2.vertices() # optional - sage.combinat + sage: perm_a2 = polytopes.generalized_permutahedron(['A',2]) # optional - sage.combinat + sage: perm_a2.vertices() # optional - sage.combinat (A vertex at (-1, -1), A vertex at (-1, 0), A vertex at (0, -1), @@ -2629,18 +2648,20 @@ def generalized_permutahedron(self, coxeter_type, point=None, exact=True, regula It works also with Coxeter types that lead to non-rational coordinates:: - sage: perm_b3 = polytopes.generalized_permutahedron(['B',3]); perm_b3 # long time # optional - sage.combinat # optional - sage.rings.number_field - A 3-dimensional polyhedron - in (Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095?)^3 - defined as the convex hull of 48 vertices + sage: perm_b3 = polytopes.generalized_permutahedron(['B',3]) # long time # optional - sage.combinat sage.rings.number_field + sage: perm_b3 # long time # optional - sage.combinat sage.rings.number_field + A 3-dimensional polyhedron in + (Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095?)^3 + defined as the convex hull of 48 vertices Setting ``regular=True`` applies a linear transformation to get isometric vertex figures and the result is inscribed. This cannot be done using rational coordinates. We first do the computations using floating point approximations (``RDF``):: - sage: perm_a2_inexact = polytopes.generalized_permutahedron(['A',2], exact=False) # optional - sage.combinat - sage: sorted(perm_a2_inexact.vertices()) # optional - sage.combinat + sage: perm_a2_inexact = polytopes.generalized_permutahedron( # optional - sage.combinat + ....: ['A',2], exact=False) + sage: sorted(perm_a2_inexact.vertices()) # optional - sage.combinat [A vertex at (-1.0, -1.0), A vertex at (-1.0, 0.0), A vertex at (0.0, -1.0), @@ -2648,9 +2669,9 @@ def generalized_permutahedron(self, coxeter_type, point=None, exact=True, regula A vertex at (1.0, 0.0), A vertex at (1.0, 1.0)] - sage: perm_a2_inexact_reg = polytopes.generalized_permutahedron(['A',2], exact=False, # optional - sage.combinat - ....: regular=True) - sage: sorted(perm_a2_inexact_reg.vertices()) # optional - sage.combinat + sage: perm_a2_inexact_reg = polytopes.generalized_permutahedron( # optional - sage.combinat + ....: ['A',2], exact=False, regular=True) + sage: sorted(perm_a2_inexact_reg.vertices()) # optional - sage.combinat [A vertex at (-1.0, 0.0), A vertex at (-0.5, -0.8660254038), A vertex at (-0.5, 0.8660254038), @@ -2660,8 +2681,9 @@ def generalized_permutahedron(self, coxeter_type, point=None, exact=True, regula We can do the same computation using exact arithmetic with the field ``AA``:: - sage: perm_a2_reg = polytopes.generalized_permutahedron(['A',2], regular=True) # optional - sage.combinat # optional - sage.rings.number_field - sage: V = sorted(perm_a2_reg.vertices()); V # random # optional - sage.combinat # optional - sage.rings.number_field + sage: perm_a2_reg = polytopes.generalized_permutahedron( # optional - sage.combinat sage.rings.number_field + ....: ['A',2], regular=True) + sage: V = sorted(perm_a2_reg.vertices()); V # random # optional - sage.combinat sage.rings.number_field [A vertex at (-1, 0), A vertex at (-1/2, -0.866025403784439?), A vertex at (-1/2, 0.866025403784439?), @@ -2672,60 +2694,62 @@ def generalized_permutahedron(self, coxeter_type, point=None, exact=True, regula Even though the numbers look like floating point approximations, the computation is actually exact. We can clean up the display a bit using ``exactify``:: - sage: for v in V: # optional - sage.combinat # optional - sage.rings.number_field + sage: for v in V: # optional - sage.combinat sage.rings.number_field ....: for x in v: ....: x.exactify() - sage: V # optional - sage.combinat # optional - sage.rings.number_field + sage: V # optional - sage.combinat sage.rings.number_field [A vertex at (-1, 0), A vertex at (-1/2, -0.866025403784439?), A vertex at (-1/2, 0.866025403784439?), A vertex at (1/2, -0.866025403784439?), A vertex at (1/2, 0.866025403784439?), A vertex at (1, 0)] - sage: perm_a2_reg.is_inscribed() # optional - sage.combinat # optional - sage.rings.number_field + sage: perm_a2_reg.is_inscribed() # optional - sage.combinat sage.rings.number_field True Larger examples take longer:: - sage: perm_a3_reg = polytopes.generalized_permutahedron(['A',3], regular=True); perm_a3_reg # long time # optional - sage.rings.number_field # optional - sage.combinat + sage: perm_a3_reg = polytopes.generalized_permutahedron( # long time # optional - sage.rings.number_field sage.combinat + ....: ['A',3], regular=True); perm_a3_reg A 3-dimensional polyhedron in AA^3 defined as the convex hull of 24 vertices - sage: perm_a3_reg.is_inscribed() # long time # optional - sage.rings.number_field # optional - sage.combinat + sage: perm_a3_reg.is_inscribed() # long time # optional - sage.rings.number_field sage.combinat True - sage: perm_b3_reg = polytopes.generalized_permutahedron(['B',3], regular=True); perm_b3_reg # not tested # optional - sage.rings.number_field # optional - sage.combinat # long time (12sec on 64 bits) + sage: perm_b3_reg = polytopes.generalized_permutahedron( # not tested # optional - sage.rings.number_field sage.combinat # long time (12sec on 64 bits) + ....: ['B',3], regular=True); perm_b3_reg A 3-dimensional polyhedron in AA^3 defined as the convex hull of 48 vertices It is faster with the backend ``'number_field'``, which internally uses an embedded number field instead of doing the computations directly with the base ring (``AA``):: - sage: perm_a3_reg_nf = polytopes.generalized_permutahedron( # optional - sage.rings.number_field # optional - sage.combinat + sage: perm_a3_reg_nf = polytopes.generalized_permutahedron( # optional - sage.rings.number_field sage.combinat ....: ['A',3], regular=True, backend='number_field'); perm_a3_reg_nf A 3-dimensional polyhedron in AA^3 defined as the convex hull of 24 vertices - sage: perm_a3_reg_nf.is_inscribed() # optional - sage.rings.number_field # optional - sage.combinat + sage: perm_a3_reg_nf.is_inscribed() # optional - sage.rings.number_field sage.combinat True - sage: perm_b3_reg_nf = polytopes.generalized_permutahedron( # long time # optional - sage.rings.number_field # optional - sage.combinat + sage: perm_b3_reg_nf = polytopes.generalized_permutahedron( # long time # optional - sage.rings.number_field sage.combinat ....: ['B',3], regular=True, backend='number_field'); perm_b3_reg_nf A 3-dimensional polyhedron in AA^3 defined as the convex hull of 48 vertices It is even faster with the backend ``'normaliz'``:: - sage: perm_a3_reg_norm = polytopes.generalized_permutahedron( # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.combinat + sage: perm_a3_reg_norm = polytopes.generalized_permutahedron( # optional - pynormaliz sage.rings.number_field sage.combinat ....: ['A',3], regular=True, backend='normaliz'); perm_a3_reg_norm A 3-dimensional polyhedron in AA^3 defined as the convex hull of 24 vertices - sage: perm_a3_reg_norm.is_inscribed() # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.combinat + sage: perm_a3_reg_norm.is_inscribed() # optional - pynormaliz sage.rings.number_field sage.combinat True - sage: perm_b3_reg_norm = polytopes.generalized_permutahedron( # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.combinat + sage: perm_b3_reg_norm = polytopes.generalized_permutahedron( # optional - pynormaliz sage.rings.number_field sage.combinat ....: ['B',3], regular=True, backend='normaliz'); perm_b3_reg_norm A 3-dimensional polyhedron in AA^3 defined as the convex hull of 48 vertices The speedups from using backend ``'normaliz'`` allow us to go even further:: - sage: perm_h3 = polytopes.generalized_permutahedron(['H',3], backend='normaliz') # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.combinat - sage: perm_h3 # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.combinat - A 3-dimensional polyhedron - in (Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790?)^3 + sage: perm_h3 = polytopes.generalized_permutahedron( # optional - pynormaliz sage.rings.number_field sage.combinat + ....: ['H',3], backend='normaliz'); perm_h3 + A 3-dimensional polyhedron in + (Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790?)^3 defined as the convex hull of 120 vertices - sage: perm_f4 = polytopes.generalized_permutahedron(['F',4], backend='normaliz') # long time # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.combinat - sage: perm_f4 # long time # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.combinat + sage: perm_f4 = polytopes.generalized_permutahedron( # long time, optional - pynormaliz sage.rings.number_field sage.combinat + ....: ['F',4], backend='normaliz'); perm_f4 A 4-dimensional polyhedron in (Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095?)^4 defined as the convex hull of 1152 vertices @@ -2737,7 +2761,7 @@ def generalized_permutahedron(self, coxeter_type, point=None, exact=True, regula TESTS:: - sage: TestSuite(perm_h3).run() # optional - pynormaliz # optional - sage.rings.number_field # optional - sage.combinat + sage: TestSuite(perm_h3).run() # optional - pynormaliz sage.rings.number_field sage.combinat """ from sage.combinat.root_system.coxeter_group import CoxeterGroup try: @@ -2817,7 +2841,7 @@ def omnitruncated_one_hundred_twenty_cell(self, exact=True, backend=None): EXAMPLES:: - sage: polytopes.omnitruncated_one_hundred_twenty_cell(backend='normaliz') # not tested - very long time ~10min + sage: polytopes.omnitruncated_one_hundred_twenty_cell(backend='normaliz') # not tested - very long time ~10min A 4-dimensional polyhedron in AA^4 defined as the convex hull of 14400 vertices """ if not exact: @@ -2850,7 +2874,7 @@ def runcitruncated_one_hundred_twenty_cell(self, exact=False, backend=None): EXAMPLES:: - sage: polytopes.runcitruncated_one_hundred_twenty_cell(exact=False) # not tested - very long time + sage: polytopes.runcitruncated_one_hundred_twenty_cell(exact=False) # not tested - very long time doctest:warning ... UserWarning: This polyhedron data is numerically complicated; cdd @@ -2861,7 +2885,8 @@ def runcitruncated_one_hundred_twenty_cell(self, exact=False, backend=None): It is possible to use the backend ``'normaliz'`` to get an exact representation:: - sage: polytopes.runcitruncated_one_hundred_twenty_cell(exact=True,backend='normaliz') # not tested - very long time + sage: polytopes.runcitruncated_one_hundred_twenty_cell(exact=True, # not tested - very long time + ....: backend='normaliz') A 4-dimensional polyhedron in AA^4 defined as the convex hull of 7200 vertices """ return self.generalized_permutahedron(['H', 4], point=[1, 0, 1, 1], exact=exact, backend=backend, regular=True) @@ -2889,7 +2914,7 @@ def cantitruncated_one_hundred_twenty_cell(self, exact=True, backend=None): EXAMPLES:: - sage: polytopes.cantitruncated_one_hundred_twenty_cell(exact=True,backend='normaliz') # not tested - very long time + sage: polytopes.cantitruncated_one_hundred_twenty_cell(exact=True, backend='normaliz') # not tested - very long time A 4-dimensional polyhedron in AA^4 defined as the convex hull of 7200 vertices """ return self.generalized_permutahedron(['H', 4], point=[0, 1, 1, 1], exact=exact, backend=backend, regular=True) @@ -2917,7 +2942,7 @@ def runcinated_one_hundred_twenty_cell(self, exact=False, backend=None): EXAMPLES:: - sage: polytopes.runcinated_one_hundred_twenty_cell(exact=False) # not tested - very long time + sage: polytopes.runcinated_one_hundred_twenty_cell(exact=False) # not tested - very long time doctest:warning ... UserWarning: This polyhedron data is numerically complicated; cdd could not convert between the inexact V and H representation without loss of data. The resulting object @@ -2927,7 +2952,8 @@ def runcinated_one_hundred_twenty_cell(self, exact=False, backend=None): It is possible to use the backend ``'normaliz'`` to get an exact representation:: - sage: polytopes.runcinated_one_hundred_twenty_cell(exact=True,backend='normaliz') # not tested - very long time + sage: polytopes.runcinated_one_hundred_twenty_cell(exact=True, # not tested - very long time + ....: backend='normaliz') A 4-dimensional polyhedron in AA^4 defined as the convex hull of 2400 vertices """ return self.generalized_permutahedron(['H', 4], point=[1, 0, 0, 1], exact=exact, backend=backend, regular=True) @@ -2955,7 +2981,7 @@ def cantellated_one_hundred_twenty_cell(self, exact=True, backend=None): EXAMPLES:: - sage: polytopes.cantellated_one_hundred_twenty_cell(backend='normaliz') # not tested - long time + sage: polytopes.cantellated_one_hundred_twenty_cell(backend='normaliz') # not tested - long time A 4-dimensional polyhedron in AA^4 defined as the convex hull of 3600 vertices """ return self.generalized_permutahedron(['H', 4], point=[0, 1, 0, 1], exact=exact, backend=backend, regular=True) @@ -2983,7 +3009,7 @@ def truncated_one_hundred_twenty_cell(self, exact=True, backend=None): EXAMPLES:: - sage: polytopes.truncated_one_hundred_twenty_cell(backend='normaliz') # not tested - long time + sage: polytopes.truncated_one_hundred_twenty_cell(backend='normaliz') # not tested - long time A 4-dimensional polyhedron in AA^4 defined as the convex hull of 2400 vertices """ return self.generalized_permutahedron(['H', 4], point=[0, 0, 1, 1], exact=exact, backend=backend, regular=True) @@ -3011,7 +3037,7 @@ def rectified_one_hundred_twenty_cell(self, exact=True, backend=None): EXAMPLES:: - sage: polytopes.rectified_one_hundred_twenty_cell(backend='normaliz') # not tested - long time + sage: polytopes.rectified_one_hundred_twenty_cell(backend='normaliz') # not tested - long time A 4-dimensional polyhedron in AA^4 defined as the convex hull of 1200 vertices """ return self.generalized_permutahedron(['H', 4], point=[0, 0, 1, 0], exact=exact, backend=backend, regular=True) @@ -3046,24 +3072,26 @@ def one_hundred_twenty_cell(self, exact=True, backend=None, construction='coxete sage: polytopes.one_hundred_twenty_cell() # not tested - long time ~15 sec. A 4-dimensional polyhedron in (Number Field in sqrt5 with defining - polynomial x^2 - 5 with sqrt5 = 2.236067977499790?)^4 defined as - the convex hull of 600 vertices + polynomial x^2 - 5 with sqrt5 = 2.236067977499790?)^4 defined as + the convex hull of 600 vertices The ``'normaliz'`` is faster:: sage: P = polytopes.one_hundred_twenty_cell(backend='normaliz'); P # optional - pynormaliz A 4-dimensional polyhedron in (Number Field in sqrt5 with defining - polynomial x^2 - 5 with sqrt5 = 2.236067977499790?)^4 defined as the convex hull of 600 vertices + polynomial x^2 - 5 with sqrt5 = 2.236067977499790?)^4 defined as + the convex hull of 600 vertices It is also possible to realize it using the generalized permutahedron of type `H_4`:: - sage: polytopes.one_hundred_twenty_cell(backend='normaliz',construction='as_permutahedron') # not tested - long time + sage: polytopes.one_hundred_twenty_cell(backend='normaliz', # not tested - long time + ....: construction='as_permutahedron') A 4-dimensional polyhedron in AA^4 defined as the convex hull of 600 vertices TESTS:: - sage: TestSuite(P).run() # optional - pynormaliz, long time + sage: TestSuite(P).run() # long time, optional - pynormaliz """ if construction == 'coxeter': if not exact: @@ -3151,7 +3179,7 @@ def hypercube(self, dim, intervals=None, backend=None): Return the `0/1`-hypercube of dimension 4:: - sage: z_cube = polytopes.hypercube(4,intervals = 'zero_one') + sage: z_cube = polytopes.hypercube(4, intervals='zero_one') sage: z_cube.vertices()[0] A vertex at (1, 0, 1, 1) sage: z_cube.is_simple() @@ -3160,13 +3188,13 @@ def hypercube(self, dim, intervals=None, backend=None): Integer Ring sage: z_cube.volume() 1 - sage: z_cube.ehrhart_polynomial() # optional - latte_int + sage: z_cube.ehrhart_polynomial() # optional - latte_int t^4 + 4*t^3 + 6*t^2 + 4*t + 1 Return the 4-dimensional combinatorial cube that is the product of [0,3]^4:: - sage: t_cube = polytopes.hypercube(4, intervals = [[0,3]]*4) + sage: t_cube = polytopes.hypercube(4, intervals=[[0,3]]*4) Checking that t_cube is three times the previous `0/1`-cube:: @@ -3194,14 +3222,14 @@ def hypercube(self, dim, intervals=None, backend=None): If the dimension ``dim`` is not equal to the length of intervals, an error is raised:: - sage: u_cube = polytopes.hypercube(2,intervals = [[0,1],[0,2],[0,3]]) + sage: u_cube = polytopes.hypercube(2, intervals=[[0,1],[0,2],[0,3]]) Traceback (most recent call last): ... ValueError: the dimension of the hypercube must match the number of intervals The intervals must be pairs `(a, b)` with `a < b`:: - sage: w_cube = polytopes.hypercube(3, intervals = [[0,1],[3,2],[0,3]]) + sage: w_cube = polytopes.hypercube(3, intervals=[[0,1],[3,2],[0,3]]) Traceback (most recent call last): ... ValueError: each interval must be a pair `(a, b)` with `a < b` @@ -3209,7 +3237,7 @@ def hypercube(self, dim, intervals=None, backend=None): If a string besides 'zero_one' is passed to ``intervals``, return an error:: - sage: v_cube = polytopes.hypercube(3,intervals = 'a_string') + sage: v_cube = polytopes.hypercube(3, intervals='a_string') Traceback (most recent call last): ... ValueError: the only allowed string is 'zero_one' @@ -3219,7 +3247,7 @@ def hypercube(self, dim, intervals=None, backend=None): sage: ls = [randint(-100,100) for _ in range(4)] sage: intervals = [[x, x+randint(1,50)] for x in ls] sage: P = polytopes.hypercube(4, intervals, backend='field') - sage: P1 = polytopes.hypercube(4, intervals, backend='ppl') + sage: P1 = polytopes.hypercube(4, intervals, backend='ppl') # optional - pplpy sage: assert P == P1 Check that coercion for input invervals is handled correctly:: @@ -3227,7 +3255,7 @@ def hypercube(self, dim, intervals=None, backend=None): sage: P = polytopes.hypercube(2, [[1/2, 2], [0, 1]]) sage: P = polytopes.hypercube(2, [[1/2, 2], [0, 1.0]]) sage: P = polytopes.hypercube(2, [[1/2, 2], [0, AA(2).sqrt()]]) # optional - sage.rings.number_field - sage: P = polytopes.hypercube(2, [[1/2, 2], [0, 1.0]], backend='ppl') + sage: P = polytopes.hypercube(2, [[1/2, 2], [0, 1.0]], backend='ppl') # optional - pplpy Traceback (most recent call last): ... ValueError: specified backend ppl cannot handle the intervals @@ -3304,13 +3332,13 @@ def cube(self, intervals=None, backend=None): - ``intervals`` -- list (default=None). It takes the following possible inputs: - - If the input is ``None`` (the default), returns the convex hull of - the eight `\pm 1` vectors of length three. + - If the input is ``None`` (the default), returns the convex hull of + the eight `\pm 1` vectors of length three. - - ``'zero_one'`` -- (string). Return the `0/1`-cube. + - ``'zero_one'`` -- (string). Return the `0/1`-cube. - - a list of 3 lists of length 2. The cube will be a product of - these three intervals. + - a list of 3 lists of length 2. The cube will be a product of + these three intervals. - ``backend`` -- the backend to use to create the polytope. @@ -3372,7 +3400,7 @@ def cross_polytope(self, dim, backend=None): TESTS:: - sage: cp = polytopes.cross_polytope(4,backend='normaliz') # optional - pynormaliz + sage: cp = polytopes.cross_polytope(4, backend='normaliz') # optional - pynormaliz sage: TestSuite(cp).run() # optional - pynormaliz :: @@ -3410,19 +3438,19 @@ def parallelotope(self, generators, backend=None): sage: polytopes.parallelotope([ (1,0), (0,1) ]) A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices - sage: polytopes.parallelotope([[1,2,3,4],[0,1,0,7],[3,1,0,2],[0,0,1,0]]) + sage: polytopes.parallelotope([[1,2,3,4], [0,1,0,7], [3,1,0,2], [0,0,1,0]]) A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 16 vertices - sage: K = QuadraticField(2, 'sqrt2') # optional - sage.rings.number_field - sage: sqrt2 = K.gen() # optional - sage.rings.number_field - sage: P = polytopes.parallelotope([(1, sqrt2), (1, -1)]); P # optional - sage.rings.number_field + sage: K = QuadraticField(2, 'sqrt2') # optional - sage.rings.number_field + sage: sqrt2 = K.gen() # optional - sage.rings.number_field + sage: P = polytopes.parallelotope([(1, sqrt2), (1, -1)]); P # optional - sage.rings.number_field A 2-dimensional polyhedron in (Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095?)^2 defined as the convex hull of 4 vertices TESTS:: - sage: TestSuite(P).run() # optional - sage.rings.number_field + sage: TestSuite(P).run() # optional - sage.rings.number_field """ from sage.modules.free_module_element import vector generators = [vector(v) for v in generators] diff --git a/src/sage/geometry/polyhedron/misc.py b/src/sage/geometry/polyhedron/misc.py index 1e0345c054f..ad0ad961bf1 100644 --- a/src/sage/geometry/polyhedron/misc.py +++ b/src/sage/geometry/polyhedron/misc.py @@ -30,7 +30,7 @@ def _to_space_separated_string(l, base_ring=None): sage: import sage.geometry.polyhedron.misc as P sage: P._to_space_separated_string([2,3]) '2 3' - sage: P._to_space_separated_string([2, 1/5], RDF) + sage: P._to_space_separated_string([2, 1/5], RDF) # optional - sage.rings.real_double '2.0 0.2' """ if base_ring: diff --git a/src/sage/geometry/polyhedron/parent.py b/src/sage/geometry/polyhedron/parent.py index 3640e0c524b..1993f17b1cc 100644 --- a/src/sage/geometry/polyhedron/parent.py +++ b/src/sage/geometry/polyhedron/parent.py @@ -64,7 +64,7 @@ def Polyhedra(ambient_space_or_base_ring=None, ambient_dim=None, backend=None, * EXAMPLES:: sage: from sage.geometry.polyhedron.parent import Polyhedra - sage: Polyhedra(AA, 3) # optional - sage.rings.number_field + sage: Polyhedra(AA, 3) # optional - sage.rings.number_field Polyhedra in AA^3 sage: Polyhedra(ZZ, 3) Polyhedra in ZZ^3 @@ -96,32 +96,34 @@ def Polyhedra(ambient_space_or_base_ring=None, ambient_dim=None, backend=None, * TESTS:: - sage: Polyhedra(RR, 3, backend='field') # optional - sage.rings.real_mpfr + sage: Polyhedra(RR, 3, backend='field') # optional - sage.rings.real_mpfr Traceback (most recent call last): ... ValueError: the 'field' backend for polyhedron cannot be used with non-exact fields - sage: Polyhedra(RR, 3) # optional - sage.rings.real_mpfr + sage: Polyhedra(RR, 3) # optional - sage.rings.real_mpfr Traceback (most recent call last): ... ValueError: no default backend for computations with Real Field with 53 bits of precision - sage: Polyhedra(QQ[I], 2) # optional - sage.rings.number_field + sage: Polyhedra(QQ[I], 2) # optional - sage.rings.number_field Traceback (most recent call last): ... - ValueError: invalid base ring: Number Field in I with defining polynomial x^2 + 1 with I = 1*I cannot be coerced to a real field - sage: Polyhedra(AA, 3, backend='polymake') # optional - jupymake # optional - sage.rings.number_field + ValueError: invalid base ring: Number Field in I + with defining polynomial x^2 + 1 with I = 1*I + cannot be coerced to a real field + sage: Polyhedra(AA, 3, backend='polymake') # optional - jupymake sage.rings.number_field Traceback (most recent call last): ... ValueError: the 'polymake' backend for polyhedron cannot be used with Algebraic Real Field - sage: Polyhedra(QQ, 2, backend='normaliz') # optional - pynormaliz + sage: Polyhedra(QQ, 2, backend='normaliz') # optional - pynormaliz Polyhedra in QQ^2 - sage: Polyhedra(SR, 2, backend='normaliz') # optional - pynormaliz # optional - sage.symbolic + sage: Polyhedra(SR, 2, backend='normaliz') # optional - pynormaliz sage.symbolic Polyhedra in (Symbolic Ring)^2 - sage: SCR = SR.subring(no_variables=True) # optional - sage.symbolic - sage: Polyhedra(SCR, 2, backend='normaliz') # optional - pynormaliz # optional - sage.symbolic + sage: SCR = SR.subring(no_variables=True) # optional - sage.symbolic + sage: Polyhedra(SCR, 2, backend='normaliz') # optional - pynormaliz sage.symbolic Polyhedra in (Symbolic Constants Subring)^2 - sage: Polyhedra(SCR, 2, backend='number_field') # optional - sage.symbolic + sage: Polyhedra(SCR, 2, backend='number_field') # optional - sage.symbolic Polyhedra in (Symbolic Constants Subring)^2 """ @@ -208,15 +210,15 @@ class Polyhedra_base(UniqueRepresentation, Parent): - ``backend`` -- string. The name of the backend for computations. There are several backends implemented: - * ``backend="ppl"`` uses the Parma Polyhedra Library + * ``backend="ppl"`` uses the Parma Polyhedra Library - * ``backend="cdd"`` uses CDD + * ``backend="cdd"`` uses CDD - * ``backend="normaliz"`` uses normaliz + * ``backend="normaliz"`` uses normaliz - * ``backend="polymake"`` uses polymake + * ``backend="polymake"`` uses polymake - * ``backend="field"`` a generic Sage implementation + * ``backend="field"`` a generic Sage implementation EXAMPLES:: @@ -270,13 +272,13 @@ def list(self): sage: P.cardinality() +Infinity - sage: P = Polyhedra(AA, 0) # optional - sage.rings.number_field - sage: P.category() # optional - sage.rings.number_field + sage: P = Polyhedra(AA, 0) # optional - sage.rings.number_field + sage: P.category() # optional - sage.rings.number_field Category of finite enumerated polyhedral sets over Algebraic Real Field - sage: P.list() # optional - sage.rings.number_field + sage: P.list() # optional - sage.rings.number_field [The empty polyhedron in AA^0, A 0-dimensional polyhedron in AA^0 defined as the convex hull of 1 vertex] - sage: P.cardinality() # optional - sage.rings.number_field + sage: P.cardinality() # optional - sage.rings.number_field 2 """ if self.ambient_dim(): @@ -380,11 +382,14 @@ def some_elements(self): sage: from sage.geometry.polyhedron.parent import Polyhedra sage: Polyhedra(QQ, 4).some_elements() - [A 3-dimensional polyhedron in QQ^4 defined as the convex hull of 4 vertices, - A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 1 vertex and 4 rays, - A 2-dimensional polyhedron in QQ^4 defined as the convex hull of 2 vertices and 1 ray, + [A 3-dimensional polyhedron in QQ^4 + defined as the convex hull of 4 vertices, + A 4-dimensional polyhedron in QQ^4 + defined as the convex hull of 1 vertex and 4 rays, + A 2-dimensional polyhedron in QQ^4 + defined as the convex hull of 2 vertices and 1 ray, The empty polyhedron in QQ^4] - sage: Polyhedra(ZZ,0).some_elements() + sage: Polyhedra(ZZ, 0).some_elements() [The empty polyhedron in ZZ^0, A 0-dimensional polyhedron in ZZ^0 defined as the convex hull of 1 vertex] """ @@ -413,7 +418,7 @@ def zero(self): sage: from sage.geometry.polyhedron.parent import Polyhedra sage: p = Polyhedra(QQ, 4).zero(); p A 0-dimensional polyhedron in QQ^4 defined as the convex hull of 1 vertex - sage: p+p == p + sage: p + p == p True """ Vrep = [[[self.base_ring().zero()]*self.ambient_dim()], [], []] @@ -443,7 +448,8 @@ def universe(self): sage: from sage.geometry.polyhedron.parent import Polyhedra sage: P = Polyhedra(QQ, 4) sage: P.universe() - A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 1 vertex and 4 lines + A 4-dimensional polyhedron in QQ^4 defined as + the convex hull of 1 vertex and 4 lines sage: P.universe().is_universe() True """ @@ -510,8 +516,8 @@ def _repr_base_ring(self): sage: from sage.geometry.polyhedron.parent import Polyhedra sage: Polyhedra(QQ, 3)._repr_base_ring() 'QQ' - sage: K. = NumberField(x^2 - 3, embedding=AA(3).sqrt()) # optional - sage.rings.number_field - sage: Polyhedra(K, 4)._repr_base_ring() # optional - sage.rings.number_field + sage: K. = NumberField(x^2 - 3, embedding=AA(3).sqrt()) # optional - sage.rings.number_field + sage: Polyhedra(K, 4)._repr_base_ring() # optional - sage.rings.number_field '(Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878?)' """ @@ -544,8 +550,8 @@ def _repr_ambient_module(self): sage: from sage.geometry.polyhedron.parent import Polyhedra sage: Polyhedra(QQ, 3)._repr_ambient_module() 'QQ^3' - sage: K. = NumberField(x^2 - 3, embedding=AA(3).sqrt()) # optional - sage.rings.number_field - sage: Polyhedra(K, 4)._repr_ambient_module() # optional - sage.rings.number_field + sage: K. = NumberField(x^2 - 3, embedding=AA(3).sqrt()) # optional - sage.rings.number_field + sage: Polyhedra(K, 4)._repr_ambient_module() # optional - sage.rings.number_field '(Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878?)^4' """ s = self._repr_base_ring() @@ -600,12 +606,13 @@ def _element_constructor_(self, *args, **kwds): Check that :trac:`21270` is fixed:: - sage: poly = polytopes.regular_polygon(7) # optional - sage.rings.number_field - sage: lp, x = poly.to_linear_program(solver='InteractiveLP', return_variable=True) # optional - sage.rings.number_field - sage: lp.set_objective(x[0] + x[1]) # optional - sage.rings.number_field - sage: b = lp.get_backend() # optional - sage.rings.number_field - sage: P = b.interactive_lp_problem() # optional - sage.rings.number_field - sage: p = P.plot() # optional - sage.plot # optional - sage.rings.number_field + sage: poly = polytopes.regular_polygon(7) # optional - sage.rings.number_field + sage: lp, x = poly.to_linear_program(solver='InteractiveLP', # optional - sage.rings.number_field + ....: return_variable=True) + sage: lp.set_objective(x[0] + x[1]) # optional - sage.rings.number_field + sage: b = lp.get_backend() # optional - sage.rings.number_field + sage: P = b.interactive_lp_problem() # optional - sage.rings.number_field + sage: p = P.plot() # optional - sage.plot sage.rings.number_field sage: Q = Polyhedron(ieqs=[[-499999, 1000000], [1499999, -1000000]]) sage: P = Polyhedron(ieqs=[[0, 1.0], [1.0, -1.0]], base_ring=RDF) @@ -627,11 +634,11 @@ def _element_constructor_(self, *args, **kwds): When the parent of the object is not ``self``, the default is not to copy:: - sage: Q = P.base_extend(AA) # optional - sage.rings.number_field - sage: q = Q._element_constructor_(p) # optional - sage.rings.number_field - sage: q is p # optional - sage.rings.number_field + sage: Q = P.base_extend(AA) # optional - sage.rings.number_field + sage: q = Q._element_constructor_(p) # optional - sage.rings.number_field + sage: q is p # optional - sage.rings.number_field False - sage: q = Q._element_constructor_(p, copy=False) # optional - sage.rings.number_field + sage: q = Q._element_constructor_(p, copy=False) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: you need to make a copy when changing the parent @@ -718,10 +725,10 @@ def _element_constructor_polyhedron(self, polyhedron, **kwds): sage: P(p) A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices - sage: P = Polyhedra(AA, 3, backend='field') # optional - sage.rings.number_field + sage: P = Polyhedra(AA, 3, backend='field') # optional - sage.rings.number_field sage: vertices = [(0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1)] - sage: p = Polyhedron(vertices=vertices) # optional - sage.rings.number_field - sage: P(p) # optional - sage.rings.number_field + sage: p = Polyhedron(vertices=vertices) # optional - sage.rings.number_field + sage: P(p) # optional - sage.rings.number_field A 3-dimensional polyhedron in AA^3 defined as the convex hull of 4 vertices """ Vrep = None @@ -745,9 +752,9 @@ def base_extend(self, base_ring, backend=None, ambient_dim=None): EXAMPLES:: sage: from sage.geometry.polyhedron.parent import Polyhedra - sage: Polyhedra(ZZ,3).base_extend(QQ) + sage: Polyhedra(ZZ, 3).base_extend(QQ) Polyhedra in QQ^3 - sage: Polyhedra(ZZ,3).an_element().base_extend(QQ) + sage: Polyhedra(ZZ, 3).an_element().base_extend(QQ) A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices sage: Polyhedra(QQ, 2).base_extend(ZZ) Polyhedra in QQ^2 @@ -781,9 +788,9 @@ def change_ring(self, base_ring, backend=None, ambient_dim=None): EXAMPLES:: sage: from sage.geometry.polyhedron.parent import Polyhedra - sage: Polyhedra(ZZ,3).change_ring(QQ) + sage: Polyhedra(ZZ, 3).change_ring(QQ) Polyhedra in QQ^3 - sage: Polyhedra(ZZ,3).an_element().change_ring(QQ) + sage: Polyhedra(ZZ, 3).an_element().change_ring(QQ) A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices sage: Polyhedra(RDF, 3).change_ring(QQ).backend() @@ -818,26 +825,26 @@ def _coerce_base_ring(self, other): - ``other`` -- must be either: - * another ``Polyhedron`` object + * another ``Polyhedron`` object - * `\ZZ`, `\QQ`, `RDF`, or a ring that can be coerced into them. + * `\ZZ`, `\QQ`, `RDF`, or a ring that can be coerced into them. - * a constant that can be coerced to `\ZZ`, `\QQ`, or `RDF`. + * a constant that can be coerced to `\ZZ`, `\QQ`, or `RDF`. OUTPUT: - Either `\ZZ`, `\QQ`, or `RDF`. Raises ``TypeError`` if + Either `\ZZ`, `\QQ`, or `RDF`. Raises :class:`TypeError` if ``other`` is not a suitable input. .. NOTE:: "Real" numbers in sage are not necessarily elements of - `RDF`. For example, the literal `1.0` is not. + ``RDF``. For example, the literal `1.0` is not. EXAMPLES:: - sage: triangle_QQ = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=QQ).parent() - sage: triangle_RDF = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=RDF).parent() + sage: triangle_QQ = Polyhedron(vertices=[[1,0],[0,1],[1,1]], base_ring=QQ).parent() + sage: triangle_RDF = Polyhedron(vertices=[[1,0],[0,1],[1,1]], base_ring=RDF).parent() sage: triangle_QQ._coerce_base_ring(QQ) Rational Field sage: triangle_QQ._coerce_base_ring(triangle_RDF) @@ -858,15 +865,15 @@ def _coerce_base_ring(self, other): Test that :trac:`28770` is fixed:: sage: z = QQ['z'].0 - sage: K = NumberField(z^2 - 2, 's') # optional - sage.rings.number_field - sage: triangle_QQ._coerce_base_ring(K) # optional - sage.rings.number_field + sage: K = NumberField(z^2 - 2, 's') # optional - sage.rings.number_field + sage: triangle_QQ._coerce_base_ring(K) # optional - sage.rings.number_field Number Field in s with defining polynomial z^2 - 2 - sage: triangle_QQ._coerce_base_ring(K.gen()) # optional - sage.rings.number_field + sage: triangle_QQ._coerce_base_ring(K.gen()) # optional - sage.rings.number_field Number Field in s with defining polynomial z^2 - 2 sage: z = QQ['z'].0 - sage: K = NumberField(z^2 - 2, 's') # optional - sage.rings.number_field - sage: K.gen() * polytopes.simplex(backend='field') # optional - sage.rings.number_field + sage: K = NumberField(z^2 - 2, 's') # optional - sage.rings.number_field + sage: K.gen() * polytopes.simplex(backend='field') # optional - sage.rings.number_field A 3-dimensional polyhedron in (Number Field in s with defining polynomial z^2 - 2)^4 defined as the convex hull of 4 vertices @@ -905,7 +912,7 @@ def _coerce_base_ring(self, other): def _coerce_map_from_(self, X): r""" - Return whether there is a coercion from ``X`` + Return whether there is a coercion from ``X``. INPUT: @@ -918,9 +925,9 @@ def _coerce_map_from_(self, X): EXAMPLES:: sage: from sage.geometry.polyhedron.parent import Polyhedra - sage: Polyhedra(QQ,3).has_coerce_map_from( Polyhedra(ZZ,3) ) # indirect doctest + sage: Polyhedra(QQ, 3).has_coerce_map_from(Polyhedra(ZZ, 3)) # indirect doctest True - sage: Polyhedra(ZZ,3).has_coerce_map_from( Polyhedra(QQ,3) ) + sage: Polyhedra(ZZ, 3).has_coerce_map_from(Polyhedra(QQ, 3)) False """ if not isinstance(X, Polyhedra_base): @@ -990,8 +997,10 @@ def _get_action_(self, other, op, self_is_left): sage: from sage.geometry.polyhedron.parent import Polyhedra sage: PZZ2.get_action(ZZ^2, op=operator.add) Right action by Ambient free module of rank 2 over the principal ideal domain Integer Ring on Polyhedra in ZZ^2 - with precomposition on left by Identity endomorphism of Polyhedra in ZZ^2 - with precomposition on right by Generic endomorphism of Ambient free module of rank 2 over the principal ideal domain Integer Ring + with precomposition on left by + Identity endomorphism of Polyhedra in ZZ^2 + with precomposition on right by + Generic endomorphism of Ambient free module of rank 2 over the principal ideal domain Integer Ring """ import operator @@ -1045,7 +1054,7 @@ def _make_Inequality(self, polyhedron, data): EXAMPLES:: - sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)]) # indirect doctest + sage: p = Polyhedron([(1,2,3), (2/3,3/4,4/5)]) # indirect doctest sage: next(p.inequality_generator()) An inequality (0, 0, -1) x + 3 >= 0 """ @@ -1072,7 +1081,7 @@ def _make_Equation(self, polyhedron, data): EXAMPLES:: - sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)]) # indirect doctest + sage: p = Polyhedron([(1,2,3), (2/3,3/4,4/5)]) # indirect doctest sage: next(p.equation_generator()) An equation (0, 44, -25) x - 13 == 0 """ @@ -1099,7 +1108,7 @@ def _make_Vertex(self, polyhedron, data): EXAMPLES:: - sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)], rays=[(5/6,6/7,7/8)]) # indirect doctest + sage: p = Polyhedron([(1,2,3), (2/3,3/4,4/5)], rays=[(5/6,6/7,7/8)]) # indirect doctest sage: next(p.vertex_generator()) A vertex at (1, 2, 3) """ @@ -1126,7 +1135,7 @@ def _make_Ray(self, polyhedron, data): EXAMPLES:: - sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)], rays=[(5/6,6/7,7/8)]) # indirect doctest + sage: p = Polyhedron([(1,2,3), (2/3,3/4,4/5)], rays=[(5/6,6/7,7/8)]) # indirect doctest sage: next(p.ray_generator()) A ray in the direction (140, 144, 147) """ @@ -1153,7 +1162,7 @@ def _make_Line(self, polyhedron, data): EXAMPLES:: - sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)], lines=[(5/6,6/7,7/8)]) # indirect doctest + sage: p = Polyhedron([(1,2,3), (2/3,3/4,4/5)], lines=[(5/6,6/7,7/8)]) # indirect doctest sage: next(p.line_generator()) A line in the direction (140, 144, 147) """ @@ -1266,9 +1275,9 @@ def does_backend_handle_base_ring(base_ring, backend): sage: from sage.geometry.polyhedron.parent import does_backend_handle_base_ring sage: does_backend_handle_base_ring(QQ, 'ppl') True - sage: does_backend_handle_base_ring(QQ[sqrt(5)], 'ppl') # optional - sage.rings.number_field + sage: does_backend_handle_base_ring(QQ[sqrt(5)], 'ppl') # optional - sage.rings.number_field sage.symbolic False - sage: does_backend_handle_base_ring(QQ[sqrt(5)], 'field') # optional - sage.rings.number_field + sage: does_backend_handle_base_ring(QQ[sqrt(5)], 'field') # optional - sage.rings.number_field sage.symbolic True """ try: diff --git a/src/sage/geometry/polyhedron/plot.py b/src/sage/geometry/polyhedron/plot.py index c54b92116f3..472ab1cf8c2 100644 --- a/src/sage/geometry/polyhedron/plot.py +++ b/src/sage/geometry/polyhedron/plot.py @@ -435,11 +435,11 @@ def identity(self): EXAMPLES:: - sage: p = polytopes.icosahedron(exact=False) # optional - sage.groups + sage: p = polytopes.icosahedron(exact=False) # optional - sage.groups sage: from sage.geometry.polyhedron.plot import Projection - sage: pproj = Projection(p) # optional - sage.groups - sage: ppid = pproj.identity() # optional - sage.groups - sage: ppid.dimension # optional - sage.groups + sage: pproj = Projection(p) # optional - sage.groups + sage: ppid = pproj.identity() # optional - sage.groups + sage: ppid.dimension # optional - sage.groups 3 """ return self(projection_func_identity) @@ -456,12 +456,11 @@ def stereographic(self, projection_point=None): EXAMPLES:: sage: from sage.geometry.polyhedron.plot import Projection - sage: proj = Projection(polytopes.buckyball()) #long time - sage: proj #long time + sage: proj = Projection(polytopes.buckyball()); proj # long time The projection of a polyhedron into 3 dimensions - sage: proj.stereographic([5,2,3]).plot() #long time # optional - sage.plot + sage: proj.stereographic([5,2,3]).plot() # long time # optional - sage.plot Graphics object consisting of 123 graphics primitives - sage: Projection( polytopes.twenty_four_cell() ).stereographic([2,0,0,0]) + sage: Projection(polytopes.twenty_four_cell()).stereographic([2,0,0,0]) The projection of a polyhedron into 3 dimensions """ if projection_point is None: @@ -505,24 +504,24 @@ def schlegel(self, facet=None, position=None): sage: tcube4 = cube4.face_truncation(cube4.faces(0)[0]) sage: tcube4.facets()[4] A 3-dimensional face of a Polyhedron in QQ^4 defined as the convex hull of 4 vertices - sage: into_tetra = Projection(tcube4).schlegel(tcube4.facets()[4]) # optional - sage.symbolic - sage: into_tetra.plot() # optional - sage.plot # optional - sage.symbolic + sage: into_tetra = Projection(tcube4).schlegel(tcube4.facets()[4]) # optional - sage.symbolic + sage: into_tetra.plot() # optional - sage.plot sage.symbolic Graphics3d Object Taking a larger value for the position changes the image:: - sage: into_tetra_far = Projection(tcube4).schlegel(tcube4.facets()[4], 4) # optional - sage.symbolic - sage: into_tetra_far.plot() # optional - sage.plot # optional - sage.symbolic + sage: into_tetra_far = Projection(tcube4).schlegel(tcube4.facets()[4], 4) # optional - sage.symbolic + sage: into_tetra_far.plot() # optional - sage.plot sage.symbolic Graphics3d Object A value which is too large or negative give a projection point that sees more than one facet resulting in a error:: - sage: Projection(tcube4).schlegel(tcube4.facets()[4],5) + sage: Projection(tcube4).schlegel(tcube4.facets()[4], 5) Traceback (most recent call last): ... ValueError: the chosen position is too large - sage: Projection(tcube4).schlegel(tcube4.facets()[4],-1) + sage: Projection(tcube4).schlegel(tcube4.facets()[4], -1) Traceback (most recent call last): ... ValueError: 'position' should be a positive number @@ -582,7 +581,7 @@ def coord_indices_of(self, v_list): sage: p = polytopes.hypercube(3) sage: proj = p.projection() - sage: proj.coord_indices_of([vector((1,1,1)),vector((1,-1,1))]) + sage: proj.coord_indices_of([vector((1,1,1)), vector((1,-1,1))]) [2, 3] """ return [self.coord_index_of(v) for v in v_list] @@ -638,7 +637,7 @@ def _init_from_2d(self, polyhedron): TESTS:: - sage: p = Polyhedron(vertices = [[0,0],[0,1],[1,0],[1,1]]) + sage: p = Polyhedron(vertices=[[0,0],[0,1],[1,0],[1,1]]) sage: proj = p.projection() sage: [proj.coordinates_of([i]) for i in proj.points] [[[0, 0]], [[0, 1]], [[1, 0]], [[1, 1]]] @@ -660,7 +659,7 @@ def _init_from_3d(self, polyhedron): TESTS:: - sage: p = Polyhedron(vertices = [[0,0,1],[0,1,2],[1,0,3],[1,1,5]]) + sage: p = Polyhedron(vertices=[[0,0,1],[0,1,2],[1,0,3],[1,1,5]]) sage: proj = p.projection() sage: [proj.coordinates_of([i]) for i in proj.points] [[[0, 0, 1]], [[0, 1, 2]], [[1, 0, 3]], [[1, 1, 5]]] @@ -699,7 +698,7 @@ def _init_lines_arrows(self, polyhedron): TESTS:: - sage: p = Polyhedron(ieqs = [[1, 0, 0, 1],[1,1,0,0]]) + sage: p = Polyhedron(ieqs=[[1, 0, 0, 1], [1, 1, 0, 0]]) sage: pp = p.projection() sage: pp.arrows [[0, 1], [0, 2], [0, 3], [0, 4]] @@ -711,7 +710,7 @@ def _init_lines_arrows(self, polyhedron): We check that :trac:`31802` is fixed:: - sage: x = Polyhedron(lines=[(1, 0, 0),(0, 1, 0)], rays=[(0, 0, 1)]) + sage: x = Polyhedron(lines=[(1, 0, 0), (0, 1, 0)], rays=[(0, 0, 1)]) sage: y = x.projection() sage: del y.arrows sage: y.arrows = Sequence([]) @@ -823,12 +822,12 @@ def _init_solid_3d(self, polyhedron): sage: proj.polygons [[1, 0, 2], [3, 0, 1], [2, 0, 3], [3, 1, 2]] - sage: x = Polyhedron(rays = [(-1, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1)]) + sage: x = Polyhedron(rays=[(-1, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1)]) sage: y = x.projection() sage: y.polygons [[5, 2, 1, 6], [2, 7, 8, 1]] - sage: cylinder = Polyhedron(vertices = [(0, 0, 0), (1, 0, 0), (0, 1, 0)], lines=[(0, 0, 1)]) + sage: cylinder = Polyhedron(vertices=[(0, 0, 0), (1, 0, 0), (0, 1, 0)], lines=[(0, 0, 1)]) sage: len(cylinder.projection().polygons) 3 """ @@ -918,8 +917,8 @@ def render_points_1d(self, **kwds): sage: cube1 = polytopes.hypercube(1) sage: proj = cube1.projection() - sage: points = proj.render_points_1d() # optional - sage.plot - sage: points._objects # optional - sage.plot + sage: points = proj.render_points_1d() # optional - sage.plot + sage: points._objects # optional - sage.plot [Point set defined by 2 point(s)] """ return point2d([c + [0] for c in self.coordinates_of(self.points)], **kwds) @@ -939,8 +938,8 @@ def render_line_1d(self, **kwds): EXAMPLES:: - sage: outline = polytopes.hypercube(1).projection().render_line_1d() # optional - sage.plot - sage: outline._objects[0] # optional - sage.plot + sage: outline = polytopes.hypercube(1).projection().render_line_1d() # optional - sage.plot + sage: outline._objects[0] # optional - sage.plot Line defined by 2 points """ if len(self.lines) == 0: @@ -957,10 +956,10 @@ def render_points_2d(self, **kwds): EXAMPLES:: - sage: hex = polytopes.regular_polygon(6) # optional - sage.rings.number_field - sage: proj = hex.projection() # optional - sage.rings.number_field - sage: hex_points = proj.render_points_2d() # optional - sage.plot # optional - sage.rings.number_field - sage: hex_points._objects # optional - sage.plot # optional - sage.rings.number_field + sage: hex = polytopes.regular_polygon(6) # optional - sage.rings.number_field + sage: proj = hex.projection() # optional - sage.rings.number_field + sage: hex_points = proj.render_points_2d() # optional - sage.plot sage.rings.number_field + sage: hex_points._objects # optional - sage.plot sage.rings.number_field [Point set defined by 6 point(s)] """ return point2d(self.coordinates_of(self.points), **kwds) @@ -971,9 +970,9 @@ def render_outline_2d(self, **kwds): EXAMPLES:: - sage: penta = polytopes.regular_polygon(5) # optional - sage.rings.number_field - sage: outline = penta.projection().render_outline_2d() # optional - sage.plot # optional - sage.rings.number_field - sage: outline._objects[0] # optional - sage.plot # optional - sage.rings.number_field + sage: penta = polytopes.regular_polygon(5) # optional - sage.rings.number_field + sage: outline = penta.projection().render_outline_2d() # optional - sage.plot sage.rings.number_field + sage: outline._objects[0] # optional - sage.plot sage.rings.number_field Line defined by 2 points """ wireframe = [] @@ -991,11 +990,11 @@ def render_fill_2d(self, **kwds): EXAMPLES:: - sage: cps = [i^3 for i in srange(-2,2,1/5)] - sage: p = Polyhedron(vertices = [[(t^2-1)/(t^2+1),2*t/(t^2+1)] for t in cps]) + sage: cps = [i^3 for i in srange(-2, 2, 1/5)] + sage: p = Polyhedron(vertices=[[(t^2-1)/(t^2+1), 2*t/(t^2+1)] for t in cps]) sage: proj = p.projection() - sage: filled_poly = proj.render_fill_2d() # optional - sage.plot - sage: filled_poly.axes_width() # optional - sage.plot + sage: filled_poly = proj.render_fill_2d() # optional - sage.plot + sage: filled_poly.axes_width() # optional - sage.plot 0.8 """ poly = [polygon2d(self.coordinates_of(p), **kwds) @@ -1010,8 +1009,8 @@ def render_vertices_3d(self, **kwds): sage: p = polytopes.cross_polytope(3) sage: proj = p.projection() - sage: verts = proj.render_vertices_3d() # optional - sage.plot - sage: verts.bounding_box() # optional - sage.plot + sage: verts = proj.render_vertices_3d() # optional - sage.plot + sage: verts.bounding_box() # optional - sage.plot ((-1.0, -1.0, -1.0), (1.0, 1.0, 1.0)) """ return point3d(self.coordinates_of(self.points), **kwds) @@ -1024,8 +1023,8 @@ def render_wireframe_3d(self, **kwds): sage: cube = polytopes.hypercube(3) sage: cube_proj = cube.projection() - sage: wire = cube_proj.render_wireframe_3d() # optional - sage.plot - sage: print(wire.tachyon().split('\n')[77]) # for testing # optional - sage.plot + sage: wire = cube_proj.render_wireframe_3d() # optional - sage.plot + sage: print(wire.tachyon().split('\n')[77]) # for testing # optional - sage.plot FCylinder base 1.0 1.0 -1.0 apex -1.0 1.0 -1.0 rad 0.005 texture... """ wireframe = [] @@ -1044,8 +1043,8 @@ def render_solid_3d(self, **kwds): EXAMPLES:: sage: p = polytopes.hypercube(3).projection() - sage: p_solid = p.render_solid_3d(opacity=.7) # optional - sage.plot - sage: type(p_solid) # optional - sage.plot + sage: p_solid = p.render_solid_3d(opacity=.7) # optional - sage.plot + sage: type(p_solid) # optional - sage.plot """ polys = self.polygons @@ -1075,9 +1074,10 @@ def render_0d(self, point_opts=None, line_opts=None, polygon_opts=None): EXAMPLES:: - sage: print(Polyhedron([]).projection().render_0d().description()) # optional - sage.plot + sage: print(Polyhedron([]).projection().render_0d().description()) # optional - sage.plot - sage: print(Polyhedron(ieqs=[(1,)]).projection().render_0d().description()) # optional - sage.plot + sage: P = Polyhedron(ieqs=[(1,)]) + sage: print(P.projection().render_0d().description()) # optional - sage.plot Point set defined by 1 point(s): [(0.0, 0.0)] """ if point_opts is None: @@ -1106,7 +1106,7 @@ def render_1d(self, point_opts=None, line_opts=None, polygon_opts=None): EXAMPLES:: - sage: Polyhedron([(0,), (1,)]).projection().render_1d() # optional - sage.plot + sage: Polyhedron([(0,), (1,)]).projection().render_1d() # optional - sage.plot Graphics object consisting of 2 graphics primitives """ plt = Graphics() @@ -1138,7 +1138,7 @@ def render_2d(self, point_opts=None, line_opts=None, polygon_opts=None): sage: q3 = p3.projection() sage: p4 = Polyhedron(vertices=[[2,0]], rays=[[1,-1]], lines=[[1,1]]) sage: q4 = p4.projection() - sage: q1.plot() + q2.plot() + q3.plot() + q4.plot() # optional - sage.plot + sage: q1.plot() + q2.plot() + q3.plot() + q4.plot() # optional - sage.plot Graphics object consisting of 18 graphics primitives """ plt = Graphics() @@ -1169,29 +1169,33 @@ def render_3d(self, point_opts=None, line_opts=None, polygon_opts=None): sage: p1 = Polyhedron(vertices=[[1,1,1]], rays=[[1,1,1]]) sage: p2 = Polyhedron(vertices=[[2,0,0], [0,2,0], [0,0,2]]) - sage: p3 = Polyhedron(vertices=[[1,0,0], [0,1,0], [0,0,1]], rays=[[-1,-1,-1]]) - sage: p1.projection().plot() + p2.projection().plot() + p3.projection().plot() # optional - sage.plot + sage: p3 = Polyhedron(vertices=[[1,0,0], [0,1,0], [0,0,1]], + ....: rays=[[-1,-1,-1]]) + sage: (p1.projection().plot() + p2.projection().plot() # optional - sage.plot + ....: + p3.projection().plot()) Graphics3d Object It correctly handles various degenerate cases:: - sage: Polyhedron(lines=[[1,0,0],[0,1,0],[0,0,1]]).plot() # whole space # optional - sage.plot + sage: Polyhedron(lines=[[1,0,0], [0,1,0], [0,0,1]]).plot() # whole space # optional - sage.plot Graphics3d Object - sage: Polyhedron(vertices=[[1,1,1]], rays=[[1,0,0]], # optional - sage.plot - ....: lines=[[0,1,0],[0,0,1]]).plot() # half space + sage: Polyhedron(vertices=[[1,1,1]], rays=[[1,0,0]], # optional - sage.plot + ....: lines=[[0,1,0], [0,0,1]]).plot() # half space Graphics3d Object - sage: Polyhedron(vertices=[[1,1,1]], # optional - sage.plot - ....: lines=[[0,1,0],[0,0,1]]).plot() # R^2 in R^3 + sage: Polyhedron(lines=[[0,1,0], [0,0,1]], # optional - sage.plot + ....: vertices=[[1,1,1]]).plot() # R^2 in R^3 Graphics3d Object - sage: Polyhedron(rays=[[0,1,0],[0,0,1]], lines=[[1,0,0]]).plot() # quadrant wedge in R^2 # optional - sage.plot + sage: Polyhedron(rays=[[0,1,0], [0,0,1]], # quadrant wedge in R^2 # optional - sage.plot + ....: lines=[[1,0,0]]).plot() Graphics3d Object - sage: Polyhedron(rays=[[0,1,0]], lines=[[1,0,0]]).plot() # upper half plane in R^3 # optional - sage.plot + sage: Polyhedron(rays=[[0,1,0]], # upper half plane in R^3 # optional - sage.plot + ....: lines=[[1,0,0]]).plot() Graphics3d Object - sage: Polyhedron(lines=[[1,0,0]]).plot() # R^1 in R^2 # optional - sage.plot + sage: Polyhedron(lines=[[1,0,0]]).plot() # R^1 in R^2 # optional - sage.plot Graphics3d Object - sage: Polyhedron(rays=[[0,1,0]]).plot() # Half-line in R^3 # optional - sage.plot + sage: Polyhedron(rays=[[0,1,0]]).plot() # Half-line in R^3 # optional - sage.plot Graphics3d Object - sage: Polyhedron(vertices=[[1,1,1]]).plot() # point in R^3 # optional - sage.plot + sage: Polyhedron(vertices=[[1,1,1]]).plot() # point in R^3 # optional - sage.plot Graphics3d Object The origin is not included, if it is not in the polyhedron (:trac:`23555`):: @@ -1199,13 +1203,13 @@ def render_3d(self, point_opts=None, line_opts=None, polygon_opts=None): sage: Q = Polyhedron([[100],[101]]) sage: P = Q*Q*Q; P A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices - sage: p = P.plot() # optional - sage.plot - sage: p.bounding_box() # optional - sage.plot + sage: p = P.plot() # optional - sage.plot + sage: p.bounding_box() # optional - sage.plot ((100.0, 100.0, 100.0), (101.0, 101.0, 101.0)) Plot 3d polytope with rainbow colors:: - sage: polytopes.hypercube(3).plot(polygon='rainbow', alpha=0.4) # optional - sage.plot + sage: polytopes.hypercube(3).plot(polygon='rainbow', alpha=0.4) # optional - sage.plot Graphics3d Object """ pplt = None @@ -1243,28 +1247,28 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, INPUT: - - ``view`` - list (default: [0,0,1]) representing the rotation axis (see note below). - - ``angle`` - integer (default: 0) angle of rotation in degree from 0 to 360 (see note + - ``view`` -- list (default: [0,0,1]) representing the rotation axis (see note below). + - ``angle`` -- integer (default: 0) angle of rotation in degree from 0 to 360 (see note below). - - ``scale`` - integer (default: 1) specifying the scaling of the tikz picture. - - ``edge_color`` - string (default: 'blue!95!black') representing colors which tikz + - ``scale`` -- integer (default: 1) specifying the scaling of the tikz picture. + - ``edge_color`` -- string (default: 'blue!95!black') representing colors which tikz recognize. - - ``facet_color`` - string (default: 'blue!95!black') representing colors which tikz + - ``facet_color`` -- string (default: 'blue!95!black') representing colors which tikz recognize. - - ``vertex_color`` - string (default: 'green') representing colors which tikz + - ``vertex_color`` -- string (default: 'green') representing colors which tikz recognize. - - ``opacity`` - real number (default: 0.8) between 0 and 1 giving the opacity of + - ``opacity`` -- real number (default: 0.8) between 0 and 1 giving the opacity of the front facets. - - ``axis`` - Boolean (default: False) draw the axes at the origin or not. - - ``output_type`` - string (default: ``None``), valid values + - ``axis`` -- Boolean (default: False) draw the axes at the origin or not. + - ``output_type`` -- string (default: ``None``), valid values are ``None`` (deprecated), ``'LatexExpr'`` and ``'TikzPicture'``, - whether to return a LatexExpr object (which inherits from Python - str) or a ``TikzPicture`` object from module + whether to return a :class:`LatexExpr` object (which inherits from Python + :class:`str`) or a :class:`TikzPicture` object from module :mod:`sage.misc.latex_standalone` OUTPUT: - - LatexExpr object or TikzPicture object + :class:`LatexExpr` object or :class:`TikzPicture` object .. NOTE:: @@ -1296,11 +1300,12 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, EXAMPLES:: - sage: P1 = polytopes.small_rhombicuboctahedron() # optional - sage.rings.number_field - sage: Image1 = P1.projection().tikz([1,3,5], 175, scale=4, output_type='TikzPicture') # optional - sage.rings.number_field - sage: type(Image1) # optional - sage.rings.number_field + sage: P1 = polytopes.small_rhombicuboctahedron() # optional - sage.rings.number_field + sage: Image1 = P1.projection().tikz([1,3,5], 175, scale=4, # optional - sage.rings.number_field + ....: output_type='TikzPicture') + sage: type(Image1) # optional - sage.rings.number_field - sage: Image1 # optional - sage.rings.number_field + sage: Image1 # optional - sage.rings.number_field \documentclass[tikz]{standalone} \begin{document} \begin{tikzpicture}% @@ -1317,15 +1322,18 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, %% \end{tikzpicture} \end{document} - sage: _ = Image1.tex('polytope-tikz1.tex') # not tested # optional - sage.rings.number_field - sage: _ = Image1.png('polytope-tikz1.png') # not tested # optional - sage.rings.number_field - sage: _ = Image1.pdf('polytope-tikz1.pdf') # not tested # optional - sage.rings.number_field - sage: _ = Image1.svg('polytope-tikz1.svg') # not tested # optional - sage.rings.number_field + sage: _ = Image1.tex('polytope-tikz1.tex') # not tested # optional - sage.rings.number_field + sage: _ = Image1.png('polytope-tikz1.png') # not tested # optional - sage.rings.number_field + sage: _ = Image1.pdf('polytope-tikz1.pdf') # not tested # optional - sage.rings.number_field + sage: _ = Image1.svg('polytope-tikz1.svg') # not tested # optional - sage.rings.number_field A second example:: sage: P2 = Polyhedron(vertices=[[1, 1], [1, 2], [2, 1]]) - sage: Image2 = P2.projection().tikz(scale=3, edge_color='blue!95!black', facet_color='orange!95!black', opacity=0.4, vertex_color='yellow', axis=True, output_type='TikzPicture') + sage: Image2 = P2.projection().tikz(scale=3, edge_color='blue!95!black', + ....: facet_color='orange!95!black', opacity=0.4, + ....: vertex_color='yellow', axis=True, + ....: output_type='TikzPicture') sage: Image2 \documentclass[tikz]{standalone} \begin{document} @@ -1346,7 +1354,10 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, The second example using a LatexExpr as output type:: - sage: Image2 = P2.projection().tikz(scale=3, edge_color='blue!95!black', facet_color='orange!95!black', opacity=0.4, vertex_color='yellow', axis=True, output_type='LatexExpr') + sage: Image2 = P2.projection().tikz(scale=3, edge_color='blue!95!black', + ....: facet_color='orange!95!black', opacity=0.4, + ....: vertex_color='yellow', axis=True, + ....: output_type='LatexExpr') sage: type(Image2) sage: print('\n'.join(Image2.splitlines()[:4])) @@ -1359,13 +1370,14 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, A third example:: - sage: P3 = Polyhedron(vertices=[[-1, -1, 2], [-1, 2, -1], [2, -1, -1]]) - sage: P3 + sage: P3 = Polyhedron(vertices=[[-1, -1, 2], [-1, 2, -1], [2, -1, -1]]); P3 A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 3 vertices - sage: Image3 = P3.projection().tikz([0.5, -1, -0.1], 55, scale=3, edge_color='blue!95!black', # optional - sage.plot + sage: Image3 = P3.projection().tikz([0.5, -1, -0.1], 55, scale=3, # optional - sage.plot + ....: edge_color='blue!95!black', ....: facet_color='orange!95!black', opacity=0.7, - ....: vertex_color='yellow', axis=True, output_type='TikzPicture') - sage: Image3 # optional - sage.plot + ....: vertex_color='yellow', axis=True, + ....: output_type='TikzPicture') + sage: Image3 # optional - sage.plot \documentclass[tikz]{standalone} \begin{document} \begin{tikzpicture}% @@ -1382,15 +1394,15 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, %% \end{tikzpicture} \end{document} - sage: _ = Image3.tex('polytope-tikz3.tex') # not tested # optional - sage.plot - sage: _ = Image3.png('polytope-tikz3.png') # not tested # optional - sage.plot - sage: _ = Image3.pdf('polytope-tikz3.pdf') # not tested # optional - sage.plot - sage: _ = Image3.svg('polytope-tikz3.svg') # not tested # optional - sage.plot + sage: _ = Image3.tex('polytope-tikz3.tex') # not tested # optional - sage.plot + sage: _ = Image3.png('polytope-tikz3.png') # not tested # optional - sage.plot + sage: _ = Image3.pdf('polytope-tikz3.pdf') # not tested # optional - sage.plot + sage: _ = Image3.svg('polytope-tikz3.svg') # not tested # optional - sage.plot A fourth example:: - sage: P = Polyhedron(vertices=[[1,1,0,0],[1,2,0,0],[2,1,0,0],[0,0,1,0],[0,0,0,1]]) - sage: P + sage: P = Polyhedron(vertices=[[1,1,0,0], [1,2,0,0], + ....: [2,1,0,0], [0,0,1,0], [0,0,0,1]]); P A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices sage: P.projection().tikz(output_type='TikzPicture') Traceback (most recent call last): @@ -1401,8 +1413,8 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, Make it possible to draw Schlegel diagram for 4-polytopes. :: - sage: P=Polyhedron(vertices=[[1,1,0,0],[1,2,0,0],[2,1,0,0],[0,0,1,0],[0,0,0,1]]) - sage: P + sage: P = Polyhedron(vertices=[[1,1,0,0], [1,2,0,0], + ....: [2,1,0,0], [0,0,1,0], [0,0,0,1]]); P A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices sage: P.projection().tikz(output_type='TikzPicture') Traceback (most recent call last): @@ -1457,25 +1469,27 @@ def _tikz_2d(self, scale, edge_color, facet_color, opacity, vertex_color, axis): INPUT: - - ``scale`` - integer specifying the scaling of the tikz picture. - - ``edge_color`` - string representing colors which tikz + - ``scale`` -- integer specifying the scaling of the tikz picture. + - ``edge_color`` -- string representing colors which tikz recognize. - - ``facet_color`` - string representing colors which tikz + - ``facet_color`` -- string representing colors which tikz recognize. - - ``vertex_color`` - string representing colors which tikz + - ``vertex_color`` -- string representing colors which tikz recognize. - - ``opacity`` - real number between 0 and 1 giving the opacity of + - ``opacity`` -- real number between 0 and 1 giving the opacity of the front facets. - - ``axis`` - Boolean (default: False) draw the axes at the origin or not. + - ``axis`` -- Boolean (default: ``False``) draw the axes at the origin or not. OUTPUT: - - LatexExpr -- containing the TikZ picture. + :class:`LatexExpr` -- containing the TikZ picture. EXAMPLES:: - sage: P = Polyhedron(vertices=[[1, 1],[1, 2],[2, 1]]) - sage: Image = P.projection()._tikz_2d(scale=3, edge_color='black', facet_color='orange', opacity=0.75, vertex_color='yellow', axis=True) + sage: P = Polyhedron(vertices=[[1, 1], [1, 2], [2, 1]]) + sage: Image = P.projection()._tikz_2d(scale=3, edge_color='black', + ....: facet_color='orange', opacity=0.75, + ....: vertex_color='yellow', axis=True) sage: type(Image) sage: print('\n'.join(Image.splitlines()[:4])) @@ -1488,7 +1502,7 @@ def _tikz_2d(self, scale, edge_color, facet_color, opacity, vertex_color, axis): Scientific notation is not used in the output (:trac:`16519`):: - sage: P = Polyhedron([[2*10^-10,0],[0,1],[1,0]],base_ring=QQ) + sage: P = Polyhedron([[2*10^-10,0], [0,1], [1,0]], base_ring=QQ) sage: tikz = P.projection().tikz(output_type='TikzPicture') sage: 'e-10' in tikz.content() False @@ -1585,26 +1599,26 @@ def _tikz_2d_in_3d(self, view, angle, scale, edge_color, facet_color, INPUT: - - ``view`` - list (default: [0,0,1]) representing the rotation axis. - - ``angle`` - integer angle of rotation in degree from 0 to 360. - - ``scale`` - integer specifying the scaling of the tikz picture. - - ``edge_color`` - string representing colors which tikz + - ``view`` -- list (default: [0,0,1]) representing the rotation axis. + - ``angle`` -- integer angle of rotation in degree from 0 to 360. + - ``scale`` -- integer specifying the scaling of the tikz picture. + - ``edge_color`` -- string representing colors which tikz recognize. - - ``facet_color`` - string representing colors which tikz + - ``facet_color`` -- string representing colors which tikz recognize. - - ``vertex_color`` - string representing colors which tikz + - ``vertex_color`` -- string representing colors which tikz recognize. - - ``opacity`` - real number between 0 and 1 giving the opacity of + - ``opacity`` -- real number between 0 and 1 giving the opacity of the front facets. - - ``axis`` - Boolean draw the axes at the origin or not. + - ``axis`` -- Boolean draw the axes at the origin or not. OUTPUT: - - LatexExpr -- containing the TikZ picture. + :class:`LatexExpr` -- containing the TikZ picture. EXAMPLES:: - sage: P = Polyhedron(vertices=[[-1, -1, 2],[-1, 2, -1],[2, -1, -1]]) + sage: P = Polyhedron(vertices=[[-1, -1, 2], [-1, 2, -1], [2, -1, -1]]) sage: P A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 3 vertices sage: Image = P.projection()._tikz_2d_in_3d(view=[0.5, -1, -0.5], angle=55, scale=3, # optional - sage.plot @@ -1739,22 +1753,22 @@ def _tikz_3d_in_3d(self, view, angle, scale, edge_color, INPUT: - - ``view`` - list (default: [0,0,1]) representing the rotation axis. - - ``angle`` - integer angle of rotation in degree from 0 to 360. - - ``scale`` - integer specifying the scaling of the tikz picture. - - ``edge_color`` - string representing colors which tikz + - ``view`` -- list (default: [0,0,1]) representing the rotation axis. + - ``angle`` -- integer angle of rotation in degree from 0 to 360. + - ``scale`` -- integer specifying the scaling of the tikz picture. + - ``edge_color`` -- string representing colors which tikz recognize. - - ``facet_color`` - string representing colors which tikz + - ``facet_color`` -- string representing colors which tikz recognize. - - ``vertex_color`` - string representing colors which tikz + - ``vertex_color`` -- string representing colors which tikz recognize. - - ``opacity`` - real number between 0 and 1 giving the opacity of + - ``opacity`` -- real number between 0 and 1 giving the opacity of the front facets. - - ``axis`` - Boolean draw the axes at the origin or not. + - ``axis`` -- Boolean draw the axes at the origin or not. OUTPUT: - - LatexExpr -- containing the TikZ picture. + :class:`LatexExpr` -- containing the TikZ picture. EXAMPLES:: diff --git a/src/sage/geometry/polyhedron/ppl_lattice_polytope.py b/src/sage/geometry/polyhedron/ppl_lattice_polytope.py index 08b767e54e2..1d4950c482b 100644 --- a/src/sage/geometry/polyhedron/ppl_lattice_polytope.py +++ b/src/sage/geometry/polyhedron/ppl_lattice_polytope.py @@ -45,7 +45,7 @@ Finally, we can compute automorphisms and identify fibrations that only differ by a lattice automorphism:: - sage: square = LatticePolytope_PPL((-1,-1),(-1,1),(1,-1),(1,1)) + sage: square = LatticePolytope_PPL((-1,-1), (-1,1), (1,-1), (1,1)) sage: fibers = [ f.vertices() for f in square.fibration_generator(1) ]; fibers [((1, 0), (-1, 0)), ((0, 1), (0, -1)), ((-1, -1), (1, 1)), ((-1, 1), (1, -1))] sage: square.pointsets_mod_automorphism(fibers) # optional - sage.groups @@ -115,39 +115,39 @@ def LatticePolytope_PPL(*args): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: LatticePolytope_PPL((0,0),(1,0),(0,1)) + sage: LatticePolytope_PPL((0,0), (1,0), (0,1)) A 2-dimensional lattice polytope in ZZ^2 with 3 vertices - sage: from ppl import point, Generator_System, C_Polyhedron, Linear_Expression, Variable - sage: p = point(Linear_Expression([2,3],0)); p + sage: from ppl import point, Generator_System, C_Polyhedron, Linear_Expression # optional - pplpy + sage: p = point(Linear_Expression([2,3],0)); p # optional - pplpy point(2/1, 3/1) - sage: LatticePolytope_PPL(p) + sage: LatticePolytope_PPL(p) # optional - pplpy A 0-dimensional lattice polytope in ZZ^2 with 1 vertex - sage: P = C_Polyhedron(Generator_System(p)); P + sage: P = C_Polyhedron(Generator_System(p)); P # optional - pplpy A 0-dimensional polyhedron in QQ^2 defined as the convex hull of 1 point - sage: LatticePolytope_PPL(P) + sage: LatticePolytope_PPL(P) # optional - pplpy A 0-dimensional lattice polytope in ZZ^2 with 1 vertex A ``TypeError`` is raised if the arguments do not specify a lattice polytope:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: LatticePolytope_PPL((0,0),(1/2,1)) + sage: LatticePolytope_PPL((0,0), (1/2,1)) # optional - pplpy Traceback (most recent call last): ... TypeError: unable to convert rational 1/2 to an integer - sage: from ppl import point, Generator_System, C_Polyhedron, Linear_Expression, Variable - sage: p = point(Linear_Expression([2,3],0), 5); p + sage: from ppl import point, Generator_System, C_Polyhedron, Linear_Expression # optional - pplpy + sage: p = point(Linear_Expression([2,3],0), 5); p # optional - pplpy point(2/5, 3/5) - sage: LatticePolytope_PPL(p) + sage: LatticePolytope_PPL(p) # optional - pplpy Traceback (most recent call last): ... TypeError: generator is not a lattice polytope generator - sage: P = C_Polyhedron(Generator_System(p)); P + sage: P = C_Polyhedron(Generator_System(p)); P # optional - pplpy A 0-dimensional polyhedron in QQ^2 defined as the convex hull of 1 point - sage: LatticePolytope_PPL(P) + sage: LatticePolytope_PPL(P) # optional - pplpy Traceback (most recent call last): ... TypeError: polyhedron has non-integral generators @@ -189,7 +189,7 @@ class LatticePolytope_PPL_class(C_Polyhedron): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: LatticePolytope_PPL((0,0),(1,0),(0,1)) + sage: LatticePolytope_PPL((0,0), (1,0), (0,1)) A 2-dimensional lattice polytope in ZZ^2 with 3 vertices """ @@ -204,7 +204,7 @@ def __repr__(self): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: P = LatticePolytope_PPL((0,0),(1,0),(0,1)) + sage: P = LatticePolytope_PPL((0,0), (1,0), (0,1)) sage: P A 2-dimensional lattice polytope in ZZ^2 with 3 vertices sage: P.__repr__() @@ -240,7 +240,7 @@ def is_bounded(self): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: LatticePolytope_PPL((0,0),(1,0),(0,1)).is_bounded() + sage: LatticePolytope_PPL((0,0), (1,0), (0,1)).is_bounded() True """ return True @@ -295,7 +295,7 @@ def bounding_box(self): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: LatticePolytope_PPL((0,0),(1,0),(0,1)).bounding_box() + sage: LatticePolytope_PPL((0,0), (1,0), (0,1)).bounding_box() ((0, 0), (1, 1)) """ box_min = [] @@ -324,7 +324,7 @@ def n_integral_points(self): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: LatticePolytope_PPL((0,0),(1,0),(0,1)).n_integral_points() + sage: LatticePolytope_PPL((0,0), (1,0), (0,1)).n_integral_points() 3 """ if self.is_empty(): @@ -349,7 +349,7 @@ def integral_points(self): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: LatticePolytope_PPL((-1,-1),(1,0),(1,1),(0,1)).integral_points() + sage: LatticePolytope_PPL((-1,-1), (1,0), (1,1), (0,1)).integral_points() ((-1, -1), (0, 0), (0, 1), (1, 0), (1, 1)) sage: simplex = LatticePolytope_PPL((1,2,3), (2,3,7), (-2,-3,-11)) @@ -385,15 +385,15 @@ def integral_points(self): sage: v = [(1,0,0), (0,1,0), (0,0,1), (0,0,-1), (0,-2,1), ....: (-1,2,-1), (-1,2,-2), (-1,1,-2), (-1,-1,2), (-1,-3,2)] sage: P = LatticePolytope_PPL(*v) - sage: pts1 = P.integral_points() # Sage's own code - sage: pts2 = LatticePolytope(v).points() # optional - palp + sage: pts1 = P.integral_points() # Sage's own code + sage: pts2 = LatticePolytope(v).points() # optional - palp sage: for p in pts1: p.set_immutable() - sage: set(pts1) == set(pts2) # optional - palp + sage: set(pts1) == set(pts2) # optional - palp True sage: len(Polyhedron(v).integral_points()) # takes about 1 ms 23 - sage: len(LatticePolytope(v).points()) # takes about 13 ms # optional - palp + sage: len(LatticePolytope(v).points()) # takes about 13 ms # optional - palp 23 sage: len(LatticePolytope_PPL(*v).integral_points()) # takes about 0.5 ms 23 @@ -426,7 +426,7 @@ def _integral_points_saturating(self): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: quad = LatticePolytope_PPL((-1,-1),(0,1),(1,0),(1,1)) + sage: quad = LatticePolytope_PPL((-1,-1), (0,1), (1,0), (1,1)) sage: quad._integral_points_saturating() (((-1, -1), frozenset({0, 1})), ((0, 0), frozenset()), @@ -449,7 +449,7 @@ def _integral_points_saturating(self): @cached_method def integral_points_not_interior_to_facets(self): """ - Return the integral points not interior to facets + Return the integral points not interior to facets. OUTPUT: @@ -460,7 +460,7 @@ def integral_points_not_interior_to_facets(self): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: square = LatticePolytope_PPL((-1,-1),(-1,1),(1,-1),(1,1)) + sage: square = LatticePolytope_PPL((-1,-1), (-1,1), (1,-1), (1,1)) sage: square.n_integral_points() 9 sage: square.integral_points_not_interior_to_facets() @@ -482,7 +482,8 @@ def vertices(self): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: p = LatticePolytope_PPL((-9,-6,-1,-1),(0,0,0,1),(0,0,1,0),(0,1,0,0),(1,0,0,0)) + sage: p = LatticePolytope_PPL((-9,-6,-1,-1), + ....: (0,0,0,1), (0,0,1,0), (0,1,0,0), (1,0,0,0)) sage: p.vertices() ((-9, -6, -1, -1), (0, 0, 0, 1), (0, 0, 1, 0), (0, 1, 0, 0), (1, 0, 0, 0)) sage: p.minimized_generators() @@ -502,7 +503,7 @@ def vertices(self): def vertices_saturating(self, constraint): r""" - Return the vertices saturating the constraint + Return the vertices saturating the constraint. INPUT: @@ -517,7 +518,7 @@ def vertices_saturating(self, constraint): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: p = LatticePolytope_PPL((0,0),(0,1),(1,0)) + sage: p = LatticePolytope_PPL((0,0), (0,1), (1,0)) sage: ieq = next(iter(p.constraints())); ieq x0>=0 sage: p.vertices_saturating(ieq) @@ -544,10 +545,10 @@ def is_full_dimensional(self): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: p = LatticePolytope_PPL((0,0),(0,1)) + sage: p = LatticePolytope_PPL((0,0), (0,1)) sage: p.is_full_dimensional() False - sage: q = LatticePolytope_PPL((0,0),(0,1),(1,0)) + sage: q = LatticePolytope_PPL((0,0), (0,1), (1,0)) sage: q.is_full_dimensional() True """ @@ -576,8 +577,9 @@ def fibration_generator(self, dim): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: p = LatticePolytope_PPL((-9,-6,-1,-1),(0,0,0,1),(0,0,1,0),(0,1,0,0),(1,0,0,0)) - sage: list( p.fibration_generator(2) ) + sage: p = LatticePolytope_PPL((-9,-6,-1,-1), + ....: (0,0,0,1), (0,0,1,0), (0,1,0,0), (1,0,0,0)) + sage: list(p.fibration_generator(2)) [A 2-dimensional lattice polytope in ZZ^4 with 3 vertices] """ assert self.is_full_dimensional() @@ -633,7 +635,7 @@ def pointsets_mod_automorphism(self, pointsets): INPUT: - - ``polytopes`` a tuple/list/iterable of subsets of the + - ``polytopes`` -- a tuple/list/iterable of subsets of the integral points of ``self``. OUTPUT: @@ -644,18 +646,18 @@ def pointsets_mod_automorphism(self, pointsets): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: square = LatticePolytope_PPL((-1,-1),(-1,1),(1,-1),(1,1)) - sage: fibers = [ f.vertices() for f in square.fibration_generator(1) ] - sage: square.pointsets_mod_automorphism(fibers) # optional - sage.groups # optional - sage.graphs + sage: square = LatticePolytope_PPL((-1,-1), (-1,1), (1,-1), (1,1)) + sage: fibers = [f.vertices() for f in square.fibration_generator(1)] + sage: square.pointsets_mod_automorphism(fibers) # optional - sage.groups sage.graphs (frozenset({(-1, -1), (1, 1)}), frozenset({(-1, 0), (1, 0)})) sage: cell24 = LatticePolytope_PPL( - ....: (1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1),(1,-1,-1,1),(0,0,-1,1), - ....: (0,-1,0,1),(-1,0,0,1),(1,0,0,-1),(0,1,0,-1),(0,0,1,-1),(-1,1,1,-1), - ....: (1,-1,-1,0),(0,0,-1,0),(0,-1,0,0),(-1,0,0,0),(1,-1,0,0),(1,0,-1,0), - ....: (0,1,1,-1),(-1,1,1,0),(-1,1,0,0),(-1,0,1,0),(0,-1,-1,1),(0,0,0,-1)) + ....: (1,0,0,0), (0,1,0,0), (0,0,1,0), (0,0,0,1), (1,-1,-1,1), (0,0,-1,1), + ....: (0,-1,0,1), (-1,0,0,1), (1,0,0,-1), (0,1,0,-1), (0,0,1,-1), (-1,1,1,-1), + ....: (1,-1,-1,0), (0,0,-1,0), (0,-1,0,0), (-1,0,0,0), (1,-1,0,0), (1,0,-1,0), + ....: (0,1,1,-1), (-1,1,1,0), (-1,1,0,0), (-1,0,1,0), (0,-1,-1,1), (0,0,0,-1)) sage: fibers = [f.vertices() for f in cell24.fibration_generator(2)] - sage: cell24.pointsets_mod_automorphism(fibers) # long time # optional - sage.groups # optional - sage.graphs + sage: cell24.pointsets_mod_automorphism(fibers) # long time # optional - sage.groups sage.graphs (frozenset({(-1, 0, 0, 0), (-1, 0, 0, 1), (0, 0, 0, -1), @@ -714,9 +716,7 @@ def contains(self, point_coordinates): - ``point_coordinates`` -- a list/tuple/iterable of rational numbers. The coordinates of the point. - OUTPUT: - - Boolean. + OUTPUT: Boolean. EXAMPLES:: @@ -739,9 +739,7 @@ def contains_origin(self): """ Test whether the polytope contains the origin - OUTPUT: - - Boolean. + OUTPUT: Boolean. EXAMPLES:: @@ -795,7 +793,7 @@ def affine_lattice_polytope(self): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: poly_4d = LatticePolytope_PPL((-9,-6,0,0),(0,1,0,0),(1,0,0,0)); poly_4d + sage: poly_4d = LatticePolytope_PPL((-9,-6,0,0), (0,1,0,0), (1,0,0,0)); poly_4d A 2-dimensional lattice polytope in ZZ^4 with 3 vertices sage: poly_4d.space_dimension() 4 @@ -825,7 +823,8 @@ def base_projection(self, fiber): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: poly = LatticePolytope_PPL((-9,-6,-1,-1),(0,0,0,1),(0,0,1,0),(0,1,0,0),(1,0,0,0)) + sage: poly = LatticePolytope_PPL((-9,-6,-1,-1), + ....: (0,0,0,1), (0,0,1,0), (0,1,0,0), (1,0,0,0)) sage: fiber = next(poly.fibration_generator(2)) sage: poly.base_projection(fiber) Finitely generated module V/W over Integer Ring with invariants (0, 0) @@ -851,7 +850,8 @@ def base_projection_matrix(self, fiber): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: poly = LatticePolytope_PPL((-9,-6,-1,-1),(0,0,0,1),(0,0,1,0),(0,1,0,0),(1,0,0,0)) + sage: poly = LatticePolytope_PPL((-9,-6,-1,-1), + ....: (0,0,0,1), (0,0,1,0), (0,1,0,0), (1,0,0,0)) sage: fiber = next(poly.fibration_generator(2)) sage: poly.base_projection_matrix(fiber) [ 0 0 -1 0] @@ -862,9 +862,9 @@ def base_projection_matrix(self, fiber): sage: proj = poly.base_projection(fiber) sage: proj_matrix = poly.base_projection_matrix(fiber) - sage: [ proj(p) for p in poly.integral_points() ] + sage: [proj(p) for p in poly.integral_points()] [(-1, -1), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 1), (1, 0)] - sage: [ proj_matrix*p for p in poly.integral_points() ] + sage: [proj_matrix*p for p in poly.integral_points()] [(1, 1), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, -1), (-1, 0)] """ return matrix(ZZ, fiber.vertices()).right_kernel_matrix() @@ -888,13 +888,14 @@ def base_rays(self, fiber, points): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: poly = LatticePolytope_PPL((-9,-6,-1,-1),(0,0,0,1),(0,0,1,0),(0,1,0,0),(1,0,0,0)) + sage: poly = LatticePolytope_PPL((-9,-6,-1,-1), + ....: (0,0,0,1), (0,0,1,0), (0,1,0,0), (1,0,0,0)) sage: fiber = next(poly.fibration_generator(2)) sage: poly.base_rays(fiber, poly.integral_points_not_interior_to_facets()) ((-1, -1), (0, 1), (1, 0)) - sage: p = LatticePolytope_PPL((1,0),(1,2),(-1,0)) - sage: f = LatticePolytope_PPL((1,0),(-1,0)) + sage: p = LatticePolytope_PPL((1,0), (1,2), (-1,0)) + sage: f = LatticePolytope_PPL((1,0), (-1,0)) sage: p.base_rays(f, p.integral_points()) ((1),) """ @@ -921,16 +922,14 @@ def has_IP_property(self): That is, the polytope is full-dimensional and the origin is a interior point not on the boundary. - OUTPUT: - - Boolean. + OUTPUT: Boolean. EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: LatticePolytope_PPL((-1,-1),(0,1),(1,0)).has_IP_property() + sage: LatticePolytope_PPL((-1,-1), (0,1), (1,0)).has_IP_property() True - sage: LatticePolytope_PPL((-1,-1),(1,1)).has_IP_property() + sage: LatticePolytope_PPL((-1,-1), (1,1)).has_IP_property() False """ origin = C_Polyhedron(point(0*Variable(self.space_dimension()))) @@ -978,22 +977,26 @@ def restricted_automorphism_group(self, vertex_labels=None): sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL sage: Z3square = LatticePolytope_PPL((0,0), (1,2), (2,1), (3,3)) - sage: G1234 = Z3square.restricted_automorphism_group(vertex_labels=(1,2,3,4)) # optional - sage.groups # optional - sage.graphs - sage: G1234 == PermutationGroup([[(2,3)],[(1,2),(3,4)]]) # optional - sage.groups # optional - sage.graphs + sage: G1234 = Z3square.restricted_automorphism_group( # optional - sage.groups sage.graphs + ....: vertex_labels=(1,2,3,4)) + sage: G1234 == PermutationGroup([[(2,3)], [(1,2),(3,4)]]) # optional - sage.groups sage.graphs True - sage: G = Z3square.restricted_automorphism_group() # optional - sage.groups # optional - sage.graphs - sage: G == PermutationGroup([[((1,2),(2,1))],[((0,0),(1,2)),((2,1),(3,3))],[((0,0),(3,3))]]) # optional - sage.groups # optional - sage.graphs + sage: G = Z3square.restricted_automorphism_group() # optional - sage.groups sage.graphs + sage: G == PermutationGroup([[((1,2),(2,1))], [((0,0),(1,2)), # optional - sage.groups sage.graphs + ....: ((2,1),(3,3))], [((0,0),(3,3))]]) True - sage: set(G.domain()) == set(Z3square.vertices()) # optional - sage.groups # optional - sage.graphs + sage: set(G.domain()) == set(Z3square.vertices()) # optional - sage.groups sage.graphs True - sage: set(map(tuple,G.orbit(Z3square.vertices()[0]))) == set([(0, 0), (1, 2), (3, 3), (2, 1)]) # optional - sage.groups # optional - sage.graphs + sage: (set(tuple(x) for x in G.orbit(Z3square.vertices()[0])) # optional - sage.groups sage.graphs + ....: == set([(0, 0), (1, 2), (3, 3), (2, 1)]) + True sage: cell24 = LatticePolytope_PPL( - ....: (1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1),(1,-1,-1,1),(0,0,-1,1), - ....: (0,-1,0,1),(-1,0,0,1),(1,0,0,-1),(0,1,0,-1),(0,0,1,-1),(-1,1,1,-1), - ....: (1,-1,-1,0),(0,0,-1,0),(0,-1,0,0),(-1,0,0,0),(1,-1,0,0),(1,0,-1,0), - ....: (0,1,1,-1),(-1,1,1,0),(-1,1,0,0),(-1,0,1,0),(0,-1,-1,1),(0,0,0,-1)) - sage: cell24.restricted_automorphism_group().cardinality() # optional - sage.groups # optional - sage.graphs + ....: (1,0,0,0), (0,1,0,0), (0,0,1,0), (0,0,0,1), (1,-1,-1,1), (0,0,-1,1), + ....: (0,-1,0,1), (-1,0,0,1), (1,0,0,-1), (0,1,0,-1), (0,0,1,-1), (-1,1,1,-1), + ....: (1,-1,-1,0), (0,0,-1,0), (0,-1,0,0), (-1,0,0,0), (1,-1,0,0), (1,0,-1,0), + ....: (0,1,1,-1), (-1,1,1,0), (-1,1,0,0), (-1,0,1,0), (0,-1,-1,1), (0,0,0,-1)) + sage: cell24.restricted_automorphism_group().cardinality() # optional - sage.groups sage.graphs 1152 """ if not self.is_full_dimensional(): @@ -1033,7 +1036,7 @@ def lattice_automorphism_group(self, points=None, point_labels=None): - ``point_labels`` -- A tuple of labels for the ``points`` or ``None`` (default). These will be used as labels for the do - permutation group. If ``None`` the ``points`` will be used + permutation group. If ``None``, the ``points`` will be used themselves. OUTPUT: @@ -1046,32 +1049,34 @@ def lattice_automorphism_group(self, points=None, point_labels=None): sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL sage: Z3square = LatticePolytope_PPL((0,0), (1,2), (2,1), (3,3)) - sage: Z3square.lattice_automorphism_group() # optional - sage.groups # optional - sage.graphs + sage: Z3square.lattice_automorphism_group() # optional - sage.groups sage.graphs Permutation Group with generators [(), ((1,2),(2,1)), ((0,0),(3,3)), ((0,0),(3,3))((1,2),(2,1))] - sage: G1 = Z3square.lattice_automorphism_group(point_labels=(1,2,3,4)); G1 # optional - sage.groups # optional - sage.graphs + sage: G1 = Z3square.lattice_automorphism_group(point_labels=(1,2,3,4)) # optional - sage.groups sage.graphs + sage: G1 Permutation Group with generators [(), (2,3), (1,4), (1,4)(2,3)] - sage: G1.cardinality() # optional - sage.groups # optional - sage.graphs + sage: G1.cardinality() # optional - sage.groups sage.graphs 4 - sage: G2 = Z3square.restricted_automorphism_group(vertex_labels=(1,2,3,4)) # optional - sage.groups # optional - sage.graphs - sage: G2 == PermutationGroup([[(2,3)], [(1,2),(3,4)], [(1,4)]]) # optional - sage.groups # optional - sage.graphs + sage: G2 = Z3square.restricted_automorphism_group(vertex_labels=(1,2,3,4)) # optional - sage.groups sage.graphs + sage: G2 == PermutationGroup([[(2,3)], [(1,2),(3,4)], [(1,4)]]) # optional - sage.groups sage.graphs True - sage: G2.cardinality() # optional - sage.groups # optional - sage.graphs + sage: G2.cardinality() # optional - sage.groups sage.graphs 8 - sage: points = Z3square.integral_points(); points + sage: points = Z3square.integral_points(); points ((0, 0), (1, 1), (1, 2), (2, 1), (2, 2), (3, 3)) - sage: Z3square.lattice_automorphism_group(points, point_labels=(1,2,3,4,5,6)) # optional - sage.groups # optional - sage.graphs + sage: Z3square.lattice_automorphism_group(points, # optional - sage.groups sage.graphs + ....: point_labels=(1,2,3,4,5,6)) Permutation Group with generators [(), (3,4), (1,6)(2,5), (1,6)(2,5)(3,4)] Point labels also work for lattice polytopes that are not full-dimensional, see :trac:`16669`:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: lp = LatticePolytope_PPL((1,0,0),(0,1,0),(-1,-1,0)) - sage: lp.lattice_automorphism_group(point_labels=(0,1,2)) # optional - sage.groups # optional - sage.graphs + sage: lp = LatticePolytope_PPL((1,0,0), (0,1,0), (-1,-1,0)) + sage: lp.lattice_automorphism_group(point_labels=(0,1,2)) # optional - sage.groups sage.graphs Permutation Group with generators [(), (1,2), (0,1), (0,1,2), (0,2,1), (0,2)] """ if not self.is_full_dimensional(): @@ -1148,17 +1153,17 @@ def _find_isomorphism_to_subreflexive_polytope(self): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: polygon = LatticePolytope_PPL((0,0,2,1),(0,1,2,0),(2,3,0,0),(2,0,0,3)) + sage: polygon = LatticePolytope_PPL((0,0,2,1), (0,1,2,0), (2,3,0,0), (2,0,0,3)) sage: polygon._find_isomorphism_to_subreflexive_polytope() (A 2-dimensional lattice polytope in ZZ^2 with 3 vertices, A 2-dimensional lattice polytope in ZZ^2 with 4 vertices, - The map A*x+b with A= - [ 1 1] - [ 0 1] - [-1 -1] - [ 1 0] - b = - (-1, 0, 3, 0)) + The map A*x+b with + A= + [ 1 1] + [ 0 1] + [-1 -1] + [ 1 0] + b = (-1, 0, 3, 0)) sage: ambient, sub, embedding = _ sage: ambient.vertices() ((0, 0), (0, 3), (3, 0)) @@ -1219,15 +1224,15 @@ def embed_in_reflexive_polytope(self, output='hom'): EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL - sage: polygon = LatticePolytope_PPL((0,0,2,1),(0,1,2,0),(2,3,0,0),(2,0,0,3)) + sage: polygon = LatticePolytope_PPL((0,0,2,1), (0,1,2,0), (2,3,0,0), (2,0,0,3)) sage: polygon.embed_in_reflexive_polytope() - The map A*x+b with A= - [ 1 1] - [ 0 1] - [-1 -1] - [ 1 0] - b = - (-1, 0, 3, 0) + The map A*x+b with + A= + [ 1 1] + [ 0 1] + [-1 -1] + [ 1 0] + b = (-1, 0, 3, 0) sage: polygon.embed_in_reflexive_polytope('polytope') A 2-dimensional lattice polytope in ZZ^2 with 3 vertices sage: polygon.embed_in_reflexive_polytope('points') diff --git a/src/sage/geometry/pseudolines.py b/src/sage/geometry/pseudolines.py index 37b9ee324ca..4bb8d6ac8c9 100644 --- a/src/sage/geometry/pseudolines.py +++ b/src/sage/geometry/pseudolines.py @@ -49,7 +49,7 @@ sage: p = PseudolineArrangement(permutations) sage: p Arrangement of pseudolines of size 4 - sage: p.show() + sage: p.show() # optional - sage.plot **Sequence of transpositions** @@ -67,7 +67,7 @@ sage: p = PseudolineArrangement(transpositions) sage: p Arrangement of pseudolines of size 4 - sage: p.show() + sage: p.show() # optional - sage.plot Note that this ordering is not necessarily unique. @@ -75,7 +75,7 @@ **Felsner's Matrix** Felser gave an encoding of an arrangement of pseudolines that takes `n^2` bits -instead of the `n^2log(n)` bits required by the two previous encodings. +instead of the `n^2\log(n)` bits required by the two previous encodings. Instead of storing the permutation ``[3, 2, 1]`` to remember that line `l_0` crosses `l_3` then `l_2` then `l_1`, it is sufficient to remember the positions @@ -129,25 +129,27 @@ avoid a common crossing of three lines by adding a random noise to `b`:: sage: n = 20 - sage: l = sorted(zip(Subsets(20*n,n).random_element(), [randint(0,20*n)+random() for i in range(n)])) - sage: print(l[:5]) # not tested - [(96, 278.0130613051349), (74, 332.92512282478714), (13, 155.65820951249867), (209, 34.753946221755307), (147, 193.51376457741441)] + sage: l = sorted(zip(Subsets(20*n, n).random_element(), # optional - sage.combinat + ....: [randint(0, 20*n) + random() for i in range(n)])) + sage: print(l[:5]) # not tested # optional - sage.combinat + [(96, 278.0130613051349), (74, 332.92512282478714), (13, 155.65820951249867), + (209, 34.753946221755307), (147, 193.51376457741441)] We can now compute for each `i` the order in which line `i` meets the other lines:: - sage: permutations = [[0..i-1]+[i+1..n-1] for i in range(n)] - sage: a = lambda x : l[x][0] - sage: b = lambda x : l[x][1] - sage: for i, perm in enumerate(permutations): - ....: perm.sort(key = lambda j : (b(j)-b(i))/(a(i)-a(j))) + sage: permutations = [[0..i-1] + [i+1..n-1] for i in range(n)] + sage: def a(x): return l[x][0] + sage: def b(x): return l[x][1] + sage: for i, perm in enumerate(permutations): # optional - sage.combinat + ....: perm.sort(key=lambda j: (b(j)-b(i))/(a(i)-a(j))) And finally build the line arrangement:: sage: from sage.geometry.pseudolines import PseudolineArrangement - sage: p = PseudolineArrangement(permutations) - sage: print(p) + sage: p = PseudolineArrangement(permutations) # optional - sage.combinat + sage: print(p) # optional - sage.combinat Arrangement of pseudolines of size 20 - sage: p.show(figsize=[20,8]) + sage: p.show(figsize=[20,8]) # optional - sage.combinat sage.plot Author ^^^^^^ @@ -174,12 +176,12 @@ def __init__(self, seq, encoding="auto"): INPUT: - - ``seq`` (a sequence describing the line arrangement). It can be : + - ``seq`` (a sequence describing the line arrangement). It can be: - - A list of `n` permutations of size `n-1`. - - A list of `\binom n 2` transpositions - - A Felsner matrix, given as a sequence of `n` binary vectors of - length `n-1`. + - A list of `n` permutations of size `n-1`. + - A list of `\binom n 2` transpositions + - A Felsner matrix, given as a sequence of `n` binary vectors of + length `n-1`. - ``encoding`` (information on how the data should be interpreted), and can assume any value among 'transpositions', 'permutations', 'Felsner' @@ -188,7 +190,7 @@ def __init__(self, seq, encoding="auto"): .. NOTE:: - * The pseudolines are assumed to be integers `0..(n-1)`. + * The pseudolines are assumed to be integers `0,\dots,n-1`. * For more information on the different encodings, see the :mod:`pseudolines module `'s @@ -417,14 +419,14 @@ def show(self, **args): sage: from sage.geometry.pseudolines import PseudolineArrangement sage: permutations = [[3, 2, 1], [3, 2, 0], [3, 1, 0], [2, 1, 0]] sage: p = PseudolineArrangement(permutations) - sage: p.show(figsize=[7,5]) + sage: p.show(figsize=[7,5]) # optional - sage.plot TESTS:: sage: from sage.geometry.pseudolines import PseudolineArrangement sage: permutations = [[3, 2, 1], [3, 2, 0], [3, 0, 1], [2, 0, 1]] sage: p = PseudolineArrangement(permutations) - sage: p.show() + sage: p.show() # optional - sage.plot Traceback (most recent call last): ... ValueError: There has been a problem while plotting the figure... diff --git a/src/sage/geometry/relative_interior.py b/src/sage/geometry/relative_interior.py index 262c927a08a..d9ba65bbff5 100644 --- a/src/sage/geometry/relative_interior.py +++ b/src/sage/geometry/relative_interior.py @@ -324,11 +324,11 @@ def __eq__(self, other): sage: ri_segment = segment.relative_interior(); ri_segment Relative interior of a 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices - sage: segment2 = Polyhedron([[1, 2], [3, 4]], base_ring=AA) - sage: ri_segment2 = segment2.relative_interior(); ri_segment2 + sage: segment2 = Polyhedron([[1, 2], [3, 4]], base_ring=AA) # optional - sage.rings.number_field + sage: ri_segment2 = segment2.relative_interior(); ri_segment2 # optional - sage.rings.number_field Relative interior of a 1-dimensional polyhedron in AA^2 defined as the convex hull of 2 vertices - sage: ri_segment == ri_segment2 + sage: ri_segment == ri_segment2 # optional - sage.rings.number_field True TESTS:: @@ -355,11 +355,11 @@ def __ne__(self, other): sage: ri_segment = segment.relative_interior(); ri_segment Relative interior of a 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices - sage: segment2 = Polyhedron([[1, 2], [3, 4]], base_ring=AA) - sage: ri_segment2 = segment2.relative_interior(); ri_segment2 + sage: segment2 = Polyhedron([[1, 2], [3, 4]], base_ring=AA) # optional - sage.rings.number_field + sage: ri_segment2 = segment2.relative_interior(); ri_segment2 # optional - sage.rings.number_field Relative interior of a 1-dimensional polyhedron in AA^2 defined as the convex hull of 2 vertices - sage: ri_segment != ri_segment2 + sage: ri_segment != ri_segment2 # optional - sage.rings.number_field False """ return not (self == other) diff --git a/src/sage/geometry/toric_plotter.py b/src/sage/geometry/toric_plotter.py index 07aed17663a..764974cf164 100644 --- a/src/sage/geometry/toric_plotter.py +++ b/src/sage/geometry/toric_plotter.py @@ -15,7 +15,7 @@ In most cases, this module is used indirectly, e.g. :: sage: fan = toric_varieties.dP6().fan() # optional - palp - sage: fan.plot() # optional - sage.plot # optional - palp + sage: fan.plot() # optional - palp sage.plot Graphics object consisting of 31 graphics primitives You may change default plotting options as follows:: @@ -25,12 +25,12 @@ sage: toric_plotter.options(show_rays=False) sage: toric_plotter.options("show_rays") False - sage: fan.plot() # optional - sage.plot # optional - palp + sage: fan.plot() # optional - palp sage.plot Graphics object consisting of 19 graphics primitives sage: toric_plotter.reset_options() sage: toric_plotter.options("show_rays") True - sage: fan.plot() # optional - sage.plot # optional - palp + sage: fan.plot() # optional - palp sage.plot Graphics object consisting of 31 graphics primitives """ @@ -49,10 +49,11 @@ from copy import copy from math import pi -from sage.functions.all import arccos, arctan2, ceil, floor +from sage.arith.misc import integer_ceil as ceil, integer_floor as floor +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.all", ["arccos", "arctan2"]) from sage.geometry.polyhedron.constructor import Polyhedron from sage.modules.free_module_element import vector -from sage.misc.lazy_import import lazy_import lazy_import("sage.plot.all", ["Color", "Graphics", "arrow", "disk", "line", "point", "polygon", "rainbow", "text"]) @@ -135,9 +136,9 @@ class ToricPlotter(SageObject): plot, e.g. :: sage: fan = toric_varieties.dP6().fan() # optional - palp - sage: fan.plot() # optional - sage.plot # optional - palp + sage: fan.plot() # optional - palp sage.plot Graphics object consisting of 31 graphics primitives - sage: print(fan.plot()) # optional - sage.plot # optional - palp + sage: print(fan.plot()) # optional - palp sage.plot Graphics object consisting of 31 graphics primitives If you do want to create your own plotting function for some toric @@ -164,16 +165,16 @@ class ToricPlotter(SageObject): follows:: sage: from sage.geometry.toric_plotter import ToricPlotter - sage: options = dict() # use default for everything + sage: options = dict() # use default for everything sage: tp = ToricPlotter(options, fan.lattice().degree()) # optional - palp sage: tp.include_points(fan.rays()) # optional - palp sage: tp.adjust_options() # optional - palp sage: tp.set_rays(fan.rays()) # optional - palp - sage: result = tp.plot_lattice() # optional - palp - sage: result += tp.plot_rays() # optional - palp - sage: result += tp.plot_generators() # optional - palp - sage: result += tp.plot_walls(fan(2)) # optional - palp - sage: result # optional - palp + sage: result = tp.plot_lattice() # optional - palp sage.plot + sage: result += tp.plot_rays() # optional - palp sage.plot + sage: result += tp.plot_generators() # optional - palp sage.plot + sage: result += tp.plot_walls(fan(2)) # optional - palp sage.plot + sage: result # optional - palp sage.plot Graphics object consisting of 31 graphics primitives In most situations it is only necessary to include generators of rays, in @@ -389,7 +390,7 @@ def plot_generators(self): sage: from sage.geometry.toric_plotter import ToricPlotter sage: tp = ToricPlotter(dict(), 2, [(3,4)]) - sage: tp.plot_generators() + sage: tp.plot_generators() # optional - sage.plot Graphics object consisting of 1 graphics primitive """ generators = self.generators @@ -440,7 +441,7 @@ def plot_labels(self, labels, positions): sage: from sage.geometry.toric_plotter import ToricPlotter sage: tp = ToricPlotter(dict(), 2) - sage: tp.plot_labels("u", [(1.5,0)]) + sage: tp.plot_labels("u", [(1.5,0)]) # optional - sage.plot Graphics object consisting of 1 graphics primitive """ result = Graphics() @@ -474,7 +475,7 @@ def plot_lattice(self): sage: from sage.geometry.toric_plotter import ToricPlotter sage: tp = ToricPlotter(dict(), 2) sage: tp.adjust_options() - sage: tp.plot_lattice() + sage: tp.plot_lattice() # optional - sage.plot Graphics object consisting of 1 graphics primitive """ if not self.show_lattice: @@ -518,7 +519,7 @@ def plot_points(self, points): sage: from sage.geometry.toric_plotter import ToricPlotter sage: tp = ToricPlotter(dict(), 2) sage: tp.adjust_options() - sage: tp.plot_points([(1,0), (0,1)]) + sage: tp.plot_points([(1,0), (0,1)]) # optional - sage.plot Graphics object consisting of 1 graphics primitive """ return point(points, color=self.point_color, size=self.point_size, @@ -542,7 +543,7 @@ def plot_ray_labels(self): sage: from sage.geometry.toric_plotter import ToricPlotter sage: tp = ToricPlotter(dict(), 2, [(3,4)]) - sage: tp.plot_ray_labels() + sage: tp.plot_ray_labels() # optional - sage.plot Graphics object consisting of 1 graphics primitive """ return self.plot_labels(self.ray_label, @@ -563,7 +564,7 @@ def plot_rays(self): sage: from sage.geometry.toric_plotter import ToricPlotter sage: tp = ToricPlotter(dict(), 2, [(3,4)]) - sage: tp.plot_rays() + sage: tp.plot_rays() # optional - sage.plot Graphics object consisting of 2 graphics primitives """ result = Graphics() @@ -605,14 +606,14 @@ def plot_walls(self, walls): sage: quadrant = Cone([(1,0), (0,1)]) sage: from sage.geometry.toric_plotter import ToricPlotter sage: tp = ToricPlotter(dict(), 2, quadrant.rays()) - sage: tp.plot_walls([quadrant]) + sage: tp.plot_walls([quadrant]) # optional - sage.plot Graphics object consisting of 2 graphics primitives Let's also check that the truncating polyhedron is functioning correctly:: sage: tp = ToricPlotter({"mode": "box"}, 2, quadrant.rays()) - sage: tp.plot_walls([quadrant]) + sage: tp.plot_walls([quadrant]) # optional - sage.plot Graphics object consisting of 2 graphics primitives """ result = Graphics() @@ -702,12 +703,12 @@ def set_rays(self, generators): sage: from sage.geometry.toric_plotter import ToricPlotter sage: tp = ToricPlotter(dict(), 2) sage: tp.adjust_options() - sage: tp.plot_rays() + sage: tp.plot_rays() # optional - sage.plot Traceback (most recent call last): ... AttributeError: 'ToricPlotter' object has no attribute 'rays' sage: tp.set_rays([(0,1)]) - sage: tp.plot_rays() + sage: tp.plot_rays() # optional - sage.plot Graphics object consisting of 2 graphics primitives """ d = self.dimension @@ -782,20 +783,20 @@ def color_list(color, n): EXAMPLES:: sage: from sage.geometry.toric_plotter import color_list - sage: color_list("grey", 1) + sage: color_list("grey", 1) # optional - sage.plot [RGB color (0.5019607843137255, 0.5019607843137255, 0.5019607843137255)] - sage: len(color_list("grey", 3)) + sage: len(color_list("grey", 3)) # optional - sage.plot 3 - sage: L = color_list("rainbow", 3) - sage: L + sage: L = color_list("rainbow", 3) # optional - sage.plot + sage: L # optional - sage.plot [RGB color (1.0, 0.0, 0.0), RGB color (0.0, 1.0, 0.0), RGB color (0.0, 0.0, 1.0)] - sage: color_list(L, 3) + sage: color_list(L, 3) # optional - sage.plot [RGB color (1.0, 0.0, 0.0), RGB color (0.0, 1.0, 0.0), RGB color (0.0, 0.0, 1.0)] - sage: color_list(L, 4) + sage: color_list(L, 4) # optional - sage.plot Traceback (most recent call last): ... ValueError: expected 4 colors, got 3! diff --git a/src/sage/geometry/triangulation/element.py b/src/sage/geometry/triangulation/element.py index b32cb952190..793b383f9dc 100644 --- a/src/sage/geometry/triangulation/element.py +++ b/src/sage/geometry/triangulation/element.py @@ -23,7 +23,7 @@ sage: points = PointConfiguration(p) sage: triang = points.triangulate(); triang (<0,1,2,5>, <0,1,3,5>, <1,3,4,5>) - sage: triang.plot(axes=False) # optional - sage.plot + sage: triang.plot(axes=False) # optional - sage.plot Graphics3d Object See :mod:`sage.geometry.triangulation.point_configuration` for more details. @@ -68,7 +68,7 @@ def triangulation_render_2d(triangulation, **kwds): sage: points = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) sage: triang = points.triangulate() - sage: triang.plot(axes=False, aspect_ratio=1) # indirect doctest # optional - sage.plot + sage: triang.plot(axes=False, aspect_ratio=1) # indirect doctest # optional - sage.plot Graphics object consisting of 12 graphics primitives """ from sage.plot.all import point2d, line2d, polygon2d @@ -130,7 +130,7 @@ def triangulation_render_3d(triangulation, **kwds): sage: p = [[0,-1,-1],[0,0,1],[0,1,0], [1,-1,-1],[1,0,1],[1,1,0]] sage: points = PointConfiguration(p) sage: triang = points.triangulate() - sage: triang.plot(axes=False) # indirect doctest # optional - sage.plot + sage: triang.plot(axes=False) # indirect doctest # optional - sage.plot Graphics3d Object """ from sage.plot.plot3d.all import point3d, line3d, polygon3d @@ -407,7 +407,7 @@ def plot(self, **kwds): sage: triangulation = p.triangulate() sage: triangulation (<1,3,4>, <2,3,4>) - sage: triangulation.plot(axes=False) # optional - sage.plot + sage: triangulation.plot(axes=False) # optional - sage.plot Graphics object consisting of 12 graphics primitives """ dim = self.point_configuration().dim() @@ -524,18 +524,17 @@ def fan(self, origin=None): sage: triangulation = pc.triangulate() sage: fan = triangulation.fan(); fan Rational polyhedral fan in 2-d lattice N - sage: fan.is_equivalent( toric_varieties.P2().fan() ) # optional - palp + sage: fan.is_equivalent(toric_varieties.P2().fan()) # optional - palp True Toric diagrams (the `\ZZ_5` hyperconifold):: sage: vertices=[(0, 1, 0), (0, 3, 1), (0, 2, 3), (0, 0, 2)] sage: interior=[(0, 1, 1), (0, 1, 2), (0, 2, 1), (0, 2, 2)] - sage: points = vertices+interior + sage: points = vertices + interior sage: pc = PointConfiguration(points, fine=True) sage: triangulation = pc.triangulate() - sage: fan = triangulation.fan( (-1,0,0) ) - sage: fan + sage: fan = triangulation.fan((-1,0,0)); fan Rational polyhedral fan in 3-d lattice N sage: fan.rays() N(1, 1, 0), @@ -568,13 +567,12 @@ def simplicial_complex(self): EXAMPLES:: sage: p = polytopes.cuboctahedron() - sage: sc = p.triangulate(engine='internal').simplicial_complex() - sage: sc + sage: sc = p.triangulate(engine='internal').simplicial_complex(); sc # optional - sage.graphs Simplicial complex with 12 vertices and 16 facets Any convex set is contractable, so its reduced homology groups vanish:: - sage: sc.homology() + sage: sc.homology() # optional - sage.graphs {0: 0, 1: 0, 2: 0, 3: 0} """ from sage.topology.simplicial_complex import SimplicialComplex @@ -672,20 +670,19 @@ def boundary_simplicial_complex(self): sage: p = polytopes.cuboctahedron() sage: triangulation = p.triangulate(engine='internal') - sage: bd_sc = triangulation.boundary_simplicial_complex() - sage: bd_sc + sage: bd_sc = triangulation.boundary_simplicial_complex(); bd_sc # optional - sage.graphs Simplicial complex with 12 vertices and 20 facets The boundary of every convex set is a topological sphere, so it has spherical homology:: - sage: bd_sc.homology() + sage: bd_sc.homology() # optional - sage.graphs {0: 0, 1: 0, 2: Z} It is a subcomplex of ``self`` as a :meth:`simplicial_complex`:: - sage: sc = triangulation.simplicial_complex() - sage: all(f in sc for f in bd_sc.maximal_faces()) + sage: sc = triangulation.simplicial_complex() # optional - sage.graphs + sage: all(f in sc for f in bd_sc.maximal_faces()) # optional - sage.graphs True """ from sage.topology.simplicial_complex import SimplicialComplex @@ -742,9 +739,9 @@ def polyhedral_complex(self, **kwds): sage: pc = PointConfiguration(P.vertices()) sage: T = pc.placing_triangulation(); T (<0,1,2,7>, <0,1,5,7>, <0,2,3,7>, <0,3,4,7>, <0,4,5,7>, <1,5,6,7>) - sage: C = T.polyhedral_complex(); C + sage: C = T.polyhedral_complex(); C # optional - sage.graphs Polyhedral complex with 6 maximal cells - sage: [P.vertices_list() for P in C.maximal_cells_sorted()] + sage: [P.vertices_list() for P in C.maximal_cells_sorted()] # optional - sage.graphs [[[-1, -1, -1], [-1, -1, 1], [-1, 1, 1], [1, -1, -1]], [[-1, -1, -1], [-1, 1, -1], [-1, 1, 1], [1, 1, -1]], [[-1, -1, -1], [-1, 1, 1], [1, -1, -1], [1, 1, -1]], @@ -778,26 +775,26 @@ def boundary_polyhedral_complex(self, **kwds): sage: pc = PointConfiguration(P.vertices()) sage: T = pc.placing_triangulation(); T (<0,1,2,7>, <0,1,5,7>, <0,2,3,7>, <0,3,4,7>, <0,4,5,7>, <1,5,6,7>) - sage: bd_C = T.boundary_polyhedral_complex(); bd_C + sage: bd_C = T.boundary_polyhedral_complex(); bd_C # optional - sage.graphs Polyhedral complex with 12 maximal cells - sage: [P.vertices_list() for P in bd_C.maximal_cells_sorted()] + sage: [P.vertices_list() for P in bd_C.maximal_cells_sorted()] # optional - sage.graphs [[[-1, -1, -1], [-1, -1, 1], [-1, 1, 1]], - [[-1, -1, -1], [-1, -1, 1], [1, -1, -1]], - [[-1, -1, -1], [-1, 1, -1], [-1, 1, 1]], - [[-1, -1, -1], [-1, 1, -1], [1, 1, -1]], - [[-1, -1, -1], [1, -1, -1], [1, 1, -1]], - [[-1, -1, 1], [-1, 1, 1], [1, -1, 1]], - [[-1, -1, 1], [1, -1, -1], [1, -1, 1]], - [[-1, 1, -1], [-1, 1, 1], [1, 1, -1]], - [[-1, 1, 1], [1, -1, 1], [1, 1, 1]], - [[-1, 1, 1], [1, 1, -1], [1, 1, 1]], - [[1, -1, -1], [1, -1, 1], [1, 1, 1]], - [[1, -1, -1], [1, 1, -1], [1, 1, 1]]] + [[-1, -1, -1], [-1, -1, 1], [1, -1, -1]], + [[-1, -1, -1], [-1, 1, -1], [-1, 1, 1]], + [[-1, -1, -1], [-1, 1, -1], [1, 1, -1]], + [[-1, -1, -1], [1, -1, -1], [1, 1, -1]], + [[-1, -1, 1], [-1, 1, 1], [1, -1, 1]], + [[-1, -1, 1], [1, -1, -1], [1, -1, 1]], + [[-1, 1, -1], [-1, 1, 1], [1, 1, -1]], + [[-1, 1, 1], [1, -1, 1], [1, 1, 1]], + [[-1, 1, 1], [1, 1, -1], [1, 1, 1]], + [[1, -1, -1], [1, -1, 1], [1, 1, 1]], + [[1, -1, -1], [1, 1, -1], [1, 1, 1]]] It is a subcomplex of ``self`` as a :meth:`polyhedral_complex`:: - sage: C = T.polyhedral_complex() - sage: bd_C.is_subcomplex(C) + sage: C = T.polyhedral_complex() # optional - sage.graphs + sage: bd_C.is_subcomplex(C) # optional - sage.graphs True """ from sage.geometry.polyhedral_complex import PolyhedralComplex @@ -921,7 +918,7 @@ def adjacency_graph(self): sage: p = PointConfiguration([[1,0,0], [0,1,0], [0,0,1], [-1,0,1], ....: [1,0,-1], [-1,0,0], [0,-1,0], [0,0,-1]]) sage: t = p.triangulate() - sage: t.adjacency_graph() + sage: t.adjacency_graph() # optional - sage.graphs Graph on 8 vertices """ diff --git a/src/sage/geometry/triangulation/point_configuration.py b/src/sage/geometry/triangulation/point_configuration.py index 055ecae5d60..4f1bbde16d7 100644 --- a/src/sage/geometry/triangulation/point_configuration.py +++ b/src/sage/geometry/triangulation/point_configuration.py @@ -42,8 +42,7 @@ A 2-dimensional point configuration:: - sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) - sage: p + sage: p = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]); p A point configuration in affine 2-space over Integer Ring consisting of 5 points. The triangulations of this point configuration are assumed to be connected, not necessarily fine, not necessarily regular. @@ -51,13 +50,12 @@ .. PLOT:: :width: 300 px - p = PointConfiguration([[-1,-1],[1,1],[1,0],[0,1],[0,0]]) + p = PointConfiguration([[-1,-1], [1,1], [1,0], [0,1], [0,0]]) sphinx_plot(p.plot(axes=False)) A triangulation of it:: - sage: t = p.triangulate() # a single triangulation - sage: t + sage: t = p.triangulate(); t # a single triangulation (<1,3,4>, <2,3,4>) sage: len(t) 2 @@ -67,35 +65,34 @@ (2, 3, 4) sage: list(t) [(1, 3, 4), (2, 3, 4)] - sage: t.plot(axes=False) # optional - sage.plot + sage: t.plot(axes=False) # optional - sage.plot Graphics object consisting of 12 graphics primitives .. PLOT:: :width: 300 px - p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) + p = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]) t = p.triangulate() sphinx_plot(t.plot(axes=False)) List triangulations of it:: - sage: list( p.triangulations() ) + sage: list(p.triangulations()) [(<1,3,4>, <2,3,4>), (<0,1,3>, <0,1,4>, <0,2,3>, <0,2,4>), (<1,2,3>, <1,2,4>), (<0,1,2>, <0,1,4>, <0,2,4>, <1,2,3>)] - sage: p_fine = p.restrict_to_fine_triangulations() - sage: p_fine + sage: p_fine = p.restrict_to_fine_triangulations(); p_fine A point configuration in affine 2-space over Integer Ring consisting of 5 points. The triangulations of this point configuration are assumed to be connected, fine, not necessarily regular. - sage: list( p_fine.triangulations() ) + sage: list(p_fine.triangulations()) [(<0,1,3>, <0,1,4>, <0,2,3>, <0,2,4>), (<0,1,2>, <0,1,4>, <0,2,4>, <1,2,3>)] A 3-dimensional point configuration:: - sage: p = [[0,-1,-1],[0,0,1],[0,1,0], [1,-1,-1],[1,0,1],[1,1,0]] + sage: p = [[0,-1,-1], [0,0,1], [0,1,0], [1,-1,-1], [1,0,1], [1,1,0]] sage: points = PointConfiguration(p) sage: triang = points.triangulate() sage: triang.plot(axes=False) # optional - sage.plot @@ -104,22 +101,25 @@ .. PLOT:: :width: 300 px - p = [[0,-1,-1],[0,0,1],[0,1,0], [1,-1,-1],[1,0,1],[1,1,0]] + p = [[0,-1,-1], [0,0,1], [0,1,0], [1,-1,-1], [1,0,1], [1,1,0]] points = PointConfiguration(p) triang = points.triangulate() sphinx_plot(triang.plot(axes=False)) The standard example of a non-regular triangulation (requires TOPCOM):: - sage: PointConfiguration.set_engine('topcom') # optional - topcom - sage: p = PointConfiguration([[-1,-5/9],[0,10/9],[1,-5/9],[-2,-10/9],[0,20/9],[2,-10/9]]) - sage: regular = p.restrict_to_regular_triangulations(True).triangulations_list() # optional - topcom - sage: nonregular = p.restrict_to_regular_triangulations(False).triangulations_list() # optional - topcom - sage: len(regular) # optional - topcom + sage: PointConfiguration.set_engine('topcom') # optional - topcom + sage: p = PointConfiguration([[-1,-5/9], [0,10/9], [1,-5/9], + ....: [-2,-10/9], [0,20/9], [2,-10/9]]) + sage: p_regular = p.restrict_to_regular_triangulations(True) # optional - topcom + sage: regular = p_regular.triangulations_list() # optional - topcom + sage: p_nonregular = p.restrict_to_regular_triangulations(False) # optional - topcom + sage: nonregular = p_nonregular.triangulations_list() # optional - topcom + sage: len(regular) # optional - topcom 16 - sage: len(nonregular) # optional - topcom + sage: len(nonregular) # optional - topcom 2 - sage: nonregular[0].plot(aspect_ratio=1, axes=False) # optional - topcom # optional - sage.plot + sage: nonregular[0].plot(aspect_ratio=1, axes=False) # optional - topcom sage.plot Graphics object consisting of 25 graphics primitives sage: PointConfiguration.set_engine('internal') # to make doctests independent of TOPCOM @@ -127,8 +127,9 @@ points may lie in a hyperplane and the linear dependencies will be removed before passing the data to TOPCOM which cannot handle it:: - sage: points = [[0,0,0,1],[0,3,0,1],[3,0,0,1],[0,0,1,1],[0,3,1,1],[3,0,1,1],[1,1,2,1]] - sage: points = [ p+[1,2,3] for p in points ] + sage: points = [[0,0,0,1], [0,3,0,1], [3,0,0,1], [0,0,1,1], + ....: [0,3,1,1], [3,0,1,1], [1,1,2,1]] + sage: points = [p + [1,2,3] for p in points] sage: pc = PointConfiguration(points) sage: pc.ambient_dim() 7 @@ -138,27 +139,27 @@ (<0,1,2,6>, <0,1,3,6>, <0,2,3,6>, <1,2,4,6>, <1,3,4,6>, <2,3,5,6>, <2,4,5,6>) sage: _ in pc.triangulations() True - sage: len( pc.triangulations_list() ) + sage: len(pc.triangulations_list()) 26 AUTHORS: - - Volker Braun: initial version, 2010 +- Volker Braun: initial version, 2010 - - Josh Whitney: added functionality for computing - volumes and secondary polytopes of PointConfigurations +- Josh Whitney: added functionality for computing + volumes and secondary polytopes of PointConfigurations - - Marshall Hampton: improved documentation and doctest coverage +- Marshall Hampton: improved documentation and doctest coverage - - Volker Braun: rewrite using Parent/Element and categories. Added - a Point class. More doctests. Less zombies. +- Volker Braun: rewrite using Parent/Element and categories. Added + a Point class. More doctests. Less zombies. - - Volker Braun: Cythonized parts of it, added a C++ implementation - of the bistellar flip algorithm to enumerate all connected - triangulations. +- Volker Braun: Cythonized parts of it, added a C++ implementation + of the bistellar flip algorithm to enumerate all connected + triangulations. - - Volker Braun 2011: switched the triangulate() method to the - placing triangulation (faster). +- Volker Braun 2011: switched the triangulate() method to the + placing triangulation (faster). """ ######################################################################## @@ -237,11 +238,11 @@ class PointConfiguration(UniqueRepresentation, PointConfiguration_base): function. In other words, the shadows of the faces of a polyhedron in one higher dimension. - * ``True``: Only regular triangulations. + * ``True``: Only regular triangulations. - * ``False``: Only non-regular triangulations. + * ``False``: Only non-regular triangulations. - * ``None`` (default): Both kinds of triangulation. + * ``None`` (default): Both kinds of triangulation. - ``star`` -- either ``None`` or a point. Whether the triangulations must be star. A triangulation is star if all @@ -251,8 +252,7 @@ class PointConfiguration(UniqueRepresentation, PointConfiguration_base): EXAMPLES:: - sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) - sage: p + sage: p = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]); p A point configuration in affine 2-space over Integer Ring consisting of 5 points. The triangulations of this point configuration are assumed to be connected, not necessarily fine, @@ -301,8 +301,8 @@ def __classcall__(cls, points, projective=False, connected=True, fine=False, reg EXAMPLES:: - sage: pc1 = PointConfiguration([[1,2],[2,3],[3,4]], connected=True) - sage: pc2 = PointConfiguration(((1,2),(2,3),(3,4)), regular=None) + sage: pc1 = PointConfiguration([[1,2], [2,3], [3,4]], connected=True) + sage: pc2 = PointConfiguration(((1,2), (2,3), (3,4)), regular=None) sage: pc1 is pc2 # indirect doctest True """ @@ -331,7 +331,8 @@ def __init__(self, points, connected, fine, regular, star, defined_affine): EXAMPLES:: - sage: p = PointConfiguration([[0,4],[2,3],[3,2],[4,0],[3,-2],[2,-3],[0,-4],[-2,-3],[-3,-2],[-4,0],[-3,2],[-2,3]]) + sage: p = PointConfiguration([[0,4], [2,3], [3,2], [4,0], [3,-2], [2,-3], + ....: [0,-4], [-2,-3], [-3,-2], [-4,0], [-3,2], [-2,3]]) sage: len(p.triangulations_list()) # long time (26s on sage.math, 2012) 16796 @@ -367,14 +368,14 @@ def set_engine(cls, engine='auto'): INPUT: - - ``engine`` -- either 'auto' (default), 'internal', or - 'topcom'. The latter two instruct this package to always use + - ``engine`` -- either ``'auto'`` (default), ``'internal'``, or + ``'topcom'``. The latter two instruct this package to always use its own triangulation algorithms or TOPCOM's algorithms, - respectively. By default ('auto'), internal routines are used. + respectively. By default (``'auto'``), internal routines are used. EXAMPLES:: - sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) + sage: p = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]) sage: p.set_engine('internal') # to make doctests independent of TOPCOM sage: p.triangulate() (<1,3,4>, <2,3,4>) @@ -399,11 +400,11 @@ def star_center(self): A :class:`~sage.geometry.triangulation.base.Point` if a distinguished star central point has been fixed. - ``ValueError`` exception is raised otherwise. + :class:`ValueError` exception is raised otherwise. EXAMPLES:: - sage: pc = PointConfiguration([(1,0),(-1,0),(0,1),(0,2)], star=(0,1)); pc + sage: pc = PointConfiguration([(1,0), (-1,0), (0,1), (0,2)], star=(0,1)); pc A point configuration in affine 2-space over Integer Ring consisting of 4 points. The triangulations of this point configuration are assumed to be connected, not necessarily @@ -411,8 +412,7 @@ def star_center(self): sage: pc.star_center() P(0, 1) - sage: pc_nostar = pc.restrict_to_star_triangulations(None) - sage: pc_nostar + sage: pc_nostar = pc.restrict_to_star_triangulations(None); pc_nostar A point configuration in affine 2-space over Integer Ring consisting of 4 points. The triangulations of this point configuration are assumed to be connected, not necessarily @@ -437,7 +437,8 @@ def __reduce__(self): sage: loads(p.dumps()) is p True - sage: p = PointConfiguration([[0, 1, 1], [0, 0, 1], [1, 0, 1], [1,1, 1]], projective=True) + sage: p = PointConfiguration([[0, 1, 1], [0, 0, 1], [1, 0, 1], [1,1, 1]], + ....: projective=True) sage: loads(p.dumps()) is p True """ @@ -469,7 +470,7 @@ def _element_constructor_(self, e): TESTS:: sage: p = PointConfiguration([[0, 1], [0, 0], [1, 0], [1,1]]) - sage: p._element_constructor_([ (0,1,2), (2,3,0) ]) + sage: p._element_constructor_([(0,1,2), (2,3,0)]) (<0,1,2>, <0,2,3>) """ return self.element_class(e, parent=self) @@ -491,11 +492,11 @@ def __iter__(self): sage: p = PointConfiguration([[1,1], [2,2], [3,3]]) sage: list(p) # indirect doctest [P(1, 1), P(2, 2), P(3, 3)] - sage: [ p[i] for i in range(p.n_points()) ] + sage: [p[i] for i in range(p.n_points())] [P(1, 1), P(2, 2), P(3, 3)] sage: list(p.points()) [P(1, 1), P(2, 2), P(3, 3)] - sage: [ p.point(i) for i in range(p.n_points()) ] + sage: [p.point(i) for i in range(p.n_points())] [P(1, 1), P(2, 2), P(3, 3)] """ for p in self.points(): @@ -507,15 +508,16 @@ def _repr_(self): TESTS:: - sage: p = PointConfiguration([[1,1,1],[-1,1,1],[1,-1,1],[-1,-1,1],[1,1,-1], - ....: [-1,1,-1],[1,-1,-1],[-1,-1,-1],[0,0,0]]) + sage: p = PointConfiguration([[1,1,1], [-1,1,1], [1,-1,1], [-1,-1,1], [1,1,-1], + ....: [-1,1,-1], [1,-1,-1], [-1,-1,-1], [0,0,0]]) sage: p._repr_() 'A point configuration in affine 3-space over Integer Ring consisting of 9 points. The triangulations of this point configuration are assumed to be connected, not necessarily fine, not necessarily regular.' - sage: PointConfiguration([[1, 1, 1], [-1, 1, 1], [1, -1, 1], [-1, -1, 1]], projective=True) + sage: PointConfiguration([[1, 1, 1], [-1, 1, 1], [1, -1, 1], [-1, -1, 1]], + ....: projective=True) A point configuration in projective 2-space over Integer Ring consisting of 4 points. The triangulations of this point configuration are assumed to be connected, @@ -595,7 +597,9 @@ def _TOPCOM_exec(cls, executable, input_string, verbose=True): TESTS:: sage: p = PointConfiguration([[1,1,1], [-1,1,1], [1,-1,1], [-1,-1,1], [1,1,-1]]) - sage: out = p._TOPCOM_exec('points2placingtriang', '[[0,0,0,1],[-2,0,0,1],[0,-2,0,1],[-2,-2,0,1],[0,0,-2,1]]', verbose=True) + sage: out = p._TOPCOM_exec('points2placingtriang', + ....: '[[0,0,0,1],[-2,0,0,1],[0,-2,0,1],[-2,-2,0,1],[0,0,-2,1]]', + ....: verbose=True) sage: list(out) # optional - topcom #### TOPCOM input #### # points2placingtriang @@ -688,7 +692,7 @@ def _TOPCOM_triangulations(self, verbose=True): EXAMPLES:: - sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) + sage: p = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]) sage: iter = p._TOPCOM_triangulations(verbose=True) sage: next(iter) # optional - topcom #### TOPCOM input #### @@ -734,7 +738,7 @@ def _TOPCOM_triangulate(self, verbose=True): EXAMPLES:: - sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) + sage: p = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]) sage: p.set_engine('topcom') # optional - topcom sage: p._TOPCOM_triangulate(verbose=False) # optional - topcom (<0,1,2>, <0,1,4>, <0,2,4>, <1,2,3>) @@ -776,8 +780,7 @@ def restrict_to_regular_triangulations(self, regular=True): EXAMPLES:: - sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) - sage: p + sage: p = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]); p A point configuration in affine 2-space over Integer Ring consisting of 5 points. The triangulations of this point configuration are assumed to be connected, not necessarily @@ -821,8 +824,7 @@ def restrict_to_connected_triangulations(self, connected=True): EXAMPLES:: - sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) - sage: p + sage: p = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]); p A point configuration in affine 2-space over Integer Ring consisting of 5 points. The triangulations of this point configuration are assumed to be connected, not necessarily @@ -859,7 +861,7 @@ def restrict_to_fine_triangulations(self, fine=True): EXAMPLES:: - sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) + sage: p = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]) sage: p A point configuration in affine 2-space over Integer Ring consisting of 5 points. The triangulations of this point @@ -900,8 +902,8 @@ def restrict_to_star_triangulations(self, star): EXAMPLES:: - sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) - sage: len(list( p.triangulations() )) + sage: p = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]) + sage: len(list(p.triangulations())) 4 sage: p_star = p.restrict_to_star_triangulations(0) sage: p_star is p.restrict_to_star_triangulations((0,0)) @@ -935,7 +937,7 @@ def triangulations(self, verbose=False): EXAMPLES:: - sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) + sage: p = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]) sage: iter = p.triangulations() sage: next(iter) (<1,3,4>, <2,3,4>) @@ -1010,7 +1012,7 @@ def triangulations_list(self, verbose=False): EXAMPLES:: - sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1]]) + sage: p = PointConfiguration([[0,0], [0,1], [1,0], [1,1]]) sage: p.triangulations_list() [(<0,1,2>, <1,2,3>), (<0,1,3>, <0,2,3>)] sage: list(map(list, p.triangulations_list())) @@ -1039,7 +1041,7 @@ def triangulate(self, verbose=False): EXAMPLES:: - sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) + sage: p = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]) sage: p.triangulate() (<1,3,4>, <2,3,4>) sage: list( p.triangulate() ) @@ -1050,7 +1052,7 @@ def triangulate(self, verbose=False): sage: p.set_engine('topcom') # optional - topcom sage: p.triangulate() # optional - topcom (<0,1,2>, <0,1,4>, <0,2,4>, <1,2,3>) - sage: list( p.triangulate() ) # optional - topcom + sage: list(p.triangulate()) # optional - topcom [(0, 1, 2), (0, 1, 4), (0, 2, 4), (1, 2, 3)] sage: p.set_engine('internal') # optional - topcom """ @@ -1077,7 +1079,7 @@ def convex_hull(self): EXAMPLES:: - sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) + sage: p = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]) sage: p.convex_hull() A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices """ @@ -1123,21 +1125,22 @@ def restricted_automorphism_group(self): EXAMPLES:: - sage: pyramid = PointConfiguration([[1,0,0],[0,1,1],[0,1,-1],[0,-1,-1],[0,-1,1]]) - sage: G = pyramid.restricted_automorphism_group() # optional - sage.graphs, sage.groups - sage: G == PermutationGroup([[(3,5)], [(2,3),(4,5)], [(2,4)]]) # optional - sage.graphs, sage.groups + sage: pyramid = PointConfiguration([[1,0,0], [0,1,1], [0,1,-1], + ....: [0,-1,-1], [0,-1,1]]) + sage: G = pyramid.restricted_automorphism_group() # optional - sage.graphs sage.groups + sage: G == PermutationGroup([[(3,5)], [(2,3),(4,5)], [(2,4)]]) # optional - sage.graphs sage.groups True - sage: DihedralGroup(4).is_isomorphic(G) # optional - sage.graphs, sage.groups + sage: DihedralGroup(4).is_isomorphic(G) # optional - sage.graphs sage.groups True The square with an off-center point in the middle. Note that the middle point breaks the restricted automorphism group `D_4` of the convex hull:: - sage: square = PointConfiguration([(3/4,3/4),(1,1),(1,-1),(-1,-1),(-1,1)]) - sage: square.restricted_automorphism_group() # optional - sage.graphs, sage.groups + sage: square = PointConfiguration([(3/4,3/4), (1,1), (1,-1), (-1,-1), (-1,1)]) + sage: square.restricted_automorphism_group() # optional - sage.graphs sage.groups Permutation Group with generators [(3,5)] - sage: DihedralGroup(1).is_isomorphic(_) # optional - sage.graphs, sage.groups + sage: DihedralGroup(1).is_isomorphic(_) # optional - sage.graphs sage.groups True """ v_list = [ vector(p.projective()) for p in self ] @@ -1170,13 +1173,14 @@ def face_codimension(self, point): P(1, 0) sage: triangle.face_codimension(2) 1 - sage: triangle.face_codimension( [1,0] ) + sage: triangle.face_codimension([1,0]) 1 This also works for degenerate cases like the tip of the pyramid over a square (which saturates four inequalities):: - sage: pyramid = PointConfiguration([[1,0,0],[0,1,1],[0,1,-1],[0,-1,-1],[0,-1,1]]) + sage: pyramid = PointConfiguration([[1,0,0], [0,1,1], [0,1,-1], + ....: [0,-1,-1], [0,-1,1]]) sage: pyramid.face_codimension(0) 3 """ @@ -1245,7 +1249,7 @@ def exclude_points(self, point_idx_list): sage: q = p.exclude_points([3]) sage: list(q) [P(-1, 0), P(0, 0), P(1, -1), P(1, 1)] - sage: p.exclude_points( p.face_interior(codim=1) ).points() + sage: p.exclude_points(p.face_interior(codim=1)).points() (P(-1, 0), P(0, 0), P(1, -1), P(1, 1)) """ points = [self.point(i) for i in range(self.n_points()) @@ -1259,7 +1263,7 @@ def exclude_points(self, point_idx_list): def volume(self, simplex=None): """ - Find n! times the n-volume of a simplex of dimension n. + Find `n!` times the `n`-volume of a simplex of dimension `n`. INPUT: @@ -1268,16 +1272,16 @@ def volume(self, simplex=None): OUTPUT: - * If a simplex was passed as an argument: n!*(volume of ``simplex``). + * If a simplex was passed as an argument: `n!` * (volume of ``simplex``). - * Without argument: n!*(the total volume of the convex hull). + * Without argument: `n!` * (the total volume of the convex hull). EXAMPLES: The volume of the standard simplex should always be 1:: - sage: p = PointConfiguration([[0,0],[1,0],[0,1],[1,1]]) - sage: p.volume( [0,1,2] ) + sage: p = PointConfiguration([[0,0], [1,0], [0,1], [1,1]]) + sage: p.volume([0,1,2]) 1 sage: simplex = p.triangulate()[0] # first simplex of triangulation sage: p.volume(simplex) @@ -1291,9 +1295,9 @@ def volume(self, simplex=None): .. note:: - We return n!*(metric volume of the simplex) to ensure that + We return `n!` * (metric volume of the simplex) to ensure that the volume is an integer. Essentially, this normalizes - things so that the volume of the standard n-simplex is 1. + things so that the volume of the standard `n`-simplex is 1. See [GKZ1994]_ page 182. """ if (simplex is None): @@ -1324,7 +1328,7 @@ def secondary_polytope(self): EXAMPLES:: - sage: p = PointConfiguration([[0,0],[1,0],[2,1],[1,2],[0,1]]) + sage: p = PointConfiguration([[0,0], [1,0], [2,1], [1,2], [0,1]]) sage: poly = p.secondary_polytope() sage: poly.vertices_matrix() [1 1 3 3 5] @@ -1437,7 +1441,7 @@ def circuits(self): EXAMPLES:: - sage: p = PointConfiguration([(0,0),(+1,0),(-1,0),(0,+1),(0,-1)]) + sage: p = PointConfiguration([(0,0), (+1,0), (-1,0), (0,+1), (0,-1)]) sage: sorted(p.circuits()) [((0,), (1, 2), (3, 4)), ((0,), (3, 4), (1, 2)), ((1, 2), (0,), (3, 4))] @@ -1452,7 +1456,7 @@ def circuits(self): ....: [ 0, 0, 0, 0, 1, 0,-1, 0, 0, 0, 0, 0, 0, 0] ....: ]) sage: p = PointConfiguration(U.columns()) - sage: len( p.circuits() ) # long time + sage: len(p.circuits()) # long time 218 """ try: @@ -1492,7 +1496,8 @@ def positive_circuits(self, *negative): EXAMPLES:: - sage: p = PointConfiguration([(1,0,0),(0,1,0),(0,0,1),(-2,0,-1),(-2,-1,0),(-3,-1,-1),(1,1,1),(-1,0,0),(0,0,0)]) + sage: p = PointConfiguration([(1,0,0), (0,1,0), (0,0,1), (-2,0,-1), (-2,-1,0), + ....: (-3,-1,-1), (1,1,1), (-1,0,0), (0,0,0)]) sage: sorted(p.positive_circuits(8)) [(0, 1, 2, 5), (0, 1, 4), (0, 2, 3), (0, 3, 4, 6), (0, 5, 6), (0, 7)] sage: p.positive_circuits(0,5,6) @@ -1525,9 +1530,9 @@ def bistellar_flips(self): sage: pc.bistellar_flips() (((<0,1,3>, <0,2,3>), (<0,1,2>, <1,2,3>)),) sage: Tpos, Tneg = pc.bistellar_flips()[0] - sage: Tpos.plot(axes=False) # optional - sage.plot + sage: Tpos.plot(axes=False) # optional - sage.plot Graphics object consisting of 11 graphics primitives - sage: Tneg.plot(axes=False) # optional - sage.plot + sage: Tneg.plot(axes=False) # optional - sage.plot Graphics object consisting of 11 graphics primitives The 3d analog:: @@ -1542,7 +1547,7 @@ def bistellar_flips(self): sage: pc.bistellar_flips() (((<0,1,3>, <0,2,3>), (<0,1,2>, <1,2,3>)),) sage: Tpos, Tneg = pc.bistellar_flips()[0] - sage: Tpos.plot(axes=False) # optional - sage.plot + sage: Tpos.plot(axes=False) # optional - sage.plot Graphics3d Object """ flips = [] @@ -1565,13 +1570,13 @@ def lexicographic_triangulation(self): EXAMPLES:: - sage: p = PointConfiguration([(0,0),(+1,0),(-1,0),(0,+1),(0,-1)]) + sage: p = PointConfiguration([(0,0), (+1,0), (-1,0), (0,+1), (0,-1)]) sage: p.lexicographic_triangulation() (<1,3,4>, <2,3,4>) TESTS:: - sage: U=matrix([ + sage: U = matrix([ ....: [ 0, 0, 0, 0, 0, 2, 4,-1, 1, 1, 0, 0, 1, 0], ....: [ 0, 0, 0, 1, 0, 0,-1, 0, 0, 0, 0, 0, 0, 0], ....: [ 0, 2, 0, 0, 0, 0,-1, 0, 1, 0, 1, 0, 0, 1], @@ -1670,7 +1675,7 @@ def distance_affine(self, x, y): EXAMPLES:: sage: pc = PointConfiguration([(0,0),(1,0),(2,1),(1,2),(0,1)]) - sage: [ pc.distance_affine(pc.point(0), p) for p in pc.points() ] + sage: [pc.distance_affine(pc.point(0), p) for p in pc.points()] [0, 1, 5, 5, 1] """ self._assert_is_affine() @@ -1705,8 +1710,8 @@ def distance_FS(self, x, y): EXAMPLES:: - sage: pc = PointConfiguration([(0,0),(1,0),(2,1),(1,2),(0,1)]) - sage: [ pc.distance_FS(pc.point(0), p) for p in pc.points() ] + sage: pc = PointConfiguration([(0,0), (1,0), (2,1), (1,2), (0,1)]) + sage: [pc.distance_FS(pc.point(0), p) for p in pc.points()] [0, 1/2, 5/6, 5/6, 1/2] """ x2 = y2 = xy = 0 @@ -1735,12 +1740,13 @@ def distance(self, x, y): EXAMPLES:: - sage: pc = PointConfiguration([(0,0),(1,0),(2,1),(1,2),(0,1)]) - sage: [ pc.distance(pc.point(0), p) for p in pc.points() ] + sage: pc = PointConfiguration([(0,0), (1,0), (2,1), (1,2), (0,1)]) + sage: [pc.distance(pc.point(0), p) for p in pc.points()] [0, 1, 5, 5, 1] - sage: pc = PointConfiguration([(0,0,1),(1,0,1),(2,1,1),(1,2,1),(0,1,1)], projective=True) - sage: [ pc.distance(pc.point(0), p) for p in pc.points() ] + sage: pc = PointConfiguration([(0,0,1), (1,0,1), (2,1,1), (1,2,1), (0,1,1)], + ....: projective=True) + sage: [pc.distance(pc.point(0), p) for p in pc.points()] [0, 1/2, 5/6, 5/6, 1/2] """ if self.is_affine(): @@ -1767,8 +1773,8 @@ def farthest_point(self, points, among=None): EXAMPLES:: - sage: pc = PointConfiguration([(0,0),(1,0),(1,1),(0,1)]) - sage: pc.farthest_point([ pc.point(0) ]) + sage: pc = PointConfiguration([(0,0), (1,0), (1,1), (0,1)]) + sage: pc.farthest_point([pc.point(0)]) P(1, 1) """ if len(points)==0: @@ -1822,7 +1828,7 @@ def contained_simplex(self, large=True, initial_point=None, point_order=None): EXAMPLES:: - sage: pc = PointConfiguration([(0,0),(1,0),(2,1),(1,1),(0,1)]) + sage: pc = PointConfiguration([(0,0), (1,0), (2,1), (1,1), (0,1)]) sage: pc.contained_simplex() (P(0, 1), P(2, 1), P(1, 0)) sage: pc.contained_simplex(large=False) @@ -1830,23 +1836,23 @@ def contained_simplex(self, large=True, initial_point=None, point_order=None): sage: pc.contained_simplex(initial_point=pc.point(2)) (P(2, 1), P(0, 0), P(1, 0)) - sage: pc = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) + sage: pc = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]) sage: pc.contained_simplex() (P(-1, -1), P(1, 1), P(0, 1)) - sage: pc.contained_simplex(point_order = [pc[1],pc[3],pc[4],pc[2],pc[0]]) + sage: pc.contained_simplex(point_order=[pc[1], pc[3], pc[4], pc[2], pc[0]]) (P(0, 1), P(1, 1), P(-1, -1)) Lower-dimensional example:: - sage: pc.contained_simplex(point_order = [pc[0],pc[3],pc[4]]) + sage: pc.contained_simplex(point_order=[pc[0], pc[3], pc[4]]) (P(0, 0), P(1, 1)) TESTS:: - sage: pc = PointConfiguration([[0,0],[0,1],[1,0]]) + sage: pc = PointConfiguration([[0,0], [0,1], [1,0]]) sage: pc.contained_simplex() (P(1, 0), P(0, 1), P(0, 0)) - sage: pc = PointConfiguration([[0,0],[0,1]]) + sage: pc = PointConfiguration([[0,0], [0,1]]) sage: pc.contained_simplex() (P(0, 1), P(0, 0)) sage: pc = PointConfiguration([[0,0]]) @@ -1907,14 +1913,14 @@ def placing_triangulation(self, point_order=None): EXAMPLES:: - sage: pc = PointConfiguration([(0,0),(1,0),(2,1),(1,2),(0,1)]) + sage: pc = PointConfiguration([(0,0), (1,0), (2,1), (1,2), (0,1)]) sage: pc.placing_triangulation() (<0,1,2>, <0,2,4>, <2,3,4>) sage: pc.placing_triangulation(point_order=(3,2,1,4,0)) (<0,1,4>, <1,2,3>, <1,3,4>) - sage: pc.placing_triangulation(point_order=[pc[1],pc[3],pc[4],pc[0]]) + sage: pc.placing_triangulation(point_order=[pc[1], pc[3], pc[4], pc[0]]) (<0,1,4>, <1,3,4>) - sage: U=matrix([ + sage: U = matrix([ ....: [ 0, 0, 0, 0, 0, 2, 4,-1, 1, 1, 0, 0, 1, 0], ....: [ 0, 0, 0, 1, 0, 0,-1, 0, 0, 0, 0, 0, 0, 0], ....: [ 0, 2, 0, 0, 0, 0,-1, 0, 1, 0, 1, 0, 0, 1], @@ -1931,7 +1937,7 @@ def placing_triangulation(self, point_order=None): <3,4,6,7,11,12>, <3,4,7,11,12,13>, <3,6,7,11,12,13>, <4,6,7,11,12,13>) sage: sum(p.volume(t) for t in triangulation) 42 - sage: p0 = PointConfiguration([(0,0),(+1,0),(-1,0),(0,+1),(0,-1)]) + sage: p0 = PointConfiguration([(0,0), (+1,0), (-1,0), (0,+1), (0,-1)]) sage: p0.pushing_triangulation(point_order=[1,2,0,3,4]) (<1,2,3>, <1,2,4>) sage: p0.pushing_triangulation(point_order=[0,1,2,3,4]) @@ -1939,7 +1945,7 @@ def placing_triangulation(self, point_order=None): The same triangulation with renumbered points 0->4, 1->0, etc:: - sage: p1 = PointConfiguration([(+1,0),(-1,0),(0,+1),(0,-1),(0,0)]) + sage: p1 = PointConfiguration([(+1,0), (-1,0), (0,+1), (0,-1), (0,0)]) sage: p1.pushing_triangulation(point_order=[4,0,1,2,3]) (<0,2,4>, <0,3,4>, <1,2,4>, <1,3,4>) """ @@ -2049,7 +2055,7 @@ def Gale_transform(self, points=None): EXAMPLES:: - sage: pc = PointConfiguration([(0,0),(1,0),(2,1),(1,1),(0,1)]) + sage: pc = PointConfiguration([(0,0), (1,0), (2,1), (1,1), (0,1)]) sage: pc.Gale_transform() [ 1 -1 0 1 -1] [ 0 0 1 -2 1] @@ -2078,14 +2084,14 @@ def plot(self, **kwds): EXAMPLES:: - sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) - sage: p.plot(axes=False) # optional - sage.plot + sage: p = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]) + sage: p.plot(axes=False) # optional - sage.plot Graphics object consisting of 5 graphics primitives .. PLOT:: :width: 300 px - p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) + p = PointConfiguration([[0,0], [0,1], [1,0], [1,1], [-1,-1]]) sphinx_plot(p.plot(axes=False)) """ return self.element_class([], parent=self, check=False).plot(**kwds) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index c2e42bcbd38..5cfca9b6a57 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -3933,7 +3933,7 @@ def chromatic_symmetric_function(self, R=None): """ from sage.combinat.sf.sf import SymmetricFunctions from sage.combinat.partition import _Partitions - from sage.misc.misc import powerset + from sage.combinat.subset import powerset if R is None: R = ZZ p = SymmetricFunctions(R).p() diff --git a/src/sage/graphs/hypergraph_generators.py b/src/sage/graphs/hypergraph_generators.py index e90beaee76d..a106f3fc7d8 100644 --- a/src/sage/graphs/hypergraph_generators.py +++ b/src/sage/graphs/hypergraph_generators.py @@ -355,7 +355,7 @@ def BinomialRandomUniform(self, n, k, p): raise ValueError("edge probability should be in [0,1]") import numpy.random as nrn - from sage.functions.other import binomial + from sage.arith.misc import binomial m = nrn.binomial(binomial(nverts, uniformity), p) return hypergraphs.UniformRandomUniform(n, k, m) diff --git a/src/sage/groups/additive_abelian/additive_abelian_group.py b/src/sage/groups/additive_abelian/additive_abelian_group.py index 62274a7bfef..fc9cb6a3088 100644 --- a/src/sage/groups/additive_abelian/additive_abelian_group.py +++ b/src/sage/groups/additive_abelian/additive_abelian_group.py @@ -450,7 +450,7 @@ def permutation_group(self): EXAMPLES:: sage: G = AdditiveAbelianGroup([2, 3]) - sage: G.permutation_group() + sage: G.permutation_group() # optional - sage.groups Permutation Group with generators [(3,4,5), (1,2)] TESTS: diff --git a/src/sage/groups/additive_abelian/additive_abelian_wrapper.py b/src/sage/groups/additive_abelian/additive_abelian_wrapper.py index 372519833bc..9224bc6a915 100644 --- a/src/sage/groups/additive_abelian/additive_abelian_wrapper.py +++ b/src/sage/groups/additive_abelian/additive_abelian_wrapper.py @@ -85,12 +85,12 @@ def __init__(self, domain): r""" EXAMPLES:: - sage: G = AdditiveAbelianGroupWrapper(QQbar, [sqrt(QQbar(2)), sqrt(QQbar(3))], [0, 0]) - sage: F = QQbar.coerce_map_from(G); F + sage: G = AdditiveAbelianGroupWrapper(QQbar, [sqrt(QQbar(2)), sqrt(QQbar(3))], [0, 0]) # optional - sage.rings.number_field + sage: F = QQbar.coerce_map_from(G); F # optional - sage.rings.number_field Generic morphism: From: Additive abelian group isomorphic to Z + Z embedded in Algebraic Field To: Algebraic Field - sage: type(F) + sage: type(F) # optional - sage.rings.number_field """ Morphism.__init__(self, domain.Hom(domain.universe())) @@ -127,8 +127,8 @@ def __init__(self, parent, vector, element=None, check=False): EXAMPLES:: sage: from sage.groups.additive_abelian.additive_abelian_wrapper import AdditiveAbelianGroupWrapper - sage: G = AdditiveAbelianGroupWrapper(QQbar, [sqrt(QQbar(2)), sqrt(QQbar(3))], [0, 0]) - sage: G.0 # indirect doctest + sage: G = AdditiveAbelianGroupWrapper(QQbar, [sqrt(QQbar(2)), sqrt(QQbar(3))], [0, 0]) # optional - sage.rings.number_field + sage: G.0 # indirect doctest # optional - sage.rings.number_field 1.414213562373095? """ addgp.AdditiveAbelianGroupElement.__init__(self, parent, vector, check) @@ -185,13 +185,15 @@ class AdditiveAbelianGroupWrapper(addgp.AdditiveAbelianGroup_fixed_gens): :: - sage: AdditiveAbelianGroupWrapper(QQbar, [sqrt(2), sqrt(3)], [0, 0]) + sage: AdditiveAbelianGroupWrapper(QQbar, [sqrt(2), sqrt(3)], [0, 0]) # optional - sage.rings.number_field sage.symbolic Additive abelian group isomorphic to Z + Z embedded in Algebraic Field :: - sage: EllipticCurve(GF(419**2), [1,0]).abelian_group() # indirect doctest - Additive abelian group isomorphic to Z/420 + Z/420 embedded in Abelian group of points on Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 419^2 + sage: EllipticCurve(GF(419**2), [1,0]).abelian_group() # indirect doctest # optional - sage.libs.pari + Additive abelian group isomorphic to Z/420 + Z/420 embedded in + Abelian group of points on Elliptic Curve + defined by y^2 = x^3 + x over Finite Field in z2 of size 419^2 """ Element = AdditiveAbelianGroupWrapperElement @@ -200,7 +202,7 @@ def __init__(self, universe, gens, invariants): r""" EXAMPLES:: - sage: AdditiveAbelianGroupWrapper(QQbar, [sqrt(QQbar(2)), sqrt(QQbar(3))], [0, 0]) # indirect doctest + sage: AdditiveAbelianGroupWrapper(QQbar, [sqrt(QQbar(2)), sqrt(QQbar(3))], [0, 0]) # indirect doctest # optional - sage.rings.number_field Additive abelian group isomorphic to Z + Z embedded in Algebraic Field """ self._universe = universe @@ -217,8 +219,8 @@ def universe(self): EXAMPLES:: - sage: G = AdditiveAbelianGroupWrapper(QQbar, [sqrt(QQbar(2)), sqrt(QQbar(3))], [0, 0]) - sage: G.universe() + sage: G = AdditiveAbelianGroupWrapper(QQbar, [sqrt(QQbar(2)), sqrt(QQbar(3))], [0, 0]) # optional - sage.rings.number_field + sage: G.universe() # optional - sage.rings.number_field Algebraic Field """ return self._universe @@ -246,8 +248,8 @@ def _repr_(self): r""" EXAMPLES:: - sage: G = AdditiveAbelianGroupWrapper(QQbar, [sqrt(QQbar(2)), sqrt(QQbar(3))], [0, 0]) - sage: repr(G) # indirect doctest + sage: G = AdditiveAbelianGroupWrapper(QQbar, [sqrt(QQbar(2)), sqrt(QQbar(3))], [0, 0]) # optional - sage.rings.number_field + sage: repr(G) # indirect doctest # optional - sage.rings.number_field 'Additive abelian group isomorphic to Z + Z embedded in Algebraic Field' """ return addgp.AdditiveAbelianGroup_fixed_gens._repr_(self) + " embedded in " + self.universe()._repr_() @@ -283,10 +285,10 @@ def discrete_exp(self, v): EXAMPLES:: - sage: G = AdditiveAbelianGroupWrapper(QQbar, [sqrt(QQbar(2)), -1], [0, 0]) - sage: v = G.discrete_exp([3, 5]); v + sage: G = AdditiveAbelianGroupWrapper(QQbar, [sqrt(QQbar(2)), -1], [0, 0]) # optional - sage.rings.number_field + sage: v = G.discrete_exp([3, 5]); v # optional - sage.rings.number_field -0.7573593128807148? - sage: v.parent() is QQbar + sage: v.parent() is QQbar # optional - sage.rings.number_field True This method is an inverse of :meth:`discrete_log`:: @@ -338,9 +340,10 @@ def discrete_log(self, x, gens=None): :: - sage: F. = GF(1009**2, modulus=x**2+11); E = EllipticCurve(j=F(940)) - sage: P, Q = E(900*t + 228, 974*t + 185), E(1007*t + 214, 865*t + 802) - sage: E.abelian_group().discrete_log(123 * P + 777 * Q, [P, Q]) + sage: x = polygen(ZZ, 'x') + sage: F. = GF(1009**2, modulus=x**2+11); E = EllipticCurve(j=F(940)) # optional - sage.libs.pari + sage: P, Q = E(900*t + 228, 974*t + 185), E(1007*t + 214, 865*t + 802) # optional - sage.libs.pari + sage: E.abelian_group().discrete_log(123 * P + 777 * Q, [P, Q]) # optional - sage.libs.pari (123, 777) :: @@ -356,8 +359,8 @@ def discrete_log(self, x, gens=None): :: - sage: G = AdditiveAbelianGroupWrapper(QQbar, [sqrt(2)], [0]) - sage: G.discrete_log(QQbar(2*sqrt(2))) + sage: G = AdditiveAbelianGroupWrapper(QQbar, [sqrt(2)], [0]) # optional - sage.rings.number_field + sage: G.discrete_log(QQbar(2*sqrt(2))) # optional - sage.rings.number_field Traceback (most recent call last): ... NotImplementedError: No black-box discrete log for infinite abelian groups @@ -425,17 +428,20 @@ def torsion_subgroup(self, n=None): sage: A = AdditiveAbelianGroupWrapper(G.0.parent(), G.gens(), ords) sage: T = A.torsion_subgroup(5) sage: T - Additive abelian group isomorphic to Z/5 + Z/5 + Z/5 embedded in Additive abelian group isomorphic to Z/2 + Z/6 + Z/30 + Z + Z/210 + Z/2310 + Additive abelian group isomorphic to Z/5 + Z/5 + Z/5 embedded in + Additive abelian group isomorphic to Z/2 + Z/6 + Z/30 + Z + Z/210 + Z/2310 sage: T.gens() ((0, 0, 6, 0, 0, 0), (0, 0, 0, 0, 42, 0), (0, 0, 0, 0, 0, 462)) :: - sage: E = EllipticCurve(GF(487^2), [311,205]) - sage: T = E.abelian_group().torsion_subgroup(42) - sage: T - Additive abelian group isomorphic to Z/42 + Z/6 embedded in Abelian group of points on Elliptic Curve defined by y^2 = x^3 + 311*x + 205 over Finite Field in z2 of size 487^2 - sage: [P.order() for P in T.gens()] + sage: E = EllipticCurve(GF(487^2), [311,205]) # optional - sage.libs.pari + sage: T = E.abelian_group().torsion_subgroup(42) # optional - sage.libs.pari + sage: T # optional - sage.libs.pari + Additive abelian group isomorphic to Z/42 + Z/6 embedded in + Abelian group of points on Elliptic Curve + defined by y^2 = x^3 + 311*x + 205 over Finite Field in z2 of size 487^2 + sage: [P.order() for P in T.gens()] # optional - sage.libs.pari [42, 6] :: @@ -551,12 +557,12 @@ def _discrete_log_pgroup(p, vals, aa, b): Check for :trac:`34716`:: - sage: E = EllipticCurve(GF(487^2), [311,205]) - sage: G = E.abelian_group().torsion_subgroup(42) - sage: G.invariants() + sage: E = EllipticCurve(GF(487^2), [311,205]) # optional - sage.libs.pari + sage: G = E.abelian_group().torsion_subgroup(42) # optional - sage.libs.pari + sage: G.invariants() # optional - sage.libs.pari (6, 42) - sage: P, Q = G.torsion_subgroup(6).gens() - sage: G.discrete_log(2*P + 3*Q, [P, Q]) # indirect doctest + sage: P, Q = G.torsion_subgroup(6).gens() # optional - sage.libs.pari + sage: G.discrete_log(2*P + 3*Q, [P, Q]) # indirect doctest # optional - sage.groups (2, 3) """ from itertools import product as iproduct diff --git a/src/sage/groups/braid.py b/src/sage/groups/braid.py index 67f1f8e4dd9..6cd4265e4bd 100644 --- a/src/sage/groups/braid.py +++ b/src/sage/groups/braid.py @@ -1187,7 +1187,6 @@ def _enhanced_states(self): [(2, [((1, 1), [], [([(0, 0), (1, 2)], 0), ([(0, 2), (1, 0)], 0)])])])] """ from sage.graphs.graph import Graph - from sage.functions.generalized import sgn crossinglist = self.Tietze() ncross = len(crossinglist) writhe = 0 @@ -1198,7 +1197,7 @@ def _enhanced_states(self): first_crossing_in_row = [None] * self.strands() crossings = [None] * ncross for i, cr in enumerate(crossinglist): - writhe = writhe + sgn(cr) + writhe = writhe + cr.sign() prevabove = last_crossing_in_row[abs(cr) - 1] prevbelow = last_crossing_in_row[abs(cr)] if prevabove is None: @@ -1243,7 +1242,7 @@ def _enhanced_states(self): v = v + [0]*(ncross - len(v)) G = Graph() for j, cr in enumerate(crossings): - if (v[j]*2-1)*sgn(cr["cr"]) == -1: # oriented resolution + if (v[j]*2-1) * cr["cr"].sign() == -1: # oriented resolution G.add_edge((j, cr["next_above"], abs(cr["cr"]) - 1), (j, 1)) G.add_edge((cr["prev_above"], j, abs(cr["cr"]) - 1), (j, 1)) G.add_edge((j, cr["next_below"], abs(cr["cr"])), (j, 3)) diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py index 6a6efb98ad8..ccd1c9868e5 100644 --- a/src/sage/groups/finitely_presented.py +++ b/src/sage/groups/finitely_presented.py @@ -136,7 +136,8 @@ from sage.libs.gap.element import GapElement from sage.misc.cachefunc import cached_method from sage.groups.free_group import FreeGroupElement -from sage.functions.generalized import sign +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.generalized", "sign") from sage.matrix.constructor import matrix from sage.categories.morphism import SetMorphism diff --git a/src/sage/groups/generic.py b/src/sage/groups/generic.py index 33e92d43ca5..29ee9041342 100644 --- a/src/sage/groups/generic.py +++ b/src/sage/groups/generic.py @@ -111,10 +111,11 @@ from copy import copy +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 @@ -1266,7 +1267,7 @@ def _order_from_multiple_helper(Q, L, S): for k in range(l): p, e = L[k] # multiplying by p**e require roughly 'e log_2(p) / 2' additions - v = e * sage.functions.log.log(float(p)) + v = e * log(float(p)) if abs(sum_left + v - (S / 2)) > abs(sum_left - (S / 2)): break sum_left += v @@ -1282,7 +1283,7 @@ def _order_from_multiple_helper(Q, L, S): S - sum_left) return o1 * o2 - return _order_from_multiple_helper(P, F, sage.functions.log.log(float(M))) + return _order_from_multiple_helper(P, F, log(float(M))) def order_from_bounds(P, bounds, d=None, operation='+', diff --git a/src/sage/groups/group.pyx b/src/sage/groups/group.pyx index 7947f0f876d..38df92c175d 100644 --- a/src/sage/groups/group.pyx +++ b/src/sage/groups/group.pyx @@ -39,11 +39,11 @@ def is_Group(x): EXAMPLES:: - sage: F. = FreeGroup() + sage: F. = FreeGroup() # optional - sage.groups sage: from sage.groups.group import is_Group - sage: is_Group(F) + sage: is_Group(F) # optional - sage.groups True - sage: is_Group("a string") + sage: is_Group("a string") # optional - sage.groups False """ from sage.groups.old import Group as OldGroup @@ -91,7 +91,7 @@ cdef class Group(Parent): sage: G = Group(category=Groups()) # todo: do the same test with some subcategory of Groups when there will exist one sage: G.category() Category of groups - sage: G = Group(category = CommutativeAdditiveGroups()) + sage: G = Group(category=CommutativeAdditiveGroups()) Traceback (most recent call last): ... ValueError: (Category of commutative additive groups,) is not a subcategory of Category of groups @@ -100,10 +100,10 @@ cdef class Group(Parent): Check for :trac:`8119`:: - sage: G = SymmetricGroup(2) - sage: h = hash(G) - sage: G.rename('S2') - sage: h == hash(G) + sage: G = SymmetricGroup(2) # optional - sage.groups + sage: h = hash(G) # optional - sage.groups + sage: G.rename('S2') # optional - sage.groups + sage: h == hash(G) # optional - sage.groups True """ from sage.categories.groups import Groups diff --git a/src/sage/groups/lie_gps/catalog.py b/src/sage/groups/lie_gps/catalog.py index 1b35d31d6b7..cafcbc4a642 100644 --- a/src/sage/groups/lie_gps/catalog.py +++ b/src/sage/groups/lie_gps/catalog.py @@ -1,5 +1,7 @@ r""" Type ``groups.lie.`` to access examples of Lie groups. """ +from sage.misc.lazy_import import lazy_import as _lazy_import -from sage.groups.lie_gps.nilpotent_lie_group import NilpotentLieGroup as Nilpotent +# We use lazy import because the module depends on sage.manifolds and thus on sage.symbolic +_lazy_import('sage.groups.lie_gps.nilpotent_lie_group', 'NilpotentLieGroup', as_='Nilpotent') diff --git a/src/sage/groups/old.pyx b/src/sage/groups/old.pyx index c17082f59cb..8049eb8e2e5 100644 --- a/src/sage/groups/old.pyx +++ b/src/sage/groups/old.pyx @@ -50,10 +50,10 @@ cdef class Group(sage.structure.parent.Parent): Check for :trac:`8119`:: - sage: G = SymmetricGroup(2) - sage: h = hash(G) - sage: G.rename('S2') - sage: h == hash(G) + sage: G = SymmetricGroup(2) # optional - sage.groups + sage: h = hash(G) # optional - sage.groups + sage: G.rename('S2') # optional - sage.groups + sage: h == hash(G) # optional - sage.groups True """ from sage.categories.basic import Groups @@ -123,7 +123,7 @@ cdef class Group(sage.structure.parent.Parent): EXAMPLES:: - sage: SL(2, 7).is_commutative() + sage: SL(2, 7).is_commutative() # optional - sage.modules False """ return self.is_abelian() diff --git a/src/sage/homology/algebraic_topological_model.py b/src/sage/homology/algebraic_topological_model.py index f89a1529dd9..ecb18e2c5e1 100644 --- a/src/sage/homology/algebraic_topological_model.py +++ b/src/sage/homology/algebraic_topological_model.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.graphs r""" Algebraic topological model for a cell complex diff --git a/src/sage/homology/all__sagemath_polyhedra.py b/src/sage/homology/all__sagemath_polyhedra.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/sage/homology/chain_complex.py b/src/sage/homology/chain_complex.py index 08e9158e590..6b318dce6ee 100644 --- a/src/sage/homology/chain_complex.py +++ b/src/sage/homology/chain_complex.py @@ -62,7 +62,6 @@ from sage.matrix.constructor import matrix from sage.misc.latex import latex from sage.misc.superseded import deprecation -from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF from sage.rings.fast_arith import prime_range from sage.homology.homology_group import HomologyGroup @@ -85,7 +84,7 @@ def _latex_module(R, m): '\\Bold{Z}^{3}' sage: _latex_module(ZZ, 0) '0' - sage: _latex_module(GF(3), 1) + sage: _latex_module(GF(3), 1) # optional - sage.rings.finite_rings '\\Bold{F}_{3}^{1}' """ if m == 0: @@ -188,11 +187,11 @@ def ChainComplex(data=None, base_ring=None, grading_group=None, Chain complex with at most 2 nonzero terms over Integer Ring sage: m = matrix(ZZ, 2, 2, [0, 1, 0, 0]) - sage: D = ChainComplex([m, m], base_ring=GF(2)); D + sage: D = ChainComplex([m, m], base_ring=GF(2)); D # optional - sage.rings.finite_rings Chain complex with at most 3 nonzero terms over Finite Field of size 2 - sage: D == loads(dumps(D)) + sage: D == loads(dumps(D)) # optional - sage.rings.finite_rings True - sage: D.differential(0)==m, m.is_immutable(), D.differential(0).is_immutable() + sage: D.differential(0)==m, m.is_immutable(), D.differential(0).is_immutable() # optional - sage.rings.finite_rings (True, False, True) Note that when a chain complex is defined in Sage, new @@ -214,20 +213,21 @@ def ChainComplex(data=None, base_ring=None, grading_group=None, sage: ChainComplex([matrix(QQ, 3, 1), matrix(ZZ, 4, 3)]) Chain complex with at most 3 nonzero terms over Rational Field - sage: ChainComplex([matrix(GF(125, 'a'), 3, 1), matrix(ZZ, 4, 3)]) + sage: ChainComplex([matrix(GF(125, 'a'), 3, 1), matrix(ZZ, 4, 3)]) # optional - sage.rings.finite_rings Chain complex with at most 3 nonzero terms over Finite Field in a of size 5^3 If the matrices are defined over incompatible rings, an error results:: - sage: ChainComplex([matrix(GF(125, 'a'), 3, 1), matrix(QQ, 4, 3)]) + sage: ChainComplex([matrix(GF(125, 'a'), 3, 1), matrix(QQ, 4, 3)]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Finite Field in a of size 5^3' and 'Rational Field' + TypeError: no common canonical parent for objects with parents: + 'Finite Field in a of size 5^3' and 'Rational Field' If the base ring is given explicitly but is not compatible with the matrices, an error results:: - sage: ChainComplex([matrix(GF(125, 'a'), 3, 1)], base_ring=QQ) + sage: ChainComplex([matrix(GF(125, 'a'), 3, 1)], base_ring=QQ) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unable to convert 0 to a rational @@ -335,14 +335,15 @@ def __init__(self, parent, vectors, check=True): EXAMPLES:: - sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}, base_ring=GF(7)) - sage: C.category() + sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}, # optional - sage.rings.finite_rings + ....: base_ring=GF(7)) + sage: C.category() # optional - sage.rings.finite_rings Category of chain complexes over Finite Field of size 7 TESTS:: sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) - sage: c = C({0:vector([0, 1, 2]), 1:vector([3, 4])}) + sage: c = C({0: vector([0, 1, 2]), 1: vector([3, 4])}) sage: TestSuite(c).run() """ # only nonzero vectors shall be stored, ensuring this is the @@ -360,7 +361,7 @@ def vector(self, degree): EXAMPLES:: sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) - sage: c = C({0:vector([1, 2, 3]), 1:vector([4, 5])}) + sage: c = C({0: vector([1, 2, 3]), 1: vector([4, 5])}) sage: c.vector(0) (1, 2, 3) sage: c.vector(1) @@ -382,9 +383,9 @@ def _repr_(self): sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) sage: C() Trivial chain - sage: C({0:vector([1, 2, 3])}) + sage: C({0: vector([1, 2, 3])}) Chain(0:(1, 2, 3)) - sage: c = C({0:vector([1, 2, 3]), 1:vector([4, 5])}); c + sage: c = C({0: vector([1, 2, 3]), 1: vector([4, 5])}); c Chain with 2 nonzero terms over Integer Ring sage: c._repr_() 'Chain with 2 nonzero terms over Integer Ring' @@ -409,8 +410,9 @@ def _ascii_art_(self): EXAMPLES:: - sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0]), 1:zero_matrix(1,2)}) - sage: c = C({0:vector([1, 2, 3]), 1:vector([4, 5])}) + sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0]), + ....: 1: zero_matrix(1,2)}) + sage: c = C({0: vector([1, 2, 3]), 1: vector([4, 5])}) sage: ascii_art(c) d_2 d_1 d_0 [1] d_-1 0 <---- [0] <---- [4] <---- [2] <----- 0 @@ -455,8 +457,9 @@ def _unicode_art_(self): EXAMPLES:: - sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0]), 1:zero_matrix(1,2)}) - sage: c = C({0:vector([1, 2, 3]), 1:vector([4, 5])}) + sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0]), + ....: 1: zero_matrix(1,2)}) + sage: c = C({0: vector([1, 2, 3]), 1: vector([4, 5])}) sage: unicode_art(c) ⎛1⎞ d_2 d_1 ⎛4⎞ d_0 ⎜2⎟ d_-1 @@ -505,7 +508,7 @@ def is_cycle(self): EXAMPLES:: sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) - sage: c = C({0:vector([0, 1, 2]), 1:vector([3, 4])}) + sage: c = C({0: vector([0, 1, 2]), 1: vector([3, 4])}) sage: c.is_cycle() True """ @@ -528,7 +531,7 @@ def is_boundary(self): EXAMPLES:: sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) - sage: c = C({0:vector([0, 1, 2]), 1:vector([3, 4])}) + sage: c = C({0: vector([0, 1, 2]), 1: vector([3, 4])}) sage: c.is_boundary() False sage: z3 = C({1:(1, 0)}) @@ -553,7 +556,7 @@ def _add_(self, other): EXAMPLES:: sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) - sage: c = C({0:vector([0, 1, 2]), 1:vector([3, 4])}) + sage: c = C({0: vector([0, 1, 2]), 1: vector([3, 4])}) sage: c + c Chain with 2 nonzero terms over Integer Ring sage: ascii_art(c + c) @@ -577,7 +580,7 @@ def _lmul_(self, scalar): EXAMPLES:: sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) - sage: c = C({0:vector([0, 1, 2]), 1:vector([3, 4])}) + sage: c = C({0: vector([0, 1, 2]), 1: vector([3, 4])}) sage: 2 * c Chain with 2 nonzero terms over Integer Ring sage: 2 * c == c + c == c * 2 @@ -599,7 +602,7 @@ def __eq__(self, other): EXAMPLES:: sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) - sage: c = C({0:vector([0, 1, 2]), 1:vector([3, 4])}) + sage: c = C({0: vector([0, 1, 2]), 1: vector([3, 4])}) sage: c == c True sage: c == C(0) @@ -616,7 +619,7 @@ def __ne__(self, other): EXAMPLES:: sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) - sage: c = C({0:vector([0, 1, 2]), 1:vector([3, 4])}) + sage: c = C({0: vector([0, 1, 2]), 1: vector([3, 4])}) sage: c != c False sage: c != C(0) @@ -767,7 +770,7 @@ def rank(self, degree, ring=None): [2] sage: C.rank(0) 1 - sage: C.rank(0, ring=GF(2)) + sage: C.rank(0, ring=GF(2)) # optional - sage.rings.finite_rings 0 """ degree = self.grading_group()(degree) @@ -1075,9 +1078,12 @@ def __eq__(self, other): EXAMPLES:: - sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}, base_ring=GF(2)) - sage: D = ChainComplex({0: matrix(GF(2), 2, 3, [1, 0, 0, 0, 0, 0]), 1: matrix(ZZ, 0, 2), 3: matrix(ZZ, 0, 0)}) # base_ring determined from the matrices - sage: C == D + sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}, # optional - sage.rings.finite_rings + ....: base_ring=GF(2)) + sage: D = ChainComplex({0: matrix(GF(2), 2, 3, [1, 0, 0, 0, 0, 0]), # optional - sage.rings.finite_rings + ....: 1: matrix(ZZ, 0, 2), + ....: 3: matrix(ZZ, 0, 0)}) # base_ring determined from the matrices + sage: C == D # optional - sage.rings.finite_rings True """ if not isinstance(other, ChainComplex_class) or self.base_ring() != other.base_ring(): @@ -1101,12 +1107,16 @@ def __ne__(self, other): EXAMPLES:: - sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}, base_ring=GF(2)) - sage: D = ChainComplex({0: matrix(GF(2), 2, 3, [1, 0, 0, 0, 0, 0]), 1: matrix(ZZ, 0, 2), 3: matrix(ZZ, 0, 0)}) # base_ring determined from the matrices - sage: C != D + sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}, # optional - sage.rings.finite_rings + ....: base_ring=GF(2)) + sage: D = ChainComplex({0: matrix(GF(2), 2, 3, [1, 0, 0, 0, 0, 0]), # optional - sage.rings.finite_rings + ....: 1: matrix(ZZ, 0, 2), + ....: 3: matrix(ZZ, 0, 0)}) # base_ring determined from the matrices + sage: C != D # optional - sage.rings.finite_rings False - sage: E = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}, base_ring=ZZ) - sage: C != E + sage: E = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}, + ....: base_ring=ZZ) + sage: C != E # optional - sage.rings.finite_rings True """ return not self == other @@ -1132,15 +1142,15 @@ def _homology_chomp(self, deg, base_ring, verbose, generators): EXAMPLES:: - sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}, base_ring=GF(2)) - sage: C._homology_chomp(None, GF(2), False, False) # optional - CHomP + sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}, base_ring=GF(2)) # optional - sage.rings.finite_rings + sage: C._homology_chomp(None, GF(2), False, False) # optional - CHomP # optional - sage.rings.finite_rings doctest:...: DeprecationWarning: the CHomP interface is deprecated; hence so is this function See https://github.com/sagemath/sage/issues/33777 for details. {0: Vector space of dimension 2 over Finite Field of size 2, 1: Vector space of dimension 1 over Finite Field of size 2} sage: D = ChainComplex({0: matrix(ZZ,1,0,[]), 1: matrix(ZZ,1,1,[0]), ....: 2: matrix(ZZ,0,1,[])}) - sage: D._homology_chomp(None, GF(2), False, False) # optional - CHomP + sage: D._homology_chomp(None, GF(2), False, False) # optional - CHomP # optional - sage.rings.finite_rings {1: Vector space of dimension 1 over Finite Field of size 2, 2: Vector space of dimension 1 over Finite Field of size 2} """ @@ -1242,7 +1252,7 @@ def homology(self, deg=None, base_ring=None, generators=False, sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) sage: C.homology() {0: Z x Z, 1: Z x C3} - sage: C.homology(deg=1, base_ring = GF(3)) + sage: C.homology(deg=1, base_ring=GF(3)) # optional - sage.rings.finite_rings Vector space of dimension 2 over Finite Field of size 3 sage: D = ChainComplex({0: identity_matrix(ZZ, 4), 4: identity_matrix(ZZ, 30)}) sage: D.homology() @@ -1269,9 +1279,9 @@ def homology(self, deg=None, base_ring=None, generators=False, From a torus using a field:: - sage: T = simplicial_complexes.Torus() - sage: C_t = T.chain_complex() - sage: C_t.homology(base_ring=QQ, generators=True) + sage: T = simplicial_complexes.Torus() # optional - sage.graphs + sage: C_t = T.chain_complex() # optional - sage.graphs + sage: C_t.homology(base_ring=QQ, generators=True) # optional - sage.graphs {0: [(Vector space of dimension 1 over Rational Field, Chain(0:(0, 0, 0, 0, 0, 0, 1)))], 1: [(Vector space of dimension 1 over Rational Field, @@ -1450,8 +1460,8 @@ def betti(self, deg=None, base_ring=None): sage: C.betti() {0: 2, 1: 1} - sage: D = ChainComplex({0:matrix(GF(5), [[3, 1],[1, 2]])}) - sage: D.betti() + sage: D = ChainComplex({0: matrix(GF(5), [[3, 1],[1, 2]])}) # optional - sage.rings.finite_rings + sage: D.betti() # optional - sage.rings.finite_rings {0: 1, 1: 1} """ if base_ring is None: @@ -1489,7 +1499,7 @@ def torsion_list(self, max_prime, min_prime=2): ALGORITHM: - let `C` denote the chain complex. Let `P` equal + Let `C` denote the chain complex. Let `P` equal ``max_prime``. Compute the mod `P` homology of `C`, and use this as the base-line computation: the assumption is that this is isomorphic to the integral homology tensored with @@ -1502,18 +1512,21 @@ def torsion_list(self, max_prime, min_prime=2): sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}) sage: C.homology() {0: Z x Z, 1: Z x C3} - sage: C.torsion_list(11) + sage: C.torsion_list(11) # optional - sage.rings.finite_rings [(3, [1])] sage: C = ChainComplex([matrix(ZZ, 1, 1, [2]), matrix(ZZ, 1, 1), matrix(1, 1, [3])]) sage: C.homology(1) C2 sage: C.homology(3) C3 - sage: C.torsion_list(5) + sage: C.torsion_list(5) # optional - sage.rings.finite_rings [(2, [1]), (3, [3])] """ if self.base_ring() != ZZ: raise NotImplementedError('only implemented for base ring the integers') + + from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF + answer = [] torsion_free = self.betti(base_ring=GF(max_prime)) for p in prime_range(min_prime, max_prime): @@ -1549,11 +1562,11 @@ def _Hom_(self, other, category=None): EXAMPLES:: - sage: S = simplicial_complexes.Sphere(2) - sage: T = simplicial_complexes.Torus() - sage: C = S.chain_complex(augmented=True,cochain=True) - sage: D = T.chain_complex(augmented=True,cochain=True) - sage: Hom(C,D) # indirect doctest + sage: S = simplicial_complexes.Sphere(2) # optional - sage.graphs + sage: T = simplicial_complexes.Torus() # optional - sage.graphs + sage: C = S.chain_complex(augmented=True, cochain=True) # optional - sage.graphs + sage: D = T.chain_complex(augmented=True, cochain=True) # optional - sage.graphs + sage: Hom(C, D) # indirect doctest # optional - sage.graphs Set of Morphisms from Chain complex with at most 4 nonzero terms over Integer Ring to Chain complex with at most 4 nonzero terms over Integer Ring in Category of chain complexes over Integer Ring @@ -1615,25 +1628,25 @@ def shift(self, n=1): EXAMPLES:: - sage: S1 = simplicial_complexes.Sphere(1).chain_complex() - sage: S1.shift(1).differential(2) == -S1.differential(1) + sage: S1 = simplicial_complexes.Sphere(1).chain_complex() # optional - sage.graphs + sage: S1.shift(1).differential(2) == -S1.differential(1) # optional - sage.graphs True - sage: S1.shift(2).differential(3) == S1.differential(1) + sage: S1.shift(2).differential(3) == S1.differential(1) # optional - sage.graphs True - sage: S1.shift(3).homology(4) + sage: S1.shift(3).homology(4) # optional - sage.graphs Z For cochain complexes, shifting goes in the other direction. Topologically, this makes sense if we grade the cochain complex for a space negatively:: - sage: T = simplicial_complexes.Torus() - sage: co_T = T.chain_complex()._flip_() - sage: co_T.homology() + sage: T = simplicial_complexes.Torus() # optional - sage.graphs + sage: co_T = T.chain_complex()._flip_() # optional - sage.graphs + sage: co_T.homology() # optional - sage.graphs {-2: Z, -1: Z x Z, 0: Z} - sage: co_T.degree_of_differential() + sage: co_T.degree_of_differential() # optional - sage.graphs 1 - sage: co_T.shift(2).homology() + sage: co_T.shift(2).homology() # optional - sage.graphs {-4: Z, -3: Z x Z, -2: Z} You can achieve the same result by tensoring (on the left, to @@ -1641,7 +1654,7 @@ def shift(self, n=1): ``-n * deg``, if ``deg`` is the degree of the differential:: sage: C = ChainComplex({-2: matrix(ZZ, 0, 1)}) - sage: C.tensor(co_T).homology() + sage: C.tensor(co_T).homology() # optional - sage.graphs {-4: Z, -3: Z x Z, -2: Z} """ deg = self.degree_of_differential() diff --git a/src/sage/homology/chain_complex_homspace.py b/src/sage/homology/chain_complex_homspace.py index 5679b275a82..037a1a4bad0 100644 --- a/src/sage/homology/chain_complex_homspace.py +++ b/src/sage/homology/chain_complex_homspace.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.graphs (because all doctests use SimplicialComplex) r""" Homspaces between chain complexes @@ -12,13 +13,16 @@ sage: S = simplicial_complexes.Sphere(2) sage: T = simplicial_complexes.Torus() - sage: C = S.chain_complex(augmented=True,cochain=True) - sage: D = T.chain_complex(augmented=True,cochain=True) - sage: G = Hom(C,D) + sage: C = S.chain_complex(augmented=True, cochain=True) + sage: D = T.chain_complex(augmented=True, cochain=True) + sage: G = Hom(C, D) sage: G - Set of Morphisms from Chain complex with at most 4 nonzero terms over Integer Ring to Chain complex with at most 4 nonzero terms over Integer Ring in Category of chain complexes over Integer Ring + Set of Morphisms + from Chain complex with at most 4 nonzero terms over Integer Ring + to Chain complex with at most 4 nonzero terms over Integer Ring + in Category of chain complexes over Integer Ring - sage: S = simplicial_complexes.ChessboardComplex(3,3) + sage: S = simplicial_complexes.ChessboardComplex(3, 3) sage: H = Hom(S,S) sage: i = H.identity() sage: x = i.associated_chain_complex_morphism(augmented=True) @@ -60,7 +64,7 @@ [0 0 0 0 0 1]} sage: S = simplicial_complexes.Sphere(2) - sage: A = Hom(S,S) + sage: A = Hom(S, S) sage: i = A.identity() sage: x = i.associated_chain_complex_morphism() sage: x @@ -75,7 +79,7 @@ To: Chain complex with at most 3 nonzero terms over Integer Ring sage: f = x._matrix_dictionary sage: C = S.chain_complex() - sage: G = Hom(C,C) + sage: G = Hom(C, C) sage: w = G(f) sage: w == x True @@ -111,7 +115,7 @@ def is_ChainComplexHomspace(x): sage: from sage.homology.chain_complex_homspace import is_ChainComplexHomspace sage: T = SimplicialComplex([[1,2,3,4],[7,8,9]]) sage: C = T.chain_complex(augmented=True, cochain=True) - sage: G = Hom(C,C) + sage: G = Hom(C, C) sage: is_ChainComplexHomspace(G) True @@ -127,9 +131,12 @@ class ChainComplexHomspace(sage.categories.homset.Homset): sage: T = SimplicialComplex([[1,2,3,4],[7,8,9]]) sage: C = T.chain_complex(augmented=True, cochain=True) - sage: G = Hom(C,C) + sage: G = Hom(C, C) sage: G - Set of Morphisms from Chain complex with at most 5 nonzero terms over Integer Ring to Chain complex with at most 5 nonzero terms over Integer Ring in Category of chain complexes over Integer Ring + Set of Morphisms + from Chain complex with at most 5 nonzero terms over Integer Ring + to Chain complex with at most 5 nonzero terms over Integer Ring + in Category of chain complexes over Integer Ring """ def __call__(self, f): @@ -139,10 +146,10 @@ def __call__(self, f): EXAMPLES:: sage: S = simplicial_complexes.Sphere(5) - sage: H = Hom(S,S) + sage: H = Hom(S, S) sage: i = H.identity() sage: C = S.chain_complex() - sage: G = Hom(C,C) + sage: G = Hom(C, C) sage: x = i.associated_chain_complex_morphism() sage: f = x._matrix_dictionary sage: y = G(f) diff --git a/src/sage/homology/chain_complex_morphism.py b/src/sage/homology/chain_complex_morphism.py index b049b534e0b..085530fea9d 100644 --- a/src/sage/homology/chain_complex_morphism.py +++ b/src/sage/homology/chain_complex_morphism.py @@ -14,25 +14,25 @@ EXAMPLES:: - sage: S = simplicial_complexes.Sphere(1) - sage: S + sage: S = simplicial_complexes.Sphere(1); S # optional - sage.graphs Minimal triangulation of the 1-sphere - sage: C = S.chain_complex() - sage: C.differential() + sage: C = S.chain_complex() # optional - sage.graphs + sage: C.differential() # optional - sage.graphs {0: [], 1: [-1 -1 0] [ 1 0 -1] [ 0 1 1], 2: []} - sage: f = {0:zero_matrix(ZZ,3,3),1:zero_matrix(ZZ,3,3)} - sage: G = Hom(C,C) - sage: x = G(f) - sage: x - Chain complex endomorphism of Chain complex with at most 2 nonzero terms over Integer Ring - sage: x._matrix_dictionary + sage: f = {0: zero_matrix(ZZ,3,3), 1: zero_matrix(ZZ,3,3)} + sage: G = Hom(C, C) # optional - sage.graphs + sage: x = G(f); x # optional - sage.graphs + Chain complex endomorphism of + Chain complex with at most 2 nonzero terms over Integer Ring + sage: x._matrix_dictionary # optional - sage.graphs {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], + 1: [0 0 0] + [0 0 0] + [0 0 0]} """ #***************************************************************************** @@ -64,18 +64,18 @@ def is_ChainComplexMorphism(x): EXAMPLES:: sage: from sage.homology.chain_complex_morphism import is_ChainComplexMorphism - sage: S = simplicial_complexes.Sphere(14) - sage: H = Hom(S,S) - sage: i = H.identity() # long time (8s on sage.math, 2011) - sage: S = simplicial_complexes.Sphere(6) - sage: H = Hom(S,S) - sage: i = H.identity() - sage: x = i.associated_chain_complex_morphism() - sage: x # indirect doctest + sage: S = simplicial_complexes.Sphere(14) # optional - sage.graphs + sage: H = Hom(S,S) # optional - sage.graphs + sage: i = H.identity() # long time (8s on sage.math, 2011) # optional - sage.graphs + sage: S = simplicial_complexes.Sphere(6) # optional - sage.graphs + sage: H = Hom(S,S) # optional - sage.graphs + sage: i = H.identity() # optional - sage.graphs + sage: x = i.associated_chain_complex_morphism() # optional - sage.graphs + sage: x # indirect doctest # optional - sage.graphs Chain complex morphism: From: Chain complex with at most 7 nonzero terms over Integer Ring To: Chain complex with at most 7 nonzero terms over Integer Ring - sage: is_ChainComplexMorphism(x) + sage: is_ChainComplexMorphism(x) # optional - sage.graphs True """ return isinstance(x, ChainComplexMorphism) @@ -91,32 +91,34 @@ def __init__(self, matrices, C, D, check=True): EXAMPLES:: - sage: S = simplicial_complexes.Sphere(1) - sage: S + sage: S = simplicial_complexes.Sphere(1); S # optional - sage.graphs Minimal triangulation of the 1-sphere - sage: C = S.chain_complex() - sage: C.differential() - {0: [], 1: [-1 -1 0] - [ 1 0 -1] - [ 0 1 1], 2: []} + sage: C = S.chain_complex() # optional - sage.graphs + sage: C.differential() # optional - sage.graphs + {0: [], + 1: [-1 -1 0] + [ 1 0 -1] + [ 0 1 1], + 2: []} sage: f = {0:zero_matrix(ZZ,3,3),1:zero_matrix(ZZ,3,3)} - sage: G = Hom(C,C) - sage: x = G(f) - sage: x - Chain complex endomorphism of Chain complex with at most 2 nonzero terms over Integer Ring - sage: x._matrix_dictionary + sage: G = Hom(C,C) # optional - sage.graphs + sage: x = G(f); x # optional - sage.graphs + Chain complex endomorphism of + Chain complex with at most 2 nonzero terms over Integer Ring + sage: x._matrix_dictionary # optional - sage.graphs {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], + 1: [0 0 0] + [0 0 0] + [0 0 0]} Check that the bug in :trac:`13220` has been fixed:: - sage: X = simplicial_complexes.Simplex(1) - sage: Y = simplicial_complexes.Simplex(0) - sage: g = Hom(X,Y)({0:0, 1:0}) - sage: g.associated_chain_complex_morphism() + sage: X = simplicial_complexes.Simplex(1) # optional - sage.graphs + sage: Y = simplicial_complexes.Simplex(0) # optional - sage.graphs + sage: g = Hom(X,Y)({0: 0, 1: 0}) # optional - sage.graphs + sage: g.associated_chain_complex_morphism() # optional - sage.graphs Chain complex morphism: From: Chain complex with at most 2 nonzero terms over Integer Ring To: Chain complex with at most 1 nonzero terms over Integer Ring @@ -189,7 +191,7 @@ def __init__(self, matrices, C, D, check=True): def in_degree(self, n): """ - The matrix representing this morphism in degree n + The matrix representing this morphism in degree `n`. INPUT: @@ -264,24 +266,24 @@ def dual(self): EXAMPLES:: - sage: X = simplicial_complexes.Simplex(1) - sage: Y = simplicial_complexes.Simplex(0) - sage: g = Hom(X,Y)({0:0, 1:0}) - sage: f = g.associated_chain_complex_morphism() - sage: f.in_degree(0) + sage: X = simplicial_complexes.Simplex(1) # optional - sage.graphs + sage: Y = simplicial_complexes.Simplex(0) # optional - sage.graphs + sage: g = Hom(X,Y)({0:0, 1:0}) # optional - sage.graphs + sage: f = g.associated_chain_complex_morphism() # optional - sage.graphs + sage: f.in_degree(0) # optional - sage.graphs [1 1] - sage: f.dual() + sage: f.dual() # optional - sage.graphs Chain complex morphism: From: Chain complex with at most 1 nonzero terms over Integer Ring - To: Chain complex with at most 2 nonzero terms over Integer Ring - sage: f.dual().in_degree(0) + To: Chain complex with at most 2 nonzero terms over Integer Ring + sage: f.dual().in_degree(0) # optional - sage.graphs [1] [1] - sage: ascii_art(f.domain()) + sage: ascii_art(f.domain()) # optional - sage.graphs [-1] [ 1] 0 <-- C_0 <----- C_1 <-- 0 - sage: ascii_art(f.dual().codomain()) + sage: ascii_art(f.dual().codomain()) # optional - sage.graphs [-1 1] 0 <-- C_1 <-------- C_0 <-- 0 """ @@ -295,26 +297,26 @@ def __neg__(self): EXAMPLES:: - sage: S = simplicial_complexes.Sphere(2) - sage: H = Hom(S,S) - sage: i = H.identity() - sage: x = i.associated_chain_complex_morphism() - sage: w = -x - sage: w._matrix_dictionary + sage: S = simplicial_complexes.Sphere(2) # optional - sage.graphs + sage: H = Hom(S,S) # optional - sage.graphs + sage: i = H.identity() # optional - sage.graphs + sage: x = i.associated_chain_complex_morphism() # optional - sage.graphs + sage: w = -x # optional - sage.graphs + sage: w._matrix_dictionary # optional - sage.graphs {0: [-1 0 0 0] - [ 0 -1 0 0] - [ 0 0 -1 0] - [ 0 0 0 -1], + [ 0 -1 0 0] + [ 0 0 -1 0] + [ 0 0 0 -1], 1: [-1 0 0 0 0 0] - [ 0 -1 0 0 0 0] - [ 0 0 -1 0 0 0] - [ 0 0 0 -1 0 0] - [ 0 0 0 0 -1 0] - [ 0 0 0 0 0 -1], + [ 0 -1 0 0 0 0] + [ 0 0 -1 0 0 0] + [ 0 0 0 -1 0 0] + [ 0 0 0 0 -1 0] + [ 0 0 0 0 0 -1], 2: [-1 0 0 0] - [ 0 -1 0 0] - [ 0 0 -1 0] - [ 0 0 0 -1]} + [ 0 -1 0 0] + [ 0 0 -1 0] + [ 0 0 0 -1]} """ f = dict() @@ -328,26 +330,26 @@ def __add__(self,x): EXAMPLES:: - sage: S = simplicial_complexes.Sphere(2) - sage: H = Hom(S,S) - sage: i = H.identity() - sage: x = i.associated_chain_complex_morphism() - sage: z = x+x - sage: z._matrix_dictionary + sage: S = simplicial_complexes.Sphere(2) # optional - sage.graphs + sage: H = Hom(S,S) # optional - sage.graphs + sage: i = H.identity() # optional - sage.graphs + sage: x = i.associated_chain_complex_morphism() # optional - sage.graphs + sage: z = x+x # optional - sage.graphs + sage: z._matrix_dictionary # optional - sage.graphs {0: [2 0 0 0] - [0 2 0 0] - [0 0 2 0] - [0 0 0 2], + [0 2 0 0] + [0 0 2 0] + [0 0 0 2], 1: [2 0 0 0 0 0] - [0 2 0 0 0 0] - [0 0 2 0 0 0] - [0 0 0 2 0 0] - [0 0 0 0 2 0] - [0 0 0 0 0 2], + [0 2 0 0 0 0] + [0 0 2 0 0 0] + [0 0 0 2 0 0] + [0 0 0 0 2 0] + [0 0 0 0 0 2], 2: [2 0 0 0] - [0 2 0 0] - [0 0 2 0] - [0 0 0 2]} + [0 2 0 0] + [0 0 2 0] + [0 0 0 2]} """ if not isinstance(x, ChainComplexMorphism) or self.codomain() != x.codomain() or self.domain() != x.domain() or self._matrix_dictionary.keys() != x._matrix_dictionary.keys(): raise TypeError("unsupported operation") @@ -363,42 +365,42 @@ def __mul__(self, x): EXAMPLES:: - sage: S = simplicial_complexes.Sphere(2) - sage: H = Hom(S,S) - sage: i = H.identity() - sage: x = i.associated_chain_complex_morphism() - sage: y = x*2 - sage: y._matrix_dictionary + sage: S = simplicial_complexes.Sphere(2) # optional - sage.graphs + sage: H = Hom(S,S) # optional - sage.graphs + sage: i = H.identity() # optional - sage.graphs + sage: x = i.associated_chain_complex_morphism() # optional - sage.graphs + sage: y = x*2 # optional - sage.graphs + sage: y._matrix_dictionary # optional - sage.graphs {0: [2 0 0 0] - [0 2 0 0] - [0 0 2 0] - [0 0 0 2], + [0 2 0 0] + [0 0 2 0] + [0 0 0 2], 1: [2 0 0 0 0 0] - [0 2 0 0 0 0] - [0 0 2 0 0 0] - [0 0 0 2 0 0] - [0 0 0 0 2 0] - [0 0 0 0 0 2], + [0 2 0 0 0 0] + [0 0 2 0 0 0] + [0 0 0 2 0 0] + [0 0 0 0 2 0] + [0 0 0 0 0 2], 2: [2 0 0 0] - [0 2 0 0] - [0 0 2 0] - [0 0 0 2]} - sage: z = y*y - sage: z._matrix_dictionary + [0 2 0 0] + [0 0 2 0] + [0 0 0 2]} + sage: z = y*y # optional - sage.graphs + sage: z._matrix_dictionary # optional - sage.graphs {0: [4 0 0 0] - [0 4 0 0] - [0 0 4 0] - [0 0 0 4], + [0 4 0 0] + [0 0 4 0] + [0 0 0 4], 1: [4 0 0 0 0 0] - [0 4 0 0 0 0] - [0 0 4 0 0 0] - [0 0 0 4 0 0] - [0 0 0 0 4 0] - [0 0 0 0 0 4], + [0 4 0 0 0 0] + [0 0 4 0 0 0] + [0 0 0 4 0 0] + [0 0 0 0 4 0] + [0 0 0 0 0 4], 2: [4 0 0 0] - [0 4 0 0] - [0 0 4 0] - [0 0 0 4]} + [0 4 0 0] + [0 0 4 0] + [0 0 0 4]} TESTS: @@ -449,13 +451,13 @@ def __rmul__(self,x): EXAMPLES:: - sage: S = simplicial_complexes.Sphere(2) - sage: H = Hom(S,S) - sage: i = H.identity() - sage: x = i.associated_chain_complex_morphism() - sage: 2*x == x*2 + sage: S = simplicial_complexes.Sphere(2) # optional - sage.graphs + sage: H = Hom(S,S) # optional - sage.graphs + sage: i = H.identity() # optional - sage.graphs + sage: x = i.associated_chain_complex_morphism() # optional - sage.graphs + sage: 2*x == x*2 # optional - sage.graphs True - sage: 3*x == x*2 + sage: 3*x == x*2 # optional - sage.graphs False """ try: @@ -473,12 +475,12 @@ def __sub__(self,x): EXAMPLES:: - sage: S = simplicial_complexes.Sphere(2) - sage: H = Hom(S,S) - sage: i = H.identity() - sage: x = i.associated_chain_complex_morphism() - sage: y = x-x - sage: y._matrix_dictionary + sage: S = simplicial_complexes.Sphere(2) # optional - sage.graphs + sage: H = Hom(S,S) # optional - sage.graphs + sage: i = H.identity() # optional - sage.graphs + sage: x = i.associated_chain_complex_morphism() # optional - sage.graphs + sage: y = x - x # optional - sage.graphs + sage: y._matrix_dictionary # optional - sage.graphs {0: [0 0 0 0] [0 0 0 0] [0 0 0 0] @@ -502,19 +504,18 @@ def __eq__(self,x): EXAMPLES:: - sage: S = SimplicialComplex(is_mutable=False) - sage: H = Hom(S,S) - sage: i = H.identity() - sage: x = i.associated_chain_complex_morphism() - sage: x + sage: S = SimplicialComplex(is_mutable=False) # optional - sage.graphs + sage: H = Hom(S,S) # optional - sage.graphs + sage: i = H.identity() # optional - sage.graphs + sage: x = i.associated_chain_complex_morphism(); x # optional - sage.graphs Chain complex morphism: From: Trivial chain complex over Integer Ring To: Trivial chain complex over Integer Ring - sage: f = x._matrix_dictionary - sage: C = S.chain_complex() - sage: G = Hom(C,C) - sage: y = G(f) - sage: x == y + sage: f = x._matrix_dictionary # optional - sage.graphs + sage: C = S.chain_complex() # optional - sage.graphs + sage: G = Hom(C,C) # optional - sage.graphs + sage: y = G(f) # optional - sage.graphs + sage: x == y # optional - sage.graphs True """ return isinstance(x,ChainComplexMorphism) \ @@ -524,36 +525,36 @@ def __eq__(self,x): def is_identity(self): """ - True if this is the identity map. + Return ``True`` if this is the identity map. EXAMPLES:: - sage: S = SimplicialComplex(is_mutable=False) - sage: H = Hom(S,S) - sage: i = H.identity() - sage: x = i.associated_chain_complex_morphism() - sage: x.is_identity() + sage: S = SimplicialComplex(is_mutable=False) # optional - sage.graphs + sage: H = Hom(S,S) # optional - sage.graphs + sage: i = H.identity() # optional - sage.graphs + sage: x = i.associated_chain_complex_morphism() # optional - sage.graphs + sage: x.is_identity() # optional - sage.graphs True """ return self.to_matrix().is_one() def is_surjective(self): """ - True if this map is surjective. + Return ``True`` if this map is surjective. EXAMPLES:: - sage: S1 = simplicial_complexes.Sphere(1) - sage: H = Hom(S1, S1) - sage: flip = H({0:0, 1:2, 2:1}) - sage: flip.associated_chain_complex_morphism().is_surjective() + sage: S1 = simplicial_complexes.Sphere(1) # optional - sage.graphs + sage: H = Hom(S1, S1) # optional - sage.graphs + sage: flip = H({0:0, 1:2, 2:1}) # optional - sage.graphs + sage: flip.associated_chain_complex_morphism().is_surjective() # optional - sage.graphs True - sage: pt = simplicial_complexes.Simplex(0) - sage: inclusion = Hom(pt, S1)({0:2}) - sage: inclusion.associated_chain_complex_morphism().is_surjective() + sage: pt = simplicial_complexes.Simplex(0) # optional - sage.graphs + sage: inclusion = Hom(pt, S1)({0:2}) # optional - sage.graphs + sage: inclusion.associated_chain_complex_morphism().is_surjective() # optional - sage.graphs False - sage: inclusion.associated_chain_complex_morphism(cochain=True).is_surjective() + sage: inclusion.associated_chain_complex_morphism(cochain=True).is_surjective() # optional - sage.graphs True """ m = self.to_matrix() @@ -561,21 +562,21 @@ def is_surjective(self): def is_injective(self): """ - True if this map is injective. + Return ``True`` if this map is injective. EXAMPLES:: - sage: S1 = simplicial_complexes.Sphere(1) - sage: H = Hom(S1, S1) - sage: flip = H({0:0, 1:2, 2:1}) - sage: flip.associated_chain_complex_morphism().is_injective() + sage: S1 = simplicial_complexes.Sphere(1) # optional - sage.graphs + sage: H = Hom(S1, S1) # optional - sage.graphs + sage: flip = H({0:0, 1:2, 2:1}) # optional - sage.graphs + sage: flip.associated_chain_complex_morphism().is_injective() # optional - sage.graphs True - sage: pt = simplicial_complexes.Simplex(0) - sage: inclusion = Hom(pt, S1)({0:2}) - sage: inclusion.associated_chain_complex_morphism().is_injective() + sage: pt = simplicial_complexes.Simplex(0) # optional - sage.graphs + sage: inclusion = Hom(pt, S1)({0:2}) # optional - sage.graphs + sage: inclusion.associated_chain_complex_morphism().is_injective() # optional - sage.graphs True - sage: inclusion.associated_chain_complex_morphism(cochain=True).is_injective() + sage: inclusion.associated_chain_complex_morphism(cochain=True).is_injective() # optional - sage.graphs False """ return self.to_matrix().right_nullity() == 0 diff --git a/src/sage/homology/chain_homotopy.py b/src/sage/homology/chain_homotopy.py index afeaee2430c..326f512b305 100644 --- a/src/sage/homology/chain_homotopy.py +++ b/src/sage/homology/chain_homotopy.py @@ -121,7 +121,8 @@ def __init__(self, matrices, f, g=None): `f - (H \partial + \partial H)`. :: sage: from sage.homology.chain_homotopy import ChainHomotopy - sage: C = ChainComplex({1: matrix(ZZ, 1, 2, (1,0)), 2: matrix(ZZ, 2, 1, (0, 2))}, degree_of_differential=-1) + sage: C = ChainComplex({1: matrix(ZZ, 1, 2, (1,0)), 2: matrix(ZZ, 2, 1, (0, 2))}, + ....: degree_of_differential=-1) sage: D = ChainComplex({2: matrix(ZZ, 1, 1, (6,))}, degree_of_differential=-1) sage: f_d = {1: matrix(ZZ, 1, 2, (0,3)), 2: identity_matrix(ZZ, 1)} sage: f = Hom(C,D)(f_d) @@ -212,15 +213,23 @@ def is_algebraic_gradient_vector_field(self): `\ZZ` in degree 0. Two chain maps `C \to C` will be chain homotopic as long as they agree in degree 0. :: - sage: f = Hom(C,C)({0: identity_matrix(ZZ, 1), 1: matrix(ZZ, 1, 1, [3]), 2: matrix(ZZ, 1, 1, [3])}) - sage: g = Hom(C,C)({0: identity_matrix(ZZ, 1), 1: matrix(ZZ, 1, 1, [2]), 2: matrix(ZZ, 1, 1, [2])}) - sage: H = ChainHomotopy({0: zero_matrix(ZZ, 0, 1), 1: zero_matrix(ZZ, 1), 2: identity_matrix(ZZ, 1)}, f, g) + sage: f = Hom(C,C)({0: identity_matrix(ZZ, 1), + ....: 1: matrix(ZZ, 1, 1, [3]), + ....: 2: matrix(ZZ, 1, 1, [3])}) + sage: g = Hom(C,C)({0: identity_matrix(ZZ, 1), + ....: 1: matrix(ZZ, 1, 1, [2]), + ....: 2: matrix(ZZ, 1, 1, [2])}) + sage: H = ChainHomotopy({0: zero_matrix(ZZ, 0, 1), + ....: 1: zero_matrix(ZZ, 1), + ....: 2: identity_matrix(ZZ, 1)}, f, g) sage: H.is_algebraic_gradient_vector_field() True A chain homotopy which is not an algebraic gradient vector field:: - sage: H = ChainHomotopy({0: zero_matrix(ZZ, 0, 1), 1: identity_matrix(ZZ, 1), 2: identity_matrix(ZZ, 1)}, f, g) + sage: H = ChainHomotopy({0: zero_matrix(ZZ, 0, 1), + ....: 1: identity_matrix(ZZ, 1), + ....: 2: identity_matrix(ZZ, 1)}, f, g) sage: H.is_algebraic_gradient_vector_field() False """ @@ -251,9 +260,15 @@ def is_homology_gradient_vector_field(self): sage: from sage.homology.chain_homotopy import ChainHomotopy sage: C = ChainComplex({0: zero_matrix(ZZ, 1), 1: identity_matrix(ZZ, 1)}) - sage: f = Hom(C,C)({0: identity_matrix(ZZ, 1), 1: matrix(ZZ, 1, 1, [3]), 2: matrix(ZZ, 1, 1, [3])}) - sage: g = Hom(C,C)({0: identity_matrix(ZZ, 1), 1: matrix(ZZ, 1, 1, [2]), 2: matrix(ZZ, 1, 1, [2])}) - sage: H = ChainHomotopy({0: zero_matrix(ZZ, 0, 1), 1: zero_matrix(ZZ, 1), 2: identity_matrix(ZZ, 1)}, f, g) + sage: f = Hom(C,C)({0: identity_matrix(ZZ, 1), + ....: 1: matrix(ZZ, 1, 1, [3]), + ....: 2: matrix(ZZ, 1, 1, [3])}) + sage: g = Hom(C,C)({0: identity_matrix(ZZ, 1), + ....: 1: matrix(ZZ, 1, 1, [2]), + ....: 2: matrix(ZZ, 1, 1, [2])}) + sage: H = ChainHomotopy({0: zero_matrix(ZZ, 0, 1), + ....: 1: zero_matrix(ZZ, 1), + ....: 2: identity_matrix(ZZ, 1)}, f, g) sage: H.is_homology_gradient_vector_field() True """ @@ -281,8 +296,8 @@ def in_degree(self, n): EXAMPLES:: sage: from sage.homology.chain_homotopy import ChainHomotopy - sage: C = ChainComplex({1: matrix(ZZ, 0, 2)}) # one nonzero term in degree 1 - sage: D = ChainComplex({0: matrix(ZZ, 0, 1)}) # one nonzero term in degree 0 + sage: C = ChainComplex({1: matrix(ZZ, 0, 2)}) # one nonzero term in degree 1 + sage: D = ChainComplex({0: matrix(ZZ, 0, 1)}) # one nonzero term in degree 0 sage: f = Hom(C, D)({}) sage: H = ChainHomotopy({1: matrix(ZZ, 1, 2, (3,1))}, f, f) sage: H.in_degree(1) @@ -316,8 +331,8 @@ def dual(self): EXAMPLES:: sage: from sage.homology.chain_homotopy import ChainHomotopy - sage: C = ChainComplex({1: matrix(ZZ, 0, 2)}) # one nonzero term in degree 1 - sage: D = ChainComplex({0: matrix(ZZ, 0, 1)}) # one nonzero term in degree 0 + sage: C = ChainComplex({1: matrix(ZZ, 0, 2)}) # one nonzero term in degree 1 + sage: D = ChainComplex({0: matrix(ZZ, 0, 1)}) # one nonzero term in degree 0 sage: f = Hom(C, D)({}) sage: H = ChainHomotopy({1: matrix(ZZ, 1, 2, (3,1))}, f, f) sage: H.in_degree(1) @@ -336,8 +351,8 @@ def __hash__(self): TESTS:: sage: from sage.homology.chain_homotopy import ChainHomotopy - sage: C = ChainComplex({1: matrix(ZZ, 0, 2)}) # one nonzero term in degree 1 - sage: D = ChainComplex({0: matrix(ZZ, 0, 1)}) # one nonzero term in degree 0 + sage: C = ChainComplex({1: matrix(ZZ, 0, 2)}) # one nonzero term in degree 1 + sage: D = ChainComplex({0: matrix(ZZ, 0, 1)}) # one nonzero term in degree 0 sage: f = Hom(C, D)({}) sage: H = ChainHomotopy({1: matrix(ZZ, 1, 2, (3,1))}, f, f) sage: hash(H) # random @@ -347,7 +362,7 @@ def __hash__(self): def _repr_(self): """ - String representation + String representation. EXAMPLES:: @@ -403,7 +418,9 @@ class ChainContraction(ChainHomotopy): sage: pi = Hom(C,D)({0: identity_matrix(ZZ, 1)}) sage: iota = Hom(D,C)({0: identity_matrix(ZZ, 1)}) - sage: H = ChainContraction({0: zero_matrix(ZZ, 0, 1), 1: zero_matrix(ZZ, 1), 2: identity_matrix(ZZ, 1)}, pi, iota) + sage: H = ChainContraction({0: zero_matrix(ZZ, 0, 1), + ....: 1: zero_matrix(ZZ, 1), + ....: 2: identity_matrix(ZZ, 1)}, pi, iota) """ def __init__(self, matrices, pi, iota): r""" @@ -488,20 +505,20 @@ def pi(self): EXAMPLES:: - sage: S2 = simplicial_complexes.Sphere(2) - sage: phi, M = S2.algebraic_topological_model(QQ) - sage: phi.pi() + sage: S2 = simplicial_complexes.Sphere(2) # optional - sage.graphs + sage: phi, M = S2.algebraic_topological_model(QQ) # optional - sage.graphs + sage: phi.pi() # optional - sage.graphs Chain complex morphism: From: Chain complex with at most 3 nonzero terms over Rational Field To: Chain complex with at most 3 nonzero terms over Rational Field - sage: phi.pi().in_degree(0) # Every vertex represents a homology class. + sage: phi.pi().in_degree(0) # Every vertex represents a homology class. # optional - sage.graphs [1 1 1 1] - sage: phi.pi().in_degree(1) # No homology in degree 1. + sage: phi.pi().in_degree(1) # No homology in degree 1. # optional - sage.graphs [] The degree 2 homology generator is detected on a single simplex:: - sage: phi.pi().in_degree(2) + sage: phi.pi().in_degree(2) # optional - sage.graphs [0 0 0 1] """ return self._pi @@ -512,16 +529,16 @@ def iota(self): EXAMPLES:: - sage: S2 = simplicial_complexes.Sphere(2) - sage: phi, M = S2.algebraic_topological_model(QQ) - sage: phi.iota() + sage: S2 = simplicial_complexes.Sphere(2) # optional - sage.graphs + sage: phi, M = S2.algebraic_topological_model(QQ) # optional - sage.graphs + sage: phi.iota() # optional - sage.graphs Chain complex morphism: From: Chain complex with at most 3 nonzero terms over Rational Field To: Chain complex with at most 3 nonzero terms over Rational Field Lifting the degree zero homology class gives a single vertex:: - sage: phi.iota().in_degree(0) + sage: phi.iota().in_degree(0) # optional - sage.graphs [0] [0] [0] @@ -530,7 +547,7 @@ def iota(self): Lifting the degree two homology class gives the signed sum of all of the 2-simplices:: - sage: phi.iota().in_degree(2) + sage: phi.iota().in_degree(2) # optional - sage.graphs [-1] [ 1] [-1] @@ -546,9 +563,9 @@ def dual(self): EXAMPLES:: - sage: S2 = simplicial_complexes.Sphere(2) - sage: phi, M = S2.algebraic_topological_model(QQ) - sage: phi.iota() + sage: S2 = simplicial_complexes.Sphere(2) # optional - sage.graphs + sage: phi, M = S2.algebraic_topological_model(QQ) # optional - sage.graphs + sage: phi.iota() # optional - sage.graphs Chain complex morphism: From: Chain complex with at most 3 nonzero terms over Rational Field To: Chain complex with at most 3 nonzero terms over Rational Field @@ -557,22 +574,22 @@ def dual(self): but the degree zero cohomology class needs to be detected on every vertex, and vice versa for degree 2:: - sage: phi.iota().in_degree(0) + sage: phi.iota().in_degree(0) # optional - sage.graphs [0] [0] [0] [1] - sage: phi.dual().iota().in_degree(0) + sage: phi.dual().iota().in_degree(0) # optional - sage.graphs [1] [1] [1] [1] - sage: phi.iota().in_degree(2) + sage: phi.iota().in_degree(2) # optional - sage.graphs [-1] [ 1] [-1] [ 1] - sage: phi.dual().iota().in_degree(2) + sage: phi.dual().iota().in_degree(2) # optional - sage.graphs [0] [0] [0] diff --git a/src/sage/homology/chains.py b/src/sage/homology/chains.py index 7bd375f35fd..86e2eaec897 100644 --- a/src/sage/homology/chains.py +++ b/src/sage/homology/chains.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.graphs (because all doctests use the catalogs simplicial_complexes, cubical_complexes) r""" Chains and cochains diff --git a/src/sage/homology/free_resolution.py b/src/sage/homology/free_resolution.py index 424086d283e..8bda4817de4 100644 --- a/src/sage/homology/free_resolution.py +++ b/src/sage/homology/free_resolution.py @@ -17,33 +17,29 @@ sage: from sage.homology.free_resolution import FreeResolution sage: S. = PolynomialRing(QQ) sage: m = matrix(S, 1, [z^2 - y*w, y*z - x*w, y^2 - x*z]).transpose() - sage: r = FreeResolution(m, name='S') - sage: r + sage: r = FreeResolution(m, name='S'); r # optional - sage.libs.singular S^1 <-- S^3 <-- S^2 <-- 0 - sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.free_resolution() - sage: r + sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) # optional - sage.libs.singular + sage: r = I.free_resolution(); r # optional - sage.libs.singular S^1 <-- S^3 <-- S^2 <-- 0 :: sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: r + sage: r = I.graded_free_resolution(); r # optional - sage.libs.singular S(0) <-- S(-2)⊕S(-2)⊕S(-2) <-- S(-3)⊕S(-3) <-- 0 An example of a minimal free resolution from [CLO2005]_:: sage: R. = QQ[] sage: I = R.ideal([y*z - x*w, y^3 - x^2*z, x*z^2 - y^2*w, z^3 - y*w^2]) - sage: r = I.free_resolution() - sage: r + sage: r = I.free_resolution(); r # optional - sage.libs.singular S^1 <-- S^4 <-- S^4 <-- S^1 <-- 0 - sage: len(r) + sage: len(r) # optional - sage.libs.singular 3 - sage: r.matrix(2) + sage: r.matrix(2) # optional - sage.libs.singular [-z^2 -x*z y*w -y^2] [ y 0 -x 0] [ -w y z x] @@ -66,8 +62,6 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.libs.singular.singular import si2sa_resolution -from sage.libs.singular.function import singular_function from sage.misc.lazy_attribute import lazy_attribute from sage.misc.abstract_method import abstract_method from sage.misc.classcall_metaclass import ClasscallMetaclass @@ -107,14 +101,14 @@ def __classcall_private__(cls, module, *args, graded=False, degrees=None, shifts sage: from sage.homology.free_resolution import FreeResolution sage: S. = PolynomialRing(QQ) - sage: m = matrix(S, 1, [z^2 - y*w, y*z - x*w, y^2 - x*z]).transpose() - sage: r = FreeResolution(m, name='S') - sage: type(r) + sage: m = matrix(S, 1, [z^2 - y*w, y*z - x*w, y^2 - x*z]).transpose() # optional - sage.libs.singular + sage: r = FreeResolution(m, name='S') # optional - sage.libs.singular + sage: type(r) # optional - sage.libs.singular - sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = FreeResolution(I) - sage: type(r) + sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) # optional - sage.libs.singular + sage: r = FreeResolution(I) # optional - sage.libs.singular + sage: type(r) # optional - sage.libs.singular sage: R. = QQ[] @@ -122,8 +116,8 @@ def __classcall_private__(cls, module, *args, graded=False, degrees=None, shifts sage: v = M([x^2, 2*x^2, 3*x^2]) sage: w = M([0, x, 2*x]) sage: S = M.submodule([v, w]) - sage: r = FreeResolution(S) - sage: type(r) + sage: r = FreeResolution(S) # optional - sage.libs.singular + sage: type(r) # optional - sage.libs.singular sage: I = R.ideal([x^4 + 3*x^2 + 2]) @@ -134,10 +128,10 @@ def __classcall_private__(cls, module, *args, graded=False, degrees=None, shifts sage: R. = QQ[] sage: I = R.ideal([x^2, y^3]) sage: Q = R.quo(I) - sage: Q.is_integral_domain() + sage: Q.is_integral_domain() # optional - sage.libs.singular False - sage: xb, yb = Q.gens() - sage: FreeResolution(Q.ideal([xb])) # has torsion + sage: xb, yb = Q.gens() # optional - sage.libs.singular + sage: FreeResolution(Q.ideal([xb])) # has torsion # optional - sage.libs.singular Traceback (most recent call last): ... NotImplementedError: the ring must be a polynomial ring using Singular @@ -199,8 +193,8 @@ def __init__(self, module, name='S', **kwds): sage: from sage.homology.free_resolution import FreeResolution sage: S. = PolynomialRing(QQ) sage: m1 = matrix(S, 1, [z^2 - y*w, y*z - x*w, y^2 - x*z]) - sage: r = FreeResolution(m1, name='S') - sage: TestSuite(r).run(skip=['_test_pickling']) + sage: r = FreeResolution(m1, name='S') # optional - sage.libs.singular + sage: TestSuite(r).run(skip=['_test_pickling']) # optional - sage.libs.singular """ if isinstance(module, Ideal_generic): S = module.ring() @@ -220,8 +214,8 @@ def _repr_(self): sage: from sage.homology.free_resolution import FreeResolution sage: S. = PolynomialRing(QQ) sage: m1 = matrix(S, 1, [z^2 - y*w, y*z - x*w, y^2 - x*z]) - sage: r = FreeResolution(m1, name='S') - sage: print(FreeResolution._repr_(r)) + sage: r = FreeResolution(m1, name='S') # optional - sage.libs.singular + sage: print(FreeResolution._repr_(r)) # optional - sage.libs.singular Free resolution of the row space of the matrix: [z^2 - y*w y*z - x*w y^2 - x*z] """ @@ -242,10 +236,10 @@ def _repr_module(self, i): sage: from sage.homology.free_resolution import FreeResolution sage: S. = PolynomialRing(QQ) sage: m = matrix(S, 1, [y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = FreeResolution(m.transpose(), name='S') - sage: r._repr_module(2) + sage: r = FreeResolution(m.transpose(), name='S') # optional - sage.libs.singular + sage: r._repr_module(2) # optional - sage.libs.singular 'S^2' - sage: r # indirect doctest + sage: r # indirect doctest # optional - sage.libs.singular S^1 <-- S^3 <-- S^2 <-- 0 """ if i == 0: @@ -276,8 +270,8 @@ def differential(self, i): sage: from sage.homology.free_resolution import FreeResolution sage: S. = PolynomialRing(QQ) sage: m1 = matrix(S, 1, [z^2 - y*w, y*z - x*w, y^2 - x*z]) - sage: r = FreeResolution(m1, name='S') - sage: FreeResolution.differiental(r, 1) + sage: r = FreeResolution(m1, name='S') # optional - sage.libs.singular + sage: FreeResolution.differiental(r, 1) # optional - sage.libs.singular Traceback (most recent call last): ... AttributeError: type object 'FreeResolution' has no attribute 'differiental' @@ -294,16 +288,17 @@ def target(self): sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: r + sage: r = I.graded_free_resolution() # optional - sage.libs.singular + sage: r # optional - sage.libs.singular S(0) <-- S(-2)⊕S(-2)⊕S(-2) <-- S(-3)⊕S(-3) <-- 0 - sage: r.target() - Quotient module by Submodule of Ambient free module of rank 1 over the integral domain - Multivariate Polynomial Ring in x, y, z, w over Rational Field - Generated by the rows of the matrix: - [-z^2 + y*w] - [ y*z - x*w] - [-y^2 + x*z] + sage: r.target() # optional - sage.libs.singular + Quotient module by + Submodule of Ambient free module of rank 1 over the integral domain + Multivariate Polynomial Ring in x, y, z, w over Rational Field + Generated by the rows of the matrix: + [-z^2 + y*w] + [ y*z - x*w] + [-y^2 + x*z] """ return self.differential(0).codomain() @@ -333,17 +328,18 @@ class FiniteFreeResolution(FreeResolution): sage: from sage.homology.free_resolution import FreeResolution sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = FreeResolution(I) - sage: r.differential(0) + sage: r = FreeResolution(I) # optional - sage.libs.singular + sage: r.differential(0) # optional - sage.libs.singular Coercion map: From: Ambient free module of rank 1 over the integral domain - Multivariate Polynomial Ring in x, y, z, w over Rational Field - To: Quotient module by Submodule of Ambient free module of rank 1 - over the integral domain Multivariate Polynomial Ring in x, y, z, w over Rational Field - Generated by the rows of the matrix: - [-z^2 + y*w] - [ y*z - x*w] - [-y^2 + x*z] + Multivariate Polynomial Ring in x, y, z, w over Rational Field + To: Quotient module by + Submodule of Ambient free module of rank 1 over the integral domain + Multivariate Polynomial Ring in x, y, z, w over Rational Field + Generated by the rows of the matrix: + [-z^2 + y*w] + [ y*z - x*w] + [-y^2 + x*z] """ @lazy_attribute def _length(self): @@ -355,8 +351,8 @@ def _length(self): sage: from sage.homology.free_resolution import FreeResolution sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = FreeResolution(I) - sage: r._length + sage: r = FreeResolution(I) # optional - sage.libs.singular + sage: r._length # optional - sage.libs.singular 2 """ return len(self._maps) @@ -373,8 +369,7 @@ def _repr_(self): sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: r + sage: r = I.graded_free_resolution(); r # optional - sage.libs.singular S(0) <-- S(-2)⊕S(-2)⊕S(-2) <-- S(-3)⊕S(-3) <-- 0 """ s = self._repr_module(0) @@ -393,10 +388,9 @@ def __len__(self): sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: r + sage: r = I.graded_free_resolution(); r # optional - sage.libs.singular S(0) <-- S(-2)⊕S(-2)⊕S(-2) <-- S(-3)⊕S(-3) <-- 0 - sage: len(r) + sage: len(r) # optional - sage.libs.singular 2 """ return len(self._maps) @@ -413,10 +407,9 @@ def __getitem__(self, i): sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: r + sage: r = I.graded_free_resolution(); r # optional - sage.libs.singular S(0) <-- S(-2)⊕S(-2)⊕S(-2) <-- S(-3)⊕S(-3) <-- 0 - sage: r.target() + sage: r.target() # optional - sage.libs.singular Quotient module by Submodule of Ambient free module of rank 1 over the integral domain Multivariate Polynomial Ring in x, y, z, w over Rational Field Generated by the rows of the matrix: @@ -446,42 +439,42 @@ def differential(self, i): sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: r + sage: r = I.graded_free_resolution() # optional - sage.libs.singular + sage: r # optional - sage.libs.singular S(0) <-- S(-2)⊕S(-2)⊕S(-2) <-- S(-3)⊕S(-3) <-- 0 - sage: r.differential(3) - Free module morphism defined by the matrix - [] - Domain: Ambient free module of rank 0 over the integral domain - Multivariate Polynomial Ring in x, y, z, w over Rational Field - Codomain: Ambient free module of rank 2 over the integral domain - Multivariate Polynomial Ring in x, y, z, w over Rational Field - sage: r.differential(2) + sage: r.differential(3) # optional - sage.libs.singular + Free module morphism defined by the matrix [] + Domain: Ambient free module of rank 0 over the integral domain + Multivariate Polynomial Ring in x, y, z, w over Rational Field + Codomain: Ambient free module of rank 2 over the integral domain + Multivariate Polynomial Ring in x, y, z, w over Rational Field + sage: r.differential(2) # optional - sage.libs.singular Free module morphism defined as left-multiplication by the matrix - [-y x] - [ z -y] - [-w z] - Domain: Ambient free module of rank 2 over the integral domain - Multivariate Polynomial Ring in x, y, z, w over Rational Field - Codomain: Ambient free module of rank 3 over the integral domain - Multivariate Polynomial Ring in x, y, z, w over Rational Field - sage: r.differential(1) + [-y x] + [ z -y] + [-w z] + Domain: Ambient free module of rank 2 over the integral domain + Multivariate Polynomial Ring in x, y, z, w over Rational Field + Codomain: Ambient free module of rank 3 over the integral domain + Multivariate Polynomial Ring in x, y, z, w over Rational Field + sage: r.differential(1) # optional - sage.libs.singular Free module morphism defined as left-multiplication by the matrix - [z^2 - y*w y*z - x*w y^2 - x*z] - Domain: Ambient free module of rank 3 over the integral domain - Multivariate Polynomial Ring in x, y, z, w over Rational Field - Codomain: Ambient free module of rank 1 over the integral domain - Multivariate Polynomial Ring in x, y, z, w over Rational Field - sage: r.differential(0) + [z^2 - y*w y*z - x*w y^2 - x*z] + Domain: Ambient free module of rank 3 over the integral domain + Multivariate Polynomial Ring in x, y, z, w over Rational Field + Codomain: Ambient free module of rank 1 over the integral domain + Multivariate Polynomial Ring in x, y, z, w over Rational Field + sage: r.differential(0) # optional - sage.libs.singular Coercion map: From: Ambient free module of rank 1 over the integral domain - Multivariate Polynomial Ring in x, y, z, w over Rational Field - To: Quotient module by Submodule of Ambient free module of rank 1 over the integral domain - Multivariate Polynomial Ring in x, y, z, w over Rational Field - Generated by the rows of the matrix: - [-z^2 + y*w] - [ y*z - x*w] - [-y^2 + x*z] + Multivariate Polynomial Ring in x, y, z, w over Rational Field + To: Quotient module by + Submodule of Ambient free module of rank 1 over the integral domain + Multivariate Polynomial Ring in x, y, z, w over Rational Field + Generated by the rows of the matrix: + [-z^2 + y*w] + [ y*z - x*w] + [-y^2 + x*z] """ if i < 0: raise IndexError('invalid index') @@ -516,16 +509,15 @@ def matrix(self, i): sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: r + sage: r = I.graded_free_resolution(); r # optional - sage.libs.singular S(0) <-- S(-2)⊕S(-2)⊕S(-2) <-- S(-3)⊕S(-3) <-- 0 - sage: r.matrix(3) + sage: r.matrix(3) # optional - sage.libs.singular [] - sage: r.matrix(2) + sage: r.matrix(2) # optional - sage.libs.singular [-y x] [ z -y] [-w z] - sage: r.matrix(1) + sage: r.matrix(1) # optional - sage.libs.singular [z^2 - y*w y*z - x*w y^2 - x*z] """ if i <= 0: @@ -545,8 +537,8 @@ def chain_complex(self): sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: unicode_art(r.chain_complex()) + sage: r = I.graded_free_resolution() # optional - sage.libs.singular + sage: unicode_art(r.chain_complex()) # optional - sage.libs.singular ⎛-y x⎞ ⎜ z -y⎟ (z^2 - y*w y*z - x*w y^2 - x*z) ⎝-w z⎠ @@ -568,13 +560,14 @@ def _initial_differential(self): sage: from sage.homology.free_resolution import FreeResolution sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = FreeResolution(I) - sage: r._initial_differential + sage: r = FreeResolution(I) # optional - sage.libs.singular + sage: r._initial_differential # optional - sage.libs.singular Coercion map: From: Ambient free module of rank 1 over the integral domain - Multivariate Polynomial Ring in x, y, z, w over Rational Field - To: Quotient module by Submodule of Ambient free module of rank 1 - over the integral domain Multivariate Polynomial Ring in x, y, z, w over Rational Field + Multivariate Polynomial Ring in x, y, z, w over Rational Field + To: Quotient module by + Submodule of Ambient free module of rank 1 over the integral domain + Multivariate Polynomial Ring in x, y, z, w over Rational Field Generated by the rows of the matrix: [-z^2 + y*w] [ y*z - x*w] @@ -607,19 +600,19 @@ def _m(self): sage: from sage.homology.free_resolution import FreeResolution sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = FreeResolution(I) - sage: r._m() + sage: r = FreeResolution(I) # optional - sage.libs.singular + sage: r._m() # optional - sage.libs.singular Ideal (-z^2 + y*w, y*z - x*w, -y^2 + x*z) of Multivariate Polynomial Ring in x, y, z, w over Rational Field - sage: m = matrix(S, 1, [z^2 - y*w, y*z - x*w, y^2 - x*z]).transpose() - sage: r = FreeResolution(m, name='S') - sage: r._m() + sage: m = matrix(S, 1, [z^2 - y*w, y*z - x*w, y^2 - x*z]).transpose() # optional - sage.libs.singular + sage: r = FreeResolution(m, name='S') # optional - sage.libs.singular + sage: r._m() # optional - sage.libs.singular [z^2 - y*w y*z - x*w y^2 - x*z] - sage: M = m.image() - sage: r = FreeResolution(M, name='S') - sage: r._m() + sage: M = m.image() # optional - sage.libs.singular + sage: r = FreeResolution(M, name='S') # optional - sage.libs.singular + sage: r._m() # optional - sage.libs.singular [z^2 - y*w y*z - x*w y^2 - x*z] """ if isinstance(self._module, Ideal_generic): @@ -646,17 +639,15 @@ class FiniteFreeResolution_free_module(FiniteFreeResolution): sage: M = R^3 sage: v = M([x^2, 2*x^2, 3*x^2]) sage: w = M([0, x, 2*x]) - sage: S = M.submodule([v, w]) - sage: S + sage: S = M.submodule([v, w]); S Free module of degree 3 and rank 2 over Univariate Polynomial Ring in x over Rational Field - Echelon basis matrix: - [ x^2 2*x^2 3*x^2] - [ 0 x 2*x] - sage: res = S.free_resolution() - sage: res + Echelon basis matrix: + [ x^2 2*x^2 3*x^2] + [ 0 x 2*x] + sage: res = S.free_resolution(); res # optional - sage.libs.singular S^3 <-- S^2 <-- 0 - sage: ascii_art(res.chain_complex()) + sage: ascii_art(res.chain_complex()) # optional - sage.libs.singular [ x^2 0] [2*x^2 x] [3*x^2 2*x] @@ -664,8 +655,7 @@ class FiniteFreeResolution_free_module(FiniteFreeResolution): sage: R. = PolynomialRing(QQ) sage: I = R.ideal([x^4 + 3*x^2 + 2]) - sage: res = I.free_resolution() - sage: res + sage: res = I.free_resolution(); res S^1 <-- S^1 <-- 0 """ @lazy_attribute @@ -680,15 +670,14 @@ def _maps(self): sage: v = M([x^2, 2*x^2, 3*x^2]) sage: w = M([0, x, 2*x]) sage: S = M.submodule([v, w]) - sage: res = S.free_resolution() - sage: res + sage: res = S.free_resolution(); res # optional - sage.libs.singular S^3 <-- S^2 <-- 0 - sage: ascii_art(res.chain_complex()) + sage: ascii_art(res.chain_complex()) # optional - sage.libs.singular [ x^2 0] [2*x^2 x] [3*x^2 2*x] 0 <-- C_0 <-------------- C_1 <-- 0 - sage: res._maps + sage: res._maps # optional - sage.libs.singular [ [ x^2 0] [2*x^2 x] @@ -705,8 +694,7 @@ def _maps(self): sage: M = matrix([[x^2, 2], ....: [3*x^2, 5], ....: [5*x^2, 4]]) - sage: res = FreeResolution(M.transpose()) - sage: res + sage: res = FreeResolution(M.transpose()); res S^3 <-- S^2 <-- 0 sage: res._m() [ 1 0] @@ -721,8 +709,7 @@ def _maps(self): An overdetermined system over a PID:: - sage: res = FreeResolution(M) - sage: res + sage: res = FreeResolution(M); res S^2 <-- S^2 <-- 0 sage: res._m() [x^2 0] @@ -776,51 +763,47 @@ class FiniteFreeResolution_singular(FiniteFreeResolution): sage: from sage.homology.free_resolution import FreeResolution sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = FreeResolution(I) - sage: r + sage: r = FreeResolution(I); r # optional - sage.libs.singular S^1 <-- S^3 <-- S^2 <-- 0 - sage: len(r) + sage: len(r) # optional - sage.libs.singular 2 :: - sage: FreeResolution(I, algorithm='minimal') + sage: FreeResolution(I, algorithm='minimal') # optional - sage.libs.singular S^1 <-- S^3 <-- S^2 <-- 0 - sage: FreeResolution(I, algorithm='shreyer') + sage: FreeResolution(I, algorithm='shreyer') # optional - sage.libs.singular S^1 <-- S^3 <-- S^2 <-- 0 - sage: FreeResolution(I, algorithm='standard') + sage: FreeResolution(I, algorithm='standard') # optional - sage.libs.singular S^1 <-- S^3 <-- S^2 <-- 0 - sage: FreeResolution(I, algorithm='heuristic') + sage: FreeResolution(I, algorithm='heuristic') # optional - sage.libs.singular S^1 <-- S^3 <-- S^2 <-- 0 We can also construct a resolution by passing in a matrix defining the initial differential:: sage: m = matrix(S, 1, [z^2 - y*w, y*z - x*w, y^2 - x*z]).transpose() - sage: r = FreeResolution(m, name='S') - sage: r + sage: r = FreeResolution(m, name='S'); r # optional - sage.libs.singular S^1 <-- S^3 <-- S^2 <-- 0 - sage: r.matrix(1) + sage: r.matrix(1) # optional - sage.libs.singular [z^2 - y*w y*z - x*w y^2 - x*z] An additional construction is using a submodule of a free module:: - sage: M = m.image() - sage: r = FreeResolution(M, name='S') - sage: r + sage: M = m.image() # optional - sage.libs.singular + sage: r = FreeResolution(M, name='S'); r # optional - sage.libs.singular S^1 <-- S^3 <-- S^2 <-- 0 A nonhomogeneous ideal:: sage: I = S.ideal([z^2 - y*w, y*z - x*w, y^2 - x]) - sage: R = FreeResolution(I) - sage: R + sage: R = FreeResolution(I); R # optional - sage.libs.singular S^1 <-- S^3 <-- S^3 <-- S^1 <-- 0 - sage: R.matrix(2) + sage: R.matrix(2) # optional - sage.libs.singular [ y*z - x*w y^2 - x 0] [-z^2 + y*w 0 y^2 - x] [ 0 -z^2 + y*w -y*z + x*w] - sage: R.matrix(3) + sage: R.matrix(3) # optional - sage.libs.singular [ y^2 - x] [-y*z + x*w] [ z^2 - y*w] @@ -834,16 +817,16 @@ def __init__(self, module, name='S', algorithm='heuristic', **kwds): sage: from sage.homology.free_resolution import FreeResolution sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = FreeResolution(I) - sage: TestSuite(r).run(skip=['_test_pickling']) + sage: r = FreeResolution(I) # optional - sage.libs.singular + sage: TestSuite(r).run(skip=['_test_pickling']) # optional - sage.libs.singular sage: m = matrix(S, 1, [z^2 - y*w, y*z - x*w, y^2 - x*z]).transpose() - sage: r = FreeResolution(m, name='S') - sage: TestSuite(r).run(skip=['_test_pickling']) + sage: r = FreeResolution(m, name='S') # optional - sage.libs.singular + sage: TestSuite(r).run(skip=['_test_pickling']) # optional - sage.libs.singular sage: M = m.image() - sage: r = FreeResolution(M, name='S') - sage: TestSuite(r).run(skip=['_test_pickling']) + sage: r = FreeResolution(M, name='S') # optional - sage.libs.singular + sage: TestSuite(r).run(skip=['_test_pickling']) # optional - sage.libs.singular """ self._algorithm = algorithm super().__init__(module, name=name, **kwds) @@ -858,14 +841,17 @@ def _maps(self): sage: from sage.homology.free_resolution import FreeResolution sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = FreeResolution(I) - sage: r._maps + sage: r = FreeResolution(I) # optional - sage.libs.singular + sage: r._maps # optional - sage.libs.singular [ [-y x] [ z -y] [z^2 - y*w y*z - x*w y^2 - x*z], [-w z] ] """ + from sage.libs.singular.singular import si2sa_resolution + from sage.libs.singular.function import singular_function + # This ensures the first component of the Singular resolution to be a # module, like the later components. This is important when the # components are converted to Sage modules. diff --git a/src/sage/homology/graded_resolution.py b/src/sage/homology/graded_resolution.py index d9aa9e11119..65c72ea47c0 100644 --- a/src/sage/homology/graded_resolution.py +++ b/src/sage/homology/graded_resolution.py @@ -9,36 +9,36 @@ sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution(algorithm='minimal') - sage: r + sage: r = I.graded_free_resolution(algorithm='minimal') # optional - sage.libs.singular + sage: r # optional - sage.libs.singular S(0) <-- S(-2)⊕S(-2)⊕S(-2) <-- S(-3)⊕S(-3) <-- 0 - sage: I.graded_free_resolution(algorithm='shreyer') + sage: I.graded_free_resolution(algorithm='shreyer') # optional - sage.libs.singular S(0) <-- S(-2)⊕S(-2)⊕S(-2) <-- S(-3)⊕S(-3) <-- 0 - sage: I.graded_free_resolution(algorithm='standard') + sage: I.graded_free_resolution(algorithm='standard') # optional - sage.libs.singular S(0) <-- S(-2)⊕S(-2)⊕S(-2) <-- S(-3)⊕S(-3) <-- 0 - sage: I.graded_free_resolution(algorithm='heuristic') + sage: I.graded_free_resolution(algorithm='heuristic') # optional - sage.libs.singular S(0) <-- S(-2)⊕S(-2)⊕S(-2) <-- S(-3)⊕S(-3) <-- 0 :: - sage: d = r.differential(2) - sage: d + sage: d = r.differential(2) # optional - sage.libs.singular + sage: d # optional - sage.libs.singular Free module morphism defined as left-multiplication by the matrix - [ y x] - [-z -y] - [ w z] - Domain: Ambient free module of rank 2 over the integral domain Multivariate Polynomial Ring - in x, y, z, w over Rational Field - Codomain: Ambient free module of rank 3 over the integral domain Multivariate Polynomial Ring - in x, y, z, w over Rational Field - sage: d.image() - Submodule of Ambient free module of rank 3 over the integral domain Multivariate Polynomial Ring - in x, y, z, w over Rational Field + [ y x] + [-z -y] + [ w z] + Domain: Ambient free module of rank 2 over the integral domain + Multivariate Polynomial Ring in x, y, z, w over Rational Field + Codomain: Ambient free module of rank 3 over the integral domain + Multivariate Polynomial Ring in x, y, z, w over Rational Field + sage: d.image() # optional - sage.libs.singular + Submodule of Ambient free module of rank 3 over the integral domain + Multivariate Polynomial Ring in x, y, z, w over Rational Field Generated by the rows of the matrix: [ y -z w] [ x -y z] - sage: m = d.image() - sage: m.graded_free_resolution(shifts=(2,2,2)) + sage: m = d.image() # optional - sage.libs.singular + sage: m.graded_free_resolution(shifts=(2,2,2)) # optional - sage.libs.singular S(-2)⊕S(-2)⊕S(-2) <-- S(-3)⊕S(-3) <-- 0 An example of multigraded resolution from Example 9.1 of [MilStu2005]_:: @@ -46,14 +46,15 @@ sage: R. = QQ[] sage: S. = QQ[] sage: phi = S.hom([s, s*t, s*t^2, s*t^3]) - sage: I = phi.kernel(); I - Ideal (c^2 - b*d, b*c - a*d, b^2 - a*c) of Multivariate Polynomial Ring in a, b, c, d over Rational Field - sage: P3 = ProjectiveSpace(S) - sage: C = P3.subscheme(I) # twisted cubic curve - sage: r = I.graded_free_resolution(degrees=[(1,0), (1,1), (1,2), (1,3)]) - sage: r + sage: I = phi.kernel(); I # optional - sage.libs.singular + Ideal (c^2 - b*d, b*c - a*d, b^2 - a*c) of + Multivariate Polynomial Ring in a, b, c, d over Rational Field + sage: P3 = ProjectiveSpace(S) # optional - sage.libs.singular + sage: C = P3.subscheme(I) # twisted cubic curve # optional - sage.libs.singular + sage: r = I.graded_free_resolution(degrees=[(1,0), (1,1), (1,2), (1,3)]) # optional - sage.libs.singular + sage: r # optional - sage.libs.singular S((0, 0)) <-- S((-2, -4))⊕S((-2, -3))⊕S((-2, -2)) <-- S((-3, -5))⊕S((-3, -4)) <-- 0 - sage: r.K_polynomial(names='s,t') + sage: r.K_polynomial(names='s,t') # optional - sage.libs.singular s^3*t^5 + s^3*t^4 - s^2*t^4 - s^2*t^3 - s^2*t^2 + 1 AUTHORS: @@ -73,8 +74,6 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.libs.singular.singular import si2sa_resolution_graded -from sage.libs.singular.function import singular_function from sage.misc.lazy_attribute import lazy_attribute from sage.structure.element import Matrix from sage.modules.free_module_element import vector @@ -115,8 +114,8 @@ def __init__(self, module, degrees=None, shifts=None, name='S', **kwds): sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: TestSuite(r).run(skip=['_test_pickling']) + sage: r = I.graded_free_resolution() # optional - sage.libs.singular + sage: TestSuite(r).run(skip=['_test_pickling']) # optional - sage.libs.singular An overdetermined system over a PID:: @@ -124,10 +123,9 @@ def __init__(self, module, degrees=None, shifts=None, name='S', **kwds): sage: M = matrix([[x^2, 2*x^2], ....: [3*x^2, 5*x^2], ....: [5*x^2, 4*x^2]]) - sage: res = FreeResolution(M, graded=True) - sage: res + sage: res = FreeResolution(M, graded=True); res # optional - sage.libs.singular S(0)⊕S(0) <-- S(-2)⊕S(-2) <-- 0 - sage: res._res_shifts + sage: res._res_shifts # optional - sage.libs.singular [[2, 2]] """ super().__init__(module, name=name, **kwds) @@ -169,18 +167,18 @@ def _repr_module(self, i): sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: r._repr_module(0) + sage: r = I.graded_free_resolution() # optional - sage.libs.singular + sage: r._repr_module(0) # optional - sage.libs.singular 'S(0)' - sage: r._repr_module(1) + sage: r._repr_module(1) # optional - sage.libs.singular 'S(-2)⊕S(-2)⊕S(-2)' - sage: r._repr_module(2) + sage: r._repr_module(2) # optional - sage.libs.singular 'S(-3)⊕S(-3)' - sage: r._repr_module(3) + sage: r._repr_module(3) # optional - sage.libs.singular '0' - sage: r = I.graded_free_resolution(shifts=[-1]) - sage: r._repr_module(0) + sage: r = I.graded_free_resolution(shifts=[-1]) # optional - sage.libs.singular + sage: r._repr_module(0) # optional - sage.libs.singular 'S(1)' """ self._maps # to set _res_shifts @@ -206,14 +204,14 @@ def shifts(self, i): sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: r.shifts(0) + sage: r = I.graded_free_resolution() # optional - sage.libs.singular + sage: r.shifts(0) # optional - sage.libs.singular [0] - sage: r.shifts(1) + sage: r.shifts(1) # optional - sage.libs.singular [2, 2, 2] - sage: r.shifts(2) + sage: r.shifts(2) # optional - sage.libs.singular [3, 3] - sage: r.shifts(3) + sage: r.shifts(3) # optional - sage.libs.singular [] """ if i < 0: @@ -242,18 +240,18 @@ def betti(self, i, a=None): sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: r.betti(0) + sage: r = I.graded_free_resolution() # optional - sage.libs.singular + sage: r.betti(0) # optional - sage.libs.singular {0: 1} - sage: r.betti(1) + sage: r.betti(1) # optional - sage.libs.singular {2: 3} - sage: r.betti(2) + sage: r.betti(2) # optional - sage.libs.singular {3: 2} - sage: r.betti(1, 0) + sage: r.betti(1, 0) # optional - sage.libs.singular 0 - sage: r.betti(1, 1) + sage: r.betti(1, 1) # optional - sage.libs.singular 0 - sage: r.betti(1, 2) + sage: r.betti(1, 2) # optional - sage.libs.singular 3 """ shifts = self.shifts(i) @@ -284,9 +282,9 @@ def K_polynomial(self, names=None): EXAMPLES:: sage: S. = PolynomialRing(QQ) - sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: r.K_polynomial() + sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) # optional - sage.libs.singular + sage: r = I.graded_free_resolution() # optional - sage.libs.singular + sage: r.K_polynomial() # optional - sage.libs.singular 2*t^3 - 3*t^2 + 1 """ if self._multigrade: @@ -327,8 +325,7 @@ class GradedFiniteFreeResolution_free_module(GradedFiniteFreeResolution, FiniteF sage: R. = QQ[] sage: M = matrix([[x^3, 3*x^3, 5*x^3], ....: [0, x, 2*x]]) - sage: res = FreeResolution(M, graded=True) - sage: res + sage: res = FreeResolution(M, graded=True); res # optional - sage.libs.singular S(0)⊕S(0)⊕S(0) <-- S(-3)⊕S(-1) <-- 0 """ def __init__(self, module, degrees=None, *args, **kwds): @@ -341,8 +338,8 @@ def __init__(self, module, degrees=None, *args, **kwds): sage: R. = QQ[] sage: M = matrix([[x^3, 3*x^3, 5*x^3], ....: [0, x, 2*x]]) - sage: res = FreeResolution(M, graded=True) - sage: TestSuite(res).run(skip="_test_pickling") + sage: res = FreeResolution(M, graded=True) # optional - sage.libs.singular + sage: TestSuite(res).run(skip="_test_pickling") # optional - sage.libs.singular """ super().__init__(module, degrees=degrees, *args, **kwds) @@ -363,25 +360,23 @@ def _maps(self): sage: R. = QQ[] sage: M = matrix([[x^3, 3*x^3, 5*x^3], ....: [0, x, 2*x]]) - sage: res = FreeResolution(M, graded=True) - sage: res + sage: res = FreeResolution(M, graded=True); res # optional - sage.libs.singular S(0)⊕S(0)⊕S(0) <-- S(-3)⊕S(-1) <-- 0 - sage: res._maps + sage: res._maps # optional - sage.libs.singular [ [ x^3 0] [3*x^3 x] [5*x^3 2*x] ] - sage: res._res_shifts + sage: res._res_shifts # optional - sage.libs.singular [[3, 1]] sage: I = R.ideal([x^4]) - sage: res = I.graded_free_resolution(shifts=[1], degrees=[2]) - sage: res + sage: res = I.graded_free_resolution(shifts=[1], degrees=[2]); res # optional - sage.libs.singular S(-1) <-- S(-9) <-- 0 - sage: res._maps + sage: res._maps # optional - sage.libs.singular [[x^4]] - sage: res._res_shifts + sage: res._res_shifts # optional - sage.libs.singular [[9]] """ def compute_degree(base, i): @@ -473,17 +468,15 @@ class GradedFiniteFreeResolution_singular(GradedFiniteFreeResolution, FiniteFree sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: r + sage: r = I.graded_free_resolution(); r # optional - sage.libs.singular S(0) <-- S(-2)⊕S(-2)⊕S(-2) <-- S(-3)⊕S(-3) <-- 0 - sage: len(r) + sage: len(r) # optional - sage.libs.singular 2 sage: I = S.ideal([z^2 - y*w, y*z - x*w, y - x]) sage: I.is_homogeneous() True - sage: r = I.graded_free_resolution() - sage: r + sage: r = I.graded_free_resolution(); r # optional - sage.libs.singular S(0) <-- S(-1)⊕S(-2)⊕S(-2) <-- S(-3)⊕S(-3)⊕S(-4) <-- S(-5) <-- 0 """ def __init__(self, module, degrees=None, shifts=None, name='S', algorithm='heuristic', **kwds): @@ -494,8 +487,8 @@ def __init__(self, module, degrees=None, shifts=None, name='S', algorithm='heuri sage: S. = PolynomialRing(QQ) sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: TestSuite(r).run(skip=['_test_pickling']) + sage: r = I.graded_free_resolution() # optional - sage.libs.singular + sage: TestSuite(r).run(skip=['_test_pickling']) # optional - sage.libs.singular """ super().__init__(module, degrees=degrees, shifts=shifts, name=name, **kwds) self._algorithm = algorithm @@ -510,17 +503,20 @@ def _maps(self): TESTS:: sage: S. = PolynomialRing(QQ) - sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) - sage: r = I.graded_free_resolution() - sage: r._maps + sage: I = S.ideal([y*w - z^2, -x*w + y*z, x*z - y^2]) # optional - sage.libs.singular + sage: r = I.graded_free_resolution() # optional - sage.libs.singular + sage: r._maps # optional - sage.libs.singular [ [-y x] [ z -y] [z^2 - y*w y*z - x*w y^2 - x*z], [-w z] ] - sage: r._res_shifts + sage: r._res_shifts # optional - sage.libs.singular [[2, 2, 2], [3, 3]] """ + from sage.libs.singular.singular import si2sa_resolution_graded + from sage.libs.singular.function import singular_function + #cdef int i, j, k, ncols, nrows #cdef list res_shifts, prev_shifts, new_shifts diff --git a/src/sage/homology/hochschild_complex.py b/src/sage/homology/hochschild_complex.py index f372a08e0e8..05af2b6cbce 100644 --- a/src/sage/homology/hochschild_complex.py +++ b/src/sage/homology/hochschild_complex.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat (because all doctests use FreeAlgebra, SymmetricGroupAlgebra, etc.) """ Hochschild Complexes """ diff --git a/src/sage/homology/homology_group.py b/src/sage/homology/homology_group.py index 0b27087a362..5948d206371 100644 --- a/src/sage/homology/homology_group.py +++ b/src/sage/homology/homology_group.py @@ -32,13 +32,13 @@ class HomologyGroup_class(AdditiveAbelianGroup_fixed_gens): EXAMPLES:: sage: from sage.homology.homology_group import HomologyGroup - sage: G = AbelianGroup(5, [5,5,7,8,9]); G + sage: G = AbelianGroup(5, [5,5,7,8,9]); G # optional - sage.groups Multiplicative Abelian group isomorphic to C5 x C5 x C7 x C8 x C9 sage: H = HomologyGroup(5, ZZ, [5,5,7,8,9]); H C5 x C5 x C7 x C8 x C9 - sage: G == loads(dumps(G)) + sage: G == loads(dumps(G)) # optional - sage.groups True - sage: AbelianGroup(4) + sage: AbelianGroup(4) # optional - sage.groups Multiplicative Abelian group isomorphic to Z x Z x Z x Z sage: HomologyGroup(4, ZZ) Z x Z x Z x Z @@ -156,11 +156,11 @@ def HomologyGroup(n, base_ring, invfac=None): EXAMPLES:: sage: from sage.homology.homology_group import HomologyGroup - sage: G = AbelianGroup(5, [5,5,7,8,9]); G + sage: G = AbelianGroup(5, [5,5,7,8,9]); G # optional - sage.groups Multiplicative Abelian group isomorphic to C5 x C5 x C7 x C8 x C9 sage: H = HomologyGroup(5, ZZ, [5,5,7,8,9]); H C5 x C5 x C7 x C8 x C9 - sage: AbelianGroup(4) + sage: AbelianGroup(4) # optional - sage.groups Multiplicative Abelian group isomorphic to Z x Z x Z x Z sage: HomologyGroup(4, ZZ) Z x Z x Z x Z diff --git a/src/sage/homology/homology_morphism.py b/src/sage/homology/homology_morphism.py index 7dfd5fc8b08..9cd1c7a4a82 100644 --- a/src/sage/homology/homology_morphism.py +++ b/src/sage/homology/homology_morphism.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.graphs (because all doctests use the catalog simplicial_complexes) r""" Induced morphisms on homology @@ -27,12 +28,19 @@ # - associated_chain_complex_morphism # Once this is done, the code here ought to work without modification. +import itertools + from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.graded_modules_with_basis import GradedModulesWithBasis from sage.categories.morphism import Morphism from sage.categories.homset import Hom from sage.rings.rational_field import QQ -from sage.topology.simplicial_complex import SimplicialComplex + +try: + from sage.topology.simplicial_complex import SimplicialComplex +except ImportError: + SimplicialComplex = () + class InducedHomologyMorphism(Morphism): r""" @@ -61,12 +69,13 @@ class InducedHomologyMorphism(Morphism): sage: f = H({0:0, 1:2, 2:1}) # f switches two vertices sage: f_star = f.induced_homology_morphism(QQ, cohomology=True) sage: f_star - Graded algebra endomorphism of Cohomology ring of Minimal triangulation of the 1-sphere over Rational Field + Graded algebra endomorphism of + Cohomology ring of Minimal triangulation of the 1-sphere over Rational Field Defn: induced by: - Simplicial complex endomorphism of Minimal triangulation of the 1-sphere - Defn: 0 |--> 0 - 1 |--> 2 - 2 |--> 1 + Simplicial complex endomorphism of Minimal triangulation of the 1-sphere + Defn: 0 |--> 0 + 1 |--> 2 + 2 |--> 1 sage: f_star.to_matrix(1) [-1] sage: f_star.to_matrix() @@ -86,7 +95,7 @@ class in the torus, we can define a map `S^1 \to T` inducing an sage: Hom(S1, T)({0:0, 1:2, 2:5}) Simplicial complex morphism: From: Minimal triangulation of the 1-sphere - To: Minimal triangulation of the torus + To: Minimal triangulation of the torus Defn: 0 |--> 0 1 |--> 2 2 |--> 5 @@ -180,7 +189,7 @@ def __init__(self, map, base_ring=None, cohomology=False): def base_ring(self): """ - The base ring for this map + The base ring for this map. EXAMPLES:: @@ -189,7 +198,7 @@ def base_ring(self): sage: id = H.identity() sage: id.induced_homology_morphism(QQ).base_ring() Rational Field - sage: id.induced_homology_morphism(GF(13)).base_ring() + sage: id.induced_homology_morphism(GF(13)).base_ring() # optional - sage.rings.finite_rings Finite Field of size 13 """ return self._base_ring @@ -234,14 +243,13 @@ def to_matrix(self, deg=None): mat = mat.transpose() H_domain, H_codomain = H_codomain, H_domain if deg is None: - import numpy as np betti_domain = [H_domain.free_module_rank(n) for n in range(domain.dimension()+1)] betti_codomain = [H_codomain.free_module_rank(n) for n in range(codomain.dimension()+1)] # Compute cumulative sums of Betti numbers to get subdivisions: - row_subdivs = list(np.cumsum(betti_codomain[:-1])) - col_subdivs = list(np.cumsum(betti_domain[:-1])) + row_subdivs = list(itertools.accumulate(betti_codomain[:-1])) + col_subdivs = list(itertools.accumulate(betti_domain[:-1])) mat.subdivide(row_subdivs, col_subdivs) return mat @@ -304,7 +312,7 @@ def __eq__(self, other): sage: g = Hom(S1, K)({0: 0, 1:0, 2:0}) sage: f.induced_homology_morphism(QQ) == g.induced_homology_morphism(QQ) True - sage: f.induced_homology_morphism(QQ) == g.induced_homology_morphism(GF(2)) + sage: f.induced_homology_morphism(QQ) == g.induced_homology_morphism(GF(2)) # optional - sage.rings.finite_rings False sage: id = Hom(K, K).identity() # different domain sage: f.induced_homology_morphism(QQ) == id.induced_homology_morphism(QQ) @@ -320,7 +328,7 @@ def __eq__(self, other): def is_identity(self): """ - True if this is the identity map on (co)homology. + Return ``True`` if this is the identity map on (co)homology. EXAMPLES:: @@ -339,7 +347,7 @@ def is_identity(self): def is_surjective(self): """ - True if this map is surjective on (co)homology. + Return ``True`` if this map is surjective on (co)homology. EXAMPLES:: @@ -357,7 +365,7 @@ def is_surjective(self): def is_injective(self): """ - True if this map is injective on (co)homology. + Return ``True`` if this map is injective on (co)homology. EXAMPLES:: diff --git a/src/sage/homology/homology_vector_space_with_basis.py b/src/sage/homology/homology_vector_space_with_basis.py index 63a80657917..fd5e2fbdc0d 100644 --- a/src/sage/homology/homology_vector_space_with_basis.py +++ b/src/sage/homology/homology_vector_space_with_basis.py @@ -1,4 +1,5 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.graphs (because all doctests use the catalogs simplicial_complexes, cubical_complexes) + """ Homology and cohomology with a basis @@ -30,8 +31,13 @@ from sage.categories.modules import Modules from sage.combinat.free_module import CombinatorialFreeModule from sage.sets.family import Family -from sage.topology.simplicial_complex import SimplicialComplex -from sage.topology.simplicial_set import SimplicialSet_arbitrary + +try: + from sage.topology.simplicial_complex import SimplicialComplex + from sage.topology.simplicial_set import SimplicialSet_arbitrary +except ImportError: + SimplicialComplex = SimplicialSet_arbitrary = () + class HomologyVectorSpaceWithBasis(CombinatorialFreeModule): r""" diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index 6679106b59c..f6b70709f2a 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -39,19 +39,19 @@ from sage.arith.misc import factor from sage.arith.srange import srange -from sage.calculus.all import symbolic_expression -from sage.calculus.functional import derivative -from sage.calculus.integration import numerical_integral as integral_numerical +from sage.misc.lazy_import import lazy_import +lazy_import("sage.calculus.all", "symbolic_expression") +lazy_import("sage.calculus.functional", "derivative") +lazy_import("sage.calculus.integration", "numerical_integral", as_="integral_numerical") from sage.ext.fast_callable import fast_callable -from sage.functions.log import exp +lazy_import("sage.functions.log", "exp") +lazy_import("sage.functions.trig", ["acos", "cos", "sin", "tan"]) from sage.misc.functional import sqrt -from sage.functions.trig import (acos, cos, sin, tan) from sage.misc.decorators import sage_wraps from sage.misc.functional import N from sage.misc.latex import latex from sage.misc.sage_eval import sage_eval from sage.misc.table import table -from sage.misc.lazy_import import lazy_import lazy_import("sage.plot.circle", "circle") lazy_import("sage.plot.complex_plot", "complex_plot") lazy_import("sage.plot.disk", "disk") @@ -65,9 +65,10 @@ from sage.repl.rich_output.pretty_print import (pretty_print, show) from sage.rings.complex_double import CDF from sage.rings.integer import Integer -from sage.symbolic.constants import pi -from sage.symbolic.relation import solve -from sage.symbolic.ring import SR +lazy_import("sage.symbolic.constants", "pi") +lazy_import("sage.symbolic.relation", "solve") +lazy_import("sage.symbolic.ring", "SR") +import math x = SR.var('x') diff --git a/src/sage/interfaces/all.py b/src/sage/interfaces/all.py index 1e0623ec4ec..728c7f443cf 100644 --- a/src/sage/interfaces/all.py +++ b/src/sage/interfaces/all.py @@ -4,8 +4,12 @@ from .gap import gap, gap_reset_workspace, Gap from .gp import gp, gp_version, Gp # import problems -#from maxima_lib import maxima_lib -from .maxima import maxima, Maxima +try: + # from maxima_lib import maxima_lib + from .maxima import maxima, Maxima +except ImportError: + pass + from .singular import singular, singular_version, Singular from .magma import magma, Magma diff --git a/src/sage/interfaces/singular.py b/src/sage/interfaces/singular.py index b79e08c44f9..3e4a5eddd50 100644 --- a/src/sage/interfaces/singular.py +++ b/src/sage/interfaces/singular.py @@ -1660,14 +1660,14 @@ def sage_global_ring(self): br = QQ elif charstr[0].startswith('Float'): from sage.rings.real_mpfr import RealField - from sage.functions.other import ceil + from sage.arith.misc import integer_ceil as ceil from sage.misc.functional import log prec = singular.eval('ringlist(basering)[1][2][1]') br = RealField(ceil((ZZ(prec)+1)/log(2,10))) is_extension = False elif charstr[0]=='complex': from sage.rings.complex_mpfr import ComplexField - from sage.functions.other import ceil + from sage.arith.misc import integer_ceil as ceil from sage.misc.functional import log prec = singular.eval('ringlist(basering)[1][2][1]') br = ComplexField(ceil((ZZ(prec)+1)/log(2,10))) diff --git a/src/sage/interfaces/sympy.py b/src/sage/interfaces/sympy.py index 9ca4203b648..6d186e89e9d 100644 --- a/src/sage/interfaces/sympy.py +++ b/src/sage/interfaces/sympy.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sympy """ SymPy --> Sage conversion diff --git a/src/sage/interfaces/tides.py b/src/sage/interfaces/tides.py index ff3861dd223..7ed3ad2bc4a 100644 --- a/src/sage/interfaces/tides.py +++ b/src/sage/interfaces/tides.py @@ -37,13 +37,15 @@ - [TIDES]_ """ -from sage.rings.real_mpfr import RealField -from sage.calculus.all import symbolic_expression + +from sage.rings.real_mpfr import RealField +from sage.misc.lazy_import import lazy_import +lazy_import("sage.calculus.all", "symbolic_expression") from sage.misc.flatten import flatten from sage.ext.fast_callable import fast_callable from sage.rings.semirings.non_negative_integer_semiring import NN -from sage.functions.log import log, exp -from sage.functions.other import floor, ceil +lazy_import("sage.functions.log", ["log", "exp"]) +lazy_import("sage.functions.other", ["floor", "ceil"]) from sage.misc.functional import sqrt diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index 4d845139d17..56866c61909 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -58,10 +58,11 @@ from sage.graphs.digraph import DiGraph from sage.graphs.graph import Graph from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing -from sage.symbolic.ring import SR +from sage.misc.lazy_import import lazy_import +lazy_import("sage.symbolic.ring", "SR") from sage.rings.integer import Integer from sage.numerical.mip import MixedIntegerLinearProgram -from sage.functions.generalized import sign +lazy_import("sage.functions.generalized", "sign") from sage.homology.chain_complex import ChainComplex from sage.misc.flatten import flatten from sage.misc.cachefunc import cached_method diff --git a/src/sage/lfunctions/zero_sums.pyx b/src/sage/lfunctions/zero_sums.pyx index 251fa0e488f..a772a80c973 100644 --- a/src/sage/lfunctions/zero_sums.pyx +++ b/src/sage/lfunctions/zero_sums.pyx @@ -937,6 +937,7 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): # PARI minicurve for computing a_p coefficients self._e = E.pari_mincurve() + from sage.symbolic.constants import pi, euler_gamma self._pi = RDF(pi) self._euler_gamma = RDF(euler_gamma) diff --git a/src/sage/libs/flint/fmpz_factor.pyx b/src/sage/libs/flint/fmpz_factor.pyx index 1d49e8ac22b..330ba3d4d4e 100644 --- a/src/sage/libs/flint/fmpz_factor.pyx +++ b/src/sage/libs/flint/fmpz_factor.pyx @@ -8,9 +8,9 @@ cdef fmpz_factor_to_pairlist(const fmpz_factor_t factors): (factor, exponent) pairs. The factors are Integers, and the exponents are Python ints. This is used and indirectly tested by both :func:`qsieve` and - :func:`sage.rings.factorint.factor_using_flint`. The output + :func:`sage.rings.factorint_flint.factor_using_flint`. The output format was ultimately based on that of - :func:`sage.rings.factorint.factor_using_pari`. + :func:`sage.rings.factorint_pari.factor_using_pari`. """ cdef list pairs = [] diff --git a/src/sage/libs/symmetrica/symmetrica.pxi b/src/sage/libs/symmetrica/symmetrica.pxi index 95f9e52fbda..2a18fc8edec 100644 --- a/src/sage/libs/symmetrica/symmetrica.pxi +++ b/src/sage/libs/symmetrica/symmetrica.pxi @@ -430,19 +430,12 @@ cdef void late_import(): Permutation = sage.combinat.permutation.Permutation Permutations = sage.combinat.permutation.Permutations - import sage.functions.all - sqrt = sage.functions.all.sqrt - - import sage.misc.all - prod = sage.misc.all.prod - - import sage.rings.polynomial.polynomial_ring_constructor - PolynomialRing = sage.rings.polynomial.polynomial_ring_constructor.PolynomialRing - - import sage.rings.all - QQ = sage.rings.all.QQ - Rational = sage.rings.all.Rational - ZZ = sage.rings.all.ZZ + from sage.misc.functional import sqrt + from sage.misc.misc_c import prod + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + from sage.rings.rational_field import QQ + from sage.rings.rational import Rational + from sage.rings.integer_ring import ZZ #Symmetric Functions import sage.combinat.sf.sf diff --git a/src/sage/matrix/action.pyx b/src/sage/matrix/action.pyx index dc057d1dce5..b9ae87fa9d3 100644 --- a/src/sage/matrix/action.pyx +++ b/src/sage/matrix/action.pyx @@ -19,11 +19,15 @@ Actions used by the coercion model for matrix and vector multiplications sage: MSZ = MatrixSpace(ZZ['x'], 2) sage: A = MSQ.get_action(MSZ) sage: A - Left action by Full MatrixSpace of 2 by 2 dense matrices over Rational Field on Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring + Left action by Full MatrixSpace of 2 by 2 dense matrices over Rational Field + on Full MatrixSpace of 2 by 2 dense matrices + over Univariate Polynomial Ring in x over Integer Ring sage: import gc sage: _ = gc.collect() sage: A - Left action by Full MatrixSpace of 2 by 2 dense matrices over Rational Field on Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring + Left action by Full MatrixSpace of 2 by 2 dense matrices over Rational Field + on Full MatrixSpace of 2 by 2 dense matrices + over Univariate Polynomial Ring in x over Integer Ring .. NOTE:: @@ -83,13 +87,17 @@ cdef class MatrixMulAction(Action): sage: MSQ = MatrixSpace(QQ, 2) sage: MSZ = MatrixSpace(ZZ['x'], 2) sage: A = MSQ.get_action(MSZ); A - Left action by Full MatrixSpace of 2 by 2 dense matrices over Rational Field on Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring + Left action by Full MatrixSpace of 2 by 2 dense matrices over Rational Field + on Full MatrixSpace of 2 by 2 dense matrices + over Univariate Polynomial Ring in x over Integer Ring sage: A.actor() Full MatrixSpace of 2 by 2 dense matrices over Rational Field sage: A.domain() - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring + Full MatrixSpace of 2 by 2 dense matrices + over Univariate Polynomial Ring in x over Integer Ring sage: A.codomain() - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field + Full MatrixSpace of 2 by 2 dense matrices + over Univariate Polynomial Ring in x over Rational Field """ def __init__(self, G, S, is_left): if not is_MatrixSpace(G): @@ -130,9 +138,13 @@ cdef class MatrixMatrixAction(MatrixMulAction): sage: MSQ = MatrixSpace(QQ, 3, 2) sage: from sage.matrix.action import MatrixMatrixAction sage: A = MatrixMatrixAction(MSR, MSQ); A - Left action by Full MatrixSpace of 3 by 3 dense matrices over Univariate Polynomial Ring in x over Integer Ring on Full MatrixSpace of 3 by 2 dense matrices over Rational Field + Left action + by Full MatrixSpace of 3 by 3 dense matrices + over Univariate Polynomial Ring in x over Integer Ring + on Full MatrixSpace of 3 by 2 dense matrices over Rational Field sage: A.codomain() - Full MatrixSpace of 3 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field + Full MatrixSpace of 3 by 2 dense matrices + over Univariate Polynomial Ring in x over Rational Field sage: A(matrix(R, 3, 3, x), matrix(QQ, 3, 2, range(6))) [ 0 x] [2*x 3*x] @@ -183,7 +195,8 @@ cdef class MatrixMatrixAction(MatrixMulAction): sage: MSR = MatrixSpace(R, 3, 3) sage: MSQ = MatrixSpace(QQ, 3, 2) sage: A = MatrixMatrixAction(MSR, MSQ); A - Left action by Full MatrixSpace of 3 by 3 dense matrices over Univariate Polynomial Ring in x over Integer Ring on Full MatrixSpace of 3 by 2 dense matrices over Rational Field + Left action by Full MatrixSpace of 3 by 3 dense matrices over Univariate Polynomial Ring in x over Integer Ring + on Full MatrixSpace of 3 by 2 dense matrices over Rational Field sage: A.codomain() Full MatrixSpace of 3 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field @@ -209,23 +222,23 @@ cdef class MatrixMatrixAction(MatrixMulAction): Respects compatible subdivisions:: - sage: M = matrix(5, 5, prime_range(100)) - sage: M.subdivide(2,3); M + sage: M = matrix(5, 5, prime_range(100)) # optional - sage.libs.pari + sage: M.subdivide(2, 3); M # optional - 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] - sage: N = matrix(5,2,[n^2 for n in range(10)]) - sage: N.subdivide(3,1); N + sage: N = matrix(5, 2, [n^2 for n in range(10)]) + sage: N.subdivide(3, 1); N [ 0| 1] [ 4| 9] [16|25] [--+--] [36|49] [64|81] - sage: M*N + sage: M*N # optional - sage.libs.pari [ 1048| 1388] [ 3056| 4117] [-----+-----] @@ -235,7 +248,7 @@ cdef class MatrixMatrixAction(MatrixMulAction): Note that this is just like block matrix multiplication:: - sage: M.subdivision(0,0) * N.subdivision(0,0) + M.subdivision(0,1) * N.subdivision(1,0) + sage: M.subdivision(0,0) * N.subdivision(0,0) + M.subdivision(0,1) * N.subdivision(1,0) # optional - sage.libs.pari [1048] [3056] @@ -249,7 +262,7 @@ cdef class MatrixMatrixAction(MatrixMulAction): [16|25] [36|49] [64|81] - sage: M*N + sage: M*N # optional - sage.libs.pari [ 1048 1388] [ 3056 4117] [ 5360 7303] @@ -304,7 +317,8 @@ cdef class MatrixVectorAction(MatrixMulAction): sage: M = MatrixSpace(QQ, 5, 3) sage: V = VectorSpace(CDF, 3) # strong reference prevents garbage collection sage: A = MatrixVectorAction(M, V); A - Left action by Full MatrixSpace of 5 by 3 dense matrices over Rational Field on Vector space of dimension 3 over Complex Double Field + Left action by Full MatrixSpace of 5 by 3 dense matrices over Rational Field + on Vector space of dimension 3 over Complex Double Field sage: A.codomain() Vector space of dimension 5 over Complex Double Field """ @@ -355,7 +369,8 @@ cdef class VectorMatrixAction(MatrixMulAction): sage: V = VectorSpace(CDF, 3) sage: A = VectorMatrixAction(M, V) sage: A - Right action by Full MatrixSpace of 3 by 5 dense matrices over Rational Field on Vector space of dimension 3 over Complex Double Field + Right action by Full MatrixSpace of 3 by 5 dense matrices over Rational Field + on Vector space of dimension 3 over Complex Double Field sage: A.codomain() Vector space of dimension 5 over Complex Double Field """ diff --git a/src/sage/matrix/args.pyx b/src/sage/matrix/args.pyx index 9e738312c27..ec4ce79d322 100644 --- a/src/sage/matrix/args.pyx +++ b/src/sage/matrix/args.pyx @@ -82,7 +82,7 @@ cdef class SparseEntry: sage: from sage.matrix.args import SparseEntry sage: SparseEntry(123, 456, "abc") SparseEntry(123, 456, 'abc') - sage: SparseEntry(1/3, 2/3, x) + sage: SparseEntry(1/3, 2/3, x) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: unable to convert rational 1/3 to an integer @@ -155,94 +155,133 @@ cdef class MatrixArgs: sage: ma = MatrixArgs(2, 2, (x for x in range(4))); ma > sage: ma.finalized() - + Many types of input are possible:: - sage: ma = MatrixArgs(2, 2, entries=None); ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs(2, 2, entries=None); ma.finalized() + + sage: ma.matrix() [0 0] [0 0] - sage: ma = MatrixArgs(2, 2, entries={}); ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs(2, 2, entries={}); ma.finalized() + + sage: ma.matrix() [0 0] [0 0] - sage: ma = MatrixArgs(2, 2, entries=[1,2,3,4]); ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs(2, 2, entries=[1,2,3,4]); ma.finalized() + + sage: ma.matrix() [1 2] [3 4] - sage: ma = MatrixArgs(2, 2, entries=math.pi); ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs(2, 2, entries=math.pi); ma.finalized() + + sage: ma.matrix() [3.141592653589793 0.0] [ 0.0 3.141592653589793] - sage: ma = MatrixArgs(2, 2, entries=pi); ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs(2, 2, entries=pi); ma.finalized() # optional - sage.symbolic + + sage: ma.matrix() [pi 0] [ 0 pi] - sage: ma = MatrixArgs(ZZ, 2, 2, entries={(0,0):7}); ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs(ZZ, 2, 2, entries={(0,0): 7}); ma.finalized() + + sage: ma.matrix() [7 0] [0 0] - sage: ma = MatrixArgs(ZZ, 2, 2, entries=((1,2),(3,4))); ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs(ZZ, 2, 2, entries=((1,2), (3,4))); ma.finalized() + + sage: ma.matrix() [1 2] [3 4] - sage: ma = MatrixArgs(ZZ, 2, 2, entries=(1,2,3,4)); ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs(ZZ, 2, 2, entries=(1,2,3,4)); ma.finalized() + + sage: ma.matrix() [1 2] [3 4] - sage: ma = MatrixArgs(QQ, entries=pari("[1,2;3,4]")); ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs(QQ, entries=pari("[1,2;3,4]")); ma.finalized() # optional - sage.libs.pari + + sage: ma.matrix() [1 2] [3 4] - sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("[1,2,3,4]")); ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("[1,2,3,4]")); ma.finalized() # optional - sage.libs.pari + + sage: ma.matrix() [1 2] [3 4] - sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("3/5")); ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("3/5")); ma.finalized() # optional - sage.libs.pari + + sage: ma.matrix() [3/5 0] [ 0 3/5] - sage: ma = MatrixArgs(entries=matrix(2,2)); ma.finalized(); ma.matrix() - + sage: ma.matrix() [0 0] [0 0] - sage: ma = MatrixArgs(2, 2, entries=lambda i,j: 1+2*i+j); ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs(2, 2, entries=lambda i,j: 1+2*i+j); ma.finalized() + + sage: ma.matrix() [1 2] [3 4] - sage: ma = MatrixArgs(ZZ, 2, 2, entries=lambda i,j: 1+2*i+j); ma.finalized(); ma.matrix() - > + sage: ma = MatrixArgs(ZZ, 2, 2, entries=lambda i,j: 1+2*i+j); ma.finalized() + > + sage: ma.matrix() [1 2] [3 4] - sage: from numpy import array - sage: ma = MatrixArgs(array([[1,2],[3,4]])); ma.finalized(); ma.matrix() - + sage: from numpy import array # optional - numpy + sage: ma = MatrixArgs(array([[1,2],[3,4]])); ma.finalized() # optional - numpy + + sage: ma.matrix() [1 2] [3 4] - sage: ma = MatrixArgs(array([[1.,2.],[3.,4.]])); ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs(array([[1.,2.],[3.,4.]])); ma.finalized() # optional - numpy + + sage: ma.matrix() [1.0 2.0] [3.0 4.0] - sage: ma = MatrixArgs(RealField(20), array([[1.,2.],[3.,4.]])); ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs(RealField(20), array([[1.,2.],[3.,4.]])); ma.finalized() # optional - numpy + + sage: ma.matrix() [1.0000 2.0000] [3.0000 4.0000] - sage: ma = MatrixArgs(graphs.CycleGraph(3)); ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs(graphs.CycleGraph(3)); ma.finalized() # optional - sage.graphs + + sage: ma.matrix() [0 1 1] [1 0 1] [1 1 0] - sage: ma = MatrixArgs([vector([0,1], sparse=True), vector([0,0], sparse=True)], sparse=True) - sage: ma.finalized(); ma.matrix() - + sage: ma = MatrixArgs([vector([0,1], sparse=True), + ....: vector([0,0], sparse=True)], sparse=True) + sage: ma.finalized() + + sage: ma.matrix() [0 1] [0 0] @@ -457,8 +496,8 @@ cdef class MatrixArgs: Sparse examples:: - sage: ma = MatrixArgs(3, 3, pi) - sage: list(ma.iter(sparse=True)) + sage: ma = MatrixArgs(3, 3, pi) # optional - sage.symbolic + sage: list(ma.iter(sparse=True)) # optional - sage.symbolic [SparseEntry(0, 0, pi), SparseEntry(1, 1, pi), SparseEntry(2, 2, pi)] sage: ma = MatrixArgs(2, 3) sage: list(ma.iter(sparse=True)) @@ -610,7 +649,8 @@ cdef class MatrixArgs: :: sage: ma = MatrixArgs(M); ma.finalized() - sage: ma.matrix() [0 1 2] @@ -619,8 +659,9 @@ cdef class MatrixArgs: :: sage: ma = MatrixArgs(M, sparse=False); ma.finalized() - + sage: ma.matrix() [0 1 2] [3 4 5] @@ -628,8 +669,9 @@ cdef class MatrixArgs: :: sage: ma = MatrixArgs(RDF, M); ma.finalized() - + sage: ma.matrix(convert=False) [0 1 2] [3 4 5] @@ -757,10 +799,10 @@ cdef class MatrixArgs: :: - sage: ma = MatrixArgs(GF(2), 2, 3, L) - sage: ma.dict(convert=False) + sage: ma = MatrixArgs(GF(2), 2, 3, L) # optional - sage.rings.finite_rings + sage: ma.dict(convert=False) # optional - sage.rings.finite_rings {(0, 1): 1, (0, 2): 2, (1, 0): 3, (1, 1): 4, (1, 2): 5} - sage: ma.dict() + sage: ma.dict() # optional - sage.rings.finite_rings {(0, 1): 1, (1, 0): 1, (1, 2): 1} """ self.finalize() @@ -789,7 +831,8 @@ cdef class MatrixArgs: sage: S = MatrixSpace(QQ, 3, 2, sparse=True) sage: _ = ma.set_space(S) sage: ma.finalized() - + sage: M = ma.matrix(); M [0 0] [0 0] @@ -818,16 +861,17 @@ cdef class MatrixArgs: EXAMPLES:: sage: from sage.matrix.args import MatrixArgs - sage: MatrixArgs(pi).finalized() + sage: MatrixArgs(pi).finalized() # optional - sage.symbolic Traceback (most recent call last): ... TypeError: the dimensions of the matrix must be specified - sage: MatrixArgs(RR, pi).finalized() + sage: MatrixArgs(RR, pi).finalized() # optional - sage.symbolic Traceback (most recent call last): ... TypeError: the dimensions of the matrix must be specified sage: MatrixArgs(2, 3, 0.0).finalized() - + sage: MatrixArgs(RR, 2, 3, 1.0).finalized() Traceback (most recent call last): ... @@ -973,19 +1017,21 @@ cdef class MatrixArgs: EXAMPLES:: sage: from sage.matrix.args import MatrixArgs - sage: ma = MatrixArgs({(2,5):1/2, (4,-3):1/3}) - sage: ma = MatrixArgs(2, 2, {(-1,0):2, (0,-1):1}, sparse=True) + sage: ma = MatrixArgs({(2,5): 1/2, (4,-3): 1/3}) + sage: ma = MatrixArgs(2, 2, {(-1,0): 2, (0,-1): 1}, sparse=True) sage: ma.finalized() - - sage: ma = MatrixArgs(2, 2, {(-1,0):2, (0,-1):1}, sparse=False) + + sage: ma = MatrixArgs(2, 2, {(-1,0): 2, (0,-1): 1}, sparse=False) sage: ma.finalized() - - sage: ma = MatrixArgs(2, 1, {(1,0):88, (0,1):89}) + + sage: ma = MatrixArgs(2, 1, {(1,0): 88, (0,1): 89}) sage: ma.finalized() Traceback (most recent call last): ... IndexError: invalid column index 1 - sage: ma = MatrixArgs(1, 2, {(1,0):88, (0,1):89}) + sage: ma = MatrixArgs(1, 2, {(1,0): 88, (0,1): 89}) sage: ma.finalized() Traceback (most recent call last): ... @@ -1196,21 +1242,21 @@ cdef class MatrixArgs: Check that :trac:`26655` is fixed:: - sage: F. = GF(9) - sage: M = MatrixSpace(F, 2, 2) - sage: A = M([[1, a], [0, 1]]) - sage: M(pari(A)) + sage: F. = GF(9) # optional - sage.rings.finite_rings + sage: M = MatrixSpace(F, 2, 2) # optional - sage.rings.finite_rings + sage: A = M([[1, a], [0, 1]]) # optional - sage.rings.finite_rings + sage: M(pari(A)) # optional - sage.rings.finite_rings [1 a] [0 1] Constructing a matrix from a PARI ``t_VEC`` or ``t_COL`` with ``t_VEC`` or ``t_COL`` elements is currently not supported:: - sage: M(pari([1, a, 0, 1])) + sage: M(pari([1, a, 0, 1])) # optional - sage.libs.pari Traceback (most recent call last): ... NameError: name 'a' is not defined - sage: M(pari([[1, a], [0, 1]])) + sage: M(pari([[1, a], [0, 1]])) # optional - sage.libs.pari Traceback (most recent call last): ... NameError: name 'a' is not defined @@ -1322,12 +1368,12 @@ cpdef MatrixArgs MatrixArgs_init(space, entries): EXAMPLES:: sage: from sage.matrix.args import MatrixArgs_init - sage: S = MatrixSpace(GF(2), 2, 4) - sage: ma = MatrixArgs_init(S, {(1,3):7}) - sage: M = ma.matrix(); M + sage: S = MatrixSpace(GF(2), 2, 4) # optional - sage.rings.finite_rings + sage: ma = MatrixArgs_init(S, {(1, 3): 7}) # optional - sage.rings.finite_rings + sage: M = ma.matrix(); M # optional - sage.rings.finite_rings [0 0 0 0] [0 0 0 1] - sage: parent(M) is S + sage: parent(M) is S # optional - sage.rings.finite_rings True """ cdef MatrixArgs ret diff --git a/src/sage/matrix/berlekamp_massey.py b/src/sage/matrix/berlekamp_massey.py index 716ed428745..9ea72f510cd 100644 --- a/src/sage/matrix/berlekamp_massey.py +++ b/src/sage/matrix/berlekamp_massey.py @@ -55,11 +55,11 @@ def berlekamp_massey(a): sage: from sage.matrix.berlekamp_massey import berlekamp_massey sage: berlekamp_massey([1,2,1,2,1,2]) x^2 - 1 - sage: berlekamp_massey([GF(7)(1),19,1,19]) + sage: berlekamp_massey([GF(7)(1), 19, 1, 19]) # optional - sage.rings.finite_rings x^2 + 6 sage: berlekamp_massey([2,2,1,2,1,191,393,132]) x^4 - 36727/11711*x^3 + 34213/5019*x^2 + 7024942/35133*x - 335813/1673 - sage: berlekamp_massey(prime_range(2,38)) + sage: berlekamp_massey(prime_range(2, 38)) # optional - sage.libs.pari x^6 - 14/9*x^5 - 7/9*x^4 + 157/54*x^3 - 25/27*x^2 - 73/18*x + 37/9 TESTS:: diff --git a/src/sage/matrix/compute_J_ideal.py b/src/sage/matrix/compute_J_ideal.py index 55dcb5e7072..53960564b6e 100644 --- a/src/sage/matrix/compute_J_ideal.py +++ b/src/sage/matrix/compute_J_ideal.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.pari (for charpoly, minimal_polynomial in __init__) r""" `J`-ideals of matrices @@ -540,8 +541,8 @@ def mccoy_column(self, p, t, nu): sage: x = polygen(ZZ, 'x') sage: nu_4 = x^2 + 3*x + 2 sage: g = C.mccoy_column(2, 2, nu_4) - sage: b = matrix(9, 1, (x-B).adjugate().list()) - sage: M = matrix.block([[b , -B.charpoly(x)*matrix.identity(9)]]) + sage: b = matrix(9, 1, (x - B).adjugate().list()) + sage: M = matrix.block([[b, -B.charpoly(x)*matrix.identity(9)]]) sage: (M*g % 4).is_zero() True diff --git a/src/sage/matrix/constructor.pyx b/src/sage/matrix/constructor.pyx index ae4652c45f8..0ad16955c87 100644 --- a/src/sage/matrix/constructor.pyx +++ b/src/sage/matrix/constructor.pyx @@ -98,32 +98,32 @@ def matrix(*args, **kwds): :: - sage: m = matrix(2,3); m; m.parent() + sage: m = matrix(2, 3); m; m.parent() [0 0 0] [0 0 0] Full MatrixSpace of 2 by 3 dense matrices over Integer Ring :: - sage: m = matrix(QQ,[[1,2,3],[4,5,6]]); m; m.parent() + sage: m = matrix(QQ, [[1,2,3], [4,5,6]]); m; m.parent() [1 2 3] [4 5 6] Full MatrixSpace of 2 by 3 dense matrices over Rational Field :: - sage: m = matrix(QQ, 3, 3, lambda i, j: i+j); m + sage: m = matrix(QQ, 3, 3, lambda i, j: i + j); m [0 1 2] [1 2 3] [2 3 4] - sage: m = matrix(3, lambda i,j: i-j); m + sage: m = matrix(3, lambda i, j: i - j); m [ 0 -1 -2] [ 1 0 -1] [ 2 1 0] :: - sage: matrix(QQ, 2, 3, lambda x, y: x+y) + sage: matrix(QQ, 2, 3, lambda x, y: x + y) [0 1 2] [1 2 3] sage: matrix(QQ, 5, 5, lambda x, y: (x+1) / (y+1)) @@ -172,9 +172,9 @@ def matrix(*args, **kwds): :: - sage: import numpy - sage: n = numpy.array([[1,2],[3,4]],float) - sage: m = matrix(n); m; m.parent() + sage: import numpy # optional - numpy + sage: n = numpy.array([[1,2], [3,4]], float) # optional - numpy + sage: m = matrix(n); m; m.parent() # optional - numpy [1.0 2.0] [3.0 4.0] Full MatrixSpace of 2 by 2 dense matrices over Real Double Field @@ -185,10 +185,10 @@ def matrix(*args, **kwds): sage: m = matrix(v); m; m.parent() [ 1 10 100] Full MatrixSpace of 1 by 3 dense matrices over Integer Ring - sage: m = matrix(GF(7), v); m; m.parent() + sage: m = matrix(GF(7), v); m; m.parent() # optional - sage.rings.finite_rings [1 3 2] Full MatrixSpace of 1 by 3 dense matrices over Finite Field of size 7 - sage: m = matrix(GF(7), 3, 1, v); m; m.parent() + sage: m = matrix(GF(7), 3, 1, v); m; m.parent() # optional - sage.rings.finite_rings [1] [3] [2] @@ -196,15 +196,15 @@ def matrix(*args, **kwds): :: - sage: matrix(pari.mathilbert(3)) + sage: matrix(pari.mathilbert(3)) # optional - sage.libs.pari [ 1 1/2 1/3] [1/2 1/3 1/4] [1/3 1/4 1/5] :: - sage: g = graphs.PetersenGraph() - sage: m = matrix(g); m; m.parent() + sage: g = graphs.PetersenGraph() # optional - sage.graphs + sage: m = matrix(g); m; m.parent() # optional - sage.graphs [0 1 0 0 1 1 0 0 0 0] [1 0 1 0 0 0 1 0 0 0] [0 1 0 1 0 0 0 1 0 0] @@ -278,11 +278,11 @@ def matrix(*args, **kwds): [0 0] [0 0] Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: m = matrix(QQ,2); m; m.parent() + sage: m = matrix(QQ, 2); m; m.parent() [0 0] [0 0] Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: m = matrix(QQ,2,3); m; m.parent() + sage: m = matrix(QQ, 2, 3); m; m.parent() [0 0 0] [0 0 0] Full MatrixSpace of 2 by 3 dense matrices over Rational Field @@ -323,19 +323,19 @@ def matrix(*args, **kwds): [1 2 3] [4 5 6] Full MatrixSpace of 2 by 3 dense matrices over Integer Ring - sage: m = matrix(QQ,2,[[1,2,3],[4,5,6]]); m; m.parent() + sage: m = matrix(QQ, 2, [[1,2,3],[4,5,6]]); m; m.parent() [1 2 3] [4 5 6] Full MatrixSpace of 2 by 3 dense matrices over Rational Field - sage: m = matrix(QQ,3,[[1,2,3],[4,5,6]]); m; m.parent() + sage: m = matrix(QQ, 3, [[1,2,3],[4,5,6]]); m; m.parent() Traceback (most recent call last): ... ValueError: inconsistent number of rows: should be 3 but got 2 - sage: m = matrix(QQ,2,3,[[1,2,3],[4,5,6]]); m; m.parent() + sage: m = matrix(QQ, 2, 3, [[1,2,3],[4,5,6]]); m; m.parent() [1 2 3] [4 5 6] Full MatrixSpace of 2 by 3 dense matrices over Rational Field - sage: m = matrix(QQ,2,4,[[1,2,3],[4,5,6]]); m; m.parent() + sage: m = matrix(QQ, 2, 4, [[1,2,3],[4,5,6]]); m; m.parent() Traceback (most recent call last): ... ValueError: sequence too short (expected length 4, got 3) @@ -349,19 +349,19 @@ def matrix(*args, **kwds): sage: m = matrix((1,2,3,4,5,6)); m; m.parent() [1 2 3 4 5 6] Full MatrixSpace of 1 by 6 dense matrices over Integer Ring - sage: m = matrix(QQ,[1,2,3,4,5,6]); m; m.parent() + sage: m = matrix(QQ, [1,2,3,4,5,6]); m; m.parent() [1 2 3 4 5 6] Full MatrixSpace of 1 by 6 dense matrices over Rational Field - sage: m = matrix(QQ,3,2,[1,2,3,4,5,6]); m; m.parent() + sage: m = matrix(QQ, 3, 2, [1,2,3,4,5,6]); m; m.parent() [1 2] [3 4] [5 6] Full MatrixSpace of 3 by 2 dense matrices over Rational Field - sage: m = matrix(QQ,2,4,[1,2,3,4,5,6]); m; m.parent() + sage: m = matrix(QQ, 2, 4, [1,2,3,4,5,6]); m; m.parent() Traceback (most recent call last): ... ValueError: sequence too short (expected length 8, got 6) - sage: m = matrix(QQ,5,[1,2,3,4,5,6]); m; m.parent() + sage: m = matrix(QQ, 5, [1,2,3,4,5,6]); m; m.parent() Traceback (most recent call last): ... ValueError: sequence too long (expected length 5, got more) @@ -376,47 +376,47 @@ def matrix(*args, **kwds): [0 0] [0 2] Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: m = matrix(QQ,{(1,1): 2}); m; m.parent() + sage: m = matrix(QQ, {(1,1): 2}); m; m.parent() [0 0] [0 2] Full MatrixSpace of 2 by 2 sparse matrices over Rational Field - sage: m = matrix(QQ,3,{(1,1): 2}); m; m.parent() + sage: m = matrix(QQ, 3, {(1,1): 2}); m; m.parent() [0 0 0] [0 2 0] [0 0 0] Full MatrixSpace of 3 by 3 sparse matrices over Rational Field - sage: m = matrix(QQ,3,4,{(1,1): 2}); m; m.parent() + sage: m = matrix(QQ, 3, 4, {(1,1): 2}); m; m.parent() [0 0 0 0] [0 2 0 0] [0 0 0 0] Full MatrixSpace of 3 by 4 sparse matrices over Rational Field - sage: m = matrix(QQ,2,{(1,1): 2}); m; m.parent() + sage: m = matrix(QQ, 2, {(1,1): 2}); m; m.parent() [0 0] [0 2] Full MatrixSpace of 2 by 2 sparse matrices over Rational Field - sage: m = matrix(QQ,1,{(1,1): 2}); m; m.parent() + sage: m = matrix(QQ, 1, {(1,1): 2}); m; m.parent() Traceback (most recent call last): ... IndexError: invalid row index 1 sage: m = matrix({}); m; m.parent() [] Full MatrixSpace of 0 by 0 sparse matrices over Integer Ring - sage: m = matrix(QQ,{}); m; m.parent() + sage: m = matrix(QQ, {}); m; m.parent() [] Full MatrixSpace of 0 by 0 sparse matrices over Rational Field - sage: m = matrix(QQ,2,{}); m; m.parent() + sage: m = matrix(QQ, 2, {}); m; m.parent() [0 0] [0 0] Full MatrixSpace of 2 by 2 sparse matrices over Rational Field - sage: m = matrix(QQ,2,3,{}); m; m.parent() + sage: m = matrix(QQ, 2, 3, {}); m; m.parent() [0 0 0] [0 0 0] Full MatrixSpace of 2 by 3 sparse matrices over Rational Field - sage: m = matrix(2,{}); m; m.parent() + sage: m = matrix(2, {}); m; m.parent() [0 0] [0 0] Full MatrixSpace of 2 by 2 sparse matrices over Integer Ring - sage: m = matrix(2,3,{}); m; m.parent() + sage: m = matrix(2, 3, {}); m; m.parent() [0 0 0] [0 0 0] Full MatrixSpace of 2 by 3 sparse matrices over Integer Ring @@ -429,104 +429,104 @@ def matrix(*args, **kwds): sage: m = matrix(2,0); m; m.parent() [] Full MatrixSpace of 2 by 0 dense matrices over Integer Ring - sage: m = matrix(0,[1]); m; m.parent() + sage: m = matrix(0, [1]); m; m.parent() Traceback (most recent call last): ... ValueError: sequence too long (expected length 0, got more) - sage: m = matrix(1,0,[]); m; m.parent() + sage: m = matrix(1, 0, []); m; m.parent() [] Full MatrixSpace of 1 by 0 dense matrices over Integer Ring - sage: m = matrix(0,1,[]); m; m.parent() + sage: m = matrix(0, 1, []); m; m.parent() [] Full MatrixSpace of 0 by 1 dense matrices over Integer Ring - sage: m = matrix(0,[]); m; m.parent() + sage: m = matrix(0, []); m; m.parent() [] Full MatrixSpace of 0 by 0 dense matrices over Integer Ring - sage: m = matrix(0,{}); m; m.parent() + sage: m = matrix(0, {}); m; m.parent() [] Full MatrixSpace of 0 by 0 sparse matrices over Integer Ring - sage: m = matrix(0,{(1,1):2}); m; m.parent() + sage: m = matrix(0, {(1,1): 2}); m; m.parent() Traceback (most recent call last): ... IndexError: invalid row index 1 - sage: m = matrix(2,0,{(1,1):2}); m; m.parent() + sage: m = matrix(2, 0, {(1,1): 2}); m; m.parent() Traceback (most recent call last): ... IndexError: invalid column index 1 Check conversion from numpy:: - sage: import numpy - sage: n = numpy.array([[complex(0,1),complex(0,2)],[3,4]],complex) - sage: m = matrix(n); m; m.parent() + sage: import numpy # optional - numpy + sage: n = numpy.array([[complex(0,1),complex(0,2)], [3,4]], complex) # optional - numpy + sage: m = matrix(n); m; m.parent() # optional - numpy [1.0*I 2.0*I] [ 3.0 4.0] Full MatrixSpace of 2 by 2 dense matrices over Complex Double Field - sage: n = numpy.array([[1,2],[3,4]],'int32') - sage: m = matrix(n); m; m.parent() + sage: n = numpy.array([[1,2], [3,4]], 'int32') # optional - numpy + sage: m = matrix(n); m; m.parent() # optional - numpy [1 2] [3 4] Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: n = numpy.array([[1,2,3],[4,5,6],[7,8,9]],'float32') - sage: m = matrix(n); m; m.parent() + sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]], 'float32') # optional - numpy + sage: m = matrix(n); m; m.parent() # optional - numpy [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Real Double Field - sage: n = numpy.matrix([[1,2,3],[4,5,6],[7,8,9]],'float64') - sage: m = matrix(n); m; m.parent() + sage: n = numpy.matrix([[1,2,3], [4,5,6], [7,8,9]], 'float64') # optional - numpy + sage: m = matrix(n); m; m.parent() # optional - numpy [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Real Double Field - sage: n = numpy.array([[1,2,3],[4,5,6],[7,8,9]],'complex64') - sage: m = matrix(n); m; m.parent() + sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]], 'complex64') # optional - numpy + sage: m = matrix(n); m; m.parent() # optional - numpy [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Complex Double Field - sage: n = numpy.matrix([[1,2,3],[4,5,6],[7,8,9]],'complex128') - sage: m = matrix(n); m; m.parent() + sage: n = numpy.matrix([[1,2,3], [4,5,6], [7,8,9]], 'complex128') # optional - numpy + sage: m = matrix(n); m; m.parent() # optional - numpy [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Complex Double Field - sage: a = matrix([[1,2],[3,4]]) - sage: b = matrix(a.numpy()); b + sage: a = matrix([[1,2], [3,4]]) + sage: b = matrix(a.numpy()); b # optional - numpy [1 2] [3 4] - sage: a == b + sage: a == b # optional - numpy True - sage: c = matrix(a.numpy('float32')); c + sage: c = matrix(a.numpy('float32')); c # optional - numpy [1.0 2.0] [3.0 4.0] - sage: matrix(numpy.array([[5]])) + sage: matrix(numpy.array([[5]])) # optional - numpy [5] - sage: matrix(numpy.matrix([[5]])) + sage: matrix(numpy.matrix([[5]])) # optional - numpy [5] A ring and a numpy array:: - sage: n = numpy.array([[1,2,3],[4,5,6],[7,8,9]],'float32') - sage: m = matrix(ZZ, n); m; m.parent() + sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]],'float32') # optional - numpy + sage: m = matrix(ZZ, n); m; m.parent() # optional - numpy [1 2 3] [4 5 6] [7 8 9] Full MatrixSpace of 3 by 3 dense matrices over Integer Ring - sage: n = matrix(QQ, 2, 2, [1, 1/2, 1/3, 1/4]).numpy(); n + sage: n = matrix(QQ, 2, 2, [1, 1/2, 1/3, 1/4]).numpy(); n # optional - numpy array([[1. , 0.5 ], [0.33333333, 0.25 ]]) - sage: matrix(QQ, n) + sage: matrix(QQ, n) # optional - numpy [ 1 1/2] [1/3 1/4] The dimensions of a matrix may be given as numpy types:: - sage: matrix(numpy.int32(2), numpy.int32(3)) + sage: matrix(numpy.int32(2), numpy.int32(3)) # optional - numpy [0 0 0] [0 0 0] - sage: matrix(nrows=numpy.int32(2), ncols=numpy.int32(3)) + sage: matrix(nrows=numpy.int32(2), ncols=numpy.int32(3)) # optional - numpy [0 0 0] [0 0 0] @@ -542,10 +542,11 @@ def matrix(*args, **kwds): sage: v = vector(ZZ, [1, 10, 100]) sage: m = matrix(ZZ['x'], v); m; m.parent() [ 1 10 100] - Full MatrixSpace of 1 by 3 dense matrices over Univariate Polynomial Ring in x over Integer Ring + Full MatrixSpace of 1 by 3 dense matrices + over Univariate Polynomial Ring in x over Integer Ring sage: matrix(ZZ, 10, 10, range(100)).parent() Full MatrixSpace of 10 by 10 dense matrices over Integer Ring - sage: m = matrix(GF(7), [[1/3,2/3,1/2], [3/4,4/5,7]]); m; m.parent() + sage: m = matrix(GF(7), [[1/3,2/3,1/2], [3/4,4/5,7]]); m; m.parent() # optional - sage.rings.finite_rings [5 3 4] [6 5 0] Full MatrixSpace of 2 by 3 dense matrices over Finite Field of size 7 @@ -553,7 +554,7 @@ def matrix(*args, **kwds): [ 1.0 2.0 3.0] [ 2.0 1.0 + 2.0*I 3.0] Full MatrixSpace of 2 by 3 dense matrices over Complex Double Field - sage: m = matrix(3,3,1/2); m; m.parent() + sage: m = matrix(3, 3, 1/2); m; m.parent() [1/2 0 0] [ 0 1/2 0] [ 0 0 1/2] @@ -566,7 +567,7 @@ def matrix(*args, **kwds): Traceback (most recent call last): ... TypeError: 'sage.rings.integer.Integer' object is not iterable - sage: matrix(vector(RR,[1,2,3])).parent() + sage: matrix(vector(RR, [1,2,3])).parent() Full MatrixSpace of 1 by 3 dense matrices over Real Field with 53 bits of precision Check :trac:`10158`:: diff --git a/src/sage/matrix/echelon_matrix.pyx b/src/sage/matrix/echelon_matrix.pyx index 3fc43b485ca..6a962fd2f82 100644 --- a/src/sage/matrix/echelon_matrix.pyx +++ b/src/sage/matrix/echelon_matrix.pyx @@ -48,8 +48,8 @@ def reduced_echelon_matrix_iterator(K, k, n, bint sparse=False, bint copy=True, EXAMPLES:: sage: from sage.matrix.echelon_matrix import reduced_echelon_matrix_iterator - sage: it = reduced_echelon_matrix_iterator(GF(2),2,3) - sage: for m in it: + sage: it = reduced_echelon_matrix_iterator(GF(2), 2, 3) # optional - sage.rings.finite_rings + sage: for m in it: # optional - sage.rings.finite_rings ....: print(m) ....: print(m.pivots()) ....: print("*******") @@ -87,21 +87,21 @@ def reduced_echelon_matrix_iterator(K, k, n, bint sparse=False, bint copy=True, Testing cardinalities:: sage: q = 71 - sage: F = GF(q) - sage: len(list(reduced_echelon_matrix_iterator(F, 1, 3, copy=False))) == q**2+q+1 + sage: F = GF(q) # optional - sage.rings.finite_rings + sage: len(list(reduced_echelon_matrix_iterator(F, 1, 3, copy=False))) == q**2+q+1 # optional - sage.rings.finite_rings True - sage: len(list(reduced_echelon_matrix_iterator(F, 2, 3, copy=False))) == q**2+q+1 + sage: len(list(reduced_echelon_matrix_iterator(F, 2, 3, copy=False))) == q**2+q+1 # optional - sage.rings.finite_rings True Testing options:: - sage: it = reduced_echelon_matrix_iterator(GF(4,'z'), 2, 4, copy=False) - sage: next(it) is next(it) + sage: it = reduced_echelon_matrix_iterator(GF(4, 'z'), 2, 4, copy=False) # optional - sage.rings.finite_rings + sage: next(it) is next(it) # optional - sage.rings.finite_rings True - sage: for a in it: pass + sage: for a in it: pass # optional - sage.rings.finite_rings - sage: it = reduced_echelon_matrix_iterator(GF(4,'z'), 2, 4, set_immutable=True) - sage: all(a.is_immutable() and a.echelon_form() == a for a in it) + sage: it = reduced_echelon_matrix_iterator(GF(4, 'z'), 2, 4, set_immutable=True) # optional - sage.rings.finite_rings + sage: all(a.is_immutable() and a.echelon_form() == a for a in it) # optional - sage.rings.finite_rings True """ cdef Matrix m0,m,mm diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index d3a5fee358e..bfacad13d55 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -8,7 +8,7 @@ Base class for matrices, part 0 EXAMPLES:: - sage: matrix(2,[1,2,3,4]) + sage: matrix(2, [1,2,3,4]) [1 2] [3 4] """ @@ -469,7 +469,8 @@ cdef class Matrix(sage.structure.element.Matrix): sage: A[0,0] = 10 Traceback (most recent call last): ... - ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M). + ValueError: matrix is immutable; please change a copy instead + (i.e., use copy(M) to change a copy of M). sage: hash(A) #random 12 sage: v = {A:1}; v @@ -545,11 +546,11 @@ cdef class Matrix(sage.structure.element.Matrix): TESTS:: - sage: class MyAlgebraicNumber(sage.rings.qqbar.AlgebraicNumber): + sage: class MyAlgebraicNumber(sage.rings.qqbar.AlgebraicNumber): # optional - sage.rings.number_fields ....: def __bool__(self): ....: raise ValueError - sage: mat = matrix(1,1,MyAlgebraicNumber(1)) - sage: bool(mat) + sage: mat = matrix(1, 1, MyAlgebraicNumber(1)) # optional - sage.rings.number_fields + sage: bool(mat) # optional - sage.rings.number_fields Traceback (most recent call last): ... ValueError @@ -677,7 +678,7 @@ cdef class Matrix(sage.structure.element.Matrix): ... TypeError: index must be an integer - sage: m=[(1, -2, -1, -1,9), (1, 8, 6, 2,2), (1, 1, -1, 1,4), (-1, 2, -2, -1,4)];M= matrix(m) + sage: m = [(1, -2, -1, -1,9), (1, 8, 6, 2,2), (1, 1, -1, 1,4), (-1, 2, -2, -1,4)]; M = matrix(m) sage: M [ 1 -2 -1 -1 9] [ 1 8 6 2 2] @@ -909,16 +910,18 @@ cdef class Matrix(sage.structure.element.Matrix): Check that submatrices with a specified implementation have the same implementation:: - sage: M = MatrixSpace(GF(2), 3, 3, implementation='generic') - sage: m = M(range(9)) - sage: type(m) + sage: M = MatrixSpace(GF(2), 3, 3, implementation='generic') # optional - sage.libs.pari + sage: m = M(range(9)) # optional - sage.libs.pari + sage: type(m) # optional - sage.libs.pari - sage: parent(m) - Full MatrixSpace of 3 by 3 dense matrices over Finite Field of size 2 (using Matrix_generic_dense) - sage: type(m[:2,:2]) + sage: parent(m) # optional - sage.libs.pari + Full MatrixSpace of 3 by 3 dense matrices + over Finite Field of size 2 (using Matrix_generic_dense) + sage: type(m[:2,:2]) # optional - sage.libs.pari - sage: parent(m[:2,:2]) - Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 2 (using Matrix_generic_dense) + sage: parent(m[:2,:2]) # optional - sage.libs.pari + Full MatrixSpace of 2 by 2 dense matrices + over Finite Field of size 2 (using Matrix_generic_dense) """ cdef list row_list cdef list col_list @@ -1620,7 +1623,7 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: m=matrix(QQ,2,[1,2,3,4]) + sage: m = matrix(QQ, 2, [1,2,3,4]) sage: m.base_ring() Rational Field """ @@ -1638,13 +1641,14 @@ cdef class Matrix(sage.structure.element.Matrix): sage: A = Matrix(QQ, 2, 2, [1/2, 1/3, 1/3, 1/4]) sage: A.parent() - Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: A.change_ring(GF(25,'a')) + Full MatrixSpace of 2 by 2 dense matrices over Rational Field + sage: A.change_ring(GF(25,'a')) # optional - sage.rings.finite_rings [3 2] [2 4] - sage: A.change_ring(GF(25,'a')).parent() - Full MatrixSpace of 2 by 2 dense matrices over Finite Field in a of size 5^2 - sage: A.change_ring(ZZ) + sage: A.change_ring(GF(25,'a')).parent() # optional - sage.rings.finite_rings + Full MatrixSpace of 2 by 2 dense matrices + over Finite Field in a of size 5^2 + sage: A.change_ring(ZZ) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: matrix has denominators so can...t change to ZZ @@ -1655,7 +1659,7 @@ cdef class Matrix(sage.structure.element.Matrix): [1/2 1/3] [-------] [1/3 1/4] - sage: A.change_ring(GF(25,'a')) + sage: A.change_ring(GF(25,'a')) # optional - sage.rings.finite_rings [3 2] [---] [2 4] @@ -2363,17 +2367,17 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: f(x,y) = x^2+y - sage: m = matrix([[f,f*f],[f^3,f^4]]); m + sage: f(x,y) = x^2 + y # optional - sage.symbolic + sage: m = matrix([[f, f*f], [f^3, f^4]]); m # optional - sage.symbolic [ (x, y) |--> x^2 + y (x, y) |--> (x^2 + y)^2] [(x, y) |--> (x^2 + y)^3 (x, y) |--> (x^2 + y)^4] - sage: m(1,2) + sage: m(1, 2) # optional - sage.symbolic [ 3 9] [27 81] - sage: m(y=2,x=1) + sage: m(y=2, x=1) # optional - sage.symbolic [ 3 9] [27 81] - sage: m(2,1) + sage: m(2, 1) # optional - sage.symbolic [ 5 25] [125 625] """ @@ -2550,7 +2554,7 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES: We create a matrix:: - sage: M = matrix(ZZ,[[1,0,0,0,0],[0,2,0,0,0],[0,0,3,0,0],[0,0,0,4,0],[0,0,0,0,5]]) + sage: M = matrix(ZZ, [[1,0,0,0,0],[0,2,0,0,0],[0,0,3,0,0],[0,0,0,4,0],[0,0,0,0,5]]) sage: M [1 0 0 0 0] [0 2 0 0 0] @@ -2561,12 +2565,12 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M`` with it:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) - sage: sigma, tau = G.gens() - sage: sigma + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups + sage: sigma, tau = G.gens() # optional - sage.groups + sage: sigma # optional - sage.groups (1,2,3)(4,5) - sage: M.permute_columns(sigma) - sage: M + sage: M.permute_columns(sigma) # optional - sage.groups + sage: M # optional - sage.groups [0 0 1 0 0] [2 0 0 0 0] [0 3 0 0 0] @@ -2601,7 +2605,7 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES: We create some matrix:: - sage: M = matrix(ZZ,[[1,0,0,0,0],[0,2,0,0,0],[0,0,3,0,0],[0,0,0,4,0],[0,0,0,0,5]]) + sage: M = matrix(ZZ, [[1,0,0,0,0],[0,2,0,0,0],[0,0,3,0,0],[0,0,0,4,0],[0,0,0,0,5]]) sage: M [1 0 0 0 0] [0 2 0 0 0] @@ -2612,11 +2616,11 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M``:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) - sage: sigma, tau = G.gens() - sage: sigma + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups + sage: sigma, tau = G.gens() # optional - sage.groups + sage: sigma # optional - sage.groups (1,2,3)(4,5) - sage: M.with_permuted_columns(sigma) + sage: M.with_permuted_columns(sigma) # optional - sage.groups [0 0 1 0 0] [2 0 0 0 0] [0 3 0 0 0] @@ -2646,8 +2650,8 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES: We create a rational matrix:: - sage: M = MatrixSpace(QQ,3,3) - sage: A = M([1,9,-7,4/5,4,3,6,4,3]) + sage: M = MatrixSpace(QQ, 3, 3) + sage: A = M([1,9,-7, 4/5,4,3, 6,4,3]) sage: A [ 1 9 -7] [4/5 4 3] @@ -2656,7 +2660,7 @@ cdef class Matrix(sage.structure.element.Matrix): Since the first row is numbered zero, this swaps the first and third rows:: - sage: A.swap_rows(0,2); A + sage: A.swap_rows(0, 2); A [ 6 4 3] [4/5 4 3] [ 1 9 -7] @@ -2733,7 +2737,7 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES: We create a matrix:: - sage: M = matrix(ZZ,[[1,0,0,0,0],[0,2,0,0,0],[0,0,3,0,0],[0,0,0,4,0],[0,0,0,0,5]]) + sage: M = matrix(ZZ, [[1,0,0,0,0],[0,2,0,0,0],[0,0,3,0,0],[0,0,0,4,0],[0,0,0,0,5]]) sage: M [1 0 0 0 0] [0 2 0 0 0] @@ -2743,12 +2747,12 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M``:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) - sage: sigma, tau = G.gens() - sage: sigma + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups + sage: sigma, tau = G.gens() # optional - sage.groups + sage: sigma # optional - sage.groups (1,2,3)(4,5) - sage: M.permute_rows(sigma) - sage: M + sage: M.permute_rows(sigma) # optional - sage.groups + sage: M # optional - sage.groups [0 2 0 0 0] [0 0 3 0 0] [1 0 0 0 0] @@ -2782,7 +2786,7 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES: We create a matrix:: - sage: M = matrix(ZZ,[[1,0,0,0,0],[0,2,0,0,0],[0,0,3,0,0],[0,0,0,4,0],[0,0,0,0,5]]) + sage: M = matrix(ZZ, [[1,0,0,0,0],[0,2,0,0,0],[0,0,3,0,0],[0,0,0,4,0],[0,0,0,0,5]]) sage: M [1 0 0 0 0] [0 2 0 0 0] @@ -2792,11 +2796,11 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M``:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) - sage: sigma, tau = G.gens() - sage: sigma + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups + sage: sigma, tau = G.gens() # optional - sage.groups + sage: sigma # optional - sage.groups (1,2,3)(4,5) - sage: M.with_permuted_rows(sigma) + sage: M.with_permuted_rows(sigma) # optional - sage.groups [0 2 0 0 0] [0 0 3 0 0] [1 0 0 0 0] @@ -2840,7 +2844,7 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES: We create a matrix:: - sage: M = matrix(ZZ,[[1,0,0,0,0],[0,2,0,0,0],[0,0,3,0,0],[0,0,0,4,0],[0,0,0,0,5]]) + sage: M = matrix(ZZ, [[1,0,0,0,0],[0,2,0,0,0],[0,0,3,0,0],[0,0,0,4,0],[0,0,0,0,5]]) sage: M [1 0 0 0 0] [0 2 0 0 0] @@ -2850,12 +2854,12 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M``:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) - sage: sigma, tau = G.gens() - sage: sigma + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups + sage: sigma, tau = G.gens() # optional - sage.groups + sage: sigma # optional - sage.groups (1,2,3)(4,5) - sage: M.permute_rows_and_columns(sigma,tau) - sage: M + sage: M.permute_rows_and_columns(sigma,tau) # optional - sage.groups + sage: M # optional - sage.groups [2 0 0 0 0] [0 3 0 0 0] [0 0 0 0 1] @@ -2885,7 +2889,7 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES: We create a matrix:: - sage: M = matrix(ZZ,[[1,0,0,0,0],[0,2,0,0,0],[0,0,3,0,0],[0,0,0,4,0],[0,0,0,0,5]]) + sage: M = matrix(ZZ, [[1,0,0,0,0],[0,2,0,0,0],[0,0,3,0,0],[0,0,0,4,0],[0,0,0,0,5]]) sage: M [1 0 0 0 0] [0 2 0 0 0] @@ -2895,11 +2899,11 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M``:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) - sage: sigma, tau = G.gens() - sage: sigma + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups + sage: sigma, tau = G.gens() # optional - sage.groups + sage: sigma # optional - sage.groups (1,2,3)(4,5) - sage: M.with_permuted_rows_and_columns(sigma,tau) + sage: M.with_permuted_rows_and_columns(sigma,tau) # optional - sage.groups [2 0 0 0 0] [0 3 0 0 0] [0 0 0 0 1] @@ -2933,10 +2937,11 @@ cdef class Matrix(sage.structure.element.Matrix): If not, we get an error message:: - sage: a.add_multiple_of_row(1,0,SR.I()) + sage: a.add_multiple_of_row(1, 0, SR.I()) # optional - sage.symbolic Traceback (most recent call last): ... - TypeError: Multiplying row by Symbolic Ring element cannot be done over Rational Field, use change_ring or with_added_multiple_of_row instead. + TypeError: Multiplying row by Symbolic Ring element cannot be done over + Rational Field, use change_ring or with_added_multiple_of_row instead. """ self.check_row_bounds_and_mutability(i,j) try: @@ -3017,10 +3022,11 @@ cdef class Matrix(sage.structure.element.Matrix): If not, we get an error message:: - sage: a.add_multiple_of_column(1,0,SR.I()) + sage: a.add_multiple_of_column(1, 0, SR.I()) # optional - sage.symbolic Traceback (most recent call last): ... - TypeError: Multiplying column by Symbolic Ring element cannot be done over Rational Field, use change_ring or with_added_multiple_of_column instead. + TypeError: Multiplying column by Symbolic Ring element cannot be done over + Rational Field, use change_ring or with_added_multiple_of_column instead. """ self.check_column_bounds_and_mutability(i,j) try: @@ -3041,10 +3047,10 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES: We add -1 times the third column to the second column of an integer matrix, remembering to start numbering cols at zero:: - sage: a = matrix(ZZ,2,3,range(6)); a + sage: a = matrix(ZZ, 2, 3, range(6)); a [0 1 2] [3 4 5] - sage: b = a.with_added_multiple_of_column(1,2,-1); b + sage: b = a.with_added_multiple_of_column(1, 2, -1); b [ 0 -1 2] [ 3 -1 5] @@ -3057,7 +3063,7 @@ cdef class Matrix(sage.structure.element.Matrix): Adding a rational multiple is okay, and reassigning a variable is okay:: - sage: a = a.with_added_multiple_of_column(0,1,1/3); a + sage: a = a.with_added_multiple_of_column(0, 1, 1/3); a [ 1/3 1 2] [13/3 4 5] """ @@ -3094,11 +3100,11 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES: We rescale the second row of a matrix over the rational numbers:: - sage: a = matrix(QQ,3,range(6)); a + sage: a = matrix(QQ, 3, range(6)); a [0 1] [2 3] [4 5] - sage: a.rescale_row(1,1/2); a + sage: a.rescale_row(1, 1/2); a [ 0 1] [ 1 3/2] [ 4 5] @@ -3106,11 +3112,11 @@ cdef class Matrix(sage.structure.element.Matrix): We rescale the second row of a matrix over a polynomial ring:: sage: R. = QQ[] - sage: a = matrix(R,3,[1,x,x^2,x^3,x^4,x^5]);a + sage: a = matrix(R, 3, [1,x,x^2,x^3,x^4,x^5]); a [ 1 x] [x^2 x^3] [x^4 x^5] - sage: a.rescale_row(1,1/2); a + sage: a.rescale_row(1, 1/2); a [ 1 x] [1/2*x^2 1/2*x^3] [ x^4 x^5] @@ -3118,13 +3124,14 @@ cdef class Matrix(sage.structure.element.Matrix): We try and fail to rescale a matrix over the integers by a non-integer:: - sage: a = matrix(ZZ,2,3,[0,1,2, 3,4,4]); a + sage: a = matrix(ZZ, 2, 3, [0,1,2, 3,4,4]); a [0 1 2] [3 4 4] - sage: a.rescale_row(1,1/2) + sage: a.rescale_row(1, 1/2) Traceback (most recent call last): ... - TypeError: Rescaling row by Rational Field element cannot be done over Integer Ring, use change_ring or with_rescaled_row instead. + TypeError: Rescaling row by Rational Field element cannot be done + over Integer Ring, use change_ring or with_rescaled_row instead. To rescale the matrix by 1/2, you must change the base ring to the rationals:: @@ -3132,7 +3139,7 @@ cdef class Matrix(sage.structure.element.Matrix): sage: a = a.change_ring(QQ); a [0 1 2] [3 4 4] - sage: a.rescale_col(1,1/2); a + sage: a.rescale_col(1, 1/2); a [ 0 1/2 2] [ 3 2 4] """ @@ -3155,11 +3162,11 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES: We rescale the second row of a matrix over the integers:: - sage: a = matrix(ZZ,3,2,range(6)); a + sage: a = matrix(ZZ, 3, 2, range(6)); a [0 1] [2 3] [4 5] - sage: b = a.with_rescaled_row(1,-2); b + sage: b = a.with_rescaled_row(1, -2); b [ 0 1] [-4 -6] [ 4 5] @@ -3174,7 +3181,7 @@ cdef class Matrix(sage.structure.element.Matrix): Adding a rational multiple is okay, and reassigning a variable is okay:: - sage: a = a.with_rescaled_row(2,1/3); a + sage: a = a.with_rescaled_row(2, 1/3); a [ 0 1] [ 2 3] [4/3 5/3] @@ -3212,33 +3219,34 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES: We rescale the last column of a matrix over the rational numbers:: - sage: a = matrix(QQ,2,3,range(6)); a + sage: a = matrix(QQ, 2, 3, range(6)); a [0 1 2] [3 4 5] - sage: a.rescale_col(2,1/2); a + sage: a.rescale_col(2, 1/2); a [ 0 1 1] [ 3 4 5/2] sage: R. = QQ[] We rescale the last column of a matrix over a polynomial ring:: - sage: a = matrix(R,2,3,[1,x,x^2,x^3,x^4,x^5]); a + sage: a = matrix(R, 2, 3, [1,x,x^2,x^3,x^4,x^5]); a [ 1 x x^2] [x^3 x^4 x^5] - sage: a.rescale_col(2,1/2); a + sage: a.rescale_col(2, 1/2); a [ 1 x 1/2*x^2] [ x^3 x^4 1/2*x^5] We try and fail to rescale a matrix over the integers by a non-integer:: - sage: a = matrix(ZZ,2,3,[0,1,2, 3,4,4]); a + sage: a = matrix(ZZ, 2, 3, [0,1,2, 3,4,4]); a [0 1 2] [3 4 4] - sage: a.rescale_col(2,1/2) + sage: a.rescale_col(2, 1/2) Traceback (most recent call last): ... - TypeError: Rescaling column by Rational Field element cannot be done over Integer Ring, use change_ring or with_rescaled_col instead. + TypeError: Rescaling column by Rational Field element cannot be done over + Integer Ring, use change_ring or with_rescaled_col instead. To rescale the matrix by 1/2, you must change the base ring to the rationals:: @@ -3270,10 +3278,10 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES: We rescale the last column of a matrix over the integers:: - sage: a = matrix(ZZ,2,3,range(6)); a + sage: a = matrix(ZZ, 2, 3, range(6)); a [0 1 2] [3 4 5] - sage: b = a.with_rescaled_col(2,-2); b + sage: b = a.with_rescaled_col(2, -2); b [ 0 1 -4] [ 3 4 -10] @@ -3286,7 +3294,7 @@ cdef class Matrix(sage.structure.element.Matrix): Adding a rational multiple is okay, and reassigning a variable is okay:: - sage: a = a.with_rescaled_col(1,1/3); a + sage: a = a.with_rescaled_col(1, 1/3); a [ 0 1/3 2] [ 3 4/3 5] """ @@ -3311,10 +3319,10 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES: We change the second row to -3 times the first row:: - sage: a = matrix(ZZ,2,3,range(6)); a + sage: a = matrix(ZZ, 2, 3, range(6)); a [0 1 2] [3 4 5] - sage: a.set_row_to_multiple_of_row(1,0,-3) + sage: a.set_row_to_multiple_of_row(1, 0, -3) sage: a [ 0 1 2] [ 0 -3 -6] @@ -3322,10 +3330,11 @@ cdef class Matrix(sage.structure.element.Matrix): If we try to multiply a row by a rational number, we get an error message:: - sage: a.set_row_to_multiple_of_row(1,0,1/2) + sage: a.set_row_to_multiple_of_row(1, 0, 1/2) Traceback (most recent call last): ... - TypeError: Multiplying row by Rational Field element cannot be done over Integer Ring, use change_ring or with_row_set_to_multiple_of_row instead. + TypeError: Multiplying row by Rational Field element cannot be done over + Integer Ring, use change_ring or with_row_set_to_multiple_of_row instead. """ self.check_row_bounds_and_mutability(i,j) cdef Py_ssize_t n @@ -3342,10 +3351,10 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES: We change the second row to -3 times the first row:: - sage: a = matrix(ZZ,2,3,range(6)); a + sage: a = matrix(ZZ, 2, 3, range(6)); a [0 1 2] [3 4 5] - sage: b = a.with_row_set_to_multiple_of_row(1,0,-3); b + sage: b = a.with_row_set_to_multiple_of_row(1, 0, -3); b [ 0 1 2] [ 0 -3 -6] @@ -3358,7 +3367,7 @@ cdef class Matrix(sage.structure.element.Matrix): Adding a rational multiple is okay, and reassigning a variable is okay:: - sage: a = a.with_row_set_to_multiple_of_row(1,0,1/2); a + sage: a = a.with_row_set_to_multiple_of_row(1, 0, 1/2); a [ 0 1 2] [ 0 1/2 1] """ @@ -3389,10 +3398,10 @@ cdef class Matrix(sage.structure.element.Matrix): :: - sage: a = matrix(ZZ,2,3,range(6)); a + sage: a = matrix(ZZ, 2, 3, range(6)); a [0 1 2] [3 4 5] - sage: a.set_col_to_multiple_of_col(1,0,-3) + sage: a.set_col_to_multiple_of_col(1, 0, -3) sage: a [ 0 0 2] [ 3 -9 5] @@ -3400,7 +3409,7 @@ cdef class Matrix(sage.structure.element.Matrix): If we try to multiply a column by a rational number, we get an error message:: - sage: a.set_col_to_multiple_of_col(1,0,1/2) + sage: a.set_col_to_multiple_of_col(1, 0, 1/2) Traceback (most recent call last): ... TypeError: Multiplying column by Rational Field element cannot be done over Integer Ring, use change_ring or with_col_set_to_multiple_of_col instead. @@ -3425,10 +3434,10 @@ cdef class Matrix(sage.structure.element.Matrix): :: - sage: a = matrix(ZZ,2,3,range(6)); a + sage: a = matrix(ZZ, 2, 3, range(6)); a [0 1 2] [3 4 5] - sage: b = a.with_col_set_to_multiple_of_col(1,0,-3); b + sage: b = a.with_col_set_to_multiple_of_col(1, 0, -3); b [ 0 0 2] [ 3 -9 5] @@ -3441,7 +3450,7 @@ cdef class Matrix(sage.structure.element.Matrix): Adding a rational multiple is okay, and reassigning a variable is okay:: - sage: a = a.with_col_set_to_multiple_of_col(1,0,1/2); a + sage: a = a.with_col_set_to_multiple_of_col(1, 0, 1/2); a [ 0 0 2] [ 3 3/2 5] """ @@ -3592,7 +3601,7 @@ cdef class Matrix(sage.structure.element.Matrix): Mutation of the B-matrix of the quiver of type `A_3`:: - sage: M = matrix(ZZ,3,[0,1,0,-1,0,-1,0,1,0]); M + sage: M = matrix(ZZ, 3, [0,1,0,-1,0,-1,0,1,0]); M [ 0 1 0] [-1 0 -1] [ 0 1 0] @@ -3607,7 +3616,7 @@ cdef class Matrix(sage.structure.element.Matrix): [-1 0 1] [ 1 -1 0] - sage: M = matrix(ZZ,6,[0,1,0,-1,0,-1,0,1,0,1,0,0,0,1,0,0,0,1]); M + sage: M = matrix(ZZ, 6, [0,1,0,-1,0,-1,0,1,0,1,0,0,0,1,0,0,0,1]); M [ 0 1 0] [-1 0 -1] [ 0 1 0] @@ -3675,12 +3684,12 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: M = matrix(ZZ,3,[0,1,0,-1,0,-1,0,1,0]); M + sage: M = matrix(ZZ, 3, [0,1,0,-1,0,-1,0,1,0]); M [ 0 1 0] [-1 0 -1] [ 0 1 0] - sage: M._travel_column({0:1},0,-1,True) + sage: M._travel_column({0: 1}, 0, -1, True) [1] """ cdef list L = [] @@ -3789,7 +3798,7 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: a = matrix(ZZ,2,3,range(6)); a + sage: a = matrix(ZZ, 2, 3, range(6)); a [0 1 2] [3 4 5] sage: a.linear_combination_of_rows([1,2]) @@ -3810,7 +3819,7 @@ cdef class Matrix(sage.structure.element.Matrix): We check that a matrix with no rows behaves properly. :: - sage: matrix(QQ,0,2).linear_combination_of_rows([]) + sage: matrix(QQ, 0, 2).linear_combination_of_rows([]) (0, 0) The object returned is a vector, or a free module element. :: @@ -3830,7 +3839,7 @@ cdef class Matrix(sage.structure.element.Matrix): The length of v can be less than the number of rows, but not greater. :: - sage: A = matrix(QQ,3,4,range(12)) + sage: A = matrix(QQ, 3, 4, range(12)) sage: A.linear_combination_of_rows([2,3]) (12, 17, 22, 27) sage: A.linear_combination_of_rows([1,2,3,4]) @@ -3866,7 +3875,7 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: a = matrix(ZZ,2,3,range(6)); a + sage: a = matrix(ZZ, 2, 3, range(6)); a [0 1 2] [3 4 5] sage: a.linear_combination_of_columns([1,1,1]) @@ -3887,7 +3896,7 @@ cdef class Matrix(sage.structure.element.Matrix): We check that a matrix with no columns behaves properly. :: - sage: matrix(QQ,2,0).linear_combination_of_columns([]) + sage: matrix(QQ, 2, 0).linear_combination_of_columns([]) (0, 0) The object returned is a vector, or a free module element. :: @@ -3907,7 +3916,7 @@ cdef class Matrix(sage.structure.element.Matrix): The length of v can be less than the number of columns, but not greater. :: - sage: A = matrix(QQ,3,5, range(15)) + sage: A = matrix(QQ, 3, 5, range(15)) sage: A.linear_combination_of_columns([1,-2,3,-4]) (-8, -18, -28) sage: A.linear_combination_of_columns([1,2,3,4,5,6]) @@ -3935,15 +3944,15 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: m=Matrix(QQ,2,range(0,4)) + sage: m = Matrix(QQ, 2, range(0,4)) sage: m.is_symmetric() False - sage: m=Matrix(QQ,2,(1,1,1,1,1,1)) + sage: m = Matrix(QQ, 2, (1,1,1,1,1,1)) sage: m.is_symmetric() False - sage: m=Matrix(QQ,1,(2,)) + sage: m = Matrix(QQ, 1, (2,)) sage: m.is_symmetric() True @@ -3989,44 +3998,44 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: A = matrix(QQbar, [[ 1 + I, 1 - 6*I, -1 - I], + sage: A = matrix(QQbar, [[ 1 + I, 1 - 6*I, -1 - I], # optional - sage.rings.number_field ....: [-3 - I, -4*I, -2], ....: [-1 + I, -2 - 8*I, 2 + I]]) - sage: A._is_hermitian(skew=False, tolerance=0) + sage: A._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field False - sage: B = A*A.conjugate_transpose() - sage: B._is_hermitian(skew=False, tolerance=0) + sage: B = A*A.conjugate_transpose() # optional - sage.rings.number_field + sage: B._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field True Sage has several fields besides the entire complex numbers where conjugation is non-trivial:: - sage: F. = QuadraticField(-7) - sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], + sage: F. = QuadraticField(-7) # optional - sage.rings.number_field + sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], # optional - sage.rings.number_field ....: [-2*b - 3, -3*b + 2, -2*b], ....: [ b + 1, 0, -2]]) - sage: C._is_hermitian(skew=False, tolerance=0) + sage: C._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field False - sage: C = C*C.conjugate_transpose() - sage: C._is_hermitian(skew=False, tolerance=0) + sage: C = C*C.conjugate_transpose() # optional - sage.rings.number_field + sage: C._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field True A matrix that is nearly Hermitian, but for a non-real diagonal entry:: - sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], + sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], # optional - sage.rings.number_field ....: [ 2+I, 3+I, 2-6*I], ....: [1-4*I, 2+6*I, 5]]) - sage: A._is_hermitian(skew=False, tolerance=0) + sage: A._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field False - sage: A[1,1] = 132 - sage: A._is_hermitian(skew=False, tolerance=0) + sage: A[1, 1] = 132 # optional - sage.rings.number_field + sage: A._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field True Rectangular matrices are never Hermitian:: - sage: A = matrix(QQbar, 3, 4) - sage: A._is_hermitian(skew=False, tolerance=0) + sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field + sage: A._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field False A square, empty matrix is trivially Hermitian:: @@ -4036,10 +4045,11 @@ cdef class Matrix(sage.structure.element.Matrix): True A matrix that is skew-Hermitian:: - sage: A = matrix(QQbar, [[-I, 2+I], [-2+I, 0]]) - sage: A._is_hermitian(skew=False, tolerance=0) + + sage: A = matrix(QQbar, [[-I, 2+I], [-2+I, 0]]) # optional - sage.rings.number_field + sage: A._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field False - sage: A._is_hermitian(skew=True, tolerance=0) + sage: A._is_hermitian(skew=True, tolerance=0) # optional - sage.rings.number_field True """ key = ("_is_hermitian", skew, tolerance) @@ -4131,44 +4141,44 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: A = matrix(QQbar, [[ 1 + I, 1 - 6*I, -1 - I], + sage: A = matrix(QQbar, [[ 1 + I, 1 - 6*I, -1 - I], # optional - sage.rings.number_field ....: [-3 - I, -4*I, -2], ....: [-1 + I, -2 - 8*I, 2 + I]]) - sage: A.is_hermitian() + sage: A.is_hermitian() # optional - sage.rings.number_field False - sage: B = A*A.conjugate_transpose() - sage: B.is_hermitian() + sage: B = A * A.conjugate_transpose() # optional - sage.rings.number_field + sage: B.is_hermitian() # optional - sage.rings.number_field True Sage has several fields besides the entire complex numbers where conjugation is non-trivial. :: - sage: F. = QuadraticField(-7) - sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], + sage: F. = QuadraticField(-7) # optional - sage.rings.number_field + sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], # optional - sage.rings.number_field ....: [-2*b - 3, -3*b + 2, -2*b], ....: [ b + 1, 0, -2]]) - sage: C.is_hermitian() + sage: C.is_hermitian() # optional - sage.rings.number_field False - sage: C = C*C.conjugate_transpose() - sage: C.is_hermitian() + sage: C = C*C.conjugate_transpose() # optional - sage.rings.number_field + sage: C.is_hermitian() # optional - sage.rings.number_field True A matrix that is nearly Hermitian, but for a non-real diagonal entry. :: - sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], + sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], # optional - sage.rings.number_field ....: [ 2+I, 3+I, 2-6*I], ....: [1-4*I, 2+6*I, 5]]) - sage: A.is_hermitian() + sage: A.is_hermitian() # optional - sage.rings.number_field False - sage: A[1,1] = 132 - sage: A.is_hermitian() + sage: A[1, 1] = 132 # optional - sage.rings.number_field + sage: A.is_hermitian() # optional - sage.rings.number_field True Rectangular matrices are never Hermitian. :: - sage: A = matrix(QQbar, 3, 4) - sage: A.is_hermitian() + sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field + sage: A.is_hermitian() # optional - sage.rings.number_field False A square, empty matrix is trivially Hermitian. :: @@ -4206,27 +4216,27 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: A = matrix(QQbar, [[0, -1], + sage: A = matrix(QQbar, [[0, -1], # optional - sage.rings.number_field ....: [1, 0]]) - sage: A.is_skew_hermitian() + sage: A.is_skew_hermitian() # optional - sage.rings.number_field True A matrix that is nearly skew-Hermitian, but for a non-real diagonal entry. :: - sage: A = matrix(QQbar, [[ -I, -1, 1-I], + sage: A = matrix(QQbar, [[ -I, -1, 1-I], # optional - sage.rings.number_field ....: [ 1, 1, -1], ....: [-1-I, 1, -I]]) - sage: A.is_skew_hermitian() + sage: A.is_skew_hermitian() # optional - sage.rings.number_field False - sage: A[1,1] = -I - sage: A.is_skew_hermitian() + sage: A[1, 1] = -I # optional - sage.rings.number_field + sage: A.is_skew_hermitian() # optional - sage.rings.number_field True Rectangular matrices are never skew-Hermitian. :: - sage: A = matrix(QQbar, 3, 4) - sage: A.is_skew_hermitian() + sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field + sage: A.is_skew_hermitian() # optional - sage.rings.number_field False A square, empty matrix is trivially Hermitian. :: @@ -4399,7 +4409,7 @@ cdef class Matrix(sage.structure.element.Matrix): sage: matrix([[0,6],[3,0]]).is_skew_symmetrizable(positive=True) False - sage: M = matrix(4,[0,1,0,0,-1,0,-1,0,0,2,0,1,0,0,-1,0]); M + sage: M = matrix(4, [0,1,0,0, -1,0,-1,0, 0,2,0,1, 0,0,-1,0]); M [ 0 1 0 0] [-1 0 -1 0] [ 0 2 0 1] @@ -4408,7 +4418,7 @@ cdef class Matrix(sage.structure.element.Matrix): sage: M.is_skew_symmetrizable(return_diag=True) [1, 1, 1/2, 1/2] - sage: M2 = diagonal_matrix([1,1,1/2,1/2])*M; M2 + sage: M2 = diagonal_matrix([1,1,1/2,1/2]) * M; M2 [ 0 1 0 0] [ -1 0 -1 0] [ 0 1 0 1/2] @@ -4434,9 +4444,9 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: matrix(QQ,2,2,range(4)).is_dense() + sage: matrix(QQ, 2, 2, range(4)).is_dense() True - sage: matrix(QQ,2,2,range(4),sparse=True).is_dense() + sage: matrix(QQ, 2, 2, range(4), sparse=True).is_dense() False """ return self.is_dense_c() @@ -4450,9 +4460,9 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: matrix(QQ,2,2,range(4)).is_sparse() + sage: matrix(QQ, 2, 2, range(4)).is_sparse() False - sage: matrix(QQ,2,2,range(4),sparse=True).is_sparse() + sage: matrix(QQ, 2, 2, range(4), sparse=True).is_sparse() True """ return self.is_sparse_c() @@ -4464,9 +4474,9 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: matrix(QQ,2,2,range(4)).is_square() + sage: matrix(QQ, 2, 2, range(4)).is_square() True - sage: matrix(QQ,2,3,range(6)).is_square() + sage: matrix(QQ, 2, 3, range(6)).is_square() False """ return self._nrows == self._ncols @@ -4499,7 +4509,7 @@ cdef class Matrix(sage.structure.element.Matrix): :: - sage: A = MatrixSpace(IntegerRing(),2)([1,10,0,-1]) + sage: A = MatrixSpace(IntegerRing(), 2)([1,10,0,-1]) sage: A.is_invertible() True sage: ~A # compute the inverse @@ -4512,7 +4522,7 @@ cdef class Matrix(sage.structure.element.Matrix): :: sage: R. = PolynomialRing(IntegerRing()) - sage: A = MatrixSpace(R,2)([1,x,0,-1]) + sage: A = MatrixSpace(R, 2)([1,x,0,-1]) sage: A.is_invertible() True sage: ~A @@ -4549,7 +4559,7 @@ cdef class Matrix(sage.structure.element.Matrix): A singular matrix over the field ``QQ``. :: - sage: A = matrix(QQ, 4, [-1,2,-3,6,0,-1,-1,0,-1,1,-5,7,-1,6,5,2]) + sage: A = matrix(QQ, 4, [-1,2,-3,6, 0,-1,-1,0, -1,1,-5,7, -1,6,5,2]) sage: A.is_singular() True sage: A.right_kernel().dimension() @@ -4557,7 +4567,7 @@ cdef class Matrix(sage.structure.element.Matrix): A matrix that is not singular, i.e. nonsingular, over a field. :: - sage: B = matrix(QQ, 4, [1,-3,-1,-5,2,-5,-2,-7,-2,5,3,4,-1,4,2,6]) + sage: B = matrix(QQ, 4, [1,-3,-1,-5, 2,-5,-2,-7, -2,5,3,4, -1,4,2,6]) sage: B.is_singular() False sage: B.left_kernel().dimension() @@ -4577,7 +4587,7 @@ cdef class Matrix(sage.structure.element.Matrix): When the base ring is not a field, then a matrix may be both not invertible and not singular. :: - sage: D = matrix(ZZ, 4, [2,0,-4,8,2,1,-2,7,2,5,7,0,0,1,4,-6]) + sage: D = matrix(ZZ, 4, [2,0,-4,8, 2,1,-2,7, 2,5,7,0, 0,1,4,-6]) sage: D.is_invertible() False sage: D.is_singular() @@ -4629,8 +4639,8 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: m = matrix(GF(7),5,range(25)) - sage: m.rank() + sage: m = matrix(GF(7), 5, range(25)) # optional - sage.rings.finite_rings + sage: m.rank() # optional - sage.rings.finite_rings 2 Rank is not implemented over the integers modulo a composite yet.:: @@ -4646,10 +4656,10 @@ cdef class Matrix(sage.structure.element.Matrix): We should be able to compute the rank of a matrix whose entries are polynomials over a finite field (:trac:`5014`):: - sage: P. = PolynomialRing(GF(17)) - sage: m = matrix(P, [ [ 6*x^2 + 8*x + 12, 10*x^2 + 4*x + 11], - ....: [8*x^2 + 12*x + 15, 8*x^2 + 9*x + 16] ]) - sage: m.rank() + sage: P. = PolynomialRing(GF(17)) # optional - sage.rings.finite_rings + sage: m = matrix(P, [[ 6*x^2 + 8*x + 12, 10*x^2 + 4*x + 11], # optional - sage.rings.finite_rings + ....: [8*x^2 + 12*x + 15, 8*x^2 + 9*x + 16]]) + sage: m.rank() # optional - sage.rings.finite_rings 2 """ x = self.fetch('rank') @@ -4670,7 +4680,7 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: a = matrix(QQ,3,3,range(9)); a + sage: a = matrix(QQ, 3, 3, range(9)); a [0 1 2] [3 4 5] [6 7 8] @@ -4881,42 +4891,42 @@ cdef class Matrix(sage.structure.element.Matrix): Over finite fields:: - sage: A = matrix(GF(59),3,[10,56,39,53,56,33,58,24,55]) - sage: A.multiplicative_order() + sage: A = matrix(GF(59), 3, [10,56,39,53,56,33,58,24,55]) # optional - sage.rings.finite_rings + sage: A.multiplicative_order() # optional - sage.rings.finite_rings 580 - sage: (A^580).is_one() + sage: (A^580).is_one() # optional - sage.rings.finite_rings True - sage: B = matrix(GF(10007^3,'b'),0) - sage: B.multiplicative_order() + sage: B = matrix(GF(10007^3, 'b'), 0) # optional - sage.rings.finite_rings + sage: B.multiplicative_order() # optional - sage.rings.finite_rings 1 - sage: M = MatrixSpace(GF(11^2,'e'),5) - sage: E = M.random_element() - sage: while E.det() == 0: + sage: M = MatrixSpace(GF(11^2, 'e'), 5) # optional - sage.rings.finite_rings + sage: E = M.random_element() # optional - sage.rings.finite_rings + sage: while E.det() == 0: # optional - sage.rings.finite_rings ....: E = M.random_element() - sage: (E^E.multiplicative_order()).is_one() + sage: (E^E.multiplicative_order()).is_one() # optional - sage.rings.finite_rings True Over `\ZZ`:: - sage: m = matrix(ZZ,2,2,[-1,1,-1,0]) - sage: m.multiplicative_order() + sage: m = matrix(ZZ, 2, 2, [-1,1,-1,0]) + sage: m.multiplicative_order() # optional - sage.groups 3 - sage: m = posets.ChainPoset(6).coxeter_transformation() - sage: m.multiplicative_order() + sage: m = posets.ChainPoset(6).coxeter_transformation() # optional - sage.combinat sage.graphs + sage: m.multiplicative_order() # optional - sage.combinat sage.graphs sage.groups 7 - sage: P = posets.TamariLattice(4).coxeter_transformation() - sage: P.multiplicative_order() + sage: P = posets.TamariLattice(4).coxeter_transformation() # optional - sage.combinat sage.graphs + sage: P.multiplicative_order() # optional - sage.combinat sage.graphs sage.groups 10 sage: M = matrix(ZZ, 2, 2, [1, 1, 0, 1]) - sage: M.multiplicative_order() + sage: M.multiplicative_order() # optional - sage.groups +Infinity - sage: for k in range(600): + sage: for k in range(600): # optional - sage.groups ....: m = SL2Z.random_element() ....: o = m.multiplicative_order() ....: if o != Infinity and m**o != SL2Z.one(): @@ -4931,19 +4941,19 @@ cdef class Matrix(sage.structure.element.Matrix): ....: else: ....: return ZZ.random_element(-100,100) sage: rnd = matrix(ZZ, 8, 8, val) - sage: (rnd * m24 * rnd.inverse_of_unit()).multiplicative_order() + sage: (rnd * m24 * rnd.inverse_of_unit()).multiplicative_order() # optional - sage.groups 24 TESTS:: - sage: C = matrix(GF(2^10,'c'),2,3,[1]*6) - sage: C.multiplicative_order() + sage: C = matrix(GF(2^10, 'c'), 2, 3, [1]*6) # optional - sage.rings.finite_rings + sage: C.multiplicative_order() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ArithmeticError: self must be invertible ... - sage: D = matrix(IntegerModRing(6),3,[5,5,3,0,2,5,5,4,0]) - sage: D.multiplicative_order() + sage: D = matrix(IntegerModRing(6), 3, [5,5,3,0,2,5,5,4,0]) + sage: D.multiplicative_order() # optional - sage.groups Traceback (most recent call last): ... NotImplementedError: ... only ... over finite fields or ZZ @@ -5033,7 +5043,7 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: B = matrix(QQ,2, [1,2,3,4]) + sage: B = matrix(QQ, 2, [1,2,3,4]) sage: V = VectorSpace(QQ, 2) sage: v = V([-1,5]) sage: v*B @@ -5062,11 +5072,11 @@ cdef class Matrix(sage.structure.element.Matrix): Check that :trac:`8198` is fixed:: - sage: R = Qp(5, 5) - sage: x = R(5).add_bigoh(1) - sage: I = matrix(R, [[1, 0], [0, 1]]) - sage: v = vector(R, [1, x]) - sage: v*I + sage: R = Qp(5, 5) # optional - sage.rings.padics + sage: x = R(5).add_bigoh(1) # optional - sage.rings.padics + sage: I = matrix(R, [[1, 0], [0, 1]]) # optional - sage.rings.padics + sage: v = vector(R, [1, x]) # optional - sage.rings.padics + sage: v*I # optional - sage.rings.padics (1 + O(5^5), O(5)) """ @@ -5096,11 +5106,11 @@ cdef class Matrix(sage.structure.element.Matrix): Check that :trac:`8198` is fixed:: - sage: R = Qp(5, 5) - sage: x = R(5).add_bigoh(1) - sage: I = matrix(R, [[1, 0], [0, 1]]) - sage: v = vector(R, [1, x]) - sage: I*v + sage: R = Qp(5, 5) # optional - sage.rings.padics + sage: x = R(5).add_bigoh(1) # optional - sage.rings.padics + sage: I = matrix(R, [[1, 0], [0, 1]]) # optional - sage.rings.padics + sage: v = vector(R, [1, x]) # optional - sage.rings.padics + sage: I*v # optional - sage.rings.padics (1 + O(5^5), O(5)) """ @@ -5136,13 +5146,13 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: A = matrix(ZZ,2, [1,1,3,5]); A + sage: A = matrix(ZZ, 2, [1,1,3,5]); A [1 1] [3 5] sage: v = vector([1,0]) - sage: A.iterates(v,0) + sage: A.iterates(v, 0) [] - sage: A.iterates(v,5) + sage: A.iterates(v, 5) [ 1 0] [ 1 1] [ 4 6] @@ -5151,17 +5161,17 @@ cdef class Matrix(sage.structure.element.Matrix): Another example:: - sage: a = matrix(ZZ,3,range(9)); a + sage: a = matrix(ZZ, 3, range(9)); a [0 1 2] [3 4 5] [6 7 8] sage: v = vector([1,0,0]) - sage: a.iterates(v,4) + sage: a.iterates(v, 4) [ 1 0 0] [ 0 1 2] [ 15 18 21] [180 234 288] - sage: a.iterates(v,4,rows=False) + sage: a.iterates(v, 4, rows=False) [ 1 0 15 180] [ 0 3 42 558] [ 0 6 69 936] @@ -5193,10 +5203,10 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: R. = FreeAlgebra(QQ,2) - sage: a = matrix(2,2, [1,2,x*y,y*x]) - sage: b = matrix(2,2, [1,2,y*x,y*x]) - sage: a+b # indirect doctest + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat + sage: a = matrix(2, 2, [1,2,x*y,y*x]) # optional - sage.combinat + sage: b = matrix(2, 2, [1,2,y*x,y*x]) # optional - sage.combinat + sage: a + b # indirect doctest # optional - sage.combinat [ 2 4] [x*y + y*x 2*y*x] @@ -5216,10 +5226,10 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: R. = FreeAlgebra(QQ,2) - sage: a = matrix(2,2, [1,2,x*y,y*x]) - sage: b = matrix(2,2, [1,2,y*x,y*x]) - sage: a-b # indirect doctest + sage: R. = FreeAlgebra(QQ,2) # optional - sage.combinat + sage: a = matrix(2, 2, [1,2,x*y,y*x]) # optional - sage.combinat + sage: b = matrix(2, 2, [1,2,y*x,y*x]) # optional - sage.combinat + sage: a - b # indirect doctest # optional - sage.combinat [ 0 0] [x*y - y*x 0] @@ -5279,24 +5289,24 @@ cdef class Matrix(sage.structure.element.Matrix): """ EXAMPLES:: - sage: a = matrix(QQ['x'],2,range(6)) + sage: a = matrix(QQ['x'], 2, range(6)) sage: (3/4) * a [ 0 3/4 3/2] [ 9/4 3 15/4] sage: R. = QQ[] - sage: a = matrix(R,2,3,[1,x,y,-x*y,x+y,x-y]); a + sage: a = matrix(R, 2, 3, [1,x,y, -x*y,x+y,x-y]); a [ 1 x y] [ -x*y x + y x - y] sage: (x*y) * a [ x*y x^2*y x*y^2] [ -x^2*y^2 x^2*y + x*y^2 x^2*y - x*y^2] - sage: R. = FreeAlgebra(ZZ,2) - sage: a = matrix(R,2,3,[1,x,y,-x*y,x+y,x-y]); a + sage: R. = FreeAlgebra(ZZ,2) # optional - sage.combinat + sage: a = matrix(R, 2, 3, [1,x,y, -x*y,x+y,x-y]); a # optional - sage.combinat [ 1 x y] [ -x*y x + y x - y] - sage: (x*y) * a # indirect doctest + sage: (x*y) * a # indirect doctest # optional - sage.combinat [ x*y x*y*x x*y^2] [ -x*y*x*y x*y*x + x*y^2 x*y*x - x*y^2] """ @@ -5325,22 +5335,22 @@ cdef class Matrix(sage.structure.element.Matrix): An example in which the base ring is not commutative:: - sage: F. = FreeAlgebra(QQ,2) - sage: a = matrix(2,[x,y,x^2,y^2]); a + sage: F. = FreeAlgebra(QQ,2) # optional - sage.combinat + sage: a = matrix(2, [x,y, x^2,y^2]); a # optional - sage.combinat [ x y] [x^2 y^2] - sage: x * a # indirect doctest + sage: x * a # indirect doctest # optional - sage.combinat [ x^2 x*y] [ x^3 x*y^2] - sage: a * y + sage: a * y # optional - sage.combinat [ x*y y^2] [x^2*y y^3] - sage: R. = FreeAlgebra(ZZ,2) - sage: a = matrix(R,2,3,[1,x,y,-x*y,x+y,x-y]); a + sage: R. = FreeAlgebra(ZZ,2) # optional - sage.combinat + sage: a = matrix(R, 2, 3, [1,x,y, -x*y,x+y,x-y]); a # optional - sage.combinat [ 1 x y] [ -x*y x + y x - y] - sage: a * (x*y) + sage: a * (x*y) # optional - sage.combinat [ x*y x^2*y y*x*y] [ -x*y*x*y x^2*y + y*x*y x^2*y - y*x*y] """ @@ -5364,17 +5374,17 @@ cdef class Matrix(sage.structure.element.Matrix): :: sage: R. = QQ[] - sage: a = matrix(R,2,3,[1,x,y,-x*y,x+y,x-y]); a + sage: a = matrix(R, 2, 3, [1,x,y, -x*y,x+y,x-y]); a [ 1 x y] [ -x*y x + y x - y] sage: b = a.transpose(); b [ 1 -x*y] [ x x + y] [ y x - y] - sage: a*b # indirect doctest + sage: a*b # indirect doctest [ x^2 + y^2 + 1 x^2 + x*y - y^2] [ x^2 + x*y - y^2 x^2*y^2 + 2*x^2 + 2*y^2] - sage: b*a # indirect doctest + sage: b*a # indirect doctest [ x^2*y^2 + 1 -x^2*y - x*y^2 + x -x^2*y + x*y^2 + y] [ -x^2*y - x*y^2 + x 2*x^2 + 2*x*y + y^2 x^2 + x*y - y^2] [ -x^2*y + x*y^2 + y x^2 + x*y - y^2 x^2 - 2*x*y + 2*y^2] @@ -5382,63 +5392,65 @@ cdef class Matrix(sage.structure.element.Matrix): We verify that the matrix multiplies are correct by comparing them with what PARI gets:: - sage: gp(a)*gp(b) - gp(a*b) + sage: gp(a)*gp(b) - gp(a*b) # optional - sage.libs.pari [0, 0; 0, 0] - sage: gp(b)*gp(a) - gp(b*a) + sage: gp(b)*gp(a) - gp(b*a) # optional - sage.libs.pari [0, 0, 0; 0, 0, 0; 0, 0, 0] EXAMPLE of matrix times matrix over different base rings:: - sage: a = matrix(ZZ,2,2,range(4)) - sage: b = matrix(GF(7),2,2,range(4)) - sage: c = matrix(QQ,2,2,range(4)) - sage: d = a*b; d + sage: a = matrix(ZZ, 2, 2, range(4)) + sage: b = matrix(GF(7), 2, 2, range(4)) # optional - sage.rings.finite_rings + sage: c = matrix(QQ, 2, 2, range(4)) + sage: d = a * b; d # optional - sage.rings.finite_rings [2 3] [6 4] - sage: parent(d) + sage: parent(d) # optional - sage.rings.finite_rings Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 - sage: parent(b*a) + sage: parent(b * a) # optional - sage.rings.finite_rings Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 - sage: d = a*c; d + sage: d = a * c; d [ 2 3] [ 6 11] sage: parent(d) Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: d = b+c + sage: d = b + c # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for +: 'Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7' and 'Full MatrixSpace of 2 by 2 dense matrices over Rational Field' - sage: d = b+c.change_ring(GF(7)); d + TypeError: unsupported operand parent(s) for +: + 'Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7' and + 'Full MatrixSpace of 2 by 2 dense matrices over Rational Field' + sage: d = b + c.change_ring(GF(7)); d # optional - sage.rings.finite_rings [0 2] [4 6] EXAMPLE of matrix times matrix where one matrix is sparse and the other is dense (in such mixed cases, the result is always dense):: - sage: a = matrix(ZZ,2,2,range(4),sparse=True) - sage: b = matrix(GF(7),2,2,range(4),sparse=False) - sage: c = a*b; c + sage: a = matrix(ZZ, 2, 2, range(4), sparse=True) + sage: b = matrix(GF(7), 2, 2, range(4), sparse=False) # optional - sage.rings.finite_rings + sage: c = a * b; c # optional - sage.rings.finite_rings [2 3] [6 4] - sage: parent(c) + sage: parent(c) # optional - sage.rings.finite_rings Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 - sage: c = b*a; c + sage: c = b * a; c # optional - sage.rings.finite_rings [2 3] [6 4] - sage: parent(c) + sage: parent(c) # optional - sage.rings.finite_rings Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 EXAMPLE of matrix multiplication over a noncommutative base ring:: - sage: R. = FreeAlgebra(QQ,2) - sage: x*y - y*x + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat + sage: x*y - y*x # optional - sage.combinat x*y - y*x - sage: a = matrix(2,2, [1,2,x,y]) - sage: b = matrix(2,2, [x,y,x^2,y^2]) - sage: a*b + sage: a = matrix(2, 2, [1,2, x,y]) # optional - sage.combinat + sage: b = matrix(2, 2, [x,y, x^2,y^2]) # optional - sage.combinat + sage: a*b # optional - sage.combinat [ x + 2*x^2 y + 2*y^2] [x^2 + y*x^2 x*y + y^3] - sage: b*a + sage: b*a # optional - sage.combinat [ x + y*x 2*x + y^2] [x^2 + y^2*x 2*x^2 + y^3] @@ -5459,7 +5471,9 @@ cdef class Matrix(sage.structure.element.Matrix): sage: a*v Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 3 dense matrices over Integer Ring' and 'Ambient free module of rank 2 over the principal ideal domain Integer Ring' + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 3 dense matrices over Integer Ring' and + 'Ambient free module of rank 2 over the principal ideal domain Integer Ring' This illustrates how coercion works:: @@ -5506,15 +5520,15 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLE of scalar multiplication in the noncommutative case:: - sage: R. = FreeAlgebra(ZZ,2) - sage: a = matrix(2,[x,y,x^2,y^2]) - sage: a * x + sage: R. = FreeAlgebra(ZZ, 2) # optional - sage.combinat + sage: a = matrix(2, [x,y, x^2,y^2]) # optional - sage.combinat + sage: a * x # optional - sage.combinat [ x^2 y*x] [ x^3 y^2*x] - sage: x * a + sage: x * a # optional - sage.combinat [ x^2 x*y] [ x^3 x*y^2] - sage: a*x - x*a + sage: a*x - x*a # optional - sage.combinat [ 0 -x*y + y*x] [ 0 -x*y^2 + y^2*x] """ @@ -5599,7 +5613,7 @@ cdef class Matrix(sage.structure.element.Matrix): :: - sage: I = MatrixSpace(ZZ,2)(1) # identity matrix + sage: I = MatrixSpace(ZZ, 2)(1) # identity matrix sage: ~I [1 0] [0 1] @@ -5614,7 +5628,7 @@ cdef class Matrix(sage.structure.element.Matrix): A matrix with 0 rows and 0 columns is invertible (see :trac:`3734`):: - sage: M = MatrixSpace(RR,0,0)(0); M + sage: M = MatrixSpace(RR, 0, 0)(0); M [] sage: M.determinant() 1.00000000000000 @@ -5625,13 +5639,13 @@ cdef class Matrix(sage.structure.element.Matrix): Matrices over the integers modulo a composite modulus:: - sage: m = matrix(Zmod(49),2,[2,1,3,3]) + sage: m = matrix(Zmod(49), 2, [2,1,3,3]) sage: type(m) sage: ~m [ 1 16] [48 17] - sage: m = matrix(Zmod(2^100),2,[2,1,3,3]) + sage: m = matrix(Zmod(2^100), 2, [2,1,3,3]) sage: type(m) sage: (~m)*m @@ -5643,8 +5657,8 @@ cdef class Matrix(sage.structure.element.Matrix): Matrices over p-adics. See :trac:`17272` :: - sage: R = ZpCA(5,5,print_mode='val-unit') - sage: A = matrix(R,3,3,[250,2369,1147,106,927,362,90,398,2483]) + sage: R = ZpCA(5, 5, print_mode='val-unit') + sage: A = matrix(R, 3, 3, [250,2369,1147,106,927,362,90,398,2483]) sage: A [5^3 * 2 + O(5^5) 2369 + O(5^5) 1147 + O(5^5)] [ 106 + O(5^5) 927 + O(5^5) 362 + O(5^5)] @@ -5656,7 +5670,7 @@ cdef class Matrix(sage.structure.element.Matrix): This matrix is not invertible:: - sage: m = matrix(Zmod(9),2,[2,1,3,3]) + sage: m = matrix(Zmod(9), 2, [2,1,3,3]) sage: ~m Traceback (most recent call last): ... @@ -5770,19 +5784,19 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: sage: R. = ZZ[] - sage: RR = R.quotient(a*d-b*c-1) - sage: a,b,c,d = RR.gens() - sage: m = matrix(2, [a,b,c,d]) - sage: n = m.inverse_of_unit() - sage: m * n + sage: RR = R.quotient(a*d - b*c - 1) # optional - sage.libs.singular + sage: a,b,c,d = RR.gens() # optional - sage.libs.singular + sage: m = matrix(2, [a,b, c,d]) # optional - sage.libs.singular + sage: n = m.inverse_of_unit() # optional - sage.libs.singular + sage: m * n # optional - sage.libs.singular [1 0] [0 1] - sage: matrix(RR, 2, 1, [a,b]).inverse_of_unit() + sage: matrix(RR, 2, 1, [a,b]).inverse_of_unit() # optional - sage.libs.singular Traceback (most recent call last): ... ArithmeticError: self must be a square matrix - sage: matrix(RR, 1, 1, [2]).inverse_of_unit() + sage: matrix(RR, 1, 1, [2]).inverse_of_unit() # optional - sage.libs.singular Traceback (most recent call last): ... NotImplementedError: Lifting of multivariate polynomials over non-fields is not implemented. @@ -5795,9 +5809,9 @@ cdef class Matrix(sage.structure.element.Matrix): Tests for :trac:`28570`:: - sage: P = posets.TamariLattice(7) - sage: M = P._hasse_diagram._leq_matrix - sage: M.inverse_of_unit() # this was very slow, now 1s + sage: P = posets.TamariLattice(7) # optional - sage.combinat sage.graphs + sage: M = P._hasse_diagram._leq_matrix # optional - sage.combinat sage.graphs + sage: M.inverse_of_unit() # this was very slow, now 1s # optional - sage.combinat sage.graphs 429 x 429 sparse matrix over Integer Ring... sage: m = matrix(Zmod(2**2), 1, 1, [1], sparse=True) @@ -5890,9 +5904,9 @@ cdef class Matrix(sage.structure.element.Matrix): Non-integer (symbolic) exponents are also supported:: - sage: k = var('k') - sage: A = matrix([[2, -1], [1, 0]]) - sage: A^(2*k+1) + sage: k = var('k') # optional - sage.symbolic + sage: A = matrix([[2, -1], [1, 0]]) # optional - sage.symbolic + sage: A^(2*k+1) # optional - sage.symbolic [ 2*k + 2 -2*k - 1] [ 2*k + 1 -2*k] """ @@ -6106,8 +6120,8 @@ def unpickle(cls, parent, immutability, cache, data, version): OVER `\ZZ`:: - sage: A = matrix(ZZ,2,range(4)) - sage: loads(dumps(A)) # indirect doctest + sage: A = matrix(ZZ, 2, range(4)) + sage: loads(dumps(A)) # indirect doctest [0 1] [2 3] diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index f38c429d994..3e89649126c 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -5,8 +5,8 @@ For design documentation see :mod:`sage.matrix.docs`. TESTS:: - sage: A = Matrix(GF(5),3,3,srange(9)) - sage: TestSuite(A).run() + sage: A = Matrix(GF(5), 3, 3, srange(9)) # optional - sage.rings.finite_rings + sage: TestSuite(A).run() # optional - sage.rings.finite_rings """ #***************************************************************************** @@ -40,11 +40,11 @@ cdef class Matrix(Matrix0): sage: a = matrix(R,2,[x+1,2/3, x^2/2, 1+x^3]); a [ x + 1 2/3] [1/2*x^2 x^3 + 1] - sage: b = gp(a); b # indirect doctest + sage: b = gp(a); b # indirect doctest # optional - sage.libs.pari [x + 1, 2/3; 1/2*x^2, x^3 + 1] sage: a.determinant() x^4 + x^3 - 1/3*x^2 + x + 1 - sage: b.matdet() + sage: b.matdet() # optional - sage.libs.pari x^4 + x^3 - 1/3*x^2 + x + 1 """ w = self.list() @@ -69,11 +69,11 @@ cdef class Matrix(Matrix0): sage: a = matrix(R,2,[x+1,2/3, x^2/2, 1+x^3]); a [ x + 1 2/3] [1/2*x^2 x^3 + 1] - sage: b = pari(a); b # indirect doctest + sage: b = pari(a); b # indirect doctest # optional - sage.libs.pari [x + 1, 2/3; 1/2*x^2, x^3 + 1] sage: a.determinant() x^4 + x^3 - 1/3*x^2 + x + 1 - sage: b.matdet() + sage: b.matdet() # optional - sage.libs.pari x^4 + x^3 - 1/3*x^2 + x + 1 This function preserves precision for entries of inexact type (e.g. @@ -97,33 +97,33 @@ cdef class Matrix(Matrix0): EXAMPLES:: sage: A = MatrixSpace(QQ,3,3)([0,1,2,3,4,5,6,7,8]) - sage: g = gap(A) # indirect doctest - sage: g + sage: g = gap(A) # indirect doctest # optional - sage.libs.gap + sage: g # optional - sage.libs.gap [ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ] ] - sage: g.CharacteristicPolynomial() + sage: g.CharacteristicPolynomial() # optional - sage.libs.gap x_1^3-12*x_1^2-18*x_1 - sage: A.characteristic_polynomial() + sage: A.characteristic_polynomial() # optional - sage.libs.gap x^3 - 12*x^2 - 18*x - sage: matrix(QQ, g) == A + sage: matrix(QQ, g) == A # optional - sage.libs.gap True Particularly difficult is the case of matrices over cyclotomic fields and general number fields. See :trac:`5618` and :trac:`8909`:: - sage: K. = CyclotomicField(8) - sage: A = MatrixSpace(K,2,2)([0,1+zeta,2*zeta,3]) - sage: g = gap(A); g + sage: K. = CyclotomicField(8) # optional - sage.rings.number_field + sage: A = MatrixSpace(K, 2, 2)([0, 1+zeta, 2*zeta, 3]) # optional - sage.rings.number_field + sage: g = gap(A); g # optional - sage.rings.number_field [ [ 0, 1+E(8) ], [ 2*E(8), 3 ] ] - sage: matrix(K, g) == A + sage: matrix(K, g) == A # optional - sage.rings.number_field True - sage: g.IsMatrix() + sage: g.IsMatrix() # optional - sage.rings.number_field true - sage: L. = NumberField(x^3-2) - sage: A = MatrixSpace(L,2,2)([0,1+tau,2*tau,3]) - sage: g = gap(A); g + sage: L. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: A = MatrixSpace(L, 2, 2)([0, 1+tau, 2*tau, 3]) # optional - sage.rings.number_field + sage: g = gap(A); g # optional - sage.rings.number_field [ [ !0, tau+1 ], [ 2*tau, !3 ] ] - sage: matrix(L, g) == A + sage: matrix(L, g) == A # optional - sage.rings.number_field True """ cdef Py_ssize_t i, j @@ -152,9 +152,9 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: libgap(identity_matrix(ZZ,2)) + sage: libgap(identity_matrix(ZZ, 2)) # optional - sage.libs.gap [ [ 1, 0 ], [ 0, 1 ] ] - sage: libgap(matrix(GF(3),2,2,[4,5,6,7])) + sage: libgap(matrix(GF(3), 2, 2, [4,5,6,7])) # optional - sage.libs.gap sage.rings.finite_rings [ [ Z(3)^0, Z(3) ], [ 0*Z(3), Z(3)^0 ] ] """ from sage.libs.gap.libgap import libgap @@ -191,9 +191,9 @@ cdef class Matrix(Matrix0): :: - sage: y = var('y') - sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) - sage: M == fricas(M).sage() # optional - fricas + sage: y = var('y') # optional - sage.symbolic + sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # optional - sage.symbolic + sage: M == fricas(M).sage() # optional - fricas # optional - sage.symbolic True """ s = ','.join('[' + ','.join(cf._fricas_init_() for cf in row) + ']' @@ -211,22 +211,22 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: M = matrix(ZZ,2,range(4)) - sage: giac(M) + sage: M = matrix(ZZ, 2, range(4)) + sage: giac(M) # optional - sage.libs.giac [[0,1],[2,3]] - sage: M = matrix(QQ,3,[1,2,3,4/3,5/3,6/4,7,8,9]) - sage: giac(M) + sage: M = matrix(QQ, 3, [1,2,3, 4/3,5/3,6/4, 7,8,9]) + sage: giac(M) # optional - sage.libs.giac [[1,2,3],[4/3,5/3,3/2],[7,8,9]] sage: P. = ZZ[] sage: M = matrix(P, 2, [-9*x^2-2*x+2, x-1, x^2+8*x, -3*x^2+5]) - sage: giac(M) + sage: giac(M) # optional - sage.libs.giac [[-9*sageVARx^2-2*sageVARx+2,sageVARx-1],[sageVARx^2+8*sageVARx,-3*sageVARx^2+5]] - sage: y = var('y') - sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) - sage: giac(M).det().sage() + sage: y = var('y') # optional - sage.symbolic + sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # optional - sage.symbolic + sage: giac(M).det().sage() # optional - sage.libs.giac sage.symbolic (y^2*dilog(y) + y*dilog(y)*sin(y) - y + 4)/y """ s = ','.join('[' + ','.join(cf._giac_init_() for cf in row) + ']' @@ -243,11 +243,11 @@ cdef class Matrix(Matrix0): [0 1 2] [3 4 5] [6 7 8] - sage: m._maxima_init_() + sage: m._maxima_init_() # optional - sage.symbolic 'matrix([0,1,2],[3,4,5],[6,7,8])' - sage: a = maxima(m); a + sage: a = maxima(m); a # optional - sage.symbolic matrix([0,1,2],[3,4,5],[6,7,8]) - sage: a.charpoly('x').expand() + sage: a.charpoly('x').expand() # optional - sage.symbolic (-x^3)+12*x^2+18*x sage: m.charpoly() x^3 - 12*x^2 - 18*x @@ -335,9 +335,9 @@ cdef class Matrix(Matrix0): We coerce a matrix over a cyclotomic field, where the generator must be named during the coercion. :: - sage: K = CyclotomicField(9) ; z = K.0 - sage: M = matrix(K,3,3,[0,1,3,z,z**4,z-1,z**17,1,0]) - sage: M + sage: K = CyclotomicField(9); z = K.0 # optional - sage.rings.number_field + sage: M = matrix(K, 3, 3, [0,1,3,z,z**4,z-1,z**17,1,0]) # optional - sage.rings.number_field + sage: M # optional - sage.rings.number_field [ 0 1 3] [ zeta9 zeta9^4 zeta9 - 1] [-zeta9^5 - zeta9^2 1 0] @@ -388,9 +388,9 @@ cdef class Matrix(Matrix0): sage: maple(M) # optional - maple Matrix(2, 2, [[-9*x^2-2*x+2,x-1],[x^2+8*x,-3*x^2+5]]) - sage: y = var('y') - sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) - sage: M == maple(M).sage() # optional - maple + sage: y = var('y') # optional - sage.symbolic + sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # optional - sage.symbolic + sage: M == maple(M).sage() # optional - maple # optional - sage.symbolic True """ s = ','.join('[' + ','.join(cf._maple_init_() for cf in row) + ']' @@ -404,12 +404,12 @@ cdef class Matrix(Matrix0): EXAMPLES:: sage: M = matrix(ZZ,2,range(4)) - sage: polymake(M) # optional - jupymake + sage: polymake(M) # optional - jupymake 0 1 2 3 - sage: K. = QuadraticField(5) - sage: M = matrix(K, [[1, 2], [sqrt5, 3]]) - sage: polymake(M) # optional - jupymake + sage: K. = QuadraticField(5) # optional - sage.rings.number_field + sage: M = matrix(K, [[1, 2], [sqrt5, 3]]) # optional - sage.rings.number_field + sage: polymake(M) # optional - jupymake # optional - sage.rings.number_field 1 2 0+1r5 3 """ @@ -484,7 +484,7 @@ cdef class Matrix(Matrix0): [1 2 3] [4 5 6] [7 8 9] - sage: a._scilab_init_() + sage: a._scilab_init_() # optional - sage.libs.pari '[1,2,3;4,5,6;7,8,9]' AUTHORS: @@ -539,49 +539,49 @@ cdef class Matrix(Matrix0): [1 2 3] [4 5 6] [7 8 9] - sage: sA = A._sympy_(); sA + sage: sA = A._sympy_(); sA # optional - sympy Matrix([ [1, 2, 3], [4, 5, 6], [7, 8, 9]]) - sage: type(sA) + sage: type(sA) # optional - sympy sage: I = MatrixSpace(QQ, 5, 5, sparse=True).identity_matrix() - sage: sI = I._sympy_(); sI + sage: sI = I._sympy_(); sI # optional - sympy Matrix([ [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]]) - sage: type(sI) + sage: type(sI) # optional - sympy If ``self`` was immutable, then converting the result to Sage gives back ``self``:: sage: immA = matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]], immutable=True) - sage: immA._sympy_()._sage_() is immA + sage: immA._sympy_()._sage_() is immA # optional - sympy True If ``self`` was mutable, then converting back to Sage creates a new matrix:: - sage: sA._sage_() is A + sage: sA._sage_() is A # optional - sympy False - sage: sA._sage_() == A + sage: sA._sage_() == A # optional - sympy True Symbolic matrices are supported:: - sage: M = matrix([[sin(x), cos(x)], [-cos(x), sin(x)]]); M + sage: M = matrix([[sin(x), cos(x)], [-cos(x), sin(x)]]); M # optional - sage.symbolic [ sin(x) cos(x)] [-cos(x) sin(x)] - sage: sM = M._sympy_(); sM + sage: sM = M._sympy_(); sM # optional - sage.symbolic sympy Matrix([ [ sin(x), cos(x)], [-cos(x), sin(x)]]) - sage: sM.subs(x, pi/4) + sage: sM.subs(x, pi/4) # optional - sage.symbolic sympy Matrix([ [ sqrt(2)/2, sqrt(2)/2], [-sqrt(2)/2, sqrt(2)/2]]) @@ -592,12 +592,12 @@ cdef class Matrix(Matrix0): sage: ZeroCol = matrix(QQ, 3, 0, sparse=False); ZeroCol [] - sage: sZeroCol = ZeroCol._sympy_(); sZeroCol + sage: sZeroCol = ZeroCol._sympy_(); sZeroCol # optional - sympy Matrix(3, 0, []) sage: ZeroRow = matrix(QQ, 0, 2, sparse=False); ZeroRow [] - sage: sZeroRow = ZeroRow._sympy_(); sZeroRow + sage: sZeroRow = ZeroRow._sympy_(); sZeroRow # optional - sympy Matrix(0, 2, []) """ @@ -625,9 +625,9 @@ cdef class Matrix(Matrix0): sage: sage_input(matrix(QQ, 3, 3, [5..13])/7, verify=True) # Verified matrix(QQ, [[5/7, 6/7, 1], [8/7, 9/7, 10/7], [11/7, 12/7, 13/7]]) - sage: M = MatrixSpace(GF(5), 50, 50, sparse=True).random_element(density=0.002) - sage: input = sage_input(M, verify=True) - sage: sage_eval(input) == M + sage: M = MatrixSpace(GF(5), 50, 50, sparse=True).random_element(density=0.002) # optional - sage.rings.finite_rings + sage: input = sage_input(M, verify=True) # optional - sage.rings.finite_rings + sage: sage_eval(input) == M # optional - sage.rings.finite_rings True sage: from sage.misc.sage_input import SageInputBuilder sage: matrix(RDF, [[3, 1], [4, 1]])._sage_input_(SageInputBuilder(), False) @@ -677,20 +677,20 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: a = matrix(3,range(12)) - sage: a.numpy() + sage: a = matrix(3, range(12)) + sage: a.numpy() # optional - numpy array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) - sage: a.numpy('f') + sage: a.numpy('f') # optional - numpy array([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.]], dtype=float32) - sage: a.numpy('d') + sage: a.numpy('d') # optional - numpy array([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.]]) - sage: a.numpy('B') + sage: a.numpy('B') # optional - numpy array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]], dtype=uint8) @@ -698,23 +698,26 @@ cdef class Matrix(Matrix0): Type ``numpy.typecodes`` for a list of the possible typecodes:: - sage: import numpy - sage: sorted(numpy.typecodes.items()) - [('All', '?bhilqpBHILQPefdgFDGSUVOMm'), ('AllFloat', 'efdgFDG'), ('AllInteger', 'bBhHiIlLqQpP'), ('Character', 'c'), ('Complex', 'FDG'), ('Datetime', 'Mm'), ('Float', 'efdg'), ('Integer', 'bhilqp'), ('UnsignedInteger', 'BHILQP')] + sage: import numpy # optional - numpy + sage: sorted(numpy.typecodes.items()) # optional - numpy + [('All', '?bhilqpBHILQPefdgFDGSUVOMm'), ('AllFloat', 'efdgFDG'), + ('AllInteger', 'bBhHiIlLqQpP'), ('Character', 'c'), ('Complex', 'FDG'), + ('Datetime', 'Mm'), ('Float', 'efdg'), ('Integer', 'bhilqp'), + ('UnsignedInteger', 'BHILQP')] Alternatively, numpy automatically calls this function (via the magic :meth:`__array__` method) to convert Sage matrices to numpy arrays:: - sage: import numpy - sage: b=numpy.array(a); b + sage: import numpy # optional - numpy + sage: b = numpy.array(a); b # optional - numpy array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) - sage: b.dtype + sage: b.dtype # optional - numpy dtype('int32') # 32-bit dtype('int64') # 64-bit - sage: b.shape + sage: b.shape # optional - numpy (3, 4) """ import numpy @@ -972,14 +975,14 @@ cdef class Matrix(Matrix0): sage: matrix(3, [1..9]).columns() [(1, 4, 7), (2, 5, 8), (3, 6, 9)] - sage: matrix(RR, 2, [sqrt(2), pi, exp(1), 0]).columns() + sage: matrix(RR, 2, [sqrt(2), pi, exp(1), 0]).columns() # optional - sage.symbolic [(1.41421356237310, 2.71828182845905), (3.14159265358979, 0.000000000000000)] sage: matrix(RR, 0, 2, []).columns() [(), ()] sage: matrix(RR, 2, 0, []).columns() [] - sage: m = matrix(RR, 3, 3, {(1,2): pi, (2, 2): -1, (0,1): sqrt(2)}) - sage: parent(m.columns()[0]) + sage: m = matrix(RR, 3, 3, {(1,2): pi, (2, 2): -1, (0,1): sqrt(2)}) # optional - sage.symbolic + sage: parent(m.columns()[0]) # optional - sage.symbolic Sparse vector space of dimension 3 over Real Field with 53 bits of precision Sparse matrices produce sparse columns. :: @@ -1034,8 +1037,8 @@ cdef class Matrix(Matrix0): [] sage: matrix(RR, 2, 0, []).rows() [(), ()] - sage: m = matrix(RR, 3, 3, {(1,2): pi, (2, 2): -1, (0,1): sqrt(2)}) - sage: parent(m.rows()[0]) + sage: m = matrix(RR, 3, 3, {(1,2): pi, (2, 2): -1, (0,1): sqrt(2)}) # optional - sage.symbolic + sage: parent(m.rows()[0]) # optional - sage.symbolic Sparse vector space of dimension 3 over Real Field with 53 bits of precision Sparse matrices produce sparse rows. :: @@ -1081,7 +1084,7 @@ cdef class Matrix(Matrix0): An example over the integers:: - sage: a = matrix(3,3,range(9)); a + sage: a = matrix(3, 3, range(9)); a [0 1 2] [3 4 5] [6 7 8] @@ -1090,7 +1093,7 @@ cdef class Matrix(Matrix0): We do an example over a polynomial ring:: - sage: R. = QQ[ ] + sage: R. = QQ[] sage: a = matrix(R, 2, [x,x^2, 2/3*x,1+x^5]); a [ x x^2] [ 2/3*x x^5 + 1] @@ -1100,13 +1103,14 @@ cdef class Matrix(Matrix0): sage: c = a.dense_columns(); c [(x, 2/3*x), (x^2, x^5 + 1)] sage: parent(c[1]) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field + Ambient free module of rank 2 over the principal ideal domain + Univariate Polynomial Ring in x over Rational Field TESTS: Check that the returned rows are immutable as per :trac:`14874`:: - sage: m = Mat(ZZ,3,3)(range(9)) + sage: m = Mat(ZZ, 3, 3)(range(9)) sage: v = m.dense_columns() sage: [x.is_mutable() for x in v] [False, False, False] @@ -1160,7 +1164,7 @@ cdef class Matrix(Matrix0): Check that the returned rows are immutable as per :trac:`14874`:: - sage: m = Mat(ZZ,3,3)(range(9)) + sage: m = Mat(ZZ, 3, 3)(range(9)) sage: v = m.dense_rows() sage: [x.is_mutable() for x in v] [False, False, False] @@ -1196,7 +1200,7 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: a = matrix(2,3,range(6)); a + sage: a = matrix(2, 3, range(6)); a [0 1 2] [3 4 5] sage: v = a.sparse_columns(); v @@ -1216,7 +1220,7 @@ cdef class Matrix(Matrix0): Check that the returned columns are immutable as per :trac:`14874`:: - sage: m = Mat(ZZ,3,3,sparse=True)(range(9)) + sage: m = Mat(ZZ, 3, 3, sparse=True)(range(9)) sage: v = m.sparse_columns() sage: [x.is_mutable() for x in v] [False, False, False] @@ -1272,7 +1276,7 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: m = Mat(ZZ,3,3,sparse=True)(range(9)); m + sage: m = Mat(ZZ, 3, 3, sparse=True)(range(9)); m [0 1 2] [3 4 5] [6 7 8] @@ -1298,7 +1302,7 @@ cdef class Matrix(Matrix0): Check that the returned rows are immutable as per :trac:`14874`:: - sage: m = Mat(ZZ,3,3,sparse=True)(range(9)) + sage: m = Mat(ZZ, 3, 3, sparse=True)(range(9)) sage: v = m.sparse_rows() sage: [x.is_mutable() for x in v] [False, False, False] @@ -1363,7 +1367,7 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: a = matrix(2,3,range(6)); a + sage: a = matrix(2, 3, range(6)); a [0 1 2] [3 4 5] sage: a.column(1) @@ -1377,7 +1381,7 @@ cdef class Matrix(Matrix0): TESTS:: - sage: a = matrix(2,3,range(6)); a + sage: a = matrix(2, 3, range(6)); a [0 1 2] [3 4 5] sage: a.column(3) @@ -1422,7 +1426,7 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: a = matrix(2,3,range(6)); a + sage: a = matrix(2, 3, range(6)); a [0 1 2] [3 4 5] sage: a.row(0) @@ -1434,7 +1438,7 @@ cdef class Matrix(Matrix0): TESTS:: - sage: a = matrix(2,3,range(6)); a + sage: a = matrix(2, 3, range(6)); a [0 1 2] [3 4 5] sage: a.row(2) @@ -1614,13 +1618,15 @@ cdef class Matrix(Matrix0): [ 1.00000000000000 2.00000000000000] [0.891207360061435 0.808496403819590] sage: C.parent() - Full MatrixSpace of 2 by 2 dense matrices over Real Field with 53 bits of precision + Full MatrixSpace of 2 by 2 dense matrices + over Real Field with 53 bits of precision sage: D = B.stack(A); D [0.891207360061435 0.808496403819590] [ 1.00000000000000 2.00000000000000] sage: D.parent() - Full MatrixSpace of 2 by 2 dense matrices over Real Field with 53 bits of precision + Full MatrixSpace of 2 by 2 dense matrices + over Real Field with 53 bits of precision :: @@ -1632,7 +1638,8 @@ cdef class Matrix(Matrix0): [ 1 2/3] [ y y^2] sage: C.parent() - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field + Full MatrixSpace of 2 by 2 dense matrices + over Univariate Polynomial Ring in y over Rational Field Stacking a dense matrix atop a sparse one returns a sparse matrix:: @@ -1888,7 +1895,8 @@ cdef class Matrix(Matrix0): [0.89120736006... 1.00000000000000] [0.80849640381... 2.00000000000000] sage: D.parent() - Full MatrixSpace of 2 by 2 dense matrices over Real Field with 53 bits of precision + Full MatrixSpace of 2 by 2 dense matrices + over Real Field with 53 bits of precision Sometimes it is not possible to coerce into the base ring of ``self``. A solution is to change the base ring of ``self`` to @@ -1902,7 +1910,8 @@ cdef class Matrix(Matrix0): sage: C = B.augment(A); C [ y y^2 1 2] sage: C.parent() - Full MatrixSpace of 1 by 4 dense matrices over Univariate Polynomial Ring in y over Rational Field + Full MatrixSpace of 1 by 4 dense matrices + over Univariate Polynomial Ring in y over Rational Field sage: D = A.augment(B) Traceback (most recent call last): @@ -1913,7 +1922,8 @@ cdef class Matrix(Matrix0): sage: F = E.augment(B); F [ 1 2 y y^2] sage: F.parent() - Full MatrixSpace of 1 by 4 dense matrices over Univariate Polynomial Ring in y over Rational Field + Full MatrixSpace of 1 by 4 dense matrices + over Univariate Polynomial Ring in y over Rational Field AUTHORS: @@ -1963,7 +1973,7 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: M = MatrixSpace(Integers(8),3,3) + sage: M = MatrixSpace(Integers(8), 3, 3) sage: A = M(range(9)); A [0 1 2] [3 4 5] @@ -2002,7 +2012,7 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: A = Matrix(3,4,range(12)); A + sage: A = Matrix(3, 4, range(12)); A [ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11] @@ -2061,7 +2071,7 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: M = MatrixSpace(Integers(8),3,3) + sage: M = MatrixSpace(Integers(8), 3, 3) sage: A = M(range(9)); A [0 1 2] [3 4 5] @@ -2099,7 +2109,7 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: A = Matrix(4,3,range(12)); A + sage: A = Matrix(4, 3, range(12)); A [ 0 1 2] [ 3 4 5] [ 6 7 8] @@ -2157,7 +2167,7 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: M = MatrixSpace(Integers(8),3,3) + sage: M = MatrixSpace(Integers(8), 3, 3) sage: A = M(range(9)); A [0 1 2] [3 4 5] @@ -2179,7 +2189,7 @@ cdef class Matrix(Matrix0): :: - sage: A.matrix_from_rows_and_columns([1,1,1],[2,0,0]) + sage: A.matrix_from_rows_and_columns([1,1,1], [2,0,0]) [5 3 3] [5 3 3] [5 3 3] @@ -2399,7 +2409,8 @@ cdef class Matrix(Matrix0): sage: A.set_column(0, [1/4, 1]); A Traceback (most recent call last): ... - TypeError: Cannot set column with Rational Field elements over Integer Ring, use change_ring first. + TypeError: Cannot set column with Rational Field elements + over Integer Ring, use change_ring first. """ if len(v) != self._nrows: msg = "list of new entries must be of length {0} (not {1})" @@ -2449,7 +2460,7 @@ cdef class Matrix(Matrix0): Specify a different base ring for the output:: - sage: M.zero_pattern_matrix(GF(2)).base_ring() + sage: M.zero_pattern_matrix(GF(2)).base_ring() # optional - sage.rings.finite_rings Finite Field of size 2 Examples for different base rings for ``self``:: @@ -2465,36 +2476,36 @@ cdef class Matrix(Matrix0): :: - sage: W. = CyclotomicField(100) - sage: M = Matrix(2, 3, [a, a/2, 0, a^2, a^100-1, a^2 - a]); M + sage: W. = CyclotomicField(100) # optional - sage.rings.number_field + sage: M = Matrix(2, 3, [a, a/2, 0, a^2, a^100-1, a^2 - a]); M # optional - sage.rings.number_field [ a 1/2*a 0] [ a^2 0 a^2 - a] - sage: M.zero_pattern_matrix() + sage: M.zero_pattern_matrix() # optional - sage.rings.number_field [0 0 1] [0 1 0] :: - sage: K. = GF(2^4) - sage: l = [a^2 + 1, a^3 + 1, 0, 0, a, a^3 + a + 1, a + 1, + sage: K. = GF(2^4) # optional - sage.rings.finite_rings + sage: l = [a^2 + 1, a^3 + 1, 0, 0, a, a^3 + a + 1, a + 1, # optional - sage.rings.finite_rings ....: a + 1, a^2, a^3 + a + 1, a^3 + a, a^3 + a] - sage: M = Matrix(K, 3, 4, l); M + sage: M = Matrix(K, 3, 4, l); M # optional - sage.rings.finite_rings [ a^2 + 1 a^3 + 1 0 0] [ a a^3 + a + 1 a + 1 a + 1] [ a^2 a^3 + a + 1 a^3 + a a^3 + a] - sage: M.zero_pattern_matrix() + sage: M.zero_pattern_matrix() # optional - sage.rings.finite_rings [0 0 1 1] [0 0 0 0] [0 0 0 0] :: - sage: K. = GF(25) - sage: M = Matrix(K, 2, 3, [0, 2, 3, 5, a, a^2]) - sage: M + sage: K. = GF(25) # optional - sage.rings.finite_rings + sage: M = Matrix(K, 2, 3, [0, 2, 3, 5, a, a^2]) # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings [ 0 2 3] [ 0 a a + 3] - sage: M.zero_pattern_matrix() + sage: M.zero_pattern_matrix() # optional - sage.rings.finite_rings [1 0 0] [1 0 0] @@ -2581,7 +2592,7 @@ cdef class Matrix(Matrix0): dict items are ETuples (see :trac:`17658`):: sage: from sage.rings.polynomial.polydict import ETuple - sage: matrix(GF(5^2,"z"),{ETuple((1, 1)): 2}).dense_matrix() + sage: matrix(GF(5^2, "z"), {ETuple((1, 1)): 2}).dense_matrix() # optional - sage.rings.finite_rings [0 0] [0 2] """ @@ -2665,9 +2676,11 @@ cdef class Matrix(Matrix0): sage: M = MatrixSpace(QQ, 3, implementation='generic') sage: m = M.an_element() sage: m.matrix_space() - Full MatrixSpace of 3 by 3 dense matrices over Rational Field (using Matrix_generic_dense) + Full MatrixSpace of 3 by 3 dense matrices over Rational Field + (using Matrix_generic_dense) sage: m.matrix_space(nrows=2, ncols=12) - Full MatrixSpace of 2 by 12 dense matrices over Rational Field (using Matrix_generic_dense) + Full MatrixSpace of 2 by 12 dense matrices over Rational Field + (using Matrix_generic_dense) sage: m.matrix_space(nrows=2, sparse=True) Full MatrixSpace of 2 by 3 sparse matrices over Rational Field """ @@ -2739,16 +2752,19 @@ cdef class Matrix(Matrix0): [0.000000000000000 0.000000000000000 0.000000000000000] [0.000000000000000 0.000000000000000 0.000000000000000] sage: A.new_matrix().parent() - Full MatrixSpace of 2 by 3 dense matrices over Real Field with 53 bits of precision + Full MatrixSpace of 2 by 3 dense matrices + over Real Field with 53 bits of precision :: sage: M = MatrixSpace(ZZ, 2, 3, implementation='generic') sage: m = M.an_element() sage: m.new_matrix().parent() - Full MatrixSpace of 2 by 3 dense matrices over Integer Ring (using Matrix_generic_dense) + Full MatrixSpace of 2 by 3 dense matrices over Integer Ring + (using Matrix_generic_dense) sage: m.new_matrix(3,3).parent() - Full MatrixSpace of 3 by 3 dense matrices over Integer Ring (using Matrix_generic_dense) + Full MatrixSpace of 3 by 3 dense matrices over Integer Ring + (using Matrix_generic_dense) sage: m.new_matrix(3,3, sparse=True).parent() Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring """ diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index e2e6449dfa9..26f1fe4a6fa 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -168,16 +168,16 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: var('a,b,d,e') + sage: var('a,b,d,e') # optional - sage.symbolic (a, b, d, e) - sage: m = matrix([[a,b], [d,e]]) - sage: m.substitute(a=1) + sage: m = matrix([[a,b], [d,e]]) # optional - sage.symbolic + sage: m.substitute(a=1) # optional - sage.symbolic [1 b] [d e] - sage: m.subs(a=b, b=d) + sage: m.subs(a=b, b=d) # optional - sage.symbolic [b d] [d e] - sage: m.subs({a: 3, b:2, d:1, e:-1}) + sage: m.subs({a: 3, b: 2, d: 1, e: -1}) # optional - sage.symbolic [ 3 2] [ 1 -1] @@ -196,7 +196,7 @@ cdef class Matrix(Matrix1): However, sparse matrices remain sparse:: - sage: m = matrix({(3,2): -x, (59,38): x^2+2}, nrows=1000, ncols=1000) + sage: m = matrix({(3,2): -x, (59,38): x^2 + 2}, nrows=1000, ncols=1000) sage: m1 = m.subs(x=1) sage: m1.is_sparse() True @@ -267,8 +267,8 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQ,4,2, [0, -1, 1, 0, -2, 2, 1, 0]) - sage: B = matrix(QQ,2,2, [1, 0, 1, -1]) + sage: A = matrix(QQ, 4,2, [0, -1, 1, 0, -2, 2, 1, 0]) + sage: B = matrix(QQ, 2,2, [1, 0, 1, -1]) sage: X = A.solve_left(B) sage: X*A == B True @@ -307,7 +307,8 @@ cdef class Matrix(Matrix1): ....: [ 3*I, -1 - I, -1 + I, -3 + I]]) sage: b = vector(CDF, [2 -3*I, 3, -2 + 3*I, 8]) sage: x = A.solve_left(b); x - (-1.55765124... - 0.644483985...*I, 0.183274021... + 0.286476868...*I, 0.270818505... + 0.246619217...*I, -1.69003558... - 0.828113879...*I) + (-1.55765124... - 0.644483985...*I, 0.183274021... + 0.286476868...*I, + 0.270818505... + 0.246619217...*I, -1.69003558... - 0.828113879...*I) sage: x.parent() Vector space of dimension 4 over Complex Double Field sage: abs(x*A - b) < 1e-14 @@ -317,7 +318,7 @@ cdef class Matrix(Matrix1): sage: A = matrix(RDF, 3, 3, [2, 5, 0, 7, 7, -2, -4.3, 0, 1]) sage: b = matrix(RDF, 2, 3, [2, -4, -5, 1, 1, 0.1]) - sage: A.solve_left(b) # tol 1e-14 + sage: A.solve_left(b) # tol 1e-14 [ -6.495454545454545 4.068181818181818 3.1363636363636354] [ 0.5277272727272727 -0.2340909090909091 -0.36818181818181817] @@ -341,8 +342,8 @@ cdef class Matrix(Matrix1): TESTS:: - sage: A = matrix(QQ,4,2, [0, -1, 1, 0, -2, 2, 1, 0]) - sage: B = vector(QQ,2, [2,1]) + sage: A = matrix(QQ, 4,2, [0, -1, 1, 0, -2, 2, 1, 0]) + sage: B = vector(QQ, 2, [2,1]) sage: X = A.solve_left(B) sage: X*A == B True @@ -392,9 +393,9 @@ cdef class Matrix(Matrix1): The vector of constants needs to be compatible with the base ring of the coefficient matrix:: - sage: F. = FiniteField(27) - sage: b = vector(F, [a,a,a,a,a]) - sage: A.solve_left(b) + sage: F. = FiniteField(27) # optional - sage.rings.finite_rings + sage: b = vector(F, [a,a,a,a,a]) # optional - sage.rings.finite_rings + sage: A.solve_left(b) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: ... @@ -413,9 +414,9 @@ cdef class Matrix(Matrix1): any are inexact, however, the ``check`` is still skipped (:trac:`29729` and :trac:`33159`):: - sage: A = matrix(SR, [[1, 1]]) # optional - sage.symbolic - sage: b = vector(SR, [2, 3]) # optional - sage.symbolic - sage: A.solve_left(b) # optional - sage.symbolic + sage: A = matrix(SR, [[1, 1]]) # optional - sage.symbolic + sage: b = vector(SR, [2, 3]) # optional - sage.symbolic + sage: A.solve_left(b) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: matrix equation has no solutions @@ -423,7 +424,7 @@ cdef class Matrix(Matrix1): In this case, turning off the ``check`` leads to a wrong result:: - sage: A.solve_left(b, check=False) # optional - sage.symbolic + sage: A.solve_left(b, check=False) # optional - sage.symbolic (2) """ @@ -497,7 +498,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: A = matrix(QQ, 3, [1,2,3,-1,2,5,2,3,1]) - sage: b = vector(QQ,[1,2,3]) + sage: b = vector(QQ, [1,2,3]) sage: x = A \ b; x (-13/12, 23/12, -7/12) sage: A * x @@ -505,7 +506,8 @@ cdef class Matrix(Matrix1): We solve with A nonsquare:: - sage: A = matrix(QQ,2,4, [0, -1, 1, 0, -2, 2, 1, 0]); B = matrix(QQ,2,2, [1, 0, 1, -1]) + sage: A = matrix(QQ, 2,4, [0, -1, 1, 0, -2, 2, 1, 0]) + sage: B = matrix(QQ, 2,2, [1, 0, 1, -1]) sage: X = A.solve_right(B); X [-3/2 1/2] [ -1 0] @@ -516,7 +518,7 @@ cdef class Matrix(Matrix1): Another nonsingular example:: - sage: A = matrix(QQ,2,3, [1,2,3,2,4,6]); v = vector([-1/2,-1]) + sage: A = matrix(QQ, 2,3, [1,2,3,2,4,6]); v = vector([-1/2,-1]) sage: x = A \ v; x (-1/2, 0, 0) sage: A*x == v @@ -524,13 +526,13 @@ cdef class Matrix(Matrix1): Same example but over `\ZZ`:: - sage: A = matrix(ZZ,2,3, [1,2,3,2,4,6]); v = vector([-1,-2]) + sage: A = matrix(ZZ, 2,3, [1,2,3,2,4,6]); v = vector([-1,-2]) sage: A \ v (-1, 0, 0) An example in which there is no solution:: - sage: A = matrix(QQ,2,3, [1,2,3,2,4,6]); v = vector([1,1]) + sage: A = matrix(QQ, 2,3, [1,2,3,2,4,6]); v = vector([1,1]) sage: A \ v Traceback (most recent call last): ... @@ -538,8 +540,8 @@ cdef class Matrix(Matrix1): A ValueError is raised if the input is invalid:: - sage: A = matrix(QQ,4,2, [0, -1, 1, 0, -2, 2, 1, 0]) - sage: B = matrix(QQ,2,2, [1, 0, 1, -1]) + sage: A = matrix(QQ, 4,2, [0, -1, 1, 0, -2, 2, 1, 0]) + sage: B = matrix(QQ, 2,2, [1, 0, 1, -1]) sage: X = A.solve_right(B) Traceback (most recent call last): ... @@ -548,7 +550,7 @@ cdef class Matrix(Matrix1): We solve with A singular:: - sage: A = matrix(QQ,2,3, [1,2,3,2,4,6]); B = matrix(QQ,2,2, [6, -6, 12, -12]) + sage: A = matrix(QQ, 2,3, [1,2,3,2,4,6]); B = matrix(QQ, 2,2, [6, -6, 12, -12]) sage: X = A.solve_right(B); X [ 6 -6] [ 0 0] @@ -583,11 +585,12 @@ cdef class Matrix(Matrix1): Solving over a polynomial ring:: sage: x = polygen(QQ, 'x') - sage: A = matrix(2, [x,2*x,-5*x^2+1,3]) - sage: v = vector([3,4*x - 2]) + sage: A = matrix(2, [x, 2*x, -5*x^2 + 1, 3]) + sage: v = vector([3, 4*x - 2]) sage: X = A \ v sage: X - ((-4/5*x^2 + 2/5*x + 9/10)/(x^3 + 1/10*x), (19/10*x^2 - 1/5*x - 3/10)/(x^3 + 1/10*x)) + ((-4/5*x^2 + 2/5*x + 9/10)/(x^3 + 1/10*x), + (19/10*x^2 - 1/5*x - 3/10)/(x^3 + 1/10*x)) sage: A * X == v True @@ -595,58 +598,58 @@ cdef class Matrix(Matrix1): sage: A = Matrix(Zmod(6), 3, 2, [1,2,3,4,5,6]) sage: B = vector(Zmod(6), [1,1,1]) - sage: A.solve_right(B) + sage: A.solve_right(B) # optional - sage.libs.pari (5, 1) sage: B = vector(Zmod(6), [5,1,1]) - sage: A.solve_right(B) + sage: A.solve_right(B) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: matrix equation has no solutions sage: A = Matrix(Zmod(128), 2, 3, [23,11,22,4,1,0]) sage: B = Matrix(Zmod(128), 2, 1, [1,0]) - sage: A.solve_right(B) + sage: A.solve_right(B) # optional - sage.libs.pari [ 5] [108] [127] sage: B = B.column(0) - sage: A.solve_right(B) + sage: A.solve_right(B) # optional - sage.libs.pari (5, 108, 127) sage: A = Matrix(Zmod(15), 3,4, range(12)) sage: B = Matrix(Zmod(15), 3,3, range(3,12)) - sage: X = A.solve_right(B) - sage: A*X == B + sage: X = A.solve_right(B) # optional - sage.libs.pari + sage: A*X == B # optional - sage.libs.pari True Solving a system over the p-adics:: - sage: k = Qp(5,4) - sage: a = matrix(k, 3, [1,7,3,2,5,4,1,1,2]); a + sage: k = Qp(5, 4) # optional - sage.rings.padics + sage: a = matrix(k, 3, [1,7,3, 2,5,4, 1,1,2]); a # optional - sage.rings.padics [ 1 + O(5^4) 2 + 5 + O(5^4) 3 + O(5^4)] [ 2 + O(5^4) 5 + O(5^5) 4 + O(5^4)] [ 1 + O(5^4) 1 + O(5^4) 2 + O(5^4)] - sage: v = vector(k, 3, [1,2,3]) - sage: x = a \ v; x + sage: v = vector(k, 3, [1,2,3]) # optional - sage.rings.padics + sage: x = a \ v; x # optional - sage.rings.padics (4 + 5 + 5^2 + 3*5^3 + O(5^4), 2 + 5 + 3*5^2 + 5^3 + O(5^4), 1 + 5 + O(5^4)) - sage: a * x == v + sage: a * x == v # optional - sage.rings.padics True Solving a system of linear equations symbolically using symbolic matrices:: - sage: var('a,b,c,d,x,y') # optional - sage.symbolic + sage: var('a,b,c,d,x,y') # optional - sage.symbolic (a, b, c, d, x, y) - sage: A = matrix(SR, 2, [a,b,c,d]); A # optional - sage.symbolic + sage: A = matrix(SR, 2, [a,b,c,d]); A # optional - sage.symbolic [a b] [c d] - sage: result = vector(SR, [3,5]); result # optional - sage.symbolic + sage: result = vector(SR, [3,5]); result # optional - sage.symbolic (3, 5) - sage: soln = A.solve_right(result); soln # optional - sage.symbolic + sage: soln = A.solve_right(result); soln # optional - sage.symbolic (-b*(3*c/a - 5)/(a*(b*c/a - d)) + 3/a, (3*c/a - 5)/(b*c/a - d)) - sage: (a*x+b*y).subs(x=soln[0], y=soln[1]).simplify_full() # optional - sage.symbolic + sage: (a*x + b*y).subs(x=soln[0], y=soln[1]).simplify_full() # optional - sage.symbolic 3 - sage: (c*x+d*y).subs(x=soln[0], y=soln[1]).simplify_full() # optional - sage.symbolic + sage: (c*x + d*y).subs(x=soln[0], y=soln[1]).simplify_full() # optional - sage.symbolic 5 - sage: (A*soln).apply_map(lambda x: x.simplify_full()) # optional - sage.symbolic + sage: (A*soln).apply_map(lambda x: x.simplify_full()) # optional - sage.symbolic (3, 5) Over inexact rings, the output of this function may not be an exact @@ -666,7 +669,7 @@ cdef class Matrix(Matrix1): [ 1.0 2.0 5.0] [ 7.6 2.3 1.0] [ 1.0 2.0 -1.0] - sage: b = vector(RDF,[1,2,3]) + sage: b = vector(RDF, [1,2,3]) sage: x = A.solve_right(b); x # tol 1e-14 (-0.1136950904392765, 1.3901808785529717, -0.33333333333333337) sage: x.parent() @@ -680,9 +683,10 @@ cdef class Matrix(Matrix1): ....: [2 + 4*I, -2 + 3*I, -1 + 2*I, -1 - I], ....: [ 2 + I, 1 - I, -1, 5], ....: [ 3*I, -1 - I, -1 + I, -3 + I]]) - sage: b = vector(CDF, [2 -3*I, 3, -2 + 3*I, 8]) + sage: b = vector(CDF, [2 - 3*I, 3, -2 + 3*I, 8]) sage: x = A.solve_right(b); x - (1.96841637... - 1.07606761...*I, -0.614323843... + 1.68416370...*I, 0.0733985765... + 1.73487544...*I, -1.6018683... + 0.524021352...*I) + (1.96841637... - 1.07606761...*I, -0.614323843... + 1.68416370...*I, + 0.0733985765... + 1.73487544...*I, -1.6018683... + 0.524021352...*I) sage: x.parent() Vector space of dimension 4 over Complex Double Field sage: abs(A*x - b) < 1e-14 @@ -692,7 +696,7 @@ cdef class Matrix(Matrix1): sage: A = matrix(RDF, 3, 3, [1, 2, 2, 3, 4, 5, 2, 2, 2]) sage: b = matrix(RDF, 3, 2, [3, 2, 3, 2, 3, 2]) - sage: A.solve_right(b) # tol 1e-14 + sage: A.solve_right(b) # tol 1e-14 [ 0.0 0.0] [ 4.5 3.0] [-3.0 -2.0] @@ -737,7 +741,7 @@ cdef class Matrix(Matrix1): sage: A = Matrix(Zmod(6), 3, 2, [1,2,3,4,5,6]) sage: b = vector(ZZ, [1,1,1]) - sage: A.solve_right(b).base_ring() is Zmod(6) + sage: A.solve_right(b).base_ring() is Zmod(6) # optional - sage.libs.pari True Check that the coercion mechanism gives consistent results @@ -778,9 +782,9 @@ cdef class Matrix(Matrix1): The vector of constants needs to be compatible with the base ring of the coefficient matrix. :: - sage: F. = FiniteField(27) - sage: b = vector(F, [a,a,a,a,a]) - sage: A.solve_right(b) + sage: F. = FiniteField(27) # optional - sage.rings.finite_rings + sage: b = vector(F, [a,a,a,a,a]) # optional - sage.rings.finite_rings + sage: A.solve_right(b) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: ... @@ -816,31 +820,31 @@ cdef class Matrix(Matrix1): any are inexact, however, the ``check`` is still skipped (:trac:`29729` and :trac:`33159`):: - sage: m = matrix(SR, [0]) # optional - sage.symbolic - sage: b = vector(SR, [1]) # optional - sage.symbolic - sage: m.solve_right(b, check=True) # optional - sage.symbolic + sage: m = matrix(SR, [0]) # optional - sage.symbolic + sage: b = vector(SR, [1]) # optional - sage.symbolic + sage: m.solve_right(b, check=True) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: matrix equation has no solutions In this case, turning off the ``check`` leads to a wrong result:: - sage: m.solve_right(b, check=False) # optional - sage.symbolic + sage: m.solve_right(b, check=False) # optional - sage.symbolic (0) In the following, we have an inexact entry in the matrix, so the ``check`` is still skipped leading to a wrong result:: - sage: m = matrix(SR, [0.0]) # optional - sage.symbolic - sage: m.solve_right(b, check=True) # optional - sage.symbolic + sage: m = matrix(SR, [0.0]) # optional - sage.symbolic + sage: m.solve_right(b, check=True) # optional - sage.symbolic (0) :: - sage: SC = SR.subring(no_variables=True) # optional - sage.symbolic - sage: m = matrix(SC, [0]) # optional - sage.symbolic - sage: b = vector(SC, [1]) # optional - sage.symbolic - sage: m.solve_right(b) # optional - sage.symbolic + sage: SC = SR.subring(no_variables=True) # optional - sage.symbolic + sage: m = matrix(SC, [0]) # optional - sage.symbolic + sage: b = vector(SC, [1]) # optional - sage.symbolic + sage: m.solve_right(b) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: matrix equation has no solutions @@ -943,8 +947,8 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQ,3,[1,2,4,5,3,1,1,2,-1]) - sage: B = matrix(QQ,3,2,[1,5,1,2,1,5]) + sage: A = matrix(QQ, 3, [1,2,4,5,3,1,1,2,-1]) + sage: B = matrix(QQ, 3,2, [1,5,1,2,1,5]) sage: A._solve_right_nonsingular_square(B) [ -1/7 -11/7] [ 4/7 23/7] @@ -975,7 +979,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQ,3,3, [0,0,0,1,2,3,2,4,6]); A + sage: A = matrix(QQ, 3,3, [0,0,0,1,2,3,2,4,6]); A [0 0 0] [1 2 3] [2 4 6] @@ -1011,7 +1015,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQ,2,3, [1,2,3,2,4,6]); B = matrix(QQ,2,2, [6, -6, 12, -12]) + sage: A = matrix(QQ, 2,3, [1,2,3,2,4,6]); B = matrix(QQ, 2,2, [6, -6, 12, -12]) sage: A._solve_right_general(B) [ 6 -6] [ 0 0] @@ -1120,6 +1124,7 @@ cdef class Matrix(Matrix1): Notice the base ring of the results in the next two examples. :: + sage: x = polygen(ZZ, 'x') sage: D = matrix(ZZ['x'],2,[1+x^2,2,3,4-x]) sage: E = matrix(QQ,2,[1,2,3,4]) sage: F = D.elementwise_product(E) @@ -1127,63 +1132,72 @@ cdef class Matrix(Matrix1): [ x^2 + 1 4] [ 9 -4*x + 16] sage: F.parent() - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field + Full MatrixSpace of 2 by 2 dense matrices + over Univariate Polynomial Ring in x over Rational Field :: - sage: G = matrix(GF(3),2,[0,1,2,2]) - sage: H = matrix(ZZ,2,[1,2,3,4]) - sage: J = G.elementwise_product(H) - sage: J + sage: G = matrix(GF(3), 2, [0, 1, 2, 2]) # optional - sage.rings.finite_rings + sage: H = matrix(ZZ, 2, [1, 2, 3, 4]) + sage: J = G.elementwise_product(H) # optional - sage.rings.finite_rings + sage: J # optional - sage.rings.finite_rings [0 2] [0 2] - sage: J.parent() - Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 + sage: J.parent() # optional - sage.rings.finite_rings + Full MatrixSpace of 2 by 2 dense matrices + over Finite Field of size 3 Non-commutative rings behave as expected. These are the usual quaternions. :: - sage: R. = QuaternionAlgebra(-1, -1) - sage: A = matrix(R, 2, [1,i,j,k]) - sage: B = matrix(R, 2, [i,i,i,i]) - sage: A.elementwise_product(B) + sage: R. = QuaternionAlgebra(-1, -1) # optional - sage.combinat + sage: A = matrix(R, 2, [1,i,j,k]) # optional - sage.combinat + sage: B = matrix(R, 2, [i,i,i,i]) # optional - sage.combinat + sage: A.elementwise_product(B) # optional - sage.combinat [ i -1] [-k j] - sage: B.elementwise_product(A) + sage: B.elementwise_product(A) # optional - sage.combinat [ i -1] [ k -j] Input that is not a matrix will raise an error. :: - sage: A = random_matrix(ZZ,5,10,x=20) + sage: A = random_matrix(ZZ, 5, 10, x=20) sage: A.elementwise_product(vector(ZZ, [1,2,3,4])) Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Full MatrixSpace of 5 by 10 dense matrices over Integer Ring' and 'Ambient free module of rank 4 over the principal ideal domain Integer Ring' + TypeError: no common canonical parent for objects with parents: + 'Full MatrixSpace of 5 by 10 dense matrices over Integer Ring' and + 'Ambient free module of rank 4 over the principal ideal domain Integer Ring' sage: A = matrix(2, 2, range(4)) sage: A.elementwise_product(polygen(parent(A))) Traceback (most recent call last): ... - TypeError: elementwise_product() argument should be a matrix or coercible to a matrix + TypeError: elementwise_product() argument should be a matrix + or coercible to a matrix Matrices of different sizes for operands will raise an error. :: - sage: A = random_matrix(ZZ,5,10,x=20) - sage: B = random_matrix(ZZ,10,5,x=40) + sage: A = random_matrix(ZZ, 5, 10, x=20) + sage: B = random_matrix(ZZ, 10, 5, x=40) sage: A.elementwise_product(B) Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Full MatrixSpace of 5 by 10 dense matrices over Integer Ring' and 'Full MatrixSpace of 10 by 5 dense matrices over Integer Ring' + TypeError: no common canonical parent for objects with parents: + 'Full MatrixSpace of 5 by 10 dense matrices over Integer Ring' and + 'Full MatrixSpace of 10 by 5 dense matrices over Integer Ring' Some pairs of rings do not have a common parent where multiplication makes sense. This will raise an error. :: sage: A = matrix(QQ, 3, 2, range(6)) - sage: B = matrix(GF(3), 3, [2]*6) - sage: A.elementwise_product(B) + sage: B = matrix(GF(3), 3, [2]*6) # optional - sage.rings.finite_rings + sage: A.elementwise_product(B) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Full MatrixSpace of 3 by 2 dense matrices over Rational Field' and 'Full MatrixSpace of 3 by 2 dense matrices over Finite Field of size 3' + TypeError: no common canonical parent for objects with parents: + 'Full MatrixSpace of 3 by 2 dense matrices over Rational Field' and + 'Full MatrixSpace of 3 by 2 dense matrices over Finite Field of size 3' We illustrate various combinations of sparse and dense matrices. The usual coercion rules apply:: @@ -1288,7 +1302,7 @@ cdef class Matrix(Matrix1): sage: A.permanent() 24 - sage: A = matrix(3,6,[1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1]) + sage: A = matrix(3,6, [1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1]) sage: A.permanent() 36 sage: B = A.change_ring(RR) @@ -1307,7 +1321,7 @@ cdef class Matrix(Matrix1): :: - sage: A = matrix(4,5,[1,1,0,1,1,0,1,1,1,1,1,0,1,0,1,1,1,0,1,0]) + sage: A = matrix(4,5, [1,1,0,1,1,0,1,1,1,1,1,0,1,0,1,1,1,0,1,0]) sage: A.permanent() 32 @@ -1323,21 +1337,21 @@ cdef class Matrix(Matrix1): :: - sage: A = matrix(QQ,2,2,[1/5,2/7,3/2,4/5]) + sage: A = matrix(QQ, 2,2, [1/5,2/7,3/2,4/5]) sage: A.permanent() 103/175 :: sage: R. = PolynomialRing(ZZ) - sage: A = matrix(R,2,2,[a,1,a,a+1]) + sage: A = matrix(R, 2,2, [a,1,a,a+1]) sage: A.permanent() a^2 + 2*a :: - sage: R. = PolynomialRing(ZZ,2) - sage: A = matrix(R,2,2,[x, y, x^2, y^2]) + sage: R. = PolynomialRing(ZZ, 2) + sage: A = matrix(R, 2,2, [x, y, x^2, y^2]) sage: A.permanent() x^2*y + x*y^2 """ @@ -1416,13 +1430,13 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(4,[1,0,1,0,1,0,1,0,1,0,10,10,1,0,1,1]) + sage: A = matrix(4, [1,0,1,0,1,0,1,0,1,0,10,10,1,0,1,1]) sage: A.permanental_minor(2) 114 :: - sage: A = matrix(3,6,[1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1]) + sage: A = matrix(3,6, [1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1]) sage: A.permanental_minor(0) 1 sage: A.permanental_minor(1) @@ -1443,7 +1457,8 @@ cdef class Matrix(Matrix1): sage: m, n = 3, 6 sage: C = matrix(m, n, lambda i,j: 1 - A[i,j]) - sage: sum((-1)^k * C.permanental_minor(k)*factorial(n-k)/factorial(n-m) for k in range(m+1)) + sage: sum((-1)^k * C.permanental_minor(k)*factorial(n-k)/factorial(n-m) + ....: for k in range(m+1)) 36 See Theorem 7.2.1 of Brualdi and Ryser: Combinatorial Matrix @@ -1545,28 +1560,28 @@ cdef class Matrix(Matrix1): Beware that the ``exact`` algorithm is not numerically stable, but the default ``numpy`` algorithm is:: - sage: M = matrix.hilbert(12,ring=RR) - sage: (~M*M).norm() # a considerable error + sage: M = matrix.hilbert(12, ring=RR) + sage: (~M * M).norm() # a considerable error 1.3... sage: Mx = M.pseudoinverse(algorithm="exact") - sage: (Mx*M).norm() # huge error + sage: (Mx * M).norm() # huge error 11.5... - sage: Mx = M.pseudoinverse(algorithm="numpy") - sage: (Mx*M).norm() # still OK + sage: Mx = M.pseudoinverse(algorithm="numpy") # optional - numpy + sage: (Mx * M).norm() # still OK 1.00... When multiplying the given matrix with the pseudoinverse, the result is symmetric for the ``exact`` algorithm or hermitian for the ``exactconj`` algorithm:: - sage: M = matrix(QQbar, 2, 2, [1, sqrt(-3), -sqrt(-3), 3]) - sage: M * M.pseudoinverse() + sage: M = matrix(QQbar, 2, 2, [1, sqrt(-3), -sqrt(-3), 3]) # optional - sage.rings.number_field sage.symbolic + sage: M * M.pseudoinverse() # optional - sage.rings.number_field sage.symbolic [ 0.2500000000000000? 0.4330127018922193?*I] [-0.4330127018922193?*I 0.750000000000000?] - sage: M * M.pseudoinverse(algorithm="exactconj") + sage: M * M.pseudoinverse(algorithm="exactconj") # optional - sage.rings.number_field sage.symbolic [ 1/4 0.4330127018922193?*I] [-0.4330127018922193?*I 3/4] - sage: M * M.pseudoinverse(algorithm="exact") + sage: M * M.pseudoinverse(algorithm="exact") # optional - sage.rings.number_field sage.symbolic [ -1/2 0.866025403784439?*I] [0.866025403784439?*I 3/2] @@ -1583,13 +1598,13 @@ cdef class Matrix(Matrix1): Numpy gives a strange answer due to rounding errors:: - sage: M.pseudoinverse(algorithm="numpy") # random + sage: M.pseudoinverse(algorithm="numpy") # random # optional - numpy [-1286742750677287/643371375338643 1000799917193445/1000799917193444] [ 519646110850445/346430740566963 -300239975158034/600479950316067] Although it is not too far off:: - sage: (~M-M.pseudoinverse(algorithm="numpy")).norm() < 1e-14 + sage: (~M - M.pseudoinverse(algorithm="numpy")).norm() < 1e-14 # optional - numpy True TESTS:: @@ -1758,20 +1773,20 @@ cdef class Matrix(Matrix1): An example with an exotic matrix (for which only Butera-Pernici and Ryser algorithms are available):: - sage: R. = PolynomialRing(GF(5)) - sage: A = matrix(R,[[1,x,y],[x*y,x**2+y,0]]) - sage: A.rook_vector(algorithm="ButeraPernici") + sage: R. = PolynomialRing(GF(5)) # optional - sage.rings.finite_rings + sage: A = matrix(R, [[1, x, y], [x*y, x**2+y, 0]]) # optional - sage.rings.finite_rings + sage: A.rook_vector(algorithm="ButeraPernici") # optional - sage.rings.finite_rings [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] - sage: A.rook_vector(algorithm="Ryser") + sage: A.rook_vector(algorithm="Ryser") # optional - sage.rings.finite_rings [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] - sage: A.rook_vector(algorithm="Godsil") + sage: A.rook_vector(algorithm="Godsil") # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: coefficients must be zero or one, but we have 'x' in position (0,1). - sage: B = A.transpose() - sage: B.rook_vector(algorithm="ButeraPernici") + sage: B = A.transpose() # optional - sage.rings.finite_rings + sage: B.rook_vector(algorithm="ButeraPernici") # optional - sage.rings.finite_rings [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] - sage: B.rook_vector(algorithm="Ryser") + sage: B.rook_vector(algorithm="Ryser") # optional - sage.rings.finite_rings [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] TESTS:: @@ -1900,7 +1915,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = Matrix(ZZ,2,3,[1,2,3,4,5,6]); A + sage: A = Matrix(ZZ, 2,3, [1,2,3,4,5,6]); A [1 2 3] [4 5 6] sage: A.minors(2) @@ -1914,15 +1929,17 @@ cdef class Matrix(Matrix1): :: - sage: k = GF(37) - sage: P. = PolynomialRing(k) - sage: A = Matrix(P,2,3,[x0*x1, x0, x1, x2, x2 + 16, x2 + 5*x1 ]) - sage: A.minors(2) - [x0*x1*x2 + 16*x0*x1 - x0*x2, 5*x0*x1^2 + x0*x1*x2 - x1*x2, 5*x0*x1 + x0*x2 - x1*x2 - 16*x1] + sage: k = GF(37) # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(k) # optional - sage.rings.finite_rings + sage: A = Matrix(P, 2, 3, [x0*x1, x0, x1, x2, x2 + 16, x2 + 5*x1]) # optional - sage.rings.finite_rings + sage: A.minors(2) # optional - sage.rings.finite_rings + [x0*x1*x2 + 16*x0*x1 - x0*x2, + 5*x0*x1^2 + x0*x1*x2 - x1*x2, + 5*x0*x1 + x0*x2 - x1*x2 - 16*x1] This test addresses an issue raised at :trac:`20512`:: - sage: A.minors(0)[0].parent() == P + sage: A.minors(0)[0].parent() == P # optional - sage.rings.finite_rings True """ from sage.combinat.combination import Combinations @@ -1942,7 +1959,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = MatrixSpace(Integers(8),3)([1,7,3, 1,1,1, 3,4,5]) + sage: A = MatrixSpace(Integers(8), 3)([1,7,3, 1,1,1, 3,4,5]) sage: A.det() 6 """ @@ -1975,7 +1992,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = MatrixSpace(Integers(8),3)([1,7,3, 1,1,1, 3,4,5]) + sage: A = MatrixSpace(Integers(8), 3)([1,7,3, 1,1,1, 3,4,5]) sage: A.determinant() 6 sage: A.determinant() is A.determinant() @@ -1986,8 +2003,8 @@ cdef class Matrix(Matrix1): We compute the determinant of the arbitrary 3x3 matrix:: - sage: R = PolynomialRing(QQ,9,'x') - sage: A = matrix(R,3,R.gens()) + sage: R = PolynomialRing(QQ, 9, 'x') + sage: A = matrix(R, 3, R.gens()) sage: A [x0 x1 x2] [x3 x4 x5] @@ -2000,7 +2017,7 @@ cdef class Matrix(Matrix1): :: - sage: R. = PolynomialRing(IntegerRing(),2) + sage: R. = PolynomialRing(IntegerRing(), 2) sage: A = MatrixSpace(R,2)([x, y, x**2, y**2]) sage: A.determinant() -x^2*y + x*y^2 @@ -2013,35 +2030,40 @@ cdef class Matrix(Matrix1): TESTS:: - sage: A = matrix(5, 5, [next_prime(i^2) for i in range(25)]) - sage: B = MatrixSpace(ZZ['x'], 5, 5)(A) - sage: A.det() - B.det() + sage: A = matrix(5, 5, [next_prime(i^2) for i in range(25)]) # optional - sage.libs.pari + sage: B = MatrixSpace(ZZ['x'], 5, 5)(A) # optional - sage.libs.pari + sage: A.det() - B.det() # optional - sage.libs.pari 0 We verify that :trac:`5569` is resolved (otherwise the following would hang for hours):: - sage: d = random_matrix(GF(next_prime(10^20)),50).det() - sage: d = random_matrix(Integers(10^50),50).det() + sage: d = random_matrix(GF(next_prime(10^20)), 50).det() # optional - sage.rings.finite_rings + sage: d = random_matrix(Integers(10^50), 50).det() # optional - sage.rings.finite_rings We verify that :trac:`7704` is resolved:: - sage: matrix(ZZ, {(0,0):1,(1,1):2,(2,2):3,(3,3):4}).det() + sage: matrix(ZZ, {(0,0): 1, (1,1): 2, (2,2): 3, (3,3): 4}).det() 24 - sage: matrix(QQ, {(0,0):1,(1,1):2,(2,2):3,(3,3):4}).det() + sage: matrix(QQ, {(0,0): 1, (1,1): 2, (2,2): 3, (3,3): 4}).det() 24 We verify that :trac:`10063` is resolved:: - sage: A = GF(2)['x,y,z'] - sage: A.inject_variables() + sage: A = GF(2)['x,y,z'] # optional - sage.rings.finite_rings + sage: A.inject_variables() # optional - sage.rings.finite_rings Defining x, y, z - sage: R = A.quotient(x^2 + 1).quotient(y^2 + 1).quotient(z^2 + 1) - sage: R.inject_variables() + sage: R = A.quotient(x^2 + 1).quotient(y^2 + 1).quotient(z^2 + 1) # optional - sage.rings.finite_rings + sage: R.inject_variables() # optional - sage.rings.finite_rings Defining xbarbarbar, ybarbarbar, zbarbarbar - sage: M = matrix([[1,1,1,1],[xbarbarbar,ybarbarbar,1,1],[0,1,zbarbarbar,1],[xbarbarbar,zbarbarbar,1,1]]) - sage: M.determinant() - xbarbarbar*ybarbarbar*zbarbarbar + xbarbarbar*ybarbarbar + xbarbarbar*zbarbarbar + ybarbarbar*zbarbarbar + xbarbarbar + ybarbarbar + zbarbarbar + 1 + sage: M = matrix([[1, 1, 1, 1], # optional - sage.rings.finite_rings + ....: [xbarbarbar, ybarbarbar, 1, 1], + ....: [0, 1, zbarbarbar, 1], + ....: [xbarbarbar, zbarbarbar, 1, 1]]) + sage: M.determinant() # optional - sage.rings.finite_rings + xbarbarbar*ybarbarbar*zbarbarbar + xbarbarbar*ybarbarbar + + xbarbarbar*zbarbarbar + ybarbarbar*zbarbarbar + xbarbarbar + + ybarbarbar + zbarbarbar + 1 Check that the determinant is computed from a cached charpoly properly:: @@ -2203,14 +2225,14 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(SR, 2, lambda i, j: f'a{i}{j}'); A # optional - sage.symbolic + sage: A = matrix(SR, 2, lambda i, j: f'a{i}{j}'); A # optional - sage.symbolic [a00 a01] [a10 a11] - sage: A.quantum_determinant() # optional - sage.symbolic + sage: A.quantum_determinant() # optional - sage.symbolic -a01*a10*q + a00*a11 - sage: A = matrix(SR, 3, lambda i, j: f'a{i}{j}') # optional - sage.symbolic - sage: A.quantum_determinant() # optional - sage.symbolic + sage: A = matrix(SR, 3, lambda i, j: f'a{i}{j}') # optional - sage.symbolic + sage: A.quantum_determinant() # optional - sage.symbolic -a02*a11*a20*q^3 + (a01*a12*a20 + a02*a10*a21)*q^2 + (-a00*a12*a21 - a01*a10*a22)*q + a00*a11*a22 @@ -2222,17 +2244,17 @@ cdef class Matrix(Matrix1): sage: A.quantum_determinant(q^-2) 7*q^-6 + q^-4 + q^-2 + 5 - sage: S. = PolynomialRing(GF(7)) - sage: R. = LaurentPolynomialRing(S) - sage: MS = MatrixSpace(S, 3, sparse=True) - sage: A = MS([[x, y, 3], [4, 2+y, x^2], [0, 1-x, x+y]]) - sage: A.det() + sage: S. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings + sage: R. = LaurentPolynomialRing(S) # optional - sage.rings.finite_rings + sage: MS = MatrixSpace(S, 3, sparse=True) # optional - sage.rings.finite_rings + sage: A = MS([[x, y, 3], [4, 2+y, x^2], [0, 1-x, x+y]]) # optional - sage.rings.finite_rings + sage: A.det() # optional - sage.rings.finite_rings x^4 - x^3 + x^2*y + x*y^2 + 2*x^2 - 2*x*y + 3*y^2 + 2*x - 2 - sage: A.quantum_determinant() + sage: A.quantum_determinant() # optional - sage.rings.finite_rings (2*x - 2)*q^2 + (x^4 - x^3 + 3*x*y + 3*y^2)*q + x^2*y + x*y^2 + 2*x^2 + 2*x*y - sage: A.quantum_determinant(int(2)) + sage: A.quantum_determinant(int(2)) # optional - sage.rings.finite_rings 2*x^4 - 2*x^3 + x^2*y + x*y^2 + 2*x^2 + x*y - y^2 + x - 1 - sage: A.quantum_determinant(q*x + q^-1*y) + sage: A.quantum_determinant(q*x + q^-1*y) # optional - sage.rings.finite_rings (2*x*y^2 - 2*y^2)*q^-2 + (x^4*y - x^3*y + 3*x*y^2 + 3*y^3)*q^-1 + (-2*x^2*y + x*y^2 + 2*x^2 - 2*x*y) + (x^5 - x^4 + 3*x^2*y + 3*x*y^2)*q + (2*x^3 - 2*x^2)*q^2 @@ -2400,13 +2422,13 @@ cdef class Matrix(Matrix1): In order to use the Bär-Faddeev-LeVerrier algorithm, the base ring must have characteristic zero:: - sage: A = matrix(GF(5), [(0, 3, 4, 1, 3, 4), + sage: A = matrix(GF(5), [(0, 3, 4, 1, 3, 4), # optional - sage.rings.finite_rings ....: (2, 0, 2, 0, 1, 0), ....: (1, 3, 0, 4, 1, 0), ....: (4, 0, 1, 0, 2, 0), ....: (2, 4, 4, 3, 0, 0), ....: (1, 0, 0, 0, 0, 0)]) - sage: A.pfaffian(algorithm='bfl') + sage: A.pfaffian(algorithm='bfl') # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: Bär-Faddeev-LeVerrier algorithm not applicable, @@ -2414,7 +2436,7 @@ cdef class Matrix(Matrix1): In that case, the definition by perfect matchings is used instead:: - sage: A.pfaffian() + sage: A.pfaffian() # optional - sage.combinat sage.rings.finite_rings 2 """ @@ -2499,7 +2521,7 @@ cdef class Matrix(Matrix1): ....: (2, -1, 0, 0, 1, 5/2), ....: (-2, 1, -3/2, -1, 0, 1/2), ....: (1/2, -3/2, -1, -5/2, -1/2, 0)]) - sage: A._pf_perfect_matchings() + sage: A._pf_perfect_matchings() # optional - sage.combinat -1/2 """ @@ -2555,9 +2577,9 @@ cdef class Matrix(Matrix1): TESTS:: - sage: A = random_matrix(ZZ[x], 6) + sage: A = random_matrix(ZZ['x'], 6) sage: A = A - A.transpose() - sage: A.pfaffian(algorithm='bfl') == A._pf_perfect_matchings() + sage: A.pfaffian(algorithm='bfl') == A._pf_perfect_matchings() # optional - sage.combinat True """ @@ -2602,13 +2624,14 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: m = matrix(ZZ, 3, 3, range(9)) - sage: phi = ZZ.hom(GF(5)) - sage: m.apply_morphism(phi) + sage: phi = ZZ.hom(GF(5)) # optional - sage.rings.finite_rings + sage: m.apply_morphism(phi) # optional - sage.rings.finite_rings [0 1 2] [3 4 0] [1 2 3] - sage: parent(m.apply_morphism(phi)) - Full MatrixSpace of 3 by 3 dense matrices over Finite Field of size 5 + sage: parent(m.apply_morphism(phi)) # optional - sage.rings.finite_rings + Full MatrixSpace of 3 by 3 dense matrices + over Finite Field of size 5 We apply a morphism to a matrix over a polynomial ring:: @@ -2650,27 +2673,29 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: m = matrix(ZZ, 3, 3, range(9)) - sage: k. = GF(9) - sage: f = lambda x: k(x) - sage: n = m.apply_map(f); n + sage: k. = GF(9) # optional - sage.rings.finite_rings + sage: f = lambda x: k(x) # optional - sage.rings.finite_rings + sage: n = m.apply_map(f); n # optional - sage.rings.finite_rings [0 1 2] [0 1 2] [0 1 2] - sage: n.parent() - Full MatrixSpace of 3 by 3 dense matrices over Finite Field in a of size 3^2 + sage: n.parent() # optional - sage.rings.finite_rings + Full MatrixSpace of 3 by 3 dense matrices + over Finite Field in a of size 3^2 In this example, we explicitly specify the codomain. :: - sage: s = GF(3) - sage: f = lambda x: s(x) - sage: n = m.apply_map(f, k); n + sage: s = GF(3) # optional - sage.rings.finite_rings + sage: f = lambda x: s(x) # optional - sage.rings.finite_rings + sage: n = m.apply_map(f, k); n # optional - sage.rings.finite_rings [0 1 2] [0 1 2] [0 1 2] - sage: n.parent() - Full MatrixSpace of 3 by 3 dense matrices over Finite Field in a of size 3^2 + sage: n.parent() # optional - sage.rings.finite_rings + Full MatrixSpace of 3 by 3 dense matrices + over Finite Field in a of size 3^2 If self is subdivided, the result will be as well:: @@ -2763,7 +2788,7 @@ cdef class Matrix(Matrix1): sage: a = matrix(QQ, 2,2, [1,2,3,4]); a [1 2] [3 4] - sage: a.characteristic_polynomial('T') + sage: a.characteristic_polynomial('T') # optional - sage.libs.pari T^2 - 5*T - 2 """ return self.charpoly(*args, **kwds) @@ -2775,9 +2800,9 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: a = matrix(QQ, 4, 4, range(16)) - sage: a.minimal_polynomial('z') + sage: a.minimal_polynomial('z') # optional - sage.libs.pari z^3 - 30*z^2 - 80*z - sage: a.minpoly() + sage: a.minpoly() # optional - sage.libs.pari x^3 - 30*x^2 - 80*x """ return self.minpoly(var, **kwds) @@ -2792,18 +2817,18 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(GF(9,'c'), 4, [1, 1, 0,0, 0,1,0,0, 0,0,5,0, 0,0,0,5]) - sage: factor(A.minpoly()) + sage: A = matrix(GF(9, 'c'), 4, [1,1,0,0, 0,1,0,0, 0,0,5,0, 0,0,0,5]) # optional - sage.rings.finite_rings + sage: factor(A.minpoly()) # optional - sage.rings.finite_rings (x + 1) * (x + 2)^2 - sage: A.minpoly()(A) == 0 + sage: A.minpoly()(A) == 0 # optional - sage.rings.finite_rings True - sage: factor(A.charpoly()) + sage: factor(A.charpoly()) # optional - sage.rings.finite_rings (x + 1)^2 * (x + 2)^2 The default variable name is `x`, but you can specify another name:: - sage: factor(A.minpoly('y')) + sage: factor(A.minpoly('y')) # optional - sage.rings.finite_rings (y + 1) * (y + 2)^2 """ f = self.fetch('minpoly') @@ -2850,8 +2875,8 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: a = matrix([[1,2],[3,4]]) - sage: a._test_minpoly() + sage: a = matrix([[1,2], [3,4]]) # optional - sage.libs.pari + sage: a._test_minpoly() # optional - sage.libs.pari """ if self.nrows() == self.ncols() and self.base_ring().is_exact(): tester = self._tester(**options) @@ -2911,8 +2936,8 @@ cdef class Matrix(Matrix1): An example over `\QQ`:: - sage: A = MatrixSpace(QQ,3)(range(9)) - sage: A.charpoly('x') + sage: A = MatrixSpace(QQ, 3)(range(9)) + sage: A.charpoly('x') # optional - sage.libs.pari x^3 - 12*x^2 - 18*x sage: A.trace() 12 @@ -2923,13 +2948,14 @@ cdef class Matrix(Matrix1): polynomial ring `\ZZ[a]`:: sage: R. = PolynomialRing(ZZ) - sage: M = MatrixSpace(R,2)([a,1, a,a+1]); M + sage: M = MatrixSpace(R, 2)([a,1, a,a+1]); M [ a 1] [ a a + 1] sage: f = M.charpoly('x'); f x^2 + (-2*a - 1)*x + a^2 sage: f.parent() - Univariate Polynomial Ring in x over Univariate Polynomial Ring in a over Integer Ring + Univariate Polynomial Ring in x + over Univariate Polynomial Ring in a over Integer Ring sage: M.trace() 2*a + 1 sage: M.determinant() @@ -2939,7 +2965,7 @@ cdef class Matrix(Matrix1): multi-variate polynomial ring `\ZZ[x,y]`:: sage: R. = PolynomialRing(ZZ,2) - sage: A = MatrixSpace(R,2)([x, y, x^2, y^2]) + sage: A = MatrixSpace(R, 2)([x, y, x^2, y^2]) sage: f = A.charpoly('x'); f x^2 + (-y^2 - x)*x - x^2*y + x*y^2 @@ -2957,16 +2983,16 @@ cdef class Matrix(Matrix1): Here is an example over a number field:: sage: x = QQ['x'].gen() - sage: K. = NumberField(x^2 - 2) - sage: m = matrix(K, [[a-1, 2], [a, a+1]]) - sage: m.charpoly('Z') + sage: K. = NumberField(x^2 - 2) # optional - sage.rings.number_field + sage: m = matrix(K, [[a-1, 2], [a, a+1]]) # optional - sage.rings.number_field + sage: m.charpoly('Z') # optional - sage.rings.number_field Z^2 - 2*a*Z - 2*a + 1 - sage: m.charpoly('a')(m) == 0 + sage: m.charpoly('a')(m) == 0 # optional - sage.rings.number_field True Over integers modulo `n` with composite `n`:: - sage: A = Mat(Integers(6),3,3)(range(9)) + sage: A = Mat(Integers(6), 3, 3)(range(9)) sage: A.charpoly() x^3 @@ -2977,7 +3003,7 @@ cdef class Matrix(Matrix1): sage: R. = QQ[] sage: S. = R.quo((b^3)) - sage: A = matrix(S, [[x*y^2,2*x],[2,x^10*y]]) + sage: A = matrix(S, [[x*y^2, 2*x], [2, x^10*y]]) sage: A [ x*y^2 2*x] [ 2 x^10*y] @@ -2987,7 +3013,7 @@ cdef class Matrix(Matrix1): TESTS:: sage: P. = PolynomialRing(Rationals()) - sage: u = MatrixSpace(P,3)([[0,0,a],[1,0,b],[0,1,c]]) + sage: u = MatrixSpace(P, 3)([[0,0,a], [1,0,b], [0,1,c]]) sage: Q. = PolynomialRing(P) sage: u.charpoly('x') x^3 - c*x^2 - b*x - a @@ -2997,15 +3023,15 @@ cdef class Matrix(Matrix1): and crash if an empty dictionary was cached. We don't cache dictionaries anymore, but this test should still pass:: - sage: z = Zp(p=5) - sage: A = matrix(z, [ [3 + O(5^1), 4 + O(5^1), 4 + O(5^1)], + sage: z = Zp(p=5) # optional - sage.rings.padics + sage: A = matrix(z, [ [3 + O(5^1), 4 + O(5^1), 4 + O(5^1)], # optional - sage.rings.padics ....: [2*5^2 + O(5^3), 2 + O(5^1), 1 + O(5^1)], ....: [5 + O(5^2), 1 + O(5^1), 1 + O(5^1)] ]) - sage: A.charpoly(algorithm='hessenberg') + sage: A.charpoly(algorithm='hessenberg') # optional - sage.rings.padics Traceback (most recent call last): ... ValueError: negative valuation - sage: A.det() + sage: A.det() # optional - sage.rings.padics 3 + O(5) The cached polynomial should be independent of the ``var`` @@ -3114,8 +3140,8 @@ cdef class Matrix(Matrix1): Test that :trac:`27937` is fixed:: - sage: R = FreeAbelianMonoid('u,v').algebra(QQ) - sage: matrix(4, 4, lambda i, j: R.an_element())._charpoly_df() + sage: R = FreeAbelianMonoid('u,v').algebra(QQ) # optional - sage.groups + sage: matrix(4, 4, lambda i, j: R.an_element())._charpoly_df() # optional - sage.groups B[1]*x^4 - 4*B[u]*x^3 .. NOTE:: @@ -3224,12 +3250,12 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = MatrixSpace(QQ,3,3) - sage: A = M([1,9,-7,4/5,4,3,6,4,3]) - sage: A.fcp() + sage: M = MatrixSpace(QQ, 3, 3) + sage: A = M([1,9,-7, 4/5,4,3, 6,4,3]) + sage: A.fcp() # optional - sage.libs.pari x^3 - 8*x^2 + 209/5*x - 286 sage: A = M([3, 0, -2, 0, -2, 0, 0, 0, 0]) - sage: A.fcp('T') + sage: A.fcp('T') # optional - sage.libs.pari (T - 3) * T * (T + 2) """ return self.charpoly(var).factor() @@ -3244,7 +3270,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = MatrixSpace(QQ,2)([1/2, 1/3, 1/5, 1/7]) + sage: A = MatrixSpace(QQ, 2)([1/2, 1/3, 1/5, 1/7]) sage: A.denominator() 210 @@ -3274,14 +3300,14 @@ cdef class Matrix(Matrix1): Here's an example involving a cyclotomic field:: - sage: K. = CyclotomicField(3) - sage: M = MatrixSpace(K,3,sparse=True) - sage: A = M([(1+z)/3,(2+z)/3,z/3,1,1+z,-2,1,5,-1+z]) - sage: print(A) + sage: K. = CyclotomicField(3) # optional - sage.rings.number_field + sage: M = MatrixSpace(K, 3, sparse=True) # optional - sage.rings.number_field + sage: A = M([(1+z)/3, (2+z)/3, z/3, 1, 1+z, -2, 1, 5, -1+z]) # optional - sage.rings.number_field + sage: print(A) # optional - sage.rings.number_field [1/3*z + 1/3 1/3*z + 2/3 1/3*z] [ 1 z + 1 -2] [ 1 5 z - 1] - sage: print(A.denominator()) + sage: print(A.denominator()) # optional - sage.rings.number_field 3 """ if self.nrows() == 0 or self.ncols() == 0: @@ -3311,7 +3337,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix([[2,5],[3,7]]); A + sage: A = matrix([[2,5], [3,7]]); A [2 5] [3 7] sage: A.diagonal() @@ -3358,13 +3384,13 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: a = matrix(3,3,range(9)); a + sage: a = matrix(3, 3, range(9)); a [0 1 2] [3 4 5] [6 7 8] sage: a.trace() 12 - sage: a = matrix({(1,1):10, (2,1):-3, (2,2):4/3}); a + sage: a = matrix({(1,1): 10, (2,1): -3, (2,2): 4/3}); a [ 0 0 0] [ 0 10 0] [ 0 -3 4/3] @@ -3413,7 +3439,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(ZZ,4,[2, 1, 1, -2, 2, 2, -1, -1, -1,1,2,3,4,5,6,7]) + sage: A = matrix(ZZ, 4, [2, 1, 1, -2, 2, 2, -1, -1, -1,1,2,3,4,5,6,7]) sage: h = A.hessenberg_form(); h [ 2 -7/2 -19/5 -2] [ 2 1/2 -17/5 -1] @@ -3457,7 +3483,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQ,3, [2, 1, 1, -2, 2, 2, -1, -1, -1]) + sage: A = matrix(QQ, 3, [2, 1, 1, -2, 2, 2, -1, -1, -1]) sage: A.hessenbergize(); A [ 2 3/2 1] [ -2 3 2] @@ -3465,7 +3491,7 @@ cdef class Matrix(Matrix1): :: - sage: A = matrix(QQ,4, [2, 1, 1, -2, 2, 2, -1, -1, -1,1,2,3,4,5,6,7]) + sage: A = matrix(QQ, 4, [2, 1, 1, -2, 2, 2, -1, -1, -1,1,2,3,4,5,6,7]) sage: A.hessenbergize(); A [ 2 -7/2 -19/5 -2] [ 2 1/2 -17/5 -1] @@ -3553,15 +3579,15 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: matrix(QQ,3,3,range(9))._charpoly_hessenberg('Z') + sage: matrix(QQ, 3,3, range(9))._charpoly_hessenberg('Z') Z^3 - 12*Z^2 - 18*Z - sage: matrix(ZZ,3,3,range(9))._charpoly_hessenberg('Z') + sage: matrix(ZZ, 3,3, range(9))._charpoly_hessenberg('Z') Z^3 - 12*Z^2 - 18*Z - sage: matrix(GF(7),3,3,range(9))._charpoly_hessenberg('Z') + sage: matrix(GF(7), 3, 3, range(9))._charpoly_hessenberg('Z') # optional - sage.rings.finite_rings Z^3 + 2*Z^2 + 3*Z - sage: matrix(QQ['x'],3,3,range(9))._charpoly_hessenberg('Z') + sage: matrix(QQ['x'], 3,3, range(9))._charpoly_hessenberg('Z') Z^3 - 12*Z^2 - 18*Z - sage: matrix(ZZ['ZZ'],3,3,range(9))._charpoly_hessenberg('Z') + sage: matrix(ZZ['ZZ'], 3,3, range(9))._charpoly_hessenberg('Z') Z^3 - 12*Z^2 - 18*Z """ if self._nrows != self._ncols: @@ -3627,7 +3653,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = Matrix(QQ,[[1,0,0,1],[0,1,1,0],[1,1,1,0]]) + sage: M = Matrix(QQ, [[1,0,0,1], [0,1,1,0], [1,1,1,0]]) sage: M.nullity() 0 sage: M.left_nullity() @@ -3684,7 +3710,7 @@ cdef class Matrix(Matrix1): OUTPUT: - Returns a pair. First item is the string 'pivot-pari-numberfield' + Returns a pair. First item is the string ``'pivot-pari-numberfield'`` that identifies the nature of the basis vectors. Second item is a matrix whose rows are a basis for the right kernel, @@ -3692,32 +3718,34 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: Q = QuadraticField(-7) - sage: a = Q.gen(0) - sage: A = matrix(Q, [[ 2, 5-a, 15-a], - ....: [2+a, a, -7 + 5*a]]) - sage: result = A._right_kernel_matrix_over_number_field() - sage: result[0] + sage: Q = QuadraticField(-7) # optional - sage.rings.number_field + sage: a = Q.gen(0) # optional - sage.rings.number_field + sage: A = matrix(Q, [[ 2, 5 - a, 15 - a], # optional - sage.rings.number_field + ....: [2 + a, a, -7 + 5*a]]) + sage: result = A._right_kernel_matrix_over_number_field() # optional - sage.rings.number_field sage.libs.pari + sage: result[0] # optional - sage.rings.number_field sage.libs.pari 'pivot-pari-numberfield' - sage: P = result[1]; P + sage: P = result[1]; P # optional - sage.rings.number_field sage.libs.pari [-a -3 1] - sage: A*P.transpose() == zero_matrix(Q, 2, 1) + sage: A * P.transpose() == zero_matrix(Q, 2, 1) # optional - sage.rings.number_field sage.libs.pari True TESTS: We test some trivial cases. :: - sage: Q = QuadraticField(-7) - sage: A = matrix(Q, 0, 2) - sage: A._right_kernel_matrix_over_number_field()[1] + sage: Q = QuadraticField(-7) # optional - sage.rings.number_field + sage: A = matrix(Q, 0, 2) # optional - sage.rings.number_field + sage: A._right_kernel_matrix_over_number_field()[1] # optional - sage.rings.number_field sage.libs.pari [1 0] [0 1] - sage: A = matrix(Q, 2, 0) - sage: A._right_kernel_matrix_over_number_field()[1].parent() - Full MatrixSpace of 0 by 0 dense matrices over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I - sage: A = zero_matrix(Q, 4, 3) - sage: A._right_kernel_matrix_over_number_field()[1] + sage: A = matrix(Q, 2, 0) # optional - sage.rings.number_field sage.libs.pari + sage: A._right_kernel_matrix_over_number_field()[1].parent() # optional - sage.rings.number_field sage.libs.pari + Full MatrixSpace of 0 by 0 dense matrices + over Number Field in a with defining polynomial x^2 + 7 + with a = 2.645751311064591?*I + sage: A = zero_matrix(Q, 4, 3) # optional - sage.rings.number_field sage.libs.pari + sage: A._right_kernel_matrix_over_number_field()[1] # optional - sage.rings.number_field sage.libs.pari [1 0 0] [0 1 0] [0 0 1] @@ -3746,34 +3774,35 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: C = CyclotomicField(14) - sage: a = C.gen(0) - sage: A = matrix(C, 3, 4, [[ 1, a, 1+a, a^3+a^5], + sage: C = CyclotomicField(14) # optional - sage.rings.number_field + sage: a = C.gen(0) # optional - sage.rings.number_field + sage: A = matrix(C, 3, 4, [[ 1, a, 1+a, a^3+a^5], # optional - sage.rings.number_field ....: [ a, a^4, a+a^4, a^4+a^8], ....: [a^2, a^6, a^2+a^6, a^5+a^10]]) - sage: result = A._right_kernel_matrix_over_field() - sage: result[0] + sage: result = A._right_kernel_matrix_over_field() # optional - sage.rings.number_field + sage: result[0] # optional - sage.rings.number_field 'pivot-generic' - sage: P = result[1]; P + sage: P = result[1]; P # optional - sage.rings.number_field [ -1 -1 1 0] [-zeta14^3 -zeta14^4 0 1] - sage: A*P.transpose() == zero_matrix(C, 3, 2) + sage: A * P.transpose() == zero_matrix(C, 3, 2) # optional - sage.rings.number_field True TESTS: We test some trivial cases. :: - sage: C = CyclotomicField(14) - sage: A = matrix(C, 0, 2) - sage: A._right_kernel_matrix_over_field()[1] + sage: C = CyclotomicField(14) # optional - sage.rings.number_field + sage: A = matrix(C, 0, 2) # optional - sage.rings.number_field + sage: A._right_kernel_matrix_over_field()[1] # optional - sage.rings.number_field [1 0] [0 1] - sage: A = matrix(C, 2, 0) - sage: A._right_kernel_matrix_over_field()[1].parent() - Full MatrixSpace of 0 by 0 dense matrices over Cyclotomic Field of order 14 and degree 6 - sage: A = zero_matrix(C, 4, 3) - sage: A._right_kernel_matrix_over_field()[1] + sage: A = matrix(C, 2, 0) # optional - sage.rings.number_field + sage: A._right_kernel_matrix_over_field()[1].parent() # optional - sage.rings.number_field + Full MatrixSpace of 0 by 0 dense matrices + over Cyclotomic Field of order 14 and degree 6 + sage: A = zero_matrix(C, 4, 3) # optional - sage.rings.number_field + sage: A._right_kernel_matrix_over_field()[1] # optional - sage.rings.number_field [1 0 0] [0 1 0] [0 0 1] @@ -3844,7 +3873,7 @@ cdef class Matrix(Matrix1): 'computed-smith-form' sage: P = result[1]; P [-1 -y 1] - sage: A*P.transpose() == zero_matrix(R, 2, 1) + sage: A * P.transpose() == zero_matrix(R, 2, 1) True TESTS: @@ -3858,7 +3887,8 @@ cdef class Matrix(Matrix1): [0 1] sage: A = matrix(R, 2, 0) sage: A._right_kernel_matrix_over_domain()[1].parent() - Full MatrixSpace of 0 by 0 dense matrices over Univariate Polynomial Ring in y over Rational Field + Full MatrixSpace of 0 by 0 dense matrices + over Univariate Polynomial Ring in y over Rational Field sage: A = zero_matrix(R, 4, 3) sage: A._right_kernel_matrix_over_domain()[1] [1 0 0] @@ -3892,15 +3922,15 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(Zmod(24480), [[1,2,3,4,5],[7,7,7,7,7]]) - sage: result = A._right_kernel_matrix_over_integer_mod_ring() - sage: result[0] + sage: A = matrix(Zmod(24480), [[1,2,3,4,5], [7,7,7,7,7]]) + sage: result = A._right_kernel_matrix_over_integer_mod_ring() # optional - sage.libs.pari + sage: result[0] # optional - sage.libs.pari 'computed-pari-matkermod' - sage: P = result[1]; P + sage: P = result[1]; P # optional - sage.libs.pari [ 1 24478 1 0 0] [ 2 24477 0 1 0] [ 3 24476 0 0 1] - sage: A*P.transpose() == 0 + sage: A * P.transpose() == 0 # optional - sage.libs.pari True """ R = self.base_ring() @@ -3989,19 +4019,19 @@ cdef class Matrix(Matrix1): sage: C = A.right_kernel_matrix(algorithm='default', basis='computed'); C [-1 2 -2 -1 0] [ 1 2 0 0 -1] - sage: A*C.transpose() == zero_matrix(QQ, 4, 2) + sage: A * C.transpose() == zero_matrix(QQ, 4, 2) True sage: P = A.right_kernel_matrix(algorithm='padic', basis='pivot'); P [ 1 -2 2 1 0] [-1 -2 0 0 1] - sage: A*P.transpose() == zero_matrix(QQ, 4, 2) + sage: A * P.transpose() == zero_matrix(QQ, 4, 2) True sage: C == -P True sage: E = A.right_kernel_matrix(algorithm='default', basis='echelon'); E [ 1 0 1 1/2 -1/2] [ 0 1 -1/2 -1/4 -1/4] - sage: A*E.transpose() == zero_matrix(QQ, 4, 2) + sage: A * E.transpose() == zero_matrix(QQ, 4, 2) True Since the rationals are a field, we can call the general code @@ -4014,7 +4044,7 @@ cdef class Matrix(Matrix1): sage: G = A.right_kernel_matrix(algorithm='generic', basis='echelon'); G [ 1 0 1 1/2 -1/2] [ 0 1 -1/2 -1/4 -1/4] - sage: A*G.transpose() == zero_matrix(QQ, 4, 2) + sage: A * G.transpose() == zero_matrix(QQ, 4, 2) True We verify that the rational matrix code is called for both @@ -4053,55 +4083,56 @@ cdef class Matrix(Matrix1): basis, so the `basis` keywords 'computed' and 'pivot' will return the same results. :: - sage: Q = QuadraticField(-7) - sage: a = Q.gen(0) - sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a], + sage: Q = QuadraticField(-7) # optional - sage.rings.number_field + sage: a = Q.gen(0) # optional - sage.rings.number_field + sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a], # optional - sage.rings.number_field ....: [2+a, a, -7 + 5*a, -3+3*a]]) - sage: C = A.right_kernel_matrix(algorithm='default', basis='computed'); C + sage: C = A.right_kernel_matrix(algorithm='default', basis='computed'); C # optional - sage.rings.number_field [ -a -3 1 0] [ -2 -a - 1 0 1] - sage: A*C.transpose() == zero_matrix(Q, 2, 2) + sage: A*C.transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field True - sage: P = A.right_kernel_matrix(algorithm='pari', basis='pivot'); P + sage: P = A.right_kernel_matrix(algorithm='pari', basis='pivot'); P # optional - sage.rings.number_field sage.libs.pari [ -a -3 1 0] [ -2 -a - 1 0 1] - sage: A*P.transpose() == zero_matrix(Q, 2, 2) + sage: A*P.transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field sage.libs.pari True - sage: E = A.right_kernel_matrix(algorithm='default', basis='echelon'); E + sage: E = A.right_kernel_matrix(algorithm='default', basis='echelon'); E # optional - sage.rings.number_field [ 1 0 7/88*a + 3/88 -3/176*a - 39/176] [ 0 1 -1/88*a - 13/88 13/176*a - 7/176] - sage: A*E.transpose() == zero_matrix(Q, 2, 2) + sage: A*E.transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field True We can bypass using PARI for number fields and use Sage's general code for matrices over any field. The basis vectors as computed are in pivot format. :: - sage: Q = QuadraticField(-7) - sage: a = Q.gen(0) - sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a],[2+a, a, -7 + 5*a, -3+3*a]]) - sage: G = A.right_kernel_matrix(algorithm='generic', basis='computed'); G + sage: Q = QuadraticField(-7) # optional - sage.rings.number_field + sage: a = Q.gen(0) # optional - sage.rings.number_field + sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a], [2+a, a, -7 + 5*a, -3+3*a]]) # optional - sage.rings.number_field + sage: G = A.right_kernel_matrix(algorithm='generic', basis='computed'); G # optional - sage.rings.number_field [ -a -3 1 0] [ -2 -a - 1 0 1] - sage: A*G.transpose() == zero_matrix(Q, 2, 2) + sage: A*G.transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field True We check that number fields are handled by the right routine as part of typical right kernel computation. :: - sage: Q = QuadraticField(-7) - sage: a = Q.gen(0) - sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a],[2+a, a, -7 + 5*a, -3+3*a]]) + sage: Q = QuadraticField(-7) # optional - sage.rings.number_field + sage: a = Q.gen(0) # optional - sage.rings.number_field + sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a], [2+a, a, -7 + 5*a, -3+3*a]]) # optional - sage.rings.number_field sage: set_verbose(1) - sage: A.right_kernel(algorithm='default') + sage: A.right_kernel(algorithm='default') # optional - sage.rings.number_field verbose ... verbose 1 () computing right kernel matrix over a number field for 2x4 matrix verbose 1 () done computing right kernel matrix over a number field for 2x4 matrix ... - Vector space of degree 4 and dimension 2 over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I - Basis matrix: - [ 1 0 7/88*a + 3/88 -3/176*a - 39/176] - [ 0 1 -1/88*a - 13/88 13/176*a - 7/176] + Vector space of degree 4 and dimension 2 over Number Field in a + with defining polynomial x^2 + 7 with a = 2.645751311064591?*I + Basis matrix: + [ 1 0 7/88*a + 3/88 -3/176*a - 39/176] + [ 0 1 -1/88*a - 13/88 13/176*a - 7/176] sage: set_verbose(0) Over the Finite Field of Order 2: @@ -4111,15 +4142,15 @@ cdef class Matrix(Matrix1): :meth:`~sage.matrix.matrix_mod2_dense.Matrix_mod2_dense._right_kernel_matrix` method. There are no options for the algorithm used. :: - sage: A = matrix(GF(2),[[0, 1, 1, 0, 0, 0], + sage: A = matrix(GF(2),[[0, 1, 1, 0, 0, 0], # optional - sage.rings.finite_rings ....: [1, 0, 0, 0, 1, 1,], ....: [1, 0, 0, 0, 1, 1]]) - sage: E = A.right_kernel_matrix(algorithm='default', format='echelon'); E + sage: E = A.right_kernel_matrix(algorithm='default', format='echelon'); E # optional - sage.rings.finite_rings [1 0 0 0 0 1] [0 1 1 0 0 0] [0 0 0 1 0 0] [0 0 0 0 1 1] - sage: A*E.transpose() == zero_matrix(GF(2), 3, 4) + sage: A*E.transpose() == zero_matrix(GF(2), 3, 4) # optional - sage.rings.finite_rings True Since GF(2) is a field we can route this computation to the generic @@ -4127,24 +4158,24 @@ cdef class Matrix(Matrix1): keywords, 'pluq', 'default' and unspecified, all have the same effect as there is no optional behavior. :: - sage: A = matrix(GF(2),[[0, 1, 1, 0, 0, 0], - ....: [1, 0, 0, 0, 1, 1,], - ....: [1, 0, 0, 0, 1, 1]]) - sage: P = A.right_kernel_matrix(algorithm='generic', basis='pivot'); P + sage: A = matrix(GF(2), [[0, 1, 1, 0, 0, 0], # optional - sage.rings.finite_rings + ....: [1, 0, 0, 0, 1, 1,], + ....: [1, 0, 0, 0, 1, 1]]) + sage: P = A.right_kernel_matrix(algorithm='generic', basis='pivot'); P # optional - sage.rings.finite_rings [0 1 1 0 0 0] [0 0 0 1 0 0] [1 0 0 0 1 0] [1 0 0 0 0 1] - sage: A*P.transpose() == zero_matrix(GF(2), 3, 4) + sage: A*P.transpose() == zero_matrix(GF(2), 3, 4) # optional - sage.rings.finite_rings True - sage: DP = A.right_kernel_matrix(algorithm='default', basis='pivot'); DP + sage: DP = A.right_kernel_matrix(algorithm='default', basis='pivot'); DP # optional - sage.rings.finite_rings [0 1 1 0 0 0] [0 0 0 1 0 0] [1 0 0 0 1 0] [1 0 0 0 0 1] - sage: A*DP.transpose() == zero_matrix(GF(2), 3, 4) + sage: A*DP.transpose() == zero_matrix(GF(2), 3, 4) # optional - sage.rings.finite_rings True - sage: A.right_kernel_matrix(algorithm='pluq', basis='echelon') + sage: A.right_kernel_matrix(algorithm='pluq', basis='echelon') # optional - sage.rings.finite_rings [1 0 0 0 0 1] [0 1 1 0 0 0] [0 0 0 1 0 0] @@ -4152,11 +4183,11 @@ cdef class Matrix(Matrix1): We test that the mod 2 code is called for matrices over GF(2). :: - sage: A = matrix(GF(2),[[0, 1, 1, 0, 0, 0], - ....: [1, 0, 0, 0, 1, 1,], - ....: [1, 0, 0, 0, 1, 1]]) + sage: A = matrix(GF(2), [[0, 1, 1, 0, 0, 0], # optional - sage.rings.finite_rings + ....: [1, 0, 0, 0, 1, 1,], + ....: [1, 0, 0, 0, 1, 1]]) sage: set_verbose(1) - sage: A.right_kernel(algorithm='default') + sage: A.right_kernel(algorithm='default') # optional - sage.rings.finite_rings verbose ... verbose 1 () computing right kernel matrix over integers mod 2 for 3x6 matrix verbose 1 () done computing right kernel matrix over integers mod 2 for 3x6 matrix @@ -4175,19 +4206,19 @@ cdef class Matrix(Matrix1): will compute a set of basis vectors in the pivot format. These could be returned as a basis in echelon form. :: - sage: F. = FiniteField(5^2) - sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], + sage: F. = FiniteField(5^2) # optional - sage.rings.finite_rings + sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], # optional - sage.rings.finite_rings ....: [ a, a^4, a+a^4, a^4+a^8], ....: [a^2, a^6, a^2+a^6, a^5+a^10]]) - sage: P = A.right_kernel_matrix(algorithm='default', basis='pivot'); P + sage: P = A.right_kernel_matrix(algorithm='default', basis='pivot'); P # optional - sage.rings.finite_rings [ 4 4 1 0] [ a + 2 3*a + 3 0 1] - sage: A*P.transpose() == zero_matrix(F, 3, 2) + sage: A*P.transpose() == zero_matrix(F, 3, 2) # optional - sage.rings.finite_rings True - sage: E = A.right_kernel_matrix(algorithm='default', basis='echelon'); E + sage: E = A.right_kernel_matrix(algorithm='default', basis='echelon'); E # optional - sage.rings.finite_rings [ 1 0 3*a + 4 2*a + 2] [ 0 1 2*a 3*a + 3] - sage: A*E.transpose() == zero_matrix(F, 3, 2) + sage: A*E.transpose() == zero_matrix(F, 3, 2) # optional - sage.rings.finite_rings True This general code can be requested for matrices over any field @@ -4214,12 +4245,12 @@ cdef class Matrix(Matrix1): We test that the generic code is called for matrices over fields, lacking any more specific routine. :: - sage: F. = FiniteField(5^2) - sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], + sage: F. = FiniteField(5^2) # optional - sage.rings.finite_rings + sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], # optional - sage.rings.finite_rings ....: [ a, a^4, a+a^4, a^4+a^8], ....: [a^2, a^6, a^2+a^6, a^5+a^10]]) sage: set_verbose(1) - sage: A.right_kernel(algorithm='default') + sage: A.right_kernel(algorithm='default') # optional - sage.rings.finite_rings verbose ... verbose 1 () computing right kernel matrix over an arbitrary field for 3x4 matrix ... @@ -4333,7 +4364,8 @@ cdef class Matrix(Matrix1): sage: A.right_kernel_matrix() Traceback (most recent call last): ... - ArithmeticError: Ideal Ideal (x^2 - x, x^2 - 8) of Univariate Polynomial Ring in x over Integer Ring not principal + ArithmeticError: Ideal Ideal (x^2 - x, x^2 - 8) of + Univariate Polynomial Ring in x over Integer Ring not principal We test that the domain code is called for domains that lack any extra structure. :: @@ -4347,9 +4379,10 @@ cdef class Matrix(Matrix1): verbose 1 () computing right kernel matrix over a domain for 2x3 matrix verbose 1 () done computing right kernel matrix over a domain for 2x3 matrix ... - Free module of degree 3 and rank 1 over Univariate Polynomial Ring in y over Rational Field - Echelon basis matrix: - [-1 -y 1] + Free module of degree 3 and rank 1 over + Univariate Polynomial Ring in y over Rational Field + Echelon basis matrix: + [-1 -y 1] sage: set_verbose(0) Over inexact rings: @@ -4369,9 +4402,9 @@ cdef class Matrix(Matrix1): ....: [-0.8090169944, 0.0, 0.5], ....: [ 0.8090169944, 0.0, -0.5], ....: [-0.8090169944, 0.0, -0.5]]).transpose() - sage: (A*A.right_kernel_matrix().transpose()).norm() > 2 + sage: (A * A.right_kernel_matrix().transpose()).norm() > 2 True - sage: (A*A.right_kernel_matrix(basis='computed').transpose()).norm() < 1e-15 + sage: (A * A.right_kernel_matrix(basis='computed').transpose()).norm() < 1e-15 True Trivial Cases: @@ -4383,8 +4416,8 @@ cdef class Matrix(Matrix1): sage: A.right_kernel_matrix() [1 0] [0 1] - sage: A = matrix(FiniteField(7), 2, 0) - sage: A.right_kernel_matrix().parent() + sage: A = matrix(FiniteField(7), 2, 0) # optional - sage.rings.finite_rings + sage: A.right_kernel_matrix().parent() # optional - sage.rings.finite_rings Full MatrixSpace of 0 by 0 dense matrices over Finite Field of size 7 TESTS: @@ -4406,7 +4439,7 @@ cdef class Matrix(Matrix1): Traceback (most recent call last): ... ValueError: matrix kernel algorithm 'junk' not recognized - sage: matrix(GF(2), 2, 2).right_kernel_matrix(algorithm='padic') + sage: matrix(GF(2), 2, 2).right_kernel_matrix(algorithm='padic') # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: 'padic' matrix kernel algorithm only available over the rationals and the integers, not over Finite Field of size 2 @@ -4658,7 +4691,7 @@ cdef class Matrix(Matrix1): [ 0 1 0 0 5 5 5] [ 0 0 1 0 -1 -2 -3] [ 0 0 0 1 0 1 1] - sage: A*K.basis_matrix().transpose() == zero_matrix(QQ, 4, 4) + sage: A * K.basis_matrix().transpose() == zero_matrix(QQ, 4, 4) True The default is basis vectors that form a matrix in echelon form. @@ -4685,7 +4718,7 @@ cdef class Matrix(Matrix1): [-1 0 0 -1 1 0 0] [-1 0 1 2 0 1 0] [ 1 0 -1 -1 0 0 1] - sage: A*K.basis_matrix().transpose() == zero_matrix(QQ, 4, 4) + sage: A * K.basis_matrix().transpose() == zero_matrix(QQ, 4, 4) True Matrices may have any field as a base ring. Number fields are @@ -4698,16 +4731,17 @@ cdef class Matrix(Matrix1): Over an arbitrary field, with two basis formats. Same vector space, different bases. :: - sage: F. = FiniteField(5^2) - sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], + sage: F. = FiniteField(5^2) # optional - sage.rings.finite_rings + sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], # optional - sage.rings.finite_rings ....: [ a, a^4, a+a^4, a^4+a^8], ....: [a^2, a^6, a^2+a^6, a^5+a^10]]) - sage: K = A.right_kernel(); K - Vector space of degree 4 and dimension 2 over Finite Field in a of size 5^2 + sage: K = A.right_kernel(); K # optional - sage.rings.finite_rings + Vector space of degree 4 and dimension 2 + over Finite Field in a of size 5^2 Basis matrix: [ 1 0 3*a + 4 2*a + 2] [ 0 1 2*a 3*a + 3] - sage: A*K.basis_matrix().transpose() == zero_matrix(F, 3, 2) + sage: A * K.basis_matrix().transpose() == zero_matrix(F, 3, 2) # optional - sage.rings.finite_rings True In the following test, we have to force usage of @@ -4717,9 +4751,10 @@ cdef class Matrix(Matrix1): installed. :: sage: from sage.matrix.matrix_generic_dense import Matrix_generic_dense - sage: B = Matrix_generic_dense(A.parent(), A.list(), False, False) - sage: P = B.right_kernel(basis = 'pivot'); P - Vector space of degree 4 and dimension 2 over Finite Field in a of size 5^2 + sage: B = Matrix_generic_dense(A.parent(), A.list(), False, False) # optional - sage.rings.finite_rings + sage: P = B.right_kernel(basis='pivot'); P # optional - sage.rings.finite_rings + Vector space of degree 4 and dimension 2 + over Finite Field in a of size 5^2 User basis matrix: [ 4 4 1 0] [ a + 2 3*a + 3 0 1] @@ -4727,34 +4762,39 @@ cdef class Matrix(Matrix1): If the optional meataxe package is installed, we again have to make sure to work with a copy of B that has the same type as ``P.basis_matrix()``:: - sage: B.parent()(B.list())*P.basis_matrix().transpose() == zero_matrix(F, 3, 2) + sage: (B.parent()(B.list()) * P.basis_matrix().transpose() # optional - sage.rings.finite_rings + ....: == zero_matrix(F, 3, 2)) True - sage: K == P + sage: K == P # optional - sage.rings.finite_rings True Over number fields, PARI is used by default, but general-purpose code can be requested. Same vector space, same bases, different code.:: - sage: Q = QuadraticField(-7) - sage: a = Q.gen(0) - sage: A = matrix(Q, [[ 2, 5-a, 15-a, 16+4*a], - ....: [2+a, a, -7 + 5*a, -3+3*a]]) - sage: K = A.right_kernel(algorithm='default'); K - Vector space of degree 4 and dimension 2 over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I + sage: Q = QuadraticField(-7) # optional - sage.rings.number_field + sage: a = Q.gen(0) # optional - sage.rings.number_field + sage: A = matrix(Q, [[ 2, 5 - a, 15 - a, 16 + 4*a], # optional - sage.rings.number_field + ....: [2 + a, a, -7 + 5*a, -3 + 3*a]]) + sage: K = A.right_kernel(algorithm='default'); K # optional - sage.rings.number_field + Vector space of degree 4 and dimension 2 + over Number Field in a with defining polynomial x^2 + 7 + with a = 2.645751311064591?*I Basis matrix: [ 1 0 7/88*a + 3/88 -3/176*a - 39/176] [ 0 1 -1/88*a - 13/88 13/176*a - 7/176] - sage: A*K.basis_matrix().transpose() == zero_matrix(Q, 2, 2) + sage: A * K.basis_matrix().transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field True - sage: B = copy(A) - sage: G = A.right_kernel(algorithm='generic'); G - Vector space of degree 4 and dimension 2 over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I + sage: B = copy(A) # optional - sage.rings.number_field + sage: G = A.right_kernel(algorithm='generic'); G # optional - sage.rings.number_field + Vector space of degree 4 and dimension 2 + over Number Field in a with defining polynomial x^2 + 7 + with a = 2.645751311064591?*I Basis matrix: [ 1 0 7/88*a + 3/88 -3/176*a - 39/176] [ 0 1 -1/88*a - 13/88 13/176*a - 7/176] - sage: B*G.basis_matrix().transpose() == zero_matrix(Q, 2, 2) + sage: B * G.basis_matrix().transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field True - sage: K == G + sage: K == G # optional - sage.rings.number_field True For matrices over the integers, several options are possible. @@ -4805,10 +4845,11 @@ cdef class Matrix(Matrix1): sage: A = matrix(R, [[ 1, y, 1+y^2], ....: [y^3, y^2, 2*y^3]]) sage: K = A.right_kernel(algorithm='default', basis='echelon'); K - Free module of degree 3 and rank 1 over Univariate Polynomial Ring in y over Rational Field - Echelon basis matrix: - [-1 -y 1] - sage: A*K.basis_matrix().transpose() == zero_matrix(ZZ, 2, 1) + Free module of degree 3 and rank 1 + over Univariate Polynomial Ring in y over Rational Field + Echelon basis matrix: + [-1 -y 1] + sage: A * K.basis_matrix().transpose() == zero_matrix(ZZ, 2, 1) True It is possible to compute a kernel for a matrix over an integral @@ -4820,7 +4861,8 @@ cdef class Matrix(Matrix1): sage: A.right_kernel() Traceback (most recent call last): ... - ArithmeticError: Ideal Ideal (x^2 - x, x^2 - 8) of Univariate Polynomial Ring in x over Integer Ring not principal + ArithmeticError: Ideal Ideal (x^2 - x, x^2 - 8) of Univariate + Polynomial Ring in x over Integer Ring not principal Matrices over non-commutative rings are not a good idea either. These are the "usual" quaternions. :: @@ -4830,7 +4872,8 @@ cdef class Matrix(Matrix1): sage: A.right_kernel() Traceback (most recent call last): ... - NotImplementedError: Cannot compute a matrix kernel over Quaternion Algebra (-1, -1) with base ring Rational Field + NotImplementedError: Cannot compute a matrix kernel over + Quaternion Algebra (-1, -1) with base ring Rational Field Sparse matrices, over the rationals and the integers, use the same routines as the dense versions. :: @@ -5018,11 +5061,11 @@ cdef class Matrix(Matrix1): Over a finite field, with a basis matrix in "pivot" format. :: - sage: A = matrix(FiniteField(7), [[5, 0, 5, 2, 4], + sage: A = matrix(FiniteField(7), [[5, 0, 5, 2, 4], # optional - sage.rings.finite_rings ....: [1, 3, 2, 3, 6], ....: [1, 1, 6, 5, 3], ....: [2, 5, 6, 0, 0]]) - sage: A.kernel(basis='pivot') + sage: A.kernel(basis='pivot') # optional - sage.rings.finite_rings Vector space of degree 4 and dimension 2 over Finite Field of size 7 User basis matrix: [5 2 1 0] @@ -5131,7 +5174,7 @@ cdef class Matrix(Matrix1): [ 0 2 0 -1] [ 0 1 -2 0] [ 0 2 0 -2] - sage: t.fcp() + sage: t.fcp() # optional - sage.libs.pari (x - 39) * (x + 2) * (x^2 - 2) sage: s = (t-39)*(t^2-2) sage: V = s.kernel(); V @@ -5227,13 +5270,14 @@ cdef class Matrix(Matrix1): An example over a bigger ring:: - sage: L. = NumberField(x^2 - x + 2) - sage: OL = L.ring_of_integers() - sage: A = matrix(L, 2, [1, w/2]) - sage: A.integer_kernel(OL) - Free module of degree 2 and rank 1 over Maximal Order in Number Field in w with defining polynomial x^2 - x + 2 - Echelon basis matrix: - [ -1 -w + 1] + sage: L. = NumberField(x^2 - x + 2) # optional - sage.rings.number_field + sage: OL = L.ring_of_integers() # optional - sage.rings.number_field + sage: A = matrix(L, 2, [1, w/2]) # optional - sage.rings.number_field + sage: A.integer_kernel(OL) # optional - sage.rings.number_field + Free module of degree 2 and rank 1 over + Maximal Order in Number Field in w with defining polynomial x^2 - x + 2 + Echelon basis matrix: + [ -1 -w + 1] """ try: @@ -5253,9 +5297,9 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: MS1 = MatrixSpace(ZZ,4) - sage: MS2 = MatrixSpace(QQ,6) - sage: A = MS1.matrix([3,4,5,6,7,3,8,10,14,5,6,7,2,2,10,9]) + sage: MS1 = MatrixSpace(ZZ, 4) + sage: MS2 = MatrixSpace(QQ, 6) + sage: A = MS1.matrix([3,4,5,6, 7,3,8,10, 14,5,6,7, 2,2,10,9]) sage: B = MS2.random_element() :: @@ -5358,23 +5402,24 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = MatrixSpace(QQ,3,3) - sage: A = M([1,9,-7,4/5,4,3,6,4,3]) + sage: M = MatrixSpace(QQ, 3, 3) + sage: A = M([1,9,-7, 4/5,4,3, 6,4,3]) sage: A.column_space() Vector space of degree 3 and dimension 3 over Rational Field Basis matrix: [1 0 0] [0 1 0] [0 0 1] - sage: W = MatrixSpace(CC,2,2) - sage: B = W([1, 2+3*I,4+5*I,9]); B + sage: W = MatrixSpace(CC, 2, 2) + sage: B = W([1, 2 + 3*I, 4 + 5*I, 9]); B [ 1.00000000000000 2.00000000000000 + 3.00000000000000*I] [4.00000000000000 + 5.00000000000000*I 9.00000000000000] sage: B.column_space() - Vector space of degree 2 and dimension 2 over Complex Field with 53 bits of precision - Basis matrix: - [ 1.00000000000000 0.000000000000000] - [0.000000000000000 1.00000000000000] + Vector space of degree 2 and dimension 2 + over Complex Field with 53 bits of precision + Basis matrix: + [ 1.00000000000000 0.000000000000000] + [0.000000000000000 1.00000000000000] """ return self.column_module() @@ -5434,7 +5479,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(ZZ, 4, [3,4,5,6,7,3,8,10,14,5,6,7,2,2,10,9]) + sage: A = matrix(ZZ, 4, [3,4,5,6, 7,3,8,10, 14,5,6,7, 2,2,10,9]) sage: B = matrix(QQ, 6, 6, range(36)) sage: B*11 [ 0 11 22 33 44 55] @@ -5443,23 +5488,23 @@ cdef class Matrix(Matrix1): [198 209 220 231 242 253] [264 275 286 297 308 319] [330 341 352 363 374 385] - sage: A.decomposition() - [ - (Ambient free module of rank 4 over the principal ideal domain Integer Ring, True) - ] - sage: B.decomposition() - [ - (Vector space of degree 6 and dimension 2 over Rational Field - Basis matrix: - [ 1 0 -1 -2 -3 -4] - [ 0 1 2 3 4 5], True), - (Vector space of degree 6 and dimension 4 over Rational Field - Basis matrix: - [ 1 0 0 0 -5 4] - [ 0 1 0 0 -4 3] - [ 0 0 1 0 -3 2] - [ 0 0 0 1 -2 1], False) - ] + sage: A.decomposition() # optional - sage.libs.pari + [ (Ambient free module of rank 4 + over the principal ideal domain Integer Ring, + True) ] + sage: B.decomposition() # optional - sage.libs.pari + [ (Vector space of degree 6 and dimension 2 over Rational Field + Basis matrix: + [ 1 0 -1 -2 -3 -4] + [ 0 1 2 3 4 5], + True), + (Vector space of degree 6 and dimension 4 over Rational Field + Basis matrix: + [ 1 0 0 0 -5 4] + [ 0 1 0 0 -4 3] + [ 0 0 1 0 -3 2] + [ 0 0 0 1 -2 1], + False) ] """ if algorithm == 'kernel' or self.base_ring() not in _Fields: return self._decomposition_using_kernels(is_diagonalizable = is_diagonalizable, dual=dual) @@ -5636,48 +5681,46 @@ cdef class Matrix(Matrix1): [ 3 0 -2] [ 0 -2 0] [ 0 0 0] - sage: t.fcp('X') # factored charpoly + sage: t.fcp('X') # factored charpoly # optional - sage.libs.pari (X - 3) * X * (X + 2) sage: v = kernel(t*(t+2)); v # an invariant subspace Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [0 1 0] [0 0 1] - sage: D = t.decomposition_of_subspace(v); D - [ - (Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [0 0 1], True), - (Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [0 1 0], True) - ] - sage: t.restrict(D[0][0]) + sage: D = t.decomposition_of_subspace(v); D # optional - sage.libs.pari + [ (Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: [0 0 1], + True), + (Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: [0 1 0], + True) ] + sage: t.restrict(D[0][0]) # optional - sage.libs.pari [0] - sage: t.restrict(D[1][0]) + sage: t.restrict(D[1][0]) # optional - sage.libs.pari [-2] We do a decomposition over ZZ:: - sage: a = matrix(ZZ,6,[0, 0, -2, 0, 2, 0, 2, -4, -2, 0, 2, 0, 0, 0, -2, -2, 0, 0, 2, 0, -2, -4, 2, -2, 0, 2, 0, -2, -2, 0, 0, 2, 0, -2, 0, 0]) - sage: a.decomposition_of_subspace(ZZ^6) - [ - (Free module of degree 6 and rank 2 over Integer Ring - Echelon basis matrix: - [ 1 0 1 -1 1 -1] - [ 0 1 0 -1 2 -1], False), - (Free module of degree 6 and rank 4 over Integer Ring - Echelon basis matrix: - [ 1 0 -1 0 1 0] - [ 0 1 0 0 0 0] - [ 0 0 0 1 0 0] - [ 0 0 0 0 0 1], False) - ] + sage: a = matrix(ZZ, 6, [0, 0, -2, 0, 2, 0, 2, -4, -2, 0, 2, 0, 0, 0, -2, -2, 0, 0, 2, 0, -2, -4, 2, -2, 0, 2, 0, -2, -2, 0, 0, 2, 0, -2, 0, 0]) + sage: a.decomposition_of_subspace(ZZ^6) # optional - sage.libs.pari + [ (Free module of degree 6 and rank 2 over Integer Ring + Echelon basis matrix: + [ 1 0 1 -1 1 -1] + [ 0 1 0 -1 2 -1], + False), + (Free module of degree 6 and rank 4 over Integer Ring + Echelon basis matrix: + [ 1 0 -1 0 1 0] + [ 0 1 0 0 0 0] + [ 0 0 0 1 0 0] + [ 0 0 0 0 0 1], + False) ] TESTS:: sage: t = matrix(QQ, 3, [3, 0, -2, 0, -2, 0, 0, 0, 0]) - sage: t.decomposition_of_subspace(v, check_restrict = False) == t.decomposition_of_subspace(v) + sage: t.decomposition_of_subspace(v, check_restrict = False) == t.decomposition_of_subspace(v) # optional - sage.libs.pari True """ if not sage.modules.free_module.is_FreeModule(M): @@ -5813,7 +5856,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: V = QQ^3 - sage: A = matrix(QQ,3,[1,2,0, 3,4,0, 0,0,0]) + sage: A = matrix(QQ, 3, [1,2,0, 3,4,0, 0,0,0]) sage: W = V.subspace([[1,0,0], [1,2,3]]) sage: A.restrict_domain(W) [1 2 0] @@ -5848,7 +5891,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQ,3,[1..9]) + sage: A = matrix(QQ, 3, [1..9]) sage: V = (QQ^3).span([[1,2,3], [7,8,9]]); V Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: @@ -5951,7 +5994,7 @@ cdef class Matrix(Matrix1): [6 7 8] sage: t.wiedemann(0) x^2 - 12*x - 18 - sage: t.charpoly() + sage: t.charpoly() # optional - sage.libs.pari x^3 - 12*x^2 - 18*x """ i = int(i); t=int(t) @@ -6015,17 +6058,17 @@ cdef class Matrix(Matrix1): of finite fields:: sage: A = matrix(QQ, 2, range(4)) - sage: A._eigenspace_format(None) == 'all' + sage: A._eigenspace_format(None) == 'all' # optional - sage.rings.number_field True - sage: B = matrix(GF(13), 2, range(4)) - sage: B._eigenspace_format(None) + sage: B = matrix(GF(13), 2, range(4)) # optional - sage.rings.finite_rings + sage: B._eigenspace_format(None) # optional - sage.rings.finite_rings 'all' Subrings are promoted to fraction fields and then checked for the existence of algebraic closures. :: sage: A = matrix(ZZ, 2, range(4)) - sage: A._eigenspace_format(None) == 'all' + sage: A._eigenspace_format(None) == 'all' # optional - sage.rings.number_field True """ if format not in [None, 'all', 'galois']: @@ -6105,61 +6148,68 @@ cdef class Matrix(Matrix1): Then we request just one eigenspace per irreducible factor of the characteristic polynomial with the `galois` keyword. :: - sage: A = matrix(QQ,3,3,range(9)); A + sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: es = A.eigenspaces_left(format='all'); es - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (-1.348469228349535?, Vector space of degree 3 and dimension 1 over Algebraic Field - User basis matrix: - [ 1 0.3101020514433644? -0.3797958971132713?]), - (13.34846922834954?, Vector space of degree 3 and dimension 1 over Algebraic Field - User basis matrix: - [ 1 1.289897948556636? 1.579795897113272?]) - ] - - sage: es = A.eigenspaces_left(format='galois'); es - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (a1, Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5]) - ] - sage: es = A.eigenspaces_left(format='galois', algebraic_multiplicity=True); es - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1], 1), - (a1, Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5], 1) - ] - sage: e, v, n = es[0]; v = v.basis()[0] - sage: delta = e*v - v*A - sage: abs(abs(delta)) < 1e-10 + sage: es = A.eigenspaces_left(format='all'); es # optional - sage.rings.number_field + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (-1.348469228349535?, + Vector space of degree 3 and dimension 1 over Algebraic Field + User basis matrix: + [ 1 0.3101020514433644? -0.3797958971132713?]), + (13.34846922834954?, + Vector space of degree 3 and dimension 1 over Algebraic Field + User basis matrix: + [ 1 1.289897948556636? 1.579795897113272?]) ] + + sage: es = A.eigenspaces_left(format='galois'); es # optional - sage.rings.number_field + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (a1, + Vector space of degree 3 and dimension 1 over + Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5]) ] + sage: es = A.eigenspaces_left(format='galois', # optional - sage.rings.number_field + ....: algebraic_multiplicity=True); es + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1], + 1), + (a1, + Vector space of degree 3 and dimension 1 over + Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5], + 1) ] + sage: e, v, n = es[0]; v = v.basis()[0] # optional - sage.rings.number_field + sage: delta = e*v - v*A # optional - sage.rings.number_field + sage: abs(abs(delta)) < 1e-10 # optional - sage.rings.number_field True The same computation, but with implicit base change to a field. :: - sage: A = matrix(ZZ,3,3,range(9)); A + sage: A = matrix(ZZ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: A.eigenspaces_left(format='galois') - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (a1, Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5]) - ] + sage: A.eigenspaces_left(format='galois') # optional - sage.rings.number_field + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (a1, + Vector space of degree 3 and dimension 1 over + Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5]) ] We compute the left eigenspaces of the matrix of the Hecke operator `T_2` on level 43 modular symbols, both with all eigenvalues (the default) @@ -6180,61 +6230,72 @@ cdef class Matrix(Matrix1): sage: factor(f) (x - 3) * (x + 2)^2 * (x^2 - 2)^2 sage: A.eigenspaces_left(algebraic_multiplicity=True) - [ - (3, Vector space of degree 7 and dimension 1 over Rational Field - User basis matrix: - [ 1 0 1/7 0 -1/7 0 -2/7], 1), - (-2, Vector space of degree 7 and dimension 2 over Rational Field - User basis matrix: - [ 0 1 0 1 -1 1 -1] - [ 0 0 1 0 -1 2 -1], 2), - (-1.414213562373095?, Vector space of degree 7 and dimension 2 over Algebraic Field - User basis matrix: - [ 0 1 0 -1 0.4142135623730951? 1 -1] - [ 0 0 1 0 -1 0 2.414213562373095?], 2), - (1.414213562373095?, Vector space of degree 7 and dimension 2 over Algebraic Field - User basis matrix: - [ 0 1 0 -1 -2.414213562373095? 1 -1] - [ 0 0 1 0 -1 0 -0.4142135623730951?], 2) - ] + [ (3, + Vector space of degree 7 and dimension 1 over Rational Field + User basis matrix: + [ 1 0 1/7 0 -1/7 0 -2/7], + 1), + (-2, + Vector space of degree 7 and dimension 2 over Rational Field + User basis matrix: + [ 0 1 0 1 -1 1 -1] + [ 0 0 1 0 -1 2 -1], + 2), + (-1.414213562373095?, + Vector space of degree 7 and dimension 2 over Algebraic Field + User basis matrix: + [ 0 1 0 -1 0.4142135623730951? 1 -1] + [ 0 0 1 0 -1 0 2.414213562373095?], + 2), + (1.414213562373095?, + Vector space of degree 7 and dimension 2 over Algebraic Field + User basis matrix: + [ 0 1 0 -1 -2.414213562373095? 1 -1] + [ 0 0 1 0 -1 0 -0.4142135623730951?], + 2) ] sage: A.eigenspaces_left(format='galois', algebraic_multiplicity=True) - [ - (3, Vector space of degree 7 and dimension 1 over Rational Field - User basis matrix: - [ 1 0 1/7 0 -1/7 0 -2/7], 1), - (-2, Vector space of degree 7 and dimension 2 over Rational Field - User basis matrix: - [ 0 1 0 1 -1 1 -1] - [ 0 0 1 0 -1 2 -1], 2), - (a2, Vector space of degree 7 and dimension 2 over Number Field in a2 with defining polynomial x^2 - 2 - User basis matrix: - [ 0 1 0 -1 -a2 - 1 1 -1] - [ 0 0 1 0 -1 0 -a2 + 1], 2) - ] + [ (3, + Vector space of degree 7 and dimension 1 over Rational Field + User basis matrix: + [ 1 0 1/7 0 -1/7 0 -2/7], + 1), + (-2, + Vector space of degree 7 and dimension 2 over Rational Field + User basis matrix: + [ 0 1 0 1 -1 1 -1] + [ 0 0 1 0 -1 2 -1], + 2), + (a2, + Vector space of degree 7 and dimension 2 + over Number Field in a2 with defining polynomial x^2 - 2 + User basis matrix: + [ 0 1 0 -1 -a2 - 1 1 -1] + [ 0 0 1 0 -1 0 -a2 + 1], + 2) ] Next we compute the left eigenspaces over the finite field of order 11. :: - sage: A = ModularSymbols(43, base_ring=GF(11), sign=1).T(2).matrix(); A + sage: A = ModularSymbols(43, base_ring=GF(11), sign=1).T(2).matrix(); A # optional - sage.rings.finite_rings [ 3 0 9 0] [ 0 9 0 10] [ 0 0 10 1] [ 0 0 1 1] - sage: A.base_ring() + sage: A.base_ring() # optional - sage.rings.finite_rings Finite Field of size 11 - sage: A.charpoly() + sage: A.charpoly() # optional - sage.rings.finite_rings x^4 + 10*x^3 + 3*x^2 + 2*x + 1 - sage: A.eigenspaces_left(format='galois', var = 'beta') - [ - (9, Vector space of degree 4 and dimension 1 over Finite Field of size 11 - User basis matrix: - [0 1 5 6]), - (3, Vector space of degree 4 and dimension 1 over Finite Field of size 11 - User basis matrix: - [1 0 1 6]), - (beta2, Vector space of degree 4 and dimension 1 over Univariate Quotient Polynomial Ring in beta2 over Finite Field of size 11 with modulus x^2 + 9 - User basis matrix: - [ 0 0 1 beta2 + 1]) - ] + sage: A.eigenspaces_left(format='galois', var='beta') # optional - sage.rings.finite_rings + [ (9, + Vector space of degree 4 and dimension 1 over Finite Field of size 11 + User basis matrix: [0 1 5 6]), + (3, + Vector space of degree 4 and dimension 1 over Finite Field of size 11 + User basis matrix: [1 0 1 6]), + (beta2, + Vector space of degree 4 and dimension 1 + over Univariate Quotient Polynomial Ring in beta2 + over Finite Field of size 11 with modulus x^2 + 9 + User basis matrix: [ 0 0 1 beta2 + 1]) ] This method is only applicable to exact matrices. The "eigenmatrix" routines for matrices with double-precision @@ -6248,11 +6309,12 @@ cdef class Matrix(Matrix1): sage: A.change_ring(RR).eigenspaces_left() Traceback (most recent call last): ... - NotImplementedError: eigenspaces cannot be computed reliably for inexact rings such as Real Field with 53 bits of precision, + NotImplementedError: eigenspaces cannot be computed reliably + for inexact rings such as Real Field with 53 bits of precision, consult numerical or symbolic matrix classes for other options sage: em = A.change_ring(RDF).eigenmatrix_left() - sage: eigenvalues = em[0]; eigenvalues.dense_matrix() # abs tol 1e-13 + sage: eigenvalues = em[0]; eigenvalues.dense_matrix() # abs tol 1e-13 [13.348469228349522 0.0 0.0] [ 0.0 -1.348469228349534 0.0] [ 0.0 0.0 0.0] @@ -6261,13 +6323,13 @@ cdef class Matrix(Matrix1): [ 0.897878732... 0.278434036... -0.341010658...] [ 0.408248290... -0.816496580... 0.408248290...] - sage: x, y = var('x y') - sage: S = matrix([[x, y], [y, 3*x^2]]) - sage: em = S.eigenmatrix_left() - sage: eigenvalues = em[0]; eigenvalues + sage: x, y = var('x y') # optional - sage.symbolic + sage: S = matrix([[x, y], [y, 3*x^2]]) # optional - sage.symbolic + sage: em = S.eigenmatrix_left() # optional - sage.symbolic + sage: eigenvalues = em[0]; eigenvalues # optional - sage.symbolic [3/2*x^2 + 1/2*x - 1/2*sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2) 0] [ 0 3/2*x^2 + 1/2*x + 1/2*sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2)] - sage: eigenvectors = em[1]; eigenvectors + sage: eigenvectors = em[1]; eigenvectors # optional - sage.symbolic [ 1 1/2*(3*x^2 - x - sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2))/y] [ 1 1/2*(3*x^2 - x + sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2))/y] @@ -6275,20 +6337,22 @@ cdef class Matrix(Matrix1): possible, will raise an error. Using the ``'galois'`` format option is more likely to be successful. :: - sage: F. = FiniteField(11^2) - sage: A = matrix(F, [[b + 1, b + 1], [10*b + 4, 5*b + 4]]) - sage: A.eigenspaces_left(format='all') + sage: F. = FiniteField(11^2) # optional - sage.rings.finite_rings + sage: A = matrix(F, [[b + 1, b + 1], [10*b + 4, 5*b + 4]]) # optional - sage.rings.finite_rings + sage: A.eigenspaces_left(format='all') # optional - sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: unable to construct eigenspaces for eigenvalues outside the base field, try the keyword option: format='galois' - sage: A.eigenspaces_left(format='galois') - [ - (a0, Vector space of degree 2 and dimension 1 over Univariate Quotient Polynomial Ring in a0 over Finite Field in b of size 11^2 with modulus x^2 + (5*b + 6)*x + 8*b + 10 - User basis matrix: - [ 1 6*b*a0 + 3*b + 1]) - ] + sage: A.eigenspaces_left(format='galois') # optional - sage.rings.finite_rings + [ (a0, + Vector space of degree 2 and dimension 1 over + Univariate Quotient Polynomial Ring in a0 over + Finite Field in b of size 11^2 + with modulus x^2 + (5*b + 6)*x + 8*b + 10 + User basis matrix: + [ 1 6*b*a0 + 3*b + 1]) ] TESTS: @@ -6296,7 +6360,7 @@ cdef class Matrix(Matrix1): sage: M = ModularSymbols(Gamma1(23), sign=1) sage: m = M.cuspidal_subspace().hecke_matrix(2) - sage: [j*m==i[0]*j for i in m.eigenspaces_left(format='all') for j in i[1].basis()] # long time (4s) + sage: [j*m==i[0]*j for i in m.eigenspaces_left(format='all') for j in i[1].basis()] # long time (4s) [True, True, True, True, True, True, True, True, True, True, True, True] sage: B = matrix(QQ, 2, 3, range(6)) @@ -6449,43 +6513,49 @@ cdef class Matrix(Matrix1): We compute the right eigenspaces of a `3\times 3` rational matrix. :: - sage: A = matrix(QQ, 3 ,3, range(9)); A + sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: A.eigenspaces_right() - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (-1.348469228349535?, Vector space of degree 3 and dimension 1 over Algebraic Field - User basis matrix: - [ 1 0.1303061543300932? -0.7393876913398137?]), - (13.34846922834954?, Vector space of degree 3 and dimension 1 over Algebraic Field - User basis matrix: - [ 1 3.069693845669907? 5.139387691339814?]) - ] - sage: es = A.eigenspaces_right(format='galois'); es - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (a1, Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5]) - ] - sage: es = A.eigenspaces_right(format='galois', algebraic_multiplicity=True); es - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1], 1), - (a1, Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5], 1) - ] - sage: e, v, n = es[0]; v = v.basis()[0] - sage: delta = v*e - A*v - sage: abs(abs(delta)) < 1e-10 + sage: A.eigenspaces_right() # optional - sage.rings.number_field + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (-1.348469228349535?, + Vector space of degree 3 and dimension 1 over Algebraic Field + User basis matrix: + [ 1 0.1303061543300932? -0.7393876913398137?]), + (13.34846922834954?, + Vector space of degree 3 and dimension 1 over Algebraic Field + User basis matrix: + [ 1 3.069693845669907? 5.139387691339814?]) ] + sage: es = A.eigenspaces_right(format='galois'); es # optional - sage.rings.number_field + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (a1, + Vector space of degree 3 and dimension 1 over + Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5]) ] + sage: es = A.eigenspaces_right(format='galois', # optional - sage.rings.number_field + ....: algebraic_multiplicity=True); es + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1], + 1), + (a1, + Vector space of degree 3 and dimension 1 over + Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5], + 1) ] + sage: e, v, n = es[0]; v = v.basis()[0] # optional - sage.rings.number_field + sage: delta = v*e - A*v # optional - sage.rings.number_field + sage: abs(abs(delta)) < 1e-10 # optional - sage.rings.number_field True The same computation, but with implicit base change to a field:: @@ -6494,15 +6564,16 @@ cdef class Matrix(Matrix1): [0 1 2] [3 4 5] [6 7 8] - sage: A.eigenspaces_right(format='galois') - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (a1, Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5]) - ] + sage: A.eigenspaces_right(format='galois') # optional - sage.rings.number_field + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (a1, + Vector space of degree 3 and dimension 1 over + Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5]) ] This method is only applicable to exact matrices. The "eigenmatrix" routines for matrices with double-precision @@ -6516,11 +6587,12 @@ cdef class Matrix(Matrix1): sage: B.eigenspaces_right() Traceback (most recent call last): ... - NotImplementedError: eigenspaces cannot be computed reliably for inexact rings such as Real Field with 53 bits of precision, + NotImplementedError: eigenspaces cannot be computed reliably + for inexact rings such as Real Field with 53 bits of precision, consult numerical or symbolic matrix classes for other options sage: em = B.change_ring(RDF).eigenmatrix_right() - sage: eigenvalues = em[0]; eigenvalues.dense_matrix() # abs tol 1e-13 + sage: eigenvalues = em[0]; eigenvalues.dense_matrix() # abs tol 1e-13 [13.348469228349522 0.0 0.0] [ 0.0 -1.348469228349534 0.0] [ 0.0 0.0 0.0] @@ -6529,13 +6601,13 @@ cdef class Matrix(Matrix1): [ 0.505774475... 0.104205787... -0.816496580...] [ 0.846785134... -0.591288087... 0.408248290...] - sage: x, y = var('x y') - sage: S = matrix([[x, y], [y, 3*x^2]]) - sage: em = S.eigenmatrix_right() - sage: eigenvalues = em[0]; eigenvalues + sage: x, y = var('x y') # optional - sage.symbolic + sage: S = matrix([[x, y], [y, 3*x^2]]) # optional - sage.symbolic + sage: em = S.eigenmatrix_right() # optional - sage.symbolic + sage: eigenvalues = em[0]; eigenvalues # optional - sage.symbolic [3/2*x^2 + 1/2*x - 1/2*sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2) 0] [ 0 3/2*x^2 + 1/2*x + 1/2*sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2)] - sage: eigenvectors = em[1]; eigenvectors + sage: eigenvectors = em[1]; eigenvectors # optional - sage.symbolic [ 1 1] [1/2*(3*x^2 - x - sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2))/y 1/2*(3*x^2 - x + sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2))/y] @@ -6589,11 +6661,11 @@ cdef class Matrix(Matrix1): right_eigenspaces = eigenspaces_right - def eigenvalues(self,extend=True): + def eigenvalues(self, extend=True): r""" Return a sequence of the eigenvalues of a matrix, with - multiplicity. If the eigenvalues are roots of polynomials in QQ, - then QQbar elements are returned that represent each separate + multiplicity. If the eigenvalues are roots of polynomials in ``QQ``, + then ``QQbar`` elements are returned that represent each separate root. If the option extend is set to False, only eigenvalues in the base @@ -6606,33 +6678,40 @@ cdef class Matrix(Matrix1): [ 4 5 6 7] [ 8 9 10 11] [12 13 14 15] - sage: sorted(a.eigenvalues(), reverse=True) + sage: sorted(a.eigenvalues(), reverse=True) # optional - sage.rings.number_field [32.46424919657298?, 0, 0, -2.464249196572981?] :: - sage: a=matrix([(1, 9, -1, -1), (-2, 0, -10, 2), (-1, 0, 15, -2), (0, 1, 0, -1)]) - sage: a.eigenvalues() - [-0.9386318578049146?, 15.50655435353258?, 0.2160387521361705? - 4.713151979747493?*I, 0.2160387521361705? + 4.713151979747493?*I] + sage: a = matrix([(1, 9, -1, -1), + ....: (-2, 0, -10, 2), + ....: (-1, 0, 15, -2), + ....: (0, 1, 0, -1)]) + sage: a.eigenvalues() # optional - sage.rings.number_field + [-0.9386318578049146?, + 15.50655435353258?, + 0.2160387521361705? - 4.713151979747493?*I, + 0.2160387521361705? + 4.713151979747493?*I] - A symmetric matrix a+a.transpose() should have real eigenvalues + A symmetric matrix ``a + a.transpose()`` should have real eigenvalues :: - sage: b=a+a.transpose() - sage: ev = b.eigenvalues(); ev - [-8.35066086057957?, -1.107247901349379?, 5.718651326708515?, 33.73925743522043?] + sage: b = a + a.transpose() + sage: ev = b.eigenvalues(); ev # optional - sage.rings.number_field + [-8.35066086057957?, -1.107247901349379?, + 5.718651326708515?, 33.73925743522043?] - The eigenvalues are elements of QQbar, so they really represent + The eigenvalues are elements of ``QQbar``, so they really represent exact roots of polynomials, not just approximations. :: - sage: e = ev[0]; e + sage: e = ev[0]; e # optional - sage.rings.number_field -8.35066086057957? - sage: p = e.minpoly(); p + sage: p = e.minpoly(); p # optional - sage.rings.number_field x^4 - 30*x^3 - 171*x^2 + 1460*x + 1784 - sage: p(e) == 0 + sage: p(e) == 0 # optional - sage.rings.number_field True To perform computations on the eigenvalue as an element of a number @@ -6640,42 +6719,46 @@ cdef class Matrix(Matrix1): :: - sage: e.as_number_field_element() - (Number Field in a with defining polynomial y^4 - 2*y^3 - 507*y^2 - 3972*y - 4264, + sage: e.as_number_field_element() # optional - sage.rings.number_field + (Number Field in a + with defining polynomial y^4 - 2*y^3 - 507*y^2 - 3972*y - 4264, a + 7, Ring morphism: - From: Number Field in a with defining polynomial y^4 - 2*y^3 - 507*y^2 - 3972*y - 4264 + From: Number Field in a with defining polynomial + y^4 - 2*y^3 - 507*y^2 - 3972*y - 4264 To: Algebraic Real Field Defn: a |--> -15.35066086057957?) - Notice the effect of the extend option. + Notice the effect of the ``extend`` option. :: - sage: M=matrix(QQ,[[0,-1,0],[1,0,0],[0,0,2]]) - sage: M.eigenvalues() + sage: M = matrix(QQ, [[0,-1,0], [1,0,0], [0,0,2]]) + sage: M.eigenvalues() # optional - sage.rings.number_field [2, -1*I, 1*I] - sage: M.eigenvalues(extend=False) + sage: M.eigenvalues(extend=False) # optional - sage.rings.number_field [2] The method also works for matrices over finite fields:: - sage: M = matrix(GF(3), [[0,1,1],[1,2,0],[2,0,1]]) - sage: ev = sorted(M.eigenvalues()); ev + sage: M = matrix(GF(3), [[0,1,1], [1,2,0], [2,0,1]]) # optional - sage.rings.finite_rings + sage: ev = sorted(M.eigenvalues()); ev # optional - sage.rings.finite_rings [2*z3, 2*z3 + 1, 2*z3 + 2] - Similarly as in the case of QQbar, the eigenvalues belong to some + Similarly as in the case of ``QQbar``, the eigenvalues belong to some algebraic closure but they can be converted to elements of a finite field:: - sage: e = ev[0] - sage: e.parent() + sage: e = ev[0] # optional - sage.rings.finite_rings + sage: e.parent() # optional - sage.rings.finite_rings Algebraic closure of Finite Field of size 3 - sage: e.as_finite_field_element() - (Finite Field in z3 of size 3^3, 2*z3, Ring morphism: - From: Finite Field in z3 of size 3^3 - To: Algebraic closure of Finite Field of size 3 - Defn: z3 |--> z3) + sage: e.as_finite_field_element() # optional - sage.rings.finite_rings + (Finite Field in z3 of size 3^3, + 2*z3, + Ring morphism: + From: Finite Field in z3 of size 3^3 + To: Algebraic closure of Finite Field of size 3 + Defn: z3 |--> z3) """ x = self.fetch('eigenvalues') if x is not None: @@ -6744,31 +6827,29 @@ cdef class Matrix(Matrix1): :: - sage: A = matrix(QQ,3,3,range(9)); A + sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: es = A.eigenvectors_left(); es - [(0, [ - (1, -2, 1) - ], 1), - (-1.348469228349535?, [(1, 0.3101020514433644?, -0.3797958971132713?)], 1), - (13.34846922834954?, [(1, 1.289897948556636?, 1.579795897113272?)], 1)] - sage: eval, [evec], mult = es[0] - sage: delta = eval*evec - evec*A - sage: abs(abs(delta)) < 1e-10 + sage: es = A.eigenvectors_left(); es # optional - sage.rings.number_field + [(0, [ (1, -2, 1) ], 1), + (-1.348469228349535?, [(1, 0.3101020514433644?, -0.3797958971132713?)], 1), + (13.34846922834954?, [(1, 1.289897948556636?, 1.579795897113272?)], 1)] + sage: eval, [evec], mult = es[0] # optional - sage.rings.number_field + sage: delta = eval*evec - evec*A # optional - sage.rings.number_field + sage: abs(abs(delta)) < 1e-10 # optional - sage.rings.number_field True Notice the difference between considering ring extensions or not. :: - sage: M=matrix(QQ,[[0,-1,0],[1,0,0],[0,0,2]]) - sage: M.eigenvectors_left() - [(2, [ - (0, 0, 1) - ], 1), (-1*I, [(1, -1*I, 0)], 1), (1*I, [(1, 1*I, 0)], 1)] - sage: M.eigenvectors_left(extend=False) + sage: M = matrix(QQ, [[0,-1,0], [1,0,0], [0,0,2]]) + sage: M.eigenvectors_left() # optional - sage.rings.number_field + [(2, [ (0, 0, 1) ], 1), + (-1*I, [(1, -1*I, 0)], 1), + (1*I, [(1, 1*I, 0)], 1)] + sage: M.eigenvectors_left(extend=False) # optional - sage.rings.number_field [(2, [ (0, 0, 1) ], 1)] @@ -6785,16 +6866,16 @@ cdef class Matrix(Matrix1): Check the deprecation:: - sage: matrix(QQ, [[1, 2], [3, 4]]).eigenvectors_left(False) + sage: matrix(QQ, [[1, 2], [3, 4]]).eigenvectors_left(False) # optional - sage.rings.number_field doctest:...: DeprecationWarning: "extend" should be used as keyword argument See https://github.com/sagemath/sage/issues/29243 for details. [] Check :trac:`30518`:: - sage: K. = QuadraticField(-1) - sage: m = matrix(K, 4, [2,4*i,-i,0, -4*i,2,-1,0, 2*i,-2,0,0, 4*i+4, 4*i-4,1-i,-2]) - sage: assert all(m*v == e*v for e, vs, _ in m.eigenvectors_right() for v in vs) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: m = matrix(K, 4, [2,4*i,-i,0, -4*i,2,-1,0, 2*i,-2,0,0, 4*i+4, 4*i-4,1-i,-2]) # optional - sage.rings.number_field + sage: assert all(m*v == e*v for e, vs, _ in m.eigenvectors_right() for v in vs) # optional - sage.rings.number_field """ if other is not None: if isinstance(other, bool): @@ -6878,23 +6959,21 @@ cdef class Matrix(Matrix1): :: - sage: A = matrix(QQ,3,3,range(9)); A + sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: es = A.eigenvectors_right(); es - [(0, [ - (1, -2, 1) - ], 1), - (-1.348469228349535?, [(1, 0.1303061543300932?, -0.7393876913398137?)], 1), - (13.34846922834954?, [(1, 3.069693845669907?, 5.139387691339814?)], 1)] - sage: A.eigenvectors_right(extend=False) + sage: es = A.eigenvectors_right(); es # optional - sage.rings.number_field + [(0, [ (1, -2, 1) ], 1), + (-1.348469228349535?, [(1, 0.1303061543300932?, -0.7393876913398137?)], 1), + (13.34846922834954?, [(1, 3.069693845669907?, 5.139387691339814?)], 1)] + sage: A.eigenvectors_right(extend=False) # optional - sage.rings.number_field [(0, [ (1, -2, 1) ], 1)] - sage: eval, [evec], mult = es[0] - sage: delta = eval*evec - A*evec - sage: abs(abs(delta)) < 1e-10 + sage: eval, [evec], mult = es[0] # optional - sage.rings.number_field + sage: delta = eval*evec - A*evec # optional - sage.rings.number_field + sage: abs(abs(delta)) < 1e-10 # optional - sage.rings.number_field True TESTS:: @@ -6950,27 +7029,27 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQ,3,3,range(9)); A + sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: D, P = A.eigenmatrix_left() - sage: D + sage: D, P = A.eigenmatrix_left() # optional - sage.rings.number_field + sage: D # optional - sage.rings.number_field [ 0 0 0] [ 0 -1.348469228349535? 0] [ 0 0 13.34846922834954?] - sage: P + sage: P # optional - sage.rings.number_field [ 1 -2 1] [ 1 0.3101020514433644? -0.3797958971132713?] [ 1 1.289897948556636? 1.579795897113272?] - sage: P*A == D*P + sage: P*A == D*P # optional - sage.rings.number_field True Because `P` is invertible, `A` is diagonalizable. :: - sage: A == (~P)*D*P + sage: A == (~P)*D*P # optional - sage.rings.number_field True The matrix `P` may contain zero rows corresponding to eigenvalues for @@ -6979,20 +7058,20 @@ cdef class Matrix(Matrix1): :: - sage: A = jordan_block(2,3); A + sage: A = jordan_block(2, 3); A [2 1 0] [0 2 1] [0 0 2] - sage: D, P = A.eigenmatrix_left() - sage: D + sage: D, P = A.eigenmatrix_left() # optional - sage.rings.number_field + sage: D # optional - sage.rings.number_field [2 0 0] [0 2 0] [0 0 2] - sage: P + sage: P # optional - sage.rings.number_field [0 0 1] [0 0 0] [0 0 0] - sage: P*A == D*P + sage: P*A == D*P # optional - sage.rings.number_field True A generalized eigenvector decomposition:: @@ -7041,7 +7120,7 @@ cdef class Matrix(Matrix1): sage: A = matrix(QQ, 3, 3, range(9)) sage: em = A.change_ring(RDF).eigenmatrix_left() - sage: evalues = em[0]; evalues.dense_matrix() # abs tol 1e-13 + sage: evalues = em[0]; evalues.dense_matrix() # abs tol 1e-13 [13.348469228349522 0.0 0.0] [ 0.0 -1.348469228349534 0.0] [ 0.0 0.0 0.0] @@ -7077,21 +7156,23 @@ cdef class Matrix(Matrix1): the algebraic multiplicity. The following examples show that these cases are detected (:trac:`27842`):: - sage: A = matrix(SR, [(225/548, 0, -175/274*sqrt(193/1446)), # optional - sage.symbolic + sage: A = matrix(SR, [(225/548, 0, -175/274*sqrt(193/1446)), # optional - sage.symbolic ....: (0, 1/2, 0), ....: (-63/548*sqrt(723/386), 0, 49/548)]) - sage: A.eigenmatrix_left() # optional - sage.symbolic + sage: A.eigenmatrix_left() # optional - sage.symbolic Traceback (most recent call last): ... - RuntimeError: failed to compute eigenvectors for eigenvalue ..., check eigenvectors_left() for partial results - sage: B = matrix(SR, [(1/2, -7/2*sqrt(1/386), 0, 49/2*sqrt(1/279078)), # optional - sage.symbolic + RuntimeError: failed to compute eigenvectors for eigenvalue ..., + check eigenvectors_left() for partial results + sage: B = matrix(SR, [(1/2, -7/2*sqrt(1/386), 0, 49/2*sqrt(1/279078)), # optional - sage.symbolic ....: (-7/2*sqrt(1/386), 211/772, 0, -8425/772*sqrt(1/723)), ....: (0, 0, 1/2, 0), ....: (49/2*sqrt(1/279078), -8425/772*sqrt(1/723), 0, 561/772)]) - sage: B.eigenmatrix_left() # long time (1.2 seconds) # optional - sage.symbolic + sage: B.eigenmatrix_left() # long time (1.2 seconds) # optional - sage.symbolic Traceback (most recent call last): ... - RuntimeError: failed to compute eigenvectors for eigenvalue ..., check eigenvectors_left() for partial results + RuntimeError: failed to compute eigenvectors for eigenvalue ..., + check eigenvectors_left() for partial results The following example shows that :trac:`12595` has been resolved:: @@ -7166,27 +7247,27 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQ,3,3,range(9)); A + sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: D, P = A.eigenmatrix_right() - sage: D + sage: D, P = A.eigenmatrix_right() # optional - sage.rings.number_field + sage: D # optional - sage.rings.number_field [ 0 0 0] [ 0 -1.348469228349535? 0] [ 0 0 13.34846922834954?] - sage: P + sage: P # optional - sage.rings.number_field [ 1 1 1] [ -2 0.1303061543300932? 3.069693845669907?] [ 1 -0.7393876913398137? 5.139387691339814?] - sage: A*P == P*D + sage: A*P == P*D # optional - sage.rings.number_field True Because `P` is invertible, `A` is diagonalizable. :: - sage: A == P*D*(~P) + sage: A == P*D*(~P) # optional - sage.rings.number_field True The matrix `P` may contain zero columns corresponding to eigenvalues @@ -7195,20 +7276,20 @@ cdef class Matrix(Matrix1): :: - sage: A = jordan_block(2,3); A + sage: A = jordan_block(2, 3); A [2 1 0] [0 2 1] [0 0 2] - sage: D, P = A.eigenmatrix_right() - sage: D + sage: D, P = A.eigenmatrix_right() # optional - sage.rings.number_field + sage: D # optional - sage.rings.number_field [2 0 0] [0 2 0] [0 0 2] - sage: P + sage: P # optional - sage.rings.number_field [1 0 0] [0 0 0] [0 0 0] - sage: A*P == P*D + sage: A*P == P*D # optional - sage.rings.number_field True A generalized eigenvector decomposition:: @@ -7308,8 +7389,8 @@ cdef class Matrix(Matrix1): sage: M.eigenvalue_multiplicity(1) 0 - sage: M = posets.DiamondPoset(5).coxeter_transformation() - sage: [M.eigenvalue_multiplicity(x) for x in [-1, 1]] + sage: M = posets.DiamondPoset(5).coxeter_transformation() # optional - sage.combinat, sage.graphs + sage: [M.eigenvalue_multiplicity(x) for x in [-1, 1]] # optional - sage.combinat, sage.graphs [3, 2] TESTS:: @@ -7362,7 +7443,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A=matrix(3,range(9)); A + sage: A = matrix(3, range(9)); A [0 1 2] [3 4 5] [6 7 8] @@ -7405,8 +7486,8 @@ cdef class Matrix(Matrix1): Since :meth:`echelon_form` is not implemented for every ring, sometimes behavior varies, as here:: - sage: R.=ZZ[] - sage: C = matrix(3,[2,x,x^2,x+1,3-x,-1,3,2,1]) + sage: R. = ZZ[] + sage: C = matrix(3, [2,x,x^2, x+1,3-x,-1, 3,2,1]) sage: C.rref() [1 0 0] [0 1 0] @@ -7416,9 +7497,11 @@ cdef class Matrix(Matrix1): sage: C.echelon_form() Traceback (most recent call last): ... - NotImplementedError: Ideal Ideal (2, x + 1) of Univariate Polynomial Ring in x over Integer Ring not principal - Echelon form not implemented over 'Univariate Polynomial Ring in x over Integer Ring'. - sage: C = matrix(3,[2,x,x^2,x+1,3-x,-1,3,2,1/2]) + NotImplementedError: Ideal Ideal (2, x + 1) of Univariate + Polynomial Ring in x over Integer Ring not principal + Echelon form not implemented over 'Univariate + Polynomial Ring in x over Integer Ring'. + sage: C = matrix(3, [2,x,x^2, x+1,3-x,-1, 3,2,1/2]) sage: C.echelon_form() [ 2 x x^2] [ 0 1 15*x^2 - 3/2*x - 31/2] @@ -7427,7 +7510,7 @@ cdef class Matrix(Matrix1): [1 0 0] [0 1 0] [0 0 1] - sage: C = matrix(3,[2,x,x^2,x+1,3-x,-1/x,3,2,1/2]) + sage: C = matrix(3, [2,x,x^2, x+1,3-x,-1/x, 3,2,1/2]) sage: C.echelon_form() [1 0 0] [0 1 0] @@ -7462,18 +7545,18 @@ cdef class Matrix(Matrix1): [ 0 4 8 12] [ 0 0 0 0] - sage: L. = NumberField(x^2 - x + 2) - sage: OL = L.ring_of_integers() - sage: m = matrix(OL, 2, 2, [1,2,3,4+w]) - sage: m.echelon_form() + sage: L. = NumberField(x^2 - x + 2) # optional - sage.rings.number_field + sage: OL = L.ring_of_integers() # optional - sage.rings.number_field + sage: m = matrix(OL, 2, 2, [1,2,3,4+w]) # optional - sage.rings.number_field + sage: m.echelon_form() # optional - sage.rings.number_field [ 1 2] [ 0 w - 2] - sage: E, T = m.echelon_form(transformation=True); E,T + sage: E, T = m.echelon_form(transformation=True); E, T # optional - sage.rings.number_field ( [ 1 2] [ 1 0] [ 0 w - 2], [-3 1] ) - sage: E == T*m + sage: E == T*m # optional - sage.rings.number_field True TESTS: @@ -7575,7 +7658,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: a = matrix(QQ,3,3,range(9)); a + sage: a = matrix(QQ, 3,3, range(9)); a [0 1 2] [3 4 5] [6 7 8] @@ -7588,7 +7671,7 @@ cdef class Matrix(Matrix1): An immutable matrix cannot be transformed into echelon form. Use ``self.echelon_form()`` instead:: - sage: a = matrix(QQ,3,3,range(9)); a.set_immutable() + sage: a = matrix(QQ, 3,3, range(9)); a.set_immutable() sage: a.echelonize() Traceback (most recent call last): ... @@ -7602,7 +7685,7 @@ cdef class Matrix(Matrix1): Echelon form over the integers is what is also classically often known as Hermite normal form:: - sage: a = matrix(ZZ,3,3,range(9)) + sage: a = matrix(ZZ, 3,3, range(9)) sage: a.echelonize(); a [ 3 0 -3] [ 0 1 2] @@ -7611,7 +7694,7 @@ cdef class Matrix(Matrix1): We compute an echelon form both over a domain and fraction field:: sage: R. = QQ[] - sage: a = matrix(R, 2, [x,y,x,y]) + sage: a = matrix(R, 2, [x,y, x,y]) sage: a.echelon_form() # not very useful? -- why two copies of the same row? [x y] [x y] @@ -7626,21 +7709,21 @@ cdef class Matrix(Matrix1): We check that the echelon form works for matrices over p-adics. See :trac:`17272`:: - sage: R = ZpCA(5,5,print_mode='val-unit') - sage: A = matrix(R,3,3,[250,2369,1147,106,927,362,90,398,2483]) - sage: A + sage: R = ZpCA(5,5,print_mode='val-unit') # optional - sage.rings.padics + sage: A = matrix(R, 3,3, [250,2369,1147, 106,927,362, 90,398,2483]) # optional - sage.rings.padics + sage: A # optional - sage.rings.padics [5^3 * 2 + O(5^5) 2369 + O(5^5) 1147 + O(5^5)] [ 106 + O(5^5) 927 + O(5^5) 362 + O(5^5)] [ 5 * 18 + O(5^5) 398 + O(5^5) 2483 + O(5^5)] - sage: K = R.fraction_field() - sage: A.change_ring(K).augment(identity_matrix(K,3)).echelon_form() + sage: K = R.fraction_field() # optional - sage.rings.padics + sage: A.change_ring(K).augment(identity_matrix(K,3)).echelon_form() # optional - sage.rings.padics [ 1 + O(5^5) O(5^5) O(5^5) 5 * 212 + O(5^5) 3031 + O(5^5) 2201 + O(5^5)] [ O(5^5) 1 + O(5^5) O(5^5) 1348 + O(5^5) 5 * 306 + O(5^5) 2648 + O(5^5)] [ O(5^5) O(5^5) 1 + O(5^5) 1987 + O(5^5) 5 * 263 + O(5^5) 154 + O(5^5)] Echelon form is not defined over arbitrary rings:: - sage: a = matrix(Integers(9),3,3,range(9)) + sage: a = matrix(Integers(9), 3,3, range(9)) sage: a.echelon_form() Traceback (most recent call last): ... @@ -7672,8 +7755,8 @@ cdef class Matrix(Matrix1): Check that :trac:`34724` is fixed (indirect doctest):: - sage: a=6.12323399573677e-17 - sage: m=matrix(RR,[[-a, -1.72508242466029], [ 0.579682446302195, a]]) + sage: a = 6.12323399573677e-17 + sage: m = matrix(RR, [[-a, -1.72508242466029], [ 0.579682446302195, a]]) sage: (~m*m).norm() 1.0 """ @@ -7769,13 +7852,13 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: MS = MatrixSpace(GF(19),2,3) - sage: C = MS.matrix([1,2,3,4,5,6]) - sage: C.rank() + sage: MS = MatrixSpace(GF(19), 2, 3) # optional - sage.rings.finite_rings + sage: C = MS.matrix([1,2,3,4,5,6]) # optional - sage.rings.finite_rings + sage: C.rank() # optional - sage.rings.finite_rings 2 - sage: C.nullity() + sage: C.nullity() # optional - sage.rings.finite_rings 0 - sage: C.echelon_form() + sage: C.echelon_form() # optional - sage.rings.finite_rings [ 1 0 18] [ 0 1 2] @@ -7783,7 +7866,7 @@ cdef class Matrix(Matrix1): the transformation matrix, so the ``transformation`` option is ignored:: - sage: C.echelon_form(transformation=True) + sage: C.echelon_form(transformation=True) # optional - sage.rings.finite_rings [ 1 0 18] [ 0 1 2] @@ -7835,17 +7918,17 @@ cdef class Matrix(Matrix1): [ 1 0 -1] [ 0 1 2] [ 0 0 0] - sage: a = matrix(QQ,2,[1..6]) + sage: a = matrix(QQ, 2, [1..6]) sage: a._echelon('classical') [ 1 0 -1] [ 0 1 2] - sage: R = ZpCA(5,5,print_mode='val-unit') - sage: A = matrix(R,3,3,[250,2369,1147,106,927,362,90,398,2483]) - sage: A + sage: R = ZpCA(5, 5, print_mode='val-unit') # optional - sage.rings.padics + sage: A = matrix(R, 3, 3, [250,2369,1147, 106,927,362, 90,398,2483]) # optional - sage.rings.padics + sage: A # optional - sage.rings.padics [5^3 * 2 + O(5^5) 2369 + O(5^5) 1147 + O(5^5)] [ 106 + O(5^5) 927 + O(5^5) 362 + O(5^5)] [ 5 * 18 + O(5^5) 398 + O(5^5) 2483 + O(5^5)] - sage: A._echelon('partial_pivoting') + sage: A._echelon('partial_pivoting') # optional - sage.rings.padics [1 + O(5^5) O(5^5) O(5^5)] [ O(5^5) 1 + O(5^5) O(5^5)] [ O(5^5) O(5^5) 1 + O(5^5)] @@ -7893,7 +7976,7 @@ cdef class Matrix(Matrix1): [ 1 0 -1] [ 0 1 2] [ 0 0 0] - sage: a = matrix(QQ,2,[1..6]) + sage: a = matrix(QQ, 2, [1..6]) sage: a._echelon_classical() [ 1 0 -1] [ 0 1 2] @@ -7918,13 +8001,13 @@ cdef class Matrix(Matrix1): sage: P = a._echelon_in_place('classical'); a [ 1 0 -1] [ 0 1 2] - sage: R = ZpCA(5,5,print_mode='val-unit') - sage: A = matrix(R,3,3,[250,2369,1147,106,927,362,90,398,2483]) - sage: A + sage: R = ZpCA(5, 5, print_mode='val-unit') # optional - sage.rings.padics + sage: A = matrix(R,3,3,[250,2369,1147,106,927,362,90,398,2483]) # optional - sage.rings.padics + sage: A # optional - sage.rings.padics [5^3 * 2 + O(5^5) 2369 + O(5^5) 1147 + O(5^5)] [ 106 + O(5^5) 927 + O(5^5) 362 + O(5^5)] [ 5 * 18 + O(5^5) 398 + O(5^5) 2483 + O(5^5)] - sage: P = A._echelon_in_place('partial_pivoting'); A + sage: P = A._echelon_in_place('partial_pivoting'); A # optional - sage.rings.padics [1 + O(5^5) O(5^5) O(5^5)] [ O(5^5) 1 + O(5^5) O(5^5)] [ O(5^5) O(5^5) 1 + O(5^5)] @@ -8067,7 +8150,7 @@ cdef class Matrix(Matrix1): [ 1 0 -1] [ 0 1 2] [ 0 0 0] - sage: a = matrix(QQ,2,[1..6]) + sage: a = matrix(QQ, 2, [1..6]) sage: P = a._echelon_in_place_classical(); a [ 1 0 -1] [ 0 1 2] @@ -8209,20 +8292,20 @@ cdef class Matrix(Matrix1): Subdivided, or not, the result is immutable, so make a copy if you want to make changes. :: - sage: A = matrix(FiniteField(7), [[2,0,3], [5,5,3], [5,6,5]]) - sage: E = A.extended_echelon_form() - sage: E.is_mutable() + sage: A = matrix(FiniteField(7), [[2,0,3], [5,5,3], [5,6,5]]) # optional - sage.rings.finite_rings + sage: E = A.extended_echelon_form() # optional - sage.rings.finite_rings + sage: E.is_mutable() # optional - sage.rings.finite_rings False - sage: F = A.extended_echelon_form(subdivide=True) - sage: F + sage: F = A.extended_echelon_form(subdivide=True) # optional - sage.rings.finite_rings + sage: F # optional - sage.rings.finite_rings [1 0 0|0 4 6] [0 1 0|4 2 2] [0 0 1|5 2 3] [-----+-----] - sage: F.is_mutable() + sage: F.is_mutable() # optional - sage.rings.finite_rings False - sage: G = copy(F) - sage: G.subdivide([],[]); G + sage: G = copy(F) # optional - sage.rings.finite_rings + sage: G.subdivide([], []); G # optional - sage.rings.finite_rings [1 0 0 0 4 6] [0 1 0 4 2 2] [0 0 1 5 2 3] @@ -8296,14 +8379,14 @@ cdef class Matrix(Matrix1): [ 6 1/4] [ 8 -5] - sage: B = M.as_bipartite_graph() - sage: B + sage: B = M.as_bipartite_graph() # optional - sage.graphs + sage: B # optional - sage.graphs Bipartite graph on 5 vertices - sage: B.edges(sort=True) + sage: B.edges(sort=True) # optional - sage.graphs [(1, 4, 1/3), (1, 5, 7), (2, 4, 6), (2, 5, 1/4), (3, 4, 8), (3, 5, -5)] - sage: len(B.left) == M.nrows() + sage: len(B.left) == M.nrows() # optional - sage.graphs True - sage: len(B.right) == M.ncols() + sage: len(B.right) == M.ncols() # optional - sage.graphs True """ from sage.graphs.bipartite_graph import BipartiteGraph @@ -8325,23 +8408,23 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = matrix(ZZ,[[1,0],[1,0],[0,1]]) + sage: M = matrix(ZZ, [[1,0],[1,0],[0,1]]) sage: M [1 0] [1 0] [0 1] - sage: A = M.automorphisms_of_rows_and_columns() - sage: A + sage: A = M.automorphisms_of_rows_and_columns() # optional - sage.groups + sage: A # optional - sage.groups [((), ()), ((1,2), ())] - sage: M = matrix(ZZ,[[1,1,1,1],[1,1,1,1]]) - sage: A = M.automorphisms_of_rows_and_columns() - sage: len(A) + sage: M = matrix(ZZ, [[1,1,1,1],[1,1,1,1]]) # optional - sage.groups + sage: A = M.automorphisms_of_rows_and_columns() # optional - sage.groups + sage: len(A) # optional - sage.groups 48 One can now apply these automorphisms to ``M`` to show that it leaves it invariant:: - sage: all(M.with_permuted_rows_and_columns(*i) == M for i in A) + sage: all(M.with_permuted_rows_and_columns(*i) == M for i in A) # optional - sage.groups True Check that :trac:`25426` is fixed:: @@ -8351,7 +8434,7 @@ cdef class Matrix(Matrix1): ....: (1, 0, 3, 0, 2), ....: (0, 1, 0, 2, 1), ....: (0, 0, 2, 1, 2)]) - sage: j.automorphisms_of_rows_and_columns() + sage: j.automorphisms_of_rows_and_columns() # optional - sage.groups [((), ()), ((1,3)(2,5), (1,3)(2,5))] """ from sage.groups.perm_gps.constructor import \ @@ -8409,7 +8492,7 @@ cdef class Matrix(Matrix1): [-1 5] [ 2 4] - sage: M.permutation_normal_form(check=True) + sage: M.permutation_normal_form(check=True) # optional - sage.graphs ( [ 5 -1] [ 4 2] @@ -8420,7 +8503,7 @@ cdef class Matrix(Matrix1): TESTS:: sage: M = matrix(ZZ, [[3, 4, 5], [3, 4, 5], [3, 5, 4], [2, 0,1]]) - sage: M.permutation_normal_form() + sage: M.permutation_normal_form() # optional - sage.graphs [5 4 3] [5 4 3] [4 5 3] @@ -8561,47 +8644,47 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = matrix(ZZ,[[1,2,3],[3,5,3],[2,6,4]]) + sage: M = matrix(ZZ, [[1,2,3], [3,5,3], [2,6,4]]) sage: M [1 2 3] [3 5 3] [2 6 4] - sage: N = matrix(ZZ,[[1,2,3],[2,6,4],[3,5,3]]) + sage: N = matrix(ZZ, [[1,2,3], [2,6,4], [3,5,3]]) sage: N [1 2 3] [2 6 4] [3 5 3] - sage: M.is_permutation_of(N) + sage: M.is_permutation_of(N) # optional - sage.graphs True Some examples that are not permutations of each other:: - sage: N = matrix(ZZ,[[1,2,3],[4,5,6],[7,8,9]]) + sage: N = matrix(ZZ, [[1,2,3], [4,5,6], [7,8,9]]) sage: N [1 2 3] [4 5 6] [7 8 9] - sage: M.is_permutation_of(N) + sage: M.is_permutation_of(N) # optional - sage.graphs False - sage: N = matrix(ZZ,[[1,2],[3,4]]) + sage: N = matrix(ZZ, [[1,2], [3,4]]) sage: N [1 2] [3 4] - sage: M.is_permutation_of(N) + sage: M.is_permutation_of(N) # optional - sage.graphs False And for when ``check`` is True:: - sage: N = matrix(ZZ,[[3,5,3],[2,6,4],[1,2,3]]) + sage: N = matrix(ZZ, [[3,5,3], [2,6,4], [1,2,3]]) sage: N [3 5 3] [2 6 4] [1 2 3] - sage: r = M.is_permutation_of(N, check=True) - sage: r + sage: r = M.is_permutation_of(N, check=True) # optional - sage.graphs + sage: r # optional - sage.graphs (True, ((1,2,3), ())) - sage: p = r[1] - sage: M.with_permuted_rows_and_columns(*p) == N + sage: p = r[1] # optional - sage.graphs + sage: M.with_permuted_rows_and_columns(*p) == N # optional - sage.graphs True """ ncols = self.ncols() @@ -8647,7 +8730,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: a = matrix(ZZ,4,4,range(16)) + sage: a = matrix(ZZ, 4,4, range(16)) sage: a._multiply_strassen(a,2) [ 56 62 68 74] [152 174 196 218] @@ -8819,26 +8902,26 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = matrix(5, 5, prime_range(100)) - sage: M.subdivide(2,3); M + sage: M = matrix(5, 5, prime_range(100)) # optional - sage.libs.pari + sage: M.subdivide(2,3); M # optional - 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] - sage: M.subdivision(0,0) + sage: M.subdivision(0,0) # optional - sage.libs.pari [ 2 3 5] [13 17 19] - sage: M.subdivision(1,0) + sage: M.subdivision(1,0) # optional - sage.libs.pari [31 37 41] [53 59 61] [73 79 83] - sage: M.subdivision_entry(1,0,0,0) + sage: M.subdivision_entry(1,0,0,0) # optional - sage.libs.pari 31 - sage: M.subdivisions() + sage: M.subdivisions() # optional - sage.libs.pari ([2], [3]) - sage: M.subdivide(None, [1,3]); M + sage: M.subdivide(None, [1,3]); M # optional - sage.libs.pari [ 2| 3 5| 7 11] [13|17 19|23 29] [31|37 41|43 47] @@ -8847,7 +8930,7 @@ cdef class Matrix(Matrix1): Degenerate cases work too:: - sage: M.subdivide([2,5], [0,1,3]); M + sage: M.subdivide([2,5], [0,1,3]); M # optional - sage.libs.pari [| 2| 3 5| 7 11] [|13|17 19|23 29] [+--+-----+-----] @@ -8855,12 +8938,12 @@ cdef class Matrix(Matrix1): [|53|59 61|67 71] [|73|79 83|89 97] [+--+-----+-----] - sage: M.subdivision(0,0) + sage: M.subdivision(0,0) # optional - sage.libs.pari [] - sage: M.subdivision(0,1) + sage: M.subdivision(0,1) # optional - sage.libs.pari [ 2] [13] - sage: M.subdivide([2,2,3], [0,0,1,1]); M + sage: M.subdivide([2,2,3], [0,0,1,1]); M # optional - sage.libs.pari [|| 2|| 3 5 7 11] [||13||17 19 23 29] [++--++-----------] @@ -8869,14 +8952,14 @@ cdef class Matrix(Matrix1): [++--++-----------] [||53||59 61 67 71] [||73||79 83 89 97] - sage: M.subdivision(0,0) + sage: M.subdivision(0,0) # optional - sage.libs.pari [] - sage: M.subdivision(2,4) + sage: M.subdivision(2,4) # optional - sage.libs.pari [37 41 43 47] Indices do not need to be in the right order (:trac:`14064`):: - sage: M.subdivide([4, 2], [3, 1]); M + sage: M.subdivide([4, 2], [3, 1]); M # optional - sage.libs.pari [ 2| 3 5| 7 11] [13|17 19|23 29] [--+-----+-----] @@ -9200,15 +9283,17 @@ cdef class Matrix(Matrix1): Different base rings are handled sensibly. :: sage: A = matrix(ZZ, 2, 3, range(6)) - sage: B = matrix(FiniteField(23), 3, 4, range(12)) - sage: C = matrix(FiniteField(29), 4, 5, range(20)) - sage: D = A.tensor_product(B) - sage: D.parent() + sage: B = matrix(FiniteField(23), 3, 4, range(12)) # optional - sage.rings.finite_rings + sage: C = matrix(FiniteField(29), 4, 5, range(20)) # optional - sage.rings.finite_rings + sage: D = A.tensor_product(B) # optional - sage.rings.finite_rings + sage: D.parent() # optional - sage.rings.finite_rings Full MatrixSpace of 6 by 12 dense matrices over Finite Field of size 23 - sage: E = C.tensor_product(B) + sage: E = C.tensor_product(B) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Finite Field of size 29' and 'Full MatrixSpace of 3 by 4 dense matrices over Finite Field of size 23' + TypeError: unsupported operand parent(s) for *: + 'Finite Field of size 29' and + 'Full MatrixSpace of 3 by 4 dense matrices over Finite Field of size 23' The input is checked to be sure it is a matrix. :: @@ -9235,9 +9320,9 @@ cdef class Matrix(Matrix1): sage: m2.tensor_product(m3).dimensions() (0, 6) - sage: m1 = MatrixSpace(GF(5), 3, 2).an_element() - sage: m2 = MatrixSpace(GF(5), 0, 4).an_element() - sage: m1.tensor_product(m2).parent() + sage: m1 = MatrixSpace(GF(5), 3, 2).an_element() # optional - sage.rings.finite_rings + sage: m2 = MatrixSpace(GF(5), 0, 4).an_element() # optional - sage.rings.finite_rings + sage: m1.tensor_product(m2).parent() # optional - sage.rings.finite_rings Full MatrixSpace of 0 by 8 dense matrices over Finite Field of size 5 """ if not isinstance(A, Matrix): @@ -9361,22 +9446,22 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: m = matrix(QQ,2,2,range(4)) + sage: m = matrix(QQ, 2,2, range(4)) sage: m.is_one() False - sage: m = matrix(QQ,2,[5,0,0,5]) + sage: m = matrix(QQ, 2, [5,0,0,5]) sage: m.is_one() False - sage: m = matrix(QQ,2,[1,0,0,1]) + sage: m = matrix(QQ, 2, [1,0,0,1]) sage: m.is_one() True - sage: m = matrix(QQ,2,[1,1,1,1]) + sage: m = matrix(QQ, 2, [1,1,1,1]) sage: m.is_one() False """ return self.is_scalar(self.base_ring().one()) - def is_scalar(self, a = None): + def is_scalar(self, a=None): """ Return True if this matrix is a scalar matrix. @@ -9392,16 +9477,16 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: m = matrix(QQ,2,2,range(4)) + sage: m = matrix(QQ, 2,2, range(4)) sage: m.is_scalar(5) False - sage: m = matrix(QQ,2,[5,0,0,5]) + sage: m = matrix(QQ, 2, [5,0,0,5]) sage: m.is_scalar(5) True - sage: m = matrix(QQ,2,[1,0,0,1]) + sage: m = matrix(QQ, 2, [1,0,0,1]) sage: m.is_scalar(1) True - sage: m = matrix(QQ,2,[1,1,1,1]) + sage: m = matrix(QQ, 2, [1,1,1,1]) sage: m.is_scalar(1) False """ @@ -9434,16 +9519,16 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: m = matrix(QQ,2,2,range(4)) + sage: m = matrix(QQ, 2,2, range(4)) sage: m.is_diagonal() False - sage: m = matrix(QQ,2,[5,0,0,5]) + sage: m = matrix(QQ, 2, [5,0,0,5]) sage: m.is_diagonal() True - sage: m = matrix(QQ,2,[1,0,0,1]) + sage: m = matrix(QQ, 2, [1,0,0,1]) sage: m.is_diagonal() True - sage: m = matrix(QQ,2,[1,1,1,1]) + sage: m = matrix(QQ, 2, [1,1,1,1]) sage: m.is_diagonal() False """ @@ -9520,26 +9605,27 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQbar, [[(1/sqrt(5))*(1+i), (1/sqrt(55))*(3+2*I), (1/sqrt(22))*(2+2*I)], - ....: [(1/sqrt(5))*(1-i), (1/sqrt(55))*(2+2*I), (1/sqrt(22))*(-3+I)], - ....: [ (1/sqrt(5))*I, (1/sqrt(55))*(3-5*I), (1/sqrt(22))*(-2)]]) - sage: A.is_unitary() + sage: A = matrix(QQbar, # optional - sage.symbolic sage.rings.number_field + ....: [[(1/sqrt(5))*(1+i), (1/sqrt(55))*(3+2*I), (1/sqrt(22))*(2+2*I)], + ....: [(1/sqrt(5))*(1-i), (1/sqrt(55))*(2+2*I), (1/sqrt(22))*(-3+I)], + ....: [ (1/sqrt(5))*I, (1/sqrt(55))*(3-5*I), (1/sqrt(22))*(-2)]]) + sage: A.is_unitary() # optional - sage.symbolic sage.rings.number_field True A permutation matrix is always orthogonal. :: - sage: sigma = Permutation([1,3,4,5,2]) - sage: P = sigma.to_matrix(); P + sage: sigma = Permutation([1,3,4,5,2]) # optional - sage.combinat + sage: P = sigma.to_matrix(); P # optional - sage.combinat [1 0 0 0 0] [0 0 0 0 1] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] - sage: P.is_unitary() + sage: P.is_unitary() # optional - sage.combinat True - sage: P.change_ring(GF(3)).is_unitary() + sage: P.change_ring(GF(3)).is_unitary() # optional - sage.combinat sage.rings.finite_rings True - sage: P.change_ring(GF(3)).is_unitary() + sage: P.change_ring(GF(3)).is_unitary() # optional - sage.combinat sage.rings.finite_rings True A square matrix far from unitary. :: @@ -9550,7 +9636,7 @@ cdef class Matrix(Matrix1): Rectangular matrices are never unitary. :: - sage: A = matrix(QQbar, 3, 4) + sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field sage: A.is_unitary() False """ @@ -9674,30 +9760,30 @@ cdef class Matrix(Matrix1): Sage has several fields besides the entire complex numbers where conjugation is non-trivial. :: - sage: F. = QuadraticField(-7) - sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], + sage: F. = QuadraticField(-7) # optional - sage.rings.number_field + sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], # optional - sage.rings.number_field ....: [-2*b - 3, -3*b + 2, -2*b], ....: [ b + 1, 0, -2]]) - sage: C = C*C.conjugate_transpose() - sage: C.is_normal() + sage: C = C*C.conjugate_transpose() # optional - sage.rings.number_field + sage: C.is_normal() # optional - sage.rings.number_field True A matrix that is nearly normal, but for a non-real diagonal entry. :: - sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], + sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], # optional - sage.rings.number_field ....: [ 2+I, 3+I, 2-6*I], ....: [1-4*I, 2+6*I, 5]]) - sage: A.is_normal() + sage: A.is_normal() # optional - sage.rings.number_field False - sage: A[1,1] = 132 - sage: A.is_normal() + sage: A[1,1] = 132 # optional - sage.rings.number_field + sage: A.is_normal() # optional - sage.rings.number_field True Rectangular matrices are never normal. :: - sage: A = matrix(QQbar, 3, 4) - sage: A.is_normal() + sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field + sage: A.is_normal() # optional - sage.rings.number_field False A square, empty matrix is trivially normal. :: @@ -9762,19 +9848,20 @@ cdef class Matrix(Matrix1): try to deduce the decomposition from the matrix :: sage: L = [] - sage: L.append((9,Permutation([4, 1, 3, 5, 2]))) - sage: L.append((6,Permutation([5, 3, 4, 1, 2]))) - sage: L.append((3,Permutation([3, 1, 4, 2, 5]))) - sage: L.append((2,Permutation([1, 4, 2, 3, 5]))) - sage: M = sum([c * p.to_matrix() for (c,p) in L]) - sage: decomp = sage.combinat.permutation.bistochastic_as_sum_of_permutations(M) - sage: print(decomp) + sage: L.append((9, Permutation([4, 1, 3, 5, 2]))) # optional - sage.combinat + sage: L.append((6, Permutation([5, 3, 4, 1, 2]))) # optional - sage.combinat + sage: L.append((3, Permutation([3, 1, 4, 2, 5]))) # optional - sage.combinat + sage: L.append((2, Permutation([1, 4, 2, 3, 5]))) # optional - sage.combinat + sage: M = sum([c * p.to_matrix() for c, p in L]) # optional - sage.combinat + sage: from sage.combinat.permutation import bistochastic_as_sum_of_permutations # optional - sage.combinat + sage: decomp = bistochastic_as_sum_of_permutations(M) # optional - sage.combinat + sage: print(decomp) # optional - sage.combinat 2*B[[1, 4, 2, 3, 5]] + 3*B[[3, 1, 4, 2, 5]] + 9*B[[4, 1, 3, 5, 2]] + 6*B[[5, 3, 4, 1, 2]] An exception is raised when the matrix is not bistochastic:: sage: M = Matrix([[2,3],[2,2]]) - sage: decomp = sage.combinat.permutation.bistochastic_as_sum_of_permutations(M) + sage: decomp = bistochastic_as_sum_of_permutations(M) # optional - sage.combinat Traceback (most recent call last): ... ValueError: The matrix is not bistochastic @@ -9829,7 +9916,7 @@ cdef class Matrix(Matrix1): Test :trac:`17341`:: - sage: random_matrix(GF(2), 8, 586, sparse=True).visualize_structure() + sage: random_matrix(GF(2), 8, 586, sparse=True).visualize_structure() # optional - sage.rings.finite_rings 512x6px 24-bit RGB image """ cdef Py_ssize_t x, y, _x, _y, v, bi, bisq @@ -9881,13 +9968,13 @@ cdef class Matrix(Matrix1): :: - sage: A = random_matrix(GF(127),200,200,density=0.3) - sage: A.density() <= 0.3 + sage: A = random_matrix(GF(127), 200, 200, density=0.3) # optional - sage.rings.finite_rings + sage: A.density() <= 0.3 # optional - sage.rings.finite_rings True :: - sage: A = matrix(QQ,3,3,[0,1,2,3,0,0,6,7,8]) + sage: A = matrix(QQ, 3,3, [0,1,2,3,0,0,6,7,8]) sage: A.density() 2/3 @@ -9953,9 +10040,9 @@ cdef class Matrix(Matrix1): Test :trac:`27473`:: - sage: F. = LaurentSeriesRing(GF(2)) - sage: M = Matrix([[t,1],[0,t]]) - sage: ~M + sage: F. = LaurentSeriesRing(GF(2)) # optional - sage.rings.finite_rings + sage: M = Matrix([[t,1], [0,t]]) # optional - sage.rings.finite_rings + sage: ~M # optional - sage.rings.finite_rings [t^-1 t^-2] [ 0 t^-1] @@ -9974,10 +10061,10 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = Matrix(ZZ,2,2,[5,2,3,4]) ; M + sage: M = Matrix(ZZ, 2, 2, [5,2,3,4]); M [5 2] [3 4] - sage: N = M.adjugate() ; N + sage: N = M.adjugate(); N [ 4 -2] [-3 5] sage: M * N @@ -9986,25 +10073,25 @@ cdef class Matrix(Matrix1): sage: N * M [14 0] [ 0 14] - sage: M = Matrix(QQ,2,2,[5/3,2/56,33/13,41/10]) ; M + sage: M = Matrix(QQ, 2, 2, [5/3,2/56, 33/13,41/10]); M [ 5/3 1/28] [33/13 41/10] - sage: N = M.adjugate() ; N + sage: N = M.adjugate(); N # optional - sage.libs.pari [ 41/10 -1/28] [-33/13 5/3] - sage: M * N + sage: M * N # optional - sage.libs.pari [7363/1092 0] [ 0 7363/1092] An alias is :meth:`adjoint_classical`, which replaces the deprecated :meth:`adjoint` method:: - sage: M.adjoint() + sage: M.adjoint() # optional - sage.libs.pari ...: DeprecationWarning: adjoint is deprecated. Please use adjugate instead. See https://github.com/sagemath/sage/issues/10501 for details. [ 41/10 -1/28] [-33/13 5/3] - sage: M.adjoint_classical() + sage: M.adjoint_classical() # optional - sage.libs.pari [ 41/10 -1/28] [-33/13 5/3] @@ -10073,19 +10160,19 @@ cdef class Matrix(Matrix1): not an integral domain:: sage: R. = QQ[] - sage: S. = R.quo((b^3)) - sage: A = matrix(S, [[x*y^2,2*x],[2,x^10*y]]) - sage: A + sage: S. = R.quo((b^3)) # optional - sage.libs.singular + sage: A = matrix(S, [[x*y^2, 2*x], [2, x^10*y]]) # optional - sage.libs.singular + sage: A # optional - sage.libs.singular [ x*y^2 2*x] [ 2 x^10*y] - sage: A.det() + sage: A.det() # optional - sage.libs.singular -4*x - sage: A.charpoly('T') + sage: A.charpoly('T') # optional - sage.libs.singular T^2 + (-x^10*y - x*y^2)*T - 4*x - sage: A.adjugate() + sage: A.adjugate() # optional - sage.libs.singular [x^10*y -2*x] [ -2 x*y^2] - sage: A.adjugate() * A + sage: A.adjugate() * A # optional - sage.libs.singular [-4*x 0] [ 0 -4*x] @@ -10108,8 +10195,8 @@ cdef class Matrix(Matrix1): presence of non-integral powers of the variable `x` (:trac:`14403`):: - sage: x = var('x') - sage: Matrix([[sqrt(x),x],[1,0]]).adjugate() + sage: x = var('x') # optional - sage.symbolic + sage: Matrix([[sqrt(x),x], [1,0]]).adjugate() # optional - sage.symbolic [ 0 -x] [ -1 sqrt(x)] @@ -10184,58 +10271,58 @@ cdef class Matrix(Matrix1): For a nonsingular matrix, the QR decomposition is unique. :: - sage: A = matrix(QQbar, [[-2, 0, -4, -1, -1], + sage: A = matrix(QQbar, [[-2, 0, -4, -1, -1], # optional - sage.rings.number_field ....: [-2, 1, -6, -3, -1], ....: [1, 1, 7, 4, 5], ....: [3, 0, 8, 3, 3], ....: [-1, 1, -6, -6, 5]]) - sage: Q, R = A.QR() - sage: Q + sage: Q, R = A.QR() # optional - sage.rings.number_field + sage: Q # optional - sage.rings.number_field [ -0.4588314677411235? -0.1260506983326509? 0.3812120831224489? -0.394573711338418? -0.6874400625964?] [ -0.4588314677411235? 0.4726901187474409? -0.05198346588033394? 0.7172941251646595? -0.2209628772631?] [ 0.2294157338705618? 0.6617661662464172? 0.6619227988762521? -0.1808720937375480? 0.1964114464561?] [ 0.6882472016116853? 0.1890760474989764? -0.2044682991293135? 0.0966302966543065? -0.6628886317894?] [ -0.2294157338705618? 0.5357154679137663? -0.609939332995919? -0.536422031427112? 0.0245514308070?] - sage: R + sage: R # optional - sage.rings.number_field [ 4.358898943540674? -0.4588314677411235? 13.07669683062202? 6.194224814505168? 2.982404540317303?] [ 0 1.670171752907625? 0.5987408170800917? -1.292019657909672? 6.207996892883057?] [ 0 0 5.444401659866974? 5.468660610611130? -0.6827161852283857?] [ 0 0 0 1.027626039419836? -3.619300149686620?] [ 0 0 0 0 0.024551430807012?] - sage: Q.conjugate_transpose()*Q + sage: Q.conjugate_transpose()*Q # optional - sage.rings.number_field [1.000000000000000? 0.?e-18 0.?e-17 0.?e-16 0.?e-13] [ 0.?e-18 1.000000000000000? 0.?e-17 0.?e-16 0.?e-13] [ 0.?e-17 0.?e-17 1.000000000000000? 0.?e-16 0.?e-13] [ 0.?e-16 0.?e-16 0.?e-16 1.000000000000000? 0.?e-13] [ 0.?e-13 0.?e-13 0.?e-13 0.?e-13 1.0000000000000?] - sage: Q*R == A + sage: Q * R == A # optional - sage.rings.number_field True An example with complex numbers in ``QQbar``, the field of algebraic numbers. :: - sage: A = matrix(QQbar, [[-8, 4*I + 1, -I + 2, 2*I + 1], + sage: A = matrix(QQbar, [[-8, 4*I + 1, -I + 2, 2*I + 1], # optional - sage.rings.number_field ....: [1, -2*I - 1, -I + 3, -I + 1], ....: [I + 7, 2*I + 1, -2*I + 7, -I + 1], ....: [I + 2, 0, I + 12, -1]]) - sage: Q, R = A.QR() - sage: Q + sage: Q, R = A.QR() # optional - sage.rings.number_field + sage: Q # optional - sage.rings.number_field [ -0.7302967433402215? 0.2070566455055649? + 0.5383472783144687?*I 0.2463049809998642? - 0.0764456358723292?*I 0.2381617683194332? - 0.1036596032779695?*I] [ 0.0912870929175277? -0.2070566455055649? - 0.3778783780476559?*I 0.3786559533863033? - 0.1952221495524667?*I 0.701244450214469? - 0.3643711650986595?*I] [ 0.6390096504226938? + 0.0912870929175277?*I 0.1708217325420910? + 0.6677576817554466?*I -0.03411475806452072? + 0.04090198741767143?*I 0.3140171085506764? - 0.0825191718705412?*I] [ 0.1825741858350554? + 0.0912870929175277?*I -0.03623491296347385? + 0.0724698259269477?*I 0.8632284069415110? + 0.06322839976356195?*I -0.4499694867611521? - 0.0116119181208918?*I] - sage: R + sage: R # optional - sage.rings.number_field [ 10.95445115010333? 0.?e-18 - 1.917028951268082?*I 5.385938482134133? - 2.190890230020665?*I -0.2738612787525831? - 2.190890230020665?*I] [ 0 4.829596256417300? + 0.?e-18*I -0.869637911123373? - 5.864879483945125?*I 0.993871898426712? - 0.3054085521207082?*I] [ 0 0 12.00160760935814? + 0.?e-16*I -0.2709533402297273? + 0.4420629644486323?*I] [ 0 0 0 1.942963944258992? + 0.?e-16*I] - sage: Q.conjugate_transpose()*Q + sage: Q.conjugate_transpose()*Q # optional - sage.rings.number_field [1.000000000000000? + 0.?e-19*I 0.?e-18 + 0.?e-17*I 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I] [ 0.?e-18 + 0.?e-17*I 1.000000000000000? + 0.?e-17*I 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I] [ 0.?e-17 + 0.?e-17*I 0.?e-17 + 0.?e-17*I 1.000000000000000? + 0.?e-17*I 0.?e-16 + 0.?e-16*I] [ 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I 1.000000000000000? + 0.?e-16*I] - sage: Q*R - A + sage: Q*R - A # optional - sage.rings.number_field [ 0.?e-17 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I] [ 0.?e-18 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I] [0.?e-17 + 0.?e-18*I 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I] @@ -10243,58 +10330,58 @@ cdef class Matrix(Matrix1): A rank-deficient rectangular matrix, with both values of the ``full`` keyword. :: - sage: A = matrix(QQbar, [[2, -3, 3], + sage: A = matrix(QQbar, [[2, -3, 3], # optional - sage.rings.number_field ....: [-1, 1, -1], ....: [-1, 3, -3], ....: [-5, 1, -1]]) - sage: Q, R = A.QR() - sage: Q + sage: Q, R = A.QR() # optional - sage.rings.number_field + sage: Q # optional - sage.rings.number_field [ 0.3592106040535498? -0.5693261797050169? 0.7239227659930268? 0.1509015305256380?] [ -0.1796053020267749? 0.1445907757980996? 0 0.9730546968377341?] [ -0.1796053020267749? 0.7048800320157352? 0.672213996993525? -0.1378927778941174?] [ -0.8980265101338745? -0.3976246334447737? 0.1551263069985058? -0.10667177157846818?] - sage: R + sage: R # optional - sage.rings.number_field [ 5.567764362830022? -2.694079530401624? 2.694079530401624?] [ 0 3.569584777515583? -3.569584777515583?] [ 0 0 0] [ 0 0 0] - sage: Q.conjugate_transpose()*Q + sage: Q.conjugate_transpose() * Q # optional - sage.rings.number_field [ 1 0.?e-18 0.?e-18 0.?e-18] [ 0.?e-18 1 0.?e-18 0.?e-18] [ 0.?e-18 0.?e-18 1.000000000000000? 0.?e-18] [ 0.?e-18 0.?e-18 0.?e-18 1.000000000000000?] - sage: Q, R = A.QR(full=False) - sage: Q + sage: Q, R = A.QR(full=False) # optional - sage.rings.number_field + sage: Q # optional - sage.rings.number_field [ 0.3592106040535498? -0.5693261797050169?] [-0.1796053020267749? 0.1445907757980996?] [-0.1796053020267749? 0.7048800320157352?] [-0.8980265101338745? -0.3976246334447737?] - sage: R + sage: R # optional - sage.rings.number_field [ 5.567764362830022? -2.694079530401624? 2.694079530401624?] [ 0 3.569584777515583? -3.569584777515583?] - sage: Q.conjugate_transpose()*Q + sage: Q.conjugate_transpose()*Q # optional - sage.rings.number_field [ 1 0.?e-18] [0.?e-18 1] Another rank-deficient rectangular matrix, with complex entries, as a reduced decomposition. :: - sage: A = matrix(QQbar, [[-3*I - 3, I - 3, -12*I + 1, -2], + sage: A = matrix(QQbar, [[-3*I - 3, I - 3, -12*I + 1, -2], # optional - sage.rings.number_field ....: [-I - 1, -2, 5*I - 1, -I - 2], ....: [-4*I - 4, I - 5, -7*I, -I - 4]]) - sage: Q, R = A.QR(full=False) - sage: Q + sage: Q, R = A.QR(full=False) # optional - sage.rings.number_field + sage: Q # optional - sage.rings.number_field [ -0.4160251471689219? - 0.4160251471689219?*I 0.5370861555295747? + 0.1790287185098583?*I] [ -0.1386750490563073? - 0.1386750490563073?*I -0.7519206177414046? - 0.2506402059138015?*I] [ -0.5547001962252291? - 0.5547001962252291?*I -0.2148344622118299? - 0.07161148740394329?*I] - sage: R + sage: R # optional - sage.rings.number_field [ 7.211102550927979? 3.328201177351375? - 5.269651864139676?*I 7.904477796209515? + 8.45917799243475?*I 4.021576422632911? - 2.634825932069838?*I] [ 0 1.074172311059150? -1.611258466588724? - 9.13046464400277?*I 1.611258466588724? + 0.5370861555295747?*I] - sage: Q.conjugate_transpose()*Q + sage: Q.conjugate_transpose()*Q # optional - sage.rings.number_field [1 0] [0 1] - sage: Q*R-A + sage: Q*R - A # optional - sage.rings.number_field [0 0 0 0] [0 0 0 0] [0 0 0 0] @@ -10302,29 +10389,29 @@ cdef class Matrix(Matrix1): Results of full decompositions are cached and thus returned immutable. :: - sage: A = random_matrix(QQbar, 2, 2) - sage: Q, R = A.QR() - sage: Q.is_mutable() + sage: A = random_matrix(QQbar, 2, 2) # optional - sage.rings.number_field + sage: Q, R = A.QR() # optional - sage.rings.number_field + sage: Q.is_mutable() # optional - sage.rings.number_field False - sage: R.is_mutable() + sage: R.is_mutable() # optional - sage.rings.number_field False Trivial cases return trivial results of the correct size, and we check `Q` itself in one case. :: - sage: A = zero_matrix(QQbar, 0, 10) - sage: Q, R = A.QR() - sage: Q.nrows(), Q.ncols() + sage: A = zero_matrix(QQbar, 0, 10) # optional - sage.rings.number_field + sage: Q, R = A.QR() # optional - sage.rings.number_field + sage: Q.nrows(), Q.ncols() # optional - sage.rings.number_field (0, 0) - sage: R.nrows(), R.ncols() + sage: R.nrows(), R.ncols() # optional - sage.rings.number_field (0, 10) - sage: A = zero_matrix(QQbar, 3, 0) - sage: Q, R = A.QR() - sage: Q.nrows(), Q.ncols() + sage: A = zero_matrix(QQbar, 3, 0) # optional - sage.rings.number_field + sage: Q, R = A.QR() # optional - sage.rings.number_field + sage: Q.nrows(), Q.ncols() # optional - sage.rings.number_field (3, 3) - sage: R.nrows(), R.ncols() + sage: R.nrows(), R.ncols() # optional - sage.rings.number_field (3, 0) - sage: Q + sage: Q # optional - sage.rings.number_field [1 0 0] [0 1 0] [0 0 1] @@ -10481,32 +10568,32 @@ cdef class Matrix(Matrix1): so we need to check with the conjugate-transpose. This example verifies that the bug on :trac:`10791` is fixed. :: - sage: F. = QuadraticField(-5) - sage: A = matrix(F, [[ 1, a - 3, a - 2, a + 1], + sage: F. = QuadraticField(-5) # optional - sage.rings.number_field + sage: A = matrix(F, [[ 1, a - 3, a - 2, a + 1], # optional - sage.rings.number_field ....: [ a, 2*a + 1, 3*a + 1, 1], ....: [a + 1, a - 6, 2*a - 5, 1], ....: [ 2*a, a, 3*a, -3], ....: [ 1, a - 1, a, a - 1]]) - sage: A.rank() + sage: A.rank() # optional - sage.rings.number_field 3 - sage: Q, R = A._gram_schmidt_noscale() - sage: Q + sage: Q, R = A._gram_schmidt_noscale() # optional - sage.rings.number_field + sage: Q # optional - sage.rings.number_field [ 1 25/33*a - 38/11 641/1163*a + 453/1163] [ a 17/11*a + 73/33 322/1163*a + 1566/1163] [ a + 1 10/33*a - 173/33 -784/1163*a + 1614/1163] [ 2*a 1/11*a + 80/33 196/1163*a - 1234/1163] [ 1 25/33*a - 16/11 855/1163*a - 1717/1163] - sage: R + sage: R # optional - sage.rings.number_field [ 1 8/33*a + 5/11 8/33*a + 16/11 2/11*a + 1/33] [ 0 1 1 -107/1163*a - 78/1163] [ 0 0 0 1] - sage: Q*R == A + sage: Q*R == A # optional - sage.rings.number_field True - sage: Q.transpose().conjugate()*Q + sage: Q.transpose().conjugate()*Q # optional - sage.rings.number_field [ 33 0 0] [ 0 2326/33 0] [ 0 0 16532/1163] - sage: Q.column_space() == A.column_space() + sage: Q.column_space() == A.column_space() # optional - sage.rings.number_field True Some trivial cases. :: @@ -10698,47 +10785,47 @@ cdef class Matrix(Matrix1): for small cases or instruction. Now we need to use the ``orthonormal`` keyword. :: - sage: A = matrix(QQbar, [[6, -8, 1], + sage: A = matrix(QQbar, [[6, -8, 1], # optional - sage.rings.number_field ....: [4, 1, 3], ....: [6, 3, 3], ....: [7, 1, -5], ....: [7, -3, 5]]) - sage: G, M = A.gram_schmidt(orthonormal=True) - sage: G + sage: G, M = A.gram_schmidt(orthonormal=True) # optional - sage.rings.number_field + sage: G # optional - sage.rings.number_field [ 0.5970223141259934? -0.7960297521679913? 0.09950371902099891?] [ 0.6063218341690895? 0.5289635311888953? 0.5937772444966257?] [ 0.5252981913594170? 0.2941669871612735? -0.798453250866314?] - sage: M + sage: M # optional - sage.rings.number_field [ 10.04987562112089? 0 0] [ 1.890570661398980? 4.735582601355131? 0] [ 1.492555785314984? 7.006153332071100? 1.638930357041381?] [ 2.885607851608969? 1.804330147889395? 7.963520581008761?] [ 7.064764050490923? 5.626248468100069? -1.197679876299471?] - sage: M*G-A + sage: M*G - A # optional - sage.rings.number_field [0 0 0] [0 0 0] [0 0 0] [0 0 0] [0 0 0] - sage: (G*G.transpose()-identity_matrix(3)).norm() < 10^-10 + sage: (G*G.transpose() - identity_matrix(3)).norm() < 10^-10 # optional - sage.rings.number_field True - sage: G.row_space() == A.row_space() + sage: G.row_space() == A.row_space() # optional - sage.rings.number_field True After :trac:`14047`, the matrix can also be over the algebraic reals ``AA``:: - sage: A = matrix(AA, [[6, -8, 1], + sage: A = matrix(AA, [[6, -8, 1], # optional - sage.rings.number_field ....: [4, 1, 3], ....: [6, 3, 3], ....: [7, 1, -5], ....: [7, -3, 5]]) - sage: G, M = A.gram_schmidt(orthonormal=True) - sage: G + sage: G, M = A.gram_schmidt(orthonormal=True) # optional - sage.rings.number_field + sage: G # optional - sage.rings.number_field [ 0.5970223141259934? -0.7960297521679913? 0.09950371902099891?] [ 0.6063218341690895? 0.5289635311888953? 0.5937772444966257?] [ 0.5252981913594170? 0.2941669871612735? -0.798453250866314?] - sage: M + sage: M # optional - sage.rings.number_field [ 10.04987562112089? 0 0] [ 1.890570661398980? 4.735582601355131? 0] [ 1.492555785314984? 7.006153332071100? 1.638930357041381?] @@ -10749,45 +10836,45 @@ cdef class Matrix(Matrix1): Note the use of the conjugate-transpose when checking the orthonormality. :: - sage: A = matrix(QQbar, [[ -2, -I - 1, 4*I + 2, -1], + sage: A = matrix(QQbar, [[ -2, -I - 1, 4*I + 2, -1], # optional - sage.rings.number_field ....: [-4*I, -2*I + 17, 0, 9*I + 1], ....: [ 1, -2*I - 6, -I + 11, -5*I + 1]]) - sage: G, M = A.gram_schmidt(orthonormal=True) - sage: (M*G-A).norm() < 10^-10 + sage: G, M = A.gram_schmidt(orthonormal=True) # optional - sage.rings.number_field + sage: (M*G - A).norm() < 10^-10 # optional - sage.rings.number_field True - sage: id3 = G*G.conjugate().transpose() - sage: (id3 - identity_matrix(3)).norm() < 10^-10 + sage: id3 = G*G.conjugate().transpose() # optional - sage.rings.number_field + sage: (id3 - identity_matrix(3)).norm() < 10^-10 # optional - sage.rings.number_field True - sage: G.row_space() == A.row_space() # long time + sage: G.row_space() == A.row_space() # long time # optional - sage.rings.number_field True A square matrix with small rank. The zero vectors produced as a result of linear dependence get eliminated, so the rows of ``G`` are a basis for the row space of ``A``. :: - sage: A = matrix(QQbar, [[2, -6, 3, 8], + sage: A = matrix(QQbar, [[2, -6, 3, 8], # optional - sage.rings.number_field ....: [1, -3, 2, 5], ....: [0, 0, 2, 4], ....: [2, -6, 3, 8]]) - sage: A.change_ring(QQ).rank() + sage: A.change_ring(QQ).rank() # optional - sage.rings.number_field 2 - sage: G, M = A.gram_schmidt(orthonormal=True) - sage: G + sage: G, M = A.gram_schmidt(orthonormal=True) # optional - sage.rings.number_field + sage: G # optional - sage.rings.number_field [ 0.1881441736767195? -0.5644325210301583? 0.2822162605150792? 0.7525766947068779?] [-0.2502818123591464? 0.750845437077439? 0.3688363550555841? 0.4873908977520218?] - sage: M + sage: M # optional - sage.rings.number_field [10.630145812734649? 0] [ 6.208757731331742? 0.6718090752798139?] [ 3.574739299857670? 2.687236301119256?] [10.630145812734649? 0] - sage: M*G-A + sage: M*G - A # optional - sage.rings.number_field [0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0] - sage: (G*G.transpose()-identity_matrix(2)).norm() < 10^-10 + sage: (G*G.transpose() - identity_matrix(2)).norm() < 10^-10 # optional - sage.rings.number_field True - sage: G.row_space() == A.row_space() + sage: G.row_space() == A.row_space() # optional - sage.rings.number_field True Exact Rings, Orthogonalization: @@ -10831,28 +10918,28 @@ cdef class Matrix(Matrix1): A complex subfield of the complex numbers. :: - sage: C. = CyclotomicField(5) + sage: C. = CyclotomicField(5) # optional - sage.rings.number_field sage: A = matrix(C, [[ -z^3 - 2*z, -z^3 - 1, 2*z^3 - 2*z^2 + 2*z, 1], ....: [ z^3 - 2*z^2 + 1, -z^3 + 2*z^2 - z - 1, -1, z^2 + z], ....: [-1/2*z^3 - 2*z^2 + z + 1, -z^3 + z - 2, -2*z^3 + 1/2*z^2, 2*z^2 - z + 2]]) - sage: G, M = A.gram_schmidt(orthonormal=False) - sage: G + sage: G, M = A.gram_schmidt(orthonormal=False) # optional - sage.rings.number_field + sage: G # optional - sage.rings.number_field [ -z^3 - 2*z -z^3 - 1 2*z^3 - 2*z^2 + 2*z 1] [ 155/139*z^3 - 161/139*z^2 + 31/139*z + 13/139 -175/139*z^3 + 180/139*z^2 - 125/139*z - 142/139 230/139*z^3 + 124/139*z^2 + 6/139*z + 19/139 -14/139*z^3 + 92/139*z^2 - 6/139*z - 95/139] [-10359/19841*z^3 - 36739/39682*z^2 + 24961/39682*z - 11879/39682 -28209/39682*z^3 - 3671/19841*z^2 + 51549/39682*z - 38613/39682 -42769/39682*z^3 - 615/39682*z^2 - 1252/19841*z - 14392/19841 4895/19841*z^3 + 57885/39682*z^2 - 46094/19841*z + 65747/39682] - sage: M + sage: M # optional - sage.rings.number_field [ 1 0 0] [ 14/139*z^3 + 47/139*z^2 + 145/139*z + 95/139 1 0] [ -7/278*z^3 + 199/278*z^2 + 183/139*z + 175/278 -3785/39682*z^3 + 3346/19841*z^2 - 3990/19841*z + 2039/19841 1] - sage: M*G - A + sage: M*G - A # optional - sage.rings.number_field [0 0 0 0] [0 0 0 0] [0 0 0 0] - sage: G*G.conjugate().transpose() + sage: G*G.conjugate().transpose() # optional - sage.rings.number_field [ 15*z^3 + 15*z^2 + 28 0 0] [ 0 463/139*z^3 + 463/139*z^2 + 1971/139 0] [ 0 0 230983/19841*z^3 + 230983/19841*z^2 + 1003433/39682] - sage: G.row_space() == A.row_space() + sage: G.row_space() == A.row_space() # optional - sage.rings.number_field True A slightly edited legacy example. :: @@ -10962,27 +11049,27 @@ cdef class Matrix(Matrix1): [ 0 1 0 0] [ 1 -1 1 0] [ 1 -1 1 2] - sage: a.jordan_form() + sage: a.jordan_form() # optional - sage.combinat [2|0 0|0] [-+---+-] [0|1 1|0] [0|0 1|0] [-+---+-] [0|0 0|1] - sage: a.jordan_form(subdivide=False) + sage: a.jordan_form(subdivide=False) # optional - sage.combinat [2 0 0 0] [0 1 1 0] [0 0 1 0] [0 0 0 1] - sage: b = matrix(ZZ,3,3,range(9)); b + sage: b = matrix(ZZ,3,3,range(9)); b # optional - sage.combinat [0 1 2] [3 4 5] [6 7 8] - sage: b.jordan_form() + sage: b.jordan_form() # optional - sage.combinat Traceback (most recent call last): ... RuntimeError: Some eigenvalue does not exist in Rational Field. - sage: b.jordan_form(RealField(15)) + sage: b.jordan_form(RealField(15)) # optional - sage.combinat Traceback (most recent call last): ... ValueError: Jordan normal form not implemented over inexact rings. @@ -10990,8 +11077,8 @@ cdef class Matrix(Matrix1): Here we need to specify a field, since the eigenvalues are not defined in the smallest ring containing the matrix entries (:trac:`14508`):: - sage: c = matrix([[0,1,0],[0,0,1],[1,0,0]]) - sage: c.jordan_form(CyclotomicField(3)) + sage: c = matrix([[0,1,0], [0,0,1], [1,0,0]]) + sage: c.jordan_form(CyclotomicField(3)) # optional - sage.combinat sage.rings.number_field [ 1| 0| 0] [----------+----------+----------] [ 0| zeta3| 0] @@ -11001,20 +11088,20 @@ cdef class Matrix(Matrix1): If you need the transformation matrix as well as the Jordan form of ``self``, then pass the option ``transformation=True``. For example:: - sage: m = matrix([[5,4,2,1],[0,1,-1,-1],[-1,-1,3,0],[1,1,-1,2]]); m + sage: m = matrix([[5,4,2,1], [0,1,-1,-1], [-1,-1,3,0], [1,1,-1,2]]); m [ 5 4 2 1] [ 0 1 -1 -1] [-1 -1 3 0] [ 1 1 -1 2] - sage: jf, p = m.jordan_form(transformation=True) - sage: jf + sage: jf, p = m.jordan_form(transformation=True) # optional - sage.combinat + sage: jf # optional - sage.combinat [2|0|0 0] [-+-+---] [0|1|0 0] [-+-+---] [0|0|4 1] [0|0|0 4] - sage: ~p * m * p + sage: ~p * m * p # optional - sage.combinat [2 0 0 0] [0 1 0 0] [0 0 4 1] @@ -11024,7 +11111,7 @@ cdef class Matrix(Matrix1): compute the Jordan normal form, since it is not numerically stable:: - sage: b = matrix(ZZ,3,3,range(9)) + sage: b = matrix(ZZ, 3, 3, range(9)) sage: jf, p = b.jordan_form(RealField(15), transformation=True) Traceback (most recent call last): ... @@ -11036,7 +11123,7 @@ cdef class Matrix(Matrix1): [1 1 1] [1 1 1] [1 1 1] - sage: c.jordan_form(subdivide=False) + sage: c.jordan_form(subdivide=False) # optional - sage.combinat [3 0 0] [0 0 0] [0 0 0] @@ -11049,19 +11136,21 @@ cdef class Matrix(Matrix1): sage: p = random_matrix(ZZ,n,n) sage: while p.rank() != n: p = random_matrix(ZZ,n,n) sage: m = p * jf * ~p - sage: mjf, mp = m.jordan_form(transformation=True) - sage: mjf == jf + sage: mjf, mp = m.jordan_form(transformation=True) # optional - sage.combinat + sage: mjf == jf # optional - sage.combinat True sage: m = diagonal_matrix([1,1,0,0]) - sage: jf,P = m.jordan_form(transformation=True) - sage: jf == ~P*m*P + sage: jf, P = m.jordan_form(transformation=True) # optional - sage.combinat + sage: jf == ~P*m*P # optional - sage.combinat True We verify that the bug from :trac:`6942` is fixed:: - sage: M = Matrix(GF(2),[[1,0,1,0,0,0,1],[1,0,0,1,1,1,0],[1,1,0,1,1,1,1],[1,1,1,0,1,1,1],[1,1,1,0,0,1,0],[1,1,1,0,1,0,0],[1,1,1,1,1,1,0]]) - sage: J, T = M.jordan_form(transformation=True) - sage: J + sage: M = Matrix(GF(2),[[1,0,1,0,0,0,1], [1,0,0,1,1,1,0], [1,1,0,1,1,1,1], # optional - sage.rings.finite_rings + ....: [1,1,1,0,1,1,1], [1,1,1,0,0,1,0], [1,1,1,0,1,0,0], + ....: [1,1,1,1,1,1,0]]) + sage: J, T = M.jordan_form(transformation=True) # optional - sage.combinat sage.rings.finite_rings + sage: J # optional - sage.combinat sage.rings.finite_rings [1 1|0 0|0 0|0] [0 1|0 0|0 0|0] [---+---+---+-] @@ -11072,17 +11161,17 @@ cdef class Matrix(Matrix1): [0 0|0 0|0 1|0] [---+---+---+-] [0 0|0 0|0 0|1] - sage: M * T == T * J + sage: M * T == T * J # optional - sage.combinat sage.rings.finite_rings True - sage: T.rank() + sage: T.rank() # optional - sage.combinat sage.rings.finite_rings 7 - sage: M.rank() + sage: M.rank() # optional - sage.combinat sage.rings.finite_rings 7 We verify that the bug from :trac:`6932` is fixed:: - sage: M=Matrix(1,1,[1]) - sage: M.jordan_form(transformation=True) + sage: M = Matrix(1, 1, [1]) # optional - sage.combinat + sage: M.jordan_form(transformation=True) # optional - sage.combinat ([1], [1]) We now go through three `10 \times 10` matrices to exhibit cases where @@ -11099,7 +11188,7 @@ cdef class Matrix(Matrix1): [ 20 26/3 -66 -199/3 -42 -41/3 0 13/3 -55/3 -2/3] [ 18 57 -9 -54 -57 0 0 0 -15 0] [ 0 0 0 0 0 0 0 0 0 3] - sage: J, T = A.jordan_form(transformation=True); J + sage: J, T = A.jordan_form(transformation=True); J # optional - sage.combinat [3 1 0|0 0 0|0 0 0|0] [0 3 1|0 0 0|0 0 0|0] [0 0 3|0 0 0|0 0 0|0] @@ -11113,9 +11202,9 @@ cdef class Matrix(Matrix1): [0 0 0|0 0 0|0 0 3|0] [-----+-----+-----+-] [0 0 0|0 0 0|0 0 0|3] - sage: T * J * T**(-1) == A + sage: T * J * T**(-1) == A # optional - sage.combinat True - sage: T.rank() + sage: T.rank() # optional - sage.combinat 10 :: @@ -11131,7 +11220,7 @@ cdef class Matrix(Matrix1): [ 20 26/3 -66 -28/3 -42 -41/3 0 13/3 2/3 82/3] [ 18 57 -9 0 -57 0 0 0 3 28] [ 0 0 0 0 0 0 0 0 0 3] - sage: J, T = A.jordan_form(transformation=True); J + sage: J, T = A.jordan_form(transformation=True); J # optional - sage.combinat [3 1 0|0 0 0|0 0|0 0] [0 3 1|0 0 0|0 0|0 0] [0 0 3|0 0 0|0 0|0 0] @@ -11145,9 +11234,9 @@ cdef class Matrix(Matrix1): [-----+-----+---+---] [0 0 0|0 0 0|0 0|3 1] [0 0 0|0 0 0|0 0|0 3] - sage: T * J * T**(-1) == A + sage: T * J * T**(-1) == A # optional - sage.combinat True - sage: T.rank() + sage: T.rank() # optional - sage.combinat 10 :: @@ -11163,7 +11252,7 @@ cdef class Matrix(Matrix1): [ 20 26/3 -30 -199/3 -42 -14/3 70 13/3 -55/3 -2/3] [ 18 57 -9 -54 -57 0 63 0 -15 0] [ 0 0 0 0 0 0 0 0 0 3] - sage: J, T = A.jordan_form(transformation=True); J + sage: J, T = A.jordan_form(transformation=True); J # optional - sage.combinat [3 1 0|0 0|0 0|0 0|0] [0 3 1|0 0|0 0|0 0|0] [0 0 3|0 0|0 0|0 0|0] @@ -11178,7 +11267,7 @@ cdef class Matrix(Matrix1): [0 0 0|0 0|0 0|0 3|0] [-----+---+---+---+-] [0 0 0|0 0|0 0|0 0|3] - sage: T * J * T**(-1) == A + sage: T * J * T**(-1) == A # optional - sage.combinat True sage: T.rank() 10 @@ -11186,9 +11275,9 @@ cdef class Matrix(Matrix1): Verify that we smoothly move to QQ from ZZ (:trac:`12693`), i.e. we work in the vector space over the field:: - sage: M = matrix(((2,2,2),(0,0,0),(-2,-2,-2))) - sage: J, P = M.jordan_form(transformation=True) - sage: J; P + sage: M = matrix(((2,2,2), (0,0,0), (-2,-2,-2))) + sage: J, P = M.jordan_form(transformation=True) # optional - sage.combinat + sage: J; P # optional - sage.combinat [0 1|0] [0 0|0] [---+-] @@ -11196,15 +11285,15 @@ cdef class Matrix(Matrix1): [ 2 1 0] [ 0 0 1] [-2 0 -1] - sage: J - ~P * M * P + sage: J - ~P * M * P # optional - sage.combinat [0 0 0] [0 0 0] [0 0 0] - sage: parent(M) + sage: parent(M) # optional - sage.combinat Full MatrixSpace of 3 by 3 dense matrices over Integer Ring - sage: parent(J) == parent(P) == MatrixSpace(QQ, 3) + sage: parent(J) == parent(P) == MatrixSpace(QQ, 3) # optional - sage.combinat True - sage: M.jordan_form(transformation=True) == (M/1).jordan_form(transformation=True) + sage: M.jordan_form(transformation=True) == (M/1).jordan_form(transformation=True) # optional - sage.combinat True By providing eigenvalues ourselves, we can compute the Jordan form even @@ -11213,16 +11302,16 @@ cdef class Matrix(Matrix1): sage: Qx = PolynomialRing(QQ, 'x11, x12, x13, x21, x22, x23, x31, x32, x33') sage: x11, x12, x13, x21, x22, x23, x31, x32, x33 = Qx.gens() sage: M = matrix(Qx, [[0, 0, x31], [0, 0, x21], [0, 0, 0]]) # This is a nilpotent matrix. - sage: M.jordan_form(eigenvalues=[(0, 3)]) + sage: M.jordan_form(eigenvalues=[(0, 3)]) # optional - sage.combinat [0 1|0] [0 0|0] [---+-] [0 0|0] - sage: M.jordan_form(eigenvalues=[(0, 2)]) + sage: M.jordan_form(eigenvalues=[(0, 2)]) # optional - sage.combinat Traceback (most recent call last): ... ValueError: The provided list of eigenvalues is not correct. - sage: M.jordan_form(transformation=True, eigenvalues=[(0, 3)]) + sage: M.jordan_form(transformation=True, eigenvalues=[(0, 3)]) # optional - sage.combinat ( [0 1|0] [0 0|0] [x31 0 1] @@ -11234,17 +11323,17 @@ cdef class Matrix(Matrix1): and it needs to be implemented. :: sage: A = matrix(Integers(6), 2, 2, range(4)) - sage: A.jordan_form() + sage: A.jordan_form() # optional - sage.combinat Traceback (most recent call last): ... ValueError: Matrix entries must be from a field, not Ring of integers modulo 6 Test for :trac:`10563`:: - sage: R = FractionField(PolynomialRing(RationalField(),'a')) + sage: R = FractionField(PolynomialRing(RationalField(), 'a')) sage: a = R.gen() - sage: A = matrix(R,[[1,a],[a,1]]) - sage: A.jordan_form() + sage: A = matrix(R, [[1,a], [a,1]]) # optional - sage.combinat + sage: A.jordan_form() # optional - sage.combinat [ a + 1| 0] [------+------] [ 0|-a + 1] @@ -11417,31 +11506,31 @@ cdef class Matrix(Matrix1): [-3 5 3 3] [ 3 -6 -4 -3] [-3 6 3 2] - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.libs.pari True - sage: A.diagonalization() + sage: A.diagonalization() # optional - sage.libs.pari ( [ 2 0 0 0] [ 1 1 0 0] [ 0 -1 0 0] [ 1 0 1 0] [ 0 0 -1 0] [-1 0 0 1] [ 0 0 0 -1], [ 1 1 -2 -1] ) - sage: D, P = A.diagonalization() - sage: P^-1*A*P == D + sage: D, P = A.diagonalization() # optional - sage.libs.pari + sage: P^-1*A*P == D # optional - sage.libs.pari True sage: A = matrix(QQ, 2, [0, 2, 1, 0]) - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.libs.pari False - sage: A.is_diagonalizable(QQbar) + sage: A.is_diagonalizable(QQbar) # optional - sage.libs.pari sage.rings.number_field True - sage: D, P = A.diagonalization(QQbar) - sage: P^-1*A*P == D + sage: D, P = A.diagonalization(QQbar) # optional - sage.libs.pari sage.rings.number_field + sage: P^-1*A*P == D # optional - sage.libs.pari sage.rings.number_field True Matrices may fail to be diagonalizable for various reasons:: - sage: A = matrix(QQ, 2, [1,2,3,4,5,6]) + sage: A = matrix(QQ, 2, [1,2,3, 4,5,6]) sage: A [1 2 3] [4 5 6] @@ -11568,9 +11657,9 @@ cdef class Matrix(Matrix1): ....: [ 9, -8, 11, -12, 51], ....: [ 3, -4, 0, -1, 9], ....: [-1, 0, -4, 4, -12]]) - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.libs.pari True - sage: A.diagonalization() + sage: A.diagonalization() # optional - sage.libs.pari ( [ 2 0 0 0 0] [ 1 1 0 1 0] [ 0 3 0 0 0] [ 1/2 0 1 0 1] @@ -11587,9 +11676,9 @@ cdef class Matrix(Matrix1): ....: [-2, -14, 0, 0, 10], ....: [3, 13, -2, 0, -11], ....: [-1, 6, 1, -3, 1]]) - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.libs.pari False - sage: A.jordan_form(subdivide=False) + sage: A.jordan_form(subdivide=False) # optional - sage.libs.pari [-1 1 0 0 0] [ 0 -1 0 0 0] [ 0 0 2 1 0] @@ -11606,46 +11695,46 @@ cdef class Matrix(Matrix1): ....: [2, -1, 1, 0, -2], ....: [0, -1, -1, -5, -8]]) - sage: [e in QQ for e in A.eigenvalues()] + sage: [e in QQ for e in A.eigenvalues()] # optional - sage.rings.number_field [False, False, False, False, False] - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.libs.pari False - sage: A.diagonalization() + sage: A.diagonalization() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: not diagonalizable over Rational Field - sage: [e in QQbar for e in A.eigenvalues()] + sage: [e in QQbar for e in A.eigenvalues()] # optional - sage.rings.number_field [True, True, True, True, True] - sage: A.is_diagonalizable(base_field=QQbar) + sage: A.is_diagonalizable(base_field=QQbar) # optional - sage.rings.number_field True Other exact fields may be employed, though it will not always be possible to extend their base fields to contain all the eigenvalues. :: - sage: F. = FiniteField(5^2) - sage: A = matrix(F, [[ 4, 3*b + 2, 3*b + 1, 3*b + 4], + sage: F. = FiniteField(5^2) # optional - sage.rings.finite_rings + sage: A = matrix(F, [[ 4, 3*b + 2, 3*b + 1, 3*b + 4], # optional - sage.rings.finite_rings ....: [2*b + 1, 4*b, 0, 2], ....: [ 4*b, b + 2, 2*b + 3, 3], ....: [ 2*b, 3*b, 4*b + 4, 3*b + 3]]) - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.rings.finite_rings False - sage: A.jordan_form() + sage: A.jordan_form() # optional - sage.rings.finite_rings [ 4 1| 0 0] [ 0 4| 0 0] [---------------+---------------] [ 0 0|2*b + 1 1] [ 0 0| 0 2*b + 1] - sage: F. = QuadraticField(-7) - sage: A = matrix(F, [[ c + 3, 2*c - 2, -2*c + 2, c - 1], + sage: F. = QuadraticField(-7) # optional - sage.rings.number_field + sage: A = matrix(F, [[ c + 3, 2*c - 2, -2*c + 2, c - 1], # optional - sage.rings.number_field ....: [2*c + 10, 13*c + 15, -13*c - 17, 11*c + 31], ....: [2*c + 10, 14*c + 10, -14*c - 12, 12*c + 30], ....: [ 0, 2*c - 2, -2*c + 2, 2*c + 2]]) - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.rings.number_field True - sage: A.diagonalization() + sage: A.diagonalization() # optional - sage.rings.number_field ( [ 4 0 0 0] [ 1 0 1 0] [ 0 -2 0 0] [ 4 1 0 1] @@ -11656,7 +11745,7 @@ cdef class Matrix(Matrix1): A trivial matrix is diagonalizable, trivially. :: sage: A = matrix(QQ, 0, 0) - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.libs.pari True A matrix must be square to be diagonalizable. :: @@ -11807,39 +11896,39 @@ cdef class Matrix(Matrix1): sage: B = matrix(ZZ, [[ 1, 12, 3], ....: [-1, -6, -1], ....: [ 0, 6, 1]]) - sage: A.is_similar(B) + sage: A.is_similar(B) # optional - sage.libs.pari True - sage: _, T = A.is_similar(B, transformation=True) - sage: T + sage: _, T = A.is_similar(B, transformation=True) # optional - sage.libs.pari + sage: T # optional - sage.libs.pari [ 1.00000000000000? + 0.?e-14*I 0.?e-14 + 0.?e-14*I 0.?e-14 + 0.?e-14*I] [-0.66666666666667? + 0.?e-15*I 0.166666666666667? + 0.?e-15*I -0.83333333333334? + 0.?e-14*I] [ 0.66666666666667? + 0.?e-14*I 0.?e-14 + 0.?e-14*I -0.33333333333333? + 0.?e-14*I] - sage: T.change_ring(QQ) + sage: T.change_ring(QQ) # optional - sage.libs.pari [ 1 0 0] [-2/3 1/6 -5/6] [ 2/3 0 -1/3] - sage: A == T.inverse()*B*T + sage: A == T.inverse()*B*T # optional - sage.libs.pari True Other exact fields are supported. :: - sage: F. = FiniteField(7^2) - sage: A = matrix(F,[[2*a + 5, 6*a + 6, a + 3], - ....: [ a + 3, 2*a + 2, 4*a + 2], - ....: [2*a + 6, 5*a + 5, 3*a]]) - sage: B = matrix(F,[[5*a + 5, 6*a + 4, a + 1], - ....: [ a + 5, 4*a + 3, 3*a + 3], - ....: [3*a + 5, a + 4, 5*a + 6]]) - sage: A.is_similar(B) + sage: F. = FiniteField(7^2) # optional - sage.rings.finite_rings + sage: A = matrix(F, [[2*a + 5, 6*a + 6, a + 3], # optional - sage.rings.finite_rings + ....: [ a + 3, 2*a + 2, 4*a + 2], + ....: [2*a + 6, 5*a + 5, 3*a]]) + sage: B = matrix(F, [[5*a + 5, 6*a + 4, a + 1], # optional - sage.rings.finite_rings + ....: [ a + 5, 4*a + 3, 3*a + 3], + ....: [3*a + 5, a + 4, 5*a + 6]]) + sage: A.is_similar(B) # optional - sage.rings.finite_rings True - sage: B.is_similar(A) + sage: B.is_similar(A) # optional - sage.rings.finite_rings True - sage: _, T = A.is_similar(B, transformation=True) - sage: T + sage: _, T = A.is_similar(B, transformation=True) # optional - sage.rings.finite_rings + sage: T # optional - sage.rings.finite_rings [ 1 0 0] [6*a + 1 4*a + 3 4*a + 2] [6*a + 3 3*a + 5 3*a + 6] - sage: A == T.inverse()*B*T + sage: A == T.inverse() * B * T # optional - sage.rings.finite_rings True Two matrices with different sets of eigenvalues, so they @@ -11853,9 +11942,9 @@ cdef class Matrix(Matrix1): ....: [-1, 2, -3, -7], ....: [-2, 3, -4, -7], ....: [ 0, -1, 0, 0]]) - sage: A.eigenvalues() == B.eigenvalues() + sage: A.eigenvalues() == B.eigenvalues() # optional - sage.rings.number_field False - sage: A.is_similar(B, transformation=True) + sage: A.is_similar(B, transformation=True) # optional - sage.libs.pari (False, None) Similarity is an equivalence relation, so this routine computes @@ -11871,7 +11960,7 @@ cdef class Matrix(Matrix1): sage: B = matrix(QQ, [[-38, -63, 42], ....: [ 14, 25, -14], ....: [-14, -21, 18]]) - sage: A.charpoly() == B.charpoly() + sage: A.charpoly() == B.charpoly() # optional - sage.libs.pari True sage: A.rational_form() [ 0 0 -48] @@ -11898,19 +11987,19 @@ cdef class Matrix(Matrix1): design, but we are not able to resurrect a similarity transformation. :: - sage: F. = FiniteField(7^2) - sage: C = matrix(F,[[ a + 2, 5*a + 4], - ....: [6*a + 6, 6*a + 4]]) - sage: S = matrix(F, [[0, 1], + sage: F. = FiniteField(7^2) # optional - sage.rings.finite_rings + sage: C = matrix(F, [[ a + 2, 5*a + 4], # optional - sage.rings.finite_rings + ....: [6*a + 6, 6*a + 4]]) + sage: S = matrix(F, [[0, 1], # optional - sage.rings.finite_rings ....: [1, 0]]) - sage: D = S.inverse()*C*S - sage: C.is_similar(D) + sage: D = S.inverse()*C*S # optional - sage.rings.finite_rings + sage: C.is_similar(D) # optional - sage.rings.finite_rings True - sage: C.is_similar(D, transformation=True) + sage: C.is_similar(D, transformation=True) # optional - sage.rings.finite_rings Traceback (most recent call last): ... RuntimeError: unable to compute transformation for similar matrices - sage: C.jordan_form() + sage: C.jordan_form() # optional - sage.rings.finite_rings Traceback (most recent call last): ... RuntimeError: Some eigenvalue does not exist in @@ -11920,9 +12009,9 @@ cdef class Matrix(Matrix1): algebraic closure of this field to find the change-of-basis matrix:: - sage: cox = posets.TamariLattice(3).coxeter_transformation() - sage: M = cox.change_ring(GF(3)) - sage: M.is_similar(M**3, True) # long time + sage: cox = posets.TamariLattice(3).coxeter_transformation() # optional - sage.graphs sage.combinat sage.rings.finite_rings + sage: M = cox.change_ring(GF(3)) # optional - sage.graphs sage.combinat sage.rings.finite_rings + sage: M.is_similar(M**3, True) # long time # optional - sage.graphs sage.combinat sage.rings.finite_rings ( [1 0 0 0 0] [0 1 1 0 2] @@ -11955,9 +12044,9 @@ cdef class Matrix(Matrix1): If the fraction fields of the entries are unequal and do not coerce in a common field, it is an error. :: - sage: A = matrix(GF(3), 2, 2, range(4)) - sage: B = matrix(GF(2), 2, 2, range(4)) - sage: A.is_similar(B, transformation=True) + sage: A = matrix(GF(3), 2, 2, range(4)) # optional - sage.rings.finite_rings + sage: B = matrix(GF(2), 2, 2, range(4)) # optional - sage.rings.finite_rings + sage: A.is_similar(B, transformation=True) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: @@ -11971,8 +12060,8 @@ cdef class Matrix(Matrix1): of ``QQ`` in ``QQbar``). :: sage: A = matrix(ZZ, 2, 2, range(4)) - sage: B = matrix(QQbar, 2, 2, range(4)) - sage: A.is_similar(B) + sage: B = matrix(QQbar, 2, 2, range(4)) # optional - sage.rings.number_field + sage: A.is_similar(B) # optional - sage.rings.number_field True TESTS: @@ -12381,18 +12470,18 @@ cdef class Matrix(Matrix1): ... TypeError: first input should be a vector, not junk - sage: A.cyclic_subspace(v, var=sin(x)) + sage: A.cyclic_subspace(v, var=sin(x)) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: polynomial variable must be a string or polynomial ring generator, not sin(x) - sage: t = polygen(GF(7), 't') - sage: A.cyclic_subspace(v, var=t) + sage: t = polygen(GF(7), 't') # optional - sage.rings.finite_rings + sage: A.cyclic_subspace(v, var=t) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: polynomial generator must be over the same ring as the matrix entries - sage: A.cyclic_subspace(v, basis='garbage') + sage: A.cyclic_subspace(v, basis='garbage') # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: basis format must be 'echelon' or 'iterates', not garbage @@ -12421,10 +12510,10 @@ cdef class Matrix(Matrix1): ... TypeError: matrix entries must be from an exact field, not Ring of integers modulo 6 - sage: F. = GF(2^4) - sage: G = matrix(QQ, 4, range(16)) - sage: w = vector(F, 4, [1, a, a^2, a^3]) - sage: G.cyclic_subspace(w) + sage: F. = GF(2^4) # optional - sage.rings.finite_rings + sage: G = matrix(QQ, 4, range(16)) # optional - sage.rings.finite_rings + sage: w = vector(F, 4, [1, a, a^2, a^3]) # optional - sage.rings.finite_rings + sage: G.cyclic_subspace(w) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unable to make vector entries compatible with matrix entries @@ -12568,55 +12657,55 @@ cdef class Matrix(Matrix1): ....: [ -2, -18, -38, 15]]) sage: A.is_symmetric() True - sage: L = A.cholesky() - sage: L + sage: L = A.cholesky() # optional - sage.rings.number_field + sage: L # optional - sage.rings.number_field [ 8.83176086632785? 0 0 0] [ -3.396831102433787? 9.51112708681461? 0 0] [ -4.189425026335004? 17.32383862241232? 2.886751345948129? 0] [-0.2264554068289192? -1.973397116652010? -1.649572197684645? 2.886751345948129?] - sage: L.parent() + sage: L.parent() # optional - sage.rings.number_field Full MatrixSpace of 4 by 4 dense matrices over Algebraic Real Field - sage: L*L.transpose() == A + sage: L*L.transpose() == A # optional - sage.rings.number_field True Some subfields of the complex numbers, such as this number field of complex numbers with rational real and imaginary parts, allow for this computation:: - sage: C. = QuadraticField(-1) - sage: A = matrix(C, [[ 23, 17*I + 3, 24*I + 25, 21*I], + sage: C. = QuadraticField(-1) # optional - sage.rings.number_field + sage: A = matrix(C, [[ 23, 17*I + 3, 24*I + 25, 21*I], # optional - sage.rings.number_field ....: [ -17*I + 3, 38, -69*I + 89, 7*I + 15], ....: [-24*I + 25, 69*I + 89, 976, 24*I + 6], ....: [ -21*I, -7*I + 15, -24*I + 6, 28]]) - sage: A.is_hermitian() + sage: A.is_hermitian() # optional - sage.rings.number_field True - sage: L = A.cholesky() + sage: L = A.cholesky() # optional - sage.rings.number_field sage: L [ 4.79...? 0 0 0] [ 0.62...? - 3.54...?*I 5.00...? 0 0] [ 5.21...? - 5.00...?*I 13.58...? + 10.72...?*I 24.98...? 0] [ -4.37...?*I -0.10...? - 0.85...?*I -0.21...? + 0.37...?*I 2.81...?] - sage: L.parent() + sage: L.parent() # optional - sage.rings.number_field Full MatrixSpace of 4 by 4 dense matrices over Algebraic Field - sage: (L*L.conjugate_transpose() - A.change_ring(QQbar)).norm() < 10^-10 + sage: (L*L.conjugate_transpose() - A.change_ring(QQbar)).norm() < 10^-10 # optional - sage.rings.number_field True The field of algebraic numbers is an ideal setting for this computation:: - sage: A = matrix(QQbar, [[ 2, 4 + 2*I, 6 - 4*I], + sage: A = matrix(QQbar, [[ 2, 4 + 2*I, 6 - 4*I], # optional - sage.rings.number_field ....: [ -2*I + 4, 11, 10 - 12*I], ....: [ 4*I + 6, 10 + 12*I, 37]]) - sage: A.is_hermitian() + sage: A.is_hermitian() # optional - sage.rings.number_field True - sage: L = A.cholesky() - sage: L + sage: L = A.cholesky() # optional - sage.rings.number_field + sage: L # optional - sage.rings.number_field [ 1.414213562373095? 0 0] [2.828427124746190? - 1.414213562373095?*I 1 0] [4.242640687119285? + 2.828427124746190?*I -2*I + 2 1.732050807568878?] - sage: L.parent() + sage: L.parent() # optional - sage.rings.number_field Full MatrixSpace of 3 by 3 dense matrices over Algebraic Field - sage: L*L.conjugate_transpose() == A + sage: L*L.conjugate_transpose() == A # optional - sage.rings.number_field True Results are cached, hence immutable. Use the ``copy`` function @@ -12652,8 +12741,8 @@ cdef class Matrix(Matrix1): Even symbolic matrices can sometimes be factored:: - sage: A = matrix(SR, [[pi,0], [0,pi]]) # optional - sage.symbolic - sage: A.cholesky() # optional - sage.symbolic + sage: A = matrix(SR, [[pi,0], [0,pi]]) # optional - sage.symbolic + sage: A.cholesky() # optional - sage.symbolic [sqrt(pi) 0] [ 0 sqrt(pi)] @@ -12672,22 +12761,22 @@ cdef class Matrix(Matrix1): The matrix may not be Hermitian:: - sage: F. = FiniteField(5^4) - sage: A = matrix(F, [[2+a^3, 3], [3, 3]]) - sage: A.cholesky() + sage: F. = FiniteField(5^4) # optional - sage.rings.finite_rings + sage: A = matrix(F, [[2+a^3, 3], [3, 3]]) # optional - sage.rings.finite_rings + sage: A.cholesky() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matrix is not Hermitian The matrix may not be positive-definite:: - sage: C. = QuadraticField(-1) - sage: B = matrix(C, [[ 2, 4 - 2*I, 2 + 2*I], + sage: C. = QuadraticField(-1) # optional - sage.rings.number_field + sage: B = matrix(C, [[ 2, 4 - 2*I, 2 + 2*I], # optional - sage.rings.number_field ....: [4 + 2*I, 8, 10*I], ....: [2 - 2*I, -10*I, -3]]) - sage: B.is_positive_definite() + sage: B.is_positive_definite() # optional - sage.rings.number_field False - sage: B.cholesky() + sage: B.cholesky() # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: matrix is not positive definite @@ -12878,32 +12967,32 @@ cdef class Matrix(Matrix1): A matrix containing real roots:: - sage: A = matrix(AA, [ [1, 0, sqrt(2)], + sage: A = matrix(AA, [ [1, 0, sqrt(2)], # optional - sage.rings.number_field sage.symbolic ....: [0, sqrt(3), 0 ], ....: [sqrt(2), 0, sqrt(5)] ]) - sage: A.is_positive_definite() + sage: A.is_positive_definite() # optional - sage.rings.number_field sage.symbolic True - sage: B = matrix(AA, [ [2*sqrt(5) + 5, 0, -sqrt(8*sqrt(5) + 18)], + sage: B = matrix(AA, [ [2*sqrt(5) + 5, 0, -sqrt(8*sqrt(5) + 18)], # optional - sage.rings.number_field sage.symbolic ....: [0, sqrt(1/3), 0], ....: [-sqrt(8*sqrt(5) + 18), 0, sqrt(5) + 2] ]) - sage: A.inverse_positive_definite() == B + sage: A.inverse_positive_definite() == B # optional - sage.rings.number_field sage.symbolic True - sage: A*B == A.matrix_space().identity_matrix() + sage: A*B == A.matrix_space().identity_matrix() # optional - sage.rings.number_field sage.symbolic True A Hermitian (but not symmetric) matrix with complex entries:: - sage: A = matrix(QQbar, [ [ 1, 0, I ], + sage: A = matrix(QQbar, [ [ 1, 0, I ], # optional - sage.rings.number_field sage.symbolic ....: [ 0, sqrt(5), 0 ], ....: [-I, 0, 3 ] ]) - sage: A.is_positive_definite() + sage: A.is_positive_definite() # optional - sage.rings.number_field sage.symbolic True - sage: B = matrix(QQbar, [ [ 3/2, 0, -I/2 ], + sage: B = matrix(QQbar, [ [ 3/2, 0, -I/2 ], # optional - sage.rings.number_field sage.symbolic ....: [ 0, sqrt(1/5), 0 ], ....: [ I/2, 0, 1/2 ] ]) - sage: A.inverse_positive_definite() == B + sage: A.inverse_positive_definite() == B # optional - sage.rings.number_field sage.symbolic True - sage: A*B == A.matrix_space().identity_matrix() + sage: A*B == A.matrix_space().identity_matrix() # optional - sage.rings.number_field sage.symbolic True TESTS: @@ -12933,15 +13022,15 @@ cdef class Matrix(Matrix1): sage: from sage.misc.prandom import choice sage: n = ZZ.random_element(2) - sage: ring = choice([AA, QQbar]) - sage: A = matrix.random(ring, n) - sage: I = matrix.identity(ring, n) - sage: A = A*A.conjugate_transpose() + I - sage: A.is_positive_definite() + sage: ring = choice([AA, QQbar]) # optional - sage.rings.number_field + sage: A = matrix.random(ring, n) # optional - sage.rings.number_field + sage: I = matrix.identity(ring, n) # optional - sage.rings.number_field + sage: A = A*A.conjugate_transpose() + I # optional - sage.rings.number_field + sage: A.is_positive_definite() # optional - sage.rings.number_field True - sage: actual = A.inverse_positive_definite() - sage: expected = A.inverse() - sage: actual == expected + sage: actual = A.inverse_positive_definite() # optional - sage.rings.number_field + sage: expected = A.inverse() # optional - sage.rings.number_field + sage: actual == expected # optional - sage.rings.number_field True """ P,L,D = self.block_ldlt() @@ -13066,47 +13155,47 @@ cdef class Matrix(Matrix1): ....: [2, 0, 1, 4, 2, 6, 0], ....: [1, 0, -1, 8, -1, -1, -3], ....: [1, 1, 2, -2, -1, 1, 3]]) - sage: P, L, U = A.LU(pivot='partial') - sage: P + sage: P, L, U = A.LU(pivot='partial') # optional - sage.combinat + sage: P # optional - sage.combinat [0 0 0 0 1] [1 0 0 0 0] [0 0 0 1 0] [0 0 1 0 0] [0 1 0 0 0] - sage: L + sage: L # optional - sage.combinat [ 1 0 0 0 0] [ 1/2 1 0 0 0] [ 1/2 1/3 1 0 0] [ 1 2/3 1/5 1 0] [ 1/2 -1/3 -2/5 0 1] - sage: U + sage: U # optional - sage.combinat [ 2 -1 0 6 4 8 -2] [ 0 3/2 2 -5 -3 -3 4] [ 0 0 -5/3 20/3 -2 -4 -10/3] [ 0 0 0 0 2/5 4/5 0] [ 0 0 0 0 1/5 2/5 0] - sage: A == P*L*U + sage: A == P*L*U # optional - sage.combinat True - sage: P, L, U = A.LU(pivot='nonzero') - sage: P + sage: P, L, U = A.LU(pivot='nonzero') # optional - sage.combinat + sage: P # optional - sage.combinat [1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] - sage: L + sage: L # optional - sage.combinat [ 1 0 0 0 0] [ 2 1 0 0 0] [ 2 2 1 0 0] [ 1 1 -1 1 0] [ 1 2 2 0 1] - sage: U + sage: U # optional - sage.combinat [ 1 -1 0 2 4 7 -1] [ 0 1 0 2 -4 -6 0] [ 0 0 1 -4 2 4 2] [ 0 0 0 0 1 2 0] [ 0 0 0 0 -1 -2 0] - sage: A == P*L*U + sage: A == P*L*U # optional - sage.combinat True An example of the compact format. :: @@ -13116,10 +13205,10 @@ cdef class Matrix(Matrix1): ....: [-1, -4, -6, -6], ....: [ 0, -2, -5, -8], ....: [-2, -6, -6, -2]]) - sage: perm, M = B.LU(format='compact') - sage: perm + sage: perm, M = B.LU(format='compact') # optional - sage.combinat + sage: perm # optional - sage.combinat (4, 3, 0, 1, 2) - sage: M + sage: M # optional - sage.combinat [ -2 -6 -6 -2] [ 0 -2 -5 -8] [-1/2 0 2 4] @@ -13133,13 +13222,13 @@ cdef class Matrix(Matrix1): ....: [ 1, -2, 1, 3], ....: [-4, 7, -3, -8], ....: [-3, 8, -1, -5]]) - sage: P, L, U = C.LU(format='plu') - sage: perm, M = C.LU(format='compact') - sage: (L - identity_matrix(4)) + U == M + sage: P, L, U = C.LU(format='plu') # optional - sage.combinat + sage: perm, M = C.LU(format='compact') # optional - sage.combinat + sage: (L - identity_matrix(4)) + U == M # optional - sage.combinat True - sage: p = [perm[i]+1 for i in range(len(perm))] - sage: PP = Permutation(p).to_matrix() - sage: PP == P + sage: p = [perm[i]+1 for i in range(len(perm))] # optional - sage.combinat + sage: PP = Permutation(p).to_matrix() # optional - sage.combinat + sage: PP == P # optional - sage.combinat True For a nonsingular matrix, and the 'nonzero' pivot @@ -13155,29 +13244,29 @@ cdef class Matrix(Matrix1): ....: [-2, 2, -3, 2, 1, 0], ....: [ 0, -1, -1, 0, 2, 5], ....: [-1, 2, -4, -1, 5, -3]]) - sage: P, L, U = D.LU(pivot='nonzero') - sage: P + sage: P, L, U = D.LU(pivot='nonzero') # optional - sage.combinat + sage: P # optional - sage.combinat [1 0 0 0 0 0] [0 1 0 0 0 0] [0 0 1 0 0 0] [0 0 0 1 0 0] [0 0 0 0 1 0] [0 0 0 0 0 1] - sage: L + sage: L # optional - sage.combinat [ 1 0 0 0 0 0] [ 3 1 0 0 0 0] [ -4 -1 1 0 0 0] [ -2 -1 -1 1 0 0] [ 0 1/2 1/4 1/2 1 0] [ -1 -1 -5/2 -2 -6 1] - sage: U + sage: U # optional - sage.combinat [ 1 0 2 0 -2 -1] [ 0 -2 -3 -1 6 9] [ 0 0 2 0 -3 -3] [ 0 0 0 1 0 4] [ 0 0 0 0 -1/4 -3/4] [ 0 0 0 0 0 1] - sage: D == L*U + sage: D == L*U # optional - sage.combinat True The base ring of the matrix may be any field, or a ring @@ -13207,45 +13296,45 @@ cdef class Matrix(Matrix1): Traceback (most recent call last): ... TypeError: cannot take absolute value of matrix entries, try 'pivot=nonzero' - sage: P, L, U = B.LU(pivot='nonzero') - sage: P + sage: P, L, U = B.LU(pivot='nonzero') # optional - sage.combinat + sage: P # optional - sage.combinat [1 0] [0 1] - sage: L + sage: L # optional - sage.combinat [ 1 0] [y^2/(y + 1) 1] - sage: U + sage: U # optional - sage.combinat [ y + 1 y^2 + y] [ 0 0] - sage: L.base_ring() + sage: L.base_ring() # optional - sage.combinat Fraction Field of Univariate Polynomial Ring in y over Rational Field - sage: B == P*L*U + sage: B == P*L*U # optional - sage.combinat True - sage: F. = FiniteField(5^2) - sage: C = matrix(F, [[a + 3, 4*a + 4, 2, 4*a + 2], + sage: F. = FiniteField(5^2) # optional - sage.rings.finite_rings + sage: C = matrix(F, [[a + 3, 4*a + 4, 2, 4*a + 2], # optional - sage.rings.finite_rings ....: [3, 2*a + 4, 2*a + 4, 2*a + 1], ....: [3*a + 1, a + 3, 2*a + 4, 4*a + 3], ....: [a, 3, 3*a + 1, a]]) - sage: P, L, U = C.LU(pivot='nonzero') - sage: P + sage: P, L, U = C.LU(pivot='nonzero') # optional - sage.combinat sage.rings.finite_rings + sage: P # optional - sage.combinat sage.rings.finite_rings [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1] - sage: L + sage: L # optional - sage.combinat sage.rings.finite_rings [ 1 0 0 0] [3*a + 3 1 0 0] [ 2*a 4*a + 2 1 0] [2*a + 3 2 2*a + 4 1] - sage: U + sage: U # optional - sage.combinat sage.rings.finite_rings [ a + 3 4*a + 4 2 4*a + 2] [ 0 a + 1 a + 3 2*a + 4] [ 0 0 1 4*a + 2] [ 0 0 0 0] - sage: L.base_ring() + sage: L.base_ring() # optional - sage.combinat sage.rings.finite_rings Finite Field in a of size 5^2 - sage: C == P*L*U + sage: C == P*L*U # optional - sage.combinat sage.rings.finite_rings True With no pivoting strategy given (i.e. ``pivot=None``) @@ -13257,10 +13346,10 @@ cdef class Matrix(Matrix1): sage: entries = [3, 20, 11, 7, 16, 28, 5, 15, 21, 23, 22, 18, 8, 23, 15, 2] sage: A = matrix(Integers(29), 4, 4, entries) - sage: perm, _ = A.LU(format='compact'); perm + sage: perm, _ = A.LU(format='compact'); perm # optional - sage.combinat (0, 1, 2, 3) sage: B = matrix(QQ, 4, 4, entries) - sage: perm, _ = B.LU(format='compact'); perm + sage: perm, _ = B.LU(format='compact'); perm # optional - sage.combinat (2, 0, 1, 3) The `U` matrix is only guaranteed to be upper-triangular. @@ -13272,8 +13361,8 @@ cdef class Matrix(Matrix1): ....: [ 0, 0, 1, -4, -1, -3, 6, -5, -6], ....: [-2, 8, -1, -4, 2, -4, 1, -8, -7], ....: [ 1, -4, 2, -4, -3, 2, 5, 6, 4]]) - sage: P, L, U = A.LU() - sage: U + sage: P, L, U = A.LU() # optional - sage.combinat + sage: U # optional - sage.combinat [ -2 8 -1 -4 2 -4 1 -8 -7] [ 0 0 1/2 -2 -1 -2 9/2 -3 -7/2] [ 0 0 3/2 -6 -2 0 11/2 2 1/2] @@ -13306,15 +13395,15 @@ cdef class Matrix(Matrix1): components of the 'plu' format are not. :: sage: A = matrix(ZZ, 2, range(4)) - sage: perm, M = A.LU(format='compact') - sage: perm[0] = 25 + sage: perm, M = A.LU(format='compact') # optional - sage.combinat + sage: perm[0] = 25 # optional - sage.combinat Traceback (most recent call last): ... TypeError: 'tuple' object does not support item assignment - sage: M.is_immutable() + sage: M.is_immutable() # optional - sage.combinat True - sage: P, L, U = A.LU(format='plu') - sage: all(A.is_mutable() for A in [P, L, U]) + sage: P, L, U = A.LU(format='plu') # optional - sage.combinat + sage: all(A.is_mutable() for A in [P, L, U]) # optional - sage.combinat True Partial pivoting is based on the absolute values of entries @@ -13322,18 +13411,18 @@ cdef class Matrix(Matrix1): absolute value must be handled carefully. This tests that situation in the case of cyclotomic fields. :: - sage: C = SymmetricGroup(5).character_table() - sage: C.base_ring() + sage: C = SymmetricGroup(5).character_table() # optional - sage.groups sage.rings.number_field + sage: C.base_ring() # optional - sage.groups sage.rings.number_field Cyclotomic Field of order 1 and degree 1 - sage: P, L, U = C.LU(pivot='partial') - sage: C == P*L*U + sage: P, L, U = C.LU(pivot='partial') # optional - sage.combinat sage.groups sage.rings.number_field + sage: C == P*L*U # optional - sage.combinat sage.groups sage.rings.number_field True Check that :trac:`32736` is solved:: - sage: M = Matrix(FiniteField(11), [[2,3],[4,5]]) - sage: P, L, U = M.LU() - sage: P.base_ring() + sage: M = Matrix(FiniteField(11), [[2,3],[4,5]]) # optional - sage.rings.finite_rings + sage: P, L, U = M.LU() # optional - sage.combinat sage.rings.finite_rings + sage: P.base_ring() # optional - sage.combinat sage.rings.finite_rings Finite Field of size 11 """ if pivot not in [None, 'partial', 'nonzero']: @@ -13502,23 +13591,23 @@ cdef class Matrix(Matrix1): A Hermitian matrix. :: - sage: x = var('x') - sage: C. = NumberField(x^2 + 1) - sage: A = matrix(C, [[ 23, 17*I + 3, 24*I + 25, 21*I], + sage: x = polygen(ZZ) + sage: C. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: A = matrix(C, [[ 23, 17*I + 3, 24*I + 25, 21*I], # optional - sage.rings.number_field ....: [ -17*I + 3, 38, -69*I + 89, 7*I + 15], ....: [-24*I + 25, 69*I + 89, 976, 24*I + 6], ....: [ -21*I, -7*I + 15, -24*I + 6, 28]]) - sage: A.is_hermitian() + sage: A.is_hermitian() # optional - sage.rings.number_field True - sage: L, d = A._indefinite_factorization('hermitian') - sage: L + sage: L, d = A._indefinite_factorization('hermitian') # optional - sage.rings.number_field + sage: L # optional - sage.rings.number_field [ 1 0 0 0] [ -17/23*I + 3/23 1 0 0] [ -24/23*I + 25/23 617/288*I + 391/144 1 0] [ -21/23*I -49/288*I - 1/48 1336/89885*I - 773/89885 1] - sage: d + sage: d # optional - sage.rings.number_field (23, 576/23, 89885/144, 142130/17977) - sage: A == L*diagonal_matrix(C, d)*L.conjugate_transpose() + sage: A == L*diagonal_matrix(C, d)*L.conjugate_transpose() # optional - sage.rings.number_field True A matrix may have a singular submatrix in the upper-left @@ -13785,23 +13874,23 @@ cdef class Matrix(Matrix1): with rational real and imaginary parts. As theory predicts, the diagonal entries will be real numbers. :: - sage: C. = QuadraticField(-1) - sage: B = matrix(C, [[ 2, 4 - 2*I, 2 + 2*I], + sage: C. = QuadraticField(-1) # optional - sage.rings.number_field + sage: B = matrix(C, [[ 2, 4 - 2*I, 2 + 2*I], # optional - sage.rings.number_field ....: [4 + 2*I, 8, 10*I], ....: [2 - 2*I, -10*I, -3]]) - sage: B.is_hermitian() + sage: B.is_hermitian() # optional - sage.rings.number_field True - sage: L, d = B.indefinite_factorization(algorithm='hermitian') - sage: D = diagonal_matrix(d) - sage: L + sage: L, d = B.indefinite_factorization(algorithm='hermitian') # optional - sage.rings.number_field + sage: D = diagonal_matrix(d) # optional - sage.rings.number_field + sage: L # optional - sage.rings.number_field [ 1 0 0] [ I + 2 1 0] [ -I + 1 2*I + 1 1] - sage: D + sage: D # optional - sage.rings.number_field [ 2 0 0] [ 0 -2 0] [ 0 0 3] - sage: B == L*D*L.conjugate_transpose() + sage: B == L*D*L.conjugate_transpose() # optional - sage.rings.number_field True If a leading principal submatrix has zero determinant, this @@ -13827,27 +13916,27 @@ cdef class Matrix(Matrix1): may be factored. This provides a reasonable alternative to the Cholesky decomposition. :: - sage: F. = FiniteField(5^3) - sage: A = matrix(F, + sage: F. = FiniteField(5^3) # optional - sage.rings.finite_rings + sage: A = matrix(F, # optional - sage.rings.finite_rings ....: [[ a^2 + 2*a, 4*a^2 + 3*a + 4, 3*a^2 + a, 2*a^2 + 2*a + 1], ....: [4*a^2 + 3*a + 4, 4*a^2 + 2, 3*a, 2*a^2 + 4*a + 2], ....: [ 3*a^2 + a, 3*a, 3*a^2 + 2, 3*a^2 + 2*a + 3], ....: [2*a^2 + 2*a + 1, 2*a^2 + 4*a + 2, 3*a^2 + 2*a + 3, 3*a^2 + 2*a + 4]]) - sage: A.is_symmetric() + sage: A.is_symmetric() # optional - sage.rings.finite_rings True - sage: L, d = A.indefinite_factorization() - sage: D = diagonal_matrix(d) - sage: L + sage: L, d = A.indefinite_factorization() # optional - sage.rings.finite_rings + sage: D = diagonal_matrix(d) # optional - sage.rings.finite_rings + sage: L # optional - sage.rings.finite_rings [ 1 0 0 0] [4*a^2 + 4*a + 3 1 0 0] [ 3 4*a^2 + a + 2 1 0] [ 4*a^2 + 4 2*a^2 + 3*a + 3 2*a^2 + 3*a + 1 1] - sage: D + sage: D # optional - sage.rings.finite_rings [ a^2 + 2*a 0 0 0] [ 0 2*a^2 + 2*a + 4 0 0] [ 0 0 3*a^2 + 4*a + 3 0] [ 0 0 0 a^2 + 3*a] - sage: A == L*D*L.transpose() + sage: A == L*D*L.transpose() # optional - sage.rings.finite_rings True This works correctly for the 0x0 matrix:: @@ -14253,13 +14342,13 @@ cdef class Matrix(Matrix1): The same is true of the following complex Hermitian matrix:: - sage: A = matrix(QQbar, [ [ 0,I], + sage: A = matrix(QQbar, [ [ 0,I], # optional - sage.rings.number_field ....: [-I,0] ]) - sage: A.block_ldlt(classical=True) + sage: A.block_ldlt(classical=True) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: matrix has no classical LDL^T factorization - sage: A.block_ldlt() + sage: A.block_ldlt() # optional - sage.rings.number_field ( [1 0] [1 0] [ 0 I] [0 1], [0 1], [-I 0] @@ -14347,11 +14436,11 @@ cdef class Matrix(Matrix1): An indefinite Hermitian matrix that happens to have a classical factorization:: - sage: F. = QuadraticField(-1) - sage: A = matrix(F, [[ 2, 4 - 2*I, 2 + 2*I], + sage: F. = QuadraticField(-1) # optional - sage.rings.number_field + sage: A = matrix(F, [[ 2, 4 - 2*I, 2 + 2*I], # optional - sage.rings.number_field ....: [4 + 2*I, 8, 10*I], ....: [2 - 2*I, -10*I, -3]]) - sage: A.block_ldlt(classical=True)[1:] + sage: A.block_ldlt(classical=True)[1:] # optional - sage.rings.number_field ( [ 2| 0| 0] [--+--+--] @@ -14383,11 +14472,11 @@ cdef class Matrix(Matrix1): correctly:: sage: n = ZZ.random_element(6) - sage: F = QuadraticField(-1, 'I') - sage: A = matrix.random(F, n) - sage: A = A + A.conjugate_transpose() - sage: P,L,D = A.block_ldlt() - sage: A == P*L*D*L.conjugate_transpose()*P.conjugate_transpose() + sage: F = QuadraticField(-1, 'I') # optional - sage.rings.number_field + sage: A = matrix.random(F, n) # optional - sage.rings.number_field + sage: A = A + A.conjugate_transpose() # optional - sage.rings.number_field + sage: P,L,D = A.block_ldlt() # optional - sage.rings.number_field + sage: A == P*L*D*L.conjugate_transpose()*P.conjugate_transpose() # optional - sage.rings.number_field True Ensure that a "random" complex positive-semidefinite matrix is @@ -14395,20 +14484,20 @@ cdef class Matrix(Matrix1): is in fact diagonal:: sage: n = ZZ.random_element(6) - sage: F = QuadraticField(-1, 'I') - sage: A = matrix.random(F, n) - sage: A = A*A.conjugate_transpose() - sage: P,L,D = A.block_ldlt() - sage: A == P*L*D*L.conjugate_transpose()*P.conjugate_transpose() + sage: F = QuadraticField(-1, 'I') # optional - sage.rings.number_field + sage: A = matrix.random(F, n) # optional - sage.rings.number_field + sage: A = A * A.conjugate_transpose() # optional - sage.rings.number_field + sage: P,L,D = A.block_ldlt() # optional - sage.rings.number_field + sage: A == P * L * D * L.conjugate_transpose() * P.conjugate_transpose() # optional - sage.rings.number_field True - sage: diagonal_matrix(D.diagonal()) == D + sage: diagonal_matrix(D.diagonal()) == D # optional - sage.rings.number_field True The factorization should be a no-op on diagonal matrices:: sage: n = ZZ.random_element(6) sage: A = matrix.diagonal(random_vector(QQ, n)) - sage: I = matrix.identity(QQ,n) + sage: I = matrix.identity(QQ, n) sage: P,L,D = A.block_ldlt() sage: P == I and L == I and A == D True @@ -14535,7 +14624,7 @@ cdef class Matrix(Matrix1): sage: A = matrix(QQ, [ [2,1], ....: [1,2] ] ) - sage: A.eigenvalues() + sage: A.eigenvalues() # optional - sage.rings.number_field [3, 1] sage: A.is_positive_semidefinite() True @@ -14604,9 +14693,10 @@ cdef class Matrix(Matrix1): a Hermitian matrix (for a non-Hermitian matrix, both "obviously" return ``False``):: - sage: F = QuadraticField(-1, 'I') + sage: rings = [ZZ, QQ, RDF, CDF] + sage: rings.append(QuadraticField(-1, 'I')) # optional - sage.rings.number_field sage: from sage.misc.prandom import choice - sage: ring = choice([ZZ, QQ, F, RDF, CDF]) + sage: ring = choice(rings) sage: A = matrix.random(ring, 10); A = A + A.conjugate_transpose() sage: def is_positive_semidefinite_naive(A): ....: if A.nrows() == 0: @@ -14622,9 +14712,9 @@ cdef class Matrix(Matrix1): either real numbers, complex numbers, or symbolics; otherwise we risk returning nonsensical results:: - sage: F = FiniteField(5^2) - sage: A = matrix.identity(F, 1) - sage: A.is_positive_semidefinite() + sage: F = FiniteField(5^2) # optional - sage.rings.finite_rings + sage: A = matrix.identity(F, 1) # optional - sage.rings.finite_rings + sage: A.is_positive_semidefinite() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: Could not see Finite Field in z2 of size 5^2 @@ -14696,7 +14786,7 @@ cdef class Matrix(Matrix1): ....: [ 2, -7, 4, 7]]) sage: A.is_positive_definite() True - sage: [A[:i,:i].determinant() for i in range(1,A.nrows()+1)] + sage: [A[:i,:i].determinant() for i in range(1, A.nrows() + 1)] [4, 36, 144, 144] A real symmetric matrix that is not positive-definite and a @@ -14732,39 +14822,39 @@ cdef class Matrix(Matrix1): confirmed by the positive determinants of its leading principal submatrices:: - sage: C. = NumberField(x^2 + 1, embedding=CC(0,1)) + sage: C. = NumberField(x^2 + 1, embedding=CC(0,1)) # optional - sage.rings.number_field sage: A = matrix(C, [[ 23, 17*I + 3, 24*I + 25, 21*I], ....: [ -17*I + 3, 38, -69*I + 89, 7*I + 15], ....: [-24*I + 25, 69*I + 89, 976, 24*I + 6], ....: [ -21*I, -7*I + 15, -24*I + 6, 28]]) - sage: A.is_positive_definite() + sage: A.is_positive_definite() # optional - sage.rings.number_field True - sage: [A[:i,:i].determinant() for i in range(1,A.nrows()+1)] + sage: [A[:i,:i].determinant() for i in range(1,A.nrows()+1)] # optional - sage.rings.number_field [23, 576, 359540, 2842600] An Hermitian matrix that is not positive-definite and a vector ``u`` that makes the corresponding quadratic form negative:: - sage: C. = QuadraticField(-1) - sage: B = matrix(C, [[ 2, 4 - 2*I, 2 + 2*I], + sage: C. = QuadraticField(-1) # optional - sage.rings.number_field + sage: B = matrix(C, [[ 2, 4 - 2*I, 2 + 2*I], # optional - sage.rings.number_field ....: [4 + 2*I, 8, 10*I], ....: [2 - 2*I, -10*I, -3]]) - sage: B.is_positive_definite() + sage: B.is_positive_definite() # optional - sage.rings.number_field False - sage: u = vector(C, [-5 + 10*I, 4 - 3*I, 0]) - sage: (B*u).hermitian_inner_product(u) + sage: u = vector(C, [-5 + 10*I, 4 - 3*I, 0]) # optional - sage.rings.number_field + sage: (B*u).hermitian_inner_product(u) # optional - sage.rings.number_field -50 A positive-definite matrix over an algebraically-closed field, confirmed by the positive determinants of its leading principal submatrices:: - sage: A = matrix(QQbar, [[ 2, 4 + 2*I, 6 - 4*I], + sage: A = matrix(QQbar, [[ 2, 4 + 2*I, 6 - 4*I], # optional - sage.rings.number_field ....: [ -2*I + 4, 11, 10 - 12*I], ....: [ 4*I + 6, 10 + 12*I, 37]]) - sage: A.is_positive_definite() + sage: A.is_positive_definite() # optional - sage.rings.number_field True - sage: [A[:i,:i].determinant() for i in range(1,A.nrows()+1)] + sage: [A[:i,:i].determinant() for i in range(1, A.nrows() + 1)] # optional - sage.rings.number_field [2, 2, 6] TESTS: @@ -14773,17 +14863,17 @@ cdef class Matrix(Matrix1): numbers, complex numbers, or symbolic ring, then this routine will fail since comparison to zero is meaningless:: - sage: F. = FiniteField(5^3) - sage: a.conjugate() + sage: F. = FiniteField(5^3) # optional - sage.rings.finite_rings + sage: a.conjugate() # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: cardinality of the field must be a square number - sage: A = matrix(F, + sage: A = matrix(F, # optional - sage.rings.finite_rings ....: [[ a^2 + 2*a, 4*a^2 + 3*a + 4, 3*a^2 + a, 2*a^2 + 2*a + 1], ....: [4*a^2 + 3*a + 4, 4*a^2 + 2, 3*a, 2*a^2 + 4*a + 2], ....: [ 3*a^2 + a, 3*a, 3*a^2 + 2, 3*a^2 + 2*a + 3], ....: [2*a^2 + 2*a + 1, 2*a^2 + 4*a + 2, 3*a^2 + 2*a + 3, 3*a^2 + 2*a + 4]]) - sage: A.is_positive_definite() + sage: A.is_positive_definite() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: Could not see Finite Field in a of size 5^3 as a subring @@ -14801,7 +14891,7 @@ cdef class Matrix(Matrix1): True sage: matrix.identity(CC,4).is_positive_definite() True - sage: matrix.identity(SR,4).is_positive_definite() # optional - sage.symbolic + sage: matrix.identity(SR,4).is_positive_definite() # optional - sage.symbolic True """ result = self._is_positive_definite_or_semidefinite(False) @@ -14833,7 +14923,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = Matrix([[1,-1/2,0],[-1/2,1,-1/2],[0,-1/2,1]]) + sage: A = Matrix([[1,-1/2,0], [-1/2,1,-1/2], [0,-1/2,1]]) sage: B = A.principal_square_root() sage: A == B^2 True @@ -15002,21 +15092,21 @@ cdef class Matrix(Matrix1): A matrix over a not-totally-real number field:: - sage: K. = NumberField(x^2+5) - sage: M = matrix(K, [[1+j,1], [0,2*j]]) - sage: M.conjugate() + sage: K. = NumberField(x^2+5) # optional - sage.rings.number_field + sage: M = matrix(K, [[1+j,1], [0,2*j]]) # optional - sage.rings.number_field + sage: M.conjugate() # optional - sage.rings.number_field [-j + 1 1] [ 0 -2*j] There is a shortcut for the conjugate:: - sage: M.C + sage: M.C # optional - sage.rings.number_field [-j + 1 1] [ 0 -2*j] There is also a shortcut for the conjugate transpose, or "Hermitian transpose":: - sage: M.H + sage: M.H # optional - sage.rings.number_field [-j + 1 0] [ 1 -2*j] @@ -15057,10 +15147,10 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = matrix(SR, 2, 2, [[2-I, 3+4*I], [9-6*I, 5*I]]) # optional - sage.symbolic - sage: M.base_ring() # optional - sage.symbolic + sage: M = matrix(SR, 2, 2, [[2-I, 3+4*I], [9-6*I, 5*I]]) # optional - sage.symbolic + sage: M.base_ring() # optional - sage.symbolic Symbolic Ring - sage: M.conjugate_transpose() # optional - sage.symbolic + sage: M.conjugate_transpose() # optional - sage.symbolic [ I + 2 6*I + 9] [-4*I + 3 -5*I] @@ -15090,32 +15180,32 @@ cdef class Matrix(Matrix1): (Matrices over quadratic number fields are another class of examples.) :: - sage: C = CyclotomicField(5) - sage: a = C.gen(); a + sage: C = CyclotomicField(5) # optional - sage.rings.number_field + sage: a = C.gen(); a # optional - sage.rings.number_field zeta5 - sage: CC(a) + sage: CC(a) # optional - sage.rings.number_field 0.309016994374947 + 0.951056516295154*I - sage: M = matrix(C, 1, 2, [a^2, a+a^3]) - sage: M.conjugate_transpose() + sage: M = matrix(C, 1, 2, [a^2, a+a^3]) # optional - sage.rings.number_field + sage: M.conjugate_transpose() # optional - sage.rings.number_field [ zeta5^3] [-zeta5^3 - zeta5 - 1] Furthermore, this method can be applied to matrices over quadratic extensions of finite fields:: - sage: F. = GF(9,'a') - sage: N = matrix(F, 2, [0,a,-a,1]); N + sage: F. = GF(9,'a') # optional - sage.rings.finite_rings + sage: N = matrix(F, 2, [0,a,-a,1]); N # optional - sage.rings.finite_rings [ 0 a] [2*a 1] - sage: N.conjugate_transpose() + sage: N.conjugate_transpose() # optional - sage.rings.finite_rings [ 0 a + 2] [2*a + 1 1] Conjugation does not make sense over rings not containing complex numbers or finite fields which are not a quadratic extension:: - sage: N = matrix(GF(5), 2, [0,1,2,3]) - sage: N.conjugate_transpose() + sage: N = matrix(GF(5), 2, [0,1,2,3]) # optional - sage.rings.finite_rings + sage: N.conjugate_transpose() # optional - sage.rings.finite_rings Traceback (most recent call last): ... AttributeError: 'sage.rings.finite_rings.integer_mod.IntegerMod_int' object has no attribute 'conjugate' @@ -15133,8 +15223,7 @@ cdef class Matrix(Matrix1): INPUT: - - ``self`` - a matrix whose entries are coercible into - CDF + - ``self`` - a matrix whose entries are coercible into ``CDF`` - ``p`` - one of the following options: @@ -15155,7 +15244,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(ZZ, [[1,2,4,3],[-1,0,3,-10]]) + sage: A = matrix(ZZ, [[1,2,4,3], [-1,0,3,-10]]) sage: A.norm(1) 13.0 sage: A.norm(Infinity) @@ -15245,32 +15334,32 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: d = matrix([[3, 0],[0,sqrt(2)]]) - sage: b = matrix([[1, -1], [2, 2]]) ; e = b * d * b.inverse();e + sage: d = matrix([[3, 0], [0, sqrt(2)]]) # optional - sage.symbolic + sage: b = matrix([[1, -1], [2, 2]]); e = b * d * b.inverse(); e # optional - sage.symbolic [ 1/2*sqrt(2) + 3/2 -1/4*sqrt(2) + 3/4] [ -sqrt(2) + 3 1/2*sqrt(2) + 3/2] :: - sage: e.numerical_approx(53) + sage: e.numerical_approx(53) # optional - sage.symbolic [ 2.20710678118655 0.396446609406726] [ 1.58578643762690 2.20710678118655] :: - sage: e.numerical_approx(20) + sage: e.numerical_approx(20) # optional - sage.symbolic [ 2.2071 0.39645] [ 1.5858 2.2071] :: - sage: (e-I).numerical_approx(20) + sage: (e - I).numerical_approx(20) # optional - sage.symbolic [2.2071 - 1.0000*I 0.39645] [ 1.5858 2.2071 - 1.0000*I] :: - sage: M=matrix(QQ,4,[i/(i+1) for i in range(12)]);M + sage: M = matrix(QQ, 4, [i/(i+1) for i in range(12)]); M [ 0 1/2 2/3] [ 3/4 4/5 5/6] [ 6/7 7/8 8/9] @@ -15286,7 +15375,7 @@ cdef class Matrix(Matrix1): :: - sage: matrix(SR, 2, 2, range(4)).n() # optional - sage.symbolic + sage: matrix(SR, 2, 2, range(4)).n() # optional - sage.symbolic [0.000000000000000 1.00000000000000] [ 2.00000000000000 3.00000000000000] @@ -15300,9 +15389,9 @@ cdef class Matrix(Matrix1): We check that :trac:`29700` is fixed:: - sage: M = matrix(3,[1,1,1,1,0,0,0,1,0]) - sage: A,B = M.diagonalization(QQbar) - sage: _ = A.n() + sage: M = matrix(3, [1,1,1,1,0,0,0,1,0]) + sage: A, B = M.diagonalization(QQbar) # optional - sage.rings.number_field + sage: _ = A.n() # optional - sage.rings.number_field """ from sage.rings.real_mpfr import RealField @@ -15337,21 +15426,21 @@ cdef class Matrix(Matrix1): A matrix over ZZ colored with different grey levels:: sage: A = matrix([[1,3,5,1],[2,4,5,6],[1,3,5,7]]) - sage: A.plot() + sage: A.plot() # optional - sage.plot Graphics object consisting of 1 graphics primitive - Here we make a random matrix over RR and use cmap='hsv' to color + Here we make a random matrix over ``RR`` and use ``cmap='hsv'`` to color the matrix elements different RGB colors (see documentation for ``matrix_plot`` for more information on cmaps):: sage: A = random_matrix(RDF, 50) - sage: plot(A, cmap='hsv') + sage: plot(A, cmap='hsv') # optional - sage.plot Graphics object consisting of 1 graphics primitive Another random plot, but over GF(389):: - sage: A = random_matrix(GF(389), 10) - sage: A.plot(cmap='Oranges') + sage: A = random_matrix(GF(389), 10) # optional - sage.rings.finite_rings + sage: A.plot(cmap='Oranges') # optional - sage.rings.finite_rings sage.plot Graphics object consisting of 1 graphics primitive """ from sage.plot.matrix_plot import matrix_plot @@ -15367,17 +15456,17 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: v = vector([1,x,x^2]) - sage: v.derivative(x) + sage: v = vector([1,x,x^2]) # optional - sage.symbolic + sage: v.derivative(x) # optional - sage.symbolic (0, 1, 2*x) - sage: type(v.derivative(x)) == type(v) + sage: type(v.derivative(x)) == type(v) # optional - sage.symbolic True - sage: v = vector([1,x,x^2], sparse=True) - sage: v.derivative(x) + sage: v = vector([1,x,x^2], sparse=True) # optional - sage.symbolic + sage: v.derivative(x) # optional - sage.symbolic (0, 1, 2*x) - sage: type(v.derivative(x)) == type(v) + sage: type(v.derivative(x)) == type(v) # optional - sage.symbolic True - sage: v.derivative(x,x) + sage: v.derivative(x,x) # optional - sage.symbolic (0, 0, 2) """ from sage.misc.derivative import multi_derivative @@ -15402,24 +15491,24 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: a=matrix([[1,2],[3,4]]) - sage: a.exp() + sage: a = matrix([[1,2], [3,4]]) + sage: a.exp() # optional - sage.symbolic [-1/22*((sqrt(33) - 11)*e^sqrt(33) - sqrt(33) - 11)*e^(-1/2*sqrt(33) + 5/2) 2/33*(sqrt(33)*e^sqrt(33) - sqrt(33))*e^(-1/2*sqrt(33) + 5/2)] [ 1/11*(sqrt(33)*e^sqrt(33) - sqrt(33))*e^(-1/2*sqrt(33) + 5/2) 1/22*((sqrt(33) + 11)*e^sqrt(33) - sqrt(33) + 11)*e^(-1/2*sqrt(33) + 5/2)] - sage: type(a.exp()) + sage: type(a.exp()) # optional - sage.symbolic - sage: a=matrix([[1/2,2/3],[3/4,4/5]]) - sage: a.exp() + sage: a = matrix([[1/2,2/3], [3/4,4/5]]) + sage: a.exp() # optional - sage.symbolic [-1/418*((3*sqrt(209) - 209)*e^(1/10*sqrt(209)) - 3*sqrt(209) - 209)*e^(-1/20*sqrt(209) + 13/20) 20/627*(sqrt(209)*e^(1/10*sqrt(209)) - sqrt(209))*e^(-1/20*sqrt(209) + 13/20)] [ 15/418*(sqrt(209)*e^(1/10*sqrt(209)) - sqrt(209))*e^(-1/20*sqrt(209) + 13/20) 1/418*((3*sqrt(209) + 209)*e^(1/10*sqrt(209)) - 3*sqrt(209) + 209)*e^(-1/20*sqrt(209) + 13/20)] - sage: a=matrix(RR,[[1,pi.n()],[1e2,1e-2]]) - sage: a.exp() + sage: a = matrix(RR, [[1,pi.n()], [1e2,1e-2]]) # optional - sage.symbolic + sage: a.exp() # optional - sage.symbolic [ 1/11882424341266*((11*sqrt(227345670387496707609) + 5941212170633)*e^(3/1275529100*sqrt(227345670387496707609)) - 11*sqrt(227345670387496707609) + 5941212170633)*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200) 445243650/75781890129165569203*(sqrt(227345670387496707609)*e^(3/1275529100*sqrt(227345670387496707609)) - sqrt(227345670387496707609))*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200)] [ 10000/53470909535697*(sqrt(227345670387496707609)*e^(3/1275529100*sqrt(227345670387496707609)) - sqrt(227345670387496707609))*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200) -1/11882424341266*((11*sqrt(227345670387496707609) - 5941212170633)*e^(3/1275529100*sqrt(227345670387496707609)) - 11*sqrt(227345670387496707609) - 5941212170633)*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200)] - sage: a.change_ring(RDF).exp() # rel tol 1e-14 + sage: a.change_ring(RDF).exp() # rel tol 1e-14 # optional - sage.symbolic [42748127.31532951 7368259.244159399] [234538976.1381042 40426191.45156228] @@ -15427,9 +15516,9 @@ cdef class Matrix(Matrix1): Check that sparse matrices are handled correctly (:trac:`28935`):: - sage: matrix.diagonal([0], sparse=True).exp() + sage: matrix.diagonal([0], sparse=True).exp() # optional - sage.symbolic [1] - sage: matrix.zero(CBF, 2, sparse=True).exp() + sage: matrix.zero(CBF, 2, sparse=True).exp() # optional - sage.symbolic [1.000000000000000 0] [ 0 1.000000000000000] """ @@ -15456,9 +15545,9 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: OE. = EquationOrder(x^2 - x + 2) - sage: m = Matrix([ [1, w],[w,7]]) - sage: m.elementary_divisors() + sage: OE. = EquationOrder(x^2 - x + 2) # optional - sage.rings.number_field + sage: m = Matrix([[1, w], [w, 7]]) # optional - sage.rings.number_field + sage: m.elementary_divisors() # optional - sage.rings.number_field [1, -w + 9] .. SEEALSO:: @@ -15547,24 +15636,25 @@ cdef class Matrix(Matrix1): An example over the ring of integers of a number field (of class number 1):: - sage: OE. = EquationOrder(x^2 - x + 2) - sage: m = Matrix([ [1, w],[w,7]]) - sage: d, u, v = m.smith_form() - sage: (d, u, v) + sage: OE. = EquationOrder(x^2 - x + 2) # optional - sage.rings.number_field + sage: m = Matrix([[1, w], [w, 7]]) # optional - sage.rings.number_field + sage: d, u, v = m.smith_form() # optional - sage.rings.number_field + sage: (d, u, v) # optional - sage.rings.number_field ( [ 1 0] [ 1 0] [ 1 -w] [ 0 -w + 9], [-w 1], [ 0 1] ) - sage: u * m * v == d + sage: u * m * v == d # optional - sage.rings.number_field True - sage: u.base_ring() == v.base_ring() == d.base_ring() == OE + sage: u.base_ring() == v.base_ring() == d.base_ring() == OE # optional - sage.rings.number_field True - sage: u.det().is_unit() and v.det().is_unit() + sage: u.det().is_unit() and v.det().is_unit() # optional - sage.rings.number_field True An example over the polynomial ring QQ[x]:: - sage: R. = QQ[]; m=x*matrix(R,2,2,1) - matrix(R, 2,2,[3,-4,1,-1]); m.smith_form() + sage: R. = QQ[]; m = x*matrix(R, 2, 2, 1) - matrix(R, 2, 2, [3,-4,1,-1]) + sage: m.smith_form() ( [ 1 0] [ 0 -1] [ 1 x + 1] [ 0 x^2 - 2*x + 1], [ 1 x - 3], [ 0 1] @@ -15572,12 +15662,13 @@ cdef class Matrix(Matrix1): An example over a field:: - sage: m = matrix( GF(17), 3, 3, [11,5,1,3,6,8,1,16,0]); d,u,v = m.smith_form() - sage: d + sage: m = matrix(GF(17), 3, 3, [11,5,1, 3,6,8, 1,16,0]) # optional - sage.rings.finite_rings + sage: d, u, v = m.smith_form() # optional - sage.rings.finite_rings + sage: d # optional - sage.rings.finite_rings [1 0 0] [0 1 0] [0 0 0] - sage: u*m*v == d + sage: u * m * v == d # optional - sage.rings.finite_rings True When the base ring has a ``ring_of_integers`` method and supports denominators, @@ -15597,45 +15688,51 @@ cdef class Matrix(Matrix1): Some examples over non-PID's work anyway:: - sage: R. = EquationOrder(x^2 + 5) # class number 2 - sage: A = matrix(R, 2, 2, [s-1,-s,-s,2*s+1]) - sage: D, U, V = A.smith_form() - sage: D, U, V + sage: R. = EquationOrder(x^2 + 5) # class number 2 # optional - sage.rings.number_field + sage: A = matrix(R, 2, 2, [s - 1, -s, -s, 2*s + 1]) # optional - sage.rings.number_field + sage: D, U, V = A.smith_form() # optional - sage.rings.number_field + sage: D, U, V # optional - sage.rings.number_field ( [ 1 0] [ 4 s + 4] [ 1 -5*s + 6] [ 0 -s - 6], [ s s - 1], [ 0 1] ) - sage: D == U*A*V + sage: D == U * A * V # optional - sage.rings.number_field True Others don't, but they fail quite constructively:: - sage: matrix(R,2,2,[s-1,-s-2,-2*s,-s-2]).smith_form() + sage: matrix(R, 2, 2, [s - 1, -s - 2, -2*s, -s - 2]).smith_form() # optional - sage.rings.number_field Traceback (most recent call last): ... ArithmeticError: Ideal Fractional ideal (2, s + 1) not principal Empty matrices are handled safely:: - sage: m = MatrixSpace(OE, 2,0)(0); d,u,v=m.smith_form(); u*m*v == d + sage: m = MatrixSpace(OE, 2,0)(0); d, u, v = m.smith_form(); u * m * v == d True - sage: m = MatrixSpace(OE, 0,2)(0); d,u,v=m.smith_form(); u*m*v == d + sage: m = MatrixSpace(OE, 0,2)(0); d, u, v = m.smith_form(); u * m * v == d True - sage: m = MatrixSpace(OE, 0,0)(0); d,u,v=m.smith_form(); u*m*v == d + sage: m = MatrixSpace(OE, 0,0)(0); d, u, v = m.smith_form(); u * m * v == d True Some pathological cases that crashed earlier versions:: - sage: m = Matrix(OE, [[2*w,2*w-1,-w+1],[2*w+2,-2*w-1,w-1],[-2*w-1,-2*w-2,2*w-1]]); d, u, v = m.smith_form(); u * m * v == d + sage: m = Matrix(OE, [[ 2*w, 2*w - 1, -w + 1], # optional - sage.rings.number_field + ....: [ 2*w + 2, -2*w - 1, w - 1], + ....: [-2*w - 1, -2*w - 2, 2*w - 1]]) + sage: d, u, v = m.smith_form(); u * m * v == d # optional - sage.rings.number_field True - sage: m = matrix(OE, 3, 3, [-5*w-1,-2*w-2,4*w-10,8*w,-w,w-1,-1,1,-8]); d,u,v = m.smith_form(); u*m*v == d + sage: m = matrix(OE, [[-5*w - 1, -2*w - 2, 4*w - 10], # optional - sage.rings.number_field + ....: [ 8*w, -w, w - 1], + ....: [ -1, 1, -8]]) + sage: d, u, v = m.smith_form(); u * m * v == d # optional - sage.rings.number_field True Over local fields, we can request the transformation matrices to be integral:; - sage: K = Qp(2, 5, print_mode='terse') - sage: M = matrix(K, 2, 3, [1/2, 1, 2, 1/3, 1, 3]) - sage: M.smith_form(integral=True) + sage: K = Qp(2, 5, print_mode='terse') # optional - sage.rings.padics + sage: M = matrix(K, 2, 3, [1/2, 1, 2, 1/3, 1, 3]) # optional - sage.rings.padics + sage: M.smith_form(integral=True) # optional - sage.rings.padics ( [1/2 + O(2^4) 0 0] [ 1 + O(2^5) 0] [ 0 1 + O(2^5) 0], [42 + O(2^6) 1 + O(2^5)], @@ -15849,31 +15946,32 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = FunctionField(GF(7),'x').maximal_order() - sage: K. = FunctionField(GF(7)); M = K.maximal_order() - sage: A = matrix(M, 2, 3, [x, 1, 2*x, x, 1+x, 2]) - sage: A.hermite_form() + sage: M = FunctionField(GF(7), 'x').maximal_order() # optional - sage.rings.finite_rings + sage: K. = FunctionField(GF(7)); M = K.maximal_order() # optional - sage.rings.finite_rings + sage: A = matrix(M, 2, 3, [x, 1, 2*x, x, 1 + x, 2]) # optional - sage.rings.finite_rings + sage: A.hermite_form() # optional - sage.rings.finite_rings [ x 1 2*x] [ 0 x 5*x + 2] - sage: A.hermite_form(transformation=True) + sage: A.hermite_form(transformation=True) # optional - sage.rings.finite_rings ( [ x 1 2*x] [1 0] [ 0 x 5*x + 2], [6 1] ) - sage: A = matrix(M, 2, 3, [x, 1, 2*x, 2*x, 2, 4*x]) - sage: A.hermite_form(transformation=True, include_zero_rows=False) + sage: A = matrix(M, 2, 3, [x, 1, 2*x, 2*x, 2, 4*x]) # optional - sage.rings.finite_rings + sage: A.hermite_form(transformation=True, include_zero_rows=False) # optional - sage.rings.finite_rings ([ x 1 2*x], [1 0]) - sage: H, U = A.hermite_form(transformation=True, include_zero_rows=True); H, U + sage: H, U = A.hermite_form(transformation=True, include_zero_rows=True) # optional - sage.rings.finite_rings + sage: H, U ( [ x 1 2*x] [1 0] [ 0 0 0], [5 1] ) - sage: U*A == H + sage: U * A == H # optional - sage.rings.finite_rings True - sage: H, U = A.hermite_form(transformation=True, include_zero_rows=False) - sage: U*A + sage: H, U = A.hermite_form(transformation=True, include_zero_rows=False) # optional - sage.rings.finite_rings + sage: U * A # optional - sage.rings.finite_rings [ x 1 2*x] - sage: U*A == H + sage: U * A == H # optional - sage.rings.finite_rings True """ left, H, pivots = self._echelon_form_PID() @@ -15900,57 +15998,57 @@ cdef class Matrix(Matrix1): column pivot. EXAMPLES:: - sage: L. = NumberField(x^3 - 2) - sage: OL = L.ring_of_integers() + sage: L. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: OL = L.ring_of_integers() # optional - sage.rings.number_field We check some degenerate cases:: - sage: m = matrix(OL, 0, 0, []); r,s,p = m._echelon_form_PID() - sage: (r,s,p) + sage: m = matrix(OL, 0, 0, []); r,s,p = m._echelon_form_PID() # optional - sage.rings.number_field + sage: (r,s,p) # optional - sage.rings.number_field ([], [], []) - sage: r * m == s and r.det() == 1 + sage: r * m == s and r.det() == 1 # optional - sage.rings.number_field True - sage: m = matrix(OL, 0, 1, []); r,s,p = m._echelon_form_PID() - sage: (r,s,p) + sage: m = matrix(OL, 0, 1, []); r,s,p = m._echelon_form_PID() # optional - sage.rings.number_field + sage: (r,s,p) # optional - sage.rings.number_field ([], [], []) - sage: r * m == s and r.det() == 1 + sage: r * m == s and r.det() == 1 # optional - sage.rings.number_field True - sage: m = matrix(OL, 1, 0, []); r,s,p = m._echelon_form_PID() - sage: (r,s,p) + sage: m = matrix(OL, 1, 0, []); r,s,p = m._echelon_form_PID() # optional - sage.rings.number_field + sage: (r,s,p) # optional - sage.rings.number_field ([1], [], []) - sage: r * m == s and r.det() == 1 + sage: r * m == s and r.det() == 1 # optional - sage.rings.number_field True A 2x2 matrix:: - sage: m = matrix(OL, 2, 2, [1,0, a, 2]) - sage: r,s,p = m._echelon_form_PID(); (r,s,p) + sage: m = matrix(OL, 2, 2, [1, 0, a, 2]) # optional - sage.rings.number_field + sage: r,s,p = m._echelon_form_PID(); (r,s,p) # optional - sage.rings.number_field ( [ 1 0] [1 0] [-a 1], [0 2], [0, 1] ) - sage: r * m == s and r.det() == 1 + sage: r * m == s and r.det() == 1 # optional - sage.rings.number_field True A larger example:: - sage: m = matrix(OL, 3, 5, [a^2 - 3*a - 1, a^2 - 3*a + 1, a^2 + 1, + sage: m = matrix(OL, 3, 5, [a^2 - 3*a - 1, a^2 - 3*a + 1, a^2 + 1, # optional - sage.rings.number_field ....: -a^2 + 2, -3*a^2 - a - 1, -6*a - 1, a^2 - 3*a - 1, ....: 2*a^2 + a + 5, -2*a^2 + 5*a + 1, -a^2 + 13*a - 3, ....: -2*a^2 + 4*a - 2, -2*a^2 + 1, 2*a, a^2 - 6, 3*a^2 - a ]) - sage: r,s,p = m._echelon_form_PID() - sage: s[2] + sage: r,s,p = m._echelon_form_PID() # optional - sage.rings.number_field + sage: s[2] # optional - sage.rings.number_field (0, 0, -3*a^2 - 18*a + 34, -68*a^2 + 134*a - 53, -111*a^2 + 275*a - 90) - sage: r * m == s and r.det() == 1 + sage: r * m == s and r.det() == 1 # optional - sage.rings.number_field True We verify that :trac:`9053` is resolved:: - sage: R. = GF(7)[] - sage: A = R^3 - sage: L = A.span([x*A.0 + (x^3 + 1)*A.1, x*A.2]) - sage: M = A.span([x*L.0]) - sage: M.0 in L + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: A = R^3 # optional - sage.rings.finite_rings + sage: L = A.span([x*A.0 + (x^3 + 1)*A.1, x*A.2]) # optional - sage.rings.finite_rings + sage: M = A.span([x*L.0]) # optional - sage.rings.finite_rings + sage: M.0 in L # optional - sage.rings.finite_rings True """ @@ -16373,7 +16471,7 @@ cdef class Matrix(Matrix1): sage: U.inverse()*B*U == Z True - sage: A.jordan_form() == B.jordan_form() + sage: A.jordan_form() == B.jordan_form() # optional - sage.combinat True Two more examples, illustrating the two extremes of the zig-zag @@ -16434,38 +16532,38 @@ cdef class Matrix(Matrix1): sage: U.inverse()*D*U == Z True - sage: C.jordan_form() == D.jordan_form() + sage: C.jordan_form() == D.jordan_form() # optional - sage.combinat True ZigZag form is achieved entirely with the operations of the field, so while the eigenvalues may lie outside the field, this does not impede the computation of the form. :: - sage: F. = GF(5^4) - sage: A = matrix(F, [[ a, 0, 0, a + 3], + sage: F. = GF(5^4) # optional - sage.rings.finite_rings + sage: A = matrix(F, [[ a, 0, 0, a + 3], # optional - sage.rings.finite_rings ....: [ 0,a^2 + 1, 0, 0], ....: [ 0, 0,a^3, 0], ....: [a^2 +4 , 0, 0,a + 2]]) - sage: A.zigzag_form() + sage: A.zigzag_form() # optional - sage.rings.finite_rings [ 0 a^3 + 2*a^2 + 2*a + 2| 0| 0] [ 1 2*a + 2| 0| 0] [-------------------------------------------+---------------------+---------------------] [ 0 0| a^3| 0] [-------------------------------------------+---------------------+---------------------] [ 0 0| 0| a^2 + 1] - sage: A.eigenvalues() + sage: A.eigenvalues() # optional - sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: algebraic closures of finite fields are only implemented for prime fields Subdivisions are optional. :: - sage: F. = GF(5^4) - sage: A = matrix(F, [[ a, 0, 0, a + 3], + sage: F. = GF(5^4) # optional - sage.rings.finite_rings + sage: A = matrix(F, [[ a, 0, 0, a + 3], # optional - sage.rings.finite_rings ....: [ 0,a^2 + 1, 0, 0], ....: [ 0, 0,a^3, 0], ....: [a^2 +4 , 0, 0,a + 2]]) - sage: A.zigzag_form(subdivide=False) + sage: A.zigzag_form(subdivide=False) # optional - sage.rings.finite_rings [ 0 a^3 + 2*a^2 + 2*a + 2 0 0] [ 1 2*a + 2 0 0] [ 0 0 a^3 0] @@ -16636,13 +16734,13 @@ cdef class Matrix(Matrix1): sage: invariants [[4, -4, 1], [-12, 4, 9, -6, 1], [216, -108, -306, 271, 41, -134, 64, -13, 1]] sage: polys = [R(p) for p in invariants] - sage: [p.factor() for p in polys] + sage: [p.factor() for p in polys] # optional - sage.rings.finite_rings [(x - 2)^2, (x - 3) * (x + 1) * (x - 2)^2, (x + 1)^2 * (x - 3)^3 * (x - 2)^3] sage: all(polys[i].divides(polys[i+1]) for i in range(len(polys)-1)) True - sage: polys[-1] == A.minimal_polynomial(var='x') + sage: polys[-1] == A.minimal_polynomial(var='x') # optional - sage.libs.pari True - sage: prod(polys) == A.characteristic_polynomial(var='x') + sage: prod(polys) == A.characteristic_polynomial(var='x') # optional - sage.libs.pari True Rational form is a canonical form. Any two matrices are similar @@ -16660,9 +16758,9 @@ cdef class Matrix(Matrix1): ....: [0, -42, 14, 8, 167, -17, -84, 13], ....: [0, -50, 17, 10, 199, -23, -98, 14], ....: [0, 15, -5, -2, -59, 7, 30, -2]]) - sage: C.minimal_polynomial().factor() + sage: C.minimal_polynomial().factor() # optional - sage.libs.pari (x - 2)^2 - sage: C.characteristic_polynomial().factor() + sage: C.characteristic_polynomial().factor() # optional - sage.libs.pari (x - 2)^8 sage: C.rational_form() [ 0 -4| 0 0| 0 0| 0 0] @@ -16685,9 +16783,9 @@ cdef class Matrix(Matrix1): ....: [ 31, -18, 135, 38, 12, 47, 155, -147], ....: [-33, 19, -138, -39, -13, -45, -156, 151], ....: [ -7, 4, -29, -8, -3, -10, -34, 34]]) - sage: D.minimal_polynomial().factor() + sage: D.minimal_polynomial().factor() # optional - sage.libs.pari (x - 2)^2 - sage: D.characteristic_polynomial().factor() + sage: D.characteristic_polynomial().factor() # optional - sage.libs.pari (x - 2)^8 sage: D.rational_form() [ 0 -4| 0 0| 0 0| 0 0] @@ -16710,9 +16808,9 @@ cdef class Matrix(Matrix1): ....: [-3, -7, 5, -6, -1, 5, -4, 14], ....: [ 6, 18, -10, 14, 4, -10, 10, -28], ....: [-2, -6, 4, -5, -1, 3, -3, 13]]) - sage: E.minimal_polynomial().factor() + sage: E.minimal_polynomial().factor() # optional - sage.libs.pari (x - 2)^3 - sage: E.characteristic_polynomial().factor() + sage: E.characteristic_polynomial().factor() # optional - sage.libs.pari (x - 2)^8 sage: E.rational_form() [ 2| 0 0| 0 0| 0 0 0] @@ -16749,9 +16847,9 @@ cdef class Matrix(Matrix1): ....: [ 139, -35, 99, -49, -18, 236, -41, -70, 370, -118, -377, -619], ....: [ 243, 9, 81, -72, -81, 386, 43, -105, 508, -124, -564, -911], ....: [-155, -3, -55, 45, 50, -245, -27, 65, -328, 77, 365, 583]]) - sage: A.characteristic_polynomial().factor() + sage: A.characteristic_polynomial().factor() # optional - sage.libs.pari (x^2 - 2)^2 * (x^2 + 2*x + 5)^4 - sage: A.eigenvalues(extend=False) + sage: A.eigenvalues(extend=False) # optional - sage.rings.number_field [] sage: A.rational_form() [ 0 -5| 0 0 0 0| 0 0 0 0 0 0] @@ -16770,14 +16868,14 @@ cdef class Matrix(Matrix1): [ 0 0| 0 0 0 0| 0 0 0 0 1 -4] sage: F. = QQ[] sage: polys = A.rational_form(format='invariants') - sage: [F(p).factor() for p in polys] + sage: [F(p).factor() for p in polys] # optional - sage.libs.pari [x^2 + 2*x + 5, (x^2 - 2) * (x^2 + 2*x + 5), (x^2 - 2) * (x^2 + 2*x + 5)^2] Rational form may be computed over any field. The matrix below is an example where the eigenvalues lie outside the field. :: - sage: F. = FiniteField(7^2) - sage: A = matrix(F, + sage: F. = FiniteField(7^2) # optional - sage.rings.finite_rings + sage: A = matrix(F, # optional - sage.rings.finite_rings ....: [[5*a + 3, 4*a + 1, 6*a + 2, 2*a + 5, 6, 4*a + 5, 4*a + 5, 5, a + 6, 5, 4*a + 4], ....: [6*a + 3, 2*a + 4, 0, 6, 5*a + 5, 2*a, 5*a + 1, 1, 5*a + 2, 4*a, 5*a + 6], ....: [3*a + 1, 6*a + 6, a + 6, 2, 0, 3*a + 6, 5*a + 4, 5*a + 6, 5*a + 2, 3, 4*a + 2], @@ -16789,7 +16887,7 @@ cdef class Matrix(Matrix1): ....: [3*a + 5, 6*a + 2, 4*a, a + 5, 0, 5*a, 6*a + 5, 2*a + 1, 3*a + 1, 3*a + 5, 4*a + 2], ....: [3*a + 2, a + 3, 3*a + 6, a, 3*a + 5, 5*a + 1, 3*a + 2, a + 3, a + 2, 6*a + 1, 3*a + 3], ....: [6*a + 6, 5*a + 1, 4*a, 2, 5*a + 5, 3*a + 5, 3*a + 1, 2*a, 2*a, 2*a + 4, 4*a + 2]]) - sage: A.rational_form() + sage: A.rational_form() # optional - sage.rings.finite_rings [ a + 2| 0 0 0| 0 0 0 0 0 0 0] [-------+-----------------------+-------------------------------------------------------] [ 0| 0 0 a + 6| 0 0 0 0 0 0 0] @@ -16803,18 +16901,18 @@ cdef class Matrix(Matrix1): [ 0| 0 0 0| 0 0 0 1 0 0 a + 6] [ 0| 0 0 0| 0 0 0 0 1 0 2*a + 1] [ 0| 0 0 0| 0 0 0 0 0 1 2*a + 1] - sage: invariants = A.rational_form(format='invariants') - sage: invariants + sage: invariants = A.rational_form(format='invariants') # optional - sage.rings.finite_rings + sage: invariants # optional - sage.rings.finite_rings [[6*a + 5, 1], [6*a + 1, a + 3, a + 3, 1], [5*a, a + 4, a + 6, 6*a + 5, 6*a + 1, 5*a + 6, 5*a + 6, 1]] - sage: R. = F[] - sage: polys = [R(p) for p in invariants] - sage: [p.factor() for p in polys] + sage: R. = F[] # optional - sage.rings.finite_rings + sage: polys = [R(p) for p in invariants] # optional - sage.rings.finite_rings + sage: [p.factor() for p in polys] # optional - sage.rings.finite_rings [x + 6*a + 5, (x + 6*a + 5) * (x^2 + (2*a + 5)*x + 5*a), (x + 6*a + 5) * (x^2 + (2*a + 5)*x + 5*a)^3] - sage: polys[-1] == A.minimal_polynomial() + sage: polys[-1] == A.minimal_polynomial() # optional - sage.rings.finite_rings True - sage: prod(polys) == A.characteristic_polynomial() + sage: prod(polys) == A.characteristic_polynomial() # optional - sage.rings.finite_rings True - sage: A.eigenvalues() + sage: A.eigenvalues() # optional - sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: algebraic closures of finite fields are only implemented for prime fields @@ -17011,46 +17109,47 @@ cdef class Matrix(Matrix1): Nonnegative matrices are positive operators on the nonnegative orthant:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = random_matrix(QQ,3).apply_map(abs) - sage: L.is_positive_operator_on(K) + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = random_matrix(QQ, 3).apply_map(abs) + sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron True Symbolic entries also work in some easy cases:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = matrix(SR, [ [0, e, 0 ], + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = matrix(SR, [ [0, e, 0 ], # optional - sage.symbolic ....: [0, 2, pi], ....: [sqrt(2), 0, 0 ] ]) - sage: L.is_positive_operator_on(K) + sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron sage.symbolic True Your matrix can be over any exact ring, for example the ring of univariate polynomials with rational coefficients:: - sage: K = Cone([(1,0),(-1,0),(0,1),(0,-1)]) - sage: K.is_full_space() + sage: K = Cone([(1,0), (-1,0), (0,1), (0,-1)]) # optional - sage.geometry.polyhedron + sage: K.is_full_space() # optional - sage.geometry.polyhedron True + sage: x = polygen(ZZ, 'x') sage: L = matrix(QQ[x], [[x,0],[0,1]]) - sage: L.is_positive_operator_on(K) + sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron True TESTS: The identity matrix is always a positive operator:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = identity_matrix(R, K.lattice_dim()) - sage: L.is_positive_operator_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = identity_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron True The zero matrix is always a positive operator:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = zero_matrix(R, K.lattice_dim()) - sage: L.is_positive_operator_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = zero_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron True Everything in ``K1.positive_operators_gens(K2)`` should be @@ -17058,11 +17157,11 @@ cdef class Matrix(Matrix1): the underlying ring symbolic (the usual case is tested by the ``positive_operators_gens`` method):: - sage: K1 = random_cone(max_ambient_dim=5) - sage: K2 = random_cone(max_ambient_dim=5) - sage: results = ( L.change_ring(SR).is_positive_operator_on(K1, K2) + sage: K1 = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron + sage: K2 = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron + sage: results = ( L.change_ring(SR).is_positive_operator_on(K1, K2) # optional - sage.geometry.polyhedron sage.symbolic ....: for L in K1.positive_operators_gens(K2) ) - sage: all(results) # long time + sage: all(results) # long time # optional - sage.geometry.polyhedron sage.symbolic True Technically we could test this, but for now only closed convex cones @@ -17077,9 +17176,9 @@ cdef class Matrix(Matrix1): We can't give reliable answers over inexact rings:: - sage: K = Cone([(1,2,3), (4,5,6)]) - sage: L = identity_matrix(RR,3) - sage: L.is_positive_operator_on(K) + sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: L = identity_matrix(RR, 3) + sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron Traceback (most recent call last): ... ValueError: The base ring of the matrix is neither symbolic nor @@ -17087,11 +17186,11 @@ cdef class Matrix(Matrix1): Symbolic subrings are fine:: - sage: SCR = SR.subring(no_variables=True); SCR + sage: SCR = SR.subring(no_variables=True); SCR # optional - sage.symbolic Symbolic Constants Subring - sage: K = Cone([(1,2,3), (4,5,6)]) - sage: L = identity_matrix(SCR, 3) - sage: L.is_positive_operator_on(K) + sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: L = identity_matrix(SCR, 3) # optional - sage.symbolic + sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron sage.symbolic True """ import sage.geometry.abc @@ -17169,38 +17268,38 @@ cdef class Matrix(Matrix1): Negative Z-matrices are cross-positive operators on the nonnegative orthant:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = matrix(SR, [ [-1, 2, 0], + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = matrix(SR, [ [-1, 2, 0], # optional - sage.symbolic ....: [ 0, 2, 7], ....: [ 3, 0, 3] ]) - sage: L.is_cross_positive_on(K) + sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron sage.symbolic True Symbolic entries also work in some easy cases:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = matrix(SR, [ [-1, e, 0 ], + sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = matrix(SR, [ [-1, e, 0 ], # optional - sage.symbolic ....: [ 0, 2, pi], ....: [ sqrt(2), 0, 3 ] ]) - sage: L.is_cross_positive_on(K) + sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron sage.symbolic True TESTS: The identity matrix is always cross-positive:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = identity_matrix(R, K.lattice_dim()) - sage: L.is_cross_positive_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = identity_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron True The zero matrix is always cross-positive:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = zero_matrix(R, K.lattice_dim()) - sage: L.is_cross_positive_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = zero_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron True Everything in ``K.cross_positive_operators_gens()`` should be @@ -17208,10 +17307,10 @@ cdef class Matrix(Matrix1): symbolic (the usual case is tested by the ``cross_positive_operators_gens`` method):: - sage: K = random_cone(max_ambient_dim=5) - sage: results = ( L.change_ring(SR).is_cross_positive_on(K) + sage: K = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron + sage: results = ( L.change_ring(SR).is_cross_positive_on(K) # optional - sage.geometry.polyhedron sage.symbolic ....: for L in K.cross_positive_operators_gens() ) - sage: all(results) # long time + sage: all(results) # long time # optional - sage.geometry.polyhedron sage.symbolic True Technically we could test this, but for now only closed convex cones @@ -17226,9 +17325,9 @@ cdef class Matrix(Matrix1): We can't give reliable answers over inexact rings:: - sage: K = Cone([(1,2,3), (4,5,6)]) - sage: L = identity_matrix(RR,3) - sage: L.is_cross_positive_on(K) + sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: L = identity_matrix(RR, 3) + sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron Traceback (most recent call last): ... ValueError: The base ring of the matrix is neither symbolic nor @@ -17236,11 +17335,11 @@ cdef class Matrix(Matrix1): Symbolic subrings are fine:: - sage: SCR = SR.subring(no_variables=True); SCR + sage: SCR = SR.subring(no_variables=True); SCR # optional - sage.symbolic Symbolic Constants Subring - sage: K = Cone([(1,2,3), (4,5,6)]) - sage: L = identity_matrix(SCR, 3) - sage: L.is_cross_positive_on(K) + sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: L = identity_matrix(SCR, 3) # optional - sage.symbolic + sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron sage.symbolic True """ import sage.geometry.abc @@ -17307,46 +17406,46 @@ cdef class Matrix(Matrix1): Z-matrices are Z-operators on the nonnegative orthant:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = matrix(SR, [ [-1, -2, 0], + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = matrix(SR, [ [-1, -2, 0], # optional - sage.symbolic ....: [ 0, 2, -7], ....: [-3, 0, 3] ]) - sage: L.is_Z_operator_on(K) + sage: L.is_Z_operator_on(K) # optional - sage.geometry.polyhedron sage.symbolic True Symbolic entries also work in some easy cases:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = matrix(SR, [ [-1, -e, 0 ], + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = matrix(SR, [ [-1, -e, 0 ], # optional - sage.symbolic ....: [ 0, 2, -pi], ....: [-sqrt(2), 0, 3 ] ]) - sage: L.is_Z_operator_on(K) + sage: L.is_Z_operator_on(K) # optional - sage.geometry.polyhedron sage.symbolic True TESTS: The identity matrix is always a Z-operator:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = identity_matrix(R, K.lattice_dim()) - sage: L.is_Z_operator_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = identity_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_Z_operator_on(K) # optional - sage.geometry.polyhedron True The zero matrix is always a Z-operator:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = zero_matrix(R, K.lattice_dim()) - sage: L.is_Z_operator_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = zero_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_Z_operator_on(K) # optional - sage.geometry.polyhedron True Everything in ``K.Z_operators_gens()`` should be a Z-operator on ``K``, , even if we make the underlying ring symbolic (the usual case is tested by the ``Z_operators_gens`` method):: - sage: K = random_cone(max_ambient_dim=5) - sage: all(L.change_ring(SR).is_Z_operator_on(K) # long time + sage: K = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron + sage: all(L.change_ring(SR).is_Z_operator_on(K) # long time # optional - sage.geometry.polyhedron sage.symbolic ....: for L in K.Z_operators_gens()) True @@ -17362,9 +17461,9 @@ cdef class Matrix(Matrix1): We can't give reliable answers over inexact rings:: - sage: K = Cone([(1,2,3), (4,5,6)]) - sage: L = identity_matrix(RR,3) - sage: L.is_Z_operator_on(K) + sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: L = identity_matrix(RR, 3) + sage: L.is_Z_operator_on(K) # optional - sage.geometry.polyhedron Traceback (most recent call last): ... ValueError: The base ring of the matrix is neither symbolic nor @@ -17426,36 +17525,36 @@ cdef class Matrix(Matrix1): Diagonal matrices are Lyapunov-like operators on the nonnegative orthant:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = diagonal_matrix(random_vector(QQ,3)) - sage: L.is_lyapunov_like_on(K) + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = diagonal_matrix(random_vector(QQ, 3)) + sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron True Symbolic entries also work in some easy cases:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = matrix(SR, [ [e, 0, 0 ], + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = matrix(SR, [ [e, 0, 0 ], # optional - sage.symbolic ....: [0, pi, 0 ], ....: [0, 0, sqrt(2)] ]) - sage: L.is_lyapunov_like_on(K) + sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron sage.symbolic True TESTS: The identity matrix is always Lyapunov-like:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = identity_matrix(R, K.lattice_dim()) - sage: L.is_lyapunov_like_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = identity_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron True The zero matrix is always Lyapunov-like:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = zero_matrix(R, K.lattice_dim()) - sage: L.is_lyapunov_like_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = zero_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron True Everything in ``K.lyapunov_like_basis()`` should be @@ -17463,8 +17562,8 @@ cdef class Matrix(Matrix1): symbolic (the usual case is tested by the ``lyapunov_like_basis`` method):: - sage: K = random_cone(max_ambient_dim=5) - sage: all(L.change_ring(SR).is_lyapunov_like_on(K) # long time + sage: K = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron + sage: all(L.change_ring(SR).is_lyapunov_like_on(K) # long time # optional - sage.geometry.polyhedron sage.symbolic ....: for L in K.lyapunov_like_basis()) True @@ -17480,9 +17579,9 @@ cdef class Matrix(Matrix1): We can't give reliable answers over inexact rings:: - sage: K = Cone([(1,2,3), (4,5,6)]) - sage: L = identity_matrix(RR,3) - sage: L.is_lyapunov_like_on(K) + sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: L = identity_matrix(RR, 3) + sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron Traceback (most recent call last): ... ValueError: The base ring of the matrix is neither symbolic nor @@ -17490,23 +17589,23 @@ cdef class Matrix(Matrix1): Symbolic subrings are fine:: - sage: SCR = SR.subring(no_variables=True); SCR + sage: SCR = SR.subring(no_variables=True); SCR # optional - sage.symbolic Symbolic Constants Subring - sage: K = Cone([(1,2,3), (4,5,6)]) - sage: L = identity_matrix(SCR, 3) - sage: L.is_lyapunov_like_on(K) + sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: L = identity_matrix(SCR, 3) # optional - sage.symbolic + sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron sage.symbolic True A matrix is Lyapunov-like on a cone if and only if both the matrix and its negation are cross-positive on the cone:: - sage: K = random_cone(max_ambient_dim=5) - sage: R = K.lattice().vector_space().base_ring() - sage: L = random_matrix(R, K.lattice_dim()) - sage: actual = L.is_lyapunov_like_on(K) # long time - sage: expected = (L.is_cross_positive_on(K) and # long time + sage: K = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = random_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: actual = L.is_lyapunov_like_on(K) # long time # optional - sage.geometry.polyhedron + sage: expected = (L.is_cross_positive_on(K) and # long time # optional - sage.geometry.polyhedron ....: (-L).is_cross_positive_on(K)) - sage: actual == expected # long time + sage: actual == expected # long time # optional - sage.geometry.polyhedron True """ import sage.geometry.abc @@ -17567,9 +17666,9 @@ cdef class Matrix(Matrix1): Create a Gram matrix and LLL-reduce it:: sage: M = Matrix(ZZ, 2, 2, [5, 3, 3, 2]) - sage: U = M.LLL_gram() - sage: MM = U.transpose() * M * U - sage: M, U, MM + sage: U = M.LLL_gram() # optional - sage.libs.pari + sage: MM = U.transpose() * M * U # optional - sage.libs.pari + sage: M, U, MM # optional - sage.libs.pari ( [5 3] [-1 1] [1 0] [3 2], [ 1 -2], [0 1] @@ -17581,28 +17680,28 @@ cdef class Matrix(Matrix1): preserve orientation). :: sage: M = Matrix(RDF, 2, 2, [1, 0, 0, 1e-5]) - sage: M.LLL_gram() + sage: M.LLL_gram() # optional - sage.libs.pari [ 0 -1] [ 1 0] The algorithm might work for some semidefinite and indefinite forms:: - sage: Matrix(ZZ, 2, 2, [2, 6, 6, 3]).LLL_gram() + sage: Matrix(ZZ, 2, 2, [2, 6, 6, 3]).LLL_gram() # optional - sage.libs.pari [-3 -1] [ 1 0] - sage: Matrix(ZZ, 2, 2, [1, 0, 0, -1]).LLL_gram() + sage: Matrix(ZZ, 2, 2, [1, 0, 0, -1]).LLL_gram() # optional - sage.libs.pari [ 0 -1] [ 1 0] However, it might fail for others, either raising a ``ValueError``:: - sage: Matrix(ZZ, 1, 1, [0]).LLL_gram() + sage: Matrix(ZZ, 1, 1, [0]).LLL_gram() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: qflllgram did not return a square matrix, perhaps the matrix is not positive definite - sage: Matrix(ZZ, 2, 2, [0, 1, 1, 0]).LLL_gram() + sage: Matrix(ZZ, 2, 2, [0, 1, 1, 0]).LLL_gram() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: qflllgram did not return a square matrix, @@ -17610,14 +17709,14 @@ cdef class Matrix(Matrix1): or running forever:: - sage: Matrix(ZZ, 2, 2, [-5, -1, -1, -5]).LLL_gram() # not tested + sage: Matrix(ZZ, 2, 2, [-5, -1, -1, -5]).LLL_gram() # not tested # optional - sage.libs.pari Traceback (most recent call last): ... RuntimeError: infinite loop while calling qflllgram Nonreal input leads to a value error:: - sage: Matrix(2, 2, [CDF(1, 1), 0, 0, 1]).LLL_gram() + sage: Matrix(2, 2, [CDF(1, 1), 0, 0, 1]).LLL_gram() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: qflllgram failed, perhaps the matrix is not positive definite @@ -17671,10 +17770,10 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQbar, [[ -3, 5 - 3*I, 7 - 4*I], + sage: A = matrix(QQbar, [[ -3, 5 - 3*I, 7 - 4*I], # optional - sage.rings.number_field ....: [7 + 3*I, -1 + 6*I, 3 + 5*I], ....: [3 + 3*I, -3 + 6*I, 5 + I]]) - sage: A.C + sage: A.C # optional - sage.rings.number_field [ -3 5 + 3*I 7 + 4*I] [ 7 - 3*I -1 - 6*I 3 - 5*I] [ 3 - 3*I -3 - 6*I 5 - 1*I] @@ -17689,10 +17788,10 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQbar, [[ -3, 5 - 3*I, 7 - 4*I], + sage: A = matrix(QQbar, [[ -3, 5 - 3*I, 7 - 4*I], # optional - sage.rings.number_field ....: [7 + 3*I, -1 + 6*I, 3 + 5*I], ....: [3 + 3*I, -3 + 6*I, 5 + I]]) - sage: A.H + sage: A.H # optional - sage.rings.number_field [ -3 7 - 3*I 3 - 3*I] [ 5 + 3*I -1 - 6*I -3 - 6*I] [ 7 + 4*I 3 - 5*I 5 - 1*I] @@ -17712,19 +17811,19 @@ def _smith_diag(d, transformation=True): EXAMPLES:: sage: from sage.matrix.matrix2 import _smith_diag - sage: OE = EquationOrder(x^2 - x + 2, 'w') - sage: A = matrix(OE, 2, [2,0,0,3]) - sage: D,U,V = _smith_diag(A); D,U,V + sage: OE = EquationOrder(x^2 - x + 2, 'w') # optional - sage.rings.number_field + sage: A = matrix(OE, 2, [2, 0, 0, 3]) # optional - sage.rings.number_field + sage: D,U,V = _smith_diag(A); D,U,V # optional - sage.rings.number_field ( [1 0] [2 1] [ 1 -3] [0 6], [3 2], [-1 4] ) - sage: D == U*A*V + sage: D == U*A*V # optional - sage.rings.number_field True - sage: m = matrix(GF(7),2, [3,0,0,6]); d,u,v = _smith_diag(m); d + sage: m = matrix(GF(7), 2, [3,0,0,6]); d,u,v = _smith_diag(m); d # optional - sage.rings.finite_rings [1 0] [0 1] - sage: u*m*v == d + sage: u*m*v == d # optional - sage.rings.finite_rings True """ @@ -17788,12 +17887,12 @@ def _generic_clear_column(m): EXAMPLES:: - sage: L. = NumberField(x^2 - x + 2) - sage: OL = L.ring_of_integers(); w = OL(w) - sage: m = matrix(OL, 8, 4, [2*w - 2, 2*w + 1, -2, w, 2, -2,-2*w - 2, -2*w + 2, -w + 2, 2*w + 1, -w + 2, -w - 2, -2*w, 2*w, -w+ 2, w - 1, -2*w + 2, 2*w + 2, 2*w - 1, -w, 2*w + 2, -w + 2, 2, 2*w -1, w - 4, -2*w - 2, 2*w - 1, 0, 6, 7, 2*w + 1, 14]) - sage: s,t = m.echelon_form(transformation=True); t*m == s # indirect doctest + sage: L. = NumberField(x^2 - x + 2) # optional - sage.rings.number_field + sage: OL = L.ring_of_integers(); w = OL(w) # optional - sage.rings.number_field + sage: m = matrix(OL, 8, 4, [2*w - 2, 2*w + 1, -2, w, 2, -2,-2*w - 2, -2*w + 2, -w + 2, 2*w + 1, -w + 2, -w - 2, -2*w, 2*w, -w+ 2, w - 1, -2*w + 2, 2*w + 2, 2*w - 1, -w, 2*w + 2, -w + 2, 2, 2*w -1, w - 4, -2*w - 2, 2*w - 1, 0, 6, 7, 2*w + 1, 14]) # optional - sage.rings.number_field + sage: s,t = m.echelon_form(transformation=True); t*m == s # indirect doctest # optional - sage.rings.number_field True - sage: s[0] + sage: s[0] # optional - sage.rings.number_field (w, 0, 0, 0) """ if m.nrows() <= 1 or m.ncols() <= 0: @@ -17895,13 +17994,13 @@ def _smith_onestep(m): EXAMPLES:: sage: from sage.matrix.matrix2 import _smith_onestep - sage: OE. = EquationOrder(x^2 - x + 2) - sage: m = matrix(OE, 3,3,[1,0,7,2,w, w+17, 13+8*w, 0, 6]) - sage: a,b,c = _smith_onestep(m); b + sage: OE. = EquationOrder(x^2 - x + 2) # optional - sage.rings.number_field + sage: m = matrix(OE, 3, 3, [1, 0, 7, 2, w, w+17, 13+8*w, 0, 6]) # optional - sage.rings.number_field + sage: a,b,c = _smith_onestep(m); b # optional - sage.rings.number_field [ 1 0 0] [ 0 w w + 3] [ 0 0 -56*w - 85] - sage: a * m * c == b + sage: a * m * c == b # optional - sage.rings.number_field True """ @@ -18099,27 +18198,27 @@ def _matrix_power_symbolic(A, n): General power of a two by two matrix:: - sage: n = SR.var('n') + sage: n = SR.var('n') # optional - sage.symbolic sage: A = matrix(QQ, [[2, -1], [1, 0]]) - sage: B = A^n; B + sage: B = A^n; B # optional - sage.symbolic [ n + 1 -n] [ n -n + 1] - sage: all(A^k == B.subs({n: k}) for k in range(8)) + sage: all(A^k == B.subs({n: k}) for k in range(8)) # optional - sage.symbolic True General power of a three by three matrix in Jordan form:: - sage: n = SR.var('n') + sage: n = SR.var('n') # optional - sage.symbolic sage: A = matrix(QQ, 3, [[2, 1, 0], [0, 2, 0], [0, 0, 3]]) sage: A [2 1 0] [0 2 0] [0 0 3] - sage: B = A^n; B + sage: B = A^n; B # optional - sage.symbolic [ 2^n 2^(n - 1)*n 0] [ 0 2^n 0] [ 0 0 3^n] - sage: all(A^k == B.subs({n: k}) for k in range(8)) + sage: all(A^k == B.subs({n: k}) for k in range(8)) # optional - sage.symbolic True General power of a three by three matrix not in Jordan form:: @@ -18129,26 +18228,26 @@ def _matrix_power_symbolic(A, n): [ 4 1 2] [ 0 2 -4] [ 0 1 6] - sage: B = A^n; B + sage: B = A^n; B # optional - sage.symbolic [ 4^n 4^(n - 1)*n 2*4^(n - 1)*n] [ 0 -2*4^(n - 1)*n + 4^n -4*4^(n - 1)*n] [ 0 4^(n - 1)*n 2*4^(n - 1)*n + 4^n] - sage: [B.subs({n: k}) for k in range(4)] + sage: [B.subs({n: k}) for k in range(4)] # optional - sage.symbolic [ [1 0 0] [ 4 1 2] [ 16 8 16] [ 64 48 96] [0 1 0] [ 0 2 -4] [ 0 0 -32] [ 0 -32 -192] [0 0 1], [ 0 1 6], [ 0 8 32], [ 0 48 160] ] - sage: all(A^k == B.subs({n: k}) for k in range(8)) + sage: all(A^k == B.subs({n: k}) for k in range(8)) # optional - sage.symbolic True TESTS: Testing exponentiation in the symbolic ring:: - sage: n = var('n') - sage: A = matrix([[pi, e],[0, -2*I]]) - sage: (A^n).list() + sage: n = var('n') # optional - sage.symbolic + sage: A = matrix([[pi, e],[0, -2*I]]) # optional - sage.symbolic + sage: (A^n).list() # optional - sage.symbolic [pi^n, -(-2*I)^n/(pi*e^(-1) + 2*I*e^(-1)) + pi^n/(pi*e^(-1) + 2*I*e^(-1)), 0, @@ -18164,15 +18263,15 @@ def _matrix_power_symbolic(A, n): Testing exponentiation in the integer ring:: - sage: A = matrix(ZZ, [[1,-1],[-1,1]]) + sage: A = matrix(ZZ, [[1,-1], [-1,1]]) sage: A^(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)] Check if :trac:`23215` is fixed:: - sage: a, b, k = var('a, b, k') - sage: (matrix(2, [a, b, -b, a])^k).list() + sage: a, b, k = var('a, b, k') # optional - sage.symbolic + sage: (matrix(2, [a, b, -b, a])^k).list() # optional - sage.symbolic [1/2*(a + I*b)^k + 1/2*(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*I*(a - I*b)^k, diff --git a/src/sage/matrix/matrix_cdv.pyx b/src/sage/matrix/matrix_cdv.pyx index 43421c74cb9..c67936f6e4c 100644 --- a/src/sage/matrix/matrix_cdv.pyx +++ b/src/sage/matrix/matrix_cdv.pyx @@ -35,29 +35,31 @@ cpdef hessenbergize_cdvf(Matrix_generic_dense H): TESTS:: - sage: K = Qp(5, print_mode="digits", prec=5) - sage: H = matrix(K, 3, 3, range(9)) - sage: H + sage: K = Qp(5, print_mode="digits", prec=5) # optional - sage.rings.padics + sage: H = matrix(K, 3, 3, range(9)) # optional - sage.rings.padics + sage: H # optional - sage.rings.padics [ 0 ...00001 ...00002] [ ...00003 ...00004 ...000010] [ ...00011 ...00012 ...00013] - sage: H.hessenbergize() - sage: H + sage: H.hessenbergize() # optional - sage.rings.padics + sage: H # optional - sage.rings.padics [ 0 ...00010 ...00002] [ ...00003 ...00024 ...000010] [ ...00000 ...44440 ...44443] :: - sage: M = random_matrix(K, 6, 6) - sage: M.charpoly()[0] == M.determinant() + sage: M = random_matrix(K, 6, 6) # optional - sage.rings.padics + sage: M.charpoly()[0] == M.determinant() # optional - sage.rings.padics True We check that :trac:`31753` is resolved:: - sage: R. = GF(5)[[]] - sage: M = matrix(3, 3, [ 1, t + O(t^3), t^2, 1 + t + O(t^3), 2 + t^2, 3 + 2*t + O(t^3), t - t^2, 2*t, 1 + t ]) - sage: M.charpoly() + sage: R. = GF(5)[[]] # optional - sage.libs.pari + sage: M = matrix(3, 3, [ 1, t + O(t^3), t^2, # optional - sage.libs.pari + ....: 1 + t + O(t^3), 2 + t^2, 3 + 2*t + O(t^3), + ....: t - t^2, 2*t, 1 + t ]) + sage: M.charpoly() # optional - sage.libs.pari x^3 + (1 + 4*t + 4*t^2 + O(t^3))*x^2 + (t + 2*t^2 + O(t^3))*x + 3 + 2*t^2 + O(t^3) """ cdef Py_ssize_t n, i, j, k diff --git a/src/sage/matrix/matrix_dense.pyx b/src/sage/matrix/matrix_dense.pyx index afc24c658e6..65d528f44dd 100644 --- a/src/sage/matrix/matrix_dense.pyx +++ b/src/sage/matrix/matrix_dense.pyx @@ -75,11 +75,11 @@ cdef class Matrix_dense(matrix.Matrix): Check :trac:`27629`:: - sage: var('x') + sage: var('x') # optional - sage.symbolic x - sage: assume(x, 'real') - sage: M = matrix([[0, -x], [x, 0]]) - sage: M.transpose() == M + sage: assume(x, 'real') # optional - sage.symbolic + sage: M = matrix([[0, -x], [x, 0]]) # optional - sage.symbolic + sage: M.transpose() == M # optional - sage.symbolic False """ other = right @@ -271,8 +271,8 @@ cdef class Matrix_dense(matrix.Matrix): EXAMPLES:: - sage: m = matrix(2, [x^i for i in range(4)]) - sage: m._derivative(x) + sage: m = matrix(2, [x^i for i in range(4)]) # optional - sage.symbolic + sage: m._derivative(x) # optional - sage.symbolic [ 0 1] [ 2*x 3*x^2] """ diff --git a/src/sage/matrix/matrix_generic_dense.pyx b/src/sage/matrix/matrix_generic_dense.pyx index 49df19eacbf..313f3c5785c 100644 --- a/src/sage/matrix/matrix_generic_dense.pyx +++ b/src/sage/matrix/matrix_generic_dense.pyx @@ -70,12 +70,12 @@ cdef class Matrix_generic_dense(matrix_dense.Matrix_dense): We check that the problem related to :trac:`9049` is not an issue any more:: - sage: S.=PolynomialRing(QQ) - sage: F.=QQ.extension(t^4+1) - sage: R.=PolynomialRing(F) - sage: M = MatrixSpace(R, 1, 2) + sage: S. = PolynomialRing(QQ) + sage: F. = QQ.extension(t^4 + 1) # optional - sage.rings.number_field + sage: R. = PolynomialRing(F) # optional - sage.rings.number_field + sage: M = MatrixSpace(R, 1, 2) # optional - sage.rings.number_field sage: from sage.matrix.matrix_generic_dense import Matrix_generic_dense - sage: Matrix_generic_dense(M, (x, y), True, True) + sage: Matrix_generic_dense(M, (x, y), True, True) # optional - sage.rings.number_field [x y] """ ma = MatrixArgs_init(parent, entries) @@ -215,10 +215,10 @@ cdef class Matrix_generic_dense(matrix_dense.Matrix_dense): EXAMPLES:: - sage: R. = FreeAlgebra(QQ,2) - sage: a = matrix(R, 2, 2, [1,2,x*y,y*x]) - sage: b = matrix(R, 2, 2, [1,2,y*x,y*x]) - sage: a._add_(b) + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat + sage: a = matrix(R, 2, 2, [1,2,x*y,y*x]) # optional - sage.combinat + sage: b = matrix(R, 2, 2, [1,2,y*x,y*x]) # optional - sage.combinat + sage: a._add_(b) # optional - sage.combinat [ 2 4] [x*y + y*x 2*y*x] """ @@ -238,10 +238,10 @@ cdef class Matrix_generic_dense(matrix_dense.Matrix_dense): EXAMPLES:: - sage: R. = FreeAlgebra(QQ,2) - sage: a = matrix(R, 2, 2, [1,2,x*y,y*x]) - sage: b = matrix(R, 2, 2, [1,2,y*x,y*x]) - sage: a._sub_(b) + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat + sage: a = matrix(R, 2, 2, [1,2,x*y,y*x]) # optional - sage.combinat + sage: b = matrix(R, 2, 2, [1,2,y*x,y*x]) # optional - sage.combinat + sage: a._sub_(b) # optional - sage.combinat [ 0 0] [x*y - y*x 0] """ diff --git a/src/sage/matrix/matrix_generic_sparse.pyx b/src/sage/matrix/matrix_generic_sparse.pyx index a342d5b7353..c84d90fe179 100644 --- a/src/sage/matrix/matrix_generic_sparse.pyx +++ b/src/sage/matrix/matrix_generic_sparse.pyx @@ -4,8 +4,9 @@ Sparse Matrices over a general ring EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: M = MatrixSpace(QQ['x'],2,3,sparse=True); M - Full MatrixSpace of 2 by 3 sparse matrices over Univariate Polynomial Ring in x over Rational Field + sage: M = MatrixSpace(QQ['x'], 2, 3, sparse=True); M + Full MatrixSpace of 2 by 3 sparse matrices over + Univariate Polynomial Ring in x over Rational Field sage: a = M(range(6)); a [0 1 2] [3 4 5] @@ -15,7 +16,7 @@ EXAMPLES:: sage: a * b.transpose() [ 2*x^2 + x 2*x^5 + x^4] [ 5*x^2 + 4*x + 3 5*x^5 + 4*x^4 + 3*x^3] - sage: pari(a)*pari(b.transpose()) + sage: pari(a)*pari(b.transpose()) # optional - sage.libs.pari [2*x^2 + x, 2*x^5 + x^4; 5*x^2 + 4*x + 3, 5*x^5 + 4*x^4 + 3*x^3] sage: c = copy(b); c [ 1 x x^2] @@ -46,7 +47,8 @@ EXAMPLES:: [ 5 x x^2] [x^3 x^4 x^5] sage: parent(d) - Full MatrixSpace of 2 by 3 dense matrices over Univariate Polynomial Ring in x over Rational Field + Full MatrixSpace of 2 by 3 dense matrices + over Univariate Polynomial Ring in x over Rational Field sage: c.sparse_matrix() is c True sage: c.is_sparse() diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index c3fd4d5bf61..5b6469b5b01 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -114,11 +114,11 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix( pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) - sage: M._check_shift_dimension(shifts=[1,3,2]) + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.rings.finite_rings + sage: M._check_shift_dimension(shifts=[1,3,2]) # optional - sage.rings.finite_rings - sage: M._check_shift_dimension(shifts=[1,3,2], row_wise=False) + sage: M._check_shift_dimension(shifts=[1,3,2], row_wise=False) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: shifts length should be the row dimension @@ -140,21 +140,21 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix( pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) - sage: M.degree() + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.rings.finite_rings + sage: M.degree() # optional - sage.rings.finite_rings 3 The zero matrix has degree ``-1``:: - sage: M = Matrix( pR, 2, 3 ) - sage: M.degree() + sage: M = Matrix(pR, 2, 3) # optional - sage.rings.finite_rings + sage: M.degree() # optional - sage.rings.finite_rings -1 For an empty matrix, the degree is not defined:: - sage: M = Matrix( pR, 3, 0 ) - sage: M.degree() + sage: M = Matrix(pR, 3, 0) # optional - sage.rings.finite_rings + sage: M.degree() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: empty matrix does not have a degree @@ -194,20 +194,20 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix( pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) - sage: M.degree_matrix() + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.rings.finite_rings + sage: M.degree_matrix() # optional - sage.rings.finite_rings [ 1 -1 0] [ 3 -1 -1] - sage: M.degree_matrix(shifts=[0,1,2]) + sage: M.degree_matrix(shifts=[0,1,2]) # optional - sage.rings.finite_rings [ 1 -1 2] [ 3 -1 -1] The zero entries in the polynomial matrix can be identified in the (shifted) degree matrix as the entries equal to ``min(shifts)-1``:: - sage: M.degree_matrix(shifts=[-2,1,2]) + sage: M.degree_matrix(shifts=[-2,1,2]) # optional - sage.rings.finite_rings [-1 -3 2] [ 1 -3 -3] @@ -215,7 +215,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): rows of the matrix (which, in terms of modules, means that we are working column-wise, see the class documentation):: - sage: M.degree_matrix(shifts=[-1,2], row_wise=False) + sage: M.degree_matrix(shifts=[-1,2], row_wise=False) # optional - sage.rings.finite_rings [ 0 -2 -1] [ 5 -2 -2] """ @@ -242,14 +242,14 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.rings.finite_rings ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.constant_matrix() + sage: M.constant_matrix() # optional - sage.rings.finite_rings [1 5 4 0] [1 1 2 0] [4 1 5 6] @@ -267,18 +267,18 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.rings.finite_rings ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.is_constant() + sage: M.is_constant() # optional - sage.rings.finite_rings False - sage: M = Matrix(pR,[[1,5,2],[3,1,5]]); M.is_constant() + sage: M = Matrix(pR, [[1,5,2], [3,1,5]]); M.is_constant() # optional - sage.rings.finite_rings True - sage: M = Matrix.zero(pR,3,5); M.is_constant() + sage: M = Matrix.zero(pR, 3, 5); M.is_constant() # optional - sage.rings.finite_rings True .. SEEALSO:: @@ -314,48 +314,48 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.rings.finite_rings ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.coefficient_matrix(2) + sage: M.coefficient_matrix(2) # optional - sage.rings.finite_rings [5 0 0 0] [6 0 0 0] [4 0 2 1] - sage: M.coefficient_matrix(0) == M.constant_matrix() + sage: M.coefficient_matrix(0) == M.constant_matrix() # optional - sage.rings.finite_rings True Row-wise and column-wise coefficient extraction are available:: - sage: M.coefficient_matrix([3,2,1]) + sage: M.coefficient_matrix([3,2,1]) # optional - sage.rings.finite_rings [1 0 0 0] [6 0 0 0] [6 5 5 5] - sage: M.coefficient_matrix([2,0,1,3], row_wise=False) + sage: M.coefficient_matrix([2,0,1,3], row_wise=False) # optional - sage.rings.finite_rings [5 5 6 0] [6 1 0 0] [4 1 5 0] Negative degrees give zero coefficients:: - sage: M.coefficient_matrix([-1,0,1,3], row_wise=False) + sage: M.coefficient_matrix([-1,0,1,3], row_wise=False) # optional - sage.rings.finite_rings [0 5 6 0] [0 1 0 0] [0 1 5 0] Length of list of degrees is checked:: - sage: M.coefficient_matrix([2,1,1,2]) + sage: M.coefficient_matrix([2,1,1,2]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: length of input degree list should be the row dimension of the input matrix - sage: M.coefficient_matrix([3,2,1], row_wise=False) + sage: M.coefficient_matrix([3,2,1], row_wise=False) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: length of input degree list should be the column @@ -410,41 +410,41 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.rings.finite_rings ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.truncate(2) + sage: M.truncate(2) # optional - sage.rings.finite_rings [5*x + 1 5 6*x + 4 0] [3*x + 1 1 2 0] [6*x + 4 5*x + 1 5*x + 5 5*x + 6] - sage: M.truncate(1) == M.constant_matrix() + sage: M.truncate(1) == M.constant_matrix() # optional - sage.rings.finite_rings True Row-wise and column-wise truncation are available:: - sage: M.truncate([3,2,1]) + sage: M.truncate([3,2,1]) # optional - sage.rings.finite_rings [5*x^2 + 5*x + 1 5 6*x + 4 0] [ 3*x + 1 1 2 0] [ 4 1 5 6] - sage: M.truncate([2,1,1,2], row_wise=False) + sage: M.truncate([2,1,1,2], row_wise=False) # optional - sage.rings.finite_rings [5*x + 1 5 4 0] [3*x + 1 1 2 0] [6*x + 4 1 5 5*x + 6] Length of list of truncation orders is checked:: - sage: M.truncate([2,1,1,2]) + sage: M.truncate([2,1,1,2]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: length of input precision list should be the row dimension of the input matrix - sage: M.truncate([3,2,1], row_wise=False) + sage: M.truncate([3,2,1], row_wise=False) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: length of input precision list should be the column @@ -501,42 +501,42 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.rings.finite_rings ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.shift(-2) + sage: M.shift(-2) # optional - sage.rings.finite_rings [ x + 5 0 0 0] [ 6 0 0 0] [2*x + 4 0 2 1] Row-wise and column-wise shifting are available:: - sage: M.shift([-1,2,-2]) + sage: M.shift([-1,2,-2]) # optional - sage.rings.finite_rings [ x^2 + 5*x + 5 0 6 0] [6*x^4 + 3*x^3 + x^2 x^2 2*x^2 0] [ 2*x + 4 0 2 1] - sage: M.shift([-1,1,0,0], row_wise=False) + sage: M.shift([-1,1,0,0], row_wise=False) # optional - sage.rings.finite_rings [ x^2 + 5*x + 5 5*x 6*x + 4 0] [ 6*x + 3 x 2 0] [2*x^2 + 4*x + 6 5*x^2 + x 2*x^2 + 5*x + 5 x^2 + 5*x + 6] - sage: M.shift([-d for d in M.row_degrees()]) == M.leading_matrix() + sage: M.shift([-d for d in M.row_degrees()]) == M.leading_matrix() # optional - sage.rings.finite_rings True Length of input shift degree list is checked:: - sage: M.shift([1,3,1,4]) + sage: M.shift([1,3,1,4]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: length of input shift list should be the row dimension of the input matrix - sage: M.shift([5,2,-1], row_wise=False) + sage: M.shift([5,2,-1], row_wise=False) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: length of input shift list should be the column @@ -609,14 +609,14 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.rings.finite_rings ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.reverse() + sage: M.reverse() # optional - sage.rings.finite_rings [ x^3 + 5*x^2 + 5*x + 1 5*x^3 4*x^3 + 6*x^2 0] [ x^3 + 3*x^2 + 6*x x^3 @@ -624,17 +624,17 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [4*x^3 + 6*x^2 + 4*x + 2 x^3 + 5*x^2 5*x^3 + 5*x^2 + 2*x 6*x^3 + 5*x^2 + x] - sage: M.reverse(1) + sage: M.reverse(1) # optional - sage.rings.finite_rings [ x + 5 5*x 4*x + 6 0] [ x + 3 x 2*x 0] [4*x + 6 x + 5 5*x + 5 6*x + 5] - sage: M.reverse(0) == M.constant_matrix() + sage: M.reverse(0) == M.constant_matrix() # optional - sage.rings.finite_rings True Entry-wise reversing with respect to each entry's degree:: - sage: M.reverse(entry_wise=True) + sage: M.reverse(entry_wise=True) # optional - sage.rings.finite_rings [ x^3 + 5*x^2 + 5*x + 1 5 4*x + 6 0] [ x^2 + 3*x + 6 1 @@ -644,7 +644,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Row-wise and column-wise degree reversing are available:: - sage: M.reverse([2,3,1]) + sage: M.reverse([2,3,1]) # optional - sage.rings.finite_rings [ x^2 + 5*x + 5 5*x^2 4*x^2 + 6*x 0] [x^3 + 3*x^2 + 6*x x^3 2*x^3 @@ -652,7 +652,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 4*x + 6 x + 5 5*x + 5 6*x + 5] - sage: M.reverse(M.column_degrees(),row_wise=False) + sage: M.reverse(M.column_degrees(), row_wise=False) # optional - sage.rings.finite_rings [ x^3 + 5*x^2 + 5*x + 1 5*x 4*x^2 + 6*x 0] [ x^3 + 3*x^2 + 6*x x @@ -662,19 +662,19 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Wrong length or negativity of input degree raise errors: - sage: M.reverse([1,3,1,4]) + sage: M.reverse([1,3,1,4]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: length of input degree list should be the row dimension of the input matrix - sage: M.reverse([5,2,1], row_wise=False) + sage: M.reverse([5,2,1], row_wise=False) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: length of input degree list should be the column dimension of the input matrix - sage: M.reverse([2,3,-1]) + sage: M.reverse([2,3,-1]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... OverflowError: can't convert negative value to unsigned long @@ -743,30 +743,30 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: A = Matrix(pR, 3, 3, \ - [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], \ - [6*x^2 + 6*x + 6, 4*x^2 + 5*x, 4*x^2 + x + 3], \ - [3*x^2 + 2, 4*x + 1, x^2 + 3*x]]) - sage: B = A.inverse_series_trunc(4); B + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: A = Matrix(pR, 3, 3, # optional - sage.rings.finite_rings + ....: [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], + ....: [6*x^2 + 6*x + 6, 4*x^2 + 5*x, 4*x^2 + x + 3], + ....: [3*x^2 + 2, 4*x + 1, x^2 + 3*x]]) + sage: B = A.inverse_series_trunc(4); B # optional - sage.rings.finite_rings [ x^3 + 5*x^2 + x + 4 x^3 + 5*x^2 + 6*x + 4 6*x^2 + 5*x + 3] [ 4*x^2 + 5*x + 6 6*x^3 + x^2 + x + 6 3*x^3 + 2*x^2 + 2] [5*x^3 + 5*x^2 + 6*x + 6 4*x^3 + 2*x^2 + 6*x + 4 6*x^3 + x^2 + 6*x + 1] - sage: (B*A).truncate(4) == 1 + sage: (B*A).truncate(4) == 1 # optional - sage.rings.finite_rings True - sage: A.inverse_series_trunc(0) + sage: A.inverse_series_trunc(0) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: the precision must be positive - sage: A[:2,:].inverse_series_trunc(4) + sage: A[:2,:].inverse_series_trunc(4) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ArithmeticError: the input matrix must be square - sage: A[0,:] = A[0,:] - A[0,:](0) + A[1,:](0) + A[2,:](0) - sage: A.inverse_series_trunc(4) + sage: A[0,:] = A[0,:] - A[0,:](0) + A[1,:](0) + A[2,:](0) # optional - sage.rings.finite_rings + sage: A.inverse_series_trunc(4) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: the constant matrix term self(0) must be invertible @@ -840,61 +840,61 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: A = Matrix(pR, 3, 3, \ - [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], \ - [6*x^2 + 6*x + 6, 4*x^2 + 5*x, 4*x^2 + x + 3], \ - [3*x^2 + 2, 4*x + 1, x^2 + 3*x]]) - sage: A.is_square() and A.constant_matrix().is_invertible() + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: A = Matrix(pR, 3, 3, # optional - sage.rings.finite_rings + ....: [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], + ....: [6*x^2 + 6*x + 6, 4*x^2 + 5*x, 4*x^2 + x + 3], + ....: [3*x^2 + 2, 4*x + 1, x^2 + 3*x]]) + sage: A.is_square() and A.constant_matrix().is_invertible() # optional - sage.rings.finite_rings True - sage: B = vector([2*x^2 + 6*x + 6, 0, x + 6]) - sage: X = A.solve_left_series_trunc(B,4); X + sage: B = vector([2*x^2 + 6*x + 6, 0, x + 6]) # optional - sage.rings.finite_rings + sage: X = A.solve_left_series_trunc(B, 4); X # optional - sage.rings.finite_rings (3*x^3 + 3*x^2 + 2*x + 4, 4*x^3 + x^2 + 2*x + 6, 6*x^3 + x + 3) - sage: B == X*A % x**4 + sage: B == X*A % x**4 # optional - sage.rings.finite_rings True - sage: B = Matrix(pR, 2, 3, \ - [[3*x, x^2 + x + 2, x^2 + 2*x + 3], \ - [ 0, 6*x^2 + 1, 1]]) - sage: A.solve_left_series_trunc(B,3) + sage: B = Matrix(pR, 2, 3, # optional - sage.rings.finite_rings + ....: [[3*x, x^2 + x + 2, x^2 + 2*x + 3], + ....: [ 0, 6*x^2 + 1, 1]]) + sage: A.solve_left_series_trunc(B, 3) # optional - sage.rings.finite_rings [6*x^2 + 2*x + 2 4*x + 3 2*x^2 + 3*x] [3*x^2 + 4*x + 5 4*x^2 + 3 x^2 + 6*x + 3] - sage: X = A.solve_left_series_trunc(B,37); B == X*A % x**37 + sage: X = A.solve_left_series_trunc(B, 37); B == X*A % x**37 # optional - sage.rings.finite_rings True Dimensions of input are checked:: - sage: A.solve_left_series_trunc(B[:,:2],3) + sage: A.solve_left_series_trunc(B[:,:2], 3) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: number of columns of self must equal number of columns of right-hand side Raises an exception when no solution:: - sage: A[2:,:].solve_left_series_trunc(B,4) + sage: A[2:,:].solve_left_series_trunc(B, 4) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matrix equation has no solutions - sage: Ax = x*A; C = vector(pR, [1,1,1]) - sage: Ax.solve_left_series_trunc(C,5) + sage: Ax = x*A; C = vector(pR, [1,1,1]) # optional - sage.rings.finite_rings + sage: Ax.solve_left_series_trunc(C, 5) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matrix equation has no solutions Supports rectangular and rank-deficient cases:: - sage: A[:,:2].solve_left_series_trunc(B[:,:2],4) + sage: A[:,:2].solve_left_series_trunc(B[:,:2], 4) # optional - sage.rings.finite_rings [5*x^2 + 2*x + 5 5*x + 5 2*x + 4] [5*x^3 + 2*x + 1 2*x^2 + 2*x + 5 4*x^2] - sage: V = Matrix([[3*x^2 + 4*x + 1, 4*x]]) - sage: A[:2,:].solve_left_series_trunc(V*A[:2,:], 4) == V + sage: V = Matrix([[3*x^2 + 4*x + 1, 4*x]]) # optional - sage.rings.finite_rings + sage: A[:2,:].solve_left_series_trunc(V*A[:2,:], 4) == V # optional - sage.rings.finite_rings True - sage: A[1,:] = (x+1) * A[0,:]; A[2,:] = (x+5) * A[0,:] - sage: B = (3*x^3+x^2+2)*A[0,:] - sage: A.solve_left_series_trunc(B, 6) + sage: A[1,:] = (x+1) * A[0,:]; A[2,:] = (x+5) * A[0,:] # optional - sage.rings.finite_rings + sage: B = (3*x^3+x^2+2)*A[0,:] # optional - sage.rings.finite_rings + sage: A.solve_left_series_trunc(B, 6) # optional - sage.rings.finite_rings [4*x^2 + 6*x + 2 3*x^2 + x 0] .. SEEALSO:: @@ -987,64 +987,64 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: A = Matrix(pR, 3, 3, \ - [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], \ - [6*x^2 + 6*x + 6, 4*x^2 + 5*x, 4*x^2 + x + 3], \ - [3*x^2 + 2, 4*x + 1, x^2 + 3*x]]) - sage: A.is_square() and A.constant_matrix().is_invertible() + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: A = Matrix(pR, 3, 3, # optional - sage.rings.finite_rings + ....: [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], + ....: [6*x^2 + 6*x + 6, 4*x^2 + 5*x, 4*x^2 + x + 3], + ....: [3*x^2 + 2, 4*x + 1, x^2 + 3*x]]) + sage: A.is_square() and A.constant_matrix().is_invertible() # optional - sage.rings.finite_rings True - sage: B = vector([2*x^2 + 6*x + 6, 0, x + 6]) - sage: X = A.solve_right_series_trunc(B,4); X + sage: B = vector([2*x^2 + 6*x + 6, 0, x + 6]) # optional - sage.rings.finite_rings + sage: X = A.solve_right_series_trunc(B, 4); X # optional - sage.rings.finite_rings (2*x^3 + x^2, 5*x^3 + x^2 + 5*x + 6, 4*x^3 + 6*x^2 + 4*x) - sage: B == A*X % x**4 + sage: B == A*X % x**4 # optional - sage.rings.finite_rings True - sage: B = Matrix(pR, 3, 2, \ - [[5*x^2 + 6*x + 3, 4*x^2 + 6*x + 4], \ - [ x^2 + 4*x + 2, 5*x + 2], \ - [ 5*x + 3, 0]]) - sage: A.solve_right_series_trunc(B,3) + sage: B = Matrix(pR, 3, 2, # optional - sage.rings.finite_rings + ....: [[5*x^2 + 6*x + 3, 4*x^2 + 6*x + 4], + ....: [ x^2 + 4*x + 2, 5*x + 2], + ....: [ 5*x + 3, 0]]) + sage: A.solve_right_series_trunc(B, 3) # optional - sage.rings.finite_rings [ 3*x^2 + x + 1 5*x^2 + 4*x + 3] [6*x^2 + 3*x + 1 4*x + 1] [ 6*x^2 + 1 2*x^2 + x + 4] - sage: X = A.solve_right_series_trunc(B,37); B == A*X % x**37 + sage: X = A.solve_right_series_trunc(B, 37); B == A*X % x**37 # optional - sage.rings.finite_rings True Dimensions of input are checked:: - sage: A.solve_right_series_trunc(B[:2,:],3) + sage: A.solve_right_series_trunc(B[:2,:], 3) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: number of rows of self must equal number of rows of right-hand side Raises an exception when no solution:: - sage: A[:,2:].solve_right_series_trunc(B,4) + sage: A[:,2:].solve_right_series_trunc(B, 4) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matrix equation has no solutions - sage: Ax = x*A; C = vector(pR, [1,1,1]) - sage: Ax.solve_right_series_trunc(C,5) + sage: Ax = x*A; C = vector(pR, [1,1,1]) # optional - sage.rings.finite_rings + sage: Ax.solve_right_series_trunc(C, 5) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matrix equation has no solutions Supports rectangular and rank-deficient cases:: - sage: A[:2,:].solve_right_series_trunc(B[:2,:],4) + sage: A[:2,:].solve_right_series_trunc(B[:2,:],4) # optional - sage.rings.finite_rings [ 5*x^2 + 4*x x + 4] [ x^2 + 3*x + 5 3*x^2 + 4*x + 4] [ 5*x + 3 3*x + 2] - sage: V = Matrix([[2*x^2 + 5*x + 1], [3*x^2+4]]) - sage: A[:,:2].solve_right_series_trunc(A[:,:2]*V, 4) == V + sage: V = Matrix([[2*x^2 + 5*x + 1], [3*x^2+4]]) # optional - sage.rings.finite_rings + sage: A[:,:2].solve_right_series_trunc(A[:,:2]*V, 4) == V # optional - sage.rings.finite_rings True - sage: A[:,1] = (x+1) * A[:,0]; A[:,2] = (x+5) * A[:,0] - sage: B = (3*x^3+x^2+2)*A[:,0] - sage: A.solve_right_series_trunc(B, 6) + sage: A[:,1] = (x+1) * A[:,0]; A[:,2] = (x+5) * A[:,0] # optional - sage.rings.finite_rings + sage: B = (3*x^3+x^2+2)*A[:,0] # optional - sage.rings.finite_rings + sage: A.solve_right_series_trunc(B, 6) # optional - sage.rings.finite_rings [4*x^2 + 6*x + 2] [ 3*x^2 + x] [ 0] @@ -1096,35 +1096,35 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ [3*x+1, 0, 1], [x^3+3, 0, 0] ]) - sage: M.row_degrees() + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.rings.finite_rings + sage: M.row_degrees() # optional - sage.rings.finite_rings [1, 3] - sage: M.row_degrees(shifts=[0,1,2]) + sage: M.row_degrees(shifts=[0,1,2]) # optional - sage.rings.finite_rings [2, 3] A zero row in a polynomial matrix can be identified in the (shifted) row degrees as the entries equal to ``min(shifts)-1``:: - sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0], [0, 0, 0]]) - sage: M.row_degrees() + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0], [0, 0, 0]]) # optional - sage.rings.finite_rings + sage: M.row_degrees() # optional - sage.rings.finite_rings [1, 3, -1] - sage: M.row_degrees(shifts=[-2,1,2]) + sage: M.row_degrees(shifts=[-2,1,2]) # optional - sage.rings.finite_rings [2, 1, -3] The row degrees of an empty matrix (`0\times n` or `m\times 0`) is not defined:: - sage: M = Matrix( pR, 0, 3 ) - sage: M.row_degrees() + sage: M = Matrix(pR, 0, 3) # optional - sage.rings.finite_rings + sage: M.row_degrees() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: empty matrix does not have row degrees - sage: M = Matrix( pR, 3, 0 ) - sage: M.row_degrees() + sage: M = Matrix(pR, 3, 0) # optional - sage.rings.finite_rings + sage: M.row_degrees() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: empty matrix does not have row degrees @@ -1163,31 +1163,31 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ [3*x+1, 0, 1], [x^3+3, 0, 0] ]) - sage: M.column_degrees() + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.rings.finite_rings + sage: M.column_degrees() # optional - sage.rings.finite_rings [3, -1, 0] - sage: M.column_degrees(shifts=[0,2]) + sage: M.column_degrees(shifts=[0,2]) # optional - sage.rings.finite_rings [5, -1, 0] A zero column in a polynomial matrix can be identified in the (shifted) column degrees as the entries equal to ``min(shifts)-1``:: - sage: M.column_degrees(shifts=[-2,1]) + sage: M.column_degrees(shifts=[-2,1]) # optional - sage.rings.finite_rings [4, -3, -2] The column degrees of an empty matrix (`0\times n` or `m\times 0`) is not defined:: - sage: M = Matrix( pR, 0, 3 ) - sage: M.column_degrees() + sage: M = Matrix(pR, 0, 3) # optional - sage.rings.finite_rings + sage: M.column_degrees() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: empty matrix does not have column degrees - sage: M = Matrix( pR, 3, 0 ) - sage: M.column_degrees() + sage: M = Matrix(pR, 3, 0) # optional - sage.rings.finite_rings + sage: M.column_degrees() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: empty matrix does not have column degrees @@ -1244,28 +1244,28 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ [3*x+1, 0, 1], [x^3+3, 0, 0] ]) - sage: M.leading_matrix() + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.rings.finite_rings + sage: M.leading_matrix() # optional - sage.rings.finite_rings [3 0 0] [1 0 0] - sage: M.leading_matrix().base_ring() + sage: M.leading_matrix().base_ring() # optional - sage.rings.finite_rings Finite Field of size 7 - sage: M.leading_matrix(shifts=[0,1,2]) + sage: M.leading_matrix(shifts=[0,1,2]) # optional - sage.rings.finite_rings [0 0 1] [1 0 0] - sage: M.leading_matrix(row_wise=False) + sage: M.leading_matrix(row_wise=False) # optional - sage.rings.finite_rings [0 0 1] [1 0 0] - sage: M.leading_matrix(shifts=[-2,1], row_wise=False) + sage: M.leading_matrix(shifts=[-2,1], row_wise=False) # optional - sage.rings.finite_rings [0 0 1] [1 0 0] - sage: M.leading_matrix(shifts=[2,0], row_wise=False) + sage: M.leading_matrix(shifts=[2,0], row_wise=False) # optional - sage.rings.finite_rings [3 0 1] [1 0 0] """ @@ -1319,19 +1319,19 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, 0, 0) - sage: M._is_empty_popov() + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: M = Matrix(pR, 0, 0) # optional - sage.rings.finite_rings + sage: M._is_empty_popov() # optional - sage.rings.finite_rings True - sage: M._is_empty_popov(include_zero_vectors=False) + sage: M._is_empty_popov(include_zero_vectors=False) # optional - sage.rings.finite_rings True - sage: M = Matrix(pR, 0, 3) - sage: M._is_empty_popov(include_zero_vectors=False) + sage: M = Matrix(pR, 0, 3) # optional - sage.rings.finite_rings + sage: M._is_empty_popov(include_zero_vectors=False) # optional - sage.rings.finite_rings True - sage: M._is_empty_popov(row_wise=False) + sage: M._is_empty_popov(row_wise=False) # optional - sage.rings.finite_rings True - sage: M._is_empty_popov(row_wise=False,include_zero_vectors=False) + sage: M._is_empty_popov(row_wise=False,include_zero_vectors=False) # optional - sage.rings.finite_rings False .. SEEALSO:: @@ -1390,23 +1390,23 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ [3*x+1, 0, 1], [x^3+3, 0, 0] ]) - sage: M.is_reduced() + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.rings.finite_rings + sage: M.is_reduced() # optional - sage.rings.finite_rings False - sage: M.is_reduced(shifts=[0,1,2]) + sage: M.is_reduced(shifts=[0,1,2]) # optional - sage.rings.finite_rings True - sage: M.is_reduced(shifts=[2,0], row_wise=False) + sage: M.is_reduced(shifts=[2,0], row_wise=False) # optional - sage.rings.finite_rings True - sage: M.is_reduced(shifts=[2,0], row_wise=False, - ....: include_zero_vectors=False) + sage: M.is_reduced(shifts=[2,0], row_wise=False, # optional - sage.rings.finite_rings + ....: include_zero_vectors=False) False - sage: M = Matrix(pR, [ [3*x+1, 0, 1], [x^3+3, 0, 0], [0, 1, 0] ]) - sage: M.is_reduced(shifts=[2,0,0], row_wise=False) + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0], [0, 1, 0]]) # optional - sage.rings.finite_rings + sage: M.is_reduced(shifts=[2,0,0], row_wise=False) # optional - sage.rings.finite_rings True .. SEEALSO:: @@ -1470,50 +1470,51 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ [3*x+1, 0, 1], [x^3+3, 0, 0] ]) - sage: M.leading_positions() + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.rings.finite_rings + sage: M.leading_positions() # optional - sage.rings.finite_rings [0, 0] - sage: M.leading_positions(return_degree=True) + sage: M.leading_positions(return_degree=True) # optional - sage.rings.finite_rings ([0, 0], [1, 3]) - sage: M.leading_positions(shifts=[0,5,2], return_degree=True) + sage: M.leading_positions(shifts=[0,5,2], return_degree=True) # optional - sage.rings.finite_rings ([2, 0], [0, 3]) - sage: M.leading_positions(row_wise=False, return_degree=True) + sage: M.leading_positions(row_wise=False, return_degree=True) # optional - sage.rings.finite_rings ([1, -1, 0], [3, -1, 0]) - sage: M.leading_positions(shifts=[1,2], row_wise=False, - ....: return_degree=True) + sage: M.leading_positions(shifts=[1,2], row_wise=False, # optional - sage.rings.finite_rings + ....: return_degree=True) ([1, -1, 0], [3, -1, 0]) In case several entries in the row (resp. column) reach the shifted row (resp. column) degree, the leading position is chosen as the rightmost (resp. bottommost) such entry:: - sage: M.leading_positions(shifts=[0,5,1],return_degree=True) + sage: M.leading_positions(shifts=[0,5,1], return_degree=True) # optional - sage.rings.finite_rings ([2, 0], [0, 3]) - sage: M.leading_positions(shifts=[2,0], row_wise=False,return_degree=True) + sage: M.leading_positions(shifts=[2,0], row_wise=False, # optional - sage.rings.finite_rings + ....: return_degree=True) ([1, -1, 0], [3, -1, 0]) The leading positions and pivot degrees of an empty matrix (`0\times n` or `m\times 0`) is not defined:: - sage: M = Matrix( pR, 0, 3 ) - sage: M.leading_positions() + sage: M = Matrix(pR, 0, 3) # optional - sage.rings.finite_rings + sage: M.leading_positions() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: empty matrix does not have leading positions - sage: M.leading_positions(row_wise=False) + sage: M.leading_positions(row_wise=False) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: empty matrix does not have leading positions - sage: M = Matrix( pR, 3, 0 ) - sage: M.leading_positions(row_wise=False) + sage: M = Matrix(pR, 3, 0) # optional - sage.rings.finite_rings + sage: M.leading_positions(row_wise=False) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: empty matrix does not have leading positions @@ -1601,58 +1602,60 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix([ [x^3+3*x^2+6*x+6, 3*x^2+3*x+6, 4*x^2+x+3], + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: M = Matrix([ [x^3+3*x^2+6*x+6, 3*x^2+3*x+6, 4*x^2+x+3], # optional - sage.rings.finite_rings ....: [5, 1, 0 ], ....: [2*x^2+2, 2*x+5, x^2+4*x+6] ]) - sage: M.is_weak_popov() + sage: M.is_weak_popov() # optional - sage.rings.finite_rings True One can check whether the leading positions, in addition to being pairwise distinct, are actually in increasing order:: - sage: M.is_weak_popov(ordered=True) + sage: M.is_weak_popov(ordered=True) # optional - sage.rings.finite_rings True - sage: N = M.with_swapped_rows(1,2) - sage: N.is_weak_popov() + sage: N = M.with_swapped_rows(1, 2) # optional - sage.rings.finite_rings + sage: N.is_weak_popov() # optional - sage.rings.finite_rings True - sage: N.is_weak_popov(ordered=True) + sage: N.is_weak_popov(ordered=True) # optional - sage.rings.finite_rings False Shifts and orientation (row-wise or column-wise) are supported:: - sage: M.is_weak_popov(shifts=[2,3,1]) + sage: M.is_weak_popov(shifts=[2,3,1]) # optional - sage.rings.finite_rings False - sage: M.is_weak_popov(shifts=[0,2,0],row_wise=False,ordered=True) + sage: M.is_weak_popov(shifts=[0,2,0], row_wise=False, # optional - sage.rings.finite_rings + ....: ordered=True) True Rectangular matrices are supported:: - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.rings.finite_rings ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.is_weak_popov(shifts=[0,2,1,3]) + sage: M.is_weak_popov(shifts=[0,2,1,3]) # optional - sage.rings.finite_rings True - sage: M.is_weak_popov(shifts=[0,2,1,3],ordered=True) + sage: M.is_weak_popov(shifts=[0,2,1,3], ordered=True) # optional - sage.rings.finite_rings True Zero rows (resp. columns) can be forbidden:: - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.rings.finite_rings ....: [ 6*x+4, 0, 5*x+1, 0], ....: [ 2, 5*x + 1, 6*x^2+3*x+1, 0], ....: [2*x^2+5*x+5, 1, 2*x^3+4*x^2+6*x+4, 0] ....: ]) - sage: M.is_weak_popov(shifts=[2,1,0], row_wise=False, ordered=True) + sage: M.is_weak_popov(shifts=[2,1,0], row_wise=False, # optional - sage.rings.finite_rings + ....: ordered=True) True - sage: M.is_weak_popov(shifts=[2,1,0], row_wise=False, - ....: include_zero_vectors=False) + sage: M.is_weak_popov(shifts=[2,1,0], row_wise=False, # optional - sage.rings.finite_rings + ....: include_zero_vectors=False) False .. SEEALSO:: @@ -1730,60 +1733,60 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ [x^4+6*x^3+4*x+4, 3*x+6, 3 ], - ....: [x^2+6*x+6, x^2+5*x+5, 2 ], - ....: [3*x, 6*x+5, x+5] ]) - sage: M.is_popov() + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: M = Matrix(pR, [[x^4+6*x^3+4*x+4, 3*x+6, 3 ], # optional - sage.rings.finite_rings + ....: [x^2+6*x+6, x^2+5*x+5, 2 ], + ....: [3*x, 6*x+5, x+5]]) + sage: M.is_popov() # optional - sage.rings.finite_rings True - sage: M.is_popov(shifts=[0,1,2]) + sage: M.is_popov(shifts=[0,1,2]) # optional - sage.rings.finite_rings True - sage: M[:,:2].is_popov() + sage: M[:,:2].is_popov() # optional - sage.rings.finite_rings False - sage: M[:2,:].is_popov(shifts=[0,1,2]) + sage: M[:2,:].is_popov(shifts=[0,1,2]) # optional - sage.rings.finite_rings True - sage: M = Matrix(pR, [ [x^4+3*x^3+x^2+2*x+6, x^3+5*x^2+5*x+1], - ....: [6*x+1, x^2+4*x+1 ], - ....: [6, 6 ] ]) - sage: M.is_popov(row_wise=False) + sage: M = Matrix(pR, [[x^4+3*x^3+x^2+2*x+6, x^3+5*x^2+5*x+1], # optional - sage.rings.finite_rings + ....: [6*x+1, x^2+4*x+1 ], + ....: [6, 6 ]]) + sage: M.is_popov(row_wise=False) # optional - sage.rings.finite_rings False - sage: M.is_popov(shifts=[0,2,3], row_wise=False) + sage: M.is_popov(shifts=[0,2,3], row_wise=False) # optional - sage.rings.finite_rings True One can forbid zero rows (or columns if not working row-wise):: - sage: N = Matrix(pR, [ [x^4+3*x^3+x^2+2*x+6, 6*x+1 ], - ....: [5*x^2+5*x+1, x^2+4*x+1 ], - ....: [0, 0 ] ]) + sage: N = Matrix(pR, [[x^4+3*x^3+x^2+2*x+6, 6*x+1 ], # optional - sage.rings.finite_rings + ....: [5*x^2+5*x+1, x^2+4*x+1 ], + ....: [0, 0 ]]) - sage: N.is_popov() + sage: N.is_popov() # optional - sage.rings.finite_rings True - sage: N.is_popov(include_zero_vectors=False) + sage: N.is_popov(include_zero_vectors=False) # optional - sage.rings.finite_rings False One can verify Popov form up to row permutation (or column permutation if not working row-wise):: - sage: M.swap_columns(0,1) - sage: M.is_popov(shifts=[0,2,3], row_wise=False) + sage: M.swap_columns(0, 1) # optional - sage.rings.finite_rings + sage: M.is_popov(shifts=[0,2,3], row_wise=False) # optional - sage.rings.finite_rings False - sage: M.is_popov(shifts=[0,2,3], row_wise=False, - ....: up_to_permutation=True) + sage: M.is_popov(shifts=[0,2,3], row_wise=False, # optional - sage.rings.finite_rings + ....: up_to_permutation=True) True - sage: N.swap_rows(0,2) + sage: N.swap_rows(0, 2) # optional - sage.rings.finite_rings - sage: N.is_popov() + sage: N.is_popov() # optional - sage.rings.finite_rings False - sage: N.is_popov(up_to_permutation=True) + sage: N.is_popov(up_to_permutation=True) # optional - sage.rings.finite_rings True """ # the matrix should be in weak Popov form (ordered except if @@ -1868,41 +1871,41 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ [x^4+6*x^3+4*x+4, 3*x+6, 3 ], - ....: [0, x^2+5*x+5, 2 ], - ....: [0, 0, x+5] ]) + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: M = Matrix(pR, [[x^4+6*x^3+4*x+4, 3*x+6, 3 ], # optional - sage.rings.finite_rings + ....: [0, x^2+5*x+5, 2 ], + ....: [0, 0, x+5]]) - sage: M.is_hermite() + sage: M.is_hermite() # optional - sage.rings.finite_rings True - sage: M.is_hermite(row_wise=False) + sage: M.is_hermite(row_wise=False) # optional - sage.rings.finite_rings True - sage: M.is_hermite(row_wise=False, lower_echelon=True) + sage: M.is_hermite(row_wise=False, lower_echelon=True) # optional - sage.rings.finite_rings False - sage: N = Matrix(pR, [ [x+5, 0, 0 ], - ....: [2, x^4+6*x^3+4*x+4, 0 ], - ....: [3, 3*x^3+6, x^2+5*x+5] ]) - sage: N.is_hermite() + sage: N = Matrix(pR, [[x+5, 0, 0 ], # optional - sage.rings.finite_rings + ....: [2, x^4+6*x^3+4*x+4, 0 ], + ....: [3, 3*x^3+6, x^2+5*x+5]]) + sage: N.is_hermite() # optional - sage.rings.finite_rings False - sage: N.is_hermite(lower_echelon=True) + sage: N.is_hermite(lower_echelon=True) # optional - sage.rings.finite_rings True - sage: N.is_hermite(row_wise=False) + sage: N.is_hermite(row_wise=False) # optional - sage.rings.finite_rings False - sage: N.is_hermite(row_wise=False, lower_echelon=True) + sage: N.is_hermite(row_wise=False, lower_echelon=True) # optional - sage.rings.finite_rings False Rectangular matrices with zero rows are supported. Zero rows (resp. columns) can be forbidden, and otherwise they should be at the bottom (resp. the right-hand side) of the matrix:: - sage: N[:,1:].is_hermite(lower_echelon=True) + sage: N[:,1:].is_hermite(lower_echelon=True) # optional - sage.rings.finite_rings False - sage: N[[1,2,0],1:].is_hermite(lower_echelon=True) + sage: N[[1,2,0],1:].is_hermite(lower_echelon=True) # optional - sage.rings.finite_rings True - sage: N[:2,:].is_hermite(row_wise=False, lower_echelon=True) + sage: N[:2,:].is_hermite(row_wise=False, lower_echelon=True) # optional - sage.rings.finite_rings True - sage: N[:2,:].is_hermite(row_wise=False, + sage: N[:2,:].is_hermite(row_wise=False, # optional - sage.rings.finite_rings ....: lower_echelon=True, ....: include_zero_vectors=False) False @@ -1983,61 +1986,61 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ \ - [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], \ - [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: M = Matrix(pR, [ # optional - sage.rings.finite_rings + ....: [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], + ....: [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) - sage: P,U = M.weak_popov_form(transformation=True) - sage: P + sage: P, U = M.weak_popov_form(transformation=True) # optional - sage.combinat sage.rings.finite_rings + sage: P # optional - sage.combinat sage.rings.finite_rings [ 4 x^2 6*x^2 + x + 2] [ 2 4*x^2 + 2*x + 4 5] - sage: U + sage: U # optional - sage.combinat sage.rings.finite_rings [2*x^2 + 1 4*x] [ 4*x 1] - sage: P.is_weak_popov() and U.is_invertible() and U*M==P + sage: P.is_weak_popov() and U.is_invertible() and U*M == P # optional - sage.combinat sage.rings.finite_rings True Demonstrating the ``ordered`` option:: - sage: P.leading_positions() + sage: P.leading_positions() # optional - sage.combinat sage.rings.finite_rings [2, 1] - sage: PP = M.weak_popov_form(ordered=True); PP + sage: PP = M.weak_popov_form(ordered=True); PP # optional - sage.combinat sage.rings.finite_rings [ 2 4*x^2 + 2*x + 4 5] [ 4 x^2 6*x^2 + x + 2] - sage: PP.leading_positions() + sage: PP.leading_positions() # optional - sage.combinat sage.rings.finite_rings [1, 2] Demonstrating shifts:: - sage: P = M.weak_popov_form(shifts=[0,2,4]); P + sage: P = M.weak_popov_form(shifts=[0,2,4]); P # optional - sage.combinat sage.rings.finite_rings [ 6*x^2 + 6*x + 4 5*x^4 + 4*x^3 + 5*x^2 + 5*x 2*x + 2] [ 2 4*x^2 + 2*x + 4 5] - sage: P==M.weak_popov_form(shifts=[-10,-8,-6]) + sage: P == M.weak_popov_form(shifts=[-10,-8,-6]) # optional - sage.combinat sage.rings.finite_rings True Column-wise form is the row-wise form of the transpose:: - sage: M.weak_popov_form() == M.T.weak_popov_form(row_wise=False).T + sage: M.weak_popov_form() == M.T.weak_popov_form(row_wise=False).T # optional - sage.combinat sage.rings.finite_rings True Zero vectors can be discarded:: - sage: M.weak_popov_form(row_wise=False) + sage: M.weak_popov_form(row_wise=False) # optional - sage.combinat sage.rings.finite_rings [x + 4 6 0] [ 5 1 0] - sage: P,U = M.weak_popov_form(transformation=True, \ - row_wise=False, \ - include_zero_vectors=False) - sage: P + sage: P, U = M.weak_popov_form(transformation=True, # optional - sage.combinat sage.rings.finite_rings + ....: row_wise=False, + ....: include_zero_vectors=False) + sage: P # optional - sage.combinat sage.rings.finite_rings [x + 4 6] [ 5 1] - sage: U + sage: U # optional - sage.combinat sage.rings.finite_rings [ 5*x + 2 5*x^2 + 4*x + 4 3*x^3 + 3*x^2 + 2*x + 4] [ 1 1 2*x + 1] [ 5*x + 5 2 6] - sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() + sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() # optional - sage.combinat sage.rings.finite_rings True .. SEEALSO:: @@ -2112,34 +2115,34 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: F. = GF(2^4,'a') - sage: PF. = F[] - sage: A = matrix(PF,[[1, a*x^17 + 1 ], + sage: F. = GF(2^4, 'a') # optional - sage.rings.finite_rings + sage: PF. = F[] # optional - sage.rings.finite_rings + sage: A = matrix(PF,[[1, a*x^17 + 1 ], # optional - sage.rings.finite_rings ....: [0, a*x^11 + a^2*x^7 + 1 ]]) - sage: M = A.__copy__() - sage: U = M._weak_popov_form(transformation=True) - sage: U * A == M + sage: M = A.__copy__() # optional - sage.rings.finite_rings + sage: U = M._weak_popov_form(transformation=True) # optional - sage.combinat sage.rings.finite_rings + sage: U * A == M # optional - sage.combinat sage.rings.finite_rings True - sage: M.is_weak_popov() + sage: M.is_weak_popov() # optional - sage.combinat sage.rings.finite_rings True - sage: U.is_invertible() + sage: U.is_invertible() # optional - sage.combinat sage.rings.finite_rings True sage: PF. = QQ[] sage: A = matrix(PF,3,[x, x^2, x^3, ....: x^2, x^1, 0, ....: x^3, x^3, x^3]) - sage: A.weak_popov_form() + sage: A.weak_popov_form() # optional - sage.combinat [ x x^2 x^3] [ x^2 x 0] [ x^3 - x x^3 - x^2 0] - sage: M = A.__copy__() - sage: U = M._weak_popov_form(transformation=True, shifts=[16,8,0]) - sage: M + sage: M = A.__copy__() # optional - sage.combinat + sage: U = M._weak_popov_form(transformation=True, shifts=[16,8,0]) # optional - sage.combinat + sage: M # optional - sage.combinat [ x x^2 x^3] [ 0 -x^2 + x -x^4 + x^3] [ 0 0 -x^5 + x^4 + x^3] - sage: U * A == M + sage: U * A == M # optional - sage.combinat True """ cdef Py_ssize_t i, j @@ -2267,56 +2270,56 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ \ - [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], \ - [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: M = Matrix(pR, [ # optional - sage.rings.finite_rings + ....: [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], + ....: [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) - sage: P,U = M.popov_form(transformation=True) - sage: P + sage: P, U = M.popov_form(transformation=True) # optional - sage.combinat sage.rings.finite_rings + sage: P # optional - sage.combinat sage.rings.finite_rings [ 4 x^2 + 4*x + 1 3] [ 0 4*x + 1 x^2 + 6*x + 1] - sage: U + sage: U # optional - sage.combinat sage.rings.finite_rings [ x 2] [5*x^2 + x + 6 3*x + 2] - sage: P.is_popov() and U.is_invertible() and U*M==P + sage: P.is_popov() and U.is_invertible() and U*M == P # optional - sage.combinat sage.rings.finite_rings True Demonstrating shifts and specific case of Hermite form:: - sage: P = M.popov_form(shifts=[0,2,4]); P + sage: P = M.popov_form(shifts=[0,2,4]); P # optional - sage.combinat sage.rings.finite_rings [ 4*x^2 + 3*x + 4 x^4 + 3*x^3 + 5*x^2 + 5*x + 5 0] [ 6 5*x^2 + 6*x + 5 1] - sage: P.is_popov(shifts=[0,2,4]) + sage: P.is_popov(shifts=[0,2,4]) # optional - sage.combinat sage.rings.finite_rings True - sage: P==M.popov_form(shifts=[-6,-4,-2]) + sage: P == M.popov_form(shifts=[-6,-4,-2]) # optional - sage.combinat sage.rings.finite_rings True - sage: dd=sum(M.row_degrees())+1 - sage: M.popov_form(shifts=[2*dd,dd,0]) == M.hermite_form() + sage: dd = sum(M.row_degrees()) + 1 # optional - sage.combinat sage.rings.finite_rings + sage: M.popov_form(shifts=[2*dd,dd,0]) == M.hermite_form() # optional - sage.combinat sage.rings.finite_rings True Column-wise form is the row-wise form of the transpose:: - sage: M.popov_form() == M.T.popov_form(row_wise=False).T + sage: M.popov_form() == M.T.popov_form(row_wise=False).T # optional - sage.combinat sage.rings.finite_rings True Zero vectors can be discarded:: - sage: M.popov_form(row_wise=False) + sage: M.popov_form(row_wise=False) # optional - sage.combinat sage.rings.finite_rings [x + 2 6 0] [ 0 1 0] - sage: P,U = M.popov_form(transformation=True, \ - row_wise=False, \ - include_zero_vectors=False) - sage: P + sage: P, U = M.popov_form(transformation=True, # optional - sage.combinat sage.rings.finite_rings + ....: row_wise=False, + ....: include_zero_vectors=False) + sage: P # optional - sage.combinat sage.rings.finite_rings [x + 2 6] [ 0 1] - sage: U + sage: U # optional - sage.combinat sage.rings.finite_rings [ 3*x^2 + 6*x + 3 5*x^2 + 4*x + 4 3*x^3 + 3*x^2 + 2*x + 4] [ 3 1 2*x + 1] [ 5*x + 2 2 6] - sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() + sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() # optional - sage.combinat sage.rings.finite_rings True .. SEEALSO:: @@ -2458,40 +2461,40 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(3)[] - sage: A = matrix(pR,3,[x, x^2, x^3, - ....: x^2, x^1, 0, - ....: x^3, x^3, x^3]) - sage: R = A.reduced_form(); R + sage: pR. = GF(3)[] # optional - sage.rings.finite_rings + sage: A = matrix(pR, 3, [x, x^2, x^3, # optional - sage.rings.finite_rings + ....: x^2, x^1, 0, + ....: x^3, x^3, x^3]) + sage: R = A.reduced_form(); R # optional - sage.rings.finite_rings [ x x^2 x^3] [ x^2 x 0] [ x^3 + 2*x x^3 + 2*x^2 0] - sage: R.is_reduced() + sage: R.is_reduced() # optional - sage.rings.finite_rings True - sage: R2 = A.reduced_form(shifts=[6,3,0]); R2 + sage: R2 = A.reduced_form(shifts=[6,3,0]); R2 # optional - sage.rings.finite_rings [ x x^2 x^3] [ 0 2*x^2 + x 2*x^4 + x^3] [ 0 0 2*x^5 + x^4 + x^3] - sage: R2.is_reduced(shifts=[6,3,0]) + sage: R2.is_reduced(shifts=[6,3,0]) # optional - sage.rings.finite_rings True - sage: R2.is_reduced() + sage: R2.is_reduced() # optional - sage.rings.finite_rings False If the matrix is an `n \times 1` matrix with at least one non-zero entry, `R` has a single non-zero entry and that entry is a scalar multiple of the greatest-common-divisor of the entries of the matrix:: - sage: A = matrix([[x*(x-1)*(x+1)],[x*(x-2)*(x+2)],[x]]) - sage: R = A.reduced_form() - sage: R + sage: A = matrix([[x*(x-1)*(x+1)], [x*(x-2)*(x+2)], [x]]) # optional - sage.rings.finite_rings + sage: R = A.reduced_form() # optional - sage.rings.finite_rings + sage: R # optional - sage.rings.finite_rings [x] [0] [0] A zero matrix is already reduced:: - sage: A = matrix(pR, 2, [0,0,0,0]) - sage: A.reduced_form() + sage: A = matrix(pR, 2, [0,0,0,0]) # optional - sage.rings.finite_rings + sage: A.reduced_form() # optional - sage.rings.finite_rings [0 0] [0 0] @@ -2505,29 +2508,29 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [0 0 x] sage: A.is_reduced() True - sage: W = A.reduced_form(); W + sage: W = A.reduced_form(); W # optional - sage.combinat [ x x x] [-x -x 0] - sage: W.is_weak_popov() + sage: W.is_weak_popov() # optional - sage.combinat True The last example shows the usage of the transformation parameter:: - sage: Fq. = GF(2^3) - sage: pR. = Fq[] - sage: A = matrix(pR, [[x^2+a, x^4+a], - ....: [ x^3, a*x^4]]) - sage: W,U = A.reduced_form(transformation=True) - sage: W,U + sage: Fq. = GF(2^3) # optional - sage.rings.finite_rings + sage: pR. = Fq[] # optional - sage.rings.finite_rings + sage: A = matrix(pR, [[x^2+a, x^4+a], # optional - sage.rings.finite_rings + ....: [ x^3, a*x^4]]) + sage: W, U = A.reduced_form(transformation=True) # optional - sage.rings.finite_rings + sage: W, U # optional - sage.rings.finite_rings ( [ x^2 + a x^4 + a] [1 0] [x^3 + a*x^2 + a^2 a^2], [a 1] ) - sage: W.is_reduced() + sage: W.is_reduced() # optional - sage.rings.finite_rings True - sage: U*W == A + sage: U*W == A # optional - sage.rings.finite_rings True - sage: U.is_invertible() + sage: U.is_invertible() # optional - sage.rings.finite_rings True .. SEEALSO:: @@ -2567,30 +2570,32 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: M. = GF(7)[] - sage: A = matrix(M, 2, 3, [x, 1, 2*x, x, 1+x, 2]) - sage: A.hermite_form() + sage: M. = GF(7)[] # optional - sage.rings.finite_rings + sage: A = matrix(M, 2, 3, [x, 1, 2*x, x, 1+x, 2]) # optional - sage.rings.finite_rings + sage: A.hermite_form() # optional - sage.rings.finite_rings [ x 1 2*x] [ 0 x 5*x + 2] - sage: A.hermite_form(transformation=True) + sage: A.hermite_form(transformation=True) # optional - sage.rings.finite_rings ( [ x 1 2*x] [1 0] [ 0 x 5*x + 2], [6 1] ) - sage: A = matrix(M, 2, 3, [x, 1, 2*x, 2*x, 2, 4*x]) - sage: A.hermite_form(transformation=True, include_zero_rows=False) + sage: A = matrix(M, 2, 3, [x, 1, 2*x, 2*x, 2, 4*x]) # optional - sage.rings.finite_rings + sage: A.hermite_form(transformation=True, include_zero_rows=False) # optional - sage.rings.finite_rings ([ x 1 2*x], [0 4]) - sage: H, U = A.hermite_form(transformation=True, include_zero_rows=True); H, U + sage: H, U = A.hermite_form(transformation=True, # optional - sage.rings.finite_rings + ....: include_zero_rows=True); H, U ( [ x 1 2*x] [0 4] [ 0 0 0], [5 1] ) - sage: U * A == H + sage: U * A == H # optional - sage.rings.finite_rings True - sage: H, U = A.hermite_form(transformation=True, include_zero_rows=False) - sage: U * A + sage: H, U = A.hermite_form(transformation=True, # optional - sage.rings.finite_rings + ....: include_zero_rows=False) + sage: U * A # optional - sage.rings.finite_rings [ x 1 2*x] - sage: U * A == H + sage: U * A == H # optional - sage.rings.finite_rings True .. SEEALSO:: @@ -2627,26 +2632,26 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: A = Matrix(pR, 3, 2, \ - [[ 3*x^3 + 3*x, 2*x^3 + 4], \ - [ 3*x^3 + 6*x + 5, 6*x^3 + 5*x^2 + 1], \ - [ 2*x^3 + 2*x + 6, 3*x^2 + 2*x + 2]]) - sage: B = Matrix(pR, 3, 3, \ - [[ 3, x + 3, 6], \ - [3*x^3 + 3*x + 1, 4*x^2 + 3*x, 6*x^3 + x + 4], \ - [ 4*x^2 + x + 4, 3*x^2 + 4*x, 3*x^2 + 3*x + 2]]) - sage: Q,R = A.left_quo_rem(B); (Q,R) + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: A = Matrix(pR, 3, 2, # optional - sage.rings.finite_rings + ....: [[ 3*x^3 + 3*x, 2*x^3 + 4], + ....: [ 3*x^3 + 6*x + 5, 6*x^3 + 5*x^2 + 1], + ....: [ 2*x^3 + 2*x + 6, 3*x^2 + 2*x + 2]]) + sage: B = Matrix(pR, 3, 3, # optional - sage.rings.finite_rings + ....: [[ 3, x + 3, 6], + ....: [3*x^3 + 3*x + 1, 4*x^2 + 3*x, 6*x^3 + x + 4], + ....: [ 4*x^2 + x + 4, 3*x^2 + 4*x, 3*x^2 + 3*x + 2]]) + sage: Q, R = A.left_quo_rem(B); Q, R # optional - sage.rings.finite_rings ( [2*x^2 + 4*x + 6 6*x^2 + 4*x + 1] [ 3 1] [ 3*x^2 + 5*x 2*x^2 + x + 5] [ 6 5*x^2 + 2*x + 3] [ 6*x^2 + 3*x 4*x^2 + 6*x + 1], [ 2*x + 3 6*x + 3] ) - sage: rdegR = R.row_degrees(); rdegB = B.row_degrees() - sage: A == B*Q+R and all([rdegR[i] < rdegB[i] for i in range(3)]) + sage: rdegR = R.row_degrees(); rdegB = B.row_degrees() # optional - sage.rings.finite_rings + sage: A == B*Q+R and all(rdegR[i] < rdegB[i] for i in range(3)) # optional - sage.rings.finite_rings True - sage: A[:2,:].left_quo_rem(B) + sage: A[:2,:].left_quo_rem(B) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: row dimension of self should be the row dimension of @@ -2656,19 +2661,19 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): no quotient and remainder (unless the matrix has full row rank, see :meth:`right_quo_rem`):: - sage: Q,R = A[:2,:].left_quo_rem(B[:2,:]); (Q,R) + sage: Q, R = A[:2,:].left_quo_rem(B[:2,:]); Q, R # optional - sage.rings.finite_rings ( [ 3*x + 3 2*x + 1] [ 3*x^2 + 5*x 2*x^2 + x + 5] [ 5 0] [ 0 0], [4*x^2 + x + 2 4*x^2 + x] ) - sage: rdegR = R.row_degrees(); rdegB = B[:2,:].row_degrees() - sage: A[:2,:] == B[:2,:]*Q+R + sage: rdegR = R.row_degrees(); rdegB = B[:2,:].row_degrees() # optional - sage.rings.finite_rings + sage: A[:2,:] == B[:2,:]*Q+R # optional - sage.rings.finite_rings True - sage: all([rdegR[i] < rdegB[i] for i in range(len(rdegR))]) + sage: all([rdegR[i] < rdegB[i] for i in range(len(rdegR))]) # optional - sage.rings.finite_rings True - sage: A.left_quo_rem(B[:,:2]) + sage: A.left_quo_rem(B[:,:2]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: division of these matrices does not admit a remainder @@ -2722,37 +2727,37 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Case where `B` is a square, column reduced matrix:: - sage: pR. = GF(7)[] - sage: A = Matrix(pR, 2, 3, \ - [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], \ - [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: A = Matrix(pR, 2, 3, # optional - sage.rings.finite_rings + ....: [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], + ....: [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) - sage: B = Matrix(pR, 3, 3, \ - [[4*x^2 + 3*x + 3, 3*x^2 + 3*x + 1, 4*x^2 + x + 4], \ - [6*x^2 + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], \ - [5*x^2 + 3*x + 6, 6*x^2 + x + 4, 3*x^2 + 3*x + 2]]) - sage: B.is_reduced(row_wise=False) + sage: B = Matrix(pR, 3, 3, # optional - sage.rings.finite_rings + ....: [[4*x^2 + 3*x + 3, 3*x^2 + 3*x + 1, 4*x^2 + x + 4], + ....: [6*x^2 + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], + ....: [5*x^2 + 3*x + 6, 6*x^2 + x + 4, 3*x^2 + 3*x + 2]]) + sage: B.is_reduced(row_wise=False) # optional - sage.rings.finite_rings True - sage: Q,R = A.right_quo_rem(B); (Q,R) + sage: Q, R = A.right_quo_rem(B); Q, R # optional - sage.rings.finite_rings ( [ 4*x x + 2 6*x + 1] [ x + 2 6*x + 1 5*x + 4] [4*x + 3 x + 6 3*x + 4], [4*x + 2 2*x + 3 4*x + 3] ) - sage: A == Q*B+R and R.degree() < 2 + sage: A == Q*B+R and R.degree() < 2 # optional - sage.rings.finite_rings True - sage: A[:,:2].right_quo_rem(B) + sage: A[:,:2].right_quo_rem(B) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: column dimension of self should be the column dimension of the input matrix - sage: B = Matrix(pR, 3, 3, \ - [[3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], \ - [x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], \ - [6, 6*x^3 + x + 4, 3*x^2 + 3*x + 2]]) - sage: B.is_reduced(row_wise=False) + sage: B = Matrix(pR, 3, 3, # optional - sage.rings.finite_rings + ....: [[3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], + ....: [x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], + ....: [6, 6*x^3 + x + 4, 3*x^2 + 3*x + 2]]) + sage: B.is_reduced(row_wise=False) # optional - sage.rings.finite_rings True - sage: Q,R = A.right_quo_rem(B); (Q,R) + sage: Q, R = A.right_quo_rem(B); Q, R # optional - sage.rings.finite_rings ( [2*x^2 + 4*x + 6 3*x^2 + 5*x 6*x^2 + 3*x] [6*x^2 + 4*x + 1 2*x^2 + x + 5 4*x^2 + 6*x + 1], @@ -2760,20 +2765,20 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 3 6 2*x + 3] [ 1 5*x^2 + 2*x + 3 6*x + 3] ) - sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() - sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) + sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() # optional - sage.rings.finite_rings + sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) # optional - sage.rings.finite_rings True With a nonsingular but also non-reduced matrix, there exists a solution, but it might not be unique:: - sage: B = Matrix(pR, 3, 3, \ - [[ 5, 0, 2*x + 6], \ - [ 4*x, 3*x^2 + 4*x + 5, x + 1], \ - [3*x^2 + 5*x + 2, 6*x^3 + 4*x + 6, 3]]) - sage: B.det() != 0 and (not B.is_reduced(row_wise=False)) + sage: B = Matrix(pR, 3, 3, # optional - sage.rings.finite_rings + ....: [[ 5, 0, 2*x + 6], + ....: [ 4*x, 3*x^2 + 4*x + 5, x + 1], + ....: [3*x^2 + 5*x + 2, 6*x^3 + 4*x + 6, 3]]) + sage: B.det() != 0 and (not B.is_reduced(row_wise=False)) # optional - sage.rings.finite_rings True - sage: Q,R = A.right_quo_rem(B); (Q,R) + sage: Q, R = A.right_quo_rem(B); Q, R # optional - sage.rings.finite_rings ( [ 6*x^2 + 3*x 4*x^2 + 3*x + 1 5*x + 1] [ x^2 + 5*x + 5 5*x^2 + 3*x + 5 x + 2], @@ -2781,17 +2786,17 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 4*x + 5 x^2 + 2*x + 1 2] [ 6*x + 3 5*x^2 + 6 3] ) - sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() - sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) + sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() # optional - sage.rings.finite_rings + sage: A == Q*B+R and all(cdegR[i] < cdegB[i] for i in range(3)) # optional - sage.rings.finite_rings True - sage: Q2 = Matrix(pR, 2, 3, \ - [[6*x^2 + 3*x + 1, 4*x^2 + 3*x + 6, 5*x + 1], \ - [ x^2 + 5*x + 3, 5*x^2 + 3*x + 2, x + 2]]) - sage: R2 = Matrix(pR, 2, 3, \ - [[ 5*x, 3*x + 4, 5], \ - [4*x + 6, 5*x, 4]]) - sage: A == Q2*B + R2 + sage: Q2 = Matrix(pR, 2, 3, # optional - sage.rings.finite_rings + ....: [[6*x^2 + 3*x + 1, 4*x^2 + 3*x + 6, 5*x + 1], + ....: [ x^2 + 5*x + 3, 5*x^2 + 3*x + 2, x + 2]]) + sage: R2 = Matrix(pR, 2, 3, # optional - sage.rings.finite_rings + ....: [[ 5*x, 3*x + 4, 5], + ....: [4*x + 6, 5*x, 4]]) + sage: A == Q2*B + R2 # optional - sage.rings.finite_rings True The same remark holds more generally for full column rank matrices: @@ -2799,8 +2804,8 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): other cases (rank-deficient matrix `B` or matrix `B` having strictly fewer rows than columns) there may be no solution:: - sage: C = B.stack(B[1,:] + B[2,:]) # matrix 4 x 3, full column rank - sage: Q,R = A.right_quo_rem(C); (Q,R) + sage: C = B.stack(B[1,:] + B[2,:]) # 4 x 3, full column rank # optional - sage.rings.finite_rings + sage: Q, R = A.right_quo_rem(C); Q, R # optional - sage.rings.finite_rings ( [ 6*x^2 + 3*x 4*x^2 + 3*x + 1 5*x + 1 0] [ x^2 + 5*x + 5 5*x^2 + 3*x + 5 x + 2 0], @@ -2809,13 +2814,13 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 6*x + 3 5*x^2 + 6 3] ) - sage: A.right_quo_rem(B[:2,:]) # matrix 2 x 3, full row rank + sage: A.right_quo_rem(B[:2,:]) # matrix 2 x 3, full row rank # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: division of these matrices does not admit a remainder with the required degree property - sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular - sage: A.right_quo_rem(D) + sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular # optional - sage.rings.finite_rings + sage: A.right_quo_rem(D) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: division of these matrices does not admit a remainder @@ -2826,11 +2831,11 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): remainder, in which case this method will find it via normal form computation:: - sage: B = Matrix(pR, 1, 2, [[x, x]]) - sage: A = Matrix(pR, 1, 2, [[x, x+2]]) - sage: A.right_quo_rem(B) + sage: B = Matrix(pR, 1, 2, [[x, x]]) # optional - sage.rings.finite_rings + sage: A = Matrix(pR, 1, 2, [[x, x+2]]) # optional - sage.rings.finite_rings + sage: A.right_quo_rem(B) # optional - sage.rings.finite_rings ([1], [0 2]) - sage: A == 1*B + Matrix([[0,2]]) + sage: A == 1*B + Matrix([[0,2]]) # optional - sage.rings.finite_rings True .. SEEALSO:: @@ -2878,32 +2883,32 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: A = Matrix(pR, 2, 3, \ - [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], \ - [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: A = Matrix(pR, 2, 3, # optional - sage.rings.finite_rings + ....: [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], + ....: [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) - sage: B = Matrix(pR, 3, 3, \ - [[4*x^2 + 3*x + 3, 3*x^2 + 3*x + 1, 4*x^2 + x + 4], \ - [6*x^2 + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], \ - [5*x^2 + 3*x + 6, 6*x^2 + x + 4, 3*x^2 + 3*x + 2]]) - sage: B.is_reduced(row_wise=False) + sage: B = Matrix(pR, 3, 3, # optional - sage.rings.finite_rings + ....: [[4*x^2 + 3*x + 3, 3*x^2 + 3*x + 1, 4*x^2 + x + 4], + ....: [6*x^2 + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], + ....: [5*x^2 + 3*x + 6, 6*x^2 + x + 4, 3*x^2 + 3*x + 2]]) + sage: B.is_reduced(row_wise=False) # optional - sage.rings.finite_rings True - sage: Q,R = A._right_quo_rem_reduced(B); (Q,R) + sage: Q, R = A._right_quo_rem_reduced(B); Q, R # optional - sage.rings.finite_rings ( [ 4*x x + 2 6*x + 1] [ x + 2 6*x + 1 5*x + 4] [4*x + 3 x + 6 3*x + 4], [4*x + 2 2*x + 3 4*x + 3] ) - sage: A == Q*B+R and R.degree() < 2 + sage: A == Q*B+R and R.degree() < 2 # optional - sage.rings.finite_rings True - sage: B = Matrix(pR, 3, 3, \ - [[4*x + 3*x + 3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], \ - [6*x + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], \ - [6, 6*x^3 + x + 4, 3*x^2 + 3*x + 2]]) - sage: B.is_reduced(row_wise=False) + sage: B = Matrix(pR, 3, 3, # optional - sage.rings.finite_rings + ....: [[4*x + 3*x + 3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], + ....: [6*x + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], + ....: [6, 6*x^3 + x + 4, 3*x^2 + 3*x + 2]]) + sage: B.is_reduced(row_wise=False) # optional - sage.rings.finite_rings True - sage: Q,R = A._right_quo_rem_reduced(B); (Q,R) + sage: Q, R = A._right_quo_rem_reduced(B); Q, R # optional - sage.rings.finite_rings ( [2*x^2 + 4*x + 6 3*x^2 + 5*x 6*x^2 + 3*x] [6*x^2 + 4*x + 1 2*x^2 + x + 5 4*x^2 + 6*x + 1], @@ -2911,8 +2916,8 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 3 6 2*x + 3] [ 1 5*x^2 + 2*x + 3 6*x + 3] ) - sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() - sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) + sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() # optional - sage.rings.finite_rings + sage: A == Q*B+R and all(cdegR[i] < cdegB[i] for i in range(3)) # optional - sage.rings.finite_rings True """ # Step 0: find parameter d (delta in above reference) @@ -2957,16 +2962,16 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: A = Matrix(pR, 2, 3, \ - [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], \ - [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: A = Matrix(pR, 2, 3, # optional - sage.rings.finite_rings + ....: [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], + ....: [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) - sage: B = Matrix(pR, 3, 3, \ - [[4*x + 3*x + 3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], \ - [6*x + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], \ - [6, 6*x^3 + x + 4, 3*x^2 + 3*x + 2]]) - sage: Q,R = A._right_quo_rem_solve(B); (Q,R) + sage: B = Matrix(pR, 3, 3, # optional - sage.rings.finite_rings + ....: [[4*x + 3*x + 3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], + ....: [6*x + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], + ....: [6, 6*x^3 + x + 4, 3*x^2 + 3*x + 2]]) + sage: Q, R = A._right_quo_rem_solve(B); Q, R # optional - sage.rings.finite_rings ( [2*x^2 + 4*x + 6 3*x^2 + 5*x 6*x^2 + 3*x] [6*x^2 + 4*x + 1 2*x^2 + x + 5 4*x^2 + 6*x + 1], @@ -2974,22 +2979,22 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 3 6 2*x + 3] [ 1 5*x^2 + 2*x + 3 6*x + 3] ) - sage: B.is_reduced(row_wise=False) + sage: B.is_reduced(row_wise=False) # optional - sage.rings.finite_rings True - sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() - sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) + sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() # optional - sage.rings.finite_rings + sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) # optional - sage.rings.finite_rings True With a nonsingular but also non-reduced matrix, there exists a solution and one is found by this method, but it might not be unique:: - sage: B = Matrix(pR, 3, 3, \ - [[ 5, 0, 2*x + 6], \ - [ 4*x, 3*x^2 + 4*x + 5, x + 1], \ - [3*x^2 + 5*x + 2, 6*x^3 + 4*x + 6, 3]]) - sage: B.det() != 0 and (not B.is_reduced(row_wise=False)) + sage: B = Matrix(pR, 3, 3, # optional - sage.rings.finite_rings + ....: [[ 5, 0, 2*x + 6], + ....: [ 4*x, 3*x^2 + 4*x + 5, x + 1], + ....: [3*x^2 + 5*x + 2, 6*x^3 + 4*x + 6, 3]]) + sage: B.det() != 0 and not B.is_reduced(row_wise=False) # optional - sage.rings.finite_rings True - sage: Q,R = A._right_quo_rem_solve(B); (Q,R) + sage: Q, R = A._right_quo_rem_solve(B); Q, R # optional - sage.rings.finite_rings ( [ 6*x^2 + 3*x 4*x^2 + 3*x + 1 5*x + 1] [ x^2 + 5*x + 5 5*x^2 + 3*x + 5 x + 2], @@ -2997,17 +3002,17 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 4*x + 5 x^2 + 2*x + 1 2] [ 6*x + 3 5*x^2 + 6 3] ) - sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() - sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) + sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() # optional - sage.rings.finite_rings + sage: A == Q*B+R and all(cdegR[i] < cdegB[i] for i in range(3)) # optional - sage.rings.finite_rings True - sage: Q2 = Matrix(pR, 2, 3, \ - [[6*x^2 + 3*x + 1, 4*x^2 + 3*x + 6, 5*x + 1], \ - [ x^2 + 5*x + 3, 5*x^2 + 3*x + 2, x + 2]]) - sage: R2 = Matrix(pR, 2, 3, \ - [[ 5*x, 3*x + 4, 5], \ - [4*x + 6, 5*x, 4]]) - sage: A == Q2*B + R2 + sage: Q2 = Matrix(pR, 2, 3, # optional - sage.rings.finite_rings + ....: [[6*x^2 + 3*x + 1, 4*x^2 + 3*x + 6, 5*x + 1], + ....: [ x^2 + 5*x + 3, 5*x^2 + 3*x + 2, x + 2]]) + sage: R2 = Matrix(pR, 2, 3, # optional - sage.rings.finite_rings + ....: [[ 5*x, 3*x + 4, 5], + ....: [4*x + 6, 5*x, 4]]) + sage: A == Q2*B + R2 # optional - sage.rings.finite_rings True The same remark holds more generally for full column rank matrices: @@ -3015,8 +3020,8 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): other cases (rank-deficient or strictly fewer rows than columns) there might be no solution:: - sage: C = B.stack(B[1,:] + B[2,:]) # matrix 4 x 3, full column rank - sage: Q,R = A._right_quo_rem_solve(C); (Q,R) + sage: C = B.stack(B[1,:] + B[2,:]) # 4 x 3, full column rank # optional - sage.rings.finite_rings + sage: Q, R = A._right_quo_rem_solve(C); Q, R # optional - sage.rings.finite_rings ( [ 6*x^2 + 3*x 4*x^2 + 3*x + 1 5*x + 1 0] [ x^2 + 5*x + 5 5*x^2 + 3*x + 5 x + 2 0], @@ -3025,12 +3030,12 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 6*x + 3 5*x^2 + 6 3] ) - sage: A._right_quo_rem_solve(B[:2,:]) # matrix 2 x 3, full row rank + sage: A._right_quo_rem_solve(B[:2,:]) # 2 x 3, full row rank # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: dividing via system solving yields no solution - sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular - sage: A._right_quo_rem_solve(D) + sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular # optional - sage.rings.finite_rings + sage: A._right_quo_rem_solve(D) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: dividing via system solving yields no solution @@ -3039,11 +3044,11 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): columns), even when there is a solution, this method might not find it:: - sage: B = Matrix(pR, 1, 2, [[x, x]]) - sage: A = Matrix(pR, 1, 2, [[x, x+2]]) - sage: A == 1*B + Matrix([[0,2]]) # a valid quo_rem + sage: B = Matrix(pR, 1, 2, [[x, x]]) # optional - sage.rings.finite_rings + sage: A = Matrix(pR, 1, 2, [[x, x+2]]) # optional - sage.rings.finite_rings + sage: A == 1*B + Matrix([[0,2]]) # a valid quo_rem # optional - sage.rings.finite_rings True - sage: A._right_quo_rem_solve(B) + sage: A._right_quo_rem_solve(B) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: dividing via system solving yields no solution @@ -3124,24 +3129,24 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: B = Matrix(pR, [ \ - [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], \ - [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) - sage: A = Matrix(pR, 1, 3, [ \ - [3*x^4+3*x^3+4*x^2+5*x+1, x^4+x^3+5*x^2+4*x+4, 4*x^4+2*x^3+x]]) + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: B = Matrix(pR, [ # optional - sage.rings.finite_rings + ....: [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], + ....: [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) + sage: A = Matrix(pR, 1, 3, [ # optional - sage.rings.finite_rings + ....: [3*x^4+3*x^3+4*x^2+5*x+1, x^4+x^3+5*x^2+4*x+4, 4*x^4+2*x^3+x]]) - sage: (Q,R) = A.reduce(B,return_quotient=True); R + sage: Q, R = A.reduce(B,return_quotient=True); R # optional - sage.rings.finite_rings [3*x^4 + 3*x^3 + 4*x + 3 2*x + 2 2*x + 6] - sage: A == Q*B + R + sage: A == Q*B + R # optional - sage.rings.finite_rings True - sage: P = B.popov_form(); P.leading_positions(return_degree=True) + sage: P = B.popov_form(); P.leading_positions(return_degree=True) # optional - sage.rings.finite_rings ([1, 2], [2, 2]) - sage: R.degree_matrix() + sage: R.degree_matrix() # optional - sage.rings.finite_rings [4 1 1] - sage: A.reduce(P) == R + sage: A.reduce(P) == R # optional - sage.rings.finite_rings True - sage: A.reduce(P[:,:2]) + sage: A.reduce(P[:,:2]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: column dimension of self should be the column @@ -3149,41 +3154,41 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Demonstrating shifts:: - sage: (Qs,Rs) = A.reduce(B,shifts=[0,2,4],return_quotient=True); Rs + sage: Qs, Rs = A.reduce(B, shifts=[0,2,4], return_quotient=True); Rs # optional - sage.rings.finite_rings [3*x^4 + 3*x^3 + 6*x + 2 4*x^3 + 5*x 0] - sage: A == Qs*B + Rs + sage: A == Qs*B + Rs # optional - sage.rings.finite_rings True - sage: Ps = B.popov_form(shifts=[0,2,4]) - sage: Ps.leading_positions(shifts=[0,2,4],return_degree=True) + sage: Ps = B.popov_form(shifts=[0,2,4]) # optional - sage.rings.finite_rings + sage: Ps.leading_positions(shifts=[0,2,4], return_degree=True) # optional - sage.rings.finite_rings ([1, 2], [4, 0]) - sage: Rs.degree_matrix() + sage: Rs.degree_matrix() # optional - sage.rings.finite_rings [ 4 3 -1] - sage: A.reduce(Ps, shifts=[0,2,4]) == Rs + sage: A.reduce(Ps, shifts=[0,2,4]) == Rs # optional - sage.rings.finite_rings True If ``return_quotient`` is ``False``, only the normal form is returned:: - sage: R == A.reduce(B) and Rs == A.reduce(B,shifts=[0,2,4]) + sage: R == A.reduce(B) and Rs == A.reduce(B, shifts=[0,2,4]) # optional - sage.rings.finite_rings True Demonstrating column-wise normal forms, with a matrix `A` which has several columns, and a matrix `B` which does not have full column rank (its column-wise Popov form has a zero column):: - sage: A = Matrix(pR, 2, 2, \ - [[5*x^3 + 2*x^2 + 4*x + 1, x^3 + 4*x + 4], \ - [2*x^3 + 5*x^2 + 2*x + 4, 2*x^3 + 3*x + 2]]) - sage: (Q,R) = A.reduce(B,row_wise=False,return_quotient=True); R + sage: A = Matrix(pR, 2, 2, # optional - sage.rings.finite_rings + ....: [[5*x^3 + 2*x^2 + 4*x + 1, x^3 + 4*x + 4], + ....: [2*x^3 + 5*x^2 + 2*x + 4, 2*x^3 + 3*x + 2]]) + sage: (Q,R) = A.reduce(B,row_wise=False, return_quotient=True); R # optional - sage.rings.finite_rings [0 3] [0 0] - sage: A == B*Q + R + sage: A == B*Q + R # optional - sage.rings.finite_rings True - sage: P = B.popov_form(row_wise=False); P + sage: P = B.popov_form(row_wise=False); P # optional - sage.rings.finite_rings [x + 2 6 0] [ 0 1 0] - sage: P.leading_positions(row_wise=False, return_degree=True) + sage: P.leading_positions(row_wise=False, return_degree=True) # optional - sage.rings.finite_rings ([0, 1, -1], [1, 0, -1]) - sage: R.degree_matrix() + sage: R.degree_matrix() # optional - sage.rings.finite_rings [-1 0] [-1 -1] @@ -3283,26 +3288,26 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(97)[] + sage: pR. = GF(97)[] # optional - sage.rings.finite_rings We consider the following example from [Arne Storjohann, Notes on computing minimal approximant bases, 2006]:: - sage: order = 8; shifts = [1,1,0,0,0] - sage: pmat = Matrix(pR, 5, 1, [ \ - pR([35, 0, 41, 87, 3, 42, 22, 90]), \ - pR([80, 15, 62, 87, 14, 93, 24, 0]), \ - pR([42, 57, 90, 87, 22, 80, 71, 53]), \ - pR([37, 72, 74, 6, 5, 75, 23, 47]), \ - pR([36, 10, 74, 1, 29, 44, 87, 74]) ]) - sage: appbas = Matrix(pR, [ \ - [x+47, 57, 58*x+44, 9*x+23, 93*x+76], \ - [ 15, x+18, 52*x+23, 15*x+58, 93*x+88], \ - [ 17, 86, x^2+77*x+16, 76*x+29, 90*x+78], \ - [ 44, 36, 3*x+42, x^2+50*x+26, 85*x+44], \ - [ 2, 22, 54*x+94, 73*x+24, x^2+2*x+25] ]) - sage: appbas.is_minimal_approximant_basis(pmat,\ - order, shifts, row_wise=True, normal_form=True) + sage: order = 8; shifts = [1,1,0,0,0] # optional - sage.rings.finite_rings + sage: pmat = Matrix(pR, 5, 1, [ # optional - sage.rings.finite_rings + ....: pR([35, 0, 41, 87, 3, 42, 22, 90]), + ....: pR([80, 15, 62, 87, 14, 93, 24, 0]), + ....: pR([42, 57, 90, 87, 22, 80, 71, 53]), + ....: pR([37, 72, 74, 6, 5, 75, 23, 47]), + ....: pR([36, 10, 74, 1, 29, 44, 87, 74])]) + sage: appbas = Matrix(pR, [ # optional - sage.rings.finite_rings + ....: [x+47, 57, 58*x+44, 9*x+23, 93*x+76], + ....: [ 15, x+18, 52*x+23, 15*x+58, 93*x+88], + ....: [ 17, 86, x^2+77*x+16, 76*x+29, 90*x+78], + ....: [ 44, 36, 3*x+42, x^2+50*x+26, 85*x+44], + ....: [ 2, 22, 54*x+94, 73*x+24, x^2+2*x+25]]) + sage: appbas.is_minimal_approximant_basis( # optional - sage.rings.finite_rings + ....: pmat, order, shifts, row_wise=True, normal_form=True) True The matrix `x^8 \mathrm{Id}_5` is square, nonsingular, in Popov form, @@ -3310,34 +3315,35 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): not an approximant basis since its rows generate a module strictly contained in the set of approximants for ``pmat`` at order 8:: - sage: (x^8*Matrix.identity(pR, 5)).is_minimal_approximant_basis(\ - pmat, 8) + sage: M = x^8 * Matrix.identity(pR, 5) # optional - sage.rings.finite_rings + sage: M.is_minimal_approximant_basis(pmat, 8) # optional - sage.rings.finite_rings False Since ``pmat`` is a single column, with nonzero constant coefficient, its column-wise approximant bases at order 8 are all `1\times 1` matrices `[c x^8]` for some nonzero field element `c`:: - sage: Matrix(pR, [x^8]).is_minimal_approximant_basis(pmat, \ - 8, row_wise=False, normal_form=True) + sage: M = Matrix(pR, [x^8]) # optional - sage.rings.finite_rings + sage: M.is_minimal_approximant_basis( # optional - sage.rings.finite_rings + ....: pmat, 8, row_wise=False, normal_form=True) True Exceptions are raised if input dimensions are not sound:: - sage: appbas.is_minimal_approximant_basis(pmat, [8,8], shifts) + sage: appbas.is_minimal_approximant_basis(pmat, [8,8], shifts) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: order length should be the column dimension of the input matrix - sage: appbas.is_minimal_approximant_basis(pmat, \ - order, shifts, row_wise=False) + sage: appbas.is_minimal_approximant_basis( # optional - sage.rings.finite_rings + ....: pmat, order, shifts, row_wise=False) Traceback (most recent call last): ... ValueError: shifts length should be the column dimension of the input matrix - sage: Matrix(pR, [x^8]).is_minimal_approximant_basis(pmat, 8) + sage: Matrix(pR, [x^8]).is_minimal_approximant_basis(pmat, 8) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: column dimension should be the row dimension of the @@ -3493,60 +3499,63 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings sage: order = [4, 3]; shifts = [-1, 2, 0] - sage: F = Matrix(pR, [[5*x^3 + 4*x^2 + 4*x + 6, 5*x^2 + 4*x + 1], \ - [ 2*x^2 + 2*x + 3, 6*x^2 + 6*x + 3], \ - [4*x^3 + x + 1, 4*x^2 + 2*x + 3] ]) - sage: P = F.minimal_approximant_basis(order, shifts) - sage: P.is_minimal_approximant_basis(F, order, shifts) + sage: F = Matrix(pR, [[5*x^3 + 4*x^2 + 4*x + 6, 5*x^2 + 4*x + 1], # optional - sage.rings.finite_rings + ....: [ 2*x^2 + 2*x + 3, 6*x^2 + 6*x + 3], + ....: [4*x^3 + x + 1, 4*x^2 + 2*x + 3]]) + sage: P = F.minimal_approximant_basis(order, shifts) # optional - sage.rings.finite_rings + sage: P.is_minimal_approximant_basis(F, order, shifts) # optional - sage.rings.finite_rings True By default, the computed basis is not required to be in normal form (and will not be except in rare special cases):: - sage: P.is_minimal_approximant_basis(F, order, shifts, \ - normal_form=True) + sage: P.is_minimal_approximant_basis(F, order, shifts, # optional - sage.rings.finite_rings + ....: normal_form=True) False - sage: P = F.minimal_approximant_basis(order, shifts, normal_form=True) - sage: P.is_minimal_approximant_basis(F, order, shifts, \ - normal_form=True) + sage: P = F.minimal_approximant_basis(order, shifts, # optional - sage.rings.finite_rings + ....: normal_form=True) + sage: P.is_minimal_approximant_basis(F, order, shifts, # optional - sage.rings.finite_rings + ....: normal_form=True) True If shifts are not specified, they are chosen as uniform `[0,\ldots,0]` by default. Besides, if the orders are all the same, one can rather give a single integer:: - sage: F.minimal_approximant_basis(3) == \ - F.minimal_approximant_basis([3,3], shifts=None) + sage: (F.minimal_approximant_basis(3) == # optional - sage.rings.finite_rings + ....: F.minimal_approximant_basis([3,3], shifts=None)) True One can work column-wise by specifying ``row_wise=False``:: - sage: P = F.minimal_approximant_basis([5,2,2], [0,1], row_wise=False) - sage: P.is_minimal_approximant_basis(F, [5,2,2], \ - shifts=[0,1], row_wise=False) + sage: P = F.minimal_approximant_basis([5,2,2], [0,1], # optional - sage.rings.finite_rings + ....: row_wise=False) + sage: P.is_minimal_approximant_basis(F, [5,2,2], shifts=[0,1], # optional - sage.rings.finite_rings + ....: row_wise=False) True - sage: F.minimal_approximant_basis(3, row_wise=True) == \ - F.transpose().minimal_approximant_basis(3, row_wise=False).transpose() + sage: (F.minimal_approximant_basis(3, row_wise=True) == # optional - sage.rings.finite_rings + ....: F.transpose().minimal_approximant_basis( + ....: 3, row_wise=False).transpose()) True Errors are raised if the input dimensions are not sound:: - sage: P = F.minimal_approximant_basis([4], shifts) + sage: P = F.minimal_approximant_basis([4], shifts) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: order length should be the column dimension - sage: P = F.minimal_approximant_basis(order, [0,0,0,0]) + sage: P = F.minimal_approximant_basis(order, [0,0,0,0]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: shifts length should be the row dimension An error is raised if order does not contain only positive integers:: - sage: P = F.minimal_approximant_basis([1,0], shifts) + sage: P = F.minimal_approximant_basis([1,0], shifts) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: order should consist of positive integers @@ -3643,31 +3652,31 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings This method supports any number of columns or rows, as well as arbitrary shifts and orders:: - sage: order = [4, 1, 2]; shifts = [-3, 4] - sage: pmat = Matrix(pR, [[5*x^3 + 4*x^2 + 4*x + 6, 5, 4], \ - [2*x^3 + 2*x^2 + 2*x + 3, 6, 6*x + 3]]) - sage: appbas,rdeg = pmat._approximant_basis_iterative(order, \ - shifts) - sage: appbas.is_minimal_approximant_basis(pmat, order, shifts) + sage: order = [4, 1, 2]; shifts = [-3, 4] # optional - sage.rings.finite_rings + sage: pmat = Matrix(pR, [[5*x^3 + 4*x^2 + 4*x + 6, 5, 4], # optional - sage.rings.finite_rings + ....: [2*x^3 + 2*x^2 + 2*x + 3, 6, 6*x + 3]]) + sage: appbas, rdeg = pmat._approximant_basis_iterative(order, # optional - sage.rings.finite_rings + ....: shifts) + sage: appbas.is_minimal_approximant_basis(pmat, order, shifts) # optional - sage.rings.finite_rings True The returned list is the shifted row degrees of ``appbas``:: - sage: rdeg == appbas.row_degrees(shifts) + sage: rdeg == appbas.row_degrees(shifts) # optional - sage.rings.finite_rings True Approximant bases for the zero matrix are all constant unimodular matrices; in fact, this algorithm returns the identity:: - sage: pmat = Matrix(pR, 3, 2) - sage: appbas,rdeg = pmat._approximant_basis_iterative([2,5], \ - [5,0,-4]) - sage: rdeg == [5,0,-4] and appbas == Matrix.identity(pR, 3) + sage: pmat = Matrix(pR, 3, 2) # optional - sage.rings.finite_rings + sage: appbas,rdeg = pmat._approximant_basis_iterative([2,5], # optional - sage.rings.finite_rings + ....: [5,0,-4]) + sage: rdeg == [5,0,-4] and appbas == Matrix.identity(pR, 3) # optional - sage.rings.finite_rings True """ # Define parameters and perform some sanity checks @@ -3796,24 +3805,26 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(97)[] - sage: pmat = Matrix(pR, [[1],[x],[x**2]]) + sage: pR. = GF(97)[] # optional - sage.rings.finite_rings + sage: pmat = Matrix(pR, [[1], [x], [x**2]]) # optional - sage.rings.finite_rings - sage: kerbas = Matrix(pR, [[x,-1,0],[0,x,-1]]) - sage: kerbas.is_minimal_kernel_basis(pmat) + sage: kerbas = Matrix(pR, [[x,-1,0], [0,x,-1]]) # optional - sage.rings.finite_rings + sage: kerbas.is_minimal_kernel_basis(pmat) # optional - sage.rings.finite_rings True A matrix in Popov form which has the right rank, all rows in the kernel, but does not generate the kernel:: - sage: kerbas = Matrix(pR, [[x**2,0,-1],[0,x,-1]]) - sage: kerbas.is_minimal_kernel_basis(pmat) + sage: kerbas = Matrix(pR, [[x**2,0,-1], [0,x,-1]]) # optional - sage.rings.finite_rings + sage: kerbas.is_minimal_kernel_basis(pmat) # optional - sage.rings.finite_rings False Shifts and right kernel bases are supported (with ``row_wise``), and one can test whether the kernel basis is normalized in shifted-Popov form (with ``normal_form``):: - sage: kerbas = Matrix(pR, [[-x,-x**2],[1,0],[0,1]]) - sage: kerbas.is_minimal_kernel_basis(pmat.transpose(),row_wise=False,normal_form=True,shifts=[0,1,2]) + sage: kerbas = Matrix(pR, [[-x,-x**2], [1,0], [0,1]]) # optional - sage.rings.finite_rings + sage: kerbas.is_minimal_kernel_basis( # optional - sage.rings.finite_rings + ....: pmat.transpose(), row_wise=False, + ....: normal_form=True, shifts=[0,1,2]) True """ m = pmat.nrows() @@ -3916,25 +3927,26 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: pmat = Matrix([[(x+1)*(x+3)],[(x+1)*(x+3)+1]]) - sage: pmat.minimal_kernel_basis() + sage: pR. = GF(7)[] # optional - sage.rings.finite_rings + sage: pmat = Matrix([[(x+1)*(x+3)], [(x+1)*(x+3)+1]]) # optional - sage.rings.finite_rings + sage: pmat.minimal_kernel_basis() # optional - sage.rings.finite_rings [6*x^2 + 3*x + 3 x^2 + 4*x + 3] - sage: pmat = Matrix([[(x+1)*(x+3)],[(x+1)*(x+4)]]) - sage: pmat.minimal_kernel_basis() + sage: pmat = Matrix([[(x+1)*(x+3)], [(x+1)*(x+4)]]) # optional - sage.rings.finite_rings + sage: pmat.minimal_kernel_basis() # optional - sage.rings.finite_rings [6*x + 3 x + 3] - sage: pmat.minimal_kernel_basis(row_wise=False) + sage: pmat.minimal_kernel_basis(row_wise=False) # optional - sage.rings.finite_rings [] - sage: pmat = Matrix(pR, [[1,x,x**2]]) - sage: pmat.minimal_kernel_basis(row_wise=False,normal_form=True) + sage: pmat = Matrix(pR, [[1, x, x**2]]) # optional - sage.rings.finite_rings + sage: pmat.minimal_kernel_basis(row_wise=False, normal_form=True) # optional - sage.rings.finite_rings [x 0] [6 x] [0 6] - sage: pmat.minimal_kernel_basis(row_wise=False,normal_form=True,shifts=[0,1,2]) + sage: pmat.minimal_kernel_basis(row_wise=False, normal_form=True, # optional - sage.rings.finite_rings + ....: shifts=[0,1,2]) [ 6*x 6*x^2] [ 1 0] [ 0 1] diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index a2583f7497a..fac0254d7bf 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -7,11 +7,11 @@ EXAMPLES:: - sage: MS = MatrixSpace(QQ,6,6,sparse=True); MS + sage: MS = MatrixSpace(QQ, 6,6, sparse=True); MS Full MatrixSpace of 6 by 6 sparse matrices over Rational Field sage: MS.base_ring() Rational Field - sage: MS = MatrixSpace(ZZ,3,5,sparse=False); MS + sage: MS = MatrixSpace(ZZ, 3,5, sparse=False); MS Full MatrixSpace of 3 by 5 dense matrices over Integer Ring TESTS:: @@ -19,7 +19,7 @@ sage: matrix(RR,2,2,sparse=True) [0.000000000000000 0.000000000000000] [0.000000000000000 0.000000000000000] - sage: matrix(GF(11),2,2,sparse=True) + sage: matrix(GF(11), 2, 2, sparse=True) # optional - sage.rings.finite_rings [0 0] [0 0] """ @@ -119,26 +119,26 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: get_matrix_class(ZZ, 3, 3, False, 'generic') - sage: get_matrix_class(GF(2^15), 3, 3, False, None) + sage: get_matrix_class(GF(2^15), 3, 3, False, None) # optional - sage.rings.finite_rings - sage: get_matrix_class(GF(2^17), 3, 3, False, None) + sage: get_matrix_class(GF(2^17), 3, 3, False, None) # optional - sage.rings.finite_rings - sage: get_matrix_class(GF(2), 2, 2, False, 'm4ri') + sage: get_matrix_class(GF(2), 2, 2, False, 'm4ri') # optional - sage.rings.finite_rings - sage: get_matrix_class(GF(4), 2, 2, False, 'm4ri') + sage: get_matrix_class(GF(4), 2, 2, False, 'm4ri') # optional - sage.rings.finite_rings - sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-float') + sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-float') # optional - sage.rings.finite_rings - sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-double') + sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-double') # optional - sage.rings.finite_rings - sage: get_matrix_class(RDF, 2, 2, False, 'numpy') + sage: get_matrix_class(RDF, 2, 2, False, 'numpy') # optional - numpy - sage: get_matrix_class(CDF, 2, 3, False, 'numpy') + sage: get_matrix_class(CDF, 2, 3, False, 'numpy') # optional - numpy - sage: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') # optional - meataxe + sage: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') # optional - meataxe sage.rings.finite_rings sage: get_matrix_class(IntegerModRing(3), 4, 4, False, 'meataxe') # optional - meataxe @@ -146,7 +146,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): Traceback (most recent call last): ... ValueError: 'meataxe' matrix can only deal with finite fields of order < 256 - sage: get_matrix_class(GF(next_prime(255)), 4, 4, False, 'meataxe') + sage: get_matrix_class(GF(next_prime(255)), 4, 4, False, 'meataxe') # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: 'meataxe' matrix can only deal with finite fields of order < 256 @@ -155,7 +155,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): Traceback (most recent call last): ... ValueError: unknown matrix implementation 'crazy_matrix' over Integer Ring - sage: get_matrix_class(GF(3), 2, 2, False, 'm4ri') + sage: get_matrix_class(GF(3), 2, 2, False, 'm4ri') # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: 'm4ri' matrices are only available for fields of characteristic 2 and order <= 65536 @@ -168,19 +168,19 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): ... ValueError: 'linbox-double' matrices can only deal with order < 8388608 - sage: type(matrix(SR, 2, 2, 0)) + sage: type(matrix(SR, 2, 2, 0)) # optional - sage.symbolic - sage: type(matrix(GF(7), 2, range(4))) + sage: type(matrix(GF(7), 2, range(4))) # optional - sage.rings.finite_rings - sage: type(matrix(GF(16007), 2, range(4))) + sage: type(matrix(GF(16007), 2, range(4))) # optional - sage.rings.finite_rings sage: type(matrix(CBF, 2, range(4))) - sage: type(matrix(GF(2), 2, range(4))) + sage: type(matrix(GF(2), 2, range(4))) # optional - sage.rings.finite_rings - sage: type(matrix(GF(64,'z'), 2, range(4))) + sage: type(matrix(GF(64, 'z'), 2, range(4))) # optional - sage.rings.finite_rings - sage: type(matrix(GF(125,'z'), 2, range(4))) # optional - meataxe + sage: type(matrix(GF(125, 'z'), 2, range(4))) # optional - meataxe sage.rings.finite_rings """ @@ -477,36 +477,37 @@ class MatrixSpace(UniqueRepresentation, Parent): Check that different implementations play together as expected:: - sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') + sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # optional - sage.libs.flint sage: M2 = MatrixSpace(ZZ, 2, implementation='generic') - sage: type(M1(range(4))) + sage: type(M1(range(4))) # optional - sage.libs.flint sage: type(M2(range(4))) - sage: M1(M2.an_element()) + sage: M1(M2.an_element()) # optional - sage.libs.flint [ 0 1] [-1 2] - sage: M2(M1.an_element()) + sage: M2(M1.an_element()) # optional - sage.libs.flint [ 0 1] [-1 2] - sage: all(((A.get_action(B) is not None) == (A is B)) for A in [M1,M2] for B in [M1,M2]) + sage: all((A.get_action(B) is not None) == (A is B) # optional - sage.libs.flint + ....: for A in [M1, M2] for B in [M1, M2]) True Check that libgap matrices over finite fields are working properly:: - sage: M2 = MatrixSpace(GF(2), 5, implementation='gap') - sage: M2.one() + sage: M2 = MatrixSpace(GF(2), 5, implementation='gap') # optional - sage.libs.gap sage.rings.finite_rings + sage: M2.one() # optional - sage.libs.gap sage.rings.finite_rings [1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] - sage: m = M2.random_element() - sage: M1 = MatrixSpace(GF(2), 5) - sage: M1(m * m) == M1(m) * M1(m) + sage: m = M2.random_element() # optional - sage.libs.gap sage.rings.finite_rings + sage: M1 = MatrixSpace(GF(2), 5) # optional - sage.rings.finite_rings + sage: M1(m * m) == M1(m) * M1(m) # optional - sage.rings.finite_rings True """ @@ -521,16 +522,18 @@ def __classcall__(cls, base_ring, nrows, ncols=None, sparse=False, implementatio sage: M1 = MatrixSpace(QQ, 2) sage: M2 = MatrixSpace(QQ, 2) - sage: M3 = MatrixSpace(QQ, 2, implementation='flint') - sage: M1 is M2 and M1 is M3 + sage: M1 is M2 + True + sage: M3 = MatrixSpace(QQ, 2, implementation='flint') # optional - sage.libs.flint + sage: M1 is M3 # optional - sage.libs.flint True :: - sage: M = MatrixSpace(ZZ, 10, implementation="flint") - sage: M + sage: M = MatrixSpace(ZZ, 10, implementation="flint") # optional - sage.libs.flint + sage: M # optional - sage.libs.flint Full MatrixSpace of 10 by 10 dense matrices over Integer Ring - sage: loads(M.dumps()) is M + sage: loads(M.dumps()) is M # optional - sage.libs.flint True sage: MatrixSpace(ZZ, 10, implementation="foobar") @@ -712,7 +715,7 @@ def cardinality(self): EXAMPLES:: - sage: MatrixSpace(GF(3), 2, 3).cardinality() + sage: MatrixSpace(GF(3), 2, 3).cardinality() # optional - sage.rings.finite_rings 729 sage: MatrixSpace(ZZ, 2).cardinality() +Infinity @@ -733,7 +736,7 @@ def characteristic(self): sage: MatrixSpace(ZZ, 2).characteristic() 0 - sage: MatrixSpace(GF(9), 0).characteristic() + sage: MatrixSpace(GF(9), 0).characteristic() # optional - sage.rings.finite_rings 3 """ return self.base_ring().characteristic() @@ -758,11 +761,11 @@ def transposed(self): EXAMPLES:: - sage: MS = MatrixSpace(GF(3), 7, 10) - sage: MS.transposed + sage: MS = MatrixSpace(GF(3), 7, 10) # optional - sage.rings.finite_rings + sage: MS.transposed # optional - sage.rings.finite_rings Full MatrixSpace of 10 by 7 dense matrices over Finite Field of size 3 - sage: MS = MatrixSpace(GF(3), 7, 7) - sage: MS.transposed is MS + sage: MS = MatrixSpace(GF(3), 7, 7) # optional - sage.rings.finite_rings + sage: MS.transposed is MS # optional - sage.rings.finite_rings True sage: M = MatrixSpace(ZZ, 2, 3) @@ -780,15 +783,15 @@ def _copy_zero(self): EXAMPLES:: - sage: MS = MatrixSpace(GF(2),20,20) - sage: MS._copy_zero + sage: MS = MatrixSpace(GF(2), 20, 20) # optional - sage.rings.finite_rings + sage: MS._copy_zero # optional - sage.rings.finite_rings False - sage: MS = MatrixSpace(GF(3),20,20) - sage: MS._copy_zero + sage: MS = MatrixSpace(GF(3), 20, 20) # optional - sage.rings.finite_rings + sage: MS._copy_zero # optional - sage.rings.finite_rings True - sage: MS = MatrixSpace(GF(3),200,200) - sage: MS._copy_zero + sage: MS = MatrixSpace(GF(3), 200, 200) # optional - sage.rings.finite_rings + sage: MS._copy_zero # optional - sage.rings.finite_rings False sage: MS = MatrixSpace(ZZ,200,200) @@ -823,9 +826,10 @@ def _element_constructor_(self, entries, **kwds): EXAMPLES:: - sage: k = GF(7); G = MatrixGroup([matrix(k,2,[1,1,0,1]), matrix(k,2,[1,0,0,2])]) - sage: g = G.0 - sage: MatrixSpace(k,2)(g) + sage: k = GF(7) # optional - sage.rings.finite_rings + sage: G = MatrixGroup([matrix(k, 2, [1,1,0,1]), matrix(k, 2, [1,0,0,2])]) # optional - sage.rings.finite_rings + sage: g = G.0 # optional - sage.rings.finite_rings + sage: MatrixSpace(k, 2)(g) # optional - sage.rings.finite_rings [1 1] [0 1] @@ -875,14 +879,17 @@ def _element_constructor_(self, entries, **kwds): Ensure that :trac:`12020` is fixed:: + sage: rings = [ZZ, QQ, RealField(100), ComplexField(100), RDF, CDF] + sage: rings.append(PolynomialRing(QQ, 'x')) + sage: rings.append(PolynomialRing(CC, 2, 'x')) + sage: rings.append(SR) # optional - sage.symbolic + sage: rings.extend([GF(2), GF(11), GF(2^8,'a'), GF(3^19,'a')]) # optional - sage.rings.finite_rings sage: x = polygen(QQ) - sage: for R in [ZZ, QQ, RealField(100), ComplexField(100), RDF, CDF, - ....: SR, GF(2), GF(11), GF(2^8,'a'), GF(3^19,'a'), - ....: NumberField(x^3+2,'a'), CyclotomicField(4), - ....: PolynomialRing(QQ,'x'), PolynomialRing(CC,2,'x')]: - ....: A = MatrixSpace(R,60,30,sparse=False)(0) + sage: rings.extend([NumberField(x^3+2, 'a'), CyclotomicField(4)]) # optional - sage.rings.number_field + sage: for R in rings: + ....: A = MatrixSpace(R, 60, 30, sparse=False)(0) ....: B = A.augment(A) - ....: A = MatrixSpace(R,60,30,sparse=True)(0) + ....: A = MatrixSpace(R, 60, 30, sparse=True)(0) ....: B = A.augment(A) Check that :trac:`13012` is fixed:: @@ -943,8 +950,9 @@ def change_ring(self, R): EXAMPLES:: - sage: Mat(QQ,3,5).change_ring(GF(7)) - Full MatrixSpace of 3 by 5 dense matrices over Finite Field of size 7 + sage: Mat(QQ, 3, 5).change_ring(GF(7)) # optional - sage.rings.finite_rings + Full MatrixSpace of 3 by 5 dense matrices + over Finite Field of size 7 """ try: return self.__change_ring[R] @@ -968,9 +976,9 @@ def base_extend(self, R): EXAMPLES:: - sage: Mat(ZZ,3,5).base_extend(QQ) + sage: Mat(ZZ, 3, 5).base_extend(QQ) Full MatrixSpace of 3 by 5 dense matrices over Rational Field - sage: Mat(QQ,3,5).base_extend(GF(7)) + sage: Mat(QQ, 3, 5).base_extend(GF(7)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no base extension defined @@ -1124,13 +1132,13 @@ def _coerce_map_from_(self, S): There are also coercions possible from matrix group and arithmetic subgroups:: - sage: MS = MatrixSpace(GF(3), 2, 2) - sage: MS.coerce_map_from(GL(2, 3)) + sage: MS = MatrixSpace(GF(3), 2, 2) # optional - sage.rings.finite_rings + sage: MS.coerce_map_from(GL(2, 3)) # optional - sage.rings.finite_rings Coercion map: From: General Linear Group of degree 2 over Finite Field of size 3 To: Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 - sage: MS.coerce_map_from(GL(2, 2)) - sage: MS.coerce_map_from(Gamma1(5)) + sage: MS.coerce_map_from(GL(2, 2)) # optional - sage.rings.finite_rings + sage: MS.coerce_map_from(Gamma1(5)) # optional - sage.rings.finite_rings Coercion map: From: Congruence Subgroup Gamma1(5) To: Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 @@ -1264,7 +1272,7 @@ def _repr_(self): sage: MS Full MatrixSpace of 2 by 4 sparse matrices over Integer Ring - sage: MatrixSpace(ZZ, 2, implementation='flint') + sage: MatrixSpace(ZZ, 2, implementation='flint') # optional - sage.libs.flint Full MatrixSpace of 2 by 2 dense matrices over Integer Ring sage: MatrixSpace(ZZ, 2, implementation='generic') Full MatrixSpace of 2 by 2 dense matrices over Integer Ring (using Matrix_generic_dense) @@ -1319,14 +1327,14 @@ def __len__(self): EXAMPLES:: - sage: len(MatrixSpace(GF(3),3,2)) + sage: len(MatrixSpace(GF(3), 3, 2)) # optional - sage.rings.finite_rings 729 - sage: len(MatrixSpace(GF(3),2,3)) + sage: len(MatrixSpace(GF(3), 2, 3)) # optional - sage.rings.finite_rings 729 - sage: 3^(2*3) + sage: 3^(2*3) # optional - sage.rings.finite_rings 729 - sage: len(MatrixSpace(GF(2003),3,2)) + sage: len(MatrixSpace(GF(2003), 3, 2)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... OverflowError: cannot fit 'int' into an index-sized integer @@ -1352,20 +1360,20 @@ def __iter__(self): :: - sage: list( GF(5) ) + sage: list(GF(5)) # optional - sage.rings.finite_rings [0, 1, 2, 3, 4] - sage: MS = MatrixSpace(GF(5), 2, 2) - sage: l = list(MS) + sage: MS = MatrixSpace(GF(5), 2, 2) # optional - sage.rings.finite_rings + sage: l = list(MS) # optional - sage.rings.finite_rings Then, consider the following matrices:: - sage: A = MS([2,1,0,1]); A + sage: A = MS([2,1,0,1]); A # optional - sage.rings.finite_rings [2 1] [0 1] - sage: B = MS([1,2,1,0]); B + sage: B = MS([1,2,1,0]); B # optional - sage.rings.finite_rings [1 2] [1 0] - sage: C = MS([1,2,0,0]); C + sage: C = MS([1,2,0,0]); C # optional - sage.rings.finite_rings [1 2] [0 0] @@ -1374,9 +1382,9 @@ def __iter__(self): :: - sage: l.index(A) + sage: l.index(A) # optional - sage.rings.finite_rings 41 - sage: l.index(B) + sage: l.index(B) # optional - sage.rings.finite_rings 46 However, A would come after the matrix C since C has a lower weight @@ -1384,9 +1392,9 @@ def __iter__(self): :: - sage: l.index(A) + sage: l.index(A) # optional - sage.rings.finite_rings 41 - sage: l.index(C) + sage: l.index(C) # optional - sage.rings.finite_rings 19 The weights of matrices over other base rings are not as obvious. @@ -1413,11 +1421,11 @@ def __iter__(self): Some more examples:: - sage: MS = MatrixSpace(GF(2),2) - sage: a = list(MS) - sage: len(a) + sage: MS = MatrixSpace(GF(2), 2) # optional - sage.rings.finite_rings + sage: a = list(MS) # optional - sage.rings.finite_rings + sage: len(a) # optional - sage.rings.finite_rings 16 - sage: for m in a: + sage: for m in a: # optional - sage.rings.finite_rings ....: print(m) ....: print('-') [0 0] @@ -1471,11 +1479,11 @@ def __iter__(self): :: - sage: MS = MatrixSpace(GF(2),2, 3) - sage: a = list(MS) - sage: len(a) + sage: MS = MatrixSpace(GF(2), 2, 3) # optional - sage.rings.finite_rings + sage: a = list(MS) # optional - sage.rings.finite_rings + sage: len(a) # optional - sage.rings.finite_rings 64 - sage: a[0] + sage: a[0] # optional - sage.rings.finite_rings [0 0 0] [0 0 0] @@ -1497,11 +1505,11 @@ def __iter__(self): :: - sage: list( MatrixSpace(GF(2), 2, 0) ) + sage: list(MatrixSpace(GF(2), 2, 0)) # optional - sage.rings.finite_rings [[]] - sage: list( MatrixSpace(GF(2), 0, 2) ) + sage: list(MatrixSpace(GF(2), 0, 2)) # optional - sage.rings.finite_rings [[]] - sage: list( MatrixSpace(GF(2), 0, 0) ) + sage: list(MatrixSpace(GF(2), 0, 0)) # optional - sage.rings.finite_rings [[]] If the base ring does not support iteration (for example, with the @@ -1571,13 +1579,15 @@ def __getitem__(self, x): EXAMPLES:: - sage: MS = MatrixSpace(GF(3), 2, 2) - sage: MS['x'] - Univariate Polynomial Ring in x over Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 - sage: MS[0] + sage: MS = MatrixSpace(GF(3), 2, 2) # optional - sage.rings.finite_rings + sage: MS['x'] # optional - sage.rings.finite_rings + Univariate Polynomial Ring in x + over Full MatrixSpace of 2 by 2 dense matrices + over Finite Field of size 3 + sage: MS[0] # optional - sage.rings.finite_rings [0 0] [0 0] - sage: MS[9] + sage: MS[9] # optional - sage.rings.finite_rings [0 2] [0 0] @@ -1778,10 +1788,10 @@ def identity_matrix(self): Check different implementations:: - sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') + sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # optional - sage.libs.flint sage: M2 = MatrixSpace(ZZ, 2, implementation='generic') - sage: type(M1.identity_matrix()) + sage: type(M1.identity_matrix()) # optional - sage.libs.flint sage: type(M2.identity_matrix()) @@ -1836,10 +1846,10 @@ def diagonal_matrix(self, entries): Check different implementations:: - sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') + sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # optional - sage.libs.flint sage: M2 = MatrixSpace(ZZ, 2, implementation='generic') - sage: type(M1.diagonal_matrix([1, 2])) + sage: type(M1.diagonal_matrix([1, 2])) # optional - sage.libs.flint sage: type(M2.diagonal_matrix([1, 2])) @@ -1872,9 +1882,9 @@ def is_sparse(self): EXAMPLES:: - sage: Mat(GF(2011),10000).is_sparse() + sage: Mat(GF(2011), 10000).is_sparse() # optional - sage.rings.finite_rings False - sage: Mat(GF(2011),10000,sparse=True).is_sparse() + sage: Mat(GF(2011), 10000, sparse=True).is_sparse() # optional - sage.rings.finite_rings True """ return self.__is_sparse @@ -1885,7 +1895,7 @@ def is_finite(self): EXAMPLES:: - sage: MatrixSpace(GF(101), 10000).is_finite() + sage: MatrixSpace(GF(101), 10000).is_finite() # optional - sage.rings.finite_rings True sage: MatrixSpace(QQ, 2).is_finite() False @@ -1901,10 +1911,10 @@ def gen(self, n): EXAMPLES:: - sage: M = Mat(GF(7),10000,5); M.ngens() + sage: M = Mat(GF(7), 10000, 5); M.ngens() # optional - sage.rings.finite_rings 50000 - sage: a = M.10 - sage: a[:4] + sage: a = M.10 # optional - sage.rings.finite_rings + sage: a[:4] # optional - sage.rings.finite_rings [0 0 0 0 0] [0 0 0 0 0] [1 0 0 0 0] @@ -1928,10 +1938,10 @@ def zero_matrix(self): EXAMPLES:: - sage: z = MatrixSpace(GF(7),2,4).zero_matrix(); z + sage: z = MatrixSpace(GF(7), 2, 4).zero_matrix(); z # optional - sage.rings.finite_rings [0 0 0 0] [0 0 0 0] - sage: z.is_mutable() + sage: z.is_mutable() # optional - sage.rings.finite_rings False TESTS:: @@ -1962,7 +1972,7 @@ def ngens(self): EXAMPLES:: - sage: M = Mat(GF(7),100,200); M.ngens() + sage: M = Mat(GF(7), 100, 200); M.ngens() # optional - sage.rings.finite_rings 20000 """ return self.dimension() @@ -2031,17 +2041,17 @@ def matrix(self, x=None, **kwds): sage: MS([[1],[2]]) [1] [2] - sage: MS = MatrixSpace(CC,2,1) - sage: F = NumberField(x^2+1, name='x') - sage: MS([F(1),F(0)]) + sage: MS = MatrixSpace(CC, 2, 1) + sage: F = NumberField(x^2 + 1, name='x') # optional - sage.rings.number_field + sage: MS([F(1), F(0)]) # optional - sage.rings.number_field [ 1.00000000000000] [0.000000000000000] :trac:`10628` allowed to provide the data as lists of matrices, but :trac:`13012` prohibited it:: - sage: MS = MatrixSpace(ZZ,4,2) - sage: MS0 = MatrixSpace(ZZ,2) + sage: MS = MatrixSpace(ZZ, 4,2) + sage: MS0 = MatrixSpace(ZZ, 2) sage: MS.matrix([MS0([1,2,3,4]), MS0([5,6,7,8])]) Traceback (most recent call last): ... @@ -2056,29 +2066,29 @@ def matrix(self, x=None, **kwds): Check that :trac:`13302` is fixed:: - sage: MatrixSpace(Qp(3),1,1)([Qp(3).zero()]) + sage: MatrixSpace(Qp(3), 1,1)([Qp(3).zero()]) # optional - sage.rings.padics [0] - sage: MatrixSpace(Qp(3),1,1)([Qp(3)(4/3)]) + sage: MatrixSpace(Qp(3), 1,1)([Qp(3)(4/3)]) # optional - sage.rings.padics [3^-1 + 1 + O(3^19)] One-rowed matrices over combinatorial free modules used to break the constructor (:trac:`17124`). Check that this is fixed:: - sage: Sym = SymmetricFunctions(ZZ) - sage: h = Sym.h() - sage: MatrixSpace(h,1,1)([h[1]]) + sage: Sym = SymmetricFunctions(ZZ) # optional - sage.combinat + sage: h = Sym.h() # optional - sage.combinat + sage: MatrixSpace(h, 1,1)([h[1]]) # optional - sage.combinat [h[1]] - sage: MatrixSpace(h,2,1)([h[1], h[2]]) + sage: MatrixSpace(h, 2,1)([h[1], h[2]]) # optional - sage.combinat [h[1]] [h[2]] Converting sparse to dense matrices used to be too slow (:trac:`20470`). Check that this is fixed:: - sage: m = identity_matrix(GF(2), 2000, sparse=True) - sage: MS = MatrixSpace(GF(2), 2000, sparse=False) - sage: md = MS(m) # used to be slow - sage: md.parent() is MS + sage: m = identity_matrix(GF(2), 2000, sparse=True) # optional - sage.rings.finite_rings + sage: MS = MatrixSpace(GF(2), 2000, sparse=False) # optional - sage.rings.finite_rings + sage: md = MS(m) # used to be slow # optional - sage.rings.finite_rings + sage: md.parent() is MS # optional - sage.rings.finite_rings True """ return self(x, **kwds) @@ -2091,12 +2101,12 @@ def matrix_space(self, nrows=None, ncols=None, sparse=False): EXAMPLES:: - sage: M = Mat(GF(7),100,200) - sage: M.matrix_space(5000) + sage: M = Mat(GF(7), 100, 200) # optional - sage.rings.finite_rings + sage: M.matrix_space(5000) # optional - sage.rings.finite_rings Full MatrixSpace of 5000 by 200 dense matrices over Finite Field of size 7 - sage: M.matrix_space(ncols=5000) + sage: M.matrix_space(ncols=5000) # optional - sage.rings.finite_rings Full MatrixSpace of 100 by 5000 dense matrices over Finite Field of size 7 - sage: M.matrix_space(sparse=True) + sage: M.matrix_space(sparse=True) # optional - sage.rings.finite_rings Full MatrixSpace of 100 by 200 sparse matrices over Finite Field of size 7 """ if nrows is None: @@ -2112,7 +2122,7 @@ def ncols(self): EXAMPLES:: - sage: M = Mat(ZZ['x'],200000,500000,sparse=True) + sage: M = Mat(ZZ['x'], 200000, 500000, sparse=True) sage: M.ncols() 500000 """ @@ -2124,7 +2134,7 @@ def nrows(self): EXAMPLES:: - sage: M = Mat(ZZ,200000,500000) + sage: M = Mat(ZZ, 200000, 500000) sage: M.nrows() 200000 """ @@ -2156,7 +2166,7 @@ def column_space(self): EXAMPLES:: - sage: M = Mat(GF(9,'a'),20,5,sparse=True); M.column_space() + sage: M = Mat(GF(9,'a'), 20, 5, sparse=True); M.column_space() # optional - sage.rings.finite_rings Sparse vector space of dimension 20 over Finite Field in a of size 3^2 """ try: @@ -2215,8 +2225,8 @@ def random_element(self, density=None, *args, **kwds): sage: M = Mat(QQ, 3, sparse=True).random_element() sage: TestSuite(M).run() - sage: M = Mat(GF(9,'a'), 3, sparse=True).random_element() - sage: TestSuite(M).run() + sage: M = Mat(GF(9,'a'), 3, sparse=True).random_element() # optional - sage.rings.finite_rings + sage: TestSuite(M).run() # optional - sage.rings.finite_rings """ Z = self.zero_matrix().__copy__() if density is None: @@ -2248,8 +2258,8 @@ def _an_element_(self): Check that this works for large matrices and that it returns a matrix which is not too trivial:: - sage: M = MatrixSpace(GF(2), 100, 100).an_element() - sage: M.rank() >= 2 + sage: M = MatrixSpace(GF(2), 100, 100).an_element() # optional - sage.rings.finite_rings + sage: M.rank() >= 2 # optional - sage.rings.finite_rings True Check that this works for sparse matrices:: @@ -2313,8 +2323,8 @@ def some_elements(self): [ 1/2 -1/2 2] [1 0 0] [0 1 0] [0 0 1] [0 0 0] [0 0 0] [0 0 0] [ -2 0 1], [0 0 0], [0 0 0], [0 0 0], [1 0 0], [0 1 0], [0 0 1] ) - sage: M = MatrixSpace(SR, 2, 2) - sage: tuple(M.some_elements()) + sage: M = MatrixSpace(SR, 2, 2) # optional - sage.symbolic + sage: tuple(M.some_elements()) # optional - sage.symbolic ( [some_variable some_variable] [1 0] [0 1] [0 0] [0 0] [some_variable some_variable], [0 0], [0 0], [1 0], [0 1] @@ -2330,12 +2340,12 @@ def _magma_init_(self, magma): :: - sage: magma(MatrixSpace(QQ,3)) # optional - magma + sage: magma(MatrixSpace(QQ, 3)) # optional - magma Full Matrix Algebra of degree 3 over Rational Field :: - sage: magma(MatrixSpace(Integers(8),2,3)) # optional - magma + sage: magma(MatrixSpace(Integers(8), 2, 3)) # optional - magma Full RMatrixSpace of 2 by 3 matrices over IntegerRing(8) """ K = magma(self.base_ring()) @@ -2349,9 +2359,9 @@ def _polymake_init_(self): EXAMPLES:: - sage: polymake(MatrixSpace(QQ,3)) # optional - jupymake + sage: polymake(MatrixSpace(QQ, 3)) # optional - jupymake Matrix - sage: polymake(MatrixSpace(QuadraticField(5),3)) # optional - jupymake + sage: polymake(MatrixSpace(QuadraticField(5), 3)) # optional - jupymake # optional - sage.rings.number_field Matrix """ from sage.interfaces.polymake import polymake @@ -2456,23 +2466,23 @@ def _test_trivial_matrices_inverse(ring, sparse=True, implementation=None, check sage: from sage.matrix.matrix_space import _test_trivial_matrices_inverse as tinv sage: tinv(ZZ, sparse=True) - sage: tinv(ZZ, sparse=False, implementation='flint') + sage: tinv(ZZ, sparse=False, implementation='flint') # optional - sage.libs.flint sage: tinv(ZZ, sparse=False, implementation='generic') sage: tinv(QQ, sparse=True) - sage: tinv(QQ, sparse=False, implementation='flint') + sage: tinv(QQ, sparse=False, implementation='flint') # optional - sage.libs.flint sage: tinv(QQ, sparse=False, implementation='generic') - sage: tinv(GF(11), sparse=True) - sage: tinv(GF(11), sparse=False) - sage: tinv(GF(2), sparse=True) - sage: tinv(GF(2), sparse=False) - sage: tinv(SR, sparse=True) - sage: tinv(SR, sparse=False) + sage: tinv(GF(11), sparse=True) # optional - sage.rings.finite_rings + sage: tinv(GF(11), sparse=False) # optional - sage.rings.finite_rings + sage: tinv(GF(2), sparse=True) # optional - sage.rings.finite_rings + sage: tinv(GF(2), sparse=False) # optional - sage.rings.finite_rings + sage: tinv(SR, sparse=True) # optional - sage.symbolic + sage: tinv(SR, sparse=False) # optional - sage.symbolic sage: tinv(RDF, sparse=True) sage: tinv(RDF, sparse=False) sage: tinv(CDF, sparse=True) sage: tinv(CDF, sparse=False) - sage: tinv(CyclotomicField(7), sparse=True) - sage: tinv(CyclotomicField(7), sparse=False) + sage: tinv(CyclotomicField(7), sparse=True) # optional - sage.rings.number_field + sage: tinv(CyclotomicField(7), sparse=False) # optional - sage.rings.number_field sage: tinv(QQ['x,y'], sparse=True) sage: tinv(QQ['x,y'], sparse=False) diff --git a/src/sage/matrix/matrix_sparse.pyx b/src/sage/matrix/matrix_sparse.pyx index dcd9c2e1550..905cdf9fc0d 100644 --- a/src/sage/matrix/matrix_sparse.pyx +++ b/src/sage/matrix/matrix_sparse.pyx @@ -1,3 +1,4 @@ + r""" Base class for sparse matrices """ @@ -45,6 +46,7 @@ cdef class Matrix_sparse(matrix.Matrix): EXAMPLES:: + sage: x = polygen(ZZ, 'x') sage: A = matrix(QQ['x,y'], 2, [0,-1,2*x,-2], sparse=True); A [ 0 -1] [2*x -2] @@ -636,13 +638,14 @@ cdef class Matrix_sparse(matrix.Matrix): EXAMPLES:: sage: m = matrix(ZZ, 3, range(9), sparse=True) - sage: phi = ZZ.hom(GF(5)) - sage: m.apply_morphism(phi) + sage: phi = ZZ.hom(GF(5)) # optional - sage.rings.finite_rings + sage: m.apply_morphism(phi) # optional - sage.rings.finite_rings [0 1 2] [3 4 0] [1 2 3] - sage: m.apply_morphism(phi).parent() - Full MatrixSpace of 3 by 3 sparse matrices over Finite Field of size 5 + sage: m.apply_morphism(phi).parent() # optional - sage.rings.finite_rings + Full MatrixSpace of 3 by 3 sparse matrices + over Finite Field of size 5 """ R = phi.codomain() M = sage.matrix.matrix_space.MatrixSpace(R, self._nrows, @@ -671,31 +674,33 @@ cdef class Matrix_sparse(matrix.Matrix): EXAMPLES:: sage: m = matrix(ZZ, 10000, {(1,2): 17}, sparse=True) - sage: k. = GF(9) - sage: f = lambda x: k(x) - sage: n = m.apply_map(f) - sage: n.parent() - Full MatrixSpace of 10000 by 10000 sparse matrices over Finite Field in a of size 3^2 - sage: n[1,2] + sage: k. = GF(9) # optional - sage.rings.finite_rings + sage: f = lambda x: k(x) # optional - sage.rings.finite_rings + sage: n = m.apply_map(f) # optional - sage.rings.finite_rings + sage: n.parent() # optional - sage.rings.finite_rings + Full MatrixSpace of 10000 by 10000 sparse matrices + over Finite Field in a of size 3^2 + sage: n[1, 2] # optional - sage.rings.finite_rings 2 An example where the codomain is explicitly specified. :: - sage: n = m.apply_map(lambda x:x%3, GF(3)) - sage: n.parent() - Full MatrixSpace of 10000 by 10000 sparse matrices over Finite Field of size 3 - sage: n[1,2] + sage: n = m.apply_map(lambda x: x%3, GF(3)) # optional - sage.rings.finite_rings + sage: n.parent() # optional - sage.rings.finite_rings + Full MatrixSpace of 10000 by 10000 sparse matrices + over Finite Field of size 3 + sage: n[1, 2] # optional - sage.rings.finite_rings 2 If we did not specify the codomain, the resulting matrix in the above case ends up over `\ZZ` again:: - sage: n = m.apply_map(lambda x:x%3) + sage: n = m.apply_map(lambda x: x%3) sage: n.parent() Full MatrixSpace of 10000 by 10000 sparse matrices over Integer Ring - sage: n[1,2] + sage: n[1, 2] 2 If self is subdivided, the result will be as well:: @@ -806,8 +811,8 @@ cdef class Matrix_sparse(matrix.Matrix): EXAMPLES:: - sage: m = matrix(2, [x^i for i in range(4)], sparse=True) - sage: m._derivative(x) + sage: m = matrix(2, [x^i for i in range(4)], sparse=True) # optional - sage.symbolic + sage: m._derivative(x) # optional - sage.symbolic [ 0 1] [ 2*x 3*x^2] """ @@ -1175,10 +1180,10 @@ cdef class Matrix_sparse(matrix.Matrix): Check that the bug in :trac:`13854` has been fixed:: - sage: A. = FreeAlgebra(QQ, 2) - sage: P. = A.g_algebra(relations={y*x:-x*y}, order = 'lex') - sage: M = Matrix([[x]], sparse=True) - sage: w = vector([y]) + sage: A. = FreeAlgebra(QQ, 2) # optional - sage.combinat + sage: P. = A.g_algebra(relations={y*x: -x*y}, order='lex') # optional - sage.combinat + sage: M = Matrix([[x]], sparse=True) # optional - sage.combinat + sage: w = vector([y]) # optional - sage.combinat doctest:...: UserWarning: You are constructing a free module over a noncommutative ring. Sage does not have a concept of left/right and both sided modules, so be careful. @@ -1189,7 +1194,7 @@ cdef class Matrix_sparse(matrix.Matrix): of left/right and both sided modules, so be careful. It's also not guaranteed that all multiplications are done from the right side. - sage: M*w + sage: M*w # optional - sage.combinat (x*y) """ cdef int i, j diff --git a/src/sage/matrix/operation_table.py b/src/sage/matrix/operation_table.py index 79acaaf8390..c7c655463d4 100644 --- a/src/sage/matrix/operation_table.py +++ b/src/sage/matrix/operation_table.py @@ -81,8 +81,8 @@ class OperationTable(SageObject): In its most basic use, the table needs a structure and an operation:: sage: from sage.matrix.operation_table import OperationTable - sage: G=SymmetricGroup(3) - sage: OperationTable(G, operation=operator.mul) + sage: G = SymmetricGroup(3) # optional - sage.groups + sage: OperationTable(G, operation=operator.mul) # optional - sage.groups * a b c d e f +------------ a| a b c d e f @@ -96,7 +96,7 @@ class OperationTable(SageObject): want:: sage: from sage.matrix.operation_table import OperationTable - sage: R=Integers(6) + sage: R = Integers(6) sage: OperationTable(R, operation=operator.add) + a b c d e f +------------ @@ -112,8 +112,8 @@ class OperationTable(SageObject): 26 elements. :: sage: from sage.matrix.operation_table import OperationTable - sage: G=DihedralGroup(14) - sage: OperationTable(G, operator.mul, names='letters') + sage: G = DihedralGroup(14) # optional - sage.groups + sage: OperationTable(G, operator.mul, names='letters') # optional - sage.groups * aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az ba bb +------------------------------------------------------------------------------------ aa| aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az ba bb @@ -149,8 +149,8 @@ class OperationTable(SageObject): zeros to make a common width. :: sage: from sage.matrix.operation_table import OperationTable - sage: G=AlternatingGroup(4) - sage: OperationTable(G, operator.mul, names='digits') + sage: G = AlternatingGroup(4) # optional - sage.groups + sage: OperationTable(G, operator.mul, names='digits') # optional - sage.groups * 00 01 02 03 04 05 06 07 08 09 10 11 +------------------------------------ 00| 00 01 02 03 04 05 06 07 08 09 10 11 @@ -171,8 +171,8 @@ class OperationTable(SageObject): of the elements can be used. :: sage: from sage.matrix.operation_table import OperationTable - sage: G=AlternatingGroup(3) - sage: OperationTable(G, operator.mul, names='elements') + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: OperationTable(G, operator.mul, names='elements') # optional - sage.groups * () (1,2,3) (1,3,2) +------------------------ ()| () (1,2,3) (1,3,2) @@ -185,15 +185,15 @@ class OperationTable(SageObject): method. :: sage: from sage.matrix.operation_table import OperationTable - sage: G = QuaternionGroup() - sage: T = OperationTable(G, operator.mul) - sage: T.column_keys() + sage: G = QuaternionGroup() # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T.column_keys() # optional - sage.groups ((), (1,2,3,4)(5,6,7,8), ..., (1,8,3,6)(2,7,4,5)) - sage: names=['1', 'I', '-1', '-I', 'J', '-K', '-J', 'K'] - sage: T.change_names(names=names) - sage: sorted(T.translation().items()) + sage: names=['1', 'I', '-1', '-I', 'J', '-K', '-J', 'K'] # optional - sage.groups + sage: T.change_names(names=names) # optional - sage.groups + sage: sorted(T.translation().items()) # optional - sage.groups [('-1', (1,3)(2,4)(5,7)(6,8)), ..., ('K', (1,8,3,6)(2,7,4,5))] - sage: T + sage: T # optional - sage.groups * 1 I -1 -I J -K -J K +------------------------ 1| 1 I -1 -I J -K -J K @@ -278,10 +278,10 @@ class OperationTable(SageObject): odd. The LaTeX version works much better. :: sage: from sage.matrix.operation_table import OperationTable - sage: L=FiniteSemigroups().example(()) + sage: L = FiniteSemigroups().example(()) sage: L An example of a finite semigroup: the left regular band generated by () - sage: T=OperationTable(L, operation=operator.mul) + sage: T = OperationTable(L, operation=operator.mul) sage: T * + @@ -302,11 +302,11 @@ class OperationTable(SageObject): Here we demonstrate the proper use first:: sage: from sage.matrix.operation_table import OperationTable - sage: H=CyclicPermutationGroup(4) - sage: H.list() + sage: H = CyclicPermutationGroup(4) # optional - sage.groups + sage: H.list() # optional - sage.groups [(), (1,2,3,4), (1,3)(2,4), (1,4,3,2)] - sage: elts = ['()', '(1,3)(2,4)'] - sage: OperationTable(H, operator.mul, elements=elts) + sage: elts = ['()', '(1,3)(2,4)'] # optional - sage.groups + sage: OperationTable(H, operator.mul, elements=elts) # optional - sage.groups * a b +---- a| a b @@ -315,11 +315,11 @@ class OperationTable(SageObject): This can be rewritten so as to pass the actual elements of the group ``H``, using a simple ``for`` loop:: - sage: L = H.list() #list of elements of the group H - sage: elts = [L[i] for i in {0, 2}] - sage: elts + sage: L = H.list() #list of elements of the group H # optional - sage.groups + sage: elts = [L[i] for i in {0, 2}] # optional - sage.groups + sage: elts # optional - sage.groups [(), (1,3)(2,4)] - sage: OperationTable(H, operator.mul, elements=elts) + sage: OperationTable(H, operator.mul, elements=elts) # optional - sage.groups * a b +---- a| a b @@ -327,31 +327,31 @@ class OperationTable(SageObject): Here are a couple of improper uses:: - sage: elts.append(5) - sage: OperationTable(H, operator.mul, elements=elts) + sage: elts.append(5) # optional - sage.groups + sage: OperationTable(H, operator.mul, elements=elts) # optional - sage.groups Traceback (most recent call last): ... TypeError: unable to coerce 5 into Cyclic group of order 4 as a permutation group - sage: elts[2] = '(1,3,2,4)' - sage: OperationTable(H, operator.mul, elements=elts) + sage: elts[2] = '(1,3,2,4)' # optional - sage.groups + sage: OperationTable(H, operator.mul, elements=elts) # optional - sage.groups Traceback (most recent call last): ... TypeError: unable to coerce (1,3,2,4) into Cyclic group of order 4 as a permutation group - sage: elts[2] = '(1,2,3,4)' - sage: OperationTable(H, operator.mul, elements=elts) + sage: elts[2] = '(1,2,3,4)' # optional - sage.groups + sage: OperationTable(H, operator.mul, elements=elts) # optional - sage.groups Traceback (most recent call last): ... ValueError: (1,3)(2,4)*(1,2,3,4)=(1,4,3,2), and so the set is not closed Unusable functions should be recognized as such:: - sage: H=CyclicPermutationGroup(4) - sage: OperationTable(H, operator.add) + sage: H = CyclicPermutationGroup(4) # optional - sage.groups + sage: OperationTable(H, operator.add) # optional - sage.groups Traceback (most recent call last): ... TypeError: elements () and () of Cyclic group of order 4 as a permutation group are incompatible with operation: - sage: from operator import xor - sage: OperationTable(H, xor) + sage: from operator import xor # optional - sage.groups + sage: OperationTable(H, xor) # optional - sage.groups Traceback (most recent call last): ... TypeError: elements () and () of Cyclic group of order 4 as a permutation group are incompatible with operation: @@ -359,9 +359,9 @@ class OperationTable(SageObject): We construct the multiplication table for a finite finitely presented group, where there is no normalization done when computing the hash:: - sage: GU. = FreeGroup() - sage: gr0 = GU / (s^(-2)*t*s*t, t^(-2)*s*t*s, s*t*s*t) - sage: gr0.multiplication_table() + sage: GU. = FreeGroup() # optional - sage.groups + sage: gr0 = GU / (s^(-2)*t*s*t, t^(-2)*s*t*s, s*t*s*t) # optional - sage.groups + sage: gr0.multiplication_table() # optional - sage.groups * a b c d e f g h i j k l +------------------------ a| a b c d e f g h i j k l @@ -388,9 +388,9 @@ def __init__(self, S, operation, names='letters', elements=None): TESTS:: sage: from sage.matrix.operation_table import OperationTable - sage: G=SymmetricGroup(3) - sage: T=OperationTable(G, operator.mul) - sage: TestSuite(T).run() + sage: G = SymmetricGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: TestSuite(T).run() # optional - sage.groups """ # Determine the elements of S, specified or not # If elements are given, we check if they are all in S @@ -510,14 +510,14 @@ def _name_maker(self, names): the nature of the output here. :: sage: from sage.matrix.operation_table import OperationTable - sage: G=SymmetricGroup(3) - sage: T=OperationTable(G, operator.mul) - sage: w, l, d = T._name_maker('letters') - sage: w + sage: G = SymmetricGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: w, l, d = T._name_maker('letters') # optional - sage.groups + sage: w # optional - sage.groups 1 - sage: l[0] + sage: l[0] # optional - sage.groups 'a' - sage: d['a'] + sage: d['a'] # optional - sage.groups () TESTS: @@ -527,17 +527,17 @@ def _name_maker(self, names): methods that rely on this one. :: sage: from sage.matrix.operation_table import OperationTable - sage: G=AlternatingGroup(3) - sage: T=OperationTable(G, operator.mul) - sage: T._name_maker(['x']) + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T._name_maker(['x']) # optional - sage.groups Traceback (most recent call last): ... ValueError: list of element names must be the same size as the set, 1 != 3 - sage: T._name_maker(['x', 'y', 4]) + sage: T._name_maker(['x', 'y', 4]) # optional - sage.groups Traceback (most recent call last): ... ValueError: list of element names must only contain strings, not 4 - sage: T._name_maker('blatzo') + sage: T._name_maker('blatzo') # optional - sage.groups Traceback (most recent call last): ... ValueError: element names must be a list, or one of the keywords: 'letters', 'digits', 'elements' @@ -608,31 +608,31 @@ def __getitem__(self, pair): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: G=DiCyclicGroup(3) - sage: T=OperationTable(G, operator.mul) - sage: T.column_keys() + sage: G = DiCyclicGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T.column_keys() # optional - sage.groups ((), (5,6,7), ..., (1,4,2,3)(5,7)) - sage: T[G('(1,2)(3,4)(5,6,7)'), G('(1,3,2,4)(5,7)')] + sage: T[G('(1,2)(3,4)(5,6,7)'), G('(1,3,2,4)(5,7)')] # optional - sage.groups (1,4,2,3)(5,6) TESTS:: sage: from sage.matrix.operation_table import OperationTable - sage: G = DiCyclicGroup(3) - sage: T = OperationTable(G, operator.mul) - sage: T[G('(1,2)(3,4)(5,6,7)')] + sage: G = DiCyclicGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T[G('(1,2)(3,4)(5,6,7)')] # optional - sage.groups Traceback (most recent call last): ... TypeError: indexing into an operation table requires exactly two elements - sage: T[G('(1,2)(3,4)(5,6,7)'), G('(1,3,2,4)(5,7)'), G('(1,3,2,4)(5,7)')] + sage: T[G('(1,2)(3,4)(5,6,7)'), G('(1,3,2,4)(5,7)'), G('(1,3,2,4)(5,7)')] # optional - sage.groups Traceback (most recent call last): ... TypeError: indexing into an operation table requires exactly two elements - sage: T[2, 3] + sage: T[2, 3] # optional - sage.groups Traceback (most recent call last): ... IndexError: invalid indices of operation table: (2, 3) - sage: T['(1,512)', '(1,3,2,4)(5,7)'] + sage: T['(1,512)', '(1,3,2,4)(5,7)'] # optional - sage.groups Traceback (most recent call last): ... IndexError: invalid indices of operation table: ((1,512), (1,3,2,4)(5,7)) @@ -663,13 +663,13 @@ def __eq__(self, other): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: G=CyclicPermutationGroup(6) - sage: H=CyclicPermutationGroup(3) - sage: P=OperationTable(G, operator.mul) - sage: Q=OperationTable(G, operator.mul) - sage: R=OperationTable(H, operator.mul) - sage: S=OperationTable(G, operator.truediv) - sage: P == P, P == Q, P == R, P == S + sage: G = CyclicPermutationGroup(6) # optional - sage.groups + sage: H = CyclicPermutationGroup(3) # optional - sage.groups + sage: P = OperationTable(G, operator.mul) # optional - sage.groups + sage: Q = OperationTable(G, operator.mul) # optional - sage.groups + sage: R = OperationTable(H, operator.mul) # optional - sage.groups + sage: S = OperationTable(G, operator.truediv) # optional - sage.groups + sage: P == P, P == Q, P == R, P == S # optional - sage.groups (True, True, False, False) """ return (self._elts == other._elts) and (self._operation == other._operation) @@ -681,13 +681,13 @@ def __ne__(self, other): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: G=CyclicPermutationGroup(6) - sage: H=CyclicPermutationGroup(3) - sage: P=OperationTable(G, operator.mul) - sage: Q=OperationTable(G, operator.mul) - sage: R=OperationTable(H, operator.mul) - sage: S=OperationTable(G, operator.truediv) - sage: P != P, P != Q, P != R, P != S + sage: G = CyclicPermutationGroup(6) # optional - sage.groups + sage: H = CyclicPermutationGroup(3) # optional - sage.groups + sage: P = OperationTable(G, operator.mul) # optional - sage.groups + sage: Q = OperationTable(G, operator.mul) # optional - sage.groups + sage: R = OperationTable(H, operator.mul) # optional - sage.groups + sage: S = OperationTable(G, operator.truediv) # optional - sage.groups + sage: P != P, P != Q, P != R, P != S # optional - sage.groups (False, False, True, True) """ return not self == other @@ -699,8 +699,8 @@ def _repr_(self): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: R=Integers(5) - sage: T=OperationTable(R, operation=operator.add) + sage: R = Integers(5) + sage: T = OperationTable(R, operation=operator.add) sage: print(T._repr_()) + a b c d e +---------- @@ -725,32 +725,32 @@ def set_print_symbols(self, ascii, latex): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: G=AlternatingGroup(3) - sage: T=OperationTable(G, operator.mul) - sage: T.set_print_symbols('@', '\\times') - sage: T + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T.set_print_symbols('@', '\\times') # optional - sage.groups + sage: T # optional - sage.groups @ a b c +------ a| a b c b| b c a c| c a b - sage: T._latex_() + sage: T._latex_() # optional - sage.groups '{\\setlength{\\arraycolsep}{2ex}\n\\begin{array}{r|*{3}{r}}\n\\multicolumn{1}{c|}{\\times}&a&b&c\\\\\\hline\n{}a&a&b&c\\\\\n{}b&b&c&a\\\\\n{}c&c&a&b\\\\\n\\end{array}}' TESTS:: sage: from sage.matrix.operation_table import OperationTable - sage: G=AlternatingGroup(3) - sage: T=OperationTable(G, operator.mul) - sage: T.set_print_symbols('@', 5) + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T.set_print_symbols('@', 5) # optional - sage.groups Traceback (most recent call last): ... ValueError: LaTeX symbol must be a string, not 5 - sage: T.set_print_symbols('@x@', '\\times') + sage: T.set_print_symbols('@x@', '\\times') # optional - sage.groups Traceback (most recent call last): ... ValueError: ASCII symbol should be a single character, not @x@ - sage: T.set_print_symbols(5, '\\times') + sage: T.set_print_symbols(5, '\\times') # optional - sage.groups Traceback (most recent call last): ... ValueError: ASCII symbol should be a single character, not 5 @@ -781,9 +781,9 @@ def column_keys(self): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: G=AlternatingGroup(3) - sage: T=OperationTable(G, operator.mul) - sage: T.column_keys() + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T.column_keys() # optional - sage.groups ((), (1,2,3), (1,3,2)) """ return self._elts @@ -807,9 +807,9 @@ def translation(self): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: G=AlternatingGroup(3) - sage: T=OperationTable(G, operator.mul, names=['p','q','r']) - sage: T.translation() + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul, names=['p','q','r']) # optional - sage.groups + sage: T.translation() # optional - sage.groups {'p': (), 'q': (1,2,3), 'r': (1,3,2)} """ return self._name_dict @@ -828,9 +828,9 @@ def table(self): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: C=CyclicPermutationGroup(3) - sage: T=OperationTable(C, operator.mul) - sage: T.table() + sage: C = CyclicPermutationGroup(3) # optional - sage.groups + sage: T=OperationTable(C, operator.mul) # optional - sage.groups + sage: T.table() # optional - sage.groups [[0, 1, 2], [1, 2, 0], [2, 0, 1]] """ return self._table @@ -870,46 +870,46 @@ def change_names(self, names): operation table uses the same routine. :: sage: from sage.matrix.operation_table import OperationTable - sage: D=DihedralGroup(2) - sage: T=OperationTable(D, operator.mul) - sage: T + sage: D = DihedralGroup(2) # optional - sage.groups + sage: T = OperationTable(D, operator.mul) # optional - sage.groups + sage: T # optional - sage.groups * a b c d +-------- a| a b c d b| b a d c c| c d a b d| d c b a - sage: T.translation()['c'] + sage: T.translation()['c'] # optional - sage.groups (1,2) - sage: T.change_names('digits') - sage: T + sage: T.change_names('digits') # optional - sage.groups + sage: T # optional - sage.groups * 0 1 2 3 +-------- 0| 0 1 2 3 1| 1 0 3 2 2| 2 3 0 1 3| 3 2 1 0 - sage: T.translation()['2'] + sage: T.translation()['2'] # optional - sage.groups (1,2) - sage: T.change_names('elements') - sage: T + sage: T.change_names('elements') # optional - sage.groups + sage: T # optional - sage.groups * () (3,4) (1,2) (1,2)(3,4) +-------------------------------------------- ()| () (3,4) (1,2) (1,2)(3,4) (3,4)| (3,4) () (1,2)(3,4) (1,2) (1,2)| (1,2) (1,2)(3,4) () (3,4) (1,2)(3,4)| (1,2)(3,4) (1,2) (3,4) () - sage: T.translation()['(1,2)'] + sage: T.translation()['(1,2)'] # optional - sage.groups (1,2) - sage: T.change_names(['w', 'x', 'y', 'z']) - sage: T + sage: T.change_names(['w', 'x', 'y', 'z']) # optional - sage.groups + sage: T # optional - sage.groups * w x y z +-------- w| w x y z x| x w z y y| y z w x z| z y x w - sage: T.translation()['y'] + sage: T.translation()['y'] # optional - sage.groups (1,2) """ self._width, self._names, self._name_dict = self._name_maker(names) @@ -927,16 +927,16 @@ def matrix_of_variables(self): ``cayley_table()`` method for permutation groups. :: sage: from sage.matrix.operation_table import OperationTable - sage: G = PermutationGroup(['(1,2,3)', '(2,3)']) - sage: T = OperationTable(G, operator.mul) - sage: T.matrix_of_variables() + sage: G = PermutationGroup(['(1,2,3)', '(2,3)']) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T.matrix_of_variables() # optional - sage.groups [x0 x1 x2 x3 x4 x5] [x1 x0 x3 x2 x5 x4] [x2 x4 x0 x5 x1 x3] [x3 x5 x1 x4 x0 x2] [x4 x2 x5 x0 x3 x1] [x5 x3 x4 x1 x2 x0] - sage: T.column_keys()[2]*T.column_keys()[2] == T.column_keys()[0] + sage: T.column_keys()[2]*T.column_keys()[2] == T.column_keys()[0] # optional - sage.groups True """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -1043,8 +1043,8 @@ def _ascii_table(self): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: R=Integers(5) - sage: T=OperationTable(R, operator.add) + sage: R = Integers(5) + sage: T = OperationTable(R, operator.add) sage: print(T._ascii_table()) + a b c d e +---------- @@ -1058,8 +1058,8 @@ def _ascii_table(self): strings used to represent elements. :: sage: from sage.matrix.operation_table import OperationTable - sage: R=Integers(10) - sage: T=OperationTable(R, operator.mul, names='digits') + sage: R = Integers(10) + sage: T = OperationTable(R, operator.mul, names='digits') sage: print(T._ascii_table()) * 0 1 2 3 4 5 6 7 8 9 +-------------------- @@ -1077,8 +1077,8 @@ def _ascii_table(self): :: sage: from sage.matrix.operation_table import OperationTable - sage: R=Integers(11) - sage: T=OperationTable(R, operator.mul, names='digits') + sage: R = Integers(11) + sage: T = OperationTable(R, operator.mul, names='digits') sage: print(T._ascii_table()) * 00 01 02 03 04 05 06 07 08 09 10 +--------------------------------- @@ -1097,8 +1097,8 @@ def _ascii_table(self): :: sage: from sage.matrix.operation_table import OperationTable - sage: R=Integers(4) - sage: T=OperationTable(R, operator.mul, names=['x','y','wwww', 'z']) + sage: R = Integers(4) + sage: T = OperationTable(R, operator.mul, names=['x','y','wwww', 'z']) sage: print(T._ascii_table()) * x y wwww z +-------------------- @@ -1135,8 +1135,8 @@ def _latex_(self): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: R=Integers(2) - sage: T=OperationTable(R, operation=operator.mul) + sage: R = Integers(2) + sage: T = OperationTable(R, operation=operator.mul) sage: T._latex_() '{\\setlength{\\arraycolsep}{2ex}\n\\begin{array}{r|*{2}{r}}\n\\multicolumn{1}{c|}{\\ast}&a&b\\\\\\hline\n{}a&a&a\\\\\n{}b&a&b\\\\\n\\end{array}}' """ diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 41a48c0e99f..92958d84a1f 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -7,7 +7,7 @@ For example, here is a circulant matrix of order five:: - sage: matrix.circulant(SR.var('a b c d e')) + sage: matrix.circulant(SR.var('a b c d e')) # optional - sage.symbolic [a b c d e] [e a b c d] [d e a b c] @@ -748,36 +748,36 @@ def diagonal_matrix(arg0=None, arg1=None, arg2=None, sparse=True): NumPy arrays may be used as input. :: - sage: import numpy - sage: entries = numpy.array([1.2, 5.6]); entries + sage: import numpy # optional - numpy + sage: entries = numpy.array([1.2, 5.6]); entries # optional - numpy array([1.2, 5.6]) - sage: A = diagonal_matrix(3, entries); A + sage: A = diagonal_matrix(3, entries); A # optional - numpy [1.2 0.0 0.0] [0.0 5.6 0.0] [0.0 0.0 0.0] - sage: A.parent() + sage: A.parent() # optional - numpy Full MatrixSpace of 3 by 3 sparse matrices over Real Double Field sage: j = complex(0,1) - sage: entries = numpy.array([2.0+j, 8.1, 3.4+2.6*j]); entries + sage: entries = numpy.array([2.0+j, 8.1, 3.4+2.6*j]); entries # optional - numpy array([2. +1.j , 8.1+0.j , 3.4+2.6j]) - sage: A = diagonal_matrix(entries); A + sage: A = diagonal_matrix(entries); A # optional - numpy [2.0 + 1.0*I 0.0 0.0] [ 0.0 8.1 0.0] [ 0.0 0.0 3.4 + 2.6*I] - sage: A.parent() + sage: A.parent() # optional - numpy Full MatrixSpace of 3 by 3 sparse matrices over Complex Double Field - sage: entries = numpy.array([4, 5, 6]) - sage: A = diagonal_matrix(entries); A + sage: entries = numpy.array([4, 5, 6]) # optional - numpy + sage: A = diagonal_matrix(entries); A # optional - numpy [4 0 0] [0 5 0] [0 0 6] - sage: A.parent() + sage: A.parent() # optional - numpy Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring - sage: entries = numpy.array([4.1, 5.2, 6.3]) - sage: A = diagonal_matrix(ZZ, entries); A + sage: entries = numpy.array([4.1, 5.2, 6.3]) # optional - numpy + sage: A = diagonal_matrix(ZZ, entries); A # optional - numpy Traceback (most recent call last): ... TypeError: unable to convert 4.1 to an element of Integer Ring @@ -3478,7 +3478,7 @@ def vandermonde(v, ring=None): A Vandermonde matrix of order three over the symbolic ring:: - sage: matrix.vandermonde(SR.var(['x0', 'x1', 'x2'])) + sage: matrix.vandermonde(SR.var(['x0', 'x1', 'x2'])) # optional - sage.symbolic [ 1 x0 x0^2] [ 1 x1 x1^2] [ 1 x2 x2^2] @@ -3565,7 +3565,7 @@ def hankel(c, r=None, ring=None): A Hankel matrix with symbolic entries:: - sage: matrix.hankel(SR.var('a, b, c, d, e')) + sage: matrix.hankel(SR.var('a, b, c, d, e')) # optional - sage.symbolic [a b c d e] [b c d e 0] [c d e 0 0] @@ -3574,7 +3574,7 @@ def hankel(c, r=None, ring=None): We can also pass the elements of the last row, starting at the second column:: - sage: matrix.hankel(SR.var('a, b, c, d, e'), SR.var('f, g, h, i')) + sage: matrix.hankel(SR.var('a, b, c, d, e'), SR.var('f, g, h, i')) # optional - sage.symbolic [a b c d e] [b c d e f] [c d e f g] diff --git a/src/sage/matrix/symplectic_basis.py b/src/sage/matrix/symplectic_basis.py index 4caee7a6da6..4a55deee93d 100644 --- a/src/sage/matrix/symplectic_basis.py +++ b/src/sage/matrix/symplectic_basis.py @@ -188,7 +188,12 @@ def symplectic_basis_over_field(M): An example over a finite field:: - sage: E = matrix(GF(7), 8, 8, [0, -1/2, -2, 1/2, 2, 0, -2, 1, 1/2, 0, -1, -3, 0, 2, 5/2, -3, 2, 1, 0, 3/2, -1, 0, -1, -2, -1/2, 3, -3/2, 0, 1, 3/2, -1/2, -1/2, -2, 0, 1, -1, 0, 0, 1, -1, 0, -2, 0, -3/2, 0, 0, 1/2, -2, 2, -5/2, 1, 1/2, -1, -1/2, 0, -1, -1, 3, 2, 1/2, 1, 2, 1, 0]); E + sage: E = matrix(GF(7), 8, 8, # optional - sage.rings.finite_rings + ....: [0, -1/2, -2, 1/2, 2, 0, -2, 1, 1/2, 0, -1, -3, 0, 2, 5/2, + ....: -3, 2, 1, 0, 3/2, -1, 0, -1, -2, -1/2, 3, -3/2, 0, 1, 3/2, + ....: -1/2, -1/2, -2, 0, 1, -1, 0, 0, 1, -1, 0, -2, 0, -3/2, 0, + ....: 0, 1/2, -2, 2, -5/2, 1, 1/2, -1, -1/2, 0, -1, -1, 3, 2, + ....: 1/2, 1, 2, 1, 0]); E [0 3 5 4 2 0 5 1] [4 0 6 4 0 2 6 4] [2 1 0 5 6 0 6 5] @@ -197,7 +202,7 @@ def symplectic_basis_over_field(M): [0 5 0 2 0 0 4 5] [2 1 1 4 6 3 0 6] [6 3 2 4 1 2 1 0] - sage: F, C = symplectic_basis_over_field(E); F + sage: F, C = symplectic_basis_over_field(E); F # optional - sage.rings.finite_rings [0 0 0 0 1 0 0 0] [0 0 0 0 0 1 0 0] [0 0 0 0 0 0 1 0] @@ -206,12 +211,16 @@ def symplectic_basis_over_field(M): [0 6 0 0 0 0 0 0] [0 0 6 0 0 0 0 0] [0 0 0 6 0 0 0 0] - sage: F == C * E * C.transpose() + sage: F == C * E * C.transpose() # optional - sage.rings.finite_rings True The tricky case of characteristic 2:: - sage: E = matrix(GF(2), 8, 8, [0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); E + sage: E = matrix(GF(2), 8, 8, # optional - sage.rings.finite_rings + ....: [0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + ....: 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, + ....: 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, + ....: 0, 1, 0, 0]); E [0 0 1 1 0 1 0 1] [0 0 0 0 0 0 0 0] [1 0 0 0 0 0 1 1] @@ -220,7 +229,7 @@ def symplectic_basis_over_field(M): [1 0 0 0 1 0 1 1] [0 0 1 0 1 1 0 0] [1 0 1 1 0 1 0 0] - sage: F, C = symplectic_basis_over_field(E); F + sage: F, C = symplectic_basis_over_field(E); F # optional - sage.rings.finite_rings [0 0 0 1 0 0 0 0] [0 0 0 0 1 0 0 0] [0 0 0 0 0 1 0 0] @@ -229,7 +238,7 @@ def symplectic_basis_over_field(M): [0 0 1 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] - sage: F == C * E * C.transpose() + sage: F == C * E * C.transpose() # optional - sage.rings.finite_rings True An inexact example:: @@ -243,7 +252,7 @@ def symplectic_basis_over_field(M): [ 1.14718543053828 -0.278305070958958 0.0840205427053993 0.356957405431611 0.836072521423577 0.000000000000000 0.214878541347751 -1.20221688928379] [ -1.03076138152950 0.0781320488361574 -1.28202592892333 0.699960114607661 -0.450137632758469 -0.214878541347751 0.000000000000000 0.785074452163036] [ 0.227739521708484 0.496003664217833 0.512563654267693 -0.0260496330859998 0.696145287292091 1.20221688928379 -0.785074452163036 0.000000000000000] - sage: F, C = symplectic_basis_over_field(E); F # random + sage: F, C = symplectic_basis_over_field(E); F # random [ 0.000000000000000 0.000000000000000 2.22044604925031e-16 -2.22044604925031e-16 1.00000000000000 0.000000000000000 0.000000000000000 -3.33066907387547e-16] [ 0.000000000000000 8.14814392305203e-17 -1.66533453693773e-16 -1.11022302462516e-16 0.000000000000000 1.00000000000000 -1.11022302462516e-16 0.000000000000000] [-5.27829526256056e-16 -2.40004077757759e-16 1.28373418199470e-16 -1.11022302462516e-16 0.000000000000000 -3.15483812822081e-16 1.00000000000000 -4.44089209850063e-16] diff --git a/src/sage/matrix/tests.py b/src/sage/matrix/tests.py index 21b7920307a..8a556b2fba8 100644 --- a/src/sage/matrix/tests.py +++ b/src/sage/matrix/tests.py @@ -11,7 +11,7 @@ Vector space of degree 1 and dimension 1 over Rational Field Basis matrix: [1] - sage: matrix(GF(7),1,0).kernel() + sage: matrix(GF(7), 1, 0).kernel() # optional - sage.rings.finite_rings Vector space of degree 1 and dimension 1 over Finite Field of size 7 Basis matrix: [1] @@ -28,7 +28,7 @@ Vector space of degree 0 and dimension 0 over Rational Field Basis matrix: [] - sage: matrix(GF(7),0,1).kernel() + sage: matrix(GF(7), 0, 1).kernel() # optional - sage.rings.finite_rings Vector space of degree 0 and dimension 0 over Finite Field of size 7 Basis matrix: [] @@ -45,7 +45,7 @@ sage: matrix(QQ, 2, 2, [1, 1, 1, 1]) / (1/2) [2 2] [2 2] - sage: matrix(QQ['x,y'], 2, 2, [1, 1, 1, 1]) / x + sage: matrix(QQ['x,y'], 2, 2, [1, 1, 1, 1]) / x # optional - sage.symbolic [1/x 1/x] [1/x 1/x] sage: A = matrix(CC, 2, 2, [1, 1, 1, 1]) / I; A diff --git a/src/sage/matroids/basis_exchange_matroid.pyx b/src/sage/matroids/basis_exchange_matroid.pyx index 8555ff67152..89dbb8e5e56 100644 --- a/src/sage/matroids/basis_exchange_matroid.pyx +++ b/src/sage/matroids/basis_exchange_matroid.pyx @@ -473,8 +473,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted(M.groundset()) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted(M.groundset()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g'] """ return self._groundset @@ -495,17 +495,17 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: type(M.groundset()) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: type(M.groundset()) # optional - sage.libs.pari <... 'frozenset'> - sage: type(M.groundset_list()) + sage: type(M.groundset_list()) # optional - sage.libs.pari <... 'list'> - sage: sorted(M.groundset_list()) + sage: sorted(M.groundset_list()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - sage: E = M.groundset_list() - sage: E.remove('a') - sage: sorted(M.groundset_list()) + sage: E = M.groundset_list() # optional - sage.libs.pari + sage: E.remove('a') # optional - sage.libs.pari + sage: sorted(M.groundset_list()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g'] """ return list(self._E) @@ -538,10 +538,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.full_rank() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.full_rank() # optional - sage.libs.pari 3 - sage: M.dual().full_rank() + sage: M.dual().full_rank() # optional - sage.libs.pari 4 """ return self._matroid_rank @@ -564,10 +564,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.full_corank() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.full_corank() # optional - sage.libs.pari 4 - sage: M.dual().full_corank() + sage: M.dual().full_corank() # optional - sage.libs.pari 3 """ return self._groundset_size - self._matroid_rank @@ -592,12 +592,12 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted(M.basis()) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted(M.basis()) # optional - sage.libs.pari ['a', 'b', 'c'] - sage: M.rank('cd') + sage: M.rank('cd') # optional - sage.libs.pari 2 - sage: sorted(M.basis()) + sage: sorted(M.basis()) # optional - sage.libs.pari ['a', 'c', 'd'] """ @@ -750,8 +750,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.P8() - sage: sorted(M._fundamental_circuit('abcd', 'e')) + sage: M = matroids.named_matroids.P8() # optional - sage.libs.pari + sage: sorted(M._fundamental_circuit('abcd', 'e')) # optional - sage.libs.pari ['a', 'b', 'c', 'e'] """ self.__pack(self._input, B) @@ -906,8 +906,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.P8() - sage: sorted(M._fundamental_cocircuit('efgh', 'e')) + sage: M = matroids.named_matroids.P8() # optional - sage.libs.pari + sage: sorted(M._fundamental_cocircuit('efgh', 'e')) # optional - sage.libs.pari ['b', 'c', 'd', 'e'] """ self.__pack(self._input, B) @@ -1255,8 +1255,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.S8() - sage: M.f_vector() + sage: M = matroids.named_matroids.S8() # optional - sage.libs.pari + sage: M.f_vector() # optional - sage.libs.pari [1, 8, 22, 14, 1] """ @@ -1321,14 +1321,14 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.S8() - sage: M.f_vector() + sage: M = matroids.named_matroids.S8() # optional - sage.libs.pari + sage: M.f_vector() # optional - sage.libs.pari [1, 8, 22, 14, 1] - sage: len(M.flats(2)) + sage: len(M.flats(2)) # optional - sage.libs.pari 22 - sage: len(M.flats(8)) + sage: len(M.flats(8)) # optional - sage.libs.pari 0 - sage: len(M.flats(4)) + sage: len(M.flats(4)) # optional - sage.libs.pari 1 """ cdef bitset_t *flats @@ -1396,14 +1396,14 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.S8().dual() - sage: M.f_vector() + sage: M = matroids.named_matroids.S8().dual() # optional - sage.libs.pari + sage: M.f_vector() # optional - sage.libs.pari [1, 8, 22, 14, 1] - sage: len(M.coflats(2)) + sage: len(M.coflats(2)) # optional - sage.libs.pari 22 - sage: len(M.coflats(8)) + sage: len(M.coflats(8)) # optional - sage.libs.pari 0 - sage: len(M.coflats(4)) + sage: len(M.coflats(4)) # optional - sage.libs.pari 1 """ cdef bitset_t *coflats @@ -1529,8 +1529,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: M.bases_count() + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: M.bases_count() # optional - sage.libs.pari 184 """ if self._bcount is not None: @@ -1556,9 +1556,9 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: I = M.independent_sets() - sage: len(I) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: I = M.independent_sets() # optional - sage.libs.pari + sage: len(I) # optional - sage.libs.pari 57 """ cdef bitset_t *I @@ -1617,10 +1617,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: M.bases_count() + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: M.bases_count() # optional - sage.libs.pari 184 - sage: [len(M.independent_r_sets(r)) for r in range(M.full_rank() + 1)] + sage: [len(M.independent_r_sets(r)) for r in range(M.full_rank() + 1)] # optional - sage.libs.pari [1, 10, 45, 120, 201, 184] """ @@ -1649,10 +1649,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: M.bases_count() + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: M.bases_count() # optional - sage.libs.pari 184 - sage: len([B for B in M.bases()]) + sage: len([B for B in M.bases()]) # optional - sage.libs.pari 184 """ return self.independent_r_sets(self.full_rank()) @@ -1671,10 +1671,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: len(M.nonbases()) + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: len(M.nonbases()) # optional - sage.libs.pari 68 - sage: [len(M.dependent_r_sets(r)) for r in range(M.full_rank() + 1)] + sage: [len(M.dependent_r_sets(r)) for r in range(M.full_rank() + 1)] # optional - sage.libs.pari [0, 0, 0, 0, 9, 68] """ @@ -1714,10 +1714,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: binomial(M.size(), M.full_rank())-M.bases_count() + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: binomial(M.size(), M.full_rank())-M.bases_count() # optional - sage.libs.pari 68 - sage: len([B for B in M.nonbases()]) + sage: len([B for B in M.nonbases()]) # optional - sage.libs.pari 68 """ return self.dependent_r_sets(self.full_rank()) @@ -1740,8 +1740,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: len(M.nonspanning_circuits()) + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: len(M.nonspanning_circuits()) # optional - sage.libs.pari 23 """ cdef SetSystem NSC @@ -1789,8 +1789,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: len(M.noncospanning_cocircuits()) + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: len(M.noncospanning_cocircuits()) # optional - sage.libs.pari 23 """ cdef SetSystem NSC @@ -1835,8 +1835,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.NonFano().bases()) - sage: sorted([sorted(C) for C in M.cocircuits()]) + sage: M = Matroid(bases=matroids.named_matroids.NonFano().bases()) # optional - sage.libs.pari + sage: sorted([sorted(C) for C in M.cocircuits()]) # optional - sage.libs.pari [['a', 'b', 'c', 'd', 'g'], ['a', 'b', 'c', 'e', 'g'], ['a', 'b', 'c', 'f', 'g'], ['a', 'b', 'd', 'e'], ['a', 'c', 'd', 'f'], ['a', 'e', 'f', 'g'], ['b', 'c', 'e', 'f'], @@ -1883,8 +1883,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = Matroid(matroids.named_matroids.NonFano().bases()) - sage: sorted([sorted(C) for C in M.circuits()]) + sage: M = Matroid(matroids.named_matroids.NonFano().bases()) # optional - sage.libs.pari + sage: sorted([sorted(C) for C in M.circuits()]) # optional - sage.libs.pari [['a', 'b', 'c', 'g'], ['a', 'b', 'd', 'e'], ['a', 'b', 'f'], ['a', 'c', 'd', 'f'], ['a', 'c', 'e'], ['a', 'd', 'e', 'f'], ['a', 'd', 'g'], ['a', 'e', 'f', 'g'], ['b', 'c', 'd'], @@ -1932,10 +1932,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: M._characteristic_setsystem() + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: M._characteristic_setsystem() # optional - sage.libs.pari Iterator over a system of subsets - sage: len(M._characteristic_setsystem()) + sage: len(M._characteristic_setsystem()) # optional - sage.libs.pari 23 """ if 2 * self._matroid_rank > self._groundset_size: @@ -1958,9 +1958,9 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) - sage: N = Matroid(matroids.named_matroids.NonFano().bases()) - sage: M._weak_invariant() == N._weak_invariant() + sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.libs.pari + sage: N = Matroid(matroids.named_matroids.NonFano().bases()) # optional - sage.libs.pari + sage: M._weak_invariant() == N._weak_invariant() # optional - sage.libs.pari False """ if self._weak_invariant_var is None: @@ -2003,9 +2003,9 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = Matroid(matroids.named_matroids.Fano().bases()) - sage: N = Matroid(matroids.named_matroids.NonFano().bases()) - sage: M._strong_invariant() == N._strong_invariant() + sage: M = Matroid(matroids.named_matroids.Fano().bases()) # optional - sage.libs.pari + sage: N = Matroid(matroids.named_matroids.NonFano().bases()) # optional - sage.libs.pari + sage: M._strong_invariant() == N._strong_invariant() # optional - sage.libs.pari False """ if self._strong_invariant_var is None: @@ -2132,10 +2132,10 @@ cdef class BasisExchangeMatroid(Matroid): sage: N._is_isomorphism(M, {e:e for e in M.groundset()}) False - sage: M = matroids.named_matroids.Fano() \ ['g'] - sage: N = matroids.Wheel(3) - sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} - sage: M._is_isomorphism(N, morphism) + sage: M = matroids.named_matroids.Fano() \ ['g'] # optional - sage.libs.pari + sage: N = matroids.Wheel(3) # optional - sage.libs.pari + sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} # optional - sage.libs.pari + sage: M._is_isomorphism(N, morphism) # optional - sage.libs.pari True TESTS: @@ -2199,9 +2199,9 @@ cdef class BasisExchangeMatroid(Matroid): sage: morphism = M1._isomorphism(M2) sage: M1._is_isomorphism(M2, morphism) True - sage: M1 = matroids.named_matroids.Fano() - sage: M2 = matroids.named_matroids.NonFano() - sage: M1._isomorphism(M2) is None + sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M1._isomorphism(M2) is None # optional - sage.libs.pari True TESTS: @@ -2212,8 +2212,8 @@ cdef class BasisExchangeMatroid(Matroid): ....: return min(len(X), 2) ....: sage: M = Matroid(groundset='abcd', rank_function=f) - sage: N = Matroid(field=GF(3), reduced_matrix=[[1,1],[1,-1]]) - sage: N._isomorphism(M) is not None + sage: N = Matroid(field=GF(3), reduced_matrix=[[1,1],[1,-1]]) # optional - sage.libs.pari + sage: N._isomorphism(M) is not None # optional - sage.libs.pari True """ if not isinstance(other, BasisExchangeMatroid): @@ -2294,11 +2294,11 @@ cdef class BasisExchangeMatroid(Matroid): True sage: M1._is_isomorphic(M2, certificate=True) (True, {0: 0, 1: 1, 2: 2, 3: 3, 4: 5, 5: 4}) - sage: M1 = BasisMatroid(matroids.named_matroids.Fano()) - sage: M2 = matroids.named_matroids.NonFano() - sage: M1._is_isomorphic(M2) + sage: M1 = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M1._is_isomorphic(M2) # optional - sage.libs.pari False - sage: M1._is_isomorphic(M2, certificate=True) + sage: M1._is_isomorphic(M2, certificate=True) # optional - sage.libs.pari (False, None) """ @@ -2370,8 +2370,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) - sage: M.is_valid() + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.libs.pari True sage: M = Matroid(groundset='abcd', bases=['ab', 'cd']) sage: M.is_valid() @@ -2381,7 +2381,7 @@ cdef class BasisExchangeMatroid(Matroid): Verify that :trac:`20172` was fixed:: - sage: M=Matroid(groundset='1234',bases=['12','13','23','34']) + sage: M = Matroid(groundset='1234', bases=['12','13','23','34']) sage: M.is_valid() False """ diff --git a/src/sage/matroids/basis_matroid.pyx b/src/sage/matroids/basis_matroid.pyx index 85f09fd8f97..4c9ccf70db5 100644 --- a/src/sage/matroids/basis_matroid.pyx +++ b/src/sage/matroids/basis_matroid.pyx @@ -110,11 +110,11 @@ cdef class BasisMatroid(BasisExchangeMatroid): Create a BasisMatroid instance out of any other matroid:: sage: from sage.matroids.advanced import * - sage: F = matroids.named_matroids.Fano() - sage: M = BasisMatroid(F) - sage: F.groundset() == M.groundset() + sage: F = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M = BasisMatroid(F) # optional - sage.libs.pari + sage: F.groundset() == M.groundset() # optional - sage.libs.pari True - sage: len(set(F.bases()).difference(M.bases())) + sage: len(set(F.bases()).difference(M.bases())) # optional - sage.libs.pari 0 It is possible to provide either bases or nonbases:: @@ -150,11 +150,11 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: F = matroids.named_matroids.Fano() - sage: M = BasisMatroid(F) - sage: F.groundset() == M.groundset() + sage: F = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M = BasisMatroid(F) # optional - sage.libs.pari + sage: F.groundset() == M.groundset() # optional - sage.libs.pari True - sage: len(set(F.bases()).difference(M.bases())) + sage: len(set(F.bases()).difference(M.bases())) # optional - sage.libs.pari 0 """ cdef SetSystem NB @@ -254,8 +254,8 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) - sage: repr(M) # indirect doctest + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: repr(M) # indirect doctest # optional - sage.libs.pari 'Matroid of rank 3 on 7 elements with 28 bases' """ @@ -429,12 +429,12 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.N2().bases()) - sage: M.truncation() + sage: M = Matroid(bases=matroids.named_matroids.N2().bases()) # optional - sage.libs.pari + sage: M.truncation() # optional - sage.libs.pari Matroid of rank 5 on 12 elements with 702 bases - sage: M.f_vector() + sage: M.f_vector() # optional - sage.libs.pari [1, 12, 66, 190, 258, 99, 1] - sage: M.truncation().f_vector() + sage: M.truncation().f_vector() # optional - sage.libs.pari [1, 12, 66, 190, 258, 1] """ @@ -511,10 +511,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) - sage: M + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Matroid of rank 3 on 7 elements with 28 bases - sage: M._with_coloop('x') + sage: M._with_coloop('x') # optional - sage.libs.pari Matroid of rank 4 on 8 elements with 28 bases """ @@ -548,11 +548,11 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) - sage: sorted(M.groundset()) + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: sorted(M.groundset()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - sage: N = M.relabel({'g':'x'}) - sage: sorted(N.groundset()) + sage: N = M.relabel({'g':'x'}) # optional - sage.libs.pari + sage: sorted(N.groundset()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'x'] """ @@ -572,10 +572,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) - sage: M + sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Matroid of rank 3 on 7 elements with 28 bases - sage: M.bases_count() + sage: M.bases_count() # optional - sage.libs.pari 28 """ if self._bcount is None: @@ -594,10 +594,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) - sage: M + sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Matroid of rank 3 on 7 elements with 28 bases - sage: len(M.bases()) + sage: len(M.bases()) # optional - sage.libs.pari 28 """ cdef long r, n @@ -630,10 +630,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) - sage: M + sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Matroid of rank 3 on 7 elements with 28 bases - sage: len(M.nonbases()) + sage: len(M.nonbases()) # optional - sage.libs.pari 7 """ if self._nonbases is not None: @@ -674,9 +674,9 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) - sage: N = BasisMatroid(matroids.named_matroids.Fano()) - sage: M._bases_invariant() == N._bases_invariant() + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M._bases_invariant() == N._bases_invariant() # optional - sage.libs.pari True """ if self._bases_invariant_var is not None: @@ -733,9 +733,9 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) - sage: N = BasisMatroid(matroids.named_matroids.NonFano()) - sage: M._bases_invariant2() == N._bases_invariant2() + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: N = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari + sage: M._bases_invariant2() == N._bases_invariant2() # optional - sage.libs.pari False """ if self._bases_invariant2_var is None: @@ -844,8 +844,8 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.N1()) - sage: sorted([e for e in M.groundset() if M.is_distinguished(e)]) + sage: M = BasisMatroid(matroids.named_matroids.N1()) # optional - sage.libs.pari + sage: sorted([e for e in M.groundset() if M.is_distinguished(e)]) # optional - sage.libs.pari ['c', 'g', 'h', 'j'] """ @@ -886,12 +886,12 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.NonFano()) - sage: N = BasisMatroid(matroids.named_matroids.Fano()) - sage: m = {e:e for e in M.groundset()} - sage: M._is_relaxation(N, m) + sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari + sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: m = {e:e for e in M.groundset()} # optional - sage.libs.pari + sage: M._is_relaxation(N, m) # optional - sage.libs.pari True - sage: N._is_relaxation(M, m) + sage: N._is_relaxation(M, m) # optional - sage.libs.pari False """ cdef long i, j @@ -941,12 +941,12 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.NonFano()) - sage: N = BasisMatroid(matroids.named_matroids.Fano()) - sage: m = {e:e for e in M.groundset()} - sage: M._is_relaxation(N, m) + sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari + sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: m = {e:e for e in M.groundset()} # optional - sage.libs.pari + sage: M._is_relaxation(N, m) # optional - sage.libs.pari True - sage: M._is_isomorphism(N, m) + sage: M._is_isomorphism(N, m) # optional - sage.libs.pari False """ if not isinstance(other, BasisMatroid): @@ -979,9 +979,9 @@ cdef class BasisMatroid(BasisExchangeMatroid): sage: morphism = M._isomorphism(N) sage: M._is_isomorphism(N, morphism) True - sage: M = BasisMatroid(matroids.named_matroids.NonFano()) - sage: N = BasisMatroid(matroids.named_matroids.Fano()) - sage: M._isomorphism(N) is not None + sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari + sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M._isomorphism(N) is not None # optional - sage.libs.pari False """ if not isinstance(other, BasisMatroid): @@ -1055,11 +1055,11 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.NonFano()) - sage: N = BasisMatroid(matroids.named_matroids.Fano()) - sage: M._is_isomorphic(N) + sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari + sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M._is_isomorphic(N) # optional - sage.libs.pari False - sage: M._is_isomorphic(N, certificate=True) + sage: M._is_isomorphic(N, certificate=True) # optional - sage.libs.pari (False, None) """ if certificate: @@ -1127,12 +1127,12 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) - sage: N = BasisMatroid(matroids.named_matroids.Fano().dual()).dual() - sage: O = BasisMatroid(matroids.named_matroids.NonFano()) - sage: hash(M) == hash(N) + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: N = BasisMatroid(matroids.named_matroids.Fano().dual()).dual() # optional - sage.libs.pari + sage: O = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari + sage: hash(M) == hash(N) # optional - sage.libs.pari True - sage: hash(M) == hash(O) + sage: hash(M) == hash(O) # optional - sage.libs.pari False """ return hash((self.groundset(), self.bases_count(), self._weak_invariant())) diff --git a/src/sage/matroids/catalog.py b/src/sage/matroids/catalog.py index 769ef123923..c82ae02d063 100644 --- a/src/sage/matroids/catalog.py +++ b/src/sage/matroids/catalog.py @@ -67,13 +67,13 @@ def Q6(): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Q6(); M + sage: M = matroids.named_matroids.Q6(); M # optional - sage.libs.pari Q6: Quaternary matroid of rank 3 on 6 elements - sage: setprint(M.hyperplanes()) + sage: setprint(M.hyperplanes()) # optional - sage.libs.pari [{'a', 'b', 'd'}, {'a', 'c'}, {'a', 'e'}, {'a', 'f'}, {'b', 'c', 'e'}, {'b', 'f'}, {'c', 'd'}, {'c', 'f'}, {'d', 'e'}, {'d', 'f'}, {'e', 'f'}] - sage: M.nonspanning_circuits() == M.noncospanning_cocircuits() + sage: M.nonspanning_circuits() == M.noncospanning_cocircuits() # optional - sage.libs.pari False """ F = GF(4, 'x') @@ -106,10 +106,10 @@ def P6(): {2: {{'a', 'b', 'c'}}, 3: {{'a', 'b', 'c', 'd', 'e', 'f'}}} sage: len(set(M.nonspanning_circuits()).difference(M.nonbases())) == 0 True - sage: Matroid(matrix=random_matrix(GF(4, 'a'), ncols=5, + sage: Matroid(matrix=random_matrix(GF(4, 'a'), ncols=5, # optional - sage.libs.pari ....: nrows=5)).has_minor(M) False - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ E = 'abcdef' @@ -134,13 +134,13 @@ def R6(): EXAMPLES:: - sage: M = matroids.named_matroids.R6(); M + sage: M = matroids.named_matroids.R6(); M # optional - sage.libs.pari R6: Ternary matroid of rank 3 on 6 elements, type 2+ - sage: M.equals(M.dual()) + sage: M.equals(M.dual()) # optional - sage.libs.pari True - sage: M.is_connected() + sage: M.is_connected() # optional - sage.libs.pari True - sage: M.is_3connected() + sage: M.is_3connected() # optional - sage.libs.pari False """ A = Matrix(GF(3), [ @@ -167,12 +167,12 @@ def Fano(): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano(); M + sage: M = matroids.named_matroids.Fano(); M # optional - sage.libs.pari Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) - sage: setprint(sorted(M.nonspanning_circuits())) + sage: setprint(sorted(M.nonspanning_circuits())) # optional - sage.libs.pari [{'a', 'b', 'f'}, {'a', 'c', 'e'}, {'a', 'd', 'g'}, {'b', 'c', 'd'}, {'b', 'e', 'g'}, {'c', 'f', 'g'}, {'d', 'e', 'f'}] - sage: M.delete(M.groundset_list()[randrange(0, + sage: M.delete(M.groundset_list()[randrange(0, # optional - sage.libs.pari ....: 7)]).is_isomorphic(matroids.CompleteGraphic(4)) True """ @@ -198,14 +198,14 @@ def NonFano(): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.NonFano(); M + sage: M = matroids.named_matroids.NonFano(); M # optional - sage.libs.pari NonFano: Ternary matroid of rank 3 on 7 elements, type 0- - sage: setprint(M.nonbases()) + sage: setprint(M.nonbases()) # optional - sage.libs.pari [{'a', 'b', 'f'}, {'a', 'c', 'e'}, {'a', 'd', 'g'}, {'b', 'c', 'd'}, {'b', 'e', 'g'}, {'c', 'f', 'g'}] - sage: M.delete('f').is_isomorphic(matroids.CompleteGraphic(4)) + sage: M.delete('f').is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.libs.pari True - sage: M.delete('g').is_isomorphic(matroids.CompleteGraphic(4)) + sage: M.delete('g').is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.libs.pari False """ A = Matrix(GF(3), [ @@ -230,11 +230,11 @@ def O7(): EXAMPLES:: - sage: M = matroids.named_matroids.O7(); M + sage: M = matroids.named_matroids.O7(); M # optional - sage.libs.pari O7: Ternary matroid of rank 3 on 7 elements, type 0+ - sage: M.delete('e').is_isomorphic(matroids.CompleteGraphic(4)) + sage: M.delete('e').is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.libs.pari True - sage: M.tutte_polynomial() + sage: M.tutte_polynomial() # optional - sage.libs.pari y^4 + x^3 + x*y^2 + 3*y^3 + 4*x^2 + 5*x*y + 5*y^2 + 4*x + 4*y """ A = Matrix(GF(3), [ @@ -259,13 +259,13 @@ def P7(): EXAMPLES:: - sage: M = matroids.named_matroids.P7(); M + sage: M = matroids.named_matroids.P7(); M # optional - sage.libs.pari P7: Ternary matroid of rank 3 on 7 elements, type 1+ - sage: M.f_vector() + sage: M.f_vector() # optional - sage.libs.pari [1, 7, 11, 1] - sage: M.has_minor(matroids.CompleteGraphic(4)) + sage: M.has_minor(matroids.CompleteGraphic(4)) # optional - sage.libs.pari False - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ A = Matrix(GF(3), [ @@ -332,14 +332,14 @@ def R8(): EXAMPLES:: - sage: M = matroids.named_matroids.R8(); M + sage: M = matroids.named_matroids.R8(); M # optional - sage.libs.pari R8: Ternary matroid of rank 4 on 8 elements, type 0+ - sage: M.contract(M.groundset_list()[randrange(0, + sage: M.contract(M.groundset_list()[randrange(0, # optional - sage.libs.pari ....: 8)]).is_isomorphic(matroids.named_matroids.NonFano()) True - sage: M.equals(M.dual()) + sage: M.equals(M.dual()) # optional - sage.libs.pari True - sage: M.has_minor(matroids.named_matroids.Fano()) + sage: M.has_minor(matroids.named_matroids.Fano()) # optional - sage.libs.pari False """ A = Matrix(GF(3), [ @@ -477,21 +477,21 @@ def S8(): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.S8(); M + sage: M = matroids.named_matroids.S8(); M # optional - sage.libs.pari S8: Binary matroid of rank 4 on 8 elements, type (2, 0) - sage: M.contract('d').is_isomorphic(matroids.named_matroids.Fano()) + sage: M.contract('d').is_isomorphic(matroids.named_matroids.Fano()) # optional - sage.libs.pari True - sage: M.delete('d').is_isomorphic( + sage: M.delete('d').is_isomorphic( # optional - sage.libs.pari ....: matroids.named_matroids.Fano().dual()) False - sage: M.is_graphic() + sage: M.is_graphic() # optional - sage.libs.pari False - sage: D = get_nonisomorphic_matroids( + sage: D = get_nonisomorphic_matroids( # optional - sage.libs.pari ....: list(matroids.named_matroids.Fano().linear_coextensions( ....: cosimple=True))) - sage: len(D) + sage: len(D) # optional - sage.libs.pari 2 - sage: [N.is_isomorphic(M) for N in D] + sage: [N.is_isomorphic(M) for N in D] # optional - sage.libs.pari [...True...] """ @@ -553,13 +553,13 @@ def T8(): EXAMPLES:: - sage: M = matroids.named_matroids.T8(); M + sage: M = matroids.named_matroids.T8(); M # optional - sage.libs.pari T8: Ternary matroid of rank 4 on 8 elements, type 0- - sage: M.truncation().is_isomorphic(matroids.Uniform(3, 8)) + sage: M.truncation().is_isomorphic(matroids.Uniform(3, 8)) # optional - sage.libs.pari True - sage: M.contract('e').is_isomorphic(matroids.named_matroids.P7()) + sage: M.contract('e').is_isomorphic(matroids.named_matroids.P7()) # optional - sage.libs.pari True - sage: M.has_minor(matroids.Uniform(3, 8)) + sage: M.has_minor(matroids.Uniform(3, 8)) # optional - sage.libs.pari False """ @@ -585,15 +585,15 @@ def J(): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.J(); M + sage: M = matroids.named_matroids.J(); M # optional - sage.libs.pari J: Ternary matroid of rank 4 on 8 elements, type 0- - sage: setprint(M.truncation().nonbases()) + sage: setprint(M.truncation().nonbases()) # optional - sage.libs.pari [{'a', 'b', 'f'}, {'a', 'c', 'g'}, {'a', 'd', 'h'}] - sage: M.is_isomorphic(M.dual()) + sage: M.is_isomorphic(M.dual()) # optional - sage.libs.pari True - sage: M.has_minor(matroids.CompleteGraphic(4)) + sage: M.has_minor(matroids.CompleteGraphic(4)) # optional - sage.libs.pari False - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ A = Matrix(GF(3), [ @@ -619,14 +619,14 @@ def P8(): EXAMPLES:: - sage: M = matroids.named_matroids.P8(); M + sage: M = matroids.named_matroids.P8(); M # optional - sage.libs.pari P8: Ternary matroid of rank 4 on 8 elements, type 2+ - sage: M.is_isomorphic(M.dual()) + sage: M.is_isomorphic(M.dual()) # optional - sage.libs.pari True - sage: Matroid(matrix=random_matrix(GF(4, 'a'), ncols=5, + sage: Matroid(matrix=random_matrix(GF(4, 'a'), ncols=5, # optional - sage.libs.pari ....: nrows=5)).has_minor(M) False - sage: M.bicycle_dimension() + sage: M.bicycle_dimension() # optional - sage.libs.pari 2 """ @@ -719,11 +719,11 @@ def TernaryDowling3(): EXAMPLES:: - sage: M = matroids.named_matroids.TernaryDowling3(); M + sage: M = matroids.named_matroids.TernaryDowling3(); M # optional - sage.libs.pari Q3(GF(3)x): Ternary matroid of rank 3 on 9 elements, type 0- - sage: len(list(M.linear_subclasses())) + sage: len(list(M.linear_subclasses())) # optional - sage.libs.pari 72 - sage: M.fundamental_cycle('abc', 'd') + sage: M.fundamental_cycle('abc', 'd') # optional - sage.libs.pari {'a': 2, 'b': 1, 'd': 1} """ @@ -853,17 +853,17 @@ def Whirl(n): EXAMPLES:: - sage: M = matroids.Whirl(5); M + sage: M = matroids.Whirl(5); M # optional - sage.libs.pari Whirl(5): Ternary matroid of rank 5 on 10 elements, type 0- - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True - sage: M.tutte_polynomial() + sage: M.tutte_polynomial() # optional - sage.libs.pari x^5 + y^5 + 5*x^4 + 5*x^3*y + 5*x^2*y^2 + 5*x*y^3 + 5*y^4 + 10*x^3 + 15*x^2*y + 15*x*y^2 + 10*y^3 + 10*x^2 + 15*x*y + 10*y^2 + 5*x + 5*y - sage: M.is_isomorphic(matroids.Wheel(5)) + sage: M.is_isomorphic(matroids.Wheel(5)) # optional - sage.libs.pari False - sage: M = matroids.Whirl(3) - sage: M.is_isomorphic(matroids.CompleteGraphic(4)) + sage: M = matroids.Whirl(3) # optional - sage.libs.pari + sage: M.is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.libs.pari False .. TODO:: @@ -960,12 +960,12 @@ def PG(n, q, x=None): EXAMPLES:: - sage: M = matroids.PG(2, 2) - sage: M.is_isomorphic(matroids.named_matroids.Fano()) + sage: M = matroids.PG(2, 2) # optional - sage.libs.pari + sage: M.is_isomorphic(matroids.named_matroids.Fano()) # optional - sage.libs.pari True - sage: matroids.PG(5, 4, 'z').size() == (4^6 - 1) / (4 - 1) + sage: matroids.PG(5, 4, 'z').size() == (4^6 - 1) / (4 - 1) # optional - sage.libs.pari True - sage: M = matroids.PG(4, 7); M + sage: M = matroids.PG(4, 7); M # optional - sage.libs.pari PG(4, 7): Linear matroid of rank 5 on 2801 elements represented over the Finite Field of size 7 """ @@ -1003,13 +1003,13 @@ def AG(n, q, x=None): EXAMPLES:: - sage: M = matroids.AG(2, 3) \ 8 - sage: M.is_isomorphic(matroids.named_matroids.AG23minus()) + sage: M = matroids.AG(2, 3) \ 8 # optional - sage.libs.pari + sage: M.is_isomorphic(matroids.named_matroids.AG23minus()) # optional - sage.libs.pari True - sage: matroids.AG(5, 4, 'z').size() == ((4 ^ 6 - 1) / (4 - 1) - + sage: matroids.AG(5, 4, 'z').size() == ((4 ^ 6 - 1) / (4 - 1) - # optional - sage.libs.pari ....: (4 ^ 5 - 1)/(4 - 1)) True - sage: M = matroids.AG(4, 2); M + sage: M = matroids.AG(4, 2); M # optional - sage.libs.pari AG(4, 2): Binary matroid of rank 5 on 16 elements, type (5, 0) """ @@ -1243,10 +1243,10 @@ def Q10(): EXAMPLES:: - sage: M = matroids.named_matroids.Q10() - sage: M.is_isomorphic(M.dual()) + sage: M = matroids.named_matroids.Q10() # optional - sage.libs.pari + sage: M.is_isomorphic(M.dual()) # optional - sage.libs.pari True - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True Check the splitter property. By Seymour's Theorem, and using self-duality, @@ -1255,8 +1255,8 @@ def Q10(): are quaternary are `U_{2, 5}, U_{3, 5}, F_7, F_7^*`. As it happens, it suffices to check for `U_{2, 5}`: - sage: S = matroids.named_matroids.Q10().linear_extensions(simple=True) - sage: [M for M in S if not M.has_line_minor(5)] # long time + sage: S = matroids.named_matroids.Q10().linear_extensions(simple=True) # optional - sage.libs.pari + sage: [M for M in S if not M.has_line_minor(5)] # long time # optional - sage.libs.pari [] """ F = GF(4, 'x') @@ -1281,10 +1281,10 @@ def N1(): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: M.is_field_isomorphic(M.dual()) + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: M.is_field_isomorphic(M.dual()) # optional - sage.libs.pari True - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ @@ -1308,10 +1308,10 @@ def N2(): EXAMPLES:: - sage: M = matroids.named_matroids.N2() - sage: M.is_field_isomorphic(M.dual()) + sage: M = matroids.named_matroids.N2() # optional - sage.libs.pari + sage: M.is_field_isomorphic(M.dual()) # optional - sage.libs.pari True - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ @@ -1422,11 +1422,11 @@ def ExtendedBinaryGolayCode(): EXAMPLES:: - sage: M = matroids.named_matroids.ExtendedBinaryGolayCode() - sage: C = LinearCode(M.representation()) - sage: C.is_permutation_equivalent(codes.GolayCode(GF(2))) # long time + sage: M = matroids.named_matroids.ExtendedBinaryGolayCode() # optional - sage.libs.pari + sage: C = LinearCode(M.representation()) # optional - sage.libs.pari + sage: C.is_permutation_equivalent(codes.GolayCode(GF(2))) # long time # optional - sage.libs.pari True - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ A = Matrix(GF(2), [ @@ -1457,11 +1457,11 @@ def ExtendedTernaryGolayCode(): EXAMPLES:: - sage: M = matroids.named_matroids.ExtendedTernaryGolayCode() - sage: C = LinearCode(M.representation()) - sage: C.is_permutation_equivalent(codes.GolayCode(GF(3))) # long time + sage: M = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari + sage: C = LinearCode(M.representation()) # optional - sage.libs.pari + sage: C.is_permutation_equivalent(codes.GolayCode(GF(3))) # long time # optional - sage.libs.pari True - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ A = Matrix(GF(3), [ @@ -1509,11 +1509,11 @@ def NotP8(): EXAMPLES:: - sage: M = matroids.named_matroids.P8() - sage: N = matroids.named_matroids.NotP8() - sage: M.is_isomorphic(N) + sage: M = matroids.named_matroids.P8() # optional - sage.libs.pari + sage: N = matroids.named_matroids.NotP8() # optional - sage.libs.pari + sage: M.is_isomorphic(N) # optional - sage.libs.pari False - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ A = Matrix(GF(3), [ @@ -1538,10 +1538,10 @@ def D16(): # A.K.A. the Carolyn Chun Matroid EXAMPLES:: - sage: M = matroids.named_matroids.D16() - sage: M + sage: M = matroids.named_matroids.D16() # optional - sage.libs.pari + sage: M # optional - sage.libs.pari D16: Binary matroid of rank 8 on 16 elements, type (0, 0) - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ @@ -1569,10 +1569,10 @@ def Terrahawk(): # A.K.A. the Dillon Mayhew Matroid EXAMPLES:: - sage: M = matroids.named_matroids.Terrahawk() - sage: M + sage: M = matroids.named_matroids.Terrahawk() # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Terrahawk: Binary matroid of rank 8 on 16 elements, type (0, 4) - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ @@ -1653,10 +1653,10 @@ def T12(): EXAMPLES:: - sage: M = matroids.named_matroids.T12() - sage: M + sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari + sage: M # optional - sage.libs.pari T12: Binary matroid of rank 6 on 12 elements, type (2, None) - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ A = Matrix(GF(2), [ @@ -1681,10 +1681,10 @@ def P9(): EXAMPLES:: - sage: M = matroids.named_matroids.P9() - sage: M + sage: M = matroids.named_matroids.P9() # optional - sage.libs.pari + sage: M # optional - sage.libs.pari P9: Binary matroid of rank 4 on 9 elements, type (1, 1) - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ A = Matrix(GF(2), [ diff --git a/src/sage/matroids/circuit_closures_matroid.pyx b/src/sage/matroids/circuit_closures_matroid.pyx index 679445a6a62..351f62c94c7 100644 --- a/src/sage/matroids/circuit_closures_matroid.pyx +++ b/src/sage/matroids/circuit_closures_matroid.pyx @@ -50,8 +50,8 @@ AUTHORS: TESTS:: sage: from sage.matroids.advanced import * - sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) - sage: TestSuite(M).run() + sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: TestSuite(M).run() # optional - sage.libs.pari Methods ======= @@ -117,8 +117,8 @@ cdef class CircuitClosuresMatroid(Matroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) - sage: M + sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Matroid of rank 3 on 7 elements with circuit-closures {2: {{'a', 'b', 'f'}, {'a', 'c', 'e'}, {'a', 'd', 'g'}, {'b', 'c', 'd'}, {'b', 'e', 'g'}, {'c', 'f', 'g'}, @@ -127,7 +127,7 @@ cdef class CircuitClosuresMatroid(Matroid): ....: circuit_closures={3: ['edfg', 'acdg', 'bcfg', 'cefh', ....: 'afgh', 'abce', 'abdf', 'begh', 'bcdh', 'adeh'], ....: 4: ['abcdefgh']}) - sage: M.equals(matroids.named_matroids.P8()) + sage: M.equals(matroids.named_matroids.P8()) # optional - sage.libs.pari True """ @@ -140,8 +140,8 @@ cdef class CircuitClosuresMatroid(Matroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) - sage: M + sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Matroid of rank 3 on 7 elements with circuit-closures {2: {{'a', 'b', 'f'}, {'a', 'c', 'e'}, {'a', 'd', 'g'}, {'b', 'c', 'd'}, {'b', 'e', 'g'}, {'c', 'f', 'g'}, @@ -152,7 +152,7 @@ cdef class CircuitClosuresMatroid(Matroid): ....: circuit_closures={3: ['edfg', 'acdg', 'bcfg', 'cefh', ....: 'afgh', 'abce', 'abdf', 'begh', 'bcdh', 'adeh'], ....: 4: ['abcdefgh']}) - sage: M.equals(matroids.named_matroids.P8()) + sage: M.equals(matroids.named_matroids.P8()) # optional - sage.libs.pari True """ if M is not None: diff --git a/src/sage/matroids/constructor.py b/src/sage/matroids/constructor.py index 99580562e96..6ab2f4917ef 100644 --- a/src/sage/matroids/constructor.py +++ b/src/sage/matroids/constructor.py @@ -53,8 +53,8 @@ A number of special matroids are collected under a ``named_matroids`` submenu. To see which, type ``matroids.named_matroids.`` as above:: - sage: F7 = matroids.named_matroids.Fano() - sage: len(F7.nonspanning_circuits()) + sage: F7 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: len(F7.nonspanning_circuits()) # optional - sage.libs.pari 7 Constructing matroids @@ -68,11 +68,11 @@ EXAMPLES:: - sage: A = Matrix(GF(2), [[1, 0, 0, 0, 1, 1, 1], + sage: A = Matrix(GF(2), [[1, 0, 0, 0, 1, 1, 1], # optional - sage.libs.pari ....: [0, 1, 0, 1, 0, 1, 1], ....: [0, 0, 1, 1, 1, 0, 1]]) - sage: M = Matroid(A) - sage: M.is_isomorphic(matroids.named_matroids.Fano()) + sage: M = Matroid(A) # optional - sage.libs.pari + sage: M.is_isomorphic(matroids.named_matroids.Fano()) # optional - sage.libs.pari True sage: M = Matroid(graphs.PetersenGraph()) diff --git a/src/sage/matroids/dual_matroid.py b/src/sage/matroids/dual_matroid.py index 804e43f035b..73ad305e1d6 100644 --- a/src/sage/matroids/dual_matroid.py +++ b/src/sage/matroids/dual_matroid.py @@ -10,13 +10,13 @@ EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: N = M.dual() - sage: M.is_basis('abc') + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: N = M.dual() # optional - sage.libs.pari + sage: M.is_basis('abc') # optional - sage.libs.pari True - sage: N.is_basis('defg') + sage: N.is_basis('defg') # optional - sage.libs.pari True - sage: M.dual().dual() == M + sage: M.dual().dual() == M # optional - sage.libs.pari True Implementation @@ -455,17 +455,17 @@ def __eq__(self, other): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M1 = matroids.named_matroids.Fano() - sage: M2 = CircuitClosuresMatroid(M1.dual()) - sage: M3 = CircuitClosuresMatroid(M1).dual() + sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M2 = CircuitClosuresMatroid(M1.dual()) # optional - sage.libs.pari + sage: M3 = CircuitClosuresMatroid(M1).dual() # optional - sage.libs.pari sage: M4 = CircuitClosuresMatroid(groundset='abcdefg', ....: circuit_closures={3: ['abcdefg'], 2: ['beg', 'cdb', 'cfg', ....: 'ace', 'fed', 'gad', 'fab']}).dual() - sage: M1.dual() == M2 # indirect doctest + sage: M1.dual() == M2 # indirect doctest # optional - sage.libs.pari False - sage: M2 == M3 + sage: M2 == M3 # optional - sage.libs.pari False - sage: M3 == M4 + sage: M3 == M4 # optional - sage.libs.pari True """ if not isinstance(other, DualMatroid): @@ -487,17 +487,17 @@ def __ne__(self, other): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M1 = matroids.named_matroids.Fano() - sage: M2 = CircuitClosuresMatroid(M1.dual()) - sage: M3 = CircuitClosuresMatroid(M1).dual() + sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M2 = CircuitClosuresMatroid(M1.dual()) # optional - sage.libs.pari + sage: M3 = CircuitClosuresMatroid(M1).dual() # optional - sage.libs.pari sage: M4 = CircuitClosuresMatroid(groundset='abcdefg', ....: circuit_closures={3: ['abcdefg'], 2: ['beg', 'cdb', 'cfg', ....: 'ace', 'fed', 'gad', 'fab']}).dual() - sage: M1.dual() != M2 # indirect doctest + sage: M1.dual() != M2 # indirect doctest # optional - sage.libs.pari True - sage: M2 != M3 + sage: M2 != M3 # optional - sage.libs.pari True - sage: M3 != M4 + sage: M3 != M4 # optional - sage.libs.pari False """ return not self == other diff --git a/src/sage/matroids/extension.pyx b/src/sage/matroids/extension.pyx index d762526d2fa..608d9363496 100644 --- a/src/sage/matroids/extension.pyx +++ b/src/sage/matroids/extension.pyx @@ -59,7 +59,7 @@ cdef class CutNode: EXAMPLES:: - sage: len(list(matroids.named_matroids.Fano().linear_subclasses())) # indirect doctest + sage: len(list(matroids.named_matroids.Fano().linear_subclasses())) # indirect doctest # optional - sage.libs.pari 16 """ cdef CutNode node diff --git a/src/sage/matroids/graphic_matroid.py b/src/sage/matroids/graphic_matroid.py index 9bafa6dc0c7..f91ad67ddcc 100644 --- a/src/sage/matroids/graphic_matroid.py +++ b/src/sage/matroids/graphic_matroid.py @@ -1,3 +1,5 @@ +# sage.doctest: optional - sage.graphs +# sage.doctest: optional - sage.groups (for DisjointSet) r""" Graphic Matroids diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 8d641737a8f..e693cbfb17d 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -216,7 +216,7 @@ in which the partition is specified as a list of lists:: sage: M = PartitionMatroid([[1, 2], [3, 4, 5], [6, 7]]) sage: M.full_rank() 3 - sage: M.tutte_polynomial(var('x'), var('y')) + sage: M.tutte_polynomial(var('x'), var('y')) # optional - sage.symbolic x^2*y^2 + 2*x*y^3 + y^4 + x^3 + 3*x^2*y + 3*x*y^2 + y^3 .. NOTE:: @@ -394,7 +394,7 @@ cdef class Matroid(SageObject): sage: M = PartitionMatroid([[1, 2], [3, 4, 5], [6, 7]]) sage: M.full_rank() 3 - sage: M.tutte_polynomial(var('x'), var('y')) + sage: M.tutte_polynomial(var('x'), var('y')) # optional - sage.symbolic x^2*y^2 + 2*x*y^3 + y^4 + x^3 + 3*x^2*y + 3*x*y^2 + y^3 .. NOTE:: @@ -1133,7 +1133,7 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.named_matroids.Vamos() - sage: M._has_minor(matroids.Whirl(3)) + sage: M._has_minor(matroids.Whirl(3)) # optional - sage.libs.pari False sage: M._has_minor(matroids.Uniform(2, 4)) True @@ -1361,12 +1361,12 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.rank() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.rank() # optional - sage.libs.pari 3 - sage: M.rank(['a', 'b', 'f']) + sage: M.rank(['a', 'b', 'f']) # optional - sage.libs.pari 2 - sage: M.rank(['a', 'b', 'x']) + sage: M.rank(['a', 'b', 'x']) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: ['a', 'b', 'x'] is not a subset of the groundset @@ -1672,12 +1672,12 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.corank() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.corank() # optional - sage.libs.pari 4 - sage: M.corank('cdeg') + sage: M.corank('cdeg') # optional - sage.libs.pari 3 - sage: M.rank(['a', 'b', 'x']) + sage: M.rank(['a', 'b', 'x']) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: ['a', 'b', 'x'] is not a subset of the groundset @@ -1914,10 +1914,10 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.loops() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.loops() # optional - sage.libs.pari frozenset() - sage: (M / ['a', 'b']).loops() + sage: (M / ['a', 'b']).loops() # optional - sage.libs.pari frozenset({'f'}) """ return self._closure(set()) @@ -2138,10 +2138,10 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano().dual() - sage: M.coloops() + sage: M = matroids.named_matroids.Fano().dual() # optional - sage.libs.pari + sage: M.coloops() # optional - sage.libs.pari frozenset() - sage: (M \ ['a', 'b']).coloops() + sage: (M \ ['a', 'b']).coloops() # optional - sage.libs.pari frozenset({'f'}) """ return self._coclosure(set()) @@ -2384,8 +2384,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted([sorted(C) for C in M.circuits()]) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted([sorted(C) for C in M.circuits()]) # optional - sage.libs.pari [['a', 'b', 'c', 'g'], ['a', 'b', 'd', 'e'], ['a', 'b', 'f'], ['a', 'c', 'd', 'f'], ['a', 'c', 'e'], ['a', 'd', 'g'], ['a', 'e', 'f', 'g'], ['b', 'c', 'd'], ['b', 'c', 'e', 'f'], @@ -2416,8 +2416,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted([sorted(C) for C in M.nonspanning_circuits()]) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted([sorted(C) for C in M.nonspanning_circuits()]) # optional - sage.libs.pari [['a', 'b', 'f'], ['a', 'c', 'e'], ['a', 'd', 'g'], ['b', 'c', 'd'], ['b', 'e', 'g'], ['c', 'f', 'g'], ['d', 'e', 'f']] @@ -2442,8 +2442,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted([sorted(C) for C in M.cocircuits()]) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted([sorted(C) for C in M.cocircuits()]) # optional - sage.libs.pari [['a', 'b', 'c', 'g'], ['a', 'b', 'd', 'e'], ['a', 'c', 'd', 'f'], ['a', 'e', 'f', 'g'], ['b', 'c', 'e', 'f'], ['b', 'd', 'f', 'g'], ['c', 'd', 'e', 'g']] @@ -2471,8 +2471,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano().dual() - sage: sorted([sorted(C) for C in M.noncospanning_cocircuits()]) + sage: M = matroids.named_matroids.Fano().dual() # optional - sage.libs.pari + sage: sorted([sorted(C) for C in M.noncospanning_cocircuits()]) # optional - sage.libs.pari [['a', 'b', 'f'], ['a', 'c', 'e'], ['a', 'd', 'g'], ['b', 'c', 'd'], ['b', 'e', 'g'], ['c', 'f', 'g'], ['d', 'e', 'f']] @@ -2497,17 +2497,17 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: CC = M.circuit_closures() - sage: len(CC[2]) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: CC = M.circuit_closures() # optional - sage.libs.pari + sage: len(CC[2]) # optional - sage.libs.pari 7 - sage: len(CC[3]) + sage: len(CC[3]) # optional - sage.libs.pari 1 - sage: len(CC[1]) + sage: len(CC[1]) # optional - sage.libs.pari Traceback (most recent call last): ... KeyError: 1 - sage: [sorted(X) for X in CC[3]] + sage: [sorted(X) for X in CC[3]] # optional - sage.libs.pari [['a', 'b', 'c', 'd', 'e', 'f', 'g']] """ CC = [set([]) for r in xrange(self.rank() + 1)] @@ -2534,11 +2534,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: CC = M.nonspanning_circuit_closures() - sage: len(CC[2]) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: CC = M.nonspanning_circuit_closures() # optional - sage.libs.pari + sage: len(CC[2]) # optional - sage.libs.pari 7 - sage: len(CC[3]) + sage: len(CC[3]) # optional - sage.libs.pari Traceback (most recent call last): ... KeyError: 3 @@ -2737,9 +2737,9 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: F = M._flags(1) - sage: sorted(M._extend_flags(F)) == sorted(M._flags(2)) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: F = M._flags(1) # optional - sage.libs.pari + sage: sorted(M._extend_flags(F)) == sorted(M._flags(2)) # optional - sage.libs.pari True """ newflags = [] @@ -2777,8 +2777,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted([M._flags(1)]) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted([M._flags(1)]) # optional - sage.libs.pari [[[frozenset({'a'}), {'a'}, frozenset({'b', 'c', 'd', 'e', 'f', 'g'})], [frozenset({'b'}), {'b'}, frozenset({'c', 'd', 'e', 'f', 'g'})], [frozenset({'c'}), {'c'}, frozenset({'d', 'e', 'f', 'g'})], @@ -2815,8 +2815,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted([sorted(F) for F in M.flats(2)]) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted([sorted(F) for F in M.flats(2)]) # optional - sage.libs.pari [['a', 'b', 'f'], ['a', 'c', 'e'], ['a', 'd', 'g'], ['b', 'c', 'd'], ['b', 'e', 'g'], ['c', 'f', 'g'], ['d', 'e', 'f']] @@ -2844,8 +2844,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Q6() - sage: sorted([sorted(F) for F in M.coflats(2)]) + sage: M = matroids.named_matroids.Q6() # optional - sage.libs.pari + sage: sorted([sorted(F) for F in M.coflats(2)]) # optional - sage.libs.pari [['a', 'b'], ['a', 'c'], ['a', 'd', 'f'], ['a', 'e'], ['b', 'c'], ['b', 'd'], ['b', 'e'], ['b', 'f'], ['c', 'd'], ['c', 'e', 'f'], ['d', 'e']] @@ -2858,8 +2858,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.lattice_of_flats() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.lattice_of_flats() # optional - sage.libs.pari Finite lattice containing 16 elements """ from sage.combinat.posets.lattices import LatticePoset @@ -3125,13 +3125,13 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.Whirl(4) - sage: P = M.matroid_polytope(); P + sage: M = matroids.Whirl(4) # optional - sage.libs.pari + sage: P = M.matroid_polytope(); P # optional - sage.geometry.polyhedron sage.libs.pari A 7-dimensional polyhedron in ZZ^8 defined as the convex hull of 46 vertices - sage: M = matroids.named_matroids.NonFano() - sage: M.matroid_polytope() + sage: M = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M.matroid_polytope() # optional - sage.geometry.polyhedron sage.libs.pari A 6-dimensional polyhedron in ZZ^7 defined as the convex hull of 29 vertices @@ -3168,13 +3168,13 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.Whirl(4) - sage: M.independence_matroid_polytope() + sage: M = matroids.Whirl(4) # optional - sage.libs.pari + sage: M.independence_matroid_polytope() # optional - sage.geometry.polyhedron sage.libs.pari A 8-dimensional polyhedron in ZZ^8 defined as the convex hull of 135 vertices - sage: M = matroids.named_matroids.NonFano() - sage: M.independence_matroid_polytope() + sage: M = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M.independence_matroid_polytope() # optional - sage.geometry.polyhedron sage.libs.pari A 7-dimensional polyhedron in ZZ^7 defined as the convex hull of 58 vertices @@ -3227,11 +3227,11 @@ cdef class Matroid(SageObject): TypeError: can only test for isomorphism between matroids. - sage: M1 = matroids.named_matroids.Fano() - sage: M2 = matroids.named_matroids.NonFano() - sage: M1.is_isomorphic(M2) + sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M1.is_isomorphic(M2) # optional - sage.libs.pari False - sage: M1.is_isomorphic(M2, certificate=True) + sage: M1.is_isomorphic(M2, certificate=True) # optional - sage.libs.pari (False, None) """ if not isinstance(other, Matroid): @@ -3267,9 +3267,9 @@ cdef class Matroid(SageObject): sage: M1._is_isomorphic(M2, certificate=True) (True, {0: 0, 1: 1, 2: 2, 3: 3, 4: 5, 5: 4}) - sage: M1 = matroids.named_matroids.Fano() - sage: M2 = matroids.named_matroids.NonFano() - sage: M1._is_isomorphic(M2) + sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M1._is_isomorphic(M2) # optional - sage.libs.pari False """ @@ -3309,9 +3309,9 @@ cdef class Matroid(SageObject): ... TypeError: can only give isomorphism between matroids. - sage: M1 = matroids.named_matroids.Fano() - sage: M2 = matroids.named_matroids.NonFano() - sage: M1.isomorphism(M2) is not None + sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M1.isomorphism(M2) is not None # optional - sage.libs.pari False """ if not isinstance(other, Matroid): @@ -3339,9 +3339,9 @@ cdef class Matroid(SageObject): sage: morphism=M1.isomorphism(M2) sage: M1.is_isomorphism(M2, morphism) True - sage: M1 = matroids.named_matroids.Fano() - sage: M2 = matroids.named_matroids.NonFano() - sage: M1.isomorphism(M2) is not None + sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M1.isomorphism(M2) is not None # optional - sage.libs.pari False """ if self is other: @@ -3385,38 +3385,38 @@ cdef class Matroid(SageObject): yields ``False``, even if the matroids are equal:: sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.Fano() - sage: M + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) - sage: M1 = BasisMatroid(M) - sage: M2 = Matroid(groundset='abcdefg', reduced_matrix=[ + sage: M1 = BasisMatroid(M) # optional - sage.libs.pari + sage: M2 = Matroid(groundset='abcdefg', reduced_matrix=[ # optional - sage.libs.pari ....: [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 0, 1]], field=GF(2)) - sage: M.equals(M1) + sage: M.equals(M1) # optional - sage.libs.pari True - sage: M.equals(M2) + sage: M.equals(M2) # optional - sage.libs.pari True - sage: M == M1 + sage: M == M1 # optional - sage.libs.pari False - sage: M == M2 + sage: M == M2 # optional - sage.libs.pari True :class:`LinearMatroid ` instances ``M`` and ``N`` satisfy ``M == N`` if the representations are equivalent up to row operations and column scaling:: - sage: M1 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), + sage: M1 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari ....: [[1, 0, 1, 1], [0, 1, 1, 2]])) - sage: M2 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), + sage: M2 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari ....: [[1, 0, 1, 1], [0, 1, 1, 3]])) - sage: M3 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), + sage: M3 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari ....: [[2, 6, 1, 0], [6, 1, 0, 1]])) - sage: M1.equals(M2) + sage: M1.equals(M2) # optional - sage.libs.pari True - sage: M1.equals(M3) + sage: M1.equals(M3) # optional - sage.libs.pari True - sage: M1 == M2 + sage: M1 == M2 # optional - sage.libs.pari False - sage: M1 == M3 + sage: M1 == M3 # optional - sage.libs.pari True """ if self is other: @@ -3463,19 +3463,19 @@ cdef class Matroid(SageObject): sage: N.is_isomorphism(M, {e:e for e in M.groundset()}) False - sage: M = matroids.named_matroids.Fano() \ ['g'] - sage: N = matroids.Wheel(3) - sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} - sage: M.is_isomorphism(N, morphism) + sage: M = matroids.named_matroids.Fano() \ ['g'] # optional - sage.libs.pari + sage: N = matroids.Wheel(3) # optional - sage.libs.pari + sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} # optional - sage.libs.pari + sage: M.is_isomorphism(N, morphism) # optional - sage.libs.pari True A morphism can be specified as a dictionary (above), a permutation, a function, and many other types of maps:: - sage: M = matroids.named_matroids.Fano() - sage: P = PermutationGroup([[('a', 'b', 'c'), + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: P = PermutationGroup([[('a', 'b', 'c'), # optional - sage.libs.pari ....: ('d', 'e', 'f'), ('g')]]).gen() - sage: M.is_isomorphism(M, P) + sage: M.is_isomorphism(M, P) # optional - sage.libs.pari True sage: M = matroids.named_matroids.Pappus() @@ -3572,10 +3572,10 @@ cdef class Matroid(SageObject): sage: N._is_isomorphism(M, {e:e for e in M.groundset()}) False - sage: M = matroids.named_matroids.Fano() \ ['g'] + sage: M = matroids.named_matroids.Fano() \ ['g'] # optional - sage.libs.pari sage: N = matroids.Wheel(3) sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} - sage: M._is_isomorphism(N, morphism) + sage: M._is_isomorphism(N, morphism) # optional - sage.libs.pari True """ from . import basis_exchange_matroid @@ -3639,19 +3639,19 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M1 = Matroid(groundset='abcd', matrix=Matrix(GF(7), + sage: M1 = Matroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari ....: [[1, 0, 1, 1], [0, 1, 1, 2]])) - sage: M2 = Matroid(groundset='abcd', matrix=Matrix(GF(7), + sage: M2 = Matroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari ....: [[1, 0, 1, 1], [0, 1, 1, 3]])) - sage: M3 = Matroid(groundset='abcd', matrix=Matrix(GF(7), + sage: M3 = Matroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari ....: [[2, 6, 1, 0], [6, 1, 0, 1]])) - sage: M1.equals(M2) + sage: M1.equals(M2) # optional - sage.libs.pari True - sage: M1.equals(M3) + sage: M1.equals(M3) # optional - sage.libs.pari True - sage: M1 != M2 # indirect doctest + sage: M1 != M2 # indirect doctest # optional - sage.libs.pari True - sage: M1 == M3 # indirect doctest + sage: M1 == M3 # indirect doctest # optional - sage.libs.pari True """ if op not in [Py_EQ, Py_NE]: @@ -3713,10 +3713,10 @@ cdef class Matroid(SageObject): The sets of contractions and deletions need not be independent, respectively coindependent:: - sage: M = matroids.named_matroids.Fano() - sage: M.rank('abf') + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.rank('abf') # optional - sage.libs.pari 2 - sage: M.minor(contractions='abf') + sage: M.minor(contractions='abf') # optional - sage.libs.pari Binary matroid of rank 1 on 4 elements, type (1, 0) However, they need to be subsets of the groundset, and disjoint:: @@ -3819,12 +3819,12 @@ cdef class Matroid(SageObject): :: - sage: M = matroids.named_matroids.Fano() - sage: sorted(M.groundset()) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted(M.groundset()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - sage: M.contract(['a', 'c']) + sage: M.contract(['a', 'c']) # optional - sage.libs.pari Binary matroid of rank 1 on 5 elements, type (1, 0) - sage: M.contract(['a']) == M / ['a'] + sage: M.contract(['a']) == M / ['a'] # optional - sage.libs.pari True One can use a single element, rather than a set:: @@ -3837,8 +3837,8 @@ cdef class Matroid(SageObject): Note that one can iterate over strings:: - sage: M = matroids.named_matroids.Fano() - sage: M / 'abc' + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M / 'abc' # optional - sage.libs.pari Binary matroid of rank 0 on 4 elements, type (0, 0) The following is therefore ambiguous. Sage will contract the single @@ -3896,12 +3896,12 @@ cdef class Matroid(SageObject): :: - sage: M = matroids.named_matroids.Fano() - sage: sorted(M.groundset()) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted(M.groundset()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - sage: M.delete(['a', 'c']) + sage: M.delete(['a', 'c']) # optional - sage.libs.pari Binary matroid of rank 3 on 5 elements, type (1, 6) - sage: M.delete(['a']) == M \ ['a'] + sage: M.delete(['a']) == M \ ['a'] # optional - sage.libs.pari True One can use a single element, rather than a set:: @@ -3914,8 +3914,8 @@ cdef class Matroid(SageObject): Note that one can iterate over strings:: - sage: M = matroids.named_matroids.Fano() - sage: M \ 'abc' + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M \ 'abc' # optional - sage.libs.pari Binary matroid of rank 3 on 4 elements, type (0, 5) The following is therefore ambiguous. Sage will delete the single @@ -3994,9 +3994,9 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: N = M.truncation() - sage: N.is_isomorphic(matroids.Uniform(2, 7)) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: N = M.truncation() # optional - sage.libs.pari + sage: N.is_isomorphic(matroids.Uniform(2, 7)) # optional - sage.libs.pari True """ if self.full_rank() == 0: @@ -4034,15 +4034,15 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.Whirl(3) - sage: matroids.named_matroids.Fano().has_minor(M) + sage: matroids.named_matroids.Fano().has_minor(M) # optional - sage.libs.pari False - sage: matroids.named_matroids.NonFano().has_minor(M) + sage: matroids.named_matroids.NonFano().has_minor(M) # optional - sage.libs.pari True - sage: matroids.named_matroids.NonFano().has_minor(M, certificate=True) + sage: matroids.named_matroids.NonFano().has_minor(M, certificate=True) # optional - sage.libs.pari (True, (frozenset(), frozenset({'g'}), {0: 'b', 1: 'c', 2: 'a', 3: 'd', 4: 'e', 5: 'f'})) - sage: M = matroids.named_matroids.Fano() - sage: M.has_minor(M, True) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.has_minor(M, True) # optional - sage.libs.pari (True, (frozenset(), frozenset(), @@ -4083,21 +4083,21 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: M.has_line_minor(4) + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: M.has_line_minor(4) # optional - sage.libs.pari True - sage: M.has_line_minor(5) + sage: M.has_line_minor(5) # optional - sage.libs.pari False - sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c']]) + sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c']]) # optional - sage.libs.pari False - sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], + sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], # optional - sage.libs.pari ....: ['a', 'b', 'd' ]]) True - sage: M.has_line_minor(4, certificate=True) + sage: M.has_line_minor(4, certificate=True) # optional - sage.libs.pari (True, frozenset({'a', 'b', 'd'})) - sage: M.has_line_minor(5, certificate=True) + sage: M.has_line_minor(5, certificate=True) # optional - sage.libs.pari (False, None) - sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], + sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], # optional - sage.libs.pari ....: ['a', 'b', 'd' ]], certificate=True) (True, frozenset({'a', 'b', 'd'})) @@ -4231,9 +4231,9 @@ cdef class Matroid(SageObject): Putting an element in parallel with another:: - sage: M = matroids.named_matroids.Fano() - sage: N = M.extension('z', ['c']) - sage: N.rank('cz') + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: N = M.extension('z', ['c']) # optional - sage.libs.pari + sage: N.rank('cz') # optional - sage.libs.pari 1 """ r = self.full_rank() - 1 @@ -4304,9 +4304,9 @@ cdef class Matroid(SageObject): Put an element in series with another:: - sage: M = matroids.named_matroids.Fano() - sage: N = M.coextension('z', ['c']) - sage: N.corank('cz') + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: N = M.coextension('z', ['c']) # optional - sage.libs.pari + sage: N.corank('cz') # optional - sage.libs.pari 1 """ return self.dual().extension(element, subsets).dual() @@ -4374,8 +4374,8 @@ cdef class Matroid(SageObject): The modular cut of the full groundset is equal to just the groundset:: - sage: M = matroids.named_matroids.Fano() - sage: M.modular_cut([M.groundset()]).difference( + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.modular_cut([M.groundset()]).difference( # optional - sage.libs.pari ....: [frozenset(M.groundset())]) set() """ @@ -4446,12 +4446,12 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: len(list(M.linear_subclasses())) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: len(list(M.linear_subclasses())) # optional - sage.libs.pari 16 - sage: len(list(M.linear_subclasses(line_length=3))) + sage: len(list(M.linear_subclasses(line_length=3))) # optional - sage.libs.pari 8 - sage: len(list(M.linear_subclasses(subsets=[{'a', 'b'}]))) + sage: len(list(M.linear_subclasses(subsets=[{'a', 'b'}]))) # optional - sage.libs.pari 5 The following matroid has an extension by element `e` such that @@ -4515,14 +4515,14 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.P8() - sage: len(list(M.extensions())) + sage: M = matroids.named_matroids.P8() # optional - sage.libs.pari + sage: len(list(M.extensions())) # optional - sage.libs.pari 1705 - sage: len(list(M.extensions(line_length=4))) + sage: len(list(M.extensions(line_length=4))) # optional - sage.libs.pari 41 - sage: sorted(M.groundset()) + sage: sorted(M.groundset()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] - sage: len(list(M.extensions(subsets=[{'a', 'b'}], line_length=4))) + sage: len(list(M.extensions(subsets=[{'a', 'b'}], line_length=4))) # optional - sage.libs.pari 5 """ @@ -4583,14 +4583,14 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.P8() - sage: len(list(M.coextensions())) + sage: M = matroids.named_matroids.P8() # optional - sage.libs.pari + sage: len(list(M.coextensions())) # optional - sage.libs.pari 1705 - sage: len(list(M.coextensions(coline_length=4))) + sage: len(list(M.coextensions(coline_length=4))) # optional - sage.libs.pari 41 - sage: sorted(M.groundset()) + sage: sorted(M.groundset()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] - sage: len(list(M.coextensions(subsets=[{'a', 'b'}], coline_length=4))) + sage: len(list(M.coextensions(subsets=[{'a', 'b'}], coline_length=4))) # optional - sage.libs.pari 5 """ @@ -4624,8 +4624,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano().contract('a') - sage: M.size() - M.simplify().size() + sage: M = matroids.named_matroids.Fano().contract('a') # optional - sage.libs.pari + sage: M.size() - M.simplify().size() # optional - sage.libs.pari 3 """ @@ -4663,8 +4663,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano().dual().delete('a') - sage: M.cosimplify().size() + sage: M = matroids.named_matroids.Fano().dual().delete('a') # optional - sage.libs.pari + sage: M.cosimplify().size() # optional - sage.libs.pari 3 """ @@ -4698,11 +4698,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.is_simple() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.is_simple() # optional - sage.libs.pari True - sage: N = M / 'a' - sage: N.is_simple() + sage: N = M / 'a' # optional - sage.libs.pari + sage: N.is_simple() # optional - sage.libs.pari False """ if self._closure(frozenset()): @@ -4734,11 +4734,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano().dual() - sage: M.is_cosimple() + sage: M = matroids.named_matroids.Fano().dual() # optional - sage.libs.pari + sage: M.is_cosimple() # optional - sage.libs.pari True - sage: N = M \ 'a' - sage: N.is_cosimple() + sage: N = M \ 'a' # optional - sage.libs.pari + sage: N.is_cosimple() # optional - sage.libs.pari False """ if self._coclosure(frozenset()): @@ -5281,14 +5281,14 @@ cdef class Matroid(SageObject): (False, True) sage: matroids.Uniform(4, 8).is_4connected() True - sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], + sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], # optional - sage.libs.pari ....: [0,1,0,1,0,1,0,1,0,0,0,1], ....: [0,0,1,1,0,0,1,1,0,1,0,1], ....: [0,0,0,0,1,1,1,1,0,0,1,1], ....: [0,0,0,0,0,0,0,0,1,1,1,1]]) - sage: M.is_4connected() == M.is_4connected(algorithm="shifting") + sage: M.is_4connected() == M.is_4connected(algorithm="shifting") # optional - sage.libs.pari True - sage: M.is_4connected() == M.is_4connected(algorithm="intersection") + sage: M.is_4connected() == M.is_4connected(algorithm="intersection") # optional - sage.libs.pari True """ if algorithm is None or algorithm == "intersection": @@ -5636,18 +5636,18 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], + sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], # optional - sage.libs.pari ....: [0,1,0,1,0,1,0,1,0,0,0,1], ....: [0,0,1,1,0,0,1,1,0,1,0,1], ....: [0,0,0,0,1,1,1,1,0,0,1,1], ....: [0,0,0,0,0,0,0,0,1,1,1,1]]) - sage: M._shifting_all(M.basis(),set([0,1]),set([0,1]),set([]),set([]),3) + sage: M._shifting_all(M.basis(),set([0,1]),set([0,1]),set([]),set([]),3) # optional - sage.libs.pari (False, None) - sage: M = Matroid(field=GF(2), reduced_matrix=[[1,0,1,1,1], + sage: M = Matroid(field=GF(2), reduced_matrix=[[1,0,1,1,1], # optional - sage.libs.pari ....: [1,1,1,1,0], ....: [0,1,1,1,0], ....: [0,0,0,1,1]]) - sage: M._shifting_all(M.basis(), set([0,1]), set([5,8]), set([]), set([]), 3)[0] + sage: M._shifting_all(M.basis(), set([0,1]), set([5,8]), set([]), set([]), 3)[0] # optional - sage.libs.pari True """ @@ -5696,18 +5696,18 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], + sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], # optional - sage.libs.pari ....: [0,1,0,1,0,1,0,1,0,0,0,1], ....: [0,0,1,1,0,0,1,1,0,1,0,1], ....: [0,0,0,0,1,1,1,1,0,0,1,1], ....: [0,0,0,0,0,0,0,0,1,1,1,1]]) - sage: M._shifting(M.basis(),set([0,1]),set([0,1]),set([]),set([]),3) + sage: M._shifting(M.basis(),set([0,1]),set([0,1]),set([]),set([]),3) # optional - sage.libs.pari (False, None) - sage: M = Matroid(field=GF(2), reduced_matrix=[[1,0,1,1,1], + sage: M = Matroid(field=GF(2), reduced_matrix=[[1,0,1,1,1], # optional - sage.libs.pari ....: [1,1,1,1,0], ....: [0,1,1,1,0], ....: [0,0,0,1,1]]) - sage: M._shifting(M.basis(), set([0,1]), set([5,8]), set([]), set([4]), 3)[0] + sage: M._shifting(M.basis(), set([0,1]), set([5,8]), set([]), set([4]), 3)[0] # optional - sage.libs.pari True """ @@ -5791,8 +5791,8 @@ cdef class Matroid(SageObject): False sage: matroids.named_matroids.BetsyRoss()._is_3connected_BC() True - sage: M = matroids.named_matroids.R6() - sage: M._is_3connected_BC() + sage: M = matroids.named_matroids.R6() # optional - sage.libs.pari + sage: M._is_3connected_BC() # optional - sage.libs.pari False """ # The 5 stages of the algorithm @@ -5837,9 +5837,9 @@ cdef class Matroid(SageObject): sage: M._is_3connected_BC_recursion(B, ....: [M.fundamental_cocircuit(B, e) for e in B]) True - sage: M = matroids.named_matroids.R6() - sage: B = M.basis() - sage: M._is_3connected_BC_recursion(B, + sage: M = matroids.named_matroids.R6() # optional - sage.libs.pari + sage: B = M.basis() # optional - sage.libs.pari + sage: M._is_3connected_BC_recursion(B, # optional - sage.libs.pari ....: [M.fundamental_cocircuit(B, e) for e in B]) False @@ -5929,13 +5929,13 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: N = matroids.named_matroids.Fano() - sage: M = N._local_binary_matroid() - sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) + sage: N = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M = N._local_binary_matroid() # optional - sage.libs.pari + sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.libs.pari True - sage: N = matroids.named_matroids.NonFano() - sage: M = N._local_binary_matroid() - sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) + sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M = N._local_binary_matroid() # optional - sage.libs.pari + sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.libs.pari False """ if basis is None: @@ -5987,11 +5987,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.binary_matroid() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.binary_matroid() # optional - sage.libs.pari Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) - sage: N = matroids.named_matroids.NonFano() - sage: N.binary_matroid() is None + sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: N.binary_matroid() is None # optional - sage.libs.pari True """ @@ -6039,11 +6039,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: N = matroids.named_matroids.Fano() - sage: N.is_binary() + sage: N = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: N.is_binary() # optional - sage.libs.pari True - sage: N = matroids.named_matroids.NonFano() - sage: N.is_binary() + sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: N.is_binary() # optional - sage.libs.pari False """ @@ -6080,13 +6080,13 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: N = matroids.named_matroids.Fano() - sage: M = N._local_ternary_matroid() - sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) + sage: N = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M = N._local_ternary_matroid() # optional - sage.libs.pari + sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.libs.pari False - sage: N = matroids.named_matroids.NonFano() - sage: M = N._local_ternary_matroid() - sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) + sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M = N._local_ternary_matroid() # optional - sage.libs.pari + sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.libs.pari True """ if basis is None: @@ -6172,11 +6172,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.ternary_matroid() is None + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.ternary_matroid() is None # optional - sage.libs.pari True - sage: N = matroids.named_matroids.NonFano() - sage: N.ternary_matroid() + sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: N.ternary_matroid() # optional - sage.libs.pari NonFano: Ternary matroid of rank 3 on 7 elements, type 0- """ @@ -6224,11 +6224,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: N = matroids.named_matroids.Fano() - sage: N.is_ternary() + sage: N = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: N.is_ternary() # optional - sage.libs.pari False - sage: N = matroids.named_matroids.NonFano() - sage: N.is_ternary() + sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: N.is_ternary() # optional - sage.libs.pari True """ @@ -6392,15 +6392,15 @@ cdef class Matroid(SageObject): sage: M = matroids.Uniform(2,4) sage: [M.is_chordal(i) for i in range(4, 8)] [True, True, True, True] - sage: M = matroids.named_matroids.NonFano() - sage: [M.is_chordal(i) for i in range(4, 8)] + sage: M = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: [M.is_chordal(i) for i in range(4, 8)] # optional - sage.libs.pari [False, True, True, True] - sage: M = matroids.named_matroids.N2() - sage: [M.is_chordal(i) for i in range(4, 10)] + sage: M = matroids.named_matroids.N2() # optional - sage.libs.pari + sage: [M.is_chordal(i) for i in range(4, 10)] # optional - sage.libs.pari [False, False, False, False, True, True] - sage: M.is_chordal(4, 5) + sage: M.is_chordal(4, 5) # optional - sage.libs.pari False - sage: M.is_chordal(4, 5, certificate=True) + sage: M.is_chordal(4, 5, certificate=True) # optional - sage.libs.pari (False, frozenset({'a', 'b', 'e', 'f', 'g'})) """ cdef frozenset C @@ -6428,11 +6428,11 @@ cdef class Matroid(SageObject): sage: M = matroids.Uniform(2,4) sage: M.chordality() 4 - sage: M = matroids.named_matroids.NonFano() - sage: M.chordality() + sage: M = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M.chordality() # optional - sage.libs.pari 5 - sage: M = matroids.named_matroids.Fano() - sage: M.chordality() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.chordality() # optional - sage.libs.pari 4 """ cdef frozenset C @@ -6474,14 +6474,14 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano() - sage: X = M.max_weight_independent() - sage: M.is_basis(X) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: X = M.max_weight_independent() # optional - sage.libs.pari + sage: M.is_basis(X) # optional - sage.libs.pari True sage: wt = {'a': 1, 'b': 2, 'c': 2, 'd': 1/2, 'e': 1, ....: 'f': 2, 'g': 2} - sage: setprint(M.max_weight_independent(weights=wt)) + sage: setprint(M.max_weight_independent(weights=wt)) # optional - sage.libs.pari {'b', 'f', 'g'} sage: def wt(x): ....: return x @@ -6561,18 +6561,18 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano() - sage: X = M.max_weight_coindependent() - sage: M.is_cobasis(X) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: X = M.max_weight_coindependent() # optional - sage.libs.pari + sage: M.is_cobasis(X) # optional - sage.libs.pari True sage: wt = {'a': 1, 'b': 2, 'c': 2, 'd': 1/2, 'e': 1, 'f': 2, ....: 'g': 2} - sage: setprint(M.max_weight_coindependent(weights=wt)) + sage: setprint(M.max_weight_coindependent(weights=wt)) # optional - sage.libs.pari {'b', 'c', 'f', 'g'} sage: wt = {'a': 1, 'b': -10, 'c': 2, 'd': 1/2, 'e': 1, 'f': 2, ....: 'g': 2} - sage: setprint(M.max_weight_coindependent(weights=wt)) + sage: setprint(M.max_weight_coindependent(weights=wt)) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: nonnegative weights were expected. @@ -6660,8 +6660,8 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano() - sage: M.is_max_weight_independent_generic() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.is_max_weight_independent_generic() # optional - sage.libs.pari False sage: def wt(x): @@ -6810,8 +6810,8 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano() - sage: M.is_max_weight_coindependent_generic() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.is_max_weight_coindependent_generic() # optional - sage.libs.pari False sage: def wt(x): @@ -6958,18 +6958,18 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() + sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari sage: w = {'a':30, 'b':10, 'c':11, 'd':20, 'e':70, 'f':21, 'g':90, ....: 'h':12, 'i':80, 'j':13, 'k':40, 'l':21} - sage: Y = M.intersection(N, w) - sage: sorted(Y) + sage: Y = M.intersection(N, w) # optional - sage.libs.pari + sage: sorted(Y) # optional - sage.libs.pari ['a', 'd', 'e', 'g', 'i', 'k'] - sage: sum([w[y] for y in Y]) + sage: sum([w[y] for y in Y]) # optional - sage.libs.pari 330 - sage: M = matroids.named_matroids.Fano() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari sage: N = matroids.Uniform(4, 7) - sage: M.intersection(N) + sage: M.intersection(N) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: matroid intersection requires equal groundsets. @@ -7017,14 +7017,14 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() + sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari sage: w = {'a':30, 'b':10, 'c':11, 'd':20, 'e':70, 'f':21, 'g':90, ....: 'h':12, 'i':80, 'j':13, 'k':40, 'l':21} - sage: Y = M._intersection(N, w) - sage: sorted(Y) + sage: Y = M._intersection(N, w) # optional - sage.libs.pari + sage: sorted(Y) # optional - sage.libs.pari ['a', 'd', 'e', 'g', 'i', 'k'] - sage: sum([w[y] for y in Y]) + sage: sum([w[y] for y in Y]) # optional - sage.libs.pari 330 """ Y = set() @@ -7063,14 +7063,14 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() + sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari sage: w = {'a':30, 'b':10, 'c':11, 'd':20, 'e':70, 'f':21, 'g':90, ....: 'h':12, 'i':80, 'j':13, 'k':40, 'l':21} - sage: Y = M.intersection(N, w) - sage: sorted(Y) + sage: Y = M.intersection(N, w) # optional - sage.libs.pari + sage: sorted(Y) # optional - sage.libs.pari ['a', 'd', 'e', 'g', 'i', 'k'] - sage: M._intersection_augmentation(N, w, Y)[0] + sage: M._intersection_augmentation(N, w, Y)[0] # optional - sage.libs.pari False """ X = self.groundset() - Y @@ -7144,13 +7144,13 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() - sage: len(M.intersection_unweighted(N)) + sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari + sage: len(M.intersection_unweighted(N)) # optional - sage.libs.pari 6 - sage: M = matroids.named_matroids.Fano() - sage: N = matroids.Uniform(4, 7) - sage: M.intersection_unweighted(N) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: N = matroids.Uniform(4, 7) # optional - sage.libs.pari + sage: M.intersection_unweighted(N) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: matroid intersection requires equal groundsets. @@ -7185,9 +7185,9 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() - sage: len(M._intersection_unweighted(N)) + sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari + sage: len(M._intersection_unweighted(N)) # optional - sage.libs.pari 6 """ Y = set() @@ -7219,15 +7219,15 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() - sage: Y = M.intersection(N) - sage: M._intersection_augmentation_unweighted(N, Y)[0] + sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari + sage: Y = M.intersection(N) # optional - sage.libs.pari + sage: M._intersection_augmentation_unweighted(N, Y)[0] # optional - sage.libs.pari False - sage: Y = M._intersection_augmentation_unweighted(N,set()) - sage: Y[0] + sage: Y = M._intersection_augmentation_unweighted(N,set()) # optional - sage.libs.pari + sage: Y[0] # optional - sage.libs.pari True - sage: len(Y[1])>0 + sage: len(Y[1])>0 # optional - sage.libs.pari True """ E = self.groundset() @@ -7425,10 +7425,10 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted(M._internal({'a', 'b', 'c'})) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted(M._internal({'a', 'b', 'c'})) # optional - sage.libs.pari ['a', 'b', 'c'] - sage: sorted(M._internal({'e', 'f', 'g'})) + sage: sorted(M._internal({'e', 'f', 'g'})) # optional - sage.libs.pari [] """ N = self.groundset() - B @@ -7464,10 +7464,10 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted(M._external({'a', 'b', 'c'})) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted(M._external({'a', 'b', 'c'})) # optional - sage.libs.pari [] - sage: sorted(M._external({'e', 'f', 'g'})) + sage: sorted(M._external({'e', 'f', 'g'})) # optional - sage.libs.pari ['a', 'b', 'c', 'd'] """ @@ -7517,10 +7517,10 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.tutte_polynomial() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.tutte_polynomial() # optional - sage.libs.pari y^4 + x^3 + 3*y^3 + 4*x^2 + 7*x*y + 6*y^2 + 3*x + 3*y - sage: M.tutte_polynomial(1, 1) == M.bases_count() + sage: M.tutte_polynomial(1, 1) == M.bases_count() # optional - sage.libs.pari True ALGORITHM: @@ -7565,8 +7565,8 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano() - sage: setprint(M.flat_cover()) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: setprint(M.flat_cover()) # optional - sage.libs.pari [{'a', 'b', 'f'}, {'a', 'c', 'e'}, {'a', 'd', 'g'}, {'b', 'c', 'd'}, {'b', 'e', 'g'}, {'c', 'f', 'g'}, {'d', 'e', 'f'}] @@ -7634,21 +7634,21 @@ cdef class Matroid(SageObject): We construct a more interesting example using the Fano matroid:: - sage: M = matroids.named_matroids.Fano() - sage: A = M.chow_ring(QQ) - sage: A + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: A = M.chow_ring(QQ) # optional - sage.libs.pari + sage: A # optional - sage.libs.pari Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) over Rational Field Next we get the non-trivial generators and do some computations:: - sage: G = A.gens()[6:] - sage: Ag, Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef = G - sage: Ag * Ag + sage: G = A.gens()[6:] # optional - sage.libs.pari + sage: Ag, Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef = G # optional - sage.libs.pari + sage: Ag * Ag # optional - sage.libs.pari 2*Adef^2 - sage: Ag * Abeg + sage: Ag * Abeg # optional - sage.libs.pari -Adef^2 - sage: matrix([[x * y for x in G] for y in G]) + sage: matrix([[x * y for x in G] for y in G]) # optional - sage.libs.pari [2*Adef^2 0 0 -Adef^2 0 -Adef^2 -Adef^2 0] [ 0 Adef^2 0 0 0 0 0 0] [ 0 0 Adef^2 0 0 0 0 0] @@ -7723,11 +7723,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M=matroids.named_matroids.Fano() - sage: G=M.plot() - sage: type(G) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: G = M.plot() # optional - sage.libs.pari sage.plot + sage: type(G) # optional - sage.libs.pari sage.plot - sage: G.show() + sage: G.show() # optional - sage.libs.pari sage.plot """ from . import matroids_plot_helpers @@ -7780,11 +7780,12 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M=matroids.named_matroids.TernaryDowling3() - sage: M.show(B=['a','b','c']) - sage: M.show(B=['a','b','c'],lineorders=[['f','e','i']]) - sage: pos = {'a':(0,0), 'b': (0,1), 'c':(1,0), 'd':(1,1), 'e':(1,-1), 'f':(-1,1), 'g':(-1,-1),'h':(2,0), 'i':(0,2)} - sage: M.show(pos_method=1, pos_dict=pos,lims=[-3,3,-3,3]) + sage: M = matroids.named_matroids.TernaryDowling3() # optional - sage.libs.pari + sage: M.show(B=['a','b','c']) # optional - sage.libs.pari sage.plot + sage: M.show(B=['a','b','c'], lineorders=[['f','e','i']]) # optional - sage.libs.pari sage.plot + sage: pos = {'a':(0,0), 'b': (0,1), 'c':(1,0), 'd':(1,1), # optional - sage.libs.pari sage.plot + ....: 'e':(1,-1), 'f':(-1,1), 'g':(-1,-1),'h':(2,0), 'i':(0,2)} + sage: M.show(pos_method=1, pos_dict=pos, lims=[-3,3,-3,3]) # optional - sage.libs.pari sage.plot """ if self.rank() > 3: raise NotImplementedError @@ -7886,8 +7887,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: B = M.bergman_complex(); B + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: B = M.bergman_complex(); B # optional - sage.libs.pari Simplicial complex with 14 vertices and 21 facets .. SEEALSO:: @@ -7925,8 +7926,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: A = M.augmented_bergman_complex(); A + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: A = M.augmented_bergman_complex(); A # optional - sage.libs.pari Simplicial complex with 22 vertices and 91 facets sage: M = matroids.Uniform(2,3) @@ -8059,7 +8060,7 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.named_matroids.Pappus() - sage: N = matroids.named_matroids.Fano().direct_sum(M); N + sage: N = matroids.named_matroids.Fano().direct_sum(M); N # optional - sage.libs.pari Matroid of rank 6 on 16 elements as matroid sum of Binary matroid of rank 3 on 7 elements, type (3, 0) Matroid of rank 3 on 9 elements with circuit-closures @@ -8067,9 +8068,9 @@ cdef class Matroid(SageObject): {'b', 'd', 'i'}, {'b', 'f', 'g'}, {'c', 'd', 'h'}, {'c', 'e', 'g'}, {'d', 'e', 'f'}, {'g', 'h', 'i'}}, 3: {{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}}} - sage: len(N.independent_sets()) + sage: len(N.independent_sets()) # optional - sage.libs.pari 6897 - sage: len(N.bases()) + sage: len(N.bases()) # optional - sage.libs.pari 2100 """ from . import union_matroid diff --git a/src/sage/matroids/minor_matroid.py b/src/sage/matroids/minor_matroid.py index 907bb54356f..7c5cbbc55ba 100644 --- a/src/sage/matroids/minor_matroid.py +++ b/src/sage/matroids/minor_matroid.py @@ -13,23 +13,23 @@ EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M \ ['a', 'c' ] == M.delete(['a', 'c']) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M \ ['a', 'c' ] == M.delete(['a', 'c']) # optional - sage.libs.pari True - sage: M / 'a' == M.contract('a') + sage: M / 'a' == M.contract('a') # optional - sage.libs.pari True - sage: M / 'c' \ 'ab' == M.minor(contractions='c', deletions='ab') + sage: M / 'c' \ 'ab' == M.minor(contractions='c', deletions='ab') # optional - sage.libs.pari True If a contraction set is not independent (or a deletion set not coindependent), this is taken care of:: - sage: M = matroids.named_matroids.Fano() - sage: M.rank('abf') + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.rank('abf') # optional - sage.libs.pari 2 - sage: M / 'abf' == M / 'ab' \ 'f' + sage: M / 'abf' == M / 'ab' \ 'f' # optional - sage.libs.pari True - sage: M / 'abf' == M / 'af' \ 'b' + sage: M / 'abf' == M / 'af' \ 'b' # optional - sage.libs.pari True .. SEEALSO:: @@ -132,9 +132,9 @@ def __init__(self, matroid, contractions=None, deletions=None): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = MinorMatroid(matroids.named_matroids.Fano(), # indirect doctest + sage: M = MinorMatroid(matroids.named_matroids.Fano(), # indirect doctest # optional - sage.libs.pari ....: contractions=set(), deletions=set(['g'])) - sage: M.is_isomorphic(matroids.Wheel(3)) + sage: M.is_isomorphic(matroids.Wheel(3)) # optional - sage.libs.pari True """ if not isinstance(matroid, Matroid): @@ -423,15 +423,15 @@ def __eq__(self, other): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.Fano() - sage: M1 = MinorMatroid(M, set('ab'), set('f')) - sage: M2 = MinorMatroid(M, set('af'), set('b')) - sage: M3 = MinorMatroid(M, set('a'), set('f'))._minor(set('b'), set()) - sage: M1 == M2 # indirect doctest + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M1 = MinorMatroid(M, set('ab'), set('f')) # optional - sage.libs.pari + sage: M2 = MinorMatroid(M, set('af'), set('b')) # optional - sage.libs.pari + sage: M3 = MinorMatroid(M, set('a'), set('f'))._minor(set('b'), set()) # optional - sage.libs.pari + sage: M1 == M2 # indirect doctest # optional - sage.libs.pari False - sage: M1.equals(M2) + sage: M1.equals(M2) # optional - sage.libs.pari True - sage: M1 == M3 + sage: M1 == M3 # optional - sage.libs.pari True """ if not isinstance(other, MinorMatroid): @@ -455,15 +455,15 @@ def __ne__(self, other): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.Fano() - sage: M1 = MinorMatroid(M, set('ab'), set('f')) - sage: M2 = MinorMatroid(M, set('af'), set('b')) - sage: M3 = MinorMatroid(M, set('a'), set('f'))._minor(set('b'), set()) - sage: M1 != M2 # indirect doctest + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M1 = MinorMatroid(M, set('ab'), set('f')) # optional - sage.libs.pari + sage: M2 = MinorMatroid(M, set('af'), set('b')) # optional - sage.libs.pari + sage: M3 = MinorMatroid(M, set('a'), set('f'))._minor(set('b'), set()) # optional - sage.libs.pari + sage: M1 != M2 # indirect doctest # optional - sage.libs.pari True - sage: M1.equals(M2) + sage: M1.equals(M2) # optional - sage.libs.pari True - sage: M1 != M3 + sage: M1 != M3 # optional - sage.libs.pari False """ return not self == other diff --git a/src/sage/matroids/set_system.pyx b/src/sage/matroids/set_system.pyx index d183f6ed5d1..9b68cfe342d 100644 --- a/src/sage/matroids/set_system.pyx +++ b/src/sage/matroids/set_system.pyx @@ -38,8 +38,8 @@ cdef class SetSystem: contents. One is most likely to encounter these as output from some Matroid methods:: - sage: M = matroids.named_matroids.Fano() - sage: M.circuits() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.circuits() # optional - sage.libs.pari Iterator over a system of subsets To access the sets in this structure, simply iterate over them. The @@ -729,11 +729,11 @@ cdef class SetSystem: Check that :trac:`15189` is fixed:: - sage: M = Matroid(ring=GF(5), reduced_matrix=[[1,0,3],[0,1,1],[1,1,0]]) - sage: N = Matroid(ring=GF(5), reduced_matrix=[[1,0,1],[0,1,1],[1,1,0]]) - sage: M.is_field_isomorphic(N) + sage: M = Matroid(ring=GF(5), reduced_matrix=[[1,0,3],[0,1,1],[1,1,0]]) # optional - sage.libs.pari + sage: N = Matroid(ring=GF(5), reduced_matrix=[[1,0,1],[0,1,1],[1,1,0]]) # optional - sage.libs.pari + sage: M.is_field_isomorphic(N) # optional - sage.libs.pari False - sage: any(M.is_field_isomorphism(N, p) for p in Permutations(range(6))) + sage: any(M.is_field_isomorphism(N, p) for p in Permutations(range(6))) # optional - sage.combinat sage.libs.pari False """ cdef long v diff --git a/src/sage/matroids/unpickling.pyx b/src/sage/matroids/unpickling.pyx index b37ae49a37f..8916067025c 100644 --- a/src/sage/matroids/unpickling.pyx +++ b/src/sage/matroids/unpickling.pyx @@ -211,11 +211,11 @@ def unpickle_binary_matrix(version, data): EXAMPLES:: sage: from sage.matroids.lean_matrix import * - sage: A = BinaryMatrix(2, 5) - sage: A == loads(dumps(A)) # indirect doctest + sage: A = BinaryMatrix(2, 5) # optional - sage.libs.pari + sage: A == loads(dumps(A)) # indirect doctest # optional - sage.libs.pari True - sage: C = BinaryMatrix(2, 2, Matrix(GF(2), [[1, 1], [0, 1]])) - sage: C == loads(dumps(C)) + sage: C = BinaryMatrix(2, 2, Matrix(GF(2), [[1, 1], [0, 1]])) # optional - sage.libs.pari + sage: C == loads(dumps(C)) # optional - sage.libs.pari True """ cdef BinaryMatrix A @@ -240,11 +240,11 @@ def unpickle_ternary_matrix(version, data): EXAMPLES:: sage: from sage.matroids.lean_matrix import * - sage: A = TernaryMatrix(2, 5) - sage: A == loads(dumps(A)) # indirect doctest + sage: A = TernaryMatrix(2, 5) # optional - sage.libs.pari + sage: A == loads(dumps(A)) # indirect doctest # optional - sage.libs.pari True - sage: C = TernaryMatrix(2, 2, Matrix(GF(3), [[1, 1], [0, 1]])) - sage: C == loads(dumps(C)) + sage: C = TernaryMatrix(2, 2, Matrix(GF(3), [[1, 1], [0, 1]])) # optional - sage.libs.pari + sage: C == loads(dumps(C)) # optional - sage.libs.pari True """ cdef TernaryMatrix A @@ -270,11 +270,11 @@ def unpickle_quaternary_matrix(version, data): EXAMPLES:: sage: from sage.matroids.lean_matrix import * - sage: A = QuaternaryMatrix(2, 5, ring=GF(4, 'x')) - sage: A == loads(dumps(A)) # indirect doctest + sage: A = QuaternaryMatrix(2, 5, ring=GF(4, 'x')) # optional - sage.libs.pari + sage: A == loads(dumps(A)) # indirect doctest # optional - sage.libs.pari True - sage: C = QuaternaryMatrix(2, 2, Matrix(GF(4, 'x'), [[1, 1], [0, 1]])) - sage: C == loads(dumps(C)) + sage: C = QuaternaryMatrix(2, 2, Matrix(GF(4, 'x'), [[1, 1], [0, 1]])) # optional - sage.libs.pari + sage: C == loads(dumps(C)) # optional - sage.libs.pari True """ cdef QuaternaryMatrix A @@ -388,12 +388,12 @@ def unpickle_linear_matroid(version, data): EXAMPLES:: - sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], + sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], # optional - sage.libs.pari ....: [0, 1, 1, 1, 3]])) - sage: M == loads(dumps(M)) # indirect doctest + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.libs.pari True - sage: M.rename("U35") - sage: loads(dumps(M)) + sage: M.rename("U35") # optional - sage.libs.pari + sage: loads(dumps(M)) # optional - sage.libs.pari U35 """ if version != 0: @@ -434,12 +434,12 @@ def unpickle_binary_matroid(version, data): EXAMPLES:: - sage: M = Matroid(Matrix(GF(2), [[1, 0, 0, 1], [0, 1, 0, 1], + sage: M = Matroid(Matrix(GF(2), [[1, 0, 0, 1], [0, 1, 0, 1], # optional - sage.libs.pari ....: [0, 0, 1, 1]])) - sage: M == loads(dumps(M)) # indirect doctest + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.libs.pari True - sage: M.rename("U34") - sage: loads(dumps(M)) + sage: M.rename("U34") # optional - sage.libs.pari + sage: loads(dumps(M)) # optional - sage.libs.pari U34 """ if version != 0: @@ -481,12 +481,12 @@ def unpickle_ternary_matroid(version, data): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = TernaryMatroid(Matrix(GF(3), [[1, 0, 0, 1], [0, 1, 0, 1], + sage: M = TernaryMatroid(Matrix(GF(3), [[1, 0, 0, 1], [0, 1, 0, 1], # optional - sage.libs.pari ....: [0, 0, 1, 1]])) - sage: M == loads(dumps(M)) # indirect doctest + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.libs.pari True - sage: M.rename("U34") - sage: loads(dumps(M)) + sage: M.rename("U34") # optional - sage.libs.pari + sage: loads(dumps(M)) # optional - sage.libs.pari U34 """ if version != 0: @@ -528,16 +528,16 @@ def unpickle_quaternary_matroid(version, data): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = QuaternaryMatroid(Matrix(GF(3), [[1, 0, 0, 1], [0, 1, 0, 1], + sage: M = QuaternaryMatroid(Matrix(GF(3), [[1, 0, 0, 1], [0, 1, 0, 1], # optional - sage.libs.pari ....: [0, 0, 1, 1]])) - sage: M == loads(dumps(M)) # indirect doctest + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.libs.pari True - sage: M.rename("U34") - sage: loads(dumps(M)) + sage: M.rename("U34") # optional - sage.libs.pari + sage: loads(dumps(M)) # optional - sage.libs.pari U34 - sage: M = QuaternaryMatroid(Matrix(GF(4, 'x'), [[1, 0, 1], + sage: M = QuaternaryMatroid(Matrix(GF(4, 'x'), [[1, 0, 1], # optional - sage.libs.pari ....: [1, 0, 1]])) - sage: loads(dumps(M)).representation() + sage: loads(dumps(M)).representation() # optional - sage.libs.pari [1 0 1] [1 0 1] """ diff --git a/src/sage/matroids/utilities.py b/src/sage/matroids/utilities.py index eb2999ea07b..a9764c86891 100644 --- a/src/sage/matroids/utilities.py +++ b/src/sage/matroids/utilities.py @@ -74,10 +74,10 @@ def setprint(X): Note that for iterables, the effect can be undesirable:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano().delete('efg') - sage: M.bases() + sage: M = matroids.named_matroids.Fano().delete('efg') # optional - sage.libs.pari + sage: M.bases() # optional - sage.libs.pari Iterator over a system of subsets - sage: setprint(M.bases()) + sage: setprint(M.bases()) # optional - sage.libs.pari [{'a', 'b', 'c'}, {'a', 'b', 'd'}, {'a', 'c', 'd'}] An exception was made for subclasses of SageObject:: @@ -215,20 +215,20 @@ def sanitize_contractions_deletions(matroid, contractions, deletions): sage: from sage.matroids.utilities import setprint sage: from sage.matroids.utilities import sanitize_contractions_deletions - sage: M = matroids.named_matroids.Fano() - sage: setprint(sanitize_contractions_deletions(M, 'abc', 'defg')) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: setprint(sanitize_contractions_deletions(M, 'abc', 'defg')) # optional - sage.libs.pari [{'a', 'b', 'c'}, {'d', 'e', 'f', 'g'}] - sage: setprint(sanitize_contractions_deletions(M, 'defg', 'abc')) + sage: setprint(sanitize_contractions_deletions(M, 'defg', 'abc')) # optional - sage.libs.pari [{'a', 'b', 'c', 'f'}, {'d', 'e', 'g'}] - sage: setprint(sanitize_contractions_deletions(M, [1, 2, 3], 'efg')) + sage: setprint(sanitize_contractions_deletions(M, [1, 2, 3], 'efg')) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: [1, 2, 3] is not a subset of the groundset - sage: setprint(sanitize_contractions_deletions(M, 'efg', [1, 2, 3])) + sage: setprint(sanitize_contractions_deletions(M, 'efg', [1, 2, 3])) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: [1, 2, 3] is not a subset of the groundset - sage: setprint(sanitize_contractions_deletions(M, 'ade', 'efg')) + sage: setprint(sanitize_contractions_deletions(M, 'ade', 'efg')) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: contraction and deletion sets are not disjoint. @@ -532,25 +532,25 @@ def lift_cross_ratios(A, lift_map=None): EXAMPLES:: sage: from sage.matroids.advanced import lift_cross_ratios, lift_map, LinearMatroid - sage: R = GF(7) - sage: to_sixth_root_of_unity = lift_map('sru') - sage: A = Matrix(R, [[1, 0, 6, 1, 2],[6, 1, 0, 0, 1],[0, 6, 3, 6, 0]]) - sage: A + sage: R = GF(7) # optional - sage.libs.pari + sage: to_sixth_root_of_unity = lift_map('sru') # optional - sage.rings.number_field + sage: A = Matrix(R, [[1, 0, 6, 1, 2],[6, 1, 0, 0, 1],[0, 6, 3, 6, 0]]) # optional - sage.libs.pari + sage: A # optional - sage.libs.pari [1 0 6 1 2] [6 1 0 0 1] [0 6 3 6 0] - sage: Z = lift_cross_ratios(A, to_sixth_root_of_unity) - sage: Z + sage: Z = lift_cross_ratios(A, to_sixth_root_of_unity) # optional - sage.libs.pari sage.rings.number_field + sage: Z # optional - sage.libs.pari sage.rings.number_field [ 1 0 1 1 1] [ 1 1 0 0 z] [ 0 -1 z 1 0] - sage: M = LinearMatroid(reduced_matrix = A) - sage: sorted(M.cross_ratios()) + sage: M = LinearMatroid(reduced_matrix=A) # optional - sage.libs.pari + sage: sorted(M.cross_ratios()) # optional - sage.libs.pari [3, 5] - sage: N = LinearMatroid(reduced_matrix = Z) - sage: sorted(N.cross_ratios()) + sage: N = LinearMatroid(reduced_matrix=Z) # optional - sage.libs.pari sage.rings.number_field + sage: sorted(N.cross_ratios()) # optional - sage.libs.pari sage.rings.number_field [-z + 1, z] - sage: M.is_isomorphism(N, {e:e for e in M.groundset()}) + sage: M.is_isomorphism(N, {e:e for e in M.groundset()}) # optional - sage.libs.pari sage.rings.number_field True """ @@ -690,8 +690,8 @@ def lift_map(target): EXAMPLES:: sage: from sage.matroids.utilities import lift_map - sage: lm = lift_map('gm') - sage: for x in lm: + sage: lm = lift_map('gm') # optional - sage.libs.pari sage.rings.number_field + sage: for x in lm: # optional - sage.libs.pari sage.rings.number_field ....: if (x == 1) is not (lm[x] == 1): ....: print('not a proper lift map') ....: for y in lm: diff --git a/src/sage/misc/all.py b/src/sage/misc/all.py index 8fea19524eb..b58c90e5c22 100644 --- a/src/sage/misc/all.py +++ b/src/sage/misc/all.py @@ -7,7 +7,6 @@ from .misc import (BackslashOperator, cputime, - union, uniq, powerset, subsets, exists, forall, is_iterator, random_sublist, walltime, pad_zeros, diff --git a/src/sage/misc/binary_tree.pyx b/src/sage/misc/binary_tree.pyx index 8827cac9ef2..2dcbe15cb99 100644 --- a/src/sage/misc/binary_tree.pyx +++ b/src/sage/misc/binary_tree.pyx @@ -286,9 +286,9 @@ cdef class BinaryTree: sage: from sage.misc.binary_tree import BinaryTree sage: t = BinaryTree() - sage: t.insert(0,Matrix([[0,0],[1,1]])) - sage: t.insert(0,1) - sage: t.get(0) + sage: t.insert(0, Matrix([[0,0], [1,1]])) # optional - sage.modules + sage: t.insert(0, 1) + sage: t.get(0) # optional - sage.modules [0 0] [1 1] """ @@ -307,7 +307,7 @@ cdef class BinaryTree: sage: t = BinaryTree() sage: t.contains(1) False - sage: t.insert(1,1) + sage: t.insert(1, 1) sage: t.contains(1) True """ diff --git a/src/sage/misc/c3_controlled.pyx b/src/sage/misc/c3_controlled.pyx index ebadb070d1d..4e0a1cde628 100644 --- a/src/sage/misc/c3_controlled.pyx +++ b/src/sage/misc/c3_controlled.pyx @@ -196,21 +196,23 @@ key. We consider the smallest poset describing a class hierarchy admitting no MRO whatsoever:: - sage: P = Poset({10: [9,8,7], 9:[6,1], 8:[5,2], 7:[4,3], 6: [3,2], 5:[3,1], 4: [2,1] }, linear_extension=True, facade=True) + sage: P = Poset({10: [9,8,7], 9: [6,1], 8: [5,2], 7: [4,3], # optional - sage.combinat sage.graphs + ....: 6: [3,2], 5: [3,1], 4: [2,1]}, + ....: linear_extension=True, facade=True) And build a :class:`HierarchyElement` from it:: sage: from sage.misc.c3_controlled import HierarchyElement - sage: x = HierarchyElement(10, P) + sage: x = HierarchyElement(10, P) # optional - sage.combinat sage.graphs Here are its bases:: - sage: HierarchyElement(10, P)._bases + sage: HierarchyElement(10, P)._bases # optional - sage.combinat sage.graphs [9, 8, 7] Using the standard ``C3`` algorithm fails:: - sage: x.mro_standard + sage: x.mro_standard # optional - sage.combinat sage.graphs Traceback (most recent call last): ... ValueError: Cannot merge the items 3, 3, 2. @@ -219,18 +221,19 @@ We also get a failure when we relabel `P` according to another linear extension. For easy relabelling, we first need to set an appropriate default linear extension for `P`:: - sage: linear_extension = list(reversed(IntegerRange(1,11))) - sage: P = P.with_linear_extension(linear_extension) - sage: list(P) + sage: linear_extension = list(reversed(IntegerRange(1, 11))) # optional - sage.combinat sage.graphs + sage: P = P.with_linear_extension(linear_extension) # optional - sage.combinat sage.graphs + sage: list(P) # optional - sage.combinat sage.graphs [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] Now we play with a specific linear extension of `P`:: - sage: Q = P.linear_extension([10, 9, 8, 7, 6, 5, 4, 1, 2, 3]).to_poset() - sage: Q.cover_relations() - [[10, 9], [10, 8], [10, 7], [9, 6], [9, 3], [8, 5], [8, 2], [7, 4], [7, 1], [6, 2], [6, 1], [5, 3], [5, 1], [4, 3], [4, 2]] - sage: x = HierarchyElement(10, Q) - sage: x.mro_standard + sage: Q = P.linear_extension([10, 9, 8, 7, 6, 5, 4, 1, 2, 3]).to_poset() # optional - sage.combinat sage.graphs + sage: Q.cover_relations() # optional - sage.combinat sage.graphs + [[10, 9], [10, 8], [10, 7], [9, 6], [9, 3], [8, 5], [8, 2], [7, 4], + [7, 1], [6, 2], [6, 1], [5, 3], [5, 1], [4, 3], [4, 2]] + sage: x = HierarchyElement(10, Q) # optional - sage.combinat sage.graphs + sage: x.mro_standard # optional - sage.combinat sage.graphs Traceback (most recent call last): ... ValueError: Cannot merge the items 2, 3, 3. @@ -238,43 +241,43 @@ Now we play with a specific linear extension of `P`:: On the other hand, both the instrumented ``C3`` algorithm, and the controlled ``C3`` algorithm give the desired MRO:: - sage: x.mro + sage: x.mro # optional - sage.combinat sage.graphs [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] - sage: x.mro_controlled + sage: x.mro_controlled # optional - sage.combinat sage.graphs [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] The above checks, and more, can be run with:: - sage: x._test_mro() + sage: x._test_mro() # optional - sage.combinat sage.graphs In practice, the control was achieved by adding the following bases:: - sage: x._bases + sage: x._bases # optional - sage.combinat sage.graphs [9, 8, 7] - sage: x._bases_controlled + sage: x._bases_controlled # optional - sage.combinat sage.graphs [9, 8, 7, 6, 5] Altogether, four bases were added for control:: - sage: sum(len(HierarchyElement(q, Q)._bases) for q in Q) + sage: sum(len(HierarchyElement(q, Q)._bases) for q in Q) # optional - sage.combinat sage.graphs 15 - sage: sum(len(HierarchyElement(q, Q)._bases_controlled) for q in Q) + sage: sum(len(HierarchyElement(q, Q)._bases_controlled) for q in Q) # optional - sage.combinat sage.graphs 19 This information can also be recovered with:: - sage: x.all_bases_len() + sage: x.all_bases_len() # optional - sage.combinat sage.graphs 15 - sage: x.all_bases_controlled_len() + sage: x.all_bases_controlled_len() # optional - sage.combinat sage.graphs 19 We now check that the ``C3`` algorithm fails for all linear extensions `l` of this poset, whereas both the instrumented and controlled ``C3`` algorithms succeed; along the way, we collect some statistics:: - sage: L = P.linear_extensions() - sage: stats = [] - sage: for l in L: + sage: L = P.linear_extensions() # optional - sage.combinat sage.graphs + sage: stats = [] # optional - sage.combinat sage.graphs + sage: for l in L: # optional - sage.combinat sage.graphs ....: x = HierarchyElement(10, l.to_poset()) ....: try: # Check that x.mro_standard always fails with a ValueError ....: x.mro_standard @@ -291,7 +294,7 @@ Depending on the linear extension `l` it was necessary to add between one and five bases for control; for example, `216` linear extensions required the addition of four bases:: - sage: sorted(Word(stats).evaluation_sparse()) + sage: sorted(Word(stats).evaluation_sparse()) # optional - sage.combinat sage.graphs [(1, 36), (2, 108), (3, 180), (4, 216), (5, 180)] We now consider a hierarchy of categories:: @@ -336,7 +339,7 @@ list below does not change radically, it's fine to just update this doctest:: sage: from sage.categories.category import category_sample - sage: sorted([C for C in category_sample() + sage: sorted([C for C in category_sample() # optional - sage.combinat sage.graphs sage.modules sage.rings.number_field ....: if len(C._super_categories_for_classes) != len(C.super_categories())], ....: key=str) [Category of affine weyl groups, @@ -545,9 +548,9 @@ cdef class CmpKeyNamed: EXAMPLES:: - sage: Algebras(GF(3))._cmp_key == Algebras(GF(5))._cmp_key # indirect doctest + sage: Algebras(GF(3))._cmp_key == Algebras(GF(5))._cmp_key # indirect doctest # optional - sage.libs.pari True - sage: Algebras(ZZ)._cmp_key != Algebras(GF(5))._cmp_key + sage: Algebras(ZZ)._cmp_key != Algebras(GF(5))._cmp_key # optional - sage.libs.pari True """ @@ -555,9 +558,9 @@ cdef class CmpKeyNamed: """ EXAMPLES:: - sage: Algebras(GF(3))._cmp_key == Algebras(GF(5))._cmp_key # indirect doctest + sage: Algebras(GF(3))._cmp_key == Algebras(GF(5))._cmp_key # indirect doctest # optional - sage.libs.pari True - sage: Algebras(ZZ)._cmp_key != Algebras(GF(5))._cmp_key + sage: Algebras(ZZ)._cmp_key != Algebras(GF(5))._cmp_key # optional - sage.libs.pari True """ @@ -951,6 +954,7 @@ cpdef tuple C3_sorted_merge(list lists, key=identity): #assert C3_merge(lists[:-1]+[suggestion_list]) == out return (out, suggestion_list) + class HierarchyElement(object, metaclass=ClasscallMetaclass): """ A class for elements in a hierarchy. @@ -988,7 +992,7 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): :class:`HopfAlgebrasWithBasis`:: sage: from sage.misc.c3_controlled import HierarchyElement - sage: G = DiGraph({ + sage: G = DiGraph({ # optional - sage.graphs ....: 44 : [43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0], ....: 43 : [42, 41, 40, 36, 35, 39, 38, 37, 33, 32, 31, 30, 29, 28, 27, 26, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0], ....: 42 : [36, 35, 37, 30, 29, 28, 27, 26, 15, 14, 12, 11, 9, 8, 5, 3, 2, 1, 0], @@ -1036,12 +1040,12 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): ....: 0 : [], ....: }) - sage: x = HierarchyElement(44, G) - sage: x.mro + sage: x = HierarchyElement(44, G) # optional - sage.combinat sage.graphs + sage: x.mro # optional - sage.combinat sage.graphs [44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - sage: x.cls + sage: x.cls # optional - sage.combinat sage.graphs - sage: x.cls.mro() + sage: x.cls.mro() # optional - sage.combinat sage.graphs [, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , <... 'object'>] """ @staticmethod @@ -1050,13 +1054,13 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): EXAMPLES:: sage: from sage.misc.c3_controlled import HierarchyElement - sage: P = Poset((divisors(30), lambda x,y: y.divides(x)), facade=True) - sage: x = HierarchyElement(10, P) - sage: x + sage: P = Poset((divisors(30), lambda x, y: y.divides(x)), facade=True) # optional - sage.combinat sage.graphs + sage: x = HierarchyElement(10, P) # optional - sage.combinat sage.graphs + sage: x # optional - sage.combinat sage.graphs 10 - sage: x.bases + sage: x.bases # optional - sage.combinat sage.graphs [5, 2] - sage: x.mro + sage: x.mro # optional - sage.combinat sage.graphs [10, 5, 2, 1] """ from sage.categories.sets_cat import Sets @@ -1082,25 +1086,25 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): EXAMPLES:: sage: from sage.misc.c3_controlled import HierarchyElement - sage: P = Poset((divisors(30), lambda x,y: y.divides(x)), facade=True) - sage: x = HierarchyElement(10, P) - sage: x + sage: P = Poset((divisors(30), lambda x, y: y.divides(x)), facade=True) # optional - sage.combinat sage.graphs + sage: x = HierarchyElement(10, P) # optional - sage.combinat sage.graphs + sage: x # optional - sage.combinat sage.graphs 10 - sage: x.value + sage: x.value # optional - sage.combinat sage.graphs 10 - sage: x._bases + sage: x._bases # optional - sage.combinat sage.graphs [5, 2] - sage: x._key + sage: x._key # optional - sage.combinat sage.graphs - sage: x._key(10) + sage: x._key(10) # optional - sage.combinat sage.graphs 10 The ``_from_value`` attribute is a function that can be used to reconstruct an element of the hierarchy from its value:: - sage: x._from_value + sage: x._from_value # optional - sage.combinat sage.graphs Cached version of .f at ...> - sage: x._from_value(x.value) is x + sage: x._from_value(x.value) is x # optional - sage.combinat sage.graphs True """ self.value = value @@ -1115,9 +1119,9 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): EXAMPLES:: sage: from sage.misc.c3_controlled import HierarchyElement - sage: P = Poset((divisors(30), lambda x,y: y.divides(x)), facade=True) - sage: x = HierarchyElement(10, P) - sage: x + sage: P = Poset((divisors(30), lambda x, y: y.divides(x)), facade=True) # optional - sage.combinat sage.graphs + sage: x = HierarchyElement(10, P) # optional - sage.combinat sage.graphs + sage: x # optional - sage.combinat sage.graphs 10 """ return repr(self.value) @@ -1134,15 +1138,15 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): EXAMPLES:: sage: from sage.misc.c3_controlled import HierarchyElement - sage: P = Poset((divisors(30), lambda x,y: y.divides(x)), facade=True) - sage: x = HierarchyElement(10, P) - sage: x.bases + sage: P = Poset((divisors(30), lambda x, y: y.divides(x)), facade=True) # optional - sage.combinat sage.graphs + sage: x = HierarchyElement(10, P) # optional - sage.combinat sage.graphs + sage: x.bases # optional - sage.combinat sage.graphs [5, 2] - sage: type(x.bases[0]) + sage: type(x.bases[0]) # optional - sage.combinat sage.graphs - sage: x.mro + sage: x.mro # optional - sage.combinat sage.graphs [10, 5, 2, 1] - sage: x._bases_controlled + sage: x._bases_controlled # optional - sage.combinat sage.graphs [5, 2] """ return self._bases @@ -1155,23 +1159,23 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): EXAMPLES:: sage: from sage.misc.c3_controlled import HierarchyElement, C3_sorted_merge, identity - sage: P = Poset({7: [5,6], 5:[1,2], 6: [3,4]}, facade = True) - sage: x = HierarchyElement(5, P) - sage: x.mro + sage: P = Poset({7: [5, 6], 5: [1, 2], 6: [3, 4]}, facade=True) # optional - sage.combinat sage.graphs + sage: x = HierarchyElement(5, P) # optional - sage.combinat sage.graphs + sage: x.mro # optional - sage.combinat sage.graphs [5, 2, 1] - sage: x = HierarchyElement(6, P) - sage: x.mro + sage: x = HierarchyElement(6, P) # optional - sage.combinat sage.graphs + sage: x.mro # optional - sage.combinat sage.graphs [6, 4, 3] - sage: x = HierarchyElement(7, P) - sage: x.mro + sage: x = HierarchyElement(7, P) # optional - sage.combinat sage.graphs + sage: x.mro # optional - sage.combinat sage.graphs [7, 6, 5, 4, 3, 2, 1] - sage: C3_sorted_merge([[6, 4, 3], [5, 2, 1], [6, 5]], identity) + sage: C3_sorted_merge([[6, 4, 3], [5, 2, 1], [6, 5]], identity) # optional - sage.combinat sage.graphs ([6, 5, 4, 3, 2, 1], [6, 5, 4]) TESTS:: - sage: assert all(isinstance(v, Integer) for v in x.mro) + sage: assert all(isinstance(v, Integer) for v in x.mro) # optional - sage.combinat sage.graphs """ bases = self._bases result, suggestion = C3_sorted_merge([base.mro for base in bases]+[[base.value for base in bases]], key=self._key) @@ -1191,11 +1195,11 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): EXAMPLES:: sage: from sage.misc.c3_controlled import HierarchyElement - sage: P = Poset({7: [5,6], 5:[1,2], 6: [3,4]}, facade = True) - sage: x = HierarchyElement(7, P) - sage: x._bases + sage: P = Poset({7: [5, 6], 5: [1, 2], 6: [3, 4]}, facade=True) # optional - sage.combinat sage.graphs + sage: x = HierarchyElement(7, P) # optional - sage.combinat sage.graphs + sage: x._bases # optional - sage.combinat sage.graphs [6, 5] - sage: x._bases_controlled + sage: x._bases_controlled # optional - sage.combinat sage.graphs [6, 5, 4] """ self.mro @@ -1209,22 +1213,22 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): EXAMPLES:: sage: from sage.misc.c3_controlled import HierarchyElement, C3_merge - sage: P = Poset({7: [5,6], 5:[1,2], 6: [3,4]}, facade=True) - sage: x = HierarchyElement(5, P) - sage: x.mro_standard + sage: P = Poset({7: [5, 6], 5: [1, 2], 6: [3, 4]}, facade=True) # optional - sage.combinat sage.graphs + sage: x = HierarchyElement(5, P) # optional - sage.combinat sage.graphs + sage: x.mro_standard # optional - sage.combinat sage.graphs [5, 2, 1] - sage: x = HierarchyElement(6, P) - sage: x.mro_standard + sage: x = HierarchyElement(6, P) # optional - sage.combinat sage.graphs + sage: x.mro_standard # optional - sage.combinat sage.graphs [6, 4, 3] - sage: x = HierarchyElement(7, P) - sage: x.mro_standard + sage: x = HierarchyElement(7, P) # optional - sage.combinat sage.graphs + sage: x.mro_standard # optional - sage.combinat sage.graphs [7, 6, 4, 3, 5, 2, 1] - sage: C3_merge([[6, 4, 3], [5, 2, 1], [6, 5]]) + sage: C3_merge([[6, 4, 3], [5, 2, 1], [6, 5]]) # optional - sage.combinat sage.graphs [6, 4, 3, 5, 2, 1] TESTS:: - sage: assert all(isinstance(v, Integer) for v in x.mro_standard) + sage: assert all(isinstance(v, Integer) for v in x.mro_standard) # optional - sage.combinat sage.graphs """ bases = self._bases return [self.value] + C3_merge([base.mro_standard for base in bases]+[[base.value for base in bases]]) @@ -1238,19 +1242,19 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): EXAMPLES:: sage: from sage.misc.c3_controlled import HierarchyElement, C3_merge - sage: P = Poset({7: [5,6], 5:[1,2], 6: [3,4]}, facade=True) - sage: x = HierarchyElement(5, P) - sage: x.mro_controlled + sage: P = Poset({7: [5, 6], 5: [1, 2], 6: [3, 4]}, facade=True) # optional - sage.combinat sage.graphs + sage: x = HierarchyElement(5, P) # optional - sage.combinat sage.graphs + sage: x.mro_controlled # optional - sage.combinat sage.graphs [5, 2, 1] - sage: x = HierarchyElement(6, P) - sage: x.mro_controlled + sage: x = HierarchyElement(6, P) # optional - sage.combinat sage.graphs + sage: x.mro_controlled # optional - sage.combinat sage.graphs [6, 4, 3] - sage: x = HierarchyElement(7, P) - sage: x.mro_controlled + sage: x = HierarchyElement(7, P) # optional - sage.combinat sage.graphs + sage: x.mro_controlled # optional - sage.combinat sage.graphs [7, 6, 5, 4, 3, 2, 1] - sage: x._bases + sage: x._bases # optional - sage.combinat sage.graphs [6, 5] - sage: x._bases_controlled + sage: x._bases_controlled # optional - sage.combinat sage.graphs [6, 5, 4] sage: C3_merge([[6, 4, 3], [5, 2, 1], [6, 5]]) [6, 4, 3, 5, 2, 1] @@ -1259,14 +1263,14 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): TESTS:: - sage: assert all(isinstance(v, Integer) for v in x.mro_controlled) + sage: assert all(isinstance(v, Integer) for v in x.mro_controlled) # optional - sage.combinat sage.graphs """ return [self.value] + C3_merge([base.mro_controlled for base in self._bases]+[self._bases_controlled]) @cached_method def _test_mro(self): r""" - Runs consistency tests. + Run consistency tests. This checks in particular that the instrumented ``C3`` and controlled ``C3`` algorithms give, as desired, the @@ -1281,9 +1285,9 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): EXAMPLES:: sage: from sage.misc.c3_controlled import HierarchyElement - sage: P = Poset({7: [5,6], 5:[1,2], 6: [3,4]}, facade=True) - sage: x = HierarchyElement(7, P) - sage: x._test_mro() + sage: P = Poset({7: [5, 6], 5: [1, 2], 6: [3, 4]}, facade=True) # optional - sage.combinat sage.graphs + sage: x = HierarchyElement(7, P) # optional - sage.combinat sage.graphs + sage: x._test_mro() # optional - sage.combinat sage.graphs """ for b in self._bases: b._test_mro() @@ -1305,17 +1309,17 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): EXAMPLES:: - sage: from sage.misc.c3_controlled import HierarchyElement - sage: P = Poset((divisors(30), lambda x,y: y.divides(x)), facade=True) - sage: x = HierarchyElement(1, P) - sage: x.cls + sage: from sage.misc.c3_controlled import HierarchyElement # optional - sage.combinat sage.graphs + sage: P = Poset((divisors(30), lambda x, y: y.divides(x)), facade=True) # optional - sage.combinat sage.graphs + sage: x = HierarchyElement(1, P) # optional - sage.combinat sage.graphs + sage: x.cls # optional - sage.combinat sage.graphs - sage: x.cls.mro() + sage: x.cls.mro() # optional - sage.combinat sage.graphs [, <... 'object'>] - sage: x = HierarchyElement(30, P) - sage: x.cls + sage: x = HierarchyElement(30, P) # optional - sage.combinat sage.graphs + sage: x.cls # optional - sage.combinat sage.graphs - sage: x.cls.mro() + sage: x.cls.mro() # optional - sage.combinat sage.graphs [, , , , , , , , <... 'object'>] """ super_classes = tuple(self._from_value(base).cls for base in self._bases_controlled) @@ -1333,12 +1337,12 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): EXAMPLES:: sage: from sage.misc.c3_controlled import HierarchyElement - sage: P = Poset((divisors(30), lambda x,y: y.divides(x)), facade=True) - sage: HierarchyElement(1, P).all_bases() + sage: P = Poset((divisors(30), lambda x, y: y.divides(x)), facade=True) # optional - sage.combinat sage.graphs + sage: HierarchyElement(1, P).all_bases() # optional - sage.combinat sage.graphs {1} - sage: HierarchyElement(10, P).all_bases() # random output + sage: HierarchyElement(10, P).all_bases() # random output # optional - sage.combinat sage.graphs {10, 5, 2, 1} - sage: sorted([x.value for x in HierarchyElement(10, P).all_bases()]) + sage: sorted([x.value for x in HierarchyElement(10, P).all_bases()]) # optional - sage.combinat sage.graphs [1, 2, 5, 10] """ return {self} | { x for base in self._bases for x in base.all_bases() } @@ -1350,8 +1354,8 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): EXAMPLES:: sage: from sage.misc.c3_controlled import HierarchyElement - sage: P = Poset((divisors(30), lambda x,y: y.divides(x)), facade=True) - sage: HierarchyElement(30, P).all_bases_len() + sage: P = Poset((divisors(30), lambda x, y: y.divides(x)), facade=True) # optional - sage.combinat sage.graphs + sage: HierarchyElement(30, P).all_bases_len() # optional - sage.combinat sage.graphs 12 """ return sum( len(x._bases) for x in self.all_bases()) @@ -1363,8 +1367,8 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): EXAMPLES:: sage: from sage.misc.c3_controlled import HierarchyElement - sage: P = Poset((divisors(30), lambda x,y: y.divides(x)), facade=True) - sage: HierarchyElement(30, P).all_bases_controlled_len() + sage: P = Poset((divisors(30), lambda x, y: y.divides(x)), facade=True) # optional - sage.combinat sage.graphs + sage: HierarchyElement(30, P).all_bases_controlled_len() # optional - sage.combinat sage.graphs 13 """ return sum( len(x._bases_controlled) for x in self.all_bases()) diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx index 9715726659b..d795ee4f43f 100644 --- a/src/sage/misc/cachefunc.pyx +++ b/src/sage/misc/cachefunc.pyx @@ -46,15 +46,15 @@ the name that the wrapped method or function should have, since otherwise the name of the original function would be used:: - sage: cython('''cpdef test_funct(x): return -x''') # optional - sage.misc.cython - sage: wrapped_funct = cached_function(test_funct, name='wrapped_funct') # optional - sage.misc.cython - sage: wrapped_funct # optional - sage.misc.cython + sage: cython('''cpdef test_funct(x): return -x''') # optional - sage.misc.cython + sage: wrapped_funct = cached_function(test_funct, name='wrapped_funct') # optional - sage.misc.cython + sage: wrapped_funct # optional - sage.misc.cython Cached version of - sage: wrapped_funct.__name__ # optional - sage.misc.cython + sage: wrapped_funct.__name__ # optional - sage.misc.cython 'wrapped_funct' - sage: wrapped_funct(5) # optional - sage.misc.cython + sage: wrapped_funct(5) # optional - sage.misc.cython -5 - sage: wrapped_funct(5) is wrapped_funct(5) # optional - sage.misc.cython + sage: wrapped_funct(5) is wrapped_funct(5) # optional - sage.misc.cython True We can proceed similarly for cached methods of Cython classes, @@ -77,21 +77,21 @@ approach is still needed for cpdef methods:: ....: ' "Some doc for direct method"', ....: ' return 2*x', ....: ' wrapped_method = cached_method(test_meth,name="wrapped_method")'] - sage: cython(os.linesep.join(cython_code)) # optional - sage.misc.cython - sage: O = MyClass() # optional - sage.misc.cython - sage: O.direct_method # optional - sage.misc.cython + sage: cython(os.linesep.join(cython_code)) # optional - sage.misc.cython + sage: O = MyClass() # optional - sage.misc.cython + sage: O.direct_method # optional - sage.misc.cython Cached version of - sage: O.wrapped_method # optional - sage.misc.cython + sage: O.wrapped_method # optional - sage.misc.cython Cached version of - sage: O.wrapped_method.__name__ # optional - sage.misc.cython + sage: O.wrapped_method.__name__ # optional - sage.misc.cython 'wrapped_method' - sage: O.wrapped_method(5) # optional - sage.misc.cython + sage: O.wrapped_method(5) # optional - sage.misc.cython -5 - sage: O.wrapped_method(5) is O.wrapped_method(5) # optional - sage.misc.cython + sage: O.wrapped_method(5) is O.wrapped_method(5) # optional - sage.misc.cython True - sage: O.direct_method(5) # optional - sage.misc.cython + sage: O.direct_method(5) # optional - sage.misc.cython 10 - sage: O.direct_method(5) is O.direct_method(5) # optional - sage.misc.cython + sage: O.direct_method(5) is O.direct_method(5) # optional - sage.misc.cython True In some cases, one would only want to keep the result in cache as long @@ -129,8 +129,8 @@ category (previously, the cache would have been broken):: ....: " @cached_method", ....: " def invert(self, x):", ....: " return -x"] - sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython - sage: C = MyCategory() # optional - sage.misc.cython + sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython + sage: C = MyCategory() # optional - sage.misc.cython In order to keep the memory footprint of elements small, it was decided to not support the same freedom of using cached methods @@ -181,88 +181,88 @@ hardly by used. ....: "from sage.structure.parent cimport Parent", ....: "cdef class MyParent(Parent):", ....: " Element = MyElement"] - sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython - sage: P = MyParent(category=C) # optional - sage.misc.cython - sage: ebroken = MyBrokenElement(P, 5) # optional - sage.misc.cython - sage: e = MyElement(P, 5) # optional - sage.misc.cython + sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython + sage: P = MyParent(category=C) # optional - sage.misc.cython + sage: ebroken = MyBrokenElement(P, 5) # optional - sage.misc.cython + sage: e = MyElement(P, 5) # optional - sage.misc.cython The cached methods inherited by the parent works:: - sage: P.one() # optional - sage.misc.cython + sage: P.one() # optional - sage.misc.cython <1> - sage: P.one() is P.one() # optional - sage.misc.cython + sage: P.one() is P.one() # optional - sage.misc.cython True - sage: P.invert(e) # optional - sage.misc.cython + sage: P.invert(e) # optional - sage.misc.cython <-5> - sage: P.invert(e) is P.invert(e) # optional - sage.misc.cython + sage: P.invert(e) is P.invert(e) # optional - sage.misc.cython True The cached methods inherited by ``MyElement`` works:: - sage: e.element_cache_test() # optional - sage.misc.cython + sage: e.element_cache_test() # optional - sage.misc.cython <-5> - sage: e.element_cache_test() is e.element_cache_test() # optional - sage.misc.cython + sage: e.element_cache_test() is e.element_cache_test() # optional - sage.misc.cython True - sage: e.element_via_parent_test() # optional - sage.misc.cython + sage: e.element_via_parent_test() # optional - sage.misc.cython <-5> - sage: e.element_via_parent_test() is e.element_via_parent_test() # optional - sage.misc.cython + sage: e.element_via_parent_test() is e.element_via_parent_test() # optional - sage.misc.cython True The other element class can only inherit a ``cached_in_parent_method``, since the cache is stored in the parent. In fact, equal elements share the cache, even if they are of different types:: - sage: e == ebroken # optional - sage.misc.cython + sage: e == ebroken # optional - sage.misc.cython True - sage: type(e) == type(ebroken) # optional - sage.misc.cython + sage: type(e) == type(ebroken) # optional - sage.misc.cython False - sage: ebroken.element_via_parent_test() is e.element_via_parent_test() # optional - sage.misc.cython + sage: ebroken.element_via_parent_test() is e.element_via_parent_test() # optional - sage.misc.cython True However, the cache of the other inherited method breaks, although the method as such works:: - sage: ebroken.element_cache_test() # optional - sage.misc.cython + sage: ebroken.element_cache_test() # optional - sage.misc.cython <-5> - sage: ebroken.element_cache_test() is ebroken.element_cache_test() # optional - sage.misc.cython + sage: ebroken.element_cache_test() is ebroken.element_cache_test() # optional - sage.misc.cython False The cache can be emptied:: - sage: a = test_pfunc(5) # optional - sage.misc.cython - sage: test_pfunc.clear_cache() # optional - sage.misc.cython - sage: a is test_pfunc(5) # optional - sage.misc.cython + sage: a = test_pfunc(5) # optional - sage.misc.cython + sage: test_pfunc.clear_cache() # optional - sage.misc.cython + sage: a is test_pfunc(5) # optional - sage.misc.cython False - sage: a = P.one() # optional - sage.misc.cython - sage: P.one.clear_cache() # optional - sage.misc.cython - sage: a is P.one() # optional - sage.misc.cython + sage: a = P.one() # optional - sage.misc.cython + sage: P.one.clear_cache() # optional - sage.misc.cython + sage: a is P.one() # optional - sage.misc.cython False Since ``e`` and ``ebroken`` share the cache, when we empty it for one element it is empty for the other as well:: - sage: b = ebroken.element_via_parent_test() # optional - sage.misc.cython - sage: e.element_via_parent_test.clear_cache() # optional - sage.misc.cython - sage: b is ebroken.element_via_parent_test() # optional - sage.misc.cython + sage: b = ebroken.element_via_parent_test() # optional - sage.misc.cython + sage: e.element_via_parent_test.clear_cache() # optional - sage.misc.cython + sage: b is ebroken.element_via_parent_test() # optional - sage.misc.cython False Introspection works:: sage: from sage.misc.edit_module import file_and_line sage: from sage.misc.sageinspect import sage_getdoc, sage_getfile, sage_getsource - sage: print(sage_getdoc(test_pfunc)) # optional - sage.misc.cython + sage: print(sage_getdoc(test_pfunc)) # optional - sage.misc.cython Some documentation - sage: print(sage_getdoc(O.wrapped_method)) # optional - sage.misc.cython + sage: print(sage_getdoc(O.wrapped_method)) # optional - sage.misc.cython some doc for a wrapped cython method - sage: print(sage_getdoc(O.direct_method)) # optional - sage.misc.cython + sage: print(sage_getdoc(O.direct_method)) # optional - sage.misc.cython Some doc for direct method - sage: print(sage_getsource(O.wrapped_method)) # optional - sage.misc.cython + sage: print(sage_getsource(O.wrapped_method)) # optional - sage.misc.cython cpdef test_meth(self,x): "some doc for a wrapped cython method" return -x - sage: print(sage_getsource(O.direct_method)) # optional - sage.misc.cython + sage: print(sage_getsource(O.direct_method)) # optional - sage.misc.cython def direct_method(self, x): "Some doc for direct method" return 2*x @@ -304,11 +304,11 @@ latter is easy:: ....: " @cached_method", ....: " def f(self, a,b):", ....: " return a*b"] - sage: cython(os.linesep.join(cython_code)) # optional - sage.misc.cython - sage: P = MyClass() # optional - sage.misc.cython - sage: P.f(2, 3) # optional - sage.misc.cython + sage: cython(os.linesep.join(cython_code)) # optional - sage.misc.cython + sage: P = MyClass() # optional - sage.misc.cython + sage: P.f(2, 3) # optional - sage.misc.cython 6 - sage: P.f(2, 3) is P.f(2, 3) # optional - sage.misc.cython + sage: P.f(2, 3) is P.f(2, 3) # optional - sage.misc.cython True Providing attribute access is a bit more tricky, since it is needed that @@ -333,19 +333,19 @@ enough in the following example:: ....: " @cached_method", ....: " def f(self, a,b):", ....: " return a+b"] - sage: cython(os.linesep.join(cython_code)) # optional - sage.misc.cython - sage: Q = MyOtherClass() # optional - sage.misc.cython - sage: Q.f(2, 3) # optional - sage.misc.cython + sage: cython(os.linesep.join(cython_code)) # optional - sage.misc.cython + sage: Q = MyOtherClass() # optional - sage.misc.cython + sage: Q.f(2, 3) # optional - sage.misc.cython 5 - sage: Q.f(2, 3) is Q.f(2, 3) # optional - sage.misc.cython + sage: Q.f(2, 3) is Q.f(2, 3) # optional - sage.misc.cython True Note that supporting attribute access is somehow faster than the easier method:: - sage: timeit("a = P.f(2,3)") # random # optional - sage.misc.cython + sage: timeit("a = P.f(2,3)") # random # optional - sage.misc.cython 625 loops, best of 3: 1.3 µs per loop - sage: timeit("a = Q.f(2,3)") # random # optional - sage.misc.cython + sage: timeit("a = Q.f(2,3)") # random # optional - sage.misc.cython 625 loops, best of 3: 931 ns per loop Some immutable objects (such as `p`-adic numbers) cannot implement a @@ -353,18 +353,18 @@ reasonable hash function because their ``==`` operator has been modified to return ``True`` for objects which might behave differently in some computations:: - sage: K. = Qq(9) # optional - sage.rings.padics - sage: b = a.add_bigoh(1) # optional - sage.rings.padics - sage: c = a + 3 # optional - sage.rings.padics - sage: b # optional - sage.rings.padics + sage: K. = Qq(9) # optional - sage.rings.padics + sage: b = a.add_bigoh(1) # optional - sage.rings.padics + sage: c = a + 3 # optional - sage.rings.padics + sage: b # optional - sage.rings.padics a + O(3) - sage: c # optional - sage.rings.padics + sage: c # optional - sage.rings.padics a + 3 + O(3^20) - sage: b == c # optional - sage.rings.padics + sage: b == c # optional - sage.rings.padics True - sage: b == a # optional - sage.rings.padics + sage: b == a # optional - sage.rings.padics True - sage: c == a # optional - sage.rings.padics + sage: c == a # optional - sage.rings.padics False If such objects defined a non-trivial hash function, this would break @@ -372,20 +372,20 @@ caching in many places. However, such objects should still be usable in caches. This can be achieved by defining an appropriate method ``_cache_key``:: - sage: hash(b) # optional - sage.rings.padics + sage: hash(b) # optional - sage.rings.padics Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' sage: @cached_method ....: def f(x): return x == a - sage: f(b) # optional - sage.rings.padics + sage: f(b) # optional - sage.rings.padics True - sage: f(c) # if b and c were hashable, this would return True # optional - sage.rings.padics + sage: f(c) # if b and c were hashable, this would return True # optional - sage.rings.padics False - sage: b._cache_key() # optional - sage.rings.padics + sage: b._cache_key() # optional - sage.rings.padics (..., ((0, 1),), 0, 1) - sage: c._cache_key() # optional - sage.rings.padics + sage: c._cache_key() # optional - sage.rings.padics (..., ((0, 1), (1,)), 0, 20) .. NOTE:: @@ -398,9 +398,9 @@ if ``a != b``, then also ``a._cache_key() != b._cache_key()``. In practice this means that the ``_cache_key`` should always include the parent as its first argument:: - sage: S. = Qq(4) # optional - sage.rings.padics - sage: d = a.add_bigoh(1) # optional - sage.rings.padics - sage: b._cache_key() == d._cache_key() # this would be True if the parents were not included # optional - sage.rings.padics + sage: S. = Qq(4) # optional - sage.rings.padics + sage: d = a.add_bigoh(1) # optional - sage.rings.padics + sage: b._cache_key() == d._cache_key() # this would be True if the parents were not included # optional - sage.rings.padics False """ @@ -537,8 +537,8 @@ cpdef inline dict_key(o): sage: from sage.misc.cachefunc import dict_key sage: dict_key(42) 42 - sage: K. = Qq(9) # optional - sage.rings.padics - sage: dict_key(u) # optional - sage.rings.padics + sage: K. = Qq(9) # optional - sage.rings.padics + sage: dict_key(u) # optional - sage.rings.padics (, (..., 20)) """ try: @@ -561,24 +561,24 @@ cpdef inline cache_key(o): EXAMPLES:: sage: from sage.misc.cachefunc import cache_key - sage: K. = Qq(9) # optional - sage.rings.padics - sage: a = K(1); a # optional - sage.rings.padics + sage: K. = Qq(9) # optional - sage.rings.padics + sage: a = K(1); a # optional - sage.rings.padics 1 + O(3^20) - sage: cache_key(a) # optional - sage.rings.padics + sage: cache_key(a) # optional - sage.rings.padics (..., ((1,),), 0, 20) This function works if ``o`` is a tuple. In this case it unpacks its entries recursively:: - sage: o = (1, 2, (3, a)) # optional - sage.rings.padics - sage: cache_key(o) # optional - sage.rings.padics + sage: o = (1, 2, (3, a)) # optional - sage.rings.padics + sage: cache_key(o) # optional - sage.rings.padics (1, 2, (3, (..., ((1,),), 0, 20))) Note that tuples are only partially unpacked if some of its entries are hashable:: - sage: o = (1/2, a) # optional - sage.rings.padics - sage: cache_key(o) # optional - sage.rings.padics + sage: o = (1/2, a) # optional - sage.rings.padics + sage: cache_key(o) # optional - sage.rings.padics (1/2, (..., ((1,),), 0, 20)) """ try: @@ -688,14 +688,14 @@ cdef class CachedFunction(): TESTS:: - sage: g = CachedFunction(number_of_partitions) - sage: g.__name__ + sage: g = CachedFunction(number_of_partitions) # optional - sage.combinat + sage: g.__name__ # optional - sage.combinat 'number_of_partitions' - sage: 'partitions' in sage.misc.sageinspect.sage_getdoc(g) + sage: 'partitions' in sage.misc.sageinspect.sage_getdoc(g) # optional - sage.combinat True - sage: g(5) + sage: g(5) # optional - sage.combinat 7 - sage: g.cache + sage: g.cache # optional - sage.combinat {((5, 'default'), ()): 7} sage: def f(t=1): print(t) sage: h = CachedFunction(f) @@ -850,6 +850,7 @@ cdef class CachedFunction(): sage: I = P*[x,y] sage: from sage.misc.sageinspect import sage_getdoc sage: print(sage_getdoc(I.groebner_basis)) # indirect doctest + WARNING: the enclosing module is marked... Return the reduced Groebner basis of this ideal. ... @@ -896,8 +897,8 @@ cdef class CachedFunction(): TESTS:: sage: from sage.misc.sageinspect import sage_getsource - sage: g = CachedFunction(number_of_partitions) - sage: 'flint' in sage_getsource(g) # indirect doctest + sage: g = CachedFunction(number_of_partitions) # optional - sage.combinat + sage: 'flint' in sage_getsource(g) # indirect doctest # optional - sage.combinat True """ @@ -948,16 +949,16 @@ cdef class CachedFunction(): TESTS:: - sage: g = CachedFunction(number_of_partitions) - sage: a = g(5) - sage: g.cache + sage: g = CachedFunction(number_of_partitions) # optional - sage.combinat + sage: a = g(5) # optional - sage.combinat + sage: g.cache # optional - sage.combinat {((5, 'default'), ()): 7} - sage: a = g(10^5) # indirect doctest - sage: a == number_of_partitions(10^5) + sage: a = g(10^5) # indirect doctest # optional - sage.combinat + sage: a == number_of_partitions(10^5) # optional - sage.combinat True - sage: a is g(10^5) + sage: a is g(10^5) # optional - sage.combinat True - sage: a is number_of_partitions(10^5) + sage: a is number_of_partitions(10^5) # optional - sage.combinat True Check that :trac:`16316` has been fixed, i.e., caching works for @@ -966,16 +967,16 @@ cdef class CachedFunction(): sage: @cached_function ....: def f(x): return x+x - sage: K. = Qq(4) # optional - sage.rings.padics - sage: x = K(1,1); x # optional - sage.rings.padics + sage: K. = Qq(4) # optional - sage.rings.padics + sage: x = K(1,1); x # optional - sage.rings.padics 1 + O(2) - sage: y = K(1,2); y # optional - sage.rings.padics + sage: y = K(1,2); y # optional - sage.rings.padics 1 + O(2^2) - sage: x == y # optional - sage.rings.padics + sage: x == y # optional - sage.rings.padics True - sage: f(x) is f(x) # optional - sage.rings.padics + sage: f(x) is f(x) # optional - sage.rings.padics True - sage: f(y) is not f(x) # optional - sage.rings.padics + sage: f(y) is not f(x) # optional - sage.rings.padics True """ @@ -1047,14 +1048,14 @@ cdef class CachedFunction(): sage: @cached_function ....: def f(x): return x - sage: K. = Qq(4) # optional - sage.rings.padics - sage: x = K(1,1); x # optional - sage.rings.padics + sage: K. = Qq(4) # optional - sage.rings.padics + sage: x = K(1,1); x # optional - sage.rings.padics 1 + O(2) - sage: f.is_in_cache(x) # optional - sage.rings.padics + sage: f.is_in_cache(x) # optional - sage.rings.padics False - sage: f(x) # optional - sage.rings.padics + sage: f(x) # optional - sage.rings.padics 1 + O(2) - sage: f.is_in_cache(x) # optional - sage.rings.padics + sage: f.is_in_cache(x) # optional - sage.rings.padics True """ @@ -1073,14 +1074,14 @@ cdef class CachedFunction(): EXAMPLES:: - sage: g = CachedFunction(number_of_partitions) - sage: a = g(5) - sage: g.cache + sage: g = CachedFunction(number_of_partitions) # optional - sage.combinat + sage: a = g(5) # optional - sage.combinat + sage: g.cache # optional - sage.combinat {((5, 'default'), ()): 7} - sage: g.set_cache(17, 5) - sage: g.cache + sage: g.set_cache(17, 5) # optional - sage.combinat + sage: g.cache # optional - sage.combinat {((5, 'default'), ()): 17} - sage: g(5) + sage: g(5) # optional - sage.combinat 17 TESTS: @@ -1091,11 +1092,11 @@ cdef class CachedFunction(): sage: @cached_function ....: def f(x): return x - sage: K. = Qq(4) # optional - sage.rings.padics - sage: x = K(1,1); x # optional - sage.rings.padics + sage: K. = Qq(4) # optional - sage.rings.padics + sage: x = K(1,1); x # optional - sage.rings.padics 1 + O(2) - sage: f.set_cache(x, x) # optional - sage.rings.padics - sage: f.is_in_cache(x) # optional - sage.rings.padics + sage: f.set_cache(x, x) # optional - sage.rings.padics + sage: f.is_in_cache(x) # optional - sage.rings.padics True DEVELOPER NOTE: @@ -1174,8 +1175,8 @@ cdef class CachedFunction(): """ EXAMPLES:: - sage: g = CachedFunction(number_of_partitions) - sage: g # indirect doctest + sage: g = CachedFunction(number_of_partitions) # optional - sage.combinat + sage: g # indirect doctest # optional - sage.combinat Cached version of """ try: @@ -1189,12 +1190,12 @@ cdef class CachedFunction(): EXAMPLES:: - sage: g = CachedFunction(number_of_partitions) - sage: a = g(5) - sage: g.cache + sage: g = CachedFunction(number_of_partitions) # optional - sage.combinat + sage: a = g(5) # optional - sage.combinat + sage: g.cache # optional - sage.combinat {((5, 'default'), ()): 7} - sage: g.clear_cache() - sage: g.cache + sage: g.clear_cache() # optional - sage.combinat + sage: g.cache # optional - sage.combinat {} """ self.cache.clear() @@ -1317,17 +1318,17 @@ cdef class WeakCachedFunction(CachedFunction): sage: from sage.misc.cachefunc import weak_cached_function sage: @weak_cached_function ....: def f(x): return x+x - sage: K. = Qq(4) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: x = t + K(1,1); x # optional - sage.rings.padics + sage: K. = Qq(4) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: x = t + K(1,1); x # optional - sage.rings.padics (1 + O(2^20))*t + 1 + O(2) - sage: y = t + K(1,2); y # optional - sage.rings.padics + sage: y = t + K(1,2); y # optional - sage.rings.padics (1 + O(2^20))*t + 1 + O(2^2) - sage: x == y # optional - sage.rings.padics + sage: x == y # optional - sage.rings.padics True - sage: f(x) is f(x) # optional - sage.rings.padics + sage: f(x) is f(x) # optional - sage.rings.padics True - sage: f(y) is not f(x) # optional - sage.rings.padics + sage: f(y) is not f(x) # optional - sage.rings.padics True Examples and tests for ``is_in_cache``:: @@ -1361,13 +1362,13 @@ cdef class WeakCachedFunction(CachedFunction): sage: from sage.misc.cachefunc import weak_cached_function sage: @weak_cached_function ....: def f(x): return x - sage: K. = Qq(4) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: f.is_in_cache(t) # optional - sage.rings.padics + sage: K. = Qq(4) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: f.is_in_cache(t) # optional - sage.rings.padics False - sage: f(t) # optional - sage.rings.padics + sage: f(t) # optional - sage.rings.padics (1 + O(2^20))*t - sage: f.is_in_cache(t) # optional - sage.rings.padics + sage: f.is_in_cache(t) # optional - sage.rings.padics True Examples and tests for ``set_cache``:: @@ -1387,10 +1388,10 @@ cdef class WeakCachedFunction(CachedFunction): sage: from sage.misc.cachefunc import weak_cached_function sage: @weak_cached_function ....: def f(x): return x - sage: K. = Qq(4) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: f.set_cache(t,t) # optional - sage.rings.padics - sage: f.is_in_cache(t) # optional - sage.rings.padics + sage: K. = Qq(4) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: f.set_cache(t,t) # optional - sage.rings.padics + sage: f.is_in_cache(t) # optional - sage.rings.padics True """ def __init__(self, f, *, classmethod=False, name=None, key=None, **kwds): @@ -1902,20 +1903,20 @@ cdef class CachedMethodCaller(CachedFunction): immutable unhashable objects which define :meth:`sage.structure.sage_object.SageObject._cache_key`:: - sage: K. = Qq(4) # optional - sage.rings.padics + sage: K. = Qq(4) # optional - sage.rings.padics sage: class A(): ....: @cached_method ....: def f(self, x): return x+x sage: a = A() - sage: x = K(1,1); x # optional - sage.rings.padics + sage: x = K(1,1); x # optional - sage.rings.padics 1 + O(2) - sage: y = K(1,2); y # optional - sage.rings.padics + sage: y = K(1,2); y # optional - sage.rings.padics 1 + O(2^2) - sage: x == y # optional - sage.rings.padics + sage: x == y # optional - sage.rings.padics True - sage: a.f(x) is a.f(x) # optional - sage.rings.padics + sage: a.f(x) is a.f(x) # optional - sage.rings.padics True - sage: a.f(y) is not a.f(x) # optional - sage.rings.padics + sage: a.f(y) is not a.f(x) # optional - sage.rings.padics True """ @@ -3670,11 +3671,11 @@ class disk_cached_function: sage: dir = tmp_dir() sage: @disk_cached_function(dir) ....: def foo(x): return next_prime(2^x)%x - sage: x = foo(200);x + sage: x = foo(200); x # optional - sage.libs.pari 11 sage: @disk_cached_function(dir) ....: def foo(x): return 1/x - sage: foo(200) + sage: foo(200) # optional - sage.libs.pari 11 sage: foo.clear_cache() sage: foo(200) @@ -3687,12 +3688,12 @@ class disk_cached_function: sage: dir = tmp_dir() sage: @disk_cached_function(dir, memory_cache=True) ....: def foo(x): return next_prime(2^x) - sage: x = foo(200) - sage: x is foo(200) + sage: x = foo(200) # optional - sage.libs.pari + sage: x is foo(200) # optional - sage.libs.pari True sage: @disk_cached_function(dir, memory_cache=False) ....: def foo(x): return next_prime(2^x) - sage: x is foo(200) + sage: x is foo(200) # optional - sage.libs.pari False """ self._dir = dir diff --git a/src/sage/misc/call.py b/src/sage/misc/call.py index ddb48610e59..7234e07863a 100644 --- a/src/sage/misc/call.py +++ b/src/sage/misc/call.py @@ -40,11 +40,11 @@ def __call__(self, x, *args): EXAMPLES:: sage: core = attrcall('core', 3) - sage: core(Partition([4,2])) + sage: core(Partition([4,2])) # optional - sage.combinat [4, 2] - sage: series = attrcall('series', x) - sage: series(sin(x), 4) + sage: series = attrcall('series', x) # optional - sage.symbolic + sage: series(sin(x), 4) # optional - sage.symbolic 1*x + (-1/6)*x^3 + Order(x^4) """ return getattr(x, self.name)(*(self.args + args), **self.kwds) @@ -159,7 +159,7 @@ def attrcall(name, *args, **kwds): sage: f = attrcall('core', 3); f *.core(3) - sage: [f(p) for p in Partitions(5)] + sage: [f(p) for p in Partitions(5)] # optional - sage.combinat [[2], [1, 1], [1, 1], [3, 1, 1], [2], [2], [1, 1]] """ return AttrCallObject(name, args, kwds) diff --git a/src/sage/misc/classcall_metaclass.pyx b/src/sage/misc/classcall_metaclass.pyx index 191534f76ee..2806918309c 100644 --- a/src/sage/misc/classcall_metaclass.pyx +++ b/src/sage/misc/classcall_metaclass.pyx @@ -79,7 +79,7 @@ cdef class ClasscallMetaclass(NestedClassMetaclass): TESTS:: - sage: PerfectMatchings(2).list() + sage: PerfectMatchings(2).list() # optional - sage.combinat [[(1, 2)]] .. NOTE:: @@ -271,12 +271,12 @@ cdef class ClasscallMetaclass(NestedClassMetaclass): The benefit, compared with using a wrapper function, is that the user interface has a single handle for the class:: - sage: x = Partition([3,2,2]) - sage: isinstance(x, Partition) # todo: not implemented + sage: x = Partition([3,2,2]) # optional - sage.combinat + sage: isinstance(x, Partition) # todo: not implemented # optional - sage.combinat instead of:: - sage: isinstance(x, sage.combinat.partition.Partition) + sage: isinstance(x, sage.combinat.partition.Partition) # optional - sage.combinat True Another difference is that ``__classcall__`` is inherited by diff --git a/src/sage/misc/decorators.py b/src/sage/misc/decorators.py index ef22aebb242..dca4427ebf9 100644 --- a/src/sage/misc/decorators.py +++ b/src/sage/misc/decorators.py @@ -67,7 +67,7 @@ def sage_wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES): ....: return x sage: g(2) 4 - sage: g(x) + sage: g(x) # optional - sage.symbolic x^2 sage: g.__doc__ 'My little function' @@ -192,9 +192,9 @@ class infix_operator(): ....: def dot(a, b): ....: '''Dot product.''' ....: return a.dot_product(b) - sage: u = vector([1, 2, 3]) - sage: v = vector([5, 4, 3]) - sage: u *dot* v + sage: u = vector([1, 2, 3]) # optional - sage.modules + sage: v = vector([5, 4, 3]) # optional - sage.modules + sage: u *dot* v # optional - sage.modules 22 An infix element-wise addition operator:: @@ -202,11 +202,11 @@ class infix_operator(): sage: @infix_operator('add') ....: def eadd(a, b): ....: return a.parent([i + j for i, j in zip(a, b)]) - sage: u = vector([1, 2, 3]) - sage: v = vector([5, 4, 3]) - sage: u +eadd+ v + sage: u = vector([1, 2, 3]) # optional - sage.modules + sage: v = vector([5, 4, 3]) # optional - sage.modules + sage: u +eadd+ v # optional - sage.modules (6, 6, 6) - sage: 2*u +eadd+ v + sage: 2*u +eadd+ v # optional - sage.modules (7, 8, 9) A hack to simulate a postfix operator:: @@ -214,7 +214,7 @@ class infix_operator(): sage: @infix_operator('or') ....: def thendo(a, b): ....: return b(a) - sage: x |thendo| cos |thendo| (lambda x: x^2) + sage: x |thendo| cos |thendo| (lambda x: x^2) # optional - sage.symbolic cos(x)^2 """ diff --git a/src/sage/misc/derivative.pyx b/src/sage/misc/derivative.pyx index 45ee7a918c5..b260099afcd 100644 --- a/src/sage/misc/derivative.pyx +++ b/src/sage/misc/derivative.pyx @@ -91,20 +91,20 @@ def derivative_parse(args): EXAMPLES:: - sage: x = var("x") - sage: y = var("y") + sage: x = var("x") # optional - sage.symbolic + sage: y = var("y") # optional - sage.symbolic sage: from sage.misc.derivative import derivative_parse Differentiate twice with respect to x, then once with respect to y, then once with respect to x:: - sage: derivative_parse([x, 2, y, x]) + sage: derivative_parse([x, 2, y, x]) # optional - sage.symbolic [x, x, y, x] Differentiate twice with respect to x, then twice with respect to the 'default variable':: - sage: derivative_parse([x, 2, 2]) + sage: derivative_parse([x, 2, 2]) # optional - sage.symbolic [x, x, None, None] Special case with empty input list:: @@ -119,7 +119,7 @@ def derivative_parse(args): Special case with single list argument provided:: - sage: derivative_parse(([x, y], )) + sage: derivative_parse(([x, y], )) # optional - sage.symbolic [x, y] If only the count is supplied:: @@ -135,15 +135,15 @@ def derivative_parse(args): Various other cases:: - sage: derivative_parse([x]) + sage: derivative_parse([x]) # optional - sage.symbolic [x] - sage: derivative_parse([x, x]) + sage: derivative_parse([x, x]) # optional - sage.symbolic [x, x] - sage: derivative_parse([x, 2]) + sage: derivative_parse([x, 2]) # optional - sage.symbolic [x, x] - sage: derivative_parse([x, 0]) + sage: derivative_parse([x, 0]) # optional - sage.symbolic [] - sage: derivative_parse([x, y, x, 2, 2, y]) + sage: derivative_parse([x, y, x, 2, 2, y]) # optional - sage.symbolic [x, y, x, x, None, None, y] """ diff --git a/src/sage/misc/dev_tools.py b/src/sage/misc/dev_tools.py index c18253358ba..68d97f203e5 100644 --- a/src/sage/misc/dev_tools.py +++ b/src/sage/misc/dev_tools.py @@ -221,12 +221,12 @@ def find_objects_from_name(name, module_name=None): sage: dt.find_objects_from_name('FareySymbol') [] - sage: import sympy - sage: dt.find_objects_from_name('RR') + sage: import sympy # optional - sympy + sage: dt.find_objects_from_name('RR') # optional - sympy [Real Field with 53 bits of precision, RR] - sage: dt.find_objects_from_name('RR', 'sage') + sage: dt.find_objects_from_name('RR', 'sage') # optional - sympy [Real Field with 53 bits of precision] - sage: dt.find_objects_from_name('RR', 'sympy') + sage: dt.find_objects_from_name('RR', 'sympy') # optional - sympy [RR] Examples that do not belong to the global namespace but in a loaded module:: diff --git a/src/sage/misc/element_with_label.py b/src/sage/misc/element_with_label.py index 2410851c7de..b490417ed50 100644 --- a/src/sage/misc/element_with_label.py +++ b/src/sage/misc/element_with_label.py @@ -25,20 +25,20 @@ class ElementWithLabel(): EXAMPLES:: - sage: P = Poset({1: [2,3]}) - sage: labs = {i: P.rank(i) for i in range(1, 4)} - sage: print(labs) + sage: P = Poset({1: [2,3]}) # optional - sage.combinat sage.graphs + sage: labs = {i: P.rank(i) for i in range(1, 4)} # optional - sage.combinat sage.graphs + sage: print(labs) # optional - sage.combinat sage.graphs {1: 0, 2: 1, 3: 1} - sage: print(P.plot(element_labels=labs)) + sage: print(P.plot(element_labels=labs)) # optional - sage.combinat sage.graphs sage.plot Graphics object consisting of 6 graphics primitives sage: from sage.misc.element_with_label import ElementWithLabel - sage: W = WeylGroup("A1") - sage: P = W.bruhat_poset(facade=True) - sage: D = W.domain() - sage: v = D.rho() - D.fundamental_weight(1) - sage: nP = P.relabel(lambda w: ElementWithLabel(w, w.action(v))) - sage: list(nP) + sage: W = WeylGroup("A1") # optional - sage.combinat + sage: P = W.bruhat_poset(facade=True) # optional - sage.combinat sage.graphs + sage: D = W.domain() # optional - sage.combinat sage.graphs + sage: v = D.rho() - D.fundamental_weight(1) # optional - sage.combinat sage.graphs + sage: nP = P.relabel(lambda w: ElementWithLabel(w, w.action(v))) # optional - sage.combinat sage.graphs + sage: list(nP) # optional - sage.combinat sage.graphs [(0, 0), (0, 0)] """ def __init__(self, element, label): @@ -65,11 +65,11 @@ def _latex_(self): TESTS:: - sage: var('a_1') + sage: var('a_1') # optional - sage.symbolic a_1 sage: from sage.misc.element_with_label import ElementWithLabel - sage: e = ElementWithLabel(1, a_1) - sage: latex(e) + sage: e = ElementWithLabel(1, a_1) # optional - sage.symbolic + sage: latex(e) # optional - sage.symbolic a_{1} """ return latex(self.label) @@ -81,11 +81,11 @@ def __str__(self): TESTS:: - sage: var('a_1') + sage: var('a_1') # optional - sage.symbolic a_1 sage: from sage.misc.element_with_label import ElementWithLabel - sage: e = ElementWithLabel(1, a_1) - sage: str(e) + sage: e = ElementWithLabel(1, a_1) # optional - sage.symbolic + sage: str(e) # optional - sage.symbolic 'a_1' """ return str(self.label) @@ -97,11 +97,11 @@ def __repr__(self): TESTS:: - sage: var('a_1') + sage: var('a_1') # optional - sage.symbolic a_1 sage: from sage.misc.element_with_label import ElementWithLabel - sage: e = ElementWithLabel(1, a_1) - sage: repr(e) + sage: e = ElementWithLabel(1, a_1) # optional - sage.symbolic + sage: repr(e) # optional - sage.symbolic 'a_1' """ return repr(self.label) diff --git a/src/sage/misc/flatten.py b/src/sage/misc/flatten.py index 8b8a7ce54b2..0a1e68d63a5 100644 --- a/src/sage/misc/flatten.py +++ b/src/sage/misc/flatten.py @@ -23,7 +23,7 @@ def flatten(in_list, ltypes=(list, tuple), max_level=sys.maxsize): [1, 1, 1, 2] sage: flatten([[1,2,3], (4,5), [[[1],[2]]]]) [1, 2, 3, 4, 5, 1, 2] - sage: flatten([[1,2,3], (4,5), [[[1],[2]]]],max_level=1) + sage: flatten([[1,2,3], (4,5), [[[1],[2]]]], max_level=1) [1, 2, 3, 4, 5, [[1], [2]]] sage: flatten([[[3],[]]],max_level=0) [[[3], []]] @@ -35,24 +35,24 @@ def flatten(in_list, ltypes=(list, tuple), max_level=sys.maxsize): In the following example, the vector is not flattened because it is not given in the ``ltypes`` input. :: - sage: flatten((['Hi',2,vector(QQ,[1,2,3])],(4,5,6))) + sage: flatten((['Hi', 2, vector(QQ, [1,2,3])], (4,5,6))) # optional - sage.modules ['Hi', 2, (1, 2, 3), 4, 5, 6] We give the vector type and then even the vector gets flattened:: - sage: tV = sage.modules.vector_rational_dense.Vector_rational_dense - sage: flatten((['Hi',2,vector(QQ,[1,2,3])], (4,5,6)), + sage: tV = sage.modules.vector_rational_dense.Vector_rational_dense # optional - sage.modules + sage: flatten((['Hi', 2, vector(QQ, [1,2,3])], (4,5,6)), # optional - sage.modules ....: ltypes=(list, tuple, tV)) ['Hi', 2, 1, 2, 3, 4, 5, 6] We flatten a finite field. :: - sage: flatten(GF(5)) + sage: flatten(GF(5)) # optional - sage.libs.pari [0, 1, 2, 3, 4] - sage: flatten([GF(5)]) + sage: flatten([GF(5)]) # optional - sage.libs.pari [Finite Field of size 5] - sage: tGF = type(GF(5)) - sage: flatten([GF(5)], ltypes = (list, tuple, tGF)) + sage: tGF = type(GF(5)) # optional - sage.libs.pari + sage: flatten([GF(5)], ltypes=(list, tuple, tGF)) # optional - sage.libs.pari [0, 1, 2, 3, 4] Degenerate cases:: diff --git a/src/sage/misc/function_mangling.pyx b/src/sage/misc/function_mangling.pyx index e1bb7978953..b910cabef0c 100644 --- a/src/sage/misc/function_mangling.pyx +++ b/src/sage/misc/function_mangling.pyx @@ -157,8 +157,8 @@ cdef class ArgumentFixer: EXAMPLES:: sage: from sage.misc.function_mangling import ArgumentFixer - sage: g = ArgumentFixer(number_of_partitions) - sage: g + sage: g = ArgumentFixer(number_of_partitions) # optional - sage.combinat + sage: g # optional - sage.combinat Argument Fixer of """ return "Argument Fixer of %s"%self.f @@ -203,10 +203,10 @@ cdef class ArgumentFixer: EXAMPLES:: sage: from sage.misc.function_mangling import ArgumentFixer - sage: def sum3(a,b,c=3,*args,**kwargs): - ....: return a+b+c + sage: def sum3(a, b, c=3, *args, **kwargs): + ....: return a + b + c sage: AF = ArgumentFixer(sum3) - sage: AF.fix_to_named(1,2,3,4,5,6,f=14,e=16) + sage: AF.fix_to_named(1, 2, 3, 4, 5, 6, f=14, e=16) ((4, 5, 6), (('a', 1), ('b', 2), ('c', 3), ('e', 16), ('f', 14))) sage: AF.fix_to_named(1,2,f=14) ((), (('a', 1), ('b', 2), ('c', 3), ('f', 14))) diff --git a/src/sage/misc/functional.py b/src/sage/misc/functional.py index aee5d035a66..ffc191fb139 100644 --- a/src/sage/misc/functional.py +++ b/src/sage/misc/functional.py @@ -58,8 +58,8 @@ def base_ring(x): EXAMPLES:: - sage: R = PolynomialRing(GF(7), 'x') - sage: base_ring(R) + sage: R = PolynomialRing(GF(7), 'x') # optional - sage.rings.finite_rings + sage: base_ring(R) # optional - sage.rings.finite_rings Finite Field of size 7 """ return x.base_ring() @@ -71,17 +71,17 @@ def base_field(x): EXAMPLES:: - sage: R = PolynomialRing(GF(7), 'x') - sage: base_ring(R) + sage: R = PolynomialRing(GF(7), 'x') # optional - sage.rings.finite_rings + sage: base_ring(R) # optional - sage.rings.finite_rings Finite Field of size 7 - sage: base_field(R) + sage: base_field(R) # optional - sage.rings.finite_rings Finite Field of size 7 This catches base rings which are fields as well, but does not implement a ``base_field`` method for objects which do not have one:: - sage: R.base_field() + sage: R.base_field() # optional - sage.rings.finite_rings Traceback (most recent call last): ... AttributeError: 'PolynomialRing_dense_mod_p_with_category' object has no attribute 'base_field' @@ -102,9 +102,9 @@ def basis(x): EXAMPLES:: - sage: V = VectorSpace(QQ,3) - sage: S = V.subspace([[1,2,0],[2,2,-1]]) - sage: basis(S) + sage: V = VectorSpace(QQ, 3) # optional - sage.modules + sage: S = V.subspace([[1,2,0], [2,2,-1]]) # optional - sage.modules + sage: basis(S) # optional - sage.modules [ (1, 0, -1), (0, 1, 1/2) @@ -119,8 +119,8 @@ def category(x): EXAMPLES:: - sage: V = VectorSpace(QQ,3) - sage: category(V) + sage: V = VectorSpace(QQ, 3) # optional - sage.modules + sage: category(V) # optional - sage.modules Category of finite dimensional vector spaces with basis over (number fields and quotient fields and metric spaces) """ @@ -137,30 +137,30 @@ def characteristic_polynomial(x, var='x'): EXAMPLES:: - sage: M = MatrixSpace(QQ,3,3) - sage: A = M([1,2,3,4,5,6,7,8,9]) - sage: charpoly(A) + sage: M = MatrixSpace(QQ, 3, 3) # optional - sage.modules + sage: A = M([1,2,3,4,5,6,7,8,9]) # optional - sage.modules + sage: charpoly(A) # optional - sage.libs.pari sage.modules x^3 - 15*x^2 - 18*x - sage: charpoly(A, 't') + sage: charpoly(A, 't') # optional - sage.libs.pari sage.modules t^3 - 15*t^2 - 18*t - sage: k. = GF(7^10); k + sage: k. = GF(7^10); k # optional - sage.rings.finite_rings Finite Field in alpha of size 7^10 - sage: alpha.charpoly('T') + sage: alpha.charpoly('T') # optional - sage.rings.finite_rings T^10 + T^6 + T^5 + 4*T^4 + T^3 + 2*T^2 + 3*T + 3 - sage: characteristic_polynomial(alpha, 'T') + sage: characteristic_polynomial(alpha, 'T') # optional - sage.rings.finite_rings T^10 + T^6 + T^5 + 4*T^4 + T^3 + 2*T^2 + 3*T + 3 Ensure the variable name of the polynomial does not conflict with variables used within the matrix, and that non-integral powers of variables do not confuse the computation (:trac:`14403`):: - sage: y = var('y') - sage: a = matrix([[x,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]) - sage: characteristic_polynomial(a).list() + sage: y = var('y') # optional - sage.libs.pari sage.symbolic + sage: a = matrix([[x,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]]) # optional - sage.libs.pari sage.symbolic + sage: characteristic_polynomial(a).list() # optional - sage.libs.pari sage.symbolic [x, -3*x - 1, 3*x + 3, -x - 3, 1] - sage: b = matrix([[y^(1/2),0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]) - sage: charpoly(b).list() + sage: b = matrix([[y^(1/2),0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]]) # optional - sage.libs.pari sage.symbolic + sage: charpoly(b).list() # optional - sage.libs.pari sage.symbolic [sqrt(y), -3*sqrt(y) - 1, 3*sqrt(y) + 3, -sqrt(y) - 3, 1] """ try: @@ -215,19 +215,20 @@ def decomposition(x): EXAMPLES:: - sage: M = matrix([[2, 3], [3, 4]]) - sage: M.decomposition() + sage: M = matrix([[2, 3], [3, 4]]) # optional - sage.libs.pari sage.modules + sage: M.decomposition() # optional - sage.libs.pari sage.modules [ (Ambient free module of rank 2 over the principal ideal domain Integer Ring, True) ] - sage: G. = DirichletGroup(20) - sage: c = a*b - sage: d = c.decomposition(); d + sage: G. = DirichletGroup(20) # optional - sage.groups + sage: c = a * b # optional - sage.groups + sage: d = c.decomposition(); d # optional - sage.groups [Dirichlet character modulo 4 of conductor 4 mapping 3 |--> -1, Dirichlet character modulo 5 of conductor 5 mapping 2 |--> zeta4] - sage: d[0].parent() - Group of Dirichlet characters modulo 4 with values in Cyclotomic Field of order 4 and degree 2 + sage: d[0].parent() # optional - sage.groups + Group of Dirichlet characters modulo 4 + with values in Cyclotomic Field of order 4 and degree 2 """ return x.decomposition() @@ -257,9 +258,9 @@ def det(x): EXAMPLES:: - sage: M = MatrixSpace(QQ,3,3) - sage: A = M([1,2,3,4,5,6,7,8,9]) - sage: det(A) + sage: M = MatrixSpace(QQ, 3, 3) # optional - sage.modules + sage: A = M([1,2,3, 4,5,6, 7,8,9]) # optional - sage.modules + sage: det(A) # optional - sage.modules 0 """ return x.det() @@ -271,9 +272,9 @@ def dimension(x): EXAMPLES:: - sage: V = VectorSpace(QQ,3) - sage: S = V.subspace([[1,2,0],[2,2,-1]]) - sage: dimension(S) + sage: V = VectorSpace(QQ, 3) # optional - sage.modules + sage: S = V.subspace([[1,2,0], [2,2,-1]]) # optional - sage.modules + sage: dimension(S) # optional - sage.modules 2 """ return x.dimension() @@ -289,9 +290,9 @@ def discriminant(x): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S = R.quotient(x^29 - 17*x - 1, 'alpha') - sage: K = S.number_field() - sage: discriminant(K) + sage: S = R.quotient(x^29 - 17*x - 1, 'alpha') # optional - sage.libs.pari + sage: K = S.number_field() # optional - sage.libs.pari sage.rings.number_field + sage: discriminant(K) # optional - sage.libs.pari sage.rings.number_field -15975100446626038280218213241591829458737190477345113376757479850566957249523 """ return x.discriminant() @@ -313,7 +314,7 @@ def eta(x): EXAMPLES:: - sage: eta(1+I) + sage: eta(1 + I) 0.7420487758365647 + 0.1988313702299107*I """ try: @@ -328,9 +329,9 @@ def fcp(x, var='x'): EXAMPLES:: - sage: M = MatrixSpace(QQ,3,3) - sage: A = M([1,2,3,4,5,6,7,8,9]) - sage: fcp(A, 'x') + sage: M = MatrixSpace(QQ, 3, 3) # optional - sage.modules + sage: A = M([1,2,3, 4,5,6, 7,8,9]) # optional - sage.modules + sage: fcp(A, 'x') # optional - sage.libs.pari sage.modules x * (x^2 - 15*x - 18) """ try: @@ -349,10 +350,10 @@ def gen(x): Univariate Polynomial Ring in x over Rational Field sage: gen(R) x - sage: gen(GF(7)) + sage: gen(GF(7)) # optional - sage.rings.finite_rings 1 - sage: A = AbelianGroup(1, [23]) - sage: gen(A) + sage: A = AbelianGroup(1, [23]) # optional - sage.groups + sage: gen(A) # optional - sage.groups f """ return x.gen() @@ -364,13 +365,13 @@ def gens(x): EXAMPLES:: - sage: R. = SR[] - sage: R + sage: R. = SR[] # optional - sage.symbolic + sage: R # optional - sage.symbolic Multivariate Polynomial Ring in x, y over Symbolic Ring - sage: gens(R) + sage: gens(R) # optional - sage.symbolic (x, y) - sage: A = AbelianGroup(5, [5,5,7,8,9]) - sage: gens(A) + sage: A = AbelianGroup(5, [5,5,7,8,9]) # optional - sage.groups + sage: gens(A) # optional - sage.groups (f0, f1, f2, f3, f4) """ return x.gens() @@ -384,7 +385,8 @@ def hecke_operator(x, n): sage: M = ModularSymbols(1,12) sage: hecke_operator(M,5) - Hecke operator T_5 on Modular Symbols space of dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field + Hecke operator T_5 on Modular Symbols space of dimension 3 for Gamma_0(1) + of weight 12 with sign 0 over Rational Field """ return x.hecke_operator(n) @@ -395,9 +397,9 @@ def image(x): EXAMPLES:: - sage: M = MatrixSpace(QQ,3,3) - sage: A = M([1,2,3,4,5,6,7,8,9]) - sage: image(A) + sage: M = MatrixSpace(QQ, 3, 3) # optional - sage.modules + sage: A = M([1,2,3, 4,5,6, 7,8,9]) # optional - sage.modules + sage: image(A) # optional - sage.modules Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [ 1 0 -1] @@ -435,18 +437,18 @@ def symbolic_sum(expression, *args, **kwds): EXAMPLES:: - sage: k, n = var('k,n') - sage: sum(k, k, 1, n).factor() + sage: k, n = var('k,n') # optional - sage.symbolic + sage: sum(k, k, 1, n).factor() # optional - sage.symbolic 1/2*(n + 1)*n :: - sage: sum(1/k^4, k, 1, oo) + sage: sum(1/k^4, k, 1, oo) # optional - sage.symbolic 1/90*pi^4 :: - sage: sum(1/k^5, k, 1, oo) + sage: sum(1/k^5, k, 1, oo) # optional - sage.symbolic zeta(5) .. WARNING:: @@ -458,9 +460,9 @@ def symbolic_sum(expression, *args, **kwds): In particular, this does not work:: - sage: n = var('n') + sage: n = var('n') # optional - sage.symbolic sage: mylist = [1,2,3,4,5] - sage: sum(mylist[n], n, 0, 3) + sage: sum(mylist[n], n, 0, 3) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: unable to convert n to an integer @@ -472,95 +474,95 @@ def symbolic_sum(expression, *args, **kwds): Also, only a limited number of functions are recognized in symbolic sums:: - sage: sum(valuation(n,2),n,1,5) + sage: sum(valuation(n, 2), n, 1, 5) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: unable to convert n to an integer Again, use python ``sum()``:: - sage: sum(valuation(n+1,2) for n in range(5)) + sage: sum(valuation(n + 1, 2) for n in range(5)) 3 (now back to the Sage ``sum`` examples) A well known binomial identity:: - sage: sum(binomial(n,k), k, 0, n) + sage: sum(binomial(n, k), k, 0, n) # optional - sage.symbolic 2^n The binomial theorem:: - sage: x, y = var('x, y') - sage: sum(binomial(n,k) * x^k * y^(n-k), k, 0, n) + sage: x, y = var('x, y') # optional - sage.symbolic + sage: sum(binomial(n, k) * x^k * y^(n-k), k, 0, n) # optional - sage.symbolic (x + y)^n :: - sage: sum(k * binomial(n, k), k, 1, n) + sage: sum(k * binomial(n, k), k, 1, n) # optional - sage.symbolic 2^(n - 1)*n :: - sage: sum((-1)^k*binomial(n,k), k, 0, n) + sage: sum((-1)^k * binomial(n, k), k, 0, n) # optional - sage.symbolic 0 :: - sage: sum(2^(-k)/(k*(k+1)), k, 1, oo) + sage: sum(2^(-k)/(k*(k+1)), k, 1, oo) # optional - sage.symbolic -log(2) + 1 Another binomial identity (:trac:`7952`):: - sage: t,k,i = var('t,k,i') - sage: sum(binomial(i+t,t),i,0,k) + sage: t, k, i = var('t,k,i') # optional - sage.symbolic + sage: sum(binomial(i + t, t), i, 0, k) # optional - sage.symbolic binomial(k + t + 1, t + 1) Summing a hypergeometric term:: - sage: sum(binomial(n, k) * factorial(k) / factorial(n+1+k), k, 0, n) + sage: sum(binomial(n, k) * factorial(k) / factorial(n+1+k), k, 0, n) # optional - sage.symbolic 1/2*sqrt(pi)/factorial(n + 1/2) We check a well known identity:: - sage: bool(sum(k^3, k, 1, n) == sum(k, k, 1, n)^2) + sage: bool(sum(k^3, k, 1, n) == sum(k, k, 1, n)^2) # optional - sage.symbolic True A geometric sum:: - sage: a, q = var('a, q') - sage: sum(a*q^k, k, 0, n) + sage: a, q = var('a, q') # optional - sage.symbolic + sage: sum(a*q^k, k, 0, n) # optional - sage.symbolic (a*q^(n + 1) - a)/(q - 1) The geometric series:: - sage: assume(abs(q) < 1) - sage: sum(a*q^k, k, 0, oo) + sage: assume(abs(q) < 1) # optional - sage.symbolic + sage: sum(a * q^k, k, 0, oo) # optional - sage.symbolic -a/(q - 1) A divergent geometric series. Don't forget to forget your assumptions:: - sage: forget() - sage: assume(q > 1) - sage: sum(a*q^k, k, 0, oo) + sage: forget() # optional - sage.symbolic + sage: assume(q > 1) # optional - sage.symbolic + sage: sum(a * q^k, k, 0, oo) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Sum is divergent. This summation only Mathematica can perform:: - sage: sum(1/(1+k^2), k, -oo, oo, algorithm = 'mathematica') # optional - mathematica + sage: sum(1/(1+k^2), k, -oo, oo, algorithm='mathematica') # optional - mathematica sage.symbolic pi*coth(pi) Use Maple as a backend for summation:: - sage: sum(binomial(n,k)*x^k, k, 0, n, algorithm = 'maple') # optional - maple + sage: sum(binomial(n, k) * x^k, k, 0, n, algorithm='maple') # optional - maple sage.symbolic (x + 1)^n Python ints should work as limits of summation (:trac:`9393`):: - sage: sum(x, x, 1r, 5r) + sage: sum(x, x, 1r, 5r) # optional - sage.symbolic 15 .. note:: @@ -573,9 +575,9 @@ def symbolic_sum(expression, *args, **kwds): Check that :trac:`34007` is fixed:: - sage: sum([1,2], start=1) + sage: sum([1, 2], start=1) # optional - sage.symbolic 4 - sage: sum([[1],[2]], start=[]) + sage: sum([[1], [2]], start=[]) # optional - sage.symbolic [1, 2] """ @@ -615,22 +617,22 @@ def symbolic_prod(expression, *args, **kwds): EXAMPLES:: - sage: i, k, n = var('i,k,n') - sage: product(k,k,1,n) + sage: i, k, n = var('i,k,n') # optional - sage.symbolic + sage: product(k, k, 1, n) # optional - sage.symbolic factorial(n) - sage: product(x + i*(i+1)/2, i, 1, 4) + sage: product(x + i*(i+1)/2, i, 1, 4) # optional - sage.symbolic x^4 + 20*x^3 + 127*x^2 + 288*x + 180 - sage: product(i^2, i, 1, 7) + sage: product(i^2, i, 1, 7) # optional - sage.symbolic 25401600 - sage: f = function('f') - sage: product(f(i), i, 1, 7) + sage: f = function('f') # optional - sage.symbolic + sage: product(f(i), i, 1, 7) # optional - sage.symbolic f(7)*f(6)*f(5)*f(4)*f(3)*f(2)*f(1) - sage: product(f(i), i, 1, n) + sage: product(f(i), i, 1, n) # optional - sage.symbolic product(f(i), i, 1, n) - sage: assume(k>0) - sage: product(integrate (x^k, x, 0, 1), k, 1, n) + sage: assume(k>0) # optional - sage.symbolic + sage: product(integrate(x^k, x, 0, 1), k, 1, n) # optional - sage.symbolic 1/factorial(n + 1) - sage: product(f(i), i, 1, n).log().log_expand() + sage: product(f(i), i, 1, n).log().log_expand() # optional - sage.symbolic sum(log(f(i)), i, 1, n) """ @@ -663,38 +665,38 @@ def integral(x, *args, **kwds): :: - sage: integral(sin(x),x) + sage: integral(sin(x), x) # optional - sage.symbolic -cos(x) :: - sage: y = var('y') - sage: integral(sin(x),y) + sage: y = var('y') # optional - sage.symbolic + sage: integral(sin(x), y) # optional - sage.symbolic y*sin(x) :: - sage: integral(sin(x), x, 0, pi/2) + sage: integral(sin(x), x, 0, pi/2) # optional - sage.symbolic 1 - sage: sin(x).integral(x, 0,pi/2) + sage: sin(x).integral(x, 0, pi/2) # optional - sage.symbolic 1 - sage: integral(exp(-x), (x, 1, oo)) + sage: integral(exp(-x), (x, 1, oo)) # optional - sage.symbolic e^(-1) Numerical approximation:: - sage: h = integral(tan(x)/x, (x, 1, pi/3)) + sage: h = integral(tan(x)/x, (x, 1, pi/3)) # optional - sage.symbolic ... - sage: h + sage: h # optional - sage.symbolic integrate(tan(x)/x, x, 1, 1/3*pi) - sage: h.n() + sage: h.n() # optional - sage.symbolic 0.07571599101... Specific algorithm can be used for integration:: - sage: integral(sin(x)^2, x, algorithm='maxima') + sage: integral(sin(x)^2, x, algorithm='maxima') # optional - sage.symbolic 1/2*x - 1/4*sin(2*x) - sage: integral(sin(x)^2, x, algorithm='sympy') + sage: integral(sin(x)^2, x, algorithm='sympy') # optional - sage.symbolic -1/2*cos(x)*sin(x) + 1/2*x TESTS: @@ -702,8 +704,8 @@ def integral(x, *args, **kwds): A symbolic integral from :trac:`11445` that was incorrect in earlier versions of Maxima:: - sage: f = abs(x - 1) + abs(x + 1) - 2*abs(x) - sage: integrate(f, (x, -Infinity, Infinity)) + sage: f = abs(x - 1) + abs(x + 1) - 2*abs(x) # optional - sage.symbolic + sage: integrate(f, (x, -Infinity, Infinity)) # optional - sage.symbolic 2 Another symbolic integral, from :trac:`11238`, that used to return @@ -714,58 +716,60 @@ def integral(x, *args, **kwds): with the default settings, so we temporarily use the Maxima setting ``domain: real``:: - sage: sage.calculus.calculus.maxima('domain: real') + sage: sage.calculus.calculus.maxima('domain: real') # optional - sage.symbolic real - sage: f = exp(-x) * sinh(sqrt(x)) - sage: t = integrate(f, x, 0, Infinity); t # long time + sage: f = exp(-x) * sinh(sqrt(x)) # optional - sage.symbolic + sage: t = integrate(f, x, 0, Infinity); t # long time # optional - sage.symbolic 1/4*sqrt(pi)*(erf(1) - 1)*e^(1/4) - 1/4*(sqrt(pi)*(erf(1) - 1) - sqrt(pi) + 2*e^(-1) - 2)*e^(1/4) + 1/4*sqrt(pi)*e^(1/4) - 1/2*e^(1/4) + 1/2*e^(-3/4) - sage: t.canonicalize_radical() # long time + sage: t.canonicalize_radical() # long time # optional - sage.symbolic 1/2*sqrt(pi)*e^(1/4) - sage: sage.calculus.calculus.maxima('domain: complex') + sage: sage.calculus.calculus.maxima('domain: complex') # optional - sage.symbolic complex An integral which used to return -1 before maxima 5.28. See :trac:`12842`:: - sage: f = e^(-2*x)/sqrt(1-e^(-2*x)) - sage: integrate(f, x, 0, infinity) + sage: f = e^(-2*x)/sqrt(1-e^(-2*x)) # optional - sage.symbolic + sage: integrate(f, x, 0, infinity) # optional - sage.symbolic 1 This integral would cause a stack overflow in earlier versions of Maxima, crashing sage. See :trac:`12377`. We don't care about the result here, just that the computation completes successfully:: - sage: y = (x^2)*exp(x) / (1 + exp(x))^2 - sage: _ = integrate(y, x, -1000, 1000) + sage: y = (x^2)*exp(x) / (1 + exp(x))^2 # optional - sage.symbolic + sage: _ = integrate(y, x, -1000, 1000) # optional - sage.symbolic When SymPy cannot solve an integral it gives it back, so we must be able to convert SymPy's ``Integral`` (:trac:`14723`):: - sage: x, y, z = var('x,y,z') - sage: f = function('f') - sage: integrate(f(x), x, algorithm='sympy') + sage: x, y, z = var('x,y,z') # optional - sage.symbolic + sage: f = function('f') # optional - sage.symbolic + sage: integrate(f(x), x, algorithm='sympy') # optional - sage.symbolic integrate(f(x), x) - sage: integrate(f(x), x, 0, 1,algorithm='sympy') + sage: integrate(f(x), x, 0, 1, algorithm='sympy') # optional - sage.symbolic integrate(f(x), x, 0, 1) - sage: integrate(integrate(integrate(f(x,y,z), x, algorithm='sympy'), y, algorithm='sympy'), z, algorithm='sympy') + sage: integrate(integrate(integrate(f(x,y,z), x, algorithm='sympy'), # optional - sage.symbolic + ....: y, algorithm='sympy'), + ....: z, algorithm='sympy') integrate(integrate(integrate(f(x, y, z), x), y), z) - sage: integrate(sin(x)*tan(x)/(1-cos(x)), x, algorithm='sympy') + sage: integrate(sin(x)*tan(x)/(1-cos(x)), x, algorithm='sympy') # optional - sage.symbolic -integrate(sin(x)*tan(x)/(cos(x) - 1), x) - sage: _ = var('a,b,x') - sage: integrate(sin(x)*tan(x)/(1-cos(x)), x, a, b, algorithm='sympy') + sage: _ = var('a,b,x') # optional - sage.symbolic + sage: integrate(sin(x)*tan(x)/(1-cos(x)), x, a, b, algorithm='sympy') # optional - sage.symbolic -integrate(sin(x)*tan(x)/(cos(x) - 1), x, a, b) - sage: import sympy - sage: x, y, z = sympy.symbols('x y z') - sage: f = sympy.Function('f') - sage: SR(sympy.Integral(f(x,y,z), x, y, z)) + sage: import sympy # optional - sympy + sage: x, y, z = sympy.symbols('x y z') # optional - sympy + sage: f = sympy.Function('f') # optional - sympy + sage: SR(sympy.Integral(f(x,y,z), x, y, z)) # optional - sympy sage.symbolic integrate(integrate(integrate(f(x, y, z), x), y), z) Ensure that the following integral containing a signum term from :trac:`11590` can be integrated:: - sage: x = SR.symbol('x', domain='real') - sage: result = integrate(x * sgn(x^2 - 1/4), x, -1, 0) + sage: x = SR.symbol('x', domain='real') # optional - sage.symbolic + sage: result = integrate(x * sgn(x^2 - 1/4), x, -1, 0) # optional - sage.symbolic ... - sage: result + sage: result # optional - sage.symbolic -1/4 """ @@ -787,11 +791,13 @@ def integral_closure(x): sage: integral_closure(QQ) Rational Field - sage: K. = QuadraticField(5) - sage: O2 = K.order(2*a); O2 - Order in Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? - sage: integral_closure(O2) - Maximal Order in Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? + sage: K. = QuadraticField(5) # optional - sage.rings.number_field + sage: O2 = K.order(2 * a); O2 # optional - sage.rings.number_field + Order in Number Field in a + with defining polynomial x^2 - 5 with a = 2.236067977499790? + sage: integral_closure(O2) # optional - sage.rings.number_field + Maximal Order in Number Field in a + with defining polynomial x^2 - 5 with a = 2.236067977499790? """ return x.integral_closure() @@ -874,9 +880,9 @@ def is_integrally_closed(x): doctest:...DeprecationWarning: use X.is_integrally_closed() See https://github.com/sagemath/sage/issues/32347 for details. True - sage: K. = NumberField(x^2 + 189*x + 394) - sage: R = K.order(2*a) - sage: is_integrally_closed(R) + sage: K. = NumberField(x^2 + 189*x + 394) # optional - sage.rings.number_field + sage: R = K.order(2*a) # optional - sage.rings.number_field + sage: is_integrally_closed(R) # optional - sage.rings.number_field False """ deprecation(32347, "use X.is_integrally_closed()") @@ -928,26 +934,26 @@ def kernel(x): EXAMPLES:: - sage: M = MatrixSpace(QQ,3,2) - sage: A = M([1,2,3,4,5,6]) - sage: kernel(A) + sage: M = MatrixSpace(QQ, 3, 2) # optional - sage.modules + sage: A = M([1,2, 3,4, 5,6]) # optional - sage.modules + sage: kernel(A) # optional - sage.modules Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: [ 1 -2 1] - sage: kernel(A.transpose()) + sage: kernel(A.transpose()) # optional - sage.modules Vector space of degree 2 and dimension 0 over Rational Field Basis matrix: [] Here are two corner cases:: - sage: M = MatrixSpace(QQ,0,3) - sage: A = M([]) - sage: kernel(A) + sage: M = MatrixSpace(QQ, 0, 3) # optional - sage.modules + sage: A = M([]) # optional - sage.modules + sage: kernel(A) # optional - sage.modules Vector space of degree 0 and dimension 0 over Rational Field Basis matrix: [] - sage: kernel(A.transpose()).basis() + sage: kernel(A.transpose()).basis() # optional - sage.modules [ (1, 0, 0), (0, 1, 0), @@ -967,9 +973,9 @@ def krull_dimension(x): 0 sage: krull_dimension(ZZ) 1 - sage: krull_dimension(ZZ[sqrt(5)]) + sage: krull_dimension(ZZ[sqrt(5)]) # optional - sage.rings.number_field sage.symbolic 1 - sage: U. = PolynomialRing(ZZ,3); U + sage: U. = PolynomialRing(ZZ, 3); U Multivariate Polynomial Ring in x, y, z over Integer Ring sage: U.krull_dimension() 4 @@ -991,8 +997,8 @@ def lift(x): We lift an element of a quotient polynomial ring:: sage: R. = QQ['x'] - sage: S. = R.quo(x^2 + 1) - sage: lift(xmod-7) + sage: S. = R.quo(x^2 + 1) # optional - sage.libs.pari + sage: lift(xmod - 7) # optional - sage.libs.pari x - 7 """ try: @@ -1049,24 +1055,24 @@ def log(*args, **kwds): 10 sage: RDF(log(1024, 2)) 10.0 - sage: log(10, 4) + sage: log(10, 4) # optional - sage.symbolic 1/2*log(10)/log(2) - sage: RDF(log(10, 4)) + sage: RDF(log(10, 4)) # optional - sage.symbolic 1.6609640474436813 - sage: log(10, 2) + sage: log(10, 2) # optional - sage.symbolic log(10)/log(2) - sage: n(log(10, 2)) + sage: n(log(10, 2)) # optional - sage.symbolic 3.32192809488736 - sage: log(10, e) + sage: log(10, e) # optional - sage.symbolic log(10) - sage: n(log(10, e)) + sage: n(log(10, e)) # optional - sage.symbolic 2.30258509299405 The log function works for negative numbers, complex numbers, and symbolic numbers too, picking the branch with angle between `-\\pi` and `\\pi`:: - sage: log(-1+0*I) + sage: log(-1+0*I) # optional - sage.symbolic I*pi sage: log(CC(-1)) 3.14159265358979*I @@ -1075,24 +1081,24 @@ def log(*args, **kwds): Small integer powers are factored out immediately:: - sage: log(4) + sage: log(4) # optional - sage.symbolic 2*log(2) - sage: log(1000000000) + sage: log(1000000000) # optional - sage.symbolic 9*log(10) - sage: log(8) - 3*log(2) + sage: log(8) - 3*log(2) # optional - sage.symbolic 0 - sage: bool(log(8) == 3*log(2)) + sage: bool(log(8) == 3*log(2)) # optional - sage.symbolic True The ``hold`` parameter can be used to prevent automatic evaluation:: - sage: log(-1,hold=True) + sage: log(-1, hold=True) # optional - sage.symbolic log(-1) - sage: log(-1) + sage: log(-1) # optional - sage.symbolic I*pi - sage: I.log(hold=True) + sage: I.log(hold=True) # optional - sage.symbolic log(I) - sage: I.log(hold=True).simplify() + sage: I.log(hold=True).simplify() # optional - sage.symbolic 1/2*I*pi For input zero, the following behavior occurs:: @@ -1107,27 +1113,27 @@ def log(*args, **kwds): The log function also works in finite fields as long as the argument lies in the multiplicative group generated by the base:: - sage: F = GF(13); g = F.multiplicative_generator(); g + sage: F = GF(13); g = F.multiplicative_generator(); g # optional - sage.rings.finite_rings 2 - sage: a = F(8) - sage: log(a,g); g^log(a,g) + sage: a = F(8) # optional - sage.rings.finite_rings + sage: log(a, g); g^log(a, g) # optional - sage.rings.finite_rings 3 8 - sage: log(a,3) + sage: log(a, 3) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: no logarithm of 8 found to base 3 modulo 13 - sage: log(F(9), 3) + sage: log(F(9), 3) # optional - sage.rings.finite_rings 2 The log function also works for p-adics (see documentation for p-adics for more information):: - sage: R = Zp(5); R + sage: R = Zp(5); R # optional - sage.rings.padics 5-adic Ring with capped relative precision 20 - sage: a = R(16); a + sage: a = R(16); a # optional - sage.rings.padics 1 + 3*5 + O(5^20) - sage: log(a) + sage: log(a) # optional - sage.rings.padics 3*5 + 3*5^2 + 3*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 2*5^8 + 5^9 + 5^11 + 2*5^12 + 5^13 + 3*5^15 + 2*5^16 + 4*5^17 + 3*5^18 + 3*5^19 + O(5^20) @@ -1137,26 +1143,26 @@ def log(*args, **kwds): Check if :trac:`10136` is fixed:: - sage: ln(x).operator() is ln + sage: ln(x).operator() is ln # optional - sage.symbolic True - sage: log(x).operator() is ln + sage: log(x).operator() is ln # optional - sage.symbolic True sage: log(1000, 10) 3 - sage: log(3,-1) + sage: log(3, -1) # optional - sage.symbolic -I*log(3)/pi - sage: log(int(8),2) + sage: log(int(8), 2) 3 - sage: log(8,int(2)) + sage: log(8, int(2)) 3 - sage: log(8,2) + sage: log(8, 2) 3 - sage: log(1/8,2) + sage: log(1/8, 2) -3 - sage: log(1/8,1/2) + sage: log(1/8, 1/2) 3 - sage: log(8,1/2) + sage: log(8, 1/2) -3 sage: log(1000, 10, base=5) @@ -1196,14 +1202,14 @@ def minimal_polynomial(x, var='x'): EXAMPLES:: - sage: a = matrix(ZZ, 2, [1..4]) - sage: minpoly(a) + sage: a = matrix(ZZ, 2, [1..4]) # optional - sage.modules + sage: minpoly(a) # optional - sage.libs.pari sage.modules x^2 - 5*x - 2 - sage: minpoly(a,'t') + sage: minpoly(a, 't') # optional - sage.libs.pari sage.modules t^2 - 5*t - 2 - sage: minimal_polynomial(a) + sage: minimal_polynomial(a) # optional - sage.libs.pari sage.modules x^2 - 5*x - 2 - sage: minimal_polynomial(a,'theta') + sage: minimal_polynomial(a, 'theta') # optional - sage.libs.pari sage.modules theta^2 - 5*theta - 2 """ try: @@ -1222,12 +1228,12 @@ def multiplicative_order(x): EXAMPLES:: - sage: a = mod(5,11) - sage: multiplicative_order(a) + sage: a = mod(5, 11) + sage: multiplicative_order(a) # optional - sage.libs.pari 5 - sage: multiplicative_order(mod(2,11)) + sage: multiplicative_order(mod(2, 11)) # optional - sage.libs.pari 10 - sage: multiplicative_order(mod(2,12)) + sage: multiplicative_order(mod(2, 12)) # optional - sage.libs.pari Traceback (most recent call last): ... ArithmeticError: multiplicative order of 2 not defined since it is not a unit modulo 12 @@ -1241,12 +1247,12 @@ def ngens(x): EXAMPLES:: - sage: R. = SR[]; R + sage: R. = SR[]; R # optional - sage.symbolic Multivariate Polynomial Ring in x, y over Symbolic Ring - sage: ngens(R) + sage: ngens(R) # optional - sage.symbolic 2 - sage: A = AbelianGroup(5, [5,5,7,8,9]) - sage: ngens(A) + sage: A = AbelianGroup(5, [5,5,7,8,9]) # optional - sage.groups + sage: ngens(A) # optional - sage.groups 5 sage: ngens(ZZ) 1 @@ -1317,24 +1323,24 @@ def norm(x): The norm of vectors:: - sage: z = 1 + 2*I - sage: norm(vector([z])) + sage: z = 1 + 2*I # optional - sage.modules sage.symbolic + sage: norm(vector([z])) # optional - sage.modules sage.symbolic sqrt(5) - sage: v = vector([-1,2,3]) - sage: norm(v) + sage: v = vector([-1,2,3]) # optional - sage.modules sage.symbolic + sage: norm(v) # optional - sage.modules sage.symbolic sqrt(14) - sage: _ = var("a b c d", domain='real') - sage: v = vector([a, b, c, d]) - sage: norm(v) + sage: _ = var("a b c d", domain='real') # optional - sage.modules sage.symbolic + sage: v = vector([a, b, c, d]) # optional - sage.modules sage.symbolic + sage: norm(v) # optional - sage.modules sage.symbolic sqrt(a^2 + b^2 + c^2 + d^2) The norm of matrices:: - sage: z = 1 + 2*I - sage: norm(matrix([[z]])) + sage: z = 1 + 2*I # optional - sage.modules + sage: norm(matrix([[z]])) # optional - sage.modules 2.23606797749979 - sage: M = matrix(ZZ, [[1,2,4,3], [-1,0,3,-10]]) - sage: norm(M) # abs tol 1e-14 + sage: M = matrix(ZZ, [[1,2,4,3], [-1,0,3,-10]]) # optional - sage.modules + sage: norm(M) # abs tol 1e-14 # optional - sage.modules 10.690331129154467 sage: norm(CDF(z)) 5.0 @@ -1354,17 +1360,17 @@ def norm(x): The complex norm of symbolic expressions:: - sage: a, b, c = var("a, b, c") - sage: assume((a, 'real'), (b, 'real'), (c, 'real')) - sage: z = a + b*I - sage: bool(norm(z).simplify() == a^2 + b^2) + sage: a, b, c = var("a, b, c") # optional - sage.symbolic + sage: assume((a, 'real'), (b, 'real'), (c, 'real')) # optional - sage.symbolic + sage: z = a + b*I # optional - sage.symbolic + sage: bool(norm(z).simplify() == a^2 + b^2) # optional - sage.symbolic True - sage: norm(a + b).simplify() + sage: norm(a + b).simplify() # optional - sage.symbolic a^2 + 2*a*b + b^2 - sage: v = vector([a, b, c]) - sage: bool(norm(v).simplify() == sqrt(a^2 + b^2 + c^2)) + sage: v = vector([a, b, c]) # optional - sage.symbolic + sage: bool(norm(v).simplify() == sqrt(a^2 + b^2 + c^2)) # optional - sage.symbolic True - sage: forget() + sage: forget() # optional - sage.symbolic """ return x.norm() @@ -1415,17 +1421,17 @@ def numerical_approx(x, prec=None, digits=None, algorithm=None): EXAMPLES:: - sage: numerical_approx(pi, 10) + sage: numerical_approx(pi, 10) # optional - sage.symbolic 3.1 - sage: numerical_approx(pi, digits=10) + sage: numerical_approx(pi, digits=10) # optional - sage.symbolic 3.141592654 - sage: numerical_approx(pi^2 + e, digits=20) + sage: numerical_approx(pi^2 + e, digits=20) # optional - sage.symbolic 12.587886229548403854 - sage: n(pi^2 + e) + sage: n(pi^2 + e) # optional - sage.symbolic 12.5878862295484 - sage: N(pi^2 + e) + sage: N(pi^2 + e) # optional - sage.symbolic 12.5878862295484 - sage: n(pi^2 + e, digits=50) + sage: n(pi^2 + e, digits=50) # optional - sage.symbolic 12.587886229548403854194778471228813633070946500941 sage: a = CC(-5).n(prec=40) sage: b = ComplexField(40)(-5) @@ -1438,45 +1444,45 @@ def numerical_approx(x, prec=None, digits=None, algorithm=None): You can also usually use method notation:: - sage: (pi^2 + e).n() + sage: (pi^2 + e).n() # optional - sage.symbolic 12.5878862295484 - sage: (pi^2 + e).numerical_approx() + sage: (pi^2 + e).numerical_approx() # optional - sage.symbolic 12.5878862295484 Vectors and matrices may also have their entries approximated:: - sage: v = vector(RDF, [1,2,3]) - sage: v.n() + sage: v = vector(RDF, [1,2,3]) # optional - sage.modules + sage: v.n() # optional - sage.modules (1.00000000000000, 2.00000000000000, 3.00000000000000) - sage: v = vector(CDF, [1,2,3]) - sage: v.n() + sage: v = vector(CDF, [1,2,3]) # optional - sage.modules + sage: v.n() # optional - sage.modules (1.00000000000000, 2.00000000000000, 3.00000000000000) - sage: _.parent() + sage: _.parent() # optional - sage.modules Vector space of dimension 3 over Complex Field with 53 bits of precision - sage: v.n(prec=20) + sage: v.n(prec=20) # optional - sage.modules (1.0000, 2.0000, 3.0000) - sage: u = vector(QQ, [1/2, 1/3, 1/4]) - sage: n(u, prec=15) + sage: u = vector(QQ, [1/2, 1/3, 1/4]) # optional - sage.modules + sage: n(u, prec=15) # optional - sage.modules (0.5000, 0.3333, 0.2500) - sage: n(u, digits=5) + sage: n(u, digits=5) # optional - sage.modules (0.50000, 0.33333, 0.25000) - sage: v = vector(QQ, [1/2, 0, 0, 1/3, 0, 0, 0, 1/4], sparse=True) - sage: u = v.numerical_approx(digits=4) - sage: u.is_sparse() + sage: v = vector(QQ, [1/2, 0, 0, 1/3, 0, 0, 0, 1/4], sparse=True) # optional - sage.modules + sage: u = v.numerical_approx(digits=4) # optional - sage.modules + sage: u.is_sparse() # optional - sage.modules True - sage: u + sage: u # optional - sage.modules (0.5000, 0.0000, 0.0000, 0.3333, 0.0000, 0.0000, 0.0000, 0.2500) - sage: A = matrix(QQ, 2, 3, range(6)) - sage: A.n() + sage: A = matrix(QQ, 2, 3, range(6)) # optional - sage.modules + sage: A.n() # optional - sage.modules [0.000000000000000 1.00000000000000 2.00000000000000] [ 3.00000000000000 4.00000000000000 5.00000000000000] - sage: B = matrix(Integers(12), 3, 8, srange(24)) - sage: N(B, digits=2) + sage: B = matrix(Integers(12), 3, 8, srange(24)) # optional - sage.modules + sage: N(B, digits=2) # optional - sage.modules [0.00 1.0 2.0 3.0 4.0 5.0 6.0 7.0] [ 8.0 9.0 10. 11. 0.00 1.0 2.0 3.0] [ 4.0 5.0 6.0 7.0 8.0 9.0 10. 11.] @@ -1485,13 +1491,13 @@ def numerical_approx(x, prec=None, digits=None, algorithm=None): Therefore, numbers which look the same in their decimal expansion might be different:: - sage: x=N(pi, digits=3); x + sage: x = N(pi, digits=3); x # optional - sage.symbolic 3.14 - sage: y=N(3.14, digits=3); y + sage: y = N(3.14, digits=3); y 3.14 - sage: x==y + sage: x == y # optional - sage.symbolic False - sage: x.str(base=2) + sage: x.str(base=2) # optional - sage.symbolic '11.001001000100' sage: y.str(base=2) '11.001000111101' @@ -1514,23 +1520,23 @@ def numerical_approx(x, prec=None, digits=None, algorithm=None): As an exceptional case, ``digits=1`` usually leads to 2 digits (one significant) in the decimal output (see :trac:`11647`):: - sage: N(pi, digits=1) + sage: N(pi, digits=1) # optional - sage.symbolic 3.2 - sage: N(pi, digits=2) + sage: N(pi, digits=2) # optional - sage.symbolic 3.1 - sage: N(100*pi, digits=1) + sage: N(100*pi, digits=1) # optional - sage.symbolic 320. - sage: N(100*pi, digits=2) + sage: N(100*pi, digits=2) # optional - sage.symbolic 310. In the following example, ``pi`` and ``3`` are both approximated to two bits of precision and then subtracted, which kills two bits of precision:: - sage: N(pi, prec=2) + sage: N(pi, prec=2) # optional - sage.symbolic 3.0 sage: N(3, prec=2) 3.0 - sage: N(pi - 3, prec=2) + sage: N(pi - 3, prec=2) # optional - sage.symbolic 0.00 TESTS:: @@ -1538,8 +1544,8 @@ def numerical_approx(x, prec=None, digits=None, algorithm=None): sage: numerical_approx(I) 1.00000000000000*I sage: x = QQ['x'].gen() - sage: F. = NumberField(x^2+2, embedding=sqrt(CC(2))*CC.0) - sage: numerical_approx(k) + sage: F. = NumberField(x^2 + 2, embedding=sqrt(CC(2))*CC.0) # optional - sage.rings.number_field sage.symbolic + sage: numerical_approx(k) # optional - sage.rings.number_field sage.symbolic 1.41421356237309*I sage: type(numerical_approx(CC(1/2))) @@ -1548,11 +1554,11 @@ def numerical_approx(x, prec=None, digits=None, algorithm=None): The following tests :trac:`10761`, in which ``n()`` would break when called on complex-valued algebraic numbers. :: - sage: E = matrix(3, [3,1,6,5,2,9,7,3,13]).eigenvalues(); E + sage: E = matrix(3, [3,1,6,5,2,9,7,3,13]).eigenvalues(); E # optional - sage.modules sage.rings.number_field [18.16815365088822?, -0.08407682544410650? - 0.2190261484802906?*I, -0.08407682544410650? + 0.2190261484802906?*I] - sage: E[1].parent() + sage: E[1].parent() # optional - sage.modules sage.rings.number_field Algebraic Field - sage: [a.n() for a in E] + sage: [a.n() for a in E] # optional - sage.modules sage.rings.number_field [18.1681536508882, -0.0840768254441065 - 0.219026148480291*I, -0.0840768254441065 + 0.219026148480291*I] Make sure we've rounded up log(10,2) enough to guarantee @@ -1628,11 +1634,11 @@ def order(x): EXAMPLES:: - sage: C = CyclicPermutationGroup(10) - sage: order(C) + sage: C = CyclicPermutationGroup(10) # optional - sage.groups + sage: order(C) # optional - sage.groups 10 - sage: F = GF(7) - sage: order(F) + sage: F = GF(7) # optional - sage.rings.finite_rings + sage: order(F) # optional - sage.rings.finite_rings 7 """ return x.order() @@ -1646,9 +1652,9 @@ def rank(x): We compute the rank of a matrix:: - sage: M = MatrixSpace(QQ,3,3) - sage: A = M([1,2,3,4,5,6,7,8,9]) - sage: rank(A) + sage: M = MatrixSpace(QQ, 3, 3) # optional - sage.modules + sage: A = M([1,2,3, 4,5,6, 7,8,9]) # optional - sage.modules + sage: rank(A) # optional - sage.modules 2 We compute the rank of an elliptic curve:: @@ -1666,7 +1672,7 @@ def regulator(x): EXAMPLES:: - sage: regulator(NumberField(x^2-2, 'a')) + sage: regulator(NumberField(x^2 - 2, 'a')) # optional - sage.rings.number_field 0.881373587019543 sage: regulator(EllipticCurve('11a')) 1.00000000000000 @@ -1684,17 +1690,17 @@ def round(x, ndigits=0): EXAMPLES:: - sage: round(sqrt(2),2) + sage: round(sqrt(2), 2) # optional - sage.symbolic 1.41 - sage: q = round(sqrt(2),5); q + sage: q = round(sqrt(2), 5); q # optional - sage.symbolic 1.41421 - sage: type(q) + sage: type(q) # optional - sage.symbolic - sage: q = round(sqrt(2)); q + sage: q = round(sqrt(2)); q # optional - sage.symbolic 1 - sage: type(q) + sage: type(q) # optional - sage.symbolic - sage: round(pi) + sage: round(pi) # optional - sage.symbolic 3 sage: b = 5.4999999999999999 sage: round(b) @@ -1708,7 +1714,7 @@ def round(x, ndigits=0): Since we use floating-point with a limited range, some roundings can't be performed:: - sage: round(sqrt(Integer('1'*1000)),2) + sage: round(sqrt(Integer('1'*1000)), 2) # optional - sage.symbolic +infinity IMPLEMENTATION: If ndigits is specified, it calls Python's builtin @@ -1746,13 +1752,13 @@ def quotient(x, y, *args, **kwds): EXAMPLES:: - sage: quotient(5,6) + sage: quotient(5, 6) 5/6 - sage: quotient(5.,6.) + sage: quotient(5., 6.) 0.833333333333333 sage: R. = ZZ[]; R Univariate Polynomial Ring in x over Integer Ring - sage: I = Ideal(R, x^2+1) + sage: I = Ideal(R, x^2 + 1) sage: quotient(R, I) Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1 """ @@ -1806,7 +1812,7 @@ def squarefree_part(x): sage: x = QQ['x'].0 sage: S = squarefree_part(-9*x*(x-6)^7*(x-3)^2); S -9*x^2 + 54*x - sage: S.factor() + sage: S.factor() # optional - sage.libs.pari (-9) * (x - 6) * x :: @@ -1815,7 +1821,7 @@ def squarefree_part(x): x^10 - x^9 + 3*x^8 + 3*x^5 - 2*x^4 - x^3 - 2*x - 1 sage: g = squarefree_part(f); g x^4 - x^3 + x^2 - 1 - sage: g.factor() + sage: g.factor() # optional - sage.libs.pari (x - 1) * (x^3 + x + 1) """ try: @@ -1861,16 +1867,16 @@ def _do_sqrt(x, prec=None, extend=True, all=False): sage: from sage.misc.functional import _do_sqrt sage: _do_sqrt(3) sqrt(3) - sage: _do_sqrt(3,prec=10) + sage: _do_sqrt(3, prec=10) 1.7 - sage: _do_sqrt(3,prec=100) + sage: _do_sqrt(3, prec=100) 1.7320508075688772935274463415 - sage: _do_sqrt(3,all=True) + sage: _do_sqrt(3, all=True) # optional - sage.symbolic [sqrt(3), -sqrt(3)] Note that the extend parameter is ignored in the symbolic ring:: - sage: _do_sqrt(3,extend=False) + sage: _do_sqrt(3, extend=False) # optional - sage.symbolic sqrt(3) """ if prec: @@ -1915,23 +1921,23 @@ def sqrt(x, *args, **kwds): sage: sqrt(-1) I - sage: sqrt(2) + sage: sqrt(2) # optional - sage.symbolic sqrt(2) - sage: sqrt(2)^2 + sage: sqrt(2)^2 # optional - sage.symbolic 2 sage: sqrt(4) 2 - sage: sqrt(4,all=True) + sage: sqrt(4, all=True) [2, -2] - sage: sqrt(x^2) + sage: sqrt(x^2) # optional - sage.symbolic sqrt(x^2) For a non-symbolic square root, there are a few options. The best is to numerically approximate afterward:: - sage: sqrt(2).n() + sage: sqrt(2).n() # optional - sage.symbolic 1.41421356237310 - sage: sqrt(2).n(prec=100) + sage: sqrt(2).n(prec=100) # optional - sage.symbolic 1.4142135623730950488016887242 Or one can input a numerical type:: @@ -1946,9 +1952,9 @@ def sqrt(x, *args, **kwds): To prevent automatic evaluation, one can use the ``hold`` parameter after coercing to the symbolic ring:: - sage: sqrt(SR(4),hold=True) + sage: sqrt(SR(4), hold=True) # optional - sage.symbolic sqrt(4) - sage: sqrt(4,hold=True) + sage: sqrt(4, hold=True) Traceback (most recent call last): ... TypeError: ..._do_sqrt() got an unexpected keyword argument 'hold' @@ -1967,9 +1973,9 @@ def sqrt(x, *args, **kwds): One can use numpy input as well:: - sage: import numpy - sage: a = numpy.arange(2,5) - sage: sqrt(a) + sage: import numpy # optional - numpy + sage: a = numpy.arange(2,5) # optional - numpy + sage: sqrt(a) # optional - numpy array([1.41421356, 1.73205081, 2. ]) """ if isinstance(x, float): @@ -1993,8 +1999,8 @@ def transpose(x): EXAMPLES:: - sage: M = MatrixSpace(QQ,3,3) - sage: A = M([1,2,3,4,5,6,7,8,9]) + sage: M = MatrixSpace(QQ, 3, 3) # optional - sage.modules + sage: A = M([1,2,3, 4,5,6, 7,8,9]) # optional - sage.modules sage: transpose(A) [1 4 7] [2 5 8] diff --git a/src/sage/misc/inline_fortran.py b/src/sage/misc/inline_fortran.py index 6e71016c427..b10394630d1 100644 --- a/src/sage/misc/inline_fortran.py +++ b/src/sage/misc/inline_fortran.py @@ -112,10 +112,10 @@ def eval(self, x, globals=None, locals=None): ....: C END FILE FIB1.F ....: ''' sage: fortran(code, globals()) - sage: import numpy - sage: a = numpy.array(range(10), dtype=float) - sage: fib(a, 10) - sage: a + sage: import numpy # optional - numpy + sage: a = numpy.array(range(10), dtype=float) # optional - numpy + sage: fib(a, 10) # optional - numpy + sage: a # optional - numpy array([ 0., 1., 1., 2., 3., 5., 8., 13., 21., 34.]) TESTS:: diff --git a/src/sage/misc/instancedoc.pyx b/src/sage/misc/instancedoc.pyx index 360d3f768b3..85a22a0b792 100644 --- a/src/sage/misc/instancedoc.pyx +++ b/src/sage/misc/instancedoc.pyx @@ -36,7 +36,8 @@ EXAMPLES:: For a Cython ``cdef class``, a decorator cannot be used. Instead, call :func:`instancedoc` as a function after defining the class:: - sage: cython(''' + sage: cython( # optional - sage.misc.cython + ....: ''' ....: from sage.misc.instancedoc import instancedoc ....: cdef class Y: ....: "Class docstring" @@ -44,9 +45,9 @@ For a Cython ``cdef class``, a decorator cannot be used. Instead, call ....: return "Instance docstring" ....: instancedoc(Y) ....: ''') - sage: Y.__doc__ + sage: Y.__doc__ # optional - sage.misc.cython 'File:...\nClass docstring' - sage: Y().__doc__ + sage: Y().__doc__ # optional - sage.misc.cython 'Instance docstring' One can still add a custom ``__doc__`` attribute on a particular @@ -59,7 +60,7 @@ instance:: This normally does not work on extension types:: - sage: Y().__doc__ = "Very special doc" + sage: Y().__doc__ = "Very special doc" # optional - sage.misc.cython Traceback (most recent call last): ... AttributeError: attribute '__doc__' of 'Y' objects is not writable diff --git a/src/sage/misc/latex.py b/src/sage/misc/latex.py index 5dc3fbe5ecd..4f36be67822 100644 --- a/src/sage/misc/latex.py +++ b/src/sage/misc/latex.py @@ -184,7 +184,8 @@ def list_function(x): '\\left[1, 2, 3\\right]' sage: latex([1,2,3]) # indirect doctest \left[1, 2, 3\right] - sage: latex([Matrix(ZZ,3,range(9)), Matrix(ZZ,3,range(9))]) # indirect doctest + sage: latex([Matrix(ZZ, 3, range(9)), # indirect doctest # optional - sage.modules + ....: Matrix(ZZ, 3, range(9))]) \left[\left(\begin{array}{rrr} 0 & 1 & 2 \\ 3 & 4 & 5 \\ @@ -367,11 +368,11 @@ def dict_function(x): EXAMPLES:: sage: from sage.misc.latex import dict_function - sage: x,y,z = var('x,y,z') - sage: print(dict_function({x/2: y^2})) + sage: x,y,z = var('x,y,z') # optional - sage.symbolic + sage: print(dict_function({x/2: y^2})) # optional - sage.symbolic \left\{\frac{1}{2} \, x : y^{2}\right\} - sage: d = {(1,2,x^2): [sin(z^2), y/2]} - sage: latex(d) + sage: d = {(1,2,x^2): [sin(z^2), y/2]} # optional - sage.symbolic + sage: latex(d) # optional - sage.symbolic \left\{\left(1, 2, x^{2}\right) : \left[\sin\left(z^{2}\right), \frac{1}{2} \, y\right]\right\} """ @@ -450,9 +451,9 @@ class LatexExpr(str): EXAMPLES:: - sage: latex(x^20 + 1) + sage: latex(x^20 + 1) # optional - sage.symbolic x^{20} + 1 - sage: LatexExpr(r"\frac{x^2 + 1}{x - 2}") + sage: LatexExpr(r"\frac{x^2 + 1}{x - 2}") # optional - sage.symbolic \frac{x^2 + 1}{x - 2} ``LatexExpr`` simply converts to string without doing anything @@ -465,15 +466,15 @@ class LatexExpr(str): The result of :func:`latex` is of type ``LatexExpr``:: - sage: L = latex(x^20 + 1) - sage: L + sage: L = latex(x^20 + 1) # optional - sage.symbolic + sage: L # optional - sage.symbolic x^{20} + 1 - sage: type(L) + sage: type(L) # optional - sage.symbolic A ``LatexExpr`` can be converted to a plain string:: - sage: str(latex(x^20 + 1)) + sage: str(latex(x^20 + 1)) # optional - sage.symbolic 'x^{20} + 1' """ def __add__(self, other): @@ -558,7 +559,7 @@ def has_latex_attr(x) -> bool: EXAMPLES:: sage: from sage.misc.latex import has_latex_attr - sage: has_latex_attr(identity_matrix(3)) + sage: has_latex_attr(identity_matrix(3)) # optional - sage.modules True sage: has_latex_attr("abc") # strings have no _latex_ method False @@ -566,15 +567,15 @@ def has_latex_attr(x) -> bool: Types inherit the ``_latex_`` method of the class to which they refer, but calling it is broken:: - sage: T = type(identity_matrix(3)); T + sage: T = type(identity_matrix(3)); T # optional - sage.modules - sage: hasattr(T, '_latex_') + sage: hasattr(T, '_latex_') # optional - sage.modules True - sage: T._latex_() + sage: T._latex_() # optional - sage.modules Traceback (most recent call last): ... TypeError: ..._latex_... needs an argument - sage: has_latex_attr(T) + sage: has_latex_attr(T) # optional - sage.modules False """ return hasattr(x, '_latex_') and not isinstance(x, type) @@ -917,12 +918,12 @@ def __call__(self, x, combine_all=False): 3 sage: latex(1==0) \mathrm{False} - sage: print(latex([x,2])) + sage: print(latex([x, 2])) # optional - sage.symbolic \left[x, 2\right] Check that :trac:`11775` is fixed:: - sage: latex((x,2), combine_all=True) + sage: latex((x,2), combine_all=True) # optional - sage.symbolic x 2 """ if has_latex_attr(x): @@ -961,9 +962,9 @@ class Latex(LatexCall): EXAMPLES:: - sage: latex(x^20 + 1) + sage: latex(x^20 + 1) # optional - sage.symbolic x^{20} + 1 - sage: latex(FiniteField(25,'a')) + sage: latex(FiniteField(25,'a')) # optional - sage.libs.pari \Bold{F}_{5^{2}} sage: latex("hello") \text{\texttt{hello}} @@ -973,7 +974,7 @@ class Latex(LatexCall): LaTeX expressions can be added; note that a space is automatically inserted:: - sage: LatexExpr(r"y \neq") + latex(x^20 + 1) + sage: LatexExpr(r"y \neq") + latex(x^20 + 1) # optional - sage.symbolic y \neq x^{20} + 1 """ def __init__(self, debug=False, slide=False, density=150, pdflatex=None, engine=None): @@ -1212,18 +1213,18 @@ def matrix_delimiters(self, left=None, right=None): EXAMPLES:: - sage: a = matrix(1, 1, [17]) - sage: latex(a) + sage: a = matrix(1, 1, [17]) # optional - sage.modules + sage: latex(a) # optional - sage.modules \left(\begin{array}{r} 17 \end{array}\right) sage: latex.matrix_delimiters("[", "]") - sage: latex(a) + sage: latex(a) # optional - sage.modules \left[\begin{array}{r} 17 \end{array}\right] sage: latex.matrix_delimiters(left="\\{") - sage: latex(a) + sage: latex(a) # optional - sage.modules \left\{\begin{array}{r} 17 \end{array}\right] @@ -1273,14 +1274,14 @@ def vector_delimiters(self, left=None, right=None): EXAMPLES:: - sage: a = vector(QQ, [1,2,3]) - sage: latex(a) + sage: a = vector(QQ, [1,2,3]) # optional - sage.modules + sage: latex(a) # optional - sage.modules \left(1,\,2,\,3\right) sage: latex.vector_delimiters("[", "]") - sage: latex(a) + sage: latex(a) # optional - sage.modules \left[1,\,2,\,3\right] sage: latex.vector_delimiters(right="\\}") - sage: latex(a) + sage: latex(a) # optional - sage.modules \left[1,\,2,\,3\right\} sage: latex.vector_delimiters() ['[', '\\}'] @@ -1318,18 +1319,18 @@ def matrix_column_alignment(self, align=None): EXAMPLES:: - sage: a = matrix(1, 1, [42]) - sage: latex(a) + sage: a = matrix(1, 1, [42]) # optional - sage.modules + sage: latex(a) # optional - sage.modules \left(\begin{array}{r} 42 \end{array}\right) sage: latex.matrix_column_alignment('c') - sage: latex(a) + sage: latex(a) # optional - sage.modules \left(\begin{array}{c} 42 \end{array}\right) sage: latex.matrix_column_alignment('l') - sage: latex(a) + sage: latex(a) # optional - sage.modules \left(\begin{array}{l} 42 \end{array}\right) @@ -2019,7 +2020,7 @@ def coeff_repr(c): sage: from sage.misc.latex import coeff_repr sage: coeff_repr(QQ(1/2)) '\\frac{1}{2}' - sage: coeff_repr(-x^2) + sage: coeff_repr(-x^2) # optional - sage.symbolic '\\left(-x^{2}\\right)' """ try: @@ -2198,8 +2199,8 @@ def latex_varify(a, is_fname=False): TESTS: - sage: abc = var('abc') - sage: latex((abc/(abc+1)+42)/(abc-1)) # trac #15870 + sage: abc = var('abc') # optional - sage.symbolic + sage: latex((abc/(abc+1)+42)/(abc-1)) # trac #15870 # optional - sage.symbolic \frac{\frac{\mathit{abc}}{\mathit{abc} + 1} + 42}{\mathit{abc} - 1} """ if a in common_varnames: @@ -2270,12 +2271,12 @@ def latex_variable_name(x, is_fname=False): TESTS:: - sage: latex_variable_name('_C') # trac #16007 + sage: latex_variable_name('_C') # trac #16007 # optional - sage.symbolic 'C' - sage: latex_variable_name('_K1') + sage: latex_variable_name('_K1') # optional - sage.symbolic 'K_{1}' - sage: latex_variable_name('5') + sage: latex_variable_name('5') # optional - sage.symbolic '5' """ # if x is an integer (it might be the case for padics), we return x diff --git a/src/sage/misc/latex_standalone.py b/src/sage/misc/latex_standalone.py index cd42519c5ec..9c5604d379f 100644 --- a/src/sage/misc/latex_standalone.py +++ b/src/sage/misc/latex_standalone.py @@ -156,35 +156,36 @@ tikzpicture code generated by Sage from some polyhedron:: sage: from sage.misc.latex_standalone import TikzPicture - sage: V = [[1,0,1],[1,0,0],[1,1,0],[0,0,-1],[0,1,0],[-1,0,0],[0,1,1],[0,0,1],[0,-1,0]] - sage: P = Polyhedron(vertices=V).polar() - sage: s = P.projection().tikz([674,108,-731],112, output_type='LatexExpr') - sage: t = TikzPicture(s) + sage: V = [[1,0,1], [1,0,0], [1,1,0], [0,0,-1], + ....: [0,1,0], [-1,0,0], [0,1,1], [0,0,1], [0,-1,0]] + sage: P = Polyhedron(vertices=V).polar() # optional - sage.geometry.polyhedron + sage: s = P.projection().tikz([674,108,-731],112, output_type='LatexExpr') # optional - sage.geometry.polyhedron sage.plot + sage: t = TikzPicture(s) # optional - sage.geometry.polyhedron sage.plot Open the image in a viewer (the returned value is a string giving the absolute path to the file in some temporary directory):: - sage: path_to_file = t.pdf() # not tested + sage: path_to_file = t.pdf() # not tested # optional - sage.geometry.polyhedron sage.plot Instead, you may save a pdf of the tikzpicture into a file of your choice (but this does not open the viewer):: - sage: _ = t.pdf('tikz_polytope.pdf') # not tested + sage: _ = t.pdf('tikz_polytope.pdf') # not tested # optional - sage.geometry.polyhedron sage.plot Opening the image in a viewer can be turned off:: - sage: _ = t.pdf(view=False) # long time (2s) # optional latex + sage: _ = t.pdf(view=False) # long time (2s) # optional latex # optional - sage.geometry.polyhedron sage.plot The same can be done with png format (translated from pdf with convert command which needs the installation of imagemagick):: - sage: _ = t.png(view=False) # long time (2s) # optional latex imagemagick + sage: _ = t.png(view=False) # long time (2s) # optional latex imagemagick # optional - sage.geometry.polyhedron sage.plot The string representation gives the header (5 lines) and tail (5 lines) of the tikzpicture. In Jupyter, it will instead use rich representation and show the image directly below the cell in png or svg format:: - sage: t + sage: t # optional - sage.geometry.polyhedron sage.plot \documentclass[tikz]{standalone} \begin{document} \begin{tikzpicture}% @@ -201,21 +202,22 @@ Use ``print(t)`` to see the complete content of the file:: - sage: print(t) # not tested + sage: print(t) # not tested # optional - sage.geometry.polyhedron sage.plot Adding a border in the options avoids cropping the vertices of a graph:: - sage: g = graphs.PetersenGraph() # optional - sage.graphs - sage: s = latex(g) # takes 3s but the result is cached # optional latex sage.graphs - sage: t = TikzPicture(s, standalone_config=["border=4mm"], usepackage=['tkz-graph']) # optional latex sage.graphs + sage: g = graphs.PetersenGraph() # optional - sage.graphs + sage: s = latex(g) # takes 3s but the result is cached # optional - latex sage.graphs + sage: t = TikzPicture(s, standalone_config=["border=4mm"], # optional - latex sage.graphs + ....: usepackage=['tkz-graph']) sage: _ = t.pdf() # not tested The current latex representation of a transducer is a tikzpicture using the tikz library automata. The string can be used as input:: - sage: s = latex(transducers.GrayCode()) # optional sage.combinat - sage: t = TikzPicture(s, usetikzlibrary=['automata']) # optional sage.combinat - sage: _ = t.pdf(view=False) # long time (2s) # optional sage.combinat latex + sage: s = latex(transducers.GrayCode()) # optional - sage.combinat + sage: t = TikzPicture(s, usetikzlibrary=['automata']) # optional - sage.combinat + sage: _ = t.pdf(view=False) # long time (2s) # optional - latex sage.combinat AUTHORS: @@ -1467,17 +1469,17 @@ def from_dot_string(cls, dotdata, prog='dot'): :: - sage: W = CoxeterGroup(["A",2]) - sage: G = W.cayley_graph() # optional sage.graphs - sage: dotdata = G.graphviz_string() # optional sage.graphs - sage: tikz = TikzPicture.from_dot_string(dotdata) # optional sage.graphs dot2tex graphviz # long time (3s) - sage: _ = tikz.pdf() # not tested + sage: W = CoxeterGroup(["A",2]) # optional - sage.combinat sage.groups + sage: G = W.cayley_graph() # optional sage.graphs # optional - sage.combinat sage.groups + sage: dotdata = G.graphviz_string() # optional sage.graphs # optional - sage.combinat sage.groups + sage: tikz = TikzPicture.from_dot_string(dotdata) # optional sage.graphs dot2tex graphviz # long time (3s) # optional - sage.combinat sage.groups + sage: _ = tikz.pdf() # not tested # optional - sage.combinat sage.groups :: - sage: dotdata = G.graphviz_string(labels='latex') # optional sage.graphs - sage: tikz = TikzPicture.from_dot_string(dotdata) # optional sage.graphs dot2tex graphviz # long time (3s) - sage: _ = tikz.pdf() # not tested + sage: dotdata = G.graphviz_string(labels='latex') # optional sage.graphs # optional - sage.combinat sage.groups + sage: tikz = TikzPicture.from_dot_string(dotdata) # optional sage.graphs dot2tex graphviz # long time (3s) # optional - sage.combinat sage.groups + sage: _ = tikz.pdf() # not tested # optional - sage.combinat sage.groups """ from sage.features import PythonModule @@ -1558,11 +1560,11 @@ def from_graph(cls, graph, merge_multiedges=True, Using ``merge_multiedges``:: - sage: alpha = var('alpha') - sage: m = matrix(2,range(4)); m.set_immutable() - sage: G = DiGraph([(0,1,alpha), (0,1,0), (0,2,9), (0,2,m)], multiedges=True) # optional sage.graphs - sage: tikz = TikzPicture.from_graph(G, merge_multiedges=True) # optional sage.graphs dot2tex graphviz - sage: _ = tikz.pdf() # not tested + sage: alpha = var('alpha') # optional - sage.symbolic + sage: m = matrix(2, range(4)); m.set_immutable() # optional - sage.symbolic sage.modules + sage: G = DiGraph([(0,1,alpha), (0,1,0), (0,2,9), (0,2,m)], multiedges=True) # optional sage.graphs # optional - sage.symbolic sage.modules + sage: tikz = TikzPicture.from_graph(G, merge_multiedges=True) # optional sage.graphs dot2tex graphviz # optional - sage.symbolic sage.modules + sage: _ = tikz.pdf() # not tested # optional - sage.symbolic sage.modules Using ``merge_multiedges`` with ``merge_label_function``:: @@ -1576,18 +1578,18 @@ def from_graph(cls, graph, merge_multiedges=True, Using subgraphs clusters (broken when using labels, see :trac:`22070`):: - sage: S = FiniteSetMaps(5) - sage: I = S((0,1,2,3,4)) - sage: a = S((0,1,3,0,0)) - sage: b = S((0,2,4,1,0)) - sage: roots = [I] - sage: succ = lambda v:[v*a,v*b,a*v,b*v] - sage: R = RecursivelyEnumeratedSet(roots, succ) - sage: G = R.to_digraph() # optional sage.graphs - sage: G # optional sage.graphs + sage: S = FiniteSetMaps(5) # optional - sage.combinat + sage: I = S((0,1,2,3,4)) # optional - sage.combinat + sage: a = S((0,1,3,0,0)) # optional - sage.combinat + sage: b = S((0,2,4,1,0)) # optional - sage.combinat + sage: roots = [I] # optional - sage.combinat + sage: succ = lambda v: [v*a,v*b,a*v,b*v] # optional - sage.combinat + sage: R = RecursivelyEnumeratedSet(roots, succ) # optional - sage.combinat + sage: G = R.to_digraph() # optional - sage.graphs # optional - sage.combinat + sage: G # optional - sage.graphs # optional - sage.combinat Looped multi-digraph on 27 vertices - sage: C = G.strongly_connected_components() # optional sage.graphs - sage: tikz = TikzPicture.from_graph(G, # optional sage.graphs dot2tex graphviz + sage: C = G.strongly_connected_components() # optional - sage.graphs # optional - sage.combinat + sage: tikz = TikzPicture.from_graph(G, # optional - dot2tex graphviz sage.combinat sage.graphs ....: merge_multiedges=False, subgraph_clusters=C) sage: _ = tikz.pdf() # not tested diff --git a/src/sage/misc/lazy_import.pyx b/src/sage/misc/lazy_import.pyx index d4a6c12ed5a..7f2c76b3ffa 100644 --- a/src/sage/misc/lazy_import.pyx +++ b/src/sage/misc/lazy_import.pyx @@ -350,7 +350,7 @@ cdef class LazyImport(): sage: from sage.misc.lazy_import import LazyImport sage: rm = LazyImport('sage.matrix.special', 'random_matrix') - sage: rm._sage_argspec_() + sage: rm._sage_argspec_() # optional - sage.modules FullArgSpec(args=['ring', 'nrows', 'ncols', 'algorithm', 'implementation'], varargs='args', varkw='kwds', defaults=(None, 'randomize', None), kwonlyargs=[], kwonlydefaults=None, annotations={}) @@ -526,12 +526,12 @@ cdef class LazyImport(): We access the ``plot`` method:: - sage: Bar.plot + sage: Bar.plot # optional - sage.plot Now ``plot`` has been replaced in the dictionary of ``Foo``:: - sage: type(Foo.__dict__['plot']) + sage: type(Foo.__dict__['plot']) # optional - sage.plot <... 'function'> """ # Don't use the namespace of the class definition @@ -662,11 +662,11 @@ cdef class LazyImport(): """ TESTS:: - sage: from sympy import Matrix + sage: from sympy import Matrix # optional - sympy sage: import sage.all__sagemath_objects - sage: sage.all__sagemath_objects.foo = Matrix([[1,1],[0,1]]) - sage: lazy_import('sage.all__sagemath_objects', 'foo') - sage: foo.__matmul__(foo) + sage: sage.all__sagemath_objects.foo = Matrix([[1,1], [0,1]]) # optional - sympy + sage: lazy_import('sage.all__sagemath_objects', 'foo') # optional - sympy + sage: foo.__matmul__(foo) # optional - sympy Matrix([ [1, 2], [0, 1]]) @@ -1059,24 +1059,27 @@ def lazy_import(module, names, as_=None, *, ....: pass sage: type(Foo.__dict__['plot']) - sage: 'EXAMPLES' in Bar.plot.__doc__ + sage: 'EXAMPLES' in Bar.plot.__doc__ # optional - sage.plot True sage: type(Foo.__dict__['plot']) <... 'function'> If deprecated then a deprecation warning is issued:: - sage: lazy_import('sage.rings.padics.factory', 'Qp', 'my_Qp', deprecation=14275) - sage: my_Qp(5) + sage: lazy_import('sage.rings.padics.factory', 'Qp', 'my_Qp', + ....: deprecation=14275) + sage: my_Qp(5) # optional - sage.rings.padics doctest:...: DeprecationWarning: - Importing my_Qp from here is deprecated; please use "from sage.rings.padics.factory import Qp as my_Qp" instead. + Importing my_Qp from here is deprecated; + please use "from sage.rings.padics.factory import Qp as my_Qp" instead. See https://github.com/sagemath/sage/issues/14275 for details. 5-adic Field with capped relative precision 20 An example of deprecation with a message:: - sage: lazy_import('sage.rings.padics.factory', 'Qp', 'my_Qp_msg', deprecation=(14275, "This is an example.")) - sage: my_Qp_msg(5) + sage: lazy_import('sage.rings.padics.factory', 'Qp', 'my_Qp_msg', + ....: deprecation=(14275, "This is an example.")) + sage: my_Qp_msg(5) # optional - sage.rings.padics doctest:...: DeprecationWarning: This is an example. See https://github.com/sagemath/sage/issues/14275 for details. 5-adic Field with capped relative precision 20 @@ -1084,13 +1087,16 @@ def lazy_import(module, names, as_=None, *, An example of an import relying on a feature:: sage: from sage.features import PythonModule - sage: lazy_import('ppl', 'equation', feature=PythonModule('ppl', spkg='pplpy')) - sage: equation + sage: lazy_import('ppl', 'equation', + ....: feature=PythonModule('ppl', spkg='pplpy')) + sage: equation # optional - pplpy - sage: lazy_import('PyNormaliz', 'NmzListConeProperties', feature=PythonModule('PyNormaliz', spkg='pynormaliz')) # optional - pynormaliz - sage: NmzListConeProperties # optional - pynormaliz + sage: lazy_import('PyNormaliz', 'NmzListConeProperties', + ....: feature=PythonModule('PyNormaliz', spkg='pynormaliz')) + sage: NmzListConeProperties # optional - pynormaliz - sage: lazy_import('foo', 'not_there', feature=PythonModule('foo', spkg='non-existing-package')) + sage: lazy_import('foo', 'not_there', + ....: feature=PythonModule('foo', spkg='non-existing-package')) sage: not_there Failed lazy import: foo is not available. @@ -1243,15 +1249,15 @@ def clean_namespace(namespace=None): EXAMPLES:: sage: from sage.misc.lazy_import import attributes, clean_namespace - sage: from sage.calculus.calculus import maxima as C - sage: attributes(C)['_as_name'] + sage: from sage.calculus.calculus import maxima as C # optional - sage.symbolic + sage: attributes(C)['_as_name'] # optional - sage.symbolic 'maxima' - sage: attributes(C)['_namespace'] is sage.calculus.calculus.__dict__ + sage: attributes(C)['_namespace'] is sage.calculus.calculus.__dict__ # optional - sage.symbolic True - sage: clean_namespace(globals()) - sage: attributes(C)['_as_name'] + sage: clean_namespace(globals()) # optional - sage.symbolic + sage: attributes(C)['_as_name'] # optional - sage.symbolic 'C' - sage: attributes(C)['_namespace'] is globals() + sage: attributes(C)['_namespace'] is globals() # optional - sage.symbolic True """ cdef LazyImport w diff --git a/src/sage/misc/lazy_list.pyx b/src/sage/misc/lazy_list.pyx index 4e25ee39299..4888db138d0 100644 --- a/src/sage/misc/lazy_list.pyx +++ b/src/sage/misc/lazy_list.pyx @@ -11,11 +11,11 @@ EXAMPLES:: sage: from sage.misc.lazy_list import lazy_list sage: P = lazy_list(Primes()) - sage: P[100] + sage: P[100] # optional - sage.libs.pari 547 - sage: P[10:34] + sage: P[10:34] # optional - sage.libs.pari lazy list [31, 37, 41, ...] - sage: P[12:23].list() + sage: P[12:23].list() # optional - sage.libs.pari [41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83] sage: f = lazy_list((i**2 - 3*i for i in range(10))) @@ -306,23 +306,23 @@ def lazy_list_formatter(L, name='lazy list', :: sage: from sage.misc.lazy_list import lazy_list - sage: L = lazy_list(Primes()); L + sage: L = lazy_list(Primes()); L # optional - sage.libs.pari lazy list [2, 3, 5, ...] - sage: repr(L) == lazy_list_formatter(L) + sage: repr(L) == lazy_list_formatter(L) # optional - sage.libs.pari True - sage: lazy_list_formatter(L, name='primes') + sage: lazy_list_formatter(L, name='primes') # optional - sage.libs.pari 'primes [2, 3, 5, ...]' - sage: lazy_list_formatter(L, opening_delimiter='(', closing_delimiter=')') + sage: lazy_list_formatter(L, opening_delimiter='(', closing_delimiter=')') # optional - sage.libs.pari 'lazy list (2, 3, 5, ...)' - sage: lazy_list_formatter(L, opening_delimiter='', closing_delimiter='') + sage: lazy_list_formatter(L, opening_delimiter='', closing_delimiter='') # optional - sage.libs.pari 'lazy list 2, 3, 5, ...' - sage: lazy_list_formatter(L, separator='--') + sage: lazy_list_formatter(L, separator='--') # optional - sage.libs.pari 'lazy list [2--3--5--...]' - sage: lazy_list_formatter(L, more='and more') + sage: lazy_list_formatter(L, more='and more') # optional - sage.libs.pari 'lazy list [2, 3, 5, and more]' - sage: lazy_list_formatter(L, preview=10) + sage: lazy_list_formatter(L, preview=10) # optional - sage.libs.pari 'lazy list [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, ...]' - sage: lazy_list_formatter(L, name='primes', + sage: lazy_list_formatter(L, name='primes', # optional - sage.libs.pari ....: opening_delimiter='', closing_delimiter='', ....: separator=' ', more='->', preview=7) 'primes 2 3 5 7 11 13 17 ->' @@ -356,9 +356,9 @@ cdef class lazy_list_generic(): sage: from sage.misc.lazy_list import lazy_list sage: l = lazy_list(Primes()) - sage: l + sage: l # optional - sage.libs.pari lazy list [2, 3, 5, ...] - sage: l[200] + sage: l[200] # optional - sage.libs.pari 1229 """ @@ -415,8 +415,9 @@ cdef class lazy_list_generic(): sage: from sage.misc.lazy_list import lazy_list sage: P = lazy_list(Primes()) - sage: P[2:143:5].list() - [5, 19, 41, 61, 83, 107, 137, 163, 191, 223, 241, 271, 307, 337, 367, 397, 431, 457, 487, 521, 563, 593, 617, 647, 677, 719, 751, 787, 823] + sage: P[2:143:5].list() # optional - sage.libs.pari + [5, 19, 41, 61, 83, 107, 137, 163, 191, 223, 241, 271, 307, 337, 367, + 397, 431, 457, 487, 521, 563, 593, 617, 647, 677, 719, 751, 787, 823] sage: P = lazy_list(iter([1,2,3])) sage: P.list() [1, 2, 3] @@ -430,11 +431,11 @@ cdef class lazy_list_generic(): Check that the cache is immutable:: sage: lazy = lazy_list(iter(Primes()))[:5] - sage: l = lazy.list(); l + sage: l = lazy.list(); l # optional - sage.libs.pari [2, 3, 5, 7, 11] - sage: l[0] = -1; l + sage: l[0] = -1; l # optional - sage.libs.pari [-1, 3, 5, 7, 11] - sage: lazy.list() + sage: lazy.list() # optional - sage.libs.pari [2, 3, 5, 7, 11] """ self._fit(self.stop - self.step) @@ -453,9 +454,9 @@ cdef class lazy_list_generic(): start 10 stop 21474838 step 4 - sage: P[0] + sage: P[0] # optional - sage.libs.pari 31 - sage: P._info() + sage: P._info() # optional - sage.libs.pari cache length 11 start 10 stop 21474838 @@ -858,9 +859,9 @@ cdef class lazy_list_generic(): sage: from sage.misc.lazy_list import lazy_list sage: L = lazy_list(Primes())[2:] - sage: L._update_cache_up_to(4) + sage: L._update_cache_up_to(4) # optional - sage.libs.pari 0 - sage: L._info() + sage: L._info() # optional - sage.libs.pari cache length 5 start 2 stop 9223372036854775807 # 64-bit @@ -885,9 +886,9 @@ cdef class lazy_list_generic(): TESTS:: sage: from sage.misc.lazy_list import lazy_list - sage: L = lazy_list(Primes()); L + sage: L = lazy_list(Primes()); L # optional - sage.libs.pari lazy list [2, 3, 5, ...] - sage: L._get_cache_() + sage: L._get_cache_() # optional - sage.libs.pari [2, 3, 5, 7] """ return self.cache @@ -964,9 +965,9 @@ cdef class lazy_list_from_iterator(lazy_list_generic): sage: from sage.misc.lazy_list import lazy_list sage: L = lazy_list(iter(Primes()))[2:] - sage: L._update_cache_up_to(4) + sage: L._update_cache_up_to(4) # optional - sage.libs.pari 0 - sage: L._info() + sage: L._info() # optional - sage.libs.pari cache length 5 start 2 stop 9223372036854775807 # 64-bit @@ -1015,9 +1016,9 @@ cdef class lazy_list_from_function(lazy_list_generic): EXAMPLES:: sage: from sage.misc.lazy_list import lazy_list_from_function - sage: lazy_list_from_function(euler_phi) + sage: lazy_list_from_function(euler_phi) # optional - sage.libs.pari lazy list [0, 1, 1, ...] - sage: lazy_list_from_function(divisors, [None]) + sage: lazy_list_from_function(divisors, [None]) # optional - sage.libs.pari lazy list [None, [1], [1, 2], ...] TESTS:: @@ -1064,9 +1065,9 @@ cdef class lazy_list_from_function(lazy_list_generic): TESTS:: sage: from sage.misc.lazy_list import lazy_list_from_function - sage: loads(dumps(lazy_list_from_function(euler_phi))) + sage: loads(dumps(lazy_list_from_function(euler_phi))) # optional - sage.libs.pari lazy list [0, 1, 1, ...] - sage: loads(dumps(lazy_list_from_function(divisors, [None]))) + sage: loads(dumps(lazy_list_from_function(divisors, [None]))) # optional - sage.libs.pari lazy list [None, [1], [1, 2], ...] """ if self.start != 0 or self.step != 1: diff --git a/src/sage/misc/lazy_string.pyx b/src/sage/misc/lazy_string.pyx index 5119775bad6..3cae657a45d 100644 --- a/src/sage/misc/lazy_string.pyx +++ b/src/sage/misc/lazy_string.pyx @@ -520,22 +520,23 @@ cdef class _LazyString(): EXAMPLES:: sage: from sage.misc.lazy_string import lazy_string - sage: f = lambda op,A,B:"unsupported operand parent(s) for %s: '%s' and '%s'"%(op,A,B) - sage: R = GF(5) - sage: S = GF(3) - sage: D = lazy_string(f, '+', R, S) - sage: D + sage: def f(op, A, B): + ....: return "unsupported operand parent(s) for %s: '%s' and '%s'" % (op, A, B) + sage: R = GF(5) # optional - sage.libs.pari + sage: S = GF(3) # optional - sage.libs.pari + sage: D = lazy_string(f, '+', R, S) # optional - sage.libs.pari + sage: D # optional - sage.libs.pari l"unsupported operand parent(s) for +: 'Finite Field of size 5' and 'Finite Field of size 3'" - sage: D.update_lazy_string(('+', S, R), {}) + sage: D.update_lazy_string(('+', S, R), {}) # optional - sage.libs.pari Apparently, the lazy string got changed in-place:: - sage: D + sage: D # optional - sage.libs.pari l"unsupported operand parent(s) for +: 'Finite Field of size 3' and 'Finite Field of size 5'" TESTS:: - sage: D.update_lazy_string(None, None) + sage: D.update_lazy_string(None, None) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: Expected tuple, got NoneType diff --git a/src/sage/misc/map_threaded.py b/src/sage/misc/map_threaded.py index c5eba670052..60342c108d7 100644 --- a/src/sage/misc/map_threaded.py +++ b/src/sage/misc/map_threaded.py @@ -10,19 +10,19 @@ def map_threaded(function, sequence): EXAMPLES:: - sage: map_threaded(log, [[1,2], [3,e]]) + sage: map_threaded(log, [[1,2], [3,e]]) # optional - sage.symbolic [[0, log(2)], [log(3), 1]] - sage: map_threaded(log, [(1,2), (3,e)]) + sage: map_threaded(log, [(1,2), (3,e)]) # optional - sage.symbolic [[0, log(2)], [log(3), 1]] - sage: map_threaded(N, [[1,2], [3,e]]) + sage: map_threaded(N, [[1,2], [3,e]]) # optional - sage.symbolic [[1.00000000000000, 2.00000000000000], [3.00000000000000, 2.71828182845905]] - sage: map_threaded((x^2).function(x), [[1,2,3,5], [2,10]]) + sage: map_threaded((x^2).function(x), [[1,2,3,5], [2,10]]) # optional - sage.symbolic [[1, 4, 9, 25], [4, 100]] map_threaded also works on any object with an apply_map method, e.g., on matrices:: - sage: map_threaded(lambda x: x^2, matrix([[1,2], [3,4]])) + sage: map_threaded(lambda x: x^2, matrix([[1,2], [3,4]])) # optional - sage.modules [ 1 4] [ 9 16] diff --git a/src/sage/misc/misc.py b/src/sage/misc/misc.py index f263f53bad3..e91a67367a9 100644 --- a/src/sage/misc/misc.py +++ b/src/sage/misc/misc.py @@ -48,6 +48,9 @@ from sage.env import DOT_SAGE, HOSTNAME from sage.misc.lazy_import import lazy_import +lazy_import("sage.combinat.subset", ["powerset", "subsets", "uniq"], + deprecation=35564) + lazy_import("sage.misc.call", ["AttrCallObject", "attrcall", "call_method"], deprecation=29869) @@ -519,88 +522,6 @@ def walltime(t=0): return time.time() - t -def union(x, y=None): - """ - Return the union of x and y, as a list. The resulting list need not - be sorted and can change from call to call. - - INPUT: - - - - ``x`` - iterable - - - ``y`` - iterable (may optionally omitted) - - - OUTPUT: list - - EXAMPLES:: - - sage: answer = union([1,2,3,4], [5,6]); answer - doctest:...: DeprecationWarning: sage.misc.misc.union is deprecated... - See https://github.com/sagemath/sage/issues/32096 for details. - [1, 2, 3, 4, 5, 6] - sage: union([1,2,3,4,5,6], [5,6]) == answer - True - sage: union((1,2,3,4,5,6), [5,6]) == answer - True - sage: union((1,2,3,4,5,6), set([5,6])) == answer - True - """ - from sage.misc.superseded import deprecation - deprecation(32096, "sage.misc.misc.union is deprecated, use 'list(set(x).union(y))' or a more suitable replacement") - if y is None: - return list(set(x)) - return list(set(x).union(y)) - - -def uniq(x): - """ - Return the sublist of all elements in the list x that is sorted and - is such that the entries in the sublist are unique. - - EXAMPLES:: - - sage: uniq([1, 1, 8, -5, 3, -5, -13, 13, -13]) - doctest:...: DeprecationWarning: the output of uniq(X) being sorted is deprecated; use sorted(set(X)) instead if you want sorted output - See https://github.com/sagemath/sage/issues/27014 for details. - [-13, -5, 1, 3, 8, 13] - """ - # After deprecation period, rename _stable_uniq -> uniq - from sage.misc.superseded import deprecation - deprecation(27014, "the output of uniq(X) being sorted is deprecated; use sorted(set(X)) instead if you want sorted output") - return sorted(set(x)) - - -def _stable_uniq(L): - """ - Iterate over the elements of ``L``, yielding every element at most - once: keep only the first occurrence of any item. - - The items must be hashable. - - INPUT: - - - ``L`` -- iterable - - EXAMPLES:: - - sage: from sage.misc.misc import _stable_uniq - sage: L = [1, 1, 8, -5, 3, -5, 'a', 'x', 'a'] - sage: it = _stable_uniq(L) - sage: it - - sage: list(it) - [1, 8, -5, 3, 'a', 'x'] - """ - seen = set() - for x in L: - if x in seen: - continue - yield x - seen.add(x) - - def exactly_one_is_true(iterable): r""" Return whether exactly one element of ``iterable`` evaluates ``True``. @@ -723,19 +644,19 @@ def compose(f, g): sage: def g(x): return 3*x sage: def f(x): return x + 1 - sage: h1 = compose(f,g) - sage: h2 = compose(g,f) - sage: _ = var ('x') - sage: h1(x) + sage: h1 = compose(f, g) + sage: h2 = compose(g, f) + sage: _ = var('x') # optional - sage.symbolic + sage: h1(x) # optional - sage.symbolic 3*x + 1 - sage: h2(x) + sage: h2(x) # optional - sage.symbolic 3*x + 3 :: - sage: _ = function('f g') - sage: _ = var ('x') - sage: compose(f,g)(x) + sage: _ = function('f g') # optional - sage.symbolic + sage: _ = var('x') # optional - sage.symbolic + sage: compose(f, g)(x) # optional - sage.symbolic f(g(x)) """ @@ -759,22 +680,22 @@ def nest(f, n, x): EXAMPLES:: sage: def f(x): return x^2 + 1 - sage: x = var('x') - sage: nest(f, 3, x) + sage: x = var('x') # optional - sage.symbolic + sage: nest(f, 3, x) # optional - sage.symbolic ((x^2 + 1)^2 + 1)^2 + 1 :: - sage: _ = function('f') - sage: _ = var('x') - sage: nest(f, 10, x) + sage: _ = function('f') # optional - sage.symbolic + sage: _ = var('x') # optional - sage.symbolic + sage: nest(f, 10, x) # optional - sage.symbolic f(f(f(f(f(f(f(f(f(f(x)))))))))) :: - sage: _ = function('f') - sage: _ = var('x') - sage: nest(f, 0, x) + sage: _ = function('f') # optional - sage.symbolic + sage: _ = var('x') # optional - sage.symbolic + sage: nest(f, 0, x) # optional - sage.symbolic x """ @@ -821,15 +742,15 @@ def __rmul__(self, left): """ EXAMPLES:: - sage: A = random_matrix(ZZ, 4) - sage: while A.rank() != 4: + sage: A = random_matrix(ZZ, 4) # optional - sage.modules + sage: while A.rank() != 4: # optional - sage.modules ....: A = random_matrix(ZZ, 4) - sage: B = random_matrix(ZZ, 4) - sage: temp = A * BackslashOperator() - sage: temp.left is A + sage: B = random_matrix(ZZ, 4) # optional - sage.modules + sage: temp = A * BackslashOperator() # optional - sage.modules + sage: temp.left is A # optional - sage.modules True - sage: X = temp * B - sage: A * X == B + sage: X = temp * B # optional - sage.modules + sage: A * X == B # optional - sage.modules True """ self.left = left @@ -839,16 +760,16 @@ def __mul__(self, right): r""" EXAMPLES:: - sage: A = matrix(RDF, 5, 5, 2) - sage: b = vector(RDF, 5, range(5)) - sage: v = A \ b - sage: v.zero_at(1e-19) # On at least one platform, we get a "negative zero" + sage: A = matrix(RDF, 5, 5, 2) # optional - sage.modules + sage: b = vector(RDF, 5, range(5)) # optional - sage.modules + sage: v = A \ b # optional - sage.modules + sage: v.zero_at(1e-19) # On at least one platform, we get a "negative zero" # optional - sage.modules (0.0, 0.5, 1.0, 1.5, 2.0) - sage: v = A._backslash_(b) - sage: v.zero_at(1e-19) + sage: v = A._backslash_(b) # optional - sage.modules + sage: v.zero_at(1e-19) # optional - sage.modules (0.0, 0.5, 1.0, 1.5, 2.0) - sage: v = A * BackslashOperator() * b - sage: v.zero_at(1e-19) + sage: v = A * BackslashOperator() * b # optional - sage.modules + sage: v.zero_at(1e-19) # optional - sage.modules (0.0, 0.5, 1.0, 1.5, 2.0) """ return self.left._backslash_(right) @@ -893,10 +814,10 @@ def is_iterator(it) -> bool: sage: list(x) [4, 3, 2, 1] - sage: P = Partitions(3) - sage: is_iterator(P) + sage: P = Partitions(3) # optional - sage.combinat + sage: is_iterator(P) # optional - sage.combinat False - sage: is_iterator(iter(P)) + sage: is_iterator(iter(P)) # optional - sage.combinat True """ # see trac #7398 for a discussion @@ -1056,69 +977,6 @@ def _some_tuples_sampling(elements, repeat, max_samples, n): yield tuple(elements[j] for j in Integer(a).digits(n, padto=repeat)) -def powerset(X): - r""" - Iterator over the *list* of all subsets of the iterable X, in no - particular order. Each list appears exactly once, up to order. - - INPUT: - - - ``X`` - an iterable - - OUTPUT: iterator of lists - - EXAMPLES:: - - sage: list(powerset([1,2,3])) - [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]] - sage: [z for z in powerset([0,[1,2]])] - [[], [0], [[1, 2]], [0, [1, 2]]] - - Iterating over the power set of an infinite set is also allowed:: - - sage: i = 0 - sage: L = [] - sage: for x in powerset(ZZ): - ....: if i > 10: - ....: break - ....: else: - ....: i += 1 - ....: L.append(x) - sage: print(" ".join(str(x) for x in L)) - [] [0] [1] [0, 1] [-1] [0, -1] [1, -1] [0, 1, -1] [2] [0, 2] [1, 2] - - You may also use subsets as an alias for powerset:: - - sage: subsets([1,2,3]) - - sage: list(subsets([1,2,3])) - [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]] - - The reason we return lists instead of sets is that the elements of - sets must be hashable and many structures on which one wants the - powerset consist of non-hashable objects. - - AUTHORS: - - - William Stein - - - Nils Bruin (2006-12-19): rewrite to work for not-necessarily - finite objects X. - """ - yield [] - pairs = [] - power2 = 1 - for x in X: - pairs.append((power2, x)) - next_power2 = power2 << 1 - for w in range(power2, next_power2): - yield [x for m, x in pairs if m & w] - power2 = next_power2 - - -subsets = powerset - - ################################################################# # Misc. ################################################################# diff --git a/src/sage/misc/misc_c.pyx b/src/sage/misc/misc_c.pyx index 20a0fe0016c..d3b65c93434 100644 --- a/src/sage/misc/misc_c.pyx +++ b/src/sage/misc/misc_c.pyx @@ -745,7 +745,7 @@ def cyflush(): EXAMPLES:: sage: R. = QQ[] - sage: t^(sys.maxsize//2) + sage: t^(sys.maxsize//2) # optional - sage.libs.flint Traceback (most recent call last): ... RuntimeError: FLINT exception diff --git a/src/sage/misc/parser.pyx b/src/sage/misc/parser.pyx index 29d7a9cd7a0..d6cc6b9c58e 100644 --- a/src/sage/misc/parser.pyx +++ b/src/sage/misc/parser.pyx @@ -480,18 +480,19 @@ cdef class Parser: sage: p.parse("1+2 == 3") True - sage: p = Parser(make_var=var) - sage: p.parse("a*b^c - 3a") + sage: p = Parser(make_var=var) # optional - sage.symbolic + sage: p.parse("a*b^c - 3a") # optional - sage.symbolic a*b^c - 3*a sage: R. = QQ[] - sage: p = Parser(make_var = {'x': x }) + sage: p = Parser(make_var={'x': x}) sage: p.parse("(x+1)^5-x") x^5 + 5*x^4 + 10*x^3 + 10*x^2 + 4*x + 1 sage: p.parse("(x+1)^5-x").parent() is R True - sage: p = Parser(make_float=RR, make_var=var, make_function={'foo': (lambda x: x*x+x)}) + sage: p = Parser(make_float=RR, make_var=var, + ....: make_function={'foo': (lambda x: x*x+x)}) sage: p.parse("1.5 + foo(b)") b^2 + b + 1.50000000000000 sage: p.parse("1.9").parent() @@ -513,8 +514,8 @@ cdef class Parser: EXAMPLES:: - sage: from sage.calculus.calculus import SR_parser - sage: SR_parser._variable_constructor() + sage: from sage.calculus.calculus import SR_parser # optional - sage.symbolic + sage: SR_parser._variable_constructor() # optional - sage.symbolic b")) + sage: p.p_eqn(Tokenizer("a > b")) # optional - sage.symbolic a > b - sage: p.p_eqn(Tokenizer("a <= b")) + sage: p.p_eqn(Tokenizer("a <= b")) # optional - sage.symbolic a <= b - sage: p.p_eqn(Tokenizer("a >= b")) + sage: p.p_eqn(Tokenizer("a >= b")) # optional - sage.symbolic a >= b - sage: p.p_eqn(Tokenizer("a != b")) + sage: p.p_eqn(Tokenizer("a != b")) # optional - sage.symbolic a != b """ lhs = self.p_expr(tokens) @@ -775,16 +776,16 @@ cdef class Parser: EXAMPLES:: sage: from sage.misc.parser import Parser, Tokenizer - sage: p = Parser(make_var=var) - sage: p.p_expr(Tokenizer("a+b")) + sage: p = Parser(make_var=var) # optional - sage.symbolic + sage: p.p_expr(Tokenizer("a+b")) # optional - sage.symbolic a + b - sage: p.p_expr(Tokenizer("a")) + sage: p.p_expr(Tokenizer("a")) # optional - sage.symbolic a - sage: p.p_expr(Tokenizer("a - b + 4*c - d^2")) + sage: p.p_expr(Tokenizer("a - b + 4*c - d^2")) # optional - sage.symbolic -d^2 + a - b + 4*c - sage: p.p_expr(Tokenizer("a - -3")) + sage: p.p_expr(Tokenizer("a - -3")) # optional - sage.symbolic a + 3 - sage: p.p_expr(Tokenizer("a + 1 == b")) + sage: p.p_expr(Tokenizer("a + 1 == b")) # optional - sage.symbolic a + 1 """ # Note: this is left-recursive, so we can't just recurse @@ -809,16 +810,16 @@ cdef class Parser: EXAMPLES:: sage: from sage.misc.parser import Parser, Tokenizer - sage: p = Parser(make_var=var) - sage: p.p_term(Tokenizer("a*b")) + sage: p = Parser(make_var=var) # optional - sage.symbolic + sage: p.p_term(Tokenizer("a*b")) # optional - sage.symbolic a*b - sage: p.p_term(Tokenizer("a * b / c * d")) + sage: p.p_term(Tokenizer("a * b / c * d")) # optional - sage.symbolic a*b*d/c - sage: p.p_term(Tokenizer("-a * b + c")) + sage: p.p_term(Tokenizer("-a * b + c")) # optional - sage.symbolic -a*b - sage: p.p_term(Tokenizer("a*(b-c)^2")) + sage: p.p_term(Tokenizer("a*(b-c)^2")) # optional - sage.symbolic a*(b - c)^2 - sage: p.p_term(Tokenizer("-3a")) + sage: p.p_term(Tokenizer("-3a")) # optional - sage.symbolic -3*a """ # Note: this is left-recursive, so we can't just recurse @@ -885,12 +886,12 @@ cdef class Parser: sage: p.p_power(Tokenizer("2^3^2")) == 2^9 True - sage: p = Parser(make_var=var) - sage: p.p_factor(Tokenizer('x!')) + sage: p = Parser(make_var=var) # optional - sage.symbolic + sage: p.p_factor(Tokenizer('x!')) # optional - sage.symbolic factorial(x) - sage: p.p_factor(Tokenizer('(x^2)!')) + sage: p.p_factor(Tokenizer('(x^2)!')) # optional - sage.symbolic factorial(x^2) - sage: p.p_factor(Tokenizer('x!^2')) + sage: p.p_factor(Tokenizer('x!^2')) # optional - sage.symbolic factorial(x)^2 """ @@ -920,23 +921,24 @@ cdef class Parser: EXAMPLES:: sage: from sage.misc.parser import Parser, Tokenizer - sage: p = Parser(make_var=var, make_function={'sin': sin}) - sage: p.p_atom(Tokenizer("1")) + sage: p = Parser(make_var=var, make_function={'sin': sin}) # optional - sage.symbolic + sage: p.p_atom(Tokenizer("1")) # optional - sage.symbolic 1 - sage: p.p_atom(Tokenizer("12")) + sage: p.p_atom(Tokenizer("12")) # optional - sage.symbolic 12 - sage: p.p_atom(Tokenizer("12.5")) + sage: p.p_atom(Tokenizer("12.5")) # optional - sage.symbolic 12.5 - sage: p.p_atom(Tokenizer("(1+a)")) + sage: p.p_atom(Tokenizer("(1+a)")) # optional - sage.symbolic a + 1 - sage: p.p_atom(Tokenizer("(1+a)^2")) + sage: p.p_atom(Tokenizer("(1+a)^2")) # optional - sage.symbolic a + 1 - sage: p.p_atom(Tokenizer("sin(1+a)")) + sage: p.p_atom(Tokenizer("sin(1+a)")) # optional - sage.symbolic sin(a + 1) - sage: p = Parser(make_var=var, make_function={'foo': sage.misc.parser.foo}) - sage: p.p_atom(Tokenizer("foo(a, b, key=value)")) + sage: p = Parser(make_var=var, # optional - sage.symbolic + ....: make_function={'foo': sage.misc.parser.foo}) + sage: p.p_atom(Tokenizer("foo(a, b, key=value)")) # optional - sage.symbolic ((a, b), {'key': value}) - sage: p.p_atom(Tokenizer("foo()")) + sage: p.p_atom(Tokenizer("foo()")) # optional - sage.symbolic ((), {}) """ cdef int token = tokens.next() @@ -1007,22 +1009,22 @@ cdef class Parser: Parsing a normal expression:: sage: from sage.misc.parser import Parser, Tokenizer - sage: p = Parser(make_var=var) - sage: p.p_arg(Tokenizer("a+b")) + sage: p = Parser(make_var=var) # optional - sage.symbolic + sage: p.p_arg(Tokenizer("a+b")) # optional - sage.symbolic a + b A keyword expression argument:: sage: from sage.misc.parser import Parser, Tokenizer - sage: p = Parser(make_var=var) - sage: p.p_arg(Tokenizer("val=a+b")) + sage: p = Parser(make_var=var) # optional - sage.symbolic + sage: p.p_arg(Tokenizer("val=a+b")) # optional - sage.symbolic ('val', a + b) A lone list:: sage: from sage.misc.parser import Parser, Tokenizer - sage: p = Parser(make_var=var) - sage: p.p_arg(Tokenizer("[x]")) + sage: p = Parser(make_var=var) # optional - sage.symbolic + sage: p.p_arg(Tokenizer("[x]")) # optional - sage.symbolic [x] """ @@ -1054,12 +1056,12 @@ cdef class LookupNameMaker: EXAMPLES:: sage: from sage.misc.parser import LookupNameMaker - sage: maker = LookupNameMaker({'pi': pi}, var) - sage: maker('pi') + sage: maker = LookupNameMaker({'pi': pi}, var) # optional - sage.symbolic + sage: maker('pi') # optional - sage.symbolic pi - sage: maker('pi') is pi + sage: maker('pi') is pi # optional - sage.symbolic True - sage: maker('a') + sage: maker('a') # optional - sage.symbolic a """ self.names = names @@ -1071,8 +1073,8 @@ cdef class LookupNameMaker: sage: from sage.misc.parser import LookupNameMaker sage: maker = LookupNameMaker({}, str) - sage: maker.set_names({'a': x}) - sage: maker('a') is x + sage: maker.set_names({'a': x}) # optional - sage.symbolic + sage: maker('a') is x # optional - sage.symbolic True """ self.names = new_names @@ -1082,12 +1084,12 @@ cdef class LookupNameMaker: TESTS:: sage: from sage.misc.parser import LookupNameMaker - sage: maker = LookupNameMaker({'a': x}, str) - sage: maker('a') + sage: maker = LookupNameMaker({'a': x}, str) # optional - sage.symbolic + sage: maker('a') # optional - sage.symbolic x - sage: maker('a') is x + sage: maker('a') is x # optional - sage.symbolic True - sage: maker('b') + sage: maker('b') # optional - sage.symbolic 'b' """ try: diff --git a/src/sage/misc/persist.pyx b/src/sage/misc/persist.pyx index ca9b2894469..e221e1ad81a 100644 --- a/src/sage/misc/persist.pyx +++ b/src/sage/misc/persist.pyx @@ -239,22 +239,23 @@ def save(obj, filename, compress=True, **kwargs): sage: import tempfile sage: d = tempfile.TemporaryDirectory() - sage: a = matrix(2, [1,2,3,-5/2]) + sage: a = matrix(2, [1,2, 3,-5/2]) # optional - sage.modules sage: objfile = os.path.join(d.name, 'test.sobj') sage: objfile_short = os.path.join(d.name, 'test') - sage: save(a, objfile) - sage: load(objfile_short) + sage: save(a, objfile) # optional - sage.modules + sage: load(objfile_short) # optional - sage.modules [ 1 2] [ 3 -5/2] - sage: E = EllipticCurve([-1,0]) - sage: P = plot(E) - sage: save(P, objfile_short) # saves the plot to "test.sobj" - sage: save(P, filename=os.path.join(d.name, "sage.png"), xmin=-2) - sage: save(P, os.path.join(d.name, "filename.with.some.wrong.ext")) + sage: E = EllipticCurve([-1,0]) # optional - sage.plot + sage: P = plot(E) # optional - sage.plot + sage: save(P, objfile_short) # saves the plot to "test.sobj" # optional - sage.plot + sage: save(P, filename=os.path.join(d.name, "sage.png"), xmin=-2) # optional - sage.plot + sage: save(P, os.path.join(d.name, "filename.with.some.wrong.ext")) # optional - sage.plot Traceback (most recent call last): ... - ValueError: allowed file extensions for images are '.eps', '.pdf', '.pgf', '.png', '.ps', '.sobj', '.svg'! - sage: print(load(objfile)) + ValueError: allowed file extensions for images are + '.eps', '.pdf', '.pgf', '.png', '.ps', '.sobj', '.svg'! + sage: print(load(objfile)) # optional - sage.plot Graphics object consisting of 2 graphics primitives sage: save("A python string", os.path.join(d.name, 'test')) sage: load(objfile) @@ -397,19 +398,19 @@ def register_unpickle_override(module, name, callable, call_name=None): pickle to play with:: sage: from sage.structure.element import Element - sage: class SourPickle(CombinatorialObject): pass - sage: class SweetPickle(CombinatorialObject, Element): pass - sage: import __main__ - sage: __main__.SourPickle = SourPickle - sage: __main__.SweetPickle = SweetPickle # a hack to allow us to pickle command line classes - sage: gherkin = dumps(SourPickle([1, 2, 3])) + sage: class SourPickle(CombinatorialObject): pass # optional - sage.combinat + sage: class SweetPickle(CombinatorialObject, Element): pass # optional - sage.combinat + sage: import __main__ # optional - sage.combinat + sage: __main__.SourPickle = SourPickle # optional - sage.combinat + sage: __main__.SweetPickle = SweetPickle # a hack to allow us to pickle command line classes # optional - sage.combinat + sage: gherkin = dumps(SourPickle([1, 2, 3])) # optional - sage.combinat Using :func:`register_unpickle_override` we try to sweeten our pickle, but we are unable to eat it:: - sage: from sage.misc.persist import register_unpickle_override - sage: register_unpickle_override('__main__', 'SourPickle', SweetPickle) - sage: loads(gherkin) + sage: from sage.misc.persist import register_unpickle_override # optional - sage.combinat + sage: register_unpickle_override('__main__', 'SourPickle', SweetPickle) # optional - sage.combinat + sage: loads(gherkin) # optional - sage.combinat Traceback (most recent call last): ... KeyError: 0 @@ -420,7 +421,7 @@ def register_unpickle_override(module, name, callable, call_name=None): unpickling for :class:`CombinatorialObject`. We can fix this by explicitly defining a new :meth:`__setstate__` method:: - sage: class SweeterPickle(CombinatorialObject, Element): + sage: class SweeterPickle(CombinatorialObject, Element): # optional - sage.combinat ....: def __setstate__(self, state): ....: # a pickle from CombinatorialObject is just its instance ....: # dictionary @@ -433,11 +434,11 @@ def register_unpickle_override(module, name, callable, call_name=None): ....: if P is not None: ....: self._set_parent(P) ....: self.__dict__ = D - sage: __main__.SweeterPickle = SweeterPickle - sage: register_unpickle_override('__main__', 'SourPickle', SweeterPickle) - sage: loads(gherkin) + sage: __main__.SweeterPickle = SweeterPickle # optional - sage.combinat + sage: register_unpickle_override('__main__', 'SourPickle', SweeterPickle) # optional - sage.combinat + sage: loads(gherkin) # optional - sage.combinat [1, 2, 3] - sage: loads(dumps(SweeterPickle([1, 2, 3]))) # check that pickles work for SweeterPickle + sage: loads(dumps(SweeterPickle([1, 2, 3]))) # check that pickles work for SweeterPickle # optional - sage.combinat [1, 2, 3] The ``state`` passed to :meth:`__setstate__` will usually be something like @@ -574,7 +575,7 @@ def unpickle_global(module, name): Test that :func:`register_unpickle_override` calls in lazily imported modules are respected:: - sage: unpickle_global('sage.combinat.root_system.type_A', 'ambient_space') + sage: unpickle_global('sage.combinat.root_system.type_A', 'ambient_space') # optional - sage.combinat sage.modules """ unpickler = unpickle_override.get((module, name)) @@ -919,9 +920,9 @@ def loads(s, compress=True, **kwargs): EXAMPLES:: - sage: a = matrix(2, [1,2,3,-4/3]) - sage: s = dumps(a) - sage: loads(s) + sage: a = matrix(2, [1,2, 3,-4/3]) # optional - sage.modules + sage: s = dumps(a) # optional - sage.modules + sage: loads(s) # optional - sage.modules [ 1 2] [ 3 -4/3] @@ -1158,7 +1159,7 @@ def make_None(*args, **kwds): EXAMPLES:: sage: from sage.misc.persist import make_None - sage: print(make_None(42, pi, foo='bar')) + sage: print(make_None(42, pi, foo='bar')) # optional - sage.symbolic None """ return None diff --git a/src/sage/misc/prandom.py b/src/sage/misc/prandom.py index 751d5b35129..19662a47adb 100644 --- a/src/sage/misc/prandom.py +++ b/src/sage/misc/prandom.py @@ -142,9 +142,9 @@ def choice(seq): EXAMPLES:: - sage: s = [choice(list(primes(10, 100))) for i in range(5)]; s # random + sage: s = [choice(list(primes(10, 100))) for i in range(5)]; s # random # optional - sage.libs.pari [17, 47, 11, 31, 47] - sage: all(t in primes(10, 100) for t in s) + sage: all(t in primes(10, 100) for t in s) # optional - sage.libs.pari True """ return _pyrand().choice(seq) @@ -227,9 +227,9 @@ def uniform(a, b): sage: 0.0 <= s <= 1.0 True - sage: s = uniform(e, pi); s # random + sage: s = uniform(e, pi); s # random # optional - sage.symbolic 0.5143475134191677*pi + 0.48565248658083227*e - sage: bool(e <= s <= pi) + sage: bool(e <= s <= pi) # optional - sage.symbolic True """ return _pyrand().uniform(a, b) diff --git a/src/sage/misc/randstate.pyx b/src/sage/misc/randstate.pyx index 4af9306cb63..4c59c060350 100644 --- a/src/sage/misc/randstate.pyx +++ b/src/sage/misc/randstate.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.groups sage.libs.gap sage.libs.ntl sage.libs.pari r""" Random Number States @@ -679,8 +680,8 @@ cdef class randstate: seed the generator itself. However, we put the call in to make the coverage tester happy. :: - sage: current_randstate().set_seed_ntl(False) - sage: ntl.ZZ_random(10^40) + sage: current_randstate().set_seed_ntl(False) # optional - sage.libs.ntl + sage: ntl.ZZ_random(10^40) # optional - sage.libs.ntl 1495283511775355459459209288047895196007 """ global _ntl_seed_randstate @@ -699,10 +700,10 @@ cdef class randstate: EXAMPLES:: sage: set_random_seed(99900000999) - sage: current_randstate().set_seed_gap() - sage: gap.Random(1, 10^50) + sage: current_randstate().set_seed_gap() # optional - sage.libs.gap + sage: gap.Random(1, 10^50) # optional - sage.libs.gap 1496738263332555434474532297768680634540939580077 - sage: gap(35).SCRRandomString() + sage: gap(35).SCRRandomString() # optional - sage.libs.gap [ 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1 ] """ @@ -738,8 +739,8 @@ cdef class randstate: EXAMPLES:: sage: set_random_seed(987654321) - sage: current_randstate().set_seed_gp() - sage: gp.random() + sage: current_randstate().set_seed_gp() # optional - sage.libs.pari + sage: gp.random() # optional - sage.libs.pari 23289294 """ if gp is None: @@ -785,8 +786,8 @@ cdef class randstate: EXAMPLES:: sage: set_random_seed(5551212) - sage: current_randstate().set_seed_pari() - sage: pari.getrand().type() + sage: current_randstate().set_seed_pari() # optional - sage.libs.pari + sage: pari.getrand().type() # optional - sage.libs.pari 't_INT' """ global _pari_seed_randstate diff --git a/src/sage/misc/repr.py b/src/sage/misc/repr.py index 80265ac3cc3..3ab32778840 100644 --- a/src/sage/misc/repr.py +++ b/src/sage/misc/repr.py @@ -20,11 +20,11 @@ def coeff_repr(c, is_latex=False): sage: from sage.misc.repr import coeff_repr sage: coeff_repr(QQ(1/2)) '1/2' - sage: coeff_repr(-x^2) + sage: coeff_repr(-x^2) # optional - sage.symbolic '(-x^2)' sage: coeff_repr(QQ(1/2), is_latex=True) '\\frac{1}{2}' - sage: coeff_repr(-x^2, is_latex=True) + sage: coeff_repr(-x^2, is_latex=True) # optional - sage.symbolic '\\left(-x^{2}\\right)' """ if not is_latex: @@ -131,12 +131,12 @@ def repr_lincomb(terms, is_latex=False, scalar_mult="*", strip_one=False, Verify that :trac:`31672` is fixed:: - sage: alpha = var("alpha") - sage: repr_lincomb([(x, alpha)], is_latex=True) + sage: alpha = var("alpha") # optional - sage.symbolic + sage: repr_lincomb([(x, alpha)], is_latex=True) # optional - sage.symbolic '\\alpha x' - sage: A. = PolynomialRing(QQ) - sage: B. = FreeAlgebra(A) - sage: (psi * t)._latex_() + sage: A. = PolynomialRing(QQ) # optional - sage.symbolic + sage: B. = FreeAlgebra(A) # optional - sage.combinat sage.modules sage.symbolic + sage: (psi * t)._latex_() # optional - sage.combinat sage.modules sage.symbolic '\\psi t' """ # Setting scalar_mult: symbol used for scalar multiplication diff --git a/src/sage/misc/reset.pyx b/src/sage/misc/reset.pyx index 50893dfea17..64b1c68fea6 100644 --- a/src/sage/misc/reset.pyx +++ b/src/sage/misc/reset.pyx @@ -35,7 +35,7 @@ def reset(vars=None, attached=False): sage: x = 5 sage: reset() - sage: x + sage: x # optional - sage.symbolic x sage: fn = tmp_filename(ext='foo.py') @@ -57,19 +57,18 @@ def reset(vars=None, attached=False): Confirm that assumptions don't survive a reset (:trac:`10855`):: - sage: assume(x > 3) - sage: assumptions() + sage: assume(x > 3) # optional - sage.symbolic + sage: assumptions() # optional - sage.symbolic [x > 3] - sage: bool(x > 3) + sage: bool(x > 3) # optional - sage.symbolic True sage: reset() - sage: assumptions() + sage: assumptions() # optional - sage.symbolic [] - sage: bool(x > 3) + sage: bool(x > 3) # optional - sage.symbolic False """ - from sage.symbolic.assumptions import forget if vars is not None: restore(vars) return @@ -82,7 +81,12 @@ def reset(vars=None, attached=False): except KeyError: pass restore() - forget() + try: + from sage.symbolic.assumptions import forget + except ImportError: + pass + else: + forget() reset_interfaces() if attached: import sage.repl.attach @@ -108,9 +112,9 @@ def restore(vars=None): Rational Field sage: x 10 - sage: y = var('y') + sage: y = var('y') # optional - sage.symbolic sage: restore('x y') - sage: x + sage: x # optional - sage.symbolic x sage: y Traceback (most recent call last): @@ -140,8 +144,12 @@ def restore(vars=None): import sage.all D = sage.all.__dict__ _restore(G, D, vars) - import sage.calculus.calculus - _restore(sage.calculus.calculus.syms_cur, sage.calculus.calculus.syms_default, vars) + try: + import sage.calculus.calculus + except ImportError: + pass + else: + _restore(sage.calculus.calculus.syms_cur, sage.calculus.calculus.syms_default, vars) def _restore(G, D, vars): @@ -165,5 +173,9 @@ def _restore(G, D, vars): def reset_interfaces(): - from sage.interfaces.quit import expect_quitall - expect_quitall() + try: + from sage.interfaces.quit import expect_quitall + except ImportError: + pass + else: + expect_quitall() diff --git a/src/sage/misc/rest_index_of_methods.py b/src/sage/misc/rest_index_of_methods.py index 5efb863ead3..c2ce7b640c2 100644 --- a/src/sage/misc/rest_index_of_methods.py +++ b/src/sage/misc/rest_index_of_methods.py @@ -52,7 +52,7 @@ def gen_rest_table_index(obj, names=None, sort=True, only_local_functions=True): EXAMPLES:: sage: from sage.misc.rest_index_of_methods import gen_rest_table_index - sage: print(gen_rest_table_index([graphs.PetersenGraph])) + sage: print(gen_rest_table_index([graphs.PetersenGraph])) # optional - sage.graphs .. csv-table:: :class: contentstable :widths: 30, 70 @@ -77,7 +77,7 @@ def gen_rest_table_index(obj, names=None, sort=True, only_local_functions=True): The table of a class:: - sage: print(gen_rest_table_index(Graph)) + sage: print(gen_rest_table_index(Graph)) # optional - sage.graphs .. csv-table:: :class: contentstable :widths: 30, 70 @@ -103,12 +103,12 @@ def gen_rest_table_index(obj, names=None, sort=True, only_local_functions=True): The inherited methods do not show up:: - sage: gen_rest_table_index(sage.combinat.posets.lattices.FiniteLatticePoset).count('\n') < 75 + sage: gen_rest_table_index(sage.combinat.posets.lattices.FiniteLatticePoset).count('\n') < 75 # optional - sage.combinat True - sage: from sage.graphs.generic_graph import GenericGraph - sage: A = gen_rest_table_index(Graph).count('\n') - sage: B = gen_rest_table_index(GenericGraph).count('\n') - sage: A < B + sage: from sage.graphs.generic_graph import GenericGraph # optional - sage.graphs + sage: A = gen_rest_table_index(Graph).count('\n') # optional - sage.graphs + sage: B = gen_rest_table_index(GenericGraph).count('\n') # optional - sage.graphs + sage: A < B # optional - sage.graphs True When ``only_local_functions`` is ``False``, we do not include @@ -141,9 +141,9 @@ def gen_rest_table_index(obj, names=None, sort=True, only_local_functions=True): A function that is imported into a class under a different name is listed under its 'new' name:: - sage: 'cliques_maximum' in gen_rest_table_index(Graph) + sage: 'cliques_maximum' in gen_rest_table_index(Graph) # optional - sage.graphs True - sage: 'all_max_cliques`' in gen_rest_table_index(Graph) + sage: 'all_max_cliques`' in gen_rest_table_index(Graph) # optional - sage.graphs False """ if names is None: @@ -223,17 +223,17 @@ def list_of_subfunctions(root, only_local_functions=True): EXAMPLES:: sage: from sage.misc.rest_index_of_methods import list_of_subfunctions - sage: l = list_of_subfunctions(Graph)[0] - sage: Graph.bipartite_color in l + sage: l = list_of_subfunctions(Graph)[0] # optional - sage.graphs + sage: Graph.bipartite_color in l # optional - sage.graphs True TESTS: A ``staticmethod`` is not callable. We must handle them correctly, however:: - sage: class A: + sage: class A: # optional - sage.graphs ....: x = staticmethod(Graph.order) - sage: list_of_subfunctions(A) + sage: list_of_subfunctions(A) # optional - sage.graphs ([], {: 'x'}) @@ -286,8 +286,8 @@ def gen_thematic_rest_table_index(root,additional_categories=None,only_local_fun EXAMPLES:: sage: from sage.misc.rest_index_of_methods import gen_thematic_rest_table_index, list_of_subfunctions - sage: l = list_of_subfunctions(Graph)[0] - sage: Graph.bipartite_color in l + sage: l = list_of_subfunctions(Graph)[0] # optional - sage.graphs + sage: Graph.bipartite_color in l # optional - sage.graphs True """ from collections import defaultdict diff --git a/src/sage/misc/sage_eval.py b/src/sage/misc/sage_eval.py index 8d0416a4cfd..5ff99c2512d 100644 --- a/src/sage/misc/sage_eval.py +++ b/src/sage/misc/sage_eval.py @@ -71,7 +71,7 @@ def sage_eval(source, locals=None, cmds='', preparse=True): 36 sage: eval('bernoulli(6)') 36 - sage: sage_eval('bernoulli(6)') + sage: sage_eval('bernoulli(6)') # optional - sage.libs.flint 1/42 :: @@ -132,13 +132,13 @@ def sage_eval(source, locals=None, cmds='', preparse=True): :: sage: R. = PolynomialRing(RationalField()) - sage: gap.eval('R:=PolynomialRing(Rationals,["x"]);') + sage: gap.eval('R:=PolynomialRing(Rationals,["x"]);') # optional - sage.libs.gap 'Rationals[x]' - sage: ff = gap.eval('x:=IndeterminatesOfPolynomialRing(R);; f:=x^2+1;'); ff + sage: ff = gap.eval('x:=IndeterminatesOfPolynomialRing(R);; f:=x^2+1;'); ff # optional - sage.libs.gap 'x^2+1' - sage: sage_eval(ff, locals={'x':x}) + sage: sage_eval(ff, locals={'x':x}) # optional - sage.libs.gap x^2 + 1 - sage: eval(ff) + sage: eval(ff) # optional - sage.libs.gap Traceback (most recent call last): ... RuntimeError: Use ** for exponentiation, not '^', which means xor @@ -212,7 +212,7 @@ def sageobj(x, vars=None): EXAMPLES:: - sage: type(sageobj(gp('34/56'))) + sage: type(sageobj(gp('34/56'))) # optional - sage.libs.pari sage: n = 5/2 sage: sageobj(n) is n @@ -224,12 +224,12 @@ def sageobj(x, vars=None): This illustrates interfaces:: - sage: f = gp('2/3') - sage: type(f) + sage: f = gp('2/3') # optional - sage.libs.pari + sage: type(f) # optional - sage.libs.pari - sage: f._sage_() + sage: f._sage_() # optional - sage.libs.pari 2/3 - sage: type(f._sage_()) + sage: type(f._sage_()) # optional - sage.libs.pari sage: a = gap(939393/2433) sage: a._sage_() diff --git a/src/sage/misc/sage_input.py b/src/sage/misc/sage_input.py index a50bf15d708..253610a27fb 100644 --- a/src/sage/misc/sage_input.py +++ b/src/sage/misc/sage_input.py @@ -13,7 +13,7 @@ sage: sage_input(3) 3 - sage: sage_input((polygen(RR) + RR(pi))^2, verify=True) + sage: sage_input((polygen(RR) + RR(pi))^2, verify=True) # optional - sage.symbolic # Verified R. = RR[] x^2 + 6.2831853071795862*x + 9.869604401089358 @@ -22,7 +22,7 @@ calling :func:`~sage.misc.sage_eval.sage_eval` on the result and verifying that it is equal to the input.:: - sage: sage_input(GF(2)(1), verify=True) + sage: sage_input(GF(2)(1), verify=True) # optional - sage.libs.pari # Verified GF(2)(1) @@ -202,21 +202,21 @@ def sage_input(x, preparse=True, verify=False, allow_locals=False): EXAMPLES:: - sage: sage_input(GF(2)(1)) + sage: sage_input(GF(2)(1)) # optional - sage.rings.finite_rings GF(2)(1) - sage: sage_input((GF(2)(0), GF(2)(1)), verify=True) + sage: sage_input((GF(2)(0), GF(2)(1)), verify=True) # optional - sage.rings.finite_rings # Verified GF_2 = GF(2) (GF_2(0), GF_2(1)) When the preparser is enabled, we use the \sage generator syntax.:: - sage: K. = GF(5)[] - sage: sage_input(x^3 + 2*x, verify=True) + sage: K. = GF(5)[] # optional - sage.rings.finite_rings + sage: sage_input(x^3 + 2*x, verify=True) # optional - sage.rings.finite_rings # Verified R. = GF(5)[] x^3 + 2*x - sage: sage_input(x^3 + 2*x, preparse=False) + sage: sage_input(x^3 + 2*x, preparse=False) # optional - sage.rings.finite_rings R = GF(5)['x'] x = R.gen() x**3 + 2*x @@ -364,14 +364,14 @@ def __call__(self, x, coerced=False): 3 sage: sib = SageInputBuilder() - sage: sib.result(sib(GF(17)(5))) + sage: sib.result(sib(GF(17)(5))) # optional - sage.rings.finite_rings GF(17)(5) The argument ``coerced=True`` or ``coerced=2`` will get passed to the \method{_sage_input_} method of the argument.:: sage: sib = SageInputBuilder() - sage: sib.result(sib(GF(17)(5), True)) + sage: sib.result(sib(GF(17)(5), True)) # optional - sage.rings.finite_rings 5 sage: sib.result(sib(RealField(200)(1.5), True)) 1.5000000000000000000000000000000000000000000000000000000000000 @@ -626,9 +626,9 @@ def cache(self, x, sie, name): sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() - sage: sie42 = sib(GF(101)(42)) - sage: sib.cache(GF(101)(42), sie42, 'the_ultimate_answer') - sage: sib.result(sib(GF(101)(42)) + sib(GF(101)(42))) + sage: sie42 = sib(GF(101)(42)) # optional - sage.rings.finite_rings + sage: sib.cache(GF(101)(42), sie42, 'the_ultimate_answer') # optional - sage.rings.finite_rings + sage: sib.result(sib(GF(101)(42)) + sib(GF(101)(42))) # optional - sage.rings.finite_rings the_ultimate_answer = GF(101)(42) the_ultimate_answer + the_ultimate_answer @@ -636,9 +636,9 @@ def cache(self, x, sie, name): is only used once.:: sage: sib = SageInputBuilder() - sage: sie42 = sib(GF(101)(42)) - sage: sib.cache(GF(101)(42), sie42, 'the_ultimate_answer') - sage: sib.result(sib(GF(101)(42)) + sib(GF(101)(43))) + sage: sie42 = sib(GF(101)(42)) # optional - sage.rings.finite_rings + sage: sib.cache(GF(101)(42), sie42, 'the_ultimate_answer') # optional - sage.rings.finite_rings + sage: sib.result(sib(GF(101)(42)) + sib(GF(101)(43))) # optional - sage.rings.finite_rings GF_101 = GF(101) GF_101(42) + GF_101(43) """ @@ -1262,7 +1262,7 @@ def _sie_is_simple(self): sage: sib = SageInputBuilder() sage: sib.name('QQ')._sie_is_simple() True - sage: sib(GF(2))._sie_is_simple() + sage: sib(GF(2))._sie_is_simple() # optional - sage.rings.finite_rings False """ return False @@ -1276,7 +1276,7 @@ def _sie_referenced(self): sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() - sage: len(sib(GF(2))._sie_referenced()) + sage: len(sib(GF(2))._sie_referenced()) # optional - sage.rings.finite_rings 2 sage: sib(5)._sie_referenced() [] @@ -1295,16 +1295,16 @@ def _sie_prepare(self, sif): sage: from sage.misc.sage_input import SageInputBuilder, SageInputFormatter sage: sib = SageInputBuilder() sage: sif = SageInputFormatter() - sage: pair = sib((GF(2), GF(2))) - sage: single = sib(GF(2)) - sage: single._sie_refcount + sage: pair = sib((GF(2), GF(2))) # optional - sage.rings.finite_rings + sage: single = sib(GF(2)) # optional - sage.rings.finite_rings + sage: single._sie_refcount # optional - sage.rings.finite_rings 0 - sage: single._sie_use_var + sage: single._sie_use_var # optional - sage.rings.finite_rings False - sage: sib((GF(2), GF(2)))._sie_prepare(sif) - sage: single._sie_refcount + sage: sib((GF(2), GF(2)))._sie_prepare(sif) # optional - sage.rings.finite_rings + sage: single._sie_refcount # optional - sage.rings.finite_rings 2 - sage: single._sie_use_var + sage: single._sie_use_var # optional - sage.rings.finite_rings True """ if self._sie_context is not sif: @@ -1827,8 +1827,8 @@ class SIE_call(SageInputExpression): sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() - sage: sie = sib.name('GF') - sage: sie(49) + sage: sie = sib.name('GF') # optional - sage.rings.finite_rings + sage: sie(49) # optional - sage.rings.finite_rings {call: {atomic:GF}({atomic:49})} """ @@ -1996,8 +1996,8 @@ def _sie_referenced(self): sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() - sage: sie = sib.name('GF')(5)['x,y'] - sage: sie._sie_referenced() + sage: sie = sib.name('GF')(5)['x,y'] # optional - sage.rings.finite_rings + sage: sie._sie_referenced() # optional - sage.rings.finite_rings [{call: {atomic:GF}({atomic:5})}, {atomic:'x,y'}] """ refs = [self._sie_coll] @@ -2190,8 +2190,8 @@ def _sie_referenced(self): sage: from sage.misc.sage_input import SageInputBuilder sage: sib = SageInputBuilder() - sage: sie = sib((ZZ, GF(5))) - sage: sie._sie_referenced() + sage: sie = sib((ZZ, GF(5))) # optional - sage.rings.finite_rings + sage: sie._sie_referenced() # optional - sage.rings.finite_rings [{atomic:ZZ}, {call: {atomic:GF}({atomic:5})}] """ return self._sie_values @@ -2812,14 +2812,14 @@ def _sie_add_command(self, sif): We also can't use the preparser syntax if there is a conflict between generator names. For example, this works:: - sage: sage_input((polygen(ZZ), polygen(GF(17), 'y'))) + sage: sage_input((polygen(ZZ), polygen(GF(17), 'y'))) # optional - sage.rings.finite_rings R1. = ZZ[] R2. = GF(17)[] (x, y) but this can't use the preparser syntax.:: - sage: sage_input((polygen(ZZ), polygen(GF(17)))) + sage: sage_input((polygen(ZZ), polygen(GF(17)))) # optional - sage.rings.finite_rings R1 = ZZ['x'] x1 = R1.gen() R2 = GF(17)['x'] @@ -2829,7 +2829,7 @@ def _sie_add_command(self, sif): If we never use the generators, then we don't bother with the preparser syntax.:: - sage: sage_input((ZZ['x'], ZZ['x'], GF(17)['y'])) + sage: sage_input((ZZ['x'], ZZ['x'], GF(17)['y'])) # optional - sage.rings.finite_rings R = ZZ['x'] (R, R, GF(17)['y']) """ @@ -2958,11 +2958,11 @@ def _sie_prepare(self, sif): sage: sib = SageInputBuilder() sage: sif = SageInputFormatter() - sage: sie = sib.gen(GF(13)['z']) - sage: sie._sie_parent._sie_assign_gens + sage: sie = sib.gen(GF(13)['z']) # optional - sage.rings.finite_rings + sage: sie._sie_parent._sie_assign_gens # optional - sage.rings.finite_rings False - sage: sie._sie_prepare(sif) - sage: sie._sie_parent._sie_assign_gens + sage: sie._sie_prepare(sif) # optional - sage.rings.finite_rings + sage: sie._sie_parent._sie_assign_gens # optional - sage.rings.finite_rings True """ super()._sie_prepare(sif) @@ -2982,11 +2982,11 @@ def _sie_format(self, sif): sage: sib = SageInputBuilder() sage: sif = SageInputFormatter() - sage: sie = sib.gen(GF(41)['x']) - sage: sie._sie_prepare(sif) - sage: sie._sie_format(sif) + sage: sie = sib.gen(GF(41)['x']) # optional - sage.rings.finite_rings + sage: sie._sie_prepare(sif) # optional - sage.rings.finite_rings + sage: sie._sie_format(sif) # optional - sage.rings.finite_rings ('x', 42) - sage: sif._commands + sage: sif._commands # optional - sage.rings.finite_rings 'R. = GF(41)[]\n' """ self._sie_parent._sie_add_command(sif) @@ -3007,11 +3007,11 @@ def _sie_got_preferred(self, sif): sage: sib = SageInputBuilder() sage: sif = SageInputFormatter() - sage: v = sib.gen(GF(2)['x']); w = sib.gen(GF(3)['y']) - sage: v._sie_prepare(sif); w._sie_prepare(sif) - sage: v._sie_got_preferred(sif) + sage: v = sib.gen(GF(2)['x']); w = sib.gen(GF(3)['y']) # optional - sage.rings.finite_rings + sage: v._sie_prepare(sif); w._sie_prepare(sif) # optional - sage.rings.finite_rings + sage: v._sie_got_preferred(sif) # optional - sage.rings.finite_rings True - sage: w._sie_got_preferred(sif) + sage: w._sie_got_preferred(sif) # optional - sage.rings.finite_rings True Now, we repeat the experiment, except that the generators now @@ -3021,11 +3021,11 @@ def _sie_got_preferred(self, sif): sage: sib = SageInputBuilder() sage: sif = SageInputFormatter() - sage: v = sib.gen(GF(2)['x']); w = sib.gen(GF(3)['x']) - sage: v._sie_prepare(sif); w._sie_prepare(sif) - sage: v._sie_got_preferred(sif) + sage: v = sib.gen(GF(2)['x']); w = sib.gen(GF(3)['x']) # optional - sage.rings.finite_rings + sage: v._sie_prepare(sif); w._sie_prepare(sif) # optional - sage.rings.finite_rings + sage: v._sie_got_preferred(sif) # optional - sage.rings.finite_rings False - sage: w._sie_got_preferred(sif) + sage: w._sie_got_preferred(sif) # optional - sage.rings.finite_rings False """ return self._sie_get_varname(sif) == self._sie_preferred_varname @@ -3313,18 +3313,18 @@ def format(self, e, prec): sage: sib = SageInputBuilder() sage: sif = SageInputFormatter() - sage: sie = sib(GF(5)) + sage: sie = sib(GF(5)) # optional - sage.rings.finite_rings Here we ``cheat`` by calling \method{_sie_prepare} twice, to make it use a variable.:: - sage: sie._sie_prepare(sif) - sage: sie._sie_prepare(sif) - sage: sif._commands + sage: sie._sie_prepare(sif) # optional - sage.rings.finite_rings + sage: sie._sie_prepare(sif) # optional - sage.rings.finite_rings + sage: sif._commands # optional - sage.rings.finite_rings '' - sage: sif.format(sie, 0) + sage: sif.format(sie, 0) # optional - sage.rings.finite_rings 'GF_5' - sage: sif._commands + sage: sif._commands # optional - sage.rings.finite_rings 'GF_5 = GF(5)\n' We demonstrate the use of commands, by showing how to construct @@ -3459,7 +3459,7 @@ def verify_same(a, b): ... assert(type(a) == type(b)) AssertionError - sage: verify_same(5, GF(7)(5)) + sage: verify_same(5, GF(7)(5)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... assert(a.parent() == b.parent()) diff --git a/src/sage/misc/sage_timeit.py b/src/sage/misc/sage_timeit.py index 8250b461dd4..41728099c39 100644 --- a/src/sage/misc/sage_timeit.py +++ b/src/sage/misc/sage_timeit.py @@ -37,7 +37,7 @@ class SageTimeitResult(): EXAMPLES:: sage: from sage.misc.sage_timeit import SageTimeitResult - sage: SageTimeitResult( (3, 5, int(8), pi, 'ms') ) + sage: SageTimeitResult( (3, 5, int(8), pi, 'ms') ) # optional - sage.symbolic 3 loops, best of 5: 3.1415927 ms per loop :: @@ -47,10 +47,10 @@ class SageTimeitResult(): sage: number = 7 sage: repeat = 13 sage: precision = int(5) - sage: best = pi / 10 ^ 9 + sage: best = pi / 10 ^ 9 # optional - sage.symbolic sage: order = 3 - sage: stats = (number, repeat, precision, best * scaling[order], units[order]) - sage: SageTimeitResult(stats) + sage: stats = (number, repeat, precision, best * scaling[order], units[order]) # optional - sage.symbolic + sage: SageTimeitResult(stats) # optional - sage.symbolic 7 loops, best of 13: 3.1416 ns per loop If the third argument is not a Python integer, a ``TypeError`` is raised:: @@ -69,10 +69,10 @@ def __init__(self, stats, series=None): EXAMPLES:: sage: from sage.misc.sage_timeit import SageTimeitResult - sage: SageTimeitResult( (3, 5, int(8), pi, 'ms') ) + sage: SageTimeitResult( (3, 5, int(8), pi, 'ms') ) # optional - sage.symbolic 3 loops, best of 5: 3.1415927 ms per loop - sage: s = SageTimeitResult( (3, 5, int(8), pi, 'ms'), [1.0,1.1,0.5]) - sage: s.series + sage: s = SageTimeitResult( (3, 5, int(8), pi, 'ms'), [1.0,1.1,0.5]) # optional - sage.symbolic + sage: s.series # optional - sage.symbolic [1.00000000000000, 1.10000000000000, 0.500000000000000] """ self.stats = stats @@ -85,8 +85,8 @@ def __repr__(self): EXAMPLES:: sage: from sage.misc.sage_timeit import SageTimeitResult - sage: stats = (1, 2, int(3), pi, 'ns') - sage: SageTimeitResult(stats) #indirect doctest + sage: stats = (1, 2, int(3), pi, 'ns') # optional - sage.symbolic + sage: SageTimeitResult(stats) #indirect doctest # optional - sage.symbolic 1 loop, best of 2: 3.14 ns per loop """ if self.stats[0] > 1: diff --git a/src/sage/misc/sage_timeit_class.pyx b/src/sage/misc/sage_timeit_class.pyx index d6b038c9de9..557f9725299 100644 --- a/src/sage/misc/sage_timeit_class.pyx +++ b/src/sage/misc/sage_timeit_class.pyx @@ -40,7 +40,7 @@ class SageTimeit: The input can contain newlines:: - sage: timeit("a = 2\nb=131\nfactor(a^b-1)", number=25) + sage: timeit("a = 2\nb=131\nfactor(a^b-1)", number=25) # optional - sage.libs.pari 25 loops, best of 3: ... per loop .. SEEALSO:: :func:`runsnake` diff --git a/src/sage/misc/sagedoc.py b/src/sage/misc/sagedoc.py index 5a69dbcb0cc..d453fb141b2 100644 --- a/src/sage/misc/sagedoc.py +++ b/src/sage/misc/sagedoc.py @@ -20,7 +20,7 @@ sage: from sage.env import SAGE_DOC sage: docfilename = os.path.join(SAGE_DOC, 'html', 'en', 'reference', 'calculus', 'sage', 'symbolic', 'expression.html') - sage: with open(docfilename) as fobj: # optional - sagemath_doc_html + sage: with open(docfilename) as fobj: # optional - sagemath_doc_html ....: for line in fobj: ....: if "#sage.symbolic.expression.Expression.numerical_approx" in line: ....: print(line) @@ -623,10 +623,10 @@ def format(s, embedded=False): EXAMPLES:: sage: from sage.misc.sagedoc import format - sage: identity_matrix(2).rook_vector.__doc__[191:263] + sage: identity_matrix(2).rook_vector.__doc__[191:263] # optional - sage.modules 'Let `A` be an `m` by `n` (0,1)-matrix. We identify `A` with a chessboard' - sage: format(identity_matrix(2).rook_vector.__doc__[191:263]) + sage: format(identity_matrix(2).rook_vector.__doc__[191:263]) # optional - sage.modules 'Let A be an m by n (0,1)-matrix. We identify A with a chessboard\n' If the first line of the string is 'nodetex', remove 'nodetex' but @@ -643,14 +643,14 @@ def format(s, embedded=False): 'identity_matrix>>>\n' sage: format('<<>>') '...Definition: identity_matrix(...' - sage: format('<<>>')[:28] # optional - sphinx + sage: format('<<>>')[:28] # optional - sphinx 'Definition: identity_matrix(' TESTS: We check that the todo Sphinx extension is correctly activated:: - sage: sage.misc.sagedoc.format(sage.combinat.ranker.on_fly.__doc__) # optional - sphinx + sage: sage.misc.sagedoc.format(sage.combinat.ranker.on_fly.__doc__) # optional - sphinx " Returns ... Todo: add tests as in combinat::rankers\n" In the following use case, the ``nodetex`` directive would have been ignored prior @@ -664,9 +664,9 @@ def format(s, embedded=False): ....: " `x \\geq y`", ....: " '''", ....: " return -x"] - sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython + sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython sage: from sage.misc.sageinspect import sage_getdoc - sage: print(sage_getdoc(testfunc)) # optional - sage.misc.cython + sage: print(sage_getdoc(testfunc)) # optional - sage.misc.cython This is a doc string with raw latex @@ -694,7 +694,7 @@ def format(s, embedded=False): Check that backslashes are preserved in code blocks (:trac:`29140`):: - sage: format('::\n' # optional - sphinx + sage: format('::\n' # optional - sphinx ....: '\n' ....: r' sage: print(r"\\\\.")' '\n' ....: r' \\\\.') @@ -1077,7 +1077,8 @@ def search_src(string, extra1='', extra2='', extra3='', extra4='', Note that you can do tab completion on the ``module`` string. Another way to accomplish a similar search:: - sage: len(search_src("matrix", path_re="calc", interact=False).splitlines()) > 15 + sage: len(search_src("matrix", path_re="calc", # optional - sage.modules + ....: interact=False).splitlines()) > 15 True The following produces an error because the string 'fetch(' is a @@ -1106,7 +1107,8 @@ def search_src(string, extra1='', extra2='', extra3='', extra4='', sage: s = search_src('MatRiX', path_re='matrix', interact=False); s.find('x') > 0 True - sage: s = search_src('MatRiX', path_re='matrix', interact=False, ignore_case=False); s.find('x') > 0 + sage: s = search_src('MatRiX', path_re='matrix', + ....: interact=False, ignore_case=False); s.find('x') > 0 False Searches are by default restricted to single lines, but this can @@ -1118,7 +1120,8 @@ def search_src(string, extra1='', extra2='', extra3='', extra4='', sage: len(search_src('log', 'derivative', interact=False).splitlines()) < 40 True - sage: len(search_src('log', 'derivative', interact=False, multiline=True).splitlines()) > 70 + sage: len(search_src('log', 'derivative', + ....: interact=False, multiline=True).splitlines()) > 70 True A little recursive narcissism: let's do a doctest that searches for @@ -1196,13 +1199,13 @@ def search_doc(string, extra1='', extra2='', extra3='', extra4='', counting the length of ``search_doc('tree', interact=False).splitlines()`` gives the number of matches. :: - sage: N = len(search_doc('tree', interact=False).splitlines()) # optional - sagemath_doc_html, long time - sage: L = search_doc('tree', whole_word=True, interact=False).splitlines() # optional - sagemath_doc_html, long time - sage: len(L) < N # optional - sagemath_doc_html, long time + sage: N = len(search_doc('tree', interact=False).splitlines()) # optional - sagemath_doc_html, long time + sage: L = search_doc('tree', whole_word=True, interact=False).splitlines() # optional - sagemath_doc_html, long time + sage: len(L) < N # optional - sagemath_doc_html, long time True sage: import re sage: tree_re = re.compile(r'(^|\W)tree(\W|$)', re.I) - sage: all(tree_re.search(l) for l in L) # optional - sagemath_doc_html, long time + sage: all(tree_re.search(l) for l in L) # optional - sagemath_doc_html, long time True """ return _search_src_or_doc('doc', string, extra1=extra1, extra2=extra2, @@ -1362,8 +1365,8 @@ def my_getsource(obj, oname=''): EXAMPLES:: sage: from sage.misc.sagedoc import my_getsource - sage: s = my_getsource(identity_matrix) - sage: s[15:34] + sage: s = my_getsource(identity_matrix) # optional - sage.modules + sage: s[15:34] # optional - sage.modules 'def identity_matrix' """ try: @@ -1399,9 +1402,9 @@ class _sage_doc: EXAMPLES:: - sage: browse_sage_doc._open("reference", testing=True)[0] # optional - sagemath_doc_html, indirect doctest + sage: browse_sage_doc._open("reference", testing=True)[0] # optional - sagemath_doc_html, indirect doctest 'http://localhost:8000/doc/live/reference/index.html' - sage: browse_sage_doc(identity_matrix, 'rst')[-107:-47] + sage: browse_sage_doc(identity_matrix, 'rst')[-107:-47] # optional - sage.modules 'Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring' """ def __init__(self): @@ -1429,19 +1432,19 @@ def __call__(self, obj, output='html', view=True): EXAMPLES:: - sage: browse_sage_doc(identity_matrix, 'rst') + sage: browse_sage_doc(identity_matrix, 'rst') # optional - sage.modules "...**File:**...**Type:**...**Definition:** identity_matrix..." - sage: identity_matrix.__doc__ in browse_sage_doc(identity_matrix, 'rst') + sage: identity_matrix.__doc__ in browse_sage_doc(identity_matrix, 'rst') # optional - sage.modules True - sage: browse_sage_doc(identity_matrix, 'html', False) # optional - sphinx sagemath_doc_html + sage: browse_sage_doc(identity_matrix, 'html', False) # optional - sphinx sagemath_doc_html '...div...File:...Type:...Definition:...identity_matrix...' In the 'text' version, double colons have been replaced with single ones (among other things):: - sage: '::' in browse_sage_doc(identity_matrix, 'rst') + sage: '::' in browse_sage_doc(identity_matrix, 'rst') # optional - sage.modules True - sage: '::' in browse_sage_doc(identity_matrix, 'text') # optional - sphinx + sage: '::' in browse_sage_doc(identity_matrix, 'text') # optional - sphinx False """ if output != 'html' and view: @@ -1571,9 +1574,9 @@ def _open(self, name, testing=False): EXAMPLES:: - sage: browse_sage_doc._open("reference", testing=True)[0] # optional - sagemath_doc_html + sage: browse_sage_doc._open("reference", testing=True)[0] # optional - sagemath_doc_html 'http://localhost:8000/doc/live/reference/index.html' - sage: browse_sage_doc._open("tutorial", testing=True)[1] # optional - sagemath_doc_html + sage: browse_sage_doc._open("tutorial", testing=True)[1] # optional - sagemath_doc_html '.../html/en/tutorial/index.html' """ url = self._base_url + os.path.join(name, "index.html") diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py index 7264d1b697b..6f0afd47599 100644 --- a/src/sage/misc/sageinspect.py +++ b/src/sage/misc/sageinspect.py @@ -252,16 +252,16 @@ def _extract_embedded_position(docstring): sage: from sage.misc.sageinspect import _extract_embedded_position sage: import inspect - sage: _extract_embedded_position(inspect.getdoc(var))[1][-21:] + sage: _extract_embedded_position(inspect.getdoc(var))[1][-21:] # optional - sage.symbolic 'sage/calculus/var.pyx' TESTS: The following has been fixed in :trac:`13916`:: - sage: cython('''cpdef test_funct(x,y): return''') # optional - sage.misc.cython - sage: func_doc = inspect.getdoc(test_funct) # optional - sage.misc.cython - sage: with open(_extract_embedded_position(func_doc)[1]) as f: # optional - sage.misc.cython + sage: cython('''cpdef test_funct(x,y): return''') # optional - sage.misc.cython + sage: func_doc = inspect.getdoc(test_funct) # optional - sage.misc.cython + sage: with open(_extract_embedded_position(func_doc)[1]) as f: # optional - sage.misc.cython ....: print(f.read()) cpdef test_funct(x,y): return @@ -272,10 +272,10 @@ def _extract_embedded_position(docstring): sage: from sage.env import DOT_SAGE sage: from sage.misc.sage_ostools import restore_cwd - sage: with restore_cwd(DOT_SAGE): # optional - sage.misc.cython + sage: with restore_cwd(DOT_SAGE): # optional - sage.misc.cython ....: cython('''cpdef test_funct(x,y): return''') - sage: func_doc = inspect.getdoc(test_funct) # optional - sage.misc.cython - sage: with open(_extract_embedded_position(func_doc)[1]) as f: # optional - sage.misc.cython + sage: func_doc = inspect.getdoc(test_funct) # optional - sage.misc.cython + sage: with open(_extract_embedded_position(func_doc)[1]) as f: # optional - sage.misc.cython ....: print(f.read()) cpdef test_funct(x,y): return @@ -1118,7 +1118,7 @@ def _sage_getargspec_from_ast(source): FullArgSpec(args=['a', 'b', 'c', 'd'], varargs=None, varkw=None, defaults=(2, {'a': [4, 5.5, False]}, (None, True)), kwonlyargs=[], kwonlydefaults=None, annotations={}) sage: from_ast(s) == inspect.getfullargspec(context['f']) True - sage: set(from_ast(sms.sage_getsource(x)) == inspect.getfullargspec(x) for x in [factor, identity_matrix, Graph.__init__]) + sage: set(from_ast(sms.sage_getsource(x)) == inspect.getfullargspec(x) for x in [factor, identity_matrix, Graph.__init__]) # optional - sage.modules sage.graphs {True} """ ast_args = ast.parse(source.lstrip()).body[0].args @@ -1203,17 +1203,21 @@ def _sage_getargspec_cython(source): sage: def dummy_python(self, *args, x=1): pass sage: sgc("def dummy_python(self, *args, x=1): pass") - FullArgSpec(args=['self', 'x'], varargs='args', varkw=None, defaults=(1,), kwonlyargs=[], kwonlydefaults=None, annotations={}) - sage: cython("def dummy_cython(self, *args, x=1): pass") + FullArgSpec(args=['self', 'x'], varargs='args', varkw=None, defaults=(1,), + kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: cython("def dummy_cython(self, *args, x=1): pass") # optional - sage.misc.cython sage: sgc("def dummy_cython(self, *args, x=1): pass") - FullArgSpec(args=['self', 'x'], varargs='args', varkw=None, defaults=(1,), kwonlyargs=[], kwonlydefaults=None, annotations={}) + FullArgSpec(args=['self', 'x'], varargs='args', varkw=None, defaults=(1,), + kwonlyargs=[], kwonlydefaults=None, annotations={}) In some examples above, a syntax error was raised when a type definition contains a pointer. An exception is made for ``char*``, since C strings are acceptable input in public Cython functions:: sage: sgc('def f(char *x = "a string", z = {(1,2,3): True}): pass') - FullArgSpec(args=['x', 'z'], varargs=None, varkw=None, defaults=('a string', {(1, 2, 3): True}), kwonlyargs=[], kwonlydefaults=None, annotations={}) + FullArgSpec(args=['x', 'z'], varargs=None, varkw=None, + defaults=('a string', {(1, 2, 3): True}), + kwonlyargs=[], kwonlydefaults=None, annotations={}) AUTHORS: @@ -1352,34 +1356,34 @@ def sage_getfile(obj): sage: from sage.misc.sageinspect import sage_getfile sage: sage_getfile(sage.rings.rational) '...sage/rings/rational.pyx' - sage: sage_getfile(Sq) + sage: sage_getfile(Sq) # optional - sage.combinat sage.modules '...sage/algebras/steenrod/steenrod_algebra.py' - sage: sage_getfile(x) + sage: sage_getfile(x) # optional - sage.symbolic '...sage/symbolic/expression.pyx' The following tests against some bugs fixed in :trac:`9976`:: - sage: obj = sage.combinat.partition_algebra.SetPartitionsAk - sage: obj = sage.combinat.partition_algebra.SetPartitionsAk - sage: sage_getfile(obj) + sage: obj = sage.combinat.partition_algebra.SetPartitionsAk # optional - sage.combinat + sage: obj = sage.combinat.partition_algebra.SetPartitionsAk # optional - sage.combinat + sage: sage_getfile(obj) # optional - sage.combinat '...sage/combinat/partition_algebra.py' And here is another bug, fixed in :trac:`11298`:: sage: P. = QQ[] - sage: sage_getfile(P) + sage: sage_getfile(P) # optional - sage.libs.singular '...sage/rings/polynomial/multi_polynomial_libsingular...' A problem fixed in :trac:`16309`:: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: class Bar: pass ....: cdef class Foo: pass ....: ''') - sage: sage_getfile(Bar) # optional - sage.misc.cython + sage: sage_getfile(Bar) # optional - sage.misc.cython '...pyx' - sage: sage_getfile(Foo) # optional - sage.misc.cython + sage: sage_getfile(Foo) # optional - sage.misc.cython '...pyx' By :trac:`18249`, we return an empty string for Python builtins. In that @@ -1433,9 +1437,9 @@ def sage_getfile_relative(obj): sage: from sage.misc.sageinspect import sage_getfile_relative sage: sage_getfile_relative(sage.rings.rational) 'sage/rings/rational.pyx' - sage: sage_getfile_relative(Sq) + sage: sage_getfile_relative(Sq) # optional - sage.combinat sage.modules 'sage/algebras/steenrod/steenrod_algebra.py' - sage: sage_getfile_relative(x) + sage: sage_getfile_relative(x) # optional - sage.symbolic 'sage/symbolic/expression.pyx' sage: sage_getfile_relative(range) '' @@ -1504,46 +1508,55 @@ def sage_getargspec(obj): We now run sage_getargspec on some functions from the Sage library:: - sage: sage_getargspec(identity_matrix) - FullArgSpec(args=['ring', 'n', 'sparse'], varargs=None, varkw=None, defaults=(0, False), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sage_getargspec(identity_matrix) # optional - sage.modules + FullArgSpec(args=['ring', 'n', 'sparse'], varargs=None, varkw=None, defaults=(0, False), + kwonlyargs=[], kwonlydefaults=None, annotations={}) sage: sage_getargspec(factor) - FullArgSpec(args=['n', 'proof', 'int_', 'algorithm', 'verbose'], varargs=None, varkw='kwds', defaults=(None, False, 'pari', 0), kwonlyargs=[], kwonlydefaults=None, annotations={}) + FullArgSpec(args=['n', 'proof', 'int_', 'algorithm', 'verbose'], varargs=None, varkw='kwds', + defaults=(None, False, 'pari', 0), kwonlyargs=[], kwonlydefaults=None, annotations={}) In the case of a class or a class instance, the ``ArgSpec`` of the ``__new__``, ``__init__`` or ``__call__`` method is returned:: sage: P. = QQ[] sage: sage_getargspec(P) - FullArgSpec(args=['base_ring', 'n', 'names', 'order'], varargs=None, varkw=None, defaults=('degrevlex',), kwonlyargs=[], kwonlydefaults=None, annotations={}) + FullArgSpec(args=['base_ring', 'n', 'names', 'order'], varargs=None, varkw=None, + defaults=('degrevlex',), kwonlyargs=[], kwonlydefaults=None, annotations={}) sage: sage_getargspec(P.__class__) - FullArgSpec(args=['self', 'x'], varargs='args', varkw='kwds', defaults=(0,), kwonlyargs=[], kwonlydefaults=None, annotations={}) + FullArgSpec(args=['self', 'x'], varargs='args', varkw='kwds', defaults=(0,), + kwonlyargs=[], kwonlydefaults=None, annotations={}) The following tests against various bugs that were fixed in :trac:`9976`:: sage: from sage.rings.polynomial.real_roots import bernstein_polynomial_factory_ratlist sage: sage_getargspec(bernstein_polynomial_factory_ratlist.coeffs_bitsize) - FullArgSpec(args=['self'], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) + FullArgSpec(args=['self'], varargs=None, varkw=None, defaults=None, + kwonlyargs=[], kwonlydefaults=None, annotations={}) sage: from sage.rings.polynomial.pbori.pbori import BooleanMonomialMonoid sage: sage_getargspec(BooleanMonomialMonoid.gen) - FullArgSpec(args=['self', 'i'], varargs=None, varkw=None, defaults=(0,), kwonlyargs=[], kwonlydefaults=None, annotations={}) + FullArgSpec(args=['self', 'i'], varargs=None, varkw=None, defaults=(0,), + kwonlyargs=[], kwonlydefaults=None, annotations={}) sage: I = P*[x,y] sage: sage_getargspec(I.groebner_basis) FullArgSpec(args=['self', 'algorithm', 'deg_bound', 'mult_bound', 'prot'], - varargs='args', varkw='kwds', defaults=('', None, None, False), kwonlyargs=[], kwonlydefaults=None, annotations={}) - sage: cython("cpdef int foo(x,y) except -1: return 1") - sage: sage_getargspec(foo) - FullArgSpec(args=['x', 'y'], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) + varargs='args', varkw='kwds', defaults=('', None, None, False), + kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: cython("cpdef int foo(x,y) except -1: return 1") # optional - sage.misc.cython + sage: sage_getargspec(foo) # optional - sage.misc.cython + FullArgSpec(args=['x', 'y'], varargs=None, varkw=None, defaults=None, + kwonlyargs=[], kwonlydefaults=None, annotations={}) If a ``functools.partial`` instance is involved, we see no other meaningful solution than to return the argspec of the underlying function:: - sage: def f(a,b,c,d=1): - ....: return a+b+c+d + sage: def f(a, b, c, d=1): + ....: return a + b + c + d sage: import functools - sage: f1 = functools.partial(f, 1,c=2) + sage: f1 = functools.partial(f, 1, c=2) sage: sage_getargspec(f1) - FullArgSpec(args=['a', 'b', 'c', 'd'], varargs=None, varkw=None, defaults=(1,), kwonlyargs=[], kwonlydefaults=None, annotations={}) + FullArgSpec(args=['a', 'b', 'c', 'd'], varargs=None, varkw=None, defaults=(1,), + kwonlyargs=[], kwonlydefaults=None, annotations={}) TESTS: @@ -1564,34 +1577,38 @@ def sage_getargspec(obj): ....: ' def _sage_src_(self):', ....: ' return "def foo(x, a=\\\')\\\"\\\', b={(2+1):\\\'bar\\\', not 1:3, 3<<4:5}): return\\n"', ....: ' def __call__(self, m,n): return "something"'] - sage: cython('\n'.join(cython_code)) - sage: O = MyClass() - sage: print(sage.misc.sageinspect.sage_getsource(O)) + sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython + sage: O = MyClass() # optional - sage.misc.cython + sage: print(sage.misc.sageinspect.sage_getsource(O)) # optional - sage.misc.cython def foo(x, a=')"', b={(2+1):'bar', not 1:3, 3<<4:5}): return - sage: spec = sage.misc.sageinspect.sage_getargspec(O) - sage: spec.args, spec.varargs, spec.varkw + sage: spec = sage.misc.sageinspect.sage_getargspec(O) # optional - sage.misc.cython + sage: spec.args, spec.varargs, spec.varkw # optional - sage.misc.cython (['x', 'a', 'b'], None, None) - sage: spec.defaults[0] + sage: spec.defaults[0] # optional - sage.misc.cython ')"' - sage: sorted(spec.defaults[1].items(), key=lambda x: str(x)) + sage: sorted(spec.defaults[1].items(), key=lambda x: str(x)) # optional - sage.misc.cython [(3, 'bar'), (48, 5), (False, 3)] - sage: sage.misc.sageinspect.sage_getargspec(O.__call__) - FullArgSpec(args=['self', 'm', 'n'], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sage.misc.sageinspect.sage_getargspec(O.__call__) # optional - sage.misc.cython + FullArgSpec(args=['self', 'm', 'n'], varargs=None, varkw=None, defaults=None, + kwonlyargs=[], kwonlydefaults=None, annotations={}) :: - sage: cython('def foo(x, a=\'\\\')"\', b={not (2+1==3):\'bar\'}): return') - sage: print(sage.misc.sageinspect.sage_getsource(foo)) + sage: cython('def foo(x, a=\'\\\')"\', b={not (2+1==3):\'bar\'}): return') # optional - sage.misc.cython + sage: print(sage.misc.sageinspect.sage_getsource(foo)) # optional - sage.misc.cython def foo(x, a='\')"', b={not (2+1==3):'bar'}): return - sage: sage.misc.sageinspect.sage_getargspec(foo) - FullArgSpec(args=['x', 'a', 'b'], varargs=None, varkw=None, defaults=('\')"', {False: 'bar'}), kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sage.misc.sageinspect.sage_getargspec(foo) # optional - sage.misc.cython + FullArgSpec(args=['x', 'a', 'b'], varargs=None, varkw=None, + defaults=('\')"', {False: 'bar'}), + kwonlyargs=[], kwonlydefaults=None, annotations={}) The following produced a syntax error before the patch at :trac:`11913`, see also :trac:`26906`:: - sage: sage.misc.sageinspect.sage_getargspec(r.lm) # optional - rpy2 - FullArgSpec(args=['self'], varargs='args', varkw='kwds', defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) + sage: sage.misc.sageinspect.sage_getargspec(r.lm) # optional - rpy2 + FullArgSpec(args=['self'], varargs='args', varkw='kwds', defaults=None, + kwonlyargs=[], kwonlydefaults=None, annotations={}) The following was fixed in :trac:`16309`:: @@ -1605,23 +1622,28 @@ def foo(x, a='\')"', b={not (2+1==3):'bar'}): return ....: cpdef meet(categories, bint as_list = False, tuple ignore_axioms=(), tuple axioms=()): pass ....: ''') sage: sage_getargspec(Foo.join) - FullArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, varkw=None, defaults=(False, (), ()), kwonlyargs=[], kwonlydefaults=None, annotations={}) + FullArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, varkw=None, + defaults=(False, (), ()), kwonlyargs=[], kwonlydefaults=None, annotations={}) sage: sage_getargspec(Bar.join) - FullArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, varkw=None, defaults=(False, (), ()), kwonlyargs=[], kwonlydefaults=None, annotations={}) + FullArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, varkw=None, + defaults=(False, (), ()), kwonlyargs=[], kwonlydefaults=None, annotations={}) sage: sage_getargspec(Bar.meet) - FullArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, varkw=None, defaults=(False, (), ()), kwonlyargs=[], kwonlydefaults=None, annotations={}) + FullArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, varkw=None, + defaults=(False, (), ()), kwonlyargs=[], kwonlydefaults=None, annotations={}) Test that :trac:`17009` is fixed:: sage: sage_getargspec(gap) - FullArgSpec(args=['self', 'x', 'name'], varargs=None, varkw=None, defaults=(None,), kwonlyargs=[], kwonlydefaults=None, annotations={}) + FullArgSpec(args=['self', 'x', 'name'], varargs=None, varkw=None, + defaults=(None,), kwonlyargs=[], kwonlydefaults=None, annotations={}) By :trac:`17814`, the following gives the correct answer (previously, the defaults would have been found ``None``):: sage: from sage.misc.nested_class import MainClass sage: sage_getargspec(MainClass.NestedClass.NestedSubClass.dummy) - FullArgSpec(args=['self', 'x', 'r'], varargs='args', varkw='kwds', defaults=((1, 2, 3.4),), kwonlyargs=[], kwonlydefaults=None, annotations={}) + FullArgSpec(args=['self', 'x', 'r'], varargs='args', varkw='kwds', + defaults=((1, 2, 3.4),), kwonlyargs=[], kwonlydefaults=None, annotations={}) In :trac:`18249` was decided to return a generic signature for Python builtin functions, rather than to raise an error (which is what Python's @@ -1867,9 +1889,9 @@ def sage_getdef(obj, obj_name=''): EXAMPLES:: sage: from sage.misc.sageinspect import sage_getdef - sage: sage_getdef(identity_matrix) + sage: sage_getdef(identity_matrix) # optional - sage.modules '(ring, n=0, sparse=False)' - sage: sage_getdef(identity_matrix, 'identity_matrix') + sage: sage_getdef(identity_matrix, 'identity_matrix') # optional - sage.modules 'identity_matrix(ring, n=0, sparse=False)' Check that :trac:`6848` has been fixed:: @@ -1920,8 +1942,8 @@ def _sage_getdoc_unformatted(obj): Integer(x=None, base=0) File: sage/rings/integer.pyx (starting at line ...) - The ``Integer`` class represents arbitrary precision - integers. It derives from the ``Element`` class, so + The :class:`Integer` class represents arbitrary precision + integers. It derives from the :class:`Element` class, so integers can be used as ring elements anywhere in Sage. ... @@ -1995,8 +2017,8 @@ def sage_getdoc_original(obj): sage: print(sage_getdoc_original(sage.rings.integer.Integer)) - The ``Integer`` class represents arbitrary precision - integers. It derives from the ``Element`` class, so + The :class:`Integer` class represents arbitrary precision + integers. It derives from the :class:`Element` class, so integers can be used as ring elements anywhere in Sage. ... @@ -2034,7 +2056,7 @@ def sage_getdoc_original(obj): If an instance of a class does not have its own docstring, the docstring of its class results:: - sage: sage_getdoc_original(sage.plot.colors.aliceblue) == sage_getdoc_original(sage.plot.colors.Color) + sage: sage_getdoc_original(sage.plot.colors.aliceblue) == sage_getdoc_original(sage.plot.colors.Color) # optional - sage.plot True """ @@ -2077,7 +2099,7 @@ def sage_getdoc(obj, obj_name='', embedded=False): EXAMPLES:: sage: from sage.misc.sageinspect import sage_getdoc - sage: sage_getdoc(identity_matrix)[87:124] + sage: sage_getdoc(identity_matrix)[87:124] # optional - sage.modules 'Return the n x n identity matrix over' sage: def f(a,b,c,d=1): return a+b+c+d ... @@ -2130,9 +2152,9 @@ def sage_getsource(obj): EXAMPLES:: sage: from sage.misc.sageinspect import sage_getsource - sage: sage_getsource(identity_matrix)[19:60] + sage: sage_getsource(identity_matrix)[19:60] # optional - sage.modules 'identity_matrix(ring, n=0, sparse=False):' - sage: sage_getsource(identity_matrix)[19:60] + sage: sage_getsource(identity_matrix)[19:60] # optional - sage.modules 'identity_matrix(ring, n=0, sparse=False):' AUTHORS: @@ -2309,9 +2331,9 @@ def sage_getsourcelines(obj): EXAMPLES:: sage: from sage.misc.sageinspect import sage_getsourcelines - sage: sage_getsourcelines(matrix)[1] + sage: sage_getsourcelines(matrix)[1] # optional - sage.modules 21 - sage: sage_getsourcelines(matrix)[0][0] + sage: sage_getsourcelines(matrix)[0][0] # optional - sage.modules 'def matrix(*args, **kwds):\n' Some classes customize this using a ``_sage_src_lines_`` method, @@ -2326,8 +2348,8 @@ def sage_getsourcelines(obj): TESTS:: - sage: cython('''cpdef test_funct(x,y): return''') # optional - sage.misc.cython - sage: sage_getsourcelines(test_funct) # optional - sage.misc.cython + sage: cython('''cpdef test_funct(x,y): return''') # optional - sage.misc.cython + sage: sage_getsourcelines(test_funct) # optional - sage.misc.cython (['cpdef test_funct(x,y): return\n'], 1) The following tests that an instance of ``functools.partial`` is correctly @@ -2548,16 +2570,16 @@ def sage_getvariablename(self, omit_underscore_names=True): EXAMPLES:: sage: from sage.misc.sageinspect import sage_getvariablename - sage: A = random_matrix(ZZ, 100) - sage: sage_getvariablename(A) + sage: A = random_matrix(ZZ, 100) # optional - sage.modules + sage: sage_getvariablename(A) # optional - sage.modules 'A' - sage: B = A - sage: sage_getvariablename(A) + sage: B = A # optional - sage.modules + sage: sage_getvariablename(A) # optional - sage.modules ['A', 'B'] If an object is not assigned to a variable, an empty list is returned:: - sage: sage_getvariablename(random_matrix(ZZ, 60)) + sage: sage_getvariablename(random_matrix(ZZ, 60)) # optional - sage.modules [] """ result = [] diff --git a/src/sage/misc/superseded.py b/src/sage/misc/superseded.py index c158317ca5a..725d524a591 100644 --- a/src/sage/misc/superseded.py +++ b/src/sage/misc/superseded.py @@ -107,7 +107,7 @@ def deprecation_cython(issue_number, message, stacklevel=3): with the same callsite reference as `deprecation` in a python function, whereas `deprecation` in a cython function does not:: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: from sage.misc.superseded import deprecation_cython, deprecation ....: def foo1(): @@ -117,7 +117,7 @@ def deprecation_cython(issue_number, message, stacklevel=3): ....: ''') sage: def foo3(): ....: deprecation(100, "boo") - sage: if True: # Execute the three "with" blocks as one doctest # optional - sage.misc.cython + sage: if True: # Execute the three "with" blocks as one doctest # optional - sage.misc.cython ....: with warnings.catch_warnings(record=True) as w1: ....: warnings.simplefilter("always") ....: foo1() @@ -127,9 +127,9 @@ def deprecation_cython(issue_number, message, stacklevel=3): ....: with warnings.catch_warnings(record=True) as w3: ....: warnings.simplefilter("always") ....: foo3() - sage: w1[0].filename == w3[0].filename # optional - sage.misc.cython + sage: w1[0].filename == w3[0].filename # optional - sage.misc.cython True - sage: w2[0].filename == w3[0].filename # optional - sage.misc.cython + sage: w2[0].filename == w3[0].filename # optional - sage.misc.cython False """ warning(issue_number, message, DeprecationWarning, stacklevel) @@ -353,9 +353,9 @@ def __init__(self, issue_number, func, module, instance=None, unbound=None): TESTS:: sage: from sage.misc.superseded import deprecated_function_alias - sage: g = deprecated_function_alias(13109, number_of_partitions) + sage: g = deprecated_function_alias(13109, number_of_partitions) # optional - sage.combinat sage: from sage.misc.superseded import deprecated_function_alias - sage: g.__doc__ + sage: g.__doc__ # optional - sage.combinat 'Deprecated: Use :func:`number_of_partitions` instead.\nSee :trac:`13109` for details.\n\n' """ _check_issue_number(issue_number) @@ -383,8 +383,8 @@ def __name__(self): TESTS:: sage: from sage.misc.superseded import deprecated_function_alias - sage: g = deprecated_function_alias(13109, number_of_partitions) - sage: g.__name__ + sage: g = deprecated_function_alias(13109, number_of_partitions) # optional - sage.combinat + sage: g.__name__ # optional - sage.combinat 'g' sage: from sage.misc.superseded import deprecated_function_alias @@ -396,14 +396,14 @@ def __name__(self): sage: cls().old_meth.__name__ 'old_meth' - sage: cython('\n'.join([ # optional - sage.misc.cython + sage: cython('\n'.join([ # optional - sage.misc.cython ....: r"from sage.misc.superseded import deprecated_function_alias", ....: r"cdef class cython_cls():", ....: r" def new_cython_meth(self):", ....: r" return 1", ....: r" old_cython_meth = deprecated_function_alias(13109, new_cython_meth)" ....: ])) - sage: cython_cls().old_cython_meth.__name__ # optional - sage.misc.cython + sage: cython_cls().old_cython_meth.__name__ # optional - sage.misc.cython 'old_cython_meth' """ # first look through variables in stack frames @@ -515,9 +515,10 @@ def deprecated_function_alias(issue_number, func): EXAMPLES:: sage: from sage.misc.superseded import deprecated_function_alias - sage: g = deprecated_function_alias(13109, number_of_partitions) - sage: g(5) - doctest:...: DeprecationWarning: g is deprecated. Please use sage.combinat.partition.number_of_partitions instead. + sage: g = deprecated_function_alias(13109, number_of_partitions) # optional - sage.combinat + sage: g(5) # optional - sage.combinat + doctest:...: DeprecationWarning: g is deprecated. + Please use sage.combinat.partition.number_of_partitions instead. See https://github.com/sagemath/sage/issues/13109 for details. 7 diff --git a/src/sage/misc/table.py b/src/sage/misc/table.py index cbd8b083a6b..4afcd513ce9 100644 --- a/src/sage/misc/table.py +++ b/src/sage/misc/table.py @@ -106,7 +106,8 @@ class table(SageObject): information. The same goes for ``header_column``. Passing lists for both arguments simultaneously is not supported. :: - sage: table([(x,n(sin(x), digits=2)) for x in [0..3]], header_row=["$x$", r"$\sin(x)$"], frame=True) + sage: table([(x,n(sin(x), digits=2)) for x in [0..3]], # optional - sage.symbolic + ....: header_row=["$x$", r"$\sin(x)$"], frame=True) +-----+-----------+ | $x$ | $\sin(x)$ | +=====+===========+ @@ -122,7 +123,9 @@ class table(SageObject): You can create the transpose of this table in several ways, for example, "by hand," that is, changing the data defining the table:: - sage: table(rows=[[x for x in [0..3]], [n(sin(x), digits=2) for x in [0..3]]], header_column=['$x$', r'$\sin(x)$'], frame=True) + sage: table(rows=[[x for x in [0..3]], # optional - sage.symbolic + ....: [n(sin(x), digits=2) for x in [0..3]]], + ....: header_column=['$x$', r'$\sin(x)$'], frame=True) +-----------++------+------+------+------+ | $x$ || 0 | 1 | 2 | 3 | +-----------++------+------+------+------+ @@ -132,7 +135,8 @@ class table(SageObject): or by passing the original data as the ``columns`` of the table and using ``header_column`` instead of ``header_row``:: - sage: table(columns=[(x,n(sin(x), digits=2)) for x in [0..3]], header_column=['$x$', r'$\sin(x)$'], frame=True) + sage: table(columns=[(x, n(sin(x), digits=2)) for x in [0..3]], # optional - sage.symbolic + ....: header_column=['$x$', r'$\sin(x)$'], frame=True) +-----------++------+------+------+------+ | $x$ || 0 | 1 | 2 | 3 | +-----------++------+------+------+------+ @@ -141,7 +145,8 @@ class table(SageObject): or by taking the :meth:`transpose` of the original table:: - sage: table(rows=[(x,n(sin(x), digits=2)) for x in [0..3]], header_row=['$x$', r'$\sin(x)$'], frame=True).transpose() + sage: table(rows=[(x, n(sin(x), digits=2)) for x in [0..3]], # optional - sage.symbolic + ....: header_row=['$x$', r'$\sin(x)$'], frame=True).transpose() +-----------++------+------+------+------+ | $x$ || 0 | 1 | 2 | 3 | +-----------++------+------+------+------+ @@ -170,11 +175,12 @@ class table(SageObject): To generate HTML you should use ``html(table(...))``:: - sage: data = [["$x$", r"$\sin(x)$"]] + [(x,n(sin(x), digits=2)) for x in [0..3]] - sage: output = html(table(data, header_row=True, frame=True)) - sage: type(output) + sage: data = [["$x$", r"$\sin(x)$"]] + [(x, n(sin(x), digits=2)) # optional - sage.symbolic + ....: for x in [0..3]] + sage: output = html(table(data, header_row=True, frame=True)) # optional - sage.symbolic + sage: type(output) # optional - sage.symbolic - sage: print(output) + sage: print(output) # optional - sage.symbolic
@@ -286,15 +292,15 @@ def __eq__(self, other): EXAMPLES:: - sage: rows = [['a', 'b', 'c'], [1,plot(sin(x)),3], [4,5,identity_matrix(2)]] - sage: T = table(rows, header_row=True) - sage: T2 = table(rows, header_row=True) - sage: T is T2 + sage: rows = [['a', 'b', 'c'], [1,plot(sin(x)),3], [4,5,identity_matrix(2)]] # optional - sage.matrix sage.plot + sage: T = table(rows, header_row=True) # optional - sage.matrix sage.plot + sage: T2 = table(rows, header_row=True) # optional - sage.matrix sage.plot + sage: T is T2 # optional - sage.matrix sage.plot False - sage: T == T2 + sage: T == T2 # optional - sage.matrix sage.plot True - sage: T2.options(frame=True) - sage: T == T2 + sage: T2.options(frame=True) # optional - sage.matrix sage.plot + sage: T == T2 # optional - sage.matrix sage.plot False """ return (self._rows == other._rows and self.options() == other.options()) @@ -561,8 +567,9 @@ def _latex_(self): EXAMPLES:: sage: from sage.misc.table import table - sage: a = [[r'$\sin(x)$', '$x$', 'text'], [1,34342,3], [identity_matrix(2),5,6]] - sage: latex(table(a)) # indirect doctest + sage: a = [[r'$\sin(x)$', '$x$', 'text'], # optional - sage.matrix + ....: [1, 34342, 3], [identity_matrix(2), 5, 6]] + sage: latex(table(a)) # indirect doctest # optional - sage.matrix \begin{tabular}{lll} $\sin(x)$ & $x$ & text \\ $1$ & $34342$ & $3$ \\ @@ -571,7 +578,7 @@ def _latex_(self): 0 & 1 \end{array}\right)$ & $5$ & $6$ \\ \end{tabular} - sage: latex(table(a, frame=True, align='center')) + sage: latex(table(a, frame=True, align='center')) # optional - sage.matrix \begin{tabular}{|c|c|c|} \hline $\sin(x)$ & $x$ & text \\ \hline $1$ & $34342$ & $3$ \\ \hline @@ -640,10 +647,11 @@ def _html_(self): EXAMPLES:: - sage: T = table([[r'$\sin(x)$', '$x$', 'text'], [1,34342,3], [identity_matrix(2),5,6]]) - sage: T._html_() + sage: T = table([[r'$\sin(x)$', '$x$', 'text'], # optional - sage.matrix + ....: [1, 34342, 3], [identity_matrix(2), 5, 6]]) + sage: T._html_() # optional - sage.matrix '' - sage: print(T._html_()) + sage: print(T._html_()) # optional - sage.matrix
@@ -672,8 +680,10 @@ def _html_(self): Note that calling ``html(table(...))`` has the same effect as calling ``table(...)._html_()``:: - sage: T = table([["$x$", r"$\sin(x)$"]] + [(x,n(sin(x), digits=2)) for x in [0..3]], header_row=True, frame=True) - sage: T + sage: T = table([["$x$", r"$\sin(x)$"]] # optional - sage.symbolic + ....: + [(x,n(sin(x), digits=2)) for x in [0..3]], + ....: header_row=True, frame=True) + sage: T # optional - sage.symbolic +-----+-----------+ | $x$ | $\sin(x)$ | +=====+===========+ @@ -685,7 +695,7 @@ def _html_(self): +-----+-----------+ | 3 | 0.14 | +-----+-----------+ - sage: print(html(T)) + sage: print(html(T)) # optional - sage.symbolic
diff --git a/src/sage/misc/trace.py b/src/sage/misc/trace.py index 2547426bc0a..c8bee6af80f 100644 --- a/src/sage/misc/trace.py +++ b/src/sage/misc/trace.py @@ -53,17 +53,17 @@ def trace(code, preparse=True): The only real way to test this is via pexpect spawning a sage subprocess that uses IPython:: - sage: import pexpect - sage: s = pexpect.spawn('sage') - sage: _ = s.sendline("trace('print(factor(10))'); print(3+97)") - sage: _ = s.expect('ipdb>', timeout=90) - sage: _ = s.sendline("s"); _ = s.sendline("c") - sage: _ = s.expect('100', timeout=90) + sage: import pexpect # optional - pexpect + sage: s = pexpect.spawn('sage') # optional - pexpect + sage: _ = s.sendline("trace('print(factor(10))'); print(3+97)") # optional - pexpect + sage: _ = s.expect('ipdb>', timeout=90) # optional - pexpect + sage: _ = s.sendline("s"); _ = s.sendline("c") # optional - pexpect + sage: _ = s.expect('100', timeout=90) # optional - pexpect Seeing the ipdb prompt and the 2 \* 5 in the output below is a strong indication that the trace command worked correctly:: - sage: print(s.before[s.before.find(b'--'):].decode()) + sage: print(s.before[s.before.find(b'--'):].decode()) # optional - pexpect --... ...ipdb> c ...2 * 5... diff --git a/src/sage/misc/weak_dict.pyx b/src/sage/misc/weak_dict.pyx index 9202e96c99e..72e13c19b98 100644 --- a/src/sage/misc/weak_dict.pyx +++ b/src/sage/misc/weak_dict.pyx @@ -339,13 +339,13 @@ cdef class WeakValueDictionary(dict): EXAMPLES:: - sage: L = [(p,GF(p)) for p in prime_range(10)] + sage: L = [(p, GF(p)) for p in prime_range(10)] # optional - sage.rings.finite_rings sage: import sage.misc.weak_dict sage: D = sage.misc.weak_dict.WeakValueDictionary() sage: len(D) 0 - sage: D = sage.misc.weak_dict.WeakValueDictionary(L) - sage: len(D) == len(L) + sage: D = sage.misc.weak_dict.WeakValueDictionary(L) # optional - sage.rings.finite_rings + sage: len(D) == len(L) # optional - sage.rings.finite_rings True """ try: @@ -429,29 +429,29 @@ cdef class WeakValueDictionary(dict): EXAMPLES:: sage: import sage.misc.weak_dict - sage: L = [(p,GF(p)) for p in prime_range(10)] - sage: D = sage.misc.weak_dict.WeakValueDictionary(L) - sage: len(D) + sage: L = [(p, GF(p)) for p in prime_range(10)] # optional - sage.rings.finite_rings + sage: D = sage.misc.weak_dict.WeakValueDictionary(L) # optional - sage.rings.finite_rings + sage: len(D) # optional - sage.rings.finite_rings 4 The value for an existing key is returned and not overridden:: - sage: D.setdefault(5, ZZ) + sage: D.setdefault(5, ZZ) # optional - sage.rings.finite_rings Finite Field of size 5 - sage: D[5] + sage: D[5] # optional - sage.rings.finite_rings Finite Field of size 5 For a non-existing key, the default value is stored and returned:: - sage: 4 in D + sage: 4 in D # optional - sage.rings.finite_rings False - sage: D.setdefault(4, ZZ) + sage: D.setdefault(4, ZZ) # optional - sage.rings.finite_rings Integer Ring - sage: 4 in D + sage: 4 in D # optional - sage.rings.finite_rings True - sage: D[4] + sage: D[4] # optional - sage.rings.finite_rings Integer Ring - sage: len(D) + sage: len(D) # optional - sage.rings.finite_rings 5 TESTS: @@ -460,7 +460,7 @@ cdef class WeakValueDictionary(dict): raised for unhashable objects:: sage: D = sage.misc.weak_dict.WeakValueDictionary() - sage: D.setdefault(matrix([]),ZZ) + sage: D.setdefault(matrix([]), ZZ) # optional - sage.modules Traceback (most recent call last): ... TypeError: mutable matrices are unhashable @@ -535,7 +535,7 @@ cdef class WeakValueDictionary(dict): raised for unhashable objects:: sage: D = sage.misc.weak_dict.WeakValueDictionary() - sage: D[matrix([])] = ZZ + sage: D[matrix([])] = ZZ # optional - sage.modules Traceback (most recent call last): ... TypeError: mutable matrices are unhashable @@ -560,15 +560,15 @@ cdef class WeakValueDictionary(dict): EXAMPLES:: sage: import sage.misc.weak_dict - sage: L = [GF(p) for p in prime_range(10^3)] - sage: D = sage.misc.weak_dict.WeakValueDictionary(enumerate(L)) - sage: 20 in D + sage: L = [GF(p) for p in prime_range(10^3)] # optional - sage.rings.finite_rings + sage: D = sage.misc.weak_dict.WeakValueDictionary(enumerate(L)) # optional - sage.rings.finite_rings + sage: 20 in D # optional - sage.rings.finite_rings True - sage: D.pop(20) + sage: D.pop(20) # optional - sage.rings.finite_rings Finite Field of size 73 - sage: 20 in D + sage: 20 in D # optional - sage.rings.finite_rings False - sage: D.pop(20) + sage: D.pop(20) # optional - sage.rings.finite_rings Traceback (most recent call last): ... KeyError: 20 @@ -579,7 +579,7 @@ cdef class WeakValueDictionary(dict): raised for unhashable objects:: sage: D = sage.misc.weak_dict.WeakValueDictionary() - sage: D.pop(matrix([])) + sage: D.pop(matrix([])) # optional - sage.modules Traceback (most recent call last): ... TypeError: mutable matrices are unhashable @@ -636,17 +636,17 @@ cdef class WeakValueDictionary(dict): EXAMPLES:: sage: import sage.misc.weak_dict - sage: L = [GF(p) for p in prime_range(10^3)] - sage: D = sage.misc.weak_dict.WeakValueDictionary(enumerate(L)) - sage: 100 in D + sage: L = [GF(p) for p in prime_range(10^3)] # optional - sage.rings.finite_rings + sage: D = sage.misc.weak_dict.WeakValueDictionary(enumerate(L)) # optional - sage.rings.finite_rings + sage: 100 in D # optional - sage.rings.finite_rings True - sage: 200 in D + sage: 200 in D # optional - sage.rings.finite_rings False - sage: D.get(100, "not found") + sage: D.get(100, "not found") # optional - sage.rings.finite_rings Finite Field of size 547 - sage: D.get(200, "not found") + sage: D.get(200, "not found") # optional - sage.rings.finite_rings 'not found' - sage: D.get(200) is None + sage: D.get(200) is None # optional - sage.rings.finite_rings True TESTS: @@ -655,7 +655,7 @@ cdef class WeakValueDictionary(dict): raised for unhashable objects:: sage: D = sage.misc.weak_dict.WeakValueDictionary() - sage: D.get(matrix([])) + sage: D.get(matrix([])) # optional - sage.modules Traceback (most recent call last): ... TypeError: mutable matrices are unhashable @@ -695,7 +695,7 @@ cdef class WeakValueDictionary(dict): raised for unhashable objects:: sage: D = sage.misc.weak_dict.WeakValueDictionary() - sage: D[matrix([])] + sage: D[matrix([])] # optional - sage.modules Traceback (most recent call last): ... TypeError: mutable matrices are unhashable @@ -739,7 +739,7 @@ cdef class WeakValueDictionary(dict): raised for unhashable objects:: sage: D = sage.misc.weak_dict.WeakValueDictionary() - sage: matrix([]) in D + sage: matrix([]) in D # optional - sage.modules Traceback (most recent call last): ... TypeError: mutable matrices are unhashable @@ -1193,13 +1193,13 @@ cdef class CachedWeakValueDictionary(WeakValueDictionary): EXAMPLES:: - sage: L = [(p,GF(p)) for p in prime_range(10)] + sage: L = [(p, GF(p)) for p in prime_range(10)] # optional - sage.rings.finite_rings sage: from sage.misc.weak_dict import CachedWeakValueDictionary - sage: D = CachedWeakValueDictionary() - sage: len(D) + sage: D = CachedWeakValueDictionary() # optional - sage.rings.finite_rings + sage: len(D) # optional - sage.rings.finite_rings 0 - sage: D = CachedWeakValueDictionary(L) - sage: len(D) == len(L) + sage: D = CachedWeakValueDictionary(L) # optional - sage.rings.finite_rings + sage: len(D) == len(L) # optional - sage.rings.finite_rings True A :class:`CachedWeakValueDictionary` with a cache size of zero diff --git a/src/sage/modular/dirichlet.py b/src/sage/modular/dirichlet.py index 68b4eaaa4f1..050eb60fa7a 100644 --- a/src/sage/modular/dirichlet.py +++ b/src/sage/modular/dirichlet.py @@ -62,10 +62,9 @@ import sage.rings.abc from sage.arith.functions import lcm -from sage.arith.misc import bernoulli, kronecker, factor, gcd, fundamental_discriminant, euler_phi, valuation +from sage.arith.misc import bernoulli, binomial, factorial, kronecker, factor, gcd, fundamental_discriminant, euler_phi, valuation from sage.categories.map import Map from sage.categories.objects import Objects -from sage.functions.other import binomial, factorial from sage.libs.pari import pari from sage.misc.cachefunc import cached_method from sage.misc.fast_methods import WithEqualityById diff --git a/src/sage/modular/hypergeometric_motive.py b/src/sage/modular/hypergeometric_motive.py index ad34fb3c92b..d2d76831498 100644 --- a/src/sage/modular/hypergeometric_motive.py +++ b/src/sage/modular/hypergeometric_motive.py @@ -64,9 +64,10 @@ from sage.arith.misc import divisors, gcd, euler_phi, moebius, is_prime from sage.arith.misc import gauss_sum, kronecker_symbol from sage.combinat.integer_vector_weighted import WeightedIntegerVectors -from sage.functions.generalized import sgn -from sage.functions.log import log -from sage.functions.other import floor, ceil +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.generalized", "sgn") +lazy_import("sage.functions.log", "log") +lazy_import("sage.functions.other", ["floor", "ceil"]) from sage.misc.cachefunc import cached_method from sage.misc.functional import cyclotomic_polynomial from sage.misc.misc_c import prod diff --git a/src/sage/modular/modform_hecketriangle/graded_ring_element.py b/src/sage/modular/modform_hecketriangle/graded_ring_element.py index 837091a6982..f09715dca3b 100644 --- a/src/sage/modular/modform_hecketriangle/graded_ring_element.py +++ b/src/sage/modular/modform_hecketriangle/graded_ring_element.py @@ -16,10 +16,10 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.functions.log import exp from sage.geometry.hyperbolic_space.hyperbolic_interface import HyperbolicPlane from sage.misc.cachefunc import cached_method from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass +from sage.misc.lazy_import import lazy_import from sage.modules.free_module_element import vector from sage.rings.big_oh import O from sage.rings.infinity import infinity @@ -30,7 +30,9 @@ from sage.structure.parent_gens import localvars from sage.structure.richcmp import op_NE, op_EQ from sage.structure.unique_representation import UniqueRepresentation -from sage.symbolic.constants import pi + +lazy_import("sage.functions.log", "exp") +lazy_import("sage.symbolic.constants", "pi") from .constructor import rational_type, FormsSpace, FormsRing from .series_constructor import MFSeriesConstructor diff --git a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py index d84bb365745..7fd468192c2 100644 --- a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py +++ b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py @@ -17,13 +17,11 @@ # **************************************************************************** from sage.arith.misc import divisors -from sage.functions.gamma import psi1 -from sage.functions.log import exp -from sage.functions.trig import cos, sec from sage.groups.matrix_gps.finitely_generated import FinitelyGeneratedMatrixGroup_generic from sage.matrix.constructor import matrix from sage.misc.cachefunc import cached_method from sage.misc.latex import latex +from sage.misc.lazy_import import lazy_import from sage.misc.misc_c import prod from sage.rings.imaginary_unit import I from sage.rings.infinity import infinity @@ -33,10 +31,15 @@ from sage.rings.qqbar import AA, AlgebraicField from sage.rings.rational_field import QQ from sage.structure.unique_representation import UniqueRepresentation -from sage.symbolic.constants import pi + +lazy_import("sage.functions.log", "exp") +lazy_import("sage.functions.gamma", "psi1") +lazy_import("sage.functions.trig", ["cos", "sec"]) +lazy_import("sage.symbolic.constants", "pi") from .hecke_triangle_group_element import HeckeTriangleGroupElement, cyclic_representative, coerce_AA + class HeckeTriangleGroup(FinitelyGeneratedMatrixGroup_generic, UniqueRepresentation): r""" diff --git a/src/sage/modular/overconvergent/hecke_series.py b/src/sage/modular/overconvergent/hecke_series.py index 2da21b57b77..7bcc088b17c 100644 --- a/src/sage/modular/overconvergent/hecke_series.py +++ b/src/sage/modular/overconvergent/hecke_series.py @@ -70,10 +70,10 @@ # **************************************************************************** from sage.arith.misc import valuation -from sage.functions.other import floor, ceil from sage.matrix.constructor import matrix, random_matrix from sage.matrix.matrix_space import MatrixSpace from sage.misc.functional import dimension, transpose, charpoly +from sage.misc.lazy_import import lazy_import from sage.misc.misc import cputime from sage.misc.verbose import verbose from sage.modular.dims import dimension_modular_forms @@ -84,6 +84,9 @@ from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ +lazy_import("sage.functions.other", ["floor", "ceil"]) + + # AUXILIARY CODE: SPACES OF MODULAR FORMS AND LINEAR ALGEBRA def compute_G(p, F): diff --git a/src/sage/modules/filtered_vector_space.py b/src/sage/modules/filtered_vector_space.py index a4a32815197..d8e2eaecd95 100644 --- a/src/sage/modules/filtered_vector_space.py +++ b/src/sage/modules/filtered_vector_space.py @@ -83,17 +83,17 @@ Any field can be used as the vector space base. For example a finite field:: - sage: F. = GF(5^3) - sage: r1 = (a, 0, F(5)); r1 + sage: F. = GF(5^3) # optional - sage.rings.finite_rings + sage: r1 = (a, 0, F(5)); r1 # optional - sage.rings.finite_rings (a, 0, 0) - sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1], oo:[1]}, base_ring=F) + sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1], oo:[1]}, base_ring=F) # optional - sage.rings.finite_rings GF(125)^2 >= GF(125)^1 in GF(125)^3 Or the algebraic field:: - sage: r1 = (1, 0, 1+QQbar(I)); r1 + sage: r1 = (1, 0, 1+QQbar(I)); r1 # optional - sage.rings.number_field (1, 0, I + 1) - sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1], oo:[1]}, base_ring=QQbar) + sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1], oo:[1]}, base_ring=QQbar) # optional - sage.rings.number_field Vector space of dimension 2 over Algebraic Field >= Vector space of dimension 1 over Algebraic Field in Vector space of dimension 3 over Algebraic Field @@ -784,11 +784,11 @@ def _repr_field_name(self): sage: FilteredVectorSpace(2, base_ring=QQ)._repr_field_name() 'QQ' - sage: F. = GF(9) - sage: FilteredVectorSpace(2, base_ring=F)._repr_field_name() + sage: F. = GF(9) # optional - sage.rings.finite_rings + sage: FilteredVectorSpace(2, base_ring=F)._repr_field_name() # optional - sage.rings.finite_rings 'GF(9)' - sage: FilteredVectorSpace(2, base_ring=AA)._repr_field_name() + sage: FilteredVectorSpace(2, base_ring=AA)._repr_field_name() # optional - sage.rings.number_field Traceback (most recent call last): ... NotImplementedError @@ -822,11 +822,11 @@ def _repr_vector_space(self, dim): sage: F = FilteredVectorSpace(3, base_ring=RDF) sage: F._repr_vector_space(1234) 'RDF^1234' - sage: F3 = FilteredVectorSpace(3, base_ring=GF(3)) - sage: F3._repr_vector_space(1234) + sage: F3 = FilteredVectorSpace(3, base_ring=GF(3)) # optional - sage.rings.finite_rings + sage: F3._repr_vector_space(1234) # optional - sage.rings.finite_rings 'GF(3)^1234' - sage: F3 = FilteredVectorSpace(3, base_ring=AA) - sage: F3._repr_vector_space(1234) + sage: F3 = FilteredVectorSpace(3, base_ring=AA) # optional - sage.rings.number_field + sage: F3._repr_vector_space(1234) # optional - sage.rings.number_field 'Vector space of dimension 1234 over Algebraic Real Field' """ if dim == 0: @@ -880,9 +880,9 @@ def _repr_(self): QQ^1 in QQ^2 sage: FilteredVectorSpace(rays, {0:[3]}) QQ^1 >= 0 in QQ^2 - sage: FilteredVectorSpace({1:[(1,0), (-1,1)], 3:[(1,0)]}, base_ring=GF(3)) + sage: FilteredVectorSpace({1:[(1,0), (-1,1)], 3:[(1,0)]}, base_ring=GF(3)) # optional - sage.rings.finite_rings GF(3)^2 >= GF(3)^1 >= GF(3)^1 >= 0 - sage: FilteredVectorSpace({1:[(1,0), (-1,1)], 3:[(1,0)]}, base_ring=AA) + sage: FilteredVectorSpace({1:[(1,0), (-1,1)], 3:[(1,0)]}, base_ring=AA) # optional - sage.rings.number_field Vector space of dimension 2 over Algebraic Real Field >= Vector space of dimension 1 over Algebraic Real Field >= Vector space of dimension 1 over Algebraic Real Field >= 0 @@ -926,7 +926,7 @@ def __eq__(self, other): sage: S1._filt[0].is_isomorphic(S2._filt[0]) # known bug True - sage: FilteredVectorSpace(2, base_ring=QQ) == FilteredVectorSpace(2, base_ring=GF(5)) + sage: FilteredVectorSpace(2, base_ring=QQ) == FilteredVectorSpace(2, base_ring=GF(5)) # optional - sage.rings.finite_rings False """ if type(self) != type(other): @@ -1107,7 +1107,7 @@ def _power_operation(self, n, operation): QQ^2 >= QQ^1 >= 0 sage: F._power_operation(2, 'symmetric') QQ^3 >= QQ^2 >= QQ^1 >= 0 - sage: F._power_operation(2, 'antisymmetric') + sage: F._power_operation(2, 'antisymmetric') # optional - sage.groups QQ^1 >= 0 """ from sage.modules.tensor_operations import VectorCollection, TensorOperation @@ -1147,13 +1147,13 @@ def exterior_power(self, n): sage: F = FilteredVectorSpace(1, 1) + FilteredVectorSpace(1, 2); F QQ^2 >= QQ^1 >= 0 - sage: F.exterior_power(1) + sage: F.exterior_power(1) # optional - sage.groups QQ^2 >= QQ^1 >= 0 - sage: F.exterior_power(2) + sage: F.exterior_power(2) # optional - sage.groups QQ^1 >= 0 - sage: F.exterior_power(3) + sage: F.exterior_power(3) # optional - sage.groups 0 - sage: F.wedge(2) + sage: F.wedge(2) # optional - sage.groups QQ^1 >= 0 """ return self._power_operation(n, 'antisymmetric') diff --git a/src/sage/modules/finite_submodule_iter.pyx b/src/sage/modules/finite_submodule_iter.pyx index eb433546f23..54a27eab437 100644 --- a/src/sage/modules/finite_submodule_iter.pyx +++ b/src/sage/modules/finite_submodule_iter.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings r""" Iterators over finite submodules of a `\ZZ`-module diff --git a/src/sage/modules/fp_graded/element.py b/src/sage/modules/fp_graded/element.py index e4f288f3264..a4055b3e3b5 100755 --- a/src/sage/modules/fp_graded/element.py +++ b/src/sage/modules/fp_graded/element.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat r""" Elements of finitely presented graded modules diff --git a/src/sage/modules/fp_graded/free_module.py b/src/sage/modules/fp_graded/free_module.py index 3f87d6b9c6f..cb1caa3581c 100755 --- a/src/sage/modules/fp_graded/free_module.py +++ b/src/sage/modules/fp_graded/free_module.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat r""" Finitely generated free graded left modules over connected graded algebras diff --git a/src/sage/modules/fp_graded/homspace.py b/src/sage/modules/fp_graded/homspace.py index 08e30a17dba..985cb1d727b 100755 --- a/src/sage/modules/fp_graded/homspace.py +++ b/src/sage/modules/fp_graded/homspace.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat r""" Homsets of finitely presented graded modules diff --git a/src/sage/modules/fp_graded/module.py b/src/sage/modules/fp_graded/module.py index 79353e754a9..34787b8d217 100755 --- a/src/sage/modules/fp_graded/module.py +++ b/src/sage/modules/fp_graded/module.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat r""" Finitely presented graded modules diff --git a/src/sage/modules/fp_graded/morphism.py b/src/sage/modules/fp_graded/morphism.py index fde00303230..75eacd961e7 100755 --- a/src/sage/modules/fp_graded/morphism.py +++ b/src/sage/modules/fp_graded/morphism.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat r""" Homomorphisms of finitely presented graded modules diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index b7618475111..c96a7149922 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -18,17 +18,17 @@ EXAMPLES:: - sage: V = VectorSpace(QQ,3) + sage: V = VectorSpace(QQ, 3) sage: W = V.subspace([[1,2,7], [1,1,0]]) sage: W Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [ 1 0 -7] [ 0 1 7] - sage: C = VectorSpaces(FiniteField(7)) - sage: C + sage: C = VectorSpaces(FiniteField(7)) # optional - sage.rings.finite_rings + sage: C # optional - sage.rings.finite_rings Category of vector spaces over Finite Field of size 7 - sage: C(W) + sage: C(W) # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 2 over Finite Field of size 7 Basis matrix: [1 0 0] @@ -37,11 +37,11 @@ :: sage: M = ZZ^3 - sage: C = VectorSpaces(FiniteField(7)) - sage: C(M) + sage: C = VectorSpaces(FiniteField(7)) # optional - sage.rings.finite_rings + sage: C(M) # optional - sage.rings.finite_rings Vector space of dimension 3 over Finite Field of size 7 - sage: W = M.submodule([[1,2,7], [8,8,0]]) - sage: C(W) + sage: W = M.submodule([[1,2,7], [8,8,0]]) # optional - sage.rings.finite_rings + sage: C(W) # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 2 over Finite Field of size 7 Basis matrix: [1 0 0] @@ -75,10 +75,10 @@ sage: print([v for _,v in zip(range(31), ZZ^3)]) [(0, 0, 0), - (1, 0, 0), (-1, 0, 0), (0, 1, 0), (0, -1, 0), (0, 0, 1), (0, 0, -1), - (1, 1, 0), (-1, 1, 0), (1, -1, 0), (-1, -1, 0), (1, 0, 1), (-1, 0, 1), (1, 0, -1), (-1, 0, -1), (0, 1, 1), (0, -1, 1), (0, 1, -1), (0, -1, -1), - (2, 0, 0), (-2, 0, 0), (0, 2, 0), (0, -2, 0), (0, 0, 2), (0, 0, -2), - (1, 1, 1), (-1, 1, 1), (1, -1, 1), (-1, -1, 1), (1, 1, -1), ...] + (1, 0, 0), (-1, 0, 0), (0, 1, 0), (0, -1, 0), (0, 0, 1), (0, 0, -1), + (1, 1, 0), (-1, 1, 0), (1, -1, 0), (-1, -1, 0), (1, 0, 1), (-1, 0, 1), (1, 0, -1), (-1, 0, -1), (0, 1, 1), (0, -1, 1), (0, 1, -1), (0, -1, -1), + (2, 0, 0), (-2, 0, 0), (0, 2, 0), (0, -2, 0), (0, 0, 2), (0, 0, -2), + (1, 1, 1), (-1, 1, 1), (1, -1, 1), (-1, -1, 1), (1, 1, -1), ...] For other infinite enumerated base rings (i.e., rings which are objects of the category :class:`InfiniteEnumeratedSets`), @@ -243,11 +243,11 @@ def create_object(self, version, key): sage: R. = QQ[] sage: Q = R.quo(R.ideal([x^2 - y^2 - 1])) - sage: Q.is_integral_domain() + sage: Q.is_integral_domain() # optional - sage.libs.singular True - sage: Q2 = FreeModule(Q, 2) - sage: from sage.modules.free_module import FreeModule_ambient_domain - sage: isinstance(Q2, FreeModule_ambient_domain) + sage: Q2 = FreeModule(Q, 2) # optional - sage.libs.singular + sage: from sage.modules.free_module import FreeModule_ambient_domain # optional - sage.libs.singular + sage: isinstance(Q2, FreeModule_ambient_domain) # optional - sage.libs.singular True """ base_ring, rank, sparse, inner_product_matrix = key @@ -385,14 +385,16 @@ def FreeModule(base_ring, rank_or_basis_keys=None, sparse=False, inner_product_m Vector space of dimension 10 over Rational Field sage: FreeModule(ZZ,10) Ambient free module of rank 10 over the principal ideal domain Integer Ring - sage: FreeModule(FiniteField(5),10) + sage: FreeModule(FiniteField(5), 10) # optional - sage.rings.finite_rings Vector space of dimension 10 over Finite Field of size 5 - sage: FreeModule(Integers(7),10) + sage: FreeModule(Integers(7), 10) Vector space of dimension 10 over Ring of integers modulo 7 - sage: FreeModule(PolynomialRing(QQ,'x'),5) - Ambient free module of rank 5 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - sage: FreeModule(PolynomialRing(ZZ,'x'),5) - Ambient free module of rank 5 over the integral domain Univariate Polynomial Ring in x over Integer Ring + sage: FreeModule(PolynomialRing(QQ,'x'), 5) + Ambient free module of rank 5 over the principal ideal domain + Univariate Polynomial Ring in x over Rational Field + sage: FreeModule(PolynomialRing(ZZ,'x'), 5) + Ambient free module of rank 5 over the integral domain + Univariate Polynomial Ring in x over Integer Ring Of course we can make rank 0 free modules:: @@ -438,8 +440,8 @@ def FreeModule(base_ring, rank_or_basis_keys=None, sparse=False, inner_product_m :: - sage: A = MatrixSpace(ZZ,2)([[1,0],[0,-1]]) - sage: M = FreeModule(ZZ,2,inner_product_matrix=A) + sage: A = MatrixSpace(ZZ, 2)([[1,0], [0,-1]]) + sage: M = FreeModule(ZZ, 2, inner_product_matrix=A) sage: v, w = M.gens() sage: v.inner_product(w) 0 @@ -456,13 +458,13 @@ def FreeModule(base_ring, rank_or_basis_keys=None, sparse=False, inner_product_m :: - sage: FreeModule(ZZ,2,inner_product_matrix=1).inner_product_matrix() + sage: FreeModule(ZZ, 2, inner_product_matrix=1).inner_product_matrix() [1 0] [0 1] - sage: FreeModule(ZZ,2,inner_product_matrix=[1,2,3,4]).inner_product_matrix() + sage: FreeModule(ZZ, 2, inner_product_matrix=[1,2,3,4]).inner_product_matrix() [1 2] [3 4] - sage: FreeModule(ZZ,2,inner_product_matrix=[[1,2],[3,4]]).inner_product_matrix() + sage: FreeModule(ZZ, 2, inner_product_matrix=[[1,2], [3,4]]).inner_product_matrix() [1 2] [3 4] @@ -613,12 +615,13 @@ def span(gens, base_ring=None, check=True, already_echelonized=False): [ 1 0 -3] [ 0 1 4] - sage: span([V.gen(0)], QuadraticField(-7,'a')) - Vector space of degree 3 and dimension 1 over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I + sage: span([V.gen(0)], QuadraticField(-7,'a')) # optional - sage.rings.number_field + Vector space of degree 3 and dimension 1 over Number Field in a + with defining polynomial x^2 + 7 with a = 2.645751311064591?*I Basis matrix: [ 1 0 -3] - sage: span([[1,2,3], [2,2,2], [1,2,5]], GF(2)) + sage: span([[1,2,3], [2,2,2], [1,2,5]], GF(2)) # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 1 over Finite Field of size 2 Basis matrix: [1 0 1] @@ -1013,8 +1016,8 @@ def some_elements(self): ... (46/103823, -46/103823, 103823/46)) - sage: F = FreeModule(SR, 2) - sage: tuple(F.some_elements()) + sage: F = FreeModule(SR, 2) # optional - sage.symbolic + sage: tuple(F.some_elements()) # optional - sage.symbolic ((1, 0), (some_variable, some_variable)) """ yield self.an_element() @@ -1108,15 +1111,15 @@ def relations_matrix(self): EXAMPLES:: - sage: V = GF(2)^2 - sage: V.relations_matrix() + sage: V = GF(2)^2 # optional - sage.rings.finite_rings + sage: V.relations_matrix() # optional - sage.rings.finite_rings [] - sage: W = V.subspace([[1, 0]]) - sage: W.relations_matrix() + sage: W = V.subspace([[1, 0]]) # optional - sage.rings.finite_rings + sage: W.relations_matrix() # optional - sage.rings.finite_rings [] - sage: Q = V / W - sage: Q.relations_matrix() + sage: Q = V / W # optional - sage.rings.finite_rings + sage: Q.relations_matrix() # optional - sage.rings.finite_rings [1 0] sage: S. = PolynomialRing(QQ) @@ -1187,22 +1190,22 @@ def __richcmp__(self, other, op): More exotic comparisons:: - sage: R1 = ZZ[sqrt(2)] - sage: F1 = R1^3 - sage: V1 = F1.span([[sqrt(2),sqrt(2),0]]) + sage: R1 = ZZ[sqrt(2)] # optional - sage.symbolic + sage: F1 = R1^3 # optional - sage.symbolic + sage: V1 = F1.span([[sqrt(2), sqrt(2), 0]]) # optional - sage.symbolic sage: F2 = ZZ^3 sage: V2 = F2.span([[2,2,0]]) - sage: V2 <= V1 # Different ambient vector spaces + sage: V2 <= V1 # Different ambient vector spaces # optional - sage.symbolic False - sage: V1 <= V2 + sage: V1 <= V2 # optional - sage.symbolic False - sage: R2 = GF(5)[x] - sage: F3 = R2^3 - sage: V3 = F3.span([[x^5-1,1+x+x^2+x^3+x^4,0]]) - sage: W3 = F3.span([[1,1,0],[0,4,0]]) - sage: V3 <= W3 + sage: R2 = GF(5)[x] # optional - sage.rings.finite_rings + sage: F3 = R2^3 # optional - sage.rings.finite_rings + sage: V3 = F3.span([[x^5 - 1, 1 + x + x^2 + x^3 + x^4, 0]]) # optional - sage.rings.finite_rings + sage: W3 = F3.span([[1,1,0], [0,4,0]]) # optional - sage.rings.finite_rings + sage: V3 <= W3 # optional - sage.rings.finite_rings True - sage: W3 <= V3 + sage: W3 <= V3 # optional - sage.rings.finite_rings False We compare a one dimensional space to a two dimensional space:: @@ -1216,7 +1219,7 @@ def __richcmp__(self, other, op): We test that :trac:`5525` is fixed:: - sage: A = (QQ^1).span([[1/3]],ZZ); B = (QQ^1).span([[1]],ZZ) + sage: A = (QQ^1).span([[1/3]], ZZ); B = (QQ^1).span([[1]], ZZ) sage: A.intersection(B) Free module of degree 1 and rank 1 over Integer Ring Echelon basis matrix: @@ -1265,8 +1268,8 @@ def __richcmp__(self, other, op): sage: P. = QQ[] sage: M = P**2 - sage: S1 = M.submodule([(x,y),(y,x)]) - sage: S2 = M.submodule([(x,y),(y-x,x-y)]) + sage: S1 = M.submodule([(x, y), (y, x)]) + sage: S2 = M.submodule([(x, y), (y - x, x - y)]) sage: S1 == S2 False sage: S1 != S2 @@ -1567,12 +1570,12 @@ def span(self, gens, base_ring=None, check=True, already_echelonized=False): EXAMPLES:: - sage: V = VectorSpace(GF(7), 3) - sage: W = V.subspace([[2,3,4]]); W + sage: V = VectorSpace(GF(7), 3) # optional - sage.rings.finite_rings + sage: W = V.subspace([[2, 3, 4]]); W # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] - sage: W.span([[1,1,1]]) + sage: W.span([[1, 1, 1]]) # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 1 1] @@ -1582,14 +1585,15 @@ def span(self, gens, base_ring=None, check=True, already_echelonized=False): sage: S. = PolynomialRing(QQ) sage: M = S**2 sage: M.span([vector([x - y, z]), vector([y*z, x*z])]) - Submodule of Ambient free module of rank 2 over the integral domain Multivariate Polynomial Ring in x, y, z over Rational Field + Submodule of Ambient free module of rank 2 over the integral domain + Multivariate Polynomial Ring in x, y, z over Rational Field Generated by the rows of the matrix: [x - y z] [ y*z x*z] Over a PID:: - sage: V = FreeModule(ZZ,3) + sage: V = FreeModule(ZZ, 3) sage: W = V.submodule([V.gen(0)]) sage: W.span([V.gen(1)]) Free module of degree 3 and rank 1 over Integer Ring @@ -1599,7 +1603,7 @@ def span(self, gens, base_ring=None, check=True, already_echelonized=False): Traceback (most recent call last): ... ArithmeticError: argument gens (= [(0, 1, 0)]) does not generate a submodule of self - sage: V.span([[1,0,0],[1/5,4,0],[6,3/4,0]]) + sage: V.span([[1,0,0], [1/5,4,0], [6,3/4,0]]) Free module of degree 3 and rank 2 over Integer Ring Echelon basis matrix: [1/5 0 0] @@ -1607,19 +1611,21 @@ def span(self, gens, base_ring=None, check=True, already_echelonized=False): It also works with other things than integers:: - sage: R.=QQ[] - sage: L=R^1 - sage: a=L.span([(1/x,)]) + sage: R. = QQ[] + sage: L = R^1 + sage: a = L.span([(1/x,)]) sage: a - Free module of degree 1 and rank 1 over Univariate Polynomial Ring in x over Rational Field + Free module of degree 1 and rank 1 + over Univariate Polynomial Ring in x over Rational Field Echelon basis matrix: [1/x] sage: b=L.span([(1/x,)]) sage: a(b.gens()[0]) (1/x) sage: L2 = R^2 - sage: L2.span([[(x^2+x)/(x^2-3*x+2),1/5],[(x^2+2*x)/(x^2-4*x+3),x]]) - Free module of degree 2 and rank 2 over Univariate Polynomial Ring in x over Rational Field + sage: L2.span([[(x^2+x)/(x^2-3*x+2), 1/5], [(x^2+2*x)/(x^2-4*x+3), x]]) + Free module of degree 2 and rank 2 + over Univariate Polynomial Ring in x over Rational Field Echelon basis matrix: [x/(x^3 - 6*x^2 + 11*x - 6) 2/15*x^2 - 17/75*x - 1/75] [ 0 x^3 - 11/5*x^2 - 3*x + 4/5] @@ -1628,28 +1634,30 @@ def span(self, gens, base_ring=None, check=True, already_echelonized=False): repeat the previous example over the fraction field of R and get a simpler vector space. :: - sage: L2.span([[(x^2+x)/(x^2-3*x+2),1/5],[(x^2+2*x)/(x^2-4*x+3),x]],base_ring=R.fraction_field()) - Vector space of degree 2 and dimension 2 over Fraction Field of Univariate Polynomial Ring in x over Rational Field + sage: L2.span([[(x^2+x)/(x^2-3*x+2), 1/5], [(x^2+2*x)/(x^2-4*x+3), x]], + ....: base_ring=R.fraction_field()) + Vector space of degree 2 and dimension 2 over + Fraction Field of Univariate Polynomial Ring in x over Rational Field Basis matrix: [1 0] [0 1] TESTS:: - sage: V = FreeModule(RDF,3) + sage: V = FreeModule(RDF, 3) sage: W = V.submodule([V.gen(0)]) - sage: W.span([V.gen(1)], base_ring=GF(7)) + sage: W.span([V.gen(1)], base_ring=GF(7)) # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [0 1 0] sage: v = V((1, pi, log(2))); v (1.0, 3.141592653589793, 0.6931471805599453) - sage: W.span([v], base_ring=GF(7)) + sage: W.span([v], base_ring=GF(7)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: argument gens (= [(1.0, 3.141592653589793, 0.6931471805599453)]) is not compatible with base_ring (= Finite Field of size 7) sage: W = V.submodule([v]) - sage: W.span([V.gen(2)], base_ring=GF(7)) + sage: W.span([V.gen(2)], base_ring=GF(7)) # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [0 0 1] @@ -1694,7 +1702,7 @@ def submodule(self, gens, check=True, already_echelonized=False): sage: M = FreeModule(ZZ, 3) sage: B = M.basis() - sage: W = M.submodule([B[0]+B[1], 2*B[1]-B[2]]) + sage: W = M.submodule([B[0] + B[1], 2*B[1] - B[2]]) sage: W Free module of degree 3 and rank 2 over Integer Ring Echelon basis matrix: @@ -1722,20 +1730,23 @@ def submodule(self, gens, check=True, already_echelonized=False): sage: R = PolynomialRing(QQ, 'x'); x = R.gen() sage: M = FreeModule(R, 3) sage: B = M.basis() - sage: W = M.submodule([x*B[0], 2*B[1]- x*B[2]]); W - Free module of degree 3 and rank 2 over Univariate Polynomial Ring in x over Rational Field + sage: W = M.submodule([x*B[0], 2*B[1] - x*B[2]]); W + Free module of degree 3 and rank 2 + over Univariate Polynomial Ring in x over Rational Field Echelon basis matrix: [ x 0 0] [ 0 2 -x] sage: W.ambient_module() - Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field + Ambient free module of rank 3 over the principal ideal domain + Univariate Polynomial Ring in x over Rational Field Over a generic ring:: sage: S. = PolynomialRing(QQ) sage: A = S**2 sage: A.submodule([vector([x - y,z]), vector([y*z, x*z])]) - Submodule of Ambient free module of rank 2 over the integral domain Multivariate Polynomial Ring in x, y, z over Rational Field + Submodule of Ambient free module of rank 2 over the integral domain + Multivariate Polynomial Ring in x, y, z over Rational Field Generated by the rows of the matrix: [x - y z] [ y*z x*z] @@ -1810,10 +1821,10 @@ def free_resolution(self, *args, **kwds): sage: S. = PolynomialRing(QQ) sage: M = S**2 sage: N = M.submodule([vector([x - y, z]), vector([y * z, x * z])]) - sage: res = N.free_resolution() - sage: res + sage: res = N.free_resolution() # optional - sage.libs.singular + sage: res # optional - sage.libs.singular S^2 <-- S^2 <-- 0 - sage: ascii_art(res.chain_complex()) + sage: ascii_art(res.chain_complex()) # optional - sage.libs.singular [x - y y*z] [ z x*z] 0 <-- C_0 <-------------- C_1 <-- 0 @@ -1842,13 +1853,13 @@ def graded_free_resolution(self, *args, **kwds): sage: S. = PolynomialRing(QQ) sage: M = S**2 sage: N = M.submodule([vector([x - y, z]), vector([y * z, x * z])]) - sage: N.graded_free_resolution(shifts=[1, -1]) + sage: N.graded_free_resolution(shifts=[1, -1]) # optional - sage.libs.singular S(-1)⊕S(1) <-- S(-2)⊕S(-3) <-- 0 - sage: N.graded_free_resolution(shifts=[2, 3]) + sage: N.graded_free_resolution(shifts=[2, 3]) # optional - sage.libs.singular S(-2)⊕S(-3) <-- S(-3)⊕S(-4) <-- 0 sage: N = M.submodule([vector([x^3 - y^6, z^2]), vector([y * z, x])]) - sage: N.graded_free_resolution(degrees=[2, 1, 3], shifts=[2, 3]) + sage: N.graded_free_resolution(degrees=[2, 1, 3], shifts=[2, 3]) # optional - sage.libs.singular S(-2)⊕S(-3) <-- S(-6)⊕S(-8) <-- 0 """ from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular @@ -1893,17 +1904,19 @@ class FreeModule_generic(Module_free_ambient): EXAMPLES:: sage: PolynomialRing(QQ,3,'x')^3 - Ambient free module of rank 3 over the integral domain Multivariate Polynomial Ring in x0, x1, x2 over Rational Field + Ambient free module of rank 3 over the integral domain + Multivariate Polynomial Ring in x0, x1, x2 over Rational Field - sage: FreeModule(GF(7),3).category() + sage: FreeModule(GF(7), 3).category() # optional - sage.rings.finite_rings Category of enumerated finite dimensional vector spaces with basis over (finite enumerated fields and subquotients of monoids and quotients of semigroups) sage: V = QQ^4; V.category() Category of finite dimensional vector spaces with basis over (number fields and quotient fields and metric spaces) - sage: V = GF(5)**20; V.category() - Category of enumerated finite dimensional vector spaces with basis over (finite enumerated fields and subquotients of monoids and quotients of semigroups) - sage: FreeModule(ZZ,3).category() + sage: V = GF(5)**20; V.category() # optional - sage.rings.finite_rings + Category of enumerated finite dimensional vector spaces with basis over + (finite enumerated fields and subquotients of monoids and quotients of semigroups) + sage: FreeModule(ZZ, 3).category() Category of finite dimensional modules with basis over (euclidean domains and infinite enumerated sets and metric spaces) @@ -1928,14 +1941,14 @@ def __init__(self, base_ring, rank, degree, sparse=False, TESTS:: - sage: M = FreeModule(ZZ,20,sparse=False) + sage: M = FreeModule(ZZ, 20, sparse=False) sage: x = M.random_element() sage: type(x) sage: M.element_class - sage: N = FreeModule(ZZ,20,sparse=True) + sage: N = FreeModule(ZZ, 20, sparse=True) sage: y = N.random_element() sage: type(y) @@ -1972,7 +1985,7 @@ def construction(self): EXAMPLES:: - sage: R = PolynomialRing(QQ,3,'x') + sage: R = PolynomialRing(QQ, 3, 'x') sage: V = R^5 sage: V.construction() (VectorFunctor, Multivariate Polynomial Ring in x0, x1, x2 over Rational Field) @@ -1997,8 +2010,8 @@ def dense_module(self): We first illustrate conversion with ambient spaces:: - sage: M = FreeModule(QQ,3) - sage: S = FreeModule(QQ,3, sparse=True) + sage: M = FreeModule(QQ, 3) + sage: S = FreeModule(QQ, 3, sparse=True) sage: M.sparse_module() Sparse vector space of dimension 3 over Rational Field sage: S.dense_module() @@ -2014,7 +2027,7 @@ def dense_module(self): Next we create a subspace:: - sage: M = FreeModule(QQ,3, sparse=True) + sage: M = FreeModule(QQ, 3, sparse=True) sage: V = M.span([ [1,2,3] ] ); V Sparse vector space of degree 3 and dimension 1 over Rational Field Basis matrix: @@ -2037,8 +2050,8 @@ def _dense_module(self): EXAMPLES:: - sage: M = FreeModule(Integers(8),3) - sage: S = FreeModule(Integers(8),3, sparse=True) + sage: M = FreeModule(Integers(8), 3) + sage: S = FreeModule(Integers(8), 3, sparse=True) sage: M is S._dense_module() True """ @@ -2054,8 +2067,8 @@ def sparse_module(self): We first illustrate conversion with ambient spaces:: - sage: M = FreeModule(Integers(8),3) - sage: S = FreeModule(Integers(8),3, sparse=True) + sage: M = FreeModule(Integers(8), 3) + sage: S = FreeModule(Integers(8), 3, sparse=True) sage: M.sparse_module() Ambient sparse free module of rank 3 over Ring of integers modulo 8 sage: S.dense_module() @@ -2094,8 +2107,8 @@ def _sparse_module(self): EXAMPLES:: - sage: M = FreeModule(Integers(8),3) - sage: S = FreeModule(Integers(8),3, sparse=True) + sage: M = FreeModule(Integers(8), 3) + sage: S = FreeModule(Integers(8), 3, sparse=True) sage: M._sparse_module() is S True """ @@ -2234,9 +2247,9 @@ def is_submodule(self, other): EXAMPLES:: - sage: M = FreeModule(ZZ,3) + sage: M = FreeModule(ZZ, 3) sage: V = M.ambient_vector_space() - sage: X = V.span([[1/2,1/2,0],[1/2,0,1/2]], ZZ) + sage: X = V.span([[1/2,1/2,0], [1/2,0,1/2]], ZZ) sage: Y = V.span([[1,1,1]], ZZ) sage: N = X + Y sage: M.is_submodule(X) @@ -2250,7 +2263,7 @@ def is_submodule(self, other): sage: M.is_submodule(N) True - sage: M = FreeModule(ZZ,2) + sage: M = FreeModule(ZZ, 2) sage: M.is_submodule(M) True sage: N = M.scale(2) @@ -2268,9 +2281,9 @@ def is_submodule(self, other): testing does not work for all PID's. However, trivial cases are already used (and useful) for coercion, e.g.:: - sage: QQ(1/2) * vector(ZZ['x']['y'],[1,2,3,4]) + sage: QQ(1/2) * vector(ZZ['x']['y'], [1,2,3,4]) (1/2, 1, 3/2, 2) - sage: vector(ZZ['x']['y'],[1,2,3,4]) * QQ(1/2) + sage: vector(ZZ['x']['y'], [1,2,3,4]) * QQ(1/2) (1/2, 1, 3/2, 2) TESTS:: @@ -2281,7 +2294,7 @@ def is_submodule(self, other): False sage: M1 = QQ^3 / [[1,2,3]] - sage: V1 = span(QQ,[(1,0,0)]) + M1.relations() + sage: V1 = span(QQ, [(1,0,0)]) + M1.relations() sage: M2 = V1 / M1.relations() sage: M2.is_submodule(M1) # Different ambient vector spaces False @@ -2355,14 +2368,16 @@ def __iter__(self): EXAMPLES:: - sage: V = VectorSpace(GF(4,'a'),2) - sage: [x for x in V] - [(0, 0), (a, 0), (a + 1, 0), (1, 0), (0, a), (a, a), (a + 1, a), (1, a), (0, a + 1), (a, a + 1), (a + 1, a + 1), (1, a + 1), (0, 1), (a, 1), (a + 1, 1), (1, 1)] + sage: V = VectorSpace(GF(4, 'a'), 2) # optional - sage.rings.finite_rings + sage: [x for x in V] # optional - sage.rings.finite_rings + [(0, 0), (a, 0), (a + 1, 0), (1, 0), (0, a), (a, a), (a + 1, a), (1, a), + (0, a + 1), (a, a + 1), (a + 1, a + 1), (1, a + 1), (0, 1), (a, 1), + (a + 1, 1), (1, 1)] :: - sage: W = V.subspace([V([1,1])]) - sage: [x for x in W] + sage: W = V.subspace([V([1, 1])]) # optional - sage.rings.finite_rings + sage: [x for x in W] # optional - sage.rings.finite_rings [(0, 0), (a, a), (a + 1, a + 1), (1, 1)] Free modules over enumerated infinite rings (i.e., those in the @@ -2379,8 +2394,8 @@ def __iter__(self): TESTS:: - sage: V = VectorSpace(GF(2,'a'),2) - sage: V.list() + sage: V = VectorSpace(GF(2, 'a'), 2) # optional - sage.rings.finite_rings + sage: V.list() # optional - sage.rings.finite_rings [(0, 0), (1, 0), (0, 1), (1, 1)] Test ``iter(ZZ^n)`` and the like:: @@ -2462,15 +2477,15 @@ def cardinality(self): EXAMPLES:: - sage: k. = FiniteField(9) - sage: V = VectorSpace(k,3) - sage: V.cardinality() + sage: k. = FiniteField(9) # optional - sage.rings.finite_rings + sage: V = VectorSpace(k, 3) # optional - sage.rings.finite_rings + sage: V.cardinality() # optional - sage.rings.finite_rings 729 - sage: W = V.span([[1,2,1],[0,1,1]]) - sage: W.cardinality() + sage: W = V.span([[1,2,1], [0,1,1]]) # optional - sage.rings.finite_rings + sage: W.cardinality() # optional - sage.rings.finite_rings 81 sage: R = IntegerModRing(12) - sage: M = FreeModule(R,2) + sage: M = FreeModule(R, 2) sage: M.cardinality() 144 sage: (QQ^3).cardinality() @@ -2526,32 +2541,32 @@ def basis_matrix(self, ring=None): EXAMPLES:: - sage: FreeModule(Integers(12),3).basis_matrix() + sage: FreeModule(Integers(12), 3).basis_matrix() [1 0 0] [0 1 0] [0 0 1] :: - sage: M = FreeModule(GF(7),3).span([[2,3,4],[1,1,1]]); M + sage: M = FreeModule(GF(7), 3).span([[2,3,4], [1,1,1]]); M # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 2 over Finite Field of size 7 Basis matrix: [1 0 6] [0 1 2] - sage: M.basis_matrix() + sage: M.basis_matrix() # optional - sage.rings.finite_rings [1 0 6] [0 1 2] :: - sage: M = FreeModule(GF(7),3).span_of_basis([[2,3,4],[1,1,1]]) - sage: M.basis_matrix() + sage: M = FreeModule(GF(7), 3).span_of_basis([[2,3,4], [1,1,1]]) # optional - sage.rings.finite_rings + sage: M.basis_matrix() # optional - sage.rings.finite_rings [2 3 4] [1 1 1] :: - sage: M = FreeModule(QQ,2).span_of_basis([[1,-1],[1,0]]); M + sage: M = FreeModule(QQ, 2).span_of_basis([[1,-1], [1,0]]); M Vector space of degree 2 and dimension 2 over Rational Field User basis matrix: [ 1 -1] @@ -2615,7 +2630,7 @@ def echelonized_basis_matrix(self): sage: R = IntegerModRing(12) sage: S. = R[] - sage: M = FreeModule(S,3) + sage: M = FreeModule(S, 3) sage: M.echelonized_basis_matrix() [1 0 0] [0 1 0] @@ -2700,9 +2715,9 @@ def coordinates(self, v, check=True): EXAMPLES:: - sage: M = FreeModule(ZZ, 2); M0,M1=M.gens() + sage: M = FreeModule(ZZ, 2); M0, M1 = M.gens() sage: W = M.submodule([M0 + M1, M0 - 2*M1]) - sage: W.coordinates(2*M0-M1) + sage: W.coordinates(2*M0 - M1) [2, -1] """ return self.coordinate_vector(v, check=check).list() @@ -2723,7 +2738,7 @@ def coordinate_vector(self, v, check=True): EXAMPLES:: - sage: M = FreeModule(ZZ, 2); M0,M1=M.gens() + sage: M = FreeModule(ZZ, 2); M0, M1 = M.gens() sage: W = M.submodule([M0 + M1, M0 - 2*M1]) sage: W.coordinate_vector(2*M0 - M1) (2, -1) @@ -2806,9 +2821,9 @@ def dimension(self): EXAMPLES:: - sage: M = FreeModule(FiniteField(19), 100) - sage: W = M.submodule([M.gen(50)]) - sage: W.dimension() + sage: M = FreeModule(FiniteField(19), 100) # optional - sage.rings.finite_rings + sage: W = M.submodule([M.gen(50)]) # optional - sage.rings.finite_rings + sage: W.dimension() # optional - sage.rings.finite_rings 1 """ return self.rank() @@ -2863,12 +2878,13 @@ def base_field(self): EXAMPLES:: - sage: FreeModule(GF(3), 2).base_field() + sage: FreeModule(GF(3), 2).base_field() # optional - sage.rings.finite_rings Finite Field of size 3 - sage: FreeModule(ZZ, 2).base_field() + sage: FreeModule(ZZ, 2).base_field() # optional - sage.rings.finite_rings Rational Field - sage: FreeModule(PolynomialRing(GF(7),'x'), 2).base_field() - Fraction Field of Univariate Polynomial Ring in x over Finite Field of size 7 + sage: FreeModule(PolynomialRing(GF(7), 'x'), 2).base_field() # optional - sage.rings.finite_rings + Fraction Field of Univariate Polynomial Ring in x + over Finite Field of size 7 """ return self.base_ring().fraction_field() @@ -3366,7 +3382,7 @@ def _magma_init_(self, magma): Inner product matrix: [ 1 0] [ 0 -1] - sage: m.sage() is M # optional - magma + sage: m.sage() is M # optional - magma True Now over a field:: @@ -3527,11 +3543,12 @@ def _mul_(self, other, switch_sides=False): Check that :trac:`17705` is fixed:: - sage: V = GF(2)^2 - sage: W = V.subspace([[1, 0]]) - sage: x = matrix(GF(2), [[1, 1], [0, 1]]) - sage: W*x - Vector space of degree 2 and dimension 1 over Finite Field of size 2 + sage: V = GF(2)^2 # optional - sage.rings.finite_rings + sage: W = V.subspace([[1, 0]]) # optional - sage.rings.finite_rings + sage: x = matrix(GF(2), [[1, 1], [0, 1]]) # optional - sage.rings.finite_rings + sage: W*x # optional - sage.rings.finite_rings + Vector space of degree 2 and dimension 1 + over Finite Field of size 2 Basis matrix: [1 1] @@ -3546,15 +3563,15 @@ def relations(self): EXAMPLES:: - sage: V = GF(2)^2 - sage: V.relations() == V.zero_submodule() + sage: V = GF(2)^2 # optional - sage.rings.finite_rings + sage: V.relations() == V.zero_submodule() # optional - sage.rings.finite_rings True - sage: W = V.subspace([[1, 0]]) - sage: W.relations() == V.zero_submodule() + sage: W = V.subspace([[1, 0]]) # optional - sage.rings.finite_rings + sage: W.relations() == V.zero_submodule() # optional - sage.rings.finite_rings True - sage: Q = V / W - sage: Q.relations() == W + sage: Q = V / W # optional - sage.rings.finite_rings + sage: Q.relations() == W # optional - sage.rings.finite_rings True """ return self.zero_submodule() @@ -3571,9 +3588,12 @@ def __init__(self, base_ring, rank, degree, sparse=False, coordinate_ring=None, EXAMPLES:: sage: FreeModule(ZZ, 2) - Ambient free module of rank 2 over the principal ideal domain Integer Ring - sage: FreeModule(PolynomialRing(GF(7),'x'), 2) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Finite Field of size 7 + Ambient free module of rank 2 + over the principal ideal domain Integer Ring + sage: FreeModule(PolynomialRing(GF(7), 'x'), 2) # optional - sage.rings.finite_rings + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x + over Finite Field of size 7 """ FreeModule_generic.__init__(self, base_ring, rank, degree, sparse, coordinate_ring, category=category) @@ -3665,9 +3685,12 @@ def __init__(self, base_ring, rank, degree, sparse=False, coordinate_ring=None, EXAMPLES:: sage: FreeModule(ZZ, 2) - Ambient free module of rank 2 over the principal ideal domain Integer Ring - sage: FreeModule(PolynomialRing(GF(7),'x'), 2) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Finite Field of size 7 + Ambient free module of rank 2 + over the principal ideal domain Integer Ring + sage: FreeModule(PolynomialRing(GF(7), 'x'), 2) # optional - sage.rings.finite_rings + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x + over Finite Field of size 7 """ super().__init__(base_ring, rank, degree, sparse, coordinate_ring, category=category) @@ -4193,10 +4216,11 @@ def vector_space_span(self, gens, check=True): :: sage: R. = QQ[] - sage: K = NumberField(x^2 + 1, 'a'); a = K.gen() - sage: V = VectorSpace(K, 3) - sage: V.vector_space_span([2*V.gen(0) + 3*V.gen(2)]) - Vector space of degree 3 and dimension 1 over Number Field in a with defining polynomial x^2 + 1 + sage: K = NumberField(x^2 + 1, 'a'); a = K.gen() # optional - sage.rings.number_field + sage: V = VectorSpace(K, 3) # optional - sage.rings.number_field + sage: V.vector_space_span([2*V.gen(0) + 3*V.gen(2)]) # optional - sage.rings.number_field + Vector space of degree 3 and dimension 1 + over Number Field in a with defining polynomial x^2 + 1 Basis matrix: [ 1 0 3/2] @@ -4206,7 +4230,7 @@ def vector_space_span(self, gens, check=True): :: - sage: M = FreeModule(ZZ,3) + sage: M = FreeModule(ZZ, 3) sage: W = M.submodule([M([1,2,3])]) sage: W.vector_space_span([M([2,3,4])]) Vector space of degree 3 and dimension 1 over Rational Field @@ -4235,7 +4259,7 @@ def vector_space_span_of_basis(self, basis, check=True): sage: V = VectorSpace(QQ, 3) sage: B = V.basis() - sage: W = V.vector_space_span_of_basis([B[0]+B[1], 2*B[1]-B[2]]) + sage: W = V.vector_space_span_of_basis([B[0] + B[1], 2*B[1] - B[2]]) sage: W Vector space of degree 3 and dimension 2 over Rational Field User basis matrix: @@ -4291,7 +4315,7 @@ def __init__(self, base_field, dimension, degree, sparse=False, category=None): sage: FreeModule(QQ, 2) Vector space of dimension 2 over Rational Field - sage: FreeModule(FiniteField(2), 7) + sage: FreeModule(FiniteField(2), 7) # optional - sage.rings.finite_rings Vector space of dimension 7 over Finite Field of size 2 We test that objects of this type are initialised correctly; @@ -4336,7 +4360,9 @@ def _Hom_(self, Y, category): sage: type(H) sage: H - Set of Morphisms (Linear Transformations) from Vector space of dimension 2 over Rational Field to Vector space of dimension 3 over Rational Field + Set of Morphisms (Linear Transformations) + from Vector space of dimension 2 over Rational Field + to Vector space of dimension 3 over Rational Field sage: V = QQ^2 sage: W = ZZ^3 @@ -4581,12 +4607,12 @@ def span_of_basis(self, basis, base_ring=None, check=True, already_echelonized=F EXAMPLES:: - sage: V = VectorSpace(GF(7), 3) - sage: W = V.subspace([[2,3,4]]); W + sage: V = VectorSpace(GF(7), 3) # optional - sage.rings.finite_rings + sage: W = V.subspace([[2,3,4]]); W # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] - sage: W.span_of_basis([[2,2,2], [3,3,0]]) + sage: W.span_of_basis([[2,2,2], [3,3,0]]) # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 2 over Finite Field of size 7 User basis matrix: [2 2 2] @@ -4595,7 +4621,7 @@ def span_of_basis(self, basis, base_ring=None, check=True, already_echelonized=F The basis vectors must be linearly independent or a ``ValueError`` exception is raised:: - sage: W.span_of_basis([[2,2,2], [3,3,3]]) + sage: W.span_of_basis([[2,2,2], [3,3,3]]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent. @@ -4636,8 +4662,8 @@ def subspace(self, gens, check=True, already_echelonized=False): ambient `3`-dimensional space over the finite field of order `7`:: - sage: V = VectorSpace(GF(7), 3) - sage: W = V.subspace([[2,3,4]]); W + sage: V = VectorSpace(GF(7), 3) # optional - sage.rings.finite_rings + sage: W = V.subspace([[2,3,4]]); W # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] @@ -4646,7 +4672,7 @@ def subspace(self, gens, check=True, already_echelonized=False): ``check=False``. This is just equivalent to computing the span of the element:: - sage: W.subspace([[1,1,0]], check=False) + sage: W.subspace([[1,1,0]], check=False) # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 1 0] @@ -4654,7 +4680,7 @@ def subspace(self, gens, check=True, already_echelonized=False): With ``check=True`` (the default) the mistake is correctly detected and reported with an ``ArithmeticError`` exception:: - sage: W.subspace([[1,1,0]], check=True) + sage: W.subspace([[1,1,0]], check=True) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ArithmeticError: argument gens (= [[1, 1, 0]]) does not generate a submodule of self @@ -4671,25 +4697,25 @@ def subspaces(self, dim): EXAMPLES:: - sage: V = VectorSpace(GF(3), 5) - sage: len(list(V.subspaces(0))) + sage: V = VectorSpace(GF(3), 5) # optional - sage.rings.finite_rings + sage: len(list(V.subspaces(0))) # optional - sage.rings.finite_rings 1 - sage: len(list(V.subspaces(1))) + sage: len(list(V.subspaces(1))) # optional - sage.rings.finite_rings 121 - sage: len(list(V.subspaces(2))) + sage: len(list(V.subspaces(2))) # optional - sage.rings.finite_rings 1210 - sage: len(list(V.subspaces(3))) + sage: len(list(V.subspaces(3))) # optional - sage.rings.finite_rings 1210 - sage: len(list(V.subspaces(4))) + sage: len(list(V.subspaces(4))) # optional - sage.rings.finite_rings 121 - sage: len(list(V.subspaces(5))) + sage: len(list(V.subspaces(5))) # optional - sage.rings.finite_rings 1 :: - sage: V = VectorSpace(GF(3), 5) - sage: V = V.subspace([V([1,1,0,0,0]),V([0,0,1,1,0])]) - sage: list(V.subspaces(1)) + sage: V = VectorSpace(GF(3), 5) # optional - sage.rings.finite_rings + sage: V = V.subspace([V([1,1,0,0,0]), V([0,0,1,1,0])]) # optional - sage.rings.finite_rings + sage: list(V.subspaces(1)) # optional - sage.rings.finite_rings [Vector space of degree 5 and dimension 1 over Finite Field of size 3 Basis matrix: [1 1 0 0 0], @@ -4720,8 +4746,8 @@ def subspace_with_basis(self, gens, check=True, already_echelonized=False): :: - sage: V = VectorSpace(GF(7), 3) - sage: W = V.subspace_with_basis([[2,2,2], [1,2,3]]); W + sage: V = VectorSpace(GF(7), 3) # optional - sage.rings.finite_rings + sage: W = V.subspace_with_basis([[2,2,2], [1,2,3]]); W # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 2 over Finite Field of size 7 User basis matrix: [2 2 2] @@ -4731,7 +4757,7 @@ def subspace_with_basis(self, gens, check=True, already_echelonized=False): :: - sage: W1 = W.subspace_with_basis([[3,4,5]]); W1 + sage: W1 = W.subspace_with_basis([[3,4,5]]); W1 # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 1 over Finite Field of size 7 User basis matrix: [3 4 5] @@ -4741,14 +4767,14 @@ def subspace_with_basis(self, gens, check=True, already_echelonized=False): :: - sage: W2 = W.subspace([[3,4,5]]); W2 + sage: W2 = W.subspace([[3,4,5]]); W2 # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 6 4] Nonetheless the two subspaces are equal (as mathematical objects):: - sage: W1 == W2 + sage: W1 == W2 # optional - sage.rings.finite_rings True """ return self.submodule_with_basis(gens, check=check, already_echelonized=already_echelonized) @@ -4796,14 +4822,14 @@ def complement(self): we can get complements which are only isomorphic to a vector space decomposition complement. :: - sage: F2 = GF(2,x) - sage: V = F2^6 - sage: W = V.span([[1,1,0,0,0,0]]) - sage: W + sage: F2 = GF(2, x) # optional - sage.rings.finite_rings + sage: V = F2^6 # optional - sage.rings.finite_rings + sage: W = V.span([[1,1,0,0,0,0]]) # optional - sage.rings.finite_rings + sage: W # optional - sage.rings.finite_rings Vector space of degree 6 and dimension 1 over Finite Field of size 2 Basis matrix: [1 1 0 0 0 0] - sage: W.complement() + sage: W.complement() # optional - sage.rings.finite_rings Vector space of degree 6 and dimension 5 over Finite Field of size 2 Basis matrix: [1 1 0 0 0 0] @@ -4811,7 +4837,7 @@ def complement(self): [0 0 0 1 0 0] [0 0 0 0 1 0] [0 0 0 0 0 1] - sage: W.intersection(W.complement()) + sage: W.intersection(W.complement()) # optional - sage.rings.finite_rings Vector space of degree 6 and dimension 1 over Finite Field of size 2 Basis matrix: [1 1 0 0 0 0] @@ -4973,23 +4999,23 @@ def linear_dependence(self, vectors, zeros='left', check=True): linearly independent vectors and add in two linear combinations to make a linearly dependent set of five vectors. :: - sage: F = FiniteField(17) - sage: v1 = vector(F, [1, 2, 3, 4, 5]) - sage: v2 = vector(F, [2, 4, 8, 16, 15]) - sage: v3 = vector(F, [1, 0, 0, 0, 1]) - sage: (F^5).linear_dependence([v1, v2, v3]) == [] + sage: F = FiniteField(17) # optional - sage.rings.finite_rings + sage: v1 = vector(F, [1, 2, 3, 4, 5]) # optional - sage.rings.finite_rings + sage: v2 = vector(F, [2, 4, 8, 16, 15]) # optional - sage.rings.finite_rings + sage: v3 = vector(F, [1, 0, 0, 0, 1]) # optional - sage.rings.finite_rings + sage: (F^5).linear_dependence([v1, v2, v3]) == [] # optional - sage.rings.finite_rings True - sage: L = [v1, v2, v3, 2*v1+v2, 3*v2+6*v3] - sage: (F^5).linear_dependence(L) + sage: L = [v1, v2, v3, 2*v1+v2, 3*v2+6*v3] # optional - sage.rings.finite_rings + sage: (F^5).linear_dependence(L) # optional - sage.rings.finite_rings [ (1, 0, 16, 8, 3), (0, 1, 2, 0, 11) ] - sage: v1 + 16*v3 + 8*(2*v1+v2) + 3*(3*v2+6*v3) + sage: v1 + 16*v3 + 8*(2*v1+v2) + 3*(3*v2+6*v3) # optional - sage.rings.finite_rings (0, 0, 0, 0, 0) - sage: v2 + 2*v3 + 11*(3*v2+6*v3) + sage: v2 + 2*v3 + 11*(3*v2+6*v3) # optional - sage.rings.finite_rings (0, 0, 0, 0, 0) - sage: (F^5).linear_dependence(L, zeros='right') + sage: (F^5).linear_dependence(L, zeros='right') # optional - sage.rings.finite_rings [ (15, 16, 0, 1, 0), (0, 14, 11, 0, 1) @@ -5005,7 +5031,8 @@ def linear_dependence(self, vectors, zeros='left', check=True): sage: (RR^3).linear_dependence([v1,v2], check=True) Traceback (most recent call last): ... - ValueError: vector (1.00000000000000, 2.00000000000000, 3.00000000000000, 4.00000000000000) is not an element of Vector space of dimension 3 over Real Field with 53 bits of precision + ValueError: vector (1.00000000000000, 2.00000000000000, 3.00000000000000, 4.00000000000000) + is not an element of Vector space of dimension 3 over Real Field with 53 bits of precision The ``zeros`` keyword is checked. :: @@ -5134,7 +5161,7 @@ def __quotient_matrices(self, sub): An example in characteristic 5:: - sage: A = GF(5)^2; B = A.span([[1,3]]); A / B + sage: A = GF(5)^2; B = A.span([[1,3]]); A / B # optional - sage.rings.finite_rings Vector space quotient V/W of dimension 1 over Finite Field of size 5 where V: Vector space of dimension 2 over Finite Field of size 5 W: Vector space of degree 2 and dimension 1 over Finite Field of size 5 @@ -5224,19 +5251,19 @@ def quotient_abstract(self, sub, check=True, **kwds): EXAMPLES:: - sage: V = GF(19)^3 - sage: W = V.span_of_basis([ [1,2,3], [1,0,1] ]) - sage: U,pi,lift = V.quotient_abstract(W) - sage: pi(V.2) + sage: V = GF(19)^3 # optional - sage.rings.finite_rings + sage: W = V.span_of_basis([[1,2,3], [1,0,1]]) # optional - sage.rings.finite_rings + sage: U, pi, lift = V.quotient_abstract(W) # optional - sage.rings.finite_rings + sage: pi(V.2) # optional - sage.rings.finite_rings (18) - sage: pi(V.0) + sage: pi(V.0) # optional - sage.rings.finite_rings (1) - sage: pi(V.0 + V.2) + sage: pi(V.0 + V.2) # optional - sage.rings.finite_rings (0) Another example involving a quotient of one subspace by another:: - sage: A = matrix(QQ,4,4,[0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0]) + sage: A = matrix(QQ, 4,4, [0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0]) sage: V = (A^3).kernel() sage: W = A.kernel() sage: U, pi, lift = V.quotient_abstract(W) @@ -5296,14 +5323,14 @@ def __init__(self, base_ring, rank, sparse=False, coordinate_ring=None, category We check that the creation of a submodule does not trigger the construction of a basis of the ambient space. See :trac:`15953`:: - sage: F. = GF(4) - sage: V = VectorSpace(F, 1) - sage: v = V.random_element() - sage: _ = V.subspace([v]) - sage: hasattr(V, '_FreeModule_ambient__basis') + sage: F. = GF(4) # optional - sage.rings.finite_rings + sage: V = VectorSpace(F, 1) # optional - sage.rings.finite_rings + sage: v = V.random_element() # optional - sage.rings.finite_rings + sage: _ = V.subspace([v]) # optional - sage.rings.finite_rings + sage: hasattr(V, '_FreeModule_ambient__basis') # optional - sage.rings.finite_rings False - sage: _ = V.basis() - sage: hasattr(V, '_FreeModule_ambient__basis') + sage: _ = V.basis() # optional - sage.rings.finite_rings + sage: hasattr(V, '_FreeModule_ambient__basis') # optional - sage.rings.finite_rings True """ FreeModule_generic.__init__(self, base_ring, rank=rank, @@ -5586,14 +5613,14 @@ def _latex_(self): :: - sage: A = GF(5)^20 - sage: latex(A) # indirect doctest + sage: A = GF(5)^20 # optional - sage.rings.finite_rings + sage: latex(A) # indirect doctest # optional - sage.rings.finite_rings \Bold{F}_{5}^{20} :: - sage: A = PolynomialRing(QQ,3,'x') ^ 20 - sage: latex(A) #indirect doctest + sage: A = PolynomialRing(QQ, 3, 'x')^20 + sage: latex(A) # indirect doctest (\Bold{Q}[x_{0}, x_{1}, x_{2}])^{20} """ t = "%s" % latex.latex(self.base_ring()) @@ -5688,12 +5715,12 @@ def change_ring(self, R): sage: A = ZZ^3; A.change_ring(QQ) Vector space of dimension 3 over Rational Field - sage: A = ZZ^3; A.change_ring(GF(5)) + sage: A = ZZ^3; A.change_ring(GF(5)) # optional - sage.rings.finite_rings Vector space of dimension 3 over Finite Field of size 5 For ambient modules any change of rings is defined:: - sage: A = GF(5)**3; A.change_ring(QQ) + sage: A = GF(5)**3; A.change_ring(QQ) # optional - sage.rings.finite_rings Vector space of dimension 3 over Rational Field TESTS: @@ -5958,9 +5985,9 @@ def _sympy_(self): EXAMPLES:: - sage: sZZ3 = (ZZ^3)._sympy_(); sZZ3 + sage: sZZ3 = (ZZ^3)._sympy_(); sZZ3 # optional - sympy ProductSet(Integers, Integers, Integers) - sage: (1, 2, 3) in sZZ3 + sage: (1, 2, 3) in sZZ3 # optional - sympy True """ from sympy import ProductSet @@ -5981,9 +6008,9 @@ class FreeModule_ambient_domain(FreeModule_generic_domain, FreeModule_ambient): EXAMPLES:: - sage: FreeModule(PolynomialRing(GF(5),'x'), 3) + sage: FreeModule(PolynomialRing(GF(5), 'x'), 3) # optional - sage.rings.finite_rings Ambient free module of rank 3 over the principal ideal domain - Univariate Polynomial Ring in x over Finite Field of size 5 + Univariate Polynomial Ring in x over Finite Field of size 5 """ def __init__(self, base_ring, rank, sparse=False, coordinate_ring=None, category=None): """ @@ -5992,8 +6019,8 @@ def __init__(self, base_ring, rank, sparse=False, coordinate_ring=None, category TESTS:: - sage: A = FreeModule(PolynomialRing(GF(5),'x'), 3) - sage: TestSuite(A).run() + sage: A = FreeModule(PolynomialRing(GF(5),'x'), 3) # optional - sage.rings.finite_rings + sage: TestSuite(A).run() # optional - sage.rings.finite_rings """ FreeModule_ambient.__init__(self, base_ring, rank, sparse, coordinate_ring, category=category) @@ -6004,7 +6031,7 @@ def _repr_(self): EXAMPLES:: sage: R = PolynomialRing(ZZ,'x') - sage: M = FreeModule(R,7) + sage: M = FreeModule(R, 7) sage: M Ambient free module of rank 7 over the integral domain Univariate Polynomial Ring in x over Integer Ring sage: print(M._repr_()) @@ -6024,7 +6051,7 @@ def _repr_(self): :: - sage: N = FreeModule(R,7,sparse=True) + sage: N = FreeModule(R, 7, sparse=True) sage: N Ambient sparse free module of rank 7 over the integral domain Univariate Polynomial Ring in x over Integer Ring @@ -6340,9 +6367,9 @@ def _element_constructor_(self, e, *args, **kwds): EXAMPLES:: - sage: k. = GF(3^4) - sage: VS = k.vector_space(map=False) - sage: VS(a) + sage: k. = GF(3^4) # optional - sage.rings.finite_rings + sage: VS = k.vector_space(map=False) # optional - sage.rings.finite_rings + sage: VS(a) # optional - sage.rings.finite_rings (0, 1, 0, 0) """ try: @@ -6409,7 +6436,7 @@ class FreeModule_submodule_with_basis_pid(FreeModule_generic_pid): EXAMPLES:: sage: M = ZZ^3 - sage: W = M.span_of_basis([[1,2,3],[4,5,6]]); W + sage: W = M.span_of_basis([[1,2,3], [4,5,6]]); W Free module of degree 3 and rank 2 over Integer Ring User basis matrix: [1 2 3] @@ -6418,7 +6445,7 @@ class FreeModule_submodule_with_basis_pid(FreeModule_generic_pid): Now we create a submodule of the ambient vector space, rather than ``M`` itself:: - sage: W = M.span_of_basis([[1,2,3/2],[4,5,6]]); W + sage: W = M.span_of_basis([[1,2,3/2], [4,5,6]]); W Free module of degree 3 and rank 2 over Integer Ring User basis matrix: [ 1 2 3/2] @@ -6453,8 +6480,8 @@ def __init__(self, ambient, basis, check=True, :trac:`10250` is solved as well:: sage: V = (QQ^2).span_of_basis([[1,1]]) - sage: w = sqrt(2) * V([1,1]) - sage: 3 * w + sage: w = sqrt(2) * V([1,1]) # optional - sage.symbolic + sage: 3 * w # optional - sage.symbolic (3*sqrt(2), 3*sqrt(2)) TESTS: @@ -6674,9 +6701,9 @@ def _echelonized_basis(self, ambient, basis): sage: W = V.submodule_with_basis([[1,1,0],[0,2,1]]) sage: W._echelonized_basis(V,W.basis()) [(1, 0, -1/2), (0, 1, 1/2)] - sage: V = SR^3 - sage: W = V.submodule_with_basis([[1,0,1]]) - sage: W._echelonized_basis(V,W.basis()) + sage: V = SR^3 # optional - sage.symbolic + sage: W = V.submodule_with_basis([[1,0,1]]) # optional - sage.symbolic + sage: W._echelonized_basis(V, W.basis()) # optional - sage.symbolic [(1, 0, 1)] """ # Return the first rank rows (i.e., the nonzero rows). @@ -6704,7 +6731,7 @@ def _denominator(self, B): EXAMPLES:: sage: V = QQ^3 - sage: L = V.span([[1,1/2,1/3], [-1/5,2/3,3]],ZZ) + sage: L = V.span([[1,1/2,1/3], [-1/5,2/3,3]], ZZ) sage: L Free module of degree 3 and rank 2 over Integer Ring Echelon basis matrix: @@ -6924,15 +6951,15 @@ def relations(self): EXAMPLES:: - sage: V = GF(2)^2 - sage: W = V.subspace([[1, 0]]) - sage: W.relations() == V.zero_submodule() + sage: V = GF(2)^2 # optional - sage.rings.finite_rings + sage: W = V.subspace([[1, 0]]) # optional - sage.rings.finite_rings + sage: W.relations() == V.zero_submodule() # optional - sage.rings.finite_rings True - sage: Q = V / W - sage: Q.relations() == W + sage: Q = V / W # optional - sage.rings.finite_rings + sage: Q.relations() == W # optional - sage.rings.finite_rings True - sage: Q.zero_submodule().relations() == W + sage: Q.zero_submodule().relations() == W # optional - sage.rings.finite_rings True """ return self.__ambient_module.relations() @@ -7333,7 +7360,7 @@ def change_ring(self, R): sage: V = QQ^3 sage: W = V.subspace([[2, 1/2, 1]]) - sage: W.change_ring(GF(7)) + sage: W.change_ring(GF(7)) # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 2 4] @@ -7349,7 +7376,8 @@ def change_ring(self, R): [0 1] sage: N = M.change_ring(QQ['x']) sage: N - Free module of degree 2 and rank 2 over Univariate Polynomial Ring in x over Rational Field + Free module of degree 2 and rank 2 + over Univariate Polynomial Ring in x over Rational Field Echelon basis matrix: [1/2 0] [ 0 1/2] @@ -7361,7 +7389,8 @@ def change_ring(self, R): sage: M.change_ring(ZZ['x']) Traceback (most recent call last): ... - TypeError: the new ring Univariate Polynomial Ring in x over Integer Ring should be a principal ideal domain + TypeError: the new ring Univariate Polynomial Ring in x over Integer Ring + should be a principal ideal domain """ if self.base_ring() is R: return self @@ -8129,8 +8158,8 @@ def element_class(R, is_sparse): EXAMPLES:: - sage: FF = FiniteField(2) - sage: P = PolynomialRing(FF,'x') + sage: FF = FiniteField(2) # optional - sage.rings.finite_rings + sage: P = PolynomialRing(FF,'x') # optional - sage.rings.finite_rings sage: sage.modules.free_module.element_class(QQ, is_sparse=True) sage: sage.modules.free_module.element_class(QQ, is_sparse=False) @@ -8139,15 +8168,15 @@ def element_class(R, is_sparse): sage: sage.modules.free_module.element_class(ZZ, is_sparse=False) - sage: sage.modules.free_module.element_class(FF, is_sparse=True) + sage: sage.modules.free_module.element_class(FF, is_sparse=True) # optional - sage.rings.finite_rings - sage: sage.modules.free_module.element_class(FF, is_sparse=False) + sage: sage.modules.free_module.element_class(FF, is_sparse=False) # optional - sage.rings.finite_rings - sage: sage.modules.free_module.element_class(GF(7), is_sparse=False) + sage: sage.modules.free_module.element_class(GF(7), is_sparse=False) # optional - sage.rings.finite_rings - sage: sage.modules.free_module.element_class(P, is_sparse=True) + sage: sage.modules.free_module.element_class(P, is_sparse=True) # optional - sage.rings.finite_rings - sage: sage.modules.free_module.element_class(P, is_sparse=False) + sage: sage.modules.free_module.element_class(P, is_sparse=False) # optional - sage.rings.finite_rings """ import sage.rings.integer_ring @@ -8158,14 +8187,21 @@ def element_class(R, is_sparse): from .vector_rational_dense import Vector_rational_dense return Vector_rational_dense elif isinstance(R, sage.rings.abc.IntegerModRing) and not is_sparse: - from .vector_mod2_dense import Vector_mod2_dense if R.order() == 2: - return Vector_mod2_dense - from .vector_modn_dense import Vector_modn_dense, MAX_MODULUS - if R.order() < MAX_MODULUS: - return Vector_modn_dense + try: + from .vector_mod2_dense import Vector_mod2_dense + except ImportError: + pass + else: + return Vector_mod2_dense + try: + from .vector_modn_dense import Vector_modn_dense, MAX_MODULUS + except ImportError: + pass else: - return free_module_element.FreeModuleElement_generic_dense + if R.order() < MAX_MODULUS: + return Vector_modn_dense + return free_module_element.FreeModuleElement_generic_dense elif isinstance(R, sage.rings.abc.RealDoubleField) and not is_sparse: try: from sage.modules.vector_real_double_dense import Vector_real_double_dense @@ -8228,7 +8264,7 @@ def __init__(self, obj): EXAMPLES:: sage: R. = QQ[] - sage: V = span(R,[[x,1+x],[x^2,2+x]]) + sage: V = span(R, [[x, 1 + x], [x^2, 2 + x]]) sage: W = R^2 sage: from sage.modules.free_module import EchelonMatrixKey sage: V = EchelonMatrixKey(V) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 65cd226a941..a790ab4f428 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -43,7 +43,7 @@ field. :: sage: K = ZZ^5 - sage: M = GF(7)^5 + sage: M = GF(7)^5 # optional - sage.rings.finite_rings Arithmetic between the `\QQ` and `\ZZ` modules is defined, and the result is always @@ -60,10 +60,12 @@ to `\QQ`. Since there is no canonical coercion map to the finite field from `\QQ` the following arithmetic is not defined:: - sage: V.0 + M.0 + sage: V.0 + M.0 # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for +: 'Vector space of dimension 5 over Rational Field' and 'Vector space of dimension 5 over Finite Field of size 7' + TypeError: unsupported operand parent(s) for +: + 'Vector space of dimension 5 over Rational Field' and + 'Vector space of dimension 5 over Finite Field of size 7' However, there is a map from `\ZZ` to the finite field, so the following is defined, and the result is in the finite @@ -71,16 +73,16 @@ field. :: - sage: w = K.0 + M.0; w + sage: w = K.0 + M.0; w # optional - sage.rings.finite_rings (2, 0, 0, 0, 0) - sage: parent(w) + sage: parent(w) # optional - sage.rings.finite_rings Vector space of dimension 5 over Finite Field of size 7 - sage: parent(M.0 + K.0) + sage: parent(M.0 + K.0) # optional - sage.rings.finite_rings Vector space of dimension 5 over Finite Field of size 7 Matrix vector multiply:: - sage: MS = MatrixSpace(QQ,3) + sage: MS = MatrixSpace(QQ, 3) sage: A = MS([0,1,0,1,0,0,0,0,1]) sage: V = QQ^3 sage: v = V([1,2,3]) @@ -214,20 +216,20 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): All entries must *canonically* coerce to some common ring:: - sage: v = vector([17, GF(11)(5), 19/3]); v + sage: v = vector([17, GF(11)(5), 19/3]); v # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unable to find a common ring for all elements :: - sage: v = vector([17, GF(11)(5), 19]); v + sage: v = vector([17, GF(11)(5), 19]); v # optional - sage.rings.finite_rings (6, 5, 8) - sage: v.parent() + sage: v.parent() # optional - sage.rings.finite_rings Vector space of dimension 3 over Finite Field of size 11 - sage: v = vector([17, GF(11)(5), 19], QQ); v + sage: v = vector([17, GF(11)(5), 19], QQ); v # optional - sage.rings.finite_rings (17, 5, 19) - sage: v.parent() + sage: v.parent() # optional - sage.rings.finite_rings Vector space of dimension 3 over Rational Field sage: v = vector((1,2,3), QQ); v (1, 2, 3) @@ -250,7 +252,7 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): We make a vector mod 3 out of a vector over `\ZZ`. :: - sage: vector(vector([1,2,3]), GF(3)) + sage: vector(vector([1,2,3]), GF(3)) # optional - sage.rings.finite_rings (1, 2, 0) The degree of a vector may be specified:: @@ -270,9 +272,9 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): you must specify the degree since it is not implied. Here we use a finite field as the base ring. :: - sage: w = vector(FiniteField(7), 4); w + sage: w = vector(FiniteField(7), 4); w # optional - sage.rings.finite_rings (0, 0, 0, 0) - sage: w.parent() + sage: w.parent() # optional - sage.rings.finite_rings Vector space of dimension 4 over Finite Field of size 7 The fastest method to construct a zero vector is to call the @@ -346,27 +348,27 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): must be contiguous, so column-wise slices of numpy matrices will raise an exception. :: - sage: import numpy - sage: x = numpy.random.randn(10) - sage: y = vector(x) - sage: parent(y) + sage: import numpy # optional - numpy + sage: x = numpy.random.randn(10) # optional - numpy + sage: y = vector(x) # optional - numpy + sage: parent(y) # optional - numpy Vector space of dimension 10 over Real Double Field - sage: parent(vector(RDF, x)) + sage: parent(vector(RDF, x)) # optional - numpy Vector space of dimension 10 over Real Double Field - sage: parent(vector(CDF, x)) + sage: parent(vector(CDF, x)) # optional - numpy Vector space of dimension 10 over Complex Double Field - sage: parent(vector(RR, x)) + sage: parent(vector(RR, x)) # optional - numpy Vector space of dimension 10 over Real Field with 53 bits of precision - sage: v = numpy.random.randn(10) * complex(0,1) - sage: w = vector(v) - sage: parent(w) + sage: v = numpy.random.randn(10) * complex(0,1) # optional - numpy + sage: w = vector(v) # optional - numpy + sage: parent(w) # optional - numpy Vector space of dimension 10 over Complex Double Field Multi-dimensional arrays are not supported:: - sage: import numpy as np - sage: a = np.array([[1, 2, 3], [4, 5, 6]], np.float64) - sage: vector(a) + sage: import numpy as np # optional - numpy + sage: a = np.array([[1, 2, 3], [4, 5, 6]], np.float64) # optional - numpy + sage: vector(a) # optional - numpy Traceback (most recent call last): ... TypeError: cannot convert 2-dimensional array to a vector @@ -391,21 +393,21 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): If the argument is a vector, it doesn't change the base ring. This fixes :trac:`6643`:: - sage: K. = QuadraticField(3) - sage: u = vector(K, (1/2, sqrt3/2) ) - sage: vector(u).base_ring() + sage: K. = QuadraticField(3) # optional - sage.rings.number_field + sage: u = vector(K, (1/2, sqrt3/2)) # optional - sage.rings.number_field + sage: vector(u).base_ring() # optional - sage.rings.number_field Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? - sage: v = vector(K, (0, 1) ) - sage: vector(v).base_ring() + sage: v = vector(K, (0, 1)) # optional - sage.rings.number_field + sage: vector(v).base_ring() # optional - sage.rings.number_field Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? Constructing a vector from a numpy array behaves as expected:: - sage: import numpy - sage: a=numpy.array([1,2,3]) - sage: v=vector(a); v + sage: import numpy # optional - numpy + sage: a = numpy.array([1,2,3]) # optional - numpy + sage: v = vector(a); v # optional - numpy (1, 2, 3) - sage: parent(v) + sage: parent(v) # optional - numpy Ambient free module of rank 3 over the principal ideal domain Integer Ring Complex numbers can be converted naturally to a sequence of length 2. And @@ -451,23 +453,23 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): sage: v = vector(QQ, w, immutable=True) sage: v.is_immutable() True - sage: import numpy as np - sage: w = np.array([1, 2, pi], float) - sage: v = vector(w, immutable=True) - sage: v.is_immutable() + sage: import numpy as np # optional - numpy + sage: w = np.array([1, 2, pi], float) # optional - numpy + sage: v = vector(w, immutable=True) # optional - numpy + sage: v.is_immutable() # optional - numpy True - sage: w = np.array([i, 2, 3], complex) - sage: v = vector(w, immutable=True) - sage: v.is_immutable() + sage: w = np.array([i, 2, 3], complex) # optional - numpy + sage: v = vector(w, immutable=True) # optional - numpy + sage: v.is_immutable() # optional - numpy True TESTS: We check that :trac:`31470` is fixed:: - sage: k. = GF(5^3) - sage: S. = k['x', k.frobenius_endomorphism()] - sage: vector(S, 3) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: S. = k['x', k.frobenius_endomorphism()] # optional - sage.rings.finite_rings + sage: vector(S, 3) # optional - sage.rings.finite_rings ... (0, 0, 0) """ @@ -844,11 +846,11 @@ def random_vector(ring, degree=None, *args, **kwds): Any ring with a ``random_element()`` method may be used. :: - sage: F = FiniteField(23) - sage: hasattr(F, 'random_element') + sage: F = FiniteField(23) # optional - sage.rings.finite_rings + sage: hasattr(F, 'random_element') # optional - sage.rings.finite_rings True - sage: v = random_vector(F, 10) - sage: v.parent() + sage: v = random_vector(F, 10) # optional - sage.rings.finite_rings + sage: v.parent() # optional - sage.rings.finite_rings Vector space of dimension 10 over Finite Field of size 23 The default implementation is a dense representation, equivalent to @@ -870,15 +872,19 @@ def random_vector(ring, degree=None, *args, **kwds): sage: v1 = random_vector(ZZ, 20, distribution="1/n") sage: v2 = random_vector(ZZ, 15, x=-1000, y=1000) sage: v3 = random_vector(QQ, 10) - sage: v4 = random_vector(FiniteField(17), 10) + sage: v4 = random_vector(FiniteField(17), 10) # optional - sage.rings.finite_rings sage: v5 = random_vector(RR, 10) sage: set_random_seed(seed) sage: w1 = vector(ZZ.random_element(distribution="1/n") for _ in range(20)) sage: w2 = vector(ZZ.random_element(x=-1000, y=1000) for _ in range(15)) sage: w3 = vector(QQ.random_element() for _ in range(10)) - sage: w4 = vector(FiniteField(17).random_element() for _ in range(10)) + sage: [v1, v2, v3] == [w1, w2, w3] + True + sage: w4 = vector(FiniteField(17).random_element() for _ in range(10)) # optional - sage.rings.finite_rings + sage: v4 == w4 # optional - sage.rings.finite_rings + True sage: w5 = vector(RR.random_element() for _ in range(10)) - sage: [v1, v2, v3, v4, v5] == [w1, w2, w3, w4, w5] + sage: v5 == w5 True Inputs get checked before constructing the vector. :: @@ -939,20 +945,20 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector(ZZ, 4, range(4)) - sage: giac(v)+v + sage: giac(v) + v # optional - sage.libs.giac [0,2,4,6] :: sage: v = vector(QQ, 3, [2/3, 0, 5/4]) - sage: giac(v) + sage: giac(v) # optional - sage.libs.giac [2/3,0,5/4] :: sage: P. = ZZ[] sage: v = vector(P, 3, [x^2 + 2, 2*x + 1, -2*x^2 + 4*x]) - sage: giac(v) + sage: giac(v) # optional - sage.libs.giac [sageVARx^2+2,2*sageVARx+1,-2*sageVARx^2+4*sageVARx] """ return self.list() @@ -968,15 +974,15 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector(range(4)) - sage: v.__pari__() + sage: v.__pari__() # optional - sage.libs.pari [0, 1, 2, 3] - sage: v.__pari__().type() + sage: v.__pari__().type() # optional - sage.libs.pari 't_VEC' A list of vectors:: sage: L = [vector(i^n for i in range(4)) for n in [1,3,5]] - sage: pari(L) + sage: pari(L) # optional - sage.libs.pari [[0, 1, 2, 3], [0, 1, 8, 27], [0, 1, 32, 243]] """ from sage.libs.pari.all import pari @@ -994,16 +1000,16 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector(range(4)) - sage: v._pari_init_() + sage: v._pari_init_() # optional - sage.libs.pari '[0,1,2,3]' Create the multiplication table of `GF(4)` using GP:: - sage: k. = GF(4, impl="pari_ffelt") - sage: v = gp(vector(list(k))) - sage: v + sage: k. = GF(4, impl="pari_ffelt") # optional - sage.libs.pari + sage: v = gp(vector(list(k))) # optional - sage.libs.pari + sage: v # optional - sage.libs.pari [0, 1, a, a + 1] - sage: v.mattranspose() * v + sage: v.mattranspose() * v # optional - sage.libs.pari [0, 0, 0, 0; 0, 1, a, a + 1; 0, a, a + 1, 1; 0, a + 1, 1, a] """ # Elements in vectors are always Sage Elements, so they should @@ -1019,36 +1025,36 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: F = FreeModule(ZZ, 2, inner_product_matrix=matrix(ZZ, 2, 2, [1, 0, 0, -1])) sage: v = F([1, 2]) - sage: M = magma(v); M # optional - magma + sage: M = magma(v); M # optional - magma (1 2) - sage: M.Type() # optional - magma + sage: M.Type() # optional - magma ModTupRngElt - sage: M.Parent() # optional - magma + sage: M.Parent() # optional - magma Full RSpace of degree 2 over Integer Ring Inner Product Matrix: [ 1 0] [ 0 -1] - sage: M.sage() # optional - magma + sage: M.sage() # optional - magma (1, 2) - sage: M.sage() == v # optional - magma + sage: M.sage() == v # optional - magma True - sage: M.sage().parent() is v.parent() # optional - magma + sage: M.sage().parent() is v.parent() # optional - magma True :: sage: v = vector(QQ, [1, 2, 5/6]) - sage: M = magma(v); M # optional - magma + sage: M = magma(v); M # optional - magma ( 1 2 5/6) - sage: M.Type() # optional - magma + sage: M.Type() # optional - magma ModTupFldElt - sage: M.Parent() # optional - magma + sage: M.Parent() # optional - magma Full Vector space of degree 3 over Rational Field - sage: M.sage() # optional - magma + sage: M.sage() # optional - magma (1, 2, 5/6) - sage: M.sage() == v # optional - magma + sage: M.sage() == v # optional - magma True - sage: M.sage().parent() is v.parent() # optional - magma + sage: M.sage().parent() is v.parent() # optional - magma True """ # Get a reference to Magma version of parent. @@ -1069,48 +1075,48 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector([1,2,3]) - sage: v.numpy() + sage: v.numpy() # optional - numpy array([1, 2, 3], dtype=object) - sage: v.numpy() * v.numpy() + sage: v.numpy() * v.numpy() # optional - numpy array([1, 4, 9], dtype=object) - sage: vector(QQ, [1, 2, 5/6]).numpy() + sage: vector(QQ, [1, 2, 5/6]).numpy() # optional - numpy array([1, 2, 5/6], dtype=object) By default the ``object`` `dtype `_ is used. Alternatively, the desired dtype can be passed in as a parameter:: sage: v = vector(QQ, [1, 2, 5/6]) - sage: v.numpy() + sage: v.numpy() # optional - numpy array([1, 2, 5/6], dtype=object) - sage: v.numpy(dtype=float) + sage: v.numpy(dtype=float) # optional - numpy array([1. , 2. , 0.83333333]) - sage: v.numpy(dtype=int) + sage: v.numpy(dtype=int) # optional - numpy array([1, 2, 0]) - sage: import numpy - sage: v.numpy(dtype=numpy.uint8) + sage: import numpy # optional - numpy + sage: v.numpy(dtype=numpy.uint8) # optional - numpy array([1, 2, 0], dtype=uint8) Passing a dtype of None will let numpy choose a native type, which can be more efficient but may have unintended consequences:: - sage: v.numpy(dtype=None) + sage: v.numpy(dtype=None) # optional - numpy array([1. , 2. , 0.83333333]) sage: w = vector(ZZ, [0, 1, 2^63 -1]); w (0, 1, 9223372036854775807) - sage: wn = w.numpy(dtype=None); wn + sage: wn = w.numpy(dtype=None); wn # optional - numpy array([ 0, 1, 9223372036854775807]...) - sage: wn.dtype + sage: wn.dtype # optional - numpy dtype('int64') - sage: w.dot_product(w) + sage: w.dot_product(w) # optional - numpy 85070591730234615847396907784232501250 - sage: wn.dot(wn) # overflow + sage: wn.dot(wn) # overflow # optional - numpy 2 Numpy can give rather obscure errors; we wrap these to give a bit of context:: - sage: vector([1, 1/2, QQ['x'].0]).numpy(dtype=float) + sage: vector([1, 1/2, QQ['x'].0]).numpy(dtype=float) # optional - numpy Traceback (most recent call last): ... ValueError: Could not convert vector over Univariate Polynomial Ring in x over Rational Field to numpy array of type <... 'float'>: setting an array element with a sequence. @@ -1128,13 +1134,13 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,2/3,pi]) - sage: v.__hash__() + sage: v = vector([1,2/3,pi]) # optional - sage.symbolic + sage: v.__hash__() # optional - sage.symbolic Traceback (most recent call last): ... TypeError: mutable vectors are unhashable - sage: v.set_immutable() - sage: v.__hash__() # random output + sage: v.set_immutable() # optional - sage.symbolic + sage: v.__hash__() # random output # optional - sage.symbolic """ if not self._is_immutable: raise TypeError("mutable vectors are unhashable") @@ -1149,14 +1155,14 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: v = vector(ZZ, [2, 12, 22]) sage: vector(v) (2, 12, 22) - sage: vector(GF(7), v) + sage: vector(GF(7), v) # optional - sage.rings.finite_rings (2, 5, 1) sage: vector(v, ZZ['x', 'y']) (2, 12, 22) sage: vector(vector((1, 6.8))) (1.00000000000000, 6.80000000000000) - sage: vector(vector(SR, (1, sqrt(2)) ) ) + sage: vector(vector(SR, (1, sqrt(2)) ) ) # optional - sage.symbolic (1, sqrt(2)) """ if R is None: @@ -1169,10 +1175,10 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: sage_input(vector(RR, [pi, e, 0.5]), verify=True) + sage: sage_input(vector(RR, [pi, e, 0.5]), verify=True) # optional - sage.symbolic # Verified vector(RR, [3.1415926535897931, 2.7182818284590451, 0.5]) - sage: sage_input(vector(GF(5), [1, 2, 3, 4, 5]), verify=True) + sage: sage_input(vector(GF(5), [1, 2, 3, 4, 5]), verify=True) # optional - sage.rings.finite_rings # Verified vector(GF(5), [1, 2, 3, 4, 0]) sage: sage_input(vector([0, 0, 0, 1, 0, 0, 0], sparse=True), verify=True) @@ -1323,14 +1329,14 @@ cdef class FreeModuleElement(Vector): # abstract base class :: - sage: v = vector(GF(2), [1,2,3]) - sage: v.n() + sage: v = vector(GF(2), [1,2,3]) # optional - sage.rings.finite_rings + sage: v.n() # optional - sage.rings.finite_rings (1.00000000000000, 0.000000000000000, 1.00000000000000) - sage: _.parent() + sage: _.parent() # optional - sage.rings.finite_rings Vector space of dimension 3 over Real Field with 53 bits of precision - sage: v.n(prec=75) + sage: v.n(prec=75) # optional - sage.rings.finite_rings (1.000000000000000000000, 0.0000000000000000000000, 1.000000000000000000000) - sage: _.parent() + sage: _.parent() # optional - sage.rings.finite_rings Vector space of dimension 3 over Real Field with 75 bits of precision TESTS: @@ -1367,8 +1373,8 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: w.parent() Full MatrixSpace of 1 by 3 dense matrices over Integer Ring - sage: x = vector(FiniteField(13), [2,4,8,16]) - sage: x.row() + sage: x = vector(FiniteField(13), [2,4,8,16]) # optional - sage.rings.finite_rings + sage: x.row() # optional - sage.rings.finite_rings [2 4 8 3] There is more than one way to get one-row matrix from a vector, @@ -1376,10 +1382,10 @@ cdef class FreeModuleElement(Vector): # abstract base class then taking a transpose. Notice that supplying a vector to the matrix constructor demonstrates Sage's preference for rows. :: - sage: x = vector(RDF, [sin(i*pi/20) for i in range(10)]) - sage: x.row() == matrix(x) + sage: x = vector(RDF, [sin(i*pi/20) for i in range(10)]) # optional - sage.symbolic + sage: x.row() == matrix(x) # optional - sage.symbolic True - sage: x.row() == x.column().transpose() + sage: x.row() == x.column().transpose() # optional - sage.symbolic True Sparse or dense implementations are preserved. :: @@ -1436,8 +1442,8 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: w.parent() Full MatrixSpace of 3 by 1 dense matrices over Integer Ring - sage: x = vector(FiniteField(13), [2,4,8,16]) - sage: x.column() + sage: x = vector(FiniteField(13), [2,4,8,16]) # optional - sage.rings.finite_rings + sage: x.column() # optional - sage.rings.finite_rings [2] [4] [8] @@ -1457,7 +1463,7 @@ cdef class FreeModuleElement(Vector): # abstract base class Sparse or dense implementations are preserved. :: sage: d = vector(RR, [1.0, 2.0, 3.0]) - sage: s = vector(CDF, {2:5.0+6.0*I}) + sage: s = vector(CDF, {2: 5.0+6.0*I}) sage: dm = d.column() sage: sm = s.column() sage: all([d.is_dense(), dm.is_dense(), s.is_sparse(), sm.is_sparse()]) @@ -1518,12 +1524,12 @@ cdef class FreeModuleElement(Vector): # abstract base class """ EXAMPLES:: - sage: var('a,b,d,e') + sage: var('a,b,d,e') # optional - sage.symbolic (a, b, d, e) - sage: v = vector([a, b, d, e]) - sage: v.substitute(a=1) + sage: v = vector([a, b, d, e]) # optional - sage.symbolic + sage: v.substitute(a=1) # optional - sage.symbolic (1, b, d, e) - sage: v.subs(a=b, b=d) + sage: v.subs(a=b, b=d) # optional - sage.symbolic (b, d, d, e) """ return self.parent()([ a.subs(in_dict, **kwds) for a in self.list() ]) @@ -1534,7 +1540,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector(QQ['x,y'], [1..5]); v.change_ring(GF(3)) + sage: v = vector(QQ['x,y'], [1..5]); v.change_ring(GF(3)) # optional - sage.rings.finite_rings (1, 2, 0, 1, 2) TESTS: @@ -1542,7 +1548,7 @@ cdef class FreeModuleElement(Vector): # abstract base class Check for :trac:`29630`:: sage: v = vector(QQ, 4, {0:1}, sparse=True) - sage: v.change_ring(AA).is_sparse() + sage: v.change_ring(AA).is_sparse() # optional - sage.rings.number_field True """ if self.base_ring() is R: @@ -1611,17 +1617,17 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,2/3,pi]) - sage: v.items() + sage: v = vector([1,2/3,pi]) # optional - sage.symbolic + sage: v.items() # optional - sage.symbolic - sage: list(v.items()) + sage: list(v.items()) # optional - sage.symbolic [(0, 1), (1, 2/3), (2, pi)] TESTS: Using iteritems as an alias:: - sage: list(v.iteritems()) + sage: list(v.iteritems()) # optional - sage.symbolic [(0, 1), (1, 2/3), (2, pi)] """ cdef dict d = self.dict(copy=False) @@ -1636,7 +1642,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1..5]); abs(v) + sage: v = vector([1..5]); abs(v) # optional - sage.symbolic sqrt(55) sage: v = vector(RDF, [1..5]); abs(v) 7.416198487095663 @@ -1663,14 +1669,14 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector([1,2,-3]) - sage: v.norm(5) + sage: v.norm(5) # optional - sage.symbolic 276^(1/5) The default is the usual Euclidean norm. :: - sage: v.norm() + sage: v.norm() # optional - sage.symbolic sqrt(14) - sage: v.norm(2) + sage: v.norm(2) # optional - sage.symbolic sqrt(14) The infinity norm is the maximum size (in absolute value) @@ -1686,10 +1692,10 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: v=vector(RDF,[1,2,3]) sage: v.norm(5) 3.077384885394063 - sage: v.norm(pi/2) #abs tol 1e-15 + sage: v.norm(pi/2) #abs tol 1e-15 # optional - sage.symbolic 4.216595864704748 - sage: _=var('a b c d p'); v=vector([a, b, c, d]) - sage: v.norm(p) + sage: _=var('a b c d p'); v=vector([a, b, c, d]) # optional - sage.symbolic + sage: v.norm(p) # optional - sage.symbolic (abs(a)^p + abs(b)^p + abs(c)^p + abs(d)^p)^(1/p) Notice that the result may be a symbolic expression, owing to @@ -1703,13 +1709,13 @@ cdef class FreeModuleElement(Vector): # abstract base class Rational Field sage: v = vector(QQ, [3, 5]) - sage: nrm = v.norm(); nrm + sage: nrm = v.norm(); nrm # optional - sage.symbolic sqrt(34) - sage: nrm.parent() + sage: nrm.parent() # optional - sage.symbolic Symbolic Ring - sage: numeric = N(nrm); numeric + sage: numeric = N(nrm); numeric # optional - sage.symbolic 5.83095189484... - sage: numeric.parent() + sage: numeric.parent() # optional - sage.symbolic Real Field with 53 bits of precision TESTS: @@ -1726,7 +1732,7 @@ cdef class FreeModuleElement(Vector): # abstract base class Norm works with Python integers (see :trac:`13502`). :: sage: v = vector(QQ, [1,2]) - sage: v.norm(int(2)) + sage: v.norm(int(2)) # optional - sage.symbolic sqrt(5) """ abs_self = [abs(x) for x in self] @@ -1742,17 +1748,17 @@ cdef class FreeModuleElement(Vector): # abstract base class """ EXAMPLES:: - sage: v = vector(SR, [0,0,0,0]) - sage: v == 0 + sage: v = vector(SR, [0,0,0,0]) # optional - sage.symbolic + sage: v == 0 # optional - sage.symbolic True - sage: v == 1 + sage: v == 1 # optional - sage.symbolic False - sage: v == v + sage: v == v # optional - sage.symbolic True - sage: w = vector(SR, [-1,x,pi,0]) - sage: bool(w < v) + sage: w = vector(SR, [-1,x,pi,0]) # optional - sage.symbolic + sage: bool(w < v) # optional - sage.symbolic True - sage: bool(w > v) + sage: bool(w > v) # optional - sage.symbolic False TESTS:: @@ -1767,14 +1773,14 @@ cdef class FreeModuleElement(Vector): # abstract base class Verify that :trac:`33697` is fixed:: - sage: v = vector(SR, [x]) - sage: w = vector(SR, [1]) - sage: v == w + sage: v = vector(SR, [x]) # optional - sage.symbolic + sage: w = vector(SR, [1]) # optional - sage.symbolic + sage: v == w # optional - sage.symbolic False - sage: assume(x > 0) - sage: v == w + sage: assume(x > 0) # optional - sage.symbolic + sage: v == w # optional - sage.symbolic False - sage: forget() + sage: forget() # optional - sage.symbolic """ cdef Py_ssize_t i for i in range(left._degree): @@ -1831,7 +1837,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: vector(SR, [1/2,2/5,0]).get(0) + sage: vector(SR, [1/2,2/5,0]).get(0) # optional - sage.symbolic 1/2 """ return self.get_unsafe(i) @@ -1894,9 +1900,9 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector(SR, [1/2,2/5,0]); v + sage: v = vector(SR, [1/2,2/5,0]); v # optional - sage.symbolic (1/2, 2/5, 0) - sage: v.set(2, pi); v + sage: v.set(2, pi); v # optional - sage.symbolic (1/2, 2/5, pi) """ assert value.parent() is self.coordinate_ring() @@ -1909,7 +1915,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: vector([1,2/3,pi]).__invert__() + sage: vector([1,2/3,pi]).__invert__() # optional - sage.symbolic Traceback (most recent call last): ... NotImplementedError @@ -1991,8 +1997,8 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,2/3,pi]) - sage: v.list_from_positions([0,0,0,2,1]) + sage: v = vector([1, 2/3, pi]) # optional - sage.symbolic + sage: v.list_from_positions([0,0,0,2,1]) # optional - sage.symbolic [1, 1, 1, pi, 2/3] """ cdef Py_ssize_t i @@ -2106,10 +2112,10 @@ cdef class FreeModuleElement(Vector): # abstract base class :: - sage: x = var('x') - sage: v = vector([x/(2*x)+sqrt(2)+var('theta')^3,x/(2*x)]); v + sage: x = var('x') # optional - sage.symbolic + sage: v = vector([x/(2*x)+sqrt(2)+var('theta')^3,x/(2*x)]); v # optional - sage.symbolic (theta^3 + sqrt(2) + 1/2, 1/2) - sage: v._repr_() + sage: v._repr_() # optional - sage.symbolic '(theta^3 + sqrt(2) + 1/2, 1/2)' """ cdef Py_ssize_t d = self._degree @@ -2191,9 +2197,9 @@ cdef class FreeModuleElement(Vector): # abstract base class The following was fixed in :trac:`8800`:: - sage: M = GF(5)^3 - sage: v = M((4,0,2)) - sage: v.denominator() + sage: M = GF(5)^3 # optional - sage.rings.finite_rings + sage: v = M((4,0,2)) # optional - sage.rings.finite_rings + sage: v.denominator() # optional - sage.rings.finite_rings 1 """ # It may be that the coordinates do not have a denominator @@ -2283,84 +2289,84 @@ cdef class FreeModuleElement(Vector): # abstract base class The following both plot the given vector:: sage: v = vector(RDF, (1,2)) - sage: A = plot(v) - sage: B = v.plot() - sage: A+B # should just show one vector + sage: A = plot(v) # optional - sage.plot + sage: B = v.plot() # optional - sage.plot + sage: A+B # should just show one vector # optional - sage.plot Graphics object consisting of 2 graphics primitives Examples of the plot types:: - sage: A = plot(v, plot_type='arrow') - sage: B = plot(v, plot_type='point', color='green', size=20) - sage: C = plot(v, plot_type='step') # calls v.plot_step() - sage: A+B+C + sage: A = plot(v, plot_type='arrow') # optional - sage.plot + sage: B = plot(v, plot_type='point', color='green', size=20) # optional - sage.plot + sage: C = plot(v, plot_type='step') # calls v.plot_step() # optional - sage.plot + sage: A+B+C # optional - sage.plot Graphics object consisting of 3 graphics primitives You can use the optional arguments for :meth:`plot_step`:: - sage: eps = 0.1 - sage: plot(v, plot_type='step', eps=eps, xmax=5, hue=0) + sage: eps = 0.1 # optional - sage.plot + sage: plot(v, plot_type='step', eps=eps, xmax=5, hue=0) # optional - sage.plot Graphics object consisting of 1 graphics primitive Three-dimensional examples:: sage: v = vector(RDF, (1,2,1)) - sage: plot(v) # defaults to an arrow plot + sage: plot(v) # defaults to an arrow plot # optional - sage.plot Graphics3d Object :: - sage: plot(v, plot_type='arrow') + sage: plot(v, plot_type='arrow') # optional - sage.plot Graphics3d Object :: - sage: from sage.plot.plot3d.shapes2 import frame3d - sage: plot(v, plot_type='point')+frame3d((0,0,0), v.list()) + sage: from sage.plot.plot3d.shapes2 import frame3d # optional - sage.plot + sage: plot(v, plot_type='point')+frame3d((0,0,0), v.list()) # optional - sage.plot Graphics3d Object :: - sage: plot(v, plot_type='step') # calls v.plot_step() + sage: plot(v, plot_type='step') # calls v.plot_step() # optional - sage.plot Graphics object consisting of 1 graphics primitive :: - sage: plot(v, plot_type='step', eps=eps, xmax=5, hue=0) + sage: plot(v, plot_type='step', eps=eps, xmax=5, hue=0) # optional - sage.plot Graphics object consisting of 1 graphics primitive With greater than three coordinates, it defaults to a step plot:: sage: v = vector(RDF, (1,2,3,4)) - sage: plot(v) + sage: plot(v) # optional - sage.plot Graphics object consisting of 1 graphics primitive One dimensional vectors are plotted along the horizontal axis of the coordinate plane:: - sage: plot(vector([1])) + sage: plot(vector([1])) # optional - sage.plot Graphics object consisting of 1 graphics primitive An optional start argument may also be specified by a tuple, list, or vector:: sage: u = vector([1,2]); v = vector([2,5]) - sage: plot(u, start=v) + sage: plot(u, start=v) # optional - sage.plot Graphics object consisting of 1 graphics primitive TESTS:: - sage: u = vector([1,1]); v = vector([2,2,2]); z=(3,3,3) - sage: plot(u) #test when start=None + sage: u = vector([1,1]); v = vector([2,2,2]); z=(3,3,3) # optional - sage.plot + sage: plot(u) #test when start=None # optional - sage.plot Graphics object consisting of 1 graphics primitive :: - sage: plot(u, start=v) #test when coordinate dimension mismatch exists + sage: plot(u, start=v) #test when coordinate dimension mismatch exists # optional - sage.plot Traceback (most recent call last): ... ValueError: vector coordinates are not of the same dimension - sage: P = plot(v, start=z) #test when start coordinates are passed as a tuple - sage: P = plot(v, start=list(z)) #test when start coordinates are passed as a list + sage: P = plot(v, start=z) # test when start coordinates are passed as a tuple # optional - sage.plot + sage: P = plot(v, start=list(z)) # test when start coordinates are passed as a list # optional - sage.plot """ # Give sensible defaults based on the vector length if plot_type is None: @@ -2431,9 +2437,9 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: eps=0.1 - sage: v = vector(RDF, [sin(n*eps) for n in range(100)]) - sage: v.plot_step(eps=eps, xmax=5, hue=0) + sage: eps = 0.1 + sage: v = vector(RDF, [sin(n*eps) for n in range(100)]) # optional - sage.plot + sage: v.plot_step(eps=eps, xmax=5, hue=0) # optional - sage.plot Graphics object consisting of 1 graphics primitive """ import math @@ -2545,21 +2551,21 @@ cdef class FreeModuleElement(Vector): # abstract base class arguments is reversed.:: sage: v = vector(ZZ, [1,2,3]) - sage: w = vector(FiniteField(3), [0,1,2]) - sage: ip = w.dot_product(v); ip + sage: w = vector(FiniteField(3), [0,1,2]) # optional - sage.rings.finite_rings + sage: ip = w.dot_product(v); ip # optional - sage.rings.finite_rings 2 - sage: ip.parent() + sage: ip.parent() # optional - sage.rings.finite_rings Finite Field of size 3 - sage: ip = v.dot_product(w); ip + sage: ip = v.dot_product(w); ip # optional - sage.rings.finite_rings 2 - sage: ip.parent() + sage: ip.parent() # optional - sage.rings.finite_rings Finite Field of size 3 The dot product of a vector with itself is the 2-norm, squared. :: sage: v = vector(QQ, [3, 4, 7]) - sage: v.dot_product(v) - v.norm()^2 + sage: v.dot_product(v) - v.norm()^2 # optional - sage.symbolic 0 TESTS: @@ -2755,26 +2761,26 @@ cdef class FreeModuleElement(Vector): # abstract base class TESTS:: - sage: F = GF(previous_prime(2^32)) - sage: v = random_vector(F, 3) - sage: w = random_vector(F, 3) - sage: vh = v.cross_product_matrix() - sage: vh*w == v.cross_product(w) + sage: F = GF(previous_prime(2^32)) # optional - sage.rings.finite_rings + sage: v = random_vector(F, 3) # optional - sage.rings.finite_rings + sage: w = random_vector(F, 3) # optional - sage.rings.finite_rings + sage: vh = v.cross_product_matrix() # optional - sage.rings.finite_rings + sage: vh*w == v.cross_product(w) # optional - sage.rings.finite_rings True - sage: w*vh == w.cross_product(v) + sage: w*vh == w.cross_product(v) # optional - sage.rings.finite_rings True - sage: vh.is_alternating() + sage: vh.is_alternating() # optional - sage.rings.finite_rings True - sage: v = random_vector(F, 7) - sage: w = random_vector(F, 7) - sage: vh = v.cross_product_matrix() - sage: vh*w == v.cross_product(w) + sage: v = random_vector(F, 7) # optional - sage.rings.finite_rings + sage: w = random_vector(F, 7) # optional - sage.rings.finite_rings + sage: vh = v.cross_product_matrix() # optional - sage.rings.finite_rings + sage: vh*w == v.cross_product(w) # optional - sage.rings.finite_rings True - sage: w*vh == w.cross_product(v) + sage: w*vh == w.cross_product(v) # optional - sage.rings.finite_rings True - sage: vh.is_alternating() + sage: vh.is_alternating() # optional - sage.rings.finite_rings True - sage: random_vector(F, 5).cross_product_matrix() + sage: random_vector(F, 5).cross_product_matrix() # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: Cross product only defined for vectors of length three or seven, not 5 @@ -2829,11 +2835,11 @@ cdef class FreeModuleElement(Vector): # abstract base class :: - sage: W = VectorSpace(GF(3),3) - sage: w = W([0,1,2]) - sage: w.pairwise_product(v) + sage: W = VectorSpace(GF(3), 3) # optional - sage.rings.finite_rings + sage: w = W([0,1,2]) # optional - sage.rings.finite_rings + sage: w.pairwise_product(v) # optional - sage.rings.finite_rings (0, 2, 0) - sage: w.pairwise_product(v).parent() + sage: w.pairwise_product(v).parent() # optional - sage.rings.finite_rings Vector space of dimension 3 over Finite Field of size 3 Implicit coercion is well defined (regardless of order), so we @@ -2841,13 +2847,11 @@ cdef class FreeModuleElement(Vector): # abstract base class :: - sage: v.pairwise_product(w).parent() + sage: v.pairwise_product(w).parent() # optional - sage.rings.finite_rings Vector space of dimension 3 over Finite Field of size 3 TESTS:: - sage: x, y = var('x, y') - :: sage: parent(vector(ZZ,[1,2]).pairwise_product(vector(ZZ,[1,2]))) @@ -2927,12 +2931,12 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: R. = QQ[] sage: vector([x, y, 3])._variables() [x, y, z] - sage: vector(SR, [x, y, 3])._variables() + sage: vector(SR, [x, y, 3])._variables() # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Unable to determine ordered variable names for Symbolic Ring - sage: v(x, y, z) = (-y, x, 0) - sage: v._variables() + sage: v(x, y, z) = (-y, x, 0) # optional - sage.symbolic + sage: v._variables() # optional - sage.symbolic [(x, y, z) |--> x, (x, y, z) |--> y, (x, y, z) |--> z] """ R = self._parent.base_ring() @@ -2965,11 +2969,11 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: vector([x*y, y*z, z*x]).div([x, y, w]) y + z - sage: vector(SR, [x*y, y*z, z*x]).div() + sage: vector(SR, [x*y, y*z, z*x]).div() # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Unable to determine ordered variable names for Symbolic Ring - sage: vector(SR, [x*y, y*z, z*x]).div([x, y, z]) + sage: vector(SR, [x*y, y*z, z*x]).div([x, y, z]) # optional - sage.symbolic x + y + z .. SEEALSO:: @@ -3006,18 +3010,18 @@ cdef class FreeModuleElement(Vector): # abstract base class For rings where the variable order is not well defined, it must be defined explicitly:: - sage: v = vector(SR, [-y, x, 0]) - sage: v.curl() + sage: v = vector(SR, [-y, x, 0]) # optional - sage.symbolic + sage: v.curl() # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Unable to determine ordered variable names for Symbolic Ring - sage: v.curl([x, y, z]) + sage: v.curl([x, y, z]) # optional - sage.symbolic (0, 0, 2) Note that callable vectors have well defined variable orderings:: - sage: v(x, y, z) = (-y, x, 0) - sage: v.curl() + sage: v(x, y, z) = (-y, x, 0) # optional - sage.symbolic + sage: v.curl() # optional - sage.symbolic (x, y, z) |--> (0, 0, 2) In two-dimensions, this returns a scalar value:: @@ -3102,14 +3106,14 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector(QQ, [4, 1, 3, 2]) - sage: v.normalized() + sage: v.normalized() # optional - sage.symbolic (2/15*sqrt(30), 1/30*sqrt(30), 1/10*sqrt(30), 1/15*sqrt(30)) sage: sum(v.normalized(1)) 1 Note that normalizing the vector may change the base ring:: - sage: v.base_ring() == v.normalized().base_ring() + sage: v.base_ring() == v.normalized().base_ring() # optional - sage.symbolic False sage: u = vector(RDF, [-3, 4, 6, 9]) sage: u.base_ring() == u.normalized().base_ring() @@ -3147,11 +3151,11 @@ cdef class FreeModuleElement(Vector): # abstract base class such as the cyclotomic fields. This example uses such a field containing a primitive 7-th root of unity named ``a``. :: - sage: F. = CyclotomicField(7) - sage: v = vector(F, [a^i for i in range(7)]) - sage: v + sage: F. = CyclotomicField(7) # optional - sage.rings.number_field + sage: v = vector(F, [a^i for i in range(7)]) # optional - sage.rings.number_field + sage: v # optional - sage.rings.number_field (1, a, a^2, a^3, a^4, a^5, -a^5 - a^4 - a^3 - a^2 - a - 1) - sage: v.conjugate() + sage: v.conjugate() # optional - sage.rings.number_field (1, -a^5 - a^4 - a^3 - a^2 - a - 1, a^5, a^4, a^3, a^2, a) Sparse vectors are returned as such. :: @@ -3402,9 +3406,9 @@ cdef class FreeModuleElement(Vector): # abstract base class But some inputs are not compatible, even if vectors. :: - sage: w = vector(GF(5), [1,2]) - sage: v = vector(GF(7), [1,2,3,4]) - sage: z = w.outer_product(v) + sage: w = vector(GF(5), [1,2]) # optional - sage.rings.finite_rings + sage: v = vector(GF(7), [1,2,3,4]) # optional - sage.rings.finite_rings + sage: z = w.outer_product(v) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 1 dense matrices over Finite Field of size 5' and 'Full MatrixSpace of 1 by 4 dense matrices over Finite Field of size 7' @@ -3579,7 +3583,7 @@ cdef class FreeModuleElement(Vector): # abstract base class :: sage: R. = QQ[] - sage: macaulay2(vector(R, [1, x+y])) # optional - macaulay2 + sage: macaulay2(vector(R, [1, x + y])) # optional - macaulay2 | 1 | | x+y | @@ -3628,16 +3632,16 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: v = vector([1, 2, 3]); v (1, 2, 3) - sage: sv = v._sympy_(); sv + sage: sv = v._sympy_(); sv # optional - sympy Matrix([ [1], [2], [3]]) - sage: type(sv) + sage: type(sv) # optional - sympy sage: w = vector({1: 1, 5: -1}, sparse=True) - sage: sw = w._sympy_(); sw + sage: sw = w._sympy_(); sw # optional - sympy Matrix([ [ 0], [ 1], @@ -3645,26 +3649,26 @@ cdef class FreeModuleElement(Vector): # abstract base class [ 0], [ 0], [-1]]) - sage: type(sw) + sage: type(sw) # optional - sympy If ``self`` was immutable, then converting the result to Sage gives back ``self``:: sage: immv = vector([1, 2, 3], immutable=True) - sage: immv._sympy_()._sage_() is immv + sage: immv._sympy_()._sage_() is immv # optional - sympy True If ``self`` was mutable, then converting back to Sage creates a new matrix (column vector):: - sage: sv._sage_() + sage: sv._sage_() # optional - sympy [1] [2] [3] - sage: sv._sage_() is v + sage: sv._sage_() is v # optional - sympy False - sage: sv._sage_() == v + sage: sv._sage_() == v # optional - sympy False """ from sage.interfaces.sympy import sympy_init @@ -3817,28 +3821,28 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: m = vector([1,x,sin(x+1)]) - sage: m.apply_map(lambda x: x^2) + sage: m = vector([1,x,sin(x+1)]) # optional - sage.symbolic + sage: m.apply_map(lambda x: x^2) # optional - sage.symbolic (1, x^2, sin(x + 1)^2) - sage: m.apply_map(sin) + sage: m.apply_map(sin) # optional - sage.symbolic (sin(1), sin(x), sin(sin(x + 1))) :: sage: m = vector(ZZ, 9, range(9)) - sage: k. = GF(9) - sage: m.apply_map(k) + sage: k. = GF(9) # optional - sage.rings.finite_rings + sage: m.apply_map(k) # optional - sage.rings.finite_rings (0, 1, 2, 0, 1, 2, 0, 1, 2) In this example, we explicitly specify the codomain. :: - sage: s = GF(3) - sage: f = lambda x: s(x) - sage: n = m.apply_map(f, k); n + sage: s = GF(3) # optional - sage.rings.finite_rings + sage: f = lambda x: s(x) # optional - sage.rings.finite_rings + sage: n = m.apply_map(f, k); n # optional - sage.rings.finite_rings (0, 1, 2, 0, 1, 2, 0, 1, 2) - sage: n.parent() + sage: n.parent() # optional - sage.rings.finite_rings Vector space of dimension 9 over Finite Field in a of size 3^2 If your map sends 0 to a non-zero value, then your resulting @@ -3873,7 +3877,7 @@ cdef class FreeModuleElement(Vector): # abstract base class TESTS:: - sage: m = vector(SR,[]) + sage: m = vector(SR,[]) # optional - sage.symbolic sage: m.apply_map(lambda x: x*x) == m True @@ -3894,10 +3898,10 @@ cdef class FreeModuleElement(Vector): # abstract base class Check that the bug in :trac:`14558` has been fixed:: - sage: F. = GF(9) - sage: v = vector([a, 0,0,0], sparse=True) - sage: f = F.hom([a**3]) - sage: v.apply_map(f) + sage: F. = GF(9) # optional - sage.rings.finite_rings + sage: v = vector([a, 0, 0, 0], sparse=True) # optional - sage.rings.finite_rings + sage: f = F.hom([a**3]) # optional - sage.rings.finite_rings + sage: v.apply_map(f) # optional - sage.rings.finite_rings (2*a + 1, 0, 0, 0) """ if sparse is None: @@ -3951,31 +3955,31 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,x,x^2]) - sage: v._derivative(x) + sage: v = vector([1,x,x^2]) # optional - sage.symbolic + sage: v._derivative(x) # optional - sage.symbolic (0, 1, 2*x) - sage: type(v._derivative(x)) == type(v) + sage: type(v._derivative(x)) == type(v) # optional - sage.symbolic True - sage: v = vector([1,x,x^2], sparse=True) - sage: v._derivative(x) + sage: v = vector([1,x,x^2], sparse=True) # optional - sage.symbolic + sage: v._derivative(x) # optional - sage.symbolic (0, 1, 2*x) - sage: type(v._derivative(x)) == type(v) + sage: type(v._derivative(x)) == type(v) # optional - sage.symbolic True If no variables are specified and the vector contains callable symbolic expressions, then calculate the matrix derivative (i.e., the Jacobian matrix):: - sage: T(r,theta)=[r*cos(theta),r*sin(theta)] - sage: T + sage: T(r,theta) = [r*cos(theta), r*sin(theta)] # optional - sage.symbolic + sage: T # optional - sage.symbolic (r, theta) |--> (r*cos(theta), r*sin(theta)) - sage: T.diff() # matrix derivative + sage: T.diff() # matrix derivative # optional - sage.symbolic [ (r, theta) |--> cos(theta) (r, theta) |--> -r*sin(theta)] [ (r, theta) |--> sin(theta) (r, theta) |--> r*cos(theta)] - sage: diff(T) # matrix derivative again + sage: diff(T) # matrix derivative again # optional - sage.symbolic [ (r, theta) |--> cos(theta) (r, theta) |--> -r*sin(theta)] [ (r, theta) |--> sin(theta) (r, theta) |--> r*cos(theta)] - sage: T.diff().det() # Jacobian + sage: T.diff().det() # Jacobian # optional - sage.symbolic (r, theta) |--> r*cos(theta)^2 + r*sin(theta)^2 """ if var is None: @@ -3999,17 +4003,17 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,x,x^2]) - sage: v.derivative(x) + sage: v = vector([1,x,x^2]) # optional - sage.symbolic + sage: v.derivative(x) # optional - sage.symbolic (0, 1, 2*x) - sage: type(v.derivative(x)) == type(v) + sage: type(v.derivative(x)) == type(v) # optional - sage.symbolic True - sage: v = vector([1,x,x^2], sparse=True) - sage: v.derivative(x) + sage: v = vector([1,x,x^2], sparse=True) # optional - sage.symbolic + sage: v.derivative(x) # optional - sage.symbolic (0, 1, 2*x) - sage: type(v.derivative(x)) == type(v) + sage: type(v.derivative(x)) == type(v) # optional - sage.symbolic True - sage: v.derivative(x,x) + sage: v.derivative(x,x) # optional - sage.symbolic (0, 0, 2) """ from sage.misc.derivative import multi_derivative @@ -4025,13 +4029,13 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: t=var('t') - sage: r=vector([t,t^2,sin(t)]) - sage: r.integral(t) + sage: t = var('t') # optional - sage.symbolic + sage: r = vector([t,t^2,sin(t)]) # optional - sage.symbolic + sage: r.integral(t) # optional - sage.symbolic (1/2*t^2, 1/3*t^3, -cos(t)) - sage: integrate(r,t) + sage: integrate(r, t) # optional - sage.symbolic (1/2*t^2, 1/3*t^3, -cos(t)) - sage: r.integrate(t,0,1) + sage: r.integrate(t, 0, 1) # optional - sage.symbolic (1/2, 1/3, -cos(1) + 1) """ @@ -4051,19 +4055,23 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: t=var('t') - sage: r=vector([t,t^2,sin(t)]) - sage: vec,answers=r.nintegral(t,0,1) - sage: vec + sage: t = var('t') # optional - sage.symbolic + sage: r = vector([t,t^2,sin(t)]) # optional - sage.symbolic + sage: vec, answers = r.nintegral(t,0,1) # optional - sage.symbolic + sage: vec # optional - sage.symbolic (0.5, 0.3333333333333334, 0.4596976941318602) - sage: type(vec) + sage: type(vec) # optional - sage.symbolic - sage: answers - [(0.5, 5.55111512312578...e-15, 21, 0), (0.3333333333333..., 3.70074341541719...e-15, 21, 0), (0.45969769413186..., 5.10366964392284...e-15, 21, 0)] + sage: answers # optional - sage.symbolic + [(0.5, 5.55111512312578...e-15, 21, 0), + (0.3333333333333..., 3.70074341541719...e-15, 21, 0), + (0.45969769413186..., 5.10366964392284...e-15, 21, 0)] - sage: r=vector([t,0,1], sparse=True) - sage: r.nintegral(t,0,1) - ((0.5, 0.0, 1.0), {0: (0.5, 5.55111512312578...e-15, 21, 0), 2: (1.0, 1.11022302462515...e-14, 21, 0)}) + sage: r = vector([t,0,1], sparse=True) # optional - sage.symbolic + sage: r.nintegral(t, 0, 1) # optional - sage.symbolic + ((0.5, 0.0, 1.0), + {0: (0.5, 5.55111512312578...e-15, 21, 0), + 2: (1.0, 1.11022302462515...e-14, 21, 0)}) """ # If Cython supported lambda functions, we would just do @@ -4151,15 +4159,15 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): :: - sage: v = vector([1,2/3,pi]) - sage: v == v + sage: v = vector([1,2/3,pi]) # optional - sage.symbolic + sage: v == v # optional - sage.symbolic True :: - sage: v = vector(RR, [1,2/3,pi]) - sage: v.set_immutable() - sage: isinstance(hash(v), int) + sage: v = vector(RR, [1,2/3,pi]) # optional - sage.symbolic + sage: v.set_immutable() # optional - sage.symbolic + sage: isinstance(hash(v), int) # optional - sage.symbolic True """ cdef _new_c(self, object v): @@ -4192,19 +4200,19 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): EXAMPLES:: - sage: v = vector([-1,0,3,pi]) - sage: type(v) + sage: v = vector([-1,0,3,pi]) # optional - sage.symbolic + sage: type(v) # optional - sage.symbolic - sage: v.__copy__() + sage: v.__copy__() # optional - sage.symbolic (-1, 0, 3, pi) - sage: v.__copy__() is v + sage: v.__copy__() is v # optional - sage.symbolic False - sage: copy(v) + sage: copy(v) # optional - sage.symbolic (-1, 0, 3, pi) - sage: copy(v) == v + sage: copy(v) == v # optional - sage.symbolic True - sage: copy(v) is v + sage: copy(v) is v # optional - sage.symbolic False """ return self._new_c(list(self._entries)) @@ -4219,11 +4227,11 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): We can initialize with lists, tuples and derived types:: sage: from sage.modules.free_module_element import FreeModuleElement_generic_dense - sage: FreeModuleElement_generic_dense(RR^5, [-1,0,2/3,pi,oo]) + sage: FreeModuleElement_generic_dense(RR^5, [-1,0,2/3,pi,oo]) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_dense(RR^5, (-1,0,2/3,pi,oo)) + sage: FreeModuleElement_generic_dense(RR^5, (-1,0,2/3,pi,oo)) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_dense(RR^5, Sequence([-1,0,2/3,pi,oo])) + sage: FreeModuleElement_generic_dense(RR^5, Sequence([-1,0,2/3,pi,oo])) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) sage: FreeModuleElement_generic_dense(RR^0, 0) () @@ -4232,26 +4240,26 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): Disabling coercion can lead to illegal objects:: - sage: FreeModuleElement_generic_dense(RR^5, [-1,0,2/3,pi,oo], coerce=False) + sage: FreeModuleElement_generic_dense(RR^5, [-1,0,2/3,pi,oo], coerce=False) # optional - sage.symbolic (-1, 0, 2/3, pi, +Infinity) We test the ``copy`` flag:: sage: from sage.modules.free_module_element import FreeModuleElement_generic_dense - sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] - sage: FreeModuleElement_generic_dense(RR^5, tuple(L), coerce=False, copy=False) + sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] # optional - sage.symbolic + sage: FreeModuleElement_generic_dense(RR^5, tuple(L), coerce=False, copy=False) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=False) - sage: L[4] = 42.0 - sage: v # last entry changed since we didn't copy + sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=False) # optional - sage.symbolic + sage: L[4] = 42.0 # optional - sage.symbolic + sage: v # last entry changed since we didn't copy # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, 42.0000000000000) :: - sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] - sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=True) - sage: L[4] = 42.0 - sage: v # last entry did not change + sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] # optional - sage.symbolic + sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=True) # optional - sage.symbolic + sage: L[4] = 42.0 # optional - sage.symbolic + sage: v # last entry did not change # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) Check that :trac:`11751` is fixed:: @@ -4309,8 +4317,8 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): EXAMPLES:: - sage: v = vector([1,2/3,pi]); w = vector([-2/3,pi^2,1]) - sage: v._add_(w) + sage: v = vector([1,2/3,pi]); w = vector([-2/3,pi^2,1]) # optional - sage.symbolic + sage: v._add_(w) # optional - sage.symbolic (1/3, pi^2 + 2/3, pi + 1) """ cdef list a = left._entries @@ -4356,10 +4364,10 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([-1,0,3,pi]) - sage: v._lmul_(2/3) + sage: v = vector([-1,0,3,pi]) # optional - sage.symbolic + sage: v._lmul_(2/3) # optional - sage.symbolic (-2/3, 0, 2, 2/3*pi) - sage: v * (2/3) + sage: v * (2/3) # optional - sage.symbolic (-2/3, 0, 2, 2/3*pi) """ if right._parent is self._parent._base: @@ -4392,9 +4400,10 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([-1,0,3,pi]) - sage: v.__reduce__() - (, (Vector space of dimension 4 over Symbolic Ring, [-1, 0, 3, pi], 4, True)) + sage: v = vector([-1,0,3,pi]) # optional - sage.symbolic + sage: v.__reduce__() # optional - sage.symbolic + (, + (Vector space of dimension 4 over Symbolic Ring, [-1, 0, 3, pi], 4, True)) """ return (make_FreeModuleElement_generic_dense_v1, (self._parent, self._entries, self._degree, not self._is_immutable)) @@ -4405,8 +4414,8 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): """ EXAMPLES:: - sage: v = vector(RR, [-1,0,2/3,pi]) - sage: v.get(3) + sage: v = vector(RR, [-1,0,2/3,pi]) # optional - sage.symbolic + sage: v.get(3) # optional - sage.symbolic 3.14159265358979 :: @@ -4485,20 +4494,20 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): EXAMPLES:: - sage: x, y = var('x,y') - sage: f = x^2 + y^2 - sage: g = f.gradient() - sage: g + sage: x, y = var('x,y') # optional - sage.symbolic + sage: f = x^2 + y^2 # optional - sage.symbolic + sage: g = f.gradient() # optional - sage.symbolic + sage: g # optional - sage.symbolic (2*x, 2*y) - sage: type(g) + sage: type(g) # optional - sage.symbolic - sage: g(y=2, x=3) + sage: g(y=2, x=3) # optional - sage.symbolic (6, 4) - sage: f(x,y) = x^2 + y^2 - sage: g = f.gradient() - sage: g(3,2) + sage: f(x,y) = x^2 + y^2 # optional - sage.symbolic + sage: g = f.gradient() # optional - sage.symbolic + sage: g(3,2) # optional - sage.symbolic (6, 4) - sage: g(x=3, y=2) + sage: g(x=3, y=2) # optional - sage.symbolic (6, 4) """ return vector([e(*args, **kwargs) for e in self]) @@ -4509,28 +4518,28 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): EXAMPLES:: - sage: x,y=var('x,y') - sage: v=vector([x,y,x*sin(y)]) - sage: w=v.function([x,y]); w + sage: x, y = var('x,y') # optional - sage.symbolic + sage: v = vector([x, y, x*sin(y)]) # optional - sage.symbolic + sage: w = v.function([x,y]); w # optional - sage.symbolic (x, y) |--> (x, y, x*sin(y)) - sage: w.coordinate_ring() + sage: w.coordinate_ring() # optional - sage.symbolic Callable function ring with arguments (x, y) - sage: w(1,2) + sage: w(1,2) # optional - sage.symbolic (1, 2, sin(2)) - sage: w(2,1) + sage: w(2,1) # optional - sage.symbolic (2, 1, 2*sin(1)) - sage: w(y=1,x=2) + sage: w(y=1,x=2) # optional - sage.symbolic (2, 1, 2*sin(1)) :: - sage: x,y=var('x,y') - sage: v=vector([x,y,x*sin(y)]) - sage: w=v.function([x]); w + sage: x,y = var('x,y') # optional - sage.symbolic + sage: v = vector([x, y, x*sin(y)]) # optional - sage.symbolic + sage: w = v.function([x]); w # optional - sage.symbolic x |--> (x, y, x*sin(y)) - sage: w.coordinate_ring() + sage: w.coordinate_ring() # optional - sage.symbolic Callable function ring with argument x - sage: w(4) + sage: w(4) # optional - sage.symbolic (4, y, 4*sin(y)) """ from sage.symbolic.callable import CallableSymbolicExpressionRing @@ -4582,9 +4591,9 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): TESTS:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v.set_immutable() - sage: isinstance(hash(v), int) + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v.set_immutable() # optional - sage.symbolic + sage: isinstance(hash(v), int) # optional - sage.symbolic True Pickling works:: @@ -4634,8 +4643,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v.__copy__() + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v.__copy__() # optional - sage.symbolic (1, 2/3, pi) """ return self._new_c(dict(self._entries)) @@ -4654,13 +4663,13 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): sage: from sage.modules.free_module_element import FreeModuleElement_generic_sparse sage: def S(R,n): ....: return FreeModule(R, n, sparse=True) - sage: FreeModuleElement_generic_sparse(S(RR,5), {0:-1, 2:2/3, 3:pi, 4:oo}) + sage: FreeModuleElement_generic_sparse(S(RR,5), {0:-1, 2:2/3, 3:pi, 4:oo}) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_sparse(S(RR,5), [-1,0,2/3,pi,oo]) + sage: FreeModuleElement_generic_sparse(S(RR,5), [-1,0,2/3,pi,oo]) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_sparse(S(RR,5), (-1,0,2/3,pi,oo)) + sage: FreeModuleElement_generic_sparse(S(RR,5), (-1,0,2/3,pi,oo)) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_sparse(S(RR,5), Sequence([-1,0,2/3,pi,oo])) + sage: FreeModuleElement_generic_sparse(S(RR,5), Sequence([-1,0,2/3,pi,oo])) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) sage: FreeModuleElement_generic_sparse(S(RR,0), 0) () @@ -4705,8 +4714,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): We correctly initialize values which become 0 only after coercion:: - sage: v = FreeModuleElement_generic_sparse(S(GF(3),6), [1,2,3,4,5,6]) - sage: v.nonzero_positions() + sage: v = FreeModuleElement_generic_sparse(S(GF(3), 6), [1,2,3,4,5,6]) # optional - sage.rings.finite_rings + sage: v.nonzero_positions() # optional - sage.rings.finite_rings [0, 1, 3, 4] """ #WARNING: In creation, we do not check that the indices i satisfy @@ -4758,8 +4767,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v._add_(v) + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v._add_(v) # optional - sage.symbolic (2, 4/3, 2*pi) """ cdef dict v = dict((right)._entries) @@ -4778,8 +4787,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v._sub_(v) + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v._sub_(v) # optional - sage.symbolic (0, 0, 0) """ cdef dict v = dict(left._entries) # dict to make a copy @@ -4798,8 +4807,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v._lmul_(SR(3)) + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v._lmul_(SR(3)) # optional - sage.symbolic (3, 2, 3*pi) """ cdef dict v = {} @@ -4814,8 +4823,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v._rmul_(SR(3)) + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v._rmul_(SR(3)) # optional - sage.symbolic (3, 2, 3*pi) """ cdef dict v = {} @@ -4882,8 +4891,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True); w = vector([-2/3,pi^2,1],sparse=True) - sage: v._pairwise_product_(w) + sage: v = vector([1,2/3,pi], sparse=True); w = vector([-2/3,pi^2,1],sparse=True) # optional - sage.symbolic + sage: v._pairwise_product_(w) # optional - sage.symbolic (-2/3, 2/3*pi^2, pi) """ # Component wise vector * vector multiplication. @@ -4907,17 +4916,17 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): TESTS:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: w = vector([1,2/3,pi], sparse=True) - sage: w == v + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: w = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: w == v # optional - sage.symbolic True Check that the bug in :trac:`13929` has been fixed:: - sage: V = FreeModule( GF(3), 2, sparse=True) - sage: a = V([0,1]) - sage: b = V([1,0]) - sage: a < b + sage: V = FreeModule(GF(3), 2, sparse=True) # optional - sage.rings.finite_rings + sage: a = V([0,1]) # optional - sage.rings.finite_rings + sage: b = V([1,0]) # optional - sage.rings.finite_rings + sage: a < b # optional - sage.rings.finite_rings True """ a = sorted((left)._entries.iteritems()) @@ -4931,17 +4940,17 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: next(v.items()) + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: next(v.items()) # optional - sage.symbolic (0, 1) - sage: list(v.items()) + sage: list(v.items()) # optional - sage.symbolic [(0, 1), (1, 2/3), (2, pi)] TESTS: Using iteritems as an alias:: - sage: list(v.iteritems()) + sage: list(v.iteritems()) # optional - sage.symbolic [(0, 1), (1, 2/3), (2, pi)] """ return iter(self._entries.iteritems()) @@ -4952,9 +4961,10 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v.__reduce__() - (, (Sparse vector space of dimension 3 over Symbolic Ring, {0: 1, 1: 2/3, 2: pi}, 3, True)) + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v.__reduce__() # optional - sage.symbolic + (, + (Sparse vector space of dimension 3 over Symbolic Ring, {0: 1, 1: 2/3, 2: pi}, 3, True)) """ return (make_FreeModuleElement_generic_sparse_v1, (self._parent, self._entries, self._degree, not self._is_immutable)) @@ -5030,15 +5040,15 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([-1,0,2/3,pi], sparse=True) - sage: v.get(1) + sage: v = vector([-1,0,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v.get(1) # optional - sage.symbolic 0 - sage: v.get(2) + sage: v.get(2) # optional - sage.symbolic 2/3 For this class, 0 is returned if the access is out of bounds:: - sage: v.get(10) + sage: v.get(10) # optional - sage.symbolic 0 """ try: @@ -5050,38 +5060,39 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: V = VectorSpace(GF(17), 10000000, sparse=True) - sage: w = V(0) - sage: w[39893] = 20 - sage: w[39893] + sage: V = VectorSpace(GF(17), 10000000, sparse=True) # optional - sage.rings.finite_rings + sage: w = V(0) # optional - sage.rings.finite_rings + sage: w[39893] = 20 # optional - sage.rings.finite_rings + sage: w[39893] # optional - sage.rings.finite_rings 3 - sage: w[39000:39003] = [4, 5, 6]; w[39000:39003] + sage: w[39000:39003] = [4, 5, 6]; w[39000:39003] # optional - sage.rings.finite_rings (4, 5, 6) - sage: parent(w[39893]) + sage: parent(w[39893]) # optional - sage.rings.finite_rings Finite Field of size 17 - sage: w[39893] = sqrt(2) + sage: w[39893] = sqrt(2) # optional - sage.rings.finite_rings sage.symbolic Traceback (most recent call last): ... TypeError: self must be a numeric expression :: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v.set(1, pi^3) - sage: v + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v.set(1, pi^3) # optional - sage.symbolic + sage: v # optional - sage.symbolic (1, pi^3, pi) - sage: v.set(2, SR(0)) - sage: v + sage: v.set(2, SR(0)) # optional - sage.symbolic + sage: v # optional - sage.symbolic (1, pi^3, 0) This assignment is illegal:: - sage: v.set(10, pi) + sage: v.set(10, pi) # optional - sage.symbolic This lack of bounds checking causes trouble later:: - sage: v - ) failed: IndexError: list assignment index out of range> + sage: v # optional - sage.symbolic + ) + failed: IndexError: list assignment index out of range> """ if value: self._entries[i] = value diff --git a/src/sage/modules/free_module_homspace.py b/src/sage/modules/free_module_homspace.py index 4d99c5f4223..1887985955e 100644 --- a/src/sage/modules/free_module_homspace.py +++ b/src/sage/modules/free_module_homspace.py @@ -5,7 +5,7 @@ We create `\mathrm{End}(\ZZ^2)` and compute a basis. :: - sage: M = FreeModule(IntegerRing(),2) + sage: M = FreeModule(IntegerRing(), 2) sage: E = End(M) sage: B = E.basis() sage: len(B) @@ -14,21 +14,20 @@ Free module morphism defined by the matrix [1 0] [0 0] - Domain: Ambient free module of rank 2 over the principal ideal domain ... + Domain: Ambient free module of rank 2 over the principal ideal domain ... Codomain: Ambient free module of rank 2 over the principal ideal domain ... We create `\mathrm{Hom}(\ZZ^3, \ZZ^2)` and compute a basis. :: - sage: V3 = FreeModule(IntegerRing(),3) - sage: V2 = FreeModule(IntegerRing(),2) - sage: H = Hom(V3,V2) + sage: V3 = FreeModule(IntegerRing(), 3) + sage: V2 = FreeModule(IntegerRing(), 2) + sage: H = Hom(V3, V2) sage: H - Set of Morphisms from Ambient free module of rank 3 over - the principal ideal domain Integer Ring - to Ambient free module of rank 2 - over the principal ideal domain Integer Ring - in Category of finite dimensional modules with basis over - (euclidean domains and infinite enumerated sets and metric spaces) + Set of Morphisms + from Ambient free module of rank 3 over the principal ideal domain Integer Ring + to Ambient free module of rank 2 over the principal ideal domain Integer Ring + in Category of finite dimensional modules with basis over + (euclidean domains and infinite enumerated sets and metric spaces) sage: B = H.basis() sage: len(B) 6 @@ -54,7 +53,7 @@ See :trac:`13321`:: - sage: (GF(7)^2).hom([[20,0],[0,21]],ZZ^2) + sage: (GF(7)^2).hom([[20, 0], [0, 21]], ZZ^2) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: nontrivial morphisms require a coercion map from the base ring @@ -167,10 +166,10 @@ def __call__(self, A, **kwds): [0 0 0] [0 0 0] [0 0 0] - Domain: Free module of degree 3 and rank 3 over Integer Ring - Echelon ... + Domain: Free module of degree 3 and rank 3 over Integer Ring + Echelon ... Codomain: Free module of degree 3 and rank 3 over Integer Ring - Echelon ... + Echelon ... The following tests the bug fixed in :trac:`31818`. If there is no coercion between base rings, one can only define the zero morphism, @@ -188,7 +187,7 @@ def __call__(self, A, **kwds): Free module morphism defined by the matrix [0 0] [0 0] - Domain: Vector space of dimension 2 over Rational Field + Domain: Vector space of dimension 2 over Rational Field Codomain: Ambient free module of rank 2 over the principal ideal domain Integer Ring sage: [h(v) for v in V.gens()] [(0, 0), (0, 0)] @@ -236,7 +235,7 @@ def zero(self, side="left"): Free module morphism defined by the matrix [0 0 0] [0 0 0] - Domain: Ambient free module of rank 2 over the principal ideal domain Integer Ring + Domain: Ambient free module of rank 2 over the principal ideal domain Integer Ring Codomain: Ambient free module of rank 3 over the principal ideal domain Integer Ring sage: f(E.an_element()) (0, 0, 0) @@ -247,7 +246,7 @@ def zero(self, side="left"): [0 0] [0 0] [0 0] - Domain: Ambient free module of rank 2 over the principal ideal domain Integer Ring + Domain: Ambient free module of rank 2 over the principal ideal domain Integer Ring Codomain: Ambient free module of rank 3 over the principal ideal domain Integer Ring @@ -259,7 +258,7 @@ def zero(self, side="left"): Free module morphism defined by the matrix [0 0 0] [0 0 0] - Domain: Ambient free module of rank 2 over the principal ideal domain Integer Ring + Domain: Ambient free module of rank 2 over the principal ideal domain Integer Ring Codomain: Ambient free module of rank 3 over the principal ideal domain Integer Ring """ return self(lambda x: self.codomain().zero(), side=side) @@ -310,24 +309,24 @@ def basis(self, side="left"): sage: H = Hom(ZZ^2, ZZ^1) sage: H.basis() (Free module morphism defined by the matrix - [1] - [0] - Domain: Ambient free module of rank 2 over the principal ideal domain ... - Codomain: Ambient free module of rank 1 over the principal ideal domain ..., - Free module morphism defined by the matrix - [0] - [1] - Domain: Ambient free module of rank 2 over the principal ideal domain ... - Codomain: Ambient free module of rank 1 over the principal ideal domain ...) + [1] + [0] + Domain: Ambient free module of rank 2 over the principal ideal domain ... + Codomain: Ambient free module of rank 1 over the principal ideal domain ..., + Free module morphism defined by the matrix + [0] + [1] + Domain: Ambient free module of rank 2 over the principal ideal domain ... + Codomain: Ambient free module of rank 1 over the principal ideal domain ...) sage: H.basis("right") (Free module morphism defined as left-multiplication by the matrix - [1 0] - Domain: Ambient free module of rank 2 over the principal ideal domain ... - Codomain: Ambient free module of rank 1 over the principal ideal domain ..., + [1 0] + Domain: Ambient free module of rank 2 over the principal ideal domain ... + Codomain: Ambient free module of rank 1 over the principal ideal domain ..., Free module morphism defined as left-multiplication by the matrix - [0 1] - Domain: Ambient free module of rank 2 over the principal ideal domain ... - Codomain: Ambient free module of rank 1 over the principal ideal domain ...) + [0 1] + Domain: Ambient free module of rank 2 over the principal ideal domain ... + Codomain: Ambient free module of rank 1 over the principal ideal domain ...) """ M = self._matrix_space(side) B = M.basis() @@ -352,7 +351,7 @@ def identity(self, side="left"): [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] - Domain: Ambient free module of rank 5 over the principal ideal domain ... + Domain: Ambient free module of rank 5 over the principal ideal domain ... Codomain: Ambient free module of rank 5 over the principal ideal domain ... """ if self.is_endomorphism_set(): diff --git a/src/sage/modules/free_module_integer.py b/src/sage/modules/free_module_integer.py index ddd8a25c92a..cf36c8960ee 100644 --- a/src/sage/modules/free_module_integer.py +++ b/src/sage/modules/free_module_integer.py @@ -109,7 +109,8 @@ def IntegerLattice(basis, lll_reduce=True): sage: K. = CyclotomicField(17) sage: O = K.ring_of_integers() - sage: f = O(-a^15 + a^13 + 4*a^12 - 12*a^11 - 256*a^10 + a^9 - a^7 - 4*a^6 + a^5 + 210*a^4 + 2*a^3 - 2*a^2 + 2*a - 2) + sage: f = O(-a^15 + a^13 + 4*a^12 - 12*a^11 - 256*a^10 + a^9 - a^7 + ....: - 4*a^6 + a^5 + 210*a^4 + 2*a^3 - 2*a^2 + 2*a - 2) sage: from sage.modules.free_module_integer import IntegerLattice sage: IntegerLattice(f) Free module of degree 16 and rank 16 over Integer Ring @@ -152,10 +153,10 @@ def IntegerLattice(basis, lll_reduce=True): Sage also interfaces with fpylll's lattice generator:: sage: from sage.modules.free_module_integer import IntegerLattice - sage: from fpylll import IntegerMatrix - sage: A = IntegerMatrix.random(8, "simdioph", bits=20, bits2=10) - sage: A = A.to_matrix(matrix(ZZ, 8, 8)) - sage: IntegerLattice(A, lll_reduce=False) + sage: from fpylll import IntegerMatrix # optional - fpylll + sage: A = IntegerMatrix.random(8, "simdioph", bits=20, bits2=10) # optional - fpylll + sage: A = A.to_matrix(matrix(ZZ, 8, 8)) # optional - fpylll + sage: IntegerLattice(A, lll_reduce=False) # optional - fpylll Free module of degree 8 and rank 8 over Integer Ring User basis matrix: [ 1024 829556 161099 11567 521155 769480 639201 689979] @@ -197,7 +198,8 @@ class FreeModule_submodule_with_basis_integer(FreeModule_submodule_with_basis_pi EXAMPLES:: sage: from sage.modules.free_module_integer import IntegerLattice - sage: L = IntegerLattice(sage.crypto.gen_lattice(type='modular', m=10, seed=1337, dual=True)); L + sage: L = IntegerLattice(sage.crypto.gen_lattice(type='modular', m=10, + ....: seed=1337, dual=True)); L Free module of degree 10 and rank 10 over Integer Ring User basis matrix: [-1 1 2 -2 0 1 0 -1 2 1] @@ -364,10 +366,10 @@ def LLL(self, *args, **kwds): ... sage: L.reduced_basis == A True - sage: old = L.reduced_basis[0].norm().n() + sage: old = L.reduced_basis[0].norm().n() # optional - sage.symbolic sage: _ = L.LLL() - sage: new = L.reduced_basis[0].norm().n() - sage: new <= old + sage: new = L.reduced_basis[0].norm().n() # optional - sage.symbolic + sage: new <= old # optional - sage.symbolic True """ basis = self.reduced_basis @@ -648,20 +650,24 @@ def voronoi_cell(self, radius=None): sage: L = IntegerLattice([[1, 0], [0, 1]]) sage: V = L.voronoi_cell() sage: V.Vrepresentation() - (A vertex at (1/2, -1/2), A vertex at (1/2, 1/2), A vertex at (-1/2, 1/2), A vertex at (-1/2, -1/2)) + (A vertex at (1/2, -1/2), + A vertex at (1/2, 1/2), + A vertex at (-1/2, 1/2), + A vertex at (-1/2, -1/2)) The volume of the Voronoi cell is the square root of the discriminant of the lattice:: - sage: L = IntegerLattice(Matrix(ZZ, 4, 4, [[0,0,1,-1],[1,-1,2,1],[-6,0,3,3,],[-6,-24,-6,-5]])); L + sage: L = IntegerLattice(Matrix(ZZ, 4, 4, [[0,0,1,-1], [1,-1,2,1], + ....: [-6,0,3,3,], [-6,-24,-6,-5]])); L Free module of degree 4 and rank 4 over Integer Ring User basis matrix: [ 0 0 1 -1] [ 1 -1 2 1] [ -6 0 3 3] [ -6 -24 -6 -5] - sage: V = L.voronoi_cell() # long time - sage: V.volume() # long time + sage: V = L.voronoi_cell() # long time + sage: V.volume() # long time 678 sage: sqrt(L.discriminant()) 678 @@ -671,7 +677,10 @@ def voronoi_cell(self, radius=None): sage: L = IntegerLattice([[2, 0, 0], [0, 2, 0]]) sage: V = L.voronoi_cell() sage: V.Hrepresentation() - (An inequality (-1, 0, 0) x + 1 >= 0, An inequality (0, -1, 0) x + 1 >= 0, An inequality (1, 0, 0) x + 1 >= 0, An inequality (0, 1, 0) x + 1 >= 0) + (An inequality (-1, 0, 0) x + 1 >= 0, + An inequality (0, -1, 0) x + 1 >= 0, + An inequality (1, 0, 0) x + 1 >= 0, + An inequality (0, 1, 0) x + 1 >= 0) ALGORITHM: diff --git a/src/sage/modules/free_module_morphism.py b/src/sage/modules/free_module_morphism.py index f7508ebeb97..37dd2614098 100644 --- a/src/sage/modules/free_module_morphism.py +++ b/src/sage/modules/free_module_morphism.py @@ -53,7 +53,7 @@ def is_FreeModuleMorphism(x): """ EXAMPLES:: - sage: V = ZZ^2; f = V.hom([V.1,-2*V.0]) + sage: V = ZZ^2; f = V.hom([V.1, -2*V.0]) sage: sage.modules.free_module_morphism.is_FreeModuleMorphism(f) True sage: sage.modules.free_module_morphism.is_FreeModuleMorphism(0) @@ -75,8 +75,8 @@ def __init__(self, parent, A, side="left"): EXAMPLES:: - sage: V = ZZ^3; W = span([[1,2,3],[-1,2,8]], ZZ) - sage: phi = V.hom(matrix(ZZ,3,[1..9])) + sage: V = ZZ^3; W = span([[1,2,3], [-1,2,8]], ZZ) + sage: phi = V.hom(matrix(ZZ, 3, [1..9])) sage: type(phi) """ @@ -93,8 +93,8 @@ def pushforward(self, x): EXAMPLES:: - sage: V = QQ^3; W = span([[1,2,3],[-1,2,5/3]], QQ) - sage: phi = V.hom(matrix(QQ,3,[1..9])) + sage: V = QQ^3; W = span([[1,2,3], [-1,2,5/3]], QQ) + sage: phi = V.hom(matrix(QQ, 3, [1..9])) sage: phi.rank() 2 sage: phi(V) #indirect doctest @@ -106,12 +106,12 @@ def pushforward(self, x): We compute the image of a submodule of a ZZ-module embedded in a rational vector space:: - sage: V = QQ^3; W = V.span_of_basis([[2,2,3],[-1,2,5/3]], ZZ) - sage: phi = W.hom([W.0, W.0-W.1]); phi + sage: V = QQ^3; W = V.span_of_basis([[2,2,3], [-1,2,5/3]], ZZ) + sage: phi = W.hom([W.0, W.0 - W.1]); phi Free module morphism defined by the matrix [ 1 0] [ 1 -1]... - sage: phi(span([2*W.1],ZZ)) + sage: phi(span([2*W.1], ZZ)) Free module of degree 3 and rank 1 over Integer Ring Echelon basis matrix: [ 6 0 8/3] @@ -129,8 +129,8 @@ def _repr_(self): EXAMPLES:: - sage: V = ZZ^3; W = span([[1,2,3],[-1,2,8]], ZZ) - sage: phi = V.hom(matrix(ZZ,3,[1..9])) + sage: V = ZZ^3; W = span([[1,2,3], [-1,2,8]], ZZ) + sage: phi = V.hom(matrix(ZZ, 3, [1..9])) sage: phi._repr_() 'Free module morphism defined by the matrix\n[1 2 3]\n[4 5 6]\n[7 8 9]\nDomain: Ambient free module of rank 3 over the principal ideal domain Integer Ring\nCodomain: Ambient free module of rank 3 over the principal ideal domain Integer Ring' @@ -192,8 +192,10 @@ def change_ring(self, R): EXAMPLES:: - sage: V0 = span([[0,0,1],[0,2,0]],ZZ); V1 = span([[1/2,0],[0,2]],ZZ); W = span([[1,0],[0,6]],ZZ) - sage: h = V0.hom([-3*V1.0-3*V1.1, -3*V1.0-3*V1.1]) + sage: V0 = span([[0,0,1], [0,2,0]], ZZ) + sage: V1 = span([[1/2,0], [0,2]], ZZ) + sage: W = span([[1,0], [0,6]], ZZ) + sage: h = V0.hom([-3*V1.0 - 3*V1.1, -3*V1.0 - 3*V1.1]) sage: h.base_ring() Integer Ring sage: h @@ -206,26 +208,26 @@ def change_ring(self, R): Vector space morphism represented by the matrix: [-3 -3] [-3 -3] - Domain: Vector space of degree 3 and dimension 2 over Rational Field - Basis matrix: - [0 1 0] - [0 0 1] + Domain: Vector space of degree 3 and dimension 2 over Rational Field + Basis matrix: + [0 1 0] + [0 0 1] Codomain: Vector space of degree 2 and dimension 2 over Rational Field - Basis matrix: - [1 0] - [0 1] - sage: f = h.change_ring(GF(7)); f + Basis matrix: + [1 0] + [0 1] + sage: f = h.change_ring(GF(7)); f # optional - sage.libs.pari Vector space morphism represented by the matrix: [4 4] [4 4] - Domain: Vector space of degree 3 and dimension 2 over Finite Field of size 7 - Basis matrix: - [0 1 0] - [0 0 1] + Domain: Vector space of degree 3 and dimension 2 over Finite Field of size 7 + Basis matrix: + [0 1 0] + [0 0 1] Codomain: Vector space of degree 2 and dimension 2 over Finite Field of size 7 - Basis matrix: - [1 0] - [0 1] + Basis matrix: + [1 0] + [0 1] """ D = self.domain().change_ring(R) C = self.codomain().change_ring(R) @@ -242,8 +244,8 @@ def inverse_image(self, V): We test computing inverse images over a field:: - sage: V = QQ^3; W = span([[1,2,3],[-1,2,5/3]], QQ) - sage: phi = V.hom(matrix(QQ,3,[1..9])) + sage: V = QQ^3; W = span([[1,2,3], [-1,2,5/3]], QQ) + sage: phi = V.hom(matrix(QQ, 3, [1..9])) sage: phi.rank() 2 sage: I = phi.inverse_image(W); I @@ -262,8 +264,10 @@ def inverse_image(self, V): We test computing inverse images between two spaces embedded in different ambient spaces.:: - sage: V0 = span([[0,0,1],[0,2,0]],ZZ); V1 = span([[1/2,0],[0,2]],ZZ); W = span([[1,0],[0,6]],ZZ) - sage: h = V0.hom([-3*V1.0-3*V1.1, -3*V1.0-3*V1.1]) + sage: V0 = span([[0,0,1], [0,2,0]], ZZ) + sage: V1 = span([[1/2,0], [0,2]], ZZ) + sage: W = span([[1,0], [0,6]], ZZ) + sage: h = V0.hom([-3*V1.0 - 3*V1.1, -3*V1.0 - 3*V1.1]) sage: h.inverse_image(W) Free module of degree 3 and rank 2 over Integer Ring Echelon basis matrix: @@ -281,8 +285,8 @@ def inverse_image(self, V): We test computing inverse images over the integers:: - sage: V = QQ^3; W = V.span_of_basis([[2,2,3],[-1,2,5/3]], ZZ) - sage: phi = W.hom([W.0, W.0-W.1]) + sage: V = QQ^3; W = V.span_of_basis([[2,2,3], [-1,2,5/3]], ZZ) + sage: phi = W.hom([W.0, W.0 - W.1]) sage: Z = W.span([2*W.1]); Z Free module of degree 3 and rank 1 over Integer Ring Echelon basis matrix: @@ -296,7 +300,7 @@ def inverse_image(self, V): We test that :trac:`24590` is resolved:: - sage: A = FreeQuadraticModule(ZZ,1,matrix([2])) + sage: A = FreeQuadraticModule(ZZ, 1, matrix([2])) sage: f = A.Hom(A).an_element() sage: f.inverse_image(A) Free module of degree 1 and rank 1 over Integer Ring @@ -414,17 +418,17 @@ def lift(self, x): This works for vector spaces, too:: - sage: V = VectorSpace(GF(3), 2) - sage: W = VectorSpace(GF(3), 3) - sage: f = V.hom([W.1, W.1 - W.0]) - sage: f.lift(W.1) + sage: V = VectorSpace(GF(3), 2) # optional - sage.libs.pari + sage: W = VectorSpace(GF(3), 3) # optional - sage.libs.pari + sage: f = V.hom([W.1, W.1 - W.0]) # optional - sage.libs.pari + sage: f.lift(W.1) # optional - sage.libs.pari (1, 0) - sage: f.lift(W.2) + sage: f.lift(W.2) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: element is not in the image - sage: w = W((17, -2, 0)) - sage: f(f.lift(w)) == w + sage: w = W((17, -2, 0)) # optional - sage.libs.pari + sage: f(f.lift(w)) == w # optional - sage.libs.pari True This example illustrates the use of the ``preimage_representative`` @@ -440,9 +444,9 @@ def lift(self, x): :: sage: V = QQ^2; m = matrix(2, [1, 1, 0, 1]) - sage: V.hom(m, side="right").lift(V.0+V.1) + sage: V.hom(m, side="right").lift(V.0 + V.1) (0, 1) - sage: V.hom(m).lift(V.0+V.1) + sage: V.hom(m).lift(V.0 + V.1) (1, 0) """ from .free_module_element import vector @@ -473,7 +477,7 @@ def lift(self, x): preimage_representative = lift - def eigenvalues(self,extend=True): + def eigenvalues(self, extend=True): r""" Returns a list with the eigenvalues of the endomorphism of vector spaces. @@ -486,18 +490,18 @@ def eigenvalues(self,extend=True): We compute the eigenvalues of an endomorphism of `\QQ^3`:: - sage: V=QQ^3 - sage: H=V.endomorphism_ring()([[1,-1,0],[-1,1,1],[0,3,1]]) - sage: H.eigenvalues() + sage: V = QQ^3 + sage: H = V.endomorphism_ring()([[1,-1,0], [-1,1,1], [0,3,1]]) + sage: H.eigenvalues() # optional - sage.rings.number_field [3, 1, -1] Note the effect of the ``extend`` option:: - sage: V=QQ^2 - sage: H=V.endomorphism_ring()([[0,-1],[1,0]]) - sage: H.eigenvalues() + sage: V = QQ^2 + sage: H = V.endomorphism_ring()([[0,-1], [1,0]]) + sage: H.eigenvalues() # optional - sage.rings.number_field [-1*I, 1*I] - sage: H.eigenvalues(extend=False) + sage: H.eigenvalues(extend=False) # optional - sage.libs.pari [] """ if self.base_ring().is_field(): @@ -508,7 +512,7 @@ def eigenvalues(self,extend=True): else: raise NotImplementedError("module must be a vector space") - def eigenvectors(self,extend=True): + def eigenvectors(self, extend=True): """ Computes the subspace of eigenvectors of a given eigenvalue. @@ -525,50 +529,30 @@ def eigenvectors(self,extend=True): EXAMPLES:: - sage: V=(QQ^4).subspace([[0,2,1,4],[1,2,5,0],[1,1,1,1]]) - sage: H=(V.Hom(V))(matrix(QQ, [[0,1,0],[-1,0,0],[0,0,3]])) - sage: H.eigenvectors() - [(3, [ - (0, 0, 1, -6/7) - ], 1), (-1*I, [ - (1, 1*I, 0, -0.571428571428572? + 2.428571428571429?*I) - ], 1), (1*I, [ - (1, -1*I, 0, -0.571428571428572? - 2.428571428571429?*I) - ], 1)] - sage: H.eigenvectors(extend=False) - [(3, [ - (0, 0, 1, -6/7) - ], 1)] - sage: H1=(V.Hom(V))(matrix(QQ, [[2,1,0],[0,2,0],[0,0,3]])) - sage: H1.eigenvectors() - [(3, [ - (0, 0, 1, -6/7) - ], 1), (2, [ - (0, 1, 0, 17/7) - ], 2)] - sage: H1.eigenvectors(extend=False) - [(3, [ - (0, 0, 1, -6/7) - ], 1), (2, [ - (0, 1, 0, 17/7) - ], 2)] + sage: V = (QQ^4).subspace([[0,2,1,4], [1,2,5,0], [1,1,1,1]]) + sage: H = (V.Hom(V))(matrix(QQ, [[0,1,0], [-1,0,0], [0,0,3]])) + sage: H.eigenvectors() # optional - sage.rings.number_field + [(3, [ (0, 0, 1, -6/7) ], 1), + (-1*I, [ (1, 1*I, 0, -0.571428571428572? + 2.428571428571429?*I) ], 1), + (1*I, [ (1, -1*I, 0, -0.571428571428572? - 2.428571428571429?*I) ], 1)] + sage: H.eigenvectors(extend=False) # optional - sage.rings.number_field + [(3, [ (0, 0, 1, -6/7) ], 1)] + sage: H1 = (V.Hom(V))(matrix(QQ, [[2,1,0],[0,2,0],[0,0,3]])) + sage: H1.eigenvectors() # optional - sage.rings.number_field + [(3, [ (0, 0, 1, -6/7) ], 1), + (2, [ (0, 1, 0, 17/7) ], 2)] + sage: H1.eigenvectors(extend=False) # optional - sage.rings.number_field + [(3, [ (0, 0, 1, -6/7) ], 1), + (2, [ (0, 1, 0, 17/7) ], 2)] :: sage: V = QQ^2 sage: m = matrix(2, [1, 1, 0, 1]) - sage: V.hom(m, side="right").eigenvectors() - [(1, - [ - (1, 0) - ], - 2)] - sage: V.hom(m).eigenvectors() - [(1, - [ - (0, 1) - ], - 2)] + sage: V.hom(m, side="right").eigenvectors() # optional - sage.rings.number_field + [(1, [ (1, 0) ], 2)] + sage: V.hom(m).eigenvectors() # optional - sage.rings.number_field + [(1, [ (0, 1) ], 2)] """ if self.base_ring().is_field(): if self.is_endomorphism(): @@ -587,7 +571,7 @@ def eigenvectors(self,extend=True): else: raise NotImplementedError("module must be a vector space") - def eigenspaces(self,extend=True): + def eigenspaces(self, extend=True): """ Compute a list of subspaces formed by eigenvectors of ``self``. @@ -603,56 +587,51 @@ def eigenspaces(self,extend=True): EXAMPLES:: sage: V = QQ^3 - sage: h = V.hom([[1,0,0],[0,0,1],[0,-1,0]], V) - sage: h.eigenspaces() - [(1, - Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [1 0 0]), - (-1*I, - Vector space of degree 3 and dimension 1 over Algebraic Field - Basis matrix: - [ 0 1 1*I]), - (1*I, - Vector space of degree 3 and dimension 1 over Algebraic Field - Basis matrix: - [ 0 1 -1*I])] - - sage: h.eigenspaces(extend=False) + sage: h = V.hom([[1,0,0], [0,0,1], [0,-1,0]], V) + sage: h.eigenspaces() # optional - sage.rings.number_field + [(1, Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: + [1 0 0]), + (-1*I, Vector space of degree 3 and dimension 1 over Algebraic Field + Basis matrix: + [ 0 1 1*I]), + (1*I, Vector space of degree 3 and dimension 1 over Algebraic Field + Basis matrix: + [ 0 1 -1*I])] + + sage: h.eigenspaces(extend=False) # optional - sage.rings.number_field [(1, Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: [1 0 0])] sage: h = V.hom([[2,1,0], [0,2,0], [0,0,-1]], V) - sage: h.eigenspaces() + sage: h.eigenspaces() # optional - sage.rings.number_field [(-1, Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [0 0 1]), - (2, Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [0 1 0])] + Basis matrix: + [0 0 1]), + (2, Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: + [0 1 0])] sage: h = V.hom([[2,1,0], [0,2,0], [0,0,2]], V) - sage: h.eigenspaces() + sage: h.eigenspaces() # optional - sage.rings.number_field [(2, Vector space of degree 3 and dimension 2 over Rational Field - Basis matrix: - [0 1 0] - [0 0 1])] + Basis matrix: + [0 1 0] + [0 0 1])] :: sage: V = QQ^2; m = matrix(2, [1, 1, 0, 1]) - sage: V.hom(m, side="right").eigenspaces() - [(1, - Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [1 0])] - sage: V.hom(m).eigenspaces() - [(1, - Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [0 1])] + sage: V.hom(m, side="right").eigenspaces() # optional - sage.rings.number_field + [(1, Vector space of degree 2 and dimension 1 over Rational Field + Basis matrix: + [1 0])] + sage: V.hom(m).eigenspaces() # optional - sage.rings.number_field + [(1, Vector space of degree 2 and dimension 1 over Rational Field + Basis matrix: + [0 1])] """ ev = self.eigenvectors(extend) return [(vec[0], Sequence(vec[1]).universe().subspace(vec[1])) @@ -676,9 +655,9 @@ def minimal_polynomial(self,var='x'): Compute the minimal polynomial, and check it. :: - sage: V=GF(7)^3 - sage: H=V.Hom(V)([[0,1,2],[-1,0,3],[2,4,1]]) - sage: H + sage: V = GF(7)^3 # optional - sage.libs.pari + sage: H = V.Hom(V)([[0,1,2], [-1,0,3], [2,4,1]]) # optional - sage.libs.pari + sage: H # optional - sage.libs.pari Vector space morphism represented by the matrix: [0 1 2] [6 0 3] @@ -686,13 +665,13 @@ def minimal_polynomial(self,var='x'): Domain: Vector space of dimension 3 over Finite Field of size 7 Codomain: Vector space of dimension 3 over Finite Field of size 7 - sage: H.minpoly() + sage: H.minpoly() # optional - sage.libs.pari x^3 + 6*x^2 + 6*x + 1 - sage: H.minimal_polynomial() + sage: H.minimal_polynomial() # optional - sage.libs.pari x^3 + 6*x^2 + 6*x + 1 - sage: H^3 + (H^2)*6 + H*6 + 1 + sage: H^3 + (H^2)*6 + H*6 + 1 # optional - sage.libs.pari Vector space morphism represented by the matrix: [0 0 0] [0 0 0] @@ -717,7 +696,8 @@ class BaseIsomorphism1D(Morphism): sage: V, from_V, to_V = R.free_module(R) sage: from_V Isomorphism morphism: - From: Ambient free module of rank 1 over the integral domain Multivariate Polynomial Ring in x, y over Rational Field + From: Ambient free module of rank 1 over the integral domain + Multivariate Polynomial Ring in x, y over Rational Field To: Multivariate Polynomial Ring in x, y over Rational Field """ def _repr_type(self): diff --git a/src/sage/modules/free_quadratic_module.py b/src/sage/modules/free_quadratic_module.py index b512db6ffbc..25f794b4054 100644 --- a/src/sage/modules/free_quadratic_module.py +++ b/src/sage/modules/free_quadratic_module.py @@ -18,8 +18,8 @@ EXAMPLES:: - sage: M = Matrix(QQ,[[2,1,0],[1,2,1],[0,1,2]]) - sage: V = VectorSpace(QQ,3,inner_product_matrix=M) + sage: M = Matrix(QQ, [[2,1,0], [1,2,1], [0,1,2]]) + sage: V = VectorSpace(QQ, 3, inner_product_matrix=M) sage: type(V) sage: V.inner_product_matrix() @@ -44,11 +44,11 @@ TESTS:: - sage: M = Matrix(QQ,[[2,1,0],[1,2,1],[0,1,2]]) - sage: V = VectorSpace(QQ,3,inner_product_matrix = M) + sage: M = Matrix(QQ, [[2,1,0], [1,2,1], [0,1,2]]) + sage: V = VectorSpace(QQ, 3, inner_product_matrix=M) sage: V == loads(dumps(V)) True - sage: W = QuadraticSpace(QQ,3,M) + sage: W = QuadraticSpace(QQ, 3, M) sage: W == V True @@ -110,13 +110,13 @@ def FreeQuadraticModule(base_ring, rank, inner_product_matrix, EXAMPLES:: - sage: M2 = FreeQuadraticModule(ZZ,2,inner_product_matrix=[1,2,3,4]) - sage: M2 is FreeQuadraticModule(ZZ,2,inner_product_matrix=[1,2,3,4]) + sage: M2 = FreeQuadraticModule(ZZ, 2, inner_product_matrix=[1,2,3,4]) + sage: M2 is FreeQuadraticModule(ZZ, 2, inner_product_matrix=[1,2,3,4]) True sage: M2.inner_product_matrix() [1 2] [3 4] - sage: M3 = FreeModule(ZZ,2,inner_product_matrix=[[1,2],[3,4]]) + sage: M3 = FreeModule(ZZ, 2, inner_product_matrix=[[1,2],[3,4]]) sage: M3 is M2 True @@ -124,9 +124,9 @@ def FreeQuadraticModule(base_ring, rank, inner_product_matrix, Check for :trac:`10577`:: - sage: m = matrix.diagonal(GF(2), [1,1]) - sage: V2 = VectorSpace(GF(2), 2, inner_product_matrix=m) - sage: deepcopy(V2) + sage: m = matrix.diagonal(GF(2), [1,1]) # optional - sage.rings.finite_rings + sage: V2 = VectorSpace(GF(2), 2, inner_product_matrix=m) # optional - sage.rings.finite_rings + sage: deepcopy(V2) # optional - sage.rings.finite_rings Ambient quadratic space of dimension 2 over Finite Field of size 2 Inner product matrix: [1 0] @@ -192,10 +192,11 @@ def QuadraticSpace(K, dimension, inner_product_matrix, sparse=False): The base can be complicated, as long as it is a field:: sage: F. = FractionField(PolynomialRing(ZZ,'x')) - sage: D = diagonal_matrix([x,x-1,x+1]) - sage: V = QuadraticSpace(F,3,D) + sage: D = diagonal_matrix([x, x - 1, x + 1]) + sage: V = QuadraticSpace(F, 3, D) sage: V - Ambient quadratic space of dimension 3 over Fraction Field of Univariate Polynomial Ring in x over Integer Ring + Ambient quadratic space of dimension 3 over + Fraction Field of Univariate Polynomial Ring in x over Integer Ring Inner product matrix: [ x 0 0] [ 0 x - 1 0] @@ -209,7 +210,7 @@ def QuadraticSpace(K, dimension, inner_product_matrix, sparse=False): The base must be a field or a ``TypeError`` is raised:: - sage: QuadraticSpace(ZZ,5,identity_matrix(ZZ,2)) + sage: QuadraticSpace(ZZ, 5, identity_matrix(ZZ,2)) Traceback (most recent call last): ... TypeError: argument K (= Integer Ring) must be a field @@ -702,7 +703,7 @@ def __init__(self, base_field, dimension, degree, inner_product_matrix, sparse=F Inner product matrix: [2 1] [1 2] - sage: FreeModule(FiniteField(2), 7, inner_product_matrix=1) + sage: FreeModule(FiniteField(2), 7, inner_product_matrix=1) # optional - sage.rings.finite_rings Ambient quadratic space of dimension 7 over Finite Field of size 2 Inner product matrix: [1 0 0 0 0 0 0] @@ -739,12 +740,12 @@ def span(self, gens, check=True, already_echelonized=False): EXAMPLES:: - sage: V = VectorSpace(GF(7), 3) - sage: W = V.subspace([[2,3,4]]); W + sage: V = VectorSpace(GF(7), 3) # optional - sage.rings.finite_rings + sage: W = V.subspace([[2,3,4]]); W # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] - sage: W.span([[1,1,1]]) + sage: W.span([[1,1,1]]) # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 1 1] @@ -779,12 +780,12 @@ def span_of_basis(self, basis, check=True, already_echelonized=False): EXAMPLES:: - sage: V = VectorSpace(GF(7), 3) - sage: W = V.subspace([[2,3,4]]); W + sage: V = VectorSpace(GF(7), 3) # optional - sage.rings.finite_rings + sage: W = V.subspace([[2,3,4]]); W # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] - sage: W.span_of_basis([[2,2,2], [3,3,0]]) + sage: W.span_of_basis([[2,2,2], [3,3,0]]) # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 2 over Finite Field of size 7 User basis matrix: [2 2 2] @@ -793,7 +794,7 @@ def span_of_basis(self, basis, check=True, already_echelonized=False): The basis vectors must be linearly independent or a ``ValueError`` exception is raised:: - sage: W.span_of_basis([[2,2,2], [3,3,3]]) + sage: W.span_of_basis([[2,2,2], [3,3,3]]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent. @@ -876,7 +877,7 @@ def _latex_(self): sage: latex(QQ^3) # indirect doctest \Bold{Q}^{3} - sage: A = GF(5)^20; latex(A) + sage: A = GF(5)^20; latex(A) # optional - sage.rings.finite_rings \Bold{F}_{5}^{20} sage: A = PolynomialRing(QQ,3,'x')^20; latex(A) @@ -943,7 +944,7 @@ def __init__(self, base_ring, rank, inner_product_matrix, sparse=False): """ EXAMPLES:: - sage: FreeModule(PolynomialRing(GF(5),'x'), 3) + sage: FreeModule(PolynomialRing(GF(5),'x'), 3) # optional - sage.rings.finite_rings Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in x over Finite Field of size 5 """ @@ -1141,8 +1142,8 @@ def __init__(self, base_field, dimension, inner_product_matrix, sparse=False): Check for :trac:`10606`:: sage: D = matrix.diagonal(ZZ, [1,1]) - sage: V = VectorSpace(GF(46349), 2, inner_product_matrix=D) - sage: deepcopy(V) + sage: V = VectorSpace(GF(46349), 2, inner_product_matrix=D) # optional - sage.rings.finite_rings + sage: deepcopy(V) # optional - sage.rings.finite_rings Ambient quadratic space of dimension 2 over Finite Field of size 46349 Inner product matrix: @@ -1356,17 +1357,17 @@ def change_ring(self, R): Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: [ 1 1/4 1/2] - sage: W.change_ring(GF(7)) + sage: W.change_ring(GF(7)) # optional - sage.rings.finite_rings Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 2 4] - sage: N = FreeModule(ZZ, 2, inner_product_matrix=[[1,-1],[2,5]]) + sage: N = FreeModule(ZZ, 2, inner_product_matrix=[[1,-1], [2,5]]) sage: N.inner_product_matrix() [ 1 -1] [ 2 5] - sage: Np = N.change_ring(RDF) - sage: Np.inner_product_matrix() + sage: Np = N.change_ring(RDF) # optional - sage.rings.finite_rings + sage: Np.inner_product_matrix() # optional - sage.rings.finite_rings [ 1.0 -1.0] [ 2.0 5.0] """ @@ -1391,7 +1392,7 @@ class FreeQuadraticModule_submodule_pid(free_module.FreeModule_submodule_pid, EXAMPLES:: sage: M = ZZ^3 - sage: W = M.span_of_basis([[1,2,3],[4,5,19]]); W + sage: W = M.span_of_basis([[1,2,3], [4,5,19]]); W Free module of degree 3 and rank 2 over Integer Ring User basis matrix: [ 1 2 3] @@ -1509,14 +1510,14 @@ def __init__(self, ambient, basis, inner_product_matrix, EXAMPLES:: sage: V = QQ^3 - sage: W = V.span_of_basis([[1,2,3],[4,5,6]]) + sage: W = V.span_of_basis([[1,2,3], [4,5,6]]) sage: W Vector space of degree 3 and dimension 2 over Rational Field User basis matrix: [1 2 3] [4 5 6] sage: V = VectorSpace(QQ, 3, inner_product_matrix=1) - sage: V.span_of_basis([[1,2,3],[4,5,6]]) + sage: V.span_of_basis([[1,2,3], [4,5,6]]) Quadratic space of degree 3 and dimension 2 over Rational Field Basis matrix: [1 2 3] @@ -1603,7 +1604,7 @@ class FreeQuadraticModule_submodule_field(free_module.FreeModule_submodule_field coordinates:: sage: V = QQ^3 - sage: W = V.span([[1,2,3],[4,5,6]]) + sage: W = V.span([[1,2,3], [4,5,6]]) sage: W Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: @@ -1629,7 +1630,7 @@ def __init__(self, ambient, gens, inner_product_matrix, check=True, already_eche EXAMPLES:: sage: V = QQ^3 - sage: W = V.span([[1,2,3],[4,5,6]]) + sage: W = V.span([[1,2,3], [4,5,6]]) sage: W Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: @@ -1646,7 +1647,7 @@ def _repr_(self): EXAMPLES:: - sage: V = VectorSpace(QQ,5) + sage: V = VectorSpace(QQ, 5) sage: U = V.submodule([ V.gen(i) - V.gen(0) for i in range(1,5) ]) sage: U # indirect doctest Vector space of degree 5 and dimension 4 over Rational Field @@ -1679,7 +1680,7 @@ def _repr_(self): Sparse vector spaces print this fact:: - sage: V = VectorSpace(QQ,5,sparse=True) + sage: V = VectorSpace(QQ, 5, sparse=True) sage: U = V.submodule([ V.gen(i) - V.gen(0) for i in range(1,5) ]) sage: U # indirect doctest Sparse vector space of degree 5 and dimension 4 over Rational Field diff --git a/src/sage/modules/free_quadratic_module_integer_symmetric.py b/src/sage/modules/free_quadratic_module_integer_symmetric.py index cc1576ab626..12927d76fcd 100644 --- a/src/sage/modules/free_quadratic_module_integer_symmetric.py +++ b/src/sage/modules/free_quadratic_module_integer_symmetric.py @@ -155,7 +155,7 @@ def IntegralLattice(data, basis=None): (see :mod:`Cartan types ` and :class:`CartanMatrix`):: - sage: IntegralLattice(["E", 7]) + sage: IntegralLattice(["E", 7]) # optional - sage.combinat Lattice of degree 7 and rank 7 over Integer Ring Standard basis Inner product matrix: @@ -166,20 +166,20 @@ def IntegralLattice(data, basis=None): [ 0 0 0 -1 2 -1 0] [ 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 -1 2] - sage: IntegralLattice(["A", 2]) + sage: IntegralLattice(["A", 2]) # optional - sage.combinat Lattice of degree 2 and rank 2 over Integer Ring Standard basis Inner product matrix: [ 2 -1] [-1 2] - sage: IntegralLattice("D3") + sage: IntegralLattice("D3") # optional - sage.combinat Lattice of degree 3 and rank 3 over Integer Ring Standard basis Inner product matrix: [ 2 -1 -1] [-1 2 0] [-1 0 2] - sage: IntegralLattice(["D", 4]) + sage: IntegralLattice(["D", 4]) # optional - sage.combinat Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -199,7 +199,7 @@ def IntegralLattice(data, basis=None): Inner product matrix: [0 1] [1 0] - sage: IntegralLattice(["A", 3], [[1,1,1]]) + sage: IntegralLattice(["A", 3], [[1,1,1]]) # optional - sage.combinat Lattice of degree 3 and rank 1 over Integer Ring Basis matrix: [1 1 1] @@ -212,7 +212,7 @@ def IntegralLattice(data, basis=None): Basis matrix: [1 1 1 1] Standard scalar product - sage: IntegralLattice("A2", [[1,1]]) + sage: IntegralLattice("A2", [[1,1]]) # optional - sage.combinat Lattice of degree 2 and rank 1 over Integer Ring Basis matrix: [1 1] @@ -222,11 +222,11 @@ def IntegralLattice(data, basis=None): TESTS:: - sage: IntegralLattice(["A", 1, 1]) + sage: IntegralLattice(["A", 1, 1]) # optional - sage.combinat Traceback (most recent call last): ... ValueError: lattices must be nondegenerate; use FreeQuadraticModule instead - sage: IntegralLattice(["D", 3, 1]) + sage: IntegralLattice(["D", 3, 1]) # optional - sage.combinat Traceback (most recent call last): ... ValueError: lattices must be nondegenerate; use FreeQuadraticModule instead @@ -272,11 +272,11 @@ def IntegralLatticeDirectSum(Lattices, return_embeddings=False): EXAMPLES:: sage: from sage.modules.free_quadratic_module_integer_symmetric import IntegralLatticeDirectSum - sage: L1 = IntegralLattice("D4") - sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) - sage: L3 = IntegralLattice("A4", [[0, 1, 1, 2], [1, 2, 3, 1]]) - sage: Lattices = [L1, L2, L3] - sage: IntegralLatticeDirectSum([L1, L2, L3]) + sage: L1 = IntegralLattice("D4") # optional - sage.combinat + sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) # optional - sage.combinat + sage: L3 = IntegralLattice("A4", [[0, 1, 1, 2], [1, 2, 3, 1]]) # optional - sage.combinat + sage: Lattices = [L1, L2, L3] # optional - sage.combinat + sage: IntegralLatticeDirectSum([L1, L2, L3]) # optional - sage.combinat Lattice of degree 11 and rank 7 over Integer Ring Basis matrix: [1 0 0 0 0 0 0 0 0 0 0] @@ -298,17 +298,17 @@ def IntegralLatticeDirectSum(Lattices, return_embeddings=False): [ 0 0 0 0 0 0 0 -1 2 -1 0] [ 0 0 0 0 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 0 0 0 0 -1 2] - sage: [L, phi] = IntegralLatticeDirectSum([L1, L2, L3], True) - sage: LL3 = L.sublattice(phi[2].image().basis_matrix()) - sage: L3.discriminant() == LL3.discriminant() + sage: [L, phi] = IntegralLatticeDirectSum([L1, L2, L3], True) # optional - sage.combinat + sage: LL3 = L.sublattice(phi[2].image().basis_matrix()) # optional - sage.combinat + sage: L3.discriminant() == LL3.discriminant() # optional - sage.combinat True - sage: x = L3([1, 2, 3, 1]) - sage: phi[2](x).inner_product(phi[2](x)) == x.inner_product(x) + sage: x = L3([1, 2, 3, 1]) # optional - sage.combinat + sage: phi[2](x).inner_product(phi[2](x)) == x.inner_product(x) # optional - sage.combinat True TESTS:: - sage: IntegralLatticeDirectSum([IntegralLattice("D4")]) + sage: IntegralLatticeDirectSum([IntegralLattice("D4")]) # optional - sage.combinat Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -318,9 +318,9 @@ def IntegralLatticeDirectSum(Lattices, return_embeddings=False): [ 0 -1 0 2] sage: L1 = IntegralLattice(2 * matrix.identity(2), [[1/2, 1/2]]) - sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) - sage: [L, phi] = IntegralLatticeDirectSum([L1, L2], True) - sage: L + sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) # optional - sage.combinat + sage: [L, phi] = IntegralLatticeDirectSum([L1, L2], True) # optional - sage.combinat + sage: L # optional - sage.combinat Lattice of degree 5 and rank 2 over Integer Ring Basis matrix: [1/2 1/2 0 0 0] @@ -416,18 +416,18 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): Inner product matrix: [4]]] - sage: L1 = IntegralLattice([[2]]) - sage: L2 = IntegralLattice([[2]]) - sage: AL1 = L1.discriminant_group() - sage: AL2 = L2.discriminant_group() - sage: AL1 + sage: L1 = IntegralLattice([[2]]) # optional - sage.combinat + sage: L2 = IntegralLattice([[2]]) # optional - sage.combinat + sage: AL1 = L1.discriminant_group() # optional - sage.combinat + sage: AL2 = L2.discriminant_group() # optional - sage.combinat + sage: AL1 # optional - sage.combinat Finite quadratic module over Integer Ring with invariants (2,) Gram matrix of the quadratic form with values in Q/2Z: [1/2] - sage: g1 = L1.discriminant_group().gens()[0] - sage: g2 = L2.discriminant_group().gens()[0] - sage: glue = [[g1, g2]] - sage: IntegralLatticeGluing([L1, L2], glue) + sage: g1 = L1.discriminant_group().gens()[0] # optional - sage.combinat + sage: g2 = L2.discriminant_group().gens()[0] # optional - sage.combinat + sage: glue = [[g1, g2]] # optional - sage.combinat + sage: IntegralLatticeGluing([L1, L2], glue) # optional - sage.combinat Lattice of degree 2 and rank 2 over Integer Ring Basis matrix: [1/2 1/2] @@ -436,13 +436,13 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): [2 0] [0 2] - sage: L1 = IntegralLattice("A4") - sage: L2 = IntegralLattice("A4") - sage: g1 = L1.discriminant_group().gens()[0] - sage: g2 = L2.discriminant_group().gens()[0] - sage: glue = [[g1, 2 * g2]] - sage: [V, phi] = IntegralLatticeGluing([L1, L2], glue, True) - sage: V + sage: L1 = IntegralLattice("A4") # optional - sage.combinat + sage: L2 = IntegralLattice("A4") # optional - sage.combinat + sage: g1 = L1.discriminant_group().gens()[0] # optional - sage.combinat + sage: g2 = L2.discriminant_group().gens()[0] # optional - sage.combinat + sage: glue = [[g1, 2 * g2]] # optional - sage.combinat + sage: [V, phi] = IntegralLatticeGluing([L1, L2], glue, True) # optional - sage.combinat + sage: V # optional - sage.combinat Lattice of degree 8 and rank 8 over Integer Ring Basis matrix: [1/5 2/5 3/5 4/5 2/5 4/5 1/5 3/5] @@ -462,7 +462,7 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): [ 0 0 0 0 -1 2 -1 0] [ 0 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 0 -1 2] - sage: V.sublattice(phi[0].image().basis_matrix()) + sage: V.sublattice(phi[0].image().basis_matrix()) # optional - sage.combinat Lattice of degree 8 and rank 4 over Integer Ring Basis matrix: [1 0 0 0 0 0 0 0] @@ -481,8 +481,8 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): Different gluings can be composed:: - sage: D4 = IntegralLattice("D4") - sage: D4.discriminant_group() + sage: D4 = IntegralLattice("D4") # optional - sage.combinat + sage: D4.discriminant_group() # optional - sage.combinat Finite quadratic module over Integer Ring with invariants (2, 2) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] @@ -493,23 +493,23 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): Gram matrix of the quadratic form with values in Q/2Z: [1/2 0] [ 0 1/2] - sage: g1 = D4.discriminant_group().gens()[0] + sage: g1 = D4.discriminant_group().gens()[0] # optional - sage.combinat sage: g2 = L2.discriminant_group().gens()[0] + L2.discriminant_group().gens()[1] - sage: D6, phi = IntegralLatticeGluing([D4, L2], [[g1, g2]], True) - sage: AD6 = D6.discriminant_group() - sage: AD6.normal_form() + sage: D6, phi = IntegralLatticeGluing([D4, L2], [[g1, g2]], True) # optional - sage.combinat + sage: AD6 = D6.discriminant_group() # optional - sage.combinat + sage: AD6.normal_form() # optional - sage.combinat Finite quadratic module over Integer Ring with invariants (2, 2) Gram matrix of the quadratic form with values in Q/2Z: [3/2 0] [ 0 3/2] - sage: f1, g1 = AD6.normal_form().gens() + sage: f1, g1 = AD6.normal_form().gens() # optional - sage.combinat sage: f2, g2 = L2.discriminant_group().gens() - sage: E8, psi = IntegralLatticeGluing([D6, L2], [[f1, f2], [g1, g2]], True) - sage: D4embed = E8.sublattice(psi[0](phi[0].image()).basis_matrix()) - sage: x = D4([1, 0, 0, 0]) - sage: psi[0](phi[0](x)).inner_product(psi[0](phi[0](x)))==x.inner_product(x) + sage: E8, psi = IntegralLatticeGluing([D6, L2], [[f1, f2], [g1, g2]], True) # optional - sage.combinat + sage: D4embed = E8.sublattice(psi[0](phi[0].image()).basis_matrix()) # optional - sage.combinat + sage: x = D4([1, 0, 0, 0]) # optional - sage.combinat + sage: psi[0](phi[0](x)).inner_product(psi[0](phi[0](x))) == x.inner_product(x) # optional - sage.combinat True - sage: D4embed + sage: D4embed # optional - sage.combinat Lattice of degree 8 and rank 4 over Integer Ring Basis matrix: [1 0 0 0 0 0 0 0] @@ -528,27 +528,28 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): The input may be a list of three or more lattices:: - sage: A7 = IntegralLattice("A7") - sage: D5 = IntegralLattice("D5") - sage: gA7 = A7.discriminant_group().gens()[0] - sage: gD5 = D5.discriminant_group().gens()[0] - sage: [L, phi] = IntegralLatticeGluing([A7, A7, D5, D5], + sage: A7 = IntegralLattice("A7") # optional - sage.combinat + sage: D5 = IntegralLattice("D5") # optional - sage.combinat + sage: gA7 = A7.discriminant_group().gens()[0] # optional - sage.combinat + sage: gD5 = D5.discriminant_group().gens()[0] # optional - sage.combinat + sage: [L, phi] = IntegralLatticeGluing([A7, A7, D5, D5], # optional - sage.combinat ....: [[gA7, gA7, gD5, 2 * gD5], ....: [gA7, 7 * gA7, 2 * gD5, gD5]], True) - sage: L.determinant() + sage: L.determinant() # optional - sage.combinat 1 - sage: B = phi[0].matrix() - sage: B*L.gram_matrix()*B.transpose()==A7.gram_matrix() + sage: B = phi[0].matrix() # optional - sage.combinat + sage: B*L.gram_matrix()*B.transpose() == A7.gram_matrix() # optional - sage.combinat True The gluing takes place in the direct sum of the respective ambient spaces:: - sage: L1 = IntegralLattice("D4", [[1, 1, 0, 0], [0, 1, 1, 0]]) - sage: L2 = IntegralLattice("E6", [[0, 2, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1]]) - sage: [f1, f2] = L1.discriminant_group().gens() - sage: [g1, g2] = L2.discriminant_group().gens() - sage: [L, phi] = IntegralLatticeGluing([L1, L2], [[f1, g1], [f2, 2 * g2]], True) - sage: phi[0] + sage: L1 = IntegralLattice("D4", [[1, 1, 0, 0], [0, 1, 1, 0]]) # optional - sage.combinat + sage: L2 = IntegralLattice("E6", [[0, 2, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1]]) # optional - sage.combinat + sage: [f1, f2] = L1.discriminant_group().gens() # optional - sage.combinat + sage: [g1, g2] = L2.discriminant_group().gens() # optional - sage.combinat + sage: [L, phi] = IntegralLatticeGluing([L1, L2], # optional - sage.combinat + ....: [[f1, g1], [f2, 2 * g2]], True) + sage: phi[0] # optional - sage.combinat Free module morphism defined by the matrix [ 2 2 -2 -1] [ 0 2 -1 0] @@ -578,8 +579,8 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): [ 0 0 0 0 0 -1 -1 2 -1 0] [ 0 0 0 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 0 0 0 -1 2] - sage: B = phi[0].matrix() - sage: B * L.gram_matrix() * B.transpose()==L1.gram_matrix() + sage: B = phi[0].matrix() # optional - sage.combinat + sage: B * L.gram_matrix() * B.transpose() == L1.gram_matrix() # optional - sage.combinat True """ [direct_sum, phi] = IntegralLatticeDirectSum(Lattices, return_embeddings=True) @@ -623,7 +624,7 @@ class FreeQuadraticModule_integer_symmetric(FreeQuadraticModule_submodule_with_b EXAMPLES:: - sage: IntegralLattice("U",basis=[vector([1,1])]) + sage: IntegralLattice("U", basis=[vector([1,1])]) Lattice of degree 2 and rank 1 over Integer Ring Basis matrix: [1 1] @@ -695,8 +696,8 @@ def _repr_(self): EXAMPLES:: - sage: A2 = IntegralLattice("A2") - sage: A2 + sage: A2 = IntegralLattice("A2") # optional - sage.combinat + sage: A2 # optional - sage.combinat Lattice of degree 2 and rank 2 over Integer Ring Standard basis Inner product matrix: @@ -731,7 +732,7 @@ def is_even(self): sage: L = IntegralLattice(G) sage: L.is_even() False - sage: L = IntegralLattice("A2") + sage: L = IntegralLattice("A2") # optional - sage.combinat sage: L.is_even() True """ @@ -759,7 +760,7 @@ def dual_lattice(self): Since our lattices are always integral, a lattice is contained in its dual:: - sage: L.is_submodule(Ldual) + sage: L.is_submodule(Ldual) # optional - sage.combinat True """ return self.span(self.gram_matrix().inverse()*self.basis_matrix()) @@ -811,9 +812,9 @@ def discriminant_group(self, s=0): sage: for k in range(1,500): # long time ....: G = L.twist(k) ....: D = G.discriminant_group() - sage: tmp = gc.collect() - sage: tmp = gc.collect() - sage: len([a for a in gc.get_objects() if type(a)==type(L)])<=300 + sage: tmp = gc.collect() # optional - sage.combinat + sage: tmp = gc.collect() # optional - sage.combinat + sage: len([a for a in gc.get_objects() if type(a) == type(L)]) <= 300 # optional - sage.combinat True sage: gc.unfreeze() """ @@ -1029,12 +1030,12 @@ def maximal_overlattice(self, p=None): EXAMPLES:: - sage: L = IntegralLattice("A4").twist(25*89) - sage: L.maximal_overlattice().determinant() + sage: L = IntegralLattice("A4").twist(25*89) # optional - sage.combinat + sage: L.maximal_overlattice().determinant() # optional - sage.combinat 5 - sage: L.maximal_overlattice(89).determinant().factor() + sage: L.maximal_overlattice(89).determinant().factor() # optional - sage.combinat 5^9 - sage: L.maximal_overlattice(5).determinant().factor() + sage: L.maximal_overlattice(5).determinant().factor() # optional - sage.combinat 5 * 89^4 TESTS:: @@ -1181,24 +1182,24 @@ def orthogonal_group(self, gens=None, is_finite=None): [ 0 0 1 0] [ 0 0 -1 -1] [ 0 1 1 1] - sage: x*g + sage: x*g # optional - sage.combinat (-1, -1, -1, 0) sage: (x*g).parent() == A4 True - sage: (g*x).parent() + sage: (g*x).parent() # optional - sage.combinat Vector space of dimension 4 over Rational Field - sage: y = A4.discriminant_group().an_element() - sage: y*g + sage: y = A4.discriminant_group().an_element() # optional - sage.combinat + sage: y*g # optional - sage.combinat (4) If the group is finite we can compute the usual things:: - sage: Aut.order() + sage: Aut.order() # optional - sage.combinat 240 - sage: conj = Aut.conjugacy_classes_representatives() - sage: len(conj) + sage: conj = Aut.conjugacy_classes_representatives() # optional - sage.combinat + sage: len(conj) # optional - sage.combinat 14 - sage: Aut.structure_description() + sage: Aut.structure_description() # optional - sage.combinat 'C2 x S5' The lattice can live in a larger ambient space:: @@ -1342,7 +1343,7 @@ def tensor_product(self, other, discard_basis=False): [-2 1 1 0 0 0 4 -2 -2] [ 1 -2 0 0 0 0 -2 4 0] [ 1 0 -2 0 0 0 -2 0 4] - sage: L1.gram_matrix() + sage: L1.gram_matrix() # optional - sage.combinat [ 36 -12 -12 4] [-12 24 4 -8] [-12 4 24 -8] @@ -1398,10 +1399,10 @@ def minimum(self): EXAMPLES:: - sage: L = IntegralLattice('A2') - sage: L.minimum() + sage: L = IntegralLattice('A2') # optional - sage.combinat + sage: L.minimum() # optional - sage.combinat 2 - sage: L.twist(-1).minimum() + sage: L.twist(-1).minimum() # optional - sage.combinat -Infinity """ p, n = self.signature_pair() @@ -1424,10 +1425,10 @@ def maximum(self): EXAMPLES:: - sage: L = IntegralLattice('A2') - sage: L.maximum() + sage: L = IntegralLattice('A2') # optional - sage.combinat + sage: L.maximum() # optional - sage.combinat +Infinity - sage: L.twist(-1).maximum() + sage: L.twist(-1).maximum() # optional - sage.combinat -2 """ if self.rank() == 0: @@ -1448,8 +1449,8 @@ def LLL(self): EXAMPLES:: - sage: L = IntegralLattice('A2') - sage: L.lll() == L + sage: L = IntegralLattice('A2') # optional - sage.combinat + sage: L.lll() == L # optional - sage.combinat True sage: G = matrix(ZZ, 3, [0,1,0, 1,0,0, 0,0,7]) sage: V = matrix(ZZ, 3, [-14,-15,-15, -4,1,16, -5,-5,-4]) @@ -1495,10 +1496,10 @@ def short_vectors(self, n, **kwargs): EXAMPLES:: - sage: A2 = IntegralLattice('A2') - sage: A2.short_vectors(3) + sage: A2 = IntegralLattice('A2') # optional - sage.combinat + sage: A2.short_vectors(3) # optional - sage.combinat [[(0, 0)], [], [(1, 1), (-1, -1), (0, 1), (0, -1), (1, 0), (-1, 0)]] - sage: A2.short_vectors(3,up_to_sign_flag=True) + sage: A2.short_vectors(3,up_to_sign_flag=True) # optional - sage.combinat [[(0, 0)], [], [(1, 1), (0, 1), (1, 0)]] """ p, m = self.signature_pair() @@ -1525,8 +1526,8 @@ def twist(self, s, discard_basis=False): EXAMPLES:: - sage: L = IntegralLattice("A4") - sage: L.twist(3) + sage: L = IntegralLattice("A4") # optional - sage.combinat + sage: L.twist(3) # optional - sage.combinat Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -1588,15 +1589,15 @@ def local_modification(M, G, p, check=True): EXAMPLES:: sage: from sage.modules.free_quadratic_module_integer_symmetric import local_modification - sage: L = IntegralLattice("A3").twist(15) - sage: M = L.maximal_overlattice() - sage: for p in prime_divisors(L.determinant()): + sage: L = IntegralLattice("A3").twist(15) # optional - sage.combinat + sage: M = L.maximal_overlattice() # optional - sage.combinat + sage: for p in prime_divisors(L.determinant()): # optional - sage.combinat ....: M = local_modification(M, L.gram_matrix(), p) - sage: M.genus() == L.genus() + sage: M.genus() == L.genus() # optional - sage.combinat True - sage: L = IntegralLattice("D4").twist(3*4) - sage: M = L.maximal_overlattice() - sage: local_modification(M, L.gram_matrix(), 2) + sage: L = IntegralLattice("D4").twist(3*4) # optional - sage.combinat + sage: M = L.maximal_overlattice() # optional - sage.combinat + sage: local_modification(M, L.gram_matrix(), 2) # optional - sage.combinat Lattice of degree 4 and rank 4 over Integer Ring Basis matrix: [1/3 0 2/3 2/3] diff --git a/src/sage/modules/matrix_morphism.py b/src/sage/modules/matrix_morphism.py index 94069fcc603..4c68b029ec4 100644 --- a/src/sage/modules/matrix_morphism.py +++ b/src/sage/modules/matrix_morphism.py @@ -21,13 +21,13 @@ [0 0 1] sage: is_MatrixMorphism(m) True - sage: m.charpoly('x') + sage: m.charpoly('x') # optional - sage.libs.pari x^3 - 3*x^2 + 3*x - 1 sage: m.base_ring() Rational Field sage: m.det() 1 - sage: m.fcp('x') + sage: m.fcp('x') # optional - sage.libs.pari (x - 1)^3 sage: m.matrix() [1 0 0] @@ -523,9 +523,9 @@ def __mul__(self, right): Composite maps can be formed with matrix morphisms:: - sage: K. = NumberField(x^2 + 23) - sage: V, VtoK, KtoV = K.vector_space() - sage: f = V.hom([V.0 - V.1, V.0 + V.1])*KtoV; f + sage: K. = NumberField(x^2 + 23) # optional - sage.rings.number_field + sage: V, VtoK, KtoV = K.vector_space() # optional - sage.rings.number_field + sage: f = V.hom([V.0 - V.1, V.0 + V.1])*KtoV; f # optional - sage.rings.number_field Composite map: From: Number Field in a with defining polynomial x^2 + 23 To: Vector space of dimension 2 over Rational Field @@ -538,9 +538,9 @@ def __mul__(self, right): [ 1 1] Domain: Vector space of dimension 2 over Rational Field Codomain: Vector space of dimension 2 over Rational Field - sage: f(a) + sage: f(a) # optional - sage.rings.number_field (1, 1) - sage: V.hom([V.0 - V.1, V.0 + V.1], side="right")*KtoV + sage: V.hom([V.0 - V.1, V.0 + V.1], side="right")*KtoV # optional - sage.rings.number_field Composite map: From: Number Field in a with defining polynomial x^2 + 23 To: Vector space of dimension 2 over Rational Field @@ -835,7 +835,7 @@ def decomposition(self, *args, **kwds): EXAMPLES:: sage: V = ZZ^2; phi = V.hom([V.0+V.1, 2*V.1]) - sage: phi.decomposition() + sage: phi.decomposition() # optional - sage.libs.pari [ Free module of degree 2 and rank 1 over Integer Ring Echelon basis matrix: @@ -845,7 +845,7 @@ def decomposition(self, *args, **kwds): [ 1 -1] ] sage: phi2 = V.hom(phi.matrix(), side="right") - sage: phi2.decomposition() + sage: phi2.decomposition() # optional - sage.libs.pari [ Free module of degree 2 and rank 1 over Integer Ring Echelon basis matrix: @@ -878,7 +878,7 @@ def trace(self): EXAMPLES:: - sage: V = ZZ^2; phi = V.hom([V.0+V.1, 2*V.1]) + sage: V = ZZ^2; phi = V.hom([V.0 + V.1, 2*V.1]) sage: phi.trace() 3 """ @@ -890,7 +890,7 @@ def det(self): EXAMPLES:: - sage: V = ZZ^2; phi = V.hom([V.0+V.1, 2*V.1]) + sage: V = ZZ^2; phi = V.hom([V.0 + V.1, 2*V.1]) sage: phi.det() 2 """ @@ -904,10 +904,10 @@ def fcp(self, var='x'): EXAMPLES:: - sage: V = ZZ^2; phi = V.hom([V.0+V.1, 2*V.1]) - sage: phi.fcp() + sage: V = ZZ^2; phi = V.hom([V.0 + V.1, 2*V.1]) + sage: phi.fcp() # optional - sage.libs.pari (x - 2) * (x - 1) - sage: phi.fcp('T') + sage: phi.fcp('T') # optional - sage.libs.pari (T - 2) * (T - 1) """ return self.charpoly(var).factor() @@ -918,14 +918,14 @@ def kernel(self): EXAMPLES:: - sage: V = VectorSpace(QQ,3) + sage: V = VectorSpace(QQ, 3) sage: id = V.Hom(V)(identity_matrix(QQ,3)) sage: null = V.Hom(V)(0*identity_matrix(QQ,3)) sage: id.kernel() Vector space of degree 3 and dimension 0 over Rational Field Basis matrix: [] - sage: phi = V.Hom(V)(matrix(QQ,3,range(9))) + sage: phi = V.Hom(V)(matrix(QQ, 3, range(9))) sage: phi.kernel() Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: @@ -968,29 +968,29 @@ def image(self): EXAMPLES:: - sage: V = VectorSpace(QQ,3) + sage: V = VectorSpace(QQ, 3) sage: phi = V.Hom(V)(matrix(QQ, 3, range(9))) sage: phi.image() Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [ 1 0 -1] [ 0 1 2] - sage: hom(GF(7)^3, GF(7)^2, zero_matrix(GF(7), 3, 2)).image() + sage: hom(GF(7)^3, GF(7)^2, zero_matrix(GF(7), 3, 2)).image() # optional - sage.libs.pari Vector space of degree 2 and dimension 0 over Finite Field of size 7 Basis matrix: [] - sage: m = matrix(3, [1, 0, 0, 1, 0, 0, 0, 0, 1]); m + sage: m = matrix(3, [1, 0, 0, 1, 0, 0, 0, 0, 1]); m # optional - sage.libs.pari [1 0 0] [1 0 0] [0 0 1] - sage: f1 = V.hom(m) - sage: f2 = V.hom(m, side="right") - sage: f1.image() + sage: f1 = V.hom(m) # optional - sage.libs.pari + sage: f2 = V.hom(m, side="right") # optional - sage.libs.pari + sage: f1.image() # optional - sage.libs.pari Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [1 0 0] [0 0 1] - sage: f2.image() + sage: f2.image() # optional - sage.libs.pari Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [1 1 0] @@ -999,7 +999,7 @@ def image(self): Compute the image of the identity map on a ZZ-submodule:: - sage: V = (ZZ^2).span([[1,2],[3,4]]) + sage: V = (ZZ^2).span([[1,2], [3,4]]) sage: phi = V.Hom(V)(identity_matrix(ZZ,2)) sage: phi(V.0) == V.0 True @@ -1520,8 +1520,8 @@ def restrict(self, sub): Codomain: Free module of degree 2 and rank 1 over Integer Ring Echelon ... - sage: V = (QQ^2).span_of_basis([[1,2],[3,4]]) - sage: phi = V.hom([V.0+V.1, 2*V.1]) + sage: V = (QQ^2).span_of_basis([[1,2], [3,4]]) + sage: phi = V.hom([V.0 + V.1, 2*V.1]) sage: phi(V.1) == 2*V.1 True sage: W = span([V.1]) @@ -1532,12 +1532,12 @@ def restrict(self, sub): sage: psi = phi.restrict(W); psi Vector space morphism represented by the matrix: [2] - Domain: Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [ 1 4/3] + Domain: Vector space of degree 2 and dimension 1 over Rational Field + Basis matrix: + [ 1 4/3] Codomain: Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [ 1 4/3] + Basis matrix: + [ 1 4/3] sage: psi.domain() == W True sage: psi(W.0) == 2*W.0 @@ -1553,26 +1553,26 @@ def restrict(self, sub): Free module morphism defined by the matrix [ 1 1] [-1 1] - Domain: Free module of degree 3 and rank 2 over Integer Ring - Echelon basis matrix: - [0 2 0] - [0 0 2] + Domain: Free module of degree 3 and rank 2 over Integer Ring + Echelon basis matrix: + [0 2 0] + [0 0 2] Codomain: Free module of degree 3 and rank 2 over Integer Ring - Echelon basis matrix: - [0 2 0] - [0 0 2] + Echelon basis matrix: + [0 2 0] + [0 0 2] sage: h2.restrict(SV) Free module morphism defined as left-multiplication by the matrix [ 1 -1] [ 1 1] - Domain: Free module of degree 3 and rank 2 over Integer Ring - Echelon basis matrix: - [0 2 0] - [0 0 2] + Domain: Free module of degree 3 and rank 2 over Integer Ring + Echelon basis matrix: + [0 2 0] + [0 0 2] Codomain: Free module of degree 3 and rank 2 over Integer Ring - Echelon basis matrix: - [0 2 0] - [0 0 2] + Echelon basis matrix: + [0 2 0] + [0 0 2] """ if not self.is_endomorphism(): raise ArithmeticError("matrix morphism must be an endomorphism") @@ -1617,7 +1617,7 @@ def __init__(self, parent, A, copy_matrix=True, side='left'): sage: from sage.modules.matrix_morphism import MatrixMorphism sage: T = End(ZZ^3) - sage: M = MatrixSpace(ZZ,3) + sage: M = MatrixSpace(ZZ, 3) sage: I = M.identity_matrix() sage: A = MatrixMorphism(T, I) sage: loads(A.dumps()) == A @@ -1706,10 +1706,10 @@ def is_injective(self): sage: V1 = QQ^2 sage: V2 = QQ^3 - sage: phi = V1.hom(Matrix([[1,2,3],[4,5,6]]),V2) + sage: phi = V1.hom(Matrix([[1,2,3], [4,5,6]]),V2) sage: phi.is_injective() True - sage: psi = V2.hom(Matrix([[1,2],[3,4],[5,6]]),V1) + sage: psi = V2.hom(Matrix([[1,2], [3,4], [5,6]]),V1) sage: psi.is_injective() False @@ -1731,19 +1731,19 @@ def is_surjective(self): sage: V1 = QQ^2 sage: V2 = QQ^3 - sage: phi = V1.hom(Matrix([[1,2,3],[4,5,6]]), V2) + sage: phi = V1.hom(Matrix([[1,2,3], [4,5,6]]), V2) sage: phi.is_surjective() False - sage: psi = V2.hom(Matrix([[1,2],[3,4],[5,6]]), V1) + sage: psi = V2.hom(Matrix([[1,2], [3,4], [5,6]]), V1) sage: psi.is_surjective() True An example over a PID that is not `\ZZ`. :: - sage: R = PolynomialRing(QQ, 'x') + sage: R. = PolynomialRing(QQ) sage: A = R^2 sage: B = R^2 - sage: H = A.hom([B([x^2-1, 1]), B([x^2, 1])]) + sage: H = A.hom([B([x^2 - 1, 1]), B([x^2, 1])]) sage: H.image() Free module of degree 2 and rank 2 over Univariate Polynomial Ring in x over Rational Field Echelon basis matrix: @@ -1755,7 +1755,7 @@ def is_surjective(self): This tests if :trac:`11552` is fixed. :: sage: V = ZZ^2 - sage: m = matrix(ZZ, [[1,2],[0,2]]) + sage: m = matrix(ZZ, [[1,2], [0,2]]) sage: phi = V.hom(m, V) sage: phi.lift(vector(ZZ, [0, 1])) Traceback (most recent call last): diff --git a/src/sage/modules/quotient_module.py b/src/sage/modules/quotient_module.py index 10db2189997..59fa0503f44 100644 --- a/src/sage/modules/quotient_module.py +++ b/src/sage/modules/quotient_module.py @@ -47,10 +47,10 @@ class QuotientModule_free_ambient(Module_free_ambient): sage: N = M.submodule([vector([x - y, z]), vector([y*z, x*z])]) sage: M.quotient_module(N) Quotient module by Submodule of Ambient free module of rank 2 over - the integral domain Multivariate Polynomial Ring in x, y, z over Rational Field - Generated by the rows of the matrix: - [x - y z] - [ y*z x*z] + the integral domain Multivariate Polynomial Ring in x, y, z over Rational Field + Generated by the rows of the matrix: + [x - y z] + [ y*z x*z] """ def __init__(self, module, sub): """ @@ -96,10 +96,10 @@ def _repr_(self): sage: N = M.submodule([vector([x - y, z]), vector([y*z , x*z])]) sage: M.quotient_module(N) Quotient module by Submodule of Ambient free module of rank 2 over - the integral domain Multivariate Polynomial Ring in x, y, z over Rational Field - Generated by the rows of the matrix: - [x - y z] - [ y*z x*z] + the integral domain Multivariate Polynomial Ring in x, y, z over Rational Field + Generated by the rows of the matrix: + [x - y z] + [ y*z x*z] """ return "Quotient module by %s" % self._sub @@ -163,12 +163,12 @@ def _coerce_map_from_(self, M): sage: Q.coerce_map_from(M) Coercion map: From: Ambient free module of rank 2 over the integral domain - Multivariate Polynomial Ring in x, y, z over Rational Field - To: Quotient module by Submodule of Ambient free module of rank 2 - over the integral domain Multivariate Polynomial Ring in x, y, z over Rational Field - Generated by the rows of the matrix: - [x - y z] - [ y*z x*z] + Multivariate Polynomial Ring in x, y, z over Rational Field + To: Quotient module by Submodule of Ambient free module of rank 2 over the + integral domain Multivariate Polynomial Ring in x, y, z over Rational Field + Generated by the rows of the matrix: + [x - y z] + [ y*z x*z] """ if isinstance(M, FreeModule_ambient): return (self.base_ring().has_coerce_map_from(M.base_ring()) and @@ -277,11 +277,12 @@ def free_relations(self): sage: NQ = Q.submodule([Q([1, x])]) sage: QNQ = Q / NQ sage: QNQ.free_relations() - Submodule of Ambient free module of rank 2 over the integral domain Multivariate Polynomial Ring in x, y, z over Rational Field - Generated by the rows of the matrix: - [ 1 x] - [x - y z] - [ y*z x*z] + Submodule of Ambient free module of rank 2 over the integral domain + Multivariate Polynomial Ring in x, y, z over Rational Field + Generated by the rows of the matrix: + [ 1 x] + [x - y z] + [ y*z x*z] Note that this is different than the defining relations:: @@ -307,45 +308,54 @@ class FreeModule_ambient_field_quotient(FreeModule_ambient_field): EXAMPLES:: - sage: k. = QuadraticField(-1) - sage: A = k^3; V = A.span([[1,0,i], [2,i,0]]) - sage: W = A.span([[3,i,i]]) - sage: U = V/W; U - Vector space quotient V/W of dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I where - V: Vector space of degree 3 and dimension 2 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I - Basis matrix: - [ 1 0 i] - [ 0 1 -2] - W: Vector space of degree 3 and dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I - Basis matrix: - [ 1 1/3*i 1/3*i] - sage: U.V() - Vector space of degree 3 and dimension 2 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + sage: k. = QuadraticField(-1) # optional - sage.rings.number_field + sage: A = k^3; V = A.span([[1,0,i], [2,i,0]]) # optional - sage.rings.number_field + sage: W = A.span([[3,i,i]]) # optional - sage.rings.number_field + sage: U = V/W; U # optional - sage.rings.number_field + Vector space quotient V/W of dimension 1 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I where + V: Vector space of degree 3 and dimension 2 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I + Basis matrix: + [ 1 0 i] + [ 0 1 -2] + W: Vector space of degree 3 and dimension 1 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I + Basis matrix: + [ 1 1/3*i 1/3*i] + sage: U.V() # optional - sage.rings.number_field + Vector space of degree 3 and dimension 2 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I Basis matrix: [ 1 0 i] [ 0 1 -2] - sage: U.W() - Vector space of degree 3 and dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + sage: U.W() # optional - sage.rings.number_field + Vector space of degree 3 and dimension 1 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I Basis matrix: [ 1 1/3*i 1/3*i] - sage: U.quotient_map() + sage: U.quotient_map() # optional - sage.rings.number_field Vector space morphism represented by the matrix: [ 1] [3*i] - Domain: Vector space of degree 3 and dimension 2 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I - Basis matrix: - [ 1 0 i] - [ 0 1 -2] - Codomain: Vector space quotient V/W of dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I where - V: Vector space of degree 3 and dimension 2 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I - Basis matrix: - [ 1 0 i] - [ 0 1 -2] - W: Vector space of degree 3 and dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I - Basis matrix: - [ 1 1/3*i 1/3*i] - sage: Z = V.quotient(W) - sage: Z == U + Domain: Vector space of degree 3 and dimension 2 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I + Basis matrix: + [ 1 0 i] + [ 0 1 -2] + Codomain: Vector space quotient V/W of dimension 1 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I where + V: Vector space of degree 3 and dimension 2 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I + Basis matrix: + [ 1 0 i] + [ 0 1 -2] + W: Vector space of degree 3 and dimension 1 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I + Basis matrix: + [ 1 1/3*i 1/3*i] + sage: Z = V.quotient(W) # optional - sage.rings.number_field + sage: Z == U # optional - sage.rings.number_field True We create three quotient spaces and compare them:: @@ -406,7 +416,7 @@ def __init__(self, domain, sub, quotient_matrix, lift_matrix, inner_product_matr sage: Q(V.0) (1) - sage: Q( V.0 - 2/3*V.1 ) + sage: Q(V.0 - 2/3*V.1) (0) sage: v = Q.lift(Q.0); v (1, 0, -1, 1, 1) @@ -432,19 +442,19 @@ def _repr_(self): We create a quotient vector space over a finite field:: - sage: k. = GF(9); A = k^3; V = A.span_of_basis([[1,0,a], [a,a,1]]); W = V.span([V.1]) - sage: Q = V/W + sage: k. = GF(9); A = k^3; V = A.span_of_basis([[1,0,a], [a,a,1]]); W = V.span([V.1]) # optional - sage.libs.pari + sage: Q = V/W # optional - sage.libs.pari Note the type:: - sage: type(Q) + sage: type(Q) # optional - sage.libs.pari The string representation mentions that this is a quotient `V/W`, that the quotient has dimension 1 and is over a finite field, and also describes `V` and `W`:: - sage: Q._repr_() + sage: Q._repr_() # optional - sage.libs.pari 'Vector space quotient V/W of dimension 1 over Finite Field in a of size 3^2 where\nV: Vector space of degree 3 and dimension 2 over Finite Field in a of size 3^2\nUser basis matrix:\n[1 0 a]\n[a a 1]\nW: Vector space of degree 3 and dimension 1 over Finite Field in a of size 3^2\nBasis matrix:\n[ 1 1 a + 2]' """ return "%s space quotient V/W of dimension %s over %s where\nV: %s\nW: %s" % ( @@ -539,23 +549,23 @@ def _coerce_map_from_(self, M): Composite map: From: Ambient free module of rank 2 over the principal ideal domain Integer Ring To: Vector space quotient V/W of dimension 1 over Rational Field where - V: Vector space of dimension 2 over Rational Field - W: Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [1 2] + V: Vector space of dimension 2 over Rational Field + W: Vector space of degree 2 and dimension 1 over Rational Field + Basis matrix: + [1 2] Defn: Coercion map: From: Ambient free module of rank 2 over the principal ideal domain Integer Ring To: Vector space of dimension 2 over Rational Field then Vector space morphism represented by the matrix: - [ 1] - [-1/2] - Domain: Vector space of dimension 2 over Rational Field - Codomain: Vector space quotient V/W of dimension 1 over Rational Field where - V: Vector space of dimension 2 over Rational Field - W: Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [1 2] + [ 1] + [-1/2] + Domain: Vector space of dimension 2 over Rational Field + Codomain: Vector space quotient V/W of dimension 1 over Rational Field where + V: Vector space of dimension 2 over Rational Field + W: Vector space of degree 2 and dimension 1 over Rational Field + Basis matrix: + [1 2] Make sure :trac:`10513` is fixed (no coercion from an abstract vector space to an isomorphic quotient vector space):: @@ -592,12 +602,12 @@ def quotient_map(self): [ 1 0] [ 0 1] [-1/3 -2/3] - Domain: Vector space of dimension 3 over Rational Field + Domain: Vector space of dimension 3 over Rational Field Codomain: Vector space quotient V/W of dimension 2 over Rational Field where - V: Vector space of dimension 3 over Rational Field - W: Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [1 2 3] + V: Vector space of dimension 3 over Rational Field + W: Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: + [1 2 3] sage: M.quotient_map()( (QQ^3)([1,2,3]) ) (0, 0) @@ -616,11 +626,11 @@ def lift_map(self): Vector space morphism represented by the matrix: [1 0 0] [0 1 0] - Domain: Vector space quotient V/W of dimension 2 over Rational Field where - V: Vector space of dimension 3 over Rational Field - W: Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [1 2 3] + Domain: Vector space quotient V/W of dimension 2 over Rational Field where + V: Vector space of dimension 3 over Rational Field + W: Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: + [1 2 3] Codomain: Vector space of dimension 3 over Rational Field """ return self.__lift_map diff --git a/src/sage/modules/tensor_operations.py b/src/sage/modules/tensor_operations.py index fafd5cc3a89..808aa7237eb 100644 --- a/src/sage/modules/tensor_operations.py +++ b/src/sage/modules/tensor_operations.py @@ -119,7 +119,7 @@ def antisymmetrized_coordinate_sums(dim, n): EXAMPLES:: sage: from sage.modules.tensor_operations import antisymmetrized_coordinate_sums - sage: antisymmetrized_coordinate_sums(3, 2) + sage: antisymmetrized_coordinate_sums(3, 2) # optional - sage.groups ((0, 1) - (1, 0), (0, 2) - (2, 0), (1, 2) - (2, 1)) """ from sage.structure.formal_sum import FormalSum @@ -379,8 +379,8 @@ def _init_power_operation_vectors(self, i, linear_combinations): sage: Sym2_R = TensorOperation([R,R], operation='symmetric') sage: Sym2_R.vectors() # indirect doctest ((1, 0, 0), (1, 2, 0), (-1, -2, 0), (1, 4, 4), (-1, -4, -4)) - sage: Alt2_R = TensorOperation([R, R], operation='antisymmetric') - sage: Alt2_R.vectors() # indirect doctest + sage: Alt2_R = TensorOperation([R, R], operation='antisymmetric') # optional - sage.groups + sage: Alt2_R.vectors() # indirect doctest # optional - sage.groups ((2), (-2)) """ rays = [self._V[j].vectors()[k] for j, k in enumerate(i)] @@ -453,8 +453,8 @@ def _init_antisymmetric(self): sage: from sage.modules.tensor_operations import \ ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (1,2), (-1,-2)], QQ, 2) - sage: Alt2_R = TensorOperation([R, R], operation='antisymmetric') # indirect doctest - sage: sorted(Alt2_R._index_map.items()) + sage: Alt2_R = TensorOperation([R, R], operation='antisymmetric') # indirect doctest # optional - sage.groups + sage: sorted(Alt2_R._index_map.items()) # optional - sage.groups [((0, 1), 0), ((0, 2), 1)] """ n = len(self._V) @@ -517,17 +517,17 @@ def index_map(self, *i): sage: from sage.modules.tensor_operations import \ ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (0,1), (-2,-3)], QQ, 2) - sage: detR = TensorOperation([R]*2, 'antisymmetric') - sage: detR.index_map(1, 0) + sage: detR = TensorOperation([R]*2, 'antisymmetric') # optional - sage.groups + sage: detR.index_map(1, 0) # optional - sage.groups 0 - sage: detR.index_map(0, 1) + sage: detR.index_map(0, 1) # optional - sage.groups 0 TESTS:: - sage: sorted(detR._index_map.items()) + sage: sorted(detR._index_map.items()) # optional - sage.groups [((0, 1), 0), ((0, 2), 1), ((1, 2), 2)] - sage: detR.vectors() + sage: detR.vectors() # optional - sage.groups ((1), (-3), (2)) """ if len(i) == 1 and isinstance(i[0], (list, tuple)): @@ -553,10 +553,10 @@ def preimage(self): sage: from sage.modules.tensor_operations import \ ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (0,1), (-2,-3)], QQ, 2) - sage: detR = TensorOperation([R]*2, 'antisymmetric') - sage: sorted(detR.preimage()) + sage: detR = TensorOperation([R]*2, 'antisymmetric') # optional - sage.groups + sage: sorted(detR.preimage()) # optional - sage.groups [(0, 1), (0, 2), (1, 2)] - sage: sorted(detR.codomain()) + sage: sorted(detR.codomain()) # optional - sage.groups [0, 1, 2] """ return self._index_map.keys() @@ -574,10 +574,10 @@ def codomain(self): sage: from sage.modules.tensor_operations import \ ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (0,1), (-2,-3)], QQ, 2) - sage: detR = TensorOperation([R]*2, 'antisymmetric') - sage: sorted(detR.preimage()) + sage: detR = TensorOperation([R]*2, 'antisymmetric') # optional - sage.groups + sage: sorted(detR.preimage()) # optional - sage.groups [(0, 1), (0, 2), (1, 2)] - sage: sorted(detR.codomain()) + sage: sorted(detR.codomain()) # optional - sage.groups [0, 1, 2] """ return self._index_map.values() diff --git a/src/sage/modules/torsion_quadratic_module.py b/src/sage/modules/torsion_quadratic_module.py index 0f1a92d8c56..72147fe115f 100644 --- a/src/sage/modules/torsion_quadratic_module.py +++ b/src/sage/modules/torsion_quadratic_module.py @@ -165,7 +165,7 @@ def quadratic_product(self): sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: W = FreeQuadraticModule(ZZ, 2, 2*matrix.identity(2)) sage: V = (1/2) * W - sage: T = TorsionQuadraticModule(V,W) + sage: T = TorsionQuadraticModule(V, W) sage: x = T.gen(0) sage: x (1, 0) @@ -375,8 +375,8 @@ def all_submodules(self): EXAMPLES:: - sage: D = IntegralLattice("D4").discriminant_group() - sage: D.all_submodules() + sage: D = IntegralLattice("D4").discriminant_group() # optional - sage.combinat + sage: D.all_submodules() # optional - sage.combinat [Finite quadratic module over Integer Ring with invariants () Gram matrix of the quadratic form with values in Q/2Z: [], @@ -429,9 +429,9 @@ def brown_invariant(self): EXAMPLES:: - sage: L = IntegralLattice("D4") - sage: D = L.discriminant_group() - sage: D.brown_invariant() + sage: L = IntegralLattice("D4") # optional - sage.combinat + sage: D = L.discriminant_group() # optional - sage.combinat + sage: D.brown_invariant() # optional - sage.combinat 4 We require the quadratic form to be defined modulo `2 \ZZ`:: @@ -588,7 +588,7 @@ def genus(self, signature_pair): We can also compute the genus of an odd lattice from its discriminant form:: - sage: L = IntegralLattice(matrix.diagonal(range(1,5))) + sage: L = IntegralLattice(matrix.diagonal(range(1, 5))) sage: D = L.discriminant_group() sage: D.genus((4,0)) # optional - sage.libs.pari Genus of @@ -764,9 +764,9 @@ def is_genus(self, signature_pair, even=True): Let us see if there is a lattice in the genus defined by the same discriminant form but with a different signature:: - sage: D.is_genus((4,2)) + sage: D.is_genus((4,2)) # optional - sage.combinat False - sage: D.is_genus((16,2)) + sage: D.is_genus((16,2)) # optional - sage.combinat True """ s_plus = ZZ(signature_pair[0]) @@ -1014,7 +1014,7 @@ def normal_form(self, partial=False): [1/2 0 0] [ 0 1/4 0] [ 0 0 5/4] - sage: AL2.normal_form() + sage: AL2.normal_form() # optional - sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4, 4) Gram matrix of the quadratic form with values in Q/2Z: [1/2 0 0] @@ -1034,7 +1034,7 @@ def normal_form(self, partial=False): [ 1/12 1/6 1/36 1/9] [ 5/36 1/36 1/36 11/72] [ 1/36 1/9 11/72 1/36] - sage: T.normal_form() + sage: T.normal_form() # optional - sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (6, 6, 12, 12) Gram matrix of the quadratic form with values in Q/(1/3)Z: [ 1/6 1/12 0 0 0 0 0 0] @@ -1051,7 +1051,7 @@ def normal_form(self, partial=False): A degenerate case:: sage: T = TorsionQuadraticModule((1/6)*D4dual, D4, modulus=1/36) - sage: T.normal_form() + sage: T.normal_form() # optional - sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (6, 6, 12, 12) Gram matrix of the quadratic form with values in Q/(1/18)Z: [1/36 1/72 0 0 0 0 0 0] diff --git a/src/sage/modules/vector_integer_dense.pyx b/src/sage/modules/vector_integer_dense.pyx index 8c0f4e2416d..d1b653a59ce 100644 --- a/src/sage/modules/vector_integer_dense.pyx +++ b/src/sage/modules/vector_integer_dense.pyx @@ -7,7 +7,7 @@ AUTHOR: EXAMPLES:: - sage: v = vector(ZZ,[1,2,3,4,5]) + sage: v = vector(ZZ, [1,2,3,4,5]) sage: v (1, 2, 3, 4, 5) sage: 3*v @@ -316,10 +316,10 @@ cdef class Vector_integer_dense(free_module_element.FreeModuleElement): sage: A = random_matrix(ZZ,1,3) sage: v = A.row(0) - sage: vs = singular(v) - sage: vs._repr_() == '{},\n{},\n{}'.format(*v) + sage: vs = singular(v) # optional - sage.libs.singular + sage: vs._repr_() == '{},\n{},\n{}'.format(*v) # optional - sage.libs.singular True - sage: vs.type() + sage: vs.type() # optional - sage.libs.singular 'intvec' """ if singular is None: diff --git a/src/sage/modules/vector_modn_dense.pyx b/src/sage/modules/vector_modn_dense.pyx index 24851fd8b27..72124577e63 100644 --- a/src/sage/modules/vector_modn_dense.pyx +++ b/src/sage/modules/vector_modn_dense.pyx @@ -3,7 +3,7 @@ Vectors with integer mod `n` entries, with small `n` EXAMPLES:: - sage: v = vector(Integers(8),[1,2,3,4,5]) + sage: v = vector(Integers(8), [1,2,3,4,5]) sage: type(v) sage: v @@ -21,8 +21,8 @@ EXAMPLES:: sage: v * v 7 - sage: v = vector(Integers(8),[1,2,3,4,5]) - sage: u = vector(Integers(8),[1,2,3,4,4]) + sage: v = vector(Integers(8), [1,2,3,4,5]) + sage: u = vector(Integers(8), [1,2,3,4,4]) sage: v - u (0, 0, 0, 0, 1) sage: u - v @@ -45,9 +45,9 @@ We make a large zero vector:: We multiply a vector by a matrix:: - sage: a = (GF(97)^5)(range(5)) - sage: m = matrix(GF(97),5,range(25)) - sage: a*m + sage: a = (GF(97)^5)(range(5)) # optional - sage.rings.finite_rings + sage: m = matrix(GF(97), 5, range(25)) # optional - sage.rings.finite_rings + sage: a*m # optional - sage.rings.finite_rings (53, 63, 73, 83, 93) TESTS:: @@ -58,41 +58,41 @@ TESTS:: sage: v = vector(Integers(389), [1,2,3,4,5]) sage: loads(dumps(v)) == v True - sage: v = vector(Integers(next_prime(10^20)), [1,2,3,4,5]) - sage: loads(dumps(v)) == v + sage: v = vector(Integers(next_prime(10^20)), [1,2,3,4,5]) # optional - sage.libs.pari + sage: loads(dumps(v)) == v # optional - sage.libs.pari True - sage: K = GF(previous_prime(2^31)) - sage: v = vector(K, [42]); type(v[0]) + sage: K = GF(previous_prime(2^31)) # optional - sage.rings.finite_rings + sage: v = vector(K, [42]); type(v[0]) # optional - sage.rings.finite_rings - sage: ~v[0] + sage: ~v[0] # optional - sage.rings.finite_rings 2096353084 - sage: K = GF(next_prime(2^31)) - sage: v = vector(K, [42]); type(v[0]) + sage: K = GF(next_prime(2^31)) # optional - sage.rings.finite_rings + sage: v = vector(K, [42]); type(v[0]) # optional - sage.rings.finite_rings - sage: ~v[0] + sage: ~v[0] # optional - sage.rings.finite_rings 1482786336 - sage: w = vector(GF(11), [-1,0,0,0]) - sage: w.set_immutable() - sage: isinstance(hash(w), int) + sage: w = vector(GF(11), [-1,0,0,0]) # optional - sage.rings.finite_rings + sage: w.set_immutable() # optional - sage.rings.finite_rings + sage: isinstance(hash(w), int) # optional - sage.rings.finite_rings True Test that :trac:`28042` is fixed:: sage: p = 193379 - sage: K = GF(p) - sage: a = K(1) - sage: b = K(191495) - sage: c = K(109320) - sage: d = K(167667) - sage: e = 103937 - sage: a*c+b*d-e + sage: K = GF(p) # optional - sage.rings.finite_rings + sage: a = K(1) # optional - sage.rings.finite_rings + sage: b = K(191495) # optional - sage.rings.finite_rings + sage: c = K(109320) # optional - sage.rings.finite_rings + sage: d = K(167667) # optional - sage.rings.finite_rings + sage: e = 103937 # optional - sage.rings.finite_rings + sage: a*c + b*d - e # optional - sage.rings.finite_rings 102041 - sage: vector([a,b]) * vector([c,d]) - e + sage: vector([a,b]) * vector([c,d]) - e # optional - sage.rings.finite_rings 102041 - sage: type(vector([a,b]) * vector([c,d])) + sage: type(vector([a,b]) * vector([c,d])) # optional - sage.rings.finite_rings AUTHOR: @@ -197,15 +197,15 @@ cdef class Vector_modn_dense(free_module_element.FreeModuleElement): """ EXAMPLES:: - sage: v = vector(GF(5), [0,0,0,0]) - sage: v == 0 + sage: v = vector(GF(5), [0,0,0,0]) # optional - sage.rings.finite_rings + sage: v == 0 # optional - sage.rings.finite_rings True - sage: v == 1 + sage: v == 1 # optional - sage.rings.finite_rings False - sage: v == v + sage: v == v # optional - sage.rings.finite_rings True - sage: w = vector(GF(11), [-1,0,0,0]) - sage: w == w + sage: w = vector(GF(11), [-1,0,0,0]) # optional - sage.rings.finite_rings + sage: w == w # optional - sage.rings.finite_rings True """ cdef Py_ssize_t i diff --git a/src/sage/modules/vector_space_homspace.py b/src/sage/modules/vector_space_homspace.py index 13004ea14ce..699827203b2 100644 --- a/src/sage/modules/vector_space_homspace.py +++ b/src/sage/modules/vector_space_homspace.py @@ -38,9 +38,9 @@ a list of matrix representations, where these matrix representatives are relative to the bases of the domain and codomain. :: - sage: K = Hom(GF(3)^2, GF(3)^2) - sage: B = K.basis() - sage: for f in B: + sage: K = Hom(GF(3)^2, GF(3)^2) # optional - sage.rings.finite_rings + sage: B = K.basis() # optional - sage.rings.finite_rings + sage: for f in B: # optional - sage.rings.finite_rings ....: print(f) ....: print("\n") Vector space morphism represented by the matrix: @@ -359,10 +359,10 @@ def __call__(self, A, check=True, **kwds): TESTS:: - sage: V = GF(3)^0 - sage: W = GF(3)^1 - sage: H = V.Hom(W) - sage: H.zero().is_zero() + sage: V = GF(3)^0 # optional - sage.rings.finite_rings + sage: W = GF(3)^1 # optional - sage.rings.finite_rings + sage: H = V.Hom(W) # optional - sage.rings.finite_rings + sage: H.zero().is_zero() # optional - sage.rings.finite_rings True Previously the above code resulted in a TypeError because the diff --git a/src/sage/modules/vector_space_morphism.py b/src/sage/modules/vector_space_morphism.py index 8044ed8dd4c..44b7d169951 100644 --- a/src/sage/modules/vector_space_morphism.py +++ b/src/sage/modules/vector_space_morphism.py @@ -41,12 +41,12 @@ sage: F = Integers(13) sage: D = F^3 sage: C = F^2 - sage: x, y, z = var('x y z') - sage: f(x, y, z) = [2*x + 3*y + 5*z, x + z] - sage: rho = linear_transformation(D, C, f) - sage: f(1, 2, 3) + sage: x, y, z = var('x y z') # optional - sage.symbolic + sage: f(x, y, z) = [2*x + 3*y + 5*z, x + z] # optional - sage.symbolic + sage: rho = linear_transformation(D, C, f) # optional - sage.symbolic + sage: f(1, 2, 3) # optional - sage.symbolic (23, 4) - sage: rho([1, 2, 3]) + sage: rho([1, 2, 3]) # optional - sage.symbolic (10, 4) A "vector space homspace" is the set of all linear transformations @@ -70,19 +70,21 @@ A homomorphism may also be created via a method on the domain. :: - sage: F = QQ[sqrt(3)] - sage: a = F.gen(0) - sage: D = F^2 - sage: C = F^2 - sage: A = matrix(F, [[a, 1], [2*a, 2]]) - sage: psi = D.hom(A, C) - sage: psi + sage: F = QQ[sqrt(3)] # optional - sage.rings.number_field sage.symbolic + sage: a = F.gen(0) # optional - sage.rings.number_field sage.symbolic + sage: D = F^2 # optional - sage.rings.number_field sage.symbolic + sage: C = F^2 # optional - sage.rings.number_field sage.symbolic + sage: A = matrix(F, [[a, 1], [2*a, 2]]) # optional - sage.rings.number_field sage.symbolic + sage: psi = D.hom(A, C) # optional - sage.rings.number_field sage.symbolic + sage: psi # optional - sage.rings.number_field sage.symbolic Vector space morphism represented by the matrix: [ sqrt3 1] [2*sqrt3 2] - Domain: Vector space of dimension 2 over Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? - Codomain: Vector space of dimension 2 over Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? - sage: psi([1, 4]) + Domain: Vector space of dimension 2 over Number Field in sqrt3 + with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? + Codomain: Vector space of dimension 2 over Number Field in sqrt3 + with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? + sage: psi([1, 4]) # optional - sage.rings.number_field sage.symbolic (9*sqrt3, 9) Properties @@ -149,10 +151,10 @@ matrix representation used to represent linear transformations are relative to the bases of both the domain and codomain. :: - sage: A = graphs.PetersenGraph().adjacency_matrix() + sage: A = graphs.PetersenGraph().adjacency_matrix() # optional - sage.graphs sage: V = QQ^10 - sage: phi = linear_transformation(V, V, A) - sage: phi + sage: phi = linear_transformation(V, V, A) # optional - sage.graphs + sage: phi # optional - sage.graphs Vector space morphism represented by the matrix: [0 1 0 0 1 1 0 0 0 0] [1 0 1 0 0 0 1 0 0 0] @@ -167,13 +169,13 @@ Domain: Vector space of dimension 10 over Rational Field Codomain: Vector space of dimension 10 over Rational Field - sage: B1 = [V.gen(i) + V.gen(i+1) for i in range(9)] + [V.gen(9)] - sage: B2 = [V.gen(0)] + [-V.gen(i-1) + V.gen(i) for i in range(1,10)] - sage: D = V.subspace_with_basis(B1) - sage: C = V.subspace_with_basis(B2) - sage: rho = phi.restrict_codomain(C) - sage: zeta = rho.restrict_domain(D) - sage: zeta + sage: B1 = [V.gen(i) + V.gen(i+1) for i in range(9)] + [V.gen(9)] # optional - sage.graphs + sage: B2 = [V.gen(0)] + [-V.gen(i-1) + V.gen(i) for i in range(1,10)] # optional - sage.graphs + sage: D = V.subspace_with_basis(B1) # optional - sage.graphs + sage: C = V.subspace_with_basis(B2) # optional - sage.graphs + sage: rho = phi.restrict_codomain(C) # optional - sage.graphs + sage: zeta = rho.restrict_domain(D) # optional - sage.graphs + sage: zeta # optional - sage.graphs Vector space morphism represented by the matrix: [6 5 4 3 3 2 1 0 0 0] [6 5 4 3 2 2 2 1 0 0] @@ -215,16 +217,16 @@ matrix that has well-behaved eigenvalues, as part of showing that these do not change as the representation changes. :: - sage: A = graphs.PetersenGraph().adjacency_matrix() + sage: A = graphs.PetersenGraph().adjacency_matrix() # optional - sage.graphs sage: V = QQ^10 - sage: phi = linear_transformation(V, V, A) - sage: phi.eigenvalues() + sage: phi = linear_transformation(V, V, A) # optional - sage.graphs + sage: phi.eigenvalues() # optional - sage.graphs [3, -2, -2, -2, -2, 1, 1, 1, 1, 1] - sage: B1 = [V.gen(i) + V.gen(i+1) for i in range(9)] + [V.gen(9)] - sage: C = V.subspace_with_basis(B1) - sage: zeta = phi.restrict(C) - sage: zeta + sage: B1 = [V.gen(i) + V.gen(i+1) for i in range(9)] + [V.gen(9)] # optional - sage.graphs + sage: C = V.subspace_with_basis(B1) # optional - sage.graphs + sage: zeta = phi.restrict(C) # optional - sage.graphs + sage: zeta # optional - sage.graphs Vector space morphism represented by the matrix: [ 1 0 1 -1 2 -1 2 -2 2 -2] [ 1 0 1 0 0 0 1 0 0 0] @@ -261,7 +263,7 @@ [0 0 0 0 0 0 0 0 1 1] [0 0 0 0 0 0 0 0 0 1] - sage: zeta.eigenvalues() + sage: zeta.eigenvalues() # optional - sage.graphs [3, -2, -2, -2, -2, 1, 1, 1, 1, 1] Equality @@ -495,10 +497,10 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): Domain: Vector space of dimension 3 over Rational Field Codomain: Vector space of dimension 2 over Rational Field - sage: x, y, z = var('x y z') - sage: h(x, y, z) = [2*x + z, 5*y] - sage: zeta = linear_transformation(QQ^3, QQ^2, h) - sage: zeta + sage: x, y, z = var('x y z') # optional - sage.symbolic + sage: h(x, y, z) = [2*x + z, 5*y] # optional - sage.symbolic + sage: zeta = linear_transformation(QQ^3, QQ^2, h) # optional - sage.symbolic + sage: zeta # optional - sage.symbolic Vector space morphism represented by the matrix: [2 0] [0 5] @@ -508,7 +510,7 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): sage: phi == rho True - sage: rho == zeta + sage: rho == zeta # optional - sage.symbolic True @@ -536,10 +538,10 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): [2 5] [3 7] - sage: s, t = var('s t') - sage: h(s, t) = [(-4/5)*s + (1/5)*t, (97/5)*s + (-13/5)*t] - sage: zeta = linear_transformation(D, C, h) - sage: zeta.matrix() + sage: s, t = var('s t') # optional - sage.symbolic + sage: h(s, t) = [(-4/5)*s + (1/5)*t, (97/5)*s + (-13/5)*t] # optional - sage.symbolic + sage: zeta = linear_transformation(D, C, h) # optional - sage.symbolic + sage: zeta.matrix() # optional - sage.symbolic [2 5] [3 7] @@ -547,21 +549,21 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): elements of the domain. :: sage: x = polygen(QQ) - sage: F. = NumberField(x^3+x+1) - sage: u = vector(F, [1, a, a^2]) - sage: v = vector(F, [a, a^2, 2]) - sage: w = u + v - sage: D = F^3 - sage: C = F^3 - sage: rho = linear_transformation(D, C, [u, v, w]) - sage: rho.matrix() + sage: F. = NumberField(x^3 + x + 1) # optional - sage.rings.number_field + sage: u = vector(F, [1, a, a^2]) # optional - sage.rings.number_field + sage: v = vector(F, [a, a^2, 2]) # optional - sage.rings.number_field + sage: w = u + v # optional - sage.rings.number_field + sage: D = F^3 # optional - sage.rings.number_field + sage: C = F^3 # optional - sage.rings.number_field + sage: rho = linear_transformation(D, C, [u, v, w]) # optional - sage.rings.number_field + sage: rho.matrix() # optional - sage.rings.number_field [ 1 a a^2] [ a a^2 2] [ a + 1 a^2 + a a^2 + 2] - sage: C = (F^3).subspace_with_basis([u, v]) - sage: D = (F^3).subspace_with_basis([u, v]) - sage: psi = linear_transformation(C, D, [u+v, u-v]) - sage: psi.matrix() + sage: C = (F^3).subspace_with_basis([u, v]) # optional - sage.rings.number_field + sage: D = (F^3).subspace_with_basis([u, v]) # optional - sage.rings.number_field + sage: psi = linear_transformation(C, D, [u+v, u-v]) # optional - sage.rings.number_field + sage: psi.matrix() # optional - sage.rings.number_field [ 1 1] [ 1 -1] @@ -655,30 +657,30 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): A Sage symbolic function can come in a variety of forms that are not representative of a linear transformation. :: - sage: x, y = var('x, y') - sage: f(x, y) = [y, x, y] - sage: linear_transformation(QQ^3, QQ^3, f) + sage: x, y = var('x, y') # optional - sage.symbolic + sage: f(x, y) = [y, x, y] # optional - sage.symbolic + sage: linear_transformation(QQ^3, QQ^3, f) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: symbolic function has the wrong number of inputs for domain - sage: linear_transformation(QQ^2, QQ^2, f) + sage: linear_transformation(QQ^2, QQ^2, f) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: symbolic function has the wrong number of outputs for codomain - sage: x, y = var('x y') - sage: f(x, y) = [y, x*y] - sage: linear_transformation(QQ^2, QQ^2, f) + sage: x, y = var('x y') # optional - sage.symbolic + sage: f(x, y) = [y, x*y] # optional - sage.symbolic + sage: linear_transformation(QQ^2, QQ^2, f) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: symbolic function must be linear in all the inputs: unable to convert y to a rational - sage: x, y = var('x y') - sage: f(x, y) = [x, 2*y] + sage: x, y = var('x y') # optional - sage.symbolic + sage: f(x, y) = [x, 2*y] # optional - sage.symbolic sage: C = (QQ^2).span([vector(QQ, [1, 1])]) - sage: linear_transformation(QQ^2, C, f) + sage: linear_transformation(QQ^2, C, f) # optional - sage.symbolic Traceback (most recent call last): ... ArithmeticError: some image of the function is not in the codomain, because @@ -902,15 +904,15 @@ def is_invertible(self): A non-invertible linear transformation, an endomorphism of a vector space over a finite field. :: - sage: F. = GF(11^2) - sage: A = matrix(F, [[6*a + 3, 8*a + 2, 10*a + 3], + sage: F. = GF(11^2) # optional - sage.rings.finite_rings + sage: A = matrix(F, [[6*a + 3, 8*a + 2, 10*a + 3], # optional - sage.rings.finite_rings ....: [2*a + 7, 4*a + 3, 2*a + 3], ....: [9*a + 2, 10*a + 10, 3*a + 3]]) - sage: A.nullity() + sage: A.nullity() # optional - sage.rings.finite_rings 1 - sage: E = End(F^3) - sage: zeta = E(A) - sage: zeta.is_invertible() + sage: E = End(F^3) # optional - sage.rings.finite_rings + sage: zeta = E(A) # optional - sage.rings.finite_rings + sage: zeta.is_invertible() # optional - sage.rings.finite_rings False """ # endomorphism or not, this is equivalent to invertibility of diff --git a/src/sage/modules/with_basis/cell_module.py b/src/sage/modules/with_basis/cell_module.py index c51d43c32b6..8c2fe5a3ac4 100644 --- a/src/sage/modules/with_basis/cell_module.py +++ b/src/sage/modules/with_basis/cell_module.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat r""" Cell modules """ diff --git a/src/sage/modules/with_basis/indexed_element.pyx b/src/sage/modules/with_basis/indexed_element.pyx index 06947bfb3b0..6a8685f37f9 100644 --- a/src/sage/modules/with_basis/indexed_element.pyx +++ b/src/sage/modules/with_basis/indexed_element.pyx @@ -82,9 +82,9 @@ cdef class IndexedFreeModuleElement(ModuleElement): sage: [i for i in sorted(f)] [('a', 1), ('c', 3)] - sage: s = SymmetricFunctions(QQ).schur() - sage: a = s([2,1]) + s([3]) - sage: [i for i in sorted(a)] + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: a = s([2,1]) + s([3]) # optional - sage.combinat + sage: [i for i in sorted(a)] # optional - sage.combinat [([2, 1], 1), ([3], 1)] """ return iter(self._monomial_coefficients.items()) @@ -107,11 +107,11 @@ cdef class IndexedFreeModuleElement(ModuleElement): sage: 'b' in f False - sage: s = SymmetricFunctions(QQ).schur() - sage: a = s([2,1]) + s([3]) - sage: Partition([2,1]) in a + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: a = s([2,1]) + s([3]) # optional - sage.combinat + sage: Partition([2,1]) in a # optional - sage.combinat True - sage: Partition([1,1,1]) in a + sage: Partition([1,1,1]) in a # optional - sage.combinat False """ deprecation(34509, "using 'index in vector' is deprecated; use 'index in vector.support()' instead") @@ -133,11 +133,11 @@ cdef class IndexedFreeModuleElement(ModuleElement): sage: hash(f) == hash(B['a'] + 4*B['c']) False - sage: F = RootSystem(['A',2]).ambient_space() - sage: f = F.simple_root(0) - sage: hash(f) == hash(F.simple_root(0)) + sage: F = RootSystem(['A',2]).ambient_space() # optional - sage.combinat + sage: f = F.simple_root(0) # optional - sage.combinat + sage: hash(f) == hash(F.simple_root(0)) # optional - sage.combinat True - sage: hash(f) == hash(F.simple_root(1)) + sage: hash(f) == hash(F.simple_root(1)) # optional - sage.combinat False This uses the recipe that was proposed for frozendicts in @@ -264,14 +264,14 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: s = SymmetricFunctions(QQ).schur() - sage: a = s([2,1])+2*s([3,2]) - sage: d = a.monomial_coefficients() - sage: type(d) + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: a = s([2,1])+2*s([3,2]) # optional - sage.combinat + sage: d = a.monomial_coefficients() # optional - sage.combinat + sage: type(d) # optional - sage.combinat <... 'dict'> - sage: d[ Partition([2,1]) ] + sage: d[ Partition([2,1]) ] # optional - sage.combinat 1 - sage: d[ Partition([3,2]) ] + sage: d[ Partition([3,2]) ] # optional - sage.combinat 2 """ if copy: @@ -347,17 +347,17 @@ cdef class IndexedFreeModuleElement(ModuleElement): """ TESTS:: - sage: M = QuasiSymmetricFunctions(QQ).M() - sage: ascii_art(M[1,3]**2) # indirect doctest + sage: M = QuasiSymmetricFunctions(QQ).M() # optional - sage.combinat + sage: ascii_art(M[1,3]**2) # indirect doctest # optional - sage.combinat 4*M + 2*M + 2*M + 2*M + 2*M + M *** ****** *** *** *** ****** *** * * **** *** ** * * *** * ** * * - sage: ascii_art(M.zero()) + sage: ascii_art(M.zero()) # optional - sage.combinat 0 - sage: DA = DescentAlgebra(QQ, 4) - sage: ascii_art(DA.an_element()) + sage: DA = DescentAlgebra(QQ, 4) # optional - sage.combinat + sage: ascii_art(DA.an_element()) # optional - sage.combinat 2*B + 2*B + 3*B * ** * * * ** @@ -424,8 +424,8 @@ cdef class IndexedFreeModuleElement(ModuleElement): """ TESTS:: - sage: M = QuasiSymmetricFunctions(QQ).M() - sage: unicode_art(M[1,1]**2) # indirect doctest + sage: M = QuasiSymmetricFunctions(QQ).M() # optional - sage.combinat + sage: unicode_art(M[1,1]**2) # indirect doctest # optional - sage.combinat 6*M + 2*M + 2*M + 2*M + M ┌┐ ┌┬┐ ┌┐ ┌┐ ┌┬┐ ├┤ ├┼┘ ┌┼┤ ├┤ ┌┼┼┘ @@ -435,7 +435,7 @@ cdef class IndexedFreeModuleElement(ModuleElement): The following test failed before :trac:`26850`:: - sage: unicode_art([M.zero()]) # indirect doctest + sage: unicode_art([M.zero()]) # indirect doctest # optional - sage.combinat [ 0 ] """ from sage.misc.repr import coeff_repr @@ -506,9 +506,9 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: QS3 = SymmetricGroupAlgebra(QQ,3) - sage: a = 2 + QS3([2,1,3]) - sage: latex(a) #indirect doctest + sage: QS3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat + sage: a = 2 + QS3([2,1,3]) # optional - sage.combinat + sage: latex(a) #indirect doctest # optional - sage.combinat 2 [1, 2, 3] + [2, 1, 3] :: @@ -568,10 +568,10 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: s = SymmetricFunctions(QQ).schur() - sage: a = s([2,1]) - sage: b = s([1,1,1]) - sage: a == b + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: a = s([2,1]) # optional - sage.combinat + sage: b = s([1,1,1]) # optional - sage.combinat + sage: a == b # optional - sage.combinat False .. TODO:: @@ -595,20 +595,20 @@ cdef class IndexedFreeModuleElement(ModuleElement): Traceback (most recent call last): ... TypeError: do not know how to make x (= 0) an element of self (=Free module generated by {1, 2, 3} over Rational Field) - sage: F = AlgebrasWithBasis(QQ).example() - sage: F.one() == 1 + sage: F = AlgebrasWithBasis(QQ).example() # optional - sage.combinat + sage: F.one() == 1 # optional - sage.combinat True - sage: 1 == F.one() + sage: 1 == F.one() # optional - sage.combinat True - sage: 2 * F.one() == int(2) + sage: 2 * F.one() == int(2) # optional - sage.combinat True - sage: int(2) == 2 * F.one() + sage: int(2) == 2 * F.one() # optional - sage.combinat True - sage: S = SymmetricFunctions(QQ); s = S.s(); p = S.p() - sage: p[2] == s[2] - s[1, 1] + sage: S = SymmetricFunctions(QQ); s = S.s(); p = S.p() # optional - sage.combinat + sage: p[2] == s[2] - s[1, 1] # optional - sage.combinat True - sage: p[2] == s[2] + sage: p[2] == s[2] # optional - sage.combinat False This feature is disputable, in particular since it can make @@ -618,19 +618,19 @@ cdef class IndexedFreeModuleElement(ModuleElement): can vary because their indices are incomparable with ``cmp``. The following test did fail before :trac:`12489` :: - sage: F = CombinatorialFreeModule(QQ, Subsets([1,2,3])) - sage: x = F.an_element() - sage: (x+F.zero()).terms() # random + sage: F = CombinatorialFreeModule(QQ, Subsets([1,2,3])) # optional - sage.combinat + sage: x = F.an_element() # optional - sage.combinat + sage: (x+F.zero()).terms() # random # optional - sage.combinat [2*B[{1}], 3*B[{2}], B[{}]] - sage: x.terms() # random + sage: x.terms() # random # optional - sage.combinat [2*B[{1}], B[{}], 3*B[{2}]] - sage: x+F.zero() == x + sage: x+F.zero() == x # optional - sage.combinat True TESTS:: sage: TestSuite(F1).run() - sage: TestSuite(F).run() + sage: TestSuite(F).run() # optional - sage.combinat """ cdef IndexedFreeModuleElement elt = other @@ -658,11 +658,11 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: s = SymmetricFunctions(QQ).schur() - sage: s([2,1]) + s([5,4]) # indirect doctest + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: s([2,1]) + s([5,4]) # indirect doctest # optional - sage.combinat s[2, 1] + s[5, 4] - sage: a = s([2,1]) + 0 - sage: len(a.monomial_coefficients()) + sage: a = s([2,1]) + 0 # optional - sage.combinat + sage: len(a.monomial_coefficients()) # optional - sage.combinat 1 """ return type(self)(self._parent, @@ -681,8 +681,8 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: s = SymmetricFunctions(QQ).schur() - sage: -s([2,1]) # indirect doctest + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: -s([2,1]) # indirect doctest # optional - sage.combinat -s[2, 1] """ return type(self)(self._parent, negate(self._monomial_coefficients)) @@ -698,8 +698,8 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: s = SymmetricFunctions(QQ).schur() - sage: s([2,1]) - s([5,4]) # indirect doctest + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: s([2,1]) - s([5,4]) # indirect doctest # optional - sage.combinat s[2, 1] - s[5, 4] """ return type(self)(self._parent, @@ -713,15 +713,15 @@ cdef class IndexedFreeModuleElement(ModuleElement): EXAMPLES:: - sage: p = Partition([2,1]) - sage: q = Partition([1,1,1]) - sage: s = SymmetricFunctions(QQ).schur() - sage: a = s(p) - sage: a[p] + sage: p = Partition([2,1]) # optional - sage.combinat + sage: q = Partition([1,1,1]) # optional - sage.combinat + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: a = s(p) # optional - sage.combinat + sage: a[p] # optional - sage.combinat 1 - sage: a[q] + sage: a[q] # optional - sage.combinat 0 - sage: a[[2,1]] + sage: a[[2,1]] # optional - sage.combinat Traceback (most recent call last): ... TypeError: unhashable type: 'list' @@ -770,23 +770,23 @@ cdef class IndexedFreeModuleElement(ModuleElement): More examples:: - sage: QS3 = SymmetricGroupAlgebra(QQ, 3) - sage: a = 2*QS3([1,2,3]) + 4*QS3([3,2,1]) - sage: a._vector_() + sage: QS3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat + sage: a = 2*QS3([1,2,3]) + 4*QS3([3,2,1]) # optional - sage.combinat + sage: a._vector_() # optional - sage.combinat (2, 0, 0, 0, 0, 4) - sage: a.to_vector() + sage: a.to_vector() # optional - sage.combinat (2, 0, 0, 0, 0, 4) - sage: vector(a) + sage: vector(a) # optional - sage.combinat (2, 0, 0, 0, 0, 4) - sage: a == QS3.from_vector(a.to_vector()) + sage: a == QS3.from_vector(a.to_vector()) # optional - sage.combinat True - sage: a.to_vector(sparse=True) + sage: a.to_vector(sparse=True) # optional - sage.combinat (2, 0, 0, 0, 0, 4) If ``new_base_ring`` is specified, then a vector over ``new_base_ring`` is returned:: - sage: a._vector_(RDF) + sage: a._vector_(RDF) # optional - sage.combinat (2.0, 0.0, 0.0, 0.0, 0.0, 4.0) .. NOTE:: @@ -864,18 +864,18 @@ cdef class IndexedFreeModuleElement(ModuleElement): example with polynomials or fraction fields (:trac:`8832`):: sage: P. = QQ['q'] - sage: V = CombinatorialFreeModule(P, Permutations()) - sage: el = V(Permutation([3,1,2])) - sage: (3/2)*el + sage: V = CombinatorialFreeModule(P, Permutations()) # optional - sage.combinat + sage: el = V(Permutation([3,1,2])) # optional - sage.combinat + sage: (3/2)*el # optional - sage.combinat 3/2*B[[3, 1, 2]] sage: P. = QQ['q'] sage: F = FractionField(P) - sage: V = CombinatorialFreeModule(F, Words()) - sage: w = Words()('abc') - sage: (1+q)*V(w) + sage: V = CombinatorialFreeModule(F, Words()) # optional - sage.combinat + sage: w = Words()('abc') # optional - sage.combinat + sage: (1+q)*V(w) # optional - sage.combinat (q+1)*B[word: abc] - sage: ((1+q)/q)*V(w) + sage: ((1+q)/q)*V(w) # optional - sage.combinat ((q+1)/q)*B[word: abc] .. TODO:: diff --git a/src/sage/modules/with_basis/invariant.py b/src/sage/modules/with_basis/invariant.py index 12565a411e2..1fa4c20c23f 100644 --- a/src/sage/modules/with_basis/invariant.py +++ b/src/sage/modules/with_basis/invariant.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.groups r""" Invariant modules """ diff --git a/src/sage/modules/with_basis/representation.py b/src/sage/modules/with_basis/representation.py index 44b9f6115e2..1ee49a740f7 100644 --- a/src/sage/modules/with_basis/representation.py +++ b/src/sage/modules/with_basis/representation.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.groups """ Representations of a semigroup diff --git a/src/sage/numerical/backends/ppl_backend.pyx b/src/sage/numerical/backends/ppl_backend.pyx index 1f50c4bdf11..f58e7729ae2 100644 --- a/src/sage/numerical/backends/ppl_backend.pyx +++ b/src/sage/numerical/backends/ppl_backend.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - pplpy """ PPL Backend @@ -60,7 +61,7 @@ cdef class PPLBackend(GenericBackend): Raise an error if a ``base_ring`` is requested that is not supported:: - sage: p = MixedIntegerLinearProgram(solver = "PPL", base_ring=AA) + sage: p = MixedIntegerLinearProgram(solver="PPL", base_ring=AA) # optional - sage.rings.number_field Traceback (most recent call last): ... TypeError: The PPL backend only supports rational data. diff --git a/src/sage/numerical/interactive_simplex_method.py b/src/sage/numerical/interactive_simplex_method.py index 26e332cd8d9..5b8e4a93fe2 100644 --- a/src/sage/numerical/interactive_simplex_method.py +++ b/src/sage/numerical/interactive_simplex_method.py @@ -64,7 +64,7 @@ Since it has only two variables, we can solve it graphically:: - sage: P.plot() + sage: P.plot() # optional - sage.plot Graphics object consisting of 19 graphics primitives @@ -202,7 +202,8 @@ from sage.rings.real_double import RDF from sage.rings.integer_ring import ZZ from sage.structure.all import SageObject -from sage.symbolic.ring import SR +from sage.misc.lazy_import import lazy_import +lazy_import("sage.symbolic.ring", "SR") # We produce rather complicated LaTeX code which needs some tweaks to be @@ -298,9 +299,9 @@ def _latex_product(coefficients, variables, sage: from sage.numerical.interactive_simplex_method import \ ....: _latex_product - sage: var("x, y") + sage: var("x, y") # optional - sage.symbolic (x, y) - sage: print(_latex_product([-1, 3], [x, y])) + sage: print(_latex_product([-1, 3], [x, y])) # optional - sage.symbolic - \mspace{-6mu}&\mspace{-6mu} x \mspace{-6mu}&\mspace{-6mu} + \mspace{-6mu}&\mspace{-6mu} 3 y """ entries = [] @@ -1534,19 +1535,19 @@ def plot(self, *args, **kwds): sage: b = (1000, 1500) sage: c = (10, 5) sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") - sage: p = P.plot() - sage: p.show() + sage: p = P.plot() # optional - sage.plot + sage: p.show() # optional - sage.plot In this case the plot works better with the following axes ranges:: - sage: p = P.plot(0, 1000, 0, 1500) - sage: p.show() + sage: p = P.plot(0, 1000, 0, 1500) # optional - sage.plot + sage: p.show() # optional - sage.plot TESTS: We check that zero objective can be dealt with:: - sage: InteractiveLPProblem(A, b, (0, 0), ["C", "B"], variable_type=">=").plot() + sage: InteractiveLPProblem(A, b, (0, 0), ["C", "B"], variable_type=">=").plot() # optional - sage.plot Graphics object consisting of 8 graphics primitives """ FP = self.plot_feasible_set(*args, **kwds) @@ -1611,13 +1612,13 @@ def plot_feasible_set(self, xmin=None, xmax=None, ymin=None, ymax=None, sage: b = (1000, 1500) sage: c = (10, 5) sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") - sage: p = P.plot_feasible_set() - sage: p.show() + sage: p = P.plot_feasible_set() # optional - sage.plot + sage: p.show() # optional - sage.plot In this case the plot works better with the following axes ranges:: - sage: p = P.plot_feasible_set(0, 1000, 0, 1500) - sage: p.show() + sage: p = P.plot_feasible_set(0, 1000, 0, 1500) # optional - sage.plot + sage: p.show() # optional - sage.plot """ if self.n() != 2: raise ValueError("only problems with 2 variables can be plotted") diff --git a/src/sage/numerical/knapsack.py b/src/sage/numerical/knapsack.py index f334c24b94b..9cfca7bba47 100644 --- a/src/sage/numerical/knapsack.py +++ b/src/sage/numerical/knapsack.py @@ -280,8 +280,6 @@ def largest_less_than(self, N): ... ValueError: seq must be a super-increasing sequence """ - from sage.functions.other import Function_floor - floor = Function_floor() # input error handling if len(self._seq) == 0: raise TypeError("self must be a non-empty list of integers.") @@ -293,7 +291,7 @@ def largest_less_than(self, N): low = 0 high = len(self._seq) - 1 while low <= high: - mid = floor((low + high) / 2) + mid = (low + high) // 2 if N == self._seq[mid]: return self._seq[mid] if N < self._seq[mid]: diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index dae234c15bf..52745c9a0da 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -315,13 +315,13 @@ cdef class MixedIntegerLinearProgram(SageObject): Computation of a maximum stable set in Petersen's graph:: - sage: g = graphs.PetersenGraph() - sage: p = MixedIntegerLinearProgram(maximization=True, solver='GLPK') - sage: b = p.new_variable(binary=True) - sage: p.set_objective(sum([b[v] for v in g])) - sage: for (u,v) in g.edges(sort=False, labels=None): + sage: g = graphs.PetersenGraph() # optional - sage.graphs + sage: p = MixedIntegerLinearProgram(maximization=True, solver='GLPK') # optional - sage.graphs + sage: b = p.new_variable(binary=True) # optional - sage.graphs + sage: p.set_objective(sum([b[v] for v in g])) # optional - sage.graphs + sage: for (u,v) in g.edges(sort=False, labels=None): # optional - sage.graphs ....: p.add_constraint(b[u] + b[v], max=1) - sage: p.solve(objective_only=True) + sage: p.solve(objective_only=True) # optional - sage.graphs 4.0 TESTS: @@ -659,13 +659,13 @@ cdef class MixedIntegerLinearProgram(SageObject): sage: p = MixedIntegerLinearProgram(solver='ppl') sage: p.base_ring() Rational Field - sage: from sage.rings.qqbar import AA # optional - sage.rings.number_field - sage: p = MixedIntegerLinearProgram(solver='InteractiveLP', base_ring=AA) # optional - sage.rings.number_field - sage: p.base_ring() # optional - sage.rings.number_field + sage: from sage.rings.qqbar import AA # optional - sage.rings.number_field + sage: p = MixedIntegerLinearProgram(solver='InteractiveLP', base_ring=AA) # optional - sage.rings.number_field + sage: p.base_ring() # optional - sage.rings.number_field Algebraic Real Field - sage: d = polytopes.dodecahedron() # optional - sage.rings.number_field - sage: p = MixedIntegerLinearProgram(base_ring=d.base_ring()) # optional - sage.rings.number_field - sage: p.base_ring() # optional - sage.rings.number_field + sage: d = polytopes.dodecahedron() # optional - sage.rings.number_field + sage: p = MixedIntegerLinearProgram(base_ring=d.base_ring()) # optional - sage.rings.number_field + sage: p.base_ring() # optional - sage.rings.number_field Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? """ return self._backend.base_ring() @@ -2629,14 +2629,14 @@ cdef class MixedIntegerLinearProgram(SageObject): Computation of a maximum stable set in Petersen's graph:: - sage: g = graphs.PetersenGraph() - sage: p = MixedIntegerLinearProgram(maximization=True, solver='GLPK') - sage: b = p.new_variable(nonnegative=True) - sage: p.set_objective(sum([b[v] for v in g])) - sage: for (u,v) in g.edges(sort=False, labels=None): + sage: g = graphs.PetersenGraph() # optional - sage.graphs + sage: p = MixedIntegerLinearProgram(maximization=True, solver='GLPK') # optional - sage.graphs + sage: b = p.new_variable(nonnegative=True) # optional - sage.graphs + sage: p.set_objective(sum([b[v] for v in g])) # optional - sage.graphs + sage: for (u,v) in g.edges(sort=False, labels=None): # optional - sage.graphs ....: p.add_constraint(b[u] + b[v], max=1) - sage: p.set_binary(b) - sage: p.solve(objective_only=True) + sage: p.set_binary(b) # optional - sage.graphs + sage: p.solve(objective_only=True) # optional - sage.graphs 4.0 Constraints in the objective function are respected:: @@ -2847,7 +2847,7 @@ cdef class MixedIntegerLinearProgram(SageObject): The command :: - sage: p = MixedIntegerLinearProgram(solver="CPLEX") # optional - CPLEX + sage: p = MixedIntegerLinearProgram(solver="CPLEX") # optional - CPLEX sage: p.solver_parameter("CPX_PARAM_TILIM", 60) # optional - CPLEX works as intended. @@ -2983,17 +2983,17 @@ cdef class MixedIntegerLinearProgram(SageObject): EXAMPLES:: - sage: g = graphs.CubeGraph(9) - sage: p = MixedIntegerLinearProgram(solver="GLPK") - sage: p.solver_parameter("mip_gap_tolerance",100) - sage: b = p.new_variable(binary=True) - sage: p.set_objective(p.sum(b[v] for v in g)) - sage: for v in g: + sage: g = graphs.CubeGraph(9) # optional - sage.graphs + sage: p = MixedIntegerLinearProgram(solver="GLPK") # optional - sage.graphs + sage: p.solver_parameter("mip_gap_tolerance",100) # optional - sage.graphs + sage: b = p.new_variable(binary=True) # optional - sage.graphs + sage: p.set_objective(p.sum(b[v] for v in g)) # optional - sage.graphs + sage: for v in g: # optional - sage.graphs ....: p.add_constraint(b[v] + p.sum(b[u] for u in g.neighbors(v)) <= 1) - sage: p.add_constraint(b[v] == 1) # Force an easy non-0 solution - sage: p.solve() # rel tol 100 + sage: p.add_constraint(b[v] == 1) # Force an easy non-0 solution # optional - sage.graphs + sage: p.solve() # rel tol 100 # optional - sage.graphs 1.0 - sage: p.best_known_objective_bound() # random + sage: p.best_known_objective_bound() # random # optional - sage.graphs 48.0 """ return self._backend.best_known_objective_bound() @@ -3017,17 +3017,17 @@ cdef class MixedIntegerLinearProgram(SageObject): EXAMPLES:: - sage: g = graphs.CubeGraph(9) - sage: p = MixedIntegerLinearProgram(solver="GLPK") - sage: p.solver_parameter("mip_gap_tolerance",100) - sage: b = p.new_variable(binary=True) - sage: p.set_objective(p.sum(b[v] for v in g)) - sage: for v in g: + sage: g = graphs.CubeGraph(9) # optional - sage.graphs + sage: p = MixedIntegerLinearProgram(solver="GLPK") # optional - sage.graphs + sage: p.solver_parameter("mip_gap_tolerance",100) # optional - sage.graphs + sage: b = p.new_variable(binary=True) # optional - sage.graphs + sage: p.set_objective(p.sum(b[v] for v in g)) # optional - sage.graphs + sage: for v in g: # optional - sage.graphs ....: p.add_constraint(b[v] + p.sum(b[u] for u in g.neighbors(v)) <= 1) - sage: p.add_constraint(b[v] == 1) # Force an easy non-0 solution - sage: p.solve() # rel tol 100 + sage: p.add_constraint(b[v] == 1) # Force an easy non-0 solution # optional - sage.graphs + sage: p.solve() # rel tol 100 # optional - sage.graphs 1.0 - sage: p.get_relative_objective_gap() # random + sage: p.get_relative_objective_gap() # random # optional - sage.graphs 46.99999999999999 TESTS: @@ -3035,7 +3035,7 @@ cdef class MixedIntegerLinearProgram(SageObject): Just make sure that the variable *has* been defined, and is not just undefined:: - sage: p.get_relative_objective_gap() > 1 + sage: p.get_relative_objective_gap() > 1 # optional - sage.graphs True """ return self._backend.get_relative_objective_gap() diff --git a/src/sage/numerical/optimize.py b/src/sage/numerical/optimize.py index 63d47674dbb..e47ffc4bfe8 100644 --- a/src/sage/numerical/optimize.py +++ b/src/sage/numerical/optimize.py @@ -370,9 +370,9 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", sage: def rosen(x): # The Rosenbrock function ....: return sum(100.0r*(x[1r:]-x[:-1r]**2.0r)**2.0r + (1r-x[:-1r])**2.0r) - sage: import numpy - sage: from numpy import zeros - sage: def rosen_der(x): + sage: import numpy # optional - numpy + sage: from numpy import zeros # optional - numpy + sage: def rosen_der(x): # optional - numpy ....: xm = x[1r:-1r] ....: xm_m1 = x[:-2r] ....: xm_p1 = x[2r:] @@ -381,7 +381,8 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", ....: der[0] = -400r*x[0r]*(x[1r]-x[0r]**2r) - 2r*(1r-x[0]) ....: der[-1] = 200r*(x[-1r]-x[-2r]**2r) ....: return der - sage: minimize(rosen, [.1,.3,.4], gradient=rosen_der, algorithm="bfgs") # abs tol 1e-6 + sage: minimize(rosen, [.1,.3,.4], gradient=rosen_der, # abs tol 1e-6 # optional - numpy + ....: algorithm="bfgs") (1.0, 1.0, 1.0) """ from sage.structure.element import Expression diff --git a/src/sage/numerical/sdp.pyx b/src/sage/numerical/sdp.pyx index 77f7fa5254c..dea3ded3942 100644 --- a/src/sage/numerical/sdp.pyx +++ b/src/sage/numerical/sdp.pyx @@ -72,17 +72,17 @@ The following example shows all these steps:: sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) sage: p.add_constraint(c1*x[0] + c2*x[1] >= matrix.zero(2,2,sparse=True)) - sage: p.solver_parameter("show_progress", True) # optional - cvxopt - sage: opt = p.solve() # optional - cvxopt + sage: p.solver_parameter("show_progress", True) # optional - cvxopt + sage: opt = p.solve() # optional - cvxopt pcost dcost gap pres dres k/t 0: ... ... Optimal solution found. - sage: print('Objective Value: {}'.format(N(opt,3))) # optional - cvxopt + sage: print('Objective Value: {}'.format(N(opt,3))) # optional - cvxopt Objective Value: 1.0 - sage: [N(x, 3) for x in sorted(p.get_values(x).values())] # optional - cvxopt + sage: [N(x, 3) for x in sorted(p.get_values(x).values())] # optional - cvxopt [3.0e-8, 1.0] - sage: p.show() # optional - cvxopt + sage: p.show() # optional - cvxopt Maximization: x_0 - x_1 Constraints: @@ -97,46 +97,47 @@ of primal and dual problems. Thus we can get the optimizer `X` of the dual probl as follows, as diagonal blocks, one per each constraint, via :meth:`~SemidefiniteProgram.dual_variable`. E.g.:: - sage: p.dual_variable(1) # rel tol 2e-03 # optional - cvxopt + sage: p.dual_variable(1) # rel tol 2e-03 # optional - cvxopt [ 85555.0 -85555.0] [-85555.0 85555.0] We can see that the optimal value of the dual is equal (up to numerical noise) to `opt`.:: - sage: opt-((p.dual_variable(0)*a3).trace()+(p.dual_variable(1)*b3).trace()) # tol 8e-08 # optional - cvxopt + sage: opt - ((p.dual_variable(0)*a3).trace() # tol 8e-08 # optional - cvxopt + ....: + (p.dual_variable(1)*b3).trace()) 0.0 Dual variable blocks at optimality are orthogonal to "slack variables", that is, matrices `C-\sum_k x_k A_k`, cf. (Primal problem) above, available via :meth:`~SemidefiniteProgram.slack`. E.g.:: - sage: (p.slack(0)*p.dual_variable(0)).trace() # tol 2e-07 # optional - cvxopt + sage: (p.slack(0)*p.dual_variable(0)).trace() # tol 2e-07 # optional - cvxopt 0.0 More interesting example, the :func:`Lovasz theta ` of the 7-gon:: - sage: c=graphs.CycleGraph(7) - sage: c2=c.distance_graph(2).adjacency_matrix() - sage: c3=c.distance_graph(3).adjacency_matrix() - sage: p.=SemidefiniteProgram() - sage: p.add_constraint((1/7)*matrix.identity(7)>=-y[0]*c2-y[1]*c3) - sage: p.set_objective(y[0]*(c2**2).trace()+y[1]*(c3**2).trace()) - sage: x=p.solve(); x+1 # optional - cvxopt + sage: c = graphs.CycleGraph(7) # optional - sage.graphs + sage: c2 = c.distance_graph(2).adjacency_matrix() # optional - sage.graphs + sage: c3 = c.distance_graph(3).adjacency_matrix() # optional - sage.graphs + sage: p. = SemidefiniteProgram() # optional - sage.graphs + sage: p.add_constraint((1/7)*matrix.identity(7)>=-y[0]*c2-y[1]*c3) # optional - sage.graphs + sage: p.set_objective(y[0]*(c2**2).trace()+y[1]*(c3**2).trace()) # optional - sage.graphs + sage: x = p.solve(); x + 1 # optional - cvxopt # optional - sage.graphs 3.31766... Unlike in the previous example, the slack variable is very far from 0:: - sage: p.slack(0).trace() # tol 1e-14 # optional - cvxopt + sage: p.slack(0).trace() # tol 1e-14 # optional - cvxopt # optional - sage.graphs 1.0 The default CVXOPT backend computes with the Real Double Field, for example:: - sage: p = SemidefiniteProgram(solver='cvxopt') # optional - cvxopt - sage: p.base_ring() # optional - cvxopt + sage: p = SemidefiniteProgram(solver='cvxopt') # optional - cvxopt + sage: p.base_ring() # optional - cvxopt Real Double Field - sage: x = p.new_variable() # optional - cvxopt - sage: 0.5 + 3/2*x[1] # optional - cvxopt + sage: x = p.new_variable() # optional - cvxopt + sage: 0.5 + 3/2*x[1] # optional - cvxopt 0.5 + 1.5*x_0 For representing an SDP with exact data, there is another backend:: @@ -285,7 +286,7 @@ cdef class SemidefiniteProgram(SageObject): sage: b3 = matrix([[3, 3.], [3., 3.]]) sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) - sage: N(p.solve(), 2) # optional - cvxopt + sage: N(p.solve(), 2) # optional - cvxopt -3.0 """ @@ -724,19 +725,19 @@ cdef class SemidefiniteProgram(SageObject): sage: b3 = matrix([[3, 3.], [3., 3.]]) sage: p.add_constraint(a1*x[3] + a2*x[5] <= a3) sage: p.add_constraint(b1*x[3] + b2*x[5] <= b3) - sage: N(p.solve(),3) # optional - cvxopt + sage: N(p.solve(),3) # optional - cvxopt -3.0 To return the optimal value of ``x[3]``:: - sage: N(p.get_values(x[3]),3) # optional - cvxopt + sage: N(p.get_values(x[3]),3) # optional - cvxopt -1.0 To get a dictionary identical to ``x`` containing optimal values for the corresponding variables :: - sage: x_sol = p.get_values(x) # optional - cvxopt - sage: sorted(x_sol) # optional - cvxopt + sage: x_sol = p.get_values(x) # optional - cvxopt + sage: sorted(x_sol) # optional - cvxopt [3, 5] """ @@ -795,10 +796,10 @@ cdef class SemidefiniteProgram(SageObject): sage: a2 = matrix([[1,1],[1,1]]) sage: a3 = matrix([[1,-1],[-1,1]]) sage: p.add_constraint(a1*x[1]+a2*x[2] <= a3) - sage: N(p.solve(),digits=3) # optional - cvxopt + sage: N(p.solve(), digits=3) # optional - cvxopt 16.2 sage: p.set_objective(None) - sage: _ = p.solve() # optional - cvxopt + sage: _ = p.solve() # optional - cvxopt """ cdef list values = [] @@ -854,7 +855,7 @@ cdef class SemidefiniteProgram(SageObject): sage: a2 = matrix([[1,1],[1,1]]) sage: a3 = matrix([[1,-1],[-1,1]]) sage: p.add_constraint(a1*x[1]+a2*x[2] <= a3) - sage: N(p.solve(),digits=3) # optional - cvxopt + sage: N(p.solve(), digits=3) # optional - cvxopt 16.2 One can also define double-bounds or equality using the symbol @@ -867,7 +868,7 @@ cdef class SemidefiniteProgram(SageObject): sage: a2 = matrix([[1,1],[1,1]]) sage: a3 = matrix([[1,-1],[-1,1]]) sage: p.add_constraint(a3 >= a1*x[1] + a2*x[2]) - sage: N(p.solve(),digits=3) # optional - cvxopt + sage: N(p.solve(), digits=3) # optional - cvxopt 16.2 TESTS: @@ -947,12 +948,12 @@ cdef class SemidefiniteProgram(SageObject): sage: b3 = matrix([[3, 3.], [3., 3.]]) sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) - sage: N(p.solve(),4) # optional - cvxopt + sage: N(p.solve(),4) # optional - cvxopt -11. - sage: x = p.get_values(x) # optional - cvxopt - sage: N(x[0],4) # optional - cvxopt + sage: x = p.get_values(x) # optional - cvxopt + sage: N(x[0],4) # optional - cvxopt -8.0 - sage: N(x[1],4) # optional - cvxopt + sage: N(x[1],4) # optional - cvxopt 3.0 """ self._backend.solve() @@ -990,7 +991,7 @@ cdef class SemidefiniteProgram(SageObject): sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) sage: p.solve() # tol 1e-08 # optional - cvxopt -3.0 - sage: x = p.get_values(x).values() # optional - cvxopt + sage: x = p.get_values(x).values() # optional - cvxopt sage: -(a3*p.dual_variable(0)).trace()-(b3*p.dual_variable(1)).trace() # tol 1e-07 # optional - cvxopt -3.0 @@ -1001,7 +1002,7 @@ cdef class SemidefiniteProgram(SageObject): TESTS:: - sage: p.dual_variable(7) # optional - cvxopt + sage: p.dual_variable(7) # optional - cvxopt Traceback (most recent call last): ... IndexError: list index out of range @@ -1035,21 +1036,21 @@ cdef class SemidefiniteProgram(SageObject): sage: b3 = matrix([[3, 3.], [3., 3.]]) sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) - sage: p.solve() # tol 1e-08 # optional - cvxopt + sage: p.solve() # tol 1e-08 # optional - cvxopt -3.0 - sage: B1 = p.slack(1); B1 # tol 1e-08 # optional - cvxopt + sage: B1 = p.slack(1); B1 # tol 1e-08 # optional - cvxopt [0.0 0.0] [0.0 0.0] - sage: B1.is_positive_definite() # optional - cvxopt + sage: B1.is_positive_definite() # optional - cvxopt True - sage: x = sorted(p.get_values(x).values()) # optional - cvxopt - sage: x[0]*b1 + x[1]*b2 - b3 + B1 # tol 1e-09 # optional - cvxopt + sage: x = sorted(p.get_values(x).values()) # optional - cvxopt + sage: x[0]*b1 + x[1]*b2 - b3 + B1 # tol 1e-09 # optional - cvxopt [0.0 0.0] [0.0 0.0] TESTS:: - sage: p.slack(7) # optional - cvxopt + sage: p.slack(7) # optional - cvxopt Traceback (most recent call last): ... IndexError: list index out of range @@ -1076,20 +1077,21 @@ cdef class SemidefiniteProgram(SageObject): EXAMPLES:: - sage: p. = SemidefiniteProgram(solver = "cvxopt", maximization = False) # optional - cvxopt - sage: p.solver_parameter("show_progress", True) # optional - cvxopt - sage: p.solver_parameter("show_progress") # optional - cvxopt + sage: p. = SemidefiniteProgram(solver="cvxopt", # optional - cvxopt + ....: maximization=False) + sage: p.solver_parameter("show_progress", True) # optional - cvxopt + sage: p.solver_parameter("show_progress") # optional - cvxopt True - sage: p.set_objective(x[0] - x[1]) # optional - cvxopt + sage: p.set_objective(x[0] - x[1]) # optional - cvxopt sage: a1 = matrix([[1, 2.], [2., 3.]]) sage: a2 = matrix([[3, 4.], [4., 2.]]) sage: a3 = matrix([[5, 6.], [6., 7.]]) sage: b1 = matrix([[1, 1.], [1., 1.]]) sage: b2 = matrix([[2, 2.], [2., 1.]]) sage: b3 = matrix([[3, 3.], [3., 3.]]) - sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) # optional - cvxopt - sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) # optional - cvxopt - sage: N(p.solve(),4) # optional - cvxopt + sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) # optional - cvxopt + sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) # optional - cvxopt + sage: N(p.solve(),4) # optional - cvxopt pcost dcost gap pres dres k/t 0: 1... ... @@ -1177,13 +1179,13 @@ class SDPSolverException(RuntimeError): No solution:: - sage: p = SemidefiniteProgram(solver="cvxopt") # optional - cvxopt - sage: x = p.new_variable() # optional - cvxopt - sage: p.set_objective(x[0]) # optional - cvxopt + sage: p = SemidefiniteProgram(solver="cvxopt") # optional - cvxopt + sage: x = p.new_variable() # optional - cvxopt + sage: p.set_objective(x[0]) # optional - cvxopt sage: a = matrix([[1,2],[2,4]]) sage: b = matrix([[1,9],[9,4]]) - sage: p.add_constraint( a*x[0] == b ) # optional - cvxopt - sage: p.solve() # optional - cvxopt + sage: p.add_constraint( a*x[0] == b ) # optional - cvxopt + sage: p.solve() # optional - cvxopt Traceback (most recent call last): ... SDPSolverException: ... diff --git a/src/sage/parallel/decorate.py b/src/sage/parallel/decorate.py index 97c612b4e45..e64b6ee087b 100644 --- a/src/sage/parallel/decorate.py +++ b/src/sage/parallel/decorate.py @@ -107,8 +107,8 @@ def __call__(self, f): sage: from sage.parallel.decorate import Parallel sage: p = Parallel() - sage: f = x^2-1 - sage: p(f) + sage: f = x^2 - 1 # optional - sage.symbolic + sage: p(f) # optional - sage.symbolic sage: P = sage.parallel.decorate.Parallel() @@ -342,7 +342,7 @@ def parallel(p_iter='fork', ncpus=None, **kwds): sage: @parallel(ncpus=3, timeout=10) ....: def fac(n): return factor(2^n-1) - sage: for X, Y in sorted(list(fac([101,119,151,197,209]))): print((X,Y)) + sage: for X, Y in sorted(list(fac([101,119,151,197,209]))): print((X,Y)) # optional - sage.libs.pari (((101,), {}), 7432339208719 * 341117531003194129) (((119,), {}), 127 * 239 * 20231 * 131071 * 62983048367 * 131105292137) (((151,), {}), 18121 * 55871 * 165799 * 2332951 * 7289088383388253664437433) @@ -531,30 +531,30 @@ def fork(f=None, timeout=0, verbose=False): We illustrate that the state of the pexpect interface is not altered by forked functions (they get their own new pexpect interfaces!):: - sage: gp.eval('a = 5') + sage: gp.eval('a = 5') # optional - sage.libs.pari '5' - sage: @fork() + sage: @fork() # optional - sage.libs.pari ....: def g(): ....: gp.eval('a = 10') ....: return gp.eval('a') - sage: g() + sage: g() # optional - sage.libs.pari '10' - sage: gp.eval('a') + sage: gp.eval('a') # optional - sage.libs.pari '5' We illustrate that the forked function has its own pexpect interface:: - sage: gp.eval('a = 15') + sage: gp.eval('a = 15') # optional - sage.libs.pari '15' - sage: @fork() + sage: @fork() # optional - sage.libs.pari ....: def g(): return gp.eval('a') - sage: g() + sage: g() # optional - sage.libs.pari 'a' We illustrate that segfaulting subprocesses are no trouble at all:: - sage: cython('def f(): print(0)') # optional - sage.misc.cython + sage: cython('def f(): print(0)') # optional - sage.misc.cython sage: @fork ....: def g(): ....: os.environ["CYSIGNALS_CRASH_NDEBUG"]="yes" # skip enhanced backtrace (it is slow) diff --git a/src/sage/plot/all.py b/src/sage/plot/all.py index 1f16e2d6789..2db3c52821d 100644 --- a/src/sage/plot/all.py +++ b/src/sage/plot/all.py @@ -34,6 +34,6 @@ from .step import plot_step_function -from .hyperbolic_arc import hyperbolic_arc -from .hyperbolic_polygon import hyperbolic_triangle, hyperbolic_polygon +lazy_import("sage.plot.hyperbolic_arc", "hyperbolic_arc") +lazy_import("sage.plot.hyperbolic_polygon", ["hyperbolic_triangle", "hyperbolic_polygon"]) lazy_import("sage.plot.hyperbolic_regular_polygon", "hyperbolic_regular_polygon") diff --git a/src/sage/plot/complex_plot.pyx b/src/sage/plot/complex_plot.pyx index 0586a96ae55..6c1eb17058d 100644 --- a/src/sage/plot/complex_plot.pyx +++ b/src/sage/plot/complex_plot.pyx @@ -670,11 +670,13 @@ def add_lightness_smoothing_to_rgb(rgb, delta): We can call this on grids of values:: - sage: import numpy as np - sage: from sage.plot.complex_plot import add_lightness_smoothing_to_rgb - sage: add_lightness_smoothing_to_rgb(np.array([[[0, 0.25, 0.5]]]), np.array([[0.75]])) # abs tol 1e-4 + sage: import numpy as np # optional - numpy + sage: from sage.plot.complex_plot import add_lightness_smoothing_to_rgb # optional - numpy + sage: add_lightness_smoothing_to_rgb( # abs tol 1e-4 # optional - numpy + ....: np.array([[[0, 0.25, 0.5]]]), np.array([[0.75]])) array([[[0.75 , 0.8125, 0.875 ]]]) - sage: add_lightness_smoothing_to_rgb(np.array([[[0, 0.25, 0.5]]]), np.array([[0.75]])) # abs tol 1e-4 + sage: add_lightness_smoothing_to_rgb( # abs tol 1e-4 # optional - numpy + ....: np.array([[[0, 0.25, 0.5]]]), np.array([[0.75]])) array([[[0.75 , 0.8125, 0.875 ]]]) """ import numpy as np @@ -732,21 +734,24 @@ def add_contours_to_rgb(rgb, delta, dark_rate=0.5): EXAMPLES:: - sage: import numpy as np - sage: from sage.plot.complex_plot import add_contours_to_rgb - sage: add_contours_to_rgb(np.array([[[0, 0.25, 0.5]]]), np.array([[0.75]])) # abs tol 1e-4 + sage: import numpy as np # optional - numpy + sage: from sage.plot.complex_plot import add_contours_to_rgb # optional - numpy + sage: add_contours_to_rgb(np.array([[[0, 0.25, 0.5]]]), # abs tol 1e-4 # optional - numpy + ....: np.array([[0.75]])) array([[[0.25 , 0.625, 1. ]]]) - sage: add_contours_to_rgb(np.array([[[0, 0, 0]]]), np.array([[1]])) # abs tol 1e-4 + sage: add_contours_to_rgb(np.array([[[0, 0, 0]]]), # abs tol 1e-4 # optional - numpy + ....: np.array([[1]])) array([[[0.5, 0.5, 0.5]]]) - sage: add_contours_to_rgb(np.array([[[1, 1, 1]]]), np.array([[-0.5]])) # abs tol 1e-4 + sage: add_contours_to_rgb(np.array([[[1, 1, 1]]]), # abs tol 1e-4 # optional - numpy + ....: np.array([[-0.5]])) array([[[0.75, 0.75, 0.75]]]) Raising ``dark_rate`` leads to bigger adjustments:: - sage: add_contours_to_rgb(np.array([[[0.5, 0.5, 0.5]]]), # abs tol 1e-4 + sage: add_contours_to_rgb(np.array([[[0.5, 0.5, 0.5]]]), # abs tol 1e-4 # optional - numpy ....: np.array([[0.5]]), dark_rate=0.1) array([[[0.55, 0.55, 0.55]]]) - sage: add_contours_to_rgb(np.array([[[0.5, 0.5, 0.5]]]), # abs tol 1e-4 + sage: add_contours_to_rgb(np.array([[[0.5, 0.5, 0.5]]]), # abs tol 1e-4 # optional - numpy ....: np.array([[0.5]]), dark_rate=0.5) array([[[0.75, 0.75, 0.75]]]) """ diff --git a/src/sage/plot/graphics.py b/src/sage/plot/graphics.py index cdc99ced263..a7d31d8829d 100644 --- a/src/sage/plot/graphics.py +++ b/src/sage/plot/graphics.py @@ -2400,7 +2400,7 @@ def _matplotlib_tick_formatter(self, subplot, base=(10, 10), x_formatter, y_formatter = tick_formatter from matplotlib.ticker import FuncFormatter, FixedFormatter from sage.misc.latex import latex - from sage.symbolic.ring import SR + from sage.structure.element import Expression from .misc import _multiple_of_constant # ---------------------- Formatting x-ticks ---------------------- if x_formatter is None: @@ -2408,7 +2408,7 @@ def _matplotlib_tick_formatter(self, subplot, base=(10, 10), x_formatter = LogFormatterMathtext(base=base[0]) else: x_formatter = ScalarFormatter() - elif x_formatter in SR: + elif isinstance(x_formatter, Expression): x_const = x_formatter x_formatter = FuncFormatter(lambda n, pos: _multiple_of_constant(n, pos, x_const)) @@ -2437,7 +2437,7 @@ def _matplotlib_tick_formatter(self, subplot, base=(10, 10), y_formatter = LogFormatterMathtext(base=base[1]) else: y_formatter = ScalarFormatter() - elif y_formatter in SR: + elif isinstance(y_formatter, Expression): y_const = y_formatter y_formatter = FuncFormatter(lambda n, pos: _multiple_of_constant(n, pos, y_const)) @@ -2720,10 +2720,10 @@ def matplotlib(self, filename=None, if stylesheet in plt.style.available: plt.style.use(stylesheet) - from sage.symbolic.ring import SR + from sage.structure.element import Expression # make sure both formatters typeset or both don't if not isinstance(tick_formatter, (list, tuple)): - if tick_formatter == "latex" or tick_formatter in SR: + if tick_formatter == "latex" or isinstance(tick_formatter, Expression): tick_formatter = (tick_formatter, "latex") else: tick_formatter = (tick_formatter, None) diff --git a/src/sage/plot/hyperbolic_regular_polygon.py b/src/sage/plot/hyperbolic_regular_polygon.py index 5874073b549..88c8d535a7a 100644 --- a/src/sage/plot/hyperbolic_regular_polygon.py +++ b/src/sage/plot/hyperbolic_regular_polygon.py @@ -21,9 +21,10 @@ from sage.rings.cc import CC from sage.rings.integer import Integer from sage.misc.decorators import options, rename_keyword -from sage.symbolic.constants import pi, e -from sage.functions.hyperbolic import arccosh -from sage.functions.trig import sin, cos, cot +from sage.misc.lazy_import import lazy_import +lazy_import("sage.symbolic.constants", ["pi", "e"]) +lazy_import("sage.functions.hyperbolic", "arccosh") +lazy_import("sage.functions.trig", ["sin", "cos", "cot"]) from sage.misc.functional import is_odd from sage.matrix.constructor import matrix diff --git a/src/sage/plot/line.py b/src/sage/plot/line.py index 691e3c31307..8c2d8ec0ad1 100644 --- a/src/sage/plot/line.py +++ b/src/sage/plot/line.py @@ -391,14 +391,14 @@ def line2d(points, **options): sage: line([]) #returns an empty plot Graphics object consisting of 0 graphics primitives - sage: import numpy; line(numpy.array([])) + sage: import numpy; line(numpy.array([])) # optional - numpy Graphics object consisting of 0 graphics primitives sage: line([(1,1)]) Graphics object consisting of 1 graphics primitive A line with numpy arrays:: - sage: line(numpy.array([[1,2], [3,4]])) + sage: line(numpy.array([[1,2], [3,4]])) # optional - numpy Graphics object consisting of 1 graphics primitive A line with a legend:: diff --git a/src/sage/plot/matrix_plot.py b/src/sage/plot/matrix_plot.py index 9e7b72d1fd6..18718db3b82 100644 --- a/src/sage/plot/matrix_plot.py +++ b/src/sage/plot/matrix_plot.py @@ -496,8 +496,8 @@ def matrix_plot(mat, xrange=None, yrange=None, **options): As does plotting of NumPy arrays:: - sage: import numpy - sage: matrix_plot(numpy.random.rand(10, 10)) + sage: import numpy # optional - numpy + sage: matrix_plot(numpy.random.rand(10, 10)) # optional - numpy Graphics object consisting of 1 graphics primitive A plot title can be added to the matrix plot.:: diff --git a/src/sage/plot/plot.py b/src/sage/plot/plot.py index ced087a3814..c3b8609d431 100644 --- a/src/sage/plot/plot.py +++ b/src/sage/plot/plot.py @@ -683,16 +683,17 @@ def SelectiveFormatter(formatter, skip_values): sage: from sage.plot.plot import SelectiveFormatter sage: import matplotlib.pyplot as plt - sage: import numpy - sage: fig=plt.figure() - sage: ax=fig.add_subplot(111) - sage: t = numpy.arange(0.0, 2.0, 0.01) - sage: s = numpy.sin(2*numpy.pi*t) - sage: p = ax.plot(t, s) - sage: formatter=SelectiveFormatter(ax.xaxis.get_major_formatter(),skip_values=[0,1]) - sage: ax.xaxis.set_major_formatter(formatter) + sage: import numpy # optional - numpy + sage: fig = plt.figure() + sage: ax = fig.add_subplot(111) + sage: t = numpy.arange(0.0, 2.0, 0.01) # optional - numpy + sage: s = numpy.sin(2*numpy.pi*t) # optional - numpy + sage: p = ax.plot(t, s) # optional - numpy + sage: formatter = SelectiveFormatter(ax.xaxis.get_major_formatter(), # optional - numpy + ....: skip_values=[0,1]) + sage: ax.xaxis.set_major_formatter(formatter) # optional - numpy sage: import tempfile - sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: + sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: # optional - numpy ....: fig.savefig(f.name) """ @@ -717,16 +718,16 @@ def __init__(self, formatter, skip_values): sage: from sage.plot.plot import SelectiveFormatter sage: import matplotlib.pyplot as plt - sage: import numpy - sage: fig=plt.figure() - sage: ax=fig.add_subplot(111) - sage: t = numpy.arange(0.0, 2.0, 0.01) - sage: s = numpy.sin(2*numpy.pi*t) - sage: line=ax.plot(t, s) - sage: formatter=SelectiveFormatter(ax.xaxis.get_major_formatter(),skip_values=[0,1]) - sage: ax.xaxis.set_major_formatter(formatter) + sage: import numpy # optional - numpy + sage: fig = plt.figure() + sage: ax = fig.add_subplot(111) + sage: t = numpy.arange(0.0, 2.0, 0.01) # optional - numpy + sage: s = numpy.sin(2*numpy.pi*t) # optional - numpy + sage: line = ax.plot(t, s) # optional - numpy + sage: formatter = SelectiveFormatter(ax.xaxis.get_major_formatter(), skip_values=[0,1]) # optional - numpy + sage: ax.xaxis.set_major_formatter(formatter) # optional - numpy sage: from tempfile import NamedTemporaryFile - sage: with NamedTemporaryFile(suffix=".png") as f: + sage: with NamedTemporaryFile(suffix=".png") as f: # optional - numpy ....: fig.savefig(f.name) """ self.formatter=formatter @@ -1139,9 +1140,12 @@ def plot(funcs, *args, **kwds): By default, color will change from one primitive to the next. This may be controlled by modifying ``color`` option:: - sage: g1 = plot([x*exp(-n*x^2)/.4 for n in [1..3]], (0, 2), color='blue', aspect_ratio=.8); g1 + sage: g1 = plot([x*exp(-n*x^2)/.4 for n in [1..3]], (0, 2), + ....: color='blue', aspect_ratio=.8); g1 Graphics object consisting of 3 graphics primitives - sage: g2 = plot([x*exp(-n*x^2)/.4 for n in [1..3]], (0, 2), color=['red','red','green'], linestyle=['-','--','-.'], aspect_ratio=.8); g2 + sage: g2 = plot([x*exp(-n*x^2)/.4 for n in [1..3]], (0, 2), + ....: color=['red','red','green'], linestyle=['-','--','-.'], + ....: aspect_ratio=.8); g2 Graphics object consisting of 3 graphics primitives .. PLOT:: @@ -1601,7 +1605,7 @@ def h2(x): return -abs(sqrt(x**3 - 1)) sage: p2 = plot(sin(x), -pi, pi, fill='min', fillalpha=1) sage: p3 = plot(sin(x), -pi, pi, fill='max') sage: p4 = plot(sin(x), -pi, pi, fill=(1-x)/3, fillcolor='blue', fillalpha=.2) - sage: graphics_array([[p1, p2], [p3, p4]]).show(frame=True, axes=False) # long time + sage: graphics_array([[p1, p2], [p3, p4]]).show(frame=True, axes=False) # long time .. PLOT:: @@ -1615,11 +1619,15 @@ def h2(x): return -abs(sqrt(x**3 - 1)) The basic options for filling a list of plots:: sage: (f1, f2) = x*exp(-1*x^2)/.35, x*exp(-2*x^2)/.35 - sage: p1 = plot([f1, f2], -pi, pi, fill={1: [0]}, fillcolor='blue', fillalpha=.25, color='blue') - sage: p2 = plot([f1, f2], -pi, pi, fill={0: x/3, 1:[0]}, color=['blue']) - sage: p3 = plot([f1, f2], -pi, pi, fill=[0, [0]], fillcolor=['orange','red'], fillalpha=1, color={1: 'blue'}) - sage: p4 = plot([f1, f2], (x,-pi, pi), fill=[x/3, 0], fillcolor=['grey'], color=['red', 'blue']) - sage: graphics_array([[p1, p2], [p3, p4]]).show(frame=True, axes=False) # long time + sage: p1 = plot([f1, f2], -pi, pi, fill={1: [0]}, + ....: fillcolor='blue', fillalpha=.25, color='blue') + sage: p2 = plot([f1, f2], -pi, pi, fill={0: x/3, 1:[0]}, + ....: color=['blue']) + sage: p3 = plot([f1, f2], -pi, pi, fill=[0, [0]], + ....: fillcolor=['orange','red'], fillalpha=1, color={1: 'blue'}) + sage: p4 = plot([f1, f2], (x,-pi, pi), fill=[x/3, 0], + ....: fillcolor=['grey'], color=['red', 'blue']) + sage: graphics_array([[p1, p2], [p3, p4]]).show(frame=True, axes=False) # long time .. PLOT:: @@ -1670,9 +1678,11 @@ def b(n): return lambda x: bessel_J(n, x) like ``i:j`` will fill between the ith function and the line y=j:: sage: def b(n): return lambda x: bessel_J(n, x) + 0.5*(n-1) - sage: plot([b(c) for c in [1..5]], 0, 20, fill={i:[i-1] for i in [1..4]}, color={i:'blue' for i in [1..5]}, aspect_ratio=3, ymax=3) + sage: plot([b(c) for c in [1..5]], 0, 20, fill={i: [i-1] for i in [1..4]}, + ....: color={i: 'blue' for i in [1..5]}, aspect_ratio=3, ymax=3) Graphics object consisting of 9 graphics primitives - sage: plot([b(c) for c in [1..5]], 0, 20, fill={i:i-1 for i in [1..4]}, color='blue', aspect_ratio=3) # long time + sage: plot([b(c) for c in [1..5]], 0, 20, fill={i: i-1 for i in [1..4]}, # long time + ....: color='blue', aspect_ratio=3) Graphics object consisting of 9 graphics primitives .. PLOT:: @@ -1687,7 +1697,8 @@ def b(n): return lambda x: bessel_J(n, x) + 0.5*(n-1) Extra options will get passed on to :meth:`~sage.plot.graphics.Graphics.show`, as long as they are valid:: - sage: plot(sin(x^2), (x, -3, 3), title=r'Plot of $\sin(x^2)$', axes_labels=['$x$','$y$']) # These labels will be nicely typeset + sage: plot(sin(x^2), (x, -3, 3), # These labels will be nicely typeset + ....: title=r'Plot of $\sin(x^2)$', axes_labels=['$x$','$y$']) Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -1697,7 +1708,8 @@ def b(n): return lambda x: bessel_J(n, x) + 0.5*(n-1) :: - sage: plot(sin(x^2), (x, -3, 3), title='Plot of sin(x^2)', axes_labels=['x','y']) # These will not + sage: plot(sin(x^2), (x, -3, 3), # These will not + ....: title='Plot of sin(x^2)', axes_labels=['x','y']) Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -1707,7 +1719,8 @@ def b(n): return lambda x: bessel_J(n, x) + 0.5*(n-1) :: - sage: plot(sin(x^2), (x, -3, 3), axes_labels=['x','y'], axes_labels_size=2.5) # Large axes labels (w.r.t. the tick marks) + sage: plot(sin(x^2), (x, -3, 3), # Large axes labels (w.r.t. the tick marks) + ....: axes_labels=['x','y'], axes_labels_size=2.5) Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -1719,7 +1732,7 @@ def b(n): return lambda x: bessel_J(n, x) + 0.5*(n-1) sage: plot(sin(x^2), (x, -3, 3), figsize=[8,2]) Graphics object consisting of 1 graphics primitive - sage: plot(sin(x^2), (x, -3, 3)).show(figsize=[8,2]) # These are equivalent + sage: plot(sin(x^2), (x, -3, 3)).show(figsize=[8,2]) # These are equivalent .. PLOT:: @@ -1731,17 +1744,19 @@ def b(n): return lambda x: bessel_J(n, x) + 0.5*(n-1) :: - sage: plot(sin(pi*x), (x, -8, 8), ticks=[[-7,-3,0,3,7],[-1/2,0,1/2]]) + sage: plot(sin(pi*x), (x, -8, 8), ticks=[[-7,-3,0,3,7], [-1/2,0,1/2]]) Graphics object consisting of 1 graphics primitive .. PLOT:: - g = plot(sin(pi*x), (x, -8, 8), ticks=[[-7,-3,0,3,7],[-1/2,0,1/2]]) + g = plot(sin(pi*x), (x, -8, 8), ticks=[[-7,-3,0,3,7], [-1/2,0,1/2]]) sphinx_plot(g) :: - sage: plot(2*x + 1, (x, 0, 5), ticks=[[0, 1, e, pi, sqrt(20)], [1, 3, 2*e + 1, 2*pi + 1, 2*sqrt(20) + 1]], tick_formatter="latex") + sage: plot(2*x + 1, (x, 0, 5), tick_formatter="latex", + ....: ticks=[[0, 1, e, pi, sqrt(20)], + ....: [1, 3, 2*e + 1, 2*pi + 1, 2*sqrt(20) + 1]]) Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -1753,7 +1768,7 @@ def b(n): return lambda x: bessel_J(n, x) + 0.5*(n-1) :: - sage: plot(sin(x),(x,0,2*pi),ticks=pi/3,tick_formatter=pi) + sage: plot(sin(x), (x,0,2*pi), ticks=pi/3, tick_formatter=pi) Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -1763,12 +1778,13 @@ def b(n): return lambda x: bessel_J(n, x) + 0.5*(n-1) You can even have custom tick labels along with custom positioning. :: - sage: plot(x**2, (x,0,3), ticks=[[1,2.5],[0.5,1,2]], tick_formatter=[["$x_1$","$x_2$"],["$y_1$","$y_2$","$y_3$"]]) + sage: plot(x**2, (x,0,3), ticks=[[1,2.5], [0.5,1,2]], + ....: tick_formatter=[["$x_1$","$x_2$"], ["$y_1$","$y_2$","$y_3$"]]) Graphics object consisting of 1 graphics primitive .. PLOT:: - g = plot(x**2, (x,0,3), ticks=[[1,2.5],[0.5,1,2]], tick_formatter=[["$x_1$","$x_2$"],["$y_1$","$y_2$","$y_3$"]]) + g = plot(x**2, (x,0,3), ticks=[[1,2.5],[0.5,1,2]], tick_formatter=[["$x_1$","$x_2$"], ["$y_1$","$y_2$","$y_3$"]]) sphinx_plot(g) You can force Type 1 fonts in your figures by providing the relevant @@ -1859,7 +1875,7 @@ def f(x): return (floor(x)+0.5) / (1-(x-0.5)**2) sage: plot(arcsec(x/2), -2, 2) # plot should be empty; no valid points Graphics object consisting of 0 graphics primitives - sage: plot(sqrt(x^2-1), -2, 2) # [-1, 1] is excluded automatically + sage: plot(sqrt(x^2 - 1), -2, 2) # [-1, 1] is excluded automatically Graphics object consisting of 2 graphics primitives .. PLOT:: @@ -2541,7 +2557,7 @@ def parametric_plot(funcs, *args, **kwargs): is 1, so that circles look like circles. :: sage: t = var('t') - sage: parametric_plot( (cos(t), sin(t)), (t, 0, 2*pi)) + sage: parametric_plot((cos(t), sin(t)), (t, 0, 2*pi)) Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -2552,7 +2568,7 @@ def parametric_plot(funcs, *args, **kwargs): :: - sage: parametric_plot( (sin(t), sin(2*t)), (t, 0, 2*pi), color=hue(0.6) ) + sage: parametric_plot((sin(t), sin(2*t)), (t, 0, 2*pi), color=hue(0.6) ) Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -2581,23 +2597,25 @@ def parametric_plot(funcs, *args, **kwargs): .. PLOT:: - t =var('t') + t = var('t') g = parametric_plot((t, t**2), (t, -4, 4), fill=True) sphinx_plot(g) A filled Hypotrochoid:: - sage: parametric_plot([cos(x) + 2 * cos(x/4), sin(x) - 2 * sin(x/4)], (x,0, 8*pi), fill=True) + sage: parametric_plot([cos(x) + 2 * cos(x/4), sin(x) - 2 * sin(x/4)], + ....: (x, 0, 8*pi), fill=True) Graphics object consisting of 2 graphics primitives .. PLOT:: - g = parametric_plot([cos(x) + 2 * cos(x/4), sin(x) - 2 * sin(x/4)], (x,0, 8*pi), fill=True) + g = parametric_plot([cos(x) + 2 * cos(x/4), sin(x) - 2 * sin(x/4)], (x, 0, 8*pi), fill=True) sphinx_plot(g) :: - sage: parametric_plot( (5*cos(x), 5*sin(x), x), (x,-12, 12), plot_points=150, color="red") # long time + sage: parametric_plot((5*cos(x), 5*sin(x), x), (x, -12, 12), # long time + ....: plot_points=150, color="red") Graphics3d Object .. PLOT:: @@ -2608,8 +2626,8 @@ def parametric_plot(funcs, *args, **kwargs): :: - sage: y=var('y') - sage: parametric_plot( (5*cos(x), x*y, cos(x*y)), (x, -4,4), (y,-4,4)) # long time` + sage: y = var('y') + sage: parametric_plot((5*cos(x), x*y, cos(x*y)), (x, -4, 4), (y, -4, 4)) # long time` Graphics3d Object .. PLOT:: @@ -2621,8 +2639,8 @@ def parametric_plot(funcs, *args, **kwargs): :: - sage: t=var('t') - sage: parametric_plot( vector((sin(t), sin(2*t))), (t, 0, 2*pi), color='green') # long time + sage: t = var('t') + sage: parametric_plot(vector((sin(t), sin(2*t))), (t, 0, 2*pi), color='green') # long time Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -2693,8 +2711,8 @@ def parametric_plot(funcs, *args, **kwargs): One test for :trac:`7165`:: - sage: m = SR.var('m') - sage: parametric_plot([real(exp(i*m)),imaginary(exp(i*m))], (m,0,7)) + sage: m = SR.var('m') # optional - sage.symbolic + sage: parametric_plot([real(exp(i*m)), imaginary(exp(i*m))], (m, 0, 7)) # optional - sage.symbolic Graphics object consisting of 1 graphics primitive """ num_ranges = 0 @@ -2797,7 +2815,8 @@ def polar_plot(funcs, *args, **kwds): Fill the area between two functions:: - sage: polar_plot(cos(4*x) + 1.5, 0, 2*pi, fill=0.5 * cos(4*x) + 2.5, fillcolor='orange') + sage: polar_plot(cos(4*x) + 1.5, 0, 2*pi, fill=0.5 * cos(4*x) + 2.5, + ....: fillcolor='orange') Graphics object consisting of 2 graphics primitives .. PLOT:: @@ -2807,7 +2826,8 @@ def polar_plot(funcs, *args, **kwds): Fill the area between several spirals:: - sage: polar_plot([(1.2+k*0.2)*log(x) for k in range(6)], 1, 3 * pi, fill={0: [1], 2: [3], 4: [5]}) + sage: polar_plot([(1.2+k*0.2)*log(x) for k in range(6)], 1, 3 * pi, + ....: fill={0: [1], 2: [3], 4: [5]}) Graphics object consisting of 9 graphics primitives .. PLOT:: @@ -2863,7 +2883,7 @@ def list_plot(data, plotjoined=False, **kwargs): EXAMPLES:: - sage: list_plot([i^2 for i in range(5)]) # long time + sage: list_plot([i^2 for i in range(5)]) # long time Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -2896,8 +2916,8 @@ def list_plot(data, plotjoined=False, **kwargs): You can provide a numpy array.:: - sage: import numpy - sage: list_plot(numpy.arange(10)) + sage: import numpy # optional - numpy + sage: list_plot(numpy.arange(10)) # optional - numpy Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -2908,7 +2928,7 @@ def list_plot(data, plotjoined=False, **kwargs): :: - sage: list_plot(numpy.array([[1,2], [2,3], [3,4]])) + sage: list_plot(numpy.array([[1,2], [2,3], [3,4]])) # optional - numpy Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -2976,7 +2996,9 @@ def list_plot(data, plotjoined=False, **kwargs): sage: list_plot(x_coords, y_coords) Traceback (most recent call last): ... - TypeError: The second argument 'plotjoined' should be boolean (True or False). If you meant to plot two lists 'x' and 'y' against each other, use 'list_plot(list(zip(x,y)))'. + TypeError: The second argument 'plotjoined' should be boolean (True or False). + If you meant to plot two lists 'x' and 'y' against each other, + use 'list_plot(list(zip(x,y)))'. Dictionaries with numeric keys and values can be plotted:: @@ -3023,12 +3045,12 @@ def list_plot(data, plotjoined=False, **kwargs): Instead this will work. We drop the point `(0,1)`.:: - sage: list_plot(list(zip(range(1,len(yl)), yl[1:])), scale='loglog') # long time + sage: list_plot(list(zip(range(1,len(yl)), yl[1:])), scale='loglog') # long time Graphics object consisting of 1 graphics primitive We use :func:`list_plot_loglog` and plot in a different base.:: - sage: list_plot_loglog(list(zip(range(1,len(yl)), yl[1:])), base=2) # long time + sage: list_plot_loglog(list(zip(range(1,len(yl)), yl[1:])), base=2) # long time Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -3235,22 +3257,22 @@ def plot_semilogy(funcs, *args, **kwds): EXAMPLES:: - sage: plot_semilogy(exp, (1,10)) # long time # plot in semilogy scale, base 10 + sage: plot_semilogy(exp, (1, 10)) # long time # plot in semilogy scale, base 10 Graphics object consisting of 1 graphics primitive .. PLOT:: - g = plot_semilogy(exp, (1,10)) # long time # plot in semilogy scale, base 10 + g = plot_semilogy(exp, (1,10)) # long time # plot in semilogy scale, base 10 sphinx_plot(g) :: - sage: plot_semilogy(exp, (1,10), base=2) # long time # with base 2 + sage: plot_semilogy(exp, (1, 10), base=2) # long time # with base 2 Graphics object consisting of 1 graphics primitive .. PLOT:: - g = plot_semilogy(exp, (1,10), base=2) # long time # with base 2 + g = plot_semilogy(exp, (1,10), base=2) # long time # with base 2 sphinx_plot(g) """ @@ -3274,19 +3296,20 @@ def list_plot_loglog(data, plotjoined=False, **kwds): EXAMPLES:: sage: yl = [5**k for k in range(10)]; xl = [2**k for k in range(10)] - sage: list_plot_loglog(list(zip(xl, yl))) # long time # plot in loglog scale with base 10 + sage: list_plot_loglog(list(zip(xl, yl))) # long time # use loglog scale with base 10 Graphics object consisting of 1 graphics primitive .. PLOT:: yl = [5**k for k in range(10)] xl = [2**k for k in range(10)] - g = list_plot_loglog(list(zip(xl, yl))) # long time # plot in loglog scale with base 10 + g = list_plot_loglog(list(zip(xl, yl))) # long time # plot in loglog scale with base 10 sphinx_plot(g) :: - sage: list_plot_loglog(list(zip(xl, yl)), base=2.1) # long time # with base 2.1 on both axes + sage: list_plot_loglog(list(zip(xl, yl)), # long time # with base 2.1 on both axes + ....: base=2.1) Graphics object consisting of 1 graphics primitive .. PLOT:: @@ -3298,7 +3321,8 @@ def list_plot_loglog(data, plotjoined=False, **kwds): :: - sage: list_plot_loglog(list(zip(xl, yl)), base=(2,5)) # long time + sage: list_plot_loglog(list(zip(xl, yl)), # long time + ....: base=(2, 5)) Graphics object consisting of 1 graphics primitive .. warning:: @@ -3472,13 +3496,14 @@ def reshape(v, n, m): :: - sage: M = [[plot(sin(k*x),(x,-pi,pi)) for k in range(3)],[plot(cos(j*x),(x,-pi,pi)) for j in [3..5]]] + sage: M = [[plot(sin(k*x), (x,-pi,pi)) for k in range(3)], + ....: [plot(cos(j*x), (x,-pi,pi)) for j in [3..5]]] sage: graphics_array(M,6,1) # long time (up to 4s on sage.math, 2012) Graphics Array of size 6 x 1 TESTS:: - sage: L = [plot(sin(k*x),(x,-pi,pi)) for k in [1..3]] + sage: L = [plot(sin(k*x), (x,-pi,pi)) for k in [1..3]] sage: graphics_array(L,0,-1) # indirect doctest Traceback (most recent call last): ... @@ -3539,10 +3564,10 @@ def graphics_array(array, nrows=None, ncols=None): sage: f(x) = sin(x) sage: g(x) = sin(2*x) sage: h(x) = sin(4*x) - sage: p1 = plot(f, (-2*pi,2*pi), color=hue(0.5)) # long time - sage: p2 = plot(g, (-2*pi,2*pi), color=hue(0.9)) # long time - sage: p3 = parametric_plot((f,g), (0,2*pi), color=hue(0.6)) # long time - sage: p4 = parametric_plot((f,h), (0,2*pi), color=hue(1.0)) # long time + sage: p1 = plot(f, (-2*pi,2*pi), color=hue(0.5)) # long time + sage: p2 = plot(g, (-2*pi,2*pi), color=hue(0.9)) # long time + sage: p3 = parametric_plot((f,g), (0,2*pi), color=hue(0.6)) # long time + sage: p4 = parametric_plot((f,h), (0,2*pi), color=hue(1.0)) # long time Now make a graphics array out of the plots:: @@ -3570,8 +3595,8 @@ def h(x): return sin(4*x) Here we give only one row:: - sage: p1 = plot(sin,(-4,4)) - sage: p2 = plot(cos,(-4,4)) + sage: p1 = plot(sin, (-4,4)) + sage: p2 = plot(cos, (-4,4)) sage: ga = graphics_array([p1, p2]) sage: ga Graphics Array of size 1 x 2 @@ -3827,7 +3852,8 @@ def adaptive_refinement(f, p1, p2, adaptive_tolerance=0.01, TESTS:: sage: from sage.plot.plot import adaptive_refinement - sage: adaptive_refinement(sin, (0,0), (pi,0), adaptive_tolerance=0.01, adaptive_recursion=0) + sage: adaptive_refinement(sin, (0,0), (pi,0), adaptive_tolerance=0.01, + ....: adaptive_recursion=0) [] sage: adaptive_refinement(sin, (0,0), (pi,0), adaptive_tolerance=0.01) [(0.125*pi, 0.3826834323650898), (0.1875*pi, 0.5555702330196022), (0.25*pi, 0.7071067811865475), (0.3125*pi, 0.8314696123025452), (0.375*pi, 0.9238795325112867), (0.4375*pi, 0.9807852804032304), (0.5*pi, 1.0), (0.5625*pi, 0.9807852804032304), (0.625*pi, 0.9238795325112867), (0.6875*pi, 0.8314696123025455), (0.75*pi, 0.7071067811865476), (0.8125*pi, 0.5555702330196022), (0.875*pi, 0.3826834323650899)] @@ -3843,7 +3869,8 @@ def adaptive_refinement(f, p1, p2, adaptive_tolerance=0.01, sage: f(x) = sin(1/x) sage: n1 = len(adaptive_refinement(f, (0,0), (pi,0), adaptive_tolerance=0.01)); n1 15 - sage: n2 = len(adaptive_refinement(f, (0,0), (pi,0), adaptive_recursion=10, adaptive_tolerance=0.01)); n2 + sage: n2 = len(adaptive_refinement(f, (0,0), (pi,0), adaptive_recursion=10, + ....: adaptive_tolerance=0.01)); n2 79 sage: n3 = len(adaptive_refinement(f, (0,0), (pi,0), adaptive_tolerance=0.001)); n3 26 diff --git a/src/sage/plot/plot3d/plot3d.py b/src/sage/plot/plot3d/plot3d.py index ff24627e81e..592781a5cba 100644 --- a/src/sage/plot/plot3d/plot3d.py +++ b/src/sage/plot/plot3d/plot3d.py @@ -220,7 +220,8 @@ def f(x,y): return math.exp(x/5)*math.cos(y) from sage.plot.colors import rainbow from .texture import Texture -from sage.functions.trig import cos, sin +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.trig", ["cos", "sin"]) from sage.misc.sageinspect import sage_getargspec, is_function_or_cython_function diff --git a/src/sage/probability/random_variable.py b/src/sage/probability/random_variable.py index 11dc4ca3cf7..2b9d1437d29 100644 --- a/src/sage/probability/random_variable.py +++ b/src/sage/probability/random_variable.py @@ -17,7 +17,8 @@ import sage.rings.abc from sage.structure.parent import Parent -from sage.functions.log import log +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.log", "log") from sage.misc.functional import sqrt from sage.rings.rational_field import is_RationalField from sage.sets.set import Set diff --git a/src/sage/quadratic_forms/binary_qf.py b/src/sage/quadratic_forms/binary_qf.py index 96247522baf..4ed7379ecef 100755 --- a/src/sage/quadratic_forms/binary_qf.py +++ b/src/sage/quadratic_forms/binary_qf.py @@ -1743,9 +1743,9 @@ def BinaryQF_reduced_representatives(D, primitive_only=False, proper=True): sage: len(BinaryQF_reduced_representatives(-13*4)) 2 - sage: QuadraticField(-13*4, 'a').class_number() + sage: QuadraticField(-13*4, 'a').class_number() # optional - sage.rings.number_field 2 - sage: p = next_prime(2^20); p + sage: p = next_prime(2^20); p # optional - sage.libs.pari 1048583 sage: len(BinaryQF_reduced_representatives(-p)) # optional - sage.libs.pari 689 diff --git a/src/sage/quadratic_forms/quadratic_form.py b/src/sage/quadratic_forms/quadratic_form.py index e2691795ba4..fad93799b30 100644 --- a/src/sage/quadratic_forms/quadratic_form.py +++ b/src/sage/quadratic_forms/quadratic_form.py @@ -423,6 +423,7 @@ class QuadraticForm(SageObject): 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", diff --git a/src/sage/repl/configuration.py b/src/sage/repl/configuration.py index 1890dc207d4..5a1f9c44ca8 100644 --- a/src/sage/repl/configuration.py +++ b/src/sage/repl/configuration.py @@ -7,11 +7,11 @@ the IPython simple prompt is being used:: sage: cmd = 'print([sys.stdin.isatty(), sys.stdout.isatty()])' - sage: import pexpect - sage: output = pexpect.run( + sage: import pexpect # optional - pexpect + sage: output = pexpect.run( # optional - pexpect ....: 'bash -c \'echo "{0}" | sage\''.format(cmd), ....: ).decode('utf-8', 'surrogateescape') - sage: 'sage: [False, True]' in output + sage: 'sage: [False, True]' in output # optional - pexpect True """ diff --git a/src/sage/repl/display/formatter.py b/src/sage/repl/display/formatter.py index 7e06656d880..6b2b6e1a083 100644 --- a/src/sage/repl/display/formatter.py +++ b/src/sage/repl/display/formatter.py @@ -24,17 +24,17 @@ sage: from sage.repl.interpreter import get_test_shell sage: shell = get_test_shell() sage: shell.run_cell('%display ascii_art') - sage: shell.run_cell('integral(x^2/pi^x, x)') + sage: shell.run_cell('integral(x^2/pi^x, x)') # optional - sage.symbolic -x / 2 2 \ -pi *\x *log (pi) + 2*x*log(pi) + 2/ -------------------------------------- 3 log (pi) - sage: shell.run_cell("i = var('i')") - sage: shell.run_cell('sum(i*x^i, i, 0, 10)') + sage: shell.run_cell("i = var('i')") # optional - sage.symbolic + sage: shell.run_cell('sum(i*x^i, i, 0, 10)') # optional - sage.symbolic 10 9 8 7 6 5 4 3 2 10*x + 9*x + 8*x + 7*x + 6*x + 5*x + 4*x + 3*x + 2*x + x - sage: shell.run_cell('StandardTableaux(4).list()') + sage: shell.run_cell('StandardTableaux(4).list()') # optional - sage.combinat [ [ 1 4 1 3 [ 1 3 4 1 2 4 1 2 3 1 3 1 2 2 2 @@ -132,8 +132,8 @@ def format(self, obj, include=None, exclude=None): sage: from sage.repl.interpreter import get_test_shell sage: shell = get_test_shell() sage: shell.run_cell('%display ascii_art') # indirect doctest - sage: shell.run_cell("i = var('i')") - sage: shell.run_cell('sum(i*x^i, i, 0, 10)') + sage: shell.run_cell("i = var('i')") # optional - sage.symbolic + sage: shell.run_cell('sum(i*x^i, i, 0, 10)') # optional - sage.symbolic 10 9 8 7 6 5 4 3 2 10*x + 9*x + 8*x + 7*x + 6*x + 5*x + 4*x + 3*x + 2*x + x sage: shell.run_cell('%display default') diff --git a/src/sage/repl/display/jsmol_iframe.py b/src/sage/repl/display/jsmol_iframe.py index 4775d2a02e7..0a7456ad75c 100644 --- a/src/sage/repl/display/jsmol_iframe.py +++ b/src/sage/repl/display/jsmol_iframe.py @@ -112,7 +112,7 @@ def __init__(self, jmol, path_to_jsmol=None, width='100%', height='100%'): EXAMPLES:: sage: from sage.repl.display.jsmol_iframe import JSMolHtml - sage: JSMolHtml(sphere(), width=500, height=300) + sage: JSMolHtml(sphere(), width=500, height=300) # optional - sage.plot JSmol Window 500x300 """ from sage.repl.rich_output.output_graphics3d import OutputSceneJmol diff --git a/src/sage/repl/interface_magic.py b/src/sage/repl/interface_magic.py index 856bdcd120d..95e1c90ec7a 100644 --- a/src/sage/repl/interface_magic.py +++ b/src/sage/repl/interface_magic.py @@ -123,7 +123,7 @@ def register_all(cls, shell=None): ('maxima', 'cell') sage: 'gap' in MockShell.magics True - sage: 'maxima' in MockShell.magics + sage: 'maxima' in MockShell.magics # optional - sage.symbolic True """ if shell is None: diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index cad6a47ca8b..4d7ee485b29 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -350,12 +350,13 @@ def cython(self, line, cell): sage: from sage.repl.interpreter import get_test_shell sage: shell = get_test_shell() - sage: shell.run_cell(''' + sage: shell.run_cell( # optional - sage.misc.cython + ....: ''' ....: %%cython ....: def f(): ....: print('test') ....: ''') - sage: f() + sage: f() # optional - sage.misc.cython test """ from sage.misc.cython import cython_compile @@ -406,10 +407,10 @@ def fortran(self, line, cell): ....: ''') sage: fib - sage: from numpy import array - sage: a = array(range(10), dtype=float) - sage: fib(a, 10) - sage: a + sage: from numpy import array # optional - numpy + sage: a = array(range(10), dtype=float) # optional - numpy + sage: fib(a, 10) # optional - numpy + sage: a # optional - numpy array([ 0., 1., 1., 2., 3., 5., 8., 13., 21., 34.]) """ from sage.misc.inline_fortran import fortran diff --git a/src/sage/repl/ipython_kernel/interact.py b/src/sage/repl/ipython_kernel/interact.py index 4f96a212ab7..3677a5a8f83 100644 --- a/src/sage/repl/ipython_kernel/interact.py +++ b/src/sage/repl/ipython_kernel/interact.py @@ -182,12 +182,12 @@ def widget_from_single_value(cls, abbrev, *args, **kwds): sage: from sage.repl.ipython_kernel.interact import sage_interactive sage: sage_interactive.widget_from_single_value("sin(x)") ...Text(value='sin(x)') - sage: sage_interactive.widget_from_single_value(sin(x)) + sage: sage_interactive.widget_from_single_value(sin(x)) # optional - sage.symbolic ...EvalText(value='sin(x)') - sage: from sage.plot.colors import Color - sage: sage_interactive.widget_from_single_value(matrix([[1, 2], [3, 4]])) + sage: sage_interactive.widget_from_single_value(matrix([[1, 2], [3, 4]])) # optional - sage.modules ...Grid(value=[[1, 2], [3, 4]], children=(Label(value=''), VBox(children=(EvalText(value='1', layout=Layout(max_width='5em')), EvalText(value='3', layout=Layout(max_width='5em')))), VBox(children=(EvalText(value='2', layout=Layout(max_width='5em')), EvalText(value='4', layout=Layout(max_width='5em')))))) - sage: sage_interactive.widget_from_single_value(Color('cornflowerblue')) + sage: from sage.plot.colors import Color # optional - sage.plot + sage: sage_interactive.widget_from_single_value(Color('cornflowerblue')) # optional - sage.plot ...SageColorPicker(value='#6495ed') """ # Support Sage matrices and colors @@ -226,15 +226,15 @@ def widget_from_tuple(cls, abbrev, *args, **kwds): ...IntSlider(value=3, max=10) sage: sage_interactive.widget_from_tuple((2, [('one', 1), ('two', 2), ('three', 3)])) ...Dropdown(index=1, options=(('one', 1), ('two', 2), ('three', 3)), value=2) - sage: sage_interactive.widget_from_tuple( (sqrt(2), pi) ) + sage: sage_interactive.widget_from_tuple( (sqrt(2), pi) ) # optional - sage.symbolic ...FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951) TESTS: Symbolic subrings:: - sage: SCR = SR.subring(no_variables=True) - sage: sage_interactive.widget_from_tuple( (SCR(sqrt(2)), SCR(pi)) ) + sage: SCR = SR.subring(no_variables=True) # optional - sage.symbolic + sage: sage_interactive.widget_from_tuple( (SCR(sqrt(2)), SCR(pi)) ) # optional - sage.symbolic ...FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951) """ # Support (description, abbrev) diff --git a/src/sage/repl/ipython_kernel/widgets.py b/src/sage/repl/ipython_kernel/widgets.py index 3ba45df9b04..1ba03bf4b9b 100644 --- a/src/sage/repl/ipython_kernel/widgets.py +++ b/src/sage/repl/ipython_kernel/widgets.py @@ -100,7 +100,7 @@ class TransformWidget(): sage: from ipywidgets import ToggleButtons sage: from sage.repl.ipython_kernel.widgets import TransformWidget sage: class TransformToggleButtons(TransformWidget, ToggleButtons): pass - sage: w = TransformToggleButtons(options=["pi", "e"], transform=lambda x: x+x) + sage: w = TransformToggleButtons(options=["pi", "e"], transform=lambda x: x + x) sage: w TransformToggleButtons(options=('pi', 'e'), value='pi') sage: w.get_interact_value() @@ -239,7 +239,8 @@ class TransformIntRangeSlider(TransformWidget, IntRangeSlider): EXAMPLES:: sage: from sage.repl.ipython_kernel.widgets import TransformIntRangeSlider - sage: w = TransformIntRangeSlider(min=0, max=100, value=(7,9), transform=lambda x: x[1]-x[0]) + sage: w = TransformIntRangeSlider(min=0, max=100, value=(7, 9), + ....: transform=lambda x: x[1] - x[0]) sage: w TransformIntRangeSlider(value=(7, 9)) sage: w.get_interact_value() @@ -256,7 +257,8 @@ class TransformFloatRangeSlider(TransformWidget, FloatRangeSlider): EXAMPLES:: sage: from sage.repl.ipython_kernel.widgets import TransformFloatRangeSlider - sage: w = TransformFloatRangeSlider(min=0, max=100, value=(7,9), transform=lambda x: x[1]-x[0]) + sage: w = TransformFloatRangeSlider(min=0, max=100, value=(7, 9), + ....: transform=lambda x: x[1] - x[0]) sage: w TransformFloatRangeSlider(value=(7.0, 9.0)) sage: w.get_interact_value() @@ -273,7 +275,7 @@ class TransformText(TransformWidget, Text): EXAMPLES:: sage: from sage.repl.ipython_kernel.widgets import TransformText - sage: w = TransformText(value="hello", transform=lambda x: x+x) + sage: w = TransformText(value="hello", transform=lambda x: x + x) sage: w TransformText(value='hello') sage: w.get_interact_value() @@ -290,7 +292,7 @@ class TransformTextarea(TransformWidget, Textarea): EXAMPLES:: sage: from sage.repl.ipython_kernel.widgets import TransformTextarea - sage: w = TransformTextarea(value="hello", transform=lambda x: x+x) + sage: w = TransformTextarea(value="hello", transform=lambda x: x + x) sage: w TransformTextarea(value='hello') sage: w.get_interact_value() @@ -351,7 +353,7 @@ def get_interact_value(self): EXAMPLES:: sage: from sage.repl.ipython_kernel.widgets import SageColorPicker - sage: SageColorPicker().get_interact_value() + sage: SageColorPicker().get_interact_value() # optional - sage.plot RGB color (0.0, 0.0, 0.0) """ return Color(self.value) @@ -370,7 +372,10 @@ class Grid(TransformWidget, HBox, ValueWidget): sage: from sage.repl.ipython_kernel.widgets import Grid sage: w = Grid(2, 2, lambda i,j: Text(value="%s,%s"%(i,j))) sage: w - Grid(value=[['0,0', '0,1'], ['1,0', '1,1']], children=(Label(value=''), VBox(children=(Text(value='0,0'), Text(value='1,0'))), VBox(children=(Text(value='0,1'), Text(value='1,1'))))) + Grid(value=[['0,0', '0,1'], ['1,0', '1,1']], + children=(Label(value=''), + VBox(children=(Text(value='0,0'), Text(value='1,0'))), + VBox(children=(Text(value='0,1'), Text(value='1,1'))))) sage: w.get_interact_value() [['0,0', '0,1'], ['1,0', '1,1']] """ @@ -398,7 +403,10 @@ def __init__(self, nrows, ncols, make_widget, description=u"", transform=None): sage: w = Grid(2, 2, lambda i,j: EvalText(str(j+4*i)), ....: description="2x2 matrix", transform=matrix) sage: w - Grid(value=[[0, 1], [4, 5]], children=(Label(value='2x2 matrix'), VBox(children=(EvalText(value='0'), EvalText(value='4'))), VBox(children=(EvalText(value='1'), EvalText(value='5'))))) + Grid(value=[[0, 1], [4, 5]], + children=(Label(value='2x2 matrix'), + VBox(children=(EvalText(value='0'), EvalText(value='4'))), + VBox(children=(EvalText(value='1'), EvalText(value='5'))))) sage: w.get_interact_value() [0 1] [4 5] diff --git a/src/sage/repl/load.py b/src/sage/repl/load.py index d43363682b0..8f9519eb095 100644 --- a/src/sage/repl/load.py +++ b/src/sage/repl/load.py @@ -132,7 +132,7 @@ def load(filename, globals, attach=False): sage: with open(t, 'w') as f: ....: _ = f.write("print(('hi', 2^3)); z = -2^7") sage: z = 1 - sage: sage.repl.load.load(t, globals()) + sage: sage.repl.load.load(t, globals()) # optional - sage.misc.cython Compiling ... ('hi', 1) sage: z diff --git a/src/sage/repl/preparse.py b/src/sage/repl/preparse.py index 6c5e15042fb..618fb66fc2a 100644 --- a/src/sage/repl/preparse.py +++ b/src/sage/repl/preparse.py @@ -82,18 +82,18 @@ Symbolic functional notation:: - sage: a=10; f(theta, beta) = theta + beta; b = x^2 + theta # optional - sage.symbolic - sage: f # optional - sage.symbolic + sage: a=10; f(theta, beta) = theta + beta; b = x^2 + theta # optional - sage.symbolic + sage: f # optional - sage.symbolic (theta, beta) |--> beta + theta - sage: a # optional - sage.symbolic + sage: a # optional - sage.symbolic 10 - sage: b # optional - sage.symbolic + sage: b # optional - sage.symbolic x^2 + theta - sage: f(theta,theta) # optional - sage.symbolic + sage: f(theta,theta) # optional - sage.symbolic 2*theta - sage: a = 5; f(x,y) = x*y*sqrt(a) # optional - sage.symbolic - sage: f # optional - sage.symbolic + sage: a = 5; f(x,y) = x*y*sqrt(a) # optional - sage.symbolic + sage: f # optional - sage.symbolic (x, y) |--> sqrt(5)*x*y This involves an =-, but should still be turned into a symbolic @@ -101,8 +101,8 @@ sage: preparse('a(x) =- 5') '__tmp__=var("x"); a = symbolic_expression(- Integer(5)).function(x)' - sage: f(x)=-x # optional - sage.symbolic - sage: f(10) # optional - sage.symbolic + sage: f(x)=-x # optional - sage.symbolic + sage: f(10) # optional - sage.symbolic -10 This involves -=, which should not be turned into a symbolic @@ -1726,7 +1726,7 @@ def preparse(line, reset=True, do_time=False, ignore_prompts=False, "ZZ = ZZ['u,v']; (x, y,) = ZZ._first_ngens(2)" sage: preparse("ZZ. = QQ[2^(1/3)]") 'ZZ = QQ[Integer(2)**(Integer(1)/Integer(3))]; (x,) = ZZ._first_ngens(1)' - sage: QQ[2^(1/3)] + sage: QQ[2^(1/3)] # optional - sage.symbolic sage.rings.number_field Number Field in a with defining polynomial x^3 - 2 with a = 1.259921049894873? sage: preparse("a^b") diff --git a/src/sage/repl/rich_output/backend_base.py b/src/sage/repl/rich_output/backend_base.py index e9ca0b4d3ba..5674f726728 100644 --- a/src/sage/repl/rich_output/backend_base.py +++ b/src/sage/repl/rich_output/backend_base.py @@ -459,11 +459,11 @@ def latex_formatter(self, obj, **kwds): sage: out.html.get_str() '\\(\\displaystyle \\frac{1}{2}\\)' - sage: out = backend.latex_formatter([1/2, x, 3/4, ZZ], concatenate=False) - sage: out.html.get_str() + sage: out = backend.latex_formatter([1/2, x, 3/4, ZZ], concatenate=False) # optional - sage.symbolic + sage: out.html.get_str() # optional - sage.symbolic '\\(\\displaystyle \\newcommand{\\Bold}[1]{\\mathbf{#1}}\\left[\\frac{1}{2}, x, \\frac{3}{4}, \\Bold{Z}\\right]\\)' - sage: out = backend.latex_formatter([1/2, x, 3/4, ZZ], concatenate=True) - sage: out.html.get_str() + sage: out = backend.latex_formatter([1/2, x, 3/4, ZZ], concatenate=True) # optional - sage.symbolic + sage: out.html.get_str() # optional - sage.symbolic '\\(\\displaystyle \\newcommand{\\Bold}[1]{\\mathbf{#1}}\\frac{1}{2} x \\frac{3}{4} \\Bold{Z}\\)' TESTS:: diff --git a/src/sage/repl/rich_output/backend_doctest.py b/src/sage/repl/rich_output/backend_doctest.py index da9cb737a2a..fd532e82fa3 100644 --- a/src/sage/repl/rich_output/backend_doctest.py +++ b/src/sage/repl/rich_output/backend_doctest.py @@ -164,14 +164,14 @@ def displayhook(self, plain_text, rich_output): This ends up calling the displayhook:: - sage: plt = plot(sin) - sage: plt + sage: plt = plot(sin) # optional - sage.plot sage.symbolic + sage: plt # optional - sage.plot sage.symbolic Graphics object consisting of 1 graphics primitive - sage: plt.show() + sage: plt.show() # optional - sage.plot sage.symbolic sage: from sage.repl.rich_output import get_display_manager sage: dm = get_display_manager() - sage: dm.displayhook(plt) # indirect doctest + sage: dm.displayhook(plt) # indirect doctest # optional - sage.plot sage.symbolic Graphics object consisting of 1 graphics primitive """ self.validate(rich_output) @@ -198,14 +198,14 @@ def display_immediately(self, plain_text, rich_output): displayhook, the plot is still shown. Nothing is shown during doctests:: - sage: plt = plot(sin) - sage: plt + sage: plt = plot(sin) # optional - sage.plot sage.symbolic + sage: plt # optional - sage.plot sage.symbolic Graphics object consisting of 1 graphics primitive - sage: plt.show() + sage: plt.show() # optional - sage.plot sage.symbolic sage: from sage.repl.rich_output import get_display_manager sage: dm = get_display_manager() - sage: dm.display_immediately(plt) # indirect doctest + sage: dm.display_immediately(plt) # indirect doctest # optional - sage.plot sage.symbolic """ self.validate(rich_output) types_to_print = [OutputPlainText, OutputAsciiArt, OutputUnicodeArt, OutputHtml] diff --git a/src/sage/repl/rich_output/display_manager.py b/src/sage/repl/rich_output/display_manager.py index f022335f8e6..80beda0f391 100644 --- a/src/sage/repl/rich_output/display_manager.py +++ b/src/sage/repl/rich_output/display_manager.py @@ -708,13 +708,14 @@ def graphics_from_save(self, save_function, save_kwds, sage: from sage.repl.rich_output import get_display_manager sage: dm = get_display_manager() - sage: plt = plot(sin) - sage: out = dm.graphics_from_save(plt.save, dict(), '.png', dm.types.OutputImagePng) - sage: out + sage: plt = plot(sin) # optional - sage.symbolic sage.plot + sage: out = dm.graphics_from_save(plt.save, dict(), '.png', # optional - sage.symbolic sage.plot + ....: dm.types.OutputImagePng) + sage: out # optional - sage.symbolic sage.plot OutputImagePng container - sage: out.png.get().startswith(b'\x89PNG') + sage: out.png.get().startswith(b'\x89PNG') # optional - sage.symbolic sage.plot True - sage: out.png.filename() # random + sage: out.png.filename() # random # optional - sage.symbolic sage.plot '/home/user/.sage/temp/localhost.localdomain/23903/tmp_pu5woK.png' """ import os diff --git a/src/sage/repl/rich_output/output_basic.py b/src/sage/repl/rich_output/output_basic.py index 2166715d364..29391c90b79 100644 --- a/src/sage/repl/rich_output/output_basic.py +++ b/src/sage/repl/rich_output/output_basic.py @@ -320,7 +320,7 @@ def __init__(self, latex): EXAMPLES:: sage: from sage.repl.rich_output.output_catalog import OutputLatex - sage: OutputLatex(latex(sqrt(x))) + sage: OutputLatex(latex(sqrt(x))) # optional - sage.symbolic OutputLatex container """ self.latex = OutputBuffer(latex) diff --git a/src/sage/rings/abc.pyx b/src/sage/rings/abc.pyx index 4d4e9bfd104..77536d718bb 100644 --- a/src/sage/rings/abc.pyx +++ b/src/sage/rings/abc.pyx @@ -14,13 +14,13 @@ class NumberField_quadratic(Field): EXAMPLES:: sage: import sage.rings.abc - sage: K. = QuadraticField(2) # optional - sage.rings.number_field - sage: isinstance(K, sage.rings.abc.NumberField_quadratic) # optional - sage.rings.number_field + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: isinstance(K, sage.rings.abc.NumberField_quadratic) # optional - sage.rings.number_field True By design, there is a unique direct subclass:: - sage: sage.rings.abc.NumberField_quadratic.__subclasses__() # optional - sage.rings.number_field + sage: sage.rings.abc.NumberField_quadratic.__subclasses__() # optional - sage.rings.number_field [] sage: len(sage.rings.abc.NumberField_quadratic.__subclasses__()) <= 1 @@ -40,13 +40,13 @@ class NumberField_cyclotomic(Field): EXAMPLES:: sage: import sage.rings.abc - sage: K. = CyclotomicField(15) # optional - sage.rings.number_field - sage: isinstance(K, sage.rings.abc.NumberField_cyclotomic) # optional - sage.rings.number_field + sage: K. = CyclotomicField(15) # optional - sage.rings.number_field + sage: isinstance(K, sage.rings.abc.NumberField_cyclotomic) # optional - sage.rings.number_field True By design, there is a unique direct subclass:: - sage: sage.rings.abc.NumberField_cyclotomic.__subclasses__() # optional - sage.rings.number_field + sage: sage.rings.abc.NumberField_cyclotomic.__subclasses__() # optional - sage.rings.number_field [] sage: len(sage.rings.abc.NumberField_cyclotomic.__subclasses__()) <= 1 @@ -66,16 +66,16 @@ class AlgebraicField_common(Field): EXAMPLES:: sage: import sage.rings.abc - sage: isinstance(QQbar, sage.rings.abc.AlgebraicField_common) # optional - sage.rings.number_field + sage: isinstance(QQbar, sage.rings.abc.AlgebraicField_common) # optional - sage.rings.number_field True - sage: isinstance(AA, sage.rings.abc.AlgebraicField_common) # optional - sage.rings.number_field + sage: isinstance(AA, sage.rings.abc.AlgebraicField_common) # optional - sage.rings.number_field True By design, other than the abstract subclasses :class:`~sage.rings.abc.AlgebraicField` and :class:`~sage.rings.abc.AlgebraicRealField`, there is only one direct implementation subclass:: - sage: sage.rings.abc.AlgebraicField_common.__subclasses__() # optional - sage.rings.number_field + sage: sage.rings.abc.AlgebraicField_common.__subclasses__() # optional - sage.rings.number_field [, , ] @@ -97,14 +97,14 @@ class AlgebraicField(AlgebraicField_common): EXAMPLES:: sage: import sage.rings.abc - sage: isinstance(QQbar, sage.rings.abc.AlgebraicField) # optional - sage.rings.number_field + sage: isinstance(QQbar, sage.rings.abc.AlgebraicField) # optional - sage.rings.number_field True - sage: isinstance(AA, sage.rings.abc.AlgebraicField) # optional - sage.rings.number_field + sage: isinstance(AA, sage.rings.abc.AlgebraicField) # optional - sage.rings.number_field False By design, there is a unique direct subclass:: - sage: sage.rings.abc.AlgebraicField.__subclasses__() # optional - sage.rings.number_field + sage: sage.rings.abc.AlgebraicField.__subclasses__() # optional - sage.rings.number_field [] sage: len(sage.rings.abc.AlgebraicField.__subclasses__()) <= 1 @@ -124,14 +124,14 @@ class AlgebraicRealField(AlgebraicField_common): EXAMPLES:: sage: import sage.rings.abc - sage: isinstance(QQbar, sage.rings.abc.AlgebraicRealField) # optional - sage.rings.number_field + sage: isinstance(QQbar, sage.rings.abc.AlgebraicRealField) # optional - sage.rings.number_field False - sage: isinstance(AA, sage.rings.abc.AlgebraicRealField) # optional - sage.rings.number_field + sage: isinstance(AA, sage.rings.abc.AlgebraicRealField) # optional - sage.rings.number_field True By design, there is a unique direct subclass:: - sage: sage.rings.abc.AlgebraicRealField.__subclasses__() # optional - sage.rings.number_field + sage: sage.rings.abc.AlgebraicRealField.__subclasses__() # optional - sage.rings.number_field [] sage: len(sage.rings.abc.AlgebraicRealField.__subclasses__()) <= 1 @@ -376,13 +376,13 @@ class Order: EXAMPLES:: sage: import sage.rings.abc - sage: K. = NumberField(x^2 + 1); O = K.order(2*a) # optional - sage.rings.number_field - sage: isinstance(O, sage.rings.abc.Order) # optional - sage.rings.number_field + sage: K. = NumberField(x^2 + 1); O = K.order(2*a) # optional - sage.rings.number_field + sage: isinstance(O, sage.rings.abc.Order) # optional - sage.rings.number_field True By design, there is a unique direct subclass:: - sage: sage.rings.abc.Order.__subclasses__() # optional - sage.rings.number_field + sage: sage.rings.abc.Order.__subclasses__() # optional - sage.rings.number_field [] sage: len(sage.rings.abc.Order.__subclasses__()) <= 1 @@ -402,14 +402,14 @@ class pAdicRing(EuclideanDomain): EXAMPLES:: sage: import sage.rings.abc - sage: isinstance(Zp(5), sage.rings.abc.pAdicRing) + sage: isinstance(Zp(5), sage.rings.abc.pAdicRing) # optional - sage.rings.padics True - sage: isinstance(Qp(5), sage.rings.abc.pAdicRing) + sage: isinstance(Qp(5), sage.rings.abc.pAdicRing) # optional - sage.rings.padics False By design, there is a unique direct subclass:: - sage: sage.rings.abc.pAdicRing.__subclasses__() + sage: sage.rings.abc.pAdicRing.__subclasses__() # optional - sage.rings.padics [] sage: len(sage.rings.abc.pAdicRing.__subclasses__()) <= 1 @@ -429,14 +429,14 @@ class pAdicField(Field): EXAMPLES:: sage: import sage.rings.abc - sage: isinstance(Zp(5), sage.rings.abc.pAdicField) + sage: isinstance(Zp(5), sage.rings.abc.pAdicField) # optional - sage.rings.padics False - sage: isinstance(Qp(5), sage.rings.abc.pAdicField) + sage: isinstance(Qp(5), sage.rings.abc.pAdicField) # optional - sage.rings.padics True By design, there is a unique direct subclass:: - sage: sage.rings.abc.pAdicField.__subclasses__() + sage: sage.rings.abc.pAdicField.__subclasses__() # optional - sage.rings.padics [] sage: len(sage.rings.abc.pAdicField.__subclasses__()) <= 1 @@ -456,13 +456,13 @@ cdef class SymbolicRing(CommutativeRing): EXAMPLES:: sage: import sage.rings.abc - sage: isinstance(SR, sage.rings.abc.SymbolicRing) # optional - sage.symbolic + sage: isinstance(SR, sage.rings.abc.SymbolicRing) # optional - sage.symbolic True By design, other than the abstract subclass :class:`~sage.rings.abc.CallableSymbolicExpressionRing`, there is only one direct implementation subclass:: - sage: sage.rings.abc.SymbolicRing.__subclasses__() # optional - sage.symbolic + sage: sage.rings.abc.SymbolicRing.__subclasses__() # optional - sage.symbolic [, ] @@ -483,13 +483,13 @@ class CallableSymbolicExpressionRing(SymbolicRing): EXAMPLES:: sage: import sage.rings.abc - sage: f = x.function(x).parent() # optional - sage.symbolic - sage: isinstance(f, sage.rings.abc.CallableSymbolicExpressionRing) # optional - sage.symbolic + sage: f = x.function(x).parent() # optional - sage.symbolic + sage: isinstance(f, sage.rings.abc.CallableSymbolicExpressionRing) # optional - sage.symbolic True By design, there is a unique direct subclass:: - sage: sage.rings.abc.CallableSymbolicExpressionRing.__subclasses__() # optional - sage.symbolic + sage: sage.rings.abc.CallableSymbolicExpressionRing.__subclasses__() # optional - sage.symbolic [] sage: len(sage.rings.abc.CallableSymbolicExpressionRing.__subclasses__()) <= 1 diff --git a/src/sage/rings/algebraic_closure_finite_field.py b/src/sage/rings/algebraic_closure_finite_field.py index 6f6b93955cb..fb62627c9dc 100644 --- a/src/sage/rings/algebraic_closure_finite_field.py +++ b/src/sage/rings/algebraic_closure_finite_field.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings r""" Algebraic closures of finite fields diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index 17dd9896212..f8e684e9d04 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -189,7 +189,9 @@ continued_fraction_list) # asymptotic ring -from .asymptotic.all import * +#from .asymptotic.all import * +lazy_import('sage.rings.asymptotic.asymptotic_ring', 'AsymptoticRing') +lazy_import('sage.rings.asymptotic.asymptotic_expansion_generators', 'asymptotic_expansions') # Register classes in numbers abc from . import numbers_abc diff --git a/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py b/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py index 37c2b2b81a6..4e3bb661c3c 100644 --- a/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +++ b/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py @@ -201,9 +201,10 @@ from sage.structure.element import RingElement from sage.structure.unique_representation import UniqueRepresentation from sage.rings.ring import Ring -from sage.calculus.var import var -from sage.calculus.functional import diff -from sage.symbolic.ring import SR +from sage.misc.lazy_import import lazy_import +lazy_import("sage.calculus.var", "var") +lazy_import("sage.calculus.functional", "diff") +lazy_import("sage.symbolic.ring", "SR") from sage.misc.misc_c import prod from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ diff --git a/src/sage/rings/bernmm.pyx b/src/sage/rings/bernmm.pyx index 00a3da0d1ff..fb633e2d6f1 100644 --- a/src/sage/rings/bernmm.pyx +++ b/src/sage/rings/bernmm.pyx @@ -13,7 +13,7 @@ Cython wrapper for bernmm library AUTHOR: - - David Harvey (2008-06): initial version +- David Harvey (2008-06): initial version """ #***************************************************************************** @@ -42,18 +42,18 @@ from sage.rings.rational cimport Rational def bernmm_bern_rat(long k, int num_threads = 1): r""" - Computes k-th Bernoulli number using a multimodular algorithm. + Compute `k`-th Bernoulli number using a multimodular algorithm. (Wrapper for bernmm library.) INPUT: - - k -- non-negative integer - - num_threads -- integer >= 1, number of threads to use + - ``k`` -- non-negative integer + - ``num_threads`` -- integer `\geq 1`, number of threads to use COMPLEXITY: - Pretty much quadratic in `k`. See the paper "A multimodular algorithm - for computing Bernoulli numbers", David Harvey, 2008, for more details. + Pretty much quadratic in `k`. See the paper "A multimodular algorithm + for computing Bernoulli numbers", David Harvey, 2008, for more details. EXAMPLES:: @@ -98,18 +98,18 @@ def bernmm_bern_rat(long k, int num_threads = 1): def bernmm_bern_modp(long p, long k): r""" - Computes `B_k \mod p`, where `B_k` is the k-th Bernoulli number. + Compute `B_k \mod p`, where `B_k` is the `k`-th Bernoulli number. - If `B_k` is not `p`-integral, returns -1. + If `B_k` is not `p`-integral, return `-1`. INPUT: - p -- a prime - k -- non-negative integer + - ``p`` -- a prime + - ``k`` -- non-negative integer COMPLEXITY: - Pretty much linear in `p`. + Pretty much linear in `p`. EXAMPLES:: diff --git a/src/sage/rings/bernoulli_mod_p.pyx b/src/sage/rings/bernoulli_mod_p.pyx index b46c6b41da1..53f1a5fb040 100644 --- a/src/sage/rings/bernoulli_mod_p.pyx +++ b/src/sage/rings/bernoulli_mod_p.pyx @@ -53,11 +53,9 @@ def verify_bernoulli_mod_p(data): INPUT: - data -- list, same format as output of bernoulli_mod_p function + - ``data`` -- list, same format as output of :func:`bernoulli_mod_p` function - OUTPUT: - - bool -- True if checksum passed + OUTPUT: bool -- True if checksum passed EXAMPLES:: @@ -102,7 +100,7 @@ def bernoulli_mod_p(int p): INPUT: - p -- integer, a prime + - ``p`` -- integer, a prime OUTPUT: @@ -134,7 +132,7 @@ def bernoulli_mod_p(int p): AUTHOR: - -- David Harvey (2006-08-06) + - David Harvey (2006-08-06) """ @@ -233,12 +231,12 @@ def bernoulli_mod_p_single(long p, long k): r""" Return the Bernoulli number `B_k` mod `p`. - If `B_k` is not `p`-integral, an ArithmeticError is raised. + If `B_k` is not `p`-integral, an :class:`ArithmeticError` is raised. INPUT: - - p -- integer, a prime - - k -- non-negative integer + - ``p`` -- integer, a prime + - ``k`` -- non-negative integer OUTPUT: @@ -274,7 +272,7 @@ def bernoulli_mod_p_single(long p, long k): ... ValueError: k must be non-negative - Check results against bernoulli_mod_p:: + Check results against :class:`bernoulli_mod_p`:: sage: bernoulli_mod_p(37) [1, 31, 16, 15, 16, 4, 17, 32, 22, 31, 15, 15, 17, 12, 29, 2, 0, 2] @@ -303,8 +301,8 @@ def bernoulli_mod_p_single(long p, long k): AUTHOR: - -- David Harvey (2007-08-31) - -- David Harvey (2008-06): rewrote to use bernmm library + - David Harvey (2007-08-31) + - David Harvey (2008-06): rewrote to use bernmm library """ if p <= 2: diff --git a/src/sage/rings/big_oh.py b/src/sage/rings/big_oh.py index 64ce5562f2c..386474cf653 100644 --- a/src/sage/rings/big_oh.py +++ b/src/sage/rings/big_oh.py @@ -9,15 +9,25 @@ - `polynomials <../../../polynomial_rings/index.html>`_ """ -import sage.arith.all as arith -from . import laurent_series_ring_element -from sage.rings.puiseux_series_ring_element import PuiseuxSeries -import sage.rings.padics.factory as padics_factory -import sage.rings.padics.padic_generic_element as padic_generic_element +from sage.arith.misc import factor +from sage.misc.lazy_import import lazy_import +lazy_import('sage.rings.padics.factory', ['Qp', 'Zp']) +lazy_import('sage.rings.padics.padic_generic_element', 'pAdicGenericElement') +from sage.rings.polynomial.polynomial_element import Polynomial + +try: + from .laurent_series_ring_element import LaurentSeries +except ImportError: + LaurentSeries = () + +try: + from .puiseux_series_ring_element import PuiseuxSeries +except ImportError: + PuiseuxSeries = () + from . import power_series_ring_element from . import integer from . import rational -from sage.rings.polynomial.polynomial_element import Polynomial from . import multi_power_series_ring_element @@ -47,41 +57,42 @@ def O(*x, **kwds): This is also useful to create `p`-adic numbers:: - sage: O(7^6) + sage: O(7^6) # optional - sage.rings.padics O(7^6) - sage: 1/3 + O(7^6) + sage: 1/3 + O(7^6) # optional - sage.rings.padics 5 + 4*7 + 4*7^2 + 4*7^3 + 4*7^4 + 4*7^5 + O(7^6) It behaves well with respect to adding negative powers of `p`:: - sage: a = O(11^-32); a + sage: a = O(11^-32); a # optional - sage.rings.padics O(11^-32) - sage: a.parent() + sage: a.parent() # optional - sage.rings.padics 11-adic Field with capped relative precision 20 There are problems if you add a rational with very negative valuation to an `O`-Term:: - sage: 11^-12 + O(11^15) + sage: 11^-12 + O(11^15) # optional - sage.rings.padics 11^-12 + O(11^8) The reason that this fails is that the constructor doesn't know the right precision cap to use. If you cast explicitly or use other means of element creation, you can get around this issue:: - sage: K = Qp(11, 30) - sage: K(11^-12) + O(11^15) + sage: K = Qp(11, 30) # optional - sage.rings.padics + sage: K(11^-12) + O(11^15) # optional - sage.rings.padics 11^-12 + O(11^15) - sage: 11^-12 + K(O(11^15)) + sage: 11^-12 + K(O(11^15)) # optional - sage.rings.padics 11^-12 + O(11^15) - sage: K(11^-12, absprec = 15) + sage: K(11^-12, absprec=15) # optional - sage.rings.padics 11^-12 + O(11^15) - sage: K(11^-12, 15) + sage: K(11^-12, 15) # optional - sage.rings.padics 11^-12 + O(11^15) We can also work with `asymptotic expansions`_:: - sage: A. = AsymptoticRing(growth_group='QQ^n * n^QQ * log(n)^QQ', coefficient_ring=QQ); A + sage: A. = AsymptoticRing(growth_group='QQ^n * n^QQ * log(n)^QQ', # optional - sage.symbolic + ....: coefficient_ring=QQ); A Asymptotic Ring over Rational Field sage: O(n) O(n) @@ -137,9 +148,8 @@ def O(*x, **kwds): "for the maximal ideal (x)") return x.parent().completion(x.parent().gen())(0, x.degree(), **kwds) - elif isinstance(x, laurent_series_ring_element.LaurentSeries): - return laurent_series_ring_element.LaurentSeries(x.parent(), 0).\ - add_bigoh(x.valuation(), **kwds) + elif isinstance(x, LaurentSeries): + return LaurentSeries(x.parent(), 0).add_bigoh(x.valuation(), **kwds) elif isinstance(x, PuiseuxSeries): return x.add_bigoh(x.valuation(), **kwds) @@ -148,18 +158,18 @@ def O(*x, **kwds): # p-adic number if x <= 0: raise ArithmeticError("x must be a prime power >= 2") - F = arith.factor(x) + F = factor(x) if len(F) != 1: raise ArithmeticError("x must be prime power") p, r = F[0] if r >= 0: - return padics_factory.Zp(p, prec=max(r, 20), - type='capped-rel')(0, absprec=r, **kwds) + return Zp(p, prec=max(r, 20), + type='capped-rel')(0, absprec=r, **kwds) else: - return padics_factory.Qp(p, prec=max(r, 20), - type='capped-rel')(0, absprec=r, **kwds) + return Qp(p, prec=max(r, 20), + type='capped-rel')(0, absprec=r, **kwds) - elif isinstance(x, padic_generic_element.pAdicGenericElement): + elif isinstance(x, pAdicGenericElement): return x.parent()(0, absprec=x.valuation(), **kwds) elif hasattr(x, 'O'): return x.O(**kwds) diff --git a/src/sage/rings/cfinite_sequence.py b/src/sage/rings/cfinite_sequence.py index 2c109271b5b..14ae02423e4 100644 --- a/src/sage/rings/cfinite_sequence.py +++ b/src/sage/rings/cfinite_sequence.py @@ -1038,7 +1038,7 @@ def an_element(self): def __contains__(self, x): """ - Return True if x is an element of ``CFiniteSequences`` or + Return ``True`` if x is an element of ``CFiniteSequences`` or canonically coerces to this ring. EXAMPLES:: diff --git a/src/sage/rings/complex_arb.pyx b/src/sage/rings/complex_arb.pyx index f17ff37893c..8412cabd59a 100644 --- a/src/sage/rings/complex_arb.pyx +++ b/src/sage/rings/complex_arb.pyx @@ -101,12 +101,13 @@ Coercion Automatic coercions work as expected:: - sage: bpol = 1/3*CBF(i) + AA(sqrt(2)) + (polygen(RealBallField(20), 'x') + QQbar(i)) - sage: bpol + sage: bpol = 1/3*CBF(i) + AA(sqrt(2)) # optional - sage.symbolic + sage: bpol += polygen(RealBallField(20), 'x') + QQbar(i) # optional - sage.symbolic + sage: bpol # optional - sage.symbolic x + [1.41421 +/- ...e-6] + [1.33333 +/- ...e-6]*I - sage: bpol.parent() + sage: bpol.parent() # optional - sage.symbolic Univariate Polynomial Ring in x over Complex ball field with 20 bits of precision - sage: bpol/3 + sage: bpol/3 # optional - sage.symbolic ([0.333333 +/- ...e-7])*x + [0.47140 +/- ...e-6] + [0.44444 +/- ...e-6]*I TESTS:: @@ -116,12 +117,12 @@ TESTS:: :: - sage: SR.coerce(CBF(0.42 + 3.33*I)) + sage: SR.coerce(CBF(0.42 + 3.33*I)) # optional - sage.symbolic [0.4200000000000000 +/- ...e-17] + [3.330000000000000 +/- ...e-17]*I Check that :trac:`19839` is fixed:: - sage: log(SR(CBF(0.42))).pyobject().parent() + sage: log(SR(CBF(0.42))).pyobject().parent() # optional - sage.symbolic Complex ball field with 53 bits of precision :trac:`24621`:: @@ -592,15 +593,15 @@ class ComplexBallField(UniqueRepresentation, sage.rings.abc.ComplexBallField): 1.000000000000000 sage: CBF(1, 1) 1.000000000000000 + 1.000000000000000*I - sage: CBF(pi, sqrt(2)) + sage: CBF(pi, sqrt(2)) # optional - sage.symbolic [3.141592653589793 +/- ...e-16] + [1.414213562373095 +/- ...e-16]*I sage: CBF(I) 1.000000000000000*I - sage: CBF(pi+I/3) + sage: CBF(pi + I/3) # optional - sage.symbolic [3.141592653589793 +/- ...e-16] + [0.3333333333333333 +/- ...e-17]*I sage: CBF(QQbar(i/7)) # abs tol 1e-16 [0.1428571428571429 +/- 4.29e-17]*I - sage: CBF(AA(sqrt(2))) + sage: CBF(AA(sqrt(2))) # optional - sage.symbolic [1.414213562373095 +/- ...e-16] sage: CBF(CIF(0, 1)) 1.000000000000000*I @@ -637,13 +638,13 @@ class ComplexBallField(UniqueRepresentation, sage.rings.abc.ComplexBallField): The following conversions used to yield incorrect enclosures:: - sage: a = CBF(airy_ai(1)); a + sage: a = CBF(airy_ai(1)); a # optional - sage.symbolic [0.1352924163128814 +/- 6.95e-17] - sage: a.overlaps(ComplexBallField(100).one().airy_ai()) + sage: a.overlaps(ComplexBallField(100).one().airy_ai()) # optional - sage.symbolic True - sage: v = CBF(zetaderiv(1, 3/2)); v + sage: v = CBF(zetaderiv(1, 3/2)); v # optional - sage.symbolic [-3.932239737431101 +/- 5.58e-16] - sage: v.overlaps(ComplexBallField(100)(3/2).zetaderiv(1)) + sage: v.overlaps(ComplexBallField(100)(3/2).zetaderiv(1)) # optional - sage.symbolic True """ try: @@ -1086,7 +1087,7 @@ class ComplexBallField(UniqueRepresentation, sage.rings.abc.ComplexBallField): sage: correct = CBF.integral(my_sqrt, 1, 2); correct [1.21895141649746 +/- ...e-15] - sage: RBF(integral(sqrt(x), x, 1, 2)) # long time + sage: RBF(integral(sqrt(x), x, 1, 2)) # long time # optional - sage.symbolic [1.21895141649746 +/- ...e-15] sage: wrong = CBF.integral(lambda z, _: z.sqrt(), 1, 2) # WRONG! sage: correct - wrong @@ -2449,7 +2450,7 @@ cdef class ComplexBall(RingElement): OUTPUT: - Return True iff ``self`` and ``other`` are equal as sets, i.e. if their + Return ``True`` iff ``self`` and ``other`` are equal as sets, i.e. if their real and imaginary parts each have the same midpoint and radius. Note that this is not the same thing as testing whether both ``self`` @@ -2470,7 +2471,7 @@ cdef class ComplexBall(RingElement): def overlaps(self, ComplexBall other): """ - Return True iff ``self`` and ``other`` have some point in common. + Return ``True`` iff ``self`` and ``other`` have some point in common. INPUT: @@ -2509,7 +2510,7 @@ cdef class ComplexBall(RingElement): sage: CBF(1).contains_exact(CBF(1)) True - sage: CBF(sqrt(2)).contains_exact(sqrt(2)) + sage: CBF(sqrt(2)).contains_exact(sqrt(2)) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: unsupported type: @@ -2538,7 +2539,7 @@ cdef class ComplexBall(RingElement): def __contains__(self, other): """ - Return True if ``other`` can be verified to be contained in ``self``. + Return ``True`` if ``other`` can be verified to be contained in ``self``. Depending on the type of ``other``, the test may use interval arithmetic with a precision determined by the parent of ``self`` and @@ -2834,7 +2835,7 @@ cdef class ComplexBall(RingElement): -1024.000000000000 sage: CBF(1,1) ^ -1r 0.5000000000000000 - 0.5000000000000000*I - sage: CBF(2)**SR.var('x') + sage: CBF(2)**SR.var('x') # optional - sage.symbolic 2.000000000000000^x """ if (isinstance(base, ComplexBall) @@ -2868,7 +2869,7 @@ cdef class ComplexBall(RingElement): TESTS:: - sage: CBF(2).pow(SR.var('x')) + sage: CBF(2).pow(SR.var('x')) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: no canonical coercion from Symbolic Ring to Complex ball @@ -3847,9 +3848,9 @@ cdef class ComplexBall(RingElement): sage: CBF(1, pi).hypergeometric([1/4], [1/4]) [-2.7182818284590 +/- ...e-14] + [+/- ...e-14]*I - sage: CBF(1000, 1000).hypergeometric([10], [AA(sqrt(2))]) + sage: CBF(1000, 1000).hypergeometric([10], [AA(sqrt(2))]) # optional - sage.symbolic [9.79300951360e+454 +/- ...e+442] + [5.522579106816e+455 +/- ...e+442]*I - sage: CBF(1000, 1000).hypergeometric([100], [AA(sqrt(2))]) + sage: CBF(1000, 1000).hypergeometric([100], [AA(sqrt(2))]) # optional - sage.symbolic [1.27967355557e+590 +/- ...e+578] + [-9.32333491987e+590 +/- ...e+578]*I sage: CBF(0, 1).hypergeometric([], [1/2, 1/3, 1/4]) @@ -3883,7 +3884,7 @@ cdef class ComplexBall(RingElement): TESTS:: - sage: CBF(0, 1).hypergeometric([QQbar(sqrt(2)), RLF(pi)], [1r, 1/2]) + sage: CBF(0, 1).hypergeometric([QQbar(sqrt(2)), RLF(pi)], [1r, 1/2]) # optional - sage.symbolic [-8.7029449215408 +/- ...e-14] + [-0.8499070546106 +/- ...e-14]*I """ @@ -4483,12 +4484,12 @@ cdef class ComplexBall(RingElement): EXAMPLES:: - sage: tau = CBF(sqrt(2),pi) - sage: tau.modular_lambda() + sage: tau = CBF(sqrt(2),pi) # optional - sage.symbolic + sage: tau.modular_lambda() # optional - sage.symbolic [-0.00022005123884157 +/- ...e-18] + [-0.00079787346459944 +/- ...e-18]*I - sage: (tau + 2).modular_lambda() + sage: (tau + 2).modular_lambda() # optional - sage.symbolic [-0.00022005123884157 +/- ...e-18] + [-0.00079787346459944 +/- ...e-18]*I - sage: (tau / (1 - 2*tau)).modular_lambda() + sage: (tau / (1 - 2*tau)).modular_lambda() # optional - sage.symbolic [-0.00022005123884 +/- ...e-15] + [-0.00079787346460 +/- ...e-15]*I """ @@ -4568,19 +4569,19 @@ cdef class ComplexBall(RingElement): EXAMPLES:: sage: tau = CBF(1,4) - sage: z = CBF(sqrt(2), sqrt(3)) - sage: z.elliptic_p(tau) + sage: z = CBF(sqrt(2), sqrt(3)) # optional - sage.symbolic + sage: z.elliptic_p(tau) # optional - sage.symbolic [-3.28920996772709 +/- ...e-15] + [-0.0003673767302933 +/- ...e-17]*I - sage: (z + tau).elliptic_p(tau) + sage: (z + tau).elliptic_p(tau) # optional - sage.symbolic [-3.28920996772709 +/- ...e-15] + [-0.000367376730293 +/- ...e-16]*I - sage: (z + 1).elliptic_p(tau) + sage: (z + 1).elliptic_p(tau) # optional - sage.symbolic [-3.28920996772709 +/- ...e-15] + [-0.0003673767302933 +/- ...e-17]*I - sage: z.elliptic_p(tau, 3) + sage: z.elliptic_p(tau, 3) # optional - sage.symbolic [[-3.28920996772709 +/- ...e-15] + [-0.0003673767302933 +/- ...e-17]*I, [0.002473055794309 +/- ...e-16] + [0.003859554040267 +/- ...e-16]*I, [-0.01299087561709 +/- ...e-15] + [0.00725027521915 +/- ...e-15]*I] - sage: (z + 3 + 4*tau).elliptic_p(tau, 3) + sage: (z + 3 + 4*tau).elliptic_p(tau, 3) # optional - sage.symbolic [[-3.28920996772709 +/- ...e-15] + [-0.00036737673029 +/- ...e-15]*I, [0.0024730557943 +/- ...e-14] + [0.0038595540403 +/- ...e-14]*I, [-0.01299087562 +/- ...e-12] + [0.00725027522 +/- ...e-12]*I] @@ -4619,7 +4620,7 @@ cdef class ComplexBall(RingElement): sage: CBF(0,1).elliptic_invariants() ([189.07272012923 +/- ...e-12], [+/- ...e-12]) - sage: CBF(sqrt(2)/2, sqrt(2)/2).elliptic_invariants() + sage: CBF(sqrt(2)/2, sqrt(2)/2).elliptic_invariants() # optional - sage.symbolic ([+/- ...e-12] + [-332.5338031465...]*I, [1254.46842157...] + [1254.46842157...]*I) """ diff --git a/src/sage/rings/complex_double.pyx b/src/sage/rings/complex_double.pyx index 332977164f4..b4fec10c68a 100644 --- a/src/sage/rings/complex_double.pyx +++ b/src/sage/rings/complex_double.pyx @@ -473,13 +473,13 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField): EXAMPLES:: - sage: CDF._magma_init_(magma) # optional - magma + sage: CDF._magma_init_(magma) # optional - magma 'ComplexField(53 : Bits := true)' - sage: magma(CDF) # optional - magma + sage: magma(CDF) # optional - magma Complex field of precision 15 sage: floor(RR(log(2**53, 10))) 15 - sage: magma(CDF).sage() # optional - magma + sage: magma(CDF).sage() # optional - magma Complex Field with 53 bits of precision """ return "ComplexField(%s : Bits := true)" % self.prec() @@ -1565,7 +1565,7 @@ cdef class ComplexDoubleElement(FieldElement): def is_integer(self): """ - Returns True if this number is a integer + Return ``True`` if this number is a integer EXAMPLES:: @@ -2570,11 +2570,11 @@ cdef class ComplexToCDF(Morphism): EXAMPLES:: - sage: import numpy - sage: f = CDF.coerce_map_from(numpy.complex_) - sage: f(numpy.complex_(I)) + sage: import numpy # optional - numpy + sage: f = CDF.coerce_map_from(numpy.complex_) # optional - numpy + sage: f(numpy.complex_(I)) # optional - numpy 1.0*I - sage: f(numpy.complex_(I)).parent() + sage: f(numpy.complex_(I)).parent() # optional - numpy Complex Double Field """ def __init__(self, R): @@ -2590,8 +2590,8 @@ cdef class ComplexToCDF(Morphism): EXAMPLES:: - sage: import numpy - sage: CDF(numpy.complex_(I)) # indirect doctest + sage: import numpy # optional - numpy + sage: CDF(numpy.complex_(I)) # indirect doctest # optional - numpy 1.0*I """ cdef ComplexDoubleElement z = ComplexDoubleElement.__new__(ComplexDoubleElement) @@ -2604,9 +2604,9 @@ cdef class ComplexToCDF(Morphism): EXAMPLES:: - sage: import numpy - sage: f = sage.rings.complex_double.ComplexToCDF(numpy.complex_) - sage: f._repr_type() + sage: import numpy # optional - numpy + sage: f = sage.rings.complex_double.ComplexToCDF(numpy.complex_) # optional - numpy + sage: f._repr_type() # optional - numpy 'Native' """ return "Native" diff --git a/src/sage/rings/complex_mpfr.pyx b/src/sage/rings/complex_mpfr.pyx index 4fc6c4c8d35..86ebff0b4d0 100644 --- a/src/sage/rings/complex_mpfr.pyx +++ b/src/sage/rings/complex_mpfr.pyx @@ -762,7 +762,7 @@ class ComplexField_class(sage.rings.abc.ComplexField): INPUT: - - ``n`` - an integer (default: 2) + - ``n`` -- an integer (default: 2) OUTPUT: a complex `n`-th root of unity. @@ -1039,10 +1039,10 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): EXAMPLES:: - sage: import numpy - sage: numpy.array([1.0, 2.5j]).dtype + sage: import numpy # optional - numpy + sage: numpy.array([1.0, 2.5j]).dtype # optional - numpy dtype('complex128') - sage: numpy.array([1.000000000000000000000000000000000000j]).dtype + sage: numpy.array([1.000000000000000000000000000000000000j]).dtype # optional - numpy dtype('O') """ if self._prec <= 53: @@ -1183,7 +1183,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): INPUT: - - ``i`` - 0 or 1 + - ``i`` -- 0 or 1 - ``0`` -- will return the real component of ``self`` - ``1`` -- will return the imaginary component of ``self`` @@ -1266,20 +1266,19 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): EXAMPLES:: - sage: a = CC(pi + I*e) - sage: a + sage: a = CC(pi + I*e); a # optional - sage.symbolic 3.14159265358979 + 2.71828182845905*I - sage: a.str(truncate=True) + sage: a.str(truncate=True) # optional - sage.symbolic '3.14159265358979 + 2.71828182845905*I' - sage: a.str() + sage: a.str() # optional - sage.symbolic '3.1415926535897931 + 2.7182818284590451*I' - sage: a.str(base=2) + sage: a.str(base=2) # optional - sage.symbolic '11.001001000011111101101010100010001000010110100011000 + 10.101101111110000101010001011000101000101011101101001*I' - sage: CC(0.5 + 0.625*I).str(base=2) + sage: CC(0.5 + 0.625*I).str(base=2) # optional - sage.symbolic '0.10000000000000000000000000000000000000000000000000000 + 0.10100000000000000000000000000000000000000000000000000*I' - sage: a.str(base=16) + sage: a.str(base=16) # optional - sage.symbolic '3.243f6a8885a30 + 2.b7e151628aed2*I' - sage: a.str(base=36) + sage: a.str(base=36) # optional - sage.symbolic '3.53i5ab8p5fc + 2.puw5nggjf8f*I' sage: CC(0) 0.000000000000000 @@ -1392,23 +1391,23 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): Coerce the object using the ``pari`` function:: sage: a = ComplexNumber(2,1) - sage: pari(a) + sage: pari(a) # optional - sage.libs.pari 2.00000000000000 + 1.00000000000000*I - sage: pari(a).type() + sage: pari(a).type() # optional - sage.libs.pari 't_COMPLEX' - sage: type(pari(a)) + sage: type(pari(a)) # optional - sage.libs.pari - sage: a.__pari__() + sage: a.__pari__() # optional - sage.libs.pari 2.00000000000000 + 1.00000000000000*I - sage: type(a.__pari__()) + sage: type(a.__pari__()) # optional - sage.libs.pari - sage: a = CC(pi) - sage: pari(a) + sage: a = CC(pi) # optional - sage.symbolic + sage: pari(a) # optional - sage.libs.pari sage.symbolic 3.14159265358979 - sage: pari(a).type() + sage: pari(a).type() # optional - sage.libs.pari sage.symbolic 't_REAL' sage: a = CC(-2).sqrt() - sage: pari(a) + sage: pari(a) # optional - sage.libs.pari 1.41421356237310*I """ if self.is_real(): @@ -1475,11 +1474,11 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): EXAMPLES:: - sage: CC(1, 0)._sympy_() + sage: CC(1, 0)._sympy_() # optional - sympy 1.00000000000000 - sage: CC(1/3, 1)._sympy_() + sage: CC(1/3, 1)._sympy_() # optional - sympy 0.333333333333333 + 1.0*I - sage: type(_) + sage: type(_) # optional - sympy """ import sympy @@ -1670,7 +1669,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): INPUT: - - ``left`` - a complex number to divide by ``self`` + - ``left`` -- a complex number to divide by ``self`` EXAMPLES:: @@ -1759,7 +1758,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): def __bool__(self): """ Return ``True`` if ``self`` is not zero. This is an internal function; - use :meth:`is_zero()` instead. + use :meth:`is_zero` instead. EXAMPLES:: @@ -2031,7 +2030,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): def multiplicative_order(self): """ Return the multiplicative order of this complex number, if known, - or raise a ``NotImplementedError``. + or raise a :class:`NotImplementedError`. EXAMPLES:: @@ -2092,13 +2091,13 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): You can either use the indirect:: sage: z = CC(0,1) - sage: plot(z) + sage: plot(z) # optional - sage.plot Graphics object consisting of 1 graphics primitive or the more direct:: sage: z = CC(0,1) - sage: z.plot() + sage: z.plot() # optional - sage.plot Graphics object consisting of 1 graphics primitive """ return sage.plot.point.point2d((self.real(), self.imag()), **kargs) @@ -2360,7 +2359,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): INPUT: - ``self`` -- element of the upper half plane (if not, - raises a ``ValueError``). + raises a :class:`ValueError`). - ``omit_frac`` -- (bool, default: ``False``), if ``True``, omit the `e^{\pi i z / 12}` factor. @@ -2555,7 +2554,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): - ``right`` (complex) -- another complex number - - ``algorithm`` (string, default "optimal") -- the algorithm to use + - ``algorithm`` (string, default ``"optimal"``) -- the algorithm to use (see below). OUTPUT: @@ -2564,18 +2563,18 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): this is a multi-valued function, and the algorithm used affects the value returned, as follows: - - "pari": Call the :pari:`agm` function from the pari library. + - ``"pari"``: Call the :pari:`agm` function from the PARI library. - - "optimal": Use the AGM sequence such that at each stage - `(a,b)` is replaced by `(a_1,b_1)=((a+b)/2,\pm\sqrt{ab})` - where the sign is chosen so that `|a_1-b_1|\le|a_1+b_1|`, or - equivalently `\Re(b_1/a_1)\ge 0`. The resulting limit is - maximal among all possible values. + - ``"optimal"``: Use the AGM sequence such that at each stage + `(a,b)` is replaced by `(a_1,b_1)=((a+b)/2,\pm\sqrt{ab})` + where the sign is chosen so that `|a_1-b_1|\le|a_1+b_1|`, or + equivalently `\Re(b_1/a_1)\ge 0`. The resulting limit is + maximal among all possible values. - - "principal": Use the AGM sequence such that at each stage - `(a,b)` is replaced by `(a_1,b_1)=((a+b)/2,\pm\sqrt{ab})` - where the sign is chosen so that `\Re(b_1)\ge 0` (the - so-called principal branch of the square root). + - ``"principal"``: Use the AGM sequence such that at each stage + `(a,b)` is replaced by `(a_1,b_1)=((a+b)/2,\pm\sqrt{ab})` + where the sign is chosen so that `\Re(b_1)\ge 0` (the + so-called principal branch of the square root). The values `AGM(a,0)`, `AGM(0,a)`, and `AGM(a,-a)` are all taken to be 0. @@ -2777,7 +2776,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): def arg(self): """ - See :meth:`argument()`. + See :meth:`argument`. EXAMPLES:: @@ -2826,7 +2825,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: a = ComplexNumber(1,0) sage: a.dilog() 1.64493406684823 - sage: float(pi^2/6) + sage: float(pi^2/6) # optional - sage.symbolic 1.6449340668482262 :: @@ -2924,8 +2923,8 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): def log(self, base=None): r""" Complex logarithm of `z` with branch chosen as follows: Write - `z = \rho e^{i \theta}` with `-\pi < \theta <= pi`. Then - `\mathrm{log}(z) = \mathrm{log}(\rho) + i \theta`. + `z = \rho e^{i \theta}` with `-\pi < \theta \leq \pi`. Then + `\log(z) = \log(\rho) + i \theta`. .. WARNING:: @@ -3002,7 +3001,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): INPUT: - - ``all`` - bool (default: ``False``); if ``True``, return a + - ``all`` -- bool (default: ``False``); if ``True``, return a list of all square roots. EXAMPLES:: @@ -3071,7 +3070,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): INPUT: - - ``all`` - bool (default: ``False``); if ``True``, return a + - ``all`` -- bool (default: ``False``); if ``True``, return a list of all `n`-th roots. EXAMPLES:: @@ -3080,10 +3079,13 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): sage: a.nth_root(3) 3.00000000000000 sage: a.nth_root(3, all=True) - [3.00000000000000, -1.50000000000000 + 2.59807621135332*I, -1.50000000000000 - 2.59807621135332*I] + [3.00000000000000, + -1.50000000000000 + 2.59807621135332*I, + -1.50000000000000 - 2.59807621135332*I] sage: a = ComplexField(20)(2,1) sage: [r^7 for r in a.nth_root(7, all=True)] - [2.0000 + 1.0000*I, 2.0000 + 1.0000*I, 2.0000 + 1.0000*I, 2.0000 + 1.0000*I, 2.0000 + 1.0000*I, 2.0000 + 1.0001*I, 2.0000 + 1.0001*I] + [2.0000 + 1.0000*I, 2.0000 + 1.0000*I, 2.0000 + 1.0000*I, 2.0000 + 1.0000*I, + 2.0000 + 1.0000*I, 2.0000 + 1.0001*I, 2.0000 + 1.0001*I] """ if self.is_zero(): return [self] if all else self @@ -3143,7 +3145,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): def is_real(self): """ - Return ``True`` if ``self`` is real, i.e. has imaginary part zero. + Return ``True`` if ``self`` is real, i.e., has imaginary part zero. EXAMPLES:: @@ -3156,7 +3158,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): def is_imaginary(self): """ - Return ``True`` if ``self`` is imaginary, i.e. has real part zero. + Return ``True`` if ``self`` is imaginary, i.e., has real part zero. EXAMPLES:: @@ -3169,7 +3171,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): def is_integer(self): """ - Return ``True`` if ``self`` is a integer + Return ``True`` if ``self`` is an integer. EXAMPLES:: @@ -3265,8 +3267,8 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): ALGORITHM: Uses the PARI C-library :pari:`algdep` command. - INPUT: Type algdep? at the top level prompt. All additional - parameters are passed onto the top-level algdep command. + INPUT: Type ``algdep?`` at the top level prompt. All additional + parameters are passed onto the top-level :func:`algdep` command. EXAMPLES:: @@ -3465,7 +3467,7 @@ cdef inline mp_exp_t max_exp(ComplexNumber z): cpdef int cmp_abs(ComplexNumber a, ComplexNumber b): """ - Return -1, 0, or 1 according to whether `|a|` is less than, equal to, or + Return `-1`, `0`, or `1` according to whether `|a|` is less than, equal to, or greater than `|b|`. Optimized for non-close numbers, where the ordering can be determined by diff --git a/src/sage/rings/continued_fraction.py b/src/sage/rings/continued_fraction.py index c8a68cb309f..0b836b44f65 100644 --- a/src/sage/rings/continued_fraction.py +++ b/src/sage/rings/continued_fraction.py @@ -2513,13 +2513,13 @@ def continued_fraction_list(x, type="std", partial_convergents=False, def continued_fraction(x, value=None): r""" - Return the continued fraction of ``x``. + Return the continued fraction of `x`. INPUT: - - `x` -- a number or a list of partial quotients (for finite - development) or two list of partial quotients (preperiod and period - for ultimately periodic development) + - ``x`` -- a number or a list of partial quotients (for finite + development) or two list of partial quotients (preperiod and period + for ultimately periodic development) EXAMPLES: @@ -2534,38 +2534,38 @@ def continued_fraction(x, value=None): It can be called with elements defined from symbolic values, in which case the partial quotients are evaluated in a lazy way:: - sage: c = continued_fraction(golden_ratio); c + sage: c = continued_fraction(golden_ratio); c # optional - sage.symbolic [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...] - sage: c.convergent(12) + sage: c.convergent(12) # optional - sage.symbolic 377/233 sage: fibonacci(14)/fibonacci(13) 377/233 - sage: continued_fraction(pi) + sage: continued_fraction(pi) # optional - sage.symbolic [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, ...] - sage: c = continued_fraction(pi); c + sage: c = continued_fraction(pi); c # optional - sage.symbolic [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, ...] - sage: a = c.convergent(3); a + sage: a = c.convergent(3); a # optional - sage.symbolic 355/113 - sage: a.n() + sage: a.n() # optional - sage.symbolic 3.14159292035398 - sage: pi.n() + sage: pi.n() # optional - sage.symbolic 3.14159265358979 - sage: continued_fraction(sqrt(2)) + sage: continued_fraction(sqrt(2)) # optional - sage.symbolic [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ...] - sage: continued_fraction(tan(1)) + sage: continued_fraction(tan(1)) # optional - sage.symbolic [1; 1, 1, 3, 1, 5, 1, 7, 1, 9, 1, 11, 1, 13, 1, 15, 1, 17, 1, 19, ...] - sage: continued_fraction(tanh(1)) + sage: continued_fraction(tanh(1)) # optional - sage.symbolic [0; 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, ...] - sage: continued_fraction(e) + sage: continued_fraction(e) # optional - sage.symbolic [2; 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1, ...] If you want to play with quadratic numbers (such as ``golden_ratio`` and ``sqrt(2)`` above), it is much more convenient to use number fields as follows since preperiods and periods are computed:: - sage: K. = NumberField(x^2-5, embedding=2.23) + sage: K. = NumberField(x^2 - 5, embedding=2.23) sage: my_golden_ratio = (1 + sqrt5)/2 sage: cf = continued_fraction((1+sqrt5)/2); cf [(1)*] @@ -2580,7 +2580,7 @@ def continued_fraction(x, value=None): sage: cf.period() (1, 3, 1, 1, 3, 9) - sage: L. = NumberField(x^2-2, embedding=1.41) + sage: L. = NumberField(x^2 - 2, embedding=1.41) sage: cf = continued_fraction(sqrt2); cf [1; (2)*] sage: cf.period() @@ -2594,7 +2594,7 @@ def continued_fraction(x, value=None): continued fraction from its preperiod and its period and get its value back:: - sage: cf = continued_fraction([(1,1),(2,8)]); cf + sage: cf = continued_fraction([(1,1), (2,8)]); cf [1; 1, (2, 8)*] sage: cf.value() 2/11*sqrt5 + 14/11 @@ -2602,7 +2602,7 @@ def continued_fraction(x, value=None): It is possible to deal with higher degree number fields but in that case the continued fraction expansion is known to be aperiodic:: - sage: K. = NumberField(x^3-2, embedding=1.25) + sage: K. = NumberField(x^3 - 2, embedding=1.25) sage: cf = continued_fraction(a); cf [1; 3, 1, 5, 1, 1, 4, 1, 1, 8, 1, 14, 1, 10, 2, 1, 4, 12, 2, 3, ...] @@ -2631,8 +2631,8 @@ def continued_fraction(x, value=None): Constants in symbolic subrings work like constants in ``SR``:: - sage: SCR = SR.subring(no_variables=True) - sage: continued_fraction(SCR(pi)) + sage: SCR = SR.subring(no_variables=True) # optional - sage.symbolic + sage: continued_fraction(SCR(pi)) # optional - sage.symbolic [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, ...] """ diff --git a/src/sage/rings/derivation.py b/src/sage/rings/derivation.py index 4c8cb4662b9..74903e6072f 100644 --- a/src/sage/rings/derivation.py +++ b/src/sage/rings/derivation.py @@ -35,7 +35,8 @@ sage: A. = QQ[] sage: M = A.derivation_module() sage: M - Module of derivations over Multivariate Polynomial Ring in x, y, z over Rational Field + Module of derivations over + Multivariate Polynomial Ring in x, y, z over Rational Field The method :meth:`~sage.rings.derivation.RingDerivationModule.gens` returns the generators of this module:: @@ -76,8 +77,10 @@ Sage knows moreover that `M` is a Lie algebra:: sage: M.category() - Join of Category of lie algebras with basis over Rational Field - and Category of modules with basis over Multivariate Polynomial Ring in x, y, z over Rational Field + Join of + Category of lie algebras with basis over Rational Field and + Category of modules with basis over + Multivariate Polynomial Ring in x, y, z over Rational Field Computations of Lie brackets are implemented as well:: @@ -116,7 +119,9 @@ sage: M = A.derivation_module(ev) sage: M - Module of derivations from Multivariate Polynomial Ring in x, y, z over Rational Field to Rational Field + Module of derivations + from Multivariate Polynomial Ring in x, y, z over Rational Field + to Rational Field sage: M.gens() (d/dx, d/dy, d/dz) @@ -138,7 +143,8 @@ sage: theta = B.hom([B(y),B(z),B(x)]) sage: theta - Ring endomorphism of Fraction Field of Multivariate Polynomial Ring in x, y, z over Rational Field + Ring endomorphism of Fraction Field of + Multivariate Polynomial Ring in x, y, z over Rational Field Defn: x |--> y y |--> z z |--> x @@ -225,25 +231,32 @@ def __init__(self, domain, codomain, twist=None): sage: TestSuite(M).run() sage: from sage.rings.derivation import RingDerivationModule - sage: R5. = GF(5)[] - sage: R25. = GF(25)[] - sage: R7. = GF(7)[] - - sage: RingDerivationModule(R5, R25) - Module of derivations from Univariate Polynomial Ring in x over Finite Field of size 5 to Univariate Polynomial Ring in x over Finite Field in z2 of size 5^2 - sage: RingDerivationModule(R5, R5^2) + sage: R5. = GF(5)[] # optional - sage.rings.finite_rings + sage: R25. = GF(25)[] # optional - sage.rings.finite_rings + sage: R7. = GF(7)[] # optional - sage.rings.finite_rings + + sage: RingDerivationModule(R5, R25) # optional - sage.rings.finite_rings + Module of derivations + from Univariate Polynomial Ring in x over Finite Field of size 5 + to Univariate Polynomial Ring in x over Finite Field in z2 of size 5^2 + sage: RingDerivationModule(R5, R5^2) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: the codomain must be an algebra over the domain or a morphism with the correct domain - sage: RingDerivationModule(R5, R7) + TypeError: the codomain must be an algebra over the domain + or a morphism with the correct domain + sage: RingDerivationModule(R5, R7) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: the codomain must be an algebra over the domain or a morphism with the correct domain - - sage: theta = R5.hom([R5.gen()^2]) - sage: RingDerivationModule(R5, R25, twist=theta) - Module of twisted derivations from Univariate Polynomial Ring in x over Finite Field of size 5 to Univariate Polynomial Ring in x over Finite Field in z2 of size 5^2 (twisting morphism: x |--> x^2) - sage: RingDerivationModule(R7, R7, twist=theta) + TypeError: the codomain must be an algebra over the domain + or a morphism with the correct domain + + sage: theta = R5.hom([R5.gen()^2]) # optional - sage.rings.finite_rings + sage: RingDerivationModule(R5, R25, twist=theta) # optional - sage.rings.finite_rings + Module of twisted derivations + from Univariate Polynomial Ring in x over Finite Field of size 5 + to Univariate Polynomial Ring in x over Finite Field in z2 of size 5^2 + (twisting morphism: x |--> x^2) + sage: RingDerivationModule(R7, R7, twist=theta) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: the domain of the derivation must coerce to the domain of the twisting homomorphism @@ -460,8 +473,10 @@ def _coerce_map_from_(self, R): sage: M1 = A.derivation_module(); M1 Module of derivations over Univariate Polynomial Ring in x over Rational Field sage: M2 = A.derivation_module(B); M2 - Module of derivations from Univariate Polynomial Ring in x over Rational Field - to Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + Module of derivations + from Univariate Polynomial Ring in x over Rational Field + to Univariate Polynomial Ring in y over + Univariate Polynomial Ring in x over Rational Field sage: M1._coerce_map_from_(M2) is None True sage: M1.has_coerce_map_from(M2) @@ -567,7 +582,8 @@ def defining_morphism(self): sage: M.defining_morphism() Polynomial base injection morphism: From: Univariate Polynomial Ring in x over Rational Field - To: Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + To: Univariate Polynomial Ring in y over + Univariate Polynomial Ring in x over Rational Field sage: ev = R.hom([QQ(0)]) sage: M = R.derivation_module(ev) @@ -857,7 +873,8 @@ def codomain(self): sage: S. = R[] sage: M = R.derivation_module(S) sage: M.random_element().codomain() - Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + Univariate Polynomial Ring in y over + Univariate Polynomial Ring in x over Rational Field sage: M.random_element().codomain() is S True @@ -1057,10 +1074,10 @@ def _richcmp_(self, other, op): EXAMPLES:: - sage: R. = GF(5)[] - sage: D = sum(v*R.derivation(v) for v in R.gens()); D + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: D = sum(v*R.derivation(v) for v in R.gens()); D # optional - sage.rings.finite_rings x*d/dx + y*d/dy + z*d/dz - sage: D.pth_power() == D + sage: D.pth_power() == D # optional - sage.rings.finite_rings True """ @@ -1132,17 +1149,17 @@ def pth_power(self): EXAMPLES:: - sage: R. = GF(5)[] - sage: Dx = R.derivation(x) - sage: Dx.pth_power() + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: Dx = R.derivation(x) # optional - sage.rings.finite_rings + sage: Dx.pth_power() # optional - sage.rings.finite_rings 0 - sage: (x*Dx).pth_power() + sage: (x*Dx).pth_power() # optional - sage.rings.finite_rings x*d/dx - sage: (x^6*Dx).pth_power() + sage: (x^6*Dx).pth_power() # optional - sage.rings.finite_rings x^26*d/dx - sage: Dy = R.derivation(y) - sage: (x*Dx + y*Dy).pth_power() + sage: Dy = R.derivation(y) # optional - sage.rings.finite_rings + sage: (x*Dx + y*Dy).pth_power() # optional - sage.rings.finite_rings x*d/dx + y*d/dy An error is raised if the domain has characteristic zero:: @@ -1165,14 +1182,14 @@ def pth_power(self): TESTS:: - sage: R. = GF(3)[] - sage: D = R.derivation_module().random_element() - sage: Dp = D.pth_power() - sage: f = R.random_element() - sage: Dp(f) == D(D(D(f))) + sage: R. = GF(3)[] # optional - sage.rings.finite_rings + sage: D = R.derivation_module().random_element() # optional - sage.rings.finite_rings + sage: Dp = D.pth_power() # optional - sage.rings.finite_rings + sage: f = R.random_element() # optional - sage.rings.finite_rings + sage: Dp(f) == D(D(D(f))) # optional - sage.rings.finite_rings True - sage: D.bracket(Dp) + sage: D.bracket(Dp) # optional - sage.rings.finite_rings 0 """ @@ -1562,14 +1579,14 @@ def __init__(self, parent, arg=None): TESTS:: sage: from sage.rings.derivation import RingDerivationWithoutTwist_wrapper - sage: R. = GF(5)[] - sage: S = R.quo([x^5, y^5]) - sage: M = S.derivation_module() - sage: der = M.random_element() - sage: isinstance(der, RingDerivationWithoutTwist_wrapper) + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: S = R.quo([x^5, y^5]) # optional - sage.rings.finite_rings + sage: M = S.derivation_module() # optional - sage.rings.finite_rings + sage: der = M.random_element() # optional - sage.rings.finite_rings + sage: isinstance(der, RingDerivationWithoutTwist_wrapper) # optional - sage.rings.finite_rings True - sage: TestSuite(der).run() + sage: TestSuite(der).run() # optional - sage.rings.finite_rings """ if isinstance(arg, list) and len(arg) == 1 and isinstance(arg[0], RingDerivation): @@ -1600,11 +1617,11 @@ def _add_(self, other): EXAMPLES:: - sage: R. = GF(5)[] - sage: S. = R.quo([X^5, Y^5]) - sage: Dx = S.derivation(x) - sage: Dy = S.derivation(y) - sage: Dx + Dy + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: S. = R.quo([X^5, Y^5]) # optional - sage.rings.finite_rings + sage: Dx = S.derivation(x) # optional - sage.rings.finite_rings + sage: Dy = S.derivation(y) # optional - sage.rings.finite_rings + sage: Dx + Dy # optional - sage.rings.finite_rings d/dx + d/dy """ @@ -1616,11 +1633,11 @@ def _sub_(self, other): EXAMPLES:: - sage: R. = GF(5)[] - sage: S. = R.quo([X^5, Y^5]) - sage: Dx = S.derivation(x) - sage: Dy = S.derivation(y) - sage: Dx - Dy + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: S. = R.quo([X^5, Y^5]) # optional - sage.rings.finite_rings + sage: Dx = S.derivation(x) # optional - sage.rings.finite_rings + sage: Dy = S.derivation(y) # optional - sage.rings.finite_rings + sage: Dx - Dy # optional - sage.rings.finite_rings d/dx - d/dy """ @@ -1632,10 +1649,10 @@ def _neg_(self): EXAMPLES:: - sage: R. = GF(5)[] - sage: S. = R.quo([X^5, Y^5]) - sage: Dx = S.derivation(x) - sage: -Dx + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: S. = R.quo([X^5, Y^5]) # optional - sage.rings.finite_rings + sage: Dx = S.derivation(x) # optional - sage.rings.finite_rings + sage: -Dx # optional - sage.rings.finite_rings -d/dx """ @@ -1647,12 +1664,12 @@ def _lmul_(self, factor): EXAMPLES:: - sage: R. = GF(5)[] - sage: S. = R.quo([X^5, Y^5]) - sage: Dx = S.derivation(x) - sage: Dx * 2 + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: S. = R.quo([X^5, Y^5]) # optional - sage.rings.finite_rings + sage: Dx = S.derivation(x) # optional - sage.rings.finite_rings + sage: Dx * 2 # optional - sage.rings.finite_rings 2*d/dx - sage: Dx * x^2 + sage: Dx * x^2 # optional - sage.rings.finite_rings x^2*d/dx """ @@ -1664,12 +1681,12 @@ def _rmul_(self, factor): EXAMPLES:: - sage: R. = GF(5)[] - sage: S. = R.quo([X^5, Y^5]) - sage: Dx = S.derivation(x) - sage: 2 * Dx + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: S. = R.quo([X^5, Y^5]) # optional - sage.rings.finite_rings + sage: Dx = S.derivation(x) # optional - sage.rings.finite_rings + sage: 2 * Dx # optional - sage.rings.finite_rings 2*d/dx - sage: x^2 * Dx + sage: x^2 * Dx # optional - sage.rings.finite_rings x^2*d/dx """ @@ -1682,20 +1699,20 @@ def list(self): EXAMPLES:: - sage: R. = GF(5)[] - sage: S. = R.quo([X^5, Y^5]) - sage: M = S.derivation_module() - sage: M.basis() + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: S. = R.quo([X^5, Y^5]) # optional - sage.rings.finite_rings + sage: M = S.derivation_module() # optional - sage.rings.finite_rings + sage: M.basis() # optional - sage.rings.finite_rings Family (d/dx, d/dy) - sage: S.derivation(x).list() + sage: S.derivation(x).list() # optional - sage.rings.finite_rings [1, 0] - sage: S.derivation(y).list() + sage: S.derivation(y).list() # optional - sage.rings.finite_rings [0, 1] - sage: f = x*S.derivation(x) + y*S.derivation(y); f + sage: f = x*S.derivation(x) + y*S.derivation(y); f # optional - sage.rings.finite_rings x*d/dx + y*d/dy - sage: f.list() + sage: f.list() # optional - sage.rings.finite_rings [x, y] """ @@ -1889,19 +1906,19 @@ def list(self): EXAMPLES:: - sage: R. = GF(5)[[]] - sage: M = R.derivation_module() - sage: M.basis() + sage: R. = GF(5)[[]] # optional - sage.rings.finite_rings + sage: M = R.derivation_module() # optional - sage.rings.finite_rings + sage: M.basis() # optional - sage.rings.finite_rings Family (d/dx, d/dy) - sage: R.derivation(x).list() + sage: R.derivation(x).list() # optional - sage.rings.finite_rings [1, 0] - sage: R.derivation(y).list() + sage: R.derivation(y).list() # optional - sage.rings.finite_rings [0, 1] - sage: f = x*R.derivation(x) + y*R.derivation(y); f + sage: f = x*R.derivation(x) + y*R.derivation(y); f # optional - sage.rings.finite_rings x*d/dx + y*d/dy - sage: f.list() + sage: f.list() # optional - sage.rings.finite_rings [x, y] """ @@ -1974,11 +1991,11 @@ def _call_(self, x): EXAMPLES:: - sage: R. = GF(5)[] - sage: S. = R.quo([X^5, Y^5]) - sage: f = x^3*S.derivation(); f + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: S. = R.quo([X^5, Y^5]) # optional - sage.rings.finite_rings + sage: f = x^3*S.derivation(); f # optional - sage.rings.finite_rings x^3*d/dx - sage: f(x^3) + sage: f(x^3) # optional - sage.rings.finite_rings 0 """ @@ -2074,10 +2091,10 @@ def _latex_(self): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: der = k.derivation(a+1, twist=Frob) - sage: latex(der) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: der = k.derivation(a + 1, twist=Frob) # optional - sage.rings.finite_rings + sage: latex(der) # optional - sage.rings.finite_rings \left(a + 1\right) \left(\left[a \mapsto a^{5}\right] - \text{id}\right) """ scalar = self._scalar diff --git a/src/sage/rings/factorint.pyx b/src/sage/rings/factorint.pyx index 77def414b13..5718d6691ae 100644 --- a/src/sage/rings/factorint.pyx +++ b/src/sage/rings/factorint.pyx @@ -9,7 +9,10 @@ AUTHORS: """ #***************************************************************************** -# Copyright (C) 2010 André Apitzsch +# Copyright (C) 2010-2011 André Apitzsch +# 2012 Nils Bruin +# 2014 David Roe +# 2014 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of @@ -17,12 +20,8 @@ AUTHORS: # http://www.gnu.org/licenses/ #***************************************************************************** -from cysignals.signals cimport sig_on, sig_off - from sage.ext.stdsage cimport PY_NEW from sage.libs.gmp.mpz cimport * -from sage.libs.flint.fmpz cimport fmpz_t, fmpz_init, fmpz_set_mpz -from sage.libs.flint.fmpz_factor cimport * from sage.rings.integer cimport Integer from sage.rings.fast_arith import prime_range @@ -53,23 +52,23 @@ cpdef aurifeuillian(n, m, F=None, bint check=True): EXAMPLES:: sage: from sage.rings.factorint import aurifeuillian - sage: aurifeuillian(2,2) + sage: aurifeuillian(2, 2) [5, 13] - sage: aurifeuillian(2,2^5) + sage: aurifeuillian(2, 2^5) [1985, 2113] - sage: aurifeuillian(5,3) + sage: aurifeuillian(5, 3) [1471, 2851] - sage: aurifeuillian(15,1) + sage: aurifeuillian(15, 1) [19231, 142111] - sage: aurifeuillian(12,3) + sage: aurifeuillian(12, 3) Traceback (most recent call last): ... ValueError: n has to be square-free - sage: aurifeuillian(1,2) + sage: aurifeuillian(1, 2) Traceback (most recent call last): ... ValueError: n has to be greater than 1 - sage: aurifeuillian(2,0) + sage: aurifeuillian(2, 0) Traceback (most recent call last): ... ValueError: m has to be positive @@ -133,24 +132,24 @@ cpdef factor_aurifeuillian(n, check=True): EXAMPLES:: sage: from sage.rings.factorint import factor_aurifeuillian as fa - sage: fa(2^6+1) + sage: fa(2^6 + 1) # optional - sage.libs.pari [5, 13] - sage: fa(2^58+1) + sage: fa(2^58 + 1) # optional - sage.libs.pari [536838145, 536903681] - sage: fa(3^3+1) + sage: fa(3^3 + 1) # optional - sage.libs.pari [4, 1, 7] - sage: fa(5^5-1) + sage: fa(5^5 - 1) # optional - sage.libs.pari [4, 11, 71] - sage: prod(_) == 5^5-1 + sage: prod(_) == 5^5 - 1 # optional - sage.libs.pari True - sage: fa(2^4+1) + sage: fa(2^4 + 1) # optional - sage.libs.pari [17] - sage: fa((6^2*3)^3+1) + sage: fa((6^2*3)^3 + 1) # optional - sage.libs.pari [109, 91, 127] TESTS:: - sage: for n in [2,3,5,6,30,31,33]: + sage: for n in [2,3,5,6,30,31,33]: # optional - sage.libs.pari ....: for m in [8,96,109201283]: ....: s = -1 if n % 4 == 1 else 1 ....: y = (m^2*n)^n + s @@ -206,9 +205,9 @@ cpdef factor_aurifeuillian(n, check=True): def factor_cunningham(m, proof=None): r""" - Return factorization of self obtained using trial division + Return factorization of ``self`` obtained using trial division for all primes in the so called Cunningham table. This is - efficient if self has some factors of type `b^n+1` or `b^n-1`, + efficient if ``self`` has some factors of type `b^n+1` or `b^n-1`, with `b` in `\{2,3,5,6,7,10,11,12\}`. You need to install an optional package to use this method, @@ -226,7 +225,7 @@ def factor_cunningham(m, proof=None): sage: from sage.rings.factorint import factor_cunningham sage: factor_cunningham(2^257-1) # optional - cunningham_tables 535006138814359 * 1155685395246619182673033 * 374550598501810936581776630096313181393 - sage: factor_cunningham((3^101+1)*(2^60).next_prime(),proof=False) # optional - cunningham_tables + sage: factor_cunningham((3^101+1)*(2^60).next_prime(), proof=False) # optional - cunningham_tables 2^2 * 379963 * 1152921504606847009 * 1017291527198723292208309354658785077827527 """ @@ -249,12 +248,12 @@ def factor_cunningham(m, proof=None): cpdef factor_trial_division(m, long limit=LONG_MAX): r""" - Return partial factorization of self obtained using trial division - for all primes up to limit, where limit must fit in a C signed long. + Return partial factorization of ``self`` obtained using trial division + for all primes up to ``limit``, where ``limit`` must fit in a C ``signed long``. INPUT: - - ``limit`` -- integer (default: ``LONG_MAX``) that fits in a C signed long + - ``limit`` -- integer (default: ``LONG_MAX``) that fits in a C ``signed long`` EXAMPLES:: @@ -292,139 +291,3 @@ cpdef factor_trial_division(m, long limit=LONG_MAX): return IntegerFactorization(F, unit=unit, unsafe=True, sort=False, simplify=False) - - -def factor_using_pari(n, int_=False, debug_level=0, proof=None): - r""" - Factor this integer using PARI. - - This function returns a list of pairs, not a ``Factorization`` - object. The first element of each pair is the factor, of type - ``Integer`` if ``int_`` is ``False`` or ``int`` otherwise, - the second element is the positive exponent, of type ``int``. - - INPUT: - - - ``int_`` -- (default: ``False``), whether the factors are - of type ``int`` instead of ``Integer`` - - - ``debug_level`` -- (default: 0), debug level of the call - to PARI - - - ``proof`` -- (default: ``None``), whether the factors are - required to be proven prime; if ``None``, the global default - is used - - OUTPUT: - - A list of pairs. - - EXAMPLES:: - - sage: factor(-2**72 + 3, algorithm='pari') # indirect doctest - -1 * 83 * 131 * 294971519 * 1472414939 - - Check that PARI's debug level is properly reset (:trac:`18792`):: - - sage: alarm(0.5); factor(2^1000 - 1, verbose=5) - Traceback (most recent call last): - ... - AlarmInterrupt - sage: pari.get_debug_level() - 0 - """ - from sage.libs.pari.all import pari - - if proof is None: - from sage.structure.proof.proof import get_flag - proof = get_flag(proof, "arithmetic") - - prev = pari.get_debug_level() - - cdef Py_ssize_t i - try: - if prev != debug_level: - pari.set_debug_level(debug_level) - - p, e = n.__pari__().factor(proof=proof) - if int_: - return [(int(p[i]), int(e[i])) for i in range(len(p))] - else: - return [(Integer(p[i]), int(e[i])) for i in range(len(p))] - finally: - if prev != debug_level: - pari.set_debug_level(prev) - - -def factor_using_flint(Integer n): - r""" - Factor the nonzero integer ``n`` using FLINT. - - This function returns a list of (factor, exponent) pairs. The - factors will be of type ``Integer``, and the exponents will be of - type ``int``. - - INPUT: - - - ``n`` -- a nonzero sage Integer; the number to factor. - - OUTPUT: - - A list of ``(Integer, int)`` pairs representing the factors and - their exponents. - - EXAMPLES:: - - sage: from sage.rings.factorint import factor_using_flint - sage: n = ZZ(9962572652930382) - sage: factors = factor_using_flint(n) - sage: factors - [(2, 1), (3, 1), (1660428775488397, 1)] - sage: prod( f^e for (f,e) in factors ) == n - True - - Negative numbers will have a leading factor of ``(-1)^1``:: - - sage: n = ZZ(-1 * 2 * 3) - sage: factor_using_flint(n) - [(-1, 1), (2, 1), (3, 1)] - - The factorization of unity is empty:: - - sage: factor_using_flint(ZZ.one()) - [] - - While zero has a single factor, of... zero:: - - sage: factor_using_flint(ZZ.zero()) - [(0, 1)] - - TESTS: - - Check that the integers [-10,000, 10,000] are factored correctly:: - - sage: all( - ....: prod( f^e for (f,e) in factor_using_flint(ZZ(c*k)) ) == c*k - ....: for k in range(10000) - ....: for c in [-1, 1] - ....: ) - True - """ - if n.is_zero(): - return [(n, int(1))] - - cdef fmpz_t p - fmpz_init(p) - fmpz_set_mpz(p, (n).value) - - cdef fmpz_factor_t factors - fmpz_factor_init(factors) - - sig_on() - fmpz_factor(factors, p) - sig_off() - - pairs = fmpz_factor_to_pairlist(factors) - - fmpz_factor_clear(factors) - return pairs diff --git a/src/sage/rings/factorint_flint.pyx b/src/sage/rings/factorint_flint.pyx new file mode 100644 index 00000000000..44d8c3ebd4a --- /dev/null +++ b/src/sage/rings/factorint_flint.pyx @@ -0,0 +1,97 @@ +# sage.doctest: optional - sage.libs.flint +r""" +Integer factorization using FLINT + +AUTHORS: + +- Michael Orlitzky (2023) +""" + +#***************************************************************************** +# Copyright (C) 2023 Michael Orlitzky +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from cysignals.signals cimport sig_on, sig_off + +from sage.libs.flint.fmpz cimport fmpz_t, fmpz_init, fmpz_set_mpz +from sage.libs.flint.fmpz_factor cimport * +from sage.rings.integer cimport Integer + + +def factor_using_flint(Integer n): + r""" + Factor the nonzero integer ``n`` using FLINT. + + This function returns a list of (factor, exponent) pairs. The + factors will be of type ``Integer``, and the exponents will be of + type ``int``. + + INPUT: + + - ``n`` -- a nonzero sage Integer; the number to factor. + + OUTPUT: + + A list of ``(Integer, int)`` pairs representing the factors and + their exponents. + + EXAMPLES:: + + sage: from sage.rings.factorint_flint import factor_using_flint + sage: n = ZZ(9962572652930382) + sage: factors = factor_using_flint(n) + sage: factors + [(2, 1), (3, 1), (1660428775488397, 1)] + sage: prod( f^e for (f,e) in factors ) == n + True + + Negative numbers will have a leading factor of ``(-1)^1``:: + + sage: n = ZZ(-1 * 2 * 3) + sage: factor_using_flint(n) + [(-1, 1), (2, 1), (3, 1)] + + The factorization of unity is empty:: + + sage: factor_using_flint(ZZ.one()) + [] + + While zero has a single factor, of... zero:: + + sage: factor_using_flint(ZZ.zero()) + [(0, 1)] + + TESTS: + + Check that the integers [-10,000, 10,000] are factored correctly:: + + sage: all( + ....: prod( f^e for (f,e) in factor_using_flint(ZZ(c*k)) ) == c*k + ....: for k in range(10000) + ....: for c in [-1, 1] + ....: ) + True + """ + if n.is_zero(): + return [(n, int(1))] + + cdef fmpz_t p + fmpz_init(p) + fmpz_set_mpz(p, (n).value) + + cdef fmpz_factor_t factors + fmpz_factor_init(factors) + + sig_on() + fmpz_factor(factors, p) + sig_off() + + pairs = fmpz_factor_to_pairlist(factors) + + fmpz_factor_clear(factors) + return pairs diff --git a/src/sage/rings/factorint_pari.pyx b/src/sage/rings/factorint_pari.pyx new file mode 100644 index 00000000000..b94682d0deb --- /dev/null +++ b/src/sage/rings/factorint_pari.pyx @@ -0,0 +1,80 @@ +# sage.doctest: optional - sage.libs.pari +r""" +Integer factorization using PARI + +AUTHORS: + +- Jeroen Demeyer (2015) +""" + +#***************************************************************************** +# Copyright (C) 2015 Jeroen Demeyer +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from sage.libs.pari.all import pari +from sage.rings.integer cimport Integer + + +def factor_using_pari(n, int_=False, debug_level=0, proof=None): + r""" + Factor this integer using PARI. + + This function returns a list of pairs, not a :class:`Factorization` + object. The first element of each pair is the factor, of type + ``Integer`` if ``int_`` is ``False`` or ``int`` otherwise, + the second element is the positive exponent, of type ``int``. + + INPUT: + + - ``int_`` -- (default: ``False``), whether the factors are + of type ``int`` instead of ``Integer`` + + - ``debug_level`` -- (default: 0), debug level of the call + to PARI + + - ``proof`` -- (default: ``None``), whether the factors are + required to be proven prime; if ``None``, the global default + is used + + OUTPUT: + + A list of pairs. + + EXAMPLES:: + + sage: factor(-2**72 + 3, algorithm='pari') # indirect doctest + -1 * 83 * 131 * 294971519 * 1472414939 + + Check that PARI's debug level is properly reset (:trac:`18792`):: + + sage: alarm(0.5); factor(2^1000 - 1, verbose=5) + Traceback (most recent call last): + ... + AlarmInterrupt + sage: pari.get_debug_level() + 0 + """ + if proof is None: + from sage.structure.proof.proof import get_flag + proof = get_flag(proof, "arithmetic") + + prev = pari.get_debug_level() + + cdef Py_ssize_t i + try: + if prev != debug_level: + pari.set_debug_level(debug_level) + + p, e = n.__pari__().factor(proof=proof) + if int_: + return [(int(p[i]), int(e[i])) for i in range(len(p))] + else: + return [(Integer(p[i]), int(e[i])) for i in range(len(p))] + finally: + if prev != debug_level: + pari.set_debug_level(prev) diff --git a/src/sage/rings/fast_arith.pyx b/src/sage/rings/fast_arith.pyx index df9b592cf97..dfaa7782962 100644 --- a/src/sage/rings/fast_arith.pyx +++ b/src/sage/rings/fast_arith.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.pari """ Basic arithmetic with C integers """ @@ -58,16 +59,16 @@ cpdef prime_range(start, stop=None, algorithm=None, bint py_ints=False): - ``algorithm`` -- optional string (default: ``None``), one of: - - ``None``: Use algorithm ``"pari_primes"`` if ``stop`` <= 436273009 - (approximately 4.36E8). Otherwise use algorithm ``"pari_isprime"``. + - ``None``: Use algorithm ``"pari_primes"`` if ``stop`` <= 436273009 + (approximately 4.36E8). Otherwise use algorithm ``"pari_isprime"``. - - ``"pari_primes"``: Use PARI's :pari:`primes` function to generate all - primes from 2 to stop. This is fast but may crash if there is - insufficient memory. Raises an error if ``stop`` > 436273009. + - ``"pari_primes"``: Use PARI's :pari:`primes` function to generate all + primes from 2 to stop. This is fast but may crash if there is + insufficient memory. Raises an error if ``stop`` > 436273009. - - ``"pari_isprime"``: Wrapper for ``list(primes(start, stop))``. Each (odd) - integer in the specified range is tested for primality by applying PARI's - :pari:`isprime` function. This is slower but will work for much larger input. + - ``"pari_isprime"``: Wrapper for ``list(primes(start, stop))``. Each (odd) + integer in the specified range is tested for primality by applying PARI's + :pari:`isprime` function. This is slower but will work for much larger input. - ``py_ints`` -- optional boolean (default ``False``), return Python ints rather than Sage Integers (faster). Ignored unless algorithm ``"pari_primes"`` is being diff --git a/src/sage/rings/finite_rings/element_base.pyx b/src/sage/rings/finite_rings/element_base.pyx index a7e32004002..daf39e3b386 100755 --- a/src/sage/rings/finite_rings/element_base.pyx +++ b/src/sage/rings/finite_rings/element_base.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings """ Base class for finite field elements @@ -25,7 +26,7 @@ from sage.misc.superseded import deprecated_function_alias def is_FiniteFieldElement(x): """ - Return True if ``x`` is a finite field element. + Return ``True`` if ``x`` is a finite field element. This function is deprecated. diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index 086590a962b..49abe86126f 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings """ Base class for finite fields diff --git a/src/sage/rings/finite_rings/finite_field_constructor.py b/src/sage/rings/finite_rings/finite_field_constructor.py index 048da483147..0ea8a3b0805 100644 --- a/src/sage/rings/finite_rings/finite_field_constructor.py +++ b/src/sage/rings/finite_rings/finite_field_constructor.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings r""" Finite fields @@ -791,7 +792,7 @@ def create_object(self, version, key, **kwds): def is_PrimeFiniteField(x): """ - Returns True if ``x`` is a prime finite field. + Return ``True`` if ``x`` is a prime finite field. This function is deprecated. diff --git a/src/sage/rings/finite_rings/hom_finite_field.pyx b/src/sage/rings/finite_rings/hom_finite_field.pyx index a69eb42b8be..23240b9d5b1 100644 --- a/src/sage/rings/finite_rings/hom_finite_field.pyx +++ b/src/sage/rings/finite_rings/hom_finite_field.pyx @@ -317,7 +317,7 @@ cdef class FiniteFieldHomomorphism_generic(RingHomomorphism_im_gens): def is_injective(self): """ - Return True since a embedding between finite fields is + Return ``True`` since a embedding between finite fields is always injective. EXAMPLES:: @@ -334,7 +334,7 @@ cdef class FiniteFieldHomomorphism_generic(RingHomomorphism_im_gens): def is_surjective(self): """ - Return true if this embedding is surjective (and hence an + Return ``True`` if this embedding is surjective (and hence an isomorphism. EXAMPLES:: @@ -773,7 +773,7 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): def is_injective(self): """ - Return true since any power of the Frobenius endomorphism + Return ``True`` since any power of the Frobenius endomorphism over a finite field is always injective. EXAMPLES:: @@ -788,7 +788,7 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): def is_surjective(self): """ - Return true since any power of the Frobenius endomorphism + Return ``True`` since any power of the Frobenius endomorphism over a finite field is always surjective. EXAMPLES:: @@ -803,7 +803,7 @@ cdef class FrobeniusEndomorphism_finite_field(FrobeniusEndomorphism_generic): def is_identity(self): """ - Return true if this morphism is the identity morphism. + Return ``True`` if this morphism is the identity morphism. EXAMPLES:: diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index ec3268dc84e..561b09766d7 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -349,11 +349,11 @@ cdef class IntegerMod_abstract(FiniteRingElement): sage: TestSuite(Zmod(2^10 * 3^5)).run() sage: TestSuite(Zmod(2^30 * 3^50 * 5^20)).run() - sage: GF(29)(SR(1/3)) + sage: GF(29)(SR(1/3)) # optional - sage.rings.finite_rings sage.symbolic 10 sage: Integers(30)(QQ['x'](1/7)) 13 - sage: Integers(30)(SR(1/4)) + sage: Integers(30)(SR(1/4)) # optional - sage.symbolic Traceback (most recent call last): ... ZeroDivisionError: inverse of Mod(4, 30) does not exist @@ -505,7 +505,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: sage: a = Integers(90384098234^3) - sage: factor(a.order()) + sage: factor(a.order()) # optional - sage.libs.pari 2^3 * 191^3 * 236607587^3 sage: b = a(2*191) sage: b.is_nilpotent() @@ -546,13 +546,13 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: sage: a = Mod(2,19) - sage: gap(a) + sage: gap(a) # optional - sage.libs.gap Z(19) - sage: gap(Mod(3, next_prime(10000))) + sage: gap(Mod(3, next_prime(10000))) # optional - sage.libs.gap Z(10007)^6190 - sage: gap(Mod(3, next_prime(100000))) + sage: gap(Mod(3, next_prime(100000))) # optional - sage.libs.gap ZmodpZObj( 3, 100003 ) - sage: gap(Mod(4, 48)) + sage: gap(Mod(4, 48)) # optional - sage.libs.gap ZmodnZObj( 4, 48 ) """ return '%s*One(ZmodnZ(%s))' % (self, self.__modulus.sageInteger) @@ -605,18 +605,18 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: - sage: K = GF(7) - sage: sage_input(K(5), verify=True) + sage: K = GF(7) # optional - sage.rings.finite_rings + sage: sage_input(K(5), verify=True) # optional - sage.rings.finite_rings # Verified GF(7)(5) - sage: sage_input(K(5) * polygen(K), verify=True) + sage: sage_input(K(5) * polygen(K), verify=True) # optional - sage.rings.finite_rings # Verified R. = GF(7)[] 5*x sage: from sage.misc.sage_input import SageInputBuilder - sage: K(5)._sage_input_(SageInputBuilder(), False) + sage: K(5)._sage_input_(SageInputBuilder(), False) # optional - sage.rings.finite_rings {call: {call: {atomic:GF}({atomic:7})}({atomic:5})} - sage: K(5)._sage_input_(SageInputBuilder(), True) + sage: K(5)._sage_input_(SageInputBuilder(), True) # optional - sage.rings.finite_rings {atomic:5} """ v = sib.int(self.lift()) @@ -653,39 +653,39 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: sage: r = Integers(125) - sage: b = r.multiplicative_generator()^3 - sage: a = b^17 - sage: a.log(b) + sage: b = r.multiplicative_generator()^3 # optional - sage.libs.pari + sage: a = b^17 # optional - sage.libs.pari + sage: a.log(b) # optional - sage.libs.pari 17 - sage: a.log() + sage: a.log() # optional - sage.libs.pari 51 A bigger example:: - sage: FF = FiniteField(2^32+61) - sage: c = FF(4294967356) - sage: x = FF(2) - sage: a = c.log(x) - sage: a + sage: FF = FiniteField(2^32 + 61) # optional - sage.rings.finite_rings + sage: c = FF(4294967356) # optional - sage.rings.finite_rings + sage: x = FF(2) # optional - sage.rings.finite_rings + sage: a = c.log(x) # optional - sage.rings.finite_rings + sage: a # optional - sage.rings.finite_rings 2147483678 - sage: x^a + sage: x^a # optional - sage.rings.finite_rings 4294967356 An example with a highly composite modulus:: sage: m = 2^99 * 77^7 * 123456789 * 13712923537615486607^2 - sage: (Mod(5,m)^5735816763073854953388147237921).log(5) + sage: (Mod(5,m)^5735816763073854953388147237921).log(5) # optional - sage.libs.pari 5735816763073854953388147237921 Errors are generated if the logarithm doesn't exist or the inputs are not units:: - sage: Mod(3, 7).log(Mod(2, 7)) + sage: Mod(3, 7).log(Mod(2, 7)) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no logarithm of 3 found to base 2 modulo 7 - sage: a = Mod(16, 100); b = Mod(4,100) - sage: a.log(b) + sage: a = Mod(16, 100); b = Mod(4, 100) # optional - sage.libs.pari + sage: a.log(b) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: logarithm of 16 is not defined since it is not a unit modulo 100 @@ -694,51 +694,51 @@ cdef class IntegerMod_abstract(FiniteRingElement): We check that :trac:`9205` is fixed:: - sage: Mod(5,9).log(Mod(2, 9)) + sage: Mod(5, 9).log(Mod(2, 9)) # optional - sage.libs.pari 5 We test against a bug (side effect on PARI) fixed in :trac:`9438`:: sage: R. = QQ[] - sage: pari(b) + sage: pari(b) # optional - sage.libs.pari b - sage: GF(7)(5).log() + sage: GF(7)(5).log() # optional - sage.rings.finite_rings 5 - sage: pari(b) + sage: pari(b) # optional - sage.libs.pari b We test that :trac:`23927` is fixed:: sage: x = mod(48475563673907791151, 10^20 + 763)^2 sage: e = 25248843418589594761 - sage: (x^e).log(x)==e + sage: (x^e).log(x) == e # optional - sage.libs.pari True Examples like this took extremely long before :trac:`32375`:: - sage: (Mod(5, 123337052926643**4) ^ (10^50-1)).log(5) + sage: (Mod(5, 123337052926643**4) ^ (10^50-1)).log(5) # optional - sage.libs.pari 99999999999999999999999999999999999999999999999999 We check that non-existence of solutions is detected: No local solutions:: - sage: Mod(1111, 1234567).log(1111**3) + sage: Mod(1111, 1234567).log(1111**3) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no logarithm of 1111 found to base 961261 modulo 1234567 (no solution modulo 9721) Incompatible local solutions:: - sage: Mod(230, 323).log(173) + sage: Mod(230, 323).log(173) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no logarithm of 230 found to base 173 modulo 323 (incompatible local solutions) We test that :trac:`12419` is fixed:: - sage: R. = GF(2)[] - sage: R(1).factor() + sage: R. = GF(2)[] # optional - sage.rings.finite_rings + sage: R(1).factor() # optional - sage.rings.finite_rings 1 AUTHORS: @@ -818,9 +818,9 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: sage: m = Mod(3, 1568) - sage: v = m.generalised_log(); v + sage: v = m.generalised_log(); v # optional - sage.libs.pari [1, 3, 1] - sage: prod([Zmod(1568).unit_gens()[i] ** v[i] for i in [0..2]]) + sage: prod([Zmod(1568).unit_gens()[i] ** v[i] for i in [0..2]]) # optional - sage.libs.pari 3 .. SEEALSO:: @@ -869,11 +869,11 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: - sage: k = GF(3) - sage: a = k.gen() - sage: a.charpoly('x') + sage: k = GF(3) # optional - sage.rings.finite_rings + sage: a = k.gen() # optional - sage.rings.finite_rings + sage: a.charpoly('x') # optional - sage.rings.finite_rings x + 2 - sage: a + 2 + sage: a + 2 # optional - sage.rings.finite_rings 0 AUTHORS: @@ -889,7 +889,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: - sage: GF(241, 'a')(1).minpoly() + sage: GF(241, 'a')(1).minpoly() # optional - sage.rings.finite_rings x + 240 """ return self.charpoly(var) @@ -900,7 +900,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: - sage: GF(241, 'a')(1).minimal_polynomial(var = 'z') + sage: GF(241, 'a')(1).minimal_polynomial(var = 'z') # optional - sage.rings.finite_rings z + 240 """ return self.minpoly(var) @@ -911,12 +911,12 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: - sage: k = GF(7) - sage: a = k.gen(); a + sage: k = GF(7) # optional - sage.rings.finite_rings + sage: a = k.gen(); a # optional - sage.rings.finite_rings 1 - sage: a.polynomial() + sage: a.polynomial() # optional - sage.rings.finite_rings 1 - sage: type(a.polynomial()) + sage: type(a.polynomial()) # optional - sage.rings.finite_rings """ R = self.parent()[var] @@ -929,9 +929,9 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: - sage: k = GF(691) - sage: a = k(389) - sage: a.norm() + sage: k = GF(691) # optional - sage.rings.finite_rings + sage: a = k(389) # optional - sage.rings.finite_rings + sage: a.norm() # optional - sage.rings.finite_rings 389 AUTHORS: @@ -947,9 +947,9 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: - sage: k = GF(691) - sage: a = k(389) - sage: a.trace() + sage: k = GF(691) # optional - sage.rings.finite_rings + sage: a = k(389) # optional - sage.rings.finite_rings + sage: a.trace() # optional - sage.rings.finite_rings 389 AUTHORS: @@ -1028,27 +1028,27 @@ cdef class IntegerMod_abstract(FiniteRingElement): r""" EXAMPLES:: - sage: Mod(3,17).is_square() + sage: Mod(3, 17).is_square() False - sage: Mod(9,17).is_square() + sage: Mod(9, 17).is_square() # optional - sage.libs.pari True - sage: Mod(9,17*19^2).is_square() + sage: Mod(9, 17*19^2).is_square() # optional - sage.libs.pari True - sage: Mod(-1,17^30).is_square() + sage: Mod(-1, 17^30).is_square() # optional - sage.libs.pari True - sage: Mod(1/9, next_prime(2^40)).is_square() + sage: Mod(1/9, next_prime(2^40)).is_square() # optional - sage.libs.pari True - sage: Mod(1/25, next_prime(2^90)).is_square() + sage: Mod(1/25, next_prime(2^90)).is_square() # optional - sage.libs.pari True TESTS:: - sage: Mod(1/25, 2^8).is_square() + sage: Mod(1/25, 2^8).is_square() # optional - sage.libs.pari True - sage: Mod(1/25, 2^40).is_square() + sage: Mod(1/25, 2^40).is_square() # optional - sage.libs.pari True - sage: for p,q,r in cartesian_product_iterator([[3,5],[11,13],[17,19]]): # long time + sage: for p,q,r in cartesian_product_iterator([[3,5],[11,13],[17,19]]): # long time # optional - sage.libs.pari ....: for ep,eq,er in cartesian_product_iterator([[0,1,2,3],[0,1,2,3],[0,1,2,3]]): ....: for e2 in [0, 1, 2, 3, 4]: ....: n = p^ep * q^eq * r^er * 2^e2 @@ -1126,21 +1126,21 @@ cdef class IntegerMod_abstract(FiniteRingElement): 86 sage: mod(7, 18).sqrt() 5 - sage: a = mod(14, 5^60).sqrt() - sage: a*a + sage: a = mod(14, 5^60).sqrt() # optional - sage.libs.pari + sage: a*a # optional - sage.libs.pari 14 - sage: mod(15, 389).sqrt(extend=False) + sage: mod(15, 389).sqrt(extend=False) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: self must be a square - sage: Mod(1/9, next_prime(2^40)).sqrt()^(-2) + sage: Mod(1/9, next_prime(2^40)).sqrt()^(-2) # optional - sage.libs.pari 9 - sage: Mod(1/25, next_prime(2^90)).sqrt()^(-2) + sage: Mod(1/25, next_prime(2^90)).sqrt()^(-2) # optional - sage.libs.pari 25 :: - sage: a = Mod(3,5); a + sage: a = Mod(3, 5); a 3 sage: x = Mod(-1, 360) sage: x.sqrt(extend=False) @@ -1171,22 +1171,22 @@ cdef class IntegerMod_abstract(FiniteRingElement): sage: R = Integers(5*13^3*37); R Ring of integers modulo 406445 - sage: v = R(-1).sqrt(all=True); v + sage: v = R(-1).sqrt(all=True); v # optional - sage.libs.pari [78853, 111808, 160142, 193097, 213348, 246303, 294637, 327592] - sage: [x^2 for x in v] + sage: [x^2 for x in v] # optional - sage.libs.pari [406444, 406444, 406444, 406444, 406444, 406444, 406444, 406444] - sage: v = R(169).sqrt(all=True); min(v), -max(v), len(v) + sage: v = R(169).sqrt(all=True); min(v), -max(v), len(v) # optional - sage.libs.pari (13, 13, 104) - sage: all(x^2 == 169 for x in v) + sage: all(x^2 == 169 for x in v) # optional - sage.libs.pari True :: - sage: t = FiniteField(next_prime(2^100))(4) - sage: t.sqrt(extend = False, all = True) + sage: t = FiniteField(next_prime(2^100))(4) # optional - sage.rings.finite_rings + sage: t.sqrt(extend=False, all=True) # optional - sage.rings.finite_rings [2, 1267650600228229401496703205651] - sage: t = FiniteField(next_prime(2^100))(2) - sage: t.sqrt(extend = False, all = True) + sage: t = FiniteField(next_prime(2^100))(2) # optional - sage.rings.finite_rings + sage: t.sqrt(extend=False, all=True) # optional - sage.rings.finite_rings [] Modulo a power of 2:: @@ -1378,38 +1378,39 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: - sage: K = GF(31) - sage: a = K(22) - sage: K(22).nth_root(7) + sage: K = GF(31) # optional - sage.rings.finite_rings + sage: a = K(22) # optional - sage.rings.finite_rings + sage: K(22).nth_root(7) # optional - sage.rings.finite_rings 13 - sage: K(25).nth_root(5) + sage: K(25).nth_root(5) # optional - sage.rings.finite_rings 5 - sage: K(23).nth_root(3) + sage: K(23).nth_root(3) # optional - sage.rings.finite_rings 29 - sage: mod(225,2^5*3^2).nth_root(4, all=True) - [225, 129, 33, 63, 255, 159, 9, 201, 105, 279, 183, 87, 81, 273, 177, 207, 111, 15, 153, 57, 249, 135, 39, 231] - sage: mod(275,2^5*7^4).nth_root(7, all=True) + sage: mod(225, 2^5*3^2).nth_root(4, all=True) # optional - sage.rings.padics + [225, 129, 33, 63, 255, 159, 9, 201, 105, 279, 183, 87, 81, + 273, 177, 207, 111, 15, 153, 57, 249, 135, 39, 231] + sage: mod(275, 2^5*7^4).nth_root(7, all=True) # optional - sage.rings.padics [58235, 25307, 69211, 36283, 3355, 47259, 14331] - sage: mod(1,8).nth_root(2,all=True) + sage: mod(1,8).nth_root(2, all=True) # optional - sage.rings.padics [1, 7, 5, 3] - sage: mod(4,8).nth_root(2,all=True) + sage: mod(4,8).nth_root(2, all=True) # optional - sage.rings.padics [2, 6] - sage: mod(1,16).nth_root(4,all=True) + sage: mod(1,16).nth_root(4, all=True) # optional - sage.rings.padics [1, 15, 13, 3, 9, 7, 5, 11] - sage: (mod(22,31)^200).nth_root(200) + sage: (mod(22,31)^200).nth_root(200) # optional - sage.groups 5 - sage: mod(3,6).nth_root(0,all=True) + sage: mod(3,6).nth_root(0, all=True) # optional - sage.rings.padics [] sage: mod(3,6).nth_root(0) Traceback (most recent call last): ... ValueError - sage: mod(1,6).nth_root(0,all=True) + sage: mod(1,6).nth_root(0, all=True) # optional - sage.rings.padics [1, 2, 3, 4, 5] TESTS:: - sage: for p in [1009,2003,10007,100003]: + sage: for p in [1009,2003,10007,100003]: # optional - sage.rings.finite_rings ....: K = GF(p) ....: for r in (p-1).divisors(): ....: if r == 1: continue @@ -1419,7 +1420,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): ....: if (y^41).nth_root(41*r)**(41*r) != y^41: raise RuntimeError ....: if (y^307).nth_root(307*r)**(307*r) != y^307: raise RuntimeError - sage: for t in range(200): + sage: for t in range(200): # optional - sage.libs.pari ....: n = randint(1,2^63) ....: K = Integers(n) ....: b = K.random_element() @@ -1434,18 +1435,18 @@ cdef class IntegerMod_abstract(FiniteRingElement): We check that :trac:`13172` is resolved:: - sage: mod(-1, 4489).nth_root(2, all=True) + sage: mod(-1, 4489).nth_root(2, all=True) # optional - sage.rings.padics [] We check that :trac:`32084` is fixed:: - sage: mod(24, 25).nth_root(50)^50 + sage: mod(24, 25).nth_root(50)^50 # optional - sage.rings.padics 24 Check that the code path cunningham might be used:: sage: a = Mod(9,11) - sage: a.nth_root(2, False, True, 'Johnston', cunningham = True) # optional - cunningham_tables + sage: a.nth_root(2, False, True, 'Johnston', cunningham=True) # optional - cunningham_tables [3, 8] ALGORITHM: @@ -1626,11 +1627,11 @@ cdef class IntegerMod_abstract(FiniteRingElement): This method is also inherited by prime finite fields elements:: - sage: k = GF(97) - sage: a = k(RationalField()('2/3')) - sage: a + sage: k = GF(97) # optional - sage.rings.finite_rings + sage: a = k(RationalField()('2/3')) # optional - sage.rings.finite_rings + sage: a # optional - sage.rings.finite_rings 33 - sage: a.rational_reconstruction() + sage: a.rational_reconstruction() # optional - sage.rings.finite_rings 2/3 """ return self.lift().rational_reconstruction(self.modulus()) @@ -1645,21 +1646,21 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: - sage: a = mod(3,5) - sage: b = mod(2,7) + sage: a = mod(3, 5) + sage: b = mod(2, 7) sage: a.crt(b) 23 :: - sage: a = mod(37,10^8) - sage: b = mod(9,3^8) + sage: a = mod(37, 10^8) + sage: b = mod(9, 3^8) sage: a.crt(b) 125900000037 :: - sage: b = mod(0,1) + sage: b = mod(0, 1) sage: a.crt(b) == a True sage: a.crt(b).modulus() @@ -1667,17 +1668,17 @@ cdef class IntegerMod_abstract(FiniteRingElement): TESTS:: - sage: mod(0,1).crt(mod(4,2^127)) + sage: mod(0, 1).crt(mod(4, 2^127)) 4 - sage: mod(4,2^127).crt(mod(0,1)) + sage: mod(4, 2^127).crt(mod(0, 1)) 4 - sage: mod(4,2^30).crt(mod(0,1)) + sage: mod(4, 2^30).crt(mod(0, 1)) 4 - sage: mod(0,1).crt(mod(4,2^30)) + sage: mod(0, 1).crt(mod(4, 2^30)) 4 - sage: mod(0,1).crt(mod(4,2^15)) + sage: mod(0, 1).crt(mod(4, 2^15)) 4 - sage: mod(4,2^15).crt(mod(0,1)) + sage: mod(4, 2^15).crt(mod(0, 1)) 4 AUTHORS: @@ -1736,20 +1737,20 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: - sage: mod(1,2).is_primitive_root() + sage: mod(1, 2).is_primitive_root() True - sage: mod(3,4).is_primitive_root() + sage: mod(3, 4).is_primitive_root() True - sage: mod(2,7).is_primitive_root() + sage: mod(2, 7).is_primitive_root() # optional - sage.libs.pari False - sage: mod(3,98).is_primitive_root() + sage: mod(3, 98).is_primitive_root() # optional - sage.libs.pari True - sage: mod(11,1009^2).is_primitive_root() + sage: mod(11, 1009^2).is_primitive_root() # optional - sage.libs.pari True TESTS:: - sage: for p in prime_range(3,12): + sage: for p in prime_range(3,12): # optional - sage.libs.pari ....: for k in range(1,4): ....: for even in [1,2]: ....: n = even*p^k @@ -1762,14 +1763,14 @@ cdef class IntegerMod_abstract(FiniteRingElement): `0` is not a primitive root mod `n` (:trac:`23624`) except for `n=0`:: - sage: mod(0, 17).is_primitive_root() + sage: mod(0, 17).is_primitive_root() # optional - sage.libs.pari False - sage: all(not mod(0, n).is_primitive_root() for n in srange(2, 20)) + sage: all(not mod(0, n).is_primitive_root() for n in srange(2, 20)) # optional - sage.libs.pari True sage: mod(0, 1).is_primitive_root() True - sage: all(not mod(p^j, p^k).is_primitive_root() + sage: all(not mod(p^j, p^k).is_primitive_root() # optional - sage.libs.pari ....: for p in prime_range(3, 12) ....: for k in srange(1, 4) ....: for j in srange(0, k)) @@ -1824,14 +1825,15 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: - sage: Mod(-1,5).multiplicative_order() + sage: Mod(-1, 5).multiplicative_order() # optional - sage.libs.pari 2 - sage: Mod(1,5).multiplicative_order() + sage: Mod(1, 5).multiplicative_order() # optional - sage.libs.pari 1 - sage: Mod(0,5).multiplicative_order() + sage: Mod(0, 5).multiplicative_order() # optional - sage.libs.pari Traceback (most recent call last): ... - ArithmeticError: multiplicative order of 0 not defined since it is not a unit modulo 5 + ArithmeticError: multiplicative order of 0 not defined + since it is not a unit modulo 5 """ try: return sage.rings.integer.Integer(self.__pari__().znorder()) @@ -1841,7 +1843,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): def valuation(self, p): """ - The largest power r such that m is in the ideal generated by p^r or infinity if there is not a largest such power. + The largest power `r` such that `m` is in the ideal generated by `p^r` or infinity if there is not a largest such power. However it is an error to take the valuation with respect to a unit. .. NOTE:: @@ -1850,13 +1852,13 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES: - This example shows that the (a*b).valuation(n) is not always the same as a.valuation(n) + b.valuation(n) + This example shows that ``(a*b).valuation(n)`` is not always the same as ``a.valuation(n) + b.valuation(n)`` :: - sage: R=ZZ.quo(9) - sage: a=R(3) - sage: b=R(6) + sage: R = ZZ.quo(9) + sage: a = R(3) + sage: b = R(6) sage: a.valuation(3) 1 sage: a.valuation(3) + b.valuation(3) @@ -1875,9 +1877,9 @@ cdef class IntegerMod_abstract(FiniteRingElement): TESTS:: - sage: R=ZZ.quo(12) - sage: a=R(2) - sage: b=R(4) + sage: R = ZZ.quo(12) + sage: a = R(2) + sage: b = R(4) sage: a.valuation(2) 1 sage: b.valuation(2) @@ -1905,7 +1907,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: - sage: GF(7)(3) // 5 + sage: GF(7)(3) // 5 # optional - sage.rings.finite_rings 2 """ return self._mul_(~right) @@ -1932,9 +1934,9 @@ cdef class IntegerMod_abstract(FiniteRingElement): EXAMPLES:: - sage: F. = GF(13) - sage: V = F.vector_space(map=False) - sage: V(a) + sage: F. = GF(13) # optional - sage.rings.finite_rings + sage: V = F.vector_space(map=False) # optional - sage.rings.finite_rings + sage: V(a) # optional - sage.rings.finite_rings (1) """ return self.parent().vector_space(map=False)([self]) @@ -1977,8 +1979,8 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): r""" EXAMPLES:: - sage: p = next_prime(2^32) - sage: GF(p)(int(p+1)) + sage: p = next_prime(2^32) # optional - sage.libs.pari + sage: GF(p)(int(p + 1)) # optional - sage.rings.finite_rings 1 """ mpz_set_si(self.value, value) @@ -2102,7 +2104,7 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): cpdef bint is_unit(self): """ - Return True iff this element is a unit. + Return ``True`` iff this element is a unit. EXAMPLES:: @@ -2250,9 +2252,9 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): sage: R = Integers(10^10) sage: R(2)^1000 5668069376 - sage: p = next_prime(11^10) - sage: R = Integers(p) - sage: R(9876)^(p-1) + sage: p = next_prime(11^10) # optional - sage.libs.pari + sage: R = Integers(p) # optional - sage.libs.pari + sage: R(9876)^(p-1) # optional - sage.libs.pari 1 sage: mod(3, 10^100)^-2 8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888889 @@ -2265,14 +2267,14 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): We define ``0^0`` to be unity, :trac:`13894`:: - sage: p = next_prime(11^10) - sage: R = Integers(p) - sage: R(0)^0 + sage: p = next_prime(11^10) # optional - sage.libs.pari + sage: R = Integers(p) # optional - sage.libs.pari + sage: R(0)^0 # optional - sage.libs.pari 1 The value returned from ``0^0`` should belong to our ring:: - sage: type(R(0)^0) == type(R(0)) + sage: type(R(0)^0) == type(R(0)) # optional - sage.libs.pari True When the modulus is ``1``, the only element in the ring is @@ -2489,7 +2491,7 @@ cdef class IntegerMod_int(IntegerMod_abstract): cpdef bint is_unit(IntegerMod_int self): """ - Return True iff this element is a unit + Return ``True`` iff this element is a unit EXAMPLES:: @@ -2908,16 +2910,16 @@ cdef class IntegerMod_int(IntegerMod_abstract): 86 sage: mod(7, 18).sqrt() 5 - sage: a = mod(14, 5^60).sqrt() - sage: a*a + sage: a = mod(14, 5^60).sqrt() # optional - sage.libs.pari + sage: a*a # optional - sage.libs.pari 14 sage: mod(15, 389).sqrt(extend=False) Traceback (most recent call last): ... ValueError: self must be a square - sage: Mod(1/9, next_prime(2^40)).sqrt()^(-2) + sage: Mod(1/9, next_prime(2^40)).sqrt()^(-2) # optional - sage.libs.pari 9 - sage: Mod(1/25, next_prime(2^90)).sqrt()^(-2) + sage: Mod(1/25, next_prime(2^90)).sqrt()^(-2) # optional - sage.libs.pari 25 :: @@ -2932,7 +2934,8 @@ cdef class IntegerMod_int(IntegerMod_abstract): sage: y = x.sqrt(); y sqrt359 sage: y.parent() - Univariate Quotient Polynomial Ring in sqrt359 over Ring of integers modulo 360 with modulus x^2 + 1 + Univariate Quotient Polynomial Ring in sqrt359 + over Ring of integers modulo 360 with modulus x^2 + 1 sage: y^2 359 @@ -2948,20 +2951,20 @@ cdef class IntegerMod_int(IntegerMod_abstract): [1, 19, 71, 89, 91, 109, 161, 179, 181, 199, 251, 269, 271, 289, 341, 359] sage: R(0).sqrt(all=True) [0, 60, 120, 180, 240, 300] - sage: GF(107)(0).sqrt(all=True) + sage: GF(107)(0).sqrt(all=True) # optional - sage.rings.finite_rings [0] :: sage: R = Integers(5*13^3*37); R Ring of integers modulo 406445 - sage: v = R(-1).sqrt(all=True); v + sage: v = R(-1).sqrt(all=True); v # optional - sage.libs.pari [78853, 111808, 160142, 193097, 213348, 246303, 294637, 327592] - sage: [x^2 for x in v] + sage: [x^2 for x in v] # optional - sage.libs.pari [406444, 406444, 406444, 406444, 406444, 406444, 406444, 406444] - sage: v = R(169).sqrt(all=True); min(v), -max(v), len(v) + sage: v = R(169).sqrt(all=True); min(v), -max(v), len(v) # optional - sage.libs.pari (13, 13, 104) - sage: all(x^2 == 169 for x in v) + sage: all(x^2 == 169 for x in v) # optional - sage.libs.pari True Modulo a power of 2:: @@ -2980,7 +2983,7 @@ cdef class IntegerMod_int(IntegerMod_abstract): Check for :trac:`30797`:: - sage: GF(103)(-1).sqrt(extend=False, all=True) + sage: GF(103)(-1).sqrt(extend=False, all=True) # optional - sage.rings.finite_rings [] """ cdef int_fast32_t i, n = self.__modulus.int32 @@ -3312,7 +3315,7 @@ cdef class IntegerMod_int64(IntegerMod_abstract): cpdef bint is_unit(IntegerMod_int64 self): """ - Return True iff this element is a unit. + Return ``True`` iff this element is a unit. EXAMPLES:: @@ -3547,9 +3550,9 @@ cdef class IntegerMod_int64(IntegerMod_abstract): sage: R = Integers(10) sage: R(2)^10 4 - sage: p = next_prime(10^5) - sage: R = Integers(p) - sage: R(1234)^(p-1) + sage: p = next_prime(10^5) # optional - sage.libs.pari + sage: R = Integers(p) # optional - sage.libs.pari + sage: R(1234)^(p - 1) # optional - sage.libs.pari 1 sage: R = Integers(17^5) sage: R(17)^5 @@ -3575,14 +3578,14 @@ cdef class IntegerMod_int64(IntegerMod_abstract): We define ``0^0`` to be unity, :trac:`13894`:: - sage: p = next_prime(10^5) - sage: R = Integers(p) - sage: R(0)^0 + sage: p = next_prime(10^5) # optional - sage.libs.pari + sage: R = Integers(p) # optional - sage.libs.pari + sage: R(0)^0 # optional - sage.libs.pari 1 The value returned from ``0^0`` should belong to our ring:: - sage: type(R(0)^0) == type(R(0)) + sage: type(R(0)^0) == type(R(0)) # optional - sage.libs.pari True When the modulus is ``1``, the only element in the ring is @@ -3902,11 +3905,11 @@ def square_root_mod_prime_power(IntegerMod_abstract a, p, e): :: - sage: a = Mod(72,97^10) - sage: b = square_root_mod_prime_power(a,97,10) - sage: b^2 == a + sage: a = Mod(72, 97^10) + sage: b = square_root_mod_prime_power(a, 97, 10) # optional - sage.libs.pari + sage: b^2 == a # optional - sage.libs.pari True - sage: mod(100, 5^7).sqrt()^2 + sage: mod(100, 5^7).sqrt()^2 # optional - sage.libs.pari 100 TESTS: @@ -3914,15 +3917,15 @@ def square_root_mod_prime_power(IntegerMod_abstract a, p, e): A big example for the binary case (:trac:`33961`):: sage: y = Mod(-7, 2^777) - sage: hex(y.sqrt()^2 - y) + sage: hex(y.sqrt()^2 - y) # optional - sage.libs.pari '0x0' Testing with random squares in random rings:: - sage: p = random_prime(999) - sage: e = randrange(1, 999) - sage: x = Zmod(p^e).random_element() - sage: (x^2).sqrt()^2 == x^2 + sage: p = random_prime(999) # optional - sage.libs.pari + sage: e = randrange(1, 999) # optional - sage.libs.pari + sage: x = Zmod(p^e).random_element() # optional - sage.libs.pari + sage: (x^2).sqrt()^2 == x^2 # optional - sage.libs.pari True """ if a.is_zero() or a.is_one(): @@ -4017,7 +4020,7 @@ cpdef square_root_mod_prime(IntegerMod_abstract a, p=None): :: sage: from sage.rings.finite_rings.integer_mod import square_root_mod_prime # sqrt() uses brute force for small p - sage: all(square_root_mod_prime(a*a)^2 == a*a + sage: all(square_root_mod_prime(a*a)^2 == a*a # optional - sage.libs.pari ....: for p in prime_range(100) ....: for a in Integers(p)) True @@ -4103,7 +4106,7 @@ def lucas_q1(mm, IntegerMod_abstract P): TESTS:: sage: from sage.rings.finite_rings.integer_mod import lucas_q1 - sage: all(lucas_q1(k, a) == BinaryRecurrenceSequence(a, -1, 2, a)(k) + sage: all(lucas_q1(k, a) == BinaryRecurrenceSequence(a, -1, 2, a)(k) # optional - sage.combinat ....: for a in Integers(23) ....: for k in range(13)) True @@ -4171,7 +4174,7 @@ def lucas(k, P, Q=1, n=None): sage: p = randint(0,100000) sage: q = randint(0,100000) sage: n = randint(1,100) - sage: all(lucas(k,p,q,n)[0] == Mod(lucas_number2(k,p,q),n) + sage: all(lucas(k, p, q, n)[0] == Mod(lucas_number2(k, p, q), n) # optional - sage.combinat ....: for k in Integers(20)) True sage: from sage.rings.finite_rings.integer_mod import lucas @@ -4179,7 +4182,7 @@ def lucas(k, P, Q=1, n=None): sage: q = randint(0,100000) sage: n = randint(1,100) sage: k = randint(0,100) - sage: lucas(k,p,q,n) == [Mod(lucas_number2(k,p,q),n),Mod(q^(int(k/2)),n)] + sage: lucas(k, p, q, n) == [Mod(lucas_number2(k, p, q), n), Mod(q^(int(k/2)), n)] # optional - sage.combinat True EXAMPLES:: @@ -4317,8 +4320,14 @@ cdef class IntegerMod_to_IntegerMod(IntegerMod_hom): sage: from sage.rings.finite_rings.integer_mod import IntegerMod_to_IntegerMod sage: Rs = [Integers(3**k) for k in range(1,30,5)] sage: [type(R(0)) for R in Rs] - [, , , , , ] - sage: fs = [IntegerMod_to_IntegerMod(S, R) for R in Rs for S in Rs if S is not R and S.order() > R.order()] + [, + , + , + , + , + ] + sage: fs = [IntegerMod_to_IntegerMod(S, R) + ....: for R in Rs for S in Rs if S is not R and S.order() > R.order()] sage: all(f(-1) == f.codomain()(-1) for f in fs) True sage: [f(-1) for f in fs] @@ -4387,7 +4396,9 @@ cdef class Integer_to_IntegerMod(IntegerMod_hom): sage: from sage.rings.finite_rings.integer_mod import Integer_to_IntegerMod sage: Rs = [Integers(10), Integers(10^5), Integers(10^10)] sage: [type(R(0)) for R in Rs] - [, , ] + [, + , + ] sage: fs = [Integer_to_IntegerMod(R) for R in Rs] sage: [f(-1) for f in fs] [9, 99999, 9999999999] @@ -4449,7 +4460,7 @@ cdef class IntegerMod_to_Integer(Map): EXAMPLES:: - sage: ZZ.convert_map_from(GF(2)) + sage: ZZ.convert_map_from(GF(2)) # optional - sage.rings.finite_rings Lifting map: From: Finite Field of size 2 To: Integer Ring @@ -4461,7 +4472,7 @@ cdef class IntegerMod_to_Integer(Map): Lifting maps are morphisms in the category of sets (see :trac:`15618`):: - sage: ZZ.convert_map_from(GF(2)).parent() + sage: ZZ.convert_map_from(GF(2)).parent() # optional - sage.rings.finite_rings Set of Morphisms from Finite Field of size 2 to Integer Ring in Category of sets """ import sage.categories.homset @@ -4493,7 +4504,11 @@ cdef class Int_to_IntegerMod(IntegerMod_hom): sage: from sage.rings.finite_rings.integer_mod import Int_to_IntegerMod sage: Rs = [Integers(2**k) for k in range(1,50,10)] sage: [type(R(0)) for R in Rs] - [, , , , ] + [, + , + , + , + ] sage: fs = [Int_to_IntegerMod(R) for R in Rs] sage: [f(-1) for f in fs] [1, 2047, 2097151, 2147483647, 2199023255551] diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index a10d84aade9..f34faa4e9a9 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -16,16 +16,16 @@ :: sage: r = Integers(7) - sage: s = GF(7) - sage: r.has_coerce_map_from(s) + sage: s = GF(7) # optional - sage.rings.finite_rings + sage: r.has_coerce_map_from(s) # optional - sage.rings.finite_rings False - sage: s.has_coerce_map_from(r) + sage: s.has_coerce_map_from(r) # optional - sage.rings.finite_rings True - sage: s(1) + r(1) + sage: s(1) + r(1) # optional - sage.rings.finite_rings 2 - sage: parent(s(1) + r(1)) + sage: parent(s(1) + r(1)) # optional - sage.rings.finite_rings Finite Field of size 7 - sage: parent(r(1) + s(1)) + sage: parent(r(1) + s(1)) # optional - sage.rings.finite_rings Finite Field of size 7 We list the elements of `\ZZ/3\ZZ`:: @@ -259,9 +259,9 @@ def is_IntegerModRing(x): Use isinstance(..., sage.rings.abc.IntegerModRing) instead. See https://github.com/sagemath/sage/issues/32606 for details. True - sage: is_IntegerModRing(GF(13)) + sage: is_IntegerModRing(GF(13)) # optional - sage.rings.finite_rings True - sage: is_IntegerModRing(GF(4, 'a')) + sage: is_IntegerModRing(GF(4, 'a')) # optional - sage.rings.finite_rings False sage: is_IntegerModRing(10) False @@ -290,9 +290,9 @@ def _unit_gens_primepowercase(p, r): sage: from sage.rings.finite_rings.integer_mod_ring import _unit_gens_primepowercase sage: _unit_gens_primepowercase(2, 3) [(7, 2), (5, 2)] - sage: _unit_gens_primepowercase(17, 1) + sage: _unit_gens_primepowercase(17, 1) # optional - sage.libs.pari [(3, 16)] - sage: _unit_gens_primepowercase(3, 3) + sage: _unit_gens_primepowercase(3, 3) # optional - sage.libs.pari [(2, 18)] """ pr = p**r @@ -344,14 +344,14 @@ class IntegerModRing_generic(quotient_ring.QuotientRing_generic, sage.rings.abc. 29 sage: FF.order() 29 - sage: gens = FF.unit_gens() - sage: a = gens[0] - sage: a + sage: gens = FF.unit_gens() # optional - sage.groups + sage: a = gens[0] # optional - sage.groups + sage: a # optional - sage.groups 2 - sage: a.is_square() + sage: a.is_square() # optional - sage.groups False - sage: def pow(i): return a**i - sage: [pow(i) for i in range(16)] + sage: def pow(i): return a**i # optional - sage.groups + sage: [pow(i) for i in range(16)] # optional - sage.groups [1, 2, 4, 8, 16, 3, 6, 12, 24, 19, 9, 18, 7, 14, 28, 27] sage: TestSuite(FF).run() @@ -404,23 +404,23 @@ class IntegerModRing_generic(quotient_ring.QuotientRing_generic, sage.rings.abc. 16 sage: Z16.characteristic() 16 - sage: gens = Z16.unit_gens() - sage: gens + sage: gens = Z16.unit_gens() # optional - sage.groups + sage: gens # optional - sage.groups (15, 5) - sage: a = gens[0] - sage: b = gens[1] - sage: def powa(i): return a**i - sage: def powb(i): return b**i - sage: gp_exp = FF.unit_group_exponent() - sage: gp_exp + sage: a = gens[0] # optional - sage.groups + sage: b = gens[1] # optional - sage.groups + sage: def powa(i): return a**i # optional - sage.groups + sage: def powb(i): return b**i # optional - sage.groups + sage: gp_exp = FF.unit_group_exponent() # optional - sage.groups + sage: gp_exp # optional - sage.groups 28 - sage: [powa(i) for i in range(15)] + sage: [powa(i) for i in range(15)] # optional - sage.groups [1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1] - sage: [powb(i) for i in range(15)] + sage: [powb(i) for i in range(15)] # optional - sage.groups [1, 5, 9, 13, 1, 5, 9, 13, 1, 5, 9, 13, 1, 5, 9] - sage: a.multiplicative_order() + sage: a.multiplicative_order() # optional - sage.groups 2 - sage: b.multiplicative_order() + sage: b.multiplicative_order() # optional - sage.groups 4 sage: TestSuite(Z16).run() @@ -572,7 +572,8 @@ def extension(self, poly, name=None, names=None, **kwds): sage: R. = QQ[] sage: Integers(8).extension(t^2 - 3) - Univariate Quotient Polynomial Ring in t over Ring of integers modulo 8 with modulus t^2 + 5 + Univariate Quotient Polynomial Ring in t + over Ring of integers modulo 8 with modulus t^2 + 5 """ if self.modulus() == 1: return self @@ -638,22 +639,22 @@ def multiplicative_subgroups(self): EXAMPLES:: - sage: Integers(5).multiplicative_subgroups() + sage: Integers(5).multiplicative_subgroups() # optional - sage.groups ((2,), (4,), ()) - sage: Integers(15).multiplicative_subgroups() + sage: Integers(15).multiplicative_subgroups() # optional - sage.groups ((11, 7), (11, 4), (2,), (11,), (14,), (7,), (4,), ()) - sage: Integers(2).multiplicative_subgroups() + sage: Integers(2).multiplicative_subgroups() # optional - sage.groups ((),) - sage: len(Integers(341).multiplicative_subgroups()) + sage: len(Integers(341).multiplicative_subgroups()) # optional - sage.groups 80 TESTS:: - sage: IntegerModRing(1).multiplicative_subgroups() + sage: IntegerModRing(1).multiplicative_subgroups() # optional - sage.groups ((),) - sage: IntegerModRing(2).multiplicative_subgroups() + sage: IntegerModRing(2).multiplicative_subgroups() # optional - sage.groups ((),) - sage: IntegerModRing(3).multiplicative_subgroups() + sage: IntegerModRing(3).multiplicative_subgroups() # optional - sage.groups ((2,), ()) """ return tuple(tuple(g.value() for g in H.gens()) @@ -667,7 +668,7 @@ def is_integral_domain(self, proof=None): sage: Integers(389).is_integral_domain() True - sage: Integers(389^2).is_integral_domain() + sage: Integers(389^2).is_integral_domain() # optional - sage.libs.pari False TESTS: @@ -688,7 +689,7 @@ def is_unique_factorization_domain(self, proof=None): sage: Integers(389).is_unique_factorization_domain() True - sage: Integers(389^2).is_unique_factorization_domain() + sage: Integers(389^2).is_unique_factorization_domain() # optional - sage.libs.pari False """ return self.is_field(proof) @@ -696,7 +697,7 @@ def is_unique_factorization_domain(self, proof=None): @cached_method def is_field(self, proof=None): r""" - Return True precisely if the order is prime. + Return ``True`` precisely if the order is prime. INPUT: @@ -790,10 +791,10 @@ def field(self): sage: R = Integers(7); R Ring of integers modulo 7 - sage: R.field() + sage: R.field() # optional - sage.rings.finite_rings Finite Field of size 7 sage: R = Integers(9) - sage: R.field() + sage: R.field() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: self must be a field @@ -827,8 +828,8 @@ def _pseudo_fraction_field(self): This should be very fast:: - sage: R. = Integers(next_prime(10^101)*next_prime(10^100))[] - sage: x / R.base_ring()(2) + sage: R. = Integers(next_prime(10^101)*next_prime(10^100))[] # optional - sage.libs.pari + sage: x / R.base_ring()(2) # optional - sage.libs.pari 500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000401*x """ return self @@ -847,18 +848,18 @@ def multiplicative_group_is_cyclic(self): sage: R.multiplicative_group_is_cyclic() True sage: R = Integers(9) - sage: R.multiplicative_group_is_cyclic() + sage: R.multiplicative_group_is_cyclic() # optional - sage.libs.pari True - sage: Integers(8).multiplicative_group_is_cyclic() + sage: Integers(8).multiplicative_group_is_cyclic() # optional - sage.libs.pari False - sage: Integers(4).multiplicative_group_is_cyclic() + sage: Integers(4).multiplicative_group_is_cyclic() # optional - sage.libs.pari True - sage: Integers(25*3).multiplicative_group_is_cyclic() + sage: Integers(25*3).multiplicative_group_is_cyclic() # optional - sage.libs.pari False We test that :trac:`5250` is fixed:: - sage: Integers(162).multiplicative_group_is_cyclic() + sage: Integers(162).multiplicative_group_is_cyclic() # optional - sage.libs.pari True """ n = self.order() @@ -885,24 +886,24 @@ def multiplicative_generator(self): sage: R = Integers(7); R Ring of integers modulo 7 - sage: R.multiplicative_generator() + sage: R.multiplicative_generator() # optional - sage.libs.pari 3 sage: R = Integers(9) - sage: R.multiplicative_generator() + sage: R.multiplicative_generator() # optional - sage.libs.pari 2 - sage: Integers(8).multiplicative_generator() + sage: Integers(8).multiplicative_generator() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: multiplicative group of this ring is not cyclic - sage: Integers(4).multiplicative_generator() + sage: Integers(4).multiplicative_generator() # optional - sage.libs.pari 3 - sage: Integers(25*3).multiplicative_generator() + sage: Integers(25*3).multiplicative_generator() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: multiplicative group of this ring is not cyclic - sage: Integers(25*3).unit_gens() + sage: Integers(25*3).unit_gens() # optional - sage.libs.pari (26, 52) - sage: Integers(162).unit_gens() + sage: Integers(162).unit_gens() # optional - sage.libs.pari (83,) """ try: @@ -927,9 +928,9 @@ def quadratic_nonresidue(self): EXAMPLES:: sage: R = Integers(17) - sage: R.quadratic_nonresidue() + sage: R.quadratic_nonresidue() # optional - sage.libs.pari 3 - sage: R(3).is_square() + sage: R(3).is_square() # optional - sage.libs.pari False """ try: @@ -954,18 +955,18 @@ def square_roots_of_one(self): sage: R = Integers(2^10) sage: [x for x in R if x^2 == 1] [1, 511, 513, 1023] - sage: R.square_roots_of_one() + sage: R.square_roots_of_one() # optional - sage.libs.pari (1, 511, 513, 1023) :: - sage: v = Integers(9*5).square_roots_of_one(); v + sage: v = Integers(9*5).square_roots_of_one(); v # optional - sage.libs.pari (1, 19, 26, 44) - sage: [x^2 for x in v] + sage: [x^2 for x in v] # optional - sage.libs.pari [1, 1, 1, 1] - sage: v = Integers(9*5*8).square_roots_of_one(); v + sage: v = Integers(9*5*8).square_roots_of_one(); v # optional - sage.libs.pari (1, 19, 71, 89, 91, 109, 161, 179, 181, 199, 251, 269, 271, 289, 341, 359) - sage: [x^2 for x in v] + sage: [x^2 for x in v] # optional - sage.libs.pari [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] """ try: @@ -1132,7 +1133,7 @@ def _pari_order(self): EXAMPLES:: - sage: Zmod(87)._pari_order() + sage: Zmod(87)._pari_order() # optional - sage.libs.pari 87 """ try: @@ -1145,14 +1146,14 @@ def _element_constructor_(self, x): """ TESTS:: - sage: K2 = GF(2) - sage: K3 = GF(3) - sage: K8 = GF(8,'a') - sage: K8(5) # indirect doctest + sage: K2 = GF(2) # optional - sage.rings.finite_rings + sage: K3 = GF(3) # optional - sage.rings.finite_rings + sage: K8 = GF(8, 'a') # optional - sage.rings.finite_rings + sage: K8(5) # indirect doctest # optional - sage.rings.finite_rings 1 - sage: K8('a+1') + sage: K8('a+1') # optional - sage.rings.finite_rings a + 1 - sage: K8(K2(1)) + sage: K8(K2(1)) # optional - sage.rings.finite_rings 1 The following test refers to :trac:`6468`:: @@ -1164,7 +1165,7 @@ def _element_constructor_(self, x): ....: raise PariError sage: P = foo_parent() sage: F = foo(P) - sage: GF(2)(F) + sage: GF(2)(F) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: error coercing to finite field @@ -1172,21 +1173,21 @@ def _element_constructor_(self, x): The following test refers to :trac:`8970`:: sage: R = Zmod(13); a = R(2) - sage: a == R(gap(a)) + sage: a == R(gap(a)) # optional - sage.libs.gap True libgap interface (:trac:`23714`):: - sage: a = libgap.eval("Z(13)^2") - sage: a.sage() + sage: a = libgap.eval("Z(13)^2") # optional - sage.libs.gap + sage: a.sage() # optional - sage.libs.gap 4 - sage: libgap(a.sage()) == a + sage: libgap(a.sage()) == a # optional - sage.libs.gap True better syntax for libgap interface:: - sage: a = libgap.Z(13)^2 - sage: libgap(a.sage()) == a + sage: a = libgap.Z(13)^2 # optional - sage.libs.gap + sage: libgap(a.sage()) == a # optional - sage.libs.gap True """ try: @@ -1295,7 +1296,7 @@ def _convert_map_from_(self, other): EXAMPLES:: - sage: Zmod(81).convert_map_from(Qp(3)) + sage: Zmod(81).convert_map_from(Qp(3)) # optional - sage.rings.padics Reduction morphism: From: 3-adic Field with capped relative precision 20 To: Ring of integers modulo 81 @@ -1318,10 +1319,12 @@ def __richcmp__(self, other, op): Ring of integers modulo 12 sage: Z13 = IntegerModRing(13); Z13 Ring of integers modulo 13 - sage: F = GF(11); F + sage: Z11 == Z11, Z11 == Z12, Z11 == Z13 + (True, False, False) + sage: F = GF(11); F # optional - sage.rings.finite_rings Finite Field of size 11 - sage: Z11 == Z11, Z11 == Z12, Z11 == Z13, Z11 == F - (True, False, False, False) + sage: Z11 == F # optional - sage.rings.finite_rings + False In :trac:`15229`, the following was implemented:: @@ -1329,7 +1332,7 @@ def __richcmp__(self, other, op): sage: R2 = IntegerModRing(5, is_field=True) sage: R1 is R2 # used to return False True - sage: R2 == GF(5) + sage: R2 == GF(5) # optional - sage.rings.finite_rings False """ @@ -1363,12 +1366,12 @@ def unit_gens(self, **kwds): EXAMPLES:: sage: R = IntegerModRing(18) - sage: R.unit_gens() + sage: R.unit_gens() # optional - sage.groups (11,) sage: R = IntegerModRing(17) - sage: R.unit_gens() + sage: R.unit_gens() # optional - sage.groups (3,) - sage: IntegerModRing(next_prime(10^30)).unit_gens() + sage: IntegerModRing(next_prime(10^30)).unit_gens() # optional - sage.groups (5,) The choice of generators is affected by the optional keyword @@ -1376,18 +1379,18 @@ def unit_gens(self, **kwds): See :meth:`unit_group` for details. :: sage: A = Zmod(55) - sage: A.unit_gens(algorithm='sage') + sage: A.unit_gens(algorithm='sage') # optional - sage.groups (12, 46) - sage: A.unit_gens(algorithm='pari') + sage: A.unit_gens(algorithm='pari') # optional - sage.groups sage.libs.pari (2, 21) TESTS:: - sage: IntegerModRing(2).unit_gens() + sage: IntegerModRing(2).unit_gens() # optional - sage.groups () - sage: IntegerModRing(4).unit_gens() + sage: IntegerModRing(4).unit_gens() # optional - sage.groups (3,) - sage: IntegerModRing(8).unit_gens() + sage: IntegerModRing(8).unit_gens() # optional - sage.groups (7, 5) """ @@ -1398,10 +1401,10 @@ def unit_group_exponent(self): EXAMPLES:: sage: R = IntegerModRing(17) - sage: R.unit_group_exponent() + sage: R.unit_group_exponent() # optional - sage.groups 16 sage: R = IntegerModRing(18) - sage: R.unit_group_exponent() + sage: R.unit_group_exponent() # optional - sage.groups 6 """ return self.unit_group().exponent() @@ -1413,7 +1416,7 @@ def unit_group_order(self): EXAMPLES:: sage: R = Integers(500) - sage: R.unit_group_order() + sage: R.unit_group_order() # optional - sage.groups 200 """ return self.unit_group().order() @@ -1452,69 +1455,71 @@ def unit_group(self, algorithm='sage'): cyclic factors are computed, but in a different order:: sage: A = Zmod(15) - sage: G = A.unit_group(); G + sage: G = A.unit_group(); G # optional - sage.groups Multiplicative Abelian group isomorphic to C2 x C4 - sage: G.gens_values() + sage: G.gens_values() # optional - sage.groups (11, 7) - sage: H = A.unit_group(algorithm='pari'); H + sage: H = A.unit_group(algorithm='pari'); H # optional - sage.groups sage.libs.pari Multiplicative Abelian group isomorphic to C4 x C2 - sage: H.gens_values() + sage: H.gens_values() # optional - sage.groups sage.libs.pari (7, 11) Here are two examples where the cyclic factors are isomorphic, but are ordered differently and have different generators:: sage: A = Zmod(40) - sage: G = A.unit_group(); G + sage: G = A.unit_group(); G # optional - sage.groups Multiplicative Abelian group isomorphic to C2 x C2 x C4 - sage: G.gens_values() + sage: G.gens_values() # optional - sage.groups (31, 21, 17) - sage: H = A.unit_group(algorithm='pari'); H + sage: H = A.unit_group(algorithm='pari'); H # optional - sage.groups sage.libs.pari Multiplicative Abelian group isomorphic to C4 x C2 x C2 - sage: H.gens_values() + sage: H.gens_values() # optional - sage.groups sage.libs.pari (17, 31, 21) sage: A = Zmod(192) - sage: G = A.unit_group(); G + sage: G = A.unit_group(); G # optional - sage.groups Multiplicative Abelian group isomorphic to C2 x C16 x C2 - sage: G.gens_values() + sage: G.gens_values() # optional - sage.groups (127, 133, 65) - sage: H = A.unit_group(algorithm='pari'); H + sage: H = A.unit_group(algorithm='pari'); H # optional - sage.groups sage.libs.pari Multiplicative Abelian group isomorphic to C16 x C2 x C2 - sage: H.gens_values() + sage: H.gens_values() # optional - sage.groups sage.libs.pari (133, 127, 65) In the following examples, the cyclic factors are not even isomorphic:: sage: A = Zmod(319) - sage: A.unit_group() + sage: A.unit_group() # optional - sage.groups Multiplicative Abelian group isomorphic to C10 x C28 - sage: A.unit_group(algorithm='pari') + sage: A.unit_group(algorithm='pari') # optional - sage.groups sage.libs.pari Multiplicative Abelian group isomorphic to C140 x C2 sage: A = Zmod(30.factorial()) - sage: A.unit_group() - Multiplicative Abelian group isomorphic to C2 x C16777216 x C3188646 x C62500 x C2058 x C110 x C156 x C16 x C18 x C22 x C28 - sage: A.unit_group(algorithm='pari') - Multiplicative Abelian group isomorphic to C20499647385305088000000 x C55440 x C12 x C12 x C4 x C2 x C2 x C2 x C2 x C2 x C2 + sage: A.unit_group() # optional - sage.groups + Multiplicative Abelian group isomorphic to + C2 x C16777216 x C3188646 x C62500 x C2058 x C110 x C156 x C16 x C18 x C22 x C28 + sage: A.unit_group(algorithm='pari') # optional - sage.groups sage.libs.pari + Multiplicative Abelian group isomorphic to + C20499647385305088000000 x C55440 x C12 x C12 x C4 x C2 x C2 x C2 x C2 x C2 x C2 TESTS: We test the cases where the unit group is trivial:: sage: A = Zmod(1) - sage: A.unit_group() + sage: A.unit_group() # optional - sage.groups Trivial Abelian group - sage: A.unit_group(algorithm='pari') + sage: A.unit_group(algorithm='pari') # optional - sage.groups sage.libs.pari Trivial Abelian group sage: A = Zmod(2) - sage: A.unit_group() + sage: A.unit_group() # optional - sage.groups Trivial Abelian group - sage: A.unit_group(algorithm='pari') + sage: A.unit_group(algorithm='pari') # optional - sage.groups sage.libs.pari Trivial Abelian group - sage: Zmod(3).unit_group(algorithm='bogus') + sage: Zmod(3).unit_group(algorithm='bogus') # optional - sage.groups Traceback (most recent call last): ... ValueError: unknown algorithm 'bogus' for computing the unit group @@ -1578,7 +1583,7 @@ def _gap_init_(self): sage: R = Integers(12345678900) sage: R Ring of integers modulo 12345678900 - sage: gap(R) # indirect doctest + sage: gap(R) # indirect doctest # optional - sage.libs.gap (Integers mod 12345678900) """ return 'ZmodnZ({})'.format(self.order()) @@ -1624,7 +1629,7 @@ def crt(v): EXAMPLES:: sage: from sage.rings.finite_rings.integer_mod_ring import crt - sage: crt([mod(3, 8),mod(1,19),mod(7, 15)]) + sage: crt([mod(3, 8), mod(1,19), mod(7, 15)]) 1027 """ if len(v) == 0: diff --git a/src/sage/rings/fraction_field.py b/src/sage/rings/fraction_field.py index 7e5703212bf..91c326b13aa 100644 --- a/src/sage/rings/fraction_field.py +++ b/src/sage/rings/fraction_field.py @@ -264,11 +264,11 @@ def _coerce_map_from_(self, S): number fields:: sage: _. = ZZ[] - sage: K. = NumberField(x^5-3*x^4+2424*x^3+2*x-232) - sage: R = K.ring_of_integers() - sage: S. = R[] - sage: F = FractionField(S) - sage: F(1/a) + sage: K. = NumberField(x^5 - 3*x^4 + 2424*x^3 + 2*x - 232) # optional - sage.rings.number_field + sage: R = K.ring_of_integers() # optional - sage.rings.number_field + sage: S. = R[] # optional - sage.rings.number_field + sage: F = FractionField(S) # optional - sage.rings.number_field + sage: F(1/a) # optional - sage.rings.number_field (a^4 - 3*a^3 + 2424*a^2 + 2)/232 Some corner cases have been known to fail in the past (:trac:`5917`):: @@ -394,11 +394,11 @@ def _number_field_to_frac_of_ring_of_integers(self, x): number fields:: sage: _. = ZZ[] - sage: K. = NumberField(x^5-3*x^4+2424*x^3+2*x-232) - sage: R = K.ring_of_integers() - sage: S. = R[] - sage: F = FractionField(S) # indirect doctest - sage: F(1/a) + sage: K. = NumberField(x^5 - 3*x^4 + 2424*x^3 + 2*x - 232) # optional - sage.rings.number_field + sage: R = K.ring_of_integers() # optional - sage.rings.number_field + sage: S. = R[] # optional - sage.rings.number_field + sage: F = FractionField(S) # indirect doctest # optional - sage.rings.number_field + sage: F(1/a) # optional - sage.rings.number_field (a^4 - 3*a^3 + 2424*a^2 + 2)/232 """ f = x.polynomial() # Polynomial over QQ @@ -459,7 +459,7 @@ def characteristic(self): Integer Ring sage: R = Frac(ZZ['t']); R.characteristic() 0 - sage: R = Frac(GF(5)['w']); R.characteristic() + sage: R = Frac(GF(5)['w']); R.characteristic() # optional - sage.rings.finite_rings 5 """ return self._R.characteristic() @@ -481,7 +481,7 @@ def _latex_(self): EXAMPLES:: - sage: latex(Frac(GF(7)['x,y,z'])) # indirect doctest + sage: latex(Frac(GF(7)['x,y,z'])) # indirect doctest # optional - sage.rings.finite_rings \mathrm{Frac}(\Bold{F}_{7}[x, y, z]) """ return "\\mathrm{Frac}(%s)" % latex.latex(self._R) @@ -494,7 +494,7 @@ def _magma_init_(self, magma): sage: QQ['x'].fraction_field()._magma_init_(magma) # optional - magma 'SageCreateWithNames(FieldOfFractions(SageCreateWithNames(PolynomialRing(_sage_ref...),["x"])),["x"])' - sage: GF(9,'a')['x,y,z'].fraction_field()._magma_init_(magma) # optional - magma + sage: GF(9,'a')['x,y,z'].fraction_field()._magma_init_(magma) # optional - magma # optional - sage.rings.finite_rings 'SageCreateWithNames(FieldOfFractions(SageCreateWithNames(PolynomialRing(_sage_ref...,3,"grevlex"),["x","y","z"])),["x","y","z"])' ``_magma_init_`` gets called implicitly below:: @@ -571,17 +571,17 @@ def _element_constructor_(self, x, y=None, coerce=True): The next example failed before :trac:`4376`:: - sage: K(pari((x + 1)/(x^2 + x + 1))) + sage: K(pari((x + 1)/(x^2 + x + 1))) # optional - sage.libs.pari (x + 1)/(x^2 + x + 1) These examples failed before :trac:`11368`:: sage: R. = PolynomialRing(QQ) sage: S = R.fraction_field() - sage: S(pari((x + y)/y)) + sage: S(pari((x + y)/y)) # optional - sage.libs.pari (x + y)/y - sage: S(pari(x + y + 1/z)) + sage: S(pari(x + y + 1/z)) # optional - sage.libs.pari (x*z + y*z + 1)/z This example failed before :trac:`23664`:: @@ -613,13 +613,13 @@ def _element_constructor_(self, x, y=None, coerce=True): Check that :trac:`24539` is fixed:: sage: tau = polygen(QQ, 'tau') - sage: PolynomialRing(CyclotomicField(2), 'z').fraction_field()(tau/(1+tau)) + sage: PolynomialRing(CyclotomicField(2), 'z').fraction_field()(tau/(1+tau)) # optional - sage.rings.number_field z/(z + 1) Check that :trac:`26150` is fixed:: - sage: z = SR.var('z') - sage: CyclotomicField(2)['z'].fraction_field()(2*(4*z + 5)/((z + 1)*(z - 1)^4)) + sage: z = SR.var('z') # optional - sage.symbolic + sage: CyclotomicField(2)['z'].fraction_field()(2*(4*z + 5)/((z + 1)*(z - 1)^4)) # optional - sage.rings.number_field sage.symbolic (8*z + 10)/(z^5 - 3*z^4 + 2*z^3 + 2*z^2 - 3*z + 1) :: @@ -731,11 +731,12 @@ def construction(self): sage: Frac(ZZ['x']).construction() (FractionField, Univariate Polynomial Ring in x over Integer Ring) - sage: K = Frac(GF(3)['t']) - sage: f, R = K.construction() - sage: f(R) - Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 3 - sage: f(R) == K + sage: K = Frac(GF(3)['t']) # optional - sage.rings.finite_rings + sage: f, R = K.construction() # optional - sage.rings.finite_rings + sage: f(R) # optional - sage.rings.finite_rings + Fraction Field of Univariate Polynomial Ring in t + over Finite Field of size 3 + sage: f(R) == K # optional - sage.rings.finite_rings True """ from sage.categories.pushout import FractionField @@ -801,7 +802,8 @@ def ngens(self): EXAMPLES:: sage: R = Frac(PolynomialRing(QQ,'z',10)); R - Fraction Field of Multivariate Polynomial Ring in z0, z1, z2, z3, z4, z5, z6, z7, z8, z9 over Rational Field + Fraction Field of Multivariate Polynomial Ring + in z0, z1, z2, z3, z4, z5, z6, z7, z8, z9 over Rational Field sage: R.ngens() 10 """ @@ -814,7 +816,8 @@ def gen(self, i=0): EXAMPLES:: sage: R = Frac(PolynomialRing(QQ,'z',10)); R - Fraction Field of Multivariate Polynomial Ring in z0, z1, z2, z3, z4, z5, z6, z7, z8, z9 over Rational Field + Fraction Field of Multivariate Polynomial Ring + in z0, z1, z2, z3, z4, z5, z6, z7, z8, z9 over Rational Field sage: R.0 z0 sage: R.gen(3) @@ -983,8 +986,8 @@ def ring_of_integers(self): EXAMPLES:: - sage: K = FractionField(GF(5)['t']) - sage: K.ring_of_integers() + sage: K = FractionField(GF(5)['t']) # optional - sage.rings.finite_rings + sage: K.ring_of_integers() # optional - sage.rings.finite_rings Univariate Polynomial Ring in t over Finite Field of size 5 """ return self._R @@ -995,8 +998,8 @@ def maximal_order(self): EXAMPLES:: - sage: K = FractionField(GF(5)['t']) - sage: K.maximal_order() + sage: K = FractionField(GF(5)['t']) # optional - sage.rings.finite_rings + sage: K.maximal_order() # optional - sage.rings.finite_rings Univariate Polynomial Ring in t over Finite Field of size 5 """ return self._R @@ -1007,8 +1010,8 @@ def class_number(self): EXAMPLES:: - sage: R. = GF(5)[]; K = R.fraction_field() - sage: K.class_number() + sage: R. = GF(5)[]; K = R.fraction_field() # optional - sage.rings.finite_rings + sage: K.class_number() # optional - sage.rings.finite_rings 1 """ return 1 @@ -1019,11 +1022,11 @@ def _factor_univariate_polynomial(self, f): EXAMPLES:: - sage: k. = GF(9) - sage: K = k['t'].fraction_field() - sage: R. = K[] - sage: f = x^3 + a - sage: f.factor() + sage: k. = GF(9) # optional - sage.rings.finite_rings + sage: K = k['t'].fraction_field() # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: f = x^3 + a # optional - sage.rings.finite_rings + sage: f.factor() # optional - sage.rings.finite_rings (x + 2*a + 1)^3 """ @@ -1038,9 +1041,9 @@ def function_field(self): EXAMPLES:: - sage: R. = GF(5)[] - sage: K = R.fraction_field() - sage: K.function_field() + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: K = R.fraction_field() # optional - sage.rings.finite_rings + sage: K.function_field() # optional - sage.rings.finite_rings Rational function field in t over Finite Field of size 5 .. SEEALSO:: @@ -1057,14 +1060,15 @@ def _coerce_map_from_(self, R): EXAMPLES:: - sage: R. = GF(5)[] - sage: K = R.fraction_field() - sage: L = K.function_field() - sage: f = K.coerce_map_from(L); f # indirect doctest + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: K = R.fraction_field() # optional - sage.rings.finite_rings + sage: L = K.function_field() # optional - sage.rings.finite_rings + sage: f = K.coerce_map_from(L); f # indirect doctest # optional - sage.rings.finite_rings Isomorphism: From: Rational function field in t over Finite Field of size 5 - To: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 - sage: f(~L.gen()) + To: Fraction Field of Univariate Polynomial Ring in t + over Finite Field of size 5 + sage: f(~L.gen()) # optional - sage.rings.finite_rings 1/t """ @@ -1162,12 +1166,12 @@ def _richcmp_(self, other, op): sage: R. = QQ[] sage: f = R.fraction_field().coerce_map_from(R) - sage: S. = GF(2)[] - sage: g = S.fraction_field().coerce_map_from(S) + sage: S. = GF(2)[] # optional - sage.rings.finite_rings + sage: g = S.fraction_field().coerce_map_from(S) # optional - sage.rings.finite_rings - sage: f == g # indirect doctest + sage: f == g # indirect doctest # optional - sage.rings.finite_rings False - sage: f == f + sage: f == f # optional - sage.rings.finite_rings True """ @@ -1232,19 +1236,19 @@ def _call_(self, x, check=True): Over inexact rings, we have to take the precision of the denominators into account:: - sage: R=ZpCR(2) - sage: S. = R[] - sage: f = x/S(R(3,absprec=2)) - sage: S(f) + sage: R = ZpCR(2) # optional - sage.rings.padics + sage: S. = R[] # optional - sage.rings.padics + sage: f = x/S(R(3, absprec=2)) # optional - sage.rings.padics + sage: S(f) # optional - sage.rings.padics (1 + 2 + O(2^2))*x Test for Localization:: sage: R. = ZZ[] - sage: L = Localization(R, x**2+2*x+ 1) - sage: 1/(x+1) in L # indirect doctest + sage: L = Localization(R, x**2 + 2*x + 1) # optional - sage.libs.pari + sage: 1/(x + 1) in L # indirect doctest # optional - sage.libs.pari True - sage: 1/(x+2) in L # indirect doctest + sage: 1/(x + 2) in L # indirect doctest # optional - sage.libs.pari False """ codom = self.codomain() @@ -1294,12 +1298,12 @@ def _richcmp_(self, other, op): sage: R. = QQ[] sage: f = R.fraction_field().coerce_map_from(R).section() - sage: S. = GF(2)[] - sage: g = S.fraction_field().coerce_map_from(S).section() + sage: S. = GF(2)[] # optional - sage.rings.finite_rings + sage: g = S.fraction_field().coerce_map_from(S).section() # optional - sage.rings.finite_rings - sage: f == g # indirect doctest + sage: f == g # indirect doctest # optional - sage.rings.finite_rings False - sage: f == f + sage: f == f # optional - sage.rings.finite_rings True """ diff --git a/src/sage/rings/fraction_field_FpT.pyx b/src/sage/rings/fraction_field_FpT.pyx index 8351963a195..1224f2de95b 100644 --- a/src/sage/rings/fraction_field_FpT.pyx +++ b/src/sage/rings/fraction_field_FpT.pyx @@ -30,7 +30,7 @@ from sage.rings.finite_rings.integer_mod cimport mod_inverse_int class FpT(FractionField_1poly_field): r""" - This class represents the fraction field GF(p)(T) for `2 < p < \sqrt{2^31-1}`. + This class represents the fraction field `\GF{p}(T)` for `2 < p < \sqrt{2^31-1}`. EXAMPLES:: @@ -93,7 +93,7 @@ class FpT(FractionField_1poly_field): cdef class FpTElement(FieldElement): """ - An element of an FpT fraction field. + An element of an :class:`FpT` fraction field. TESTS:: @@ -563,7 +563,7 @@ cdef class FpTElement(FieldElement): cpdef FpTElement next(self): """ - This function iterates through all polynomials, returning the "next" polynomial after this one. + Iterate through all polynomials, returning the "next" polynomial after this one. The strategy is as follows: @@ -572,7 +572,7 @@ cdef class FpTElement(FieldElement): - We progress through the elements with both numerator and denominator monic, and with the denominator less than the numerator. For each such, we output all the scalar multiples of it, then all of the scalar multiples of its inverse. - - So if the leading coefficient of the numerator is less than p-1, we scale the numerator to increase it by 1. + - So if the leading coefficient of the numerator is less than `p-1`, we scale the numerator to increase it by 1. - Otherwise, we consider the multiple with numerator and denominator monic. @@ -741,7 +741,7 @@ cdef class FpTElement(FieldElement): cpdef bint is_square(self): """ - Return True if this element is the square of another element of the fraction field. + Return ``True`` if this element is the square of another element of the fraction field. EXAMPLES:: @@ -1848,11 +1848,11 @@ cdef class ZZ_FpT_coerce(RingHomomorphism): cdef inline bint normalize(nmod_poly_t numer, nmod_poly_t denom, long p): """ - Put numer/denom into a normal form: denominator monic and sharing no common factor with the numerator. + Put ``numer`` / ``denom`` into a normal form: denominator monic and sharing no common factor with the numerator. The normalized form of 0 is 0/1. - Return True if numer and denom were changed. + Return ``True`` if ``numer`` and ``denom`` were changed. """ cdef long a cdef bint changed @@ -1923,9 +1923,9 @@ cdef inline long nmod_poly_cmp(nmod_poly_t a, nmod_poly_t b): """ Compare `a` and `b`, returning 0 if they are equal. - - If the degree of `a` is less than that of `b`, returns -1. + - If the degree of `a` is less than that of `b`, returns `-1`. - - If the degree of `b` is less than that of `a`, returns 1. + - If the degree of `b` is less than that of `a`, returns `1`. - Otherwise, compares `a` and `b` lexicographically, starting at the leading terms. """ @@ -1949,7 +1949,7 @@ cdef inline long nmod_poly_cmp(nmod_poly_t a, nmod_poly_t b): cdef bint nmod_poly_sqrt_check(nmod_poly_t poly): """ - Quick check to see if poly could possibly be a square. + Quick check to see if ``poly`` could possibly be a square. """ # We could use Sage's jacobi_int which is for 32 bits integers rather # than FLINT's n_jacobi which is for longs as the FpT class is crafted @@ -1977,8 +1977,8 @@ def unpickle_FpT_element(K, numer, denom): # elsewhere at some point. cdef int sage_cmp_nmod_poly_t(nmod_poly_t L, nmod_poly_t R): """ - Compare two nmod_poly_t in a Pythonic way, so this returns -1, 0, - or 1, and is consistent. + Compare two ``nmod_poly_t`` in a Pythonic way, so this returns `-1`, `0`, + or `1`, and is consistent. """ cdef int j cdef Py_ssize_t i diff --git a/src/sage/rings/fraction_field_element.pyx b/src/sage/rings/fraction_field_element.pyx index b4d59afbf6d..ca1dedf1803 100644 --- a/src/sage/rings/fraction_field_element.pyx +++ b/src/sage/rings/fraction_field_element.pyx @@ -67,9 +67,9 @@ cdef class FractionFieldElement(FieldElement): Test if :trac:`5451` is fixed:: - sage: A = FiniteField(9,'theta')['t'] - sage: K. = FractionField(A) - sage: f= 2/(t^2+2*t); g =t^9/(t^18 + t^10 + t^2);f+g + sage: A = FiniteField(9,'theta')['t'] # optional - sage.rings.finite_rings + sage: K. = FractionField(A) # optional - sage.rings.finite_rings + sage: f = 2/(t^2 + 2*t); g = t^9/(t^18 + t^10 + t^2); f + g # optional - sage.rings.finite_rings (2*t^15 + 2*t^14 + 2*t^13 + 2*t^12 + 2*t^11 + 2*t^10 + 2*t^9 + t^7 + t^6 + t^5 + t^4 + t^3 + t^2 + t + 1)/(t^17 + t^9 + t) Test if :trac:`8671` is fixed:: @@ -102,8 +102,8 @@ cdef class FractionFieldElement(FieldElement): sage: f.numerator() 'hi' - sage: x = var('x') - sage: K((x + 1)/(x^2 + x + 1)) + sage: x = var('x') # optional - sage.symbolic + sage: K((x + 1)/(x^2 + x + 1)) # optional - sage.symbolic (x + 1)/(x^2 + x + 1) sage: K(355/113) 355/113 @@ -130,31 +130,31 @@ cdef class FractionFieldElement(FieldElement): sage: F = ZZ['x,y'].fraction_field() sage: x,y = F.gens() - sage: K = GF(7)['a,b'].fraction_field() - sage: a,b = K.gens() + sage: K = GF(7)['a,b'].fraction_field() # optional - sage.rings.finite_rings + sage: a,b = K.gens() # optional - sage.rings.finite_rings :: - sage: phi = F.hom([a+b, a*b], K) - sage: phi(x+y) # indirect doctest + sage: phi = F.hom([a + b, a*b], K) # optional - sage.rings.finite_rings + sage: phi(x+y) # indirect doctest # optional - sage.rings.finite_rings a*b + a + b :: - sage: (x^2/y)._im_gens_(K, [a+b, a*b]) + sage: (x^2/y)._im_gens_(K, [a + b, a*b]) # optional - sage.rings.finite_rings (a^2 + 2*a*b + b^2)/(a*b) - sage: (x^2/y)._im_gens_(K, [a, a*b]) + sage: (x^2/y)._im_gens_(K, [a, a*b]) # optional - sage.rings.finite_rings a/b :: sage: Zx. = ZZ[] - sage: K. = NumberField(x^2 + 1) - sage: cc = K.hom([-i]) - sage: R. = K[] - sage: F = R.fraction_field() - sage: phi = F.hom([F(b),F(a)], base_map=cc) - sage: phi(i/a) + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: cc = K.hom([-i]) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: F = R.fraction_field() # optional - sage.rings.number_field + sage: phi = F.hom([F(b), F(a)], base_map=cc) # optional - sage.rings.number_field + sage: phi(i/a) # optional - sage.rings.number_field ((-i))/b """ nnum = codomain.coerce(self.__numerator._im_gens_(codomain, im_gens, base_map=base_map)) @@ -221,7 +221,7 @@ cdef class FractionFieldElement(FieldElement): EXAMPLES:: sage: R. = ZZ[] - sage: f = x/y+1; f + sage: f = x/y + 1; f (x + y)/y sage: copy(f) (x + y)/y @@ -236,7 +236,7 @@ cdef class FractionFieldElement(FieldElement): EXAMPLES:: sage: R. = ZZ[] - sage: f = x/y+1; f + sage: f = x/y + 1; f (x + y)/y sage: f.numerator() x + y @@ -250,7 +250,7 @@ cdef class FractionFieldElement(FieldElement): EXAMPLES:: sage: R. = ZZ[] - sage: f = x/y+1; f + sage: f = x/y + 1; f (x + y)/y sage: f.denominator() y @@ -396,10 +396,10 @@ cdef class FractionFieldElement(FieldElement): Check that :trac:`25199` is fixed:: - sage: R.=QQbar[] - sage: hash(R.0)==hash(FractionField(R).0) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: hash(R.0) == hash(FractionField(R).0) # optional - sage.rings.number_field True - sage: ((x+1)/(x^2+1)).subs({x:1}) + sage: ((x+1)/(x^2+1)).subs({x: 1}) # optional - sage.rings.number_field 1 """ if self.__denominator.is_one(): @@ -438,7 +438,7 @@ cdef class FractionFieldElement(FieldElement): -2*x1*x2 + x0 + x1 sage: f(1,2,5) -17 - sage: h = f /(x[1] + x[2]) + sage: h = f / (x[1] + x[2]) sage: h (-2*x1*x2 + x0 + x1)/(x1 + x2) sage: h(1,2,5) @@ -533,7 +533,7 @@ cdef class FractionFieldElement(FieldElement): EXAMPLES:: sage: R. = ZZ[] - sage: magma((x^2 + x + 1)/(x + 1)) # optional - magma # indirect doctest + sage: magma((x^2 + x + 1)/(x + 1)) # optional - magma # indirect doctest (x^2 + x + 1)/(x + 1) :: @@ -576,8 +576,8 @@ cdef class FractionFieldElement(FieldElement): Subtraction is implemented by adding the negative:: - sage: K. = Frac(GF(7)['t']) - sage: t - 1/t # indirect doctest + sage: K. = Frac(GF(7)['t']) # optional - sage.rings.finite_rings + sage: t - 1/t # indirect doctest # optional - sage.rings.finite_rings (t^2 + 6)/t """ rnum = self.__numerator @@ -649,10 +649,10 @@ cdef class FractionFieldElement(FieldElement): EXAMPLES:: - sage: K. = Frac(GF(7)['t']) - sage: a = t/(1+t) - sage: b = 3/t - sage: a*b # indirect doctest + sage: K. = Frac(GF(7)['t']) # optional - sage.rings.finite_rings + sage: a = t/(1+t) # optional - sage.rings.finite_rings + sage: b = 3/t # optional - sage.rings.finite_rings + sage: a * b # indirect doctest # optional - sage.rings.finite_rings 3/(t + 1) """ rnum = self.__numerator @@ -778,7 +778,7 @@ cdef class FractionFieldElement(FieldElement): TESTS:: sage: K = Frac(ZZ['x']) - sage: QQ(K(x) / K(2*x)) + sage: QQ(K(x) / K(2*x)) # optional - sage.symbolic 1/2 """ return self._conversion(QQ) @@ -814,15 +814,15 @@ cdef class FractionFieldElement(FieldElement): 3/2 sage: x = polygen(QQ) - sage: A. = NumberField(x^3 - 2) - sage: A((x+3) / (2*x - 1)) + sage: A. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: A((x+3) / (2*x - 1)) # optional - sage.rings.number_field 14/15*u^2 + 7/15*u + 11/15 - sage: B = A['y'].fraction_field() - sage: A(B(u)) + sage: B = A['y'].fraction_field() # optional - sage.rings.number_field + sage: A(B(u)) # optional - sage.rings.number_field u - sage: C = A['x,y'].fraction_field() - sage: A(C(u)) + sage: C = A['x,y'].fraction_field() # optional - sage.rings.number_field + sage: A(C(u)) # optional - sage.rings.number_field u """ if self.__denominator.is_one(): @@ -900,10 +900,10 @@ cdef class FractionFieldElement(FieldElement): """ EXAMPLES:: - sage: K. = Frac(GF(5)['t']) - sage: f = (t^2+t)/(t+2); f + sage: K. = Frac(GF(5)['t']) # optional - sage.rings.finite_rings + sage: f = (t^2+t)/(t+2); f # optional - sage.rings.finite_rings (t^2 + t)/(t + 2) - sage: -f + sage: -f # optional - sage.rings.finite_rings (4*t^2 + 4*t)/(t + 2) """ return self.__class__(self._parent, @@ -924,9 +924,9 @@ cdef class FractionFieldElement(FieldElement): """ EXAMPLES:: - sage: K. = Frac(GF(7)['t']) - sage: f = (t^2+5)/(t-1) - sage: ~f + sage: K. = Frac(GF(7)['t']) # optional - sage.rings.finite_rings + sage: f = (t^2+5)/(t-1) # optional - sage.rings.finite_rings + sage: ~f # optional - sage.rings.finite_rings (t + 6)/(t^2 + 5) """ if self.is_zero(): @@ -938,12 +938,12 @@ cdef class FractionFieldElement(FieldElement): """ EXAMPLES:: - sage: K. = Frac(GF(7)['t']) - sage: t/t == 1 + sage: K. = Frac(GF(7)['t']) # optional - sage.rings.finite_rings + sage: t/t == 1 # optional - sage.rings.finite_rings True - sage: t+1/t == (t^2+1)/t + sage: t + 1/t == (t^2+1)/t # optional - sage.rings.finite_rings True - sage: t == t/5 + sage: t == t/5 # optional - sage.rings.finite_rings False :: @@ -972,7 +972,7 @@ cdef class FractionFieldElement(FieldElement): (-1/2*x^2 - 1/2)/(x^2 - 1/2*x) sage: f.valuation() -1 - sage: f.valuation(x^2+1) + sage: f.valuation(x^2 + 1) 1 """ return self.__numerator.valuation(v) - self.__denominator.valuation(v) @@ -1042,9 +1042,9 @@ cdef class FractionFieldElement(FieldElement): sage: x,y = F.gens() sage: elt = (2*x + 2*y) / (3*x - 3*y); elt (2*x + 2*y)/(3*x - 3*y) - sage: elt._symbolic_(SR) + sage: elt._symbolic_(SR) # optional - sage.symbolic 2/3*(x + y)/(x - y) - sage: symbolic_expression(elt) + sage: symbolic_expression(elt) # optional - sage.symbolic 2/3*(x + y)/(x - y) """ return ring(self.__numerator)/ring(self.__denominator) @@ -1101,18 +1101,18 @@ cdef class FractionFieldElement(FieldElement): Check that :trac:`25440` has been resolved:: - sage: R. = GF(2)[] - sage: S. = R.fraction_field()[] - sage: (y+1)(R.one()) + sage: R. = GF(2)[] # optional - sage.rings.finite_rings + sage: S. = R.fraction_field()[] # optional - sage.rings.finite_rings + sage: (y+1)(R.one()) # optional - sage.rings.finite_rings 0 Check that inexact elements are treated correctly:: - sage: K=Qp(2,5) - sage: R. = K[] - sage: L = R.fraction_field() - sage: S. = L[] - sage: y(K(1,1)/x) + sage: K = Qp(2, 5) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: L = R.fraction_field() # optional - sage.rings.padics + sage: S. = L[] # optional - sage.rings.padics + sage: y(K(1,1)/x) # optional - sage.rings.padics (1 + O(2))/((1 + O(2))*x) """ if self.numerator().is_one(): @@ -1205,8 +1205,9 @@ cdef class FractionFieldElement_1poly_field(FractionFieldElement): EXAMPLES:: sage: R. = QQ[] - sage: h = (t^14 + 2*t^12 - 4*t^11 - 8*t^9 + 6*t^8 + 12*t^6 - 4*t^5 - 8*t^3 + t^2 + 2)/(t^6 + 6*t^5 + 9*t^4 - 2*t^2 - 12*t - 18) - sage: h.support() + sage: h = (t^14 + 2*t^12 - 4*t^11 - 8*t^9 + 6*t^8 + 12*t^6 - 4*t^5 + ....: - 8*t^3 + t^2 + 2)/(t^6 + 6*t^5 + 9*t^4 - 2*t^2 - 12*t - 18) + sage: h.support() # optional - sage.libs.pari [t - 1, t + 3, t^2 + 2, t^2 + t + 1, t^4 - 2] """ L = [fac[0] for fac in self.numerator().factor()] + [fac[0] for fac in self.denominator().factor()] @@ -1249,7 +1250,7 @@ def make_element(parent, numerator, denominator): sage: R = ZZ['x,y'] sage: x,y = R.gens() sage: F = R.fraction_field() - sage: make_element(F, 1+x, 1+y) + sage: make_element(F, 1 + x, 1 + y) (x + 1)/(y + 1) """ @@ -1265,7 +1266,8 @@ def make_element_old(parent, cdict): sage: from sage.rings.fraction_field_element import make_element_old sage: R. = ZZ[] sage: F = R.fraction_field() - sage: make_element_old(F, {'_FractionFieldElement__numerator':x+y,'_FractionFieldElement__denominator':x-y}) + sage: make_element_old(F, {'_FractionFieldElement__numerator': x + y, + ....: '_FractionFieldElement__denominator': x - y}) (x + y)/(x - y) """ return FractionFieldElement(parent, diff --git a/src/sage/rings/function_field/drinfeld_modules/action.py b/src/sage/rings/function_field/drinfeld_modules/action.py index 32a00f9ea71..cfa9774058a 100644 --- a/src/sage/rings/function_field/drinfeld_modules/action.py +++ b/src/sage/rings/function_field/drinfeld_modules/action.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings r""" The module action induced by a Drinfeld module @@ -58,7 +59,8 @@ class DrinfeldModuleAction(Action): sage: phi = DrinfeldModule(A, [z, 0, 0, 1]) sage: action = phi.action() sage: action - Action on Finite Field in z of size 11^2 over its base induced by Drinfeld module defined by T |--> t^3 + z + Action on Finite Field in z of size 11^2 over its base + induced by Drinfeld module defined by T |--> t^3 + z The action on elements is computed as follows:: diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index b50193c1862..23a992f2ce1 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings r""" Drinfeld modules @@ -171,7 +172,10 @@ class DrinfeldModule(Parent, UniqueRepresentation): sage: phi(T) # phi_T, the generator of the Drinfeld module t^2 + t + z sage: phi(T^3 + T + 1) # phi_(T^3 + T + 1) - t^6 + (z^11 + z^9 + 2*z^6 + 2*z^4 + 2*z + 1)*t^4 + (2*z^11 + 2*z^10 + z^9 + z^8 + 2*z^7 + 2*z^6 + z^5 + 2*z^3)*t^3 + (2*z^11 + z^10 + z^9 + 2*z^7 + 2*z^6 + z^5 + z^4 + 2*z^3 + 2*z + 2)*t^2 + (2*z^11 + 2*z^8 + 2*z^6 + z^5 + z^4 + 2*z^2)*t + z^3 + z + 1 + t^6 + (z^11 + z^9 + 2*z^6 + 2*z^4 + 2*z + 1)*t^4 + + (2*z^11 + 2*z^10 + z^9 + z^8 + 2*z^7 + 2*z^6 + z^5 + 2*z^3)*t^3 + + (2*z^11 + z^10 + z^9 + 2*z^7 + 2*z^6 + z^5 + z^4 + 2*z^3 + 2*z + 2)*t^2 + + (2*z^11 + 2*z^8 + 2*z^6 + z^5 + z^4 + 2*z^2)*t + z^3 + z + 1 sage: phi(1) # phi_1 1 @@ -228,7 +232,8 @@ class DrinfeldModule(Parent, UniqueRepresentation): :: sage: phi.ore_polring() # K{t} - Ore Polynomial Ring in t over Finite Field in z of size 3^12 over its base twisted by Frob^2 + Ore Polynomial Ring in t over Finite Field in z of size 3^12 over its base + twisted by Frob^2 :: @@ -252,7 +257,9 @@ class DrinfeldModule(Parent, UniqueRepresentation): sage: phi.morphism() # The Drinfeld module as a morphism Ring morphism: From: Univariate Polynomial Ring in T over Finite Field in z2 of size 3^2 - To: Ore Polynomial Ring in t over Finite Field in z of size 3^12 over its base twisted by Frob^2 + To: Ore Polynomial Ring in t + over Finite Field in z of size 3^12 over its base + twisted by Frob^2 Defn: T |--> t^2 + t + z One can compute the rank and height:: @@ -353,7 +360,8 @@ class DrinfeldModule(Parent, UniqueRepresentation): sage: P = (2*z^6 + z^3 + 2*z^2 + z + 2)*t + z^11 + 2*z^10 + 2*z^9 + 2*z^8 + z^7 + 2*z^6 + z^5 + z^3 + z^2 + z sage: psi = phi.velu(P) sage: psi - Drinfeld module defined by T |--> (2*z^11 + 2*z^9 + z^6 + 2*z^5 + 2*z^4 + 2*z^2 + 1)*t^2 + (2*z^11 + 2*z^10 + 2*z^9 + z^8 + 2*z^7 + 2*z^6 + z^5 + 2*z^4 + 2*z^2 + 2*z)*t + z + Drinfeld module defined by T |--> (2*z^11 + 2*z^9 + z^6 + 2*z^5 + 2*z^4 + 2*z^2 + 1)*t^2 + + (2*z^11 + 2*z^10 + 2*z^9 + z^8 + 2*z^7 + 2*z^6 + z^5 + 2*z^4 + 2*z^2 + 2*z)*t + z sage: P in Hom(phi, psi) True sage: P * phi(T) == psi(T) * P @@ -385,7 +393,8 @@ class DrinfeldModule(Parent, UniqueRepresentation): sage: action = phi.action() sage: action - Action on Finite Field in z of size 3^12 over its base induced by Drinfeld module defined by T |--> t^2 + t + z + Action on Finite Field in z of size 3^12 over its base + induced by Drinfeld module defined by T |--> t^2 + t + z The action on elements is computed by calling the action object:: @@ -867,7 +876,9 @@ def action(self): sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5]) sage: action = phi.action() sage: action - Action on Finite Field in z12 of size 5^12 over its base induced by Drinfeld module defined by T |--> z12^5*t^2 + z12^3*t + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 + Action on Finite Field in z12 of size 5^12 over its base + induced by Drinfeld module defined by T |--> z12^5*t^2 + z12^3*t + 2*z12^11 + + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 The action on elements is computed as follows:: @@ -901,7 +912,8 @@ def coefficient(self, n): sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5]) sage: phi.coefficient(0) - 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 sage: phi.coefficient(0) == p_root True sage: phi.coefficient(1) @@ -938,7 +950,8 @@ def coefficients(self, sparse=True): sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5]) sage: phi.coefficients() - [2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12, + [2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12, z12^3, z12^5] @@ -947,10 +960,12 @@ def coefficients(self, sparse=True): sage: rho = DrinfeldModule(A, [p_root, 0, 0, 0, 1]) sage: rho.coefficients() - [2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12, + [2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12, 1] sage: rho.coefficients(sparse=False) - [2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12, + [2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12, 0, 0, 0, @@ -1120,8 +1135,10 @@ def morphism(self): sage: phi.morphism() Ring morphism: From: Univariate Polynomial Ring in T over Finite Field in z2 of size 5^2 - To: Ore Polynomial Ring in t over Finite Field in z12 of size 5^12 over its base twisted by Frob^2 - Defn: T |--> z12^5*t^2 + z12^3*t + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 + To: Ore Polynomial Ring in t over Finite Field in z12 of size 5^12 + over its base twisted by Frob^2 + Defn: T |--> z12^5*t^2 + z12^3*t + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 sage: from sage.rings.morphism import RingHomomorphism sage: isinstance(phi.morphism(), RingHomomorphism) True @@ -1144,7 +1161,8 @@ class the ``__call__`` method of this morphism:: sage: m.codomain() is phi.ore_polring() True sage: m.im_gens() - [z12^5*t^2 + z12^3*t + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12] + [z12^5*t^2 + z12^3*t + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12] sage: phi(T) == m.im_gens()[0] True """ @@ -1220,7 +1238,10 @@ def velu(self, isog): sage: isog = t + 2*z12^11 + 4*z12^9 + 2*z12^8 + 2*z12^6 + 3*z12^5 + z12^4 + 2*z12^3 + 4*z12^2 + 4*z12 + 4 sage: psi = phi.velu(isog) sage: psi - Drinfeld module defined by T |--> (z12^11 + 3*z12^10 + z12^9 + z12^7 + z12^5 + 4*z12^4 + 4*z12^3 + z12^2 + 1)*t^2 + (2*z12^11 + 4*z12^10 + 2*z12^8 + z12^6 + 3*z12^5 + z12^4 + 2*z12^3 + z12^2 + z12 + 4)*t + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 + Drinfeld module defined by T |--> + (z12^11 + 3*z12^10 + z12^9 + z12^7 + z12^5 + 4*z12^4 + 4*z12^3 + z12^2 + 1)*t^2 + + (2*z12^11 + 4*z12^10 + 2*z12^8 + z12^6 + 3*z12^5 + z12^4 + 2*z12^3 + z12^2 + z12 + 4)*t + + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 sage: isog in Hom(phi, psi) True diff --git a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py index 6cc78a53fb4..9d468dba511 100644 --- a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings r""" Finite Drinfeld modules @@ -221,7 +222,8 @@ def frobenius_charpoly(self, var='X'): sage: phi = DrinfeldModule(A, [1, 0, z6]) sage: chi = phi.frobenius_charpoly() sage: chi - X^2 + ((3*z3^2 + z3 + 4)*T + 4*z3^2 + 6*z3 + 3)*X + (5*z3^2 + 2*z3)*T^2 + (4*z3^2 + 3*z3)*T + 5*z3^2 + 2*z3 + X^2 + ((3*z3^2 + z3 + 4)*T + 4*z3^2 + 6*z3 + 3)*X + + (5*z3^2 + 2*z3)*T^2 + (4*z3^2 + 3*z3)*T + 5*z3^2 + 2*z3 :: diff --git a/src/sage/rings/function_field/drinfeld_modules/homset.py b/src/sage/rings/function_field/drinfeld_modules/homset.py index 84fdc4c6e14..c4f43db19da 100644 --- a/src/sage/rings/function_field/drinfeld_modules/homset.py +++ b/src/sage/rings/function_field/drinfeld_modules/homset.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings r""" Set of morphisms between two Drinfeld modules @@ -46,7 +47,9 @@ class DrinfeldModuleHomset(Homset): sage: psi = DrinfeldModule(A, [z6, 2*z6^5 + 2*z6^4 + 2*z6 + 1, 2]) sage: H = Hom(phi, psi) sage: H - Set of Drinfeld module morphisms from (gen) 2*t^2 + z6*t + z6 to (gen) 2*t^2 + (2*z6^5 + 2*z6^4 + 2*z6 + 1)*t + z6 + Set of Drinfeld module morphisms + from (gen) 2*t^2 + z6*t + z6 + to (gen) 2*t^2 + (2*z6^5 + 2*z6^4 + 2*z6 + 1)*t + z6 :: diff --git a/src/sage/rings/function_field/drinfeld_modules/morphism.py b/src/sage/rings/function_field/drinfeld_modules/morphism.py index dab86c43efa..2d5414095f5 100644 --- a/src/sage/rings/function_field/drinfeld_modules/morphism.py +++ b/src/sage/rings/function_field/drinfeld_modules/morphism.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings r""" Drinfeld module morphisms diff --git a/src/sage/rings/function_field/element_polymod.pyx b/src/sage/rings/function_field/element_polymod.pyx index 2c858f8568c..2d6a0100185 100644 --- a/src/sage/rings/function_field/element_polymod.pyx +++ b/src/sage/rings/function_field/element_polymod.pyx @@ -76,7 +76,7 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): def __bool__(self): """ - Return True if the element is not zero. + Return ``True`` if the element is not zero. EXAMPLES:: diff --git a/src/sage/rings/function_field/element_rational.pyx b/src/sage/rings/function_field/element_rational.pyx index 1ff227e5d27..7bbb8f809b5 100644 --- a/src/sage/rings/function_field/element_rational.pyx +++ b/src/sage/rings/function_field/element_rational.pyx @@ -106,7 +106,7 @@ cdef class FunctionFieldElement_rational(FunctionFieldElement): def __bool__(self): """ - Return True if the element is not zero. + Return ``True`` if the element is not zero. EXAMPLES:: diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index 8d203e9f019..25317e4d80c 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -93,7 +93,7 @@ # **************************************************************************** from sage.misc.latex import latex -from sage.misc.misc import powerset +from sage.combinat.subset import powerset from sage.structure.parent import Parent from sage.structure.element import Element from sage.structure.richcmp import richcmp diff --git a/src/sage/rings/homset.py b/src/sage/rings/homset.py index 6f7a2d4b415..77fa3323bc0 100644 --- a/src/sage/rings/homset.py +++ b/src/sage/rings/homset.py @@ -133,25 +133,26 @@ def _element_constructor_(self, x, check=True, base_map=None): You can provide a morphism on the base:: - sage: k = GF(9) - sage: z2 = k.gen() - sage: cc = k.frobenius_endomorphism() - sage: R. = k[] - sage: H = Hom(R, R) - sage: phi = H([x^2], base_map=cc); phi - Ring endomorphism of Univariate Polynomial Ring in x over Finite Field in z2 of size 3^2 + sage: k = GF(9) # optional - sage.rings.finite_rings + sage: z2 = k.gen() # optional - sage.rings.finite_rings + sage: cc = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: R. = k[] # optional - sage.rings.finite_rings + sage: H = Hom(R, R) # optional - sage.rings.finite_rings + sage: phi = H([x^2], base_map=cc); phi # optional - sage.rings.finite_rings + Ring endomorphism of Univariate Polynomial Ring in x + over Finite Field in z2 of size 3^2 Defn: x |--> x^2 with map of base ring - sage: phi(z2*x) == z2^3 * x^2 + sage: phi(z2 * x) == z2^3 * x^2 # optional - sage.rings.finite_rings True sage: R. = ZZ[] - sage: K. = GF(7^2) - sage: L. = K.extension(x^3 - 3) - sage: phi = L.hom([u^7], base_map=K.frobenius_endomorphism()) - sage: phi(u) == u^7 + sage: K. = GF(7^2) # optional - sage.rings.finite_rings + sage: L. = K.extension(x^3 - 3) # optional - sage.rings.finite_rings + sage: phi = L.hom([u^7], base_map=K.frobenius_endomorphism()) # optional - sage.rings.finite_rings + sage: phi(u) == u^7 # optional - sage.rings.finite_rings True - sage: phi(a) == a^7 + sage: phi(a) == a^7 # optional - sage.rings.finite_rings True TESTS:: @@ -247,14 +248,15 @@ class RingHomset_quo_ring(RingHomset_generic): EXAMPLES:: sage: R. = PolynomialRing(QQ, 2) - sage: S. = R.quotient(x^2 + y^2) - sage: phi = S.hom([b,a]); phi - Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) + sage: S. = R.quotient(x^2 + y^2) # optional - sage.libs.singular + sage: phi = S.hom([b,a]); phi # optional - sage.libs.singular + Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y + over Rational Field by the ideal (x^2 + y^2) Defn: a |--> b b |--> a - sage: phi(a) + sage: phi(a) # optional - sage.libs.singular b - sage: phi(b) + sage: phi(b) # optional - sage.libs.singular a TESTS: @@ -264,15 +266,15 @@ class RingHomset_quo_ring(RingHomset_generic): :: sage: R. = PolynomialRing(QQ, 2) - sage: S. = R.quotient(x^2 + y^2) - sage: H = S.Hom(R) - sage: H == loads(dumps(H)) + sage: S. = R.quotient(x^2 + y^2) # optional - sage.libs.singular + sage: H = S.Hom(R) # optional - sage.libs.singular + sage: H == loads(dumps(H)) # optional - sage.libs.singular True We test pickling of actual homomorphisms in a quotient:: - sage: phi = S.hom([b,a]) - sage: phi == loads(dumps(phi)) + sage: phi = S.hom([b,a]) # optional - sage.libs.singular + sage: phi == loads(dumps(phi)) # optional - sage.libs.singular True """ @@ -285,17 +287,17 @@ def _element_constructor_(self, x, base_map=None, check=True): EXAMPLES:: sage: R. = PolynomialRing(QQ, 2) - sage: S. = R.quotient(x^2 + y^2) - sage: H = S.Hom(R) - sage: phi = H([b, a]); phi + sage: S. = R.quotient(x^2 + y^2) # optional - sage.libs.singular + sage: H = S.Hom(R) # optional - sage.libs.singular + sage: phi = H([b, a]); phi # optional - sage.libs.singular Ring morphism: From: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) To: Multivariate Polynomial Ring in x, y over Rational Field Defn: a |--> b b |--> a sage: R2. = PolynomialRing(ZZ, 2) - sage: H2 = Hom(R2, S) - sage: H2(phi) + sage: H2 = Hom(R2, S) # optional - sage.libs.singular + sage: H2(phi) # optional - sage.libs.singular Composite map: From: Multivariate Polynomial Ring in x, y over Integer Ring To: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) diff --git a/src/sage/rings/ideal.py b/src/sage/rings/ideal.py index 8c51c69a9ae..bf557adc1a1 100644 --- a/src/sage/rings/ideal.py +++ b/src/sage/rings/ideal.py @@ -125,9 +125,9 @@ def Ideal(*args, **kwds): Note that some rings use different ideal implementations than the standard, even if they are PIDs.:: - sage: R. = GF(5)[] - sage: I = R*(x^2+3) - sage: type(I) + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: I = R * (x^2 + 3) # optional - sage.rings.finite_rings + sage: type(I) # optional - sage.rings.finite_rings You can also pass in a specific ideal type:: @@ -163,11 +163,11 @@ def Ideal(*args, **kwds): sage: J = R.ideal([2*x + 2*x^2]) sage: J Principal ideal (x^2 + x) of Univariate Polynomial Ring in x over Rational Field - sage: S = R.quotient_ring(I) - sage: U = R.quotient_ring(J) + sage: S = R.quotient_ring(I) # optional - sage.libs.pari + sage: U = R.quotient_ring(J) # optional - sage.libs.pari sage: I == J True - sage: S == U + sage: S == U # optional - sage.libs.pari True """ if len(args) == 0: @@ -295,8 +295,8 @@ def _repr_short(self): the generators are not represented from left to right but from top to bottom. This is the case, e.g., for matrices:: - sage: MS = MatrixSpace(QQ,2,2) - sage: MS*[MS.1,2] + sage: MS = MatrixSpace(QQ, 2, 2) # optional - sage.modules + sage: MS * [MS.1, 2] # optional - sage.modules Left Ideal ( [0 1] @@ -337,9 +337,9 @@ def random_element(self, *args, **kwds): EXAMPLES:: - sage: P. = GF(5)[[]] - sage: I = P.ideal([a^2, a*b + c, c^3]) - sage: I.random_element() # random + sage: P. = GF(5)[[]] # optional - sage.rings.finite_rings + sage: I = P.ideal([a^2, a*b + c, c^3]) # optional - sage.rings.finite_rings + sage: I.random_element() # random # optional - sage.rings.finite_rings 2*a^5*c + a^2*b*c^4 + ... + O(a, b, c)^13 """ @@ -376,11 +376,11 @@ def __contains__(self, x): EXAMPLES:: sage: P. = QQ[] - sage: I = P*[a, b] - sage: a + b in I + sage: I = P * [a, b] + sage: a + b in I # optional - sage.libs.singular True sage: P2. = QQ[] - sage: x + 2*y + w*z in I + sage: x + 2*y + w*z in I # optional - sage.libs.singular False """ try: @@ -470,11 +470,11 @@ def base_ring(self): And `p`-adic numbers:: - sage: R = Zp(7, prec=10); R + sage: R = Zp(7, prec=10); R # optional - sage.rings.padics 7-adic Ring with capped relative precision 10 - sage: I = 7*R; I + sage: I = 7*R; I # optional - sage.rings.padics Principal ideal (7 + O(7^11)) of 7-adic Ring with capped relative precision 10 - sage: I.base_ring() + sage: I.base_ring() # optional - sage.rings.padics 7-adic Ring with capped relative precision 10 """ return self.ring().base_ring() @@ -488,11 +488,14 @@ def apply_morphism(self, phi): sage: psi = CC['x'].hom([-CC['x'].0]) sage: J = ideal([CC['x'].0 + 1]); J - Principal ideal (x + 1.00000000000000) of Univariate Polynomial Ring in x over Complex Field with 53 bits of precision + Principal ideal (x + 1.00000000000000) of Univariate Polynomial Ring in x + over Complex Field with 53 bits of precision sage: psi(J) - Principal ideal (x - 1.00000000000000) of Univariate Polynomial Ring in x over Complex Field with 53 bits of precision + Principal ideal (x - 1.00000000000000) of Univariate Polynomial Ring in x + over Complex Field with 53 bits of precision sage: J.apply_morphism(psi) - Principal ideal (x - 1.00000000000000) of Univariate Polynomial Ring in x over Complex Field with 53 bits of precision + Principal ideal (x - 1.00000000000000) of Univariate Polynomial Ring in x + over Complex Field with 53 bits of precision :: @@ -585,12 +588,14 @@ def ring(self): sage: I = R.ideal(x^2 - 3) sage: I.ring() Univariate Polynomial Ring in x over Rational Field - sage: Rbar = R.quotient(I, names='a') - sage: S = PolynomialRing(Rbar, 'y'); y = Rbar.gen(); S - Univariate Polynomial Ring in y over Univariate Quotient Polynomial Ring in a over Rational Field with modulus x^2 - 3 - sage: J = S.ideal(y^2 + 1) - sage: J.ring() - Univariate Polynomial Ring in y over Univariate Quotient Polynomial Ring in a over Rational Field with modulus x^2 - 3 + sage: Rbar = R.quotient(I, names='a') # optional - sage.libs.pari + sage: S = PolynomialRing(Rbar, 'y'); y = Rbar.gen(); S # optional - sage.libs.pari + Univariate Polynomial Ring in y over + Univariate Quotient Polynomial Ring in a over Rational Field with modulus x^2 - 3 + sage: J = S.ideal(y^2 + 1) # optional - sage.libs.pari + sage: J.ring() # optional - sage.libs.pari + Univariate Polynomial Ring in y over + Univariate Quotient Polynomial Ring in a over Rational Field with modulus x^2 - 3 """ return self.__ring @@ -693,16 +698,16 @@ def is_maximal(self): sage: R = ZZ sage: I = R.ideal(7) - sage: I.is_maximal() + sage: I.is_maximal() # optional - sage.libs.pari True - sage: R.ideal(16).is_maximal() + sage: R.ideal(16).is_maximal() # optional - sage.libs.pari False sage: S = Integers(8) - sage: S.ideal(0).is_maximal() + sage: S.ideal(0).is_maximal() # optional - sage.libs.pari False - sage: S.ideal(2).is_maximal() + sage: S.ideal(2).is_maximal() # optional - sage.libs.pari True - sage: S.ideal(4).is_maximal() + sage: S.ideal(4).is_maximal() # optional - sage.libs.pari False """ from sage.rings.integer_ring import ZZ @@ -738,28 +743,28 @@ def is_primary(self, P=None): sage: R. = QQ[] sage: I = R.ideal([x^2, x*y]) - sage: I.is_primary() + sage: I.is_primary() # optional - sage.libs.singular False - sage: J = I.primary_decomposition()[1]; J + sage: J = I.primary_decomposition()[1]; J # optional - sage.libs.singular Ideal (y, x^2) of Multivariate Polynomial Ring in x, y over Rational Field - sage: J.is_primary() + sage: J.is_primary() # optional - sage.libs.singular True - sage: J.is_prime() + sage: J.is_prime() # optional - sage.libs.singular False Some examples from the Macaulay2 documentation:: - sage: R. = GF(101)[] - sage: I = R.ideal([y^6]) - sage: I.is_primary() + sage: R. = GF(101)[] # optional - sage.rings.finite_rings + sage: I = R.ideal([y^6]) # optional - sage.rings.finite_rings + sage: I.is_primary() # optional - sage.libs.singular sage.rings.finite_rings True - sage: I.is_primary(R.ideal([y])) + sage: I.is_primary(R.ideal([y])) # optional - sage.libs.singular sage.rings.finite_rings True - sage: I = R.ideal([x^4, y^7]) - sage: I.is_primary() + sage: I = R.ideal([x^4, y^7]) # optional - sage.libs.singular sage.rings.finite_rings + sage: I.is_primary() # optional - sage.libs.singular sage.rings.finite_rings True - sage: I = R.ideal([x*y, y^2]) - sage: I.is_primary() + sage: I = R.ideal([x*y, y^2]) # optional - sage.libs.singular sage.rings.finite_rings + sage: I.is_primary() # optional - sage.libs.singular sage.rings.finite_rings False .. NOTE:: @@ -798,24 +803,24 @@ def is_prime(self): sage: R. = QQ[] sage: I = R.ideal([x, y]) - sage: I.is_prime() # a maximal ideal + sage: I.is_prime() # a maximal ideal # optional - sage.libs.singular True - sage: I = R.ideal([x^2-y]) - sage: I.is_prime() # a non-maximal prime ideal + sage: I = R.ideal([x^2 - y]) + sage: I.is_prime() # a non-maximal prime ideal # optional - sage.libs.singular True sage: I = R.ideal([x^2, y]) - sage: I.is_prime() # a non-prime primary ideal + sage: I.is_prime() # a non-prime primary ideal # optional - sage.libs.singular False sage: I = R.ideal([x^2, x*y]) - sage: I.is_prime() # a non-prime non-primary ideal + sage: I.is_prime() # a non-prime non-primary ideal # optional - sage.libs.singular False sage: S = Integers(8) - sage: S.ideal(0).is_prime() + sage: S.ideal(0).is_prime() # optional - sage.libs.singular False - sage: S.ideal(2).is_prime() + sage: S.ideal(2).is_prime() # optional - sage.libs.singular True - sage: S.ideal(4).is_prime() + sage: S.ideal(4).is_prime() # optional - sage.libs.singular False Note that this method is not implemented for all rings where it @@ -886,7 +891,7 @@ def embedded_primes(self): sage: R. = QQ[] sage: I = R.ideal(x^2, x*y) - sage: I.embedded_primes() + sage: I.embedded_primes() # optional - sage.libs.singular [Ideal (y, x) of Multivariate Polynomial Ring in x, y over Rational Field] """ # by definition, embedded primes are associated primes that @@ -915,13 +920,13 @@ def is_principal(self): EXAMPLES:: - sage: R = ZZ['x'] - sage: I = R.ideal(2,x) + sage: R. = ZZ[] + sage: I = R.ideal(2, x) sage: I.is_principal() Traceback (most recent call last): ... NotImplementedError - sage: J = R.base_extend(QQ).ideal(2,x) + sage: J = R.base_extend(QQ).ideal(2, x) sage: J.is_principal() True """ @@ -954,7 +959,7 @@ def is_trivial(self): :: sage: I = QQ['x', 'y'].ideal(-5) - sage: I.is_trivial() + sage: I.is_trivial() # optional - sage.libs.singular True :: @@ -967,7 +972,7 @@ def is_trivial(self): sage: R = QQ['x', 'y'] sage: I = R.ideal(R.gens()) - sage: I.is_trivial() + sage: I.is_trivial() # optional - sage.libs.singular False """ return self.is_zero() or self == self.ring().unit_ideal() @@ -1112,10 +1117,11 @@ def norm(self): EXAMPLES:: - sage: R. = GF(8, names='a')[] - sage: I = R.ideal(t^4 + t + 1) - sage: I.norm() - Principal ideal (t^4 + t + 1) of Univariate Polynomial Ring in t over Finite Field in a of size 2^3 + sage: R. = GF(8, names='a')[] # optional - sage.rings.finite_rings + sage: I = R.ideal(t^4 + t + 1) # optional - sage.rings.finite_rings + sage: I.norm() # optional - sage.rings.finite_rings + Principal ideal (t^4 + t + 1) of Univariate Polynomial Ring in t + over Finite Field in a of size 2^3 """ return self @@ -1135,9 +1141,9 @@ def absolute_norm(self): EXAMPLES:: - sage: R. = GF(9, names='a')[] - sage: I = R.ideal(t^4 + t + 1) - sage: I.absolute_norm() + sage: R. = GF(9, names='a')[] # optional - sage.rings.finite_rings + sage: I = R.ideal(t^4 + t + 1) # optional - sage.rings.finite_rings + sage: I.absolute_norm() # optional - sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError @@ -1155,7 +1161,7 @@ def _macaulay2_init_(self, macaulay2=None): sage: R. = PolynomialRing(ZZ, 4) sage: I = R.ideal([x*y-z^2, y^2-w^2]); I Ideal (x*y - z^2, y^2 - w^2) of Multivariate Polynomial Ring in x, y, z, w over Integer Ring - sage: macaulay2(I) # optional - macaulay2 + sage: macaulay2(I) # optional - macaulay2 2 2 2 ideal (x*y - z , y - w ) @@ -1164,28 +1170,28 @@ def _macaulay2_init_(self, macaulay2=None): sage: R. = PolynomialRing(ZZ) sage: I = R.ideal([4 + 3*x + x^2, 1 + x^2]); I Ideal (x^2 + 3*x + 4, x^2 + 1) of Univariate Polynomial Ring in x over Integer Ring - sage: macaulay2(I) # optional - macaulay2 + sage: macaulay2(I) # optional - macaulay2 2 2 ideal (x + 3x + 4, x + 1) Field ideals generated from the polynomial ring over two variables in the finite field of size 2:: - sage: P. = PolynomialRing(GF(2), 2) - sage: I = sage.rings.ideal.FieldIdeal(P); I - Ideal (x^2 + x, y^2 + y) of Multivariate Polynomial Ring in x, y over - Finite Field of size 2 - sage: macaulay2(I) # optional - macaulay2 + sage: P. = PolynomialRing(GF(2), 2) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.FieldIdeal(P); I # optional - sage.rings.finite_rings + Ideal (x^2 + x, y^2 + y) of Multivariate Polynomial Ring in x, y + over Finite Field of size 2 + sage: macaulay2(I) # optional - macaulay2 # optional - sage.rings.finite_rings 2 2 ideal (x + x, y + y) Ideals in PIDs:: - sage: macaulay2(ideal(5)) # optional - macaulay2 + sage: macaulay2(ideal(5)) # optional - macaulay2 ideal 5 sage: J = ideal(QQ(5)) ... - sage: macaulay2(J) # optional - macaulay2 + sage: macaulay2(J) # optional - macaulay2 ideal 1 TESTS: @@ -1222,7 +1228,7 @@ def free_resolution(self, *args, **kwds): sage: R. = PolynomialRing(QQ) sage: I = R.ideal([x^4 + 3*x^2 + 2]) - sage: I.free_resolution() + sage: I.free_resolution() # optional - sage.modules S^1 <-- S^1 <-- 0 """ if not self.is_principal(): @@ -1241,7 +1247,7 @@ def graded_free_resolution(self, *args, **kwds): sage: R. = PolynomialRing(QQ) sage: I = R.ideal([x^3]) - sage: I.graded_free_resolution() + sage: I.graded_free_resolution() # optional - sage.modules S(0) <-- S(-3) <-- 0 """ from sage.homology.graded_resolution import GradedFiniteFreeResolution_free_module @@ -1568,18 +1574,18 @@ def is_prime(self): EXAMPLES:: - sage: ZZ.ideal(2).is_prime() + sage: ZZ.ideal(2).is_prime() # optional - sage.libs.pari True - sage: ZZ.ideal(-2).is_prime() + sage: ZZ.ideal(-2).is_prime() # optional - sage.libs.pari True - sage: ZZ.ideal(4).is_prime() + sage: ZZ.ideal(4).is_prime() # optional - sage.libs.pari False - sage: ZZ.ideal(0).is_prime() + sage: ZZ.ideal(0).is_prime() # optional - sage.libs.pari True sage: R. = QQ[] - sage: P = R.ideal(x^2+1); P + sage: P = R.ideal(x^2 + 1); P # optional - sage.libs.pari Principal ideal (x^2 + 1) of Univariate Polynomial Ring in x over Rational Field - sage: P.is_prime() + sage: P.is_prime() # optional - sage.libs.pari True In fields, only the zero ideal is prime:: @@ -1609,18 +1615,18 @@ def is_maximal(self): EXAMPLES:: - sage: R. = GF(5)[] - sage: p = R.ideal(t^2 + 2) - sage: p.is_maximal() + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: p = R.ideal(t^2 + 2) # optional - sage.rings.finite_rings + sage: p.is_maximal() # optional - sage.rings.finite_rings True - sage: p = R.ideal(t^2 + 1) - sage: p.is_maximal() + sage: p = R.ideal(t^2 + 1) # optional - sage.rings.finite_rings + sage: p.is_maximal() # optional - sage.rings.finite_rings False - sage: p = R.ideal(0) - sage: p.is_maximal() + sage: p = R.ideal(0) # optional - sage.rings.finite_rings + sage: p.is_maximal() # optional - sage.rings.finite_rings False - sage: p = R.ideal(1) - sage: p.is_maximal() + sage: p = R.ideal(1) # optional - sage.rings.finite_rings + sage: p.is_maximal() # optional - sage.rings.finite_rings False """ if not self.ring().is_field() and self.is_zero(): @@ -1640,41 +1646,41 @@ def residue_field(self): sage: P = ZZ.ideal(61); P Principal ideal (61) of Integer Ring - sage: F = P.residue_field(); F + sage: F = P.residue_field(); F # optional - sage.libs.pari Residue field of Integers modulo 61 - sage: pi = F.reduction_map(); pi + sage: pi = F.reduction_map(); pi # optional - sage.libs.pari Partially defined reduction map: From: Rational Field To: Residue field of Integers modulo 61 - sage: pi(123/234) + sage: pi(123/234) # optional - sage.libs.pari 6 - sage: pi(1/61) + sage: pi(1/61) # optional - sage.libs.pari Traceback (most recent call last): ... ZeroDivisionError: Cannot reduce rational 1/61 modulo 61: it has negative valuation - sage: lift = F.lift_map(); lift + sage: lift = F.lift_map(); lift # optional - sage.libs.pari Lifting map: From: Residue field of Integers modulo 61 To: Integer Ring - sage: lift(F(12345/67890)) + sage: lift(F(12345/67890)) # optional - sage.libs.pari 33 sage: (12345/67890) % 61 33 TESTS:: - sage: ZZ.ideal(96).residue_field() + sage: ZZ.ideal(96).residue_field() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: The ideal (Principal ideal (96) of Integer Ring) is not prime :: - sage: R.=QQ[] - sage: I=R.ideal(x^2+1) - sage: I.is_prime() + sage: R. = QQ[] + sage: I = R.ideal(x^2 + 1) + sage: I.is_prime() # optional - sage.libs.pari True - sage: I.residue_field() + sage: I.residue_field() # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: residue fields only supported for polynomial rings over finite fields. @@ -1699,8 +1705,8 @@ def __repr__(self): EXAMPLES:: sage: from sage.rings.ideal import Ideal_fractional - sage: K. = NumberField(x^2 + 1) - sage: Ideal_fractional(K, [a]) # indirect doctest + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: Ideal_fractional(K, [a]) # indirect doctest # optional - sage.rings.number_field Fractional ideal (a) of Number Field in a with defining polynomial x^2 + 1 """ return "Fractional ideal %s of %s"%(self._repr_short(), self.ring()) @@ -1735,21 +1741,20 @@ def Cyclic(R, n=None, homog=False, singular=None): An example from a multivariate polynomial ring over the rationals:: - sage: P. = PolynomialRing(QQ,3,order='lex') - sage: I = sage.rings.ideal.Cyclic(P) - sage: I - Ideal (x + y + z, x*y + x*z + y*z, x*y*z - 1) of Multivariate Polynomial - Ring in x, y, z over Rational Field - sage: I.groebner_basis() + sage: P. = PolynomialRing(QQ, 3, order='lex') + sage: I = sage.rings.ideal.Cyclic(P); I # optional - sage.libs.singular + Ideal (x + y + z, x*y + x*z + y*z, x*y*z - 1) + of Multivariate Polynomial Ring in x, y, z over Rational Field + sage: I.groebner_basis() # optional - sage.libs.singular [x + y + z, y^2 + y*z + z^2, z^3 - 1] We compute a Groebner basis for cyclic 6, which is a standard benchmark and test ideal:: sage: R. = QQ['x,y,z,t,u,v'] - sage: I = sage.rings.ideal.Cyclic(R,6) - sage: B = I.groebner_basis() - sage: len(B) + sage: I = sage.rings.ideal.Cyclic(R, 6) # optional - sage.libs.singular + sage: B = I.groebner_basis() # optional - sage.libs.singular + sage: len(B) # optional - sage.libs.singular 45 """ from .rational_field import RationalField @@ -1794,15 +1799,15 @@ def Katsura(R, n=None, homog=False, singular=None): EXAMPLES:: - sage: P. = PolynomialRing(QQ,3) - sage: I = sage.rings.ideal.Katsura(P,3); I + sage: P. = PolynomialRing(QQ, 3) + sage: I = sage.rings.ideal.Katsura(P, 3); I # optional - sage.libs.singular Ideal (x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y + 2*y*z - y) of Multivariate Polynomial Ring in x, y, z over Rational Field :: - sage: Q. = PolynomialRing(QQ, implementation="singular") - sage: J = sage.rings.ideal.Katsura(Q,1); J + sage: Q. = PolynomialRing(QQ, implementation="singular") # optional - sage.libs.singular + sage: J = sage.rings.ideal.Katsura(Q,1); J # optional - sage.libs.singular Ideal (x - 1) of Multivariate Polynomial Ring in x over Rational Field """ from .rational_field import RationalField @@ -1842,18 +1847,18 @@ def FieldIdeal(R): The field ideal generated from the polynomial ring over two variables in the finite field of size 2:: - sage: P. = PolynomialRing(GF(2),2) - sage: I = sage.rings.ideal.FieldIdeal(P); I - Ideal (x^2 + x, y^2 + y) of Multivariate Polynomial Ring in x, y over - Finite Field of size 2 + sage: P. = PolynomialRing(GF(2), 2) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.FieldIdeal(P); I # optional - sage.rings.finite_rings + Ideal (x^2 + x, y^2 + y) of + Multivariate Polynomial Ring in x, y over Finite Field of size 2 Another, similar example:: - sage: Q. = PolynomialRing(GF(2^4,name='alpha'), 4) - sage: J = sage.rings.ideal.FieldIdeal(Q); J + sage: Q. = PolynomialRing(GF(2^4, name='alpha'), 4) # optional - sage.rings.finite_rings + sage: J = sage.rings.ideal.FieldIdeal(Q); J # optional - sage.rings.finite_rings Ideal (x1^16 + x1, x2^16 + x2, x3^16 + x3, x4^16 + x4) of - Multivariate Polynomial Ring in x1, x2, x3, x4 over Finite - Field in alpha of size 2^4 + Multivariate Polynomial Ring in x1, x2, x3, x4 + over Finite Field in alpha of size 2^4 """ q = R.base_ring().order() import sage.rings.infinity diff --git a/src/sage/rings/ideal_monoid.py b/src/sage/rings/ideal_monoid.py index b22b7208f6f..01193661aae 100644 --- a/src/sage/rings/ideal_monoid.py +++ b/src/sage/rings/ideal_monoid.py @@ -3,8 +3,8 @@ WARNING: This is used by some rings that are not commutative! :: - sage: MS = MatrixSpace(QQ,3,3) - sage: type(MS.ideal(MS.one()).parent()) + sage: MS = MatrixSpace(QQ, 3, 3) # optional - sage.modules + sage: type(MS.ideal(MS.one()).parent()) # optional - sage.modules """ @@ -21,7 +21,8 @@ def IdealMonoid(R): EXAMPLES:: sage: R = QQ['x'] - sage: sage.rings.ideal_monoid.IdealMonoid(R) + sage: from sage.rings.ideal_monoid import IdealMonoid + sage: IdealMonoid(R) Monoid of ideals of Univariate Polynomial Ring in x over Rational Field """ return IdealMonoid_c(R) @@ -34,7 +35,8 @@ class IdealMonoid_c(Parent): TESTS:: sage: R = QQ['x'] - sage: M = sage.rings.ideal_monoid.IdealMonoid(R) + sage: from sage.rings.ideal_monoid import IdealMonoid + sage: M = IdealMonoid(R) sage: TestSuite(M).run() Failure in _test_category: ... @@ -51,16 +53,18 @@ def __init__(self, R): TESTS:: - sage: R = QuadraticField(-23, 'a') - sage: M = sage.rings.ideal_monoid.IdealMonoid(R); M # indirect doctest - Monoid of ideals of Number Field in a with defining polynomial x^2 + 23 with a = 4.795831523312720?*I + sage: R = QuadraticField(-23, 'a') # optional - sage.rings.number_field + sage: from sage.rings.ideal_monoid import IdealMonoid + sage: M = IdealMonoid(R); M # indirect doctest # optional - sage.rings.number_field + Monoid of ideals of Number Field in a with defining polynomial x^2 + 23 + with a = 4.795831523312720?*I sage: id = QQ.ideal(6) sage: id.parent().category() Category of commutative monoids - sage: MS = MatrixSpace(QQ,3,3) - sage: MS.ideal(MS.one()).parent().category() + sage: MS = MatrixSpace(QQ, 3, 3) # optional - sage.modules + sage: MS.ideal(MS.one()).parent().category() # optional - sage.modules Category of monoids """ self.__R = R @@ -77,9 +81,11 @@ def _repr_(self): TESTS:: - sage: R = QuadraticField(-23, 'a') - sage: M = sage.rings.ideal_monoid.IdealMonoid(R); M._repr_() - 'Monoid of ideals of Number Field in a with defining polynomial x^2 + 23 with a = 4.795831523312720?*I' + sage: R = QuadraticField(-23, 'a') # optional - sage.rings.number_field + sage: from sage.rings.ideal_monoid import IdealMonoid + sage: M = IdealMonoid(R); M._repr_() # optional - sage.rings.number_field + 'Monoid of ideals of Number Field in a with defining polynomial x^2 + 23 + with a = 4.795831523312720?*I' """ return "Monoid of ideals of %s" % self.__R @@ -89,8 +95,9 @@ def ring(self): EXAMPLES:: - sage: R = QuadraticField(-23, 'a') - sage: M = sage.rings.ideal_monoid.IdealMonoid(R); M.ring() is R + sage: R = QuadraticField(-23, 'a') # optional - sage.rings.number_field + sage: from sage.rings.ideal_monoid import IdealMonoid + sage: M = IdealMonoid(R); M.ring() is R # optional - sage.rings.number_field True """ return self.__R @@ -101,11 +108,12 @@ def _element_constructor_(self, x): EXAMPLES:: - sage: R. = QuadraticField(-23) - sage: M = sage.rings.ideal_monoid.IdealMonoid(R) - sage: M(a) # indirect doctest + sage: R. = QuadraticField(-23) # optional - sage.rings.number_field + sage: from sage.rings.ideal_monoid import IdealMonoid + sage: M = IdealMonoid(R) # optional - sage.rings.number_field + sage: M(a) # indirect doctest # optional - sage.rings.number_field Fractional ideal (a) - sage: M([a-4, 13]) + sage: M([a-4, 13]) # optional - sage.rings.number_field Fractional ideal (13, 1/2*a + 9/2) """ try: @@ -129,15 +137,15 @@ def _coerce_map_from_(self, x): EXAMPLES:: - sage: R = QuadraticField(-23, 'a') - sage: M = R.ideal_monoid() - sage: M.has_coerce_map_from(R) # indirect doctest + sage: R = QuadraticField(-23, 'a') # optional - sage.rings.number_field + sage: M = R.ideal_monoid() # optional - sage.rings.number_field + sage: M.has_coerce_map_from(R) # indirect doctest # optional - sage.rings.number_field True - sage: M.has_coerce_map_from(QQ.ideal_monoid()) + sage: M.has_coerce_map_from(QQ.ideal_monoid()) # optional - sage.rings.number_field True - sage: M.has_coerce_map_from(Zmod(6)) + sage: M.has_coerce_map_from(Zmod(6)) # optional - sage.rings.number_field False - sage: M.has_coerce_map_from(loads(dumps(M))) + sage: M.has_coerce_map_from(loads(dumps(M))) # optional - sage.rings.number_field True """ if isinstance(x, IdealMonoid_c): @@ -151,13 +159,13 @@ def __eq__(self, other): EXAMPLES:: - sage: R = QuadraticField(-23, 'a') - sage: M = R.ideal_monoid() - sage: M == QQ + sage: R = QuadraticField(-23, 'a') # optional - sage.rings.number_field + sage: M = R.ideal_monoid() # optional - sage.rings.number_field + sage: M == QQ # optional - sage.rings.number_field False - sage: M == 17 + sage: M == 17 # optional - sage.rings.number_field False - sage: M == R.ideal_monoid() + sage: M == R.ideal_monoid() # optional - sage.rings.number_field True """ if not isinstance(other, IdealMonoid_c): @@ -171,13 +179,13 @@ def __ne__(self, other): EXAMPLES:: - sage: R = QuadraticField(-23, 'a') - sage: M = R.ideal_monoid() - sage: M != QQ + sage: R = QuadraticField(-23, 'a') # optional - sage.rings.number_field + sage: M = R.ideal_monoid() # optional - sage.rings.number_field + sage: M != QQ # optional - sage.rings.number_field True - sage: M != 17 + sage: M != 17 # optional - sage.rings.number_field True - sage: M != R.ideal_monoid() + sage: M != R.ideal_monoid() # optional - sage.rings.number_field False """ return not (self == other) @@ -188,13 +196,13 @@ def __hash__(self): EXAMPLES:: - sage: R = QuadraticField(-23, 'a') - sage: M = R.ideal_monoid() - sage: hash(M) == hash(QQ) + sage: R = QuadraticField(-23, 'a') # optional - sage.rings.number_field + sage: M = R.ideal_monoid() # optional - sage.rings.number_field + sage: hash(M) == hash(QQ) # optional - sage.rings.number_field False - sage: hash(M) == 17 + sage: hash(M) == 17 # optional - sage.rings.number_field False - sage: hash(M) == hash(R.ideal_monoid()) + sage: hash(M) == hash(R.ideal_monoid()) # optional - sage.rings.number_field True """ # uses a random number, to have a distinct hash diff --git a/src/sage/rings/infinity.py b/src/sage/rings/infinity.py index c1ac3aee408..d4cbe9372bb 100644 --- a/src/sage/rings/infinity.py +++ b/src/sage/rings/infinity.py @@ -203,8 +203,8 @@ We check that :trac:`17990` is fixed:: - sage: m = Matrix([Infinity]) - sage: m.rows() + sage: m = Matrix([Infinity]) # optional - sage.modules + sage: m.rows() # optional - sage.modules [(+Infinity)] """ #***************************************************************************** @@ -290,7 +290,7 @@ def _maxima_init_(self): """ TESTS:: - sage: maxima(-oo) + sage: maxima(-oo) # optional - sage.symbolic minf sage: [x._maxima_init_() for x in [unsigned_infinity, oo, -oo]] ['inf', 'inf', 'minf'] @@ -324,9 +324,9 @@ def __pari__(self): EXAMPLES:: - sage: pari(-oo) + sage: pari(-oo) # optional - sage.libs.pari -oo - sage: pari(oo) + sage: pari(oo) # optional - sage.libs.pari +oo """ from sage.libs.pari.all import pari @@ -472,7 +472,7 @@ def _div_(self, other): Traceback (most recent call last): ... ValueError: unsigned oo times smaller number not defined - sage: SR(infinity) / unsigned_infinity + sage: SR(infinity) / unsigned_infinity # optional - sage.symbolic Traceback (most recent call last): ... RuntimeError: indeterminate expression: 0 * infinity encountered. @@ -568,8 +568,8 @@ def __init__(self): Sage can understand SymPy's complex infinity (:trac:`17493`):: - sage: import sympy - sage: SR(sympy.zoo) + sage: import sympy # optional - sympy + sage: SR(sympy.zoo) # optional - sympy Infinity Some equality checks:: @@ -676,7 +676,7 @@ def _element_constructor_(self, x): sage: UnsignedInfinityRing(2) # indirect doctest A number less than infinity - sage: UnsignedInfinityRing(I) + sage: UnsignedInfinityRing(I) # optional - sage.rings.number_field A number less than infinity sage: UnsignedInfinityRing(unsigned_infinity) Infinity @@ -684,10 +684,10 @@ def _element_constructor_(self, x): Infinity sage: UnsignedInfinityRing(-oo) Infinity - sage: K. = QuadraticField(3) - sage: UnsignedInfinityRing(a) + sage: K. = QuadraticField(3) # optional - sage.rings.number_field + sage: UnsignedInfinityRing(a) # optional - sage.rings.number_field A number less than infinity - sage: UnsignedInfinityRing(a - 2) + sage: UnsignedInfinityRing(a - 2) # optional - sage.rings.number_field A number less than infinity sage: UnsignedInfinityRing(RDF(oo)), UnsignedInfinityRing(RDF(-oo)) (Infinity, Infinity) @@ -701,14 +701,14 @@ def _element_constructor_(self, x): (Infinity, Infinity) sage: UnsignedInfinityRing(float('+inf')), UnsignedInfinityRing(float('-inf')) (Infinity, Infinity) - sage: UnsignedInfinityRing(SR(oo)), UnsignedInfinityRing(SR(-oo)) + sage: UnsignedInfinityRing(SR(oo)), UnsignedInfinityRing(SR(-oo)) # optional - sage.symbolic (Infinity, Infinity) The following rings have a ``is_infinity`` method:: sage: RR(oo).is_infinity() True - sage: SR(oo).is_infinity() + sage: SR(oo).is_infinity() # optional - sage.symbolic True """ # Lazy elements can wrap infinity or not, unwrap first @@ -748,11 +748,11 @@ def _coerce_map_from_(self, R): True sage: UnsignedInfinityRing.has_coerce_map_from(CC) True - sage: UnsignedInfinityRing.has_coerce_map_from(QuadraticField(-163, 'a')) + sage: UnsignedInfinityRing.has_coerce_map_from(QuadraticField(-163, 'a')) # optional - sage.rings.number_field True - sage: UnsignedInfinityRing.has_coerce_map_from(QQ^3) + sage: UnsignedInfinityRing.has_coerce_map_from(QQ^3) # optional - sage.modules False - sage: UnsignedInfinityRing.has_coerce_map_from(SymmetricGroup(13)) + sage: UnsignedInfinityRing.has_coerce_map_from(SymmetricGroup(13)) # optional - sage.groups False """ return isinstance(R, Ring) or R in (int, float, complex) @@ -942,12 +942,12 @@ def _sympy_(self): EXAMPLES:: - sage: import sympy - sage: SR(unsigned_infinity)._sympy_() + sage: import sympy # optional - sympy + sage: SR(unsigned_infinity)._sympy_() # optional - sympy zoo - sage: gamma(-3)._sympy_() is sympy.factorial(-2) + sage: gamma(-3)._sympy_() is sympy.factorial(-2) # optional - sympy True - sage: gamma(-3) is sympy.factorial(-2)._sage_() + sage: gamma(-3) is sympy.factorial(-2)._sage_() # optional - sympy True """ import sympy @@ -1128,11 +1128,12 @@ def _element_constructor_(self, x): sage: InfinityRing(-1.5) A negative finite number sage: [InfinityRing(a) for a in [-2..2]] - [A negative finite number, A negative finite number, Zero, A positive finite number, A positive finite number] - sage: K. = QuadraticField(3) - sage: InfinityRing(a) + [A negative finite number, A negative finite number, Zero, + A positive finite number, A positive finite number] + sage: K. = QuadraticField(3) # optional - sage.rings.number_field + sage: InfinityRing(a) # optional - sage.rings.number_field A positive finite number - sage: InfinityRing(a - 2) + sage: InfinityRing(a - 2) # optional - sage.rings.number_field A negative finite number sage: InfinityRing(RDF(oo)), InfinityRing(RDF(-oo)) (+Infinity, -Infinity) @@ -1142,7 +1143,7 @@ def _element_constructor_(self, x): (+Infinity, -Infinity) sage: InfinityRing(float('+inf')), InfinityRing(float('-inf')) (+Infinity, -Infinity) - sage: InfinityRing(SR(oo)), InfinityRing(SR(-oo)) + sage: InfinityRing(SR(oo)), InfinityRing(SR(-oo)) # optional - sage.symbolic (+Infinity, -Infinity) The following rings have ``is_positive_infinity`` / @@ -1150,7 +1151,7 @@ def _element_constructor_(self, x): sage: RR(oo).is_positive_infinity(), RR(-oo).is_negative_infinity() (True, True) - sage: SR(oo).is_positive_infinity(), SR(-oo).is_negative_infinity() + sage: SR(oo).is_positive_infinity(), SR(-oo).is_negative_infinity() # optional - sage.symbolic (True, True) Complex infinity raises an exception. This is fine (there is @@ -1226,7 +1227,7 @@ def _coerce_map_from_(self, R): sage: InfinityRing.has_coerce_map_from(int) # indirect doctest True - sage: InfinityRing.has_coerce_map_from(AA) + sage: InfinityRing.has_coerce_map_from(AA) # optional - sage.rings.number_field True sage: InfinityRing.has_coerce_map_from(RDF) True @@ -1237,7 +1238,7 @@ def _coerce_map_from_(self, R): infinity ring:: sage: cm = get_coercion_model() - sage: cm.explain(AA(3), oo, operator.lt) + sage: cm.explain(AA(3), oo, operator.lt) # optional - sage.rings.number_field Coercion on left operand via Coercion map: From: Algebraic Real Field @@ -1250,9 +1251,9 @@ def _coerce_map_from_(self, R): symbolic comparisons with infinities all happen in the symbolic ring:: - sage: SR.has_coerce_map_from(InfinityRing) + sage: SR.has_coerce_map_from(InfinityRing) # optional - sage.symbolic True - sage: InfinityRing.has_coerce_map_from(SR) + sage: InfinityRing.has_coerce_map_from(SR) # optional - sage.symbolic False Complex numbers do not coerce into the infinity ring (what @@ -1278,7 +1279,7 @@ def _pushout_(self, other): r""" EXAMPLES:: - sage: QQbar(-2*i)*infinity + sage: QQbar(-2*i)*infinity # optional - sage.rings.number_field sage.symbolic (-I)*Infinity """ from sage.symbolic.ring import SR @@ -1479,9 +1480,9 @@ def _latex_(self): TESTS:: - sage: a = InfinityRing(pi); a + sage: a = InfinityRing(pi); a # optional - sage.symbolic A positive finite number - sage: a._latex_() + sage: a._latex_() # optional - sage.symbolic 'A positive finite number' sage: [latex(InfinityRing(a)) for a in [-2..2]] [A negative finite number, A negative finite number, Zero, A positive finite number, A positive finite number] @@ -1622,12 +1623,12 @@ def _sympy_(self): EXAMPLES:: - sage: import sympy - sage: bool(-oo == -sympy.oo) + sage: import sympy # optional - sympy + sage: bool(-oo == -sympy.oo) # optional - sympy True - sage: bool(SR(-oo) == -sympy.oo) + sage: bool(SR(-oo) == -sympy.oo) # optional - sympy True - sage: bool((-oo)._sympy_() == -sympy.oo) + sage: bool((-oo)._sympy_() == -sympy.oo) # optional - sympy True """ @@ -1640,9 +1641,9 @@ def _gap_init_(self): EXAMPLES:: - sage: gap(-Infinity) + sage: gap(-Infinity) # optional - sage.libs.gap -infinity - sage: libgap(-Infinity) + sage: libgap(-Infinity) # optional - sage.libs.gap -infinity """ return '-infinity' @@ -1723,10 +1724,10 @@ def _sympy_(self): EXAMPLES:: - sage: import sympy - sage: bool(oo == sympy.oo) # indirect doctest + sage: import sympy # optional - sympy + sage: bool(oo == sympy.oo) # indirect doctest # optional - sympy True - sage: bool(SR(oo) == sympy.oo) + sage: bool(SR(oo) == sympy.oo) # optional - sage.symbolic sympy True """ import sympy @@ -1738,9 +1739,9 @@ def _gap_init_(self): EXAMPLES:: - sage: gap(+Infinity) + sage: gap(+Infinity) # optional - sage.libs.gap infinity - sage: libgap(+Infinity) + sage: libgap(+Infinity) # optional - sage.libs.gap infinity """ return 'infinity' @@ -1768,7 +1769,7 @@ def test_comparison(ring): EXAMPLES:: sage: from sage.rings.infinity import test_comparison - sage: rings = [ZZ, QQ, RR, RealField(200), RDF, RLF, AA, RIF] + sage: rings = [ZZ, QQ, RR, RealField(200), RDF, RLF, RIF] sage: for R in rings: ....: print('testing {}'.format(R)) ....: test_comparison(R) @@ -1778,20 +1779,20 @@ def test_comparison(ring): testing Real Field with 200 bits of precision testing Real Double Field testing Real Lazy Field - testing Algebraic Real Field testing Real Interval Field with 53 bits of precision + sage: test_comparison(AA) # optional - sage.rings.number_field Comparison with number fields does not work:: - sage: K. = NumberField(x^2-3) - sage: (-oo < 1+sqrt3) and (1+sqrt3 < oo) # known bug + sage: K. = NumberField(x^2 - 3) # optional - sage.rings.number_field + sage: (-oo < 1 + sqrt3) and (1 + sqrt3 < oo) # known bug # optional - sage.rings.number_field False The symbolic ring handles its own infinities, but answers ``False`` (meaning: cannot decide) already for some very elementary comparisons:: - sage: test_comparison(SR) # known bug + sage: test_comparison(SR) # known bug # optional - sage.symbolic Traceback (most recent call last): ... AssertionError: testing -1000.0 in Symbolic Ring: id = ... diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 61c980557ff..4c0ee165cee 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -8,7 +8,7 @@ EXAMPLES: Add 2 integers:: - sage: a = Integer(3) ; b = Integer(4) + sage: a = Integer(3); b = Integer(4) sage: a + b == 7 True @@ -25,7 +25,7 @@ Add an integer and a rational number:: Add an integer and a complex number:: sage: b = ComplexField().0 + 1.5 - sage: loads((a+b).dumps()) == a+b + sage: loads((a + b).dumps()) == a + b True sage: z = 32 @@ -40,7 +40,7 @@ Add an integer and a complex number:: Multiplication:: - sage: a = Integer(3) ; b = Integer(4) + sage: a = Integer(3); b = Integer(4) sage: a * b == 12 True sage: loads((a * 4.0).dumps()) == a*b @@ -55,13 +55,13 @@ Multiplication:: :: - sage: 'sage'*Integer(3) + sage: 'sage' * Integer(3) 'sagesagesage' COERCIONS: Return version of this integer in the multi-precision floating -real field R:: +real field `\RR`:: sage: n = 9390823 sage: RR = RealField(200) @@ -235,7 +235,7 @@ cdef _digits_naive(mpz_t v,l,int offset,Integer base,digits): - ``base`` -- the base to which we finding digits - ``digits`` - a python sequence type with objects to use for digits - note that python negative index semantics are relied upon + note that python negative index semantics are relied upon AUTHORS: @@ -277,7 +277,7 @@ cdef _digits_internal(mpz_t v,l,int offset,int power_index,power_list,digits): to fill at - ``power_index`` - a measure of size to fill and index to - power_list we're filling 1 << (power_index+1) digits + power_list we're filling ``1 << (power_index+1)`` digits - ``power_list`` - a list of powers of the base, precomputed in method digits digits - a python sequence type with objects to @@ -323,7 +323,7 @@ mpz_ui_pow_ui(PARI_PSEUDOPRIME_LIMIT, 2, 64) def is_Integer(x): """ - Return true if x is of the Sage integer type. + Return ``True`` if ``x`` is of the Sage :class:`Integer` type. EXAMPLES:: @@ -347,30 +347,30 @@ cdef inline Integer as_Integer(x): cdef class IntegerWrapper(Integer): r""" - Rationale for the ``IntegerWrapper`` class: + Rationale for the :class:`IntegerWrapper` class: - With ``Integers``, the allocation/deallocation function slots are + With :class:`Integer` objects, the allocation/deallocation function slots are hijacked with custom functions that stick already allocated - ``Integers`` (with initialized ``parent`` and ``mpz_t`` fields) + :class:`Integer` objects (with initialized ``parent`` and ``mpz_t`` fields) into a pool on "deallocation" and then pull them out whenever a - new one is needed. Because ``Integers`` are so common, this is - actually a significant savings. However , this does cause issues - with subclassing a Python class directly from ``Integer`` (but + new one is needed. Because :class:`Integers` objects are so common, this is + actually a significant savings. However, this does cause issues + with subclassing a Python class directly from :class:`Integer` (but that's ok for a Cython class). As a workaround, one can instead derive a class from the - intermediate class ``IntegerWrapper``, which sets statically its - alloc/dealloc methods to the *original* ``Integer`` alloc/dealloc + intermediate class :class:`IntegerWrapper`, which sets statically its + alloc/dealloc methods to the *original* :class:`Integer` alloc/dealloc methods, before they are swapped manually for the custom ones. - The constructor of ``IntegerWrapper`` further allows for - specifying an alternative parent to ``IntegerRing()``. + The constructor of :class:`IntegerWrapper` further allows for + specifying an alternative parent to :class:`IntegerRing`. """ def __init__(self, parent=None, x=None, unsigned int base=0): """ We illustrate how to create integers with parents different - from ``IntegerRing()``:: + from :class:`IntegerRing``:: sage: from sage.rings.integer import IntegerWrapper @@ -396,15 +396,15 @@ cdef class IntegerWrapper(Integer): cdef class Integer(sage.structure.element.EuclideanDomainElement): r""" - The ``Integer`` class represents arbitrary precision - integers. It derives from the ``Element`` class, so + The :class:`Integer` class represents arbitrary precision + integers. It derives from the :class:`Element` class, so integers can be used as ring elements anywhere in Sage. - Integer() interprets strings that begin with ``0o`` as octal numbers, + The constructor of :class:`Integer` interprets strings that begin with ``0o`` as octal numbers, strings that begin with ``0x`` as hexadecimal numbers and strings that begin with ``0b`` as binary numbers. - The class ``Integer`` is implemented in Cython, as a wrapper of the + The class :class:`Integer` is implemented in Cython, as a wrapper of the GMP ``mpz_t`` integer type. EXAMPLES:: @@ -425,9 +425,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): Conversion from PARI:: - sage: Integer(pari('-10380104371593008048799446356441519384')) # optional - sage.libs.pari + sage: Integer(pari('-10380104371593008048799446356441519384')) # optional - sage.libs.pari -10380104371593008048799446356441519384 - sage: Integer(pari('Pol([-3])')) # optional - sage.libs.pari + sage: Integer(pari('Pol([-3])')) # optional - sage.libs.pari -3 Conversion from gmpy2:: @@ -463,11 +463,11 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): -901824309821093821093812093810928309183091832091 sage: ZZ(RR(2.0)^80) 1208925819614629174706176 - sage: ZZ(QQbar(sqrt(28-10*sqrt(3)) + sqrt(3))) # optional - sage.rings.number_field, sage.symbolic + sage: ZZ(QQbar(sqrt(28-10*sqrt(3)) + sqrt(3))) # optional - sage.rings.number_field sage.symbolic 5 - sage: ZZ(AA(32).nth_root(5)) # optional - sage.rings.number_field + sage: ZZ(AA(32).nth_root(5)) # optional - sage.rings.number_field 2 - sage: ZZ(pari('Mod(-3,7)')) # optional - sage.libs.pari + sage: ZZ(pari('Mod(-3,7)')) # optional - sage.libs.pari 4 sage: ZZ('sage') Traceback (most recent call last): @@ -479,10 +479,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): '3b' sage: ZZ( ZZ(5).digits(3) , 3) 5 - sage: import numpy - sage: ZZ(numpy.int64(7^7)) + sage: import numpy # optional - numpy + sage: ZZ(numpy.int64(7^7)) # optional - numpy 823543 - sage: ZZ(numpy.ubyte(-7)) + sage: ZZ(numpy.ubyte(-7)) # optional - numpy 249 sage: ZZ(True) 1 @@ -498,8 +498,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): :: - sage: k = GF(2) # optional - sage.libs.pari - sage: ZZ((k(0),k(1)), 2) # optional - sage.libs.pari + sage: k = GF(2) # optional - sage.rings.finite_rings + sage: ZZ((k(0),k(1)), 2) # optional - sage.rings.finite_rings 2 :: @@ -535,72 +535,72 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): Test conversion from PARI (:trac:`11685`):: - sage: ZZ(pari(-3)) # optional - sage.libs.pari + sage: ZZ(pari(-3)) # optional - sage.libs.pari -3 - sage: ZZ(pari("-3.0")) # optional - sage.libs.pari + sage: ZZ(pari("-3.0")) # optional - sage.libs.pari -3 - sage: ZZ(pari("-3.5")) # optional - sage.libs.pari + sage: ZZ(pari("-3.5")) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: Attempt to coerce non-integral real number to an Integer - sage: ZZ(pari("1e100")) # optional - sage.libs.pari + sage: ZZ(pari("1e100")) # optional - sage.libs.pari Traceback (most recent call last): ... PariError: precision too low in truncr (precision loss in truncation) - sage: ZZ(pari("10^50")) # optional - sage.libs.pari + sage: ZZ(pari("10^50")) # optional - sage.libs.pari 100000000000000000000000000000000000000000000000000 - sage: ZZ(pari("Pol(3)")) # optional - sage.libs.pari + sage: ZZ(pari("Pol(3)")) # optional - sage.libs.pari 3 - sage: ZZ(GF(3^20,'t')(1)) # optional - sage.libs.pari + sage: ZZ(GF(3^20,'t')(1)) # optional - sage.rings.finite_rings 1 - sage: ZZ(pari(GF(3^20,'t')(1))) # optional - sage.libs.pari + sage: ZZ(pari(GF(3^20,'t')(1))) # optional - sage.libs.pari sage.rings.finite_rings 1 sage: x = polygen(QQ) - sage: K. = NumberField(x^2+3) # optional - sage.rings.number_field - sage: ZZ(a^2) # optional - sage.rings.number_field + sage: K. = NumberField(x^2 + 3) # optional - sage.rings.number_field + sage: ZZ(a^2) # optional - sage.rings.number_field -3 - sage: ZZ(pari(a)^2) # optional - sage.libs.pari, sage.rings.number_field + sage: ZZ(pari(a)^2) # optional - sage.libs.pari sage.rings.number_field -3 - sage: ZZ(pari("Mod(x, x^3+x+1)")) # Note error message refers to lifted element # optional - sage.libs.pari + sage: ZZ(pari("Mod(x, x^3+x+1)")) # Note error message refers to lifted element # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: Unable to coerce PARI x to an Integer Test coercion of p-adic with negative valuation:: - sage: ZZ(pari(Qp(11)(11^-7))) # optional - sage.libs.pari + sage: ZZ(pari(Qp(11)(11^-7))) # optional - sage.libs.pari sage.rings.padics Traceback (most recent call last): ... TypeError: cannot convert p-adic with negative valuation to an integer Test converting a list with a very large base:: - sage: a=ZZ(randint(0,2^128-1)) + sage: a = ZZ(randint(0, 2^128 - 1)) sage: L = a.digits(2^64) sage: a == sum([x * 2^(64*i) for i,x in enumerate(L)]) True - sage: a == ZZ(L,base=2^64) + sage: a == ZZ(L, base=2^64) True Test comparisons with numpy types (see :trac:`13386` and :trac:`18076`):: - sage: import numpy - sage: numpy.int8('12') == 12 + sage: import numpy # optional - numpy + sage: numpy.int8('12') == 12 # optional - numpy True - sage: 12 == numpy.int8('12') + sage: 12 == numpy.int8('12') # optional - numpy True - sage: float('15') == 15 + sage: float('15') == 15 # optional - numpy True - sage: 15 == float('15') + sage: 15 == float('15') # optional - numpy True Test underscores as digit separators (PEP 515, https://www.python.org/dev/peps/pep-0515/):: - sage: Integer('1_3') + sage: Integer('1_3') # optional - numpy 13 - sage: Integer(b'1_3') + sage: Integer(b'1_3') # optional - numpy 13 """ # TODO: All the code below should somehow be in an external @@ -762,15 +762,15 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def _im_gens_(self, codomain, im_gens, base_map=None): """ - Return the image of self under the map that sends the generators of + Return the image of ``self`` under the map that sends the generators of the parent to im_gens. Since ZZ maps canonically in the category of rings, this is just the natural coercion. EXAMPLES:: sage: n = -10 - sage: R = GF(17) # optional - sage.libs.pari - sage: n._im_gens_(R, [R(1)]) # optional - sage.libs.pari + sage: R = GF(17) # optional - sage.rings.finite_rings + sage: n._im_gens_(R, [R(1)]) # optional - sage.rings.finite_rings 7 """ return codomain.coerce(self) @@ -1007,9 +1007,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: - sage: ex = SR(ZZ(7)); ex + sage: ex = SR(ZZ(7)); ex # optional - sage.symbolic 7 - sage: parent(ex) + sage: parent(ex) # optional - sage.symbolic Symbolic Ring """ return sring._force_pyobject(self, force=True) @@ -1020,9 +1020,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: - sage: n = 5; n._sympy_() + sage: n = 5; n._sympy_() # optional - sympy 5 - sage: n = -5; n._sympy_() + sage: n = -5; n._sympy_() # optional - sympy -5 """ import sympy @@ -1077,7 +1077,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): :: - sage: two=Integer(2) + sage: two = Integer(2) sage: two.str(1) Traceback (most recent call last): ... @@ -1114,7 +1114,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def __format__(self, *args, **kwargs): """ - Returns a string representation using Python's Format protocol. + Return a string representation using Python's Format protocol. Valid format descriptions are exactly those for Python integers. EXAMPLES:: @@ -1127,7 +1127,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def ordinal_str(self): """ - Returns a string representation of the ordinal associated to self. + Return a string representation of the ordinal associated to ``self``. EXAMPLES:: @@ -1255,7 +1255,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def bits(self): r""" - Return the bits in self as a list, least significant first. The + Return the bits in ``self`` as a list, least significant first. The result satisfies the identity :: @@ -1338,7 +1338,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def trailing_zero_bits(self): """ - Return the number of trailing zero bits in self, i.e. + Return the number of trailing zero bits in ``self``, i.e. the exponent of the largest power of 2 dividing self. EXAMPLES:: @@ -1364,7 +1364,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): Return a list of digits for ``self`` in the given base in little endian order. - The returned value is unspecified if self is a negative number + The returned value is unspecified if ``self`` is a negative number and the digits are given. INPUT: @@ -1466,7 +1466,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: l[16] [1, 1] - This function is comparable to ``str`` for speed. + This function is comparable to :func:`str` for speed. :: @@ -1594,7 +1594,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): between ``-b//2`` and ``b//2`` (both included). For instance in base 9, one uses digits from -4 to 4. If ``b`` is even, one has to choose between digits from ``-b//2`` to ``b//2 - 1`` or ``-b//2 + 1`` to ``b//2`` - (base 10 for instance: either -5 to 4 or -4 to 5), and this is + (base 10 for instance: either `-5` to `4` or `-4` to `5`), and this is defined by the value of ``positive_shift``. INPUT: @@ -1603,9 +1603,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): nonnegative or the nonpositive integers can be represented by ``balanced_digits``. Thus we say base must be greater than 2. - - ``positive_shift`` -- boolean (default: True); for even bases, the + - ``positive_shift`` -- boolean (default: ``True``); for even bases, the representation uses digits from ``-b//2 + 1`` to ``b//2`` if set to - True, and from ``-b//2`` to ``b//2 - 1`` otherwise. This has no + ``True``, and from ``-b//2`` to ``b//2 - 1`` otherwise. This has no effect for odd bases. EXAMPLES:: @@ -1695,7 +1695,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def ndigits(self, base=10): """ - Return the number of digits of self expressed in the given base. + Return the number of digits of ``self`` expressed in the given base. INPUT: @@ -2008,7 +2008,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): Traceback (most recent call last): ... ZeroDivisionError: rational division by zero - sage: 3 / QQbar.zero() # optional - sage.rings.number_field + sage: 3 / QQbar.zero() # optional - sage.rings.number_field Traceback (most recent call last): ... ZeroDivisionError: division by zero in algebraic field @@ -2056,7 +2056,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: - sage: a = Integer(321) ; b = Integer(10) + sage: a = Integer(321); b = Integer(10) sage: a // b 32 sage: z = Integer(-231) @@ -2113,7 +2113,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): 1 sage: 2^-0 1 - sage: (-1)^(1/3) # optional - sage.symbolic + sage: (-1)^(1/3) # optional - sage.symbolic (-1)^(1/3) For consistency with Python and MPFR, 0^0 is defined to be 1 in @@ -2140,7 +2140,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): We raise 2 to various interesting exponents:: - sage: 2^x # symbolic x # optional - sage.symbolic + sage: 2^x # symbolic x # optional - sage.symbolic 2^x sage: 2^1.5 # real number 2.82842712474619 @@ -2151,19 +2151,19 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: r = 2 ^ int(-3); r; type(r) 1/8 - sage: f = 2^(sin(x)-cos(x)); f # optional - sage.symbolic + sage: f = 2^(sin(x)-cos(x)); f # optional - sage.symbolic 2^(-cos(x) + sin(x)) sage: f(x=3) 2^(-cos(3) + sin(3)) A symbolic sum:: - sage: x, y, z = var('x,y,z') # optional - sage.symbolic - sage: 2^(x + y + z) # optional - sage.symbolic + sage: x, y, z = var('x,y,z') # optional - sage.symbolic + sage: 2^(x + y + z) # optional - sage.symbolic 2^(x + y + z) - sage: 2^(1/2) # optional - sage.symbolic + sage: 2^(1/2) # optional - sage.symbolic sqrt(2) - sage: 2^(-1/2) # optional - sage.symbolic + sage: 2^(-1/2) # optional - sage.symbolic 1/2*sqrt(2) TESTS:: @@ -2220,7 +2220,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): ... ZeroDivisionError: rational division by zero - The exponent must fit in a long unless the base is -1, 0, or 1:: + The exponent must fit in a ``long`` unless the base is `-1`, `0`, or `1`:: sage: 2 ^ 100000000000000000000000 Traceback (most recent call last): @@ -2316,25 +2316,25 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def nth_root(self, int n, bint truncate_mode=0): r""" - Returns the (possibly truncated) n'th root of self. + Return the (possibly truncated) ``n``-th root of ``self``. INPUT: - - ``n`` - integer >= 1 (must fit in C int type). + - ``n`` - integer `\geq 1` (must fit in the C ``int`` type). - ``truncate_mode`` - boolean, whether to allow truncation if - self is not an n'th power. + ``self`` is not an ``n``-th power. OUTPUT: - If truncate_mode is 0 (default), then returns the exact n'th root - if self is an n'th power, or raises a ValueError if it is not. + If ``truncate_mode`` is 0 (default), then returns the exact n'th root + if ``self`` is an n'th power, or raises a ValueError if it is not. - If truncate_mode is 1, then if either n is odd or self is - positive, returns a pair (root, exact_flag) where root is the - truncated nth root (rounded towards zero) and exact_flag is a + If ``truncate_mode`` is 1, then if either ``n`` is odd or ``self`` is + positive, returns a pair ``(root, exact_flag)`` where ``root`` is the + truncated ``n``-th root (rounded towards zero) and ``exact_flag`` is a boolean indicating whether the root extraction was exact; - otherwise raises a ValueError. + otherwise raises a :class:`ValueError`. AUTHORS: @@ -2603,7 +2603,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def exact_log(self, m): r""" - Returns the largest integer `k` such that `m^k \leq \text{self}`, + Return the largest integer `k` such that `m^k \leq \text{self}`, i.e., the floor of `\log_m(\text{self})`. This is guaranteed to return the correct answer even when the usual @@ -2611,13 +2611,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``m`` - integer >= 2 + - ``m`` - integer `\geq 2` AUTHORS: - David Harvey (2006-09-15) - Joel B. Mohler (2009-04-08) -- rewrote this to handle small cases - and/or easy cases up to 100x faster.. + and/or easy cases up to 100x faster.. EXAMPLES:: @@ -2643,11 +2643,12 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: # The following are very very fast. sage: # Note that for base m a perfect power of 2, we get the exact log by counting bits. - sage: n=2983579823750185701375109835; m=32 + sage: n = 2983579823750185701375109835; m = 32 sage: n.exact_log(m) 18 sage: # The next is a favorite of mine. The log2 approximate is exact and immediately provable. - sage: n=90153710570912709517902579010793251709257901270941709247901209742124;m=213509721309572 + sage: n = 90153710570912709517902579010793251709257901270941709247901209742124 + sage: m = 213509721309572 sage: n.exact_log(m) 4 @@ -2663,9 +2664,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: x.exact_log(3) 100000 - sage: (x+1).exact_log(3) + sage: (x + 1).exact_log(3) 100000 - sage: (x-1).exact_log(3) + sage: (x - 1).exact_log(3) 99999 :: @@ -2750,24 +2751,24 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def log(self, m=None, prec=None): r""" - Returns symbolic log by default, unless the logarithm is exact (for - an integer argument). When precision is given, the RealField + Return symbolic log by default, unless the logarithm is exact (for + an integer argument). When ``prec`` is given, the :class:`RealField` approximation to that bit precision is used. This function is provided primarily so that Sage integers may be treated in the same manner as real numbers when convenient. Direct - use of exact_log is probably best for arithmetic log computation. + use of :meth:`exact_log` is probably best for arithmetic log computation. INPUT: - ``m`` - default: natural log base e - - ``prec`` - integer (default: None): if None, returns - symbolic, else to given bits of precision as in RealField + - ``prec`` - integer (default: ``None``): if ``None``, returns + symbolic, else to given bits of precision as in :class:`RealField` EXAMPLES:: - sage: Integer(124).log(5) # optional - sage.symbolic + sage: Integer(124).log(5) # optional - sage.symbolic log(124)/log(5) sage: Integer(124).log(5, 100) 2.9950093311241087454822446806 @@ -2775,7 +2776,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): 3 sage: Integer(125).log(5, prec=53) 3.00000000000000 - sage: log(Integer(125)) + sage: log(Integer(125)) # optional - sage.symbolic 3*log(5) For extremely large numbers, this works:: @@ -2784,32 +2785,32 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: log(x, 3) 100000 - With the new Pynac symbolic backend, log(x) also - works in a reasonable amount of time for this x:: + Also ``log(x)``, giving a symbolic output, + works in a reasonable amount of time for this ``x``:: sage: x = 3^100000 - sage: log(x) + sage: log(x) # optional - sage.symbolic log(1334971414230...5522000001) But approximations are probably more useful in this case, and work to as high a precision as we desire:: - sage: x.log(3,53) # default precision for RealField + sage: x.log(3, 53) # default precision for RealField 100000.000000000 - sage: (x+1).log(3,53) + sage: (x + 1).log(3, 53) 100000.000000000 - sage: (x+1).log(3,1000) + sage: (x + 1).log(3, 1000) 100000.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 We can use non-integer bases, with default e:: - sage: x.log(2.5,prec=53) + sage: x.log(2.5, prec=53) 119897.784671579 We also get logarithms of negative integers, via the - symbolic ring, using the branch from `-pi` to `pi`:: + symbolic ring, using the branch from `-\pi` to `\pi`:: - sage: log(-1) + sage: log(-1) # optional - sage.symbolic I*pi The logarithm of zero is done likewise:: @@ -2829,7 +2830,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): TESTS:: - sage: (-2).log(3) # optional - sage.symbolic + sage: (-2).log(3) # optional - sage.symbolic (I*pi + log(2))/log(3) """ cdef int self_sgn @@ -2872,7 +2873,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def exp(self, prec=None): r""" - Returns the exponential function of self as a real number. + Return the exponential function of ``self`` as a real number. This function is provided only so that Sage integers may be treated in the same manner as real numbers when convenient. @@ -2881,16 +2882,16 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): - ``prec`` - integer (default: None): if None, returns - symbolic, else to given bits of precision as in RealField + symbolic, else to given bits of precision as in :class:`RealField` EXAMPLES:: - sage: Integer(8).exp() # optional - sage.symbolic + sage: Integer(8).exp() # optional - sage.symbolic e^8 - sage: Integer(8).exp(prec=100) # optional - sage.symbolic + sage: Integer(8).exp(prec=100) # optional - sage.symbolic 2980.9579870417282747435920995 - sage: exp(Integer(8)) # optional - sage.symbolic + sage: exp(Integer(8)) # optional - sage.symbolic e^8 For even fairly large numbers, this may not be useful. @@ -2898,9 +2899,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): :: sage: y = Integer(145^145) - sage: y.exp() # optional - sage.symbolic + sage: y.exp() # optional - sage.symbolic e^25024207011349079210459585279553675697932183658421565260323592409432707306554163224876110094014450895759296242775250476115682350821522931225499163750010280453185147546962559031653355159703678703793369785727108337766011928747055351280379806937944746847277089168867282654496776717056860661614337004721164703369140625 - sage: y.exp(prec=53) # default RealField precision # optional - sage.symbolic + sage: y.exp(prec=53) # default RealField precision # optional - sage.symbolic +infinity """ from sage.functions.all import exp @@ -2911,8 +2912,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def prime_to_m_part(self, m): """ - Returns the prime-to-m part of self, i.e., the largest divisor of - ``self`` that is coprime to ``m``. + Return the prime-to-`m` part of ``self``, i.e., the largest divisor of + ``self`` that is coprime to `m`. INPUT: @@ -2955,8 +2956,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): """ Return the prime divisors of this integer, sorted in increasing order. - If this integer is negative, we do *not* include -1 among - its prime divisors, since -1 is not a prime number. + If this integer is negative, we do *not* include `-1` among + its prime divisors, since `-1` is not a prime number. INPUT: @@ -2980,12 +2981,12 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): Setting the optional ``limit`` argument works as expected:: sage: a = 10^100 + 1 - sage: a.prime_divisors() + sage: a.prime_divisors() # optional - sage.libs.pari [73, 137, 401, 1201, 1601, 1676321, 5964848081, 129694419029057750551385771184564274499075700947656757821537291527196801] - sage: a.prime_divisors(limit=10^3) + sage: a.prime_divisors(limit=10^3) # optional - sage.libs.pari [73, 137, 401] - sage: a.prime_divisors(limit=10^7) + sage: a.prime_divisors(limit=10^7) # optional - sage.libs.pari [73, 137, 401, 1201, 1601, 1676321] """ res = [r[0] for r in self.factor(*args, **kwds)] @@ -3027,32 +3028,32 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): [1, 2, 3, 4, 6, 8, 9, 12, 17, 18, 24, 34, 36, 51, 68, 72, 102, 136, 153, 204, 306, 408, 612, 1224] sage: a = odd_part(factorial(31)) - sage: v = a.divisors() - sage: len(v) + sage: v = a.divisors() # optional - sage.libs.pari + sage: len(v) # optional - sage.libs.pari 172800 - sage: prod(e + 1 for p, e in factor(a)) + sage: prod(e + 1 for p, e in factor(a)) # optional - sage.libs.pari 172800 - sage: all(t.divides(a) for t in v) + sage: all(t.divides(a) for t in v) # optional - sage.libs.pari True :: sage: n = 2^551 - 1 - sage: L = n.divisors() # optional - sage.libs.pari - sage: len(L) # optional - sage.libs.pari + sage: L = n.divisors() # optional - sage.libs.pari + sage: len(L) # optional - sage.libs.pari 256 - sage: L[-1] == n # optional - sage.libs.pari + sage: L[-1] == n # optional - sage.libs.pari True TESTS: Overflow:: - sage: prod(primes_first_n(64)).divisors() # optional - sage.libs.pari + sage: prod(primes_first_n(64)).divisors() # optional - sage.libs.pari Traceback (most recent call last): ... OverflowError: value too large - sage: prod(primes_first_n(58)).divisors() # optional - sage.libs.pari + sage: prod(primes_first_n(58)).divisors() # optional - sage.libs.pari Traceback (most recent call last): ... OverflowError: value too large # 32-bit @@ -3062,8 +3063,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): (the ``divisors`` call below allocates about 800 MB every time, so a memory leak will not go unnoticed):: - sage: n = prod(primes_first_n(25)) # optional - sage.libs.pari - sage: for i in range(20): # long time # optional - sage.libs.pari + sage: n = prod(primes_first_n(25)) # optional - sage.libs.pari + sage: for i in range(20): # long time # optional - sage.libs.pari ....: try: ....: alarm(RDF.random_element(1e-3, 0.5)) ....: _ = n.divisors() @@ -3289,7 +3290,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def sign(self): """ - Returns the sign of this integer, which is -1, 0, or 1 + Return the sign of this integer, which is `-1`, `0`, or `1` depending on whether this number is negative, zero, or positive respectively. @@ -3345,9 +3346,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): This example caused trouble in :trac:`6083`:: - sage: a = next_prime(2**31) # optional - sage.libs.pari - sage: b = Integers(a)(100) # optional - sage.libs.pari - sage: a % b # optional - sage.libs.pari + sage: a = next_prime(2**31) # optional - sage.libs.pari + sage: b = Integers(a)(100) # optional - sage.libs.pari + sage: a % b # optional - sage.libs.pari Traceback (most recent call last): ... ArithmeticError: reduction modulo 100 not defined @@ -3394,7 +3395,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def quo_rem(Integer self, other): """ - Returns the quotient and the remainder of self divided by other. + Return the quotient and the remainder of ``self`` divided by other. Note that the remainder returned is always either zero or of the same sign as other. @@ -3443,10 +3444,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: divmod(1, sys.maxsize+1r) # should not raise OverflowError: Python int too large to convert to C long (0, 1) - sage: import mpmath - sage: mpmath.mp.prec = 1000 - sage: root = mpmath.findroot(lambda x: x^2 - 3, 2) - sage: len(str(root)) + sage: import mpmath # optional - mpmath + sage: mpmath.mp.prec = 1000 # optional - mpmath + sage: root = mpmath.findroot(lambda x: x^2 - 3, 2) # optional - mpmath + sage: len(str(root)) # optional - mpmath 301 """ cdef Integer q = PY_NEW(Integer) @@ -3484,7 +3485,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def powermod(self, exp, mod): r""" - Compute self\*\*exp modulo mod. + Compute ``self**exp`` modulo ``mod``. EXAMPLES:: @@ -3517,11 +3518,11 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): return x def rational_reconstruction(self, Integer m): - """ - Return the rational reconstruction of this integer modulo m, i.e., - the unique (if it exists) rational number that reduces to self + r""" + Return the rational reconstruction of this integer modulo `m`, i.e., + the unique (if it exists) rational number that reduces to ``self`` modulo m and whose numerator and denominator is bounded by - sqrt(m/2). + `\sqrt{m/2}`. INPUT: @@ -3609,7 +3610,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def _rpy_(self): """ - Returns int(self) so that rpy can convert self into an object it + Return int(self) so that rpy can convert ``self`` into an object it knows how to work with. EXAMPLES:: @@ -3687,58 +3688,56 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def trial_division(self, long bound=LONG_MAX, long start=2): """ - Return smallest prime divisor of self up to bound, beginning - checking at start, or abs(self) if no such divisor is found. + Return smallest prime divisor of ``self`` up to bound, beginning + checking at ``start``, or ``abs(self)`` if no such divisor is found. INPUT: - - ``bound`` -- a positive integer that fits in a C signed long - - ``start`` -- a positive integer that fits in a C signed long - - OUTPUT: + - ``bound`` -- a positive integer that fits in a C ``signed long`` + - ``start`` -- a positive integer that fits in a C ``signed long`` - - a positive integer + OUTPUT: A positive integer EXAMPLES:: - sage: n = next_prime(10^6)*next_prime(10^7); n.trial_division() # optional - sage.libs.pari + sage: n = next_prime(10^6)*next_prime(10^7); n.trial_division() # optional - sage.libs.pari 1000003 - sage: (-n).trial_division() # optional - sage.libs.pari + sage: (-n).trial_division() # optional - sage.libs.pari 1000003 - sage: n.trial_division(bound=100) # optional - sage.libs.pari + sage: n.trial_division(bound=100) # optional - sage.libs.pari 10000049000057 - sage: n.trial_division(bound=-10) # optional - sage.libs.pari + sage: n.trial_division(bound=-10) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: bound must be positive - sage: n.trial_division(bound=0) # optional - sage.libs.pari + sage: n.trial_division(bound=0) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: bound must be positive - sage: ZZ(0).trial_division() # optional - sage.libs.pari + sage: ZZ(0).trial_division() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: self must be nonzero - sage: n = next_prime(10^5) * next_prime(10^40); n.trial_division() # optional - sage.libs.pari + sage: n = next_prime(10^5) * next_prime(10^40); n.trial_division() # optional - sage.libs.pari 100003 - sage: n.trial_division(bound=10^4) # optional - sage.libs.pari + sage: n.trial_division(bound=10^4) # optional - sage.libs.pari 1000030000000000000000000000000000000012100363 - sage: (-n).trial_division(bound=10^4) # optional - sage.libs.pari + sage: (-n).trial_division(bound=10^4) # optional - sage.libs.pari 1000030000000000000000000000000000000012100363 - sage: (-n).trial_division() # optional - sage.libs.pari + sage: (-n).trial_division() # optional - sage.libs.pari 100003 - sage: n = 2 * next_prime(10^40); n.trial_division() # optional - sage.libs.pari + sage: n = 2 * next_prime(10^40); n.trial_division() # optional - sage.libs.pari 2 - sage: n = 3 * next_prime(10^40); n.trial_division() # optional - sage.libs.pari + sage: n = 3 * next_prime(10^40); n.trial_division() # optional - sage.libs.pari 3 - sage: n = 5 * next_prime(10^40); n.trial_division() # optional - sage.libs.pari + sage: n = 5 * next_prime(10^40); n.trial_division() # optional - sage.libs.pari 5 - sage: n = 2 * next_prime(10^4); n.trial_division() # optional - sage.libs.pari + sage: n = 2 * next_prime(10^4); n.trial_division() # optional - sage.libs.pari 2 - sage: n = 3 * next_prime(10^4); n.trial_division() # optional - sage.libs.pari + sage: n = 3 * next_prime(10^4); n.trial_division() # optional - sage.libs.pari 3 - sage: n = 5 * next_prime(10^4); n.trial_division() # optional - sage.libs.pari + sage: n = 5 * next_prime(10^4); n.trial_division() # optional - sage.libs.pari 5 You can specify a starting point:: @@ -3849,12 +3848,12 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): - ``'ecm'`` - use ECM-GMP, an implementation of Hendrik Lenstra's elliptic curve method. - - ``proof`` - bool (default: True) whether or not to prove + - ``proof`` - bool (default: ``True``) whether or not to prove primality of each factor (only applicable for ``'pari'`` and ``'ecm'``). - ``limit`` - int or None (default: None) if limit is - given it must fit in a signed int, and the factorization is done + given it must fit in a ``signed int``, and the factorization is done using trial division and primes up to limit. OUTPUT: @@ -3864,7 +3863,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: - sage: n = 2^100 - 1; n.factor() # optional - sage.libs.pari + sage: n = 2^100 - 1; n.factor() # optional - sage.libs.pari 3 * 5^3 * 11 * 31 * 41 * 101 * 251 * 601 * 1801 * 4051 * 8101 * 268501 This factorization can be converted into a list of pairs `(p, @@ -3887,13 +3886,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: dict(f)[3] 6 - We use proof=False, which doesn't prove correctness of the primes + We use ``proof=False``, which doesn't prove correctness of the primes that appear in the factorization:: sage: n = 920384092842390423848290348203948092384082349082 - sage: n.factor(proof=False) # optional - sage.libs.pari + sage: n.factor(proof=False) # optional - sage.libs.pari 2 * 11 * 1531 * 4402903 * 10023679 * 619162955472170540533894518173 - sage: n.factor(proof=True) # optional - sage.libs.pari + sage: n.factor(proof=True) # optional - sage.libs.pari 2 * 11 * 1531 * 4402903 * 10023679 * 619162955472170540533894518173 We factor using trial division only:: @@ -3904,15 +3903,15 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): An example where FLINT is used:: sage: n = 82862385732327628428164127822 - sage: n.factor(algorithm='flint') + sage: n.factor(algorithm='flint') # optional - sage.libs.flint 2 * 3 * 11 * 13 * 41 * 73 * 22650083 * 1424602265462161 We factor using a quadratic sieve algorithm:: - sage: p = next_prime(10^20) # optional - sage.libs.pari - sage: q = next_prime(10^21) # optional - sage.libs.pari - sage: n = p * q # optional - sage.libs.pari - sage: n.factor(algorithm='qsieve') # optional - sage.libs.pari + sage: p = next_prime(10^20) # optional - sage.libs.pari + sage: q = next_prime(10^21) # optional - sage.libs.pari + sage: n = p * q # optional - sage.libs.pari + sage: n.factor(algorithm='qsieve') # optional - sage.libs.pari doctest:... RuntimeWarning: the factorization returned by qsieve may be incomplete (the factors may not be prime) or even wrong; see qsieve? for details @@ -3920,10 +3919,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): We factor using the elliptic curve method:: - sage: p = next_prime(10^15) # optional - sage.libs.pari - sage: q = next_prime(10^21) # optional - sage.libs.pari - sage: n = p * q # optional - sage.libs.pari - sage: n.factor(algorithm='ecm') # optional - sage.libs.pari + sage: p = next_prime(10^15) # optional - sage.libs.pari + sage: q = next_prime(10^21) # optional - sage.libs.pari + sage: n = p * q # optional - sage.libs.pari + sage: n.factor(algorithm='ecm') # optional - sage.libs.pari 1000000000000037 * 1000000000000000000117 TESTS:: @@ -3985,13 +3984,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): return factor_trial_division(self) if algorithm == 'pari': - from sage.rings.factorint import factor_using_pari + from sage.rings.factorint_pari import factor_using_pari F = factor_using_pari(n, int_=int_, debug_level=verbose, proof=proof) F.sort() return IntegerFactorization(F, unit=unit, unsafe=True, sort=False, simplify=False) elif algorithm == 'flint': - from sage.rings.factorint import factor_using_flint + from sage.rings.factorint_flint import factor_using_flint F = factor_using_flint(n) F.sort() return IntegerFactorization(F, unit=unit, unsafe=True, @@ -4038,7 +4037,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: (-999).support() [3, 37] - Trying to find the support of 0 gives an arithmetic error:: + Trying to find the support of 0 raises an :class:`ArithmeticError`:: sage: 0.support() Traceback (most recent call last): @@ -4146,7 +4145,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def divides(self, n): """ - Return True if self divides n. + Return ``True`` if ``self`` divides ``n``. EXAMPLES:: @@ -4170,7 +4169,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cpdef RingElement _valuation(Integer self, Integer p): r""" - Return the p-adic valuation of self. + Return the p-adic valuation of ``self``. We do not require that p be prime, but it must be at least 2. For more documentation see ``valuation`` @@ -4195,8 +4194,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cdef object _val_unit(Integer self, Integer p): r""" - Returns a pair: the p-adic valuation of self, and the p-adic unit - of self. + Return a pair: the p-adic valuation of ``self``, and the p-adic unit + of ``self``. We do not require the p be prime, but it must be at least 2. For more documentation see ``val_unit`` @@ -4220,7 +4219,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def valuation(self, p): """ - Return the p-adic valuation of self. + Return the p-adic valuation of ``self``. INPUT: @@ -4240,7 +4239,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): ... ValueError: You can only compute the valuation with respect to a integer larger than 1. - We do not require that p is a prime:: + We do not require that ``p`` is a prime:: sage: (2^11).valuation(4) 5 @@ -4252,7 +4251,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def p_primary_part(self, p): """ - Return the p-primary part of ``self``. + Return the ``p``-primary part of ``self``. INPUT: @@ -4281,8 +4280,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def val_unit(self, p): r""" - Returns a pair: the p-adic valuation of self, and the p-adic unit - of self. + Return a pair: the p-adic valuation of ``self``, and the p-adic unit + of ``self``. INPUT: @@ -4317,10 +4316,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): IMPLEMENTATION: - Currently returns 0 when self is 0. This behaviour is fairly arbitrary, + Currently returns 0 when ``self`` is 0. This behaviour is fairly arbitrary, and in Sage 4.6 this special case was not handled at all, eventually propagating a TypeError. The caller should not rely on the behaviour - in case self is 0. + in case ``self`` is 0. EXAMPLES:: @@ -4344,10 +4343,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cdef Integer _divide_knowing_divisible_by(Integer self, Integer right): r""" - Returns the integer self / right when self is divisible by right. + Return the integer ``self`` / ``right`` when ``self`` is divisible by right. - If self is not divisible by right, the return value is undefined, - and may not even be close to self/right. For more documentation see + If ``self`` is not divisible by right, the return value is undefined, + and may not even be close to ``self`` / ``right``. For more documentation see ``divide_knowing_divisible_by`` AUTHORS: @@ -4370,10 +4369,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def divide_knowing_divisible_by(self, right): r""" - Returns the integer self / right when self is divisible by right. + Return the integer ``self`` / ``right`` when ``self`` is divisible by ``right``. - If self is not divisible by right, the return value is undefined, - and may not even be close to self/right for multi-word integers. + If ``self`` is not divisible by right, the return value is undefined, + and may not even be close to ``self`` / ``right`` for multi-word integers. EXAMPLES:: @@ -4400,7 +4399,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def _lcm(self, Integer n): """ - Returns the least common multiple of self and `n`. + Return the least common multiple of ``self`` and `n`. EXAMPLES:: @@ -4416,7 +4415,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def _gcd(self, Integer n): """ - Return the greatest common divisor of self and `n`. + Return the greatest common divisor of ``self`` and `n`. EXAMPLES:: @@ -4488,7 +4487,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): r""" Return the factorial `n! = 1 \cdot 2 \cdot 3 \cdots n`. - If the input does not fit in an ``unsigned long int`` an ``OverflowError`` + If the input does not fit in an ``unsigned long int``, an :class:`OverflowError` is raised. EXAMPLES:: @@ -4503,14 +4502,14 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): 5 120 6 720 - Large integers raise an ``OverflowError``:: + Large integers raise an :class:`OverflowError`:: sage: (2**64).factorial() Traceback (most recent call last): ... OverflowError: argument too large for factorial - And negative ones a ``ValueError``:: + And negative ones a :class:`ValueError`:: sage: (-1).factorial() Traceback (most recent call last): @@ -4533,7 +4532,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def multifactorial(self, long k): r""" - Compute the k-th factorial `n!^{(k)}` of self. + Compute the k-th factorial `n!^{(k)}` of ``self``. The multifactorial number `n!^{(k)}` is defined for non-negative integers `n` as follows. For `k=1` this is the standard factorial, @@ -4567,7 +4566,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): ... ValueError: multifactorial undefined - When entries are too large an ``OverflowError`` is raised:: + When entries are too large an :class:`OverflowError` is raised:: sage: (2**64).multifactorial(2) Traceback (most recent call last): @@ -4619,13 +4618,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: - sage: gamma(5) + sage: gamma(5) # optional - sage.symbolic 24 - sage: gamma(0) + sage: gamma(0) # optional - sage.symbolic Infinity - sage: gamma(-1) + sage: gamma(-1) # optional - sage.symbolic Infinity - sage: gamma(-2^150) + sage: gamma(-2^150) # optional - sage.symbolic Infinity """ if mpz_sgn(self.value) > 0: @@ -4635,7 +4634,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def floor(self): """ - Return the floor of self, which is just self since self is an + Return the floor of ``self``, which is just self since ``self`` is an integer. EXAMPLES:: @@ -4648,7 +4647,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def ceil(self): """ - Return the ceiling of self, which is self since self is an + Return the ceiling of ``self``, which is ``self`` since ``self`` is an integer. EXAMPLES:: @@ -4661,8 +4660,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def trunc(self): """ - Round this number to the nearest integer, which is self since - self is an integer. + Round this number to the nearest integer, which is ``self`` since + ``self`` is an integer. EXAMPLES:: @@ -4674,8 +4673,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def round(Integer self, mode="away"): """ - Returns the nearest integer to ``self``, which is self since - self is an integer. + Return the nearest integer to ``self``, which is ``self`` since + ``self`` is an integer. EXAMPLES: @@ -4689,7 +4688,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def real(self): """ - Returns the real part of self, which is self. + Return the real part of ``self``, which is ``self``. EXAMPLES:: @@ -4700,7 +4699,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def imag(self): """ - Returns the imaginary part of self, which is zero. + Return the imaginary part of ``self``, which is zero. EXAMPLES:: @@ -4711,7 +4710,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def is_one(self): r""" - Returns ``True`` if the integer is `1`, otherwise ``False``. + Return ``True`` if the integer is `1`, otherwise ``False``. EXAMPLES:: @@ -4724,7 +4723,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def __bool__(self): r""" - Returns ``True`` if the integer is not `0`, otherwise ``False``. + Return ``True`` if the integer is not `0`, otherwise ``False``. EXAMPLES:: @@ -4760,7 +4759,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def is_integer(self): """ - Returns ``True`` as they are integers + Return ``True`` as they are integers EXAMPLES:: @@ -4771,7 +4770,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def is_unit(self): r""" - Returns ``true`` if this integer is a unit, i.e., 1 or `-1`. + Return ``True`` if this integer is a unit, i.e., `1` or `-1`. EXAMPLES:: @@ -4787,7 +4786,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def is_square(self): r""" - Returns ``True`` if self is a perfect square. + Return ``True`` if ``self`` is a perfect square. EXAMPLES:: @@ -4800,7 +4799,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def perfect_power(self): r""" - Returns ``(a, b)``, where this integer is `a^b` and `b` is maximal. + Return ``(a, b)``, where this integer is `a^b` and `b` is maximal. If called on `-1`, `0` or `1`, `b` will be `1`, since there is no maximal value of `b`. @@ -4815,23 +4814,23 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: - sage: 144.perfect_power() # optional - sage.libs.pari + sage: 144.perfect_power() # optional - sage.libs.pari (12, 2) - sage: 1.perfect_power() # optional - sage.libs.pari + sage: 1.perfect_power() # optional - sage.libs.pari (1, 1) - sage: 0.perfect_power() # optional - sage.libs.pari + sage: 0.perfect_power() # optional - sage.libs.pari (0, 1) - sage: (-1).perfect_power() # optional - sage.libs.pari + sage: (-1).perfect_power() # optional - sage.libs.pari (-1, 1) - sage: (-8).perfect_power() # optional - sage.libs.pari + sage: (-8).perfect_power() # optional - sage.libs.pari (-2, 3) - sage: (-4).perfect_power() # optional - sage.libs.pari + sage: (-4).perfect_power() # optional - sage.libs.pari (-4, 1) - sage: (101^29).perfect_power() # optional - sage.libs.pari + sage: (101^29).perfect_power() # optional - sage.libs.pari (101, 29) - sage: (-243).perfect_power() # optional - sage.libs.pari + sage: (-243).perfect_power() # optional - sage.libs.pari (-3, 5) - sage: (-64).perfect_power() # optional - sage.libs.pari + sage: (-64).perfect_power() # optional - sage.libs.pari (-4, 3) """ parians = self.__pari__().ispower() @@ -4839,7 +4838,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def global_height(self, prec=None): r""" - Returns the absolute logarithmic height of this rational integer. + Return the absolute logarithmic height of this rational integer. INPUT: @@ -4874,10 +4873,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cdef bint _is_power_of(Integer self, Integer n): r""" - Returns a non-zero int if there is an integer b with + Return a non-zero int if there is an integer b with `\mathtt{self} = n^b`. - For more documentation see ``is_power_of``. + For more documentation see :meth:`is_power_of`. AUTHORS: @@ -4994,7 +4993,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def is_power_of(Integer self, n): r""" - Returns ``True`` if there is an integer b with + Return ``True`` if there is an integer `b` with `\mathtt{self} = n^b`. .. SEEALSO:: @@ -5038,8 +5037,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): .. NOTE:: - For large integers self, is_power_of() is faster than - is_perfect_power(). The following examples gives some indication of + For large integers ``self``, :meth:`is_power_of` is faster than + :meth:`is_perfect_power`. The following examples give some indication of how much faster. :: @@ -5047,15 +5046,15 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: b = lcm(range(1,10000)) sage: b.exact_log(2) 14446 - sage: t=cputime() + sage: t = cputime() sage: for a in range(2, 1000): k = b.is_perfect_power() sage: cputime(t) # random 0.53203299999999976 - sage: t=cputime() + sage: t = cputime() sage: for a in range(2, 1000): k = b.is_power_of(2) sage: cputime(t) # random 0.0 - sage: t=cputime() + sage: t = cputime() sage: for a in range(2, 1000): k = b.is_power_of(3) sage: cputime(t) # random 0.032002000000000308 @@ -5065,19 +5064,20 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: b = lcm(range(1, 1000)) sage: b.exact_log(2) 1437 - sage: t=cputime() - sage: for a in range(2, 10000): k = b.is_perfect_power() # note that we change the range from the example above + sage: t = cputime() + sage: for a in range(2, 10000): # note: changed range from the example above + ....: k = b.is_perfect_power() sage: cputime(t) # random 0.17201100000000036 - sage: t=cputime(); TWO=int(2) + sage: t = cputime(); TWO = int(2) sage: for a in range(2, 10000): k = b.is_power_of(TWO) sage: cputime(t) # random 0.0040000000000000036 - sage: t=cputime() + sage: t = cputime() sage: for a in range(2, 10000): k = b.is_power_of(3) sage: cputime(t) # random 0.040003000000000011 - sage: t=cputime() + sage: t = cputime() sage: for a in range(2, 10000): k = b.is_power_of(a) sage: cputime(t) # random 0.02800199999999986 @@ -5118,55 +5118,55 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: - sage: 17.is_prime_power() # optional - sage.libs.pari + sage: 17.is_prime_power() # optional - sage.libs.pari True - sage: 10.is_prime_power() # optional - sage.libs.pari + sage: 10.is_prime_power() # optional - sage.libs.pari False - sage: 64.is_prime_power() # optional - sage.libs.pari + sage: 64.is_prime_power() # optional - sage.libs.pari True - sage: (3^10000).is_prime_power() # optional - sage.libs.pari + sage: (3^10000).is_prime_power() # optional - sage.libs.pari True - sage: (10000).is_prime_power() # optional - sage.libs.pari + sage: (10000).is_prime_power() # optional - sage.libs.pari False - sage: (-3).is_prime_power() # optional - sage.libs.pari + sage: (-3).is_prime_power() # optional - sage.libs.pari False - sage: 0.is_prime_power() # optional - sage.libs.pari + sage: 0.is_prime_power() # optional - sage.libs.pari False - sage: 1.is_prime_power() # optional - sage.libs.pari + sage: 1.is_prime_power() # optional - sage.libs.pari False - sage: p = next_prime(10^20); p # optional - sage.libs.pari + sage: p = next_prime(10^20); p # optional - sage.libs.pari 100000000000000000039 - sage: p.is_prime_power() # optional - sage.libs.pari + sage: p.is_prime_power() # optional - sage.libs.pari True - sage: (p^97).is_prime_power() # optional - sage.libs.pari + sage: (p^97).is_prime_power() # optional - sage.libs.pari True - sage: (p+1).is_prime_power() # optional - sage.libs.pari + sage: (p + 1).is_prime_power() # optional - sage.libs.pari False With the ``get_data`` keyword set to ``True``:: - sage: (3^100).is_prime_power(get_data=True) # optional - sage.libs.pari + sage: (3^100).is_prime_power(get_data=True) # optional - sage.libs.pari (3, 100) - sage: 12.is_prime_power(get_data=True) # optional - sage.libs.pari + sage: 12.is_prime_power(get_data=True) # optional - sage.libs.pari (12, 0) - sage: (p^97).is_prime_power(get_data=True) # optional - sage.libs.pari + sage: (p^97).is_prime_power(get_data=True) # optional - sage.libs.pari (100000000000000000039, 97) - sage: q = p.next_prime(); q # optional - sage.libs.pari + sage: q = p.next_prime(); q # optional - sage.libs.pari 100000000000000000129 - sage: (p*q).is_prime_power(get_data=True) # optional - sage.libs.pari + sage: (p*q).is_prime_power(get_data=True) # optional - sage.libs.pari (10000000000000000016800000000000000005031, 0) - The method works for large entries when `proof=False`:: + The method works for large entries when ``proof=False``:: sage: proof.arithmetic(False) - sage: ((10^500 + 961)^4).is_prime_power() # optional - sage.libs.pari + sage: ((10^500 + 961)^4).is_prime_power() # optional - sage.libs.pari True sage: proof.arithmetic(True) We check that :trac:`4777` is fixed:: sage: n = 150607571^14 - sage: n.is_prime_power() # optional - sage.libs.pari + sage: n.is_prime_power() # optional - sage.libs.pari True """ if mpz_sgn(self.value) <= 0: @@ -5226,9 +5226,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``proof`` -- Boolean or ``None`` (default). If False, use a + - ``proof`` -- Boolean or ``None`` (default). If ``False``, use a strong pseudo-primality test (see :meth:`is_pseudoprime`). - If True, use a provable primality test. If unset, use the + If ``True``, use a provable primality test. If unset, use the :mod:`default arithmetic proof flag `. .. NOTE:: @@ -5240,26 +5240,26 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: sage: z = 2^31 - 1 - sage: z.is_prime() # optional - sage.libs.pari + sage: z.is_prime() # optional - sage.libs.pari True sage: z = 2^31 - sage: z.is_prime() # optional - sage.libs.pari + sage: z.is_prime() # optional - sage.libs.pari False sage: z = 7 - sage: z.is_prime() # optional - sage.libs.pari + sage: z.is_prime() # optional - sage.libs.pari True sage: z = -7 - sage: z.is_prime() # optional - sage.libs.pari + sage: z.is_prime() # optional - sage.libs.pari False - sage: z.is_irreducible() # optional - sage.libs.pari + sage: z.is_irreducible() # optional - sage.libs.pari True :: sage: z = 10^80 + 129 - sage: z.is_prime(proof=False) # optional - sage.libs.pari + sage: z.is_prime(proof=False) # optional - sage.libs.pari True - sage: z.is_prime(proof=True) # optional - sage.libs.pari + sage: z.is_prime(proof=True) # optional - sage.libs.pari True When starting Sage the arithmetic proof flag is True. We can change @@ -5268,17 +5268,17 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: proof.arithmetic() True sage: n = 10^100 + 267 - sage: timeit("n.is_prime()") # not tested # optional - sage.libs.pari + sage: timeit("n.is_prime()") # not tested # optional - sage.libs.pari 5 loops, best of 3: 163 ms per loop sage: proof.arithmetic(False) sage: proof.arithmetic() False - sage: timeit("n.is_prime()") # not tested # optional - sage.libs.pari + sage: timeit("n.is_prime()") # not tested # optional - sage.libs.pari 1000 loops, best of 3: 573 us per loop ALGORITHM: - Calls the PARI ``isprime`` function. + Calls the PARI function :pari:`isprime`. TESTS: @@ -5290,7 +5290,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): ....: if tab[i]: ....: for j in range(2*i, size, i): ....: tab[j] = 0 - sage: all(ZZ(i).is_prime() == b for i,b in enumerate(tab)) # optional - sage.libs.pari + sage: all(ZZ(i).is_prime() == b for i,b in enumerate(tab)) # optional - sage.libs.pari True """ if mpz_sgn(self.value) <= 0: @@ -5329,7 +5329,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): - ``self`` -- A PARI pseudoprime - - ``proof`` -- Mandatory proof flag (True, False or None) + - ``proof`` -- Mandatory proof flag (``True``, ``False`` or ``None``) OUTPUT: @@ -5347,22 +5347,22 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def is_irreducible(self): r""" - Returns ``True`` if self is irreducible, i.e. +/- + Return ``True`` if ``self`` is irreducible, i.e. +/- prime EXAMPLES:: sage: z = 2^31 - 1 - sage: z.is_irreducible() # optional - sage.libs.pari + sage: z.is_irreducible() # optional - sage.libs.pari True sage: z = 2^31 - sage: z.is_irreducible() # optional - sage.libs.pari + sage: z.is_irreducible() # optional - sage.libs.pari False sage: z = 7 - sage: z.is_irreducible() # optional - sage.libs.pari + sage: z.is_irreducible() # optional - sage.libs.pari True sage: z = -7 - sage: z.is_irreducible() # optional - sage.libs.pari + sage: z.is_irreducible() # optional - sage.libs.pari True """ cdef Integer n = self if self >= 0 else -self @@ -5374,7 +5374,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): This uses PARI's Baillie-PSW probabilistic primality test. Currently, there are no known pseudoprimes for - Baillie-PSW that are not actually prime. However it is + Baillie-PSW that are not actually prime. However, it is conjectured that there are infinitely many. See :wikipedia:`Baillie-PSW_primality_test` @@ -5382,10 +5382,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: sage: z = 2^31 - 1 - sage: z.is_pseudoprime() # optional - sage.libs.pari + sage: z.is_pseudoprime() # optional - sage.libs.pari True sage: z = 2^31 - sage: z.is_pseudoprime() # optional - sage.libs.pari + sage: z.is_pseudoprime() # optional - sage.libs.pari False """ return self.__pari__().ispseudoprime() @@ -5406,17 +5406,17 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: sage: x = 10^200 + 357 - sage: x.is_pseudoprime() # optional - sage.libs.pari + sage: x.is_pseudoprime() # optional - sage.libs.pari True - sage: (x^12).is_pseudoprime_power() # optional - sage.libs.pari + sage: (x^12).is_pseudoprime_power() # optional - sage.libs.pari True - sage: (x^12).is_pseudoprime_power(get_data=True) # optional - sage.libs.pari + sage: (x^12).is_pseudoprime_power(get_data=True) # optional - sage.libs.pari (1000...000357, 12) - sage: (997^100).is_pseudoprime_power() # optional - sage.libs.pari + sage: (997^100).is_pseudoprime_power() # optional - sage.libs.pari True - sage: (998^100).is_pseudoprime_power() # optional - sage.libs.pari + sage: (998^100).is_pseudoprime_power() # optional - sage.libs.pari False - sage: ((10^1000 + 453)^2).is_pseudoprime_power() # optional - sage.libs.pari + sage: ((10^1000 + 453)^2).is_pseudoprime_power() # optional - sage.libs.pari True TESTS:: @@ -5425,21 +5425,21 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): False sage: (-1).is_pseudoprime_power() False - sage: 1.is_pseudoprime_power() # optional - sage.libs.pari + sage: 1.is_pseudoprime_power() # optional - sage.libs.pari False """ return self.is_prime_power(proof=False, get_data=get_data) def is_perfect_power(self): r""" - Returns ``True`` if ``self`` is a perfect power, ie if there exist integers + Return ``True`` if ``self`` is a perfect power, ie if there exist integers `a` and `b`, `b > 1` with ``self`` `= a^b`. .. SEEALSO:: - :meth:`perfect_power`: Finds the minimal base for which this integer is a perfect power. - - :meth:`is_power_of`: If you know the base already this method is + - :meth:`is_power_of`: If you know the base already, this method is the fastest option. - :meth:`is_prime_power`: Checks whether the base is prime. @@ -5492,20 +5492,20 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: - sage: K = NumberField(x^2 - 2, 'beta') # optional - sage.rings.number_field + sage: K = NumberField(x^2 - 2, 'beta') # optional - sage.rings.number_field sage: n = 4 - sage: n.is_norm(K) # optional - sage.rings.number_field + sage: n.is_norm(K) # optional - sage.rings.number_field True - sage: 5.is_norm(K) # optional - sage.rings.number_field + sage: 5.is_norm(K) # optional - sage.rings.number_field False sage: 7.is_norm(QQ) True - sage: n.is_norm(K, element=True) # optional - sage.rings.number_field + sage: n.is_norm(K, element=True) # optional - sage.rings.number_field (True, -4*beta + 6) - sage: n.is_norm(K, element=True)[1].norm() # optional - sage.rings.number_field + sage: n.is_norm(K, element=True)[1].norm() # optional - sage.rings.number_field 4 sage: n = 5 - sage: n.is_norm(K, element=True) # optional - sage.rings.number_field + sage: n.is_norm(K, element=True) # optional - sage.rings.number_field (False, None) sage: n = 7 sage: n.is_norm(QQ, element=True) @@ -5521,9 +5521,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: - sage: 3._bnfisnorm(QuadraticField(-1, 'i')) # optional - sage.rings.number_field + sage: 3._bnfisnorm(QuadraticField(-1, 'i')) # optional - sage.rings.number_field (1, 3) - sage: 7._bnfisnorm(CyclotomicField(7)) # optional - sage.rings.number_field + sage: 7._bnfisnorm(CyclotomicField(7)) # optional - sage.rings.number_field (zeta7^5 - zeta7^2, 1) """ from sage.rings.rational_field import QQ @@ -5531,7 +5531,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def jacobi(self, b): r""" - Calculate the Jacobi symbol `\left(\frac{self}{b}\right)`. + Calculate the Jacobi symbol `\left(\frac{\text{self}}{b}\right)`. EXAMPLES:: @@ -5568,9 +5568,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def kronecker(self, b): r""" - Calculate the Kronecker symbol `\left(\frac{self}{b}\right)` - with the Kronecker extension `(self/2)=(2/self)` when `self` is odd, - or `(self/2)=0` when `self` is even. + Calculate the Kronecker symbol `\left(\frac{\text{self}}{b}\right)` + with the Kronecker extension `(\text{self}/2)=(2/\text{self})` when ``self`` is odd, + or `(\text{self}/2)=0` when ``self`` is even. EXAMPLES:: @@ -5599,13 +5599,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``self`` -- an integer congruent to `0` or `1\mod4` which is + - ``self`` -- an integer congruent to `0` or `1` mod `4` which is not a square - - ``proof`` (boolean, default ``True``) -- if ``False`` then + - ``proof`` (boolean, default ``True``) -- if ``False``, then for negative discriminants a faster algorithm is used by the PARI library which is known to give incorrect results - when the class group has many cyclic factors. However the + when the class group has many cyclic factors. However, the results are correct for discriminants `D` with `|D|\le 2\cdot10^{10}`. OUTPUT: @@ -5624,11 +5624,11 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: - sage: (-163).class_number() # optional - sage.libs.pari + sage: (-163).class_number() # optional - sage.libs.pari 1 - sage: (-104).class_number() # optional - sage.libs.pari + sage: (-104).class_number() # optional - sage.libs.pari 6 - sage: [((4*n+1),(4*n+1).class_number()) for n in [21..29]] # optional - sage.libs.pari + sage: [((4*n + 1), (4*n + 1).class_number()) for n in [21..29]] # optional - sage.libs.pari [(85, 2), (89, 1), (93, 1), @@ -5641,7 +5641,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): TESTS: - The integer must not be a square or an error is raised:: + The integer must not be a square, or an error is raised:: sage: 100.class_number() Traceback (most recent call last): @@ -5649,7 +5649,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): ValueError: class_number not defined for square integers - The integer must be 0 or 1 mod 4 or an error is raised:: + The integer must be 0 or 1 mod 4, or an error is raised:: sage: 10.class_number() Traceback (most recent call last): @@ -5678,7 +5678,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): Use ``self.radical()`` for the product of the primes that divide self. - If self is 0, just returns 0. + If ``self`` is 0, just returns 0. EXAMPLES:: @@ -5710,8 +5710,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): 2 sage: a.squarefree_part(bound=2**14) 2 - sage: a = 7^3 * next_prime(2^100)^2 * next_prime(2^200) # optional - sage.libs.pari - sage: a / a.squarefree_part(bound=1000) # optional - sage.libs.pari + sage: a = 7^3 * next_prime(2^100)^2 * next_prime(2^200) # optional - sage.libs.pari + sage: a / a.squarefree_part(bound=1000) # optional - sage.libs.pari 49 """ cdef Integer z @@ -5754,56 +5754,56 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def next_probable_prime(self): """ - Return the next probable prime after self, as determined by PARI. + Return the next probable prime after ``self``, as determined by PARI. EXAMPLES:: - sage: (-37).next_probable_prime() # optional - sage.libs.pari + sage: (-37).next_probable_prime() # optional - sage.libs.pari 2 - sage: (100).next_probable_prime() # optional - sage.libs.pari + sage: (100).next_probable_prime() # optional - sage.libs.pari 101 - sage: (2^512).next_probable_prime() # optional - sage.libs.pari + sage: (2^512).next_probable_prime() # optional - sage.libs.pari 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084171 - sage: 0.next_probable_prime() # optional - sage.libs.pari + sage: 0.next_probable_prime() # optional - sage.libs.pari 2 - sage: 126.next_probable_prime() # optional - sage.libs.pari + sage: 126.next_probable_prime() # optional - sage.libs.pari 127 - sage: 144168.next_probable_prime() # optional - sage.libs.pari + sage: 144168.next_probable_prime() # optional - sage.libs.pari 144169 """ return Integer( self.__pari__().nextprime(True) ) def next_prime(self, proof=None): r""" - Return the next prime after self. + Return the next prime after ``self``. - This method calls the PARI ``nextprime`` function. + This method calls the PARI function :pari:`nextprime`. INPUT: - ``proof`` - bool or None (default: None, see - proof.arithmetic or sage.structure.proof) Note that the global Sage - default is proof=True + ``proof.arithmetic`` or :mod:`sage.structure.proof`) Note that the global Sage + default is ``proof=True`` EXAMPLES:: - sage: 100.next_prime() # optional - sage.libs.pari + sage: 100.next_prime() # optional - sage.libs.pari 101 - sage: (10^50).next_prime() # optional - sage.libs.pari + sage: (10^50).next_prime() # optional - sage.libs.pari 100000000000000000000000000000000000000000000000151 Use ``proof=False``, which is way faster since it does not need a primality proof:: - sage: b = (2^1024).next_prime(proof=False) # optional - sage.libs.pari - sage: b - 2^1024 # optional - sage.libs.pari + sage: b = (2^1024).next_prime(proof=False) # optional - sage.libs.pari + sage: b - 2^1024 # optional - sage.libs.pari 643 :: - sage: Integer(0).next_prime() # optional - sage.libs.pari + sage: Integer(0).next_prime() # optional - sage.libs.pari 2 - sage: Integer(1001).next_prime() # optional - sage.libs.pari + sage: Integer(1001).next_prime() # optional - sage.libs.pari 1009 """ # Use PARI to compute the next *pseudo*-prime @@ -5814,9 +5814,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def previous_prime(self, proof=None): r""" - Returns the previous prime before self. + Return the previous prime before ``self``. - This method calls the PARI ``precprime`` function. + This method calls the PARI function :pari:`precprime`. INPUT: @@ -5832,11 +5832,11 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: - sage: 10.previous_prime() # optional - sage.libs.pari + sage: 10.previous_prime() # optional - sage.libs.pari 7 - sage: 7.previous_prime() # optional - sage.libs.pari + sage: 7.previous_prime() # optional - sage.libs.pari 5 - sage: 14376485.previous_prime() # optional - sage.libs.pari + sage: 14376485.previous_prime() # optional - sage.libs.pari 14376463 sage: 2.previous_prime() @@ -5847,8 +5847,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): An example using ``proof=False``, which is way faster since it does not need a primality proof:: - sage: b = (2^1024).previous_prime(proof=False) # optional - sage.libs.pari - sage: 2^1024 - b # optional - sage.libs.pari + sage: b = (2^1024).previous_prime(proof=False) # optional - sage.libs.pari + sage: 2^1024 - b # optional - sage.libs.pari 105 """ if mpz_cmp_ui(self.value, 2) <= 0: @@ -5862,7 +5862,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def next_prime_power(self, proof=None): r""" - Return the next prime power after self. + Return the next prime power after ``self``. INPUT: @@ -5874,7 +5874,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): ALGORITHM: - The algorithm is naive. It computes the next power of 2 and go through + The algorithm is naive. It computes the next power of 2 and goes through the odd numbers calling :meth:`is_prime_power`. .. SEEALSO:: @@ -5888,23 +5888,23 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: (-1).next_prime_power() 2 - sage: 2.next_prime_power() # optional - sage.libs.pari + sage: 2.next_prime_power() # optional - sage.libs.pari 3 - sage: 103.next_prime_power() # optional - sage.libs.pari + sage: 103.next_prime_power() # optional - sage.libs.pari 107 - sage: 107.next_prime_power() # optional - sage.libs.pari + sage: 107.next_prime_power() # optional - sage.libs.pari 109 - sage: 2044.next_prime_power() # optional - sage.libs.pari + sage: 2044.next_prime_power() # optional - sage.libs.pari 2048 TESTS:: - sage: [(2**k-1).next_prime_power() for k in range(1,10)] # optional - sage.libs.pari + sage: [(2**k - 1).next_prime_power() for k in range(1,10)] # optional - sage.libs.pari [2, 4, 8, 16, 32, 64, 128, 256, 512] - sage: [(2**k).next_prime_power() for k in range(10)] # optional - sage.libs.pari + sage: [(2**k).next_prime_power() for k in range(10)] # optional - sage.libs.pari [2, 3, 5, 9, 17, 37, 67, 131, 257, 521] - sage: for _ in range(10): # optional - sage.libs.pari + sage: for _ in range(10): # optional - sage.libs.pari ....: n = ZZ.random_element(2**256).next_prime_power() ....: m = n.next_prime_power().previous_prime_power() ....: assert m == n, "problem with n = {}".format(n) @@ -5928,7 +5928,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def previous_prime_power(self, proof=None): r""" - Return the previous prime power before self. + Return the previous prime power before ``self``. INPUT: @@ -5940,7 +5940,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): ALGORITHM: - The algorithm is naive. It computes the previous power of 2 and go + The algorithm is naive. It computes the previous power of 2 and goes through the odd numbers calling the method :meth:`is_prime_power`. .. SEEALSO:: @@ -5952,13 +5952,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: - sage: 3.previous_prime_power() # optional - sage.libs.pari + sage: 3.previous_prime_power() # optional - sage.libs.pari 2 - sage: 103.previous_prime_power() # optional - sage.libs.pari + sage: 103.previous_prime_power() # optional - sage.libs.pari 101 - sage: 107.previous_prime_power() # optional - sage.libs.pari + sage: 107.previous_prime_power() # optional - sage.libs.pari 103 - sage: 2044.previous_prime_power() # optional - sage.libs.pari + sage: 2044.previous_prime_power() # optional - sage.libs.pari 2039 sage: 2.previous_prime_power() @@ -5968,12 +5968,12 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): TESTS:: - sage: [(2**k+1).previous_prime_power() for k in range(1,10)] # optional - sage.libs.pari + sage: [(2**k + 1).previous_prime_power() for k in range(1,10)] # optional - sage.libs.pari [2, 4, 8, 16, 32, 64, 128, 256, 512] - sage: [(2**k).previous_prime_power() for k in range(2, 10)] # optional - sage.libs.pari + sage: [(2**k).previous_prime_power() for k in range(2, 10)] # optional - sage.libs.pari [3, 7, 13, 31, 61, 127, 251, 509] - sage: for _ in range(10): # optional - sage.libs.pari + sage: for _ in range(10): # optional - sage.libs.pari ....: n = ZZ.random_element(3,2**256).previous_prime_power() ....: m = n.previous_prime_power().next_prime_power() ....: assert m == n, "problem with n = {}".format(n) @@ -5999,7 +5999,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def additive_order(self): """ - Return the additive order of self. + Return the additive order of ``self``. EXAMPLES:: @@ -6015,7 +6015,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def multiplicative_order(self): r""" - Return the multiplicative order of self. + Return the multiplicative order of ``self``. EXAMPLES:: @@ -6037,23 +6037,23 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def is_squarefree(self): """ - Returns True if this integer is not divisible by the square of any - prime and False otherwise. + Return ``True`` if this integer is not divisible by the square of any + prime and ``False`` otherwise. EXAMPLES:: - sage: 100.is_squarefree() # optional - sage.libs.pari + sage: 100.is_squarefree() # optional - sage.libs.pari False - sage: 102.is_squarefree() # optional - sage.libs.pari + sage: 102.is_squarefree() # optional - sage.libs.pari True - sage: 0.is_squarefree() # optional - sage.libs.pari + sage: 0.is_squarefree() # optional - sage.libs.pari False """ return self.__pari__().issquarefree() def is_discriminant(self): """ - Returns True if this integer is a discriminant. + Return ``True`` if this integer is a discriminant. .. NOTE:: @@ -6083,7 +6083,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def is_fundamental_discriminant(self): """ - Returns True if this integer is a fundamental_discriminant. + Return ``True`` if this integer is a fundamental discriminant. .. NOTE:: @@ -6120,21 +6120,21 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cpdef __pari__(self): """ - Returns the PARI version of this integer. + Return the PARI version of this integer. EXAMPLES:: sage: n = 9390823 - sage: m = n.__pari__(); m # optional - sage.libs.pari + sage: m = n.__pari__(); m # optional - sage.libs.pari 9390823 - sage: type(m) # optional - sage.libs.pari + sage: type(m) # optional - sage.libs.pari TESTS:: sage: n = 10^10000000 - sage: m = n.__pari__() # crash from trac 875 # optional - sage.libs.pari - sage: m % 1234567 # optional - sage.libs.pari + sage: m = n.__pari__() # crash from trac 875 # optional - sage.libs.pari + sage: m % 1234567 # optional - sage.libs.pari 1041334 """ @@ -6164,19 +6164,19 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): EXAMPLES:: - sage: import numpy - sage: numpy.array([1, 2, 3]) + sage: import numpy # optional - numpy + sage: numpy.array([1, 2, 3]) # optional - numpy array([1, 2, 3]) - sage: numpy.array([1, 2, 3]).dtype + sage: numpy.array([1, 2, 3]).dtype # optional - numpy dtype('int32') # 32-bit dtype('int64') # 64-bit - sage: numpy.array(2**40).dtype + sage: numpy.array(2**40).dtype # optional - numpy dtype('int64') - sage: numpy.array(2**400).dtype + sage: numpy.array(2**400).dtype # optional - numpy dtype('O') - sage: numpy.array([1,2,3,0.1]).dtype + sage: numpy.array([1,2,3,0.1]).dtype # optional - numpy dtype('float64') """ if mpz_fits_slong_p(self.value): @@ -6258,9 +6258,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def sqrtrem(self): r""" - Return (s, r) where s is the integer square root of self and - r is the remainder such that `\text{self} = s^2 + r`. - Raises ``ValueError`` if self is negative. + Return `(s, r)` where `s` is the integer square root of ``self`` and + `r` is the remainder such that `\text{self} = s^2 + r`. + Raises :class:`ValueError` if ``self`` is negative. EXAMPLES:: @@ -6288,8 +6288,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def isqrt(self): r""" - Returns the integer floor of the square root of self, or raises an - ``ValueError`` if self is negative. + Return the integer floor of the square root of ``self``, or raises an + :class:`ValueError` if ``self`` is negative. EXAMPLES:: @@ -6321,17 +6321,17 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): INPUT: - - ``prec`` - integer (default: None): if None, return an exact + - ``prec`` -- integer (default: ``None``): if ``None``, return an exact square root; otherwise return a numerical square root, to the given bits of precision. - - ``extend`` - bool (default: True); if True, return a + - ``extend`` -- bool (default: ``True``); if ``True``, return a square root in an extension ring, if necessary. Otherwise, raise a - ValueError if the square is not in the base ring. Ignored if prec - is not None. + :class:`ValueError` if the square is not in the base ring. Ignored if ``prec`` + is not ``None``. - - ``all`` - bool (default: False); if True, return all - square roots of self (a list of length 0, 1 or 2). + - ``all`` - bool (default: ``False``); if ``True``, return all + square roots of ``self`` (a list of length 0, 1, or 2). EXAMPLES:: @@ -6339,13 +6339,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): 12 sage: sqrt(Integer(144)) 12 - sage: Integer(102).sqrt() # optional - sage.symbolic + sage: Integer(102).sqrt() # optional - sage.symbolic sqrt(102) :: sage: n = 2 - sage: n.sqrt(all=True) # optional - sage.symbolic + sage: n.sqrt(all=True) # optional - sage.symbolic [sqrt(2), -sqrt(2)] sage: n.sqrt(prec=10) 1.4 @@ -6368,7 +6368,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): TESTS:: - sage: type(5.sqrt()) # optional - sage.symbolic + sage: type(5.sqrt()) # optional - sage.symbolic sage: type(5.sqrt(prec=53)) @@ -6586,12 +6586,12 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cpdef _shift_helper(Integer self, y, int sign): """ - Function used to compute left and right shifts of integers. - Shifts self y bits to the left if sign is 1, and to the right - if sign is -1. + Compute left and right shifts of integers. + Shifts ``self`` ``y`` bits to the left if ``sign`` is `1`, and to the right + if ``sign`` is `-1`. WARNING: This function does no error checking. In particular, - it assumes that sign is either 1 or -1, + it assumes that ``sign`` is either `1` or `-1`. EXAMPLES:: @@ -6768,7 +6768,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def __invert__(self): """ - Return the multiplicative inverse of self, as a rational number. + Return the multiplicative inverse of ``self``, as a rational number. EXAMPLES:: @@ -6794,8 +6794,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def inverse_of_unit(self): """ - Return inverse of self if self is a unit in the integers, i.e., - self is -1 or 1. Otherwise, raise a ZeroDivisionError. + Return inverse of ``self`` if ``self`` is a unit in the integers, i.e., + ``self`` is `-1` or `1`. Otherwise, raise a :class:`ZeroDivisionError`. EXAMPLES:: @@ -6819,9 +6819,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def inverse_mod(self, n): r""" - Return the inverse of self modulo `n`, if this inverse exists. + Return the inverse of ``self`` modulo `n`, if this inverse exists. - Otherwise, raises a ``ZeroDivisionError`` exception. + Otherwise, raise a :class:`ZeroDivisionError` exception. INPUT: @@ -6836,7 +6836,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): IMPLEMENTATION: - Call the mpz_invert GMP library function. + Call the ``mpz_invert`` GMP library function. EXAMPLES:: @@ -6942,7 +6942,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def popcount(self): """ Return the number of 1 bits in the binary representation. - If self<0, we return Infinity. + If ``self`` < 0, we return Infinity. EXAMPLES:: @@ -6976,7 +6976,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): def binomial(self, m, algorithm='gmp'): """ - Return the binomial coefficient "self choose m". + Return the binomial coefficient "``self`` choose ``m``". INPUT: @@ -6986,15 +6986,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): ``gmp``), or ``'pari'``; ``'gmp'`` is faster for small ``m``, and ``'pari'`` tends to be faster for large ``m`` - OUTPUT: - - - integer + OUTPUT: integer EXAMPLES:: sage: 10.binomial(2) 45 - sage: 10.binomial(2, algorithm='pari') # optional - sage.libs.pari + sage: 10.binomial(2, algorithm='pari') # optional - sage.libs.pari 45 sage: 10.binomial(-2) 0 @@ -7003,11 +7001,11 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: (-3).binomial(0) 1 - The argument ``m`` or (``self-m``) must fit into unsigned long:: + The argument ``m`` or (``self - m``) must fit into an ``unsigned long``:: sage: (2**256).binomial(2**256) 1 - sage: (2**256).binomial(2**256-1) + sage: (2**256).binomial(2**256 - 1) 115792089237316195423570985008687907853269984665640564039457584007913129639936 sage: (2**256).binomial(2**128) Traceback (most recent call last): @@ -7036,7 +7034,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): check for reliable interrupting, see :trac:`18919`:: sage: from cysignals import AlarmInterrupt - sage: for i in [1..10]: # long time (5s) # optional - sage.libs.pari + sage: for i in [1..10]: # long time (5s) # optional - sage.libs.pari ....: try: ....: alarm(i/11) ....: (2^100).binomial(2^22, algorithm='pari') @@ -7287,7 +7285,7 @@ def GCD_list(v): @cython.binding(True) def make_integer(s): """ - Create a Sage integer from the base-32 Python *string* s. This is + Create a Sage integer from the base-32 Python *string* ``s``. This is used in unpickling integers. EXAMPLES:: @@ -7360,7 +7358,7 @@ cdef class int_to_Z(Morphism): cpdef Element _call_(self, a): """ - Returns a new integer with the same value as a. + Return a new integer with the same value as ``a``. TESTS:: @@ -7433,7 +7431,7 @@ _mpz_realloc(global_dummy_Integer.value, 1) def _check_global_dummy_Integer(): """ - Return true if the global dummy Integer is ok. + Return ``True`` if the global dummy :class:`Integer` is ok. TESTS:: diff --git a/src/sage/rings/integer_ring.pyx b/src/sage/rings/integer_ring.pyx index 09b239a7dea..8a307b3988c 100644 --- a/src/sage/rings/integer_ring.pyx +++ b/src/sage/rings/integer_ring.pyx @@ -126,8 +126,8 @@ cdef class IntegerRing_class(PrincipalIdealDomain): False sage: Z.category() Join of Category of euclidean domains - and Category of infinite enumerated sets - and Category of metric spaces + and Category of infinite enumerated sets + and Category of metric spaces sage: Z(2^(2^5) + 1) 4294967297 @@ -151,9 +151,9 @@ cdef class IntegerRing_class(PrincipalIdealDomain): The lists are interpreted in little-endian order, so that entry ``i`` of the list is the coefficient of ``base^i``:: - sage: Z([4,1,7],base=100) + sage: Z([4,1,7], base=100) 70104 - sage: Z([4,1,7],base=10) + sage: Z([4,1,7], base=10) 714 sage: Z([3, 7], 10) 73 @@ -166,13 +166,13 @@ cdef class IntegerRing_class(PrincipalIdealDomain): ``z`` represent numbers 10 to 36. Letter case does not matter. :: - sage: Z("sage",base=32) + sage: Z("sage", base=32) 928270 - sage: Z("SAGE",base=32) + sage: Z("SAGE", base=32) 928270 - sage: Z("Sage",base=32) + sage: Z("Sage", base=32) 928270 - sage: Z([14, 16, 10, 28],base=32) + sage: Z([14, 16, 10, 28], base=32) 928270 sage: 14 + 16*32 + 10*32^2 + 28*32^3 928270 @@ -248,23 +248,23 @@ cdef class IntegerRing_class(PrincipalIdealDomain): 17 sage: Z(Mod(19,23)) 19 - sage: Z(2 + 3*5 + O(5^3)) + sage: Z(2 + 3*5 + O(5^3)) # optional - sage.rings.padics 17 Arbitrary numeric bases are supported; strings or list of integers are used to provide the digits (more details in :class:`IntegerRing_class`):: - sage: Z("sage",base=32) + sage: Z("sage", base=32) 928270 - sage: Z([14, 16, 10, 28],base=32) + sage: Z([14, 16, 10, 28], base=32) 928270 The :meth:`digits<~sage.rings.integer.Integer.digits>` method allows you to get the list of digits of an integer in a different basis (note that the digits are returned in little-endian order):: - sage: b = Z([4,1,7],base=100) + sage: b = Z([4,1,7], base=100) sage: b 70104 sage: b.digits(base=71) @@ -397,19 +397,19 @@ cdef class IntegerRing_class(PrincipalIdealDomain): EXAMPLES:: - sage: ZZ[sqrt(2), sqrt(3)] + sage: ZZ[sqrt(2), sqrt(3)] # optional - sage.rings.number_field sage.symbolic Relative Order in Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field sage: ZZ['x'] Univariate Polynomial Ring in x over Integer Ring sage: ZZ['x,y'] Multivariate Polynomial Ring in x, y over Integer Ring - sage: R = ZZ[sqrt(5) + 1]; R + sage: R = ZZ[sqrt(5) + 1]; R # optional - sage.rings.number_field sage.symbolic Order in Number Field in a with defining polynomial x^2 - 2*x - 4 with a = 3.236067977499790? - sage: R.is_maximal() + sage: R.is_maximal() # optional - sage.rings.number_field sage.symbolic False - sage: R = ZZ[(1+sqrt(5))/2]; R + sage: R = ZZ[(1 + sqrt(5))/2]; R # optional - sage.rings.number_field sage.symbolic Order in Number Field in a with defining polynomial x^2 - x - 1 with a = 1.618033988749895? - sage: R.is_maximal() + sage: R.is_maximal() # optional - sage.rings.number_field sage.symbolic True """ if x in self: @@ -433,23 +433,25 @@ cdef class IntegerRing_class(PrincipalIdealDomain): sage: ZZ.range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - sage: ZZ.range(-5,5) + sage: ZZ.range(-5, 5) [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4] - sage: ZZ.range(0,50,5) + sage: ZZ.range(0, 50, 5) [0, 5, 10, 15, 20, 25, 30, 35, 40, 45] - sage: ZZ.range(0,50,-5) + sage: ZZ.range(0, 50, -5) [] - sage: ZZ.range(50,0,-5) + sage: ZZ.range(50, 0, -5) [50, 45, 40, 35, 30, 25, 20, 15, 10, 5] - sage: ZZ.range(50,0,5) + sage: ZZ.range(50, 0, 5) [] - sage: ZZ.range(50,-1,-5) + sage: ZZ.range(50, -1, -5) [50, 45, 40, 35, 30, 25, 20, 15, 10, 5, 0] It uses different code if the step doesn't fit in a long:: - sage: ZZ.range(0,2^83,2^80) - [0, 1208925819614629174706176, 2417851639229258349412352, 3626777458843887524118528, 4835703278458516698824704, 6044629098073145873530880, 7253554917687775048237056, 8462480737302404222943232] + sage: ZZ.range(0, 2^83, 2^80) + [0, 1208925819614629174706176, 2417851639229258349412352, + 3626777458843887524118528, 4835703278458516698824704, 6044629098073145873530880, + 7253554917687775048237056, 8462480737302404222943232] Make sure :trac:`8818` is fixed:: @@ -532,7 +534,7 @@ cdef class IntegerRing_class(PrincipalIdealDomain): sage: ZZ.coerce(int(5)) # indirect doctest 5 - sage: ZZ.coerce(GF(7)(2)) + sage: ZZ.coerce(GF(7)(2)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no canonical coercion from Finite Field of size 7 to Integer Ring @@ -554,14 +556,14 @@ cdef class IntegerRing_class(PrincipalIdealDomain): Coercions are available from numpy integer types:: - sage: import numpy - sage: ZZ.coerce(numpy.int8('1')) + sage: import numpy # optional - numpy + sage: ZZ.coerce(numpy.int8('1')) # optional - numpy 1 - sage: ZZ.coerce(numpy.int32('32')) + sage: ZZ.coerce(numpy.int32('32')) # optional - numpy 32 - sage: ZZ.coerce(numpy.int64('-12')) + sage: ZZ.coerce(numpy.int64('-12')) # optional - numpy -12 - sage: ZZ.coerce(numpy.uint64('11')) + sage: ZZ.coerce(numpy.uint64('11')) # optional - numpy 11 TESTS:: @@ -666,7 +668,8 @@ cdef class IntegerRing_class(PrincipalIdealDomain): ....: counter += 1 ....: dic[ZZ.random_element(*args, **kwds)] += 1 - sage: prob = lambda x : 1/5 + sage: def prob(x): + ....: return 1/5 sage: dic = defaultdict(Integer) sage: counter = 0.0 sage: add_samples(distribution="uniform") @@ -690,7 +693,8 @@ cdef class IntegerRing_class(PrincipalIdealDomain): sage: -10 <= ZZ.random_element(-10, 10) < 10 True - sage: prob = lambda x : 1/20 + sage: def prob(x): + ....: return 1/20 sage: dic = defaultdict(Integer) sage: counter = 0.0 sage: add_samples(-10, 10) @@ -699,7 +703,8 @@ cdef class IntegerRing_class(PrincipalIdealDomain): sage: 0 <= ZZ.random_element(5) < 5 True - sage: prob = lambda x : 1/5 + sage: def prob(x): + ....: return 1/5 sage: dic = defaultdict(Integer) sage: counter = 0.0 sage: add_samples(5) @@ -831,7 +836,7 @@ cdef class IntegerRing_class(PrincipalIdealDomain): True sage: ZZ._is_valid_homomorphism_(ZZ,[2]) False - sage: ZZ._is_valid_homomorphism_(ZZ.quotient_ring(8),[ZZ.quotient_ring(8)(1)]) + sage: ZZ._is_valid_homomorphism_(ZZ.quotient_ring(8), [ZZ.quotient_ring(8)(1)]) True """ if base_map is None: @@ -920,11 +925,11 @@ cdef class IntegerRing_class(PrincipalIdealDomain): EXAMPLES:: - sage: ZZ.extension(x^2-5, 'a') + sage: ZZ.extension(x^2 - 5, 'a') # optional - sage.rings.number_field Order in Number Field in a with defining polynomial x^2 - 5 - sage: ZZ.extension([x^2 + 1, x^2 + 2], 'a,b') - Relative Order in Number Field in a with defining polynomial - x^2 + 1 over its base field + sage: ZZ.extension([x^2 + 1, x^2 + 2], 'a,b') # optional - sage.rings.number_field + Relative Order in Number Field in a + with defining polynomial x^2 + 1 over its base field """ from sage.rings.number_field.order import EquationOrder return EquationOrder(poly, names=names, **kwds) @@ -976,40 +981,40 @@ cdef class IntegerRing_class(PrincipalIdealDomain): EXAMPLES:: - sage: F = ZZ.residue_field(61); F + sage: F = ZZ.residue_field(61); F # optional - sage.libs.pari Residue field of Integers modulo 61 - sage: pi = F.reduction_map(); pi + sage: pi = F.reduction_map(); pi # optional - sage.libs.pari Partially defined reduction map: From: Rational Field To: Residue field of Integers modulo 61 - sage: pi(123/234) + sage: pi(123/234) # optional - sage.libs.pari 6 - sage: pi(1/61) + sage: pi(1/61) # optional - sage.libs.pari Traceback (most recent call last): ... ZeroDivisionError: Cannot reduce rational 1/61 modulo 61: it has negative valuation - sage: lift = F.lift_map(); lift + sage: lift = F.lift_map(); lift # optional - sage.libs.pari Lifting map: From: Residue field of Integers modulo 61 To: Integer Ring - sage: lift(F(12345/67890)) + sage: lift(F(12345/67890)) # optional - sage.libs.pari 33 - sage: (12345/67890) % 61 + sage: (12345/67890) % 61 # optional - sage.libs.pari 33 Construction can be from a prime ideal instead of a prime:: - sage: ZZ.residue_field(ZZ.ideal(97)) + sage: ZZ.residue_field(ZZ.ideal(97)) # optional - sage.libs.pari Residue field of Integers modulo 97 TESTS:: - sage: ZZ.residue_field(ZZ.ideal(96)) + sage: ZZ.residue_field(ZZ.ideal(96)) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: Principal ideal (96) of Integer Ring is not prime - sage: ZZ.residue_field(96) + sage: ZZ.residue_field(96) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: 96 is not prime @@ -1160,7 +1165,7 @@ cdef class IntegerRing_class(PrincipalIdealDomain): sage: ZZ.completion(infinity, 53) Integer Ring - sage: ZZ.completion(5, 15, {'print_mode': 'bars'}) + sage: ZZ.completion(5, 15, {'print_mode': 'bars'}) # optional - sage.rings.padics 5-adic Ring with capped relative precision 15 """ if p == sage.rings.infinity.Infinity: @@ -1275,41 +1280,41 @@ cdef class IntegerRing_class(PrincipalIdealDomain): sage: R. = PolynomialRing(ZZ, sparse=True) sage: p = (x + 1)^23 * (x - 1)^23 * (x - 100) * (x + 5445)^5 - sage: ZZ._roots_univariate_polynomial(p) + sage: ZZ._roots_univariate_polynomial(p) # optional - sage.libs.pari [(100, 1), (-5445, 5), (1, 23), (-1, 23)] sage: p *= (1 + x^3458645 - 76*x^3435423343 + x^45346567867756556) - sage: ZZ._roots_univariate_polynomial(p) + sage: ZZ._roots_univariate_polynomial(p) # optional - sage.libs.pari [(1, 23), (-1, 23), (100, 1), (-5445, 5)] sage: p *= x^156468451540687043504386074354036574634735074 - sage: ZZ._roots_univariate_polynomial(p) + sage: ZZ._roots_univariate_polynomial(p) # optional - sage.libs.pari [(0, 156468451540687043504386074354036574634735074), (1, 23), (-1, 23), (100, 1), (-5445, 5)] - sage: ZZ._roots_univariate_polynomial(p, multiplicities=False) + sage: ZZ._roots_univariate_polynomial(p, multiplicities=False) # optional - sage.libs.pari [0, 1, -1, 100, -5445] sage: R. = PolynomialRing(ZZ, sparse=False) sage: p = (x + 1)^23 * (x - 1)^23 * (x - 100) * (x + 5445)^5 - sage: ZZ._roots_univariate_polynomial(p) + sage: ZZ._roots_univariate_polynomial(p) # optional - sage.libs.pari [(100, 1), (-5445, 5), (1, 23), (-1, 23)] - sage: ZZ._roots_univariate_polynomial(p, multiplicities=False) + sage: ZZ._roots_univariate_polynomial(p, multiplicities=False) # optional - sage.libs.pari [100, -5445, 1, -1] - sage: ZZ._roots_univariate_polynomial(p, algorithm="sparse") + sage: ZZ._roots_univariate_polynomial(p, algorithm="sparse") # optional - sage.libs.pari [(100, 1), (-5445, 5), (1, 23), (-1, 23)] - sage: ZZ._roots_univariate_polynomial(p, algorithm="dense") + sage: ZZ._roots_univariate_polynomial(p, algorithm="dense") # optional - sage.libs.pari [(100, 1), (-5445, 5), (1, 23), (-1, 23)] - sage: ZZ._roots_univariate_polynomial(p, algorithm="foobar") + sage: ZZ._roots_univariate_polynomial(p, algorithm="foobar") # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: unknown algorithm 'foobar' sage: p = x^20 * p - sage: ZZ._roots_univariate_polynomial(p, algorithm="sparse") + sage: ZZ._roots_univariate_polynomial(p, algorithm="sparse") # optional - sage.libs.pari [(0, 20), (100, 1), (-5445, 5), (1, 23), (-1, 23)] - sage: ZZ._roots_univariate_polynomial(p, algorithm="dense") + sage: ZZ._roots_univariate_polynomial(p, algorithm="dense") # optional - sage.libs.pari [(100, 1), (-5445, 5), (0, 20), (1, 23), (-1, 23)] """ deg = p.degree() @@ -1462,7 +1467,7 @@ cdef class IntegerRing_class(PrincipalIdealDomain): EXAMPLES:: - sage: gap(ZZ) # indirect doctest + sage: gap(ZZ) # indirect doctest # optional - sage.libs.gap Integers """ return 'Integers' @@ -1495,7 +1500,7 @@ cdef class IntegerRing_class(PrincipalIdealDomain): EXAMPLES:: - sage: macaulay2(ZZ) #optional - macaulay2 + sage: macaulay2(ZZ) # optional - macaulay2 ZZ """ return "ZZ" @@ -1518,7 +1523,7 @@ cdef class IntegerRing_class(PrincipalIdealDomain): EXAMPLES:: - sage: ZZ._sympy_() + sage: ZZ._sympy_() # optional - sympy Integers """ from sympy import Integers @@ -1548,9 +1553,9 @@ cdef class IntegerRing_class(PrincipalIdealDomain): EXAMPLES:: - sage: v = ZZ.valuation(3); v + sage: v = ZZ.valuation(3); v # optional - sage.rings.padics 3-adic valuation - sage: v(3) + sage: v(3) # optional - sage.rings.padics 1 .. SEEALSO:: diff --git a/src/sage/rings/invariants/invariant_theory.py b/src/sage/rings/invariants/invariant_theory.py index 2f6850f97cc..a64e7473c3a 100644 --- a/src/sage/rings/invariants/invariant_theory.py +++ b/src/sage/rings/invariants/invariant_theory.py @@ -140,15 +140,15 @@ def _guess_variables(polynomial, *args): sage: from sage.rings.invariants.invariant_theory import _guess_variables sage: R. = QQ[] - sage: _guess_variables(x^2+y^2) + sage: _guess_variables(x^2 + y^2) (x, y) sage: _guess_variables([x^2, y^2]) (x, y) - sage: _guess_variables(x^2+y^2, x) + sage: _guess_variables(x^2 + y^2, x) (x,) - sage: _guess_variables(x^2+y^2, x,y) + sage: _guess_variables(x^2 + y^2, x, y) (x, y) - sage: _guess_variables(x^2+y^2, [x,y]) + sage: _guess_variables(x^2 + y^2, [x,y]) (x, y) """ if isinstance(polynomial, (list, tuple)): @@ -177,7 +177,7 @@ def transvectant(f, g, h=1, scale='default'): INPUT: - - ``f,g`` -- two homogeneous binary forms in the same polynomial ring. + - ``f``, ``g`` -- two homogeneous binary forms in the same polynomial ring. - ``h`` -- the order of the transvectant. If it is not specified, the first transvectant is returned. @@ -214,14 +214,14 @@ def transvectant(f, g, h=1, scale='default'): factor will not be invertible in that case. The scale argument ``'none'`` can be used to compute the transvectant in this case:: - sage: R. = GF(5)[] - sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 + a5*x0^5 - sage: f = AlgebraicForm(2, 5, p, x0, x1) - sage: transvectant(f, f, 4) + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: f = AlgebraicForm(2, 5, a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 # optional - sage.rings.finite_rings + ....: + a3*x1^2*x0^3 + a4*x1*x0^4 + a5*x0^5, x0, x1) + sage: transvectant(f, f, 4) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError - sage: transvectant(f, f, 4, scale='none') + sage: transvectant(f, f, 4, scale='none') # optional - sage.rings.finite_rings Binary quadratic given by -a3^2*x0^2 + a2*a4*x0^2 + a2*a3*x0*x1 - a1*a4*x0*x1 - a2^2*x1^2 + a1*a3*x1^2 @@ -230,8 +230,8 @@ def transvectant(f, g, h=1, scale='default'): it to the scaled version:: sage: R. = QQ[] - sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 + a5*x0^5 - sage: f = AlgebraicForm(2, 5, p, x0, x1) + sage: f = AlgebraicForm(2, 5, a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + ....: + a3*x1^2*x0^3 + a4*x1*x0^4 + a5*x0^5, x0, x1) sage: transvectant(f, f, 4) Binary quadratic given by 3/50*a3^2*x0^2 - 4/25*a2*a4*x0^2 + 2/5*a1*a5*x0^2 + 1/25*a2*a3*x0*x1 - 6/25*a1*a4*x0*x1 + 2*a0*a5*x0*x1 @@ -247,14 +247,14 @@ def transvectant(f, g, h=1, scale='default'): one variable:: sage: R. = QQ[] - sage: quintic = invariant_theory.binary_quintic(x^5+x^3+2*x^2+y^5, x) + sage: quintic = invariant_theory.binary_quintic(x^5 + x^3 + 2*x^2 + y^5, x) sage: transvectant(quintic, quintic, 2) Traceback (most recent call last): ... ValueError: polynomial is not homogeneous sage: R. = QQ[] sage: S. = R[] - sage: quintic = invariant_theory.binary_quintic(x^5+x^3+2*x^2+y^5, x) + sage: quintic = invariant_theory.binary_quintic(x^5 + x^3 + 2*x^2 + y^5, x) sage: transvectant(quintic, quintic, 2) Binary sextic given by 1/5*x^6 + 6/5*x^5*h - 3/25*x^4*h^2 + (50*y^5 - 8)/25*x^3*h^3 - 12/25*x^2*h^4 + (3*y^5)/5*x*h^5 @@ -271,7 +271,7 @@ def transvectant(f, g, h=1, scale='default'): if h > f._d or h > g._d: tv = R(0) else: - from sage.functions.other import binomial, factorial + from sage.arith.misc import binomial, factorial if scale == 'default': scalar = factorial(f._d-h) * factorial(g._d-h) \ * R(factorial(f._d)*factorial(g._d))**(-1) @@ -385,12 +385,12 @@ def ring(self): EXAMPLES:: sage: R. = QQ[] - sage: quartic = invariant_theory.binary_quartic(x^4+y^4+t*x^2*y^2, [x,y]) + sage: quartic = invariant_theory.binary_quartic(x^4 + y^4 + t*x^2*y^2, [x,y]) sage: quartic.ring() Multivariate Polynomial Ring in x, y, t over Rational Field sage: R. = QQ[] - sage: quartic = invariant_theory.binary_quartic(x^4+1+t*x^2, [x]) + sage: quartic = invariant_theory.binary_quartic(x^4 + 1 + t*x^2, [x]) sage: quartic.ring() Multivariate Polynomial Ring in x, y, t over Rational Field """ @@ -408,12 +408,12 @@ def variables(self): EXAMPLES:: sage: R. = QQ[] - sage: quartic = invariant_theory.binary_quartic(x^4+y^4+t*x^2*y^2, [x,y]) + sage: quartic = invariant_theory.binary_quartic(x^4 + y^4 + t*x^2*y^2, [x,y]) sage: quartic.variables() (x, y) sage: R. = QQ[] - sage: quartic = invariant_theory.binary_quartic(x^4+1+t*x^2, [x]) + sage: quartic = invariant_theory.binary_quartic(x^4 + 1 + t*x^2, [x]) sage: quartic.variables() (x, None) """ @@ -431,14 +431,14 @@ def is_homogeneous(self): EXAMPLES:: sage: R. = QQ[] - sage: quartic = invariant_theory.binary_quartic(x^4+y^4+t*x^2*y^2, [x,y]) + sage: quartic = invariant_theory.binary_quartic(x^4 + y^4 + t*x^2*y^2, [x,y]) sage: quartic.is_homogeneous() True sage: quartic.form() x^2*y^2*t + x^4 + y^4 sage: R. = QQ[] - sage: quartic = invariant_theory.binary_quartic(x^4+1+t*x^2, [x]) + sage: quartic = invariant_theory.binary_quartic(x^4 + 1 + t*x^2, [x]) sage: quartic.is_homogeneous() False sage: quartic.form() @@ -505,7 +505,7 @@ class AlgebraicForm(FormsBase): ... ValueError: polynomial is of the wrong degree - sage: AlgebraicForm(2, 2, x^2+y, [x,y]).variables() + sage: AlgebraicForm(2, 2, x^2 + y, [x,y]).variables() Traceback (most recent call last): ... ValueError: polynomial is not homogeneous @@ -650,7 +650,7 @@ def _repr_(self): EXAMPLES:: sage: R. = QQ[] - sage: quartic = invariant_theory.binary_quartic(x^4+y^4) + sage: quartic = invariant_theory.binary_quartic(x^4 + y^4) sage: quartic._repr_() 'Binary quartic with coefficients (1, 0, 0, 0, 1)' @@ -694,7 +694,7 @@ def form(self): EXAMPLES:: sage: R. = QQ[] - sage: quartic = invariant_theory.binary_quartic(x^4+y^4) + sage: quartic = invariant_theory.binary_quartic(x^4 + y^4) sage: quartic.form() x^4 + y^4 sage: quartic.polynomial() @@ -792,7 +792,7 @@ def _extract_coefficients(self, monomials): (a30, a03, a00, a21, a20, a12, a02, a10, a01, a11) sage: T. = QQ[] - sage: univariate = AlgebraicForm(2, 3, t^3+2*t^2+3*t+4) + sage: univariate = AlgebraicForm(2, 3, t^3 + 2*t^2 + 3*t + 4) sage: m = [t^3, 1, t, t^2] sage: univariate._extract_coefficients(m) (1, 4, 3, 2) @@ -806,7 +806,7 @@ def _extract_coefficients(self, monomials): Check for :trac:`30035`:: sage: R. = QQ[] - sage: f = 3*a**3+b**3+a*b*c + sage: f = 3*a**3 + b**3 + a*b*c sage: T = invariant_theory.ternary_cubic(f) sage: T.S_invariant().parent() Rational Field @@ -905,9 +905,9 @@ def transformed(self, g): sage: R. = QQ[] sage: cubic = invariant_theory.ternary_cubic(x^3 + 2*y^3 + 3*z^3 + 4*x*y*z) - sage: cubic.transformed({x:y, y:z, z:x}).form() + sage: cubic.transformed({x: y, y: z, z: x}).form() 3*x^3 + y^3 + 4*x*y*z + 2*z^3 - sage: cyc = matrix([[0,1,0],[0,0,1],[1,0,0]]) + sage: cyc = matrix([[0,1,0], [0,0,1], [1,0,0]]) sage: cubic.transformed(cyc) == cubic.transformed({x:y, y:z, z:x}) True sage: g = matrix(QQ, [[1, 0, 0], [-1, 1, -3], [-5, -5, 16]]) @@ -973,11 +973,11 @@ def __init__(self, n, d, polynomial, *args): sage: R. = QQ[] sage: from sage.rings.invariants.invariant_theory import QuadraticForm - sage: form = QuadraticForm(2, 2, x^2+2*y^2+3*x*y) + sage: form = QuadraticForm(2, 2, x^2 + 2*y^2 + 3*x*y) sage: form Binary quadratic with coefficients (1, 2, 3) sage: form._check_covariant('discriminant', invariant=True) - sage: QuadraticForm(3, 2, x^2+y^2) + sage: QuadraticForm(3, 2, x^2 + y^2) Ternary quadratic with coefficients (1, 1, 0, 0, 0, 0) """ assert d == 2 @@ -1024,11 +1024,11 @@ def monomials(self): EXAMPLES:: sage: R. = QQ[] - sage: quadratic = invariant_theory.quadratic_form(x^2+y^2) + sage: quadratic = invariant_theory.quadratic_form(x^2 + y^2) sage: quadratic.monomials() (x^2, y^2, x*y) - sage: quadratic = invariant_theory.inhomogeneous_quadratic_form(x^2+y^2) + sage: quadratic = invariant_theory.inhomogeneous_quadratic_form(x^2 + y^2) sage: quadratic.monomials() (x^2, y^2, 1, x*y, x, y) """ @@ -1158,7 +1158,7 @@ def discriminant(self): EXAMPLES:: sage: R. = QQ[] - sage: p = a*x^2+b*x*y+c*y^2 + sage: p = a*x^2 + b*x*y + c*y^2 sage: quadratic = invariant_theory.quadratic_form(p, x,y) sage: quadratic.discriminant() b^2 - 4*a*c @@ -1291,7 +1291,7 @@ def as_QuadraticForm(self): EXAMPLES:: sage: R. = QQ[] - sage: p = x^2+y^2+z^2+2*x*y+3*x*z + sage: p = x^2 + y^2 + z^2 + 2*x*y + 3*x*z sage: quadratic = invariant_theory.ternary_quadratic(p) sage: matrix(quadratic) [ 1 1 3/2] @@ -1344,7 +1344,7 @@ def __init__(self, n, d, polynomial, *args): sage: R. = QQ[] sage: from sage.rings.invariants.invariant_theory import BinaryQuartic - sage: BinaryQuartic(2, 4, x^4+y^4) + sage: BinaryQuartic(2, 4, x^4 + y^4) Binary quartic with coefficients (1, 0, 0, 0, 1) """ assert n == 2 and d == 4 @@ -1365,7 +1365,7 @@ def monomials(self): EXAMPLES:: sage: R. = QQ[] - sage: quartic = invariant_theory.binary_quartic(x^4+y^4) + sage: quartic = invariant_theory.binary_quartic(x^4 + y^4) sage: quartic.monomials() (y^4, x*y^3, x^2*y^2, x^3*y, x^4) """ @@ -1456,7 +1456,7 @@ def EisensteinD(self): EXAMPLES:: sage: R. = QQ[] - sage: f = a0*x1^4+4*a1*x0*x1^3+6*a2*x0^2*x1^2+4*a3*x0^3*x1+a4*x0^4 + sage: f = a0*x1^4 + 4*a1*x0*x1^3 + 6*a2*x0^2*x1^2 + 4*a3*x0^3*x1 + a4*x0^4 sage: inv = invariant_theory.binary_quartic(f, x0, x1) sage: inv.EisensteinD() 3*a2^2 - 4*a1*a3 + a0*a4 @@ -1485,7 +1485,7 @@ def EisensteinE(self): EXAMPLES:: sage: R. = QQ[] - sage: f = a0*x1^4+4*a1*x0*x1^3+6*a2*x0^2*x1^2+4*a3*x0^3*x1+a4*x0^4 + sage: f = a0*x1^4 + 4*a1*x0*x1^3 + 6*a2*x0^2*x1^2 + 4*a3*x0^3*x1 + a4*x0^4 sage: inv = invariant_theory.binary_quartic(f, x0, x1) sage: inv.EisensteinE() a2^3 - 2*a1*a2*a3 + a0*a3^2 + a1^2*a4 - a0*a2*a4 @@ -1517,7 +1517,7 @@ def g_covariant(self): EXAMPLES:: sage: R. = QQ[] - sage: p = a0*x^4+4*a1*x^3*y+6*a2*x^2*y^2+4*a3*x*y^3+a4*y^4 + sage: p = a0*x^4 + 4*a1*x^3*y + 6*a2*x^2*y^2 + 4*a3*x*y^3 + a4*y^4 sage: inv = invariant_theory.binary_quartic(p, x, y) sage: g = inv.g_covariant(); g a1^2*x^4 - a0*a2*x^4 + 2*a1*a2*x^3*y - 2*a0*a3*x^3*y + 3*a2^2*x^2*y^2 @@ -1568,7 +1568,7 @@ def h_covariant(self): EXAMPLES:: sage: R. = QQ[] - sage: p = a0*x^4+4*a1*x^3*y+6*a2*x^2*y^2+4*a3*x*y^3+a4*y^4 + sage: p = a0*x^4 + 4*a1*x^3*y + 6*a2*x^2*y^2 + 4*a3*x*y^3 + a4*y^4 sage: inv = invariant_theory.binary_quartic(p, x, y) sage: h = inv.h_covariant(); h -2*a1^3*x^6 + 3*a0*a1*a2*x^6 - a0^2*a3*x^6 - 6*a1^2*a2*x^5*y + 9*a0*a2^2*x^5*y @@ -1587,7 +1587,7 @@ def h_covariant(self): + 2*a1*a3*a4*x + a0*a4^2*x + 2*a3^3 - 3*a2*a3*a4 + a1*a4^2 sage: g = inv.g_covariant() - sage: h == 1/8 * (p.derivative(x)*g.derivative(y)-p.derivative(y)*g.derivative(x)) + sage: h == 1/8 * (p.derivative(x)*g.derivative(y) - p.derivative(y)*g.derivative(x)) True """ a0, a1, a2, a3, a4 = self.scaled_coeffs() @@ -1716,7 +1716,7 @@ def monomials(self): EXAMPLES:: sage: R. = QQ[] - sage: quintic = invariant_theory.binary_quintic(x^5+y^5) + sage: quintic = invariant_theory.binary_quintic(x^5 + y^5) sage: quintic.monomials() (y^5, x*y^4, x^2*y^3, x^3*y^2, x^4*y, x^5) """ @@ -2584,7 +2584,7 @@ def monomials(self): EXAMPLES:: sage: R. = QQ[] - sage: quadratic = invariant_theory.ternary_quadratic(x^2+y*z) + sage: quadratic = invariant_theory.ternary_quadratic(x^2 + y*z) sage: quadratic.monomials() (x^2, y^2, z^2, x*y, x*z, y*z) """ @@ -2668,8 +2668,8 @@ def covariant_conic(self, other): EXAMPLES:: sage: ring. = QQ[] - sage: Q = invariant_theory.ternary_quadratic(x^2+y^2+z^2) - sage: R = invariant_theory.ternary_quadratic(x*y+x*z+y*z) + sage: Q = invariant_theory.ternary_quadratic(x^2 + y^2 + z^2) + sage: R = invariant_theory.ternary_quadratic(x*y + x*z + y*z) sage: Q.covariant_conic(R) -x*y - x*z - y*z sage: R.covariant_conic(Q) @@ -2716,7 +2716,7 @@ class TernaryCubic(AlgebraicForm): TESTS:: sage: R. = QQ[] - sage: cubic = invariant_theory.ternary_cubic(x^3+y^3+z^3) + sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + z^3) sage: cubic Ternary cubic with coefficients (1, 1, 1, 0, 0, 0, 0, 0, 0, 0) sage: TestSuite(cubic).run() @@ -2850,7 +2850,7 @@ def S_invariant(self): EXAMPLES:: sage: R. = QQ[] - sage: cubic = invariant_theory.ternary_cubic(x^2*y+y^3+z^3+x*y*z) + sage: cubic = invariant_theory.ternary_cubic(x^2*y + y^3 + z^3 + x*y*z) sage: cubic.S_invariant() -1/1296 """ @@ -2871,12 +2871,12 @@ def T_invariant(self): EXAMPLES:: sage: R. = QQ[] - sage: cubic = invariant_theory.ternary_cubic(x^3+y^3+z^3) + sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + z^3) sage: cubic.T_invariant() 1 sage: R. = GF(7)[] - sage: cubic = invariant_theory.ternary_cubic(x^3+y^3+z^3+t*x*y*z, [x,y,z]) + sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + z^3 + t*x*y*z, [x,y,z]) sage: cubic.T_invariant() -t^6 - t^3 + 1 """ @@ -2972,12 +2972,12 @@ def Hessian(self): EXAMPLES:: sage: R. = QQ[] - sage: cubic = invariant_theory.ternary_cubic(x^3+y^3+z^3) + sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + z^3) sage: cubic.Hessian() x*y*z sage: R. = QQ[] - sage: cubic = invariant_theory.ternary_cubic(x^3+y^3+1) + sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + 1) sage: cubic.Hessian() x*y """ @@ -3003,12 +3003,12 @@ def Theta_covariant(self): EXAMPLES:: sage: R. = QQ[] - sage: cubic = invariant_theory.ternary_cubic(x^3+y^3+z^3) + sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + z^3) sage: cubic.Theta_covariant() -x^3*y^3 - x^3*z^3 - y^3*z^3 sage: R. = QQ[] - sage: cubic = invariant_theory.ternary_cubic(x^3+y^3+1) + sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + 1) sage: cubic.Theta_covariant() -x^3*y^3 - x^3 - y^3 @@ -3036,12 +3036,12 @@ def J_covariant(self): EXAMPLES:: sage: R. = QQ[] - sage: cubic = invariant_theory.ternary_cubic(x^3+y^3+z^3) + sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + z^3) sage: cubic.J_covariant() x^6*y^3 - x^3*y^6 - x^6*z^3 + y^6*z^3 + x^3*z^6 - y^3*z^6 sage: R. = QQ[] - sage: cubic = invariant_theory.ternary_cubic(x^3+y^3+1) + sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + 1) sage: cubic.J_covariant() x^6*y^3 - x^3*y^6 - x^6 + y^6 + x^3 - y^3 """ @@ -3256,7 +3256,7 @@ def homogenized(self, var='h'): EXAMPLES:: sage: R. = QQ[] - sage: q = invariant_theory.quaternary_biquadratic(x^2+1, y^2+1, [x,y,z]) + sage: q = invariant_theory.quaternary_biquadratic(x^2 + 1, y^2 + 1, [x,y,z]) sage: q Joint quaternary quadratic with coefficients (1, 0, 0, 1, 0, 0, 0, 0, 0, 0) and quaternary quadratic with coefficients (0, 1, 0, 1, 0, 0, 0, 0, 0, 0) @@ -3394,7 +3394,8 @@ class TwoTernaryQuadratics(TwoAlgebraicForms): TESTS:: sage: R. = QQ[] - sage: inv = invariant_theory.ternary_biquadratic(x^2+y^2+z^2, x*y+y*z+x*z, [x, y, z]) + sage: inv = invariant_theory.ternary_biquadratic(x^2 + y^2 + z^2, + ....: x*y + y*z + x*z, [x, y, z]) sage: inv Joint ternary quadratic with coefficients (1, 1, 1, 0, 0, 0) and ternary quadratic with coefficients (0, 0, 0, 1, 1, 1) @@ -3451,7 +3452,7 @@ def _Theta_helper(self, scaled_coeffs_1, scaled_coeffs_2): TESTS:: sage: R. = QQ[] - sage: inv = invariant_theory.ternary_biquadratic(x^2 + y*z, x*y+z^2, x, y, z) + sage: inv = invariant_theory.ternary_biquadratic(x^2 + y*z, x*y + z^2, x, y, z) sage: inv._Theta_helper([1]*6, [2]*6) 0 """ @@ -3607,7 +3608,7 @@ class TwoQuaternaryQuadratics(TwoAlgebraicForms): TESTS:: sage: R. = QQ[] - sage: inv = invariant_theory.quaternary_biquadratic(w^2+x^2, y^2+z^2, w, x, y, z) + sage: inv = invariant_theory.quaternary_biquadratic(w^2 + x^2, y^2 + z^2, w, x, y, z) sage: inv Joint quaternary quadratic with coefficients (1, 1, 0, 0, 0, 0, 0, 0, 0, 0) and quaternary quadratic with coefficients (0, 0, 1, 1, 0, 0, 0, 0, 0, 0) @@ -3670,7 +3671,7 @@ def _Theta_helper(self, scaled_coeffs_1, scaled_coeffs_2): TESTS:: sage: R. = QQ[] - sage: inv = invariant_theory.quaternary_biquadratic(w^2+x^2, y^2+z^2, w, x, y, z) + sage: inv = invariant_theory.quaternary_biquadratic(w^2 + x^2, y^2 + z^2, w, x, y, z) sage: inv._Theta_helper([1]*10, [2]*10) 0 """ @@ -4022,10 +4023,10 @@ class InvariantTheoryFactory(): EXAMPLES:: sage: R. = QQ[] - sage: invariant_theory.ternary_cubic(x^3+y^3+z^3) + sage: invariant_theory.ternary_cubic(x^3 + y^3 + z^3) Ternary cubic with coefficients (1, 1, 1, 0, 0, 0, 0, 0, 0, 0) - sage: invariant_theory.ternary_cubic(x^3+y^3+z^3).J_covariant() + sage: invariant_theory.ternary_cubic(x^3 + y^3 + z^3).J_covariant() x^6*y^3 - x^3*y^6 - x^6*z^3 + y^6*z^3 + x^3*z^6 - y^3*z^6 """ @@ -4059,7 +4060,7 @@ def quadratic_form(self, polynomial, *args): EXAMPLES:: sage: R. = QQ[] - sage: quadratic = x^2+y^2+z^2 + sage: quadratic = x^2 + y^2 + z^2 sage: inv = invariant_theory.quadratic_form(quadratic) sage: type(inv) @@ -4068,7 +4069,7 @@ def quadratic_form(self, polynomial, *args): you need to specify the polynomial variables:: sage: R. = QQ[] - sage: quadratic = a*x^2+b*y^2+z^2+2*y*z + sage: quadratic = a*x^2 + b*y^2 + z^2 + 2*y*z sage: invariant_theory.quadratic_form(quadratic, x,y,z) Ternary quadratic with coefficients (a, b, 1, 0, 0, 2) sage: invariant_theory.quadratic_form(quadratic, [x,y,z]) # alternate syntax @@ -4103,11 +4104,11 @@ def inhomogeneous_quadratic_form(self, polynomial, *args): EXAMPLES:: sage: R. = QQ[] - sage: quadratic = x^2+2*y^2+3*x*y+4*x+5*y+6 + sage: quadratic = x^2 + 2*y^2 + 3*x*y + 4*x + 5*y + 6 sage: inv3 = invariant_theory.inhomogeneous_quadratic_form(quadratic) sage: type(inv3) - sage: inv4 = invariant_theory.inhomogeneous_quadratic_form(x^2+y^2+z^2) + sage: inv4 = invariant_theory.inhomogeneous_quadratic_form(x^2 + y^2 + z^2) sage: type(inv4) """ @@ -4136,7 +4137,7 @@ def binary_quadratic(self, quadratic, *args): EXAMPLES:: sage: R. = QQ[] - sage: invariant_theory.binary_quadratic(x^2+y^2) + sage: invariant_theory.binary_quadratic(x^2 + y^2) Binary quadratic with coefficients (1, 1, 0) sage: T. = QQ[] @@ -4164,11 +4165,11 @@ def quaternary_quadratic(self, quadratic, *args): EXAMPLES:: sage: R. = QQ[] - sage: invariant_theory.quaternary_quadratic(w^2+x^2+y^2+z^2) + sage: invariant_theory.quaternary_quadratic(w^2 + x^2 + y^2 + z^2) Quaternary quadratic with coefficients (1, 1, 1, 1, 0, 0, 0, 0, 0, 0) sage: R. = QQ[] - sage: invariant_theory.quaternary_quadratic(1+x^2+y^2+z^2) + sage: invariant_theory.quaternary_quadratic(1 + x^2 + y^2 + z^2) Quaternary quadratic with coefficients (1, 1, 1, 1, 0, 0, 0, 0, 0, 0) """ return QuadraticForm(4, 2, quadratic, *args) @@ -4212,7 +4213,7 @@ def binary_quartic(self, quartic, *args, **kwds): EXAMPLES:: sage: R. = QQ[] - sage: quartic = invariant_theory.binary_quartic(x^4+y^4) + sage: quartic = invariant_theory.binary_quartic(x^4 + y^4) sage: quartic Binary quartic with coefficients (1, 0, 0, 0, 1) sage: type(quartic) @@ -4251,14 +4252,14 @@ def binary_quintic(self, quintic, *args, **kwds): If no variables are provided, they will be guessed:: sage: R. = QQ[] - sage: quintic = invariant_theory.binary_quintic(x^5+y^5) + sage: quintic = invariant_theory.binary_quintic(x^5 + y^5) sage: quintic Binary quintic with coefficients (1, 0, 0, 0, 0, 1) If only one variable is given, the quintic is the homogenisation of the provided polynomial:: - sage: quintic = invariant_theory.binary_quintic(x^5+y^5, x) + sage: quintic = invariant_theory.binary_quintic(x^5 + y^5, x) sage: quintic Binary quintic with coefficients (y^5, 0, 0, 0, 0, 1) sage: quintic.is_homogeneous() @@ -4268,11 +4269,11 @@ def binary_quintic(self, quintic, *args, **kwds): specified:: sage: R. = QQ[] - sage: quintic = invariant_theory.binary_quintic(x^5+z*y^5) + sage: quintic = invariant_theory.binary_quintic(x^5 + z*y^5) Traceback (most recent call last): ... ValueError: need 2 or 1 variables, got (x, y, z) - sage: quintic = invariant_theory.binary_quintic(x^5+z*y^5, x, y) + sage: quintic = invariant_theory.binary_quintic(x^5 + z*y^5, x, y) sage: quintic Binary quintic with coefficients (z, 0, 0, 0, 0, 1) @@ -4342,12 +4343,13 @@ def binary_form_from_invariants(self, degree, invariants, variables=None, as_for Binary quintic with coefficients (-37725479487783/1048576, 565882192316745/8388608, 0, 1033866765362693115/67108864, 12849486940936328715/268435456, -23129076493685391687/2147483648) - sage: invariant_theory.binary_form_from_invariants(5, invariants, scaling='normalized') + sage: invariant_theory.binary_form_from_invariants(5, invariants, + ....: scaling='normalized') Binary quintic with coefficients (24389/892616806656, 4205/11019960576, 0, 1015/209952, -145/1296, -3/16) - sage: invariant_theory.binary_form_from_invariants(5, invariants, scaling='coprime') - Binary quintic with coefficients (-2048, 3840, 0, 876960, 2724840, - -613089) + sage: invariant_theory.binary_form_from_invariants(5, invariants, + ....: scaling='coprime') + Binary quintic with coefficients (-2048, 3840, 0, 876960, 2724840, -613089) The invariants can also be computed using the invariants of a given binary quintic. The resulting form has the same invariants up to scaling, is @@ -4359,7 +4361,8 @@ def binary_form_from_invariants(self, degree, invariants, variables=None, as_for sage: p = 3*x1^5 + 6*x1^4*x0 + 3*x1^3*x0^2 + 4*x1^2*x0^3 - 5*x1*x0^4 + 4*x0^5 sage: quintic = invariant_theory.binary_quintic(p, x0, x1) sage: invariants = quintic.clebsch_invariants(as_tuple=True) - sage: newquintic = invariant_theory.binary_form_from_invariants(5, invariants, variables=quintic.variables()) + sage: newquintic = invariant_theory.binary_form_from_invariants( + ....: 5, invariants, variables=quintic.variables()) sage: newquintic Binary quintic with coefficients (9592267437341790539005557/244140625000000, 2149296928207625556323004064707/610351562500000000, @@ -4468,14 +4471,14 @@ def ternary_quadratic(self, quadratic, *args, **kwds): EXAMPLES:: sage: R. = QQ[] - sage: invariant_theory.ternary_quadratic(x^2+y^2+z^2) + sage: invariant_theory.ternary_quadratic(x^2 + y^2 + z^2) Ternary quadratic with coefficients (1, 1, 1, 0, 0, 0) sage: T. = QQ[] - sage: invariant_theory.ternary_quadratic(1+u^2+v^2) + sage: invariant_theory.ternary_quadratic(1 + u^2 + v^2) Ternary quadratic with coefficients (1, 1, 1, 0, 0, 0) - sage: quadratic = x^2+y^2+z^2 + sage: quadratic = x^2 + y^2 + z^2 sage: inv = invariant_theory.ternary_quadratic(quadratic) sage: type(inv) @@ -4540,7 +4543,7 @@ def ternary_cubic(self, cubic, *args, **kwds): EXAMPLES:: sage: R. = QQ[] - sage: cubic = invariant_theory.ternary_cubic(x^3+y^3+z^3) + sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + z^3) sage: type(cubic) """ @@ -4562,7 +4565,7 @@ def ternary_biquadratic(self, quadratic1, quadratic2, *args, **kwds): EXAMPLES:: sage: R. = QQ[] - sage: q1 = x^2+y^2+z^2 + sage: q1 = x^2 + y^2 + z^2 sage: q2 = x*y + y*z + x*z sage: inv = invariant_theory.ternary_biquadratic(q1, q2) sage: type(inv) @@ -4616,7 +4619,7 @@ def quaternary_biquadratic(self, quadratic1, quadratic2, *args, **kwds): EXAMPLES:: sage: R. = QQ[] - sage: q1 = w^2+x^2+y^2+z^2 + sage: q1 = w^2 + x^2 + y^2 + z^2 sage: q2 = w*x + y*z sage: inv = invariant_theory.quaternary_biquadratic(q1, q2) sage: type(inv) diff --git a/src/sage/rings/invariants/reconstruction.py b/src/sage/rings/invariants/reconstruction.py index 99941d306b8..4619bf777f1 100644 --- a/src/sage/rings/invariants/reconstruction.py +++ b/src/sage/rings/invariants/reconstruction.py @@ -41,7 +41,7 @@ def binary_quadratic_coefficients_from_invariants(discriminant, invariant_choice EXAMPLES:: sage: from sage.rings.invariants.reconstruction import binary_quadratic_coefficients_from_invariants - sage: quadratic = invariant_theory.binary_form_from_invariants(2, [24]) # indirect doctest + sage: quadratic = invariant_theory.binary_form_from_invariants(2, [24]) # indirect doctest sage: quadratic Binary quadratic with coefficients (1, -6, 0) sage: quadratic.discriminant() @@ -142,7 +142,8 @@ def binary_quintic_coefficients_from_invariants(invariants, K=None, invariant_ch sage: p = 3*x1^5 + 6*x1^4*x0 + 3*x1^3*x0^2 + 4*x1^2*x0^3 - 5*x1*x0^4 + 4*x0^5 sage: quintic = invariant_theory.binary_quintic(p, x0, x1) sage: invs = quintic.clebsch_invariants(as_tuple=True) - sage: reconstructed = invariant_theory.binary_form_from_invariants(5, invs, variables=quintic.variables()) # indirect doctest + sage: reconstructed = invariant_theory.binary_form_from_invariants( # indirect doctest + ....: 5, invs, variables=quintic.variables()) sage: reconstructed Binary quintic with coefficients (9592267437341790539005557/244140625000000, 2149296928207625556323004064707/610351562500000000, @@ -167,8 +168,10 @@ def binary_quintic_coefficients_from_invariants(invariants, K=None, invariant_ch sage: alpha = quintic.alpha_covariant() sage: beta = quintic.beta_covariant() - sage: g = matrix([[alpha(x0=1,x1=0),alpha(x0=0,x1=1)],[beta(x0=1,x1=0),beta(x0=0,x1=1)]])^-1 - sage: transformed = tuple([g.determinant()^-5*x for x in quintic.transformed(g).coeffs()]) + sage: g = matrix([[alpha(x0=1,x1=0), alpha(x0=0,x1=1)], + ....: [beta(x0=1,x1=0), beta(x0=0,x1=1)]])^-1 + sage: transformed = tuple([g.determinant()^-5*x + ....: for x in quintic.transformed(g).coeffs()]) sage: transformed == reconstructed.coeffs() True @@ -231,7 +234,8 @@ def binary_quintic_coefficients_from_invariants(invariants, K=None, invariant_ch sage: binary_quintic_coefficients_from_invariants([3,1,2], K=GF(5)) Traceback (most recent call last): ... - NotImplementedError: no reconstruction of binary quintics implemented for fields of characteristic 2, 3 or 5 + NotImplementedError: no reconstruction of binary quintics implemented + for fields of characteristic 2, 3 or 5 TESTS:: diff --git a/src/sage/rings/laurent_series_ring.py b/src/sage/rings/laurent_series_ring.py index 56551b50a55..e2a5c524cfe 100644 --- a/src/sage/rings/laurent_series_ring.py +++ b/src/sage/rings/laurent_series_ring.py @@ -6,11 +6,11 @@ sage: R = LaurentSeriesRing(QQ, "x") sage: R.base_ring() Rational Field - sage: S = LaurentSeriesRing(GF(17)['x'], 'y') - sage: S - Laurent Series Ring in y over Univariate Polynomial Ring in x over - Finite Field of size 17 - sage: S.base_ring() + sage: S = LaurentSeriesRing(GF(17)['x'], 'y') # optional - sage.rings.finite_rings + sage: S # optional - sage.rings.finite_rings + Laurent Series Ring in y over + Univariate Polynomial Ring in x over Finite Field of size 17 + sage: S.base_ring() # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 17 .. SEEALSO:: @@ -47,6 +47,11 @@ from sage.rings.integer_ring import ZZ +try: + from sage.libs.pari.all import pari_gen +except ImportError: + pari_gen = () + def is_LaurentSeriesRing(x): """ @@ -74,7 +79,7 @@ class LaurentSeriesRing(UniqueRepresentation, CommutativeRing): sage: R = LaurentSeriesRing(QQ, 'x'); R Laurent Series Ring in x over Rational Field sage: x = R.0 - sage: g = 1 - x + x^2 - x^4 +O(x^8); g + sage: g = 1 - x + x^2 - x^4 + O(x^8); g 1 - x + x^2 - x^4 + O(x^8) sage: g = 10*x^(-3) + 2006 - 19*x + x^2 - x^4 +O(x^8); g 10*x^-3 + 2006 - 19*x + x^2 - x^4 + O(x^8) @@ -84,7 +89,7 @@ class LaurentSeriesRing(UniqueRepresentation, CommutativeRing): sage: Frac(QQ[['x']]) Laurent Series Ring in x over Rational Field - sage: Frac(GF(5)['y']) + sage: Frac(GF(5)['y']) # optional - sage.rings.finite_rings Fraction Field of Univariate Polynomial Ring in y over Finite Field of size 5 When the base ring is a domain, the fraction field is the @@ -96,17 +101,17 @@ class LaurentSeriesRing(UniqueRepresentation, CommutativeRing): Laurent series rings are determined by their variable and the base ring, and are globally unique:: - sage: K = Qp(5, prec = 5) - sage: L = Qp(5, prec = 200) - sage: R. = LaurentSeriesRing(K) - sage: S. = LaurentSeriesRing(L) - sage: R is S + sage: K = Qp(5, prec=5) # optional - sage.rings.padics + sage: L = Qp(5, prec=200) # optional - sage.rings.padics + sage: R. = LaurentSeriesRing(K) # optional - sage.rings.padics + sage: S. = LaurentSeriesRing(L) # optional - sage.rings.padics + sage: R is S # optional - sage.rings.padics False - sage: T. = LaurentSeriesRing(Qp(5,prec=200)) - sage: S is T + sage: T. = LaurentSeriesRing(Qp(5, prec=200)) # optional - sage.rings.padics + sage: S is T # optional - sage.rings.padics True - sage: W. = LaurentSeriesRing(Qp(5,prec=199)) - sage: W is T + sage: W. = LaurentSeriesRing(Qp(5, prec=199)) # optional - sage.rings.padics + sage: W is T # optional - sage.rings.padics False sage: K = LaurentSeriesRing(CC, 'q') @@ -122,11 +127,15 @@ class LaurentSeriesRing(UniqueRepresentation, CommutativeRing): a field equipped with a discrete valuation for which it is complete. The appropriate (sub)category is automatically set in this case:: - sage: k = GF(11) - sage: R. = k[[]] - sage: F = Frac(R) - sage: F.category() - Join of Category of complete discrete valuation fields and Category of commutative algebras over (finite enumerated fields and subquotients of monoids and quotients of semigroups) and Category of infinite sets + sage: k = GF(11) # optional - sage.rings.finite_rings + sage: R. = k[[]] # optional - sage.rings.finite_rings + sage: F = Frac(R) # optional - sage.rings.finite_rings + sage: F.category() # optional - sage.rings.finite_rings + Join of + Category of complete discrete valuation fields and + Category of commutative algebras over (finite enumerated fields and + subquotients of monoids and quotients of semigroups) and + Category of infinite sets sage: TestSuite(F).run() TESTS: @@ -147,11 +156,14 @@ class LaurentSeriesRing(UniqueRepresentation, CommutativeRing): Check categories (:trac:`24420`):: sage: LaurentSeriesRing(ZZ, 'x').category() - Category of infinite commutative no zero divisors algebras over (euclidean domains and infinite enumerated sets and metric spaces) + Category of infinite commutative no zero divisors algebras + over (euclidean domains and infinite enumerated sets and metric spaces) sage: LaurentSeriesRing(QQ, 'x').category() - Join of Category of complete discrete valuation fields and Category of commutative algebras over (number fields and quotient fields and metric spaces) and Category of infinite sets + Join of Category of complete discrete valuation fields and Category of commutative algebras + over (number fields and quotient fields and metric spaces) and Category of infinite sets sage: LaurentSeriesRing(Zmod(4), 'x').category() - Category of infinite commutative algebras over (finite commutative rings and subquotients of monoids and quotients of semigroups and finite enumerated sets) + Category of infinite commutative algebras + over (finite commutative rings and subquotients of monoids and quotients of semigroups and finite enumerated sets) Check coercions (:trac:`24431`):: @@ -215,27 +227,34 @@ def __init__(self, power_series): sage: RZZ = LaurentSeriesRing(ZZ, 't') sage: RZZ.category() - Category of infinite commutative no zero divisors algebras over (euclidean domains and infinite enumerated sets and metric spaces) + Category of infinite commutative no zero divisors algebras + over (euclidean domains and infinite enumerated sets and metric spaces) sage: TestSuite(RZZ).run() sage: R1 = LaurentSeriesRing(Zmod(1), 't') sage: R1.category() - Category of finite commutative algebras over (finite commutative rings and subquotients of monoids and quotients of semigroups and finite enumerated sets) + Category of finite commutative algebras + over (finite commutative rings and subquotients of monoids and quotients of semigroups and finite enumerated sets) sage: TestSuite(R1).run() sage: R2 = LaurentSeriesRing(Zmod(2), 't') sage: R2.category() - Join of Category of complete discrete valuation fields and Category of commutative algebras over (finite enumerated fields and subquotients of monoids and quotients of semigroups) and Category of infinite sets + Join of Category of complete discrete valuation fields + and Category of commutative algebras over (finite enumerated fields and subquotients of monoids and quotients of semigroups) + and Category of infinite sets sage: TestSuite(R2).run() sage: R4 = LaurentSeriesRing(Zmod(4), 't') sage: R4.category() - Category of infinite commutative algebras over (finite commutative rings and subquotients of monoids and quotients of semigroups and finite enumerated sets) + Category of infinite commutative algebras + over (finite commutative rings and subquotients of monoids and quotients of semigroups and finite enumerated sets) sage: TestSuite(R4).run() sage: RQQ = LaurentSeriesRing(QQ, 't') sage: RQQ.category() - Join of Category of complete discrete valuation fields and Category of commutative algebras over (number fields and quotient fields and metric spaces) and Category of infinite sets + Join of Category of complete discrete valuation fields + and Category of commutative algebras over (number fields and quotient fields and metric spaces) + and Category of infinite sets sage: TestSuite(RQQ).run() """ base_ring = power_series.base_ring() @@ -361,9 +380,9 @@ def _repr_(self): """ EXAMPLES:: - sage: LaurentSeriesRing(QQ,'q') # indirect doctest + sage: LaurentSeriesRing(QQ, 'q') # indirect doctest Laurent Series Ring in q over Rational Field - sage: LaurentSeriesRing(ZZ,'t',sparse=True) + sage: LaurentSeriesRing(ZZ, 't', sparse=True) Sparse Laurent Series Ring in t over Integer Ring """ s = "Laurent Series Ring in %s over %s" % (self.variable_name(), self.base_ring()) @@ -386,35 +405,35 @@ def _element_constructor_(self, x, n=0, prec=infinity): EXAMPLES:: - sage: R. = LaurentSeriesRing(Qp(5, 10)) - sage: S. = LaurentSeriesRing(RationalField()) - sage: R(t + t^2 + O(t^3)) + sage: R. = LaurentSeriesRing(Qp(5, 10)) # optional - sage.rings.padics + sage: S. = LaurentSeriesRing(RationalField()) # optional - sage.rings.padics + sage: R(t + t^2 + O(t^3)) # optional - sage.rings.padics (1 + O(5^10))*u + (1 + O(5^10))*u^2 + O(u^3) - sage: R(t + t^2 + O(t^3), prec=2) + sage: R(t + t^2 + O(t^3), prec=2) # optional - sage.rings.padics (1 + O(5^10))*u + O(u^2) Coercing an element into its own parent produces that element again, unless a different ``n`` or ``prec`` is given:: - sage: u is R(u) + sage: u is R(u) # optional - sage.rings.padics True - sage: R(u, n=3, prec=7) + sage: R(u, n=3, prec=7) # optional - sage.rings.padics (1 + O(5^10))*u^4 + O(u^7) Rational functions are accepted:: - sage: I = sqrt(-1) - sage: K. = QQ[I] - sage: P. = PolynomialRing(K) - sage: L. = LaurentSeriesRing(QQ[I]) - sage: L((t*I)/(t^3+I*2*t)) + sage: I = sqrt(-1) # optional - sage.rings.number_field sage.symbolic + sage: K. = QQ[I] # optional - sage.rings.number_field sage.symbolic + sage: P. = PolynomialRing(K) # optional - sage.rings.number_field sage.symbolic + sage: L. = LaurentSeriesRing(QQ[I]) # optional - sage.rings.number_field sage.symbolic + sage: L((t*I)/(t^3+I*2*t)) # optional - sage.rings.number_field sage.symbolic 1/2 + 1/4*I*u^2 - 1/8*u^4 - 1/16*I*u^6 + 1/32*u^8 + 1/64*I*u^10 - 1/128*u^12 - 1/256*I*u^14 + 1/512*u^16 + 1/1024*I*u^18 + O(u^20) :: - sage: L(t*I) / L(t^3+I*2*t) + sage: L(t*I) / L(t^3+I*2*t) # optional - sage.rings.number_field 1/2 + 1/4*I*u^2 - 1/8*u^4 - 1/16*I*u^6 + 1/32*u^8 + 1/64*I*u^10 - 1/128*u^12 - 1/256*I*u^14 + 1/512*u^16 + 1/1024*I*u^18 + O(u^20) @@ -440,23 +459,23 @@ def _element_constructor_(self, x, n=0, prec=infinity): Various conversions from PARI (see also :trac:`2508`):: sage: L. = LaurentSeriesRing(QQ, default_prec=10) - sage: L(pari('1/x')) + sage: L(pari('1/x')) # optional - sage.libs.pari q^-1 - sage: L(pari('polchebyshev(5)')) + sage: L(pari('polchebyshev(5)')) # optional - sage.libs.pari 5*q - 20*q^3 + 16*q^5 - sage: L(pari('polchebyshev(5) - 1/x^4')) + sage: L(pari('polchebyshev(5) - 1/x^4')) # optional - sage.libs.pari -q^-4 + 5*q - 20*q^3 + 16*q^5 - sage: L(pari('1/polchebyshev(5)')) + sage: L(pari('1/polchebyshev(5)')) # optional - sage.libs.pari 1/5*q^-1 + 4/5*q + 64/25*q^3 + 192/25*q^5 + 2816/125*q^7 + O(q^9) - sage: L(pari('polchebyshev(5) + O(x^40)')) + sage: L(pari('polchebyshev(5) + O(x^40)')) # optional - sage.libs.pari 5*q - 20*q^3 + 16*q^5 + O(q^40) - sage: L(pari('polchebyshev(5) - 1/x^4 + O(x^40)')) + sage: L(pari('polchebyshev(5) - 1/x^4 + O(x^40)')) # optional - sage.libs.pari -q^-4 + 5*q - 20*q^3 + 16*q^5 + O(q^40) - sage: L(pari('1/polchebyshev(5) + O(x^10)')) + sage: L(pari('1/polchebyshev(5) + O(x^10)')) # optional - sage.libs.pari 1/5*q^-1 + 4/5*q + 64/25*q^3 + 192/25*q^5 + 2816/125*q^7 + 8192/125*q^9 + O(q^10) - sage: L(pari('1/polchebyshev(5) + O(x^10)'), -10) # Multiply by q^-10 + sage: L(pari('1/polchebyshev(5) + O(x^10)'), -10) # Multiply by q^-10 # optional - sage.libs.pari 1/5*q^-11 + 4/5*q^-9 + 64/25*q^-7 + 192/25*q^-5 + 2816/125*q^-3 + 8192/125*q^-1 + O(1) - sage: L(pari('O(x^-10)')) + sage: L(pari('O(x^-10)')) # optional - sage.libs.pari O(q^-10) Check that :trac:`30073` is fixed:: @@ -469,7 +488,6 @@ def _element_constructor_(self, x, n=0, prec=infinity): from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.polynomial.multi_polynomial import MPolynomial from sage.structure.element import parent - from sage.libs.pari.all import pari_gen P = parent(x) if isinstance(x, self.element_class) and n == 0 and P is self: @@ -522,8 +540,8 @@ def random_element(self, algorithm='default'): EXAMPLES:: - sage: S. = LaurentSeriesRing(GF(3)) - sage: S.random_element() # random + sage: S. = LaurentSeriesRing(GF(3)) # optional - sage.rings.finite_rings + sage: S.random_element() # random # optional - sage.rings.finite_rings s^-8 + s^-7 + s^-6 + s^-5 + s^-1 + s + s^3 + s^4 + s^5 + 2*s^6 + s^7 + s^11 + O(s^12) """ @@ -559,9 +577,9 @@ def construction(self): sage: parent(1/2 * t) Laurent Series Ring in t over Rational Field - sage: QQbar.gen() * t + sage: QQbar.gen() * t # optional - sage.rings.number_field I*t - sage: parent(QQbar.gen() * t) + sage: parent(QQbar.gen() * t) # optional - sage.rings.number_field Laurent Series Ring in t over Algebraic Field """ from sage.categories.pushout import CompletionFunctor @@ -637,14 +655,15 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): """ EXAMPLES:: - sage: R. = LaurentSeriesRing(GF(17)) - sage: S. = LaurentSeriesRing(GF(19)) - sage: R.hom([y], S) # indirect doctest + sage: R. = LaurentSeriesRing(GF(17)) # optional - sage.rings.finite_rings + sage: S. = LaurentSeriesRing(GF(19)) # optional - sage.rings.finite_rings + sage: R.hom([y], S) # indirect doctest # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: relations do not all (canonically) map to 0 under map determined by images of generators - sage: f = R.hom(x+x^3,R) - sage: f(x^2) + ValueError: relations do not all (canonically) map to 0 + under map determined by images of generators + sage: f = R.hom(x + x^3, R) # optional - sage.rings.finite_rings + sage: f(x^2) # optional - sage.rings.finite_rings x^2 + 2*x^4 + x^6 The image of the generator needs to be a unit:: @@ -671,8 +690,8 @@ def characteristic(self): """ EXAMPLES:: - sage: R. = LaurentSeriesRing(GF(17)) - sage: R.characteristic() + sage: R. = LaurentSeriesRing(GF(17)) # optional - sage.rings.finite_rings + sage: R.characteristic() # optional - sage.rings.finite_rings 17 """ return self.base_ring().characteristic() @@ -686,8 +705,8 @@ def residue_field(self): EXAMPLES:: - sage: R. = LaurentSeriesRing(GF(17)) - sage: R.residue_field() + sage: R. = LaurentSeriesRing(GF(17)) # optional - sage.rings.finite_rings + sage: R.residue_field() # optional - sage.rings.finite_rings Finite Field of size 17 sage: R. = LaurentSeriesRing(ZZ) diff --git a/src/sage/rings/laurent_series_ring_element.pyx b/src/sage/rings/laurent_series_ring_element.pyx index b11989eafbe..5eee4eb7b3f 100644 --- a/src/sage/rings/laurent_series_ring_element.pyx +++ b/src/sage/rings/laurent_series_ring_element.pyx @@ -3,16 +3,16 @@ Laurent Series EXAMPLES:: - sage: R. = LaurentSeriesRing(GF(7), 't'); R + sage: R. = LaurentSeriesRing(GF(7), 't'); R # optional - sage.rings.finite_rings Laurent Series Ring in t over Finite Field of size 7 - sage: f = 1/(1-t+O(t^10)); f + sage: f = 1/(1-t+O(t^10)); f # optional - sage.rings.finite_rings 1 + t + t^2 + t^3 + t^4 + t^5 + t^6 + t^7 + t^8 + t^9 + O(t^10) Laurent series are immutable:: - sage: f[2] + sage: f[2] # optional - sage.rings.finite_rings 1 - sage: f[2] = 5 + sage: f[2] = 5 # optional - sage.rings.finite_rings Traceback (most recent call last): ... IndexError: Laurent series are immutable @@ -112,18 +112,18 @@ cdef class LaurentSeries(AlgebraElement): sage: R. = LaurentSeriesRing(ZZ) sage: R([1,2,3]) 1 + 2*q + 3*q^2 - sage: R([1,2,3],-5) + sage: R([1,2,3], -5) q^-5 + 2*q^-4 + 3*q^-3 :: - sage: S. = LaurentSeriesRing(GF(5)) - sage: T. = PowerSeriesRing(pAdicRing(5)) - sage: S(t) + sage: S. = LaurentSeriesRing(GF(5)) # optional - sage.rings.finite_rings sage.rings.padics + sage: T. = PowerSeriesRing(pAdicRing(5)) # optional - sage.rings.finite_rings sage.rings.padics + sage: S(t) # optional - sage.rings.finite_rings sage.rings.padics s - sage: parent(S(t)) + sage: parent(S(t)) # optional - sage.rings.finite_rings sage.rings.padics Laurent Series Ring in s over Finite Field of size 5 - sage: parent(S(t)[1]) + sage: parent(S(t)[1]) # optional - sage.rings.finite_rings sage.rings.padics Finite Field of size 5 """ AlgebraElement.__init__(self, parent) @@ -185,7 +185,7 @@ cdef class LaurentSeries(AlgebraElement): sage: R. = LaurentSeriesRing(ZZ) sage: p = R([1,2,3]); p 1 + 2*q + 3*q^2 - sage: p.change_ring(GF(2)) + sage: p.change_ring(GF(2)) # optional - sage.rings.finite_rings 1 + q^2 """ return self._parent.change_ring(R)(self) @@ -197,9 +197,9 @@ cdef class LaurentSeries(AlgebraElement): EXAMPLES:: sage: R. = LaurentSeriesRing(QQ) - sage: (2+t).is_unit() + sage: (2 + t).is_unit() True - sage: f = 2+t^2+O(t^10); f.is_unit() + sage: f = 2 + t^2 + O(t^10); f.is_unit() True sage: 1/f 1/2 - 1/4*t^2 + 1/8*t^4 - 1/16*t^6 + 1/32*t^8 + O(t^10) @@ -235,7 +235,7 @@ cdef class LaurentSeries(AlgebraElement): def is_monomial(self): """ - Return True if this element is a monomial. That is, if self is + Return ``True`` if this element is a monomial. That is, if self is `x^n` for some integer `n`. EXAMPLES:: @@ -288,16 +288,16 @@ cdef class LaurentSeries(AlgebraElement): EXAMPLES:: sage: Zx. = ZZ[] - sage: K. = NumberField(x^2 + 1) - sage: R. = LaurentSeriesRing(K) - sage: z = t^-1 + i*t - sage: z._im_gens_(R, [t^2]) + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: R. = LaurentSeriesRing(K) # optional - sage.rings.number_field + sage: z = t^-1 + i*t # optional - sage.rings.number_field + sage: z._im_gens_(R, [t^2]) # optional - sage.rings.number_field t^-2 + i*t^2 The argument base_map is not yet supported, because it isn't over power series:: - sage: cc = K.hom([i]) - sage: z._im_gens_(R, [t^2], base_map=cc) + sage: cc = K.hom([i]) # optional - sage.rings.number_field + sage: z._im_gens_(R, [t^2], base_map=cc) # optional - sage.rings.number_field Traceback (most recent call last): ... NotImplementedError @@ -442,9 +442,9 @@ cdef class LaurentSeries(AlgebraElement): Verify that :trac:`6656` has been fixed:: - sage: R.=PolynomialRing(QQ) - sage: T.=LaurentSeriesRing(R) - sage: y = a*x+b*x + sage: R. = PolynomialRing(QQ) + sage: T. = LaurentSeriesRing(R) + sage: y = a*x + b*x sage: y._latex_() '\\left(a + b\\right)x' sage: latex(y) @@ -616,10 +616,10 @@ cdef class LaurentSeries(AlgebraElement): EXAMPLES:: sage: t = LaurentSeriesRing(ZZ,'t').gen() - sage: f = 1/t**2+2/t+3+4*t + sage: f = 1/t**2 + 2/t + 3 + 4*t sage: f.residue() 2 - sage: f = t+t**2 + sage: f = t + t**2 sage: f.residue() 0 sage: f.residue().parent() @@ -671,11 +671,11 @@ cdef class LaurentSeries(AlgebraElement): EXAMPLES:: - sage: A. = LaurentSeriesRing(GF(5)) - sage: x = t^(-1) + t^2 + O(t^5) - sage: x.lift_to_precision(10) + sage: A. = LaurentSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: x = t^(-1) + t^2 + O(t^5) # optional - sage.rings.finite_rings + sage: x.lift_to_precision(10) # optional - sage.rings.finite_rings t^-1 + t^2 + O(t^10) - sage: x.lift_to_precision() + sage: x.lift_to_precision() # optional - sage.rings.finite_rings t^-1 + t^2 """ if absprec is not None and absprec <= self.precision_absolute(): @@ -1028,7 +1028,8 @@ cdef class LaurentSeries(AlgebraElement): sage: A. = LaurentSeriesRing(ZZ) sage: f = 1/(1-x) sage: f - 1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + x^10 + x^11 + x^12 + x^13 + x^14 + x^15 + x^16 + x^17 + x^18 + x^19 + O(x^20) + 1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + x^10 + x^11 + + x^12 + x^13 + x^14 + x^15 + x^16 + x^17 + x^18 + x^19 + O(x^20) sage: f.truncate(10) 1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 """ @@ -1046,7 +1047,8 @@ cdef class LaurentSeries(AlgebraElement): sage: A. = LaurentSeriesRing(ZZ) sage: f = 1/(1-x) sage: f - 1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + x^10 + x^11 + x^12 + x^13 + x^14 + x^15 + x^16 + x^17 + x^18 + x^19 + O(x^20) + 1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + x^10 + x^11 + + x^12 + x^13 + x^14 + x^15 + x^16 + x^17 + x^18 + x^19 + O(x^20) sage: f.truncate_laurentseries(10) 1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + O(x^10) """ @@ -1489,8 +1491,11 @@ cdef class LaurentSeries(AlgebraElement): ring:: sage: R. = LaurentSeriesRing(QQ, default_prec=20) - sage: (x - x^2).reverse() # get some Catalan numbers - x + x^2 + 2*x^3 + 5*x^4 + 14*x^5 + 42*x^6 + 132*x^7 + 429*x^8 + 1430*x^9 + 4862*x^10 + 16796*x^11 + 58786*x^12 + 208012*x^13 + 742900*x^14 + 2674440*x^15 + 9694845*x^16 + 35357670*x^17 + 129644790*x^18 + 477638700*x^19 + O(x^20) + sage: (x - x^2).reverse() # get some Catalan numbers + x + x^2 + 2*x^3 + 5*x^4 + 14*x^5 + 42*x^6 + 132*x^7 + 429*x^8 + 1430*x^9 + + 4862*x^10 + 16796*x^11 + 58786*x^12 + 208012*x^13 + 742900*x^14 + + 2674440*x^15 + 9694845*x^16 + 35357670*x^17 + 129644790*x^18 + + 477638700*x^19 + O(x^20) sage: (x - x^2).reverse(precision=3) x + x^2 + O(x^3) @@ -1589,8 +1594,8 @@ cdef class LaurentSeries(AlgebraElement): TESTS:: - sage: y = var('y') - sage: f.derivative(y) + sage: y = var('y') # optional - sage.symbolic + sage: f.derivative(y) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: cannot differentiate with respect to y @@ -1743,10 +1748,10 @@ cdef class LaurentSeries(AlgebraElement): Check whether a polynomial over a Laurent series ring is contained in the polynomial ring over the power series ring (see :trac:`19459`): - sage: L. = LaurentSeriesRing(GF(2)) - sage: R. = PolynomialRing(L) - sage: S. = PolynomialRing(L._power_series_ring) - sage: t**(-1)*x*y in S + sage: L. = LaurentSeriesRing(GF(2)) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(L) # optional - sage.rings.finite_rings + sage: S. = PolynomialRing(L._power_series_ring) # optional - sage.rings.finite_rings + sage: t**(-1)*x*y in S # optional - sage.rings.finite_rings False There used to be an issue with non-canonical representations of zero, @@ -1766,8 +1771,8 @@ cdef class LaurentSeries(AlgebraElement): Test for :trac:`32440`:: - sage: L. = LaurentSeriesRing(QQ, implementation='pari') - sage: (x + O(x^3)).power_series() + sage: L. = LaurentSeriesRing(QQ, implementation='pari') # optional - sage.libs.pari + sage: (x + O(x^3)).power_series() # optional - sage.libs.pari x + O(x^3) """ if self.__n < 0: @@ -1808,13 +1813,13 @@ cdef class LaurentSeries(AlgebraElement): x*t^-2 + O(t^2) sage: f(y=x) x*t^-2 + x*t^2 + O(t^8) - sage: f(t^3, x=2, y=x+x^2) + sage: f(t^3, x=2, y=x + x^2) 2*t^-6 + (x^2 + x)*t^6 + O(t^24) sage: f(t^3, 2, x+x^2) 2*t^-6 + (x^2 + x)*t^6 + O(t^24) - sage: f(x=2, t=t^3, y=x+x^2) + sage: f(x=2, t=t^3, y=x + x^2) 2*t^-6 + (x^2 + x)*t^6 + O(t^24) - sage: f(2, x+x^2, t=t^3) + sage: f(2, x + x^2, t=t^3) Traceback (most recent call last): ... ValueError: must not specify t keyword and positional argument @@ -1828,9 +1833,9 @@ cdef class LaurentSeries(AlgebraElement): Test for :trac:`23928`:: - sage: R. = LaurentSeriesRing(QQ, implementation='pari') - sage: f = x.add_bigoh(7) - sage: f(x) + sage: R. = LaurentSeriesRing(QQ, implementation='pari') # optional - sage.libs.pari + sage: f = x.add_bigoh(7) # optional - sage.libs.pari + sage: f(x) # optional - sage.libs.pari x + O(x^7) """ if len(kwds) >= 1: @@ -1870,16 +1875,16 @@ cdef class LaurentSeries(AlgebraElement): sage: L. = LaurentSeriesRing(QQ) sage: f = x + 1/x + O(x^2); f x^-1 + x + O(x^2) - sage: f.__pari__() + sage: f.__pari__() # optional - sage.libs.pari x^-1 + x + O(x^2) Check that :trac:`32437` is fixed:: - sage: F. = GF(257^2) - sage: R. = LaurentSeriesRing(F) - sage: g = t + O(t^99) - sage: f = u*t + O(t^99) - sage: g(f) # indirect doctest + sage: F. = GF(257^2) # optional - sage.rings.finite_rings + sage: R. = LaurentSeriesRing(F) # optional - sage.rings.finite_rings + sage: g = t + O(t^99) # optional - sage.rings.finite_rings + sage: f = u*t + O(t^99) # optional - sage.rings.finite_rings + sage: g(f) # indirect doctest # optional - sage.libs.pari sage.rings.finite_rings u*t + O(t^99) """ f = self.__u diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index f31488d5354..b6c25b26dcf 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -83,9 +83,9 @@ A similar statement is true for lazy symmetric functions:: - sage: h = SymmetricFunctions(QQ).h() - sage: L = LazySymmetricFunctions(h) - sage: 1 / (1-L(h[1])) + sage: h = SymmetricFunctions(QQ).h() # optional - sage.combinat + sage: L = LazySymmetricFunctions(h) # optional - sage.combinat + sage: 1 / (1-L(h[1])) # optional - sage.combinat h[] + h[1] + (h[1,1]) + (h[1,1,1]) + (h[1,1,1,1]) + (h[1,1,1,1,1]) + (h[1,1,1,1,1,1]) + O^7 We can change the base ring:: @@ -145,9 +145,9 @@ sage: check(L, z) sage: L. = LazyPowerSeriesRing(QQ) sage: check(L, z) - sage: p = SymmetricFunctions(QQ).p() - sage: L = LazySymmetricFunctions(p) - sage: check(L, L(p[1])) + sage: p = SymmetricFunctions(QQ).p() # optional - sage.combinat + sage: L = LazySymmetricFunctions(p) # optional - sage.combinat + sage: check(L, L(p[1])) # optional - sage.combinat We check that the elements in the cache of the stream of homogeneous components are in the correct ring:: @@ -171,30 +171,31 @@ ....: yield n ....: n += 1 - sage: L. = LazyLaurentSeriesRing(GF(2)) - sage: check(L, lambda n: n, valuation=-5) - sage: check(L, gen(), valuation=-5) + sage: L. = LazyLaurentSeriesRing(GF(2)) # optional - sage.rings.finite_rings + sage: check(L, lambda n: n, valuation=-5) # optional - sage.rings.finite_rings + sage: check(L, gen(), valuation=-5) # optional - sage.rings.finite_rings sage: L = LazyDirichletSeriesRing(QQbar, "s") sage: check(L, lambda n: n, valuation=2) sage: check(L, gen(), valuation=2) - sage: L. = LazyPowerSeriesRing(GF(2)) - sage: check(L, lambda n: n, valuation=0) - sage: check(L, gen(), valuation=0) + sage: L. = LazyPowerSeriesRing(GF(2)) # optional - sage.rings.finite_rings + sage: check(L, lambda n: n, valuation=0) # optional - sage.rings.finite_rings + sage: check(L, gen(), valuation=0) # optional - sage.rings.finite_rings - sage: L. = LazyPowerSeriesRing(GF(2)) - sage: check(L, lambda n: (x + y)^n, valuation=None) - sage: def gen(): + sage: L. = LazyPowerSeriesRing(GF(2)) # optional - sage.rings.finite_rings + sage: check(L, lambda n: (x + y)^n, valuation=None) # optional - sage.rings.finite_rings + sage: def gen(): # optional - sage.rings.finite_rings ....: n = 0 ....: while True: ....: yield (x+y)^n ....: n += 1 - sage: check(L, gen(), valuation=None) + sage: check(L, gen(), valuation=None) # optional - sage.rings.finite_rings - sage: s = SymmetricFunctions(GF(2)).s() - sage: L = LazySymmetricFunctions(s) - sage: check(L, lambda n: sum(k*s(la) for k, la in enumerate(Partitions(n))), valuation=0) + sage: s = SymmetricFunctions(GF(2)).s() # optional - sage.combinat sage.rings.finite_rings + sage: L = LazySymmetricFunctions(s) # optional - sage.combinat sage.rings.finite_rings + sage: check(L, lambda n: sum(k*s(la) for k, la in enumerate(Partitions(n))), # optional - sage.combinat sage.rings.finite_rings + ....: valuation=0) """ # **************************************************************************** @@ -209,13 +210,12 @@ # https://www.gnu.org/licenses/ # **************************************************************************** +from sage.arith.functions import lcm +from sage.arith.misc import divisors, factorial, moebius +from sage.arith.power import generic_power from sage.structure.element import Element, parent from sage.structure.richcmp import op_EQ, op_NE -from sage.functions.other import factorial from sage.misc.misc_c import prod -from sage.arith.power import generic_power -from sage.arith.functions import lcm -from sage.arith.misc import divisors, moebius from sage.combinat.partition import Partition, Partitions from sage.misc.derivative import derivative_parse from sage.categories.integral_domains import IntegralDomains @@ -436,9 +436,9 @@ def coefficients(self, n=None): sage: f.coefficients() lazy list [1, 1, -1/6, ...] - sage: L. = LazyPowerSeriesRing(GF(2)) - sage: f = L(lambda n: n) - sage: f.coefficients(5) + sage: L. = LazyPowerSeriesRing(GF(2)) # optional - sage.rings.finite_rings + sage: f = L(lambda n: n) # optional - sage.rings.finite_rings + sage: f.coefficients(5) # optional - sage.rings.finite_rings [1, 1, 1, 1, 1] """ coeff_stream = self._coeff_stream @@ -495,9 +495,11 @@ def map_coefficients(self, f): Similarly for Dirichlet series:: sage: L = LazyDirichletSeriesRing(ZZ, "z") - sage: s = L(lambda n: n-1); s + sage: s = L(lambda n: n-1) + sage: s # optional - sage.symbolic 1/(2^z) + 2/3^z + 3/4^z + 4/5^z + 5/6^z + 6/7^z + O(1/(8^z)) - sage: s.map_coefficients(lambda c: c + 1) + sage: ms = s.map_coefficients(lambda c: c + 1) + sage: ms # optional - sage.symbolic 2/2^z + 3/3^z + 4/4^z + 5/5^z + 6/6^z + 7/7^z + 8/8^z + O(1/(9^z)) Similarly for multivariate power series:: @@ -518,12 +520,12 @@ def map_coefficients(self, f): Similarly for lazy symmetric functions:: - sage: p = SymmetricFunctions(QQ).p() - sage: L = LazySymmetricFunctions(p) - sage: f = 1/(1-2*L(p[1])); f + sage: p = SymmetricFunctions(QQ).p() # optional - sage.combinat + sage: L = LazySymmetricFunctions(p) # optional - sage.combinat + sage: f = 1/(1-2*L(p[1])); f # optional - sage.combinat p[] + 2*p[1] + (4*p[1,1]) + (8*p[1,1,1]) + (16*p[1,1,1,1]) + (32*p[1,1,1,1,1]) + (64*p[1,1,1,1,1,1]) + O^7 - sage: f.map_coefficients(lambda c: log(c, 2)) + sage: f.map_coefficients(lambda c: log(c, 2)) # optional - sage.combinat p[1] + (2*p[1,1]) + (3*p[1,1,1]) + (4*p[1,1,1,1]) + (5*p[1,1,1,1,1]) + (6*p[1,1,1,1,1,1]) + O^7 @@ -660,9 +662,11 @@ def shift(self, n): 2 + 3*z^2 + z^5 + z^6 + z^7 + O(z^8) sage: D = LazyDirichletSeriesRing(QQ, 't') - sage: f = D([0,1,2]); f + sage: f = D([0,1,2]) + sage: f # optional - sage.symbolic 1/(2^t) + 2/3^t - sage: f.shift(3) + sage: sf = f.shift(3) + sage: sf # optional - sage.symbolic 1/(5^t) + 2/6^t Examples with power series (where the minimal valuation is `0`):: @@ -1006,60 +1010,60 @@ def __bool__(self): TESTS:: - sage: L. = LazyLaurentSeriesRing(GF(2)) - sage: bool(z-z) + sage: L. = LazyLaurentSeriesRing(GF(2)) # optional - sage.rings.finite_rings + sage: bool(z - z) # optional - sage.rings.finite_rings False - sage: f = 1/(1 - z) - sage: bool(f) + sage: f = 1/(1 - z) # optional - sage.rings.finite_rings + sage: bool(f) # optional - sage.rings.finite_rings True - sage: M = L(lambda n: n, valuation=0); M + sage: M = L(lambda n: n, valuation=0); M # optional - sage.rings.finite_rings z + z^3 + z^5 + O(z^7) - sage: M.is_zero() + sage: M.is_zero() # optional - sage.rings.finite_rings False - sage: M = L(lambda n: 2*n if n < 10 else 1, valuation=0); M + sage: M = L(lambda n: 2*n if n < 10 else 1, valuation=0); M # optional - sage.rings.finite_rings O(z^7) - sage: bool(M) + sage: bool(M) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: undecidable as lazy Laurent series - sage: M[15] + sage: M[15] # optional - sage.rings.finite_rings 1 - sage: bool(M) + sage: bool(M) # optional - sage.rings.finite_rings True - sage: L. = LazyLaurentSeriesRing(GF(2), sparse=True) - sage: M = L(lambda n: 2*n if n < 10 else 1, valuation=0); M + sage: L. = LazyLaurentSeriesRing(GF(2), sparse=True) # optional - sage.rings.finite_rings + sage: M = L(lambda n: 2*n if n < 10 else 1, valuation=0); M # optional - sage.rings.finite_rings O(z^7) - sage: bool(M) + sage: bool(M) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: undecidable as lazy Laurent series - sage: M[15] + sage: M[15] # optional - sage.rings.finite_rings 1 - sage: bool(M) + sage: bool(M) # optional - sage.rings.finite_rings True Uninitialized series:: - sage: g = L.undefined(valuation=0) - sage: bool(g) + sage: g = L.undefined(valuation=0) # optional - sage.rings.finite_rings + sage: bool(g) # optional - sage.rings.finite_rings True - sage: g.define(0) - sage: bool(g) + sage: g.define(0) # optional - sage.rings.finite_rings + sage: bool(g) # optional - sage.rings.finite_rings False - sage: g = L.undefined(valuation=0) - sage: bool(g) + sage: g = L.undefined(valuation=0) # optional - sage.rings.finite_rings + sage: bool(g) # optional - sage.rings.finite_rings True - sage: g.define(1 + z) - sage: bool(g) + sage: g.define(1 + z) # optional - sage.rings.finite_rings + sage: bool(g) # optional - sage.rings.finite_rings True - sage: g = L.undefined(valuation=0) - sage: bool(g) + sage: g = L.undefined(valuation=0) # optional - sage.rings.finite_rings + sage: bool(g) # optional - sage.rings.finite_rings True - sage: g.define(1 + z*g) - sage: bool(g) + sage: g.define(1 + z*g) # optional - sage.rings.finite_rings + sage: bool(g) # optional - sage.rings.finite_rings True """ if isinstance(self._coeff_stream, Stream_zero): @@ -1186,7 +1190,7 @@ def define(self, s): sage: F.define(1 + g*F) sage: F[:16] [1, 1, 1, 2, 1, 3, 1, 4, 2, 3, 1, 8, 1, 3, 3] - sage: oeis(_) # optional, internet + sage: oeis(_) # optional - internet 0: A002033: Number of perfect partitions of n. 1: A074206: Kalmár's [Kalmar's] problem: number of ordered factorizations of n. ... @@ -1198,14 +1202,14 @@ def define(self, s): We can compute the Frobenius character of unlabeled trees:: - sage: m = SymmetricFunctions(QQ).m() - sage: s = SymmetricFunctions(QQ).s() - sage: L = LazySymmetricFunctions(m) - sage: E = L(lambda n: s[n], valuation=0) - sage: X = L(s[1]) - sage: A = L.undefined() - sage: A.define(X*E(A, check=False)) - sage: A[:6] + sage: m = SymmetricFunctions(QQ).m() # optional - sage.combinat + sage: s = SymmetricFunctions(QQ).s() # optional - sage.combinat + sage: L = LazySymmetricFunctions(m) # optional - sage.combinat + sage: E = L(lambda n: s[n], valuation=0) # optional - sage.combinat + sage: X = L(s[1]) # optional - sage.combinat + sage: A = L.undefined() # optional - sage.combinat + sage: A.define(X*E(A, check=False)) # optional - sage.combinat + sage: A[:6] # optional - sage.combinat [m[1], 2*m[1, 1] + m[2], 9*m[1, 1, 1] + 5*m[2, 1] + 2*m[3], @@ -1247,7 +1251,7 @@ def define(self, s): sage: g = D.undefined(valuation=2) sage: o = D(constant=1, valuation=2) sage: g.define(o * e(g)) - sage: g + sage: g # optional - sage.symbolic 1/(2^s) + 1/(3^s) + 2/4^s + 1/(5^s) + 3/6^s + 1/(7^s) + 9/2/8^s + O(1/(9^s)) For Laurent series there is no minimal valuation, so it has @@ -1272,10 +1276,10 @@ def define(self, s): sage: g = D([0, 1]) sage: f = D.undefined() sage: f.define(1 + ~f*g) - sage: f + sage: f # optional - sage.symbolic 1 + 1/(2^s) - 1/(4^s) + O(1/(8^s)) - sage: oeis(f[:30]) # optional, internet + sage: oeis(f[:30]) # optional - internet 0: A122698: a(1)=a(2)=1 then a(n) = Sum_{d|n, 1 = LazyLaurentSeriesRing(e) - sage: L.options.display_length = 3 - sage: ascii_art(1 / (1 - e[1]*z)) + sage: e = SymmetricFunctions(QQ).e() # optional - sage.combinat + sage: L. = LazyLaurentSeriesRing(e) # optional - sage.combinat + sage: L.options.display_length = 3 # optional - sage.combinat + sage: ascii_art(1 / (1 - e[1]*z)) # optional - sage.combinat e[] + e[1]*z + e[1, 1]*z^2 + O(e[]*z^3) - sage: L.options._reset() + sage: L.options._reset() # optional - sage.combinat """ from sage.typeset.ascii_art import ascii_art, AsciiArt if isinstance(self._coeff_stream, Stream_zero): @@ -1475,12 +1479,12 @@ def _unicode_art_(self): EXAMPLES:: - sage: e = SymmetricFunctions(QQ).e() - sage: L. = LazyLaurentSeriesRing(e) - sage: L.options.display_length = 3 - sage: unicode_art(1 / (1 - e[1]*z)) + sage: e = SymmetricFunctions(QQ).e() # optional - sage.combinat + sage: L. = LazyLaurentSeriesRing(e) # optional - sage.combinat + sage: L.options.display_length = 3 # optional - sage.combinat + sage: unicode_art(1 / (1 - e[1]*z)) # optional - sage.combinat e[] + e[1]*z + e[1, 1]*z^2 + O(e[]*z^3) - sage: L.options._reset() + sage: L.options._reset() # optional - sage.combinat """ from sage.typeset.unicode_art import unicode_art, UnicodeArt if isinstance(self._coeff_stream, Stream_zero): @@ -1534,7 +1538,8 @@ def change_ring(self, ring): sage: t = s.change_ring(QQ) sage: t.parent() Lazy Dirichlet Series Ring in z over Rational Field - sage: t^-1 + sage: it = t^-1 + sage: it # optional - sage.symbolic 1/2 - 1/2/2^z - 1/2/3^z - 1/2/5^z + 1/2/6^z - 1/2/7^z + O(1/(8^z)) A Taylor series example:: @@ -1601,23 +1606,29 @@ def _add_(self, other): Similarly for Dirichlet series:: sage: L = LazyDirichletSeriesRing(ZZ, "z") - sage: s = L(lambda n: n); s + sage: s = L(lambda n: n) + sage: s # optional - sage.symbolic 1 + 2/2^z + 3/3^z + 4/4^z + 5/5^z + 6/6^z + 7/7^z + O(1/(8^z)) - sage: t = L(constant=1); t + sage: t = L(constant=1) + sage: t # optional - sage.symbolic 1 + 1/(2^z) + 1/(3^z) + O(1/(4^z)) - sage: s + t + sage: st = s + t + sage: st # optional - sage.symbolic 2 + 3/2^z + 4/3^z + 5/4^z + 6/5^z + 7/6^z + 8/7^z + O(1/(8^z)) sage: r = L(constant=-1) - sage: r + t + sage: rt = r + t + sage: rt # optional - sage.symbolic 0 sage: r = L([1,2,3]) - sage: r + t + sage: rt = r + t + sage: rt # optional - sage.symbolic 2 + 3/2^z + 4/3^z + 1/(4^z) + 1/(5^z) + 1/(6^z) + O(1/(7^z)) sage: r = L([1,2,3], constant=-1) - sage: r + t + sage: rt = r + t + sage: rt # optional - sage.symbolic 2 + 3/2^z + 4/3^z """ P = self.parent() @@ -1812,15 +1823,16 @@ def _acted_upon_(self, scalar, self_on_left): sage: L = LazyDirichletSeriesRing(ZZ, "z") sage: g = L([0,1]) - sage: 2 * g + sage: 2 * g # optional - sage.symbolic 2/2^z - sage: -1 * g + sage: -1 * g # optional - sage.symbolic -1/(2^z) - sage: 0*g + sage: 0*g # optional - sage.symbolic 0 - sage: M = L(lambda n: n); M + sage: M = L(lambda n: n) + sage: M # optional - sage.symbolic 1 + 2/2^z + 3/3^z + 4/4^z + 5/5^z + 6/6^z + 7/7^z + O(1/(8^z)) - sage: 3 * M + sage: 3 * M # optional - sage.symbolic 3 + 6/2^z + 9/3^z + 12/4^z + 15/5^z + 18/6^z + 21/7^z + O(1/(8^z)) sage: 1 * M is M @@ -1943,7 +1955,7 @@ def exp(self): sage: L = LazyDirichletSeriesRing(QQ, "s") sage: Z = L(constant=1, valuation=2) - sage: exp(Z) + sage: exp(Z) # optional - sage.symbolic 1 + 1/(2^s) + 1/(3^s) + 3/2/4^s + 1/(5^s) + 2/6^s + 1/(7^s) + O(1/(8^s)) """ from .lazy_series_ring import LazyLaurentSeriesRing @@ -1959,7 +1971,7 @@ def log(self): sage: L = LazyDirichletSeriesRing(QQ, "s") sage: Z = L(constant=1) - sage: log(Z) + sage: log(Z) # optional - sage.symbolic 1/(2^s) + 1/(3^s) + 1/2/4^s + 1/(5^s) + 1/(7^s) + O(1/(8^s)) """ from .lazy_series_ring import LazyLaurentSeriesRing @@ -2612,14 +2624,14 @@ def __pow__(self, n): sage: D = LazyDirichletSeriesRing(QQ, 's') sage: Z = D(constant=1) - sage: Z^2 + sage: Z^2 # optional - sage.symbolic 1 + 2/2^s + 2/3^s + 3/4^s + 2/5^s + 4/6^s + 2/7^s + O(1/(8^s)) sage: f = Z^(1/3) - sage: f + sage: f # optional - sage.symbolic 1 + 1/3/2^s + 1/3/3^s + 2/9/4^s + 1/3/5^s + 1/9/6^s + 1/3/7^s + O(1/(8^s)) - sage: f^2 + sage: f^2 # optional - sage.symbolic 1 + 2/3/2^s + 2/3/3^s + 5/9/4^s + 2/3/5^s + 4/9/6^s + 2/3/7^s + O(1/(8^s)) - sage: f^3 - Z + sage: f^3 - Z # optional - sage.symbolic O(1/(8^s)) sage: L. = LazyLaurentSeriesRing(QQ) @@ -2676,9 +2688,9 @@ def sqrt(self): sage: D = LazyDirichletSeriesRing(SR, "s") sage: Z = D(constant=1) sage: f = sqrt(Z) - sage: f + sage: f # optional - sage.symbolic 1 + 1/2/2^s + 1/2/3^s + 3/8/4^s + 1/2/5^s + 1/4/6^s + 1/2/7^s + O(1/(8^s)) - sage: f*f - Z + sage: f*f - Z # optional - sage.symbolic O(1/(8^s)) """ return self ** QQ((1, 2)) # == 1/2 @@ -3490,17 +3502,16 @@ def _im_gens_(self, codomain, im_gens, base_map=None): EXAMPLES:: sage: Z. = ZZ[] - sage: K. = NumberField(x^2 + 1) - sage: R. = LazyLaurentSeriesRing(K) - sage: f = R(lambda n: i^n, valuation=-2) - sage: f + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: R. = LazyLaurentSeriesRing(K) # optional - sage.rings.number_field + sage: f = R(lambda n: i^n, valuation=-2); f # optional - sage.rings.number_field -t^-2 - i*t^-1 + 1 + i*t - t^2 - i*t^3 + t^4 + O(t^5) - sage: f._im_gens_(R, [t + t^2]) + sage: f._im_gens_(R, [t + t^2]) # optional - sage.rings.number_field -t^-2 + (-i + 2)*t^-1 + (i - 2) + 4*t + (2*i - 6)*t^2 + (-2*i + 4)*t^3 + (-2*i - 7)*t^4 + O(t^5) - sage: cc = K.hom([-i]) - sage: f._im_gens_(R, [t + t^2], base_map=cc) + sage: cc = K.hom([-i]) # optional - sage.rings.number_field + sage: f._im_gens_(R, [t + t^2], base_map=cc) # optional - sage.rings.number_field -t^-2 + (i + 2)*t^-1 + (-i - 2) + 4*t + (-2*i - 6)*t^2 + (2*i + 4)*t^3 + (2*i - 7)*t^4 + O(t^5) """ @@ -3736,7 +3747,8 @@ def __call__(self, g, *, check=True): sage: L. = LazyLaurentSeriesRing(QQ) sage: e = L(lambda n: 1/factorial(n), 0) sage: D = LazyDirichletSeriesRing(QQ, "s") - sage: g = D(constant=1)-1; g + sage: g = D(constant=1)-1 + sage: g # optional - sage.symbolic 1/(2^s) + 1/(3^s) + 1/(4^s) + O(1/(5^s)) sage: e(g)[0:10] @@ -3745,7 +3757,8 @@ def __call__(self, g, *, check=True): sage: sum(g^k/factorial(k) for k in range(10))[0:10] [0, 1, 1, 1, 3/2, 1, 2, 1, 13/6, 3/2] - sage: g = D([0,1,0,1,1,2]); g + sage: g = D([0,1,0,1,1,2]) + sage: g # optional - sage.symbolic 1/(2^s) + 1/(4^s) + 1/(5^s) + 2/6^s sage: e(g)[0:10] [0, 1, 1, 0, 3/2, 1, 2, 0, 7/6, 0] @@ -3757,11 +3770,12 @@ def __call__(self, g, *, check=True): ... ValueError: can only compose with a positive valuation series - sage: e5 = L(e, degree=5); e5 + sage: e5 = L(e, degree=5) + sage: e5 # optional - sage.symbolic 1 + z + 1/2*z^2 + 1/6*z^3 + 1/24*z^4 - sage: e5(g) + sage: e5(g) # optional - sage.symbolic 1 + 1/(2^s) + 3/2/4^s + 1/(5^s) + 2/6^s + O(1/(8^s)) - sage: sum(e5[k] * g^k for k in range(5)) + sage: sum(e5[k] * g^k for k in range(5)) # optional - sage.symbolic 1 + 1/(2^s) + 3/2/4^s + 1/(5^s) + 2/6^s + O(1/(8^s)) The output parent is always the common parent between the base ring @@ -4532,24 +4546,27 @@ def __call__(self, *g, check=True): We perform the composition with a lazy Dirichlet series:: sage: D = LazyDirichletSeriesRing(QQ, "s") - sage: g = D(constant=1)-1; g + sage: g = D(constant=1)-1 + sage: g # optional - sage.symbolic 1/(2^s) + 1/(3^s) + 1/(4^s) + O(1/(5^s)) sage: f = 1 / (1 - x - y*z); f 1 + x + (x^2+y*z) + (x^3+2*x*y*z) + (x^4+3*x^2*y*z+y^2*z^2) + (x^5+4*x^3*y*z+3*x*y^2*z^2) + (x^6+5*x^4*y*z+6*x^2*y^2*z^2+y^3*z^3) + O(x,y,z)^7 - sage: fog = f(g, g, g); fog + sage: fog = f(g, g, g) + sage: fog # optional - sage.symbolic 1 + 1/(2^s) + 1/(3^s) + 3/4^s + 1/(5^s) + 5/6^s + O(1/(7^s)) - sage: fg = 1 / (1 - g - g*g); fg + sage: fg = 1 / (1 - g - g*g) + sage: fg # optional - sage.symbolic 1 + 1/(2^s) + 1/(3^s) + 3/4^s + 1/(5^s) + 5/6^s + 1/(7^s) + O(1/(8^s)) - sage: fog - fg + sage: fog - fg # optional - sage.symbolic O(1/(8^s)) sage: f = 1 / (1 - 2*a) - sage: f(g) + sage: f(g) # optional - sage.symbolic 1 + 2/2^s + 2/3^s + 6/4^s + 2/5^s + 10/6^s + 2/7^s + O(1/(8^s)) - sage: 1 / (1 - 2*g) + sage: 1 / (1 - 2*g) # optional - sage.symbolic 1 + 2/2^s + 2/3^s + 6/4^s + 2/5^s + 10/6^s + 2/7^s + O(1/(8^s)) The output parent is always the common parent between the base ring @@ -6319,7 +6336,8 @@ class LazyDirichletSeries(LazyModuleElement): EXAMPLES:: sage: L = LazyDirichletSeriesRing(ZZ, "z") - sage: f = L(constant=1)^2; f + sage: f = L(constant=1)^2 + sage: f # optional - sage.symbolic 1 + 2/2^z + 2/3^z + 3/4^z + 2/5^z + 4/6^z + 2/7^z + O(1/(8^z)) sage: f.coefficient(100) == number_of_divisors(100) True @@ -6327,7 +6345,7 @@ class LazyDirichletSeries(LazyModuleElement): Lazy Dirichlet series is picklable:: sage: g = loads(dumps(f)) - sage: g + sage: g # optional - sage.symbolic 1 + 2/2^z + 2/3^z + 3/4^z + 2/5^z + 4/6^z + 2/7^z + O(1/(8^z)) sage: g == f True @@ -6393,35 +6411,37 @@ def _mul_(self, other): TESTS:: sage: D = LazyDirichletSeriesRing(QQ, "s") - sage: zeta = D(constant=1); zeta + sage: zeta = D(constant=1) + sage: zeta # optional - sage.symbolic 1 + 1/(2^s) + 1/(3^s) + O(1/(4^s)) - sage: zeta * zeta + sage: zeta * zeta # optional - sage.symbolic 1 + 2/2^s + 2/3^s + 3/4^s + 2/5^s + 4/6^s + 2/7^s + O(1/(8^s)) sage: [number_of_divisors(n) for n in range(1, 8)] [1, 2, 2, 3, 2, 4, 2] - sage: mu = D(moebius); mu + sage: mu = D(moebius) + sage: mu # optional - sage.symbolic 1 - 1/(2^s) - 1/(3^s) - 1/(5^s) + 1/(6^s) - 1/(7^s) + O(1/(8^s)) - sage: zeta * mu + sage: zeta * mu # optional - sage.symbolic 1 + O(1/(8^s)) sage: D.one() * mu is mu True sage: mu * D.one() is mu True - sage: zeta*(2-zeta) + sage: zeta*(2-zeta) # optional - sage.symbolic 1 - 1/(4^s) - 2/6^s + O(1/(8^s)) sage: d1 = D([0,0,1,2,3]) sage: d2 = D([0,1,2,3]) - sage: d1 * d2 + sage: d1 * d2 # optional - sage.symbolic 1/(6^s) + 2/8^s + 2/9^s + 3/10^s + 7/12^s + O(1/(13^s)) - sage: d1 * d2 # not tested - exact result + sage: d1 * d2 # not tested - exact result # optional - sage.symbolic 1/(6^s) + 2/8^s + 2/9^s + 3/10^s + 7/12^s + 6/15^s + 6/16^s + 9/20^s sage: L. = LazyLaurentSeriesRing(D) - sage: 1/(1-t*zeta) + sage: 1/(1-t*zeta) # optional - sage.symbolic (1 + O(1/(8^s))) + (1 + 1/(2^s) + 1/(3^s) + 1/(4^s) + 1/(5^s) + 1/(6^s) + 1/(7^s) + O(1/(8^s)))*t + (1 + 2/2^s + 2/3^s + 3/4^s + 2/5^s + 4/6^s + 2/7^s + O(1/(8^s)))*t^2 @@ -6534,7 +6554,8 @@ def __call__(self, p, *, check=True): sage: Z(1) Infinity - sage: f = D([1,2,-3,-4], valuation=2); f + sage: f = D([1,2,-3,-4], valuation=2) + sage: f # optional - sage.symbolic 1/(2^s) + 2/3^s - 3/4^s - 4/5^s sage: f(2) 449/3600 @@ -6604,22 +6625,22 @@ def _format_series(self, formatter, format_strings=False): sage: L = LazyDirichletSeriesRing(QQ, "s") sage: f = L(constant=1) - sage: f._format_series(repr) + sage: f._format_series(repr) # optional - sage.symbolic '1 + 1/(2^s) + 1/(3^s) + O(1/(4^s))' - sage: f._format_series(unicode_art) + sage: f._format_series(unicode_art) # optional - sage.symbolic -s -s 1 + 2 + 3 + O(1/(4^s)) - sage: L([1,-1,1])._format_series(repr) + sage: L([1,-1,1])._format_series(repr) # optional - sage.symbolic '1 - 1/(2^s) + 1/(3^s)' - sage: L([1,-1,1])._format_series(ascii_art) + sage: L([1,-1,1])._format_series(ascii_art) # optional - sage.symbolic -s -s 1 + -2 + 3 sage: R. = QQ[] sage: L = LazyDirichletSeriesRing(R, "s") - sage: L([1,-1 + x,1/3])._format_series(ascii_art) + sage: L([1,-1 + x,1/3])._format_series(ascii_art) # optional - sage.symbolic ( -s) (3 ) ( -s ) (---) @@ -6627,9 +6648,10 @@ def _format_series(self, formatter, format_strings=False): sage: L. = LazyLaurentSeriesRing(QQ) sage: D = LazyDirichletSeriesRing(L, "s") - sage: f = D([2, 0, 1/(1-z), 3]); f + sage: f = D([2, 0, 1/(1-z), 3]) + sage: f # optional - sage.symbolic (2)/1^s + ((1+z+z^2+O(z^3))/3^s) + (3)/4^s - sage: f._format_series(ascii_art) + sage: f._format_series(ascii_art) # optional - sage.symbolic ((2)/1^s) + ((1 + z + z^2 + O(z^3))/3^s) + ((3)/4^s) """ P = self.parent() diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index d8ba728a61b..89d4cd39127 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -52,6 +52,7 @@ CompleteDiscreteValuationRings) from sage.misc.cachefunc import cached_method +from sage.misc.lazy_attribute import lazy_attribute from sage.rings.integer_ring import ZZ from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing @@ -64,7 +65,6 @@ LazySymmetricFunction, LazyDirichletSeries) from sage.structure.global_options import GlobalOptions -from sage.symbolic.ring import SR from sage.data_structures.stream import ( Stream_zero, @@ -155,10 +155,10 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No If ``x`` can be converted into an element of the underlying Laurent polynomial ring, we do this:: - sage: L = LazyLaurentSeriesRing(GF(2), 'z') - sage: L(2) + sage: L = LazyLaurentSeriesRing(GF(2), 'z') # optional - sage.rings.finite_rings + sage: L(2) # optional - sage.rings.finite_rings 0 - sage: L(3) + sage: L(3) # optional - sage.rings.finite_rings 1 In particular, ``x`` can be a Laurent polynomial:: @@ -288,21 +288,21 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No Converting various series from a univariate power series:: - sage: L = LazyLaurentSeriesRing(GF(2), 'z') - sage: R = LazyPowerSeriesRing(ZZ, 'z') - sage: L.has_coerce_map_from(R) + sage: L = LazyLaurentSeriesRing(GF(2), 'z') # optional - sage.rings.finite_rings + sage: R = LazyPowerSeriesRing(ZZ, 'z') # optional - sage.rings.finite_rings + sage: L.has_coerce_map_from(R) # optional - sage.rings.finite_rings True - sage: L(R(lambda n: n)) + sage: L(R(lambda n: n)) # optional - sage.rings.finite_rings z + z^3 + z^5 + z^7 + O(z^8) - sage: L(R([2,4,6])) == L.zero() + sage: L(R([2,4,6])) == L.zero() # optional - sage.rings.finite_rings True - sage: L(R([2,4,6], valuation=2, constant=4)) == L.zero() + sage: L(R([2,4,6], valuation=2, constant=4)) == L.zero() # optional - sage.rings.finite_rings True - sage: L(R([2,4,6], valuation=2, constant=5)) + sage: L(R([2,4,6], valuation=2, constant=5)) # optional - sage.rings.finite_rings z^5 + z^6 + z^7 + O(z^8) - sage: L(R([2,3,4], valuation=2, constant=4)) + sage: L(R([2,3,4], valuation=2, constant=4)) # optional - sage.rings.finite_rings z^3 - sage: L(R([2,3,4], valuation=2, constant=5)) + sage: L(R([2,3,4], valuation=2, constant=5)) # optional - sage.rings.finite_rings z^3 + z^5 + z^6 + z^7 + O(z^8) Can only convert from known to be constant multivariate power series:: @@ -760,14 +760,14 @@ def characteristic(self): sage: L.characteristic() 0 - sage: R. = LazyLaurentSeriesRing(GF(11)); R + sage: R. = LazyLaurentSeriesRing(GF(11)); R # optional - sage.rings.finite_rings Lazy Laurent Series Ring in w over Finite Field of size 11 - sage: R.characteristic() + sage: R.characteristic() # optional - sage.rings.finite_rings 11 - sage: R. = LazyPowerSeriesRing(GF(7)); R + sage: R. = LazyPowerSeriesRing(GF(7)); R # optional - sage.rings.finite_rings Multivariate Lazy Taylor Series Ring in x, y over Finite Field of size 7 - sage: R.characteristic() + sage: R.characteristic() # optional - sage.rings.finite_rings 7 sage: L = LazyDirichletSeriesRing(ZZ, "s") @@ -782,13 +782,13 @@ def _coerce_map_from_(self, S): EXAMPLES:: - sage: L = LazyLaurentSeriesRing(GF(2), 'z') - sage: L.has_coerce_map_from(ZZ) + sage: L = LazyLaurentSeriesRing(GF(2), 'z') # optional - sage.rings.finite_rings + sage: L.has_coerce_map_from(ZZ) # optional - sage.rings.finite_rings True - sage: L.has_coerce_map_from(GF(2)) + sage: L.has_coerce_map_from(GF(2)) # optional - sage.rings.finite_rings True sage: R = LazyPowerSeriesRing(ZZ, 'z') - sage: L.has_coerce_map_from(R) + sage: L.has_coerce_map_from(R) # optional - sage.rings.finite_rings True sage: L = LazyLaurentSeriesRing(QQ, 'z') @@ -802,17 +802,17 @@ def _coerce_map_from_(self, S): sage: L.has_coerce_map_from(R) False - sage: L = LazyPowerSeriesRing(GF(2), 'z') - sage: L.has_coerce_map_from(ZZ) + sage: L = LazyPowerSeriesRing(GF(2), 'z') # optional - sage.rings.finite_rings + sage: L.has_coerce_map_from(ZZ) # optional - sage.rings.finite_rings True - sage: L.has_coerce_map_from(GF(2)) + sage: L.has_coerce_map_from(GF(2)) # optional - sage.rings.finite_rings True - sage: s = SymmetricFunctions(GF(2)).s() - sage: L = LazySymmetricFunctions(s) - sage: L.has_coerce_map_from(ZZ) + sage: s = SymmetricFunctions(GF(2)).s() # optional - sage.rings.finite_rings + sage: L = LazySymmetricFunctions(s) # optional - sage.rings.finite_rings + sage: L.has_coerce_map_from(ZZ) # optional - sage.rings.finite_rings True - sage: L.has_coerce_map_from(GF(2)) + sage: L.has_coerce_map_from(GF(2)) # optional - sage.rings.finite_rings True """ if self.base_ring().has_coerce_map_from(S): @@ -845,11 +845,14 @@ def _coerce_map_from_base_ring(self): sage: L = LazyDirichletSeriesRing(QQ, 'z') sage: phi = L._coerce_map_from_base_ring() - sage: phi(2) + sage: m = phi(2) + sage: m # optional - sage.symbolic 2 - sage: phi(2, valuation=2) + sage: m = phi(2, valuation=2) + sage: m # optional - sage.symbolic 2/2^z - sage: phi(2, valuation=2, constant=4) + sage: m = phi(2, valuation=2, constant=4) + sage: m # optional - sage.symbolic 2/2^z + 4/3^z + 4/4^z + 4/5^z + O(1/(6^z)) """ # Return a DefaultConvertMap_unique; this can pass additional @@ -1048,12 +1051,12 @@ class LazyLaurentSeriesRing(LazySeriesRing): Lazy Laurent series ring over a finite field:: - sage: L. = LazyLaurentSeriesRing(GF(3)); L + sage: L. = LazyLaurentSeriesRing(GF(3)); L # optional - sage.rings.finite_rings Lazy Laurent Series Ring in z over Finite Field of size 3 - sage: e = 1 / (1 + z) - sage: e.coefficient(100) + sage: e = 1 / (1 + z) # optional - sage.rings.finite_rings + sage: e.coefficient(100) # optional - sage.rings.finite_rings 1 - sage: e.coefficient(100).parent() + sage: e.coefficient(100).parent() # optional - sage.rings.finite_rings Finite Field of size 3 Series can be defined by specifying a coefficient function @@ -1202,14 +1205,14 @@ def __init__(self, base_ring, names, sparse=True, category=None): (euclidean domains and infinite enumerated sets and metric spaces) and infinite sets) - sage: L = LazyLaurentSeriesRing(GF(5), 't') - sage: TestSuite(L).run() + sage: L = LazyLaurentSeriesRing(GF(5), 't') # optional - sage.rings.finite_rings + sage: TestSuite(L).run() # optional - sage.rings.finite_rings - sage: L = LazyLaurentSeriesRing(GF(5)['x'], 't') - sage: TestSuite(L).run() + sage: L = LazyLaurentSeriesRing(GF(5)['x'], 't') # optional - sage.rings.finite_rings + sage: TestSuite(L).run() # optional - sage.rings.finite_rings - sage: L = LazyLaurentSeriesRing(GF(5)['x, y'], 't') - sage: TestSuite(L).run() + sage: L = LazyLaurentSeriesRing(GF(5)['x, y'], 't') # optional - sage.rings.finite_rings + sage: TestSuite(L).run() # optional - sage.rings.finite_rings sage: L = LazyLaurentSeriesRing(Zmod(6), 't') sage: TestSuite(L).run(skip=['_test_revert']) @@ -1252,7 +1255,7 @@ def _repr_(self): EXAMPLES:: - sage: LazyLaurentSeriesRing(GF(2), 'z') + sage: LazyLaurentSeriesRing(GF(2), 'z') # optional - sage.rings.finite_rings Lazy Laurent Series Ring in z over Finite Field of size 2 """ return "Lazy Laurent Series Ring in {} over {}".format(self.variable_name(), self.base_ring()) @@ -1263,8 +1266,8 @@ def _latex_(self): EXAMPLES:: - sage: L = LazyLaurentSeriesRing(GF(2), 'z') - sage: latex(L) + sage: L = LazyLaurentSeriesRing(GF(2), 'z') # optional - sage.rings.finite_rings + sage: latex(L) # optional - sage.rings.finite_rings \Bold{F}_{2} (\!(z)\!) """ from sage.misc.latex import latex @@ -1349,16 +1352,16 @@ def some_elements(self): -2*z^-3 - 2*z^-2 + 4*z^-1 + 11 - z - 34*z^2 - 31*z^3 + O(z^4), 4*z^-2 + z^-1 + z + 4*z^2 + 9*z^3 + 16*z^4 + O(z^5)] - sage: L = LazyLaurentSeriesRing(GF(2), 'z') - sage: L.some_elements()[:7] + sage: L = LazyLaurentSeriesRing(GF(2), 'z') # optional - sage.rings.finite_rings + sage: L.some_elements()[:7] # optional - sage.rings.finite_rings [0, 1, z, z^-4 + z^-3 + z^2 + z^3, z^-2, 1 + z + z^3 + z^4 + z^6 + O(z^7), z^-1 + z + z^3 + O(z^5)] - sage: L = LazyLaurentSeriesRing(GF(3), 'z') - sage: L.some_elements()[:7] + sage: L = LazyLaurentSeriesRing(GF(3), 'z') # optional - sage.rings.finite_rings + sage: L.some_elements()[:7] # optional - sage.rings.finite_rings [0, 1, z, z^-3 + z^-1 + 2 + z + z^2 + z^3, z^-2, @@ -1666,11 +1669,11 @@ def __init__(self, base_ring, names, sparse=True, category=None): sage: L = LazyPowerSeriesRing(QQ, 's, t') sage: TestSuite(L).run(skip="_test_fraction_field") - sage: L = LazyPowerSeriesRing(GF(5), 't') - sage: TestSuite(L).run() + sage: L = LazyPowerSeriesRing(GF(5), 't') # optional - sage.rings.finite_rings + sage: TestSuite(L).run() # optional - sage.rings.finite_rings - sage: L = LazyPowerSeriesRing(GF(5), 's, t') - sage: TestSuite(L).run(skip=['_test_fraction_field']) + sage: L = LazyPowerSeriesRing(GF(5), 's, t') # optional - sage.rings.finite_rings + sage: TestSuite(L).run(skip=['_test_fraction_field']) # optional - sage.rings.finite_rings sage: L = LazyPowerSeriesRing(Zmod(6), 't') sage: TestSuite(L).run(skip=['_test_revert']) @@ -1752,7 +1755,7 @@ def _repr_(self): EXAMPLES:: - sage: LazyPowerSeriesRing(GF(2), 'z') + sage: LazyPowerSeriesRing(GF(2), 'z') # optional - sage.rings.finite_rings Lazy Taylor Series Ring in z over Finite Field of size 2 """ BR = self.base_ring() @@ -1767,8 +1770,8 @@ def _latex_(self): EXAMPLES:: - sage: L = LazyPowerSeriesRing(GF(2), 'z') - sage: latex(L) + sage: L = LazyPowerSeriesRing(GF(2), 'z') # optional - sage.rings.finite_rings + sage: latex(L) # optional - sage.rings.finite_rings \Bold{F}_{2} [\![z]\!] """ from sage.misc.latex import latex @@ -1866,10 +1869,10 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No EXAMPLES:: - sage: L = LazyPowerSeriesRing(GF(2), 'z') - sage: L(2) + sage: L = LazyPowerSeriesRing(GF(2), 'z') # optional - sage.rings.finite_rings + sage: L(2) # optional - sage.rings.finite_rings 0 - sage: L(3) + sage: L(3) # optional - sage.rings.finite_rings 1 sage: L = LazyPowerSeriesRing(ZZ, 'z') @@ -1883,7 +1886,7 @@ def _element_constructor_(self, x=None, valuation=None, constant=None, degree=No sage: X.valuation() 2 - sage: e = L(lambda n: n+1); e + sage: e = L(lambda n: n + 1); e 1 + 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7) sage: f = e^-1; f 1 - 2*z + z^2 + O(z^7) @@ -2188,15 +2191,15 @@ def some_elements(self): 1 + z - 2*z^2 - 7*z^3 - z^4 + 20*z^5 + 23*z^6 + O(z^7), z + 4*z^2 + 9*z^3 + 16*z^4 + 25*z^5 + 36*z^6 + O(z^7)] - sage: L = LazyPowerSeriesRing(GF(3)["q"], 'z') - sage: L.some_elements()[:6] + sage: L = LazyPowerSeriesRing(GF(3)["q"], 'z') # optional - sage.rings.finite_rings + sage: L.some_elements()[:6] # optional - sage.rings.finite_rings [0, 1, z + q*z^2 + q*z^3 + q*z^4 + O(z^5), z + z^2 + z^3, 1 + z + z^2 + 2*z^3 + 2*z^4 + 2*z^5 + O(z^6), z + z^2 + z^4 + z^5 + O(z^7)] - sage: L = LazyPowerSeriesRing(GF(3), 'q, t') - sage: L.some_elements()[:6] + sage: L = LazyPowerSeriesRing(GF(3), 'q, t') # optional - sage.rings.finite_rings + sage: L.some_elements()[:6] # optional - sage.rings.finite_rings [0, 1, q, q + q^2 + q^3, 1 + q + q^2 + (-q^3) + (-q^4) + (-q^5) + (-q^6) + O(q,t)^7, @@ -2274,9 +2277,9 @@ def __init__(self, basis, sparse=True, category=None): sage: L = LazySymmetricFunctions(s) sage: TestSuite(L).run() - sage: p = SymmetricFunctions(GF(5)).p() - sage: L = LazySymmetricFunctions(p) - sage: TestSuite(L).run() + sage: p = SymmetricFunctions(GF(5)).p() # optional - sage.rings.finite_rings + sage: L = LazySymmetricFunctions(p) # optional - sage.rings.finite_rings + sage: TestSuite(L).run() # optional - sage.rings.finite_rings Reversion will only work when the base ring is a field:: @@ -2342,8 +2345,8 @@ def _repr_(self): EXAMPLES:: - sage: s = SymmetricFunctions(GF(2)).s() - sage: LazySymmetricFunctions(s) + sage: s = SymmetricFunctions(GF(2)).s() # optional - sage.rings.finite_rings + sage: LazySymmetricFunctions(s) # optional - sage.rings.finite_rings Lazy completion of Symmetric Functions over Finite Field of size 2 in the Schur basis """ return "Lazy completion of {}".format(self._laurent_poly_ring) @@ -2354,9 +2357,9 @@ def _latex_(self): EXAMPLES:: - sage: s = SymmetricFunctions(GF(2)).s() - sage: L = LazySymmetricFunctions(s) - sage: latex(L) + sage: s = SymmetricFunctions(GF(2)).s() # optional - sage.rings.finite_rings + sage: L = LazySymmetricFunctions(s) # optional - sage.rings.finite_rings + sage: latex(L) # optional - sage.rings.finite_rings \text{\texttt{Symmetric{ }Functions{ }over{ }Finite{ }Field{ }of{ }size{ }2{ }in{ }the{ }Schur{ }basis}} """ from sage.misc.latex import latex @@ -2393,11 +2396,11 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No EXAMPLES:: - sage: m = SymmetricFunctions(GF(2)).m() - sage: L = LazySymmetricFunctions(m) - sage: L(2) + sage: m = SymmetricFunctions(GF(2)).m() # optional - sage.rings.finite_rings + sage: L = LazySymmetricFunctions(m) # optional - sage.rings.finite_rings + sage: L(2) # optional - sage.rings.finite_rings 0 - sage: L(3) + sage: L(3) # optional - sage.rings.finite_rings m[] sage: m = SymmetricFunctions(ZZ).m() @@ -2577,9 +2580,9 @@ def some_elements(self): EXAMPLES:: - sage: m = SymmetricFunctions(GF(5)).m() - sage: L = LazySymmetricFunctions(m) - sage: L.some_elements()[:5] + sage: m = SymmetricFunctions(GF(5)).m() # optional - sage.rings.finite_rings + sage: L = LazySymmetricFunctions(m) # optional - sage.rings.finite_rings + sage: L.some_elements()[:5] # optional - sage.rings.finite_rings [0, m[], 2*m[] + 2*m[1] + 3*m[2], 2*m[1] + 3*m[2], 3*m[] + 2*m[1] + (m[1,1]+m[2]) + (2*m[1,1,1]+m[3]) @@ -2710,6 +2713,24 @@ class LazyDirichletSeriesRing(LazySeriesRing): # Follow the "generic" normalization __classcall_private__ = LazySeriesRing.__classcall_private__ + @lazy_attribute + def _laurent_poly_ring(self): + r""" + Return the symbolic ring. + + .. TODO:: + + It would be good to have something better than the symbolic ring. + + TESTS:: + + sage: L = LazyDirichletSeriesRing(ZZ, 't') + sage: L._laurent_poly_ring is SR # optional - sage.symbolic + True + """ + from sage.symbolic.ring import SR + return SR + def __init__(self, base_ring, names, sparse=True, category=None): r""" Initialize the ring. @@ -2733,7 +2754,6 @@ def __init__(self, base_ring, names, sparse=True, category=None): self._sparse = sparse self._minimal_valuation = 1 self._arity = 1 - self._laurent_poly_ring = SR # TODO: it would be good to have something better than the symbolic ring self._internal_poly_ring = PolynomialRing(base_ring, names, sparse=sparse) category = Algebras(base_ring.category()) @@ -2751,7 +2771,7 @@ def _repr_(self): EXAMPLES:: - sage: LazyDirichletSeriesRing(QQbar, 'z') + sage: LazyDirichletSeriesRing(QQbar, 'z') # optional - sage.rings.number_field Lazy Dirichlet Series Ring in z over Algebraic Field """ return "Lazy Dirichlet Series Ring in {} over {}".format(self.variable_name(), self.base_ring()) @@ -2764,9 +2784,9 @@ def one(self): EXAMPLES:: sage: L = LazyDirichletSeriesRing(ZZ, 'z') - sage: L.one() + sage: L.one() # optional - sage.symbolic 1 - sage: ~L.one() + sage: ~L.one() # optional - sage.symbolic 1 + O(1/(8^z)) """ R = self.base_ring() @@ -2804,25 +2824,32 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No EXAMPLES:: sage: L = LazyDirichletSeriesRing(ZZ, 'z') - sage: L(3) + sage: R = L(3) + sage: R # optional - sage.symbolic 3 - sage: L(lambda i: i, constant=1, degree=6) + sage: S = L(lambda i: i, constant=1, degree=6) + sage: S # optional - sage.symbolic 1 + 2/2^z + 3/3^z + 4/4^z + 5/5^z + 1/(6^z) + 1/(7^z) + 1/(8^z) + O(1/(9^z)) - sage: X = L(constant=5, degree=3); X + sage: X = L(constant=5, degree=3) + sage: X # optional - sage.symbolic 5/3^z + 5/4^z + 5/5^z + O(1/(6^z)) sage: X.valuation() log(3) - sage: e = L(moebius); e + sage: e = L(moebius) + sage: e # optional - sage.symbolic 1 - 1/(2^z) - 1/(3^z) - 1/(5^z) + 1/(6^z) - 1/(7^z) + O(1/(8^z)) - sage: L([0], constant=1) + sage: T = L([0], constant=1) + sage: T # optional - sage.symbolic 1/(2^z) + 1/(3^z) + 1/(4^z) + O(1/(5^z)) - sage: L(constant=1) + sage: U = L(constant=1) + sage: U # optional - sage.symbolic 1 + 1/(2^z) + 1/(3^z) + O(1/(4^z)) - sage: L(lambda i: i, valuation=3) + sage: V = L(lambda i: i, valuation=3) + sage: V # optional - sage.symbolic 3/3^z + 4/4^z + 5/5^z + 6/6^z + 7/7^z + 8/8^z + 9/9^z + O(1/(10^z)) Alternatively, ``x`` can be a list of elements of the base ring. @@ -2831,37 +2858,45 @@ def _element_constructor_(self, x=None, valuation=None, degree=None, constant=No may be just an element of the base ring instead of a tuple or can be simply omitted if it is zero:: - sage: f = L([1,2,3,4], 4); f + sage: f = L([1,2,3,4], 4) + sage: f # optional - sage.symbolic 1/(4^z) + 2/5^z + 3/6^z + 4/7^z - sage: g = L([1,3,5,7,9], 6, constant=-1); g - 1/(6^z) + 3/7^z + 5/8^z + 7/9^z + 9/10^z - 1/(11^z) - 1/(12^z) - 1/(13^z) + O(1/(14^z)) + sage: g = L([1,3,5,7,9], 6, constant=-1) + sage: g # optional - sage.symbolic + 1/(6^z) + 3/7^z + 5/8^z + 7/9^z + 9/10^z - 1/(11^z) - 1/(12^z) + - 1/(13^z) + O(1/(14^z)) TESTS:: - sage: L = LazyDirichletSeriesRing(GF(2), 'z') + sage: L = LazyDirichletSeriesRing(GF(2), 'z') # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: positive characteristic not allowed for Dirichlet series sage: L. = LazyLaurentSeriesRing(QQ) sage: D = LazyDirichletSeriesRing(QQ, 't') - sage: D(L.one()) + sage: d = D(L.one()) + sage: d # optional - sage.symbolic 1 + 1/(2^t) + 1/(3^t) + 1/(4^t) + 1/(5^t) + 1/(6^t) + 1/(7^t) + O(1/(8^t)) sage: R. = LaurentPolynomialRing(QQ) sage: D = LazyDirichletSeriesRing(QQ, 't') - sage: D(coefficients=z+z^2) + sage: dd = D(coefficients=z + z^2) + sage: dd # optional - sage.symbolic 2 + 6/2^t + 12/3^t + 20/4^t + 30/5^t + 42/6^t + 56/7^t + O(1/(8^t)) sage: s = D(lambda n: n) - sage: D(s, valuation=2) + sage: d2 = D(s, valuation=2) + sage: d2 # optional - sage.symbolic 1/(2^t) + 2/3^t + 3/4^t + 4/5^t + 5/6^t + 6/7^t + 7/8^t + O(1/(9^t)) sage: Ds = LazyDirichletSeriesRing(ZZ, 's') - sage: m = Ds(moebius, valuation=2); m + sage: m = Ds(moebius, valuation=2) + sage: m # optional - sage.symbolic -1/(2^s) - 1/(3^s) - 1/(5^s) + 1/(6^s) - 1/(7^s) + O(1/(9^s)) sage: D = LazyDirichletSeriesRing(QQ, 't') - sage: D(m) + sage: dm = D(m) + sage: dm # optional - sage.symbolic -1/(2^t) - 1/(3^t) - 1/(5^t) + 1/(6^t) - 1/(7^t) + O(1/(9^t)) """ if isinstance(x, (list, tuple)): @@ -2906,7 +2941,8 @@ def _an_element_(self): EXAMPLES:: sage: L = LazyDirichletSeriesRing(ZZ, 'z') - sage: L.an_element() + sage: m = L.an_element() + sage: m # optional - sage.symbolic 1/(4^z) + 1/(5^z) + 1/(6^z) + O(1/(7^z)) """ c = self.base_ring().an_element() @@ -2919,7 +2955,8 @@ def some_elements(self): EXAMPLES:: sage: L = LazyDirichletSeriesRing(ZZ, 'z') - sage: L.some_elements() + sage: l = L.some_elements() + sage: l # optional - sage.symbolic [0, 1, 1/(4^z) + 1/(5^z) + 1/(6^z) + O(1/(7^z)), 1/(2^z) - 1/(3^z) + 2/4^z - 2/5^z + 3/6^z - 3/7^z + 4/8^z - 4/9^z, @@ -2927,7 +2964,8 @@ def some_elements(self): 1 + 4/2^z + 9/3^z + 16/4^z + 25/5^z + 36/6^z + 49/7^z + O(1/(8^z))] sage: L = LazyDirichletSeriesRing(QQ, 'z') - sage: L.some_elements() + sage: l = L.some_elements() + sage: l # optional - sage.symbolic [0, 1, 1/2/4^z + 1/2/5^z + 1/2/6^z + O(1/(7^z)), 1/2 - 1/2/2^z + 2/3^z - 2/4^z + 1/(6^z) - 1/(7^z) + 42/8^z + 2/3/9^z, @@ -2949,7 +2987,8 @@ def _monomial(self, c, n): EXAMPLES:: sage: L = LazyDirichletSeriesRing(ZZ, 'z') - sage: L._monomial(5, 3) + sage: m = L._monomial(5, 3) + sage: m # optional - sage.symbolic 5/3^z """ try: @@ -2969,11 +3008,11 @@ def _skip_leading_zeros(iterator): sage: [x for x, _ in zip(_skip_leading_zeros(it), range(10))] [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] - sage: it = map(GF(3), NN) - sage: [x for x, _ in zip(it, range(10))] + sage: it = map(GF(3), NN) # optional - sage.rings.finite_rings + sage: [x for x, _ in zip(it, range(10))] # optional - sage.rings.finite_rings [0, 1, 2, 0, 1, 2, 0, 1, 2, 0] - sage: it = map(GF(3), NN) - sage: [x for x, _ in zip(_skip_leading_zeros(it), range(10))] + sage: it = map(GF(3), NN) # optional - sage.rings.finite_rings + sage: [x for x, _ in zip(_skip_leading_zeros(it), range(10))] # optional - sage.rings.finite_rings [1, 2, 0, 1, 2, 0, 1, 2, 0, 1] """ while True: diff --git a/src/sage/rings/localization.py b/src/sage/rings/localization.py index 138ac172745..3062c9439d8 100644 --- a/src/sage/rings/localization.py +++ b/src/sage/rings/localization.py @@ -10,18 +10,18 @@ EXAMPLES:: sage: LZ = Localization(ZZ, (5,11)) - sage: m = matrix(LZ, [[5, 7], [0,11]]) - sage: m.parent() + sage: m = matrix(LZ, [[5, 7], [0,11]]) # optional - sage.modules + sage: m.parent() # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Integer Ring localized at (5, 11) - sage: ~m # parent of inverse is different: see documentation of m.__invert__ + sage: ~m # parent of inverse is different: see documentation of m.__invert__ # optional - sage.modules [ 1/5 -7/55] [ 0 1/11] - sage: _.parent() + sage: _.parent() # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: mi = matrix(LZ, ~m) - sage: mi.parent() + sage: mi = matrix(LZ, ~m) # optional - sage.modules + sage: mi.parent() # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Integer Ring localized at (5, 11) - sage: mi == ~m + sage: mi == ~m # optional - sage.modules True The next example defines the most general ring containing the coefficients of the irreducible @@ -34,123 +34,123 @@ sage: I = S.cartesian_product(S) sage: add_units = u + [q, q + 1] + [ui - uj for ui, uj in I if ui != uj] sage: add_units += [q*ui - uj for ui, uj in I if ui != uj] - sage: L = R.localization(tuple(add_units)); L + sage: L = R.localization(tuple(add_units)); L # optional - sage.libs.pari Multivariate Polynomial Ring in u0, u1, u2, q over Integer Ring localized at - (q, q + 1, u2, u1, u1 - u2, u0, u0 - u2, u0 - u1, u2*q - u1, u2*q - u0, - u1*q - u2, u1*q - u0, u0*q - u2, u0*q - u1) + (q, q + 1, u2, u1, u1 - u2, u0, u0 - u2, u0 - u1, u2*q - u1, u2*q - u0, + u1*q - u2, u1*q - u0, u0*q - u2, u0*q - u1) Define the representation matrices (of one of the three dimensional irreducible representations):: - sage: m1 = matrix(L, [[u1, 0, 0],[0, u0, 0],[0, 0, u0]]) - sage: m2 = matrix(L, [[(u0*q - u0)/(u0 - u1), (u0*q - u1)/(u0 - u1), 0], + sage: m1 = matrix(L, [[u1, 0, 0], [0, u0, 0], [0, 0, u0]]) # optional - sage.modules + sage: m2 = matrix(L, [[(u0*q - u0)/(u0 - u1), (u0*q - u1)/(u0 - u1), 0], # optional - sage.modules ....: [(-u1*q + u0)/(u0 - u1), (-u1*q + u1)/(u0 - u1), 0], ....: [0, 0, -1]]) - sage: m3 = matrix(L, [[-1, 0, 0], + sage: m3 = matrix(L, [[-1, 0, 0], # optional - sage.modules ....: [0, u0*(1 - q)/(u1*q - u0), q*(u1 - u0)/(u1*q - u0)], ....: [0, (u1*q^2 - u0)/(u1*q - u0), (u1*q^ 2 - u1*q)/(u1*q - u0)]]) - sage: m1.base_ring() == L + sage: m1.base_ring() == L # optional - sage.modules True Check relations of the Ariki-Koike algebra:: - sage: m1*m2*m1*m2 == m2*m1*m2*m1 + sage: m1*m2*m1*m2 == m2*m1*m2*m1 # optional - sage.modules True - sage: m2*m3*m2 == m3*m2*m3 + sage: m2*m3*m2 == m3*m2*m3 # optional - sage.modules True - sage: m1*m3 == m3*m1 + sage: m1*m3 == m3*m1 # optional - sage.modules True - sage: m1**3 -(u0+u1+u2)*m1**2 +(u0*u1+u0*u2+u1*u2)*m1 - u0*u1*u2 == 0 + sage: m1**3 - (u0+u1+u2)*m1**2 + (u0*u1+u0*u2+u1*u2)*m1 - u0*u1*u2 == 0 # optional - sage.modules True - sage: m2**2 -(q-1)*m2 - q == 0 + sage: m2**2 - (q-1)*m2 - q == 0 # optional - sage.modules True - sage: m3**2 -(q-1)*m3 - q == 0 + sage: m3**2 - (q-1)*m3 - q == 0 # optional - sage.modules True - sage: ~m1 in m1.parent() + sage: ~m1 in m1.parent() # optional - sage.modules True - sage: ~m2 in m2.parent() + sage: ~m2 in m2.parent() # optional - sage.modules True - sage: ~m3 in m3.parent() + sage: ~m3 in m3.parent() # optional - sage.modules True Obtain specializations in positive characteristic:: - sage: Fp = GF(17) - sage: f = L.hom((3,5,7,11), codomain=Fp); f + sage: Fp = GF(17) # optional - sage.rings.finite_rings + sage: f = L.hom((3,5,7,11), codomain=Fp); f # optional - sage.rings.finite_rings Ring morphism: From: Multivariate Polynomial Ring in u0, u1, u2, q over Integer Ring localized at - (q, q + 1, u2, u1, u1 - u2, u0, u0 - u2, u0 - u1, u2*q - u1, u2*q - u0, - u1*q - u2, u1*q - u0, u0*q - u2, u0*q - u1) + (q, q + 1, u2, u1, u1 - u2, u0, u0 - u2, u0 - u1, u2*q - u1, u2*q - u0, + u1*q - u2, u1*q - u0, u0*q - u2, u0*q - u1) To: Finite Field of size 17 Defn: u0 |--> 3 u1 |--> 5 u2 |--> 7 q |--> 11 - sage: mFp1 = matrix({k:f(v) for k, v in m1.dict().items()}); mFp1 + sage: mFp1 = matrix({k: f(v) for k, v in m1.dict().items()}); mFp1 # optional - sage.modules sage.rings.finite_rings [5 0 0] [0 3 0] [0 0 3] - sage: mFp1.base_ring() + sage: mFp1.base_ring() # optional - sage.modules sage.rings.finite_rings Finite Field of size 17 - sage: mFp2 = matrix({k:f(v) for k, v in m2.dict().items()}); mFp2 + sage: mFp2 = matrix({k: f(v) for k, v in m2.dict().items()}); mFp2 # optional - sage.modules sage.rings.finite_rings [ 2 3 0] [ 9 8 0] [ 0 0 16] - sage: mFp3 = matrix({k:f(v) for k, v in m3.dict().items()}); mFp3 + sage: mFp3 = matrix({k: f(v) for k, v in m3.dict().items()}); mFp3 # optional - sage.modules sage.rings.finite_rings [16 0 0] [ 0 4 5] [ 0 7 6] Obtain specializations in characteristic 0:: - sage: fQ = L.hom((3,5,7,11), codomain=QQ); fQ + sage: fQ = L.hom((3,5,7,11), codomain=QQ); fQ # optional - sage.rings.finite_rings Ring morphism: - From: Multivariate Polynomial Ring in u0, u1, u2, q over Integer Ring localized at - (q, q + 1, u2, u1, u1 - u2, u0, u0 - u2, u0 - u1, u2*q - u1, u2*q - u0, - u1*q - u2, u1*q - u0, u0*q - u2, u0*q - u1) + From: Multivariate Polynomial Ring in u0, u1, u2, q over Integer Ring + localized at (q, q + 1, u2, u1, u1 - u2, u0, u0 - u2, u0 - u1, + u2*q - u1, u2*q - u0, u1*q - u2, u1*q - u0, u0*q - u2, u0*q - u1) To: Rational Field Defn: u0 |--> 3 u1 |--> 5 u2 |--> 7 q |--> 11 - sage: mQ1 = matrix({k:fQ(v) for k, v in m1.dict().items()}); mQ1 + sage: mQ1 = matrix({k: fQ(v) for k, v in m1.dict().items()}); mQ1 # optional - sage.modules sage.rings.finite_rings [5 0 0] [0 3 0] [0 0 3] - sage: mQ1.base_ring() + sage: mQ1.base_ring() # optional - sage.modules sage.rings.finite_rings Rational Field - sage: mQ2 = matrix({k:fQ(v) for k, v in m2.dict().items()}); mQ2 + sage: mQ2 = matrix({k: fQ(v) for k, v in m2.dict().items()}); mQ2 # optional - sage.modules sage.rings.finite_rings [-15 -14 0] [ 26 25 0] [ 0 0 -1] - sage: mQ3 = matrix({k:fQ(v) for k, v in m3.dict().items()}); mQ3 + sage: mQ3 = matrix({k: fQ(v) for k, v in m3.dict().items()}); mQ3 # optional - sage.modules sage.rings.finite_rings [ -1 0 0] [ 0 -15/26 11/26] [ 0 301/26 275/26] sage: S. = QQ[] - sage: T = S.quo(x+y+z) - sage: F = T.fraction_field() - sage: fF = L.hom((x, y, z, t), codomain=F); fF + sage: T = S.quo(x + y + z) + sage: F = T.fraction_field() # optional - sage.libs.singular + sage: fF = L.hom((x, y, z, t), codomain=F); fF # optional - sage.libs.singular Ring morphism: - From: Multivariate Polynomial Ring in u0, u1, u2, q over Integer Ring localized at - (q, q + 1, u2, u1, u1 - u2, u0, u0 - u2, u0 - u1, u2*q - u1, u2*q - u0, - u1*q - u2, u1*q - u0, u0*q - u2, u0*q - u1) - To: Fraction Field of Quotient of Multivariate Polynomial Ring in x, y, z, t over - Rational Field by the ideal (x + y + z) + From: Multivariate Polynomial Ring in u0, u1, u2, q over Integer Ring + localized at (q, q + 1, u2, u1, u1 - u2, u0, u0 - u2, u0 - u1, + u2*q - u1, u2*q - u0, u1*q - u2, u1*q - u0, u0*q - u2, u0*q - u1) + To: Fraction Field of Quotient of Multivariate Polynomial Ring in x, y, z, t + over Rational Field by the ideal (x + y + z) Defn: u0 |--> -ybar - zbar u1 |--> ybar u2 |--> zbar q |--> tbar - sage: mF1 = matrix({k:fF(v) for k, v in m1.dict().items()}); mF1 + sage: mF1 = matrix({k: fF(v) for k, v in m1.dict().items()}); mF1 # optional - sage.libs.singular sage.modules [ ybar 0 0] [ 0 -ybar - zbar 0] [ 0 0 -ybar - zbar] - sage: mF1.base_ring() == F + sage: mF1.base_ring() == F # optional - sage.libs.singular sage.modules True TESTS:: - sage: TestSuite(L).run() + sage: TestSuite(L).run() # optional - sage.libs.singular sage.modules AUTHORS: @@ -199,21 +199,21 @@ def normalize_extra_units(base_ring, add_units, warning=True): sage: normalize_extra_units(ZZ, [3, -15, 45, 9, 2, 50]) [2, 3, 5] sage: P. = ZZ[] - sage: normalize_extra_units(P, [3*x, z*y**2, 2*z, 18*(x*y*z)**2, x*z, 6*x*z, 5]) + sage: normalize_extra_units(P, [3*x, z*y**2, 2*z, 18*(x*y*z)**2, x*z, 6*x*z, 5]) # optional - sage.libs.pari [2, 3, 5, z, y, x] sage: P. = QQ[] - sage: normalize_extra_units(P, [3*x, z*y**2, 2*z, 18*(x*y*z)**2, x*z, 6*x*z, 5]) + sage: normalize_extra_units(P, [3*x, z*y**2, 2*z, 18*(x*y*z)**2, x*z, 6*x*z, 5]) # optional - sage.libs.pari [z, y, x] sage: R. = ZZ[] - sage: Q. = R.quo(x**2-5) - sage: p = b**2-5 - sage: p == (b-a)*(b+a) + sage: Q. = R.quo(x**2 - 5) # optional - sage.libs.singular + sage: p = b**2 - 5 # optional - sage.libs.singular + sage: p == (b-a)*(b+a) # optional - sage.libs.singular True - sage: normalize_extra_units(Q, [p]) + sage: normalize_extra_units(Q, [p]) # optional - sage.libs.pari doctest:...: UserWarning: Localization may not be represented uniquely [b^2 - 5] - sage: normalize_extra_units(Q, [p], warning=False) + sage: normalize_extra_units(Q, [p], warning=False) # optional - sage.libs.pari [b^2 - 5] """ # convert to base ring @@ -251,11 +251,11 @@ class LocalizationElement(IntegralDomainElement): EXAMPLES:: sage: from sage.rings.localization import LocalizationElement - sage: P. = GF(5)[] - sage: L = P.localization((x, y*z-x)) - sage: LocalizationElement(L, 4/(y*z-x)**2) + sage: P. = GF(5)[] # optional - sage.rings.finite_rings + sage: L = P.localization((x, y*z-x)) # optional - sage.rings.finite_rings + sage: LocalizationElement(L, 4/(y*z-x)**2) # optional - sage.rings.finite_rings (-1)/(y^2*z^2 - 2*x*y*z + x^2) - sage: _.parent() + sage: _.parent() # optional - sage.rings.finite_rings Multivariate Polynomial Ring in x, y, z over Finite Field of size 5 localized at (x, y*z - x) """ @@ -389,10 +389,10 @@ def factor(self, proof=None): EXAMPLES:: sage: P. = QQ['x, y'] - sage: L = P.localization(X-Y) + sage: L = P.localization(X - Y) sage: x, y = L.gens() - sage: p = (x^2 - y^2)/(x-y)^2 - sage: p.factor() + sage: p = (x^2 - y^2)/(x-y)^2 # optional - sage.libs.singular + sage: p.factor() # optional - sage.libs.singular (1/(x - y)) * (x + y) """ num = self._value.numerator() @@ -411,9 +411,9 @@ def _im_gens_(self, codomain, im_gens, base_map=None): EXAMPLES:: sage: R. = ZZ[] - sage: L = Localization(R, x**2+1) - sage: f = L.hom([5], codomain=Localization(ZZ, 26)) # indirect doctest - sage: f(x/(x**2+1)) + sage: L = Localization(R, x**2 + 1) # optional - sage.libs.pari + sage: f = L.hom([5], codomain=Localization(ZZ, 26)) # indirect doctest # optional - sage.libs.pari + sage: f(x/(x**2+1)) # optional - sage.libs.pari 5/26 """ return self._value._im_gens_(codomain, im_gens, base_map=base_map) @@ -449,12 +449,12 @@ def is_unit(self): EXAMPLES:: sage: P. = QQ[] - sage: L = P.localization((x, y*z)) - sage: L(y*z).is_unit() + sage: L = P.localization((x, y*z)) # optional - sage.libs.pari + sage: L(y*z).is_unit() # optional - sage.libs.pari True - sage: L(z).is_unit() + sage: L(z).is_unit() # optional - sage.libs.pari True - sage: L(x*y*z).is_unit() + sage: L(x*y*z).is_unit() # optional - sage.libs.pari True """ return self.parent()._cut_off_extra_units_from_base_ring_element(self._value.numerator()).is_unit() @@ -467,9 +467,9 @@ def inverse_of_unit(self): sage: P. = ZZ[] sage: L = Localization(P, x*y*z) - sage: L(x*y*z).inverse_of_unit() + sage: L(x*y*z).inverse_of_unit() # optional - sage.libs.singular 1/(x*y*z) - sage: L(z).inverse_of_unit() + sage: L(z).inverse_of_unit() # optional - sage.libs.singular 1/z """ parent = self.parent() @@ -481,11 +481,11 @@ def _richcmp_(self, other, op): """ EXAMPLES:: - sage: P. = GF(7)[] - sage: L = Localization(P, (x, y, z)) - sage: L(1/x) < L(3/(x*y*z)**3) + sage: P. = GF(7)[] # optional - sage.rings.finite_rings + sage: L = Localization(P, (x, y, z)) # optional - sage.rings.finite_rings + sage: L(1/x) < L(3/(x*y*z)**3) # optional - sage.rings.finite_rings False - sage: ~L(y*z/x) == L(x/(y*z)) + sage: ~L(y*z/x) == L(x/(y*z)) # optional - sage.rings.finite_rings True """ sval = self._value @@ -518,8 +518,8 @@ def _rational_(self): TESTS:: sage: L = ZZ.localization(5) - sage: cp3 = cyclotomic_polynomial(3).change_ring(L) - sage: cp3.splitting_field('t') # indirect doctest + sage: cp3 = cyclotomic_polynomial(3).change_ring(L) # optional - sage.libs.pari + sage: cp3.splitting_field('t') # indirect doctest # optional - sage.libs.pari sage.rings.number_field Number Field in t with defining polynomial x^2 + x + 1 """ from sage.rings.rational_field import QQ @@ -601,40 +601,41 @@ class Localization(IntegralDomain, UniqueRepresentation): ... ValueError: factor 7 of denominator is not a unit - sage: Localization(Zp(7), (3, 5)) + sage: Localization(Zp(7), (3, 5)) # optional - sage.rings.padics Traceback (most recent call last): ... - ValueError: all given elements are invertible in 7-adic Ring with capped relative precision 20 + ValueError: all given elements are invertible in + 7-adic Ring with capped relative precision 20 sage: R. = ZZ[] - sage: L = R.localization(x**2+1) + sage: L = R.localization(x**2 + 1) # optional - sage.libs.pari sage: s = (x+5)/(x**2+1) - sage: s in L + sage: s in L # optional - sage.libs.pari True sage: t = (x+5)/(x**2+2) - sage: t in L + sage: t in L # optional - sage.libs.pari False - sage: L(t) + sage: L(t) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: fraction must have unit denominator - sage: L(s) in R + sage: L(s) in R # optional - sage.libs.pari False - sage: y = L(x) - sage: g = L(s) - sage: g.parent() + sage: y = L(x) # optional - sage.libs.pari + sage: g = L(s) # optional - sage.libs.pari + sage: g.parent() # optional - sage.libs.pari Univariate Polynomial Ring in x over Integer Ring localized at (x^2 + 1,) - sage: f = (y+5)/(y**2+1); f + sage: f = (y+5)/(y**2+1); f # optional - sage.libs.pari (x + 5)/(x^2 + 1) - sage: f == g + sage: f == g # optional - sage.libs.pari True - sage: (y+5)/(y**2+2) + sage: (y+5)/(y**2+2) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: factor x^2 + 2 of denominator is not a unit sage: Lau. = LaurentPolynomialRing(ZZ) - sage: LauL = Lau.localization(u+1) + sage: LauL = Lau.localization(u + 1) sage: LauL(~u).parent() Multivariate Polynomial Ring in u, v over Integer Ring localized at (v, u, u + 1) @@ -657,12 +658,12 @@ def __init__(self, base_ring, extra_units, names=None, normalize=True, category= TESTS:: - sage: L = Localization(ZZ, (3,5)) + sage: L = Localization(ZZ, (3, 5)) sage: TestSuite(L).run() sage: R. = ZZ[] - sage: L = R.localization(x**2+1) - sage: TestSuite(L).run() + sage: L = R.localization(x**2 + 1) # optional - sage.libs.pari + sage: TestSuite(L).run() # optional - sage.libs.pari """ if type(extra_units) is tuple: extra_units = list(extra_units) @@ -702,9 +703,10 @@ def _repr_(self): EXAMPLES:: - sage: R. = GF(3)[] - sage: Localization(R, a**2-1) - Univariate Polynomial Ring in a over Finite Field of size 3 localized at (a + 1, a + 2) + sage: R. = GF(3)[] # optional - sage.rings.finite_rings + sage: Localization(R, a**2 - 1) # optional - sage.rings.finite_rings + Univariate Polynomial Ring in a over Finite Field of size 3 + localized at (a + 1, a + 2) """ return "%s localized at %s" % (self.base(), self._extra_units) @@ -733,37 +735,38 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): EXAMPLES:: sage: R. = ZZ[] - sage: L = Localization(R, x**2+1) - sage: L.hom([5]) # indirect doctest + sage: L = Localization(R, x**2 + 1) # optional - sage.libs.pari + sage: L.hom([5]) # indirect doctest # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: images of some localized elements fail to be units - sage: L.hom([5], codomain=Localization(ZZ, 26)) # indirect doctest + sage: L.hom([5], codomain=Localization(ZZ, 26)) # indirect doctest # optional - sage.libs.pari Ring morphism: - From: Univariate Polynomial Ring in x over Integer Ring localized at (x^2 + 1,) + From: Univariate Polynomial Ring in x over Integer Ring + localized at (x^2 + 1,) To: Integer Ring localized at (2, 13) Defn: x |--> 5 TESTS:: - sage: phi=R.hom([5]) - sage: L._is_valid_homomorphism_(ZZ, [3], base_map=phi) + sage: phi = R.hom([5]) + sage: L._is_valid_homomorphism_(ZZ, [3], base_map=phi) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: given base_map is not compatible with im_gens - sage: L._is_valid_homomorphism_(ZZ, [5], base_map=phi) + sage: L._is_valid_homomorphism_(ZZ, [5], base_map=phi) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: images of some localized elements fail to be units - sage: phi=R.hom([5], codomain=QQ) - sage: L._is_valid_homomorphism_(ZZ, [5], base_map=phi) + sage: phi = R.hom([5], codomain=QQ) + sage: L._is_valid_homomorphism_(ZZ, [5], base_map=phi) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: codomain of base_map must be Integer Ring - sage: L._is_valid_homomorphism_(QQ, [5], base_map=phi) + sage: L._is_valid_homomorphism_(QQ, [5], base_map=phi) # optional - sage.libs.pari True """ B = self.base_ring() @@ -795,7 +798,7 @@ def ngens(self): EXAMPLES:: sage: R. = ZZ[] - sage: Localization(R, (x**2+1, y-1)).ngens() + sage: Localization(R, (x**2 + 1, y - 1)).ngens() # optional - sage.libs.pari 2 sage: Localization(ZZ, 2).ngens() @@ -811,7 +814,7 @@ def gen(self, i): EXAMPLES:: sage: R. = ZZ[] - sage: R.localization((x**2+1, y-1)).gen(0) + sage: R.localization((x**2 + 1, y - 1)).gen(0) # optional - sage.libs.pari x sage: ZZ.localization(2).gen(0) @@ -827,7 +830,7 @@ def gens(self): EXAMPLES:: sage: R. = ZZ[] - sage: Localization(R, (x**2+1, y-1)).gens() + sage: Localization(R, (x**2 + 1, y - 1)).gens() # optional - sage.libs.pari (x, y) sage: Localization(ZZ, 2).gens() @@ -851,10 +854,10 @@ def _cut_off_extra_units_from_base_ring_element(self, x): EXAMPLES:: sage: P. = QQ[] - sage: L = Localization(P, (x, y*z)) - sage: L._cut_off_extra_units_from_base_ring_element(x*y*z) + sage: L = Localization(P, (x, y*z)) # optional - sage.libs.pari + sage: L._cut_off_extra_units_from_base_ring_element(x*y*z) # optional - sage.libs.pari 1 - sage: L._cut_off_extra_units_from_base_ring_element(x*z) + sage: L._cut_off_extra_units_from_base_ring_element(x*z) # optional - sage.libs.pari 1 TESTS: @@ -894,16 +897,16 @@ def _fraction_to_element(self, x): EXAMPLES:: sage: P. = QQ[] - sage: d = x**2+y**2+z**2 - sage: L = Localization(P, d) - sage: L._fraction_to_element((x+y+z)/d) + sage: d = x**2 + y**2 + z**2 + sage: L = Localization(P, d) # optional - sage.libs.pari + sage: L._fraction_to_element((x+y+z)/d) # optional - sage.libs.pari (x + y + z)/(x^2 + y^2 + z^2) - sage: _ in L + sage: _ in L # optional - sage.libs.pari True TESTS:: - sage: TestSuite(L).run() + sage: TestSuite(L).run() # optional - sage.libs.pari """ potential_non_unit_denom = self._cut_off_extra_units_from_base_ring_element(x.denominator()) if potential_non_unit_denom.is_unit(): @@ -932,7 +935,7 @@ def _coerce_map_from_(self, S): True sage: N._coerce_map_from_(M) False - sage: O = Localization(L, x**2+1) + sage: O = Localization(L, x**2 + 1) sage: O._coerce_map_from_(M) False sage: O._coerce_map_from_(L) @@ -951,11 +954,11 @@ def fraction_field(self): EXAMPLES:: - sage: R. = GF(5)[] - sage: L = Localization(R, (a**2-3, a)) - sage: L.fraction_field() + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: L = Localization(R, (a**2 - 3, a)) # optional - sage.rings.finite_rings + sage: L.fraction_field() # optional - sage.rings.finite_rings Fraction Field of Univariate Polynomial Ring in a over Finite Field of size 5 - sage: L.is_subring(_) + sage: L.is_subring(_) # optional - sage.rings.finite_rings True """ return self._fraction_field @@ -966,9 +969,9 @@ def characteristic(self): EXAMPLES:: - sage: R. = GF(5)[] - sage: L = R.localization((a**2-3, a)) - sage: L.characteristic() + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: L = R.localization((a**2 - 3, a)) # optional - sage.rings.finite_rings + sage: L.characteristic() # optional - sage.rings.finite_rings 5 """ return self.base_ring().characteristic() @@ -984,7 +987,7 @@ def krull_dimension(self): EXAMPLES:: - sage: R = ZZ.localization((2,3)) + sage: R = ZZ.localization((2, 3)) sage: R.krull_dimension() 1 """ @@ -1008,7 +1011,7 @@ def is_field(self, proof=True): EXAMPLES:: - sage: R = ZZ.localization((2,3)) + sage: R = ZZ.localization((2, 3)) sage: R.is_field() False """ diff --git a/src/sage/rings/morphism.pyx b/src/sage/rings/morphism.pyx index 84f288793d3..929bc55703f 100644 --- a/src/sage/rings/morphism.pyx +++ b/src/sage/rings/morphism.pyx @@ -17,7 +17,8 @@ Natural inclusion `\ZZ \hookrightarrow \QQ`:: sage: phi(2/3) Traceback (most recent call last): ... - TypeError: 2/3 fails to convert into the map's domain Integer Ring, but a `pushforward` method is not properly implemented + TypeError: 2/3 fails to convert into the map's domain Integer Ring, + but a `pushforward` method is not properly implemented There is no homomorphism in the other direction:: @@ -25,30 +26,31 @@ There is no homomorphism in the other direction:: sage: H([1]) Traceback (most recent call last): ... - ValueError: relations do not all (canonically) map to 0 under map determined by images of generators + ValueError: relations do not all (canonically) map to 0 + under map determined by images of generators EXAMPLES: Reduction to finite field:: - sage: H = Hom(ZZ, GF(9, 'a')) - sage: phi = H([1]) - sage: phi(5) + sage: H = Hom(ZZ, GF(9, 'a')) # optional - sage.rings.finite_rings + sage: phi = H([1]) # optional - sage.rings.finite_rings + sage: phi(5) # optional - sage.rings.finite_rings 2 - sage: psi = H([4]) - sage: psi(5) + sage: psi = H([4]) # optional - sage.rings.finite_rings + sage: psi(5) # optional - sage.rings.finite_rings 2 Map from single variable polynomial ring:: sage: R. = ZZ[] - sage: phi = R.hom([2], GF(5)) - sage: phi + sage: phi = R.hom([2], GF(5)) # optional - sage.rings.finite_rings + sage: phi # optional - sage.rings.finite_rings Ring morphism: From: Univariate Polynomial Ring in x over Integer Ring To: Finite Field of size 5 Defn: x |--> 2 - sage: phi(x + 12) + sage: phi(x + 12) # optional - sage.rings.finite_rings 4 Identity map on the real numbers:: @@ -61,7 +63,8 @@ Identity map on the real numbers:: sage: f = RR.hom( [2.0] ) Traceback (most recent call last): ... - ValueError: relations do not all (canonically) map to 0 under map determined by images of generators + ValueError: relations do not all (canonically) map to 0 + under map determined by images of generators Homomorphism from one precision of field to another. @@ -71,7 +74,8 @@ From smaller to bigger doesn't make sense:: sage: f = RR.hom( R200 ) Traceback (most recent call last): ... - TypeError: natural coercion morphism from Real Field with 53 bits of precision to Real Field with 200 bits of precision not defined + TypeError: natural coercion morphism from Real Field with 53 bits of precision + to Real Field with 200 bits of precision not defined From bigger to small does:: @@ -108,7 +112,8 @@ An endomorphism of a quotient of a multi-variate polynomial ring:: sage: S. = quo(R, ideal(1 + y^2)) sage: phi = S.hom([a^2, -b]) sage: phi - Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (y^2 + 1) + Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y + over Rational Field by the ideal (y^2 + 1) Defn: a |--> a^2 b |--> -b sage: phi(b) @@ -142,28 +147,28 @@ a quotient ring:: Inclusion of ``GF(2)`` into ``GF(4,'a')``:: - sage: k = GF(2) - sage: i = k.hom(GF(4, 'a')) - sage: i + sage: k = GF(2) # optional - sage.rings.finite_rings + sage: i = k.hom(GF(4, 'a')) # optional - sage.rings.finite_rings + sage: i # optional - sage.rings.finite_rings Ring morphism: From: Finite Field of size 2 To: Finite Field in a of size 2^2 Defn: 1 |--> 1 - sage: i(0) + sage: i(0) # optional - sage.rings.finite_rings 0 - sage: a = i(1); a.parent() + sage: a = i(1); a.parent() # optional - sage.rings.finite_rings Finite Field in a of size 2^2 We next compose the inclusion with reduction from the integers to ``GF(2)``:: - sage: pi = ZZ.hom(k) - sage: pi + sage: pi = ZZ.hom(k) # optional - sage.rings.finite_rings + sage: pi # optional - sage.rings.finite_rings Natural morphism: From: Integer Ring To: Finite Field of size 2 - sage: f = i * pi - sage: f + sage: f = i * pi # optional - sage.rings.finite_rings + sage: f # optional - sage.rings.finite_rings Composite map: From: Integer Ring To: Finite Field in a of size 2^2 @@ -175,27 +180,27 @@ We next compose the inclusion with reduction from the integers to From: Finite Field of size 2 To: Finite Field in a of size 2^2 Defn: 1 |--> 1 - sage: a = f(5); a + sage: a = f(5); a # optional - sage.rings.finite_rings 1 - sage: a.parent() + sage: a.parent() # optional - sage.rings.finite_rings Finite Field in a of size 2^2 Inclusion from `\QQ` to the 3-adic field:: - sage: phi = QQ.hom(Qp(3, print_mode = 'series')) - sage: phi + sage: phi = QQ.hom(Qp(3, print_mode='series')) # optional - sage.rings.padics + sage: phi # optional - sage.rings.padics Ring morphism: From: Rational Field To: 3-adic Field with capped relative precision 20 - sage: phi.codomain() + sage: phi.codomain() # optional - sage.rings.padics 3-adic Field with capped relative precision 20 - sage: phi(394) + sage: phi(394) # optional - sage.rings.padics 1 + 2*3 + 3^2 + 2*3^3 + 3^4 + 3^5 + O(3^20) An automorphism of a quotient of a univariate polynomial ring:: sage: R. = PolynomialRing(QQ) - sage: S. = R.quo(x^2-2) + sage: S. = R.quo(x^2 - 2) sage: sqrt2^2 2 sage: (3+sqrt2)^10 @@ -227,19 +232,19 @@ Endomorphism of power series ring:: Frobenius on a power series ring over a finite field:: - sage: R. = PowerSeriesRing(GF(5)) - sage: f = R.hom([t^5]); f + sage: R. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: f = R.hom([t^5]); f # optional - sage.rings.finite_rings Ring endomorphism of Power Series Ring in t over Finite Field of size 5 Defn: t |--> t^5 - sage: a = 2 + t + 3*t^2 + 4*t^3 + O(t^4) - sage: b = 1 + t + 2*t^2 + t^3 + O(t^5) - sage: f(a) + sage: a = 2 + t + 3*t^2 + 4*t^3 + O(t^4) # optional - sage.rings.finite_rings + sage: b = 1 + t + 2*t^2 + t^3 + O(t^5) # optional - sage.rings.finite_rings + sage: f(a) # optional - sage.rings.finite_rings 2 + t^5 + 3*t^10 + 4*t^15 + O(t^20) - sage: f(b) + sage: f(b) # optional - sage.rings.finite_rings 1 + t^5 + 2*t^10 + t^15 + O(t^25) - sage: f(a*b) + sage: f(a*b) # optional - sage.rings.finite_rings 2 + 3*t^5 + 3*t^10 + t^15 + O(t^20) - sage: f(a)*f(b) + sage: f(a)*f(b) # optional - sage.rings.finite_rings 2 + 3*t^5 + 3*t^10 + t^15 + O(t^20) Homomorphism of Laurent series ring:: @@ -332,44 +337,51 @@ TESTS:: :: - sage: K. = CyclotomicField(7) - sage: c = K.hom([1/zeta7]) - sage: c == loads(dumps(c)) + sage: K. = CyclotomicField(7) # optional - sage.rings.number_field + sage: c = K.hom([1/zeta7]) # optional - sage.rings.number_field + sage: c == loads(dumps(c)) # optional - sage.rings.number_field True :: - sage: R. = PowerSeriesRing(GF(5)) - sage: f = R.hom([t^5]) - sage: f == loads(dumps(f)) + sage: R. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: f = R.hom([t^5]) # optional - sage.rings.finite_rings + sage: f == loads(dumps(f)) # optional - sage.rings.finite_rings True We define the identity map in many possible ways. These should all compare equal:: - sage: k = GF(2) - sage: R. = k[] - sage: F4. = R.quo(x^2+x+1) - sage: H = End(F4) + sage: k = GF(2) # optional - sage.rings.finite_rings + sage: R. = k[] # optional - sage.rings.finite_rings + sage: F4. = R.quo(x^2+x+1) # optional - sage.rings.finite_rings + sage: H = End(F4) # optional - sage.rings.finite_rings sage: from sage.rings.morphism import * - sage: phi1 = H.identity(); phi1 - Identity endomorphism of Univariate Quotient Polynomial Ring in a over Finite Field of size 2 with modulus x^2 + x + 1 - sage: phi2 = H([a]); phi2 - Ring endomorphism of Univariate Quotient Polynomial Ring in a over Finite Field of size 2 with modulus x^2 + x + 1 + sage: phi1 = H.identity(); phi1 # optional - sage.rings.finite_rings + Identity endomorphism of Univariate Quotient Polynomial Ring in a + over Finite Field of size 2 with modulus x^2 + x + 1 + sage: phi2 = H([a]); phi2 # optional - sage.rings.finite_rings + Ring endomorphism of Univariate Quotient Polynomial Ring in a + over Finite Field of size 2 with modulus x^2 + x + 1 Defn: a |--> a - sage: phi3 = RingHomomorphism_from_base(H, R.hom([x])); phi3 - Ring endomorphism of Univariate Quotient Polynomial Ring in a over Finite Field of size 2 with modulus x^2 + x + 1 + sage: phi3 = RingHomomorphism_from_base(H, R.hom([x])); phi3 # optional - sage.rings.finite_rings + Ring endomorphism of Univariate Quotient Polynomial Ring in a + over Finite Field of size 2 with modulus x^2 + x + 1 Defn: Induced from base ring by - Ring endomorphism of Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) + Ring endomorphism of Univariate Polynomial Ring in x + over Finite Field of size 2 (using GF2X) Defn: x |--> x - sage: phi4 = RingHomomorphism_cover(H); phi4 - Ring endomorphism of Univariate Quotient Polynomial Ring in a over Finite Field of size 2 with modulus x^2 + x + 1 + sage: phi4 = RingHomomorphism_cover(H); phi4 # optional - sage.rings.finite_rings + Ring endomorphism of Univariate Quotient Polynomial Ring in a + over Finite Field of size 2 with modulus x^2 + x + 1 Defn: Natural quotient map - sage: phi5 = F4.frobenius_endomorphism() ^ 2; phi5 - Frobenius endomorphism x |--> x^(2^2) of Univariate Quotient Polynomial Ring in a over Finite Field of size 2 with modulus x^2 + x + 1 - sage: maps = [phi1, phi2, phi3, phi4, phi5] - sage: for f in maps: + sage: phi5 = F4.frobenius_endomorphism() ^ 2; phi5 # optional - sage.rings.finite_rings + Frobenius endomorphism x |--> x^(2^2) of + Univariate Quotient Polynomial Ring in a + over Finite Field of size 2 with modulus x^2 + x + 1 + sage: maps = [phi1, phi2, phi3, phi4, phi5] # optional - sage.rings.finite_rings + sage: for f in maps: # optional - sage.rings.finite_rings ....: for g in maps: ....: if f != g: ....: print("{} != {}".format(f, g)) @@ -457,13 +469,14 @@ cdef class RingMap_lift(RingMap): EXAMPLES:: sage: R. = QQ[] - sage: S. = R.quo( (x^2 + y^2, y) ) - sage: S.lift() + sage: S. = R.quo( (x^2 + y^2, y) ) # optional - sage.libs.singular + sage: S.lift() # optional - sage.libs.singular Set-theoretic ring morphism: - From: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2, y) + From: Quotient of Multivariate Polynomial Ring in x, y + over Rational Field by the ideal (x^2 + y^2, y) To: Multivariate Polynomial Ring in x, y over Rational Field Defn: Choice of lifting map - sage: S.lift() == 0 + sage: S.lift() == 0 # optional - sage.libs.singular False Since :trac:`11068`, it is possible to create @@ -473,10 +486,10 @@ cdef class RingMap_lift(RingMap): of :class:`sage.rings.ring.Ring`, as in the following example:: - sage: MS = MatrixSpace(GF(5),2,2) - sage: I = MS*[MS.0*MS.1,MS.2+MS.3]*MS - sage: Q = MS.quo(I) - sage: Q.0*Q.1 # indirect doctest + sage: MS = MatrixSpace(GF(5), 2, 2) # optional - sage.modules sage.rings.finite_rings + sage: I = MS * [MS.0*MS.1, MS.2+MS.3] * MS # optional - sage.modules sage.rings.finite_rings + sage: Q = MS.quo(I) # optional - sage.modules sage.rings.finite_rings + sage: Q.0*Q.1 # indirect doctest # optional - sage.modules sage.rings.finite_rings [0 1] [0 0] """ @@ -496,12 +509,13 @@ cdef class RingMap_lift(RingMap): An invalid example:: - sage: GF9. = GaussianIntegers().quotient(3) - sage: from sage.rings.morphism import RingMap_lift - sage: RingMap_lift(GF9, ZZ) + sage: GF9. = GaussianIntegers().quotient(3) # optional - sage.rings.number_field + sage: from sage.rings.morphism import RingMap_lift # optional - sage.rings.number_field + sage: RingMap_lift(GF9, ZZ) # optional - sage.rings.number_field Traceback (most recent call last): ... - TypeError: no canonical coercion from Number Field in I with defining polynomial x^2 + 1 with I = 1*I to Integer Ring + TypeError: no canonical coercion from Number Field in I + with defining polynomial x^2 + 1 with I = 1*I to Integer Ring """ self.S = S x = R(0).lift() @@ -640,14 +654,14 @@ cdef class RingHomomorphism(RingMap): EXAMPLES:: - sage: f = ZZ.hom(Zp(3)); f + sage: f = ZZ.hom(Zp(3)); f # optional - sage.rings.padics Ring morphism: From: Integer Ring To: 3-adic Ring with capped relative precision 20 TESTS:: - sage: isinstance(f, sage.rings.morphism.RingHomomorphism) + sage: isinstance(f, sage.rings.morphism.RingHomomorphism) # optional - sage.rings.padics True """ @@ -662,7 +676,7 @@ cdef class RingHomomorphism(RingMap): TESTS:: - sage: ZZ.hom(Zp(3))._repr_type() + sage: ZZ.hom(Zp(3))._repr_type() # optional - sage.rings.padics 'Ring' """ @@ -775,18 +789,19 @@ cdef class RingHomomorphism(RingMap): result has the type of a homomorphism between its domain and codomain:: - sage: C = CyclotomicField(24) - sage: f = End(C)[1] - sage: type(f*f) == type(f) + sage: C = CyclotomicField(24) # optional - sage.rings.number_field + sage: f = End(C)[1] # optional - sage.rings.number_field + sage: type(f*f) == type(f) # optional - sage.rings.number_field True An example where the domain of ``right`` is a relative number field:: sage: PQ. = QQ[] - sage: K. = NumberField([X^2 - 2, X^2 - 3]) - sage: e, u, v, w = End(K) - sage: u*v - Relative number field endomorphism of Number Field in a with defining polynomial X^2 - 2 over its base field + sage: K. = NumberField([X^2 - 2, X^2 - 3]) # optional - sage.rings.number_field + sage: e, u, v, w = End(K) # optional - sage.rings.number_field + sage: u*v # optional - sage.rings.number_field + Relative number field endomorphism of + Number Field in a with defining polynomial X^2 - 2 over its base field Defn: a |--> -a b |--> b @@ -804,39 +819,44 @@ cdef class RingHomomorphism(RingMap): then Coercion map: From: Multivariate Polynomial Ring in a, b over Rational Field - To: Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field + To: Fraction Field of + Multivariate Polynomial Ring in a, b over Rational Field We check that composition works when there is a base map:: sage: R. = ZZ[] - sage: K. = GF(7^2) - sage: L. = K.extension(x^3 - 3) - sage: phi = L.hom([u^7], base_map=K.frobenius_endomorphism()) - sage: phi - Ring endomorphism of Univariate Quotient Polynomial Ring in u over Finite Field in a of size 7^2 with modulus u^3 + 4 + sage: K. = GF(7^2) # optional - sage.rings.finite_rings + sage: L. = K.extension(x^3 - 3) # optional - sage.rings.finite_rings + sage: phi = L.hom([u^7], base_map=K.frobenius_endomorphism()) # optional - sage.rings.finite_rings + sage: phi # optional - sage.rings.finite_rings + Ring endomorphism of Univariate Quotient Polynomial Ring in u + over Finite Field in a of size 7^2 with modulus u^3 + 4 Defn: u |--> 2*u with map of base ring - sage: psi = phi^3; psi - Ring endomorphism of Univariate Quotient Polynomial Ring in u over Finite Field in a of size 7^2 with modulus u^3 + 4 + sage: psi = phi^3; psi # optional - sage.rings.finite_rings + Ring endomorphism of Univariate Quotient Polynomial Ring in u + over Finite Field in a of size 7^2 with modulus u^3 + 4 Defn: u |--> u with map of base ring - sage: psi(a) == phi(phi(phi(a))) + sage: psi(a) == phi(phi(phi(a))) # optional - sage.rings.finite_rings True It also works when the image of the base map is not contained within the base ring of the codomain:: sage: S. = QQ[] sage: T. = S[] - sage: cc = S.hom([x+y]) - sage: f = T.hom([x-y], base_map=cc) + sage: cc = S.hom([x + y]) + sage: f = T.hom([x - y], base_map=cc) sage: f*f - Ring endomorphism of Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + Ring endomorphism of Univariate Polynomial Ring in y + over Univariate Polynomial Ring in x over Rational Field Defn: y |--> 2*y with map of base ring sage: (f*f).base_map() Ring morphism: From: Univariate Polynomial Ring in x over Rational Field - To: Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + To: Univariate Polynomial Ring in y over + Univariate Polynomial Ring in x over Rational Field Defn: x |--> 2*x with map of base ring @@ -887,9 +907,10 @@ cdef class RingHomomorphism(RingMap): EXAMPLES:: - sage: R. = QQ[]; S. = R.quo([x^2,y^2]); f = S.cover() - sage: f.pushforward(R.ideal([x,3*x+x*y+y^2])) - Ideal (xx, xx*yy + 3*xx) of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2, y^2) + sage: R. = QQ[]; S. = R.quo([x^2, y^2]); f = S.cover() # optional - sage.libs.singular + sage: f.pushforward(R.ideal([x, 3*x + x*y + y^2])) # optional - sage.libs.singular + Ideal (xx, xx*yy + 3*xx) of Quotient of Multivariate Polynomial Ring + in x, y over Rational Field by the ideal (x^2, y^2) """ if not ideal.is_Ideal(I): raise TypeError("I must be an ideal") @@ -920,18 +941,18 @@ cdef class RingHomomorphism(RingMap): sage: S. = QQ[] sage: f = R.hom([u^2, u*v, v^2], S) sage: I = S.ideal([u^6, u^5*v, u^4*v^2, u^3*v^3]) - sage: J = f.inverse_image(I); J + sage: J = f.inverse_image(I); J # optional - sage.libs.singular Ideal (y^2 - x*z, x*y*z, x^2*z, x^2*y, x^3) of Multivariate Polynomial Ring in x, y, z over Rational Field - sage: f(J) == I + sage: f(J) == I # optional - sage.libs.singular True Under the above homomorphism, there exists an inverse image for every element that only involves monomials of even degree:: - sage: [f.inverse_image(p) for p in [u^2, u^4, u*v + u^3*v^3]] + sage: [f.inverse_image(p) for p in [u^2, u^4, u*v + u^3*v^3]] # optional - sage.libs.singular [x, x^2, x*y*z + y] - sage: f.inverse_image(u*v^2) + sage: f.inverse_image(u*v^2) # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: element u*v^2 does not have preimage @@ -939,27 +960,27 @@ cdef class RingHomomorphism(RingMap): The image of the inverse image ideal can be strictly smaller than the original ideal:: - sage: S. = QQ['u,v'].quotient('v^2 - 2') - sage: f = QuadraticField(2).hom([v], S) - sage: I = S.ideal(u + v) - sage: J = f.inverse_image(I) - sage: J.is_zero() + sage: S. = QQ['u,v'].quotient('v^2 - 2') # optional - sage.libs.singular + sage: f = QuadraticField(2).hom([v], S) # optional - sage.libs.singular sage.rings.number_field + sage: I = S.ideal(u + v) # optional - sage.libs.singular sage.rings.number_field + sage: J = f.inverse_image(I) # optional - sage.libs.singular sage.rings.number_field + sage: J.is_zero() # optional - sage.libs.singular sage.rings.number_field True - sage: f(J) < I + sage: f(J) < I # optional - sage.libs.singular sage.rings.number_field True Fractional ideals are not yet fully supported:: - sage: K. = NumberField(QQ['x']('x^2+2')) - sage: f = K.hom([-a], K) - sage: I = K.ideal([a + 1]) - sage: f.inverse_image(I) + sage: K. = NumberField(QQ['x']('x^2+2')) # optional - sage.rings.number_field + sage: f = K.hom([-a], K) # optional - sage.rings.number_field + sage: I = K.ideal([a + 1]) # optional - sage.rings.number_field + sage: f.inverse_image(I) # optional - sage.rings.number_field Traceback (most recent call last): ... NotImplementedError: inverse image not implemented... - sage: f.inverse_image(K.ideal(0)).is_zero() + sage: f.inverse_image(K.ideal(0)).is_zero() # optional - sage.rings.number_field True - sage: f.inverse()(I) + sage: f.inverse()(I) # optional - sage.rings.number_field Fractional ideal (-a + 1) ALGORITHM: @@ -973,7 +994,7 @@ cdef class RingHomomorphism(RingMap): TESTS:: - sage: ZZ.hom(Zp(2)).inverse_image(ZZ.ideal(2)) + sage: ZZ.hom(Zp(2)).inverse_image(ZZ.ideal(2)) # optional - sage.rings.padics Traceback (most recent call last): ... ValueError: not an ideal or element in codomain 2-adic Ring @@ -981,7 +1002,7 @@ cdef class RingHomomorphism(RingMap): :: - sage: ZZ.hom(Zp(2)).inverse_image(Zp(2).ideal(2)) + sage: ZZ.hom(Zp(2)).inverse_image(Zp(2).ideal(2)) # optional - sage.rings.padics Traceback (most recent call last): ... NotImplementedError: base rings must be equal @@ -1001,13 +1022,13 @@ cdef class RingHomomorphism(RingMap): EXAMPLES:: - sage: R. = QQbar[] - sage: f = R.hom([x, QQbar(i) * x + y^2], R) - sage: I = R.ideal(y^3) - sage: J = f._inverse_image_ideal(I); J + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = R.hom([x, QQbar(i) * x + y^2], R) # optional - sage.rings.number_field + sage: I = R.ideal(y^3) # optional - sage.rings.number_field + sage: J = f._inverse_image_ideal(I); J # optional - sage.rings.number_field Ideal (x^2 + 2*I*x*y - y^2) - of Multivariate Polynomial Ring in x, y over Algebraic Field - sage: f(J) <= I + of Multivariate Polynomial Ring in x, y over Algebraic Field + sage: f(J) <= I # optional - sage.rings.number_field True TESTS: @@ -1015,17 +1036,17 @@ cdef class RingHomomorphism(RingMap): Check that :trac:`31367` is fixed:: sage: A. = QQ[] - sage: B. = QQ['x,y'].quotient('y') - sage: f = A.hom([x], B) - sage: f.kernel() + sage: B. = QQ['x,y'].quotient('y') # optional - sage.libs.singular + sage: f = A.hom([x], B) # optional - sage.libs.singular + sage: f.kernel() # optional - sage.libs.singular Principal ideal (0) of Univariate Polynomial Ring in t over Rational Field :: sage: A. = QQ[] - sage: B. = QQ['x,y,z'].quotient('z') - sage: f = A.hom([x, y], B) - sage: f.kernel() + sage: B. = QQ['x,y,z'].quotient('z') # optional - sage.libs.singular + sage: f = A.hom([x, y], B) # optional - sage.libs.singular + sage: f.kernel() # optional - sage.libs.singular Ideal (0) of Multivariate Polynomial Ring in t, u over Rational Field """ from .polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing @@ -1067,36 +1088,36 @@ cdef class RingHomomorphism(RingMap): A degenerate case:: - sage: R. = QQ['x,y'].quotient(1) - sage: f = R.hom([y, x], R) - sage: f.inverse_image(x), f.inverse_image(y) # indirect doctest + sage: R. = QQ['x,y'].quotient(1) # optional - sage.libs.singular + sage: f = R.hom([y, x], R) # optional - sage.libs.singular + sage: f.inverse_image(x), f.inverse_image(y) # indirect doctest # optional - sage.libs.singular (0, 0) Check cases involving quotient rings in which a generator is constant (:trac:`31178`):: sage: R. = QQ[] - sage: B. = R.quotient(R.ideal(x)) - sage: g = R.hom([d^2, d^3], B) - sage: g.inverse_image(d) + sage: B. = R.quotient(R.ideal(x)) # optional - sage.libs.singular + sage: g = R.hom([d^2, d^3], B) # optional - sage.libs.singular + sage: g.inverse_image(d) # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: element d does not have preimage - sage: g.inverse_image(d^2) + sage: g.inverse_image(d^2) # optional - sage.libs.singular x - sage: g.inverse_image(d^3) + sage: g.inverse_image(d^3) # optional - sage.libs.singular y - sage: A. = R.quotient(R.ideal(y^2 - x^3)) - sage: h = A.hom([d^2, d^3], B) - sage: h.inverse_image(d^2) + sage: A. = R.quotient(R.ideal(y^2 - x^3)) # optional - sage.libs.singular + sage: h = A.hom([d^2, d^3], B) # optional - sage.libs.singular + sage: h.inverse_image(d^2) # optional - sage.libs.singular a Check that quotient rings are handled correctly (:trac:`33217`):: - sage: A. = QQ['X,Y,Z'].quotient('X^2+Y^2+Z^2-1') - sage: B. = QQ['T,U,V,W'].quotient(['T^2+U^2-1', 'V^2+W^2-1']) - sage: psi = A.hom([v*u, w*u, t], B) - sage: psi.inverse_image(t^2) == z^2 + sage: A. = QQ['X,Y,Z'].quotient('X^2+Y^2+Z^2-1') # optional - sage.libs.singular + sage: B. = QQ['T,U,V,W'].quotient(['T^2+U^2-1', 'V^2+W^2-1']) # optional - sage.libs.singular + sage: psi = A.hom([v*u, w*u, t], B) # optional - sage.libs.singular + sage: psi.inverse_image(t^2) == z^2 # optional - sage.libs.singular True """ graph, from_B, to_A = self._graph_ideal() @@ -1116,7 +1137,7 @@ cdef class RingHomomorphism(RingMap): sage: A. = QQ[] sage: B. = QQ[] sage: f = A.hom([t^4, t^3 - t^2], B) - sage: f.kernel() + sage: f.kernel() # optional - sage.libs.singular Ideal (y^4 - x^3 + 4*x^2*y - 2*x*y^2 + x^2) of Multivariate Polynomial Ring in x, y over Rational Field @@ -1124,50 +1145,50 @@ cdef class RingHomomorphism(RingMap): sage: A. = QQ[] sage: B. = QQ[] - sage: f = A.hom([u^3, u^2*v, u*v^2, v^3],B) - sage: f.kernel() == A.ideal(matrix.hankel([a, b, c], [d]).minors(2)) + sage: f = A.hom([u^3, u^2*v, u*v^2, v^3], B) + sage: f.kernel() == A.ideal(matrix.hankel([a, b, c], [d]).minors(2)) # optional - sage.libs.singular True - sage: Q = A.quotient(f.kernel()) - sage: Q.hom(f.im_gens(), B).is_injective() + sage: Q = A.quotient(f.kernel()) # optional - sage.libs.singular + sage: Q.hom(f.im_gens(), B).is_injective() # optional - sage.libs.singular True The Steiner-Roman surface:: sage: R. = QQ[] - sage: S = R.quotient(x^2 + y^2 + z^2 - 1) - sage: f = R.hom([x*y, x*z, y*z], S) - sage: f.kernel() + sage: S = R.quotient(x^2 + y^2 + z^2 - 1) # optional - sage.libs.singular + sage: f = R.hom([x*y, x*z, y*z], S) # optional - sage.libs.singular + sage: f.kernel() # optional - sage.libs.singular Ideal (x^2*y^2 + x^2*z^2 + y^2*z^2 - x*y*z) - of Multivariate Polynomial Ring in x, y, z over Rational Field + of Multivariate Polynomial Ring in x, y, z over Rational Field TESTS: The results are cached:: - sage: f.kernel() is f.kernel() + sage: f.kernel() is f.kernel() # optional - sage.libs.singular True A degenerate case:: sage: R. = QQ[] - sage: f = R.hom([0, 0], R.quotient(1)) - sage: f.kernel().is_one() + sage: f = R.hom([0, 0], R.quotient(1)) # optional - sage.libs.singular + sage: f.kernel().is_one() # optional - sage.libs.singular True :: - sage: K. = QuadraticField(2) - sage: K.hom([-sqrt2], K).kernel().is_zero() + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: K.hom([-sqrt2], K).kernel().is_zero() # optional - sage.rings.number_field True :: - sage: A. = QuadraticField(2) - sage: B. = A.extension(A['b']('b^2-3')) - sage: C. = B.absolute_field() - sage: A.hom([B(a)], C).kernel().is_zero() + sage: A. = QuadraticField(2) # optional - sage.rings.number_field + sage: B. = A.extension(A['b']('b^2-3')) # optional - sage.rings.number_field + sage: C. = B.absolute_field() # optional - sage.rings.number_field + sage: A.hom([B(a)], C).kernel().is_zero() # optional - sage.rings.number_field True - sage: A.hom([a], B).kernel() + sage: A.hom([a], B).kernel() # optional - sage.rings.number_field Traceback (most recent call last): ... NotImplementedError: base rings must be equal @@ -1242,32 +1263,32 @@ 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: 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, + sage: A. = QQbar['z,w'].quotient('z*w - 1') # optional - sage.rings.number_field + sage: B. = QQbar['x,y'].quotient('2*x^2 + y^2 - 1') # optional - sage.rings.number_field + sage: f = A.hom([QQbar(2).sqrt()*x + QQbar(I)*y, # optional - sage.rings.number_field ....: QQbar(2).sqrt()*x - QQbar(I)*y], B) - sage: f._graph_ideal()[0] + sage: f._graph_ideal()[0] # optional - sage.rings.number_field Ideal (z*w - 1, 2*x^2 + y^2 - 1, 1.414213562373095?*x + I*y - z, 1.414213562373095?*x + (-I)*y - w) of Multivariate Polynomial Ring in x, y, z, w over Algebraic Field - sage: f.inverse()(f(z)), f.inverse()(f(w)) + sage: f.inverse()(f(z)), f.inverse()(f(w)) # optional - sage.rings.number_field (z, w) Non-trivial base maps are not supported:: - sage: K. = QuadraticField(2) - sage: R. = K[] - sage: f = R.hom([x, a*x + y], R, base_map=K.hom([-a], K)) - sage: f._graph_ideal() + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: f = R.hom([x, a*x + y], R, base_map=K.hom([-a], K)) # optional - sage.rings.number_field + sage: f._graph_ideal() # optional - sage.rings.number_field Traceback (most recent call last): ... NotImplementedError: base map must be trivial Non-commutative rings are not supported (:trac:`32824`):: - sage: A = GradedCommutativeAlgebra(QQ, 'x,y,z') - sage: A.hom(A.gens(), A).kernel() + sage: A = GradedCommutativeAlgebra(QQ, 'x,y,z') # optional - sage.combinat sage.modules + sage: A.hom(A.gens(), A).kernel() # optional - sage.combinat sage.modules Traceback (most recent call last): ... NotImplementedError: rings are not commutative @@ -1324,7 +1345,7 @@ cdef class RingHomomorphism(RingMap): sage: R. = QQ[] sage: f = R.hom([2*t - 1], R) - sage: f.inverse() + sage: f.inverse() # optional - sage.libs.singular Ring endomorphism of Univariate Polynomial Ring in t over Rational Field Defn: t |--> 1/2*t + 1/2 @@ -1333,15 +1354,15 @@ cdef class RingHomomorphism(RingMap): sage: R. = QQ[] sage: f = R.hom([y*z, x*z, x*y], R) - sage: f.inverse() + sage: f.inverse() # optional - sage.libs.singular Traceback (most recent call last): ... ZeroDivisionError: ring homomorphism not surjective - sage: f.is_injective() + sage: f.is_injective() # optional - sage.libs.singular True - sage: Q. = R.quotient(x*y*z - 1) - sage: g = Q.hom([y*z, x*z, x*y], Q) - sage: g.inverse() + sage: Q. = R.quotient(x*y*z - 1) # optional - sage.libs.singular + sage: g = Q.hom([y*z, x*z, x*y], Q) # optional - sage.libs.singular + sage: g.inverse() # optional - sage.libs.singular Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by the ideal (x*y*z - 1) Defn: x |--> y*z @@ -1352,24 +1373,24 @@ cdef class RingHomomorphism(RingMap): sage: S. = ZZ[] sage: f = S.hom([x + 2*y, x + 3*y], S) - sage: f.inverse() + sage: f.inverse() # optional - sage.libs.singular Ring endomorphism of Multivariate Polynomial Ring in x, y over Integer Ring Defn: x |--> 3*x - 2*y y |--> -x + y - sage: (f.inverse() * f).is_identity() + sage: (f.inverse() * f).is_identity() # optional - sage.libs.singular True The following homomorphism is invertible over the rationals, but not over the integers:: sage: g = S.hom([x + y, x - y - 2], S) - sage: g.inverse() + sage: g.inverse() # optional - sage.libs.singular Traceback (most recent call last): ... ZeroDivisionError: ring homomorphism not surjective sage: R. = QQ[x,y] sage: h = R.hom([x + y, x - y - 2], R) - sage: (h.inverse() * h).is_identity() + sage: (h.inverse() * h).is_identity() # optional - sage.libs.singular True This example by M. Nagata is a wild automorphism:: @@ -1377,13 +1398,13 @@ cdef class RingHomomorphism(RingMap): sage: R. = QQ[] sage: sigma = R.hom([x - 2*y*(z*x+y^2) - z*(z*x+y^2)^2, ....: y + z*(z*x+y^2), z], R) - sage: tau = sigma.inverse(); tau + sage: tau = sigma.inverse(); tau # optional - sage.libs.singular Ring endomorphism of Multivariate Polynomial Ring in x, y, z over Rational Field Defn: x |--> -y^4*z - 2*x*y^2*z^2 - x^2*z^3 + 2*y^3 + 2*x*y*z + x y |--> -y^2*z - x*z^2 + y z |--> z - sage: (tau * sigma).is_identity() + sage: (tau * sigma).is_identity() # optional - sage.libs.singular True We compute the triangular automorphism that converts moments to @@ -1407,37 +1428,37 @@ cdef class RingHomomorphism(RingMap): x1^5 + 10*x1^3*x2 + 15*x1*x2^2 + 10*x1^2*x3 + 10*x2*x3 + 5*x1*x4 + x5] sage: all(p.is_homogeneous() for p in phi.im_gens()) True - sage: phi.inverse().im_gens()[:5] + sage: phi.inverse().im_gens()[:5] # optional - sage.libs.singular [x1, -x1^2 + x2, 2*x1^3 - 3*x1*x2 + x3, -6*x1^4 + 12*x1^2*x2 - 3*x2^2 - 4*x1*x3 + x4, 24*x1^5 - 60*x1^3*x2 + 30*x1*x2^2 + 20*x1^2*x3 - 10*x2*x3 - 5*x1*x4 + x5] - sage: (phi.inverse() * phi).is_identity() + sage: (phi.inverse() * phi).is_identity() # optional - sage.libs.singular True Automorphisms of number fields as well as Galois fields are supported:: - sage: K. = CyclotomicField(7) - sage: c = K.hom([1/zeta7]) - sage: (c.inverse() * c).is_identity() + sage: K. = CyclotomicField(7) # optional - sage.rings.number_field + sage: c = K.hom([1/zeta7]) # optional - sage.rings.number_field + sage: (c.inverse() * c).is_identity() # optional - sage.rings.number_field True - sage: F. = GF(7^3) - sage: f = F.hom(t^7, F) - sage: (f.inverse() * f).is_identity() + sage: F. = GF(7^3) # optional - sage.rings.finite_rings + sage: f = F.hom(t^7, F) # optional - sage.rings.finite_rings + sage: (f.inverse() * f).is_identity() # optional - sage.rings.finite_rings True An isomorphism between the algebraic torus and the circle over a 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') - sage: f = A.hom([x + i*y, x - i*y], B) - sage: g = f.inverse() - sage: g.morphism_from_cover().im_gens() + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: A. = K['z,w'].quotient('z*w - 1') # optional - sage.rings.number_field + sage: B. = K['x,y'].quotient('x^2 + y^2 - 1') # optional - sage.rings.number_field + sage: f = A.hom([x + i*y, x - i*y], B) # optional - sage.rings.number_field + sage: g = f.inverse() # optional - sage.rings.number_field + sage: g.morphism_from_cover().im_gens() # optional - sage.rings.number_field [1/2*z + 1/2*w, (-1/2*i)*z + (1/2*i)*w] - sage: all(g(f(z)) == z for z in A.gens()) + sage: all(g(f(z)) == z for z in A.gens()) # optional - sage.rings.number_field True TESTS: @@ -1445,43 +1466,43 @@ cdef class RingHomomorphism(RingMap): Morphisms involving quotient rings:: sage: R. = QQ[] - sage: S. = QQ['s,u,t'].quotient('u-t^2') - sage: f = R.hom([s, -t], S) - sage: (f.inverse() * f).is_identity() + sage: S. = QQ['s,u,t'].quotient('u-t^2') # optional - sage.libs.singular + sage: f = R.hom([s, -t], S) # optional - sage.libs.singular + sage: (f.inverse() * f).is_identity() # optional - sage.libs.singular True - sage: Q. = R.quotient(x-y^2) - sage: g = Q.hom([v, -w], Q) - sage: g.inverse()(g(v)) == v and g.inverse()(g(w)) == w + sage: Q. = R.quotient(x - y^2) # optional - sage.libs.singular + sage: g = Q.hom([v, -w], Q) # optional - sage.libs.singular + sage: g.inverse()(g(v)) == v and g.inverse()(g(w)) == w # optional - sage.libs.singular True sage: S. = QQ[] - sage: h = Q.hom([z^2, -z], S) - sage: h.inverse()(h(v)) == v and h.inverse()(h(w)) == w + sage: h = Q.hom([z^2, -z], S) # optional - sage.libs.singular + sage: h.inverse()(h(v)) == v and h.inverse()(h(w)) == w # optional - sage.libs.singular True Morphisms between number fields and quotient rings:: - sage: K. = QuadraticField(2) - sage: f = K.hom([-sqrt2], K.polynomial_quotient_ring()) - sage: (f.inverse() * f).is_identity() + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: f = K.hom([-sqrt2], K.polynomial_quotient_ring()) # optional - sage.rings.number_field + sage: (f.inverse() * f).is_identity() # optional - sage.rings.number_field True - sage: g = K.polynomial_quotient_ring().hom([-sqrt2], K) - sage: (g.inverse() * g).is_identity() + sage: g = K.polynomial_quotient_ring().hom([-sqrt2], K) # optional - sage.rings.number_field + sage: (g.inverse() * g).is_identity() # optional - sage.rings.number_field True Morphisms involving Galois fields:: - sage: A. = GF(7^3) - sage: R = A.polynomial_ring().quotient(A.polynomial()) - sage: g = A.hom(R.gens(), R) - sage: (g.inverse() * g).is_identity() + sage: A. = GF(7^3) # optional - sage.rings.finite_rings + sage: R = A.polynomial_ring().quotient(A.polynomial()) # optional - sage.rings.finite_rings + sage: g = A.hom(R.gens(), R) # optional - sage.rings.finite_rings + sage: (g.inverse() * g).is_identity() # optional - sage.rings.finite_rings True - sage: B., f = A.extension(3, map=True) - sage: f.inverse() + sage: B., f = A.extension(3, map=True) # optional - sage.rings.finite_rings + sage: f.inverse() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: ring homomorphism not surjective - sage: B., f = A.extension(1, map=True) - sage: f.inverse() + sage: B., f = A.extension(1, map=True) # optional - sage.rings.finite_rings + sage: f.inverse() # optional - sage.rings.finite_rings Ring morphism: From: Finite Field in T of size 7^3 To: Finite Field in t of size 7^3 @@ -1491,7 +1512,7 @@ cdef class RingHomomorphism(RingMap): sage: R. = QQ[] sage: S. = QQ[] - sage: S.hom([x, y, 0], R).inverse() + sage: S.hom([x, y, 0], R).inverse() # optional - sage.libs.singular Traceback (most recent call last): ... ZeroDivisionError: ring homomorphism not injective @@ -1500,12 +1521,12 @@ cdef class RingHomomorphism(RingMap): Traceback (most recent call last): ... ZeroDivisionError: ring homomorphism not injective - sage: Q. = R.quotient([x^5, y^4]) - sage: R.hom([u, v], Q).inverse() + sage: Q. = R.quotient([x^5, y^4]) # optional - sage.libs.singular + sage: R.hom([u, v], Q).inverse() # optional - sage.libs.singular Traceback (most recent call last): ... ZeroDivisionError: ring homomorphism not injective - sage: Q.cover().inverse() + sage: Q.cover().inverse() # optional - sage.libs.singular Traceback (most recent call last): ... ZeroDivisionError: ring homomorphism not injective @@ -1519,23 +1540,23 @@ cdef class RingHomomorphism(RingMap): A homomorphism over ``QQbar``:: - sage: R. = QQbar[] - sage: f = R.hom([x + QQbar(I)*y^2, -y], R) - sage: (f.inverse() * f).is_identity() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = R.hom([x + QQbar(I)*y^2, -y], R) # optional - sage.rings.number_field + sage: (f.inverse() * f).is_identity() # optional - sage.rings.number_field True Check that results are cached:: - sage: R. = GF(823)[] - sage: f = R.hom([x, y+x^2], R) - sage: f.inverse() is f.inverse() + sage: R. = GF(823)[] # optional - sage.rings.finite_rings + sage: f = R.hom([x, y+x^2], R) # optional - sage.rings.finite_rings + sage: f.inverse() is f.inverse() # optional - sage.rings.finite_rings True Some subclasses of ring homomorphisms are not supported:: sage: from sage.rings.morphism import FrobeniusEndomorphism_generic - sage: K. = PowerSeriesRing(GF(5)) - sage: FrobeniusEndomorphism_generic(K).inverse() + sage: K. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: FrobeniusEndomorphism_generic(K).inverse() # optional - sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError @@ -1562,11 +1583,11 @@ cdef class RingHomomorphism(RingMap): sage: R. = QQ[] sage: f = R.hom([x + 123*y^2, y], R) - sage: f._graph_ideal()[0].groebner_basis.is_in_cache() + sage: f._graph_ideal()[0].groebner_basis.is_in_cache() # optional - sage.libs.singular False - sage: f.is_injective() + sage: f.is_injective() # optional - sage.libs.singular True - sage: f._graph_ideal()[0].groebner_basis.is_in_cache() + sage: f._graph_ideal()[0].groebner_basis.is_in_cache() # optional - sage.libs.singular True """ if not self.is_injective(): @@ -1586,9 +1607,9 @@ cdef class RingHomomorphism(RingMap): EXAMPLES:: - sage: R. = GF(17)[] - sage: f = R.hom([3*x, y + x^2 + x^3], R) - sage: (f * ~f).is_identity() + sage: R. = GF(17)[] # optional - sage.rings.finite_rings + sage: f = R.hom([3*x, y + x^2 + x^3], R) # optional - sage.rings.finite_rings + sage: (f * ~f).is_identity() # optional - sage.rings.finite_rings True """ return self.inverse() @@ -1600,10 +1621,10 @@ cdef class RingHomomorphism(RingMap): EXAMPLES:: sage: R. = QQ[] - sage: R.hom([y*z, x*z, x*y], R).is_surjective() + sage: R.hom([y*z, x*z, x*y], R).is_surjective() # optional - sage.libs.singular False - sage: Q. = R.quotient(x*y*z - 1) - sage: R.hom([y*z, x*z, x*y], Q).is_surjective() + sage: Q. = R.quotient(x*y*z - 1) # optional - sage.libs.singular + sage: R.hom([y*z, x*z, x*y], Q).is_surjective() # optional - sage.libs.singular True ALGORITHM: @@ -1624,10 +1645,10 @@ cdef class RingHomomorphism(RingMap): EXAMPLES:: sage: R. = QQ[] - sage: R.hom([y*z, x*z, x*y], R).is_invertible() + sage: R.hom([y*z, x*z, x*y], R).is_invertible() # optional - sage.libs.singular False - sage: Q. = R.quotient(x*y*z - 1) - sage: Q.hom([y*z, x*z, x*y], Q).is_invertible() + sage: Q. = R.quotient(x*y*z - 1) # optional - sage.libs.singular + sage: Q.hom([y*z, x*z, x*y], Q).is_invertible() # optional - sage.libs.singular True ALGORITHM: @@ -1760,7 +1781,7 @@ cdef class RingHomomorphism_im_gens(RingHomomorphism): EXAMPLES:: sage: R. = QQ[] - sage: phi = R.hom([x,x+y]); phi + sage: phi = R.hom([x, x + y]); phi Ring endomorphism of Multivariate Polynomial Ring in x, y over Rational Field Defn: x |--> x y |--> x + y @@ -1769,33 +1790,34 @@ cdef class RingHomomorphism_im_gens(RingHomomorphism): Here's another example where the domain isn't free:: - sage: S. = R.quotient(x - y) - sage: phi = S.hom([xx+1,xx+1]) + sage: S. = R.quotient(x - y) # optional - sage.libs.singular + sage: phi = S.hom([xx + 1, xx + 1]) # optional - sage.libs.singular Note that one has to specify valid images:: - sage: phi = S.hom([xx+1,xx-1]) + sage: phi = S.hom([xx + 1, xx - 1]) # optional - sage.libs.singular Traceback (most recent call last): ... - ValueError: relations do not all (canonically) map to 0 under map determined by images of generators + ValueError: relations do not all (canonically) map to 0 + under map determined by images of generators You can give a map of the base ring:: sage: Zx. = ZZ[] - sage: K. = NumberField(x^2 + 1) - sage: cc = K.hom([-i]) - sage: R. = K[] - sage: z = 1 + i*t + (3+4*i)*t^2 - sage: z._im_gens_(R, [t^2], base_map=cc) + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: cc = K.hom([-i]) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: z = 1 + i*t + (3+4*i)*t^2 # optional - sage.rings.number_field + sage: z._im_gens_(R, [t^2], base_map=cc) # optional - sage.rings.number_field (-4*i + 3)*t^4 - i*t^2 + 1 The base map's codomain is extended to the whole codomain:: sage: S. = QQ[] sage: T. = S[] - sage: cc = S.hom([x+1]) - sage: f = T.hom([x-y], base_map=cc) - sage: g = T.hom([x-y], base_map=cc.extend_codomain(T)) + sage: cc = S.hom([x + 1]) + sage: f = T.hom([x - y], base_map=cc) + sage: g = T.hom([x - y], base_map=cc.extend_codomain(T)) sage: f == g True sage: f.base_map() == cc.extend_codomain(T) @@ -1806,11 +1828,12 @@ cdef class RingHomomorphism_im_gens(RingHomomorphism): speed up creation of a homomorphism:: sage: R. = QQ[] - sage: S. = R.quotient(x - y) - sage: phi = S.hom([xx+1,xx-1], check=False) + sage: S. = R.quotient(x - y) # optional - sage.libs.singular + sage: phi = S.hom([xx + 1, xx - 1], check=False) # optional - sage.libs.singular Traceback (most recent call last): ... - ValueError: relations do not all (canonically) map to 0 under map determined by images of generators + ValueError: relations do not all (canonically) map to 0 + under map determined by images of generators """ RingHomomorphism.__init__(self, parent) if not isinstance(im_gens, sage.structure.sequence.Sequence_generic): @@ -1848,7 +1871,7 @@ cdef class RingHomomorphism_im_gens(RingHomomorphism): EXAMPLES:: sage: R. = QQ[] - sage: f = R.hom([x,x+y]) + sage: f = R.hom([x, x + y]) sage: f.im_gens() [x, x + y] @@ -1869,28 +1892,31 @@ cdef class RingHomomorphism_im_gens(RingHomomorphism): EXAMPLES:: sage: R. = ZZ[] - sage: K. = NumberField(x^2 + 1) - sage: cc = K.hom([-i]) - sage: S. = K[] - sage: phi = S.hom([y^2], base_map=cc) - sage: phi - Ring endomorphism of Univariate Polynomial Ring in y over Number Field in i with defining polynomial x^2 + 1 + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: cc = K.hom([-i]) # optional - sage.rings.number_field + sage: S. = K[] # optional - sage.rings.number_field + sage: phi = S.hom([y^2], base_map=cc) # optional - sage.rings.number_field + sage: phi # optional - sage.rings.number_field + Ring endomorphism of Univariate Polynomial Ring in y + over Number Field in i with defining polynomial x^2 + 1 Defn: y |--> y^2 with map of base ring - sage: phi(y) + sage: phi(y) # optional - sage.rings.number_field y^2 - sage: phi(i*y) + sage: phi(i*y) # optional - sage.rings.number_field -i*y^2 - sage: phi.base_map() + sage: phi.base_map() # optional - sage.rings.number_field Composite map: From: Number Field in i with defining polynomial x^2 + 1 - To: Univariate Polynomial Ring in y over Number Field in i with defining polynomial x^2 + 1 + To: Univariate Polynomial Ring in y over Number Field in i + with defining polynomial x^2 + 1 Defn: Ring endomorphism of Number Field in i with defining polynomial x^2 + 1 Defn: i |--> -i then Polynomial base injection morphism: From: Number Field in i with defining polynomial x^2 + 1 - To: Univariate Polynomial Ring in y over Number Field in i with defining polynomial x^2 + 1 + To: Univariate Polynomial Ring in y over Number Field in i + with defining polynomial x^2 + 1 """ return self._base_map @@ -1901,7 +1927,7 @@ cdef class RingHomomorphism_im_gens(RingHomomorphism): EXAMPLES:: sage: R. = QQ[] - sage: f = R.hom([x,x+y]) + sage: f = R.hom([x, x + y]) sage: g = copy(f) # indirect doctest sage: g == f True @@ -1921,7 +1947,7 @@ cdef class RingHomomorphism_im_gens(RingHomomorphism): EXAMPLES:: sage: R. = QQ[] - sage: f = R.hom([x,x+y]) + sage: f = R.hom([x, x + y]) sage: g = copy(f) # indirect doctest sage: g == f True @@ -1942,51 +1968,51 @@ cdef class RingHomomorphism_im_gens(RingHomomorphism): A single variate quotient over `\QQ`:: sage: R. = QQ[] - sage: Q. = R.quotient(x^2 + x + 1) - sage: f1 = R.hom([a]) - sage: f2 = R.hom([a + a^2 + a + 1]) - sage: f1 == f2 + sage: Q. = R.quotient(x^2 + x + 1) # optional - sage.libs.pari + sage: f1 = R.hom([a]) # optional - sage.libs.pari + sage: f2 = R.hom([a + a^2 + a + 1]) # optional - sage.libs.pari + sage: f1 == f2 # optional - sage.libs.pari True - sage: f1 == R.hom([a^2]) + sage: f1 == R.hom([a^2]) # optional - sage.libs.pari False - sage: f1(x^3 + x) + sage: f1(x^3 + x) # optional - sage.libs.pari a + 1 - sage: f2(x^3 + x) + sage: f2(x^3 + x) # optional - sage.libs.pari a + 1 TESTS:: - sage: loads(dumps(f2)) == f2 + sage: loads(dumps(f2)) == f2 # optional - sage.libs.pari True :: - sage: R. = QQ[]; f = R.hom([x,x+y]); g = R.hom([y,x]) - sage: f == g # indirect doctest + sage: R. = QQ[]; f = R.hom([x, x + y]); g = R.hom([y, x]) # optional - sage.libs.pari + sage: f == g # indirect doctest # optional - sage.libs.pari False EXAMPLES: A multivariate quotient over a finite field:: - sage: R. = GF(7)[] - sage: Q. = R.quotient([x^2 + x + 1, y^2 + y + 1]) - sage: f1 = R.hom([a, b]) - sage: f2 = R.hom([a + a^2 + a + 1, b + b^2 + b + 1]) - sage: f1 == f2 + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: Q. = R.quotient([x^2 + x + 1, y^2 + y + 1]) # optional - sage.rings.finite_rings + sage: f1 = R.hom([a, b]) # optional - sage.rings.finite_rings + sage: f2 = R.hom([a + a^2 + a + 1, b + b^2 + b + 1]) # optional - sage.rings.finite_rings + sage: f1 == f2 # optional - sage.rings.finite_rings True - sage: f1 == R.hom([b,a]) + sage: f1 == R.hom([b, a]) # optional - sage.rings.finite_rings False - sage: x^3 + x + y^2 + sage: x^3 + x + y^2 # optional - sage.rings.finite_rings x^3 + y^2 + x - sage: f1(x^3 + x + y^2) + sage: f1(x^3 + x + y^2) # optional - sage.rings.finite_rings a - b - sage: f2(x^3 + x + y^2) + sage: f2(x^3 + x + y^2) # optional - sage.rings.finite_rings a - b TESTS:: - sage: loads(dumps(f2)) == f2 + sage: loads(dumps(f2)) == f2 # optional - sage.rings.finite_rings True This was fixed in :trac:`24277`:: @@ -2078,8 +2104,10 @@ cdef class RingHomomorphism_from_base(RingHomomorphism): sage: Pf = PR.hom(f,PS) sage: Pf Ring morphism: - From: Univariate Polynomial Ring in t over Multivariate Polynomial Ring in x, y over Rational Field - To: Univariate Polynomial Ring in t over Univariate Polynomial Ring in z over Rational Field + From: Univariate Polynomial Ring in t + over Multivariate Polynomial Ring in x, y over Rational Field + To: Univariate Polynomial Ring in t + over Univariate Polynomial Ring in z over Rational Field Defn: Induced from base ring by Ring morphism: From: Multivariate Polynomial Ring in x, y over Rational Field @@ -2093,44 +2121,54 @@ cdef class RingHomomorphism_from_base(RingHomomorphism): Similarly, we can construct the induced homomorphism on a matrix ring over our polynomial rings:: - sage: MR = MatrixSpace(R,2,2) - sage: MS = MatrixSpace(S,2,2) - sage: M = MR([x^2 + 1/7*x*y - y^2, - 1/2*y^2 + 2*y + 1/6, 4*x^2 - 14*x, 1/2*y^2 + 13/4*x - 2/11*y]) - sage: Mf = MR.hom(f,MS) - sage: Mf + sage: MR = MatrixSpace(R, 2, 2) # optional - sage.modules + sage: MS = MatrixSpace(S, 2, 2) # optional - sage.modules + sage: M = MR([x^2 + 1/7*x*y - y^2, -1/2*y^2 + 2*y + 1/6, # optional - sage.modules + ....: 4*x^2 - 14*x, 1/2*y^2 + 13/4*x - 2/11*y]) + sage: Mf = MR.hom(f, MS) # optional - sage.modules + sage: Mf # optional - sage.modules Ring morphism: - From: Full MatrixSpace of 2 by 2 dense matrices over Multivariate Polynomial Ring in x, y over Rational Field - To: Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in z over Rational Field + From: Full MatrixSpace of 2 by 2 dense matrices + over Multivariate Polynomial Ring in x, y over Rational Field + To: Full MatrixSpace of 2 by 2 dense matrices + over Univariate Polynomial Ring in z over Rational Field Defn: Induced from base ring by Ring morphism: From: Multivariate Polynomial Ring in x, y over Rational Field To: Univariate Polynomial Ring in z over Rational Field Defn: x |--> 2*z y |--> 3*z - sage: Mf(M) + sage: Mf(M) # optional - sage.modules [ -29/7*z^2 -9/2*z^2 + 6*z + 1/6] [ 16*z^2 - 28*z 9/2*z^2 + 131/22*z] The construction of induced homomorphisms is recursive, and so we have:: - sage: MPR = MatrixSpace(PR, 2) - sage: MPS = MatrixSpace(PS, 2) - sage: M = MPR([(- x + y)*t^2 + 58*t - 3*x^2 + x*y, (- 1/7*x*y - 1/40*x)*t^2 + (5*x^2 + y^2)*t + 2*y, (- 1/3*y + 1)*t^2 + 1/3*x*y + y^2 + 5/2*y + 1/4, (x + 6*y + 1)*t^2]) - sage: MPf = MPR.hom(f,MPS); MPf + sage: MPR = MatrixSpace(PR, 2) # optional - sage.modules + sage: MPS = MatrixSpace(PS, 2) # optional - sage.modules + sage: M = MPR([(-x + y)*t^2 + 58*t - 3*x^2 + x*y, # optional - sage.modules + ....: (- 1/7*x*y - 1/40*x)*t^2 + (5*x^2 + y^2)*t + 2*y, + ....: (- 1/3*y + 1)*t^2 + 1/3*x*y + y^2 + 5/2*y + 1/4, + ....: (x + 6*y + 1)*t^2]) + sage: MPf = MPR.hom(f, MPS); MPf # optional - sage.modules Ring morphism: - From: Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in t over Multivariate Polynomial Ring in x, y over Rational Field - To: Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in t over Univariate Polynomial Ring in z over Rational Field + From: Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial + Ring in t over Multivariate Polynomial Ring in x, y over Rational Field + To: Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial + Ring in t over Univariate Polynomial Ring in z over Rational Field Defn: Induced from base ring by Ring morphism: - From: Univariate Polynomial Ring in t over Multivariate Polynomial Ring in x, y over Rational Field - To: Univariate Polynomial Ring in t over Univariate Polynomial Ring in z over Rational Field + From: Univariate Polynomial Ring in t + over Multivariate Polynomial Ring in x, y over Rational Field + To: Univariate Polynomial Ring in t + over Univariate Polynomial Ring in z over Rational Field Defn: Induced from base ring by Ring morphism: From: Multivariate Polynomial Ring in x, y over Rational Field To: Univariate Polynomial Ring in z over Rational Field Defn: x |--> 2*z y |--> 3*z - sage: MPf(M) + sage: MPf(M) # optional - sage.modules [ z*t^2 + 58*t - 6*z^2 (-6/7*z^2 - 1/20*z)*t^2 + 29*z^2*t + 6*z] [ (-z + 1)*t^2 + 11*z^2 + 15/2*z + 1/4 (20*z + 1)*t^2] """ @@ -2142,11 +2180,12 @@ cdef class RingHomomorphism_from_base(RingHomomorphism): sage: from sage.rings.morphism import RingHomomorphism_from_base sage: R. = ZZ[] - sage: f = R.hom([2*x],R) - sage: P = MatrixSpace(R,2).Hom(MatrixSpace(R,2)) - sage: g = RingHomomorphism_from_base(P,f) - sage: g - Ring endomorphism of Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring + sage: f = R.hom([2*x], R) + sage: P = MatrixSpace(R, 2).Hom(MatrixSpace(R, 2)) # optional - sage.modules + sage: g = RingHomomorphism_from_base(P, f) # optional - sage.modules + sage: g # optional - sage.modules + Ring endomorphism of Full MatrixSpace of 2 by 2 dense matrices + over Univariate Polynomial Ring in x over Integer Ring Defn: Induced from base ring by Ring endomorphism of Univariate Polynomial Ring in x over Integer Ring Defn: x |--> 2*x @@ -2155,11 +2194,13 @@ cdef class RingHomomorphism_from_base(RingHomomorphism): codomain are constructed in a compatible way. So, the following results in an error:: - sage: P = MatrixSpace(R,2).Hom(R['t']) - sage: g = RingHomomorphism_from_base(P,f) + sage: P = MatrixSpace(R, 2).Hom(R['t']) # optional - sage.modules + sage: g = RingHomomorphism_from_base(P, f) # optional - sage.modules Traceback (most recent call last): ... - ValueError: domain (Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring) and codomain (Univariate Polynomial Ring in t over Univariate Polynomial Ring in x over Integer Ring) must have the same functorial construction over their base rings + ValueError: domain (Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring) + and codomain (Univariate Polynomial Ring in t over Univariate Polynomial Ring in x over Integer Ring) + must have the same functorial construction over their base rings """ RingHomomorphism.__init__(self, parent) if underlying.domain() != parent.domain().base(): @@ -2178,11 +2219,11 @@ cdef class RingHomomorphism_from_base(RingHomomorphism): sage: R. = QQ[] sage: S. = QQ[] - sage: f = R.hom([2*z,3*z],S) - sage: MR = MatrixSpace(R,2) - sage: MS = MatrixSpace(S,2) - sage: g = MR.hom(f,MS) - sage: g.underlying_map() == f + sage: f = R.hom([2*z, 3*z], S) + sage: MR = MatrixSpace(R, 2) # optional - sage.modules + sage: MS = MatrixSpace(S, 2) # optional - sage.modules + sage: g = MR.hom(f, MS) # optional - sage.modules + sage: g.underlying_map() == f # optional - sage.modules True """ return self._underlying @@ -2195,10 +2236,10 @@ cdef class RingHomomorphism_from_base(RingHomomorphism): sage: R. = QQ[] sage: S. = QQ[] - sage: f = R.hom([2*z,3*z],S) + sage: f = R.hom([2*z, 3*z],S) sage: PR. = R[] sage: PS = S['t'] - sage: phi = PR.hom(f,PS) + sage: phi = PR.hom(f, PS) sage: type(phi) sage: psi = copy(phi); psi # indirect doctest @@ -2256,24 +2297,24 @@ cdef class RingHomomorphism_from_base(RingHomomorphism): `\QQ`:: sage: R. = QQ[] - sage: Q. = R.quotient(x^2 + x + 1) - sage: f1 = R.hom([a]) - sage: f2 = R.hom([a + a^2 + a + 1]) - sage: PR. = R[] - sage: PQ = Q['s','t'] - sage: f1P = PR.hom(f1,PQ) - sage: f2P = PR.hom(f2,PQ) - sage: f1P == f2P + sage: Q. = R.quotient(x^2 + x + 1) # optional - sage.libs.pari sage.modules + sage: f1 = R.hom([a]) # optional - sage.libs.pari sage.libs.singular sage.modules + sage: f2 = R.hom([a + a^2 + a + 1]) # optional - sage.libs.pari sage.libs.singular sage.modules + sage: PR. = R[] # optional - sage.libs.pari sage.libs.singular sage.modules + sage: PQ = Q['s','t'] # optional - sage.libs.pari sage.libs.singular sage.modules + sage: f1P = PR.hom(f1,PQ) # optional - sage.libs.pari sage.libs.singular sage.modules + sage: f2P = PR.hom(f2,PQ) # optional - sage.libs.pari sage.libs.singular sage.modules + sage: f1P == f2P # optional - sage.libs.pari sage.libs.singular sage.modules True TESTS:: - sage: f1P == loads(dumps(f1P)) + sage: f1P == loads(dumps(f1P)) # optional - sage.libs.pari sage.libs.singular sage.modules True - sage: R. = QQ[]; f = R.hom([x,x+y]); g = R.hom([y,x]) + sage: R. = QQ[]; f = R.hom([x, x + y]); g = R.hom([y, x]) sage: S. = R[] - sage: fS = S.hom(f,S); gS = S.hom(g,S) + sage: fS = S.hom(f, S); gS = S.hom(g, S) sage: fS != gS # indirect doctest True @@ -2281,20 +2322,20 @@ cdef class RingHomomorphism_from_base(RingHomomorphism): A matrix ring over a multivariate quotient over a finite field:: - sage: R. = GF(7)[] - sage: Q. = R.quotient([x^2 + x + 1, y^2 + y + 1]) - sage: f1 = R.hom([a, b]) - sage: f2 = R.hom([a + a^2 + a + 1, b + b^2 + b + 1]) - sage: MR = MatrixSpace(R,2) - sage: MQ = MatrixSpace(Q,2) - sage: f1M = MR.hom(f1,MQ) - sage: f2M = MR.hom(f2,MQ) - sage: f1M == f2M + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: Q. = R.quotient([x^2 + x + 1, y^2 + y + 1]) # optional - sage.rings.finite_rings + sage: f1 = R.hom([a, b]) # optional - sage.rings.finite_rings + sage: f2 = R.hom([a + a^2 + a + 1, b + b^2 + b + 1]) # optional - sage.rings.finite_rings + sage: MR = MatrixSpace(R, 2) # optional - sage.rings.finite_rings sage.modules + sage: MQ = MatrixSpace(Q, 2) # optional - sage.rings.finite_rings sage.modules + sage: f1M = MR.hom(f1, MQ) # optional - sage.rings.finite_rings sage.modules + sage: f2M = MR.hom(f2, MQ) # optional - sage.rings.finite_rings sage.modules + sage: f1M == f2M # optional - sage.rings.finite_rings sage.modules True TESTS:: - sage: f1M == loads(dumps(f1M)) + sage: f1M == loads(dumps(f1M)) # optional - sage.rings.finite_rings sage.modules True """ if not isinstance(other, RingHomomorphism_from_base): @@ -2314,11 +2355,12 @@ cdef class RingHomomorphism_from_base(RingHomomorphism): over a multivariate polynomial ring:: sage: R1. = ZZ[] - sage: f = R1.hom([x+y,x-y]) - sage: R2 = MatrixSpace(FractionField(R1)['t'],2) - sage: g = R2.hom(f,R2) - sage: g #indirect doctest - Ring endomorphism of Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in t over Fraction Field of Multivariate Polynomial Ring in x, y over Integer Ring + sage: f = R1.hom([x + y, x - y]) + sage: R2 = MatrixSpace(FractionField(R1)['t'], 2) # optional - sage.modules + sage: g = R2.hom(f, R2) # optional - sage.modules + sage: g #indirect doctest # optional - sage.modules + Ring endomorphism of Full MatrixSpace of 2 by 2 dense matrices + over Univariate Polynomial Ring in t over Fraction Field of Multivariate Polynomial Ring in x, y over Integer Ring Defn: Induced from base ring by Ring endomorphism of Univariate Polynomial Ring in t over Fraction Field of Multivariate Polynomial Ring in x, y over Integer Ring Defn: Induced from base ring by @@ -2364,11 +2406,11 @@ cdef class RingHomomorphism_from_base(RingHomomorphism): sage: R. = QQ[] sage: S. = QQ[] - sage: f = R.hom([a+b, a-b], S) + sage: f = R.hom([a + b, a - b], S) # optional - sage.libs.singular sage: PR. = R[] sage: PS = S['t'] - sage: Pf = PR.hom(f, PS) - sage: Pf.inverse() + sage: Pf = PR.hom(f, PS) # optional - sage.libs.singular + sage: Pf.inverse() # optional - sage.libs.singular Ring morphism: From: Univariate Polynomial Ring in t over Multivariate Polynomial Ring in a, b over Rational Field @@ -2380,7 +2422,7 @@ cdef class RingHomomorphism_from_base(RingHomomorphism): To: Multivariate Polynomial Ring in x, y over Rational Field Defn: a |--> 1/2*x + 1/2*y b |--> 1/2*x - 1/2*y - sage: Pf.inverse()(Pf(x*t^2 + y*t)) + sage: Pf.inverse()(Pf(x*t^2 + y*t)) # optional - sage.libs.singular x*t^2 + y*t """ return self.parent().reversed()(self._underlying.inverse()) @@ -2394,8 +2436,8 @@ cdef class RingHomomorphism_from_fraction_field(RingHomomorphism): sage: S. = QQ[] sage: f = S.hom([x^2]) - sage: g = f.extend_to_fraction_field() - sage: type(g) + sage: g = f.extend_to_fraction_field() # optional - sage.libs.singular + sage: type(g) # optional - sage.libs.singular """ def __init__(self, parent, morphism): @@ -2404,10 +2446,11 @@ cdef class RingHomomorphism_from_fraction_field(RingHomomorphism): TESTS:: - sage: A. = ZZ.extension(x^2 - 2) - sage: f = A.coerce_map_from(ZZ) - sage: g = f.extend_to_fraction_field() # indirect doctest - sage: g + sage: x = polygen(ZZ, 'x') + sage: A. = ZZ.extension(x^2 - 2) # optional - sage.rings.number_field + sage: f = A.coerce_map_from(ZZ) # optional - sage.rings.number_field + sage: g = f.extend_to_fraction_field() # indirect doctest # optional - sage.rings.number_field + sage: g # optional - sage.rings.number_field Ring morphism: From: Rational Field To: Number Field in a with defining polynomial x^2 - 2 @@ -2422,11 +2465,11 @@ cdef class RingHomomorphism_from_fraction_field(RingHomomorphism): EXAMPLES:: sage: S. = QQ[] - sage: f = S.hom([x^2]).extend_to_fraction_field() - sage: f + sage: f = S.hom([x^2]).extend_to_fraction_field() # optional - sage.libs.singular + sage: f # optional - sage.libs.singular Ring endomorphism of Fraction Field of Univariate Polynomial Ring in x over Rational Field Defn: x |--> x^2 - sage: f._repr_defn() + sage: f._repr_defn() # optional - sage.libs.singular 'x |--> x^2' """ return self._morphism._repr_defn() @@ -2442,10 +2485,10 @@ cdef class RingHomomorphism_from_fraction_field(RingHomomorphism): EXAMPLES:: sage: S. = QQ[] - sage: f = S.hom([x+1]).extend_to_fraction_field() - sage: f(1/x) + sage: f = S.hom([x + 1]).extend_to_fraction_field() # optional - sage.libs.singular + sage: f(1/x) # optional - sage.libs.singular 1/(x + 1) - sage: f(1/(x-1)) + sage: f(1/(x-1)) # optional - sage.libs.singular 1/x """ return self._morphism(x.numerator()) / self._morphism(x.denominator()) @@ -2457,12 +2500,12 @@ cdef class RingHomomorphism_from_fraction_field(RingHomomorphism): TESTS:: sage: S. = QQ[] - sage: f = S.hom([x+1]).extend_to_fraction_field() + sage: f = S.hom([x + 1]).extend_to_fraction_field() # optional - sage.libs.singular - sage: g = copy(f) # indirect doctest - sage: f == g + sage: g = copy(f) # indirect doctest # optional - sage.libs.singular + sage: f == g # optional - sage.libs.singular True - sage: f is g + sage: f is g # optional - sage.libs.singular False """ self._morphism = _slots['_morphism'] @@ -2475,8 +2518,8 @@ cdef class RingHomomorphism_from_fraction_field(RingHomomorphism): TESTS:: sage: S. = QQ[] - sage: f = S.hom([x+1]).extend_to_fraction_field() - sage: loads(dumps(f)) == f + sage: f = S.hom([x + 1]).extend_to_fraction_field() # optional - sage.libs.singular + sage: loads(dumps(f)) == f # optional - sage.libs.singular True """ slots = RingHomomorphism._extra_slots(self) @@ -2492,10 +2535,10 @@ cdef class RingHomomorphism_from_fraction_field(RingHomomorphism): sage: S. = QQ[] sage: f = S.hom([2*x - 1]) - sage: g = f.extend_to_fraction_field() - sage: g.inverse() + sage: g = f.extend_to_fraction_field() # optional - sage.libs.singular + sage: g.inverse() # optional - sage.libs.singular Ring endomorphism of Fraction Field of Univariate Polynomial Ring - in x over Rational Field + in x over Rational Field Defn: x |--> 1/2*x + 1/2 """ return self.parent().reversed()(self._morphism.inverse()) @@ -2508,13 +2551,14 @@ cdef class RingHomomorphism_cover(RingHomomorphism): EXAMPLES:: sage: R. = PolynomialRing(QQ, 2) - sage: S. = R.quo(x^2 + y^2) - sage: phi = S.cover(); phi + sage: S. = R.quo(x^2 + y^2) # optional - sage.libs.singular + sage: phi = S.cover(); phi # optional - sage.libs.singular Ring morphism: From: Multivariate Polynomial Ring in x, y over Rational Field - To: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) + To: Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x^2 + y^2) Defn: Natural quotient map - sage: phi(x+y) + sage: phi(x + y) # optional - sage.libs.singular a + b """ def __init__(self, parent): @@ -2561,7 +2605,8 @@ cdef class RingHomomorphism_cover(RingHomomorphism): sage: f(1/2) Traceback (most recent call last): ... - TypeError: 1/2 fails to convert into the map's domain Integer Ring, but a `pushforward` method is not properly implemented + TypeError: 1/2 fails to convert into the map's domain Integer Ring, + but a `pushforward` method is not properly implemented """ return self.codomain()(x) @@ -2599,11 +2644,11 @@ cdef class RingHomomorphism_cover(RingHomomorphism): EXAMPLES:: sage: R. = PolynomialRing(QQ, 2) - sage: S. = R.quo(x^2 + y^2) - sage: phi = S.cover() - sage: phi == loads(dumps(phi)) + sage: S. = R.quo(x^2 + y^2) # optional - sage.libs.singular + sage: phi = S.cover() # optional - sage.libs.singular + sage: phi == loads(dumps(phi)) # optional - sage.libs.singular True - sage: phi == R.quo(x^2 + y^3).cover() + sage: phi == R.quo(x^2 + y^3).cover() # optional - sage.libs.singular False """ if not isinstance(other, RingHomomorphism_cover): @@ -2619,13 +2664,13 @@ cdef class RingHomomorphism_cover(RingHomomorphism): TESTS:: sage: R. = PolynomialRing(QQ, 2) - sage: S. = R.quo(x^2 + y^2) - sage: phi = S.cover() - sage: type(phi) + sage: S. = R.quo(x^2 + y^2) # optional - sage.libs.singular + sage: phi = S.cover() # optional - sage.libs.singular + sage: type(phi) # optional - sage.libs.singular - sage: hash(phi) == hash(phi) + sage: hash(phi) == hash(phi) # optional - sage.libs.singular True - sage: {phi: 1}[phi] + sage: {phi: 1}[phi] # optional - sage.libs.singular 1 """ return hash((self.domain(), self.codomain())) @@ -2640,12 +2685,12 @@ cdef class RingHomomorphism_cover(RingHomomorphism): EXAMPLES:: - sage: R. = QQ['x,y'].quotient('x^2 * y^2') - sage: R.cover().inverse_image(R.ideal(x^3, y^3 + 1)) + sage: R. = QQ['x,y'].quotient('x^2 * y^2') # optional - sage.libs.singular + sage: R.cover().inverse_image(R.ideal(x^3, y^3 + 1)) # optional - sage.libs.singular Ideal (x^2*y^2, x^3, y^3 + 1) of Multivariate Polynomial Ring in x, y over Rational Field - sage: S. = QQbar['u,v'].quotient('u^4 - 1') - sage: S.cover().inverse_image(S.ideal(u^2 - 1)) + sage: S. = QQbar['u,v'].quotient('u^4 - 1') # optional - sage.libs.singular + sage: S.cover().inverse_image(S.ideal(u^2 - 1)) # optional - sage.libs.singular Ideal (u^4 - 1, u^2 - 1) of Multivariate Polynomial Ring in u, v over Algebraic Field """ @@ -2660,8 +2705,8 @@ cdef class RingHomomorphism_cover(RingHomomorphism): EXAMPLES:: - sage: Q. = QQ['x,y'].quotient('x + y') - sage: Q.cover().inverse_image(u) + sage: Q. = QQ['x,y'].quotient('x + y') # optional - sage.libs.singular + sage: Q.cover().inverse_image(u) # optional - sage.libs.singular -y """ return b.lift() @@ -2690,25 +2735,27 @@ cdef class RingHomomorphism_from_quotient(RingHomomorphism): EXAMPLES:: sage: R. = PolynomialRing(QQ, 3) - sage: S. = R.quo(x^3 + y^3 + z^3) - sage: phi = S.hom([b, c, a]); phi - Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by the ideal (x^3 + y^3 + z^3) + sage: S. = R.quo(x^3 + y^3 + z^3) # optional - sage.libs.singular + sage: phi = S.hom([b, c, a]); phi # optional - sage.libs.singular + Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y, z + over Rational Field by the ideal (x^3 + y^3 + z^3) Defn: a |--> b b |--> c c |--> a - sage: phi(a+b+c) + sage: phi(a + b + c) # optional - sage.libs.singular a + b + c - sage: loads(dumps(phi)) == phi + sage: loads(dumps(phi)) == phi # optional - sage.libs.singular True Validity of the homomorphism is determined, when possible, and a ``TypeError`` is raised if there is no homomorphism sending the generators to the given images:: - sage: S.hom([b^2, c^2, a^2]) + sage: S.hom([b^2, c^2, a^2]) # optional - sage.libs.singular Traceback (most recent call last): ... - ValueError: relations do not all (canonically) map to 0 under map determined by images of generators + ValueError: relations do not all (canonically) map to 0 + under map determined by images of generators """ def __init__(self, parent, phi): """ @@ -2716,8 +2763,9 @@ cdef class RingHomomorphism_from_quotient(RingHomomorphism): EXAMPLES:: - sage: R. = QQ[]; S. = R.quo([x^2,y^2]); S.hom([yy,xx]) - Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2, y^2) + sage: R. = QQ[]; S. = R.quo([x^2,y^2]); S.hom([yy,xx]) # optional - sage.libs.singular + Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y + over Rational Field by the ideal (x^2, y^2) Defn: xx |--> yy yy |--> xx """ @@ -2743,20 +2791,21 @@ cdef class RingHomomorphism_from_quotient(RingHomomorphism): EXAMPLES:: sage: R. = PolynomialRing(QQ, 3) - sage: S. = R.quo(x^3 + y^3 + z^3) - sage: phi = S.hom([b, c, a]); phi - Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by the ideal (x^3 + y^3 + z^3) + sage: S. = R.quo(x^3 + y^3 + z^3) # optional - sage.libs.singular + sage: phi = S.hom([b, c, a]); phi # optional - sage.libs.singular + Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y, z + over Rational Field by the ideal (x^3 + y^3 + z^3) Defn: a |--> b b |--> c c |--> a - sage: phi(a+b+c) + sage: phi(a + b + c) # optional - sage.libs.singular a + b + c - sage: psi = copy(phi) # indirect doctest - sage: psi == phi + sage: psi = copy(phi) # indirect doctest # optional - sage.libs.singular + sage: psi == phi # optional - sage.libs.singular True - sage: psi is phi + sage: psi is phi # optional - sage.libs.singular False - sage: psi(a) == phi(a) + sage: psi(a) == phi(a) # optional - sage.libs.singular True """ @@ -2770,20 +2819,21 @@ cdef class RingHomomorphism_from_quotient(RingHomomorphism): EXAMPLES:: sage: R. = PolynomialRing(QQ, 3) - sage: S. = R.quo(x^3 + y^3 + z^3) - sage: phi = S.hom([b, c, a]); phi - Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by the ideal (x^3 + y^3 + z^3) + sage: S. = R.quo(x^3 + y^3 + z^3) # optional - sage.libs.singular + sage: phi = S.hom([b, c, a]); phi # optional - sage.libs.singular + Ring endomorphism of Quotient of Multivariate Polynomial Ring in x, y, z + over Rational Field by the ideal (x^3 + y^3 + z^3) Defn: a |--> b b |--> c c |--> a - sage: phi(a+b+c) + sage: phi(a + b + c) # optional - sage.libs.singular a + b + c - sage: psi = copy(phi) # indirect doctest - sage: psi == phi + sage: psi = copy(phi) # indirect doctest # optional - sage.libs.singular + sage: psi == phi # optional - sage.libs.singular True - sage: psi is phi + sage: psi is phi # optional - sage.libs.singular False - sage: psi(a) == phi(a) + sage: psi(a) == phi(a) # optional - sage.libs.singular True """ slots = RingHomomorphism._extra_slots(self) @@ -2797,8 +2847,8 @@ cdef class RingHomomorphism_from_quotient(RingHomomorphism): EXAMPLES:: - sage: R. = QQ[]; S. = R.quo([x^2,y^2]); f = S.hom([yy,xx]) - sage: f._phi() + sage: R. = QQ[]; S. = R.quo([x^2, y^2]); f = S.hom([yy,xx]) # optional - sage.libs.singular + sage: f._phi() # optional - sage.libs.singular Ring morphism: From: Multivariate Polynomial Ring in x, y over Rational Field To: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2, y^2) @@ -2814,11 +2864,12 @@ cdef class RingHomomorphism_from_quotient(RingHomomorphism): EXAMPLES:: - sage: R. = QQ[]; S. = R.quo([x^2,y^2]) - sage: S.hom([yy,xx]).morphism_from_cover() + sage: R. = QQ[]; S. = R.quo([x^2, y^2]) # optional - sage.libs.singular + sage: S.hom([yy,xx]).morphism_from_cover() # optional - sage.libs.singular Ring morphism: From: Multivariate Polynomial Ring in x, y over Rational Field - To: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2, y^2) + To: Quotient of Multivariate Polynomial Ring in x, y + over Rational Field by the ideal (x^2, y^2) Defn: x |--> yy y |--> xx """ @@ -2830,14 +2881,14 @@ cdef class RingHomomorphism_from_quotient(RingHomomorphism): EXAMPLES:: - sage: R. = PolynomialRing(GF(19), 3) - sage: S. = R.quo(x^3 + y^3 + z^3) - sage: phi = S.hom([b, c, a]) - sage: psi = S.hom([c, b, a]) - sage: f = S.hom([b, c, a + a^3 + b^3 + c^3]) - sage: phi == psi + sage: R. = PolynomialRing(GF(19), 3) # optional - sage.rings.finite_rings + sage: S. = R.quo(x^3 + y^3 + z^3) # optional - sage.rings.finite_rings + sage: phi = S.hom([b, c, a]) # optional - sage.rings.finite_rings + sage: psi = S.hom([c, b, a]) # optional - sage.rings.finite_rings + sage: f = S.hom([b, c, a + a^3 + b^3 + c^3]) # optional - sage.rings.finite_rings + sage: phi == psi # optional - sage.rings.finite_rings False - sage: phi == f + sage: phi == f # optional - sage.rings.finite_rings True """ if not isinstance(other, RingHomomorphism_from_quotient): @@ -2854,14 +2905,14 @@ cdef class RingHomomorphism_from_quotient(RingHomomorphism): EXAMPLES:: - sage: R. = PolynomialRing(GF(19), 3) - sage: S. = R.quo(x^3 + y^3 + z^3) - sage: phi = S.hom([b, c, a]) - sage: type(phi) + sage: R. = PolynomialRing(GF(19), 3) # optional - sage.rings.finite_rings + sage: S. = R.quo(x^3 + y^3 + z^3) # optional - sage.rings.finite_rings + sage: phi = S.hom([b, c, a]) # optional - sage.rings.finite_rings + sage: type(phi) # optional - sage.rings.finite_rings - sage: hash(phi) == hash(phi) + sage: hash(phi) == hash(phi) # optional - sage.rings.finite_rings True - sage: {phi: 1}[phi] + sage: {phi: 1}[phi] # optional - sage.rings.finite_rings 1 """ return hash(self.phi) @@ -2872,9 +2923,9 @@ cdef class RingHomomorphism_from_quotient(RingHomomorphism): EXAMPLES:: - sage: R. = QQ[]; S. = R.quo([x^2,y^2]) - sage: f = S.hom([yy,xx]) - sage: print(f._repr_defn()) + sage: R. = QQ[]; S. = R.quo([x^2,y^2]) # optional - sage.libs.singular + sage: f = S.hom([yy, xx]) # optional - sage.libs.singular + sage: print(f._repr_defn()) # optional - sage.libs.singular xx |--> yy yy |--> xx """ @@ -2889,8 +2940,8 @@ cdef class RingHomomorphism_from_quotient(RingHomomorphism): EXAMPLES:: - sage: R. = QQ[]; S. = R.quo([x^2,y^2]); f = S.hom([yy,xx]) - sage: f(3*x + (1/2)*y) # indirect doctest + sage: R. = QQ[]; S. = R.quo([x^2, y^2]); f = S.hom([yy, xx]) # optional - sage.libs.singular + sage: f(3*x + (1/2)*y) # indirect doctest # optional - sage.libs.singular 1/2*xx + 3*yy """ return self.phi(self.lift(x)) @@ -2917,11 +2968,13 @@ cdef class FrobeniusEndomorphism_generic(RingHomomorphism): TESTS:: sage: from sage.rings.morphism import FrobeniusEndomorphism_generic - sage: K. = PowerSeriesRing(GF(5)) - sage: FrobeniusEndomorphism_generic(K) - Frobenius endomorphism x |--> x^5 of Power Series Ring in u over Finite Field of size 5 - sage: FrobeniusEndomorphism_generic(K, 2) - Frobenius endomorphism x |--> x^(5^2) of Power Series Ring in u over Finite Field of size 5 + sage: K. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: FrobeniusEndomorphism_generic(K) # optional - sage.rings.finite_rings + Frobenius endomorphism x |--> x^5 of Power Series Ring in u + over Finite Field of size 5 + sage: FrobeniusEndomorphism_generic(K, 2) # optional - sage.rings.finite_rings + Frobenius endomorphism x |--> x^(5^2) of Power Series Ring in u + over Finite Field of size 5 """ from .ring import CommutativeRing from sage.categories.homset import Hom @@ -2948,10 +3001,10 @@ cdef class FrobeniusEndomorphism_generic(RingHomomorphism): EXAMPLES:: - sage: K = Frac(GF(5)['T']) - sage: phi = K.frobenius_endomorphism() - sage: psi = copy(phi) - sage: phi == psi + sage: K = Frac(GF(5)['T']) # optional - sage.rings.finite_rings + sage: phi = K.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: psi = copy(phi) # optional - sage.rings.finite_rings + sage: phi == psi # optional - sage.rings.finite_rings True """ self._p = _slots['_domain'].characteristic() @@ -2968,14 +3021,16 @@ cdef class FrobeniusEndomorphism_generic(RingHomomorphism): EXAMPLES:: - sage: K = Frac(GF(25)['T']) - sage: phi = K.frobenius_endomorphism(2) - sage: phi - Frobenius endomorphism x |--> x^(5^2) of Fraction Field of Univariate Polynomial Ring in T over Finite Field in z2 of size 5^2 + sage: K = Frac(GF(25)['T']) # optional - sage.rings.finite_rings + sage: phi = K.frobenius_endomorphism(2) # optional - sage.rings.finite_rings + sage: phi # optional - sage.rings.finite_rings + Frobenius endomorphism x |--> x^(5^2) of Fraction Field of + Univariate Polynomial Ring in T over Finite Field in z2 of size 5^2 - sage: psi = loads(dumps(phi)); psi - Frobenius endomorphism x |--> x^(5^2) of Fraction Field of Univariate Polynomial Ring in T over Finite Field in z2 of size 5^2 - sage: phi == psi + sage: psi = loads(dumps(phi)); psi # optional - sage.rings.finite_rings + Frobenius endomorphism x |--> x^(5^2) of Fraction Field of + Univariate Polynomial Ring in T over Finite Field in z2 of size 5^2 + sage: phi == psi # optional - sage.rings.finite_rings True """ slots = RingHomomorphism._extra_slots(self) @@ -2988,12 +3043,14 @@ cdef class FrobeniusEndomorphism_generic(RingHomomorphism): EXAMPLES:: - sage: K. = PowerSeriesRing(GF(5)) - sage: Frob = K.frobenius_endomorphism(); Frob - Frobenius endomorphism x |--> x^5 of Power Series Ring in u over Finite Field of size 5 + sage: K. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: Frob = K.frobenius_endomorphism(); Frob # optional - sage.rings.finite_rings + Frobenius endomorphism x |--> x^5 of Power Series Ring in u + over Finite Field of size 5 - sage: Frob._repr_() - 'Frobenius endomorphism x |--> x^5 of Power Series Ring in u over Finite Field of size 5' + sage: Frob._repr_() # optional - sage.rings.finite_rings + 'Frobenius endomorphism x |--> x^5 of Power Series Ring in u + over Finite Field of size 5' """ if self._power == 0: s = "Identity endomorphism" @@ -3010,11 +3067,11 @@ cdef class FrobeniusEndomorphism_generic(RingHomomorphism): EXAMPLES:: - sage: K. = PowerSeriesRing(GF(5)) - sage: Frob = K.frobenius_endomorphism() - sage: Frob._repr_short() + sage: K. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: Frob = K.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: Frob._repr_short() # optional - sage.rings.finite_rings 'Frob' - sage: (Frob^2)._repr_short() + sage: (Frob^2)._repr_short() # optional - sage.rings.finite_rings 'Frob^2' """ if self._power == 0: @@ -3031,9 +3088,9 @@ cdef class FrobeniusEndomorphism_generic(RingHomomorphism): EXAMPLES:: - sage: K. = PowerSeriesRing(GF(5)) - sage: Frob = K.frobenius_endomorphism(2) - sage: Frob._latex_() + sage: K. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: Frob = K.frobenius_endomorphism(2) # optional - sage.rings.finite_rings + sage: Frob._latex_() # optional - sage.rings.finite_rings '\\verb"Frob"^{2}' """ if self._power == 0: @@ -3048,11 +3105,11 @@ cdef class FrobeniusEndomorphism_generic(RingHomomorphism): """ TESTS:: - sage: K. = PowerSeriesRing(GF(5)) - sage: Frob = K.frobenius_endomorphism() - sage: Frob(u) + sage: K. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: Frob = K.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: Frob(u) # optional - sage.rings.finite_rings u^5 - sage: (Frob^2)(1+u) + sage: (Frob^2)(1 + u) # optional - sage.rings.finite_rings 1 + u^25 """ return x ** self._q @@ -3065,11 +3122,11 @@ cdef class FrobeniusEndomorphism_generic(RingHomomorphism): EXAMPLES:: - sage: K. = PowerSeriesRing(GF(5)) - sage: Frob = K.frobenius_endomorphism() - sage: Frob.power() + sage: K. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: Frob = K.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: Frob.power() # optional - sage.rings.finite_rings 1 - sage: (Frob^9).power() + sage: (Frob^9).power() # optional - sage.rings.finite_rings 9 """ return self._power @@ -3080,11 +3137,13 @@ cdef class FrobeniusEndomorphism_generic(RingHomomorphism): EXAMPLES:: - sage: K. = PowerSeriesRing(GF(5)) - sage: Frob = K.frobenius_endomorphism(); Frob - Frobenius endomorphism x |--> x^5 of Power Series Ring in u over Finite Field of size 5 - sage: Frob^2 - Frobenius endomorphism x |--> x^(5^2) of Power Series Ring in u over Finite Field of size 5 + sage: K. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: Frob = K.frobenius_endomorphism(); Frob # optional - sage.rings.finite_rings + Frobenius endomorphism x |--> x^5 of Power Series Ring in u + over Finite Field of size 5 + sage: Frob^2 # optional - sage.rings.finite_rings + Frobenius endomorphism x |--> x^(5^2) of Power Series Ring in u + over Finite Field of size 5 """ return self.__class__(self.domain(), self.power()*n) @@ -3094,13 +3153,16 @@ cdef class FrobeniusEndomorphism_generic(RingHomomorphism): EXAMPLES:: - sage: K. = PowerSeriesRing(GF(5)) - sage: f = K.frobenius_endomorphism(); f - Frobenius endomorphism x |--> x^5 of Power Series Ring in u over Finite Field of size 5 - sage: g = K.frobenius_endomorphism(2); g - Frobenius endomorphism x |--> x^(5^2) of Power Series Ring in u over Finite Field of size 5 - sage: f * g - Frobenius endomorphism x |--> x^(5^3) of Power Series Ring in u over Finite Field of size 5 + sage: K. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: f = K.frobenius_endomorphism(); f # optional - sage.rings.finite_rings + Frobenius endomorphism x |--> x^5 of Power Series Ring in u + over Finite Field of size 5 + sage: g = K.frobenius_endomorphism(2); g # optional - sage.rings.finite_rings + Frobenius endomorphism x |--> x^(5^2) of Power Series Ring in u + over Finite Field of size 5 + sage: f * g # optional - sage.rings.finite_rings + Frobenius endomorphism x |--> x^(5^3) of Power Series Ring in u + over Finite Field of size 5 """ if isinstance(right, FrobeniusEndomorphism_generic): return self.__class__(self.domain(), self._power + right.power()) @@ -3140,15 +3202,15 @@ def _tensor_product_ring(B, A): sage: from sage.rings.morphism import _tensor_product_ring sage: R. = QQ[] - sage: S. = R.quotient(x^2 + y^2) - sage: Q = _tensor_product_ring(S, R); Q + sage: S. = R.quotient(x^2 + y^2) # optional - sage.libs.singular + sage: Q = _tensor_product_ring(S, R); Q # optional - sage.libs.singular Quotient of Multivariate Polynomial Ring in u, v, x, y over Rational Field by the ideal (u^2 + v^2) - sage: Q.term_order() + sage: Q.term_order() # optional - sage.libs.singular Block term order with blocks: (Degree reverse lexicographic term order of length 2, Degree reverse lexicographic term order of length 2) - sage: _tensor_product_ring(R, R) + sage: _tensor_product_ring(R, R) # optional - sage.libs.singular Multivariate Polynomial Ring in y0, y1, x0, x1 over Rational Field TESTS: diff --git a/src/sage/rings/multi_power_series_ring.py b/src/sage/rings/multi_power_series_ring.py index 3ed94af4f02..20e3cba3977 100644 --- a/src/sage/rings/multi_power_series_ring.py +++ b/src/sage/rings/multi_power_series_ring.py @@ -49,9 +49,9 @@ True sage: TestSuite(M).run() - sage: H = PowerSeriesRing(PolynomialRing(ZZ,3,'z'),4,'f'); H - Multivariate Power Series Ring in f0, f1, f2, f3 over Multivariate - Polynomial Ring in z0, z1, z2 over Integer Ring + sage: H = PowerSeriesRing(PolynomialRing(ZZ, 3, 'z'), 4, 'f'); H + Multivariate Power Series Ring in f0, f1, f2, f3 + over Multivariate Polynomial Ring in z0, z1, z2 over Integer Ring sage: TestSuite(H).run() sage: loads(dumps(H)) is H True @@ -75,21 +75,21 @@ - Use angle-bracket notation:: - sage: S. = PowerSeriesRing(GF(65537)); S + sage: S. = PowerSeriesRing(GF(65537)); S # optional - sage.rings.finite_rings Multivariate Power Series Ring in x, y over Finite Field of size 65537 - sage: s = -30077*x + 9485*x*y - 6260*y^3 + 12870*x^2*y^2 - 20289*y^4 + S.O(5); s + sage: s = -30077*x + 9485*x*y - 6260*y^3 + 12870*x^2*y^2 - 20289*y^4 + S.O(5); s # optional - sage.rings.finite_rings -30077*x + 9485*x*y - 6260*y^3 + 12870*x^2*y^2 - 20289*y^4 + O(x, y)^5 - sage: s in S + sage: s in S # optional - sage.rings.finite_rings True - sage: TestSuite(S).run() - sage: loads(dumps(S)) is S + sage: TestSuite(S).run() # optional - sage.rings.finite_rings + sage: loads(dumps(S)) is S # optional - sage.rings.finite_rings True - Use double square bracket notation:: sage: ZZ[['s,t,u']] Multivariate Power Series Ring in s, t, u over Integer Ring - sage: GF(127931)[['x,y']] + sage: GF(127931)[['x,y']] # optional - sage.rings.finite_rings Multivariate Power Series Ring in x, y over Finite Field of size 127931 Variable ordering determines how series are displayed. @@ -118,15 +118,15 @@ sage: R. = PowerSeriesRing(QQ); R Multivariate Power Series Ring in t, u, v over Rational Field sage: R.base_extend(RR) - Multivariate Power Series Ring in t, u, v over Real Field with 53 - bits of precision + Multivariate Power Series Ring in t, u, v + over Real Field with 53 bits of precision sage: R.change_ring(IntegerModRing(10)) - Multivariate Power Series Ring in t, u, v over Ring of integers - modulo 10 + Multivariate Power Series Ring in t, u, v + over Ring of integers modulo 10 - sage: S = PowerSeriesRing(GF(65537),2,'x,y'); S + sage: S = PowerSeriesRing(GF(65537),2,'x,y'); S # optional - sage.rings.finite_rings Multivariate Power Series Ring in x, y over Finite Field of size 65537 - sage: S.change_ring(GF(5)) + sage: S.change_ring(GF(5)) # optional - sage.rings.finite_rings Multivariate Power Series Ring in x, y over Finite Field of size 5 Coercion from polynomial ring:: @@ -159,19 +159,19 @@ Coercion from symbolic ring:: - sage: x,y = var('x,y') - sage: S = PowerSeriesRing(GF(11),2,'x,y'); S + sage: x,y = var('x,y') # optional - sage.symbolic + sage: S = PowerSeriesRing(GF(11),2,'x,y'); S # optional - sage.rings.finite_rings Multivariate Power Series Ring in x, y over Finite Field of size 11 - sage: type(x) + sage: type(x) # optional - sage.symbolic - sage: type(S(x)) + sage: type(S(x)) # optional - sage.rings.finite_rings sage.symbolic - sage: f = S(2/7 -100*x^2 + 1/3*x*y + y^2).O(3); f + sage: f = S(2/7 -100*x^2 + 1/3*x*y + y^2).O(3); f # optional - sage.rings.finite_rings sage.symbolic 5 - x^2 + 4*x*y + y^2 + O(x, y)^3 - sage: f.parent() + sage: f.parent() # optional - sage.rings.finite_rings sage.symbolic Multivariate Power Series Ring in x, y over Finite Field of size 11 - sage: f.parent() == S + sage: f.parent() == S # optional - sage.rings.finite_rings sage.symbolic True The implementation of the multivariate power series ring uses a combination @@ -224,18 +224,18 @@ def is_MPowerSeriesRing(x): """ - Return true if input is a multivariate power series ring. + Return ``True`` if input is a multivariate power series ring. TESTS:: sage: from sage.rings.power_series_ring import is_PowerSeriesRing sage: from sage.rings.multi_power_series_ring import is_MPowerSeriesRing - sage: M = PowerSeriesRing(ZZ,4,'v') + sage: M = PowerSeriesRing(ZZ, 4, 'v') sage: is_PowerSeriesRing(M) False sage: is_MPowerSeriesRing(M) True - sage: T = PowerSeriesRing(RR,'v') + sage: T = PowerSeriesRing(RR, 'v') sage: is_PowerSeriesRing(T) True sage: is_MPowerSeriesRing(T) @@ -290,7 +290,7 @@ def __classcall__(cls, base_ring, num_gens, name_list, TESTS:: - sage: P1 = PowerSeriesRing(QQ, ['f0','f1','f2','f3'], order = TermOrder('degrevlex')) + sage: P1 = PowerSeriesRing(QQ, ['f0','f1','f2','f3'], order=TermOrder('degrevlex')) sage: P2 = PowerSeriesRing(QQ,4,'f', order='degrevlex') sage: P1 is P2 # indirect doctest True @@ -390,11 +390,11 @@ def _repr_(self): EXAMPLES:: - sage: R. = PowerSeriesRing(GF(17)) - sage: R #indirect doctest + sage: R. = PowerSeriesRing(GF(17)) # optional - sage.rings.finite_rings + sage: R #indirect doctest # optional - sage.rings.finite_rings Multivariate Power Series Ring in x, y over Finite Field of size 17 - sage: R.rename('my multivariate power series ring') - sage: R + sage: R.rename('my multivariate power series ring') # optional - sage.rings.finite_rings + sage: R # optional - sage.rings.finite_rings my multivariate power series ring """ if self.ngens() == 0: @@ -423,7 +423,7 @@ def _latex_(self): def is_integral_domain(self, proof=False): """ - Return True if the base ring is an integral domain; otherwise + Return ``True`` if the base ring is an integral domain; otherwise return False. EXAMPLES:: @@ -479,10 +479,10 @@ def characteristic(self): EXAMPLES:: - sage: H = PowerSeriesRing(GF(65537),4,'f'); H + sage: H = PowerSeriesRing(GF(65537),4,'f'); H # optional - sage.rings.finite_rings Multivariate Power Series Ring in f0, f1, f2, f3 over Finite Field of size 65537 - sage: H.characteristic() + sage: H.characteristic() # optional - sage.rings.finite_rings 65537 """ return self.base_ring().characteristic() @@ -493,12 +493,12 @@ def construction(self): EXAMPLES:: - sage: M = PowerSeriesRing(QQ,4,'f'); M + sage: M = PowerSeriesRing(QQ, 4, 'f'); M Multivariate Power Series Ring in f0, f1, f2, f3 over Rational Field sage: (c,R) = M.construction(); (c,R) (Completion[('f0', 'f1', 'f2', 'f3'), prec=12], - Multivariate Polynomial Ring in f0, f1, f2, f3 over Rational Field) + Multivariate Polynomial Ring in f0, f1, f2, f3 over Rational Field) sage: c Completion[('f0', 'f1', 'f2', 'f3'), prec=12] sage: c(R) @@ -555,10 +555,10 @@ def change_ring(self, R): TypeError: no base extension defined - sage: S = PowerSeriesRing(GF(65537),2,'x,y'); S + sage: S = PowerSeriesRing(GF(65537),2,'x,y'); S # optional - sage.rings.finite_rings Multivariate Power Series Ring in x, y over Finite Field of size 65537 - sage: S.change_ring(GF(5)) + sage: S.change_ring(GF(5)) # optional - sage.rings.finite_rings Multivariate Power Series Ring in x, y over Finite Field of size 5 """ return PowerSeriesRing(R, names = self.variable_names(), default_prec = self.default_prec()) @@ -576,16 +576,16 @@ def remove_var(self, *var): Power Series Ring in u over Integer Ring - sage: M = PowerSeriesRing(GF(5),5,'t'); M - Multivariate Power Series Ring in t0, t1, t2, t3, t4 over - Finite Field of size 5 - sage: M.remove_var(M.gens()[3]) - Multivariate Power Series Ring in t0, t1, t2, t4 over Finite - Field of size 5 + sage: M = PowerSeriesRing(GF(5),5,'t'); M # optional - sage.rings.finite_rings + Multivariate Power Series Ring in t0, t1, t2, t3, t4 + over Finite Field of size 5 + sage: M.remove_var(M.gens()[3]) # optional - sage.rings.finite_rings + Multivariate Power Series Ring in t0, t1, t2, t4 + over Finite Field of size 5 Removing all variables results in the base ring:: - sage: M.remove_var(*M.gens()) + sage: M.remove_var(*M.gens()) # optional - sage.rings.finite_rings Finite Field of size 5 """ @@ -634,10 +634,10 @@ def _coerce_impl(self, f): sage: R(f2) -2*v^2 + 5*u*v^2 + O(t, u, v)^6 - sage: R2 = R.change_ring(GF(2)) - sage: R2(f1) + sage: R2 = R.change_ring(GF(2)) # optional - sage.rings.finite_rings + sage: R2(f1) # optional - sage.rings.finite_rings v + t*v - sage: R2(f2) + sage: R2(f2) # optional - sage.rings.finite_rings u*v^2 + O(t, u, v)^6 TESTS:: @@ -674,8 +674,8 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): EXAMPLES:: sage: R. = PowerSeriesRing(Zmod(8)); R - Multivariate Power Series Ring in a, b, c over Ring of integers - modulo 8 + Multivariate Power Series Ring in a, b, c + over Ring of integers modulo 8 sage: M = PowerSeriesRing(ZZ,3,'x,y,z') sage: M._is_valid_homomorphism_(R,[a,c,b]) True @@ -709,13 +709,13 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): from the base ring to the codomain:: sage: T. = ZZ[] - sage: K. = NumberField(t^2 + 1) - sage: Q8. = CyclotomicField(8) - sage: X. = PowerSeriesRing(Q8) - sage: M. = PowerSeriesRing(K) - sage: M._is_valid_homomorphism_(X, [x,x,x+x^2]) # no coercion + sage: K. = NumberField(t^2 + 1) # optional - sage.rings.number_field + sage: Q8. = CyclotomicField(8) # optional - sage.rings.number_field + sage: X. = PowerSeriesRing(Q8) # optional - sage.rings.number_field + sage: M. = PowerSeriesRing(K) # optional - sage.rings.number_field + sage: M._is_valid_homomorphism_(X, [x,x,x+x^2]) # no coercion # optional - sage.rings.number_field False - sage: M._is_valid_homomorphism_(X, [x,x,x+x^2], base_map=K.hom([z^2])) + sage: M._is_valid_homomorphism_(X, [x,x,x+x^2], base_map=K.hom([z^2])) # optional - sage.rings.number_field True """ try: @@ -757,32 +757,32 @@ def _coerce_map_from_(self, P): EXAMPLES:: - sage: A = GF(17)[['x','y']] - sage: A.has_coerce_map_from(ZZ) + sage: A = GF(17)[['x','y']] # optional - sage.rings.finite_rings + sage: A.has_coerce_map_from(ZZ) # optional - sage.rings.finite_rings True - sage: A.has_coerce_map_from(ZZ['x']) + sage: A.has_coerce_map_from(ZZ['x']) # optional - sage.rings.finite_rings True - sage: A.has_coerce_map_from(ZZ['y','x']) + sage: A.has_coerce_map_from(ZZ['y','x']) # optional - sage.rings.finite_rings True - sage: A.has_coerce_map_from(ZZ[['x']]) + sage: A.has_coerce_map_from(ZZ[['x']]) # optional - sage.rings.finite_rings True - sage: A.has_coerce_map_from(ZZ[['y','x']]) + sage: A.has_coerce_map_from(ZZ[['y','x']]) # optional - sage.rings.finite_rings True - sage: A.has_coerce_map_from(ZZ['x','z']) + sage: A.has_coerce_map_from(ZZ['x','z']) # optional - sage.rings.finite_rings False - sage: A.has_coerce_map_from(GF(3)['x','y']) + sage: A.has_coerce_map_from(GF(3)['x','y']) # optional - sage.rings.finite_rings False - sage: A.has_coerce_map_from(Frac(ZZ['y','x'])) + sage: A.has_coerce_map_from(Frac(ZZ['y','x'])) # optional - sage.rings.finite_rings False TESTS:: - sage: M = PowerSeriesRing(ZZ,3,'x,y,z') + sage: M = PowerSeriesRing(ZZ, 3, 'x,y,z') sage: M._coerce_map_from_(M) True - sage: M._coerce_map_from_(M.remove_var(x)) + sage: M._coerce_map_from_(M.remove_var(x)) # optional - sage.symbolic True - sage: M._coerce_map_from_(PowerSeriesRing(ZZ,x)) + sage: M._coerce_map_from_(PowerSeriesRing(ZZ,x)) # optional - sage.symbolic True sage: M._coerce_map_from_(PolynomialRing(ZZ,'x,z')) True @@ -800,7 +800,8 @@ def _coerce_map_from_(self, P): sage: P = PolynomialRing(ZZ,3,'z') sage: H = PowerSeriesRing(P,4,'f'); H - Multivariate Power Series Ring in f0, f1, f2, f3 over Multivariate Polynomial Ring in z0, z1, z2 over Integer Ring + Multivariate Power Series Ring in f0, f1, f2, f3 over + Multivariate Polynomial Ring in z0, z1, z2 over Integer Ring sage: H._coerce_map_from_(P) True sage: H._coerce_map_from_(P.remove_var(P.gen(1))) @@ -919,11 +920,11 @@ def is_sparse(self): EXAMPLES:: - sage: M = PowerSeriesRing(ZZ,3,'s,t,u'); M + sage: M = PowerSeriesRing(ZZ, 3, 's,t,u'); M Multivariate Power Series Ring in s, t, u over Integer Ring sage: M.is_sparse() False - sage: N = PowerSeriesRing(ZZ,3,'s,t,u',sparse=True); N + sage: N = PowerSeriesRing(ZZ, 3, 's,t,u', sparse=True); N Sparse Multivariate Power Series Ring in s, t, u over Integer Ring sage: N.is_sparse() True @@ -936,11 +937,11 @@ def is_dense(self): EXAMPLES:: - sage: M = PowerSeriesRing(ZZ,3,'s,t,u'); M + sage: M = PowerSeriesRing(ZZ, 3, 's,t,u'); M Multivariate Power Series Ring in s, t, u over Integer Ring sage: M.is_dense() True - sage: N = PowerSeriesRing(ZZ,3,'s,t,u',sparse=True); N + sage: N = PowerSeriesRing(ZZ, 3, 's,t,u', sparse=True); N Sparse Multivariate Power Series Ring in s, t, u over Integer Ring sage: N.is_dense() False @@ -953,7 +954,7 @@ def gen(self, n=0): EXAMPLES:: - sage: M = PowerSeriesRing(ZZ,10,'v') + sage: M = PowerSeriesRing(ZZ, 10, 'v') sage: M.gen(6) v6 """ @@ -968,7 +969,7 @@ def ngens(self): EXAMPLES:: - sage: M = PowerSeriesRing(ZZ,10,'v') + sage: M = PowerSeriesRing(ZZ, 10, 'v') sage: M.ngens() 10 """ @@ -984,8 +985,8 @@ def prec_ideal(self): sage: A. = PowerSeriesRing(ZZ) sage: A.prec_ideal() - Ideal (s, t, u) of Multivariate Polynomial Ring in s, t, u over - Integer Ring + Ideal (s, t, u) of + Multivariate Polynomial Ring in s, t, u over Integer Ring """ return self._poly_ring().ideal(self._poly_ring().gens()) diff --git a/src/sage/rings/multi_power_series_ring_element.py b/src/sage/rings/multi_power_series_ring_element.py index 978de36ce2d..20e8158871e 100644 --- a/src/sage/rings/multi_power_series_ring_element.py +++ b/src/sage/rings/multi_power_series_ring_element.py @@ -29,7 +29,7 @@ sage: f*g - g 2*s^2*t^2 + O(s, t)^5 - sage: f*=s; f + sage: f *= s; f s + 2*s^2 + 3*s^3 + O(s, t)^8 sage: f%2 s + s^3 + O(s, t)^8 @@ -56,43 +56,43 @@ sage: f = s^2 + s*t + s^3 + s^2*t + 3*s^4 + 3*s^3*t + R.O(5); f s^2 + s*t + s^3 + s^2*t + 3*s^4 + 3*s^3*t + O(s, t)^5 - sage: f(t,s) + sage: f(t, s) s*t + t^2 + s*t^2 + t^3 + 3*s*t^3 + 3*t^4 + O(s, t)^5 - sage: f(t^2,s^2) + sage: f(t^2, s^2) s^2*t^2 + t^4 + s^2*t^4 + t^6 + 3*s^2*t^6 + 3*t^8 + O(s, t)^10 Substitution is defined only for elements of positive valuation, unless `f` has infinite precision:: - sage: f(t^2,s^2+1) + sage: f(t^2, s^2 + 1) Traceback (most recent call last): ... TypeError: Substitution defined only for elements of positive valuation, unless self has infinite precision. sage: g = f.truncate() - sage: g(t^2,s^2+1) + sage: g(t^2, s^2 + 1) t^2 + s^2*t^2 + 2*t^4 + s^2*t^4 + 4*t^6 + 3*s^2*t^6 + 3*t^8 - sage: g(t^2,(s^2+1).O(3)) + sage: g(t^2, (s^2+1).O(3)) t^2 + s^2*t^2 + 2*t^4 + O(s, t)^5 0 has valuation ``+Infinity``:: - sage: f(t^2,0) + sage: f(t^2, 0) t^4 + t^6 + 3*t^8 + O(s, t)^10 - sage: f(t^2,s^2+s) + sage: f(t^2, s^2 + s) s*t^2 + s^2*t^2 + t^4 + O(s, t)^5 Substitution of power series with finite precision works too:: - sage: f(s.O(2),t) + sage: f(s.O(2), t) s^2 + s*t + O(s, t)^3 - sage: f(f,f) + sage: f(f, f) 2*s^4 + 4*s^3*t + 2*s^2*t^2 + 4*s^5 + 8*s^4*t + 4*s^3*t^2 + 16*s^6 + 34*s^5*t + 20*s^4*t^2 + 2*s^3*t^3 + O(s, t)^7 - sage: t(f,f) + sage: t(f, f) s^2 + s*t + s^3 + s^2*t + 3*s^4 + 3*s^3*t + O(s, t)^5 - sage: t(0,f) == s(f,0) + sage: t(0, f) == s(f, 0) True The ``subs`` syntax works as expected:: @@ -100,10 +100,10 @@ sage: r0 = -t^2 - s*t^3 - 2*t^6 + s^7 + s^5*t^2 + R.O(10) sage: r1 = s^4 - s*t^4 + s^6*t - 4*s^2*t^5 - 6*s^3*t^5 + R.O(10) sage: r2 = 2*s^3*t^2 - 2*s*t^4 - 2*s^3*t^4 + s*t^7 + R.O(10) - sage: r0.subs({t:r2,s:r1}) + sage: r0.subs({t: r2, s: r1}) -4*s^6*t^4 + 8*s^4*t^6 - 4*s^2*t^8 + 8*s^6*t^6 - 8*s^4*t^8 - 4*s^4*t^9 + 4*s^2*t^11 - 4*s^6*t^8 + O(s, t)^15 - sage: r0.subs({t:r2,s:r1}) == r0(r1,r2) + sage: r0.subs({t: r2, s: r1}) == r0(r1, r2) True Construct ring homomorphisms from one power series ring to another:: @@ -253,19 +253,19 @@ class MPowerSeries(PowerSeries): 1 + s + t - s*t + O(s, t)^5 - sage: T = PowerSeriesRing(GF(3),5,'t'); T - Multivariate Power Series Ring in t0, t1, t2, t3, t4 over Finite - Field of size 3 - sage: t = T.gens() - sage: w = t[0] - 2*t[1]*t[3] + 5*t[4]^3 - t[0]^3*t[2]^2; w + sage: T = PowerSeriesRing(GF(3),5,'t'); T # optional - sage.rings.finite_rings + Multivariate Power Series Ring in t0, t1, t2, t3, t4 + over Finite Field of size 3 + sage: t = T.gens() # optional - sage.rings.finite_rings + sage: w = t[0] - 2*t[1]*t[3] + 5*t[4]^3 - t[0]^3*t[2]^2; w # optional - sage.rings.finite_rings t0 + t1*t3 - t4^3 - t0^3*t2^2 - sage: w = w.add_bigoh(5); w + sage: w = w.add_bigoh(5); w # optional - sage.rings.finite_rings t0 + t1*t3 - t4^3 + O(t0, t1, t2, t3, t4)^5 - sage: w in T + sage: w in T # optional - sage.rings.finite_rings True - sage: w = t[0] - 2*t[0]*t[2] + 5*t[4]^3 - t[0]^3*t[2]^2 + T.O(6) - sage: w + sage: w = t[0] - 2*t[0]*t[2] + 5*t[4]^3 - t[0]^3*t[2]^2 + T.O(6) # optional - sage.rings.finite_rings + sage: w # optional - sage.rings.finite_rings t0 + t0*t2 - t4^3 - t0^3*t2^2 + O(t0, t1, t2, t3, t4)^6 @@ -274,20 +274,20 @@ class MPowerSeries(PowerSeries): sage: S.random_element(4) # random -2*t + t^2 - 12*s^3 + O(s, t)^4 - sage: T.random_element(10) # random + sage: T.random_element(10) # random # optional - sage.rings.finite_rings -t1^2*t3^2*t4^2 + t1^5*t3^3*t4 + O(t0, t1, t2, t3, t4)^10 Convert elements from polynomial rings:: - sage: R = PolynomialRing(ZZ,5,T.variable_names()) - sage: t = R.gens() - sage: r = -t[2]*t[3] + t[3]^2 + t[4]^2 - sage: T(r) + sage: R = PolynomialRing(ZZ, 5, T.variable_names()) # optional - sage.libs.pari + sage: t = R.gens() # optional - sage.libs.pari + sage: r = -t[2]*t[3] + t[3]^2 + t[4]^2 # optional - sage.libs.pari + sage: T(r) # optional - sage.libs.pari -t2*t3 + t3^2 + t4^2 - sage: r.parent() + sage: r.parent() # optional - sage.libs.pari Multivariate Polynomial Ring in t0, t1, t2, t3, t4 over Integer Ring - sage: r in T + sage: r in T # optional - sage.libs.pari True """ @@ -313,10 +313,11 @@ def __init__(self, parent, x=0, prec=infinity, is_gen=False, check=False): sage: g.parent() Multivariate Power Series Ring in s, t over Rational Field - sage: K = NumberField(x-3,'a') - sage: g = K.random_element()*f - sage: g.parent() - Multivariate Power Series Ring in s, t over Number Field in a with defining polynomial x - 3 + sage: K = NumberField(x - 3,'a') # optional - sage.rings.number_field + sage: g = K.random_element()*f # optional - sage.rings.number_field + sage: g.parent() # optional - sage.rings.number_field + Multivariate Power Series Ring in s, t over + Number Field in a with defining polynomial x - 3 TESTS:: @@ -449,20 +450,20 @@ def __call__(self, *x, **kwds): Checking that :trac:`15059` is fixed:: - sage: M. = PowerSeriesRing(GF(5)) - sage: s = M.hom([u, u+v]) - sage: s(M.one()) + sage: M. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: s = M.hom([u, u+v]) # optional - sage.rings.finite_rings + sage: s(M.one()) # optional - sage.rings.finite_rings 1 Since :trac:`26105` you can specify a map on the base ring:: sage: Zx. = ZZ[] - sage: K. = NumberField(x^2 + 1) - sage: cc = K.hom([-i]) - sage: R. = PowerSeriesRing(K) - sage: f = s^2 + i*s*t + (3+4*i)*s^3 + R.O(4); f + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: cc = K.hom([-i]) # optional - sage.rings.number_field + sage: R. = PowerSeriesRing(K) # optional - sage.rings.number_field + sage: f = s^2 + i*s*t + (3+4*i)*s^3 + R.O(4); f # optional - sage.rings.number_field s^2 + i*s*t + (4*i + 3)*s^3 + O(s, t)^4 - sage: f(t, s, base_map=cc) + sage: f(t, s, base_map=cc) # optional - sage.rings.number_field (-i)*s*t + t^2 + (-4*i + 3)*t^3 + O(s, t)^4 """ if len(x) != self.parent().ngens(): @@ -565,14 +566,14 @@ def _value(self): EXAMPLES:: - sage: R. = PowerSeriesRing(GF(5)); R + sage: R. = PowerSeriesRing(GF(5)); R # optional - sage.rings.finite_rings Multivariate Power Series Ring in a, b, c over Finite Field of size 5 - sage: f = 1 + a + b - a*b + R.O(3); f + sage: f = 1 + a + b - a*b + R.O(3); f # optional - sage.rings.finite_rings 1 + a + b - a*b + O(a, b, c)^3 - sage: f._value() + sage: f._value() # optional - sage.rings.finite_rings 1 + a + b - a*b - sage: f._value().parent() + sage: f._value().parent() # optional - sage.rings.finite_rings Multivariate Polynomial Ring in a, b, c over Finite Field of size 5 """ return self._go_to_fg(self._bg_value) @@ -601,15 +602,15 @@ def _latex_(self): EXAMPLES:: - sage: M = PowerSeriesRing(GF(5),3,'t'); M + sage: M = PowerSeriesRing(GF(5),3,'t'); M # optional - sage.rings.finite_rings Multivariate Power Series Ring in t0, t1, t2 over Finite Field of size 5 - sage: t = M.gens() - sage: f = -t[0]^4*t[1]^3*t[2]^4 - 2*t[0]*t[1]^4*t[2]^7 \ - + 2*t[1]*t[2]^12 + 2*t[0]^7*t[1]^5*t[2]^2 + M.O(15) - sage: f + sage: t = M.gens() # optional - sage.rings.finite_rings + sage: f = (-t[0]^4*t[1]^3*t[2]^4 - 2*t[0]*t[1]^4*t[2]^7 # optional - sage.rings.finite_rings + ....: + 2*t[1]*t[2]^12 + 2*t[0]^7*t[1]^5*t[2]^2 + M.O(15)) + sage: f # optional - sage.rings.finite_rings -t0^4*t1^3*t2^4 - 2*t0*t1^4*t2^7 + 2*t1*t2^12 + 2*t0^7*t1^5*t2^2 + O(t0, t1, t2)^15 - sage: f._latex_() + sage: f._latex_() # optional - sage.rings.finite_rings '-t_{0}^{4} t_{1}^{3} t_{2}^{4} + 3 t_{0} t_{1}^{4} t_{2}^{7} + 2 t_{1} t_{2}^{12} + 2 t_{0}^{7} t_{1}^{5} t_{2}^{2} + O(t_{0}, t_{1}, t_{2})^{15}' @@ -707,30 +708,30 @@ def _richcmp_(self, other, op): EXAMPLES:: - sage: R. = PowerSeriesRing(GF(5)); R + sage: R. = PowerSeriesRing(GF(5)); R # optional - sage.rings.finite_rings Multivariate Power Series Ring in a, b, c over Finite Field of size 5 - sage: f = a + b + c + a^2*c - sage: f == f^2 + sage: f = a + b + c + a^2*c # optional - sage.rings.finite_rings + sage: f == f^2 # optional - sage.rings.finite_rings False - sage: f = f.truncate() - sage: f == f.O(4) + sage: f = f.truncate() # optional - sage.rings.finite_rings + sage: f == f.O(4) # optional - sage.rings.finite_rings True Ordering is determined by underlying polynomial ring:: - sage: a > b + sage: a > b # optional - sage.rings.finite_rings True - sage: a > a^2 + sage: a > a^2 # optional - sage.rings.finite_rings True - sage: b > a^2 + sage: b > a^2 # optional - sage.rings.finite_rings True - sage: (f^2).O(3) + sage: (f^2).O(3) # optional - sage.rings.finite_rings a^2 + 2*a*b + 2*a*c + b^2 + 2*b*c + c^2 + O(a, b, c)^3 - sage: f < f^2 + sage: f < f^2 # optional - sage.rings.finite_rings False - sage: f > f^2 + sage: f > f^2 # optional - sage.rings.finite_rings True - sage: f < 2*f + sage: f < 2*f # optional - sage.rings.finite_rings True """ return richcmp(self._bg_value, other._bg_value, op) @@ -892,24 +893,24 @@ def quo_rem(self, other, precision=None): sage: R. = PowerSeriesRing(ZZ) sage: f = 1 + a + b - a*b + R.O(3) sage: g = 1 + 2*a - 3*a*b + R.O(3) - sage: q, r = f.quo_rem(g); q, r + sage: q, r = f.quo_rem(g); q, r # optional - sage.libs.singular (1 - a + b + 2*a^2 + O(a, b, c)^3, 0 + O(a, b, c)^3) - sage: f == q*g+r + sage: f == q*g + r # optional - sage.libs.singular True - sage: q, r = (a*f).quo_rem(g); q, r + sage: q, r = (a*f).quo_rem(g); q, r # optional - sage.libs.singular (a - a^2 + a*b + 2*a^3 + O(a, b, c)^4, 0 + O(a, b, c)^4) - sage: a*f == q*g+r + sage: a*f == q*g + r # optional - sage.libs.singular True - sage: q, r = (a*f).quo_rem(a*g); q, r + sage: q, r = (a*f).quo_rem(a*g); q, r # optional - sage.libs.singular (1 - a + b + 2*a^2 + O(a, b, c)^3, 0 + O(a, b, c)^4) - sage: a*f == q*(a*g)+r + sage: a*f == q*(a*g) + r # optional - sage.libs.singular True - sage: q, r = (a*f).quo_rem(b*g); q, r + sage: q, r = (a*f).quo_rem(b*g); q, r # optional - sage.libs.singular (a - 3*a^2 + O(a, b, c)^3, a + a^2 + O(a, b, c)^4) - sage: a*f == q*(b*g)+r + sage: a*f == q*(b*g) + r # optional - sage.libs.singular True Trying to divide two polynomials, we run into the issue that @@ -918,59 +919,61 @@ def quo_rem(self, other, precision=None): algorithm would never terminate). Here, default precision comes to our help:: - sage: (1+a^3).quo_rem(a+a^2) - (a^2 - a^3 + a^4 - a^5 + a^6 - a^7 + a^8 - a^9 + a^10 + O(a, b, c)^11, 1 + O(a, b, c)^12) + sage: (1 + a^3).quo_rem(a + a^2) # optional - sage.libs.singular + (a^2 - a^3 + a^4 - a^5 + a^6 - a^7 + a^8 - a^9 + a^10 + O(a, b, c)^11, + 1 + O(a, b, c)^12) - sage: (1+a^3+a*b).quo_rem(b+c) + sage: (1 + a^3 + a*b).quo_rem(b + c) # optional - sage.libs.singular (a + O(a, b, c)^11, 1 - a*c + a^3 + O(a, b, c)^12) - sage: (1+a^3+a*b).quo_rem(b+c, precision=17) + sage: (1 + a^3 + a*b).quo_rem(b + c, precision=17) # optional - sage.libs.singular (a + O(a, b, c)^16, 1 - a*c + a^3 + O(a, b, c)^17) - sage: (a^2+b^2+c^2).quo_rem(a+b+c) + sage: (a^2 + b^2 + c^2).quo_rem(a + b + c) # optional - sage.libs.singular (a - b - c + O(a, b, c)^11, 2*b^2 + 2*b*c + 2*c^2 + O(a, b, c)^12) - sage: (a^2+b^2+c^2).quo_rem(1/(1+a+b+c)) - (a^2 + b^2 + c^2 + a^3 + a^2*b + a^2*c + a*b^2 + a*c^2 + b^3 + b^2*c + b*c^2 + c^3 + O(a, b, c)^14, + sage: (a^2 + b^2 + c^2).quo_rem(1/(1+a+b+c)) # optional - sage.libs.singular + (a^2 + b^2 + c^2 + a^3 + a^2*b + a^2*c + a*b^2 + a*c^2 + + b^3 + b^2*c + b*c^2 + c^3 + O(a, b, c)^14, 0) - sage: (a^2+b^2+c^2).quo_rem(a/(1+a+b+c)) + sage: (a^2 + b^2 + c^2).quo_rem(a/(1+a+b+c)) # optional - sage.libs.singular (a + a^2 + a*b + a*c + O(a, b, c)^13, b^2 + c^2) - sage: (1+a+a^15).quo_rem(a^2) + sage: (1 + a + a^15).quo_rem(a^2) # optional - sage.libs.singular (0 + O(a, b, c)^10, 1 + a + O(a, b, c)^12) - sage: (1+a+a^15).quo_rem(a^2, precision=15) + sage: (1 + a + a^15).quo_rem(a^2, precision=15) # optional - sage.libs.singular (0 + O(a, b, c)^13, 1 + a + O(a, b, c)^15) - sage: (1+a+a^15).quo_rem(a^2, precision=16) + sage: (1 + a + a^15).quo_rem(a^2, precision=16) # optional - sage.libs.singular (a^13 + O(a, b, c)^14, 1 + a + O(a, b, c)^16) Illustrating the dependency on the ordering of variables:: - sage: (1+a+b).quo_rem(b+c) + sage: (1 + a + b).quo_rem(b + c) # optional - sage.libs.singular (1 + O(a, b, c)^11, 1 + a - c + O(a, b, c)^12) - sage: (1+b+c).quo_rem(c+a) + sage: (1 + b + c).quo_rem(c + a) # optional - sage.libs.singular (0 + O(a, b, c)^11, 1 + b + c + O(a, b, c)^12) - sage: (1+c+a).quo_rem(a+b) + sage: (1 + c + a).quo_rem(a + b) # optional - sage.libs.singular (1 + O(a, b, c)^11, 1 - b + c + O(a, b, c)^12) TESTS:: - sage: (f).quo_rem(R.zero()) + sage: (f).quo_rem(R.zero()) # optional - sage.libs.singular Traceback (most recent call last): ... ZeroDivisionError - sage: (f).quo_rem(R.zero().add_bigoh(2)) + sage: (f).quo_rem(R.zero().add_bigoh(2)) # optional - sage.libs.singular Traceback (most recent call last): ... ZeroDivisionError Coercion is applied on ``other``:: - sage: (a+b).quo_rem(1) + sage: (a + b).quo_rem(1) # optional - sage.libs.singular (a + b + O(a, b, c)^12, 0 + O(a, b, c)^12) sage: R. = PowerSeriesRing(QQ) - sage: R(3).quo_rem(2) + sage: R(3).quo_rem(2) # optional - sage.libs.singular (3/2 + O(a, b, c)^12, 0 + O(a, b, c)^12) """ parent = self.parent() @@ -1034,30 +1037,30 @@ def _div_(self, denom_r): When possible, division by non-units also works:: - sage: a/(a*f) + sage: a/(a*f) # optional - sage.libs.singular 1 - a - b + a^2 + 3*a*b + b^2 + O(a, b, c)^3 - sage: a/(R.zero()) + sage: a/(R.zero()) # optional - sage.libs.singular Traceback (most recent call last): ZeroDivisionError - sage: (a*f)/f + sage: (a*f)/f # optional - sage.libs.singular a + O(a, b, c)^4 - sage: f/(a*f) + sage: f/(a*f) # optional - sage.libs.singular Traceback (most recent call last): ... ValueError: not divisible An example where one loses precision:: - sage: ((1+a)*f - f) / a*f + sage: ((1+a)*f - f) / a*f # optional - sage.libs.singular 1 + 2*a + 2*b + O(a, b, c)^2 TESTS:: - sage: ((a+b)*f) / f == (a+b) + sage: ((a+b)*f) / f == (a+b) # optional - sage.libs.singular True - sage: ((a+b)*f) / (a+b) == f + sage: ((a+b)*f) / (a+b) == f # optional - sage.libs.singular True """ if denom_r.is_unit(): # faster if denom_r is a unit @@ -1080,7 +1083,7 @@ def __mod__(self, other): False sage: g in R.base_extend(Zmod(2)) True - sage: g.polynomial() == f.polynomial() % 2 + sage: g.polynomial() == f.polynomial() % 2 # optional - sage.libs.singular True """ if isinstance(other, (int, Integer)): @@ -1155,14 +1158,14 @@ def variables(self): EXAMPLES:: - sage: T = PowerSeriesRing(GF(3),5,'t'); T + sage: T = PowerSeriesRing(GF(3),5,'t'); T # optional - sage.rings.finite_rings Multivariate Power Series Ring in t0, t1, t2, t3, t4 over Finite Field of size 3 - sage: t = T.gens() - sage: w = t[0] - 2*t[0]*t[2] + 5*t[4]^3 - t[0]^3*t[2]^2 + T.O(6) - sage: w + sage: t = T.gens() # optional - sage.rings.finite_rings + sage: w = t[0] - 2*t[0]*t[2] + 5*t[4]^3 - t[0]^3*t[2]^2 + T.O(6) # optional - sage.rings.finite_rings + sage: w # optional - sage.rings.finite_rings t0 + t0*t2 - t4^3 - t0^3*t2^2 + O(t0, t1, t2, t3, t4)^6 - sage: w.variables() + sage: w.variables() # optional - sage.rings.finite_rings (t0, t2, t4) """ return tuple(self.parent(v) for v in self._value().variables()) @@ -1392,16 +1395,16 @@ def valuation(self): EXAMPLES:: - sage: R. = PowerSeriesRing(GF(4949717)); R - Multivariate Power Series Ring in a, b over Finite Field of - size 4949717 - sage: f = a^2 + a*b + a^3 + R.O(9) - sage: f.valuation() + sage: R. = PowerSeriesRing(GF(4949717)); R # optional - sage.rings.finite_rings + Multivariate Power Series Ring in a, b + over Finite Field of size 4949717 + sage: f = a^2 + a*b + a^3 + R.O(9) # optional - sage.rings.finite_rings + sage: f.valuation() # optional - sage.rings.finite_rings 2 - sage: g = 1 + a + a^3 - sage: g.valuation() + sage: g = 1 + a + a^3 # optional - sage.rings.finite_rings + sage: g.valuation() # optional - sage.rings.finite_rings 0 - sage: R.zero().valuation() + sage: R.zero().valuation() # optional - sage.rings.finite_rings +Infinity """ try: @@ -1441,8 +1444,7 @@ def is_nilpotent(self): EXAMPLES:: sage: R. = PowerSeriesRing(Zmod(8)); R - Multivariate Power Series Ring in a, b, c over Ring of integers - modulo 8 + Multivariate Power Series Ring in a, b, c over Ring of integers modulo 8 sage: f = a + b + c + a^2*c sage: f.is_nilpotent() False @@ -1535,7 +1537,7 @@ def is_square(self): TESTS:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = a + b + a*b + T.O(5) sage: f.is_square() Traceback (most recent call last): @@ -1551,7 +1553,7 @@ def square_root(self): TESTS:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = a + b + a*b + T.O(5) sage: f.square_root() Traceback (most recent call last): @@ -1569,7 +1571,7 @@ def derivative(self, *args): EXAMPLES:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = a + b + a^2*b + T.O(5) sage: f.derivative(a) 1 + 2*a*b + O(a, b)^4 @@ -1602,7 +1604,7 @@ def integral(self, *args): EXAMPLES:: - sage: T. = PowerSeriesRing(QQ,2) + sage: T. = PowerSeriesRing(QQ, 2) sage: f = a + b + a^2*b + T.O(5) sage: f.integral(a, 2) 1/6*a^3 + 1/2*a^2*b + 1/12*a^4*b + O(a, b)^7 @@ -1613,7 +1615,7 @@ def integral(self, *args): Only integration with respect to variables works:: - sage: f.integral(a+b) + sage: f.integral(a + b) Traceback (most recent call last): ... ValueError: a + b is not a variable @@ -1626,7 +1628,7 @@ def integral(self, *args): first case, Sage will report that it has not been able to coerce some coefficient to the base ring:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = a + T.O(5) sage: f.integral(a) Traceback (most recent call last): @@ -1648,7 +1650,7 @@ def integral(self, *args): In non-zero characteristic, Sage will report that a zero division occurred :: - sage: T. = PowerSeriesRing(Zmod(3),2) + sage: T. = PowerSeriesRing(Zmod(3), 2) sage: (a^3).integral(a) a^4 sage: (a^2).integral(a) @@ -1724,7 +1726,7 @@ def ogf(self): TESTS:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = a + b + a*b + T.O(5) sage: f.ogf() Traceback (most recent call last): @@ -1739,7 +1741,7 @@ def egf(self): TESTS:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = a + b + a*b + T.O(5) sage: f.egf() Traceback (most recent call last): @@ -1754,7 +1756,7 @@ def __pari__(self): TESTS:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = a + b + a*b + T.O(5) sage: f.__pari__() Traceback (most recent call last): @@ -1773,7 +1775,7 @@ def list(self): TESTS:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = a + b + a*b + T.O(5) sage: f.list() Traceback (most recent call last): @@ -1790,7 +1792,7 @@ def variable(self): TESTS:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = a + b + a*b + T.O(5) sage: f.variable() Traceback (most recent call last): @@ -1806,7 +1808,7 @@ def shift(self, n): TESTS:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = a + b + a*b + T.O(5) sage: f.shift(3) Traceback (most recent call last): @@ -1821,7 +1823,7 @@ def __lshift__(self, n): TESTS:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = a + b + a*b + T.O(5) sage: f.__lshift__(3) Traceback (most recent call last): @@ -1836,7 +1838,7 @@ def __rshift__(self, n): TESTS:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = a + b + a*b + T.O(5) sage: f.__rshift__(3) Traceback (most recent call last): @@ -1852,7 +1854,7 @@ def valuation_zero_part(self): TESTS:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = a + b + a*b + T.O(5) sage: f.valuation_zero_part() Traceback (most recent call last): @@ -1868,7 +1870,7 @@ def solve_linear_de(self, prec=infinity, b=None, f0=None): TESTS:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = a + b + a*b + T.O(5) sage: f.solve_linear_de() Traceback (most recent call last): @@ -1893,15 +1895,15 @@ def exp(self, prec=infinity): EXAMPLES:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = a + b + a*b + T.O(3) - sage: exp(f) + sage: exp(f) # optional - sage.symbolic 1 + a + b + 1/2*a^2 + 2*a*b + 1/2*b^2 + O(a, b)^3 - sage: f.exp() + sage: f.exp() # optional - sage.symbolic 1 + a + b + 1/2*a^2 + 2*a*b + 1/2*b^2 + O(a, b)^3 - sage: f.exp(prec=2) + sage: f.exp(prec=2) # optional - sage.symbolic 1 + a + b + O(a, b)^2 - sage: log(exp(f)) - f + sage: log(exp(f)) - f # optional - sage.symbolic 0 + O(a, b)^3 If the power series has a constant coefficient `c` and @@ -1909,8 +1911,8 @@ def exp(self, prec=infinity): power series over the :class:`~sage.symbolic.ring.SymbolicRing`. These are not yet implemented and therefore such cases raise an error:: - sage: g = 2+f - sage: exp(g) + sage: g = 2 + f + sage: exp(g) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for *: 'Symbolic Ring' and @@ -1920,7 +1922,7 @@ def exp(self, prec=infinity): Another workaround for this limitation is to change base ring to one which is closed under exponentiation, such as `\RR` or `\CC`:: - sage: exp(g.change_ring(RDF)) + sage: exp(g.change_ring(RDF)) # optional - sage.symbolic 7.38905609... + 7.38905609...*a + 7.38905609...*b + 3.69452804...*a^2 + 14.7781121...*a*b + 3.69452804...*b^2 + O(a, b)^3 @@ -1928,17 +1930,17 @@ def exp(self, prec=infinity): sage: T.default_prec() 12 - sage: exp(a) + sage: exp(a) # optional - sage.symbolic 1 + a + 1/2*a^2 + 1/6*a^3 + 1/24*a^4 + 1/120*a^5 + 1/720*a^6 + 1/5040*a^7 + 1/40320*a^8 + 1/362880*a^9 + 1/3628800*a^10 + 1/39916800*a^11 + O(a, b)^12 sage: a.exp(prec=5) 1 + a + 1/2*a^2 + 1/6*a^3 + 1/24*a^4 + O(a, b)^5 - sage: exp(a + T.O(5)) + sage: exp(a + T.O(5)) # optional - sage.symbolic 1 + a + 1/2*a^2 + 1/6*a^3 + 1/24*a^4 + O(a, b)^5 TESTS:: - sage: exp(a^2 + T.O(5)) + sage: exp(a^2 + T.O(5)) # optional - sage.symbolic 1 + a^2 + 1/2*a^4 + O(a, b)^5 """ R = self.parent() @@ -1985,13 +1987,13 @@ def log(self, prec=infinity): EXAMPLES:: - sage: T. = PowerSeriesRing(ZZ,2) + sage: T. = PowerSeriesRing(ZZ, 2) sage: f = 1 + a + b + a*b + T.O(5) - sage: f.log() + sage: f.log() # optional - sage.symbolic a + b - 1/2*a^2 - 1/2*b^2 + 1/3*a^3 + 1/3*b^3 - 1/4*a^4 - 1/4*b^4 + O(a, b)^5 - sage: log(f) + sage: log(f) # optional - sage.symbolic a + b - 1/2*a^2 - 1/2*b^2 + 1/3*a^3 + 1/3*b^3 - 1/4*a^4 - 1/4*b^4 + O(a, b)^5 - sage: exp(log(f)) - f + sage: exp(log(f)) - f # optional - sage.symbolic 0 + O(a, b)^5 If the power series has a constant coefficient `c` and @@ -1999,8 +2001,8 @@ def log(self, prec=infinity): power series over the :class:`~sage.symbolic.ring.SymbolicRing`. These are not yet implemented and therefore such cases raise an error:: - sage: g = 2+f - sage: log(g) + sage: g = 2 + f # optional - sage.symbolic + sage: log(g) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for -: 'Symbolic Ring' and 'Power @@ -2009,7 +2011,7 @@ def log(self, prec=infinity): Another workaround for this limitation is to change base ring to one which is closed under exponentiation, such as `\RR` or `\CC`:: - sage: log(g.change_ring(RDF)) + sage: log(g.change_ring(RDF)) # optional - sage.symbolic 1.09861228... + 0.333333333...*a + 0.333333333...*b - 0.0555555555...*a^2 + 0.222222222...*a*b - 0.0555555555...*b^2 + 0.0123456790...*a^3 - 0.0740740740...*a^2*b - 0.0740740740...*a*b^2 + 0.0123456790...*b^3 @@ -2018,17 +2020,17 @@ def log(self, prec=infinity): TESTS:: - sage: (1+a).log(prec=10).exp() + sage: (1+a).log(prec=10).exp() # optional - sage.symbolic 1 + a + O(a, b)^10 - sage: a.exp(prec=10).log() + sage: a.exp(prec=10).log() # optional - sage.symbolic a + O(a, b)^10 - sage: log(1+a) + sage: log(1+a) # optional - sage.symbolic a - 1/2*a^2 + 1/3*a^3 - 1/4*a^4 + 1/5*a^5 - 1/6*a^6 + 1/7*a^7 - 1/8*a^8 + 1/9*a^9 - 1/10*a^10 + 1/11*a^11 + O(a, b)^12 - sage: -log(1-a+T.O(5)) + sage: -log(1-a+T.O(5)) # optional - sage.symbolic a + 1/2*a^2 + 1/3*a^3 + 1/4*a^4 + O(a, b)^5 - sage: a.log(prec=10) + sage: a.log(prec=10) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Can only take formal power series for non-zero constant term. @@ -2090,7 +2092,7 @@ class MO(): sage: m^1 0 + O(u, v)^1 - sage: T. = PowerSeriesRing(ZZ,3) + sage: T. = PowerSeriesRing(ZZ, 3) sage: z = O(a, b, c) sage: z^1 0 + O(a, b, c)^1 diff --git a/src/sage/rings/noncommutative_ideals.pyx b/src/sage/rings/noncommutative_ideals.pyx index 0661987be2a..af27882313d 100644 --- a/src/sage/rings/noncommutative_ideals.pyx +++ b/src/sage/rings/noncommutative_ideals.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules """ Ideals of non-commutative rings diff --git a/src/sage/rings/number_field/S_unit_solver.py b/src/sage/rings/number_field/S_unit_solver.py index af226730584..c8791e7b4ce 100644 --- a/src/sage/rings/number_field/S_unit_solver.py +++ b/src/sage/rings/number_field/S_unit_solver.py @@ -1,7 +1,7 @@ r""" Solve S-unit equation x + y = 1 -Inspired by work of Tzanakis--de Weger, Baker--Wustholz and Smart, we use the LLL methods in Sage to implement an algorithm that returns all S-unit solutions to the equation `x + y = 1`. +Inspired by work of Tzanakis--de Weger, Baker--Wustholz and Smart, we use the LLL methods in Sage to implement an algorithm that returns all `S`-unit solutions to the equation `x + y = 1`. REFERENCES: @@ -22,7 +22,7 @@ EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import solve_S_unit_equation, eq_up_to_order - sage: K. = NumberField(x^2+x+1) + sage: K. = NumberField(x^2 + x + 1) sage: S = K.primes_above(3) sage: expected = [((0, 1), (4, 0), xi + 2, -xi - 1), ....: ((1, -1), (0, -1), 1/3*xi + 2/3, -1/3*xi + 1/3), @@ -55,12 +55,13 @@ from sage.rings.infinity import Infinity -from sage.symbolic.ring import SR +from sage.misc.lazy_import import lazy_import +lazy_import("sage.symbolic.ring", "SR") from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.real_mpfr import RealField, RR from sage.rings.complex_mpfr import ComplexField -from sage.functions.log import exp +lazy_import("sage.functions.log", "exp") from sage.rings.rational_field import QQ from sage.rings.number_field.number_field import is_real_place, refine_embedding from sage.rings.number_field.unit_group import UnitGroup @@ -96,7 +97,7 @@ def column_Log(SUK, iota, U, prec=106): EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import column_Log - sage: K. = NumberField(x^3-3) + sage: K. = NumberField(x^3 - 3) sage: S = tuple(K.primes_above(3)) sage: SUK = UnitGroup(K, S=S) sage: phi_complex = K.places()[1] @@ -125,15 +126,15 @@ def c3_func(SUK, prec=106): OUTPUT: - The constant ``c3``, as a real number + The constant `c_3`, as a real number EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import c3_func - sage: K. = NumberField(x^3-3) + sage: K. = NumberField(x^3 - 3) sage: SUK = UnitGroup(K, S=tuple(K.primes_above(3))) - sage: c3_func(SUK) # abs tol 1e-29 + sage: c3_func(SUK) # abs tol 1e-29 0.4257859134798034746197327286726 .. NOTE:: @@ -177,25 +178,25 @@ def c4_func(SUK, v, A, prec=106): OUTPUT: - The constant ``c4``, as a real number + The constant `c_4`, as a real number EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import c4_func - sage: K. = NumberField(x^3-3) + sage: K. = NumberField(x^3 - 3) sage: SUK = UnitGroup(K, S=tuple(K.primes_above(3))) sage: phi_real = K.places()[0] sage: phi_complex = K.places()[1] sage: v_fin = tuple(K.primes_above(3))[0] sage: A = K.roots_of_unity() - sage: c4_func(SUK,phi_real,A) + sage: c4_func(SUK, phi_real, A) 1.000000000000000000000000000000 - sage: c4_func(SUK,phi_complex,A) + sage: c4_func(SUK, phi_complex, A) 1.000000000000000000000000000000 - sage: c4_func(SUK,v_fin,A) + sage: c4_func(SUK, v_fin, A) 1.000000000000000000000000000000 REFERENCES: @@ -220,11 +221,11 @@ def beta_k(betas_and_ns): EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import beta_k - sage: K. = NumberField(x^3-3) + sage: K. = NumberField(x^3 - 3) sage: SUK = UnitGroup(K, S=tuple(K.primes_above(3))) sage: v_fin = tuple(K.primes_above(3))[0] - sage: betas = [ [beta, beta.valuation(v_fin)] for beta in SUK.fundamental_units() ] + sage: betas = [[beta, beta.valuation(v_fin)] for beta in SUK.fundamental_units()] sage: beta_k(betas) [xi, 1] @@ -297,12 +298,12 @@ def possible_mu0s(SUK, v): EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import possible_mu0s - sage: K. = NumberField(x^3-3) + sage: K. = NumberField(x^3 - 3) sage: S = tuple(K.primes_above(3)) sage: SUK = UnitGroup(K, S=S) sage: v_fin = S[0] - sage: possible_mu0s(SUK,v_fin) + sage: possible_mu0s(SUK, v_fin) [-1, 1] .. NOTE:: @@ -343,7 +344,7 @@ def Yu_a1_kappa1_c1(p, dK, ep): - ``p`` -- a rational prime number - ``dK`` -- the absolute degree of some number field `K` - - ``ep`` -- the absolute ramification index of some prime `frak_p` of `K` lying above `p` + - ``ep`` -- the absolute ramification index of some prime ``frak_p`` of `K` lying above `p` OUTPUT: @@ -515,18 +516,18 @@ def Yu_modified_height(mu, n, v, prec=106): def Omega_prime(dK, v, mu_list, prec=106): r""" - Return the constant Omega' appearing in [AKMRVW]_. + Return the constant `\Omega'` appearing in [AKMRVW]_. INPUT: - ``dK`` -- the degree of a number field `K` - ``v`` -- a finite place of `K` - - ``mu_list`` -- a list of nonzero elements of `K`. It is assumed that the sublist mu[1:] is multiplicatively independent. + - ``mu_list`` -- a list of nonzero elements of `K`. It is assumed that the sublist ``mu_list[1:]`` is multiplicatively independent. - ``prec`` -- the precision of the real field OUTPUT: - The constant `Omega'`. + The constant `\Omega'`. EXAMPLES:: @@ -559,7 +560,7 @@ def Omega_prime(dK, v, mu_list, prec=106): def Yu_C1_star(n, v, prec=106): r""" - Return the constant C_1^* appearing in [Yu2007]_ (1.23). + Return the constant `C_1^*` appearing in [Yu2007]_ (1.23). INPUT: @@ -569,7 +570,7 @@ def Yu_C1_star(n, v, prec=106): OUTPUT: - The constant `C1_star` as a real number. + The constant `C_1^*` as a real number. EXAMPLES:: @@ -619,7 +620,7 @@ def Yu_C1_star(n, v, prec=106): def Yu_bound(SUK, v, prec=106): r""" - Return `c8` such that `c8 >= exp(2)/\log(2)` and `ord_p (\Theta - 1) < c8 \log B`, + Return `c_8` such that `c_8 \geq exp(2)/\log(2)` and `ord_p (\Theta - 1) < c_8 \log B`, where `\Theta = \prod_{j=1}^n \alpha_j^{b_j}` and `B \geq \max_j |b_j|` and `B \geq 3`. INPUT: @@ -630,7 +631,7 @@ def Yu_bound(SUK, v, prec=106): OUTPUT: - The constant `c8` as a real number. + The constant `c_8` as a real number. EXAMPLES:: @@ -707,12 +708,12 @@ def K0_func(SUK, A, prec=106): INPUT: - ``SUK`` -- a group of `S`-units - - ``A`` -- the set of the products of the coefficients of the `S`-unit equation with each root of unity of ``K`` + - ``A`` -- the set of the products of the coefficients of the `S`-unit equation with each root of unity of `K` - ``prec`` -- the precision of the real field (default: 106) OUTPUT: - The constant ``K0``, a real number. + The constant `K_0`, a real number. EXAMPLES:: @@ -756,18 +757,18 @@ def c11_func(SUK, v, A, prec=106): INPUT: - ``SUK`` -- a group of `S`-units - - ``v`` -- a place of ``K``, finite (a fractional ideal) or infinite (element of ``SUK.number_field().places(prec)``) - - ``A`` -- the set of the product of the coefficients of the `S`-unit equation with each root of unity of ``K`` + - ``v`` -- a place of `K`, finite (a fractional ideal) or infinite (element of ``SUK.number_field().places(prec)``) + - ``A`` -- the set of the product of the coefficients of the `S`-unit equation with each root of unity of `K` - ``prec`` -- the precision of the real field (default: 106) OUTPUT: - The constant ``c11``, a real number + The constant `c_{11}`, a real number EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import c11_func - sage: K. = NumberField(x^3-3) + sage: K. = NumberField(x^3 - 3) sage: SUK = UnitGroup(K, S=tuple(K.primes_above(3))) sage: phi_real = K.places()[0] sage: phi_complex = K.places()[1] @@ -802,7 +803,7 @@ def c13_func(SUK, v, prec=106): OUTPUT: - The constant ``c13``, as a real number + The constant `c_{13}`, as a real number EXAMPLES:: @@ -848,18 +849,18 @@ def K1_func(SUK, v, A, prec=106): INPUT: - ``SUK`` -- a group of `S`-units - - ``v`` -- an infinite place of ``K`` (element of ``SUK.number_field().places(prec)``) - - ``A`` -- a list of all products of each potential ``a``, ``b`` in the `S`-unit equation ``ax + by + 1 = 0`` with each root of unity of ``K`` + - ``v`` -- an infinite place of `K` (element of ``SUK.number_field().places(prec)``) + - ``A`` -- a list of all products of each potential `a`, `b` in the `S`-unit equation `ax + by + 1 = 0` with each root of unity of `K` - ``prec`` -- the precision of the real field (default: 106) OUTPUT: - The constant ``K1,`` a real number + The constant `K_1`, a real number EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import K1_func - sage: K. = NumberField(x^3-3) + sage: K. = NumberField(x^3 - 3) sage: SUK = UnitGroup(K, S=tuple(K.primes_above(3))) sage: phi_real = K.places()[0] sage: phi_complex = K.places()[1] @@ -914,9 +915,9 @@ def minimal_vector(A, y, prec=106): r""" INPUT: - - ``A`` : a square n by n non-singular integer matrix whose rows generate a lattice `\mathcal L` - - ``y`` : a row (1 by n) vector with integer coordinates - - ``prec`` : precision of real field (default: 106) + - ``A`` -- a square `n` by `n` non-singular integer matrix whose rows generate a lattice `\mathcal L` + - ``y`` -- a row (1 by `n`) vector with integer coordinates + - ``prec`` -- precision of real field (default: 106) OUTPUT: @@ -1002,9 +1003,10 @@ def reduction_step_complex_case(place, B0, list_of_gens, torsion_gen, c13): EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import reduction_step_complex_case - sage: K. = NumberField([x^3-2]) + sage: K. = NumberField([x^3 - 2]) sage: SK = sum([K.primes_above(p) for p in [2,3,5]],[]) - sage: G = [g for g in K.S_unit_group(S=SK).gens_values() if g.multiplicative_order()==Infinity] + sage: G = [g for g in K.S_unit_group(S=SK).gens_values() + ....: if g.multiplicative_order() == Infinity] sage: p1 = K.places(prec=100)[1] sage: reduction_step_complex_case(p1, 10^5, G, -1, 2) (18, False) @@ -1160,7 +1162,7 @@ def cx_LLL_bound(SUK, A, prec=106): INPUT: - ``SUK`` -- a group of `S`-units - - ``A`` -- a list of all products of each potential ``a``, ``b`` in the `S`-unit equation ``ax + by + 1 = 0`` with each root of unity of ``K`` + - ``A`` -- a list of all products of each potential `a`, `b` in the `S`-unit equation `ax + by + 1 = 0` with each root of unity of `K` - ``prec`` -- precision of real field (default: 106) OUTPUT: @@ -1170,11 +1172,11 @@ def cx_LLL_bound(SUK, A, prec=106): EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import cx_LLL_bound - sage: K. = NumberField(x^3-3) - sage: SUK = UnitGroup(K,S=tuple(K.primes_above(3))) + sage: K. = NumberField(x^3 - 3) + sage: SUK = UnitGroup(K, S=tuple(K.primes_above(3))) sage: A = K.roots_of_unity() - sage: cx_LLL_bound(SUK,A) # long time + sage: cx_LLL_bound(SUK, A) # long time 35 """ cx_LLL = 0 @@ -1219,7 +1221,7 @@ def log_p(a, prime, prec): OUTPUT: - An element of `K` which is congruent to the ``prime``-adic logarithm of ``a`` with respect to ``prime`` modulo ``p^prec``, where ``p`` is the rational prime below ``prime`` + An element of `K` which is congruent to the ``prime``-adic logarithm of `a` with respect to ``prime`` modulo ``p^prec``, where `p` is the rational prime below ``prime`` .. NOTE:: @@ -1228,7 +1230,7 @@ def log_p(a, prime, prec): EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import log_p - sage: K. = NumberField(x^2+14) + sage: K. = NumberField(x^2 + 14) sage: p1 = K.primes_above(3)[0] sage: p1 Fractional ideal (3, a + 1) @@ -1237,7 +1239,7 @@ def log_p(a, prime, prec): :: - sage: K. = NumberField(x^4+14) + sage: K. = NumberField(x^4 + 14) sage: p1 = K.primes_above(5)[0] sage: p1 Fractional ideal (5, a + 1) @@ -1283,7 +1285,7 @@ def log_p_series_part(a, prime, prec): OUTPUT: - The ``prime``-adic logarithm of ``a`` and accuracy ``p^prec``, where ``p`` is the rational prime below ``prime`` + The ``prime``-adic logarithm of `a` and accuracy ``p^prec``, where `p` is the rational prime below ``prime`` ALGORITHM: @@ -1292,16 +1294,16 @@ def log_p_series_part(a, prime, prec): EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import log_p_series_part - sage: K. = NumberField(x^2-5) + sage: K. = NumberField(x^2 - 5) sage: p1 = K.primes_above(3)[0] sage: p1 Fractional ideal (3) - sage: log_p_series_part(a^2-a+1, p1, 30) + sage: log_p_series_part(a^2 - a + 1, p1, 30) 120042736778562*a + 263389019530092 :: - sage: K. = NumberField(x^4+14) + sage: K. = NumberField(x^4 + 14) sage: p1 = K.primes_above(5)[0] sage: p1 Fractional ideal (5, a + 1) @@ -1442,7 +1444,7 @@ def embedding_to_Kp(a, prime, prec): OUTPUT: - An element of `K` that is equivalent to ``a`` modulo ``p^(prec)`` and the generator of `K` appears with exponent less than `e \cdot f`, where ``p`` is the rational prime below ``prime`` and `e,f` are the ramification index and residue degree, respectively. + An element of `K` that is equivalent to `a` modulo ``p^(prec)`` and the generator of `K` appears with exponent less than `e \cdot f`, where `p` is the rational prime below ``prime`` and `e`, `f` are the ramification index and residue degree, respectively. .. NOTE:: @@ -1459,10 +1461,10 @@ def embedding_to_Kp(a, prime, prec): :: - sage: K. = NumberField(x^4-2) + sage: K. = NumberField(x^4 - 2) sage: p = K.prime_above(7); p Fractional ideal (-a^2 + a - 1) - sage: embedding_to_Kp(a^3-3, p, 15) + sage: embedding_to_Kp(a^3 - 3, p, 15) -1261985118949117459462968282807202378 """ K = prime.ring() @@ -1486,7 +1488,7 @@ def p_adic_LLL_bound_one_prime(prime, B0, M, M_logp, m0, c3, prec=106): - ``M_logp`` -- the p-adic logarithm of elements in `M` - ``m0`` -- an element of `K`, this is `\mu_0` from Lemma IX.3 of [Sma1998]_ - ``c3`` -- a positive real constant - - ``prec`` -- the precision of the calculations (default: 106), i.e., values are known to O(p^prec) + - ``prec`` -- the precision of the calculations (default: 106), i.e., values are known to ``O(p^prec)`` OUTPUT: @@ -1506,32 +1508,36 @@ def p_adic_LLL_bound_one_prime(prime, B0, M, M_logp, m0, c3, prec=106): sage: from sage.rings.number_field.S_unit_solver import p_adic_LLL_bound_one_prime sage: prec = 50 - sage: K. = NumberField(x^3-3) + sage: K. = NumberField(x^3 - 3) sage: S = tuple(K.primes_above(3)) sage: SUK = UnitGroup(K, S=S) sage: v = S[0] sage: A = SUK.roots_of_unity() sage: K0_old = 9.4755766731093e17 sage: Mus = [a^2 - 2] - sage: Log_p_Mus = [185056824593551109742400*a^2 + 1389583284398773572269676*a + 717897987691852588770249] + sage: Log_p_Mus = [185056824593551109742400*a^2 + ....: + 1389583284398773572269676*a + 717897987691852588770249] sage: mu0 = K(-1) sage: c3_value = 0.42578591347980 - sage: m0_Kv_new, increase_precision = p_adic_LLL_bound_one_prime(v, K0_old, Mus, Log_p_Mus, mu0, c3_value, prec) + sage: m0_Kv_new, increase_prec = p_adic_LLL_bound_one_prime(v, K0_old, Mus, Log_p_Mus, + ....: mu0, c3_value, prec) sage: m0_Kv_new 0 - sage: increase_precision + sage: increase_prec True And now we increase the precision to make it all work:: sage: prec = 106 sage: K0_old = 9.475576673109275443280257946930e17 - sage: Log_p_Mus = [1029563604390986737334686387890424583658678662701816*a^2 + 661450700156368458475507052066889190195530948403866*a] + sage: Log_p_Mus = [1029563604390986737334686387890424583658678662701816*a^2 + ....: + 661450700156368458475507052066889190195530948403866*a] sage: c3_value = 0.4257859134798034746197327286726 - sage: m0_Kv_new, increase_precision = p_adic_LLL_bound_one_prime(v, K0_old, Mus, Log_p_Mus, mu0, c3_value, prec) + sage: m0_Kv_new, increase_prec = p_adic_LLL_bound_one_prime(v, K0_old, Mus, Log_p_Mus, + ....: mu0, c3_value, prec) sage: m0_Kv_new 476 - sage: increase_precision + sage: increase_prec False """ if any(g.valuation(prime) != 0 for g in M+[m0]): @@ -1629,7 +1635,7 @@ def p_adic_LLL_bound(SUK, A, prec=106): INPUT: - ``SUK`` -- a group of `S`-units - - ``A`` -- a list of all products of each potential ``a``, ``b`` in the `S`-unit equation ``ax + by + 1 = 0`` with each root of unity of ``K`` + - ``A`` -- a list of all products of each potential `a`, `b` in the `S`-unit equation `ax + by + 1 = 0` with each root of unity of `K` - ``prec``-- precision for p-adic LLL calculations (default: 106) OUTPUT: @@ -1639,11 +1645,11 @@ def p_adic_LLL_bound(SUK, A, prec=106): EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import p_adic_LLL_bound - sage: K. = NumberField(x^3-3) - sage: SUK = UnitGroup(K,S=tuple(K.primes_above(3))) + sage: K. = NumberField(x^3 - 3) + sage: SUK = UnitGroup(K, S=tuple(K.primes_above(3))) sage: A = SUK.roots_of_unity() sage: prec = 100 - sage: p_adic_LLL_bound(SUK,A, prec) + sage: p_adic_LLL_bound(SUK, A, prec) 89 """ S = SUK.primes() @@ -1683,7 +1689,7 @@ def p_adic_LLL_bound(SUK, A, prec=106): def split_primes_large_lcm(SUK, bound): r""" - Return a list ``L`` of rational primes `q` which split completely in `K` and which have desirable properties (see NOTE). + Return a list `L` of rational primes `q` which split completely in `K` and which have desirable properties (see NOTE). INPUT: @@ -1697,7 +1703,7 @@ def split_primes_large_lcm(SUK, bound): - each prime `q` in `L` splits completely in `K` - if `Q` is a prime in `S` and `q` is the rational prime below `Q`, then `q` is **not** in `L` - - the value ``lcm { q-1 : q in L }`` is greater than or equal to ``2*bound + 1``. + - the value `\lcm(\{ q-1 : q \in L \})` is greater than or equal to ``2*bound + 1``. .. NOTE:: @@ -1713,7 +1719,7 @@ def split_primes_large_lcm(SUK, bound): sage: from sage.rings.number_field.S_unit_solver import split_primes_large_lcm sage: K. = NumberField(x^3 - 3*x + 1) sage: S = K.primes_above(3) - sage: SUK = UnitGroup(K,S=tuple(S)) + sage: SUK = UnitGroup(K, S=tuple(S)) sage: split_primes_large_lcm(SUK, 200) [17, 19, 37, 53] @@ -1752,7 +1758,7 @@ def split_primes_large_lcm(SUK, bound): def sieve_ordering(SUK, q): r""" - Returns ordered data for running sieve on the primes in `SUK` over the rational prime `q`. + Return ordered data for running sieve on the primes in ``SUK`` over the rational prime `q`. INPUT: @@ -1763,7 +1769,7 @@ def sieve_ordering(SUK, q): A list of tuples, ``[ideals_over_q, residue_fields, rho_images, product_rho_orders]``, where - 1. ``ideals_over_q`` is a list of the `d = [K:\mathbb{Q}]` ideals in `K` over `q` + 1. ``ideals_over_q`` is a list of the `d = [K:\QQ]` ideals in `K` over `q` 2. ``residue_fields[i]`` is the residue field of ``ideals_over_q[i]`` 3. ``rho_images[i]`` is a list of the reductions of the generators in of the `S`-unit group, modulo ``ideals_over_q[i]`` 4. ``product_rho_orders[i]`` is the product of the multiplicative orders of the elements in ``rho_images[i]`` @@ -1771,7 +1777,7 @@ def sieve_ordering(SUK, q): .. NOTE:: - The list ``ideals_over_q`` is sorted so that the product of orders is smallest for ``ideals_over_q[0]``, as this will make the later sieving steps more efficient. - - The primes of ``S`` must not lie over ``q``. + - The primes of `S` must not lie over `q`. EXAMPLES:: @@ -1821,7 +1827,7 @@ def sieve_ordering(SUK, q): def clean_rfv_dict(rfv_dictionary): r""" - Given a residue field vector dictionary, removes some impossible keys and entries. + Given a residue field vector dictionary, remove some impossible keys and entries. INPUT: @@ -1829,13 +1835,13 @@ def clean_rfv_dict(rfv_dictionary): OUTPUT: - None. But it removes some keys from the input dictionary. + ``None``. But it removes some keys from the input dictionary. .. NOTE:: - - The keys of a residue field vector dictionary are exponent vectors modulo ``(q-1)`` for some prime ``q``. - - The values are residue field vectors. It is known that the entries of a residue field vector - which comes from a solution to the S-unit equation cannot have 1 in any entry. + - The keys of a residue field vector dictionary are exponent vectors modulo `q-1` for some prime `q`. + - The values are residue field vectors. It is known that a residue field vector + which comes from a solution to the `S`-unit equation cannot have 1 in any entry. EXAMPLES: @@ -1843,7 +1849,8 @@ def clean_rfv_dict(rfv_dictionary): polynomial `x^2+x+1` and `S` consists of the primes above 3:: sage: from sage.rings.number_field.S_unit_solver import clean_rfv_dict - sage: rfv_dict = {(1, 3): [3, 2], (3, 0): [6, 6], (5, 4): [3, 6], (2, 1): [4, 6], (5, 1): [3, 1], (2, 5): [1, 5], (0, 3): [1, 6]} + sage: rfv_dict = {(1, 3): [3, 2], (3, 0): [6, 6], (5, 4): [3, 6], (2, 1): [4, 6], + ....: (5, 1): [3, 1], (2, 5): [1, 5], (0, 3): [1, 6]} sage: len(rfv_dict) 7 sage: clean_rfv_dict(rfv_dict) @@ -1866,8 +1873,8 @@ def construct_rfv_to_ev(rfv_dictionary, q, d, verbose=False): - ``rfv_dictionary`` -- a dictionary whose keys are exponent vectors and whose values are the associated residue field vectors - ``q`` -- a prime (assumed to split completely in the relevant number field) - - ``d`` -- the number of primes in `K` above the rational prime ``q`` - - ``verbose`` -- a boolean flag to indicate more detailed output is desired (default: False) + - ``d`` -- the number of primes in `K` above the rational prime `q` + - ``verbose`` -- a boolean flag to indicate more detailed output is desired (default: ``False``) OUTPUT: @@ -1876,7 +1883,7 @@ def construct_rfv_to_ev(rfv_dictionary, q, d, verbose=False): .. NOTE:: - - For example, if ``rfv_dictionary[ e0 ] = r0``, then ``P[ r0 ]`` is a list which contains ``e0``. + - For example, if ``rfv_dictionary[e0] = r0``, then ``P[r0]`` is a list which contains ``e0``. - During construction, some residue field vectors can be eliminated as coming from solutions to the `S`-unit equation. Such vectors are dropped from the keys of the dictionary ``P``. @@ -1886,7 +1893,8 @@ def construct_rfv_to_ev(rfv_dictionary, q, d, verbose=False): polynomial `x^2+x+1` and `S` consists of the primes above 3:: sage: from sage.rings.number_field.S_unit_solver import construct_rfv_to_ev - sage: rfv_dict = {(1, 3): [3, 2], (3, 0): [6, 6], (5, 4): [3, 6], (2, 1): [4, 6], (4, 0): [4, 2], (1, 2): [5, 6]} + sage: rfv_dict = {(1, 3): [3, 2], (3, 0): [6, 6], (5, 4): [3, 6], (2, 1): [4, 6], + ....: (4, 0): [4, 2], (1, 2): [5, 6]} sage: construct_rfv_to_ev(rfv_dict,7,2,False) {(3, 2): [(1, 3)], (4, 2): [(4, 0)], (4, 6): [(2, 1)], (5, 6): [(1, 2)]} """ @@ -2013,7 +2021,15 @@ def construct_comp_exp_vec(rfv_to_ev_dict, q): :: sage: from sage.rings.number_field.S_unit_solver import construct_comp_exp_vec - sage: rfv_to_ev_dict = {(6, 6): [(3, 0)], (5, 6): [(1, 2)], (5, 4): [(5, 3)], (6, 2): [(5, 5)], (2, 5): [(0, 1)], (5, 5): [(3, 4)], (4, 4): [(0, 2)], (6, 3): [(1, 4)], (3, 6): [(5, 4)], (2, 2): [(0, 4)], (3, 5): [(1, 0)], (6, 4): [(1, 1)], (3, 2): [(1, 3)], (2, 6): [(4, 5)], (4, 5): [(4, 3)], (2, 3): [(2, 3)], (4, 2): [(4, 0)], (6, 5): [(5, 2)], (3, 3): [(3, 2)], (5, 3): [(5, 0)], (4, 6): [(2, 1)], (3, 4): [(3, 5)], (4, 3): [(0, 5)], (5, 2): [(3, 1)], (2, 4): [(2, 0)]} + sage: rfv_to_ev_dict = {(6, 6): [(3, 0)], (5, 6): [(1, 2)], (5, 4): [(5, 3)], + ....: (6, 2): [(5, 5)], (2, 5): [(0, 1)], (5, 5): [(3, 4)], + ....: (4, 4): [(0, 2)], (6, 3): [(1, 4)], (3, 6): [(5, 4)], + ....: (2, 2): [(0, 4)], (3, 5): [(1, 0)], (6, 4): [(1, 1)], + ....: (3, 2): [(1, 3)], (2, 6): [(4, 5)], (4, 5): [(4, 3)], + ....: (2, 3): [(2, 3)], (4, 2): [(4, 0)], (6, 5): [(5, 2)], + ....: (3, 3): [(3, 2)], (5, 3): [(5, 0)], (4, 6): [(2, 1)], + ....: (3, 4): [(3, 5)], (4, 3): [(0, 5)], (5, 2): [(3, 1)], + ....: (2, 4): [(2, 0)]} sage: construct_comp_exp_vec(rfv_to_ev_dict, 7) {(0, 1): [(1, 4)], (0, 2): [(0, 2)], @@ -2054,17 +2070,17 @@ def construct_comp_exp_vec(rfv_to_ev_dict, q): def drop_vector(ev, p, q, complement_ev_dict): r""" - Determines if the exponent vector, ``ev``, may be removed from the complement dictionary during construction. - This will occur if ``ev`` is not compatible with an exponent vector mod ``q-1``. + Determine if the exponent vector, ``ev``, may be removed from the complement dictionary during construction. + This will occur if ``ev`` is not compatible with an exponent vector mod `q-1`. INPUT: - - ``ev`` -- an exponent vector modulo ``p - 1`` - - ``p`` -- the prime such that ev is an exponent vector modulo ``p-1`` - - ``q`` -- a prime, distinct from ``p``, that is a key in the ``complement_ev_dict`` - - ``complement_ev_dict`` -- a dictionary of dictionaries, whose keys are primes - ``complement_ev_dict[q]`` is a dictionary whose keys are exponent vectors modulo ``q-1`` - and whose values are lists of complementary exponent vectors modulo ``q-1`` + - ``ev`` -- an exponent vector modulo `p-1` + - ``p`` -- the prime such that ``ev`` is an exponent vector modulo `p-1` + - ``q`` -- a prime, distinct from `p`, that is a key in the ``complement_ev_dict`` + - ``complement_ev_dict`` -- a dictionary of dictionaries, whose keys are primes. + ``complement_ev_dict[q]`` is a dictionary whose keys are exponent vectors modulo `q-1` + and whose values are lists of complementary exponent vectors modulo `q-1` OUTPUT: @@ -2072,19 +2088,35 @@ def drop_vector(ev, p, q, complement_ev_dict): .. NOTE:: - - If ``ev`` is not compatible with any of the vectors modulo ``q-1``, then it can no longer correspond to a solution + - If ``ev`` is not compatible with any of the vectors modulo `q-1`, then it can no longer correspond to a solution of the `S`-unit equation. It returns ``True`` to indicate that it should be removed. EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import drop_vector - sage: drop_vector((1, 2, 5), 7, 11, {11: {(1, 1, 3): [(1, 1, 3),(2, 3, 4)]}}) + sage: drop_vector((1, 2, 5), 7, 11, {11: {(1, 1, 3): [(1, 1, 3), (2, 3, 4)]}}) True :: - sage: P={3: {(1, 0, 0): [(1, 0, 0), (0, 1, 0)], (0, 1, 0): [(1, 0, 0), (0, 1, 0)]}, 7: {(0, 3, 4): [(0, 1, 2), (0, 3, 4), (0, 5, 0)], (1, 2, 4): [(1, 0, 4), (1, 4, 2), (1, 2, 0)], (0, 1, 2): [(0, 1, 2), (0, 3, 4), (0, 5, 0)], (0, 5, 4): [(1, 0, 0), (1, 4, 4), (1, 2, 2)], (1, 4, 2): [(1, 2, 4), (1, 4, 0), (1, 0, 2)], (1, 0, 4): [(1, 2, 4), (1, 4, 0), (1, 0, 2)], (0, 3, 2): [(1, 0, 0), (1, 4, 4), (1, 2, 2)], (1, 0, 0): [(0, 5, 4), (0, 3, 2), (0, 1, 0)], (1, 2, 0): [(1, 2, 4), (1, 4, 0), (1, 0, 2)], (0, 1, 0): [(1, 0, 0), (1, 4, 4), (1, 2, 2)], (0, 5, 0): [(0, 1, 2), (0, 3, 4), (0, 5, 0)], (1, 2, 2): [(0, 5, 4), (0, 3, 2), (0, 1, 0)], (1, 4, 0): [(1, 0, 4), (1, 4, 2), (1, 2, 0)], (1, 0, 2): [(1, 0, 4), (1, 4, 2), (1, 2, 0)], (1, 4, 4): [(0, 5, 4), (0, 3, 2), (0, 1, 0)]}} - sage: drop_vector((0,1,0),3,7,P) + sage: P = {3: {(1, 0, 0): [(1, 0, 0), (0, 1, 0)], + ....: (0, 1, 0): [(1, 0, 0), (0, 1, 0)]}, + ....: 7: {(0, 3, 4): [(0, 1, 2), (0, 3, 4), (0, 5, 0)], + ....: (1, 2, 4): [(1, 0, 4), (1, 4, 2), (1, 2, 0)], + ....: (0, 1, 2): [(0, 1, 2), (0, 3, 4), (0, 5, 0)], + ....: (0, 5, 4): [(1, 0, 0), (1, 4, 4), (1, 2, 2)], + ....: (1, 4, 2): [(1, 2, 4), (1, 4, 0), (1, 0, 2)], + ....: (1, 0, 4): [(1, 2, 4), (1, 4, 0), (1, 0, 2)], + ....: (0, 3, 2): [(1, 0, 0), (1, 4, 4), (1, 2, 2)], + ....: (1, 0, 0): [(0, 5, 4), (0, 3, 2), (0, 1, 0)], + ....: (1, 2, 0): [(1, 2, 4), (1, 4, 0), (1, 0, 2)], + ....: (0, 1, 0): [(1, 0, 0), (1, 4, 4), (1, 2, 2)], + ....: (0, 5, 0): [(0, 1, 2), (0, 3, 4), (0, 5, 0)], + ....: (1, 2, 2): [(0, 5, 4), (0, 3, 2), (0, 1, 0)], + ....: (1, 4, 0): [(1, 0, 4), (1, 4, 2), (1, 2, 0)], + ....: (1, 0, 2): [(1, 0, 4), (1, 4, 2), (1, 2, 0)], + ....: (1, 4, 4): [(0, 5, 4), (0, 3, 2), (0, 1, 0)]}} + sage: drop_vector((0, 1, 0), 3, 7, P) False """ # returns True if it is OK to drop exp_vec given the current comp_exp_vec dictionary associated to some q. @@ -2105,7 +2137,7 @@ def drop_vector(ev, p, q, complement_ev_dict): def construct_complement_dictionaries(split_primes_list, SUK, verbose=False): r""" - A function to construct the complement exponent vector dictionaries. + Construct the complement exponent vector dictionaries. INPUT: @@ -2116,15 +2148,15 @@ def construct_complement_dictionaries(split_primes_list, SUK, verbose=False): OUTPUT: A dictionary of dictionaries. The keys coincide with the primes in ``split_primes_list`` - For each ``q``, ``comp_exp_vec[q]`` is a dictionary whose keys are exponent vectors modulo ``q-1``, - and whose values are lists of exponent vectors modulo ``q-1`` + For each `q`, ``comp_exp_vec[q]`` is a dictionary whose keys are exponent vectors modulo `q-1`, + and whose values are lists of exponent vectors modulo `q-1` - If ``w`` is an exponent vector in ``comp_exp_vec[q][v]``, then the residue field vectors modulo ``q`` for - ``v`` and ``w`` sum to ``[1,1,...,1]`` + If `w` is an exponent vector in ``comp_exp_vec[q][v]``, then the residue field vectors modulo `q` for + `v` and `w` sum to ``[1,1,...,1]`` .. NOTE:: - - The data of ``comp_exp_vec`` will later be lifted to `\mathbb{Z}` to look for true `S`-Unit equation solutions. + - The data of ``comp_exp_vec`` will later be lifted to `\ZZ` to look for true `S`-Unit equation solutions. - During construction, the various dictionaries are compared to each other several times to eliminate as many mod `q` solutions as possible. - The authors acknowledge a helpful discussion with Norman Danner which helped formulate this code. @@ -2155,7 +2187,8 @@ def construct_complement_dictionaries(split_primes_list, SUK, verbose=False): ....: (1, 4, 0): [(1, 0, 4), (1, 4, 2), (1, 2, 0)], ....: (1, 4, 2): [(1, 2, 4), (1, 4, 0), (1, 0, 2)], ....: (1, 4, 4): [(0, 5, 4), (0, 3, 2), (0, 1, 0)]}} - sage: all(set(actual[p][vec]) == set(expected[p][vec]) for p in [3,7] for vec in expected[p]) + sage: all(set(actual[p][vec]) == set(expected[p][vec]) + ....: for p in [3, 7] for vec in expected[p]) True """ # We initialize some dictionaries. @@ -2318,7 +2351,7 @@ def epsilon_q(a, i): def compatible_vectors_check(a0, a1, g, l): r""" - Given exponent vectors with respect to two moduli, determines if they are compatible. + Given exponent vectors with respect to two moduli, determine if they are compatible. INPUT: @@ -2329,7 +2362,7 @@ def compatible_vectors_check(a0, a1, g, l): OUTPUT: - True if there is an integer exponent vector a satisfying + ``True`` if there is an integer exponent vector a satisfying .. MATH:: @@ -2339,7 +2372,7 @@ def compatible_vectors_check(a0, a1, g, l): a[1:] &== a1[1:] \mod m_1 \end{aligned} - and False otherwise. + and ``False`` otherwise. .. NOTE:: @@ -2363,14 +2396,14 @@ def compatible_vectors_check(a0, a1, g, l): def compatible_vectors(a, m0, m1, g): r""" - Given an exponent vector ``a`` modulo ``m0``, returns an iterator over the exponent vectors for the modulus ``m1``, such that a lift to the lcm modulus exists. + Given an exponent vector ``a`` modulo ``m0``, return an iterator over the exponent vectors for the modulus ``m1``, such that a lift to the lcm modulus exists. INPUT: - ``a`` -- an exponent vector for the modulus ``m0`` - ``m0`` -- a positive integer (specifying the modulus for ``a``) - ``m1`` -- a positive integer (specifying the alternate modulus) - - ``g`` -- the gcd of m0 and m1 + - ``g`` -- the gcd of ``m0`` and ``m1`` OUTPUT: @@ -2386,13 +2419,13 @@ def compatible_vectors(a, m0, m1, g): sage: a = (3, 1, 8, 1) sage: list(compatible_vectors(a, 18, 12, gcd(18,12))) [(3, 1, 2, 1), - (3, 1, 2, 7), - (3, 1, 8, 1), - (3, 1, 8, 7), - (3, 7, 2, 1), - (3, 7, 2, 7), - (3, 7, 8, 1), - (3, 7, 8, 7)] + (3, 1, 2, 7), + (3, 1, 8, 1), + (3, 1, 8, 7), + (3, 7, 2, 1), + (3, 7, 2, 7), + (3, 7, 8, 1), + (3, 7, 8, 7)] The order of the moduli matters. :: @@ -2408,7 +2441,7 @@ def compatible_vectors(a, m0, m1, g): def compatible_systems(split_prime_list, complement_exp_vec_dict): r""" - Given dictionaries of complement exponent vectors for various primes that split in K, compute all possible compatible systems. + Given dictionaries of complement exponent vectors for various primes that split in `K`, compute all possible compatible systems. INPUT: @@ -2421,21 +2454,21 @@ def compatible_systems(split_prime_list, complement_exp_vec_dict): .. NOTE:: - - For any ``q`` in ``split_prime_list``, ``complement_exp_vec_dict[q]`` is a dictionary whose keys are exponent vectors modulo ``q-1`` - and whose values are lists of exponent vectors modulo ``q-1`` which are complementary to the key. + - For any `q` in ``split_prime_list``, ``complement_exp_vec_dict[q]`` is a dictionary whose keys are exponent vectors modulo `q-1` + and whose values are lists of exponent vectors modulo `q-1` which are complementary to the key. - - an item in system_list has the form ``[ [v0, w0], [v1, w1], ..., [vk, wk] ]``, where:: + - An item in ``system_list`` has the form ``[ [v0, w0], [v1, w1], ..., [vk, wk] ]``, where:: - - ``qj = split_prime_list[j]`` - - ``vj`` and ``wj`` are complementary exponent vectors modulo ``qj - 1`` - - the pairs are all simultaneously compatible. + - ``qj = split_prime_list[j]`` + - ``vj`` and ``wj`` are complementary exponent vectors modulo ``qj - 1`` + - the pairs are all simultaneously compatible. - Let ``H = lcm( qj - 1 : qj in split_primes_list )``. Then for any compatible system, there is at most one pair of integer exponent vectors ``[v, w]`` such that:: - - every entry of ``v`` and ``w`` is bounded in absolute value by ``H`` - - for any ``qj``, ``v`` and ``vj`` agree modulo ``(qj - 1)`` - - for any ``qj``, ``w`` and ``wj`` agree modulo ``(qj - 1)`` + - every entry of ``v`` and ``w`` is bounded in absolute value by ``H`` + - for any ``qj``, ``v`` and ``vj`` agree modulo ``(qj - 1)`` + - for any ``qj``, ``w`` and ``wj`` agree modulo ``(qj - 1)`` EXAMPLES:: @@ -2535,14 +2568,14 @@ def compatible_system_lift(compatible_system, split_primes_list): def solutions_from_systems(SUK, bound, cs_list, split_primes_list): r""" - Lifts compatible systems to the integers and returns the S-unit equation solutions the lifts yield. + Lift compatible systems to the integers and return the `S`-unit equation solutions that the lifts yield. INPUT: - ``SUK`` -- the group of `S`-units where we search for solutions - ``bound`` -- a bound for the entries of all entries of all lifts - ``cs_list`` -- a list of compatible systems of exponent vectors modulo `q-1` for - various primes `q` + various primes `q` - ``split_primes_list`` -- a list of primes giving the moduli of the exponent vectors in ``cs_list`` OUTPUT: @@ -2565,11 +2598,11 @@ def solutions_from_systems(SUK, bound, cs_list, split_primes_list): Given a single compatible system, a solution can be found. :: sage: from sage.rings.number_field.S_unit_solver import solutions_from_systems - sage: K. = NumberField(x^2-15) + sage: K. = NumberField(x^2 - 15) sage: SUK = K.S_unit_group(S=K.primes_above(2)) sage: split_primes_list = [7, 17] sage: a_compatible_system = [[[(0, 0, 5), (0, 0, 5)], [(0, 0, 15), (0, 0, 15)]]] - sage: solutions_from_systems( SUK, 20, a_compatible_system, split_primes_list ) + sage: solutions_from_systems(SUK, 20, a_compatible_system, split_primes_list) [((0, 0, -1), (0, 0, -1), 1/2, 1/2)] """ solutions = [] @@ -2591,19 +2624,19 @@ def solutions_from_systems(SUK, bound, cs_list, split_primes_list): def clean_sfs(sfs_list): r""" - Given a list of S-unit equation solutions, remove trivial redundancies. + Given a list of `S`-unit equation solutions, remove trivial redundancies. INPUT: - - ``sfs_list`` -- a list of solutions to the S-unit equation + - ``sfs_list`` -- a list of solutions to the `S`-unit equation OUTPUT: - A list of solutions to the S-unit equation + A list of solutions to the `S`-unit equation .. NOTE:: - The function looks for cases where ``x + y = 1`` and ``y + x = 1`` appear\ + The function looks for cases where `x + y = 1` and `y + x = 1` appear as separate solutions, and removes one. EXAMPLES: @@ -2627,37 +2660,38 @@ def clean_sfs(sfs_list): def sieve_below_bound(K, S, bound=10, bump=10, split_primes_list=[], verbose=False): r""" - Return all solutions to the S-unit equation ``x + y = 1`` over K with exponents below the given bound. + Return all solutions to the `S`-unit equation `x + y = 1` over `K` with exponents below the given bound. INPUT: - ``K`` -- a number field (an absolute extension of the rationals) - - ``S`` -- a list of finite primes of ``K`` + - ``S`` -- a list of finite primes of `K` - ``bound`` -- a positive integer upper bound for exponents, solutions with exponents having absolute value below this bound will be found (default: 10) - ``bump`` -- a positive integer by which the minimum LCM will be increased if not enough split primes are found in sieving step (default: 10) - - ``split_primes_list`` -- a list of rational primes that split completely in the extension K/Q, used for sieving. For complete list of solutions should have lcm of {(p_i-1)} for primes p_i greater than bound (default: []) - - ``verbose`` -- an optional parameter allowing the user to print information during the sieving process (default: False) + - ``split_primes_list`` -- a list of rational primes that split completely in the extension `K/\QQ`, used for sieving. + For complete list of solutions should have lcm of `\{(p_i-1)\} for primes `p_i` greater than bound (default: ``[]``) + - ``verbose`` -- an optional parameter allowing the user to print information during the sieving process (default: ``False``) OUTPUT: - A list of tuples ``[( A_1, B_1, x_1, y_1), (A_2, B_2, x_2, y_2), ... ( A_n, B_n, x_n, y_n)]`` such that: + A list of tuples `[(A_1, B_1, x_1, y_1), (A_2, B_2, x_2, y_2), \dots (A_n, B_n, x_n, y_n)]` such that: - 1. The first two entries are tuples ``A_i = (a_0, a_1, ... , a_t)`` and ``B_i = (b_0, b_1, ... , b_t)`` of exponents. - 2. The last two entries are ``S``-units ``x_i`` and ``y_i`` in ``K`` with ``x_i + y_i = 1``. - 3. If the default generators for the ``S``-units of ``K`` are ``(rho_0, rho_1, ... , rho_t)``, then these satisfy ``x_i = \prod(rho_i)^(a_i)`` and ``y_i = \prod(rho_i)^(b_i)``. + 1. The first two entries are tuples `A_i = (a_0, a_1, \dots, a_t)` and `B_i = (b_0, b_1, \dots, b_t)` of exponents. + 2. The last two entries are `S`-units `x_i` and `y_i` in `K` with `x_i + y_i = 1`. + 3. If the default generators for the `S`-units of `K` are `(\rho_0, \rho_1, \dots, \rho_t)`, + then these satisfy `x_i = \prod(\rho_i)^{(a_i)}` and `y_i = \prod(\rho_i)^{(b_i)}`. EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import sieve_below_bound, eq_up_to_order - sage: K. = NumberField(x^2+x+1) - sage: SUK = UnitGroup(K,S=tuple(K.primes_above(3))) + sage: K. = NumberField(x^2 + x + 1) + sage: SUK = UnitGroup(K, S=tuple(K.primes_above(3))) sage: S = SUK.primes() sage: sols = sieve_below_bound(K, S, 10) - sage: expected = [ - ....: ((1, -1), (0, -1), 1/3*xi + 2/3, -1/3*xi + 1/3), - ....: ((0, 1), (4, 0), xi + 2, -xi - 1), - ....: ((2, 0), (5, 1), xi, -xi + 1), - ....: ((1, 0), (5, 0), xi + 1, -xi)] + sage: expected = [((1, -1), (0, -1), 1/3*xi + 2/3, -1/3*xi + 1/3), + ....: ((0, 1), (4, 0), xi + 2, -xi - 1), + ....: ((2, 0), (5, 1), xi, -xi + 1), + ....: ((1, 0), (5, 0), xi + 1, -xi)] sage: eq_up_to_order(sols, expected) True """ @@ -2687,42 +2721,41 @@ def sieve_below_bound(K, S, bound=10, bump=10, split_primes_list=[], verbose=Fal def solve_S_unit_equation(K, S, prec=106, include_exponents=True, include_bound=False, proof=None, verbose=False): r""" - Return all solutions to the S-unit equation ``x + y = 1`` over K. + Return all solutions to the `S`-unit equation `x + y = 1` over `K`. INPUT: - ``K`` -- a number field (an absolute extension of the rationals) - - ``S`` -- a list of finite primes of ``K`` + - ``S`` -- a list of finite primes of `K` - ``prec`` -- precision used for computations in real, complex, and p-adic fields (default: 106) - - ``include_exponents`` -- whether to include the exponent vectors in the returned value (default: True). - - ``include_bound`` -- whether to return the final computed bound (default: False) - - ``verbose`` -- whether to print information during the sieving step (default: False) + - ``include_exponents`` -- whether to include the exponent vectors in the returned value (default: ``True``). + - ``include_bound`` -- whether to return the final computed bound (default: ``False``) + - ``verbose`` -- whether to print information during the sieving step (default: ``False``) OUTPUT: - A list of tuples ``[( A_1, B_1, x_1, y_1), (A_2, B_2, x_2, y_2), ... ( A_n, B_n, x_n, y_n)]`` such that: + A list of tuples `[(A_1, B_1, x_1, y_1), (A_2, B_2, x_2, y_2), \dots (A_n, B_n, x_n, y_n)]` such that: - 1. The first two entries are tuples ``A_i = (a_0, a_1, ... , a_t)`` and ``B_i = (b_0, b_1, ... , b_t)`` of exponents. These will be omitted if ``include_exponents`` is ``False``. - 2. The last two entries are ``S``-units ``x_i`` and ``y_i`` in ``K`` with ``x_i + y_i = 1``. - 3. If the default generators for the ``S``-units of ``K`` are ``(rho_0, rho_1, ... , rho_t)``, then these satisfy ``x_i = \prod(rho_i)^(a_i)`` and ``y_i = \prod(rho_i)^(b_i)``. + 1. The first two entries are tuples `A_i = (a_0, a_1, \dots, a_t)` and `B_i = (b_0, b_1, \dots, b_t)` of exponents. These will be omitted if ``include_exponents`` is ``False``. + 2. The last two entries are `S`-units `x_i` and `y_i` in `K` with `x_i + y_i = 1`. + 3. If the default generators for the `S`-units of `K` are `(\rho_0, \rho_1, \dots, \rho_t)``, then these satisfy `x_i = \prod(\rho_i)^{(a_i)}` and `y_i = \prod(\rho_i)^{(b_i)}`. If ``include_bound``, will return a pair ``(sols, bound)`` where ``sols`` is as above and ``bound`` is the bound used for the entries in the exponent vectors. EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import solve_S_unit_equation, eq_up_to_order - sage: K. = NumberField(x^2+x+1) + sage: K. = NumberField(x^2 + x + 1) sage: S = K.primes_above(3) sage: sols = solve_S_unit_equation(K, S, 200) - sage: expected = [ - ....: ((0, 1), (4, 0), xi + 2, -xi - 1), - ....: ((1, -1), (0, -1), 1/3*xi + 2/3, -1/3*xi + 1/3), - ....: ((1, 0), (5, 0), xi + 1, -xi), - ....: ((2, 0), (5, 1), xi, -xi + 1)] + sage: expected = [((0, 1), (4, 0), xi + 2, -xi - 1), + ....: ((1, -1), (0, -1), 1/3*xi + 2/3, -1/3*xi + 1/3), + ....: ((1, 0), (5, 0), xi + 1, -xi), + ....: ((2, 0), (5, 1), xi, -xi + 1)] sage: eq_up_to_order(sols, expected) True - In order to see the bound as well use the optional parameter ``include_bound``:: + In order to see the bound as well, use the optional parameter ``include_bound``:: sage: solutions, bound = solve_S_unit_equation(K, S, 100, include_bound=True) sage: bound @@ -2731,7 +2764,8 @@ def solve_S_unit_equation(K, S, prec=106, include_exponents=True, include_bound= You can omit the exponent vectors:: sage: sols = solve_S_unit_equation(K, S, 200, include_exponents=False) - sage: expected = [(xi + 2, -xi - 1), (1/3*xi + 2/3, -1/3*xi + 1/3), (-xi, xi + 1), (-xi + 1, xi)] + sage: expected = [(xi + 2, -xi - 1), (1/3*xi + 2/3, -1/3*xi + 1/3), + ....: (-xi, xi + 1), (-xi + 1, xi)] sage: set(frozenset(a) for a in sols) == set(frozenset(b) for b in expected) True @@ -2740,11 +2774,12 @@ def solve_S_unit_equation(K, S, prec=106, include_exponents=True, include_bound= sage: solve_S_unit_equation(K, [3], 200) Traceback (most recent call last): ... - ValueError: S must consist only of prime ideals, or a single element from which a prime ideal can be constructed. + ValueError: S must consist only of prime ideals, + or a single element from which a prime ideal can be constructed. We check the case that the rank is 0:: - sage: K. = NumberField(x^2+x+1) + sage: K. = NumberField(x^2 + x + 1) sage: solve_S_unit_equation(K, []) [((1,), (5,), xi + 1, -xi)] """ @@ -2799,8 +2834,8 @@ def solve_S_unit_equation(K, S, prec=106, include_exponents=True, include_bound= def eq_up_to_order(A, B): """ - If A and B are lists of four-tuples ``[a0,a1,a2,a3]`` and ``[b0,b1,b2,b3]``, - checks that there is some reordering so that either ``ai=bi`` for all ``i`` or + If ``A`` and ``B`` are lists of four-tuples ``[a0,a1,a2,a3]`` and ``[b0,b1,b2,b3]``, + check that there is some reordering so that either ``ai=bi`` for all ``i`` or ``a0==b1``, ``a1==b0``, ``a2==b3``, ``a3==b2``. The entries must be hashable. @@ -2808,14 +2843,14 @@ def eq_up_to_order(A, B): EXAMPLES:: sage: from sage.rings.number_field.S_unit_solver import eq_up_to_order - sage: L = [(1,2,3,4),(5,6,7,8)] - sage: L1 = [L[1],L[0]] - sage: L2 = [(2,1,4,3),(6,5,8,7)] + sage: L = [(1,2,3,4), (5,6,7,8)] + sage: L1 = [L[1], L[0]] + sage: L2 = [(2,1,4,3), (6,5,8,7)] sage: eq_up_to_order(L, L1) True sage: eq_up_to_order(L, L2) True - sage: eq_up_to_order(L, [(1,2,4,3),(5,6,8,7)]) + sage: eq_up_to_order(L, [(1,2,4,3), (5,6,8,7)]) False """ # does not look very optimal diff --git a/src/sage/rings/number_field/bdd_height.py b/src/sage/rings/number_field/bdd_height.py index d0f37a2b192..fdb2bee52e0 100644 --- a/src/sage/rings/number_field/bdd_height.py +++ b/src/sage/rings/number_field/bdd_height.py @@ -279,9 +279,9 @@ def integer_points_in_polytope(matrix, interval_radius): Return the set of integer points in the polytope obtained by acting on a cube by a linear transformation. - Given an r-by-r matrix ``matrix`` and a real number ``interval_radius``, + Given an `r`-by-`r` matrix ``matrix`` and a real number ``interval_radius``, this function finds all integer lattice points in the polytope obtained by - transforming the cube [-interval_radius,interval_radius]^r via the linear + transforming the cube ``[-interval_radius, interval_radius]^r`` via the linear map induced by ``matrix``. INPUT: @@ -296,37 +296,38 @@ def integer_points_in_polytope(matrix, interval_radius): EXAMPLES: - Stretch the interval [-1,1] by a factor of 2 and find the integers in the + Stretch the interval `[-1,1]` by a factor of 2 and find the integers in the resulting interval:: sage: from sage.rings.number_field.bdd_height import integer_points_in_polytope sage: m = matrix([2]) sage: r = 1 - sage: integer_points_in_polytope(m,r) + sage: integer_points_in_polytope(m, r) [(-2), (-1), (0), (1), (2)] Integer points inside a parallelogram:: sage: from sage.rings.number_field.bdd_height import integer_points_in_polytope - sage: m = matrix([[1, 2],[3, 4]]) + sage: m = matrix([[1, 2], [3, 4]]) sage: r = RealField()(1.3) - sage: integer_points_in_polytope(m,r) - [(-3, -7), (-2, -5), (-2, -4), (-1, -3), (-1, -2), (-1, -1), (0, -1), (0, 0), (0, 1), (1, 1), (1, 2), (1, 3), (2, 4), (2, 5), (3, 7)] + sage: integer_points_in_polytope(m, r) + [(-3, -7), (-2, -5), (-2, -4), (-1, -3), (-1, -2), (-1, -1), (0, -1), + (0, 0), (0, 1), (1, 1), (1, 2), (1, 3), (2, 4), (2, 5), (3, 7)] Integer points inside a parallelepiped:: sage: from sage.rings.number_field.bdd_height import integer_points_in_polytope - sage: m = matrix([[1.2,3.7,0.2],[-5.3,-.43,3],[1.2,4.7,-2.1]]) + sage: m = matrix([[1.2,3.7,0.2], [-5.3,-.43,3], [1.2,4.7,-2.1]]) sage: r = 2.2 - sage: L = integer_points_in_polytope(m,r) + sage: L = integer_points_in_polytope(m, r) sage: len(L) 4143 If ``interval_radius`` is 0, the output should include only the zero tuple:: sage: from sage.rings.number_field.bdd_height import integer_points_in_polytope - sage: m = matrix([[1,2,3,7],[4,5,6,2],[7,8,9,3],[0,3,4,5]]) - sage: integer_points_in_polytope(m,0) + sage: m = matrix([[1,2,3,7], [4,5,6,2], [7,8,9,3], [0,3,4,5]]) + sage: integer_points_in_polytope(m, 0) [(0, 0, 0, 0)] """ T = matrix @@ -350,15 +351,15 @@ def bdd_height(K, height_bound, tolerance=1e-2, precision=53): multiplicative height at most ``height_bound``. The function can only be called for number fields `K` with positive unit - rank. An error will occur if `K` is `QQ` or an imaginary quadratic field. + rank. An error will occur if `K` is `\QQ` or an imaginary quadratic field. - This algorithm computes 2 lists: L containing elements x in `K` such that - H_k(x) <= B, and a list L' containing elements x in `K` that, due to + This algorithm computes 2 lists: `L`, containing elements `x` in `K` such that + `H_k(x) \leq B`, and a list `L'` containing elements `x` in `K` that, due to floating point issues, may be slightly larger then the bound. This can be controlled by lowering the tolerance. - In current implementation both lists (L,L') are merged and returned in + In current implementation both lists `(L,L')` are merged and returned in form of iterator. ALGORITHM: @@ -376,7 +377,7 @@ def bdd_height(K, height_bound, tolerance=1e-2, precision=53): OUTPUT: - - an iterator of number field elements + an iterator of number field elements EXAMPLES: @@ -384,35 +385,35 @@ def bdd_height(K, height_bound, tolerance=1e-2, precision=53): sage: from sage.rings.number_field.bdd_height import bdd_height sage: K. = NumberField(x^5 - x + 7) - sage: list(bdd_height(K,-3)) + sage: list(bdd_height(K, -3)) [] The only nonzero elements of height 1 are the roots of unity:: sage: from sage.rings.number_field.bdd_height import bdd_height sage: K. = QuadraticField(3) - sage: list(bdd_height(K,1)) + sage: list(bdd_height(K, 1)) [0, -1, 1] :: sage: from sage.rings.number_field.bdd_height import bdd_height sage: K. = QuadraticField(36865) - sage: len(list(bdd_height(K,101))) # long time (4 s) + sage: len(list(bdd_height(K, 101))) # long time (4 s) 131 :: sage: from sage.rings.number_field.bdd_height import bdd_height sage: K. = NumberField(x^6 + 2) - sage: len(list(bdd_height(K,60))) # long time (5 s) + sage: len(list(bdd_height(K, 60))) # long time (5 s) 1899 :: sage: from sage.rings.number_field.bdd_height import bdd_height sage: K. = NumberField(x^4 - x^3 - 3*x^2 + x + 1) - sage: len(list(bdd_height(K,10))) + sage: len(list(bdd_height(K, 10))) 99 TESTS: @@ -454,14 +455,14 @@ def rational_in(x, y): def delta_approximation(x, delta): r""" - Compute a rational number in range `(x-delta, x+delta)` + Compute a rational number in range `(x-\delta, x+\delta)` """ return rational_in(x - delta, x + delta) def vector_delta_approximation(v, delta): r""" Compute a rational vector `w=(w_1, ..., w_n)` - such that `|v_i-w_i|=QuadraticField(-23) - sage: OK=K.ring_of_integers() - sage: C=OK.class_group() - sage: P2a,P2b=[P for P,e in (2*OK).factor()] - sage: c = C(P2a); c - Fractional ideal class (2, 1/2*w - 1/2) - sage: c.gens() - (2, 1/2*w - 1/2) + sage: K. = QuadraticField(-23) + sage: OK = K.ring_of_integers() + sage: C = OK.class_group() + sage: P2a, P2b = [P for P, e in (2*OK).factor()] + sage: c = C(P2a); c + Fractional ideal class (2, 1/2*w - 1/2) + sage: c.gens() + (2, 1/2*w - 1/2) """ def __init__(self, parent, element, ideal=None): """ - Returns the ideal class of this fractional ideal. + Return the ideal class of this fractional ideal. EXAMPLES:: @@ -108,7 +107,8 @@ def _mul_(self, other): EXAMPLES:: sage: G = NumberField(x^2 + 23,'a').class_group(); G - Class group of order 3 with structure C3 of Number Field in a with defining polynomial x^2 + 23 + Class group of order 3 with structure C3 of + Number Field in a with defining polynomial x^2 + 23 sage: I = G.0; I Fractional ideal class (2, 1/2*a - 1/2) sage: I*I # indirect doctest @@ -135,7 +135,8 @@ def _div_(self, other): EXAMPLES:: sage: G = NumberField(x^2 + 23,'a').class_group(); G - Class group of order 3 with structure C3 of Number Field in a with defining polynomial x^2 + 23 + Class group of order 3 with structure C3 of + Number Field in a with defining polynomial x^2 + 23 sage: I = G.0; I Fractional ideal class (2, 1/2*a - 1/2) sage: I*I # indirect doctest @@ -154,7 +155,7 @@ def __pow__(self, n): EXAMPLES:: sage: K. = NumberField(x^3 - 3*x + 8) - sage: C=K.class_group() + sage: C = K.class_group() sage: c = C(2, a) sage: c^2 Fractional ideal class (4, a) @@ -192,15 +193,15 @@ def inverse(self): def is_principal(self): r""" - Returns True iff this ideal class is the trivial (principal) class + Return ``True`` iff this ideal class is the trivial (principal) class. EXAMPLES:: - sage: K.=QuadraticField(-23) - sage: OK=K.ring_of_integers() - sage: C=OK.class_group() - sage: P2a,P2b=[P for P,e in (2*OK).factor()] - sage: c=C(P2a) + sage: K. = QuadraticField(-23) + sage: OK = K.ring_of_integers() + sage: C = OK.class_group() + sage: P2a, P2b = [P for P, e in (2*OK).factor()] + sage: c = C(P2a) sage: c.is_principal() False sage: (c^2).is_principal() @@ -218,8 +219,8 @@ def reduce(self): EXAMPLES:: sage: k. = NumberField(x^2 + 20072); G = k.class_group(); G - Class group of order 76 with structure C38 x C2 - of Number Field in a with defining polynomial x^2 + 20072 + Class group of order 76 with structure C38 x C2 of + Number Field in a with defining polynomial x^2 + 20072 sage: I = (G.0)^11; I Fractional ideal class (33, 1/2*a + 8) sage: J = G(I.ideal()^5); J @@ -237,11 +238,11 @@ def ideal(self): EXAMPLES:: - sage: K.=QuadraticField(-23) - sage: OK=K.ring_of_integers() - sage: C=OK.class_group() - sage: P2a,P2b=[P for P,e in (2*OK).factor()] - sage: c=C(P2a); c + sage: K. = QuadraticField(-23) + sage: OK = K.ring_of_integers() + sage: C = OK.class_group() + sage: P2a, P2b = [P for P, e in (2*OK).factor()] + sage: c = C(P2a); c Fractional ideal class (2, 1/2*w - 1/2) sage: c.ideal() Fractional ideal (2, 1/2*w - 1/2) @@ -254,31 +255,31 @@ def representative_prime(self, norm_bound=1000): INPUT: - ``norm_bound`` (positive integer) -- upper bound on the norm of primes tested. + - ``norm_bound`` -- (positive integer) upper bound on the norm of primes tested. EXAMPLES:: - sage: K. = NumberField(x^2+31) + sage: K. = NumberField(x^2 + 31) sage: K.class_number() 3 sage: Cl = K.class_group() sage: [c.representative_prime() for c in Cl] [Fractional ideal (3), - Fractional ideal (2, 1/2*a + 1/2), - Fractional ideal (2, 1/2*a - 1/2)] + Fractional ideal (2, 1/2*a + 1/2), + Fractional ideal (2, 1/2*a - 1/2)] - sage: K. = NumberField(x^2+223) + sage: K. = NumberField(x^2 + 223) sage: K.class_number() 7 sage: Cl = K.class_group() sage: [c.representative_prime() for c in Cl] [Fractional ideal (3), - Fractional ideal (2, 1/2*a + 1/2), - Fractional ideal (17, 1/2*a + 7/2), - Fractional ideal (7, 1/2*a - 1/2), - Fractional ideal (7, 1/2*a + 1/2), - Fractional ideal (17, 1/2*a + 27/2), - Fractional ideal (2, 1/2*a - 1/2)] + Fractional ideal (2, 1/2*a + 1/2), + Fractional ideal (17, 1/2*a + 7/2), + Fractional ideal (7, 1/2*a - 1/2), + Fractional ideal (7, 1/2*a + 1/2), + Fractional ideal (17, 1/2*a + 27/2), + Fractional ideal (2, 1/2*a - 1/2)] """ if self.value().is_prime(): return self.value() @@ -297,14 +298,14 @@ def representative_prime(self, norm_bound=1000): def gens(self): r""" Return generators for a representative ideal in this - (S-)ideal class. + (`S`-)ideal class. EXAMPLES:: - sage: K.=QuadraticField(-23) + sage: K. = QuadraticField(-23) sage: OK = K.ring_of_integers() sage: C = OK.class_group() - sage: P2a,P2b=[P for P,e in (2*OK).factor()] + sage: P2a, P2b = [P for P, e in (2*OK).factor()] sage: c = C(P2a); c Fractional ideal class (2, 1/2*w - 1/2) sage: c.gens() @@ -315,48 +316,47 @@ def gens(self): class SFractionalIdealClass(FractionalIdealClass): r""" - An S-fractional ideal class in a number field for a tuple of primes S. - - EXAMPLES:: + An `S`-fractional ideal class in a number field for a tuple `S` of primes. - sage: K. = QuadraticField(-14) - sage: I = K.ideal(2,a) - sage: S = (I,) - sage: CS = K.S_class_group(S) - sage: J = K.ideal(7,a) - sage: G = K.ideal(3,a+1) - sage: CS(I) - Trivial S-ideal class - sage: CS(J) - Trivial S-ideal class - sage: CS(G) - Fractional S-ideal class (3, a + 1) + EXAMPLES:: - EXAMPLES:: + sage: K. = QuadraticField(-14) + sage: I = K.ideal(2, a) + sage: S = (I,) + sage: CS = K.S_class_group(S) + sage: J = K.ideal(7, a) + sage: G = K.ideal(3, a + 1) + sage: CS(I) + Trivial S-ideal class + sage: CS(J) + Trivial S-ideal class + sage: CS(G) + Fractional S-ideal class (3, a + 1) - sage: K. = QuadraticField(-14) - sage: I = K.ideal(2,a) - sage: S = (I,) - sage: CS = K.S_class_group(S) - sage: J = K.ideal(7,a) - sage: G = K.ideal(3,a+1) - sage: CS(I).ideal() - Fractional ideal (2, a) - sage: CS(J).ideal() - Fractional ideal (7, a) - sage: CS(G).ideal() - Fractional ideal (3, a + 1) + :: + sage: K. = QuadraticField(-14) + sage: I = K.ideal(2, a) + sage: S = (I,) + sage: CS = K.S_class_group(S) + sage: J = K.ideal(7, a) + sage: G = K.ideal(3, a + 1) + sage: CS(I).ideal() + Fractional ideal (2, a) + sage: CS(J).ideal() + Fractional ideal (7, a) + sage: CS(G).ideal() + Fractional ideal (3, a + 1) - EXAMPLES:: + :: - sage: K. = QuadraticField(-14) - sage: I = K.ideal(2,a) - sage: S = (I,) - sage: CS = K.S_class_group(S) - sage: G = K.ideal(3,a+1) - sage: CS(G).inverse() - Fractional S-ideal class (3, a + 2) + sage: K. = QuadraticField(-14) + sage: I = K.ideal(2, a) + sage: S = (I,) + sage: CS = K.S_class_group(S) + sage: G = K.ideal(3, a + 1) + sage: CS(G).inverse() + Fractional S-ideal class (3, a + 2) TESTS:: @@ -376,7 +376,7 @@ class SFractionalIdealClass(FractionalIdealClass): def _repr_(self): r""" - Returns a string representation of the S-ideal class of this fractional ideal. + Return a string representation of the `S`-ideal class of this fractional ideal. EXAMPLES:: @@ -403,7 +403,8 @@ class ClassGroup(AbelianGroupWithValues_class): sage: K. = NumberField(x^2 + 23) sage: G = K.class_group(); G - Class group of order 3 with structure C3 of Number Field in a with defining polynomial x^2 + 23 + Class group of order 3 with structure C3 of + Number Field in a with defining polynomial x^2 + 23 sage: G.category() Category of finite enumerated commutative groups @@ -482,7 +483,7 @@ def _ideal_log(self, ideal): EXAMPLES:: - sage: K. = NumberField(x^2 + 23,'a') + sage: K. = NumberField(x^2 + 23, 'a') sage: G = K.class_group() sage: g = G.an_element() sage: G._ideal_log(g.ideal()) @@ -494,7 +495,7 @@ def _ideal_log(self, ideal): def gens_ideals(self): r""" - Return generating ideals for the (S-)class group. + Return generating ideals for the (`S`-)class group. This is an alias for :meth:`gens_values`. @@ -581,7 +582,7 @@ def _iter_inner(self, i0, k): def _repr_(self): r""" - Return string representation of self. + Return string representation of ``self``. EXAMPLES:: @@ -597,12 +598,13 @@ def _repr_(self): def number_field(self): r""" - Return the number field that this (S-)class group is attached to. + Return the number field that this (`S`-)class group is attached to. EXAMPLES:: sage: C = NumberField(x^2 + 23, 'w').class_group(); C - Class group of order 3 with structure C3 of Number Field in w with defining polynomial x^2 + 23 + Class group of order 3 with structure C3 of + Number Field in w with defining polynomial x^2 + 23 sage: C.number_field() Number Field in w with defining polynomial x^2 + 23 @@ -616,7 +618,7 @@ def number_field(self): class SClassGroup(ClassGroup): r""" - The S-class group of a number field. + The `S`-class group of a number field. EXAMPLES:: @@ -627,7 +629,8 @@ class SClassGroup(ClassGroup): sage: K. = QuadraticField(-974) sage: CS = K.S_class_group(K.primes_above(2)); CS - S-class group of order 18 with structure C6 x C3 of Number Field in a with defining polynomial x^2 + 974 with a = 31.20897306865447?*I + S-class group of order 18 with structure C6 x C3 of + Number Field in a with defining polynomial x^2 + 974 with a = 31.20897306865447?*I sage: CS.gen(0) # random Fractional S-ideal class (3, a + 2) sage: CS.gen(1) # random @@ -637,7 +640,7 @@ class SClassGroup(ClassGroup): def __init__(self, gens_orders, names, number_field, gens, S, proof=True): r""" - Create an S-class group. + Create an `S`-class group. EXAMPLES:: @@ -663,13 +666,15 @@ def S(self): EXAMPLES:: sage: K. = QuadraticField(-14) - sage: I = K.ideal(2,a) + sage: I = K.ideal(2, a) sage: S = (I,) sage: CS = K.S_class_group(S);CS - S-class group of order 2 with structure C2 of Number Field in a with defining polynomial x^2 + 14 with a = 3.741657386773942?*I + S-class group of order 2 with structure C2 of + Number Field in a with defining polynomial x^2 + 14 with a = 3.741657386773942?*I sage: T = tuple() sage: CT = K.S_class_group(T);CT - S-class group of order 4 with structure C4 of Number Field in a with defining polynomial x^2 + 14 with a = 3.741657386773942?*I + S-class group of order 4 with structure C4 of + Number Field in a with defining polynomial x^2 + 14 with a = 3.741657386773942?*I sage: CS.S() (Fractional ideal (2, a),) sage: CT.S() diff --git a/src/sage/rings/number_field/galois_group.py b/src/sage/rings/number_field/galois_group.py index 1bf6189b7d9..7dbb4d24c91 100644 --- a/src/sage/rings/number_field/galois_group.py +++ b/src/sage/rings/number_field/galois_group.py @@ -49,7 +49,8 @@ class GaloisGroup_v1(SageObject): sage: G = GaloisGroup_v1(K.absolute_polynomial().galois_group(pari_group=True), K); G ...DeprecationWarning: GaloisGroup_v1 is deprecated; please use GaloisGroup_v2 See https://github.com/sagemath/sage/issues/28782 for details. - Galois group PARI group [6, -1, 2, "S3"] of degree 3 of the Number Field in a with defining polynomial x^3 - 2 with a = 1.259921049894873? + Galois group PARI group [6, -1, 2, "S3"] of degree 3 of the + Number Field in a with defining polynomial x^3 - 2 with a = 1.259921049894873? sage: G.order() 6 sage: G.group() @@ -69,7 +70,8 @@ def __init__(self, group, number_field): sage: GaloisGroup_v1(K.absolute_polynomial().galois_group(pari_group=True), K) ...DeprecationWarning: GaloisGroup_v1 is deprecated; please use GaloisGroup_v2 See https://github.com/sagemath/sage/issues/28782 for details. - Galois group PARI group [4, 1, 2, "E(4) = 2[x]2"] of degree 4 of the Number Field in a0 with defining polynomial x^2 + 1 over its base field + Galois group PARI group [4, 1, 2, "E(4) = 2[x]2"] of degree 4 of the + Number Field in a0 with defining polynomial x^2 + 1 over its base field """ deprecation(28782, "GaloisGroup_v1 is deprecated; please use GaloisGroup_v2") self.__group = group @@ -178,7 +180,8 @@ def order(self): sage: G = GaloisGroup_v1(K.absolute_polynomial().galois_group(pari_group=True), K); G ...DeprecationWarning: GaloisGroup_v1 is deprecated; please use GaloisGroup_v2 See https://github.com/sagemath/sage/issues/28782 for details. - Galois group PARI group [20, -1, 3, "F(5) = 5:4"] of degree 5 of the Number Field in theta_1 with defining polynomial x^5 + 2 + Galois group PARI group [20, -1, 3, "F(5) = 5:4"] of degree 5 of the + Number Field in theta_1 with defining polynomial x^5 + 2 sage: G.order() 20 """ @@ -195,7 +198,8 @@ def number_field(self): sage: G = GaloisGroup_v1(K.absolute_polynomial().galois_group(pari_group=True), K); G ...DeprecationWarning: GaloisGroup_v1 is deprecated; please use GaloisGroup_v2 See https://github.com/sagemath/sage/issues/28782 for details. - Galois group PARI group [12, -1, 3, "D(6) = S(3)[x]2"] of degree 6 of the Number Field in t with defining polynomial x^6 + 2 + Galois group PARI group [12, -1, 3, "D(6) = S(3)[x]2"] of degree 6 of the + Number Field in t with defining polynomial x^6 + 2 sage: G.number_field() Number Field in t with defining polynomial x^6 + 2 """ @@ -208,10 +212,10 @@ class GaloisGroup_v2(GaloisGroup_perm): .. NOTE:: - We define the Galois group of a non-normal field K to be the - Galois group of its Galois closure L, and elements are stored as - permutations of the roots of the defining polynomial of L, *not* as - permutations of the roots (in L) of the defining polynomial of K. The + We define the Galois group of a non-normal field `K` to be the + Galois group of its Galois closure `L`, and elements are stored as + permutations of the roots of the defining polynomial of `L`, *not* as + permutations of the roots (in `L`) of the defining polynomial of `K`. The latter would probably be preferable, but is harder to implement. Thus the permutation group that is returned is always simply-transitive. @@ -222,7 +226,8 @@ class GaloisGroup_v2(GaloisGroup_perm): sage: G = NumberField(x^3 - x - 1, 'a').galois_closure('b').galois_group() sage: G.subgroup([G([(1,2,3),(4,5,6)])]) - Subgroup generated by [(1,2,3)(4,5,6)] of (Galois group 6T2 ([3]2) with order 6 of x^6 - 6*x^4 + 9*x^2 + 23) + Subgroup generated by [(1,2,3)(4,5,6)] of + (Galois group 6T2 ([3]2) with order 6 of x^6 - 6*x^4 + 9*x^2 + 23) Subgroups can be specified using generators (:trac:`26816`):: @@ -314,7 +319,7 @@ def _pol_galgp(self, algorithm=None): def group(self): """ - While GaloisGroup_v1 is being deprecated, this provides public access to the Pari/GAP group + While :class:`GaloisGroup_v1` is being deprecated, this provides public access to the PARI/GAP group in order to keep all aspects of that API. EXAMPLES:: @@ -325,7 +330,8 @@ def group(self): ...DeprecationWarning: the different Galois types have been merged into one class See https://github.com/sagemath/sage/issues/28782 for details. sage: G.group() - ...DeprecationWarning: the group method is deprecated; you can use _pol_galgp if you really need it + ...DeprecationWarning: the group method is deprecated; + you can use _pol_galgp if you really need it See https://github.com/sagemath/sage/issues/28782 for details. PARI group [6, -1, 2, "S3"] of degree 3 """ @@ -379,7 +385,7 @@ def easy_order(self, algorithm=None): @cached_method(key=_alg_key) def transitive_number(self, algorithm=None, recompute=False): """ - Regardless of the value of ``gc_numbering``, this gives the transitive number + Regardless of the value of ``gc_numbering``, give the transitive number for the action on the roots of the defining polynomial of the original number field, not the Galois closure. @@ -413,7 +419,7 @@ def transitive_number(self, algorithm=None, recompute=False): def pari_label(self): """ - Return the label assigned by Pari for this Galois group, an attempt at giving a human readable description of the group. + Return the label assigned by PARI for this Galois group, an attempt at giving a human readable description of the group. EXAMPLES:: @@ -430,7 +436,7 @@ def pari_label(self): @cached_method def signature(self): """ - Return 1 if contained in the alternating group, -1 otherwise. + Return `1` if contained in the alternating group, `-1` otherwise. EXAMPLES:: @@ -455,7 +461,7 @@ def signature(self): @lazy_attribute def _gcdata(self): """ - Return the galois closure, together with the embedding of the top field into it + Return the Galois closure, together with the embedding of the top field into it EXAMPLES:: @@ -506,7 +512,7 @@ def _gcdata(self): @lazy_attribute def _pari_data(self): """ - Return the corresponding Pari Galois group structure. + Return the corresponding PARI Galois group structure. EXAMPLES:: @@ -548,7 +554,7 @@ def _elts(self): @lazy_attribute def _gens(self): """ - Computes the generators as permutations. + Compute the generators as permutations. EXAMPLES:: @@ -641,7 +647,7 @@ def _element_constructor_(self, x, check=True): def is_galois(self): r""" - Whether the underlying number field is Galois + Whether the underlying number field is Galois. EXAMPLES:: @@ -697,7 +703,7 @@ def number_field(self): def list(self): r""" - List of the elements of self. + List of the elements of ``self``. EXAMPLES:: @@ -708,12 +714,12 @@ def list(self): def unrank(self, i): r""" - Return the ``i``-th element of ``self``. + Return the `i`-th element of ``self``. INPUT: - - ``i`` -- integer between ``0`` and ``n-1`` where - ``n`` is the cardinality of this set + - ``i`` -- integer between `0` and `n-1` where + `n` is the cardinality of this set EXAMPLES:: @@ -777,22 +783,23 @@ def _ramgroups(self, P): def decomposition_group(self, P): r""" - Decomposition group of a prime ideal P, i.e. the subgroup of elements - that map P to itself. This is the same as the Galois group of the - extension of local fields obtained by completing at P. + Decomposition group of a prime ideal `P`, i.e., the subgroup of elements + that map `P` to itself. This is the same as the Galois group of the + extension of local fields obtained by completing at `P`. - This function will raise an error if P is not prime or the given number + This function will raise an error if `P` is not prime or the given number field is not Galois. - P can also be an infinite prime, i.e. an embedding into `\RR` or `\CC`. + `P` can also be an infinite prime, i.e., an embedding into `\RR` or `\CC`. EXAMPLES:: - sage: K. = NumberField(x^4 - 2*x^2 + 2,'b').galois_closure() + sage: K. = NumberField(x^4 - 2*x^2 + 2, 'b').galois_closure() sage: P = K.ideal([17, a^2]) sage: G = K.galois_group() sage: G.decomposition_group(P) - Subgroup generated by [(1,8)(2,7)(3,6)(4,5)] of (Galois group 8T4 ([4]2) with order 8 of x^8 - 20*x^6 + 104*x^4 - 40*x^2 + 1156) + Subgroup generated by [(1,8)(2,7)(3,6)(4,5)] of + (Galois group 8T4 ([4]2) with order 8 of x^8 - 20*x^6 + 104*x^4 - 40*x^2 + 1156) sage: G.decomposition_group(P^2) Traceback (most recent call last): ... @@ -804,7 +811,7 @@ def decomposition_group(self, P): An example with an infinite place:: - sage: L. = NumberField(x^3 - 2,'a').galois_closure(); G=L.galois_group() + sage: L. = NumberField(x^3 - 2,'a').galois_closure(); G = L.galois_group() sage: x = L.places()[0] sage: G.decomposition_group(x).order() 2 @@ -822,8 +829,8 @@ def decomposition_group(self, P): def complex_conjugation(self, P=None): """ - Return the unique element of self corresponding to complex conjugation, - for a specified embedding P into the complex numbers. If P is not + Return the unique element of ``self`` corresponding to complex conjugation, + for a specified embedding `P` into the complex numbers. If `P` is not specified, use the "standard" embedding, whenever that is well-defined. EXAMPLES:: @@ -838,7 +845,7 @@ def complex_conjugation(self, P=None): An example where the field is not CM, so complex conjugation really depends on the choice of embedding:: - sage: L = NumberField(x^6 + 40*x^3 + 1372,'a') + sage: L = NumberField(x^6 + 40*x^3 + 1372, 'a') sage: G = L.galois_group() sage: [G.complex_conjugation(x) for x in L.places()] [(1,3)(2,6)(4,5), (1,5)(2,4)(3,6), (1,2)(3,4)(5,6)] @@ -865,17 +872,18 @@ def complex_conjugation(self, P=None): def ramification_group(self, P, v): """ - Return the vth ramification group of self for the prime P, i.e. the set - of elements s of self such that s acts trivially modulo P^(v+1). This + Return the `v`-th ramification group of ``self`` for the prime `P`, i.e., the set + of elements `s` of ``self`` such that `s` acts trivially modulo `P^{(v+1)}`. This is only defined for Galois fields. EXAMPLES:: - sage: K. = NumberField(x^3 - 3,'a').galois_closure() + sage: K. = NumberField(x^3 - 3, 'a').galois_closure() sage: G=K.galois_group() sage: P = K.primes_above(3)[0] sage: G.ramification_group(P, 3) - Subgroup generated by [(1,2,4)(3,5,6)] of (Galois group 6T2 ([3]2) with order 6 of x^6 + 243) + Subgroup generated by [(1,2,4)(3,5,6)] of + (Galois group 6T2 ([3]2) with order 6 of x^6 + 243) sage: G.ramification_group(P, 5) Subgroup generated by [()] of (Galois group 6T2 ([3]2) with order 6 of x^6 + 243) """ @@ -891,12 +899,12 @@ def ramification_group(self, P, v): def inertia_group(self, P): """ - Return the inertia group of the prime P, i.e. the group of elements acting - trivially modulo P. This is just the 0th ramification group of P. + Return the inertia group of the prime `P`, i.e., the group of elements acting + trivially modulo `P`. This is just the 0th ramification group of `P`. EXAMPLES:: - sage: K. = NumberField(x^2 - 3,'a') + sage: K. = NumberField(x^2 - 3, 'a') sage: G = K.galois_group() sage: G.inertia_group(K.primes_above(2)[0]) Subgroup generated by [(1,2)] of (Galois group 2T1 (S2) with order 2 of x^2 - 3) @@ -909,8 +917,8 @@ def inertia_group(self, P): def ramification_breaks(self, P): r""" - Return the set of ramification breaks of the prime ideal P, i.e. the - set of indices i such that the ramification group `G_{i+1} \ne G_{i}`. + Return the set of ramification breaks of the prime ideal `P`, i.e., the + set of indices `i` such that the ramification group `G_{i+1} \ne G_{i}`. This is only defined for Galois fields. EXAMPLES:: @@ -920,7 +928,9 @@ def ramification_breaks(self, P): sage: P = K.primes_above(2)[0] sage: G.ramification_breaks(P) {1, 3, 5} - sage: min( [ G.ramification_group(P, i).order() / G.ramification_group(P, i+1).order() for i in G.ramification_breaks(P)] ) + sage: min(G.ramification_group(P, i).order() + ....: / G.ramification_group(P, i + 1).order() + ....: for i in G.ramification_breaks(P)) 2 """ if not self.is_galois(): @@ -934,17 +944,18 @@ def ramification_breaks(self, P): def artin_symbol(self, P): r""" Return the Artin symbol `\left(\frac{K / - \QQ}{\mathfrak{P}}\right)`, where K is the number field of self, + \QQ}{\mathfrak{P}}\right)`, where `K` is the number field of ``self``, and `\mathfrak{P}` is an unramified prime ideal. This is the unique - element s of the decomposition group of `\mathfrak{P}` such that `s(x) = x^p \bmod - \mathfrak{P}`, where p is the residue characteristic of `\mathfrak{P}`. + element `s` of the decomposition group of `\mathfrak{P}` such that `s(x) = x^p \bmod + \mathfrak{P}`, where `p` is the residue characteristic of `\mathfrak{P}`. EXAMPLES:: sage: K. = NumberField(x^4 - 2*x^2 + 2, 'a').galois_closure() sage: G = K.galois_group() sage: [G.artin_symbol(P) for P in K.primes_above(7)] - [(1,4)(2,3)(5,8)(6,7), (1,4)(2,3)(5,8)(6,7), (1,5)(2,6)(3,7)(4,8), (1,5)(2,6)(3,7)(4,8)] + [(1,4)(2,3)(5,8)(6,7), (1,4)(2,3)(5,8)(6,7), + (1,5)(2,6)(3,7)(4,8), (1,5)(2,6)(3,7)(4,8)] sage: G.artin_symbol(17) Traceback (most recent call last): ... @@ -990,7 +1001,7 @@ class GaloisGroup_subgroup(GaloisSubgroup_perm): - ``category`` -- the category for this object - - ``canonicalize`` -- if true, sorts and removes duplicates + - ``canonicalize`` -- if ``True``, sorts and removes duplicates - ``check`` -- whether to check that generators actually lie in the ambient group @@ -999,9 +1010,10 @@ class GaloisGroup_subgroup(GaloisSubgroup_perm): sage: from sage.rings.number_field.galois_group import GaloisGroup_subgroup sage: G = NumberField(x^3 - x - 1, 'a').galois_closure('b').galois_group() sage: GaloisGroup_subgroup( G, [G([(1,2,3),(4,5,6)])]) - Subgroup generated by [(1,2,3)(4,5,6)] of (Galois group 6T2 ([3]2) with order 6 of x^6 - 6*x^4 + 9*x^2 + 23) + Subgroup generated by [(1,2,3)(4,5,6)] of + (Galois group 6T2 ([3]2) with order 6 of x^6 - 6*x^4 + 9*x^2 + 23) - sage: K. = NumberField(x^6-3*x^2-1) + sage: K. = NumberField(x^6 - 3*x^2 - 1) sage: L. = K.galois_closure() sage: G = L.galois_group() sage: P = L.primes_above(3)[0] @@ -1012,7 +1024,8 @@ class GaloisGroup_subgroup(GaloisSubgroup_perm): sage: G = NumberField(x^3 - x - 1, 'a').galois_closure('b').galois_group() sage: H = G.subgroup([G([(1,2,3),(4,5,6)])]) sage: H - Subgroup generated by [(1,2,3)(4,5,6)] of (Galois group 6T2 ([3]2) with order 6 of x^6 - 6*x^4 + 9*x^2 + 23) + Subgroup generated by [(1,2,3)(4,5,6)] of + (Galois group 6T2 ([3]2) with order 6 of x^6 - 6*x^4 + 9*x^2 + 23) TESTS: @@ -1030,7 +1043,7 @@ class GaloisGroup_subgroup(GaloisSubgroup_perm): @lazy_attribute def _pari_data(self): """ - Access to Pari information for the ambient Galois group. + Access to PARI information for the ambient Galois group. EXAMPLES:: @@ -1052,7 +1065,7 @@ def fixed_field(self, name=None, polred=None, threshold=None): - ``name`` -- a variable name for the new field. - ``polred`` -- whether to optimize the generator of the newly created field - for a simpler polynomial, using pari's polredbest. + for a simpler polynomial, using PARI's :pari:`polredbest`. Defaults to ``True`` when the degree of the fixed field is at most 8. - ``threshold`` -- positive number; polred only performed if the cost is at most this threshold @@ -1077,28 +1090,32 @@ def fixed_field(self, name=None, polred=None, threshold=None): sage: sigma, tau = G.gens() sage: H = G.subgroup([tau]) sage: H.fixed_field(polred=False) - (Number Field in a0 with defining polynomial x^2 + 84375 with a0 = 5*ac^5 + 25*ac^3, + (Number Field in a0 with defining polynomial x^2 + 84375 + with a0 = 5*ac^5 + 25*ac^3, Ring morphism: - From: Number Field in a0 with defining polynomial x^2 + 84375 with a0 = 5*ac^5 + 25*ac^3 + From: Number Field in a0 with defining polynomial x^2 + 84375 + with a0 = 5*ac^5 + 25*ac^3 To: Number Field in ac with defining polynomial x^10 + 10*x^8 + 25*x^6 + 3375 Defn: a0 |--> 5*ac^5 + 25*ac^3) sage: H.fixed_field(polred=True) - (Number Field in a0 with defining polynomial x^2 - x + 4 with a0 = -1/30*ac^5 - 1/6*ac^3 + 1/2, + (Number Field in a0 with defining polynomial x^2 - x + 4 + with a0 = -1/30*ac^5 - 1/6*ac^3 + 1/2, Ring morphism: - From: Number Field in a0 with defining polynomial x^2 - x + 4 with a0 = -1/30*ac^5 - 1/6*ac^3 + 1/2 + From: Number Field in a0 with defining polynomial x^2 - x + 4 + with a0 = -1/30*ac^5 - 1/6*ac^3 + 1/2 To: Number Field in ac with defining polynomial x^10 + 10*x^8 + 25*x^6 + 3375 Defn: a0 |--> -1/30*ac^5 - 1/6*ac^3 + 1/2) sage: G.splitting_field() Number Field in ac with defining polynomial x^10 + 10*x^8 + 25*x^6 + 3375 - An embedding is returned also if the subgroup is trivial (:trac:`26817`):: sage: H = G.subgroup([]) sage: H.fixed_field() (Number Field in ac with defining polynomial x^10 + 10*x^8 + 25*x^6 + 3375, - Identity endomorphism of Number Field in ac with defining polynomial x^10 + 10*x^8 + 25*x^6 + 3375) + Identity endomorphism of + Number Field in ac with defining polynomial x^10 + 10*x^8 + 25*x^6 + 3375) """ G = self._ambient_group L = G._galois_closure @@ -1151,14 +1168,15 @@ class GaloisGroupElement(PermutationGroupElement): @cached_method def as_hom(self): r""" - Return the homomorphism L -> L corresponding to self, where L is the + Return the homomorphism `L \to L` corresponding to ``self``, where `L` is the Galois closure of the ambient number field. EXAMPLES:: sage: G = QuadraticField(-7,'w').galois_group() sage: G[1].as_hom() - Ring endomorphism of Number Field in w with defining polynomial x^2 + 7 with w = 2.645751311064591?*I + Ring endomorphism of Number Field in w with defining polynomial x^2 + 7 + with w = 2.645751311064591?*I Defn: w |--> -w TESTS: @@ -1206,8 +1224,8 @@ def __call__(self, x): def ramification_degree(self, P): """ - Return the greatest value of v such that s acts trivially modulo P^v. - Should only be used if P is prime and s is in the decomposition group of P. + Return the greatest value of `v` such that `s` acts trivially modulo `P^v`. + Should only be used if `P` is prime and `s` is in the decomposition group of `P`. EXAMPLES:: diff --git a/src/sage/rings/number_field/homset.py b/src/sage/rings/number_field/homset.py index 6353353afe1..ac3726c0896 100644 --- a/src/sage/rings/number_field/homset.py +++ b/src/sage/rings/number_field/homset.py @@ -177,7 +177,7 @@ def order(self): sage: End(k).order() 1 - sage: K. = NumberField( [x^3 + 2, x^2 + x + 1] ) + sage: K. = NumberField([x^3 + 2, x^2 + x + 1]) sage: End(K).order() 6 """ @@ -188,7 +188,7 @@ def order(self): @cached_method def list(self): """ - Return a list of all the elements of self. + Return a list of all the elements of ``self``. EXAMPLES:: @@ -261,13 +261,14 @@ class RelativeNumberFieldHomset(NumberFieldHomset): sage: L. = CyclotomicField(3).extension(x^3 - 2) sage: phi = L.hom([cuberoot2 * zeta3]); phi - Relative number field endomorphism of Number Field in cuberoot2 with defining polynomial x^3 - 2 over its base field + Relative number field endomorphism of + Number Field in cuberoot2 with defining polynomial x^3 - 2 over its base field Defn: cuberoot2 |--> zeta3*cuberoot2 zeta3 |--> zeta3 sage: phi(cuberoot2 + zeta3) zeta3*cuberoot2 + zeta3 - In fact, this phi is a generator for the Kummer Galois group of this + In fact, this ``phi`` is a generator for the Kummer Galois group of this cyclic extension:: sage: phi(phi(cuberoot2 + zeta3)) @@ -422,7 +423,7 @@ def _from_im(self, im_gen, base_map, check=True): @cached_method def default_base_hom(self): r""" - Pick an embedding of the base field of self into the codomain of this + Pick an embedding of the base field of ``self`` into the codomain of this homset. This is done in an essentially arbitrary way. EXAMPLES:: @@ -468,7 +469,7 @@ def default_base_hom(self): @cached_method def list(self): """ - Return a list of all the elements of self (for which the domain + Return a list of all the elements of ``self`` (for which the domain is a relative number field). EXAMPLES:: @@ -476,11 +477,13 @@ def list(self): sage: K. = NumberField([x^2 + x + 1, x^3 + 2]) sage: End(K).list() [ - Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field + Relative number field endomorphism of + Number Field in a with defining polynomial x^2 + x + 1 over its base field Defn: a |--> a b |--> b, ... - Relative number field endomorphism of Number Field in a with defining polynomial x^2 + x + 1 over its base field + Relative number field endomorphism of + Number Field in a with defining polynomial x^2 + x + 1 over its base field Defn: a |--> a b |--> -b*a - b ] @@ -574,7 +577,7 @@ def _element_constructor_(self, x, check=True): @cached_method def list(self): """ - Return a list of all the elements of self (for which the domain + Return a list of all the elements of ``self`` (for which the domain is a cyclotomic field). EXAMPLES:: diff --git a/src/sage/rings/number_field/maps.py b/src/sage/rings/number_field/maps.py index 68d03c73af3..7a6d0fcbb2f 100644 --- a/src/sage/rings/number_field/maps.py +++ b/src/sage/rings/number_field/maps.py @@ -11,12 +11,16 @@ sage: from_K, to_K = K.structure() sage: from_K Isomorphism map: - From: Number Field in a with defining polynomial x^6 - 3*x^5 + 6*x^4 - 11*x^3 + 12*x^2 + 3*x + 1 - To: Number Field in cuberoot2 with defining polynomial x^3 - 2 over its base field + From: Number Field in a with defining polynomial + x^6 - 3*x^5 + 6*x^4 - 11*x^3 + 12*x^2 + 3*x + 1 + To: Number Field in cuberoot2 with defining polynomial + x^3 - 2 over its base field sage: to_K Isomorphism map: - From: Number Field in cuberoot2 with defining polynomial x^3 - 2 over its base field - To: Number Field in a with defining polynomial x^6 - 3*x^5 + 6*x^4 - 11*x^3 + 12*x^2 + 3*x + 1 + From: Number Field in cuberoot2 with defining polynomial + x^3 - 2 over its base field + To: Number Field in a with defining polynomial + x^6 - 3*x^5 + 6*x^4 - 11*x^3 + 12*x^2 + 3*x + 1 """ #***************************************************************************** @@ -118,9 +122,11 @@ class MapVectorSpaceToNumberField(NumberFieldIsomorphism): (True, True) sage: fr.domain(), to.codomain() - (Vector space of dimension 4 over Rational Field, Vector space of dimension 4 over Rational Field) + (Vector space of dimension 4 over Rational Field, + Vector space of dimension 4 over Rational Field) sage: to.domain(), fr.codomain() - (Number Field in a with defining polynomial x^4 + 3*x + 1, Number Field in a with defining polynomial x^4 + 3*x + 1) + (Number Field in a with defining polynomial x^4 + 3*x + 1, + Number Field in a with defining polynomial x^4 + 3*x + 1) sage: fr * to Composite map: From: Number Field in a with defining polynomial x^4 + 3*x + 1 @@ -243,8 +249,10 @@ class MapRelativeVectorSpaceToRelativeNumberField(NumberFieldIsomorphism): Vector space of dimension 2 over Number Field in b0 with defining polynomial x^2 + 1 sage: fr Isomorphism map: - From: Vector space of dimension 2 over Number Field in b0 with defining polynomial x^2 + 1 - To: Number Field in a with defining polynomial x^2 - b0*x + 1 over its base field + From: Vector space of dimension 2 + over Number Field in b0 with defining polynomial x^2 + 1 + To: Number Field in a + with defining polynomial x^2 - b0*x + 1 over its base field sage: type(fr) @@ -380,7 +388,8 @@ class NameChangeMap(NumberFieldIsomorphism): From: Number Field in a with defining polynomial x^2 - 3 To: Number Field in b with defining polynomial x^2 - 3 sage: type(from_L), type(to_L) - (, ) + (, + ) """ def __init__(self, K, L): r""" @@ -391,7 +400,8 @@ def __init__(self, K, L): sage: L.structure() (Isomorphism given by variable name change map: From: Number Field in c with defining polynomial x^2 - 3 over its base field - To: Number Field in a with defining polynomial x^2 - 3 over its base field, Isomorphism given by variable name change map: + To: Number Field in a with defining polynomial x^2 - 3 over its base field, + Isomorphism given by variable name change map: From: Number Field in a with defining polynomial x^2 - 3 over its base field To: Number Field in c with defining polynomial x^2 - 3 over its base field) """ diff --git a/src/sage/rings/number_field/morphism.py b/src/sage/rings/number_field/morphism.py index 174252dad61..946eb529556 100644 --- a/src/sage/rings/number_field/morphism.py +++ b/src/sage/rings/number_field/morphism.py @@ -86,17 +86,17 @@ def __invert__(self): def preimage(self, y): r""" - Computes a preimage of `y` in the domain, provided one exists. - Raises a ValueError if `y` has no preimage. + Compute a preimage of `y` in the domain, provided one exists. + Raises a :class:`ValueError` if `y` has no preimage. INPUT: - - `y` -- an element of the codomain of self. + - ``y`` -- an element of the codomain of ``self``. OUTPUT: Returns the preimage of `y` in the domain, if one exists. - Raises a ValueError if `y` has no preimage. + Raises a :class:`ValueError` if `y` has no preimage. EXAMPLES:: @@ -113,9 +113,9 @@ def preimage(self, y): :: sage: F. = QuadraticField(23) - sage: G. = F.extension(x^3+5) + sage: G. = F.extension(x^3 + 5) sage: f = F.embeddings(G)[0] - sage: f.preimage(a^3+2*b+3) + sage: f.preimage(a^3 + 2*b + 3) 2*b - 2 """ # Throughout this method I am using the convention that self is a homomorphism from the number field K to the number field L @@ -155,7 +155,8 @@ def __init__(self, parent, abs_hom): sage: K. = NumberField( [x^3 + 2, x^2 + x + 1] ) sage: f = K.hom(-a*b - a, K); f - Relative number field endomorphism of Number Field in a with defining polynomial x^3 + 2 over its base field + Relative number field endomorphism of + Number Field in a with defining polynomial x^3 + 2 over its base field Defn: a |--> (-b - 1)*a b |--> b sage: type(f) @@ -174,10 +175,11 @@ def abs_hom(self): EXAMPLES:: - sage: K. = NumberField( [x^3 + 2, x^2 + x + 1] ) + sage: K. = NumberField([x^3 + 2, x^2 + x + 1]) sage: K.hom(a, K).abs_hom() Ring morphism: - From: Number Field in a with defining polynomial x^6 - 3*x^5 + 6*x^4 - 3*x^3 - 9*x + 9 + From: Number Field in a with defining polynomial + x^6 - 3*x^5 + 6*x^4 - 3*x^3 - 9*x + 9 To: Number Field in a with defining polynomial x^3 + 2 over its base field Defn: a |--> a - b """ @@ -202,7 +204,7 @@ def im_gens(self): EXAMPLES:: - sage: K. = NumberField( [x^3 + 2, x^2 + x + 1] ) + sage: K. = NumberField([x^3 + 2, x^2 + x + 1]) sage: K.hom(a, K).im_gens() [a, b] """ @@ -229,7 +231,7 @@ def _repr_defn(self): EXAMPLES:: - sage: K. = NumberField( [x^3 + 2, x^2 + x + 1] ) + sage: K. = NumberField([x^3 + 2, x^2 + x + 1]) sage: K.hom(a, K)._repr_defn() 'a |--> a\nb |--> b' """ @@ -248,7 +250,7 @@ def _call_(self, x): EXAMPLES:: - sage: K. = NumberField( [x^3 + 2, x^2 + x + 1] ) + sage: K. = NumberField([x^3 + 2, x^2 + x + 1]) sage: K.hom(a*b, K)(17 + 3*a + 2*b) # indirect doctest 3*b*a + 2*b + 17 """ diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 1627b841c30..a7468b88aba 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -208,7 +208,7 @@ def proof_flag(t): """ Used for easily determining the correct proof flag to use. - Return t if t is not ``None``, otherwise return the system-wide + Return ``t`` if ``t`` is not ``None``, otherwise return the system-wide proof-flag for number fields (default: ``True``). EXAMPLES:: @@ -262,30 +262,30 @@ def NumberField(polynomial, name=None, check=True, names=None, embedding=None, INPUT: - - ``polynomial`` - a polynomial over `\QQ` or a number field, or a list - of such polynomials. - - ``names`` (or ``name``) - a string or a list of strings, the names of - the generators - - ``check`` - a boolean (default: ``True``); do type checking and - irreducibility checking. - - ``embedding`` - ``None``, an element, or a list of elements, the - images of the generators in an ambient field (default: ``None``) - - ``latex_names`` (or ``latex_name``) - ``None``, a string, or a - list of strings (default: ``None``), how the generators are printed - for latex output - - ``assume_disc_small`` -- a boolean (default: ``False``); if ``True``, - assume that no square of a prime greater than PARI's primelimit - (which should be 500000); only applies for absolute fields at - present. - - ``maximize_at_primes`` -- ``None`` or a list of primes (default: - ``None``); if not ``None``, then the maximal order is computed by - maximizing only at the primes in this list, which completely avoids - having to factor the discriminant, but of course can lead to wrong - results; only applies for absolute fields at present. - - ``structure`` -- ``None``, a list or an instance of - :class:`structure.NumberFieldStructure` (default: ``None``), - internally used to pass in additional structural information, e.g., - about the field from which this field is created as a subfield. + - ``polynomial`` -- a polynomial over `\QQ` or a number field, or a list + of such polynomials. + - ``names`` (or ``name``) - a string or a list of strings, the names of + the generators + - ``check`` -- a boolean (default: ``True``); do type checking and + irreducibility checking. + - ``embedding`` -- ``None``, an element, or a list of elements, the + images of the generators in an ambient field (default: ``None``) + - ``latex_names`` (or ``latex_name``) - ``None``, a string, or a + list of strings (default: ``None``), how the generators are printed + for latex output + - ``assume_disc_small`` -- a boolean (default: ``False``); if ``True``, + assume that no square of a prime greater than PARI's primelimit + (which should be 500000); only applies for absolute fields at + present. + - ``maximize_at_primes`` -- ``None`` or a list of primes (default: + ``None``); if not ``None``, then the maximal order is computed by + maximizing only at the primes in this list, which completely avoids + having to factor the discriminant, but of course can lead to wrong + results; only applies for absolute fields at present. + - ``structure`` -- ``None``, a list or an instance of + :class:`structure.NumberFieldStructure` (default: ``None``), + internally used to pass in additional structural information, e.g., + about the field from which this field is created as a subfield. We accept ``implementation`` and ``prec`` attributes for compatibility with :class:`~sage.categories.pushout.AlgebraicExtensionFunctor` @@ -294,7 +294,7 @@ def NumberField(polynomial, name=None, check=True, names=None, embedding=None, EXAMPLES:: sage: z = QQ['z'].0 - sage: K = NumberField(z^2 - 2,'s'); K + sage: K = NumberField(z^2 - 2, 's'); K Number Field in s with defining polynomial z^2 - 2 sage: s = K.0; s s @@ -307,7 +307,7 @@ def NumberField(polynomial, name=None, check=True, names=None, embedding=None, sage: K. = NumberField(x^2 - 2) sage: R. = K[] - sage: L. = K.extension(t^3+t+a); L + sage: L. = K.extension(t^3 + t + a); L Number Field in b with defining polynomial t^3 + t + a over its base field sage: L.absolute_field('c') Number Field in c with defining polynomial x^6 + 2*x^4 + x^2 - 2 @@ -357,13 +357,14 @@ def NumberField(polynomial, name=None, check=True, names=None, embedding=None, for arithmetic and deduce relations with other number fields which would not be valid for an abstract number field. :: - sage: K. = NumberField(x^3-2, embedding=1.2) + sage: K. = NumberField(x^3 - 2, embedding=1.2) sage: RR.coerce_map_from(K) Composite map: From: Number Field in a with defining polynomial x^3 - 2 with a = 1.259921049894873? To: Real Field with 53 bits of precision Defn: Generic morphism: - From: Number Field in a with defining polynomial x^3 - 2 with a = 1.259921049894873? + From: Number Field in a with defining polynomial x^3 - 2 + with a = 1.259921049894873? To: Real Lazy Field Defn: a -> 1.259921049894873? then @@ -378,7 +379,7 @@ def NumberField(polynomial, name=None, check=True, names=None, embedding=None, 1/3*a^2 - 1/3*a + 1/3 sage: RR(b) 0.442493334024442 - sage: L. = NumberField(x^6-2, embedding=1.1) + sage: L. = NumberField(x^6 - 2, embedding=1.1) sage: L(a) b^2 sage: a + b @@ -400,7 +401,8 @@ def NumberField(polynomial, name=None, check=True, names=None, embedding=None, sage: f = polygen(L)^3 - 2 sage: K. = NumberField(x^3-2, embedding=f.roots()[0][0]) sage: a + L(1) - 4 + 2*5^2 + 2*5^3 + 3*5^4 + 5^5 + 4*5^6 + 2*5^8 + 3*5^9 + 4*5^12 + 4*5^14 + 4*5^15 + 3*5^16 + 5^17 + 5^18 + 2*5^19 + O(5^20) + 4 + 2*5^2 + 2*5^3 + 3*5^4 + 5^5 + 4*5^6 + 2*5^8 + 3*5^9 + 4*5^12 + + 4*5^14 + 4*5^15 + 3*5^16 + 5^17 + 5^18 + 2*5^19 + O(5^20) sage: L. = NumberField(x^6-x^2+1/10, embedding=1) sage: K. = NumberField(x^3-x+1/10, embedding=b^2) sage: a+b @@ -410,7 +412,8 @@ def NumberField(polynomial, name=None, check=True, names=None, embedding=None, sage: K.coerce_embedding() Generic morphism: From: Number Field in a with defining polynomial x^3 - x + 1/10 with a = b^2 - To: Number Field in b with defining polynomial x^6 - x^2 + 1/10 with b = 0.9724449978911874? + To: Number Field in b with defining polynomial x^6 - x^2 + 1/10 + with b = 0.9724449978911874? Defn: a -> b^2 The ``QuadraticField`` and ``CyclotomicField`` constructors @@ -429,7 +432,7 @@ def NumberField(polynomial, name=None, check=True, names=None, embedding=None, Note that the codomain of the embedding must be ``QQbar`` or ``AA`` for this to work (see :trac:`20184`):: - sage: N. = NumberField(x^3+2,embedding=1) + sage: N. = NumberField(x^3 + 2,embedding=1) sage: 1 < g False sage: g > 1 @@ -440,7 +443,7 @@ def NumberField(polynomial, name=None, check=True, names=None, embedding=None, If no embedding is specified or is complex, the comparison is not returning something meaningful.:: - sage: N. = NumberField(x^3+2) + sage: N. = NumberField(x^3 + 2) sage: 1 < g False sage: g > 1 @@ -505,7 +508,7 @@ def NumberField(polynomial, name=None, check=True, names=None, embedding=None, :: - sage: W1 = NumberField(x^2+1,'a') + sage: W1 = NumberField(x^2 + 1,'a') sage: K. = CyclotomicField(5)[] sage: W. = NumberField(x^2 + 1); W Number Field in a with defining polynomial x^2 + 1 over its base field @@ -513,8 +516,8 @@ def NumberField(polynomial, name=None, check=True, names=None, embedding=None, The following has been fixed in :trac:`8800`:: sage: P. = QQ[] - sage: K. = NumberField(x^3-5,embedding=0) - sage: L. = K.extension(x^2+a) + sage: K. = NumberField(x^3 - 5,embedding=0) + sage: L. = K.extension(x^2 + a) sage: F, R = L.construction() sage: F(R) == L # indirect doctest True @@ -534,7 +537,8 @@ def NumberField(polynomial, name=None, check=True, names=None, embedding=None, Another problem that was found while working on :trac:`11670`, ``maximize_at_primes`` and ``assume_disc_small`` were lost when pickling:: - sage: K. = NumberField(x^3-2, assume_disc_small=True, maximize_at_primes=[2], latex_name='\\alpha', embedding=2^(1/3)) + sage: K. = NumberField(x^3 - 2, assume_disc_small=True, maximize_at_primes=[2], + ....: latex_name='\\alpha', embedding=2^(1/3)) sage: L = loads(dumps(K)) sage: L._assume_disc_small True @@ -585,27 +589,27 @@ class NumberFieldFactory(UniqueFactory): INPUT: - - ``polynomial`` - a polynomial over `\QQ` or a number field. - - ``name`` - a string (default: ``'a'``), the name of the generator - - ``check`` - a boolean (default: ``True``); do type checking and - irreducibility checking. - - ``embedding`` - ``None`` or an element, the images of the generator - in an ambient field (default: ``None``) - - ``latex_name`` - ``None`` or a string (default: ``None``), how the - generator is printed for latex output - - ``assume_disc_small`` -- a boolean (default: ``False``); if ``True``, - assume that no square of a prime greater than PARI's primelimit - (which should be 500000); only applies for absolute fields at - present. - - ``maximize_at_primes`` -- ``None`` or a list of primes (default: - ``None``); if not ``None``, then the maximal order is computed by - maximizing only at the primes in this list, which completely avoids - having to factor the discriminant, but of course can lead to wrong - results; only applies for absolute fields at present. - - ``structure`` -- ``None`` or an instance of - :class:`structure.NumberFieldStructure` (default: ``None``), - internally used to pass in additional structural information, e.g., - about the field from which this field is created as a subfield. + - ``polynomial`` -- a polynomial over `\QQ` or a number field. + - ``name`` -- a string (default: ``'a'``), the name of the generator + - ``check`` -- a boolean (default: ``True``); do type checking and + irreducibility checking. + - ``embedding`` -- ``None`` or an element, the images of the generator + in an ambient field (default: ``None``) + - ``latex_name`` -- ``None`` or a string (default: ``None``), how the + generator is printed for latex output + - ``assume_disc_small`` -- a boolean (default: ``False``); if ``True``, + assume that no square of a prime greater than PARI's primelimit + (which should be 500000); only applies for absolute fields at + present. + - ``maximize_at_primes`` -- ``None`` or a list of primes (default: + ``None``); if not ``None``, then the maximal order is computed by + maximizing only at the primes in this list, which completely avoids + having to factor the discriminant, but of course can lead to wrong + results; only applies for absolute fields at present. + - ``structure`` -- ``None`` or an instance of + :class:`structure.NumberFieldStructure` (default: ``None``), + internally used to pass in additional structural information, e.g., + about the field from which this field is created as a subfield. TESTS:: @@ -722,20 +726,20 @@ def NumberFieldTower(polynomials, names, check=True, embeddings=None, latex_name INPUT: - - ``polynomials`` - a list of polynomials. Each entry must be polynomial + - ``polynomials`` -- a list of polynomials. Each entry must be polynomial which is irreducible over the number field generated by the roots of the following entries. - - ``names`` - a list of strings or a string, the names of the generators of + - ``names`` -- a list of strings or a string, the names of the generators of the relative number fields. If a single string, then names are generated from that string. - - ``check`` - a boolean (default: ``True``), whether to check that the + - ``check`` -- a boolean (default: ``True``), whether to check that the polynomials are irreducible - - ``embeddings`` - a list of elements or ``None`` (default: ``None``), + - ``embeddings`` -- a list of elements or ``None`` (default: ``None``), embeddings of the relative number fields in an ambient field. - - ``latex_names`` - a list of strings or ``None`` (default: ``None``), names + - ``latex_names`` -- a list of strings or ``None`` (default: ``None``), names used to print the generators for latex output. - ``assume_disc_small`` -- a boolean (default: ``False``); if ``True``, - assume that no square of a prime greater than PARI's primelimit + assume that no square of a prime greater than PARI's ``primelimit`` (which should be 500000); only applies for absolute fields at present. - ``maximize_at_primes`` -- ``None`` or a list of primes (default: @@ -811,7 +815,8 @@ def NumberFieldTower(polynomials, names, check=True, embeddings=None, latex_name LaTeX versions of generator names can be specified either as:: - sage: K = NumberField([x^3 - 2, x^3 - 3, x^3 - 5], names=['a', 'b', 'c'], latex_names=[r'\alpha', r'\beta', r'\gamma']) + sage: K = NumberField([x^3 - 2, x^3 - 3, x^3 - 5], names=['a', 'b', 'c'], + ....: latex_names=[r'\alpha', r'\beta', r'\gamma']) sage: K.inject_variables(verbose=False) sage: latex(a + b + c) \alpha + \beta + \gamma @@ -882,16 +887,16 @@ def QuadraticField(D, name='a', check=True, embedding=True, latex_name='sqrt', * INPUT: - - ``D`` - a rational number + - ``D`` -- a rational number - - ``name`` - variable name (default: 'a') + - ``name`` -- variable name (default: 'a') - - ``check`` - bool (default: ``True``) + - ``check`` -- bool (default: ``True``) - - ``embedding`` - bool or square root of D in an - ambient field (default: ``True``) + - ``embedding`` -- bool or square root of `D` in an + ambient field (default: ``True``) - - ``latex_name`` - latex variable name (default: \sqrt{D}) + - ``latex_name`` -- latex variable name (default: `\sqrt{D}`) OUTPUT: A number field defined by a quadratic polynomial. Unless @@ -1004,7 +1009,7 @@ def QuadraticField(D, name='a', check=True, embedding=True, latex_name='sqrt', * def GaussianField(): r""" - The field QQ[i]. + The field `\QQ[i]`. TESTS:: @@ -1022,8 +1027,8 @@ def GaussianField(): def is_AbsoluteNumberField(x): - """ - Return True if x is an absolute number field. + r""" + Return ``True`` if ``x`` is an absolute number field. EXAMPLES:: @@ -1046,7 +1051,7 @@ def is_AbsoluteNumberField(x): def is_QuadraticField(x) -> bool: r""" - Return True if x is of the quadratic *number* field type. + Return ``True`` if ``x`` is of the quadratic *number* field type. This function is deprecated. Use :func:`isinstance` with :class:`~sage.rings.abc.NumberField_quadratic` instead. @@ -1086,14 +1091,14 @@ class CyclotomicFieldFactory(UniqueFactory): INPUT: - - ``n`` - a nonnegative integer, default:``0`` + - ``n`` -- a nonnegative integer, default: ``0`` - - ``names`` - name of generator (optional - defaults to zetan) + - ``names`` -- name of generator (optional - defaults to zetan) - - ``bracket`` - Defines the brackets in the case of ``n==0``, and + - ``bracket`` -- Defines the brackets in the case of ``n==0``, and is ignored otherwise. Can be any even length string, with ``"()"`` being the default. - - ``embedding`` - bool or n-th root of unity in an + - ``embedding`` -- bool or `n`-th root of unity in an ambient field (default True) EXAMPLES: @@ -1240,8 +1245,8 @@ def create_object(self, version, key, **extra_args): def is_CyclotomicField(x) -> bool: """ - Return True if x is a cyclotomic field, i.e., of the special - cyclotomic field class. This function does not return True for a + Return ``True`` if x is a cyclotomic field, i.e., of the special + cyclotomic field class. This function does not return ``True`` for a number field that just happens to be isomorphic to a cyclotomic field. @@ -1278,9 +1283,9 @@ def is_CyclotomicField(x) -> bool: class NumberField_generic(WithEqualityById, number_field_base.NumberField): - """ + r""" Generic class for number fields defined by an irreducible - polynomial over `\\QQ`. + polynomial over `\QQ`. EXAMPLES:: @@ -1332,7 +1337,7 @@ class NumberField_generic(WithEqualityById, number_field_base.NumberField): sage: K. = QuadraticField(2) sage: R. = K[] - sage: L. = K.extension(x^2+1) + sage: L. = K.extension(x^2 + 1) sage: M. = L.absolute_field() sage: M == L False @@ -1341,8 +1346,8 @@ class NumberField_generic(WithEqualityById, number_field_base.NumberField): sage: R. = QQ[] sage: R. = QQ[] - sage: K. = NumberField(x^2+1) - sage: L. = NumberField(y^2+1) + sage: K. = NumberField(x^2 + 1) + sage: L. = NumberField(y^2 + 1) sage: K == L False sage: hash(K) == hash(L) @@ -1365,7 +1370,7 @@ class NumberField_generic(WithEqualityById, number_field_base.NumberField): This example illustrates the issue resolved in :trac:`18942`:: - sage: F. = NumberField(x^2+x+1) + sage: F. = NumberField(x^2 + x + 1) sage: xx = polygen(F) sage: ps = [p for p, _ in F(7).factor()] sage: for mu in ps: @@ -1407,7 +1412,7 @@ def __init__(self, polynomial, name, latex_name, ... ValueError: defining polynomial (x^2 - 1) must be irreducible - If you use check=False, you avoid checking irreducibility of the + If you use ``check=False``, you avoid checking irreducibility of the defining polynomial, which can save time. :: @@ -1438,7 +1443,7 @@ def __init__(self, polynomial, name, latex_name, Number Field in a with defining polynomial x^4 + 23 sage: NumberField(QQ['x'].0^4 + 23, 'a') Number Field in a with defining polynomial x^4 + 23 - sage: NumberField(GF(7)['x'].0^4 + 23, 'a') + sage: NumberField(GF(7)['x'].0^4 + 23, 'a') # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: polynomial must be defined over rational field @@ -1533,7 +1538,7 @@ def _magma_polynomial_(self, magma): EXAMPLES:: sage: R. = QQ[] # optional - magma - sage: K. = NumberField(x^3+2) # optional - magma + sage: K. = NumberField(x^3 + 2) # optional - magma sage: K._magma_polynomial_(magma) # optional - magma x^3 + 2 sage: magma2=Magma() # optional - magma @@ -1595,8 +1600,8 @@ def construction(self): EXAMPLES:: - sage: K.=NumberField(x^3+x^2+1,embedding=CC.gen()) - sage: F,R = K.construction() + sage: K. = NumberField(x^3 + x^2 + 1,embedding=CC.gen()) + sage: F, R = K.construction() sage: F AlgebraicExtensionFunctor sage: R @@ -1611,11 +1616,11 @@ def construction(self): TESTS:: - sage: K. = NumberField(x^3+x+1) + sage: K. = NumberField(x^3 + x + 1) sage: R. = ZZ[] - sage: a+t # indirect doctest + sage: a + t # indirect doctest t + a - sage: (a+t).parent() + sage: (a + t).parent() Univariate Polynomial Ring in t over Number Field in a with defining polynomial x^3 + x + 1 The construction works for non-absolute number fields as well:: @@ -1760,8 +1765,8 @@ def _element_constructor_(self, x, check=True): Check that :trac:`30961` is fixed:: sage: QQi = i.parent() - sage: x = SR.var('x') - sage: QQi((x, x)) + sage: x = SR.var('x') # optional - sage.symbolic + sage: QQi((x, x)) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: unable to convert x to a rational @@ -1847,6 +1852,7 @@ def _convert_non_number_field_element(self, x): EXAMPLES:: + sage: x = polygen(QQ, 'x') sage: K. = NumberField(x^3 + 2/3) sage: K._convert_non_number_field_element(-7/8) -7/8 @@ -1862,17 +1868,17 @@ def _convert_non_number_field_element(self, x): will convert to the number field, e.g., this one in characteristic 7:: - sage: f = GF(7)['y']([1,2,3]); f + sage: f = GF(7)['y']([1,2,3]); f # optional - sage.rings.finite_rings 3*y^2 + 2*y + 1 - sage: K._convert_non_number_field_element(f) + sage: K._convert_non_number_field_element(f) # optional - sage.rings.finite_rings 3*a^2 + 2*a + 1 But not this one over a field of order 27:: - sage: F27. = GF(27) - sage: f = F27['z']([g^2, 2*g, 1]); f + sage: F27. = GF(27) # optional - sage.rings.finite_rings + sage: f = F27['z']([g^2, 2*g, 1]); f # optional - sage.rings.finite_rings z^2 + 2*g*z + g^2 - sage: K._convert_non_number_field_element(f) + sage: K._convert_non_number_field_element(f) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unable to convert g^2 to a rational @@ -1887,16 +1893,16 @@ def _convert_non_number_field_element(self, x): We can convert symbolic expressions:: - sage: I = sqrt(-1); parent(I) + sage: I = sqrt(-1); parent(I) # optional - sage.symbolic Symbolic Ring - sage: GaussianIntegers()(2 + I) + sage: GaussianIntegers()(2 + I) # optional - sage.symbolic I + 2 - sage: K1 = QuadraticField(3) - sage: K2 = QuadraticField(5) - sage: (K,) = K1.composite_fields(K2, preserve_embedding=True) - sage: K(sqrt(3) + sqrt(5)) + sage: K1 = QuadraticField(3) # optional - sage.symbolic + sage: K2 = QuadraticField(5) # optional - sage.symbolic + sage: (K,) = K1.composite_fields(K2, preserve_embedding=True) # optional - sage.symbolic + sage: K(sqrt(3) + sqrt(5)) # optional - sage.symbolic -1/2*a0^3 + 8*a0 - sage: K(sqrt(-3)*I) + sage: K(sqrt(-3)*I) # optional - sage.symbolic 1/4*a0^3 - 7/2*a0 """ if isinstance(x, (int, Rational, Integer, pari_gen, list)): @@ -2020,12 +2026,19 @@ def _Hom_(self, codomain, category=None): sage: K.Hom(K) # indirect doctest Automorphism group of Number Field in i with defining polynomial x^2 + 1 sage: Hom(K, QuadraticField(-1, 'b')) - Set of field embeddings from Number Field in i with defining polynomial x^2 + 1 to Number Field in b with defining polynomial x^2 + 1 with b = 1*I + Set of field embeddings + from Number Field in i with defining polynomial x^2 + 1 + to Number Field in b with defining polynomial x^2 + 1 with b = 1*I CHECKME: handling of the case where codomain is not a number field? - sage: Hom(K, VectorSpace(QQ,3)) - Set of Morphisms from Number Field in i with defining polynomial x^2 + 1 to Vector space of dimension 3 over Rational Field in Category of commutative additive groups + :: + + sage: Hom(K, VectorSpace(QQ,3)) + Set of Morphisms + from Number Field in i with defining polynomial x^2 + 1 + to Vector space of dimension 3 over Rational Field + in Category of commutative additive groups TESTS: @@ -2148,27 +2161,25 @@ def random_element(self, num_bound=None, den_bound=None, INPUT: - - ``num_bound`` - Bound on numerator of the coefficients of - the resulting element - - - ``den_bound`` - Bound on denominators of the coefficients - of the resulting element + - ``num_bound`` -- Bound on numerator of the coefficients of + the resulting element - - ``integral_coefficients`` (default: ``False``) - If ``True``, then - the resulting element will have integral - coefficients. This option overrides any - value of `den_bound`. + - ``den_bound`` -- Bound on denominators of the coefficients + of the resulting element - - ``distribution`` - Distribution to use for the coefficients - of the resulting element + - ``integral_coefficients`` -- (default: ``False``) If ``True``, then + the resulting element will have integral + coefficients. This option overrides any + value of ``den_bound``. - OUTPUT: + - ``distribution`` -- Distribution to use for the coefficients + of the resulting element - - Element of this number field + OUTPUT: Element of this number field EXAMPLES:: - sage: K. = NumberField(x^8+1) + sage: K. = NumberField(x^8 + 1) sage: K.random_element().parent() is K True @@ -2181,7 +2192,7 @@ def random_element(self, num_bound=None, den_bound=None, sage: while not K.random_element().is_prime(): ....: pass - sage: K. = NumberField([x^2-2,x^2-3,x^2-5]) + sage: K. = NumberField([x^2 - 2, x^2 - 3, x^2 - 5]) sage: K.random_element().parent() is K True @@ -2190,7 +2201,7 @@ def random_element(self, num_bound=None, den_bound=None, sage: while not K.random_element().is_prime(): # long time ....: pass - sage: K. = NumberField(x^5-2) + sage: K. = NumberField(x^5 - 2) sage: p = K.random_element(integral_coefficients=True) sage: p.is_integral() True @@ -2199,12 +2210,12 @@ def random_element(self, num_bound=None, den_bound=None, TESTS:: - sage: K. = NumberField(x^5-2) + sage: K. = NumberField(x^5 - 2) sage: K.random_element(-1) Traceback (most recent call last): ... TypeError: x must be < y - sage: K.random_element(5,0) + sage: K.random_element(5, 0) Traceback (most recent call last): ... TypeError: x must be < y @@ -2224,19 +2235,19 @@ def subfield(self, alpha, name=None, names=None): r""" Return a number field `K` isomorphic to `\QQ(\alpha)` (if this is an absolute number field) or `L(\alpha)` (if this - is a relative extension `M/L`) and a map from K to self that - sends the generator of K to alpha. + is a relative extension `M/L`) and a map from `K` to ``self`` that + sends the generator of `K` to ``alpha``. INPUT: - - ``alpha`` - an element of self, or something that - coerces to an element of self. + - ``alpha`` -- an element of ``self``, or something that + coerces to an element of ``self``. OUTPUT: - - ``K`` - a number field - - ``from_K`` - a homomorphism from K to self that - sends the generator of K to alpha. + - ``K`` -- a number field + - ``from_K`` -- a homomorphism from `K` to ``self`` that + sends the generator of `K` to ``alpha``. EXAMPLES:: @@ -2265,7 +2276,7 @@ def subfield(self, alpha, name=None, names=None): Subfields inherit embeddings:: sage: K. = CyclotomicField(5) - sage: L, K_from_L = K.subfield(z-z^2-z^3+z^4) + sage: L, K_from_L = K.subfield(z - z^2 - z^3 + z^4) sage: L Number Field in z0 with defining polynomial x^2 - 5 with z0 = 2.236067977499790? sage: CLF_from_K = K.coerce_embedding(); CLF_from_K @@ -2275,7 +2286,8 @@ def subfield(self, alpha, name=None, names=None): Defn: z -> 0.309016994374948? + 0.951056516295154?*I sage: CLF_from_L = L.coerce_embedding(); CLF_from_L Generic morphism: - From: Number Field in z0 with defining polynomial x^2 - 5 with z0 = 2.236067977499790? + From: Number Field in z0 with defining polynomial x^2 - 5 + with z0 = 2.236067977499790? To: Complex Lazy Field Defn: z0 -> 2.236067977499790? @@ -2319,9 +2331,9 @@ def subfield(self, alpha, name=None, names=None): def change_generator(self, alpha, name=None, names=None): r""" - Given the number field self, construct another isomorphic number - field `K` generated by the element alpha of self, along - with isomorphisms from `K` to self and from self to + Given the number field ``self``, construct another isomorphic number + field `K` generated by the element ``alpha`` of ``self``, along + with isomorphisms from `K` to ``self`` and from ``self`` to `K`. EXAMPLES:: @@ -2333,13 +2345,15 @@ def change_generator(self, alpha, name=None, names=None): Number Field in i0 with defining polynomial x^2 - 6*x + 37/4 with i0 = 1/2*i + 3 sage: from_K Ring morphism: - From: Number Field in i0 with defining polynomial x^2 - 6*x + 37/4 with i0 = 1/2*i + 3 + From: Number Field in i0 with defining polynomial x^2 - 6*x + 37/4 + with i0 = 1/2*i + 3 To: Number Field in i with defining polynomial x^2 + 1 Defn: i0 |--> 1/2*i + 3 sage: to_K Ring morphism: From: Number Field in i with defining polynomial x^2 + 1 - To: Number Field in i0 with defining polynomial x^2 - 6*x + 37/4 with i0 = 1/2*i + 3 + To: Number Field in i0 with defining polynomial x^2 - 6*x + 37/4 + with i0 = 1/2*i + 3 Defn: i |--> 2*i0 - 6 We can also do @@ -2357,7 +2371,7 @@ def change_generator(self, alpha, name=None, names=None): sage: to_K(i) 2*c - 6 - Note that the image is indeed a square root of -1. + Note that the image is indeed a square root of `-1`. :: @@ -2396,9 +2410,9 @@ def subfield_from_elements(self, alpha, name=None, polred=True, threshold=None): INPUT: - - ``alpha`` - list of elements in this number field + - ``alpha`` -- list of elements in this number field - - ``name`` - a name for the generator of the new number field + - ``name`` -- a name for the generator of the new number field - ``polred`` (boolean, default ``True``) - whether to optimize the generator of the newly created field @@ -2408,11 +2422,11 @@ def subfield_from_elements(self, alpha, name=None, polred=True, threshold=None): OUTPUT: a triple ``(field, beta, hom)`` where - - ``field`` - a subfield of this number field + - ``field`` -- a subfield of this number field - - ``beta`` - a list of elements of ``field`` corresponding to ``alpha`` + - ``beta`` -- a list of elements of ``field`` corresponding to ``alpha`` - - ``hom`` - inclusion homomorphism from ``field`` to ``self`` + - ``hom`` -- inclusion homomorphism from ``field`` to ``self`` EXAMPLES:: @@ -2680,7 +2694,7 @@ def absolute_field(self, names): def is_isomorphic(self, other, isomorphism_maps=False) -> bool: """ - Return True if self is isomorphic as a number field to other. + Return ``True`` if ``self`` is isomorphic as a number field to ``other``. EXAMPLES:: @@ -2740,43 +2754,43 @@ def is_isomorphic(self, other, isomorphism_maps=False) -> bool: def is_totally_real(self): """ - Return True if self is totally real, and False otherwise. + Return ``True`` if ``self`` is totally real, and ``False`` otherwise. - Totally real means that every isomorphic embedding of self into the + Totally real means that every isomorphic embedding of ``self`` into the complex numbers has image contained in the real numbers. EXAMPLES:: - sage: NumberField(x^2+2, 'alpha').is_totally_real() + sage: NumberField(x^2 + 2, 'alpha').is_totally_real() False - sage: NumberField(x^2-2, 'alpha').is_totally_real() + sage: NumberField(x^2 - 2, 'alpha').is_totally_real() True - sage: NumberField(x^4-2, 'alpha').is_totally_real() + sage: NumberField(x^4 - 2, 'alpha').is_totally_real() False """ return self.signature()[1] == 0 def is_totally_imaginary(self): """ - Return True if self is totally imaginary, and False otherwise. + Return ``True`` if self is totally imaginary, and ``False`` otherwise. - Totally imaginary means that no isomorphic embedding of self into + Totally imaginary means that no isomorphic embedding of ``self`` into the complex numbers has image contained in the real numbers. EXAMPLES:: - sage: NumberField(x^2+2, 'alpha').is_totally_imaginary() + sage: NumberField(x^2 + 2, 'alpha').is_totally_imaginary() True - sage: NumberField(x^2-2, 'alpha').is_totally_imaginary() + sage: NumberField(x^2 - 2, 'alpha').is_totally_imaginary() False - sage: NumberField(x^4-2, 'alpha').is_totally_imaginary() + sage: NumberField(x^4 - 2, 'alpha').is_totally_imaginary() False """ return self.signature()[0] == 0 def is_CM(self): r""" - Return True if self is a CM field (i.e. a totally imaginary + Return ``True`` if self is a CM field (i.e. a totally imaginary quadratic extension of a totally real field). EXAMPLES:: @@ -2799,7 +2813,7 @@ def is_CM(self): sage: F. = NumberField(x^3 - 2) sage: F.is_CM() False - sage: F. = NumberField(x^4-x^3-3*x^2+x+1) + sage: F. = NumberField(x^4 - x^3 - 3*x^2 + x + 1) sage: F.is_CM() False @@ -2833,8 +2847,8 @@ def is_CM(self): :: - sage: E_0. = NumberField(x^7 - 4*x^6 - 4*x^5 + 10*x^4 + 4*x^3 - \ - 6*x^2 - x + 1) + sage: E_0. = NumberField(x^7 - 4*x^6 - 4*x^5 + 10*x^4 + 4*x^3 + ....: - 6*x^2 - x + 1) sage: E_0.is_totally_real() True sage: E. = E_0.extension(x^2 + 1) @@ -2899,12 +2913,12 @@ def is_CM(self): def complex_conjugation(self): """ - Return the complex conjugation of self. + Return the complex conjugation of ``self``. This is only well-defined for fields contained in CM fields (i.e. for totally real fields and CM fields). Recall that a CM field is a totally imaginary quadratic extension of a totally - real field. For other fields, a ValueError is raised. + real field. For other fields, a :class:`ValueError` is raised. EXAMPLES:: @@ -2991,45 +3005,58 @@ def complex_conjugation(self): def maximal_totally_real_subfield(self): """ - Return the maximal totally real subfield of self together with an embedding of it into self. + Return the maximal totally real subfield of ``self`` together with an embedding of it into ``self``. EXAMPLES:: sage: F. = QuadraticField(11) sage: F.maximal_totally_real_subfield() [Number Field in a with defining polynomial x^2 - 11 with a = 3.316624790355400?, - Identity endomorphism of Number Field in a with defining polynomial x^2 - 11 with a = 3.316624790355400?] + Identity endomorphism of + Number Field in a with defining polynomial x^2 - 11 with a = 3.316624790355400?] sage: F. = QuadraticField(-15) sage: F.maximal_totally_real_subfield() [Rational Field, Natural morphism: From: Rational Field - To: Number Field in a with defining polynomial x^2 + 15 with a = 3.872983346207417?*I] + To: Number Field in a with defining polynomial x^2 + 15 + with a = 3.872983346207417?*I] sage: F. = CyclotomicField(29) sage: F.maximal_totally_real_subfield() - (Number Field in a0 with defining polynomial x^14 + x^13 - 13*x^12 - 12*x^11 + 66*x^10 + 55*x^9 - 165*x^8 - 120*x^7 + 210*x^6 + 126*x^5 - 126*x^4 - 56*x^3 + 28*x^2 + 7*x - 1 with a0 = 1.953241111420174?, + (Number Field in a0 with defining polynomial x^14 + x^13 - 13*x^12 - 12*x^11 + + 66*x^10 + 55*x^9 - 165*x^8 - 120*x^7 + 210*x^6 + 126*x^5 - 126*x^4 + - 56*x^3 + 28*x^2 + 7*x - 1 with a0 = 1.953241111420174?, Ring morphism: - From: Number Field in a0 with defining polynomial x^14 + x^13 - 13*x^12 - 12*x^11 + 66*x^10 + 55*x^9 - 165*x^8 - 120*x^7 + 210*x^6 + 126*x^5 - 126*x^4 - 56*x^3 + 28*x^2 + 7*x - 1 with a0 = 1.953241111420174? + From: Number Field in a0 with defining polynomial x^14 + x^13 - 13*x^12 - 12*x^11 + + 66*x^10 + 55*x^9 - 165*x^8 - 120*x^7 + 210*x^6 + 126*x^5 - 126*x^4 + - 56*x^3 + 28*x^2 + 7*x - 1 with a0 = 1.953241111420174? To: Cyclotomic Field of order 29 and degree 28 - Defn: a0 |--> -a^27 - a^26 - a^25 - a^24 - a^23 - a^22 - a^21 - a^20 - a^19 - a^18 - a^17 - a^16 - a^15 - a^14 - a^13 - a^12 - a^11 - a^10 - a^9 - a^8 - a^7 - a^6 - a^5 - a^4 - a^3 - a^2 - 1) + Defn: a0 |--> -a^27 - a^26 - a^25 - a^24 - a^23 - a^22 - a^21 - a^20 - a^19 + - a^18 - a^17 - a^16 - a^15 - a^14 - a^13 - a^12 - a^11 - a^10 + - a^9 - a^8 - a^7 - a^6 - a^5 - a^4 - a^3 - a^2 - 1) sage: F. = NumberField(x^3 - 2) sage: F.maximal_totally_real_subfield() - [Rational Field, Coercion map: + [Rational Field, + Coercion map: From: Rational Field To: Number Field in a with defining polynomial x^3 - 2] sage: F. = NumberField(x^4 - x^3 - x^2 + x + 1) sage: F.maximal_totally_real_subfield() - [Rational Field, Coercion map: + [Rational Field, + Coercion map: From: Rational Field To: Number Field in a with defining polynomial x^4 - x^3 - x^2 + x + 1] sage: F. = NumberField(x^4 - x^3 + 2*x^2 + x + 1) sage: F.maximal_totally_real_subfield() - [Number Field in a1 with defining polynomial x^2 - x - 1, Ring morphism: + [Number Field in a1 with defining polynomial x^2 - x - 1, + Ring morphism: From: Number Field in a1 with defining polynomial x^2 - x - 1 To: Number Field in a with defining polynomial x^4 - x^3 + 2*x^2 + x + 1 Defn: a1 |--> -1/2*a^3 - 1/2] - sage: F. = NumberField(x^4-4*x^2-x+1) + sage: F. = NumberField(x^4 - 4*x^2 - x + 1) sage: F.maximal_totally_real_subfield() - [Number Field in a with defining polynomial x^4 - 4*x^2 - x + 1, Identity endomorphism of Number Field in a with defining polynomial x^4 - 4*x^2 - x + 1] + [Number Field in a with defining polynomial x^4 - 4*x^2 - x + 1, + Identity endomorphism of + Number Field in a with defining polynomial x^4 - 4*x^2 - x + 1] An example of a relative extension where the base field is not the maximal totally real subfield. @@ -3039,17 +3066,21 @@ def maximal_totally_real_subfield(self): sage: y = polygen(E_0) sage: E. = E_0.extension(y^2 - E_0.gen() / 2) sage: E.maximal_totally_real_subfield() - [Number Field in z1 with defining polynomial x^2 - 2*x - 5, Composite map: + [Number Field in z1 with defining polynomial x^2 - 2*x - 5, + Composite map: From: Number Field in z1 with defining polynomial x^2 - 2*x - 5 To: Number Field in z with defining polynomial x^2 - 1/2*a over its base field Defn: Ring morphism: From: Number Field in z1 with defining polynomial x^2 - 2*x - 5 - To: Number Field in z with defining polynomial x^4 - 2*x^3 + x^2 + 6*x + 3 + To: Number Field in z with defining + polynomial x^4 - 2*x^3 + x^2 + 6*x + 3 Defn: z1 |--> -1/3*z^3 + 1/3*z^2 + z - 1 then Isomorphism map: - From: Number Field in z with defining polynomial x^4 - 2*x^3 + x^2 + 6*x + 3 - To: Number Field in z with defining polynomial x^2 - 1/2*a over its base field] + From: Number Field in z with defining + polynomial x^4 - 2*x^3 + x^2 + 6*x + 3 + To: Number Field in z with defining + polynomial x^2 - 1/2*a over its base field] """ @@ -3099,7 +3130,7 @@ def maximal_totally_real_subfield(self): def complex_embeddings(self, prec=53): r""" Return all homomorphisms of this number field into the approximate - complex field with precision prec. + complex field with precision ``prec``. This always embeds into an MPFR based complex field. If you want embeddings into the 53-bit double precision, which is @@ -3138,9 +3169,9 @@ def complex_embeddings(self, prec=53): def real_embeddings(self, prec=53): r""" Return all homomorphisms of this number field into the approximate - real field with precision prec. + real field with precision ``prec``. - If prec is 53 (the default), then the real double field is + If ``prec`` is 53 (the default), then the real double field is used; otherwise the arbitrary precision (but slow) real field is used. If you want embeddings into the 53-bit double precision, which is faster, use ``self.embeddings(RDF)``. @@ -3179,7 +3210,7 @@ def real_embeddings(self, prec=53): As this is a numerical function, the number of embeddings may be incorrect if the precision is too low:: - sage: K = NumberField(x^2+2*10^1000*x + 10^2000+1, 'a') + sage: K = NumberField(x^2 + 2*10^1000*x + 10^2000+1, 'a') sage: len(K.real_embeddings()) 2 sage: len(K.real_embeddings(100)) @@ -3198,10 +3229,10 @@ def specified_complex_embedding(self): Return the embedding of this field into the complex numbers which has been specified. - Fields created with the ``QuadraticField`` or - ``CyclotomicField`` constructors come with an implicit + Fields created with the :func:`QuadraticField` or + :func:`CyclotomicField` constructors come with an implicit embedding. To get one of these fields without the embedding, use - the generic ``NumberField`` constructor. + the generic :class:`NumberField` constructor. EXAMPLES:: @@ -3215,7 +3246,8 @@ def specified_complex_embedding(self): sage: QuadraticField(3, 'a').specified_complex_embedding() Generic morphism: - From: Number Field in a with defining polynomial x^2 - 3 with a = 1.732050807568878? + From: Number Field in a with defining polynomial x^2 - 3 + with a = 1.732050807568878? To: Real Lazy Field Defn: a -> 1.732050807568878? @@ -3230,33 +3262,41 @@ def specified_complex_embedding(self): Most fields don't implicitly have embeddings unless explicitly specified:: - sage: NumberField(x^2-2, 'a').specified_complex_embedding() is None + sage: NumberField(x^2 - 2, 'a').specified_complex_embedding() is None True - sage: NumberField(x^3-x+5, 'a').specified_complex_embedding() is None + sage: NumberField(x^3 - x + 5, 'a').specified_complex_embedding() is None True - sage: NumberField(x^3-x+5, 'a', embedding=2).specified_complex_embedding() + sage: NumberField(x^3 - x + 5, 'a', embedding=2).specified_complex_embedding() Generic morphism: - From: Number Field in a with defining polynomial x^3 - x + 5 with a = -1.904160859134921? + From: Number Field in a with defining polynomial x^3 - x + 5 + with a = -1.904160859134921? To: Real Lazy Field Defn: a -> -1.904160859134921? - sage: NumberField(x^3-x+5, 'a', embedding=CDF.0).specified_complex_embedding() + sage: NumberField(x^3 - x + 5, 'a', embedding=CDF.0).specified_complex_embedding() Generic morphism: - From: Number Field in a with defining polynomial x^3 - x + 5 with a = 0.952080429567461? + 1.311248044077123?*I + From: Number Field in a with defining polynomial x^3 - x + 5 + with a = 0.952080429567461? + 1.311248044077123?*I To: Complex Lazy Field Defn: a -> 0.952080429567461? + 1.311248044077123?*I This function only returns complex embeddings:: - sage: K. = NumberField(x^2-2, embedding=Qp(7)(2).sqrt()) - sage: K.specified_complex_embedding() is None + sage: K. = NumberField(x^2 - 2, embedding=Qp(7)(2).sqrt()) # optional - sage.rings.padics + sage: K.specified_complex_embedding() is None # optional - sage.rings.padics True - sage: K.gen_embedding() - 3 + 7 + 2*7^2 + 6*7^3 + 7^4 + 2*7^5 + 7^6 + 2*7^7 + 4*7^8 + 6*7^9 + 6*7^10 + 2*7^11 + 7^12 + 7^13 + 2*7^15 + 7^16 + 7^17 + 4*7^18 + 6*7^19 + O(7^20) - sage: K.coerce_embedding() + sage: K.gen_embedding() # optional - sage.rings.padics + 3 + 7 + 2*7^2 + 6*7^3 + 7^4 + 2*7^5 + 7^6 + 2*7^7 + 4*7^8 + 6*7^9 + 6*7^10 + + 2*7^11 + 7^12 + 7^13 + 2*7^15 + 7^16 + 7^17 + 4*7^18 + 6*7^19 + O(7^20) + sage: K.coerce_embedding() # optional - sage.rings.padics Generic morphism: - From: Number Field in a with defining polynomial x^2 - 2 with a = 3 + 7 + 2*7^2 + 6*7^3 + 7^4 + 2*7^5 + 7^6 + 2*7^7 + 4*7^8 + 6*7^9 + 6*7^10 + 2*7^11 + 7^12 + 7^13 + 2*7^15 + 7^16 + 7^17 + 4*7^18 + 6*7^19 + O(7^20) + From: Number Field in a with defining polynomial x^2 - 2 + with a = 3 + 7 + 2*7^2 + 6*7^3 + 7^4 + 2*7^5 + 7^6 + 2*7^7 + 4*7^8 + + 6*7^9 + 6*7^10 + 2*7^11 + 7^12 + 7^13 + 2*7^15 + 7^16 + + 7^17 + 4*7^18 + 6*7^19 + O(7^20) To: 7-adic Field with capped relative precision 20 - Defn: a -> 3 + 7 + 2*7^2 + 6*7^3 + 7^4 + 2*7^5 + 7^6 + 2*7^7 + 4*7^8 + 6*7^9 + 6*7^10 + 2*7^11 + 7^12 + 7^13 + 2*7^15 + 7^16 + 7^17 + 4*7^18 + 6*7^19 + O(7^20) + Defn: a -> 3 + 7 + 2*7^2 + 6*7^3 + 7^4 + 2*7^5 + 7^6 + 2*7^7 + 4*7^8 + + 6*7^9 + 6*7^10 + 2*7^11 + 7^12 + 7^13 + 2*7^15 + 7^16 + + 7^17 + 4*7^18 + 6*7^19 + O(7^20) """ embedding = self.coerce_embedding() if embedding is not None and embedding.codomain()._is_numerical(): @@ -3266,13 +3306,13 @@ def specified_complex_embedding(self): def gen_embedding(self): """ If an embedding has been specified, return the image of the - generator under that embedding. Otherwise return None. + generator under that embedding. Otherwise return ``None``. EXAMPLES:: sage: QuadraticField(-7, 'a').gen_embedding() 2.645751311064591?*I - sage: NumberField(x^2+7, 'a').gen_embedding() # None + sage: NumberField(x^2 + 7, 'a').gen_embedding() # None """ embedding = self.coerce_embedding() if embedding is None: @@ -3282,14 +3322,14 @@ def gen_embedding(self): def algebraic_closure(self): """ - Return the algebraic closure of self (which is QQbar). + Return the algebraic closure of ``self`` (which is ``QQbar``). EXAMPLES:: sage: K. = QuadraticField(-1) sage: K.algebraic_closure() Algebraic Field - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: K.algebraic_closure() Algebraic Field sage: K = CyclotomicField(23) @@ -3303,12 +3343,13 @@ def algebraic_closure(self): def conductor(self, check_abelian=True): r""" Computes the conductor of the abelian field `K`. - If check_abelian is set to false and the field is not an + If ``check_abelian`` is set to ``False`` and the field is not an abelian extension of `\QQ`, the output is not meaningful. INPUT: - - ``check_abelian`` - a boolean (default: ``True``); check to see that this is an abelian extension of `\QQ` + - ``check_abelian`` -- a boolean (default: ``True``); check to see + that this is an abelian extension of `\QQ` OUTPUT: @@ -3342,7 +3383,7 @@ def conductor(self, check_abelian=True): ALGORITHM: For odd primes, it is easy to compute from the ramification - index because the p-Sylow subgroup is cyclic. For p=2, there + index because the `p`-Sylow subgroup is cyclic. For `p=2`, there are two choices for a given ramification index. They can be distinguished by the parity of the exponent in the discriminant of a 2-adic completion. @@ -3375,35 +3416,33 @@ def conductor(self, check_abelian=True): def dirichlet_group(self): r""" - Given a abelian field `K`, this computes and returns the + Given a abelian field `K`, compute and return the set of all Dirichlet characters corresponding to the - characters of the Galois group of `K/\mathbb{Q}`. - - The output is random if the field is not abelian + characters of the Galois group of `K/\QQ`. - OUTPUT: + The output is random if the field is not abelian. - - a list of Dirichlet characters + OUTPUT: a list of Dirichlet characters EXAMPLES:: - sage: K. = NumberField(x^3+x^2-36*x-4) + sage: K. = NumberField(x^3 + x^2 - 36*x - 4) sage: K.conductor() 109 sage: K.dirichlet_group() [Dirichlet character modulo 109 of conductor 1 mapping 6 |--> 1, - Dirichlet character modulo 109 of conductor 109 mapping 6 |--> zeta3, - Dirichlet character modulo 109 of conductor 109 mapping 6 |--> -zeta3 - 1] + Dirichlet character modulo 109 of conductor 109 mapping 6 |--> zeta3, + Dirichlet character modulo 109 of conductor 109 mapping 6 |--> -zeta3 - 1] sage: K = CyclotomicField(44) sage: L = K.subfields(5)[0][0] sage: X = L.dirichlet_group() sage: X [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, + 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] sage: X[4]^2 Dirichlet character modulo 11 of conductor 11 mapping 2 |--> zeta5^3 sage: X[4]^2 in X @@ -3515,7 +3554,7 @@ def _fractional_ideal_class_(self): This function is required by the general ring/ideal machinery. The value defined here is the default value for all number fields *except* relative number fields; this function is overridden by - one of the same name on class NumberField_relative. + one of the same name in class :class:`NumberField_relative`. EXAMPLES:: @@ -3526,15 +3565,15 @@ def _fractional_ideal_class_(self): def ideal(self, *gens, **kwds): """ - K.ideal() returns a fractional ideal of the field, except for the - zero ideal which is not a fractional ideal. + Return a fractional ideal of the field, except for the + zero ideal, which is not a fractional ideal. EXAMPLES:: - sage: K.=NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: K.ideal(2) Fractional ideal (2) - sage: K.ideal(2+i) + sage: K.ideal(2 + i) Fractional ideal (i + 2) sage: K.ideal(0) Ideal (0) of Number Field in i with defining polynomial x^2 + 1 @@ -3545,7 +3584,7 @@ def ideal(self, *gens, **kwds): sage: x = polygen(QQ) sage: K. = NumberField(x^6 - x^5 - 5*x^4 + 4*x^3 + 6*x^2 - 3*x - 1) - sage: K.ideal(1,1) + sage: K.ideal(1, 1) Fractional ideal (1) """ try: @@ -3562,9 +3601,9 @@ def idealchinese(self, ideals, residues): INPUT: - - ``ideals`` - a list of ideals of the number field. + - ``ideals`` -- a list of ideals of the number field. - - ``residues`` - a list of elements of the number field. + - ``residues`` -- a list of elements of the number field. OUTPUT: @@ -3580,25 +3619,25 @@ def idealchinese(self, ideals, residues): This is the example from the pari page on ``idealchinese``:: - sage: K. = NumberField(sqrt(2).minpoly()) - sage: ideals = [K.ideal(4),K.ideal(3)] - sage: residues = [sqrt2,1] - sage: r = K.idealchinese(ideals,residues); r + sage: K. = NumberField(sqrt(2).minpoly()) # optional - sage.symbolic + sage: ideals = [K.ideal(4), K.ideal(3)] # optional - sage.symbolic + sage: residues = [sqrt2, 1] # optional - sage.symbolic + sage: r = K.idealchinese(ideals, residues); r # optional - sage.symbolic -3*sqrt2 + 4 - sage: all((r - a) in I for I,a in zip(ideals,residues)) + sage: all((r - a) in I for I, a in zip(ideals, residues)) # optional - sage.symbolic True The result may be non-integral if the results are non-integral:: - sage: K. = NumberField(sqrt(2).minpoly()) - sage: ideals = [K.ideal(4),K.ideal(21)] - sage: residues = [1/sqrt2,1] - sage: r = K.idealchinese(ideals,residues); r + sage: K. = NumberField(sqrt(2).minpoly()) # optional - sage.symbolic + sage: ideals = [K.ideal(4), K.ideal(21)] # optional - sage.symbolic + sage: residues = [1/sqrt2, 1] # optional - sage.symbolic + sage: r = K.idealchinese(ideals, residues); r # optional - sage.symbolic -63/2*sqrt2 - 20 - sage: all( - ....: (r-a).valuation(P) >= k - ....: for I,a in zip(ideals,residues) - ....: for P,k in I.factor() + sage: all( # optional - sage.symbolic + ....: (r - a).valuation(P) >= k + ....: for I, a in zip(ideals, residues) + ....: for P, k in I.factor() ....: ) True """ @@ -3614,22 +3653,22 @@ def idealchinese(self, ideals, residues): def fractional_ideal(self, *gens, **kwds): r""" - Return the ideal in `\mathcal{O}_K` generated by gens. - This overrides the ``sage.rings.ring.Field`` method to - use the ``sage.rings.ring.Ring`` one instead, since + Return the ideal in `\mathcal{O}_K` generated by ``gens``. + This overrides the :class:`sage.rings.ring.Field` method to + use the :class:`sage.rings.ring.Ring` one instead, since we're not really concerned with ideals in a field but in its ring of integers. INPUT: - - ``gens`` - a list of generators, or a number field + - ``gens`` -- a list of generators, or a number field ideal. EXAMPLES:: - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: K.fractional_ideal([1/a]) Fractional ideal (1/2*a^2) @@ -3668,16 +3707,14 @@ def fractional_ideal(self, *gens, **kwds): return self._fractional_ideal_class_()(self, gens, **kwds) def ideals_of_bdd_norm(self, bound): - """ - All integral ideals of bounded norm. + r""" + Return all integral ideals of bounded norm. INPUT: + - ``bound`` -- a positive integer - - ``bound`` - a positive integer - - - OUTPUT: A dict of all integral ideals I such that Norm(I) <= bound, + OUTPUT: A dict of all integral ideals `I` such that Norm(`I`) `\leq` ``bound``, keyed by norm. EXAMPLES:: @@ -3726,19 +3763,19 @@ def ideals_of_bdd_norm(self, bound): def primes_above(self, x, degree=None): r""" - Return prime ideals of self lying over x. + Return prime ideals of ``self`` lying over `x`. INPUT: - - ``x``: usually an element or ideal of self. It - should be such that self.ideal(x) is sensible. This excludes x=0. + - ``x``: usually an element or ideal of ``self``. It + should be such that ``self.ideal(x)`` is sensible. This excludes `x=0`. - ``degree`` (default: ``None``): ``None`` or an integer. - If ``None``, find all primes above x of any degree. If an - integer, find all primes above x such that the resulting + If ``None``, find all primes above `x` of any degree. If an + integer, find all primes above `x` such that the resulting residue field has exactly this degree. - OUTPUT: A list of prime ideals of self lying over x. If degree + OUTPUT: A list of prime ideals of ``self`` lying over `x`. If ``degree`` is specified and no such ideal exists, returns the empty list. The output is sorted by residue degree first, then by underlying prime (or equivalently, by norm). @@ -3772,7 +3809,7 @@ def primes_above(self, x, degree=None): sage: [ P3.norm() for P3 in P3s ] [3] - The ideal (3) is totally ramified in F, so there is no degree 2 + The ideal `(3)` is totally ramified in `F`, so there is no degree 2 prime above 3:: sage: F.primes_above(3, degree=2) @@ -3811,7 +3848,7 @@ def primes_above(self, x, degree=None): sage: K.primes_above(I, degree=4) == [Q] True - It doesn't make sense to factor the ideal (0), so this raises an error:: + It doesn't make sense to factor the ideal `(0)`, so this raises an error:: sage: F.prime_above(0) Traceback (most recent call last): @@ -3829,20 +3866,20 @@ def primes_above(self, x, degree=None): def prime_above(self, x, degree=None): r""" - Return a prime ideal of self lying over x. + Return a prime ideal of ``self`` lying over `x`. INPUT: - - ``x``: usually an element or ideal of self. It - should be such that self.ideal(x) is sensible. This excludes x=0. + - ``x``: usually an element or ideal of ``self``. It + should be such that ``self.ideal(x)`` is sensible. This excludes `x=0`. - ``degree`` (default: ``None``): ``None`` or an integer. - If one, find a prime above x of any degree. If an integer, find a - prime above x such that the resulting residue field has exactly + If one, find a prime above `x` of any degree. If an integer, find a + prime above `x` such that the resulting residue field has exactly this degree. - OUTPUT: A prime ideal of self lying over x. If degree is specified - and no such ideal exists, raises a ValueError. + OUTPUT: A prime ideal of ``self`` lying over `x`. If ``degree`` is specified + and no such ideal exists, raises a :class:`ValueError`. EXAMPLES:: @@ -3873,8 +3910,8 @@ def prime_above(self, x, degree=None): sage: P3.norm() 3 - The ideal (3) is totally ramified in F, so there is no degree 2 - prime above 3:: + The ideal `(3)` is totally ramified in `F`, so there is no degree 2 + prime above `3`:: sage: F.prime_above(3, degree=2) Traceback (most recent call last): @@ -3905,7 +3942,7 @@ def prime_above(self, x, degree=None): sage: G.prime_above(7) Fractional ideal (b + 2) - It doesn't make sense to factor the ideal (0):: + It doesn't make sense to factor the ideal `(0)`:: sage: F.prime_above(0) Traceback (most recent call last): @@ -3945,10 +3982,11 @@ def primes_of_bounded_norm(self, B): sage: K. = QuadraticField(-1) sage: K.primes_of_bounded_norm(10) - [Fractional ideal (i + 1), Fractional ideal (-i - 2), Fractional ideal (2*i + 1), Fractional ideal (3)] + [Fractional ideal (i + 1), Fractional ideal (-i - 2), + Fractional ideal (2*i + 1), Fractional ideal (3)] sage: K.primes_of_bounded_norm(1) [] - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: P = K.primes_of_bounded_norm(30) sage: P [Fractional ideal (a), @@ -4054,17 +4092,15 @@ def primes_of_degree_one_iter(self, num_integer_primes=10000, max_iterations=100 INPUT: + - ``num_integer_primes (default: 10000)`` - an + integer. We try to find primes of absolute norm no greater than the + ``num_integer_primes``-th prime number. For example, if + ``num_integer_primes`` is 2, the largest norm found will be 3, since + the second prime is 3. - - ``num_integer_primes (default: 10000)`` - an - integer. We try to find primes of absolute norm no greater than the - num_integer_primes-th prime number. For example, if - num_integer_primes is 2, the largest norm found will be 3, since - the second prime is 3. - - - ``max_iterations (default: 100)`` - an integer. We - test max_iterations integers to find small primes before raising - StopIteration. - + - ``max_iterations (default: 100)`` - an integer. We + test ``max_iterations`` integers to find small primes before raising + :class:`StopIteration`. EXAMPLES:: @@ -4072,10 +4108,12 @@ def primes_of_degree_one_iter(self, num_integer_primes=10000, max_iterations=100 sage: it = K.primes_of_degree_one_iter() sage: Ps = [ next(it) for i in range(3) ] sage: Ps # random - [Fractional ideal (z^3 + z + 1), Fractional ideal (3*z^3 - z^2 + z - 1), Fractional ideal (2*z^3 - 3*z^2 + z - 2)] - sage: [ P.norm() for P in Ps ] # random + [Fractional ideal (z^3 + z + 1), + Fractional ideal (3*z^3 - z^2 + z - 1), + Fractional ideal (2*z^3 - 3*z^2 + z - 2)] + sage: [P.norm() for P in Ps] # random [11, 31, 41] - sage: [ P.residue_class_degree() for P in Ps ] + sage: [P.residue_class_degree() for P in Ps] [1, 1, 1] """ from sage.rings.number_field.small_primes_of_degree_one import Small_primes_of_degree_one_iter @@ -4083,13 +4121,13 @@ def primes_of_degree_one_iter(self, num_integer_primes=10000, max_iterations=100 def primes_of_degree_one_list(self, n, num_integer_primes=10000, max_iterations=100): r""" - Return a list of n prime ideals of absolute degree one and small + Return a list of `n` prime ideals of absolute degree one and small norm. .. warning:: It is possible that there are no primes of `K` of - absolute degree one of small prime norm, and it possible + absolute degree one of small prime norm, and it is possible that this algorithm will not find any primes of small norm. See module :mod:`sage.rings.number_field.small_primes_of_degree_one` @@ -4097,25 +4135,27 @@ def primes_of_degree_one_list(self, n, num_integer_primes=10000, max_iterations= INPUT: - - ``num_integer_primes (default: 10000)`` - an - integer. We try to find primes of absolute norm no greater than the - num_integer_primes-th prime number. For example, if - num_integer_primes is 2, the largest norm found will be 3, since - the second prime is 3. + - ``num_integer_primes`` -- (default: 10000) an + integer. We try to find primes of absolute norm no greater than the + ``num_integer_primes``-th prime number. For example, if + ``num_integer_primes`` is 2, the largest norm found will be 3, since + the second prime is 3. - - ``max_iterations (default: 100)`` - an integer. We - test max_iterations integers to find small primes before raising - ``StopIteration``. + - ``max_iterations`` -- (default: 100) an integer. We + test ``max_iterations`` integers to find small primes before raising + :class:`StopIteration`. EXAMPLES:: sage: K. = CyclotomicField(10) sage: Ps = K.primes_of_degree_one_list(3) sage: Ps # random output - [Fractional ideal (-z^3 - z^2 + 1), Fractional ideal (2*z^3 - 2*z^2 + 2*z - 3), Fractional ideal (2*z^3 - 3*z^2 + z - 2)] - sage: [ P.norm() for P in Ps ] + [Fractional ideal (-z^3 - z^2 + 1), + Fractional ideal (2*z^3 - 2*z^2 + 2*z - 3), + Fractional ideal (2*z^3 - 3*z^2 + z - 2)] + sage: [P.norm() for P in Ps] [11, 31, 41] - sage: [ P.residue_class_degree() for P in Ps ] + sage: [P.residue_class_degree() for P in Ps] [1, 1, 1] """ it = self.primes_of_degree_one_iter() @@ -4131,7 +4171,7 @@ def completely_split_primes(self, B=200): OUTPUT: - A list of all primes ``p < B`` which split completely in ``K``. + A list of all primes `p < B` which split completely in ``K``. EXAMPLES:: @@ -4158,7 +4198,7 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): images of generators. To do this we just check that the elements of the image of the - given generator (im_gens always has length 1) satisfies the + given generator (``im_gens`` always has length 1) satisfies the relation of the defining poly of this field. EXAMPLES:: @@ -4307,7 +4347,7 @@ def pari_nf(self, important=True): INPUT: - ``important`` -- boolean (default: ``True``). If ``False``, - raise a ``RuntimeError`` if we need to do a difficult + raise a :class:`RuntimeError` if we need to do a difficult discriminant factorization. This is useful when an integral basis is not strictly required, such as for factoring polynomials over this number field. @@ -4352,7 +4392,7 @@ def pari_nf(self, important=True): RuntimeError: Unable to factor discriminant with trial division Next, we illustrate the ``maximize_at_primes`` and ``assume_disc_small`` - parameters of the ``NumberField`` constructor. The following would take + parameters of the :class:`NumberField` constructor. The following would take a very long time without the ``maximize_at_primes`` option:: sage: K. = NumberField(x^2 - p*q, maximize_at_primes=[p]) @@ -4375,10 +4415,10 @@ def pari_nf(self, important=True): return self._pari_nf def pari_zk(self): - """ + r""" Integral basis of the PARI number field corresponding to this field. - This is the same as pari_nf().getattr('zk'), but much faster. + This is the same as ``pari_nf().getattr('zk')``, but much faster. EXAMPLES:: @@ -4476,7 +4516,7 @@ def pari_bnf(self, proof=None, units=True): def pari_rnfnorm_data(self, L, proof=True): """ Return the PARI :pari:`rnfisnorminit` data corresponding to the - extension L/self. + extension `L` / ``self``. EXAMPLES:: @@ -4500,18 +4540,17 @@ def pari_rnfnorm_data(self, L, proof=True): def _gap_init_(self): """ - Create a gap object representing self and return its name + Create a GAP object representing ``self`` and return its name. EXAMPLES:: sage: z = QQ['z'].0 sage: K. = NumberField(z^2 - 2) - sage: K._gap_init_() # the following variable name $sage1 represents the F.base_ring() in gap and is somehow random + sage: K._gap_init_() # the following variable name $sage1 represents the F.base_ring() in gap and is somehow random # optional - sage.libs.gap 'CallFuncList(function() local z,E; z:=Indeterminate($sage1,"z"); E:=AlgebraicExtension($sage1,z^2 - 2,"zeta"); return E; end,[])' - sage: k = gap(K) - sage: k + sage: k = gap(K); k # optional - sage.libs.gap - sage: k.GeneratorsOfDivisionRing() + sage: k.GeneratorsOfDivisionRing() # optional - sage.libs.gap [ zeta ] The following tests that it is possible to use a defining @@ -4521,11 +4560,11 @@ def _gap_init_(self): sage: P. = QQ[] sage: L. = NumberField(E^3 - 2) - sage: l = gap(L); l + sage: l = gap(L); l # optional - sage.libs.gap - sage: l.GeneratorsOfField() + sage: l.GeneratorsOfField() # optional - sage.libs.gap [ tau ] - sage: gap(tau)^3 + sage: gap(tau)^3 # optional - sage.libs.gap !2 """ if not self.is_absolute(): @@ -4558,14 +4597,12 @@ def class_group(self, proof=None, names='c'): INPUT: + - ``proof`` -- if ``True`` then compute the class group + provably correctly. Default is ``True``. Call :func:`number_field_proof` to + change this default globally. - - ``proof`` - if True then compute the class group - provably correctly. Default is True. Call number_field_proof to - change this default globally. - - - ``names`` - names of the generators of this class - group. - + - ``names`` -- names of the generators of this class + group. OUTPUT: The class group of this number field. @@ -4573,7 +4610,8 @@ def class_group(self, proof=None, names='c'): sage: K. = NumberField(x^2 + 23) sage: G = K.class_group(); G - Class group of order 3 with structure C3 of Number Field in a with defining polynomial x^2 + 23 + Class group of order 3 with structure C3 of + Number Field in a with defining polynomial x^2 + 23 sage: G.0 Fractional ideal class (2, 1/2*a - 1/2) sage: G.gens() @@ -4594,7 +4632,8 @@ def class_group(self, proof=None, names='c'): sage: k. = NumberField(x^2 + 20072) sage: G = k.class_group(); G - Class group of order 76 with structure C38 x C2 of Number Field in a with defining polynomial x^2 + 20072 + Class group of order 76 with structure C38 x C2 of + Number Field in a with defining polynomial x^2 + 20072 sage: G.0 # random Fractional ideal class (41, a + 10) sage: G.0^38 @@ -4635,10 +4674,8 @@ def class_number(self, proof=None): INPUT: - - - ``proof`` - bool (default: ``True`` unless you called - number_field_proof) - + - ``proof`` -- bool (default: ``True`` unless you called + ``number_field_proof``) EXAMPLES:: @@ -4658,17 +4695,15 @@ def S_class_group(self, S, proof=None, names='c'): INPUT: - - ``S`` - a set of primes of the base field + - ``S`` -- a set of primes of the base field - - ``proof`` - if False, assume the GRH in computing the class group. - Default is True. Call ``number_field_proof`` to change this + - ``proof`` -- if False, assume the GRH in computing the class group. + Default is ``True``. Call ``number_field_proof`` to change this default globally. - - ``names`` - names of the generators of this class group. - - OUTPUT: + - ``names`` -- names of the generators of this class group. - The S-class group of this number field. + OUTPUT: The S-class group of this number field. EXAMPLES: @@ -4676,7 +4711,8 @@ def S_class_group(self, S, proof=None, names='c'): sage: K. = QuadraticField(-5) sage: K.S_class_group([]) - S-class group of order 2 with structure C2 of Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I + S-class group of order 2 with structure C2 of Number Field in a + with defining polynomial x^2 + 5 with a = 2.236067977499790?*I When we include the prime `(2, a+1)`, the S-class group becomes trivial:: @@ -4687,15 +4723,18 @@ def S_class_group(self, S, proof=None, names='c'): TESTS:: sage: K. = QuadraticField(-14) - sage: I = K.ideal(2,a) + sage: I = K.ideal(2, a) sage: S = (I,) - sage: CS = K.S_class_group(S);CS - S-class group of order 2 with structure C2 of Number Field in a with defining polynomial x^2 + 14 with a = 3.741657386773942?*I + sage: CS = K.S_class_group(S); CS + S-class group of order 2 with structure C2 of Number Field in a + with defining polynomial x^2 + 14 with a = 3.741657386773942?*I sage: T = tuple() - sage: CT = K.S_class_group(T);CT - S-class group of order 4 with structure C4 of Number Field in a with defining polynomial x^2 + 14 with a = 3.741657386773942?*I + sage: CT = K.S_class_group(T); CT + S-class group of order 4 with structure C4 of Number Field in a + with defining polynomial x^2 + 14 with a = 3.741657386773942?*I sage: K.class_group() - Class group of order 4 with structure C4 of Number Field in a with defining polynomial x^2 + 14 with a = 3.741657386773942?*I + Class group of order 4 with structure C4 of Number Field in a + with defining polynomial x^2 + 14 with a = 3.741657386773942?*I """ proof = proof_flag(proof) if all(P.is_principal() for P in S): @@ -4716,19 +4755,18 @@ def S_units(self, S, proof=True): - ``proof`` -- if ``False``, assume the GRH in computing the class group - OUTPUT: - - A list of generators of the unit group. + OUTPUT: A list of generators of the unit group. .. note:: - For more functionality see the S_unit_group() function. + For more functionality see the function :func:`S_unit_group`. EXAMPLES:: sage: K. = QuadraticField(-3) sage: K.unit_group() - Unit group with structure C6 of Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I + Unit group with structure C6 of Number Field in a + with defining polynomial x^2 + 3 with a = 1.732050807568878?*I sage: K.S_units([]) # random [1/2*a + 1/2] sage: K.S_units([])[0].multiplicative_order() @@ -4754,7 +4792,7 @@ def S_units(self, S, proof=True): This checks that the multiple entries issue at :trac:`9341` is fixed:: sage: _. = QQ[] - sage: K. = NumberField(t-1) + sage: K. = NumberField(t - 1) sage: I = K.ideal(2) sage: K.S_units([I]) [2, -1] @@ -4772,17 +4810,15 @@ def _S_class_group_and_units(self, S, proof=True): INPUT: - - ``S`` - a tuple of prime ideals of self + - ``S`` -- a tuple of prime ideals of ``self`` - - ``proof`` - if False, assume the GRH in computing the class group + - ``proof`` -- if ``False``, assume the GRH in computing the class group OUTPUT: - - ``units, clgp_gens``, where: - - - ``units`` - A list of generators of the unit group. + - ``units`` -- A list of generators of the unit group. - - ``clgp_gens`` - A list of generators of the `S`-class group. + - ``clgp_gens`` -- A list of generators of the `S`-class group. Each generator is represented as a pair ``(gen, order)``, where ``gen`` is a fractional ideal of self and ``order`` is its order in the `S`-class group. @@ -4893,9 +4929,9 @@ def selmer_generators(self, S, m, proof=True, orders=False): - ``m`` -- a positive integer - - ``proof`` -- if False, assume the GRH in computing the class group + - ``proof`` -- if ``False``, assume the GRH in computing the class group - - ``orders`` (default False) -- if True, output two lists, the + - ``orders`` -- (default: ``False``) if ``True``, output two lists, the generators and their orders OUTPUT: @@ -4925,7 +4961,7 @@ def selmer_generators(self, S, m, proof=True, orders=False): :meth:`NumberField_generic.selmer_space`, which gives additional output when `m=p` is prime: as well as generators, - it gives an abstract vector space over `GF(p)` isomorphic to + it gives an abstract vector space over `\GF{p}` isomorphic to `K(S,p)` and maps implementing the isomorphism between this space and `K(S,p)` as a subgroup of `K^*/(K^*)^p`. @@ -4980,8 +5016,8 @@ def selmer_generators(self, S, m, proof=True, orders=False): TESTS:: sage: K. = QuadraticField(-5) - sage: P2 = K.ideal(2, -a+1) - sage: P3 = K.ideal(3, a+1) + sage: P2 = K.ideal(2, -a + 1) + sage: P3 = K.ideal(3, a + 1) sage: P5 = K.ideal(a) sage: S = K.selmer_generators([P2, P3, P5], 3) sage: S in ([2, a + 1, a], [2, a + 1, -a], [2, -a - 1, a], [2, -a - 1, -a]) or S @@ -5088,9 +5124,9 @@ def selmer_group_iterator(self, S, m, proof=True): [1, 2, -1, -2] sage: list(K.selmer_group_iterator((), 4)) [1, 4, -1, -4] - sage: list(K.selmer_group_iterator([K.ideal(2, -a+1)], 2)) + sage: list(K.selmer_group_iterator([K.ideal(2, -a + 1)], 2)) [1, -1, 2, -2] - sage: list(K.selmer_group_iterator([K.ideal(2, -a+1), K.ideal(3, a+1)], 2)) + sage: list(K.selmer_group_iterator([K.ideal(2, -a + 1), K.ideal(3, a + 1)], 2)) [1, -1, -a - 1, a + 1, 2, -2, -2*a - 2, 2*a + 2] Examples over `\QQ` (as a number field):: @@ -5201,7 +5237,7 @@ def selmer_space(self, S, p, proof=None): ....: if not v: ....: continue ....: a = fromKS2(v) - ....: print((a,K.extension(x^2-a, 'roota').relative_discriminant().factor())) + ....: print((a, K.extension(x^2 - a, 'roota').relative_discriminant().factor())) (2, (Fractional ideal (2, a + 1))^4) (-1, 1) (-2, (Fractional ideal (2, a + 1))^4) @@ -5356,12 +5392,15 @@ def composite_fields(self, other, names=None, both_maps=False, preserve_embeddin sage: L. = NumberField([x^3 - 5, x^2 + 3]) sage: CyclotomicField(3, 'w').composite_fields(L, both_maps=True) - [(Number Field in a with defining polynomial x^3 - 5 over its base field, Ring morphism: - From: Cyclotomic Field of order 3 and degree 2 - To: Number Field in a with defining polynomial x^3 - 5 over its base field - Defn: w |--> -1/2*b - 1/2, Relative number field endomorphism of Number Field in a with defining polynomial x^3 - 5 over its base field - Defn: a |--> a - b |--> b, None)] + [(Number Field in a with defining polynomial x^3 - 5 over its base field, + Ring morphism: + From: Cyclotomic Field of order 3 and degree 2 + To: Number Field in a with defining polynomial x^3 - 5 over its base field + Defn: w |--> -1/2*b - 1/2, + Relative number field endomorphism of Number Field in a with defining polynomial x^3 - 5 over its base field + Defn: a |--> a + b |--> b, + None)] Number fields defined by non-monic and non-integral polynomials are supported (:trac:`252`):: @@ -5420,7 +5459,8 @@ def composite_fields(self, other, names=None, both_maps=False, preserve_embeddin sage: A. = NumberField(x^3 - 7, embedding=CC(-0.95+1.65*I)) sage: B. = NumberField(y^9 - 7, embedding=CC(-1.16+0.42*I)) sage: A.composite_fields(B) - [Number Field in b with defining polynomial y^9 - 7 with b = -1.166502297945062? + 0.4245721146551276?*I] + [Number Field in b with defining polynomial y^9 - 7 + with b = -1.166502297945062? + 0.4245721146551276?*I] """ if not isinstance(other, NumberField_generic): raise TypeError("other must be a number field.") @@ -5602,7 +5642,7 @@ def absolute_degree(self): return self.polynomial().degree() def degree(self): - """ + r""" Return the degree of this number field. EXAMPLES:: @@ -5664,8 +5704,8 @@ def different(self): def discriminant(self, v=None): """ Return the discriminant of the ring of integers of the number - field, or if v is specified, the determinant of the trace pairing - on the elements of the list v. + field, or if ``v`` is specified, the determinant of the trace pairing + on the elements of the list ``v``. INPUT: @@ -5673,7 +5713,7 @@ def discriminant(self, v=None): OUTPUT: - Integer if `v` is omitted, and Rational otherwise. + Integer if ``v`` is omitted, and Rational otherwise. EXAMPLES:: @@ -5700,7 +5740,7 @@ def discriminant(self, v=None): def disc(self, v=None): """ - Shortcut for self.discriminant. + Shortcut for :meth:`discriminant`. EXAMPLES:: @@ -5736,7 +5776,7 @@ def elements_of_norm(self, n, proof=None) -> list: INPUT: - - `n` -- integer + - ``n`` -- integer - ``proof`` -- boolean (default: ``True``, unless you called :meth:`proof.number_field` and set it otherwise) @@ -5748,7 +5788,7 @@ def elements_of_norm(self, n, proof=None) -> list: EXAMPLES:: - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: K.elements_of_norm(3) [] sage: K.elements_of_norm(50) @@ -5789,7 +5829,7 @@ def extension(self, poly, name=None, names=None, latex_name=None, latex_names=No sage: m. = k.extension(y^2 + 2); m Number Field in b with defining polynomial y^2 + 2 over its base field - Note that b is a root of `y^2 + 2`:: + Note that `b` is a root of `y^2 + 2`:: sage: b.minpoly() x^2 + 2 @@ -5864,7 +5904,8 @@ def factor(self, n): sage: K.factor(1+a) Fractional ideal (a + 1) sage: K.factor(1+a/5) - (Fractional ideal (a + 1)) * (Fractional ideal (-a - 2))^-1 * (Fractional ideal (2*a + 1))^-1 * (Fractional ideal (-2*a + 3)) + (Fractional ideal (a + 1)) * (Fractional ideal (-a - 2))^-1 + * (Fractional ideal (2*a + 1))^-1 * (Fractional ideal (-2*a + 3)) An example over a relative number field:: @@ -5876,7 +5917,7 @@ def factor(self, n): sage: f.value() == a+1 True - It doesn't make sense to factor the ideal (0), so this raises an error:: + It doesn't make sense to factor the ideal `(0)`, so this raises an error:: sage: L.factor(0) Traceback (most recent call last): @@ -5916,7 +5957,9 @@ def prime_factors(self, x): sage: K. = NumberField(x^2 + 23) sage: K.prime_factors(w + 1) - [Fractional ideal (2, 1/2*w - 1/2), Fractional ideal (2, 1/2*w + 1/2), Fractional ideal (3, 1/2*w + 1/2)] + [Fractional ideal (2, 1/2*w - 1/2), + Fractional ideal (2, 1/2*w + 1/2), + Fractional ideal (3, 1/2*w + 1/2)] """ return self.ideal(x).prime_factors() @@ -5941,7 +5984,8 @@ def decomposition_type(self, p): EXAMPLES:: 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. = 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() True sage: K.discriminant().factor() @@ -5955,7 +5999,8 @@ def decomposition_type(self, p): This example is only ramified at 11:: - sage: K. = NumberField(x^24 + 11^2*(90*x^12 - 640*x^8 + 2280*x^6 - 512*x^4 +2432/11*x^2 - 11)) + sage: K. = NumberField(x^24 + 11^2*(90*x^12 - 640*x^8 + 2280*x^6 + ....: - 512*x^4 + 2432/11*x^2 - 11)) sage: K.discriminant().factor() -1 * 11^43 sage: K.decomposition_type(11) @@ -5976,7 +6021,8 @@ def decomposition_type(self, p): It also works for relative extensions:: sage: K. = QuadraticField(-143) - sage: M. = K.extension(x^10 - 6*x^8 + (a + 12)*x^6 + (-7/2*a - 89/2)*x^4 + (13/2*a - 77/2)*x^2 + 25) + sage: M. = K.extension(x^10 - 6*x^8 + (a + 12)*x^6 + (-7/2*a - 89/2)*x^4 + ....: + (13/2*a - 77/2)*x^2 + 25) There is a unique prime above `11` and above `13` in `K`, each of which is unramified in `M`:: @@ -6027,7 +6073,7 @@ def gen(self, n=0): INPUT: - - ``n`` - must be 0 (the default), or an exception is + - ``n`` -- must be 0 (the default), or an exception is raised. @@ -6088,7 +6134,7 @@ def _generator_matrix(self): def is_field(self, proof=True): """ - Return True since a number field is a field. + Return ``True`` since a number field is a field. EXAMPLES:: @@ -6100,7 +6146,7 @@ def is_field(self, proof=True): @cached_method def is_galois(self): r""" - Return True if this number field is a Galois extension of + Return ``True`` if this number field is a Galois extension of `\QQ`. EXAMPLES:: @@ -6109,9 +6155,15 @@ def is_galois(self): True sage: NumberField(x^3 + 2, 'a').is_galois() False - sage: NumberField(x^15 + x^14 - 14*x^13 - 13*x^12 + 78*x^11 + 66*x^10 - 220*x^9 - 165*x^8 + 330*x^7 + 210*x^6 - 252*x^5 - 126*x^4 + 84*x^3 + 28*x^2 - 8*x - 1, 'a').is_galois() + sage: K = NumberField(x^15 + x^14 - 14*x^13 - 13*x^12 + 78*x^11 + 66*x^10 + ....: - 220*x^9 - 165*x^8 + 330*x^7 + 210*x^6 - 252*x^5 + ....: - 126*x^4 + 84*x^3 + 28*x^2 - 8*x - 1, 'a') + sage: K.is_galois() True - sage: NumberField(x^15 + x^14 - 14*x^13 - 13*x^12 + 78*x^11 + 66*x^10 - 220*x^9 - 165*x^8 + 330*x^7 + 210*x^6 - 252*x^5 - 126*x^4 + 84*x^3 + 28*x^2 - 8*x - 10, 'a').is_galois() + sage: K = NumberField(x^15 + x^14 - 14*x^13 - 13*x^12 + 78*x^11 + 66*x^10 + ....: - 220*x^9 - 165*x^8 + 330*x^7 + 210*x^6 - 252*x^5 + ....: - 126*x^4 + 84*x^3 + 28*x^2 - 8*x - 10, 'a') + sage: K.is_galois() False """ return self.galois_group().is_galois() @@ -6119,7 +6171,7 @@ def is_galois(self): @cached_method def is_abelian(self): r""" - Return True if this number field is an abelian Galois extension of + Return ``True`` if this number field is an abelian Galois extension of `\QQ`. EXAMPLES:: @@ -6156,23 +6208,23 @@ def galois_group(self, type=None, algorithm='pari', names=None, gc_numbering=Non INPUT: - - ``type`` - Deprecated; the different versions of Galois groups have been - merged in :trac:`28782`. + - ``type`` -- Deprecated; the different versions of Galois groups have been + merged in :trac:`28782`. - - ``algorithm`` - 'pari', 'gap', 'kash', 'magma'. (default: 'pari'; - for degrees between 12 and 15 default is 'gap', and - when the degree is >= 16 it is 'kash'.) + - ``algorithm`` -- ``'pari'``, ``'gap'``, ``'kash'``, ``'magma'``. (default: ``'pari'``; + for degrees between 12 and 15 default is ``'gap'``, and + when the degree is >= 16 it is ``'kash'``.) - - ``names`` - a string giving a name for the generator of the Galois - closure of self, when this field is not Galois. + - ``names`` -- a string giving a name for the generator of the Galois + closure of ``self``, when this field is not Galois. - - ``gc_numbering`` -- if ``True``, permutations will be written - in terms of the action on the roots of a defining polynomial - for the Galois closure, rather than the defining polynomial for - the original number field. This is significantly faster; - but not the standard way of presenting Galois groups. - The default currently depends on the algorithm (``True`` for ``'pari'``, - ``False`` for ``'magma'``) and may change in the future. + - ``gc_numbering`` -- if ``True``, permutations will be written + in terms of the action on the roots of a defining polynomial + for the Galois closure, rather than the defining polynomial for + the original number field. This is significantly faster; + but not the standard way of presenting Galois groups. + The default currently depends on the algorithm (``True`` for ``'pari'``, + ``False`` for ``'magma'``) and may change in the future. The resulting group will only compute with automorphisms when necessary, so certain functions (such as :meth:`sage.rings.number_field.galois_group.GaloisGroup_v2.order`) @@ -6183,7 +6235,7 @@ def galois_group(self, type=None, algorithm='pari', names=None, gc_numbering=Non EXAMPLES:: - sage: k. = NumberField(x^2 - 14) # a Galois extension + sage: k. = NumberField(x^2 - 14) # a Galois extension sage: G = k.galois_group(); G Galois group 2T1 (S2) with order 2 of x^2 - 14 sage: G.gen(0) @@ -6200,7 +6252,8 @@ def galois_group(self, type=None, algorithm='pari', names=None, gc_numbering=Non (1,2,3)(4,5,6) sage: NumberField(x^3 + 2*x + 1, 'a').galois_group(algorithm='magma') # optional - magma - Galois group Transitive group number 2 of degree 3 of the Number Field in a with defining polynomial x^3 + 2*x + 1 + Galois group Transitive group number 2 of degree 3 + of the Number Field in a with defining polynomial x^3 + 2*x + 1 EXPLICIT GALOIS GROUP: We compute the Galois group as an explicit group of automorphisms of the Galois closure of a field. @@ -6237,7 +6290,8 @@ def galois_group(self, type=None, algorithm='pari', names=None, gc_numbering=Non sage: R. = PolynomialRing(K) sage: L = K.extension(t^5-t+a, 'b') sage: L.galois_group() - ...DeprecationWarning: Use .absolute_field().galois_group() if you want the Galois group of the absolute field + ...DeprecationWarning: Use .absolute_field().galois_group() + if you want the Galois group of the absolute field See https://github.com/sagemath/sage/issues/28782 for details. Galois group 10T22 (S(5)[x]2) with order 240 of t^5 - t + a @@ -6261,7 +6315,7 @@ def galois_group(self, type=None, algorithm='pari', names=None, gc_numbering=Non def _normalize_prime_list(self, v): """ - Internal function to convert into a tuple of primes either None or + Internal function to convert into a tuple of primes either ``None`` or a single prime or a list. EXAMPLES:: @@ -6323,13 +6377,13 @@ def power_basis(self): def integral_basis(self, v=None): """ - Return a list containing a ZZ-basis for the full ring of integers + Return a list containing a ``ZZ``-basis for the full ring of integers of this number field. INPUT: - - ``v`` - None, a prime, or a list of primes. See the - documentation for self.maximal_order. + - ``v`` -- ``None``, a prime, or a list of primes. See the + documentation for :meth:`maximal_order`. EXAMPLES:: @@ -6347,7 +6401,7 @@ def integral_basis(self, v=None): sage: K.integral_basis() [1, 1/2*a^2 + 1/2*a, a^2] - ALGORITHM: Uses the pari library (via _pari_integral_basis). + ALGORITHM: Uses the PARI library (via :pari:`_pari_integral_basis`). """ return self.maximal_order(v=v).basis() @@ -6358,11 +6412,11 @@ def _pari_integral_basis(self, v=None, important=True): INPUT: - - ``v`` -- None, a prime, or a list of primes. See the - documentation for self.maximal_order. + - ``v`` -- ``None``, a prime, or a list of primes. See the + documentation for :meth:``maximal_order``. - ``important`` -- boolean (default: ``True``). If ``False``, - raise a ``RuntimeError`` if we need to do a difficult + raise a :class:`RuntimeError` if we need to do a difficult discriminant factorization. This is useful when an integral basis is not strictly required. @@ -6450,11 +6504,14 @@ def reduced_basis(self, prec=None): EXAMPLES:: - sage: F. = NumberField(x^6-7*x^4-x^3+11*x^2+x-1) + sage: F. = NumberField(x^6 - 7*x^4 - x^3 + 11*x^2 + x - 1) sage: F.maximal_order().basis() [1/2*t^5 + 1/2*t^4 + 1/2*t^2 + 1/2, t, t^2, t^3, t^4, t^5] sage: F.reduced_basis() - [-1, -1/2*t^5 + 1/2*t^4 + 3*t^3 - 3/2*t^2 - 4*t - 1/2, t, 1/2*t^5 + 1/2*t^4 - 4*t^3 - 5/2*t^2 + 7*t + 1/2, 1/2*t^5 - 1/2*t^4 - 2*t^3 + 3/2*t^2 - 1/2, 1/2*t^5 - 1/2*t^4 - 3*t^3 + 5/2*t^2 + 4*t - 5/2] + [-1, -1/2*t^5 + 1/2*t^4 + 3*t^3 - 3/2*t^2 - 4*t - 1/2, t, + 1/2*t^5 + 1/2*t^4 - 4*t^3 - 5/2*t^2 + 7*t + 1/2, + 1/2*t^5 - 1/2*t^4 - 2*t^3 + 3/2*t^2 - 1/2, + 1/2*t^5 - 1/2*t^4 - 3*t^3 + 5/2*t^2 + 4*t - 5/2] sage: CyclotomicField(12).reduced_basis() [1, zeta12^2, zeta12, zeta12^3] @@ -6504,9 +6561,9 @@ def reduced_gram_matrix(self, prec=None): to calculate the Minkowski embedding. (See NOTE below.) OUTPUT: The Gram matrix `[\langle x_i,x_j \rangle]` of an LLL reduced - basis for the maximal order of self, where the integral basis for - self is given by `\{x_0, \dots, x_{n-1}\}`. Here `\langle , \rangle` is - the usual inner product on `\RR^n`, and self is embedded in `\RR^n` by + basis for the maximal order of ``self``, where the integral basis for + ``self`` is given by `\{x_0, \dots, x_{n-1}\}`. Here `\langle , \rangle` is + the usual inner product on `\RR^n`, and ``self`` is embedded in `\RR^n` by the Minkowski embedding. See the docstring for :meth:`NumberField_absolute.minkowski_embedding` for more information. @@ -6517,16 +6574,16 @@ def reduced_gram_matrix(self, prec=None): approximations, and so the result is only as good as the precision promised by PARI. In particular, in this case, the returned matrix will *not* be integral, and may not - have enough precision to recover the correct gram matrix + have enough precision to recover the correct Gram matrix (which is known to be integral for theoretical - reasons). Thus the need for the prec flag above. + reasons). Thus the need for the ``prec`` parameter above. If the following run-time error occurs: "PariError: not a definite - matrix in lllgram (42)" try increasing the prec parameter, + matrix in lllgram (42)", try increasing the ``prec`` parameter, EXAMPLES:: - sage: F. = NumberField(x^6-7*x^4-x^3+11*x^2+x-1) + sage: F. = NumberField(x^6 - 7*x^4 - x^3 + 11*x^2 + x - 1) sage: F.reduced_gram_matrix() [ 6 3 0 2 0 1] [ 3 9 0 1 0 -2] @@ -6534,7 +6591,8 @@ def reduced_gram_matrix(self, prec=None): [ 2 1 6 16 -3 3] [ 0 0 -2 -3 16 6] [ 1 -2 3 3 6 19] - sage: Matrix(6, [(x*y).trace() for x in F.integral_basis() for y in F.integral_basis()]) + sage: Matrix(6, [(x*y).trace() + ....: for x in F.integral_basis() for y in F.integral_basis()]) [2550 133 259 664 1368 3421] [ 133 14 3 54 30 233] [ 259 3 54 30 233 217] @@ -6545,7 +6603,7 @@ def reduced_gram_matrix(self, prec=None): :: sage: x = polygen(QQ) - sage: F. = NumberField(x^4+x^2+712312*x+131001238) + sage: F. = NumberField(x^4 + x^2 + 712312*x + 131001238) sage: F.reduced_gram_matrix(prec=128) [ 4.0000000000000000000000000000000000000 0.00000000000000000000000000000000000000 -1.9999999999999999999999999999999999037 -0.99999999999999999999999999999999383702] [ 0.00000000000000000000000000000000000000 46721.539331563218381658483353092335550 -11488.910026551724275122749703614966768 -418.12718083977141198754424579680468382] @@ -6604,10 +6662,10 @@ def _positive_integral_elements_with_trace(self, C): EXAMPLES:: - sage: K. = NumberField(ZZ['x'].0^2-2) + sage: K. = NumberField(ZZ['x'].0^2 - 2) sage: K._positive_integral_elements_with_trace([0,5]) [alpha + 2, -alpha + 2, 2, 1] - sage: L. = NumberField(ZZ['x'].0^2+1) + sage: L. = NumberField(ZZ['x'].0^2 + 1) sage: L._positive_integral_elements_with_trace([5,11]) Traceback (most recent call last): ... @@ -6644,12 +6702,12 @@ def narrow_class_group(self, proof=None): INPUT: - - ``proof`` - default: ``None`` (use the global proof + - ``proof`` -- default: ``None`` (use the global proof setting, which defaults to ``True``). EXAMPLES:: - sage: NumberField(x^3+x+9, 'a').narrow_class_group() + sage: NumberField(x^3 + x + 9, 'a').narrow_class_group() Multiplicative Abelian group isomorphic to C2 TESTS:: @@ -6707,7 +6765,7 @@ def absolute_polynomial_ntl(self): return self.polynomial_ntl() def polynomial_ntl(self): - """ + r""" Return defining polynomial of this number field as a pair, an ntl polynomial and a denominator. @@ -6728,11 +6786,10 @@ def polynomial_ntl(self): return (self.__polynomial_ntl, self.__denominator_ntl) def polynomial(self): - """ + r""" Return the defining polynomial of this number field. - This is exactly the same as - ``self.defining_polynomial()``. + This is exactly the same as :meth:`defining_polynomial`. EXAMPLES:: @@ -6742,10 +6799,10 @@ def polynomial(self): return self.__polynomial def defining_polynomial(self): # do not overload this -- overload polynomial instead - """ + r""" Return the defining polynomial of this number field. - This is exactly the same as ``self.polynomial()``. + This is exactly the same as :meth:`polynomial`. EXAMPLES:: @@ -6761,7 +6818,7 @@ def defining_polynomial(self): # do not overload this -- overload polynomial i return self.polynomial() def polynomial_ring(self): - """ + r""" Return the polynomial ring that we view this number field as being a quotient of (by a principal ideal). @@ -6779,12 +6836,13 @@ def polynomial_ring(self): sage: M. = NumberField([y^3 + 97, y^2 + 1]); M Number Field in a0 with defining polynomial y^3 + 97 over its base field sage: M.polynomial_ring() - Univariate Polynomial Ring in y over Number Field in a1 with defining polynomial y^2 + 1 + Univariate Polynomial Ring in y over + Number Field in a1 with defining polynomial y^2 + 1 """ return self.relative_polynomial().parent() def polynomial_quotient_ring(self): - """ + r""" Return the polynomial quotient ring isomorphic to this number field. @@ -6792,12 +6850,13 @@ def polynomial_quotient_ring(self): sage: K = NumberField(x^3 + 2*x - 5, 'alpha') sage: K.polynomial_quotient_ring() - Univariate Quotient Polynomial Ring in alpha over Rational Field with modulus x^3 + 2*x - 5 + Univariate Quotient Polynomial Ring in alpha over Rational Field + with modulus x^3 + 2*x - 5 """ return self.polynomial_ring().quotient(self.relative_polynomial(), self.variable_name()) def regulator(self, proof=None): - """ + r""" Return the regulator of this number field. Note that PARI computes the regulator to higher precision than the @@ -6805,13 +6864,13 @@ def regulator(self, proof=None): INPUT: - - ``proof`` - default: ``True``, unless you set it otherwise. + - ``proof`` -- default: ``True``, unless you set it otherwise. EXAMPLES:: - sage: NumberField(x^2-2, 'a').regulator() + sage: NumberField(x^2 - 2, 'a').regulator() 0.881373587019543 - sage: NumberField(x^4+x^3+x^2+x+1, 'a').regulator() + sage: NumberField(x^4 + x^3 + x^2 + x + 1, 'a').regulator() 0.962423650119207 """ proof = proof_flag(proof) @@ -6824,30 +6883,27 @@ def regulator(self, proof=None): return self.__regulator def residue_field(self, prime, names=None, check=True): - """ + r""" Return the residue field of this number field at a given prime, ie `O_K / p O_K`. INPUT: + - ``prime`` -- a prime ideal of the maximal order in + this number field, or an element of the field which generates a + principal prime ideal. - - ``prime`` - a prime ideal of the maximal order in - this number field, or an element of the field which generates a - principal prime ideal. - - - ``names`` - the name of the variable in the residue - field - - - ``check`` - whether or not to check the primality of - prime. + - ``names`` -- the name of the variable in the residue + field + - ``check`` -- whether or not to check the primality of ``prime``. OUTPUT: The residue field at this prime. EXAMPLES:: sage: R. = QQ[] - sage: K. = NumberField(x^4+3*x^2-17) + sage: K. = NumberField(x^4 + 3*x^2 - 17) sage: P = K.ideal(61).factor()[0][0] sage: K.residue_field(P) Residue field in abar of Fractional ideal (61, a^2 + 30) @@ -6894,8 +6950,8 @@ def residue_field(self, prime, names=None, check=True): return ResidueField(prime, names=names, check=False) def signature(self): - """ - Return (r1, r2), where r1 and r2 are the number of real embeddings + r""" + Return `(r_1, r_2)`, where `r_1` and `r_2` are the number of real embeddings and pairs of complex embeddings of this field, respectively. EXAMPLES:: @@ -6909,14 +6965,14 @@ def signature(self): return (ZZ(r1), ZZ(r2)) def trace_pairing(self, v): - """ + r""" Return the matrix of the trace pairing on the elements of the list - `v`. + ``v``. EXAMPLES:: sage: K. = NumberField(x^2 + 3) - sage: K.trace_pairing([1,zeta3]) + sage: K.trace_pairing([1, zeta3]) [ 2 0] [ 0 -6] """ @@ -6931,31 +6987,31 @@ def trace_pairing(self, v): def uniformizer(self, P, others="positive"): """ - Return an element of self with valuation 1 at the prime ideal P. + Return an element of ``self`` with valuation 1 at the prime ideal `P`. INPUT: - - ``self`` - a number field + - ``self`` -- a number field - - ``P`` - a prime ideal of self + - ``P`` -- a prime ideal of ``self`` - - ``others`` - either "positive" (default), in which + - ``others`` -- either ``"positive"`` (default), in which case the element will have non-negative valuation at all other - primes of self, or "negative", in which case the element will have - non-positive valuation at all other primes of self. + primes of ``self``, or ``"negative"``, in which case the element will have + non-positive valuation at all other primes of ``self``. .. note:: - When P is principal (e.g. always when self has class number - one) the result may or may not be a generator of P! + When `P` is principal (e.g., always when ``self`` has class number + one) the result may or may not be a generator of `P`! EXAMPLES:: sage: K. = NumberField(x^2 + 5); K Number Field in a with defining polynomial x^2 + 5 - sage: P,Q = K.ideal(3).prime_factors() + sage: P, Q = K.ideal(3).prime_factors() sage: P Fractional ideal (3, a + 1) sage: pi = K.uniformizer(P); pi @@ -6970,11 +7026,11 @@ def uniformizer(self, P, others="positive"): :: sage: K = CyclotomicField(9) - sage: Plist=K.ideal(17).prime_factors() + sage: Plist = K.ideal(17).prime_factors() sage: pilist = [K.uniformizer(P) for P in Plist] sage: [pi.is_integral() for pi in pilist] [True, True, True] - sage: [pi.valuation(P) for pi,P in zip(pilist,Plist)] + sage: [pi.valuation(P) for pi, P in zip(pilist, Plist)] [1, 1, 1] sage: [ pilist[i] in Plist[i] for i in range(len(Plist)) ] [True, True, True] @@ -6997,7 +7053,7 @@ def uniformizer(self, P, others="positive"): Use PARI. More precisely, use the second component of :pari:`idealprimedec` in the "positive" case. Use :pari:`idealappr` - with exponent of -1 and invert the result in the "negative" + with exponent of `-1` and invert the result in the "negative" case. TESTS: @@ -7029,11 +7085,11 @@ def units(self, proof=None): INPUT: - - ``proof`` (bool, default True) flag passed to ``pari``. + - ``proof`` (bool, default ``True``) flag passed to PARI. .. note:: - For more functionality see the unit_group() function. + For more functionality see :meth:`unit_group`. .. SEEALSO:: @@ -7111,7 +7167,7 @@ def unit_group(self, proof=None): INPUT: - - ``proof`` (bool, default True) flag passed to ``pari``. + - ``proof`` (bool, default ``True``) flag passed to PARI. .. note:: @@ -7129,7 +7185,8 @@ def unit_group(self, proof=None): sage: A = x^4 - 10*x^3 + 20*5*x^2 - 15*5^2*x + 11*5^3 sage: K = NumberField(A, 'a') sage: U = K.unit_group(); U - Unit group with structure C10 x Z of Number Field in a with defining polynomial x^4 - 10*x^3 + 100*x^2 - 375*x + 1375 + Unit group with structure C10 x Z of Number Field in a + with defining polynomial x^4 - 10*x^3 + 100*x^2 - 375*x + 1375 sage: U.gens() (u0, u1) sage: U.gens_values() # random @@ -7149,11 +7206,20 @@ def unit_group(self, proof=None): ... sage: U = K.unit_group(proof=False) sage: U - Unit group with structure C2 x Z x Z x Z x Z x Z x Z x Z x Z of Number Field in a with defining polynomial x^17 + 3 + Unit group with structure C2 x Z x Z x Z x Z x Z x Z x Z x Z of + Number Field in a with defining polynomial x^17 + 3 sage: U.gens() (u0, u1, u2, u3, u4, u5, u6, u7, u8) sage: U.gens_values() # result not independently verified - [-1, -a^9 - a + 1, -a^16 + a^15 - a^14 + a^12 - a^11 + a^10 + a^8 - a^7 + 2*a^6 - a^4 + 3*a^3 - 2*a^2 + 2*a - 1, 2*a^16 - a^14 - a^13 + 3*a^12 - 2*a^10 + a^9 + 3*a^8 - 3*a^6 + 3*a^5 + 3*a^4 - 2*a^3 - 2*a^2 + 3*a + 4, a^15 + a^14 + 2*a^11 + a^10 - a^9 + a^8 + 2*a^7 - a^5 + 2*a^3 - a^2 - 3*a + 1, -a^16 - a^15 - a^14 - a^13 - a^12 - a^11 - a^10 - a^9 - a^8 - a^7 - a^6 - a^5 - a^4 - a^3 - a^2 + 2, -2*a^16 + 3*a^15 - 3*a^14 + 3*a^13 - 3*a^12 + a^11 - a^9 + 3*a^8 - 4*a^7 + 5*a^6 - 6*a^5 + 4*a^4 - 3*a^3 + 2*a^2 + 2*a - 4, a^15 - a^12 + a^10 - a^9 - 2*a^8 + 3*a^7 + a^6 - 3*a^5 + a^4 + 4*a^3 - 3*a^2 - 2*a + 2, 2*a^16 + a^15 - a^11 - 3*a^10 - 4*a^9 - 4*a^8 - 4*a^7 - 5*a^6 - 7*a^5 - 8*a^4 - 6*a^3 - 5*a^2 - 6*a - 7] + [-1, + -a^9 - a + 1, + -a^16 + a^15 - a^14 + a^12 - a^11 + a^10 + a^8 - a^7 + 2*a^6 - a^4 + 3*a^3 - 2*a^2 + 2*a - 1, + 2*a^16 - a^14 - a^13 + 3*a^12 - 2*a^10 + a^9 + 3*a^8 - 3*a^6 + 3*a^5 + 3*a^4 - 2*a^3 - 2*a^2 + 3*a + 4, + a^15 + a^14 + 2*a^11 + a^10 - a^9 + a^8 + 2*a^7 - a^5 + 2*a^3 - a^2 - 3*a + 1, + -a^16 - a^15 - a^14 - a^13 - a^12 - a^11 - a^10 - a^9 - a^8 - a^7 - a^6 - a^5 - a^4 - a^3 - a^2 + 2, + -2*a^16 + 3*a^15 - 3*a^14 + 3*a^13 - 3*a^12 + a^11 - a^9 + 3*a^8 - 4*a^7 + 5*a^6 - 6*a^5 + 4*a^4 - 3*a^3 + 2*a^2 + 2*a - 4, + a^15 - a^12 + a^10 - a^9 - 2*a^8 + 3*a^7 + a^6 - 3*a^5 + a^4 + 4*a^3 - 3*a^2 - 2*a + 2, + 2*a^16 + a^15 - a^11 - 3*a^10 - 4*a^9 - 4*a^8 - 4*a^7 - 5*a^6 - 7*a^5 - 8*a^4 - 6*a^3 - 5*a^2 - 6*a - 7] """ proof = proof_flag(proof) @@ -7177,7 +7243,7 @@ def unit_group(self, proof=None): def S_unit_group(self, proof=None, S=None): """ - Return the S-unit group (including torsion) of this number field. + Return the `S`-unit group (including torsion) of this number field. ALGORITHM: Uses PARI's :pari:`bnfsunit` command. @@ -7185,10 +7251,10 @@ def S_unit_group(self, proof=None, S=None): - ``proof`` (bool, default True) flag passed to ``pari``. - - ``S`` - list or tuple of prime ideals, or an ideal, or a single + - ``S`` -- list or tuple of prime ideals, or an ideal, or a single ideal or element from which an ideal can be constructed, in - which case the support is used. If None, the global unit - group is constructed; otherwise, the S-unit group is + which case the support is used. If ``None``, the global unit + group is constructed; otherwise, the `S`-unit group is constructed. .. note:: @@ -7200,17 +7266,22 @@ def S_unit_group(self, proof=None, S=None): sage: x = polygen(QQ) sage: K. = NumberField(x^4 - 10*x^3 + 20*5*x^2 - 15*5^2*x + 11*5^3) sage: U = K.S_unit_group(S=a); U - S-unit group with structure C10 x Z x Z x Z of Number Field in a with defining polynomial x^4 - 10*x^3 + 100*x^2 - 375*x + 1375 with S = (Fractional ideal (5, 1/275*a^3 + 4/55*a^2 - 5/11*a + 5), Fractional ideal (11, 1/275*a^3 + 4/55*a^2 - 5/11*a + 9)) + S-unit group with structure C10 x Z x Z x Z of + Number Field in a with defining polynomial x^4 - 10*x^3 + 100*x^2 - 375*x + 1375 + with S = (Fractional ideal (5, 1/275*a^3 + 4/55*a^2 - 5/11*a + 5), + Fractional ideal (11, 1/275*a^3 + 4/55*a^2 - 5/11*a + 9)) sage: U.gens() (u0, u1, u2, u3) sage: U.gens_values() # random - [-1/275*a^3 + 7/55*a^2 - 6/11*a + 4, 1/275*a^3 + 4/55*a^2 - 5/11*a + 3, 1/275*a^3 + 4/55*a^2 - 5/11*a + 5, -14/275*a^3 + 21/55*a^2 - 29/11*a + 6] + [-1/275*a^3 + 7/55*a^2 - 6/11*a + 4, 1/275*a^3 + 4/55*a^2 - 5/11*a + 3, + 1/275*a^3 + 4/55*a^2 - 5/11*a + 5, -14/275*a^3 + 21/55*a^2 - 29/11*a + 6] sage: U.invariants() (10, 0, 0, 0) sage: [u.multiplicative_order() for u in U.gens()] [10, +Infinity, +Infinity, +Infinity] sage: U.primes() - (Fractional ideal (5, 1/275*a^3 + 4/55*a^2 - 5/11*a + 5), Fractional ideal (11, 1/275*a^3 + 4/55*a^2 - 5/11*a + 9)) + (Fractional ideal (5, 1/275*a^3 + 4/55*a^2 - 5/11*a + 5), + Fractional ideal (11, 1/275*a^3 + 4/55*a^2 - 5/11*a + 9)) With the default value of `S`, the S-unit group is the same as the global unit group:: @@ -7226,20 +7297,20 @@ def S_unit_group(self, proof=None, S=None): sage: K. = NumberField(x^3 + 3) sage: U = K.S_unit_group(proof=False, S=K.ideal(6).prime_factors()); U - S-unit group with structure C2 x Z x Z x Z x Z of Number Field in a with defining polynomial x^3 + 3 with S = (Fractional ideal (-a^2 + a - 1), Fractional ideal (a + 1), Fractional ideal (a)) + S-unit group with structure C2 x Z x Z x Z x Z of Number Field in a with defining polynomial x^3 + 3 + with S = (Fractional ideal (-a^2 + a - 1), Fractional ideal (a + 1), Fractional ideal (a)) sage: K. = NumberField(x^3 + 3) sage: U = K.S_unit_group(proof=False, S=K.ideal(6)); U - S-unit group with structure C2 x Z x Z x Z x Z of Number Field in a with defining polynomial x^3 + 3 with S = (Fractional ideal (-a^2 + a - 1), Fractional ideal (a + 1), Fractional ideal (a)) + S-unit group with structure C2 x Z x Z x Z x Z of Number Field in a with defining polynomial x^3 + 3 + with S = (Fractional ideal (-a^2 + a - 1), Fractional ideal (a + 1), Fractional ideal (a)) sage: K. = NumberField(x^3 + 3) sage: U = K.S_unit_group(proof=False, S=6); U - S-unit group with structure C2 x Z x Z x Z x Z of Number Field in a with defining polynomial x^3 + 3 with S = (Fractional ideal (-a^2 + a - 1), Fractional ideal (a + 1), Fractional ideal (a)) - - sage: U - S-unit group with structure C2 x Z x Z x Z x Z of Number Field in a with defining polynomial x^3 + 3 with S = (Fractional ideal (-a^2 + a - 1), Fractional ideal (a + 1), Fractional ideal (a)) + S-unit group with structure C2 x Z x Z x Z x Z of Number Field in a with defining polynomial x^3 + 3 + with S = (Fractional ideal (-a^2 + a - 1), Fractional ideal (a + 1), Fractional ideal (a)) sage: U.primes() (Fractional ideal (-a^2 + a - 1), - Fractional ideal (a + 1), - Fractional ideal (a)) + Fractional ideal (a + 1), + Fractional ideal (a)) sage: U.gens() (u0, u1, u2, u3, u4) sage: U.gens_values() @@ -7303,7 +7374,7 @@ def S_unit_group(self, proof=None, S=None): def S_unit_solutions(self, S=[], prec=106, include_exponents=False, include_bound=False, proof=None): r""" - Return all solutions to the S-unit equation ``x + y = 1`` over K. + Return all solutions to the `S`-unit equation `x + y = 1` over ``self``. INPUT: @@ -7315,19 +7386,24 @@ def S_unit_solutions(self, S=[], prec=106, include_exponents=False, include_boun OUTPUT: - A list of tuples ``[( A_1, B_1, x_1, y_1), (A_2, B_2, x_2, y_2), ... ( A_n, B_n, x_n, y_n)]`` such that: + A list `[(A_1, B_1, x_1, y_1), (A_2, B_2, x_2, y_2), \dots, (A_n, B_n, x_n, y_n)]` of tuples such that: + + 1. The first two entries are tuples `A_i = (a_0, a_1, \dots, a_t)` and `B_i = (b_0, b_1, \dots, b_t)` of exponents. + These will be omitted if ``include_exponents`` is ``False``. + + 2. The last two entries are `S`-units `x_i` and `y_i` in ``self`` with `x_i + y_i = 1`. - 1. The first two entries are tuples ``A_i = (a_0, a_1, ... , a_t)`` and ``B_i = (b_0, b_1, ... , b_t)`` of exponents. These will be omitted if ``include_exponents`` is ``False``. - 2. The last two entries are ``S``-units ``x_i`` and ``y_i`` in ``K`` with ``x_i + y_i = 1``. - 3. If the default generators for the ``S``-units of ``K`` are ``(rho_0, rho_1, ... , rho_t)``, then these satisfy ``x_i = \prod(rho_i)^(a_i)`` and ``y_i = \prod(rho_i)^(b_i)``. + 3. If the default generators for the `S`-units of ``self`` are `(\rho_0, \rho_1, \dots, \rho_t)``, + then these satisfy `x_i = \prod(\rho_i)^{(a_i)}` and `y_i = \prod(\rho_i)^{(b_i)}`. - If ``include_bound``, will return a pair ``(sols, bound)`` where ``sols`` is as above and ``bound`` is the bound used for the entries in the exponent vectors. + If ``include_bound`` is ``True``, will return a pair ``(sols, bound)`` where ``sols`` is as above + and ``bound`` is the bound used for the entries in the exponent vectors. EXAMPLES:: - sage: K. = NumberField(x^2+x+1) + sage: K. = NumberField(x^2 + x + 1) sage: S = K.primes_above(3) - sage: K.S_unit_solutions(S) # random, due to ordering + sage: K.S_unit_solutions(S) # random, due to ordering [(xi + 2, -xi - 1), (1/3*xi + 2/3, -1/3*xi + 1/3), (-xi, xi + 1), (-xi + 1, xi)] You can get the exponent vectors:: @@ -7349,14 +7425,14 @@ def S_unit_solutions(self, S=[], prec=106, include_exponents=False, include_boun def zeta(self, n=2, all=False): """ - Return one, or a list of all, primitive n-th root of unity in this field. + Return one, or a list of all, primitive `n`-th root of unity in this field. INPUT: - - ``n`` -- positive integer + - ``n`` -- positive integer - ``all`` -- boolean. If ``False`` (default), return a primitive - `n`-th root of unity in this field, or raise a ``ValueError`` + `n`-th root of unity in this field, or raise a :class:`ValueError` exception if there are none. If ``True``, return a list of all primitive `n`-th roots of unity in this field (possibly empty). @@ -7392,7 +7468,7 @@ def zeta(self, n=2, all=False): :: sage: r. = QQ[] - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: K.zeta(4) b sage: K.zeta(4,all=True) @@ -7401,7 +7477,7 @@ def zeta(self, n=2, all=False): Traceback (most recent call last): ... ValueError: there are no 3rd roots of unity in self - sage: K.zeta(3,all=True) + sage: K.zeta(3, all=True) [] Number fields defined by non-monic and non-integral @@ -7465,10 +7541,10 @@ def zeta_order(self): EXAMPLES:: - sage: F. = NumberField(x**22+3) + sage: F. = NumberField(x^22 + 3) sage: F.zeta_order() 6 - sage: F. = NumberField(x**2-7) + sage: F. = NumberField(x^2 - 7) sage: F.zeta_order() 2 @@ -7510,13 +7586,13 @@ def primitive_root_of_unity(self): EXAMPLES:: - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: z = K.primitive_root_of_unity(); z i sage: z.multiplicative_order() 4 - sage: K. = NumberField(x^2+x+1) + sage: K. = NumberField(x^2 + x + 1) sage: z = K.primitive_root_of_unity(); z a + 1 sage: z.multiplicative_order() @@ -7581,10 +7657,10 @@ def roots_of_unity(self): EXAMPLES:: - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: zs = K.roots_of_unity(); zs [b, -1, -b, 1] - sage: [ z**K.number_of_roots_of_unity() for z in zs ] + sage: [z**K.number_of_roots_of_unity() for z in zs] [1, 1, 1, 1] """ z = self.primitive_root_of_unity() @@ -7593,13 +7669,13 @@ def roots_of_unity(self): def zeta_coefficients(self, n): """ - Compute the first n coefficients of the Dedekind zeta function of + Compute the first `n` coefficients of the Dedekind zeta function of this field as a Dirichlet series. EXAMPLES:: sage: x = QQ['x'].0 - sage: NumberField(x^2+1, 'a').zeta_coefficients(10) + sage: NumberField(x^2 + 1, 'a').zeta_coefficients(10) [1, 1, 0, 1, 2, 0, 0, 1, 1, 2] """ return self.pari_nf().dirzetak(n) @@ -7614,11 +7690,11 @@ def solve_CRT(self, reslist, Ilist, check=True): - ``Ilist`` -- a list of integral ideals, assumed pairwise coprime - - ``check`` (boolean, default True) -- if True, result is checked + - ``check`` -- (boolean, default ``True``) if ``True``, result is checked OUTPUT: - An integral element x such that x-reslist[i] is in Ilist[i] for all i. + An integral element `x` such that ``x - reslist[i]`` is in ``Ilist[i]`` for all `i`. .. note:: @@ -7627,17 +7703,17 @@ def solve_CRT(self, reslist, Ilist, check=True): EXAMPLES:: - sage: K. = NumberField(x^2-10) + sage: K. = NumberField(x^2 - 10) sage: Ilist = [K.primes_above(p)[0] for p in prime_range(10)] - sage: b = K.solve_CRT([1,2,3,4],Ilist,True) - sage: all(b-i-1 in Ilist[i] for i in range(4)) + sage: b = K.solve_CRT([1,2,3,4], Ilist, True) + sage: all(b - i - 1 in Ilist[i] for i in range(4)) True sage: Ilist = [K.ideal(a), K.ideal(2)] - sage: K.solve_CRT([0,1],Ilist,True) + sage: K.solve_CRT([0,1], Ilist, True) Traceback (most recent call last): ... ArithmeticError: ideals in solve_CRT() must be pairwise coprime - sage: Ilist[0]+Ilist[1] + sage: Ilist[0] + Ilist[1] Fractional ideal (2, a) """ n = len(reslist) @@ -7690,7 +7766,8 @@ def valuation(self, prime): sage: K.valuation(5) Traceback (most recent call last): ... - ValueError: The valuation Gauss valuation induced by 5-adic valuation does not approximate a unique extension of 5-adic valuation with respect to x^2 + 1 + ValueError: The valuation Gauss valuation induced by 5-adic valuation does not + approximate a unique extension of 5-adic valuation with respect to x^2 + 1 The valuation can also be selected by giving a valuation on the base ring that extends uniquely:: @@ -7703,7 +7780,8 @@ def valuation(self, prime): sage: K.valuation(ZZ.valuation(5)) Traceback (most recent call last): ... - ValueError: The valuation Gauss valuation induced by 5-adic valuation does not approximate a unique extension of 5-adic valuation with respect to x^2 + 1 + ValueError: The valuation Gauss valuation induced by 5-adic valuation does not + approximate a unique extension of 5-adic valuation with respect to x^2 + 1 For a number field which is of the form `K[x]/(G)`, you can specify a valuation by providing a discrete pseudo-valuation on `K[x]` which sends @@ -7711,15 +7789,16 @@ def valuation(self, prime): valuation we care about in the above example:: sage: R. = QQ[] - sage: v = K.valuation(GaussValuation(R, QQ.valuation(5)).augmentation(x + 2, infinity)) - sage: w = K.valuation(GaussValuation(R, QQ.valuation(5)).augmentation(x + 1/2, infinity)) + sage: G5 = GaussValuation(R, QQ.valuation(5)) + sage: v = K.valuation(G5.augmentation(x + 2, infinity)) + sage: w = K.valuation(G5.augmentation(x + 1/2, infinity)) sage: v == w False Note that you get the same valuation, even if you write down the pseudo-valuation differently:: - sage: ww = K.valuation(GaussValuation(R, QQ.valuation(5)).augmentation(x + 3, infinity)) + sage: ww = K.valuation(G5.augmentation(x + 3, infinity)) sage: w is ww True @@ -7729,7 +7808,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: v = GaussValuation(R, QQ.valuation(5)).augmentation(x + 3, 1) + sage: v = G5.augmentation(x + 3, 1) sage: K.valuation(v) [ 5-adic valuation, v(x + 3) = 1 ]-adic valuation @@ -7823,30 +7902,30 @@ def maximal_order(self, v=None, assume_maximal='non-maximal-non-unique'): INPUT: - - ``v`` - ``None``, a prime, or a list of integer primes (default: ``None``) + - ``v`` -- ``None``, a prime, or a list of integer primes (default: ``None``) - - if ``None``, return the maximal order. + - if ``None``, return the maximal order. - - if a prime `p`, return an order that is `p`-maximal. + - if a prime `p`, return an order that is `p`-maximal. - - if a list, return an order that is maximal at each prime of these primes + - if a list, return an order that is maximal at each prime of these primes - - ``assume_maximal`` - ``True``, ``False``, ``None``, or + - ``assume_maximal`` -- ``True``, ``False``, ``None``, or ``"non-maximal-non-unique"`` (default: ``"non-maximal-non-unique"``) ignored when ``v`` is ``None``; otherwise, controls whether we assume that the order :meth:`order.is_maximal` outside of ``v``. - - if ``True``, the order is assumed to be maximal at all primes. + - if ``True``, the order is assumed to be maximal at all primes. - - if ``False``, the order is assumed to be non-maximal at some prime - not in ``v``. + - if ``False``, the order is assumed to be non-maximal at some prime + not in ``v``. - - if ``None``, no assumptions are made about primes not in ``v``. + - if ``None``, no assumptions are made about primes not in ``v``. - - if ``"non-maximal-non-unique"`` (deprecated), like ``False``, - however, the order is not a unique parent, so creating the same - order later does typically not poison caches with the information - that the order is not maximal. + - if ``"non-maximal-non-unique"`` (deprecated), like ``False``, + however, the order is not a unique parent, so creating the same + order later does typically not poison caches with the information + that the order is not maximal. EXAMPLES: @@ -7919,7 +7998,8 @@ def maximal_order(self, v=None, assume_maximal='non-maximal-non-unique'): sage: K.maximal_order(v=2, assume_maximal=False) Traceback (most recent call last): ... - ValueError: cannot assume this order to be non-maximal because we already found it to be a maximal order + ValueError: cannot assume this order to be non-maximal + because we already found it to be a maximal order TESTS: @@ -7934,7 +8014,8 @@ def maximal_order(self, v=None, assume_maximal='non-maximal-non-unique'): sage: K. = NumberField([x^4 + 1, x^4 - 3]) sage: K.maximal_order() - Maximal Relative Order in Number Field in a with defining polynomial x^4 + 1 over its base field + Maximal Relative Order in + Number Field in a with defining polynomial x^4 + 1 over its base field An example with nontrivial ``v``:: @@ -7962,7 +8043,7 @@ def maximal_order(self, v=None, assume_maximal='non-maximal-non-unique'): class NumberField_absolute(NumberField_generic): def __init__(self, polynomial, name, latex_name=None, check=True, embedding=None, assume_disc_small=False, maximize_at_primes=None, structure=None): - """ + r""" Function to initialize an absolute number field. EXAMPLES:: @@ -7982,7 +8063,7 @@ def __init__(self, polynomial, name, latex_name=None, check=True, embedding=None self._init_embedding_approx() def _coerce_from_other_number_field(self, x): - """ + r""" Coerce a number field element x into this number field. Unless `x` is in ``QQ``, this requires ``x.parent()`` and @@ -8018,7 +8099,9 @@ def _coerce_from_other_number_field(self, x): sage: K._coerce_from_other_number_field(b) Traceback (most recent call last): ... - TypeError: No compatible natural embeddings found for Number Field in a with defining polynomial x^3 + 2 and Number Field in b with defining polynomial x^2 + 1 + TypeError: No compatible natural embeddings found for + Number Field in a with defining polynomial x^3 + 2 and + Number Field in b with defining polynomial x^2 + 1 Two number fields both containing `i`:: @@ -8045,7 +8128,9 @@ def _coerce_from_other_number_field(self, x): sage: L(1/2*a^3 + 5/2*a) Traceback (most recent call last): ... - TypeError: No compatible natural embeddings found for Number Field in b with defining polynomial x^4 + 8*x^2 + 4 and Number Field in a with defining polynomial x^4 + 6*x^2 + 1 + TypeError: No compatible natural embeddings found for + Number Field in b with defining polynomial x^4 + 8*x^2 + 4 and + Number Field in a with defining polynomial x^4 + 6*x^2 + 1 Embeddings can also be `p`-adic:: @@ -8063,7 +8148,8 @@ def _coerce_from_other_number_field(self, x): sage: L(a) Traceback (most recent call last): ... - ValueError: cannot convert a to Number Field in b with defining polynomial x^3 - 4*x + 1 with b = 1.860805853111704? (using the specified embeddings) + ValueError: cannot convert a to Number Field in b with defining polynomial x^3 - 4*x + 1 + with b = 1.860805853111704? (using the specified embeddings) Subfields automatically come with an embedding:: @@ -8216,7 +8302,7 @@ def _coerce_from_other_number_field(self, x): raise ValueError("cannot convert %s to %s (using the specified embeddings)" % (x, K)) def _coerce_map_from_(self, R): - """ + r""" Canonical coercion of a ring R into self. Currently any ring coercing into the base ring canonically coerces @@ -8322,8 +8408,8 @@ def _coerce_map_from_(self, R): return None def base_field(self): - """ - Return the base field of self, which is always ``QQ``. + r""" + Return the base field of ``self``, which is always ``QQ``. EXAMPLES:: @@ -8334,8 +8420,8 @@ def base_field(self): return QQ def is_absolute(self): - """ - Return ``True`` since self is an absolute field. + r""" + Return ``True`` since ``self`` is an absolute field. EXAMPLES:: @@ -8348,7 +8434,7 @@ def is_absolute(self): def absolute_polynomial(self): r""" Return absolute polynomial that defines this absolute field. This - is the same as ``self.polynomial()``. + is the same as :meth:`polynomial`. EXAMPLES:: @@ -8377,10 +8463,10 @@ def absolute_generator(self): return self.gen() def optimized_representation(self, name=None, both_maps=True): - """ - Return a field isomorphic to self with a better defining polynomial + r""" + Return a field isomorphic to ``self`` with a better defining polynomial if possible, along with field isomorphisms from the new field to - self and from self to the new field. + ``self`` and from ``self`` to the new field. EXAMPLES: We construct a compositum of 3 quadratic fields, then find an optimized representation and transform elements back and @@ -8392,8 +8478,7 @@ def optimized_representation(self, name=None, both_maps=True): Number Field in b with defining polynomial x^8 + 40*x^6 + 352*x^4 + 960*x^2 + 576 sage: L, from_L, to_L = K.optimized_representation() sage: L # your answer may different, since algorithm is random - Number Field in b1 with defining polynomial x^8 + 4*x^6 + 7*x^4 + - 36*x^2 + 81 + Number Field in b1 with defining polynomial x^8 + 4*x^6 + 7*x^4 + 36*x^2 + 81 sage: to_L(K.0) # random 4/189*b1^7 + 1/63*b1^6 + 1/27*b1^5 - 2/9*b1^4 - 5/27*b1^3 - 8/9*b1^2 + 3/7*b1 - 3/7 sage: from_L(L.0) # random @@ -8479,8 +8564,8 @@ def optimized_representation(self, name=None, both_maps=True): def optimized_subfields(self, degree=0, name=None, both_maps=True): """ Return optimized representations of many (but *not* necessarily - all!) subfields of self of the given degree, or of all possible degrees if - degree is 0. + all!) subfields of ``self`` of the given ``degree``, or of all possible degrees if + ``degree`` is 0. EXAMPLES:: @@ -8506,10 +8591,12 @@ def optimized_subfields(self, degree=0, name=None, both_maps=True): sage: from_M # may be slightly random Ring morphism: From: Number Field in b2 with defining polynomial x^4 - 5*x^2 + 25 - To: Number Field in a1 with defining polynomial x^8 + 40*x^6 + 352*x^4 + 960*x^2 + 576 - Defn: b2 |--> -5/1152*a1^7 + 1/96*a1^6 - 97/576*a1^5 + 17/48*a1^4 - 95/72*a1^3 + 17/12*a1^2 - 53/24*a1 - 1 + To: Number Field in a1 with defining polynomial + x^8 + 40*x^6 + 352*x^4 + 960*x^2 + 576 + Defn: b2 |--> -5/1152*a1^7 + 1/96*a1^6 - 97/576*a1^5 + 17/48*a1^4 + - 95/72*a1^3 + 17/12*a1^2 - 53/24*a1 - 1 - The to_M map is None, since there is no map from K to M:: + The ``to_M`` map is ``None``, since there is no map from `K` to `M`:: sage: to_M @@ -8517,7 +8604,8 @@ def optimized_subfields(self, degree=0, name=None, both_maps=True): rather large element of `K`:: sage: from_M(M.0) # random - -5/1152*a1^7 + 1/96*a1^6 - 97/576*a1^5 + 17/48*a1^4 - 95/72*a1^3 + 17/12*a1^2 - 53/24*a1 - 1 + -5/1152*a1^7 + 1/96*a1^6 - 97/576*a1^5 + 17/48*a1^4 + - 95/72*a1^3 + 17/12*a1^2 - 53/24*a1 - 1 Nevertheless, that large-ish element lies in a degree 4 subfield:: @@ -8570,18 +8658,16 @@ def optimized_subfields(self, degree=0, name=None, both_maps=True): def change_names(self, names): r""" - Return number field isomorphic to self but with the given generator + Return number field isomorphic to ``self`` but with the given generator name. INPUT: + - ``names`` -- should be exactly one variable name. - - ``names`` - should be exactly one variable name. - - - Also, ``K.structure()`` returns from_K and to_K, - where from_K is an isomorphism from K to self and to_K is an - isomorphism from self to K. + Also, ``K.structure()`` returns ``from_K`` and ``to_K``, + where ``from_K`` is an isomorphism from `K` to ``self`` and ``to_K`` is an + isomorphism from ``self`` to `K`. EXAMPLES:: @@ -8601,9 +8687,9 @@ def change_names(self, names): def subfields(self, degree=0, name=None): """ - Return all subfields of self of the given degree, - or of all possible degrees if degree is 0. The subfields are returned as - absolute fields together with an embedding into self. For the case of the + Return all subfields of ``self`` of the given ``degree``, + or of all possible degrees if ``degree`` is 0. The subfields are returned as + absolute fields together with an embedding into ``self``. For the case of the field itself, the reverse isomorphism is also provided. EXAMPLES:: @@ -8674,7 +8760,7 @@ def subfields(self, degree=0, name=None): def _subfields_helper(self, degree=0, name=None, both_maps=True, optimize=False): """ - Internal function: common code for optimized_subfields() and subfields(). + Internal function: common code for :meth:`optimized_subfields` and :meth:`subfields`. TESTS: @@ -8789,17 +8875,17 @@ def order(self, *args, **kwds): INPUT: - - ``gens`` - list of elements in this number field; if no generators + - ``gens`` -- list of elements in this number field; if no generators are given, just returns the cardinality of this number field (`\infty`) for consistency. - - ``check_is_integral`` - bool (default: ``True``), whether to check + - ``check_is_integral`` -- bool (default: ``True``), whether to check that each generator is integral. - - ``check_rank`` - bool (default: ``True``), whether to check that the + - ``check_rank`` -- bool (default: ``True``), whether to check that the ring generated by ``gens`` is of full rank. - - ``allow_subfield`` - bool (default: ``False``), if ``True`` and the + - ``allow_subfield`` -- bool (default: ``False``), if ``True`` and the generators do not generate an order, i.e., they generate a subring of smaller rank, instead of raising an error, return an order in a smaller number field. @@ -8888,8 +8974,8 @@ def _order(self, gens, **kwds): @cached_method(key=lambda self, base, basis, map: (base or self.base_ring(), basis, map)) def free_module(self, base=None, basis=None, map=True): - """ - Return a vector space V and isomorphisms self --> V and V --> self. + r""" + Return a vector space `V` and isomorphisms ``self`` `\to` `V` and `V` `\to` ``self``. INPUT: @@ -8902,16 +8988,13 @@ def free_module(self, base=None, basis=None, map=True): - ``maps`` -- boolean (default ``True``), whether to return `R`-linear maps to and from `V` - OUTPUT: + - `V` - a vector space over the rational numbers - - ``V`` - a vector space over the rational numbers - - - ``from_V`` - an isomorphism from V to self (if requested) - - - ``to_V`` - an isomorphism from self to V (if requested) + - ``from_V`` -- an isomorphism from `V` to ``self`` (if requested) + - ``to_V`` -- an isomorphism from ``self`` to `V` (if requested) EXAMPLES:: @@ -8952,7 +9035,7 @@ def absolute_vector_space(self, *args, **kwds): and in the other direction. For an absolute extension this is identical to - ``self.vector_space()``. + :meth:`vector_space`. EXAMPLES:: @@ -8970,12 +9053,12 @@ def absolute_vector_space(self, *args, **kwds): def _galois_closure_and_embedding(self, names=None): r""" - Return number field `K` that is the Galois closure of self and an - embedding of self into `K`. + Return number field `K` that is the Galois closure of ``self`` and an + embedding of ``self`` into `K`. INPUT: - - ``names`` - variable name for Galois closure + - ``names`` -- variable name for Galois closure .. warning:: @@ -9020,15 +9103,15 @@ def _galois_closure_and_embedding(self, names=None): def galois_closure(self, names=None, map=False): """ - Return number field `K` that is the Galois closure of self, + Return number field `K` that is the Galois closure of ``self``, i.e., is generated by all roots of the defining polynomial of - self, and possibly an embedding of self into `K`. + ``self``, and possibly an embedding of ``self`` into `K`. INPUT: - - ``names`` - variable name for Galois closure + - ``names`` -- variable name for Galois closure - - ``map`` - (default: ``False``) also return an embedding of self into `K` + - ``map`` -- (default: ``False``) also return an embedding of ``self`` into `K` EXAMPLES:: @@ -9062,7 +9145,9 @@ def galois_closure(self, names=None, map=False): sage: K. = NumberField(cyclotomic_polynomial(23)) sage: L. = K.galois_closure() sage: L - Number Field in z with defining polynomial x^22 + x^21 + x^20 + x^19 + x^18 + x^17 + x^16 + x^15 + x^14 + x^13 + x^12 + x^11 + x^10 + x^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1 + Number Field in z with defining polynomial + x^22 + x^21 + x^20 + x^19 + x^18 + x^17 + x^16 + x^15 + x^14 + x^13 + x^12 + + x^11 + x^10 + x^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1 TESTS: @@ -9083,7 +9168,7 @@ def galois_closure(self, names=None, map=False): def automorphisms(self): r""" - Compute all Galois automorphisms of self. + Compute all Galois automorphisms of ``self``. This uses PARI's :pari:`nfgaloisconj` and is much faster than root finding for many fields. @@ -9108,7 +9193,10 @@ def automorphisms(self): `L` is the Galois closure of `K`:: - sage: L = NumberField(x^24 - 84*x^22 + 2814*x^20 - 15880*x^18 - 409563*x^16 - 8543892*x^14 + 25518202*x^12 + 32831026956*x^10 - 672691027218*x^8 - 4985379093428*x^6 + 320854419319140*x^4 + 817662865724712*x^2 + 513191437605441, 'a') + sage: L = NumberField(x^24 - 84*x^22 + 2814*x^20 - 15880*x^18 - 409563*x^16 + ....: - 8543892*x^14 + 25518202*x^12 + 32831026956*x^10 + ....: - 672691027218*x^8 - 4985379093428*x^6 + 320854419319140*x^4 + ....: + 817662865724712*x^2 + 513191437605441, 'a') sage: len(L.automorphisms()) 24 @@ -9135,11 +9223,11 @@ def automorphisms(self): @cached_method def embeddings(self, K): """ - Compute all field embeddings of this field into the field K (which need + Compute all field embeddings of this field into the field `K` (which need not even be a number field, e.g., it could be the complex numbers). - This will return an identical result when given K as input again. + This will return an identical result when given `K` as input again. - If possible, the most natural embedding of this field into K + If possible, the most natural embedding of this field into `K` is put first in the list. INPUT: @@ -9166,11 +9254,13 @@ def embeddings(self, K): sage: L.embeddings(K) [ Ring morphism: - From: Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I + From: Number Field in a with defining polynomial x^2 + 7 + with a = 2.645751311064591?*I To: Cyclotomic Field of order 7 and degree 6 Defn: a |--> 2*zeta7^4 + 2*zeta7^2 + 2*zeta7 + 1, Ring morphism: - From: Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I + From: Number Field in a with defining polynomial x^2 + 7 + with a = 2.645751311064591?*I To: Cyclotomic Field of order 7 and degree 6 Defn: a |--> -2*zeta7^4 - 2*zeta7^2 - 2*zeta7 - 1 ] @@ -9226,22 +9316,22 @@ def embeddings(self, K): def minkowski_embedding(self, B=None, prec=None): r""" Return an nxn matrix over RDF whose columns are the images of the - basis `\{1, \alpha, \dots, \alpha^{n-1}\}` of self over + basis `\{1, \alpha, \dots, \alpha^{n-1}\}` of ``self`` over `\QQ` (as vector spaces), where here - `\alpha` is the generator of self over - `\QQ`, i.e. self.gen(0). If B is not None, return - the images of the vectors in B as the columns instead. If prec is - not None, use RealField(prec) instead of RDF. + `\alpha` is the generator of ``self`` over + `\QQ`, i.e. ``self.gen(0)``. If `B` is not ``None``, return + the images of the vectors in `B` as the columns instead. If ``prec`` is + not ``None``, use ``RealField(prec)`` instead of ``RDF``. This embedding is the so-called "Minkowski embedding" of a number field in `\RR^n`: given the `n` embeddings - `\sigma_1, \dots, \sigma_n` of self in + `\sigma_1, \dots, \sigma_n` of ``self`` in `\CC`, write `\sigma_1, \dots, \sigma_r` for the real embeddings, and `\sigma_{r+1}, \dots, \sigma_{r+s}` for choices of one of each pair of complex conjugate embeddings (in our case, we simply choose the one where the image of `\alpha` has positive - real part). Here `(r,s)` is the signature of self. Then the + real part). Here `(r,s)` is the signature of ``self``. Then the Minkowski embedding is given by .. MATH:: @@ -9252,9 +9342,9 @@ def minkowski_embedding(self, B=None, prec=None): \sqrt{2}\Re(\sigma_{r+s}(x)), \sqrt{2}\Im(\sigma_{r+s}(x))) - Equivalently, this is an embedding of self in `\RR^n` so + Equivalently, this is an embedding of ``self`` in `\RR^n` so that the usual norm on `\RR^n` coincides with - `|x| = \sum_i |\sigma_i(x)|^2` on self. + `|x| = \sum_i |\sigma_i(x)|^2` on ``self``. .. TODO:: @@ -9263,7 +9353,7 @@ def minkowski_embedding(self, B=None, prec=None): EXAMPLES:: - sage: F. = NumberField(x^3+2) + sage: F. = NumberField(x^3 + 2) sage: F.minkowski_embedding() [ 1.00000000000000 -1.25992104989487 1.58740105196820] [ 1.41421356237... 0.8908987181... -1.12246204830...] @@ -9321,7 +9411,7 @@ def logarithmic_embedding(self, prec=53): OUTPUT: - - the morphism of ``self`` under the logarithmic embedding in the category Set. + the morphism of ``self`` under the logarithmic embedding in the category Set. EXAMPLES:: @@ -9380,71 +9470,71 @@ def closure_map(x, prec=53): def places(self, all_complex=False, prec=None): r""" - Return the collection of all infinite places of self. + Return the collection of all infinite places of ``self``. By default, this returns the set of real places as - homomorphisms into RIF first, followed by a choice of one of - each pair of complex conjugate homomorphisms into CIF. + homomorphisms into ``RIF`` first, followed by a choice of one of + each pair of complex conjugate homomorphisms into ``CIF``. - On the other hand, if prec is not None, we simply return places - into RealField(prec) and ComplexField(prec) (or RDF, CDF if - prec=53). One can also use ``prec=infinity``, which returns embeddings + On the other hand, if ``prec`` is not ``None``, we simply return places + into ``RealField(prec)`` and ``ComplexField(prec)`` (or ``RDF``, ``CDF`` if + ``prec=53``). One can also use ``prec=infinity``, which returns embeddings into the field `\overline{\QQ}` of algebraic numbers (or its subfield `\mathbb{A}` of algebraic reals); this permits exact computation, but can be extremely slow. - There is an optional flag all_complex, which defaults to False. If - all_complex is True, then the real embeddings are returned as - embeddings into CIF instead of RIF. + There is an optional flag ``all_complex``, which defaults to ``False``. If + ``all_complex`` is ``True``, then the real embeddings are returned as + embeddings into ``CIF`` instead of ``RIF``. EXAMPLES:: - sage: F. = NumberField(x^3-100*x+1) ; F.places() + sage: F. = NumberField(x^3 - 100*x + 1); F.places() [Ring morphism: - From: Number Field in alpha with defining polynomial x^3 - 100*x + 1 - To: Real Field with 106 bits of precision - Defn: alpha |--> -10.00499625499181184573367219280, - Ring morphism: - From: Number Field in alpha with defining polynomial x^3 - 100*x + 1 - To: Real Field with 106 bits of precision - Defn: alpha |--> 0.01000001000003000012000055000273, - Ring morphism: - From: Number Field in alpha with defining polynomial x^3 - 100*x + 1 - To: Real Field with 106 bits of precision - Defn: alpha |--> 9.994996244991781845613530439509] + From: Number Field in alpha with defining polynomial x^3 - 100*x + 1 + To: Real Field with 106 bits of precision + Defn: alpha |--> -10.00499625499181184573367219280, + Ring morphism: + From: Number Field in alpha with defining polynomial x^3 - 100*x + 1 + To: Real Field with 106 bits of precision + Defn: alpha |--> 0.01000001000003000012000055000273, + Ring morphism: + From: Number Field in alpha with defining polynomial x^3 - 100*x + 1 + To: Real Field with 106 bits of precision + Defn: alpha |--> 9.994996244991781845613530439509] :: - sage: F. = NumberField(x^3+7) ; F.places() + sage: F. = NumberField(x^3 + 7); F.places() [Ring morphism: - From: Number Field in alpha with defining polynomial x^3 + 7 - To: Real Field with 106 bits of precision - Defn: alpha |--> -1.912931182772389101199116839549, - Ring morphism: - From: Number Field in alpha with defining polynomial x^3 + 7 - To: Complex Field with 53 bits of precision - Defn: alpha |--> 0.956465591386195 + 1.65664699997230*I] + From: Number Field in alpha with defining polynomial x^3 + 7 + To: Real Field with 106 bits of precision + Defn: alpha |--> -1.912931182772389101199116839549, + Ring morphism: + From: Number Field in alpha with defining polynomial x^3 + 7 + To: Complex Field with 53 bits of precision + Defn: alpha |--> 0.956465591386195 + 1.65664699997230*I] :: - sage: F. = NumberField(x^3+7) ; F.places(all_complex=True) + sage: F. = NumberField(x^3 + 7) ; F.places(all_complex=True) [Ring morphism: - From: Number Field in alpha with defining polynomial x^3 + 7 - To: Complex Field with 53 bits of precision - Defn: alpha |--> -1.91293118277239, - Ring morphism: - From: Number Field in alpha with defining polynomial x^3 + 7 - To: Complex Field with 53 bits of precision - Defn: alpha |--> 0.956465591386195 + 1.65664699997230*I] + From: Number Field in alpha with defining polynomial x^3 + 7 + To: Complex Field with 53 bits of precision + Defn: alpha |--> -1.91293118277239, + Ring morphism: + From: Number Field in alpha with defining polynomial x^3 + 7 + To: Complex Field with 53 bits of precision + Defn: alpha |--> 0.956465591386195 + 1.65664699997230*I] sage: F.places(prec=10) [Ring morphism: - From: Number Field in alpha with defining polynomial x^3 + 7 - To: Real Field with 10 bits of precision - Defn: alpha |--> -1.9, - Ring morphism: - From: Number Field in alpha with defining polynomial x^3 + 7 - To: Complex Field with 10 bits of precision - Defn: alpha |--> 0.96 + 1.7*I] + From: Number Field in alpha with defining polynomial x^3 + 7 + To: Real Field with 10 bits of precision + Defn: alpha |--> -1.9, + Ring morphism: + From: Number Field in alpha with defining polynomial x^3 + 7 + To: Complex Field with 10 bits of precision + Defn: alpha |--> 0.96 + 1.7*I] """ if prec is None: R = RIF @@ -9522,18 +9612,18 @@ def abs_val(self, v, iota, prec=None): EXAMPLES:: - sage: K. = NumberField(x^3-3) + sage: K. = NumberField(x^3 - 3) sage: phi_real = K.places()[0] sage: phi_complex = K.places()[1] sage: v_fin = tuple(K.primes_above(3))[0] - sage: K.abs_val(phi_real,xi^2) + sage: K.abs_val(phi_real, xi^2) 2.08008382305190 - sage: K.abs_val(phi_complex,xi^2) + sage: K.abs_val(phi_complex, xi^2) 4.32674871092223 - sage: K.abs_val(v_fin,xi^2) + sage: K.abs_val(v_fin, xi^2) 0.111111111111111 Check that :trac:`28345` is fixed:: @@ -9559,17 +9649,17 @@ def abs_val(self, v, iota, prec=None): def relativize(self, alpha, names, structure=None): r""" - Given an element in self or an embedding of a subfield into self, - return a relative number field `K` isomorphic to self that is relative - over the absolute field `\QQ(\alpha)` or the domain of `alpha`, along - with isomorphisms from `K` to self and from self to `K`. + Given an element in ``self`` or an embedding of a subfield into ``self``, + return a relative number field `K` isomorphic to ``self`` that is relative + over the absolute field `\QQ(\alpha)` or the domain of `\alpha`, along + with isomorphisms from `K` to ``self`` and from ``self`` to `K`. INPUT: - - ``alpha`` - an element of self or an embedding of a subfield into - self - - ``names`` - 2-tuple of names of generator for output field K and the - subfield QQ(alpha) names[0] generators K and names[1] QQ(alpha). + - ``alpha`` -- an element of ``self`` or an embedding of a subfield into + ``self`` + - ``names`` -- 2-tuple of names of generator for output field `K` and the + subfield `\QQ(\alpha)` - ``structure`` -- an instance of :class:`structure.NumberFieldStructure` or ``None`` (default: ``None``), if ``None``, then the resulting field's :meth:`structure` @@ -9578,17 +9668,18 @@ def relativize(self, alpha, names, structure=None): OUTPUT: - K -- relative number field + `K` -- relative number field - Also, ``K.structure()`` returns from_K and to_K, where - from_K is an isomorphism from K to self and to_K is an isomorphism - from self to K. + Also, ``K.structure()`` returns ``from_K`` and ``to_K``, where + ``from_K`` is an isomorphism from `K` to ``self`` and ``to_K`` is an isomorphism + from ``self`` to `K`. EXAMPLES:: sage: K. = NumberField(x^10 - 2) sage: L. = K.relativize(a^4 + a^2 + 2); L - Number Field in c with defining polynomial x^2 - 1/5*d^4 + 8/5*d^3 - 23/5*d^2 + 7*d - 18/5 over its base field + Number Field in c with defining polynomial + x^2 - 1/5*d^4 + 8/5*d^3 - 23/5*d^2 + 7*d - 18/5 over its base field sage: c.absolute_minpoly() x^10 - 2 sage: d.absolute_minpoly() @@ -9693,7 +9784,8 @@ def relativize(self, alpha, names, structure=None): sage: K. = CyclotomicField(16) sage: L, L_into_K, _ = K.subfields(4)[0]; L - Number Field in z0 with defining polynomial x^4 + 16 with z0 = 1.414213562373095? + 1.414213562373095?*I + Number Field in z0 with defining polynomial x^4 + 16 + with z0 = 1.414213562373095? + 1.414213562373095?*I sage: F, F_into_L, _ = L.subfields(2)[0]; F Number Field in z0_0 with defining polynomial x^2 + 64 with z0_0 = 8*I @@ -9820,7 +9912,7 @@ def relativize(self, alpha, names, structure=None): def absolute_degree(self): """ - A synonym for degree. + A synonym for :meth:`degree`. EXAMPLES:: @@ -9832,7 +9924,7 @@ def absolute_degree(self): def relative_degree(self): """ - A synonym for degree. + A synonym for :meth:`degree`. EXAMPLES:: @@ -9844,7 +9936,7 @@ def relative_degree(self): def relative_polynomial(self): """ - A synonym for polynomial. + A synonym for :meth:`polynomial`. EXAMPLES:: @@ -9856,7 +9948,7 @@ def relative_polynomial(self): def relative_vector_space(self, *args, **kwds): """ - A synonym for vector_space. + A synonym for :meth:`vector_space`. EXAMPLES:: @@ -9874,7 +9966,7 @@ def relative_vector_space(self, *args, **kwds): def absolute_discriminant(self): """ - A synonym for discriminant. + A synonym for :meth:`discriminant`. EXAMPLES:: @@ -9886,7 +9978,7 @@ def absolute_discriminant(self): def relative_discriminant(self): """ - A synonym for discriminant. + A synonym for :meth:`discriminant`. EXAMPLES:: @@ -9898,7 +9990,7 @@ def relative_discriminant(self): def absolute_different(self): """ - A synonym for different. + A synonym for :meth:`different`. EXAMPLES:: @@ -9910,7 +10002,7 @@ def absolute_different(self): def relative_different(self): """ - A synonym for different. + A synonym for :meth:`different`. EXAMPLES:: @@ -9922,64 +10014,64 @@ def relative_different(self): def hilbert_symbol(self, a, b, P=None): r""" - Return the Hilbert symbol `(a,b)_P` for a prime P of self - and non-zero elements a and b of self. + Return the Hilbert symbol `(a,b)_P` for a prime `P` of ``self`` + and non-zero elements `a` and `b` of ``self``. - If P is omitted, return the global Hilbert symbol `(a,b)` instead. + If `P` is omitted, return the global Hilbert symbol `(a,b)` instead. INPUT: - - ``a``, ``b`` -- elements of self + - ``a``, ``b`` -- elements of ``self`` - - ``P`` -- (default: ``None``) If `P` is ``None``, compute the global - symbol. Otherwise, `P` should be either a prime ideal of self + - ``P`` -- (default: ``None``) If ``None``, compute the global + symbol. Otherwise, `P` should be either a prime ideal of ``self`` (which may also be given as a generator or set of generators) or a real or complex embedding. OUTPUT: - If a or b is zero, returns 0. + If `a` or `b` is zero, returns 0. - If a and b are non-zero and P is specified, returns - the Hilbert symbol `(a,b)_P`, which is 1 if the equation + If `a` and `b` are non-zero and `P` is specified, returns + the Hilbert symbol `(a,b)_P`, which is `1` if the equation `a x^2 + b y^2 = 1` has a solution in the completion of - self at P, and is -1 otherwise. + ``self`` at `P`, and is `-1` otherwise. - If a and b are non-zero and P is unspecified, returns 1 - if the equation has a solution in self and -1 otherwise. + If `a` and `b` are non-zero and `P` is unspecified, returns `1` + if the equation has a solution in ``self`` and `-1` otherwise. EXAMPLES: Some global examples:: sage: K. = NumberField(x^2 - 23) - sage: K.hilbert_symbol(0, a+5) + sage: K.hilbert_symbol(0, a + 5) 0 sage: K.hilbert_symbol(a, 0) 0 - sage: K.hilbert_symbol(-a, a+1) + sage: K.hilbert_symbol(-a, a + 1) 1 - sage: K.hilbert_symbol(-a, a+2) + sage: K.hilbert_symbol(-a, a + 2) -1 - sage: K.hilbert_symbol(a, a+5) + sage: K.hilbert_symbol(a, a + 5) -1 That the latter two are unsolvable should be visible in local obstructions. For the first, this is a prime ideal above 19. For the second, the ramified prime above 23:: - sage: K.hilbert_symbol(-a, a+2, a+2) + sage: K.hilbert_symbol(-a, a + 2, a + 2) -1 - sage: K.hilbert_symbol(a, a+5, K.ideal(23).factor()[0][0]) + sage: K.hilbert_symbol(a, a + 5, K.ideal(23).factor()[0][0]) -1 More local examples:: sage: K.hilbert_symbol(a, 0, K.ideal(5)) 0 - sage: K.hilbert_symbol(a, a+5, K.ideal(5)) + sage: K.hilbert_symbol(a, a + 5, K.ideal(5)) 1 - sage: K.hilbert_symbol(a+1, 13, (a+6)*K.maximal_order()) + sage: K.hilbert_symbol(a + 1, 13, (a+6)*K.maximal_order()) -1 sage: [emb1, emb2] = K.embeddings(AA) sage: K.hilbert_symbol(a, -1, emb1) @@ -9991,10 +10083,10 @@ def hilbert_symbol(self, a, b, P=None): sage: K. = NumberField(x^5 - 23) sage: pi = 2*a^4 + 3*a^3 + 4*a^2 + 15*a + 11 - sage: K.hilbert_symbol(a, a+5, pi) + sage: K.hilbert_symbol(a, a + 5, pi) 1 sage: rho = 2*a^4 + 3*a^3 + 4*a^2 + 15*a + 11 - sage: K.hilbert_symbol(a, a+5, rho) + sage: K.hilbert_symbol(a, a + 5, rho) 1 This also works for non-principal ideals:: @@ -10003,9 +10095,9 @@ def hilbert_symbol(self, a, b, P=None): sage: P = K.ideal(3).factor()[0][0] sage: P.gens_reduced() # random, could be the other factor (3, a + 1) - sage: K.hilbert_symbol(a, a+3, P) + sage: K.hilbert_symbol(a, a + 3, P) 1 - sage: K.hilbert_symbol(a, a+3, [3, a+1]) + sage: K.hilbert_symbol(a, a + 3, [3, a+1]) 1 Primes above 2:: @@ -10013,11 +10105,11 @@ def hilbert_symbol(self, a, b, P=None): sage: K. = NumberField(x^5 - 23) sage: O = K.maximal_order() sage: p = [p[0] for p in (2*O).factor() if p[0].norm() == 16][0] - sage: K.hilbert_symbol(a, a+5, p) + sage: K.hilbert_symbol(a, a + 5, p) 1 sage: K.hilbert_symbol(a, 2, p) 1 - sage: K.hilbert_symbol(-1, a-2, p) + sage: K.hilbert_symbol(-1, a - 2, p) -1 Various real fields are allowed:: @@ -10037,36 +10129,40 @@ def hilbert_symbol(self, a, b, P=None): Traceback (most recent call last): ... ValueError: Possibly real place (=Ring morphism: - From: Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? + From: Number Field in a with defining polynomial x^2 - 5 + with a = 2.236067977499790? To: Complex Field with 53 bits of precision - Defn: a |--> -2.23606797749979) given as complex embedding in hilbert_symbol. Is it real or complex? + Defn: a |--> -2.23606797749979) + given as complex embedding in hilbert_symbol. Is it real or complex? sage: K.hilbert_symbol(-1, -1, K.embeddings(QQbar)[0]) Traceback (most recent call last): ... ValueError: Possibly real place (=Ring morphism: - From: Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? + From: Number Field in a with defining polynomial x^2 - 5 + with a = 2.236067977499790? To: Algebraic Field - Defn: a |--> -2.236067977499790?) given as complex embedding in hilbert_symbol. Is it real or complex? + Defn: a |--> -2.236067977499790?) + given as complex embedding in hilbert_symbol. Is it real or complex? sage: K. = QuadraticField(-5) sage: K.hilbert_symbol(-1, -1, K.embeddings(CDF)[0]) 1 sage: K.hilbert_symbol(-1, -1, K.embeddings(QQbar)[0]) 1 - a and b do not have to be integral or coprime:: + `a` and `b` do not have to be integral or coprime:: sage: K. = QuadraticField(-1) sage: O = K.maximal_order() sage: K.hilbert_symbol(1/2, 1/6, 3*O) 1 - sage: p = 1+i + sage: p = 1 + i sage: K.hilbert_symbol(p, p, p) 1 sage: K.hilbert_symbol(p, 3*p, p) -1 sage: K.hilbert_symbol(3, p, p) -1 - sage: K.hilbert_symbol(1/3, 1/5, 1+i) + sage: K.hilbert_symbol(1/3, 1/5, 1 + i) 1 sage: L = QuadraticField(5, 'a') sage: L.hilbert_symbol(-3, -1/2, 2) @@ -10074,24 +10170,24 @@ def hilbert_symbol(self, a, b, P=None): Various other examples:: - sage: K. = NumberField(x^3+x+1) - sage: K.hilbert_symbol(-6912, 24, -a^2-a-2) + sage: K. = NumberField(x^3 + x + 1) + sage: K.hilbert_symbol(-6912, 24, -a^2 - a - 2) 1 - sage: K. = NumberField(x^5-23) + sage: K. = NumberField(x^5 - 23) sage: P = K.ideal(-1105*a^4 + 1541*a^3 - 795*a^2 - 2993*a + 11853) sage: Q = K.ideal(-7*a^4 + 13*a^3 - 13*a^2 - 2*a + 50) sage: b = -a+5 - sage: K.hilbert_symbol(a,b,P) + sage: K.hilbert_symbol(a, b, P) 1 - sage: K.hilbert_symbol(a,b,Q) + sage: K.hilbert_symbol(a, b, Q) 1 - sage: K. = NumberField(x^5-23) + sage: K. = NumberField(x^5 - 23) sage: P = K.ideal(-1105*a^4 + 1541*a^3 - 795*a^2 - 2993*a + 11853) - sage: K.hilbert_symbol(a, a+5, P) + sage: K.hilbert_symbol(a, a + 5, P) 1 sage: K.hilbert_symbol(a, 2, P) 1 - sage: K.hilbert_symbol(a+5, 2, P) + sage: K.hilbert_symbol(a + 5, 2, P) -1 sage: K. = NumberField(x^3 - 4*x + 2) sage: K.hilbert_symbol(2, -2, K.primes_above(2)[0]) @@ -10149,13 +10245,13 @@ def hilbert_symbol(self, a, b, P=None): def hilbert_symbol_negative_at_S(self, S, b, check=True): """ - Return `a` such that the hilbert conductor of `a` and `b` is `S`. + Return `a` such that the Hilbert conductor of `a` and `b` is `S`. INPUT: - ``S`` -- a list of places (or prime ideals) of even cardinality - ``b`` -- a non-zero rational number which is a non-square locally - at every place in S. + at every place in `S`. - ``check`` -- bool (default: ``True``) perform additional checks on the input and confirm the output @@ -10192,7 +10288,7 @@ def hilbert_symbol_negative_at_S(self, S, b, check=True): sage: [k.hilbert_symbol(a, b, p) for p in S] [-1, -1, -1, -1] - Note that the closely related hilbert conductor + Note that the closely related Hilbert conductor takes only the finite places into account:: sage: k.hilbert_conductor(a, b) @@ -10324,7 +10420,7 @@ def phi(x): def hilbert_conductor(self, a, b): """ - This is the product of all (finite) primes where the Hilbert symbol is -1. + This is the product of all (finite) primes where the Hilbert symbol is `-1`. What is the same, this is the (reduced) discriminant of the quaternion algebra `(a,b)` over a number field. @@ -10334,17 +10430,17 @@ def hilbert_conductor(self, a, b): OUTPUT: - - squarefree ideal of the ring of integers of ``self`` + squarefree ideal of the ring of integers of ``self`` EXAMPLES:: - sage: F. = NumberField(x^2-x-1) - sage: F.hilbert_conductor(2*a,F(-1)) + sage: F. = NumberField(x^2 - x - 1) + sage: F.hilbert_conductor(2*a, F(-1)) Fractional ideal (2) - sage: K. = NumberField(x^3-4*x+2) - sage: K.hilbert_conductor(K(2),K(-2)) + sage: K. = NumberField(x^3 - 4*x + 2) + sage: K.hilbert_conductor(K(2), K(-2)) Fractional ideal (1) - sage: K.hilbert_conductor(K(2*b),K(-2)) + sage: K.hilbert_conductor(K(2*b), K(-2)) Fractional ideal (b^2 + b - 2) AUTHOR: @@ -10363,13 +10459,13 @@ def elements_of_bounded_height(self, **kwds): Return an iterator over the elements of ``self`` with relative multiplicative height at most ``bound``. - This algorithm computes 2 lists: L containing elements x in `K` such that - H_k(x) <= B, and a list L' containing elements x in `K` that, due to + This algorithm computes 2 lists: `L` containing elements `x` in `K` such that + `H_k(x) \leq B`, and a list `L'` containing elements `x` in `K` that, due to floating point issues, - may be slightly larger then the bound. This can be controlled + may be slightly larger than the bound. This can be controlled by lowering the tolerance. - In current implementation both lists (L,L') are merged and returned in + In the current implementation, both lists `(L,L')` are merged and returned in form of iterator. ALGORITHM: @@ -10381,15 +10477,15 @@ def elements_of_bounded_height(self, **kwds): kwds: - - ``bound`` - a real number + - ``bound`` -- a real number - - ``tolerance`` - (default: 0.01) a rational number in (0,1] + - ``tolerance`` -- (default: 0.01) a rational number in `(0,1]` - - ``precision`` - (default: 53) a positive integer + - ``precision`` -- (default: 53) a positive integer OUTPUT: - - an iterator of number field elements + an iterator of number field elements EXAMPLES: @@ -10542,8 +10638,8 @@ class NumberField_cyclotomic(NumberField_absolute, sage.rings.abc.NumberField_cy """ Create a cyclotomic extension of the rational field. - The command CyclotomicField(n) creates the n-th cyclotomic field, - obtained by adjoining an n-th root of unity to the rational field. + The command ``CyclotomicField(n)`` creates the `n`-th cyclotomic field, + obtained by adjoining an `n`-th root of unity to the rational field. EXAMPLES:: @@ -10568,26 +10664,26 @@ class NumberField_cyclotomic(NumberField_absolute, sage.rings.abc.NumberField_cy :: - sage: cf12 = CyclotomicField( 12 ) + sage: cf12 = CyclotomicField(12) sage: z12 = cf12.0 - sage: cf6 = CyclotomicField( 6 ) + sage: cf6 = CyclotomicField(6) sage: z6 = cf6.0 - sage: FF = Frac( cf12['x'] ) + sage: FF = Frac(cf12['x']) sage: x = FF.0 sage: z6*x^3/(z6 + x) zeta12^2*x^3/(x + zeta12^2) :: - sage: cf6 = CyclotomicField(6) ; z6 = cf6.gen(0) - sage: cf3 = CyclotomicField(3) ; z3 = cf3.gen(0) + sage: cf6 = CyclotomicField(6); z6 = cf6.gen(0) + sage: cf3 = CyclotomicField(3); z3 = cf3.gen(0) sage: cf3(z6) zeta3 + 1 sage: cf6(z3) zeta6 - 1 sage: type(cf6(z3)) - sage: cf1 = CyclotomicField(1) ; z1 = cf1.0 + sage: cf1 = CyclotomicField(1); z1 = cf1.0 sage: cf3(z1) 1 sage: type(cf3(z1)) @@ -10595,7 +10691,7 @@ class NumberField_cyclotomic(NumberField_absolute, sage.rings.abc.NumberField_cy """ def __init__(self, n, names, embedding=None, assume_disc_small=False, maximize_at_primes=None): """ - A cyclotomic field, i.e., a field obtained by adjoining an n-th + A cyclotomic field, i.e., a field obtained by adjoining an `n`-th root of unity to the rational numbers. EXAMPLES:: @@ -10752,10 +10848,10 @@ def _magma_init_(self, magma): EXAMPLES:: - sage: K=CyclotomicField(7,'z') # optional - magma + sage: K = CyclotomicField(7,'z') sage: K._magma_init_(magma) # optional - magma 'SageCreateWithNames(CyclotomicField(7),["z"])' - sage: K=CyclotomicField(7,'zeta') # optional - magma + sage: K = CyclotomicField(7,'zeta') sage: K._magma_init_(magma) # optional - magma 'SageCreateWithNames(CyclotomicField(7),["zeta"])' """ @@ -10830,7 +10926,7 @@ def _repr_(self): def _n(self): """ - Return the n used to create this cyclotomic field. + Return the `n` used to create this cyclotomic field. EXAMPLES:: @@ -10882,7 +10978,7 @@ def _latex_(self): def _coerce_map_from_(self, K): r""" - Return a coercion map from `K` to ``self``, or None. + Return a coercion map from `K` to ``self``, or ``None``. The cyclotomic field `\QQ(\zeta_n)` coerces into the cyclotomic field `\QQ(\zeta_m)` if and only if `n' \mid m`, @@ -10948,27 +11044,32 @@ def _coerce_map_from_(self, K): Check that custom embeddings are respected (:trac:`13765`):: - sage: z105 = CDF(exp(2*pi*I/105)) - sage: Ka. = CyclotomicField(105, embedding=z105^11) - sage: Kb. = CyclotomicField(35, embedding=z105^6) - sage: Ka.coerce_map_from(Kb) + sage: z105 = CDF(exp(2*pi*I/105)) # optional - sage.symbolic + sage: Ka. = CyclotomicField(105, embedding=z105^11) # optional - sage.symbolic + sage: Kb. = CyclotomicField(35, embedding=z105^6) # optional - sage.symbolic + sage: Ka.coerce_map_from(Kb) # optional - sage.symbolic Generic morphism: From: Cyclotomic Field of order 35 and degree 24 To: Cyclotomic Field of order 105 and degree 48 - Defn: b -> -a^44 - a^42 + a^39 + a^37 + a^35 - a^29 - a^27 - a^25 + a^24 - a^23 + a^22 - a^21 + a^20 + a^18 + a^16 - a^12 - a^10 - a^8 - a^6 + a^5 + a^3 + a - sage: CC(b) + Defn: b -> -a^44 - a^42 + a^39 + a^37 + a^35 - a^29 - a^27 - a^25 + a^24 + - a^23 + a^22 - a^21 + a^20 + a^18 + a^16 - a^12 - a^10 + - a^8 - a^6 + a^5 + a^3 + a + sage: CC(b) # optional - sage.symbolic 0.936234870639737 + 0.351374824081343*I - sage: CC(-a^44 - a^42 + a^39 + a^37 + a^35 - a^29 - a^27 - a^25 + a^24 - a^23 + a^22 - a^21 + a^20 + a^18 + a^16 - a^12 - a^10 - a^8 - a^6 + a^5 + a^3 + a) + sage: CC(-a^44 - a^42 + a^39 + a^37 + a^35 - a^29 - a^27 - a^25 + a^24 # optional - sage.symbolic + ....: - a^23 + a^22 - a^21 + a^20 + a^18 + a^16 - a^12 - a^10 + ....: - a^8 - a^6 + a^5 + a^3 + a) 0.936234870639731 + 0.351374824081341*I - sage: z15 = CDF(exp(2*pi*I/15)) - sage: CyclotomicField(15).coerce_map_from(CyclotomicField(6, embedding=-z15^5)) + sage: z15 = CDF(exp(2*pi*I/15)) # optional - sage.symbolic + sage: K6 = CyclotomicField(6, embedding=-z15^5) # optional - sage.symbolic + sage: CyclotomicField(15).coerce_map_from(K6) # optional - sage.symbolic Generic morphism: From: Cyclotomic Field of order 6 and degree 2 To: Cyclotomic Field of order 15 and degree 8 Defn: zeta6 -> -zeta15^5 - sage: CyclotomicField(15, embedding=z15^4).coerce_map_from(CyclotomicField(6, embedding=-z15^5)) + sage: CyclotomicField(15, embedding=z15^4).coerce_map_from(K6) # optional - sage.symbolic Generic morphism: From: Cyclotomic Field of order 6 and degree 2 To: Cyclotomic Field of order 15 and degree 8 @@ -11016,13 +11117,13 @@ def _coerce_map_from_(self, K): def _log_gen(self, x): """ - Return an integer `e` such that `self.gen()^e == x`, or `None` + Return an integer `e` such that `self.gen()^e == x`, or ``None`` if no such integer exists. This is primarily used to construct embedding-respecting coercions. If `x` is complex, the result is either an integer `e` such - that the absolute value of `self.gen()^e-x` is small or - `None` if no such `e` is found. + that the absolute value of ``self.gen()^e - x`` is small or + ``None`` if no such `e` is found. EXAMPLES:: @@ -11032,30 +11133,33 @@ def _log_gen(self, x): sage: K._log_gen(CDF(a^4)) 4 - sage: zeta105 = CC(exp(2*pi*i/105)) - sage: K. = CyclotomicField(105, embedding=zeta105^13) - sage: zeta105^13, CC(a) - (0.712376096951345 + 0.701797902883992*I, 0.712376096951345 + 0.701797902883991*I) - sage: K._log_gen(zeta105^26) + sage: zeta105 = CC(exp(2*pi*i/105)) # optional - sage.symbolic + sage: K. = CyclotomicField(105, embedding=zeta105^13) # optional - sage.symbolic + sage: zeta105^13, CC(a) # optional - sage.symbolic + (0.712376096951345 + 0.701797902883992*I, + 0.712376096951345 + 0.701797902883991*I) + sage: K._log_gen(zeta105^26) # optional - sage.symbolic 2 - sage: K._log_gen(zeta105) + sage: K._log_gen(zeta105) # optional - sage.symbolic 97 - sage: zeta105, CC(a^97) - (0.998210129767735 + 0.0598041539450342*I, 0.998210129767736 + 0.0598041539450313*I) - sage: K._log_gen(zeta105^3) + sage: zeta105, CC(a^97) # optional - sage.symbolic + (0.998210129767735 + 0.0598041539450342*I, + 0.998210129767736 + 0.0598041539450313*I) + sage: K._log_gen(zeta105^3) # optional - sage.symbolic 81 - sage: zeta105^3, CC(a)^81 - (0.983929588598630 + 0.178556894798637*I, 0.983929588598631 + 0.178556894798635*I) + sage: zeta105^3, CC(a)^81 # optional - sage.symbolic + (0.983929588598630 + 0.178556894798637*I, + 0.983929588598631 + 0.178556894798635*I) sage: K. = CyclotomicField(5, embedding=None) sage: K._log_gen(CDF(.5, -.8)) is None True - sage: zeta5 = cyclotomic_polynomial(5).change_ring(Qp(11)).roots()[0][0] - sage: zeta5 ^ 5 + sage: zeta5 = cyclotomic_polynomial(5).change_ring(Qp(11)).roots()[0][0] # optional - sage.rings.padics + sage: zeta5 ^ 5 # optional - sage.rings.padics 1 + O(11^20) - sage: K. = CyclotomicField(5, embedding=zeta5^2) - sage: K._log_gen(zeta5) + sage: K. = CyclotomicField(5, embedding=zeta5^2) # optional - sage.rings.padics + sage: K._log_gen(zeta5) # optional - sage.rings.padics 3 sage: K60. = CyclotomicField(60) @@ -11103,20 +11207,19 @@ def _log_gen(self, x): gen_pow_e *= gen def _element_constructor_(self, x, check=True): - """ + r""" Create an element of this cyclotomic field from `x`. EXAMPLES: The following example illustrates coercion from the - cyclotomic field Q(zeta_42) to the cyclotomic field Q(zeta_6), in + cyclotomic field `\QQ(\zeta_{42})` to the cyclotomic field `\QQ(\zeta_6)`, in a case where such coercion is defined:: sage: k42 = CyclotomicField(42) sage: k6 = CyclotomicField(6) sage: a = k42.gen(0) - sage: b = a^7 - sage: b + sage: b = a^7; b zeta42^7 sage: k6(b) # indirect doctest zeta6 @@ -11136,9 +11239,9 @@ def _element_constructor_(self, x, check=True): sage: CF(E(5)) zeta10^2 - Coercion of GAP cyclotomic elements is also supported:: + Coercion of GAP cyclotomic elements is also supported:: - sage: CyclotomicField(18)(gap('E(3)')) # indirect doctest + sage: CyclotomicField(18)(gap('E(3)')) # indirect doctest # optional - sage.libs.gap zeta18^3 - 1 Converting from rings of integers:: @@ -11171,21 +11274,21 @@ def _element_constructor_(self, x, check=True): def _coerce_from_other_cyclotomic_field(self, x, only_canonical=False): """ - Coerce an element x of a cyclotomic field into self, if at all + Coerce an element `x` of a cyclotomic field into ``self``, if at all possible. INPUT: - - ``x`` - number field element + - ``x`` -- number field element - - ``only_canonical`` - bool (default: ``False``); Attempt - to work, even in some cases when x is not in a subfield of the - cyclotomics (as long as x is a root of unity). + - ``only_canonical`` -- bool (default: ``False``); Attempt + to work, even in some cases when `x` is not in a subfield of the + cyclotomics (as long as `x` is a root of unity). EXAMPLES:: - sage: K = CyclotomicField(24) ; L = CyclotomicField(48) - sage: L._coerce_from_other_cyclotomic_field(K.0+1) + sage: K = CyclotomicField(24); L = CyclotomicField(48) + sage: L._coerce_from_other_cyclotomic_field(K.0 + 1) zeta48^2 + 1 sage: K(L.0**2) zeta24 @@ -11232,12 +11335,11 @@ def _coerce_from_gap(self, x): EXAMPLES:: sage: k5. = CyclotomicField(5) - sage: w = libgap.eval('E(5)^7 + 3') - sage: w + sage: w = libgap.eval('E(5)^7 + 3'); w # optional - sage.libs.gap -3*E(5)-2*E(5)^2-3*E(5)^3-3*E(5)^4 - sage: z^7 + 3 + sage: z^7 + 3 # optional - sage.libs.gap z^2 + 3 - sage: k5(w) # indirect doctest + sage: k5(w) # indirect doctest # optional - sage.libs.gap z^2 + 3 It may be that GAP uses a name for the generator of the cyclotomic field. @@ -11245,28 +11347,28 @@ def _coerce_from_gap(self, x): sage: F = CyclotomicField(8) sage: z = F.gen() - sage: a = libgap(z+1/z); a + sage: a = libgap(z + 1/z); a # optional - sage.libs.gap E(8)-E(8)^3 - sage: F(a) + sage: F(a) # optional - sage.libs.gap -zeta8^3 + zeta8 Matrices over cyclotomic fields are correctly dealt with it as well:: - sage: b = libgap.eval('[[E(4), 1], [0, 1+E(8)-E(8)^3]]') - sage: matrix(F, b) + sage: b = libgap.eval('[[E(4), 1], [0, 1+E(8)-E(8)^3]]') # optional - sage.libs.gap + sage: matrix(F, b) # optional - sage.libs.gap [ zeta8^2 1] [ 0 -zeta8^3 + zeta8 + 1] It also works with the old pexpect interface to GAP:: - sage: a = gap(z + 1/z) - sage: b = gap(Matrix(F,[[z^2,1],[0,a+1]])); b + sage: a = gap(z + 1/z) # optional - sage.libs.gap + sage: b = gap(Matrix(F,[[z^2,1],[0,a+1]])); b # optional - sage.libs.gap [ [ E(4), 1 ], [ 0, 1+E(8)-E(8)^3 ] ] - sage: b[1,2] + sage: b[1,2] # optional - sage.libs.gap 1 - sage: F(b[1,2]) + sage: F(b[1,2]) # optional - sage.libs.gap 1 - sage: matrix(F, b) + sage: matrix(F, b) # optional - sage.libs.gap [ zeta8^2 1] [ 0 -zeta8^3 + zeta8 + 1] """ @@ -11278,10 +11380,10 @@ def _coerce_from_gap(self, x): def _Hom_(self, codomain, cat=None): """ - Return homset of homomorphisms from the cyclotomic field self to + Return homset of homomorphisms from the cyclotomic field ``self`` to the number field codomain. - The cat option is currently ignored. + The ``cat`` option is currently ignored. EXAMPLES: @@ -11293,7 +11395,9 @@ def _Hom_(self, codomain, cat=None): sage: K. = NumberField(x^2 + 3); K Number Field in a with defining polynomial x^2 + 3 sage: CyclotomicField(3).Hom(K) # indirect doctest - Set of field embeddings from Cyclotomic Field of order 3 and degree 2 to Number Field in a with defining polynomial x^2 + 3 + Set of field embeddings + from Cyclotomic Field of order 3 and degree 2 + to Number Field in a with defining polynomial x^2 + 3 sage: End(CyclotomicField(21)) Automorphism group of Cyclotomic Field of order 21 and degree 12 """ @@ -11305,7 +11409,7 @@ def _Hom_(self, codomain, cat=None): def is_galois(self): """ - Return True since all cyclotomic fields are automatically Galois. + Return ``True`` since all cyclotomic fields are automatically Galois. EXAMPLES:: @@ -11316,7 +11420,7 @@ def is_galois(self): def is_abelian(self): """ - Return True since all cyclotomic fields are automatically abelian. + Return ``True`` since all cyclotomic fields are automatically abelian. EXAMPLES:: @@ -11327,8 +11431,8 @@ def is_abelian(self): def is_isomorphic(self, other): """ - Return True if the cyclotomic field self is isomorphic as a number - field to other. + Return ``True`` if the cyclotomic field ``self`` is isomorphic as a number + field to ``other``. EXAMPLES:: @@ -11336,7 +11440,7 @@ def is_isomorphic(self, other): True sage: CyclotomicField(11).is_isomorphic(CyclotomicField(23)) False - sage: CyclotomicField(3).is_isomorphic(NumberField(x^2 + x +1, 'a')) + sage: CyclotomicField(3).is_isomorphic(NumberField(x^2 + x + 1, 'a')) True sage: CyclotomicField(18).is_isomorphic(CyclotomicField(9)) True @@ -11346,7 +11450,7 @@ def is_isomorphic(self, other): Check :trac:`14300`:: sage: K = CyclotomicField(4) - sage: N = K.extension(x^2-5, 'z') + sage: N = K.extension(x^2 - 5, 'z') sage: K.is_isomorphic(N) False sage: K.is_isomorphic(CyclotomicField(8)) @@ -11359,8 +11463,8 @@ def is_isomorphic(self, other): def complex_embedding(self, prec=53): r""" Return the embedding of this cyclotomic field into the approximate - complex field with precision prec obtained by sending the generator - `\zeta` of self to exp(2\*pi\*i/n), where `n` is + complex field with precision ``prec`` obtained by sending the generator + `\zeta` of ``self`` to exp(2\*pi\*i/n), where `n` is the multiplicative order of `\zeta`. EXAMPLES:: @@ -11372,8 +11476,8 @@ def complex_embedding(self, prec=53): To: Complex Field with 53 bits of precision Defn: zeta4 |--> 6.12323399573677e-17 + 1.00000000000000*I - Note in the example above that the way zeta is computed (using sin - and cosine in MPFR) means that only the prec bits of the number + Note in the example above that the way zeta is computed (using sine + and cosine in MPFR) means that only the ``prec`` bits of the number after the decimal point are valid. :: @@ -11395,7 +11499,7 @@ def complex_embedding(self, prec=53): @cached_method def embeddings(self, K): r""" - Compute all field embeddings of this field into the field ``K``. + Compute all field embeddings of this field into the field `K`. INPUT: @@ -11408,7 +11512,7 @@ def embeddings(self, K): From: Cyclotomic Field of order 5 and degree 4 To: Complex Field with 53 bits of precision Defn: zeta5 |--> -0.809016994374947 + 0.587785252292473*I - sage: CyclotomicField(5).embeddings(Qp(11, 4, print_mode='digits'))[1] + sage: CyclotomicField(5).embeddings(Qp(11, 4, print_mode='digits'))[1] # optional - sage.rings.padics Ring morphism: From: Cyclotomic Field of order 5 and degree 4 To: 11-adic Field with capped relative precision 4 @@ -11435,7 +11539,7 @@ def embeddings(self, K): def complex_embeddings(self, prec=53): r""" Return all embeddings of this cyclotomic field into the approximate - complex field with precision prec. + complex field with precision ``prec``. If you want 53-bit double precision, which is faster but less reliable, then do ``self.embeddings(CDF)``. @@ -11468,7 +11572,7 @@ def complex_embeddings(self, prec=53): def real_embeddings(self, prec=53): r""" Return all embeddings of this cyclotomic field into the approximate - real field with precision prec. + real field with precision ``prec``. Mostly, of course, there are no such embeddings. @@ -11488,12 +11592,12 @@ def real_embeddings(self, prec=53): return self.embeddings(K) def signature(self): - """ - Return (r1, r2), where r1 and r2 are the number of real embeddings + r""" + Return `(r_1, r_2)`, where `r_1` and `r_2` are the number of real embeddings and pairs of complex embeddings of this cyclotomic field, respectively. - Trivial since, apart from QQ, cyclotomic fields are totally + Trivial since, apart from `\QQ`, cyclotomic fields are totally complex. EXAMPLES:: @@ -11511,7 +11615,7 @@ def signature(self): def different(self): """ - Return the different ideal of the cyclotomic field self. + Return the different ideal of the cyclotomic field ``self``. EXAMPLES:: @@ -11543,20 +11647,17 @@ def different(self): def discriminant(self, v=None): """ Return the discriminant of the ring of integers of the cyclotomic - field self, or if v is specified, the determinant of the trace - pairing on the elements of the list v. + field ``self``, or if ``v`` is specified, the determinant of the trace + pairing on the elements of the list ``v``. Uses the formula for the discriminant of a prime power cyclotomic field and Hilbert Theorem 88 on the discriminant of composita. INPUT: + - ``v`` -- (optional) list of elements of this number field - - ``v (optional)`` - list of element of this number - field - - - OUTPUT: Integer if v is omitted, and Rational otherwise. + OUTPUT: Integer if ``v`` is omitted, and Rational otherwise. EXAMPLES:: @@ -11652,8 +11753,8 @@ def zeta_order(self): return self.__zeta_order def _multiplicative_order_table(self): - """ - Return a dictionary that maps powers of zeta to their order. This + r""" + Return a dictionary that maps powers of `\zeta` to their order. This makes computing the orders of the elements of finite order in this field faster. @@ -11684,7 +11785,7 @@ def zeta(self, n=None, all=False): Return an element of multiplicative order `n` in this cyclotomic field. - If there is no such element, raise a ``ValueError``. + If there is no such element, raise a :class:`ValueError`. INPUT: @@ -11968,27 +12069,26 @@ def _polymake_init_(self): def discriminant(self, v=None): """ Return the discriminant of the ring of integers of the number - field, or if v is specified, the determinant of the trace pairing - on the elements of the list v. + field, or if ``v`` is specified, the determinant of the trace pairing + on the elements of the list ``v``. INPUT: - - ``v (optional)`` - list of element of this number - field + - ``v`` -- (optional) list of element of this number field - OUTPUT: Integer if v is omitted, and Rational otherwise. + OUTPUT: Integer if ``v`` is omitted, and Rational otherwise. EXAMPLES:: - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: K.discriminant() -4 - sage: K. = NumberField(x^2+5) + sage: K. = NumberField(x^2 + 5) sage: K.discriminant() -20 - sage: K. = NumberField(x^2-5) + sage: K. = NumberField(x^2 - 5) sage: K.discriminant() 5 """ @@ -12006,7 +12106,7 @@ def discriminant(self, v=None): def is_galois(self): """ - Return True since all quadratic fields are automatically Galois. + Return ``True`` since all quadratic fields are automatically Galois. EXAMPLES:: @@ -12017,7 +12117,7 @@ def is_galois(self): def class_number(self, proof=None): r""" - Return the size of the class group of self. + Return the size of the class group of ``self``. INPUT: @@ -12042,7 +12142,8 @@ def class_number(self, proof=None): These are all the primes so that the class number of `\QQ(\sqrt{-p})` is `1`:: - sage: [d for d in prime_range(2,300) if not is_square(d) and QuadraticField(-d,'a').class_number() == 1] + sage: [d for d in prime_range(2,300) + ....: if not is_square(d) and QuadraticField(-d,'a').class_number() == 1] [2, 3, 7, 11, 19, 43, 67, 163] It is an open problem to *prove* that there are infinity many @@ -12051,7 +12152,8 @@ def class_number(self, proof=None): :: - sage: len([d for d in range(2,200) if not is_square(d) and QuadraticField(d,'a').class_number() == 1]) + sage: len([d for d in range(2,200) + ....: if not is_square(d) and QuadraticField(d,'a').class_number() == 1]) 121 TESTS:: @@ -12102,7 +12204,9 @@ def hilbert_class_field_defining_polynomial(self, name='x'): sage: K.class_number() 21 sage: K.hilbert_class_field_defining_polynomial(name='z') - z^21 + 6*z^20 + 9*z^19 - 4*z^18 + 33*z^17 + 140*z^16 + 220*z^15 + 243*z^14 + 297*z^13 + 461*z^12 + 658*z^11 + 743*z^10 + 722*z^9 + 681*z^8 + 619*z^7 + 522*z^6 + 405*z^5 + 261*z^4 + 119*z^3 + 35*z^2 + 7*z + 1 + z^21 + 6*z^20 + 9*z^19 - 4*z^18 + 33*z^17 + 140*z^16 + 220*z^15 + 243*z^14 + + 297*z^13 + 461*z^12 + 658*z^11 + 743*z^10 + 722*z^9 + 681*z^8 + 619*z^7 + + 522*z^6 + 405*z^5 + 261*z^4 + 119*z^3 + 35*z^2 + 7*z + 1 """ f = pari(self.discriminant()).quadhilbert() return QQ[name](f) @@ -12125,7 +12229,8 @@ def hilbert_class_field(self, names): sage: L = K.hilbert_class_field('b'); L Number Field in b with defining polynomial x^3 - x^2 + 1 over its base field sage: L.absolute_field('c') - Number Field in c with defining polynomial x^6 - 2*x^5 + 70*x^4 - 90*x^3 + 1631*x^2 - 1196*x + 12743 + Number Field in c with defining polynomial + x^6 - 2*x^5 + 70*x^4 - 90*x^3 + 1631*x^2 - 1196*x + 12743 sage: K.hilbert_class_field_defining_polynomial() x^3 - x^2 + 1 """ @@ -12161,7 +12266,7 @@ def number_of_roots_of_unity(self): """ Return the number of roots of unity in this quadratic field. - This is always 2 except when d is -3 or -4. + This is always 2 except when `d` is `-3` or `-4`. EXAMPLES:: @@ -12204,7 +12309,7 @@ def order_of_conductor(self, f): def is_fundamental_discriminant(D): r""" - Return True if the integer `D` is a fundamental + Return ``True`` if the integer `D` is a fundamental discriminant, i.e., if `D \cong 0,1\pmod{4}`, and `D\neq 0, 1` and either (1) `D` is square free or (2) we have `D\cong 0\pmod{4}` with @@ -12215,10 +12320,12 @@ def is_fundamental_discriminant(D): sage: [D for D in range(-15,15) if is_fundamental_discriminant(D)] ... - DeprecationWarning: is_fundamental_discriminant(D) is deprecated; please use D.is_fundamental_discriminant() + DeprecationWarning: is_fundamental_discriminant(D) is deprecated; + please use D.is_fundamental_discriminant() ... [-15, -11, -8, -7, -4, -3, 5, 8, 12, 13] - sage: [D for D in range(-15,15) if not is_square(D) and QuadraticField(D,'a').disc() == D] + sage: [D for D in range(-15,15) + ....: if not is_square(D) and QuadraticField(D,'a').disc() == D] [-15, -11, -8, -7, -4, -3, 5, 8, 12, 13] """ deprecation(35147, "is_fundamental_discriminant(D) is deprecated; please use D.is_fundamental_discriminant()") @@ -12292,19 +12399,19 @@ def put_natural_embedding_first(v): sage: K. = CyclotomicField(7) sage: embs = K.embeddings(K) - sage: [e(a) for e in embs] # random - there is no natural sort order + sage: [e(a) for e in embs] # random - there is no natural sort order [a, a^2, a^3, a^4, a^5, -a^5 - a^4 - a^3 - a^2 - a - 1] - sage: id = [ e for e in embs if e(a) == a ][0]; id + sage: id = [e for e in embs if e(a) == a][0]; id Ring endomorphism of Cyclotomic Field of order 7 and degree 6 Defn: a |--> a sage: permuted_embs = list(embs); permuted_embs.remove(id); permuted_embs.append(id) - sage: [e(a) for e in permuted_embs] # random - but natural map is not first + sage: [e(a) for e in permuted_embs] # random - but natural map is not first [a^2, a^3, a^4, a^5, -a^5 - a^4 - a^3 - a^2 - a - 1, a] sage: permuted_embs[0] != a True sage: from sage.rings.number_field.number_field import put_natural_embedding_first sage: put_natural_embedding_first(permuted_embs) - sage: [e(a) for e in permuted_embs] # random - but natural map is first + sage: [e(a) for e in permuted_embs] # random - but natural map is first [a, a^3, a^4, a^5, -a^5 - a^4 - a^3 - a^2 - a - 1, a^2] sage: permuted_embs[0] == id True @@ -12322,15 +12429,15 @@ def put_natural_embedding_first(v): def refine_embedding(e, prec=None): r""" Given an embedding from a number field to either `\RR` or - `\CC`, returns an equivalent embedding with higher precision. + `\CC`, return an equivalent embedding with higher precision. INPUT: - - ``e`` - an embedding of a number field into either - RR or CC (with some precision) + - ``e`` -- an embedding of a number field into either + `\RR` or `\CC` (with some precision) - - ``prec`` - (default None) the desired precision; if None, - current precision is doubled; if Infinity, the equivalent + - ``prec`` -- (default ``None``) the desired precision; if ``None``, + current precision is doubled; if ``Infinity``, the equivalent embedding into either ``QQbar`` or ``AA`` is returned. EXAMPLES:: @@ -12346,7 +12453,7 @@ def refine_embedding(e, prec=None): An example where we extend a real embedding into ``AA``:: - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: K.signature() (1, 1) sage: e = K.embeddings(RR)[0]; e @@ -12354,7 +12461,7 @@ def refine_embedding(e, prec=None): From: Number Field in a with defining polynomial x^3 - 2 To: Real Field with 53 bits of precision Defn: a |--> 1.25992104989487 - sage: e = refine_embedding(e,Infinity); e + sage: e = refine_embedding(e, Infinity); e Ring morphism: From: Number Field in a with defining polynomial x^3 - 2 To: Algebraic Real Field @@ -12366,7 +12473,7 @@ def refine_embedding(e, prec=None): 1.2599210498948731647672106072782283505702515 sage: _^3 2.0000000000000000000000000000000000000000000 - sage: RealField(200)(e(a^2-3*a+7)) + sage: RealField(200)(e(a^2 - 3*a + 7)) 4.8076379022835799804500738174376232086807389337953290695624 Complex embeddings can be extended into ``QQbar``:: @@ -12382,7 +12489,8 @@ def refine_embedding(e, prec=None): To: Algebraic Field Defn: a |--> -0.6299605249474365? - 1.091123635971722?*I sage: ComplexField(200)(e(a)) - -0.62996052494743658238360530363911417528512573235075399004099 - 1.0911236359717214035600726141898088813258733387403009407036*I + -0.62996052494743658238360530363911417528512573235075399004099 + - 1.0911236359717214035600726141898088813258733387403009407036*I sage: e(a)^3 2 @@ -12398,7 +12506,8 @@ def refine_embedding(e, prec=None): Ring morphism: From: Cyclotomic Field of order 7 and degree 6 To: Complex Field with 300 bits of precision - Defn: zeta7 |--> 0.623489801858733530525004884004239810632274730896402105365549439096853652456487284575942507 + 0.781831482468029808708444526674057750232334518708687528980634958045091731633936441700868007*I + Defn: zeta7 |--> 0.623489801858733530525004884004239810632274730896402105365549439096853652456487284575942507 + + 0.781831482468029808708444526674057750232334518708687528980634958045091731633936441700868007*I sage: refine_embedding(x, infinity) Ring morphism: From: Cyclotomic Field of order 7 and degree 6 @@ -12460,11 +12569,11 @@ def refine_embedding(e, prec=None): def is_real_place(v): r""" - Return ``True`` if ``v`` is real, ``False`` if ``v`` is complex + Return ``True`` if `v` is real, ``False`` if `v` is complex INPUT: - - ``v`` -- an infinite place of ``K`` + - ``v`` -- an infinite place of ``self`` OUTPUT: @@ -12472,7 +12581,7 @@ def is_real_place(v): EXAMPLES:: - sage: K. = NumberField(x^3-3) + sage: K. = NumberField(x^3 - 3) sage: phi_real = K.places()[0] sage: phi_complex = K.places()[1] sage: v_fin = tuple(K.primes_above(3))[0] @@ -12505,7 +12614,7 @@ def _splitting_classes_gens_(K, m, d): r""" Given a number field `K` of conductor `m` and degree `d`, this returns a set of multiplicative generators of the - subgroup of `(\mathbb{Z}/m\mathbb{Z})^{\times}` + subgroup of `(\ZZ/m\ZZ)^{\times}` containing exactly the classes that contain the primes splitting completely in `K`. diff --git a/src/sage/rings/number_field/number_field_base.pyx b/src/sage/rings/number_field/number_field_base.pyx index dd9a8b9d550..0a4e0beb664 100644 --- a/src/sage/rings/number_field/number_field_base.pyx +++ b/src/sage/rings/number_field/number_field_base.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.number_field """ Base class for all number fields @@ -11,7 +12,7 @@ TESTS:: def is_NumberField(x): """ - Return True if ``x`` is of number field type. + Return ``True`` if ``x`` is of number field type. This function is deprecated. @@ -144,7 +145,7 @@ cdef class NumberField(Field): def ring_of_integers(self, *args, **kwds): r""" - Synonym for ``self.maximal_order(...)``. + Synonym for :meth:`maximal_order`. EXAMPLES:: @@ -156,7 +157,7 @@ cdef class NumberField(Field): def OK(self, *args, **kwds): r""" - Synonym for ``self.maximal_order(...)``. + Synonym for :meth:`maximal_order`. EXAMPLES:: @@ -166,7 +167,7 @@ cdef class NumberField(Field): return self.maximal_order(*args, **kwds) def maximal_order(self): - """ + r""" Return the maximal order, i.e., the ring of integers of this number field. @@ -178,8 +179,8 @@ cdef class NumberField(Field): raise NotImplementedError def is_absolute(self): - """ - Return True if self is viewed as a single extension over Q. + r""" + Return ``True`` if ``self`` is viewed as a single extension over `\QQ`. EXAMPLES:: @@ -196,8 +197,8 @@ cdef class NumberField(Field): raise NotImplementedError def signature(self): - """ - Return (r1, r2), where r1 and r2 are the number of real embeddings + r""" + Return `(r_1, r_2)`, where `r_1` and `r_2` are the number of real embeddings and pairs of complex embeddings of this field, respectively. EXAMPLES:: @@ -233,9 +234,9 @@ cdef class NumberField(Field): r""" Return the Minkowski bound associated to this number field. - This is a bound B so that every integral ideal is equivalent + This is a bound `B` so that every integral ideal is equivalent modulo principal fractional ideals to an integral ideal of - norm at most B. + norm at most `B`. .. SEEALSO:: @@ -308,9 +309,9 @@ cdef class NumberField(Field): r""" Return the Bach bound associated to this number field. - Assuming the General Riemann Hypothesis, this is a bound B so + Assuming the General Riemann Hypothesis, this is a bound `B` so that every integral ideal is equivalent modulo principal - fractional ideals to an integral ideal of norm at most B. + fractional ideals to an integral ideal of norm at most `B`. .. SEEALSO:: @@ -344,7 +345,8 @@ cdef class NumberField(Field): sage: K.bach_bound().n() 191669.304126267 - The bound of course also works for the rational numbers: + The bound of course also works for the rational numbers:: + sage: QQ.minkowski_bound() 1 """ @@ -419,7 +421,7 @@ cdef class NumberField(Field): If a real embedding is not specified, this method will result in an error:: - sage: N. = NumberField(x^3+2) + sage: N. = NumberField(x^3 + 2) sage: N._get_embedding_approx(1) Traceback (most recent call last): ... @@ -447,7 +449,7 @@ cdef class NumberField(Field): def _matrix_charpoly(self, M, var): r""" - Use PARI to compute the characteristic polynomial of self as a + Use PARI to compute the characteristic polynomial of ``self`` as a polynomial over the base ring. EXAMPLES:: diff --git a/src/sage/rings/number_field/number_field_element.pyx b/src/sage/rings/number_field/number_field_element.pyx index d80c87ea00c..e249bab8fa1 100644 --- a/src/sage/rings/number_field/number_field_element.pyx +++ b/src/sage/rings/number_field/number_field_element.pyx @@ -101,7 +101,7 @@ TUNE_CHARPOLY_NF = 25 def is_NumberFieldElement(x): """ - Return True if x is of type NumberFieldElement, i.e., an element of + Return ``True`` if `x` is of type :class:`NumberFieldElement`, i.e., an element of a number field. EXAMPLES:: @@ -162,10 +162,10 @@ def __create__NumberFieldElement_version1(parent, cls, poly): def _inverse_mod_generic(elt, I): r""" - Return an inverse of elt modulo the given ideal. This is a separate - function called from each of the OrderElement_xxx classes, since + Return an inverse of ``elt`` modulo the given ideal. This is a separate + function called from each of the ``OrderElement_xxx`` classes, since otherwise we'd have to have the same code three times over (there - is no OrderElement_generic class - no multiple inheritance). See + is no ``OrderElement_generic`` class - no multiple inheritance). See :trac:`4190`. EXAMPLES:: @@ -246,9 +246,9 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - ``parent`` - a number field + - ``parent`` -- a number field - - ``f`` - defines an element of a number field. + - ``f`` -- defines an element of a number field. EXAMPLES: @@ -532,10 +532,9 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: f = gap(F) sage: f.GeneratorsOfDivisionRing() [ E(8) ] - sage: p = F.gen()^2+2*F.gen()-3 - sage: p + sage: p = F.gen()^2 + 2*F.gen() - 3; p zeta8^2 + 2*zeta8 - 3 - sage: p._gap_init_() # The variable name $sage2 belongs to the gap(F) and is somehow random + sage: p._gap_init_() # The variable name $sage2 belongs to the gap(F) and is somehow random 'GeneratorsOfField($sage2)[1]^2 + 2*GeneratorsOfField($sage2)[1] - 3' sage: gap(p._gap_init_()) -3+2*E(8)+E(8)^2 @@ -574,19 +573,19 @@ cdef class NumberFieldElement(NumberFieldElement_base): EXAMPLES:: sage: F = CyclotomicField(8) - sage: F.gen()._libgap_() + sage: F.gen()._libgap_() # optional - sage.libs.gap E(8) - sage: libgap(F.gen()) # syntactic sugar + sage: libgap(F.gen()) # syntactic sugar # optional - sage.libs.gap E(8) - sage: E8 = F.gen() - sage: libgap(E8 + 3/2*E8^2 + 100*E8^7) + sage: E8 = F.gen() # optional - sage.libs.gap + sage: libgap(E8 + 3/2*E8^2 + 100*E8^7) # optional - sage.libs.gap E(8)+3/2*E(8)^2-100*E(8)^3 - sage: type(_) + sage: type(_) # optional - sage.libs.gap Check that :trac:`15276` is fixed:: - sage: for n in range(2,20): + sage: for n in range(2,20): # optional - sage.libs.gap ....: K = CyclotomicField(n) ....: assert K(libgap(K.gen())) == K.gen(), "n = {}".format(n) ....: assert K(libgap(K.one())) == K.one(), "n = {}".format(n) @@ -613,13 +612,13 @@ cdef class NumberFieldElement(NumberFieldElement_base): TESTS: sage: K. = NumberField(x^3 + 2) - sage: K.zero()._pari_polynomial('x') + sage: K.zero()._pari_polynomial('x') # optional - sage.libs.pari 0 - sage: K.one()._pari_polynomial() + sage: K.one()._pari_polynomial() # optional - sage.libs.pari 1 - sage: (a + 1)._pari_polynomial() + sage: (a + 1)._pari_polynomial() # optional - sage.libs.pari y + 1 - sage: a._pari_polynomial('c') + sage: a._pari_polynomial('c') # optional - sage.libs.pari c """ f = pari(self._coefficients()).Polrev() @@ -643,20 +642,20 @@ cdef class NumberFieldElement(NumberFieldElement_base): EXAMPLES:: sage: K. = NumberField(x^3 + 2) - sage: K(1).__pari__() + sage: K(1).__pari__() # optional - sage.libs.pari Mod(1, y^3 + 2) - sage: (a + 2).__pari__() + sage: (a + 2).__pari__() # optional - sage.libs.pari Mod(y + 2, y^3 + 2) sage: L. = K.extension(x^2 + 2) - sage: (b + a).__pari__() + sage: (b + a).__pari__() # optional - sage.libs.pari Mod(24/101*y^5 - 9/101*y^4 + 160/101*y^3 - 156/101*y^2 + 397/101*y + 364/101, y^6 + 6*y^4 - 4*y^3 + 12*y^2 + 24*y + 12) :: sage: k. = QuadraticField(-1) - sage: j.__pari__('j') + sage: j.__pari__('j') # optional - sage.libs.pari Mod(j, j^2 + 1) - sage: pari(j) + sage: pari(j) # optional - sage.libs.pari Mod(y, y^2 + 1) By default the variable name is 'y'. This allows 'x' to be used @@ -665,7 +664,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: P. = PolynomialRing(QQ) sage: K. = NumberField(a^2 + 1) sage: R. = PolynomialRing(K) - sage: pari(b*x) + sage: pari(b*x) # optional - sage.libs.pari Mod(y, y^2 + 1)*x In PARI many variable names are reserved, for example ``theta`` @@ -673,25 +672,25 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: R. = PolynomialRing(QQ) sage: K. = NumberField(theta^2 + 1) - sage: theta.__pari__('theta') + sage: theta.__pari__('theta') # optional - sage.libs.pari Traceback (most recent call last): ... PariError: theta already exists with incompatible valence - sage: theta.__pari__() + sage: theta.__pari__() # optional - sage.libs.pari Mod(y, y^2 + 1) sage: k. = QuadraticField(-1) - sage: I.__pari__('I') + sage: I.__pari__('I') # optional - sage.libs.pari Traceback (most recent call last): ... PariError: I already exists with incompatible valence Instead, request the variable be named different for the coercion:: - sage: pari(I) + sage: pari(I) # optional - sage.libs.pari Mod(y, y^2 + 1) - sage: I.__pari__('i') + sage: I.__pari__('i') # optional - sage.libs.pari Mod(i, i^2 + 1) - sage: I.__pari__('II') + sage: I.__pari__('II') # optional - sage.libs.pari Mod(II, II^2 + 1) Examples with relative number fields, which always yield an @@ -699,13 +698,13 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: y = QQ['y'].gen() sage: k. = NumberField([y^2 - 7, y^3 - 2]) - sage: pari(j) + sage: pari(j) # optional - sage.libs.pari Mod(42/5515*y^5 - 9/11030*y^4 - 196/1103*y^3 + 273/5515*y^2 + 10281/5515*y + 4459/11030, y^6 - 21*y^4 + 4*y^3 + 147*y^2 + 84*y - 339) sage: j^2 7 - sage: pari(j)^2 + sage: pari(j)^2 # optional - sage.libs.pari Mod(7, y^6 - 21*y^4 + 4*y^3 + 147*y^2 + 84*y - 339) - sage: (j^2).__pari__('x') + sage: (j^2).__pari__('x') # optional - sage.libs.pari Mod(7, x^6 - 21*x^4 + 4*x^3 + 147*x^2 + 84*x - 339) A tower of three number fields:: @@ -714,11 +713,11 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: K. = NumberField(x^2 + 2) sage: L. = NumberField(polygen(K)^2 + a) sage: M. = NumberField(polygen(L)^3 + b) - sage: L(b).__pari__() + sage: L(b).__pari__() # optional - sage.libs.pari Mod(y, y^4 + 2) - sage: M(b).__pari__('c') + sage: M(b).__pari__('c') # optional - sage.libs.pari Mod(-c^3, c^12 + 2) - sage: c.__pari__('c') + sage: c.__pari__('c') # optional - sage.libs.pari Mod(c, c^12 + 2) """ f = self._pari_polynomial(name) @@ -740,9 +739,9 @@ cdef class NumberFieldElement(NumberFieldElement_base): EXAMPLES:: sage: K. = NumberField(x^5 - x - 1) - sage: ((1 + 1/3*a)^4)._pari_init_() + sage: ((1 + 1/3*a)^4)._pari_init_() # optional - sage.libs.pari 'Mod(1/81*y^4 + 4/27*y^3 + 2/3*y^2 + 4/3*y + 1, y^5 - y - 1)' - sage: ((1 + 1/3*a)^4)._pari_init_('a') + sage: ((1 + 1/3*a)^4)._pari_init_('a') # optional - sage.libs.pari 'Mod(1/81*a^4 + 4/27*a^3 + 2/3*a^2 + 4/3*a + 1, a^5 - a - 1)' Note that _pari_init_ can fail because of reserved words in @@ -752,7 +751,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: K. = NumberField(x^5 - x - 1) sage: b = (1/2 - 2/3*theta)^3; b -8/27*theta^3 + 2/3*theta^2 - 1/2*theta + 1/8 - sage: b._pari_init_('theta') + sage: b._pari_init_('theta') # optional - sage.libs.pari Traceback (most recent call last): ... PariError: theta already exists with incompatible valence @@ -760,7 +759,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): Fortunately pari_init returns everything in terms of y by default:: - sage: pari(b) + sage: pari(b) # optional - sage.libs.pari Mod(-8/27*y^3 + 2/3*y^2 - 1/2*y + 1/8, y^5 - y - 1) """ return repr(self.__pari__(name=name)) @@ -796,7 +795,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): ... IndexError: index must be between 0 and degree minus 1 - The list method implicitly calls ``__getitem__``:: + The :func:`list` function implicitly calls :meth:`__getitem__`:: sage: list(c) [8/27, -16/15, 32/25, -64/125] @@ -904,15 +903,15 @@ cdef class NumberFieldElement(NumberFieldElement_base): def _random_element(self, num_bound=None, den_bound=None, distribution=None): """ - Return a new random element with the same parent as self. + Return a new random element with the same parent as ``self``. INPUT: - - ``num_bound`` - Bound for the numerator of coefficients of result + - ``num_bound`` -- Bound for the numerator of coefficients of result - - ``den_bound`` - Bound for the denominator of coefficients of result + - ``den_bound`` -- Bound for the denominator of coefficients of result - - ``distribution`` - Distribution to use for coefficients of result + - ``distribution`` -- Distribution to use for coefficients of result EXAMPLES:: @@ -1268,9 +1267,9 @@ cdef class NumberFieldElement(NumberFieldElement_base): 4 sage: (-b).round() -4 - sage: (b+1/2).round() + sage: (b + 1/2).round() 5 - sage: (-b-1/2).round() + sage: (-b - 1/2).round() -5 This function always succeeds even if a tremendous precision is needed:: @@ -1321,9 +1320,9 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - ``prec`` - (default: None) integer bits of precision + - ``prec`` -- (default: None) integer bits of precision - - ``i`` - (default: None) integer, which embedding to + - ``i`` -- (default: None) integer, which embedding to use @@ -1334,19 +1333,19 @@ cdef class NumberFieldElement(NumberFieldElement_base): 1.00000000000000 sage: abs(z^2 + 17*z - 3) 16.0604426799931 - sage: K. = NumberField(x^3+17) + sage: K. = NumberField(x^3 + 17) sage: abs(a) 2.57128159065824 sage: a.abs(prec=100) 2.5712815906582353554531872087 - sage: a.abs(prec=100,i=1) + sage: a.abs(prec=100, i=1) 2.5712815906582353554531872087 sage: a.abs(100, 2) 2.5712815906582353554531872087 Here's one where the absolute value depends on the embedding:: - sage: K. = NumberField(x^2-2) + sage: K. = NumberField(x^2 - 2) sage: a = 1 + b sage: a.abs(i=0) 0.414213562373095 @@ -1406,10 +1405,10 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - ``P`` - a prime ideal of the parent of self + - ``P`` -- a prime ideal of the parent of ``self`` - ``prec`` (int) -- desired floating point precision (default: - default RealField precision). + default :class:`RealField` precision). OUTPUT: @@ -1421,7 +1420,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): EXAMPLES:: - sage: K. = NumberField(x^2+5) + sage: K. = NumberField(x^2 + 5) sage: [1/K(2).abs_non_arch(P) for P in K.primes_above(2)] [2.00000000000000] sage: [1/K(3).abs_non_arch(P) for P in K.primes_above(3)] @@ -1431,7 +1430,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): A relative example:: - sage: L. = K.extension(x^2-5) + sage: L. = K.extension(x^2 - 5) sage: [b.abs_non_arch(P) for P in L.primes_above(b)] [0.447213595499958, 0.447213595499958] """ @@ -1449,9 +1448,9 @@ cdef class NumberFieldElement(NumberFieldElement_base): def coordinates_in_terms_of_powers(self): r""" - Let `\alpha` be self. Return a callable object (of type + Let `\alpha` be ``self``. Return a callable object (of type :class:`~CoordinateFunction`) that takes any element of the - parent of self in `\QQ(\alpha)` and writes it in terms of the + parent of ``self`` in `\QQ(\alpha)` and writes it in terms of the powers of `\alpha`: `1, \alpha, \alpha^2, ...`. (NOT CACHED). @@ -1478,7 +1477,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: c((1+beta)^10) [54, 162, 189] - This function works even if self only generates a subfield of this + This function works even if ``self`` only generates a subfield of this number field. :: @@ -1514,25 +1513,29 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - ``prec`` - integer (default: 53) bits of precision + - ``prec`` -- integer (default: 53) bits of precision EXAMPLES:: sage: k. = NumberField(x^3 - 2) sage: a.complex_embeddings() - [-0.629960524947437 - 1.09112363597172*I, -0.629960524947437 + 1.09112363597172*I, 1.25992104989487] + [-0.629960524947437 - 1.09112363597172*I, + -0.629960524947437 + 1.09112363597172*I, + 1.25992104989487] sage: a.complex_embeddings(10) [-0.63 - 1.1*I, -0.63 + 1.1*I, 1.3] sage: a.complex_embeddings(100) - [-0.62996052494743658238360530364 - 1.0911236359717214035600726142*I, -0.62996052494743658238360530364 + 1.0911236359717214035600726142*I, 1.2599210498948731647672106073] + [-0.62996052494743658238360530364 - 1.0911236359717214035600726142*I, + -0.62996052494743658238360530364 + 1.0911236359717214035600726142*I, + 1.2599210498948731647672106073] """ phi = self.number_field().complex_embeddings(prec) return [f(self) for f in phi] def complex_embedding(self, prec=53, i=0): """ - Return the i-th embedding of self in the complex numbers, to the + Return the `i`-th embedding of ``self`` in the complex numbers, to the given precision. EXAMPLES:: @@ -1583,35 +1586,36 @@ cdef class NumberFieldElement(NumberFieldElement_base): def is_norm(self, L, element=False, proof=True): r""" - Determine whether self is the relative norm of an element - of L/K, where K is self.parent(). + Determine whether ``self`` is the relative norm of an element + of `L/K`, where `K` is ``self.parent()``. INPUT: - - L -- a number field containing K=self.parent() - - element -- True or False, whether to also output an element - of which self is a norm - - proof -- If True, then the output is correct unconditionally. - If False, then the output is correct under GRH. + - ``L`` -- a number field containing `K` = ``self.parent()``. + - ``element`` -- ``True`` or ``False``, whether to also output an element + of which ``self`` is a norm. + - ``proof`` -- If ``True``, then the output is correct unconditionally. + If ``False``, then the output is correct under GRH. OUTPUT: - If element is False, then the output is a boolean B, which is - True if and only if self is the relative norm of an element of L - to K. - If element is False, then the output is a pair (B, x), where - B is as above. If B is True, then x is an element of L such that - self == x.norm(K). Otherwise, x is None. + If ``element`` is ``False``, then the output is a boolean `B`, which is + ``True`` if and only if ``self`` is the relative norm of an element of `L` + to `K`. + + If ``element`` is ``True``, then the output is a pair `(B, x)`, where + `B` is as above. If `B` is ``True``, then `x` is an element of `L` such that + ``self == x.norm(K)``. Otherwise, `x` is ``None``. ALGORITHM: - Uses PARI's :pari:`rnfisnorm`. See self._rnfisnorm(). + Uses PARI's :pari:`rnfisnorm`. See :meth:`_rnfisnorm`. EXAMPLES:: - sage: K. = NumberField(x^3+5) + sage: K. = NumberField(x^3 + 5) sage: Q. = K[] - sage: L = K.extension(X^2+X+beta, 'gamma') + sage: L = K.extension(X^2 + X + beta, 'gamma') sage: (beta/2).is_norm(L) False sage: beta.is_norm(L) @@ -1637,14 +1641,15 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: (a/2).is_norm(L) Traceback (most recent call last): ... - NotImplementedError: is_norm is not implemented unconditionally for norms from non-Galois number fields + NotImplementedError: is_norm is not implemented unconditionally + for norms from non-Galois number fields sage: (a/2).is_norm(L, proof=False) False sage: K. = NumberField(x^3 + x + 1) sage: Q. = K[] sage: L. = NumberField(X^4 + a) - sage: t, u = (-a).is_norm(L, element=True); u # random (not unique) + sage: t, u = (-a).is_norm(L, element=True); u # random (not unique) b^3 + 1 sage: t and u.norm(K) == -a True @@ -1654,7 +1659,8 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: L. = CyclotomicField(24); L Cyclotomic Field of order 24 and degree 8 sage: K = L.subfield(z24^3, 'z8')[0]; K - Number Field in z8 with defining polynomial x^4 + 1 with z8 = 0.7071067811865475? + 0.7071067811865475?*I + Number Field in z8 with defining polynomial x^4 + 1 + with z8 = 0.7071067811865475? + 0.7071067811865475?*I sage: flag, c = K(-7).is_norm(K, element=True); flag True sage: c.norm(K) @@ -1711,41 +1717,41 @@ cdef class NumberFieldElement(NumberFieldElement_base): def _rnfisnorm(self, L, proof=True, extra_primes=0): r""" - Gives the output of the PARI function rnfisnorm. + Give the output of the PARI function :pari:`rnfisnorm`. - This tries to decide whether the number field element self is - the norm of some x in the extension L/K (with K = self.parent()). + This tries to decide whether the number field element ``self`` is + the norm of some `x` in the extension `L/K` (with `K` = ``self.parent()``). - The output is a pair (x, q), where self = Norm(x)*q. The - algorithm looks for a solution x that is an S-integer, with S - a list of places of L containing at least the ramified primes, - the generators of the class group of L, as well as those primes + The output is a pair `(x, q)`, where ``self`` = ``Norm(x)*q``. The + algorithm looks for a solution `x` that is an `S`-integer, with `S` + a list of places of `L` containing at least the ramified primes, + the generators of the class group of `L`, as well as those primes dividing self. - If L/K is Galois, then this is enough; otherwise, - extra_primes is used to add more primes to S: all the places - above the primes p <= extra_primes (resp. p|extra_primes) if - extra_primes > 0 (resp. extra_primes < 0). + If `L/K` is Galois, then this is enough; otherwise, + ``extra_primes`` is used to add more primes to `S`: all the places + above the primes `p \leq ` ``extra_primes`` (resp., `p \mid` ``extra_primes``) if + ``extra_primes`` > 0 (resp., ``extra_primes`` < 0). - The answer is guaranteed (i.e., self is a norm iff q = 1) if the - field is Galois, or, under GRH, if S contains all primes less - than 12log^2|\disc(M)|, where M is the normal closure of L/K. + The answer is guaranteed (i.e., ``self`` is a norm iff `q = 1`) if the + field is Galois, or, under GRH, if `S` contains all primes less + than `12 \log^2|\disc(M)|`, where `M` is the normal closure of `L/K`. INPUT: - - L -- a relative number field with base field self.parent() - - proof -- whether to certify outputs of PARI init functions. - If false, truth of the output depends on GRH. - - extra_primes -- an integer as explained above. + - `L` -- a relative number field with base field ``self.parent()`` + - ``proof`` -- whether to certify outputs of PARI init functions. + If ``False``, truth of the output depends on GRH. + - ``extra_primes`` -- an integer as explained above. OUTPUT: - A pair (x, q) with x in L and q in K as explained above - such that self == x.norm(K)*q. + A pair `(x, q)` with `x` in `L` and `q` in `K` as explained above + such that ``self == x.norm(K)*q``. ALGORITHM: - Uses PARI's rnfisnorm. + Uses PARI's :pari:`rnfisnorm`. EXAMPLES:: @@ -1839,14 +1845,14 @@ cdef class NumberFieldElement(NumberFieldElement_base): Verify that :trac:`13005` has been fixed:: - sage: K. = NumberField(x^2-5) + sage: K. = NumberField(x^2 - 5) sage: RR(K(1)) 1.00000000000000 sage: RR(a) Traceback (most recent call last): ... TypeError: Unable to coerce a to a rational - sage: K. = NumberField(x^3+2, embedding=-1.25) + sage: K. = NumberField(x^3 + 2, embedding=-1.25) sage: RR(a) -1.25992104989487 sage: RealField(prec=100)(a) @@ -1956,17 +1962,17 @@ cdef class NumberFieldElement(NumberFieldElement_base): OUTPUT: - (Factorization) If all the prime ideals in the support are - principal, the output is a Factorization as a product of prime + (:class:`Factorization`) If all the prime ideals in the support are + principal, the output is a :class:`Factorization` as a product of prime elements raised to appropriate powers, with an appropriate unit factor. - Raise ValueError if the factorization of the - ideal (self) contains a non-principal prime ideal. + Raise :class:`ValueError` if the factorization of the + ideal (``self``) contains a non-principal prime ideal. EXAMPLES:: - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: (6*i + 6).factor() (-i) * (i + 1)^3 * 3 @@ -2021,8 +2027,8 @@ cdef class NumberFieldElement(NumberFieldElement_base): EXAMPLES:: - sage: K. = NumberField(x^2+1) - sage: (1+i).is_prime() + sage: K. = NumberField(x^2 + 1) + sage: (1 + i).is_prime() True sage: ((1+i)/2).is_prime() False @@ -2046,7 +2052,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): - A generator of the ideal ``(self, other)``. If the parent is a number field, this always returns 0 or 1. For maximal orders, - this raises ``ArithmeticError`` if the ideal is not principal. + this raises :class:`ArithmeticError` if the ideal is not principal. EXAMPLES:: @@ -2067,7 +2073,8 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: R(1).gcd(R(4*i)) Traceback (most recent call last): ... - NotImplementedError: gcd() for Order in Number Field in i with defining polynomial x^2 + 1 with i = 1*I is not implemented + NotImplementedError: gcd() for Order in Number Field in i + with defining polynomial x^2 + 1 with i = 1*I is not implemented The following field has class number 3, but if the ideal ``(self, other)`` happens to be principal, this still works:: @@ -2111,13 +2118,13 @@ cdef class NumberFieldElement(NumberFieldElement_base): def is_totally_positive(self): """ - Returns True if self is positive for all real embeddings of its + Return ``True`` if ``self`` is positive for all real embeddings of its parent number field. We do nothing at complex places, so e.g. any - element of a totally complex number field will return True. + element of a totally complex number field will return ``True``. EXAMPLES:: - sage: F. = NumberField(x^3-3*x-1) + sage: F. = NumberField(x^3 - 3*x - 1) sage: b.is_totally_positive() False sage: (b^2).is_totally_positive() @@ -2132,19 +2139,19 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: a = 30122754096401; b = 21300003689580 sage: (a/b)^2 > 2 True - sage: (a/b+sqrt2).is_totally_positive() + sage: (a/b + sqrt2).is_totally_positive() True sage: r = RealField(3020)(2).sqrt()*2^3000 sage: a = floor(r)/2^3000 sage: b = ceil(r)/2^3000 - sage: (a+sqrt2).is_totally_positive() + sage: (a + sqrt2).is_totally_positive() False - sage: (b+sqrt2).is_totally_positive() + sage: (b + sqrt2).is_totally_positive() True Check that 0 is handled correctly:: - sage: K. = NumberField(x^5+4*x+1) + sage: K. = NumberField(x^5 + 4*x + 1) sage: K(0).is_totally_positive() False """ @@ -2155,14 +2162,14 @@ cdef class NumberFieldElement(NumberFieldElement_base): def is_square(self, root=False): """ - Return True if self is a square in its parent number field and - otherwise return False. + Return ``True`` if ``self`` is a square in its parent number field and + otherwise return ``False``. INPUT: - - ``root`` - if True, also return a square root (or - None if self is not a perfect square) + - ``root`` -- if ``True``, also return a square root (or + ``None`` if ``self`` is not a perfect square) EXAMPLES:: @@ -2185,7 +2192,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): (True, 2/3*b + 5) sage: is_square(c) True - sage: is_square(c+1) + sage: is_square(c + 1) False TESTS: @@ -2273,7 +2280,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): Using the ``extend`` keyword:: sage: K = QuadraticField(-5) - sage: z = K(-7).sqrt(extend=True); z + sage: z = K(-7).sqrt(extend=True); z # optional - sage.symbolic sqrt(-7) sage: CyclotomicField(4)(4).sqrt(extend=False) 2 @@ -2284,9 +2291,10 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: K(-7).sqrt(extend=False) Traceback (most recent call last): ... - ValueError: -7 not a square in Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I + ValueError: -7 not a square in Number Field in a + with defining polynomial x^2 + 5 with a = 2.236067977499790?*I - ALGORITHM: Use PARI to factor `x^2` - ``self`` in `K`. + ALGORITHM: Use PARI to factor `x^2` `-` ``self`` in `K`. """ # For now, use pari's factoring abilities K = self.number_field() @@ -2338,11 +2346,11 @@ cdef class NumberFieldElement(NumberFieldElement_base): def is_nth_power(self, n): r""" - Return True if ``self`` is an `n`'th power in its parent `K`. + Return ``True`` if ``self`` is an `n`'th power in its parent `K`. EXAMPLES:: - sage: K. = NumberField(x^4-7) + sage: K. = NumberField(x^4 - 7) sage: K(7).is_nth_power(2) True sage: K(7).is_nth_power(4) @@ -2373,12 +2381,12 @@ cdef class NumberFieldElement(NumberFieldElement_base): If the exponent is not integral, perform this operation in the symbolic ring:: - sage: sqrt2^(1/5) + sage: sqrt2^(1/5) # optional - sage.symbolic 2^(1/10) - sage: sqrt2^sqrt2 + sage: sqrt2^sqrt2 # optional - sage.symbolic 2^(1/2*sqrt(2)) - Sage follows Python's convention 0^0 = 1:: + Sage follows Python's convention `0^0 = 1`:: sage: a = K(0)^0; a 1 @@ -2393,10 +2401,10 @@ cdef class NumberFieldElement(NumberFieldElement_base): Test :trac:`14895`:: sage: K. = QuadraticField(2) - sage: 2^sqrt2 + sage: 2^sqrt2 # optional - sage.symbolic 2^sqrt(2) sage: K. = NumberField(x^2+1) - sage: 2^a + sage: 2^a # optional - sage.symbolic Traceback (most recent call last): ... TypeError: no canonical coercion from Number Field in a with defining polynomial x^2 + 1 to Symbolic Ring @@ -2638,7 +2646,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def __bool__(self): """ - Return True if this number field element is nonzero. + Return ``True`` if this number field element is nonzero. EXAMPLES:: @@ -2751,7 +2759,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def __invert__(self): """ - Returns the multiplicative inverse of self in the number field. + Return the multiplicative inverse of self in the number field. EXAMPLES:: @@ -2885,15 +2893,15 @@ cdef class NumberFieldElement(NumberFieldElement_base): EXAMPLES:: sage: K. = QuadraticField(2) - sage: SR(a) # indirect doctest + sage: SR(a) # indirect doctest # optional - sage.symbolic sqrt(2) - sage: SR(3*a-5) # indirect doctest + sage: SR(3*a-5) # indirect doctest # optional - sage.symbolic 3*sqrt(2) - 5 sage: K. = QuadraticField(2, embedding=-1.4) - sage: SR(a) # indirect doctest + sage: SR(a) # indirect doctest # optional - sage.symbolic -sqrt(2) sage: K. = NumberField(x^2 - 2) - sage: SR(a) # indirect doctest + sage: SR(a) # indirect doctest # optional - sage.symbolic Traceback (most recent call last): ... TypeError: an embedding into RR or CC must be specified @@ -2901,29 +2909,29 @@ cdef class NumberFieldElement(NumberFieldElement_base): Now a more complicated example:: sage: K. = NumberField(x^3 + x - 1, embedding=0.68) - sage: b = SR(a); b # indirect doctest + sage: b = SR(a); b # indirect doctest # optional - sage.symbolic (1/18*sqrt(31)*sqrt(3) + 1/2)^(1/3) - 1/3/(1/18*sqrt(31)*sqrt(3) + 1/2)^(1/3) - sage: (b^3 + b - 1).canonicalize_radical() + sage: (b^3 + b - 1).canonicalize_radical() # optional - sage.symbolic 0 Make sure we got the right one:: sage: CC(a) 0.682327803828019 - sage: CC(b) + sage: CC(b) # optional - sage.symbolic 0.682327803828019 Special case for cyclotomic fields:: sage: K. = CyclotomicField(19) - sage: SR(zeta) # indirect doctest + sage: SR(zeta) # indirect doctest # optional - sage.symbolic e^(2/19*I*pi) sage: CC(zeta) 0.945817241700635 + 0.324699469204683*I - sage: CC(SR(zeta)) + sage: CC(SR(zeta)) # optional - sage.symbolic 0.945817241700635 + 0.324699469204683*I - sage: SR(zeta^5 + 2) + sage: SR(zeta^5 + 2) # optional - sage.symbolic e^(10/19*I*pi) + 2 For degree greater than 5, sometimes Galois theory prevents a @@ -2932,22 +2940,22 @@ cdef class NumberFieldElement(NumberFieldElement_base): printed as a numerical approximation:: sage: K. = NumberField(x^5-x+1, embedding=-1) - sage: SR(a) + sage: SR(a) # optional - sage.symbolic -1.167303978261419? :: sage: K. = NumberField(x^6-x^3-1, embedding=1) - sage: SR(a) + sage: SR(a) # optional - sage.symbolic (1/2*sqrt(5) + 1/2)^(1/3) In this field, general elements cannot be written in terms of radicals, but particular elements might be:: sage: K. = NumberField(x^10 + 6*x^6 + 9*x^2 + 1, embedding=CC(0.332*I)) - sage: SR(a) + sage: SR(a) # optional - sage.symbolic 0.3319890295845093?*I - sage: SR(a^5+3*a) + sage: SR(a^5+3*a) # optional - sage.symbolic I Conversely, some elements are too complicated to be written in @@ -2959,10 +2967,11 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: K. = NumberField(QQ['x']([6, -65, 163, -185, 81, -15, 1]), embedding=4.9) sage: b = a + a^3 - sage: SR(b.minpoly()).solve(SR('x'), explicit_solutions=True) + sage: SR(b.minpoly()).solve(SR('x'), explicit_solutions=True) # optional - sage.symbolic [] - sage: SR(b) - 1/8*(sqrt(4*(1/9*sqrt(109)*sqrt(3) + 2)^(1/3) - 4/3/(1/9*sqrt(109)*sqrt(3) + 2)^(1/3) + 17) + 5)^3 + 1/2*sqrt(4*(1/9*sqrt(109)*sqrt(3) + 2)^(1/3) - 4/3/(1/9*sqrt(109)*sqrt(3) + 2)^(1/3) + 17) + 5/2 + sage: SR(b) # optional - sage.symbolic + 1/8*(sqrt(4*(1/9*sqrt(109)*sqrt(3) + 2)^(1/3) - 4/3/(1/9*sqrt(109)*sqrt(3) + 2)^(1/3) + 17) + 5)^3 + + 1/2*sqrt(4*(1/9*sqrt(109)*sqrt(3) + 2)^(1/3) - 4/3/(1/9*sqrt(109)*sqrt(3) + 2)^(1/3) + 17) + 5/2 TESTS: @@ -2972,7 +2981,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: p = x^8 + x^7 - 9*x^6 - 3*x^5 - 6*x^4 + x^3 - 14*x^2 + 2*x + 2 sage: rt = sorted(p.roots(AA, multiplicities=False))[1] sage: K. = NumberField(p, embedding=rt) - sage: SR(a) + sage: SR(a) # optional - sage.symbolic -0.3056815681115094? """ @@ -3012,7 +3021,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def galois_conjugates(self, K): r""" Return all Gal(Qbar/Q)-conjugates of this number field element in - the field K. + the field `K`. EXAMPLES: @@ -3068,7 +3077,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): This is only well-defined for fields contained in CM fields (i.e. for totally real fields and CM fields). Recall that a CM field is a totally imaginary quadratic extension of a totally - real field. For other fields, a ValueError is raised. + real field. For other fields, a :class:`ValueError` is raised. EXAMPLES:: @@ -3090,7 +3099,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: j.conjugate() -j - Raise a ValueError if the field is not contained in a CM field. + Raise a :class:`ValueError` if the field is not contained in a CM field. :: @@ -3098,7 +3107,8 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: b.conjugate() Traceback (most recent call last): ... - ValueError: Complex conjugation is only well-defined for fields contained in CM fields. + ValueError: Complex conjugation is only well-defined + for fields contained in CM fields. An example of a non-quadratic totally real field. @@ -3300,7 +3310,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: a.multiplicative_order() 3 - You can be evil with this so be careful. That's why the function + You can be evil with this, so be careful. That's why the function name begins with an underscore. :: @@ -3326,7 +3336,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): +Infinity sage: x = polygen(QQ) - sage: K.=NumberField(x^40 - x^20 + 4) + sage: K. = NumberField(x^40 - x^20 + 4) sage: u = 1/4*a^30 + 1/4*a^10 + 1/2 sage: u.multiplicative_order() 6 @@ -3374,8 +3384,8 @@ cdef class NumberFieldElement(NumberFieldElement_base): def additive_order(self): r""" - Return the additive order of this element (i.e. infinity if - self != 0, 1 if self == 0) + Return the additive order of this element (i.e., infinity if + ``self != 0`` and 1 if ``self == 0``) EXAMPLES:: @@ -3384,7 +3394,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): +Infinity sage: K(0).additive_order() 1 - sage: K.ring_of_integers().characteristic() # implicit doctest + sage: K.ring_of_integers().characteristic() # implicit doctest 0 """ if not self: return ZZ.one() @@ -3413,7 +3423,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): cpdef bint is_rational(self): r""" - Test whether this number field element is a rational number + Test whether this number field element is a rational number. .. SEEALSO:: @@ -3438,7 +3448,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def is_integer(self): r""" - Test whether this number field element is an integer + Test whether this number field element is an integer. .. SEEALSO:: @@ -3462,21 +3472,21 @@ cdef class NumberFieldElement(NumberFieldElement_base): return ZZX_deg(self.__numerator) <= 0 and ZZ_IsOne(self.__denominator) == 1 def trace(self, K=None): - """ + r""" Return the absolute or relative trace of this number field element. - If K is given then K must be a subfield of the parent L of self, in - which case the trace is the relative trace from L to K. In all - other cases, the trace is the absolute trace down to QQ. + If `K` is given, then `K` must be a subfield of the parent `L` of ``self``, in + which case the trace is the relative trace from `L` to `K`. In all + other cases, the trace is the absolute trace down to `\QQ`. EXAMPLES:: - sage: K. = NumberField(x^3 -132/7*x^2 + x + 1); K + sage: K. = NumberField(x^3 - 132/7*x^2 + x + 1); K Number Field in a with defining polynomial x^3 - 132/7*x^2 + x + 1 sage: a.trace() 132/7 - sage: (a+1).trace() == a.trace() + 3 + sage: (a + 1).trace() == a.trace() + 3 True If we are in an order, the trace is an integer:: @@ -3488,7 +3498,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): TESTS:: - sage: F. = CyclotomicField(5) ; t = 3*z**3 + 4*z**2 + 2 + sage: F. = CyclotomicField(5); t = 3*z**3 + 4*z**2 + 2 sage: t.trace(F) 3*z^3 + 4*z^2 + 2 """ @@ -3498,12 +3508,12 @@ cdef class NumberFieldElement(NumberFieldElement_base): return self.matrix(K).trace() def norm(self, K=None): - """ + r""" Return the absolute or relative norm of this number field element. - If K is given then K must be a subfield of the parent L of self, in - which case the norm is the relative norm from L to K. In all other - cases, the norm is the absolute norm down to QQ. + If `K` is given, then `K` must be a subfield of the parent `L` of ``self``, in + which case the norm is the relative norm from `L` to `K`. In all other + cases, the norm is the absolute norm down to `\QQ`. EXAMPLES:: @@ -3530,21 +3540,21 @@ cdef class NumberFieldElement(NumberFieldElement_base): 1 sage: a a - sage: (a+b+c).norm() + sage: (a + b + c).norm() 121 - sage: (a+b+c).norm(L) + sage: (a + b + c).norm(L) 2*c*b - 7 - sage: (a+b+c).norm(M) + sage: (a + b + c).norm(M) -11 We illustrate that norm is compatible with towers:: - sage: z = (a+b+c).norm(L); z.norm(M) + sage: z = (a + b + c).norm(L); z.norm(M) -11 If we are in an order, the norm is an integer:: - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: a.norm().parent() Rational Field sage: R = K.ring_of_integers() @@ -3612,7 +3622,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def vector(self): """ - Return vector representation of self in terms of the basis for the + Return vector representation of ``self`` in terms of the basis for the ambient number field. EXAMPLES:: @@ -3656,11 +3666,11 @@ cdef class NumberFieldElement(NumberFieldElement_base): EXAMPLES:: - sage: K. = NumberField(x^2+3) + sage: K. = NumberField(x^2 + 3) sage: a.minpoly('x') x^2 + 3 sage: R. = K['X'] - sage: L. = K.extension(X^2-(22 + a)) + sage: L. = K.extension(X^2 - (22 + a)) sage: b.minpoly('t') t^2 - a - 22 sage: b.absolute_minpoly('t') @@ -3693,8 +3703,8 @@ cdef class NumberFieldElement(NumberFieldElement_base): An example in a relative extension:: - sage: K. = NumberField([x^2+1, x^2+3]) - sage: (a+b).is_integral() + sage: K. = NumberField([x^2 + 1, x^2 + 3]) + sage: (a + b).is_integral() True sage: ((a-b)/2).is_integral() False @@ -3703,24 +3713,24 @@ cdef class NumberFieldElement(NumberFieldElement_base): def matrix(self, base=None): r""" - If base is None, return the matrix of right multiplication by the + If ``base`` is ``None``, return the matrix of right multiplication by the element on the power basis `1, x, x^2, \ldots, x^{d-1}` for the number field. Thus the *rows* of this matrix give the images of each of the `x^i`. - If base is not None, then base must be either a field that embeds - in the parent of self or a morphism to the parent of self, in which - case this function returns the matrix of multiplication by self on + If ``base`` is not ``None``, then ``base`` must be either a field that embeds + in the parent of ``self`` or a morphism to the parent of ``self``, in which + case this function returns the matrix of multiplication by ``self`` on the power basis, where we view the parent field as a field over - base. + ``base``. - Specifying base as the base field over which the parent of self - is a relative extension is equivalent to base being None + Specifying ``base`` as the base field over which the parent of ``self`` + is a relative extension is equivalent to ``base`` being ``None``. INPUT: - - ``base`` - field or morphism + - ``base`` -- field or morphism EXAMPLES: @@ -3790,7 +3800,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): TESTS:: - sage: F. = CyclotomicField(5) ; t = 3*z**3 + 4*z**2 + 2 + sage: F. = CyclotomicField(5); t = 3*z**3 + 4*z**2 + 2 sage: t.matrix(F) [3*z^3 + 4*z^2 + 2] sage: x = QQ['x'].gen() @@ -3837,7 +3847,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def valuation(self, P): """ - Return the valuation of ``self`` at a given prime ideal ``P``. + Return the valuation of ``self`` at a given prime ideal `P`. INPUT: @@ -3845,12 +3855,12 @@ cdef class NumberFieldElement(NumberFieldElement_base): .. NOTE:: - The function ``ord()`` is an alias for ``valuation()``. + The method :meth:`ord` is an alias for :meth:`valuation`. EXAMPLES:: sage: R. = QQ[] - sage: K. = NumberField(x^4+3*x^2-17) + sage: K. = NumberField(x^4 + 3*x^2 - 17) sage: P = K.ideal(61).factor()[0][0] sage: b = a^2 + 30 sage: b.valuation(P) @@ -3908,29 +3918,29 @@ cdef class NumberFieldElement(NumberFieldElement_base): def local_height(self, P, prec=None, weighted=False): r""" - Returns the local height of self at a given prime ideal `P`. + Returns the local height of ``self`` at a given prime ideal `P`. INPUT: - - ``P`` - a prime ideal of the parent of self + - ``P`` -- a prime ideal of the parent of ``self`` - ``prec`` (int) -- desired floating point precision (default: - default RealField precision). + default :class:`RealField` precision). - - ``weighted`` (bool, default False) -- if True, apply local + - ``weighted`` (bool, default ``False``) -- if ``True``, apply local degree weighting. OUTPUT: (real) The local height of this number field element at the - place `P`. If ``weighted`` is True, this is multiplied by the + place `P`. If ``weighted`` is ``True``, this is multiplied by the local degree (as required for global heights). EXAMPLES:: sage: R. = QQ[] - sage: K. = NumberField(x^4+3*x^2-17) + sage: K. = NumberField(x^4 + 3*x^2 - 17) sage: P = K.ideal(61).factor()[0][0] sage: b = 1/(a^2 + 30) sage: b.local_height(P) @@ -3948,7 +3958,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: PK. = K[] sage: L. = NumberField(y^2 + a) - sage: L(1/4).local_height(L.ideal(2, c-a+1)) + sage: L(1/4).local_height(L.ideal(2, c - a + 1)) 1.38629436111989 """ if self.valuation(P) >= 0: ## includes the case self=0 @@ -3965,36 +3975,35 @@ cdef class NumberFieldElement(NumberFieldElement_base): def local_height_arch(self, i, prec=None, weighted=False): r""" - Returns the local height of self at the `i`'th infinite place. + Returns the local height of ``self`` at the `i`'th infinite place. INPUT: - - - ``i`` (int) - an integer in ``range(r+s)`` where `(r,s)` is the - signature of the parent field (so `n=r+2s` is the degree). + - ``i`` (int) -- an integer in ``range(r+s)`` where `(r,s)` is the + signature of the parent field (so `n=r+2s` is the degree). - ``prec`` (int) -- desired floating point precision (default: - default RealField precision). + default :class:`RealField` precision). - - ``weighted`` (bool, default False) -- if True, apply local + - ``weighted`` (bool, default ``False``) -- if ``True``, apply local degree weighting, i.e. double the value for complex places. OUTPUT: (real) The archimedean local height of this number field element at the `i`'th infinite place. If ``weighted`` is - True, this is multiplied by the local degree (as required for + ``True``, this is multiplied by the local degree (as required for global heights), i.e. 1 for real places and 2 for complex places. EXAMPLES:: sage: R. = QQ[] - sage: K. = NumberField(x^4+3*x^2-17) + sage: K. = NumberField(x^4 + 3*x^2 - 17) sage: [p.codomain() for p in K.places()] [Real Field with 106 bits of precision, - Real Field with 106 bits of precision, - Complex Field with 53 bits of precision] + Real Field with 106 bits of precision, + Complex Field with 53 bits of precision] sage: [a.local_height_arch(i) for i in range(3)] [0.5301924545717755083366563897519, 0.5301924545717755083366563897519, @@ -4047,7 +4056,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): EXAMPLES:: sage: R. = QQ[] - sage: K. = NumberField(x^4+3*x^2-17) + sage: K. = NumberField(x^4 + 3*x^2 - 17) sage: b = a/6 sage: b.global_height_non_arch() 7.16703787691222 @@ -4080,12 +4089,12 @@ cdef class NumberFieldElement(NumberFieldElement_base): def global_height_arch(self, prec=None): """ - Returns the total archimedean component of the height of self. + Returns the total archimedean component of the height of ``self``. INPUT: - ``prec`` (int) -- desired floating point precision (default: - default RealField precision). + default :class:`RealField` precision). OUTPUT: @@ -4096,7 +4105,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): EXAMPLES:: sage: R. = QQ[] - sage: K. = NumberField(x^4+3*x^2-17) + sage: K. = NumberField(x^4 + 3*x^2 - 17) sage: b = a/2 sage: b.global_height_arch() 0.38653407379277... @@ -4112,7 +4121,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - ``prec`` (int) -- desired floating point precision (default: - default RealField precision). + default :class:`RealField` precision). OUTPUT: @@ -4171,7 +4180,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): EXAMPLES:: - sage: K. = NumberField(x^2+5) + sage: K. = NumberField(x^2 + 5) sage: b = (1+a)/2 sage: b.norm() 3/2 @@ -4202,7 +4211,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): EXAMPLES:: - sage: K. = NumberField(x^2+5) + sage: K. = NumberField(x^2 + 5) sage: b = (1+a)/2 sage: b.norm() 3/2 @@ -4223,7 +4232,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): """ Return the support of this number field element. - OUTPUT: A sorted list of the primes ideals at which this number + OUTPUT: A sorted list of the prime ideals at which this number field element has nonzero valuation. An error is raised if the element is zero. @@ -4259,12 +4268,12 @@ cdef class NumberFieldElement(NumberFieldElement_base): def _matrix_over_base(self, L): """ - Return the matrix of self over the base field L. + Return the matrix of ``self`` over the base field `L`. EXAMPLES:: - sage: K. = NumberField(ZZ['x'].0^3-2, 'a') - sage: L. = K.extension(ZZ['x'].0^2+3, 'b') + sage: K. = NumberField(ZZ['x'].0^3 - 2, 'a') + sage: L. = K.extension(ZZ['x'].0^2 + 3, 'b') sage: L(a)._matrix_over_base(K) == L(a).matrix() True """ @@ -4277,12 +4286,12 @@ cdef class NumberFieldElement(NumberFieldElement_base): def _matrix_over_base_morphism(self, phi): """ - Return the matrix of self over a specified base, where phi gives a - map from the specified base to self.parent(). + Return the matrix of ``self`` over a specified base, where ``phi`` gives a + map from the specified base to ``self.parent()``. EXAMPLES:: - sage: F. = NumberField(ZZ['x'].0^5-2) + sage: F. = NumberField(ZZ['x'].0^5 - 2) sage: h = Hom(QQ,F)([1]) sage: alpha._matrix_over_base_morphism(h) == alpha.matrix() True @@ -4330,7 +4339,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): def list(self): """ - Return the list of coefficients of self written in terms of a power + Return the list of coefficients of ``self`` written in terms of a power basis. EXAMPLES:: @@ -4343,17 +4352,19 @@ cdef class NumberFieldElement(NumberFieldElement_base): raise NotImplementedError def inverse_mod(self, I): - """ - Returns the inverse of self mod the integral ideal I. + r""" + Returns the inverse of ``self`` mod the integral ideal `I`. INPUT: - - ``I`` - may be an ideal of self.parent(), or an element or list - of elements of self.parent() generating a nonzero ideal. A ValueError - is raised if I is non-integral or zero. A ZeroDivisionError is - raised if I + (x) != (1). + - ``I`` -- may be an ideal of ``self.parent()``, or an element or list + of elements of ``self.parent()`` generating a nonzero ideal. A :class:`ValueError` + is raised if `I` is non-integral or zero. A :class:`ZeroDivisionError` is + raised if `I + (x) \neq (1)`. + + .. NOTE:: - NOTE: It's not implemented yet for non-integral elements. + It's not implemented yet for non-integral elements. EXAMPLES:: @@ -4388,27 +4399,30 @@ cdef class NumberFieldElement(NumberFieldElement_base): def residue_symbol(self, P, m, check=True): r""" - The m-th power residue symbol for an element self and proper ideal P. + The `m`-th power residue symbol for an element ``self`` and proper ideal `P`. .. MATH:: \left(\frac{\alpha}{\mathbf{P}}\right) \equiv \alpha^{\frac{N(\mathbf{P})-1}{m}} \operatorname{mod} \mathbf{P} - .. NOTE:: accepts m=1, in which case returns 1 + .. NOTE:: accepts `m=1`, in which case returns 1 .. NOTE:: can also be called for an ideal from sage.rings.number_field_ideal.residue_symbol .. NOTE:: self is coerced into the number field of the ideal P - .. NOTE:: if m=2, self is an integer, and P is an ideal of a number field of absolute degree 1 (i.e. it is a copy of the rationals), then this calls kronecker_symbol, which is implemented using GMP. + .. NOTE:: + + if `m=2`, ``self`` is an integer, and `P` is an ideal of a number field of absolute degree 1 (i.e. it is a copy of the rationals), + then this calls :func:`kronecker_symbol`, which is implemented using GMP. INPUT: - - ``P`` - proper ideal of the number field (or an extension) + - ``P`` -- proper ideal of the number field (or an extension) - - ``m`` - positive integer + - ``m`` -- positive integer OUTPUT: - - an m-th root of unity in the number field + - an `m`-th root of unity in the number field EXAMPLES: @@ -4417,7 +4431,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): sage: K. = NumberField(x - 1) sage: K(11).residue_symbol(K.ideal(17),2) -1 - sage: kronecker_symbol(11,17) + sage: kronecker_symbol(11, 17) -1 The result depends on the number field of the ideal:: @@ -4453,17 +4467,17 @@ cdef class NumberFieldElement(NumberFieldElement_base): INPUT: - - ``K`` (number field, default \QQ) -- a subfield of the + - ``K`` (number field, default `\QQ`) -- a subfield of the parent number field `L` of ``self`` - ``d`` (positive integer, default 2) -- an integer at least 2 OUTPUT: - A list, possibly empty, of elements of ``K`` equal to ``self`` + A list, possibly empty, of elements of `K` equal to ``self`` modulo `d`'th powers, i.e. the preimages of ``self`` under the map `K^*/(K^*)^d \rightarrow L^*/(L^*)^d` where `L` is the - parent of ``self``. A ``ValueError`` is raised if `K` does + parent of ``self``. A :class:`ValueError` is raised if `K` does not embed into `L`. ALGORITHM: @@ -4621,7 +4635,7 @@ cdef class NumberFieldElement_absolute(NumberFieldElement): INPUT: - - ``magma`` - a Magma interpreter + - ``magma`` -- a Magma interpreter OUTPUT: MagmaElement that has parent the Magma object corresponding @@ -4688,19 +4702,25 @@ cdef class NumberFieldElement_absolute(NumberFieldElement): EXAMPLES:: sage: x = ZZ['x'].0 - sage: f = x^10 - 5*x^9 + 15*x^8 - 68*x^7 + 81*x^6 - 221*x^5 + 141*x^4 - 242*x^3 - 13*x^2 - 33*x - 135 + sage: f = (x^10 - 5*x^9 + 15*x^8 - 68*x^7 + 81*x^6 - 221*x^5 + ....: + 141*x^4 - 242*x^3 - 13*x^2 - 33*x - 135) sage: K. = NumberField(f, 'a') sage: a.absolute_charpoly() - x^10 - 5*x^9 + 15*x^8 - 68*x^7 + 81*x^6 - 221*x^5 + 141*x^4 - 242*x^3 - 13*x^2 - 33*x - 135 + x^10 - 5*x^9 + 15*x^8 - 68*x^7 + 81*x^6 - 221*x^5 + + 141*x^4 - 242*x^3 - 13*x^2 - 33*x - 135 sage: a.absolute_charpoly('y') - y^10 - 5*y^9 + 15*y^8 - 68*y^7 + 81*y^6 - 221*y^5 + 141*y^4 - 242*y^3 - 13*y^2 - 33*y - 135 - sage: b = -79/9995*a^9 + 52/9995*a^8 + 271/9995*a^7 + 1663/9995*a^6 + 13204/9995*a^5 + 5573/9995*a^4 + 8435/1999*a^3 - 3116/9995*a^2 + 7734/1999*a + 1620/1999 + y^10 - 5*y^9 + 15*y^8 - 68*y^7 + 81*y^6 - 221*y^5 + + 141*y^4 - 242*y^3 - 13*y^2 - 33*y - 135 + sage: b = (-79/9995*a^9 + 52/9995*a^8 + 271/9995*a^7 + 1663/9995*a^6 + ....: + 13204/9995*a^5 + 5573/9995*a^4 + 8435/1999*a^3 + ....: - 3116/9995*a^2 + 7734/1999*a + 1620/1999) sage: b.absolute_charpoly() - x^10 + 10*x^9 + 25*x^8 - 80*x^7 - 438*x^6 + 80*x^5 + 2950*x^4 + 1520*x^3 - 10439*x^2 - 5130*x + 18225 + x^10 + 10*x^9 + 25*x^8 - 80*x^7 - 438*x^6 + 80*x^5 + + 2950*x^4 + 1520*x^3 - 10439*x^2 - 5130*x + 18225 sage: b.absolute_minpoly() x^5 + 5*x^4 - 40*x^2 - 19*x + 135 - sage: b.absolute_minpoly(algorithm='pari') == b.absolute_minpoly(algorithm='sage') + sage: b.absolute_minpoly(algorithm='pari') == b.absolute_minpoly(algorithm='sage') # optional - sage.libs.pari True """ return self.minpoly(var, algorithm) @@ -4708,18 +4728,18 @@ cdef class NumberFieldElement_absolute(NumberFieldElement): def charpoly(self, var='x', algorithm=None): r""" The characteristic polynomial of this element, over - `\QQ` if self is an element of a field, and over - `\ZZ` is self is an element of an order. + `\QQ` if ``self`` is an element of a field, and over + `\ZZ` is ``self`` is an element of an order. - This is the same as ``self.absolute_charpoly`` since + This is the same as :meth:`absolute_charpoly` since this is an element of an absolute extension. - The optional argument algorithm controls how the - characteristic polynomial is computed: 'pari' uses PARI, - 'sage' uses charpoly for Sage matrices. The default value - None means that 'pari' is used for small degrees (up to the - value of the constant TUNE_CHARPOLY_NF, currently at 25), - otherwise 'sage' is used. The constant TUNE_CHARPOLY_NF + The optional argument ``algorithm`` controls how the + characteristic polynomial is computed: ``'pari'`` uses PARI, + ``'sage'`` uses ``charpoly`` for Sage matrices. The default value + ``None`` means that ``'pari'`` is used for small degrees (up to the + value of the constant ``TUNE_CHARPOLY_NF``, currently at 25), + otherwise ``'sage'`` is used. The constant ``TUNE_CHARPOLY_NF`` should give reasonable performance on all architectures; however, if you feel the need to customize it to your own machine, see :trac:`5213` for a tuning script. @@ -4731,7 +4751,7 @@ cdef class NumberFieldElement_absolute(NumberFieldElement): :: sage: R. = QQ[] - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: a.charpoly('x') x^3 - 2 sage: a.charpoly('y').parent() @@ -4745,7 +4765,7 @@ cdef class NumberFieldElement_absolute(NumberFieldElement): sage: R(a).charpoly().parent() Univariate Polynomial Ring in x over Integer Ring - sage: R(a).charpoly(algorithm='pari') == R(a).charpoly(algorithm='sage') + sage: R(a).charpoly(algorithm='pari') == R(a).charpoly(algorithm='sage') # optional - sage.libs.pari True """ if algorithm is None: @@ -4763,7 +4783,7 @@ cdef class NumberFieldElement_absolute(NumberFieldElement): """ Return the minimal polynomial of this number field element. - For the meaning of the optional argument algorithm, see charpoly(). + For the meaning of the optional argument ``algorithm``, see :meth:`charpoly`. EXAMPLES: @@ -4772,7 +4792,7 @@ cdef class NumberFieldElement_absolute(NumberFieldElement): :: sage: R. = QQ[] - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: a.minpoly('x') x^3 - 2 sage: a.minpoly('y').parent() @@ -4793,14 +4813,14 @@ cdef class NumberFieldElement_absolute(NumberFieldElement): return self.charpoly(var, algorithm).radical() # square free part of charpoly def list(self): - """ - Return the list of coefficients of self written in terms of a power + r""" + Return the list of coefficients of ``self`` written in terms of a power basis. EXAMPLES:: sage: K. = CyclotomicField(3) - sage: (2+3/5*z).list() + sage: (2 + 3/5*z).list() [2, 3/5] sage: (5*z).list() [0, 5] @@ -4813,9 +4833,9 @@ cdef class NumberFieldElement_absolute(NumberFieldElement): return v + [z]*(n - len(v)) def lift(self, var='x'): - """ - Return an element of QQ[x], where this number field element - lives in QQ[x]/(f(x)). + r""" + Return an element of `\QQ[x]`, where this number field element + lives in `\QQ[x]/(f(x))`. EXAMPLES:: @@ -4836,29 +4856,29 @@ cdef class NumberFieldElement_absolute(NumberFieldElement): The algorithm first checks that ``self`` is not a strictly complex number. Then if ``self`` is not zero, by approximation - more and more precise, the method answers True if the - number is positive. Using `RealInterval`, the result is + more and more precise, the method answers ``True`` if the + number is positive. Using :class:`RealInterval`, the result is guaranteed to be correct. - For CyclotomicField, the embedding is the natural one - sending `zetan` on `cos(2*pi/n)`. + For :class:`CyclotomicField`, the embedding is the natural one + sending ``zetan`` on `\cos(2*\pi/n)`. EXAMPLES:: sage: K. = CyclotomicField(3) - sage: (a+a^2).is_real_positive() + sage: (a + a^2).is_real_positive() False - sage: (-a-a^2).is_real_positive() + sage: (-a - a^2).is_real_positive() True sage: K. = CyclotomicField(1000) - sage: (a+a^(-1)).is_real_positive() + sage: (a + a^(-1)).is_real_positive() True sage: K. = CyclotomicField(1009) sage: d = a^252 - sage: (d+d.conjugate()).is_real_positive() + sage: (d + d.conjugate()).is_real_positive() True sage: d = a^253 - sage: (d+d.conjugate()).is_real_positive() + sage: (d + d.conjugate()).is_real_positive() False sage: K. = QuadraticField(3) sage: a.is_real_positive() @@ -4866,7 +4886,7 @@ cdef class NumberFieldElement_absolute(NumberFieldElement): sage: K. = QuadraticField(-3) sage: a.is_real_positive() False - sage: (a-a).is_real_positive() + sage: (a - a).is_real_positive() False """ if self != self.conjugate() or self.is_zero(): @@ -4901,7 +4921,7 @@ cdef class NumberFieldElement_relative(NumberFieldElement): def __getitem__(self, n): """ - Return the n-th coefficient of this relative number field element, written + Return the `n`-th coefficient of this relative number field element, written as a polynomial in the generator. Note that `n` must be between 0 and `d-1`, where @@ -4951,7 +4971,7 @@ cdef class NumberFieldElement_relative(NumberFieldElement): def list(self): """ - Return the list of coefficients of self written in terms of a power + Return the list of coefficients of ``self`` written in terms of a power basis. EXAMPLES:: @@ -4968,8 +4988,8 @@ cdef class NumberFieldElement_relative(NumberFieldElement): def lift(self, var='x'): """ - Return an element of K[x], where this number field element - lives in the relative number field K[x]/(f(x)). + Return an element of `K[x]`, where this number field element + lives in the relative number field `K[x]/(f(x))`. EXAMPLES:: @@ -5001,7 +5021,7 @@ cdef class NumberFieldElement_relative(NumberFieldElement): def _latex_(self): r""" - Returns the latex representation for this element. + Return the latex representation for this element. EXAMPLES:: @@ -5068,12 +5088,12 @@ cdef class NumberFieldElement_relative(NumberFieldElement): We construct a relative extension and find the characteristic polynomial over `\QQ`. - The optional argument algorithm controls how the - characteristic polynomial is computed: 'pari' uses PARI, - 'sage' uses charpoly for Sage matrices. The default value - None means that 'pari' is used for small degrees (up to the - value of the constant TUNE_CHARPOLY_NF, currently at 25), - otherwise 'sage' is used. The constant TUNE_CHARPOLY_NF + The optional argument ``algorithm`` controls how the + characteristic polynomial is computed: ``'pari'`` uses PARI, + ``'sage'`` uses ``charpoly`` for Sage matrices. The default value + ``None`` means that ``'pari'`` is used for small degrees (up to the + value of the constant ``TUNE_CHARPOLY_NF``, currently at 25), + otherwise ``'sage'`` is used. The constant ``TUNE_CHARPOLY_NF`` should give reasonable performance on all architectures; however, if you feel the need to customize it to your own machine, see :trac:`5213` for a tuning script. @@ -5096,7 +5116,7 @@ cdef class NumberFieldElement_relative(NumberFieldElement): sage: a.absolute_charpoly('y') y^9 + 51*y^6 + 867*y^3 + 4913 - sage: a.absolute_charpoly(algorithm='pari') == a.absolute_charpoly(algorithm='sage') + sage: a.absolute_charpoly(algorithm='pari') == a.absolute_charpoly(algorithm='sage') # optional - sage.libs.pari True """ if algorithm is None: @@ -5134,7 +5154,8 @@ cdef class NumberFieldElement_relative(NumberFieldElement): sage: L(a).absolute_minpoly() x^2 + 2 sage: L(b).absolute_charpoly() - x^8 + 4000*x^7 + 6000004*x^6 + 4000012000*x^5 + 1000012000006*x^4 + 4000012000*x^3 + 6000004*x^2 + 4000*x + 1 + x^8 + 4000*x^7 + 6000004*x^6 + 4000012000*x^5 + 1000012000006*x^4 + + 4000012000*x^3 + 6000004*x^2 + 4000*x + 1 sage: L(b).absolute_minpoly() x^2 + 1000*x + 1 """ @@ -5142,13 +5163,11 @@ cdef class NumberFieldElement_relative(NumberFieldElement): def valuation(self, P): """ - Returns the valuation of self at a given prime ideal P. + Return the valuation of ``self`` at a given prime ideal `P`. INPUT: - - - ``P`` - a prime ideal of relative number field which is the parent of self - + - ``P`` -- a prime ideal of relative number field which is the parent of ``self`` EXAMPLES:: @@ -5202,7 +5221,7 @@ cdef class OrderElement_absolute(NumberFieldElement_absolute): cdef _new(self): """ Quickly creates a new initialized NumberFieldElement with the same - parent as self. + parent as ``self``. EXAMPLES: @@ -5222,7 +5241,7 @@ cdef class OrderElement_absolute(NumberFieldElement_absolute): cdef number_field(self): r""" - Return the number field of self. Only accessible from Cython. + Return the number field of ``self``. Only accessible from Cython. EXAMPLES:: @@ -5236,16 +5255,14 @@ cdef class OrderElement_absolute(NumberFieldElement_absolute): def inverse_mod(self, I): r""" - Return an inverse of self modulo the given ideal. + Return an inverse of ``self`` modulo the given ideal. INPUT: - - - ``I`` - may be an ideal of self.parent(), or an - element or list of elements of self.parent() generating a nonzero - ideal. A ValueError is raised if I is non-integral or is zero. - A ZeroDivisionError is raised if I + (x) != (1). - + - ``I`` -- may be an ideal of ``self.parent()``, or an + element or list of elements of ``self.parent()`` generating a nonzero + ideal. A :class:`ValueError` is raised if `I` is non-integral or is zero. + A :class:`ZeroDivisionError` is raised if `I + (x) \neq (1)`. EXAMPLES:: @@ -5273,7 +5290,7 @@ cdef class OrderElement_absolute(NumberFieldElement_absolute): EXAMPLES:: - sage: K = NumberField(x^3 -x + 2, 'a') + sage: K = NumberField(x^3 - x + 2, 'a') sage: OK = K.ring_of_integers() sage: a = OK(K.gen()) sage: (~a).parent() is K @@ -5364,15 +5381,15 @@ cdef class OrderElement_relative(NumberFieldElement_relative): def inverse_mod(self, I): r""" - Return an inverse of self modulo the given ideal. + Return an inverse of ``self`` modulo the given ideal. INPUT: - - ``I`` - may be an ideal of self.parent(), or an - element or list of elements of self.parent() generating a nonzero - ideal. A ValueError is raised if I is non-integral or is zero. - A ZeroDivisionError is raised if I + (x) != (1). + - ``I`` -- may be an ideal of ``self.parent()``, or an + element or list of elements of ``self.parent()`` generating a nonzero + ideal. A :class:`ValueError` is raised if `I` is non-integral or is zero. + A :class:`ZeroDivisionError` is raised if `I + (x) \neq (1)`. EXAMPLES:: @@ -5392,8 +5409,8 @@ cdef class OrderElement_relative(NumberFieldElement_relative): r""" The characteristic polynomial of this order element over its base ring. - This special implementation works around bug \#4738. At this - time the base ring of relative order elements is ZZ; it should + This special implementation works around :trac:`4738`. At this + time the base ring of relative order elements is `\ZZ`; it should be the ring of integers of the base field. EXAMPLES:: @@ -5405,7 +5422,8 @@ cdef class OrderElement_relative(NumberFieldElement_relative): sage: charpoly(OK.1) x^2 + b*x + 1 sage: charpoly(OK.1).parent() - Univariate Polynomial Ring in x over Maximal Order in Number Field in b with defining polynomial x^2 - 3 + Univariate Polynomial Ring in x over + Maximal Order in Number Field in b with defining polynomial x^2 - 3 sage: [ charpoly(t) for t in OK.basis() ] [x^2 - 2*x + 1, x^2 + b*x + 1, x^2 - x + 1, x^2 + 1] """ @@ -5416,8 +5434,8 @@ cdef class OrderElement_relative(NumberFieldElement_relative): r""" The minimal polynomial of this order element over its base ring. - This special implementation works around bug \#4738. At this - time the base ring of relative order elements is ZZ; it should + This special implementation works around :trac:`4738`. At this + time the base ring of relative order elements is `\ZZ`; it should be the ring of integers of the base field. EXAMPLES:: @@ -5429,7 +5447,8 @@ cdef class OrderElement_relative(NumberFieldElement_relative): sage: minpoly(OK.1) x^2 + b*x + 1 sage: charpoly(OK.1).parent() - Univariate Polynomial Ring in x over Maximal Order in Number Field in b with defining polynomial x^2 - 3 + Univariate Polynomial Ring in x over + Maximal Order in Number Field in b with defining polynomial x^2 - 3 sage: _, u, _, v = OK.basis() sage: t = 2*u - v; t -b @@ -5449,7 +5468,7 @@ cdef class OrderElement_relative(NumberFieldElement_relative): def absolute_charpoly(self, var='x'): r""" - The absolute characteristic polynomial of this order element over ZZ. + The absolute characteristic polynomial of this order element over `\ZZ`. EXAMPLES:: @@ -5472,7 +5491,7 @@ cdef class OrderElement_relative(NumberFieldElement_relative): def absolute_minpoly(self, var='x'): r""" - The absolute minimal polynomial of this order element over ZZ. + The absolute minimal polynomial of this order element over `\ZZ`. EXAMPLES:: diff --git a/src/sage/rings/number_field/number_field_element_base.pyx b/src/sage/rings/number_field/number_field_element_base.pyx index 5385833f1d4..c4938237a6d 100644 --- a/src/sage/rings/number_field/number_field_element_base.pyx +++ b/src/sage/rings/number_field/number_field_element_base.pyx @@ -20,8 +20,8 @@ cdef class NumberFieldElement_base(FieldElement): EXAMPLES:: - sage: k. = NumberField(x^3 + x + 1) - sage: isinstance(a, sage.rings.number_field.number_field_element_base.NumberFieldElement_base) + sage: k. = NumberField(x^3 + x + 1) # optional - sage.rings.number_field + sage: isinstance(a, sage.rings.number_field.number_field_element_base.NumberFieldElement_base) # optional - sage.rings.number_field True By design, there is a unique direct subclass:: diff --git a/src/sage/rings/number_field/number_field_element_quadratic.pyx b/src/sage/rings/number_field/number_field_element_quadratic.pyx index bcba57457e5..062e15b238d 100644 --- a/src/sage/rings/number_field/number_field_element_quadratic.pyx +++ b/src/sage/rings/number_field/number_field_element_quadratic.pyx @@ -7,7 +7,7 @@ r""" Optimized Quadratic Number Field Elements -This file defines a Cython class ``NumberFieldElement_quadratic`` to speed up +This file defines a Cython class :class:`NumberFieldElement_quadratic` to speed up computations in quadratic extensions of `\QQ`. AUTHORS: @@ -101,11 +101,11 @@ def __make_NumberFieldElement_quadratic1(parent, cls, a, b, denom): cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): r""" - A NumberFieldElement_quadratic object gives an efficient representation of + A :class:`NumberFieldElement_quadratic` object gives an efficient representation of an element of a quadratic extension of `\QQ`. Elements are represented internally as triples `(a, b, c)` of integers, - where `{\rm gcd}(a, b, c) = 1` and `c > 0`, representing the element `(a + + where `\gcd(a, b, c) = 1` and `c > 0`, representing the element `(a + b \sqrt{D}) / c`. Note that if the discriminant `D` is `1 \bmod 4`, integral elements do not necessarily have `c = 1`. @@ -116,19 +116,19 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): We set up some fields:: - sage: K. = NumberField(x^2+23) + sage: K. = NumberField(x^2 + 23) sage: a.parts() (0, 1) - sage: F. = NumberField(x^2-x+7) + sage: F. = NumberField(x^2 - x + 7) sage: b.parts() (1/2, 3/2) - We construct elements of these fields in various ways - firstly, from + We construct elements of these fields in various ways -- firstly, from polynomials:: - sage: NumberFieldElement_quadratic_sqrt(K, x-1) + sage: NumberFieldElement_quadratic_sqrt(K, x - 1) a - 1 - sage: NumberFieldElement_quadratic(F, x-1) + sage: NumberFieldElement_quadratic(F, x - 1) b - 1 From triples of Integers:: @@ -142,11 +142,11 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): From pairs of Rationals:: - sage: NumberFieldElement_quadratic_sqrt(K, (1/2,1/3)) + sage: NumberFieldElement_quadratic_sqrt(K, (1/2, 1/3)) 1/3*a + 1/2 - sage: NumberFieldElement_quadratic(F, (1/2,1/3)) + sage: NumberFieldElement_quadratic(F, (1/2, 1/3)) 2/9*b + 7/18 - sage: NumberFieldElement_quadratic(F, (1/2,1/3)).parts() + sage: NumberFieldElement_quadratic(F, (1/2, 1/3)).parts() (1/2, 1/3) Direct from Rationals:: @@ -158,7 +158,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): This checks a bug when converting from lists:: - sage: w = CyclotomicField(3)([1/2,1]) + sage: w = CyclotomicField(3)([1/2, 1]) sage: w == w.__invert__().__invert__() True """ @@ -294,9 +294,9 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): EXAMPLES:: sage: K. = QuadraticField(-1) - sage: (1/3 + a/2)._sympy_() + sage: (1/3 + a/2)._sympy_() # optional - sympy 1/3 + I/2 - sage: type(_) + sage: type(_) # optional - sympy """ a = self.parent().gen() @@ -313,7 +313,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): EXAMPLES:: sage: K. = QuadraticField(5) - sage: polymake(3+2*sqrt5) # optional - jupymake + sage: polymake(3 + 2*sqrt5) # optional - jupymake 3+2r5 sage: polymake(2**100/7 - 2*sqrt5/3**50) # optional - jupymake 1267650600228229401496703205376/7-2/717897987691852588770249r5 @@ -892,7 +892,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): cpdef tuple parts(self): r""" - This function returns a pair of rationals `a` and `b` such that self `= + Return a pair of rationals `a` and `b` such that ``self`` `= a+b\sqrt{D}`. This is much closer to the internal storage format of the @@ -902,19 +902,19 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): EXAMPLES:: - sage: K. = NumberField(x^2-13) + sage: K. = NumberField(x^2 - 13) sage: K.discriminant() 13 sage: a.parts() (0, 1) - sage: (a/2-4).parts() + sage: (a/2 - 4).parts() (-4, 1/2) - sage: K. = NumberField(x^2-7) + sage: K. = NumberField(x^2 - 7) sage: K.discriminant() 28 sage: a.parts() (0, 1) - sage: K. = NumberField(x^2-x+7) + sage: K. = NumberField(x^2 - x + 7) sage: a.parts() (1/2, 3/2) sage: a._coefficients() @@ -943,7 +943,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): def sign(self): r""" - Returns the sign of self (0 if zero, +1 if positive and -1 if negative). + Returns the sign of ``self`` (`0` if zero, `+1` if positive, and `-1` if negative). EXAMPLES:: @@ -1235,7 +1235,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): sage: K. = QuadraticField(2) sage: sqrt2.continued_fraction_list() ((1,), (2,)) - sage: (1/2+sqrt2/3).continued_fraction_list() + sage: (1/2 + sqrt2/3).continued_fraction_list() ((0, 1, 33), (1, 32)) For rational entries a pair of tuples is also returned but the second @@ -1755,7 +1755,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): sage: K. = QuadraticField(3) sage: sqrt3.is_rational() False - sage: (sqrt3-1/2).is_rational() + sage: (sqrt3 - 1/2).is_rational() False sage: K(0).is_rational() True @@ -1780,7 +1780,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): sage: K. = QuadraticField(3) sage: sqrt3.is_integer() False - sage: (sqrt3-1/2).is_integer() + sage: (sqrt3 - 1/2).is_integer() False sage: K(0).is_integer() True @@ -1848,7 +1848,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): 1/2*sqrt3 sage: a.real() -1/2 - sage: SR(a) + sage: SR(a) # optional - sage.symbolic 1/2*I*sqrt(3) - 1/2 sage: bool(QQbar(I)*QQbar(a.imag()) + QQbar(a.real()) == QQbar(a)) True @@ -1938,7 +1938,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): r""" Return the denominator of ``self``. - This is the LCM of the denominators of the coefficients of `self``, and + This is the LCM of the denominators of the coefficients of ``self``, and thus it may well be `> 1` even when the element is an algebraic integer. EXAMPLES:: @@ -1950,7 +1950,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): sage: b.is_integral() True - sage: K. = NumberField(x^2-x+7) + sage: K. = NumberField(x^2 - x + 7) sage: c.denominator() 1 """ @@ -1970,7 +1970,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): EXAMPLES:: - sage: K. = NumberField(x^2+x+41) + sage: K. = NumberField(x^2 + x + 41) sage: b = (2*a+1)/6 sage: b.denominator() 6 @@ -1988,7 +1988,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): """ EXAMPLES:: - sage: K. = NumberField(x^2+x+41) + sage: K. = NumberField(x^2 + x + 41) sage: a.trace() -1 sage: a.matrix() @@ -1997,14 +1997,14 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): The trace is additive:: - sage: K. = NumberField(x^2+7) - sage: (a+1).trace() + sage: K. = NumberField(x^2 + 7) + sage: (a + 1).trace() 2 sage: K(3).trace() 6 - sage: (a+4).trace() + sage: (a + 4).trace() 8 - sage: (a/3+1).trace() + sage: (a/3 + 1).trace() 2 """ # trace = 2*self.a / self.denom @@ -2023,24 +2023,24 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): Return the norm of ``self``. If the second argument is ``None``, this is the - norm down to `\QQ`. Otherwise, return the norm down to K (which had + norm down to `\QQ`. Otherwise, return the norm down to `K` (which had better be either `\QQ` or this number field). EXAMPLES:: - sage: K. = NumberField(x^2-x+3) + sage: K. = NumberField(x^2 - x + 3) sage: a.norm() 3 sage: a.matrix() [ 0 1] [-3 1] - sage: K. = NumberField(x^2+5) - sage: (1+a).norm() + sage: K. = NumberField(x^2 + 5) + sage: (1 + a).norm() 6 The norm is multiplicative:: - sage: K. = NumberField(x^2-3) + sage: K. = NumberField(x^2 - 3) sage: a.norm() -3 sage: K(3).norm() @@ -2136,15 +2136,15 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): INPUT: - ``var`` -- the minimal polynomial is defined over a polynomial ring - in a variable with this name. If not specified this defaults to ``x`` + in a variable with this name. If not specified, this defaults to ``'x'`` - ``algorithm`` -- for compatibility with general number field elements; ignored EXAMPLES:: - sage: K. = NumberField(x^2-x+13) + sage: K. = NumberField(x^2 - x + 13) sage: a.charpoly() x^2 - x + 13 - sage: b = 3-a/2 + sage: b = 3 - a/2 sage: f = b.charpoly(); f x^2 - 11/2*x + 43/4 sage: f(b) @@ -2160,18 +2160,17 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): INPUT: - ``var`` -- the minimal polynomial is defined over a polynomial ring - in a variable with this name. If not specified this defaults to ``x`` + in a variable with this name. If not specified, this defaults to ``'x'`` - ``algorithm`` -- for compatibility with general number field elements: and ignored - EXAMPLES:: - sage: K. = NumberField(x^2+13) + sage: K. = NumberField(x^2 + 13) sage: a.minpoly() x^2 + 13 sage: a.minpoly('T') T^2 + 13 - sage: (a+1/2-a).minpoly() + sage: (a + 1/2 - a).minpoly() x - 1/2 """ if self.is_rational(): @@ -2208,18 +2207,18 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): def floor(self): r""" - Returns the floor of x. + Returns the floor of ``self``. EXAMPLES:: - sage: K. = QuadraticField(2,name='sqrt2') + sage: K. = QuadraticField(2, name='sqrt2') sage: sqrt2.floor() 1 sage: (-sqrt2).floor() -2 sage: (13/197 + 3702/123*sqrt2).floor() 42 - sage: (13/197-3702/123*sqrt2).floor() + sage: (13/197 - 3702/123*sqrt2).floor() -43 TESTS:: @@ -2274,7 +2273,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): def ceil(self): r""" - Returns the ceil. + Return the ceil. EXAMPLES:: @@ -2353,7 +2352,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): cdef class NumberFieldElement_quadratic_sqrt(NumberFieldElement_quadratic): r""" - A NumberFieldElement_quadratic object gives an efficient representation of + A :class:`NumberFieldElement_quadratic_sqrt` object gives an efficient representation of an element of a quadratic extension of `\QQ` for the case when :func:`is_sqrt_disc()` is ``True``. """ @@ -2361,12 +2360,12 @@ cdef class NumberFieldElement_quadratic_sqrt(NumberFieldElement_quadratic): r""" Return the denominator of ``self``. - This is the LCM of the denominators of the coefficients of `self``, and + This is the LCM of the denominators of the coefficients of ``self``, and thus it may well be `> 1` even when the element is an algebraic integer. EXAMPLES:: - sage: K. = NumberField(x^2+x+41) + sage: K. = NumberField(x^2 + x + 41) sage: a.denominator() 1 sage: b = (2*a+1)/6 @@ -2481,11 +2480,11 @@ cdef class NumberFieldElement_gaussian(NumberFieldElement_quadratic_sqrt): r""" EXAMPLES:: - sage: SR(1 + 2*i) + sage: SR(1 + 2*i) # optional - sage.symbolic 2*I + 1 sage: K. = QuadraticField(-1, embedding=CC(0,-1)) - sage: SR(1 + mi) + sage: SR(1 + mi) # optional - sage.symbolic -I + 1 """ from sage.symbolic.constants import I @@ -2591,7 +2590,7 @@ cdef class NumberFieldElement_gaussian(NumberFieldElement_quadratic_sqrt): EXAMPLES:: - sage: I.log() + sage: I.log() # optional - sage.symbolic 1/2*I*pi """ from sage.symbolic.ring import SR @@ -2666,7 +2665,7 @@ cdef class OrderElement_quadratic(NumberFieldElement_quadratic): INPUT: - ``var`` -- the minimal polynomial is defined over a polynomial ring - in a variable with this name. If not specified this defaults to ``x`` + in a variable with this name. If not specified, this defaults to ``'x'`` - ``algorithm`` -- for compatibility with general number field elements; ignored @@ -2692,10 +2691,9 @@ cdef class OrderElement_quadratic(NumberFieldElement_quadratic): INPUT: - ``var`` -- the minimal polynomial is defined over a polynomial ring - in a variable with this name. If not specified this defaults to ``x`` + in a variable with this name. If not specified, this defaults to ``'x'`` - ``algorithm`` -- for compatibility with general number field elements; ignored - EXAMPLES:: sage: K. = NumberField(x^2 + 163) @@ -2779,16 +2777,14 @@ cdef class OrderElement_quadratic(NumberFieldElement_quadratic): def inverse_mod(self, I): r""" - Return an inverse of self modulo the given ideal. + Return an inverse of ``self`` modulo the given ideal. INPUT: - - - ``I`` - may be an ideal of self.parent(), or an - element or list of elements of self.parent() generating a nonzero - ideal. A ValueError is raised if I is non-integral or is zero. - A ZeroDivisionError is raised if I + (x) != (1). - + - ``I`` -- may be an ideal of ``self.parent()``, or an + element or list of elements of ``self.parent()`` generating a nonzero + ideal. A :class:`ValueError` is raised if `I` is non-integral or is zero. + A :class:`ZeroDivisionError` is raised if `I + (x) \neq (1)`. EXAMPLES:: @@ -2838,12 +2834,12 @@ cdef class OrderElement_quadratic(NumberFieldElement_quadratic): r""" Return the denominator of ``self``. - This is the LCM of the denominators of the coefficients of `self``, and + This is the LCM of the denominators of the coefficients of ``self``, and thus it may well be `> 1` even when the element is an algebraic integer. EXAMPLES:: - sage: K. = NumberField(x^2-27) + sage: K. = NumberField(x^2 - 27) sage: R = K.ring_of_integers() sage: aa = R.gen(1) sage: aa.denominator() @@ -2871,7 +2867,7 @@ cdef class OrderElement_quadratic(NumberFieldElement_quadratic): cdef class Z_to_quadratic_field_element(Morphism): """ Morphism that coerces from integers to elements of a quadratic number - field K. + field `K`. EXAMPLES:: @@ -2973,7 +2969,7 @@ cdef class Z_to_quadratic_field_element(Morphism): cdef class Q_to_quadratic_field_element(Morphism): """ Morphism that coerces from rationals to elements of a quadratic number - field K. + field `K`. EXAMPLES:: diff --git a/src/sage/rings/number_field/number_field_ideal.py b/src/sage/rings/number_field/number_field_ideal.py index afdf29c52f5..ce1e8bce645 100644 --- a/src/sage/rings/number_field/number_field_ideal.py +++ b/src/sage/rings/number_field/number_field_ideal.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.pari """ Number Field Ideals @@ -11,7 +12,9 @@ NumberFieldFractionalIdeal now used for all except the 0 ideal - Radoslav Kirov and Alyson Deines (2010-06-22): - prime_to_S_part, is_S_unit, is_S_integral + prime_to_S_part, is_S_unit, is_S_integral + +TESTS: We test that pickling works:: @@ -69,9 +72,9 @@ def __init__(self, field, gens, coerce=True): """ INPUT: - - ``field`` - a number field + - ``field`` -- a number field - - ``x`` - a list of NumberFieldElements belonging to the field + - ``x`` -- a list of :class:`NumberFieldElement` objects belonging to the field EXAMPLES:: @@ -95,7 +98,7 @@ def __init__(self, field, gens, coerce=True): TESTS: - Check that _pari_prime is set when initializing from a PARI + Check that ``_pari_prime`` is set when initializing from a PARI prime ideal:: sage: K.ideal(pari(K).idealprimedec(5)[0])._pari_prime @@ -143,10 +146,10 @@ def _magma_init_(self, magma): INPUT: - - ``magma`` - a Magma interpreter + - ``magma`` -- a Magma interpreter - OUTPUT: MagmaElement corresponding to this ideal. + OUTPUT: :class:`MagmaElement` corresponding to this ideal. EXAMPLES:: @@ -258,9 +261,9 @@ def _richcmp_(self, other, op): def _mul_(self, other): """ - Returns the product of self and other. + Return the product of ``self`` and ``other``. - This is implemented by just calling pari to do the multiplication. + This is implemented by just calling PARI to do the multiplication. EXAMPLES:: @@ -291,37 +294,39 @@ def _mul_(self, other): def coordinates(self, x): r""" - Returns the coordinate vector of `x` with respect to this ideal. + Return the coordinate vector of `x` with respect to this ideal. INPUT: - ``x`` -- an element of the number field (or ring of integers) of this ideal. + + - ``x`` -- an element of the number field (or ring of integers) of this ideal. OUTPUT: - List giving the coordinates of `x` with respect to the integral basis - of the ideal. In general this will be a vector of - rationals; it will consist of integers if and only if `x` - is in the ideal. + + List giving the coordinates of `x` with respect to the integral basis + of the ideal. In general this will be a vector of + rationals; it will consist of integers if and only if `x` + is in the ideal. AUTHOR: John Cremona 2008-10-31 ALGORITHM: Uses linear algebra. - Provides simpler implementations for ``_contains_()``, - ``is_integral()`` and ``smallest_integer()``. + Provides simpler implementations for :meth:`_contains_`, + :meth:`is_integral` and :meth:`smallest_integer`. EXAMPLES:: sage: K. = QuadraticField(-1) - sage: I = K.ideal(7+3*i) + sage: I = K.ideal(7 + 3*i) sage: Ibasis = I.integral_basis(); Ibasis [58, i + 41] - sage: a = 23-14*i + sage: a = 23 - 14*i sage: acoords = I.coordinates(a); acoords (597/58, -14) sage: sum([Ibasis[j]*acoords[j] for j in range(2)]) == a True - sage: b = 123+456*i + sage: b = 123 + 456*i sage: bcoords = I.coordinates(b); bcoords (-18573/58, 456) sage: sum([Ibasis[j]*bcoords[j] for j in range(2)]) == b @@ -343,7 +348,7 @@ def coordinates(self, x): def _contains_(self, x): """ - Return True if x is an element of this ideal. + Return ``True`` if `x` is an element of this ideal. This function is called (indirectly) when the ``in`` operator is used. @@ -490,7 +495,7 @@ def _repr_short(self): def _gens_repr(self): """ - Returns tuple of generators to be used for printing this number + Return tuple of generators to be used for printing this number field ideal. The gens are reduced only if the absolute value of the norm of the discriminant of the defining polynomial is at most sage.rings.number_field.number_field_ideal.SMALL_DISC. @@ -526,7 +531,7 @@ def _gens_repr(self): def __pari__(self): """ - Returns PARI Hermite Normal Form representations of this + Return PARI Hermite Normal Form representations of this ideal. EXAMPLES:: @@ -541,7 +546,7 @@ def __pari__(self): def _pari_init_(self): """ - Returns self in PARI Hermite Normal Form as a string + Return self in PARI Hermite Normal Form as a string EXAMPLES:: @@ -577,7 +582,7 @@ def pari_hnf(self): @cached_method def basis(self): r""" - Return a basis for this ideal viewed as a `\ZZ` -module. + Return a basis for this ideal viewed as a `\ZZ`-module. OUTPUT: @@ -589,7 +594,8 @@ def basis(self): sage: K. = CyclotomicField(7) sage: I = K.factor(11)[0][0] sage: I.basis() # warning -- choice of basis can be somewhat random - [11, 11*z, 11*z^2, z^3 + 5*z^2 + 4*z + 10, z^4 + z^2 + z + 5, z^5 + z^4 + z^3 + 2*z^2 + 6*z + 5] + [11, 11*z, 11*z^2, z^3 + 5*z^2 + 4*z + 10, + z^4 + z^2 + z + 5, z^5 + z^4 + z^3 + 2*z^2 + 6*z + 5] An example of a non-integral ideal.:: @@ -597,7 +603,9 @@ def basis(self): sage: J # warning -- choice of generators can be somewhat random Fractional ideal (2/11*z^5 + 2/11*z^4 + 3/11*z^3 + 2/11) sage: J.basis() # warning -- choice of basis can be somewhat random - [1, z, z^2, 1/11*z^3 + 7/11*z^2 + 6/11*z + 10/11, 1/11*z^4 + 1/11*z^2 + 1/11*z + 7/11, 1/11*z^5 + 1/11*z^4 + 1/11*z^3 + 2/11*z^2 + 8/11*z + 7/11] + [1, z, z^2, 1/11*z^3 + 7/11*z^2 + 6/11*z + 10/11, + 1/11*z^4 + 1/11*z^2 + 1/11*z + 7/11, + 1/11*z^5 + 1/11*z^4 + 1/11*z^3 + 2/11*z^2 + 8/11*z + 7/11] Number fields defined by non-monic and non-integral polynomials are supported (:trac:`252`):: @@ -734,7 +742,7 @@ def gens_reduced(self, proof=None): Express this ideal in terms of at most two generators, and one if possible. - This function indirectly uses ``bnfisprincipal``, so set + This function indirectly uses :pari:`bnfisprincipal`, so set ``proof=True`` if you want to prove correctness (which *is* the default). @@ -744,12 +752,12 @@ def gens_reduced(self, proof=None): sage: K. = NumberField(x^2 + 5) sage: K.ideal(0).gens_reduced() (0,) - sage: J = K.ideal([a+2, 9]) + sage: J = K.ideal([a + 2, 9]) sage: J.gens() (a + 2, 9) sage: J.gens_reduced() # random sign (a + 2,) - sage: K.ideal([a+2, 3]).gens_reduced() + sage: K.ideal([a + 2, 3]).gens_reduced() (3, a + 2) TESTS:: @@ -804,12 +812,12 @@ def gens_two(self): sage: R. = PolynomialRing(QQ) sage: K. = NumberField(x^2 + 5) - sage: J = K.ideal([a+2, 9]) + sage: J = K.ideal([a + 2, 9]) sage: J.gens() (a + 2, 9) sage: J.gens_two() (9, a + 2) - sage: K.ideal([a+5, a+8]).gens_two() + sage: K.ideal([a + 5, a + 8]).gens_two() (3, a + 2) sage: K.ideal(0).gens_two() (0, 0) @@ -855,7 +863,7 @@ def integral_basis(self): sage: R. = PolynomialRing(QQ) sage: K. = NumberField(x^2 + 1) - sage: J = K.ideal(i+1) + sage: J = K.ideal(i + 1) sage: J.integral_basis() [2, i + 1] """ @@ -870,11 +878,11 @@ def integral_split(self): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^2-5) + sage: K. = NumberField(x^2 - 5) sage: I = K.ideal(2/(5+a)) sage: I.is_integral() False - sage: J,d = I.integral_split() + sage: J, d = I.integral_split() sage: J Fractional ideal (-1/2*a + 5/2) sage: J.is_integral() @@ -904,20 +912,20 @@ def integral_split(self): def intersection(self, other): r""" - Return the intersection of self and other. + Return the intersection of ``self`` and ``other``. EXAMPLES:: sage: K. = QuadraticField(-11) sage: p = K.ideal((a + 1)/2); q = K.ideal((a + 3)/2) - sage: p.intersection(q) == q.intersection(p) == K.ideal(a-2) + sage: p.intersection(q) == q.intersection(p) == K.ideal(a - 2) True An example with non-principal ideals:: sage: L. = NumberField(x^3 - 7) sage: p = L.ideal(a^2 + a + 1, 2) - sage: q = L.ideal(a+1) + sage: q = L.ideal(a + 1) sage: p.intersection(q) == L.ideal(8, 2*a + 2) True @@ -948,12 +956,12 @@ def intersection(self, other): def is_integral(self): """ - Return True if this ideal is integral. + Return ``True`` if this ideal is integral. EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^5-x+1) + sage: K. = NumberField(x^5 - x + 1) sage: K.ideal(a).is_integral() True sage: (K.ideal(1) / (3*a+1)).is_integral() @@ -968,8 +976,8 @@ def is_integral(self): def is_maximal(self): """ - Return True if this ideal is maximal. This is equivalent to - self being prime and nonzero. + Return ``True`` if this ideal is maximal. This is equivalent to + ``self`` being prime and nonzero. EXAMPLES:: @@ -984,7 +992,7 @@ def is_maximal(self): def is_prime(self): """ - Return True if this ideal is prime. + Return ``True`` if this ideal is prime. EXAMPLES:: @@ -1031,11 +1039,11 @@ def is_prime(self): def pari_prime(self): r""" - Returns a PARI prime ideal corresponding to the ideal ``self``. + Return a PARI prime ideal corresponding to the ideal ``self``. INPUT: - - ``self`` - a prime ideal. + - ``self`` -- a prime ideal. OUTPUT: a PARI "prime ideal", i.e. a five-component vector `[p,a,e,f,b]` representing the prime ideal `p O_K + a O_K`, `e`, `f` as usual, `a` as @@ -1129,7 +1137,7 @@ def _cache_bnfisprincipal(self, proof=None, gens=False): def is_principal(self, proof=None): r""" - Return True if this ideal is principal. + Return ``True`` if this ideal is principal. Since it uses the PARI method :pari:`bnfisprincipal`, specify ``proof=True`` (this is the default setting) to prove the correctness @@ -1191,7 +1199,8 @@ def ideal_class_log(self, proof=None): sage: K. = NumberField([x^3 - x + 1, x^2 + 26]) sage: K.class_group() - Class group of order 18 with structure C6 x C3 of Number Field in a with defining polynomial x^3 - x + 1 over its base field + Class group of order 18 with structure C6 x C3 of + Number Field in a with defining polynomial x^3 - x + 1 over its base field sage: K.primes_above(7)[0].ideal_class_log() # random [1, 2] """ @@ -1238,10 +1247,10 @@ def S_ideal_class_log(self, S): def is_zero(self): """ - Return True iff self is the zero ideal + Return ``True`` iff ``self`` is the zero ideal - Note that `(0)` is a ``NumberFieldIdeal``, not a - ``NumberFieldFractionalIdeal``. + Note that `(0)` is a :class:`NumberFieldIdeal`, not a + :class:`NumberFieldFractionalIdeal`. EXAMPLES:: @@ -1249,7 +1258,7 @@ def is_zero(self): Number Field in a with defining polynomial x^2 + 2 sage: K.ideal(3).is_zero() False - sage: I=K.ideal(0); I.is_zero() + sage: I = K.ideal(0); I.is_zero() True sage: I Ideal (0) of Number Field in a with defining polynomial x^2 + 2 @@ -1283,7 +1292,7 @@ def norm(self): def absolute_norm(self): """ - A synonym for norm. + A synonym for :meth:`norm`. EXAMPLES:: @@ -1295,7 +1304,7 @@ def absolute_norm(self): def relative_norm(self): """ - A synonym for norm. + A synonym for :meth:`norm`. EXAMPLES:: @@ -1307,7 +1316,7 @@ def relative_norm(self): def absolute_ramification_index(self): """ - A synonym for ramification_index. + A synonym for :meth:`ramification_index`. EXAMPLES:: @@ -1319,7 +1328,7 @@ def absolute_ramification_index(self): def relative_ramification_index(self): """ - A synonym for ramification_index. + A synonym for :meth:`ramification_index`. EXAMPLES:: @@ -1339,7 +1348,7 @@ def number_field(self): Number Field in a with defining polynomial x^2 + 2 sage: K.ideal(3).number_field() Number Field in a with defining polynomial x^2 + 2 - sage: K.ideal(0).number_field() # not tested (not implemented) + sage: K.ideal(0).number_field() # not tested (not implemented) Number Field in a with defining polynomial x^2 + 2 """ return self.ring() @@ -1352,8 +1361,8 @@ def smallest_integer(self): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^2+6) - sage: I = K.ideal([4,a])/7; I + sage: K. = NumberField(x^2 + 6) + sage: I = K.ideal([4, a])/7; I Fractional ideal (2/7, 1/7*a) sage: I.smallest_integer() 2 @@ -1413,7 +1422,7 @@ def valuation(self, p): (integer) The valuation of this fractional ideal at the prime `\mathfrak{p}`. If `\mathfrak{p}` is not prime, raise a - ValueError. + :class:`ValueError`. EXAMPLES:: @@ -1430,7 +1439,8 @@ def valuation(self, p): sage: i.valuation(0) Traceback (most recent call last): ... - ValueError: p (= Ideal (0) of Number Field in a with defining polynomial x^5 + 2) must be nonzero + ValueError: p (= Ideal (0) of Number Field in a + with defining polynomial x^5 + 2) must be nonzero sage: K.ideal(0).valuation(K.factor(2)[0][0]) +Infinity """ @@ -1447,11 +1457,10 @@ def valuation(self, p): def decomposition_group(self): r""" - Return the decomposition group of self, as a subset of the - automorphism group of the number field of self. Raises an - error if the field isn't Galois. See the decomposition_group - method of the ``GaloisGroup_v2`` class for further examples - and doctests. + Return the decomposition group of ``self``, as a subset of the + automorphism group of the number field of ``self``. Raises an + error if the field isn't Galois. See the :meth:`GaloisGroup_v2.decomposition_group` + method for further examples and doctests. EXAMPLES:: @@ -1462,11 +1471,11 @@ def decomposition_group(self): def ramification_group(self, v): r""" - Return the `v`'th ramification group of self, i.e. the set of - elements `s` of the Galois group of the number field of self + Return the `v`'th ramification group of ``self``, i.e. the set of + elements `s` of the Galois group of the number field of ``self`` (which we assume is Galois) such that `s` acts trivially modulo the `(v+1)`'st power of self. See the - ramification_group method of the ``GaloisGroup`` class for + :meth:`GaloisGroup.ramification_group` method for further examples and doctests. EXAMPLES:: @@ -1481,11 +1490,11 @@ def ramification_group(self, v): def inertia_group(self): r""" - Return the inertia group of self, i.e. the set of elements s of the - Galois group of the number field of self (which we assume is Galois) - such that s acts trivially modulo self. This is the same as the 0th - ramification group of self. See the inertia_group method of the - ``GaloisGroup_v2`` class for further examples and doctests. + Return the inertia group of ``self``, i.e. the set of elements `s` of the + Galois group of the number field of ``self`` (which we assume is Galois) + such that `s` acts trivially modulo ``self``. This is the same as the 0th + ramification group of ``self``. See the + :meth:`GaloisGroup_v2.inertia_group` method further examples and doctests. EXAMPLES:: @@ -1512,23 +1521,23 @@ def random_element(self, *args, **kwds): EXAMPLES:: sage: K. = NumberField(x^3 + 2) - sage: I = K.ideal(1-a) + sage: I = K.ideal(1 - a) sage: I.random_element() # random output -a^2 - a - 19 sage: I.random_element(distribution="uniform") # random output a^2 - 2*a - 8 - sage: I.random_element(-30,30) # random output + sage: I.random_element(-30, 30) # random output -7*a^2 - 17*a - 75 sage: I.random_element(-100, 200).is_integral() True - sage: I.random_element(-30,30).parent() is K + sage: I.random_element(-30, 30).parent() is K True A relative example:: sage: K. = NumberField([x^2 + 2, x^2 + 1000*x + 1]) - sage: I = K.ideal(1-a) - sage: I.random_element() # random output + sage: I = K.ideal(1 - a) + sage: I.random_element() # random output 17/500002*a^3 + 737253/250001*a^2 - 1494505893/500002*a + 752473260/250001 sage: I.random_element().is_integral() True @@ -1543,14 +1552,14 @@ def random_element(self, *args, **kwds): def artin_symbol(self): r""" - Return the Artin symbol `( K / \QQ, P)`, where `K` is the - number field of `P` =self. This is the unique element `s` of + Return the Artin symbol `(K / \QQ, P)`, where `K` is the + number field of `P` = ``self``. This is the unique element `s` of the decomposition group of `P` such that `s(x) = x^p \pmod{P}` where `p` is the residue characteristic of `P`. (Here `P` - (self) should be prime and unramified.) + (``self``) should be prime and unramified.) - See the ``artin_symbol`` method of the ``GaloisGroup_v2`` - class for further documentation and examples. + See the :meth:`GaloisGroup_v2.artin_symbol` method + for further documentation and examples. EXAMPLES:: @@ -1561,23 +1570,26 @@ class for further documentation and examples. def residue_symbol(self, e, m, check=True): r""" - The m-th power residue symbol for an element e and the proper ideal. + The `m`-th power residue symbol for an element `e` and the proper ideal. .. MATH:: \left(\frac{\alpha}{\mathbf{P}}\right) \equiv \alpha^{\frac{N(\mathbf{P})-1}{m}} \operatorname{mod} \mathbf{P} - .. note:: accepts m=1, in which case returns 1 + .. note:: accepts `m=1`, in which case returns 1 .. note:: can also be called for an element from sage.rings.number_field_element.residue_symbol - .. note:: e is coerced into the number field of self + .. note:: `e` is coerced into the number field of ``self`` - .. note:: if m=2, e is an integer, and self.number_field() has absolute degree 1 (i.e. it is a copy of the rationals), then this calls kronecker_symbol, which is implemented using GMP. + .. note:: + + if `m=2`, `e` is an integer, and ``self.number_field()`` has absolute degree 1 (i.e. it is a copy of the rationals), + then this calls :func:`kronecker_symbol`, which is implemented using GMP. INPUT: - - ``e`` - element of the number field + - ``e`` -- element of the number field - - ``m`` - positive integer + - ``m`` -- positive integer OUTPUT: @@ -1594,13 +1606,13 @@ def residue_symbol(self, e, m, check=True): Cubic Residue:: sage: K. = NumberField(x^2 - x + 1) - sage: K.ideal(17).residue_symbol(w^2 + 3,3) + sage: K.ideal(17).residue_symbol(w^2 + 3, 3) -w - The field must contain the m-th roots of unity:: + The field must contain the `m`-th roots of unity:: sage: K. = NumberField(x^2 - x + 1) - sage: K.ideal(17).residue_symbol(w^2 + 3,5) + sage: K.ideal(17).residue_symbol(w^2 + 3, 5) Traceback (most recent call last): ... ValueError: The residue symbol to that power is not defined for the number field @@ -1735,7 +1747,7 @@ def basis_to_module(B, K): def is_NumberFieldIdeal(x): """ - Return True if x is an ideal of a number field. + Return ``True`` if `x` is an ideal of a number field. EXAMPLES:: @@ -1814,7 +1826,7 @@ def __repr__(self): EXAMPLES:: - sage: K.=NumberField(x^2+5) + sage: K. = NumberField(x^2 + 5) sage: I = K.ideal([2,1+a]); I Fractional ideal (2, a + 1) sage: type(I) @@ -1824,7 +1836,7 @@ def __repr__(self): def divides(self, other): """ - Returns True if this ideal divides other and False otherwise. + Return ``True`` if this ideal divides other and False otherwise. EXAMPLES:: @@ -1854,11 +1866,13 @@ def factor(self): sage: I = K.ideal(19); I Fractional ideal (19) sage: F = I.factor(); F - (Fractional ideal (19, 1/2*a^2 + a - 17/2)) * (Fractional ideal (19, 1/2*a^2 - a - 17/2)) + (Fractional ideal (19, 1/2*a^2 + a - 17/2)) + * (Fractional ideal (19, 1/2*a^2 - a - 17/2)) sage: type(F) sage: list(F) - [(Fractional ideal (19, 1/2*a^2 + a - 17/2), 1), (Fractional ideal (19, 1/2*a^2 - a - 17/2), 1)] + [(Fractional ideal (19, 1/2*a^2 + a - 17/2), 1), + (Fractional ideal (19, 1/2*a^2 - a - 17/2), 1)] sage: F.prod() Fractional ideal (19) @@ -1893,18 +1907,21 @@ def factor(self): def prime_factors(self): """ - Return a list of the prime ideal factors of self + Return a list of the prime ideal factors of ``self``. OUTPUT: - list -- list of prime ideals (a new list is returned - each time this function is called) + + list of prime ideals (a new list is returned + each time this function is called) EXAMPLES:: sage: K. = NumberField(x^2 + 23) sage: I = ideal(w+1) sage: I.prime_factors() - [Fractional ideal (2, 1/2*w - 1/2), Fractional ideal (2, 1/2*w + 1/2), Fractional ideal (3, 1/2*w + 1/2)] + [Fractional ideal (2, 1/2*w - 1/2), + Fractional ideal (2, 1/2*w + 1/2), + Fractional ideal (3, 1/2*w + 1/2)] """ return [x[0] for x in self.factor()] @@ -1912,7 +1929,7 @@ def prime_factors(self): def _div_(self, other): """ - Return the quotient self / other. + Return the quotient ``self`` / ``other``. EXAMPLES:: @@ -1932,7 +1949,7 @@ def _div_(self, other): def __invert__(self): """ - Return the multiplicative inverse of self. Call with ~self. + Return the multiplicative inverse of ``self``. Call with ``~self``. EXAMPLES:: @@ -1955,8 +1972,8 @@ def __invert__(self): def is_maximal(self): """ - Return True if this ideal is maximal. This is equivalent to - self being prime, since it is nonzero. + Return ``True`` if this ideal is maximal. This is equivalent to + ``self`` being prime, since it is nonzero. EXAMPLES:: @@ -1971,7 +1988,7 @@ def is_maximal(self): def is_trivial(self, proof=None): """ - Returns True if this is a trivial ideal. + Return ``True`` if this is a trivial ideal. EXAMPLES:: @@ -1990,7 +2007,7 @@ def is_trivial(self, proof=None): def ramification_index(self): r""" Return the ramification index of this fractional ideal, - assuming it is prime. Otherwise, raise a ValueError. + assuming it is prime. Otherwise, raise a :class:`ValueError`. The ramification index is the power of this prime appearing in the factorization of the prime in `\ZZ` that this prime lies @@ -2015,8 +2032,8 @@ def ramification_index(self): def reduce(self, f): r""" - Return the canonical reduction of the element of `f` modulo the ideal - `I` (=self). This is an element of `R` (the ring of integers of the + Return the canonical reduction of the element `f` modulo the ideal + `I` (= ``self``). This is an element of `R` (the ring of integers of the number field) that is equivalent modulo `I` to `f`. An error is raised if this fractional ideal is not integral or @@ -2024,22 +2041,23 @@ def reduce(self, f): INPUT: - - ``f`` - an integral element of the number field + - ``f`` -- an integral element of the number field OUTPUT: - An integral element `g`, such that `f - g` belongs to the ideal self + An integral element `g`, such that `f - g` belongs to the ideal ``self`` and such that `g` is a canonical reduced representative of the coset - `f + I` (`I` =self) as described in the ``residues`` function, namely an integral element with coordinates `(r_0, \dots,r_{n-1})`, where: + `f + I` (where `I` = ``self``) as described in the method :meth:`residues`, + namely an integral element with coordinates `(r_0, \dots,r_{n-1})`, where: - `r_i` is reduced modulo `d_i` - - `d_i = b_i[i]`, with `{b_0, b_1, \dots, b_n}` HNF basis - of the ideal self. + - `d_i = b_i[i]`, with `\{b_0, b_1, \dots, b_n\}` HNF basis + of the ideal ``self``. .. note:: The reduced element `g` is not necessarily small. To get a - small `g` use the method ``small_residue``. + small `g` use the method :meth:`small_residue`. EXAMPLES:: @@ -2060,7 +2078,7 @@ def reduce(self, f): True The reduced element does not necessarily have smaller norm (use - ``small_residue`` for that) + :meth:`small_residue` for that) :: @@ -2127,31 +2145,32 @@ def residues(self): - `r_i` is reduced modulo `d_i` - - `d_i = b_i[i]`, with `{b_0, b_1, \dots, b_n}` HNF basis + - `d_i = b_i[i]`, with `\{b_0, b_1, \dots, b_n\}` HNF basis of the ideal. AUTHOR: John Cremona (modified by Maite Aranes) EXAMPLES:: - sage: K.=NumberField(x^2+1) - sage: res = K.ideal(2).residues(); res + sage: K.=NumberField(x^2 + 1) + sage: res = K.ideal(2).residues(); res xmrange_iter([[0, 1], [0, 1]], at 0x...>) sage: list(res) [0, i, 1, i + 1] - sage: list(K.ideal(2+i).residues()) + sage: list(K.ideal(2 + i).residues()) [-2*i, -i, 0, i, 2*i] sage: list(K.ideal(i).residues()) [0] - sage: I = K.ideal(3+6*i) - sage: reps=I.residues() + sage: I = K.ideal(3 + 6*i) + sage: reps = I.residues() sage: len(list(reps)) == I.norm() True - sage: all(r == s or not (r-s) in I for r in reps for s in reps) # long time (6s on sage.math, 2011) + sage: all(r == s or not (r-s) in I # long time (6s on sage.math, 2011) + ....: for r in reps for s in reps) True - sage: K. = NumberField(x^3-10) - sage: I = K.ideal(a-1) + sage: K. = NumberField(x^3 - 10) + sage: I = K.ideal(a - 1) sage: len(list(I.residues())) == I.norm() True @@ -2176,45 +2195,45 @@ def residues(self): def invertible_residues(self, reduce=True): r""" - Returns a iterator through a list of invertible residues + Return an iterator through a list of invertible residues modulo this integral ideal. An error is raised if this fractional ideal is not integral. INPUT: - - ``reduce`` - bool. If True (default), use ``small_residue`` to get + - ``reduce`` -- bool. If ``True`` (default), use ``small_residue`` to get small representatives of the residues. OUTPUT: - - An iterator through a list of invertible residues modulo this ideal - `I`, i.e. a list of elements in the ring of integers `R` representing - the elements of `(R/I)^*`. + An iterator through a list of invertible residues modulo this ideal + `I`, i.e. a list of elements in the ring of integers `R` representing + the elements of `(R/I)^*`. ALGORITHM: Use :pari:`idealstar` to find the group structure and generators of the multiplicative group modulo the ideal. EXAMPLES:: - sage: K.=NumberField(x^2+1) - sage: ires = K.ideal(2).invertible_residues(); ires + sage: K. = NumberField(x^2 + 1) + sage: ires = K.ideal(2).invertible_residues(); ires xmrange_iter([[0, 1]], at 0x...>) sage: list(ires) [1, -i] - sage: list(K.ideal(2+i).invertible_residues()) + sage: list(K.ideal(2 + i).invertible_residues()) [1, 2, 4, 3] sage: list(K.ideal(i).residues()) [0] sage: list(K.ideal(i).invertible_residues()) [1] - sage: I = K.ideal(3+6*i) - sage: units=I.invertible_residues() - sage: len(list(units))==I.euler_phi() + sage: I = K.ideal(3 + 6*i) + sage: units = I.invertible_residues() + sage: len(list(units)) == I.euler_phi() True - sage: K. = NumberField(x^3-10) - sage: I = K.ideal(a-1) + sage: K. = NumberField(x^3 - 10) + sage: I = K.ideal(a - 1) sage: len(list(I.invertible_residues())) == I.euler_phi() True @@ -2236,38 +2255,38 @@ def invertible_residues(self, reduce=True): def invertible_residues_mod(self, subgp_gens=[], reduce=True): r""" - Returns a iterator through a list of representatives for the invertible + Return a iterator through a list of representatives for the invertible residues modulo this integral ideal, modulo the subgroup generated by the elements in the list ``subgp_gens``. INPUT: - - ``subgp_gens`` - either None or a list of elements of the number - field of self. These need not be integral, but should be coprime to - the ideal self. If the list is empty or None, the function returns + - ``subgp_gens`` -- either ``None`` or a list of elements of the number + field of ``self``. These need not be integral, but should be coprime to + the ideal ``self``. If the list is empty or ``None``, the function returns an iterator through a list of representatives for the invertible - residues modulo the integral ideal self. + residues modulo the integral ideal ``self``. - - ``reduce`` - bool. If True (default), use ``small_residues`` to + - ``reduce`` -- bool. If ``True`` (default), use ``small_residues`` to get small representatives of the residues. .. note:: - See also invertible_residues() for a simpler version without the subgroup. + See also :meth:`invertible_residues` for a simpler version without the subgroup. OUTPUT: - - An iterator through a list of representatives for the invertible - residues modulo self and modulo the group generated by - ``subgp_gens``, i.e. a list of elements in the ring of integers `R` - representing the elements of `(R/I)^*/U`, where `I` is this ideal and - `U` is the subgroup of `(R/I)^*` generated by ``subgp_gens``. + An iterator through a list of representatives for the invertible + residues modulo ``self`` and modulo the group generated by + ``subgp_gens``, i.e. a list of elements in the ring of integers `R` + representing the elements of `(R/I)^*/U`, where `I` is this ideal and + `U` is the subgroup of `(R/I)^*` generated by ``subgp_gens``. EXAMPLES: :: - sage: k. = NumberField(x^2 +23) + sage: k. = NumberField(x^2 + 23) sage: I = k.ideal(a) sage: list(I.invertible_residues_mod([-1])) [1, 5, 2, 10, 4, 20, 8, 17, 16, 11, 9] @@ -2280,8 +2299,8 @@ def invertible_residues_mod(self, subgp_gens=[], reduce=True): :: - sage: K. = NumberField(x^3-10) - sage: I = K.ideal(a-1) + sage: K. = NumberField(x^3 - 10) + sage: I = K.ideal(a - 1) sage: len(list(I.invertible_residues_mod([]))) == I.euler_phi() True @@ -2337,7 +2356,7 @@ def denominator(self): EXAMPLES:: - sage: K.=NumberField(x^2+1) + sage: K.=NumberField(x^2 + 1) sage: I = K.ideal((3+4*i)/5); I Fractional ideal (4/5*i + 3/5) sage: I.denominator() @@ -2367,7 +2386,7 @@ def numerator(self): EXAMPLES:: - sage: K.=NumberField(x^2+1) + sage: K.=NumberField(x^2 + 1) sage: I = K.ideal((3+4*i)/5); I Fractional ideal (4/5*i + 3/5) sage: I.denominator() @@ -2390,7 +2409,7 @@ def numerator(self): def is_coprime(self, other): """ - Returns True if this ideal is coprime to the other, else False. + Return ``True`` if this ideal is coprime to ``other``, else ``False``. INPUT: @@ -2399,7 +2418,7 @@ def is_coprime(self, other): OUTPUT: - True if self and other are coprime, else False. + ``True`` if ``self`` and ``other`` are coprime, else ``False``. .. note:: @@ -2410,16 +2429,16 @@ def is_coprime(self, other): EXAMPLES:: - sage: K.=NumberField(x^2+1) - sage: I = K.ideal(2+i) - sage: J = K.ideal(2-i) + sage: K. = NumberField(x^2 + 1) + sage: I = K.ideal(2 + i) + sage: J = K.ideal(2 - i) sage: I.is_coprime(J) True sage: (I^-1).is_coprime(J^3) True sage: I.is_coprime(5) False - sage: I.is_coprime(6+i) + sage: I.is_coprime(6 + i) True See :trac:`4536`:: @@ -2457,22 +2476,24 @@ def is_coprime(self, other): def idealcoprime(self, J): """ - Returns l such that l*self is coprime to J. + Return `l` such that ``l*self`` is coprime to `J`. INPUT: - - ``J`` - another integral ideal of the same field as self, which must also be integral. + - ``J`` -- another integral ideal of the same field as ``self``, which must also be integral. OUTPUT: - - ``l`` - an element such that l*self is coprime to the ideal J + an element `l` such that ``l*self`` is coprime to the ideal `J` - TODO: Extend the implementation to non-integral ideals. + .. TODO:: + + Extend the implementation to non-integral ideals. EXAMPLES:: sage: k. = NumberField(x^2 + 23) - sage: A = k.ideal(a+1) + sage: A = k.ideal(a + 1) sage: B = k.ideal(3) sage: A.is_coprime(B) False @@ -2490,7 +2511,7 @@ def idealcoprime(self, J): depends on the PARI version:: sage: k. = NumberField(x^2 + 23) - sage: A = k.ideal(a+1) + sage: A = k.ideal(a + 1) sage: B = k.ideal(3) sage: lam = A.idealcoprime(B) sage: lam in (-1/6*a + 1/6, 1/6*a - 1/6) @@ -2507,15 +2528,15 @@ def idealcoprime(self, J): def small_residue(self, f): r""" - Given an element `f` of the ambient number field, returns an - element `g` such that `f - g` belongs to the ideal self (which + Given an element `f` of the ambient number field, return an + element `g` such that `f - g` belongs to the ideal ``self`` (which must be integral), and `g` is small. .. note:: The reduced representative returned is not uniquely determined. - ALGORITHM: Uses Pari function :pari:`nfeltreduce`. + ALGORITHM: Uses PARI function :pari:`nfeltreduce`. EXAMPLES: @@ -2541,13 +2562,13 @@ def small_residue(self, f): def _pari_bid_(self, flag=1): """ - Returns the pari structure ``bid`` associated to the ideal self. + Return the PARI structure ``bid`` associated to the ideal ``self``. INPUT: - - ``flag`` - when flag=2 it computes the generators of the group - `(O_K/I)^*`, which takes more time. By default - flag=1 (no generators are computed). + - ``flag`` -- when ``flag=2`` it computes the generators of the group + `(O_K/I)^*`, which takes more time. By default + ``flag=1`` (no generators are computed). OUTPUT: @@ -2579,15 +2600,15 @@ def _pari_bid_(self, flag=1): def idealstar(self, flag=1): r""" - Returns the finite abelian group `(O_K/I)^*`, where I is the ideal self - of the number field K, and `O_K` is the ring of integers of K. + Return the finite abelian group `(O_K/I)^*`, where `I` is the ideal ``self`` + of the number field `K`, and `O_K` is the ring of integers of `K`. INPUT: - ``flag`` (int default 1) -- when ``flag`` =2, it also computes the generators of the group `(O_K/I)^*`, which takes more time. By default ``flag`` =1 (no generators are - computed). In both cases the special pari structure ``bid`` + computed). In both cases the special PARI structure ``bid`` is computed as well. If ``flag`` =0 (deprecated) it computes only the group structure of `(O_K/I)^*` (with generators) and not the special ``bid`` structure. @@ -2598,10 +2619,10 @@ def idealstar(self, flag=1): .. note:: - Uses the pari function :pari:`idealstar`. The pari function outputs + Uses the PARI function :pari:`idealstar`. The PARI function outputs a special ``bid`` structure which is stored in the internal - field ``_bid`` of the ideal (when flag=1,2). The special structure - ``bid`` is used in the pari function :pari:`ideallog` + field ``_bid`` of the ideal (when ``flag`` = 1,2). The special structure + ``bid`` is used in the PARI function :pari:`ideallog` to compute discrete logarithms. EXAMPLES:: @@ -2647,32 +2668,32 @@ def idealstar(self, flag=1): def ideallog(self, x, gens=None, check=True): r""" - Returns the discrete logarithm of x with respect to the generators - given in the ``bid`` structure of the ideal self, or with respect to + Return the discrete logarithm of `x` with respect to the generators + given in the ``bid`` structure of the ideal ``self``, or with respect to the generators ``gens`` if these are given. INPUT: - - ``x`` - a non-zero element of the number field of self, + - ``x`` -- a non-zero element of the number field of ``self``, which must have valuation equal to 0 at all prime ideals in - the support of the ideal self. - - ``gens`` - a list of elements of the number field which generate `(R + the support of the ideal ``self``. + - ``gens`` -- a list of elements of the number field which generate `(R / I)^*`, where `R` is the ring of integers of the field and `I` is this ideal, or ``None``. If ``None``, use the generators calculated by :meth:`~idealstar`. - - ``check`` - if True, do a consistency check on the results. Ignored - if ``gens`` is None. + - ``check`` -- if ``True``, do a consistency check on the results. Ignored + if ``gens`` is ``None``. OUTPUT: - - ``l`` - a list of non-negative integers `(x_i)` such that `x = - \prod_i g_i^{x_i}` in `(R/I)^*`, where `x_i` are the generators, and - the list `(x_i)` is lexicographically minimal with respect to this - requirement. If the `x_i` generate independent cyclic factors of - order `d_i`, as is the case for the default generators calculated by - :meth:`~idealstar`, this just means that `0 \le x_i < d_i`. + a list of non-negative integers `(x_i)` such that `x = + \prod_i g_i^{x_i}` in `(R/I)^*`, where `x_i` are the generators, and + the list `(x_i)` is lexicographically minimal with respect to this + requirement. If the `x_i` generate independent cyclic factors of + order `d_i`, as is the case for the default generators calculated by + :meth:`~idealstar`, this just means that `0 \le x_i < d_i`. - A ``ValueError`` will be raised if the elements specified in ``gens`` + A :class:`ValueError` will be raised if the elements specified in ``gens`` do not in fact generate the unit group (even if the element `x` is in the subgroup they generate). @@ -2681,7 +2702,7 @@ def ideallog(self, x, gens=None, check=True): sage: k. = NumberField(x^3 - 11) sage: A = k.ideal(5) sage: G = A.idealstar(2) - sage: l = A.ideallog(a^2 +3) + sage: l = A.ideallog(a^2 + 3) sage: r = G(l).value() sage: (a^2 + 3) - r in A True @@ -2692,16 +2713,16 @@ def ideallog(self, x, gens=None, check=True): sage: K. = NumberField(x^2 - 7) sage: I = K.ideal(17) - sage: I.ideallog(a + 7, [1+a, 2]) + sage: I.ideallog(a + 7, [1 + a, 2]) [10, 3] - sage: I.ideallog(a + 7, [2, 1+a]) + sage: I.ideallog(a + 7, [2, 1 + a]) [0, 118] sage: L. = NumberField(x^4 - x^3 - 7*x^2 + 3*x + 2) sage: J = L.ideal(-b^3 - b^2 - 2) sage: u = -14*b^3 + 21*b^2 + b - 1 sage: v = 4*b^2 + 2*b - 1 - sage: J.ideallog(5+2*b, [u, v], check=True) + sage: J.ideallog(5 + 2*b, [u, v], check=True) [4, 13] A non-example:: @@ -2709,10 +2730,11 @@ def ideallog(self, x, gens=None, check=True): sage: I.ideallog(a + 7, [2]) Traceback (most recent call last): ... - ValueError: Given elements do not generate unit group -- they generate a subgroup of index 36 + ValueError: Given elements do not generate unit group -- + they generate a subgroup of index 36 - ALGORITHM: Uses Pari function :pari:`ideallog`, and (if ``gens`` is not - None) a Hermite normal form calculation to express the result in terms + ALGORITHM: Uses PARI function :pari:`ideallog`, and (if ``gens`` is not + ``None``) a Hermite normal form calculation to express the result in terms of the generators ``gens``. """ # sanitise input @@ -2770,7 +2792,7 @@ def ideallog(self, x, gens=None, check=True): def element_1_mod(self, other): r""" - Returns an element `r` in this ideal such that `1-r` is in other + Return an element `r` in this ideal such that `1-r` is in ``other`` An error is raised if either ideal is not integral of if they are not coprime. @@ -2782,29 +2804,29 @@ def element_1_mod(self, other): OUTPUT: - An element `r` of the ideal self such that `1-r` is in the ideal other + An element `r` of the ideal self such that `1-r` is in the ideal ``other`` AUTHOR: Maite Aranes (modified to use PARI's :pari:`idealaddtoone` by Francis Clarke) EXAMPLES:: - sage: K. = NumberField(x^3-2) - sage: A = K.ideal(a+1); A; A.norm() + sage: K. = NumberField(x^3 - 2) + sage: A = K.ideal(a + 1); A; A.norm() Fractional ideal (a + 1) 3 - sage: B = K.ideal(a^2-4*a+2); B; B.norm() + sage: B = K.ideal(a^2 - 4*a + 2); B; B.norm() Fractional ideal (a^2 - 4*a + 2) 68 sage: r = A.element_1_mod(B); r -33 sage: r in A True - sage: 1-r in B + sage: 1 - r in B True TESTS:: - sage: K. = NumberField(x^3-2) + sage: K. = NumberField(x^3 - 2) sage: A = K.ideal(a+1) sage: B = K.ideal(a^2-4*a+1); B; B.norm() Fractional ideal (a^2 - 4*a + 1) @@ -2839,7 +2861,7 @@ def element_1_mod(self, other): def euler_phi(self): r""" - Returns the Euler `\varphi`-function of this integral ideal. + Return the Euler `\varphi`-function of this integral ideal. This is the order of the multiplicative group of the quotient modulo the ideal. @@ -2848,8 +2870,8 @@ def euler_phi(self): EXAMPLES:: - sage: K.=NumberField(x^2+1) - sage: I = K.ideal(2+i) + sage: K. = NumberField(x^2 + 1) + sage: I = K.ideal(2 + i) sage: [r for r in I.residues() if I.is_coprime(r)] [-2*i, -i, i, 2*i] sage: I.euler_phi() @@ -2859,7 +2881,7 @@ def euler_phi(self): 100 sage: len([r for r in J.residues() if J.is_coprime(r)]) 100 - sage: J = K.ideal(3-2*i) + sage: J = K.ideal(3 - 2*i) sage: I.is_coprime(J) True sage: I.euler_phi()*J.euler_phi() == (I*J).euler_phi() @@ -2876,7 +2898,7 @@ def euler_phi(self): def prime_to_S_part(self, S): r""" Return the part of this fractional ideal which is coprime to - the prime ideals in the list ``S``. + the prime ideals in the list `S`. .. NOTE:: @@ -2886,7 +2908,7 @@ def prime_to_S_part(self, S): INPUT: - - `S` -- a list of prime ideals + - ``S`` -- a list of prime ideals OUTPUT: @@ -2896,18 +2918,20 @@ def prime_to_S_part(self, S): EXAMPLES:: - sage: K. = NumberField(x^2-23) + sage: K. = NumberField(x^2 - 23) sage: I = K.ideal(24) - sage: S = [K.ideal(-a+5),K.ideal(5)] + sage: S = [K.ideal(-a + 5), K.ideal(5)] sage: I.prime_to_S_part(S) Fractional ideal (3) sage: J = K.ideal(15) sage: J.prime_to_S_part(S) Fractional ideal (3) - sage: K. = NumberField(x^5-23) + sage: K. = NumberField(x^5 - 23) sage: I = K.ideal(24) - sage: S = [K.ideal(15161*a^4 + 28383*a^3 + 53135*a^2 + 99478*a + 186250),K.ideal(2*a^4 + 3*a^3 + 4*a^2 + 15*a + 11), K.ideal(101)] + sage: S = [K.ideal(15161*a^4 + 28383*a^3 + 53135*a^2 + 99478*a + 186250), + ....: K.ideal(2*a^4 + 3*a^3 + 4*a^2 + 15*a + 11), + ....: K.ideal(101)] sage: I.prime_to_S_part(S) Fractional ideal (24) """ @@ -2919,11 +2943,11 @@ def prime_to_S_part(self, S): def is_S_unit(self, S): r""" - Return True if this fractional ideal is a unit with respect to the list of primes ``S``. + Return ``True`` if this fractional ideal is a unit with respect to the list of primes `S`. INPUT: - - `S` - a list of prime ideals (not checked if they are + - ``S`` -- a list of prime ideals (not checked if they are indeed prime). .. note:: @@ -2934,8 +2958,8 @@ def is_S_unit(self, S): OUTPUT: - True, if the ideal is an `S`-unit: that is, if the valuations of - the ideal at all primes not in `S` are zero. False, otherwise. + ``True``, if the ideal is an `S`-unit: that is, if the valuations of + the ideal at all primes not in `S` are zero. ``False``, otherwise. EXAMPLES:: @@ -2949,11 +2973,11 @@ def is_S_unit(self, S): def is_S_integral(self, S): r""" - Return True if this fractional ideal is integral with respect to the list of primes ``S``. + Return ``True`` if this fractional ideal is integral with respect to the list of primes `S`. INPUT: - - `S` - a list of prime ideals (not checked if they are indeed + - `S` -- a list of prime ideals (not checked if they are indeed prime). .. note:: @@ -2964,8 +2988,8 @@ def is_S_integral(self, S): OUTPUT: - True, if the ideal is `S`-integral: that is, if the valuations - of the ideal at all primes not in `S` are non-negative. False, + ``True``, if the ideal is `S`-integral: that is, if the valuations + of the ideal at all primes not in `S` are non-negative. ``False``, otherwise. EXAMPLES:: @@ -2987,7 +3011,7 @@ def is_S_integral(self, S): def prime_to_idealM_part(self, M): r""" Version for integral ideals of the ``prime_to_m_part`` function over `\ZZ`. - Returns the largest divisor of self that is coprime to the ideal ``M``. + Return the largest divisor of ``self`` that is coprime to the ideal `M`. INPUT: @@ -2995,14 +3019,14 @@ def prime_to_idealM_part(self, M): OUTPUT: - An ideal which is the largest divisor of self that is coprime to `M`. + An ideal which is the largest divisor of ``self`` that is coprime to `M`. AUTHOR: Maite Aranes EXAMPLES:: sage: k. = NumberField(x^2 + 23) - sage: I = k.ideal(a+1) + sage: I = k.ideal(a + 1) sage: M = k.ideal(2, 1/2*a - 1/2) sage: J = I.prime_to_idealM_part(M); J Fractional ideal (12, 1/2*a + 13/2) @@ -3041,9 +3065,9 @@ def _p_quotient(self, p): OUTPUT: - - ``V`` -- a vector space of characteristic ``p`` + - `V` -- a vector space of characteristic `p` - ``quo`` -- a partially defined quotient homomorphism from the - ambient number field to ``V`` + ambient number field to `V` - ``lift`` -- a section of ``quo``. EXAMPLES:: @@ -3062,7 +3086,7 @@ def _p_quotient(self, p): sage: K. = NumberField(x^2 + 1); O = K.maximal_order() sage: I = K.factor(5)[0][0] - sage: Q,quo,lift = I._p_quotient(5) + sage: Q, quo, lift = I._p_quotient(5) sage: lift(quo(i)) 3 sage: lift(quo(i)) - i in I @@ -3078,9 +3102,14 @@ def _p_quotient(self, p): Basis matrix: [1 3] sage: quo - Partially defined quotient map from Number Field in i with defining polynomial x^2 + 1 to an explicit vector space representation for the quotient of the ring of integers by (p,I) for the ideal I=Fractional ideal (-i - 2). + Partially defined quotient map + from Number Field in i with defining polynomial x^2 + 1 + to an explicit vector space representation for the quotient of + the ring of integers by (p,I) for the ideal I=Fractional ideal (-i - 2). sage: lift - Lifting map to Gaussian Integers in Number Field in i with defining polynomial x^2 + 1 from quotient of integers by Fractional ideal (-i - 2) + Lifting map + to Gaussian Integers in Number Field in i with defining polynomial x^2 + 1 + from quotient of integers by Fractional ideal (-i - 2) """ return quotient_char_p(self, p) @@ -3091,7 +3120,7 @@ def residue_field(self, names=None): EXAMPLES:: - sage: K. = NumberField(x^3-7) + sage: K. = NumberField(x^3 - 7) sage: P = K.ideal(29).factor()[0][0] sage: P.residue_field() Residue field in abar of Fractional ideal (2*a^2 + 3*a - 10) @@ -3100,7 +3129,7 @@ def residue_field(self, names=None): Another example:: - sage: K. = NumberField(x^3-7) + sage: K. = NumberField(x^3 - 7) sage: P = K.ideal(389).factor()[0][0]; P Fractional ideal (389, a^2 - 44*a - 9) sage: P.residue_class_degree() @@ -3124,11 +3153,12 @@ def residue_field(self, names=None): has been fixed:: sage: K. = NumberField(x^2 + 1) - sage: P1, P2 = [g[0] for g in K.factor(5)]; (P1,P2) + sage: P1, P2 = [g[0] for g in K.factor(5)]; P1, P2 (Fractional ideal (-i - 2), Fractional ideal (2*i + 1)) sage: a = 1/(1+2*i) - sage: F1, F2 = [g.residue_field() for g in [P1,P2]]; (F1,F2) - (Residue field of Fractional ideal (-i - 2), Residue field of Fractional ideal (2*i + 1)) + sage: F1, F2 = [g.residue_field() for g in [P1, P2]]; F1, F2 + (Residue field of Fractional ideal (-i - 2), + Residue field of Fractional ideal (2*i + 1)) sage: a.valuation(P1) 0 sage: F1(i/7) @@ -3140,7 +3170,8 @@ def residue_field(self, names=None): sage: F2(a) Traceback (most recent call last): ... - ZeroDivisionError: Cannot reduce field element -2/5*i + 1/5 modulo Fractional ideal (2*i + 1): it has negative valuation + ZeroDivisionError: Cannot reduce field element -2/5*i + 1/5 + modulo Fractional ideal (2*i + 1): it has negative valuation An example with a relative number field:: @@ -3170,7 +3201,7 @@ def residue_field(self, names=None): def residue_class_degree(self): r""" Return the residue class degree of this fractional ideal, - assuming it is prime. Otherwise, raise a ValueError. + assuming it is prime. Otherwise, raise a :class:`ValueError`. The residue class degree of a prime ideal `I` is the degree of the extension `O_K/I` of its prime subfield. @@ -3180,7 +3211,9 @@ def residue_class_degree(self): sage: K. = NumberField(x^5 + 2); K Number Field in a with defining polynomial x^5 + 2 sage: f = K.factor(19); f - (Fractional ideal (a^2 + a - 3)) * (Fractional ideal (2*a^4 + a^2 - 2*a + 1)) * (Fractional ideal (a^2 + a - 1)) + (Fractional ideal (a^2 + a - 3)) + * (Fractional ideal (2*a^4 + a^2 - 2*a + 1)) + * (Fractional ideal (a^2 + a - 1)) sage: [i.residue_class_degree() for i, _ in f] [2, 2, 1] """ @@ -3189,7 +3222,7 @@ def residue_class_degree(self): def ray_class_number(self): r""" Return the order of the ray class group modulo this ideal. This is a - wrapper around Pari's :pari:`bnrclassno` function. + wrapper around PARI's :pari:`bnrclassno` function. EXAMPLES:: @@ -3210,7 +3243,7 @@ def ray_class_number(self): def is_NumberFieldFractionalIdeal(x): """ - Return True if x is a fractional ideal of a number field. + Return ``True`` if `x` is a fractional ideal of a number field. EXAMPLES:: diff --git a/src/sage/rings/number_field/number_field_ideal_rel.py b/src/sage/rings/number_field/number_field_ideal_rel.py index 1292219f843..c465ecf438a 100644 --- a/src/sage/rings/number_field/number_field_ideal_rel.py +++ b/src/sage/rings/number_field/number_field_ideal_rel.py @@ -93,7 +93,7 @@ def _richcmp_(self, other, op): def _contains_(self, x): """ - Return True if x is an element of this ideal. + Return ``True`` if `x` is an element of this ideal. This function is called (indirectly) when the ``in`` operator is used. @@ -154,10 +154,10 @@ def absolute_ideal(self, names = 'a'): Fractional ideal (13) Now a non-trivial ideal in `L` that is principal in the - subfield `K`. Since the optional 'names' argument is not - passed, the generators of the absolute ideal J are returned - in terms of the default field generator 'a'. This does not agree - with the generator 'm' of the absolute field F defined above:: + subfield `K`. Since the optional ``names`` argument is not + passed, the generators of the absolute ideal `J` are returned + in terms of the default field generator `a`. This does not agree + with the generator `m` of the absolute field `F` defined above:: sage: J = L.ideal(b); J Fractional ideal (b) @@ -170,7 +170,7 @@ def absolute_ideal(self, names = 'a'): sage: J.absolute_ideal().norm() 4 - Now pass 'm' as the name for the generator of the absolute field:: + Now pass `m` as the name for the generator of the absolute field:: sage: J.absolute_ideal('m') Fractional ideal (m^2) @@ -202,7 +202,7 @@ def absolute_ideal(self, names = 'a'): def _from_absolute_ideal(self, id): r""" - Convert the absolute ideal id to a relative number field ideal. + Convert the absolute ideal ``id`` to a relative number field ideal. WARNING: This is an internal helper function. @@ -291,7 +291,7 @@ def gens_reduced(self): def __invert__(self): """ - Return the multiplicative inverse of self. Call with ~self. + Return the multiplicative inverse of ``self``. Call with ``~self``. EXAMPLES:: @@ -308,8 +308,8 @@ def __invert__(self): def is_principal(self, proof=None): """ - Return True if this ideal is principal. If so, set - self.__reduced_generators, with length one. + Return ``True`` if this ideal is principal. If so, set + ``self.__reduced_generators``, with length one. EXAMPLES:: @@ -334,7 +334,7 @@ def is_principal(self, proof=None): def is_zero(self): r""" - Return True if this is the zero ideal. + Return ``True`` if this is the zero ideal. EXAMPLES:: @@ -371,7 +371,7 @@ def relative_norm(self): EXAMPLES:: sage: R. = QQ[] - sage: K. = NumberField(x^2+6) + sage: K. = NumberField(x^2 + 6) sage: L. = K.extension(K['x'].gen()^4 + a) sage: N = L.ideal(b).relative_norm(); N Fractional ideal (-a) @@ -420,7 +420,8 @@ def norm(self): sage: K.ideal(2).norm() Traceback (most recent call last): ... - NotImplementedError: For a fractional ideal in a relative number field you must use relative_norm or absolute_norm as appropriate + NotImplementedError: For a fractional ideal in a relative number field + you must use relative_norm or absolute_norm as appropriate """ raise NotImplementedError("For a fractional ideal in a relative number field you must use relative_norm or absolute_norm as appropriate") @@ -431,12 +432,12 @@ def ideal_below(self): EXAMPLES:: sage: R. = QQ[] - sage: K. = NumberField(x^2+6) + sage: K. = NumberField(x^2 + 6) sage: L. = K.extension(K['x'].gen()^4 + a) sage: N = L.ideal(b) sage: M = N.ideal_below(); M == K.ideal([-a]) True - sage: Np = L.ideal( [ L(t) for t in M.gens() ]) + sage: Np = L.ideal([L(t) for t in M.gens()]) sage: Np.ideal_below() == M True sage: M.parent() @@ -496,7 +497,7 @@ def ideal_below(self): sage: K0.ideal([-a0 + 1]) == K0.ideal([-a0 + 5]) False - It works when the base_field is itself a relative number field:: + It works when the base field is itself a relative number field:: sage: PQ. = QQ[] sage: F. = NumberFieldTower([X^2 - 2, X^2 - 3]) @@ -534,9 +535,11 @@ def factor(self): sage: K. = QQ.extension([x^2 + 11, x^2 - 5]) sage: K.factor(5) - (Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 3/4))^2 * (Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 7/4))^2 + (Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 3/4))^2 + * (Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 7/4))^2 sage: K.ideal(5).factor() - (Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 3/4))^2 * (Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 7/4))^2 + (Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 3/4))^2 + * (Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 7/4))^2 sage: K.ideal(5).prime_factors() [Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 3/4), Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 7/4)] @@ -564,13 +567,13 @@ def factor(self): def integral_basis(self): r""" - Return a basis for self as a `\ZZ`-module. + Return a basis for ``self`` as a `\ZZ`-module. EXAMPLES:: sage: K. = NumberField([x^2 + 1, x^2 - 3]) sage: I = K.ideal(17*b - 3*a) - sage: x = I.integral_basis(); x # random + sage: x = I.integral_basis(); x # random [438, -b*a + 309, 219*a - 219*b, 156*a - 154*b] The exact results are somewhat unpredictable, hence the ``# random`` @@ -624,7 +627,7 @@ def is_prime(self): def is_integral(self): """ - Return True if this ideal is integral. + Return ``True`` if this ideal is integral. EXAMPLES:: @@ -640,15 +643,15 @@ def is_integral(self): def absolute_ramification_index(self): """ Return the absolute ramification index of this fractional ideal, - assuming it is prime. Otherwise, raise a ValueError. + assuming it is prime. Otherwise, raise a :class:`ValueError`. The absolute ramification index is the power of this prime appearing in the factorization of the rational prime that this prime lies over. - Use relative_ramification_index to obtain the power of this + Use :meth:`relative_ramification_index` to obtain the power of this prime occurring in the factorization of the prime ideal - of the base field that this prime lies over. + of the base field that this prime lies over. EXAMPLES:: @@ -671,13 +674,13 @@ def absolute_ramification_index(self): def relative_ramification_index(self): """ Return the relative ramification index of this fractional ideal, - assuming it is prime. Otherwise, raise a ValueError. + assuming it is prime. Otherwise, raise a :class:`ValueError`. The relative ramification index is the power of this prime appearing in the factorization of the prime ideal of the base field that this prime lies over. - Use absolute_ramification_index to obtain the power of this + Use :meth:`absolute_ramification_index` to obtain the power of this prime occurring in the factorization of the rational prime that this prime lies over. @@ -705,7 +708,7 @@ def relative_ramification_index(self): def ramification_index(self): r""" - For ideals in relative number fields, ``ramification_index`` + For ideals in relative number fields, :meth:`ramification_index` is deliberately not implemented in order to avoid ambiguity. Either :meth:`~relative_ramification_index` or :meth:`~absolute_ramification_index` should be used instead. @@ -762,7 +765,7 @@ def residues(self): def element_1_mod(self, other): r""" - Returns an element `r` in this ideal such that `1-r` is in other. + Returns an element `r` in this ideal such that `1-r` is in ``other``. An error is raised if either ideal is not integral of if they are not coprime. @@ -774,7 +777,7 @@ def element_1_mod(self, other): OUTPUT: an element `r` of the ideal self such that `1-r` is in the - ideal other. + ideal ``other``. EXAMPLES:: @@ -820,7 +823,7 @@ def smallest_integer(self): def valuation(self, p): r""" - Return the valuation of this fractional ideal at ``p``. + Return the valuation of this fractional ideal at `\mathfrak{p}`. INPUT: @@ -830,7 +833,7 @@ def valuation(self, p): (integer) The valuation of this fractional ideal at the prime `\mathfrak{p}`. If `\mathfrak{p}` is not prime, raise a - ValueError. + :class:`ValueError`. EXAMPLES:: @@ -858,7 +861,7 @@ def valuation(self, p): def is_NumberFieldFractionalIdeal_rel(x): """ - Return True if x is a fractional ideal of a relative number field. + Return ``True`` if `x` is a fractional ideal of a relative number field. EXAMPLES:: @@ -874,7 +877,7 @@ def is_NumberFieldFractionalIdeal_rel(x): sage: is_NumberFieldFractionalIdeal_rel(I) False sage: R. = QQ[] - sage: K. = NumberField(x^2+6) + sage: K. = NumberField(x^2 + 6) sage: L. = K.extension(K['x'].gen()^4 + a) sage: I = L.ideal(b); I Fractional ideal (6, b) diff --git a/src/sage/rings/number_field/number_field_morphisms.pyx b/src/sage/rings/number_field/number_field_morphisms.pyx index 34a51a97c62..3a732cd9b39 100644 --- a/src/sage/rings/number_field/number_field_morphisms.pyx +++ b/src/sage/rings/number_field/number_field_morphisms.pyx @@ -150,7 +150,7 @@ cdef class NumberFieldEmbedding(Morphism): def gen_image(self): """ - Returns the image of the generator under this embedding. + Return the image of the generator under this embedding. EXAMPLES:: @@ -177,15 +177,15 @@ cdef class EmbeddedNumberFieldMorphism(NumberFieldEmbedding): EXAMPLES:: - sage: K. = NumberField(x^2+1,embedding=QQbar(I)) - sage: L. = NumberField(x^2+1,embedding=-QQbar(I)) + sage: K. = NumberField(x^2 + 1, embedding=QQbar(I)) + sage: L. = NumberField(x^2 + 1, embedding=-QQbar(I)) sage: from sage.rings.number_field.number_field_morphisms import EmbeddedNumberFieldMorphism - sage: EmbeddedNumberFieldMorphism(K,L,CDF) + sage: EmbeddedNumberFieldMorphism(K, L, CDF) Generic morphism: From: Number Field in i with defining polynomial x^2 + 1 with i = I To: Number Field in i with defining polynomial x^2 + 1 with i = -I Defn: i -> -i - sage: EmbeddedNumberFieldMorphism(K,L,QQbar) + sage: EmbeddedNumberFieldMorphism(K, L, QQbar) Generic morphism: From: Number Field in i with defining polynomial x^2 + 1 with i = I To: Number Field in i with defining polynomial x^2 + 1 with i = -I @@ -225,7 +225,9 @@ cdef class EmbeddedNumberFieldMorphism(NumberFieldEmbedding): sage: F1.gen() + F2.gen() Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for +: 'Number Field in a with defining polynomial x^3 + 2 with a = -1.259921049894873?' and 'Number Field in a with defining polynomial x^3 + 2 with a = 0.6299605249474365? + 1.091123635971722?*I' + TypeError: unsupported operand parent(s) for +: + 'Number Field in a with defining polynomial x^3 + 2 with a = -1.259921049894873?' and + 'Number Field in a with defining polynomial x^3 + 2 with a = 0.6299605249474365? + 1.091123635971722?*I' The following was fixed to raise a ``TypeError`` in :trac:`15331`:: @@ -272,13 +274,13 @@ cdef class EmbeddedNumberFieldMorphism(NumberFieldEmbedding): EXAMPLES:: sage: from sage.rings.number_field.number_field_morphisms import EmbeddedNumberFieldMorphism - sage: K. = NumberField(x^2-700, embedding=25) - sage: L. = NumberField(x^6-700, embedding=3) + sage: K. = NumberField(x^2 - 700, embedding=25) + sage: L. = NumberField(x^6 - 700, embedding=3) sage: f = EmbeddedNumberFieldMorphism(K, L) - sage: f(2*a-1) + sage: f(2*a - 1) 2*b^3 - 1 sage: g = f.section() - sage: g(2*b^3-1) + sage: g(2*b^3 - 1) 2*a - 1 """ return EmbeddedNumberFieldConversion(self.codomain(), self.domain(), self.ambient_field) @@ -340,12 +342,12 @@ cdef class EmbeddedNumberFieldConversion(Map): cpdef matching_root(poly, target, ambient_field=None, margin=1, max_prec=None): """ - Given a polynomial and a target, this function chooses the root that - target best approximates as compared in ambient_field. + Given a polynomial and a ``target``, choose the root that + ``target`` best approximates as compared in ``ambient_field``. - If the parent of target is exact, the equality is required, otherwise + If the parent of ``target`` is exact, the equality is required, otherwise find closest root (with respect to the ``abs`` function) in the - ambient field to the target, and return the root of poly (if any) that + ambient field to the ``target``, and return the root of ``poly`` (if any) that approximates it best. EXAMPLES:: @@ -403,11 +405,11 @@ cpdef matching_root(poly, target, ambient_field=None, margin=1, max_prec=None): cpdef closest(target, values, margin=1): """ - This is a utility function that returns the item in values closest to - target (with respect to the ``abs`` function). If margin is greater - than 1, and x and y are the first and second closest elements to target, - then only return x if x is margin times closer to target than y, i.e. - margin * abs(target-x) < abs(target-y). + This is a utility function that returns the item in ``values`` closest to + target (with respect to the ``abs`` function). If ``margin`` is greater + than 1, and `x` and `y` are the first and second closest elements to ``target``, + then only return `x` if `x` is ``margin`` times closer to ``target`` than `y`, i.e. + ``margin * abs(target-x) < abs(target-y)``. TESTS:: @@ -492,10 +494,13 @@ def root_from_approx(f, a): return LazyAlgebraic(CLF, f, a, prec=0) # p-adic lazy, when implemented, would go here else: - from sage.symbolic.relation import test_relation_maxima rel = (f(a) != 0) - if (rel is True - or (not isinstance(rel, bool) and test_relation_maxima(rel))): + if rel is False: + return a + if rel is True: + raise ValueError("{} is not a root of {}".format(a, f)) + from sage.symbolic.relation import test_relation_maxima + if test_relation_maxima(rel): raise ValueError("{} is not a root of {}".format(a, f)) return a @@ -560,7 +565,7 @@ cdef class CyclotomicFieldEmbedding(NumberFieldEmbedding): """ Specialized class for converting cyclotomic field elements into a cyclotomic field of higher order. All the real work is done by - _lift_cyclotomic_element. + :meth:`_lift_cyclotomic_element`. """ cdef ratio diff --git a/src/sage/rings/number_field/number_field_rel.py b/src/sage/rings/number_field/number_field_rel.py index 88284bf8ed0..7405a08b4bb 100644 --- a/src/sage/rings/number_field/number_field_rel.py +++ b/src/sage/rings/number_field/number_field_rel.py @@ -157,7 +157,7 @@ class NumberField_relative(NumberField_generic): sage: K. = NumberField(x^3 - 2) sage: t = polygen(K) - sage: L. = K.extension(t^2+t+a); L + sage: L. = K.extension(t^2 + t + a); L Number Field in b with defining polynomial x^2 + x + a over its base field TESTS:: @@ -324,17 +324,17 @@ def __init__(self, base, polynomial, name, def change_names(self, names): r""" - Return relative number field isomorphic to self but with the + Return relative number field isomorphic to ``self`` but with the given generator names. INPUT: - ``names`` -- number of names should be at most the number of - generators of self, i.e., the number of steps in the tower + generators of ``self``, i.e., the number of steps in the tower of relative fields. Also, ``K.structure()`` returns ``from_K`` and ``to_K``, where - from_K is an isomorphism from `K` to self and ``to_K`` is an + ``from_K`` is an isomorphism from `K` to ``self`` and ``to_K`` is an isomorphism from self to `K`. EXAMPLES:: @@ -366,14 +366,19 @@ def change_names(self, names): sage: PF. = F[] sage: K. = F.extension(Y^2 - (1 + a)*(a + b)*a*b) sage: L. = K.change_names(); L - Number Field in m with defining polynomial x^2 + (-2*r - 3)*n - 2*r - 6 over its base field + Number Field in m with defining polynomial + x^2 + (-2*r - 3)*n - 2*r - 6 over its base field sage: L.structure() (Isomorphism given by variable name change map: - From: Number Field in m with defining polynomial x^2 + (-2*r - 3)*n - 2*r - 6 over its base field - To: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field, + From: Number Field in m with defining polynomial + x^2 + (-2*r - 3)*n - 2*r - 6 over its base field + To: Number Field in c with defining polynomial + Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field, Isomorphism given by variable name change map: - From: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field - To: Number Field in m with defining polynomial x^2 + (-2*r - 3)*n - 2*r - 6 over its base field) + From: Number Field in c with defining polynomial + Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + To: Number Field in m with defining polynomial + x^2 + (-2*r - 3)*n - 2*r - 6 over its base field) """ if len(names) == 0: names = self.variable_names() @@ -387,9 +392,9 @@ def change_names(self, names): def subfields(self, degree=0, name=None): """ - Return all subfields of this relative number field self of the given degree, + Return all subfields of this relative number field ``self`` of the given degree, or of all possible degrees if degree is 0. The subfields are returned as - absolute fields together with an embedding into self. For the case of the + absolute fields together with an embedding into ``self``. For the case of the field itself, the reverse isomorphism is also provided. EXAMPLES:: @@ -400,27 +405,42 @@ def subfields(self, degree=0, name=None): sage: K. = F.extension(Y^2 - (1 + a)*(a + b)*a*b) sage: K.subfields(2) [ - (Number Field in c0 with defining polynomial x^2 - 24*x + 96, Ring morphism: - From: Number Field in c0 with defining polynomial x^2 - 24*x + 96 - To: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field - Defn: c0 |--> -4*b + 12, None), - (Number Field in c1 with defining polynomial x^2 - 24*x + 120, Ring morphism: - From: Number Field in c1 with defining polynomial x^2 - 24*x + 120 - To: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field - Defn: c1 |--> 2*b*a + 12, None), - (Number Field in c2 with defining polynomial x^2 - 24*x + 72, Ring morphism: - From: Number Field in c2 with defining polynomial x^2 - 24*x + 72 - To: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field - Defn: c2 |--> -6*a + 12, None) + (Number Field in c0 with defining polynomial x^2 - 24*x + 96, + Ring morphism: + From: Number Field in c0 with defining polynomial x^2 - 24*x + 96 + To: Number Field in c with defining polynomial + Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + Defn: c0 |--> -4*b + 12, + None), + (Number Field in c1 with defining polynomial x^2 - 24*x + 120, + Ring morphism: + From: Number Field in c1 with defining polynomial x^2 - 24*x + 120 + To: Number Field in c with defining polynomial + Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + Defn: c1 |--> 2*b*a + 12, + None), + (Number Field in c2 with defining polynomial x^2 - 24*x + 72, + Ring morphism: + From: Number Field in c2 with defining polynomial x^2 - 24*x + 72 + To: Number Field in c with defining polynomial + Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + Defn: c2 |--> -6*a + 12, + None) ] sage: K.subfields(8, 'w') [ - (Number Field in w0 with defining polynomial x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9, Ring morphism: - From: Number Field in w0 with defining polynomial x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9 - To: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field - Defn: w0 |--> (-1/2*b*a + 1/2*b + 1/2)*c, Relative number field morphism: - From: Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field - To: Number Field in w0 with defining polynomial x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9 + (Number Field in w0 with defining polynomial x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9, + Ring morphism: + From: Number Field in w0 with defining polynomial + x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9 + To: Number Field in c with defining polynomial + Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + Defn: w0 |--> (-1/2*b*a + 1/2*b + 1/2)*c, + Relative number field morphism: + From: Number Field in c with defining polynomial + Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + To: Number Field in w0 with defining polynomial + x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9 Defn: c |--> -1/3*w0^7 + 4*w0^5 - 12*w0^3 + 11*w0 a |--> 1/3*w0^6 - 10/3*w0^4 + 5*w0^2 b |--> -2/3*w0^6 + 7*w0^4 - 14*w0^2 + 6) @@ -444,7 +464,7 @@ def subfields(self, degree=0, name=None): def is_absolute(self): r""" - Returns False, since this is not an absolute field. + Return ``False``, since this is not an absolute field. EXAMPLES:: @@ -550,57 +570,62 @@ def galois_closure(self, names=None): sage: K. = NumberField([x^4 + 3, x^2 + 2]); K Number Field in a with defining polynomial x^4 + 3 over its base field sage: K.galois_closure('c') - Number Field in c with defining polynomial x^16 + 16*x^14 + 28*x^12 + 784*x^10 + 19846*x^8 - 595280*x^6 + 2744476*x^4 + 3212848*x^2 + 29953729 + Number Field in c with defining polynomial x^16 + 16*x^14 + 28*x^12 + + 784*x^10 + 19846*x^8 - 595280*x^6 + 2744476*x^4 + 3212848*x^2 + 29953729 """ return self.absolute_field('a').galois_closure(names=names) def composite_fields(self, other, names=None, both_maps=False, preserve_embedding=True): """ - List of all possible composite number fields formed from self and - other, together with (optionally) embeddings into the compositum; - see the documentation for both_maps below. + List of all possible composite number fields formed from ``self`` and + ``other``, together with (optionally) embeddings into the compositum; + see the documentation for ``both_maps`` below. Since relative fields do not have ambient embeddings, - preserve_embedding has no effect. In every case all possible + ``preserve_embedding`` has no effect. In every case all possible composite number fields are returned. INPUT: - - ``other`` - a number field + - ``other`` -- a number field - - ``names`` - generator name for composite fields + - ``names`` -- generator name for composite fields - - ``both_maps`` - (default: False) if True, return quadruples - (F, self_into_F, other_into_F, k) such that self_into_F maps self into - F, other_into_F maps other into F. For relative number fields k is - always None. - - ``preserve_embedding`` - (default: True) has no effect, but is kept - for compatibility with the absolute version of this function. In every + - ``both_maps`` -- (default: ``False``) if ``True``, return quadruples + (`F`, ``self_into_F, ``other_into_F``, `k`) such that ``self_into_F`` maps ``self`` into + `F`, ``other_into_F`` maps ``other`` into `F`. For relative number fields, `k` is + always ``None``. + + - ``preserve_embedding`` -- (default: ``True``) has no effect, but is kept + for compatibility with the absolute version of this method. In every case the list of all possible compositums is returned. OUTPUT: - - ``list`` - list of the composite fields, possibly with maps. - + list of the composite fields, possibly with maps. EXAMPLES:: sage: K. = NumberField([x^2 + 5, x^2 - 2]) sage: L. = NumberField([x^2 + 5, x^2 - 3]) sage: K.composite_fields(L, 'e') - [Number Field in e with defining polynomial x^8 - 24*x^6 + 464*x^4 + 3840*x^2 + 25600] + [Number Field in e with defining polynomial + x^8 - 24*x^6 + 464*x^4 + 3840*x^2 + 25600] sage: K.composite_fields(L, 'e', both_maps=True) - [[Number Field in e with defining polynomial x^8 - 24*x^6 + 464*x^4 + 3840*x^2 + 25600, + [[Number Field in e with defining polynomial + x^8 - 24*x^6 + 464*x^4 + 3840*x^2 + 25600, Relative number field morphism: - From: Number Field in a with defining polynomial x^2 + 5 over its base field - To: Number Field in e with defining polynomial x^8 - 24*x^6 + 464*x^4 + 3840*x^2 + 25600 - Defn: a |--> -9/66560*e^7 + 11/4160*e^5 - 241/4160*e^3 - 101/104*e - b |--> -21/166400*e^7 + 73/20800*e^5 - 779/10400*e^3 + 7/260*e, + From: Number Field in a with defining polynomial x^2 + 5 over its base field + To: Number Field in e with defining polynomial + x^8 - 24*x^6 + 464*x^4 + 3840*x^2 + 25600 + Defn: a |--> -9/66560*e^7 + 11/4160*e^5 - 241/4160*e^3 - 101/104*e + b |--> -21/166400*e^7 + 73/20800*e^5 - 779/10400*e^3 + 7/260*e, Relative number field morphism: - From: Number Field in c with defining polynomial x^2 + 5 over its base field - To: Number Field in e with defining polynomial x^8 - 24*x^6 + 464*x^4 + 3840*x^2 + 25600 - Defn: c |--> -9/66560*e^7 + 11/4160*e^5 - 241/4160*e^3 - 101/104*e - d |--> -3/25600*e^7 + 7/1600*e^5 - 147/1600*e^3 + 1/40*e, + From: Number Field in c with defining polynomial x^2 + 5 over its base field + To: Number Field in e with defining polynomial + x^8 - 24*x^6 + 464*x^4 + 3840*x^2 + 25600 + Defn: c |--> -9/66560*e^7 + 11/4160*e^5 - 241/4160*e^3 - 101/104*e + d |--> -3/25600*e^7 + 7/1600*e^5 - 147/1600*e^3 + 1/40*e, None]] """ if not isinstance(other, NumberField_generic): @@ -674,7 +699,8 @@ def degree(self): sage: K.degree() Traceback (most recent call last): ... - NotImplementedError: For a relative number field you must use relative_degree or absolute_degree as appropriate + NotImplementedError: For a relative number field + you must use relative_degree or absolute_degree as appropriate """ raise NotImplementedError("For a relative number field you must use relative_degree or absolute_degree as appropriate") @@ -1127,23 +1153,25 @@ def _pari_base_nf(self): def is_galois(self): r""" - For a relative number field, ``is_galois()`` is deliberately not + For a relative number field, :meth:`is_galois` is deliberately not implemented, since it is not clear whether this would mean "Galois over - `\QQ`" or "Galois over the given base field". Use either ``is_galois_absolute()`` or ``is_galois_relative()`` respectively. + `\QQ`" or "Galois over the given base field". + Use either :meth:`is_galois_absolute` or :meth:`is_galois_relative`, respectively. EXAMPLES:: - sage: k. =NumberField([x^3 - 2, x^2 + x + 1]) + sage: k. = NumberField([x^3 - 2, x^2 + x + 1]) sage: k.is_galois() Traceback (most recent call last): ... - NotImplementedError: For a relative number field L you must use either L.is_galois_relative() or L.is_galois_absolute() as appropriate + NotImplementedError: For a relative number field L you must use + either L.is_galois_relative() or L.is_galois_absolute() as appropriate """ raise NotImplementedError("For a relative number field L you must use either L.is_galois_relative() or L.is_galois_absolute() as appropriate") def is_galois_relative(self): r""" - Return True if for this relative extension `L/K`, `L` is a + Return ``True`` if for this relative extension `L/K`, `L` is a Galois extension of `K`. EXAMPLES:: @@ -1172,7 +1200,7 @@ def is_galois_relative(self): def is_galois_absolute(self): r""" - Return True if for this relative extension `L/K`, `L` is a Galois extension of `\QQ`. + Return ``True`` if for this relative extension `L/K`, `L` is a Galois extension of `\QQ`. EXAMPLES:: @@ -1187,7 +1215,7 @@ def is_galois_absolute(self): def is_isomorphic_relative(self, other, base_isom=None): r""" - For this relative extension `L/K` and another relative extension `M/K`, return True + For this relative extension `L/K` and another relative extension `M/K`, return ``True`` if there is a `K`-linear isomorphism from `L` to `M`. More generally, ``other`` can be a relative extension `M/K^\prime` with ``base_isom`` an isomorphism from `K` to `K^\prime`. @@ -1210,7 +1238,7 @@ def is_isomorphic_relative(self, other, base_isom=None): False If we have two extensions over different, but isomorphic, bases, we can compare them by - letting ``base_isom`` be an isomorphism from self's base field to other's base field:: + letting ``base_isom`` be an isomorphism from ``self``'s base field to ``other``'s base field:: sage: Kcyc. = CyclotomicField(9) sage: Rcyc. = PolynomialRing(Kcyc) @@ -1227,12 +1255,14 @@ def is_isomorphic_relative(self, other, base_isom=None): sage: L2.is_isomorphic_relative(L1cyc, base_isom=phi2) True - Omitting ``base_isom`` raises a ValueError when the base fields are not identical:: + Omitting ``base_isom`` raises a :class:`ValueError` when the base fields are not identical:: sage: L1.is_isomorphic_relative(L1cyc) Traceback (most recent call last): ... - ValueError: other does not have the same base field as self, so an isomorphism from self's base_field to other's base_field must be provided using the base_isom parameter. + ValueError: other does not have the same base field as self, + so an isomorphism from self's base_field to other's base_field + must be provided using the base_isom parameter. The parameter ``base_isom`` can also be used to check if the relative extensions are Galois conjugate:: @@ -1265,7 +1295,7 @@ def is_isomorphic_relative(self, other, base_isom=None): def is_CM_extension(self): """ - Return True is this is a CM extension, i.e. a totally imaginary + Return ``True`` is this is a CM extension, i.e. a totally imaginary quadratic extension of a totally real field. EXAMPLES:: @@ -1283,7 +1313,7 @@ def is_CM_extension(self): sage: K.is_CM_extension() False - A CM field K such that K/F is not a CM extension + A CM field `K` such that `K/F` is not a CM extension :: @@ -1362,8 +1392,8 @@ def free_module(self, base=None, basis=None, map=True): def relative_vector_space(self, base=None, *args, **kwds): """ - Return vector space over the base field of self and isomorphisms - from the vector space to self and in the other direction. + Return vector space over the base field of ``self`` and isomorphisms + from the vector space to ``self`` and in the other direction. EXAMPLES:: @@ -1425,7 +1455,7 @@ def absolute_vector_space(self, base=None, *args, **kwds): def vector_space(self, *args, **kwds): r""" - For a relative number field, ``vector_space()`` is + For a relative number field, :meth:`vector_space` is deliberately not implemented, so that a user cannot confuse :meth:`~relative_vector_space` with :meth:`~absolute_vector_space`. @@ -1435,7 +1465,8 @@ def vector_space(self, *args, **kwds): sage: K.vector_space() Traceback (most recent call last): ... - NotImplementedError: For a relative number field L you must use either L.relative_vector_space() or L.absolute_vector_space() as appropriate + NotImplementedError: For a relative number field L you must use either + L.relative_vector_space() or L.absolute_vector_space() as appropriate """ raise NotImplementedError("For a relative number field L you must use either L.relative_vector_space() or L.absolute_vector_space() as appropriate") @@ -1669,8 +1700,8 @@ def pari_relative_polynomial(self): Return the PARI relative polynomial associated to this number field. - This is always a polynomial in x and y, suitable for PARI's - rnfinit function. Notice that if this is a relative extension + This is always a polynomial in `x` and `y`, suitable for PARI's + :pari:`rnfinit` function. Notice that if this is a relative extension of a relative extension, the base field is the absolute base field. @@ -1690,8 +1721,8 @@ def pari_relative_polynomial(self): return self._pari_relative_structure()[0] def number_of_roots_of_unity(self): - """ - Return number of roots of unity in this relative field. + r""" + Return the number of roots of unity in this relative field. EXAMPLES:: @@ -1702,7 +1733,7 @@ def number_of_roots_of_unity(self): return self.absolute_field('a').number_of_roots_of_unity() def roots_of_unity(self): - """ + r""" Return all the roots of unity in this relative field, primitive or not. EXAMPLES:: @@ -1767,14 +1798,16 @@ def absolute_field(self, names): sage: from_L, to_L = L.structure() sage: from_L Isomorphism map: - From: Number Field in c with defining polynomial x^8 + 8*x^6 + 30*x^4 - 40*x^2 + 49 + From: Number Field in c with defining polynomial + x^8 + 8*x^6 + 30*x^4 - 40*x^2 + 49 To: Number Field in a with defining polynomial x^4 + 3 over its base field sage: from_L(c) a - b sage: to_L Isomorphism map: From: Number Field in a with defining polynomial x^4 + 3 over its base field - To: Number Field in c with defining polynomial x^8 + 8*x^6 + 30*x^4 - 40*x^2 + 49 + To: Number Field in c with defining polynomial + x^8 + 8*x^6 + 30*x^4 - 40*x^2 + 49 sage: to_L(a) -5/182*c^7 - 87/364*c^5 - 185/182*c^3 + 323/364*c sage: to_L(b) @@ -1860,7 +1893,7 @@ def relative_polynomial(self): sage: K.relative_polynomial() x^2 + x + 1 - Use absolute polynomial for a polynomial that defines the absolute + Use :meth:`absolute_polynomial` for a polynomial that defines the absolute extension.:: sage: K.absolute_polynomial() @@ -1872,7 +1905,7 @@ def defining_polynomial(self): """ Return the defining polynomial of this relative number field. - This is exactly the same as ``relative_polynomial()``. + This is exactly the same as :meth:`relative_polynomial`. EXAMPLES:: @@ -1887,7 +1920,7 @@ def defining_polynomial(self): def polynomial(self): """ - For a relative number field, ``polynomial()`` is deliberately + For a relative number field, :meth:`polynomial` is deliberately not implemented. Either :meth:`~relative_polynomial` or :meth:`~absolute_polynomial` must be used. @@ -1897,7 +1930,8 @@ def polynomial(self): sage: K.polynomial() Traceback (most recent call last): ... - NotImplementedError: For a relative number field L you must use either L.relative_polynomial() or L.absolute_polynomial() as appropriate + NotImplementedError: For a relative number field L you must use either + L.relative_polynomial() or L.absolute_polynomial() as appropriate """ raise NotImplementedError("For a relative number field L you must use either L.relative_polynomial() or L.absolute_polynomial() as appropriate") @@ -1953,7 +1987,7 @@ def embeddings(self, K): EXAMPLES:: - sage: K. = NumberField([x^3 - 2, x^2+1]) + sage: K. = NumberField([x^3 - 2, x^2 + 1]) sage: f = K.embeddings(ComplexField(58)); f [ Relative number field morphism: @@ -1995,8 +2029,8 @@ def embeddings(self, K): def automorphisms(self): r""" - Compute all Galois automorphisms of self over the base field. This is - different than computing the embeddings of self into self; there, + Compute all Galois automorphisms of ``self`` over the base field. This is + different from computing the embeddings of ``self`` into ``self``; there, automorphisms that do not fix the base field are considered. EXAMPLES:: @@ -2005,10 +2039,12 @@ def automorphisms(self): Number Field in a with defining polynomial x^2 + 10000 over its base field sage: K.automorphisms() [ - Relative number field endomorphism of Number Field in a with defining polynomial x^2 + 10000 over its base field + Relative number field endomorphism of Number Field in a + with defining polynomial x^2 + 10000 over its base field Defn: a |--> a b |--> b, - Relative number field endomorphism of Number Field in a with defining polynomial x^2 + 10000 over its base field + Relative number field endomorphism of Number Field in a + with defining polynomial x^2 + 10000 over its base field Defn: a |--> -a b |--> b ] @@ -2022,10 +2058,12 @@ def automorphisms(self): Number Field in b with defining polynomial x^2 + x + 50 over its base field sage: L.automorphisms() [ - Relative number field endomorphism of Number Field in b with defining polynomial x^2 + x + 50 over its base field + Relative number field endomorphism of Number Field in b + with defining polynomial x^2 + x + 50 over its base field Defn: b |--> b a |--> a, - Relative number field endomorphism of Number Field in b with defining polynomial x^2 + x + 50 over its base field + Relative number field endomorphism of Number Field in b + with defining polynomial x^2 + x + 50 over its base field Defn: b |--> -b - 1 a |--> a ] @@ -2041,11 +2079,13 @@ def automorphisms(self): sage: K. = F.extension(Y^2 - (1 + a)*(a + b)*a*b) sage: K.automorphisms() [ - Relative number field endomorphism of Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + Relative number field endomorphism of Number Field in c + with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field Defn: c |--> c a |--> a b |--> b, - Relative number field endomorphism of Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + Relative number field endomorphism of Number Field in c + with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field Defn: c |--> -c a |--> a b |--> b @@ -2083,7 +2123,7 @@ def logarithmic_embedding(self, prec=53): OUTPUT: - - the morphism of ``self`` under the logarithmic embedding in the category Set. + the morphism of ``self`` under the logarithmic embedding in the category Set. EXAMPLES:: @@ -2139,44 +2179,44 @@ def closure_map(x, prec=53): def places(self, all_complex=False, prec=None): """ - Return the collection of all infinite places of self. + Return the collection of all infinite places of ``self``. By default, this returns the set of real places as - homomorphisms into RIF first, followed by a choice of one of - each pair of complex conjugate homomorphisms into CIF. + homomorphisms into ``RIF`` first, followed by a choice of one of + each pair of complex conjugate homomorphisms into ``CIF``. - On the other hand, if prec is not None, we simply return places - into RealField(prec) and ComplexField(prec) (or RDF, CDF if - prec=53). + On the other hand, if ``prec`` is not ``None``, we simply return places + into ``RealField(prec)`` and ``ComplexField(prec)`` (or ``RDF``, ``CDF`` if + ``prec=53``). - There is an optional flag all_complex, which defaults to False. If - all_complex is True, then the real embeddings are returned as - embeddings into CIF instead of RIF. + There is an optional flag ``all_complex``, which defaults to ``False``. If + ``all_complex`` is ``True``, then the real embeddings are returned as + embeddings into ``CIF`` instead of ``RIF``. EXAMPLES:: sage: L. = NumberFieldTower([x^2 - 5, x^3 + x + 3]) sage: L.places() [Relative number field morphism: - From: Number Field in b with defining polynomial x^2 - 5 over its base field - To: Real Field with 106 bits of precision - Defn: b |--> -2.236067977499789696409173668937 - c |--> -1.213411662762229634132131377426, - Relative number field morphism: - From: Number Field in b with defining polynomial x^2 - 5 over its base field - To: Real Field with 106 bits of precision - Defn: b |--> 2.236067977499789696411548005367 - c |--> -1.213411662762229634130492421800, - Relative number field morphism: - From: Number Field in b with defining polynomial x^2 - 5 over its base field - To: Complex Field with 53 bits of precision - Defn: b |--> -2.23606797749979 ...e-1...*I - c |--> 0.606705831381... - 1.45061224918844*I, - Relative number field morphism: - From: Number Field in b with defining polynomial x^2 - 5 over its base field - To: Complex Field with 53 bits of precision - Defn: b |--> 2.23606797749979 - 4.44089209850063e-16*I - c |--> 0.606705831381115 - 1.45061224918844*I] + From: Number Field in b with defining polynomial x^2 - 5 over its base field + To: Real Field with 106 bits of precision + Defn: b |--> -2.236067977499789696409173668937 + c |--> -1.213411662762229634132131377426, + Relative number field morphism: + From: Number Field in b with defining polynomial x^2 - 5 over its base field + To: Real Field with 106 bits of precision + Defn: b |--> 2.236067977499789696411548005367 + c |--> -1.213411662762229634130492421800, + Relative number field morphism: + From: Number Field in b with defining polynomial x^2 - 5 over its base field + To: Complex Field with 53 bits of precision + Defn: b |--> -2.23606797749979 ...e-1...*I + c |--> 0.606705831381... - 1.45061224918844*I, + Relative number field morphism: + From: Number Field in b with defining polynomial x^2 - 5 over its base field + To: Complex Field with 53 bits of precision + Defn: b |--> 2.23606797749979 - 4.44089209850063e-16*I + c |--> 0.606705831381115 - 1.45061224918844*I] """ L = self.absolute_field('a') pl = L.places(all_complex, prec) @@ -2186,7 +2226,7 @@ def absolute_different(self): r""" Return the absolute different of this relative number field `L`, as an ideal of `L`. To get the relative different of `L/K`, use - ``L.relative_different()``. + :meth:`relative_different`. EXAMPLES:: @@ -2204,7 +2244,7 @@ def relative_different(self): r""" Return the relative different of this extension `L/K` as an ideal of `L`. If you want the absolute different of - `L/\QQ`, use ``L.absolute_different()``. + `L/\QQ`, use :meth:`absolute_different`. EXAMPLES:: @@ -2230,7 +2270,8 @@ def different(self): sage: K.different() Traceback (most recent call last): ... - NotImplementedError: For a relative number field you must use relative_different or absolute_different as appropriate + NotImplementedError: For a relative number field you must use + relative_different or absolute_different as appropriate """ raise NotImplementedError("For a relative number field you must use relative_different or absolute_different as appropriate") @@ -2309,7 +2350,8 @@ def discriminant(self): sage: K.discriminant() Traceback (most recent call last): ... - NotImplementedError: For a relative number field you must use relative_discriminant or absolute_discriminant as appropriate + NotImplementedError: For a relative number field you must use + relative_discriminant or absolute_discriminant as appropriate """ raise NotImplementedError("For a relative number field you must use relative_discriminant or absolute_discriminant as appropriate") @@ -2325,7 +2367,8 @@ def disc(self): sage: K.disc() Traceback (most recent call last): ... - NotImplementedError: For a relative number field you must use relative_discriminant or absolute_discriminant as appropriate + NotImplementedError: For a relative number field you must use + relative_discriminant or absolute_discriminant as appropriate """ raise NotImplementedError("For a relative number field you must use relative_discriminant or absolute_discriminant as appropriate") @@ -2336,25 +2379,26 @@ def order(self, *gens, **kwds): INPUT: - - ``gens`` -- list of elements of self; if no generators are given, just - returns the cardinality of this number field (oo) for consistency. - - ``check_is_integral`` -- bool (default: True), whether to check that each + - ``gens`` -- list of elements of ``self``; if no generators are given, just + returns the cardinality of this number field (`\infty`) for consistency. + - ``check_is_integral`` -- bool (default: ``True``), whether to check that each generator is integral. - - ``check_rank`` -- bool (default: True), whether to check that the ring - generated by gens is of full rank. - - ``allow_subfield`` -- bool (default: False), if True and the generators + - ``check_rank`` -- bool (default: ``True``), whether to check that the ring + generated by ``gens`` is of full rank. + - ``allow_subfield`` -- bool (default: ``False``), if ``True`` and the generators do not generate an order, i.e., they generate a subring of smaller rank, instead of raising an error, return an order in a smaller number field. - The check_is_integral and check_rank inputs must be given as + The ``check_is_integral`` and ``check_rank`` inputs must be given as explicit keyword arguments. EXAMPLES:: sage: P. = QQ[2^(1/2), 2^(1/3), 3^(1/2)] sage: R = P.order([a,b,c]); R - Relative Order in Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field + Relative Order in Number Field in sqrt2 + with defining polynomial x^2 - 2 over its base field The base ring of an order in a relative extension is still `\ZZ`.:: @@ -2364,7 +2408,7 @@ def order(self, *gens, **kwds): One must give enough generators to generate a ring of finite index in the maximal order:: - sage: P.order([a,b]) + sage: P.order([a, b]) Traceback (most recent call last): ... ValueError: the rank of the span of gens is wrong @@ -2389,7 +2433,7 @@ def is_free(self, proof=None): EXAMPLES:: sage: x = polygen(QQ) - sage: K. = NumberField(x^2+6) + sage: K. = NumberField(x^2 + 6) sage: x = polygen(K) sage: L. = K.extension(x^2 + 3) # extend by x^2+3 sage: L.is_free() @@ -2424,7 +2468,7 @@ def _factor_univariate_polynomial(self, poly, **kwargs): def lift_to_base(self, element): """ Lift an element of this extension into the base field if possible, - or raise a ValueError if it is not possible. + or raise a :class:`ValueError` if it is not possible. EXAMPLES:: @@ -2474,21 +2518,21 @@ def lift_to_base(self, element): def relativize(self, alpha, names): r""" - Given an element in self or an embedding of a subfield into self, - return a relative number field `K` isomorphic to self that is relative + Given an element in ``self`` or an embedding of a subfield into ``self``, + return a relative number field `K` isomorphic to ``self`` that is relative over the absolute field `\QQ(\alpha)` or the domain of `\alpha`, along - with isomorphisms from `K` to self and from self to `K`. + with isomorphisms from `K` to ``self`` and from ``self`` to `K`. INPUT: - - ``alpha`` -- an element of self, or an embedding of a subfield into self + - ``alpha`` -- an element of ``self``, or an embedding of a subfield into ``self`` - ``names`` -- name of generator for output field `K`. OUTPUT: `K` -- a relative number field Also, ``K.structure()`` returns ``from_K`` and ``to_K``, where - ``from_K`` is an isomorphism from `K` to self and ``to_K`` is - an isomorphism from self to `K`. + ``from_K`` is an isomorphism from `K` to ``self`` and ``to_K`` is + an isomorphism from ``self`` to `K`. EXAMPLES:: @@ -2500,7 +2544,8 @@ def relativize(self, alpha, names): sage: w^2 -3 sage: L - Number Field in z with defining polynomial x^4 + (-2*w + 4)*x^2 + 4*w + 1 over its base field + Number Field in z with defining polynomial + x^4 + (-2*w + 4)*x^2 + 4*w + 1 over its base field sage: L.base_field() Number Field in w with defining polynomial x^2 + 3 @@ -2517,7 +2562,8 @@ def relativize(self, alpha, names): sage: L_over_K = L.relativize(K_into_L, 'c'); L_over_K Number Field in c with defining polynomial x^2 + a0_0 over its base field sage: L_over_K_to_L, L_to_L_over_K = L_over_K.structure() - sage: M_over_L_over_K = M.relativize(L_into_M * L_over_K_to_L, 'd'); M_over_L_over_K + sage: M_over_L_over_K = M.relativize(L_into_M * L_over_K_to_L, 'd') + sage: M_over_L_over_K Number Field in d with defining polynomial x^2 + c over its base field sage: M_over_L_over_K.base_field() is L_over_K True @@ -2567,25 +2613,24 @@ def relativize(self, alpha, names): def uniformizer(self, P, others = "positive"): """ - Returns an element of self with valuation 1 at the prime ideal P. + Returns an element of ``self`` with valuation 1 at the prime ideal `P`. INPUT: + - ``self`` -- a number field - - ``self`` - a number field - - - ``P`` - a prime ideal of self + - ``P`` -- a prime ideal of ``self`` - - ``others`` - either "positive" (default), in which + - ``others`` -- either ``"positive"`` (default), in which case the element will have non-negative valuation at all other - primes of self, or "negative", in which case the element will have - non-positive valuation at all other primes of self. + primes of ``self``, or ``"negative"``, in which case the element will have + non-positive valuation at all other primes of ``self``. .. note:: - When P is principal (e.g. always when self has class number - one) the result may or may not be a generator of P! + When `P` is principal (e.g., always when ``self`` has class number + one), the result may or may not be a generator of `P`! EXAMPLES:: diff --git a/src/sage/rings/number_field/order.py b/src/sage/rings/number_field/order.py index 288e4dc83c5..5dff61c7f68 100644 --- a/src/sage/rings/number_field/order.py +++ b/src/sage/rings/number_field/order.py @@ -16,7 +16,7 @@ We compute a basis for an order in a relative extension that is generated by 2 elements:: - sage: K. = NumberField([x^2 + 1, x^2 - 3]); O = K.order([3*a,2*b]) + sage: K. = NumberField([x^2 + 1, x^2 - 3]); O = K.order([3*a, 2*b]) sage: O.basis() [1, 3*a - 2*b, -6*b*a + 6, 3*a] @@ -24,12 +24,14 @@ sage: K. = NumberField((x+1)^10 + 17) sage: K.maximal_order() - Maximal Order in Number Field in a with defining polynomial x^10 + 10*x^9 + 45*x^8 + 120*x^7 + 210*x^6 + 252*x^5 + 210*x^4 + 120*x^3 + 45*x^2 + 10*x + 18 + Maximal Order in Number Field in a with defining polynomial x^10 + 10*x^9 + + 45*x^8 + 120*x^7 + 210*x^6 + 252*x^5 + 210*x^4 + 120*x^3 + 45*x^2 + 10*x + 18 We compute a suborder, which has index a power of 17 in the maximal order:: sage: O = K.order(17*a); O - Order in Number Field in a with defining polynomial x^10 + 10*x^9 + 45*x^8 + 120*x^7 + 210*x^6 + 252*x^5 + 210*x^4 + 120*x^3 + 45*x^2 + 10*x + 18 + Order in Number Field in a with defining polynomial x^10 + 10*x^9 + + 45*x^8 + 120*x^7 + 210*x^6 + 252*x^5 + 210*x^4 + 120*x^3 + 45*x^2 + 10*x + 18 sage: m = O.index_in(K.maximal_order()); m 23453165165327788911665591944416226304630809183732482257 sage: factor(m) @@ -262,7 +264,8 @@ class RelativeOrderFactory(OrderFactory): sage: R. = K[] sage: L. = K.extension(j^2 - 2) sage: L.order([i, j]) - Relative Order in Number Field in j with defining polynomial j^2 - 2 over its base field + Relative Order in Number Field in j + with defining polynomial j^2 - 2 over its base field """ @@ -321,7 +324,7 @@ def create_object(self, version, key, is_maximal=None, is_maximal_at=()): def is_NumberFieldOrder(R): r""" - Return True if R is either an order in a number field or is the ring `\ZZ` of integers. + Return ``True`` if `R` is either an order in a number field or is the ring `\ZZ` of integers. EXAMPLES:: @@ -341,7 +344,7 @@ def is_NumberFieldOrder(R): def EquationOrder(f, names, **kwds): r""" Return the equation order generated by a root of the irreducible - polynomial f or list of polynomials `f` (to construct a relative + polynomial `f` or list ``f`` of polynomials (to construct a relative equation order). IMPORTANT: Note that the generators of the returned order need @@ -350,9 +353,10 @@ def EquationOrder(f, names, **kwds): EXAMPLES:: - sage: O. = EquationOrder([x^2+1, x^2+2]) + sage: O. = EquationOrder([x^2 + 1, x^2 + 2]) sage: O - Relative Order in Number Field in a with defining polynomial x^2 + 1 over its base field + Relative Order in Number Field in a + with defining polynomial x^2 + 1 over its base field sage: O.0 -b*a - 1 sage: O.1 @@ -365,7 +369,7 @@ def EquationOrder(f, names, **kwds): ... ValueError: each generator must be integral - sage: R = EquationOrder( [x^3 + x + 1, x^2 + 1/2], 'alpha'); R + sage: R = EquationOrder([x^3 + x + 1, x^2 + 1/2], 'alpha'); R Traceback (most recent call last): ... ValueError: each generator must be integral @@ -468,7 +472,8 @@ def ideal(self, *args, **kwds): sage: R.ideal(2/3 + 7*a, a) Traceback (most recent call last): ... - ValueError: ideal must be integral; use fractional_ideal to create a non-integral ideal. + ValueError: ideal must be integral; + use fractional_ideal to create a non-integral ideal. sage: R.ideal(7*a, 77 + 28*a) Fractional ideal (7) sage: R = K.order(4*a) @@ -589,7 +594,7 @@ def is_noetherian(self): return True def is_integrally_closed(self): - """ + r""" Return ``True`` if this ring is integrally closed, i.e., is equal to the maximal order. @@ -609,7 +614,7 @@ def is_integrally_closed(self): return self.is_maximal() def krull_dimension(self): - """ + r""" Return the Krull dimension of this order, which is 1. EXAMPLES:: @@ -625,16 +630,18 @@ def krull_dimension(self): return ZZ(1) def integral_closure(self): - """ + r""" Return the integral closure of this order. EXAMPLES:: sage: K. = QuadraticField(5) sage: O2 = K.order(2*a); O2 - Order in Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? + Order in Number Field in a with defining polynomial x^2 - 5 + with a = 2.236067977499790? sage: O2.integral_closure() - Maximal Order in Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? + Maximal Order in Number Field in a with defining polynomial x^2 - 5 + with a = 2.236067977499790? sage: OK = K.maximal_order() sage: OK is OK.integral_closure() True @@ -674,7 +681,7 @@ def gen(self, i): return self.basis()[i] def ngens(self): - """ + r""" Return the number of module generators of this order. EXAMPLES:: @@ -722,7 +729,7 @@ def coordinates(self, x): Uses linear algebra. The change-of-basis matrix is cached. Provides simpler implementations for - ``_contains_()``, ``is_integral()`` and ``smallest_integer()``. + :meth:`_contains_`, :meth:`is_integral` and :meth:`smallest_integer`. EXAMPLES:: @@ -779,7 +786,7 @@ def free_module(self): [ 0 0 1] An example in a relative extension. Notice that the module is - a `\ZZ`-module in the absolute_field associated to the relative + a `\ZZ`-module in the absolute field associated to the relative field:: sage: K. = NumberField([x^2 + 1, x^2 + 2]) @@ -805,7 +812,7 @@ def free_module(self): @cached_method def ring_generators(self): """ - Return generators for self as a ring. + Return generators for ``self`` as a ring. EXAMPLES:: @@ -829,7 +836,9 @@ def ring_generators(self): sage: K. = NumberField([x^2 + x + 1, x^3 - 3]) sage: O = K.maximal_order() sage: O.ring_generators() - [(-5/3*b^2 + 3*b - 2)*a - 7/3*b^2 + b + 3, (-5*b^2 - 9)*a - 5*b^2 - b, (-6*b^2 - 11)*a - 6*b^2 - b] + [(-5/3*b^2 + 3*b - 2)*a - 7/3*b^2 + b + 3, + (-5*b^2 - 9)*a - 5*b^2 - b, + (-6*b^2 - 11)*a - 6*b^2 - b] """ K = self._K n = [] @@ -868,8 +877,8 @@ def _defining_names(self): def zeta(self, n=2, all=False): r""" - Return a primitive n-th root of unity in this order, if it - contains one. If all is True, return all of them. + Return a primitive `n`-th root of unity in this order, if it + contains one. If ``all`` is ``True``, return all of them. EXAMPLES:: @@ -915,10 +924,10 @@ def number_field(self): def ambient(self): r""" - Return the ambient number field that contains self. + Return the ambient number field that contains ``self``. - This is the same as ``self.number_field()`` and - ``self.fraction_field()`` + This is the same as :meth:`number_field` and + :meth:`fraction_field` EXAMPLES:: @@ -935,12 +944,12 @@ def ambient(self): def residue_field(self, prime, names=None, check=False): """ - Return the residue field of this order at a given prime, ie `O/pO`. + Return the residue field of this order at a given prime, i.e., `O/pO`. INPUT: - ``prime`` -- a prime ideal of the maximal order in this number field. - - ``names`` -- the name of the variable in the residue field + - ``names`` -- the name of the variable in the residue field. - ``check`` -- whether or not to check the primality of prime. OUTPUT: @@ -950,7 +959,7 @@ def residue_field(self, prime, names=None, check=False): EXAMPLES:: sage: R. = QQ[] - sage: K. = NumberField(x^4+3*x^2-17) + sage: K. = NumberField(x^4 + 3*x^2 - 17) sage: P = K.ideal(61).factor()[0][0] sage: OK = K.maximal_order() sage: OK.residue_field(P) @@ -1002,7 +1011,7 @@ def rank(self): `\ZZ`-module, or the degree of the ambient number field that contains this order. - This is a synonym for ``degree()``. + This is a synonym for :meth:`degree`. EXAMPLES:: @@ -1036,7 +1045,8 @@ def class_number(self, proof=None): sage: ZZ[11*2^(1/3)].class_number() Traceback (most recent call last): ... - NotImplementedError: computation of class numbers of non-maximal orders not in quadratic fields is not implemented + NotImplementedError: computation of class numbers of non-maximal orders + not in quadratic fields is not implemented """ if not self.is_maximal(): @@ -1058,7 +1068,8 @@ def class_group(self, proof=None, names='c'): sage: O = k.maximal_order(); O Maximal Order in Number Field in a with defining polynomial x^2 + 5077 sage: O.class_group() - Class group of order 22 with structure C22 of Number Field in a with defining polynomial x^2 + 5077 + Class group of order 22 with structure C22 of + Number Field in a with defining polynomial x^2 + 5077 """ if self.is_maximal(): return self.number_field().class_group(proof=proof, names=names) @@ -1067,8 +1078,8 @@ def class_group(self, proof=None, names='c'): def is_suborder(self, other): """ - Return True if self and other are both orders in the - same ambient number field and self is a subset of other. + Return ``True`` if ``self`` and ``other`` are both orders in the + same ambient number field and ``self`` is a subset of ``other``. EXAMPLES:: @@ -1088,13 +1099,13 @@ def is_suborder(self, other): sage: W2. = NumberField(x^2 + 1) sage: P5 = W2.order(5*j) - This is False because the ambient number fields are not equal.:: + This is ``False`` because the ambient number fields are not equal.:: sage: O5.is_suborder(P5) False - We create a field that contains (in no natural way!) W, - and of course again is_suborder returns False:: + We create a field that contains (in no natural way!) `W`, + and of course again :meth:`is_suborder` returns False:: sage: K. = NumberField(x^4 + 1) sage: M = K.order(5*z) @@ -1250,7 +1261,8 @@ def random_element(self, *args, **kwds): sage: K. = CyclotomicField(17) sage: OK = K.ring_of_integers() sage: OK.random_element() # random output - z^15 - z^11 - z^10 - 4*z^9 + z^8 + 2*z^7 + z^6 - 2*z^5 - z^4 - 445*z^3 - 2*z^2 - 15*z - 2 + z^15 - z^11 - z^10 - 4*z^9 + z^8 + 2*z^7 + z^6 + - 2*z^5 - z^4 - 445*z^3 - 2*z^2 - 15*z - 2 sage: OK.random_element().is_integral() True sage: OK.random_element().parent() is OK @@ -1287,7 +1299,7 @@ def random_element(self, *args, **kwds): def absolute_degree(self): r""" - Return the absolute degree of this order, ie the degree of this order over `\ZZ`. + Return the absolute degree of this order, i.e., the degree of this order over `\ZZ`. EXAMPLES:: @@ -1300,11 +1312,11 @@ def absolute_degree(self): def valuation(self, p): r""" - Return the ``p``-adic valuation on this order. + Return the `p`-adic valuation on this order. EXAMPLES: - The valuation can be specified with an integer ``prime`` that is + The valuation can be specified with an integer prime `p` that is completely ramified or unramified:: sage: K. = NumberField(x^2 + 1) @@ -1320,12 +1332,13 @@ def valuation(self, p): sage: GaussianIntegers().valuation(3) 3-adic valuation - A ``prime`` that factors into pairwise distinct factors, results in an error:: + A prime `p` that factors into pairwise distinct factors, results in an error:: sage: GaussianIntegers().valuation(5) Traceback (most recent call last): ... - ValueError: The valuation Gauss valuation induced by 5-adic valuation does not approximate a unique extension of 5-adic valuation with respect to x^2 + 1 + ValueError: The valuation Gauss valuation induced by 5-adic valuation does not + approximate a unique extension of 5-adic valuation with respect to x^2 + 1 The valuation can also be selected by giving a valuation on the base ring that extends uniquely:: @@ -1338,15 +1351,17 @@ def valuation(self, p): sage: GaussianIntegers().valuation(ZZ.valuation(5)) Traceback (most recent call last): ... - ValueError: The valuation Gauss valuation induced by 5-adic valuation does not approximate a unique extension of 5-adic valuation with respect to x^2 + 1 + ValueError: The valuation Gauss valuation induced by 5-adic valuation does not + approximate a unique extension of 5-adic valuation with respect to x^2 + 1 If the fraction field is of the form `K[x]/(G)`, you can specify a valuation by providing a discrete pseudo-valuation on `K[x]` which sends `G` to infinity:: sage: R. = QQ[] - sage: v = GaussianIntegers().valuation(GaussValuation(R, QQ.valuation(5)).augmentation(x + 2, infinity)) - sage: w = GaussianIntegers().valuation(GaussValuation(R, QQ.valuation(5)).augmentation(x + 1/2, infinity)) + sage: GV5 = GaussValuation(R, QQ.valuation(5)) + sage: v = GaussianIntegers().valuation(GV5.augmentation(x + 2, infinity)) + sage: w = GaussianIntegers().valuation(GV5.augmentation(x + 1/2, infinity)) sage: v == w False @@ -1441,7 +1456,7 @@ def __init__(self, K, module_rep): sage: from sage.rings.number_field.order import * sage: x = polygen(QQ) - sage: K. = NumberField(x^3+2) + sage: K. = NumberField(x^3 + 2) sage: V, from_v, to_v = K.vector_space() sage: M = span([to_v(a^2), to_v(a), to_v(1)],ZZ) sage: O = AbsoluteOrder(K, M); O @@ -1665,7 +1680,7 @@ def is_maximal(self, p=None): INPUT: - ``p`` -- an integer prime or ``None`` (default: ``None``); if - set, return whether this order is maximal at the prime ``p``. + set, return whether this order is maximal at the prime `p`. EXAMPLES:: @@ -1694,7 +1709,7 @@ def is_maximal(self, p=None): An example involving a relative order:: sage: K. = NumberField([x^2 + 1, x^2 - 3]) - sage: O = K.order([3*a,2*b]) + sage: O = K.order([3*a, 2*b]) sage: O.is_maximal() False @@ -1886,10 +1901,10 @@ def change_names(self, names): def index_in(self, other): """ - Return the index of self in other. + Return the index of ``self`` in ``other``. This is a lattice index, - so it is a rational number if self is not contained in other. + so it is a rational number if ``self`` is not contained in ``other``. INPUT: @@ -2061,7 +2076,7 @@ class Order_relative(Order): """ A relative order in a number field. - A relative order is an order in some relative number field + A relative order is an order in some relative number field. Invariants of this order may be computed with respect to the contained order. @@ -2163,7 +2178,8 @@ def absolute_order(self, names='z'): EXAMPLES:: sage: R = EquationOrder([x^2 + 1, x^2 - 5], 'i,g'); R - Relative Order in Number Field in i with defining polynomial x^2 + 1 over its base field + Relative Order in Number Field in i + with defining polynomial x^2 + 1 over its base field sage: R.basis() [1, 6*i - g, -g*i + 2, 7*i - g] @@ -2173,11 +2189,12 @@ def absolute_order(self, names='z'): [1, 5/12*z^3 + 1/6*z, 1/2*z^2, 1/2*z^3] We compute a relative order in alpha0, alpha1, then make the - number field that contains the absolute order be called + generator of the number field that contains the absolute order be called gamma.:: - sage: R = EquationOrder( [x^2 + 2, x^2 - 3], 'alpha'); R - Relative Order in Number Field in alpha0 with defining polynomial x^2 + 2 over its base field + sage: R = EquationOrder([x^2 + 2, x^2 - 3], 'alpha'); R + Relative Order in Number Field in alpha0 + with defining polynomial x^2 + 2 over its base field sage: R.absolute_order('gamma') Order in Number Field in gamma with defining polynomial x^4 - 2*x^2 + 25 sage: R.absolute_order('gamma').basis() @@ -2294,7 +2311,7 @@ def is_maximal(self, p=None): INPUT: - ``p`` -- an integer prime or ``None`` (default: ``None``); if - set, return whether this order is maximal at the prime ``p``. + set, return whether this order is maximal at the prime `p`. EXAMPLES:: @@ -2425,8 +2442,8 @@ def _assume_maximal(self, is_maximal=True, p=None): def absolute_discriminant(self): """ - Return the absolute discriminant of self, which is the discriminant - of the absolute order associated to self. + Return the absolute discriminant of ``self``, which is the discriminant + of the absolute order associated to ``self``. OUTPUT: @@ -2446,13 +2463,13 @@ def absolute_discriminant(self): def is_suborder(self, other): """ - Return True if self is a subset of the order other. + Return ``True`` if ``self`` is a subset of the order ``other``. EXAMPLES:: sage: K. = NumberField([x^2 + 1, x^3 + 2]) - sage: R1 = K.order([a,b]) - sage: R2 = K.order([2*a,b]) + sage: R1 = K.order([a, b]) + sage: R2 = K.order([2*a, b]) sage: R3 = K.order([a + b, b + 2*a]) sage: R1.is_suborder(R2) False @@ -2469,10 +2486,10 @@ def is_suborder(self, other): def index_in(self, other): """ - Return the index of self in other. + Return the index of ``self`` in ``other``. This is a lattice index, - so it is a rational number if self is not contained in other. + so it is a rational number if ``self`` is not contained in ``other``. INPUT: @@ -2521,13 +2538,13 @@ def absolute_order_from_ring_generators(gens, check_is_integral=True, INPUT: - ``gens`` -- list of integral elements of an absolute order. - - ``check_is_integral`` -- bool (default: True), whether to check that each + - ``check_is_integral`` -- bool (default: ``True``), whether to check that each generator is integral. - - ``check_rank`` -- bool (default: True), whether to check that the ring - generated by gens is of full rank. - - ``is_maximal`` -- bool (or None); set if maximality of the generated order is + - ``check_rank`` -- bool (default: ``True``), whether to check that the ring + generated by ``gens`` is of full rank. + - ``is_maximal`` -- bool (or ``None``); set if maximality of the generated order is known - - ``allow_subfield`` -- bool (default: False), if True and the generators do + - ``allow_subfield`` -- bool (default: ``False``), if ``True`` and the generators do not generate an order, i.e., they generate a subring of smaller rank, instead of raising an error, return an order in a smaller number field. @@ -2543,7 +2560,7 @@ def absolute_order_from_ring_generators(gens, check_is_integral=True, sage: from sage.rings.number_field.order import absolute_order_from_ring_generators sage: absolute_order_from_ring_generators([a]) Order in Number Field in a with defining polynomial x^4 - 5 - sage: absolute_order_from_ring_generators([3*a, 2, 6*a+1]) + sage: absolute_order_from_ring_generators([3*a, 2, 6*a + 1]) Order in Number Field in a with defining polynomial x^4 - 5 If one of the inputs is non-integral, it is an error.:: @@ -2553,7 +2570,7 @@ def absolute_order_from_ring_generators(gens, check_is_integral=True, ... ValueError: each generator must be integral - If the gens do not generate an order, i.e., generate a ring of full + If the ``gens`` do not generate an order, i.e., generate a ring of full rank, then it is an error.:: sage: absolute_order_from_ring_generators([a^2]) @@ -2587,16 +2604,16 @@ def absolute_order_from_module_generators(gens, check_integral=True, check_rank=True, check_is_ring=True, is_maximal=None, allow_subfield=False, is_maximal_at=()): - """ + r""" INPUT: - ``gens`` -- list of elements of an absolute number field that generates an - order in that number field as a ZZ *module*. - - ``check_integral`` -- check that each gen is integral - - ``check_rank`` -- check that the gens span a module of the correct rank + order in that number field as a `\ZZ`-*module*. + - ``check_integral`` -- check that each generator is integral + - ``check_rank`` -- check that the ``gens`` span a module of the correct rank - ``check_is_ring`` -- check that the module is closed under multiplication (this is very expensive) - - ``is_maximal`` -- bool (or None); set if maximality of the generated order is known + - ``is_maximal`` -- bool (or ``None``); set if maximality of the generated order is known - ``is_maximal_at`` -- a tuple of primes where this order is known to be maximal OUTPUT: @@ -2641,11 +2658,13 @@ def absolute_order_from_module_generators(gens, off various check flags:: sage: k. = NumberField(x^2 + 1) - sage: R = absolute_order_from_module_generators([2, 2*i], check_is_ring=False); R + sage: R = absolute_order_from_module_generators([2, 2*i], + ....: check_is_ring=False); R Order in Number Field in i with defining polynomial x^2 + 1 sage: R.basis() [2, 2*i] - sage: R = absolute_order_from_module_generators([k(1)], check_rank=False); R + sage: R = absolute_order_from_module_generators([k(1)], + ....: check_rank=False); R Order in Number Field in i with defining polynomial x^2 + 1 sage: R.basis() [1] @@ -2654,25 +2673,31 @@ def absolute_order_from_module_generators(gens, that, we will find that the rank is wrong or that the order is not closed under multiplication:: - sage: absolute_order_from_module_generators([1/2, i], check_integral=False) + sage: absolute_order_from_module_generators([1/2, i], + ....: check_integral=False) Traceback (most recent call last): ... ValueError: the module span of the gens is not closed under multiplication. - sage: R = absolute_order_from_module_generators([1/2, i], check_is_ring=False, check_integral=False); R + sage: R = absolute_order_from_module_generators([1/2, i], + ....: check_is_ring=False, + ....: check_integral=False); R Order in Number Field in i with defining polynomial x^2 + 1 sage: R.basis() [1/2, i] We turn off all check flags and make a really messed up order:: - sage: R = absolute_order_from_module_generators([1/2, i], check_is_ring=False, check_integral=False, check_rank=False); R + sage: R = absolute_order_from_module_generators([1/2, i], + ....: check_is_ring=False, + ....: check_integral=False, + ....: check_rank=False); R Order in Number Field in i with defining polynomial x^2 + 1 sage: R.basis() [1/2, i] An order that lives in a subfield:: - sage: F. = NumberField(x**4+3) + sage: F. = NumberField(x**4 + 3) sage: F.order([alpha**2], allow_subfield=True) Order in Number Field in beta with defining polynomial ... with beta = ... """ @@ -2733,12 +2758,12 @@ def relative_order_from_ring_generators(gens, INPUT: - ``gens`` -- list of integral elements of an absolute order. - - ``check_is_integral`` -- bool (default: True), whether to check that each + - ``check_is_integral`` -- bool (default: ``True``), whether to check that each generator is integral. - - ``check_rank`` -- bool (default: True), whether to check that the ring - generated by gens is of full rank. - - ``is_maximal`` -- bool (or None); set if maximality of the generated order is - known + - ``check_rank`` -- bool (default: ``True``), whether to check that the ring + generated by ``gens`` is of full rank. + - ``is_maximal`` -- bool (or ``None``); set if maximality of the generated order is + known. EXAMPLES: @@ -2749,7 +2774,8 @@ def relative_order_from_ring_generators(gens, sage: K. = NumberField([x^2 + 1, x^2 - 17]) sage: R = K.base_field().maximal_order() sage: S = relative_order_from_ring_generators([i,a]); S - Relative Order in Number Field in i with defining polynomial x^2 + 1 over its base field + Relative Order in Number Field in i + with defining polynomial x^2 + 1 over its base field Basis for the relative order, which is obtained by computing the algebra generated by i and a:: @@ -2816,13 +2842,14 @@ def EisensteinIntegers(names="omega"): This is the ring of all complex numbers of the form `a + b \omega` with `a` and `b` integers and - `omega = (-1 + \sqrt{-3})/2`. + `\omega = (-1 + \sqrt{-3})/2`. EXAMPLES:: sage: R. = EisensteinIntegers() sage: R - Eisenstein Integers in Number Field in omega with defining polynomial x^2 + x + 1 with omega = -0.50000000000000000? + 0.866025403784439?*I + Eisenstein Integers in Number Field in omega with defining polynomial x^2 + x + 1 + with omega = -0.50000000000000000? + 0.866025403784439?*I sage: factor(3 + omega) (-1) * (-omega - 3) sage: CC(omega) diff --git a/src/sage/rings/number_field/selmer_group.py b/src/sage/rings/number_field/selmer_group.py index 487550ef4d5..a80f1a66163 100644 --- a/src/sage/rings/number_field/selmer_group.py +++ b/src/sage/rings/number_field/selmer_group.py @@ -353,23 +353,23 @@ class is a ``p``'th power; def pSelmerGroup(K, S, p, proof=None, debug=False): r""" - Return the ``p``-Selmer group `K(S,p)` of the number field ``K`` - with respect to the prime ideals in ``S`` + Return the `p`-Selmer group `K(S,p)` of the number field `K` + with respect to the prime ideals in ``S``. INPUT: - - ``K`` (number field) -- a number field, or `\QQ`. + - ``K`` -- a number field or `\QQ`. - - ``S`` (list) -- a list of prime ideals in ``K``, or prime - numbers when ``K`` is `\QQ`. + - ``S`` -- a list of prime ideals in `K`, or prime + numbers when `K` is `\QQ`. - - ``p`` (prime) -- a prime number. + - ``p`` -- a prime number. - - ``proof`` - if True then compute the class group provably - correctly. Default is True. Call :meth:`proof.number_field` to + - ``proof`` -- if ``True``, compute the class group provably + correctly. Default is ``True``. Call :meth:`proof.number_field` to change this default globally. - - ``debug`` (boolean, default ``False``) -- debug flag. + - ``debug`` -- (boolean, default ``False``) debug flag. OUTPUT: diff --git a/src/sage/rings/number_field/small_primes_of_degree_one.py b/src/sage/rings/number_field/small_primes_of_degree_one.py index facd5207a1c..b5cb57bb2df 100644 --- a/src/sage/rings/number_field/small_primes_of_degree_one.py +++ b/src/sage/rings/number_field/small_primes_of_degree_one.py @@ -108,17 +108,17 @@ class Small_primes_of_degree_one_iter(): INPUT: - - ``field`` -- a ``NumberField``. + - ``field`` -- a :class:`NumberField`. - - ``num_integer_primes`` (default: 10000) -- an integer. We try to find + - ``num_integer_primes`` -- (default: 10000) an integer. We try to find primes of absolute norm no greater than the ``num_integer_primes``-th prime number. For example, if ``num_integer_primes`` is 2, the largest norm found will be 3, since the second prime is 3. - - ``max_iterations`` (default: 100) -- an integer. We test + - ``max_iterations`` -- (default: 100) an integer. We test ``max_iterations`` integers to find small primes before raising - ``StopIteration``. + :class:`StopIteration`. AUTHOR: diff --git a/src/sage/rings/number_field/structure.py b/src/sage/rings/number_field/structure.py index 52e6ed6d503..72091140d9a 100644 --- a/src/sage/rings/number_field/structure.py +++ b/src/sage/rings/number_field/structure.py @@ -14,8 +14,10 @@ identical because `M` carries additional information:: sage: L.structure() - (Identity endomorphism of Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095?, - Identity endomorphism of Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095?) + (Identity endomorphism of + Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095?, + Identity endomorphism of + Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095?) sage: M.structure() (Isomorphism given by variable name change map: From: Number Field in a with defining polynomial x^2 - 2 @@ -26,7 +28,7 @@ This used to cause trouble with caching and made (absolute) number fields not unique when they should have been. The underlying technical problem is that the -morphisms returned by ``structure()`` can only be defined once the fields in +morphisms returned by :meth:`structure` can only be defined once the fields in question have been created. Therefore, these morphisms cannot be part of a key which uniquely identifies a number field. @@ -72,7 +74,7 @@ class NumberFieldStructure(UniqueRepresentation): True sage: R. = QQ[] - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: L = K.change_names('j').change_names('i') sage: K is L # K and L differ in "structure", one is the "name-change" of the other False diff --git a/src/sage/rings/number_field/totallyreal.pyx b/src/sage/rings/number_field/totallyreal.pyx index ecb8236260c..ecd563fb3cf 100644 --- a/src/sage/rings/number_field/totallyreal.pyx +++ b/src/sage/rings/number_field/totallyreal.pyx @@ -45,7 +45,8 @@ fields of discriminant `\le 50`. [40, x^2 - 10], [41, x^2 - x - 10], [44, x^2 - 11]] - sage: [ d for d in range(5,50) if (is_squarefree(d) and d%4 == 1) or (d%4 == 0 and is_squarefree(d/4)) ] + sage: [d for d in range(5,50) + ....: if (is_squarefree(d) and d%4 == 1) or (d%4 == 0 and is_squarefree(d/4))] [5, 8, 12, 13, 17, 20, 21, 24, 28, 29, 33, 37, 40, 41, 44] Next, we compute all totally real quintic fields of discriminant `\le 10^5`:: @@ -116,15 +117,15 @@ from sage.rings.number_field.totallyreal_data cimport tr_data cpdef double odlyzko_bound_totallyreal(int n): r""" This function returns the unconditional Odlyzko bound for the root - discriminant of a totally real number field of degree n. + discriminant of a totally real number field of degree `n`. .. NOTE:: - The bounds for n > 50 are not necessarily optimal. + The bounds for `n > 50` are not necessarily optimal. INPUT: - - n (integer) the degree + - ``n`` -- (integer) the degree OUTPUT: @@ -132,7 +133,8 @@ cpdef double odlyzko_bound_totallyreal(int n): EXAMPLES:: - sage: [sage.rings.number_field.totallyreal.odlyzko_bound_totallyreal(n) for n in range(1,5)] + sage: from sage.rings.number_field.totallyreal import odlyzko_bound_totallyreal + sage: [odlyzko_bound_totallyreal(n) for n in range(1, 5)] [1.0, 2.223, 3.61, 5.067] AUTHORS: @@ -164,7 +166,7 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False just_print=False, return_pari_objects=True): r""" - This function enumerates primitive totally real fields of degree + Enumerate primitive totally real fields of degree `n>1` with discriminant `d \leq B`; optionally one can specify the first few coefficients, where the sequence `a` corresponds to @@ -183,26 +185,26 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False - ``n`` -- (integer) the degree - ``B`` -- (integer) the discriminant bound - - ``a`` -- (list, default: []) the coefficient list to begin with + - ``a`` -- (list, default: ``[]``) the coefficient list to begin with - ``verbose`` -- (integer or string, default: 0) if ``verbose == 1`` (or ``2``), then print to the screen (really) verbosely; if verbose is a string, then print verbosely to the file specified by verbose. - - ``return_seqs`` -- (boolean, default False) If ``True``, then return + - ``return_seqs`` -- (boolean, default ``False``) If ``True``, then return the polynomials as sequences (for easier exporting to a file). - - ``phc`` -- boolean or integer (default: False) - - ``keep_fields`` -- (boolean or integer, default: False) If - ``keep_fields`` is True, then keep fields up to ``B*log(B)``; if + - ``phc`` -- boolean or integer (default: ``False``) + - ``keep_fields`` -- (boolean or integer, default: ``False``) If + ``keep_fields`` is ``True``, then keep fields up to ``B*log(B)``; if ``keep_fields`` is an integer, then keep fields up to that integer. - ``t_2`` -- (boolean or integer, default: False) If ``t_2 = T``, then keep only polynomials with t_2 norm >= T. - - ``just_print`` -- (boolean, default: False): if ``just_print`` is not - False, instead of creating a sorted list of totally real number + - ``just_print`` -- (boolean, default: ``False``): if ``just_print`` is not + ``False``, instead of creating a sorted list of totally real number fields, we simply write each totally real field we find to the file whose filename is given by ``just_print``. In this case, we don't return anything. - - ``return_pari_objects`` -- (boolean, default: True) if + - ``return_pari_objects`` -- (boolean, default: ``True``) if both ``return_seqs`` and ``return_pari_objects`` are ``False`` then - it returns the elements as Sage objects; otherwise it returns pari + it returns the elements as Sage objects; otherwise it returns PARI objects. OUTPUT: @@ -479,7 +481,7 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False def weed_fields(S, Py_ssize_t lenS=0): r""" Function used internally by the :func:`~enumerate_totallyreal_fields_prim` - routine. (Weeds the fields listed by [discriminant, polynomial] + routine. (Weeds the fields listed by ``[discriminant, polynomial]`` for isomorphism classes.) Returns the size of the resulting list. EXAMPLES:: diff --git a/src/sage/rings/number_field/totallyreal_data.pyx b/src/sage/rings/number_field/totallyreal_data.pyx index adc52e6cfab..c0d865db02c 100644 --- a/src/sage/rings/number_field/totallyreal_data.pyx +++ b/src/sage/rings/number_field/totallyreal_data.pyx @@ -51,9 +51,9 @@ from libc.math cimport lrint, floor, ceil, fabs, round def hermite_constant(n): r""" - This function returns the nth Hermite constant + Return the `n`-th Hermite constant. - The nth Hermite constant (typically denoted `\gamma_n`), is defined + The `n`-th Hermite constant (typically denoted `\gamma_n`), is defined to be .. MATH:: @@ -67,11 +67,11 @@ def hermite_constant(n): INPUT: - - n -- integer + - ``n`` -- integer OUTPUT: - - (an upper bound for) the Hermite constant gamma_n + (an upper bound for) the Hermite constant `\gamma_n` EXAMPLES:: @@ -197,12 +197,14 @@ cdef void newton_in_intervals(int *f, int *df, int n, double *beta, cpdef lagrange_degree_3(int n, int an1, int an2, int an3): r""" Private function. Solves the equations which arise in the Lagrange multiplier - for degree 3: for each 1 <= r <= n-2, we solve + for degree 3: for each `1 \leq r \leq n-2`, we solve - r*x^i + (n-1-r)*y^i + z^i = s_i (i = 1,2,3) + .. MATH:: + + r*x^i + (n-1-r)\cdot y^i + z^i = s_i \quad (i = 1,2,3) - where the s_i are the power sums determined by the coefficients a. - We output the largest value of z which occurs. + where the `s_i` are the power sums determined by the coefficients `a`. + We output the largest value of `z` which occurs. We use a precomputed elimination ideal. EXAMPLES:: @@ -323,7 +325,7 @@ for i from 0 <= i < 46: def int_has_small_square_divisor(sage.rings.integer.Integer d): r""" - Returns the largest a such that a^2 divides d and a has prime divisors < 200. + Return the largest `a` such that `a^2` divides `d` and `a` has prime divisors `< 200`. EXAMPLES:: @@ -452,7 +454,7 @@ cdef class tr_data: We do not give a complete description here. For more information, see the attached functions; all of these are used internally by the - functions in totallyreal.py, so see that file for examples and + functions in :mod:`.totallyreal`, so see that file for examples and further documentation. """ @@ -584,9 +586,9 @@ cdef class tr_data: def increment(self, verbose=False, haltk=0, phc=False): r""" - This function 'increments' the totally real data to the next + 'Increment' the totally real data to the next value which satisfies the bounds essentially given by Rolle's - theorem, and returns the next polynomial as a sequence of + theorem, and return the next polynomial as a sequence of integers. The default or usual case just increments the constant @@ -598,10 +600,10 @@ cdef class tr_data: INPUT: - - verbose -- boolean to print verbosely computational details - - haltk -- integer, the level at which to halt the inductive + - ``verbose`` -- boolean to print verbosely computational details + - ``haltk`` -- integer, the level at which to halt the inductive coefficient bounds - - phc -- boolean, if PHCPACK is available, use it when k == n-5 to + - ``phc`` -- boolean, if PHCPACK is available, use it when `k = n-5` to compute an improved Lagrange multiplier bound OUTPUT: @@ -912,7 +914,7 @@ cdef class tr_data: def printa(self): """ - Print relevant data for self. + Print relevant data for ``self``. EXAMPLES:: diff --git a/src/sage/rings/number_field/totallyreal_phc.py b/src/sage/rings/number_field/totallyreal_phc.py index 59467e5af40..f53358ad7dd 100644 --- a/src/sage/rings/number_field/totallyreal_phc.py +++ b/src/sage/rings/number_field/totallyreal_phc.py @@ -3,8 +3,7 @@ AUTHORS: - -- John Voight (2007-10-10): - * Zeroth attempt. +- John Voight (2007-10-10): Zeroth attempt. """ # **************************************************************************** @@ -23,14 +22,14 @@ def coefficients_to_power_sums(n, m, a): r""" - Takes the list a, representing a list of initial coefficients of - a (monic) polynomial of degree n, and returns the power sums - of the roots of f up to (m-1)th powers. + Take the list ``a``, representing a list of initial coefficients of + a (monic) polynomial of degree `n`, and return the power sums + of the roots of `f` up to `(m-1)`-th powers. INPUT: - - n -- integer, the degree - - a -- list of integers, the coefficients + - ``n`` -- integer, the degree + - ``a`` -- list of integers, the coefficients OUTPUT: diff --git a/src/sage/rings/number_field/totallyreal_rel.py b/src/sage/rings/number_field/totallyreal_rel.py index 07477c46f8f..20abe5ba445 100644 --- a/src/sage/rings/number_field/totallyreal_rel.py +++ b/src/sage/rings/number_field/totallyreal_rel.py @@ -13,7 +13,7 @@ :: sage: ZZx = ZZ['x'] - sage: F. = NumberField(x^2-2) + sage: F. = NumberField(x^2 - 2) sage: enumerate_totallyreal_fields_rel(F, 2, 2000) [[1600, x^4 - 6*x^2 + 4, xF^2 + xF - 1]] @@ -24,7 +24,7 @@ :: - sage: F. = NumberField(x^2-5) + sage: F. = NumberField(x^2 - 5) sage: ls = enumerate_totallyreal_fields_rel(F, 2, 10^4) sage: ls # random (the second factor is platform-dependent) [[725, x^4 - x^3 - 3*x^2 + x + 1, xF^2 + (-1/2*t - 7/2)*xF + 1], @@ -111,30 +111,32 @@ def integral_elements_in_box(K, C): r""" Return all integral elements of the totally real field `K` whose embeddings lie *numerically* within the bounds specified by the - list `C`. The output is architecture dependent, and one may want - to expand the bounds that define C by some epsilon. + list ``C``. The output is architecture dependent, and one may want + to expand the bounds that define ``C`` by some epsilon. INPUT: - - `K` -- a totally real number field - - `C` -- a list [[lower, upper], ...] of lower and upper bounds, + - ``K`` -- a totally real number field + - ``C`` -- a list ``[[lower, upper], ...]`` of lower and upper bounds, for each embedding EXAMPLES:: sage: x = polygen(QQ) - sage: K. = NumberField(x^2-2) + sage: K. = NumberField(x^2 - 2) sage: eps = 10e-6 - sage: C = [[0-eps,5+eps],[0-eps,10+eps]] + sage: C = [[0-eps, 5+eps], [0-eps, 10+eps]] sage: ls = sage.rings.number_field.totallyreal_rel.integral_elements_in_box(K, C) - sage: sorted([ a.trace() for a in ls ]) + sage: sorted(a.trace() for a in ls) [0, 2, 4, 4, 4, 6, 6, 6, 6, 8, 8, 8, 10, 10, 10, 10, 12, 12, 14] sage: len(ls) 19 sage: v = sage.rings.number_field.totallyreal_rel.integral_elements_in_box(K, C) sage: sorted(v) - [0, -alpha + 2, 1, -alpha + 3, 2, 3, alpha + 2, 4, alpha + 3, 5, alpha + 4, 2*alpha + 3, alpha + 5, 2*alpha + 4, alpha + 6, 2*alpha + 5, 2*alpha + 6, 3*alpha + 5, 2*alpha + 7] + [0, -alpha + 2, 1, -alpha + 3, 2, 3, alpha + 2, 4, alpha + 3, 5, alpha + 4, + 2*alpha + 3, alpha + 5, 2*alpha + 4, alpha + 6, 2*alpha + 5, 2*alpha + 6, + 3*alpha + 5, 2*alpha + 7] A cubic field:: @@ -148,7 +150,8 @@ def integral_elements_in_box(K, C): below, and sometimes it isn't):: sage: sorted(v) - [-1/2*a + 2, 1/4*a^2 + 1/2*a, 0, 1, 2, 3, 4,...-1/4*a^2 - 1/2*a + 5, 1/2*a + 3, -1/4*a^2 + 5] + [-1/2*a + 2, 1/4*a^2 + 1/2*a, 0, 1, 2, 3, 4,...-1/4*a^2 - 1/2*a + 5, + 1/2*a + 3, -1/4*a^2 + 5] """ d = K.degree() Foo = K.real_embeddings() @@ -243,18 +246,18 @@ def __init__(self, F, m, B, a=None): - ``F`` -- number field, the base field - ``m`` -- integer, the relative degree - ``B`` -- integer, the discriminant bound - - ``a`` -- list (default: []), the coefficient list to begin with, + - ``a`` -- list (default: ``[]``), the coefficient list to begin with, corresponding to ``a[len(a)]*x^n + ... + a[0]x^(n-len(a))``. OUTPUT: the data initialized to begin enumeration of totally real fields - with base field F, degree n, discriminant bounded by B, and starting - with coefficients a. + with base field `F`, degree `n`, discriminant bounded by `B`, and starting + with coefficients `a`. EXAMPLES:: - sage: F. = NumberField(x^2-2) + sage: F. = NumberField(x^2 - 2) sage: T = sage.rings.number_field.totallyreal_rel.tr_data_rel(F, 2, 2000) """ if a is None: # don't make the stupid noob mistake of putting a=[] @@ -352,10 +355,10 @@ def __init__(self, F, m, B, a=None): def incr(self, f_out, verbose=False, haltk=0): r""" - This function 'increments' the totally real data to the next + 'Increment' the totally real data to the next value which satisfies the bounds essentially given by Rolle's - theorem, and returns the next polynomial in the sequence - f_out. + theorem, and return the next polynomial in the sequence + ``f_out``. The default or usual case just increments the constant coefficient; then inductively, if this is outside of the @@ -368,7 +371,7 @@ def incr(self, f_out, verbose=False, haltk=0): - ``f_out`` -- an integer sequence, to be written with the coefficients of the next polynomial - - ``verbose`` -- boolean or nonnegative integer (default: False) + - ``verbose`` -- boolean or nonnegative integer (default: ``False``) print verbosely computational details. It prints extra information if ``verbose`` is set to ``2`` or more - ``haltk`` -- integer, the level at which to halt the inductive @@ -662,26 +665,26 @@ def enumerate_totallyreal_fields_rel(F, m, B, a=[], verbose=0, - ``F`` -- number field, the base field - ``m`` -- integer, the degree - ``B`` -- integer, the discriminant bound - - ``a`` -- list (default: []), the coefficient list to begin with + - ``a`` -- list (default: ``[]``), the coefficient list to begin with - ``verbose`` -- boolean or nonnegative integer or string (default: 0) give a verbose description of the computations being performed. If ``verbose`` is set to ``2`` or more then it outputs some extra information. If ``verbose`` is a string then it outputs to a file specified by ``verbose`` - - ``return_seqs`` -- (boolean, default False) If ``True``, then return + - ``return_seqs`` -- (boolean, default ``False``) If ``True``, then return the polynomials as sequences (for easier exporting to a file). This also returns a list of four numbers, as explained in the OUTPUT section below. - - ``return_pari_objects`` -- (boolean, default: True) if + - ``return_pari_objects`` -- (boolean, default: ``True``) if both ``return_seqs`` and ``return_pari_objects`` are ``False`` then - it returns the elements as Sage objects; otherwise it returns pari + it returns the elements as Sage objects; otherwise it returns PARI objects. OUTPUT: - the list of fields with entries ``[d,fabs,f]``, where ``d`` is the discriminant, ``fabs`` is an absolute defining polynomial, and ``f`` - is a defining polynomial relative to ``F``, sorted by discriminant. + is a defining polynomial relative to `F`, sorted by discriminant. - if ``return_seqs`` is ``True``, then the first field of the list is a list containing the count of four items as explained below @@ -691,12 +694,12 @@ def enumerate_totallyreal_fields_rel(F, m, B, a=[], verbose=0, discriminant having a large enough square divisor - the third entry is the number of irreducible polynomials - the fourth entry is the number of irreducible polynomials with - discriminant at most ``B`` + discriminant at most `B` EXAMPLES:: sage: ZZx = ZZ['x'] - sage: F. = NumberField(x^2-2) + sage: F. = NumberField(x^2 - 2) sage: enumerate_totallyreal_fields_rel(F, 1, 2000) [[1, [-2, 0, 1], xF - 1]] sage: enumerate_totallyreal_fields_rel(F, 2, 2000) @@ -902,7 +905,7 @@ def enumerate_totallyreal_fields_rel(F, m, B, a=[], verbose=0, def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False, return_pari_objects=True): r""" - Enumerates *all* totally real fields of degree ``n`` with discriminant + Enumerate *all* totally real fields of degree ``n`` with discriminant at most ``B``, primitive or otherwise. INPUT: @@ -911,16 +914,16 @@ def enumerate_totallyreal_fields_all(n, B, verbose=0, return_seqs=False, - ``B`` -- integer, the discriminant bound - ``verbose`` -- boolean or nonnegative integer or string (default: 0) give a verbose description of the computations being performed. If - ``verbose`` is set to ``2`` or more then it outputs some extra - information. If ``verbose`` is a string then it outputs to a file + ``verbose`` is set to ``2`` or more, it outputs some extra + information. If ``verbose`` is a string, it outputs to a file specified by ``verbose`` - - ``return_seqs`` -- (boolean, default False) If ``True``, then return + - ``return_seqs`` -- (boolean, default ``False``) If ``True``, then return the polynomials as sequences (for easier exporting to a file). This also returns a list of four numbers, as explained in the OUTPUT section below. - ``return_pari_objects`` -- (boolean, default: True) if both ``return_seqs`` and ``return_pari_objects`` are ``False`` then it - returns the elements as Sage objects; otherwise it returns pari + returns the elements as Sage objects; otherwise it returns PARI objects. EXAMPLES:: diff --git a/src/sage/rings/number_field/unit_group.py b/src/sage/rings/number_field/unit_group.py index d8f9b7a9c2f..42c3933219b 100644 --- a/src/sage/rings/number_field/unit_group.py +++ b/src/sage/rings/number_field/unit_group.py @@ -4,9 +4,10 @@ EXAMPLES:: sage: x = polygen(QQ) - sage: K. = NumberField(x^4-8*x^2+36) + sage: K. = NumberField(x^4 - 8*x^2 + 36) sage: UK = UnitGroup(K); UK - Unit group with structure C4 x Z of Number Field in a with defining polynomial x^4 - 8*x^2 + 36 + Unit group with structure C4 x Z of + Number Field in a with defining polynomial x^4 - 8*x^2 + 36 The first generator is a primitive root of unity in the field:: @@ -36,12 +37,12 @@ 1 sage: UK(-1) u0^2 - sage: [UK(u) for u in (x^4-1).roots(K, multiplicities=False)] + sage: [UK(u) for u in (x^4 - 1).roots(K, multiplicities=False)] [1, u0^2, u0, u0^3] sage: UK.fundamental_units() # random [1/24*a^3 + 1/4*a^2 - 1/12*a - 1] - sage: torsion_gen = UK.torsion_generator(); torsion_gen + sage: torsion_gen = UK.torsion_generator(); torsion_gen u0 sage: torsion_gen.value() 1/12*a^3 - 1/6*a @@ -63,20 +64,22 @@ sage: all(UK.log(u^k) == (0,k) for k in range(10)) True - sage: K. = NumberField(x^5-2,'a') + sage: K. = NumberField(x^5 - 2,'a') sage: UK = UnitGroup(K) sage: UK.rank() 2 sage: UK.fundamental_units() [a^3 + a^2 - 1, a - 1] -S-unit groups may be constructed, where S is a set of primes:: +`S`-unit groups may be constructed, where `S` is a set of primes:: - sage: K. = NumberField(x^6+2) + sage: K. = NumberField(x^6 + 2) sage: S = K.ideal(3).prime_factors(); S [Fractional ideal (3, a + 1), Fractional ideal (3, a - 1)] sage: SUK = UnitGroup(K,S=tuple(S)); SUK - S-unit group with structure C2 x Z x Z x Z x Z of Number Field in a with defining polynomial x^6 + 2 with S = (Fractional ideal (3, a + 1), Fractional ideal (3, a - 1)) + S-unit group with structure C2 x Z x Z x Z x Z of + Number Field in a with defining polynomial x^6 + 2 + with S = (Fractional ideal (3, a + 1), Fractional ideal (3, a - 1)) sage: SUK.primes() (Fractional ideal (3, a + 1), Fractional ideal (3, a - 1)) sage: SUK.rank() @@ -94,7 +97,8 @@ sage: L. = NumberField([x^2 + x + 1, x^4 + 1]) sage: UL = L.unit_group(); UL - Unit group with structure C24 x Z x Z x Z of Number Field in a with defining polynomial x^2 + x + 1 over its base field + Unit group with structure C24 x Z x Z x Z of + Number Field in a with defining polynomial x^2 + x + 1 over its base field sage: UL.gens_values() # random [-b^3*a - b^3, -b^3*a + b, (-b^3 - b^2 - b)*a - b - 1, (-b^3 - 1)*a - b^2 + b - 1] sage: UL.zeta_order() @@ -132,7 +136,8 @@ sage: PF. = F[] sage: K. = F.extension(Y^2 - (1 + a)*(a + b)*a*b) sage: K.unit_group() - Unit group with structure C2 x Z x Z x Z x Z x Z x Z x Z of Number Field in c with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field + Unit group with structure C2 x Z x Z x Z x Z x Z x Z x Z of Number Field in c + with defining polynomial Y^2 + (-2*b - 3)*a - 2*b - 6 over its base field TESTS:: @@ -169,7 +174,7 @@ class UnitGroup(AbelianGroupWithValues_class): """ - The unit group or an S-unit group of a number field. + The unit group or an `S`-unit group of a number field. TESTS:: @@ -229,17 +234,17 @@ def __init__(self, number_field, proof=True, S=None): INPUT: - - ``number_field`` - a number field - - ``proof`` - boolean (default True): proof flag - - ``S`` - tuple of prime ideals, or an ideal, or a single + - ``number_field`` -- a number field + - ``proof`` -- boolean (default ``True``): proof flag + - ``S`` -- tuple of prime ideals, or an ideal, or a single ideal or element from which an ideal can be constructed, in - which case the support is used. If None, the global unit - group is constructed; otherwise, the S-unit group is + which case the support is used. If ``None``, the global unit + group is constructed; otherwise, the `S`-unit group is constructed. - The proof flag is passed to pari via the ``pari_bnf()`` function + The ``proof`` flag is passed to PARI via the :pari:`pari_bnf` function which computes the unit group. See the documentation for the - number_field module. + ``number_field`` module. EXAMPLES:: @@ -268,7 +273,8 @@ def __init__(self, number_field, proof=True, S=None): sage: UK.gens_values() # random [-z^11, z^5 + z^3, z^6 + z^5, z^9 + z^7 + z^5, z^9 + z^5 + z^4 + 1, z^5 + z] sage: SUK = UnitGroup(K,S=2); SUK - S-unit group with structure C26 x Z x Z x Z x Z x Z x Z of Cyclotomic Field of order 13 and degree 12 with S = (Fractional ideal (2),) + S-unit group with structure C26 x Z x Z x Z x Z x Z x Z of + Cyclotomic Field of order 13 and degree 12 with S = (Fractional ideal (2),) TESTS: @@ -278,9 +284,12 @@ def __init__(self, number_field, proof=True, S=None): sage: K. = NumberField(7/9*x^3 + 7/3*x^2 - 56*x + 123) sage: K.unit_group() - Unit group with structure C2 x Z x Z of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123 + Unit group with structure C2 x Z x Z of + Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123 sage: UnitGroup(K, S=tuple(K.primes_above(7))) - S-unit group with structure C2 x Z x Z x Z of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123 with S = (Fractional ideal (...),) + S-unit group with structure C2 x Z x Z x Z of + Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123 + with S = (Fractional ideal (...),) sage: K.primes_above(7)[0] in (7/225*a^2 - 7/75*a - 42/25, 28/225*a^2 + 77/75*a - 133/25) True @@ -416,7 +425,7 @@ def rank(self): sage: K. = CyclotomicField(13) sage: UnitGroup(K).rank() 5 - sage: SUK = UnitGroup(K,S=2); SUK.rank() + sage: SUK = UnitGroup(K, S=2); SUK.rank() 6 """ return self.ngens()-1 @@ -433,8 +442,10 @@ def _repr_(self): Unit group with structure C2 x Z of Number Field in a with defining polynomial x^3 - 2 sage: U._repr_() 'Unit group with structure C2 x Z of Number Field in a with defining polynomial x^3 - 2' - sage: UnitGroup(NumberField(x^3 - 2, 'a'),S=2) - S-unit group with structure C2 x Z x Z of Number Field in a with defining polynomial x^3 - 2 with S = (Fractional ideal (a),) + sage: UnitGroup(NumberField(x^3 - 2, 'a'), S=2) + S-unit group with structure C2 x Z x Z of + Number Field in a with defining polynomial x^3 - 2 + with S = (Fractional ideal (a),) """ if self.__S: return 'S-unit group with structure %s of %s with S = %s'%( @@ -466,7 +477,7 @@ def roots_of_unity(self): EXAMPLES:: sage: x = polygen(QQ) - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: U = UnitGroup(K) sage: zs = U.roots_of_unity(); zs [b, -1, -b, 1] @@ -509,7 +520,7 @@ def zeta_order(self): def zeta(self, n=2, all=False): """ - Return one, or a list of all, primitive n-th root of unity in this unit group. + Return one, or a list of all, primitive `n`-th root of unity in this unit group. EXAMPLES:: @@ -532,7 +543,7 @@ def zeta(self, n=2, all=False): ValueError: n (=4) does not divide order of generator sage: r. = QQ[] - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: U = UnitGroup(K) sage: U.zeta(4) b @@ -542,7 +553,7 @@ def zeta(self, n=2, all=False): Traceback (most recent call last): ... ValueError: n (=3) does not divide order of generator - sage: U.zeta(3,all=True) + sage: U.zeta(3, all=True) [] """ @@ -580,7 +591,8 @@ def number_field(self): EXAMPLES:: sage: U = UnitGroup(QuadraticField(-23, 'w')); U - Unit group with structure C2 of Number Field in w with defining polynomial x^2 + 23 with w = 4.795831523312720?*I + Unit group with structure C2 of + Number Field in w with defining polynomial x^2 + 23 with w = 4.795831523312720?*I sage: U.number_field() Number Field in w with defining polynomial x^2 + 23 with w = 4.795831523312720?*I """ @@ -596,7 +608,9 @@ def primes(self): sage: S = tuple(K.ideal(3).prime_factors()); S (Fractional ideal (3, 1/2*a - 1/2), Fractional ideal (3, 1/2*a + 1/2)) sage: U = UnitGroup(K,S=tuple(S)); U - S-unit group with structure C2 x Z x Z of Number Field in a with defining polynomial x^2 + 23 with a = 4.795831523312720?*I with S = (Fractional ideal (3, 1/2*a - 1/2), Fractional ideal (3, 1/2*a + 1/2)) + S-unit group with structure C2 x Z x Z of + Number Field in a with defining polynomial x^2 + 23 with a = 4.795831523312720?*I + with S = (Fractional ideal (3, 1/2*a - 1/2), Fractional ideal (3, 1/2*a + 1/2)) sage: U.primes() == S True """ @@ -604,16 +618,16 @@ def primes(self): def log(self, u): r""" - Return the exponents of the unit ``u`` with respect to group generators. + Return the exponents of the unit `u` with respect to group generators. INPUT: - ``u`` -- Any object from which an element of the unit group's number field `K` may be constructed; an error is raised if an element of `K` - cannot be constructed from u, or if the element constructed is not a + cannot be constructed from `u`, or if the element constructed is not a unit. - OUTPUT: a list of integers giving the exponents of ``u`` with + OUTPUT: a list of integers giving the exponents of `u` with respect to the unit group's basis. EXAMPLES:: @@ -630,16 +644,18 @@ def log(self, u): (0, 0, 0, 0, 0, 1)] sage: vec = [65,6,7,8,9,10] sage: unit = UK.exp(vec); unit # random - -253576*z^11 + 7003*z^10 - 395532*z^9 - 35275*z^8 - 500326*z^7 - 35275*z^6 - 395532*z^5 + 7003*z^4 - 253576*z^3 - 59925*z - 59925 + -253576*z^11 + 7003*z^10 - 395532*z^9 - 35275*z^8 - 500326*z^7 - 35275*z^6 + - 395532*z^5 + 7003*z^4 - 253576*z^3 - 59925*z - 59925 sage: UK.log(unit) (13, 6, 7, 8, 9, 10) An S-unit example:: - sage: SUK = UnitGroup(K,S=2) + sage: SUK = UnitGroup(K, S=2) sage: v = (3,1,4,1,5,9,2) sage: u = SUK.exp(v); u - 8732*z^11 - 15496*z^10 - 51840*z^9 - 68804*z^8 - 51840*z^7 - 15496*z^6 + 8732*z^5 - 34216*z^3 - 64312*z^2 - 64312*z - 34216 + 8732*z^11 - 15496*z^10 - 51840*z^9 - 68804*z^8 - 51840*z^7 - 15496*z^6 + + 8732*z^5 - 34216*z^3 - 64312*z^2 - 64312*z - 34216 sage: SUK.log(u) (3, 1, 4, 1, 5, 9, 2) sage: SUK.log(u) == v @@ -655,10 +671,10 @@ def exp(self, exponents): - ``u`` -- Any object from which an element of the unit group's number field `K` may be constructed; an error is - raised if an element of `K` cannot be constructed from u, or + raised if an element of `K` cannot be constructed from `u`, or if the element constructed is not a unit. - OUTPUT: a list of integers giving the exponents of ``u`` with + OUTPUT: a list of integers giving the exponents of `u` with respect to the unit group's basis. EXAMPLES:: @@ -686,7 +702,8 @@ def exp(self, exponents): sage: SUK = UnitGroup(K,S=2) sage: v = (3,1,4,1,5,9,2) sage: u = SUK.exp(v); u - 8732*z^11 - 15496*z^10 - 51840*z^9 - 68804*z^8 - 51840*z^7 - 15496*z^6 + 8732*z^5 - 34216*z^3 - 64312*z^2 - 64312*z - 34216 + 8732*z^11 - 15496*z^10 - 51840*z^9 - 68804*z^8 - 51840*z^7 - 15496*z^6 + + 8732*z^5 - 34216*z^3 - 64312*z^2 - 64312*z - 34216 sage: SUK.log(u) (3, 1, 4, 1, 5, 9, 2) sage: SUK.log(u) == v diff --git a/src/sage/rings/numbers_abc.py b/src/sage/rings/numbers_abc.py index 478a0b36408..6bbcddccf40 100644 --- a/src/sage/rings/numbers_abc.py +++ b/src/sage/rings/numbers_abc.py @@ -57,10 +57,10 @@ def register_sage_classes(): Because we do this, NumPy's ``isscalar()`` recognizes Sage types:: - sage: from numpy import isscalar - sage: isscalar(3.141) + sage: from numpy import isscalar # optional - numpy + sage: isscalar(3.141) # optional - numpy True - sage: isscalar(4/17) + sage: isscalar(4/17) # optional - numpy True """ from sage.misc.superseded import deprecation diff --git a/src/sage/rings/padics/CR_template.pxi b/src/sage/rings/padics/CR_template.pxi index 73f87ed27e9..cb57bb2cb48 100644 --- a/src/sage/rings/padics/CR_template.pxi +++ b/src/sage/rings/padics/CR_template.pxi @@ -2,14 +2,14 @@ Capped relative template for complete discrete valuation rings and their fraction fields In order to use this template you need to write a linkage file and gluing file. -For an example see mpz_linkage.pxi (linkage file) and padic_capped_relative_element.pyx (gluing file). +For an example see ``mpz_linkage.pxi`` (linkage file) and ``padic_capped_relative_element.pyx`` (gluing file). -The linkage file implements a common API that is then used in the class CRElement defined here. -See the documentation of mpz_linkage.pxi for the functions needed. +The linkage file implements a common API that is then used in the class :class:`CRElement` defined here. +See the documentation of ``mpz_linkage.pxi`` for the functions needed. The gluing file does the following: -- ctypedef's celement to be the appropriate type (e.g. mpz_t) +- ``ctypedef``'s ``celement`` to be the appropriate type (e.g. ``mpz_t``) - includes the linkage file - includes this template - defines a concrete class inheriting from ``CRElement``, and implements @@ -423,7 +423,7 @@ cdef class CRElement(pAdicTemplateElement): def __invert__(self): r""" - Returns the multiplicative inverse of this element. + Return the multiplicative inverse of this element. .. NOTE:: @@ -882,7 +882,7 @@ cdef class CRElement(pAdicTemplateElement): def add_bigoh(self, absprec): """ - Returns a new element with absolute precision decreased to + Return a new element with absolute precision decreased to ``absprec``. INPUT: @@ -891,7 +891,7 @@ cdef class CRElement(pAdicTemplateElement): OUTPUT: - an equal element with precision set to the minimum of ``self's`` + an equal element with precision set to the minimum of ``self``'s precision and ``absprec`` EXAMPLES:: @@ -959,7 +959,7 @@ cdef class CRElement(pAdicTemplateElement): cpdef bint _is_exact_zero(self) except -1: """ - Returns true if this element is exactly zero. + Return ``True`` if this element is exactly zero. EXAMPLES:: @@ -975,7 +975,7 @@ cdef class CRElement(pAdicTemplateElement): cpdef bint _is_inexact_zero(self) except -1: """ - Returns True if this element is indistinguishable from zero + Return ``True`` if this element is indistinguishable from zero but has finite precision. EXAMPLES:: @@ -992,10 +992,10 @@ cdef class CRElement(pAdicTemplateElement): def is_zero(self, absprec = None): r""" - Determines whether this element is zero modulo + Determine whether this element is zero modulo `\pi^{\mbox{absprec}}`. - If ``absprec is None``, returns ``True`` if this element is + If ``absprec`` is ``None``, returns ``True`` if this element is indistinguishable from zero. INPUT: @@ -1037,7 +1037,7 @@ cdef class CRElement(pAdicTemplateElement): def __bool__(self): """ - Returns True if self is distinguishable from zero. + Return ``True`` if ``self`` is distinguishable from zero. For most applications, explicitly specifying the power of p modulo which the element is supposed to be nonzero is @@ -1053,10 +1053,10 @@ cdef class CRElement(pAdicTemplateElement): def is_equal_to(self, _right, absprec=None): r""" - Returns whether self is equal to right modulo + Return whether ``self`` is equal to ``right`` modulo `\pi^{\mbox{absprec}}`. - If ``absprec is None``, returns True if self and right are + If ``absprec`` is ``None``, returns ``True`` if ``self`` and ``right`` are equal to the minimum of their precisions. INPUT: @@ -1390,10 +1390,10 @@ cdef class CRElement(pAdicTemplateElement): def precision_relative(self): """ - Returns the relative precision of this element. + Return the relative precision of this element. This is the power of the maximal ideal modulo which the unit - part of self is defined. + part of ``self`` is defined. EXAMPLES:: @@ -1417,7 +1417,7 @@ cdef class CRElement(pAdicTemplateElement): cpdef pAdicTemplateElement unit_part(self): r""" - Returns `u`, where this element is `\pi^v u`. + Return `u`, where this element is `\pi^v u`. EXAMPLES:: @@ -1461,7 +1461,7 @@ cdef class CRElement(pAdicTemplateElement): cdef long valuation_c(self): """ - Returns the valuation of this element. + Return the valuation of this element. If self is an exact zero, returns ``maxordp``, which is defined as ``(1L << (sizeof(long) * 8 - 2))-1``. @@ -1480,16 +1480,16 @@ cdef class CRElement(pAdicTemplateElement): cpdef val_unit(self, p=None): """ - Returns a pair ``(self.valuation(), self.unit_part())``. + Return a pair ``(self.valuation(), self.unit_part())``. INPUT: - - ``p`` -- a prime (default: ``None``). If specified, will make sure that p==self.parent().prime() + - ``p`` -- a prime (default: ``None``). If specified, will make sure that ``p == self.parent().prime()`` .. NOTE:: The optional argument ``p`` is used for consistency with the - valuation methods on integer and rational. + valuation methods on integers and rationals. EXAMPLES:: @@ -1707,7 +1707,7 @@ cdef class pAdicConvert_CR_ZZ(RingMap): returns the smallest non-negative integer approximation to its input which is accurate up to the precision. - Raises a ``ValueError``, if the input is not in the closure of the image of + Raises a :class:`ValueError`, if the input is not in the closure of the image of the integers. EXAMPLES:: @@ -2113,7 +2113,7 @@ cdef class pAdicConvert_QQ_CR(Morphism): def section(self): """ - Returns the map back to the rationals that returns the smallest + Return the map back to the rationals that returns the smallest non-negative integer approximation to its input which is accurate up to the precision. @@ -2130,8 +2130,8 @@ cdef class pAdicConvert_QQ_CR(Morphism): return self._section cdef class pAdicCoercion_CR_frac_field(RingHomomorphism): - """ - The canonical inclusion of Zq into its fraction field. + r""" + The canonical inclusion of `\ZZ_q` into its fraction field. EXAMPLES:: @@ -2246,7 +2246,7 @@ cdef class pAdicCoercion_CR_frac_field(RingHomomorphism): def section(self): """ - Returns a map back to the ring that converts elements of + Return a map back to the ring that converts elements of non-negative valuation. EXAMPLES:: @@ -2356,8 +2356,8 @@ cdef class pAdicCoercion_CR_frac_field(RingHomomorphism): cdef class pAdicConvert_CR_frac_field(Morphism): - """ - The section of the inclusion from `\ZZ_q`` to its fraction field. + r""" + The section of the inclusion from `\ZZ_q` to its fraction field. EXAMPLES:: diff --git a/src/sage/rings/padics/FM_template.pxi b/src/sage/rings/padics/FM_template.pxi index df7bd8bdf38..ea7d4055660 100644 --- a/src/sage/rings/padics/FM_template.pxi +++ b/src/sage/rings/padics/FM_template.pxi @@ -2,19 +2,19 @@ Fixed modulus template for complete discrete valuation rings In order to use this template you need to write a linkage file and -gluing file. For an example see mpz_linkage.pxi (linkage file) and -padic_fixed_modulus_element.pyx (gluing file). +gluing file. For an example see ``mpz_linkage.pxi`` (linkage file) and +``padic_fixed_modulus_element.pyx`` (gluing file). The linkage file implements a common API that is then used in the -class FMElement defined here. See sage/libs/linkages/padics/API.pxi +class :class:`FMElement` defined here. See ``sage/libs/linkages/padics/API.pxi`` for the functions needed. The gluing file does the following: -- ctypedef's celement to be the appropriate type (e.g. mpz_t) +- ``ctypedef``'s ``celement`` to be the appropriate type (e.g. ``mpz_t``) - includes the linkage file - includes this template -- defines a concrete class inheriting from FMElement, and implements +- defines a concrete class inheriting from :class:`FMElement`, and implements any desired extra methods AUTHORS: @@ -463,7 +463,7 @@ cdef class FMElement(pAdicTemplateElement): def add_bigoh(self, absprec): """ - Returns a new element truncated modulo `\pi^{\mbox{absprec}}`. + Return a new element truncated modulo `\pi^{\mbox{absprec}}`. INPUT: @@ -471,7 +471,7 @@ cdef class FMElement(pAdicTemplateElement): OUTPUT: - - a new element truncated modulo `\pi^{\mbox{absprec}}`. + a new element truncated modulo `\pi^{\mbox{absprec}}`. EXAMPLES:: @@ -525,7 +525,7 @@ cdef class FMElement(pAdicTemplateElement): cpdef bint _is_inexact_zero(self) except -1: """ - Returns True if self is indistinguishable from zero. + Return ``True`` if self is indistinguishable from zero. EXAMPLES:: @@ -539,7 +539,7 @@ cdef class FMElement(pAdicTemplateElement): def is_zero(self, absprec = None): r""" - Returns whether self is zero modulo `\pi^{\mbox{absprec}}`. + Returns whether ``self`` is zero modulo `\pi^{\mbox{absprec}}`. INPUT: @@ -582,13 +582,13 @@ cdef class FMElement(pAdicTemplateElement): def is_equal_to(self, _right, absprec=None): r""" - Returns whether this element is equal to ``right`` modulo `p^{\mbox{absprec}}`. + Return whether this element is equal to ``right`` modulo `p^{\mbox{absprec}}`. If ``absprec`` is ``None``, returns if ``self == 0``. INPUT: - - ``right`` -- a p-adic element with the same parent + - ``right`` -- a `p`-adic element with the same parent - ``absprec`` -- a positive integer or ``None`` (default: ``None``) EXAMPLES:: @@ -780,9 +780,9 @@ cdef class FMElement(pAdicTemplateElement): cpdef pAdicTemplateElement unit_part(FMElement self): r""" - Returns the unit part of self. + Return the unit part of ``self``. - If the valuation of self is positive, then the high digits of the + If the valuation of ``self`` is positive, then the high digits of the result will be zero. EXAMPLES:: @@ -805,7 +805,7 @@ cdef class FMElement(pAdicTemplateElement): cdef long valuation_c(self): """ - Returns the valuation of this element. + Return the valuation of this element. TESTS:: @@ -836,10 +836,10 @@ cdef class FMElement(pAdicTemplateElement): cpdef val_unit(self): """ - Returns a 2-tuple, the first element set to the valuation of - self, and the second to the unit part of self. + Return a 2-tuple, the first element set to the valuation of + ``self``, and the second to the unit part of ``self``. - If self == 0, then the unit part is O(p^self.parent().precision_cap()). + If ``self == 0``, then the unit part is ``O(p^self.parent().precision_cap())``. EXAMPLES:: @@ -868,8 +868,8 @@ cdef class FMElement(pAdicTemplateElement): return chash(self.value, 0, self.prime_pow.ram_prec_cap, self.prime_pow) cdef class pAdicCoercion_ZZ_FM(RingHomomorphism): - """ - The canonical inclusion from ZZ to a fixed modulus ring. + r""" + The canonical inclusion from `\ZZ` to a fixed modulus ring. EXAMPLES:: @@ -993,8 +993,8 @@ cdef class pAdicCoercion_ZZ_FM(RingHomomorphism): return ans def section(self): - """ - Returns a map back to ZZ that approximates an element of this + r""" + Returns a map back to `\ZZ` that approximates an element of this `p`-adic ring by an integer. EXAMPLES:: @@ -1010,11 +1010,11 @@ cdef class pAdicCoercion_ZZ_FM(RingHomomorphism): return self._section cdef class pAdicConvert_FM_ZZ(RingMap): - """ - The map from a fixed modulus ring back to ZZ that returns the smallest + r""" + The map from a fixed modulus ring back to `\ZZ` that returns the smallest non-negative integer approximation to its input which is accurate up to the precision. - If the input is not in the closure of the image of ZZ, raises a ValueError. + If the input is not in the closure of the image of `\ZZ`, raises a :class:`ValueError`. EXAMPLES:: @@ -1057,9 +1057,9 @@ cdef class pAdicConvert_FM_ZZ(RingMap): return ans cdef class pAdicConvert_QQ_FM(Morphism): - """ - The inclusion map from QQ to a fixed modulus ring that is defined - on all elements with non-negative p-adic valuation. + r""" + The inclusion map from `\QQ` to a fixed modulus ring that is defined + on all elements with non-negative `p`-adic valuation. EXAMPLES:: @@ -1175,8 +1175,8 @@ cdef class pAdicConvert_QQ_FM(Morphism): return ans cdef class pAdicCoercion_FM_frac_field(RingHomomorphism): - """ - The canonical inclusion of Zq into its fraction field. + r""" + The canonical inclusion of `\ZZ_q` into its fraction field. EXAMPLES:: @@ -1282,7 +1282,7 @@ cdef class pAdicCoercion_FM_frac_field(RingHomomorphism): def section(self): """ - Returns a map back to the ring that converts elements of + Return a map back to the ring that converts elements of non-negative valuation. EXAMPLES:: @@ -1388,7 +1388,7 @@ cdef class pAdicCoercion_FM_frac_field(RingHomomorphism): cdef class pAdicConvert_FM_frac_field(Morphism): r""" - The section of the inclusion from `\ZZ_q`` to its fraction field. + The section of the inclusion from `\ZZ_q` to its fraction field. EXAMPLES:: diff --git a/src/sage/rings/padics/FP_template.pxi b/src/sage/rings/padics/FP_template.pxi index befd8ee01fb..57ec619b278 100644 --- a/src/sage/rings/padics/FP_template.pxi +++ b/src/sage/rings/padics/FP_template.pxi @@ -2,19 +2,19 @@ Floating point template for complete discrete valuation rings In order to use this template you need to write a linkage file and -gluing file. For an example see mpz_linkage.pxi (linkage file) and -padic_floating_point_element.pyx (gluing file). +gluing file. For an example see ``mpz_linkage.pxi`` (linkage file) and +``padic_floating_point_element.pyx`` (gluing file). The linkage file implements a common API that is then used in the -class FPElement defined here. See sage/libs/linkages/padics/API.pxi +class :class:`FPElement` defined here. See ``sage/libs/linkages/padics/API.pxi`` for the functions needed. The gluing file does the following: -- ctypedef's celement to be the appropriate type (e.g. mpz_t) +- ``ctypedef``'s ``celement`` to be the appropriate type (e.g. ``mpz_t``) - includes the linkage file - includes this template -- defines a concrete class inheriting from FPElement, and implements +- defines a concrete class inheriting from :class:`FPElement`, and implements any desired extra methods AUTHORS: @@ -795,7 +795,7 @@ cdef class FPElement(pAdicTemplateElement): def add_bigoh(self, absprec): """ - Returns a new element truncated modulo `\pi^{\mbox{absprec}}`. + Return a new element truncated modulo `\pi^{\mbox{absprec}}`. INPUT: @@ -803,7 +803,7 @@ cdef class FPElement(pAdicTemplateElement): OUTPUT: - - a new element truncated modulo `\pi^{\mbox{absprec}}`. + a new element truncated modulo `\pi^{\mbox{absprec}}`. EXAMPLES:: @@ -851,7 +851,7 @@ cdef class FPElement(pAdicTemplateElement): cpdef bint _is_inexact_zero(self) except -1: """ - Returns True if self is indistinguishable from zero. + Return ``True`` if self is indistinguishable from zero. EXAMPLES:: @@ -865,7 +865,7 @@ cdef class FPElement(pAdicTemplateElement): def is_zero(self, absprec = None): r""" - Returns whether self is zero modulo `\pi^{\mbox{absprec}}`. + Returns whether ``self`` is zero modulo `\pi^{\mbox{absprec}}`. INPUT: @@ -897,7 +897,7 @@ cdef class FPElement(pAdicTemplateElement): """ Return ``True`` if this element is distinguishable from zero. - For most applications, explicitly specifying the power of p + For most applications, explicitly specifying the power of `p` modulo which the element is supposed to be nonzero is preferable. EXAMPLES:: @@ -910,14 +910,14 @@ cdef class FPElement(pAdicTemplateElement): def is_equal_to(self, _right, absprec=None): r""" - Returns whether this element is equal to ``right`` modulo `p^{\mbox{absprec}}`. + Return whether this element is equal to ``right`` modulo `p^{\mbox{absprec}}`. - If ``absprec`` is ``None``, determines whether self and right + If ``absprec`` is ``None``, determines whether ``self`` and ``right`` have the same value. INPUT: - - ``right`` -- a p-adic element with the same parent + - ``right`` -- a `p`-adic element with the same parent - ``absprec`` -- a positive integer or ``None`` (default: ``None``) EXAMPLES:: @@ -1137,7 +1137,7 @@ cdef class FPElement(pAdicTemplateElement): cpdef pAdicTemplateElement unit_part(FPElement self): r""" - Returns the unit part of this element. + Return the unit part of this element. If the valuation of this element is positive, then the high digits of the result will be zero. @@ -1167,7 +1167,7 @@ cdef class FPElement(pAdicTemplateElement): cdef long valuation_c(self): """ - Returns the valuation of this element. + Return the valuation of this element. If this element is an exact zero, returns ``maxordp``, which is defined as ``(1L << (sizeof(long) * 8 - 2))-1``. @@ -1204,7 +1204,7 @@ cdef class FPElement(pAdicTemplateElement): cpdef val_unit(self, p=None): """ - Returns a 2-tuple, the first element set to the valuation of + Return a 2-tuple, the first element set to the valuation of this element, and the second to the unit part. If this element is either zero or infinity, raises an error. @@ -1380,8 +1380,8 @@ cdef class pAdicCoercion_ZZ_FP(RingHomomorphism): return ans def section(self): - """ - Returns a map back to ZZ that approximates an element of this + r""" + Returns a map back to `\ZZ` that approximates an element of this `p`-adic ring by an integer. EXAMPLES:: @@ -1398,11 +1398,11 @@ cdef class pAdicCoercion_ZZ_FP(RingHomomorphism): cdef class pAdicConvert_FP_ZZ(RingMap): - """ - The map from a floating point ring back to ZZ that returns the smallest + r""" + The map from a floating point ring back to `\ZZ` that returns the smallest non-negative integer approximation to its input which is accurate up to the precision. - If the input is not in the closure of the image of ZZ, raises a ValueError. + If the input is not in the closure of the image of `\ZZ`, raises a :class:`ValueError`. EXAMPLES:: @@ -1602,7 +1602,7 @@ cdef class pAdicCoercion_QQ_FP(RingHomomorphism): def section(self): """ - Returns a map back to the rationals that approximates an element by + Return a map back to the rationals that approximates an element by a rational number. EXAMPLES:: @@ -1669,8 +1669,8 @@ cdef class pAdicConvert_FP_QQ(RingMap): return ans cdef class pAdicConvert_QQ_FP(Morphism): - """ - The inclusion map from QQ to a floating point ring. + r""" + The inclusion map from `\QQ` to a floating point ring. EXAMPLES:: @@ -1908,7 +1908,7 @@ cdef class pAdicCoercion_FP_frac_field(RingHomomorphism): def section(self): r""" - Returns a map back to the ring that converts elements of + Return a map back to the ring that converts elements of non-negative valuation. EXAMPLES:: diff --git a/src/sage/rings/padics/eisenstein_extension_generic.py b/src/sage/rings/padics/eisenstein_extension_generic.py index 4f68e63ffae..84c3c1980a9 100644 --- a/src/sage/rings/padics/eisenstein_extension_generic.py +++ b/src/sage/rings/padics/eisenstein_extension_generic.py @@ -26,7 +26,7 @@ class EisensteinExtensionGeneric(pAdicExtensionGeneric): def __init__(self, poly, prec, print_mode, names, element_class): """ - Initializes self. + Initializes ``self``. EXAMPLES:: @@ -74,7 +74,7 @@ def absolute_e(self): def inertia_subring(self): """ - Returns the inertia subring. + Return the inertia subring. Since an Eisenstein extension is totally ramified, this is just the ground field. @@ -83,7 +83,7 @@ def inertia_subring(self): sage: A = Zp(7,10) sage: S. = A[] - sage: B. = A.ext(x^2+7) + sage: B. = A.ext(x^2 + 7) sage: B.inertia_subring() 7-adic Ring with capped relative precision 10 """ @@ -91,21 +91,21 @@ def inertia_subring(self): def residue_class_field(self): """ - Returns the residue class field. + Return the residue class field. INPUT: - - self -- a p-adic ring + - ``self`` -- a p-adic ring OUTPUT: - - the residue field + the residue field EXAMPLES:: sage: A = Zp(7,10) sage: S. = A[] - sage: B. = A.ext(x^2+7) + sage: B. = A.ext(x^2 + 7) sage: B.residue_class_field() Finite Field of size 7 """ @@ -113,7 +113,7 @@ def residue_class_field(self): def residue_ring(self, n): """ - Return the quotient of the ring of integers by the nth power of its maximal ideal. + Return the quotient of the ring of integers by the `n`-th power of its maximal ideal. EXAMPLES:: @@ -162,13 +162,13 @@ def residue_ring(self, n): def gen(self, n=0): """ - Returns a generator for self as an extension of its ground ring. + Return a generator for ``self`` as an extension of its ground ring. EXAMPLES:: sage: A = Zp(7,10) sage: S. = A[] - sage: B. = A.ext(x^2+7) + sage: B. = A.ext(x^2 + 7) sage: B.gen() t + O(t^21) """ @@ -178,14 +178,14 @@ def gen(self, n=0): def uniformizer_pow(self, n): """ - Returns the nth power of the uniformizer of self (as an - element of self). + Return the `n`-th power of the uniformizer of ``self`` (as an + element of ``self``). EXAMPLES:: sage: A = Zp(7,10) sage: S. = A[] - sage: B. = A.ext(x^2+7) + sage: B. = A.ext(x^2 + 7) sage: B.uniformizer_pow(5) t^5 + O(t^25) """ @@ -196,14 +196,14 @@ def uniformizer_pow(self, n): def uniformizer(self): """ - Returns the uniformizer of self, ie a generator for the unique + Return the uniformizer of ``self``, i.e., a generator for the unique maximal ideal. EXAMPLES:: sage: A = Zp(7,10) sage: S. = A[] - sage: B. = A.ext(x^2+7) + sage: B. = A.ext(x^2 + 7) sage: B.uniformizer() t + O(t^21) """ @@ -211,7 +211,7 @@ def uniformizer(self): def _uniformizer_print(self): """ - Returns a string representation of how the uniformizer of self + Return a string representation of how the uniformizer of self prints. Mainly for internal use. EXAMPLES:: diff --git a/src/sage/rings/padics/factory.py b/src/sage/rings/padics/factory.py index fae673de284..25e5c796cc2 100644 --- a/src/sage/rings/padics/factory.py +++ b/src/sage/rings/padics/factory.py @@ -161,7 +161,7 @@ def _canonicalize_show_prec(type, print_mode, show_prec=None): def get_key_base(p, prec, type, print_mode, names, ram_name, print_pos, print_sep, print_alphabet, print_max_terms, show_prec, check, valid_types, label=None): r""" - This implements create_key for Zp and Qp: moving it here prevents code duplication. + This implements ``create_key`` for ``Zp`` and ``Qp``: moving it here prevents code duplication. It fills in unspecified values and checks for contradictions in the input. It also standardizes irrelevant options so that duplicate parents are not created. @@ -468,7 +468,9 @@ class Qp_class(UniqueFactory): sage: R = Qp(5, print_mode='series'); a = R(70700); a 3*5^2 + 3*5^4 + 2*5^5 + 4*5^6 + O(5^22) sage: b = R(-70700); b - 2*5^2 + 4*5^3 + 5^4 + 2*5^5 + 4*5^7 + 4*5^8 + 4*5^9 + 4*5^10 + 4*5^11 + 4*5^12 + 4*5^13 + 4*5^14 + 4*5^15 + 4*5^16 + 4*5^17 + 4*5^18 + 4*5^19 + 4*5^20 + 4*5^21 + O(5^22) + 2*5^2 + 4*5^3 + 5^4 + 2*5^5 + 4*5^7 + 4*5^8 + 4*5^9 + 4*5^10 + 4*5^11 + + 4*5^12 + 4*5^13 + 4*5^14 + 4*5^15 + 4*5^16 + 4*5^17 + 4*5^18 + + 4*5^19 + 4*5^20 + 4*5^21 + O(5^22) *print_pos* controls whether negatives can be used in the coefficients of powers of `p`. :: @@ -832,7 +834,7 @@ def Qq(q, prec = None, type = 'capped-rel', modulus = None, names=None, - ``q`` -- integer, list, tuple or ``Factorization`` object. If ``q`` is an integer, it is the prime power `q` in `\QQ_q`. If ``q`` is a - ``Factorization`` object, it is the factorization of the prime power `q`. + :class:`Factorization` object, it is the factorization of the prime power `q`. As a tuple it is the pair ``(p, n)``, and as a list it is a single element list ``[(p, n)]``. @@ -860,7 +862,7 @@ def Qq(q, prec = None, type = 'capped-rel', modulus = None, names=None, - ``res_name`` -- string (defaults to ``None``, which corresponds to adding a ``'0'`` to the end of the name). Controls how elements of - the reside field print. + the residue field print. - ``print_pos`` -- bool (default ``None``) Whether to only use positive integers in the representations of elements. See PRINTING below. @@ -1012,9 +1014,15 @@ def Qq(q, prec = None, type = 'capped-rel', modulus = None, names=None, sage: R. = Qq(9, 20, 'capped-rel', print_mode='series'); (1+2*a)^4 2 + (2*a + 2)*3 + (2*a + 1)*3^2 + O(3^20) sage: -3*(1+2*a)^4 - 3 + a*3^2 + 3^3 + (2*a + 2)*3^4 + (2*a + 2)*3^5 + (2*a + 2)*3^6 + (2*a + 2)*3^7 + (2*a + 2)*3^8 + (2*a + 2)*3^9 + (2*a + 2)*3^10 + (2*a + 2)*3^11 + (2*a + 2)*3^12 + (2*a + 2)*3^13 + (2*a + 2)*3^14 + (2*a + 2)*3^15 + (2*a + 2)*3^16 + (2*a + 2)*3^17 + (2*a + 2)*3^18 + (2*a + 2)*3^19 + (2*a + 2)*3^20 + O(3^21) + 3 + a*3^2 + 3^3 + (2*a + 2)*3^4 + (2*a + 2)*3^5 + (2*a + 2)*3^6 + (2*a + 2)*3^7 + + (2*a + 2)*3^8 + (2*a + 2)*3^9 + (2*a + 2)*3^10 + (2*a + 2)*3^11 + + (2*a + 2)*3^12 + (2*a + 2)*3^13 + (2*a + 2)*3^14 + (2*a + 2)*3^15 + + (2*a + 2)*3^16 + (2*a + 2)*3^17 + (2*a + 2)*3^18 + (2*a + 2)*3^19 + + (2*a + 2)*3^20 + O(3^21) sage: ~(3*a+18) - (a + 2)*3^-1 + 1 + 2*3 + (a + 1)*3^2 + 3^3 + 2*3^4 + (a + 1)*3^5 + 3^6 + 2*3^7 + (a + 1)*3^8 + 3^9 + 2*3^10 + (a + 1)*3^11 + 3^12 + 2*3^13 + (a + 1)*3^14 + 3^15 + 2*3^16 + (a + 1)*3^17 + 3^18 + O(3^19) + (a + 2)*3^-1 + 1 + 2*3 + (a + 1)*3^2 + 3^3 + 2*3^4 + (a + 1)*3^5 + 3^6 + 2*3^7 + + (a + 1)*3^8 + 3^9 + 2*3^10 + (a + 1)*3^11 + 3^12 + 2*3^13 + (a + 1)*3^14 + + 3^15 + 2*3^16 + (a + 1)*3^17 + 3^18 + O(3^19) *print_pos* controls whether negatives can be used in the coefficients of powers of `p`. :: @@ -1074,7 +1082,8 @@ def Qq(q, prec = None, type = 'capped-rel', modulus = None, names=None, *print_pos* controls whether to use a balanced representation or not. :: - sage: S. = Qq(9, 7, print_mode='val-unit', print_pos=False); b = (1+3*a)^9 - 1; b + sage: S. = Qq(9, 7, print_mode='val-unit', print_pos=False) + sage: b = (1+3*a)^9 - 1; b 3^3 * (15 - 17*a) + O(3^7) sage: ~b 3^-3 * (-40 + a) + O(3) @@ -1082,15 +1091,19 @@ def Qq(q, prec = None, type = 'capped-rel', modulus = None, names=None, *ram_name* affects how the prime is printed. :: sage: A. = Qp(next_prime(10^6), print_mode='val-unit')[] - sage: T. = Qq(next_prime(10^6)^3, 4, print_mode='val-unit', ram_name='p', modulus=x^3+385831*x^2+106556*x+321036); b = ~(next_prime(10^6)^2*(a^2 + a - 4)); b - p^-2 * (503009563508519137754940 + 704413692798200940253892*a + 968097057817740999537581*a^2) + O(p^2) + sage: T. = Qq(next_prime(10^6)^3, 4, print_mode='val-unit', ram_name='p', + ....: modulus=x^3+385831*x^2+106556*x+321036) + sage: b = ~(next_prime(10^6)^2*(a^2 + a - 4)); b + p^-2 * (503009563508519137754940 + 704413692798200940253892*a + + 968097057817740999537581*a^2) + O(p^2) sage: b * (a^2 + a - 4) p^-2 * 1 + O(p^2) *print_max_terse_terms* controls how many terms of the polynomial appear in the unit part. :: - sage: U. = Qq(17^4, 6, print_mode='val-unit', print_max_terse_terms=3); b = ~(17*(a^3-a+14)); b + sage: U. = Qq(17^4, 6, print_mode='val-unit', print_max_terse_terms=3) + sage: b = ~(17*(a^3-a+14)); b 17^-1 * (22110411 + 11317400*a + 20656972*a^2 + ...) + O(17^5) sage: b*17*(a^3-a+14) 1 + O(17^6) @@ -1176,7 +1189,8 @@ def Qq(q, prec = None, type = 'capped-rel', modulus = None, names=None, series, but more compactly. :: sage: R. = Qq(125); (a+5)^6 - (4*a^2 + 3*a + 4) + (3*a^2 + 2*a)*5 + (a^2 + a + 1)*5^2 + (3*a + 2)*5^3 + (3*a^2 + a + 3)*5^4 + (2*a^2 + 3*a + 2)*5^5 + O(5^20) + (4*a^2 + 3*a + 4) + (3*a^2 + 2*a)*5 + (a^2 + a + 1)*5^2 + (3*a + 2)*5^3 + + (3*a^2 + a + 3)*5^4 + (2*a^2 + 3*a + 2)*5^5 + O(5^20) sage: R. = Qq(125, print_mode='bars', prec=8); repr((a+5)^6) '...[2, 3, 2]|[3, 1, 3]|[2, 3]|[1, 1, 1]|[0, 2, 3]|[4, 3, 4]' sage: repr((a-5)^6) @@ -1267,14 +1281,16 @@ def Qq(q, prec = None, type = 'capped-rel', modulus = None, names=None, sage: p = next_prime(2^123) sage: k = Qp(p) sage: R. = k[] - sage: K = Qq([(p, 5)], modulus=x^5+x+4, names='a', ram_name='p', print_pos=False, check=False) + sage: K = Qq([(p, 5)], modulus=x^5+x+4, names='a', ram_name='p', + ....: print_pos=False, check=False) sage: K.0^5 (-a - 4) + O(p^20) In tests on ``sage.math.washington.edu``, the creation of ``K`` as above took an average of 1.58ms, while:: - sage: K = Qq(p^5, modulus=x^5+x+4, names='a', ram_name='p', print_pos=False, check=True) + sage: K = Qq(p^5, modulus=x^5+x+4, names='a', ram_name='p', + ....: print_pos=False, check=True) took an average of 24.5ms. Of course, with smaller primes these savings disappear. @@ -1368,7 +1384,7 @@ def QpCR(p, prec = None, *args, **kwds): r""" A shortcut function to create capped relative `p`-adic fields. - Same functionality as ``Qp``. See documentation for ``Qp`` for a + Same functionality as :func:`Qp`. See documentation for :func:`Qp` for a description of the input parameters. EXAMPLES:: @@ -1382,7 +1398,7 @@ def QpFP(p, prec = None, *args, **kwds): r""" A shortcut function to create floating point `p`-adic fields. - Same functionality as ``Qp``. See documentation for ``Qp`` for a + Same functionality as :func:`Qp`. See documentation for :func:`Qp` for a description of the input parameters. EXAMPLES:: @@ -1397,7 +1413,7 @@ def QqCR(q, prec = None, *args, **kwds): A shortcut function to create capped relative unramified `p`-adic fields. - Same functionality as ``Qq``. See documentation for ``Qq`` for a + Same functionality as :func:`Qq`. See documentation for :func:`Qq` for a description of the input parameters. EXAMPLES:: @@ -1412,7 +1428,7 @@ def QqFP(q, prec = None, *args, **kwds): A shortcut function to create floating point unramified `p`-adic fields. - Same functionality as ``Qq``. See documentation for ``Qq`` for a + Same functionality as :func:`Qq`. See documentation for :func:`Qq` for a description of the input parameters. EXAMPLES:: @@ -1486,22 +1502,22 @@ class Zp_class(UniqueFactory): - ``prec`` -- integer (default: ``20``) the precision cap of the ring. In the lattice capped case, ``prec`` can either be a pair (``relative_cap``, ``absolute_cap``) or an integer - (understood at relative cap). + (understood as relative cap). In the relaxed case, ``prec`` can be either a pair (``default_prec``, ``halting_prec``) or an integer - (understood at default precision). + (understood as default precision). Except for the fixed modulus and floating point cases, individual elements keep track of their own precision. See TYPES and PRECISION below. - ``type`` -- string (default: ``'capped-rel'``) Valid types are ``'capped-rel'``, ``'capped-abs'``, ``'fixed-mod'``, - ``'floating-point'``, ``'lattice-cap'``, ``'lattice-float'``, ``'relaxed'`` - See TYPES and PRECISION below + ``'floating-point'``, ``'lattice-cap'``, ``'lattice-float'``, ``'relaxed'``. + See TYPES and PRECISION below. - ``print_mode`` -- string (default: ``None``). Valid modes are ``'series'``, ``'val-unit'``, ``'terse'``, ``'digits'``, and - ``'bars'``. See PRINTING below + ``'bars'``. See PRINTING below. - ``names`` -- string or tuple (defaults to a string representation of `p`). What to use whenever `p` is printed. @@ -1630,7 +1646,7 @@ class Zp_class(UniqueFactory): There are many different ways to print `p`-adic elements. The way elements of a given ring print is controlled by options passed in at the creation of the ring. There are five basic - printing modes (series, val-unit, terse, digits and bars), as + printing modes (``'series'``, ``'val-unit'``, ``'terse'``, ``'digits'`` and ``'bars'``), as well as various options that either hide some information in the print representation or sometimes make print representations more compact. Note that the printing options @@ -1641,7 +1657,9 @@ class Zp_class(UniqueFactory): sage: R = Zp(5, print_mode='series'); a = R(70700); a 3*5^2 + 3*5^4 + 2*5^5 + 4*5^6 + O(5^22) sage: b = R(-70700); b - 2*5^2 + 4*5^3 + 5^4 + 2*5^5 + 4*5^7 + 4*5^8 + 4*5^9 + 4*5^10 + 4*5^11 + 4*5^12 + 4*5^13 + 4*5^14 + 4*5^15 + 4*5^16 + 4*5^17 + 4*5^18 + 4*5^19 + 4*5^20 + 4*5^21 + O(5^22) + 2*5^2 + 4*5^3 + 5^4 + 2*5^5 + 4*5^7 + 4*5^8 + 4*5^9 + 4*5^10 + 4*5^11 + + 4*5^12 + 4*5^13 + 4*5^14 + 4*5^15 + 4*5^16 + 4*5^17 + 4*5^18 + + 4*5^19 + 4*5^20 + 4*5^21 + O(5^22) *print_pos* controls whether negatives can be used in the coefficients of powers of `p`. :: @@ -1768,12 +1786,13 @@ class Zp_class(UniqueFactory): greater than 9. Defaults to ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'):: - sage: T = Zp(5, print_mode='digits', print_alphabet=('1','2','3','4','5')); repr(T(-70700)) + sage: T = Zp(5, print_mode='digits', print_alphabet=('1','2','3','4','5')) + sage: repr(T(-70700)) '...5555555555555551325311' *show_prec* determines how the precision is printed. - It can be either 'none' (or equivalently ``False``), 'dots' - (or equivalently ``True``) or 'bigoh'. + It can be either ``'none'`` (or equivalently ``False``), ``'dots'`` + (or equivalently ``True``) or ``'bigoh'``. The default is ``False`` for the ``'floating-point'`` and ``'fixed-mod'`` types and ``True`` for all other types. :: @@ -1802,7 +1821,7 @@ class Zp_class(UniqueFactory): *print_pos* controls whether the digits can be negative. :: - sage: S = Zp(5, print_mode='bars',print_pos=False); b = S(-70700); repr(b) + sage: S = Zp(5, print_mode='bars', print_pos=False); b = S(-70700); repr(b) '...-1|0|2|2|-1|2|0|0' *print_max_terms* limits the number of digits that are printed. :: @@ -1835,7 +1854,7 @@ class Zp_class(UniqueFactory): EXAMPLES: - We allow non-prime `p`, but only if ``check = False``. Note that some + We allow non-prime `p`, but only if ``check=False``. Note that some features will not work. :: sage: K = Zp(15, check=False); a = K(999); a @@ -1857,7 +1876,8 @@ class Zp_class(UniqueFactory): It works even with a fairly huge cap:: sage: Zp(next_prime(10^50), 100000) - 100000000000000000000000000000000000000000000000151-adic Ring with capped relative precision 100000 + 100000000000000000000000000000000000000000000000151-adic Ring + with capped relative precision 100000 We create each type of ring:: @@ -1917,7 +1937,7 @@ def create_key(self, p, prec = None, type = 'capped-rel', print_mode = None, r""" Creates a key from input parameters for ``Zp``. - See the documentation for ``Zp`` for more information. + See the documentation for :func:`Zp` for more information. TESTS:: @@ -1955,7 +1975,7 @@ def create_object(self, version, key): r""" Creates an object using a given key. - See the documentation for ``Zp`` for more information. + See the documentation for :func:`Zp` for more information. TESTS:: @@ -2025,7 +2045,7 @@ def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, INPUT: - ``q`` -- integer, list or tuple: the prime power in `\QQ_q`. Or a - factorization object, single element list ``[(p, n)]`` where ``p`` is + :class:`Factorization` object, single element list ``[(p, n)]`` where ``p`` is a prime and ``n`` a positive integer, or the pair ``(p, n)``. - ``prec`` -- integer (default: ``20``) the precision cap of the @@ -2034,9 +2054,9 @@ def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, - ``type`` -- string (default: ``'capped-rel'``) Valid types are ``'capped-abs'``, ``'capped-rel'``, ``'fixed-mod'``, and - ``'floating-point'``. See TYPES and PRECISION below + ``'floating-point'``. See TYPES and PRECISION below. - - modulus -- polynomial (default None) A polynomial defining an + - ``modulus`` -- polynomial (default None) A polynomial defining an unramified extension of `\ZZ_p`. See MODULUS below. - ``names`` -- string or tuple (``None`` is only allowed when @@ -2047,12 +2067,12 @@ def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, ``'val-unit'``, ``'terse'``, and ``'bars'``. See PRINTING below. - ``ram_name`` -- string (defaults to string representation of `p` if - None). ``ram_name`` controls how the prime is printed. See PRINTING + ``None``). ``ram_name`` controls how the prime is printed. See PRINTING below. - ``res_name`` -- string (defaults to ``None``, which corresponds to adding a ``'0'`` to the end of the name). Controls how - elements of the reside field print. + elements of the residue field print. - ``print_pos`` -- bool (default ``None``) Whether to only use positive integers in the representations of elements. See @@ -2077,12 +2097,12 @@ def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, - ``check`` -- bool (default ``True``) whether to check inputs. - - ``implementation`` -- string (default ``FLINT``) which - implementation to use. ``NTL`` is the other option. + - ``implementation`` -- string (default ``'FLINT'``) which + implementation to use. ``'NTL'`` is the other option. OUTPUT: - - The corresponding unramified `p`-adic ring. + The corresponding unramified `p`-adic ring. TYPES AND PRECISION: @@ -2284,7 +2304,7 @@ def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, '(...)*2 + (...)*2^2 + (...)*2^3 + (...)*2^4 + (...)*2^5 + (...)*2^6 + (...)*2^7 + O(2^8)' *show_prec* determines how the precision is printed. - It can be either 'none' (or equivalently ``False``), 'bigoh' + It can be either ``'none'`` (or equivalently ``False``), ``'bigoh'`` (or equivalently ``True``). The default is ``False`` for the ``'floating-point'`` and ``'fixed-mod'`` types and ``True`` for all other types. :: @@ -2317,19 +2337,23 @@ def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, *ram_name* affects how the prime is printed. :: sage: A. = Zp(next_prime(10^6), print_mode='val-unit')[] - sage: T. = Zq(next_prime(10^6)^3, 4, print_mode='val-unit', ram_name='p', modulus=x^3+385831*x^2+106556*x+321036); b = (next_prime(10^6)^2*(a^2 + a - 4)^4); b - p^2 * (87996187118837557387483 + 246348888344392418464080*a + 1353538653775332610349*a^2) + O(p^6) + sage: T. = Zq(next_prime(10^6)^3, 4, print_mode='val-unit', ram_name='p', + ....: modulus=x^3+385831*x^2+106556*x+321036) + sage: b = next_prime(10^6)^2*(a^2 + a - 4)^4; b + p^2 * (87996187118837557387483 + 246348888344392418464080*a + 1353538653775332610349*a^2) + + O(p^6) sage: b * (a^2 + a - 4)^-4 p^2 * 1 + O(p^6) *print_max_terse_terms* controls how many terms of the polynomial appear in the unit part. :: - sage: U. = Zq(17^4, 6, print_mode='val-unit', print_max_terse_terms=3); b = (17*(a^3-a+14)^6); b + sage: U. = Zq(17^4, 6, print_mode='val-unit', print_max_terse_terms=3) + sage: b = 17*(a^3-a+14)^6; b 17 * (12131797 + 12076378*a + 10809706*a^2 + ...) + O(17^7) *show_prec* determines how the precision is printed. - It can be either 'none' (or equivalently ``False``), 'bigoh' + It can be either ``'none'`` (or equivalently ``False``), ``'bigoh'`` (or equivalently ``True``). The default is ``False`` for the ``'floating-point'`` and ``'fixed-mod'`` types and ``True`` for all other types. :: @@ -2386,7 +2410,7 @@ def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, 106251/5^6 + 49994/5^5*a + ... + O(5^14) *show_prec* determines how the precision is printed. - It can be either 'none' (or equivalently ``False``), 'bigoh' + It can be either ``'none'`` (or equivalently ``False``), ``'bigoh'`` (or equivalently ``True``). The default is ``False`` for the ``'floating-point'`` and ``'fixed-mod'`` types and ``True`` for all other types. :: @@ -2410,7 +2434,8 @@ def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, but more compactly. :: sage: R. = Zq(125); (a+5)^6 - (4*a^2 + 3*a + 4) + (3*a^2 + 2*a)*5 + (a^2 + a + 1)*5^2 + (3*a + 2)*5^3 + (3*a^2 + a + 3)*5^4 + (2*a^2 + 3*a + 2)*5^5 + O(5^20) + (4*a^2 + 3*a + 4) + (3*a^2 + 2*a)*5 + (a^2 + a + 1)*5^2 + (3*a + 2)*5^3 + + (3*a^2 + a + 3)*5^4 + (2*a^2 + 3*a + 2)*5^5 + O(5^20) sage: R. = Zq(125, print_mode='bars', prec=8); repr((a+5)^6) '...[2, 3, 2]|[3, 1, 3]|[2, 3]|[1, 1, 1]|[0, 2, 3]|[4, 3, 4]' sage: repr((a-5)^6) @@ -2464,8 +2489,8 @@ def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, '...[...][...][...][...][][...][...]' *show_prec* determines how the precision is printed. - It can be either 'none' (or equivalently ``False``), 'dots' - (or equivalently ``True``) or 'bigoh'. + It can be either ``'none'`` (or equivalently ``False``), ``'dots'`` + (or equivalently ``True``) or ``'bigoh'``. The default is ``False`` for the ``'floating-point'`` and ``'fixed-mod'`` types and ``True`` for all other types. :: @@ -2481,7 +2506,7 @@ def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, EXAMPLES: - Unlike for ``Zp``, you can't create ``Zq(N)`` when ``N`` is not a prime power. + Unlike for :func:`Zp`, you can't create ``Zq(N)`` when ``N`` is not a prime power. However, you can use ``check=False`` to pass in a pair in order to not have to factor. If you do so, you need to use names explicitly @@ -2490,14 +2515,16 @@ def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, sage: p = next_prime(2^123) sage: k = Zp(p) sage: R. = k[] - sage: K = Zq([(p, 5)], modulus=x^5+x+4, names='a', ram_name='p', print_pos=False, check=False) + sage: K = Zq([(p, 5)], modulus=x^5+x+4, names='a', ram_name='p', + ....: print_pos=False, check=False) sage: K.0^5 (-a - 4) + O(p^20) In tests on sage.math, the creation of ``K`` as above took an average of 1.58ms, while:: - sage: K = Zq(p^5, modulus=x^5+x+4, names='a', ram_name='p', print_pos=False, check=True) + sage: K = Zq(p^5, modulus=x^5+x+4, names='a', ram_name='p', + ....: print_pos=False, check=True) took an average of 24.5ms. Of course, with smaller primes these savings disappear. @@ -2576,7 +2603,7 @@ def ZpCR(p, prec = None, *args, **kwds): r""" A shortcut function to create capped relative `p`-adic rings. - Same functionality as ``Zp``. See documentation for ``Zp`` for a + Same functionality as :func:`Zp`. See documentation for :func:`Zp` for a description of the input parameters. EXAMPLES:: @@ -2616,7 +2643,7 @@ def ZpFP(p, prec = None, *args, **kwds): r""" A shortcut function to create floating point `p`-adic rings. - Same functionality as ``Zp``. See documentation for ``Zp`` for a + Same functionality as :func:`Zp`. See documentation for :func:`Zp` for a description of the input parameters. EXAMPLES:: @@ -2630,7 +2657,7 @@ def ZqCR(q, prec = None, *args, **kwds): r""" A shortcut function to create capped relative unramified `p`-adic rings. - Same functionality as ``Zq``. See documentation for ``Zq`` for a + Same functionality as :func:`Zq`. See documentation for :func:`Zq` for a description of the input parameters. EXAMPLES:: @@ -2670,7 +2697,7 @@ def ZqFP(q, prec = None, *args, **kwds): r""" A shortcut function to create floating point unramified `p`-adic rings. - Same functionality as ``Zq``. See documentation for ``Zq`` for a + Same functionality as :func:`Zq`. See documentation for :func:`Zq` for a description of the input parameters. EXAMPLES:: @@ -3110,7 +3137,7 @@ def ZpER(p, prec=None, halt=None, secure=False, *args, **kwds): sage: a == aa False - This annoying situation, where the output of `a == aa` may change + This annoying situation, where the output of ``a == aa`` may change depending on previous computations, cannot occur when the parent is created with ``secure=True``. Indeed, in this case, if the equality cannot be decided, an error @@ -3202,7 +3229,7 @@ class pAdicExtension_class(UniqueFactory): sage: R = Zp(5,3) sage: S. = ZZ[] - sage: W. = pAdicExtension(R, x^4-15) + sage: W. = pAdicExtension(R, x^4 - 15) sage: W 5-adic Eisenstein Extension Ring in w defined by x^4 - 15 sage: W.precision_cap() @@ -3215,9 +3242,9 @@ def create_key_and_extra_args(self, base, modulus, prec = None, print_mode = Non print_max_unram_terms = None, print_max_terse_terms = None, show_prec = None, check = True, unram = False, implementation='FLINT'): r""" - Creates a key from input parameters for pAdicExtension. + Creates a key from input parameters for :class:`pAdicExtension`. - See the documentation for ``Qq`` for more information. + See the documentation for :func:`Qq` for more information. TESTS:: @@ -3362,7 +3389,7 @@ def create_object(self, version, key, approx_modulus=None, shift_seed=None): r""" Creates an object using a given key. - See the documentation for pAdicExtension for more information. + See the documentation for :class:`pAdicExtension` for more information. TESTS:: @@ -3425,11 +3452,12 @@ def split(poly, prec): sage: k = Qp(13) sage: x = polygen(k) - sage: f = x^2+1 + sage: f = x^2 + 1 sage: sage.rings.padics.factory.split(f, 10) Traceback (most recent call last): ... - NotImplementedError: Extensions by general polynomials not yet supported. Please use an unramified or Eisenstein polynomial. + NotImplementedError: Extensions by general polynomials not yet supported. + Please use an unramified or Eisenstein polynomial. TESTS: @@ -3463,24 +3491,24 @@ def truncate_to_prec(poly, R, absprec): def krasner_check(poly, prec): r""" - Returns True iff poly determines a unique isomorphism class of - extensions at precision prec. + Return ``True`` iff ``poly`` determines a unique isomorphism class of + extensions at precision ``prec``. - Currently just returns True (thus allowing extensions that are not + Currently just returns ``True`` (thus allowing extensions that are not defined to high enough precision in order to specify them up to isomorphism). This will change in the future. EXAMPLES:: sage: from sage.rings.padics.factory import krasner_check - sage: krasner_check(1,2) #this is a stupid example. + sage: krasner_check(1,2) # this is a stupid example. True """ return True #This needs to be implemented def is_eisenstein(poly): r""" - Returns True iff this monic polynomial is Eisenstein. + Return ``True`` iff this monic polynomial is Eisenstein. A polynomial is Eisenstein if it is monic, the constant term has valuation 1 and all other terms have positive valuation. @@ -3508,7 +3536,7 @@ def is_eisenstein(poly): def is_unramified(poly): r""" - Returns true iff this monic polynomial is unramified. + Return ``True`` iff this monic polynomial is unramified. A polynomial is unramified if its reduction modulo the maximal ideal is irreducible. diff --git a/src/sage/rings/padics/generic_nodes.py b/src/sage/rings/padics/generic_nodes.py index f84a5387b2a..062bc28d8f8 100644 --- a/src/sage/rings/padics/generic_nodes.py +++ b/src/sage/rings/padics/generic_nodes.py @@ -272,7 +272,7 @@ class pAdicLatticeGeneric(pAdicGeneric): INPUT: - - `p` -- the underlying prime number + - ``p`` -- the underlying prime number - ``prec`` -- the precision @@ -616,7 +616,7 @@ def convert_multiple(self, *elts): 6 As a consequence, if we convert ``x`` and ``y`` separately, we - loose some precision:: + lose some precision:: sage: R2 = ZpLC(2, label='copy') sage: x2 = R2(x); y2 = R2(y) @@ -706,7 +706,7 @@ class pAdicRelaxedGeneric(pAdicGeneric): INPUT: - - `p` -- the underlying prime number + - ``p`` -- the underlying prime number - ``prec`` -- the default precision @@ -777,7 +777,7 @@ def is_relaxed(self): def is_secure(self): r""" Return ``False`` if this `p`-adic relaxed ring is not secure - (i.e. if indistinguishable elements at the working precision + (i.e., if indistinguishable elements at the working precision are considered as equal); ``True`` otherwise (in which case, an error is raised when equality cannot be decided). @@ -1135,7 +1135,8 @@ def random_element(self, integral=False, prec=None): sage: b = R.random_element(prec=15) sage: b # random - 2 + 3*5^2 + 5^3 + 3*5^4 + 5^5 + 3*5^6 + 3*5^8 + 3*5^9 + 4*5^10 + 5^11 + 4*5^12 + 5^13 + 2*5^14 + O(5^15) + 2 + 3*5^2 + 5^3 + 3*5^4 + 5^5 + 3*5^6 + 3*5^8 + 3*5^9 + 4*5^10 + + 5^11 + 4*5^12 + 5^13 + 2*5^14 + O(5^15) sage: b.precision_absolute() 15 """ @@ -1393,11 +1394,11 @@ class pAdicFloatingPointFieldGeneric(pAdicFieldGeneric, FloatingPointFieldGeneri class pAdicRingBaseGeneric(pAdicBaseGeneric, pAdicRingGeneric): def construction(self, forbid_frac_field=False): """ - Return the functorial construction of self, namely, - completion of the rational numbers with respect a given prime. + Return the functorial construction of ``self``, namely, + completion of the rational numbers with respect to a given prime. Also preserves other information that makes this field unique - (e.g. precision, rounding, print mode). + (e.g., precision, rounding, print mode). INPUT: @@ -1441,11 +1442,11 @@ def construction(self, forbid_frac_field=False): def random_element(self, algorithm='default'): r""" - Return a random element of self, optionally using the - algorithm argument to decide how it generates the + Return a random element of ``self``, optionally using the + ``algorithm`` argument to decide how it generates the element. Algorithms currently implemented: - - default: Choose `a_i`, `i >= 0`, randomly between `0` and + - ``'default'``: Choose `a_i`, `i \geq 0`, randomly between `0` and `p-1` until a nonzero choice is made. Then continue choosing `a_i` randomly between `0` and `p-1` until we reach precision_cap, and return `\sum a_i p^i`. @@ -1484,7 +1485,7 @@ def random_element(self, algorithm='default'): class pAdicFieldBaseGeneric(pAdicBaseGeneric, pAdicFieldGeneric): def composite(self, subfield1, subfield2): r""" - Return the composite of two subfields of self, i.e., the + Return the composite of two subfields of ``self``, i.e., the largest subfield containing both INPUT: @@ -1495,7 +1496,7 @@ def composite(self, subfield1, subfield2): OUTPUT: - - the composite of subfield1 and subfield2 + the composite of ``subfield1`` and ``subfield2`` EXAMPLES:: @@ -1509,7 +1510,7 @@ def composite(self, subfield1, subfield2): def subfields_of_degree(self, n): r""" - Return the number of subfields of self of degree `n` + Return the number of subfields of ``self`` of degree `n` INPUT: @@ -1518,7 +1519,7 @@ def subfields_of_degree(self, n): OUTPUT: - - integer -- the number of subfields of degree ``n`` over self.base_ring() + integer -- the number of subfields of degree `n` over ``self.base_ring()`` EXAMPLES:: @@ -1533,7 +1534,7 @@ def subfields_of_degree(self, n): def subfield(self, list): r""" - Return the subfield generated by the elements in list + Return the subfield generated by the elements in ``list`` INPUT: @@ -1542,7 +1543,7 @@ def subfield(self, list): OUTPUT: - - the subfield of ``self`` generated by the elements of list + the subfield of ``self`` generated by the elements of ``list`` EXAMPLES:: @@ -1560,7 +1561,7 @@ def construction(self, forbid_frac_field=False): completion of the rational numbers with respect a given prime. Also preserves other information that makes this field unique - (e.g. precision, rounding, print mode). + (e.g., precision, rounding, print mode). INPUT: diff --git a/src/sage/rings/padics/lattice_precision.py b/src/sage/rings/padics/lattice_precision.py index 810d9de650c..c855e3bd25c 100644 --- a/src/sage/rings/padics/lattice_precision.py +++ b/src/sage/rings/padics/lattice_precision.py @@ -60,7 +60,7 @@ class pRational: r""" This class implements rational numbers viewed as elements of ``Qp``. In particular, it provides additional methods which are specific to - ``p``-adics (as ``p``-adic valuation). + `p`-adics (as `p`-adic valuation). Only for internal use. @@ -72,8 +72,8 @@ class pRational: - ``exponent`` -- an integer (default: 0) - - ``valuation`` -- an integer or None (default: ``None``), - the ``p``-adic valuation of this element + - ``valuation`` -- an integer or ``None`` (default: ``None``), + the `p`-adic valuation of this element If not ``None``, this method trusts the given value to the attribute ``valuation``. @@ -259,7 +259,7 @@ def valuation(self): def is_p_power(self): r""" - Return true if this element is a power of `p`. + Return ``True`` if this element is a power of `p`. TESTS:: @@ -279,7 +279,7 @@ def is_p_power(self): def is_zero(self): r""" - Return true if this element vanishes. + Return ``True`` if this element vanishes. TESTS:: @@ -503,7 +503,7 @@ def unit_part(self): def xgcd(self, other): r""" Return the gcd of ``self`` and ``other`` together with two - element ``u`` and ``v`` such that ``u*self + v*other = gcd``. + elements ``u`` and ``v`` such that ``u*self + v*other = gcd``. The ``gcd`` is normalized so that it is a power of `p`. @@ -1483,20 +1483,20 @@ def timings(self, action=None): INPUT: - - ``action`` -- ``None`` (the default), ``add``, ``mark``, ``del``, - ``partial reduce`` or ``full reduce``; if not None, return the + - ``action`` -- ``None`` (the default), ``'add'``, ``'mark'``, ``'del'``, + ``'partial reduce'`` or ``'full reduce'``; if not ``None``, return the cumulated timing corresponding to this action; otherwise, return a dictionary Here are the meanings of the keywords above: - - ``add``: time spent in adding new columns to the precision matrix + - ``'add'``: time spent in adding new columns to the precision matrix (corresponding to the creation of new elements) - - ``mark``: time spent in marking elements for deletion - - ``del``: time spent in deleting columns of the precision matrix + - ``'mark'``: time spent in marking elements for deletion + - ``'del'``: time spent in deleting columns of the precision matrix and re-echelonizing the matrix - - ``partial reduce``: time spent in partial Hermite reduction - - ``full reduce``: time spent in full Hermite reduction. + - ``'partial reduce'``: time spent in partial Hermite reduction + - ``'full reduce'``: time spent in full Hermite reduction. EXAMPLES:: @@ -2860,8 +2860,8 @@ def __repr__(self): def list_of_padics(elements): r""" - Convert a list of p-adic composed elements (such as polynomials, matrices) - to a list of weak references of their p-adic coefficients. + Convert a list of `p`-adic composed elements (such as polynomials, matrices) + to a list of weak references of their `p`-adic coefficients. This is a helper function for the method :meth:`precision_lattice`. diff --git a/src/sage/rings/padics/local_generic.py b/src/sage/rings/padics/local_generic.py index 6db8866aff8..83d77282c2a 100644 --- a/src/sage/rings/padics/local_generic.py +++ b/src/sage/rings/padics/local_generic.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.padics r""" Local Generic diff --git a/src/sage/rings/padics/local_generic_element.pyx b/src/sage/rings/padics/local_generic_element.pyx index e7b9ba76b80..8df39a52363 100644 --- a/src/sage/rings/padics/local_generic_element.pyx +++ b/src/sage/rings/padics/local_generic_element.pyx @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.rings.padics """ Local Generic Element diff --git a/src/sage/rings/padics/misc.py b/src/sage/rings/padics/misc.py index 71f9e80ed99..d3c3a72083d 100644 --- a/src/sage/rings/padics/misc.py +++ b/src/sage/rings/padics/misc.py @@ -71,9 +71,9 @@ def gauss_sum(a, p, f, prec=20, factored=False, algorithm='pari', parent=None): - ``prec`` -- positive integer (optional, 20 by default) - - ``factored`` - boolean (optional, False by default) + - ``factored`` -- boolean (optional, ``False`` by default) - - ``algorithm`` - flag passed to p-adic Gamma function (optional, "pari" by default) + - ``algorithm`` -- flag passed to p-adic Gamma function (optional, ``"pari"`` by default) OUTPUT: @@ -91,25 +91,25 @@ def gauss_sum(a, p, f, prec=20, factored=False, algorithm='pari', parent=None): In this example, we verify that `g_3(0) = -1`:: sage: from sage.rings.padics.misc import gauss_sum - sage: -gauss_sum(0,3,1) + sage: -gauss_sum(0, 3, 1) # optional - sage.rings.padics 1 + O(pi^40) Next, we verify that `g_5(a) g_5(-a) = 5 (-1)^a`:: sage: from sage.rings.padics.misc import gauss_sum - sage: gauss_sum(2,5,1)^2-5 + sage: gauss_sum(2,5,1)^2 - 5 # optional - sage.rings.padics O(pi^84) - sage: gauss_sum(1,5,1)*gauss_sum(3,5,1)+5 + sage: gauss_sum(1,5,1)*gauss_sum(3,5,1) + 5 # optional - sage.rings.padics O(pi^84) Finally, we compute a non-trivial value:: sage: from sage.rings.padics.misc import gauss_sum - sage: gauss_sum(2,13,2) + sage: gauss_sum(2,13,2) # optional - sage.rings.padics 6*pi^2 + 7*pi^14 + 11*pi^26 + 3*pi^62 + 6*pi^74 + 3*pi^86 + 5*pi^98 + pi^110 + 7*pi^134 + 9*pi^146 + 4*pi^158 + 6*pi^170 + 4*pi^194 + pi^206 + 6*pi^218 + 9*pi^230 + O(pi^242) - sage: gauss_sum(2,13,2,prec=5,factored=True) + sage: gauss_sum(2,13,2, prec=5, factored=True) # optional - sage.rings.padics (2, 6 + 6*13 + 10*13^2 + O(13^5)) .. SEEALSO:: diff --git a/src/sage/rings/padics/morphism.pyx b/src/sage/rings/padics/morphism.pyx index 407bc146990..ab64f3c5cae 100644 --- a/src/sage/rings/padics/morphism.pyx +++ b/src/sage/rings/padics/morphism.pyx @@ -29,13 +29,13 @@ from sage.categories.morphism cimport Morphism cdef class FrobeniusEndomorphism_padics(RingHomomorphism): """ - A class implementing Frobenius endomorphisms on padic fields. + A class implementing Frobenius endomorphisms on p-adic fields. """ def __init__ (self,domain,n=1): """ INPUT: - - ``domain`` -- an unramified padic field + - ``domain`` -- an unramified p-adic field - ``n`` -- an integer (default: 1) @@ -271,8 +271,8 @@ cdef class FrobeniusEndomorphism_padics(RingHomomorphism): def is_injective(self): """ - Return true since any power of the Frobenius endomorphism - over an unramified padic field is always injective. + Return ``True`` since any power of the Frobenius endomorphism + over an unramified p-adic field is always injective. EXAMPLES:: @@ -286,8 +286,8 @@ cdef class FrobeniusEndomorphism_padics(RingHomomorphism): def is_surjective(self): """ - Return true since any power of the Frobenius endomorphism - over an unramified padic field is always surjective. + Return ``True`` since any power of the Frobenius endomorphism + over an unramified p-adic field is always surjective. EXAMPLES:: @@ -301,7 +301,7 @@ cdef class FrobeniusEndomorphism_padics(RingHomomorphism): def is_identity(self): """ - Return true if this morphism is the identity morphism. + Return ``True`` if this morphism is the identity morphism. EXAMPLES:: @@ -335,7 +335,7 @@ cdef class FrobeniusEndomorphism_padics(RingHomomorphism): cpdef _richcmp_(left, right, int op): """ - Compare ``left'' and ``right'' + Compare ``left`` and ``right`` EXAMPLES:: diff --git a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx index 3d744acd62c..544921f1df5 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx @@ -10,14 +10,14 @@ r""" This file implements elements of Eisenstein and unramified extensions of `\ZZ_p` and `\QQ_p` with capped relative precision. -For the parent class see padic_extension_leaves.pyx. +For the parent class see :mod:`sage.rings.padics.padic_extension_leaves`. The underlying implementation is through NTL's ``ZZ_pX`` class. Each element contains the following data: - ``ordp`` (``long``) -- A power of the uniformizer to scale the unit by. For unramified extensions this uniformizer is `p`, for Eisenstein - extensions it is not. A value equal to the maximum value of a long + extensions it is not. A value equal to the maximum value of a ``long`` indicates that the element is an exact zero. - ``relprec`` (``long``) -- A signed integer giving the precision to @@ -39,14 +39,14 @@ element contains the following data: may not actually be a unit. This ``ZZ_pX`` is created with global ntl modulus determined by the absolute value of ``relprec``. If ``relprec`` is 0, ``unit`` **is not initialized**, or destructed if - normalized and found to be zero. Otherwise, let `r` be relprec and + normalized and found to be zero. Otherwise, let `r` be ``relprec`` and `e` be the ramification index over `\QQ_p` or `\ZZ_p`. Then the modulus of unit is given by `p^{ceil(r/e)}`. Note that all kinds of problems arise if you try to mix moduli. ``ZZ_pX_conv_modulus`` gives a semi-safe way to convert between different moduli without having to pass through ``ZZX``. -- ``prime_pow`` (some subclass of ``PowComputer_ZZ_pX``) -- a class, +- ``prime_pow`` (some subclass of :class:`PowComputer_ZZ_pX`) -- a class, identical among all elements with the same parent, holding common data. @@ -57,7 +57,7 @@ element contains the following data: + ``prime_pow.f`` -- The inertia degree + ``prime_pow.prec_cap`` -- the unramified precision cap. For - Eisenstein extensions this is the smallest power of p that is + Eisenstein extensions this is the smallest power of `p` that is zero. + ``prime_pow.ram_prec_cap`` -- the ramified precision cap. For @@ -67,14 +67,14 @@ element contains the following data: + ``prime_pow.pow_ZZ_tmp``, prime_pow.pow_mpz_t_tmp``, ``prime_pow.pow_Integer`` -- functions for accessing powers of `p`. The first two return pointers. See - ``sage/rings/padics/pow_computer_ext`` for examples and important + :mod:`sage.rings.padics.pow_computer_ext` for examples and important warnings. + ``prime_pow.get_context``, ``prime_pow.get_context_capdiv``, ``prime_pow.get_top_context`` -- obtain an ``ntl_ZZ_pContext_class`` corresponding to `p^n`. The capdiv version divides by ``prime_pow.e`` as appropriate. - ``top_context`` corresponds to `p^{prec_cap}`. + ``top_context`` corresponds to `p^{\text{prec_cap}}`. + ``prime_pow.restore_context``, ``prime_pow.restore_context_capdiv``, @@ -726,7 +726,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _set_from_mpz_rel(self, mpz_t x, long relprec) except -1: """ - Sets ``self`` from an ``mpz_t`` with relative precision bounded by ``relprec``. + Set ``self`` from an ``mpz_t`` with relative precision bounded by ``relprec``. EXAMPLES:: @@ -772,7 +772,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _set_from_mpz_both(self, mpz_t x, long absprec, long relprec) except -1: """ - Sets ``self`` from an ``mpz_t`` with relative precision bounded by ``relprec`` + Set ``self`` from an ``mpz_t`` with relative precision bounded by ``relprec`` and absolute precision bounded by ``absprec``. EXAMPLES:: @@ -1256,7 +1256,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): If ``relprec`` is negative, will set ``self.relprec`` to be negative (indicating unnormalized unit) - Returns`` True`` iff ``self.relprec = 0``, ie ``self`` was set to an + Returns ``True`` iff ``self.relprec = 0``, ie ``self`` was set to an inexact zero. Note that this will wipe out anything in ``self.unit``. Be @@ -1538,7 +1538,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef int _cmp_units(left, pAdicGenericElement right) except -2: """ - For units ``left`` and ``right``, returns 0 if they are equal up to + For units ``left`` and ``right``, return 0 if they are equal up to the lesser of the two precisions, or 1 if they are not. EXAMPLES:: @@ -2056,7 +2056,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cpdef _add_(self, _right): """ - Computes the sum of ``self`` and ``right``. + Compute the sum of ``self`` and ``right``. EXAMPLES:: @@ -2350,7 +2350,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): is indistinguishable from zero. If this element is an inexact zero of valuation less than ``absprec``, - raises a ``PrecisionError``. + raises a :class:`PrecisionError`. EXAMPLES:: @@ -2660,9 +2660,11 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): sage: a = W(345, 17); a 4*w^5 + 3*w^7 + w^9 + 3*w^10 + 2*w^11 + 4*w^12 + w^13 + 2*w^14 + 2*w^15 + O(w^17) sage: b = a.lift_to_precision(19); b - 4*w^5 + 3*w^7 + w^9 + 3*w^10 + 2*w^11 + 4*w^12 + w^13 + 2*w^14 + 2*w^15 + w^17 + 2*w^18 + O(w^19) + 4*w^5 + 3*w^7 + w^9 + 3*w^10 + 2*w^11 + 4*w^12 + w^13 + 2*w^14 + 2*w^15 + + w^17 + 2*w^18 + O(w^19) sage: c = a.lift_to_precision(24); c - 4*w^5 + 3*w^7 + w^9 + 3*w^10 + 2*w^11 + 4*w^12 + w^13 + 2*w^14 + 2*w^15 + w^17 + 2*w^18 + 4*w^19 + 4*w^20 + 2*w^21 + 4*w^23 + O(w^24) + 4*w^5 + 3*w^7 + w^9 + 3*w^10 + 2*w^11 + 4*w^12 + w^13 + 2*w^14 + 2*w^15 + + w^17 + 2*w^18 + 4*w^19 + 4*w^20 + 2*w^21 + 4*w^23 + O(w^24) sage: a._ntl_rep() [19 35 118 60 121] sage: b._ntl_rep() @@ -2718,7 +2720,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): def expansion(self, n = None, lift_mode = 'simple'): """ - Return a list giving a series representation of self. + Return a list giving a series representation of ``self``. - If ``lift_mode == 'simple'`` or ``'smallest'``, the returned list will consist of integers (in the Eisenstein case) or a @@ -2838,7 +2840,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): the power basis `1, x, x^2, \ldots, x^{d-1}` for this extension field. Thus the *rows* of this matrix give the images of each of the `x^i`. The entries of the matrices are - IntegerMod elements, defined modulo `p^{N / e}` where `N` is + :class:`IntegerMod` elements, defined modulo `p^{N / e}` where `N` is the absolute precision of this element (unless this element is zero to arbitrary precision; in that case the entries are integer zeros.) @@ -2954,7 +2956,11 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): sage: E = a.teichmuller_expansion(); E 5-adic expansion of a + O(5^4) (teichmuller) sage: list(E) - [a + (2*a^3 + 2*a^2 + 3*a + 4)*5 + (4*a^3 + 3*a^2 + 3*a + 2)*5^2 + (4*a^2 + 2*a + 2)*5^3 + O(5^4), (3*a^3 + 3*a^2 + 2*a + 1) + (a^3 + 4*a^2 + 1)*5 + (a^2 + 4*a + 4)*5^2 + O(5^3), (4*a^3 + 2*a^2 + a + 1) + (2*a^3 + 2*a^2 + 2*a + 4)*5 + O(5^2), (a^3 + a^2 + a + 4) + O(5)] + [a + (2*a^3 + 2*a^2 + 3*a + 4)*5 + (4*a^3 + 3*a^2 + 3*a + 2)*5^2 + + (4*a^2 + 2*a + 2)*5^3 + O(5^4), + (3*a^3 + 3*a^2 + 2*a + 1) + (a^3 + 4*a^2 + 1)*5 + (a^2 + 4*a + 4)*5^2 + O(5^3), + (4*a^3 + 2*a^2 + a + 1) + (2*a^3 + 2*a^2 + 2*a + 4)*5 + O(5^2), + (a^3 + a^2 + a + 4) + O(5)] sage: sum([c * 5^i for i, c in enumerate(E)]) a + O(5^4) sage: all(c^625 == c for c in E) @@ -2964,14 +2970,17 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): sage: f = x^3 - 98*x + 7 sage: W. = ZpCR(7,3).ext(f) sage: b = (1+w)^5; L = b.teichmuller_expansion(); L - [1 + O(w^9), 5 + 5*w^3 + w^6 + 4*w^7 + O(w^8), 3 + 3*w^3 + O(w^7), 3 + 3*w^3 + O(w^6), O(w^5), 4 + 5*w^3 + O(w^4), 3 + O(w^3), 6 + O(w^2), 6 + O(w)] + [1 + O(w^9), 5 + 5*w^3 + w^6 + 4*w^7 + O(w^8), 3 + 3*w^3 + O(w^7), + 3 + 3*w^3 + O(w^6), O(w^5), 4 + 5*w^3 + O(w^4), 3 + O(w^3), + 6 + O(w^2), 6 + O(w)] sage: sum([w^i*L[i] for i in range(9)]) == b True sage: all(L[i]^(7^3) == L[i] for i in range(9)) True sage: L = W(3).teichmuller_expansion(); L - [3 + 3*w^3 + w^7 + O(w^9), O(w^8), O(w^7), 4 + 5*w^3 + O(w^6), O(w^5), O(w^4), 3 + O(w^3), 6 + O(w^2)] + [3 + 3*w^3 + w^7 + O(w^9), O(w^8), O(w^7), 4 + 5*w^3 + O(w^6), + O(w^5), O(w^4), 3 + O(w^3), 6 + O(w^2)] sage: sum([w^i*L[i] for i in range(len(L))]) 3 + O(w^9) """ @@ -3039,7 +3048,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): sage: S. = R[] sage: f = x^5 + 77*x^3 - 98*x^2 - 7 sage: W. = R.ext(f) - sage: y = W.teichmuller(3, 15); y #indirect doctest + sage: y = W.teichmuller(3, 15); y # indirect doctest 3 + 4*w^5 + 2*w^8 + 6*w^10 + w^11 + 6*w^12 + 5*w^13 + 4*w^14 + O(w^15) sage: y^7 == y @@ -3081,7 +3090,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): def precision_absolute(self): """ - Return the absolute precision of this element, ie the power of the + Return the absolute precision of this element, i.e., the power of the uniformizer modulo which this element is defined. EXAMPLES:: @@ -3116,7 +3125,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): def precision_relative(self): """ - Return the relative precision of this element, ie the power of the + Return the relative precision of this element, i.e., the power of the uniformizer modulo which the unit part of ``self`` is defined. EXAMPLES:: @@ -3149,7 +3158,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cdef long valuation_c(self): """ - Return the valuation of this element + Return the valuation of this element. EXAMPLES:: @@ -3173,7 +3182,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): cpdef pAdicZZpXCRElement unit_part(self): """ - Return the unit part of this element, ie ``self / uniformizer^(self.valuation())`` + Return the unit part of this element, ie ``self / uniformizer^(self.valuation())``. EXAMPLES:: @@ -3222,7 +3231,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): otherwise they will be in the interval `[(1-p)/2, p/2]`. Note that zeros are truncated from the returned list, so you - must use the ``valuation()`` function to completely recover ``self``. + must use the method :meth:`valuation` to completely recover ``self``. EXAMPLES:: diff --git a/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx index 548a8e635d2..e55dd548c6f 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx @@ -20,7 +20,7 @@ element contains the following data: This ``ZZ_pX`` is created with global ntl modulus determined by the parent's precision cap and shared among all elements. -- ``prime_pow`` (some subclass of ``PowComputer_ZZ_pX``) -- a class, +- ``prime_pow`` (some subclass of :class:`PowComputer_ZZ_pX`) -- a class, identical among all elements with the same parent, holding common data. diff --git a/src/sage/rings/padics/padic_base_leaves.py b/src/sage/rings/padics/padic_base_leaves.py index 3c382fd292b..99823338bc4 100644 --- a/src/sage/rings/padics/padic_base_leaves.py +++ b/src/sage/rings/padics/padic_base_leaves.py @@ -32,8 +32,8 @@ 22 The number of times that `p` divides the element is called the -valuation, and can be accessed with the functions ``valuation()`` and -``ordp()``: +valuation, and can be accessed with the methods :meth:`valuation` and +:meth:`ordp`: sage: a.valuation() 2 @@ -111,7 +111,7 @@ 1 + 2*5^2 + 5^3 `p`-adic rings and fields should be created using the creation -functions ``Zp`` and ``Qp`` as above. This will ensure that there is +functions :func:`Zp` and :func:`Qp` as above. This will ensure that there is only one instance of `\ZZ_p` and `\QQ_p` of a given type, `p`, print mode and precision. It also saves typing very long class names.:: @@ -347,7 +347,7 @@ def __init__(self, p, prec, print_mode, names): def _coerce_map_from_(self, R): """ - Returns ``True`` if there is a coerce map from ``R`` to ``self``. + Return ``True`` if there is a coerce map from ``R`` to ``self``. EXAMPLES:: @@ -446,7 +446,7 @@ def __init__(self, p, prec, print_mode, names): def _coerce_map_from_(self, R): """ - Returns ``True`` if there is a coerce map from ``R`` to ``self``. + Return ``True`` if there is a coerce map from ``R`` to ``self``. EXAMPLES:: @@ -478,7 +478,7 @@ def _coerce_map_from_(self, R): def _convert_map_from_(self, R): """ - Finds conversion maps from R to this ring. + Finds conversion maps from ``R`` to this ring. EXAMPLES:: @@ -548,7 +548,7 @@ def __init__(self, p, prec, print_mode, names): def _coerce_map_from_(self, R): """ - Returns ``True`` if there is a coerce map from ``R`` to ``self``. + Return ``True`` if there is a coerce map from ``R`` to ``self``. EXAMPLES:: @@ -653,7 +653,7 @@ def __init__(self, p, prec, print_mode, names): def _coerce_map_from_(self, R): """ - Returns ``True`` if there is a coerce map from ``R`` to ``self``. + Return ``True`` if there is a coerce map from ``R`` to ``self``. EXAMPLES:: @@ -711,11 +711,11 @@ def _convert_map_from_(self, R): def random_element(self, algorithm='default'): r""" - Returns a random element of ``self``, optionally using the ``algorithm`` + Return a random element of ``self``, optionally using the ``algorithm`` argument to decide how it generates the element. Algorithms currently implemented: - - default: Choose an integer `k` using the standard + - ``'default'``: Choose an integer `k` using the standard distribution on the integers. Then choose an integer `a` uniformly in the range `0 \le a < p^N` where `N` is the precision cap of ``self``. Return ``self(p^k * a, absprec = @@ -778,7 +778,7 @@ def __init__(self, p, prec, print_mode, names): def _coerce_map_from_(self, R): """ - Returns ``True`` if there is a coerce map from ``R`` to ``self``. + Return ``True`` if there is a coerce map from ``R`` to ``self``. EXAMPLES:: @@ -858,7 +858,8 @@ class pAdicRingLattice(pAdicLatticeGeneric, pAdicRingBaseGeneric): EXAMPLES:: sage: R = ZpLC(next_prime(10^60)) # indirect doctest - doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. + doctest:...: FutureWarning: This class/method/function is marked as experimental. + It, its functionality or its interface might change without a formal deprecation. See https://github.com/sagemath/sage/issues/23505 for details. sage: type(R) @@ -937,7 +938,8 @@ def random_element(self, prec=None): sage: R = ZpLC(2) sage: R.random_element() # random - 2^3 + 2^4 + 2^5 + 2^6 + 2^7 + 2^10 + 2^11 + 2^14 + 2^15 + 2^16 + 2^17 + 2^18 + 2^19 + 2^21 + O(2^23) + 2^3 + 2^4 + 2^5 + 2^6 + 2^7 + 2^10 + 2^11 + 2^14 + 2^15 + 2^16 + + 2^17 + 2^18 + 2^19 + 2^21 + O(2^23) sage: R.random_element(prec=10) # random 1 + 2^3 + 2^4 + 2^7 + O(2^10) @@ -987,7 +989,8 @@ class pAdicFieldLattice(pAdicLatticeGeneric, pAdicFieldBaseGeneric): EXAMPLES:: sage: R = QpLC(next_prime(10^60)) # indirect doctest - doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. + doctest:...: FutureWarning: This class/method/function is marked as experimental. + It, its functionality or its interface might change without a formal deprecation. See https://github.com/sagemath/sage/issues/23505 for details. sage: type(R) @@ -1062,7 +1065,7 @@ def random_element(self, prec=None, integral=False): - ``prec`` -- an integer or ``None`` (the default): the absolute precision of the generated random element - - ``integral`` -- a boolean (default: ``False``); if true + - ``integral`` -- a boolean (default: ``False``); if ``True``, return an element in the ring of integers EXAMPLES:: @@ -1071,7 +1074,8 @@ def random_element(self, prec=None, integral=False): sage: K.random_element() # not tested, known bug (see :trac:`32126`) 2^-8 + 2^-7 + 2^-6 + 2^-5 + 2^-3 + 1 + 2^2 + 2^3 + 2^5 + O(2^12) sage: K.random_element(integral=True) # random - 2^3 + 2^4 + 2^5 + 2^6 + 2^7 + 2^10 + 2^11 + 2^14 + 2^15 + 2^16 + 2^17 + 2^18 + 2^19 + O(2^20) + 2^3 + 2^4 + 2^5 + 2^6 + 2^7 + 2^10 + 2^11 + 2^14 + 2^15 + 2^16 + + 2^17 + 2^18 + 2^19 + O(2^20) sage: K.random_element(prec=10) # random 2^(-3) + 1 + 2 + 2^4 + 2^8 + O(2^10) diff --git a/src/sage/rings/padics/padic_extension_leaves.py b/src/sage/rings/padics/padic_extension_leaves.py index f17c6ed5428..ed171e833e4 100644 --- a/src/sage/rings/padics/padic_extension_leaves.py +++ b/src/sage/rings/padics/padic_extension_leaves.py @@ -1,7 +1,7 @@ -""" +r""" `p`-adic Extension Leaves -The final classes for extensions of Zp and Qp (ie classes that are not +The final classes for extensions of `\ZZ_p` and `\QQ_p` (i.e., classes that are not just designed to be inherited from). AUTHORS: @@ -93,8 +93,8 @@ class UnramifiedExtensionRingCappedRelative(UnramifiedExtensionGeneric, pAdicCap sage: TestSuite(R).run(skip='_test_log',max_runs=4) """ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, implementation='FLINT'): - """ - A capped relative representation of Zq. + r""" + A capped relative representation of `\ZZ_q`. INPUT: @@ -102,7 +102,7 @@ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, imp This could be a polynomial with integer coefficients, for example, while ``poly`` has coefficients in a `p`-adic ring. - - ``poly`` -- t polynomial with coefficients in :meth:`base_ring` + - ``poly`` -- the polynomial with coefficients in :meth:`base_ring` defining this extension - ``prec`` -- the precision cap of this ring @@ -152,7 +152,7 @@ class UnramifiedExtensionFieldCappedRelative(UnramifiedExtensionGeneric, pAdicCa """ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, implementation='FLINT'): r""" - A representation of Qq. + A representation of `\QQ_q`. INPUT: @@ -237,21 +237,21 @@ class UnramifiedExtensionRingCappedAbsolute(UnramifiedExtensionGeneric, pAdicCap sage: TestSuite(R).run(skip='_test_log',max_runs=4) """ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, implementation='FLINT'): - """ - A capped absolute representation of Zq. + r""" + A capped absolute representation of `ZZ_q`. INPUT: - ``exact_modulus`` -- the original polynomial defining the extension. This could be a polynomial with integer coefficients, for example, - while poly has coefficients in a `p`-adic ring. + while ``poly`` has coefficients in a `p`-adic ring. - ``poly`` -- the polynomial with coefficients in :meth:`base_ring` defining this extension - ``prec`` -- the precision cap of this ring - - ``print_mode`` -- A dictionary of print options + - ``print_mode`` -- a dictionary of print options - ``shift_seed`` -- unused @@ -358,14 +358,14 @@ class UnramifiedExtensionRingFloatingPoint(UnramifiedExtensionGeneric, pAdicFloa True """ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, implementation='FLINT'): - """ - A floating point representation of Zq. + r""" + A floating point representation of `\ZZ_q`. INPUT: - ``exact_modulus`` -- the original polynomial defining the extension. This could be a polynomial with integer coefficients, for example, - while ``poly`` has coefficients in Zp. + while ``poly`` has coefficients in `\ZZ_p`. - ``poly`` -- the polynomial with coefficients in :meth:`base_ring` defining this extension @@ -415,8 +415,8 @@ class UnramifiedExtensionFieldFloatingPoint(UnramifiedExtensionGeneric, pAdicFlo True """ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, implementation='FLINT'): - """ - A representation of Qq. + r""" + A representation of `\QQ_q`. INPUT: @@ -484,8 +484,8 @@ class EisensteinExtensionRingCappedRelative(EisensteinExtensionGeneric, pAdicCap sage: TestSuite(R).run(skip='_test_log',max_runs=4) """ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, implementation='NTL'): - """ - A capped relative representation of an eisenstein extension of Zp. + r""" + A capped relative representation of an Eisenstein extension of `\ZZ_p`. INPUT: @@ -539,8 +539,8 @@ class EisensteinExtensionFieldCappedRelative(EisensteinExtensionGeneric, pAdicCa sage: TestSuite(R).run(skip='_test_log',max_runs=4) """ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, implementation='NTL'): - """ - A capped relative representation of an eisenstein extension of Qp. + r""" + A capped relative representation of an Eisenstein extension of `\QQ_p`. INPUT: @@ -595,8 +595,8 @@ class EisensteinExtensionRingCappedAbsolute(EisensteinExtensionGeneric, pAdicCap sage: TestSuite(R).run(skip='_test_log',max_runs=4) """ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, implementation): - """ - A capped absolute representation of an eisenstein extension of Zp. + r""" + A capped absolute representation of an Eisenstein extension of `\ZZ_p`. INPUT: @@ -650,8 +650,8 @@ class EisensteinExtensionRingFixedMod(EisensteinExtensionGeneric, pAdicFixedModR sage: TestSuite(R).run(skip='_test_log',max_runs=4) """ def __init__(self, exact_modulus, poly, prec, print_mode, shift_seed, names, implementation='NTL'): - """ - A fixed modulus representation of an eisenstein extension of Zp. + r""" + A fixed modulus representation of an eisenstein extension of `\ZZ_p`. INPUT: @@ -706,7 +706,8 @@ def fraction_field(self): sage: R.fraction_field() Traceback (most recent call last): ... - TypeError: This implementation of the p-adic ring does not support fields of fractions. + TypeError: This implementation of the p-adic ring + does not support fields of fractions. """ raise TypeError("This implementation of the p-adic ring does not support fields of fractions.") diff --git a/src/sage/rings/padics/padic_generic.py b/src/sage/rings/padics/padic_generic.py index bde23bea380..b7caad54122 100644 --- a/src/sage/rings/padics/padic_generic.py +++ b/src/sage/rings/padics/padic_generic.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.padics r""" `p`-adic Generic diff --git a/src/sage/rings/padics/padic_generic_element.pyx b/src/sage/rings/padics/padic_generic_element.pyx index 081c086f5af..534538e28ff 100644 --- a/src/sage/rings/padics/padic_generic_element.pyx +++ b/src/sage/rings/padics/padic_generic_element.pyx @@ -46,7 +46,7 @@ cdef long maxordp = (1L << (sizeof(long) * 8 - 2)) - 1 cdef class pAdicGenericElement(LocalGenericElement): cpdef _richcmp_(left, right, int op): - """ + r""" First compare valuations, then compare normalized residue of unit part. @@ -173,7 +173,7 @@ cdef class pAdicGenericElement(LocalGenericElement): cpdef bint _is_exact_zero(self) except -1: """ - Returns True if self is exactly zero. Since + Return ``True`` if self is exactly zero. Since non-capped-relative elements cannot be exact, this function always returns False. @@ -186,7 +186,7 @@ cdef class pAdicGenericElement(LocalGenericElement): cpdef bint _is_inexact_zero(self) except -1: """ - Returns True if self is indistinguishable from zero, but not + Return ``True`` if self is indistinguishable from zero, but not exactly zero. EXAMPLES:: @@ -198,7 +198,7 @@ cdef class pAdicGenericElement(LocalGenericElement): cpdef bint _is_zero_rep(self) except -1: """ - Returns True is self is indistinguishable from zero. + Return ``True`` is self is indistinguishable from zero. EXAMPLES:: @@ -534,7 +534,7 @@ cdef class pAdicGenericElement(LocalGenericElement): def str(self, mode=None): """ - Returns a string representation of self. + Return a string representation of ``self``. EXAMPLES:: @@ -545,7 +545,7 @@ cdef class pAdicGenericElement(LocalGenericElement): def _repr_(self, mode=None, do_latex=False): r""" - Returns a string representation of this element. + Return a string representation of this element. INPUT: @@ -570,8 +570,8 @@ cdef class pAdicGenericElement(LocalGenericElement): def additive_order(self, prec=None): r""" - Returns the additive order of this element truncated - at precision ``prec`` + Return the additive order of this element truncated + at precision ``prec``. INPUT: @@ -606,11 +606,11 @@ cdef class pAdicGenericElement(LocalGenericElement): the desired precision on the result; if ``None``, the precision is derived from the precision on the input - - ``algorithm`` -- ``direct``, ``series``, ``newton`` or + - ``algorithm`` -- ``'direct'``, ``'series'``, ``'newton'`` or ``None`` (default) The direct algorithm computes the Artin-Hasse exponential - of ``x``, namely ``AH(x)`` as + of `x`, namely ``AH(x)`` as .. MATH:: @@ -622,7 +622,7 @@ cdef class pAdicGenericElement(LocalGenericElement): The series algorithm computes the series defining the Artin-Hasse exponential and evaluates it. - The ``Newton`` algorithm solves the equation + The ``'newton'`` algorithm solves the equation .. MATH:: @@ -631,11 +631,11 @@ cdef class pAdicGenericElement(LocalGenericElement): using a Newton scheme. It runs roughly as fast as the computation of the logarithm. - By default, we use the direct algorithm if a fast algorithm for + By default, we use the ``'direct'`` algorithm if a fast algorithm for computing the exponential is available. - If not, we use the Newton algorithm if a fast algorithm for + If not, we use the ``'newton'`` algorithm if a fast algorithm for computing the logarithm is available. - Otherwise we switch to the series algorithm. + Otherwise we switch to the ``'series'`` algorithm. OUTPUT: @@ -849,11 +849,11 @@ cdef class pAdicGenericElement(LocalGenericElement): AH(x) = \exp(x + \frac{x^p}{p} + \frac{x^{p^2}}{p^2} + \dots) - at enough precision and the plug the input element in it. + at enough precision and then plugs in the input element. INPUT: - - ``prec`` -- an integer, this precision at which the + - ``prec`` -- an integer, the precision at which the result should be computed EXAMPLES:: @@ -889,8 +889,8 @@ cdef class pAdicGenericElement(LocalGenericElement): r""" Return the Artin-Hasse exponential of this element. - If ``x`` denotes the input element, its Artin-Hasse exponential - is computed by solving the following equation in ``y`` + If `x` denotes the input element, its Artin-Hasse exponential + is computed by solving the following equation in `y` .. MATH:: @@ -903,7 +903,7 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``prec`` -- an integer, this precision at which the + - ``prec`` -- an integer, the precision at which the result should be computed EXAMPLES:: @@ -972,7 +972,7 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``name`` -- string (default: ``x``): the name of the variable + - ``name`` -- string (default: ``'x'``): the name of the variable - ``base`` -- a ring (default: the base ring of the parent): the base ring over which the minimal polynomial is computed @@ -1035,13 +1035,13 @@ cdef class pAdicGenericElement(LocalGenericElement): def norm(self, base=None): """ - Returns the norm of this `p`-adic element over ``base``. + Return the norm of this `p`-adic element over ``base``. .. WARNING:: This is not the `p`-adic absolute value. This is a field theoretic norm down to a base ring. If you want the - `p`-adic absolute value, use the ``abs()`` function + `p`-adic absolute value, use the method :meth:`abs` instead. INPUT: @@ -1135,22 +1135,23 @@ cdef class pAdicGenericElement(LocalGenericElement): irreducible, and indeed usually won't be if this number is a good approximation to an algebraic number of degree less than `n`. - ALGORITHM: Uses the PARI C-library ``algdep`` command. + ALGORITHM: Uses the PARI C-library :pari:`algdep` command. INPUT: - - ``self`` -- a p-adic element + - ``self`` -- a `p`-adic element - ``n`` -- an integer OUTPUT: - polynomial -- degree n polynomial approximately satisfied by self + polynomial -- degree `n` polynomial approximately satisfied by ``self`` EXAMPLES:: sage: K = Qp(3,20,'capped-rel','series'); R = Zp(3,20,'capped-rel','series') sage: a = K(7/19); a - 1 + 2*3 + 3^2 + 3^3 + 2*3^4 + 2*3^5 + 3^8 + 2*3^9 + 3^11 + 3^12 + 2*3^15 + 2*3^16 + 3^17 + 2*3^19 + O(3^20) + 1 + 2*3 + 3^2 + 3^3 + 2*3^4 + 2*3^5 + 3^8 + 2*3^9 + 3^11 + 3^12 + + 2*3^15 + 2*3^16 + 3^17 + 2*3^19 + O(3^20) sage: a.algdep(1) 19*x - 7 sage: K2 = Qp(7,20,'capped-rel') @@ -1160,7 +1161,8 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: b = K2.zeta(); b.algdep(4) x^4 - x^3 + x^2 - x + 1 sage: a = R(7/19); a - 1 + 2*3 + 3^2 + 3^3 + 2*3^4 + 2*3^5 + 3^8 + 2*3^9 + 3^11 + 3^12 + 2*3^15 + 2*3^16 + 3^17 + 2*3^19 + O(3^20) + 1 + 2*3 + 3^2 + 3^3 + 2*3^4 + 2*3^5 + 3^8 + 2*3^9 + 3^11 + 3^12 + + 2*3^15 + 2*3^16 + 3^17 + 2*3^19 + O(3^20) sage: a.algdep(1) 19*x - 7 sage: R2 = Zp(7,20,'capped-rel') @@ -1181,7 +1183,7 @@ cdef class pAdicGenericElement(LocalGenericElement): be irreducible, and indeed usually won't be if this number is a good approximation to an algebraic number of degree less than `n`. - ALGORITHM: Uses the PARI C-library algdep command. + ALGORITHM: Uses the PARI C-library :pari:`algdep` command. INPUT: @@ -1190,13 +1192,14 @@ cdef class pAdicGenericElement(LocalGenericElement): OUTPUT: - polynomial -- degree n polynomial approximately satisfied by self + polynomial -- degree `n` polynomial approximately satisfied by ``self`` EXAMPLES:: sage: K = Qp(3,20,'capped-rel','series'); R = Zp(3,20,'capped-rel','series') sage: a = K(7/19); a - 1 + 2*3 + 3^2 + 3^3 + 2*3^4 + 2*3^5 + 3^8 + 2*3^9 + 3^11 + 3^12 + 2*3^15 + 2*3^16 + 3^17 + 2*3^19 + O(3^20) + 1 + 2*3 + 3^2 + 3^3 + 2*3^4 + 2*3^5 + 3^8 + 2*3^9 + 3^11 + 3^12 + + 2*3^15 + 2*3^16 + 3^17 + 2*3^19 + O(3^20) sage: a.algebraic_dependency(1) 19*x - 7 sage: K2 = Qp(7,20,'capped-rel') @@ -1206,7 +1209,8 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: b = K2.zeta(); b.algebraic_dependency(4) x^4 - x^3 + x^2 - x + 1 sage: a = R(7/19); a - 1 + 2*3 + 3^2 + 3^3 + 2*3^4 + 2*3^5 + 3^8 + 2*3^9 + 3^11 + 3^12 + 2*3^15 + 2*3^16 + 3^17 + 2*3^19 + O(3^20) + 1 + 2*3 + 3^2 + 3^3 + 2*3^4 + 2*3^5 + 3^8 + 2*3^9 + 3^11 + 3^12 + + 2*3^15 + 2*3^16 + 3^17 + 2*3^19 + O(3^20) sage: a.algebraic_dependency(1) 19*x - 7 sage: R2 = Zp(7,20,'capped-rel') @@ -1239,7 +1243,7 @@ cdef class pAdicGenericElement(LocalGenericElement): OUTPUT: - A ``p``-- adic integer. + A `p`-adic integer. .. NOTE:: @@ -1301,9 +1305,9 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - ``algorithm`` -- string. Can be set to ``'pari'`` to call - the pari function, or ``'sage'`` to call the function - implemented in sage. The default is ``'pari'`` since - pari is about 10 times faster than sage. + the PARI function, or ``'sage'`` to call the function + implemented in Sage. The default is ``'pari'`` since + PARI is about 10 times faster than Sage. OUTPUT: @@ -1315,7 +1319,7 @@ cdef class pAdicGenericElement(LocalGenericElement): Villegas (http://www.ma.utexas.edu/cnt/cnt-frames.html). William Stein sped it up for GP (http://sage.math.washington.edu/home/wstein/www/home/wbhart/pari-2.4.2.alpha/src/basemath/trans2.c). - The 'sage' version uses dwork_expansion() to compute the + The ``'sage'`` version uses dwork_expansion() to compute the `p`-adic gamma function of self as in [RV2007]_ section 6.2. EXAMPLES: @@ -1732,7 +1736,7 @@ cdef class pAdicGenericElement(LocalGenericElement): INPUT: - - ``self`` -- a p-adic element + - ``self`` -- a `p`-adic element EXAMPLES:: @@ -1900,17 +1904,17 @@ cdef class pAdicGenericElement(LocalGenericElement): def multiplicative_order(self, prec = None): r""" - Returns the multiplicative order of self, where self is + Returns the multiplicative order of ``self``, where ``self`` is considered to be one if it is one modulo `p^{\mbox{prec}}`. INPUT: - - ``self`` -- a p-adic element + - ``self`` -- a `p`-adic element - ``prec`` -- an integer OUTPUT: - - integer -- the multiplicative order of self + - integer -- the multiplicative order of ``self`` EXAMPLES:: @@ -1996,22 +2000,22 @@ cdef class pAdicGenericElement(LocalGenericElement): return infinity def valuation(self, p = None): - """ - Returns the valuation of this element. + r""" + Return the valuation of this element. INPUT: - - ``self`` -- a p-adic element - - ``p`` -- a prime (default: None). If specified, will make sure that p==self.parent().prime() + - ``self`` -- a `p`-adic element + - ``p`` -- a prime (default: ``None``). If specified, will make sure that ``p == self.parent().prime()`` .. NOTE:: - The optional argument p is used for consistency with the valuation - methods on integer and rational. + The optional argument `p` is used for consistency with the valuation + methods on integers and rationals. OUTPUT: - integer -- the valuation of self + integer -- the valuation of ``self`` EXAMPLES:: @@ -2109,7 +2113,7 @@ cdef class pAdicGenericElement(LocalGenericElement): raise NotImplementedError cpdef val_unit(self): - """ + r""" Return ``(self.valuation(), self.unit_part())``. To be overridden in derived classes. @@ -2122,21 +2126,21 @@ cdef class pAdicGenericElement(LocalGenericElement): def ordp(self, p = None): r""" - Returns the valuation of self, normalized so that the valuation of `p` is 1 + Return the valuation of ``self``, normalized so that the valuation of `p` is 1. INPUT: - - ``self`` -- a p-adic element + - ``self`` -- a `p`-adic element - ``p`` -- a prime (default: ``None``). If specified, will make sure that ``p == self.parent().prime()`` .. NOTE:: - The optional argument p is used for consistency with the valuation - methods on integer and rational. + The optional argument `p` is used for consistency with the valuation + methods on integers and rationals. OUTPUT: - integer -- the valuation of self, normalized so that the valuation of `p` is 1 + integer -- the valuation of ``self``, normalized so that the valuation of `p` is 1 EXAMPLES:: @@ -2162,7 +2166,7 @@ cdef class pAdicGenericElement(LocalGenericElement): def is_prime(self): """ - Return whether this element is prime in its parent + Return whether this element is prime in its parent. EXAMPLES:: @@ -2192,9 +2196,9 @@ cdef class pAdicGenericElement(LocalGenericElement): def rational_reconstruction(self): r""" - Returns a rational approximation to this `p`-adic number + Returns a rational approximation to this `p`-adic number. - This will raise an ArithmeticError if there are no valid + This will raise an :class:`ArithmeticError` if there are no valid approximations to the unit part with numerator and denominator bounded by ``sqrt(p^absprec / 2)``. @@ -2204,7 +2208,7 @@ cdef class pAdicGenericElement(LocalGenericElement): OUTPUT: - rational -- an approximation to self + rational -- an approximation to ``self`` EXAMPLES:: @@ -2245,7 +2249,7 @@ cdef class pAdicGenericElement(LocalGenericElement): def _number_field_(self, K): r""" - Return an element of K approximating this p-adic number. + Return an element of `K` approximating this `p`-adic number. INPUT: @@ -2546,7 +2550,7 @@ cdef class pAdicGenericElement(LocalGenericElement): the same as the input (default) or if it should change to the fraction field of the input. - - ``algorithm`` -- ``generic``, ``binary_splitting`` or ``None`` (default) + - ``algorithm`` -- ``'generic'``, ``'binary_splitting'`` or ``None`` (default) The generic algorithm evaluates naively the series defining the log, namely @@ -2556,10 +2560,10 @@ cdef class pAdicGenericElement(LocalGenericElement): Its binary complexity is quadratic with respect to the precision. - The binary splitting algorithm is faster, it has a quasi-linear + The ``'binary_splitting'`` algorithm is faster, it has a quasi-linear complexity. - By default, we use the binary splitting if it is available. Otherwise - we switch to the generic algorithm. + By default, we use ``'binary_splitting'`` if it is available. Otherwise + we switch to the ``'generic'`` algorithm. .. NOTE:: @@ -2573,7 +2577,7 @@ cdef class pAdicGenericElement(LocalGenericElement): .. TODO:: There is a soft-linear time algorithm for logarithm described - by Dan Berstein at + by Dan Bernstein at http://cr.yp.to/lineartime/multapps-20041007.pdf EXAMPLES:: @@ -2656,15 +2660,19 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: b.log(p_branch=w) w + O(w^20) sage: b.log(pi_branch=0) - 3*w^2 + 2*w^4 + 2*w^6 + 3*w^8 + 4*w^10 + w^13 + w^14 + 2*w^15 + 2*w^16 + w^18 + 4*w^19 + O(w^20) + 3*w^2 + 2*w^4 + 2*w^6 + 3*w^8 + 4*w^10 + w^13 + w^14 + 2*w^15 + + 2*w^16 + w^18 + 4*w^19 + O(w^20) sage: b.unit_part().log() - 3*w^2 + 2*w^4 + 2*w^6 + 3*w^8 + 4*w^10 + w^13 + w^14 + 2*w^15 + 2*w^16 + w^18 + 4*w^19 + O(w^20) + 3*w^2 + 2*w^4 + 2*w^6 + 3*w^8 + 4*w^10 + w^13 + w^14 + 2*w^15 + + 2*w^16 + w^18 + 4*w^19 + O(w^20) sage: y = w^2 * 4*w^7; y 4*w^9 + O(w^29) sage: y.log(p_branch=0) - 2*w^2 + 2*w^4 + 2*w^6 + 2*w^8 + w^10 + w^12 + 4*w^13 + 4*w^14 + 3*w^15 + 4*w^16 + 4*w^17 + w^18 + 4*w^19 + O(w^20) + 2*w^2 + 2*w^4 + 2*w^6 + 2*w^8 + w^10 + w^12 + 4*w^13 + 4*w^14 + 3*w^15 + + 4*w^16 + 4*w^17 + w^18 + 4*w^19 + O(w^20) sage: y.log(p_branch=w) - w + 2*w^2 + 2*w^4 + 4*w^5 + 2*w^6 + 2*w^7 + 2*w^8 + 4*w^9 + w^10 + 3*w^11 + w^12 + 4*w^14 + 4*w^16 + 2*w^17 + w^19 + O(w^20) + w + 2*w^2 + 2*w^4 + 4*w^5 + 2*w^6 + 2*w^7 + 2*w^8 + 4*w^9 + w^10 + + 3*w^11 + w^12 + 4*w^14 + 4*w^16 + 2*w^17 + w^19 + O(w^20) Check that log is multiplicative:: @@ -2677,7 +2685,8 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: A. = R.ext(g) sage: b = 1 + 5*(1 + a^2) + 5^3*(3 + 2*a) sage: b.log() - (a^2 + 1)*5 + (3*a^2 + 4*a + 2)*5^2 + (3*a^2 + 2*a)*5^3 + (3*a^2 + 2*a + 2)*5^4 + O(5^5) + (a^2 + 1)*5 + (3*a^2 + 4*a + 2)*5^2 + (3*a^2 + 2*a)*5^3 + + (3*a^2 + 2*a + 2)*5^4 + O(5^5) Check that log is multiplicative:: @@ -2685,7 +2694,7 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: b.log() + c.log() - (b*c).log() O(5^5) - We illustrate the effect of the precision argument:: + We illustrate the effect of the ``precision`` argument:: sage: R = ZpCA(7,10) sage: x = R(41152263); x @@ -2723,7 +2732,8 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: w.log(p_branch=2) Traceback (most recent call last): ... - ValueError: logarithm is not integral, use change_frac=True to obtain a result in the fraction field + ValueError: logarithm is not integral, use change_frac=True + to obtain a result in the fraction field sage: w.log(p_branch=2, change_frac=True) 2*w^-3 + O(w^24) @@ -3148,10 +3158,10 @@ cdef class pAdicGenericElement(LocalGenericElement): - ``aprec`` -- an integer or ``None`` (default: ``None``); if specified, computes only up to the indicated precision - - ``algorithm`` -- ``generic``, ``binary_splitting``, ``newton`` + - ``algorithm`` -- ``'generic'``, ``'binary_splitting'``, ``'newton'`` or ``None`` (default) - The generic algorithm evaluates naively the series defining the + The ``'generic'`` algorithm evaluates naively the series defining the exponential, namely .. MATH:: @@ -3160,17 +3170,17 @@ cdef class pAdicGenericElement(LocalGenericElement): Its binary complexity is quadratic with respect to the precision. - The binary splitting algorithm is faster, it has a quasi-linear + The ``'binary_splitting'`` algorithm is faster, it has a quasi-linear complexity. - The ``Newton`` algorithms solve the equation `\log(x) =` ``self`` + The ``'newton'`` algorithms solve the equation `\log(x) =` ``self`` using a Newton scheme. It runs roughly as fast as the computation of the logarithm. - By default, we use the binary splitting if it is available. - If it is not, we use the Newton algorithm if a fast algorithm for + By default, we use the ``'binary_splitting'`` if it is available. + If it is not, we use the ``'newton'`` algorithm if a fast algorithm for computing the logarithm is available. - Otherwise we switch to the generic algorithm. + Otherwise we switch to the ``'generic'`` algorithm. EXAMPLES: @@ -3194,7 +3204,8 @@ cdef class pAdicGenericElement(LocalGenericElement): exponentials:: sage: R = Zp(5,10) - sage: e = R(2*5 + 2*5**2 + 4*5**3 + 3*5**4 + 5**5 + 3*5**7 + 2*5**8 + 4*5**9).add_bigoh(10); e + sage: e = R(2*5 + 2*5**2 + 4*5**3 + 3*5**4 + ....: + 5**5 + 3*5**7 + 2*5**8 + 4*5**9).add_bigoh(10); e 2*5 + 2*5^2 + 4*5^3 + 3*5^4 + 5^5 + 3*5^7 + 2*5^8 + 4*5^9 + O(5^10) sage: e.exp()*R.teichmuller(4) 4 + 2*5 + 3*5^3 + O(5^10) @@ -3202,7 +3213,8 @@ cdef class pAdicGenericElement(LocalGenericElement): :: sage: K = Qp(5,10) - sage: e = K(2*5 + 2*5**2 + 4*5**3 + 3*5**4 + 5**5 + 3*5**7 + 2*5**8 + 4*5**9).add_bigoh(10); e + sage: e = K(2*5 + 2*5**2 + 4*5**3 + 3*5**4 + ....: + 5**5 + 3*5**7 + 2*5**8 + 4*5**9).add_bigoh(10); e 2*5 + 2*5^2 + 4*5^3 + 3*5^4 + 5^5 + 3*5^7 + 2*5^8 + 4*5^9 + O(5^10) sage: e.exp()*K.teichmuller(4) 4 + 2*5 + 3*5^3 + O(5^10) @@ -3373,15 +3385,15 @@ cdef class pAdicGenericElement(LocalGenericElement): - ``extend`` -- a boolean (default: ``True``); if ``True``, return a square root in an extension if necessary; if ``False`` and no root - exists in the given ring or field, raise a ValueError. + exists in the given ring or field, raise a :class:`ValueError`. - ``all`` -- a boolean (default: ``False``); if ``True``, return a list of all square roots. - ``algorithm`` -- ``"pari"``, ``"sage"`` or ``None`` (default: ``None``); Sage provides an implementation for any extension of - `Q_p` whereas only square roots over `Q_p` is implemented in Pari; - the default is ``"pari"`` if the ground field is `Q_p`, ``"sage"`` + `\QQ_p`, whereas only square roots over `\QQ_p` are implemented in PARI; + the default is ``"pari"`` if the ground field is `\QQ_p`, ``"sage"`` otherwise. OUTPUT: @@ -3426,7 +3438,8 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: R. = Zq(2^10, 10) sage: u = 1 + 8*t sage: u.square_root() - 1 + t*2^2 + t^2*2^3 + t^2*2^4 + (t^4 + t^3 + t^2)*2^5 + (t^4 + t^2)*2^6 + (t^5 + t^2)*2^7 + (t^6 + t^5 + t^4 + t^2)*2^8 + O(2^9) + 1 + t*2^2 + t^2*2^3 + t^2*2^4 + (t^4 + t^3 + t^2)*2^5 + (t^4 + t^2)*2^6 + + (t^5 + t^2)*2^7 + (t^6 + t^5 + t^4 + t^2)*2^8 + O(2^9) sage: R. = Zp(2).extension(x^3 - 2) sage: u = R(1 + a^4 + a^5 + a^7 + a^8, 10); u @@ -3566,14 +3579,14 @@ cdef class pAdicGenericElement(LocalGenericElement): def nth_root(self, n, all=False): """ - Return the nth root of this element. + Return the `n`-th root of this element. INPUT: - ``n`` -- an integer - ``all`` -- a boolean (default: ``False``): if ``True``, - return all ntn roots of this element, instead of just one. + return all `n`-th roots of this element, instead of just one. EXAMPLES:: @@ -3593,7 +3606,7 @@ cdef class pAdicGenericElement(LocalGenericElement): When `n` is divisible by the underlying prime `p`, we are losing precision (which is consistent with the fact - that raising to the pth power increases precision):: + that raising to the `p`-th power increases precision):: sage: z = x.nth_root(5); z 1 + 5^2 + 3*5^3 + 2*5^4 + 5^5 + 3*5^7 + 2*5^8 + O(5^9) @@ -3610,7 +3623,7 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: R(5).nth_root(7, all=True) [pi + O(pi^141)] - An error is raised if the given element is not a nth power + An error is raised if the given element is not an `n`-th power in the ring:: sage: R(5).nth_root(11) @@ -3632,7 +3645,7 @@ cdef class pAdicGenericElement(LocalGenericElement): sage: K = Qp(29) sage: x = polygen(K) - sage: L. = K.extension(x^2 -29) + sage: L. = K.extension(x^2 - 29) sage: L(4).nth_root(2) 2 + O(a^40) @@ -4036,8 +4049,8 @@ cdef class pAdicGenericElement(LocalGenericElement): return Rational(K.prime())**(-self.valuation()) cpdef bint _is_base_elt(self, p) except -1: - """ - Return ``True`` if this element is an element of Zp or Qp (rather than + r""" + Return ``True`` if this element is an element of `\ZZ_p` or `\QQ_p` (rather than an extension). INPUT: @@ -4148,7 +4161,7 @@ cdef class pAdicGenericElement(LocalGenericElement): - ``n`` -- a non-negative integer - ``p_branch`` -- an element in the base ring or its fraction field; the implementation will choose the branch of the - logarithm which sends `p` to ``branch`` + logarithm which sends `p` to ``p_branch`` EXAMPLES: @@ -4480,7 +4493,7 @@ cpdef dwork_mahler_coeffs(R, int bd=20): INPUT: - - ``R`` -- p-adic ring in which to compute + - ``R`` -- `p`-adic ring in which to compute - ``bd`` -- integer. Number of terms in the expansion to use OUTPUT: @@ -4494,9 +4507,11 @@ cpdef dwork_mahler_coeffs(R, int bd=20): sage: v = dwork_mahler_coeffs(R) sage: x = R(1/7) sage: evaluate_dwork_mahler(v, x, 3, 20, 1) - 2 + 2*3 + 3^2 + 3^3 + 3^4 + 3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^11 + 2*3^12 + 3^13 + 3^14 + 2*3^16 + 3^17 + 3^19 + O(3^20) - sage: x.dwork_expansion(a=1) # Same result - 2 + 2*3 + 3^2 + 3^3 + 3^4 + 3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^11 + 2*3^12 + 3^13 + 3^14 + 2*3^16 + 3^17 + 3^19 + O(3^20) + 2 + 2*3 + 3^2 + 3^3 + 3^4 + 3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^11 + + 2*3^12 + 3^13 + 3^14 + 2*3^16 + 3^17 + 3^19 + O(3^20) + sage: x.dwork_expansion(a=1) # Same result + 2 + 2*3 + 3^2 + 3^3 + 3^4 + 3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^11 + + 2*3^12 + 3^13 + 3^14 + 2*3^16 + 3^17 + 3^19 + O(3^20) """ from sage.rings.padics.factory import Qp cdef int i @@ -4528,9 +4543,11 @@ cpdef evaluate_dwork_mahler(v, x, long long p, int bd, long long a): sage: v = dwork_mahler_coeffs(R) sage: x = R(1/7) sage: evaluate_dwork_mahler(v, x, 3, 20, 1) - 2 + 2*3 + 3^2 + 3^3 + 3^4 + 3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^11 + 2*3^12 + 3^13 + 3^14 + 2*3^16 + 3^17 + 3^19 + O(3^20) - sage: x.dwork_expansion(a=1) # Same result - 2 + 2*3 + 3^2 + 3^3 + 3^4 + 3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^11 + 2*3^12 + 3^13 + 3^14 + 2*3^16 + 3^17 + 3^19 + O(3^20) + 2 + 2*3 + 3^2 + 3^3 + 3^4 + 3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^11 + + 2*3^12 + 3^13 + 3^14 + 2*3^16 + 3^17 + 3^19 + O(3^20) + sage: x.dwork_expansion(a=1) # Same result + 2 + 2*3 + 3^2 + 3^3 + 3^4 + 3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + 2*3^11 + + 2*3^12 + 3^13 + 3^14 + 2*3^16 + 3^17 + 3^19 + O(3^20) """ cdef int k bd -= 1 @@ -4569,16 +4586,16 @@ cpdef gauss_table(long long p, int f, int prec, bint use_longs): INPUT: - - `p` - prime - - `f`, `prec` - positive integers - - `use_longs` - boolean; if True, computations are done in C long long + - ``p`` - prime + - ``f``, ``prec`` - positive integers + - ``use_longs`` - boolean; if ``True``, computations are done in C ``long long`` integers rather than Sage `p`-adics, and the results are returned as a Python array rather than a list. OUTPUT: A list of length `q-1=p^f-1`. The entries are `p`-adic units created with - absolute precision `prec`. + absolute precision ``prec``. EXAMPLES:: diff --git a/src/sage/rings/padics/padic_printing.pyx b/src/sage/rings/padics/padic_printing.pyx index bd4715a7859..344a1e544a7 100644 --- a/src/sage/rings/padics/padic_printing.pyx +++ b/src/sage/rings/padics/padic_printing.pyx @@ -48,16 +48,16 @@ cdef enum print_modes: def pAdicPrinter(ring, options={}): """ - Creates a pAdicPrinter. + Create a :class:`pAdicPrinter`. INPUT: - - ring -- a p-adic ring or field. + - ring -- a p-adic ring or field. - - options -- a dictionary, with keys in 'mode', 'pos', - 'ram_name', 'unram_name', 'var_name', 'max_ram_terms', - 'max_unram_terms', 'max_terse_terms', 'sep', 'alphabet'; see - pAdicPrinter_class for the meanings of these keywords. + - options -- a dictionary, with keys in ``'mode'``, ``'pos'``, + ``'ram_name'``, ``'unram_name'``, ``'var_name'``, ``'max_ram_terms'``, + ``'max_unram_terms'``, ``'max_terse_terms'``, ``'sep'``, ``'alphabet'``; see + :class:`pAdicPrinter_class` for the meanings of these keywords. EXAMPLES:: @@ -76,7 +76,7 @@ class pAdicPrinterDefaults(SageObject): This class stores global defaults for p-adic printing. """ def __init__(self, mode = 'series', pos = True, max_ram_terms = -1, max_unram_terms = -1, max_terse_terms = -1, sep = "|", alphabet = None): - """ + r""" Instances of this class store global defaults used in determining printing options during the creation of p-adic rings and fields. One instance stored in padic_printing @@ -109,13 +109,13 @@ class pAdicPrinterDefaults(SageObject): self._alphabet = alphabet def mode(self, mode=None): - """ + r""" Set the default printing mode. - mode=None returns the current value. + ``mode=None`` returns the current value. - The allowed values for mode are: 'val-unit', 'series', - 'terse', 'digits' and 'bars'. + The allowed values for mode are: ``'val-unit'``, ``'series'``, + ``'terse'``, ``'digits'`` and ``'bars'``. EXAMPLES:: @@ -150,10 +150,10 @@ class pAdicPrinterDefaults(SageObject): raise ValueError("invalid printing mode") def allow_negatives(self, neg = None): - """ + r""" Controls whether or not to display a balanced representation. - neg=None returns the current value. + ``neg=None`` returns the current value. EXAMPLES:: @@ -172,13 +172,13 @@ class pAdicPrinterDefaults(SageObject): self._pos = not neg def max_series_terms(self, max = None): - """ + r""" Controls the maximum number of terms shown when printing in - 'series', 'digits' or 'bars' mode. + ``'series'``, ``'digits'`` or ``'bars'`` mode. - max=None returns the current value. + ``max=None`` returns the current value. - max=-1 encodes 'no limit.' + ``max=-1`` encodes 'no limit.' EXAMPLES:: @@ -197,14 +197,14 @@ class pAdicPrinterDefaults(SageObject): self._max_ram_terms = int(max) def max_unram_terms(self, max = None): - """ + r""" For rings with non-prime residue fields, controls how many - terms appear in the coefficient of each pi^n when printing in - 'series' or 'bar' modes. + terms appear in the coefficient of each ``pi^n`` when printing in + ``'series'`` or ``'bar'`` modes. - max=None returns the current value. + ``max=None`` returns the current value. - max=-1 encodes 'no limit.' + ``max=-1`` encodes 'no limit.' EXAMPLES:: @@ -222,13 +222,13 @@ class pAdicPrinterDefaults(SageObject): self._max_unram_terms = int(max) def max_poly_terms(self, max = None): - """ + r""" Controls the number of terms appearing when printing - polynomial representations in 'terse' or 'val-unit' modes. + polynomial representations in ``'terse'`` or ``'val-unit'`` modes. - max=None returns the current value. + ``max=None`` returns the current value. - max=-1 encodes 'no limit.' + ``max=-1`` encodes 'no limit.' EXAMPLES:: @@ -248,10 +248,10 @@ class pAdicPrinterDefaults(SageObject): self._max_terse_terms = int(max) def sep(self, sep = None): - """ - Controls the separator used in 'bars' mode. + r""" + Controls the separator used in ``'bars'`` mode. - sep=None returns the current value. + ``sep=None`` returns the current value. EXAMPLES:: @@ -271,13 +271,13 @@ class pAdicPrinterDefaults(SageObject): self._sep = str(sep) def alphabet(self, alphabet = None): - """ + r""" Controls the alphabet used to translate p-adic digits into - strings (so that no separator need be used in 'digits' mode). + strings (so that no separator need be used in ``'digits'`` mode). - alphabet should be passed in as a list or tuple. + ``alphabet`` should be passed in as a list or tuple. - alphabet=None returns the current value. + ``alphabet=None`` returns the current value. EXAMPLES:: @@ -305,11 +305,11 @@ cdef class pAdicPrinter_class(SageObject): """ def __init__(self, ring, mode, pos, ram_name, unram_name, var_name, max_ram_terms, max_unram_terms, max_terse_terms, sep, alphabet, show_prec): """ - Initializes a pAdicPrinter. + Initializes a :class:`pAdicPrinter`. INPUT: - - ring -- the ring or field to which this pAdicPrinter is + - ring -- the ring or field to which this :class:`pAdicPrinter` is attached. - mode -- The allowed values for mode are: 'val-unit', @@ -514,14 +514,14 @@ cdef class pAdicPrinter_class(SageObject): def richcmp_modes(pAdicPrinter_class self, pAdicPrinter_class other, int op): """ - Return a comparison of the printing modes of self and other. + Return a comparison of the printing modes of ``self`` and ``other``. Return 0 if and only if all relevant modes are equal - (max_unram_terms is irrelevant if the ring is totally ramified - over the base for example). This does not check if the rings are + (``max_unram_terms`` is irrelevant if the ring is totally ramified + over the base, for example). This does not check if the rings are equal (to prevent infinite recursion in the comparison functions of p-adic rings), but it does check if the primes - are the same (since the prime affects whether pos is + are the same (since the prime affects whether ``pos`` is relevant). EXAMPLES:: @@ -531,7 +531,7 @@ cdef class pAdicPrinter_class(SageObject): sage: R._printer == S._printer True sage: R = Qp(7) - sage: S = Qp(7,print_mode='val-unit') + sage: S = Qp(7, print_mode='val-unit') sage: R == S False sage: R._printer < S._printer @@ -636,7 +636,7 @@ cdef class pAdicPrinter_class(SageObject): def dict(self): """ - Returns a dictionary storing all of self's printing options. + Return a dictionary storing all of ``self``'s printing options. EXAMPLES:: @@ -849,10 +849,10 @@ cdef class pAdicPrinter_class(SageObject): INPUT: - - elt -- a p-adic element of the appropriate ring to print. + - ``elt`` -- a p-adic element of the appropriate ring to print. - - do_latex -- whether to return a latex representation or - a normal one. + - ``do_latex`` -- whether to return a latex representation or + a normal one. EXAMPLES:: diff --git a/src/sage/rings/padics/unramified_extension_generic.py b/src/sage/rings/padics/unramified_extension_generic.py index 7973ed814c3..5bc08a7a54f 100644 --- a/src/sage/rings/padics/unramified_extension_generic.py +++ b/src/sage/rings/padics/unramified_extension_generic.py @@ -26,21 +26,21 @@ class UnramifiedExtensionGeneric(pAdicExtensionGeneric): - """ - An unramified extension of Qp or Zp. + r""" + An unramified extension of `\QQ_p` or `\ZZ_p`. """ def __init__(self, poly, prec, print_mode, names, element_class): """ - Initializes self + Initializes ``self``. INPUT: - - poly -- Polynomial defining this extension. - - prec -- The precision cap - - print_mode -- a dictionary with print options - - names -- a 4-tuple, (variable_name, residue_name, - unramified_subextension_variable_name, uniformizer_name) - - element_class -- the class for elements of this unramified extension. + - ``poly`` -- Polynomial defining this extension. + - ``prec`` -- The precision cap + - ``print_mode`` -- a dictionary with print options + - ``names`` -- a 4-tuple, (``variable_name``, ``residue_name``, + ``unramified_subextension_variable_name``, ``uniformizer_name``) + - ``element_class`` -- the class for elements of this unramified extension. EXAMPLES:: @@ -76,7 +76,7 @@ def _extension_type(self): def absolute_f(self): """ Return the degree of the residue field of this ring/field - over its prime subfield + over its prime subfield. EXAMPLES:: @@ -113,7 +113,7 @@ def residue_class_field(self): def residue_ring(self, n): """ - Return the quotient of the ring of integers by the nth power of its maximal ideal. + Return the quotient of the ring of integers by the `n`-th power of its maximal ideal. EXAMPLES:: @@ -135,11 +135,11 @@ def residue_ring(self, n): def discriminant(self, K=None): """ - Returns the discriminant of self over the subring K. + Return the discriminant of ``self`` over the subring `K`. INPUT: - - K -- a subring/subfield (defaults to the base ring). + - ``K`` -- a subring/subfield (defaults to the base ring). EXAMPLES:: @@ -174,13 +174,13 @@ def discriminant(self, K=None): def is_galois(self, K=None): """ - Returns True if this extension is Galois. + Return ``True`` if this extension is Galois. Every unramified extension is Galois. INPUT: - - K -- a subring/subfield (defaults to the base ring). + - ``K`` -- a subring/subfield (defaults to the base ring). EXAMPLES:: @@ -193,7 +193,7 @@ def is_galois(self, K=None): def gen(self, n=0): """ - Returns a generator for this unramified extension. + Return a generator for this unramified extension. This is an element that satisfies the polynomial defining this extension. Such an element will reduce to a generator of the @@ -211,7 +211,7 @@ def gen(self, n=0): @cached_method def _frob_gen(self, arithmetic = True): """ - Returns frobenius of the generator for this unramified extension + Return frobenius of the generator for this unramified extension EXAMPLES:: @@ -233,7 +233,7 @@ def _frob_gen(self, arithmetic = True): def uniformizer_pow(self, n): """ - Returns the nth power of the uniformizer of self (as an element of self). + Return the `n`-th power of the uniformizer of ``self`` (as an element of ``self``). EXAMPLES:: @@ -244,8 +244,8 @@ def uniformizer_pow(self, n): return self(self.prime_pow(n)) def uniformizer(self): - """ - Returns a uniformizer for this extension. + r""" + Return a uniformizer for this extension. Since this extension is unramified, a uniformizer for the ground ring will also be a uniformizer for this extension. @@ -259,8 +259,8 @@ def uniformizer(self): return self(self.ground_ring().uniformizer()) def _uniformizer_print(self): - """ - Returns how the uniformizer is supposed to print. + r""" + Return how the uniformizer is supposed to print. EXAMPLES:: @@ -270,8 +270,8 @@ def _uniformizer_print(self): return self.ground_ring()._uniformizer_print() def _unram_print(self): - """ - Returns how the generator prints. + r""" + Return how the generator prints. EXAMPLES:: @@ -282,20 +282,19 @@ def _unram_print(self): def has_pth_root(self): r""" - Returns whether or not `\ZZ_p` has a primitive `p^{\mbox{th}}` root of unity. + Return whether or not `\ZZ_p` has a primitive `p`-th root of unity. - Since adjoining a `p^{\mbox{th}}` root of unity yields a - totally ramified extension, self will contain one if and only + Since adjoining a `p`-th root of unity yields a + totally ramified extension, ``self`` will contain one if and only if the ground ring does. INPUT: - - self -- a p-adic ring + - ``self`` -- a `p`-adic ring OUTPUT: - - boolean -- whether self has primitive `p^{\mbox{th}}` - root of unity. + boolean -- whether ``self`` has primitive `p`-th root of unity. EXAMPLES:: @@ -308,12 +307,12 @@ def has_pth_root(self): def has_root_of_unity(self, n): r""" - Return whether or not `\ZZ_p` has a primitive `n^{\mbox{th}}` + Return whether or not `\ZZ_p` has a primitive `n`-th root of unity. INPUT: - - ``self`` -- a p-adic ring + - ``self`` -- a `p`-adic ring - ``n`` -- an integer OUTPUT: diff --git a/src/sage/rings/polynomial/all__sagemath_polyhedra.py b/src/sage/rings/polynomial/all__sagemath_polyhedra.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/sage/rings/polynomial/binary_form_reduce.py b/src/sage/rings/polynomial/binary_form_reduce.py index fb60089a751..82c5921f954 100644 --- a/src/sage/rings/polynomial/binary_form_reduce.py +++ b/src/sage/rings/polynomial/binary_form_reduce.py @@ -26,9 +26,10 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.calculus.functions import jacobian -from sage.functions.hyperbolic import cosh, sinh -from sage.functions.log import exp +from sage.misc.lazy_import import lazy_import +lazy_import("sage.calculus.functions", "jacobian") +lazy_import("sage.functions.hyperbolic", ["cosh", "sinh"]) +lazy_import("sage.functions.log", "exp") from sage.matrix.constructor import matrix from sage.misc.misc_c import prod from sage.modules.free_module_element import vector diff --git a/src/sage/rings/polynomial/cyclotomic.pyx b/src/sage/rings/polynomial/cyclotomic.pyx index 1053f471a7a..ee39dccb907 100644 --- a/src/sage/rings/polynomial/cyclotomic.pyx +++ b/src/sage/rings/polynomial/cyclotomic.pyx @@ -35,7 +35,7 @@ from sage.structure.element cimport parent from sage.arith.misc import factor from sage.rings.integer_ring import ZZ from sage.misc.misc_c import prod -from sage.misc.misc import subsets +from sage.combinat.subset import subsets from sage.rings.integer cimport Integer from sage.rings.rational cimport Rational from sage.libs.pari.all import pari diff --git a/src/sage/rings/polynomial/flatten.py b/src/sage/rings/polynomial/flatten.py index 4ffe29f9ebe..84c38e52ee5 100644 --- a/src/sage/rings/polynomial/flatten.py +++ b/src/sage/rings/polynomial/flatten.py @@ -10,7 +10,10 @@ sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: phi = FlatteningMorphism(R); phi Flattening morphism: - From: Univariate Polynomial Ring in X over Multivariate Polynomial Ring in s, t over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + From: Univariate Polynomial Ring in X + over Multivariate Polynomial Ring in s, t + over Univariate Polynomial Ring in y + over Univariate Polynomial Ring in x over Rational Field To: Multivariate Polynomial Ring in x, y, s, t, X over Rational Field sage: phi('x*y*s + t*X').parent() Multivariate Polynomial Ring in x, y, s, t, X over Rational Field @@ -108,36 +111,36 @@ def __init__(self, domain): :: - sage: K. = NumberField(x^3 - 2) - sage: R = K['x','y']['a','b'] + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: R = K['x','y']['a','b'] # optional - sage.rings.number_field sage: from sage.rings.polynomial.flatten import FlatteningMorphism - sage: f = FlatteningMorphism(R) - sage: f(R('v*a*x^2 + b^2 + 1/v*y')) + sage: f = FlatteningMorphism(R) # optional - sage.rings.number_field + sage: f(R('v*a*x^2 + b^2 + 1/v*y')) # optional - sage.rings.number_field v*x^2*a + b^2 + (1/2*v^2)*y :: - sage: R = QQbar['x','y']['a','b'] + sage: R = QQbar['x','y']['a','b'] # optional - sage.rings.number_field sage: from sage.rings.polynomial.flatten import FlatteningMorphism - sage: f = FlatteningMorphism(R) - sage: f(R('QQbar(sqrt(2))*a*x^2 + b^2 + QQbar(I)*y')) + sage: f = FlatteningMorphism(R) # optional - sage.rings.number_field + sage: f(R('QQbar(sqrt(2))*a*x^2 + b^2 + QQbar(I)*y')) # optional - sage.rings.number_field 1.414213562373095?*x^2*a + b^2 + I*y :: - sage: R. = PolynomialRing(QQbar,1) + sage: R. = PolynomialRing(QQbar, 1) # optional - sage.rings.number_field sage: from sage.rings.polynomial.flatten import FlatteningMorphism - sage: f = FlatteningMorphism(R) - sage: f.domain(), f.codomain() + sage: f = FlatteningMorphism(R) # optional - sage.rings.number_field + sage: f.domain(), f.codomain() # optional - sage.rings.number_field (Multivariate Polynomial Ring in z over Algebraic Field, Multivariate Polynomial Ring in z over Algebraic Field) :: - sage: R. = PolynomialRing(QQbar) + sage: R. = PolynomialRing(QQbar) # optional - sage.rings.number_field sage: from sage.rings.polynomial.flatten import FlatteningMorphism - sage: f = FlatteningMorphism(R) - sage: f.domain(), f.codomain() + sage: f = FlatteningMorphism(R) # optional - sage.rings.number_field + sage: f.domain(), f.codomain() # optional - sage.rings.number_field (Univariate Polynomial Ring in z over Algebraic Field, Univariate Polynomial Ring in z over Algebraic Field) @@ -243,7 +246,8 @@ def section(self): sage: h.section() Unflattening morphism: From: Multivariate Polynomial Ring in a, b, c, x, y, z over Rational Field - To: Multivariate Polynomial Ring in x, y, z over Multivariate Polynomial Ring in a, b, c over Rational Field + To: Multivariate Polynomial Ring in x, y, z + over Multivariate Polynomial Ring in a, b, c over Rational Field :: @@ -252,7 +256,8 @@ def section(self): sage: FlatteningMorphism(R).section() Unflattening morphism: From: Multivariate Polynomial Ring in a, b, c over Integer Ring - To: Univariate Polynomial Ring in c over Univariate Polynomial Ring in b over Univariate Polynomial Ring in a over Integer Ring + To: Univariate Polynomial Ring in c over Univariate Polynomial Ring in b + over Univariate Polynomial Ring in a over Integer Ring """ return UnflatteningMorphism(self.codomain(), self.domain()) @@ -268,7 +273,8 @@ def inverse(self): sage: f.inverse() Unflattening morphism: From: Multivariate Polynomial Ring in x, y, u, v over Rational Field - To: Multivariate Polynomial Ring in u, v over Multivariate Polynomial Ring in x, y over Rational Field + To: Multivariate Polynomial Ring in u, v + over Multivariate Polynomial Ring in x, y over Rational Field """ return self.section() @@ -286,7 +292,8 @@ class UnflatteningMorphism(Morphism): sage: g = f(R('x^2 + c*y^2 - z^2'));g x^2 + c*y^2 - z^2 sage: g.parent() - Multivariate Polynomial Ring in x, y, z over Univariate Polynomial Ring in c over Rational Field + Multivariate Polynomial Ring in x, y, z + over Univariate Polynomial Ring in c over Rational Field :: @@ -296,7 +303,8 @@ class UnflatteningMorphism(Morphism): sage: UnflatteningMorphism(R, S) Unflattening morphism: From: Multivariate Polynomial Ring in a, b, x, y over Rational Field - To: Multivariate Polynomial Ring in x, y over Multivariate Polynomial Ring in a, b over Rational Field + To: Multivariate Polynomial Ring in x, y + over Multivariate Polynomial Ring in a, b over Rational Field """ def __init__(self, domain, codomain): @@ -366,8 +374,10 @@ def _call_(self, p): TESTS:: sage: from sage.rings.polynomial.flatten import FlatteningMorphism - sage: for R in [ZZ['x']['y']['a,b,c'], GF(4)['x','y']['a','b'], - ....: AA['x']['a','b']['y'], QQbar['a1','a2']['t']['X','Y']]: + sage: rings = [ZZ['x']['y']['a,b,c']] + sage: rings += [GF(4)['x','y']['a','b']] # optional - sage.rings.finite_rings + sage: rings += [AA['x']['a','b']['y'], QQbar['a1','a2']['t']['X','Y']] # optional - sage.rings.number_field + sage: for R in rings: ....: f = FlatteningMorphism(R) ....: g = f.section() ....: for _ in range(10): @@ -423,8 +433,9 @@ class SpecializationMorphism(Morphism): sage: from sage.rings.polynomial.flatten import SpecializationMorphism sage: xi = SpecializationMorphism(S, {c:0}); xi Specialization morphism: - From: Univariate Polynomial Ring in z over Univariate Polynomial Ring in c over Rational Field - To: Univariate Polynomial Ring in z over Rational Field + From: Univariate Polynomial Ring in z + over Univariate Polynomial Ring in c over Rational Field + To: Univariate Polynomial Ring in z over Rational Field sage: xi(z^2+c) z^2 @@ -437,8 +448,11 @@ class SpecializationMorphism(Morphism): sage: from sage.rings.polynomial.flatten import SpecializationMorphism sage: xi = SpecializationMorphism(S, D); xi Specialization morphism: - From: Multivariate Polynomial Ring in x, y, z over Multivariate Polynomial Ring in a, b, c over Multivariate Polynomial Ring in u, v over Rational Field - To: Multivariate Polynomial Ring in y, z over Univariate Polynomial Ring in c over Univariate Polynomial Ring in v over Rational Field + From: Multivariate Polynomial Ring in x, y, z + over Multivariate Polynomial Ring in a, b, c + over Multivariate Polynomial Ring in u, v over Rational Field + To: Multivariate Polynomial Ring in y, z over Univariate Polynomial Ring in c + over Univariate Polynomial Ring in v over Rational Field sage: xi(a*(x*z+y^2)*u+b*v*u*(x*z+y^2)*y^2*c+c*y^2*z^2) 2*v*c*y^4 + c*y^2*z^2 + y^2 """ @@ -655,8 +669,10 @@ def __init__(self, domain, D): sage: phi = FractionSpecializationMorphism(Frac(S), {c:3}) sage: phi Fraction Specialization morphism: - From: Fraction Field of Multivariate Polynomial Ring in x, y over Multivariate Polynomial Ring in a, c over Rational Field - To: Fraction Field of Multivariate Polynomial Ring in x, y over Univariate Polynomial Ring in a over Rational Field + From: Fraction Field of Multivariate Polynomial Ring in x, y + over Multivariate Polynomial Ring in a, c over Rational Field + To: Fraction Field of Multivariate Polynomial Ring in x, y + over Univariate Polynomial Ring in a over Rational Field """ if not is_FractionField(domain): raise TypeError("domain must be a fraction field") diff --git a/src/sage/rings/polynomial/hilbert.pyx b/src/sage/rings/polynomial/hilbert.pyx index 01cb166b7fb..864e2766407 100644 --- a/src/sage/rings/polynomial/hilbert.pyx +++ b/src/sage/rings/polynomial/hilbert.pyx @@ -442,16 +442,16 @@ def first_hilbert_series(I, grading=None, return_grading=False): sage: I = singular.ideal(['x^2','y^2','z^2']) sage: first_hilbert_series(I) -t^6 + 3*t^4 - 3*t^2 + 1 - sage: first_hilbert_series(I,return_grading=True) + sage: first_hilbert_series(I, return_grading=True) (-t^6 + 3*t^4 - 3*t^2 + 1, (1, 1, 1)) - sage: first_hilbert_series(I,grading=(1,2,3)) + sage: first_hilbert_series(I, grading=(1,2,3)) -t^12 + t^10 + t^8 - t^4 - t^2 + 1 TESTS: We test against some corner cases:: - sage: R.=PolynomialRing(QQ) + sage: R. = PolynomialRing(QQ) sage: I = 0*R sage: first_hilbert_series(I) 1 @@ -559,18 +559,19 @@ def hilbert_poincare_series(I, grading=None): sage: from sage.rings.polynomial.hilbert import hilbert_poincare_series sage: R = PolynomialRing(QQ,'x',9) - sage: I = [m.lm() for m in ((matrix(R,3,R.gens())^2).list()*R).groebner_basis()]*R + sage: I = [m.lm() + ....: for m in ((matrix(R, 3, R.gens())^2).list() * R).groebner_basis()] * R sage: hilbert_poincare_series(I) (t^7 - 3*t^6 + 2*t^5 + 2*t^4 - 2*t^3 + 6*t^2 + 5*t + 1)/(t^4 - 4*t^3 + 6*t^2 - 4*t + 1) - sage: hilbert_poincare_series((R*R.gens())^2, grading=range(1,10)) + sage: hilbert_poincare_series((R * R.gens())^2, grading=range(1,10)) t^9 + t^8 + t^7 + t^6 + t^5 + t^4 + t^3 + t^2 + t + 1 The following example is taken from :trac:`20145`:: - sage: n=4;m=11;P = PolynomialRing(QQ,n*m,"x"); x = P.gens(); M = Matrix(n,x) + sage: n=4; m=11; P = PolynomialRing(QQ, n*m, "x"); x = P.gens(); M = Matrix(n, x) sage: from sage.rings.polynomial.hilbert import first_hilbert_series sage: I = P.ideal(M.minors(2)) - sage: J = P*[m.lm() for m in I.groebner_basis()] + sage: J = P * [m.lm() for m in I.groebner_basis()] sage: hilbert_poincare_series(J).numerator() 120*t^3 + 135*t^2 + 30*t + 1 sage: hilbert_poincare_series(J).denominator().factor() @@ -578,7 +579,7 @@ def hilbert_poincare_series(I, grading=None): This example exceeded the capabilities of Singular before version 4.2.1p2. In Singular 4.3.1, it works correctly on 64-bit, but on 32-bit, it prints overflow warnings - and omits some terms. + and omits some terms:: sage: J.hilbert_numerator(algorithm='singular') 120*t^33 - 3465*t^32 + 48180*t^31 - 429374*t^30 + 2753520*t^29 - 13522410*t^28 + 52832780*t^27 - 168384150*t^26 + 445188744*t^25 - 987193350*t^24 + 1847488500*t^23 + 1372406746*t^22 - 403422496*t^21 - 8403314*t^20 - 471656596*t^19 + 1806623746*t^18 + 752776200*t^17 + 752776200*t^16 - 1580830020*t^15 + 1673936550*t^14 - 1294246800*t^13 + 786893250*t^12 - 382391100*t^11 + 146679390*t^10 - 42299400*t^9 + 7837830*t^8 - 172260*t^7 - 468930*t^6 + 183744*t^5 - 39270*t^4 + 5060*t^3 - 330*t^2 + 1 # 64-bit diff --git a/src/sage/rings/polynomial/ideal.py b/src/sage/rings/polynomial/ideal.py index 857718c9a10..d84264e9d69 100644 --- a/src/sage/rings/polynomial/ideal.py +++ b/src/sage/rings/polynomial/ideal.py @@ -26,28 +26,29 @@ class Ideal_1poly_field(Ideal_pid): """ def residue_class_degree(self): """ - Returns the degree of the generator of this ideal. + Return the degree of the generator of this ideal. This function is included for compatibility with ideals in rings of integers of number fields. EXAMPLES:: - sage: R. = GF(5)[] - sage: P = R.ideal(t^4 + t + 1) - sage: P.residue_class_degree() + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: P = R.ideal(t^4 + t + 1) # optional - sage.rings.finite_rings + sage: P.residue_class_degree() # optional - sage.rings.finite_rings 4 """ return self.gen().degree() def residue_field(self, names=None, check=True): r""" - If this ideal is `P \subset F_p[t]`, returns the quotient `F_p[t]/P`. + If this ideal is `P \subset F_p[t]`, return the quotient `F_p[t]/P`. EXAMPLES:: - sage: R. = GF(17)[]; P = R.ideal(t^3 + 2*t + 9) - sage: k. = P.residue_field(); k - Residue field in a of Principal ideal (t^3 + 2*t + 9) of Univariate Polynomial Ring in t over Finite Field of size 17 + sage: R. = GF(17)[]; P = R.ideal(t^3 + 2*t + 9) # optional - sage.rings.finite_rings + sage: k. = P.residue_field(); k # optional - sage.rings.finite_rings + Residue field in a of Principal ideal (t^3 + 2*t + 9) of + Univariate Polynomial Ring in t over Finite Field of size 17 """ if check: if not self.ring().base_ring().is_finite(): @@ -74,11 +75,11 @@ def groebner_basis(self, algorithm=None): sage: R. = QQ[] sage: I = R.ideal([x^2 - 1, x^3 - 1]) - sage: G = I.groebner_basis(); G + sage: G = I.groebner_basis(); G # optional - sage.libs.singular [x - 1] - sage: type(G) + sage: type(G) # optional - sage.libs.singular - sage: list(G) + sage: list(G) # optional - sage.libs.singular [x - 1] """ gb = self.gens_reduced() diff --git a/src/sage/rings/polynomial/infinite_polynomial_element.py b/src/sage/rings/polynomial/infinite_polynomial_element.py index c7d43e31d1b..cad5877fd0f 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_element.py +++ b/src/sage/rings/polynomial/infinite_polynomial_element.py @@ -18,7 +18,7 @@ x_3 sage: b y_4 - sage: c = a*b+a^3-2*b^4 + sage: c = a*b + a^3 - 2*b^4 sage: c x_3^3 + x_3*y_4 - 2*y_4^4 @@ -48,8 +48,8 @@ There is a permutation action on Infinite Polynomial Rings by permuting the indices of the variables:: - sage: P = Permutation(((4,5),(2,3))) - sage: c^P + sage: P = Permutation(((4,5),(2,3))) # optional - sage.combinat + sage: c^P # optional - sage.combinat x_2^3 + x_2*y_5 - 2*y_5^4 Note that ``P(0)==0``, and thus variables of index zero are invariant @@ -80,7 +80,7 @@ sage: C. = InfinitePolynomialRing(B,order='degrevlex') sage: C Infinite polynomial ring in b, c over Infinite polynomial ring in a over Integer Ring - sage: 1/2*b_1*a[4]+c[3] + sage: 1/2*b_1*a[4] + c[3] 1/2*a_4*b_1 + c_3 """ @@ -299,15 +299,16 @@ def polynomial(self): EXAMPLES:: - sage: X. = InfinitePolynomialRing(GF(7)) - sage: p = x[2]*y[1]+3*y[0] - sage: p + sage: X. = InfinitePolynomialRing(GF(7)) # optional - sage.rings.finite_rings + sage: p = x[2]*y[1] + 3*y[0] # optional - sage.rings.finite_rings + sage: p # optional - sage.rings.finite_rings x_2*y_1 + 3*y_0 - sage: p.polynomial() + sage: p.polynomial() # optional - sage.rings.finite_rings x_2*y_1 + 3*y_0 - sage: p.polynomial().parent() - Multivariate Polynomial Ring in x_2, x_1, x_0, y_2, y_1, y_0 over Finite Field of size 7 - sage: p.parent() + sage: p.polynomial().parent() # optional - sage.rings.finite_rings + Multivariate Polynomial Ring in x_2, x_1, x_0, y_2, y_1, y_0 + over Finite Field of size 7 + sage: p.parent() # optional - sage.rings.finite_rings Infinite polynomial ring in x, y over Finite Field of size 7 """ @@ -402,7 +403,7 @@ def subs(self, fixed=None, **kwargs): INPUT: - - ``fixed`` -- (optional) ``dict`` with ``{variable:value}`` pairs + - ``fixed`` -- (optional) ``dict`` with ``{variable: value}`` pairs - ``**kwargs`` -- named parameters OUTPUT: @@ -439,13 +440,13 @@ def subs(self, fixed=None, **kwargs): The substitution can also handle matrices:: - sage: M = matrix([[1,0],[0,2]]) - sage: N = matrix([[0,3],[4,0]]) - sage: g = x[0]^2 + 3*x[1] - sage: g.subs({'x_0': M}) + sage: M = matrix([[1,0], [0,2]]) # optional - sage.modules + sage: N = matrix([[0,3], [4,0]]) # optional - sage.modules + sage: g = x[0]^2 + 3*x[1] # optional - sage.modules + sage: g.subs({'x_0': M}) # optional - sage.modules [3*x_1 + 1 0] [ 0 3*x_1 + 4] - sage: g.subs({x[0]: M, x[1]: N}) + sage: g.subs({x[0]: M, x[1]: N}) # optional - sage.modules [ 1 9] [12 4] @@ -454,11 +455,11 @@ def subs(self, fixed=None, **kwargs): sage: R. = InfinitePolynomialRing(QQ) sage: f = x[0] - sage: f.subs({x[0]:1}) + sage: f.subs({x[0]: 1}) 1 sage: f.subs(x_0=5) 5 - sage: f.subs({x[0]:1}, x_0=5) + sage: f.subs({x[0]: 1}, x_0=5) 1 TESTS:: @@ -487,7 +488,7 @@ def ring(self): EXAMPLES:: sage: X. = InfinitePolynomialRing(ZZ,implementation='sparse') - sage: p = x[100]*y[1]^3*x[1]^2+2*x[10]*y[30] + sage: p = x[100]*y[1]^3*x[1]^2 + 2*x[10]*y[30] sage: p.ring() Infinite polynomial ring in x, y over Integer Ring @@ -502,7 +503,7 @@ def is_unit(self): sage: R1. = InfinitePolynomialRing(ZZ) sage: R2. = InfinitePolynomialRing(QQ) - sage: (1+x[2]).is_unit() + sage: (1 + x[2]).is_unit() False sage: R1(1).is_unit() True @@ -510,7 +511,7 @@ def is_unit(self): False sage: R2(2).is_unit() True - sage: (1+a[2]).is_unit() + sage: (1 + a[2]).is_unit() False Check that :trac:`22454` is fixed:: @@ -539,10 +540,10 @@ def is_nilpotent(self): EXAMPLES:: - sage: R. = InfinitePolynomialRing(QQbar) - sage: (x[0]+x[1]).is_nilpotent() + sage: R. = InfinitePolynomialRing(QQbar) # optional - sage.rings.number_field + sage: (x[0] + x[1]).is_nilpotent() # optional - sage.rings.number_field False - sage: R(0).is_nilpotent() + sage: R(0).is_nilpotent() # optional - sage.rings.number_field True sage: _. = InfinitePolynomialRing(Zmod(4)) sage: (2*x[0]).is_nilpotent() @@ -586,7 +587,7 @@ def max_index(self): EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: p=x[1]^2+y[2]^2+x[1]*x[2]*y[3]+x[1]*y[4] + sage: p = x[1]^2 + y[2]^2 + x[1]*x[2]*y[3] + x[1]*y[4] sage: p.max_index() 4 sage: x[0].max_index() @@ -633,7 +634,7 @@ def _div_(self, x): Division by an integer over `\ZZ`:: sage: R. = InfinitePolynomialRing(ZZ, implementation='sparse') - sage: p = x[3]+x[2] + sage: p = x[3] + x[2] sage: q = p/2 sage: q 1/2*x_3 + 1/2*x_2 @@ -647,7 +648,7 @@ def _div_(self, x): 1/x_1 sage: (x[0]/x[0]) x_0/x_0 - sage: qt = 1/x[2]+2/x[1]; qt + sage: qt = 1/x[2] + 2/x[1]; qt (2*x_2 + x_1)/(x_2*x_1) sage: qt.parent() Fraction Field of Infinite polynomial ring in x over Rational Field @@ -655,7 +656,7 @@ def _div_(self, x): sage: z = 1/(x[2]*(x[1]+x[2]))+1/(x[1]*(x[1]+x[2])) sage: z.parent() Fraction Field of Infinite polynomial ring in x over Rational Field - sage: factor(z) + sage: factor(z) # optional - sage.libs.singular x_1^-1 * x_2^-1 """ if not x.variables(): @@ -700,7 +701,7 @@ def lm(self): EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: p = 2*x[10]*y[30]+x[10]*y[1]^3*x[1]^2 + sage: p = 2*x[10]*y[30] + x[10]*y[1]^3*x[1]^2 sage: p.lm() x_10*x_1^2*y_1^3 @@ -722,7 +723,7 @@ def lc(self): EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: p = 2*x[10]*y[30]+3*x[10]*y[1]^3*x[1]^2 + sage: p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2 sage: p.lc() 3 @@ -742,7 +743,7 @@ def lt(self): EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: p = 2*x[10]*y[30]+3*x[10]*y[1]^3*x[1]^2 + sage: p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2 sage: p.lt() 3*x_10*x_1^2*y_1^3 @@ -762,7 +763,7 @@ def tail(self): EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: p = 2*x[10]*y[30]+3*x[10]*y[1]^3*x[1]^2 + sage: p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2 sage: p.tail() 2*x_10*y_30 @@ -811,7 +812,7 @@ def footprint(self): EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: p = x[30]*y[1]^3*x[1]^2+2*x[10]*y[30] + sage: p = x[30]*y[1]^3*x[1]^2 + 2*x[10]*y[30] sage: sorted(p.footprint().items()) [(1, [2, 3]), (30, [1, 0])] @@ -863,7 +864,7 @@ def symmetric_cancellation_order(self, other): INPUT: - self, other -- two Infinite Polynomials + ``self``, ``other`` -- two Infinite Polynomials ASSUMPTION: @@ -895,11 +896,11 @@ def symmetric_cancellation_order(self, other): sage: X. = InfinitePolynomialRing(QQ) sage: (x[2]*x[1]).symmetric_cancellation_order(x[2]^2) (None, 1, 1) - sage: (x[2]*x[1]).symmetric_cancellation_order(x[2]*x[3]*y[1]) + sage: (x[2]*x[1]).symmetric_cancellation_order(x[2]*x[3]*y[1]) # optional - sage.combinat (-1, [2, 3, 1], y_1) - sage: (x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[1]) + sage: (x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[1]) # optional - sage.combinat (None, 1, 1) - sage: (x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[2]) + sage: (x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[2]) # optional - sage.combinat (-1, [2, 3, 1], 1) """ @@ -1085,7 +1086,7 @@ def reduce(self, I, tailreduce=False, report=None): EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: p = y[1]^2*y[3]+y[2]*x[3]^3 + sage: p = y[1]^2*y[3] + y[2]*x[3]^3 sage: p.reduce([y[2]*x[1]^2]) x_3^3*y_2 + y_3*y_1^2 @@ -1111,7 +1112,7 @@ def reduce(self, I, tailreduce=False, report=None): Last, we demonstrate the ``report`` option:: - sage: p=x[1]^2+y[2]^2+x[1]*x[2]*y[3]+x[1]*y[4] + sage: p = x[1]^2 + y[2]^2 + x[1]*x[2]*y[3] + x[1]*y[4] sage: p.reduce(I, tailreduce=True, report=True) :T[2]:> > @@ -1200,7 +1201,7 @@ def gcd(self, x): EXAMPLES:: sage: R.=InfinitePolynomialRing(QQ) - sage: p1=x[0]+x[1]**2 + sage: p1=x[0] + x[1]**2 sage: gcd(p1,p1+3) 1 sage: gcd(p1,p1)==p1 @@ -1232,9 +1233,11 @@ class InfinitePolynomial_sparse(InfinitePolynomial): sage: p a*b_100 + 1/2*c_4 sage: p.parent() - Infinite polynomial ring in b, c over Univariate Polynomial Ring in a over Rational Field + Infinite polynomial ring in b, c + over Univariate Polynomial Ring in a over Rational Field sage: p.polynomial().parent() - Multivariate Polynomial Ring in b_100, b_0, c_4, c_0 over Univariate Polynomial Ring in a over Rational Field + Multivariate Polynomial Ring in b_100, b_0, c_4, c_0 + over Univariate Polynomial Ring in a over Rational Field """ @@ -1255,8 +1258,8 @@ def __call__(self, *args, **kwargs): sage: a(x_1=x[100]) x_100 + x_0 - sage: M = matrix([[1,1],[2,0]]) - sage: a(x_1=M) + sage: M = matrix([[1,1], [2,0]]) # optional - sage.modules + sage: a(x_1=M) # optional - sage.modules [x_0 + 1 1] [ 2 x_0] """ @@ -1384,10 +1387,10 @@ def __pow__(self, n): EXAMPLES:: - sage: X. = InfinitePolynomialRing(QQ,implementation='sparse') - sage: p = x[10]*y[2]+2*x[1]*y[3] - sage: P = Permutation(((1,2),(3,4,5))) - sage: p^P # indirect doctest + sage: X. = InfinitePolynomialRing(QQ, implementation='sparse') + sage: p = x[10]*y[2] + 2*x[1]*y[3] + sage: P = Permutation(((1,2),(3,4,5))) # optional - sage.combinat + sage: p^P # indirect doctest # optional - sage.combinat x_10*y_1 + 2*x_2*y_4 """ @@ -1471,16 +1474,16 @@ def _richcmp_(self, x, op): Two infinite polynomial rings in different implementation and order:: - sage: Y = InfinitePolynomialRing(QQ,['x','y'],order='deglex',implementation='dense') + sage: Y = InfinitePolynomialRing(QQ,['x','y'],order='deglex', implementation='dense') sage: x[2] == Y(x[2]) # indirect doctest True An example in which a previous version had failed:: - sage: X. = InfinitePolynomialRing(GF(3), order='degrevlex', implementation='sparse') - sage: p = Y('x_3*x_0^2 + x_0*y_3*y_0') - sage: q = Y('x_1*x_0^2 + x_0*y_1*y_0') - sage: p < q # indirect doctest + sage: X. = InfinitePolynomialRing(GF(3), order='degrevlex', implementation='sparse') # optional - sage.rings.finite_rings + sage: p = Y('x_3*x_0^2 + x_0*y_3*y_0') # optional - sage.rings.finite_rings + sage: q = Y('x_1*x_0^2 + x_0*y_1*y_0') # optional - sage.rings.finite_rings + sage: p < q # indirect doctest # optional - sage.rings.finite_rings False """ @@ -1523,9 +1526,6 @@ class InfinitePolynomial_dense(InfinitePolynomial): Of course, one should not directly invoke this class, but rather construct elements of ``A`` in the usual way. - This class inherits from - :class:`~sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_sparse`. See - there for a description of the methods. """ def __call__(self, *args, **kwargs): @@ -1534,7 +1534,7 @@ def __call__(self, *args, **kwargs): sage: X. = InfinitePolynomialRing(QQ) sage: a = x[0] + x[1] - sage: a(x_0=2,x_1=x[1]) + sage: a(x_0=2, x_1=x[1]) x_1 + 2 sage: _.parent() Infinite polynomial ring in x over Rational Field @@ -1569,7 +1569,7 @@ def _richcmp_(self, x, op): A classical and an infinite polynomial ring:: - sage: X. = InfinitePolynomialRing(ZZ,order='degrevlex') + sage: X. = InfinitePolynomialRing(ZZ, order='degrevlex') sage: Y. = QQ[] sage: x[3] == x_3 True @@ -1577,16 +1577,16 @@ def _richcmp_(self, x, op): Two infinite polynomial rings with different order and implementation:: - sage: Y = InfinitePolynomialRing(QQ,['x','y'],order='deglex',implementation='sparse') + sage: Y = InfinitePolynomialRing(QQ,['x','y'], order='deglex', implementation='sparse') sage: x[2] == Y(x[2]) True An example in which a previous version had failed:: - sage: X. = InfinitePolynomialRing(GF(3), order='degrevlex', implementation='dense') - sage: p = Y('x_3*x_0^2 + x_0*y_3*y_0') - sage: q = Y('x_1*x_0^2 + x_0*y_1*y_0') - sage: p < q + sage: X. = InfinitePolynomialRing(GF(3), order='degrevlex', implementation='dense') # optional - sage.rings.finite_rings + sage: p = Y('x_3*x_0^2 + x_0*y_3*y_0') # optional - sage.rings.finite_rings + sage: q = Y('x_1*x_0^2 + x_0*y_1*y_0') # optional - sage.rings.finite_rings + sage: p < q # optional - sage.rings.finite_rings False """ @@ -1664,9 +1664,9 @@ def __pow__(self, n): sage: X. = InfinitePolynomialRing(QQ) sage: x[10]^3 x_10^3 - sage: p = x[10]*y[2]+2*x[1]*y[3] - sage: P = Permutation(((1,2),(3,4,5))) - sage: p^P + sage: p = x[10]*y[2] + 2*x[1]*y[3] + sage: P = Permutation(((1,2),(3,4,5))) # optional - sage.combinat + sage: p^P # optional - sage.combinat x_10*y_1 + 2*x_2*y_4 """ diff --git a/src/sage/rings/polynomial/infinite_polynomial_ring.py b/src/sage/rings/polynomial/infinite_polynomial_ring.py index 8e3ba4156e9..b9318c36d49 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_ring.py +++ b/src/sage/rings/polynomial/infinite_polynomial_ring.py @@ -71,11 +71,12 @@ sage: g2 = 3*beta[1]; g2 3*beta_1 sage: A.polynomial_ring() - Multivariate Polynomial Ring in alpha_5, alpha_4, alpha_3, alpha_2, alpha_1, alpha_0, beta_5, beta_4, beta_3, beta_2, beta_1, beta_0 over Rational Field + Multivariate Polynomial Ring in alpha_5, alpha_4, alpha_3, alpha_2, alpha_1, alpha_0, + beta_5, beta_4, beta_3, beta_2, beta_1, beta_0 over Rational Field Of course, we provide the usual polynomial arithmetic:: - sage: f+g + sage: f + g x_5 + 3*y_1 + 2 sage: p = x[10]^2*(f+g); p x_10^2*x_5 + 3*x_10^2*y_1 + 2*x_10^2 @@ -85,10 +86,10 @@ There is a permutation action on the variables, by permuting positive variable indices:: - sage: P = Permutation(((10,1))) - sage: p^P + sage: P = Permutation(((10,1))) # optional - sage.combinat + sage: p^P # optional - sage.combinat x_5*x_1^2 + 3*x_1^2*y_10 + 2*x_1^2 - sage: p2^P + sage: p2^P # optional - sage.combinat alpha_5*alpha_1^2 + 3*alpha_1^2*beta_10 + 2*alpha_1^2 Note that `x_0^P = x_0`, since the permutations only change *positive* @@ -101,8 +102,8 @@ multiplication by ring elements and permutation of variables. If the base ring is a field, one can compute Symmetric Groebner Bases:: - sage: J = A*(alpha[1]*beta[2]) - sage: J.groebner_basis() + sage: J = A * (alpha[1]*beta[2]) + sage: J.groebner_basis() # optional - sage.combinat [alpha_1*beta_2, alpha_2*beta_1] For more details, see :class:`~sage.rings.polynomial.symmetric_ideal.SymmetricIdeal`. @@ -126,7 +127,8 @@ sage: A. = ZZ[] sage: B. = InfinitePolynomialRing(A, order='degrevlex') sage: B - Infinite polynomial ring in b, c, d over Multivariate Polynomial Ring in a_3, a_1 over Integer Ring + Infinite polynomial ring in b, c, d over + Multivariate Polynomial Ring in a_3, a_1 over Integer Ring It is no problem if one generator of the Infinite Polynomial Ring is called ``x`` and one variable of the base ring is also called @@ -144,7 +146,8 @@ :: sage: Y - Infinite polynomial ring in x, z over Multivariate Polynomial Ring in x, y_1 over Integer Ring + Infinite polynomial ring in x, z over + Multivariate Polynomial Ring in x, y_1 over Integer Ring The variable ``x`` of ``X`` can still be interpreted in ``Y``, although the first generator of ``Y`` is called ``x`` as well:: @@ -171,7 +174,7 @@ Traceback (most recent call last): ... CoercionException: Overlapping variables (('z', 'y'),['y_1']) are incompatible - sage: X. = PolynomialRing(ZZ,order='lex') + sage: X. = PolynomialRing(ZZ, order='lex') sage: # y_1 and y_2 would be in opposite order in an Infinite Polynomial Ring sage: Y. = InfinitePolynomialRing(X) Traceback (most recent call last): @@ -184,10 +187,10 @@ construction available:: sage: X. = InfinitePolynomialRing(ZZ) - sage: Y. = InfinitePolynomialRing(X,order='degrevlex') + sage: Y. = InfinitePolynomialRing(X, order='degrevlex') sage: Y Infinite polynomial ring in z over Infinite polynomial ring in x, y over Integer Ring - sage: Y. = InfinitePolynomialRing(X,implementation='sparse') + sage: Y. = InfinitePolynomialRing(X, implementation='sparse') sage: Y Infinite polynomial ring in z over Infinite polynomial ring in x, y over Integer Ring @@ -203,18 +206,18 @@ sage: x[2]/2+(5/3)*a[3]*x[4] + 1 5/3*a_3*x_4 + 1/2*x_2 + 1 - sage: R. = InfinitePolynomialRing(ZZ,implementation='sparse') + sage: R. = InfinitePolynomialRing(ZZ, implementation='sparse') sage: X. = InfinitePolynomialRing(R) sage: x[2]/2+(5/3)*a[3]*x[4] + 1 5/3*a_3*x_4 + 1/2*x_2 + 1 - sage: R. = InfinitePolynomialRing(ZZ,implementation='sparse') - sage: X. = InfinitePolynomialRing(R,implementation='sparse') + sage: R. = InfinitePolynomialRing(ZZ, implementation='sparse') + sage: X. = InfinitePolynomialRing(R, implementation='sparse') sage: x[2]/2+(5/3)*a[3]*x[4] + 1 5/3*a_3*x_4 + 1/2*x_2 + 1 sage: R. = InfinitePolynomialRing(ZZ) - sage: X. = InfinitePolynomialRing(R,implementation='sparse') + sage: X. = InfinitePolynomialRing(R, implementation='sparse') sage: x[2]/2+(5/3)*a[3]*x[4] + 1 5/3*a_3*x_4 + 1/2*x_2 + 1 @@ -309,11 +312,13 @@ def create_key(self, R, names=('x',), order='lex', implementation='dense'): (InfPoly{[y1], "lex", "dense"}(FractionField(...)), Integer Ring) sage: _[0].all [FractionField, InfPoly{[y1], "lex", "dense"}] - sage: InfinitePolynomialRing.create_key(QQ, names=['beta'], order='deglex', implementation='sparse') + sage: InfinitePolynomialRing.create_key(QQ, names=['beta'], order='deglex', + ....: implementation='sparse') (InfPoly{[beta], "deglex", "sparse"}(FractionField(...)), Integer Ring) sage: _[0].all [FractionField, InfPoly{[beta], "deglex", "sparse"}] - sage: InfinitePolynomialRing.create_key(QQ, names=['x','y'], implementation='dense') + sage: InfinitePolynomialRing.create_key(QQ, names=['x','y'], + ....: implementation='dense') (InfPoly{[x,y], "lex", "dense"}(FractionField(...)), Integer Ring) sage: _[0].all [FractionField, InfPoly{[x,y], "lex", "dense"}] @@ -805,8 +810,8 @@ def construction(self): EXAMPLES:: - sage: R. = InfinitePolynomialRing(GF(5)) - sage: R.construction() + sage: R. = InfinitePolynomialRing(GF(5)) # optional - sage.rings.finite_rings + sage: R.construction() # optional - sage.rings.finite_rings [InfPoly{[x,y], "lex", "dense"}, Finite Field of size 5] """ @@ -1104,10 +1109,10 @@ def is_noetherian(self): TESTS:: - sage: R = InfinitePolynomialRing(GF(2)) - sage: R + sage: R = InfinitePolynomialRing(GF(2)) # optional - sage.rings.finite_rings + sage: R # optional - sage.rings.finite_rings Infinite polynomial ring in x over Finite Field of size 2 - sage: R.is_noetherian() + sage: R.is_noetherian() # optional - sage.rings.finite_rings False sage: R. = InfinitePolynomialRing(QQ) @@ -1131,10 +1136,10 @@ def is_field(self, *args, **kwds): TESTS:: - sage: R = InfinitePolynomialRing(GF(2)) - sage: R + sage: R = InfinitePolynomialRing(GF(2)) # optional - sage.rings.finite_rings + sage: R # optional - sage.rings.finite_rings Infinite polynomial ring in x over Finite Field of size 2 - sage: R.is_field() + sage: R.is_field() # optional - sage.rings.finite_rings False :trac:`9443`:: @@ -1225,8 +1230,8 @@ def gen(self, i=None): x_1 sage: X.gen() is X.gen(0) True - sage: XX = InfinitePolynomialRing(GF(5)) - sage: XX.gen(0) is XX.gen() + sage: XX = InfinitePolynomialRing(GF(5)) # optional - sage.rings.finite_rings + sage: XX.gen(0) is XX.gen() # optional - sage.rings.finite_rings True """ if i is not None and i > len(self._names): @@ -1292,10 +1297,10 @@ def characteristic(self): EXAMPLES:: - sage: X. = InfinitePolynomialRing(GF(25,'a')) - sage: X + sage: X. = InfinitePolynomialRing(GF(25,'a')) # optional - sage.rings.finite_rings + sage: X # optional - sage.rings.finite_rings Infinite polynomial ring in x, y over Finite Field in a of size 5^2 - sage: X.characteristic() + sage: X.characteristic() # optional - sage.rings.finite_rings 5 """ @@ -1344,8 +1349,8 @@ def order(self): EXAMPLES:: - sage: R. = InfinitePolynomialRing(GF(2)) - sage: R.order() + sage: R. = InfinitePolynomialRing(GF(2)) # optional - sage.rings.finite_rings + sage: R.order() # optional - sage.rings.finite_rings +Infinity """ from sage.rings.infinity import Infinity @@ -1358,8 +1363,8 @@ def key_basis(self): EXAMPLES:: - sage: R. = InfinitePolynomialRing(GF(2)) - sage: R.key_basis() + sage: R. = InfinitePolynomialRing(GF(2)) # optional - sage.rings.finite_rings + sage: R.key_basis() # optional - sage.rings.finite_rings Key polynomial basis over Finite Field of size 2 """ from sage.combinat.key_polynomial import KeyPolynomialBasis @@ -1567,8 +1572,8 @@ def construction(self): EXAMPLES:: - sage: R. = InfinitePolynomialRing(GF(5)) - sage: R.construction() + sage: R. = InfinitePolynomialRing(GF(5)) # optional - sage.rings.finite_rings + sage: R.construction() # optional - sage.rings.finite_rings [InfPoly{[x,y], "lex", "dense"}, Finite Field of size 5] """ return [InfinitePolynomialFunctor(self._names, self._order, 'dense'), self._base] @@ -1641,7 +1646,8 @@ def polynomial_ring(self): Multivariate Polynomial Ring in xx_0, yy_0 over Integer Ring sage: a = yy[3] sage: X.polynomial_ring() - Multivariate Polynomial Ring in xx_3, xx_2, xx_1, xx_0, yy_3, yy_2, yy_1, yy_0 over Integer Ring + Multivariate Polynomial Ring in xx_3, xx_2, xx_1, xx_0, yy_3, yy_2, yy_1, yy_0 + over Integer Ring """ return self._P diff --git a/src/sage/rings/polynomial/laurent_polynomial.pxd b/src/sage/rings/polynomial/laurent_polynomial.pxd index cb0a4ab4ea0..3648d6d1ed1 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pxd +++ b/src/sage/rings/polynomial/laurent_polynomial.pxd @@ -1,6 +1,4 @@ from sage.structure.element cimport CommutativeAlgebraElement, ModuleElement, RingElement, Element -from sage.rings.polynomial.polydict cimport ETuple, PolyDict -from sage.rings.polynomial.multi_polynomial cimport MPolynomial cdef class LaurentPolynomial(CommutativeAlgebraElement): @@ -17,13 +15,3 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): cpdef __normalize(self) cpdef _unsafe_mutate(self, i, value) -cdef class LaurentPolynomial_mpair(LaurentPolynomial): - cdef ETuple _mon - cdef MPolynomial _poly - cdef PolyDict _prod - cdef _compute_polydict(self) - cdef _normalize(self, i=*) - cpdef rescale_vars(self, dict d, h=*, new_ring=*) - cpdef toric_coordinate_change(self, M, h=*, new_ring=*) - cpdef toric_substitute(self, v, v1, a, h=*, new_ring=*) - diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index b597397c9e5..e7b17b2cd32 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -19,7 +19,6 @@ from sage.rings.polynomial.polydict cimport monomial_exponent from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.polynomial.polynomial_ring import is_PolynomialRing from sage.structure.richcmp cimport richcmp, rich_to_bool -from sage.matrix.matrix0 cimport Matrix cdef class LaurentPolynomial(CommutativeAlgebraElement): """ @@ -31,8 +30,8 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): EXAMPLES:: - sage: L. = LaurentPolynomialRing(QQ) # indirect doctest - sage: x*y + sage: L. = LaurentPolynomialRing(QQ) # indirect doctest # optional - sage.modules + sage: x*y # optional - sage.modules x*y """ cdef type t = type(self) @@ -114,18 +113,18 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): :: - sage: L. = LaurentPolynomialRing(QQ) - sage: L(42)._integer_(ZZ) + sage: L. = LaurentPolynomialRing(QQ) # optional - sage.modules + sage: L(42)._integer_(ZZ) # optional - sage.modules 42 - sage: a._integer_(ZZ) + sage: a._integer_(ZZ) # optional - sage.modules Traceback (most recent call last): ... ValueError: a is not constant - sage: L(2/3)._integer_(ZZ) + sage: L(2/3)._integer_(ZZ) # optional - sage.modules Traceback (most recent call last): ... TypeError: no conversion of this rational to integer - sage: ZZ(L(42)) + sage: ZZ(L(42)) # optional - sage.modules 42 """ if not self.is_constant(): @@ -156,14 +155,14 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): :: - sage: L. = LaurentPolynomialRing(QQ) - sage: L(42)._rational_() + sage: L. = LaurentPolynomialRing(QQ) # optional - sage.modules + sage: L(42)._rational_() # optional - sage.modules 42 - sage: a._rational_() + sage: a._rational_() # optional - sage.modules Traceback (most recent call last): ... ValueError: a is not constant - sage: QQ(L(2/3)) + sage: QQ(L(2/3)) # optional - sage.modules 2/3 """ if not self.is_constant(): @@ -179,14 +178,14 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): sage: R. = LaurentPolynomialRing(QQ) sage: a = x^2 + 3*x^3 + 5*x^-1 - sage: a.change_ring(GF(3)) + sage: a.change_ring(GF(3)) # optional - sage.rings.finite_rings 2*x^-1 + x^2 Check that :trac:`22277` is fixed:: sage: R. = LaurentPolynomialRing(QQ) sage: a = 2*x^2 + 3*x^3 + 4*x^-1 - sage: a.change_ring(GF(3)) + sage: a.change_ring(GF(3)) # optional - sage.rings.finite_rings -x^2 + x^-1 """ return self._parent.change_ring(R)(self) @@ -255,38 +254,40 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): EXAMPLES:: - sage: k. = GF(9) - sage: R. = LaurentPolynomialRing(k) - sage: f = x*a + a - sage: f.map_coefficients(lambda a : a + 1) + sage: k. = GF(9) # optional - sage.rings.finite_rings + sage: R. = LaurentPolynomialRing(k) # optional - sage.rings.finite_rings + sage: f = x*a + a # optional - sage.rings.finite_rings + sage: f.map_coefficients(lambda a: a + 1) # optional - sage.rings.finite_rings (a + 1) + (a + 1)*x - sage: R. = LaurentPolynomialRing(k, 2) - sage: f = x*a + 2*x^3*y*a + a - sage: f.map_coefficients(lambda a : a + 1) + sage: R. = LaurentPolynomialRing(k, 2) # optional - sage.rings.finite_rings + sage: f = x*a + 2*x^3*y*a + a # optional - sage.rings.finite_rings + sage: f.map_coefficients(lambda a: a + 1) # optional - sage.rings.finite_rings (2*a + 1)*x^3*y + (a + 1)*x + a + 1 Examples with different base ring:: - sage: R. = GF(9); S. = GF(81) - sage: h = Hom(R,S)[0]; h + sage: R. = GF(9); S. = GF(81) # optional - sage.rings.finite_rings + sage: h = Hom(R, S)[0]; h # optional - sage.rings.finite_rings Ring morphism: From: Finite Field in r of size 3^2 To: Finite Field in s of size 3^4 Defn: r |--> 2*s^3 + 2*s^2 + 1 - sage: T. = LaurentPolynomialRing(R, 2) - sage: f = r*X+Y - sage: g = f.map_coefficients(h); g + sage: T. = LaurentPolynomialRing(R, 2) # optional - sage.modules sage.rings.finite_rings + sage: f = r*X + Y # optional - sage.modules sage.rings.finite_rings + sage: g = f.map_coefficients(h); g # optional - sage.modules sage.rings.finite_rings (2*s^3 + 2*s^2 + 1)*X + Y - sage: g.parent() - Multivariate Laurent Polynomial Ring in X, Y over Finite Field in s of size 3^4 + sage: g.parent() # optional - sage.modules sage.rings.finite_rings + Multivariate Laurent Polynomial Ring in X, Y + over Finite Field in s of size 3^4 sage: h = lambda x: x.trace() - sage: g = f.map_coefficients(h); g + sage: g = f.map_coefficients(h); g # optional - sage.modules sage.rings.finite_rings X - Y - sage: g.parent() - Multivariate Laurent Polynomial Ring in X, Y over Finite Field in r of size 3^2 - sage: g = f.map_coefficients(h, new_base_ring=GF(3)); g + sage: g.parent() # optional - sage.modules sage.rings.finite_rings + Multivariate Laurent Polynomial Ring in X, Y + over Finite Field in r of size 3^2 + sage: g = f.map_coefficients(h, new_base_ring=GF(3)); g # optional - sage.modules sage.rings.finite_rings X - Y - sage: g.parent() + sage: g.parent() # optional - sage.modules sage.rings.finite_rings Multivariate Laurent Polynomial Ring in X, Y over Finite Field of size 3 """ @@ -331,13 +332,13 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): :: - sage: S. = LaurentPolynomialRing(GF(5)) - sage: T. = PolynomialRing(pAdicRing(5)) - sage: S(t) + sage: S. = LaurentPolynomialRing(GF(5)) # optional - sage.rings.finite_rings sage.rings.padics + sage: T. = PolynomialRing(pAdicRing(5)) # optional - sage.rings.finite_rings sage.rings.padics + sage: S(t) # optional - sage.rings.finite_rings sage.rings.padics s - sage: parent(S(t)) + sage: parent(S(t)) # optional - sage.rings.finite_rings sage.rings.padics Univariate Laurent Polynomial Ring in s over Finite Field of size 5 - sage: parent(S(t)[1]) + sage: parent(S(t)[1]) # optional - sage.rings.finite_rings sage.rings.padics Finite Field of size 5 :: @@ -387,7 +388,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: Pxy = PolynomialRing(QQ, "x,y") sage: Paxb = PolynomialRing(QQ, "a,x,b") sage: Qx = PolynomialRing(ZZ, "x") - sage: Rx = PolynomialRing(GF(2), "x") + sage: Rx = PolynomialRing(GF(2), "x") # optional - sage.rings.finite_rings sage: p1 = Lx.gen() sage: p2 = Lx.zero() sage: p3 = Lx.one() @@ -395,8 +396,10 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: p5 = Lx.gen()**3 + 2*Lx.gen()**2 sage: p6 = Lx.gen() >> 2 - sage: for P,x in [(Px, Px.gen()), (Qx, Qx.gen()), (Rx, Rx.gen()), - ....: (Pxy, Pxy.gen(0)), (Paxb, Paxb.gen(1))]: + sage: Pxes = [(Px, Px.gen()), (Qx, Qx.gen()), + ....: (Pxy, Pxy.gen(0)), (Paxb, Paxb.gen(1))] + sage: Pxes += [(Rx, Rx.gen())] # optional - sage.rings.finite_rings + sage: for P, x in Pxes: ....: assert P(p1) == x and parent(P(p1)) is P ....: assert P(p2) == P.zero() and parent(P(p2)) is P ....: assert P(p3) == P.one() and parent(P(p3)) is P @@ -439,7 +442,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) - sage: (2+t).is_unit() + sage: (2 + t).is_unit() False sage: f = 2*t sage: f.is_unit() @@ -511,12 +514,12 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): You can specify a map on the base ring:: sage: Zx. = ZZ[] - sage: K. = NumberField(x^2 + 1) - sage: cc = K.hom([-i]) - sage: R. = LaurentPolynomialRing(K) - sage: H = Hom(R, R) - sage: phi = H([t^-2], base_map=cc) - sage: phi(i*t) + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: cc = K.hom([-i]) # optional - sage.rings.number_field + sage: R. = LaurentPolynomialRing(K) # optional - sage.rings.number_field + sage: H = Hom(R, R) # optional - sage.rings.number_field + sage: phi = H([t^-2], base_map=cc) # optional - sage.rings.number_field + sage: phi(i*t) # optional - sage.rings.number_field -i*t^-2 """ x = im_gens[0] @@ -534,7 +537,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) - sage: elt = t^2 + t^4 # indirect doctest + sage: elt = t^2 + t^4 # indirect doctest sage: elt.polynomial_construction() (t^2 + 1, 2) @@ -605,9 +608,9 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): Verify that :trac:`6656` has been fixed:: - sage: R.=PolynomialRing(QQ) - sage: T.=LaurentPolynomialRing(R) - sage: y = a*x+b*x + sage: R. = PolynomialRing(QQ) + sage: T. = LaurentPolynomialRing(R) + sage: y = a*x + b*x sage: y._latex_() '\\left(a + b\\right)x' sage: latex(y) @@ -813,20 +816,20 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: R. = LaurentPolynomialRing(QQ) sage: f = x^3 + 2/x - sage: g = f._symbolic_(SR); g + sage: g = f._symbolic_(SR); g # optional - sage.symbolic (x^4 + 2)/x - sage: g(x=2) + sage: g(x=2) # optional - sage.symbolic 9 - sage: g = SR(f) - sage: g(x=2) + sage: g = SR(f) # optional - sage.symbolic + sage: g(x=2) # optional - sage.symbolic 9 Since :trac:`24072` the symbolic ring does not accept positive characteristic:: - sage: R. = LaurentPolynomialRing(GF(7)) - sage: SR(2*w^3 + 1) + sage: R. = LaurentPolynomialRing(GF(7)) # optional - sage.rings.finite_rings + sage: SR(2*w^3 + 1) # optional - sage.rings.finite_rings sage.symbolic Traceback (most recent call last): ... TypeError: positive characteristic not allowed in symbolic computations @@ -1046,10 +1049,10 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): """ EXAMPLES:: - sage: R. = LaurentPolynomialRing(GF(2)) - sage: f = 1/x^3 + x + x^2 + 3*x^4 - sage: g = 1 - x + x^2 - x^4 - sage: f*g + sage: R. = LaurentPolynomialRing(GF(2)) # optional - sage.rings.finite_rings + sage: f = 1/x^3 + x + x^2 + 3*x^4 # optional - sage.rings.finite_rings + sage: g = 1 - x + x^2 - x^4 # optional - sage.rings.finite_rings + sage: f*g # optional - sage.rings.finite_rings x^-3 + x^-2 + x^-1 + x^8 """ cdef LaurentPolynomial_univariate right = right_r @@ -1625,10 +1628,10 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): The answer is dependent of the base ring:: - sage: S. = LaurentPolynomialRing(QQbar) - sage: (2 + 4*t + 2*t^2).is_square() + sage: S. = LaurentPolynomialRing(QQbar) # optional - sage.rings.number_field + sage: (2 + 4*t + 2*t^2).is_square() # optional - sage.rings.number_field False - sage: (2 + 4*u + 2*u^2).is_square() + sage: (2 + 4*u + 2*u^2).is_square() # optional - sage.rings.number_field True TESTS:: @@ -1753,10 +1756,10 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: R. = LaurentPolynomialRing(ZZ) sage: p = 1/x + 1 + x - sage: x,y = var("x, y") - sage: p._derivative(x) + sage: x,y = var("x, y") # optional - sage.symbolic + sage: p._derivative(x) # optional - sage.symbolic -x^-2 + 1 - sage: p._derivative(y) + sage: p._derivative(y) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: cannot differentiate with respect to y @@ -1903,7 +1906,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: R. = LaurentPolynomialRing(ZZ) sage: f = 4*t^-7 + 3*t^3 + 2*t^4 + t^-6 - sage: f.factor() + sage: f.factor() # optional - sage.libs.pari (t^-7) * (4 + t + 3*t^10 + 2*t^11) """ cdef LaurentPolynomial_univariate u, d @@ -1961,1809 +1964,3 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): 0 """ return self.__u[-self.__n] - - -cdef class LaurentPolynomial_mpair(LaurentPolynomial): - """ - Multivariate Laurent polynomials. - """ - def __init__(self, parent, x, mon=None, reduce=True): - """ - Currently, one can only create LaurentPolynomials out of dictionaries - and elements of the base ring. - - INPUT: - - - ``parent`` -- a SageMath parent - - - ``x`` -- an element or dictionary or anything the underlying - polynomial ring accepts - - - ``mon`` -- (default: ``None``) a tuple specifying the shift - in the exponents - - - ``reduce`` -- (default: ``True``) a boolean - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = L({(-1,-1):1}); f - w^-1*z^-1 - sage: f = L({(1,1):1}); f - w*z - sage: f = L({(-1,-1):1, (1,3):4}); f - 4*w*z^3 + w^-1*z^-1 - sage: L(1/2) - 1/2 - - TESTS: - - Check that :trac:`19538` is fixed:: - - sage: R = LaurentPolynomialRing(QQ,'x2,x0') - sage: S = LaurentPolynomialRing(QQ,'x',3) - sage: f = S.coerce_map_from(R) - sage: f(R.gen(0) + R.gen(1)^2) - x0^2 + x2 - sage: _.parent() - Multivariate Laurent Polynomial Ring in x0, x1, x2 over Rational Field - - :: - - sage: from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial_mpair - sage: LaurentPolynomial_mpair(L, {(1,2): 1/42}, mon=(-3, -3)) - 1/42*w^-2*z^-1 - - :trac:`22398`:: - - sage: LQ = LaurentPolynomialRing(QQ, 'x0, x1, x2, y0, y1, y2, y3, y4, y5') - sage: LZ = LaurentPolynomialRing(ZZ, 'x0, x1, x2, y0, y1, y2, y3, y4, y5') - sage: LQ.inject_variables() - Defining x0, x1, x2, y0, y1, y2, y3, y4, y5 - sage: x2^-1*y0*y1*y2*y3*y4*y5 + x1^-1*x2^-1*y0*y1*y3*y4 + x0^-1 in LZ - True - sage: x2^-1*y0*y1*y2*y3*y4*y5 + x1^-1*x2^-1*y0*y1*y3*y4 + x0^-1*x1^-1*y0*y3 + x0^-1 in LZ - True - - Check that input is not modified:: - - sage: LQ. = LaurentPolynomialRing(QQ) - sage: D = {(-1, 1): 1} - sage: k = tuple(D)[0] - sage: v = D[k] - sage: type(k), type(v) - (<... 'tuple'>, ) - sage: LQ(D) - x^-1*y - sage: tuple(D)[0] is k - True - sage: D[k] is v - True - """ - if isinstance(x, PolyDict): - x = x.dict() - if mon is not None: - if isinstance(mon, ETuple): - self._mon = mon - else: - self._mon = ETuple(mon) - else: - if isinstance(x, dict): - self._mon = ETuple({}, int(parent.ngens())) - D = {} - for k, x_k in x.iteritems(): # ETuple-ize keys, set _mon - if not isinstance(k, (tuple, ETuple)) or len(k) != parent.ngens(): - self._mon = ETuple({}, int(parent.ngens())) - break - if isinstance(k, tuple): - k = ETuple(k) - D[k] = x_k - self._mon = self._mon.emin(k) # point-wise min of _mon and k - else: - x = D - if not self._mon.is_constant(): # factor out _mon - x = {k.esub(self._mon): x_k for k, x_k in x.iteritems()} - elif (isinstance(x, LaurentPolynomial_mpair) and - parent.variable_names() == x.parent().variable_names()): - self._mon = (x)._mon - x = (x)._poly - else: # since x should coerce into parent, _mon should be (0,...,0) - self._mon = ETuple({}, int(parent.ngens())) - self._poly = parent._R(x) - CommutativeAlgebraElement.__init__(self, parent) - - def __reduce__(self): - """ - TESTS:: - - sage: R = LaurentPolynomialRing(QQ,2,'x') - sage: R. = LaurentPolynomialRing(QQ) - sage: loads(dumps(x1)) == x1 # indirect doctest - True - sage: z = x1/x2 - sage: loads(dumps(z)) == z - True - """ - return self._parent, (self._poly, self._mon) - - def __hash__(self): - r""" - TESTS: - - Test that the hash is non-constant (see also :trac:`27914`):: - - sage: L. = LaurentPolynomialRing(QQ) - sage: len({hash(w^i*z^j) for i in [-2..2] for j in [-2..2]}) - 25 - - Check that :trac:`20490` is fixed:: - - sage: R. = LaurentPolynomialRing(ZZ) - sage: p = a*~a - sage: p._fraction_pair() - (a, a) - sage: p == R.one() - True - sage: hash(p) - 1 - - Check that :trac:`23864` is fixed (compatibility with integers, rationals - and polynomial rings):: - - sage: L = LaurentPolynomialRing(QQ, 'x0,x1,x2') - sage: hash(L.zero()) - 0 - sage: hash(L.one()) - 1 - sage: hash(-L.one()) - -2 - sage: hash(L(1/2)) == hash(1/2) - True - - sage: R = PolynomialRing(QQ, 'x0,x1,x2') - sage: x0,x1,x2 = R.gens() - sage: hash(x0) == hash(L(x0)) - True - sage: hash(1 - 7*x0 + x1*x2) == hash(L(1 - 7*x0 + x1*x2)) - True - - Check that :trac:`27914` is fixed:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: Lw = LaurentPolynomialRing(QQ, 'w') - sage: Lz = LaurentPolynomialRing(QQ, 'z') - sage: all(hash(w^k) == hash(Lw(w^k)) - ....: and hash(z^k) == hash(Lz(z^k)) for k in (-5..5)) - True - sage: p = w^-1 + 2 + w - sage: hash(p) == hash(Lw(p)) - True - """ - # we reimplement the hash from multipolynomial to handle negative exponents - # (see multi_polynomial.pyx) - cdef long result = 0 - cdef long exponent - cdef list var_name_hash = [hash(v) for v in self._parent.variable_names()] - cdef int p - cdef int n = len(var_name_hash) - cdef long c_hash - for m, c in self._poly.iterator_exp_coeff(): - c_hash = hash(c) - if c_hash != 0: - for p in range(n): - exponent = m[p] + self._mon[p] - if exponent > 0: - c_hash = (1000003 * c_hash) ^ var_name_hash[p] - c_hash = (1000003 * c_hash) ^ exponent - elif exponent < 0: - c_hash = (1000003 * c_hash) ^ var_name_hash[p] - c_hash = (700005 * c_hash) ^ exponent - result += c_hash - - return result - - def _im_gens_(self, codomain, im_gens, base_map=None): - """ - Return the image of ``self`` under the morphism defined by - ``im_gens`` in ``codomain``. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(ZZ) - sage: M. = LaurentPolynomialRing(ZZ) - sage: phi = L.hom([u,v]) - sage: phi(x^2*~y -5*y**3) # indirect doctest - -5*v^3 + u^2*v^-1 - - TESTS: - - check compatibility with :trac:`26105`:: - - sage: F. = GF(4) - sage: LF. = LaurentPolynomialRing(F) - sage: rho = LF.hom([b,a], base_map=F.frobenius_endomorphism()) - sage: s = t*~a + b +~t*(b**-3)*a**2; rs = rho(s); rs - a + (t + 1)*b^-1 + t*a^-3*b^2 - sage: s == rho(rs) - True - """ - p = self._poly - m = self._mon - if base_map is not None: - p = p.map_coefficients(base_map) - from sage.misc.misc_c import prod - return codomain(p(im_gens) * prod(ig**m[im_gens.index(ig)] for ig in im_gens)) - - cdef _normalize(self, i=None): - r""" - Remove the common monomials from ``self._poly`` and store - them in ``self._mon``. - - INPUT: - - - ``i`` -- an integer - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = x*y + 2*y*x^2 + y # indirect doctest - sage: f.factor() # Notice the y has been factored out. - (y) * (2*x^2 + x + 1) - - Check that :trac:`23864` has been fixed:: - - sage: hash(L.zero()) - 0 - """ - if not self._poly: - self._mon = ETuple({}, int(self._parent.ngens())) - return - - #cdef dict D = self._poly._mpoly_dict_recursive( - # self._parent.variable_names(), - # self._parent.base_ring() - # ) - cdef dict D = self._poly.dict() - - cdef ETuple e - if i is None: - e = None - for k in D: - if e is None: - e = k - else: - e = e.emin(k) - if not e.is_constant(): - self._poly = (self._poly // self._poly._parent({e: 1})) - self._mon = self._mon.eadd(e) - else: - e = None - for k in D: - if e is None or k[i] < e: - e = k[i] - if e > 0: - self._poly = (self._poly // self._poly._parent.gen(i)) - self._mon = self._mon.eadd_p(e, i) - - cdef _compute_polydict(self): - """ - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: a = w^2*z^-1 +3 - sage: a.dict() # indirect doctest - {(0, 0): 3, (2, -1): 1} - """ - #cdef dict D = self._poly._mpoly_dict_recursive(self._parent.variable_names(), - # self._parent.base_ring()) - cdef dict D = self._poly.dict() - cdef dict DD - if self._mon.is_constant(): - self._prod = PolyDict(D) - return - DD = {} - for k in D: - DD[k.eadd(self._mon)] = D[k] - self._prod = PolyDict(DD) - - def is_unit(self): - """ - Return ``True`` if ``self`` is a unit. - - The ground ring is assumed to be an integral domain. - - This means that the Laurent polynomial is a monomial - with unit coefficient. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: (x*y/2).is_unit() - True - sage: (x + y).is_unit() - False - sage: (L.zero()).is_unit() - False - sage: (L.one()).is_unit() - True - - sage: L. = LaurentPolynomialRing(ZZ) - sage: (2*x*y).is_unit() - False - """ - coeffs = self.coefficients() - if len(coeffs) != 1: - return False - return coeffs[0].is_unit() - - def _repr_(self): - """ - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = x^2 + x*y/2 + 2*y^-1 - sage: f._repr_() - 'x^2 + 1/2*x*y + 2*y^-1' - """ - if self._prod is None: - self._compute_polydict() - try: - key = self.parent().term_order().sortkey - except AttributeError: - key = None - atomic = self.parent().base_ring()._repr_option('element_is_atomic') - return self._prod.poly_repr(self.parent().variable_names(), - atomic_coefficients=atomic, sortkey=key) - - def _latex_(self): - r""" - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: a = w^2*z^-1+3; a - w^2*z^-1 + 3 - sage: latex(a) - w^{2} z^{-1} + 3 - - TESTS:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: latex(1/lambda2 + y2^(-3)) - \lambda_{2}^{-1} + y_{2}^{-3} - """ - if self._prod is None: - self._compute_polydict() - try: - key = self.parent().term_order().sortkey - except AttributeError: - key = None - atomic = self.parent().base_ring()._repr_option('element_is_atomic') - return self._prod.latex(self.parent().latex_variable_names(), - atomic_coefficients=atomic, sortkey=key) - - cpdef long number_of_terms(self) except -1: - """ - Return the number of non-zero coefficients of ``self``. - - Also called weight, hamming weight or sparsity. - - EXAMPLES:: - - sage: R. = LaurentPolynomialRing(ZZ) - sage: f = x^3 - y - sage: f.number_of_terms() - 2 - sage: R(0).number_of_terms() - 0 - sage: f = (x+1/y)^100 - sage: f.number_of_terms() - 101 - - The method :meth:`hamming_weight` is an alias:: - - sage: f.hamming_weight() - 101 - """ - return self._poly.number_of_terms() - - def __invert__(LaurentPolynomial_mpair self): - """ - Return the inverse of ``self``. - - This treats monomials specially so they remain Laurent - polynomials; the inverse of any other polynomial is an element - of the rational function field. - - TESTS:: - - sage: L. = LaurentPolynomialRing(ZZ) - sage: f = ~x - sage: parent(f) - Multivariate Laurent Polynomial Ring in x, y over Integer Ring - sage: parent(f.coefficients()[0]) is parent(f).base_ring() - True - sage: g = ~(2*x) - sage: parent(g) - Multivariate Laurent Polynomial Ring in x, y over Rational Field - sage: parent(g.coefficients()[0]) is parent(g).base_ring() - True - """ - cdef ETuple e - if self._poly.is_term(): - (e, c), = self.dict().items() - e = e.emul(-1) - P = self._parent - try: - c = c.inverse_of_unit() - except (AttributeError, ZeroDivisionError, ArithmeticError): - c = ~c - if c.parent() is not P.base_ring(): - P = P.change_ring(c.parent()) - return P({e: c}) - return super().__invert__() - - def __pow__(LaurentPolynomial_mpair self, n, m): - """ - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = x + y - sage: f^2 - x^2 + 2*x*y + y^2 - sage: f^(-1) - 1/(x + y) - - TESTS: - - Check that :trac:`2952` is fixed:: - - sage: R. = QQ[] - sage: L. = LaurentPolynomialRing(R) - sage: f = (x+y+z^-1)^2 - sage: f.substitute(z=1) - x^2 + 2*x*y + y^2 + 2*x + 2*y + 1 - """ - cdef LaurentPolynomial_mpair ans - if n < 0: - return ~(self ** -n) - ans = self._new_c() - ans._poly = self._poly ** n - ans._mon = self._mon.emul(n) - return ans - - def __getitem__(self, n): - r""" - Return the coefficient of `x^n = x_1^{n_1} \cdots x_k^{n_k}` where - `n` is a tuple of length `k` and `k` is the number of variables. - - If the number of inputs is not equal to the number of variables, this - raises a ``TypeError``. - - EXAMPLES:: - - sage: P. = LaurentPolynomialRing(QQ) - sage: f = (y^2 - x^9 - 7*x*y^3 + 5*x*y)*x^-3 + x*z; f - -x^6 + x*z - 7*x^-2*y^3 + 5*x^-2*y + x^-3*y^2 - sage: f[6,0,0] - -1 - sage: f[-2,3,0] - -7 - sage: f[-1,4,2] - 0 - sage: f[1,0,1] - 1 - sage: f[6] - Traceback (most recent call last): - ... - TypeError: must have exactly 3 inputs - sage: f[6,0] - Traceback (most recent call last): - ... - TypeError: must have exactly 3 inputs - sage: f[6,0,0,0] - Traceback (most recent call last): - ... - TypeError: must have exactly 3 inputs - """ - if isinstance(n, slice): - raise TypeError("multivariate Laurent polynomials are not iterable") - if not isinstance(n, tuple) or len(n) != self._parent.ngens(): - raise TypeError("must have exactly %s inputs" % - self.parent().ngens()) - cdef ETuple t = ETuple(n) - if self._prod is None: - self._compute_polydict() - try: - return self._prod[t] - except KeyError: - return self._parent.base_ring().zero() - - def __iter__(self): - """ - Iterate through all terms by returning a list of the coefficient and - the corresponding monomial. - - EXAMPLES:: - - sage: P. = LaurentPolynomialRing(QQ) - sage: f = (y^2 - x^9 - 7*x*y^3 + 5*x*y)*x^-3 - sage: sorted(f) # indirect doctest - [(-7, x^-2*y^3), (-1, x^6), (1, x^-3*y^2), (5, x^-2*y)] - """ - P = self._parent - one = P._R.one() - if self._mon.is_constant(): - for exp, coeff in self._poly.iterator_exp_coeff(): - yield (coeff, P.element_class(P, one, exp)) - else: - for exp, coeff in self._poly.iterator_exp_coeff(): - yield (coeff, P.element_class(P, one, exp.eadd(self._mon))) - - def iterator_exp_coeff(self): - """ - Iterate over ``self`` as pairs of (ETuple, coefficient). - - EXAMPLES:: - - sage: P. = LaurentPolynomialRing(QQ) - sage: f = (y^2 - x^9 - 7*x*y^3 + 5*x*y)*x^-3 - sage: list(f.iterator_exp_coeff()) - [((6, 0), -1), ((-2, 3), -7), ((-2, 1), 5), ((-3, 2), 1)] - """ - for exp, coeff in self._poly.iterator_exp_coeff(): - yield (exp.eadd(self._mon), coeff) - - def monomials(self): - """ - Return the list of monomials in ``self``. - - EXAMPLES:: - - sage: P. = LaurentPolynomialRing(QQ) - sage: f = (y^2 - x^9 - 7*x*y^3 + 5*x*y)*x^-3 - sage: sorted(f.monomials()) - [x^-3*y^2, x^-2*y, x^-2*y^3, x^6] - """ - return [mon for coeff, mon in self] - - def monomial_coefficient(self, mon): - """ - Return the coefficient in the base ring of the monomial ``mon`` in - ``self``, where ``mon`` must have the same parent as ``self``. - - This function contrasts with the function :meth:`coefficient()` - which returns the coefficient of a monomial viewing this - polynomial in a polynomial ring over a base ring having fewer - variables. - - INPUT: - - - ``mon`` -- a monomial - - .. SEEALSO:: - - For coefficients in a base ring of fewer variables, see - :meth:`coefficient()`. - - EXAMPLES:: - - sage: P. = LaurentPolynomialRing(QQ) - sage: f = (y^2 - x^9 - 7*x*y^3 + 5*x*y)*x^-3 - sage: f.monomial_coefficient(x^-2*y^3) - -7 - sage: f.monomial_coefficient(x^2) - 0 - - TESTS:: - - sage: P. = LaurentPolynomialRing(QQ) - sage: f = y^2 * x^-2 - sage: f.monomial_coefficient(x + y) - Traceback (most recent call last): - ... - ValueError: not a monomial - """ - if parent(mon) != self._parent: - raise TypeError("input must have the same parent") - cdef LaurentPolynomial_mpair m = mon - if m._prod is None: - m._compute_polydict() - if self._prod is None: - self._compute_polydict() - exp = monomial_exponent(m._prod) - zero = self._parent.base_ring().zero() - return self._prod.get(exp, zero) - - def constant_coefficient(self): - """ - Return the constant coefficient of ``self``. - - EXAMPLES:: - - sage: P. = LaurentPolynomialRing(QQ) - sage: f = (y^2 - x^9 - 7*x*y^2 + 5*x*y)*x^-3; f - -x^6 - 7*x^-2*y^2 + 5*x^-2*y + x^-3*y^2 - sage: f.constant_coefficient() - 0 - sage: f = (x^3 + 2*x^-2*y+y^3)*y^-3; f - x^3*y^-3 + 1 + 2*x^-2*y^-2 - sage: f.constant_coefficient() - 1 - """ - return self[(0,)*self._parent.ngens()] - - def coefficient(self, mon): - r""" - Return the coefficient of ``mon`` in ``self``, where ``mon`` must - have the same parent as ``self``. - - The coefficient is defined as follows. If `f` is this polynomial, then - the coefficient `c_m` is sum: - - .. MATH:: - - c_m := \sum_T \frac{T}{m} - - where the sum is over terms `T` in `f` that are exactly divisible - by `m`. - - A monomial `m(x,y)` 'exactly divides' `f(x,y)` if `m(x,y) | f(x,y)` - and neither `x \cdot m(x,y)` nor `y \cdot m(x,y)` divides `f(x,y)`. - - INPUT: - - - ``mon`` -- a monomial - - OUTPUT: - - Element of the parent of ``self``. - - .. NOTE:: - - To get the constant coefficient, call - :meth:`constant_coefficient()`. - - EXAMPLES:: - - sage: P. = LaurentPolynomialRing(QQ) - - The coefficient returned is an element of the parent of ``self``; in - this case, ``P``. :: - - sage: f = 2 * x * y - sage: c = f.coefficient(x*y); c - 2 - sage: c.parent() - Multivariate Laurent Polynomial Ring in x, y over Rational Field - - sage: P. = LaurentPolynomialRing(QQ) - sage: f = (y^2 - x^9 - 7*x*y^2 + 5*x*y)*x^-3; f - -x^6 - 7*x^-2*y^2 + 5*x^-2*y + x^-3*y^2 - sage: f.coefficient(y) - 5*x^-2 - sage: f.coefficient(y^2) - -7*x^-2 + x^-3 - sage: f.coefficient(x*y) - 0 - sage: f.coefficient(x^-2) - -7*y^2 + 5*y - sage: f.coefficient(x^-2*y^2) - -7 - sage: f.coefficient(1) - -x^6 - 7*x^-2*y^2 + 5*x^-2*y + x^-3*y^2 - """ - if mon.parent() is not self._parent: - mon = self._parent(mon) - cdef LaurentPolynomial_mpair m = mon - if self._prod is None: - self._compute_polydict() - if m._prod is None: - m._compute_polydict() - return self._parent(self._prod.coefficient(m.dict())) - - def coefficients(self): - """ - Return the nonzero coefficients of ``self`` in a list. - - The returned list is decreasingly ordered by the term ordering - of ``self.parent()``. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ,order='degrevlex') - sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 - sage: f.coefficients() - [4, 3, 2, 1] - sage: L. = LaurentPolynomialRing(QQ,order='lex') - sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 - sage: f.coefficients() - [4, 1, 2, 3] - """ - return self._poly.coefficients() - - def variables(self, sort=True): - """ - Return a tuple of all variables occurring in ``self``. - - INPUT: - - - ``sort`` -- specifies whether the indices shall be sorted - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 - sage: f.variables() - (z, y, x) - sage: f.variables(sort=False) #random - (y, z, x) - """ - cdef dict d = self.dict() - cdef tuple g = self._parent.gens() - cdef Py_ssize_t nvars = len(g) - cdef set vars = set() - for k in d: - vars.update(k.nonzero_positions()) - if len(vars) == nvars: - break - cdef list v = [g[i] for i in vars] - if sort: - v.sort() - return tuple(v) - - cpdef dict dict(self): - """ - Return ``self`` represented as a ``dict``. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 - sage: sorted(f.dict().items()) - [((3, 1, 0), 3), ((4, 0, -2), 2), ((6, -7, 0), 1), ((7, 0, -1), 4)] - """ - if self._prod is None: - self._compute_polydict() - return self._prod.dict() - - def _fraction_pair(self): - """ - Return one representation of ``self`` as a pair - ``(numerator, denominator)``. - - Here both the numerator and the denominator are polynomials. - - This is used for coercion into the fraction field. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 - sage: f._fraction_pair() - (4*x^7*y^7*z + 3*x^3*y^8*z^2 + 2*x^4*y^7 + x^6*z^2, y^7*z^2) - """ - ring = self._parent._R - numer = self._poly - denom = ring.one() - var = ring.gens() - for i, j in enumerate(self._mon): - if j > 0: - numer *= var[i] ** j - else: - denom *= var[i] ** (-j) - return (numer, denom) - - cpdef _add_(self, _right): - """ - Return the Laurent polynomial ``self + right``. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = x + y^-1 - sage: g = y + z - sage: f + g - x + y + z + y^-1 - """ - cdef LaurentPolynomial_mpair ans = self._new_c() - cdef LaurentPolynomial_mpair right = _right - ans._mon, a, b = self._mon.combine_to_positives(right._mon) - if not a.is_constant(): - ans._poly = self._poly * self._poly._parent({a: 1}) - else: - ans._poly = self._poly - if not b.is_constant(): - ans._poly += right._poly * self._poly._parent({b: 1}) - else: - ans._poly += right._poly - return ans - - cpdef _sub_(self, _right): - """ - Return the Laurent polynomial ``self - right``. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = x + y^-1 - sage: g = y + z + x - sage: f - g - -y - z + y^-1 - """ - cdef LaurentPolynomial_mpair ans = self._new_c() - cdef LaurentPolynomial_mpair right = _right - cdef ETuple a, b - ans._mon, a, b = self._mon.combine_to_positives(right._mon) - if not a.is_constant(): - ans._poly = self._poly * self._poly._parent({a: 1}) - else: - ans._poly = self._poly - if not b.is_constant(): - ans._poly -= right._poly * self._poly._parent({b: 1}) - else: - ans._poly -= right._poly - return ans - - cpdef _div_(self, rhs): - """ - Return the division of ``self`` by ``rhs``. - - If the denominator is not a unit, - the result will be given in the fraction field. - - EXAMPLES:: - - sage: R. = LaurentPolynomialRing(QQ) - sage: 1/s - s^-1 - sage: 1/(s*q) - s^-1*q^-1 - sage: 1/(s+q) - 1/(s + q) - sage: (1/(s+q)).parent() - Fraction Field of Multivariate Polynomial Ring in s, q, t over Rational Field - sage: (1/(s*q)).parent() - Multivariate Laurent Polynomial Ring in s, q, t over Rational Field - sage: (s+q)/(q^2*t^(-2)) - s*q^-2*t^2 + q^-1*t^2 - """ - cdef LaurentPolynomial_mpair right = rhs - if right.is_zero(): - raise ZeroDivisionError - if right._poly.is_term(): - return self * ~right - else: - return RingElement._div_(self, rhs) - - def is_monomial(self): - """ - Return ``True`` if ``self`` is a monomial. - - EXAMPLES:: - - sage: k. = LaurentPolynomialRing(QQ) - sage: z.is_monomial() - True - sage: k(1).is_monomial() - True - sage: (z+1).is_monomial() - False - sage: (z^-2909).is_monomial() - True - sage: (38*z^-2909).is_monomial() - False - """ - return self._poly.is_monomial() - - cpdef _neg_(self): - """ - Return ``-self``. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = x + y^-1 - sage: -f - -x - y^-1 - """ - cdef LaurentPolynomial_mpair ans = self._new_c() - ans._mon = self._mon - ans._poly = -self._poly - return ans - - cpdef _lmul_(self, Element right): - """ - Return ``self * right`` where ``right`` is in ``self``'s base ring. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = x + y^-1 - sage: f*(1/2) - 1/2*x + 1/2*y^-1 - """ - cdef LaurentPolynomial_mpair ans = self._new_c() - ans._mon = self._mon - ans._poly = self._poly * right - return ans - - cpdef _rmul_(self, Element left): - """ - Return ``left * self`` where ``left`` is in ``self``'s base ring. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = x + y^-1 - sage: (1/2)*f - 1/2*x + 1/2*y^-1 - """ - cdef LaurentPolynomial_mpair ans = self._new_c() - ans._mon = self._mon - ans._poly = left * self._poly - return ans - - cpdef _mul_(self, right): - """ - Return ``self * right``. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = x + y^-1 - sage: g = y + z - sage: f*g - x*y + x*z + 1 + y^-1*z - """ - cdef LaurentPolynomial_mpair ans = self._new_c() - ans._mon = self._mon.eadd((right)._mon) - ans._poly = self._poly * (right)._poly - return ans - - cpdef _floordiv_(self, right): - """ - Perform division with remainder and return the quotient. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = x^3 + y^-3 - sage: g = y + x - sage: f // g - x^5*y^-3 - x^4*y^-2 + x^3*y^-1 - - sage: h = x + y^(-1) - sage: f // h - x^2 - x*y^-1 + y^-2 - sage: h * (f // h) == f - True - sage: f // 1 - x^3 + y^-3 - sage: 1 // f - 0 - - TESTS: - - Check that :trac:`19357` is fixed:: - - sage: x // y - x*y^-1 - - Check that :trac:`21999` is fixed:: - - sage: L. = LaurentPolynomialRing(QQbar) - sage: (a+a*b) // a - b + 1 - """ - cdef LaurentPolynomial_mpair ans = self._new_c() - cdef LaurentPolynomial_mpair rightl = right - self._normalize() - rightl._normalize() - ans._mon = self._mon.esub(rightl._mon) - ans._poly = self._poly // rightl._poly - return ans - - @coerce_binop - def quo_rem(self, right): - """ - Divide this Laurent polynomial by ``right`` and return a quotient and - a remainder. - - INPUT: - - - ``right`` -- a Laurent polynomial - - OUTPUT: - - A pair of Laurent polynomials. - - EXAMPLES:: - - sage: R. = LaurentPolynomialRing(QQ) - sage: (s^2-t^2).quo_rem(s-t) - (s + t, 0) - sage: (s^-2-t^2).quo_rem(s-t) - (s + t, -s^2 + s^-2) - sage: (s^-2-t^2).quo_rem(s^-1-t) - (t + s^-1, 0) - - TESTS: - - Verify that :trac:`31257` is fixed:: - - sage: R. = LaurentPolynomialRing(QQ) - sage: q, r = (1/x).quo_rem(y) - sage: q, r - (x^-1*y^-1, 0) - sage: q*y + r == 1/x - True - sage: q,r = (x^-2 - y^2).quo_rem(x - y) - sage: q*(x - y) + r == x^-2 - y^2 - True - """ - # make copies of self and right so that the input can be normalized - # without affecting the objects that were passed to the method - cdef LaurentPolynomial_mpair selfl = self._new_c() - selfl._poly = self._poly - selfl._mon = self._mon - cdef LaurentPolynomial_mpair rightl = self._new_c() - rightl._poly = ( right)._poly - rightl._mon = ( right)._mon - - selfl._normalize() - rightl._normalize() - q, r = selfl._poly.quo_rem(rightl._poly) - ql = LaurentPolynomial_mpair(self._parent, q, - mon=selfl._mon.esub(rightl._mon)) - rl = LaurentPolynomial_mpair(self._parent, r, - mon=selfl._mon) - ql._normalize() - rl._normalize() - return (ql, rl) - - cpdef _richcmp_(self, right, int op): - """ - Compare two polynomials in a `LaurentPolynomialRing` based on the term - order from the parent ring. If the parent ring does not specify a term - order then only comparison by equality is supported. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = x + y^-1 - sage: g = y + z - sage: f == f - True - sage: f == g - False - sage: f == 2 - False - """ - if self._prod is None: - self._compute_polydict() - if ( right)._prod is None: - ( right)._compute_polydict() - - try: - sortkey = self._parent.term_order().sortkey - except AttributeError: - sortkey = None - - return self._prod.rich_compare((right)._prod, - op, sortkey) - - def exponents(self): - """ - Return a list of the exponents of ``self``. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: a = w^2*z^-1+3; a - w^2*z^-1 + 3 - sage: e = a.exponents() - sage: e.sort(); e - [(0, 0), (2, -1)] - - """ - return [a.eadd(self._mon) for a in self._poly.exponents()] - - def degree(self, x=None): - """ - Return the degree of ``x`` in ``self``. - - EXAMPLES:: - - sage: R. = LaurentPolynomialRing(QQ) - sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 - sage: f.degree(x) - 7 - sage: f.degree(y) - 1 - sage: f.degree(z) - 0 - """ - if not x: - return self._poly.total_degree() + sum(self._mon) - - cdef tuple g = self._parent.gens() - cdef Py_ssize_t i - cdef bint no_generator_found = True - for i in range(len(g)): - if g[i] is x: - no_generator_found = False - break - if no_generator_found: - raise TypeError("x must be a generator of parent") - return self._poly.degree(self._parent._R.gens()[i]) + self._mon[i] - - def has_inverse_of(self, i): - """ - INPUT: - - - ``i`` -- The index of a generator of ``self.parent()`` - - OUTPUT: - - Returns True if self contains a monomial including the inverse of - ``self.parent().gen(i)``, False otherwise. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 - sage: f.has_inverse_of(0) - False - sage: f.has_inverse_of(1) - True - sage: f.has_inverse_of(2) - True - """ - if (not isinstance(i, (int, Integer))) or (i < 0) or (i >= self._parent.ngens()): - raise TypeError("argument is not the index of a generator") - if self._mon[i] < 0: - self._normalize(i) - if self._mon[i] < 0: - return True - return False - return False - - def has_any_inverse(self): - """ - Returns True if self contains any monomials with a negative exponent, False otherwise. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 - sage: f.has_any_inverse() - True - sage: g = x^2 + y^2 - sage: g.has_any_inverse() - False - """ - for m in self._mon.nonzero_values(sort=False): - if m < 0: - return True - return False - - def __call__(self, *x, **kwds): - """ - Compute value of ``self`` at ``x``. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = x + 2*y + 3*z - sage: f(1,1,1) - 6 - sage: f = x^-1 + y + z - sage: f(0,1,1) - Traceback (most recent call last): - ... - ZeroDivisionError - - TESTS:: - - sage: f = x + 2*y + 3*z - sage: f(2) - Traceback (most recent call last): - ... - TypeError: number of arguments does not match the number of generators in parent - sage: f(2,0) - Traceback (most recent call last): - ... - TypeError: number of arguments does not match the number of generators in parent - sage: f( (1,1,1) ) - 6 - """ - if kwds: - f = self.subs(**kwds) - if x: # More than 1 non-keyword argument - return f(*x) - else: - return f - - cdef int l = len(x) - - if l == 1 and isinstance(x[0], (tuple, list)): - x = x[0] - l = len(x) - - if l != self._parent.ngens(): - raise TypeError("number of arguments does not match the number" - " of generators in parent") - - #Check to make sure that we aren't dividing by zero - cdef Py_ssize_t m - for m in range(l): - if x[m] == 0: - if self.has_inverse_of(m): - raise ZeroDivisionError - - ans = self._poly(*x) - if ans: - for m in self._mon.nonzero_positions(): - ans *= x[m]**self._mon[m] - - return ans - - def subs(self, in_dict=None, **kwds): - """ - Substitute some variables in this Laurent polynomial. - - Variable/value pairs for the substitution may be given - as a dictionary or via keyword-value pairs. If both are - present, the latter take precedence. - - INPUT: - - - ``in_dict`` -- dictionary (optional) - - - ``**kwargs`` -- keyword arguments - - OUTPUT: - - A Laurent polynomial. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = x + 2*y + 3*z - sage: f.subs(x=1) - 2*y + 3*z + 1 - sage: f.subs(y=1) - x + 3*z + 2 - sage: f.subs(z=1) - x + 2*y + 3 - sage: f.subs(x=1, y=1, z=1) - 6 - - sage: f = x^-1 - sage: f.subs(x=2) - 1/2 - sage: f.subs({x: 2}) - 1/2 - - sage: f = x + 2*y + 3*z - sage: f.subs({x: 1, y: 1, z: 1}) - 6 - sage: f.substitute(x=1, y=1, z=1) - 6 - - TESTS:: - - sage: f = x + 2*y + 3*z - sage: f(q=10) - x + 2*y + 3*z - - sage: x.subs({x: 2}, x=1) - 1 - """ - cdef list variables = list(self._parent.gens()) - cdef Py_ssize_t i - for i in range(len(variables)): - if str(variables[i]) in kwds: - variables[i] = kwds[str(variables[i])] - elif in_dict and variables[i] in in_dict: - variables[i] = in_dict[variables[i]] - return self(tuple(variables)) - - def is_constant(self): - r""" - Return whether this Laurent polynomial is constant. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: L(0).is_constant() - True - sage: L(42).is_constant() - True - sage: a.is_constant() - False - sage: (1/b).is_constant() - False - """ - return (self._mon == ETuple({}, int(self._parent.ngens())) and - self._poly.is_constant()) - - def _symbolic_(self, R): - """ - EXAMPLES:: - - sage: R. = LaurentPolynomialRing(QQ) - sage: f = x^3 + y/x - sage: g = f._symbolic_(SR); g - (x^4 + y)/x - sage: g(x=2,y=2) - 9 - - sage: g = SR(f) - sage: g(x=2,y=2) - 9 - """ - d = {repr(g): R.var(g) for g in self._parent.gens()} - return self.subs(**d) - - def derivative(self, *args): - r""" - The formal derivative of this Laurent polynomial, with respect - to variables supplied in args. - - Multiple variables and iteration counts may be supplied; see - documentation for the global :func:`derivative` function for more - details. - - .. SEEALSO:: - - :meth:`_derivative` - - EXAMPLES:: - - sage: R = LaurentPolynomialRing(ZZ,'x, y') - sage: x, y = R.gens() - sage: t = x**4*y+x*y+y+x**(-1)+y**(-3) - sage: t.derivative(x, x) - 12*x^2*y + 2*x^-3 - sage: t.derivative(y, 2) - 12*y^-5 - """ - return multi_derivative(self, args) - - # add .diff(), .differentiate() as aliases for .derivative() - diff = differentiate = derivative - - def _derivative(self, var=None): - """ - Computes formal derivative of this Laurent polynomial with - respect to the given variable. - - If var is among the generators of this ring, the derivative - is with respect to the generator. Otherwise, ``_derivative(var)`` is called - recursively for each coefficient of this polynomial. - - .. SEEALSO:: :meth:`derivative` - - EXAMPLES:: - - sage: R = LaurentPolynomialRing(ZZ,'x, y') - sage: x, y = R.gens() - sage: t = x**4*y+x*y+y+x**(-1)+y**(-3) - sage: t._derivative(x) - 4*x^3*y + y - x^-2 - sage: t._derivative(y) - x^4 + x + 1 - 3*y^-4 - - sage: R = LaurentPolynomialRing(QQ['z'],'x') - sage: z = R.base_ring().gen() - sage: x = R.gen() - sage: t = 33*z*x**4+x**(-1) - sage: t._derivative(z) - 33*x^4 - sage: t._derivative(x) - -x^-2 + 132*z*x^3 - """ - if var is None: - raise ValueError("must specify which variable to differentiate " - "with respect to") - P = self._parent - cdef list gens = list(P.gens()) - - # check if var is one of the generators - try: - index = gens.index(var) - except ValueError: - # call _derivative() recursively on coefficients - return P({m: c._derivative(var) - for (m, c) in self.dict().iteritems()}) - - # compute formal derivative with respect to generator - cdef dict d = {} - for m, c in self.dict().iteritems(): - if m[index] != 0: - new_m = [u for u in m] - new_m[index] += -1 - d[ETuple(new_m)] = m[index] * c - return P(d) - - def is_univariate(self): - """ - Return ``True`` if this is a univariate or constant Laurent polynomial, - and ``False`` otherwise. - - EXAMPLES:: - - sage: R. = LaurentPolynomialRing(QQ) - sage: f = (x^3 + y^-3)*z - sage: f.is_univariate() - False - sage: g = f(1,y,4) - sage: g.is_univariate() - True - sage: R(1).is_univariate() - True - """ - return len(self.variables()) < 2 - - def univariate_polynomial(self, R=None): - """ - Returns a univariate polynomial associated to this - multivariate polynomial. - - INPUT: - - - ``R`` - (default: ``None``) a univariate Laurent polynomial ring - - If this polynomial is not in at most one variable, then a - ``ValueError`` exception is raised. The new polynomial is over - the same base ring as the given ``LaurentPolynomial`` and in the - variable ``x`` if no ring ``R`` is provided. - - EXAMPLES:: - - sage: R. = LaurentPolynomialRing(ZZ) - sage: f = 3*x^2 - 2*y^-1 + 7*x^2*y^2 + 5 - sage: f.univariate_polynomial() - Traceback (most recent call last): - ... - TypeError: polynomial must involve at most one variable - sage: g = f(10,y); g - 700*y^2 + 305 - 2*y^-1 - sage: h = g.univariate_polynomial(); h - -2*y^-1 + 305 + 700*y^2 - sage: h.parent() - Univariate Laurent Polynomial Ring in y over Integer Ring - sage: g.univariate_polynomial(LaurentPolynomialRing(QQ,'z')) - -2*z^-1 + 305 + 700*z^2 - - Here's an example with a constant multivariate polynomial:: - - sage: g = R(1) - sage: h = g.univariate_polynomial(); h - 1 - sage: h.parent() - Univariate Laurent Polynomial Ring in x over Integer Ring - """ - from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing - v = self.variables() - if len(v) > 1: - raise TypeError("polynomial must involve at most one variable") - elif len(v) == 1: - x = v[0] - i = self._parent.gens().index(x) - x = str(x) - else: - x = 'x' - i = 0 - - #construct ring if none - if R is None: - R = LaurentPolynomialRing(self.base_ring(), x) - - return R({m[i]: c for m,c in self.dict().iteritems()}) - - def factor(self): - """ - Returns a Laurent monomial (the unit part of the factorization) and a factored multi-polynomial. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 - sage: f.factor() - (x^3*y^-7*z^-2) * (4*x^4*y^7*z + 3*y^8*z^2 + 2*x*y^7 + x^3*z^2) - - TESTS: - - Tests for :trac:`29173`:: - - sage: L. = LaurentPolynomialRing(ZZ, 'a, b') - sage: (a*b + a + b + 1).factor() - (b + 1) * (a + 1) - sage: ((a^-1)*(a*b + a + b + 1)).factor() - (a^-1) * (b + 1) * (a + 1) - sage: L(-12).factor() - -1 * 2^2 * 3 - """ - pf = self._poly.factor() - - if self._poly.degree() == 0: - # Factorization is broken for polynomials, see - # https://github.com/sagemath/sage/issues/20214 - return pf - - u = self.parent(pf.unit()) - - cdef tuple g = self._parent.gens() - for i in self._mon.nonzero_positions(): - u *= g[i] ** self._mon[i] - - cdef list f = [] - cdef dict d - for t in pf: - d = (t[0].dict()) - if len(d) == 1: # monomials are units - u *= self.parent(d) ** t[1] - else: - f.append((self.parent(d), t[1])) - - return Factorization(f, unit=u) - - def is_square(self, root=False): - r""" - Test whether this Laurent polynomial is a square. - - INPUT: - - - ``root`` - boolean (default ``False``) - if set to ``True`` - then return a pair ``(True, sqrt)`` with ``sqrt`` a square - root of this Laurent polynomial when it exists or - ``(False, None)``. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ) - sage: p = (1 + x*y + z^-3) - sage: (p**2).is_square() - True - sage: (p**2).is_square(root=True) - (True, x*y + 1 + z^-3) - - sage: x.is_square() - False - sage: x.is_square(root=True) - (False, None) - - sage: (x**-4 * (1 + z)).is_square(root=False) - False - sage: (x**-4 * (1 + z)).is_square(root=True) - (False, None) - """ - self._normalize() - if not self._mon.is_multiple_of(2): - return (False, None) if root else False - - cdef LaurentPolynomial_mpair ans - - if not root: - return self._poly.is_square(root=False) - else: - (pans, root) = self._poly.is_square(root=True) - if not pans: - return (False, None) - - mon = self._mon.escalar_div(2) - ans = self._new_c() - ans._mon = mon - ans._poly = root - return (True, ans) - - cpdef rescale_vars(self, dict d, h=None, new_ring=None): - r""" - Rescale variables in a Laurent polynomial. - - INPUT: - - - ``d`` -- a ``dict`` whose keys are the generator indices - and values are the coefficients; so a pair ``(i, v)`` - means `x_i \mapsto v x_i` - - ``h`` -- (optional) a map to be applied to coefficients - done after rescaling - - ``new_ring`` -- (optional) a new ring to map the result into - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ, 2) - sage: p = x^-2*y + x*y^-2 - sage: p.rescale_vars({0: 2, 1: 3}) - 2/9*x*y^-2 + 3/4*x^-2*y - sage: F = GF(2) - sage: p.rescale_vars({0: 3, 1: 7}, new_ring=L.change_ring(F)) - x*y^-2 + x^-2*y - - Test for :trac:`30331`:: - - sage: F. = CyclotomicField(3) - sage: p.rescale_vars({0: 2, 1: z}, new_ring=L.change_ring(F)) - 2*z*x*y^-2 + 1/4*z*x^-2*y - """ - cdef int i - cdef dict df - cdef ETuple v - cdef LaurentPolynomial_mpair ans - - if self._prod is None: - self._compute_polydict() - - df = dict(self._prod.__repn) # This makes a copy for us to manipulate - if new_ring is None: - R = self._parent._base - else: - R = new_ring._base - if h is None: - for v in df: - val = df[v] - for i in d: - val *= d[i]**v[i] - df[v] = val - else: - for v in df: - val = df[v] - for i in d: - val *= d[i]**v[i] - df[v] = R(h(val)) - - ans = self._new_c() - ans._prod = PolyDict(df) - ans._mon = self._mon - if new_ring is None: - S = self._poly._parent - else: - S = self._poly._parent.change_ring(R) - ans._poly = S({v.esub(ans._mon): df[v] for v in df}) - if new_ring is not None: - return new_ring(ans) - return ans - - cpdef toric_coordinate_change(self, M, h=None, new_ring=None): - r""" - Apply a matrix to the exponents in a Laurent polynomial. - - For efficiency, we implement this directly, rather than as a substitution. - - The optional argument ``h`` is a map to be applied to coefficients. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ, 2) - sage: p = 2*x^2 + y - x*y - sage: p.toric_coordinate_change(Matrix([[1,-3],[1,1]])) - 2*x^2*y^2 - x^-2*y^2 + x^-3*y - sage: F = GF(2) - sage: p.toric_coordinate_change(Matrix([[1,-3],[1,1]]), new_ring=L.change_ring(F)) - x^-2*y^2 + x^-3*y - - """ - cdef int n, i, j, x - cdef dict d, dr - cdef ETuple v - cdef LaurentPolynomial_mpair ans - cdef list L, mon, exp - cdef Matrix mat = M - - n = self._parent.ngens() - if mat.dimensions() != (n, n): - raise ValueError("the matrix M must be a {k} x {k} matrix".format(k=n)) - - if not self: - if new_ring is None: - return self._parent.zero() - else: - return new_ring.zero() - - if self._prod is None: - self._compute_polydict() - - d = self._prod.__repn - dr = {} - mon = [0] * n - for v in d: - # Make a copy of mon as this might be faster than creating the data from scratch. - # We will set every entry, so no need to clear the data. - exp = list(mon) - for j in range(n): - x = 0 - for i in range(n): - if not mat.get_is_zero_unsafe(j, i): - x += ( v[i]) * int(mat.get_unsafe(j, i)) - if x < ( mon[j]): - mon[j] = x - exp[j] = x - dr[ETuple(exp)] = d[v] - - if h is not None: - for v in dr: - dr[v] = self._parent._base(h(dr[v])) - - ans = self._new_c() - ans._prod = PolyDict(dr) - ans._mon = ETuple(mon) - ans._poly = self._poly._parent({v.esub(ans._mon): dr[v] for v in dr}) - if new_ring is not None: - return new_ring(ans) - return ans - - cpdef toric_substitute(self, v, v1, a, h=None, new_ring=None): - r""" - Perform a single-variable substitution up to a toric coordinate change. - - The optional argument ``h`` is a map to be applied to coefficients. - - EXAMPLES:: - - sage: L. = LaurentPolynomialRing(QQ, 2) - sage: p = x + y - sage: p.toric_substitute((2,3), (-1,1), 2) - 1/2*x^3*y^3 + 2*x^-2*y^-2 - sage: F = GF(5) - sage: p.toric_substitute((2,3), (-1,1), 2, new_ring=L.change_ring(F)) - 3*x^3*y^3 + 2*x^-2*y^-2 - - TESTS: - - Tests for :trac:`30331`:: - - sage: L. = LaurentPolynomialRing(QQ, 2) - sage: p = x + y - sage: F. = CyclotomicField(3) - sage: p.toric_substitute((2,3), (-1,1), z, new_ring=L.change_ring(F)) - (-z - 1)*x^3*y^3 + z*x^-2*y^-2 - - sage: P. = LaurentPolynomialRing(QQ, 1) - sage: u = x - 1 - sage: v = u.toric_substitute((-1,), (-1,), 1) - sage: v.is_zero() - True - """ - cdef dict d, dr - cdef ETuple ve, v1e, w, w1, mon - cdef LaurentPolynomial_mpair ans - cdef int t - - if self._prod is None: - self._compute_polydict() - - d = self._prod.__repn - dr = {} - ve = ETuple(v) - v1e = ETuple(v1) - mon = self._mon - if h is not None: - d = dict(d) # Make a copy so we can manipulate it - for w in d: - d[w] = h(d[w]) - for w in d: - x = d[w] - t = w.dotprod(v1e) - w1 = w.eadd_scaled(ve, -t) - if w1 in dr: - dr[w1] += x * a**t - else: - dr[w1] = x * a**t - mon = mon.emin(w1) - for v in tuple(dr.keys()): - if not dr[v]: - del dr[v] - - if new_ring is None: - S = self._poly._parent - else: - S = self._poly._parent.change_ring(new_ring._base) - ans = self._new_c() - ans._prod = PolyDict(dr) - ans._mon = mon - ans._poly = S({v.esub(ans._mon): dr[v] for v in dr}) - if new_ring is not None: - return new_ring(ans) - return ans diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index 0168a56e267..2289b69e111 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -55,10 +55,12 @@ def __init__(self, ring, gens, coerce=True, hint=None): sage: R. = LaurentPolynomialRing(IntegerRing(), 2, order='lex') sage: R.ideal([x, y]) - Ideal (x, y) of Multivariate Laurent Polynomial Ring in x, y over Integer Ring - sage: R. = LaurentPolynomialRing(GF(3), 2) - sage: R.ideal([x0^2, x1^-3]) - Ideal (x0^2, x1^-3) of Multivariate Laurent Polynomial Ring in x0, x1 over Finite Field of size 3 + Ideal (x, y) of Multivariate Laurent Polynomial Ring in x, y + over Integer Ring + sage: R. = LaurentPolynomialRing(GF(3), 2) # optional - sage.rings.finite_rings + sage: R.ideal([x0^2, x1^-3]) # optional - sage.rings.finite_rings + Ideal (x0^2, x1^-3) of Multivariate Laurent Polynomial Ring in x0, x1 + over Finite Field of size 3 sage: P. = LaurentPolynomialRing(QQ, 2) sage: I = P.ideal([~x + ~y - 1]) @@ -70,19 +72,20 @@ def __init__(self, ring, gens, coerce=True, hint=None): True sage: P. = LaurentPolynomialRing(QQ, 3) - sage: I1 = P.ideal([x*y*z+x*y+2*y^2, x+z]) - sage: I2 = P.ideal([x*y*z+x*y+2*y^2+x+z, x+z]) + sage: I1 = P.ideal([x*y*z + x*y + 2*y^2, x + z]) + sage: I2 = P.ideal([x*y*z + x*y + 2*y^2 + x + z, x + z]) sage: I1 == I2 True - sage: I3 = P.ideal([x*y*z+x*y+2*y^2+x+z, x+z, y]) + sage: I3 = P.ideal([x*y*z + x*y + 2*y^2 + x + z, x + z, y]) sage: I1 < I3 True sage: I1.minimal_associated_primes() - (Ideal (-1/2*z^2 + y - 1/2*z, x + z) of Multivariate Laurent Polynomial Ring in x, y, z over Rational Field,) + (Ideal (-1/2*z^2 + y - 1/2*z, x + z) of Multivariate + Laurent Polynomial Ring in x, y, z over Rational Field,) - sage: K. = CyclotomicField(4) - sage: J = I1.base_extend(K) - sage: J.base_ring() + sage: K. = CyclotomicField(4) # optional - sage.rings.number_field + sage: J = I1.base_extend(K) # optional - sage.rings.number_field + sage: J.base_ring() # optional - sage.rings.number_field Cyclotomic Field of order 4 and degree 2 """ Ideal_generic.__init__(self, ring, gens, coerce=coerce) @@ -207,10 +210,11 @@ def change_ring(self, R, hint=None): EXAMPLES:: sage: P. = LaurentPolynomialRing(QQ, 2) - sage: I = P.ideal([x+y]) + sage: I = P.ideal([x + y]) sage: Q. = LaurentPolynomialRing(QQ, 3) sage: I.change_ring(Q) - Ideal (x + y) of Multivariate Laurent Polynomial Ring in x, y, z over Rational Field + Ideal (x + y) of Multivariate Laurent Polynomial Ring in x, y, z + over Rational Field """ return R.ideal(self.gens(), hint=hint) @@ -223,10 +227,11 @@ def base_extend(self, F): EXAMPLES:: sage: P. = LaurentPolynomialRing(QQ, 2) - sage: I = P.ideal([x+y]) - sage: K. = CyclotomicField(3) - sage: I.base_extend(K) - Ideal (x + y) of Multivariate Laurent Polynomial Ring in x, y over Cyclotomic Field of order 3 and degree 2 + sage: I = P.ideal([x + y]) + sage: K. = CyclotomicField(3) # optional - sage.rings.number_field + sage: I.base_extend(K) # optional - sage.rings.number_field + Ideal (x + y) of Multivariate Laurent Polynomial Ring in x, y + over Cyclotomic Field of order 3 and degree 2 """ ring = self.ring() return self.change_ring(ring.change_ring(F), hint=self._hint) @@ -241,12 +246,14 @@ def apply_map(self, f, new_ring=None, new_base_ring=None, apply_to_hint=None): EXAMPLES:: sage: P. = LaurentPolynomialRing(QQ, 2) - sage: I = P.ideal([x+1, y-1]) - sage: I.apply_map(lambda z: z+2) - Ideal (x + 3, y + 1) of Multivariate Laurent Polynomial Ring in x, y over Rational Field - sage: K. = CyclotomicField(4) - sage: I.apply_map(lambda z: z+2, new_base_ring=K) - Ideal (x + 3, y + 1) of Multivariate Laurent Polynomial Ring in x, y over Cyclotomic Field of order 4 and degree 2 + sage: I = P.ideal([x + 1, y - 1]) + sage: I.apply_map(lambda z: z + 2) + Ideal (x + 3, y + 1) of Multivariate Laurent Polynomial Ring in x, y + over Rational Field + sage: K. = CyclotomicField(4) # optional - sage.rings.number_field + sage: I.apply_map(lambda z: z + 2, new_base_ring=K) # optional - sage.rings.number_field + Ideal (x + 3, y + 1) of Multivariate Laurent Polynomial Ring in x, y + over Cyclotomic Field of order 4 and degree 2 """ ring = self.ring() if new_ring is not None: @@ -269,16 +276,18 @@ def apply_coeff_map(self, f, new_base_ring=None, forward_hint=True): EXAMPLES:: - sage: K. = CyclotomicField(3) - sage: P. = LaurentPolynomialRing(K, 2) - sage: I = P.ideal([x+z, y-z]) - sage: h = K.hom([z^2]) - sage: I.apply_coeff_map(h) - Ideal (x - z - 1, y + z + 1) of Multivariate Laurent Polynomial Ring in x, y over Cyclotomic Field of order 3 and degree 2 - sage: K1. = CyclotomicField(12) - sage: h1 = K.hom([z1^4]) - sage: I.apply_coeff_map(h1, new_base_ring=K1) - Ideal (x + z1^2 - 1, y - z1^2 + 1) of Multivariate Laurent Polynomial Ring in x, y over Cyclotomic Field of order 12 and degree 4 + sage: K. = CyclotomicField(3) # optional - sage.rings.number_field + sage: P. = LaurentPolynomialRing(K, 2) # optional - sage.rings.number_field + sage: I = P.ideal([x + z, y - z]) # optional - sage.rings.number_field + sage: h = K.hom([z^2]) # optional - sage.rings.number_field + sage: I.apply_coeff_map(h) # optional - sage.rings.number_field + Ideal (x - z - 1, y + z + 1) of Multivariate Laurent Polynomial Ring + in x, y over Cyclotomic Field of order 3 and degree 2 + sage: K1. = CyclotomicField(12) # optional - sage.rings.number_field + sage: h1 = K.hom([z1^4]) # optional - sage.rings.number_field + sage: I.apply_coeff_map(h1, new_base_ring=K1) # optional - sage.rings.number_field + Ideal (x + z1^2 - 1, y - z1^2 + 1) of Multivariate Laurent Polynomial Ring + in x, y over Cyclotomic Field of order 12 and degree 4 """ ring = self.ring() if new_base_ring is None: @@ -301,12 +310,13 @@ def toric_coordinate_change(self, M, forward_hint=True): EXAMPLES:: - sage: K. = CyclotomicField(3) - sage: P. = LaurentPolynomialRing(K, 2) - sage: I = P.ideal([x+1, y-1]) - sage: M = Matrix([[2,1],[1,-3]]) - sage: I.toric_coordinate_change(M) - Ideal (x^2*y + 1, -1 + x*y^-3) of Multivariate Laurent Polynomial Ring in x, y over Cyclotomic Field of order 3 and degree 2 + sage: K. = CyclotomicField(3) # optional - sage.rings.number_field + sage: P. = LaurentPolynomialRing(K, 2) # optional - sage.rings.number_field + sage: I = P.ideal([x + 1, y - 1]) # optional - sage.rings.number_field + sage: M = Matrix([[2,1], [1,-3]]) # optional - sage.rings.number_field + sage: I.toric_coordinate_change(M) # optional - sage.rings.number_field + Ideal (x^2*y + 1, -1 + x*y^-3) of Multivariate Laurent Polynomial Ring + in x, y over Cyclotomic Field of order 3 and degree 2 """ if forward_hint: R = self.ring() @@ -357,10 +367,12 @@ def normalize_gens(self): sage: P. = LaurentPolynomialRing(QQ, 2) sage: I = P.ideal([~x+y]) sage: J = P.ideal([y+1]) - sage: I+J - Ideal (y + x^-1, y + 1) of Multivariate Laurent Polynomial Ring in x, y over Rational Field - sage: (I+J).normalize_gens() - Ideal (x - 1, y + 1) of Multivariate Laurent Polynomial Ring in x, y over Rational Field + sage: I + J + Ideal (y + x^-1, y + 1) of Multivariate Laurent Polynomial Ring + in x, y over Rational Field + sage: (I + J).normalize_gens() + Ideal (x - 1, y + 1) of Multivariate Laurent Polynomial Ring + in x, y over Rational Field """ return self.ring().ideal(self.groebner_basis(), hint=self._hint) @@ -381,7 +393,8 @@ def polynomial_ideal(self, saturate=True): sage: P. = LaurentPolynomialRing(QQ, 2) sage: I = P.ideal([x^2*y + 3*x*y^2]) sage: I.polynomial_ideal() - Ideal (x + 3*y) of Multivariate Polynomial Ring in x, y over Rational Field + Ideal (x + 3*y) of Multivariate Polynomial Ring in x, y + over Rational Field """ if self._poly_ideal is not None and (self._saturated or not saturate): return self._poly_ideal @@ -416,9 +429,9 @@ def groebner_basis(self, saturate=True): EXAMPLES:: sage: P. = LaurentPolynomialRing(QQ, 2) - sage: I = P.ideal([x+y]) - sage: J = P.ideal([y+1]) - sage: (I+J).groebner_basis() + sage: I = P.ideal([x + y]) + sage: J = P.ideal([y + 1]) + sage: (I + J).groebner_basis() (x - 1, y + 1) """ l = self.polynomial_ideal(saturate=saturate).groebner_basis() @@ -470,10 +483,12 @@ def associated_primes(self): sage: P. = LaurentPolynomialRing(QQ, 3) sage: p = z^2 + 1; q = z^3 + 2 - sage: I = P.ideal((p*q^2, y-z^2)) + sage: I = P.ideal((p*q^2, y - z^2)) sage: tuple(sorted(I.associated_primes(), key=str)) - (Ideal (y + 1, z^2 + 1) of Multivariate Laurent Polynomial Ring in x, y, z over Rational Field, - Ideal (z^2 - y, y*z + 2, y^2 + 2*z) of Multivariate Laurent Polynomial Ring in x, y, z over Rational Field) + (Ideal (y + 1, z^2 + 1) of + Multivariate Laurent Polynomial Ring in x, y, z over Rational Field, + Ideal (z^2 - y, y*z + 2, y^2 + 2*z) of + Multivariate Laurent Polynomial Ring in x, y, z over Rational Field) """ l = self.polynomial_ideal(saturate=False).associated_primes() l2 = [self.ring().ideal(I.gens(), hint=I) for I in l] @@ -490,10 +505,12 @@ def minimal_associated_primes(self, saturate=False): sage: P. = LaurentPolynomialRing(QQ, 3) sage: p = z^2 + 1; q = z^3 + 2 - sage: I = P.ideal((p*q^2, y-z^2)) + sage: I = P.ideal((p*q^2, y - z^2)) sage: tuple(sorted(I.minimal_associated_primes(), key=str)) - (Ideal (z^2 + 1, -z^2 + y) of Multivariate Laurent Polynomial Ring in x, y, z over Rational Field, - Ideal (z^3 + 2, -z^2 + y) of Multivariate Laurent Polynomial Ring in x, y, z over Rational Field) + (Ideal (z^2 + 1, -z^2 + y) of + Multivariate Laurent Polynomial Ring in x, y, z over Rational Field, + Ideal (z^3 + 2, -z^2 + y) of + Multivariate Laurent Polynomial Ring in x, y, z over Rational Field) """ l = self.polynomial_ideal(saturate=saturate).minimal_associated_primes() l2 = [self.ring().ideal(I.gens(), hint=I) for I in l] @@ -508,7 +525,8 @@ def radical(self): sage: P. = LaurentPolynomialRing(QQ, 3) sage: I = P.ideal(((x+1)^2, (y+1)^3, ((x+1)*z)^4 + (y+1)^3 + 10*(x+1)^2)) sage: I.radical() - Ideal (y + 1, x + 1) of Multivariate Laurent Polynomial Ring in x, y, z over Rational Field + Ideal (y + 1, x + 1) of Multivariate Laurent Polynomial Ring in x, y, z + over Rational Field """ J = self.polynomial_ideal().radical() return self.ring().ideal(J.gens()) diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pxd b/src/sage/rings/polynomial/laurent_polynomial_mpair.pxd new file mode 100644 index 00000000000..79f09def6aa --- /dev/null +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pxd @@ -0,0 +1,14 @@ +from sage.rings.polynomial.laurent_polynomial cimport LaurentPolynomial +from sage.rings.polynomial.multi_polynomial cimport MPolynomial +from sage.rings.polynomial.polydict cimport ETuple, PolyDict + + +cdef class LaurentPolynomial_mpair(LaurentPolynomial): + cdef ETuple _mon + cdef MPolynomial _poly + cdef PolyDict _prod + cdef _compute_polydict(self) + cdef _normalize(self, i=*) + cpdef rescale_vars(self, dict d, h=*, new_ring=*) + cpdef toric_coordinate_change(self, M, h=*, new_ring=*) + cpdef toric_substitute(self, v, v1, a, h=*, new_ring=*) diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx new file mode 100644 index 00000000000..4597219b678 --- /dev/null +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -0,0 +1,1829 @@ +r""" +Elements of multivariate Laurent polynomial rings +""" + +# **************************************************************************** +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from sage.rings.integer cimport Integer +from sage.categories.map cimport Map +from sage.structure.element cimport CommutativeAlgebraElement, Element, ModuleElement, RingElement +from sage.structure.element import is_Element, coerce_binop, parent +from sage.structure.factorization import Factorization +from sage.misc.derivative import multi_derivative +from sage.rings.polynomial.polydict cimport monomial_exponent +from sage.rings.polynomial.polynomial_element import Polynomial +from sage.structure.richcmp cimport richcmp, rich_to_bool +from sage.matrix.matrix0 cimport Matrix + + +cdef class LaurentPolynomial_mpair(LaurentPolynomial): + """ + Multivariate Laurent polynomials. + """ + def __init__(self, parent, x, mon=None, reduce=True): + """ + Currently, one can only create LaurentPolynomials out of dictionaries + and elements of the base ring. + + INPUT: + + - ``parent`` -- a SageMath parent + + - ``x`` -- an element or dictionary or anything the underlying + polynomial ring accepts + + - ``mon`` -- (default: ``None``) a tuple specifying the shift + in the exponents + + - ``reduce`` -- (default: ``True``) a boolean + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = L({(-1,-1):1}); f + w^-1*z^-1 + sage: f = L({(1,1):1}); f + w*z + sage: f = L({(-1,-1):1, (1,3):4}); f + 4*w*z^3 + w^-1*z^-1 + sage: L(1/2) + 1/2 + + TESTS: + + Check that :trac:`19538` is fixed:: + + sage: R = LaurentPolynomialRing(QQ,'x2,x0') + sage: S = LaurentPolynomialRing(QQ,'x',3) + sage: f = S.coerce_map_from(R) + sage: f(R.gen(0) + R.gen(1)^2) + x0^2 + x2 + sage: _.parent() + Multivariate Laurent Polynomial Ring in x0, x1, x2 over Rational Field + + :: + + sage: from sage.rings.polynomial.laurent_polynomial_mpair import LaurentPolynomial_mpair + sage: LaurentPolynomial_mpair(L, {(1,2): 1/42}, mon=(-3, -3)) + 1/42*w^-2*z^-1 + + :trac:`22398`:: + + sage: LQ = LaurentPolynomialRing(QQ, 'x0, x1, x2, y0, y1, y2, y3, y4, y5') + sage: LZ = LaurentPolynomialRing(ZZ, 'x0, x1, x2, y0, y1, y2, y3, y4, y5') + sage: LQ.inject_variables() + Defining x0, x1, x2, y0, y1, y2, y3, y4, y5 + sage: x2^-1*y0*y1*y2*y3*y4*y5 + x1^-1*x2^-1*y0*y1*y3*y4 + x0^-1 in LZ + True + sage: x2^-1*y0*y1*y2*y3*y4*y5 + x1^-1*x2^-1*y0*y1*y3*y4 + x0^-1*x1^-1*y0*y3 + x0^-1 in LZ + True + + Check that input is not modified:: + + sage: LQ. = LaurentPolynomialRing(QQ) + sage: D = {(-1, 1): 1} + sage: k = tuple(D)[0] + sage: v = D[k] + sage: type(k), type(v) + (<... 'tuple'>, ) + sage: LQ(D) + x^-1*y + sage: tuple(D)[0] is k + True + sage: D[k] is v + True + """ + if isinstance(x, PolyDict): + x = x.dict() + if mon is not None: + if isinstance(mon, ETuple): + self._mon = mon + else: + self._mon = ETuple(mon) + else: + if isinstance(x, dict): + self._mon = ETuple({}, int(parent.ngens())) + D = {} + for k, x_k in x.iteritems(): # ETuple-ize keys, set _mon + if not isinstance(k, (tuple, ETuple)) or len(k) != parent.ngens(): + self._mon = ETuple({}, int(parent.ngens())) + break + if isinstance(k, tuple): + k = ETuple(k) + D[k] = x_k + self._mon = self._mon.emin(k) # point-wise min of _mon and k + else: + x = D + if not self._mon.is_constant(): # factor out _mon + x = {k.esub(self._mon): x_k for k, x_k in x.iteritems()} + elif (isinstance(x, LaurentPolynomial_mpair) and + parent.variable_names() == x.parent().variable_names()): + self._mon = (x)._mon + x = (x)._poly + else: # since x should coerce into parent, _mon should be (0,...,0) + self._mon = ETuple({}, int(parent.ngens())) + self._poly = parent._R(x) + CommutativeAlgebraElement.__init__(self, parent) + + def __reduce__(self): + """ + TESTS:: + + sage: R = LaurentPolynomialRing(QQ, 2, 'x') + sage: R. = LaurentPolynomialRing(QQ) + sage: loads(dumps(x1)) == x1 # indirect doctest + True + sage: z = x1/x2 + sage: loads(dumps(z)) == z + True + """ + return self._parent, (self._poly, self._mon) + + def __hash__(self): + r""" + TESTS: + + Test that the hash is non-constant (see also :trac:`27914`):: + + sage: L. = LaurentPolynomialRing(QQ) + sage: len({hash(w^i*z^j) for i in [-2..2] for j in [-2..2]}) + 25 + + Check that :trac:`20490` is fixed:: + + sage: R. = LaurentPolynomialRing(ZZ) + sage: p = a*~a + sage: p._fraction_pair() + (a, a) + sage: p == R.one() + True + sage: hash(p) + 1 + + Check that :trac:`23864` is fixed (compatibility with integers, rationals + and polynomial rings):: + + sage: L = LaurentPolynomialRing(QQ, 'x0,x1,x2') + sage: hash(L.zero()) + 0 + sage: hash(L.one()) + 1 + sage: hash(-L.one()) + -2 + sage: hash(L(1/2)) == hash(1/2) + True + + sage: R = PolynomialRing(QQ, 'x0,x1,x2') + sage: x0,x1,x2 = R.gens() + sage: hash(x0) == hash(L(x0)) + True + sage: hash(1 - 7*x0 + x1*x2) == hash(L(1 - 7*x0 + x1*x2)) + True + + Check that :trac:`27914` is fixed:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: Lw = LaurentPolynomialRing(QQ, 'w') + sage: Lz = LaurentPolynomialRing(QQ, 'z') + sage: all(hash(w^k) == hash(Lw(w^k)) + ....: and hash(z^k) == hash(Lz(z^k)) for k in (-5..5)) + True + sage: p = w^-1 + 2 + w + sage: hash(p) == hash(Lw(p)) + True + """ + # we reimplement the hash from multipolynomial to handle negative exponents + # (see multi_polynomial.pyx) + cdef long result = 0 + cdef long exponent + cdef list var_name_hash = [hash(v) for v in self._parent.variable_names()] + cdef int p + cdef int n = len(var_name_hash) + cdef long c_hash + for m, c in self._poly.iterator_exp_coeff(): + c_hash = hash(c) + if c_hash != 0: + for p in range(n): + exponent = m[p] + self._mon[p] + if exponent > 0: + c_hash = (1000003 * c_hash) ^ var_name_hash[p] + c_hash = (1000003 * c_hash) ^ exponent + elif exponent < 0: + c_hash = (1000003 * c_hash) ^ var_name_hash[p] + c_hash = (700005 * c_hash) ^ exponent + result += c_hash + + return result + + def _im_gens_(self, codomain, im_gens, base_map=None): + """ + Return the image of ``self`` under the morphism defined by + ``im_gens`` in ``codomain``. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(ZZ) + sage: M. = LaurentPolynomialRing(ZZ) + sage: phi = L.hom([u,v]) + sage: phi(x^2*~y -5*y**3) # indirect doctest + -5*v^3 + u^2*v^-1 + + TESTS: + + check compatibility with :trac:`26105`:: + + sage: F. = GF(4) # optional - sage.rings.finite_rings + sage: LF. = LaurentPolynomialRing(F) # optional - sage.rings.finite_rings + sage: rho = LF.hom([b,a], base_map=F.frobenius_endomorphism()) # optional - sage.rings.finite_rings + sage: s = t*~a + b +~t*(b**-3)*a**2; rs = rho(s); rs # optional - sage.rings.finite_rings + a + (t + 1)*b^-1 + t*a^-3*b^2 + sage: s == rho(rs) # optional - sage.rings.finite_rings + True + """ + p = self._poly + m = self._mon + if base_map is not None: + p = p.map_coefficients(base_map) + from sage.misc.misc_c import prod + return codomain(p(im_gens) * prod(ig**m[im_gens.index(ig)] for ig in im_gens)) + + cdef _normalize(self, i=None): + r""" + Remove the common monomials from ``self._poly`` and store + them in ``self._mon``. + + INPUT: + + - ``i`` -- an integer + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = x*y + 2*y*x^2 + y # indirect doctest + sage: f.factor() # Notice the y has been factored out. + (y) * (2*x^2 + x + 1) + + Check that :trac:`23864` has been fixed:: + + sage: hash(L.zero()) + 0 + """ + if not self._poly: + self._mon = ETuple({}, int(self._parent.ngens())) + return + + #cdef dict D = self._poly._mpoly_dict_recursive( + # self._parent.variable_names(), + # self._parent.base_ring() + # ) + cdef dict D = self._poly.dict() + + cdef ETuple e + if i is None: + e = None + for k in D: + if e is None: + e = k + else: + e = e.emin(k) + if not e.is_constant(): + self._poly = (self._poly // self._poly._parent({e: 1})) + self._mon = self._mon.eadd(e) + else: + e = None + for k in D: + if e is None or k[i] < e: + e = k[i] + if e > 0: + self._poly = (self._poly // self._poly._parent.gen(i)) + self._mon = self._mon.eadd_p(e, i) + + cdef _compute_polydict(self): + """ + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: a = w^2*z^-1 +3 + sage: a.dict() # indirect doctest + {(0, 0): 3, (2, -1): 1} + """ + #cdef dict D = self._poly._mpoly_dict_recursive(self._parent.variable_names(), + # self._parent.base_ring()) + cdef dict D = self._poly.dict() + cdef dict DD + if self._mon.is_constant(): + self._prod = PolyDict(D) + return + DD = {} + for k in D: + DD[k.eadd(self._mon)] = D[k] + self._prod = PolyDict(DD) + + def is_unit(self): + """ + Return ``True`` if ``self`` is a unit. + + The ground ring is assumed to be an integral domain. + + This means that the Laurent polynomial is a monomial + with unit coefficient. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: (x*y/2).is_unit() + True + sage: (x + y).is_unit() + False + sage: (L.zero()).is_unit() + False + sage: (L.one()).is_unit() + True + + sage: L. = LaurentPolynomialRing(ZZ) + sage: (2*x*y).is_unit() + False + """ + coeffs = self.coefficients() + if len(coeffs) != 1: + return False + return coeffs[0].is_unit() + + def _repr_(self): + """ + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = x^2 + x*y/2 + 2*y^-1 + sage: f._repr_() + 'x^2 + 1/2*x*y + 2*y^-1' + """ + if self._prod is None: + self._compute_polydict() + try: + key = self.parent().term_order().sortkey + except AttributeError: + key = None + atomic = self.parent().base_ring()._repr_option('element_is_atomic') + return self._prod.poly_repr(self.parent().variable_names(), + atomic_coefficients=atomic, sortkey=key) + + def _latex_(self): + r""" + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: a = w^2*z^-1+3; a + w^2*z^-1 + 3 + sage: latex(a) + w^{2} z^{-1} + 3 + + TESTS:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: latex(1/lambda2 + y2^(-3)) + \lambda_{2}^{-1} + y_{2}^{-3} + """ + if self._prod is None: + self._compute_polydict() + try: + key = self.parent().term_order().sortkey + except AttributeError: + key = None + atomic = self.parent().base_ring()._repr_option('element_is_atomic') + return self._prod.latex(self.parent().latex_variable_names(), + atomic_coefficients=atomic, sortkey=key) + + cpdef long number_of_terms(self) except -1: + """ + Return the number of non-zero coefficients of ``self``. + + Also called weight, hamming weight or sparsity. + + EXAMPLES:: + + sage: R. = LaurentPolynomialRing(ZZ) + sage: f = x^3 - y + sage: f.number_of_terms() + 2 + sage: R(0).number_of_terms() + 0 + sage: f = (x+1/y)^100 + sage: f.number_of_terms() + 101 + + The method :meth:`hamming_weight` is an alias:: + + sage: f.hamming_weight() + 101 + """ + return self._poly.number_of_terms() + + def __invert__(LaurentPolynomial_mpair self): + """ + Return the inverse of ``self``. + + This treats monomials specially so they remain Laurent + polynomials; the inverse of any other polynomial is an element + of the rational function field. + + TESTS:: + + sage: L. = LaurentPolynomialRing(ZZ) + sage: f = ~x + sage: parent(f) + Multivariate Laurent Polynomial Ring in x, y over Integer Ring + sage: parent(f.coefficients()[0]) is parent(f).base_ring() + True + sage: g = ~(2*x) + sage: parent(g) + Multivariate Laurent Polynomial Ring in x, y over Rational Field + sage: parent(g.coefficients()[0]) is parent(g).base_ring() + True + """ + cdef ETuple e + if self._poly.is_term(): + (e, c), = self.dict().items() + e = e.emul(-1) + P = self._parent + try: + c = c.inverse_of_unit() + except (AttributeError, ZeroDivisionError, ArithmeticError): + c = ~c + if c.parent() is not P.base_ring(): + P = P.change_ring(c.parent()) + return P({e: c}) + return super().__invert__() + + def __pow__(LaurentPolynomial_mpair self, n, m): + """ + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = x + y + sage: f^2 + x^2 + 2*x*y + y^2 + sage: f^(-1) + 1/(x + y) + + TESTS: + + Check that :trac:`2952` is fixed:: + + sage: R. = QQ[] + sage: L. = LaurentPolynomialRing(R) + sage: f = (x+y+z^-1)^2 + sage: f.substitute(z=1) + x^2 + 2*x*y + y^2 + 2*x + 2*y + 1 + """ + cdef LaurentPolynomial_mpair ans + if n < 0: + return ~(self ** -n) + ans = self._new_c() + ans._poly = self._poly ** n + ans._mon = self._mon.emul(n) + return ans + + def __getitem__(self, n): + r""" + Return the coefficient of `x^n = x_1^{n_1} \cdots x_k^{n_k}` where + `n` is a tuple of length `k` and `k` is the number of variables. + + If the number of inputs is not equal to the number of variables, this + raises a ``TypeError``. + + EXAMPLES:: + + sage: P. = LaurentPolynomialRing(QQ) + sage: f = (y^2 - x^9 - 7*x*y^3 + 5*x*y)*x^-3 + x*z; f + -x^6 + x*z - 7*x^-2*y^3 + 5*x^-2*y + x^-3*y^2 + sage: f[6,0,0] + -1 + sage: f[-2,3,0] + -7 + sage: f[-1,4,2] + 0 + sage: f[1,0,1] + 1 + sage: f[6] + Traceback (most recent call last): + ... + TypeError: must have exactly 3 inputs + sage: f[6,0] + Traceback (most recent call last): + ... + TypeError: must have exactly 3 inputs + sage: f[6,0,0,0] + Traceback (most recent call last): + ... + TypeError: must have exactly 3 inputs + """ + if isinstance(n, slice): + raise TypeError("multivariate Laurent polynomials are not iterable") + if not isinstance(n, tuple) or len(n) != self._parent.ngens(): + raise TypeError("must have exactly %s inputs" % + self.parent().ngens()) + cdef ETuple t = ETuple(n) + if self._prod is None: + self._compute_polydict() + try: + return self._prod[t] + except KeyError: + return self._parent.base_ring().zero() + + def __iter__(self): + """ + Iterate through all terms by returning a list of the coefficient and + the corresponding monomial. + + EXAMPLES:: + + sage: P. = LaurentPolynomialRing(QQ) + sage: f = (y^2 - x^9 - 7*x*y^3 + 5*x*y)*x^-3 + sage: sorted(f) # indirect doctest + [(-7, x^-2*y^3), (-1, x^6), (1, x^-3*y^2), (5, x^-2*y)] + """ + P = self._parent + one = P._R.one() + if self._mon.is_constant(): + for exp, coeff in self._poly.iterator_exp_coeff(): + yield (coeff, P.element_class(P, one, exp)) + else: + for exp, coeff in self._poly.iterator_exp_coeff(): + yield (coeff, P.element_class(P, one, exp.eadd(self._mon))) + + def iterator_exp_coeff(self): + """ + Iterate over ``self`` as pairs of (ETuple, coefficient). + + EXAMPLES:: + + sage: P. = LaurentPolynomialRing(QQ) + sage: f = (y^2 - x^9 - 7*x*y^3 + 5*x*y)*x^-3 + sage: list(f.iterator_exp_coeff()) + [((6, 0), -1), ((-2, 3), -7), ((-2, 1), 5), ((-3, 2), 1)] + """ + for exp, coeff in self._poly.iterator_exp_coeff(): + yield (exp.eadd(self._mon), coeff) + + def monomials(self): + """ + Return the list of monomials in ``self``. + + EXAMPLES:: + + sage: P. = LaurentPolynomialRing(QQ) + sage: f = (y^2 - x^9 - 7*x*y^3 + 5*x*y)*x^-3 + sage: sorted(f.monomials()) + [x^-3*y^2, x^-2*y, x^-2*y^3, x^6] + """ + return [mon for coeff, mon in self] + + def monomial_coefficient(self, mon): + """ + Return the coefficient in the base ring of the monomial ``mon`` in + ``self``, where ``mon`` must have the same parent as ``self``. + + This function contrasts with the function :meth:`coefficient()` + which returns the coefficient of a monomial viewing this + polynomial in a polynomial ring over a base ring having fewer + variables. + + INPUT: + + - ``mon`` -- a monomial + + .. SEEALSO:: + + For coefficients in a base ring of fewer variables, see + :meth:`coefficient()`. + + EXAMPLES:: + + sage: P. = LaurentPolynomialRing(QQ) + sage: f = (y^2 - x^9 - 7*x*y^3 + 5*x*y)*x^-3 + sage: f.monomial_coefficient(x^-2*y^3) + -7 + sage: f.monomial_coefficient(x^2) + 0 + + TESTS:: + + sage: P. = LaurentPolynomialRing(QQ) + sage: f = y^2 * x^-2 + sage: f.monomial_coefficient(x + y) + Traceback (most recent call last): + ... + ValueError: not a monomial + """ + if parent(mon) != self._parent: + raise TypeError("input must have the same parent") + cdef LaurentPolynomial_mpair m = mon + if m._prod is None: + m._compute_polydict() + if self._prod is None: + self._compute_polydict() + exp = monomial_exponent(m._prod) + zero = self._parent.base_ring().zero() + return self._prod.get(exp, zero) + + def constant_coefficient(self): + """ + Return the constant coefficient of ``self``. + + EXAMPLES:: + + sage: P. = LaurentPolynomialRing(QQ) + sage: f = (y^2 - x^9 - 7*x*y^2 + 5*x*y)*x^-3; f + -x^6 - 7*x^-2*y^2 + 5*x^-2*y + x^-3*y^2 + sage: f.constant_coefficient() + 0 + sage: f = (x^3 + 2*x^-2*y+y^3)*y^-3; f + x^3*y^-3 + 1 + 2*x^-2*y^-2 + sage: f.constant_coefficient() + 1 + """ + return self[(0,)*self._parent.ngens()] + + def coefficient(self, mon): + r""" + Return the coefficient of ``mon`` in ``self``, where ``mon`` must + have the same parent as ``self``. + + The coefficient is defined as follows. If `f` is this polynomial, then + the coefficient `c_m` is sum: + + .. MATH:: + + c_m := \sum_T \frac{T}{m} + + where the sum is over terms `T` in `f` that are exactly divisible + by `m`. + + A monomial `m(x,y)` 'exactly divides' `f(x,y)` if `m(x,y) | f(x,y)` + and neither `x \cdot m(x,y)` nor `y \cdot m(x,y)` divides `f(x,y)`. + + INPUT: + + - ``mon`` -- a monomial + + OUTPUT: + + Element of the parent of ``self``. + + .. NOTE:: + + To get the constant coefficient, call + :meth:`constant_coefficient()`. + + EXAMPLES:: + + sage: P. = LaurentPolynomialRing(QQ) + + The coefficient returned is an element of the parent of ``self``; in + this case, ``P``. :: + + sage: f = 2 * x * y + sage: c = f.coefficient(x*y); c + 2 + sage: c.parent() + Multivariate Laurent Polynomial Ring in x, y over Rational Field + + sage: P. = LaurentPolynomialRing(QQ) + sage: f = (y^2 - x^9 - 7*x*y^2 + 5*x*y)*x^-3; f + -x^6 - 7*x^-2*y^2 + 5*x^-2*y + x^-3*y^2 + sage: f.coefficient(y) + 5*x^-2 + sage: f.coefficient(y^2) + -7*x^-2 + x^-3 + sage: f.coefficient(x*y) + 0 + sage: f.coefficient(x^-2) + -7*y^2 + 5*y + sage: f.coefficient(x^-2*y^2) + -7 + sage: f.coefficient(1) + -x^6 - 7*x^-2*y^2 + 5*x^-2*y + x^-3*y^2 + """ + if mon.parent() is not self._parent: + mon = self._parent(mon) + cdef LaurentPolynomial_mpair m = mon + if self._prod is None: + self._compute_polydict() + if m._prod is None: + m._compute_polydict() + return self._parent(self._prod.coefficient(m.dict())) + + def coefficients(self): + """ + Return the nonzero coefficients of ``self`` in a list. + + The returned list is decreasingly ordered by the term ordering + of ``self.parent()``. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ, order='degrevlex') + sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 + sage: f.coefficients() + [4, 3, 2, 1] + sage: L. = LaurentPolynomialRing(QQ,order='lex') + sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 + sage: f.coefficients() + [4, 1, 2, 3] + """ + return self._poly.coefficients() + + def variables(self, sort=True): + """ + Return a tuple of all variables occurring in ``self``. + + INPUT: + + - ``sort`` -- specifies whether the indices shall be sorted + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 + sage: f.variables() + (z, y, x) + sage: f.variables(sort=False) #random + (y, z, x) + """ + cdef dict d = self.dict() + cdef tuple g = self._parent.gens() + cdef Py_ssize_t nvars = len(g) + cdef set vars = set() + for k in d: + vars.update(k.nonzero_positions()) + if len(vars) == nvars: + break + cdef list v = [g[i] for i in vars] + if sort: + v.sort() + return tuple(v) + + cpdef dict dict(self): + """ + Return ``self`` represented as a ``dict``. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 + sage: sorted(f.dict().items()) + [((3, 1, 0), 3), ((4, 0, -2), 2), ((6, -7, 0), 1), ((7, 0, -1), 4)] + """ + if self._prod is None: + self._compute_polydict() + return self._prod.dict() + + def _fraction_pair(self): + """ + Return one representation of ``self`` as a pair + ``(numerator, denominator)``. + + Here both the numerator and the denominator are polynomials. + + This is used for coercion into the fraction field. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 + sage: f._fraction_pair() + (4*x^7*y^7*z + 3*x^3*y^8*z^2 + 2*x^4*y^7 + x^6*z^2, y^7*z^2) + """ + ring = self._parent._R + numer = self._poly + denom = ring.one() + var = ring.gens() + for i, j in enumerate(self._mon): + if j > 0: + numer *= var[i] ** j + else: + denom *= var[i] ** (-j) + return (numer, denom) + + cpdef _add_(self, _right): + """ + Return the Laurent polynomial ``self + right``. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = x + y^-1 + sage: g = y + z + sage: f + g + x + y + z + y^-1 + """ + cdef LaurentPolynomial_mpair ans = self._new_c() + cdef LaurentPolynomial_mpair right = _right + ans._mon, a, b = self._mon.combine_to_positives(right._mon) + if not a.is_constant(): + ans._poly = self._poly * self._poly._parent({a: 1}) + else: + ans._poly = self._poly + if not b.is_constant(): + ans._poly += right._poly * self._poly._parent({b: 1}) + else: + ans._poly += right._poly + return ans + + cpdef _sub_(self, _right): + """ + Return the Laurent polynomial ``self - right``. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = x + y^-1 + sage: g = y + z + x + sage: f - g + -y - z + y^-1 + """ + cdef LaurentPolynomial_mpair ans = self._new_c() + cdef LaurentPolynomial_mpair right = _right + cdef ETuple a, b + ans._mon, a, b = self._mon.combine_to_positives(right._mon) + if not a.is_constant(): + ans._poly = self._poly * self._poly._parent({a: 1}) + else: + ans._poly = self._poly + if not b.is_constant(): + ans._poly -= right._poly * self._poly._parent({b: 1}) + else: + ans._poly -= right._poly + return ans + + cpdef _div_(self, rhs): + """ + Return the division of ``self`` by ``rhs``. + + If the denominator is not a unit, + the result will be given in the fraction field. + + EXAMPLES:: + + sage: R. = LaurentPolynomialRing(QQ) + sage: 1/s + s^-1 + sage: 1/(s*q) + s^-1*q^-1 + sage: 1/(s+q) + 1/(s + q) + sage: (1/(s+q)).parent() + Fraction Field of Multivariate Polynomial Ring in s, q, t over Rational Field + sage: (1/(s*q)).parent() + Multivariate Laurent Polynomial Ring in s, q, t over Rational Field + sage: (s+q)/(q^2*t^(-2)) + s*q^-2*t^2 + q^-1*t^2 + """ + cdef LaurentPolynomial_mpair right = rhs + if right.is_zero(): + raise ZeroDivisionError + if right._poly.is_term(): + return self * ~right + else: + return RingElement._div_(self, rhs) + + def is_monomial(self): + """ + Return ``True`` if ``self`` is a monomial. + + EXAMPLES:: + + sage: k. = LaurentPolynomialRing(QQ) + sage: z.is_monomial() + True + sage: k(1).is_monomial() + True + sage: (z+1).is_monomial() + False + sage: (z^-2909).is_monomial() + True + sage: (38*z^-2909).is_monomial() + False + """ + return self._poly.is_monomial() + + cpdef _neg_(self): + """ + Return ``-self``. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = x + y^-1 + sage: -f + -x - y^-1 + """ + cdef LaurentPolynomial_mpair ans = self._new_c() + ans._mon = self._mon + ans._poly = -self._poly + return ans + + cpdef _lmul_(self, Element right): + """ + Return ``self * right`` where ``right`` is in ``self``'s base ring. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = x + y^-1 + sage: f*(1/2) + 1/2*x + 1/2*y^-1 + """ + cdef LaurentPolynomial_mpair ans = self._new_c() + ans._mon = self._mon + ans._poly = self._poly * right + return ans + + cpdef _rmul_(self, Element left): + """ + Return ``left * self`` where ``left`` is in ``self``'s base ring. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = x + y^-1 + sage: (1/2)*f + 1/2*x + 1/2*y^-1 + """ + cdef LaurentPolynomial_mpair ans = self._new_c() + ans._mon = self._mon + ans._poly = left * self._poly + return ans + + cpdef _mul_(self, right): + """ + Return ``self * right``. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = x + y^-1 + sage: g = y + z + sage: f*g + x*y + x*z + 1 + y^-1*z + """ + cdef LaurentPolynomial_mpair ans = self._new_c() + ans._mon = self._mon.eadd((right)._mon) + ans._poly = self._poly * (right)._poly + return ans + + cpdef _floordiv_(self, right): + """ + Perform division with remainder and return the quotient. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = x^3 + y^-3 + sage: g = y + x + sage: f // g + x^5*y^-3 - x^4*y^-2 + x^3*y^-1 + + sage: h = x + y^(-1) + sage: f // h + x^2 - x*y^-1 + y^-2 + sage: h * (f // h) == f + True + sage: f // 1 + x^3 + y^-3 + sage: 1 // f + 0 + + TESTS: + + Check that :trac:`19357` is fixed:: + + sage: x // y + x*y^-1 + + Check that :trac:`21999` is fixed:: + + sage: L. = LaurentPolynomialRing(QQbar) + sage: (a+a*b) // a + b + 1 + """ + cdef LaurentPolynomial_mpair ans = self._new_c() + cdef LaurentPolynomial_mpair rightl = right + self._normalize() + rightl._normalize() + ans._mon = self._mon.esub(rightl._mon) + ans._poly = self._poly // rightl._poly + return ans + + @coerce_binop + def quo_rem(self, right): + """ + Divide this Laurent polynomial by ``right`` and return a quotient and + a remainder. + + INPUT: + + - ``right`` -- a Laurent polynomial + + OUTPUT: + + A pair of Laurent polynomials. + + EXAMPLES:: + + sage: R. = LaurentPolynomialRing(QQ) + sage: (s^2 - t^2).quo_rem(s - t) + (s + t, 0) + sage: (s^-2 - t^2).quo_rem(s - t) + (s + t, -s^2 + s^-2) + sage: (s^-2 - t^2).quo_rem(s^-1 - t) + (t + s^-1, 0) + + TESTS: + + Verify that :trac:`31257` is fixed:: + + sage: R. = LaurentPolynomialRing(QQ) + sage: q, r = (1/x).quo_rem(y) + sage: q, r + (x^-1*y^-1, 0) + sage: q*y + r == 1/x + True + sage: q,r = (x^-2 - y^2).quo_rem(x - y) + sage: q*(x - y) + r == x^-2 - y^2 + True + """ + # make copies of self and right so that the input can be normalized + # without affecting the objects that were passed to the method + cdef LaurentPolynomial_mpair selfl = self._new_c() + selfl._poly = self._poly + selfl._mon = self._mon + cdef LaurentPolynomial_mpair rightl = self._new_c() + rightl._poly = ( right)._poly + rightl._mon = ( right)._mon + + selfl._normalize() + rightl._normalize() + q, r = selfl._poly.quo_rem(rightl._poly) + ql = LaurentPolynomial_mpair(self._parent, q, + mon=selfl._mon.esub(rightl._mon)) + rl = LaurentPolynomial_mpair(self._parent, r, + mon=selfl._mon) + ql._normalize() + rl._normalize() + return (ql, rl) + + cpdef _richcmp_(self, right, int op): + """ + Compare two polynomials in a `LaurentPolynomialRing` based on the term + order from the parent ring. If the parent ring does not specify a term + order then only comparison by equality is supported. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = x + y^-1 + sage: g = y + z + sage: f == f + True + sage: f == g + False + sage: f == 2 + False + """ + if self._prod is None: + self._compute_polydict() + if ( right)._prod is None: + ( right)._compute_polydict() + + try: + sortkey = self._parent.term_order().sortkey + except AttributeError: + sortkey = None + + return self._prod.rich_compare((right)._prod, + op, sortkey) + + def exponents(self): + """ + Return a list of the exponents of ``self``. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: a = w^2*z^-1 + 3; a + w^2*z^-1 + 3 + sage: e = a.exponents() + sage: e.sort(); e + [(0, 0), (2, -1)] + + """ + return [a.eadd(self._mon) for a in self._poly.exponents()] + + def degree(self, x=None): + """ + Return the degree of ``x`` in ``self``. + + EXAMPLES:: + + sage: R. = LaurentPolynomialRing(QQ) + sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 + sage: f.degree(x) + 7 + sage: f.degree(y) + 1 + sage: f.degree(z) + 0 + """ + if not x: + return self._poly.total_degree() + sum(self._mon) + + cdef tuple g = self._parent.gens() + cdef Py_ssize_t i + cdef bint no_generator_found = True + for i in range(len(g)): + if g[i] is x: + no_generator_found = False + break + if no_generator_found: + raise TypeError("x must be a generator of parent") + return self._poly.degree(self._parent._R.gens()[i]) + self._mon[i] + + def has_inverse_of(self, i): + """ + INPUT: + + - ``i`` -- The index of a generator of ``self.parent()`` + + OUTPUT: + + Return ``True`` if ``self`` contains a monomial including the inverse of + ``self.parent().gen(i)``, ``False`` otherwise. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 + sage: f.has_inverse_of(0) + False + sage: f.has_inverse_of(1) + True + sage: f.has_inverse_of(2) + True + """ + if (not isinstance(i, (int, Integer))) or (i < 0) or (i >= self._parent.ngens()): + raise TypeError("argument is not the index of a generator") + if self._mon[i] < 0: + self._normalize(i) + if self._mon[i] < 0: + return True + return False + return False + + def has_any_inverse(self): + """ + Return ``True`` if ``self`` contains any monomials with a negative exponent, False otherwise. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 + sage: f.has_any_inverse() + True + sage: g = x^2 + y^2 + sage: g.has_any_inverse() + False + """ + for m in self._mon.nonzero_values(sort=False): + if m < 0: + return True + return False + + def __call__(self, *x, **kwds): + """ + Compute value of ``self`` at ``x``. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = x + 2*y + 3*z + sage: f(1,1,1) + 6 + sage: f = x^-1 + y + z + sage: f(0,1,1) + Traceback (most recent call last): + ... + ZeroDivisionError + + TESTS:: + + sage: f = x + 2*y + 3*z + sage: f(2) + Traceback (most recent call last): + ... + TypeError: number of arguments does not match the number of generators in parent + sage: f(2,0) + Traceback (most recent call last): + ... + TypeError: number of arguments does not match the number of generators in parent + sage: f( (1,1,1) ) + 6 + """ + if kwds: + f = self.subs(**kwds) + if x: # More than 1 non-keyword argument + return f(*x) + else: + return f + + cdef int l = len(x) + + if l == 1 and isinstance(x[0], (tuple, list)): + x = x[0] + l = len(x) + + if l != self._parent.ngens(): + raise TypeError("number of arguments does not match the number" + " of generators in parent") + + #Check to make sure that we aren't dividing by zero + cdef Py_ssize_t m + for m in range(l): + if x[m] == 0: + if self.has_inverse_of(m): + raise ZeroDivisionError + + ans = self._poly(*x) + if ans: + for m in self._mon.nonzero_positions(): + ans *= x[m]**self._mon[m] + + return ans + + def subs(self, in_dict=None, **kwds): + """ + Substitute some variables in this Laurent polynomial. + + Variable/value pairs for the substitution may be given + as a dictionary or via keyword-value pairs. If both are + present, the latter take precedence. + + INPUT: + + - ``in_dict`` -- dictionary (optional) + + - ``**kwds`` -- keyword arguments + + OUTPUT: + + A Laurent polynomial. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = x + 2*y + 3*z + sage: f.subs(x=1) + 2*y + 3*z + 1 + sage: f.subs(y=1) + x + 3*z + 2 + sage: f.subs(z=1) + x + 2*y + 3 + sage: f.subs(x=1, y=1, z=1) + 6 + + sage: f = x^-1 + sage: f.subs(x=2) + 1/2 + sage: f.subs({x: 2}) + 1/2 + + sage: f = x + 2*y + 3*z + sage: f.subs({x: 1, y: 1, z: 1}) + 6 + sage: f.substitute(x=1, y=1, z=1) + 6 + + TESTS:: + + sage: f = x + 2*y + 3*z + sage: f(q=10) + x + 2*y + 3*z + + sage: x.subs({x: 2}, x=1) + 1 + """ + cdef list variables = list(self._parent.gens()) + cdef Py_ssize_t i + for i in range(len(variables)): + if str(variables[i]) in kwds: + variables[i] = kwds[str(variables[i])] + elif in_dict and variables[i] in in_dict: + variables[i] = in_dict[variables[i]] + return self(tuple(variables)) + + def is_constant(self): + r""" + Return whether this Laurent polynomial is constant. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: L(0).is_constant() + True + sage: L(42).is_constant() + True + sage: a.is_constant() + False + sage: (1/b).is_constant() + False + """ + return (self._mon == ETuple({}, int(self._parent.ngens())) and + self._poly.is_constant()) + + def _symbolic_(self, R): + """ + EXAMPLES:: + + sage: R. = LaurentPolynomialRing(QQ) + sage: f = x^3 + y/x + sage: g = f._symbolic_(SR); g # optional - sage.symbolic + (x^4 + y)/x + sage: g(x=2, y=2) # optional - sage.symbolic + 9 + + sage: g = SR(f) # optional - sage.symbolic + sage: g(x=2, y=2) # optional - sage.symbolic + 9 + """ + d = {repr(g): R.var(g) for g in self._parent.gens()} + return self.subs(**d) + + def derivative(self, *args): + r""" + The formal derivative of this Laurent polynomial, with respect + to variables supplied in args. + + Multiple variables and iteration counts may be supplied; see + documentation for the global :func:`derivative` function for more + details. + + .. SEEALSO:: + + :meth:`_derivative` + + EXAMPLES:: + + sage: R = LaurentPolynomialRing(ZZ,'x, y') + sage: x, y = R.gens() + sage: t = x**4*y + x*y + y + x**(-1) + y**(-3) + sage: t.derivative(x, x) + 12*x^2*y + 2*x^-3 + sage: t.derivative(y, 2) + 12*y^-5 + """ + return multi_derivative(self, args) + + # add .diff(), .differentiate() as aliases for .derivative() + diff = differentiate = derivative + + def _derivative(self, var=None): + """ + Compute formal derivative of this Laurent polynomial with + respect to the given variable. + + If ``var`` is among the generators of this ring, the derivative + is with respect to the generator. Otherwise, ``_derivative(var)`` is called + recursively for each coefficient of this polynomial. + + .. SEEALSO:: :meth:`derivative` + + EXAMPLES:: + + sage: R = LaurentPolynomialRing(ZZ,'x, y') + sage: x, y = R.gens() + sage: t = x**4*y+x*y+y+x**(-1)+y**(-3) + sage: t._derivative(x) + 4*x^3*y + y - x^-2 + sage: t._derivative(y) + x^4 + x + 1 - 3*y^-4 + + sage: R = LaurentPolynomialRing(QQ['z'],'x') + sage: z = R.base_ring().gen() + sage: x = R.gen() + sage: t = 33*z*x**4+x**(-1) + sage: t._derivative(z) + 33*x^4 + sage: t._derivative(x) + -x^-2 + 132*z*x^3 + """ + if var is None: + raise ValueError("must specify which variable to differentiate " + "with respect to") + P = self._parent + cdef list gens = list(P.gens()) + + # check if var is one of the generators + try: + index = gens.index(var) + except ValueError: + # call _derivative() recursively on coefficients + return P({m: c._derivative(var) + for (m, c) in self.dict().iteritems()}) + + # compute formal derivative with respect to generator + cdef dict d = {} + for m, c in self.dict().iteritems(): + if m[index] != 0: + new_m = [u for u in m] + new_m[index] += -1 + d[ETuple(new_m)] = m[index] * c + return P(d) + + def is_univariate(self): + """ + Return ``True`` if this is a univariate or constant Laurent polynomial, + and ``False`` otherwise. + + EXAMPLES:: + + sage: R. = LaurentPolynomialRing(QQ) + sage: f = (x^3 + y^-3)*z + sage: f.is_univariate() + False + sage: g = f(1, y, 4) + sage: g.is_univariate() + True + sage: R(1).is_univariate() + True + """ + return len(self.variables()) < 2 + + def univariate_polynomial(self, R=None): + """ + Return a univariate polynomial associated to this + multivariate polynomial. + + INPUT: + + - ``R`` - (default: ``None``) a univariate Laurent polynomial ring + + If this polynomial is not in at most one variable, then a + :class:`ValueError` exception is raised. The new polynomial is over + the same base ring as the given :class:`LaurentPolynomial` and in the + variable ``x`` if no ring ``R`` is provided. + + EXAMPLES:: + + sage: R. = LaurentPolynomialRing(ZZ) + sage: f = 3*x^2 - 2*y^-1 + 7*x^2*y^2 + 5 + sage: f.univariate_polynomial() + Traceback (most recent call last): + ... + TypeError: polynomial must involve at most one variable + sage: g = f(10, y); g + 700*y^2 + 305 - 2*y^-1 + sage: h = g.univariate_polynomial(); h + -2*y^-1 + 305 + 700*y^2 + sage: h.parent() + Univariate Laurent Polynomial Ring in y over Integer Ring + sage: g.univariate_polynomial(LaurentPolynomialRing(QQ,'z')) + -2*z^-1 + 305 + 700*z^2 + + Here's an example with a constant multivariate polynomial:: + + sage: g = R(1) + sage: h = g.univariate_polynomial(); h + 1 + sage: h.parent() + Univariate Laurent Polynomial Ring in x over Integer Ring + """ + from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing + v = self.variables() + if len(v) > 1: + raise TypeError("polynomial must involve at most one variable") + elif len(v) == 1: + x = v[0] + i = self._parent.gens().index(x) + x = str(x) + else: + x = 'x' + i = 0 + + #construct ring if none + if R is None: + R = LaurentPolynomialRing(self.base_ring(), x) + + return R({m[i]: c for m,c in self.dict().iteritems()}) + + def factor(self): + """ + Return a Laurent monomial (the unit part of the factorization) and a factored multi-polynomial. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 + sage: f.factor() + (x^3*y^-7*z^-2) * (4*x^4*y^7*z + 3*y^8*z^2 + 2*x*y^7 + x^3*z^2) + + TESTS: + + Tests for :trac:`29173`:: + + sage: L. = LaurentPolynomialRing(ZZ, 'a, b') + sage: (a*b + a + b + 1).factor() + (b + 1) * (a + 1) + sage: ((a^-1)*(a*b + a + b + 1)).factor() + (a^-1) * (b + 1) * (a + 1) + sage: L(-12).factor() + -1 * 2^2 * 3 + """ + pf = self._poly.factor() + + if self._poly.degree() == 0: + # Factorization is broken for polynomials, see + # https://github.com/sagemath/sage/issues/20214 + return pf + + u = self.parent(pf.unit()) + + cdef tuple g = self._parent.gens() + for i in self._mon.nonzero_positions(): + u *= g[i] ** self._mon[i] + + cdef list f = [] + cdef dict d + for t in pf: + d = (t[0].dict()) + if len(d) == 1: # monomials are units + u *= self.parent(d) ** t[1] + else: + f.append((self.parent(d), t[1])) + + return Factorization(f, unit=u) + + def is_square(self, root=False): + r""" + Test whether this Laurent polynomial is a square. + + INPUT: + + - ``root`` - boolean (default ``False``) - if set to ``True`` + then return a pair ``(True, sqrt)`` with ``sqrt`` a square + root of this Laurent polynomial when it exists or + ``(False, None)``. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ) + sage: p = 1 + x*y + z^-3 + sage: (p**2).is_square() + True + sage: (p**2).is_square(root=True) + (True, x*y + 1 + z^-3) + + sage: x.is_square() + False + sage: x.is_square(root=True) + (False, None) + + sage: (x**-4 * (1 + z)).is_square(root=False) + False + sage: (x**-4 * (1 + z)).is_square(root=True) + (False, None) + """ + self._normalize() + if not self._mon.is_multiple_of(2): + return (False, None) if root else False + + cdef LaurentPolynomial_mpair ans + + if not root: + return self._poly.is_square(root=False) + else: + (pans, root) = self._poly.is_square(root=True) + if not pans: + return (False, None) + + mon = self._mon.escalar_div(2) + ans = self._new_c() + ans._mon = mon + ans._poly = root + return (True, ans) + + cpdef rescale_vars(self, dict d, h=None, new_ring=None): + r""" + Rescale variables in a Laurent polynomial. + + INPUT: + + - ``d`` -- a ``dict`` whose keys are the generator indices + and values are the coefficients; so a pair ``(i, v)`` + means `x_i \mapsto v x_i` + - ``h`` -- (optional) a map to be applied to coefficients + done after rescaling + - ``new_ring`` -- (optional) a new ring to map the result into + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ, 2) + sage: p = x^-2*y + x*y^-2 + sage: p.rescale_vars({0: 2, 1: 3}) + 2/9*x*y^-2 + 3/4*x^-2*y + sage: F = GF(2) # optional - sage.rings.finite_rings + sage: p.rescale_vars({0: 3, 1: 7}, new_ring=L.change_ring(F)) # optional - sage.rings.finite_rings + x*y^-2 + x^-2*y + + Test for :trac:`30331`:: + + sage: F. = CyclotomicField(3) # optional - sage.rings.number_field + sage: p.rescale_vars({0: 2, 1: z}, new_ring=L.change_ring(F)) # optional - sage.rings.number_field + 2*z*x*y^-2 + 1/4*z*x^-2*y + """ + cdef int i + cdef dict df + cdef ETuple v + cdef LaurentPolynomial_mpair ans + + if self._prod is None: + self._compute_polydict() + + df = dict(self._prod.__repn) # This makes a copy for us to manipulate + if new_ring is None: + R = self._parent._base + else: + R = new_ring._base + if h is None: + for v in df: + val = df[v] + for i in d: + val *= d[i]**v[i] + df[v] = val + else: + for v in df: + val = df[v] + for i in d: + val *= d[i]**v[i] + df[v] = R(h(val)) + + ans = self._new_c() + ans._prod = PolyDict(df) + ans._mon = self._mon + if new_ring is None: + S = self._poly._parent + else: + S = self._poly._parent.change_ring(R) + ans._poly = S({v.esub(ans._mon): df[v] for v in df}) + if new_ring is not None: + return new_ring(ans) + return ans + + cpdef toric_coordinate_change(self, M, h=None, new_ring=None): + r""" + Apply a matrix to the exponents in a Laurent polynomial. + + For efficiency, we implement this directly, rather than as a substitution. + + The optional argument ``h`` is a map to be applied to coefficients. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ, 2) + sage: p = 2*x^2 + y - x*y + sage: p.toric_coordinate_change(Matrix([[1,-3], [1,1]])) + 2*x^2*y^2 - x^-2*y^2 + x^-3*y + sage: F = GF(2) # optional - sage.rings.finite_rings + sage: p.toric_coordinate_change(Matrix([[1,-3], [1,1]]), # optional - sage.rings.finite_rings + ....: new_ring=L.change_ring(F)) + x^-2*y^2 + x^-3*y + + """ + cdef int n, i, j, x + cdef dict d, dr + cdef ETuple v + cdef LaurentPolynomial_mpair ans + cdef list L, mon, exp + cdef Matrix mat = M + + n = self._parent.ngens() + if mat.dimensions() != (n, n): + raise ValueError("the matrix M must be a {k} x {k} matrix".format(k=n)) + + if not self: + if new_ring is None: + return self._parent.zero() + else: + return new_ring.zero() + + if self._prod is None: + self._compute_polydict() + + d = self._prod.__repn + dr = {} + mon = [0] * n + for v in d: + # Make a copy of mon as this might be faster than creating the data from scratch. + # We will set every entry, so no need to clear the data. + exp = list(mon) + for j in range(n): + x = 0 + for i in range(n): + if not mat.get_is_zero_unsafe(j, i): + x += ( v[i]) * int(mat.get_unsafe(j, i)) + if x < ( mon[j]): + mon[j] = x + exp[j] = x + dr[ETuple(exp)] = d[v] + + if h is not None: + for v in dr: + dr[v] = self._parent._base(h(dr[v])) + + ans = self._new_c() + ans._prod = PolyDict(dr) + ans._mon = ETuple(mon) + ans._poly = self._poly._parent({v.esub(ans._mon): dr[v] for v in dr}) + if new_ring is not None: + return new_ring(ans) + return ans + + cpdef toric_substitute(self, v, v1, a, h=None, new_ring=None): + r""" + Perform a single-variable substitution up to a toric coordinate change. + + The optional argument ``h`` is a map to be applied to coefficients. + + EXAMPLES:: + + sage: L. = LaurentPolynomialRing(QQ, 2) + sage: p = x + y + sage: p.toric_substitute((2,3), (-1,1), 2) + 1/2*x^3*y^3 + 2*x^-2*y^-2 + sage: F = GF(5) + sage: p.toric_substitute((2,3), (-1,1), 2, new_ring=L.change_ring(F)) + 3*x^3*y^3 + 2*x^-2*y^-2 + + TESTS: + + Tests for :trac:`30331`:: + + sage: L. = LaurentPolynomialRing(QQ, 2) + sage: p = x + y + sage: F. = CyclotomicField(3) + sage: p.toric_substitute((2,3), (-1,1), z, new_ring=L.change_ring(F)) + (-z - 1)*x^3*y^3 + z*x^-2*y^-2 + + sage: P. = LaurentPolynomialRing(QQ, 1) + sage: u = x - 1 + sage: v = u.toric_substitute((-1,), (-1,), 1) + sage: v.is_zero() + True + """ + cdef dict d, dr + cdef ETuple ve, v1e, w, w1, mon + cdef LaurentPolynomial_mpair ans + cdef int t + + if self._prod is None: + self._compute_polydict() + + d = self._prod.__repn + dr = {} + ve = ETuple(v) + v1e = ETuple(v1) + mon = self._mon + if h is not None: + d = dict(d) # Make a copy so we can manipulate it + for w in d: + d[w] = h(d[w]) + for w in d: + x = d[w] + t = w.dotprod(v1e) + w1 = w.eadd_scaled(ve, -t) + if w1 in dr: + dr[w1] += x * a**t + else: + dr[w1] = x * a**t + mon = mon.emin(w1) + for v in tuple(dr.keys()): + if not dr[v]: + del dr[v] + + if new_ring is None: + S = self._poly._parent + else: + S = self._poly._parent.change_ring(new_ring._base) + ans = self._new_c() + ans._prod = PolyDict(dr) + ans._mon = mon + ans._poly = S({v.esub(ans._mon): dr[v] for v in dr}) + if new_ring is not None: + return new_ring(ans) + return ans diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index aaa1166b9d2..ece3c70c34f 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -20,7 +20,7 @@ sage: A. = QQ[] sage: R. = LaurentPolynomialRing(A) - sage: matrix(R,2,2,[X,0,0,1]) + sage: matrix(R,2,2,[X,0,0,1]) # optional - sage.modules [X 0] [0 1] @@ -42,15 +42,16 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.structure.element import parent -from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial_mpair, LaurentPolynomial_univariate +from sage.misc.lazy_import import LazyImport +from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial, LaurentPolynomial_univariate from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.structure.element import parent def is_LaurentPolynomialRing(R): """ - Returns True if and only if R is a Laurent polynomial ring. + Return ``True`` if and only if R is a Laurent polynomial ring. EXAMPLES:: @@ -63,8 +64,8 @@ def is_LaurentPolynomialRing(R): See https://github.com/sagemath/sage/issues/35229 for details. False - sage: R = LaurentPolynomialRing(QQ,3,'x') - sage: is_LaurentPolynomialRing(R) + sage: R = LaurentPolynomialRing(QQ,3,'x') # optional - sage.modules + sage: is_LaurentPolynomialRing(R) # optional - sage.modules True """ from sage.misc.superseded import deprecation @@ -88,7 +89,7 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): 3. ``LaurentPolynomialRing(base_ring, name, n, order='degrevlex')`` 4. ``LaurentPolynomialRing(base_ring, n, name, order='degrevlex')`` - The optional arguments sparse and order *must* be explicitly + The optional arguments ``sparse`` and ``order`` *must* be explicitly named, and the other arguments must be given positionally. INPUT: @@ -101,10 +102,10 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): - ``order`` -- string or :class:`~sage.rings.polynomial.term_order.TermOrder`, e.g., - - ``'degrevlex'`` (default) -- degree reverse lexicographic - - ``'lex'`` -- lexicographic - - ``'deglex'`` -- degree lexicographic - - ``TermOrder('deglex',3) + TermOrder('deglex',3)`` -- block ordering + - ``'degrevlex'`` (default) -- degree reverse lexicographic + - ``'lex'`` -- lexicographic + - ``'deglex'`` -- degree lexicographic + - ``TermOrder('deglex',3) + TermOrder('deglex',3)`` -- block ordering OUTPUT: @@ -120,9 +121,9 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): :: - sage: R. = LaurentPolynomialRing(QQ,2); R + sage: R. = LaurentPolynomialRing(QQ, 2); R # optional - sage.modules Multivariate Laurent Polynomial Ring in x, y over Rational Field - sage: f = x^2 - 2*y^-2 + sage: f = x^2 - 2*y^-2 # optional - sage.modules You can't just globally change the names of those variables. This is because objects all over Sage could have pointers to @@ -130,7 +131,7 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): :: - sage: R._assign_names(['z','w']) + sage: R._assign_names(['z','w']) # optional - sage.modules Traceback (most recent call last): ... ValueError: variable names cannot be changed after object creation. @@ -162,8 +163,9 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): sage: R. = LaurentPolynomialRing(QQ, sparse=True); R Univariate Laurent Polynomial Ring in abc over Rational Field - sage: R. = LaurentPolynomialRing(PolynomialRing(GF(7),'k')); R - Univariate Laurent Polynomial Ring in w over Univariate Polynomial Ring in k over Finite Field of size 7 + sage: R. = LaurentPolynomialRing(PolynomialRing(GF(7),'k')); R # optional - sage.rings.finite_rings + Univariate Laurent Polynomial Ring in w over + Univariate Polynomial Ring in k over Finite Field of size 7 Rings with different variables are different:: @@ -174,31 +176,31 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): :: - sage: R = LaurentPolynomialRing(QQ, 'a,b,c'); R + sage: R = LaurentPolynomialRing(QQ, 'a,b,c'); R # optional - sage.modules Multivariate Laurent Polynomial Ring in a, b, c over Rational Field - sage: S = LaurentPolynomialRing(QQ, ['a','b','c']); S + sage: S = LaurentPolynomialRing(QQ, ['a','b','c']); S # optional - sage.modules Multivariate Laurent Polynomial Ring in a, b, c over Rational Field - sage: T = LaurentPolynomialRing(QQ, ('a','b','c')); T + sage: T = LaurentPolynomialRing(QQ, ('a','b','c')); T # optional - sage.modules Multivariate Laurent Polynomial Ring in a, b, c over Rational Field All three rings are identical. :: - sage: (R is S) and (S is T) + sage: (R is S) and (S is T) # optional - sage.modules True There is a unique Laurent polynomial ring with each term order:: - sage: R = LaurentPolynomialRing(QQ, 'x,y,z', order='degrevlex'); R + sage: R = LaurentPolynomialRing(QQ, 'x,y,z', order='degrevlex'); R # optional - sage.modules Multivariate Laurent Polynomial Ring in x, y, z over Rational Field - sage: S = LaurentPolynomialRing(QQ, 'x,y,z', order='invlex'); S + sage: S = LaurentPolynomialRing(QQ, 'x,y,z', order='invlex'); S # optional - sage.modules Multivariate Laurent Polynomial Ring in x, y, z over Rational Field - sage: S is LaurentPolynomialRing(QQ, 'x,y,z', order='invlex') + sage: S is LaurentPolynomialRing(QQ, 'x,y,z', order='invlex') # optional - sage.modules True - sage: R == S + sage: R == S # optional - sage.modules False @@ -209,24 +211,27 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): :: - sage: LaurentPolynomialRing(QQ, 'x', 10) - Multivariate Laurent Polynomial Ring in x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 over Rational Field + sage: LaurentPolynomialRing(QQ, 'x', 10) # optional - sage.modules + Multivariate Laurent Polynomial Ring in x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 + over Rational Field - sage: LaurentPolynomialRing(GF(7), 'y', 5) - Multivariate Laurent Polynomial Ring in y0, y1, y2, y3, y4 over Finite Field of size 7 + sage: LaurentPolynomialRing(GF(7), 'y', 5) # optional - sage.modules sage.rings.finite_rings + Multivariate Laurent Polynomial Ring in y0, y1, y2, y3, y4 + over Finite Field of size 7 - sage: LaurentPolynomialRing(QQ, 'y', 3, sparse=True) + sage: LaurentPolynomialRing(QQ, 'y', 3, sparse=True) # optional - sage.modules Multivariate Laurent Polynomial Ring in y0, y1, y2 over Rational Field By calling the :meth:`~sage.structure.category_object.CategoryObject.inject_variables` method, all those variable names are available for interactive use:: - sage: R = LaurentPolynomialRing(GF(7),15,'w'); R - Multivariate Laurent Polynomial Ring in w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14 over Finite Field of size 7 - sage: R.inject_variables() + sage: R = LaurentPolynomialRing(GF(7), 15, 'w'); R # optional - sage.modules sage.rings.finite_rings + Multivariate Laurent Polynomial Ring in w0, w1, w2, w3, w4, w5, w6, w7, + w8, w9, w10, w11, w12, w13, w14 over Finite Field of size 7 + sage: R.inject_variables() # optional - sage.modules sage.rings.finite_rings Defining w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14 - sage: (w0 + 2*w8 + w13)^2 + sage: (w0 + 2*w8 + w13)^2 # optional - sage.modules sage.rings.finite_rings w0^2 + 4*w0*w8 + 4*w8^2 + 2*w0*w13 + 4*w8*w13 + w13^2 """ from sage.rings.polynomial.polynomial_ring import is_PolynomialRing @@ -349,12 +354,12 @@ def _split_laurent_polynomial_dict_(P, M, d): TESTS:: - sage: L. = LaurentPolynomialRing(ZZ) - sage: M = LaurentPolynomialRing(ZZ, 'c, d') - sage: N = LaurentPolynomialRing(M, 'a, b') - sage: M(c/d + 1/c) # indirect doctest + sage: L. = LaurentPolynomialRing(ZZ) # optional - sage.modules + sage: M = LaurentPolynomialRing(ZZ, 'c, d') # optional - sage.modules + sage: N = LaurentPolynomialRing(M, 'a, b') # optional - sage.modules + sage: M(c/d + 1/c) # indirect doctest # optional - sage.modules c*d^-1 + c^-1 - sage: N(a + b/c/d + 1/b) # indirect doctest + sage: N(a + b/c/d + 1/b) # indirect doctest # optional - sage.modules a + (c^-1*d^-1)*b + b^-1 """ vars_P = P.variable_names() @@ -406,10 +411,10 @@ def from_fraction_field(L, x): EXAMPLES:: sage: from sage.rings.polynomial.laurent_polynomial_ring import from_fraction_field - sage: L. = LaurentPolynomialRing(ZZ) - sage: F = L.fraction_field() - sage: xi = F(~x) - sage: from_fraction_field(L, xi) == ~x + sage: L. = LaurentPolynomialRing(ZZ) # optional - sage.modules + sage: F = L.fraction_field() # optional - sage.modules + sage: xi = F(~x) # optional - sage.modules + sage: from_fraction_field(L, xi) == ~x # optional - sage.modules True """ d = L(x.denominator()) @@ -476,22 +481,22 @@ def _element_constructor_(self, x): sage: U = LaurentPolynomialRing(QQ, 'a') sage: V = LaurentPolynomialRing(QQ, 'c') sage: L. = LaurentPolynomialRing(QQ) - sage: M = LaurentPolynomialRing(QQ, 'c, d') - sage: Mc, Md = M.gens() - sage: N = LaurentPolynomialRing(M, 'a, b') - sage: Na, Nb = N.gens() - sage: U(Na) + sage: M = LaurentPolynomialRing(QQ, 'c, d') # optional - sage.modules + sage: Mc, Md = M.gens() # optional - sage.modules + sage: N = LaurentPolynomialRing(M, 'a, b') # optional - sage.modules + sage: Na, Nb = N.gens() # optional - sage.modules + sage: U(Na) # optional - sage.modules a - sage: V(Mc) + sage: V(Mc) # optional - sage.modules c - sage: M(L(0)) + sage: M(L(0)) # optional - sage.modules 0 - sage: N(L(0)) + sage: N(L(0)) # optional - sage.modules 0 - sage: L(M(0)) + sage: L(M(0)) # optional - sage.modules 0 - sage: L(N(0)) + sage: L(N(0)) # optional - sage.modules 0 :: @@ -503,8 +508,8 @@ def _element_constructor_(self, x): sage: C. = LaurentPolynomialRing(B) sage: B(C(b)) b - sage: D. = LaurentPolynomialRing(B) - sage: B(D(b)) + sage: D. = LaurentPolynomialRing(B) # optional - sage.modules + sage: B(D(b)) # optional - sage.modules b TESTS: @@ -526,7 +531,7 @@ def _element_constructor_(self, x): if isinstance(x, Expression): return x.laurent_polynomial(ring=self) - elif isinstance(x, (LaurentPolynomial_univariate, LaurentPolynomial_mpair)): + elif isinstance(x, LaurentPolynomial): P = x.parent() if set(self.variable_names()) & set(P.variable_names()): if isinstance(x, LaurentPolynomial_univariate): @@ -573,11 +578,11 @@ def __init__(self, R): """ EXAMPLES:: - sage: L = LaurentPolynomialRing(QQ,2,'x') - sage: type(L) + sage: L = LaurentPolynomialRing(QQ,2,'x') # optional - sage.modules + sage: type(L) # optional - sage.modules - sage: L == loads(dumps(L)) + sage: L == loads(dumps(L)) # optional - sage.modules True """ if R.ngens() <= 0: @@ -586,15 +591,15 @@ def __init__(self, R): raise ValueError("base ring must be an integral domain") LaurentPolynomialRing_generic.__init__(self, R) - Element = LaurentPolynomial_mpair + Element = LazyImport('sage.rings.polynomial.laurent_polynomial_mpair', 'LaurentPolynomial_mpair') def _repr_(self): """ TESTS:: - sage: LaurentPolynomialRing(QQ,2,'x').__repr__() + sage: LaurentPolynomialRing(QQ,2,'x').__repr__() # optional - sage.modules 'Multivariate Laurent Polynomial Ring in x0, x1 over Rational Field' - sage: LaurentPolynomialRing(QQ,1,'x').__repr__() + sage: LaurentPolynomialRing(QQ,1,'x').__repr__() # optional - sage.modules 'Multivariate Laurent Polynomial Ring in x over Rational Field' """ return "Multivariate Laurent Polynomial Ring in %s over %s"%(", ".join(self._R.variable_names()), self._R.base_ring()) @@ -605,21 +610,21 @@ def monomial(self, *args): EXAMPLES:: - sage: L = LaurentPolynomialRing(QQ, 'x', 2) - sage: L.monomial(-3, 5) + sage: L = LaurentPolynomialRing(QQ, 'x', 2) # optional - sage.modules + sage: L.monomial(-3, 5) # optional - sage.modules x0^-3*x1^5 - sage: L.monomial(1, 1) + sage: L.monomial(1, 1) # optional - sage.modules x0*x1 - sage: L.monomial(0, 0) + sage: L.monomial(0, 0) # optional - sage.modules 1 - sage: L.monomial(-2, -3) + sage: L.monomial(-2, -3) # optional - sage.modules x0^-2*x1^-3 - sage: x0, x1 = L.gens() - sage: L.monomial(-1, 2) == x0^-1 * x1^2 + sage: x0, x1 = L.gens() # optional - sage.modules + sage: L.monomial(-1, 2) == x0^-1 * x1^2 # optional - sage.modules True - sage: L.monomial(1, 2, 3) + sage: L.monomial(1, 2, 3) # optional - sage.modules Traceback (most recent call last): ... TypeError: tuple key must have same length as ngens @@ -635,96 +640,96 @@ def _element_constructor_(self, x, mon=None): """ EXAMPLES:: - sage: L = LaurentPolynomialRing(QQ,2,'x') - sage: L(1/2) + sage: L = LaurentPolynomialRing(QQ,2,'x') # optional - sage.modules + sage: L(1/2) # optional - sage.modules 1/2 - sage: M = LaurentPolynomialRing(QQ, 'x, y') - sage: var('x, y') + sage: M = LaurentPolynomialRing(QQ, 'x, y') # optional - sage.modules + sage: var('x, y') # optional - sage.modules (x, y) - sage: M(x/y + 3/x) + sage: M(x/y + 3/x) # optional - sage.modules x*y^-1 + 3*x^-1 :: - sage: M(exp(x)) + sage: M(exp(x)) # optional - sage.modules Traceback (most recent call last): ... TypeError: unable to convert e^x to a rational :: - sage: L. = LaurentPolynomialRing(QQ) - sage: M = LaurentPolynomialRing(QQ, 'c, d') - sage: Mc, Md = M.gens() - sage: N = LaurentPolynomialRing(M, 'a, b') - sage: Na, Nb = N.gens() - sage: M(c/d) + sage: L. = LaurentPolynomialRing(QQ) # optional - sage.modules + sage: M = LaurentPolynomialRing(QQ, 'c, d') # optional - sage.modules + sage: Mc, Md = M.gens() # optional - sage.modules + sage: N = LaurentPolynomialRing(M, 'a, b') # optional - sage.modules + sage: Na, Nb = N.gens() # optional - sage.modules + sage: M(c/d) # optional - sage.modules c*d^-1 - sage: N(a*b/c/d) + sage: N(a*b/c/d) # optional - sage.modules (c^-1*d^-1)*a*b - sage: N(c/d) + sage: N(c/d) # optional - sage.modules c*d^-1 - sage: L(Mc) + sage: L(Mc) # optional - sage.modules c - sage: L(Nb) + sage: L(Nb) # optional - sage.modules b - sage: M(L(0)) + sage: M(L(0)) # optional - sage.modules 0 - sage: N(L(0)) + sage: N(L(0)) # optional - sage.modules 0 - sage: L(M(0)) + sage: L(M(0)) # optional - sage.modules 0 - sage: L(N(0)) + sage: L(N(0)) # optional - sage.modules 0 sage: U = LaurentPolynomialRing(QQ, 'a') sage: Ua = U.gen() sage: V = LaurentPolynomialRing(QQ, 'c') sage: Vc = V.gen() - sage: L(Ua) + sage: L(Ua) # optional - sage.modules a - sage: L(Vc) + sage: L(Vc) # optional - sage.modules c - sage: N(Ua) + sage: N(Ua) # optional - sage.modules a - sage: M(Vc) + sage: M(Vc) # optional - sage.modules c - sage: P = LaurentPolynomialRing(QQ, 'a, b') - sage: Q = LaurentPolynomialRing(P, 'c, d') - sage: Q(P.0) + sage: P = LaurentPolynomialRing(QQ, 'a, b') # optional - sage.modules + sage: Q = LaurentPolynomialRing(P, 'c, d') # optional - sage.modules + sage: Q(P.0) # optional - sage.modules a :: sage: A. = LaurentPolynomialRing(QQ) sage: B. = LaurentPolynomialRing(A) - sage: C = LaurentPolynomialRing(QQ, 'a, b') - sage: C(B({1: a})) + sage: C = LaurentPolynomialRing(QQ, 'a, b') # optional - sage.modules + sage: C(B({1: a})) # optional - sage.modules a*b - sage: D. = LaurentPolynomialRing(B) - sage: F. = LaurentPolynomialRing(D) - sage: D(F(d*e)) + sage: D. = LaurentPolynomialRing(B) # optional - sage.modules + sage: F. = LaurentPolynomialRing(D) # optional - sage.modules + sage: D(F(d*e)) # optional - sage.modules d*e :: sage: from sage.rings.polynomial.polydict import ETuple - sage: R. = LaurentPolynomialRing(QQ) - sage: mon = ETuple({}, int(3)) - sage: P = R.polynomial_ring() - sage: R(sum(P.gens()), mon) + sage: R. = LaurentPolynomialRing(QQ) # optional - sage.modules + sage: mon = ETuple({}, int(3)) # optional - sage.modules + sage: P = R.polynomial_ring() # optional - sage.modules + sage: R(sum(P.gens()), mon) # optional - sage.modules x + y + z - sage: R(sum(P.gens()), (-1,-1,-1)) + sage: R(sum(P.gens()), (-1,-1,-1)) # optional - sage.modules y^-1*z^-1 + x^-1*z^-1 + x^-1*y^-1 :: - sage: RL = R.localization(x+1) - sage: xi = RL(~x) - sage: R(xi) == ~x # indirect doctests + sage: RL = R.localization(x+1) # optional - sage.modules + sage: xi = RL(~x) # optional - sage.modules + sage: R(xi) == ~x # indirect doctests # optional - sage.modules True """ from sage.structure.element import Expression @@ -742,7 +747,7 @@ def _element_constructor_(self, x, mon=None): elif isinstance(x, Expression): return x.laurent_polynomial(ring=self) - elif isinstance(x, (LaurentPolynomial_univariate, LaurentPolynomial_mpair)): + elif isinstance(x, LaurentPolynomial): if self.variable_names() == P.variable_names(): # No special processing needed here; # handled by LaurentPolynomial_mpair.__init__ @@ -781,8 +786,8 @@ def __reduce__(self): EXAMPLES:: - sage: L = LaurentPolynomialRing(QQ, 2, 'x') - sage: loads(dumps(L)) == L + sage: L = LaurentPolynomialRing(QQ, 2, 'x') # optional - sage.modules + sage: loads(dumps(L)) == L # optional - sage.modules True """ return LaurentPolynomialRing_mpair, (self._R,) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py index 82394e3930c..93d8f9a4fc0 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py @@ -40,7 +40,10 @@ class LaurentPolynomialRing_generic(CommutativeRing, Parent): sage: R. = LaurentPolynomialRing(QQ) sage: R.category() - Join of Category of unique factorization domains and Category of commutative algebras over (number fields and quotient fields and metric spaces) and Category of infinite sets + Join of Category of unique factorization domains + and Category of commutative algebras + over (number fields and quotient fields and metric spaces) + and Category of infinite sets sage: TestSuite(R).run() """ @@ -48,7 +51,7 @@ def __init__(self, R): """ EXAMPLES:: - sage: R = LaurentPolynomialRing(QQ,2,'x') + sage: R = LaurentPolynomialRing(QQ, 2, 'x') sage: R == loads(dumps(R)) True """ @@ -65,9 +68,9 @@ def ngens(self): EXAMPLES:: - sage: LaurentPolynomialRing(QQ,2,'x').ngens() + sage: LaurentPolynomialRing(QQ, 2, 'x').ngens() 2 - sage: LaurentPolynomialRing(QQ,1,'x').ngens() + sage: LaurentPolynomialRing(QQ, 1, 'x').ngens() 1 """ return self._n @@ -79,16 +82,16 @@ def gen(self, i=0): EXAMPLES:: - sage: LaurentPolynomialRing(QQ,2,'x').gen() + sage: LaurentPolynomialRing(QQ, 2, 'x').gen() x0 - sage: LaurentPolynomialRing(QQ,2,'x').gen(0) + sage: LaurentPolynomialRing(QQ, 2, 'x').gen(0) x0 - sage: LaurentPolynomialRing(QQ,2,'x').gen(1) + sage: LaurentPolynomialRing(QQ, 2, 'x').gen(1) x1 TESTS:: - sage: LaurentPolynomialRing(QQ,2,'x').gen(3) + sage: LaurentPolynomialRing(QQ, 2, 'x').gen(3) Traceback (most recent call last): ... ValueError: generator not defined @@ -136,28 +139,29 @@ def variable_names_recursive(self, depth=infinity): def is_integral_domain(self, proof=True): """ - Returns True if self is an integral domain. + Return ``True`` if self is an integral domain. EXAMPLES:: - sage: LaurentPolynomialRing(QQ,2,'x').is_integral_domain() + sage: LaurentPolynomialRing(QQ, 2, 'x').is_integral_domain() True The following used to fail; see :trac:`7530`:: sage: L = LaurentPolynomialRing(ZZ, 'X') sage: L['Y'] - Univariate Polynomial Ring in Y over Univariate Laurent Polynomial Ring in X over Integer Ring + Univariate Polynomial Ring in Y over + Univariate Laurent Polynomial Ring in X over Integer Ring """ return self.base_ring().is_integral_domain(proof) def is_noetherian(self): """ - Returns True if self is Noetherian. + Return ``True`` if self is Noetherian. EXAMPLES:: - sage: LaurentPolynomialRing(QQ,2,'x').is_noetherian() + sage: LaurentPolynomialRing(QQ, 2, 'x').is_noetherian() Traceback (most recent call last): ... NotImplementedError @@ -170,9 +174,9 @@ def construction(self): EXAMPLES:: - sage: LaurentPolynomialRing(QQ,2,'x,y').construction() + sage: LaurentPolynomialRing(QQ, 2, 'x,y').construction() (LaurentPolynomialFunctor, - Univariate Laurent Polynomial Ring in x over Rational Field) + Univariate Laurent Polynomial Ring in x over Rational Field) """ from sage.categories.pushout import LaurentPolynomialFunctor @@ -195,11 +199,9 @@ def completion(self, p=None, prec=20, extras=None): EXAMPLES:: - sage: P. = LaurentPolynomialRing(QQ) - sage: P + sage: P. = LaurentPolynomialRing(QQ); P Univariate Laurent Polynomial Ring in x over Rational Field - sage: PP = P.completion(x) - sage: PP + sage: PP = P.completion(x); PP Laurent Series Ring in x over Rational Field sage: f = 1 - 1/x sage: PP(f) @@ -344,7 +346,7 @@ def _latex_(self): r""" EXAMPLES:: - sage: latex(LaurentPolynomialRing(QQ,2,'x')) + sage: latex(LaurentPolynomialRing(QQ, 2, 'x')) \Bold{Q}[x_{0}^{\pm 1}, x_{1}^{\pm 1}] """ from sage.misc.latex import latex @@ -356,7 +358,7 @@ def _ideal_class_(self, n=0): """ EXAMPLES:: - sage: LaurentPolynomialRing(QQ,2,'x')._ideal_class_() + sage: LaurentPolynomialRing(QQ, 2, 'x')._ideal_class_() Traceback (most recent call last): ... NotImplementedError @@ -368,7 +370,7 @@ def ideal(self, *args, **kwds): """ EXAMPLES:: - sage: LaurentPolynomialRing(QQ,2,'x').ideal([1]) + sage: LaurentPolynomialRing(QQ, 2, 'x').ideal([1]) Ideal (1) of Multivariate Laurent Polynomial Ring in x0, x1 over Rational Field TESTS: @@ -415,7 +417,7 @@ def term_order(self): EXAMPLES:: - sage: LaurentPolynomialRing(QQ,2,'x').term_order() + sage: LaurentPolynomialRing(QQ, 2, 'x').term_order() Degree reverse lexicographic term order """ @@ -425,7 +427,7 @@ def is_finite(self): """ EXAMPLES:: - sage: LaurentPolynomialRing(QQ,2,'x').is_finite() + sage: LaurentPolynomialRing(QQ, 2, 'x').is_finite() False """ @@ -435,7 +437,7 @@ def is_field(self, proof = True): """ EXAMPLES:: - sage: LaurentPolynomialRing(QQ,2,'x').is_field() + sage: LaurentPolynomialRing(QQ, 2, 'x').is_field() False """ return False @@ -446,9 +448,9 @@ def polynomial_ring(self): EXAMPLES:: - sage: LaurentPolynomialRing(QQ,2,'x').polynomial_ring() + sage: LaurentPolynomialRing(QQ, 2, 'x').polynomial_ring() Multivariate Polynomial Ring in x0, x1 over Rational Field - sage: LaurentPolynomialRing(QQ,1,'x').polynomial_ring() + sage: LaurentPolynomialRing(QQ, 1, 'x').polynomial_ring() Multivariate Polynomial Ring in x over Rational Field """ return self._R @@ -459,7 +461,7 @@ def characteristic(self): EXAMPLES:: - sage: LaurentPolynomialRing(QQ,2,'x').characteristic() + sage: LaurentPolynomialRing(QQ, 2, 'x').characteristic() 0 sage: LaurentPolynomialRing(GF(3), 2, 'x').characteristic() # optional - sage.libs.pari 3 @@ -471,7 +473,7 @@ def krull_dimension(self): """ EXAMPLES:: - sage: LaurentPolynomialRing(QQ,2,'x').krull_dimension() + sage: LaurentPolynomialRing(QQ, 2, 'x').krull_dimension() Traceback (most recent call last): ... NotImplementedError @@ -482,7 +484,7 @@ def random_element(self, low_degree = -2, high_degree = 2, terms = 5, choose_deg """ EXAMPLES:: - sage: LaurentPolynomialRing(QQ,2,'x').random_element() + sage: LaurentPolynomialRing(QQ, 2, 'x').random_element() Traceback (most recent call last): ... NotImplementedError @@ -491,13 +493,13 @@ def random_element(self, low_degree = -2, high_degree = 2, terms = 5, choose_deg def is_exact(self): """ - Returns True if the base ring is exact. + Return ``True`` if the base ring is exact. EXAMPLES:: - sage: LaurentPolynomialRing(QQ,2,'x').is_exact() + sage: LaurentPolynomialRing(QQ, 2, 'x').is_exact() True - sage: LaurentPolynomialRing(RDF,2,'x').is_exact() + sage: LaurentPolynomialRing(RDF, 2, 'x').is_exact() False """ return self.base_ring().is_exact() @@ -506,7 +508,7 @@ def change_ring(self, base_ring=None, names=None, sparse=False, order=None): """ EXAMPLES:: - sage: R = LaurentPolynomialRing(QQ,2,'x') + sage: R = LaurentPolynomialRing(QQ, 2, 'x') sage: R.change_ring(ZZ) Multivariate Laurent Polynomial Ring in x0, x1 over Integer Ring diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index 28d4265dc82..52cf994aa27 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -122,7 +122,7 @@ cdef class MPolynomial(CommutativePolynomial): _number_field_ = _scalar_conversion def __int__(self): - """ + r""" TESTS:: sage: type(RR['x,y']) @@ -153,7 +153,7 @@ cdef class MPolynomial(CommutativePolynomial): return self._scalar_conversion(int) def __float__(self): - """ + r""" TESTS:: sage: float(RR['x,y'](0)) # indirect doctest @@ -166,7 +166,7 @@ cdef class MPolynomial(CommutativePolynomial): return self._scalar_conversion(float) def _rational_(self): - """ + r""" TESTS:: sage: QQ(RR['x,y'](0.5)) # indirect doctest @@ -180,18 +180,18 @@ cdef class MPolynomial(CommutativePolynomial): return self._scalar_conversion(QQ) def _symbolic_(self, R): - """ + r""" EXAMPLES:: sage: R. = QQ[] sage: f = x^3 + y - sage: g = f._symbolic_(SR); g + sage: g = f._symbolic_(SR); g # optional - sage.symbolic x^3 + y - sage: g(x=2,y=2) + sage: g(x=2, y=2) # optional - sage.symbolic 10 - sage: g = SR(f) - sage: g(x=2,y=2) + sage: g = SR(f) # optional - sage.symbolic + sage: g(x=2, y=2) # optional - sage.symbolic 10 """ d = dict([(repr(g), R.var(g)) for g in self.parent().gens()]) @@ -214,23 +214,23 @@ cdef class MPolynomial(CommutativePolynomial): EXAMPLES:: - sage: R. = PolynomialRing(QQ,3,order='degrevlex') - sage: f=23*x^6*y^7 + x^3*y+6*x^7*z + sage: R. = PolynomialRing(QQ, 3, order='degrevlex') + sage: f = 23*x^6*y^7 + x^3*y+6*x^7*z sage: f.coefficients() [23, 6, 1] - sage: R. = PolynomialRing(QQ,3,order='lex') - sage: f=23*x^6*y^7 + x^3*y+6*x^7*z + sage: R. = PolynomialRing(QQ, 3, order='lex') + sage: f = 23*x^6*y^7 + x^3*y+6*x^7*z sage: f.coefficients() [6, 23, 1] Test the same stuff with base ring `\ZZ` -- different implementation:: - sage: R. = PolynomialRing(ZZ,3,order='degrevlex') - sage: f=23*x^6*y^7 + x^3*y+6*x^7*z + sage: R. = PolynomialRing(ZZ, 3, order='degrevlex') + sage: f = 23*x^6*y^7 + x^3*y+6*x^7*z sage: f.coefficients() [23, 6, 1] - sage: R. = PolynomialRing(ZZ,3,order='lex') - sage: f=23*x^6*y^7 + x^3*y+6*x^7*z + sage: R. = PolynomialRing(ZZ, 3, order='lex') + sage: f = 23*x^6*y^7 + x^3*y+6*x^7*z sage: f.coefficients() [6, 23, 1] @@ -242,10 +242,10 @@ cdef class MPolynomial(CommutativePolynomial): return [d[i] for i in self.exponents()] def truncate(self, var, n): - """ - Returns a new multivariate polynomial obtained from self by + r""" + Returns a new multivariate polynomial obtained from ``self`` by deleting all terms that involve the given variable to a power - at least n. + at least ``n``. """ cdef int ind R = self.parent() @@ -259,8 +259,8 @@ cdef class MPolynomial(CommutativePolynomial): return R(dict([(k, c) for k, c in d.iteritems() if k[ind] < n])) def _fast_callable_(self, etb): - """ - Given an ExpressionTreeBuilder, return an Expression representing + r""" + Given an :class:`ExpressionTreeBuilder`, return an :class:`Expression` representing this value. EXAMPLES:: @@ -303,10 +303,10 @@ cdef class MPolynomial(CommutativePolynomial): def derivative(self, *args): r""" The formal derivative of this polynomial, with respect to - variables supplied in args. + variables supplied in ``args``. Multiple variables and iteration counts may be supplied; see - documentation for the global derivative() function for more details. + documentation for the global function :func:`derivative` for more details. .. SEEALSO:: :meth:`._derivative` @@ -314,13 +314,13 @@ cdef class MPolynomial(CommutativePolynomial): Polynomials implemented via Singular:: - sage: R. = PolynomialRing(FiniteField(5)) - sage: f = x^3*y^5 + x^7*y - sage: type(f) + sage: R. = PolynomialRing(FiniteField(5)) # optional - sage.rings.finite_rings + sage: f = x^3*y^5 + x^7*y # optional - sage.rings.finite_rings + sage: type(f) # optional - sage.rings.finite_rings - sage: f.derivative(x) + sage: f.derivative(x) # optional - sage.rings.finite_rings 2*x^6*y - 2*x^2*y^5 - sage: f.derivative(y) + sage: f.derivative(y) # optional - sage.rings.finite_rings x^7 Generic multivariate polynomials:: @@ -347,21 +347,21 @@ cdef class MPolynomial(CommutativePolynomial): Polynomials over the symbolic ring (just for fun....):: - sage: x = var("x") - sage: S. = PolynomialRing(SR) - sage: f = u*v*x - sage: f.derivative(x) == u*v + sage: x = var("x") # optional - sage.symbolic + sage: S. = PolynomialRing(SR) # optional - sage.symbolic + sage: f = u*v*x # optional - sage.symbolic + sage: f.derivative(x) == u*v # optional - sage.symbolic True - sage: f.derivative(u) == v*x + sage: f.derivative(u) == v*x # optional - sage.symbolic True """ return multi_derivative(self, args) def polynomial(self, var): - """ - Let var be one of the variables of the parent of self. This - returns self viewed as a univariate polynomial in var over the + r""" + Let ``var`` be one of the variables of the parent of ``self``. This + returns ``self`` viewed as a univariate polynomial in ``var`` over the polynomial ring generated by all the other variables of the parent. EXAMPLES:: @@ -371,7 +371,8 @@ cdef class MPolynomial(CommutativePolynomial): sage: f.polynomial(x) x^3 + (17*w^3 + 3*w)*x + w^5 + z^5 sage: parent(f.polynomial(x)) - Univariate Polynomial Ring in x over Multivariate Polynomial Ring in w, z over Rational Field + Univariate Polynomial Ring in x + over Multivariate Polynomial Ring in w, z over Rational Field sage: f.polynomial(w) w^5 + 17*x*w^3 + 3*x*w + z^5 + x^3 @@ -387,11 +388,11 @@ cdef class MPolynomial(CommutativePolynomial): z^5 + x*w*k*z + w^5 + 17*x*w^3 + x^3 + 3*x*w + 5 sage: f.polynomial(k) x*w*z*k + w^5 + z^5 + 17*x*w^3 + x^3 + 3*x*w + 5 - sage: R.=GF(5)[] - sage: f=x^2+x+y - sage: f.polynomial(x) + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: f = x^2 + x + y # optional - sage.rings.finite_rings + sage: f.polynomial(x) # optional - sage.rings.finite_rings x^2 + x + y - sage: f.polynomial(y) + sage: f.polynomial(y) # optional - sage.rings.finite_rings y + x^2 + x """ cdef int ind @@ -444,8 +445,8 @@ cdef class MPolynomial(CommutativePolynomial): TESTS:: - sage: R = Qp(7)['x,y,z,t,p']; S = ZZ['x,z,t']['p'] - sage: R(S.0) + sage: R = Qp(7)['x,y,z,t,p']; S = ZZ['x,z,t']['p'] # optional - sage.rings.padics + sage: R(S.0) # optional - sage.rings.padics p sage: R = QQ['x,y,z,t,p']; S = ZZ['x']['y,z,t']['p'] sage: z = S.base_ring().gen(1) @@ -455,8 +456,8 @@ cdef class MPolynomial(CommutativePolynomial): sage: z = S.base_ring().gen(1); p = S.0; x = S.base_ring().base_ring().gen() sage: R(z+p) z + p - sage: R = Qp(7)['x,y,z,p']; S = ZZ['x']['y,z,t']['p'] # shouldn't work, but should throw a better error - sage: R(S.0) + sage: R = Qp(7)['x,y,z,p']; S = ZZ['x']['y,z,t']['p'] # shouldn't work, but should throw a better error # optional - sage.rings.padics + sage: R(S.0) # optional - sage.rings.padics p See :trac:`2601`:: @@ -528,7 +529,7 @@ cdef class MPolynomial(CommutativePolynomial): return D cdef long _hash_c(self) except -1: - """ + r""" This hash incorporates the variable name in an effort to respect the obvious inclusions into multi-variable polynomial rings. @@ -559,9 +560,9 @@ cdef class MPolynomial(CommutativePolynomial): Verify that :trac:`16251` has been resolved, i.e., polynomials with unhashable coefficients are unhashable:: - sage: K. = Qq(9) - sage: R. = K[] - sage: hash(t) + sage: K. = Qq(9) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: hash(t) # optional - sage.rings.padics Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' @@ -597,7 +598,7 @@ cdef class MPolynomial(CommutativePolynomial): def args(self): r""" - Returns the named of the arguments of self, in the + Returns the names of the arguments of ``self``, in the order they are accepted from call. EXAMPLES:: @@ -689,9 +690,9 @@ cdef class MPolynomial(CommutativePolynomial): In particular, this can be surprising in positive characteristic:: - sage: R. = GF(2)[] - sage: f = x + 1 - sage: f.homogenize(x) + sage: R. = GF(2)[] # optional - sage.rings.finite_rings + sage: f = x + 1 # optional - sage.rings.finite_rings + sage: f.homogenize(x) # optional - sage.rings.finite_rings 0 TESTS:: @@ -738,7 +739,7 @@ cdef class MPolynomial(CommutativePolynomial): def is_homogeneous(self): r""" - Return ``True`` if self is a homogeneous polynomial. + Return ``True`` if ``self`` is a homogeneous polynomial. TESTS:: @@ -773,7 +774,7 @@ cdef class MPolynomial(CommutativePolynomial): return True def homogeneous_components(self): - """ + r""" Return the homogeneous components of this polynomial. OUTPUT: @@ -808,21 +809,21 @@ cdef class MPolynomial(CommutativePolynomial): return {k: self._parent(d[k]) for k in d} cpdef _mod_(self, other): - """ + r""" EXAMPLES:: sage: R. = PolynomialRing(QQ) sage: f = (x^2*y + 2*x - 3) sage: g = (x + 1)*f - sage: g % f + sage: g % f # optional - sage.libs.singular 0 - sage: (g+1) % f + sage: (g+1) % f # optional - sage.libs.singular 1 sage: M = x*y sage: N = x^2*y^3 - sage: M.divides(N) + sage: M.divides(N) # optional - sage.libs.singular True """ try: @@ -834,7 +835,7 @@ cdef class MPolynomial(CommutativePolynomial): return r def change_ring(self, R): - """ + r""" Return a copy of this polynomial but with coefficients in ``R``, if at all possible. @@ -846,21 +847,21 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = QQ[] sage: f = x^3 + 3/5*y + 1 - sage: f.change_ring(GF(7)) + sage: f.change_ring(GF(7)) # optional - sage.rings.finite_rings x^3 + 2*y + 1 :: - sage: R. = GF(9,'a')[] - sage: (x+2*y).change_ring(GF(3)) + sage: R. = GF(9,'a')[] # optional - sage.rings.finite_rings + sage: (x+2*y).change_ring(GF(3)) # optional - sage.rings.finite_rings x - y :: - sage: K. = CyclotomicField(3) - sage: R. = K[] - sage: f = x^2 + z*y - sage: f.change_ring(K.embeddings(CC)[1]) + sage: K. = CyclotomicField(3) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: f = x^2 + z*y # optional - sage.rings.number_field + sage: f.change_ring(K.embeddings(CC)[1]) # optional - sage.rings.number_field x^2 + (-0.500000000000000 - 0.866025403784438*I)*y TESTS: @@ -868,7 +869,7 @@ cdef class MPolynomial(CommutativePolynomial): Check that :trac:`25022` is fixed:: sage: K. = ZZ[] - sage: (x*y).change_ring(SR).monomials() + sage: (x*y).change_ring(SR).monomials() # optional - sage.rings.number_field sage.symbolic [x*y] """ if isinstance(R, Map): @@ -892,47 +893,51 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = QQ[] sage: p = (x+y+z)**2 - 3 * (x+y)*(x+z)*(y+z) - sage: p.is_symmetric() + sage: p.is_symmetric() # optional - sage.groups True - sage: (x + y - z).is_symmetric() + sage: (x + y - z).is_symmetric() # optional - sage.groups False - sage: R.one().is_symmetric() + sage: R.one().is_symmetric() # optional - sage.groups True sage: p = (x-y)*(y-z)*(z-x) - sage: p.is_symmetric() + sage: p.is_symmetric() # optional - sage.groups False - sage: p.is_symmetric(AlternatingGroup(3)) + sage: p.is_symmetric(AlternatingGroup(3)) # optional - sage.groups True sage: R. = QQ[] - sage: ((x + y)**2).is_symmetric() + sage: ((x + y)**2).is_symmetric() # optional - sage.groups True - sage: R.one().is_symmetric() + sage: R.one().is_symmetric() # optional - sage.groups True - sage: (x + 2*y).is_symmetric() + sage: (x + 2*y).is_symmetric() # optional - sage.groups False An example with a GAP permutation group (here the quaternions):: sage: R = PolynomialRing(QQ, 'x', 8) sage: x = R.gens() - sage: p = sum(prod(x[i] for i in e) for e in [(0,1,2), (0,1,7), (0,2,7), (1,2,7), (3,4,5), (3,4,6), (3,5,6), (4,5,6)]) - sage: p.is_symmetric(libgap.TransitiveGroup(8, 5)) + sage: p = sum(prod(x[i] for i in e) + ....: for e in [(0,1,2), (0,1,7), (0,2,7), (1,2,7), + ....: (3,4,5), (3,4,6), (3,5,6), (4,5,6)]) + sage: p.is_symmetric(libgap.TransitiveGroup(8, 5)) # optional - sage.groups True - sage: p = sum(prod(x[i] for i in e) for e in [(0,1,2), (0,1,7), (0,2,7), (1,2,7), (3,4,5), (3,4,6), (3,5,6)]) - sage: p.is_symmetric(libgap.TransitiveGroup(8, 5)) + sage: p = sum(prod(x[i] for i in e) + ....: for e in [(0,1,2), (0,1,7), (0,2,7), (1,2,7), + ....: (3,4,5), (3,4,6), (3,5,6)]) + sage: p.is_symmetric(libgap.TransitiveGroup(8, 5)) # optional - sage.groups False TESTS:: sage: R = PolynomialRing(QQ, 'x', 3) - sage: R.one().is_symmetric(3) + sage: R.one().is_symmetric(3) # optional - sage.groups Traceback (most recent call last): ... ValueError: argument must be a permutation group - sage: R.one().is_symmetric(SymmetricGroup(4)) + sage: R.one().is_symmetric(SymmetricGroup(4)) # optional - sage.groups Traceback (most recent call last): ... ValueError: invalid data to initialize a permutation @@ -963,7 +968,7 @@ cdef class MPolynomial(CommutativePolynomial): for e, coeff in coeffs.items() for g in gens) def _gap_(self, gap): - """ + r""" Return a representation of ``self`` in the GAP interface INPUT: @@ -975,39 +980,39 @@ cdef class MPolynomial(CommutativePolynomial): Multivariate polynomial over integers:: sage: R. = ZZ[] - sage: gap(-x*y + 3*z) # indirect doctest + sage: gap(-x*y + 3*z) # indirect doctest # optional - sage.libs.gap -x*y+3*z - sage: gap(R.zero()) # indirect doctest + sage: gap(R.zero()) # indirect doctest # optional - sage.libs.gap 0 - sage: (x+y+z)._gap_(libgap) + sage: (x+y+z)._gap_(libgap) # optional - sage.libs.gap x+y+z - sage: g = gap(x - y + 3*x*y*z) - sage: R(g) + sage: g = gap(x - y + 3*x*y*z) # optional - sage.libs.gap + sage: R(g) # optional - sage.libs.gap 3*x*y*z + x - y - sage: g = libgap(5*x - y*z) - sage: R(g) + sage: g = libgap(5*x - y*z) # optional - sage.libs.gap + sage: R(g) # optional - sage.libs.gap -y*z + 5*x Multivariate polynomial over a cyclotomic field:: - sage: F. = CyclotomicField(8) - sage: P. = F[] - sage: p = zeta + zeta^2*x + zeta^3*y + (1+zeta)*x*y - sage: gap(p) # indirect doctest + sage: F. = CyclotomicField(8) # optional - sage.rings.number_field + sage: P. = F[] # optional - sage.rings.number_field + sage: p = zeta + zeta^2*x + zeta^3*y + (1+zeta)*x*y # optional - sage.rings.number_field + sage: gap(p) # indirect doctest # optional - sage.libs.gap sage.rings.number_field (1+E(8))*x*y+E(4)*x+E(8)^3*y+E(8) - sage: libgap(p) # indirect doctest + sage: libgap(p) # indirect doctest # optional - sage.libs.gap sage.rings.number_field (1+E(8))*x*y+E(4)*x+E(8)^3*y+E(8) Multivariate polynomial over a polynomial ring over a cyclotomic field:: - sage: S. = F[] - sage: P. = S[] - sage: p = zeta + zeta^2*x*z + zeta^3*y*z^2 + (1+zeta)*x*y*z - sage: gap(p) # indirect doctest + sage: S. = F[] # optional - sage.rings.number_field + sage: P. = S[] # optional - sage.rings.number_field + sage: p = zeta + zeta^2*x*z + zeta^3*y*z^2 + (1+zeta)*x*y*z # optional - sage.rings.number_field + sage: gap(p) # indirect doctest # optional - sage.libs.gap sage.rings.number_field ((1+E(8))*z)*x*y+E(4)*z*x+E(8)^3*z^2*y+E(8) - sage: libgap(p) # indirect doctest + sage: libgap(p) # indirect doctest # optional - sage.libs.gap sage.rings.number_field ((1+E(8))*z)*x*y+E(4)*z*x+E(8)^3*z^2*y+E(8) """ R = gap(self.parent()) @@ -1019,27 +1024,27 @@ cdef class MPolynomial(CommutativePolynomial): TESTS:: sage: R. = ZZ[] - sage: libgap(-x*y + 3*z) # indirect doctest + sage: libgap(-x*y + 3*z) # indirect doctest # optional - sage.libs.gap -x*y+3*z - sage: libgap(R.zero()) # indirect doctest + sage: libgap(R.zero()) # indirect doctest # optional - sage.libs.gap 0 """ from sage.libs.gap.libgap import libgap return self._gap_(libgap) def _magma_init_(self, magma): - """ - Returns a Magma string representation of self valid in the + r""" + Returns a Magma string representation of ``self`` valid in the given magma session. EXAMPLES:: - sage: k. = GF(25); R. = k[] - sage: f = y*x^2*b + x*(b+1) + 1 - sage: magma = Magma() # so var names same below - sage: magma(f) # optional - magma + sage: k. = GF(25); R. = k[] # optional - sage.rings.finite_rings + sage: f = y*x^2*b + x*(b+1) + 1 # optional - sage.rings.finite_rings + sage: magma = Magma() # so var names same below # optional - sage.rings.finite_rings + sage: magma(f) # optional - magma # optional - sage.rings.finite_rings b*x^2*y + b^22*x + 1 - sage: f._magma_init_(magma) # optional - magma + sage: f._magma_init_(magma) # optional - magma # optional - sage.rings.finite_rings '_sage_[...]!((_sage_[...]!(_sage_[...]))*_sage_[...]^2*_sage_[...]+(_sage_[...]!(_sage_[...] + 1))*_sage_[...]+(_sage_[...]!(1))*1)' A more complicated nested example:: @@ -1069,13 +1074,13 @@ cdef class MPolynomial(CommutativePolynomial): TESTS:: - sage: R. = GF(101)['e,i'][] - sage: f = R('e*i') * x + y^2 - sage: f._giac_init_() + sage: R. = GF(101)['e,i'][] # optional - sage.rings.finite_rings + sage: f = R('e*i') * x + y^2 # optional - sage.rings.finite_rings + sage: f._giac_init_() # optional - sage.rings.finite_rings '((1)*1)*sageVARy^2+((1)*sageVARe*sageVARi)*sageVARx' - sage: giac(f) + sage: giac(f) # optional - sage.rings.finite_rings sageVARy^2+sageVARe*sageVARi*sageVARx - sage: giac(R.zero()) + sage: giac(R.zero()) # optional - sage.rings.finite_rings 0 """ g = ['sageVAR' + x for x in self.parent().variable_names()] @@ -1091,7 +1096,7 @@ cdef class MPolynomial(CommutativePolynomial): EXAMPLES:: - sage: P. = PolynomialRing(ZZ,3) + sage: P. = PolynomialRing(ZZ, 3) sage: f = x*y + 1 sage: f.gradient() [y, x, 0] @@ -1107,32 +1112,33 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = QQ[] sage: f = x^3 + y^3 + z^3 sage: f.jacobian_ideal() - Ideal (3*x^2, 3*y^2, 3*z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field + Ideal (3*x^2, 3*y^2, 3*z^2) of + Multivariate Polynomial Ring in x, y, z over Rational Field """ return self.parent().ideal(self.gradient()) def newton_polytope(self): - """ + r""" Return the Newton polytope of this polynomial. EXAMPLES:: sage: R. = QQ[] sage: f = 1 + x*y + x^3 + y^3 - sage: P = f.newton_polytope() - sage: P + sage: P = f.newton_polytope() # optional - sage.geometry.polyhedron + sage: P # optional - sage.geometry.polyhedron A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices - sage: P.is_simple() + sage: P.is_simple() # optional - sage.geometry.polyhedron True TESTS:: sage: R. = QQ[] - sage: R(0).newton_polytope() + sage: R(0).newton_polytope() # optional - sage.geometry.polyhedron The empty polyhedron in ZZ^0 - sage: R(1).newton_polytope() + sage: R(1).newton_polytope() # optional - sage.geometry.polyhedron A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex - sage: R(x^2+y^2).newton_polytope().integral_points() + sage: R(x^2+y^2).newton_polytope().integral_points() # optional - sage.geometry.polyhedron ((0, 2), (1, 1), (2, 0)) """ from sage.geometry.polyhedron.constructor import Polyhedron @@ -1141,8 +1147,8 @@ cdef class MPolynomial(CommutativePolynomial): return P def __iter__(self): - """ - Facilitates iterating over the monomials of self, + r""" + Facilitates iterating over the monomials of ``self``, returning tuples of the form ``(coeff, mon)`` for each non-zero monomial. @@ -1160,13 +1166,13 @@ cdef class MPolynomial(CommutativePolynomial): yield (coeff, self.monomial(exp)) def iterator_exp_coeff(self, as_ETuples=True): - """ + r""" Iterate over ``self`` as pairs of ((E)Tuple, coefficient). INPUT: - - ``as_ETuples`` -- (default: ``True``) if ``True`` iterate over - pairs whose first element is an ETuple, otherwise as a tuples + - ``as_ETuples`` -- (default: ``True``) if ``True``, iterate over + pairs whose first element is an :class:`ETuple`, otherwise as a tuples EXAMPLES:: @@ -1186,8 +1192,8 @@ cdef class MPolynomial(CommutativePolynomial): yield (exp, self.monomial_coefficient(exp)) def content(self): - """ - Returns the content of this polynomial. Here, we define content as + r""" + Return the content of this polynomial. Here, we define content as the gcd of the coefficients in the base ring. .. SEEALSO:: @@ -1218,7 +1224,7 @@ cdef class MPolynomial(CommutativePolynomial): return gcd(self.coefficients()) def content_ideal(self): - """ + r""" Return the content ideal of this polynomial, defined as the ideal generated by its coefficients. @@ -1246,17 +1252,17 @@ cdef class MPolynomial(CommutativePolynomial): EXAMPLES:: - sage: R.=ZZ[] + sage: R. = ZZ[] sage: x.is_generator() True - sage: (x+y-y).is_generator() + sage: (x + y - y).is_generator() True sage: (x*y).is_generator() False - sage: R.=QQ[] + sage: R. = QQ[] sage: x.is_generator() True - sage: (x+y-y).is_generator() + sage: (x + y - y).is_generator() True sage: (x*y).is_generator() False @@ -1264,50 +1270,50 @@ cdef class MPolynomial(CommutativePolynomial): return (self in self.parent().gens()) def map_coefficients(self, f, new_base_ring=None): - """ + r""" Returns the polynomial obtained by applying ``f`` to the non-zero - coefficients of self. + coefficients of ``self``. If ``f`` is a :class:`sage.categories.map.Map`, then the resulting polynomial will be defined over the codomain of ``f``. Otherwise, the - resulting polynomial will be over the same ring as self. Set + resulting polynomial will be over the same ring as ``self``. Set ``new_base_ring`` to override this behaviour. INPUT: - - ``f`` -- a callable that will be applied to the coefficients of self. + - ``f`` -- a callable that will be applied to the coefficients of ``self``. - ``new_base_ring`` (optional) -- if given, the resulting polynomial will be defined over this ring. EXAMPLES:: - sage: k. = GF(9); R. = k[]; f = x*a + 2*x^3*y*a + a - sage: f.map_coefficients(lambda a : a + 1) + sage: k. = GF(9); R. = k[]; f = x*a + 2*x^3*y*a + a # optional - sage.rings.finite_rings + sage: f.map_coefficients(lambda a: a + 1) # optional - sage.rings.finite_rings (-a + 1)*x^3*y + (a + 1)*x + (a + 1) Examples with different base ring:: - sage: R. = GF(9); S. = GF(81) - sage: h = Hom(R,S)[0]; h + sage: R. = GF(9); S. = GF(81) # optional - sage.rings.finite_rings + sage: h = Hom(R,S)[0]; h # optional - sage.rings.finite_rings Ring morphism: From: Finite Field in r of size 3^2 To: Finite Field in s of size 3^4 Defn: r |--> 2*s^3 + 2*s^2 + 1 - sage: T. = R[] - sage: f = r*X+Y - sage: g = f.map_coefficients(h); g + sage: T. = R[] # optional - sage.rings.finite_rings + sage: f = r*X + Y # optional - sage.rings.finite_rings + sage: g = f.map_coefficients(h); g # optional - sage.rings.finite_rings (-s^3 - s^2 + 1)*X + Y - sage: g.parent() + sage: g.parent() # optional - sage.rings.finite_rings Multivariate Polynomial Ring in X, Y over Finite Field in s of size 3^4 - sage: h = lambda x: x.trace() - sage: g = f.map_coefficients(h); g + sage: h = lambda x: x.trace() # optional - sage.rings.finite_rings + sage: g = f.map_coefficients(h); g # optional - sage.rings.finite_rings X - Y - sage: g.parent() + sage: g.parent() # optional - sage.rings.finite_rings Multivariate Polynomial Ring in X, Y over Finite Field in r of size 3^2 - sage: g = f.map_coefficients(h, new_base_ring=GF(3)); g + sage: g = f.map_coefficients(h, new_base_ring=GF(3)); g # optional - sage.rings.finite_rings X - Y - sage: g.parent() + sage: g.parent() # optional - sage.rings.finite_rings Multivariate Polynomial Ring in X, Y over Finite Field of size 3 """ @@ -1331,10 +1337,10 @@ cdef class MPolynomial(CommutativePolynomial): EXAMPLES:: - sage: k. = GF(9) - sage: R. = PolynomialRing(k) - sage: f = (x-a)*(y-a) - sage: f._norm_over_nonprime_finite_field() + sage: k. = GF(9) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(k) # optional - sage.rings.finite_rings + sage: f = (x-a) * (y-a) # optional - sage.rings.finite_rings + sage: f._norm_over_nonprime_finite_field() # optional - sage.rings.finite_rings x^2*y^2 - x^2*y - x*y^2 - x^2 + x*y - y^2 + x + y + 1 """ P = self.parent() @@ -1347,8 +1353,8 @@ cdef class MPolynomial(CommutativePolynomial): return prod(v).change_ring(k.prime_subfield()) def sylvester_matrix(self, right, variable = None): - """ - Given two nonzero polynomials self and right, returns the Sylvester + r""" + Given two nonzero polynomials ``self`` and ``right``, return the Sylvester matrix of the polynomials with respect to a given variable. Note that the Sylvester matrix is not defined if one of the polynomials @@ -1356,22 +1362,22 @@ cdef class MPolynomial(CommutativePolynomial): INPUT: - - self , right: multivariate polynomials - - variable: optional, compute the Sylvester matrix with respect to this - variable. If variable is not provided, the first variable of the + - ``self``, ``right`` -- multivariate polynomials + - ``variable`` -- optional, compute the Sylvester matrix with respect to this + variable. If ``variable`` is not provided, the first variable of the polynomial ring is used. OUTPUT: - - The Sylvester matrix of self and right. + - The Sylvester matrix of ``self`` and ``right``. EXAMPLES:: sage: R. = PolynomialRing(ZZ) sage: f = (y + 1)*x + 3*x**2 sage: g = (y + 2)*x + 4*x**2 - sage: M = f.sylvester_matrix(g, x) - sage: M + sage: M = f.sylvester_matrix(g, x) # optional - sage.modules + sage: M # optional - sage.modules [ 3 y + 1 0 0] [ 0 3 y + 1 0] [ 4 y + 2 0 0] @@ -1380,18 +1386,18 @@ cdef class MPolynomial(CommutativePolynomial): If the polynomials share a non-constant common factor then the determinant of the Sylvester matrix will be zero:: - sage: M.determinant() + sage: M.determinant() # optional - sage.modules 0 - sage: f.sylvester_matrix(1 + g, x).determinant() + sage: f.sylvester_matrix(1 + g, x).determinant() # optional - sage.modules y^2 - y + 7 - If both polynomials are of positive degree with respect to variable, the + If both polynomials are of positive degree with respect to ``variable``, the determinant of the Sylvester matrix is the resultant:: sage: f = R.random_element(4) or (x^2 * y^2) sage: g = R.random_element(4) or (x^2 * y^2) - sage: f.sylvester_matrix(g, x).determinant() == f.resultant(g, x) + sage: f.sylvester_matrix(g, x).determinant() == f.resultant(g, x) # optional - sage.modules True TESTS: @@ -1400,7 +1406,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: f = x + y sage: g = x + y - sage: f.sylvester_matrix(g) + sage: f.sylvester_matrix(g) # optional - sage.modules [1 y] [1 y] @@ -1412,45 +1418,47 @@ cdef class MPolynomial(CommutativePolynomial): sage: g = x + y sage: R. = GF(25, 'a')[] sage: h = x + y - sage: f.sylvester_matrix(g, 'x') + sage: f.sylvester_matrix(g, 'x') # optional - sage.modules [1 y] [1 y] - sage: g.sylvester_matrix(h, 'x') + sage: g.sylvester_matrix(h, 'x') # optional - sage.modules [1 y] [1 y] - sage: f.sylvester_matrix(h, 'x') + sage: f.sylvester_matrix(h, 'x') # optional - sage.modules Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Multivariate Polynomial Ring in x, y over Rational Field' and 'Multivariate Polynomial Ring in x, y over Finite Field in a of size 5^2' + TypeError: no common canonical parent for objects with parents: + 'Multivariate Polynomial Ring in x, y over Rational Field' and + 'Multivariate Polynomial Ring in x, y over Finite Field in a of size 5^2' sage: K. = QQ[] sage: f = x + y sage: L. = QQ[] sage: g = x + z - sage: f.sylvester_matrix(g) + sage: f.sylvester_matrix(g) # optional - sage.modules [1 y] [1 z] Corner cases:: - sage: K.=QQ[] - sage: f = x^2+1 + sage: K.=QQ[] + sage: f = x^2 + 1 sage: g = K(0) - sage: f.sylvester_matrix(g) + sage: f.sylvester_matrix(g) # optional - sage.modules Traceback (most recent call last): ... ValueError: The Sylvester matrix is not defined for zero polynomials - sage: g.sylvester_matrix(f) + sage: g.sylvester_matrix(f) # optional - sage.modules Traceback (most recent call last): ... ValueError: The Sylvester matrix is not defined for zero polynomials - sage: g.sylvester_matrix(g) + sage: g.sylvester_matrix(g) # optional - sage.modules Traceback (most recent call last): ... ValueError: The Sylvester matrix is not defined for zero polynomials - sage: K(3).sylvester_matrix(x^2) + sage: K(3).sylvester_matrix(x^2) # optional - sage.modules [3 0] [0 3] - sage: K(3).sylvester_matrix(K(4)) + sage: K(3).sylvester_matrix(K(4)) # optional - sage.modules [] """ @@ -1500,53 +1508,49 @@ cdef class MPolynomial(CommutativePolynomial): return M def discriminant(self,variable): - """ - Returns the discriminant of self with respect to the given variable. + r""" + Returns the discriminant of ``self`` with respect to the given variable. INPUT: - - ``variable`` - The variable with respect to which we compute - the discriminant - - OUTPUT: - - - An element of the base ring of the polynomial ring. + - ``variable`` - The variable with respect to which we compute + the discriminant + OUTPUT: An element of the base ring of the polynomial ring. EXAMPLES:: - sage: R.=QQ[] - sage: f=4*x*y^2 + 1/4*x*y*z + 3/2*x*z^2 - 1/2*z^2 - sage: f.discriminant(x) + sage: R. = QQ[] + sage: f = 4*x*y^2 + 1/4*x*y*z + 3/2*x*z^2 - 1/2*z^2 + sage: f.discriminant(x) # optional - sage.libs.singular 1 - sage: f.discriminant(y) + sage: f.discriminant(y) # optional - sage.libs.singular -383/16*x^2*z^2 + 8*x*z^2 - sage: f.discriminant(z) + sage: f.discriminant(z) # optional - sage.libs.singular -383/16*x^2*y^2 + 8*x*y^2 Note that, unlike the univariate case, the result lives in the same ring as the polynomial:: - sage: R.=QQ[] - sage: f=x^5*y+3*x^2*y^2-2*x+y-1 - sage: f.discriminant(y) + sage: R. = QQ[] + sage: f = x^5*y + 3*x^2*y^2 - 2*x + y - 1 + sage: f.discriminant(y) # optional - sage.libs.singular x^10 + 2*x^5 + 24*x^3 + 12*x^2 + 1 - sage: f.polynomial(y).discriminant() + sage: f.polynomial(y).discriminant() # optional - sage.libs.singular x^10 + 2*x^5 + 24*x^3 + 12*x^2 + 1 - sage: f.discriminant(y).parent()==f.polynomial(y).discriminant().parent() + sage: f.discriminant(y).parent() == f.polynomial(y).discriminant().parent() # optional - sage.libs.singular False TESTS: Test polynomials over QQbar (:trac:`25265`):: - sage: R.=QQbar[] - sage: f=x^5*y+3*x^2*y^2-2*x+y-1 - sage: f.discriminant(y) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = x^5*y + 3*x^2*y^2 - 2*x + y - 1 # optional - sage.rings.number_field + sage: f.discriminant(y) # optional - sage.rings.number_field x^10 + 2*x^5 + 24*x^3 + 12*x^2 + 1 - AUTHOR: - Miguel Marco + AUTHOR: Miguel Marco """ if self.is_zero(): return self.parent().zero() @@ -1595,7 +1599,7 @@ cdef class MPolynomial(CommutativePolynomial): def macaulay_resultant(self, *args): r""" - This is an implementation of the Macaulay Resultant. It computes + 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 @@ -1610,36 +1614,36 @@ cdef class MPolynomial(CommutativePolynomial): INPUT: - ``args`` -- a list of `n-1` homogeneous polynomials in `n` variables. - works when ``args[0]`` is the list of polynomials, - or ``args`` is itself the list of polynomials + works when ``args[0]`` is the list of polynomials, + or ``args`` is itself the list of polynomials OUTPUT: - - the macaulay resultant + - the Macaulay resultant EXAMPLES: The number of polynomials has to match the number of variables:: - sage: R. = PolynomialRing(QQ,3) - sage: y.macaulay_resultant(x+z) + sage: R. = PolynomialRing(QQ, 3) + sage: y.macaulay_resultant(x + z) # optional - sage.modules Traceback (most recent call last): ... TypeError: number of polynomials(= 2) must equal number of variables (= 3) The polynomials need to be all homogeneous:: - sage: R. = PolynomialRing(QQ,3) - sage: y.macaulay_resultant([x+z, z+x^3]) + sage: R. = PolynomialRing(QQ, 3) + sage: y.macaulay_resultant([x + z, z + x^3]) # optional - sage.modules Traceback (most recent call last): ... TypeError: resultant for non-homogeneous polynomials is not supported All polynomials must be in the same ring:: - sage: R. = PolynomialRing(QQ,3) + sage: R. = PolynomialRing(QQ, 3) sage: S. = PolynomialRing(QQ, 2) - sage: y.macaulay_resultant(z+x,z) + sage: y.macaulay_resultant(z + x, z) # optional - sage.modules Traceback (most recent call last): ... TypeError: not all inputs are polynomials in the calling ring @@ -1647,15 +1651,19 @@ cdef class MPolynomial(CommutativePolynomial): The following example recreates Proposition 2.10 in Ch.3 of Using Algebraic Geometry:: sage: K. = PolynomialRing(ZZ, 2) - sage: flist,R = K._macaulay_resultant_universal_polynomials([1,1,2]) - sage: flist[0].macaulay_resultant(flist[1:]) - u2^2*u4^2*u6 - 2*u1*u2*u4*u5*u6 + u1^2*u5^2*u6 - u2^2*u3*u4*u7 + u1*u2*u3*u5*u7 + u0*u2*u4*u5*u7 - u0*u1*u5^2*u7 + u1*u2*u3*u4*u8 - u0*u2*u4^2*u8 - u1^2*u3*u5*u8 + u0*u1*u4*u5*u8 + u2^2*u3^2*u9 - 2*u0*u2*u3*u5*u9 + u0^2*u5^2*u9 - u1*u2*u3^2*u10 + u0*u2*u3*u4*u10 + u0*u1*u3*u5*u10 - u0^2*u4*u5*u10 + u1^2*u3^2*u11 - 2*u0*u1*u3*u4*u11 + u0^2*u4^2*u11 + sage: flist, R = K._macaulay_resultant_universal_polynomials([1,1,2]) + sage: flist[0].macaulay_resultant(flist[1:]) # optional - sage.modules + u2^2*u4^2*u6 - 2*u1*u2*u4*u5*u6 + u1^2*u5^2*u6 - u2^2*u3*u4*u7 + u1*u2*u3*u5*u7 + + u0*u2*u4*u5*u7 - u0*u1*u5^2*u7 + u1*u2*u3*u4*u8 - u0*u2*u4^2*u8 - u1^2*u3*u5*u8 + + u0*u1*u4*u5*u8 + u2^2*u3^2*u9 - 2*u0*u2*u3*u5*u9 + u0^2*u5^2*u9 + - u1*u2*u3^2*u10 + u0*u2*u3*u4*u10 + u0*u1*u3*u5*u10 - u0^2*u4*u5*u10 + + u1^2*u3^2*u11 - 2*u0*u1*u3*u4*u11 + u0^2*u4^2*u11 - The following example degenerates into the determinant of a `3*3` matrix:: + The following example degenerates into the determinant of a `3\times 3` matrix:: sage: K. = PolynomialRing(ZZ, 2) - sage: flist,R = K._macaulay_resultant_universal_polynomials([1,1,1]) - sage: flist[0].macaulay_resultant(flist[1:]) + sage: flist, R = K._macaulay_resultant_universal_polynomials([1,1,1]) + sage: flist[0].macaulay_resultant(flist[1:]) # optional - sage.modules -u2*u4*u6 + u1*u5*u6 + u2*u3*u7 - u0*u5*u7 - u1*u3*u8 + u0*u4*u8 The following example is by Patrick Ingram (:arxiv:`1310.4114`):: @@ -1665,56 +1673,56 @@ cdef class MPolynomial(CommutativePolynomial): sage: f0 = y0*x2^2 - x0^2 + 2*x1*x2 sage: f1 = y1*x2^2 - x1^2 + 2*x0*x2 sage: f2 = x0*x1 - x2^2 - sage: f0.macaulay_resultant(f1,f2) + sage: f0.macaulay_resultant(f1, f2) # optional - sage.modules y0^2*y1^2 - 4*y0^3 - 4*y1^3 + 18*y0*y1 - 27 a simple example with constant rational coefficients:: - sage: R. = PolynomialRing(QQ,4) - sage: w.macaulay_resultant([z,y,x]) + sage: R. = PolynomialRing(QQ, 4) + sage: w.macaulay_resultant([z, y, x]) # optional - sage.modules 1 an example where the resultant vanishes:: - sage: R. = PolynomialRing(QQ,3) - sage: (x+y).macaulay_resultant([y^2,x]) + sage: R. = PolynomialRing(QQ, 3) + sage: (x + y).macaulay_resultant([y^2, x]) # optional - sage.modules 0 an example of bad reduction at a prime ``p = 5``:: - sage: R. = PolynomialRing(QQ,3) - sage: y.macaulay_resultant([x^3+25*y^2*x,5*z]) + sage: R. = PolynomialRing(QQ, 3) + sage: y.macaulay_resultant([x^3 + 25*y^2*x, 5*z]) # optional - sage.modules 125 The input can given as an unpacked list of polynomials:: - sage: R. = PolynomialRing(QQ,3) - sage: y.macaulay_resultant(x^3+25*y^2*x,5*z) + sage: R. = PolynomialRing(QQ, 3) + sage: y.macaulay_resultant(x^3 + 25*y^2*x, 5*z) # optional - sage.modules 125 an example when the coefficients live in a finite field:: - sage: F = FiniteField(11) - sage: R. = PolynomialRing(F,4) - sage: z.macaulay_resultant([x^3,5*y,w]) + sage: F = FiniteField(11) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(F, 4) # optional - sage.rings.finite_rings + sage: z.macaulay_resultant([x^3, 5*y, w]) # optional - sage.rings.finite_rings sage.modules 4 example when the denominator in the algorithm vanishes(in this case the resultant is the constant term of the quotient of char polynomials of numerator/denominator):: - sage: R. = PolynomialRing(QQ,3) - sage: y.macaulay_resultant([x+z, z^2]) + sage: R. = PolynomialRing(QQ, 3) + sage: y.macaulay_resultant([x + z, z^2]) # optional - sage.modules -1 - when there are only 2 polynomials, macaulay resultant degenerates to the traditional resultant:: + When there are only 2 polynomials, the Macaulay resultant degenerates to the traditional resultant:: - sage: R. = PolynomialRing(QQ,1) - sage: f = x^2+1; g = x^5+1 + sage: R. = PolynomialRing(QQ, 1) + sage: f = x^2 + 1; g = x^5 + 1 sage: fh = f.homogenize() sage: gh = g.homogenize() sage: RH = fh.parent() - sage: f.resultant(g) == fh.macaulay_resultant(gh) + sage: f.resultant(g) == fh.macaulay_resultant(gh) # optional - sage.modules True """ @@ -1723,12 +1731,12 @@ cdef class MPolynomial(CommutativePolynomial): return self.parent().macaulay_resultant(self, *args) def denominator(self): - """ - Return a denominator of self. + r""" + Return a denominator of ``self``. - First, the lcm of the denominators of the entries of self + First, the lcm of the denominators of the entries of ``self`` is computed and returned. If this computation fails, the - unit of the parent of self is returned. + unit of the parent of ``self`` is returned. Note that some subclasses may implement its own denominator function. @@ -1755,10 +1763,10 @@ cdef class MPolynomial(CommutativePolynomial): :: - sage: R. = NumberField(symbolic_expression(x^2+3) ,'a')['x,y'] - sage: f = (1/17)*x^19 + (1/6)*y - (2/3)*x + 1/3; f + sage: R. = NumberField(symbolic_expression(x^2+3),'a')['x,y'] # optional - sage.rings.number_field sage.symbolic + sage: f = (1/17)*x^19 + (1/6)*y - (2/3)*x + 1/3; f # optional - sage.rings.number_field sage.symbolic 1/17*x^19 - 2/3*x + 1/6*y + 1/3 - sage: f.denominator() + sage: f.denominator() # optional - sage.rings.number_field sage.symbolic 102 Finally, we try to compute the denominator of a polynomial with @@ -1776,18 +1784,18 @@ cdef class MPolynomial(CommutativePolynomial): Check that the denominator is an element over the base whenever the base has no denominator function. This closes :trac:`9063`:: - sage: R. = GF(5)[] - sage: x = R(0) - sage: x.denominator() + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: x = R(0) # optional - sage.rings.finite_rings + sage: x.denominator() # optional - sage.rings.finite_rings 1 - sage: type(x.denominator()) + sage: type(x.denominator()) # optional - sage.rings.finite_rings - sage: type(a.denominator()) + sage: type(a.denominator()) # optional - sage.rings.finite_rings sage: from sage.rings.polynomial.multi_polynomial_element import MPolynomial - sage: isinstance(a / b, MPolynomial) + sage: isinstance(a / b, MPolynomial) # optional - sage.rings.finite_rings False - sage: isinstance(a.numerator() / a.denominator(), MPolynomial) + sage: isinstance(a.numerator() / a.denominator(), MPolynomial) # optional - sage.rings.finite_rings True """ if self.degree() == -1: @@ -1802,8 +1810,8 @@ cdef class MPolynomial(CommutativePolynomial): return self.base_ring().one() def numerator(self): - """ - Return a numerator of self computed as self * self.denominator() + r""" + Return a numerator of ``self``, computed as ``self * self.denominator()``. Note that some subclasses may implement its own numerator function. @@ -1811,13 +1819,13 @@ cdef class MPolynomial(CommutativePolynomial): .. warning:: This is not the numerator of the rational function - defined by self, which would always be self since self is a + defined by ``self``, which would always be self since ``self`` is a polynomial. EXAMPLES: First we compute the numerator of a polynomial with - integer coefficients, which is of course self. + integer coefficients, which is of course ``self``. :: @@ -1832,12 +1840,12 @@ cdef class MPolynomial(CommutativePolynomial): :: - sage: R. = NumberField(symbolic_expression(x^2+3) ,'a')['x,y'] - sage: f = (1/17)*y^19 - (2/3)*x + 1/3; f + sage: R. = NumberField(symbolic_expression(x^2+3), 'a')['x,y'] # optional - sage.rings.number_field sage.symbolic + sage: f = (1/17)*y^19 - (2/3)*x + 1/3; f # optional - sage.rings.number_field sage.symbolic 1/17*y^19 - 2/3*x + 1/3 - sage: f.numerator() + sage: f.numerator() # optional - sage.rings.number_field sage.symbolic 3*y^19 - 34*x + 17 - sage: f == f.numerator() + sage: f == f.numerator() # optional - sage.rings.number_field sage.symbolic False We try to compute the numerator of a polynomial with coefficients in @@ -1845,36 +1853,36 @@ cdef class MPolynomial(CommutativePolynomial): :: - sage: K. = GF(3)['x, y, z'] - sage: f = 2*x*z + 2*z^2 + 2*y + 1; f + sage: K. = GF(3)['x, y, z'] # optional - sage.rings.finite_rings + sage: f = 2*x*z + 2*z^2 + 2*y + 1; f # optional - sage.rings.finite_rings -x*z - z^2 - y + 1 - sage: f.numerator() + sage: f.numerator() # optional - sage.rings.finite_rings -x*z - z^2 - y + 1 We check that the computation the numerator and denominator - are valid + are valid. :: - sage: K=NumberField(symbolic_expression('x^3+2'),'a')['x']['s,t'] - sage: f=K.random_element() - sage: f.numerator() / f.denominator() == f + sage: K = NumberField(symbolic_expression('x^3+2'), 'a')['x']['s,t'] # optional - sage.rings.number_field sage.symbolic + sage: f = K.random_element() # optional - sage.rings.number_field sage.symbolic + sage: f.numerator() / f.denominator() == f # optional - sage.rings.number_field sage.symbolic True - sage: R=RR['x,y,z'] - sage: f=R.random_element() + sage: R = RR['x,y,z'] + sage: f = R.random_element() sage: f.numerator() / f.denominator() == f True """ return self * self.denominator() def lift(self, I): - """ - given an ideal ``I = (f_1,...,f_r)`` and some ``g (== self)`` in ``I``, - find ``s_1,...,s_r`` such that ``g = s_1 f_1 + ... + s_r f_r``. + r""" + Given an ideal `I = (f_1,\dots,f_r)` that contains ``self``, + find `s_1,\dots,s_r` such that ``self`` `= s_1 f_1 + ... + s_r f_r`. EXAMPLES:: - sage: A. = PolynomialRing(CC,2,order='degrevlex') + sage: A. = PolynomialRing(CC, 2, order='degrevlex') sage: I = A.ideal([x^10 + x^9*y^2, y^8 - x^2*y^7 ]) sage: f = x*y^13 + y^12 sage: M = f.lift(I) @@ -1886,25 +1894,26 @@ cdef class MPolynomial(CommutativePolynomial): raise NotImplementedError def inverse_mod(self, I): - """ - Returns an inverse of self modulo the polynomial ideal `I`, + r""" + Returns an inverse of ``self`` modulo the polynomial ideal `I`, namely a multivariate polynomial `f` such that ``self * f - 1`` belongs to `I`. INPUT: - - ``I`` -- an ideal of the polynomial ring in which self lives + + - ``I`` -- an ideal of the polynomial ring in which ``self`` lives OUTPUT: - - a multivariate polynomial representing the inverse of ``f`` modulo ``I`` + a multivariate polynomial representing the inverse of ``f`` modulo `I` EXAMPLES:: sage: R. = QQ[] sage: I = R.ideal(x2**2 + x1 - 2, x1**2 - 1) - sage: f = x1 + 3*x2^2; g = f.inverse_mod(I); g + sage: f = x1 + 3*x2^2; g = f.inverse_mod(I); g # optional - sage.libs.singular 1/16*x1 + 3/16 - sage: (f*g).reduce(I) + sage: (f*g).reduce(I) # optional - sage.libs.singular 1 Test a non-invertible element:: @@ -1912,7 +1921,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = QQ[] sage: I = R.ideal(x2**2 + x1 - 2, x1**2 - 1) sage: f = x1 + x2 - sage: f.inverse_mod(I) + sage: f.inverse_mod(I) # optional - sage.libs.singular Traceback (most recent call last): ... ArithmeticError: element is non-invertible @@ -1926,7 +1935,7 @@ cdef class MPolynomial(CommutativePolynomial): raise ArithmeticError("element is non-invertible") def weighted_degree(self, *weights): - """ + r""" Return the weighted degree of ``self``, which is the maximum weighted degree of all monomials in ``self``; the weighted degree of a monomial is the sum of all powers of the variables in the monomial, each power @@ -1945,42 +1954,42 @@ cdef class MPolynomial(CommutativePolynomial): EXAMPLES:: - sage: R. = GF(7)[] - sage: p = x^3 + y + x*z^2 - sage: p.weighted_degree({z:0, x:1, y:2}) + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: p = x^3 + y + x*z^2 # optional - sage.rings.finite_rings + sage: p.weighted_degree({z:0, x:1, y:2}) # optional - sage.rings.finite_rings 3 - sage: p.weighted_degree(1, 2, 0) + sage: p.weighted_degree(1, 2, 0) # optional - sage.rings.finite_rings 3 - sage: p.weighted_degree((1, 4, 2)) + sage: p.weighted_degree((1, 4, 2)) # optional - sage.rings.finite_rings 5 - sage: p.weighted_degree((1, 4, 1)) + sage: p.weighted_degree((1, 4, 1)) # optional - sage.rings.finite_rings 4 - sage: p.weighted_degree(2**64, 2**50, 2**128) + sage: p.weighted_degree(2**64, 2**50, 2**128) # optional - sage.rings.finite_rings 680564733841876926945195958937245974528 - sage: q = R.random_element(100, 20) #random - sage: q.weighted_degree(1, 1, 1) == q.total_degree() + sage: q = R.random_element(100, 20) #random # optional - sage.rings.finite_rings + sage: q.weighted_degree(1, 1, 1) == q.total_degree() # optional - sage.rings.finite_rings True You may also work with negative weights :: - sage: p.weighted_degree(-1, -2, -1) + sage: p.weighted_degree(-1, -2, -1) # optional - sage.rings.finite_rings -2 Note that only integer weights are allowed :: - sage: p.weighted_degree(x,1,1) + sage: p.weighted_degree(x, 1, 1) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unable to convert non-constant polynomial x to Integer Ring - sage: p.weighted_degree(2/1,1,1) + sage: p.weighted_degree(2/1, 1, 1) # optional - sage.rings.finite_rings 6 - The ``weighted_degree`` coincides with the ``degree`` of a weighted - polynomial ring, but the later is faster. + The :meth:`weighted_degree` coincides with the :meth:`degree` of a weighted + polynomial ring, but the latter is faster. :: @@ -2034,7 +2043,7 @@ cdef class MPolynomial(CommutativePolynomial): return deg def gcd(self, other): - """ + r""" Return a greatest common divisor of this polynomial and ``other``. INPUT: @@ -2048,7 +2057,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: r = x*y - (2*z-1)/(z^2+z+1) * x + y/z sage: p = r * (x + z*y - 1/z^2) sage: q = r * (x*y*z + 1) - sage: gcd(p,q) + sage: gcd(p, q) (z^3 + z^2 + z)*x*y + (-2*z^2 + z)*x + (z^2 + z + 1)*y Polynomials over polynomial rings are converted to a simpler polynomial @@ -2056,21 +2065,23 @@ cdef class MPolynomial(CommutativePolynomial): sage: A. = ZZ[] sage: B. = A[] - sage: r = x*y*z*t+1 + sage: r = x*y*z*t + 1 sage: p = r * (x - y + z - t + 1) sage: q = r * (x*z - y*t) - sage: gcd(p,q) + sage: gcd(p, q) z*t*x*y + 1 sage: _.parent() - Multivariate Polynomial Ring in x, y over Multivariate Polynomial Ring in z, t over Integer Ring + Multivariate Polynomial Ring in x, y over + Multivariate Polynomial Ring in z, t over Integer Ring Some multivariate polynomial rings have no gcd implementation:: - sage: R. =GaussianIntegers()[] + sage: R. = GaussianIntegers()[] sage: x.gcd(x) Traceback (most recent call last): ... - NotImplementedError: GCD is not implemented for multivariate polynomials over Gaussian Integers in Number Field in I with defining polynomial x^2 + 1 with I = 1*I + NotImplementedError: GCD is not implemented for multivariate polynomials over + Gaussian Integers in Number Field in I with defining polynomial x^2 + 1 with I = 1*I TESTS:: @@ -2159,11 +2170,11 @@ cdef class MPolynomial(CommutativePolynomial): def is_square(self, root=False): r""" - Test whether this polynomial is a square root. + Test whether this polynomial is a square. INPUT: - - ``root`` - if set to ``True`` return a pair ``(True, root)`` + - ``root`` - if set to ``True``, return a pair ``(True, root)`` where ``root`` is a square root or ``(False, None)`` if it is not a square. @@ -2196,7 +2207,7 @@ cdef class MPolynomial(CommutativePolynomial): - ``D`` -- dictionary (optional) - - ``phi`` -- SpecializationMorphism (optional) + - ``phi`` -- :class:`SpecializationMorphism` (optional) OUTPUT: a new polynomial @@ -2273,11 +2284,11 @@ cdef class MPolynomial(CommutativePolynomial): keywords: - - ``prec`` -- integer, sets the precision (default:300) + - ``prec`` -- integer, sets the precision (default: 300) - - ``return_conjugation`` -- boolean. Returns element of `SL(2, \ZZ)` (default:True) + - ``return_conjugation`` -- boolean. Returns element of `SL(2, \ZZ)` (default: True) - - ``error_limit`` -- sets the error tolerance (default:0.000001) + - ``error_limit`` -- sets the error tolerance (default: 0.000001) - ``smallest_coeffs`` -- (default: True), boolean, whether to find the model with smallest coefficients @@ -2285,16 +2296,18 @@ cdef class MPolynomial(CommutativePolynomial): - ``norm_type`` -- either ``'norm'`` or ``'height'``. What type of norm to use for smallest coefficients - - ``emb`` -- (optional) embedding of based field into CC + - ``emb`` -- (optional) embedding of based field into ``CC`` OUTPUT: - - a polynomial (reduced binary form) + - a polynomial (reduced binary form) + + - a matrix (element of `SL(2, \ZZ)`) - - a matrix (element of `SL(2, \ZZ)`) + .. TODO:: - TODO: When Newton's Method doesn't converge to a root in the upper half plane. - Now we just return z0. It would be better to modify and find the unique root + When Newton's Method doesn't converge to a root in the upper half plane. + Now we just return `z_0`. It would be better to modify and find the unique root in the upper half plane. EXAMPLES:: @@ -2302,7 +2315,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: f = 19*x^8 - 262*x^7*h + 1507*x^6*h^2 - 4784*x^5*h^3 + 9202*x^4*h^4\ -10962*x^3*h^5 + 7844*x^2*h^6 - 3040*x*h^7 + 475*h^8 - sage: f.reduced_form(prec=200, smallest_coeffs=False) + sage: f.reduced_form(prec=200, smallest_coeffs=False) # optional - sage.modules ( -x^8 - 2*x^7*h + 7*x^6*h^2 + 16*x^5*h^3 + 2*x^4*h^4 - 2*x^3*h^5 + 4*x^2*h^6 - 5*h^8, @@ -2315,7 +2328,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: f = x^3 + 378666*x^2*y - 12444444*x*y^2 + 1234567890*y^3 sage: j = f * (x-545*y)^9 - sage: j.reduced_form(prec=200, smallest_coeffs=False) + sage: j.reduced_form(prec=200, smallest_coeffs=False) # optional - sage.modules Traceback (most recent call last): ... ValueError: cannot have a root with multiplicity >= 12/2 @@ -2324,7 +2337,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: F = x^6 + 3*x^5*y - 8*x^4*y^2 - 2*x^3*y^3 - 44*x^2*y^4 - 8*x*y^5 - sage: F.reduced_form(smallest_coeffs=False, prec=400) + sage: F.reduced_form(smallest_coeffs=False, prec=400) # optional - sage.modules Traceback (most recent call last): ... ArithmeticError: Newton's method converged to z not in the upper half plane @@ -2333,7 +2346,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: F = 5*x^2*y - 5*x*y^2 - 30*y^3 - sage: F.reduced_form(smallest_coeffs=False) + sage: F.reduced_form(smallest_coeffs=False) # optional - sage.modules ( [1 1] 5*x^2*y + 5*x*y^2 - 30*y^3, [0 1] @@ -2342,12 +2355,14 @@ cdef class MPolynomial(CommutativePolynomial): An example where precision needs to be increased:: sage: R. = PolynomialRing(QQ) - sage: F=-16*x^7 - 114*x^6*y - 345*x^5*y^2 - 599*x^4*y^3 - 666*x^3*y^4 - 481*x^2*y^5 - 207*x*y^6 - 40*y^7 - sage: F.reduced_form(prec=50, smallest_coeffs=False) + sage: F = (-16*x^7 - 114*x^6*y - 345*x^5*y^2 - 599*x^4*y^3 + ....: - 666*x^3*y^4 - 481*x^2*y^5 - 207*x*y^6 - 40*y^7) + sage: F.reduced_form(prec=50, smallest_coeffs=False) # optional - sage.modules Traceback (most recent call last): ... - ValueError: accuracy of Newton's root not within tolerance(0.000012... > 1e-06), increase precision - sage: F.reduced_form(prec=100, smallest_coeffs=False) + ValueError: accuracy of Newton's root not within tolerance(0.000012... > 1e-06), + increase precision + sage: F.reduced_form(prec=100, smallest_coeffs=False) # optional - sage.modules ( [-1 -1] -x^5*y^2 - 24*x^3*y^4 - 3*x^2*y^5 - 2*x*y^6 + 16*y^7, [ 1 0] @@ -2357,14 +2372,14 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: F = - 8*x^4 - 3933*x^3*y - 725085*x^2*y^2 - 59411592*x*y^3 - 1825511633*y^4 - sage: F.reduced_form(return_conjugation=False) + sage: F.reduced_form(return_conjugation=False) # optional - sage.modules x^4 + 9*x^3*y - 3*x*y^3 - 8*y^4 :: sage: R. = QQ[] sage: F = -2*x^3 + 2*x^2*y + 3*x*y^2 + 127*y^3 - sage: F.reduced_form() + sage: F.reduced_form() # optional - sage.modules ( [1 4] -2*x^3 - 22*x^2*y - 77*x*y^2 + 43*y^3, [0 1] @@ -2374,7 +2389,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = QQ[] sage: F = -2*x^3 + 2*x^2*y + 3*x*y^2 + 127*y^3 - sage: F.reduced_form(norm_type='height') + sage: F.reduced_form(norm_type='height') # optional - sage.modules ( [5 4] -58*x^3 - 47*x^2*y + 52*x*y^2 + 43*y^3, [1 1] @@ -2384,7 +2399,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: F = x^4 + x^3*y*z + y^2*z - sage: F.reduced_form() + sage: F.reduced_form() # optional - sage.modules Traceback (most recent call last): ... ValueError: (=x^3*y*z + x^4 + y^2*z) must have two variables @@ -2393,7 +2408,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(ZZ) sage: F = - 8*x^6 - 3933*x^3*y - 725085*x^2*y^2 - 59411592*x*y^3 - 99*y^6 - sage: F.reduced_form(return_conjugation=False) + sage: F.reduced_form(return_conjugation=False) # optional - sage.modules Traceback (most recent call last): ... ValueError: (=-8*x^6 - 99*y^6 - 3933*x^3*y - 725085*x^2*y^2 - @@ -2402,11 +2417,12 @@ cdef class MPolynomial(CommutativePolynomial): :: sage: R. = PolynomialRing(RR) - sage: F = 217.992172373276*x^3 + 96023.1505442490*x^2*y + 1.40987971253579e7*x*y^2\ - + 6.90016027113216e8*y^3 - sage: F.reduced_form(smallest_coeffs=False) # tol 1e-8 + sage: F = (217.992172373276*x^3 + 96023.1505442490*x^2*y + ....: + 1.40987971253579e7*x*y^2 + 6.90016027113216e8*y^3) + sage: F.reduced_form(smallest_coeffs=False) # tol 1e-8 # optional - sage.modules ( - -39.5673942565918*x^3 + 111.874026298523*x^2*y + 231.052762985229*x*y^2 - 138.380829811096*y^3, + -39.5673942565918*x^3 + 111.874026298523*x^2*y + + 231.052762985229*x*y^2 - 138.380829811096*y^3, [-147 -148] [ 1 1] @@ -2415,12 +2431,16 @@ cdef class MPolynomial(CommutativePolynomial): :: sage: R. = PolynomialRing(CC) - sage: F = (0.759099196558145 + 0.845425869641446*CC.0)*x^3 + (84.8317207268542 + 93.8840848648033*CC.0)*x^2*y\ - + (3159.07040755858 + 3475.33037377779*CC.0)*x*y^2 + (39202.5965389079 + 42882.5139724962*CC.0)*y^3 - sage: F.reduced_form(smallest_coeffs=False) # tol 1e-11 + sage: F = ((0.759099196558145 + 0.845425869641446*CC.0)*x^3 + ....: + (84.8317207268542 + 93.8840848648033*CC.0)*x^2*y + ....: + (3159.07040755858 + 3475.33037377779*CC.0)*x*y^2 + ....: + (39202.5965389079 + 42882.5139724962*CC.0)*y^3) + sage: F.reduced_form(smallest_coeffs=False) # tol 1e-11 # optional - sage.modules ( - (-0.759099196558145 - 0.845425869641446*I)*x^3 + (-0.571709908900118 - 0.0418133346027929*I)*x^2*y - + (0.856525964330103 - 0.0721403997649759*I)*x*y^2 + (-0.965531044130330 + 0.754252314465703*I)*y^3, + (-0.759099196558145 - 0.845425869641446*I)*x^3 + + (-0.571709908900118 - 0.0418133346027929*I)*x^2*y + + (0.856525964330103 - 0.0721403997649759*I)*x*y^2 + + (-0.965531044130330 + 0.754252314465703*I)*y^3, [-1 37] [ 0 -1] @@ -2507,16 +2527,16 @@ cdef class MPolynomial(CommutativePolynomial): EXAMPLES:: - sage: R. = QQbar[] - sage: (x+y).is_unit() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: (x + y).is_unit() # optional - sage.rings.number_field False - sage: R(0).is_unit() + sage: R(0).is_unit() # optional - sage.rings.number_field False - sage: R(-1).is_unit() + sage: R(-1).is_unit() # optional - sage.rings.number_field True - sage: R(-1 + x).is_unit() + sage: R(-1 + x).is_unit() # optional - sage.rings.number_field False - sage: R(2).is_unit() + sage: R(2).is_unit() # optional - sage.rings.number_field True Check that :trac:`22454` is fixed:: @@ -2553,18 +2573,18 @@ cdef class MPolynomial(CommutativePolynomial): EXAMPLES:: - sage: R. = QQbar[] - sage: (x+y).is_nilpotent() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: (x + y).is_nilpotent() # optional - sage.rings.number_field False - sage: R(0).is_nilpotent() + sage: R(0).is_nilpotent() # optional - sage.rings.number_field True sage: _. = Zmod(4)[] sage: (2*x).is_nilpotent() True - sage: (2+y*x).is_nilpotent() + sage: (2 + y*x).is_nilpotent() False sage: _. = Zmod(36)[] - sage: (4+6*x).is_nilpotent() + sage: (4 + 6*x).is_nilpotent() False sage: (6*x + 12*y + 18*x*y + 24*(x^2+y^2)).is_nilpotent() True @@ -2585,8 +2605,8 @@ cdef class MPolynomial(CommutativePolynomial): TESTS:: - sage: R. = QQbar[] - sage: (x + y)._test_subs() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: (x + y)._test_subs() # optional - sage.rings.number_field """ if tester is None: tester = self._tester(**options) @@ -2865,11 +2885,12 @@ cdef class MPolynomial_libsingular(MPolynomial): EXAMPLES:: + sage: from sage.rings.polynomial.multi_polynomial import MPolynomial_libsingular sage: R1. = QQ[] - sage: isinstance(x, sage.rings.polynomial.multi_polynomial.MPolynomial_libsingular) + sage: isinstance(x, MPolynomial_libsingular) False sage: R2. = QQ[] - sage: isinstance(y, sage.rings.polynomial.multi_polynomial.MPolynomial_libsingular) + sage: isinstance(y, MPolynomial_libsingular) # optional - sage.libs.singular True By design, there is a unique direct subclass:: diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 08cc3dee4d0..f270ea6ee78 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -31,8 +31,10 @@ We verify Lagrange's four squares identity:: - sage: R. = QQbar[] - sage: (a0^2 + a1^2 + a2^2 + a3^2)*(b0^2 + b1^2 + b2^2 + b3^2) == (a0*b0 - a1*b1 - a2*b2 - a3*b3)^2 + (a0*b1 + a1*b0 + a2*b3 - a3*b2)^2 + (a0*b2 - a1*b3 + a2*b0 + a3*b1)^2 + (a0*b3 + a1*b2 - a2*b1 + a3*b0)^2 + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: ((a0^2 + a1^2 + a2^2 + a3^2) * (b0^2 + b1^2 + b2^2 + b3^2) == # optional - sage.rings.number_field + ....: (a0*b0 - a1*b1 - a2*b2 - a3*b3)^2 + (a0*b1 + a1*b0 + a2*b3 - a3*b2)^2 + ....: + (a0*b2 - a1*b3 + a2*b0 + a3*b1)^2 + (a0*b3 + a1*b2 - a2*b1 + a3*b0)^2) True """ #***************************************************************************** @@ -92,12 +94,12 @@ def __init__(self, parent, x): """ EXAMPLES:: - sage: K. = NumberField(x^3 - 2) - sage: L. = K.extension(x^3 - 3) - sage: S. = L.extension(x^2 - 2) - sage: S + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: L. = K.extension(x^3 - 3) # optional - sage.rings.number_field + sage: S. = L.extension(x^2 - 2) # optional - sage.rings.number_field + sage: S # optional - sage.rings.number_field Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field - sage: P. = PolynomialRing(S) # indirect doctest + sage: P. = PolynomialRing(S) # indirect doctest # optional - sage.rings.number_field """ CommutativeRingElement.__init__(self, parent) self.__element = x @@ -106,8 +108,8 @@ def _repr_(self): """ EXAMPLES:: - sage: P. = PolynomialRing(QQbar) - sage: x + QQbar(sqrt(2) - 1/2*I) # indirect doctest + sage: P. = PolynomialRing(QQbar) # optional - sage.rings.number_field + sage: x + QQbar(sqrt(2) - 1/2*I) # indirect doctest # optional - sage.rings.number_field x + 1.414213562373095? - 0.50000000000000000?*I """ return "%s"%self.__element @@ -184,15 +186,15 @@ def _richcmp_(self, right, op): EXAMPLES:: - sage: R.=PolynomialRing(QQbar,3,order='lex') - sage: x^1*y^2 > y^3*z^4 + sage: R. = PolynomialRing(QQbar, 3, order='lex') # optional - sage.rings.number_field + sage: x^1*y^2 > y^3*z^4 # optional - sage.rings.number_field True - sage: x^3*y^2*z^4 < x^3*y^2*z^1 + sage: x^3*y^2*z^4 < x^3*y^2*z^1 # optional - sage.rings.number_field False :: - sage: R.=PolynomialRing(CC,3,order='deglex') + sage: R. = PolynomialRing(CC, 3, order='deglex') sage: x^1*y^2*z^3 > x^3*y^2*z^0 True sage: x^1*y^2*z^4 < x^1*y^1*z^5 @@ -200,10 +202,10 @@ def _richcmp_(self, right, op): :: - sage: R.=PolynomialRing(QQbar,3,order='degrevlex') - sage: x^1*y^5*z^2 > x^4*y^1*z^3 + sage: R. = PolynomialRing(QQbar, 3, order='degrevlex') # optional - sage.rings.number_field + sage: x^1*y^5*z^2 > x^4*y^1*z^3 # optional - sage.rings.number_field True - sage: x^4*y^7*z^1 < x^4*y^2*z^3 + sage: x^4*y^7*z^1 < x^4*y^2*z^3 # optional - sage.rings.number_field False """ return self.__element.rich_compare(right.__element, op, @@ -213,9 +215,9 @@ def _im_gens_(self, codomain, im_gens, base_map=None): """ EXAMPLES:: - sage: R. = PolynomialRing(QQbar, 2) - sage: f = R.hom([y,x], R) - sage: f(x^2 + 3*y^5) # indirect doctest + sage: R. = PolynomialRing(QQbar, 2) # optional - sage.rings.number_field + sage: f = R.hom([y, x], R) # optional - sage.rings.number_field + sage: f(x^2 + 3*y^5) # indirect doctest # optional - sage.rings.number_field 3*x^5 + y^2 You can specify a map on the base ring:: @@ -272,10 +274,10 @@ def __neg__(self): EXAMPLES:: - sage: R. = QQbar[] - sage: -x + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: -x # optional - sage.rings.number_field -x - sage: -(y-1) + sage: -(y-1) # optional - sage.rings.number_field -y + 1 """ return self.__class__(self.parent(), -self.__element) @@ -286,8 +288,8 @@ def _add_(self, right): EXAMPLES:: - sage: R. = QQbar[] - sage: x + y + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: x + y # optional - sage.rings.number_field x + y """ elt = self.__element + right.__element @@ -300,8 +302,8 @@ def _sub_(self, right): EXAMPLES:: - sage: R. = QQbar[] - sage: x - y + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: x - y # optional - sage.rings.number_field x - y """ elt = self.__element - right.__element @@ -314,8 +316,8 @@ def _mul_(self, right): EXAMPLES:: - sage: R. = QQbar[] - sage: x * y + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: x * y # optional - sage.rings.number_field x*y """ elt = self.__element * right.__element @@ -334,9 +336,9 @@ def _lmul_(self, a): :: - sage: R. = QQbar[] - sage: f = (x + y) - sage: 3*f + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = (x + y) # optional - sage.rings.number_field + sage: 3 * f # optional - sage.rings.number_field 3*x + 3*y """ elt = self.__element.scalar_lmult(a) @@ -355,9 +357,9 @@ def _rmul_(self, a): :: - sage: R. = QQbar[] - sage: f = (x + y) - sage: f*3 + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = (x + y) # optional - sage.rings.number_field + sage: f * 3 # optional - sage.rings.number_field 3*x + 3*y """ elt = self.__element.scalar_rmult(a) @@ -388,8 +390,8 @@ def _div_(self, right): Ensure that :trac:`13704` is fixed.:: - sage: R.=PolynomialRing(QQ) - sage: S.=PolynomialRing(R) + sage: R. = PolynomialRing(QQ) + sage: S. = PolynomialRing(R) sage: x/S(2) 1/2*x """ @@ -420,15 +422,15 @@ def change_ring(self, R): sage: R. = QQ[] sage: f = x^2 + 5*y - sage: f.change_ring(GF(5)) + sage: f.change_ring(GF(5)) # optional - sage.rings.finite_rings x^2 :: - sage: K. = CyclotomicField(5) - sage: R. = K[] - sage: f = x^2 + w*y - sage: f.change_ring(K.embeddings(QQbar)[1]) + sage: K. = CyclotomicField(5) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: f = x^2 + w*y # optional - sage.rings.number_field + sage: f.change_ring(K.embeddings(QQbar)[1]) # optional - sage.rings.number_field x^2 + (-0.8090169943749474? + 0.5877852522924731?*I)*y """ if isinstance(R, Morphism): @@ -449,10 +451,10 @@ def __init__(self, parent, x): """ EXAMPLES:: - sage: R, x = PolynomialRing(QQbar, 10, 'x').objgens() - sage: x + sage: R, x = PolynomialRing(QQbar, 10, 'x').objgens() # optional - sage.rings.number_field + sage: x # optional - sage.rings.number_field (x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) - sage: loads(dumps(x)) == x + sage: loads(dumps(x)) == x # optional - sage.rings.number_field True """ if not isinstance(x, polydict.PolyDict): @@ -482,12 +484,12 @@ def _repr_(self): """ EXAMPLES:: - sage: R.=QQbar[] - sage: repr(-x^2-y+1) # indirect doc-test + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: repr(-x^2 - y + 1) # indirect doctest # optional - sage.rings.number_field '-x^2 - y + 1' - sage: K.=QuadraticField(-1) - sage: R.=K[] - sage: repr(-I*y-x^2) # indirect doc-test + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: repr(-I*y - x^2) # indirect doctest # optional - sage.rings.number_field '-x^2 + (-I)*y' """ try: @@ -503,12 +505,12 @@ def _latex_(self): r""" EXAMPLES:: - sage: R.=QQbar[] - sage: latex(-x^2-y+1) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: latex(-x^2 - y + 1) # optional - sage.rings.number_field -x^{2} - y + 1 - sage: K.=QuadraticField(-1) - sage: R.=K[] - sage: latex(-I*y+I*x^2) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: latex(-I*y + I*x^2) # optional - sage.rings.number_field \left(\sqrt{-1}\right) x^{2} + \left(-\sqrt{-1}\right) y """ try: @@ -523,9 +525,9 @@ def _repr_with_changed_varnames(self, varnames): """ EXAMPLES:: - sage: R.=QQbar[] - sage: f=-x^2-y+1 - sage: f._repr_with_changed_varnames(['jack','jill']) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = -x^2 - y + 1 # optional - sage.rings.number_field + sage: f._repr_with_changed_varnames(['jack', 'jill']) # optional - sage.rings.number_field '-jack^2 - jill + 1' """ try: @@ -540,8 +542,8 @@ def _macaulay2_(self, macaulay2=None): """ EXAMPLES:: - sage: R = GF(13)['a,b']['c,d'] - sage: macaulay2(R('a^2 + c')) # optional - macaulay2 + sage: R = GF(13)['a,b']['c,d'] # optional - sage.rings.finite_rings + sage: macaulay2(R('a^2 + c')) # optional - macaulay2 sage.rings.finite_rings 2 c + a @@ -550,7 +552,7 @@ def _macaulay2_(self, macaulay2=None): Elements of the base ring are coerced to the polynomial ring correctly:: - sage: macaulay2(R('a^2')).ring()._operator('===', R) # optional - macaulay2 + sage: macaulay2(R('a^2')).ring()._operator('===', R) # optional - macaulay2 sage.rings.finite_rings true """ if macaulay2 is None: @@ -568,20 +570,20 @@ def degrees(self): EXAMPLES:: - sage: R.=PolynomialRing(QQbar) - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.degrees() + sage: R. = PolynomialRing(QQbar) # optional - sage.rings.number_field + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field + sage: f.degrees() # optional - sage.rings.number_field (2, 2, 0) - sage: f = x^2+z^2 - sage: f.degrees() + sage: f = x^2 + z^2 # optional - sage.rings.number_field + sage: f.degrees() # optional - sage.rings.number_field (2, 0, 2) - sage: f.total_degree() # this simply illustrates that total degree is not the sum of the degrees + sage: f.total_degree() # this simply illustrates that total degree is not the sum of the degrees # optional - sage.rings.number_field 2 - sage: R.=PolynomialRing(QQbar) - sage: f=(1-x)*(1+y+z+x^3)^5 - sage: f.degrees() + sage: R. = PolynomialRing(QQbar) # optional - sage.rings.number_field + sage: f = (1-x) * (1+y+z+x^3)^5 # optional - sage.rings.number_field + sage: f.degrees() # optional - sage.rings.number_field (16, 5, 5, 0) - sage: R(0).degrees() + sage: R(0).degrees() # optional - sage.rings.number_field (0, 0, 0, 0) """ if not self: @@ -591,17 +593,17 @@ def degrees(self): def degree(self, x=None, std_grading=False): """ - Return the degree of self in x, where x must be one of the - generators for the parent of self. + Return the degree of ``self`` in ``x``, where ``x`` must be one of the + generators for the parent of ``self``. INPUT: - ``x`` - multivariate polynomial (a generator of the parent - of self). If ``x`` is not specified (or is None), return - the total degree, which is the maximum degree of any - monomial. Note that a weighted term ordering alters the - grading of the generators of the ring; see the tests below. - To avoid this behavior, set the optional argument ``std_grading=True``. + of ``self``). If ``x`` is not specified (or is None), return + the total degree, which is the maximum degree of any + monomial. Note that a weighted term ordering alters the + grading of the generators of the ring; see the tests below. + To avoid this behavior, set the optional argument ``std_grading=True``. OUTPUT: integer @@ -623,15 +625,15 @@ def degree(self, x=None, std_grading=False): :: - sage: R = PolynomialRing(QQ,'x,y',order=TermOrder('wdeglex',(2,3))) + sage: R = PolynomialRing(QQ, 'x,y', order=TermOrder('wdeglex',(2,3))) sage: x,y = R.gens() sage: x.degree() 2 sage: y.degree() 3 - sage: x.degree(y),x.degree(x),y.degree(x),y.degree(y) + sage: x.degree(y), x.degree(x), y.degree(x), y.degree(y) (0, 1, 0, 1) - sage: f = (x^2*y+x*y^2) + sage: f = x^2*y + x*y^2 sage: f.degree(x) 2 sage: f.degree(y) @@ -641,7 +643,7 @@ def degree(self, x=None, std_grading=False): sage: f.degree(std_grading=True) 3 - Note that if ``x`` is not a generator of the parent of self, + Note that if ``x`` is not a generator of the parent of ``self``, for example if it is a generator of a polynomial algebra which maps naturally to this one, then it is converted to an element of this algebra. (This fixes the problem reported in @@ -659,37 +661,37 @@ def degree(self, x=None, std_grading=False): ... TypeError: x must canonically coerce to parent - sage: GF(3037000453)['x','y'].gen(0).degree(x^2) + sage: GF(3037000453)['x','y'].gen(0).degree(x^2) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: x must be one of the generators of the parent TESTS:: - sage: R = PolynomialRing(GF(2)['t'],'x,y',order=TermOrder('wdeglex',(2,3))) - sage: x,y = R.gens() - sage: x.degree() + sage: R = PolynomialRing(GF(2)['t'], 'x,y', order=TermOrder('wdeglex', (2,3))) # optional - sage.rings.finite_rings + sage: x, y = R.gens() # optional - sage.rings.finite_rings + sage: x.degree() # optional - sage.rings.finite_rings 2 - sage: y.degree() + sage: y.degree() # optional - sage.rings.finite_rings 3 - sage: x.degree(y),x.degree(x),y.degree(x),y.degree(y) + sage: x.degree(y), x.degree(x), y.degree(x), y.degree(y) # optional - sage.rings.finite_rings (0, 1, 0, 1) - sage: f = (x^2*y+x*y^2) - sage: f.degree(x) + sage: f = (x^2*y + x*y^2) # optional - sage.rings.finite_rings + sage: f.degree(x) # optional - sage.rings.finite_rings 2 - sage: f.degree(y) + sage: f.degree(y) # optional - sage.rings.finite_rings 2 - sage: f.degree() + sage: f.degree() # optional - sage.rings.finite_rings 8 - sage: f.degree(std_grading=True) + sage: f.degree(std_grading=True) # optional - sage.rings.finite_rings 3 - sage: R(0).degree() + sage: R(0).degree() # optional - sage.rings.finite_rings -1 Degree of zero polynomial for other implementation :trac:`20048` :: - sage: R. = GF(3037000453)[] - sage: R.zero().degree(x) + sage: R. = GF(3037000453)[] # optional - sage.rings.finite_rings + sage: R.zero().degree(x) # optional - sage.rings.finite_rings -1 """ if x is None: @@ -710,37 +712,37 @@ def degree(self, x=None, std_grading=False): def total_degree(self): """ - Return the total degree of self, which is the maximum degree of any - monomial in self. + Return the total degree of ``self``, which is the maximum degree of any + monomial in ``self``. EXAMPLES:: - sage: R. = QQbar[] - sage: f=2*x*y^3*z^2 - sage: f.total_degree() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = 2*x*y^3*z^2 # optional - sage.rings.number_field + sage: f.total_degree() # optional - sage.rings.number_field 6 - sage: f=4*x^2*y^2*z^3 - sage: f.total_degree() + sage: f = 4*x^2*y^2*z^3 # optional - sage.rings.number_field + sage: f.total_degree() # optional - sage.rings.number_field 7 - sage: f=99*x^6*y^3*z^9 - sage: f.total_degree() + sage: f = 99*x^6*y^3*z^9 # optional - sage.rings.number_field + sage: f.total_degree() # optional - sage.rings.number_field 18 - sage: f=x*y^3*z^6+3*x^2 - sage: f.total_degree() + sage: f = x*y^3*z^6 + 3*x^2 # optional - sage.rings.number_field + sage: f.total_degree() # optional - sage.rings.number_field 10 - sage: f=z^3+8*x^4*y^5*z - sage: f.total_degree() + sage: f = z^3 + 8*x^4*y^5*z # optional - sage.rings.number_field + sage: f.total_degree() # optional - sage.rings.number_field 10 - sage: f=z^9+10*x^4+y^8*x^2 - sage: f.total_degree() + sage: f = z^9 + 10*x^4 + y^8*x^2 # optional - sage.rings.number_field + sage: f.total_degree() # optional - sage.rings.number_field 10 """ return self.degree() def monomial_coefficient(self, mon): """ - Return the coefficient in the base ring of the monomial mon in - self, where mon must have the same parent as self. + Return the coefficient in the base ring of the monomial ``mon`` in + ``self``, where ``mon`` must have the same parent as ``self``. This function contrasts with the function ``coefficient`` which returns the coefficient of a @@ -761,43 +763,35 @@ def monomial_coefficient(self, mon): EXAMPLES: - The parent of the return is a member of the base ring. - :: - sage: R.=QQbar[] - - The parent of the return is a member of the base ring. - - :: - - sage: f = 2 * x * y - sage: c = f.monomial_coefficient(x*y); c + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = 2 * x * y # optional - sage.rings.number_field + sage: c = f.monomial_coefficient(x*y); c # optional - sage.rings.number_field 2 - sage: c.parent() + sage: c.parent() # optional - sage.rings.number_field Algebraic Field :: - sage: f = y^2 + y^2*x - x^9 - 7*x + 5*x*y - sage: f.monomial_coefficient(y^2) + sage: f = y^2 + y^2*x - x^9 - 7*x + 5*x*y # optional - sage.rings.number_field + sage: f.monomial_coefficient(y^2) # optional - sage.rings.number_field 1 - sage: f.monomial_coefficient(x*y) + sage: f.monomial_coefficient(x*y) # optional - sage.rings.number_field 5 - sage: f.monomial_coefficient(x^9) + sage: f.monomial_coefficient(x^9) # optional - sage.rings.number_field -1 - sage: f.monomial_coefficient(x^10) + sage: f.monomial_coefficient(x^10) # optional - sage.rings.number_field 0 :: - sage: var('a') - a - sage: K. = NumberField(a^2+a+1) - sage: P. = K[] - sage: f=(a*x-1)*((a+1)*y-1); f + sage: a = polygen(ZZ, 'a') + sage: K. = NumberField(a^2 + a + 1) # optional - sage.rings.number_field + sage: P. = K[] # optional - sage.rings.number_field + sage: f = (a*x - 1) * ((a+1)*y - 1); f # optional - sage.rings.number_field -x*y + (-a)*x + (-a - 1)*y + 1 - sage: f.monomial_coefficient(x) + sage: f.monomial_coefficient(x) # optional - sage.rings.number_field -a """ if parent(mon) is not self.parent(): @@ -819,23 +813,23 @@ def __iter__(self): EXAMPLES:: - sage: R. = PolynomialRing(QQbar, order='lex') - sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) - sage: list(f) + sage: R. = PolynomialRing(QQbar, order='lex') # optional - sage.rings.number_field + sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # optional - sage.rings.number_field + sage: list(f) # optional - sage.rings.number_field [(1, x^4*y*z^3), (1, x^2*z), (1, x*y^5*z^2)] :: - sage: R. = PolynomialRing(QQbar, order='deglex') - sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) - sage: list(f) + sage: R. = PolynomialRing(QQbar, order='deglex') # optional - sage.rings.number_field + sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # optional - sage.rings.number_field + sage: list(f) # optional - sage.rings.number_field [(1, x^4*y*z^3), (1, x*y^5*z^2), (1, x^2*z)] :: - sage: R. = PolynomialRing(QQbar, order='degrevlex') - sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) - sage: list(f) + sage: R. = PolynomialRing(QQbar, order='degrevlex') # optional - sage.rings.number_field + sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # optional - sage.rings.number_field + sage: list(f) # optional - sage.rings.number_field [(1, x*y^5*z^2), (1, x^4*y*z^3), (1, x^2*z)] :: @@ -866,22 +860,22 @@ def __getitem__(self, x): EXAMPLES:: - sage: R. = PolynomialRing(QQbar, 2) - sage: f = -10*x^3*y + 17*x*y - sage: f[3,1] + sage: R. = PolynomialRing(QQbar, 2) # optional - sage.rings.number_field + sage: f = -10*x^3*y + 17*x*y # optional - sage.rings.number_field + sage: f[3,1] # optional - sage.rings.number_field -10 - sage: f[1,1] + sage: f[1,1] # optional - sage.rings.number_field 17 - sage: f[0,1] + sage: f[0,1] # optional - sage.rings.number_field 0 :: - sage: R. = PolynomialRing(QQbar,1); R + sage: R. = PolynomialRing(QQbar, 1); R # optional - sage.rings.number_field Multivariate Polynomial Ring in x over Algebraic Field - sage: f = 5*x^2 + 3; f + sage: f = 5*x^2 + 3; f # optional - sage.rings.number_field 5*x^2 + 3 - sage: f[2] + sage: f[2] # optional - sage.rings.number_field 5 """ if isinstance(x, MPolynomial): @@ -907,14 +901,14 @@ def iterator_exp_coeff(self, as_ETuples=True): EXAMPLES:: - sage: R. = PolynomialRing(QQbar, order='lex') - sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) - sage: list(f.iterator_exp_coeff()) + sage: R. = PolynomialRing(QQbar, order='lex') # optional - sage.rings.number_field + sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # optional - sage.rings.number_field + sage: list(f.iterator_exp_coeff()) # optional - sage.rings.number_field [((4, 1, 3), 1), ((2, 0, 1), 1), ((1, 5, 2), 1)] - sage: R. = PolynomialRing(QQbar, order='deglex') - sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) - sage: list(f.iterator_exp_coeff(as_ETuples=False)) + sage: R. = PolynomialRing(QQbar, order='deglex') # optional - sage.rings.number_field + sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # optional - sage.rings.number_field + sage: list(f.iterator_exp_coeff(as_ETuples=False)) # optional - sage.rings.number_field [((4, 1, 3), 1), ((1, 5, 2), 1), ((2, 0, 1), 1)] """ elt = self.element() @@ -950,7 +944,7 @@ def coefficient(self, degrees): - a monomial (very fast, but not as flexible) - OUTPUT: element of the parent of self + OUTPUT: element of the parent of ``self`` .. SEEALSO:: @@ -959,38 +953,38 @@ def coefficient(self, degrees): EXAMPLES:: - sage: R. = QQbar[] - sage: f = 2 * x * y - sage: c = f.coefficient({x:1,y:1}); c + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = 2 * x * y # optional - sage.rings.number_field + sage: c = f.coefficient({x: 1, y: 1}); c # optional - sage.rings.number_field 2 - sage: c.parent() + sage: c.parent() # optional - sage.rings.number_field Multivariate Polynomial Ring in x, y over Algebraic Field - sage: c in PolynomialRing(QQbar, 2, names = ['x','y']) + sage: c in PolynomialRing(QQbar, 2, names=['x', 'y']) # optional - sage.rings.number_field True - sage: f = y^2 - x^9 - 7*x + 5*x*y - sage: f.coefficient({y:1}) + sage: f = y^2 - x^9 - 7*x + 5*x*y # optional - sage.rings.number_field + sage: f.coefficient({y: 1}) # optional - sage.rings.number_field 5*x - sage: f.coefficient({y:0}) + sage: f.coefficient({y: 0}) # optional - sage.rings.number_field -x^9 + (-7)*x - sage: f.coefficient({x:0,y:0}) + sage: f.coefficient({x: 0, y: 0}) # optional - sage.rings.number_field 0 - sage: f=(1+y+y^2)*(1+x+x^2) - sage: f.coefficient({x:0}) + sage: f = (1+y+y^2) * (1+x+x^2) # optional - sage.rings.number_field + sage: f.coefficient({x: 0}) # optional - sage.rings.number_field y^2 + y + 1 - sage: f.coefficient([0,None]) + sage: f.coefficient([0, None]) # optional - sage.rings.number_field y^2 + y + 1 - sage: f.coefficient(x) + sage: f.coefficient(x) # optional - sage.rings.number_field y^2 + y + 1 sage: # Be aware that this may not be what you think! sage: # The physical appearance of the variable x is deceiving -- particularly if the exponent would be a variable. - sage: f.coefficient(x^0) # outputs the full polynomial + sage: f.coefficient(x^0) # outputs the full polynomial # optional - sage.rings.number_field x^2*y^2 + x^2*y + x*y^2 + x^2 + x*y + y^2 + x + y + 1 :: sage: R. = RR[] - sage: f=x*y+5 - sage: c=f.coefficient({x:0,y:0}); c + sage: f = x*y + 5 + sage: c = f.coefficient({x: 0, y: 0}); c 5.00000000000000 sage: parent(c) Multivariate Polynomial Ring in x, y over Real Field with 53 bits of precision @@ -1025,36 +1019,34 @@ def global_height(self, prec=None): INPUT: - ``prec`` -- desired floating point precision (default: - default RealField precision). - - OUTPUT: + default :class:`RealField` precision). - - a real number. + OUTPUT: a real number. EXAMPLES:: - sage: R. = PolynomialRing(QQbar, 2) - sage: f = QQbar(i)*x^2 + 3*x*y - sage: f.global_height() + sage: R. = PolynomialRing(QQbar, 2) # optional - sage.rings.number_field + sage: f = QQbar(i)*x^2 + 3*x*y # optional - sage.rings.number_field + sage: f.global_height() # optional - sage.rings.number_field 1.09861228866811 Scaling should not change the result:: - sage: R. = PolynomialRing(QQbar, 2) - sage: f = 1/25*x^2 + 25/3*x + 1 + QQbar(sqrt(2))*y^2 - sage: f.global_height() + sage: R. = PolynomialRing(QQbar, 2) # optional - sage.rings.number_field + sage: f = 1/25*x^2 + 25/3*x + 1 + QQbar(sqrt(2))*y^2 # optional - sage.rings.number_field sage.symbolic + sage: f.global_height() # optional - sage.rings.number_field sage.symbolic 6.43775164973640 - sage: g = 100 * f - sage: g.global_height() + sage: g = 100 * f # optional - sage.rings.number_field sage.symbolic + sage: g.global_height() # optional - sage.rings.number_field sage.symbolic 6.43775164973640 :: sage: R. = QQ[] - sage: K. = NumberField(x^2 + 1) - sage: Q. = PolynomialRing(K, implementation='generic') - sage: f = 12*q - sage: f.global_height() + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: Q. = PolynomialRing(K, implementation='generic') # optional - sage.rings.number_field + sage: f = 12 * q # optional - sage.rings.number_field + sage: f.global_height() # optional - sage.rings.number_field 0.000000000000000 :: @@ -1107,9 +1099,7 @@ def local_height(self, v, prec=None): - ``prec`` -- desired floating point precision (default: default RealField precision). - OUTPUT: - - - a real number. + OUTPUT: a real number. EXAMPLES:: @@ -1121,11 +1111,11 @@ def local_height(self, v, prec=None): :: sage: R. = QQ[] - sage: K. = NumberField(x^2 - 5) - sage: T. = PolynomialRing(K, implementation='generic') - sage: I = K.ideal(3) - sage: f = 1/3*t*w + 3 - sage: f.local_height(I) + sage: K. = NumberField(x^2 - 5) # optional - sage.rings.number_field + sage: T. = PolynomialRing(K, implementation='generic') # optional - sage.rings.number_field + sage: I = K.ideal(3) # optional - sage.rings.number_field + sage: f = 1/3*t*w + 3 # optional - sage.rings.number_field + sage: f.local_height(I) # optional - sage.rings.number_field sage.symbolic 1.09861228866811 :: @@ -1157,11 +1147,9 @@ def local_height_arch(self, i, prec=None): - ``i`` -- an integer. - ``prec`` -- desired floating point precision (default: - default RealField precision). + default :class:`RealField` precision). - OUTPUT: - - - a real number. + OUTPUT: a real number. EXAMPLES:: @@ -1173,10 +1161,10 @@ def local_height_arch(self, i, prec=None): :: sage: R. = QQ[] - sage: K. = NumberField(x^2 - 5) - sage: T. = PolynomialRing(K, implementation='generic') - sage: f = 1/2*t*w + 3 - sage: f.local_height_arch(1, prec=52) + sage: K. = NumberField(x^2 - 5) # optional - sage.rings.number_field + sage: T. = PolynomialRing(K, implementation='generic') # optional - sage.rings.number_field + sage: f = 1/2*t*w + 3 # optional - sage.rings.number_field + sage: f.local_height_arch(1, prec=52) # optional - sage.rings.number_field 1.09861228866811 :: @@ -1208,9 +1196,9 @@ def _exponents(self): EXAMPLES:: - sage: R. = PolynomialRing(QQbar, 3) - sage: f = a^3 + b + 2*b^2 - sage: f._exponents + sage: R. = PolynomialRing(QQbar, 3) # optional - sage.rings.number_field + sage: f = a^3 + b + 2*b^2 # optional - sage.rings.number_field + sage: f._exponents # optional - sage.rings.number_field [(3, 0, 0), (0, 2, 0), (0, 1, 0)] """ return sorted(self.element().dict(), key=self.parent().term_order().sortkey, reverse=True) @@ -1230,29 +1218,29 @@ def exponents(self, as_ETuples=True): EXAMPLES:: - sage: R. = PolynomialRing(QQbar, 3) - sage: f = a^3 + b + 2*b^2 - sage: f.exponents() + sage: R. = PolynomialRing(QQbar, 3) # optional - sage.rings.number_field + sage: f = a^3 + b + 2*b^2 # optional - sage.rings.number_field + sage: f.exponents() # optional - sage.rings.number_field [(3, 0, 0), (0, 2, 0), (0, 1, 0)] By default the list of exponents is a list of ETuples:: - sage: type(f.exponents()[0]) + sage: type(f.exponents()[0]) # optional - sage.rings.number_field - sage: type(f.exponents(as_ETuples=False)[0]) + sage: type(f.exponents(as_ETuples=False)[0]) # optional - sage.rings.number_field <... 'tuple'> TESTS: Check that we can mutate the list and not change the result:: - sage: R. = PolynomialRing(QQbar, 3) - sage: f = a^3 + b + 2*b^2 - sage: E = f.exponents(); E + sage: R. = PolynomialRing(QQbar, 3) # optional - sage.rings.number_field + sage: f = a^3 + b + 2*b^2 # optional - sage.rings.number_field + sage: E = f.exponents(); E # optional - sage.rings.number_field [(3, 0, 0), (0, 2, 0), (0, 1, 0)] - sage: E.pop() + sage: E.pop() # optional - sage.rings.number_field (0, 1, 0) - sage: E != f.exponents() + sage: E != f.exponents() # optional - sage.rings.number_field True """ if as_ETuples: @@ -1280,22 +1268,22 @@ def inverse_of_unit(self): def is_homogeneous(self): """ - Return True if self is a homogeneous polynomial. + Return ``True`` if ``self`` is a homogeneous polynomial. EXAMPLES:: - sage: R. = QQbar[] - sage: (x+y).is_homogeneous() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: (x + y).is_homogeneous() # optional - sage.rings.number_field True - sage: (x.parent()(0)).is_homogeneous() + sage: (x.parent()(0)).is_homogeneous() # optional - sage.rings.number_field True - sage: (x+y^2).is_homogeneous() + sage: (x + y^2).is_homogeneous() # optional - sage.rings.number_field False - sage: (x^2 + y^2).is_homogeneous() + sage: (x^2 + y^2).is_homogeneous() # optional - sage.rings.number_field True - sage: (x^2 + y^2*x).is_homogeneous() + sage: (x^2 + y^2*x).is_homogeneous() # optional - sage.rings.number_field False - sage: (x^2*y + y^2*x).is_homogeneous() + sage: (x^2*y + y^2*x).is_homogeneous() # optional - sage.rings.number_field True """ return self.element().is_homogeneous() @@ -1317,11 +1305,11 @@ def _homogenize(self, var): EXAMPLES:: - sage: P. = QQbar[] - sage: f = x^2 + y + 1 + 5*x*y^1 - sage: g = f.homogenize('z'); g # indirect doctest + sage: P. = QQbar[] # optional - sage.rings.number_field + sage: f = x^2 + y + 1 + 5*x*y^1 # optional - sage.rings.number_field + sage: g = f.homogenize('z'); g # indirect doctest # optional - sage.rings.number_field x^2 + 5*x*y + y*z + z^2 - sage: g.parent() + sage: g.parent() # optional - sage.rings.number_field Multivariate Polynomial Ring in x, y, z over Algebraic Field SEE: ``self.homogenize`` @@ -1339,12 +1327,12 @@ def is_generator(self): EXAMPLES:: - sage: R.=QQbar[] - sage: x.is_generator() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: x.is_generator() # optional - sage.rings.number_field True - sage: (x+y-y).is_generator() + sage: (x + y - y).is_generator() # optional - sage.rings.number_field True - sage: (x*y).is_generator() + sage: (x*y).is_generator() # optional - sage.rings.number_field False """ elt = self.element() @@ -1362,21 +1350,21 @@ def is_monomial(self): EXAMPLES:: - sage: R.=QQbar[] - sage: x.is_monomial() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: x.is_monomial() # optional - sage.rings.number_field True - sage: (x+2*y).is_monomial() + sage: (x + 2*y).is_monomial() # optional - sage.rings.number_field False - sage: (2*x).is_monomial() + sage: (2*x).is_monomial() # optional - sage.rings.number_field False - sage: (x*y).is_monomial() + sage: (x*y).is_monomial() # optional - sage.rings.number_field True - To allow a non-1 leading coefficient, use is_term():: + To allow a non-1 leading coefficient, use :meth:`is_term`:: - sage: (2*x*y).is_term() + sage: (2*x*y).is_term() # optional - sage.rings.number_field True - sage: (2*x*y).is_monomial() + sage: (2*x*y).is_monomial() # optional - sage.rings.number_field False """ return len(self.element()) == 1 and self.element().coefficients()[0] == 1 @@ -1391,31 +1379,31 @@ def is_term(self): EXAMPLES:: - sage: R.=QQbar[] - sage: x.is_term() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: x.is_term() # optional - sage.rings.number_field True - sage: (x+2*y).is_term() + sage: (x + 2*y).is_term() # optional - sage.rings.number_field False - sage: (2*x).is_term() + sage: (2*x).is_term() # optional - sage.rings.number_field True - sage: (7*x^5*y).is_term() + sage: (7*x^5*y).is_term() # optional - sage.rings.number_field True - To require leading coefficient 1, use is_monomial():: + To require leading coefficient 1, use :meth:`is_monomial`:: - sage: (2*x*y).is_monomial() + sage: (2*x*y).is_monomial() # optional - sage.rings.number_field False - sage: (2*x*y).is_term() + sage: (2*x*y).is_term() # optional - sage.rings.number_field True """ return len(self.element()) == 1 def subs(self, fixed=None, **kw): """ - Fixes some given variables in a given multivariate polynomial and - returns the changed multivariate polynomials. The polynomial itself - is not affected. The variable,value pairs for fixing are to be - provided as a dictionary of the form {variable:value}. + Fix some given variables in a given multivariate polynomial and + return the changed multivariate polynomials. The polynomial itself + is not affected. The variable, value pairs for fixing are to be + provided as a dictionary of the form ``{variable: value}``. This is a special case of evaluating the polynomial with some of the variables constants and the others the original variables. @@ -1428,15 +1416,15 @@ def subs(self, fixed=None, **kw): - ``**kw`` - named parameters - OUTPUT: new MPolynomial + OUTPUT: new :class:`MPolynomial` EXAMPLES:: - sage: R. = QQbar[] - sage: f = x^2 + y + x^2*y^2 + 5 - sage: f((5,y)) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = x^2 + y + x^2*y^2 + 5 # optional - sage.rings.number_field + sage: f((5, y)) # optional - sage.rings.number_field 25*y^2 + y + 30 - sage: f.subs({x:5}) + sage: f.subs({x: 5}) # optional - sage.rings.number_field 25*y^2 + y + 30 """ variables = list(self.parent().gens()) @@ -1449,29 +1437,28 @@ def subs(self, fixed=None, **kw): def monomials(self): """ - Returns the list of monomials in self. The returned list is - decreasingly ordered by the term ordering of self.parent(). + Return the list of monomials in ``self``. The returned list is + decreasingly ordered by the term ordering of ``self.parent()``. - OUTPUT: list of MPolynomials representing Monomials + OUTPUT: list of :class:`MPolynomial` instances, representing monomials EXAMPLES:: - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.monomials() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field + sage: f.monomials() # optional - sage.rings.number_field [x^2*y^2, x^2, y, 1] :: - sage: R. = QQbar[] - sage: F = ((fx*gy - fy*gx)^3) - sage: F + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: F = (fx*gy - fy*gx)^3; F # optional - sage.rings.number_field -fy^3*gx^3 + 3*fx*fy^2*gx^2*gy + (-3)*fx^2*fy*gx*gy^2 + fx^3*gy^3 - sage: F.monomials() + sage: F.monomials() # optional - sage.rings.number_field [fy^3*gx^3, fx*fy^2*gx^2*gy, fx^2*fy*gx*gy^2, fx^3*gy^3] - sage: F.coefficients() + sage: F.coefficients() # optional - sage.rings.number_field [-1, 3, -3, 1] - sage: sum(map(mul,zip(F.coefficients(),F.monomials()))) == F + sage: sum(map(mul, zip(F.coefficients(), F.monomials()))) == F # optional - sage.rings.number_field True """ ring = self.parent() @@ -1485,12 +1472,12 @@ def constant_coefficient(self): EXAMPLES:: - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.constant_coefficient() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field + sage: f.constant_coefficient() # optional - sage.rings.number_field 5 - sage: f = 3*x^2 - sage: f.constant_coefficient() + sage: f = 3*x^2 # optional - sage.rings.number_field + sage: f.constant_coefficient() # optional - sage.rings.number_field 0 """ #v = (0,)*int(self.parent().ngens()) @@ -1502,21 +1489,21 @@ def constant_coefficient(self): def is_univariate(self): """ - Returns True if this multivariate polynomial is univariate and + Return ``True`` if this multivariate polynomial is univariate and False otherwise. EXAMPLES:: - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.is_univariate() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field + sage: f.is_univariate() # optional - sage.rings.number_field False - sage: g = f.subs({x:10}); g + sage: g = f.subs({x: 10}); g # optional - sage.rings.number_field 700*y^2 + (-2)*y + 305 - sage: g.is_univariate() + sage: g.is_univariate() # optional - sage.rings.number_field True - sage: f = x^0 - sage: f.is_univariate() + sage: f = x^0 # optional - sage.rings.number_field + sage: f.is_univariate() # optional - sage.rings.number_field True """ mons = self.element().dict() @@ -1539,27 +1526,27 @@ def univariate_polynomial(self, R=None): INPUT: - - ``R`` - (default: None) PolynomialRing + - ``R`` - (default: None) :class:`PolynomialRing` If this polynomial is not in at most one variable, then a - ValueError exception is raised. This is checked using the - is_univariate() method. The new Polynomial is over the same base - ring as the given MPolynomial. + :class:`ValueError` exception is raised. This is checked using the + method :meth:`is_univariate`. The new :class:`Polynomial` is over the same base + ring as the given :class:`MPolynomial`. EXAMPLES:: - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.univariate_polynomial() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field + sage: f.univariate_polynomial() # optional - sage.rings.number_field Traceback (most recent call last): ... TypeError: polynomial must involve at most one variable - sage: g = f.subs({x:10}); g + sage: g = f.subs({x: 10}); g # optional - sage.rings.number_field 700*y^2 + (-2)*y + 305 - sage: g.univariate_polynomial () + sage: g.univariate_polynomial() # optional - sage.rings.number_field 700*y^2 - 2*y + 305 - sage: g.univariate_polynomial(PolynomialRing(QQ,'z')) + sage: g.univariate_polynomial(PolynomialRing(QQ, 'z')) # optional - sage.rings.number_field 700*z^2 - 2*z + 305 TESTS:: @@ -1614,13 +1601,13 @@ def variables(self): EXAMPLES:: - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.variables() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field + sage: f.variables() # optional - sage.rings.number_field (x, y) - sage: g = f.subs({x:10}); g + sage: g = f.subs({x: 10}); g # optional - sage.rings.number_field 700*y^2 + (-2)*y + 305 - sage: g.variables() + sage: g.variables() # optional - sage.rings.number_field (y,) TESTS: @@ -1635,32 +1622,32 @@ def variables(self): def variable(self,i): """ - Returns `i`-th variable occurring in this polynomial. + Return the `i`-th variable occurring in this polynomial. EXAMPLES:: - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.variable(0) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field + sage: f.variable(0) # optional - sage.rings.number_field x - sage: f.variable(1) + sage: f.variable(1) # optional - sage.rings.number_field y """ return self.variables()[int(i)] def nvariables(self): """ - Number of variables in this polynomial + Return the number of variables in this polynomial. EXAMPLES:: - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.nvariables () + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field + sage: f.nvariables() # optional - sage.rings.number_field 2 - sage: g = f.subs({x:10}); g + sage: g = f.subs({x: 10}); g # optional - sage.rings.number_field 700*y^2 + (-2)*y + 305 - sage: g.nvariables () + sage: g.nvariables() # optional - sage.rings.number_field 1 """ return len(self.degrees().nonzero_positions()) @@ -1671,32 +1658,32 @@ def is_constant(self): EXAMPLES:: - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.is_constant() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field + sage: f.is_constant() # optional - sage.rings.number_field False - sage: g = 10*x^0 - sage: g.is_constant() + sage: g = 10*x^0 # optional - sage.rings.number_field + sage: g.is_constant() # optional - sage.rings.number_field True """ return self.element().is_constant() def lm(self): """ - Returns the lead monomial of self with respect to the term order of - self.parent(). + Return the lead monomial of ``self`` with respect to the term order of + ``self.parent()``. EXAMPLES:: - sage: R.=PolynomialRing(GF(7),3,order='lex') - sage: (x^1*y^2 + y^3*z^4).lm() + sage: R. = PolynomialRing(GF(7), 3, order='lex') # optional - sage.rings.finite_rings + sage: (x^1*y^2 + y^3*z^4).lm() # optional - sage.rings.finite_rings x*y^2 - sage: (x^3*y^2*z^4 + x^3*y^2*z^1).lm() + sage: (x^3*y^2*z^4 + x^3*y^2*z^1).lm() # optional - sage.rings.finite_rings x^3*y^2*z^4 :: - sage: R.=PolynomialRing(CC,3,order='deglex') + sage: R. = PolynomialRing(CC, 3, order='deglex') sage: (x^1*y^2*z^3 + x^3*y^2*z^0).lm() x*y^2*z^3 sage: (x^1*y^2*z^4 + x^1*y^1*z^5).lm() @@ -1704,18 +1691,18 @@ def lm(self): :: - sage: R.=PolynomialRing(QQbar,3,order='degrevlex') - sage: (x^1*y^5*z^2 + x^4*y^1*z^3).lm() + sage: R. = PolynomialRing(QQbar, 3, order='degrevlex') # optional - sage.rings.number_field + sage: (x^1*y^5*z^2 + x^4*y^1*z^3).lm() # optional - sage.rings.number_field x*y^5*z^2 - sage: (x^4*y^7*z^1 + x^4*y^2*z^3).lm() + sage: (x^4*y^7*z^1 + x^4*y^2*z^3).lm() # optional - sage.rings.number_field x^4*y^7*z TESTS:: sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict - sage: R.=MPolynomialRing_polydict(GF(2),2,order='lex') - sage: f=x+y - sage: f.lm() + sage: R. = MPolynomialRing_polydict(GF(2), 2, order='lex') # optional - sage.rings.finite_rings + sage: f = x + y # optional - sage.rings.finite_rings + sage: f.lm() # optional - sage.rings.finite_rings x """ @@ -1732,14 +1719,14 @@ def lm(self): def lc(self): """ - Returns the leading coefficient of self i.e., - self.coefficient(self.lm()) + Returns the leading coefficient of ``self``, i.e., + ``self.coefficient(self.lm())`` EXAMPLES:: - sage: R.=QQbar[] - sage: f=3*x^2-y^2-x*y - sage: f.lc() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = 3*x^2 - y^2 - x*y # optional - sage.rings.number_field + sage: f.lc() # optional - sage.rings.number_field 3 """ try: @@ -1754,27 +1741,27 @@ def lc(self): def lt(self): r""" - Returns the leading term of self i.e., self.lc()\*self.lm(). The + Return the leading term of ``self`` i.e., ``self.lc()*self.lm()``. The notion of "leading term" depends on the ordering defined in the parent ring. EXAMPLES:: - sage: R.=PolynomialRing(QQbar) - sage: f=3*x^2-y^2-x*y - sage: f.lt() + sage: R. = PolynomialRing(QQbar) # optional - sage.rings.number_field + sage: f = 3*x^2 - y^2 - x*y # optional - sage.rings.number_field + sage: f.lt() # optional - sage.rings.number_field 3*x^2 - sage: R.=PolynomialRing(QQbar,order="invlex") - sage: f=3*x^2-y^2-x*y - sage: f.lt() + sage: R. = PolynomialRing(QQbar, order="invlex") # optional - sage.rings.number_field + sage: f = 3*x^2 - y^2 - x*y # optional - sage.rings.number_field + sage: f.lt() # optional - sage.rings.number_field -y^2 TESTS:: sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict - sage: R.=MPolynomialRing_polydict(GF(2),2,order='lex') - sage: f=x+y - sage: f.lt() + sage: R. = MPolynomialRing_polydict(GF(2), 2, order='lex') # optional - sage.rings.finite_rings + sage: f = x + y # optional - sage.rings.finite_rings + sage: f.lt() # optional - sage.rings.finite_rings x """ try: @@ -1809,7 +1796,7 @@ def __ne__(self, right): def __bool__(self): """ - Return True if self != 0 + Return ``True`` if self != 0 .. note:: @@ -1819,7 +1806,7 @@ def __bool__(self): def _floordiv_(self, right): r""" - Quotient of division of self by other. This is denoted //. + Quotient of division of ``self`` by other. This is denoted //. .. note:: @@ -1828,14 +1815,14 @@ def _floordiv_(self, right): EXAMPLES:: - sage: R.=QQbar[] - sage: 2*x*y//y + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: 2*x*y//y # optional - sage.rings.number_field 2*x - sage: 2*x//y + sage: 2*x//y # optional - sage.rings.number_field 0 - sage: 2*x//4 + sage: 2*x//4 # optional - sage.rings.number_field 1/2*x - sage: type(0//y) + sage: type(0//y) # optional - sage.rings.number_field """ # handle division by monomials without using Singular @@ -1856,7 +1843,7 @@ def _derivative(self, var=None): r""" Differentiates ``self`` with respect to variable ``var``. - If ``var`` is not one of the generators of this ring, _derivative(var) + If ``var`` is not one of the generators of this ring, ``_derivative(var)`` is called recursively on each coefficient of this polynomial. .. SEEALSO:: @@ -1865,24 +1852,26 @@ def _derivative(self, var=None): EXAMPLES:: - sage: R. = PowerSeriesRing(QQbar) - sage: S. = PolynomialRing(R) - sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3 - sage: f.parent() - Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field - sage: f._derivative(x) # with respect to x + sage: R. = PowerSeriesRing(QQbar) # optional - sage.rings.number_field + sage: S. = PolynomialRing(R) # optional - sage.rings.number_field + sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3 # optional - sage.rings.number_field + sage: f.parent() # optional - sage.rings.number_field + Multivariate Polynomial Ring in x, y + over Power Series Ring in t over Algebraic Field + sage: f._derivative(x) # with respect to x # optional - sage.rings.number_field (2*t^2 + O(t^3))*x*y^3 + (111*t^4 + O(t^5))*x^2 - sage: f._derivative(x).parent() - Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field - sage: f._derivative(y) # with respect to y + sage: f._derivative(x).parent() # optional - sage.rings.number_field + Multivariate Polynomial Ring in x, y + over Power Series Ring in t over Algebraic Field + sage: f._derivative(y) # with respect to y # optional - sage.rings.number_field (3*t^2 + O(t^3))*x^2*y^2 - sage: f._derivative(t) # with respect to t (recurses into base ring) + sage: f._derivative(t) # with respect to t (recurses into base ring) # optional - sage.rings.number_field (2*t + O(t^2))*x^2*y^3 + (148*t^3 + O(t^4))*x^3 - sage: f._derivative(x)._derivative(y) # with respect to x and then y + sage: f._derivative(x)._derivative(y) # with respect to x and then y # optional - sage.rings.number_field (6*t^2 + O(t^3))*x*y^2 - sage: f.derivative(y, 3) # with respect to y three times + sage: f.derivative(y, 3) # with respect to y three times # optional - sage.rings.number_field (6*t^2 + O(t^3))*x^2 - sage: f._derivative() # can't figure out the variable + sage: f._derivative() # can't figure out the variable # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: must specify which variable to differentiate with respect to @@ -1915,7 +1904,7 @@ def integral(self, var=None): The integral is always chosen so the constant term is 0. - If ``var`` is not one of the generators of this ring, integral(var) + If ``var`` is not one of the generators of this ring, ``integral(var)`` is called recursively on each coefficient of this polynomial. EXAMPLES: @@ -1932,28 +1921,31 @@ def integral(self, var=None): sage: R = ZZ['x']['y, z'] sage: y, z = R.gens() sage: R.an_element().integral(y).parent() - Multivariate Polynomial Ring in y, z over Univariate Polynomial Ring in x over Rational Field + Multivariate Polynomial Ring in y, z + over Univariate Polynomial Ring in x over Rational Field On polynomials with coefficients in power series:: - sage: R. = PowerSeriesRing(QQbar) - sage: S. = PolynomialRing(R) - sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3 - sage: f.parent() - Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field - sage: f.integral(x) # with respect to x + sage: R. = PowerSeriesRing(QQbar) # optional - sage.rings.number_field + sage: S. = PolynomialRing(R) # optional - sage.rings.number_field + sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3 # optional - sage.rings.number_field + sage: f.parent() # optional - sage.rings.number_field + Multivariate Polynomial Ring in x, y + over Power Series Ring in t over Algebraic Field + sage: f.integral(x) # with respect to x # optional - sage.rings.number_field (1/3*t^2 + O(t^3))*x^3*y^3 + (37/4*t^4 + O(t^5))*x^4 - sage: f.integral(x).parent() - Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field + sage: f.integral(x).parent() # optional - sage.rings.number_field + Multivariate Polynomial Ring in x, y + over Power Series Ring in t over Algebraic Field - sage: f.integral(y) # with respect to y + sage: f.integral(y) # with respect to y # optional - sage.rings.number_field (1/4*t^2 + O(t^3))*x^2*y^4 + (37*t^4 + O(t^5))*x^3*y - sage: f.integral(t) # with respect to t (recurses into base ring) + sage: f.integral(t) # with respect to t (recurses into base ring) # optional - sage.rings.number_field (1/3*t^3 + O(t^4))*x^2*y^3 + (37/5*t^5 + O(t^6))*x^3 TESTS:: - sage: f.integral() # can't figure out the variable + sage: f.integral() # can't figure out the variable # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: must specify which variable to integrate with respect to @@ -2005,7 +1997,7 @@ def factor(self, proof=None): INPUT: - - ``proof'' - insist on provably correct results (default: ``True`` + - ``proof`` - insist on provably correct results (default: ``True`` unless explicitly disabled for the ``"polynomial"`` subsystem with :class:`sage.structure.proof.proof.WithProof`.) @@ -2044,8 +2036,8 @@ def factor(self, proof=None): Check that we can factor over the algebraic field (:trac:`25390`):: - sage: R. = PolynomialRing(QQbar) - sage: factor(x^2 + y^2) + sage: R. = PolynomialRing(QQbar) # optional - sage.rings.number_field + sage: factor(x^2 + y^2) # optional - sage.rings.number_field (x + (-1*I)*y) * (x + 1*I*y) Check that the global proof flag for polynomials is honored:: @@ -2095,12 +2087,12 @@ def factor(self, proof=None): We check a case that failed with an exception at some point:: - sage: k. = GF(4) - sage: R. = k[] - sage: l. = R.quo(v^3 + v + 1) - sage: R. = l[] - sage: f = y^3 + x^3 + (u + 1)*x - sage: f.factor() + sage: k. = GF(4) # optional - sage.rings.finite_rings + sage: R. = k[] # optional - sage.rings.finite_rings + sage: l. = R.quo(v^3 + v + 1) # optional - sage.rings.finite_rings + sage: R. = l[] # optional - sage.rings.finite_rings + sage: f = y^3 + x^3 + (u + 1)*x # optional - sage.rings.finite_rings + sage: f.factor() # optional - sage.rings.finite_rings x^3 + y^3 + (u + 1)*x """ @@ -2159,15 +2151,15 @@ def factor(self, proof=None): @handle_AA_and_QQbar def lift(self,I): """ - given an ideal I = (f_1,...,f_r) and some g (== self) in I, find - s_1,...,s_r such that g = s_1 f_1 + ... + s_r f_r + Given an ideal `I = (f_1,...,f_r)` and some `g` (= ``self``) in `I`, find + `s_1,...,s_r` such that `g = s_1 f_1 + ... + s_r f_r`. ALGORITHM: Use Singular. EXAMPLES:: - sage: A. = PolynomialRing(CC,2,order='degrevlex') - sage: I = A.ideal([x^10 + x^9*y^2, y^8 - x^2*y^7 ]) + sage: A. = PolynomialRing(CC, 2, order='degrevlex') + sage: I = A.ideal([x^10 + x^9*y^2, y^8 - x^2*y^7]) sage: f = x*y^13 + y^12 sage: M = f.lift(I) sage: M @@ -2177,13 +2169,13 @@ def lift(self,I): TESTS: - Check that this method works over QQbar (:trac:`25351`):: + Check that this method works over ``QQbar`` (:trac:`25351`):: - sage: A. = QQbar[] - sage: I = A.ideal([x^2 + y^2 - 1, x^2 - y^2]) - sage: f = 2*x^2 - 1 - sage: M = f.lift(I) - sage: sum( map( mul , zip( M, I.gens() ) ) ) == f + sage: A. = QQbar[] # optional - sage.rings.number_field + sage: I = A.ideal([x^2 + y^2 - 1, x^2 - y^2]) # optional - sage.rings.number_field + sage: f = 2*x^2 - 1 # optional - sage.rings.number_field + sage: M = f.lift(I) # optional - sage.rings.number_field + sage: sum(map(mul, zip(M, I.gens()))) == f # optional - sage.rings.number_field True """ fs = self._singular_() @@ -2199,7 +2191,7 @@ def lift(self,I): @handle_AA_and_QQbar def quo_rem(self, right): """ - Returns quotient and remainder of self and right. + Returns quotient and remainder of ``self`` and ``right``. EXAMPLES:: @@ -2224,11 +2216,11 @@ def quo_rem(self, right): TESTS: - Check that this method works over QQbar (:trac:`25351`):: + Check that this method works over ``QQbar`` (:trac:`25351`):: - sage: R. = QQbar[] - sage: f = y*x^2 + x + 1 - sage: f.quo_rem(x) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = y*x^2 + x + 1 # optional - sage.rings.number_field + sage: f.quo_rem(x) # optional - sage.rings.number_field (x*y + 1, 1) """ R = self.parent() @@ -2270,9 +2262,9 @@ def resultant(self, other, variable=None): sage: P. = PolynomialRing(QQ, 2) sage: a = x + y sage: b = x^3 - y^3 - sage: a.resultant(b) + sage: a.resultant(b) # optional - sage.libs.singular -2*y^3 - sage: a.resultant(b, y) + sage: a.resultant(b, y) # optional - sage.libs.singular 2*x^3 TESTS:: @@ -2281,15 +2273,15 @@ def resultant(self, other, variable=None): sage: P. = MPolynomialRing_polydict_domain(QQ, 2, order='degrevlex') sage: a = x + y sage: b = x^3 - y^3 - sage: a.resultant(b) + sage: a.resultant(b) # optional - sage.libs.singular -2*y^3 - sage: a.resultant(b, y) + sage: a.resultant(b, y) # optional - sage.libs.singular 2*x^3 Check that :trac:`15061` is fixed:: - sage: R. = AA[] - sage: (x^2 + 1).resultant(x^2 - y) + sage: R. = AA[] # optional - sage.rings.number_field + sage: (x^2 + 1).resultant(x^2 - y) # optional - sage.rings.number_field y^2 + 2*y + 1 Test for :trac:`2693`:: @@ -2297,17 +2289,17 @@ def resultant(self, other, variable=None): sage: R. = RR[] sage: p = x + y sage: q = x*y - sage: p.resultant(q) + sage: p.resultant(q) # optional - sage.libs.singular -y^2 Check that this method works over QQbar (:trac:`25351`):: - sage: P. = QQbar[] - sage: a = x + y - sage: b = x^3 - y^3 - sage: a.resultant(b) + sage: P. = QQbar[] # optional - sage.rings.number_field + sage: a = x + y # optional - sage.rings.number_field + sage: b = x^3 - y^3 # optional - sage.rings.number_field + sage: a.resultant(b) # optional - sage.rings.number_field (-2)*y^3 - sage: a.resultant(b, y) + sage: a.resultant(b, y) # optional - sage.rings.number_field 2*x^3 """ R = self.parent() @@ -2337,13 +2329,13 @@ def subresultants(self, other, variable=None): EXAMPLES:: - 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) - sage: p.subresultants(q, y) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: p = (y^2 + 6)*(x - 1) - y*(x^2 + 1) # optional - sage.rings.number_field + sage: q = (x^2 + 6)*(y - 1) - x*(y^2 + 1) # optional - sage.rings.number_field + sage: p.subresultants(q, y) # optional - sage.rings.number_field [2*x^6 + (-22)*x^5 + 102*x^4 + (-274)*x^3 + 488*x^2 + (-552)*x + 288, -x^3 - x^2*y + 6*x^2 + 5*x*y + (-11)*x + (-6)*y + 6] - sage: p.subresultants(q, x) + sage: p.subresultants(q, x) # optional - sage.rings.number_field [2*y^6 + (-22)*y^5 + 102*y^4 + (-274)*y^3 + 488*y^2 + (-552)*y + 288, x*y^2 + y^3 + (-5)*x*y + (-6)*y^2 + 6*x + 11*y - 6] @@ -2367,48 +2359,48 @@ def reduce(self, I): EXAMPLES:: - sage: P. = QQbar[] - sage: f1 = -2 * x^2 + x^3 - sage: f2 = -2 * y + x* y - 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: P. = QQbar[] # optional - sage.rings.number_field + sage: f1 = -2 * x^2 + x^3 # optional - sage.rings.number_field + sage: f2 = -2 * y + x * y # optional - sage.rings.number_field + sage: f3 = -x^2 + y^2 # optional - sage.rings.number_field + sage: F = Ideal([f1, f2, f3]) # optional - sage.rings.number_field + sage: g = x*y - 3*x*y^2 # optional - sage.rings.number_field + sage: g.reduce(F) # optional - sage.rings.number_field (-6)*y^2 + 2*y - sage: g.reduce(F.gens()) + sage: g.reduce(F.gens()) # optional - sage.rings.number_field (-6)*y^2 + 2*y :: - sage: f = 3*x - sage: f.reduce([2*x,y]) + sage: f = 3*x # optional - sage.rings.number_field + sage: f.reduce([2*x, y]) # optional - sage.rings.number_field 0 :: - sage: k. = CyclotomicField(3) - sage: A. = PolynomialRing(k) - sage: J = [ y9 + y12] - sage: f = y9 - y12; f.reduce(J) + sage: k. = CyclotomicField(3) # optional - sage.rings.number_field + sage: A. = PolynomialRing(k) # optional - sage.rings.number_field + sage: J = [y9 + y12] # optional - sage.rings.number_field + sage: f = y9 - y12; f.reduce(J) # optional - sage.rings.number_field -2*y12 - sage: f = y13*y15; f.reduce(J) + sage: f = y13*y15; f.reduce(J) # optional - sage.rings.number_field y13*y15 - sage: f = y13*y15 + y9 - y12; f.reduce(J) + sage: f = y13*y15 + y9 - y12; f.reduce(J) # optional - sage.rings.number_field y13*y15 - 2*y12 Make sure the remainder returns the correct type, fixing :trac:`13903`:: - sage: R.=PolynomialRing(Qp(5),2, order='lex') - sage: G=[y1^2 + y2^2, y1*y2 + y2^2, y2^3] - sage: type((y2^3).reduce(G)) + sage: R. = PolynomialRing(Qp(5), 2, order='lex') # optional - sage.rings.padics + sage: G = [y1^2 + y2^2, y1*y2 + y2^2, y2^3] # optional - sage.rings.padics + sage: type((y2^3).reduce(G)) # optional - sage.rings.padics TESTS: Verify that :trac:`34105` is fixed:: - sage: R. = AA[] - sage: x.reduce(R.zero_ideal()) + sage: R. = AA[] # optional - sage.rings.number_field + sage: x.reduce(R.zero_ideal()) # optional - sage.rings.number_field x """ from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal @@ -2455,30 +2447,28 @@ def reduce(self, I): def degree_lowest_rational_function(r, x): r""" - Return the difference of valuations of r with respect to variable x. + Return the difference of valuations of ``r`` with respect to variable ``x``. INPUT: - ``r`` -- a multivariate rational function - - ``x`` -- a multivariate polynomial ring generator x - - OUTPUT: + - ``x`` -- a multivariate polynomial ring generator - - ``integer`` -- the difference val_x(p) - val_x(q) where r = p/q + OUTPUT: integer -- the difference `val_x(p) - val_x(q)` where `r = p/q` .. NOTE:: This function should be made a method of the - FractionFieldElement class. + :class:`FractionFieldElement` class. EXAMPLES:: - sage: R1 = PolynomialRing(FiniteField(5), 3, names = ["a","b","c"]) - sage: F = FractionField(R1) - sage: a,b,c = R1.gens() - sage: f = 3*a*b^2*c^3+4*a*b*c - sage: g = a^2*b*c^2+2*a^2*b^4*c^7 + sage: R1 = PolynomialRing(FiniteField(5), 3, names=["a", "b", "c"]) # optional - sage.rings.finite_rings + sage: F = FractionField(R1) # optional - sage.rings.finite_rings + sage: a,b,c = R1.gens() # optional - sage.rings.finite_rings + sage: f = 3*a*b^2*c^3 + 4*a*b*c # optional - sage.rings.finite_rings + sage: g = a^2*b*c^2 + 2*a^2*b^4*c^7 # optional - sage.rings.finite_rings Consider the quotient `f/g = \frac{4 + 3 bc^{2}}{ac + 2 ab^{3}c^{6}}` (note the @@ -2486,13 +2476,13 @@ def degree_lowest_rational_function(r, x): :: - sage: r = f/g; r + sage: r = f/g; r # optional - sage.rings.finite_rings (-2*b*c^2 - 1)/(2*a*b^3*c^6 + a*c) - sage: degree_lowest_rational_function(r,a) + sage: degree_lowest_rational_function(r, a) # optional - sage.rings.finite_rings -1 - sage: degree_lowest_rational_function(r,b) + sage: degree_lowest_rational_function(r, b) # optional - sage.rings.finite_rings 0 - sage: degree_lowest_rational_function(r,c) + sage: degree_lowest_rational_function(r, c) # optional - sage.rings.finite_rings -1 """ from sage.rings.fraction_field import FractionField diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 49d603599e3..47f14f96229 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.singular r""" Ideals in multivariate polynomial rings @@ -11,7 +12,7 @@ EXAMPLES: We compute a Groebner basis for some given ideal. The type returned by -the ``groebner_basis`` method is ``PolynomialSequence``, i.e. it is not a +the ``groebner_basis`` method is ``PolynomialSequence``, i.e., it is not a :class:`MPolynomialIdeal`:: sage: x,y,z = QQ['x,y,z'].gens() @@ -144,42 +145,43 @@ surprising as there are 4 equations in 3 unknowns). :: sage: P. = PolynomialRing(ZZ,order='lex') - sage: I = ideal(-y^2 - 3*y + z^2 + 3, -2*y*z + z^2 + 2*z + 1, \ - x*z + y*z + z^2, -3*x*y + 2*y*z + 6*z^2) + sage: I = ideal(-y^2 - 3*y + z^2 + 3, -2*y*z + z^2 + 2*z + 1, + ....: x*z + y*z + z^2, -3*x*y + 2*y*z + 6*z^2) sage: I.change_ring(P.change_ring(QQ)).groebner_basis() [1] - However, when we compute the Groebner basis of I (defined over + 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: I.groebner_basis() - [x + y + 57119*z + 4, y^2 + 3*y + 17220, y*z + ..., 2*y + 158864, z^2 + 17223, 2*z + 41856, 164878] + [x + y + 57119*z + 4, y^2 + 3*y + 17220, y*z + ..., + 2*y + 158864, z^2 + 17223, 2*z + 41856, 164878] Now for each prime `p` dividing this integer 164878, the Groebner - basis of I modulo `p` will be non-trivial and will thus give a + basis of `I` modulo `p` will be non-trivial and will thus give a solution of the original system modulo `p`. :: sage: factor(164878) 2 * 7 * 11777 - sage: I.change_ring(P.change_ring( GF(2) )).groebner_basis() + sage: I.change_ring(P.change_ring(GF(2))).groebner_basis() # optional - sage.rings.finite_rings [x + y + z, y^2 + y, y*z + y, z^2 + 1] - sage: I.change_ring(P.change_ring( GF(7) )).groebner_basis() + sage: I.change_ring(P.change_ring(GF(7))).groebner_basis() # optional - sage.rings.finite_rings [x - 1, y + 3, z - 2] - sage: I.change_ring(P.change_ring( GF(11777 ))).groebner_basis() + sage: I.change_ring(P.change_ring(GF(11777))).groebner_basis() # optional - sage.rings.finite_rings [x + 5633, y - 3007, z - 2626] The Groebner basis modulo any product of the prime factors is also non-trivial:: - sage: I.change_ring(P.change_ring( IntegerModRing(2*7) )).groebner_basis() + sage: I.change_ring(P.change_ring(IntegerModRing(2 * 7))).groebner_basis() [x + 9*y + 13*z, y^2 + 3*y, y*z + 7*y + 6, 2*y + 6, z^2 + 3, 2*z + 10] 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() # optional - sage.rings.finite_rings [1] TESTS:: @@ -301,7 +303,7 @@ def __call__(self, *args, **kwds): def is_MPolynomialIdeal(x): """ - Return ``True`` if the provided argument ``x`` is an ideal in the + Return ``True`` if the provided argument ``x`` is an ideal in a multivariate polynomial ring. INPUT: @@ -341,9 +343,9 @@ def _magma_init_(self, magma): EXAMPLES:: - sage: R. = PolynomialRing(GF(127),10) - sage: I = sage.rings.ideal.Cyclic(R,4) # indirect doctest - sage: magma(I) # optional - magma + sage: R. = PolynomialRing(GF(127),10) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Cyclic(R,4) # indirect doctest # optional - sage.rings.finite_rings + sage: magma(I) # optional - magma # optional - sage.rings.finite_rings Ideal of Polynomial ring of rank 10 over GF(127) Order: Graded Reverse Lexicographical Variables: a, b, c, d, e, f, g, h, i, j @@ -378,18 +380,18 @@ def _groebner_basis_magma(self, deg_bound=None, prot=False, magma=magma_default) EXAMPLES:: - sage: R. = PolynomialRing(GF(127),10) - sage: I = sage.rings.ideal.Cyclic(R,6) - sage: gb = I.groebner_basis('magma:GroebnerBasis') # indirect doctest; optional - magma - sage: len(gb) # optional - magma + sage: R. = PolynomialRing(GF(127), 10) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Cyclic(R, 6) # optional - sage.rings.finite_rings + sage: gb = I.groebner_basis('magma:GroebnerBasis') # indirect doctest; optional - magma sage.rings.finite_rings + sage: len(gb) # optional - magma # optional - sage.rings.finite_rings 45 We may also pass a degree bound to Magma:: - sage: R. = PolynomialRing(GF(127),10) - sage: I = sage.rings.ideal.Cyclic(R,6) - sage: gb = I.groebner_basis('magma:GroebnerBasis', deg_bound=4) # indirect doctest; optional - magma - sage: len(gb) # optional - magma + sage: R. = PolynomialRing(GF(127), 10) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Cyclic(R, 6) # optional - sage.rings.finite_rings + sage: gb = I.groebner_basis('magma:GroebnerBasis', deg_bound=4) # indirect doctest; optional - magma # optional - sage.rings.finite_rings + sage: len(gb) # optional - magma # optional - sage.rings.finite_rings 5 """ R = self.ring() @@ -726,7 +728,7 @@ def complete_primary_decomposition(self, algorithm="sy"): `b^n \in Q` for some `n \in \ZZ`. If `Q` is a primary ideal of the ring `R`, then the radical - ideal `P` of `Q` (i.e. the ideal consisting of all `a \in R` + ideal `P` of `Q` (i.e., the ideal consisting of all `a \in R` with a^n \in Q` for some `n \in \ZZ`), is called the associated prime of `Q`. @@ -760,7 +762,7 @@ def complete_primary_decomposition(self, algorithm="sy"): sage: R. = PolynomialRing(QQ, 3, order='lex') sage: p = z^2 + 1; q = z^3 + 2 - sage: I = (p*q^2, y-z^2)*R + sage: I = (p*q^2, y - z^2) * R sage: pd = I.complete_primary_decomposition(); sorted(pd, key=str) [(Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over Rational Field, Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over Rational Field), @@ -839,8 +841,8 @@ def primary_decomposition(self, algorithm='sy'): `b^n \in Q` for some `n \in \ZZ`. If `Q` is a primary ideal of the ring `R`, then the radical - ideal `P` of `Q` (i.e. the ideal consisting of all `a \in R` - with a^n \in Q` for some `n \in \ZZ`), is called the + ideal `P` of `Q` (i.e., the ideal consisting of all `a \in R` + with `a^n \in Q` for some `n \in \ZZ`), is called the associated prime of `Q`. If `I` is a proper ideal of a Noetherian ring `R`, then there @@ -872,15 +874,17 @@ def primary_decomposition(self, algorithm='sy'): sage: R. = PolynomialRing(QQ, 3, order='lex') sage: p = z^2 + 1; q = z^3 + 2 - sage: I = (p*q^2, y-z^2)*R + sage: I = (p*q^2, y - z^2) * R sage: pd = I.primary_decomposition(); sorted(pd, key=str) - [Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over Rational Field, - Ideal (z^6 + 4*z^3 + 4, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field] + [Ideal (z^2 + 1, y + 1) + of Multivariate Polynomial Ring in x, y, z over Rational Field, + Ideal (z^6 + 4*z^3 + 4, y - z^2) + of Multivariate Polynomial Ring in x, y, z over Rational Field] :: sage: from functools import reduce - sage: reduce(lambda Qi,Qj: Qi.intersection(Qj), pd) == I + sage: reduce(lambda Qi, Qj: Qi.intersection(Qj), pd) == I True ALGORITHM: @@ -929,22 +933,20 @@ def associated_primes(self, algorithm='sy'): INPUT: - - ``algorithm`` - string: - - - ``'sy'`` - (default) use the Shimoyama-Yokoyama algorithm + - ``algorithm`` -- string: - - ``'gtz'`` - use the Gianni-Trager-Zacharias algorithm + - ``'sy'`` -- (default) use the Shimoyama-Yokoyama algorithm + - ``'gtz'`` -- use the Gianni-Trager-Zacharias algorithm - OUTPUT: - - ``list`` - a list of associated primes + OUTPUT: a list of associated primes EXAMPLES:: sage: R. = PolynomialRing(QQ, 3, order='lex') sage: p = z^2 + 1; q = z^3 + 2 - sage: I = (p*q^2, y-z^2)*R + sage: I = (p*q^2, y - z^2) * R sage: pd = I.associated_primes(); sorted(pd, key=str) [Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over Rational Field, Ideal (z^3 + 2, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field] @@ -968,19 +970,19 @@ def is_prime(self, **kwds): INPUT: - keyword arguments are passed on to - ``complete_primary_decomposition``; in this way you can + :meth:`complete_primary_decomposition`; in this way you can specify the algorithm to use. EXAMPLES:: sage: R. = PolynomialRing(QQ, 2) - sage: I = (x^2 - y^2 - 1)*R + sage: I = (x^2 - y^2 - 1) * R sage: I.is_prime() True sage: (I^2).is_prime() False - sage: J = (x^2 - y^2)*R + sage: J = (x^2 - y^2) * R sage: J.is_prime() False sage: (J^3).is_prime() @@ -994,9 +996,12 @@ def is_prime(self, **kwds): fraction field is not the quotient ring itself:: sage: Q = R.quotient(I); Q - Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 - y^2 - 1) + Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x^2 - y^2 - 1) sage: Q.fraction_field() - Fraction Field of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 - y^2 - 1) + Fraction Field of + Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x^2 - y^2 - 1) """ if not self.ring().base_ring().is_field(): raise NotImplementedError @@ -1016,7 +1021,7 @@ def triangular_decomposition(self, algorithm=None, singular=singular_default): sets. This requires that the given basis is reduced w.r.t. to the - lexicographical monomial ordering. If the basis of self does + lexicographical monomial ordering. If the basis of ``self`` does not have this property, the required Groebner basis is computed implicitly. @@ -1026,14 +1031,14 @@ def triangular_decomposition(self, algorithm=None, singular=singular_default): ALGORITHMS: - - ``singular:triangL`` - decomposition of self into triangular + - ``"singular:triangL"`` - decomposition of ``self`` into triangular systems (Lazard). - - ``singular:triangLfak`` - decomp. of self into tri. systems + - ``"singular:triangLfak"`` - decomposition of ``self`` into triangular systems plus factorization. - - ``singular:triangM`` - decomposition of self into - triangular systems (Moeller). + - ``"singular:triangM"`` - decomposition of ``self`` into + triangular systems (Moeller). OUTPUT: a list `T` of lists `t` such that the variety of ``self`` is the union of the varieties of `t` in `L` and each @@ -1041,23 +1046,38 @@ def triangular_decomposition(self, algorithm=None, singular=singular_default): EXAMPLES:: - sage: P. = PolynomialRing(QQ,5,order='lex') + sage: P. = PolynomialRing(QQ, 5, order='lex'); P.rename("P") sage: I = sage.rings.ideal.Cyclic(P) sage: GB = Ideal(I.groebner_basis('libsingular:stdfglm')) sage: GB.triangular_decomposition('singular:triangLfak') - [Ideal (a - 1, b - 1, c - 1, d^2 + 3*d + 1, e + d + 3) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, - Ideal (a - 1, b - 1, c^2 + 3*c + 1, d + c + 3, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, - Ideal (a - 1, b^2 + 3*b + 1, c + b + 3, d - 1, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, - Ideal (a - 1, b^4 + b^3 + b^2 + b + 1, -c + b^2, -d + b^3, e + b^3 + b^2 + b + 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, - Ideal (a^2 + 3*a + 1, b - 1, c - 1, d - 1, e + a + 3) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, - Ideal (a^2 + 3*a + 1, b + a + 3, c - 1, d - 1, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, - Ideal (a^4 - 4*a^3 + 6*a^2 + a + 1, -11*b^2 + 6*b*a^3 - 26*b*a^2 + 41*b*a - 4*b - 8*a^3 + 31*a^2 - 40*a - 24, 11*c + 3*a^3 - 13*a^2 + 26*a - 2, 11*d + 3*a^3 - 13*a^2 + 26*a - 2, -11*e - 11*b + 6*a^3 - 26*a^2 + 41*a - 4) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, - Ideal (a^4 + a^3 + a^2 + a + 1, b - 1, c + a^3 + a^2 + a + 1, -d + a^3, -e + a^2) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, - Ideal (a^4 + a^3 + a^2 + a + 1, b - a, c - a, d^2 + 3*d*a + a^2, e + d + 3*a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, - Ideal (a^4 + a^3 + a^2 + a + 1, b - a, c^2 + 3*c*a + a^2, d + c + 3*a, e - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, - Ideal (a^4 + a^3 + a^2 + a + 1, b^2 + 3*b*a + a^2, c + b + 3*a, d - a, e - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, - Ideal (a^4 + a^3 + a^2 + a + 1, b^3 + b^2*a + b^2 + b*a^2 + b*a + b + a^3 + a^2 + a + 1, c + b^2*a^3 + b^2*a^2 + b^2*a + b^2, -d + b^2*a^2 + b^2*a + b^2 + b*a^2 + b*a + a^2, -e + b^2*a^3 - b*a^2 - b*a - b - a^2 - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, - Ideal (a^4 + a^3 + 6*a^2 - 4*a + 1, -11*b^2 + 6*b*a^3 + 10*b*a^2 + 39*b*a + 2*b + 16*a^3 + 23*a^2 + 104*a - 24, 11*c + 3*a^3 + 5*a^2 + 25*a + 1, 11*d + 3*a^3 + 5*a^2 + 25*a + 1, -11*e - 11*b + 6*a^3 + 10*a^2 + 39*a + 2) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field] + [Ideal (a - 1, b - 1, c - 1, d^2 + 3*d + 1, e + d + 3) of P, + Ideal (a - 1, b - 1, c^2 + 3*c + 1, d + c + 3, e - 1) of P, + Ideal (a - 1, b^2 + 3*b + 1, c + b + 3, d - 1, e - 1) of P, + Ideal (a - 1, b^4 + b^3 + b^2 + b + 1, -c + b^2, -d + b^3, + e + b^3 + b^2 + b + 1) of P, + Ideal (a^2 + 3*a + 1, b - 1, c - 1, d - 1, e + a + 3) of P, + Ideal (a^2 + 3*a + 1, b + a + 3, c - 1, d - 1, e - 1) of P, + Ideal (a^4 - 4*a^3 + 6*a^2 + a + 1, + -11*b^2 + 6*b*a^3 - 26*b*a^2 + 41*b*a - 4*b - 8*a^3 + 31*a^2 - 40*a - 24, + 11*c + 3*a^3 - 13*a^2 + 26*a - 2, 11*d + 3*a^3 - 13*a^2 + 26*a - 2, + -11*e - 11*b + 6*a^3 - 26*a^2 + 41*a - 4) of P, + Ideal (a^4 + a^3 + a^2 + a + 1, + b - 1, c + a^3 + a^2 + a + 1, -d + a^3, -e + a^2) of P, + Ideal (a^4 + a^3 + a^2 + a + 1, + b - a, c - a, d^2 + 3*d*a + a^2, e + d + 3*a) of P, + Ideal (a^4 + a^3 + a^2 + a + 1, + b - a, c^2 + 3*c*a + a^2, d + c + 3*a, e - a) of P, + Ideal (a^4 + a^3 + a^2 + a + 1, + b^2 + 3*b*a + a^2, c + b + 3*a, d - a, e - a) of P, + Ideal (a^4 + a^3 + a^2 + a + 1, + b^3 + b^2*a + b^2 + b*a^2 + b*a + b + a^3 + a^2 + a + 1, + c + b^2*a^3 + b^2*a^2 + b^2*a + b^2, + -d + b^2*a^2 + b^2*a + b^2 + b*a^2 + b*a + a^2, + -e + b^2*a^3 - b*a^2 - b*a - b - a^2 - a) of P, + Ideal (a^4 + a^3 + 6*a^2 - 4*a + 1, + -11*b^2 + 6*b*a^3 + 10*b*a^2 + 39*b*a + 2*b + 16*a^3 + 23*a^2 + 104*a - 24, + 11*c + 3*a^3 + 5*a^2 + 25*a + 1, 11*d + 3*a^3 + 5*a^2 + 25*a + 1, + -11*e - 11*b + 6*a^3 + 10*a^2 + 39*a + 2) of P] sage: R. = PolynomialRing(QQ, 2, order='lex') sage: f1 = 1/2*((x1^2 + 2*x1 - 4)*x2^2 + 2*(x1^2 + x1)*x2 + x1^2) @@ -1067,7 +1087,8 @@ def triangular_decomposition(self, algorithm=None, singular=singular_default): [Ideal (x2, x1^2) of Multivariate Polynomial Ring in x1, x2 over Rational Field, Ideal (x2, x1^2) of Multivariate Polynomial Ring in x1, x2 over Rational Field, Ideal (x2, x1^2) of Multivariate Polynomial Ring in x1, x2 over Rational Field, - Ideal (x2^4 + 4*x2^3 - 6*x2^2 - 20*x2 + 5, 8*x1 - x2^3 + x2^2 + 13*x2 - 5) of Multivariate Polynomial Ring in x1, x2 over Rational Field] + Ideal (x2^4 + 4*x2^3 - 6*x2^2 - 20*x2 + 5, 8*x1 - x2^3 + x2^2 + 13*x2 - 5) + of Multivariate Polynomial Ring in x1, x2 over Rational Field] TESTS:: @@ -1078,9 +1099,9 @@ def triangular_decomposition(self, algorithm=None, singular=singular_default): Check that this method works over QQbar (:trac:`25351`):: - sage: R. = QQbar[] - sage: J = Ideal(x^2+y^2-2, y^2-1) - sage: J.triangular_decomposition() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: J = Ideal(x^2 + y^2 - 2, y^2 - 1) # optional - sage.rings.number_field + sage: J.triangular_decomposition() # optional - sage.rings.number_field [Ideal (y^2 - 1, x^2 - 1) of Multivariate Polynomial Ring in x, y over Algebraic Field] """ P = self.ring() @@ -1136,9 +1157,9 @@ def dimension(self, singular=singular_default): EXAMPLES:: - sage: P. = PolynomialRing(GF(32003),order='degrevlex') - sage: I = ideal(x^2-y,x^3) - sage: I.dimension() + sage: P. = PolynomialRing(GF(32003), order='degrevlex') # optional - sage.rings.finite_rings + sage: I = ideal(x^2 - y, x^3) # optional - sage.rings.finite_rings + sage: I.dimension() # optional - sage.rings.finite_rings 1 If the ideal is the total ring, the dimension is `-1` by convention. @@ -1150,22 +1171,22 @@ def dimension(self, singular=singular_default): EXAMPLES:: - sage: R. = PolynomialRing(GF(2147483659^2),order='lex') - sage: I = R.ideal([x*y,x*y+1]) - sage: I.dimension() + sage: R. = PolynomialRing(GF(2147483659^2), order='lex') # optional - sage.rings.finite_rings + sage: I = R.ideal([x*y, x*y + 1]) # optional - sage.rings.finite_rings + sage: I.dimension() # optional - sage.rings.finite_rings verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation. -1 - sage: I=ideal([x*(x*y+1),y*(x*y+1)]) - sage: I.dimension() + sage: I=ideal([x*(x*y+1), y*(x*y+1)]) # optional - sage.rings.finite_rings + sage: I.dimension() # optional - sage.rings.finite_rings verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation. 1 - sage: I = R.ideal([x^3*y,x*y^2]) - sage: I.dimension() + sage: I = R.ideal([x^3*y, x*y^2]) # optional - sage.rings.finite_rings + sage: I.dimension() # optional - sage.rings.finite_rings verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation. 1 - sage: R. = PolynomialRing(GF(2147483659^2),order='lex') - sage: I = R.ideal(0) - sage: I.dimension() + sage: R. = PolynomialRing(GF(2147483659^2), order='lex') # optional - sage.rings.finite_rings + sage: I = R.ideal(0) # optional - sage.rings.finite_rings + sage: I.dimension() # optional - sage.rings.finite_rings verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation. 2 @@ -1177,9 +1198,9 @@ def dimension(self, singular=singular_default): Check that this method works over QQbar (:trac:`25351`):: - sage: P. = QQbar[] - sage: I = ideal(x^2-y,x^3-QQbar(-1)) - sage: I.dimension() + sage: P. = QQbar[] # optional - sage.rings.number_field + sage: I = ideal(x^2-y, x^3-QQbar(-1)) # optional - sage.rings.number_field + sage: I.dimension() # optional - sage.rings.number_field 1 .. NOTE:: @@ -1251,7 +1272,7 @@ def dimension(self, singular=singular_default): def vector_space_dimension(self): """ Return the vector space dimension of the ring modulo this ideal. If - the ideal is not zero-dimensional, a TypeError is raised. + the ideal is not zero-dimensional, a :class:`TypeError` is raised. ALGORITHM: @@ -1278,19 +1299,19 @@ def vector_space_dimension(self): Due to integer overflow, the result is correct only modulo ``2^32``, see :trac:`8586`:: - sage: P. = PolynomialRing(GF(32003),3) - sage: sage.rings.ideal.FieldIdeal(P).vector_space_dimension() # known bug + sage: P. = PolynomialRing(GF(32003), 3) # optional - sage.rings.finite_rings + sage: sage.rings.ideal.FieldIdeal(P).vector_space_dimension() # known bug # optional - sage.rings.finite_rings 32777216864027 TESTS: Check that this method works over QQbar (:trac:`25351`):: - sage: P. = QQbar[] - sage: I = ideal(x^2-y,x^3-QQbar(-1),z-y) - sage: I.dimension() + sage: P. = QQbar[] # optional - sage.rings.number_field + sage: I = ideal(x^2-y,x^3-QQbar(-1),z-y) # optional - sage.rings.number_field + sage: I.dimension() # optional - sage.rings.number_field 0 - sage: I.vector_space_dimension() + sage: I.vector_space_dimension() # optional - sage.rings.number_field 3 """ @@ -1327,12 +1348,12 @@ def _groebner_basis_ginv(self, algorithm="TQ", criteria='CritPartially', divisio sage: P. = PolynomialRing(QQ,order='degrevlex') sage: I = sage.rings.ideal.Katsura(P) - sage: I.groebner_basis(algorithm='ginv') # optional - ginv + sage: I.groebner_basis(algorithm='ginv') # optional - ginv [z^3 - 79/210*z^2 + 1/30*y + 1/70*z, y^2 - 3/5*z^2 - 1/5*y + 1/5*z, y*z + 6/5*z^2 - 1/10*y - 2/5*z, x + 2*y + 2*z - 1] - sage: P. = PolynomialRing(GF(127),order='degrevlex') - sage: I = sage.rings.ideal.Katsura(P) - sage: I.groebner_basis(algorithm='ginv') # optional - ginv + sage: P. = PolynomialRing(GF(127), order='degrevlex') # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings + sage: I.groebner_basis(algorithm='ginv') # optional - ginv # optional - sage.rings.finite_rings ... [z^3 + 22*z^2 - 55*y + 49*z, y^2 - 26*z^2 - 51*y + 51*z, y*z + 52*z^2 + 38*y + 25*z, x + 2*y + 2*z - 1] @@ -1575,9 +1596,9 @@ def genus(self): Check that this method works over QQbar (:trac:`25351`):: - sage: P. = QQbar[] - sage: I = ideal(y^3*z + x^3*y + x*z^3) - sage: I.genus() + sage: P. = QQbar[] # optional - sage.rings.number_field + sage: I = ideal(y^3*z + x^3*y + x*z^3) # optional - sage.rings.number_field + sage: I.genus() # optional - sage.rings.number_field 3 """ from sage.libs.singular.function_factory import ff @@ -1601,22 +1622,23 @@ def intersection(self, *others): The following simple example illustrates that the product need not equal the intersection. :: - sage: I = (x^2, y)*R - sage: J = (y^2, x)*R + sage: I = (x^2, y) * R + sage: J = (y^2, x) * R sage: K = I.intersection(J); K Ideal (y^2, x*y, x^2) of Multivariate Polynomial Ring in x, y over Rational Field sage: IJ = I*J; IJ - Ideal (x^2*y^2, x^3, y^3, x*y) of Multivariate Polynomial Ring in x, y over Rational Field + Ideal (x^2*y^2, x^3, y^3, x*y) + of Multivariate Polynomial Ring in x, y over Rational Field sage: IJ == K False Intersection of several ideals:: sage: R. = PolynomialRing(QQ, 3, order='lex') - sage: I1 = x*R - sage: I2 = y*R - sage: I3 = (x, y)*R - sage: I4 = (x^2 + x*y*z, y^2 - z^3*y, z^3 + y^5*x*z)*R + sage: I1 = x * R + sage: I2 = y * R + sage: I3 = (x, y) * R + sage: I4 = (x^2 + x*y*z, y^2 - z^3*y, z^3 + y^5*x*z) * R sage: I1.intersection(I2, I3, I4).groebner_basis() [x^2*y + x*y*z^4, x*y^2 - x*y*z^3, x*y*z^20 - x*y*z^3] @@ -1635,10 +1657,10 @@ def intersection(self, *others): Check that this method works over QQbar (:trac:`25351`):: - sage: R. = QQbar[] - sage: I = x*R - sage: J = y*R - sage: I.intersection(J) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: I = x*R # optional - sage.rings.number_field + sage: J = y*R # optional - sage.rings.number_field + sage: I.intersection(J) # optional - sage.rings.number_field Ideal (x*y) of Multivariate Polynomial Ring in x, y over Algebraic Field """ R = self.ring() @@ -1665,10 +1687,12 @@ def minimal_associated_primes(self): sage: R. = PolynomialRing(QQ, 3, 'xyz') sage: p = z^2 + 1; q = z^3 + 2 - sage: I = (p*q^2, y-z^2)*R + sage: I = (p*q^2, y - z^2) * R sage: sorted(I.minimal_associated_primes(), key=str) - [Ideal (z^2 + 1, -z^2 + y) of Multivariate Polynomial Ring in x, y, z over Rational Field, - Ideal (z^3 + 2, -z^2 + y) of Multivariate Polynomial Ring in x, y, z over Rational Field] + [Ideal (z^2 + 1, -z^2 + y) + of Multivariate Polynomial Ring in x, y, z over Rational Field, + Ideal (z^3 + 2, -z^2 + y) + of Multivariate Polynomial Ring in x, y, z over Rational Field] ALGORITHM: @@ -1692,7 +1716,7 @@ def radical(self): This is an obviously not radical ideal:: sage: R. = PolynomialRing(QQ, 3) - sage: I = (x^2, y^3, (x*z)^4 + y^3 + 10*x^2)*R + sage: I = (x^2, y^3, (x*z)^4 + y^3 + 10*x^2) * R sage: I.radical() Ideal (y, x) of Multivariate Polynomial Ring in x, y, z over Rational Field @@ -1704,9 +1728,10 @@ def radical(self): This is the example from the Singular manual:: sage: p = z^2 + 1; q = z^3 + 2 - sage: I = (p*q^2, y-z^2)*R + sage: I = (p*q^2, y - z^2) * R sage: I.radical() - Ideal (z^2 - y, y^2*z + y*z + 2*y + 2) of Multivariate Polynomial Ring in x, y, z over Rational Field + Ideal (z^2 - y, y^2*z + y*z + 2*y + 2) + of Multivariate Polynomial Ring in x, y, z over Rational Field .. NOTE:: @@ -1716,11 +1741,12 @@ def radical(self): :: - sage: R. = PolynomialRing(GF(37), 3) - sage: p = z^2 + 1; q = z^3 + 2 - sage: I = (p*q^2, y - z^2)*R - sage: I.radical() - Ideal (z^2 - y, y^2*z + y*z + 2*y + 2) of Multivariate Polynomial Ring in x, y, z over Finite Field of size 37 + sage: R. = PolynomialRing(GF(37), 3) # optional - sage.rings.finite_rings + sage: p = z^2 + 1; q = z^3 + 2 # optional - sage.rings.finite_rings + sage: I = (p*q^2, y - z^2) * R # optional - sage.rings.finite_rings + sage: I.radical() # optional - sage.rings.finite_rings + Ideal (z^2 - y, y^2*z + y*z + 2*y + 2) + of Multivariate Polynomial Ring in x, y, z over Finite Field of size 37 """ from sage.libs.singular.function_factory import ff radical = ff.primdec__lib.radical @@ -1743,22 +1769,22 @@ def integral_closure(self, p=0, r=True, singular=singular_default): Return the integral closure of `I, ..., I^p`, where `sI` is an ideal in the polynomial ring `R=k[x(1),...x(n)]`. If `p` is not given, or `p=0`, compute the closure of all powers up to - the maximum degree in t occurring in the closure of `R[It]` + the maximum degree in `t` occurring in the closure of `R[It]` (so this is the last power whose closure is not just the sum/product of the smaller). If `r` is given and ``r is - True``, ``I.integral_closure()`` starts with a check whether I + True``, ``I.integral_closure()`` starts with a check whether `I` is already a radical ideal. INPUT: - - ``p`` - powers of I (default: 0) + - ``p`` - powers of `I` (default: 0) - - ``r`` - check whether self is a radical ideal first (default: ``True``) + - ``r`` - check whether ``self`` is a radical ideal first (default: ``True``) EXAMPLES:: sage: R. = QQ[] - sage: I = ideal([x^2,x*y^4,y^5]) + sage: I = ideal([x^2, x*y^4, y^5]) sage: I.integral_closure() [x^2, x*y^4, y^5, x*y^3] @@ -1803,16 +1829,16 @@ def syzygy_module(self): Check that this method works over QQbar (:trac:`25351`):: - sage: R. = QQbar[] - sage: f = 2*x^2 + y - sage: g = y - sage: h = 2*f + g - sage: I = Ideal([f,g,h]) - sage: M = I.syzygy_module(); M + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = 2*x^2 + y # optional - sage.rings.number_field + sage: g = y # optional - sage.rings.number_field + sage: h = 2*f + g # optional - sage.rings.number_field + sage: I = Ideal([f,g,h]) # optional - sage.rings.number_field + sage: M = I.syzygy_module(); M # optional - sage.rings.number_field [ -2 -1 1] [ -y 2*x^2 + y 0] - sage: G = vector(I.gens()) - sage: M*G + sage: G = vector(I.gens()) # optional - sage.rings.number_field + sage: M*G # optional - sage.rings.number_field (0, 0) """ from sage.libs.singular.function_factory import ff @@ -1904,50 +1930,50 @@ def graded_free_resolution(self, *args, **kwds): @libsingular_gb_standard_options def interreduced_basis(self): r""" - If this ideal is spanned by `(f_1, ..., f_n)` this method - returns `(g_1, ..., g_s)` such that: + If this ideal is spanned by `(f_1, ..., f_n)`, + return `(g_1, ..., g_s)` such that: - `(f_1,...,f_n) = (g_1,...,g_s)` - - `LT(g_i) != LT(g_j)` for all `i != j` + - `LT(g_i) \neq LT(g_j)` for all `i \neq j` - `LT(g_i)` does not divide `m` for all monomials `m` of - `\{g_1,...,g_{i-1},g_{i+1},...,g_s\}` + `\{g_1,...,g_{i-1},g_{i+1},...,g_s\}` - - `LC(g_i) == 1` for all `i` if the coefficient ring is a field. + - `LC(g_i) = 1` for all `i` if the coefficient ring is a field. EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: I = Ideal([z*x+y^3,z+y^3,z+x*y]) + sage: I = Ideal([z*x + y^3, z + y^3, z + x*y]) sage: I.interreduced_basis() [y^3 + z, x*y + z, x*z - z] Note that tail reduction for local orderings is not well-defined:: sage: R. = PolynomialRing(QQ,order='negdegrevlex') - sage: I = Ideal([z*x+y^3,z+y^3,z+x*y]) + sage: I = Ideal([z*x + y^3, z + y^3, z + x*y]) sage: I.interreduced_basis() [z + x*y, x*y - y^3, x^2*y - y^3] A fixed error with nonstandard base fields:: - sage: R.=QQ['t'] - sage: K.=R.fraction_field()['x,y'] - sage: I=t*x*K + sage: R. = QQ['t'] + sage: K. = R.fraction_field()['x,y'] + sage: I = t*x * K sage: I.interreduced_basis() [x] The interreduced basis of 0 is 0:: - sage: P. = GF(2)[] - sage: Ideal(P(0)).interreduced_basis() + sage: P. = GF(2)[] # optional - sage.rings.finite_rings + sage: Ideal(P(0)).interreduced_basis() # optional - sage.rings.finite_rings [0] ALGORITHM: - Uses Singular's interred command or + Uses Singular's ``interred`` command or :func:`sage.rings.polynomial.toy_buchberger.inter_reduction` if conversion to Singular fails. @@ -1955,9 +1981,9 @@ def interreduced_basis(self): Check that this method works over QQbar (:trac:`25351`):: - sage: R. = QQbar[] - sage: I = Ideal([z*x+y^3,z+y^3,z+x*y]) - sage: I.interreduced_basis() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: I = Ideal([z*x + y^3, z + y^3, z + x*y]) # optional - sage.rings.number_field + sage: I.interreduced_basis() # optional - sage.rings.number_field [y^3 + z, x*y + z, x*z - z] """ return self.basis.reduced() @@ -1985,44 +2011,63 @@ def basis_is_groebner(self, singular=singular_default): EXAMPLES:: - sage: R. = PolynomialRing(GF(127),10) - sage: I = sage.rings.ideal.Cyclic(R,4) - sage: I.basis_is_groebner() + sage: R. = PolynomialRing(GF(127), 10) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Cyclic(R, 4) # optional - sage.rings.finite_rings + sage: I.basis_is_groebner() # optional - sage.rings.finite_rings False - sage: I2 = Ideal(I.groebner_basis()) - sage: I2.basis_is_groebner() + sage: I2 = Ideal(I.groebner_basis()) # optional - sage.rings.finite_rings + sage: I2.basis_is_groebner() # optional - sage.rings.finite_rings True A more complicated example:: - sage: R. = PolynomialRing(GF(7583)) - sage: l = [u6 + u5 + u4 + u3 + u2 - 3791*h, \ - U6 + U5 + U4 + U3 + U2 - 3791*h, \ - U2*u2 - h^2, U3*u3 - h^2, U4*u4 - h^2, \ - U5*u4 + U5*u3 + U4*u3 + U5*u2 + U4*u2 + U3*u2 - 3791*U5*h - 3791*U4*h - 3791*U3*h - 3791*U2*h - 2842*h^2, \ - U4*u5 + U3*u5 + U2*u5 + U3*u4 + U2*u4 + U2*u3 - 3791*u5*h - 3791*u4*h - 3791*u3*h - 3791*u2*h - 2842*h^2, \ - U5*u5 - h^2, U4*U2*u3 + U5*U3*u2 + U4*U3*u2 + U3^2*u2 - 3791*U5*U3*h - 3791*U4*U3*h - 3791*U3^2*h - 3791*U5*U2*h \ - - 3791*U4*U2*h + U3*U2*h - 3791*U2^2*h - 3791*U4*u3*h - 3791*U4*u2*h - 3791*U3*u2*h - 2843*U5*h^2 + 1897*U4*h^2 - 946*U3*h^2 - 947*U2*h^2 + 2370*h^3, \ - U3*u5*u4 + U2*u5*u4 + U3*u4^2 + U2*u4^2 + U2*u4*u3 - 3791*u5*u4*h - 3791*u4^2*h - 3791*u4*u3*h - 3791*u4*u2*h + u5*h^2 - 2842*u4*h^2, \ - U2*u5*u4*u3 + U2*u4^2*u3 + U2*u4*u3^2 - 3791*u5*u4*u3*h - 3791*u4^2*u3*h - 3791*u4*u3^2*h - 3791*u4*u3*u2*h + u5*u4*h^2 + u4^2*h^2 + u5*u3*h^2 - 2842*u4*u3*h^2, \ - U5^2*U4*u3 + U5*U4^2*u3 + U5^2*U4*u2 + U5*U4^2*u2 + U5^2*U3*u2 + 2*U5*U4*U3*u2 + U5*U3^2*u2 - 3791*U5^2*U4*h - 3791*U5*U4^2*h - 3791*U5^2*U3*h \ - + U5*U4*U3*h - 3791*U5*U3^2*h - 3791*U5^2*U2*h + U5*U4*U2*h + U5*U3*U2*h - 3791*U5*U2^2*h - 3791*U5*U3*u2*h - 2842*U5^2*h^2 + 1897*U5*U4*h^2 \ - - U4^2*h^2 - 947*U5*U3*h^2 - U4*U3*h^2 - 948*U5*U2*h^2 - U4*U2*h^2 - 1422*U5*h^3 + 3791*U4*h^3, \ - u5*u4*u3*u2*h + u4^2*u3*u2*h + u4*u3^2*u2*h + u4*u3*u2^2*h + 2*u5*u4*u3*h^2 + 2*u4^2*u3*h^2 + 2*u4*u3^2*h^2 + 2*u5*u4*u2*h^2 + 2*u4^2*u2*h^2 \ - + 2*u5*u3*u2*h^2 + 1899*u4*u3*u2*h^2, \ - U5^2*U4*U3*u2 + U5*U4^2*U3*u2 + U5*U4*U3^2*u2 - 3791*U5^2*U4*U3*h - 3791*U5*U4^2*U3*h - 3791*U5*U4*U3^2*h - 3791*U5*U4*U3*U2*h \ - + 3791*U5*U4*U3*u2*h + U5^2*U4*h^2 + U5*U4^2*h^2 + U5^2*U3*h^2 - U4^2*U3*h^2 - U5*U3^2*h^2 - U4*U3^2*h^2 - U5*U4*U2*h^2 \ - - U5*U3*U2*h^2 - U4*U3*U2*h^2 + 3791*U5*U4*h^3 + 3791*U5*U3*h^3 + 3791*U4*U3*h^3, \ - u4^2*u3*u2*h^2 + 1515*u5*u3^2*u2*h^2 + u4*u3^2*u2*h^2 + 1515*u5*u4*u2^2*h^2 + 1515*u5*u3*u2^2*h^2 + u4*u3*u2^2*h^2 \ - + 1521*u5*u4*u3*h^3 - 3028*u4^2*u3*h^3 - 3028*u4*u3^2*h^3 + 1521*u5*u4*u2*h^3 - 3028*u4^2*u2*h^3 + 1521*u5*u3*u2*h^3 + 3420*u4*u3*u2*h^3, \ - U5^2*U4*U3*U2*h + U5*U4^2*U3*U2*h + U5*U4*U3^2*U2*h + U5*U4*U3*U2^2*h + 2*U5^2*U4*U3*h^2 + 2*U5*U4^2*U3*h^2 + 2*U5*U4*U3^2*h^2 \ - + 2*U5^2*U4*U2*h^2 + 2*U5*U4^2*U2*h^2 + 2*U5^2*U3*U2*h^2 - 2*U4^2*U3*U2*h^2 - 2*U5*U3^2*U2*h^2 - 2*U4*U3^2*U2*h^2 \ - - 2*U5*U4*U2^2*h^2 - 2*U5*U3*U2^2*h^2 - 2*U4*U3*U2^2*h^2 - U5*U4*U3*h^3 - U5*U4*U2*h^3 - U5*U3*U2*h^3 - U4*U3*U2*h^3] - - sage: Ideal(l).basis_is_groebner() + sage: R. = PolynomialRing(GF(7583)) # optional - sage.rings.finite_rings + sage: l = [u6 + u5 + u4 + u3 + u2 - 3791*h, # optional - sage.rings.finite_rings + ....: U6 + U5 + U4 + U3 + U2 - 3791*h, + ....: U2*u2 - h^2, U3*u3 - h^2, U4*u4 - h^2, + ....: U5*u4 + U5*u3 + U4*u3 + U5*u2 + U4*u2 + U3*u2 - 3791*U5*h + ....: - 3791*U4*h - 3791*U3*h - 3791*U2*h - 2842*h^2, + ....: U4*u5 + U3*u5 + U2*u5 + U3*u4 + U2*u4 + U2*u3 - 3791*u5*h + ....: - 3791*u4*h - 3791*u3*h - 3791*u2*h - 2842*h^2, + ....: U5*u5 - h^2, U4*U2*u3 + U5*U3*u2 + U4*U3*u2 + U3^2*u2 - 3791*U5*U3*h + ....: - 3791*U4*U3*h - 3791*U3^2*h - 3791*U5*U2*h- 3791*U4*U2*h + U3*U2*h + ....: - 3791*U2^2*h - 3791*U4*u3*h - 3791*U4*u2*h - 3791*U3*u2*h + ....: - 2843*U5*h^2 + 1897*U4*h^2 - 946*U3*h^2 - 947*U2*h^2 + 2370*h^3, + ....: U3*u5*u4 + U2*u5*u4 + U3*u4^2 + U2*u4^2 + U2*u4*u3 - 3791*u5*u4*h + ....: - 3791*u4^2*h - 3791*u4*u3*h - 3791*u4*u2*h + u5*h^2 - 2842*u4*h^2, + ....: U2*u5*u4*u3 + U2*u4^2*u3 + U2*u4*u3^2 - 3791*u5*u4*u3*h + ....: - 3791*u4^2*u3*h - 3791*u4*u3^2*h - 3791*u4*u3*u2*h + u5*u4*h^2 + ....: + u4^2*h^2 + u5*u3*h^2 - 2842*u4*u3*h^2, + ....: U5^2*U4*u3 + U5*U4^2*u3 + U5^2*U4*u2 + U5*U4^2*u2 + U5^2*U3*u2 + ....: + 2*U5*U4*U3*u2 + U5*U3^2*u2 - 3791*U5^2*U4*h - 3791*U5*U4^2*h + ....: - 3791*U5^2*U3*h + U5*U4*U3*h - 3791*U5*U3^2*h - 3791*U5^2*U2*h + ....: + U5*U4*U2*h+ U5*U3*U2*h - 3791*U5*U2^2*h - 3791*U5*U3*u2*h + ....: - 2842*U5^2*h^2 + 1897*U5*U4*h^2 - U4^2*h^2 - 947*U5*U3*h^2 + ....: - U4*U3*h^2 - 948*U5*U2*h^2 - U4*U2*h^2 - 1422*U5*h^3 + 3791*U4*h^3, + ....: u5*u4*u3*u2*h + u4^2*u3*u2*h + u4*u3^2*u2*h + u4*u3*u2^2*h + ....: + 2*u5*u4*u3*h^2 + 2*u4^2*u3*h^2 + 2*u4*u3^2*h^2 + 2*u5*u4*u2*h^2 + ....: + 2*u4^2*u2*h^2 + 2*u5*u3*u2*h^2 + 1899*u4*u3*u2*h^2, + ....: U5^2*U4*U3*u2 + U5*U4^2*U3*u2 + U5*U4*U3^2*u2 - 3791*U5^2*U4*U3*h + ....: - 3791*U5*U4^2*U3*h - 3791*U5*U4*U3^2*h - 3791*U5*U4*U3*U2*h + ....: + 3791*U5*U4*U3*u2*h + U5^2*U4*h^2 + U5*U4^2*h^2 + U5^2*U3*h^2 + ....: - U4^2*U3*h^2 - U5*U3^2*h^2 - U4*U3^2*h^2 - U5*U4*U2*h^2 - U5*U3*U2*h^2 + ....: - U4*U3*U2*h^2 + 3791*U5*U4*h^3 + 3791*U5*U3*h^3 + 3791*U4*U3*h^3, + ....: u4^2*u3*u2*h^2 + 1515*u5*u3^2*u2*h^2 + u4*u3^2*u2*h^2 + ....: + 1515*u5*u4*u2^2*h^2 + 1515*u5*u3*u2^2*h^2 + u4*u3*u2^2*h^2 + ....: + 1521*u5*u4*u3*h^3 - 3028*u4^2*u3*h^3 - 3028*u4*u3^2*h^3 + ....: + 1521*u5*u4*u2*h^3 - 3028*u4^2*u2*h^3 + 1521*u5*u3*u2*h^3 + ....: + 3420*u4*u3*u2*h^3, + ....: U5^2*U4*U3*U2*h + U5*U4^2*U3*U2*h + U5*U4*U3^2*U2*h + U5*U4*U3*U2^2*h + ....: + 2*U5^2*U4*U3*h^2 + 2*U5*U4^2*U3*h^2 + 2*U5*U4*U3^2*h^2 + ....: + 2*U5^2*U4*U2*h^2 + 2*U5*U4^2*U2*h^2 + 2*U5^2*U3*U2*h^2 + ....: - 2*U4^2*U3*U2*h^2 - 2*U5*U3^2*U2*h^2 - 2*U4*U3^2*U2*h^2 + ....: - 2*U5*U4*U2^2*h^2 - 2*U5*U3*U2^2*h^2 - 2*U4*U3*U2^2*h^2 + ....: - U5*U4*U3*h^3 - U5*U4*U2*h^3 - U5*U3*U2*h^3 - U4*U3*U2*h^3] + + sage: Ideal(l).basis_is_groebner() # optional - sage.rings.finite_rings False - sage: gb = Ideal(l).groebner_basis() - sage: Ideal(gb).basis_is_groebner() + sage: gb = Ideal(l).groebner_basis() # optional - sage.rings.finite_rings + sage: Ideal(gb).basis_is_groebner() # optional - sage.rings.finite_rings True .. NOTE:: @@ -2031,21 +2076,21 @@ def basis_is_groebner(self, singular=singular_default): this method: 'The result may have no meaning if the second argument (``self``) is not a standard basis'. I (malb) believe this refers to the mathematical fact that the - results may have no meaning if self is no standard basis, + results may have no meaning if ``self`` is no standard basis, i.e., Singular doesn't 'add' any additional 'nonsense' to the result. So we may actually use reduce to determine if - self is a Groebner basis. + ``self`` is a Groebner basis. TESTS: Check that this method works over QQbar (:trac:`25351`):: - sage: R. = QQbar[] - sage: I = sage.rings.ideal.Cyclic(R,4) - sage: I.basis_is_groebner() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: I = sage.rings.ideal.Cyclic(R,4) # optional - sage.rings.number_field + sage: I.basis_is_groebner() # optional - sage.rings.number_field False - sage: I2 = Ideal(I.groebner_basis()) - sage: I2.basis_is_groebner() + sage: I2 = Ideal(I.groebner_basis()) # optional - sage.rings.number_field + sage: I2.basis_is_groebner() # optional - sage.rings.number_field True """ from sage.matrix.constructor import matrix @@ -2095,25 +2140,25 @@ def transformed_basis(self, algorithm="gwalk", other_ring=None, singular=singula - ``algorithm`` - see below for options. - - ``other_ring`` - only valid for algorithm 'fglm', if - provided conversion will be performed to this + - ``other_ring`` - only valid for ``algorithm='fglm'``; if + provided, conversion will be performed to this ring. Otherwise a lex Groebner basis will be returned. ALGORITHMS: - - ``fglm`` - FGLM algorithm. The input ideal must be given with a reduced + - ``"fglm"`` - FGLM algorithm. The input ideal must be given with a reduced Groebner Basis of a zero-dimensional ideal - - ``gwalk`` - Groebner Walk algorithm (*default*) + - ``"gwalk"`` - Groebner Walk algorithm (*default*) - - ``awalk1`` - 'first alternative' algorithm + - ``"awalk1"`` - 'first alternative' algorithm - - ``awalk2`` - 'second alternative' algorithm + - ``"awalk2"`` - 'second alternative' algorithm - - ``twalk`` - Tran algorithm + - ``"twalk"`` - Tran algorithm - - ``fwalk`` - Fractal Walk algorithm + - ``"fwalk"`` - Fractal Walk algorithm EXAMPLES:: @@ -2124,21 +2169,22 @@ def transformed_basis(self, algorithm="gwalk", other_ring=None, singular=singula sage: J = Ideal(I.transformed_basis('fglm',S)) sage: J Ideal (z^4 + y^3 - y, x^2 + y^3, x*y^3 - y^3, y^4 + y^3) - of Multivariate Polynomial Ring in z, x, y over Rational Field + of Multivariate Polynomial Ring in z, x, y over Rational Field :: - sage: R.=PolynomialRing(GF(32003),3,order='lex') - sage: I=Ideal([y^3+x*y*z+y^2*z+x*z^3,3+x*y+x^2*y+y^2*z]) - sage: I.transformed_basis('gwalk') + sage: R. = PolynomialRing(GF(32003), 3, order='lex') # optional - sage.rings.finite_rings + sage: I = Ideal([y^3 + x*y*z + y^2*z + x*z^3, 3 + x*y + x^2*y + y^2*z]) # optional - sage.rings.finite_rings + sage: I.transformed_basis('gwalk') # optional - sage.rings.finite_rings [z*y^2 + y*x^2 + y*x + 3, - z*x + 8297*y^8*x^2 + 8297*y^8*x + 3556*y^7 - 8297*y^6*x^4 + 15409*y^6*x^3 - 8297*y^6*x^2 - - 8297*y^5*x^5 + 15409*y^5*x^4 - 8297*y^5*x^3 + 3556*y^5*x^2 + 3556*y^5*x + 3556*y^4*x^3 - + 3556*y^4*x^2 - 10668*y^4 - 10668*y^3*x - 8297*y^2*x^9 - 1185*y^2*x^8 + 14224*y^2*x^7 - - 1185*y^2*x^6 - 8297*y^2*x^5 - 14223*y*x^7 - 10666*y*x^6 - 10666*y*x^5 - 14223*y*x^4 - + x^5 + 2*x^4 + x^3, - y^9 - y^7*x^2 - y^7*x - y^6*x^3 - y^6*x^2 - 3*y^6 - 3*y^5*x - y^3*x^7 - 3*y^3*x^6 - - 3*y^3*x^5 - y^3*x^4 - 9*y^2*x^5 - 18*y^2*x^4 - 9*y^2*x^3 - 27*y*x^3 - 27*y*x^2 - 27*x] + z*x + 8297*y^8*x^2 + 8297*y^8*x + 3556*y^7 - 8297*y^6*x^4 + 15409*y^6*x^3 + - 8297*y^6*x^2 - 8297*y^5*x^5 + 15409*y^5*x^4 - 8297*y^5*x^3 + 3556*y^5*x^2 + + 3556*y^5*x + 3556*y^4*x^3 + 3556*y^4*x^2 - 10668*y^4 - 10668*y^3*x + - 8297*y^2*x^9 - 1185*y^2*x^8 + 14224*y^2*x^7 - 1185*y^2*x^6 - 8297*y^2*x^5 + - 14223*y*x^7 - 10666*y*x^6 - 10666*y*x^5 - 14223*y*x^4 + x^5 + 2*x^4 + x^3, + y^9 - y^7*x^2 - y^7*x - y^6*x^3 - y^6*x^2 - 3*y^6 - 3*y^5*x - y^3*x^7 + - 3*y^3*x^6 - 3*y^3*x^5 - y^3*x^4 - 9*y^2*x^5 - 18*y^2*x^4 - 9*y^2*x^3 + - 27*y*x^3 - 27*y*x^2 - 27*x] ALGORITHM: @@ -2149,12 +2195,12 @@ def transformed_basis(self, algorithm="gwalk", other_ring=None, singular=singula Check that this method works over QQbar (:trac:`25351`). We are not currently able to specify other_ring, due to the limitations of @handle_AA_and_QQbar:: - sage: R. = QQbar[] - sage: I = Ideal([y^3+x^2,x^2*y+x^2, x^3-x^2, z^4-x^2-y]) - sage: I = Ideal(I.groebner_basis()) - sage: S. = PolynomialRing(QQbar,3,order='lex') - sage: J = Ideal(I.transformed_basis('fglm',other_ring=S)) # known bug - sage: J # known bug + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: I = Ideal([y^3 + x^2, x^2*y + x^2, x^3 - x^2, z^4 - x^2 - y]) # optional - sage.rings.number_field + sage: I = Ideal(I.groebner_basis()) # optional - sage.rings.number_field + sage: S. = PolynomialRing(QQbar, 3, order='lex') # optional - sage.rings.number_field + sage: J = Ideal(I.transformed_basis('fglm', other_ring=S)) # known bug # optional - sage.rings.number_field + sage: J # known bug # optional - sage.rings.number_field """ from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence R = self.ring() @@ -2199,7 +2245,7 @@ def elimination_ideal(self, variables, algorithm=None, *args, **kwds): - ``variables`` -- a list or tuple of variables in ``self.ring()`` - ``algorithm`` - determines the algorithm to use, see below - for available algorithms. + for available algorithms. ALGORITHMS: @@ -2214,10 +2260,10 @@ def elimination_ideal(self, variables, algorithm=None, *args, **kwds): EXAMPLES:: sage: R. = PolynomialRing(QQ,5) - sage: I = R * [x-t,y-t^2,z-t^3,s-x+y^3] - sage: J = I.elimination_ideal([t,s]); J - Ideal (y^2 - x*z, x*y - z, x^2 - y) of Multivariate - Polynomial Ring in x, y, t, s, z over Rational Field + sage: I = R * [x - t, y - t^2, z - t^3, s - x + y^3] + sage: J = I.elimination_ideal([t, s]); J + Ideal (y^2 - x*z, x*y - z, x^2 - y) + of Multivariate Polynomial Ring in x, y, t, s, z over Rational Field You can use Giac to compute the elimination ideal:: @@ -2241,12 +2287,12 @@ def elimination_ideal(self, variables, algorithm=None, *args, **kwds): Check that this method works over QQbar (:trac:`25351`):: - sage: R. = QQbar[] - sage: I = R * [x-t,y-t^2,z-t^3,s-x+y^3] - sage: J = I.elimination_ideal([t,s]); J + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: I = R * [x - t, y - t^2, z - t^3, s - x + y^3] # optional - sage.rings.number_field + sage: J = I.elimination_ideal([t, s]); J # optional - sage.rings.number_field Ideal (y^2 - x*z, x*y - z, x^2 - y) of Multivariate Polynomial Ring in x, y, t, s, z over Algebraic Field - sage: print("possible output from giac", flush=True); I.elimination_ideal([t, s], algorithm="giac") == J + sage: print("possible output from giac", flush=True); I.elimination_ideal([t, s], algorithm="giac") == J # optional - sage.rings.number_field possible output... True @@ -2316,15 +2362,15 @@ def quotient(self, J): EXAMPLES:: - sage: R. = PolynomialRing(GF(181),3) - sage: I = Ideal([x^2+x*y*z,y^2-z^3*y,z^3+y^5*x*z]) - sage: J = Ideal([x]) - sage: Q = I.quotient(J) - sage: y*z + x in I + sage: R. = PolynomialRing(GF(181), 3) # optional - sage.rings.finite_rings + sage: I = Ideal([x^2 + x*y*z, y^2 - z^3*y, z^3 + y^5*x*z]) # optional - sage.rings.finite_rings + sage: J = Ideal([x]) # optional - sage.rings.finite_rings + sage: Q = I.quotient(J) # optional - sage.rings.finite_rings + sage: y*z + x in I # optional - sage.rings.finite_rings False - sage: x in J + sage: x in J # optional - sage.rings.finite_rings True - sage: x * (y*z + x) in I + sage: x * (y*z + x) in I # optional - sage.rings.finite_rings True TESTS: @@ -2339,10 +2385,10 @@ def quotient(self, J): Check that this method works over QQbar (:trac:`25351`):: - sage: R. = QQbar[] - sage: I = ideal(x,z) - sage: J = ideal(R(1)) - sage: I.quotient(J) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: I = ideal(x, z) # optional - sage.rings.number_field + sage: J = ideal(R(1)) # optional - sage.rings.number_field + sage: I.quotient(J) # optional - sage.rings.number_field Ideal (z, x) of Multivariate Polynomial Ring in x, y, z over Algebraic Field Check that :trac:`12803` is fixed:: @@ -2379,9 +2425,7 @@ def saturation(self, other): - ``other`` -- another ideal in the same ring - OUTPUT: - - - a pair (ideal, integer) + OUTPUT: a pair (ideal, integer) EXAMPLES:: @@ -2395,10 +2439,10 @@ def saturation(self, other): Check that this method works over QQbar (:trac:`25351`):: - sage: R. = QQbar[] - sage: I = R.ideal(x^5*z^3, x*y*z, y*z^4) - sage: J = R.ideal(z) - sage: I.saturation(other = J) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: I = R.ideal(x^5*z^3, x*y*z, y*z^4) # optional - sage.rings.number_field + sage: J = R.ideal(z) # optional - sage.rings.number_field + sage: I.saturation(other = J) # optional - sage.rings.number_field (Ideal (y, x^5) of Multivariate Polynomial Ring in x, y, z over Algebraic Field, 4) """ from sage.libs.singular.function_factory import ff @@ -2412,7 +2456,7 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition", proof=True r""" Return the variety of this ideal. - Given a zero-dimensional ideal `I` (== ``self``) of a + Given a zero-dimensional ideal `I` (= ``self``) of a polynomial ring `P` whose order is lexicographic, return the variety of `I` as a list of dictionaries with ``(variable, value)`` pairs. By default, the variety of the ideal over its @@ -2448,41 +2492,41 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition", proof=True EXAMPLES:: - sage: K. = GF(27) # this example is from the MAGMA handbook - sage: P. = PolynomialRing(K, 2, order='lex') - sage: I = Ideal([ x^8 + y + 2, y^6 + x*y^5 + x^2 ]) - sage: I = Ideal(I.groebner_basis()); I - Ideal (x - y^47 - y^45 + y^44 - y^43 + y^41 - y^39 - y^38 - - y^37 - y^36 + y^35 - y^34 - y^33 + y^32 - y^31 + y^30 + - y^28 + y^27 + y^26 + y^25 - y^23 + y^22 + y^21 - y^19 - - y^18 - y^16 + y^15 + y^13 + y^12 - y^10 + y^9 + y^8 + y^7 - - y^6 + y^4 + y^3 + y^2 + y - 1, y^48 + y^41 - y^40 + y^37 - - y^36 - y^33 + y^32 - y^29 + y^28 - y^25 + y^24 + y^2 + y - + 1) of Multivariate Polynomial Ring in x, y over Finite - Field in w of size 3^3 - - sage: V = I.variety(); - sage: sorted(V, key=str) + sage: K. = GF(27) # this example is from the MAGMA handbook # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(K, 2, order='lex') # optional - sage.rings.finite_rings + sage: I = Ideal([x^8 + y + 2, y^6 + x*y^5 + x^2]) # optional - sage.rings.finite_rings + sage: I = Ideal(I.groebner_basis()); I # optional - sage.rings.finite_rings + Ideal (x - y^47 - y^45 + y^44 - y^43 + y^41 - y^39 - y^38 - y^37 - y^36 + + y^35 - y^34 - y^33 + y^32 - y^31 + y^30 + y^28 + y^27 + y^26 + + y^25 - y^23 + y^22 + y^21 - y^19 - y^18 - y^16 + y^15 + y^13 + + y^12 - y^10 + y^9 + y^8 + y^7 - y^6 + y^4 + y^3 + y^2 + y - 1, + y^48 + y^41 - y^40 + y^37 - y^36 - y^33 + y^32 - y^29 + y^28 + - y^25 + y^24 + y^2 + y + 1) + of Multivariate Polynomial Ring in x, y over Finite Field in w of size 3^3 + + sage: V = I.variety(); # optional - sage.rings.finite_rings + sage: sorted(V, key=str) # optional - sage.rings.finite_rings [{y: w^2 + 2*w, x: 2*w + 2}, {y: w^2 + 2, x: 2*w}, {y: w^2 + w, x: 2*w + 1}] - sage: [f.subs(v) for f in I.gens() for v in V] # check that all polynomials vanish + sage: [f.subs(v) # check that all polynomials vanish # optional - sage.rings.finite_rings + ....: for f in I.gens() for v in V] [0, 0, 0, 0, 0, 0] - sage: [I.subs(v).is_zero() for v in V] # same test, but nicer syntax + sage: [I.subs(v).is_zero() for v in V] # same test, but nicer syntax # optional - sage.rings.finite_rings [True, True, True] However, we only account for solutions in the ground field and not in the algebraic closure:: - sage: I.vector_space_dimension() + sage: I.vector_space_dimension() # optional - sage.rings.finite_rings 48 Here we compute the points of intersection of a hyperbola and a circle, in several fields:: sage: K. = PolynomialRing(QQ, 2, order='lex') - sage: I = Ideal([ x*y - 1, (x-2)^2 + (y-1)^2 - 1]) + sage: I = Ideal([x*y - 1, (x-2)^2 + (y-1)^2 - 1]) sage: I = Ideal(I.groebner_basis()); I Ideal (x + y^3 - 2*y^2 + 4*y - 4, y^4 - 2*y^3 + 4*y^2 - 4*y + 1) - of Multivariate Polynomial Ring in x, y over Rational Field + of Multivariate Polynomial Ring in x, y over Rational Field These two curves have one rational intersection:: @@ -2494,7 +2538,7 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition", proof=True sage: sorted(I.variety(ring=RR), key=str) [{y: 0.361103080528647, x: 2.76929235423863}, {y: 1.00000000000000, x: 1.00000000000000}] - sage: I.variety(ring=AA) + sage: I.variety(ring=AA) # optional - sage.rings.number_field [{y: 1, x: 1}, {y: 0.3611030805286474?, x: 2.769292354238632?}] @@ -2507,7 +2551,7 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition", proof=True x: 0.11535382288068... + 0.58974280502220...*I}, {y: 0.36110308052864..., x: 2.7692923542386...}, {y: 1.00000000000000, x: 1.00000000000000}] - sage: sorted(I.variety(ring=QQbar), key=str) + sage: sorted(I.variety(ring=QQbar), key=str) # optional - sage.rings.number_field [{y: 0.3194484597356763? + 1.633170240915238?*I, x: 0.11535382288068429? - 0.5897428050222055?*I}, {y: 0.3194484597356763? - 1.633170240915238?*I, @@ -2519,7 +2563,7 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition", proof=True to compute the variety. See :mod:`~sage.rings.polynomial.msolve` for more information. :: - sage: I.variety(RBF, algorithm='msolve', proof=False) # optional - msolve + sage: I.variety(RBF, algorithm='msolve', proof=False) # optional - msolve [{x: [2.76929235423863 +/- 2.08e-15], y: [0.361103080528647 +/- 4.53e-16]}, {x: 1.000000000000000, y: 1.000000000000000}] @@ -2542,9 +2586,9 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition", proof=True If the ground field's characteristic is too large for Singular, we resort to a toy implementation:: - sage: R. = PolynomialRing(GF(2147483659^3),order='lex') - sage: I=ideal([x^3-2*y^2,3*x+y^4]) - sage: I.variety() + sage: R. = PolynomialRing(GF(2147483659^3), order='lex') # optional - sage.rings.finite_rings + sage: I = ideal([x^3 - 2*y^2, 3*x + y^4]) # optional - sage.rings.finite_rings + sage: I.variety() # optional - sage.rings.finite_rings verbose 0 (...: multi_polynomial_ideal.py, groebner_basis) Warning: falling back to very slow toy implementation. verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation. verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: falling back to very slow toy implementation. @@ -2556,21 +2600,23 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition", proof=True or even generator names as strings, when provided as keys:: sage: K. = QQ[] - sage: I = ideal([x^2+2*y-5,x+y+3]) - sage: v = I.variety(AA)[0]; v[x], v[y] + sage: I = ideal([x^2 + 2*y - 5, x + y + 3]) + sage: v = I.variety(AA)[0]; v[x], v[y] # optional - sage.rings.number_field (4.464101615137755?, -7.464101615137755?) - sage: list(v)[0].parent() + sage: list(v)[0].parent() # optional - sage.rings.number_field Multivariate Polynomial Ring in x, y over Algebraic Real Field - sage: v[x] + sage: v[x] # optional - sage.rings.number_field 4.464101615137755? - sage: v["y"] + sage: v["y"] # optional - sage.rings.number_field -7.464101615137755? - msolve also works over finite fields:: + ``msolve`` also works over finite fields:: - sage: R. = PolynomialRing(GF(536870909), 2, order='lex') - sage: I = Ideal([ x^2 - 1, y^2 - 1 ]) - sage: sorted(I.variety(algorithm='msolve', proof=False), key=str) # optional - msolve + sage: R. = PolynomialRing(GF(536870909), 2, order='lex') # optional - sage.rings.finite_rings + sage: I = Ideal([x^2 - 1, y^2 - 1]) # optional - sage.rings.finite_rings + sage: sorted(I.variety(algorithm='msolve', # optional - msolve # optional - sage.rings.finite_rings + ....: proof=False), + ....: key=str) [{x: 1, y: 1}, {x: 1, y: 536870908}, {x: 536870908, y: 1}, @@ -2579,9 +2625,9 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition", proof=True but may fail in small characteristic, especially with ideals of high degree with respect to the characteristic:: - sage: R. = PolynomialRing(GF(3), 2, order='lex') - sage: I = Ideal([ x^2 - 1, y^2 - 1 ]) - sage: I.variety(algorithm='msolve', proof=False) # optional - msolve + sage: R. = PolynomialRing(GF(3), 2, order='lex') # optional - sage.rings.finite_rings + sage: I = Ideal([x^2 - 1, y^2 - 1]) # optional - sage.rings.finite_rings + sage: I.variety(algorithm='msolve', proof=False) # optional - msolve # optional - sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: characteristic 3 too small @@ -2616,20 +2662,20 @@ def _variety_triangular_decomposition(self, ring): TESTS:: - sage: K. = GF(27) - sage: P. = PolynomialRing(K, 2, order='lex') - sage: I = Ideal([ x^8 + y + 2, y^6 + x*y^5 + x^2 ]) + sage: K. = GF(27) # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(K, 2, order='lex') # optional - sage.rings.finite_rings + sage: I = Ideal([ x^8 + y + 2, y^6 + x*y^5 + x^2 ]) # optional - sage.rings.finite_rings Testing the robustness of the Singular interface:: - sage: T = I.triangular_decomposition('singular:triangLfak') - sage: sorted(I.variety(), key=str) + sage: T = I.triangular_decomposition('singular:triangLfak') # optional - sage.rings.finite_rings + sage: sorted(I.variety(), key=str) # optional - sage.rings.finite_rings [{y: w^2 + 2*w, x: 2*w + 2}, {y: w^2 + 2, x: 2*w}, {y: w^2 + w, x: 2*w + 1}] Testing that a bug is indeed fixed :: - sage: R = PolynomialRing(GF(2), 30, ['x%d'%(i+1) for i in range(30)], order='lex') - sage: R.inject_variables() + sage: R = PolynomialRing(GF(2), 30, ['x%d'%(i+1) for i in range(30)], order='lex') # optional - sage.rings.finite_rings + sage: R.inject_variables() # optional - sage.rings.finite_rings Defining... sage: I = Ideal([x1 + 1, x2, x3 + 1, x5*x10 + x10 + x18, x5*x11 + x11, \ x5*x18, x6, x7 + 1, x9, x10*x11 + x10 + x18, x10*x18 + x18, \ @@ -2640,10 +2686,10 @@ def _variety_triangular_decomposition(self, ring): x11^2 + x11, x12^2 + x12, x13^2 + x13, x14^2 + x14, x15^2 + x15, \ x16^2 + x16, x17^2 + x17, x18^2 + x18, x19^2 + x19, x20^2 + x20, \ x21^2 + x21, x22^2 + x22, x23^2 + x23, x24^2 + x24, x25^2 + x25, \ - x26^2 + x26, x27^2 + x27, x28^2 + x28, x29^2 + x29, x30^2 + x30]) + x26^2 + x26, x27^2 + x27, x28^2 + x28, x29^2 + x29, x30^2 + x30]) # optional - sage.rings.finite_rings sage: I.basis_is_groebner() True - sage: sorted("".join(str(V[g]) for g in R.gens()) for V in I.variety()) # long time (6s on sage.math, 2011) + sage: sorted("".join(str(V[g]) for g in R.gens()) for V in I.variety()) # long time (6s on sage.math, 2011) # optional - sage.rings.finite_rings ['101000100000000110001000100110', '101000100000000110001000101110', '101000100100000101001000100110', @@ -2696,7 +2742,7 @@ def _variety_triangular_decomposition(self, ring): sage: R. = PolynomialRing(QQ, order='lex') sage: I = R.ideal(c^2-2, b-c, a) - sage: I.variety(QQbar) + sage: I.variety(QQbar) # optional - sage.rings.number_field [...a: 0...] An early version of :trac:`25351` broke this method by adding the @@ -2704,13 +2750,13 @@ def _variety_triangular_decomposition(self, ring): that this circle and this hyperbola have two real intersections and two more complex ones:: - sage: K. = PolynomialRing(AA) - sage: I = Ideal([ x*y - 1, (x-2)^2 + (y-1)^2 - 1]) - sage: len(I.variety()) + sage: K. = PolynomialRing(AA) # optional - sage.rings.number_field + sage: I = Ideal([ x*y - 1, (x-2)^2 + (y-1)^2 - 1]) # optional - sage.rings.number_field + sage: len(I.variety()) # optional - sage.rings.number_field 2 - sage: K. = PolynomialRing(QQbar) - sage: I = Ideal([ x*y - 1, (x-2)^2 + (y-1)^2 - 1]) - sage: len(I.variety()) + sage: K. = PolynomialRing(QQbar) # optional - sage.rings.number_field + sage: I = Ideal([ x*y - 1, (x-2)^2 + (y-1)^2 - 1]) # optional - sage.rings.number_field + sage: len(I.variety()) # optional - sage.rings.number_field 4 """ @@ -2789,38 +2835,40 @@ def hilbert_polynomial(self, algorithm='sage'): `R = \bigoplus_d R_d` (which is ``self.ring()``) be a graded commutative algebra over a field `K`. The *Hilbert polynomial* is the unique polynomial `HP(t)` with rational coefficients - such that `HP(d) = dim_K R_d` for all but finitely many + such that `HP(d) = \dim_K R_d` for all but finitely many positive integers `d`. EXAMPLES:: sage: P. = PolynomialRing(QQ) sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5]) - sage: I.hilbert_polynomial() + sage: I.hilbert_polynomial() # optional - sage.libs.flint 5*t - 5 Of course, the Hilbert polynomial of a zero-dimensional ideal is zero:: - sage: J0 = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5, y^3-2*x*z^2+x*y,x^4+x*y-y*z^2]) + sage: J0 = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5, + ....: y^3 - 2*x*z^2 + x*y, x^4 + x*y - y*z^2]) sage: J = P*[m.lm() for m in J0.groebner_basis()] sage: J.dimension() 0 - sage: J.hilbert_polynomial() + sage: J.hilbert_polynomial() # optional - sage.libs.flint 0 It is possible to request a computation using the Singular library:: - sage: I.hilbert_polynomial(algorithm = 'singular') == I.hilbert_polynomial() + sage: I.hilbert_polynomial(algorithm='singular') == I.hilbert_polynomial() # optional - sage.libs.flint sage.libs.singular True - sage: J.hilbert_polynomial(algorithm = 'singular') == J.hilbert_polynomial() + sage: J.hilbert_polynomial(algorithm='singular') == J.hilbert_polynomial() # optional - sage.libs.flint sage.libs.singular True Here is a bigger examples:: - sage: n = 4; m = 11; P = PolynomialRing(QQ, n * m, "x"); x = P.gens(); M = Matrix(n, x) + sage: n = 4; m = 11; P = PolynomialRing(QQ, n * m, "x"); x = P.gens() + sage: M = Matrix(n, x) sage: Minors = P.ideal(M.minors(2)) - sage: hp = Minors.hilbert_polynomial(); hp + sage: hp = Minors.hilbert_polynomial(); hp # optional - sage.libs.flint 1/21772800*t^13 + 61/21772800*t^12 + 1661/21772800*t^11 + 26681/21772800*t^10 + 93841/7257600*t^9 + 685421/7257600*t^8 + 1524809/3110400*t^7 + 39780323/21772800*t^6 + 6638071/1360800*t^5 @@ -2831,7 +2879,7 @@ def hilbert_polynomial(self, algorithm='sage'): with Singular. We don't test it here, as it has a side-effect on other tests that is not understood yet (see :trac:`26300`):: - sage: Minors.hilbert_polynomial(algorithm = 'singular') # not tested + sage: Minors.hilbert_polynomial(algorithm='singular') # not tested # optional - sage.libs.singular Traceback (most recent call last): ... RuntimeError: error in Singular function call 'hilbPoly': @@ -2842,9 +2890,10 @@ def hilbert_polynomial(self, algorithm='sage'): Note that in this example, the Hilbert polynomial gives the coefficients of the Hilbert-Poincaré series in all degrees:: - sage: P = PowerSeriesRing(QQ, 't', default_prec = 50) - sage: hs = Minors.hilbert_series() - sage: list(P(hs.numerator()) / P(hs.denominator())) == [hp(t = k) for k in range(50)] + sage: P = PowerSeriesRing(QQ, 't', default_prec=50) + sage: hs = Minors.hilbert_series() # optional - sage.libs.flint + sage: list(P(hs.numerator()) / P(hs.denominator())) == [hp(t=k) # optional - sage.libs.flint + ....: for k in range(50)] True TESTS: @@ -2853,23 +2902,23 @@ def hilbert_polynomial(self, algorithm='sage'): sage: P. = PolynomialRing(QQ) sage: I = Ideal([x^3, x*y^2, y^4, x^2*y*z, y^3*z, x^2*z^2, x*y*z^2, x*z^3]) - sage: I.hilbert_polynomial(algorithm='singular') + sage: I.hilbert_polynomial(algorithm='singular') # optional - sage.libs.singular 3 - sage: I.hilbert_polynomial() + sage: I.hilbert_polynomial() # optional - sage.libs.flint 3 - Check that this method works over QQbar (:trac:`25351`):: + Check that this method works over ``QQbar`` (:trac:`25351`):: - sage: P. = QQbar[] - sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5]) - sage: I.hilbert_polynomial() + sage: P. = QQbar[] # optional - sage.rings.number_field + sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5]) # optional - sage.rings.number_field + sage: I.hilbert_polynomial() # optional - sage.rings.number_field 5*t - 5 Check for :trac:`33597`:: sage: R. = QQ[] sage: I = R.ideal([X^2*Y^3, X*Z]) - sage: I.hilbert_polynomial() + sage: I.hilbert_polynomial() # optional - sage.libs.flint t + 5 """ if not self.is_homogeneous(): @@ -2915,13 +2964,13 @@ def hilbert_series(self, grading=None, algorithm='sage'): Let `I` (which is ``self``) be a homogeneous ideal and `R = \bigoplus_d R_d` (which is ``self.ring()``) be a graded commutative algebra over a field `K`. Then the - *Hilbert function* is defined as `H(d) = dim_K R_d` and + *Hilbert function* is defined as `H(d) = \dim_K R_d` and the *Hilbert series* of `I` is defined as the formal power series `HS(t) = \sum_{d=0}^{\infty} H(d) t^d`. This power series can be expressed as `HS(t) = Q(t) / (1-t)^n` where `Q(t)` is a polynomial - over `Z` and `n` the number of variables in `R`. + over `\ZZ` and `n` the number of variables in `R`. This method returns `Q(t) / (1-t)^n`, normalised so that the leading monomial of the numerator is positive. @@ -2932,48 +2981,48 @@ def hilbert_series(self, grading=None, algorithm='sage'): sage: P. = PolynomialRing(QQ) sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5]) - sage: I.hilbert_series() + sage: I.hilbert_series() # optional - sage.libs.flint (t^4 + t^3 + t^2 + t + 1)/(t^2 - 2*t + 1) sage: R. = PolynomialRing(QQ) - sage: J = R.ideal([a^2*b,a*b^2]) - sage: J.hilbert_series() + sage: J = R.ideal([a^2*b, a*b^2]) + sage: J.hilbert_series() # optional - sage.libs.flint (t^3 - t^2 - t - 1)/(t - 1) - sage: J.hilbert_series(grading=(10,3)) + sage: J.hilbert_series(grading=(10,3)) # optional - sage.libs.flint (t^25 + t^24 + t^23 - t^15 - t^14 - t^13 - t^12 - t^11 - t^10 - t^9 - t^8 - t^7 - t^6 - t^5 - t^4 - t^3 - t^2 - t - 1)/(t^12 + t^11 + t^10 - t^2 - t - 1) sage: K = R.ideal([a^2*b^3, a*b^4 + a^3*b^2]) - sage: K.hilbert_series(grading=[1,2]) + sage: K.hilbert_series(grading=[1,2]) # optional - sage.libs.flint (t^11 + t^8 - t^6 - t^5 - t^4 - t^3 - t^2 - t - 1)/(t^2 - 1) - sage: K.hilbert_series(grading=[2,1]) + sage: K.hilbert_series(grading=[2,1]) # optional - sage.libs.flint (2*t^7 - t^6 - t^4 - t^2 - 1)/(t - 1) TESTS:: - sage: I.hilbert_series() == I.hilbert_series(algorithm = 'singular') + sage: I.hilbert_series() == I.hilbert_series(algorithm='singular') # optional - sage.libs.flint sage.libs.singular True - sage: J.hilbert_series() == J.hilbert_series(algorithm = 'singular') + sage: J.hilbert_series() == J.hilbert_series(algorithm='singular') # optional - sage.libs.flint sage.libs.singular True - sage: J.hilbert_series(grading = (10,3)) == J.hilbert_series(grading = (10,3), algorithm = 'singular') + sage: J.hilbert_series(grading=(10,3)) == J.hilbert_series(grading=(10,3), algorithm='singular') # optional - sage.libs.flint sage.libs.singular True - sage: K.hilbert_series(grading = (1,2)) == K.hilbert_series(grading = (1,2), algorithm = 'singular') + sage: K.hilbert_series(grading=(1,2)) == K.hilbert_series(grading=(1,2), algorithm='singular') # optional - sage.libs.flint sage.libs.singular True - sage: K.hilbert_series(grading = (2,1)) == K.hilbert_series(grading = (2,1), algorithm = 'singular') + sage: K.hilbert_series(grading=(2,1)) == K.hilbert_series(grading=(2,1), algorithm='singular') # optional - sage.libs.flint sage.libs.singular True sage: P. = PolynomialRing(QQ) sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5]) - sage: I.hilbert_series(grading=5) + sage: I.hilbert_series(grading=5) # optional - sage.libs.flint Traceback (most recent call last): ... TypeError: grading must be a list or a tuple of integers Check that this method works over QQbar (:trac:`25351`):: - sage: P. = QQbar[] - sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5]) - sage: I.hilbert_series() + sage: P. = QQbar[] # optional - sage.rings.number_field + sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5]) # optional - sage.rings.number_field + sage: I.hilbert_series() # optional - sage.rings.number_field (t^4 + t^3 + t^2 + t + 1)/(t^2 - 2*t + 1) """ if not self.is_homogeneous(): @@ -3016,13 +3065,13 @@ def hilbert_numerator(self, grading = None, algorithm = 'sage'): Let `I` (which is ``self``) be a homogeneous ideal and `R = \bigoplus_d R_d` (which is ``self.ring()``) be a graded commutative algebra over a field `K`. Then the - *Hilbert function* is defined as `H(d) = dim_K R_d` and + *Hilbert function* is defined as `H(d) = \dim_K R_d` and the *Hilbert series* of `I` is defined as the formal power series `HS(t) = \sum_{d=0}^{\infty} H(d) t^d`. This power series can be expressed as `HS(t) = Q(t) / (1-t)^n` where `Q(t)` is a polynomial - over `Z` and `n` the number of variables in `R`. This + over `\ZZ` and `n` the number of variables in `R`. This method returns `Q(t)`, the numerator; hence the name, ``hilbert_numerator``. An optional ``grading`` can be given, in which case the graded (or weighted) Hilbert numerator is given. @@ -3031,29 +3080,29 @@ def hilbert_numerator(self, grading = None, algorithm = 'sage'): sage: P. = PolynomialRing(QQ) sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5]) - sage: I.hilbert_numerator() + sage: I.hilbert_numerator() # optional - sage.libs.flint -t^5 + 1 sage: R. = PolynomialRing(QQ) - sage: J = R.ideal([a^2*b,a*b^2]) - sage: J.hilbert_numerator() + sage: J = R.ideal([a^2*b, a*b^2]) + sage: J.hilbert_numerator() # optional - sage.libs.flint t^4 - 2*t^3 + 1 - sage: J.hilbert_numerator(grading=(10,3)) + sage: J.hilbert_numerator(grading=(10,3)) # optional - sage.libs.flint t^26 - t^23 - t^16 + 1 TESTS:: - sage: I.hilbert_numerator() == I.hilbert_numerator(algorithm = 'singular') + sage: I.hilbert_numerator() == I.hilbert_numerator(algorithm='singular') # optional - sage.libs.flint sage.libs.singular True - sage: J.hilbert_numerator() == J.hilbert_numerator(algorithm = 'singular') + sage: J.hilbert_numerator() == J.hilbert_numerator(algorithm='singular') # optional - sage.libs.flint sage.libs.singular True - sage: J.hilbert_numerator(grading=(10,3)) == J.hilbert_numerator(grading=(10,3), algorithm = 'singular') + sage: J.hilbert_numerator(grading=(10,3)) == J.hilbert_numerator(grading=(10,3), algorithm='singular') # optional - sage.libs.flint sage.libs.singular True Check that this method works over QQbar (:trac:`25351`):: - sage: P. = QQbar[] - sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5]) - sage: I.hilbert_numerator() + sage: P. = QQbar[] # optional - sage.rings.number_field + sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5]) # optional - sage.rings.number_field + sage: I.hilbert_numerator() # optional - sage.rings.number_field -t^5 + 1 Our two algorithms should always agree; not tested until @@ -3191,7 +3240,7 @@ def normal_basis(self, degree=None, algorithm='libsingular', EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: I = R.ideal(x^2+y^2+z^2-4, x^2+2*y^2-5, x*z-1) + sage: I = R.ideal(x^2 + y^2 + z^2 - 4, x^2 + 2*y^2 - 5, x*z - 1) sage: I.normal_basis() [y*z^2, z^2, y*z, z, x*y, y, x, 1] sage: I.normal_basis(algorithm='singular') @@ -3201,7 +3250,7 @@ def normal_basis(self, degree=None, algorithm='libsingular', particularly useful when the quotient ring is not finite-dimensional as a vector space. :: - sage: J = R.ideal(x^2+y^2+z^2-4, x^2+2*y^2-5) + sage: J = R.ideal(x^2 + y^2 + z^2 - 4, x^2 + 2*y^2 - 5) sage: J.dimension() 1 sage: [J.normal_basis(d) for d in (0..3)] @@ -3223,19 +3272,19 @@ def normal_basis(self, degree=None, algorithm='libsingular', Check that this method works over QQbar (:trac:`25351`):: - sage: R. = QQbar[] - sage: I = R.ideal(x^2+y^2+z^2-4, x^2+2*y^2-5, x*z-1) - sage: I.normal_basis() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: I = R.ideal(x^2+y^2+z^2-4, x^2+2*y^2-5, x*z-1) # optional - sage.rings.number_field + sage: I.normal_basis() # optional - sage.rings.number_field [y*z^2, z^2, y*z, z, x*y, y, x, 1] - sage: J = R.ideal(x^2+y^2+z^2-4, x^2+2*y^2-5) - sage: [J.normal_basis(d) for d in (0..3)] + sage: J = R.ideal(x^2+y^2+z^2-4, x^2+2*y^2-5) # optional - sage.rings.number_field + sage: [J.normal_basis(d) for d in (0..3)] # optional - sage.rings.number_field [[1], [z, y, x], [z^2, y*z, x*z, x*y], [z^3, y*z^2, x*z^2, x*y*z]] Check the option ``algorithm="singular"`` with a weighted term order:: sage: T = TermOrder('wdegrevlex', (1, 2, 3)) - sage: S. = PolynomialRing(GF(2), order=T) - sage: S.ideal(x^6 + y^3 + z^2).normal_basis(6, algorithm='singular') + sage: S. = PolynomialRing(GF(2), order=T) # optional - sage.rings.finite_rings + sage: S.ideal(x^6 + y^3 + z^2).normal_basis(6, algorithm='singular') # optional - sage.rings.finite_rings [x^4*y, x^2*y^2, y^3, x^3*z, x*y*z, z^2] """ from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence @@ -3315,14 +3364,14 @@ def _groebner_basis_macaulay2(self, strategy=None): Over finite fields, Macaulay2 supports different algorithms to compute Gröbner bases:: - sage: R = PolynomialRing(GF(101), 'x', 4) - sage: I = sage.rings.ideal.Cyclic(R) - sage: gb1 = I.groebner_basis('macaulay2:gb') # optional - macaulay2 - sage: I = sage.rings.ideal.Cyclic(R) - sage: gb2 = I.groebner_basis('macaulay2:mgb') # optional - macaulay2 - sage: I = sage.rings.ideal.Cyclic(R) - sage: gb3 = I.groebner_basis('macaulay2:f4') # optional - macaulay2 - sage: gb1 == gb2 == gb3 # optional - macaulay2 + sage: R = PolynomialRing(GF(101), 'x', 4) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Cyclic(R) # optional - sage.rings.finite_rings + sage: gb1 = I.groebner_basis('macaulay2:gb') # optional - macaulay2 # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Cyclic(R) # optional - sage.rings.finite_rings + sage: gb2 = I.groebner_basis('macaulay2:mgb') # optional - macaulay2 # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Cyclic(R) # optional - sage.rings.finite_rings + sage: gb3 = I.groebner_basis('macaulay2:f4') # optional - macaulay2 # optional - sage.rings.finite_rings + sage: gb1 == gb2 == gb3 # optional - macaulay2 # optional - sage.rings.finite_rings True TESTS:: @@ -3380,26 +3429,32 @@ def __init__(self, ring, gens, coerce=True, side = "left"): - ``gens`` - the generators of this ideal - ``coerce`` (optional - default True) - generators are coerced into the ring before creating the ideal - - ``side`` - optional string, either "left" (default) - or "twosided"; defines whether this ideal is left + - ``side`` - optional string, either ``"left"`` (default) + or ``"twosided"``; defines whether this ideal is left of two-sided. EXAMPLES:: - sage: A. = FreeAlgebra(QQ, 3) - sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) - sage: H.inject_variables() + sage: A. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y}) # optional - sage.combinat sage.modules + sage: H.inject_variables() # optional - sage.combinat sage.modules Defining x, y, z - sage: I = H.ideal([y^2, x^2, z^2-H.one()],coerce=False) # indirect doctest - sage: I #random - Left Ideal (y^2, x^2, z^2 - 1) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} - sage: sorted(I.gens(),key=str) + sage: I = H.ideal([y^2, x^2, z^2 - H.one()], # indirect doctest # optional - sage.combinat sage.modules + ....: coerce=False) + sage: I # random # optional - sage.combinat sage.modules + Left Ideal (y^2, x^2, z^2 - 1) of + Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, + nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} + sage: sorted(I.gens(), key=str) # optional - sage.combinat sage.modules [x^2, y^2, z^2 - 1] - sage: H.ideal([y^2, x^2, z^2-H.one()], side="twosided") #random - Twosided Ideal (y^2, x^2, z^2 - 1) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} - sage: sorted(H.ideal([y^2, x^2, z^2-H.one()], side="twosided").gens(),key=str) + sage: H.ideal([y^2, x^2, z^2 - H.one()], side="twosided") # random # optional - sage.combinat sage.modules + Twosided Ideal (y^2, x^2, z^2 - 1) of + Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, + nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} + sage: sorted(H.ideal([y^2, x^2, z^2 - H.one()], side="twosided").gens(), # optional - sage.combinat sage.modules + ....: key=str) [x^2, y^2, z^2 - 1] - sage: H.ideal([y^2, x^2, z^2-H.one()], side="right") + sage: H.ideal([y^2, x^2, z^2 - H.one()], side="right") # optional - sage.combinat sage.modules Traceback (most recent call last): ... ValueError: Only left and two-sided ideals are allowed. @@ -3424,14 +3479,15 @@ def __call_singular(self, cmd, arg = None): EXAMPLES:: - sage: A. = FreeAlgebra(QQ, 3) - sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) - sage: H.inject_variables() + sage: A. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y}) # optional - sage.combinat sage.modules + sage: H.inject_variables() # optional - sage.combinat sage.modules Defining x, y, z - sage: id = H.ideal(x + y, y + z) - sage: id.std() # indirect doctest # random - Left Ideal (z, y, x) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} - sage: sorted(id.std().gens(),key=str) + sage: id = H.ideal(x + y, y + z) # optional - sage.combinat sage.modules + sage: id.std() # indirect doctest # random # optional - sage.combinat sage.modules + Left Ideal (z, y, x) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, + nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} + sage: sorted(id.std().gens(), key=str) # optional - sage.combinat sage.modules [x, y, z] """ from sage.libs.singular.function import singular_function @@ -3444,47 +3500,61 @@ def __call_singular(self, cmd, arg = None): @cached_method def std(self): r""" - Computes a GB of the ideal. It is two-sided if and only if the ideal is two-sided. + Compute a GB of the ideal. It is two-sided if and only if the ideal is two-sided. EXAMPLES:: - sage: A. = FreeAlgebra(QQ, 3) - sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) - sage: H.inject_variables() + sage: A. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y}) # optional - sage.combinat sage.modules + sage: H.inject_variables() # optional - sage.combinat sage.modules Defining x, y, z - sage: I = H.ideal([y^2, x^2, z^2-H.one()],coerce=False) - sage: I.std() #random - Left Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} - sage: sorted(I.std().gens(),key=str) + sage: I = H.ideal([y^2, x^2, z^2 - H.one()], coerce=False) # optional - sage.combinat sage.modules + sage: I.std() #random # optional - sage.combinat sage.modules + Left Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of + Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, + nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} + sage: sorted(I.std().gens(), key=str) # optional - sage.combinat sage.modules [2*x*y - z - 1, x*z + x, x^2, y*z - y, y^2, z^2 - 1] - If the ideal is a left ideal, then std returns a left + If the ideal is a left ideal, then :meth:`std` returns a left Groebner basis. But if it is a two-sided ideal, then - the output of std and :meth:`twostd` coincide:: - - sage: JL = H.ideal([x^3, y^3, z^3 - 4*z]) - sage: JL #random - Left Ideal (x^3, y^3, z^3 - 4*z) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} - sage: sorted(JL.gens(),key=str) + the output of :meth:`std` and :meth:`twostd` coincide:: + + sage: JL = H.ideal([x^3, y^3, z^3 - 4*z]) # optional - sage.combinat sage.modules + sage: JL #random # optional - sage.combinat sage.modules + Left Ideal (x^3, y^3, z^3 - 4*z) of + Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, + nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} + sage: sorted(JL.gens(), key=str) # optional - sage.combinat sage.modules [x^3, y^3, z^3 - 4*z] - sage: JL.std() #random - Left Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z, 2*x*y*z - z^2 - 2*z, y^3, x^3) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} - sage: sorted(JL.std().gens(),key=str) + sage: JL.std() # random # optional - sage.combinat sage.modules + Left Ideal (z^3 - 4*z, y*z^2 - 2*y*z, + x*z^2 + 2*x*z, 2*x*y*z - z^2 - 2*z, y^3, x^3) of + Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, + nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} + sage: sorted(JL.std().gens(), key=str) # optional - sage.combinat sage.modules [2*x*y*z - z^2 - 2*z, x*z^2 + 2*x*z, x^3, y*z^2 - 2*y*z, y^3, z^3 - 4*z] - sage: JT = H.ideal([x^3, y^3, z^3 - 4*z], side='twosided') - sage: JT #random - Twosided Ideal (x^3, y^3, z^3 - 4*z) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} - sage: sorted(JT.gens(),key=str) + sage: JT = H.ideal([x^3, y^3, z^3 - 4*z], side='twosided') # optional - sage.combinat sage.modules + sage: JT #random # optional - sage.combinat sage.modules + Twosided Ideal (x^3, y^3, z^3 - 4*z) of + Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, + nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} + sage: sorted(JT.gens(), key=str) # optional - sage.combinat sage.modules [x^3, y^3, z^3 - 4*z] - sage: JT.std() #random - Twosided Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z, y^2*z - 2*y^2, 2*x*y*z - z^2 - 2*z, x^2*z + 2*x^2, y^3, x*y^2 - y*z, x^2*y - x*z - 2*x, x^3) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} - sage: sorted(JT.std().gens(),key=str) - [2*x*y*z - z^2 - 2*z, x*y^2 - y*z, x*z^2 + 2*x*z, x^2*y - x*z - 2*x, x^2*z + 2*x^2, x^3, y*z^2 - 2*y*z, y^2*z - 2*y^2, y^3, z^3 - 4*z] - sage: JT.std() == JL.twostd() + sage: JT.std() #random # optional - sage.combinat sage.modules + Twosided Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z, + y^2*z - 2*y^2, 2*x*y*z - z^2 - 2*z, x^2*z + 2*x^2, + y^3, x*y^2 - y*z, x^2*y - x*z - 2*x, x^3) of + Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, + nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} + sage: sorted(JT.std().gens(), key=str) # optional - sage.combinat sage.modules + [2*x*y*z - z^2 - 2*z, x*y^2 - y*z, x*z^2 + 2*x*z, x^2*y - x*z - 2*x, + x^2*z + 2*x^2, x^3, y*z^2 - 2*y*z, y^2*z - 2*y^2, y^3, z^3 - 4*z] + sage: JT.std() == JL.twostd() # optional - sage.combinat sage.modules True - ALGORITHM: Uses Singular's std command + ALGORITHM: Uses Singular's ``std`` command """ if self.side() == 'twosided': return self.twostd() @@ -3494,25 +3564,30 @@ def std(self): def elimination_ideal(self, variables): r""" Return the elimination ideal of this ideal with respect to the - variables given in "variables". + variables given in ``variables``. EXAMPLES:: - sage: A. = FreeAlgebra(QQ, 3) - sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) - sage: H.inject_variables() + sage: A. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y}) # optional - sage.combinat sage.modules + sage: H.inject_variables() # optional - sage.combinat sage.modules Defining x, y, z - sage: I = H.ideal([y^2, x^2, z^2-H.one()],coerce=False) - sage: I.elimination_ideal([x, z]) - Left Ideal (y^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {...} - sage: J = I.twostd() - sage: J - Twosided Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {...} - sage: J.elimination_ideal([x, z]) - Twosided Ideal (y^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {...} - - - ALGORITHM: Uses Singular's eliminate command + sage: I = H.ideal([y^2, x^2, z^2 - H.one()], coerce=False) # optional - sage.combinat sage.modules + sage: I.elimination_ideal([x, z]) # optional - sage.combinat sage.modules + Left Ideal (y^2) of + Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, + nc-relations: {...} + sage: J = I.twostd(); J # optional - sage.combinat sage.modules + Twosided Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of + Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, + nc-relations: {...} + sage: J.elimination_ideal([x, z]) # optional - sage.combinat sage.modules + Twosided Ideal (y^2) of + Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, + nc-relations: {...} + + + ALGORITHM: Uses Singular's ``eliminate`` command """ from sage.misc.misc_c import prod if self.side() == 'twosided': @@ -3525,21 +3600,22 @@ def elimination_ideal(self, variables): @cached_method def twostd(self): r""" - Computes a two-sided GB of the ideal (even if it is a left ideal). + Compute a two-sided GB of the ideal (even if it is a left ideal). EXAMPLES:: - sage: A. = FreeAlgebra(QQ, 3) - sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) - sage: H.inject_variables() + sage: A. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y}) # optional - sage.combinat sage.modules + sage: H.inject_variables() # optional - sage.combinat sage.modules Defining x, y, z - sage: I = H.ideal([y^2, x^2, z^2-H.one()],coerce=False) - sage: I.twostd() #random - Twosided Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field... - sage: sorted(I.twostd().gens(),key=str) + sage: I = H.ideal([y^2, x^2, z^2 - H.one()], coerce=False) # optional - sage.combinat sage.modules + sage: I.twostd() #random # optional - sage.combinat sage.modules + Twosided Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of + Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field... + sage: sorted(I.twostd().gens(), key=str) # optional - sage.combinat sage.modules [2*x*y - z - 1, x*z + x, x^2, y*z - y, y^2, z^2 - 1] - ALGORITHM: Uses Singular's twostd command + ALGORITHM: Uses Singular's ``twostd`` command """ return self.ring().ideal( self.__call_singular('twostd'), side='twosided') # return self.__call_singular('twostd') @@ -3555,13 +3631,13 @@ def _groebner_strategy(self): EXAMPLES:: - sage: A. = FreeAlgebra(QQ, 3) - sage: H. = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) - sage: I = H.ideal([y^2, x^2, z^2-H.one()],coerce=False) - sage: I._groebner_strategy() #random + sage: A. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: H. = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y}) # optional - sage.combinat sage.modules + sage: I = H.ideal([y^2, x^2, z^2-H.one()], coerce=False) # optional - sage.combinat sage.modules + sage: I._groebner_strategy() # random # optional - sage.combinat sage.modules Groebner Strategy for ideal generated by 6 elements over - Noncommutative Multivariate Polynomial Ring in x, y, z over Rational - Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} + Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, + nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} .. NOTE:: @@ -3577,31 +3653,29 @@ def reduce(self,p): It returns 0 if and only if the element is in this ideal. In any case, this reduction is unique up to monomial orders. - NOTE: - - There are left and two-sided ideals. Hence, - EXAMPLES:: - sage: A. = FreeAlgebra(QQ, 3) - sage: H. = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) - sage: I = H.ideal([y^2, x^2, z^2-H.one()],coerce=False, side='twosided') - sage: Q = H.quotient(I); Q #random - Quotient of Noncommutative Multivariate Polynomial Ring in x, y, z - over Rational Field, nc-relations: {z*x: x*z + 2*x, - z*y: y*z - 2*y, y*x: x*y - z} by the ideal (y^2, x^2, z^2 - 1) - sage: Q.2^2 == Q.one() # indirect doctest + sage: A. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: H. = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y}) # optional - sage.combinat sage.modules + sage: I = H.ideal([y^2, x^2, z^2 - H.one()], # optional - sage.combinat sage.modules + ....: coerce=False, side='twosided') + sage: Q = H.quotient(I); Q #random # optional - sage.combinat sage.modules + Quotient of + Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, + nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} + by the ideal (y^2, x^2, z^2 - 1) + sage: Q.2^2 == Q.one() # indirect doctest # optional - sage.combinat sage.modules True Here, we see that the relation that we just found in the quotient is actually a consequence of the given relations:: - sage: H.2^2-H.one() in I.std().gens() + sage: H.2^2 - H.one() in I.std().gens() # optional - sage.combinat sage.modules True Here is the corresponding direct test:: - sage: I.reduce(z^2) + sage: I.reduce(z^2) # optional - sage.combinat sage.modules 1 """ @@ -3613,21 +3687,26 @@ def _contains_(self,p): We define a left and a two-sided ideal:: - sage: A. = FreeAlgebra(QQ, 3) - sage: H. = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) - sage: JL = H.ideal([x^3, y^3, z^3 - 4*z]) - sage: JL.std() #random - Left Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z, 2*x*y*z - z^2 - 2*z, y^3, x^3) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} - sage: JT = H.ideal([x^3, y^3, z^3 - 4*z], side='twosided') - sage: JT.std() #random - Twosided Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z, y^2*z - 2*y^2, 2*x*y*z - z^2 - 2*z, x^2*z + 2*x^2, y^3, x*y^2 - y*z, x^2*y - x*z - 2*x, x^3) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} + sage: A. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: H. = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y}) # optional - sage.combinat sage.modules + sage: JL = H.ideal([x^3, y^3, z^3 - 4*z]) # optional - sage.combinat sage.modules + sage: JL.std() #random # optional - sage.combinat sage.modules + Left Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z, 2*x*y*z - z^2 - 2*z, y^3, x^3) of + Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, + nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} + sage: JT = H.ideal([x^3, y^3, z^3 - 4*z], side='twosided') # optional - sage.combinat sage.modules + sage: JT.std() #random # optional - sage.combinat sage.modules + Twosided Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z, y^2*z - 2*y^2, 2*x*y*z - z^2 - 2*z, + x^2*z + 2*x^2, y^3, x*y^2 - y*z, x^2*y - x*z - 2*x, x^3) of + Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, + nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} Apparently, ``x*y^2-y*z`` should be in the two-sided, but not in the left ideal:: - sage: x*y^2-y*z in JL #indirect doctest + sage: x*y^2-y*z in JL #indirect doctest # optional - sage.combinat sage.modules False - sage: x*y^2-y*z in JT + sage: x*y^2-y*z in JT # optional - sage.combinat sage.modules True """ @@ -3636,7 +3715,7 @@ def _contains_(self,p): @require_field def syzygy_module(self): r""" - Computes the first syzygy (i.e., the module of relations of the + Compute the first syzygy (i.e., the module of relations of the given generators) of the ideal. NOTE: @@ -3647,12 +3726,12 @@ def syzygy_module(self): EXAMPLES:: - sage: A. = FreeAlgebra(QQ, 3) - sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) - sage: H.inject_variables() + sage: A. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y}) # optional - sage.combinat sage.modules + sage: H.inject_variables() # optional - sage.combinat sage.modules Defining x, y, z - sage: I = H.ideal([y^2, x^2, z^2-H.one()],coerce=False) - sage: G = vector(I.gens()); G + sage: I = H.ideal([y^2, x^2, z^2-H.one()], coerce=False) # optional - sage.combinat sage.modules + sage: G = vector(I.gens()); G # optional - sage.combinat sage.modules d...: UserWarning: You are constructing a free module over a noncommutative ring. Sage does not have a concept of left/right and both sided modules, so be careful. @@ -3664,7 +3743,7 @@ def syzygy_module(self): It's also not guaranteed that all multiplications are done from the right side. (y^2, x^2, z^2 - 1) - sage: M = I.syzygy_module(); M + sage: M = I.syzygy_module(); M # optional - sage.combinat sage.modules [ -z^2 - 8*z - 15 0 y^2] [ 0 -z^2 + 8*z - 15 x^2] [ x^2*z^2 + 8*x^2*z + 15*x^2 -y^2*z^2 + 8*y^2*z - 15*y^2 -4*x*y*z + 2*z^2 + 2*z] @@ -3675,10 +3754,10 @@ def syzygy_module(self): [ x^4*z + 4*x^4 -x^2*y^2*z + 4*x^2*y^2 - 4*x*y*z^2 + 32*x*y*z - 6*z^3 - 64*x*y + 66*z^2 - 240*z + 288 0] [x^3*y^2*z + 4*x^3*y^2 + 18*x^2*y*z - 36*x*z^3 + 66*x^2*y - 432*x*z^2 - 1656*x*z - 2052*x -x*y^4*z + 4*x*y^4 - 8*y^3*z^2 + 62*y^3*z - 114*y^3 48*y*z^2 - 36*y*z] - sage: M*G + sage: M*G # optional - sage.combinat sage.modules (0, 0, 0, 0, 0, 0, 0, 0, 0) - ALGORITHM: Uses Singular's syz command + ALGORITHM: Uses Singular's ``syz`` command """ if self.side() == 'twosided': warn("The result of this Syzygy computation is one-sided (left)!") @@ -3702,12 +3781,12 @@ def res(self, length): EXAMPLES:: - sage: A. = FreeAlgebra(QQ, 3) - sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) - sage: H.inject_variables() + sage: A. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y}) # optional - sage.combinat sage.modules + sage: H.inject_variables() # optional - sage.combinat sage.modules Defining x, y, z - sage: I = H.ideal([y^2, x^2, z^2-H.one()],coerce=False) - sage: I.res(3) + sage: I = H.ideal([y^2, x^2, z^2-H.one()], coerce=False) # optional - sage.combinat sage.modules + sage: I.res(3) # optional - sage.combinat sage.modules """ if self.side() == 'twosided': @@ -3730,15 +3809,15 @@ def __init__(self, ring, gens, coerce=True): - ``gens`` - a list of generators for the ideal - - ``coerce`` - coerce elements to the ring ``ring``? + - ``coerce`` - whether to coerce elements to the ring ``ring`` EXAMPLES:: sage: R. = PolynomialRing(IntegerRing(), 2, order='lex') sage: R.ideal([x, y]) Ideal (x, y) of Multivariate Polynomial Ring in x, y over Integer Ring - sage: R. = GF(3)[] - sage: R.ideal([x0^2, x1^3]) + sage: R. = GF(3)[] # optional - sage.rings.finite_rings + sage: R.ideal([x0^2, x1^3]) # optional - sage.rings.finite_rings Ideal (x0^2, x1^3) of Multivariate Polynomial Ring in x0, x1 over Finite Field of size 3 """ Ideal_generic.__init__(self, ring, gens, coerce=coerce) @@ -3765,7 +3844,7 @@ def gens(self): EXAMPLES:: sage: P. = PolynomialRing(QQ,2) - sage: I = Ideal([x,y+1]); I + sage: I = Ideal([x, y + 1]); I Ideal (x, y + 1) of Multivariate Polynomial Ring in x, y over Rational Field sage: I.gens() [x, y + 1] @@ -3781,7 +3860,7 @@ def basis(self): EXAMPLES:: sage: P. = PolynomialRing(QQ,2) - sage: I = Ideal([x,y+1]) + sage: I = Ideal([x, y + 1]) sage: I.basis [x, y + 1] @@ -3824,22 +3903,22 @@ def __richcmp__(self, other, op): :: - sage: R. = GF(32003)[] - sage: I = R*[x^2 + x, y] - sage: J = R*[x + 1, y] - sage: J < I + sage: R. = GF(32003)[] # optional - sage.rings.finite_rings + sage: I = R*[x^2 + x, y] # optional - sage.rings.finite_rings + sage: J = R*[x + 1, y] # optional - sage.rings.finite_rings + sage: J < I # optional - sage.rings.finite_rings False - sage: I < J + sage: I < J # optional - sage.rings.finite_rings True :: - sage: R. = GF(32003)[] - sage: I = R*[x^2 + x, y] - sage: J = R*[x + 1, y] - sage: J > I + sage: R. = GF(32003)[] # optional - sage.rings.finite_rings + sage: I = R*[x^2 + x, y] # optional - sage.rings.finite_rings + sage: J = R*[x + 1, y] # optional - sage.rings.finite_rings + sage: J > I # optional - sage.rings.finite_rings True - sage: I > J + sage: I > J # optional - sage.rings.finite_rings False :: @@ -3858,8 +3937,8 @@ def __richcmp__(self, other, op): :: sage: R. = QQ[] - sage: I = (x^3 + y, y)*R - sage: J = (x^3 + y, y, y*x^3 + y^2)*R + sage: I = (x^3 + y, y) * R + sage: J = (x^3 + y, y, y*x^3 + y^2) * R sage: I == J True @@ -3877,15 +3956,15 @@ def __richcmp__(self, other, op): We test to make sure that pickling works with the cached Groebner basis:: - sage: R. = GF(32003)[] - sage: I = R*[x^2 + x, y] - sage: J = R*[x + 1, y] - sage: J >= I + sage: R. = GF(32003)[] # optional - sage.rings.finite_rings + sage: I = R*[x^2 + x, y] # optional - sage.rings.finite_rings + sage: J = R*[x + 1, y] # optional - sage.rings.finite_rings + sage: J >= I # optional - sage.rings.finite_rings True - sage: I >= J + sage: I >= J # optional - sage.rings.finite_rings False - sage: loads(dumps(I)).__getstate__() + sage: loads(dumps(I)).__getstate__() # optional - sage.rings.finite_rings (Monoid of ideals of Multivariate Polynomial Ring in x, y over Finite Field of size 32003, {'_Ideal_generic__gens': (x^2 + x, y), '_Ideal_generic__ring': Multivariate Polynomial Ring in x, y over Finite Field of size 32003, @@ -4059,7 +4138,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal INPUT: - ``algorithm`` - determines the algorithm to use, see below - for available algorithms. + for available algorithms. - ``deg_bound`` - only compute to degree ``deg_bound``, that is, ignore all S-polynomials of higher degree. (default: @@ -4079,78 +4158,78 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal :func:`set_verbose`. - ``*args`` - additional parameters passed to the respective - implementations + implementations - ``**kwds`` - additional keyword parameters passed to the - respective implementations + respective implementations ALGORITHMS: - '' + ``''`` autoselect (default) - 'singular:groebner' + ``'singular:groebner'`` Singular's ``groebner`` command - 'singular:std' + ``'singular:std'`` Singular's ``std`` command - 'singular:stdhilb' + ``'singular:stdhilb'`` Singular's ``stdhib`` command - 'singular:stdfglm' + ``'singular:stdfglm'`` Singular's ``stdfglm`` command - 'singular:slimgb' + ``'singular:slimgb'`` Singular's ``slimgb`` command - 'libsingular:groebner' + ``'libsingular:groebner'`` libSingular's ``groebner`` command - 'libsingular:std' + ``'libsingular:std'`` libSingular's ``std`` command - 'libsingular:slimgb' + ``'libsingular:slimgb'`` libSingular's ``slimgb`` command - 'libsingular:stdhilb' + ``'libsingular:stdhilb'`` libSingular's ``stdhib`` command - 'libsingular:stdfglm' + ``'libsingular:stdfglm'`` libSingular's ``stdfglm`` command - 'toy:buchberger' + ``'toy:buchberger'`` Sage's toy/educational buchberger without Buchberger criteria - 'toy:buchberger2' + ``'toy:buchberger2'`` Sage's toy/educational buchberger with Buchberger criteria - 'toy:d_basis' + ``'toy:d_basis'`` Sage's toy/educational algorithm for computation over PIDs - 'macaulay2:gb' + ``'macaulay2:gb'`` Macaulay2's ``gb`` command (if available) - 'macaulay2:f4' + ``'macaulay2:f4'`` Macaulay2's ``GroebnerBasis`` command with the strategy "F4" (if available) - 'macaulay2:mgb' + ``'macaulay2:mgb'`` Macaulay2's ``GroebnerBasis`` command with the strategy "MGB" (if available) - 'msolve' + ``'msolve'`` `optional package msolve <../spkg/msolve.html>`_ (degrevlex order, prime fields) - 'magma:GroebnerBasis' + ``'magma:GroebnerBasis'`` Magma's ``Groebnerbasis`` command (if available) - 'ginv:TQ', 'ginv:TQBlockHigh', 'ginv:TQBlockLow' and 'ginv:TQDegree' + ``'ginv:TQ'``, ``'ginv:TQBlockHigh'``, ``'ginv:TQBlockLow'`` and ``'ginv:TQDegree'`` One of GINV's implementations (if available) - 'giac:gbasis' + ``'giac:gbasis'`` Giac's ``gbasis`` command (if available) - If only a system is given - e.g. 'magma' - the default algorithm is + If only a system is given - e.g. ``'magma'`` - the default algorithm is chosen for that system. .. NOTE:: @@ -4158,7 +4237,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal The Singular and libSingular versions of the respective algorithms are identical, but the former calls an external Singular process while the latter calls a C function, - i.e. the calling overhead is smaller. However, the + and thus the calling overhead is smaller. However, the libSingular interface does not support pretty printing of computation protocols. @@ -4222,9 +4301,9 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal Giac's gbasis over `\QQ` can benefit from a probabilistic lifting and multi threaded operations:: - sage: A9=PolynomialRing(QQ,9,'x') - sage: I9=sage.rings.ideal.Katsura(A9) - sage: print("possible output from giac", flush=True); I9.groebner_basis("giac",proba_epsilon=1e-7) # long time (3s) + sage: A9 = PolynomialRing(QQ, 9, 'x') + sage: I9 = sage.rings.ideal.Katsura(A9) + sage: print("possible output from giac", flush=True); I9.groebner_basis("giac", proba_epsilon=1e-7) # long time (3s) possible output... Polynomial Sequence with 143 Polynomials in 9 Variables @@ -4251,41 +4330,41 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal Here we use Macaulay2 with three different strategies over a finite field. :: - sage: R. = PolynomialRing(GF(101), 3) - sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching - sage: I.groebner_basis('macaulay2:gb') # optional - macaulay2 + sage: R. = PolynomialRing(GF(101), 3) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching # optional - sage.rings.finite_rings + sage: I.groebner_basis('macaulay2:gb') # optional - macaulay2 # optional - sage.rings.finite_rings [c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c, b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1] - sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching - sage: I.groebner_basis('macaulay2:f4') # optional - macaulay2 + sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching # optional - sage.rings.finite_rings + sage: I.groebner_basis('macaulay2:f4') # optional - macaulay2 # optional - sage.rings.finite_rings [c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c, b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1] - sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching - sage: I.groebner_basis('macaulay2:mgb') # optional - macaulay2 + sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching # optional - sage.rings.finite_rings + sage: I.groebner_basis('macaulay2:mgb') # optional - macaulay2 # optional - sage.rings.finite_rings [c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c, b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1] Over prime fields of small characteristic, we can also use the `optional package msolve <../spkg/msolve.html>`_:: - sage: R. = PolynomialRing(GF(101), 3) - sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching - sage: I.groebner_basis('msolve') # optional - msolve + sage: R. = PolynomialRing(GF(101), 3) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching # optional - sage.rings.finite_rings + sage: I.groebner_basis('msolve') # optional - msolve # optional - sage.rings.finite_rings [a + 2*b + 2*c - 1, b*c - 19*c^2 + 10*b + 40*c, b^2 - 41*c^2 + 20*b - 20*c, c^3 + 28*c^2 - 37*b + 13*c] :: - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching - sage: I.groebner_basis('magma:GroebnerBasis') # optional - magma + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # optional - sage.rings.finite_rings + sage: I.groebner_basis('magma:GroebnerBasis') # optional - magma # optional - sage.rings.finite_rings [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c] Singular and libSingular can compute Groebner basis with degree restrictions. :: sage: R. = QQ[] - sage: I = R*[x^3+y^2,x^2*y+1] + sage: I = R*[x^3 + y^2, x^2*y + 1] sage: I.groebner_basis(algorithm='singular') [x^3 + y^2, x^2*y + 1, y^3 - x] - sage: I.groebner_basis(algorithm='singular',deg_bound=2) + sage: I.groebner_basis(algorithm='singular', deg_bound=2) [x^3 + y^2, x^2*y + 1] sage: I.groebner_basis() [x^3 + y^2, x^2*y + 1, y^3 - x] @@ -4367,16 +4446,16 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal Sage also supports local orderings:: - sage: P. = PolynomialRing(QQ,3,order='negdegrevlex') - sage: I = P * ( x*y*z + z^5, 2*x^2 + y^3 + z^7, 3*z^5 +y ^5 ) + sage: P. = PolynomialRing(QQ, 3, order='negdegrevlex') + sage: I = P * ( x*y*z + z^5, 2*x^2 + y^3 + z^7, 3*z^5 + y^5 ) sage: I.groebner_basis() [x^2 + 1/2*y^3, x*y*z + z^5, y^5 + 3*z^5, y^4*z - 2*x*z^5, z^6] We can represent every element in the ideal as a combination of the generators using the :meth:`~sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict.lift` method:: - sage: P. = PolynomialRing(QQ,3) - sage: I = P * ( x*y*z + z^5, 2*x^2 + y^3 + z^7, 3*z^5 +y ^5 ) + sage: P. = PolynomialRing(QQ, 3) + sage: I = P * ( x*y*z + z^5, 2*x^2 + y^3 + z^7, 3*z^5 + y^5 ) sage: J = Ideal(I.groebner_basis()) sage: f = sum(P.random_element(terms=2)*f for f in I.gens()) sage: f # random @@ -4448,54 +4527,54 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal Check that this method works over QQbar (:trac:`25351`):: - sage: P. = PolynomialRing(QQbar,3, order='lex') - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching - sage: I.groebner_basis() + sage: P. = PolynomialRing(QQbar, 3, order='lex') # optional - sage.rings.number_field + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # optional - sage.rings.number_field + sage: I.groebner_basis() # optional - sage.rings.number_field [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching - sage: I.groebner_basis('libsingular:groebner') + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # optional - sage.rings.number_field + sage: I.groebner_basis('libsingular:groebner') # optional - sage.rings.number_field [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching - sage: I.groebner_basis('libsingular:std') + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # optional - sage.rings.number_field + sage: I.groebner_basis('libsingular:std') # optional - sage.rings.number_field [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching - sage: I.groebner_basis('libsingular:stdhilb') + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # optional - sage.rings.number_field + sage: I.groebner_basis('libsingular:stdhilb') # optional - sage.rings.number_field [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching - sage: I.groebner_basis('libsingular:stdfglm') + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # optional - sage.rings.number_field + sage: I.groebner_basis('libsingular:stdfglm') # optional - sage.rings.number_field [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching - sage: I.groebner_basis('libsingular:slimgb') + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # optional - sage.rings.number_field + sage: I.groebner_basis('libsingular:slimgb') # optional - sage.rings.number_field [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching - sage: J = I.change_ring(P.change_ring(order='degrevlex')) - sage: gb = J.groebner_basis('giac') # random - sage: gb + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # optional - sage.rings.number_field + sage: J = I.change_ring(P.change_ring(order='degrevlex')) # optional - sage.rings.number_field + sage: gb = J.groebner_basis('giac') # random # optional - sage.rings.number_field + sage: gb # optional - sage.rings.number_field [c^3 + (-79/210)*c^2 + 1/30*b + 1/70*c, b^2 + (-3/5)*c^2 + (-1/5)*b + 1/5*c, b*c + 6/5*c^2 + (-1/10)*b + (-2/5)*c, a + 2*b + 2*c - 1] - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching - sage: I.groebner_basis('toy:buchberger2') + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # optional - sage.rings.number_field + sage: I.groebner_basis('toy:buchberger2') # optional - sage.rings.number_field [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching - sage: I.groebner_basis('macaulay2:gb') # optional - macaulay2 + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # optional - sage.rings.number_field + sage: I.groebner_basis('macaulay2:gb') # optional - macaulay2 # optional - sage.rings.number_field [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching - sage: I.groebner_basis('magma:GroebnerBasis') # optional - magma + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # optional - sage.rings.number_field + sage: I.groebner_basis('magma:GroebnerBasis') # optional - magma # optional - sage.rings.number_field [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] msolve currently supports the degrevlex order only:: - sage: R. = PolynomialRing(GF(101), 3, order='lex') - sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching - sage: I.groebner_basis('msolve') # optional - msolve + sage: R. = PolynomialRing(GF(101), 3, order='lex') # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching # optional - sage.rings.finite_rings + sage: I.groebner_basis('msolve') # optional - msolve # optional - sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: msolve only supports the degrevlex order (use transformed_basis()) @@ -4717,27 +4796,32 @@ def subs(self, in_dict=None, **kwds): OUTPUT: A new ideal with modified generators. If possible, in the same - polynomial ring. Raises a ``TypeError`` if no common + polynomial ring. Raises a :class:`TypeError` if no common polynomial ring of the substituted generators can be found. EXAMPLES:: - sage: R. = PolynomialRing(ZZ,2,'xy') - sage: I = R.ideal(x^5+y^5, x^2 + y + x^2*y^2 + 5); I - Ideal (x^5 + y^5, x^2*y^2 + x^2 + y + 5) of Multivariate Polynomial Ring in x, y over Integer Ring + sage: R. = PolynomialRing(ZZ, 2, 'xy') + sage: I = R.ideal(x^5 + y^5, x^2 + y + x^2*y^2 + 5); I + Ideal (x^5 + y^5, x^2*y^2 + x^2 + y + 5) + of Multivariate Polynomial Ring in x, y over Integer Ring sage: I.subs(x=y) - Ideal (2*y^5, y^4 + y^2 + y + 5) of Multivariate Polynomial Ring in x, y over Integer Ring - sage: I.subs({x:y}) # same substitution but with dictionary - Ideal (2*y^5, y^4 + y^2 + y + 5) of Multivariate Polynomial Ring in x, y over Integer Ring + Ideal (2*y^5, y^4 + y^2 + y + 5) + of Multivariate Polynomial Ring in x, y over Integer Ring + sage: I.subs({x: y}) # same substitution but with dictionary + Ideal (2*y^5, y^4 + y^2 + y + 5) + of Multivariate Polynomial Ring in x, y over Integer Ring The new ideal can be in a different ring:: - sage: R. = PolynomialRing(QQ,2) - sage: S. = PolynomialRing(QQ,2) - sage: I = R.ideal(a^2+b^2+a-b+2); I - Ideal (a^2 + b^2 + a - b + 2) of Multivariate Polynomial Ring in a, b over Rational Field + sage: R. = PolynomialRing(QQ, 2) + sage: S. = PolynomialRing(QQ, 2) + sage: I = R.ideal(a^2 + b^2 + a - b + 2); I + Ideal (a^2 + b^2 + a - b + 2) + of Multivariate Polynomial Ring in a, b over Rational Field sage: I.subs(a=x, b=y) - Ideal (x^2 + y^2 + x - y + 2) of Multivariate Polynomial Ring in x, y over Rational Field + Ideal (x^2 + y^2 + x - y + 2) + of Multivariate Polynomial Ring in x, y over Rational Field The resulting ring need not be a multivariate polynomial ring:: @@ -4751,9 +4835,10 @@ def subs(self, in_dict=None, **kwds): Variables that are not substituted remain unchanged:: - sage: R. = PolynomialRing(QQ,2) - sage: I = R.ideal(x^2+y^2+x-y+2); I - Ideal (x^2 + y^2 + x - y + 2) of Multivariate Polynomial Ring in x, y over Rational Field + sage: R. = PolynomialRing(QQ, 2) + sage: I = R.ideal(x^2 + y^2 + x - y + 2); I + Ideal (x^2 + y^2 + x - y + 2) + of Multivariate Polynomial Ring in x, y over Rational Field sage: I.subs(x=1) Ideal (y^2 - y + 4) of Multivariate Polynomial Ring in x, y over Rational Field """ @@ -4775,7 +4860,7 @@ def reduce(self, f): EXAMPLES:: sage: R. = PolynomialRing(QQ, 2) - sage: I = (x^3 + y, y)*R + sage: I = (x^3 + y, y) * R sage: I.reduce(y) 0 sage: I.reduce(x^3) @@ -4783,7 +4868,7 @@ def reduce(self, f): sage: I.reduce(x - y) x - sage: I = (y^2 - (x^3 + x))*R + sage: I = (y^2 - (x^3 + x)) * R sage: I.reduce(x^3) y^2 - x sage: I.reduce(x^6) @@ -4813,7 +4898,7 @@ def _contains_(self, f): EXAMPLES:: sage: R. = QQ[] - sage: I = (x^3 + y, y)*R + sage: I = (x^3 + y, y) * R sage: x in I # indirect doctest False sage: y in I @@ -4842,28 +4927,28 @@ def homogenize(self, var='h'): EXAMPLES:: - sage: P. = PolynomialRing(GF(2)) - sage: I = Ideal([x^2*y + z + 1, x + y^2 + 1]); I + sage: P. = PolynomialRing(GF(2)) # optional - sage.rings.finite_rings + sage: I = Ideal([x^2*y + z + 1, x + y^2 + 1]); I # optional - sage.rings.finite_rings Ideal (x^2*y + z + 1, y^2 + x + 1) of Multivariate Polynomial Ring in x, y, z over Finite Field of size 2 :: - sage: I.homogenize() + sage: I.homogenize() # optional - sage.rings.finite_rings Ideal (x^2*y + z*h^2 + h^3, y^2 + x*h + h^2) of Multivariate Polynomial Ring in x, y, z, h over Finite Field of size 2 :: - sage: I.homogenize(y) + sage: I.homogenize(y) # optional - sage.rings.finite_rings Ideal (x^2*y + y^3 + y^2*z, x*y) of Multivariate Polynomial Ring in x, y, z over Finite Field of size 2 :: - sage: I = Ideal([x^2*y + z^3 + y^2*x, x + y^2 + 1]) - sage: I.homogenize() + sage: I = Ideal([x^2*y + z^3 + y^2*x, x + y^2 + 1]) # optional - sage.rings.finite_rings + sage: I.homogenize() # optional - sage.rings.finite_rings Ideal (x^2*y + x*y^2 + z^3, y^2 + x*h + h^2) of Multivariate Polynomial Ring in x, y, z, h over Finite Field of size 2 @@ -4875,7 +4960,7 @@ def homogenize(self, var='h'): def is_homogeneous(self): r""" Return ``True`` if this ideal is spanned by homogeneous - polynomials, i.e. if it is a homogeneous ideal. + polynomials, i.e., if it is a homogeneous ideal. EXAMPLES:: @@ -4939,51 +5024,51 @@ def degree_of_semi_regularity(self): We consider a homogeneous example:: sage: n = 8 - sage: K = GF(127) - sage: P = PolynomialRing(K,n,'x') - sage: s = [K.random_element() for _ in range(n)] - sage: L = [] - sage: for i in range(2*n): - ....: f = P.random_element(degree=2, terms=binomial(n,2)) + sage: K = GF(127) # optional - sage.rings.finite_rings + sage: P = PolynomialRing(K, n, 'x') # optional - sage.rings.finite_rings + sage: s = [K.random_element() for _ in range(n)] # optional - sage.rings.finite_rings + sage: L = [] # optional - sage.rings.finite_rings + sage: for i in range(2 * n): # optional - sage.rings.finite_rings + ....: f = P.random_element(degree=2, terms=binomial(n, 2)) ....: f -= f(*s) ....: L.append(f.homogenize()) - sage: I = Ideal(L) - sage: I.degree_of_semi_regularity() + sage: I = Ideal(L) # optional - sage.rings.finite_rings + sage: I.degree_of_semi_regularity() # optional - sage.rings.finite_rings 4 From this, we expect a Groebner basis computation to reach at most degree 4. For homogeneous systems this is equivalent to the largest degree in the Groebner basis:: - sage: max(f.degree() for f in I.groebner_basis()) + sage: max(f.degree() for f in I.groebner_basis()) # optional - sage.rings.finite_rings 4 We increase the number of polynomials and observe a decrease the degree of regularity:: - sage: for i in range(2*n): - ....: f = P.random_element(degree=2, terms=binomial(n,2)) + sage: for i in range(2 * n): # optional - sage.rings.finite_rings + ....: f = P.random_element(degree=2, terms=binomial(n, 2)) ....: f -= f(*s) ....: L.append(f.homogenize()) - sage: I = Ideal(L) - sage: I.degree_of_semi_regularity() + sage: I = Ideal(L) # optional - sage.rings.finite_rings + sage: I.degree_of_semi_regularity() # optional - sage.rings.finite_rings 3 - sage: max(f.degree() for f in I.groebner_basis()) + sage: max(f.degree() for f in I.groebner_basis()) # optional - sage.rings.finite_rings 3 The degree of regularity approaches 2 for quadratic systems as the number of polynomials approaches `n^2`:: - sage: for i in range((n-4)*n): - ....: f = P.random_element(degree=2, terms=binomial(n,2)) + sage: for i in range((n-4) * n): # optional - sage.rings.finite_rings + ....: f = P.random_element(degree=2, terms=binomial(n, 2)) ....: f -= f(*s) ....: L.append(f.homogenize()) - sage: I = Ideal(L) - sage: I.degree_of_semi_regularity() + sage: I = Ideal(L) # optional - sage.rings.finite_rings + sage: I.degree_of_semi_regularity() # optional - sage.rings.finite_rings 2 - sage: max(f.degree() for f in I.groebner_basis()) + sage: max(f.degree() for f in I.groebner_basis()) # optional - sage.rings.finite_rings 2 .. NOTE:: @@ -5018,59 +5103,59 @@ def plot(self, *args, **kwds): - ``self`` - a principal ideal in 2 variables - ``algorithm`` - set this to 'surf' if you want 'surf' to - plot the ideal (default: None) + plot the ideal (default: None) - ``*args`` - optional tuples ``(variable, minimum, maximum)`` - for plotting dimensions + for plotting dimensions - ``**kwds`` - optional keyword arguments passed on to - ``implicit_plot`` + ``implicit_plot`` EXAMPLES: Implicit plotting in 2-d:: - sage: R. = PolynomialRing(QQ,2) + sage: R. = PolynomialRing(QQ, 2) sage: I = R.ideal([y^3 - x^2]) - sage: I.plot() # cusp + sage: I.plot() # cusp # optional - sage.plot Graphics object consisting of 1 graphics primitive :: sage: I = R.ideal([y^2 - x^2 - 1]) - sage: I.plot((x,-3, 3), (y, -2, 2)) # hyperbola + sage: I.plot((x,-3, 3), (y, -2, 2)) # hyperbola # optional - sage.plot Graphics object consisting of 1 graphics primitive :: sage: I = R.ideal([y^2 + x^2*(1/4) - 1]) - sage: I.plot() # ellipse + sage: I.plot() # ellipse # optional - sage.plot Graphics object consisting of 1 graphics primitive :: sage: I = R.ideal([y^2-(x^2-1)*(x-2)]) - sage: I.plot() # elliptic curve + sage: I.plot() # elliptic curve # optional - sage.plot Graphics object consisting of 1 graphics primitive :: sage: f = ((x+3)^3 + 2*(x+3)^2 - y^2)*(x^3 - y^2)*((x-3)^3-2*(x-3)^2-y^2) sage: I = R.ideal(f) - sage: I.plot() # the Singular logo + sage: I.plot() # the Singular logo # optional - sage.plot Graphics object consisting of 1 graphics primitive :: - sage: R. = PolynomialRing(QQ,2) + sage: R. = PolynomialRing(QQ, 2) sage: I = R.ideal([x - 1]) - sage: I.plot((y, -2, 2)) # vertical line + sage: I.plot((y, -2, 2)) # vertical line # optional - sage.plot Graphics object consisting of 1 graphics primitive :: sage: I = R.ideal([-x^2*y + 1]) - sage: I.plot() # blow up + sage: I.plot() # blow up # optional - sage.plot Graphics object consisting of 1 graphics primitive """ @@ -5149,12 +5234,12 @@ def random_element(self, degree, compute_gb=False, *args, **kwds): We compute a uniformly random element up to the provided degree. :: - sage: P. = GF(127)[] - sage: I = sage.rings.ideal.Katsura(P) - sage: f = I.random_element(degree=4, compute_gb=True, terms=infinity) - sage: f.degree() <= 4 + sage: P. = GF(127)[] # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings + sage: f = I.random_element(degree=4, compute_gb=True, terms=infinity) # optional - sage.rings.finite_rings + sage: f.degree() <= 4 # optional - sage.rings.finite_rings True - sage: len(list(f)) <= 35 + sage: len(list(f)) <= 35 # optional - sage.rings.finite_rings True Note that sampling uniformly at random from the ideal at some large enough degree is @@ -5162,45 +5247,48 @@ def random_element(self, degree, compute_gb=False, *args, **kwds): basis if we can sample uniformly at random from an ideal:: sage: n = 3; d = 4 - sage: P = PolynomialRing(GF(127), n, 'x') - sage: I = sage.rings.ideal.Cyclic(P) + sage: P = PolynomialRing(GF(127), n, 'x') # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Cyclic(P) # optional - sage.rings.finite_rings 1. We sample `n^d` uniformly random elements in the ideal:: - sage: F = Sequence(I.random_element(degree=d, compute_gb=True, terms=infinity) for _ in range(n^d)) + sage: F = Sequence(I.random_element(degree=d, compute_gb=True, # optional - sage.rings.finite_rings + ....: terms=infinity) + ....: for _ in range(n^d)) 2. We linearize and compute the echelon form:: - sage: A,v = F.coefficient_matrix() - sage: A.echelonize() + sage: A, v = F.coefficient_matrix() # optional - sage.rings.finite_rings + sage: A.echelonize() # optional - sage.rings.finite_rings 3. The result is the desired Gröbner basis:: - sage: G = Sequence((A*v).list()) - sage: G.is_groebner() - True - sage: Ideal(G) == I - True + sage: G = Sequence((A * v).list()) # optional - sage.rings.finite_rings + sage: G.is_groebner() # optional - sage.rings.finite_rings + True + sage: Ideal(G) == I # optional - sage.rings.finite_rings + True We return some element in the ideal with no guarantee on the distribution:: - sage: P = PolynomialRing(GF(127), 10, 'x') - sage: I = sage.rings.ideal.Katsura(P) - sage: f = I.random_element(degree=3) - sage: f # random + sage: P = PolynomialRing(GF(127), 10, 'x') # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings + sage: f = I.random_element(degree=3) # optional - sage.rings.finite_rings + sage: f # random # optional - sage.rings.finite_rings -25*x0^2*x1 + 14*x1^3 + 57*x0*x1*x2 + ... + 19*x7*x9 + 40*x8*x9 + 49*x1 - sage: f.degree() + sage: f.degree() # optional - sage.rings.finite_rings 3 We show that the default method does not sample uniformly at random from the ideal:: - sage: P. = GF(127)[] - sage: G = Sequence([x+7, y-2, z+110]) - sage: I = Ideal([sum(P.random_element() * g for g in G) for _ in range(4)]) - sage: all(I.random_element(degree=1) == 0 for _ in range(100)) + sage: P. = GF(127)[] # optional - sage.rings.finite_rings + sage: G = Sequence([x + 7, y - 2, z + 110]) # optional - sage.rings.finite_rings + sage: I = Ideal([sum(P.random_element() * g for g in G) # optional - sage.rings.finite_rings + ....: for _ in range(4)]) + sage: all(I.random_element(degree=1) == 0 for _ in range(100)) # optional - sage.rings.finite_rings True - If degree equals the degree of the generators a random linear + If ``degree`` equals the degree of the generators, a random linear combination of the generators is returned:: sage: P. = QQ[] @@ -5258,118 +5346,130 @@ def weil_restriction(self): If the input and the output ideals are radical, this is equivalent to the statement about algebraic varieties above. - OUTPUT: MPolynomial Ideal + OUTPUT: :class:`MPolynomialIdeal` EXAMPLES:: - sage: k. = GF(2^2) - sage: P. = PolynomialRing(k,2) - sage: I = Ideal([x*y + 1, a*x + 1]) - sage: I.variety() + sage: k. = GF(2^2) # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(k, 2) # optional - sage.rings.finite_rings + sage: I = Ideal([x*y + 1, a*x + 1]) # optional - sage.rings.finite_rings + sage: I.variety() # optional - sage.rings.finite_rings [{y: a, x: a + 1}] - sage: J = I.weil_restriction() - sage: J + sage: J = I.weil_restriction() # optional - sage.rings.finite_rings + sage: J # optional - sage.rings.finite_rings Ideal (x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1) of - Multivariate Polynomial Ring in x0, x1, y0, y1 over Finite Field of size - 2 - sage: J += sage.rings.ideal.FieldIdeal(J.ring()) # ensure radical ideal - sage: J.variety() + Multivariate Polynomial Ring in x0, x1, y0, y1 over Finite Field of size 2 + sage: J += sage.rings.ideal.FieldIdeal(J.ring()) # ensure radical ideal # optional - sage.rings.finite_rings + sage: J.variety() # optional - sage.rings.finite_rings [{y1: 1, y0: 0, x1: 1, x0: 1}] - sage: J.weil_restriction() # returns J - Ideal (x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1, x0^2 + - x0, x1^2 + x1, y0^2 + y0, y1^2 + y1) of Multivariate Polynomial Ring in - x0, x1, y0, y1 over Finite Field of size 2 + sage: J.weil_restriction() # returns J # optional - sage.rings.finite_rings + Ideal (x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1, + x0^2 + x0, x1^2 + x1, y0^2 + y0, y1^2 + y1) of Multivariate + Polynomial Ring in x0, x1, y0, y1 over Finite Field of size 2 - sage: k. = GF(3^5) - sage: P. = PolynomialRing(k) - sage: I = sage.rings.ideal.Katsura(P) - sage: I.dimension() + sage: k. = GF(3^5) # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(k) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings + sage: I.dimension() # optional - sage.rings.finite_rings 0 - sage: I.variety() + sage: I.variety() # optional - sage.rings.finite_rings [{z: 0, y: 0, x: 1}] - sage: J = I.weil_restriction(); J - Ideal (x0 - y0 - z0 - 1, x1 - y1 - z1, x2 - y2 - z2, x3 - y3 - z3, x4 - - y4 - z4, x0^2 + x2*x3 + x1*x4 - y0^2 - y2*y3 - y1*y4 - z0^2 - z2*z3 - - z1*z4 - x0, -x0*x1 - x2*x3 - x3^2 - x1*x4 + x2*x4 + y0*y1 + y2*y3 + y3^2 - + y1*y4 - y2*y4 + z0*z1 + z2*z3 + z3^2 + z1*z4 - z2*z4 - x1, x1^2 - - x0*x2 + x3^2 - x2*x4 + x3*x4 - y1^2 + y0*y2 - y3^2 + y2*y4 - y3*y4 - - z1^2 + z0*z2 - z3^2 + z2*z4 - z3*z4 - x2, -x1*x2 - x0*x3 - x3*x4 - x4^2 - + y1*y2 + y0*y3 + y3*y4 + y4^2 + z1*z2 + z0*z3 + z3*z4 + z4^2 - x3, x2^2 - - x1*x3 - x0*x4 + x4^2 - y2^2 + y1*y3 + y0*y4 - y4^2 - z2^2 + z1*z3 + - z0*z4 - z4^2 - x4, -x0*y0 + x4*y1 + x3*y2 + x2*y3 + x1*y4 - y0*z0 + - y4*z1 + y3*z2 + y2*z3 + y1*z4 - y0, -x1*y0 - x0*y1 - x4*y1 - x3*y2 + - x4*y2 - x2*y3 + x3*y3 - x1*y4 + x2*y4 - y1*z0 - y0*z1 - y4*z1 - y3*z2 + - y4*z2 - y2*z3 + y3*z3 - y1*z4 + y2*z4 - y1, -x2*y0 - x1*y1 - x0*y2 - - x4*y2 - x3*y3 + x4*y3 - x2*y4 + x3*y4 - y2*z0 - y1*z1 - y0*z2 - y4*z2 - - y3*z3 + y4*z3 - y2*z4 + y3*z4 - y2, -x3*y0 - x2*y1 - x1*y2 - x0*y3 - - x4*y3 - x3*y4 + x4*y4 - y3*z0 - y2*z1 - y1*z2 - y0*z3 - y4*z3 - y3*z4 + - y4*z4 - y3, -x4*y0 - x3*y1 - x2*y2 - x1*y3 - x0*y4 - x4*y4 - y4*z0 - - y3*z1 - y2*z2 - y1*z3 - y0*z4 - y4*z4 - y4) of Multivariate Polynomial - Ring in x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, z0, z1, z2, z3, z4 over - Finite Field of size 3 - sage: J += sage.rings.ideal.FieldIdeal(J.ring()) # ensure radical ideal + sage: J = I.weil_restriction(); J # optional - sage.rings.finite_rings + Ideal (x0 - y0 - z0 - 1, + x1 - y1 - z1, x2 - y2 - z2, x3 - y3 - z3, x4 - y4 - z4, + x0^2 + x2*x3 + x1*x4 - y0^2 - y2*y3 - y1*y4 - z0^2 - z2*z3 - z1*z4 - x0, + -x0*x1 - x2*x3 - x3^2 - x1*x4 + x2*x4 + y0*y1 + y2*y3 + + y3^2 + y1*y4 - y2*y4 + z0*z1 + z2*z3 + z3^2 + z1*z4 - z2*z4 - x1, + x1^2 - x0*x2 + x3^2 - x2*x4 + x3*x4 - y1^2 + y0*y2 + - y3^2 + y2*y4 - y3*y4 - z1^2 + z0*z2 - z3^2 + z2*z4 - z3*z4 - x2, + -x1*x2 - x0*x3 - x3*x4 - x4^2 + + y1*y2 + y0*y3 + y3*y4 + y4^2 + z1*z2 + z0*z3 + z3*z4 + z4^2 - x3, + x2^2 - x1*x3 - x0*x4 + x4^2 - y2^2 + + y1*y3 + y0*y4 - y4^2 - z2^2 + z1*z3 + z0*z4 - z4^2 - x4, + -x0*y0 + x4*y1 + x3*y2 + x2*y3 + + x1*y4 - y0*z0 + y4*z1 + y3*z2 + y2*z3 + y1*z4 - y0, + -x1*y0 - x0*y1 - x4*y1 - x3*y2 + x4*y2 - x2*y3 + x3*y3 + - x1*y4 + x2*y4 - y1*z0 - y0*z1 - y4*z1 - y3*z2 + + y4*z2 - y2*z3 + y3*z3 - y1*z4 + y2*z4 - y1, + -x2*y0 - x1*y1 - x0*y2 - x4*y2 - x3*y3 + x4*y3 - x2*y4 + x3*y4 + - y2*z0 - y1*z1 - y0*z2 - y4*z2 - y3*z3 + y4*z3 - y2*z4 + y3*z4 - y2, + -x3*y0 - x2*y1 - x1*y2 - x0*y3 - x4*y3 - x3*y4 + x4*y4 + - y3*z0 - y2*z1 - y1*z2 - y0*z3 - y4*z3 - y3*z4 + y4*z4 - y3, + -x4*y0 - x3*y1 - x2*y2 - x1*y3 - x0*y4 - x4*y4 + - y4*z0 - y3*z1 - y2*z2 - y1*z3 - y0*z4 - y4*z4 - y4) + of Multivariate Polynomial Ring in x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, + z0, z1, z2, z3, z4 over Finite Field of size 3 + sage: J += sage.rings.ideal.FieldIdeal(J.ring()) # ensure radical ideal # optional - sage.rings.finite_rings sage: from sage.doctest.fixtures import reproducible_repr - sage: print(reproducible_repr(J.variety())) - [{x0: 1, x1: 0, x2: 0, x3: 0, x4: 0, y0: 0, y1: 0, y2: 0, y3: 0, y4: 0, z0: 0, z1: 0, z2: 0, z3: 0, z4: 0}] + sage: print(reproducible_repr(J.variety())) # optional - sage.rings.finite_rings + [{x0: 1, x1: 0, x2: 0, x3: 0, x4: 0, + y0: 0, y1: 0, y2: 0, y3: 0, y4: 0, + z0: 0, z1: 0, z2: 0, z3: 0, z4: 0}] Weil restrictions are often used to study elliptic curves over extension fields so we give a simple example involving those:: - sage: K. = QuadraticField(1/3) - sage: E = EllipticCurve(K,[1,2,3,4,5]) + sage: K. = QuadraticField(1/3) # optional - sage.rings.number_field + sage: E = EllipticCurve(K, [1,2,3,4,5]) # optional - sage.rings.number_field We pick a point on ``E``:: - sage: p = E.lift_x(1); p + sage: p = E.lift_x(1); p # optional - sage.rings.number_field (1 : 2 : 1) - sage: I = E.defining_ideal(); I - Ideal (-x^3 - 2*x^2*z + x*y*z + y^2*z - 4*x*z^2 + 3*y*z^2 - 5*z^3) of Multivariate Polynomial Ring in x, y, z over Number Field in a with defining polynomial x^2 - 1/3 with a = 0.5773502691896258? + sage: I = E.defining_ideal(); I # optional - sage.rings.number_field + Ideal (-x^3 - 2*x^2*z + x*y*z + y^2*z - 4*x*z^2 + 3*y*z^2 - 5*z^3) + of Multivariate Polynomial Ring in x, y, z + over Number Field in a with defining polynomial x^2 - 1/3 + with a = 0.5773502691896258? Of course, the point ``p`` is a root of all generators of ``I``:: - sage: I.subs(x=1,y=2,z=1) - Ideal (0) of Multivariate Polynomial Ring in x, y, z over Number Field in a with defining polynomial x^2 - 1/3 with a = 0.5773502691896258? + sage: I.subs(x=1, y=2, z=1) # optional - sage.rings.number_field + Ideal (0) of Multivariate Polynomial Ring in x, y, z + over Number Field in a with defining polynomial x^2 - 1/3 + with a = 0.5773502691896258? ``I`` is also radical:: - sage: I.radical() == I + sage: I.radical() == I # optional - sage.rings.number_field True So we compute its Weil restriction:: - sage: J = I.weil_restriction() - sage: J - Ideal (-x0^3 - x0*x1^2 - 2*x0^2*z0 - 2/3*x1^2*z0 + x0*y0*z0 + y0^2*z0 + - 1/3*x1*y1*z0 + 1/3*y1^2*z0 - 4*x0*z0^2 + 3*y0*z0^2 - 5*z0^3 - - 4/3*x0*x1*z1 + 1/3*x1*y0*z1 + 1/3*x0*y1*z1 + 2/3*y0*y1*z1 - 8/3*x1*z0*z1 - + 2*y1*z0*z1 - 4/3*x0*z1^2 + y0*z1^2 - 5*z0*z1^2, -3*x0^2*x1 - 1/3*x1^3 - - 4*x0*x1*z0 + x1*y0*z0 + x0*y1*z0 + 2*y0*y1*z0 - 4*x1*z0^2 + 3*y1*z0^2 - - 2*x0^2*z1 - 2/3*x1^2*z1 + x0*y0*z1 + y0^2*z1 + 1/3*x1*y1*z1 + - 1/3*y1^2*z1 - 8*x0*z0*z1 + 6*y0*z0*z1 - 15*z0^2*z1 - 4/3*x1*z1^2 + - y1*z1^2 - 5/3*z1^3) of Multivariate Polynomial Ring in x0, x1, y0, y1, - z0, z1 over Rational Field + sage: J = I.weil_restriction() # optional - sage.rings.number_field + sage: J # optional - sage.rings.number_field + Ideal (-x0^3 - x0*x1^2 - 2*x0^2*z0 - 2/3*x1^2*z0 + x0*y0*z0 + y0^2*z0 + + 1/3*x1*y1*z0 + 1/3*y1^2*z0 - 4*x0*z0^2 + 3*y0*z0^2 - 5*z0^3 + - 4/3*x0*x1*z1 + 1/3*x1*y0*z1 + 1/3*x0*y1*z1 + 2/3*y0*y1*z1 + - 8/3*x1*z0*z1 + 2*y1*z0*z1 - 4/3*x0*z1^2 + y0*z1^2 - 5*z0*z1^2, + -3*x0^2*x1 - 1/3*x1^3 - 4*x0*x1*z0 + x1*y0*z0 + x0*y1*z0 + + 2*y0*y1*z0 - 4*x1*z0^2 + 3*y1*z0^2 - 2*x0^2*z1 - 2/3*x1^2*z1 + + x0*y0*z1 + y0^2*z1 + 1/3*x1*y1*z1 + 1/3*y1^2*z1 - 8*x0*z0*z1 + + 6*y0*z0*z1 - 15*z0^2*z1 - 4/3*x1*z1^2 + y1*z1^2 - 5/3*z1^3) + of Multivariate Polynomial Ring in x0, x1, y0, y1, z0, z1 over Rational Field We can check that the point ``p`` is still a root of all generators of ``J``:: - sage: J.subs(x0=1,y0=2,z0=1,x1=0,y1=0,z1=0) - Ideal (0, 0) of Multivariate Polynomial Ring in x0, x1, y0, y1, z0, z1 over Rational Field + sage: J.subs(x0=1, y0=2, z0=1, x1=0, y1=0, z1=0) # optional - sage.rings.number_field + Ideal (0, 0) of Multivariate Polynomial Ring in x0, x1, y0, y1, z0, z1 + over Rational Field Example for relative number fields:: sage: R. = QQ[] - sage: K. = NumberField(x^5-2) - sage: R. = K[] - sage: L. = K.extension(x^2+1) - sage: S. = L[] - sage: I = S.ideal([y^2-x^3-1]) - sage: I.weil_restriction() - Ideal (-x0^3 + 3*x0*x1^2 + y0^2 - y1^2 - 1, -3*x0^2*x1 + x1^3 + 2*y0*y1) - of Multivariate Polynomial Ring in x0, x1, y0, y1 over Number Field in w - with defining polynomial x^5 - 2 + sage: K. = NumberField(x^5 - 2) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: L. = K.extension(x^2 + 1) # optional - sage.rings.number_field + sage: S. = L[] # optional - sage.rings.number_field + sage: I = S.ideal([y^2 - x^3 - 1]) # optional - sage.rings.number_field + sage: I.weil_restriction() # optional - sage.rings.number_field + Ideal (-x0^3 + 3*x0*x1^2 + y0^2 - y1^2 - 1, -3*x0^2*x1 + x1^3 + 2*y0*y1) of + Multivariate Polynomial Ring in x0, x1, y0, y1 + over Number Field in w with defining polynomial x^5 - 2 .. NOTE:: @@ -5442,8 +5542,9 @@ class MPolynomialIdeal_quotient(MPolynomialIdeal): sage: Q. = QQ['x,y,z,w'].quotient(['x*y-z^2', 'y^2-w^2']) sage: I = ideal(x + y^2 + z - 1) sage: I - Ideal (w^2 + x + z - 1) of Quotient of Multivariate Polynomial Ring - in x, y, z, w over Rational Field by the ideal (x*y - z^2, y^2 - w^2) + Ideal (w^2 + x + z - 1) of Quotient + of Multivariate Polynomial Ring in x, y, z, w over Rational Field + by the ideal (x*y - z^2, y^2 - w^2) """ def reduce(self, f): r""" @@ -5454,9 +5555,9 @@ def reduce(self, f): EXAMPLES:: sage: R. = PolynomialRing(QQ, order='lex') - sage: I = R.ideal([T^2+U^2-1, V^2+W^2-1, X^2+Y^2+Z^2-1]) + sage: I = R.ideal([T^2 + U^2 - 1, V^2 + W^2 - 1, X^2 + Y^2 + Z^2 - 1]) sage: Q. = R.quotient(I) - sage: J = Q.ideal([u*v-x, u*w-y, t-z]) + sage: J = Q.ideal([u*v - x, u*w - y, t - z]) sage: J.reduce(t^2 - z^2) 0 sage: J.reduce(u^2) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 64f01724081..112ef8c10dd 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -370,7 +370,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): Traceback (most recent call last): ... NotImplementedError: polynomials over Ring of integers modulo 1 are not supported in Singular - sage: MPolynomialRing_libsingular(SR, 1, ["x"], "lex") + sage: MPolynomialRing_libsingular(SR, 1, ["x"], "lex") # optional - sage.symbolic Traceback (most recent call last): ... NotImplementedError: polynomials over Symbolic Ring are not supported in Singular @@ -468,7 +468,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): cpdef _coerce_map_from_(self, other): """ - Return True if and only if there exists a coercion map from + Return ``True`` if and only if there exists a coercion map from ``other`` to ``self``. TESTS:: @@ -1373,8 +1373,6 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): // block 2 : ordering C """ - from sage.functions.other import ceil - if singular is None: from sage.interfaces.singular import singular diff --git a/src/sage/rings/polynomial/multi_polynomial_ring.py b/src/sage/rings/polynomial/multi_polynomial_ring.py index 239737eb500..acf72a9e175 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring.py +++ b/src/sage/rings/polynomial/multi_polynomial_ring.py @@ -27,13 +27,13 @@ We construct the Frobenius morphism on `\GF{5}[x,y,z]` over `\GF{5}`:: - sage: R. = GF(5)[] - sage: frob = R.hom([x^5, y^5, z^5]) - sage: frob(x^2 + 2*y - z^4) + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: frob = R.hom([x^5, y^5, z^5]) # optional - sage.rings.finite_rings + sage: frob(x^2 + 2*y - z^4) # optional - sage.rings.finite_rings -z^20 + x^10 + 2*y^5 - sage: frob((x + 2*y)^3) + sage: frob((x + 2*y)^3) # optional - sage.rings.finite_rings x^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15 - sage: (x^5 + 2*y^5)^3 + sage: (x^5 + 2*y^5)^3 # optional - sage.rings.finite_rings x^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15 We make a polynomial ring in one variable over a polynomial ring in @@ -46,7 +46,7 @@ TESTS:: - sage: PolynomialRing(GF(5), 3, 'xyz').objgens() + sage: PolynomialRing(GF(5), 3, 'xyz').objgens() # optional - sage.rings.finite_rings (Multivariate Polynomial Ring in x, y, z over Finite Field of size 5, (x, y, z)) """ @@ -203,7 +203,7 @@ def __call__(self, x=0, check=True): sage: R. = QQ[] sage: S. = ZZ[] - sage: T. = GF(7)[] + sage: T. = GF(7)[] # optional - sage.rings.finite_rings We convert from integer polynomials to rational polynomials, and back:: @@ -219,9 +219,9 @@ def __call__(self, x=0, check=True): :: - sage: f = R(T.0^2 - 4*T.1^3); f + sage: f = R(T.0^2 - 4*T.1^3); f # optional - sage.rings.finite_rings 3*y^3 + x^2 - sage: parent(f) + sage: parent(f) # optional - sage.rings.finite_rings Multivariate Polynomial Ring in x, y over Rational Field We dump and load the polynomial ring S:: @@ -241,24 +241,24 @@ def __call__(self, x=0, check=True): variable names:: sage: R. = PolynomialRing(QQ,2) - sage: S. = PolynomialRing(GF(7),2) + sage: S. = PolynomialRing(GF(7),2) # optional - sage.rings.finite_rings sage: f = x^2 + 2/3*y^3 - sage: S(f) + sage: S(f) # optional - sage.rings.finite_rings 3*b^3 + a^2 Conversion from symbolic variables:: - sage: x,y,z = var('x,y,z') - sage: R = QQ['x,y,z'] - sage: type(x) + sage: x,y,z = var('x,y,z') # optional - sage.symbolic + sage: R = QQ['x,y,z'] # optional - sage.symbolic + sage: type(x) # optional - sage.symbolic - sage: type(R(x)) + sage: type(R(x)) # optional - sage.symbolic - sage: f = R(x^3 + y^3 - z^3); f + sage: f = R(x^3 + y^3 - z^3); f # optional - sage.symbolic x^3 + y^3 - z^3 - sage: type(f) + sage: type(f) # optional - sage.symbolic - sage: parent(f) + sage: parent(f) # optional - sage.symbolic Multivariate Polynomial Ring in x, y, z over Rational Field A more complicated symbolic and computational mix. Behind the @@ -267,11 +267,11 @@ def __call__(self, x=0, check=True): :: sage: R = QQ['x,y,z'] - sage: f = (x^3 + y^3 - z^3)^10; f + sage: f = (x^3 + y^3 - z^3)^10; f # optional - sage.symbolic (x^3 + y^3 - z^3)^10 - sage: g = R(f); parent(g) + sage: g = R(f); parent(g) # optional - sage.symbolic Multivariate Polynomial Ring in x, y, z over Rational Field - sage: (f - g).expand() + sage: (f - g).expand() # optional - sage.symbolic 0 It intelligently handles conversions from polynomial rings in a subset @@ -279,12 +279,12 @@ def __call__(self, x=0, check=True): :: - sage: R = GF(5)['x,y,z'] + sage: R = GF(5)['x,y,z'] # optional - sage.rings.finite_rings sage: S = ZZ['y'] - sage: R(7*S.0) + sage: R(7*S.0) # optional - sage.rings.finite_rings 2*y sage: T = ZZ['x,z'] - sage: R(2*T.0 + 6*T.1 + T.0*T.1^2) + sage: R(2*T.0 + 6*T.1 + T.0*T.1^2) # optional - sage.rings.finite_rings x*z^2 + 2*x + z :: @@ -793,7 +793,7 @@ def monomial_divides(self, a, b): def monomial_pairwise_prime(self, h, g): r""" - Return True if ``h`` and ``g`` are pairwise prime. + Return ``True`` if ``h`` and ``g`` are pairwise prime. Both are treated as monomials. @@ -895,7 +895,7 @@ def sum(self, terms): r""" Return a sum of elements of this multipolynomial ring. - This is method is much faster than the Python builtin sum. + This is method is much faster than the Python builtin :func:`sum`. EXAMPLES:: @@ -906,7 +906,7 @@ def sum(self, terms): sage: S.sum([x*y, 2*x^2*z - 2*x*y, 1 + y + z]) (-x + 1)*y + (2*x^2 + 1)*z + 1 - Comparison with builtin sum:: + Comparison with builtin :func:`sum`:: sage: sum([x*y, 2*x^2*z - 2*x*y, 1 + y + z]) (-x + 1)*y + (2*x^2 + 1)*z + 1 diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 70e1e7c861b..ce12783d73b 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -74,10 +74,10 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): Check that :trac:`26958` is fixed:: - sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular - sage: class Foo(MPolynomialRing_libsingular): + sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular # optional - sage.libs.singular + sage: class Foo(MPolynomialRing_libsingular): # optional - sage.libs.singular ....: pass - sage: Foo(QQ, 2, ['x','y'], 'degrevlex') + sage: Foo(QQ, 2, ['x','y'], 'degrevlex') # optional - sage.libs.singular Multivariate Polynomial Ring in x, y over Rational Field """ if base_ring not in _CommutativeRings: @@ -133,14 +133,13 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: QQ['a','b']['x','y'].flattening_morphism() Flattening morphism: - From: Multivariate Polynomial Ring in x, y over Multivariate - Polynomial Ring in a, b over Rational Field - To: Multivariate Polynomial Ring in a, b, x, y over Rational - Field + From: Multivariate Polynomial Ring in x, y + over Multivariate Polynomial Ring in a, b over Rational Field + To: Multivariate Polynomial Ring in a, b, x, y over Rational Field sage: QQ['x,y'].flattening_morphism() - Identity endomorphism of Multivariate Polynomial Ring in x, y - over Rational Field + Identity endomorphism of + Multivariate Polynomial Ring in x, y over Rational Field """ base = self.base_ring() if is_MPolynomialRing(base) or polynomial_ring.is_PolynomialRing(base): @@ -151,7 +150,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): def construction(self): """ - Returns a functor F and base ring R such that F(R) == self. + Returns a functor ``F`` and base ring ``R`` such that ``F(R) == self``. EXAMPLES:: @@ -238,7 +237,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: P. = PolynomialRing(ZZ) sage: P.completion([]) is P True - sage: P.completion(SR.var('x')) + sage: P.completion(SR.var('x')) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: x is not an element of Multivariate Polynomial Ring @@ -284,7 +283,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): def remove_var(self, *var, order=None): """ - Remove a variable or sequence of variables from self. + Remove a variable or sequence of variables from ``self``. If ``order`` is not specified, then the subring inherits the term order of the original ring, if possible. @@ -294,14 +293,14 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: P. = PolynomialRing(ZZ) sage: P.remove_var(z) Multivariate Polynomial Ring in x, y, w over Integer Ring - sage: P.remove_var(z,x) + sage: P.remove_var(z, x) Multivariate Polynomial Ring in y, w over Integer Ring - sage: P.remove_var(y,z,x) + sage: P.remove_var(y, z, x) Univariate Polynomial Ring in w over Integer Ring Removing all variables results in the base ring:: - sage: P.remove_var(y,z,x,w) + sage: P.remove_var(y, z, x, w) Integer Ring If possible, the term order is kept:: @@ -317,7 +316,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): Be careful with block orders when removing variables:: sage: R. = PolynomialRing(ZZ, order='deglex(2),lex(3)') - sage: R.remove_var(x,y,z) + sage: R.remove_var(x, y, z) Traceback (most recent call last): ... ValueError: impossible to use the original term order (most @@ -345,18 +344,18 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): def univariate_ring(self, x): """ Return a univariate polynomial ring whose base ring comprises all - but one variables of self. + but one variables of ``self``. INPUT: - - ``x`` -- a variable of self. + - ``x`` -- a variable of ``self``. EXAMPLES:: sage: P. = QQ[] sage: P.univariate_ring(y) - Univariate Polynomial Ring in y over Multivariate Polynomial - Ring in x, z over Rational Field + Univariate Polynomial Ring in y + over Multivariate Polynomial Ring in x, z over Rational Field """ return self.remove_var(x)[str(x)] @@ -368,9 +367,9 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): This function can be called in two ways: - 1. interpolation(bound, points, values) + 1. ``interpolation(bound, points, values)`` - 2. interpolation(bound, function) + 2. ``interpolation(bound, function)`` INPUT: @@ -399,18 +398,16 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): ....: return a^3*b + b + c^2 + 25 ....: sage: R. = PolynomialRing(QQ) - sage: R.interpolation(4, F) + sage: R.interpolation(4, F) # optional - sage.modules x^3*y + z^2 + y + 25 - sage: def F(a,b,c): ....: return a^3*b + b + c^2 + 25 ....: sage: R. = PolynomialRing(QQ) - sage: R.interpolation([3,1,2], F) + sage: R.interpolation([3,1,2], F) # optional - sage.modules x^3*y + z^2 + y + 25 - sage: def F(a,b,c): ....: return a^3*b + b + c^2 + 25 ....: @@ -419,7 +416,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): ....: (2,7,0),(1,10,13),(0,0,1),(-1,1,0),(2,5,3),(1,1,1),(7,4,11), ....: (12,1,9),(1,1,3),(4,-1,2),(0,1,5),(5,1,3),(3,1,-2),(2,11,3), ....: (4,12,19),(3,1,1),(5,2,-3),(12,1,1),(2,3,4)] - sage: R.interpolation([3,1,2], points, [F(*x) for x in points]) + sage: R.interpolation([3,1,2], points, [F(*x) for x in points]) # optional - sage.modules x^3*y + z^2 + y + 25 ALGORITHM: @@ -438,7 +435,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): without any notice that there are more. Lastly, the interpolation function for univariate polynomial rings - is called ``lagrange_polynomial()``. + is called :meth:`lagrange_polynomial`. .. WARNING:: @@ -447,14 +444,14 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): the given bounds. In particular it will *not* notice or check whether the result yields the correct evaluation for other points as well. So if you give wrong bounds, you will get a wrong answer - without any warning. + without any warning. :: - sage: def F(a,b,c): - ....: return a^3*b + b + c^2 + 25 - ....: - sage: R. = PolynomialRing(QQ) - sage: R.interpolation(3,F) - 1/2*x^3 + x*y + z^2 - 1/2*x + y + 25 + sage: def F(a,b,c): + ....: return a^3*b + b + c^2 + 25 + ....: + sage: R. = PolynomialRing(QQ) + sage: R.interpolation(3, F) # optional - sage.modules + 1/2*x^3 + x*y + z^2 - 1/2*x + y + 25 .. SEEALSO:: @@ -583,13 +580,13 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): implicitly calling ``_coerce_c_impl``:: sage: z = polygen(QQ, 'z') - sage: W.=NumberField(z^2+1) - sage: Q. = W[] - sage: W1 = FractionField (Q) - sage: S. = W1[] - sage: u + x + sage: W. = NumberField(z^2 + 1) # optional - sage.rings.number_field + sage: Q. = W[] # optional - sage.rings.number_field + sage: W1 = FractionField(Q) # optional - sage.rings.number_field + sage: S. = W1[] # optional - sage.rings.number_field + sage: u + x # optional - sage.rings.number_field x + u - sage: x + 1/u + sage: x + 1/u # optional - sage.rings.number_field x + 1/u """ try: @@ -679,7 +676,8 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): EXAMPLES:: - sage: P. = PolynomialRing(QQ,order=TermOrder('degrevlex',1)+TermOrder('lex',2)) + sage: P. = PolynomialRing(QQ, order=TermOrder('degrevlex',1) + ....: + TermOrder('lex',2)) sage: print(P.repr_long()) Polynomial Ring Base Ring : Rational Field @@ -718,12 +716,12 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): EXAMPLES:: sage: T. = ZZ[] - sage: K. = NumberField(t^2 + 1) - sage: R. = K[] - sage: Q5 = Qp(5); i5 = Q5(-1).sqrt() - sage: R._is_valid_homomorphism_(Q5, [Q5.teichmuller(2), Q5(6).log()]) # no coercion + sage: K. = NumberField(t^2 + 1) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: Q5 = Qp(5); i5 = Q5(-1).sqrt() # optional - sage.rings.number_field + sage: R._is_valid_homomorphism_(Q5, [Q5.teichmuller(2), Q5(6).log()]) # no coercion # optional - sage.rings.number_field False - sage: R._is_valid_homomorphism_(Q5, [Q5.teichmuller(2), Q5(6).log()], base_map=K.hom([i5])) + sage: R._is_valid_homomorphism_(Q5, [Q5.teichmuller(2), Q5(6).log()], base_map=K.hom([i5])) # optional - sage.rings.number_field True """ if base_map is None: @@ -740,33 +738,33 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): EXAMPLES:: - sage: R. = PolynomialRing(GF(127),10) - sage: R._magma_init_(magma) # optional - magma + sage: R. = PolynomialRing(GF(127),10) # optional - sage.rings.finite_rings + sage: R._magma_init_(magma) # optional - magma # optional - sage.rings.finite_rings 'SageCreateWithNames(PolynomialRing(_sage_ref...,10,"grevlex"),["a","b","c","d","e","f","g","h","i","j"])' - sage: R. = PolynomialRing(QQ,3) - sage: magma(R) # optional - magma + sage: R. = PolynomialRing(QQ, 3) # optional - sage.rings.finite_rings + sage: magma(R) # optional - magma # optional - sage.rings.finite_rings Polynomial ring of rank 3 over Rational Field Order: Graded Reverse Lexicographical Variables: y, z, w A complicated nested example:: - sage: R. = PolynomialRing(GF(9,'a')); S. = R[]; S + sage: R. = PolynomialRing(GF(9,'a')); S. = R[]; S # optional - sage.rings.finite_rings Multivariate Polynomial Ring in T, W over Multivariate Polynomial Ring in a, b, c over Finite Field in a of size 3^2 - sage: magma(S) # optional - magma + sage: magma(S) # optional - magma # optional - sage.rings.finite_rings Polynomial ring of rank 2 over Polynomial ring of rank 3 over GF(3^2) Order: Graded Reverse Lexicographical Variables: T, W - sage: magma(PolynomialRing(GF(7),4, 'x')) # optional - magma + sage: magma(PolynomialRing(GF(7),4, 'x')) # optional - magma # optional - sage.rings.finite_rings Polynomial ring of rank 4 over GF(7) Order: Graded Reverse Lexicographical Variables: x0, x1, x2, x3 - sage: magma(PolynomialRing(GF(49,'a'),10, 'x')) # optional - magma + sage: magma(PolynomialRing(GF(49,'a'),10, 'x')) # optional - magma # optional - sage.rings.finite_rings Polynomial ring of rank 10 over GF(7^2) Order: Graded Reverse Lexicographical Variables: x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 @@ -800,11 +798,11 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): EXAMPLES:: - sage: F = CyclotomicField(8) - sage: P. = F[] - sage: gap(P) # indirect doctest + sage: F = CyclotomicField(8) # optional - sage.rings.number_field + sage: P. = F[] # optional - sage.rings.number_field + sage: gap(P) # indirect doctest # optional - sage.rings.number_field PolynomialRing( CF(8), ["x", "y"] ) - sage: libgap(P) + sage: libgap(P) # optional - sage.rings.number_field [x,y] """ L = ['"%s"' % t for t in self.variable_names()] @@ -862,8 +860,8 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: R = PolynomialRing(QQ, 'x', 3) sage: R.characteristic() 0 - sage: R = PolynomialRing(GF(7),'x', 20) - sage: R.characteristic() + sage: R = PolynomialRing(GF(7), 'x', 20) # optional - sage.rings.finite_rings + sage: R.characteristic() # optional - sage.rings.finite_rings 7 """ return self.base_ring().characteristic() @@ -1335,9 +1333,9 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): def change_ring(self, base_ring=None, names=None, order=None): """ - Return a new multivariate polynomial ring which isomorphic to - self, but has a different ordering given by the parameter - 'order' or names given by the parameter 'names'. + Return a new multivariate polynomial ring which is isomorphic to + ``self``, but has a different ordering given by the parameter + ``order`` or names given by the parameter ``names``. INPUT: @@ -1347,11 +1345,11 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): EXAMPLES:: - sage: P. = PolynomialRing(GF(127),3,order='lex') - sage: x > y^2 + sage: P. = PolynomialRing(GF(127), 3, order='lex') # optional - sage.rings.finite_rings + sage: x > y^2 # optional - sage.rings.finite_rings True - sage: Q. = P.change_ring(order='degrevlex') - sage: x > y^2 + sage: Q. = P.change_ring(order='degrevlex') # optional - sage.rings.finite_rings + sage: x > y^2 # optional - sage.rings.finite_rings False """ if base_ring is None: @@ -1406,7 +1404,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): The number of such monomials equals `\binom{n+k-1}{k}` where `n` is the number of variables and `k` the degree:: - sage: len(mons) == binomial(3+2-1,2) + sage: len(mons) == binomial(3 + 2 - 1, 2) True """ deg_of_gens = [x.degree() for x in self.gens()] @@ -1527,7 +1525,7 @@ 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 + 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 @@ -1550,17 +1548,17 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): INPUT: - ``args`` -- a list of `n` homogeneous polynomials in `n` variables. - works when ``args[0]`` is the list of polynomials, - or ``args`` is itself the list of polynomials + works when ``args[0]`` is the list of polynomials, + or ``args`` is itself the list of polynomials kwds: - ``sparse`` -- boolean (optional - default: ``False``) - if ``True`` function creates sparse matrices. + if ``True``, the function creates sparse matrices. OUTPUT: - - the macaulay resultant, an element of the base ring of ``self`` + - the Macaulay resultant, an element of the base ring of ``self`` .. TODO:: Working with sparse matrices should usually give faster results, @@ -1571,27 +1569,25 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): The number of polynomials has to match the number of variables:: - sage: R. = PolynomialRing(QQ,3) - sage: R.macaulay_resultant([y,x+z]) + sage: R. = PolynomialRing(QQ, 3) + sage: R.macaulay_resultant([y, x + z]) # optional - sage.modules Traceback (most recent call last): ... - TypeError: number of polynomials(= 2) must equal number of - variables (= 3) + TypeError: number of polynomials(= 2) must equal number of variables (= 3) The polynomials need to be all homogeneous:: - sage: R. = PolynomialRing(QQ,3) - sage: R.macaulay_resultant([y, x+z, z+x^3]) + sage: R. = PolynomialRing(QQ, 3) + sage: R.macaulay_resultant([y, x + z, z + x^3]) # optional - sage.modules Traceback (most recent call last): ... - TypeError: resultant for non-homogeneous polynomials is - not supported + TypeError: resultant for non-homogeneous polynomials is not supported All polynomials must be in the same ring:: sage: S. = PolynomialRing(QQ, 2) sage: R. = PolynomialRing(QQ,3) - sage: S.macaulay_resultant([y, z+x]) + sage: S.macaulay_resultant([y, z+x]) # optional - sage.modules Traceback (most recent call last): ... TypeError: not all inputs are polynomials in the calling ring @@ -1599,8 +1595,8 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): The following example recreates Proposition 2.10 in Ch.3 in [CLO2005]:: sage: K. = PolynomialRing(ZZ, 2) - sage: flist,R = K._macaulay_resultant_universal_polynomials([1,1,2]) - sage: R.macaulay_resultant(flist) + sage: flist, R = K._macaulay_resultant_universal_polynomials([1,1,2]) + sage: R.macaulay_resultant(flist) # optional - sage.modules u2^2*u4^2*u6 - 2*u1*u2*u4*u5*u6 + u1^2*u5^2*u6 - u2^2*u3*u4*u7 + u1*u2*u3*u5*u7 + u0*u2*u4*u5*u7 - u0*u1*u5^2*u7 + u1*u2*u3*u4*u8 - u0*u2*u4^2*u8 - u1^2*u3*u5*u8 + u0*u1*u4*u5*u8 + u2^2*u3^2*u9 - @@ -1609,11 +1605,11 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): u1^2*u3^2*u11 - 2*u0*u1*u3*u4*u11 + u0^2*u4^2*u11 The following example degenerates into the determinant of - a `3*3` matrix:: + a `3\times 3` matrix:: sage: K. = PolynomialRing(ZZ, 2) sage: flist,R = K._macaulay_resultant_universal_polynomials([1,1,1]) - sage: R.macaulay_resultant(flist) + sage: R.macaulay_resultant(flist) # optional - sage.modules -u2*u4*u6 + u1*u5*u6 + u2*u3*u7 - u0*u5*u7 - u1*u3*u8 + u0*u4*u8 The following example is by Patrick Ingram (:arxiv:`1310.4114`):: @@ -1624,57 +1620,57 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: f1 = y1*x2^2 - x1^2 + 2*x0*x2 sage: f2 = x0*x1 - x2^2 sage: flist = [f0,f1,f2] - sage: R.macaulay_resultant([f0,f1,f2]) + sage: R.macaulay_resultant([f0,f1,f2]) # optional - sage.modules y0^2*y1^2 - 4*y0^3 - 4*y1^3 + 18*y0*y1 - 27 A simple example with constant rational coefficients:: - sage: R. = PolynomialRing(QQ,4) - sage: R.macaulay_resultant([w,z,y,x]) + sage: R. = PolynomialRing(QQ, 4) + sage: R.macaulay_resultant([w, z, y, x]) # optional - sage.modules 1 An example where the resultant vanishes:: - sage: R. = PolynomialRing(QQ,3) - sage: R.macaulay_resultant([x+y,y^2,x]) + sage: R. = PolynomialRing(QQ, 3) + sage: R.macaulay_resultant([x + y, y^2, x]) # optional - sage.modules 0 An example of bad reduction at a prime `p = 5`:: - sage: R. = PolynomialRing(QQ,3) - sage: R.macaulay_resultant([y,x^3+25*y^2*x,5*z]) + sage: R. = PolynomialRing(QQ, 3) + sage: R.macaulay_resultant([y, x^3 + 25*y^2*x, 5*z]) # optional - sage.modules 125 The input can given as an unpacked list of polynomials:: - sage: R. = PolynomialRing(QQ,3) - sage: R.macaulay_resultant(y,x^3+25*y^2*x,5*z) + sage: R. = PolynomialRing(QQ, 3) + sage: R.macaulay_resultant(y, x^3 + 25*y^2*x, 5*z) # optional - sage.modules 125 An example when the coefficients live in a finite field:: - sage: F = FiniteField(11) - sage: R. = PolynomialRing(F,4) - sage: R.macaulay_resultant([z,x^3,5*y,w]) + sage: F = FiniteField(11) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(F, 4) # optional - sage.rings.finite_rings + sage: R.macaulay_resultant([z, x^3, 5*y, w]) # optional - sage.modules sage.rings.finite_rings 4 Example when the denominator in the algorithm vanishes(in this case the resultant is the constant term of the quotient of char polynomials of numerator/denominator):: - sage: R. = PolynomialRing(QQ,3) - sage: R.macaulay_resultant([y, x+z, z^2]) + sage: R. = PolynomialRing(QQ, 3) + sage: R.macaulay_resultant([y, x + z, z^2]) # optional - sage.modules -1 - When there are only 2 polynomials, macaulay resultant degenerates + When there are only 2 polynomials, the Macaulay resultant degenerates to the traditional resultant:: - sage: R. = PolynomialRing(QQ,1) - sage: f = x^2+1; g = x^5+1 + sage: R. = PolynomialRing(QQ, 1) + sage: f = x^2 + 1; g = x^5 + 1 sage: fh = f.homogenize() sage: gh = g.homogenize() sage: RH = fh.parent() - sage: f.resultant(g) == RH.macaulay_resultant([fh,gh]) + sage: f.resultant(g) == RH.macaulay_resultant([fh, gh]) # optional - sage.modules True """ @@ -1754,9 +1750,9 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): EXAMPLES:: sage: R = QQ['x,y,z'] - sage: W = R.weyl_algebra(); W + sage: W = R.weyl_algebra(); W # optional - sage.combinat sage.modules Differential Weyl algebra of polynomials in x, y, z over Rational Field - sage: W.polynomial_ring() == R + sage: W.polynomial_ring() == R # optional - sage.combinat sage.modules True """ from sage.algebras.weyl_algebra import DifferentialWeylAlgebra @@ -1773,8 +1769,8 @@ cdef class BooleanPolynomialRing_base(MPolynomialRing_base): EXAMPLES:: sage: from sage.rings.polynomial.multi_polynomial_ring_base import BooleanPolynomialRing_base - sage: R. = BooleanPolynomialRing() - sage: isinstance(R, BooleanPolynomialRing_base) + sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: isinstance(R, BooleanPolynomialRing_base) # optional - sage.rings.polynomial.pbori True By design, there is only one direct implementation subclass:: diff --git a/src/sage/rings/polynomial/multi_polynomial_sequence.py b/src/sage/rings/polynomial/multi_polynomial_sequence.py index c4ad2530b58..8168439c2df 100644 --- a/src/sage/rings/polynomial/multi_polynomial_sequence.py +++ b/src/sage/rings/polynomial/multi_polynomial_sequence.py @@ -23,24 +23,24 @@ As an example consider a small scale variant of the AES:: - sage: sr = mq.SR(2,1,2,4,gf2=True,polybori=True) - sage: sr + sage: sr = mq.SR(2, 1, 2, 4, gf2=True, polybori=True) # optional - sage.rings.polynomial.pbori + sage: sr # optional - sage.rings.polynomial.pbori SR(2,1,2,4) We can construct a polynomial sequence for a random plaintext-ciphertext pair and study it:: - sage: set_random_seed(1) - sage: while True: # workaround (see :trac:`31891`) + sage: set_random_seed(1) # optional - sage.rings.polynomial.pbori + sage: while True: # workaround (see :trac:`31891`) # optional - sage.rings.polynomial.pbori ....: try: ....: F, s = sr.polynomial_system() ....: break ....: except ZeroDivisionError: ....: pass - sage: F + sage: F # optional - sage.rings.polynomial.pbori Polynomial Sequence with 112 Polynomials in 64 Variables - sage: r2 = F.part(2); r2 + sage: r2 = F.part(2); r2 # optional - sage.rings.polynomial.pbori (w200 + k100 + x100 + x102 + x103, w201 + k101 + x100 + x101 + x103 + 1, w202 + k102 + x100 + x101 + x102 + 1, @@ -76,7 +76,7 @@ We separate the system in independent subsystems:: - sage: C = Sequence(r2).connected_components(); C + sage: C = Sequence(r2).connected_components(); C # optional - sage.rings.polynomial.pbori [[w200 + k100 + x100 + x102 + x103, w201 + k101 + x100 + x101 + x103 + 1, w202 + k102 + x100 + x101 + x102 + 1, @@ -109,37 +109,37 @@ x110*w110 + x110*w111 + x110*w112 + x111*w112 + x112*w110 + x112*w111 + x112*w113 + x113*w111 + w112, x110*w111 + x111*w110 + x111*w112 + x112*w110 + x113*w111 + x113*w113 + w113, x110*w112 + x111*w111 + x112*w110 + x113*w113 + 1]] - sage: C[0].groebner_basis() + sage: C[0].groebner_basis() # optional - sage.rings.polynomial.pbori Polynomial Sequence with 30 Polynomials in 16 Variables and compute the coefficient matrix:: - sage: A,v = Sequence(r2).coefficient_matrix() - sage: A.rank() + sage: A,v = Sequence(r2).coefficient_matrix() # optional - sage.rings.polynomial.pbori + sage: A.rank() # optional - sage.rings.polynomial.pbori 32 Using these building blocks we can implement a simple XL algorithm easily:: - sage: sr = mq.SR(1,1,1,4, gf2=True, polybori=True, order='lex') - sage: while True: # workaround (see :trac:`31891`) + sage: sr = mq.SR(1,1,1,4, gf2=True, polybori=True, order='lex') # optional - sage.rings.polynomial.pbori + sage: while True: # workaround (see :trac:`31891`) # optional - sage.rings.polynomial.pbori ....: try: ....: F, s = sr.polynomial_system() ....: break ....: except ZeroDivisionError: ....: pass - sage: monomials = [a*b for a in F.variables() for b in F.variables() if a = PolynomialRing(GF(127),4) - sage: I = sage.rings.ideal.Katsura(P) + sage: P. = PolynomialRing(GF(127), 4) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings If a list of tuples is provided, those form the parts:: - sage: F = Sequence([I.gens(),I.gens()], I.ring()); F # indirect doctest + sage: F = Sequence([I.gens(),I.gens()], I.ring()); F # indirect doctest # optional - sage.rings.finite_rings [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, @@ -234,12 +234,12 @@ def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None): a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] - sage: F.nparts() + sage: F.nparts() # optional - sage.rings.finite_rings 2 If an ideal is provided, the generators are used:: - sage: Sequence(I) + sage: Sequence(I) # optional - sage.rings.finite_rings [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, @@ -247,22 +247,22 @@ def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None): If a list of polynomials is provided, the system has only one part:: - sage: F = Sequence(I.gens(), I.ring()); F + sage: F = Sequence(I.gens(), I.ring()); F # optional - sage.rings.finite_rings [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] - sage: F.nparts() + sage: F.nparts() # optional - sage.rings.finite_rings 1 We test that the ring is inferred correctly:: - sage: P. = GF(2)[] + sage: P. = GF(2)[] # optional - sage.rings.finite_rings sage: from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence - sage: PolynomialSequence([1,x,y]).ring() + sage: PolynomialSequence([1,x,y]).ring() # optional - sage.rings.finite_rings Multivariate Polynomial Ring in x, y, z over Finite Field of size 2 - sage: PolynomialSequence([[1,x,y], [0]]).ring() + sage: PolynomialSequence([[1,x,y], [0]]).ring() # optional - sage.rings.finite_rings Multivariate Polynomial Ring in x, y, z over Finite Field of size 2 TESTS: @@ -271,10 +271,10 @@ def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None): characteristic 2 (see :trac:`19452`):: sage: from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence - sage: F = GF(2) - sage: L. = PowerSeriesRing(F,'t') - sage: R. = PolynomialRing(L,'x,y') - sage: PolynomialSequence([0], R) + sage: F = GF(2) # optional - sage.rings.finite_rings + sage: L. = PowerSeriesRing(F,'t') # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(L,'x,y') # optional - sage.rings.finite_rings + sage: PolynomialSequence([0], R) # optional - sage.rings.finite_rings [0] A PolynomialSequence can be created from an iterator (see :trac:`25989`):: @@ -386,22 +386,25 @@ def __init__(self, parts, ring, immutable=False, cr=False, cr_str=None): EXAMPLES:: - sage: P. = PolynomialRing(GF(127),4) - sage: I = sage.rings.ideal.Katsura(P) + sage: P. = PolynomialRing(GF(127), 4) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings - sage: Sequence([I.gens()], I.ring()) # indirect doctest - [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] + sage: Sequence([I.gens()], I.ring()) # indirect doctest # optional - sage.rings.finite_rings + [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, + 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] If an ideal is provided, the generators are used.:: - sage: Sequence(I) - [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] + sage: Sequence(I) # optional - sage.rings.finite_rings + [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, + 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] If a list of polynomials is provided, the system has only one part.:: - sage: Sequence(I.gens(), I.ring()) - [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] + sage: Sequence(I.gens(), I.ring()) # optional - sage.rings.finite_rings + [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, + 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] """ Sequence_generic.__init__(self, sum(parts,tuple()), ring, check=False, immutable=immutable, @@ -415,11 +418,11 @@ def __copy__(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) - sage: F,s = sr.polynomial_system() - sage: copy(F) # indirect doctest + sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori + sage: F,s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori + sage: copy(F) # indirect doctest # optional - sage.rings.polynomial.pbori Polynomial Sequence with 40 Polynomials in 20 Variables - sage: type(F) == type(copy(F)) + sage: type(F) == type(copy(F)) # optional - sage.rings.polynomial.pbori True """ return self.__class__(self._parts, self._ring, immutable=self.is_immutable()) @@ -430,9 +433,9 @@ def ring(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True,gf2=True,order='block') - sage: F,s = sr.polynomial_system() - sage: print(F.ring().repr_long()) + sage: sr = mq.SR(allow_zero_inversions=True, gf2=True, order='block') # optional - sage.rings.polynomial.pbori + sage: F, s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori + sage: print(F.ring().repr_long()) # optional - sage.rings.polynomial.pbori Polynomial Ring Base Ring : Finite Field of size 2 Size : 20 Variables @@ -451,9 +454,9 @@ def nparts(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) - sage: F,s = sr.polynomial_system() - sage: F.nparts() + sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori + sage: F, s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori + sage: F.nparts() # optional - sage.rings.polynomial.pbori 4 """ return len(self._parts) @@ -464,10 +467,10 @@ def parts(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) - sage: F,s = sr.polynomial_system() - sage: l = F.parts() - sage: len(l) + sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori + sage: F, s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori + sage: l = F.parts() # optional - sage.rings.polynomial.pbori + sage: len(l) # optional - sage.rings.polynomial.pbori 4 """ return tuple(self._parts) @@ -478,10 +481,10 @@ def part(self, i): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) - sage: F,s = sr.polynomial_system() - sage: R0 = F.part(1) - sage: R0 + sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori + sage: F, s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori + sage: R0 = F.part(1) # optional - sage.rings.polynomial.pbori + sage: R0 # optional - sage.rings.polynomial.pbori (k000^2 + k001, k001^2 + k002, k002^2 + k003, k003^2 + k000) """ return self._parts[i] @@ -492,14 +495,14 @@ def ideal(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) - sage: F,s = sr.polynomial_system() - sage: P = F.ring() - sage: I = F.ideal() - sage: J = I.elimination_ideal(P.gens()[4:-4]) - sage: J <= I + sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori + sage: F, s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori + sage: P = F.ring() # optional - sage.rings.polynomial.pbori + sage: I = F.ideal() # optional - sage.rings.polynomial.pbori + sage: J = I.elimination_ideal(P.gens()[4:-4]) # optional - sage.rings.polynomial.pbori + sage: J <= I # optional - sage.rings.polynomial.pbori True - sage: set(J.gens().variables()).issubset(P.gens()[:4] + P.gens()[-4:]) + sage: set(J.gens().variables()).issubset(P.gens()[:4] + P.gens()[-4:]) # optional - sage.rings.polynomial.pbori True """ return self._ring.ideal(tuple(self)) @@ -519,10 +522,10 @@ def groebner_basis(self, *args, **kwargs): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) - sage: F,s = sr.polynomial_system() - sage: gb = F.groebner_basis() - sage: Ideal(gb).basis_is_groebner() + sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori + sage: F, s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori + sage: gb = F.groebner_basis() # optional - sage.rings.polynomial.pbori + sage: Ideal(gb).basis_is_groebner() # optional - sage.rings.polynomial.pbori True TESTS: @@ -530,12 +533,12 @@ def groebner_basis(self, *args, **kwargs): Check that this method also works for boolean polynomials (:trac:`10680`):: - sage: B. = BooleanPolynomialRing() - sage: F0 = Sequence(map(lambda f: f.lm(),[a,b,c,d])) - sage: F0.groebner_basis() + sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: F0 = Sequence(map(lambda f: f.lm(), [a,b,c,d])) # optional - sage.rings.polynomial.pbori + sage: F0.groebner_basis() # optional - sage.rings.polynomial.pbori [a, b, c, d] - sage: F1 = Sequence([a,b,c*d,d^2]) - sage: F1.groebner_basis() + sage: F1 = Sequence([a,b,c*d,d^2]) # optional - sage.rings.polynomial.pbori + sage: F1.groebner_basis() # optional - sage.rings.polynomial.pbori [a, b, d] """ return self.ideal().groebner_basis(*args, **kwargs) @@ -546,9 +549,9 @@ def monomials(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) - sage: F,s = sr.polynomial_system() - sage: len(F.monomials()) + sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori + sage: F,s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori + sage: len(F.monomials()) # optional - sage.rings.polynomial.pbori 49 """ M = set() @@ -563,9 +566,9 @@ def nmonomials(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) - sage: F,s = sr.polynomial_system() - sage: F.nmonomials() + sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori + sage: F,s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori + sage: F.nmonomials() # optional - sage.rings.polynomial.pbori 49 """ return len(self.monomials()) @@ -577,9 +580,9 @@ def variables(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) - sage: F,s = sr.polynomial_system() - sage: F.variables()[:10] + sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori + sage: F,s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori + sage: F.variables()[:10] # optional - sage.rings.polynomial.pbori (k003, k002, k001, k000, s003, s002, s001, s000, w103, w102) """ V = set() @@ -594,9 +597,9 @@ def nvariables(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) - sage: F,s = sr.polynomial_system() - sage: F.nvariables() + sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori + sage: F,s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori + sage: F.nvariables() # optional - sage.rings.polynomial.pbori 20 """ return len(self.variables()) @@ -637,11 +640,13 @@ def algebraic_dependence(self): :: - sage: R. = PolynomialRing(GF(7)) - sage: S = Sequence([x, (x^2 + y^2 - 1)^2, x*y - 2]) - sage: I = S.algebraic_dependence(); I - Ideal (2 - 3*T2 - T0^2 + 3*T2^2 - T0^2*T2 + T2^3 + 2*T0^4 - 2*T0^2*T2^2 + T2^4 - T0^4*T1 + T0^4*T2 - 2*T0^6 + 2*T0^4*T2^2 + T0^8) of Multivariate Polynomial Ring in T0, T1, T2 over Finite Field of size 7 - sage: [F(S) for F in I.gens()] + sage: R. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings + sage: S = Sequence([x, (x^2 + y^2 - 1)^2, x*y - 2]) # optional - sage.rings.finite_rings + sage: I = S.algebraic_dependence(); I # optional - sage.rings.finite_rings + Ideal (2 - 3*T2 - T0^2 + 3*T2^2 - T0^2*T2 + T2^3 + 2*T0^4 - 2*T0^2*T2^2 + + T2^4 - T0^4*T1 + T0^4*T2 - 2*T0^6 + 2*T0^4*T2^2 + T0^8) + of Multivariate Polynomial Ring in T0, T1, T2 over Finite Field of size 7 + sage: [F(S) for F in I.gens()] # optional - sage.rings.finite_rings [0] .. NOTE:: @@ -702,23 +707,23 @@ def coefficient_matrix(self, sparse=True): EXAMPLES:: - sage: P. = PolynomialRing(GF(127),4) - sage: I = sage.rings.ideal.Katsura(P) - sage: I.gens() + sage: P. = PolynomialRing(GF(127), 4) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings + sage: I.gens() # optional - sage.rings.finite_rings [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] - sage: F = Sequence(I) - sage: A,v = F.coefficient_matrix() - sage: A + sage: F = Sequence(I) # optional - sage.rings.finite_rings + sage: A,v = F.coefficient_matrix() # optional - sage.rings.finite_rings + sage: A # optional - sage.rings.finite_rings [ 0 0 0 0 0 0 0 0 0 1 2 2 2 126] [ 1 0 2 0 0 2 0 0 2 126 0 0 0 0] [ 0 2 0 0 2 0 0 2 0 0 126 0 0 0] [ 0 0 1 2 0 0 2 0 0 0 0 126 0 0] - sage: v + sage: v # optional - sage.rings.finite_rings [a^2] [a*b] [b^2] @@ -734,7 +739,7 @@ def coefficient_matrix(self, sparse=True): [ d] [ 1] - sage: A*v + sage: A*v # optional - sage.rings.finite_rings [ a + 2*b + 2*c + 2*d - 1] [a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a] [ 2*a*b + 2*b*c + 2*c*d - b] @@ -764,20 +769,20 @@ def coefficient_matrix(self, sparse=True): def subs(self, *args, **kwargs): """ Substitute variables for every polynomial in this system and - return a new system. See ``MPolynomial.subs`` for calling + return a new system. See :meth:`MPolynomial.subs` for calling convention. INPUT: - - ``args`` - arguments to be passed to ``MPolynomial.subs`` - - ``kwargs`` - keyword arguments to be passed to ``MPolynomial.subs`` + - ``args`` - arguments to be passed to :meth:`MPolynomial.subs` + - ``kwargs`` - keyword arguments to be passed to :meth:`MPolynomial.subs` EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) - sage: F,s = sr.polynomial_system(); F + sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori + sage: F, s = sr.polynomial_system(); F # optional - sage.rings.polynomial.pbori Polynomial Sequence with 40 Polynomials in 20 Variables - sage: F = F.subs(s); F + sage: F = F.subs(s); F # optional - sage.rings.polynomial.pbori Polynomial Sequence with 40 Polynomials in 16 Variables """ return PolynomialSequence(self._ring, [tuple([f.subs(*args,**kwargs) for f in r]) for r in self._parts]) @@ -788,14 +793,14 @@ def _singular_(self): EXAMPLES:: - sage: P. = PolynomialRing(GF(127)) - sage: I = sage.rings.ideal.Katsura(P) - sage: F = Sequence(I); F + sage: P. = PolynomialRing(GF(127)) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings + sage: F = Sequence(I); F # optional - sage.rings.finite_rings [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] - sage: F._singular_() + sage: F._singular_() # optional - sage.rings.finite_rings a+2*b+2*c+2*d-1, a^2+2*b^2+2*c^2+2*d^2-a, 2*a*b+2*b*c+2*c*d-b, @@ -810,10 +815,10 @@ def _magma_init_(self, magma): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True,gf2=True) - sage: F,s = sr.polynomial_system() - sage: F.set_immutable() - sage: magma(F) # indirect doctest; optional - magma + sage: sr = mq.SR(allow_zero_inversions=True, gf2=True) # optional - sage.rings.polynomial.pbori + sage: F,s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori + sage: F.set_immutable() # optional - sage.rings.polynomial.pbori + sage: magma(F) # indirect doctest; optional - magma # optional - sage.rings.polynomial.pbori Ideal of Boolean polynomial ring of rank 20 over GF(2) Order: Graded Lexicographical (bit vector word) Variables: k100, k101, k102, k103, x100, x101, x102, x103, w100, w101, w102, w103, s000, s001, s002, s003, k000, k001, k002, k003 @@ -832,9 +837,9 @@ def _repr_(self): EXAMPLES:: - sage: P. = PolynomialRing(GF(127)) - sage: I = sage.rings.ideal.Katsura(P) - sage: F = Sequence(I); F # indirect doctest + sage: P. = PolynomialRing(GF(127)) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings + sage: F = Sequence(I); F # indirect doctest # optional - sage.rings.finite_rings [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, @@ -843,8 +848,8 @@ def _repr_(self): If the system contains 20 or more polynomials, a short summary is printed:: - sage: sr = mq.SR(allow_zero_inversions=True,gf2=True) - sage: F,s = sr.polynomial_system(); F + sage: sr = mq.SR(allow_zero_inversions=True, gf2=True) # optional - sage.rings.polynomial.pbori + sage: F,s = sr.polynomial_system(); F # optional - sage.rings.polynomial.pbori Polynomial Sequence with 36 Polynomials in 20 Variables """ @@ -860,24 +865,24 @@ def __add__(self, right): EXAMPLES:: - sage: P. = PolynomialRing(GF(127)) - sage: I = sage.rings.ideal.Katsura(P) - sage: F = Sequence(I) - sage: F + [a^127 + a] + sage: P. = PolynomialRing(GF(127)) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings + sage: F = Sequence(I) # optional - sage.rings.finite_rings + sage: F + [a^127 + a] # optional - sage.rings.finite_rings [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c, a^127 + a] - sage: F + P.ideal([a^127 + a]) + sage: F + P.ideal([a^127 + a]) # optional - sage.rings.finite_rings [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c, a^127 + a] - sage: F + Sequence([a^127 + a], P) + sage: F + Sequence([a^127 + a], P) # optional - sage.rings.finite_rings [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, @@ -904,35 +909,35 @@ def connection_graph(self): EXAMPLES:: - sage: B. = BooleanPolynomialRing() - sage: F = Sequence([x*y + y + 1, z + 1]) - sage: G = F.connection_graph(); G + sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: F = Sequence([x*y + y + 1, z + 1]) # optional - sage.rings.polynomial.pbori + sage: G = F.connection_graph(); G # optional - sage.rings.polynomial.pbori Graph on 3 vertices - sage: G.is_connected() + sage: G.is_connected() # optional - sage.rings.polynomial.pbori False - sage: F = Sequence([x]) - sage: F.connection_graph() + sage: F = Sequence([x]) # optional - sage.rings.polynomial.pbori + sage: F.connection_graph() # optional - sage.rings.polynomial.pbori Graph on 1 vertex TESTS:: - sage: F = Sequence([], B) - sage: F.connection_graph() + sage: F = Sequence([], B) # optional - sage.rings.polynomial.pbori + sage: F.connection_graph() # optional - sage.rings.polynomial.pbori Graph on 0 vertices - sage: F = Sequence([1], B) - sage: F.connection_graph() + sage: F = Sequence([1], B) # optional - sage.rings.polynomial.pbori + sage: F.connection_graph() # optional - sage.rings.polynomial.pbori Graph on 0 vertices - sage: F = Sequence([x]) - sage: F.connection_graph() + sage: F = Sequence([x]) # optional - sage.rings.polynomial.pbori + sage: F.connection_graph() # optional - sage.rings.polynomial.pbori Graph on 1 vertex - sage: F = Sequence([x, y]) - sage: F.connection_graph() + sage: F = Sequence([x, y]) # optional - sage.rings.polynomial.pbori + sage: F.connection_graph() # optional - sage.rings.polynomial.pbori Graph on 2 vertices - sage: F = Sequence([x*y*z]) - sage: F.connection_graph().is_clique() + sage: F = Sequence([x*y*z]) # optional - sage.rings.polynomial.pbori + sage: F.connection_graph().is_clique() # optional - sage.rings.polynomial.pbori True - sage: F = Sequence([x*y, y*z]) - sage: F.connection_graph().is_clique() + sage: F = Sequence([x*y, y*z]) # optional - sage.rings.polynomial.pbori + sage: F.connection_graph().is_clique() # optional - sage.rings.polynomial.pbori False """ from sage.graphs.graph import Graph @@ -951,15 +956,15 @@ def connected_components(self): As an example consider one part of AES, which naturally splits into four subsystems which are independent:: - sage: sr = mq.SR(2,4,4,8,gf2=True,polybori=True) - sage: while True: # workaround (see :trac:`31891`) + sage: sr = mq.SR(2, 4, 4, 8, gf2=True, polybori=True) # optional - sage.rings.polynomial.pbori + sage: while True: # workaround (see :trac:`31891`) # optional - sage.rings.polynomial.pbori ....: try: ....: F, s = sr.polynomial_system() ....: break ....: except ZeroDivisionError: ....: pass - sage: Fz = Sequence(F.part(2)) - sage: Fz.connected_components() + sage: Fz = Sequence(F.part(2)) # optional - sage.rings.polynomial.pbori + sage: Fz.connected_components() # optional - sage.rings.polynomial.pbori [Polynomial Sequence with 128 Polynomials in 128 Variables, Polynomial Sequence with 128 Polynomials in 128 Variables, Polynomial Sequence with 128 Polynomials in 128 Variables, @@ -1005,9 +1010,9 @@ def _groebner_strategy(self): EXAMPLES:: - sage: P. = PolynomialRing(GF(127)) - sage: F = Sequence([x*y + z, y + z + 1]) - sage: F._groebner_strategy() + sage: P. = PolynomialRing(GF(127)) # optional - sage.rings.finite_rings + sage: F = Sequence([x*y + z, y + z + 1]) # optional - sage.rings.finite_rings + sage: F._groebner_strategy() # optional - sage.rings.finite_rings Groebner Strategy for ideal generated by 2 elements over Multivariate Polynomial Ring in x, y, z over Finite Field of size 127 """ @@ -1020,13 +1025,13 @@ def maximal_degree(self): EXAMPLES:: - sage: P. = PolynomialRing(GF(7)) - sage: F = Sequence([x*y + x, x]) - sage: F.maximal_degree() + sage: P. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings + sage: F = Sequence([x*y + x, x]) # optional - sage.rings.finite_rings + sage: F.maximal_degree() # optional - sage.rings.finite_rings 2 - sage: P. = PolynomialRing(GF(7)) - sage: F = Sequence([], universe=P) - sage: F.maximal_degree() + sage: P. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings + sage: F = Sequence([], universe=P) # optional - sage.rings.finite_rings + sage: F.maximal_degree() # optional - sage.rings.finite_rings -1 """ @@ -1039,15 +1044,15 @@ def __reduce__(self): """ TESTS:: - sage: P. = PolynomialRing(GF(127)) - sage: F = Sequence([x*y + z, y + z + 1]) - sage: loads(dumps(F)) == F # indirect doctest + sage: P. = PolynomialRing(GF(127)) # optional - sage.rings.finite_rings + sage: F = Sequence([x*y + z, y + z + 1]) # optional - sage.rings.finite_rings + sage: loads(dumps(F)) == F # indirect doctest # optional - sage.rings.finite_rings True We check that :trac:`26354` is fixed:: - sage: f = P.hom([y,z,x]) - sage: hash(f) == hash(loads(dumps(f))) + sage: f = P.hom([y,z,x]) # optional - sage.rings.finite_rings + sage: hash(f) == hash(loads(dumps(f))) # optional - sage.rings.finite_rings True """ @@ -1063,12 +1068,12 @@ def reduced(self): - `(f_1,...,f_n) = (g_1,...,g_s)` - - `LT(g_i) != LT(g_j)` for all `i != j` + - `LT(g_i) \neq LT(g_j)` for all `i \neq j` - `LT(g_i)` does not divide `m` for all monomials `m` of - `\{g_1,...,g_{i-1},g_{i+1},...,g_s\}` + `\{g_1,...,g_{i-1},g_{i+1},...,g_s\}` - - `LC(g_i) == 1` for all `i` if the coefficient ring is a field. + - `LC(g_i) = 1` for all `i` if the coefficient ring is a field. EXAMPLES:: @@ -1166,12 +1171,12 @@ def is_groebner(self, singular=singular): EXAMPLES:: - sage: R. = PolynomialRing(GF(127),10) - sage: I = sage.rings.ideal.Cyclic(R,4) - sage: I.basis.is_groebner() + sage: R. = PolynomialRing(GF(127), 10) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Cyclic(R, 4) # optional - sage.rings.finite_rings + sage: I.basis.is_groebner() # optional - sage.rings.finite_rings False - sage: I2 = Ideal(I.groebner_basis()) - sage: I2.basis.is_groebner() + sage: I2 = Ideal(I.groebner_basis()) # optional - sage.rings.finite_rings + sage: I2.basis.is_groebner() # optional - sage.rings.finite_rings True """ @@ -1203,64 +1208,64 @@ def eliminate_linear_variables(self, maxlength=Infinity, skip=None, return_reduc with linear leading terms which were used for reduction is also returned (default: ``False``). - - ```use_polybori`` - if ``True`` then ``polybori.ll.eliminate`` is - called. While this is typically faster what is implemented here, it + - ``use_polybori`` - if ``True`` then ``polybori.ll.eliminate`` is + called. While this is typically faster than what is implemented here, it is less flexible (``skip`` is not supported) and may increase the degree (default: ``False``) OUTPUT: - When ``return_reductors==True``, then a pair of sequences of + With ``return_reductors=True``, a pair of sequences of boolean polynomials are returned, along with the promises that: - 1. The union of the two sequences spans the - same boolean ideal as the argument of the method + 1. The union of the two sequences spans the + same boolean ideal as the argument of the method - 2. The second sequence only contains linear polynomials, and - it forms a reduced groebner basis (they all have pairwise - distinct leading variables, and the leading variable of a - polynomial does not occur anywhere in other polynomials). + 2. The second sequence only contains linear polynomials, and + it forms a reduced groebner basis (they all have pairwise + distinct leading variables, and the leading variable of a + polynomial does not occur anywhere in other polynomials). - 3. The leading variables of the second sequence do not occur - anywhere in the first sequence (these variables have been - eliminated). + 3. The leading variables of the second sequence do not occur + anywhere in the first sequence (these variables have been + eliminated). - When ``return_reductors==False``, only the first sequence is + With ``return_reductors=False``, only the first sequence is returned. EXAMPLES:: - sage: B. = BooleanPolynomialRing() - sage: F = Sequence([c + d + b + 1, a + c + d, a*b + c, b*c*d + c]) - sage: F.eliminate_linear_variables() # everything vanishes + sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: F = Sequence([c + d + b + 1, a + c + d, a*b + c, b*c*d + c]) # optional - sage.rings.polynomial.pbori + sage: F.eliminate_linear_variables() # everything vanishes # optional - sage.rings.polynomial.pbori [] - sage: F.eliminate_linear_variables(maxlength=2) + sage: F.eliminate_linear_variables(maxlength=2) # optional - sage.rings.polynomial.pbori [b + c + d + 1, b*c + b*d + c, b*c*d + c] - sage: F.eliminate_linear_variables(skip=lambda lm,tail: str(lm)=='a') + sage: F.eliminate_linear_variables(skip=lambda lm,tail: str(lm)=='a') # optional - sage.rings.polynomial.pbori [a + c + d, a*c + a*d + a + c, c*d + c] - The list of reductors can be requested by setting 'return_reductors' to ``True``:: + The list of reductors can be requested by setting ``return_reductors`` to ``True``:: - sage: B. = BooleanPolynomialRing() - sage: F = Sequence([a + b + d, a + b + c]) - sage: F,R = F.eliminate_linear_variables(return_reductors=True) - sage: F + sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: F = Sequence([a + b + d, a + b + c]) # optional - sage.rings.polynomial.pbori + sage: F, R = F.eliminate_linear_variables(return_reductors=True) # optional - sage.rings.polynomial.pbori + sage: F # optional - sage.rings.polynomial.pbori [] - sage: R + sage: R # optional - sage.rings.polynomial.pbori [a + b + d, c + d] - If the input system is detected to be inconsistent then [1] is returned + If the input system is detected to be inconsistent then ``[1]`` is returned, and the list of reductors is empty:: - sage: R. = BooleanPolynomialRing() - sage: S = Sequence([x*y*z+x*y+z*y+x*z, x+y+z+1, x+y+z]) - sage: S.eliminate_linear_variables() + sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + 1, x + y + z]) # optional - sage.rings.polynomial.pbori + sage: S.eliminate_linear_variables() # optional - sage.rings.polynomial.pbori [1] - sage: R. = BooleanPolynomialRing() - sage: S = Sequence([x*y*z+x*y+z*y+x*z, x+y+z+1, x+y+z]) - sage: S.eliminate_linear_variables(return_reductors=True) + sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + 1, x + y + z]) # optional - sage.rings.polynomial.pbori + sage: S.eliminate_linear_variables(return_reductors=True) # optional - sage.rings.polynomial.pbori ([1], []) @@ -1268,30 +1273,30 @@ def eliminate_linear_variables(self, maxlength=Infinity, skip=None, return_reduc The function should really dispose of linear equations (:trac:`13968`):: - sage: R. = BooleanPolynomialRing() - sage: S = Sequence([x+y+z+1, y+z]) - sage: S.eliminate_linear_variables(return_reductors=True) + sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: S = Sequence([x + y + z + 1, y + z]) # optional - sage.rings.polynomial.pbori + sage: S.eliminate_linear_variables(return_reductors=True) # optional - sage.rings.polynomial.pbori ([], [x + 1, y + z]) The function should take care of linear variables created by previous substitution of linear variables :: - sage: R. = BooleanPolynomialRing() - sage: S = Sequence([x*y*z+x*y+z*y+x*z, x+y+z+1, x+y]) - sage: S.eliminate_linear_variables(return_reductors=True) + sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + 1, x + y]) # optional - sage.rings.polynomial.pbori + sage: S.eliminate_linear_variables(return_reductors=True) # optional - sage.rings.polynomial.pbori ([], [x + y, z + 1]) We test a case which would increase the degree with ``polybori=True``:: - sage: B. = BooleanPolynomialRing() - sage: f = a*d + a + b*d + c*d + 1 - sage: Sequence([f, a + b*c + c+d + 1]).eliminate_linear_variables() + sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: f = a*d + a + b*d + c*d + 1 # optional - sage.rings.polynomial.pbori + sage: Sequence([f, a + b*c + c+d + 1]).eliminate_linear_variables() # optional - sage.rings.polynomial.pbori [a*d + a + b*d + c*d + 1, a + b*c + c + d + 1] - sage: B. = BooleanPolynomialRing() - sage: f = a*d + a + b*d + c*d + 1 - sage: Sequence([f, a + b*c + c+d + 1]).eliminate_linear_variables(use_polybori=True) + sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: f = a*d + a + b*d + c*d + 1 # optional - sage.rings.polynomial.pbori + sage: Sequence([f, a + b*c + c+d + 1]).eliminate_linear_variables(use_polybori=True) # optional - sage.rings.polynomial.pbori [b*c*d + b*c + b*d + c + d] .. NOTE:: @@ -1372,15 +1377,15 @@ def _groebner_strategy(self): EXAMPLES:: - sage: P. = PolynomialRing(GF(2)) - sage: F = Sequence([x*y + z, y + z + 1]) - sage: F._groebner_strategy() + sage: P. = PolynomialRing(GF(2)) # optional - sage.rings.finite_rings + sage: F = Sequence([x*y + z, y + z + 1]) # optional - sage.rings.finite_rings + sage: F._groebner_strategy() # optional - sage.rings.finite_rings Groebner Strategy for ideal generated by 2 elements over Multivariate Polynomial Ring in x, y, z over Finite Field of size 2 - sage: P. = BooleanPolynomialRing() - sage: F = Sequence([x*y + z, y + z + 1]) - sage: F._groebner_strategy() + sage: P. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: F = Sequence([x*y + z, y + z + 1]) # optional - sage.rings.polynomial.pbori + sage: F._groebner_strategy() # optional - sage.rings.polynomial.pbori """ from sage.rings.polynomial.multi_polynomial_ring_base import BooleanPolynomialRing_base @@ -1436,63 +1441,63 @@ def solve(self, algorithm='polybori', n=1, eliminate_linear_variables=True, ver Without argument, a single arbitrary solution is returned:: sage: from sage.doctest.fixtures import reproducible_repr - sage: R. = BooleanPolynomialRing() - sage: S = Sequence([x*y+z, y*z+x, x+y+z+1]) - sage: sol = S.solve() - sage: print(reproducible_repr(sol)) + sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: S = Sequence([x*y + z, y*z + x, x + y + z + 1]) # optional - sage.rings.polynomial.pbori + sage: sol = S.solve() # optional - sage.rings.polynomial.pbori + sage: print(reproducible_repr(sol)) # optional - sage.rings.polynomial.pbori [{x: 0, y: 1, z: 0}] We check that it is actually a solution:: - sage: S.subs( sol[0] ) + sage: S.subs(sol[0]) # optional - sage.rings.polynomial.pbori [0, 0, 0] We obtain all solutions:: - sage: sols = S.solve(n=Infinity) - sage: print(reproducible_repr(sols)) + sage: sols = S.solve(n=Infinity) # optional - sage.rings.polynomial.pbori + sage: print(reproducible_repr(sols)) # optional - sage.rings.polynomial.pbori [{x: 0, y: 1, z: 0}, {x: 1, y: 1, z: 1}] - sage: [S.subs(x) for x in sols] + sage: [S.subs(x) for x in sols] # optional - sage.rings.polynomial.pbori [[0, 0, 0], [0, 0, 0]] We can force the use of exhaustive search if the optional package ``FES`` is present:: - sage: sol = S.solve(algorithm='exhaustive_search') # optional - FES - sage: print(reproducible_repr(sol)) # optional - FES + sage: sol = S.solve(algorithm='exhaustive_search') # optional - FES # optional - sage.rings.polynomial.pbori + sage: print(reproducible_repr(sol)) # optional - FES # optional - sage.rings.polynomial.pbori [{x: 1, y: 1, z: 1}] - sage: S.subs( sol[0] ) + sage: S.subs(sol[0]) # optional - FES # optional - sage.rings.polynomial.pbori [0, 0, 0] And we may use SAT-solvers if they are available:: - sage: sol = S.solve(algorithm='sat') # optional - pycryptosat - sage: print(reproducible_repr(sol)) # optional - pycryptosat + sage: sol = S.solve(algorithm='sat') # optional - pycryptosat # optional - sage.rings.polynomial.pbori + sage: print(reproducible_repr(sol)) # optional - pycryptosat # optional - sage.rings.polynomial.pbori [{x: 0, y: 1, z: 0}] - sage: S.subs( sol[0] ) + sage: S.subs(sol[0]) # optional - sage.rings.polynomial.pbori [0, 0, 0] TESTS: Make sure that variables not occurring in the equations are no problem:: - sage: R. = BooleanPolynomialRing() - sage: S = Sequence([x*y+z, y*z+x, x+y+z+1]) - sage: sols = S.solve(n=Infinity) - sage: [S.subs(x) for x in sols] + sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: S = Sequence([x*y + z, y*z + x, x + y + z + 1]) # optional - sage.rings.polynomial.pbori + sage: sols = S.solve(n=Infinity) # optional - sage.rings.polynomial.pbori + sage: [S.subs(x) for x in sols] # optional - sage.rings.polynomial.pbori [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] Not eliminating linear variables:: - sage: sols = S.solve(n=Infinity, eliminate_linear_variables=False) - sage: [S.subs(x) for x in sols] + sage: sols = S.solve(n=Infinity, eliminate_linear_variables=False) # optional - sage.rings.polynomial.pbori + sage: [S.subs(x) for x in sols] # optional - sage.rings.polynomial.pbori [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] A tricky case where the linear equations are insatisfiable:: - sage: R. = BooleanPolynomialRing() - sage: S = Sequence([x*y*z+x*y+z*y+x*z, x+y+z+1, x+y+z]) - sage: S.solve() + sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + 1, x + y + z]) # optional - sage.rings.polynomial.pbori + sage: S.solve() # optional - sage.rings.polynomial.pbori [] """ @@ -1560,27 +1565,27 @@ def solve(self, algorithm='polybori', n=1, eliminate_linear_variables=True, ver return solutions def reduced(self): - """ - If this sequence is `(f_1, ..., f_n)` this method returns `(g_1, ..., g_s)` such that: + r""" + If this sequence is `f_1, ..., f_n`, return `g_1, ..., g_s` such that: - - ` = ` - - `LT(g_i) != LT(g_j)` for all `i != j`` + - `(f_1,...,f_n) = (g_1,...,g_s)` + - `LT(g_i) \neq LT(g_j)` for all `i \neq j` - `LT(g_i)` does not divide `m` for all monomials `m` of `{g_1,...,g_{i-1},g_{i+1},...,g_s}` EXAMPLES:: - sage: sr = mq.SR(1, 1, 1, 4, gf2=True, polybori=True) - sage: while True: # workaround (see :trac:`31891`) + sage: sr = mq.SR(1, 1, 1, 4, gf2=True, polybori=True) # optional - sage.rings.polynomial.pbori + sage: while True: # workaround (see :trac:`31891`) # optional - sage.rings.polynomial.pbori ....: try: ....: F, s = sr.polynomial_system() ....: break ....: except ZeroDivisionError: ....: pass - sage: g = F.reduced() - sage: len(g) == len(set(gi.lt() for gi in g)) + sage: g = F.reduced() # optional - sage.rings.polynomial.pbori + sage: len(g) == len(set(gi.lt() for gi in g)) # optional - sage.rings.polynomial.pbori True - sage: for i in range(len(g)): + sage: for i in range(len(g)): # optional - sage.rings.polynomial.pbori ....: for j in range(len(g)): ....: if i == j: ....: continue @@ -1618,27 +1623,27 @@ def weil_restriction(self): EXAMPLES:: - sage: k. = GF(2^2) - sage: P. = PolynomialRing(k,2) - sage: a = P.base_ring().gen() - sage: F = Sequence([x*y + 1, a*x + 1], P) - sage: F2 = F.weil_restriction() - sage: F2 + sage: k. = GF(2^2) # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(k, 2) # optional - sage.rings.finite_rings + sage: a = P.base_ring().gen() # optional - sage.rings.finite_rings + sage: F = Sequence([x*y + 1, a*x + 1], P) # optional - sage.rings.finite_rings + sage: F2 = F.weil_restriction() # optional - sage.rings.finite_rings + sage: F2 # optional - sage.rings.finite_rings [x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1, x0^2 + x0, - x1^2 + x1, y0^2 + y0, y1^2 + y1] + x1^2 + x1, y0^2 + y0, y1^2 + y1] Another bigger example for a small scale AES:: - sage: sr = mq.SR(1,1,1,4,gf2=False) - sage: while True: # workaround (see :trac:`31891`) + sage: sr = mq.SR(1, 1, 1, 4, gf2=False) # optional - sage.rings.polynomial.pbori + sage: while True: # workaround (see :trac:`31891`) # optional - sage.rings.polynomial.pbori ....: try: ....: F, s = sr.polynomial_system() ....: break ....: except ZeroDivisionError: ....: pass - sage: F + sage: F # optional - sage.rings.polynomial.pbori Polynomial Sequence with 40 Polynomials in 20 Variables - sage: F2 = F.weil_restriction(); F2 + sage: F2 = F.weil_restriction(); F2 # optional - sage.rings.polynomial.pbori Polynomial Sequence with 240 Polynomials in 80 Variables """ from sage.rings.ideal import FieldIdeal diff --git a/src/sage/rings/polynomial/ore_polynomial_element.pyx b/src/sage/rings/polynomial/ore_polynomial_element.pyx index 4db1a1652ff..d30478b4f48 100644 --- a/src/sage/rings/polynomial/ore_polynomial_element.pyx +++ b/src/sage/rings/polynomial/ore_polynomial_element.pyx @@ -164,48 +164,48 @@ cdef class OrePolynomial(AlgebraElement): Here is another example over a finite field:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: a = x^4 + (4*t + 1)*x^3 + (t^2 + 3*t + 3)*x^2 + (3*t^2 + 2*t + 2)*x + (3*t^2 + 3*t + 1) - sage: b = (2*t^2 + 3)*x^2 + (3*t^2 + 1)*x + 4*t + 2 - sage: q,r = a.left_quo_rem(b) - sage: q + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: a = x^4 + (4*t + 1)*x^3 + (t^2 + 3*t + 3)*x^2 + (3*t^2 + 2*t + 2)*x + (3*t^2 + 3*t + 1) # optional - sage.rings.finite_rings + sage: b = (2*t^2 + 3)*x^2 + (3*t^2 + 1)*x + 4*t + 2 # optional - sage.rings.finite_rings + sage: q, r = a.left_quo_rem(b) # optional - sage.rings.finite_rings + sage: q # optional - sage.rings.finite_rings (4*t^2 + t + 1)*x^2 + (2*t^2 + 2*t + 2)*x + 2*t^2 + 4*t + 3 - sage: r + sage: r # optional - sage.rings.finite_rings (t + 2)*x + 3*t^2 + 2*t + 4 - sage: a == b*q + r + sage: a == b*q + r # optional - sage.rings.finite_rings True Once we have euclidean divisions, we have for free gcd and lcm (at least if the base ring is a field):: - sage: a = (x + t) * (x + t^2)^2 - sage: b = (x + t) * (t*x + t + 1) * (x + t^2) - sage: a.right_gcd(b) + sage: a = (x + t) * (x + t^2)^2 # optional - sage.rings.finite_rings + sage: b = (x + t) * (t*x + t + 1) * (x + t^2) # optional - sage.rings.finite_rings + sage: a.right_gcd(b) # optional - sage.rings.finite_rings x + t^2 - sage: a.left_gcd(b) + sage: a.left_gcd(b) # optional - sage.rings.finite_rings x + t The left lcm has the following meaning: given Ore polynomials `a` and `b`, their left lcm is the least degree polynomial `c = ua = vb` for some Ore polynomials `u, v`. Such a `c` always exist if the base ring is a field:: - sage: c = a.left_lcm(b); c + sage: c = a.left_lcm(b); c # optional - sage.rings.finite_rings x^5 + (4*t^2 + t + 3)*x^4 + (3*t^2 + 4*t)*x^3 + 2*t^2*x^2 + (2*t^2 + t)*x + 4*t^2 + 4 - sage: c.is_right_divisible_by(a) + sage: c.is_right_divisible_by(a) # optional - sage.rings.finite_rings True - sage: c.is_right_divisible_by(b) + sage: c.is_right_divisible_by(b) # optional - sage.rings.finite_rings True The right lcm is defined similarly as the least degree polynomial `c = au = bv` for some `u,v`:: - sage: d = a.right_lcm(b); d + sage: d = a.right_lcm(b); d # optional - sage.rings.finite_rings x^5 + (t^2 + 1)*x^4 + (3*t^2 + 3*t + 3)*x^3 + (3*t^2 + t + 2)*x^2 + (4*t^2 + 3*t)*x + 4*t + 4 - sage: d.is_left_divisible_by(a) + sage: d.is_left_divisible_by(a) # optional - sage.rings.finite_rings True - sage: d.is_left_divisible_by(b) + sage: d.is_left_divisible_by(b) # optional - sage.rings.finite_rings True .. SEEALSO:: @@ -291,10 +291,10 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: sage: from sage.rings.polynomial.ore_polynomial_element import OrePolynomialBaseringInjection - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: OrePolynomialBaseringInjection(k, k['x', Frob]) #indirect doctest + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: OrePolynomialBaseringInjection(k, k['x', Frob]) #indirect doctest # optional - sage.rings.finite_rings Ore Polynomial base injection morphism: From: Finite Field in t of size 5^3 To: Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 @@ -313,10 +313,10 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: a = x + t - sage: a[1] = t + 1 + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: a = x + t # optional - sage.rings.finite_rings + sage: a[1] = t + 1 # optional - sage.rings.finite_rings Traceback (most recent call last): ... IndexError: Ore polynomials are immutable @@ -484,26 +484,26 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: a = (3*t^2 + 3*t + 2)*x^3 + (2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2 - sage: b = a.left_monic(); b + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: a = (3*t^2 + 3*t + 2)*x^3 + (2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2 # optional - sage.rings.finite_rings + sage: b = a.left_monic(); b # optional - sage.rings.finite_rings x^3 + (4*t^2 + 3*t)*x^2 + (4*t + 2)*x + 2*t^2 + 4*t + 3 Check list:: - sage: b.degree() == a.degree() + sage: b.degree() == a.degree() # optional - sage.rings.finite_rings True - sage: b.is_left_divisible_by(a) + sage: b.is_left_divisible_by(a) # optional - sage.rings.finite_rings True - sage: twist = S.twisting_morphism(-a.degree()) - sage: a == b * twist(a.leading_coefficient()) + sage: twist = S.twisting_morphism(-a.degree()) # optional - sage.rings.finite_rings + sage: a == b * twist(a.leading_coefficient()) # optional - sage.rings.finite_rings True Note that `b` does not divide `a` on the right:: - sage: a.is_right_divisible_by(b) + sage: a.is_right_divisible_by(b) # optional - sage.rings.finite_rings False This function does not work if the leading coefficient is not a @@ -537,25 +537,25 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: a = (3*t^2 + 3*t + 2)*x^3 + (2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2 - sage: b = a.right_monic(); b + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: a = (3*t^2 + 3*t + 2)*x^3 + (2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2 # optional - sage.rings.finite_rings + sage: b = a.right_monic(); b # optional - sage.rings.finite_rings x^3 + (2*t^2 + 3*t + 4)*x^2 + (3*t^2 + 4*t + 1)*x + 2*t^2 + 4*t + 3 Check list:: - sage: b.degree() == a.degree() + sage: b.degree() == a.degree() # optional - sage.rings.finite_rings True - sage: b.is_right_divisible_by(a) + sage: b.is_right_divisible_by(a) # optional - sage.rings.finite_rings True - sage: a == a.leading_coefficient() * b + sage: a == a.leading_coefficient() * b # optional - sage.rings.finite_rings True Note that `b` does not divide `a` on the right:: - sage: a.is_left_divisible_by(b) + sage: a.is_left_divisible_by(b) # optional - sage.rings.finite_rings False This function does not work if the leading coefficient is not a @@ -635,14 +635,15 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: R. = GF(11)[] - sage: der = R.derivation() - sage: S. = R['x', der] - sage: f = t/x - sage: f + sage: R. = GF(11)[] # optional - sage.rings.finite_rings + sage: der = R.derivation() # optional - sage.rings.finite_rings + sage: S. = R['x', der] # optional - sage.rings.finite_rings + sage: f = t/x # optional - sage.rings.finite_rings + sage: f # optional - sage.rings.finite_rings (x + 10/t)^(-1) * t - sage: f.parent() - Ore Function Field in x over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 11 twisted by d/dt + sage: f.parent() # optional - sage.rings.finite_rings + Ore Function Field in x over + Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 11 twisted by d/dt """ parent = self.parent().fraction_field() return parent(self) / parent(right) @@ -696,20 +697,20 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: a = x^2 + t*x + t^2 + 3 - sage: b = x^3 + (t + 1)*x^2 + 1 - sage: c = a*b - sage: c.is_right_divisible_by(a) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: a = x^2 + t*x + t^2 + 3 # optional - sage.rings.finite_rings + sage: b = x^3 + (t + 1)*x^2 + 1 # optional - sage.rings.finite_rings + sage: c = a*b # optional - sage.rings.finite_rings + sage: c.is_right_divisible_by(a) # optional - sage.rings.finite_rings False - sage: c.is_right_divisible_by(b) + sage: c.is_right_divisible_by(b) # optional - sage.rings.finite_rings True Divisibility by `0` does not make sense:: - sage: c.is_right_divisible_by(S(0)) + sage: c.is_right_divisible_by(S(0)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: division by zero is not valid @@ -745,20 +746,20 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: a = x^2 + t*x + t^2 + 3 - sage: b = x^3 + (t + 1)*x^2 + 1 - sage: c = a*b - sage: a.left_divides(c) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: a = x^2 + t*x + t^2 + 3 # optional - sage.rings.finite_rings + sage: b = x^3 + (t + 1)*x^2 + 1 # optional - sage.rings.finite_rings + sage: c = a*b # optional - sage.rings.finite_rings + sage: a.left_divides(c) # optional - sage.rings.finite_rings True - sage: b.left_divides(c) + sage: b.left_divides(c) # optional - sage.rings.finite_rings False Divisibility by `0` does not make sense:: - sage: S(0).left_divides(c) + sage: S(0).left_divides(c) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: division by zero is not valid @@ -780,20 +781,20 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: a = x^2 + t*x + t^2 + 3 - sage: b = x^3 + (t + 1)*x^2 + 1 - sage: c = a*b - sage: a.right_divides(c) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: a = x^2 + t*x + t^2 + 3 # optional - sage.rings.finite_rings + sage: b = x^3 + (t + 1)*x^2 + 1 # optional - sage.rings.finite_rings + sage: c = a*b # optional - sage.rings.finite_rings + sage: a.right_divides(c) # optional - sage.rings.finite_rings False - sage: b.right_divides(c) + sage: b.right_divides(c) # optional - sage.rings.finite_rings True Divisibility by `0` does not make sense:: - sage: S(0).right_divides(c) + sage: S(0).right_divides(c) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: division by zero is not valid @@ -858,21 +859,21 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: a = (x + t) * (x^2 + t*x + 1) - sage: b = 2 * (x + t) * (x^3 + (t+1)*x^2 + t^2) - sage: g,u,v = a.left_xgcd(b); g + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: a = (x + t) * (x^2 + t*x + 1) # optional - sage.rings.finite_rings + sage: b = 2 * (x + t) * (x^3 + (t+1)*x^2 + t^2) # optional - sage.rings.finite_rings + sage: g,u,v = a.left_xgcd(b); g # optional - sage.rings.finite_rings x + t - sage: a*u + b*v == g + sage: a*u + b*v == g # optional - sage.rings.finite_rings True Specifying ``monic=False``, we *can* get a nonmonic gcd:: - sage: g,u,v = a.left_xgcd(b, monic=False); g + sage: g,u,v = a.left_xgcd(b, monic=False); g # optional - sage.rings.finite_rings 2*t*x + 4*t + 2 - sage: a*u + b*v == g + sage: a*u + b*v == g # optional - sage.rings.finite_rings True The base ring must be a field:: @@ -961,13 +962,13 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: a = (3*t^2 + 3*t + 2)*x^3 + (2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2 - sage: b = (3*t^2 + 4*t + 2)*x^2 + (2*t^2 + 4*t + 3)*x + 2*t^2 + t + 1 - sage: q,r = a.left_quo_rem(b) - sage: a == b*q + r + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: a = (3*t^2 + 3*t + 2)*x^3 + (2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2 # optional - sage.rings.finite_rings + sage: b = (3*t^2 + 4*t + 2)*x^2 + (2*t^2 + 4*t + 3)*x + 2*t^2 + t + 1 # optional - sage.rings.finite_rings + sage: q,r = a.left_quo_rem(b) # optional - sage.rings.finite_rings + sage: a == b*q + r # optional - sage.rings.finite_rings True In the following example, Sage does not know the inverse @@ -1090,21 +1091,21 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: a = (x^2 + t*x + 1) * (x + t) - sage: b = 2 * (x^3 + (t+1)*x^2 + t^2) * (x + t) - sage: g,u,v = a.right_xgcd(b); g + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: a = (x^2 + t*x + 1) * (x + t) # optional - sage.rings.finite_rings + sage: b = 2 * (x^3 + (t+1)*x^2 + t^2) * (x + t) # optional - sage.rings.finite_rings + sage: g,u,v = a.right_xgcd(b); g # optional - sage.rings.finite_rings x + t - sage: u*a + v*b == g + sage: u*a + v*b == g # optional - sage.rings.finite_rings True Specifying ``monic=False``, we *can* get a nonmonic gcd:: - sage: g,u,v = a.right_xgcd(b,monic=False); g + sage: g,u,v = a.right_xgcd(b, monic=False); g # optional - sage.rings.finite_rings (4*t^2 + 4*t + 1)*x + 4*t^2 + 4*t + 3 - sage: u*a + v*b == g + sage: u*a + v*b == g # optional - sage.rings.finite_rings True The base ring must be a field:: @@ -1173,17 +1174,17 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: a = (x^2 + t*x + 1) * (x + t) - sage: b = 2 * (x^3 + (t+1)*x^2 + t^2) * (x + t) - sage: a.right_gcd(b) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: a = (x^2 + t*x + 1) * (x + t) # optional - sage.rings.finite_rings + sage: b = 2 * (x^3 + (t+1)*x^2 + t^2) * (x + t) # optional - sage.rings.finite_rings + sage: a.right_gcd(b) # optional - sage.rings.finite_rings x + t Specifying ``monic=False``, we *can* get a nonmonic gcd:: - sage: a.right_gcd(b,monic=False) + sage: a.right_gcd(b,monic=False) # optional - sage.rings.finite_rings (4*t^2 + 4*t + 1)*x + 4*t^2 + 4*t + 3 The base ring need to be a field:: @@ -1240,22 +1241,22 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: a = (x + t) * (x^2 + t*x + 1) - sage: b = 2 * (x + t) * (x^3 + (t+1)*x^2 + t^2) - sage: a.left_gcd(b) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: a = (x + t) * (x^2 + t*x + 1) # optional - sage.rings.finite_rings + sage: b = 2 * (x + t) * (x^3 + (t+1)*x^2 + t^2) # optional - sage.rings.finite_rings + sage: a.left_gcd(b) # optional - sage.rings.finite_rings x + t Specifying ``monic=False``, we *can* get a nonmonic gcd:: - sage: a.left_gcd(b,monic=False) + sage: a.left_gcd(b,monic=False) # optional - sage.rings.finite_rings 2*t*x + 4*t + 2 The base ring needs to be a field:: - sage: R. = QQ[] + sage: R. = QQ[] # optional - sage.rings.finite_rings sage: sigma = R.hom([t+1]) sage: S. = R['x',sigma] sage: a = (x + t) * (x^2 + t*x + 1) @@ -1301,23 +1302,23 @@ cdef class OrePolynomial(AlgebraElement): TESTS:: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: from sage.rings.polynomial.ore_polynomial_element cimport OrePolynomial ....: def left_lcm_cofactor(OrePolynomial P, OrePolynomial Q): ....: return P._left_lcm_cofactor(Q) ....: ''') - sage: k. = GF(7^5) - sage: Frob = k.frobenius_endomorphism(3) - sage: S. = k['x', Frob] + sage: k. = GF(7^5) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism(3) # optional - sage.rings.finite_rings + sage: S. = k['x', Frob] # optional - sage.rings.finite_rings - sage: D = S.random_element(degree=2) - sage: P = S.random_element(degree=2) * D - sage: Q = S.random_element(degree=2) * D - sage: L = P.left_lcm(Q) - sage: U = left_lcm_cofactor(P, Q) # optional - sage.misc.cython - sage: (U*P).right_monic() == L # optional - sage.misc.cython + sage: D = S.random_element(degree=2) # optional - sage.rings.finite_rings + sage: P = S.random_element(degree=2) * D # optional - sage.rings.finite_rings + sage: Q = S.random_element(degree=2) * D # optional - sage.rings.finite_rings + sage: L = P.left_lcm(Q) # optional - sage.rings.finite_rings + sage: U = left_lcm_cofactor(P, Q) # optional - sage.misc.cython sage.rings.finite_rings + sage: (U*P).right_monic() == L # optional - sage.misc.cython sage.rings.finite_rings True """ cdef OrePolynomial Q, R, T @@ -1344,18 +1345,18 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: P = (x + t^2) * (x + t) - sage: Q = 2 * (x^2 + t + 1) * (x * t) - sage: L, U, V = P.left_xlcm(Q) - sage: L + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: P = (x + t^2) * (x + t) # optional - sage.rings.finite_rings + sage: Q = 2 * (x^2 + t + 1) * (x * t) # optional - sage.rings.finite_rings + sage: L, U, V = P.left_xlcm(Q) # optional - sage.rings.finite_rings + sage: L # optional - sage.rings.finite_rings x^5 + (2*t^2 + t + 4)*x^4 + (3*t^2 + 4)*x^3 + (3*t^2 + 3*t + 2)*x^2 + (t^2 + t + 2)*x - sage: U*P == L + sage: U*P == L # optional - sage.rings.finite_rings True - sage: V*Q == L + sage: V*Q == L # optional - sage.rings.finite_rings True """ if self.base_ring() not in _Fields: @@ -1379,23 +1380,23 @@ cdef class OrePolynomial(AlgebraElement): TESTS:: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: from sage.rings.polynomial.ore_polynomial_element cimport OrePolynomial ....: def right_lcm_cofactor(OrePolynomial P, OrePolynomial Q): ....: return P._right_lcm_cofactor(Q) ....: ''') - sage: k. = GF(7^5) - sage: Frob = k.frobenius_endomorphism(3) - sage: S. = k['x', Frob] + sage: k. = GF(7^5) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism(3) # optional - sage.rings.finite_rings + sage: S. = k['x', Frob] # optional - sage.rings.finite_rings - sage: D = S.random_element(degree=2) - sage: P = D * S.random_element(degree=2) - sage: Q = D * S.random_element(degree=2) - sage: L = P.right_lcm(Q) - sage: U = right_lcm_cofactor(P, Q) # optional - sage.misc.cython - sage: (P*U).left_monic() == L # optional - sage.misc.cython + sage: D = S.random_element(degree=2) # optional - sage.rings.finite_rings + sage: P = D * S.random_element(degree=2) # optional - sage.rings.finite_rings + sage: Q = D * S.random_element(degree=2) # optional - sage.rings.finite_rings + sage: L = P.right_lcm(Q) # optional - sage.rings.finite_rings + sage: U = right_lcm_cofactor(P, Q) # optional - sage.misc.cython sage.rings.finite_rings + sage: (P*U).left_monic() == L # optional - sage.misc.cython sage.rings.finite_rings True """ cdef OrePolynomial Q, R, T @@ -1429,17 +1430,17 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: P = (x + t) * (x + t^2) - sage: Q = 2 * (x + t) * (x^2 + t + 1) - sage: L, U, V = P.right_xlcm(Q) - sage: L + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: P = (x + t) * (x + t^2) # optional - sage.rings.finite_rings + sage: Q = 2 * (x + t) * (x^2 + t + 1) # optional - sage.rings.finite_rings + sage: L, U, V = P.right_xlcm(Q) # optional - sage.rings.finite_rings + sage: L # optional - sage.rings.finite_rings x^4 + (2*t^2 + t + 2)*x^3 + (3*t^2 + 4*t + 1)*x^2 + (3*t^2 + 4*t + 1)*x + t^2 + 4 - sage: P*U == L + sage: P*U == L # optional - sage.rings.finite_rings True - sage: Q*V == L + sage: Q*V == L # optional - sage.rings.finite_rings True """ if self.base_ring() not in _Fields: @@ -1484,23 +1485,23 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: a = (x + t^2) * (x + t) - sage: b = 2 * (x^2 + t + 1) * (x * t) - sage: c = a.left_lcm(b); c + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: a = (x + t^2) * (x + t) # optional - sage.rings.finite_rings + sage: b = 2 * (x^2 + t + 1) * (x * t) # optional - sage.rings.finite_rings + sage: c = a.left_lcm(b); c # optional - sage.rings.finite_rings x^5 + (2*t^2 + t + 4)*x^4 + (3*t^2 + 4)*x^3 + (3*t^2 + 3*t + 2)*x^2 + (t^2 + t + 2)*x - sage: c.is_right_divisible_by(a) + sage: c.is_right_divisible_by(a) # optional - sage.rings.finite_rings True - sage: c.is_right_divisible_by(b) + sage: c.is_right_divisible_by(b) # optional - sage.rings.finite_rings True - sage: a.degree() + b.degree() == c.degree() + a.right_gcd(b).degree() + sage: a.degree() + b.degree() == c.degree() + a.right_gcd(b).degree() # optional - sage.rings.finite_rings True Specifying ``monic=False``, we *can* get a nonmonic gcd:: - sage: a.left_lcm(b,monic=False) + sage: a.left_lcm(b,monic=False) # optional - sage.rings.finite_rings (t^2 + t)*x^5 + (4*t^2 + 4*t + 1)*x^4 + (t + 1)*x^3 + (t^2 + 2)*x^2 + (3*t + 4)*x The base ring needs to be a field:: @@ -1554,23 +1555,23 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: a = (x + t) * (x + t^2) - sage: b = 2 * (x + t) * (x^2 + t + 1) - sage: c = a.right_lcm(b); c + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: a = (x + t) * (x + t^2) # optional - sage.rings.finite_rings + sage: b = 2 * (x + t) * (x^2 + t + 1) # optional - sage.rings.finite_rings + sage: c = a.right_lcm(b); c # optional - sage.rings.finite_rings x^4 + (2*t^2 + t + 2)*x^3 + (3*t^2 + 4*t + 1)*x^2 + (3*t^2 + 4*t + 1)*x + t^2 + 4 - sage: c.is_left_divisible_by(a) + sage: c.is_left_divisible_by(a) # optional - sage.rings.finite_rings True - sage: c.is_left_divisible_by(b) + sage: c.is_left_divisible_by(b) # optional - sage.rings.finite_rings True - sage: a.degree() + b.degree() == c.degree() + a.left_gcd(b).degree() + sage: a.degree() + b.degree() == c.degree() + a.left_gcd(b).degree() # optional - sage.rings.finite_rings True Specifying ``monic=False``, we *can* get a nonmonic gcd:: - sage: a.right_lcm(b,monic=False) + sage: a.right_lcm(b,monic=False) # optional - sage.rings.finite_rings 2*t*x^4 + (3*t + 1)*x^3 + (4*t^2 + 4*t + 3)*x^2 + (3*t^2 + 4*t + 2)*x + 3*t^2 + 2*t + 3 @@ -2052,12 +2053,12 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: a = 1 + t*x^2 - sage: b = x + 1 - sage: a.left_mod(b) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: a = 1 + t*x^2 # optional - sage.rings.finite_rings + sage: b = x + 1 # optional - sage.rings.finite_rings + sage: a.left_mod(b) # optional - sage.rings.finite_rings 2*t^2 + 4*t """ _, r = self.left_quo_rem(other) @@ -2853,54 +2854,55 @@ cdef class OrePolynomial_generic_dense(OrePolynomial): EXAMPLES:: - sage: R. = GF(7)[] - sage: der = R.derivation() - sage: A. = R['d', der] + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: der = R.derivation() # optional - sage.rings.finite_rings + sage: A. = R['d', der] # optional - sage.rings.finite_rings - sage: L = d^3 + t*d^2 - sage: L.hilbert_shift(t) + sage: L = d^3 + t*d^2 # optional - sage.rings.finite_rings + sage: L.hilbert_shift(t) # optional - sage.rings.finite_rings d^3 + 4*t*d^2 + (5*t^2 + 3)*d + 2*t^3 + 4*t - sage: (d+t)^3 + t*(d+t)^2 + sage: (d+t)^3 + t*(d+t)^2 # optional - sage.rings.finite_rings d^3 + 4*t*d^2 + (5*t^2 + 3)*d + 2*t^3 + 4*t One can specify another variable name:: - sage: L.hilbert_shift(t, var='x') + sage: L.hilbert_shift(t, var='x') # optional - sage.rings.finite_rings x^3 + 4*t*x^2 + (5*t^2 + 3)*x + 2*t^3 + 4*t When the twisting morphism is not trivial, the output lies in a different Ore polynomial ring:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x', Frob] + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x', Frob] # optional - sage.rings.finite_rings - sage: P = x^2 + a*x + a^2 - sage: Q = P.hilbert_shift(a); Q + sage: P = x^2 + a*x + a^2 # optional - sage.rings.finite_rings + sage: Q = P.hilbert_shift(a); Q # optional - sage.rings.finite_rings x^2 + (2*a^2 + a + 4)*x + a^2 + 3*a + 4 - sage: Q.parent() - Ore Polynomial Ring in x over Finite Field in a of size 5^3 twisted by a |--> a^5 and a*([a |--> a^5] - id) - sage: Q.parent() is S + sage: Q.parent() # optional - sage.rings.finite_rings + Ore Polynomial Ring in x over + Finite Field in a of size 5^3 twisted by a |--> a^5 and a*([a |--> a^5] - id) + sage: Q.parent() is S # optional - sage.rings.finite_rings False This behavior ensures that the Hilbert shift by a fixed element defines an homomorphism of rings:: - sage: U = S.random_element(degree=5) - sage: V = S.random_element(degree=5) - sage: s = k.random_element() - sage: (U+V).hilbert_shift(s) == U.hilbert_shift(s) + V.hilbert_shift(s) + sage: U = S.random_element(degree=5) # optional - sage.rings.finite_rings + sage: V = S.random_element(degree=5) # optional - sage.rings.finite_rings + sage: s = k.random_element() # optional - sage.rings.finite_rings + sage: (U+V).hilbert_shift(s) == U.hilbert_shift(s) + V.hilbert_shift(s) # optional - sage.rings.finite_rings True - sage: (U*V).hilbert_shift(s) == U.hilbert_shift(s) * V.hilbert_shift(s) + sage: (U*V).hilbert_shift(s) == U.hilbert_shift(s) * V.hilbert_shift(s) # optional - sage.rings.finite_rings True We check that shifting by an element and then by its opposite gives back the initial Ore polynomial:: - sage: P = S.random_element(degree=10) - sage: s = k.random_element() - sage: P.hilbert_shift(s).hilbert_shift(-s) == P + sage: P = S.random_element(degree=10) # optional - sage.rings.finite_rings + sage: s = k.random_element() # optional - sage.rings.finite_rings + sage: P.hilbert_shift(s).hilbert_shift(-s) == P # optional - sage.rings.finite_rings True """ from sage.rings.polynomial.ore_polynomial_ring import OrePolynomialRing @@ -3002,7 +3004,8 @@ cdef class OrePolynomialBaseringInjection(Morphism): sage: S.coerce_map_from(S.base_ring()) #indirect doctest Ore Polynomial base injection morphism: From: Univariate Polynomial Ring in t over Rational Field - To: Ore Polynomial Ring in x over Univariate Polynomial Ring in t over Rational Field twisted by t |--> t + 1 + To: Ore Polynomial Ring in x over Univariate Polynomial Ring in t + over Rational Field twisted by t |--> t + 1 """ def __init__(self, domain, codomain): r""" @@ -3018,10 +3021,10 @@ cdef class OrePolynomialBaseringInjection(Morphism): TESTS:: sage: from sage.rings.polynomial.ore_polynomial_element import OrePolynomialBaseringInjection - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: OrePolynomialBaseringInjection(k, k['x', Frob]) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: OrePolynomialBaseringInjection(k, k['x', Frob]) # optional - sage.rings.finite_rings Ore Polynomial base injection morphism: From: Finite Field in t of size 5^3 To: Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 @@ -3045,11 +3048,11 @@ cdef class OrePolynomialBaseringInjection(Morphism): EXAMPLES:: sage: from sage.rings.polynomial.ore_polynomial_element import OrePolynomialBaseringInjection - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: m = OrePolynomialBaseringInjection(k, k['x', Frob]) - sage: m.an_element() + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: m = OrePolynomialBaseringInjection(k, k['x', Frob]) # optional - sage.rings.finite_rings + sage: m.an_element() # optional - sage.rings.finite_rings x """ return self._an_element @@ -3070,13 +3073,13 @@ cdef class OrePolynomialBaseringInjection(Morphism): TESTS:: sage: from sage.rings.polynomial.ore_polynomial_element import OrePolynomialBaseringInjection - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: m = OrePolynomialBaseringInjection(k, k['x', Frob]) - sage: m(4) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: m = OrePolynomialBaseringInjection(k, k['x', Frob]) # optional - sage.rings.finite_rings + sage: m(4) # optional - sage.rings.finite_rings 4 - sage: parent(m(4)) + sage: parent(m(4)) # optional - sage.rings.finite_rings Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 """ try: @@ -3092,11 +3095,11 @@ cdef class OrePolynomialBaseringInjection(Morphism): TESTS:: sage: from sage.rings.polynomial.ore_polynomial_element import OrePolynomialBaseringInjection - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: m = OrePolynomialBaseringInjection(k, k['x', Frob]) - sage: m.section() + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: m = OrePolynomialBaseringInjection(k, k['x', Frob]) # optional - sage.rings.finite_rings + sage: m.section() # optional - sage.rings.finite_rings Generic map: From: Ore Polynomial Ring 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 diff --git a/src/sage/rings/polynomial/padics/polynomial_padic.py b/src/sage/rings/polynomial/padics/polynomial_padic.py index 5dca5066033..b9c16923cc3 100644 --- a/src/sage/rings/polynomial/padics/polynomial_padic.py +++ b/src/sage/rings/polynomial/padics/polynomial_padic.py @@ -189,7 +189,8 @@ def factor(self): sage: factor(t^2) Traceback (most recent call last): ... - PrecisionError: p-adic factorization not well-defined since the discriminant is zero up to the requestion p-adic precision + PrecisionError: p-adic factorization not well-defined since + the discriminant is zero up to the requestion p-adic precision An example of factoring a constant polynomial (see :trac:`26669`):: @@ -254,8 +255,8 @@ def factor(self): def root_field(self, names, check_irreducible=True, **kwds): """ - Return the p-adic extension field generated by the roots of the irreducible - polynomial self. + Return the `p`-adic extension field generated by the roots of the irreducible + polynomial ``self``. INPUT: diff --git a/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py b/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py index cef06997537..204ae5c54f4 100644 --- a/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py +++ b/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py @@ -731,7 +731,7 @@ def _unsafe_mutate(self, n, value): def __pari__(self, variable=None): """ - Return ``self`` as a Pari object. + Return ``self`` as a PARI object. """ if variable is None: variable = self.parent().variable_name() @@ -749,7 +749,7 @@ def degree(self, secure=False): INPUT: - - secure -- a boolean (default: ``False``) + - ``secure`` -- a boolean (default: ``False``) If ``secure`` is ``True`` and the degree of this polynomial is not determined (because the leading coefficient is @@ -817,15 +817,15 @@ def precision_absolute(self, n=None): INPUT: - ``self`` -- a p-adic polynomial + - ``self`` -- a p-adic polynomial - n -- ``None`` or an integer (default ``None``). + - ``n`` -- ``None`` or an integer (default ``None``). OUTPUT: - If n == None, returns a list of absolute precisions of + If ``n`` is ``None``, returns a list of absolute precisions of coefficients. Otherwise, returns the absolute precision of - the coefficient of x^n. + the coefficient of `x^n`. EXAMPLES:: @@ -846,15 +846,15 @@ def precision_relative(self, n=None): INPUT: - ``self`` -- a p-adic polynomial + - ``self`` -- a p-adic polynomial - n -- ``None`` or an integer (default ``None``). + - ``n`` -- ``None`` or an integer (default ``None``). OUTPUT: - If n == None, returns a list of relative precisions of + If ``n`` is ``None``, returns a list of relative precisions of coefficients. Otherwise, returns the relative precision of - the coefficient of x^n. + the coefficient of `x^n`. EXAMPLES:: @@ -882,14 +882,14 @@ def valuation_of_coefficient(self, n=None): INPUT: - ``self`` -- a p-adic polynomial + - ``self`` -- a p-adic polynomial - n -- ``None`` or an integer (default ``None``). + - ``n`` -- ``None`` or an integer (default ``None``). OUTPUT: - If n == None, returns a list of valuations of coefficients. Otherwise, - returns the valuation of the coefficient of x^n. + If ``n`` is ``None``, returns a list of valuations of coefficients. Otherwise, + returns the valuation of the coefficient of `x^n`. EXAMPLES:: @@ -916,15 +916,15 @@ def valuation(self, val_of_var=None): INPUT: - ``self`` -- a p-adic polynomial + - ``self`` -- a p-adic polynomial - val_of_var -- ``None`` or a rational (default ``None``). + - ``val_of_var`` -- ``None`` or a rational (default ``None``). OUTPUT: - If val_of_var == None, returns the largest power of the + If ``val_of_var`` is ``None``, returns the largest power of the variable dividing self. Otherwise, returns the valuation of - ``self`` where the variable is assigned valuation val_of_var + ``self`` where the variable is assigned valuation ``val_of_var`` EXAMPLES:: @@ -997,7 +997,7 @@ def reverse(self, degree=None): def rescale(self, a): r""" - Return f(a*X) + Return `f(a\cdot x)`. .. TODO:: @@ -1085,7 +1085,7 @@ def _quo_rem_naive(self, right): def _quo_rem_list(self, right, secure): """ - An implementation of quo_rem using lists of coefficients. + An implementation of :meth:`quo_rem` using lists of coefficients. Faster than :meth:`_quo_rem_naive`. @@ -1138,7 +1138,7 @@ def newton_polygon(self): OUTPUT: - - a Newton polygon + - a :class:`NewtonPolygon` EXAMPLES:: diff --git a/src/sage/rings/polynomial/polydict.pyx b/src/sage/rings/polynomial/polydict.pyx index 3db1bb6c531..5bb858aa2df 100644 --- a/src/sage/rings/polynomial/polydict.pyx +++ b/src/sage/rings/polynomial/polydict.pyx @@ -782,7 +782,7 @@ cdef class PolyDict: Check that :trac:`29604` is fixed:: - sage: PolyDict({(1, 0): GF(2)(1)}).latex(['x', 'y']) + sage: PolyDict({(1, 0): GF(2)(1)}).latex(['x', 'y']) # optional - sage.rings.finite_rings 'x' """ if not self: @@ -1004,9 +1004,9 @@ cdef class PolyDict: sage: f + g PolyDict with representation {(1, 1): 3, (1, 2): 3, (1, 5): -3, (2, 1): 4, (2, 3): 0} - sage: K = GF(2) - sage: f = PolyDict({(1, 1): K(1)}) - sage: f + f + sage: K = GF(2) # optional - sage.rings.finite_rings + sage: f = PolyDict({(1, 1): K(1)}) # optional - sage.rings.finite_rings + sage: f + f # optional - sage.rings.finite_rings PolyDict with representation {(1, 1): 0} """ cdef dict D = self.__repn @@ -1074,9 +1074,9 @@ cdef class PolyDict: EXAMPLES:: sage: from sage.rings.polynomial.polydict import PolyDict - sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! - sage: f = PolyDict({(2, 3): x}) - sage: f.scalar_rmult(y) + sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! # optional - sage.groups + sage: f = PolyDict({(2, 3): x}) # optional - sage.groups + sage: f.scalar_rmult(y) # optional - sage.groups PolyDict with representation {(2, 3): x*y} sage: f = PolyDict({(2,3):2, (1, 2): 3, (2, 1): 4}) sage: f.scalar_rmult(-2) @@ -1096,9 +1096,9 @@ cdef class PolyDict: EXAMPLES:: sage: from sage.rings.polynomial.polydict import PolyDict - sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! - sage: f = PolyDict({(2,3):x}) - sage: f.scalar_lmult(y) + sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! # optional - sage.groups + sage: f = PolyDict({(2,3):x}) # optional - sage.groups + sage: f.scalar_lmult(y) # optional - sage.groups PolyDict with representation {(2, 3): y*x} sage: f = PolyDict({(2,3):2, (1,2):3, (2,1):4}) sage: f.scalar_lmult(-2) @@ -1125,9 +1125,9 @@ cdef class PolyDict: EXAMPLES:: sage: from sage.rings.polynomial.polydict import ETuple, PolyDict - sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! - sage: f = PolyDict({(2, 3): x}) - sage: f.term_lmult(ETuple((1, 2)), y) + sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! # optional - sage.groups + sage: f = PolyDict({(2, 3): x}) # optional - sage.groups + sage: f.term_lmult(ETuple((1, 2)), y) # optional - sage.groups PolyDict with representation {(3, 5): y*x} sage: f = PolyDict({(2,3): 2, (1,2): 3, (2,1): 4}) @@ -1154,9 +1154,9 @@ cdef class PolyDict: EXAMPLES:: sage: from sage.rings.polynomial.polydict import ETuple, PolyDict - sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! - sage: f = PolyDict({(2, 3): x}) - sage: f.term_rmult(ETuple((1, 2)), y) + sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! # optional - sage.groups + sage: f = PolyDict({(2, 3): x}) # optional - sage.groups + sage: f.term_rmult(ETuple((1, 2)), y) # optional - sage.groups PolyDict with representation {(3, 5): x*y} sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4}) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 9000c358b26..1d3ac46e9d1 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -139,7 +139,7 @@ from sage.misc.cachefunc import cached_method cpdef is_Polynomial(f): """ - Return True if f is of type univariate polynomial. + Return ``True`` if ``f`` is of type univariate polynomial. This function is deprecated. @@ -152,29 +152,30 @@ cpdef is_Polynomial(f): sage: from sage.rings.polynomial.polynomial_element import is_Polynomial sage: R. = ZZ[] sage: is_Polynomial(x^3 + x + 1) - doctest:...: DeprecationWarning: the function is_Polynomial is deprecated; use isinstance(x, sage.structure.element.Polynomial) instead + doctest:...: DeprecationWarning: the function is_Polynomial is deprecated; + use isinstance(x, sage.structure.element.Polynomial) instead See https://github.com/sagemath/sage/issues/32709 for details. True sage: S. = R[] - sage: f = y^3 + x*y -3*x; f + sage: f = y^3 + x*y - 3*x; f y^3 + x*y - 3*x sage: is_Polynomial(f) True - However this function does not return True for genuine multivariate + However this function does not return ``True`` for genuine multivariate polynomial type objects or symbolic polynomials, since those are not of the same data type as univariate polynomials:: sage: R. = QQ[] - sage: f = y^3 + x*y -3*x; f + sage: f = y^3 + x*y - 3*x; f y^3 + x*y - 3*x sage: is_Polynomial(f) False - sage: var('x,y') + sage: var('x,y') # optional - sage.symbolic (x, y) - sage: f = y^3 + x*y -3*x; f + sage: f = y^3 + x*y - 3*x; f # optional - sage.symbolic y^3 + x*y - 3*x - sage: is_Polynomial(f) + sage: is_Polynomial(f) # optional - sage.symbolic False """ from sage.misc.superseded import deprecation @@ -296,12 +297,12 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: R = GF(2)['x']['y'] - sage: R([0,1]).is_zero() + sage: R = GF(2)['x']['y'] # optional - sage.rings.finite_rings + sage: R([0,1]).is_zero() # optional - sage.rings.finite_rings False - sage: R([0]).is_zero() + sage: R([0]).is_zero() # optional - sage.rings.finite_rings True - sage: R([-1]).is_zero() + sage: R([-1]).is_zero() # optional - sage.rings.finite_rings False """ return self.degree() < 0 @@ -313,7 +314,7 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: R. = QQ[] - sage: (x-3).is_one() + sage: (x - 3).is_one() False sage: R(1).is_one() True @@ -346,11 +347,11 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: x = polygen(GF(389)) - sage: plot(x^2 + 1, rgbcolor=(0,0,1)) + sage: x = polygen(GF(389)) # optional - sage.rings.finite_rings + sage: plot(x^2 + 1, rgbcolor=(0,0,1)) # optional - sage.rings.finite_rings sage.plot Graphics object consisting of 1 graphics primitive sage: x = polygen(QQ) - sage: plot(x^2 + 1, rgbcolor=(1,0,0)) + sage: plot(x^2 + 1, rgbcolor=(1,0,0)) # optional - sage.plot Graphics object consisting of 1 graphics primitive """ R = self.base_ring() @@ -412,9 +413,9 @@ cdef class Polynomial(CommutativePolynomial): def subs(self, *x, **kwds): r""" - Identical to self(\*x). + Identical to ``self(*x)``. - See the docstring for ``self.__call__``. + See the docstring for :meth:`__call__`. EXAMPLES:: @@ -486,12 +487,12 @@ cdef class Polynomial(CommutativePolynomial): We evaluate a polynomial over a quaternion algebra:: - sage: A. = QuaternionAlgebra(QQ, -1,-1) - sage: R. = PolynomialRing(A,sparse=True) - sage: f = i*j*w^5 - 13*i*w^2 + (i+j)*w + i - sage: f(i+j+1) + sage: A. = QuaternionAlgebra(QQ, -1, -1) # optional - sage.combinat sage.modules + sage: R. = PolynomialRing(A, sparse=True) # optional - sage.combinat sage.modules + sage: f = i*j*w^5 - 13*i*w^2 + (i+j)*w + i # optional - sage.combinat sage.modules + sage: f(i+j+1) # optional - sage.combinat sage.modules 24 + 26*i - 10*j - 25*k - sage: w = i+j+1; i*j*w^5 - 13*i*w^2 + (i+j)*w + i + sage: w = i+j+1; i*j*w^5 - 13*i*w^2 + (i+j)*w + i # optional - sage.combinat sage.modules 24 + 26*i - 10*j - 25*k The parent ring of the answer always "starts" with the parent of @@ -502,28 +503,28 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: f = R(2/3) - sage: a = matrix(ZZ,2) - sage: b = f(a); b + sage: a = matrix(ZZ, 2) # optional - sage.combinat sage.modules + sage: b = f(a); b # optional - sage.combinat sage.modules [2/3 0] [ 0 2/3] - sage: b.parent() + sage: b.parent() # optional - sage.combinat sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field sage: f = R(1) - sage: b = f(a); b + sage: b = f(a); b # optional - sage.combinat sage.modules [1 0] [0 1] - sage: b.parent() + sage: b.parent() # optional - sage.combinat sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field :: - sage: R. = GF(17)[] - sage: f = w^3 + 3*w +2 - sage: f(5) + sage: R. = GF(17)[] # optional - sage.rings.finite_rings + sage: f = w^3 + 3*w +2 # optional - sage.rings.finite_rings + sage: f(5) # optional - sage.rings.finite_rings 6 - sage: f(w=5) + sage: f(w=5) # optional - sage.rings.finite_rings 6 - sage: f(x=10) # x isn't mentioned + sage: f(x=10) # x isn't mentioned # optional - sage.rings.finite_rings w^3 + 3*w + 2 Nested polynomial ring elements can be called like multivariate @@ -572,7 +573,7 @@ cdef class Polynomial(CommutativePolynomial): The following results in an element of the symbolic ring. :: - sage: f(x=sqrt(2)) + sage: f(x=sqrt(2)) # optional - sage.symbolic y^2 + sqrt(2)*y + sqrt(2) :: @@ -598,7 +599,7 @@ cdef class Polynomial(CommutativePolynomial): 3 sage: parent(f(0)) Rational Field - sage: parent(f(Qp(5)(0))) + sage: parent(f(Qp(5)(0))) # optional - sage.rings.padics 5-adic Field with capped relative precision 20 TESTS: @@ -677,8 +678,8 @@ cdef class Polynomial(CommutativePolynomial): sage: one(1, 1.).parent() Real Field with 53 bits of precision - sage: zero = GF(2)['x'](0) - sage: zero(1.).parent() # should raise an error + sage: zero = GF(2)['x'](0) # optional - sage.rings.finite_rings + sage: zero(1.).parent() # should raise an error # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: @@ -707,37 +708,37 @@ cdef class Polynomial(CommutativePolynomial): These were drastically slower prior to :trac:`33165`:: - sage: R. = GF(31337)[] - sage: f = R(list(range(100,201))) - sage: g = R(list(range(1,1001))) - sage: S. = R.quotient(f) - sage: g(y) + sage: R. = GF(31337)[] # optional - sage.rings.finite_rings + sage: f = R(list(range(100, 201))) # optional - sage.rings.finite_rings + sage: g = R(list(range(1, 1001))) # optional - sage.rings.finite_rings + sage: S. = R.quotient(f) # optional - sage.rings.finite_rings + sage: g(y) # optional - sage.rings.finite_rings 22537*y^99 + 4686*y^98 + 13285*y^97 + 4216*y^96 + ... + 6389*y^3 + 30062*y^2 + 13755*y + 11875 :: - sage: T. = GF(31337)[] - sage: g(z) + sage: T. = GF(31337)[] # optional - sage.rings.finite_rings + sage: g(z) # optional - sage.rings.finite_rings 1000*z^999 + 999*z^998 + 998*z^997 + 997*z^996 + ... + 5*z^4 + 4*z^3 + 3*z^2 + 2*z + 1 - sage: g(z^2) + sage: g(z^2) # optional - sage.rings.finite_rings 1000*z^1998 + 999*z^1996 + 998*z^1994 + 997*z^1992 + ... + 5*z^8 + 4*z^6 + 3*z^4 + 2*z^2 + 1 - sage: g(T([0,1])) + sage: g(T([0, 1])) # optional - sage.rings.finite_rings 1000*z^999 + 999*z^998 + 998*z^997 + 997*z^996 + ... + 5*z^4 + 4*z^3 + 3*z^2 + 2*z + 1 - sage: g(T.zero()) + sage: g(T.zero()) # optional - sage.rings.finite_rings 1 - sage: g(T(2)) + sage: g(T(2)) # optional - sage.rings.finite_rings 23069 :: - sage: U. = GF(31337)[] - sage: g(u) + sage: U. = GF(31337)[] # optional - sage.rings.finite_rings + sage: g(u) # optional - sage.rings.finite_rings 1000*u^999 + 999*u^998 + 998*u^997 + 997*u^996 + ... + 5*u^4 + 4*u^3 + 3*u^2 + 2*u + 1 - sage: g(u*v^2) + sage: g(u*v^2) # optional - sage.rings.finite_rings 1000*u^999*v^1998 + 999*u^998*v^1996 + 998*u^997*v^1994 + ... + 4*u^3*v^6 + 3*u^2*v^4 + 2*u*v^2 + 1 - sage: g(U.zero()) + sage: g(U.zero()) # optional - sage.rings.finite_rings 1 - sage: g(U(2)) + sage: g(U(2)) # optional - sage.rings.finite_rings -8268 Sparse tests for :trac:`33165`:: @@ -924,7 +925,8 @@ cdef class Polynomial(CommutativePolynomial): sage: (1 + x + x^2/2 + x^3/6 + x^4/24 + x^5/120).compose_trunc(1 + x, 2) Traceback (most recent call last): ... - NotImplementedError: truncated composition is not implemented for this subclass of polynomials + NotImplementedError: truncated composition is not implemented + for this subclass of polynomials """ raise NotImplementedError("truncated composition is not implemented " "for this subclass of polynomials") @@ -1084,7 +1086,7 @@ cdef class Polynomial(CommutativePolynomial): """ EXAMPLES:: - sage: P = PolynomialRing(ZZ,'x')(0) + sage: P = PolynomialRing(ZZ, 'x')(0) sage: bool(P) False sage: P = PolynomialRing(ZZ, 'x')([1,2,3]) @@ -1188,21 +1190,21 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: K. = Qq(4) - sage: R. = K[] - sage: f = x - sage: hash(f) + sage: K. = Qq(4) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: f = x # optional - sage.rings.padics + sage: hash(f) # optional - sage.rings.padics Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' - sage: f._cache_key() + sage: f._cache_key() # optional - sage.rings.padics (Univariate Polynomial Ring in x over 2-adic Unramified Extension Field in u defined by x^2 + x + 1, 0, 1 + O(2^20)) sage: @cached_function ....: def foo(t): return t ....: - sage: foo(x) + sage: foo(x) # optional - sage.rings.padics (1 + O(2^20))*x """ return (self._parent,) + tuple(self) @@ -1239,9 +1241,9 @@ cdef class Polynomial(CommutativePolynomial): Verify that :trac:`16251` has been resolved, i.e., polynomials with unhashable coefficients are unhashable:: - sage: K. = Qq(9) - sage: R. = K[] - sage: hash(t) + sage: K. = Qq(9) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: hash(t) # optional - sage.rings.padics Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' @@ -1295,11 +1297,11 @@ cdef class Polynomial(CommutativePolynomial): sage: f(x^2 + 3) # indirect doctest 28 - sage: K. = NumberField(x^2 + 1) - sage: cc = K.hom([-i]) - sage: S. = K[] - sage: phi = S.hom([y^2], base_map=cc) - sage: phi(i*y) + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: cc = K.hom([-i]) # optional - sage.rings.number_field + sage: S. = K[] # optional - sage.rings.number_field + sage: phi = S.hom([y^2], base_map=cc) # optional - sage.rings.number_field + sage: phi(i*y) # optional - sage.rings.number_field -i*y^2 """ a = im_gens[0] @@ -1328,9 +1330,9 @@ cdef class Polynomial(CommutativePolynomial): sage: a = QQ['x'](1/5) sage: QQ(a) 1/5 - sage: AA(a) + sage: AA(a) # optional - sage.rings.number_field 1/5 - sage: QQbar(a) + sage: QQbar(a) # optional - sage.rings.number_field 1/5 sage: RDF(a) 0.2 @@ -1353,30 +1355,30 @@ cdef class Polynomial(CommutativePolynomial): sage: complex(a) (0.2+0j) - sage: b = AA['x'](AA(2/3).sqrt()) - sage: AA(b) + sage: b = AA['x'](AA(2/3).sqrt()) # optional - sage.rings.number_field + sage: AA(b) # optional - sage.rings.number_field 0.8164965809277260? - sage: RR(b) + sage: RR(b) # optional - sage.rings.number_field 0.816496580927726 - sage: RBF(b) + sage: RBF(b) # optional - sage.rings.number_field [0.816496580927726 +/- 2.44e-16] - sage: RIF(b) + sage: RIF(b) # optional - sage.rings.number_field 0.8164965809277260? - sage: float(b) + sage: float(b) # optional - sage.rings.number_field 0.816496580927726 - sage: c = QQbar['x'](QQbar(-2/5).sqrt()) - sage: QQbar(c) + sage: c = QQbar['x'](QQbar(-2/5).sqrt()) # optional - sage.rings.number_field + sage: QQbar(c) # optional - sage.rings.number_field 0.6324555320336758?*I - sage: CDF(c) + sage: CDF(c) # optional - sage.rings.number_field 0.6324555320336758*I - sage: CC(c) + sage: CC(c) # optional - sage.rings.number_field 0.632455532033676*I - sage: CBF(c) # abs tol 1e-16 + sage: CBF(c) # abs tol 1e-16 # optional - sage.rings.number_field [0.6324555320336759 +/- 3.38e-17]*I - sage: CIF(c) + sage: CIF(c) # optional - sage.rings.number_field 0.6324555320336758?*I - sage: complex(c) + sage: complex(c) # optional - sage.rings.number_field 0.6324555320336758j sage: K. = Frac(RR['x']) @@ -1388,8 +1390,8 @@ cdef class Polynomial(CommutativePolynomial): TypeError: cannot convert nonconstant polynomial sage: x = polygen(QQ) - sage: A. = NumberField(x^3 - 2) - sage: A(A['x'](u)) + sage: A. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: A(A['x'](u)) # optional - sage.rings.number_field u """ if self.degree() > 0: @@ -1431,8 +1433,8 @@ cdef class Polynomial(CommutativePolynomial): r""" EXAMPLES:: - sage: p = PolynomialRing(QQbar, 'x')(1+I) - sage: complex(p) + sage: p = PolynomialRing(QQbar, 'x')(1+I) # optional - sage.rings.number_field + sage: complex(p) # optional - sage.rings.number_field (1+1j) """ return self._scalar_conversion(complex) @@ -1457,20 +1459,20 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: f = x^3 + x - sage: g = f._symbolic_(SR); g + sage: g = f._symbolic_(SR); g # optional - sage.symbolic x^3 + x - sage: g(x=2) + sage: g(x=2) # optional - sage.symbolic 10 - sage: g = SR(f) - sage: g(x=2) + sage: g = SR(f) # optional - sage.symbolic + sage: g(x=2) # optional - sage.symbolic 10 The polynomial has to be over a field of characteristic 0 (see :trac:`24072`):: - sage: R. = GF(7)[] - sage: f = SR(2*w^3 + 1); f + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: f = SR(2*w^3 + 1); f # optional - sage.rings.finite_rings sage.symbolic Traceback (most recent call last): ... TypeError: positive characteristic not allowed in symbolic computations @@ -1500,7 +1502,8 @@ cdef class Polynomial(CommutativePolynomial): sage: f.inverse_of_unit() Traceback (most recent call last): ... - ArithmeticError: x - 90283 is not a unit in Univariate Polynomial Ring in x over Rational Field + ArithmeticError: x - 90283 is not a unit + in Univariate Polynomial Ring in x over Rational Field sage: f = R(-90283); g = f.inverse_of_unit(); g -1/90283 sage: parent(g) @@ -1526,10 +1529,11 @@ cdef class Polynomial(CommutativePolynomial): def inverse_mod(a, m): """ - Inverts the polynomial a with respect to m, or raises a ValueError - if no such inverse exists. The parameter m may be either a single - polynomial or an ideal (for consistency with inverse_mod in other - rings). + Invert the polynomial ``a`` with respect to ``m``, or raise a :class:`ValueError` + if no such inverse exists. + + The parameter ``m`` may be either a single polynomial or an ideal + (for consistency with :meth:`inverse_mod` in other rings). .. SEEALSO:: @@ -1544,9 +1548,9 @@ cdef class Polynomial(CommutativePolynomial): -1/2*t^2 - 1/2*t + 1/2 sage: f * (t^2 + 1) % (t^3 + 1) 1 - sage: f = t.inverse_mod((t+1)^7); f + sage: f = t.inverse_mod((t + 1)^7); f -t^6 - 7*t^5 - 21*t^4 - 35*t^3 - 35*t^2 - 21*t - 7 - sage: (f * t) + (t+1)^7 + sage: (f * t) + (t + 1)^7 1 sage: t.inverse_mod(S.ideal((t + 1)^7)) == f True @@ -1557,28 +1561,30 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = RDF[] sage: epsilon = RDF(1).ulp()*50 # Allow an error of up to 50 ulp - sage: f = inverse_mod(x^2 + 1, x^5 + x + 1); f # abs tol 1e-14 + sage: f = inverse_mod(x^2 + 1, x^5 + x + 1); f # abs tol 1e-14 # optional - sage.modules 0.4*x^4 - 0.2*x^3 - 0.4*x^2 + 0.2*x + 0.8 - sage: poly = f * (x^2 + 1) % (x^5 + x + 1) + sage: poly = f * (x^2 + 1) % (x^5 + x + 1) # optional - sage.modules sage: # Remove noisy zero terms: - sage: parent(poly)([ 0.0 if abs(c)<=epsilon else c for c in poly.coefficients(sparse=False) ]) + sage: parent(poly)([0.0 if abs(c) <= epsilon else c # optional - sage.modules + ....: for c in poly.coefficients(sparse=False)]) 1.0 - sage: f = inverse_mod(x^3 - x + 1, x - 2); f + sage: f = inverse_mod(x^3 - x + 1, x - 2); f # optional - sage.modules 0.14285714285714285 - sage: f * (x^3 - x + 1) % (x - 2) + sage: f * (x^3 - x + 1) % (x - 2) # optional - sage.modules 1.0 - sage: g = 5*x^3+x-7; m = x^4-12*x+13; f = inverse_mod(g, m); f + sage: g = 5*x^3 + x - 7; m = x^4 - 12*x + 13; f = inverse_mod(g, m); f # optional - sage.modules -0.0319636125...*x^3 - 0.0383269759...*x^2 - 0.0463050900...*x + 0.346479687... - sage: poly = f*g % m + sage: poly = f*g % m # optional - sage.modules sage: # Remove noisy zero terms: - sage: parent(poly)([ 0.0 if abs(c)<=epsilon else c for c in poly.coefficients(sparse=False) ]) # abs tol 1e-14 + sage: parent(poly)([0.0 if abs(c) <= epsilon else c # abs tol 1e-14 # optional - sage.modules + ....: for c in poly.coefficients(sparse=False)]) 1.0000000000000004 - ALGORITHM: Solve the system as + mt = 1, returning s as the inverse - of a mod m. + ALGORITHM: Solve the system `as + mt = 1`, returning `s` as the inverse + of `a` mod `m`. Uses the Euclidean algorithm for exact rings, and solves a linear - system for the coefficients of s and t for inexact rings (as the + system for the coefficients of `s` and `t` for inexact rings (as the Euclidean algorithm may not converge in that case). AUTHORS: @@ -1648,10 +1654,10 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: x = polygen(ZZ) - sage: s = (1+x).inverse_series_trunc(5) + sage: s = (1 + x).inverse_series_trunc(5) sage: s x^4 - x^3 + x^2 - x + 1 - sage: s * (1+x) + sage: s * (1 + x) x^5 + 1 Note that the constant coefficient needs to be a unit:: @@ -1678,20 +1684,20 @@ cdef class Polynomial(CommutativePolynomial): Even noncommutative ones:: - sage: M = MatrixSpace(ZZ,2) - sage: x = polygen(M) - sage: p = M([1,2,3,4])*x^3 + M([-1,0,0,1])*x^2 + M([1,3,-1,0])*x + M.one() - sage: q = p.inverse_series_trunc(5) - sage: (p*q).truncate(5) == M.one() + sage: M = MatrixSpace(ZZ, 2) # optional - sage.modules + sage: x = polygen(M) # optional - sage.modules + sage: p = M([1,2,3,4])*x^3 + M([-1,0,0,1])*x^2 + M([1,3,-1,0])*x + M.one() # optional - sage.modules + sage: q = p.inverse_series_trunc(5) # optional - sage.modules + sage: (p*q).truncate(5) == M.one() # optional - sage.modules True - sage: q = p.inverse_series_trunc(13) - sage: (p*q).truncate(13) == M.one() + sage: q = p.inverse_series_trunc(13) # optional - sage.modules + sage: (p*q).truncate(13) == M.one() # optional - sage.modules True TESTS:: sage: x = polygen(ZZ['a','b']) - sage: (x+1).inverse_series_trunc(0) + sage: (x + 1).inverse_series_trunc(0) Traceback (most recent call last): ... ValueError: the precision must be positive, got 0 @@ -1739,8 +1745,8 @@ cdef class Polynomial(CommutativePolynomial): sage: Pol. = CBF[] sage: (x + x^3/6 + x^5/120).revert_series(6) ([0.075000000000000 +/- ...e-17])*x^5 + ([-0.166666666666667 +/- ...e-16])*x^3 + x - sage: Pol. = SR[] - sage: x.revert_series(6) + sage: Pol. = SR[] # optional - sage.symbolic + sage: x.revert_series(6) # optional - sage.symbolic Traceback (most recent call last): ... NotImplementedError: only implemented for certain base rings @@ -1752,7 +1758,7 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: R. = ZZ[] - sage: (x - 4)*(x^2 - 8*x + 16) + sage: (x - 4) * (x^2 - 8*x + 16) x^3 - 12*x^2 + 48*x - 64 sage: C. = PowerSeriesRing(ZZ) sage: D. = PolynomialRing(C) @@ -1769,20 +1775,20 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: - sage: Pol. = MatrixSpace(ZZ, 2)[] - sage: a = matrix([[1,0],[0,0]]) - sage: b = matrix([[1,2],[3,4]]) - sage: list((a*x)*(b*x + 1)) + sage: Pol. = MatrixSpace(ZZ, 2)[] # optional - sage.modules + sage: a = matrix([[1,0], [0,0]]) # optional - sage.modules + sage: b = matrix([[1,2], [3,4]]) # optional - sage.modules + sage: list((a*x)*(b*x + 1)) # optional - sage.modules [ [0 0] [1 0] [1 2] [0 0], [0 0], [0 0] ] - sage: list((b*x + 1)*(a*x)) + sage: list((b*x + 1)*(a*x)) # optional - sage.modules [ [0 0] [1 0] [1 0] [0 0], [0 0], [3 0] ] - sage: list((a*x + 1)*(b*x)) + sage: list((a*x + 1)*(b*x)) # optional - sage.modules [ [0 0] [1 2] [1 2] [0 0], [3 4], [0 0] @@ -1908,17 +1914,17 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: x = polygen(QQ) - sage: p = 37 * (x-1)^3 * (x-2)^3 * (x-1/3)^7 * (x-3/7) + sage: p = 37 * (x - 1)^3 * (x - 2)^3 * (x - 1/3)^7 * (x - 3/7) sage: p.squarefree_decomposition() (37*x - 111/7) * (x^2 - 3*x + 2)^3 * (x - 1/3)^7 - sage: p = 37 * (x-2/3)^2 + sage: p = 37 * (x - 2/3)^2 sage: p.squarefree_decomposition() (37) * (x - 2/3)^2 - sage: x = polygen(GF(3)) - sage: x.squarefree_decomposition() + sage: x = polygen(GF(3)) # optional - sage.rings.finite_rings + sage: x.squarefree_decomposition() # optional - sage.rings.finite_rings x - sage: f = QQbar['x'](1) - sage: f.squarefree_decomposition() + sage: f = QQbar['x'](1) # optional - sage.rings.number_field + sage: f.squarefree_decomposition() # optional - sage.rings.number_field 1 """ @@ -1956,7 +1962,7 @@ cdef class Polynomial(CommutativePolynomial): sage: (x^4 + 2*x^3 - x^2 - 2*x + 1).is_square(root=True) (True, x^2 + x - 1) - sage: f = 12*(x+1)^2 * (x+3)^2 + sage: f = 12 * (x + 1)^2 * (x + 3)^2 sage: f.is_square() False sage: f.is_square(root=True) @@ -1968,7 +1974,7 @@ cdef class Polynomial(CommutativePolynomial): (True, 2*x^2 + 8*x + 6) sage: S. = PolynomialRing(RR) - sage: g = 12*(y+1)^2 * (y+3)^2 + sage: g = 12 * (y + 1)^2 * (y + 3)^2 sage: g.is_square() True @@ -2021,80 +2027,94 @@ cdef class Polynomial(CommutativePolynomial): contained within the given ring. - ``assume_squarefree`` (bool) -- Used for polynomials over - finite fields. If True, this polynomial is assumed to be + finite fields. If ``True``, this polynomial is assumed to be squarefree. EXAMPLES:: - sage: R. = GF(11)[] - sage: f = 7*x^7 + 8*x^6 + 4*x^5 + x^4 + 6*x^3 + 10*x^2 + 8*x + 5 - sage: f.any_root() + sage: R. = GF(11)[] # optional - sage.rings.finite_rings + sage: f = 7*x^7 + 8*x^6 + 4*x^5 + x^4 + 6*x^3 + 10*x^2 + 8*x + 5 # optional - sage.rings.finite_rings + sage: f.any_root() # optional - sage.rings.finite_rings 2 - sage: f.factor() + sage: f.factor() # optional - sage.rings.finite_rings (7) * (x + 9) * (x^6 + 10*x^4 + 6*x^3 + 5*x^2 + 2*x + 2) - sage: f = x^6 + 10*x^4 + 6*x^3 + 5*x^2 + 2*x + 2 - sage: f.any_root(GF(11^6, 'a')) + sage: f = x^6 + 10*x^4 + 6*x^3 + 5*x^2 + 2*x + 2 # optional - sage.rings.finite_rings + sage: f.any_root(GF(11^6, 'a')) # optional - sage.rings.finite_rings a^5 + a^4 + 7*a^3 + 2*a^2 + 10*a - sage: sorted(f.roots(GF(11^6, 'a'))) - [(10*a^5 + 2*a^4 + 8*a^3 + 9*a^2 + a, 1), (a^5 + a^4 + 7*a^3 + 2*a^2 + 10*a, 1), (9*a^5 + 5*a^4 + 10*a^3 + 8*a^2 + 3*a + 1, 1), (2*a^5 + 8*a^4 + 3*a^3 + 6*a + 2, 1), (a^5 + 3*a^4 + 8*a^3 + 2*a^2 + 3*a + 4, 1), (10*a^5 + 3*a^4 + 8*a^3 + a^2 + 10*a + 4, 1)] - sage: f.any_root(GF(11^6, 'a')) + sage: sorted(f.roots(GF(11^6, 'a'))) # optional - sage.rings.finite_rings + [(10*a^5 + 2*a^4 + 8*a^3 + 9*a^2 + a, 1), + (a^5 + a^4 + 7*a^3 + 2*a^2 + 10*a, 1), + (9*a^5 + 5*a^4 + 10*a^3 + 8*a^2 + 3*a + 1, 1), + (2*a^5 + 8*a^4 + 3*a^3 + 6*a + 2, 1), + (a^5 + 3*a^4 + 8*a^3 + 2*a^2 + 3*a + 4, 1), + (10*a^5 + 3*a^4 + 8*a^3 + a^2 + 10*a + 4, 1)] + sage: f.any_root(GF(11^6, 'a')) # optional - sage.rings.finite_rings a^5 + a^4 + 7*a^3 + 2*a^2 + 10*a - sage: g = (x-1)*(x^2 + 3*x + 9) * (x^5 + 5*x^4 + 8*x^3 + 5*x^2 + 3*x + 5) - sage: g.any_root(ring=GF(11^10, 'b'), degree=1) + sage: g = (x-1)*(x^2 + 3*x + 9) * (x^5 + 5*x^4 + 8*x^3 + 5*x^2 + 3*x + 5) # optional - sage.rings.finite_rings + sage: g.any_root(ring=GF(11^10, 'b'), degree=1) # optional - sage.rings.finite_rings 1 - sage: g.any_root(ring=GF(11^10, 'b'), degree=2) + sage: g.any_root(ring=GF(11^10, 'b'), degree=2) # optional - sage.rings.finite_rings 5*b^9 + 4*b^7 + 4*b^6 + 8*b^5 + 10*b^2 + 10*b + 5 - sage: g.any_root(ring=GF(11^10, 'b'), degree=5) + sage: g.any_root(ring=GF(11^10, 'b'), degree=5) # optional - sage.rings.finite_rings 5*b^9 + b^8 + 3*b^7 + 2*b^6 + b^5 + 4*b^4 + 3*b^3 + 7*b^2 + 10*b TESTS:: - sage: R. = GF(5)[] - sage: K. = GF(5^12) - sage: for _ in range(40): + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: K. = GF(5^12) # optional - sage.rings.finite_rings + sage: for _ in range(40): # optional - sage.rings.finite_rings ....: f = R.random_element(degree=4) ....: assert f(f.any_root(K)) == 0 Check that our Cantor-Zassenhaus implementation does not loop over finite fields of even characteristic (see :trac:`16162`):: - sage: K. = GF(2**8) - sage: x = polygen(K) - sage: r = (x**2+x+1).any_root() # used to loop - sage: r**2 + r + sage: K. = GF(2**8) # optional - sage.rings.finite_rings + sage: x = polygen(K) # optional - sage.rings.finite_rings + sage: r = (x**2+x+1).any_root() # used to loop # optional - sage.rings.finite_rings + sage: r**2 + r # optional - sage.rings.finite_rings 1 - sage: (x**2+a+1).any_root() + sage: (x**2+a+1).any_root() # optional - sage.rings.finite_rings a^7 + a^2 Also check that such computations can be interrupted:: - sage: K. = GF(2^8) - sage: x = polygen(K) - sage: pol = x^1000000 + x + a - sage: alarm(0.5); pol.any_root() + sage: K. = GF(2^8) # optional - sage.rings.finite_rings + sage: x = polygen(K) # optional - sage.rings.finite_rings + sage: pol = x^1000000 + x + a # optional - sage.rings.finite_rings + sage: alarm(0.5); pol.any_root() # optional - sage.rings.finite_rings Traceback (most recent call last): ... AlarmInterrupt Check root computation over large finite fields:: - sage: K. = GF(2**50) - sage: x = polygen(K) - sage: (x**10+x+a).any_root() - a^49 + a^47 + a^44 + a^42 + a^41 + a^39 + a^38 + a^37 + a^36 + a^34 + a^33 + a^29 + a^27 + a^26 + a^25 + a^23 + a^18 + a^13 + a^7 + a^5 + a^4 + a^3 + a^2 + a - sage: K. = GF(2**150) - sage: x = polygen(K) - sage: (x**10+x+a).any_root() - a^149 + a^148 + a^146 + a^144 + a^143 + a^140 + a^138 + a^136 + a^134 + a^132 + a^131 + a^130 + a^129 + a^127 + a^123 + a^120 + a^118 + a^114 + a^113 + a^112 + a^111 + a^108 + a^104 + a^103 + a^102 + a^99 + a^98 + a^94 + a^91 + a^90 + a^88 + a^79 + a^78 + a^75 + a^73 + a^72 + a^67 + a^65 + a^64 + a^63 + a^62 + a^61 + a^59 + a^57 + a^52 + a^50 + a^48 + a^47 + a^46 + a^45 + a^43 + a^41 + a^39 + a^37 + a^34 + a^31 + a^29 + a^27 + a^25 + a^23 + a^22 + a^20 + a^18 + a^16 + a^14 + a^11 + a^10 + a^8 + a^6 + a^5 + a^4 + a + 1 + sage: K. = GF(2**50) # optional - sage.rings.finite_rings + sage: x = polygen(K) # optional - sage.rings.finite_rings + sage: (x**10+x+a).any_root() # optional - sage.rings.finite_rings + a^49 + a^47 + a^44 + a^42 + a^41 + a^39 + a^38 + a^37 + a^36 + + a^34 + a^33 + a^29 + a^27 + a^26 + a^25 + a^23 + a^18 + + a^13 + a^7 + a^5 + a^4 + a^3 + a^2 + a + sage: K. = GF(2**150) # optional - sage.rings.finite_rings + sage: x = polygen(K) # optional - sage.rings.finite_rings + sage: (x**10+x+a).any_root() # optional - sage.rings.finite_rings + a^149 + a^148 + a^146 + a^144 + a^143 + a^140 + a^138 + a^136 + a^134 + + a^132 + a^131 + a^130 + a^129 + a^127 + a^123 + a^120 + a^118 + a^114 + + a^113 + a^112 + a^111 + a^108 + a^104 + a^103 + a^102 + a^99 + a^98 + + a^94 + a^91 + a^90 + a^88 + a^79 + a^78 + a^75 + a^73 + a^72 + a^67 + + a^65 + a^64 + a^63 + a^62 + a^61 + a^59 + a^57 + a^52 + a^50 + a^48 + + a^47 + a^46 + a^45 + a^43 + a^41 + a^39 + a^37 + a^34 + a^31 + a^29 + + a^27 + a^25 + a^23 + a^22 + a^20 + a^18 + a^16 + a^14 + a^11 + a^10 + + a^8 + a^6 + a^5 + a^4 + a + 1 Check that :trac:`21998` has been resolved:: - sage: K. = GF(2^4) - sage: R. = K[] - sage: f = x^2 + x + a^2 + a - sage: r = f.any_root() - sage: r^2 + r + sage: K. = GF(2^4) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: f = x^2 + x + a^2 + a # optional - sage.rings.finite_rings + sage: r = f.any_root() # optional - sage.rings.finite_rings + sage: r^2 + r # optional - sage.rings.finite_rings a^2 + a """ if self.base_ring().is_finite() and self.base_ring().is_field(): @@ -2288,9 +2308,9 @@ cdef class Polynomial(CommutativePolynomial): :: - sage: R. = PolynomialRing(GF(5^2, 'a'), 'x') - sage: f = x^3 + 4*x - sage: f / (x - 1) + sage: R. = PolynomialRing(GF(5^2, 'a'), 'x') # optional - sage.rings.finite_rings + sage: f = x^3 + 4*x # optional - sage.rings.finite_rings + sage: f / (x - 1) # optional - sage.rings.finite_rings x^2 + x Be careful about coercions (this used to be broken):: @@ -2305,21 +2325,21 @@ cdef class Polynomial(CommutativePolynomial): Check that :trac:`12217` is fixed:: - sage: P. = GF(5)[] - sage: x/0 + sage: P. = GF(5)[] # optional - sage.rings.finite_rings + sage: x/0 # optional - sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: inverse of Mod(0, 5) does not exist - sage: P. = GF(25, 'a')[] - sage: x/5 + sage: P. = GF(25, 'a')[] # optional - sage.rings.finite_rings + sage: x/5 # optional - sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: division by zero in finite field Check that :trac:`23611` is fixed:: - sage: int(1) / x + sage: int(1) / x # optional - sage.rings.finite_rings 1/x """ # Same parents => bypass coercion @@ -2352,10 +2372,10 @@ cdef class Polynomial(CommutativePolynomial): sage: f^3 x^3 - 3*x^2 + 3*x - 1 - sage: R = PolynomialRing(GF(2), 'x') - sage: f = R(x^9 + x^7 + x^6 + x^5 + x^4 + x^2 + x) - sage: h = R(x^10 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + 1) - sage: pow(f, 2, h) + sage: R = PolynomialRing(GF(2), 'x') # optional - sage.rings.finite_rings + sage: f = R(x^9 + x^7 + x^6 + x^5 + x^4 + x^2 + x) # optional - sage.rings.finite_rings + sage: h = R(x^10 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + 1) # optional - sage.rings.finite_rings + sage: pow(f, 2, h) # optional - sage.rings.finite_rings x^9 + x^8 + x^7 + x^5 + x^3 TESTS:: @@ -2382,46 +2402,46 @@ cdef class Polynomial(CommutativePolynomial): :: - sage: k = GF(5) - sage: D. = k[] - sage: l. = k.extension(x^2 + 2) - sage: R. = l[] - sage: f = t^4 + (2*x - 1)*t^3 + (2*x + 1)*t^2 + 3 - sage: h = t^4 - x*t^3 + (3*x + 1)*t^2 + 2*t + 2*x - 1 - sage: pow(f, 2, h) + sage: k = GF(5) # optional - sage.rings.finite_rings + sage: D. = k[] # optional - sage.rings.finite_rings + sage: l. = k.extension(x^2 + 2) # optional - sage.rings.finite_rings + sage: R. = l[] # optional - sage.rings.finite_rings + sage: f = t^4 + (2*x - 1)*t^3 + (2*x + 1)*t^2 + 3 # optional - sage.rings.finite_rings + sage: h = t^4 - x*t^3 + (3*x + 1)*t^2 + 2*t + 2*x - 1 # optional - sage.rings.finite_rings + sage: pow(f, 2, h) # optional - sage.rings.finite_rings 3*t^3 + (2*x + 3)*t^2 + (2*x + 2)*t + 2*x + 2 - sage: pow(f, 10**7, h) + sage: pow(f, 10**7, h) # optional - sage.rings.finite_rings 4*x*t^3 + 2*x*t^2 + 4*x*t + 4 Check that :trac:`18457` is fixed:: - sage: R. = PolynomialRing(GF(5), sparse=True) - sage: (1+x)^(5^10) # used to hang forever + sage: R. = PolynomialRing(GF(5), sparse=True) # optional - sage.rings.finite_rings + sage: (1+x)^(5^10) # used to hang forever # optional - sage.rings.finite_rings x^9765625 + 1 - sage: S. = GF(3)[] - sage: R1. = PolynomialRing(S, sparse=True) - sage: (1+x+t)^(3^10) + sage: S. = GF(3)[] # optional - sage.rings.finite_rings + sage: R1. = PolynomialRing(S, sparse=True) # optional - sage.rings.finite_rings + sage: (1+x+t)^(3^10) # optional - sage.rings.finite_rings x^59049 + t^59049 + 1 - sage: R2. = PolynomialRing(S, sparse=False) - sage: (1+x+t)^(3^10) + sage: R2. = PolynomialRing(S, sparse=False) # optional - sage.rings.finite_rings + sage: (1+x+t)^(3^10) # optional - sage.rings.finite_rings x^59049 + t^59049 + 1 Check that the algorithm used is indeed correct:: sage: from sage.arith.power import generic_power - sage: R1 = PolynomialRing(GF(8,'a'), 'x') - sage: R2 = PolynomialRing(GF(9,'b'), 'x', sparse=True) - sage: R3 = PolynomialRing(R2, 'y') - sage: R4 = PolynomialRing(R1, 'y', sparse=True) - sage: for d in range(20,40): # long time + sage: R1 = PolynomialRing(GF(8,'a'), 'x') # optional - sage.rings.finite_rings + sage: R2 = PolynomialRing(GF(9,'b'), 'x', sparse=True) # optional - sage.rings.finite_rings + sage: R3 = PolynomialRing(R2, 'y') # optional - sage.rings.finite_rings + sage: R4 = PolynomialRing(R1, 'y', sparse=True) # optional - sage.rings.finite_rings + sage: for d in range(20,40): # long time # optional - sage.rings.finite_rings ....: for R in [R1, R2, R3, R3]: ....: a = R.random_element() ....: assert a^d == generic_power(a, d) Test the powering modulo ``x^n`` (calling :meth:`power_trunc`):: - sage: R. = GF(3)[] - sage: pow(x + 1, 51, x^7) + sage: R. = GF(3)[] # optional - sage.rings.finite_rings + sage: pow(x + 1, 51, x^7) # optional - sage.rings.finite_rings x^6 + 2*x^3 + 1 sage: S. = QQ[] @@ -2432,10 +2452,10 @@ cdef class Polynomial(CommutativePolynomial): Check that fallback method is used when it is not possible to compute the characteristic of the base ring (:trac:`24308`):: - sage: kk. = GF(2)[] - sage: k. = kk.quo(a^2+a+1) - sage: K. = k[] - sage: (T*y)^21 + sage: kk. = GF(2)[] # optional - sage.rings.finite_rings + sage: k. = kk.quo(a^2+a+1) # optional - sage.rings.finite_rings + sage: K. = k[] # optional - sage.rings.finite_rings + sage: (T*y)^21 # optional - sage.rings.finite_rings T^21 """ if not isinstance(left, Polynomial): @@ -2522,25 +2542,23 @@ cdef class Polynomial(CommutativePolynomial): -1800*x^7 + 1590*x^6 - 1052*x^5 + 530*x^4 - 200*x^3 + 55*x^2 - 10*x + 1 sage: S. = R[] - sage: (x+y).power_trunc(5,5) + sage: (x + y).power_trunc(5,5) 5*x*y^4 + 10*x^2*y^3 + 10*x^3*y^2 + 5*x^4*y + x^5 - sage: ((x+y)^5).truncate(5) + sage: ((x + y)^5).truncate(5) 5*x*y^4 + 10*x^2*y^3 + 10*x^3*y^2 + 5*x^4*y + x^5 - sage: R. = GF(3)[] - sage: p = x^2 - x + 1 - sage: q = p.power_trunc(80, 20) - sage: q + sage: R. = GF(3)[] # optional - sage.rings.finite_rings + sage: p = x^2 - x + 1 # optional - sage.rings.finite_rings + sage: q = p.power_trunc(80, 20); q # optional - sage.rings.finite_rings x^19 + x^18 + ... + 2*x^4 + 2*x^3 + x + 1 - sage: (p^80).truncate(20) == q + sage: (p^80).truncate(20) == q # optional - sage.rings.finite_rings True - sage: R. = GF(7)[] - sage: p = (x^2 + x + 1).power_trunc(2^100, 100) - sage: p + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: p = (x^2 + x + 1).power_trunc(2^100, 100); p # optional - sage.rings.finite_rings 2*x^99 + x^98 + x^95 + 2*x^94 + ... + 3*x^2 + 2*x + 1 - sage: for i in range(100): + sage: for i in range(100): # optional - sage.rings.finite_rings ....: q1 = (x^2 + x + 1).power_trunc(2^100 + i, 100) ....: q2 = p * (x^2 + x + 1).power_trunc(i, 100) ....: q2 = q2.truncate(100) @@ -2630,10 +2648,10 @@ cdef class Polynomial(CommutativePolynomial): elements in the Sage library yet that do not implement ``__bool__``, so we have to create one artificially.):: - sage: class PatchedAlgebraicNumber(sage.rings.qqbar.AlgebraicNumber): + sage: class PatchedAlgebraicNumber(sage.rings.qqbar.AlgebraicNumber): # optional - sage.rings.number_field ....: def __bool__(self): raise NotImplementedError() - sage: R. = QQbar[] - sage: R([PatchedAlgebraicNumber(0), 1]) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: R([PatchedAlgebraicNumber(0), 1]) # optional - sage.rings.number_field x + 0 """ if name is None: @@ -2708,10 +2726,10 @@ cdef class Polynomial(CommutativePolynomial): :: - sage: C3. = CyclotomicField(3) - sage: R. = C3[] - sage: f = X^3 - omega*X - sage: latex(f) + sage: C3. = CyclotomicField(3) # optional - sage.rings.number_field + sage: R. = C3[] # optional - sage.rings.number_field + sage: f = X^3 - omega*X # optional - sage.rings.number_field + sage: latex(f) # optional - sage.rings.number_field X^{3} - \omega X sage: R. = RDF[] sage: latex(x+2) @@ -2724,9 +2742,9 @@ cdef class Polynomial(CommutativePolynomial): The following illustrates a (non-intentional) superfluity of parentheses - sage: K.=QuadraticField(-1) - sage: R.=K[] - sage: latex(I*x^2-I*x) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: latex(I*x^2 - I*x) # optional - sage.rings.number_field \left(\sqrt{-1}\right) x^{2} + \left(-\sqrt{-1}\right) x """ s = " " @@ -2799,7 +2817,7 @@ cdef class Polynomial(CommutativePolynomial): # Verified R. = RR[] 3.1415926535897931*x - sage: sage_input(polygen(GF(7)) + 12, verify=True) + sage: sage_input(polygen(GF(7)) + 12, verify=True) # optional - sage.rings.finite_rings # Verified R. = GF(7)[] x + 5 @@ -2855,7 +2873,7 @@ cdef class Polynomial(CommutativePolynomial): cpdef _floordiv_(self, right): r""" - Quotient of division of self by other. This is denoted //. + Quotient of division of ``self`` by ``other``. This is denoted //. If self = quotient \* right + remainder, this function returns quotient. @@ -2878,7 +2896,7 @@ cdef class Polynomial(CommutativePolynomial): def __mod__(self, other): """ - Remainder of division of self by other. + Remainder of division of ``self`` by ``other``. EXAMPLES:: @@ -2893,7 +2911,7 @@ cdef class Polynomial(CommutativePolynomial): def mod(self, other): """ - Remainder of division of self by other. + Remainder of division of ``self`` by ``other``. EXAMPLES:: @@ -2908,14 +2926,14 @@ cdef class Polynomial(CommutativePolynomial): Check the problem reported at :trac:`12529` is fixed:: sage: gens = 'y a0 a1 a2 b0 b1 b2 c1 c2 d0 d1 d2 d3 d4 d5 d6 d7'.split() - sage: R = PolynomialRing(GF(8), 17, gens) - sage: R.inject_variables(verbose=False) - sage: A, B, C = a0 + a1*y + a2*y^2, b0 + b1*y + b2*y^2, c1*y + c2*y^2 - sage: D = d0 + d1*y + d2*y^2 + d3*y^3 + d4*y^4 + d5*y^5 + d6*y^6 + d7*y^7 - sage: F = D.subs({y: B}) - sage: G = A.subs({y: F}) + C - sage: g = G.mod(y^8 + y) - sage: g.degree(y) + sage: R = PolynomialRing(GF(8), 17, gens) # optional - sage.rings.finite_rings + sage: R.inject_variables(verbose=False) # optional - sage.rings.finite_rings + sage: A, B, C = a0 + a1*y + a2*y^2, b0 + b1*y + b2*y^2, c1*y + c2*y^2 # optional - sage.rings.finite_rings + sage: D = d0 + d1*y + d2*y^2 + d3*y^3 + d4*y^4 + d5*y^5 + d6*y^6 + d7*y^7 # optional - sage.rings.finite_rings + sage: F = D.subs({y: B}) # optional - sage.rings.finite_rings + sage: G = A.subs({y: F}) + C # optional - sage.rings.finite_rings + sage: g = G.mod(y^8 + y) # optional - sage.rings.finite_rings + sage: g.degree(y) # optional - sage.rings.finite_rings 7 """ return self % other @@ -2938,7 +2956,7 @@ cdef class Polynomial(CommutativePolynomial): cpdef _mul_generic(self, right): """ - Compute the product of self and right using the classical quadratic + Compute the product of ``self`` and ``right`` using the classical quadratic algorithm. This method is the default for inexact rings. For two polynomials of degree n and m this method needs @@ -2954,21 +2972,21 @@ cdef class Polynomial(CommutativePolynomial): Show the product in the symbolic ring:: - sage: L = SR['x'] - sage: var('a0,a1,b0,b1') + sage: L = SR['x'] # optional - sage.symbolic + sage: var('a0,a1,b0,b1') # optional - sage.symbolic (a0, a1, b0, b1) - sage: L([a0,a1])._mul_generic(L([b0,b1])) + sage: L([a0, a1])._mul_generic(L([b0, b1])) # optional - sage.symbolic a1*b1*x^2 + (a1*b0 + a0*b1)*x + a0*b0 A non-commutative example:: - sage: A. = QuaternionAlgebra(QQ, -1,-1) - sage: R. = PolynomialRing(A) - sage: f = i*w + j - sage: g = k*w + 1 - sage: f._mul_generic(g) + sage: A. = QuaternionAlgebra(QQ, -1,-1) # optional - sage.combinat sage.modules + sage: R. = PolynomialRing(A) # optional - sage.combinat sage.modules + sage: f = i*w + j # optional - sage.combinat sage.modules + sage: g = k*w + 1 # optional - sage.combinat sage.modules + sage: f._mul_generic(g) # optional - sage.combinat sage.modules -j*w^2 + 2*i*w + j - sage: g._mul_generic(f) + sage: g._mul_generic(f) # optional - sage.combinat sage.modules j*w^2 + j @@ -3098,7 +3116,7 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - ``self`` - Polynomial - - ``right`` - Polynomial (over same base ring as self) + - ``right`` - Polynomial (over same base ring as ``self``) - ``K_threshold`` - (optional) Integer. A threshold to fall back to schoolbook algorithm. In the recursion, if one of the polynomials is of degree less that K_threshold then the classic quadratic @@ -3172,23 +3190,23 @@ cdef class Polynomial(CommutativePolynomial): Show the product in the symbolic ring:: - sage: L = SR['x'] - sage: var('a0,a1,b0,b1') + sage: L = SR['x'] # optional - sage.symbolic + sage: var('a0,a1,b0,b1') # optional - sage.symbolic (a0, a1, b0, b1) - sage: L([a0,a1])._mul_karatsuba(L([b0,b1]),0) + sage: L([a0, a1])._mul_karatsuba(L([b0, b1]), 0) # optional - sage.symbolic a1*b1*x^2 + ((a0 + a1)*(b0 + b1) - a0*b0 - a1*b1)*x + a0*b0 - sage: L([a0,a1])._mul_karatsuba(L([b0,b1]),2) + sage: L([a0, a1])._mul_karatsuba(L([b0, b1]), 2) # optional - sage.symbolic a1*b1*x^2 + (a1*b0 + a0*b1)*x + a0*b0 A noncommutative example:: - sage: A. = QuaternionAlgebra(QQ, -1,-1) - sage: R. = PolynomialRing(A) - sage: f = i*w + j - sage: g = k*w + 1 - sage: f._mul_karatsuba(g,0) + sage: A. = QuaternionAlgebra(QQ, -1,-1) # optional - sage.combinat sage.modules + sage: R. = PolynomialRing(A) # optional - sage.combinat sage.modules + sage: f = i*w + j # optional - sage.combinat sage.modules + sage: g = k*w + 1 # optional - sage.combinat sage.modules + sage: f._mul_karatsuba(g,0) # optional - sage.combinat sage.modules -j*w^2 + 2*i*w + j - sage: g._mul_karatsuba(f,0) + sage: g._mul_karatsuba(f,0) # optional - sage.combinat sage.modules j*w^2 + j TESTS:: @@ -3214,28 +3232,28 @@ cdef class Polynomial(CommutativePolynomial): Random tests for noncommutative rings:: - sage: A. = QuaternionAlgebra(QQ, -1,-1) - sage: R. = PolynomialRing(A) - sage: f = R.random_element(randint(10,100)) - sage: g = R.random_element(randint(10,100)) - sage: f._mul_generic(g) == f._mul_karatsuba(g,0) + sage: A. = QuaternionAlgebra(QQ, -1,-1) # optional - sage.combinat sage.modules + sage: R. = PolynomialRing(A) # optional - sage.combinat sage.modules + sage: f = R.random_element(randint(10,100)) # optional - sage.combinat sage.modules + sage: g = R.random_element(randint(10,100)) # optional - sage.combinat sage.modules + sage: f._mul_generic(g) == f._mul_karatsuba(g,0) # optional - sage.combinat sage.modules True - sage: f._mul_generic(g) == f._mul_karatsuba(g,16) + sage: f._mul_generic(g) == f._mul_karatsuba(g,16) # optional - sage.combinat sage.modules True - sage: g = R.random_element(0) - sage: f._mul_karatsuba(g,0) == f._mul_generic(g) + sage: g = R.random_element(0) # optional - sage.combinat sage.modules + sage: f._mul_karatsuba(g,0) == f._mul_generic(g) # optional - sage.combinat sage.modules True - sage: g._mul_karatsuba(f,0) == g._mul_generic(f) + sage: g._mul_karatsuba(f,0) == g._mul_generic(f) # optional - sage.combinat sage.modules True Polynomials over matrices:: - sage: K = PolynomialRing(MatrixSpace(QQ,2),'x') - sage: f = K.random_element(randint(5,10)) - sage: g = K.random_element(randint(5,10)) - sage: h1 = f._mul_generic(g) - sage: h2 = f._mul_karatsuba(g,randint(0,10)) - sage: h1 == h2 + sage: K = PolynomialRing(MatrixSpace(QQ, 2), 'x') # optional - sage.modules + sage: f = K.random_element(randint(5, 10)) # optional - sage.modules + sage: g = K.random_element(randint(5, 10)) # optional - sage.modules + sage: h1 = f._mul_generic(g) # optional - sage.modules + sage: h2 = f._mul_karatsuba(g,randint(0, 10)) # optional - sage.modules + sage: h1 == h2 # optional - sage.modules True """ if self.is_zero(): @@ -3284,32 +3302,32 @@ cdef class Polynomial(CommutativePolynomial): def base_ring(self): """ - Return the base ring of the parent of self. + Return the base ring of the parent of ``self``. EXAMPLES:: sage: R. = ZZ[] sage: x.base_ring() Integer Ring - sage: (2*x+3).base_ring() + sage: (2*x + 3).base_ring() Integer Ring """ return self._parent.base_ring() cpdef base_extend(self, R): """ - Return a copy of this polynomial but with coefficients in R, if - there is a natural map from coefficient ring of self to R. + Return a copy of this polynomial but with coefficients in ``R``, if + there is a natural map from the coefficient ring of ``self`` to ``R``. EXAMPLES:: sage: R. = QQ[] sage: f = x^3 - 17*x + 3 - sage: f.base_extend(GF(7)) + sage: f.base_extend(GF(7)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no such base extension - sage: f.change_ring(GF(7)) + sage: f.change_ring(GF(7)) # optional - sage.rings.finite_rings x^3 + 4*x + 3 """ S = self._parent.base_extend(R) @@ -3342,17 +3360,17 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: K. = CyclotomicField(3) - sage: f = K.defining_polynomial() - sage: f.change_ring(GF(7)) + sage: K. = CyclotomicField(3) # optional - sage.rings.number_field + sage: f = K.defining_polynomial() # optional - sage.rings.number_field + sage: f.change_ring(GF(7)) # optional - sage.rings.finite_rings # optional - sage.rings.number_field x^2 + x + 1 :: - sage: K. = CyclotomicField(3) - sage: R. = K[] - sage: f = x^2 + z - sage: f.change_ring(K.embeddings(CC)[1]) + sage: K. = CyclotomicField(3) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: f = x^2 + z # optional - sage.rings.number_field + sage: f.change_ring(K.embeddings(CC)[1]) # optional - sage.rings.number_field x^2 - 0.500000000000000 - 0.866025403784438*I :: @@ -3367,17 +3385,17 @@ cdef class Polynomial(CommutativePolynomial): Check that :trac:`25022` is fixed:: sage: K. = ZZ[] - sage: x.change_ring(SR) == SR['x'].gen() + sage: x.change_ring(SR) == SR['x'].gen() # optional - sage.symbolic True sage: x.change_ring(ZZ['x']) == ZZ['x']['x'].gen() True Check that :trac:`28541` is fixed:: - sage: F. = GF(7^2) - sage: S. = F[] - sage: P = x^2 + a*x + a^2 - sage: P.change_ring(F.frobenius_endomorphism()) + sage: F. = GF(7^2) # optional - sage.rings.finite_rings + sage: S. = F[] # optional - sage.rings.finite_rings + sage: P = x^2 + a*x + a^2 # optional - sage.rings.finite_rings + sage: P.change_ring(F.frobenius_endomorphism()) # optional - sage.rings.finite_rings x^2 + (6*a + 1)*x + 6*a + 5 """ if isinstance(R, Map): @@ -3442,8 +3460,9 @@ cdef class Polynomial(CommutativePolynomial): def __copy__(self): """ - Return a "copy" of self. This is just self, since in Sage - polynomials are immutable this just returns self again. + Return a "copy" of ``self``. + + This is just ``self``, since in Sage polynomials are immutable. EXAMPLES: @@ -3464,7 +3483,7 @@ cdef class Polynomial(CommutativePolynomial): def degree(self, gen=None): """ Return the degree of this polynomial. The zero polynomial has - degree -1. + degree `-1`. EXAMPLES:: @@ -3521,20 +3540,20 @@ cdef class Polynomial(CommutativePolynomial): def denominator(self): """ - Return a denominator of self. + Return a denominator of ``self``. - First, the lcm of the denominators of the entries of self + First, the lcm of the denominators of the entries of ``self`` is computed and returned. If this computation fails, the - unit of the parent of self is returned. + unit of the parent of ``self`` is returned. Note that some subclasses may implement their own - denominator function. For example, see + :meth:`denominator` method. For example, see :class:`sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint` .. warning:: This is not the denominator of the rational function - defined by self, which would always be 1 since self is a + defined by ``self``, which would always be 1 since ``self`` is a polynomial. EXAMPLES: @@ -3562,7 +3581,7 @@ cdef class Polynomial(CommutativePolynomial): Finally, we try to compute the denominator of a polynomial with coefficients in the real numbers, which is a ring whose elements do - not have a denominator method. + not have a :meth:`denominator` method. :: @@ -3573,17 +3592,17 @@ cdef class Polynomial(CommutativePolynomial): 1.00000000000000 Check that the denominator is an element over the base whenever the base - has no denominator function. This closes :trac:`9063`. :: + has no :meth:`denominator` method. This closes :trac:`9063`. :: - sage: R. = GF(5)[] - sage: x = R(0) - sage: x.denominator() + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: x = R(0) # optional - sage.rings.finite_rings + sage: x.denominator() # optional - sage.rings.finite_rings 1 - sage: type(x.denominator()) + sage: type(x.denominator()) # optional - sage.rings.finite_rings - sage: isinstance(x.numerator() / x.denominator(), Polynomial) + sage: isinstance(x.numerator() / x.denominator(), Polynomial) # optional - sage.rings.finite_rings True - sage: isinstance(x.numerator() / R(1), Polynomial) + sage: isinstance(x.numerator() / R(1), Polynomial) # optional - sage.rings.finite_rings False TESTS: @@ -3609,7 +3628,7 @@ cdef class Polynomial(CommutativePolynomial): def numerator(self): """ - Return a numerator of self computed as self * self.denominator() + Return a numerator of ``self``, computed as ``self * self.denominator()`` Note that some subclasses may implement its own numerator function. For example, see @@ -3618,13 +3637,13 @@ cdef class Polynomial(CommutativePolynomial): .. warning:: This is not the numerator of the rational function - defined by self, which would always be self since self is a + defined by ``self``, which would always be ``self`` since ``self`` is a polynomial. EXAMPLES: First we compute the numerator of a polynomial with - integer coefficients, which is of course self. + integer coefficients, which is of course ``self``. :: @@ -3660,17 +3679,17 @@ cdef class Polynomial(CommutativePolynomial): sage: f.numerator() x + 0.300000000000000 - We check that the computation the numerator and denominator - are valid + We check that the computation of the numerator and denominator + are valid. :: - sage: K=NumberField(symbolic_expression('x^3+2'),'a')['s,t']['x'] - sage: f=K.random_element() - sage: f.numerator() / f.denominator() == f + sage: K = NumberField(symbolic_expression('x^3+2'), 'a')['s,t']['x'] # optional - sage.rings.number_field sage.symbolic + sage: f = K.random_element() # optional - sage.rings.number_field sage.symbolic + sage: f.numerator() / f.denominator() == f # optional - sage.rings.number_field sage.symbolic True - sage: R=RR['x'] - sage: f=R.random_element() + sage: R = RR['x'] + sage: f = R.random_element() sage: f.numerator() / f.denominator() == f True """ @@ -3679,10 +3698,10 @@ cdef class Polynomial(CommutativePolynomial): def derivative(self, *args): r""" The formal derivative of this polynomial, with respect to variables - supplied in args. + supplied in ``args``. Multiple variables and iteration counts may be supplied; see - documentation for the global derivative() function for more + documentation for the global :func:`derivative` function for more details. .. SEEALSO:: @@ -3780,17 +3799,17 @@ cdef class Polynomial(CommutativePolynomial): Check that :trac:`28147` is fixed:: - sage: R. = GF(65537)[] - sage: p = x^4 - 17*x^3 + 2*x^2 - x + 7 - sage: p.derivative() + sage: R. = GF(65537)[] # optional - sage.rings.finite_rings + sage: p = x^4 - 17*x^3 + 2*x^2 - x + 7 # optional - sage.rings.finite_rings + sage: p.derivative() # optional - sage.rings.finite_rings 4*x^3 + 65486*x^2 + 4*x + 65536 - sage: R. = GF(19^2)[] - sage: p = x^4 - 17*x^3 + 2*x^2 - x + 7 - sage: p.derivative() + sage: R. = GF(19^2)[] # optional - sage.rings.finite_rings + sage: p = x^4 - 17*x^3 + 2*x^2 - x + 7 # optional - sage.rings.finite_rings + sage: p.derivative() # optional - sage.rings.finite_rings 4*x^3 + 6*x^2 + 4*x + 18 - sage: R. = GF(2)[] - sage: p = x^4 + x^2 + x - sage: p.derivative() + sage: R. = GF(2)[] # optional - sage.rings.finite_rings + sage: p = x^4 + x^2 + x # optional - sage.rings.finite_rings + sage: p.derivative() # optional - sage.rings.finite_rings 1 sage: R. = Integers(77)[] @@ -3805,8 +3824,8 @@ cdef class Polynomial(CommutativePolynomial): ... ValueError: cannot differentiate with respect to 2*x - sage: y = var("y") - sage: f._derivative(y) + sage: y = var("y") # optional - sage.symbolic + sage: f._derivative(y) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: cannot differentiate with respect to y @@ -3814,21 +3833,21 @@ cdef class Polynomial(CommutativePolynomial): Check that :trac:`26844` is fixed by :trac:`28147`:: - sage: A = PolynomialRing(GF(3), name='t') - sage: K = A.fraction_field() - sage: t = K.gen() - sage: t.derivative(t) + sage: A = PolynomialRing(GF(3), name='t') # optional - sage.rings.finite_rings + sage: K = A.fraction_field() # optional - sage.rings.finite_rings + sage: t = K.gen() # optional - sage.rings.finite_rings + sage: t.derivative(t) # optional - sage.rings.finite_rings 1 Check that :trac:`28187` is fixed:: - sage: R. = GF(65537)[] - sage: x._derivative(2*x) + sage: R. = GF(65537)[] # optional - sage.rings.finite_rings + sage: x._derivative(2*x) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: cannot differentiate with respect to 2*x - sage: y = var('y') - sage: R.gen()._derivative(y) + sage: y = var('y') # optional - sage.symbolic + sage: R.gen()._derivative(y) # optional - sage.rings.finite_rings sage.symbolic Traceback (most recent call last): ... ValueError: cannot differentiate with respect to y @@ -3905,16 +3924,16 @@ cdef class Polynomial(CommutativePolynomial): This shows that the issue at :trac:`7711` is resolved:: - sage: P. = PolynomialRing(GF(2147483647)) - sage: Q. = PolynomialRing(P) - sage: p=x+y+z - sage: p.integral() + sage: P. = PolynomialRing(GF(2147483647)) # optional - sage.rings.finite_rings + sage: Q. = PolynomialRing(P) # optional - sage.rings.finite_rings + sage: p = x + y + z # optional - sage.rings.finite_rings + sage: p.integral() # optional - sage.rings.finite_rings -1073741823*y^2 + (x + z)*y - sage: P. = PolynomialRing(GF(next_prime(2147483647))) - sage: Q. = PolynomialRing(P) - sage: p=x+y+z - sage: p.integral() + sage: P. = PolynomialRing(GF(next_prime(2147483647))) # optional - sage.rings.finite_rings + sage: Q. = PolynomialRing(P) # optional - sage.rings.finite_rings + sage: p = x + y + z # optional - sage.rings.finite_rings + sage: p.integral() # optional - sage.rings.finite_rings 1073741830*y^2 + (x + z)*y A truly convoluted example:: @@ -3946,7 +3965,7 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: t = PolynomialRing(R,'t').gen() - sage: f = x*t +5*t^2 + sage: f = x*t + 5*t^2 sage: f.integral(x) 5*x*t^2 + 1/2*x^2*t @@ -4032,14 +4051,14 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - ``kwargs`` -- any keyword arguments are passed to the method - ``_factor_univariate_polynomial()`` of the base ring if it + :meth:`_factor_univariate_polynomial` of the base ring if it defines such a method. OUTPUT: - - A factorization of ``self`` over its parent into a unit and - irreducible factors. If the parent is a polynomial ring - over a field, these factors are monic. + A factorization of ``self`` over its parent into a unit and + irreducible factors. If the parent is a polynomial ring + over a field, these factors are monic. EXAMPLES: @@ -4047,38 +4066,39 @@ cdef class Polynomial(CommutativePolynomial): sage: x = QQ['x'].0 sage: f = (x^3 - 1)^2 - sage: f.factor() + sage: f.factor() # optional - sage.libs.pari (x - 1)^2 * (x^2 + x + 1)^2 Since `\QQ` is a field, the irreducible factors are monic:: sage: f = 10*x^5 - 1 - sage: f.factor() + sage: f.factor() # optional - sage.libs.pari (10) * (x^5 - 1/10) sage: f = 10*x^5 - 10 - sage: f.factor() + sage: f.factor() # optional - sage.libs.pari (10) * (x - 1) * (x^4 + x^3 + x^2 + x + 1) Over `\ZZ` the irreducible factors need not be monic:: sage: x = ZZ['x'].0 sage: f = 10*x^5 - 1 - sage: f.factor() + sage: f.factor() # optional - sage.libs.pari 10*x^5 - 1 We factor a non-monic polynomial over a finite field of 25 elements:: - sage: k. = GF(25) - sage: R. = k[] - sage: f = 2*x^10 + 2*x + 2*a - sage: F = f.factor(); F - (2) * (x + a + 2) * (x^2 + 3*x + 4*a + 4) * (x^2 + (a + 1)*x + a + 2) * (x^5 + (3*a + 4)*x^4 + (3*a + 3)*x^3 + 2*a*x^2 + (3*a + 1)*x + 3*a + 1) + sage: k. = GF(25) # optional - sage.rings.finite_rings + sage: R. = k[] # optional - sage.rings.finite_rings + sage: f = 2*x^10 + 2*x + 2*a # optional - sage.rings.finite_rings + sage: F = f.factor(); F # optional - sage.rings.finite_rings + (2) * (x + a + 2) * (x^2 + 3*x + 4*a + 4) * (x^2 + (a + 1)*x + a + 2) + * (x^5 + (3*a + 4)*x^4 + (3*a + 3)*x^3 + 2*a*x^2 + (3*a + 1)*x + 3*a + 1) Notice that the unit factor is included when we multiply `F` back out:: - sage: expand(F) + sage: expand(F) # optional - sage.rings.finite_rings 2*x^10 + 2*x + 2*a A new ring. In the example below, we set the special method @@ -4087,20 +4107,23 @@ cdef class Polynomial(CommutativePolynomial): used to easily extend polynomial factorization to work over new rings you introduce:: - sage: R. = PolynomialRing(IntegerModRing(4),implementation="NTL") - sage: (x^2).factor() + sage: R. = PolynomialRing(IntegerModRing(4), implementation="NTL") # optional - sage.libs.ntl + sage: (x^2).factor() # optional - sage.libs.ntl Traceback (most recent call last): ... - NotImplementedError: factorization of polynomials over rings with composite characteristic is not implemented - sage: R.base_ring()._factor_univariate_polynomial = lambda f: f.change_ring(ZZ).factor() - sage: (x^2).factor() + NotImplementedError: factorization of polynomials over rings with + composite characteristic is not implemented + sage: def my_factor(f): + ....: return f.change_ring(ZZ).factor() + sage: R.base_ring()._factor_univariate_polynomial = my_factor # optional - sage.libs.ntl + sage: (x^2).factor() # optional - sage.libs.ntl sage.libs.pari x^2 - sage: del R.base_ring()._factor_univariate_polynomial # clean up + sage: del R.base_ring()._factor_univariate_polynomial # clean up # optional - sage.libs.ntl Arbitrary precision real and complex factorization:: sage: R. = RealField(100)[] - sage: F = factor(x^2-3); F + sage: F = factor(x^2 - 3); F (x - 1.7320508075688772935274463415) * (x + 1.7320508075688772935274463415) sage: expand(F) x^2 - 3.0000000000000000000000000000 @@ -4108,11 +4131,11 @@ cdef class Polynomial(CommutativePolynomial): x^2 + 1.0000000000000000000000000000 sage: R. = ComplexField(100)[] - sage: F = factor(x^2+3); F + sage: F = factor(x^2 + 3); F (x - 1.7320508075688772935274463415*I) * (x + 1.7320508075688772935274463415*I) sage: expand(F) x^2 + 3.0000000000000000000000000000 - sage: factor(x^2+1) + sage: factor(x^2 + 1) (x - I) * (x + I) sage: f = R(I) * (x^2 + 1) ; f I*x^2 + I @@ -4123,24 +4146,26 @@ cdef class Polynomial(CommutativePolynomial): Over a number field:: - sage: K. = CyclotomicField(15) - sage: x = polygen(K) - sage: ((x^3 + z*x + 1)^3*(x - z)).factor() + sage: K. = CyclotomicField(15) # optional - sage.rings.number_field + sage: x = polygen(K) # optional - sage.rings.number_field + sage: ((x^3 + z*x + 1)^3 * (x - z)).factor() # optional - sage.rings.number_field (x - z) * (x^3 + z*x + 1)^3 - sage: cyclotomic_polynomial(12).change_ring(K).factor() + sage: cyclotomic_polynomial(12).change_ring(K).factor() # optional - sage.rings.number_field (x^2 - z^5 - 1) * (x^2 + z^5) - sage: ((x^3 + z*x + 1)^3*(x/(z+2) - 1/3)).factor() - (-1/331*z^7 + 3/331*z^6 - 6/331*z^5 + 11/331*z^4 - 21/331*z^3 + 41/331*z^2 - 82/331*z + 165/331) * (x - 1/3*z - 2/3) * (x^3 + z*x + 1)^3 + sage: ((x^3 + z*x + 1)^3 * (x/(z+2) - 1/3)).factor() # optional - sage.rings.number_field + (-1/331*z^7 + 3/331*z^6 - 6/331*z^5 + 11/331*z^4 + - 21/331*z^3 + 41/331*z^2 - 82/331*z + 165/331) + * (x - 1/3*z - 2/3) * (x^3 + z*x + 1)^3 Over a relative number field:: sage: x = polygen(QQ) - sage: K. = CyclotomicField(3) - sage: L. = K.extension(x^3 - 2) - sage: t = polygen(L, 't') - sage: f = (t^3 + t + a)*(t^5 + t + z); f + sage: K. = CyclotomicField(3) # optional - sage.rings.number_field + sage: L. = K.extension(x^3 - 2) # optional - sage.rings.number_field + sage: t = polygen(L, 't') # optional - sage.rings.number_field + sage: f = (t^3 + t + a) * (t^5 + t + z); f # optional - sage.rings.number_field t^8 + t^6 + a*t^5 + t^4 + z*t^3 + t^2 + (a + z)*t + z*a - sage: f.factor() + sage: f.factor() # optional - sage.rings.number_field (t^3 + t + a) * (t^5 + t + z) Over the real double field:: @@ -4168,33 +4193,42 @@ cdef class Polynomial(CommutativePolynomial): sage: f = (x^2 + 2*R(I))^3 sage: F = f.factor() sage: F # abs tol 3e-5 - (x - 1.0000138879287663 + 1.0000013435286879*I) * (x - 0.9999942196864997 + 0.9999873009803959*I) * (x - 0.9999918923847313 + 1.0000113554909125*I) * (x + 0.9999908759550227 - 1.0000069659624138*I) * (x + 0.9999985293216753 - 0.9999886153831807*I) * (x + 1.0000105947233 - 1.0000044186544053*I) + (x - 1.0000138879287663 + 1.0000013435286879*I) * (x - 0.9999942196864997 + 0.9999873009803959*I) * (x - 0.9999918923847313 + 1.0000113554909125*I) + * (x + 0.9999908759550227 - 1.0000069659624138*I) * (x + 0.9999985293216753 - 0.9999886153831807*I) * (x + 1.0000105947233 - 1.0000044186544053*I) sage: [f(t[0][0]).abs() for t in F] # abs tol 1e-13 - [1.979365054e-14, 1.97936298566e-14, 1.97936990747e-14, 3.6812407475e-14, 3.65211563729e-14, 3.65220890052e-14] + [1.979365054e-14, 1.97936298566e-14, 1.97936990747e-14, + 3.6812407475e-14, 3.65211563729e-14, 3.65220890052e-14] Factoring polynomials over `\ZZ/n\ZZ` for composite `n` is not implemented:: sage: R. = PolynomialRing(Integers(35)) - sage: f = (x^2+2*x+2)*(x^2+3*x+9) + sage: f = (x^2 + 2*x + 2) * (x^2 + 3*x + 9) sage: f.factor() Traceback (most recent call last): ... - NotImplementedError: factorization of polynomials over rings with composite characteristic is not implemented + NotImplementedError: factorization of polynomials over + rings with composite characteristic is not implemented Factoring polynomials over the algebraic numbers (see :trac:`8544`):: - sage: R. = QQbar[] - sage: (x^8-1).factor() - (x - 1) * (x - 0.7071067811865475? - 0.7071067811865475?*I) * (x - 0.7071067811865475? + 0.7071067811865475?*I) * (x - I) * (x + I) * (x + 0.7071067811865475? - 0.7071067811865475?*I) * (x + 0.7071067811865475? + 0.7071067811865475?*I) * (x + 1) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: (x^8 - 1).factor() # optional - sage.rings.number_field + (x - 1) * (x - 0.7071067811865475? - 0.7071067811865475?*I) + * (x - 0.7071067811865475? + 0.7071067811865475?*I) * (x - I) * (x + I) + * (x + 0.7071067811865475? - 0.7071067811865475?*I) + * (x + 0.7071067811865475? + 0.7071067811865475?*I) * (x + 1) Factoring polynomials over the algebraic reals (see :trac:`8544`):: - sage: R. = AA[] - sage: (x^8+1).factor() - (x^2 - 1.847759065022574?*x + 1.000000000000000?) * (x^2 - 0.7653668647301795?*x + 1.000000000000000?) * (x^2 + 0.7653668647301795?*x + 1.000000000000000?) * (x^2 + 1.847759065022574?*x + 1.000000000000000?) + sage: R. = AA[] # optional - sage.rings.number_field + sage: (x^8 + 1).factor() # optional - sage.rings.number_field + (x^2 - 1.847759065022574?*x + 1.000000000000000?) + * (x^2 - 0.7653668647301795?*x + 1.000000000000000?) + * (x^2 + 0.7653668647301795?*x + 1.000000000000000?) + * (x^2 + 1.847759065022574?*x + 1.000000000000000?) TESTS: @@ -4215,91 +4249,94 @@ cdef class Polynomial(CommutativePolynomial): sage: f = 8*x^9 + 42*x^6 + 6*x^3 - 1 sage: g = x^24 - 12*x^23 + 72*x^22 - 286*x^21 + 849*x^20 - 2022*x^19 + 4034*x^18 - 6894*x^17 + 10182*x^16 - 13048*x^15 + 14532*x^14 - 13974*x^13 + 11365*x^12 - 7578*x^11 + 4038*x^10 - 1766*x^9 + 762*x^8 - 408*x^7 + 236*x^6 - 126*x^5 + 69*x^4 - 38*x^3 + 18*x^2 - 6*x + 1 sage: assert g.is_irreducible() - sage: K. = NumberField(g) - sage: len(f.roots(K)) + sage: K. = NumberField(g) # optional - sage.rings.number_field + sage: len(f.roots(K)) # optional - sage.rings.number_field 9 sage: f.factor() (8) * (x^3 + 1/4) * (x^6 + 5*x^3 - 1/2) - sage: f.change_ring(K).factor() + sage: f.change_ring(K).factor() # optional - sage.rings.number_field (8) * (x - 3260097/3158212*a^22 + 35861067/3158212*a^21 - 197810817/3158212*a^20 + 722970825/3158212*a^19 - 1980508347/3158212*a^18 + 4374189477/3158212*a^17 - 4059860553/1579106*a^16 + 6442403031/1579106*a^15 - 17542341771/3158212*a^14 + 20537782665/3158212*a^13 - 20658463789/3158212*a^12 + 17502836649/3158212*a^11 - 11908953451/3158212*a^10 + 6086953981/3158212*a^9 - 559822335/789553*a^8 + 194545353/789553*a^7 - 505969453/3158212*a^6 + 338959407/3158212*a^5 - 155204647/3158212*a^4 + 79628015/3158212*a^3 - 57339525/3158212*a^2 + 26692783/3158212*a - 1636338/789553) * ... - sage: f = QQbar['x'](1) - sage: f.factor() + sage: f = QQbar['x'](1) # optional - sage.rings.number_field + sage: f.factor() # optional - sage.rings.number_field 1 Factorization also works even if the variable of the finite field is nefariously labeled `x`:: - sage: R. = GF(3^2, 'x')[] - sage: f = x^10 +7*x -13 - sage: G = f.factor(); G - (x + x) * (x + 2*x + 1) * (x^4 + (x + 2)*x^3 + (2*x + 2)*x + 2) * (x^4 + 2*x*x^3 + (x + 1)*x + 2) + sage: R. = GF(3^2, 'x')[] # optional - sage.rings.finite_rings + sage: f = x^10 +7*x -13 # optional - sage.rings.finite_rings + sage: G = f.factor(); G # optional - sage.rings.finite_rings + (x + x) * (x + 2*x + 1) * (x^4 + (x + 2)*x^3 + (2*x + 2)*x + 2) + * (x^4 + 2*x*x^3 + (x + 1)*x + 2) sage: prod(G) == f True :: - sage: R. = GF(9,'x')[] # purposely calling it x to test robustness - sage: f = x0^3 + x0 + 1 - sage: f.factor() + sage: R. = GF(9,'x')[] # purposely calling it x to test robustness # optional - sage.rings.finite_rings + sage: f = x0^3 + x0 + 1 # optional - sage.rings.finite_rings + sage: f.factor() # optional - sage.rings.finite_rings (x0 + 2) * (x0 + x) * (x0 + 2*x + 1) - sage: f = 0*x0 - sage: f.factor() + sage: f = 0*x0 # optional - sage.rings.finite_rings + sage: f.factor() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ArithmeticError: factorization of 0 is not defined :: - sage: f = x0^0 - sage: f.factor() + sage: f = x0^0 # optional - sage.rings.finite_rings + sage: f.factor() # optional - sage.rings.finite_rings 1 Over a complicated number field:: sage: x = polygen(QQ, 'x') sage: f = x^6 + 10/7*x^5 - 867/49*x^4 - 76/245*x^3 + 3148/35*x^2 - 25944/245*x + 48771/1225 - sage: K. = NumberField(f) - sage: S. = K[] - sage: ff = S(f); ff + sage: K. = NumberField(f) # optional - sage.rings.number_field + sage: S. = K[] # optional - sage.rings.number_field + sage: ff = S(f); ff # optional - sage.rings.number_field T^6 + 10/7*T^5 - 867/49*T^4 - 76/245*T^3 + 3148/35*T^2 - 25944/245*T + 48771/1225 - sage: F = ff.factor() - sage: len(F) + sage: F = ff.factor() # optional - sage.rings.number_field + sage: len(F) # optional - sage.rings.number_field 4 - sage: F[:2] - [(T - a, 1), (T - 40085763200/924556084127*a^5 - 145475769880/924556084127*a^4 + 527617096480/924556084127*a^3 + 1289745809920/924556084127*a^2 - 3227142391585/924556084127*a - 401502691578/924556084127, 1)] - sage: expand(F) + sage: F[:2] # optional - sage.rings.number_field + [(T - a, 1), + (T - 40085763200/924556084127*a^5 - 145475769880/924556084127*a^4 + 527617096480/924556084127*a^3 + + 1289745809920/924556084127*a^2 - 3227142391585/924556084127*a - 401502691578/924556084127, 1)] + sage: expand(F) # optional - sage.rings.number_field T^6 + 10/7*T^5 - 867/49*T^4 - 76/245*T^3 + 3148/35*T^2 - 25944/245*T + 48771/1225 :: sage: f = x^2 - 1/3 - sage: K. = NumberField(f) - sage: A. = K[] - sage: A(x^2 - 1).factor() + sage: K. = NumberField(f) # optional - sage.rings.number_field + sage: A. = K[] # optional - sage.rings.number_field + sage: A(x^2 - 1).factor() # optional - sage.rings.number_field (T - 1) * (T + 1) :: - sage: A(3*x^2 - 1).factor() + sage: A(3*x^2 - 1).factor() # optional - sage.rings.number_field (3) * (T - a) * (T + a) :: - sage: A(x^2 - 1/3).factor() + sage: A(x^2 - 1/3).factor() # optional - sage.rings.number_field (T - a) * (T + a) Test that :trac:`10279` is fixed:: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(t^4 - t^2 + 1) - sage: pol = t^3 + (-4*a^3 + 2*a)*t^2 - 11/3*a^2*t + 2/3*a^3 - 4/3*a - sage: pol.factor() + sage: K. = NumberField(t^4 - t^2 + 1) # optional - sage.rings.number_field + sage: pol = t^3 + (-4*a^3 + 2*a)*t^2 - 11/3*a^2*t + 2/3*a^3 - 4/3*a # optional - sage.rings.number_field + sage: pol.factor() # optional - sage.rings.number_field (t - 2*a^3 + a) * (t - 4/3*a^3 + 2/3*a) * (t - 2/3*a^3 + 1/3*a) Test that this factorization really uses ``nffactor()`` internally:: sage: pari.default("debug", 3) - sage: F = pol.factor() + sage: F = pol.factor() # optional - sage.rings.number_field Entering nffactor: ... @@ -4308,55 +4345,55 @@ cdef class Polynomial(CommutativePolynomial): Test that :trac:`10369` is fixed:: sage: x = polygen(QQ) - sage: K. = NumberField(x^6 + x^5 + x^4 + x^3 + x^2 + x + 1) - sage: R. = PolynomialRing(K) + sage: K. = NumberField(x^6 + x^5 + x^4 + x^3 + x^2 + x + 1) # optional - sage.rings.number_field + sage: R. = PolynomialRing(K) # optional - sage.rings.number_field - sage: pol = (-1/7*a^5 - 1/7*a^4 - 1/7*a^3 - 1/7*a^2 - 2/7*a - 1/7)*t^10 + (4/7*a^5 - 2/7*a^4 - 2/7*a^3 - 2/7*a^2 - 2/7*a - 6/7)*t^9 + (90/49*a^5 + 152/49*a^4 + 18/49*a^3 + 24/49*a^2 + 30/49*a + 36/49)*t^8 + (-10/49*a^5 + 10/7*a^4 + 198/49*a^3 - 102/49*a^2 - 60/49*a - 26/49)*t^7 + (40/49*a^5 + 45/49*a^4 + 60/49*a^3 + 277/49*a^2 - 204/49*a - 78/49)*t^6 + (90/49*a^5 + 110/49*a^4 + 2*a^3 + 80/49*a^2 + 46/7*a - 30/7)*t^5 + (30/7*a^5 + 260/49*a^4 + 250/49*a^3 + 232/49*a^2 + 32/7*a + 8)*t^4 + (-184/49*a^5 - 58/49*a^4 - 52/49*a^3 - 66/49*a^2 - 72/49*a - 72/49)*t^3 + (18/49*a^5 - 32/49*a^4 + 10/49*a^3 + 4/49*a^2)*t^2 + (2/49*a^4 - 4/49*a^3 + 2/49*a^2)*t - sage: pol.factor() + sage: pol = (-1/7*a^5 - 1/7*a^4 - 1/7*a^3 - 1/7*a^2 - 2/7*a - 1/7)*t^10 + (4/7*a^5 - 2/7*a^4 - 2/7*a^3 - 2/7*a^2 - 2/7*a - 6/7)*t^9 + (90/49*a^5 + 152/49*a^4 + 18/49*a^3 + 24/49*a^2 + 30/49*a + 36/49)*t^8 + (-10/49*a^5 + 10/7*a^4 + 198/49*a^3 - 102/49*a^2 - 60/49*a - 26/49)*t^7 + (40/49*a^5 + 45/49*a^4 + 60/49*a^3 + 277/49*a^2 - 204/49*a - 78/49)*t^6 + (90/49*a^5 + 110/49*a^4 + 2*a^3 + 80/49*a^2 + 46/7*a - 30/7)*t^5 + (30/7*a^5 + 260/49*a^4 + 250/49*a^3 + 232/49*a^2 + 32/7*a + 8)*t^4 + (-184/49*a^5 - 58/49*a^4 - 52/49*a^3 - 66/49*a^2 - 72/49*a - 72/49)*t^3 + (18/49*a^5 - 32/49*a^4 + 10/49*a^3 + 4/49*a^2)*t^2 + (2/49*a^4 - 4/49*a^3 + 2/49*a^2)*t # optional - sage.rings.number_field + sage: pol.factor() # optional - sage.rings.number_field (-1/7*a^5 - 1/7*a^4 - 1/7*a^3 - 1/7*a^2 - 2/7*a - 1/7) * t * (t - a^5 - a^4 - a^3 - a^2 - a - 1)^4 * (t^5 + (-12/7*a^5 - 10/7*a^4 - 8/7*a^3 - 6/7*a^2 - 4/7*a - 2/7)*t^4 + (12/7*a^5 - 8/7*a^3 + 16/7*a^2 + 2/7*a + 20/7)*t^3 + (-20/7*a^5 - 20/7*a^3 - 20/7*a^2 + 4/7*a - 2)*t^2 + (12/7*a^5 + 12/7*a^3 + 2/7*a + 16/7)*t - 4/7*a^5 - 4/7*a^3 - 4/7*a - 2/7) - sage: pol = (1/7*a^2 - 1/7*a)*t^10 + (4/7*a - 6/7)*t^9 + (102/49*a^5 + 99/49*a^4 + 96/49*a^3 + 93/49*a^2 + 90/49*a + 150/49)*t^8 + (-160/49*a^5 - 36/49*a^4 - 48/49*a^3 - 8/7*a^2 - 60/49*a - 60/49)*t^7 + (30/49*a^5 - 55/49*a^4 + 20/49*a^3 + 5/49*a^2)*t^6 + (6/49*a^4 - 12/49*a^3 + 6/49*a^2)*t^5 - sage: pol.factor() + sage: pol = (1/7*a^2 - 1/7*a)*t^10 + (4/7*a - 6/7)*t^9 + (102/49*a^5 + 99/49*a^4 + 96/49*a^3 + 93/49*a^2 + 90/49*a + 150/49)*t^8 + (-160/49*a^5 - 36/49*a^4 - 48/49*a^3 - 8/7*a^2 - 60/49*a - 60/49)*t^7 + (30/49*a^5 - 55/49*a^4 + 20/49*a^3 + 5/49*a^2)*t^6 + (6/49*a^4 - 12/49*a^3 + 6/49*a^2)*t^5 # optional - sage.rings.number_field + sage: pol.factor() # optional - sage.rings.number_field (1/7*a^2 - 1/7*a) * t^5 * (t^5 + (-40/7*a^5 - 38/7*a^4 - 36/7*a^3 - 34/7*a^2 - 32/7*a - 30/7)*t^4 + (60/7*a^5 - 30/7*a^4 - 18/7*a^3 - 9/7*a^2 - 3/7*a)*t^3 + (60/7*a^4 - 40/7*a^3 - 16/7*a^2 - 4/7*a)*t^2 + (30/7*a^3 - 25/7*a^2 - 5/7*a)*t + 6/7*a^2 - 6/7*a) - sage: pol = x^10 + (4/7*a - 6/7)*x^9 + (9/49*a^2 - 3/7*a + 15/49)*x^8 + (8/343*a^3 - 32/343*a^2 + 40/343*a - 20/343)*x^7 + (5/2401*a^4 - 20/2401*a^3 + 40/2401*a^2 - 5/343*a + 15/2401)*x^6 + (-6/16807*a^4 + 12/16807*a^3 - 18/16807*a^2 + 12/16807*a - 6/16807)*x^5 - sage: pol.factor() + sage: pol = x^10 + (4/7*a - 6/7)*x^9 + (9/49*a^2 - 3/7*a + 15/49)*x^8 + (8/343*a^3 - 32/343*a^2 + 40/343*a - 20/343)*x^7 + (5/2401*a^4 - 20/2401*a^3 + 40/2401*a^2 - 5/343*a + 15/2401)*x^6 + (-6/16807*a^4 + 12/16807*a^3 - 18/16807*a^2 + 12/16807*a - 6/16807)*x^5 # optional - sage.rings.number_field + sage: pol.factor() # optional - sage.rings.number_field x^5 * (x^5 + (4/7*a - 6/7)*x^4 + (9/49*a^2 - 3/7*a + 15/49)*x^3 + (8/343*a^3 - 32/343*a^2 + 40/343*a - 20/343)*x^2 + (5/2401*a^4 - 20/2401*a^3 + 40/2401*a^2 - 5/343*a + 15/2401)*x - 6/16807*a^4 + 12/16807*a^3 - 18/16807*a^2 + 12/16807*a - 6/16807) Factoring over a number field over which we cannot factor the discriminant by trial division:: sage: x = polygen(QQ) - sage: K. = NumberField(x^16 - x - 6) - sage: R. = PolynomialRing(K) - sage: f = (x+a)^50 - (a-1)^50 - sage: len(factor(f)) + sage: K. = NumberField(x^16 - x - 6) # optional - sage.rings.number_field + sage: R. = PolynomialRing(K) # optional - sage.rings.number_field + sage: f = (x+a)^50 - (a-1)^50 # optional - sage.rings.number_field + sage: len(factor(f)) # optional - sage.rings.number_field 6 - sage: pari(K.discriminant()).factor(limit=10^6) + sage: pari(K.discriminant()).factor(limit=10^6) # optional - sage.rings.number_field [-1, 1; 3, 15; 23, 1; 887, 1; 12583, 1; 2354691439917211, 1] - sage: factor(K.discriminant()) + sage: factor(K.discriminant()) # optional - sage.rings.number_field -1 * 3^15 * 23 * 887 * 12583 * 6335047 * 371692813 Factoring over a number field over which we cannot factor the discriminant and over which `nffactor()` fails:: sage: p = next_prime(10^50); q = next_prime(10^51); n = p*q - sage: K. = QuadraticField(p*q) - sage: R. = PolynomialRing(K) - sage: K.pari_polynomial('a').nffactor("x^2+1") + sage: K. = QuadraticField(p*q) # optional - sage.rings.number_field + sage: R. = PolynomialRing(K) # optional - sage.rings.number_field + sage: K.pari_polynomial('a').nffactor("x^2+1") # optional - sage.rings.number_field Mat([x^2 + 1, 1]) - sage: factor(x^2 + 1) + sage: factor(x^2 + 1) # optional - sage.rings.number_field x^2 + 1 - sage: factor( (x - a) * (x + 2*a) ) + sage: factor((x - a) * (x + 2*a)) # optional - sage.rings.number_field (x - a) * (x + 2*a) A test where nffactor used to fail without a nf structure:: sage: x = polygen(QQ) - sage: K = NumberField([x^2-1099511627777, x^3-3],'a') - sage: x = polygen(K) - sage: f = x^3 - 3 - sage: factor(f) + sage: K = NumberField([x^2-1099511627777, x^3-3], 'a') # optional - sage.rings.number_field + sage: x = polygen(K) # optional - sage.rings.number_field + sage: f = x^3 - 3 # optional - sage.rings.number_field + sage: factor(f) # optional - sage.rings.number_field (x - a1) * (x^2 + a1*x + a1^2) We check that :trac:`7554` is fixed:: @@ -4373,7 +4410,7 @@ cdef class Polynomial(CommutativePolynomial): sage: P. = PolynomialRing(ZZ) sage: R. = PolynomialRing(FractionField(P)) - sage: p = (x - a)*(b*x + c)*(a*b*x + a*c) / (a + 2) + sage: p = (x - a) * (b*x + c) * (a*b*x + a*c) / (a + 2) sage: factor(p) (a/(a + 2)) * (x - a) * (b*x + c)^2 @@ -4538,31 +4575,33 @@ cdef class Polynomial(CommutativePolynomial): sage: R.=PolynomialRing(ZZ) sage: f = (2*x + 1) * (3*x^2 - 5)^2 - sage: f._factor_pari_helper(pari(f).factor()) + sage: f._factor_pari_helper(pari(f).factor()) # optional - sage.libs.pari (2*x + 1) * (3*x^2 - 5)^2 - sage: f._factor_pari_helper(pari(f).factor(), unit=11) + sage: f._factor_pari_helper(pari(f).factor(), unit=11) # optional - sage.libs.pari 11 * (2*x + 1) * (3*x^2 - 5)^2 - sage: (8*f)._factor_pari_helper(pari(f).factor()) + sage: (8*f)._factor_pari_helper(pari(f).factor()) # optional - sage.libs.pari 8 * (2*x + 1) * (3*x^2 - 5)^2 - sage: (8*f)._factor_pari_helper(pari(f).factor(), unit=11) + sage: (8*f)._factor_pari_helper(pari(f).factor(), unit=11) # optional - sage.libs.pari 88 * (2*x + 1) * (3*x^2 - 5)^2 - sage: QQ['x'](f)._factor_pari_helper(pari(f).factor()) + sage: QQ['x'](f)._factor_pari_helper(pari(f).factor()) # optional - sage.libs.pari (18) * (x + 1/2) * (x^2 - 5/3)^2 - sage: QQ['x'](f)._factor_pari_helper(pari(f).factor(), unit=11) + sage: QQ['x'](f)._factor_pari_helper(pari(f).factor(), unit=11) # optional - sage.libs.pari (198) * (x + 1/2) * (x^2 - 5/3)^2 - sage: f = prod((k^2*x^k + k)^(k-1) for k in primes(10)) - sage: F = f._factor_pari_helper(pari(f).factor()); F + sage: f = prod((k^2*x^k + k)^(k-1) for k in primes(10)) # optional - sage.libs.pari + sage: F = f._factor_pari_helper(pari(f).factor()); F # optional - sage.libs.pari 1323551250 * (2*x^2 + 1) * (3*x^3 + 1)^2 * (5*x^5 + 1)^4 * (7*x^7 + 1)^6 - sage: F.prod() == f + sage: F.prod() == f # optional - sage.libs.pari True - sage: QQ['x'](f)._factor_pari_helper(pari(f).factor()) + sage: QQ['x'](f)._factor_pari_helper(pari(f).factor()) # optional - sage.libs.pari (1751787911376562500) * (x^2 + 1/2) * (x^3 + 1/3)^2 * (x^5 + 1/5)^4 * (x^7 + 1/7)^6 - sage: g = GF(19)['x'](f) - sage: G = g._factor_pari_helper(pari(g).factor()); G - (4) * (x + 3) * (x + 16)^5 * (x + 11)^6 * (x^2 + 7*x + 9)^4 * (x^2 + 15*x + 9)^4 * (x^3 + 13)^2 * (x^6 + 8*x^5 + 7*x^4 + 18*x^3 + 11*x^2 + 12*x + 1)^6 - sage: G.prod() == g + sage: g = GF(19)['x'](f) # optional - sage.libs.pari + sage: G = g._factor_pari_helper(pari(g).factor()); G # optional - sage.libs.pari + (4) * (x + 3) * (x + 16)^5 * (x + 11)^6 * (x^2 + 7*x + 9)^4 + * (x^2 + 15*x + 9)^4 * (x^3 + 13)^2 + * (x^6 + 8*x^5 + 7*x^4 + 18*x^3 + 11*x^2 + 12*x + 1)^6 + sage: G.prod() == g # optional - sage.libs.pari True """ pols, exps = G @@ -4623,25 +4662,26 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: K. = (x^3 + 2).splitting_field(); K - Number Field in a with defining polynomial x^6 + 3*x^5 + 6*x^4 + 11*x^3 + 12*x^2 - 3*x + 1 - sage: K. = (x^3 - 3*x + 1).splitting_field(); K + sage: K. = (x^3 + 2).splitting_field(); K # optional - sage.rings.number_field + Number Field in a with defining polynomial + x^6 + 3*x^5 + 6*x^4 + 11*x^3 + 12*x^2 - 3*x + 1 + sage: K. = (x^3 - 3*x + 1).splitting_field(); K # optional - sage.rings.number_field Number Field in a with defining polynomial x^3 - 3*x + 1 Relative situation:: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^3 + 2) - sage: S. = PolynomialRing(K) - sage: L. = (t^2 - a).splitting_field() - sage: L + sage: K. = NumberField(x^3 + 2) # optional - sage.rings.number_field + sage: S. = PolynomialRing(K) # optional - sage.rings.number_field + sage: L. = (t^2 - a).splitting_field() # optional - sage.rings.number_field + sage: L # optional - sage.rings.number_field Number Field in b with defining polynomial t^6 + 2 With ``map=True``, we also get the embedding of the base field into the splitting field:: - sage: L., phi = (t^2 - a).splitting_field(map=True) - sage: phi + sage: L., phi = (t^2 - a).splitting_field(map=True) # optional - sage.rings.number_field + sage: phi # optional - sage.rings.number_field Ring morphism: From: Number Field in a with defining polynomial x^3 + 2 To: Number Field in b with defining polynomial t^6 + 2 @@ -4649,14 +4689,14 @@ cdef class Polynomial(CommutativePolynomial): An example over a finite field:: - sage: P. = PolynomialRing(GF(7)) - sage: t = x^2 + 1 - sage: t.splitting_field('b') + sage: P. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings + sage: t = x^2 + 1 # optional - sage.rings.finite_rings + sage: t.splitting_field('b') # optional - sage.rings.finite_rings Finite Field in b of size 7^2 - sage: P. = PolynomialRing(GF(7^3, 'a')) - sage: t = x^2 + 1 - sage: t.splitting_field('b', map=True) + sage: P. = PolynomialRing(GF(7^3, 'a')) # optional - sage.rings.finite_rings + sage: t = x^2 + 1 # optional - sage.rings.finite_rings + sage: t.splitting_field('b', map=True) # optional - sage.rings.finite_rings (Finite Field in b of size 7^6, Ring morphism: From: Finite Field in a of size 7^3 @@ -4666,13 +4706,13 @@ cdef class Polynomial(CommutativePolynomial): If the extension is trivial and the generators have the same name, the map will be the identity:: - sage: t = 24*x^13 + 2*x^12 + 14 - sage: t.splitting_field('a', map=True) + sage: t = 24*x^13 + 2*x^12 + 14 # optional - sage.rings.finite_rings + sage: t.splitting_field('a', map=True) # optional - sage.rings.finite_rings (Finite Field in a of size 7^3, Identity endomorphism of Finite Field in a of size 7^3) - sage: t = x^56 - 14*x^3 - sage: t.splitting_field('b', map=True) + sage: t = x^56 - 14*x^3 # optional - sage.rings.finite_rings + sage: t.splitting_field('b', map=True) # optional - sage.rings.finite_rings (Finite Field in b of size 7^3, Ring morphism: From: Finite Field in a of size 7^3 @@ -4694,48 +4734,48 @@ cdef class Polynomial(CommutativePolynomial): ... NotImplementedError: splitting_field() is only implemented over number fields and finite fields - sage: P. = PolynomialRing(GF(11^5, 'a')) - sage: t = x^2 + 1 - sage: t.splitting_field('b') + sage: P. = PolynomialRing(GF(11^5, 'a')) # optional - sage.rings.finite_rings + sage: t = x^2 + 1 # optional - sage.rings.finite_rings + sage: t.splitting_field('b') # optional - sage.rings.finite_rings Finite Field in b of size 11^10 - sage: t = 24*x^13 + 2*x^12 + 14 - sage: t.splitting_field('b') + sage: t = 24*x^13 + 2*x^12 + 14 # optional - sage.rings.finite_rings + sage: t.splitting_field('b') # optional - sage.rings.finite_rings Finite Field in b of size 11^30 - sage: t = x^56 - 14*x^3 - sage: t.splitting_field('b') + sage: t = x^56 - 14*x^3 # optional - sage.rings.finite_rings + sage: t.splitting_field('b') # optional - sage.rings.finite_rings Finite Field in b of size 11^130 - sage: P. = PolynomialRing(GF(19^6, 'a')) - sage: t = -x^6 + x^2 + 1 - sage: t.splitting_field('b') + sage: P. = PolynomialRing(GF(19^6, 'a')) # optional - sage.rings.finite_rings + sage: t = -x^6 + x^2 + 1 # optional - sage.rings.finite_rings + sage: t.splitting_field('b') # optional - sage.rings.finite_rings Finite Field in b of size 19^6 - sage: t = 24*x^13 + 2*x^12 + 14 - sage: t.splitting_field('b') + sage: t = 24*x^13 + 2*x^12 + 14 # optional - sage.rings.finite_rings + sage: t.splitting_field('b') # optional - sage.rings.finite_rings Finite Field in b of size 19^18 - sage: t = x^56 - 14*x^3 - sage: t.splitting_field('b') + sage: t = x^56 - 14*x^3 # optional - sage.rings.finite_rings + sage: t.splitting_field('b') # optional - sage.rings.finite_rings Finite Field in b of size 19^156 - sage: P. = PolynomialRing(GF(83^6, 'a')) - sage: t = 2*x^14 - 5 + 6*x - sage: t.splitting_field('b') + sage: P. = PolynomialRing(GF(83^6, 'a')) # optional - sage.rings.finite_rings + sage: t = 2*x^14 - 5 + 6*x # optional - sage.rings.finite_rings + sage: t.splitting_field('b') # optional - sage.rings.finite_rings Finite Field in b of size 83^84 - sage: t = 24*x^13 + 2*x^12 + 14 - sage: t.splitting_field('b') + sage: t = 24*x^13 + 2*x^12 + 14 # optional - sage.rings.finite_rings + sage: t.splitting_field('b') # optional - sage.rings.finite_rings Finite Field in b of size 83^78 - sage: t = x^56 - 14*x^3 - sage: t.splitting_field('b') + sage: t = x^56 - 14*x^3 # optional - sage.rings.finite_rings + sage: t.splitting_field('b') # optional - sage.rings.finite_rings Finite Field in b of size 83^12 - sage: P. = PolynomialRing(GF(401^13, 'a')) - sage: t = 2*x^14 - 5 + 6*x - sage: t.splitting_field('b') + sage: P. = PolynomialRing(GF(401^13, 'a')) # optional - sage.rings.finite_rings + sage: t = 2*x^14 - 5 + 6*x # optional - sage.rings.finite_rings + sage: t.splitting_field('b') # optional - sage.rings.finite_rings Finite Field in b of size 401^104 - sage: t = 24*x^13 + 2*x^12 + 14 - sage: t.splitting_field('b') + sage: t = 24*x^13 + 2*x^12 + 14 # optional - sage.rings.finite_rings + sage: t.splitting_field('b') # optional - sage.rings.finite_rings Finite Field in b of size 401^156 - sage: t = x^56 - 14*x^3 - sage: t.splitting_field('b') + sage: t = x^56 - 14*x^3 # optional - sage.rings.finite_rings + sage: t.splitting_field('b') # optional - sage.rings.finite_rings Finite Field in b of size 401^52 sage: R. = QQ[] @@ -4792,7 +4832,7 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = PolynomialRing(ZZ, sparse=True) sage: p = x^4 + 6*x^3 + x^2 - x + 2 sage: q = 2*x^2 - 3*x - 1 - sage: (quo,rem)=p.pseudo_quo_rem(q); quo,rem + sage: quo, rem = p.pseudo_quo_rem(q); quo, rem (4*x^2 + 30*x + 51, 175*x + 67) sage: 2^(4-2+1)*p == quo*q + rem True @@ -4800,9 +4840,10 @@ cdef class Polynomial(CommutativePolynomial): sage: S. = R[] sage: p = (-3*x^2 - x)*T^3 - 3*x*T^2 + (x^2 - x)*T + 2*x^2 + 3*x - 2 sage: q = (-x^2 - 4*x - 5)*T^2 + (6*x^2 + x + 1)*T + 2*x^2 - x - sage: quo,rem=p.pseudo_quo_rem(q); quo,rem + sage: quo, rem = p.pseudo_quo_rem(q); quo, rem ((3*x^4 + 13*x^3 + 19*x^2 + 5*x)*T + 18*x^4 + 12*x^3 + 16*x^2 + 16*x, - (-113*x^6 - 106*x^5 - 133*x^4 - 101*x^3 - 42*x^2 - 41*x)*T - 34*x^6 + 13*x^5 + 54*x^4 + 126*x^3 + 134*x^2 - 5*x - 50) + (-113*x^6 - 106*x^5 - 133*x^4 - 101*x^3 - 42*x^2 - 41*x)*T + - 34*x^6 + 13*x^5 + 54*x^4 + 126*x^3 + 134*x^2 - 5*x - 50) sage: (-x^2 - 4*x - 5)^(3-2+1) * p == quo*q + rem True """ @@ -4848,7 +4889,7 @@ cdef class Polynomial(CommutativePolynomial): The actual algorithm for computing greatest common divisors depends on the base ring underlying the polynomial ring. If the base ring - defines a method ``_gcd_univariate_polynomial``, then this method + defines a method :meth:`_gcd_univariate_polynomial`, then this method will be called (see examples below). EXAMPLES:: @@ -4864,20 +4905,22 @@ cdef class Polynomial(CommutativePolynomial): One can easily add gcd functionality to new rings by providing a method ``_gcd_univariate_polynomial``:: - sage: O = ZZ[-sqrt(5)] - sage: R. = O[] - sage: a = O.1 - sage: p = x + a - sage: q = x^2 - 5 - sage: p.gcd(q) + sage: O = ZZ[-sqrt(5)] # optional - sage.rings.number_field sage.symbolic + sage: R. = O[] # optional - sage.rings.number_field sage.symbolic + sage: a = O.1 # optional - sage.rings.number_field sage.symbolic + sage: p = x + a # optional - sage.rings.number_field sage.symbolic + sage: q = x^2 - 5 # optional - sage.rings.number_field sage.symbolic + sage: p.gcd(q) # optional - sage.rings.number_field sage.symbolic Traceback (most recent call last): ... - NotImplementedError: Order in Number Field in a with defining polynomial x^2 - 5 with a = -2.236067977499790? does not provide a gcd implementation for univariate polynomials - sage: S. = O.number_field()[] - sage: O._gcd_univariate_polynomial = lambda f,g : R(S(f).gcd(S(g))) - sage: p.gcd(q) + NotImplementedError: Order in Number Field in a + with defining polynomial x^2 - 5 with a = -2.236067977499790? + does not provide a gcd implementation for univariate polynomials + sage: S. = O.number_field()[] # optional - sage.rings.number_field sage.symbolic + sage: O._gcd_univariate_polynomial = lambda f, g: R(S(f).gcd(S(g))) # optional - sage.rings.number_field sage.symbolic + sage: p.gcd(q) # optional - sage.rings.number_field sage.symbolic x + a - sage: del O._gcd_univariate_polynomial + sage: del O._gcd_univariate_polynomial # optional - sage.rings.number_field sage.symbolic Use multivariate implementation for polynomials over polynomials rings:: @@ -4887,7 +4930,7 @@ cdef class Polynomial(CommutativePolynomial): sage: r = 2*x*y + z sage: p = r * (3*x*y*z - 1) sage: q = r * (x + y + z - 2) - sage: p.gcd(q) + sage: p.gcd(q) # optional - sage.libs.singular z + 2*x*y sage: R. = QQ[] @@ -4895,13 +4938,13 @@ cdef class Polynomial(CommutativePolynomial): sage: r = 2*x*y + 1 sage: p = r * (x - 1/2 * y) sage: q = r * (x*y^2 - x + 1/3) - sage: p.gcd(q) + sage: p.gcd(q) # optional - sage.libs.singular 2*x*y + 1 TESTS:: sage: Pol = QQ['x','y']['x'] - sage: Pol.one().gcd(1) + sage: Pol.one().gcd(1) # optional - sage.libs.singular 1 """ cdef Polynomial _other = other @@ -4924,15 +4967,15 @@ cdef class Polynomial(CommutativePolynomial): @coerce_binop def lcm(self, other): """ - Let f and g be two polynomials. Then this function returns the - monic least common multiple of f and g. + Let `f` and `g` be two polynomials. Then this function returns the + monic least common multiple of `f` and `g`. TESTS: Check that :trac:`32033` has been fixed:: - sage: R. = GF(3)[] - sage: lcm(R(0), R(0)) + sage: R. = GF(3)[] # optional - sage.rings.finite_rings + sage: lcm(R(0), R(0)) # optional - sage.rings.finite_rings 0 :: @@ -4951,8 +4994,8 @@ cdef class Polynomial(CommutativePolynomial): def _lcm(self, other): """ - Let f and g be two polynomials. Then this function returns the - monic least common multiple of f and g. + Let `f` and `g` be two polynomials. Then this function returns the + monic least common multiple of `f` and `g`. """ if self.is_zero() or other.is_zero(): P = self.parent() @@ -4975,7 +5018,7 @@ cdef class Polynomial(CommutativePolynomial): - (ring theory) A polynomial over a ring is primitive if its coefficients generate the unit ideal. - Calling `is_primitive` on a polynomial over an infinite field will + Calling :meth:`is_primitive` on a polynomial over an infinite field will raise an error. The additional inputs to this function are to speed up computation for @@ -4983,116 +5026,116 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - - ``n`` (default: ``None``) - if provided, should equal - `q-1` where ``self.parent()`` is the field with `q` - elements; otherwise it will be computed. + - ``n`` (default: ``None``) - if provided, should equal + `q-1` where ``self.parent()`` is the field with `q` + elements; otherwise it will be computed. - - ``n_prime_divs`` (default: ``None``) - if provided, should - be a list of the prime divisors of ``n``; otherwise it - will be computed. + - ``n_prime_divs`` (default: ``None``) - if provided, should + be a list of the prime divisors of `n`; otherwise it + will be computed. .. NOTE:: - Computation of the prime divisors of ``n`` can dominate the running + Computation of the prime divisors of `n` can dominate the running time of this method, so performing this computation externally - (e.g. ``pdivs=n.prime_divisors()``) is a good idea for repeated calls - to is_primitive for polynomials of the same degree. + (e.g., ``pdivs = n.prime_divisors()``) is a good idea for repeated calls + to :meth:`is_primitive` for polynomials of the same degree. - Results may be incorrect if the wrong ``n`` and/or factorization are + Results may be incorrect if the wrong `n` and/or factorization are provided. - EXAMPLES:: + EXAMPLES: - Field semantics examples. + Field semantics examples. - :: + :: - sage: R. = GF(2)['x'] - sage: f = x^4+x^3+x^2+x+1 - sage: f.is_irreducible(), f.is_primitive() + sage: R. = GF(2)['x'] # optional - sage.rings.finite_rings + sage: f = x^4 + x^3 + x^2 + x + 1 # optional - sage.rings.finite_rings + sage: f.is_irreducible(), f.is_primitive() # optional - sage.rings.finite_rings (True, False) - sage: f = x^3+x+1 - sage: f.is_irreducible(), f.is_primitive() + sage: f = x^3 + x + 1 # optional - sage.rings.finite_rings + sage: f.is_irreducible(), f.is_primitive() # optional - sage.rings.finite_rings (True, True) - sage: R. = GF(3)[] - sage: f = x^3-x+1 - sage: f.is_irreducible(), f.is_primitive() + sage: R. = GF(3)[] # optional - sage.rings.finite_rings + sage: f = x^3 - x + 1 # optional - sage.rings.finite_rings + sage: f.is_irreducible(), f.is_primitive() # optional - sage.rings.finite_rings (True, True) - sage: f = x^2+1 - sage: f.is_irreducible(), f.is_primitive() + sage: f = x^2 + 1 # optional - sage.rings.finite_rings + sage: f.is_irreducible(), f.is_primitive() # optional - sage.rings.finite_rings (True, False) - sage: R. = GF(5)[] - sage: f = x^2+x+1 - sage: f.is_primitive() + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: f = x^2 + x + 1 # optional - sage.rings.finite_rings + sage: f.is_primitive() # optional - sage.rings.finite_rings False - sage: f = x^2-x+2 - sage: f.is_primitive() + sage: f = x^2 - x + 2 # optional - sage.rings.finite_rings + sage: f.is_primitive() # optional - sage.rings.finite_rings True - sage: x=polygen(QQ); f=x^2+1 + sage: x = polygen(QQ); f = x^2 + 1 sage: f.is_primitive() Traceback (most recent call last): ... NotImplementedError: is_primitive() not defined for polynomials over infinite fields. - Ring semantics examples. + Ring semantics examples. - :: + :: sage: x=polygen(ZZ) - sage: f = 5*x^2+2 + sage: f = 5*x^2 + 2 sage: f.is_primitive() True - sage: f = 5*x^2+5 + sage: f = 5*x^2 + 5 sage: f.is_primitive() False - sage: K=NumberField(x^2+5,'a') - sage: R=K.ring_of_integers() - sage: a=R.gen(1) - sage: a^2 + sage: K = NumberField(x^2 + 5, 'a') # optional - sage.rings.number_field + sage: R = K.ring_of_integers() # optional - sage.rings.number_field + sage: a = R.gen(1) # optional - sage.rings.number_field + sage: a^2 # optional - sage.rings.number_field -5 - sage: f=a*x+2 - sage: f.is_primitive() + sage: f = a*x + 2 # optional - sage.rings.number_field + sage: f.is_primitive() # optional - sage.rings.number_field True - sage: f=(1+a)*x+2 - sage: f.is_primitive() + sage: f = (1+a)*x + 2 # optional - sage.rings.number_field + sage: f.is_primitive() # optional - sage.rings.number_field False sage: x = polygen(Integers(10)) - sage: f = 5*x^2+2 + sage: f = 5*x^2 + 2 sage: #f.is_primitive() #BUG:: elsewhere in Sage, should return True - sage: f=4*x^2+2 + sage: f = 4*x^2 + 2 sage: #f.is_primitive() #BUG:: elsewhere in Sage, should return False TESTS:: - sage: R. = GF(2)['x'] - sage: f = x^4+x^3+x^2+x+1 - sage: f.is_primitive(15) + sage: R. = GF(2)['x'] # optional - sage.rings.finite_rings + sage: f = x^4 + x^3 + x^2 + x + 1 # optional - sage.rings.finite_rings + sage: f.is_primitive(15) # optional - sage.rings.finite_rings False - sage: f.is_primitive(15, [3,5]) + sage: f.is_primitive(15, [3,5]) # optional - sage.rings.finite_rings False - sage: f.is_primitive(n_prime_divs=[3,5]) + sage: f.is_primitive(n_prime_divs=[3,5]) # optional - sage.rings.finite_rings False - sage: f = x^3+x+1 - sage: f.is_primitive(7, [7]) + sage: f = x^3 + x + 1 # optional - sage.rings.finite_rings + sage: f.is_primitive(7, [7]) # optional - sage.rings.finite_rings True - sage: R. = GF(3)[] - sage: f = x^3-x+1 - sage: f.is_primitive(26, [2,13]) + sage: R. = GF(3)[] # optional - sage.rings.finite_rings + sage: f = x^3 - x + 1 # optional - sage.rings.finite_rings + sage: f.is_primitive(26, [2,13]) # optional - sage.rings.finite_rings True - sage: f = x^2+1 - sage: f.is_primitive(8, [2]) + sage: f = x^2 + 1 # optional - sage.rings.finite_rings + sage: f.is_primitive(8, [2]) # optional - sage.rings.finite_rings False - sage: R. = GF(5)[] - sage: f = x^2+x+1 - sage: f.is_primitive(24, [2,3]) + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: f = x^2 + x + 1 # optional - sage.rings.finite_rings + sage: f.is_primitive(24, [2,3]) # optional - sage.rings.finite_rings False - sage: f = x^2-x+2 - sage: f.is_primitive(24, [2,3]) + sage: f = x^2 - x + 2 # optional - sage.rings.finite_rings + sage: f.is_primitive(24, [2,3]) # optional - sage.rings.finite_rings True - sage: x=polygen(Integers(103)); f=x^2+1 - sage: f.is_primitive() + sage: x = polygen(Integers(103)); f = x^2 + 1 + sage: f.is_primitive() # optional - sage.rings.finite_rings False """ R = self.base_ring() @@ -5116,12 +5159,12 @@ cdef class Polynomial(CommutativePolynomial): def is_constant(self): """ - Return True if this is a constant polynomial. + Return ``True`` if this is a constant polynomial. OUTPUT: - - ``bool`` - True if and only if this polynomial is + - ``bool`` - ``True`` if and only if this polynomial is constant @@ -5139,14 +5182,14 @@ cdef class Polynomial(CommutativePolynomial): def is_monomial(self): """ - Return True if self is a monomial, i.e., a power of the generator. + Return ``True`` if ``self`` is a monomial, i.e., a power of the generator. EXAMPLES:: sage: R. = QQ[] sage: x.is_monomial() True - sage: (x+1).is_monomial() + sage: (x + 1).is_monomial() False sage: (x^2).is_monomial() True @@ -5158,15 +5201,15 @@ cdef class Polynomial(CommutativePolynomial): sage: (2*x^5).is_monomial() False - To allow a non-1 leading coefficient, use is_term():: + To allow a non-1 leading coefficient, use :meth:`is_term`:: sage: (2*x^5).is_term() True .. warning:: - The definition of is_monomial in Sage up to 4.7.1 was the - same as is_term, i.e., it allowed a coefficient not equal + The definition of :meth:`is_monomial` in Sage up to 4.7.1 was the + same as :meth:`is_term`, i.e., it allowed a coefficient not equal to 1. """ return len(self.exponents()) == 1 and self.leading_coefficient() == 1 @@ -5187,10 +5230,10 @@ cdef class Polynomial(CommutativePolynomial): True sage: (3*x^5).is_term() True - sage: (1+3*x^5).is_term() + sage: (1 + 3*x^5).is_term() False - To require that the coefficient is 1, use :meth:`is_monomial()` + To require that the coefficient is 1, use :meth:`is_monomial` instead:: sage: (3*x^5).is_monomial() @@ -5201,7 +5244,7 @@ cdef class Polynomial(CommutativePolynomial): def root_field(self, names, check_irreducible=True): """ Return the field generated by the roots of the irreducible - polynomial self. The output is either a number field, relative + polynomial ``self``. The output is either a number field, relative number field, a quotient of a polynomial ring over a field, or the fraction field of the base ring. @@ -5209,55 +5252,56 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ['x'] sage: f = x^3 + x + 17 - sage: f.root_field('a') + sage: f.root_field('a') # optional - sage.rings.number_field Number Field in a with defining polynomial x^3 + x + 17 :: sage: R. = QQ['x'] sage: f = x - 3 - sage: f.root_field('b') + sage: f.root_field('b') # optional - sage.rings.number_field Rational Field :: sage: R. = ZZ['x'] sage: f = x^3 + x + 17 - sage: f.root_field('b') + sage: f.root_field('b') # optional - sage.rings.number_field Number Field in b with defining polynomial x^3 + x + 17 :: sage: y = QQ['x'].0 - sage: L. = NumberField(y^3-2) - sage: R. = L['x'] - sage: f = x^3 + x + 17 - sage: f.root_field('c') + sage: L. = NumberField(y^3 - 2) # optional - sage.rings.number_field + sage: R. = L['x'] # optional - sage.rings.number_field + sage: f = x^3 + x + 17 # optional - sage.rings.number_field + sage: f.root_field('c') # optional - sage.rings.number_field Number Field in c with defining polynomial x^3 + x + 17 over its base field :: - sage: R. = PolynomialRing(GF(9,'a')) - sage: f = x^3 + x^2 + 8 - sage: K. = f.root_field(); K - Univariate Quotient Polynomial Ring in alpha over Finite Field in a of size 3^2 with modulus x^3 + x^2 + 2 - sage: alpha^2 + 1 + sage: R. = PolynomialRing(GF(9, 'a')) # optional - sage.rings.finite_rings + sage: f = x^3 + x^2 + 8 # optional - sage.rings.finite_rings + sage: K. = f.root_field(); K # optional - sage.rings.finite_rings + Univariate Quotient Polynomial Ring in alpha + over Finite Field in a of size 3^2 with modulus x^3 + x^2 + 2 + sage: alpha^2 + 1 # optional - sage.rings.finite_rings alpha^2 + 1 - sage: alpha^3 + alpha^2 + sage: alpha^3 + alpha^2 # optional - sage.rings.finite_rings 1 :: sage: R. = QQ[] sage: f = x^2 - sage: K. = f.root_field() + sage: K. = f.root_field() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: polynomial must be irreducible TESTS:: - sage: (PolynomialRing(Integers(31),name='x').0+5).root_field('a') + sage: (PolynomialRing(Integers(31), name='x').0 + 5).root_field('a') # optional - sage.rings.finite_rings Ring of integers modulo 31 """ R = self.base_ring() @@ -5284,24 +5328,23 @@ cdef class Polynomial(CommutativePolynomial): def sylvester_matrix(self, right, variable = None): """ - Return the Sylvester matrix of self and right. + Return the Sylvester matrix of ``self`` and ``right``. Note that the Sylvester matrix is not defined if one of the polynomials is zero. INPUT: - - right: a polynomial in the same ring as self. - - variable: optional, included for compatibility with the multivariate + - ``right`` -- a polynomial in the same ring as ``self``. + - ``variable`` -- optional, included for compatibility with the multivariate case only. The variable of the polynomials. EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: f = (6*x + 47)*(7*x^2 - 2*x + 38) - sage: g = (6*x + 47)*(3*x^3 + 2*x + 1) - sage: M = f.sylvester_matrix(g) - sage: M + sage: f = (6*x + 47) * (7*x^2 - 2*x + 38) + sage: g = (6*x + 47) * (3*x^3 + 2*x + 1) + sage: M = f.sylvester_matrix(g); M # optional - sage.modules [ 42 317 134 1786 0 0 0] [ 0 42 317 134 1786 0 0] [ 0 0 42 317 134 1786 0] @@ -5313,24 +5356,24 @@ cdef class Polynomial(CommutativePolynomial): If the polynomials share a non-constant common factor then the determinant of the Sylvester matrix will be zero:: - sage: M.determinant() + sage: M.determinant() # optional - sage.modules 0 - If self and right are polynomials of positive degree, the determinant + If ``self`` and ``right`` are polynomials of positive degree, the determinant of the Sylvester matrix is the resultant of the polynomials.:: sage: h1 = R._random_nonzero_element() sage: h2 = R._random_nonzero_element() - sage: M1 = h1.sylvester_matrix(h2) - sage: M1.determinant() == h1.resultant(h2) + sage: M1 = h1.sylvester_matrix(h2) # optional - sage.modules + sage: M1.determinant() == h1.resultant(h2) # optional - sage.libs.pari sage.modules True The rank of the Sylvester matrix is related to the degree of the - gcd of self and right:: + gcd of ``self`` and ``right``:: - sage: f.gcd(g).degree() == f.degree() + g.degree() - M.rank() + sage: f.gcd(g).degree() == f.degree() + g.degree() - M.rank() # optional - sage.modules True - sage: h1.gcd(h2).degree() == h1.degree() + h2.degree() - M1.rank() + sage: h1.gcd(h2).degree() == h1.degree() + h2.degree() - M1.rank() # optional - sage.modules True TESTS: @@ -5338,65 +5381,69 @@ cdef class Polynomial(CommutativePolynomial): The variable is optional, but must be the same in both rings:: sage: K. = QQ['x'] - sage: f = x+1 + sage: f = x + 1 sage: g = QQ['y']([1, 0, 1]) - sage: f.sylvester_matrix(f, x) + sage: f.sylvester_matrix(f, x) # optional - sage.modules [1 1] [1 1] - sage: f.sylvester_matrix(g, x) + sage: f.sylvester_matrix(g, x) # optional - sage.modules Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Univariate Polynomial Ring in x over Rational Field' and 'Univariate Polynomial Ring in y over Rational Field' + TypeError: no common canonical parent for objects with parents: + 'Univariate Polynomial Ring in x over Rational Field' and + 'Univariate Polynomial Ring in y over Rational Field' Polynomials must be defined over compatible base rings:: sage: f = QQ['x']([1, 0, 1]) sage: g = ZZ['x']([1, 0, 1]) - sage: h = GF(25, 'a')['x']([1, 0, 1]) - sage: f.sylvester_matrix(g) + sage: h = GF(25, 'a')['x']([1, 0, 1]) # optional - sage.rings.finite_rings + sage: f.sylvester_matrix(g) # optional - sage.modules [1 0 1 0] [0 1 0 1] [1 0 1 0] [0 1 0 1] - sage: g.sylvester_matrix(h) + sage: g.sylvester_matrix(h) # optional - sage.rings.finite_rings sage.modules [1 0 1 0] [0 1 0 1] [1 0 1 0] [0 1 0 1] - sage: f.sylvester_matrix(h) + sage: f.sylvester_matrix(h) # optional - sage.rings.finite_rings sage.modules Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Univariate Polynomial Ring in x over Rational Field' and 'Univariate Polynomial Ring in x over Finite Field in a of size 5^2' + TypeError: no common canonical parent for objects with parents: + 'Univariate Polynomial Ring in x over Rational Field' and + 'Univariate Polynomial Ring in x over Finite Field in a of size 5^2' We can compute the sylvester matrix of a univariate and multivariate polynomial:: sage: K. = QQ['x,y'] sage: g = K.random_element() - sage: f.sylvester_matrix(g) == K(f).sylvester_matrix(g,x) + sage: f.sylvester_matrix(g) == K(f).sylvester_matrix(g, x) # optional - sage.modules True Corner cases:: - sage: K.=QQ[] - sage: f = x^2+1 + sage: K. = QQ[] + sage: f = x^2 + 1 sage: g = K(0) - sage: f.sylvester_matrix(g) + sage: f.sylvester_matrix(g) # optional - sage.modules Traceback (most recent call last): ... ValueError: The Sylvester matrix is not defined for zero polynomials - sage: g.sylvester_matrix(f) + sage: g.sylvester_matrix(f) # optional - sage.modules Traceback (most recent call last): ... ValueError: The Sylvester matrix is not defined for zero polynomials - sage: g.sylvester_matrix(g) + sage: g.sylvester_matrix(g) # optional - sage.modules Traceback (most recent call last): ... ValueError: The Sylvester matrix is not defined for zero polynomials - sage: K(3).sylvester_matrix(x^2) + sage: K(3).sylvester_matrix(x^2) # optional - sage.modules [3 0] [0 3] - sage: K(3).sylvester_matrix(K(4)) + sage: K(3).sylvester_matrix(K(4)) # optional - sage.modules [] """ @@ -5468,10 +5515,10 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: R. = PolynomialRing(GF(9,'a'), sparse=True) - sage: a = w._new_constant_poly(0, R); a + sage: R. = PolynomialRing(GF(9, 'a'), sparse=True) # optional - sage.rings.finite_rings + sage: a = w._new_constant_poly(0, R); a # optional - sage.rings.finite_rings 0 - sage: a.coefficients() + sage: a.coefficients() # optional - sage.rings.finite_rings [] """ t = type(self) @@ -5479,7 +5526,7 @@ cdef class Polynomial(CommutativePolynomial): def is_monic(self): """ - Returns True if this polynomial is monic. The zero polynomial is by + Returns ``True`` if this polynomial is monic. The zero polynomial is by definition not monic. EXAMPLES:: @@ -5506,7 +5553,7 @@ cdef class Polynomial(CommutativePolynomial): def is_unit(self): r""" - Return True if this polynomial is a unit. + Return ``True`` if this polynomial is a unit. EXAMPLES:: @@ -5514,12 +5561,12 @@ cdef class Polynomial(CommutativePolynomial): sage: b = a(2*191*236607587) sage: b.is_nilpotent() True - sage: R. = a[] - sage: f = 3 + b*x + b^2*x^2 - sage: f.is_unit() + sage: R. = a[] # optional - sage.libs.pari + sage: f = 3 + b*x + b^2*x^2 # optional - sage.libs.pari + sage: f.is_unit() # optional - sage.libs.pari True - sage: f = 3 + b*x + b^2*x^2 + 17*x^3 - sage: f.is_unit() + sage: f = 3 + b*x + b^2*x^2 + 17*x^3 # optional - sage.libs.pari + sage: f.is_unit() # optional - sage.libs.pari False EXERCISE (Atiyah-McDonald, Ch 1): Let `A[x]` be a @@ -5553,7 +5600,7 @@ cdef class Polynomial(CommutativePolynomial): def is_nilpotent(self): r""" - Return True if this polynomial is nilpotent. + Return ``True`` if this polynomial is nilpotent. EXAMPLES:: @@ -5588,7 +5635,7 @@ cdef class Polynomial(CommutativePolynomial): def is_gen(self): r""" - Return True if this polynomial is the distinguished generator of + Return ``True`` if this polynomial is the distinguished generator of the parent polynomial ring. EXAMPLES:: @@ -5599,8 +5646,8 @@ cdef class Polynomial(CommutativePolynomial): sage: R(x).is_gen() True - Important - this function doesn't return True if self equals the - generator; it returns True if self *is* the generator. + Important - this function doesn't return ``True`` if ``self`` equals the + generator; it returns ``True`` if ``self`` *is* the generator. :: @@ -5620,7 +5667,8 @@ cdef class Polynomial(CommutativePolynomial): Return the leading coefficient of this polynomial. OUTPUT: element of the base ring - This method is same as :meth:`leading_coefficient`. + + This method is the same as :meth:`leading_coefficient`. EXAMPLES:: @@ -5749,7 +5797,7 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: _. = PolynomialRing(ZZ) - sage: f = x^4+2*x^2+1 + sage: f = x^4 + 2*x^2 + 1 sage: f.coefficients() [1, 2, 1] sage: f.coefficients(sparse=False) @@ -5771,11 +5819,9 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - ``prec`` -- desired floating point precision (default: - default RealField precision). - - OUTPUT: + default :class:`RealField` precision). - - a real number. + OUTPUT: a real number. EXAMPLES:: @@ -5796,18 +5842,18 @@ cdef class Polynomial(CommutativePolynomial): :: - sage: R. = PolynomialRing(QQbar) - sage: f = QQbar(i)*x^2 + 3*x - sage: f.global_height() + sage: R. = PolynomialRing(QQbar) # optional - sage.rings.number_field + sage: f = QQbar(i)*x^2 + 3*x # optional - sage.rings.number_field + sage: f.global_height() # optional - sage.rings.number_field 1.09861228866811 :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^2 + 5) - sage: T. = PolynomialRing(K) - sage: f = 1/1331 * t^2 + 5 * t + 7 - sage: f.global_height() + sage: K. = NumberField(x^2 + 5) # optional - sage.rings.number_field + sage: T. = PolynomialRing(K) # optional - sage.rings.number_field + sage: f = 1/1331 * t^2 + 5 * t + 7 # optional - sage.rings.number_field + sage: f.global_height() # optional - sage.rings.number_field 9.13959596745043 :: @@ -5857,11 +5903,9 @@ cdef class Polynomial(CommutativePolynomial): - ``v`` -- a prime or prime ideal of the base ring. - ``prec`` -- desired floating point precision (default: - default RealField precision). - - OUTPUT: + default :class:`RealField` precision). - - a real number. + OUTPUT: a real number. EXAMPLES:: @@ -5873,11 +5917,11 @@ cdef class Polynomial(CommutativePolynomial): :: sage: R. = QQ[] - sage: K. = NumberField(x^2 - 5) - sage: T. = K[] - sage: I = K.ideal(3) - sage: f = 1/3*t^2 + 3 - sage: f.local_height(I) + sage: K. = NumberField(x^2 - 5) # optional - sage.rings.number_field + sage: T. = K[] # optional - sage.rings.number_field + sage: I = K.ideal(3) # optional - sage.rings.number_field + sage: f = 1/3*t^2 + 3 # optional - sage.rings.number_field + sage: f.local_height(I) # optional - sage.rings.number_field 1.09861228866811 :: @@ -5909,11 +5953,9 @@ cdef class Polynomial(CommutativePolynomial): - ``i`` -- an integer. - ``prec`` -- desired floating point precision (default: - default RealField precision). + default :class:`RealField` precision). - OUTPUT: - - - a real number. + OUTPUT: a real number. EXAMPLES:: @@ -5925,10 +5967,10 @@ cdef class Polynomial(CommutativePolynomial): :: sage: R. = QQ[] - sage: K. = NumberField(x^2 - 5) - sage: T. = K[] - sage: f = 1/2*t^2 + 3 - sage: f.local_height_arch(1, prec=52) + sage: K. = NumberField(x^2 - 5) # optional - sage.rings.number_field + sage: T. = K[] # optional - sage.rings.number_field + sage: f = 1/2*t^2 + 3 # optional - sage.rings.number_field + sage: f.local_height_arch(1, prec=52) # optional - sage.rings.number_field 1.09861228866811 :: @@ -5959,7 +6001,7 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: _. = PolynomialRing(ZZ) - sage: f = x^4+2*x^2+1 + sage: f = x^4 + 2*x^2 + 1 sage: f.exponents() [0, 2, 4] @@ -5983,7 +6025,7 @@ cdef class Polynomial(CommutativePolynomial): sage: v = f.list(); v [-1/3, 2, 0, -2/5] - Note that v is a list, it is mutable, and each call to the list + Note that ``v`` is a list, it is mutable, and each call to the :meth:`list` method returns a new list:: sage: type(v) @@ -5996,7 +6038,7 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: S. = R[] - sage: f = y^3 + x*y -3*x; f + sage: f = y^3 + x*y - 3*x; f y^3 + x*y - 3*x sage: type(f) @@ -6026,7 +6068,7 @@ cdef class Polynomial(CommutativePolynomial): def padded_list(self, n=None): """ - Return list of coefficients of self up to (but not including) + Return list of coefficients of ``self`` up to (but not including) `q^n`. Includes 0's in the list on the right so that the list has length @@ -6086,15 +6128,11 @@ cdef class Polynomial(CommutativePolynomial): - ``m`` - a monomial - OUTPUT: - - Coefficient in base ring. + OUTPUT: Coefficient in base ring. EXAMPLES:: sage: P. = QQ[] - - The parent of the return is a member of the base ring. sage: f = 2 * x sage: c = f.monomial_coefficient(x); c 2 @@ -6145,11 +6183,11 @@ cdef class Polynomial(CommutativePolynomial): sage: f = - 1/2*x^2 + x^9 + 7*x + 5/11 sage: f.monomials() [x^9, x^2, x, 1] - sage: x = var('x') - sage: K. = NumberField(x**2 + 1) - sage: R. = QQ[] - sage: p = rho*y - sage: p.monomials() + sage: x = polygen(ZZ, 'x') + sage: K. = NumberField(x**2 + 1) # optional - sage.rings.number_field + sage: R. = QQ[] # optional - sage.rings.number_field + sage: p = rho * y # optional - sage.rings.number_field + sage: p.monomials() # optional - sage.rings.number_field [y] """ if self.is_zero(): @@ -6165,22 +6203,22 @@ cdef class Polynomial(CommutativePolynomial): polynomial, computed using the Newton-Raphson method. The Newton-Raphson method is an iterative root-finding algorithm. - For f(x) a polynomial, as is the case here, this is essentially the + For `f(x)` a polynomial, as is the case here, this is essentially the same as Horner's method. INPUT: - - ``n`` - an integer (=the number of iterations), + - ``n`` - an integer (the number of iterations), - - ``x0`` - an initial guess x0. + - ``x0`` - an initial guess `x_0`. OUTPUT: A list of numbers hopefully approximating a root of - f(x)=0. + `f(x)=0`. - If one of the iterates is a critical point of f then a - ZeroDivisionError exception is raised. + If one of the iterates is a critical point of `f`, a + :class:`ZeroDivisionError` exception is raised. EXAMPLES:: @@ -6205,17 +6243,17 @@ cdef class Polynomial(CommutativePolynomial): def polynomial(self, var): r""" - Let var be one of the variables of the parent of self. This returns - self viewed as a univariate polynomial in var over the polynomial + Let ``var`` be one of the variables of the parent of ``self``. This returns + ``self`` viewed as a univariate polynomial in ``var`` over the polynomial ring generated by all the other variables of the parent. - For univariate polynomials, if var is the generator of the parent + For univariate polynomials, if ``var`` is the generator of the parent ring, we return this polynomial, otherwise raise an error. EXAMPLES:: sage: R. = QQ[] - sage: (x+1).polynomial(x) + sage: (x + 1).polynomial(x) x + 1 TESTS:: @@ -6233,31 +6271,31 @@ cdef class Polynomial(CommutativePolynomial): def newton_slopes(self, p, lengths=False): """ - Return the `p`-adic slopes of the Newton polygon of self, + Return the `p`-adic slopes of the Newton polygon of ``self``, when this makes sense. OUTPUT: - If `lengths` is `False`, a list of rational numbers. If `lengths` is - `True`, a list of couples `(s,l)` where `s` is the slope and `l` the + If ``lengths`` is ``False``, a list of rational numbers. If ``lengths`` is + ``True``, a list of couples `(s,l)` where `s` is the slope and `l` the length of the corresponding segment in the Newton polygon. EXAMPLES:: sage: x = QQ['x'].0 sage: f = x^3 + 2 - sage: f.newton_slopes(2) + sage: f.newton_slopes(2) # optional - sage.libs.pari [1/3, 1/3, 1/3] sage: R. = PolynomialRing(ZZ, sparse=True) sage: p = x^5 + 6*x^2 + 4 - sage: p.newton_slopes(2) + sage: p.newton_slopes(2) # optional - sage.libs.pari [1/2, 1/2, 1/3, 1/3, 1/3] sage: p.newton_slopes(2, lengths=True) [(1/2, 2), (1/3, 3)] sage: (x^2^100 + 27).newton_slopes(3, lengths=True) [(3/1267650600228229401496703205376, 1267650600228229401496703205376)] - ALGORITHM: Uses PARI if `lengths` is `False`. + ALGORITHM: Uses PARI if ``lengths`` is ``False``. """ if not lengths: f = self.__pari__() @@ -6307,13 +6345,13 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: Pol. = QQ[] - sage: x.dispersion_set(x + 1) + sage: x.dispersion_set(x + 1) # optional - sage.libs.pari [1] - sage: (x + 1).dispersion_set(x) + sage: (x + 1).dispersion_set(x) # optional - sage.libs.pari [] sage: pol = x^3 + x - 7 - sage: (pol*pol(x+3)^2).dispersion_set() + sage: (pol*pol(x+3)^2).dispersion_set() # optional - sage.libs.pari [0, 3] """ other = self if other is None else self._parent.coerce(other) @@ -6354,16 +6392,16 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: Pol. = QQ[] - sage: x.dispersion(x + 1) + sage: x.dispersion(x + 1) # optional - sage.libs.pari 1 - sage: (x + 1).dispersion(x) + sage: (x + 1).dispersion(x) # optional - sage.libs.pari -Infinity - sage: Pol. = QQbar[] - sage: pol = Pol([sqrt(5), 1, 3/2]) - sage: pol.dispersion() + sage: Pol. = QQbar[] # optional - sage.libs.pari sage.rings.number_field + sage: pol = Pol([sqrt(5), 1, 3/2]) # optional - sage.libs.pari sage.rings.number_field sage.symbolic + sage: pol.dispersion() # optional - sage.libs.pari sage.rings.number_field sage.symbolic 0 - sage: (pol*pol(x+3)).dispersion() + sage: (pol*pol(x+3)).dispersion() # optional - sage.libs.pari sage.rings.number_field sage.symbolic 3 """ dispersions = self.dispersion_set(other) @@ -6384,7 +6422,7 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: f = QQ['x']([0,1,2/3,3]) - sage: pari(f) + sage: pari(f) # optional - sage.libs.pari 3*x^3 + 2/3*x^2 + x :: @@ -6392,19 +6430,20 @@ cdef class Polynomial(CommutativePolynomial): sage: S. = QQ['a'] sage: R. = S['x'] sage: f = R([0, a]) + R([0, 0, 2/3]) - sage: pari(f) + sage: pari(f) # optional - sage.libs.pari 2/3*x^2 + a*x Polynomials over a number field work, provided that the variable is called 'x':: sage: x = polygen(QQ) - sage: K. = NumberField(x^2 + x + 1) - sage: R. = PolynomialRing(K) - sage: pol = (b + x)^3; pol + sage: K. = NumberField(x^2 + x + 1) # optional - sage.rings.number_field + sage: R. = PolynomialRing(K) # optional - sage.rings.number_field + sage: pol = (b + x)^3; pol # optional - sage.rings.number_field x^3 + 3*b*x^2 + (-3*b - 3)*x + 1 - sage: pari(pol) - Mod(1, y^2 + y + 1)*x^3 + Mod(3*y, y^2 + y + 1)*x^2 + Mod(-3*y - 3, y^2 + y + 1)*x + Mod(1, y^2 + y + 1) + sage: pari(pol) # optional - sage.libs.pari sage.rings.number_field + Mod(1, y^2 + y + 1)*x^3 + Mod(3*y, y^2 + y + 1)*x^2 + + Mod(-3*y - 3, y^2 + y + 1)*x + Mod(1, y^2 + y + 1) TESTS: @@ -6413,7 +6452,7 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: S. = R[] sage: f = x^2 + a; g = y^3 + a - sage: pari(f) + sage: pari(f) # optional - sage.libs.pari Traceback (most recent call last): ... PariError: incorrect priority in gtopoly: variable x <= a @@ -6423,9 +6462,9 @@ cdef class Polynomial(CommutativePolynomial): sage: S. = QQ['a'] sage: R. = S['x'] - sage: pari(x^2 + 2*x) + sage: pari(x^2 + 2*x) # optional - sage.libs.pari x^2 + 2*x - sage: pari(a*x + 2*x^3) + sage: pari(a*x + 2*x^3) # optional - sage.libs.pari 2*x^3 + a*x Stacked polynomial rings, second with a multivariate ring on the @@ -6433,27 +6472,27 @@ cdef class Polynomial(CommutativePolynomial): sage: S. = ZZ['a', 'b'] sage: R. = S['x'] - sage: pari(x^2 + 2*x) + sage: pari(x^2 + 2*x) # optional - sage.libs.pari x^2 + 2*x - sage: pari(a*x + 2*b*x^3) + sage: pari(a*x + 2*b*x^3) # optional - sage.libs.pari 2*b*x^3 + a*x Stacked polynomial rings with exotic base rings:: - sage: S. = GF(7)['a', 'b'] - sage: R. = S['x'] - sage: pari(x^2 + 9*x) + sage: S. = GF(7)['a', 'b'] # optional - sage.rings.finite_rings + sage: R. = S['x'] # optional - sage.rings.finite_rings + sage: pari(x^2 + 9*x) # optional - sage.rings.finite_rings x^2 + 2*x - sage: pari(a*x + 9*b*x^3) + sage: pari(a*x + 9*b*x^3) # optional - sage.rings.finite_rings 2*b*x^3 + a*x :: sage: S. = Integers(8)['a'] sage: R. = S['x'] - sage: pari(x^2 + 2*x) + sage: pari(x^2 + 2*x) # optional - sage.libs.pari Mod(1, 8)*x^2 + Mod(2, 8)*x - sage: pari(a*x + 10*x^3) + sage: pari(a*x + 10*x^3) # optional - sage.libs.pari Mod(2, 8)*x^3 + Mod(1, 8)*a*x """ return self._pari_with_name(self._parent.variable_name()) @@ -6474,18 +6513,18 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = PolynomialRing(ZZ) sage: pol = 2*x^2 + 7*x - 5 - sage: pol._pari_or_constant() + sage: pol._pari_or_constant() # optional - sage.libs.pari 2*x^2 + 7*x - 5 - sage: pol._pari_or_constant('a') + sage: pol._pari_or_constant('a') # optional - sage.libs.pari 2*a^2 + 7*a - 5 sage: pol = R(7) - sage: pol._pari_or_constant() + sage: pol._pari_or_constant() # optional - sage.libs.pari 7 - sage: pol._pari_or_constant().type() + sage: pol._pari_or_constant().type() # optional - sage.libs.pari 't_INT' - sage: pol.__pari__().type() + sage: pol.__pari__().type() # optional - sage.libs.pari 't_POL' - sage: PolynomialRing(IntegerModRing(101), 't')()._pari_or_constant() + sage: PolynomialRing(IntegerModRing(101), 't')()._pari_or_constant() # optional - sage.libs.pari Mod(0, 101) """ if self.is_constant(): @@ -6504,9 +6543,9 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: (2*a^2 + a)._pari_with_name() + sage: (2*a^2 + a)._pari_with_name() # optional - sage.libs.pari 2*x^2 + x - sage: (2*a^2 + a)._pari_with_name('y') + sage: (2*a^2 + a)._pari_with_name('y') # optional - sage.libs.pari 2*y^2 + y """ vals = [x.__pari__() for x in self.list()] @@ -6521,7 +6560,7 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: magma = Magma() # new session + sage: magma = Magma() # new session # optional - magma sage: R. = ZZ[] sage: f = y^3 - 17*y + 5 sage: f._magma_init_(magma) # optional - magma @@ -6547,8 +6586,8 @@ cdef class Polynomial(CommutativePolynomial): A more complicated nested example:: - sage: k. = GF(9); R. = k[]; S. = R[] - sage: magma(a*W^20 + s*t/a) # optional - magma + sage: k. = GF(9); R. = k[]; S. = R[] # optional - sage.rings.finite_rings + sage: magma(a*W^20 + s*t/a) # optional - magma # optional - sage.rings.finite_rings a*W^20 + a^7*s*t """ # Get a reference to Magma version of parent. @@ -6569,33 +6608,33 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = ZZ[] sage: f = y^3 - 17*y + 5 - sage: g = gap(f); g # indirect doctest + sage: g = gap(f); g # indirect doctest # optional - sage.libs.gap y^3-17*y+5 - sage: f._gap_init_() + sage: f._gap_init_() # optional - sage.libs.gap 'y^3 - 17*y + 5' sage: R. = ZZ[] - sage: gap(R) + sage: gap(R) # optional - sage.libs.gap PolynomialRing( Integers, ["z"] ) - sage: g + sage: g # optional - sage.libs.gap y^3-17*y+5 - sage: gap(z^2 + z) + sage: gap(z^2 + z) # optional - sage.libs.gap z^2+z - sage: libgap(z^2 + z) + sage: libgap(z^2 + z) # optional - sage.libs.gap z^2+z Coefficients in a finite field:: - sage: R. = GF(7)[] - sage: f = y^3 - 17*y + 5 - sage: g = gap(f); g + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: f = y^3 - 17*y + 5 # optional - sage.rings.finite_rings + sage: g = gap(f); g # optional - sage.libs.gap sage.rings.finite_rings y^3+Z(7)^4*y+Z(7)^5 - sage: h = libgap(f); h + sage: h = libgap(f); h # optional - sage.libs.gap sage.rings.finite_rings y^3+Z(7)^4*y+Z(7)^5 - sage: g.Factors() + sage: g.Factors() # optional - sage.libs.gap sage.rings.finite_rings [ y+Z(7)^0, y+Z(7)^0, y+Z(7)^5 ] - sage: h.Factors() + sage: h.Factors() # optional - sage.libs.gap sage.rings.finite_rings [ y+Z(7)^0, y+Z(7)^0, y+Z(7)^5 ] - sage: f.factor() + sage: f.factor() # optional - sage.libs.gap sage.rings.finite_rings (y + 5) * (y + 1)^2 """ R = gap(self._parent) @@ -6607,9 +6646,9 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: sage: R. = ZZ[] - sage: libgap(-x^3 + 3*x) # indirect doctest + sage: libgap(-x^3 + 3*x) # indirect doctest # optional - sage.libs.gap -x^3+3*x - sage: libgap(R.zero()) # indirect doctest + sage: libgap(R.zero()) # indirect doctest # optional - sage.libs.gap 0 """ from sage.libs.gap.libgap import libgap @@ -6621,13 +6660,13 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: - sage: R. = GF(101)['e,i'][] - sage: f = R('e*i') * x + x^2 - sage: f._giac_init_() + sage: R. = GF(101)['e,i'][] # optional - sage.rings.finite_rings + sage: f = R('e*i') * x + x^2 # optional - sage.rings.finite_rings + sage: f._giac_init_() # optional - sage.rings.finite_rings '((1)*1)*sageVARx^2+((1)*sageVARe*sageVARi)*sageVARx' - sage: giac(f) + sage: giac(f) # optional - sage.rings.finite_rings sageVARx^2+sageVARe*sageVARi*sageVARx - sage: giac(R.zero()) + sage: giac(R.zero()) # optional - sage.rings.finite_rings 0 """ g = 'sageVAR' + self.variable_name() @@ -6650,7 +6689,7 @@ cdef class Polynomial(CommutativePolynomial): ALGORITHM: - Uses PARI's ``polresultant`` function. For base rings that + Uses PARI's function :pari:`polresultant`. For base rings that are not supported by PARI, the resultant is computed as the determinant of the Sylvester matrix. @@ -6658,9 +6697,9 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: f = x^3 + x + 1; g = x^3 - x - 1 - sage: r = f.resultant(g); r + sage: r = f.resultant(g); r # optional - sage.libs.pari -8 - sage: r.parent() is QQ + sage: r.parent() is QQ # optional - sage.libs.pari True We can compute resultants over univariate and multivariate @@ -6669,9 +6708,9 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: S. = R[] sage: f = x^2 + a; g = x^3 + a - sage: r = f.resultant(g); r + sage: r = f.resultant(g); r # optional - sage.libs.pari a^3 + a^2 - sage: r.parent() is R + sage: r.parent() is R # optional - sage.libs.pari True :: @@ -6679,9 +6718,9 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: S. = R[] sage: f = x^2 + a; g = x^3 + b - sage: r = f.resultant(g); r + sage: r = f.resultant(g); r # optional - sage.libs.pari a^3 + b^2 - sage: r.parent() is R + sage: r.parent() is R # optional - sage.libs.pari True TESTS:: @@ -6689,18 +6728,18 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: S. = R[] sage: f = x^2 + a; g = y^3 + a - sage: h = f.resultant(g); h + sage: h = f.resultant(g); h # optional - sage.libs.pari y^3 - x^2 - sage: h.parent() is R + sage: h.parent() is R # optional - sage.libs.pari True Check that :trac:`13672` is fixed:: - sage: R. = GF(2)[] - sage: S. = R[] - sage: f = (t^2 + t)*x + t^2 + t - sage: g = (t + 1)*x + t^2 - sage: f.resultant(g) + sage: R. = GF(2)[] # optional - sage.rings.finite_rings + sage: S. = R[] # optional - sage.rings.finite_rings + sage: f = (t^2 + t)*x + t^2 + t # optional - sage.rings.finite_rings + sage: g = (t + 1)*x + t^2 # optional - sage.rings.finite_rings + sage: f.resultant(g) # optional - sage.rings.finite_rings t^4 + t Check that :trac:`15061` is fixed:: @@ -6709,23 +6748,23 @@ cdef class Polynomial(CommutativePolynomial): sage: F = R([1,1],2) sage: RP. = PolynomialRing(R) sage: P = x^2 - F - sage: P.resultant(P.derivative()) + sage: P.resultant(P.derivative()) # optional - sage.libs.pari -4 - 4*T + O(T^2) Check that :trac:`16360` is fixed:: sage: K. = FunctionField(QQ) sage: R. = K[] - sage: y.resultant(y+x) + sage: y.resultant(y + x) # optional - sage.libs.pari x sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(b^2-a) - sage: R. = L[] - sage: f=x^2-a - sage: g=x-b - sage: f.resultant(g) + sage: L. = K.extension(b^2 - a) # optional - sage.libs.singular + sage: R. = L[] # optional - sage.libs.singular + sage: f = x^2 - a # optional - sage.libs.singular + sage: g = x - b # optional - sage.libs.singular + sage: f.resultant(g) # optional - sage.libs.pari sage.libs.singular 0 Check that :trac:`17817` is fixed:: @@ -6736,7 +6775,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) + sage: p.resultant(q) # optional - sage.libs.pari (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 @@ -6745,7 +6784,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) # optional - sage.libs.pari 133.92599999999996 + 37.56999999999999*I """ variable = self.variable_name() @@ -6769,8 +6808,8 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: R. = ZZ[] - sage: f = x^8 + x^6 -3*x^4 -3*x^3 +8*x^2 +2*x -5 - sage: g = 3*x^6 +5*x^4 -4*x^2 -9*x +21 + sage: f = x^8 + x^6 - 3*x^4 - 3*x^3 + 8*x^2 + 2*x - 5 + sage: g = 3*x^6 + 5*x^4 - 4*x^2 - 9*x + 21 sage: f.subresultants(g) [260708, 9326*x - 12300, @@ -6848,8 +6887,8 @@ cdef class Polynomial(CommutativePolynomial): where the roots `a` and `b` are to be considered in the algebraic closure of the fraction field of the coefficients and counted with multiplicities. If the polynomials are not monic this quantity is - multiplied by `\\alpha_1^{deg(p_2)} \\alpha_2^{deg(p_1)}` where - `\\alpha_1` and `\\alpha_2` are the leading coefficients of `p_1` and + multiplied by `\alpha_1^{\deg(p_2)} \alpha_2^{\deg(p_1)}` where + `\alpha_1` and `\alpha_2` are the leading coefficients of `p_1` and `p_2` respectively. INPUT: @@ -6860,7 +6899,7 @@ cdef class Polynomial(CommutativePolynomial): - ``op`` -- ``operator.OP`` where ``OP=add`` or ``sub`` or ``mul`` or ``truediv``. - - ``algorithm`` -- can be "resultant" or "BFSS"; + - ``algorithm`` -- can be ``"resultant"`` or ``"BFSS"``; by default the former is used when the polynomials have few nonzero coefficients and small degrees or if the base ring is not `\ZZ` or `\QQ`. Otherwise the latter is used. @@ -6872,7 +6911,7 @@ cdef class Polynomial(CommutativePolynomial): ALGORITHM: The computation is straightforward using resultants. Indeed for the - composed sum it would be `Res_y(p1(x-y), p2(y))`. However, the method + composed sum it would be `Res_y(p_1(x-y), p_2(y))`. However, the method from [BFSS2006]_ using series expansions is asymptotically much faster. Note that the algorithm ``BFSS`` with polynomials with coefficients in @@ -6895,48 +6934,45 @@ cdef class Polynomial(CommutativePolynomial): sage: x = polygen(ZZ) sage: p1 = x^2 - 1 sage: p2 = x^4 - 1 - sage: p1.composed_op(p2, operator.add) + sage: p1.composed_op(p2, operator.add) # optional - sage.libs.singular x^8 - 4*x^6 + 4*x^4 - 16*x^2 - sage: p1.composed_op(p2, operator.mul) + sage: p1.composed_op(p2, operator.mul) # optional - sage.libs.singular x^8 - 2*x^4 + 1 - sage: p1.composed_op(p2, operator.truediv) + sage: p1.composed_op(p2, operator.truediv) # optional - sage.libs.singular x^8 - 2*x^4 + 1 This function works over any field. However for base rings other than `\ZZ` and `\QQ` only the resultant algorithm is available:: - sage: x = polygen(QQbar) - sage: p1 = x**2 - AA(2).sqrt() - sage: p2 = x**3 - AA(3).sqrt() - sage: r1 = p1.roots(multiplicities=False) - sage: r2 = p2.roots(multiplicities=False) - sage: p = p1.composed_op(p2, operator.add) - sage: p - x^6 - 4.242640687119285?*x^4 - 3.464101615137755?*x^3 + 6*x^2 - 14.69693845669907?*x + 0.1715728752538099? - sage: all(p(x+y).is_zero() for x in r1 for y in r2) - True - - sage: x = polygen(GF(2)) - sage: p1 = x**2 + x - 1 - sage: p2 = x**3 + x - 1 - sage: p_add = p1.composed_op(p2, operator.add) - sage: p_add + sage: x = polygen(QQbar) # optional - sage.rings.number_field + sage: p1 = x**2 - AA(2).sqrt() # optional - sage.rings.number_field + sage: p2 = x**3 - AA(3).sqrt() # optional - sage.rings.number_field + sage: r1 = p1.roots(multiplicities=False) # optional - sage.rings.number_field + sage: r2 = p2.roots(multiplicities=False) # optional - sage.rings.number_field + sage: p = p1.composed_op(p2, operator.add); p # optional - sage.rings.number_field + x^6 - 4.242640687119285?*x^4 - 3.464101615137755?*x^3 + 6*x^2 + - 14.69693845669907?*x + 0.1715728752538099? + sage: all(p(x+y).is_zero() for x in r1 for y in r2) # optional - sage.rings.number_field + True + + sage: x = polygen(GF(2)) # optional - sage.rings.finite_rings + sage: p1 = x**2 + x - 1 # optional - sage.rings.finite_rings + sage: p2 = x**3 + x - 1 # optional - sage.rings.finite_rings + sage: p_add = p1.composed_op(p2, operator.add); p_add # optional - sage.rings.finite_rings x^6 + x^5 + x^3 + x^2 + 1 - sage: p_mul = p1.composed_op(p2, operator.mul) - sage: p_mul + sage: p_mul = p1.composed_op(p2, operator.mul); p_mul # optional - sage.rings.finite_rings x^6 + x^4 + x^2 + x + 1 - sage: p_div = p1.composed_op(p2, operator.truediv) - sage: p_div + sage: p_div = p1.composed_op(p2, operator.truediv); p_div # optional - sage.rings.finite_rings x^6 + x^5 + x^4 + x^2 + 1 - sage: K = GF(2**6, 'a') - sage: r1 = p1.roots(K, multiplicities=False) - sage: r2 = p2.roots(K, multiplicities=False) - sage: all(p_add(x1+x2).is_zero() for x1 in r1 for x2 in r2) + sage: K = GF(2**6, 'a') # optional - sage.rings.finite_rings + sage: r1 = p1.roots(K, multiplicities=False) # optional - sage.rings.finite_rings + sage: r2 = p2.roots(K, multiplicities=False) # optional - sage.rings.finite_rings + sage: all(p_add(x1+x2).is_zero() for x1 in r1 for x2 in r2) # optional - sage.rings.finite_rings True - sage: all(p_mul(x1*x2).is_zero() for x1 in r1 for x2 in r2) + sage: all(p_mul(x1*x2).is_zero() for x1 in r1 for x2 in r2) # optional - sage.rings.finite_rings True - sage: all(p_div(x1/x2).is_zero() for x1 in r1 for x2 in r2) + sage: all(p_div(x1/x2).is_zero() for x1 in r1 for x2 in r2) # optional - sage.rings.finite_rings True TESTS: @@ -6944,7 +6980,7 @@ cdef class Polynomial(CommutativePolynomial): :: sage: y = polygen(ZZ) - sage: for p1 in [2*y^3 - y + 3, -y^5 - 2, 4*y - 3]: + sage: for p1 in [2*y^3 - y + 3, -y^5 - 2, 4*y - 3]: # optional - sage.libs.singular ....: for p2 in [5*y^2 - 7, -3*y - 1]: ....: for monic in [True,False]: ....: for op in [operator.add, operator.sub, operator.mul, operator.truediv]: @@ -7085,28 +7121,28 @@ cdef class Polynomial(CommutativePolynomial): The polynomial of degree `d^k` where `d` is the degree, whose roots are all `k`-fold products of roots of this polynomial. That is, `f*f*\dots*f` where this is `f` and - `f*f=` f.composed_op(f,operator.mul). + `f*f=` ``f.composed_op(f, operator.mul)``. EXAMPLES:: sage: R. = ZZ[] sage: x = polygen(R) - sage: f = (x-a)*(x-b)*(x-c) - sage: f.compose_power(2).factor() + sage: f = (x - a) * (x - b) * (x - c) + sage: f.compose_power(2).factor() # optional - sage.libs.singular sage.modules (x - c^2) * (x - b^2) * (x - a^2) * (x - b*c)^2 * (x - a*c)^2 * (x - a*b)^2 sage: x = polygen(QQ) - sage: f = x^2-2*x+2 + sage: f = x^2 - 2*x + 2 sage: f2 = f.compose_power(2); f2 x^4 - 4*x^3 + 8*x^2 - 16*x + 16 - sage: f2 == f.composed_op(f,operator.mul) + sage: f2 == f.composed_op(f, operator.mul) # optional - sage.libs.singular sage.modules True - sage: f3 = f.compose_power(3); f3 + sage: f3 = f.compose_power(3); f3 # optional - sage.libs.singular sage.modules x^8 - 8*x^7 + 32*x^6 - 64*x^5 + 128*x^4 - 512*x^3 + 2048*x^2 - 4096*x + 4096 - sage: f3 == f2.composed_op(f,operator.mul) + sage: f3 == f2.composed_op(f, operator.mul) # optional - sage.libs.singular sage.modules True - sage: f4 = f.compose_power(4) - sage: f4 == f3.composed_op(f,operator.mul) + sage: f4 = f.compose_power(4) # optional - sage.libs.singular sage.modules + sage: f4 == f3.composed_op(f, operator.mul) # optional - sage.libs.singular sage.modules True """ try: @@ -7146,33 +7182,33 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: f = cyclotomic_polynomial(30) - sage: f.adams_operator(7)==f + sage: f = cyclotomic_polynomial(30) # optional - sage.libs.pari + sage: f.adams_operator(7)==f # optional - sage.libs.pari True - sage: f.adams_operator(6) == cyclotomic_polynomial(5)**2 + sage: f.adams_operator(6) == cyclotomic_polynomial(5)**2 # optional - sage.libs.pari True - sage: f.adams_operator(10) == cyclotomic_polynomial(3)**4 + sage: f.adams_operator(10) == cyclotomic_polynomial(3)**4 # optional - sage.libs.pari True - sage: f.adams_operator(15) == cyclotomic_polynomial(2)**8 + sage: f.adams_operator(15) == cyclotomic_polynomial(2)**8 # optional - sage.libs.pari True - sage: f.adams_operator(30) == cyclotomic_polynomial(1)**8 + sage: f.adams_operator(30) == cyclotomic_polynomial(1)**8 # optional - sage.libs.pari True sage: x = polygen(QQ) - sage: f = x^2-2*x+2 - sage: f.adams_operator(10) + sage: f = x^2 - 2*x + 2 + sage: f.adams_operator(10) # optional - sage.libs.singular x^2 + 1024 - When f is monic the output will have leading coefficient + When ``self`` is monic, the output will have leading coefficient `\pm1` depending on the degree, but we can force it to be monic:: sage: R. = ZZ[] sage: x = polygen(R) - sage: f = (x-a)*(x-b)*(x-c) - sage: f.adams_operator(3).factor() + sage: f = (x - a) * (x - b) * (x - c) + sage: f.adams_operator(3).factor() # optional - sage.libs.singular (-1) * (x - c^3) * (x - b^3) * (x - a^3) - sage: f.adams_operator(3,monic=True).factor() + sage: f.adams_operator(3, monic=True).factor() # optional - sage.libs.singular (x - c^3) * (x - b^3) * (x - a^3) """ @@ -7191,12 +7227,12 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: x = polygen(QQ) - sage: f = x^4-x+2 - sage: [f.symmetric_power(k) for k in range(5)] + sage: f = x^4 - x + 2 + sage: [f.symmetric_power(k) for k in range(5)] # optional - sage.libs.singular [x - 1, x^4 - x + 2, x^6 - 2*x^4 - x^3 - 4*x^2 + 8, x^4 - x^3 + 8, x - 2] - sage: f = x^5-2*x+2 - sage: [f.symmetric_power(k) for k in range(6)] + sage: f = x^5 - 2*x + 2 + sage: [f.symmetric_power(k) for k in range(6)] # optional - sage.libs.singular [x - 1, x^5 - 2*x + 2, x^10 + 2*x^8 - 4*x^6 - 8*x^5 - 8*x^4 - 8*x^3 + 16, @@ -7206,8 +7242,8 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = ZZ[] sage: x = polygen(R) - sage: f = (x-a)*(x-b)*(x-c)*(x-d) - sage: [f.symmetric_power(k).factor() for k in range(5)] + sage: f = (x - a) * (x - b) * (x - c) * (x - d) + sage: [f.symmetric_power(k).factor() for k in range(5)] # optional - sage.libs.singular [x - 1, (-x + d) * (-x + c) * (-x + b) * (-x + a), (x - c*d) * (x - b*d) * (x - a*d) * (x - b*c) * (x - a*c) * (x - a*b), @@ -7282,8 +7318,8 @@ cdef class Polynomial(CommutativePolynomial): R_n := a_n^{2 n-2} \prod_{1 = QQ[] sage: f = x^3 + x + 1 - sage: d = f.discriminant(); d + sage: d = f.discriminant(); d # optional - sage.libs.pari -31 - sage: d.parent() is QQ + sage: d.parent() is QQ # optional - sage.libs.pari True - sage: EllipticCurve([1, 1]).discriminant()/16 + sage: EllipticCurve([1, 1]).discriminant()/16 # optional - sage.libs.pari -31 :: sage: R. = QQ[] sage: f = 2*x^3 + x + 1 - sage: d = f.discriminant(); d + sage: d = f.discriminant(); d # optional - sage.libs.pari -116 We can compute discriminants over univariate and multivariate @@ -7322,9 +7358,9 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: S. = R[] sage: f = a*x + x + a + 1 - sage: d = f.discriminant(); d + sage: d = f.discriminant(); d # optional - sage.libs.pari 1 - sage: d.parent() is R + sage: d.parent() is R # optional - sage.libs.pari True :: @@ -7332,9 +7368,9 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: S. = R[] sage: f = x^2 + a + b - sage: d = f.discriminant(); d + sage: d = f.discriminant(); d # optional - sage.libs.pari -4*a - 4*b - sage: d.parent() is R + sage: d.parent() is R # optional - sage.libs.pari True TESTS:: @@ -7342,41 +7378,41 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: S. = R[] sage: f = x^2 + a - sage: f.discriminant() + sage: f.discriminant() # optional - sage.libs.pari 1 Check that :trac:`13672` is fixed:: - sage: R. = GF(5)[] - sage: S. = R[] - sage: f = x^10 + 2*x^6 + 2*x^5 + x + 2 - sage: (f-t).discriminant() + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: S. = R[] # optional - sage.rings.finite_rings + sage: f = x^10 + 2*x^6 + 2*x^5 + x + 2 # optional - sage.rings.finite_rings + sage: (f - t).discriminant() # optional - sage.rings.finite_rings 4*t^5 The following examples show that :trac:`11782` has been fixed:: - sage: var('x') + sage: var('x') # optional - sage.symbolic x - sage: ZZ.quo(81)['x'](3*x^2 + 3*x + 3).discriminant() + sage: ZZ.quo(81)['x'](3*x^2 + 3*x + 3).discriminant() # optional - sage.libs.pari sage.symbolic 54 - sage: ZZ.quo(9)['x'](2*x^3 + x^2 + x).discriminant() + sage: ZZ.quo(9)['x'](2*x^3 + x^2 + x).discriminant() # optional - sage.libs.pari sage.symbolic 2 This was fixed by :trac:`15422`:: - sage: R. = PolynomialRing(Qp(2)) - sage: (s^2).discriminant() + sage: R. = PolynomialRing(Qp(2)) # optional - sage.rings.padics + sage: (s^2).discriminant() # optional - sage.rings.padics 0 This was fixed by :trac:`16014`:: sage: PR. = QQ[] sage: PRmu. = PR[] - sage: E1 = diagonal_matrix(PR, [1, b^2, -b^2]) - sage: M = matrix(PR, [[1,-t1,x1-t1*y1],[t1,1,y1+t1*x1],[0,0,1]]) - sage: E1 = M.transpose()*E1*M - sage: E2 = E1.subs(t1=t2, x1=x2, y1=y2) - sage: det(mu*E1 + E2).discriminant().degrees() + sage: E1 = diagonal_matrix(PR, [1, b^2, -b^2]) # optional - sage.modules + sage: M = matrix(PR, [[1,-t1,x1-t1*y1], [t1,1,y1+t1*x1], [0,0,1]]) # optional - sage.modules + sage: E1 = M.transpose()*E1*M # optional - sage.modules + sage: E2 = E1.subs(t1=t2, x1=x2, y1=y2) # optional - sage.modules + sage: det(mu*E1 + E2).discriminant().degrees() # optional - sage.modules sage.libs.pari (24, 12, 12, 8, 8, 8, 8) This addresses an issue raised by :trac:`15061`:: @@ -7385,7 +7421,7 @@ cdef class Polynomial(CommutativePolynomial): sage: F = R([1,1],2) sage: RP. = PolynomialRing(R) sage: P = x^2 - F - sage: P.discriminant() + sage: P.discriminant() # optional - sage.libs.pari 4 + 4*T + O(T^2) """ # Late import to avoid cyclic dependencies: @@ -7424,7 +7460,7 @@ cdef class Polynomial(CommutativePolynomial): """ Return polynomial but with the coefficients reversed. - If an optional degree argument is given the coefficient list will be + If an optional ``degree`` argument is given, the coefficient list will be truncated or zero padded as necessary before reversing it. Assuming that the constant coefficient of ``self`` is nonzero, the reverse polynomial will have the specified degree. @@ -7432,7 +7468,7 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: R. = ZZ[]; S. = R[] - sage: f = y^3 + x*y -3*x; f + sage: f = y^3 + x*y - 3*x; f y^3 + x*y - 3*x sage: f.reverse() -3*x*y^3 + x*y^2 + 1 @@ -7483,9 +7519,9 @@ cdef class Polynomial(CommutativePolynomial): - ``ring`` - the ring to find roots in - - ``multiplicities`` - bool (default: True) if True - return list of pairs (r, n), where r is the root and n is the - multiplicity. If False, just return the unique roots, with no + - ``multiplicities`` - bool (default: ``True``) if ``True`` + return list of pairs `(r, n)`, where `r` is the root and `n` is the + multiplicity. If ``False``, just return the unique roots, with no information about multiplicities. - ``algorithm`` - the root-finding algorithm to use. @@ -7514,7 +7550,7 @@ cdef class Polynomial(CommutativePolynomial): always ill-conditioned; there's a footnote at the end of the docstring about this. - If the output ring is a RealIntervalField or ComplexIntervalField + If the output ring is a :class:`RealIntervalField` or :class:`ComplexIntervalField` of a given precision, then the answer will always be correct (or an exception will be raised, if a case is not implemented). Each root will be contained in one of the returned intervals, and the @@ -7523,53 +7559,56 @@ cdef class Polynomial(CommutativePolynomial): At the end of this docstring (after the examples) is a description of all the cases implemented in this function, and the algorithms - used. That section also describes the possibilities for - "algorithm=", for the cases where multiple algorithms exist. + used. That section also describes the possibilities for the + ``algorithm`` keyword, for the cases where multiple algorithms exist. EXAMPLES:: sage: x = QQ['x'].0 sage: f = x^3 - 1 - sage: f.roots() + sage: f.roots() # optional - sage.libs.pari [(1, 1)] - sage: f.roots(ring=CC) # note -- low order bits slightly different on ppc. - [(1.00000000000000, 1), (-0.500000000000000 - 0.86602540378443...*I, 1), (-0.500000000000000 + 0.86602540378443...*I, 1)] + sage: f.roots(ring=CC) # ... - low order bits slightly different on ppc # optional - sage.libs.pari + [(1.00000000000000, 1), + (-0.500000000000000 - 0.86602540378443...*I, 1), + (-0.500000000000000 + 0.86602540378443...*I, 1)] sage: f = (x^3 - 1)^2 - sage: f.roots() + sage: f.roots() # optional - sage.libs.pari [(1, 2)] :: sage: f = -19*x + 884736 - sage: f.roots() + sage: f.roots() # optional - sage.libs.pari [(884736/19, 1)] - sage: (f^20).roots() + sage: (f^20).roots() # optional - sage.libs.pari [(884736/19, 20)] :: - sage: K. = CyclotomicField(3) - sage: f = K.defining_polynomial() - sage: f.roots(ring=GF(7)) + sage: K. = CyclotomicField(3) # optional - sage.rings.number_field + sage: f = K.defining_polynomial() # optional - sage.rings.number_field + sage: f.roots(ring=GF(7)) # optional - sage.rings.finite_rings sage.rings.number_field [(4, 1), (2, 1)] - sage: g = f.change_ring(GF(7)) - sage: g.roots() + sage: g = f.change_ring(GF(7)) # optional - sage.rings.finite_rings sage.rings.number_field + sage: g.roots() # optional - sage.rings.finite_rings sage.rings.number_field [(4, 1), (2, 1)] - sage: g.roots(multiplicities=False) + sage: g.roots(multiplicities=False) # optional - sage.rings.finite_rings sage.rings.number_field [4, 2] A new ring. In the example below, we add the special method - _roots_univariate_polynomial to the base ring, and observe + :meth:`_roots_univariate_polynomial` to the base ring, and observe that this method is called instead to find roots of polynomials over this ring. This facility can be used to easily extend root finding to work over new rings you introduce:: sage: R. = QQ[] - sage: (x^2 + 1).roots() + sage: (x^2 + 1).roots() # optional - sage.libs.pari [] - sage: g = lambda f, *args, **kwds: f.change_ring(CDF).roots() - sage: QQ._roots_univariate_polynomial = g + sage: def my_roots(f, *args, **kwds): + ....: return f.change_ring(CDF).roots() + sage: QQ._roots_univariate_polynomial = my_roots sage: (x^2 + 1).roots() # abs tol 1e-14 [(2.7755575615628914e-17 - 1.0*I, 1), (0.9999999999999997*I, 1)] sage: del QQ._roots_univariate_polynomial @@ -7578,30 +7617,34 @@ cdef class Polynomial(CommutativePolynomial): returned:: sage: x = RR['x'].0 - sage: f = x^3 -2 + sage: f = x^3 - 2 sage: f.roots() [(1.25992104989487, 1)] sage: f.factor() (x - 1.25992104989487) * (x^2 + 1.25992104989487*x + 1.58740105196820) sage: x = RealField(100)['x'].0 - sage: f = x^3 -2 + sage: f = x^3 - 2 sage: f.roots() [(1.2599210498948731647672106073, 1)] :: sage: x = CC['x'].0 - sage: f = x^3 -2 + sage: f = x^3 - 2 sage: f.roots() - [(1.25992104989487, 1), (-0.62996052494743... - 1.09112363597172*I, 1), (-0.62996052494743... + 1.09112363597172*I, 1)] - sage: f.roots(algorithm='pari') - [(1.25992104989487, 1), (-0.629960524947437 - 1.09112363597172*I, 1), (-0.629960524947437 + 1.09112363597172*I, 1)] + [(1.25992104989487, 1), + (-0.62996052494743... - 1.09112363597172*I, 1), + (-0.62996052494743... + 1.09112363597172*I, 1)] + sage: f.roots(algorithm='pari') # optional - sage.libs.pari + [(1.25992104989487, 1), + (-0.629960524947437 - 1.09112363597172*I, 1), + (-0.629960524947437 + 1.09112363597172*I, 1)] Another example showing that only roots in the base ring are returned:: sage: x = polygen(ZZ) - sage: f = (2*x-3) * (x-1) * (x+1) + sage: f = (2*x - 3) * (x - 1) * (x + 1) sage: f.roots() [(1, 1), (-1, 1)] sage: f.roots(ring=QQ) @@ -7611,7 +7654,7 @@ cdef class Polynomial(CommutativePolynomial): base ring:: sage: Pols. = QQ[] - sage: pol = (n - 1/2)^2*(n - 1)^2*(n-2) + sage: pol = (n - 1/2)^2 * (n - 1)^2 * (n - 2) sage: pol.roots(ZZ) [(2, 1), (1, 2)] @@ -7621,7 +7664,7 @@ cdef class Polynomial(CommutativePolynomial): sage: f = x^2 - 1e100 sage: f.roots() [(-1.00000000000000e50, 1), (1.00000000000000e50, 1)] - sage: f = x^10 - 2*(5*x-1)^2 + sage: f = x^10 - 2 * (5*x - 1)^2 sage: f.roots(multiplicities=False) [-1.6772670339941..., 0.19995479628..., 0.20004530611..., 1.5763035161844...] @@ -7629,10 +7672,10 @@ cdef class Polynomial(CommutativePolynomial): sage: x = CC['x'].0 sage: i = CC.0 - sage: f = (x - 1)*(x - i) + sage: f = (x - 1) * (x - i) sage: f.roots(multiplicities=False) [1.00000000000000, 1.00000000000000*I] - sage: g=(x-1.33+1.33*i)*(x-2.66-2.66*i) + sage: g = (x - 1.33 + 1.33*i) * (x - 2.66 - 2.66*i) sage: g.roots(multiplicities=False) [1.33000000000000 - 1.33000000000000*I, 2.66000000000000 + 2.66000000000000*I] @@ -7640,15 +7683,15 @@ cdef class Polynomial(CommutativePolynomial): sage: x = QQ['x'].0 sage: f = x^2 + 2 - sage: f.roots(SR) + sage: f.roots(SR) # optional - sage.symbolic [(-I*sqrt(2), 1), (I*sqrt(2), 1)] - sage: f.roots(SR, multiplicities=False) + sage: f.roots(SR, multiplicities=False) # optional - sage.symbolic [-I*sqrt(2), I*sqrt(2)] The roots of some polynomials cannot be described using radical expressions:: - sage: (x^5 - x + 1).roots(SR) + sage: (x^5 - x + 1).roots(SR) # optional - sage.symbolic [] For some other polynomials, no roots can be found at the moment @@ -7656,27 +7699,29 @@ cdef class Polynomial(CommutativePolynomial): these defects. Until that gets implemented, one such example is the following:: - sage: f = x^6-300*x^5+30361*x^4-1061610*x^3+1141893*x^2-915320*x+101724 + sage: f = x^6 - 300*x^5 + 30361*x^4 - 1061610*x^3 + 1141893*x^2 - 915320*x + 101724 sage: f.roots() [] A purely symbolic roots example:: - sage: X = var('X') - sage: f = expand((X-1)*(X-I)^3*(X^2 - sqrt(2))); f - X^6 - (3*I + 1)*X^5 - sqrt(2)*X^4 + (3*I - 3)*X^4 + (3*I + 1)*sqrt(2)*X^3 + (I + 3)*X^3 - (3*I - 3)*sqrt(2)*X^2 - I*X^2 - (I + 3)*sqrt(2)*X + I*sqrt(2) - sage: f.roots() + sage: X = var('X') # optional - sage.symbolic + sage: f = expand((X - 1) * (X - I)^3 * (X^2 - sqrt(2))); f # optional - sage.symbolic + X^6 - (3*I + 1)*X^5 - sqrt(2)*X^4 + (3*I - 3)*X^4 + (3*I + 1)*sqrt(2)*X^3 + + (I + 3)*X^3 - (3*I - 3)*sqrt(2)*X^2 - I*X^2 - (I + 3)*sqrt(2)*X + I*sqrt(2) + sage: f.roots() # optional - sage.symbolic [(I, 3), (-2^(1/4), 1), (2^(1/4), 1), (1, 1)] The same operation, performed over a polynomial ring with symbolic coefficients:: - sage: X = SR['X'].0 - sage: f = (X-1)*(X-I)^3*(X^2 - sqrt(2)); f - X^6 + (-3*I - 1)*X^5 + (-sqrt(2) + 3*I - 3)*X^4 + ((3*I + 1)*sqrt(2) + I + 3)*X^3 + (-(3*I - 3)*sqrt(2) - I)*X^2 + (-(I + 3)*sqrt(2))*X + I*sqrt(2) - sage: f.roots() + sage: X = SR['X'].0 # optional - sage.symbolic + sage: f = (X - 1) * (X - I)^3 * (X^2 - sqrt(2)); f # optional - sage.symbolic + X^6 + (-3*I - 1)*X^5 + (-sqrt(2) + 3*I - 3)*X^4 + ((3*I + 1)*sqrt(2) + I + 3)*X^3 + + (-(3*I - 3)*sqrt(2) - I)*X^2 + (-(I + 3)*sqrt(2))*X + I*sqrt(2) + sage: f.roots() # optional - sage.symbolic [(I, 3), (-2^(1/4), 1), (2^(1/4), 1), (1, 1)] - sage: f.roots(multiplicities=False) + sage: f.roots(multiplicities=False) # optional - sage.symbolic [I, -2^(1/4), 2^(1/4), 1] A couple of examples where the base ring does not have a @@ -7685,11 +7730,12 @@ cdef class Polynomial(CommutativePolynomial): sage: R = Integers(6) sage: S. = R['x'] - sage: p = x^2-1 + sage: p = x^2 - 1 sage: p.roots() Traceback (most recent call last): ... - NotImplementedError: root finding with multiplicities for this polynomial not implemented (try the multiplicities=False option) + NotImplementedError: root finding with multiplicities for this polynomial + not implemented (try the multiplicities=False option) sage: p.roots(multiplicities=False) [5, 1] sage: R = Integers(9) @@ -7706,9 +7752,11 @@ cdef class Polynomial(CommutativePolynomial): sage: f = R.cyclotomic_polynomial(5); f x^4 + x^3 + x^2 + x + 1.0 sage: f.roots(multiplicities=False) # abs tol 1e-9 - [-0.8090169943749469 - 0.5877852522924724*I, -0.8090169943749473 + 0.5877852522924724*I, 0.30901699437494773 - 0.951056516295154*I, 0.30901699437494756 + 0.9510565162951525*I] + [-0.8090169943749469 - 0.5877852522924724*I, -0.8090169943749473 + 0.5877852522924724*I, + 0.30901699437494773 - 0.951056516295154*I, 0.30901699437494756 + 0.9510565162951525*I] sage: [z^5 for z in f.roots(multiplicities=False)] # abs tol 2e-14 - [0.9999999999999957 - 1.2864981197413038e-15*I, 0.9999999999999976 + 3.062854959141552e-15*I, 1.0000000000000024 + 1.1331077795295987e-15*I, 0.9999999999999953 - 2.0212861992297117e-15*I] + [0.9999999999999957 - 1.2864981197413038e-15*I, 0.9999999999999976 + 3.062854959141552e-15*I, + 1.0000000000000024 + 1.1331077795295987e-15*I, 0.9999999999999953 - 2.0212861992297117e-15*I] sage: f = CDF['x']([1,2,3,4]); f 4.0*x^3 + 3.0*x^2 + 2.0*x + 1.0 sage: r = f.roots(multiplicities=False) @@ -7718,9 +7766,9 @@ cdef class Polynomial(CommutativePolynomial): Another example over RDF:: sage: x = RDF['x'].0 - sage: ((x^3 -1)).roots() # abs tol 4e-16 + sage: ((x^3 - 1)).roots() # abs tol 4e-16 [(1.0000000000000002, 1)] - sage: ((x^3 -1)).roots(multiplicities=False) # abs tol 4e-16 + sage: ((x^3 - 1)).roots(multiplicities=False) # abs tol 4e-16 [1.0000000000000002] More examples involving the complex double field:: @@ -7730,15 +7778,20 @@ cdef class Polynomial(CommutativePolynomial): sage: f = x^3 + 2*i; f x^3 + 2.0*I sage: f.roots() - [(-1.09112363597172... - 0.62996052494743...*I, 1), (...1.25992104989487...*I, 1), (1.09112363597172... - 0.62996052494743...*I, 1)] + [(-1.09112363597172... - 0.62996052494743...*I, 1), + (...1.25992104989487...*I, 1), + (1.09112363597172... - 0.62996052494743...*I, 1)] sage: f.roots(multiplicities=False) - [-1.09112363597172... - 0.62996052494743...*I, ...1.25992104989487...*I, 1.09112363597172... - 0.62996052494743...*I] + [-1.09112363597172... - 0.62996052494743...*I, ...1.25992104989487...*I, + 1.09112363597172... - 0.62996052494743...*I] sage: [abs(f(z)) for z in f.roots(multiplicities=False)] # abs tol 1e-14 [8.95090418262362e-16, 8.728374398092689e-16, 1.0235750533041806e-15] sage: f = i*x^3 + 2; f I*x^3 + 2.0 sage: f.roots() - [(-1.09112363597172... + 0.62996052494743...*I, 1), (...1.25992104989487...*I, 1), (1.09112363597172... + 0.62996052494743...*I, 1)] + [(-1.09112363597172... + 0.62996052494743...*I, 1), + (...1.25992104989487...*I, 1), + (1.09112363597172... + 0.62996052494743...*I, 1)] sage: abs(f(f.roots()[0][0])) # abs tol 1e-13 1.1102230246251565e-16 @@ -7753,14 +7806,19 @@ cdef class Polynomial(CommutativePolynomial): sage: f.roots(ring=RIF, multiplicities=False) [-0.6180339887498948482045868343657?, 1.6180339887498948482045868343657?] sage: f.roots(ring=RealIntervalField(150)) - [(-0.6180339887498948482045868343656381177203091798057628621354486227?, 1), (1.618033988749894848204586834365638117720309179805762862135448623?, 1)] - sage: f.roots(ring=AA) + [(-0.6180339887498948482045868343656381177203091798057628621354486227?, 1), + (1.618033988749894848204586834365638117720309179805762862135448623?, 1)] + sage: f.roots(ring=AA) # optional - sage.rings.number_field [(-0.618033988749895?, 1), (1.618033988749895?, 1)] sage: f = f^2 * (x - 1) sage: f.roots(ring=RIF) - [(-0.6180339887498948482045868343657?, 2), (1.0000000000000000000000000000000?, 1), (1.6180339887498948482045868343657?, 2)] + [(-0.6180339887498948482045868343657?, 2), + (1.0000000000000000000000000000000?, 1), + (1.6180339887498948482045868343657?, 2)] sage: f.roots(ring=RIF, multiplicities=False) - [-0.6180339887498948482045868343657?, 1.0000000000000000000000000000000?, 1.6180339887498948482045868343657?] + [-0.6180339887498948482045868343657?, + 1.0000000000000000000000000000000?, + 1.6180339887498948482045868343657?] Examples using complex root isolation:: @@ -7769,15 +7827,19 @@ cdef class Polynomial(CommutativePolynomial): sage: p.roots() [] sage: p.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)] sage: p.roots(ring=ComplexIntervalField(200)) [(1.167303978261418684256045899854842180720560371525489039140082?, 1), (-0.76488443360058472602982318770854173032899665194736756700778? - 0.35247154603172624931794709140258105439420648082424733283770?*I, 1), (-0.76488443360058472602982318770854173032899665194736756700778? + 0.35247154603172624931794709140258105439420648082424733283770?*I, 1), (0.18123244446987538390180023778112063996871646618462304743774? - 1.08395410131771066843034449298076657427364024315511565430114?*I, 1), (0.18123244446987538390180023778112063996871646618462304743774? + 1.08395410131771066843034449298076657427364024315511565430114?*I, 1)] - sage: rts = p.roots(ring=QQbar); rts + sage: rts = p.roots(ring=QQbar); rts # optional - sage.rings.number_field [(1.167303978261419?, 1), (-0.7648844336005847? - 0.3524715460317263?*I, 1), (-0.7648844336005847? + 0.3524715460317263?*I, 1), (0.1812324444698754? - 1.083954101317711?*I, 1), (0.1812324444698754? + 1.083954101317711?*I, 1)] - sage: p.roots(ring=AA) + sage: p.roots(ring=AA) # optional - sage.rings.number_field [(1.167303978261419?, 1)] sage: p = (x - rts[4][0])^2 * (3*x^2 + x + 1) - sage: p.roots(ring=QQbar) + sage: p.roots(ring=QQbar) # optional - sage.rings.number_field [(-0.1666666666666667? - 0.552770798392567?*I, 1), (-0.1666666666666667? + 0.552770798392567?*I, 1), (0.1812324444698754? + 1.083954101317711?*I, 2)] sage: p.roots(ring=CIF) [(-0.1666666666666667? - 0.552770798392567?*I, 1), (-0.1666666666666667? + 0.552770798392567?*I, 1), (0.1812324444698754? + 1.083954101317711?*I, 2)] @@ -7799,35 +7861,44 @@ cdef class Polynomial(CommutativePolynomial): Note that coefficients in a number field with defining polynomial `x^2 + 1` are considered to be Gaussian rationals (with the - generator mapping to +I), if you ask for complex roots. + generator mapping to `+I`), if you ask for complex roots. :: - sage: K. = QuadraticField(-1) - sage: y = polygen(K) - sage: p = y^4 - 2 - im - sage: p.roots(ring=CC) - [(-1.2146389322441... - 0.14142505258239...*I, 1), (-0.14142505258239... + 1.2146389322441...*I, 1), (0.14142505258239... - 1.2146389322441...*I, 1), (1.2146389322441... + 0.14142505258239...*I, 1)] - sage: p = p^2 * (y^2 - 2) - sage: p.roots(ring=CIF) - [(-1.414213562373095?, 1), (1.414213562373095?, 1), (-1.214638932244183? - 0.141425052582394?*I, 2), (-0.141425052582394? + 1.214638932244183?*I, 2), (0.141425052582394? - 1.214638932244183?*I, 2), (1.214638932244183? + 0.141425052582394?*I, 2)] + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: y = polygen(K) # optional - sage.rings.number_field + sage: p = y^4 - 2 - im # optional - sage.rings.number_field + sage: p.roots(ring=CC) # optional - sage.rings.number_field + [(-1.2146389322441... - 0.14142505258239...*I, 1), + (-0.14142505258239... + 1.2146389322441...*I, 1), + (0.14142505258239... - 1.2146389322441...*I, 1), + (1.2146389322441... + 0.14142505258239...*I, 1)] + sage: p = p^2 * (y^2 - 2) # optional - sage.rings.number_field + sage: p.roots(ring=CIF) # optional - sage.rings.number_field + [(-1.414213562373095?, 1), (1.414213562373095?, 1), + (-1.214638932244183? - 0.141425052582394?*I, 2), + (-0.141425052582394? + 1.214638932244183?*I, 2), + (0.141425052582394? - 1.214638932244183?*I, 2), + (1.214638932244183? + 0.141425052582394?*I, 2)] Note that one should not use NumPy when wanting high precision output as it does not support any of the high precision types:: sage: R. = RealField(200)[] - sage: f = x^2 - R(pi) - sage: f.roots() - [(-1.7724538509055160272981674833411451827975494561223871282138, 1), (1.7724538509055160272981674833411451827975494561223871282138, 1)] - sage: f.roots(algorithm='numpy') - doctest... UserWarning: NumPy does not support arbitrary precision arithmetic. The roots found will likely have less precision than you expect. + sage: f = x^2 - R(pi) # optional - sage.symbolic + sage: f.roots() # optional - sage.symbolic + [(-1.7724538509055160272981674833411451827975494561223871282138, 1), + (1.7724538509055160272981674833411451827975494561223871282138, 1)] + sage: f.roots(algorithm='numpy') # optional - numpy sage.symbolic + doctest... UserWarning: NumPy does not support arbitrary precision arithmetic. + The roots found will likely have less precision than you expect. [(-1.77245385090551..., 1), (1.77245385090551..., 1)] We can also find roots over number fields:: - sage: K. = CyclotomicField(15) - sage: R. = PolynomialRing(K) - sage: (x^2 + x + 1).roots() + sage: K. = CyclotomicField(15) # optional - sage.rings.number_field + sage: R. = PolynomialRing(K) # optional - sage.rings.number_field + sage: (x^2 + x + 1).roots() # optional - sage.rings.number_field [(z^5, 1), (-z^5 - 1, 1)] There are many combinations of floating-point input and output @@ -7863,22 +7934,23 @@ cdef class Polynomial(CommutativePolynomial): Note that we can find the roots of a polynomial with algebraic coefficients:: - sage: rt2 = sqrt(AA(2)) - sage: rt3 = sqrt(AA(3)) - sage: x = polygen(AA) - sage: f = (x - rt2) * (x - rt3); f - x^2 - 3.146264369941973?*x + 2.449489742783178? - sage: rts = f.roots(); rts + sage: rt2 = sqrt(AA(2)) # optional - sage.rings.number_field + sage: rt3 = sqrt(AA(3)) # optional - sage.rings.number_field + sage: x = polygen(AA) # optional - sage.rings.number_field + sage: f = (x - rt2) * (x - rt3); f # optional - sage.rings.number_field + x^2 - 3.146264369941973?*x + 2.449489742783178? + sage: rts = f.roots(); rts # optional - sage.rings.number_field [(1.414213562373095?, 1), (1.732050807568878?, 1)] - sage: rts[0][0] == rt2 + sage: rts[0][0] == rt2 # optional - sage.rings.number_field True - sage: f.roots(ring=RealIntervalField(150)) - [(1.414213562373095048801688724209698078569671875376948073176679738?, 1), (1.732050807568877293527446341505872366942805253810380628055806980?, 1)] + sage: f.roots(ring=RealIntervalField(150)) # optional - sage.rings.number_field + [(1.414213562373095048801688724209698078569671875376948073176679738?, 1), + (1.732050807568877293527446341505872366942805253810380628055806980?, 1)] We can handle polynomials with huge coefficients. This number doesn't even fit in an IEEE double-precision float, but - RR and CC allow a much larger range of floating-point numbers:: + ``RR`` and ``CC`` allow a much larger range of floating-point numbers:: sage: bigc = 2^1500 sage: CDF(bigc) @@ -7891,62 +7963,62 @@ cdef class Polynomial(CommutativePolynomial): sage: x = polygen(QQ) sage: p = x + bigc - sage: p.roots(ring=RR, algorithm='numpy') + sage: p.roots(ring=RR, algorithm='numpy') # optional - numpy Traceback (most recent call last): ... LinAlgError: Array must not contain infs or NaNs - sage: p.roots(ring=RR, algorithm='pari') + sage: p.roots(ring=RR, algorithm='pari') # optional - sage.libs.pari [(-3.50746621104340e451, 1)] - sage: p.roots(ring=AA) + sage: p.roots(ring=AA) # optional - sage.rings.number_field [(-3.5074662110434039?e451, 1)] - sage: p.roots(ring=QQbar) + sage: p.roots(ring=QQbar) # optional - sage.rings.number_field [(-3.5074662110434039?e451, 1)] sage: p = bigc*x + 1 sage: p.roots(ring=RR) [(-2.85106096489671e-452, 1)] - sage: p.roots(ring=AA) + sage: p.roots(ring=AA) # optional - sage.rings.number_field [(-2.8510609648967059?e-452, 1)] - sage: p.roots(ring=QQbar) + sage: p.roots(ring=QQbar) # optional - sage.rings.number_field [(-2.8510609648967059?e-452, 1)] sage: p = x^2 - bigc sage: p.roots(ring=RR) [(-5.92238652153286e225, 1), (5.92238652153286e225, 1)] - sage: p.roots(ring=QQbar) + sage: p.roots(ring=QQbar) # optional - sage.rings.number_field [(-5.9223865215328558?e225, 1), (5.9223865215328558?e225, 1)] Check that :trac:`30522` is fixed:: - sage: PolynomialRing(SR, names="x")("x^2").roots() + sage: PolynomialRing(SR, names="x")("x^2").roots() # optional - sage.symbolic [(0, 2)] Check that :trac:`30523` is fixed:: - sage: PolynomialRing(SR, names="x")("x^2 + q").roots() + sage: PolynomialRing(SR, names="x")("x^2 + q").roots() # optional - sage.symbolic [(-sqrt(-q), 1), (sqrt(-q), 1)] - Algorithms used: + ALGORITHM: - For brevity, we will use RR to mean any RealField of any precision; - similarly for RIF, CC, and CIF. Since Sage has no specific + For brevity, we will use ``RR`` to mean any :class:`RealField` of any precision; + similarly for ``RIF``, ``CC``, and ``CIF``. Since Sage has no specific implementation of Gaussian rationals (or of number fields with embedding, at all), when we refer to Gaussian rationals below we will accept any number field with defining polynomial `x^2+1`, mapping the field generator to +I. - We call the base ring of the polynomial K, and the ring given by - the ring= argument L. (If ring= is not specified, then L is the - same as K.) - - If K and L are floating-point (RDF, CDF, RR, or CC), then a - floating-point root-finder is used. If L is RDF or CDF then we - default to using NumPy's roots(); otherwise, we use PARI's - polroots(). This choice can be overridden with - algorithm='pari' or algorithm='numpy'. If the algorithm is - unspecified and NumPy's roots() algorithm fails, then we fall - back to pari (numpy will fail if some coefficient is infinite, + We call the base ring of the polynomial `K`, and the ring given by + the ``ring`` argument `L`. (If ``ring`` is not specified, then `L` is the + same as `K`.) + + If `K` and `L` are floating-point (``RDF``, ``CDF``, ``RR``, or ``CC``), then a + floating-point root-finder is used. If `L` is ``RDF`` or ``CDF``, then we + default to using NumPy's :func:`roots`; otherwise, we use PARI's + function :pari:`polroots`. This choice can be overridden with + ``algorithm='pari'`` or ``algorithm='numpy'``. If the algorithm is + unspecified and NumPy's :func:`roots` algorithm fails, then we fall + back to PARI (NumPy will fail if some coefficient is infinite, for instance). - If L is SR (or one of its subrings), then the roots will be radical + If `L` is ``SR`` (or one of its subrings), then the roots will be radical expressions, computed as the solutions of a symbolic polynomial expression. At the moment this delegates to :meth:`sage.symbolic.expression.Expression.solve` @@ -7955,47 +8027,47 @@ cdef class Polynomial(CommutativePolynomial): Once :trac:`17516` gets implemented, all possible radical solutions should become available. - If L is AA or RIF, and K is ZZ, QQ, or AA, then the root isolation - algorithm sage.rings.polynomial.real_roots.real_roots() is used. - (You can call real_roots() directly to get more control than this + If `L` is ``AA`` or ``RIF``, and `K` is ``ZZ``, ``QQ``, or ``AA``, then the root isolation + algorithm :func:`sage.rings.polynomial.real_roots.real_roots` is used. + (You can call :func:`real_roots` directly to get more control than this method gives.) - If L is QQbar or CIF, and K is ZZ, QQ, AA, QQbar, or the Gaussian + If `L` is ``QQbar`` or ``CIF``, and `K` is ``ZZ``, ``QQ``, ``AA``, ``QQbar``, or the Gaussian rationals, then the root isolation algorithm - sage.rings.polynomial.complex_roots.complex_roots() is used. (You - can call complex_roots() directly to get more control than this + :func:`sage.rings.polynomial.complex_roots.complex_roots` is used. (You + can call :func:`complex_roots` directly to get more control than this method gives.) - If L is AA and K is QQbar or the Gaussian rationals, then - complex_roots() is used (as above) to find roots in QQbar, then + If `L` is ``AA`` and `K` is ``QQbar`` or the Gaussian rationals, then + :func:`complex_roots` is used (as above) to find roots in ``QQbar``, then these roots are filtered to select only the real roots. - If L is floating-point and K is not, then we attempt to change the - polynomial ring to L (using .change_ring()) (or, if L is complex - and K is not, to the corresponding real field). Then we use either - PARI or numpy as specified above. + If `L` is floating-point and `K` is not, then we attempt to change the + polynomial ring to `L` (using :meth:`change_ring`) (or, if `L` is complex + and `K` is not, to the corresponding real field). Then we use either + PARI or NumPy as specified above. - For all other cases where K is different than L, we attempt to use - .change_ring(L). When that fails but L is a subring of K, we also - attempt to compute the roots over K and filter the ones belonging - to L. + For all other cases where `K` is different from `L`, we attempt to use + ``.change_ring(L)``. When that fails but `L` is a subring of `K`, we also + attempt to compute the roots over `K` and filter the ones belonging + to `L`. - The next method, which is used if K is an integral domain, is to + The next method, which is used if `K` is an integral domain, is to attempt to factor the polynomial. If this succeeds, then for every - degree-one factor a\*x+b, we add -b/a as a root (as long as this + degree-one factor `ax+b`, we add `-b/a` as a root (as long as this quotient is actually in the desired ring). - If factoring over K is not implemented (or K is not an integral - domain), and K is finite, then we find the roots by enumerating all - elements of K and checking whether the polynomial evaluates to zero + If factoring over `K` is not implemented (or `K` is not an integral + domain), and `K` is finite, then we find the roots by enumerating all + elements of `K` and checking whether the polynomial evaluates to zero at that value. .. NOTE:: We mentioned above that polynomials with multiple roots are - always ill-conditioned; if your input is given to n bits of - precision, you should not expect more than n/k good bits - for a k-fold root. (You can get solutions that make the + always ill-conditioned; if your input is given to `n` bits of + precision, you should not expect more than `n/k` good bits + for a `k`-fold root. (You can get solutions that make the polynomial evaluate to a number very close to zero; basically the problem is that with a multiple root, there are many such numbers, and it's difficult to choose between @@ -8013,9 +8085,9 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: - sage: K. = CyclotomicField(2) - sage: R. = K[] - sage: factor(x^3-1) + sage: K. = CyclotomicField(2) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: factor(x^3 - 1) # optional - sage.rings.number_field (x - 1) * (x^2 + x + 1) This shows that the issue from :trac:`6237` is fixed:: @@ -8023,9 +8095,11 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: g = -27*u^14 - 32*u^9 sage: g.roots(CDF, multiplicities=False) # abs tol 2e-15 - [-1.0345637159435719, 0.0, -0.3196977699902601 - 0.9839285635706636*I, -0.3196977699902601 + 0.9839285635706636*I, 0.8369796279620465 - 0.6081012947885318*I, 0.8369796279620465 + 0.6081012947885318*I] + [-1.0345637159435719, 0.0, -0.3196977699902601 - 0.9839285635706636*I, -0.3196977699902601 + 0.9839285635706636*I, + 0.8369796279620465 - 0.6081012947885318*I, 0.8369796279620465 + 0.6081012947885318*I] sage: g.roots(CDF) # abs tol 2e-15 - [(-1.0345637159435719, 1), (0.0, 9), (-0.3196977699902601 - 0.9839285635706636*I, 1), (-0.3196977699902601 + 0.9839285635706636*I, 1), (0.8369796279620465 - 0.6081012947885318*I, 1), (0.8369796279620465 + 0.6081012947885318*I, 1)] + [(-1.0345637159435719, 1), (0.0, 9), (-0.3196977699902601 - 0.9839285635706636*I, 1), (-0.3196977699902601 + 0.9839285635706636*I, 1), + (0.8369796279620465 - 0.6081012947885318*I, 1), (0.8369796279620465 + 0.6081012947885318*I, 1)] This shows that the issue at :trac:`2418` is fixed:: @@ -8038,13 +8112,13 @@ cdef class Polynomial(CommutativePolynomial): This shows that the issue at :trac:`10901` is fixed:: - sage: a = var('a'); R. = SR[] - sage: f = x - a - sage: f.roots(RR) + sage: a = var('a'); R. = SR[] # optional - sage.symbolic + sage: f = x - a # optional - sage.symbolic + sage: f.roots(RR) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: cannot evaluate symbolic expression to a numeric value - sage: f.roots(CC) + sage: f.roots(CC) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: cannot evaluate symbolic expression to a numeric value @@ -8054,19 +8128,19 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = ZZ[] sage: pol = (x - 1)^2 - sage: pol.roots(Qp(3,5)) + sage: pol.roots(Qp(3, 5)) # optional - sage.rings.padics [(1 + O(3^5), 2)] We lose precision if we first change coefficients to `\QQ_p`:: - sage: pol.change_ring(Qp(3,5)).roots() + sage: pol.change_ring(Qp(3, 5)).roots() # optional - sage.rings.padics [(1 + O(3^3), 2)] - sage: (pol - 3^6).roots(Qp(3,5)) + sage: (pol - 3^6).roots(Qp(3, 5)) # optional - sage.rings.padics [(1 + 2*3^3 + 2*3^4 + O(3^5), 1), (1 + 3^3 + O(3^5), 1)] - sage: r = pol.roots(Zp(3,5), multiplicities=False); r + sage: r = pol.roots(Zp(3, 5), multiplicities=False); r # optional - sage.rings.padics [1 + O(3^5)] - sage: parent(r[0]) + sage: parent(r[0]) # optional - sage.rings.padics 3-adic Ring with capped relative precision 5 Spurious crash with pari-2.5.5, see :trac:`16165`:: @@ -8095,7 +8169,7 @@ cdef class Polynomial(CommutativePolynomial): Test that roots in fixed modulus p-adic fields work (:trac:`17598`):: - sage: len(cyclotomic_polynomial(3).roots(ZpFM(739, 566))) + sage: len(cyclotomic_polynomial(3).roots(ZpFM(739, 566))) # optional - sage.rings.padics 2 Check that :trac:`26421` is fixed:: @@ -8109,8 +8183,8 @@ cdef class Polynomial(CommutativePolynomial): Check that :trac:`31040` is fixed:: sage: R. = QQ[] - sage: K. = Qq(3).extension(x^2 + 1) - sage: (x^2 + 1).roots(K) + sage: K. = Qq(3).extension(x^2 + 1) # optional - sage.rings.padics + sage: (x^2 + 1).roots(K) # optional - sage.rings.padics [(a + O(3^20), 1), (2*a + 2*a*3 + 2*a*3^2 + 2*a*3^3 + 2*a*3^4 + 2*a*3^5 + 2*a*3^6 + 2*a*3^7 + 2*a*3^8 + 2*a*3^9 + 2*a*3^10 + 2*a*3^11 + 2*a*3^12 + 2*a*3^13 + 2*a*3^14 + 2*a*3^15 + 2*a*3^16 + 2*a*3^17 + 2*a*3^18 + 2*a*3^19 + O(3^20), 1)] @@ -8395,11 +8469,11 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = ZZ[] sage: pol = 20*x^3 - 50*x^2 + 20*x - sage: F = pol.factor(); F + sage: F = pol.factor(); F # optional - sage.libs.pari 2 * 5 * (x - 2) * x * (2*x - 1) - sage: pol._roots_from_factorization(F, multiplicities=True) + sage: pol._roots_from_factorization(F, multiplicities=True) # optional - sage.libs.pari [(2, 1), (0, 1)] - sage: pol.change_ring(QQ)._roots_from_factorization(F, multiplicities=False) + sage: pol.change_ring(QQ)._roots_from_factorization(F, multiplicities=False) # optional - sage.libs.pari [2, 0, 1/2] """ seq = [] @@ -8428,15 +8502,15 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: sage: Pols. = QQ[] - sage: pol = (n - 1/2)^2*(n - 1)^2*(n-2) - sage: rts = pol.roots(ZZ, multiplicities=False); rts + sage: pol = (n - 1/2)^2 * (n - 1)^2 * (n - 2) + sage: rts = pol.roots(ZZ, multiplicities=False); rts # optional - sage.libs.pari [2, 1] - sage: rts[0].parent() + sage: rts[0].parent() # optional - sage.libs.pari Integer Ring sage: Pols_x. = QQ[] sage: Pols_xy. = Pols_x[] - sage: ((y - 1)*(y - x))._roots_in_subring(QQ, True, None) + sage: ((y - 1)*(y - x))._roots_in_subring(QQ, True, None) # optional - sage.libs.singular [(1, 1)] """ K = self._parent.base_ring() @@ -8462,9 +8536,9 @@ cdef class Polynomial(CommutativePolynomial): """ Return the real roots of this polynomial, without multiplicities. - Calls self.roots(ring=RR), unless this is a polynomial with + Calls ``self.roots(ring=RR)``, unless this is a polynomial with floating-point real coefficients, in which case it calls - self.roots(). + ``self.roots()``. EXAMPLES:: @@ -8496,7 +8570,7 @@ cdef class Polynomial(CommutativePolynomial): Return the complex roots of this polynomial, without multiplicities. - Calls self.roots(ring=CC), unless this is a polynomial with + Calls ``self.roots(ring=CC)``, unless this is a polynomial with floating-point coefficients, in which case it is uses the appropriate precision from the input coefficients. @@ -8540,50 +8614,50 @@ cdef class Polynomial(CommutativePolynomial): def number_of_roots_in_interval(self, a=None, b=None): r""" Return the number of roots of this polynomial in the interval - [a,b], counted without multiplicity. The endpoints a, b default to - -Infinity, Infinity (which are also valid input values). + `[a,b]`, counted without multiplicity. The endpoints `a`, `b` default to + ``-Infinity``, ``Infinity`` (which are also valid input values). Calls the PARI routine :pari:`polsturm`. Note that as of version 2.8, PARI includes the left endpoint of the interval (and no longer uses Sturm's algorithm on exact - inputs). polsturm requires a polynomial with real + inputs). :pari:`polsturm` requires a polynomial with real coefficients; in case PARI returns an error, we try again - after taking the GCD of `self` with its complex conjugate. + after taking the GCD of ``self`` with its complex conjugate. EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: pol = (x-1)^2 * (x-2)^2 * (x-3) - sage: pol.number_of_roots_in_interval(1, 2) + sage: pol = (x - 1)^2 * (x - 2)^2 * (x - 3) + sage: pol.number_of_roots_in_interval(1, 2) # optional - sage.libs.pari 2 - sage: pol.number_of_roots_in_interval(1.01, 2) + sage: pol.number_of_roots_in_interval(1.01, 2) # optional - sage.libs.pari 1 - sage: pol.number_of_roots_in_interval(None, 2) + sage: pol.number_of_roots_in_interval(None, 2) # optional - sage.libs.pari 2 - sage: pol.number_of_roots_in_interval(1, Infinity) + sage: pol.number_of_roots_in_interval(1, Infinity) # optional - sage.libs.pari 3 - sage: pol.number_of_roots_in_interval() + sage: pol.number_of_roots_in_interval() # optional - sage.libs.pari 3 - sage: pol = (x-1)*(x-2)*(x-3) + sage: pol = (x - 1) * (x - 2) * (x - 3) sage: pol2 = pol.change_ring(CC) - sage: pol2.number_of_roots_in_interval() + sage: pol2.number_of_roots_in_interval() # optional - sage.libs.pari 3 sage: R. = PolynomialRing(CC) - sage: pol = (x-1)*(x-CC(I)) - sage: pol.number_of_roots_in_interval(0,2) + sage: pol = (x - 1) * (x - CC(I)) + sage: pol.number_of_roots_in_interval(0, 2) # optional - sage.libs.pari 1 TESTS:: sage: R. = PolynomialRing(ZZ) - sage: pol = (x-1)^2 * (x-2)^2 * (x-3) - sage: pol.number_of_roots_in_interval(1, 2) + sage: pol = (x - 1)^2 * (x - 2)^2 * (x - 3) + sage: pol.number_of_roots_in_interval(1, 2) # optional - sage.libs.pari 2 sage: pol = chebyshev_T(5,x) - sage: pol.number_of_roots_in_interval(-1,2) + sage: pol.number_of_roots_in_interval(-1, 2) # optional - sage.libs.pari 5 - sage: pol.number_of_roots_in_interval(0,2) + sage: pol.number_of_roots_in_interval(0, 2) # optional - sage.libs.pari 3 """ @@ -8612,40 +8686,40 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: pol = (x-1)^2 * (x-2)^2 * (x-3) - sage: pol.number_of_real_roots() + sage: pol = (x - 1)^2 * (x - 2)^2 * (x - 3) + sage: pol.number_of_real_roots() # optional - sage.libs.pari 3 - sage: pol = (x-1)*(x-2)*(x-3) + sage: pol = (x - 1) * (x - 2) * (x - 3) sage: pol2 = pol.change_ring(CC) - sage: pol2.number_of_real_roots() + sage: pol2.number_of_real_roots() # optional - sage.libs.pari 3 sage: R. = PolynomialRing(CC) - sage: pol = (x-1)*(x-CC(I)) - sage: pol.number_of_real_roots() + sage: pol = (x - 1) * (x - CC(I)) + sage: pol.number_of_real_roots() # optional - sage.libs.pari 1 """ return self.number_of_roots_in_interval() def all_roots_in_interval(self, a=None, b=None): r""" - Return True if the roots of this polynomial are all real and + Return ``True`` if the roots of this polynomial are all real and contained in the given interval. EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: pol = (x-1)^2 * (x-2)^2 * (x-3) - sage: pol.all_roots_in_interval(1, 3) + sage: pol = (x - 1)^2 * (x - 2)^2 * (x - 3) + sage: pol.all_roots_in_interval(1, 3) # optional - sage.libs.pari True - sage: pol.all_roots_in_interval(1.01, 3) + sage: pol.all_roots_in_interval(1.01, 3) # optional - sage.libs.pari False - sage: pol = chebyshev_T(5,x) - sage: pol.all_roots_in_interval(-1,1) + sage: pol = chebyshev_T(5, x) + sage: pol.all_roots_in_interval(-1, 1) # optional - sage.libs.pari True - sage: pol = chebyshev_T(5,x/2) - sage: pol.all_roots_in_interval(-1,1) + sage: pol = chebyshev_T(5, x/2) + sage: pol.all_roots_in_interval(-1, 1) # optional - sage.libs.pari False - sage: pol.all_roots_in_interval() + sage: pol.all_roots_in_interval() # optional - sage.libs.pari True """ pol = self // self.gcd(self.derivative()) @@ -8653,16 +8727,16 @@ cdef class Polynomial(CommutativePolynomial): def is_real_rooted(self): r""" - Return True if the roots of this polynomial are all real. + Return ``True`` if the roots of this polynomial are all real. EXAMPLES:: sage: R. = PolynomialRing(ZZ) sage: pol = chebyshev_T(5, x) - sage: pol.is_real_rooted() + sage: pol.is_real_rooted() # optional - sage.libs.pari True sage: pol = x^2 + 1 - sage: pol.is_real_rooted() + sage: pol.is_real_rooted() # optional - sage.libs.pari False """ return self.all_roots_in_interval() @@ -8693,7 +8767,7 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: pol. = PolynomialRing(Rationals()) - sage: u = x^2+x-1 + sage: u = x^2 + x - 1 sage: u.reciprocal_transform() x^4 + x^3 + x^2 + x + 1 sage: u.reciprocal_transform(R=x-1) @@ -8743,22 +8817,22 @@ cdef class Polynomial(CommutativePolynomial): We check that this function works for rings that have a coercion to the reals:: - sage: K. = NumberField(x^2-2,embedding=1.4) - sage: u = x^4 + a*x^3 + 3*x^2 + 2*a*x + 4 - sage: u.trace_polynomial() + sage: K. = NumberField(x^2 - 2, embedding=1.4) # optional - sage.rings.number_field + sage: u = x^4 + a*x^3 + 3*x^2 + 2*a*x + 4 # optional - sage.rings.number_field + sage: u.trace_polynomial() # optional - sage.rings.number_field (x^2 + a*x - 1, 1, 2) - sage: (u*(x^2-2)).trace_polynomial() + sage: (u*(x^2-2)).trace_polynomial() # optional - sage.rings.number_field (x^2 + a*x - 1, x^2 - 2, 2) - sage: (u*(x^2-2)^2).trace_polynomial() + sage: (u*(x^2-2)^2).trace_polynomial() # optional - sage.rings.number_field (x^4 + a*x^3 - 9*x^2 - 8*a*x + 8, 1, 2) - sage: (u*(x^2-2)^3).trace_polynomial() + sage: (u*(x^2-2)^3).trace_polynomial() # optional - sage.rings.number_field (x^4 + a*x^3 - 9*x^2 - 8*a*x + 8, x^2 - 2, 2) - sage: u = x^4 + a*x^3 + 3*x^2 + 4*a*x + 16 - sage: u.trace_polynomial() + sage: u = x^4 + a*x^3 + 3*x^2 + 4*a*x + 16 # optional - sage.rings.number_field + sage: u.trace_polynomial() # optional - sage.rings.number_field (x^2 + a*x - 5, 1, 4) - sage: (u*(x-2)).trace_polynomial() + sage: (u*(x-2)).trace_polynomial() # optional - sage.rings.number_field (x^2 + a*x - 5, x - 2, 4) - sage: (u*(x+2)).trace_polynomial() + sage: (u*(x+2)).trace_polynomial() # optional - sage.rings.number_field (x^2 + a*x - 5, x + 2, 4) TESTS: @@ -8805,7 +8879,7 @@ cdef class Polynomial(CommutativePolynomial): def is_weil_polynomial(self, return_q=False): r""" - Return True if this is a Weil polynomial. + Return ``True`` if this is a Weil polynomial. This polynomial must have rational or integer coefficients. @@ -8814,8 +8888,8 @@ cdef class Polynomial(CommutativePolynomial): - ``self`` -- polynomial with rational or integer coefficients - ``return_q`` -- (default ``False``) if ``True``, return a second value `q` - which is the prime power with respect to which this is `q`-Weil, - or 0 if there is no such value. + which is the prime power with respect to which this is `q`-Weil, + or 0 if there is no such value. EXAMPLES:: @@ -8823,20 +8897,20 @@ cdef class Polynomial(CommutativePolynomial): sage: P0 = x^4 + 5*x^3 + 15*x^2 + 25*x + 25 sage: P1 = x^4 + 25*x^3 + 15*x^2 + 5*x + 25 sage: P2 = x^4 + 5*x^3 + 25*x^2 + 25*x + 25 - sage: P0.is_weil_polynomial(return_q=True) + sage: P0.is_weil_polynomial(return_q=True) # optional - sage.libs.pari (True, 5) - sage: P0.is_weil_polynomial(return_q=False) + sage: P0.is_weil_polynomial(return_q=False) # optional - sage.libs.pari True - sage: P1.is_weil_polynomial(return_q=True) + sage: P1.is_weil_polynomial(return_q=True) # optional - sage.libs.pari (False, 0) - sage: P1.is_weil_polynomial(return_q=False) + sage: P1.is_weil_polynomial(return_q=False) # optional - sage.libs.pari False - sage: P2.is_weil_polynomial() + sage: P2.is_weil_polynomial() # optional - sage.libs.pari False .. SEEALSO:: - Polynomial rings have a method `weil_polynomials` to compute sets of Weil + Polynomial rings have a method :meth:`weil_polynomials` to compute sets of Weil polynomials. This computation uses the iterator :class:`sage.rings.polynomial.weil.weil_polynomials.WeilPolynomials`. @@ -8846,7 +8920,7 @@ cdef class Polynomial(CommutativePolynomial): sage: P. = QQ[] sage: u = t^10 + 4*t^9 + 8*t^8 + 18*t^7 + 81*t^6 + 272*t^5 + 567*t^4 + 882*t^3 + 2744*t^2 + 9604*t + 16807 - sage: u.is_weil_polynomial() + sage: u.is_weil_polynomial() # optional - sage.libs.pari True AUTHORS: @@ -8962,21 +9036,21 @@ cdef class Polynomial(CommutativePolynomial): The actual algorithm for computing the extended gcd depends on the base ring underlying the polynomial ring. If the base ring defines - a method ``_xgcd_univariate_polynomial``, then this method will be + a method :meth:`_xgcd_univariate_polynomial`, then this method will be called (see examples below). EXAMPLES:: - sage: R. = QQbar[] - sage: (2*x^2).gcd(2*x) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: (2*x^2).gcd(2*x) # optional - sage.rings.number_field x - sage: R.zero().gcd(0) + sage: R.zero().gcd(0) # optional - sage.rings.number_field 0 - sage: (2*x).gcd(0) + sage: (2*x).gcd(0) # optional - sage.rings.number_field x One can easily add xgcd functionality to new rings by providing a - method ``_xgcd_univariate_polynomial``:: + method :meth:`_xgcd_univariate_polynomial`:: sage: R. = QQ[] sage: S. = R[] @@ -8985,12 +9059,13 @@ cdef class Polynomial(CommutativePolynomial): sage: h1.xgcd(h2) Traceback (most recent call last): ... - NotImplementedError: Univariate Polynomial Ring in x over Rational Field does not provide an xgcd implementation for univariate polynomials + NotImplementedError: Univariate Polynomial Ring in x over Rational Field + does not provide an xgcd implementation for univariate polynomials sage: T. = QQ[] - sage: def poor_xgcd(f,g): + sage: def poor_xgcd(f, g): ....: ret = S(T(f).gcd(g)) - ....: if ret == f: return ret,S.one(),S.zero() - ....: if ret == g: return ret,S.zero(),S.one() + ....: if ret == f: return ret, S.one(), S.zero() + ....: if ret == g: return ret, S.zero(), S.one() ....: raise NotImplementedError sage: R._xgcd_univariate_polynomial = poor_xgcd sage: h1.xgcd(h2) @@ -9028,10 +9103,10 @@ cdef class Polynomial(CommutativePolynomial): sage: z = PolynomialRing(QQ, 'z').gen() sage: p = -z**16 - z**15 - z**14 + z**13 + z**12 + z**11 - z**5 - z**4 - z**3 + z**2 + z + 1 sage: m = z**21 - sage: n, d = p.rational_reconstruction(m) - sage: print((n ,d)) - (z^4 + 2*z^3 + 3*z^2 + 2*z + 1, z^10 + z^9 + z^8 + z^7 + z^6 + z^5 + z^4 + z^3 + z^2 + z + 1) - sage: print(((p*d - n) % m ).is_zero()) + sage: n, d = p.rational_reconstruction(m); n, d + (z^4 + 2*z^3 + 3*z^2 + 2*z + 1, + z^10 + z^9 + z^8 + z^7 + z^6 + z^5 + z^4 + z^3 + z^2 + z + 1) + sage: ((p*d - n) % m).is_zero() True Over `\ZZ[z]`:: @@ -9039,27 +9114,25 @@ cdef class Polynomial(CommutativePolynomial): sage: z = PolynomialRing(ZZ, 'z').gen() sage: p = -z**16 - z**15 - z**14 + z**13 + z**12 + z**11 - z**5 - z**4 - z**3 + z**2 + z + 1 sage: m = z**21 - sage: n, d = p.rational_reconstruction(m) - sage: print((n ,d)) - (z^4 + 2*z^3 + 3*z^2 + 2*z + 1, z^10 + z^9 + z^8 + z^7 + z^6 + z^5 + z^4 + z^3 + z^2 + z + 1) - sage: print(((p*d - n) % m ).is_zero()) + sage: n, d = p.rational_reconstruction(m); n, d + (z^4 + 2*z^3 + 3*z^2 + 2*z + 1, + z^10 + z^9 + z^8 + z^7 + z^6 + z^5 + z^4 + z^3 + z^2 + z + 1) + sage: ((p*d - n) % m).is_zero() True - Over an integral domain ``d`` might not be monic:: + Over an integral domain, ``d`` might not be monic:: - sage: P = PolynomialRing(ZZ,'x') + sage: P = PolynomialRing(ZZ, 'x') sage: x = P.gen() sage: p = 7*x^5 - 10*x^4 + 16*x^3 - 32*x^2 + 128*x + 256 sage: m = x^5 - sage: n, d = p.rational_reconstruction(m, 3, 2) - sage: print((n ,d)) + sage: n, d = p.rational_reconstruction(m, 3, 2); n, d (-32*x^3 + 384*x^2 + 2304*x + 2048, 5*x + 8) - sage: print(((p*d - n) % m ).is_zero()) + sage: ((p*d - n) % m).is_zero() True - sage: n, d = p.rational_reconstruction(m, 4, 0) - sage: print((n ,d)) + sage: n, d = p.rational_reconstruction(m, 4, 0); n, d (-10*x^4 + 16*x^3 - 32*x^2 + 128*x + 256, 1) - sage: print(((p*d - n) % m ).is_zero()) + sage: ((p*d - n) % m).is_zero() True Over `\QQ(t)[z]`:: @@ -9071,17 +9144,17 @@ cdef class Polynomial(CommutativePolynomial): sage: # p = (1 + t^2*z + z^4) / (1 - t*z) sage: p = (1 + t^2*z + z^4)*(1 - t*z).inverse_mod(z^9) sage: m = z^9 - sage: n, d = p.rational_reconstruction(m) - sage: print((n ,d)) + sage: n, d = p.rational_reconstruction(m); n, d (-1/t*z^4 - t*z - 1/t, z - 1/t) - sage: print(((p*d - n) % m ).is_zero()) + sage: ((p*d - n) % m).is_zero() True sage: w = PowerSeriesRing(P.fraction_field(), 'w').gen() sage: n = -10*t^2*z^4 + (-t^2 + t - 1)*z^3 + (-t - 8)*z^2 + z + 2*t^2 - t sage: d = z^4 + (2*t + 4)*z^3 + (-t + 5)*z^2 + (t^2 + 2)*z + t^2 + 2*t + 1 sage: prec = 9 - sage: nc, dc = Pz((n.subs(z = w)/d.subs(z = w) + O(w^prec)).list()).rational_reconstruction(z^prec) - sage: print( (nc, dc) == (n, d) ) + sage: x = n.subs(z=w)/d.subs(z=w) + O(w^prec) + sage: nc, dc = Pz(x.list()).rational_reconstruction(z^prec) + sage: (nc, dc) == (n, d) True Over `\QQ[t][z]`:: @@ -9092,70 +9165,63 @@ cdef class Polynomial(CommutativePolynomial): sage: # p = (1 + t^2*z + z^4) / (1 - t*z) mod z^9 sage: p = (1 + t^2*z + z^4) * sum((t*z)**i for i in range(9)) sage: m = z^9 - sage: n, d = p.rational_reconstruction(m,) - sage: print((n ,d)) + sage: n, d = p.rational_reconstruction(m,); n, d (-z^4 - t^2*z - 1, t*z - 1) - sage: print(((p*d - n) % m ).is_zero()) + sage: ((p*d - n) % m).is_zero() True Over `\QQ_5`:: - sage: x = PolynomialRing(Qp(5),'x').gen() - sage: p = 4*x^5 + 3*x^4 + 2*x^3 + 2*x^2 + 4*x + 2 - sage: m = x^6 - sage: n, d = p.rational_reconstruction(m, 3, 2) - sage: print(((p*d - n) % m ).is_zero()) + sage: x = PolynomialRing(Qp(5), 'x').gen() # optional - sage.rings.padics + sage: p = 4*x^5 + 3*x^4 + 2*x^3 + 2*x^2 + 4*x + 2 # optional - sage.rings.padics + sage: m = x^6 # optional - sage.rings.padics + sage: n, d = p.rational_reconstruction(m, 3, 2) # optional - sage.rings.padics + sage: ((p*d - n) % m).is_zero() # optional - sage.rings.padics True Can also be used to obtain known Padé approximations:: sage: z = PowerSeriesRing(QQ, 'z').gen() - sage: P = PolynomialRing(QQ,'x') + sage: P = PolynomialRing(QQ, 'x') sage: x = P.gen() - sage: p = P(exp(z).list()) + sage: p = P(z.exp().list()) sage: m = x^5 - sage: n, d = p.rational_reconstruction(m, 4, 0) - sage: print((n ,d)) + sage: n, d = p.rational_reconstruction(m, 4, 0); n, d (1/24*x^4 + 1/6*x^3 + 1/2*x^2 + x + 1, 1) - sage: print(((p*d - n) % m ).is_zero()) + sage: ((p*d - n) % m).is_zero() True sage: m = x^3 - sage: n, d = p.rational_reconstruction(m, 1, 1) - sage: print((n ,d)) + sage: n, d = p.rational_reconstruction(m, 1, 1); n, d (-x - 2, x - 2) - sage: print(((p*d - n) % m ).is_zero()) + sage: ((p*d - n) % m).is_zero() True sage: p = P(log(1-z).list()) sage: m = x^9 - sage: n, d = p.rational_reconstruction(m, 4, 4) - sage: print((n ,d)) + sage: n, d = p.rational_reconstruction(m, 4, 4); n, d (25/6*x^4 - 130/3*x^3 + 105*x^2 - 70*x, x^4 - 20*x^3 + 90*x^2 - 140*x + 70) - sage: print(((p*d - n) % m ).is_zero()) + sage: ((p*d - n) % m).is_zero() True sage: p = P(sqrt(1+z).list()) sage: m = x^6 - sage: n, d = p.rational_reconstruction(m, 3, 2) - sage: print((n ,d)) + sage: n, d = p.rational_reconstruction(m, 3, 2); n, d (1/6*x^3 + 3*x^2 + 8*x + 16/3, x^2 + 16/3*x + 16/3) - sage: print(((p*d - n) % m ).is_zero()) + sage: ((p*d - n) % m).is_zero() True - sage: p = P(exp(2*z).list()) + sage: p = P((2*z).exp().list()) sage: m = x^7 - sage: n, d = p.rational_reconstruction(m, 3, 3) - sage: print((n ,d)) + sage: n, d = p.rational_reconstruction(m, 3, 3); n, d (-x^3 - 6*x^2 - 15*x - 15, x^3 - 6*x^2 + 15*x - 15) - sage: print(((p*d - n) % m ).is_zero()) + sage: ((p*d - n) % m).is_zero() True Over `\RR[z]`:: sage: z = PowerSeriesRing(RR, 'z').gen() - sage: P = PolynomialRing(RR,'x') + sage: P = PolynomialRing(RR, 'x') sage: x = P.gen() - sage: p = P(exp(2*z).list()) + sage: p = P((2*z).exp().list()) sage: m = x^7 - sage: n, d = p.rational_reconstruction(m, 3, 3) - sage: print((n ,d)) # absolute tolerance 1e-10 + sage: n, d = p.rational_reconstruction(m, 3, 3); n, d # absolute tolerance 1e-10 (-x^3 - 6.0*x^2 - 15.0*x - 15.0, x^3 - 6.0*x^2 + 15.0*x - 15.0) .. SEEALSO:: @@ -9266,20 +9332,20 @@ cdef class Polynomial(CommutativePolynomial): `\infty`. If a prime (or non-prime) `p` is given, then the valuation - is the largest power of `p` which divides self. + is the largest power of `p` which divides ``self``. - The valuation at `\infty` is -self.degree(). + The valuation at `\infty` is ``-self.degree()``. EXAMPLES:: sage: P. = ZZ[] - sage: (x^2+x).valuation() + sage: (x^2 + x).valuation() 1 - sage: (x^2+x).valuation(x+1) + sage: (x^2 + x).valuation(x + 1) 1 - sage: (x^2+1).valuation() + sage: (x^2 + 1).valuation() 0 - sage: (x^3+1).valuation(infinity) + sage: (x^3 + 1).valuation(infinity) -3 sage: P(0).valuation() +Infinity @@ -9321,21 +9387,21 @@ cdef class Polynomial(CommutativePolynomial): def ord(self, p=None): r""" - This is the same as the valuation of self at p. See the - documentation for ``self.valuation``. + This is the same as the valuation of ``self`` at `p`. See the + documentation for :meth:`valuation`. EXAMPLES:: sage: R. = ZZ[] - sage: (x^2+x).ord(x+1) + sage: (x^2 + x).ord(x + 1) 1 """ return self.valuation(p) def add_bigoh(self, prec): r""" - Return the power series of precision at most prec got by adding - `O(q^\text{prec})` to self, where q is its variable. + Return the power series of precision at most ``prec`` got by adding + `O(q^\text{prec})` to self, where `q` is its variable. EXAMPLES:: @@ -9358,11 +9424,11 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: R. = ZZ[] - sage: (x^3 + 1).is_irreducible() + sage: (x^3 + 1).is_irreducible() # optional - sage.libs.pari False - sage: (x^2 - 1).is_irreducible() + sage: (x^2 - 1).is_irreducible() # optional - sage.libs.pari False - sage: (x^3 + 2).is_irreducible() + sage: (x^3 + 2).is_irreducible() # optional - sage.libs.pari True sage: R(0).is_irreducible() False @@ -9371,31 +9437,31 @@ cdef class Polynomial(CommutativePolynomial): polynomial in `\QQ[x]`, but not in `\ZZ[x]`:: sage: R. = ZZ[] - sage: R(2*x).is_irreducible() + sage: R(2*x).is_irreducible() # optional - sage.libs.pari False sage: R. = QQ[] - sage: R(2*x).is_irreducible() + sage: R(2*x).is_irreducible() # optional - sage.libs.pari True TESTS:: - sage: F. = NumberField(x^2-5) - sage: Fx. = PolynomialRing(F) - sage: f = Fx([2*t - 5, 5*t - 10, 3*t - 6, -t, -t + 2, 1]) - sage: f.is_irreducible() + sage: F. = NumberField(x^2 - 5) # optional - sage.rings.number_field + sage: Fx. = PolynomialRing(F) # optional - sage.rings.number_field + sage: f = Fx([2*t - 5, 5*t - 10, 3*t - 6, -t, -t + 2, 1]) # optional - sage.rings.number_field + sage: f.is_irreducible() # optional - sage.rings.number_field False - sage: f = Fx([2*t - 3, 5*t - 10, 3*t - 6, -t, -t + 2, 1]) - sage: f.is_irreducible() + sage: f = Fx([2*t - 3, 5*t - 10, 3*t - 6, -t, -t + 2, 1]) # optional - sage.rings.number_field + sage: f.is_irreducible() # optional - sage.rings.number_field True If the base ring implements `_is_irreducible_univariate_polynomial`, then this method gets used instead of the generic algorithm which just factors the input:: - sage: R. = QQbar[] - sage: hasattr(QQbar, "_is_irreducible_univariate_polynomial") + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: hasattr(QQbar, "_is_irreducible_univariate_polynomial") # optional - sage.rings.number_field True - sage: (x^2 + 1).is_irreducible() + sage: (x^2 + 1).is_irreducible() # optional - sage.rings.number_field False Constants can be irreducible if they are not units:: @@ -9403,17 +9469,17 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = ZZ[] sage: R(1).is_irreducible() False - sage: R(4).is_irreducible() + sage: R(4).is_irreducible() # optional - sage.libs.pari False - sage: R(5).is_irreducible() + sage: R(5).is_irreducible() # optional - sage.libs.pari True Check that caching works:: sage: R. = ZZ[] - sage: x.is_irreducible() + sage: x.is_irreducible() # optional - sage.libs.pari True - sage: x.is_irreducible.cache + sage: x.is_irreducible.cache # optional - sage.libs.pari True @@ -9513,13 +9579,13 @@ cdef class Polynomial(CommutativePolynomial): cpdef Polynomial truncate(self, long n): r""" - Return the polynomial of degree ` < n` which is equivalent + Return the polynomial of degree `< n` which is equivalent to self modulo `x^n`. EXAMPLES:: sage: R. = ZZ[]; S. = PolynomialRing(R, sparse=True) - sage: f = y^3 + x*y -3*x; f + sage: f = y^3 + x*y - 3*x; f y^3 + x*y - 3*x sage: f.truncate(2) x*y - 3*x @@ -9538,7 +9604,7 @@ cdef class Polynomial(CommutativePolynomial): @cached_method def is_squarefree(self): """ - Return False if this polynomial is not square-free, i.e., if there is a + Return ``False`` if this polynomial is not square-free, i.e., if there is a non-unit `g` in the polynomial ring such that `g^2` divides ``self``. .. WARNING:: @@ -9550,78 +9616,79 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: R. = QQ[] - sage: f = (x-1)*(x-2)*(x^2-5)*(x^17-3); f + sage: f = (x-1) * (x-2) * (x^2-5) * (x^17-3); f x^21 - 3*x^20 - 3*x^19 + 15*x^18 - 10*x^17 - 3*x^4 + 9*x^3 + 9*x^2 - 45*x + 30 sage: f.is_squarefree() True - sage: (f*(x^2-5)).is_squarefree() + sage: (f * (x^2-5)).is_squarefree() False A generic implementation is available, which relies on gcd computations:: sage: R. = ZZ[] - sage: (2*x).is_squarefree() + sage: (2*x).is_squarefree() # optional - sage.libs.pari True - sage: (4*x).is_squarefree() + sage: (4*x).is_squarefree() # optional - sage.libs.pari False - sage: (2*x^2).is_squarefree() + sage: (2*x^2).is_squarefree() # optional - sage.libs.pari False - sage: R(0).is_squarefree() + sage: R(0).is_squarefree() # optional - sage.libs.pari False - sage: S. = QQ[] - sage: R. = S[] - sage: (2*x*y).is_squarefree() + sage: S. = QQ[] # optional - sage.libs.pari + sage: R. = S[] # optional - sage.libs.pari + sage: (2*x*y).is_squarefree() # optional - sage.libs.pari True - sage: (2*x*y^2).is_squarefree() + sage: (2*x*y^2).is_squarefree() # optional - sage.libs.pari False In positive characteristic, we compute the square-free decomposition or a full factorization, depending on which is available:: - sage: K. = FunctionField(GF(3)) - sage: R. = K[] - sage: (x^3-x).is_squarefree() + sage: K. = FunctionField(GF(3)) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: (x^3 - x).is_squarefree() # optional - sage.rings.finite_rings True - sage: (x^3-1).is_squarefree() + sage: (x^3 - 1).is_squarefree() # optional - sage.rings.finite_rings False - sage: (x^3+t).is_squarefree() + sage: (x^3 + t).is_squarefree() # optional - sage.rings.finite_rings True - sage: (x^3+t^3).is_squarefree() + sage: (x^3 + t^3).is_squarefree() # optional - sage.rings.finite_rings False In the following example, `t^2` is a unit in the base field:: - sage: R(t^2).is_squarefree() + sage: R(t^2).is_squarefree() # optional - sage.rings.finite_rings True This method is not consistent with :meth:`.squarefree_decomposition`:: sage: R. = ZZ[] sage: f = 4 * x - sage: f.is_squarefree() + sage: f.is_squarefree() # optional - sage.rings.finite_rings False - sage: f.squarefree_decomposition() + sage: f.squarefree_decomposition() # optional - sage.rings.finite_rings (4) * x If you want this method equally not to consider the content, you can remove it as in the following example:: sage: c = f.content() - sage: (f/c).is_squarefree() + sage: (f/c).is_squarefree() # optional - sage.rings.finite_rings True If the base ring is not an integral domain, the question is not mathematically well-defined:: sage: R. = IntegerModRing(9)[] - sage: pol = (x + 3)*(x + 6); pol + sage: pol = (x + 3) * (x + 6); pol x^2 sage: pol.is_squarefree() Traceback (most recent call last): ... - TypeError: is_squarefree() is not defined for polynomials over Ring of integers modulo 9 + TypeError: is_squarefree() is not defined for + polynomials over Ring of integers modulo 9 TESTS: @@ -9638,15 +9705,15 @@ cdef class Polynomial(CommutativePolynomial): then this method gets used instead of the generic algorithm in :meth:`_is_squarefree_generic`:: - sage: R. = QQbar[] - sage: (x^2).is_squarefree() + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: (x^2).is_squarefree() # optional - sage.rings.number_field False - sage: hasattr(QQbar, '_is_squarefree_univariate_polynomial') + sage: hasattr(QQbar, '_is_squarefree_univariate_polynomial') # optional - sage.rings.number_field False - sage: QQbar._is_squarefree_univariate_polynomial = lambda self: True - sage: (x^2).is_squarefree() + sage: QQbar._is_squarefree_univariate_polynomial = lambda self: True # optional - sage.rings.number_field + sage: (x^2).is_squarefree() # optional - sage.rings.number_field True - sage: del(QQbar._is_squarefree_univariate_polynomial) + sage: del(QQbar._is_squarefree_univariate_polynomial) # optional - sage.rings.number_field """ B = self._parent.base_ring() @@ -9666,10 +9733,10 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: R. = QQbar[] - sage: (x^2*(x + 1)).is_squarefree() # indirect doctest + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: (x^2*(x + 1)).is_squarefree() # indirect doctest # optional - sage.rings.number_field False - sage: (x*(x+1)).is_squarefree() # indirect doctest + sage: (x*(x+1)).is_squarefree() # indirect doctest # optional - sage.rings.number_field True """ @@ -9701,12 +9768,12 @@ cdef class Polynomial(CommutativePolynomial): def radical(self): """ - Return the radical of self. + Return the radical of ``self``. Over a field, this is the product of - the distinct irreducible factors of self. (This is also sometimes - called the "square-free part" of self, but that term is ambiguous; - it is sometimes used to mean the quotient of self by its maximal + the distinct irreducible factors of ``self``. (This is also sometimes + called the "square-free part" of ``self``, but that term is ambiguous; + it is sometimes used to mean the quotient of ``self`` by its maximal square factor.) EXAMPLES:: @@ -9720,8 +9787,8 @@ cdef class Polynomial(CommutativePolynomial): If self has a factor of multiplicity divisible by the characteristic (see :trac:`8736`):: - sage: P. = GF(2)[] - sage: (x^3 + x^2).radical() + sage: P. = GF(2)[] # optional - sage.rings.finite_rings + sage: (x^3 + x^2).radical() # optional - sage.rings.finite_rings x^2 + x """ P = self._parent @@ -9847,13 +9914,13 @@ cdef class Polynomial(CommutativePolynomial): 2 sage: R(0).number_of_terms() 0 - sage: f = (x+1)^100 + sage: f = (x + 1)^100 sage: f.number_of_terms() 101 - sage: S = GF(5)['y'] - sage: S(f).number_of_terms() + sage: S = GF(5)['y'] # optional - sage.rings.finite_rings + sage: S(f).number_of_terms() # optional - sage.rings.finite_rings 5 - sage: cyclotomic_polynomial(105).number_of_terms() + sage: cyclotomic_polynomial(105).number_of_terms() # optional - sage.rings.finite_rings 33 The method :meth:`hamming_weight` is an alias:: @@ -9877,29 +9944,29 @@ cdef class Polynomial(CommutativePolynomial): If ``f`` is a :class:`sage.categories.map.Map`, then the resulting polynomial will be defined over the codomain of ``f``. Otherwise, the - resulting polynomial will be over the same ring as self. Set + resulting polynomial will be over the same ring as ``self``. Set ``new_base_ring`` to override this behaviour. INPUT: - - ``f`` -- a callable that will be applied to the coefficients of self. + - ``f`` -- a callable that will be applied to the coefficients of ``self``. - ``new_base_ring`` (optional) -- if given, the resulting polynomial will be defined over this ring. EXAMPLES:: - sage: R. = SR[] - sage: f = (1+I)*x^2 + 3*x - I - sage: f.map_coefficients(lambda z: z.conjugate()) + sage: R. = SR[] # optional - sage.symbolic + sage: f = (1+I)*x^2 + 3*x - I # optional - sage.symbolic + sage: f.map_coefficients(lambda z: z.conjugate()) # optional - sage.symbolic (-I + 1)*x^2 + 3*x + I sage: R. = ZZ[] sage: f = x^2 + 2 sage: f.map_coefficients(lambda a: a + 42) 43*x^2 + 44 - sage: R. = PolynomialRing(SR, sparse=True) - sage: f = (1+I)*x^(2^32) - I - sage: f.map_coefficients(lambda z: z.conjugate()) + sage: R. = PolynomialRing(SR, sparse=True) # optional - sage.symbolic + sage: f = (1+I)*x^(2^32) - I # optional - sage.symbolic + sage: f.map_coefficients(lambda z: z.conjugate()) # optional - sage.symbolic (-I + 1)*x^4294967296 + I sage: R. = PolynomialRing(ZZ, sparse=True) sage: f = x^(2^32) + 2 @@ -9909,21 +9976,21 @@ cdef class Polynomial(CommutativePolynomial): Examples with different base ring:: sage: R. = ZZ[] - sage: k = GF(2) - sage: residue = lambda x: k(x) - sage: f = 4*x^2+x+3 - sage: g = f.map_coefficients(residue); g + sage: k = GF(2) # optional - sage.rings.finite_rings + sage: residue = lambda x: k(x) # optional - sage.rings.finite_rings + sage: f = 4*x^2 + x + 3 # optional - sage.rings.finite_rings + sage: g = f.map_coefficients(residue); g # optional - sage.rings.finite_rings x + 1 - sage: g.parent() + sage: g.parent() # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Integer Ring - sage: g = f.map_coefficients(residue, new_base_ring = k); g + sage: g = f.map_coefficients(residue, new_base_ring=k); g # optional - sage.rings.finite_rings x + 1 - sage: g.parent() + sage: g.parent() # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) - sage: residue = k.coerce_map_from(ZZ) - sage: g = f.map_coefficients(residue); g + sage: residue = k.coerce_map_from(ZZ) # optional - sage.rings.finite_rings + sage: g = f.map_coefficients(residue); g # optional - sage.rings.finite_rings x + 1 - sage: g.parent() + sage: g.parent() # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) """ R = self._parent @@ -9954,14 +10021,14 @@ cdef class Polynomial(CommutativePolynomial): INPUT: - ``certificate`` -- boolean, default to ``False``. Only works with - ``algorithm`` set to "pari". + ``algorithm`` set to ``"pari"``. - - ``algorithm`` -- either "pari" or "sage" (default is "pari") + - ``algorithm`` -- either ``"pari"`` or ``"sage"`` (default is ``"pari"``) ALGORITHM: The native algorithm implemented in Sage uses the first - algorithm of [BD1989]_. The algorithm in pari (using + algorithm of [BD1989]_. The algorithm in PARI (using :pari:`poliscyclo`) is more subtle since it does compute the inverse of the Euler `\phi` function to determine the `n` such that the polynomial is the `n`-th cyclotomic polynomial. @@ -9971,38 +10038,40 @@ cdef class Polynomial(CommutativePolynomial): Quick tests:: sage: P. = ZZ['x'] - sage: (x - 1).is_cyclotomic() + sage: (x - 1).is_cyclotomic() # optional - sage.libs.pari True - sage: (x + 1).is_cyclotomic() + sage: (x + 1).is_cyclotomic() # optional - sage.libs.pari True - sage: (x^2 - 1).is_cyclotomic() + sage: (x^2 - 1).is_cyclotomic() # optional - sage.libs.pari False - sage: (x^2 + x + 1).is_cyclotomic(certificate=True) + sage: (x^2 + x + 1).is_cyclotomic(certificate=True) # optional - sage.libs.pari 3 - sage: (x^2 + 2*x + 1).is_cyclotomic(certificate=True) + sage: (x^2 + 2*x + 1).is_cyclotomic(certificate=True) # optional - sage.libs.pari 0 Test first 100 cyclotomic polynomials:: - sage: all(cyclotomic_polynomial(i).is_cyclotomic() for i in range(1,101)) + sage: all(cyclotomic_polynomial(i).is_cyclotomic() for i in range(1, 101)) # optional - sage.libs.pari True Some more tests:: - sage: (x^16 + x^14 - x^10 + x^8 - x^6 + x^2 + 1).is_cyclotomic(algorithm="pari") + sage: f = x^16 + x^14 - x^10 + x^8 - x^6 + x^2 + 1 + sage: f.is_cyclotomic(algorithm="pari") # optional - sage.libs.pari False - sage: (x^16 + x^14 - x^10 + x^8 - x^6 + x^2 + 1).is_cyclotomic(algorithm="sage") + sage: f.is_cyclotomic(algorithm="sage") # optional - sage.libs.pari False - sage: (x^16 + x^14 - x^10 - x^8 - x^6 + x^2 + 1).is_cyclotomic(algorithm="pari") + sage: g = x^16 + x^14 - x^10 - x^8 - x^6 + x^2 + 1 + sage: g.is_cyclotomic(algorithm="pari") # optional - sage.libs.pari True - sage: (x^16 + x^14 - x^10 - x^8 - x^6 + x^2 + 1).is_cyclotomic(algorithm="sage") + sage: g.is_cyclotomic(algorithm="sage") # optional - sage.libs.pari True sage: y = polygen(QQ) - sage: (y/2 - 1/2).is_cyclotomic() + sage: (y/2 - 1/2).is_cyclotomic() # optional - sage.libs.pari False - sage: (2*(y/2 - 1/2)).is_cyclotomic() + sage: (2*(y/2 - 1/2)).is_cyclotomic() # optional - sage.libs.pari True Invalid arguments:: @@ -10014,8 +10083,8 @@ cdef class Polynomial(CommutativePolynomial): Test using other rings:: - sage: z = polygen(GF(5)) - sage: (z - 1).is_cyclotomic() + sage: z = polygen(GF(5)) # optional - sage.rings.finite_rings + sage: (z - 1).is_cyclotomic() # optional - sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: not implemented in non-zero characteristic @@ -10023,28 +10092,28 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: sage: R = ZZ['x'] - sage: for _ in range(20): + sage: for _ in range(20): # optional - sage.libs.pari ....: p = R.random_element(degree=randint(10,20)) ....: ans_pari = p.is_cyclotomic(algorithm="pari") ....: ans_sage = p.is_cyclotomic(algorithm="sage") ....: assert ans_pari == ans_sage, "problem with p={}".format(p) - sage: for d in range(2,20): + sage: for d in range(2, 20): # optional - sage.libs.pari ....: p = cyclotomic_polynomial(d) ....: assert p.is_cyclotomic(algorithm="pari"), "pari problem with p={}".format(p) ....: assert p.is_cyclotomic(algorithm="sage"), "sage problem with p={}".format(p) Test the output type when ``certificate=True``:: - sage: type((x^2 - 2).is_cyclotomic(certificate=True)) + sage: type((x^2 - 2).is_cyclotomic(certificate=True)) # optional - sage.libs.pari - sage: type((x -1).is_cyclotomic(certificate=True)) + sage: type((x - 1).is_cyclotomic(certificate=True)) # optional - sage.libs.pari Check that the arguments are forwarded when the input is not a polynomial with coefficients in `\ZZ`:: sage: x = polygen(QQ) - sage: (x-1).is_cyclotomic(certificate=True) + sage: (x - 1).is_cyclotomic(certificate=True) # optional - sage.libs.pari 1 """ S = self.base_ring() @@ -10121,20 +10190,20 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: x = polygen(ZZ) - sage: (x^5 - 1).is_cyclotomic_product() + sage: (x^5 - 1).is_cyclotomic_product() # optional - sage.libs.pari True - sage: (x^5 + x^4 - x^2 + 1).is_cyclotomic_product() + sage: (x^5 + x^4 - x^2 + 1).is_cyclotomic_product() # optional - sage.libs.pari False - sage: p = prod(cyclotomic_polynomial(i) for i in [2,5,7,12]) - sage: p.is_cyclotomic_product() + sage: p = prod(cyclotomic_polynomial(i) for i in [2, 5, 7, 12]) # optional - sage.libs.pari + sage: p.is_cyclotomic_product() # optional - sage.libs.pari True - sage: (x^5 - 1/3).is_cyclotomic_product() + sage: (x^5 - 1/3).is_cyclotomic_product() # optional - sage.libs.pari False sage: x = polygen(Zmod(5)) - sage: (x-1).is_cyclotomic_product() + sage: (x - 1).is_cyclotomic_product() # optional - sage.libs.pari Traceback (most recent call last): ... NotImplementedError: not implemented in non-zero characteristic @@ -10235,12 +10304,12 @@ cdef class Polynomial(CommutativePolynomial): def has_cyclotomic_factor(self): r""" - Return True if the given polynomial has a nontrivial cyclotomic factor. + Return ``True`` if the given polynomial has a nontrivial cyclotomic factor. The algorithm assumes that the polynomial has rational coefficients. If the polynomial is known to be irreducible, it may be slightly more - efficient to call `is_cyclotomic` instead. + efficient to call :meth:`is_cyclotomic` instead. .. SEEALSO:: @@ -10251,12 +10320,12 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: pol. = PolynomialRing(Rationals()) - sage: u = x^5-1; u.has_cyclotomic_factor() + sage: u = x^5 - 1; u.has_cyclotomic_factor() True - sage: u = x^5-2; u.has_cyclotomic_factor() + sage: u = x^5 - 2; u.has_cyclotomic_factor() False - sage: u = pol(cyclotomic_polynomial(7)) * pol.random_element() #random - sage: u.has_cyclotomic_factor() # random + sage: u = pol(cyclotomic_polynomial(7)) * pol.random_element() # random # optional - sage.libs.pari + sage: u.has_cyclotomic_factor() # random # optional - sage.libs.pari True """ if not QQ.has_coerce_map_from(self.base_ring()): @@ -10347,9 +10416,9 @@ cdef class Polynomial(CommutativePolynomial): In positive characteristic, the degree can drop in this case:: - sage: R. = GF(2)[] - sage: f = x + 1 - sage: f.homogenize(x) + sage: R. = GF(2)[] # optional - sage.rings.finite_rings + sage: f = x + 1 # optional - sage.rings.finite_rings + sage: f.homogenize(x) # optional - sage.rings.finite_rings 0 For compatibility with the multivariate case, the parameter ``var`` can @@ -10392,7 +10461,7 @@ cdef class Polynomial(CommutativePolynomial): True sage: P(0).is_homogeneous() True - sage: (x+1).is_homogeneous() + sage: (x + 1).is_homogeneous() False """ return len(self.exponents()) < 2 @@ -10405,7 +10474,7 @@ cdef class Polynomial(CommutativePolynomial): series. This method works only when the base ring is an integral domain. Moreover, for polynomial whose coefficient of lower degree is different from 1, the elements of the base - ring should have a method ``nth_root`` implemented. + ring should have a method :meth:`nth_root` implemented. EXAMPLES:: @@ -10426,43 +10495,43 @@ cdef class Polynomial(CommutativePolynomial): sage: a.nth_root(2) 1/56*x^3 + 103/336*x^2 + 365/252*x + 25/12 - sage: K. = QuadraticField(2) - sage: R. = K[] - sage: a = (x + sqrt2)^3 * ((1+sqrt2)*x - 1/sqrt2)^6 - sage: b = a.nth_root(3); b + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: a = (x + sqrt2)^3 * ((1+sqrt2)*x - 1/sqrt2)^6 # optional - sage.rings.number_field + sage: b = a.nth_root(3); b # optional - sage.rings.number_field (2*sqrt2 + 3)*x^3 + (2*sqrt2 + 2)*x^2 + (-2*sqrt2 - 3/2)*x + 1/2*sqrt2 - sage: b^3 == a + sage: b^3 == a # optional - sage.rings.number_field True - sage: R. = QQbar[] - sage: p = x**3 + QQbar(2).sqrt() * x - QQbar(3).sqrt() - sage: r = (p**5).nth_root(5) - sage: r * p[0] == p * r[0] + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: p = x**3 + QQbar(2).sqrt() * x - QQbar(3).sqrt() # optional - sage.rings.number_field + sage: r = (p**5).nth_root(5) # optional - sage.rings.number_field + sage: r * p[0] == p * r[0] # optional - sage.rings.number_field True - sage: p = (x+1)^20 + x^20 - sage: p.nth_root(20) + sage: p = (x+1)^20 + x^20 # optional - sage.rings.number_field + sage: p.nth_root(20) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: not a 20th power - sage: z = GF(4).gen() - sage: R. = GF(4)[] - sage: p = z*x**4 + 2*x - 1 - sage: r = (p**15).nth_root(15) - sage: r * p[0] == p * r[0] + sage: z = GF(4).gen() # optional - sage.rings.finite_rings + sage: R. = GF(4)[] # optional - sage.rings.finite_rings + sage: p = z*x**4 + 2*x - 1 # optional - sage.rings.finite_rings + sage: r = (p**15).nth_root(15) # optional - sage.rings.finite_rings + sage: r * p[0] == p * r[0] # optional - sage.rings.finite_rings True - sage: ((x+1)**2).nth_root(2) + sage: ((x+1)**2).nth_root(2) # optional - sage.rings.finite_rings x + 1 - sage: ((x+1)**4).nth_root(4) + sage: ((x+1)**4).nth_root(4) # optional - sage.rings.finite_rings x + 1 - sage: ((x+1)**12).nth_root(12) + sage: ((x+1)**12).nth_root(12) # optional - sage.rings.finite_rings x + 1 - sage: (x^4 + x^3 + 1).nth_root(2) + sage: (x^4 + x^3 + 1).nth_root(2) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: not a 2nd power - sage: p = (x+1)^17 + x^17 - sage: r = p.nth_root(17) + sage: p = (x+1)^17 + x^17 # optional - sage.rings.finite_rings + sage: r = p.nth_root(17) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: not a 17th power @@ -10479,14 +10548,14 @@ cdef class Polynomial(CommutativePolynomial): example with a non-trivial coefficient of lowest degree raises an error:: sage: R. = QQ[] - sage: R2 = R.quotient(x**2 + 1) - sage: x = R2.gen() - sage: R3. = R2[] - sage: (y**2 - 2*y + 1).nth_root(2) + sage: R2 = R.quotient(x**2 + 1) # optional - sage.libs.pari + sage: x = R2.gen() # optional - sage.libs.pari + sage: R3. = R2[] # optional - sage.libs.pari + sage: (y**2 - 2*y + 1).nth_root(2) # optional - sage.libs.pari -y + 1 - sage: (y**3).nth_root(3) + sage: (y**3).nth_root(3) # optional - sage.libs.pari y - sage: (y**2 + x).nth_root(2) + sage: (y**2 + x).nth_root(2) # optional - sage.libs.pari Traceback (most recent call last): ... AttributeError: ... has no attribute 'nth_root' @@ -10522,7 +10591,7 @@ cdef class Polynomial(CommutativePolynomial): Some random tests:: - sage: for R in [QQ['x'], GF(4)['x']]: + sage: for R in [QQ['x'], GF(4)['x']]: # optional - sage.rings.finite_rings ....: for _ in range(30): ....: p = R.random_element(degree=randint(10,20)) ....: n = ZZ.random_element(2,20) @@ -10606,10 +10675,10 @@ cdef class Polynomial(CommutativePolynomial): sage: R.one()._nth_root_series(3, 5) 1 - sage: R. = QQbar[] - sage: p = 2 + 3*x^2 - sage: q = p._nth_root_series(3, 20) - sage: (q**3).truncate(20) + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: p = 2 + 3*x^2 # optional - sage.rings.number_field + sage: q = p._nth_root_series(3, 20) # optional - sage.rings.number_field + sage: (q**3).truncate(20) # optional - sage.rings.number_field 3*x^2 + 2 The exponent must be invertible in the base ring:: @@ -10631,12 +10700,12 @@ cdef class Polynomial(CommutativePolynomial): Finite characteristic:: - sage: R. = GF(2)[] - sage: (1 + x)._nth_root_series(3, 10) + sage: R. = GF(2)[] # optional - sage.rings.finite_rings + sage: (1 + x)._nth_root_series(3, 10) # optional - sage.rings.finite_rings x^9 + x^8 + x^3 + x^2 + x + 1 - sage: (1 + x^2)._nth_root_series(2, 10) + sage: (1 + x^2)._nth_root_series(2, 10) # optional - sage.rings.finite_rings x + 1 - sage: (1 + x)._nth_root_series(2, 10) + sage: (1 + x)._nth_root_series(2, 10) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: not a 2nd power @@ -10715,7 +10784,7 @@ cdef class Polynomial(CommutativePolynomial): @coerce_binop def divides(self, p): r""" - Return `True` if this polynomial divides `p`. + Return ``True`` if this polynomial divides `p`. This method is only implemented for polynomials over an integral domain. @@ -10749,21 +10818,21 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: - sage: R. = PolynomialRing(ZZ, implementation="NTL") - sage: (2*x + 1).divides(4*x**2 + 1) + sage: R. = PolynomialRing(ZZ, implementation="NTL") # optional - sage.libs.ntl + sage: (2*x + 1).divides(4*x**2 + 1) # optional - sage.libs.ntl False - sage: K. = GF(4) - sage: R. = K[] - sage: S. = R[] - sage: p = ((3*z + 2)*x + 2*z - 1) * y + 2*x + z - sage: q = y^2 + z*y*x + 2*y + z - sage: p.divides(q), p.divides(p*q) + sage: K. = GF(4) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: S. = R[] # optional - sage.rings.finite_rings + sage: p = ((3*z + 2)*x + 2*z - 1) * y + 2*x + z # optional - sage.rings.finite_rings + sage: q = y^2 + z*y*x + 2*y + z # optional - sage.rings.finite_rings + sage: p.divides(q), p.divides(p*q) # optional - sage.rings.finite_rings (False, True) - sage: R. = GF(2)[] - sage: S. = R[] - sage: p = (x+y+1) * z + x*y - sage: q = (y^2-x^2) * z^2 + z + x-y - sage: p.divides(q), p.divides(p*q) + sage: R. = GF(2)[] # optional - sage.rings.finite_rings + sage: S. = R[] # optional - sage.rings.finite_rings + sage: p = (x+y+1) * z + x*y # optional - sage.rings.finite_rings + sage: q = (y^2-x^2) * z^2 + z + x-y # optional - sage.rings.finite_rings + sage: p.divides(q), p.divides(p*q) # optional - sage.rings.finite_rings (False, True) """ if not self.base_ring().is_integral_domain(): @@ -10799,7 +10868,7 @@ cdef class Polynomial(CommutativePolynomial): - ``D`` -- dictionary (optional) - - ``phi`` -- SpecializationMorphism (optional) + - ``phi`` -- :class:`SpecializationMorphism` (optional) OUTPUT: a new polynomial @@ -11002,8 +11071,8 @@ cdef list do_schoolbook_product(list x, list y, Py_ssize_t deg): INPUT: - - ``x``, ``y``: lists of coefficients - - ``deg``: degree at which the output should be truncated, + - ``x``, ``y`` -- lists of coefficients + - ``deg`` -- degree at which the output should be truncated, negative values mean not to truncate at all TESTS: @@ -11241,7 +11310,7 @@ cdef class Polynomial_generic_dense(Polynomial): sage: R. = QQ[] sage: S = R['y'] - sage: S((x^2, 2, 1+x)) + sage: S((x^2, 2, 1 + x)) (x + 1)*y^2 + 2*y + x^2 """ def __init__(self, parent, x=None, int check=1, is_gen=False, int construct=0, **kwds): @@ -11362,14 +11431,14 @@ cdef class Polynomial_generic_dense(Polynomial): EXAMPLES:: - sage: R. = SR[] - sage: R(0).is_term() + sage: R. = SR[] # optional - sage.symbolic + sage: R(0).is_term() # optional - sage.symbolic False - sage: R(1).is_term() + sage: R(1).is_term() # optional - sage.symbolic True - sage: (3*x^5).is_term() + sage: (3*x^5).is_term() # optional - sage.symbolic True - sage: (1+3*x^5).is_term() + sage: (1 + 3*x^5).is_term() # optional - sage.symbolic False """ if not self.__coeffs: @@ -11493,30 +11562,30 @@ cdef class Polynomial_generic_dense(Polynomial): EXAMPLES:: - sage: R. = QQbar[] - sage: f = (1+2*x)^3 + 3*x; f + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: f = (1+2*x)^3 + 3*x; f # optional - sage.rings.number_field 8*x^3 + 12*x^2 + 9*x + 1 - sage: g = f // (1+2*x); g + sage: g = f // (1+2*x); g # optional - sage.rings.number_field 4*x^2 + 4*x + 5/2 - sage: f - g * (1+2*x) + sage: f - g * (1+2*x) # optional - sage.rings.number_field -3/2 - sage: f.quo_rem(1+2*x) + sage: f.quo_rem(1+2*x) # optional - sage.rings.number_field (4*x^2 + 4*x + 5/2, -3/2) TESTS: Check that :trac:`13048` and :trac:`2034` are fixed:: - sage: R. = QQbar[] - sage: x // x + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: x // x # optional - sage.rings.number_field 1 - sage: x // 1 + sage: x // 1 # optional - sage.rings.number_field x - sage: x // int(1) + sage: x // int(1) # optional - sage.rings.number_field x - sage: x //= int(1); x + sage: x //= int(1); x # optional - sage.rings.number_field x - sage: int(1) // x # check that this doesn't segfault + sage: int(1) // x # check that this doesn't segfault # optional - sage.rings.number_field Traceback (most recent call last): ... AttributeError: type object 'int' has no attribute 'base_ring' @@ -11609,8 +11678,7 @@ cdef class Polynomial_generic_dense(Polynomial): """ Return the constant coefficient of this polynomial. - OUTPUT: - element of base ring + OUTPUT: element of base ring EXAMPLES:: @@ -11631,10 +11699,10 @@ cdef class Polynomial_generic_dense(Polynomial): EXAMPLES:: - sage: R. = GF(17)[] - sage: f = (1+2*x)^3 + 3*x; f + sage: R. = GF(17)[] # optional - sage.rings.finite_rings + sage: f = (1+2*x)^3 + 3*x; f # optional - sage.rings.finite_rings 8*x^3 + 12*x^2 + 9*x + 1 - sage: f.list() + sage: f.list() # optional - sage.rings.finite_rings [1, 9, 12, 8] """ if copy: @@ -11711,8 +11779,8 @@ cdef class Polynomial_generic_dense(Polynomial): Return the quotient and remainder of the Euclidean division of ``self`` and ``other``. - Raises a ``ZerodivisionError`` if ``other`` is zero. Raises an - ``ArithmeticError`` if the division is not exact. + Raises a :class:`ZeroDivisionError` if ``other`` is zero. Raises an + :class:`ArithmeticError` if the division is not exact. EXAMPLES:: @@ -11727,7 +11795,8 @@ cdef class Polynomial_generic_dense(Polynomial): sage: f.quo_rem(g) Traceback (most recent call last): ... - ArithmeticError: division non exact (consider coercing to polynomials over the fraction field) + ArithmeticError: division non exact (consider coercing + to polynomials over the fraction field) sage: g = 0 sage: f.quo_rem(g) Traceback (most recent call last): @@ -11737,12 +11806,12 @@ cdef class Polynomial_generic_dense(Polynomial): Polynomials over noncommutative rings are also allowed (after :trac:`34733`):: - sage: HH = QuaternionAlgebra(QQ, -1, -1) - sage: P. = HH[] - sage: f = P.random_element(5) - sage: g = P.random_element((0, 5)) - sage: q, r = f.quo_rem(g) - sage: f == q*g + r + sage: HH = QuaternionAlgebra(QQ, -1, -1) # optional - sage.combinat sage.modules + sage: P. = HH[] # optional - sage.combinat sage.modules + sage: f = P.random_element(5) # optional - sage.combinat sage.modules + sage: g = P.random_element((0, 5)) # optional - sage.combinat sage.modules + sage: q, r = f.quo_rem(g) # optional - sage.combinat sage.modules + sage: f == q*g + r # optional - sage.combinat sage.modules True TESTS: @@ -11812,19 +11881,19 @@ cdef class Polynomial_generic_dense(Polynomial): cpdef Polynomial truncate(self, long n): r""" - Return the polynomial of degree ` < n` which is equivalent + Return the polynomial of degree `< n` which is equivalent to self modulo `x^n`. EXAMPLES:: sage: S. = QQ['t']['q'] - sage: f = (1+q^10+q^11+q^12).truncate(11); f + sage: f = (1 + q^10 + q^11 + q^12).truncate(11); f q^10 + 1 - sage: f = (1+q^10+q^100).truncate(50); f + sage: f = (1 + q^10 + q^100).truncate(50); f q^10 + 1 sage: f.degree() 10 - sage: f = (1+q^10+q^100).truncate(500); f + sage: f = (1 + q^10 + q^100).truncate(500); f q^100 + q^10 + 1 TESTS: @@ -11874,13 +11943,13 @@ def universal_discriminant(n): EXAMPLES:: sage: from sage.rings.polynomial.polynomial_element import universal_discriminant - sage: universal_discriminant(1) + sage: universal_discriminant(1) # optional - sage.libs.pari 1 - sage: universal_discriminant(2) + sage: universal_discriminant(2) # optional - sage.libs.pari a1^2 - 4*a0*a2 - sage: universal_discriminant(3) + sage: universal_discriminant(3) # optional - sage.libs.pari a1^2*a2^2 - 4*a0*a2^3 - 4*a1^3*a3 + 18*a0*a1*a2*a3 - 27*a0^2*a3^2 - sage: universal_discriminant(4).degrees() + sage: universal_discriminant(4).degrees() # optional - sage.libs.pari (3, 4, 4, 4, 3) .. SEEALSO:: @@ -11902,7 +11971,7 @@ cpdef Polynomial generic_power_trunc(Polynomial p, Integer n, long prec): - ``n`` - an integer (of type :class:`sage.rings.integer.Integer`) - - ``prec`` - a precision (should fit into a C long) + - ``prec`` - a precision (should fit into a C ``long``) TESTS: @@ -11910,7 +11979,7 @@ cpdef Polynomial generic_power_trunc(Polynomial p, Integer n, long prec): sage: from sage.rings.polynomial.polynomial_element import generic_power_trunc - sage: for S in [ZZ, GF(3)]: # known bug # not tested (see :trac:`32075`) + sage: for S in [ZZ, GF(3)]: # known bug # not tested (see :trac:`32075`) # optional - sage.rings.finite_rings ....: R = PolynomialRing(S, 'x') ....: for _ in range(100): ....: p = R.random_element() @@ -12010,9 +12079,9 @@ cdef class Polynomial_generic_dense_inexact(Polynomial_generic_dense): Coefficients indistinguishable from 0 are not removed. - sage: R = Zp(5) - sage: S. = R[] - sage: S([1,R(0,20)]) + sage: R = Zp(5) # optional - sage.rings.padics + sage: S. = R[] # optional - sage.rings.padics + sage: S([1, R(0, 20)]) # optional - sage.rings.padics O(5^20)*x + 1 + O(5^20) """ cdef list x = self.__coeffs @@ -12030,43 +12099,41 @@ cdef class Polynomial_generic_dense_inexact(Polynomial_generic_dense): r""" INPUT: - - secure -- a boolean (default: False) + - ``secure`` -- a boolean (default: ``False``) - OUTPUT: - - The degree of self. + OUTPUT: The degree of ``self``. - If ``secure`` is True and the degree of this polynomial + If ``secure`` is ``True`` and the degree of this polynomial is not determined (because the leading coefficient is indistinguishable from 0), an error is raised - If ``secure`` is False, the returned value is the largest + If ``secure`` is ``False``, the returned value is the largest `n` so that the coefficient of `x^n` does not compare equal to `0`. EXAMPLES:: - sage: K = Qp(3,10) - sage: R. = K[] - sage: f = T + 2; f + sage: K = Qp(3, 10) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: f = T + 2; f # optional - sage.rings.padics (1 + O(3^10))*T + 2 + O(3^10) - sage: f.degree() + sage: f.degree() # optional - sage.rings.padics 1 - sage: (f-T).degree() + sage: (f - T).degree() # optional - sage.rings.padics 0 - sage: (f-T).degree(secure=True) + sage: (f - T).degree(secure=True) # optional - sage.rings.padics Traceback (most recent call last): ... PrecisionError: the leading coefficient is indistinguishable from 0 - sage: x = O(3^5) - sage: li = [3^i * x for i in range(0,5)]; li + sage: x = O(3^5) # optional - sage.rings.padics + sage: li = [3^i * x for i in range(0,5)]; li # optional - sage.rings.padics [O(3^5), O(3^6), O(3^7), O(3^8), O(3^9)] - sage: f = R(li); f + sage: f = R(li); f # optional - sage.rings.padics O(3^9)*T^4 + O(3^8)*T^3 + O(3^7)*T^2 + O(3^6)*T + O(3^5) - sage: f.degree() + sage: f.degree() # optional - sage.rings.padics -1 - sage: f.degree(secure=True) + sage: f.degree(secure=True) # optional - sage.rings.padics Traceback (most recent call last): ... PrecisionError: the leading coefficient is indistinguishable from 0 @@ -12098,20 +12165,20 @@ cdef class Polynomial_generic_dense_inexact(Polynomial_generic_dense): EXAMPLES:: - sage: K = Qp(3,10) - sage: R. = K[] - sage: f = T + 2; f + sage: K = Qp(3, 10) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: f = T + 2; f # optional - sage.rings.padics (1 + O(3^10))*T + 2 + O(3^10) - sage: f.degree() + sage: f.degree() # optional - sage.rings.padics 1 - sage: f.prec_degree() + sage: f.prec_degree() # optional - sage.rings.padics 1 - sage: g = f - T; g + sage: g = f - T; g # optional - sage.rings.padics O(3^10)*T + 2 + O(3^10) - sage: g.degree() + sage: g.degree() # optional - sage.rings.padics 0 - sage: g.prec_degree() + sage: g.prec_degree() # optional - sage.rings.padics 1 AUTHOR: @@ -12125,25 +12192,25 @@ cdef class ConstantPolynomialSection(Map): """ This class is used for conversion from a polynomial ring to its base ring. - Since :trac:`9944`, it calls the ``constant_coefficient`` method, + Since :trac:`9944`, it calls the :meth:`constant_coefficient` method, which can be optimized for a particular polynomial type. EXAMPLES:: - sage: P0. = GF(3)[] - sage: P1. = GF(3)[] - sage: P0(-y_1) # indirect doctest + sage: P0. = GF(3)[] # optional - sage.rings.finite_rings + sage: P1. = GF(3)[] # optional - sage.rings.finite_rings + sage: P0(-y_1) # indirect doctest # optional - sage.rings.finite_rings 2*y_1 - sage: phi = GF(3).convert_map_from(P0); phi + sage: phi = GF(3).convert_map_from(P0); phi # optional - sage.rings.finite_rings Generic map: From: Univariate Polynomial Ring in y_1 over Finite Field of size 3 To: Finite Field of size 3 - sage: type(phi) + sage: type(phi) # optional - sage.rings.finite_rings - sage: phi(P0.one()) + sage: phi(P0.one()) # optional - sage.rings.finite_rings 1 - sage: phi(y_1) + sage: phi(y_1) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: not a constant polynomial @@ -12180,12 +12247,12 @@ cdef class PolynomialBaseringInjection(Morphism): This class is used for conversion from a ring to a polynomial over that ring. - It calls the _new_constant_poly method on the generator, + It calls the :meth:`_new_constant_poly` method on the generator, which should be optimized for a particular polynomial type. Technically, it should be a method of the polynomial ring, but - few polynomial rings are cython classes, and so, as a method - of a cython polynomial class, it is faster. + few polynomial rings are Cython classes, and so, as a method + of a Cython polynomial class, it is faster. EXAMPLES: @@ -12194,16 +12261,18 @@ cdef class PolynomialBaseringInjection(Morphism): supposed to be the fastest maps for that purpose. See :trac:`9944`. :: - sage: R. = Qp(3)[] - sage: R.coerce_map_from(R.base_ring()) + sage: R. = Qp(3)[] # optional - sage.rings.padics + sage: R.coerce_map_from(R.base_ring()) # optional - sage.rings.padics Polynomial base injection morphism: From: 3-adic Field with capped relative precision 20 - To: Univariate Polynomial Ring in x over 3-adic Field with capped relative precision 20 - sage: R. = Qp(3)[] - sage: R.coerce_map_from(R.base_ring()) + To: Univariate Polynomial Ring in x over + 3-adic Field with capped relative precision 20 + sage: R. = Qp(3)[] # optional - sage.rings.padics + sage: R.coerce_map_from(R.base_ring()) # optional - sage.rings.padics Polynomial base injection morphism: From: 3-adic Field with capped relative precision 20 - To: Multivariate Polynomial Ring in x, y over 3-adic Field with capped relative precision 20 + To: Multivariate Polynomial Ring in x, y over + 3-adic Field with capped relative precision 20 sage: R. = QQ[] sage: R.coerce_map_from(R.base_ring()) Polynomial base injection morphism: @@ -12242,11 +12311,11 @@ cdef class PolynomialBaseringInjection(Morphism): :: - sage: R. = Qp(2)[] - sage: f = R.convert_map_from(R.base_ring()) # indirect doctest - sage: f(Qp(2).one()*3) + sage: R. = Qp(2)[] # optional - sage.rings.padics + sage: f = R.convert_map_from(R.base_ring()) # indirect doctest # optional - sage.rings.padics + sage: f(Qp(2).one()*3) # optional - sage.rings.padics 1 + 2 + O(2^20) - sage: (Qp(2).one()*3)*t + sage: (Qp(2).one()*3)*t # optional - sage.rings.padics (1 + 2 + O(2^20))*t """ assert codomain.base_ring() is domain, "domain must be basering" @@ -12310,8 +12379,8 @@ cdef class PolynomialBaseringInjection(Morphism): TESTS:: sage: from sage.rings.polynomial.polynomial_element import PolynomialBaseringInjection - sage: m = PolynomialBaseringInjection(Qp(5), Qp(5)['x']) - sage: m(1 + O(5^11), absprec = 5) # indirect doctest + sage: m = PolynomialBaseringInjection(Qp(5), Qp(5)['x']) # optional - sage.rings.padics + sage: m(1 + O(5^11), absprec=5) # indirect doctest # optional - sage.rings.padics 1 + O(5^11) """ try: diff --git a/src/sage/rings/polynomial/polynomial_element_generic.py b/src/sage/rings/polynomial/polynomial_element_generic.py index 78692bc93d8..2f012daca29 100644 --- a/src/sage/rings/polynomial/polynomial_element_generic.py +++ b/src/sage/rings/polynomial/polynomial_element_generic.py @@ -12,12 +12,12 @@ We test coercion in a particularly complicated situation:: - sage: W.=QQ['w'] - sage: WZ.=W['z'] - sage: m = matrix(WZ,2,2,[1,z,z,z^2]) - sage: a = m.charpoly() - sage: R. = WZ[] - sage: R(a) + sage: W. = QQ['w'] + sage: WZ. = W['z'] + sage: m = matrix(WZ, 2, 2, [1, z, z, z^2]) # optional - sage.modules + sage: a = m.charpoly() # optional - sage.modules + sage: R. = WZ[] # optional - sage.modules + sage: R(a) # optional - sage.modules x^2 + (-z^2 - 1)*x """ @@ -65,13 +65,15 @@ class Polynomial_generic_sparse(Polynomial): A more extensive example:: - sage: A. = PolynomialRing(Integers(5),sparse=True) ; f = T^2+1 ; B = A.quo(f) - sage: C. = PolynomialRing(B) - sage: C - Univariate Polynomial Ring in s over Univariate Quotient Polynomial Ring in Tbar over Ring of integers modulo 5 with modulus T^2 + 1 - sage: s + T + sage: A. = PolynomialRing(Integers(5), sparse=True) # optional - sage.libs.pari + sage: f = T^2 + 1; B = A.quo(f) # optional - sage.libs.pari + sage: C. = PolynomialRing(B) # optional - sage.libs.pari + sage: C # optional - sage.libs.pari + Univariate Polynomial Ring in s over Univariate Quotient Polynomial Ring in Tbar + over Ring of integers modulo 5 with modulus T^2 + 1 + sage: s + T # optional - sage.libs.pari s + Tbar - sage: (s + T)**2 + sage: (s + T)**2 # optional - sage.libs.pari s^2 + 2*Tbar*s + 4 """ @@ -188,13 +190,13 @@ def valuation(self, p=None): EXAMPLES:: - sage: R. = PolynomialRing(GF(9,'a'), sparse=True) - sage: f = w^1997 - w^10000 - sage: f.valuation() + sage: R. = PolynomialRing(GF(9, 'a'), sparse=True) # optional - sage.rings.finite_rings + sage: f = w^1997 - w^10000 # optional - sage.rings.finite_rings + sage: f.valuation() # optional - sage.rings.finite_rings 1997 - sage: R(19).valuation() + sage: R(19).valuation() # optional - sage.rings.finite_rings 0 - sage: R(0).valuation() + sage: R(0).valuation() # optional - sage.rings.finite_rings +Infinity """ if not self.__coeffs: @@ -243,10 +245,10 @@ def _derivative(self, var=None): Check that :trac:`28187` is fixed:: sage: R = PolynomialRing(ZZ, 't', sparse=True) - sage: t, u = var('t, u') - sage: R.gen()._derivative(t) + sage: t, u = var('t, u') # optional - sage.symbolic + sage: R.gen()._derivative(t) # optional - sage.symbolic 1 - sage: R.gen()._derivative(u) + sage: R.gen()._derivative(u) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: cannot differentiate with respect to u @@ -417,14 +419,14 @@ def __getitem__(self, n): EXAMPLES:: sage: R. = PolynomialRing(RDF, sparse=True) - sage: e = RDF(e) - sage: f = sum(e^n*w^n for n in range(4)); f # abs tol 1.1e-14 + sage: e = RDF(e) # optional - sage.symbolic + sage: f = sum(e^n*w^n for n in range(4)); f # abs tol 1.1e-14 # optional - sage.symbolic 20.085536923187664*w^3 + 7.3890560989306495*w^2 + 2.718281828459045*w + 1.0 - sage: f[1] # abs tol 5e-16 + sage: f[1] # abs tol 5e-16 # optional - sage.symbolic 2.718281828459045 - sage: f[5] + sage: f[5] # optional - sage.symbolic 0.0 - sage: f[-1] + sage: f[-1] # optional - sage.symbolic 0.0 sage: R. = PolynomialRing(RealField(19), sparse=True) sage: f = (2-3.5*x)^3; f @@ -547,14 +549,14 @@ def __floordiv__(self, right): EXAMPLES:: - sage: R. = PolynomialRing(QQbar, sparse=True) - sage: f = (1+2*x)^3 + 3*x; f + sage: R. = PolynomialRing(QQbar, sparse=True) # optional - sage.rings.number_field + sage: f = (1+2*x)^3 + 3*x; f # optional - sage.rings.number_field 8*x^3 + 12*x^2 + 9*x + 1 - sage: g = f // (1+2*x); g + sage: g = f // (1+2*x); g # optional - sage.rings.number_field 4*x^2 + 4*x + 5/2 - sage: f - g * (1+2*x) + sage: f - g * (1+2*x) # optional - sage.rings.number_field -3/2 - sage: f.quo_rem(1+2*x) + sage: f.quo_rem(1+2*x) # optional - sage.rings.number_field (4*x^2 + 4*x + 5/2, -3/2) """ @@ -734,7 +736,7 @@ def _richcmp_(self, other, op): def shift(self, n): r""" - Returns this polynomial multiplied by the power `x^n`. + Return this polynomial multiplied by the power `x^n`. If `n` is negative, terms below `x^n` will be discarded. Does not change this polynomial. @@ -785,12 +787,12 @@ def shift(self, n): @coerce_binop def quo_rem(self, other): """ - Returns the quotient and remainder of the Euclidean division of + Return the quotient and remainder of the Euclidean division of ``self`` and ``other``. - Raises ZerodivisionError if ``other`` is zero. + Raises :class:`ZeroDivisionError` if ``other`` is zero. - Raises ArithmeticError if ``other`` has a nonunit leading coefficient + Raises :class:`ArithmeticError` if ``other`` has a nonunit leading coefficient and this causes the Euclidean division to fail. EXAMPLES:: @@ -808,7 +810,8 @@ def quo_rem(self, other): sage: f.quo_rem(g) Traceback (most recent call last): ... - ArithmeticError: Division non exact (consider coercing to polynomials over the fraction field) + ArithmeticError: Division non exact + (consider coercing to polynomials over the fraction field) sage: g = 0 sage: f.quo_rem(g) Traceback (most recent call last): @@ -824,12 +827,12 @@ def quo_rem(self, other): Polynomials over noncommutative rings are also allowed:: - sage: HH = QuaternionAlgebra(QQ, -1, -1) - sage: P. = PolynomialRing(HH, sparse=True) - sage: f = P.random_element(5) - sage: g = P.random_element((0, 5)) - sage: q, r = f.quo_rem(g) - sage: f == q*g + r + sage: HH = QuaternionAlgebra(QQ, -1, -1) # optional - sage.combinat sage.modules + sage: P. = PolynomialRing(HH, sparse=True) # optional - sage.combinat sage.modules + sage: f = P.random_element(5) # optional - sage.combinat sage.modules + sage: g = P.random_element((0, 5)) # optional - sage.combinat sage.modules + sage: q, r = f.quo_rem(g) # optional - sage.combinat sage.modules + sage: f == q*g + r # optional - sage.combinat sage.modules True TESTS:: @@ -892,7 +895,7 @@ def quo_rem(self, other): @coerce_binop def gcd(self,other,algorithm=None): - """ + r""" Return the gcd of this polynomial and ``other`` INPUT: @@ -904,27 +907,27 @@ def gcd(self,other,algorithm=None): Two algorithms are provided: - - ``generic``: Uses the generic implementation, which depends on the + - ``generic`` -- Uses the generic implementation, which depends on the base ring being a UFD or a field. - - ``dense``: The polynomials are converted to the dense representation, + - ``dense`` -- The polynomials are converted to the dense representation, their gcd is computed and is converted back to the sparse representation. - Default is ``dense`` for polynomials over ZZ and ``generic`` in the + Default is ``dense`` for polynomials over `\ZZ` and ``generic`` in the other cases. EXAMPLES:: - sage: R. = PolynomialRing(ZZ,sparse=True) + sage: R. = PolynomialRing(ZZ, sparse=True) sage: p = x^6 + 7*x^5 + 8*x^4 + 6*x^3 + 2*x^2 + x + 2 sage: q = 2*x^4 - x^3 - 2*x^2 - 4*x - 1 - sage: gcd(p,q) + sage: gcd(p, q) x^2 + x + 1 - sage: gcd(p, q, algorithm = "dense") + sage: gcd(p, q, algorithm="dense") x^2 + x + 1 - sage: gcd(p, q, algorithm = "generic") + sage: gcd(p, q, algorithm="generic") x^2 + x + 1 - sage: gcd(p, q, algorithm = "foobar") + sage: gcd(p, q, algorithm="foobar") Traceback (most recent call last): ... ValueError: Unknown algorithm 'foobar' @@ -971,7 +974,7 @@ def reverse(self, degree=None): """ Return this polynomial but with the coefficients reversed. - If an optional degree argument is given the coefficient list will be + If an optional degree argument is given, the coefficient list will be truncated or zero padded as necessary and the reverse polynomial will have the specified degree. @@ -993,7 +996,7 @@ def reverse(self, degree=None): def truncate(self, n): """ - Return the polynomial of degree `< n` equal to `self` modulo `x^n`. + Return the polynomial of degree `< n` equal to ``self`` modulo `x^n`. EXAMPLES:: @@ -1011,7 +1014,7 @@ def number_of_terms(self): EXAMPLES:: - sage: R. = PolynomialRing(ZZ,sparse=True) + sage: R. = PolynomialRing(ZZ, sparse=True) sage: p = x^100 - 3*x^10 + 12 sage: p.number_of_terms() 3 @@ -1058,17 +1061,17 @@ class Polynomial_generic_field(Polynomial_singular_repr, @coerce_binop def quo_rem(self, other): """ - Returns a tuple (quotient, remainder) where - self = quotient * other + remainder. + Return a tuple ``(quotient, remainder)`` where + ``self = quotient * other + remainder``. EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(y^2 - 2) - sage: P. = PolynomialRing(K) - sage: x.quo_rem(K(1)) + sage: K. = NumberField(y^2 - 2) # optional - sage.rings.number_field + sage: P. = PolynomialRing(K) # optional - sage.rings.number_field + sage: x.quo_rem(K(1)) # optional - sage.rings.number_field (x, 0) - sage: x.xgcd(K(1)) + sage: x.xgcd(K(1)) # optional - sage.rings.number_field (1, 0, 1) """ P = self.parent() @@ -1129,7 +1132,7 @@ class Polynomial_generic_cdv(Polynomial_generic_domain): """ def newton_slopes(self, repetition=True): """ - Returns a list of the Newton slopes of this polynomial. + Return a list of the Newton slopes of this polynomial. These are the valuations of the roots of this polynomial. @@ -1139,15 +1142,15 @@ def newton_slopes(self, repetition=True): EXAMPLES:: - sage: K = Qp(5) - sage: R. = K[] - sage: f = 5 + 3*t + t^4 + 25*t^10 - sage: f.newton_polygon() + sage: K = Qp(5) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: f = 5 + 3*t + t^4 + 25*t^10 # optional - sage.rings.padics + sage: f.newton_polygon() # optional - sage.rings.padics Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0), (10, 2) - sage: f.newton_slopes() + sage: f.newton_slopes() # optional - sage.rings.padics [1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3] - sage: f.newton_slopes(repetition=False) + sage: f.newton_slopes(repetition=False) # optional - sage.rings.padics [1, 0, -1/3] AUTHOR: @@ -1159,7 +1162,7 @@ def newton_slopes(self, repetition=True): def newton_polygon(self): r""" - Returns a list of vertices of the Newton polygon of this polynomial. + Return a list of vertices of the Newton polygon of this polynomial. .. NOTE:: @@ -1167,15 +1170,15 @@ def newton_polygon(self): EXAMPLES:: - sage: K = Qp(5) - sage: R. = K[] - sage: f = 5 + 3*t + t^4 + 25*t^10 - sage: f.newton_polygon() + sage: K = Qp(5) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: f = 5 + 3*t + t^4 + 25*t^10 # optional - sage.rings.padics + sage: f.newton_polygon() # optional - sage.rings.padics Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0), (10, 2) - sage: g = f + K(0,0)*t^4; g + sage: g = f + K(0,0)*t^4; g # optional - sage.rings.padics (5^2 + O(5^22))*t^10 + O(5^0)*t^4 + (3 + O(5^20))*t + 5 + O(5^21) - sage: g.newton_polygon() + sage: g.newton_polygon() # optional - sage.rings.padics Traceback (most recent call last): ... PrecisionError: The coefficient of t^4 has not enough precision @@ -1184,10 +1187,10 @@ def newton_polygon(self): Check that :trac:`22936` is fixed:: - sage: S. = PowerSeriesRing(GF(5)) - sage: R. = S[] - sage: p = x^2+y+x*y^2 - sage: p.newton_polygon() + sage: S. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: R. = S[] # optional - sage.rings.finite_rings + sage: p = x^2 + y + x*y^2 # optional - sage.rings.finite_rings + sage: p.newton_polygon() # optional - sage.rings.finite_rings Finite Newton polygon with 3 vertices: (0, 2), (1, 0), (2, 1) AUTHOR: @@ -1222,16 +1225,16 @@ def hensel_lift(self, a): EXAMPLES:: - sage: K = Qp(5, 10) - sage: P. = PolynomialRing(K) - sage: f = x^2 + 1 - sage: root = f.hensel_lift(2); root + sage: K = Qp(5, 10) # optional - sage.rings.padics + sage: P. = PolynomialRing(K) # optional - sage.rings.padics + sage: f = x^2 + 1 # optional - sage.rings.padics + sage: root = f.hensel_lift(2); root # optional - sage.rings.padics 2 + 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10) - sage: f(root) + sage: f(root) # optional - sage.rings.padics O(5^10) - sage: g = (x^2 + 1)*(x - 7) - sage: g.hensel_lift(2) # here, 2 is a multiple root modulo p + sage: g = (x^2 + 1) * (x - 7) # optional - sage.rings.padics + sage: g.hensel_lift(2) # here, 2 is a multiple root modulo p # optional - sage.rings.padics Traceback (most recent call last): ... ValueError: a is not close enough to a root of this polynomial @@ -1270,27 +1273,27 @@ def _factor_of_degree(self, deg): EXAMPLES:: - sage: K = Qp(5) - sage: R. = K[] - sage: K = Qp(5) - sage: R. = K[] - sage: f = 5 + 3*t + t^4 + 25*t^10 + sage: K = Qp(5) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: K = Qp(5) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: f = 5 + 3*t + t^4 + 25*t^10 # optional - sage.rings.padics - sage: g = f._factor_of_degree(4) - sage: (f % g).is_zero() + sage: g = f._factor_of_degree(4) # optional - sage.rings.padics + sage: (f % g).is_zero() # optional - sage.rings.padics True - sage: g = f._factor_of_degree(3) # not tested + sage: g = f._factor_of_degree(3) # not tested # optional - sage.rings.padics Traceback (most recent call last) ... KeyboardInterrupt: TESTS:: - sage: S. = PowerSeriesRing(GF(5)) - sage: R. = S[] - sage: p = x^2+y+x*y^2 - sage: p._factor_of_degree(1) + sage: S. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: R. = S[] # optional - sage.rings.finite_rings + sage: p = x^2 + y + x*y^2 # optional - sage.rings.finite_rings + sage: p._factor_of_degree(1) # optional - sage.rings.finite_rings (1 + O(x^20))*y + x^2 + x^5 + 2*x^8 + 4*x^14 + 2*x^17 + 2*x^20 + O(x^22) AUTHOR: @@ -1323,7 +1326,7 @@ def factor_of_slope(self, slope=None): """ INPUT: - - slope -- a rational number (default: the first slope + - ``slope`` -- a rational number (default: the first slope in the Newton polygon of ``self``) OUTPUT: @@ -1334,30 +1337,30 @@ def factor_of_slope(self, slope=None): EXAMPLES:: - sage: K = Qp(5) - sage: R. = K[] - sage: K = Qp(5) - sage: R. = K[] - sage: f = 5 + 3*t + t^4 + 25*t^10 - sage: f.newton_slopes() + sage: K = Qp(5) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: K = Qp(5) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: f = 5 + 3*t + t^4 + 25*t^10 # optional - sage.rings.padics + sage: f.newton_slopes() # optional - sage.rings.padics [1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3] - sage: g = f.factor_of_slope(0) - sage: g.newton_slopes() + sage: g = f.factor_of_slope(0) # optional - sage.rings.padics + sage: g.newton_slopes() # optional - sage.rings.padics [0, 0, 0] - sage: (f % g).is_zero() + sage: (f % g).is_zero() # optional - sage.rings.padics True - sage: h = f.factor_of_slope() - sage: h.newton_slopes() + sage: h = f.factor_of_slope() # optional - sage.rings.padics + sage: h.newton_slopes() # optional - sage.rings.padics [1] - sage: (f % h).is_zero() + sage: (f % h).is_zero() # optional - sage.rings.padics True If ``slope`` is not a slope of ``self``, the corresponding factor is `1`:: - sage: f.factor_of_slope(-1) + sage: f.factor_of_slope(-1) # optional - sage.rings.padics 1 + O(5^20) AUTHOR: @@ -1403,18 +1406,18 @@ def slope_factorization(self): EXAMPLES:: - sage: K = Qp(5) - sage: R. = K[] - sage: K = Qp(5) - sage: R. = K[] - sage: f = 5 + 3*t + t^4 + 25*t^10 - sage: f.newton_slopes() + sage: K = Qp(5) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: K = Qp(5) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: f = 5 + 3*t + t^4 + 25*t^10 # optional - sage.rings.padics + sage: f.newton_slopes() # optional - sage.rings.padics [1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3] - sage: F = f.slope_factorization() - sage: F.prod() == f + sage: F = f.slope_factorization() # optional - sage.rings.padics + sage: F.prod() == f # optional - sage.rings.padics True - sage: for (f,_) in F: + sage: for (f,_) in F: # optional - sage.rings.padics ....: print(f.newton_slopes()) [-1/3, -1/3, -1/3, -1/3, -1/3, -1/3] [0, 0, 0] @@ -1422,11 +1425,13 @@ def slope_factorization(self): TESTS:: - sage: S. = PowerSeriesRing(GF(5)) - sage: R. = S[] - sage: p = x^2+y+x*y^2 - sage: p.slope_factorization() - (x) * ((x + O(x^22))*y + 1 + 4*x^3 + 4*x^6 + 3*x^9 + x^15 + 3*x^18 + O(x^21)) * ((x^-1 + O(x^20))*y + x + x^4 + 2*x^7 + 4*x^13 + 2*x^16 + 2*x^19 + O(x^22)) + sage: S. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: R. = S[] # optional - sage.rings.finite_rings + sage: p = x^2 + y + x*y^2 # optional - sage.rings.finite_rings + sage: p.slope_factorization() # optional - sage.rings.finite_rings + (x) + * ((x + O(x^22))*y + 1 + 4*x^3 + 4*x^6 + 3*x^9 + x^15 + 3*x^18 + O(x^21)) + * ((x^-1 + O(x^20))*y + x + x^4 + 2*x^7 + 4*x^13 + 2*x^16 + 2*x^19 + O(x^22)) AUTHOR: @@ -1478,11 +1483,11 @@ def _roots(self, secure, minval, hint): TESTS:: - sage: R = Zp(2) - sage: S. = R[] - sage: P = (x-1) * (x-2) * (x-4) * (x-8) * (x-16) - sage: Q = P^2 - sage: Q.roots(algorithm="sage") # indirect doctest + sage: R = Zp(2) # optional - sage.rings.padics + sage: S. = R[] # optional - sage.rings.padics + sage: P = (x-1) * (x-2) * (x-4) * (x-8) * (x-16) # optional - sage.rings.padics + sage: Q = P^2 # optional - sage.rings.padics + sage: Q.roots(algorithm="sage") # indirect doctest # optional - sage.rings.padics [(2^4 + O(2^14), 2), (2^3 + O(2^13), 2), (2^2 + O(2^12), 2), diff --git a/src/sage/rings/polynomial/polynomial_gf2x.pyx b/src/sage/rings/polynomial/polynomial_gf2x.pyx index 97b565e9cd0..552e6d72de6 100644 --- a/src/sage/rings/polynomial/polynomial_gf2x.pyx +++ b/src/sage/rings/polynomial/polynomial_gf2x.pyx @@ -34,8 +34,8 @@ from sage.matrix.matrix_mod2_dense cimport Matrix_mod2_dense from sage.misc.cachefunc import cached_method cdef class Polynomial_GF2X(Polynomial_template): - """ - Univariate Polynomials over GF(2) via NTL's GF2X. + r""" + Univariate Polynomials over `\GF{2}` via NTL's GF2X. EXAMPLES:: @@ -44,8 +44,8 @@ cdef class Polynomial_GF2X(Polynomial_template): x^3 + x^2 + 1 """ def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): - """ - Create a new univariate polynomials over GF(2). + r""" + Create a new univariate polynomials over `\GF{2}`. EXAMPLES:: @@ -117,7 +117,7 @@ cdef class Polynomial_GF2X(Polynomial_template): - ``g`` -- a polynomial - ``h`` -- a polynomial - - ``algorithm`` -- either 'native' or 'ntl' (default: 'native') + - ``algorithm`` -- either ``'native'`` or ``'ntl'`` (default: ``'native'``) EXAMPLES:: @@ -132,7 +132,7 @@ cdef class Polynomial_GF2X(Polynomial_template): sage: f = x^29 + x^24 + x^22 + x^21 + x^20 + x^16 + x^15 + x^14 + x^10 + x^9 + x^8 + x^7 + x^6 + x^5 + x^2 sage: g = x^31 + x^30 + x^28 + x^26 + x^24 + x^21 + x^19 + x^18 + x^11 + x^10 + x^9 + x^8 + x^5 + x^2 + 1 sage: h = x^30 + x^28 + x^26 + x^25 + x^24 + x^22 + x^21 + x^18 + x^17 + x^15 + x^13 + x^12 + x^11 + x^10 + x^9 + x^4 - sage: f.modular_composition(g,h) == f(g) % h + sage: f.modular_composition(g, h) == f(g) % h True AUTHORS: @@ -259,7 +259,7 @@ cdef class Polynomial_GF2X(Polynomial_template): @cached_method def is_irreducible(self): r""" - Return whether this polynomial is irreducible over `\GF{2}`.` + Return whether this polynomial is irreducible over `\GF{2}`. EXAMPLES:: diff --git a/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx b/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx index 55cb653f6dc..af32b6c624b 100644 --- a/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx @@ -637,7 +637,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): cpdef _add_(self, right): r""" - Returns self plus right. + Return ``self`` plus ``right``. EXAMPLES:: @@ -657,7 +657,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): cpdef _sub_(self, right): r""" - Return self minus right. + Return ``self`` minus ``right``. EXAMPLES:: @@ -677,7 +677,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): cpdef _neg_(self): r""" - Returns negative of self. + Return negative of ``self``. EXAMPLES:: @@ -695,7 +695,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): @coerce_binop def quo_rem(self, Polynomial_integer_dense_flint right): r""" - Attempts to divide self by right, and return a quotient and remainder. + Attempts to divide ``self`` by ``right``, and return a quotient and remainder. EXAMPLES:: @@ -764,7 +764,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): cpdef bint is_zero(self) except -1: """ - Returns True if self is equal to zero. + Return ``True`` if ``self`` is equal to zero. EXAMPLES:: @@ -780,7 +780,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): cpdef bint is_one(self) except -1: """ - Returns True if self is equal to one. + Return ``True`` if ``self`` is equal to one. EXAMPLES:: @@ -796,7 +796,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): def __bool__(self): """ - Check if self is not zero. + Check if ``self`` is not zero. EXAMPLES:: @@ -813,14 +813,14 @@ cdef class Polynomial_integer_dense_flint(Polynomial): @coerce_binop def gcd(self, right): r""" - Return the GCD of self and right. The leading + Return the GCD of ``self`` and ``right``. The leading coefficient need not be 1. EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: f = (6*x + 47)*(7*x^2 - 2*x + 38) - sage: g = (6*x + 47)*(3*x^3 + 2*x + 1) + sage: f = (6*x + 47) * (7*x^2 - 2*x + 38) + sage: g = (6*x + 47) * (3*x^3 + 2*x + 1) sage: f.gcd(g) 6*x + 47 """ @@ -840,16 +840,16 @@ cdef class Polynomial_integer_dense_flint(Polynomial): @coerce_binop def lcm(self, right): """ - Return the LCM of self and right. + Return the LCM of ``self`` and ``right``. EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: f = (6*x + 47)*(7*x^2 - 2*x + 38) - sage: g = (6*x + 47)*(3*x^3 + 2*x + 1) + sage: f = (6*x + 47) * (7*x^2 - 2*x + 38) + sage: g = (6*x + 47) * (3*x^3 + 2*x + 1) sage: h = f.lcm(g); h 126*x^6 + 951*x^5 + 486*x^4 + 6034*x^3 + 585*x^2 + 3706*x + 1786 - sage: h == (6*x + 47)*(7*x^2 - 2*x + 38)*(3*x^3 + 2*x + 1) + sage: h == (6*x + 47) * (7*x^2 - 2*x + 38) * (3*x^3 + 2*x + 1) True TESTS: @@ -868,9 +868,9 @@ cdef class Polynomial_integer_dense_flint(Polynomial): @coerce_binop def xgcd(self, right): - """ - Return a triple ``(g,s,t)`` such that `g = s*self + t*right` and such - that `g` is the `gcd` of ``self`` and ``right`` up to a divisor of the + r""" + Return a triple `(g,s,t)` such that `g = s\cdot{}` ``self`` + `t\cdot{}` ``right`` and such + that `g` is the gcd of ``self`` and ``right`` up to a divisor of the resultant of ``self`` and ``other``. As integer polynomials do not form a principal ideal domain, it is not @@ -886,14 +886,14 @@ cdef class Polynomial_integer_dense_flint(Polynomial): sage: P. = PolynomialRing(ZZ) - sage: (x+2).xgcd(x+4) + sage: (x + 2).xgcd(x + 4) (2, -1, 1) - sage: (x+2).resultant(x+4) + sage: (x + 2).resultant(x + 4) 2 - sage: (x+2).gcd(x+4) + sage: (x + 2).gcd(x + 4) 1 - sage: F = (x^2 + 2)*x^3; G = (x^2+2)*(x-3) + sage: F = (x^2 + 2)*x^3; G = (x^2 + 2) * (x - 3) sage: g, u, v = F.xgcd(G) sage: g, u, v (27*x^2 + 54, 1, -x^2 - 3*x - 9) @@ -906,7 +906,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): sage: zero.xgcd(x) (x, 0, 1) - sage: F = (x-3)^3; G = (x-15)^2 + sage: F = (x - 3)^3; G = (x - 15)^2 sage: g, u, v = F.xgcd(G) sage: g, u, v (2985984, -432*x + 8208, 432*x^2 + 864*x + 14256) @@ -960,7 +960,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): cpdef _mul_(self, right): r""" - Returns self multiplied by right. + Return ``self`` multiplied by ``right``. EXAMPLES:: @@ -1008,7 +1008,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): cpdef _lmul_(self, Element right): r""" - Returns self multiplied by right, where right is a scalar (integer). + Return ``self`` multiplied by ``right``, where ``right`` is a scalar (integer). EXAMPLES:: @@ -1026,7 +1026,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): cpdef _rmul_(self, Element right): r""" - Returns self multiplied by right, where right is a scalar (integer). + Return ``self`` multiplied by ``right``, where right is a scalar (integer). EXAMPLES:: @@ -1260,7 +1260,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): EXAMPLES:: sage: x = polygen(ZZ) - sage: p = 1+x+2*x^2 + sage: p = 1 + x + 2*x^2 sage: q5 = p.inverse_series_trunc(5) sage: q5 -x^4 + 3*x^3 - x^2 - x + 1 @@ -1345,7 +1345,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): def real_root_intervals(self): """ - Returns isolating intervals for the real roots of this + Return isolating intervals for the real roots of this polynomial. EXAMPLES: @@ -1372,7 +1372,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): """ Return the degree of this polynomial. - The zero polynomial has degree -1. + The zero polynomial has degree `-1`. EXAMPLES:: @@ -1431,7 +1431,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): def discriminant(self, proof=True): r""" - Return the discriminant of self, which is by definition + Return the discriminant of ``self``, which is by definition .. MATH:: @@ -1490,11 +1490,11 @@ cdef class Polynomial_integer_dense_flint(Polynomial): def squarefree_decomposition(Polynomial_integer_dense_flint self): """ - Return the square-free decomposition of self. This is - a partial factorization of self into square-free, relatively + Return the square-free decomposition of ``self``. This is + a partial factorization of ``self`` into square-free, relatively prime polynomials. - This is a wrapper for the NTL function SquareFreeDecomp. + This is a wrapper for the NTL function ``SquareFreeDecomp``. EXAMPLES:: @@ -1616,7 +1616,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): def factor(self): """ This function overrides the generic polynomial factorization to - make a somewhat intelligent decision to use Pari or NTL based on + make a somewhat intelligent decision to use PARI or NTL based on some benchmarking. Note: This function factors the content of the polynomial, @@ -1626,11 +1626,11 @@ cdef class Polynomial_integer_dense_flint(Polynomial): EXAMPLES:: - sage: R.=ZZ[] - sage: f=x^4-1 + sage: R. = ZZ[] + sage: f = x^4 - 1 sage: f.factor() (x - 1) * (x + 1) * (x^2 + 1) - sage: f=1-x + sage: f = 1 - x sage: f.factor() (-1) * (x - 1) sage: f.factor().unit() @@ -1651,15 +1651,13 @@ cdef class Polynomial_integer_dense_flint(Polynomial): def factor_mod(self, p): """ - Return the factorization of self modulo the prime `p`. + Return the factorization of ``self`` modulo the prime `p`. INPUT: - ``p`` -- prime - OUTPUT: - - factorization of self reduced modulo p. + OUTPUT: factorization of ``self`` reduced modulo `p`. EXAMPLES:: @@ -1667,13 +1665,13 @@ cdef class Polynomial_integer_dense_flint(Polynomial): sage: f = -3*x*(x-2)*(x-9) + x sage: f.factor_mod(3) x - sage: f = -3*x*(x-2)*(x-9) + sage: f = -3 * x * (x - 2) * (x - 9) sage: f.factor_mod(3) Traceback (most recent call last): ... ArithmeticError: factorization of 0 is not defined - sage: f = 2*x*(x-2)*(x-9) + sage: f = 2 * x * (x - 2) * (x - 9) sage: f.factor_mod(7) (2) * x * (x + 5)^2 """ @@ -1691,7 +1689,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): def factor_padic(self, p, prec=10): """ - Return `p`-adic factorization of self to given precision. + Return `p`-adic factorization of ``self`` to given precision. INPUT: @@ -1699,22 +1697,22 @@ cdef class Polynomial_integer_dense_flint(Polynomial): - ``prec`` -- integer; the precision - OUTPUT: - - - factorization of ``self`` over the completion at `p`. + OUTPUT: factorization of ``self`` over the completion at `p`. EXAMPLES:: sage: R. = PolynomialRing(ZZ) sage: f = x^2 + 1 sage: f.factor_padic(5, 4) - ((1 + O(5^4))*x + 2 + 5 + 2*5^2 + 5^3 + O(5^4)) * ((1 + O(5^4))*x + 3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4)) + ((1 + O(5^4))*x + 2 + 5 + 2*5^2 + 5^3 + O(5^4)) + * ((1 + O(5^4))*x + 3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4)) A more difficult example:: sage: f = 100 * (5*x + 1)^2 * (x + 5)^2 sage: f.factor_padic(5, 10) - (4 + O(5^10)) * (5 + O(5^11))^2 * ((1 + O(5^10))*x + 5 + O(5^10))^2 * ((5 + O(5^10))*x + 1 + O(5^10))^2 + (4 + O(5^10)) * (5 + O(5^11))^2 * ((1 + O(5^10))*x + 5 + O(5^10))^2 + * ((5 + O(5^10))*x + 1 + O(5^10))^2 """ from sage.rings.padics.factory import Zp @@ -1753,20 +1751,18 @@ cdef class Polynomial_integer_dense_flint(Polynomial): @coerce_binop def resultant(self, other, proof=True): """ - Returns the resultant of self and other, which must lie in the same + Return the resultant of ``self`` and ``other``, which must lie in the same polynomial ring. - If ``proof = False`` (the default is ``proof=True``), then this function may + If ``proof=False`` (the default is ``proof=True``), then this function may use a randomized strategy that errors with probability no more than `2^{-80}`. INPUT: - - other -- a polynomial - - OUTPUT: + - ``other`` -- a polynomial - an element of the base ring of the polynomial ring + OUTPUT: an element of the base ring of the polynomial ring EXAMPLES:: @@ -1842,7 +1838,7 @@ cdef class Polynomial_integer_dense_flint(Polynomial): def revert_series(self, n): r""" - Return a polynomial `f` such that `f(self(x)) = self(f(x)) = x mod x^n`. + Return a polynomial `f` such that `f(` ``self`` `(x)) =` ``self`` `(f(x)) = x` (mod `x^n`). EXAMPLES:: diff --git a/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx b/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx index 38e2470f1f1..0d9da73602e 100644 --- a/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx +++ b/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx @@ -469,7 +469,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): cpdef _neg_(self): r""" - Returns negative of self. + Returns negative of ``self``. EXAMPLES:: @@ -486,13 +486,13 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): @coerce_binop def quo_rem(self, right): r""" - Attempts to divide self by right, and return a quotient and remainder. + Attempt to divide ``self`` by ``right``, and return a quotient and remainder. - If right is monic, then it returns ``(q, r)`` where `self = q * right + r` - and `deg(r) < deg(right)`. + If right is monic, then it returns ``(q, r)`` where ``self = q * right + r`` + and ``deg(r) < deg(right)``. - If right is not monic, then it returns `(q, 0)` where q = self/right if - right exactly divides self, otherwise it raises an exception. + If right is not monic, then it returns `(q, 0)` where ``q = self/right`` if + ``right`` exactly divides ``self``, otherwise it raises an exception. EXAMPLES:: @@ -574,14 +574,14 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): @coerce_binop def gcd(self, right): r""" - Return the GCD of self and right. The leading + Return the GCD of ``self`` and ``right``. The leading coefficient need not be 1. EXAMPLES:: sage: R. = PolynomialRing(ZZ, implementation='NTL') - sage: f = (6*x + 47)*(7*x^2 - 2*x + 38) - sage: g = (6*x + 47)*(3*x^3 + 2*x + 1) + sage: f = (6*x + 47) * (7*x^2 - 2*x + 38) + sage: g = (6*x + 47) * (3*x^3 + 2*x + 1) sage: f.gcd(g) 6*x + 47 """ @@ -596,16 +596,16 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): @coerce_binop def lcm(self, right): """ - Return the LCM of self and right. + Return the LCM of ``self`` and ``right``. EXAMPLES:: sage: R. = PolynomialRing(ZZ, implementation='NTL') - sage: f = (6*x + 47)*(7*x^2 - 2*x + 38) - sage: g = (6*x + 47)*(3*x^3 + 2*x + 1) + sage: f = (6*x + 47) * (7*x^2 - 2*x + 38) + sage: g = (6*x + 47) * (3*x^3 + 2*x + 1) sage: h = f.lcm(g); h 126*x^6 + 951*x^5 + 486*x^4 + 6034*x^3 + 585*x^2 + 3706*x + 1786 - sage: h == (6*x + 47)*(7*x^2 - 2*x + 38)*(3*x^3 + 2*x + 1) + sage: h == (6*x + 47) * (7*x^2 - 2*x + 38) * (3*x^3 + 2*x + 1) True TESTS: @@ -625,7 +625,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): @coerce_binop def xgcd(self, right): """ - This function can't in general return ``(g,s,t)`` as above, + This function can't in general return `(g,s,t)` as above, since they need not exist. Instead, over the integers, we first multiply `g` by a divisor of the resultant of `a/g` and `b/g`, up to sign, and return ``g, u, v`` such that @@ -634,7 +634,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): If ``self`` and ``right`` are coprime as polynomials over the rationals, then ``g`` is guaranteed to be the resultant of - self and right, as a constant polynomial. + ``self`` and ``right``, as a constant polynomial. EXAMPLES:: @@ -815,7 +815,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): def degree(self, gen=None): """ Return the degree of this polynomial. The zero polynomial has - degree -1. + degree `-1`. EXAMPLES:: @@ -833,11 +833,11 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): def discriminant(self, proof=True): r""" - Return the discriminant of self, which is by definition + Return the discriminant of ``self``, which is by definition .. MATH:: - (-1)^{m(m-1)/2} {\mbox{\tt resultant}}(a, a')/lc(a), + (-1)^{m(m-1)/2} \text{resultant}(a, a')/lc(a), where `m = deg(a)`, and `lc(a)` is the leading coefficient of a. If ``proof`` is False (the default is True), then this function @@ -863,7 +863,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): """ EXAMPLES:: - sage: t = PolynomialRing(ZZ,"t",implementation='NTL').gen() + sage: t = PolynomialRing(ZZ, "t", implementation='NTL').gen() sage: f = t^3 + 3*t - 17 sage: pari(f) t^3 + 3*t - 17 @@ -875,11 +875,11 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): def squarefree_decomposition(self): """ - Return the square-free decomposition of self. This is - a partial factorization of self into square-free, relatively + Return the square-free decomposition of ``self``. This is + a partial factorization of ``self`` into square-free, relatively prime polynomials. - This is a wrapper for the NTL function SquareFreeDecomp. + This is a wrapper for the NTL function ``SquareFreeDecomp``. EXAMPLES:: @@ -893,7 +893,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): Verify that :trac:`13053` has been resolved:: sage: R. = PolynomialRing(ZZ, implementation='NTL') - sage: f=-x^2 + sage: f = -x^2 sage: f.squarefree_decomposition() (-1) * x^2 @@ -977,7 +977,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): def factor(self): """ This function overrides the generic polynomial factorization to - make a somewhat intelligent decision to use Pari or NTL based on + make a somewhat intelligent decision to use PARI or NTL based on some benchmarking. Note: This function factors the content of the polynomial, @@ -987,11 +987,11 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): EXAMPLES:: - sage: R.=ZZ[] - sage: f=x^4-1 + sage: R. = ZZ[] + sage: f = x^4 - 1 sage: f.factor() (x - 1) * (x + 1) * (x^2 + 1) - sage: f=1-x + sage: f = 1 - x sage: f.factor() (-1) * (x - 1) sage: f.factor().unit() @@ -1011,13 +1011,13 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): def factor_mod(self, p): """ - Return the factorization of self modulo the prime p. + Return the factorization of ``self`` modulo the prime `p`. INPUT: - ``p`` -- prime - OUTPUT: factorization of self reduced modulo p. + OUTPUT: factorization of ``self`` reduced modulo `p`. EXAMPLES:: @@ -1049,7 +1049,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): def factor_padic(self, p, prec=10): """ - Return `p`-adic factorization of self to given precision. + Return `p`-adic factorization of ``self`` to given precision. INPUT: @@ -1066,13 +1066,15 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): sage: R. = PolynomialRing(ZZ, implementation='NTL') sage: f = x^2 + 1 sage: f.factor_padic(5, 4) - ((1 + O(5^4))*x + 2 + 5 + 2*5^2 + 5^3 + O(5^4)) * ((1 + O(5^4))*x + 3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4)) + ((1 + O(5^4))*x + 2 + 5 + 2*5^2 + 5^3 + O(5^4)) + * ((1 + O(5^4))*x + 3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4)) A more difficult example:: sage: f = 100 * (5*x + 1)^2 * (x + 5)^2 sage: f.factor_padic(5, 10) - (4 + O(5^10)) * (5 + O(5^11))^2 * ((1 + O(5^10))*x + 5 + O(5^10))^2 * ((5 + O(5^10))*x + 1 + O(5^10))^2 + (4 + O(5^10)) * (5 + O(5^11))^2 * ((1 + O(5^10))*x + 5 + O(5^10))^2 + * ((5 + O(5^10))*x + 1 + O(5^10))^2 """ from sage.rings.padics.factory import Zp @@ -1097,11 +1099,11 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): EXAMPLES:: - sage: x = PolynomialRing(ZZ,'x',implementation='NTL').0 + sage: x = PolynomialRing(ZZ, 'x', implementation='NTL').0 sage: f = x^3 + 3*x - 17 sage: f.list() [-17, 3, 0, 1] - sage: f = PolynomialRing(ZZ,'x',implementation='NTL')(0) + sage: f = PolynomialRing(ZZ, 'x', implementation='NTL')(0) sage: f.list() [] """ @@ -1111,23 +1113,21 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): @coerce_binop def resultant(self, other, proof=True): """ - Returns the resultant of self and other, which must lie in the same + Returns the resultant of ``self`` and ``other``, which must lie in the same polynomial ring. - If proof = False (the default is proof=True), then this function may use a + If ``proof=False`` (the default is ``proof=True``), then this function may use a randomized strategy that errors with probability no more than `2^{-80}`. INPUT: - - other -- a polynomial + - ``other`` -- a polynomial - OUTPUT: - - an element of the base ring of the polynomial ring + OUTPUT: an element of the base ring of the polynomial ring EXAMPLES:: - sage: x = PolynomialRing(ZZ,'x',implementation='NTL').0 + sage: x = PolynomialRing(ZZ, 'x', implementation='NTL').0 sage: f = x^3 + x + 1; g = x^3 - x - 1 sage: r = f.resultant(g); r -8 diff --git a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx index e0621f2c4a4..6021e96d3bc 100644 --- a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +++ b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx @@ -85,7 +85,7 @@ cdef class Polynomial_dense_mod_n(Polynomial): sage: R. = PolynomialRing(Integers(100), implementation='NTL') sage: p = 3*x sage: q = 7*x - sage: p+q + sage: p + q 10*x sage: R. = PolynomialRing(Integers(8), implementation='NTL') sage: parent(p) @@ -172,7 +172,7 @@ cdef class Polynomial_dense_mod_n(Polynomial): """ EXAMPLES:: - sage: t = PolynomialRing(IntegerModRing(17),"t", implementation='NTL').gen() + sage: t = PolynomialRing(IntegerModRing(17), "t", implementation='NTL').gen() sage: f = t^3 + 3*t - 17 sage: pari(f) Mod(1, 17)*t^3 + Mod(3, 17)*t @@ -202,7 +202,7 @@ cdef class Polynomial_dense_mod_n(Polynomial): sage: R. = PolynomialRing(Integers(100), implementation='NTL') sage: from sage.rings.polynomial.polynomial_modn_dense_ntl import Polynomial_dense_mod_n - sage: f = Polynomial_dense_mod_n(R,[5,10,13,1,4]); f + sage: f = Polynomial_dense_mod_n(R, [5,10,13,1,4]); f 4*x^4 + x^3 + 13*x^2 + 10*x + 5 sage: f[2] 13 @@ -248,8 +248,8 @@ cdef class Polynomial_dense_mod_n(Polynomial): @coerce_binop def quo_rem(self, right): """ - Returns a tuple (quotient, remainder) where self = quotient*other + - remainder. + Return a tuple ``(quotient, remainder)`` where ``self = quotient*other + + remainder``. """ v = self.__poly.quo_rem((right).__poly) P = self.parent() @@ -257,7 +257,7 @@ cdef class Polynomial_dense_mod_n(Polynomial): def shift(self, n): r""" - Returns this polynomial multiplied by the power `x^n`. If `n` is negative, + Return this polynomial multiplied by the power `x^n`. If `n` is negative, terms below `x^n` will be discarded. Does not change this polynomial. EXAMPLES:: @@ -475,7 +475,7 @@ def small_roots(self, X=None, beta=1.0, epsilon=None, **kwds): To compute its roots we need to factor the modulus `N` and use the Chinese remainder theorem:: - sage: p,q = N.prime_divisors() + sage: p, q = N.prime_divisors() sage: f.change_ring(GF(p)).roots() [(4, 1)] sage: f.change_ring(GF(q)).roots() @@ -510,7 +510,7 @@ def small_roots(self, X=None, beta=1.0, epsilon=None, **kwds): sage: K = ZZ.random_element(0, 2^Kbits) - and pad it with 512-56=456 1s:: + and pad it with `512-56=456` 1s:: sage: Kdigits = K.digits(2) sage: M = [0]*Kbits + [1]*(Nbits-Kbits) @@ -688,7 +688,7 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): def int_list(self): """ - Returns the coefficients of self as efficiently as possible as a + Return the coefficients of ``self`` as efficiently as possible as a list of python ints. EXAMPLES:: @@ -731,7 +731,7 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): TESTS:: sage: R. = PolynomialRing(Integers(100), implementation='NTL') - sage: (x+5) + (x^2 - 6) + sage: (x + 5) + (x^2 - 6) x^2 + x + 99 """ cdef Polynomial_dense_modn_ntl_zz right = _right @@ -748,7 +748,7 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): TESTS:: sage: R. = PolynomialRing(Integers(100), implementation='NTL') - sage: (x+5) - (x^2 - 6) + sage: (x + 5) - (x^2 - 6) 99*x^2 + x + 11 """ cdef Polynomial_dense_modn_ntl_zz right = _right @@ -765,7 +765,7 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): TESTS:: sage: R. = PolynomialRing(Integers(100), implementation='NTL') - sage: (x+5) * (x^2 - 1) + sage: (x + 5) * (x^2 - 1) x^3 + 5*x^2 + 99*x + 95 """ cdef Polynomial_dense_modn_ntl_zz right = _right @@ -919,9 +919,9 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): @coerce_binop def quo_rem(self, right): - """ - Returns `q` and `r`, with the degree of `r` less than the degree of `right`, - such that `q * right + r = self`. + r""" + Return `q` and `r`, with the degree of `r` less than the degree of ``right``, + such that `q \cdot` ``right`` `{}+ r =` ``self``. EXAMPLES:: @@ -946,7 +946,7 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): cpdef _floordiv_(self, right): """ - Returns the whole part of self/right, without remainder. + Return the whole part of ``self``/``right``, without remainder. For q = n // d, we have deg(n - q*d) < deg(d) @@ -1043,7 +1043,7 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): def _derivative(self, var=None): r""" - Return the formal derivative of self with respect to ``var``. + Return the formal derivative of ``self`` with respect to ``var``. ``var`` must be either the generator of the polynomial ring to which this polynomial belongs, or ``None`` (either way the behaviour is the @@ -1140,8 +1140,8 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): def valuation(self): """ - Returns the valuation of self, that is, the power of the - lowest non-zero monomial of self. + Return the valuation of ``self``, that is, the power of the + lowest non-zero monomial of ``self``. EXAMPLES:: @@ -1177,7 +1177,7 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): cpdef Polynomial truncate(self, long n): """ - Returns this polynomial mod `x^n`. + Return this polynomial mod `x^n`. EXAMPLES:: @@ -1193,14 +1193,14 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): def __call__(self, *args, **kwds): """ - Evaluate self at x. If x is a single argument coercible into - the base ring of self, this is done directly in NTL, otherwise + Evaluate self at ``x``. If ``x`` is a single argument coercible into + the base ring of ``self``, this is done directly in NTL, otherwise the generic Polynomial call code is used. EXAMPLES:: sage: R. = PolynomialRing(Integers(100), implementation='NTL') - sage: f = x^3+7 + sage: f = x^3 + 7 sage: f(5) 32 sage: f(5r) @@ -1303,7 +1303,7 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): TESTS:: sage: R. = PolynomialRing(Integers(10^30), implementation='NTL') - sage: (x+5) + (x^2 - 6) + sage: (x + 5) + (x^2 - 6) x^2 + x + 999999999999999999999999999999 """ cdef Polynomial_dense_modn_ntl_ZZ right = _right @@ -1320,7 +1320,7 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): TESTS:: sage: R. = PolynomialRing(Integers(10^30), implementation='NTL') - sage: (x+5) - (x^2 - 6) + sage: (x + 5) - (x^2 - 6) 999999999999999999999999999999*x^2 + x + 11 """ cdef Polynomial_dense_modn_ntl_ZZ right = _right @@ -1476,9 +1476,9 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): @coerce_binop def quo_rem(self, right): - """ - Returns `q` and `r`, with the degree of `r` less than the degree of `right`, - such that `q * right + r = self`. + r""" + Return `q` and `r`, with the degree of `r` less than the degree of ``right``, + such that `q \cdot` ``right`` `+ r =` ``self``. EXAMPLES:: @@ -1503,7 +1503,7 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): cpdef _floordiv_(self, right): """ - Returns the whole part of self/right, without remainder. + Return the whole part of ``self`` / ``right``, without remainder. For q = n // d, we have deg(n - q*d) < deg(d) @@ -1601,7 +1601,7 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): def _derivative(self, var=None): r""" - Return the formal derivative of self with respect to ``var``. + Return the formal derivative of ``self`` with respect to ``var``. ``var`` must be either the generator of the polynomial ring to which this polynomial belongs, or None (either way the behaviour is the @@ -1686,19 +1686,19 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): def valuation(self): """ - Returns the valuation of self, that is, the power of the - lowest non-zero monomial of self. + Return the valuation of ``self``, that is, the power of the + lowest non-zero monomial of ``self``. EXAMPLES:: sage: R. = PolynomialRing(Integers(10^50), implementation='NTL') sage: x.valuation() 1 - sage: f = x-3; f.valuation() + sage: f = x - 3; f.valuation() 0 sage: f = x^99; f.valuation() 99 - sage: f = x-x; f.valuation() + sage: f = x - x; f.valuation() +Infinity """ cdef long n @@ -1738,7 +1738,7 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): cpdef Polynomial truncate(self, long n): """ - Returns this polynomial mod `x^n`. + Return this polynomial mod `x^n`. EXAMPLES:: @@ -1754,14 +1754,14 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): def __call__(self, *args, **kwds): """ - Evaluate self at x. If x is a single argument coercible into - the base ring of self, this is done directly in NTL, otherwise + Evaluate ``self`` at ``x``. If ``x`` is a single argument coercible into + the base ring of ``self``, this is done directly in NTL, otherwise the generic Polynomial call code is used. EXAMPLES:: sage: R. = PolynomialRing(Integers(10^30), implementation='NTL') - sage: f = x^3+7 + sage: f = x^3 + 7 sage: f(5) 132 sage: f(5r) @@ -1796,7 +1796,7 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): cdef class Polynomial_dense_mod_p(Polynomial_dense_mod_n): """ - A dense polynomial over the integers modulo p, where p is prime. + A dense polynomial over the integers modulo `p`, where `p` is prime. """ @coerce_binop @@ -1811,8 +1811,8 @@ cdef class Polynomial_dense_mod_p(Polynomial_dense_mod_n): EXAMPLES:: - sage: R. = PolynomialRing(GF(3),implementation="NTL") - sage: f,g = x + 2, x^2 - 1 + sage: R. = PolynomialRing(GF(3), implementation="NTL") + sage: f, g = x + 2, x^2 - 1 sage: f.gcd(g) x + 2 @@ -1836,7 +1836,7 @@ cdef class Polynomial_dense_mod_p(Polynomial_dense_mod_n): EXAMPLES:: - sage: R. = PolynomialRing(GF(3),implementation='NTL') + sage: R. = PolynomialRing(GF(3), implementation='NTL') sage: x.xgcd(x) (x, 0, 1) sage: (x^2 - 1).xgcd(x - 1) @@ -1855,7 +1855,7 @@ cdef class Polynomial_dense_mod_p(Polynomial_dense_mod_n): @coerce_binop def resultant(self, other): """ - Returns the resultant of self and other, which must lie in the same + Return the resultant of ``self`` and ``other``, which must lie in the same polynomial ring. INPUT: @@ -1866,7 +1866,7 @@ cdef class Polynomial_dense_mod_p(Polynomial_dense_mod_n): EXAMPLES:: - sage: R. = PolynomialRing(GF(19),implementation='NTL') + sage: R. = PolynomialRing(GF(19), implementation='NTL') sage: f = x^3 + x + 1; g = x^3 - x - 1 sage: r = f.resultant(g); r 11 @@ -1880,7 +1880,7 @@ cdef class Polynomial_dense_mod_p(Polynomial_dense_mod_n): """ EXAMPLES:: - sage: _. = PolynomialRing(GF(19),implementation='NTL') + sage: _. = PolynomialRing(GF(19), implementation='NTL') sage: f = x^3 + 3*x - 17 sage: f.discriminant() 12 diff --git a/src/sage/rings/polynomial/polynomial_number_field.pyx b/src/sage/rings/polynomial/polynomial_number_field.pyx index 82c3d467bea..05bb580bbed 100644 --- a/src/sage/rings/polynomial/polynomial_number_field.pyx +++ b/src/sage/rings/polynomial/polynomial_number_field.pyx @@ -1,5 +1,5 @@ r""" -Univariate polynomials over number fields. +Univariate polynomials over number fields AUTHOR: @@ -10,11 +10,11 @@ EXAMPLES: Define a polynomial over an absolute number field and perform basic operations with them:: - sage: N. = NumberField(x^2-2) + sage: N. = NumberField(x^2 - 2) sage: K. = N[] sage: f = x - a sage: g = x^3 - 2*a + 1 - sage: f*(x + a) + sage: f * (x + a) x^2 - 2 sage: f + g x^3 + x - 3*a + 1 @@ -29,34 +29,34 @@ operations with them:: Polynomials are aware of embeddings of the underlying field:: - sage: x = var('x') - sage: Q7 = Qp(7) - sage: r1 = Q7(3 + 7 + 2*7^2 + 6*7^3 + 7^4 + 2*7^5 + 7^6 + 2*7^7 + 4*7^8 +\ - 6*7^9 + 6*7^10 + 2*7^11 + 7^12 + 7^13 + 2*7^15 + 7^16 + 7^17 +\ - 4*7^18 + 6*7^19) - sage: N. = NumberField(x^2-2, embedding = r1) - sage: K. = N[] - sage: f = t^3-2*t+1 - sage: f(r1) + sage: x = polygen(ZZ, 'x') + sage: Q7 = Qp(7) # optional - sage.rings.padics + sage: r1 = Q7(3 + 7 + 2*7^2 + 6*7^3 + 7^4 + 2*7^5 + 7^6 + 2*7^7 + 4*7^8 # optional - sage.rings.padics + ....: + 6*7^9 + 6*7^10 + 2*7^11 + 7^12 + 7^13 + 2*7^15 + 7^16 + 7^17 + ....: + 4*7^18 + 6*7^19) + sage: N. = NumberField(x^2 - 2, embedding=r1) # optional - sage.rings.padics + sage: K. = N[] # optional - sage.rings.padics + sage: f = t^3 - 2*t + 1 # optional - sage.rings.padics + sage: f(r1) # optional - sage.rings.padics 1 + O(7^20) We can also construct polynomials over relative number fields:: - sage: N. = QQ[I, sqrt(2)] - sage: K. = N[] - sage: f = x - s2 - sage: g = x^3 - 2*i*x^2 + s2*x - sage: f*(x + s2) + sage: N. = QQ[I, sqrt(2)] # optional - sage.symbolic + sage: K. = N[] # optional - sage.symbolic + sage: f = x - s2 # optional - sage.symbolic + sage: g = x^3 - 2*i*x^2 + s2*x # optional - sage.symbolic + sage: f * (x + s2) # optional - sage.symbolic x^2 - 2 - sage: f + g + sage: f + g # optional - sage.symbolic x^3 - 2*I*x^2 + (sqrt2 + 1)*x - sqrt2 - sage: g // f + sage: g // f # optional - sage.symbolic x^2 + (-2*I + sqrt2)*x - 2*sqrt2*I + sqrt2 + 2 - sage: g % f + sage: g % f # optional - sage.symbolic -4*I + 2*sqrt2 + 2 - sage: factor(i*x^4 - 2*i*x^2 + 9*i) + sage: factor(i*x^4 - 2*i*x^2 + 9*i) # optional - sage.symbolic (I) * (x - I + sqrt2) * (x + I - sqrt2) * (x - I - sqrt2) * (x + I + sqrt2) - sage: gcd(f, x-i) + sage: gcd(f, x - i) # optional - sage.symbolic 1 """ @@ -122,13 +122,11 @@ class Polynomial_absolute_number_field_dense(Polynomial_generic_dense_field): - ``other`` -- a polynomial with the same parent as ``self``. - OUTPUT: - - - The monic gcd of ``self`` and ``other``. + OUTPUT: The monic gcd of ``self`` and ``other``. EXAMPLES:: - sage: N. = NumberField(x^3-1/2, 'a') + sage: N. = NumberField(x^3 - 1/2, 'a') sage: R. = N['r'] sage: f = (5/4*a^2 - 2*a + 4)*r^2 + (5*a^2 - 81/5*a - 17/2)*r + 4/5*a^2 + 24*a + 6 sage: g = (5/4*a^2 - 2*a + 4)*r^2 + (-11*a^2 + 79/5*a - 7/2)*r - 4/5*a^2 - 24*a - 6 @@ -138,8 +136,8 @@ class Polynomial_absolute_number_field_dense(Polynomial_generic_dense_field): sage: f = R.random_element(2) sage: g = f + 1 sage: h = R.random_element(2).monic() - sage: f *=h - sage: g *=h + sage: f *= h + sage: g *= h sage: gcd(f, g) - h 0 sage: f.gcd(g) - h @@ -149,8 +147,8 @@ class Polynomial_absolute_number_field_dense(Polynomial_generic_dense_field): Test for degree one extensions:: - sage: x = var('x') - sage: N = NumberField(x-3, 'a') + sage: x = polygen(ZZ, 'x') + sage: N = NumberField(x - 3, 'a') sage: a = N.gen() sage: R = N['x'] sage: f = R._random_nonzero_element() @@ -167,7 +165,7 @@ class Polynomial_absolute_number_field_dense(Polynomial_generic_dense_field): Test for coercion with other rings and force weird variables to test PARI behavior:: - sage: r = var('r') + sage: r = polygen(ZZ, 'r') sage: N = NumberField(r^2 - 2, 'r') sage: a = N.gen() sage: R = N['r'] @@ -180,8 +178,9 @@ class Polynomial_absolute_number_field_dense(Polynomial_generic_dense_field): sage: h = f.gcd(g); h 1 sage: h.parent() - Univariate Polynomial Ring in r over Number Field in r with defining polynomial r^2 - 2 - sage: gcd([a*r+2, r^2-2]) + Univariate Polynomial Ring in r over + Number Field in r with defining polynomial r^2 - 2 + sage: gcd([a*r + 2, r^2 - 2]) r + r """ if self.is_zero(): @@ -236,7 +235,7 @@ class Polynomial_relative_number_field_dense(Polynomial_generic_dense_field): EXAMPLES:: - sage: f = NumberField([x^2-2, x^2-3], 'a')['x'].random_element() + sage: f = NumberField([x^2 - 2, x^2 - 3], 'a')['x'].random_element() sage: from sage.rings.polynomial.polynomial_number_field import Polynomial_relative_number_field_dense sage: isinstance(f, Polynomial_relative_number_field_dense) True @@ -268,7 +267,7 @@ class Polynomial_relative_number_field_dense(Polynomial_generic_dense_field): sage: N = QQ[sqrt(2), sqrt(3)] sage: s2, s3 = N.gens() sage: x = polygen(N) - sage: f = x^4 - 5*x^2 +6 + sage: f = x^4 - 5*x^2 + 6 sage: g = x^3 + (-2*s2 + s3)*x^2 + (-2*s3*s2 + 2)*x + 2*s3 sage: gcd(f, g) x^2 + (-sqrt2 + sqrt3)*x - sqrt3*sqrt2 @@ -277,11 +276,11 @@ class Polynomial_relative_number_field_dense(Polynomial_generic_dense_field): TESTS:: - sage: x = var('x') - sage: R = NumberField([x^2-2, x^2-3], 'a')['x'] + sage: x = polygen(ZZ, 'x') + sage: R = NumberField([x^2 - 2, x^2 - 3], 'a')['x'] sage: f = R._random_nonzero_element() sage: g1 = R.random_element() - sage: g2 = R.random_element()*g1+1 + sage: g2 = R.random_element()*g1 + 1 sage: g1 *= f sage: g2 *= f sage: f.monic() - g1.gcd(g2) @@ -289,10 +288,10 @@ class Polynomial_relative_number_field_dense(Polynomial_generic_dense_field): Test for degree one extensions:: - sage: R = NumberField([x-2,x+1,x-3],'a')['x'] + sage: R = NumberField([x - 2, x + 1, x - 3], 'a')['x'] sage: f = R.random_element(2) sage: g1 = R.random_element(2) - sage: g2 = R.random_element(2)*g1+1 + sage: g2 = R.random_element(2)*g1 + 1 sage: g1 *= f sage: g2 *= f sage: d = gcd(g1, g2) diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index 0c9be09df64..057aecded7c 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -5,14 +5,14 @@ EXAMPLES:: sage: R. = QQ[] - sage: S = R.quotient(x**3-3*x+1, 'alpha') - sage: S.gen()**2 in S + sage: S = R.quotient(x**3 - 3*x + 1, 'alpha') # optional - sage.libs.pari + sage: S.gen()**2 in S # optional - sage.libs.pari True - sage: x in S + sage: x in S # optional - sage.libs.pari True - sage: S.gen() in R + sage: S.gen() in R # optional - sage.libs.pari False - sage: 1 in S + sage: 1 in S # optional - sage.libs.pari True TESTS:: @@ -80,25 +80,26 @@ class PolynomialQuotientRingFactory(UniqueFactory): demonstrate many basic functions with it:: sage: Z = IntegerRing() - sage: R = PolynomialRing(Z,'x'); x = R.gen() - sage: S = R.quotient(x^3 + 7, 'a'); a = S.gen() - sage: S - Univariate Quotient Polynomial Ring in a over Integer Ring with modulus x^3 + 7 - sage: a^3 + sage: R = PolynomialRing(Z, 'x'); x = R.gen() + sage: S = R.quotient(x^3 + 7, 'a'); a = S.gen() # optional - sage.libs.pari + sage: S # optional - sage.libs.pari + Univariate Quotient Polynomial Ring in a + over Integer Ring with modulus x^3 + 7 + sage: a^3 # optional - sage.libs.pari -7 - sage: S.is_field() + sage: S.is_field() # optional - sage.libs.pari False - sage: a in S + sage: a in S # optional - sage.libs.pari True - sage: x in S + sage: x in S # optional - sage.libs.pari True - sage: a in R + sage: a in R # optional - sage.libs.pari False - sage: S.polynomial_ring() + sage: S.polynomial_ring() # optional - sage.libs.pari Univariate Polynomial Ring in x over Integer Ring - sage: S.modulus() + sage: S.modulus() # optional - sage.libs.pari x^3 + 7 - sage: S.degree() + sage: S.degree() # optional - sage.libs.pari 3 We create the "iterated" polynomial ring quotient @@ -109,35 +110,43 @@ class PolynomialQuotientRingFactory(UniqueFactory): :: - sage: A. = PolynomialRing(GF(2)); A + sage: A. = PolynomialRing(GF(2)); A # optional - sage.rings.finite_rings Univariate Polynomial Ring in y over Finite Field of size 2 (using GF2X) - sage: B = A.quotient(y^2 + y + 1, 'y2'); B - Univariate Quotient Polynomial Ring in y2 over Finite Field of size 2 with modulus y^2 + y + 1 - sage: C = PolynomialRing(B, 'x'); x=C.gen(); C - Univariate Polynomial Ring in x over Univariate Quotient Polynomial Ring in y2 over Finite Field of size 2 with modulus y^2 + y + 1 - sage: R = C.quotient(x^3 - 5); R - Univariate Quotient Polynomial Ring in xbar over Univariate Quotient Polynomial Ring in y2 over Finite Field of size 2 with modulus y^2 + y + 1 with modulus x^3 + 1 + sage: B = A.quotient(y^2 + y + 1, 'y2'); B # optional - sage.rings.finite_rings + Univariate Quotient Polynomial Ring in y2 over Finite Field of size 2 + with modulus y^2 + y + 1 + sage: C = PolynomialRing(B, 'x'); x = C.gen(); C # optional - sage.rings.finite_rings + Univariate Polynomial Ring in x + over Univariate Quotient Polynomial Ring in y2 + over Finite Field of size 2 with modulus y^2 + y + 1 + sage: R = C.quotient(x^3 - 5); R # optional - sage.rings.finite_rings + Univariate Quotient Polynomial Ring in xbar + over Univariate Quotient Polynomial Ring in y2 + over Finite Field of size 2 with modulus y^2 + y + 1 + with modulus x^3 + 1 Next we create a number field, but viewed as a quotient of a polynomial ring over `\QQ`:: sage: R = PolynomialRing(RationalField(), 'x'); x = R.gen() - sage: S = R.quotient(x^3 + 2*x - 5, 'a') - sage: S - Univariate Quotient Polynomial Ring in a over Rational Field with modulus x^3 + 2*x - 5 - sage: S.is_field() + sage: S = R.quotient(x^3 + 2*x - 5, 'a') # optional - sage.libs.pari + sage: S # optional - sage.libs.pari + Univariate Quotient Polynomial Ring in a over Rational Field + with modulus x^3 + 2*x - 5 + sage: S.is_field() # optional - sage.libs.pari True - sage: S.degree() + sage: S.degree() # optional - sage.libs.pari 3 There are conversion functions for easily going back and forth between quotients of polynomial rings over `\QQ` and number fields:: - sage: K = S.number_field(); K + sage: K = S.number_field(); K # optional - sage.libs.pari sage.rings.number_field Number Field in a with defining polynomial x^3 + 2*x - 5 - sage: K.polynomial_quotient_ring() - Univariate Quotient Polynomial Ring in a over Rational Field with modulus x^3 + 2*x - 5 + sage: K.polynomial_quotient_ring() # optional - sage.libs.pari sage.rings.number_field + Univariate Quotient Polynomial Ring in a + over Rational Field with modulus x^3 + 2*x - 5 The leading coefficient must be a unit (but need not be 1). @@ -154,14 +163,14 @@ class PolynomialQuotientRingFactory(UniqueFactory): sage: R. = PolynomialRing(IntegerRing()) sage: f = x^2 + 1 - sage: R.quotient(f) + sage: R.quotient(f) # optional - sage.libs.pari Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1 This shows that the issue at :trac:`5482` is solved:: sage: R. = PolynomialRing(QQ) - sage: f = x^2-1 - sage: R.quotient_by_principal_ideal(f) + sage: f = x^2 - 1 + sage: R.quotient_by_principal_ideal(f) # optional - sage.libs.pari Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 - 1 """ @@ -186,19 +195,19 @@ def create_key(self, ring, polynomial, names=None): Consequently, you get two distinct objects:: - sage: S = PolynomialQuotientRing(R, x + 1); S + sage: S = PolynomialQuotientRing(R, x + 1); S # optional - sage.libs.pari Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x + 1 - sage: T = PolynomialQuotientRing(R, 2*x + 2); T + sage: T = PolynomialQuotientRing(R, 2*x + 2); T # optional - sage.libs.pari Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus 2*x + 2 - sage: S is T + sage: S is T # optional - sage.libs.pari False - sage: S == T + sage: S == T # optional - sage.libs.pari False In most applications this will not be a concern since the calling code takes care of normalizing the generators:: - sage: R.quo(x + 1) is R.quo(2*x + 2) + sage: R.quo(x + 1) is R.quo(2*x + 2) # optional - sage.libs.pari True """ @@ -227,7 +236,8 @@ def create_object(self, version, key): EXAMPLES:: sage: R. = QQ[] - sage: PolynomialQuotientRing.create_object((8, 0, 0), (R, x^2 - 1, ('xbar'))) + sage: PolynomialQuotientRing.create_object((8, 0, 0), # optional - sage.libs.pari + ....: (R, x^2 - 1, ('xbar'))) Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 - 1 """ @@ -265,7 +275,8 @@ class PolynomialQuotientRing_generic(QuotientRing_generic): sage: R. = PolynomialRing(Integers(8)); R Univariate Polynomial Ring in x over Ring of integers modulo 8 sage: S. = R.quotient(x^2 + 1); S - Univariate Quotient Polynomial Ring in xbar over Ring of integers modulo 8 with modulus x^2 + 1 + Univariate Quotient Polynomial Ring in xbar over Ring of integers modulo 8 + with modulus x^2 + 1 We demonstrate object persistence. @@ -281,18 +292,19 @@ class PolynomialQuotientRing_generic(QuotientRing_generic): :: sage: R. = PolynomialRing(ZZ) - sage: S = R.quo(x^2-4) - sage: f = S.hom([2]) - sage: f + sage: S = R.quo(x^2 - 4) # optional - sage.libs.pari + sage: f = S.hom([2]) # optional - sage.libs.pari + sage: f # optional - sage.libs.pari Ring morphism: - From: Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 - 4 + From: Univariate Quotient Polynomial Ring in xbar over Integer Ring + with modulus x^2 - 4 To: Integer Ring Defn: xbar |--> 2 - sage: f(x) + sage: f(x) # optional - sage.libs.pari 2 - sage: f(x^2 - 4) + sage: f(x^2 - 4) # optional - sage.libs.pari 0 - sage: f(x^2) + sage: f(x^2) # optional - sage.libs.pari 4 TESTS: @@ -308,8 +320,8 @@ class of the quotient ring and its newly created elements. Thus, in order to document that this works fine, we go into some detail:: sage: P. = QQ[] - sage: Q = P.quotient(x^2+2) - sage: Q.category() + sage: Q = P.quotient(x^2 + 2) # optional - sage.libs.pari + sage: Q.category() # optional - sage.libs.pari Category of commutative no zero divisors quotients of algebras over (number fields and quotient fields and metric spaces) @@ -318,23 +330,24 @@ class of the quotient ring and its newly created elements. class of the category, and store the current class of the quotient ring:: - sage: isinstance(Q.an_element(),Q.element_class) + sage: isinstance(Q.an_element(), Q.element_class) # optional - sage.libs.pari True - sage: [s for s in dir(Q.category().element_class) if not s.startswith('_')] - ['cartesian_product', 'inverse', 'inverse_of_unit', 'is_idempotent', 'is_one', 'is_unit', 'lift', 'powers'] - sage: first_class = Q.__class__ + sage: [s for s in dir(Q.category().element_class) if not s.startswith('_')] # optional - sage.libs.pari + ['cartesian_product', 'inverse', 'inverse_of_unit', 'is_idempotent', + 'is_one', 'is_unit', 'lift', 'powers'] + sage: first_class = Q.__class__ # optional - sage.libs.pari We try to find out whether `Q` is a field. Indeed it is, and thus its category, including its class and element class, is changed accordingly:: - sage: Q in Fields() + sage: Q in Fields() # optional - sage.libs.pari True - sage: Q.category() + sage: Q.category() # optional - sage.libs.pari Category of commutative division no zero divisors quotients of algebras over (number fields and quotient fields and metric spaces) - sage: first_class == Q.__class__ + sage: first_class == Q.__class__ # optional - sage.libs.pari False - sage: [s for s in dir(Q.category().element_class) if not s.startswith('_')] + sage: [s for s in dir(Q.category().element_class) if not s.startswith('_')] # optional - sage.libs.pari ['cartesian_product', 'euclidean_degree', 'factor', @@ -358,22 +371,22 @@ class of the category, and store the current class of the quotient new methods from the category of fields, thanks to :meth:`Element.__getattr__`:: - sage: e = Q.an_element() - sage: isinstance(e, Q.element_class) + sage: e = Q.an_element() # optional - sage.libs.pari + sage: isinstance(e, Q.element_class) # optional - sage.libs.pari False - sage: e.gcd(e+1) + sage: e.gcd(e + 1) # optional - sage.libs.pari 1 The test suite passes. However, we have to skip the test for its elements, since `an_element` has been cached in the call above and its class does not match the new category's element class anymore:: - sage: TestSuite(Q).run(skip=['_test_elements']) + sage: TestSuite(Q).run(skip=['_test_elements']) # optional - sage.libs.pari Newly created elements are fine, though, and their test suite passes:: - sage: TestSuite(Q(x)).run() - sage: isinstance(Q(x), Q.element_class) + sage: TestSuite(Q(x)).run() # optional - sage.libs.pari + sage: isinstance(Q(x), Q.element_class) # optional - sage.libs.pari True """ Element = PolynomialQuotientRingElement @@ -383,18 +396,18 @@ def __init__(self, ring, polynomial, name=None, category=None): TESTS:: sage: R. = PolynomialRing(ZZ) - sage: S = R.quo(x^2-4) + sage: S = R.quo(x^2 - 4) # optional - sage.libs.pari sage: from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic - sage: S == PolynomialQuotientRing_generic(R,x^2-4,'xbar') + sage: S == PolynomialQuotientRing_generic(R, x^2 - 4, 'xbar') # optional - sage.libs.pari True Check that :trac:`26161` has been resolved:: - sage: R. = GF(2)[] - sage: S = R.quo(x) - sage: S in FiniteFields() + sage: R. = GF(2)[] # optional - sage.rings.finite_rings + sage: S = R.quo(x) # optional - sage.rings.finite_rings + sage: S in FiniteFields() # optional - sage.rings.finite_rings True - sage: type(S).mro() + sage: type(S).mro() # optional - sage.rings.finite_rings [, ... , @@ -440,18 +453,18 @@ def _element_constructor_(self, x): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S. = R.quotient(x^3-3*x+1) - sage: S(x) + sage: S. = R.quotient(x^3 - 3*x + 1) # optional - sage.libs.pari + sage: S(x) # optional - sage.libs.pari alpha - sage: S(x^3) + sage: S(x^3) # optional - sage.libs.pari 3*alpha - 1 - sage: S([1,2]) + sage: S([1,2]) # optional - sage.libs.pari 2*alpha + 1 - sage: S([1,2,3,4,5]) + sage: S([1,2,3,4,5]) # optional - sage.libs.pari 18*alpha^2 + 9*alpha - 3 - sage: S(S.gen()+1) + sage: S(S.gen()+1) # optional - sage.libs.pari alpha + 1 - sage: S(S.gen()^10+1) + sage: S(S.gen()^10+1) # optional - sage.libs.pari 90*alpha^2 - 109*alpha + 28 TESTS: @@ -460,53 +473,54 @@ def _element_constructor_(self, x): This was fixed in :trac:`8800`:: sage: P. = QQ[] - sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) - sage: Q = P.quo([(x^2+1)^2]) - sage: Q1.has_coerce_map_from(Q) + sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) # optional - sage.libs.pari + sage: Q = P.quo([(x^2+1)^2]) # optional - sage.libs.pari + sage: Q1.has_coerce_map_from(Q) # optional - sage.libs.pari False - sage: Q1(Q.gen()) + sage: Q1(Q.gen()) # optional - sage.libs.pari xbar Here we test against several issues discussed in :trac:`8992`:: sage: P. = QQ[] - sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) - sage: Q2 = P.quo([(x^2+1)^2*(x^5+3)]) - sage: p = Q1.gen() + Q2.gen() - sage: p + sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) # optional - sage.libs.pari + sage: Q2 = P.quo([(x^2+1)^2*(x^5+3)]) # optional - sage.libs.pari + sage: p = Q1.gen() + Q2.gen() # optional - sage.libs.pari + sage: p # optional - sage.libs.pari 2*xbar - sage: p.parent() - Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^4 + 2*x^2 + 1 - sage: p.parent()('xbar') + sage: p.parent() # optional - sage.libs.pari + Univariate Quotient Polynomial Ring in xbar over Rational Field + with modulus x^4 + 2*x^2 + 1 + sage: p.parent()('xbar') # optional - sage.libs.pari xbar Note that the result of string conversion has the correct parent, even when the given string suggests an element of the cover ring or the base ring:: - sage: a = Q1('x'); a + sage: a = Q1('x'); a # optional - sage.libs.pari xbar - sage: a.parent() is Q1 + sage: a.parent() is Q1 # optional - sage.libs.pari True - sage: b = Q1('1'); b + sage: b = Q1('1'); b # optional - sage.libs.pari 1 - sage: b.parent() is Q1 + sage: b.parent() is Q1 # optional - sage.libs.pari True Conversion may lift an element of one quotient ring to the base ring of another quotient ring:: - sage: R. = P[] - sage: Q3 = R.quo([(y^2+1)]) - sage: Q3(Q1.gen()) + sage: R. = P[] # optional - sage.libs.pari + sage: Q3 = R.quo([(y^2+1)]) # optional - sage.libs.pari + sage: Q3(Q1.gen()) # optional - sage.libs.pari x - sage: Q3.has_coerce_map_from(Q1) + sage: Q3.has_coerce_map_from(Q1) # optional - sage.libs.pari False String conversion takes into account both the generators of the quotient ring and its base ring:: - sage: Q3('x*ybar^2') + sage: Q3('x*ybar^2') # optional - sage.libs.pari -x """ @@ -548,25 +562,25 @@ def _coerce_map_from_(self, R): TESTS:: - sage: P5. = GF(5)[] - sage: Q = P5.quo([(x^2+1)^2]) + sage: P5. = GF(5)[] # optional - sage.rings.finite_rings + sage: Q = P5.quo([(x^2+1)^2]) # optional - sage.rings.finite_rings sage: P. = ZZ[] - sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) - sage: Q2 = P.quo([(x^2+1)^2*(x^5+3)]) - sage: Q.has_coerce_map_from(Q1) #indirect doctest + sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) # optional - sage.libs.pari + sage: Q2 = P.quo([(x^2+1)^2*(x^5+3)]) # optional - sage.libs.pari + sage: Q.has_coerce_map_from(Q1) #indirect doctest # optional - sage.libs.pari sage.rings.finite_rings True - sage: Q1.has_coerce_map_from(Q) + sage: Q1.has_coerce_map_from(Q) # optional - sage.libs.pari sage.rings.finite_rings False - sage: Q1.has_coerce_map_from(Q2) + sage: Q1.has_coerce_map_from(Q2) # optional - sage.libs.pari sage.rings.finite_rings False The following tests against a bug fixed in :trac:`8992`:: sage: P. = QQ[] - sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) + sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) # optional - sage.libs.pari sage: R. = P[] - sage: Q2 = R.quo([(y^2+1)]) - sage: Q2.has_coerce_map_from(Q1) + sage: Q2 = R.quo([(y^2 + 1)]) # optional - sage.libs.pari + sage: Q2.has_coerce_map_from(Q1) # optional - sage.libs.pari False """ @@ -587,15 +601,15 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): EXAMPLES:: sage: T. = ZZ[] - sage: K. = NumberField(t^2 + 1) - sage: R. = K[] - sage: S. = R.quotient(x^2 - i) - sage: Q8. = CyclotomicField(8) - sage: S._is_valid_homomorphism_(Q8, [z]) # no coercion from K to Q8 + sage: K. = NumberField(t^2 + 1) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: S. = R.quotient(x^2 - i) # optional - sage.rings.number_field + sage: Q8. = CyclotomicField(8) # optional - sage.rings.number_field + sage: S._is_valid_homomorphism_(Q8, [z]) # no coercion from K to Q8 # optional - sage.rings.number_field False - sage: S._is_valid_homomorphism_(Q8, [z], K.hom([z^2])) + sage: S._is_valid_homomorphism_(Q8, [z], K.hom([z^2])) # optional - sage.rings.number_field True - sage: S._is_valid_homomorphism_(Q8, [1/z], K.hom([z^-2])) + sage: S._is_valid_homomorphism_(Q8, [1/z], K.hom([z^-2])) # optional - sage.rings.number_field True """ if base_map is None and not codomain.has_coerce_map_from(self.base_ring()): @@ -645,12 +659,12 @@ def lift(self, x): EXAMPLES:: sage: P. = QQ[] - sage: Q = P.quotient(x^2+2) - sage: Q.lift(Q.0^3) + sage: Q = P.quotient(x^2 + 2) # optional - sage.libs.pari + sage: Q.lift(Q.0^3) # optional - sage.libs.pari -2*x - sage: Q(-2*x) + sage: Q(-2*x) # optional - sage.libs.pari -2*xbar - sage: Q.0^3 + sage: Q.0^3 # optional - sage.libs.pari -2*xbar """ @@ -666,14 +680,14 @@ def __eq__(self, other): sage: Ry. = PolynomialRing(QQ) sage: Rx == Ry False - sage: Qx = Rx.quotient(x^2+1) - sage: Qy = Ry.quotient(y^2+1) - sage: Qx == Qy + sage: Qx = Rx.quotient(x^2 + 1) # optional - sage.libs.pari + sage: Qy = Ry.quotient(y^2 + 1) # optional - sage.libs.pari + sage: Qx == Qy # optional - sage.libs.pari False - sage: Qx == Qx + sage: Qx == Qx # optional - sage.libs.pari True - sage: Qz = Rx.quotient(x^2+1) - sage: Qz == Qx + sage: Qz = Rx.quotient(x^2 + 1) # optional - sage.libs.pari + sage: Qz == Qx # optional - sage.libs.pari True """ if not isinstance(other, PolynomialQuotientRing_generic): @@ -691,14 +705,14 @@ def __ne__(self, other): sage: Ry. = PolynomialRing(QQ) sage: Rx != Ry True - sage: Qx = Rx.quotient(x^2+1) - sage: Qy = Ry.quotient(y^2+1) - sage: Qx != Qy + sage: Qx = Rx.quotient(x^2 + 1) # optional - sage.libs.pari + sage: Qy = Ry.quotient(y^2 + 1) # optional - sage.libs.pari + sage: Qx != Qy # optional - sage.libs.pari True - sage: Qx != Qx + sage: Qx != Qx # optional - sage.libs.pari False - sage: Qz = Rx.quotient(x^2+1) - sage: Qz != Qx + sage: Qz = Rx.quotient(x^2 + 1) # optional - sage.libs.pari + sage: Qz != Qx # optional - sage.libs.pari False """ return not (self == other) @@ -713,14 +727,14 @@ def __hash__(self): sage: Ry. = PolynomialRing(QQ) sage: hash(Rx) == hash(Ry) False - sage: Qx = Rx.quotient(x^2+1) - sage: Qy = Ry.quotient(y^2+1) - sage: hash(Qx) == hash(Qy) + sage: Qx = Rx.quotient(x^2 + 1) # optional - sage.libs.pari + sage: Qy = Ry.quotient(y^2 + 1) # optional - sage.libs.pari + sage: hash(Qx) == hash(Qy) # optional - sage.libs.pari False - sage: hash(Qx) == hash(Qx) + sage: hash(Qx) == hash(Qx) # optional - sage.libs.pari True - sage: Qz = Rx.quotient(x^2+1) - sage: hash(Qz) == hash(Qx) + sage: Qz = Rx.quotient(x^2 + 1) # optional - sage.libs.pari + sage: hash(Qz) == hash(Qx) # optional - sage.libs.pari True """ return hash((self.polynomial_ring(), self.modulus())) @@ -732,8 +746,8 @@ def _singular_init_(self, S=None): TESTS:: sage: P. = QQ[] - sage: Q = P.quo([(x^2+1)]) - sage: singular(Q) # indirect doctest + sage: Q = P.quo([(x^2 + 1)]) # optional - sage.libs.pari + sage: singular(Q) # indirect doctest # optional - sage.libs.pari polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 1 @@ -742,7 +756,7 @@ def _singular_init_(self, S=None): // block 2 : ordering C // quotient ring from ideal _[1]=xbar^2+1 - sage: singular(Q.gen()) + sage: singular(Q.gen()) # optional - sage.libs.pari xbar """ @@ -766,15 +780,15 @@ def construction(self): EXAMPLES:: - sage: P.=ZZ[] - sage: Q = P.quo(5+t^2) - sage: F, R = Q.construction() - sage: F(R) == Q + sage: P. = ZZ[] + sage: Q = P.quo(5 + t^2) # optional - sage.libs.pari + sage: F, R = Q.construction() # optional - sage.libs.pari + sage: F(R) == Q # optional - sage.libs.pari True - sage: P. = GF(3)[] - sage: Q = P.quo([2+t^2]) - sage: F, R = Q.construction() - sage: F(R) == Q + sage: P. = GF(3)[] # optional - sage.rings.finite_rings + sage: Q = P.quo([2 + t^2]) # optional - sage.rings.finite_rings + sage: F, R = Q.construction() # optional - sage.rings.finite_rings + sage: F(R) == Q # optional - sage.rings.finite_rings True AUTHOR: @@ -803,8 +817,8 @@ def base_ring(self): :: sage: R. = PolynomialRing(ZZ) - sage: S. = R.quo(z^3 + z^2 + z + 1) - sage: S.base_ring() + sage: S. = R.quo(z^3 + z^2 + z + 1) # optional - sage.libs.pari + sage: S.base_ring() # optional - sage.libs.pari Integer Ring Next we make a polynomial quotient ring over `S` and ask @@ -812,10 +826,11 @@ def base_ring(self): :: - sage: T. = PolynomialRing(S) - sage: W = T.quotient(t^99 + 99) - sage: W.base_ring() - Univariate Quotient Polynomial Ring in beta over Integer Ring with modulus z^3 + z^2 + z + 1 + sage: T. = PolynomialRing(S) # optional - sage.libs.pari + sage: W = T.quotient(t^99 + 99) # optional - sage.libs.pari + sage: W.base_ring() # optional - sage.libs.pari + Univariate Quotient Polynomial Ring in beta + over Integer Ring with modulus z^3 + z^2 + z + 1 """ return self.__ring.base_ring() @@ -830,22 +845,22 @@ def cardinality(self): sage: R. = ZZ[] sage: R.quo(1).cardinality() 1 - sage: R.quo(x^3-2).cardinality() + sage: R.quo(x^3 - 2).cardinality() # optional - sage.libs.pari +Infinity sage: R.quo(1).order() 1 - sage: R.quo(x^3-2).order() + sage: R.quo(x^3 - 2).order() # optional - sage.libs.pari +Infinity :: - sage: R. = GF(9,'a')[] - sage: R.quo(2*x^3+x+1).cardinality() + sage: R. = GF(9, 'a')[] # optional - sage.rings.finite_rings + sage: R.quo(2*x^3 + x + 1).cardinality() # optional - sage.rings.finite_rings 729 - sage: GF(9,'a').extension(2*x^3+x+1).cardinality() + sage: GF(9, 'a').extension(2*x^3 + x + 1).cardinality() # optional - sage.rings.finite_rings 729 - sage: R.quo(2).cardinality() + sage: R.quo(2).cardinality() # optional - sage.rings.finite_rings 1 TESTS:: @@ -879,21 +894,21 @@ def is_finite(self): sage: R. = ZZ[] sage: R.quo(1).is_finite() True - sage: R.quo(x^3-2).is_finite() + sage: R.quo(x^3 - 2).is_finite() # optional - sage.libs.pari False :: - sage: R. = GF(9,'a')[] - sage: R.quo(2*x^3+x+1).is_finite() + sage: R. = GF(9, 'a')[] # optional - sage.rings.finite_rings + sage: R.quo(2*x^3 + x + 1).is_finite() # optional - sage.rings.finite_rings True - sage: R.quo(2).is_finite() + sage: R.quo(2).is_finite() # optional - sage.rings.finite_rings True :: - sage: P. = GF(2)[] - sage: P.quotient(v^2-v).is_finite() + sage: P. = GF(2)[] # optional - sage.rings.finite_rings + sage: P.quotient(v^2 - v).is_finite() # optional - sage.rings.finite_rings True """ f = self.modulus() @@ -909,9 +924,9 @@ def __iter__(self): r""" EXAMPLES:: - sage: R. = GF(3)[] - sage: Q = R.quo(x^3 - x^2 - x - 1) - sage: list(Q) + sage: R. = GF(3)[] # optional - sage.rings.finite_rings + sage: Q = R.quo(x^3 - x^2 - x - 1) # optional - sage.rings.finite_rings + sage: list(Q) # optional - sage.rings.finite_rings [0, 1, 2, @@ -922,7 +937,7 @@ def __iter__(self): ... 2*xbar^2 + 2*xbar + 1, 2*xbar^2 + 2*xbar + 2] - sage: len(_) == Q.cardinality() == 27 + sage: len(_) == Q.cardinality() == 27 # optional - sage.rings.finite_rings True """ if not self.is_finite(): @@ -943,12 +958,12 @@ def characteristic(self): EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: S. = R.quo(z - 19) - sage: S.characteristic() + sage: S. = R.quo(z - 19) # optional - sage.libs.pari + sage: S.characteristic() # optional - sage.libs.pari 0 - sage: R. = PolynomialRing(GF(9,'a')) - sage: S = R.quotient(x^3 + 1) - sage: S.characteristic() + sage: R. = PolynomialRing(GF(9, 'a')) # optional - sage.rings.finite_rings + sage: S = R.quotient(x^3 + 1) # optional - sage.rings.finite_rings + sage: S.characteristic() # optional - sage.rings.finite_rings 3 """ return self.base_ring().characteristic() @@ -960,9 +975,9 @@ def degree(self): EXAMPLES:: - sage: R. = PolynomialRing(GF(3)) - sage: S = R.quotient(x^2005 + 1) - sage: S.degree() + sage: R. = PolynomialRing(GF(3)) # optional - sage.rings.finite_rings + sage: S = R.quotient(x^2005 + 1) # optional - sage.rings.finite_rings + sage: S.degree() # optional - sage.rings.finite_rings 2005 """ return self.modulus().degree() @@ -976,11 +991,11 @@ def discriminant(self, v=None): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S = R.quotient(x^3 + x^2 + x + 1) - sage: S.discriminant() + sage: S = R.quotient(x^3 + x^2 + x + 1) # optional - sage.libs.pari + sage: S.discriminant() # optional - sage.libs.pari -16 - sage: S = R.quotient((x + 1) * (x + 1)) - sage: S.discriminant() + sage: S = R.quotient((x + 1) * (x + 1)) # optional - sage.libs.pari + sage: S.discriminant() # optional - sage.libs.pari 0 The discriminant of the quotient polynomial ring need not equal the @@ -988,10 +1003,10 @@ def discriminant(self, v=None): discriminant of a number field is by definition the discriminant of the ring of integers of the number field:: - sage: S = R.quotient(x^2 - 8) - sage: S.number_field().discriminant() + sage: S = R.quotient(x^2 - 8) # optional - sage.libs.pari + sage: S.number_field().discriminant() # optional - sage.libs.pari 8 - sage: S.discriminant() + sage: S.discriminant() # optional - sage.libs.pari 32 """ return self.modulus().discriminant() @@ -1004,8 +1019,8 @@ class of the image of the generator of the polynomial ring. EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S = R.quotient(x^2 - 8, 'gamma') - sage: S.gen() + sage: S = R.quotient(x^2 - 8, 'gamma') # optional - sage.libs.pari + sage: S.gen() # optional - sage.libs.pari gamma """ if n != 0: @@ -1023,26 +1038,28 @@ def is_field(self, proof = True): EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: S = R.quo(z^2-2) - sage: S.is_field() + sage: S = R.quo(z^2 - 2) # optional - sage.libs.pari + sage: S.is_field() # optional - sage.libs.pari False sage: R. = PolynomialRing(QQ) - sage: S = R.quotient(x^2 - 2) - sage: S.is_field() + sage: S = R.quotient(x^2 - 2) # optional - sage.libs.pari + sage: S.is_field() # optional - sage.libs.pari True If proof is ``True``, requires the ``is_irreducible`` method of the modulus to be implemented:: - sage: R1. = Qp(2)[] - sage: F1 = R1.quotient_ring(x^2+x+1) - sage: R2. = F1[] - sage: F2 = R2.quotient_ring(x^2+x+1) - sage: F2.is_field() + sage: R1. = Qp(2)[] # optional - sage.rings.padics + sage: F1 = R1.quotient_ring(x^2 + x + 1) # optional - sage.rings.padics + sage: R2. = F1[] # optional - sage.rings.padics + sage: F2 = R2.quotient_ring(x^2 + x + 1) # optional - sage.rings.padics + sage: F2.is_field() # optional - sage.rings.padics Traceback (most recent call last): ... - NotImplementedError: cannot rewrite Univariate Quotient Polynomial Ring in xbar over 2-adic Field with capped relative precision 20 with modulus (1 + O(2^20))*x^2 + (1 + O(2^20))*x + 1 + O(2^20) as an isomorphic ring - sage: F2.is_field(proof = False) + NotImplementedError: cannot rewrite Univariate Quotient Polynomial Ring in + xbar over 2-adic Field with capped relative precision 20 with modulus + (1 + O(2^20))*x^2 + (1 + O(2^20))*x + 1 + O(2^20) as an isomorphic ring + sage: F2.is_field(proof = False) # optional - sage.rings.padics False """ @@ -1067,25 +1084,25 @@ def is_integral_domain(self, proof = True): EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: S = R.quotient(z^2 - z) - sage: S.is_integral_domain() + sage: S = R.quotient(z^2 - z) # optional - sage.libs.pari + sage: S.is_integral_domain() # optional - sage.libs.pari False - sage: T = R.quotient(z^2 + 1) - sage: T.is_integral_domain() + sage: T = R.quotient(z^2 + 1) # optional - sage.libs.pari + sage: T.is_integral_domain() # optional - sage.libs.pari True sage: U = R.quotient(-1) sage: U.is_integral_domain() False sage: R2. = PolynomialRing(R) - sage: S2 = R2.quotient(z^2 - y^3) - sage: S2.is_integral_domain() + sage: S2 = R2.quotient(z^2 - y^3) # optional - sage.libs.pari + sage: S2.is_integral_domain() # optional - sage.libs.pari True - sage: S3 = R2.quotient(z^2 - 2*y*z + y^2) - sage: S3.is_integral_domain() + sage: S3 = R2.quotient(z^2 - 2*y*z + y^2) # optional - sage.libs.pari + sage: S3.is_integral_domain() # optional - sage.libs.pari False sage: R. = PolynomialRing(ZZ.quotient(4)) - sage: S = R.quotient(z-1) + sage: S = R.quotient(z - 1) sage: S.is_integral_domain() False @@ -1095,17 +1112,18 @@ def is_integral_domain(self, proof = True): domain, even though the base ring is integral and the modulus is irreducible:: - sage: B = ZZ.extension(x^2 - 5, 'a') - sage: R. = PolynomialRing(B) - sage: S = R.quotient(y^2 - y - 1) - sage: S.is_integral_domain() + sage: x = polygen(ZZ, 'x') + sage: B = ZZ.extension(x^2 - 5, 'a') # optional - sage.rings.number_field + sage: R. = PolynomialRing(B) # optional - sage.rings.number_field + sage: S = R.quotient(y^2 - y - 1) # optional - sage.libs.pari sage.rings.number_field + sage: S.is_integral_domain() # optional - sage.libs.pari sage.rings.number_field Traceback (most recent call last): ... NotImplementedError - sage: S.is_integral_domain(proof = False) + sage: S.is_integral_domain(proof=False) # optional - sage.libs.pari sage.rings.number_field False - The reason that the modulus y^2 - y -1 is not prime is that it + The reason that the modulus y^2 - y - 1 is not prime is that it divides the product (2*y-(1+a))*(2*y-(1-a)) = 4*y^2 - 4*y - 4. @@ -1150,11 +1168,12 @@ def krull_dimension(self): EXAMPLES:: - sage: R = PolynomialRing(ZZ,'x').quotient(x**6-1) - sage: R.krull_dimension() + sage: x = polygen(ZZ, 'x') + sage: R = PolynomialRing(ZZ, 'x').quotient(x**6 - 1) # optional - sage.libs.pari + sage: R.krull_dimension() # optional - sage.libs.pari 1 - sage: R = PolynomialRing(ZZ,'x').quotient(1) - sage: R.krull_dimension() + sage: R = PolynomialRing(ZZ, 'x').quotient(1) # optional - sage.libs.pari + sage: R.krull_dimension() # optional - sage.libs.pari -1 """ if self.is_zero(): @@ -1167,9 +1186,9 @@ def modulus(self): EXAMPLES:: - sage: R. = PolynomialRing(GF(3)) - sage: S = R.quotient(x^2 - 2) - sage: S.modulus() + sage: R. = PolynomialRing(GF(3)) # optional - sage.rings.finite_rings + sage: S = R.quotient(x^2 - 2) # optional - sage.rings.finite_rings + sage: S.modulus() # optional - sage.rings.finite_rings x^2 + 1 """ return self.__polynomial @@ -1199,12 +1218,11 @@ def number_field(self): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S. = R.quotient(x^29 - 17*x - 1) - sage: K = S.number_field() - sage: K + sage: S. = R.quotient(x^29 - 17*x - 1) # optional - sage.libs.pari + sage: K = S.number_field(); K # optional - sage.libs.pari sage.rings.number_field Number Field in alpha with defining polynomial x^29 - 17*x - 1 - sage: alpha = K.gen() - sage: alpha^29 + sage: alpha = K.gen() # optional - sage.libs.pari sage.rings.number_field + sage: alpha^29 # optional - sage.libs.pari sage.rings.number_field 17*alpha + 1 """ if self.characteristic() != 0: @@ -1222,8 +1240,8 @@ def polynomial_ring(self): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S = R.quotient(x^2-2) - sage: S.polynomial_ring() + sage: S = R.quotient(x^2 - 2) # optional - sage.libs.pari + sage: S.polynomial_ring() # optional - sage.libs.pari Univariate Polynomial Ring in x over Rational Field """ return self.__ring @@ -1246,10 +1264,10 @@ def random_element(self, *args, **kwds): EXAMPLES:: - sage: F1. = GF(2^7) - sage: P1. = F1[] - sage: F2 = F1.extension(x^2+x+1, 'u') - sage: F2.random_element().parent() is F2 + sage: F1. = GF(2^7) # optional - sage.rings.finite_rings + sage: P1. = F1[] # optional - sage.rings.finite_rings + sage: F2 = F1.extension(x^2 + x + 1, 'u') # optional - sage.rings.finite_rings + sage: F2.random_element().parent() is F2 # optional - sage.rings.finite_rings True """ return self(self.polynomial_ring().random_element( @@ -1265,22 +1283,22 @@ def _S_decomposition(self, S): EXAMPLES:: - sage: K. = QuadraticField(-5) - sage: R. = K[] - sage: S. = R.quotient((x^2 + 23)*(x^2 + 31)) - sage: fields, isos, iso_classes = S._S_decomposition(tuple(K.primes_above(3))) + sage: K. = QuadraticField(-5) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: S. = R.quotient((x^2 + 23) * (x^2 + 31)) # optional - sage.rings.number_field + sage: fields, isos, iso_classes = S._S_decomposition(tuple(K.primes_above(3))) # optional - sage.rings.number_field Representatives of the number fields up to isomorphism that occur in the decomposition:: - sage: fields + sage: fields # optional - sage.rings.number_field [Number Field in x0 with defining polynomial x^2 + 23 over its base field, Number Field in x1 with defining polynomial x^2 + 31 over its base field] In this case, the isomorphisms of these representatives to the components are the identity maps:: - sage: isos + sage: isos # optional - sage.rings.number_field [(Ring endomorphism of Number Field in y0 with defining polynomial x^4 + 56*x^2 + 324 Defn: y0 |--> y0, 0), @@ -1291,9 +1309,9 @@ def _S_decomposition(self, S): There are four primes above 3 in the first component and two in the second component:: - sage: len(iso_classes[0][1]) + sage: len(iso_classes[0][1]) # optional - sage.rings.number_field 4 - sage: len(iso_classes[1][1]) + sage: len(iso_classes[1][1]) # optional - sage.rings.number_field 2 """ from sage.rings.number_field.number_field_base import NumberField @@ -1340,7 +1358,7 @@ def _S_decomposition(self, S): def S_class_group(self, S, proof=True): r""" - If self is an étale algebra `D` over a number field `K` (i.e. + If ``self`` is an étale algebra `D` over a number field `K` (i.e. a quotient of `K[x]` by a squarefree polynomial) and `S` is a finite set of places of `K`, return a list of generators of the `S`-class group of `D`. @@ -1372,42 +1390,43 @@ def S_class_group(self, S, proof=True): A trivial algebra over `\QQ(\sqrt{-5})` has the same class group as its base:: - sage: K. = QuadraticField(-5) - sage: R. = K[] - sage: S. = R.quotient(x) - sage: S.S_class_group([]) + sage: K. = QuadraticField(-5) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: S. = R.quotient(x) # optional - sage.rings.number_field + sage: S.S_class_group([]) # optional - sage.rings.number_field [((2, -a + 1), 2)] When we include the prime `(2, -a+1)`, the `S`-class group becomes trivial:: - sage: S.S_class_group([K.ideal(2, -a+1)]) + sage: S.S_class_group([K.ideal(2, -a+1)]) # optional - sage.rings.number_field [] Here is an example where the base and the extension both contribute to the class group:: - sage: K. = QuadraticField(-5) - sage: K.class_group() - Class group of order 2 with structure C2 of Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I - sage: R. = K[] - sage: S. = R.quotient(x^2 + 23) - sage: S.S_class_group([]) + sage: K. = QuadraticField(-5) # optional - sage.rings.number_field + sage: K.class_group() # optional - sage.rings.number_field + Class group of order 2 with structure C2 of Number Field in a + with defining polynomial x^2 + 5 with a = 2.236067977499790?*I + sage: R. = K[] # optional - sage.rings.number_field + sage: S. = R.quotient(x^2 + 23) # optional - sage.rings.number_field + sage: S.S_class_group([]) # optional - sage.rings.number_field [((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)] - sage: S.S_class_group([K.ideal(3, a-1)]) + sage: S.S_class_group([K.ideal(3, a-1)]) # optional - sage.rings.number_field [] - sage: S.S_class_group([K.ideal(2, a+1)]) + sage: S.S_class_group([K.ideal(2, a+1)]) # optional - sage.rings.number_field [] - sage: S.S_class_group([K.ideal(a)]) + sage: S.S_class_group([K.ideal(a)]) # optional - sage.rings.number_field [((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)] Now we take an example over a nontrivial base with two factors, each contributing to the class group:: - sage: K. = QuadraticField(-5) - sage: R. = K[] - sage: S. = R.quotient((x^2 + 23)*(x^2 + 31)) - sage: S.S_class_group([]) # representation varies, not tested + sage: K. = QuadraticField(-5) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: S. = R.quotient((x^2 + 23) * (x^2 + 31)) # optional - sage.rings.number_field + sage: S.S_class_group([]) # representation varies, not tested # optional - sage.rings.number_field [((1/4*xbar^2 + 31/4, (-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8, 1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16, @@ -1428,26 +1447,33 @@ def S_class_group(self, S, proof=True): `x^2 + 31` from 12 to 2, i.e. we lose a generator of order 6 (this was fixed in :trac:`14489`):: - sage: S.S_class_group([K.ideal(a)]) # representation varies, not tested - [((1/4*xbar^2 + 31/4, (-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8, 1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16, -1/16*a*xbar^3 + (1/16*a + 1/8)*xbar^2 - 31/16*a*xbar + 31/16*a + 31/8), 6), ((-1/4*xbar^2 - 23/4, (1/8*a - 1/8)*xbar^2 + 23/8*a - 23/8, -1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16, 1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8), 2)] + sage: S.S_class_group([K.ideal(a)]) # representation varies, not tested # optional - sage.rings.number_field + [((1/4*xbar^2 + 31/4, (-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8, + 1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16, + -1/16*a*xbar^3 + (1/16*a + 1/8)*xbar^2 - 31/16*a*xbar + 31/16*a + 31/8), + 6), + ((-1/4*xbar^2 - 23/4, (1/8*a - 1/8)*xbar^2 + 23/8*a - 23/8, + -1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16, + 1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8), + 2)] Note that all the returned values live where we expect them to:: - sage: CG = S.S_class_group([]) - sage: type(CG[0][0][1]) + sage: CG = S.S_class_group([]) # optional - sage.rings.number_field + sage: type(CG[0][0][1]) # optional - sage.rings.number_field - sage: type(CG[0][1]) + sage: type(CG[0][1]) # optional - sage.rings.number_field TESTS: We verify the above test, where the representation depends on the PARI version:: - sage: K. = QuadraticField(-5) - sage: R. = K[] - sage: S. = R.quotient((x^2 + 23)*(x^2 + 31)) - sage: C = S.S_class_group([]) - sage: C[:2] + sage: K. = QuadraticField(-5) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: S. = R.quotient((x^2 + 23) * (x^2 + 31)) # optional - sage.rings.number_field + sage: C = S.S_class_group([]) # optional - sage.rings.number_field + sage: C[:2] # optional - sage.rings.number_field [((1/4*xbar^2 + 31/4, (-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8, 1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16, @@ -1458,21 +1484,21 @@ def S_class_group(self, S, proof=True): -1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16, 1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8), 6)] - sage: C[2][1] + sage: C[2][1] # optional - sage.rings.number_field 2 - sage: gens = C[2][0] - sage: expected_gens = ( + sage: gens = C[2][0] # optional - sage.rings.number_field + sage: expected_gens = ( # optional - sage.rings.number_field ....: -5/4*xbar^2 - 115/4, ....: 1/4*a*xbar^2 + 23/4*a, ....: -1/16*xbar^3 - 7/16*xbar^2 - 23/16*xbar - 161/16, ....: 1/16*a*xbar^3 - 1/16*a*xbar^2 + 23/16*a*xbar - 23/16*a) - sage: gens[0] == expected_gens[0] + sage: gens[0] == expected_gens[0] # optional - sage.rings.number_field True - sage: gens[1] in (expected_gens[1], expected_gens[1]/2 + expected_gens[0]/2) + sage: gens[1] in (expected_gens[1], expected_gens[1]/2 + expected_gens[0]/2) # optional - sage.rings.number_field True - sage: gens[2] in (expected_gens[2], expected_gens[2] + expected_gens[0]/2) + sage: gens[2] in (expected_gens[2], expected_gens[2] + expected_gens[0]/2) # optional - sage.rings.number_field True - sage: gens[3] in (expected_gens[3], expected_gens[3] + expected_gens[0]/2) + sage: gens[3] in (expected_gens[3], expected_gens[3] + expected_gens[0]/2) # optional - sage.rings.number_field True """ fields, isos, iso_classes = self._S_decomposition(tuple(S)) @@ -1503,7 +1529,7 @@ def S_class_group(self, S, proof=True): def class_group(self, proof=True): r""" - If self is a quotient ring of a polynomial ring over a number + If ``self`` is a quotient ring of a polynomial ring over a number field `K`, by a polynomial of nonzero discriminant, return a list of generators of the class group. @@ -1527,54 +1553,62 @@ def class_group(self, proof=True): EXAMPLES:: - sage: K. = QuadraticField(-3) - sage: K.class_group() - Class group of order 1 of Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I - sage: K. = QQ['x'].quotient(x^2 + 3) - sage: K.class_group() + sage: K. = QuadraticField(-3) # optional - sage.rings.number_field + sage: K.class_group() # optional - sage.rings.number_field + Class group of order 1 of Number Field in a + with defining polynomial x^2 + 3 with a = 1.732050807568878?*I + sage: K. = QQ['x'].quotient(x^2 + 3) # optional - sage.libs.pari sage.rings.number_field + sage: K.class_group() # optional - sage.libs.pari sage.rings.number_field [] A trivial algebra over `\QQ(\sqrt{-5})` has the same class group as its base:: - sage: K. = QuadraticField(-5) - sage: R. = K[] - sage: S. = R.quotient(x) - sage: S.class_group() + sage: K. = QuadraticField(-5) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: S. = R.quotient(x) # optional - sage.rings.number_field + sage: S.class_group() # optional - sage.rings.number_field [((2, -a + 1), 2)] The same algebra constructed in a different way:: - sage: K. = QQ['x'].quotient(x^2 + 5) - sage: K.class_group(()) + sage: x = polygen(ZZ, 'x') + sage: K. = QQ['x'].quotient(x^2 + 5) # optional - sage.libs.pari + sage: K.class_group(()) # optional - sage.libs.pari [((2, a + 1), 2)] Here is an example where the base and the extension both contribute to the class group:: - sage: K. = QuadraticField(-5) - sage: K.class_group() - Class group of order 2 with structure C2 of Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I - sage: R. = K[] - sage: S. = R.quotient(x^2 + 23) - sage: S.class_group() + sage: K. = QuadraticField(-5) # optional - sage.rings.number_field + sage: K.class_group() # optional - sage.rings.number_field + Class group of order 2 with structure C2 of Number Field in a + with defining polynomial x^2 + 5 with a = 2.236067977499790?*I + sage: R. = K[] # optional - sage.rings.number_field + sage: S. = R.quotient(x^2 + 23) # optional - sage.rings.number_field + sage: S.class_group() # optional - sage.rings.number_field [((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)] Here is an example of a product of number fields, both of which contribute to the class group:: - sage: R. = QQ[] - sage: S. = R.quotient((x^2 + 23)*(x^2 + 47)) - sage: S.class_group() - [((1/12*xbar^2 + 47/12, 1/48*xbar^3 - 1/48*xbar^2 + 47/48*xbar - 47/48), 3), ((-1/12*xbar^2 - 23/12, -1/48*xbar^3 - 1/48*xbar^2 - 23/48*xbar - 23/48), 5)] + sage: R. = QQ[] # optional - sage.rings.number_field + sage: S. = R.quotient((x^2 + 23) * (x^2 + 47)) # optional - sage.rings.number_field + sage: S.class_group() # optional - sage.rings.number_field + [((1/12*xbar^2 + 47/12, + 1/48*xbar^3 - 1/48*xbar^2 + 47/48*xbar - 47/48), + 3), + ((-1/12*xbar^2 - 23/12, + -1/48*xbar^3 - 1/48*xbar^2 - 23/48*xbar - 23/48), + 5)] Now we take an example over a nontrivial base with two factors, each contributing to the class group:: - sage: K. = QuadraticField(-5) - sage: R. = K[] - sage: S. = R.quotient((x^2 + 23)*(x^2 + 31)) - sage: S.class_group() # representation varies, not tested + sage: K. = QuadraticField(-5) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: S. = R.quotient((x^2 + 23) * (x^2 + 31)) # optional - sage.rings.number_field + sage: S.class_group() # representation varies, not tested # optional - sage.rings.number_field [((1/4*xbar^2 + 31/4, (-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8, 1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16, @@ -1593,10 +1627,10 @@ def class_group(self, proof=True): Note that all the returned values live where we expect them to:: - sage: CG = S.class_group() - sage: type(CG[0][0][1]) + sage: CG = S.class_group() # optional - sage.rings.number_field + sage: type(CG[0][0][1]) # optional - sage.rings.number_field - sage: type(CG[0][1]) + sage: type(CG[0][1]) # optional - sage.rings.number_field """ @@ -1622,35 +1656,40 @@ def S_units(self, S, proof=True): EXAMPLES:: - sage: K. = QuadraticField(-3) - sage: K.unit_group() - Unit group with structure C6 of Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I - sage: K. = QQ['x'].quotient(x^2 + 3) - sage: u,o = K.S_units([])[0]; o + sage: K. = QuadraticField(-3) # optional - sage.rings.number_field + sage: K.unit_group() # optional - sage.rings.number_field + Unit group with structure C6 of Number Field in a + with defining polynomial x^2 + 3 with a = 1.732050807568878?*I + sage: x = polygen(ZZ, 'x') + sage: K. = QQ['x'].quotient(x^2 + 3) # optional - sage.libs.pari + sage: u, o = K.S_units([])[0]; o # optional - sage.libs.pari 6 - sage: 2*u - 1 in {a, -a} + sage: 2*u - 1 in {a, -a} # optional - sage.libs.pari True - sage: u^6 + sage: u^6 # optional - sage.libs.pari 1 - sage: u^3 + sage: u^3 # optional - sage.libs.pari -1 - sage: 2*u^2 + 1 in {a, -a} + sage: 2*u^2 + 1 in {a, -a} # optional - sage.libs.pari True :: - sage: K. = QuadraticField(-3) - sage: y = polygen(K) - sage: L. = K['y'].quotient(y^3 + 5); L - Univariate Quotient Polynomial Ring in b over Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I with modulus y^3 + 5 - sage: [u for u, o in L.S_units([]) if o is Infinity] + sage: K. = QuadraticField(-3) # optional - sage.rings.number_field + sage: y = polygen(K) # optional - sage.rings.number_field + sage: L. = K['y'].quotient(y^3 + 5); L # optional - sage.rings.number_field + Univariate Quotient Polynomial Ring in b over Number Field in a + with defining polynomial x^2 + 3 with a = 1.732050807568878?*I + with modulus y^3 + 5 + sage: [u for u, o in L.S_units([]) if o is Infinity] # optional - sage.rings.number_field [(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2, 2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2] - sage: [u for u, o in L.S_units([K.ideal(1/2*a - 3/2)]) if o is Infinity] + sage: [u for u, o in L.S_units([K.ideal(1/2*a - 3/2)]) # optional - sage.rings.number_field + ....: if o is Infinity] [(-1/6*a - 1/2)*b^2 + (1/3*a - 1)*b + 4/3*a, (-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2, 2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2] - sage: [u for u, o in L.S_units([K.ideal(2)]) if o is Infinity] + sage: [u for u, o in L.S_units([K.ideal(2)]) if o is Infinity] # optional - sage.rings.number_field [(1/2*a - 1/2)*b^2 + (a + 1)*b + 3, (1/6*a + 1/2)*b^2 + (-1/3*a + 1)*b - 5/6*a + 1/2, (1/6*a + 1/2)*b^2 + (-1/3*a + 1)*b - 5/6*a - 1/2, @@ -1659,12 +1698,12 @@ def S_units(self, S, proof=True): Note that all the returned values live where we expect them to:: - sage: U = L.S_units([]) - sage: type(U[0][0]) + sage: U = L.S_units([]) # optional - sage.rings.number_field + sage: type(U[0][0]) # optional - sage.rings.number_field - sage: type(U[0][1]) + sage: type(U[0][1]) # optional - sage.rings.number_field - sage: type(U[1][1]) + sage: type(U[1][1]) # optional - sage.rings.number_field """ @@ -1708,49 +1747,56 @@ def units(self, proof=True): EXAMPLES:: - sage: K. = QuadraticField(-3) - sage: K.unit_group() - Unit group with structure C6 of Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I - sage: K. = QQ['x'].quotient(x^2 + 3) - sage: u = K.units()[0][0] - sage: 2*u - 1 in {a, -a} + sage: K. = QuadraticField(-3) # optional - sage.rings.number_field + sage: K.unit_group() # optional - sage.rings.number_field + Unit group with structure C6 of + Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I + sage: x = polygen(ZZ, 'x') + sage: K. = QQ['x'].quotient(x^2 + 3) # optional - sage.libs.pari + sage: u = K.units()[0][0] # optional - sage.libs.pari + sage: 2*u - 1 in {a, -a} # optional - sage.libs.pari True - sage: u^6 + sage: u^6 # optional - sage.libs.pari 1 - sage: u^3 + sage: u^3 # optional - sage.libs.pari -1 - sage: 2*u^2 + 1 in {a, -a} + sage: 2*u^2 + 1 in {a, -a} # optional - sage.libs.pari True - sage: K. = QQ['x'].quotient(x^2 + 5) - sage: K.units(()) + sage: x = polygen(ZZ, 'x') + sage: K. = QQ['x'].quotient(x^2 + 5) # optional - sage.libs.pari + sage: K.units(()) # optional - sage.libs.pari [(-1, 2)] :: - sage: K. = QuadraticField(-3) - sage: y = polygen(K) - sage: L. = K['y'].quotient(y^3 + 5); L - Univariate Quotient Polynomial Ring in b over Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I with modulus y^3 + 5 - sage: [u for u, o in L.units() if o is Infinity] + sage: K. = QuadraticField(-3) # optional - sage.rings.number_field + sage: y = polygen(K) # optional - sage.rings.number_field + sage: L. = K['y'].quotient(y^3 + 5); L # optional - sage.rings.number_field + Univariate Quotient Polynomial Ring in b over Number Field in a + with defining polynomial x^2 + 3 with a = 1.732050807568878?*I + with modulus y^3 + 5 + sage: [u for u, o in L.units() if o is Infinity] # optional - sage.rings.number_field [(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2, 2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2] - sage: L. = K.extension(y^3 + 5) - sage: L.unit_group() - Unit group with structure C6 x Z x Z of Number Field in b with defining polynomial x^3 + 5 over its base field - sage: L.unit_group().gens() # abstract generators + sage: L. = K.extension(y^3 + 5) # optional - sage.rings.number_field + sage: L.unit_group() # optional - sage.rings.number_field + Unit group with structure C6 x Z x Z of + Number Field in b with defining polynomial x^3 + 5 over its base field + sage: L.unit_group().gens() # abstract generators # optional - sage.rings.number_field (u0, u1, u2) - sage: L.unit_group().gens_values()[1:] - [(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2, 2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2] + sage: L.unit_group().gens_values()[1:] # optional - sage.rings.number_field + [(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2, + 2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2] Note that all the returned values live where we expect them to:: - sage: L. = K['y'].quotient(y^3 + 5) - sage: U = L.units() - sage: type(U[0][0]) + sage: L. = K['y'].quotient(y^3 + 5) # optional - sage.libs.pari + sage: U = L.units() # optional - sage.libs.pari + sage: type(U[0][0]) # optional - sage.libs.pari - sage: type(U[0][1]) + sage: type(U[0][1]) # optional - sage.libs.pari - sage: type(U[1][1]) + sage: type(U[1][1]) # optional - sage.libs.pari """ @@ -1779,22 +1825,24 @@ def selmer_generators(self, S, m, proof=True): EXAMPLES:: - sage: K. = QuadraticField(-5) - sage: R. = K[] - sage: D. = R.quotient(x) - sage: D.selmer_generators((), 2) + sage: K. = QuadraticField(-5) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: D. = R.quotient(x) # optional - sage.rings.number_field + sage: D.selmer_generators((), 2) # optional - sage.rings.number_field [-1, 2] - sage: D.selmer_generators([K.ideal(2, -a+1)], 2) + sage: D.selmer_generators([K.ideal(2, -a + 1)], 2) # optional - sage.rings.number_field [2, -1] - sage: D.selmer_generators([K.ideal(2, -a+1), K.ideal(3, a+1)], 2) + sage: D.selmer_generators([K.ideal(2, -a + 1), K.ideal(3, a + 1)], 2) # optional - sage.rings.number_field [2, a + 1, -1] - sage: D.selmer_generators((K.ideal(2, -a+1),K.ideal(3, a+1)), 4) + sage: D.selmer_generators((K.ideal(2, -a + 1), K.ideal(3, a + 1)), 4) # optional - sage.rings.number_field [2, a + 1, -1] - sage: D.selmer_generators([K.ideal(2, -a+1)], 3) + sage: D.selmer_generators([K.ideal(2, -a + 1)], 3) # optional - sage.rings.number_field [2] - sage: D.selmer_generators([K.ideal(2, -a+1), K.ideal(3, a+1)], 3) + sage: D.selmer_generators([K.ideal(2, -a + 1), K.ideal(3, a + 1)], 3) # optional - sage.rings.number_field [2, a + 1] - sage: D.selmer_generators([K.ideal(2, -a+1), K.ideal(3, a+1), K.ideal(a)], 3) + sage: D.selmer_generators([K.ideal(2, -a + 1), # optional - sage.rings.number_field + ....: K.ideal(3, a + 1), + ....: K.ideal(a)], 3) [2, a + 1, -a] """ @@ -1829,13 +1877,13 @@ def _factor_multivariate_polynomial(self, f, proof=True): TESTS:: - sage: k. = GF(4) - sage: R. = k[] - sage: l. = k.extension(b^2 + b + a) - sage: K. = FunctionField(l) - sage: R. = K[] - sage: F = t*x - sage: F.factor(proof=False) + sage: k. = GF(4) # optional - sage.rings.finite_rings + sage: R. = k[] # optional - sage.rings.finite_rings + sage: l. = k.extension(b^2 + b + a) # optional - sage.rings.finite_rings + sage: K. = FunctionField(l) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: F = t * x # optional - sage.rings.finite_rings + sage: F.factor(proof=False) # optional - sage.rings.finite_rings (x) * t """ @@ -1856,17 +1904,17 @@ def _factor_univariate_polynomial(self, f): TESTS:: - sage: K = GF(2) - sage: R. = K[] - sage: L. = K.extension(x^2 + x + 1) - sage: R. = L[] - sage: M. = L.extension(y^2 + y + x) - sage: R. = M[] - sage: R(y).factor() # indirect doctest + sage: K = GF(2) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(x^2 + x + 1) # optional - sage.rings.finite_rings + sage: R. = L[] # optional - sage.rings.finite_rings + sage: M. = L.extension(y^2 + y + x) # optional - sage.rings.finite_rings + sage: R. = M[] # optional - sage.rings.finite_rings + sage: R(y).factor() # indirect doctest # optional - sage.rings.finite_rings y - sage: (T^2 + T + x).factor() # indirect doctest + sage: (T^2 + T + x).factor() # indirect doctest # optional - sage.rings.finite_rings (T + y) * (T + y + 1) - sage: (y*T^2 + y*T + y*x).factor() # indirect doctest + sage: (y*T^2 + y*T + y*x).factor() # indirect doctest # optional - sage.rings.finite_rings (y) * (T + y) * (T + y + 1) """ @@ -1907,32 +1955,36 @@ def _isomorphic_ring(self): EXAMPLES:: - sage: K. = GF(4) - sage: R. = K[] - sage: L. = K.extension(b^2+b+a); L - Univariate Quotient Polynomial Ring in b over Finite Field in a of size 2^2 with modulus b^2 + b + a - sage: from_M, to_M, M = L._isomorphic_ring(); M + sage: K. = GF(4) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(b^2 + b + a); L # optional - sage.rings.finite_rings + Univariate Quotient Polynomial Ring in b + over Finite Field in a of size 2^2 with modulus b^2 + b + a + sage: from_M, to_M, M = L._isomorphic_ring(); M # optional - sage.rings.finite_rings Finite Field in z4 of size 2^4 - sage: R. = L[] - sage: M. = L.extension(c^2+b*c+b); M - Univariate Quotient Polynomial Ring in c over Univariate Quotient Polynomial Ring in b over Finite Field in a of size 2^2 with modulus b^2 + b + a with modulus c^2 + b*c + b - sage: from_N, to_N, N = M._isomorphic_ring(); N + sage: R. = L[] # optional - sage.rings.finite_rings + sage: M. = L.extension(c^2 + b*c + b); M # optional - sage.rings.finite_rings + Univariate Quotient Polynomial Ring in c + over Univariate Quotient Polynomial Ring in b + over Finite Field in a of size 2^2 with modulus b^2 + b + a + with modulus c^2 + b*c + b + sage: from_N, to_N, N = M._isomorphic_ring(); N # optional - sage.rings.finite_rings Finite Field in z8 of size 2^8 sage: R. = QQ[] - sage: K = R.quo(x^2 + 1) - sage: from_L, to_L, L = K._isomorphic_ring() - sage: L + sage: K = R.quo(x^2 + 1) # optional - sage.libs.pari + sage: from_L, to_L, L = K._isomorphic_ring() # optional - sage.libs.pari sage.rings.number_field + sage: L # optional - sage.libs.pari sage.rings.number_field Number Field in xbar with defining polynomial x^2 + 1 TESTS: Verify that this works for trivial extensions:: - sage: K. = GF(4) - sage: R. = K[] - sage: from_L, to_L, L = R.quo(b)._isomorphic_ring(); L + sage: K. = GF(4) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: from_L, to_L, L = R.quo(b)._isomorphic_ring(); L # optional - sage.rings.finite_rings Finite Field in a of size 2^2 """ @@ -2049,13 +2101,13 @@ def _test_isomorphic_ring(self, **options): TESTS:: - sage: K. = GF(4) - sage: R. = K[] - sage: L. = K.extension(b^2+b+a) - sage: L._test_isomorphic_ring() - sage: R. = L[] - sage: M. = L.extension(c^2+b*c+b) - sage: M._test_isomorphic_ring() + sage: K. = GF(4) # optional - sage.rings.finite_rings + sage: R. = K[] # optional - sage.rings.finite_rings + sage: L. = K.extension(b^2 + b + a) # optional - sage.rings.finite_rings + sage: L._test_isomorphic_ring() # optional - sage.rings.finite_rings + sage: R. = L[] # optional - sage.rings.finite_rings + sage: M. = L.extension(c^2 + b*c + b) # optional - sage.rings.finite_rings + sage: M._test_isomorphic_ring() # optional - sage.rings.finite_rings """ tester = self._tester(**options) @@ -2093,25 +2145,27 @@ class PolynomialQuotientRing_coercion(DefaultConvertMap_unique): sage: R. = ZZ[] sage: S. = QQ[] - sage: f = S.quo(x^2 + 1).coerce_map_from(R.quo(x^2 + 1)); f + sage: f = S.quo(x^2 + 1).coerce_map_from(R.quo(x^2 + 1)); f # optional - sage.libs.pari Coercion map: - From: Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1 - To: Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1 + From: Univariate Quotient Polynomial Ring in xbar over Integer Ring + with modulus x^2 + 1 + To: Univariate Quotient Polynomial Ring in xbar over Rational Field + with modulus x^2 + 1 TESTS:: sage: from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_coercion - sage: isinstance(f, PolynomialQuotientRing_coercion) + sage: isinstance(f, PolynomialQuotientRing_coercion) # optional - sage.libs.pari True - sage: TestSuite(f).run(skip=['_test_pickling']) + sage: TestSuite(f).run(skip=['_test_pickling']) # optional - sage.libs.pari Pickling works:: - sage: g = loads(dumps(f)); g + sage: g = loads(dumps(f)); g # optional - sage.libs.pari Coercion map: From: Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1 To: Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1 - sage: f == g + sage: f == g # optional - sage.libs.pari True """ @@ -2127,8 +2181,8 @@ def is_injective(self): sage: R. = ZZ[] sage: S. = QQ[] - sage: f = S.quo(x^2 + 1).coerce_map_from(R.quo(x^2 + 1)) - sage: f.is_injective() + sage: f = S.quo(x^2 + 1).coerce_map_from(R.quo(x^2 + 1)) # optional - sage.libs.pari + sage: f.is_injective() # optional - sage.libs.pari True """ @@ -2151,18 +2205,18 @@ def is_surjective(self): domain:: sage: R. = ZZ[] - sage: f = R.quo(x).coerce_map_from(R.quo(x^2)) - sage: f.is_surjective() + sage: f = R.quo(x).coerce_map_from(R.quo(x^2)) # optional - sage.libs.pari + sage: f.is_surjective() # optional - sage.libs.pari True If the modulus of the domain and the codomain is the same, then the map is surjective iff the underlying map on the constants is:: - sage: A. = ZqCA(9) - sage: R. = A[] - sage: S. = A.fraction_field()[] - sage: f = S.quo(x^2 + 2).coerce_map_from(R.quo(x^2 + 2)) - sage: f.is_surjective() + sage: A. = ZqCA(9) # optional - sage.rings.padics + sage: R. = A[] # optional - sage.rings.padics + sage: S. = A.fraction_field()[] # optional - sage.rings.padics + sage: f = S.quo(x^2 + 2).coerce_map_from(R.quo(x^2 + 2)) # optional - sage.rings.padics + sage: f.is_surjective() # optional - sage.rings.padics False """ @@ -2181,11 +2235,11 @@ def _richcmp_(self, other, op): sage: R. = ZZ[] sage: S. = ZZ[] - sage: f = S.quo(x).coerce_map_from(R.quo(x^2)) - sage: g = S.quo(x).coerce_map_from(R.quo(x^3)) - sage: f == g + sage: f = S.quo(x).coerce_map_from(R.quo(x^2)) # optional - sage.libs.pari + sage: g = S.quo(x).coerce_map_from(R.quo(x^3)) # optional - sage.libs.pari + sage: f == g # optional - sage.libs.pari False - sage: f == f + sage: f == f # optional - sage.libs.pari True """ @@ -2193,17 +2247,19 @@ def _richcmp_(self, other, op): return NotImplemented return richcmp(self.parent(), other.parent(), op) + class PolynomialQuotientRing_domain(PolynomialQuotientRing_generic, IntegralDomain): """ EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: S. = R.quotient(x^2 + 1) - sage: S - Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1 - sage: loads(S.dumps()) == S + sage: S. = R.quotient(x^2 + 1) # optional - sage.libs.pari + sage: S # optional - sage.libs.pari + Univariate Quotient Polynomial Ring in xbar + over Integer Ring with modulus x^2 + 1 + sage: loads(S.dumps()) == S # optional - sage.libs.pari True - sage: loads(xbar.dumps()) == xbar + sage: loads(xbar.dumps()) == xbar # optional - sage.libs.pari True """ def __init__(self, ring, polynomial, name=None, category=None): @@ -2213,21 +2269,21 @@ def __init__(self, ring, polynomial, name=None, category=None): TESTS:: sage: R. = PolynomialRing(ZZ) - sage: S. = R.quotient(x^2 + 1) - sage: TestSuite(S).run() + sage: S. = R.quotient(x^2 + 1) # optional - sage.libs.pari + sage: TestSuite(S).run() # optional - sage.libs.pari Check that :trac:`17450` is fixed:: - sage: S in IntegralDomains() + sage: S in IntegralDomains() # optional - sage.libs.pari True Check that :trac:`29017` is fixed:: sage: R. = ZZ[] - sage: Q = R.quo(x-1) - sage: H = R.Hom(Q) - sage: h = R.hom(Q) - sage: h.parent() is H + sage: Q = R.quo(x - 1) # optional - sage.libs.pari + sage: H = R.Hom(Q) # optional - sage.libs.pari + sage: h = R.hom(Q) # optional - sage.libs.pari + sage: h.parent() is H # optional - sage.libs.pari True """ category = CommutativeAlgebras(ring.base_ring().category()).Quotients().NoZeroDivisors().or_subcategory(category) @@ -2235,38 +2291,38 @@ def __init__(self, ring, polynomial, name=None, category=None): def field_extension(self, names): r""" - Takes a polynomial quotient ring, and returns a tuple with three - elements: the NumberField defined by the same polynomial quotient - ring, a homomorphism from its parent to the NumberField sending the + Take a polynomial quotient ring, and return a tuple with three + elements: the :class:`NumberField` defined by the same polynomial quotient + ring, a homomorphism from its parent to the :class:`NumberField` sending the generators to one another, and the inverse isomorphism. OUTPUT: - field - - homomorphism from self to field + - homomorphism from ``self`` to field - - homomorphism from field to self + - homomorphism from field to ``self`` EXAMPLES:: sage: R. = PolynomialRing(Rationals()) - sage: S. = R.quotient(x^3-2) - sage: F., f, g = S.field_extension() - sage: F + sage: S. = R.quotient(x^3 - 2) # optional - sage.libs.pari + sage: F., f, g = S.field_extension() # optional - sage.libs.pari sage.rings.number_field + sage: F # optional - sage.libs.pari sage.rings.number_field Number Field in b with defining polynomial x^3 - 2 - sage: a = F.gen() - sage: f(alpha) + sage: a = F.gen() # optional - sage.libs.pari sage.rings.number_field + sage: f(alpha) # optional - sage.libs.pari sage.rings.number_field b - sage: g(a) + sage: g(a) # optional - sage.libs.pari sage.rings.number_field alpha Note that the parent ring must be an integral domain:: - sage: R. = GF(25,'f25')['x'] - sage: S. = R.quo(x^3 - 2) - sage: F, g, h = S.field_extension('b') + sage: R. = GF(25, 'f25')['x'] # optional - sage.rings.finite_rings + sage: S. = R.quo(x^3 - 2) # optional - sage.rings.finite_rings + sage: F, g, h = S.field_extension('b') # optional - sage.rings.finite_rings Traceback (most recent call last): ... AttributeError: 'PolynomialQuotientRing_generic_with_category' object has no attribute 'field_extension' @@ -2274,21 +2330,21 @@ def field_extension(self, names): Over a finite field, the corresponding field extension is not a number field:: - sage: R. = GF(25, 'a')['x'] - sage: S. = R.quo(x^3 + 2*x + 1) - sage: F, g, h = S.field_extension('b') - sage: h(F.0^2 + 3) + sage: R. = GF(25, 'a')['x'] # optional - sage.rings.finite_rings + sage: S. = R.quo(x^3 + 2*x + 1) # optional - sage.rings.finite_rings + sage: F, g, h = S.field_extension('b') # optional - sage.rings.finite_rings + sage: h(F.0^2 + 3) # optional - sage.rings.finite_rings a^2 + 3 - sage: g(x^2 + 2) + sage: g(x^2 + 2) # optional - sage.rings.finite_rings b^2 + 2 We do an example involving a relative number field:: sage: R. = QQ['x'] - sage: K. = NumberField(x^3 - 2) - sage: S. = K['X'] - sage: Q. = S.quo(X^3 + 2*X + 1) - sage: Q.field_extension('b') + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: S. = K['X'] # optional - sage.rings.number_field + sage: Q. = S.quo(X^3 + 2*X + 1) # optional - sage.rings.number_field + sage: Q.field_extension('b') # optional - sage.rings.number_field (Number Field in b with defining polynomial X^3 + 2*X + 1 over its base field, ... Defn: b |--> b, Relative number field morphism: From: Number Field in b with defining polynomial X^3 + 2*X + 1 over its base field @@ -2301,19 +2357,19 @@ def field_extension(self, names): :: sage: R. = QQ['x'] - sage: K. = NumberField(x^3 - 2) - sage: S. = K['X'] - sage: f = (X+a)^3 + 2*(X+a) + 1 - sage: f + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: S. = K['X'] # optional - sage.rings.number_field + sage: f = (X+a)^3 + 2*(X+a) + 1 # optional - sage.rings.number_field + sage: f # optional - sage.rings.number_field X^3 + 3*a*X^2 + (3*a^2 + 2)*X + 2*a + 3 - sage: Q. = S.quo(f) - sage: F., g, h = Q.field_extension() - sage: c = g(z) - sage: f(c) + sage: Q. = S.quo(f) # optional - sage.rings.number_field + sage: F., g, h = Q.field_extension() # optional - sage.rings.number_field + sage: c = g(z) # optional - sage.rings.number_field + sage: f(c) # optional - sage.rings.number_field 0 - sage: h(g(z)) + sage: h(g(z)) # optional - sage.rings.number_field z - sage: g(h(w)) + sage: g(h(w)) # optional - sage.rings.number_field w AUTHORS: @@ -2331,12 +2387,13 @@ class PolynomialQuotientRing_field(PolynomialQuotientRing_domain, Field): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S. = R.quotient(x^2 + 1) - sage: S - Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1 - sage: loads(S.dumps()) == S + sage: S. = R.quotient(x^2 + 1) # optional - sage.rings.number_field + sage: S # optional - sage.rings.number_field + Univariate Quotient Polynomial Ring in xbar over Rational Field + with modulus x^2 + 1 + sage: loads(S.dumps()) == S # optional - sage.rings.number_field True - sage: loads(xbar.dumps()) == xbar + sage: loads(xbar.dumps()) == xbar # optional - sage.rings.number_field True """ def __init__(self, ring, polynomial, name=None, category=None): @@ -2344,23 +2401,27 @@ def __init__(self, ring, polynomial, name=None, category=None): def base_field(self): r""" - Alias for base_ring, when we're defined over a field. + Alias for :meth:`base_ring`, when we're defined over a field. """ return self.base_ring() def complex_embeddings(self, prec=53): r""" Return all homomorphisms of this ring into the approximate complex - field with precision prec. + field with precision ``prec``. EXAMPLES:: sage: R. = QQ[] sage: f = x^5 + x + 17 - sage: k = R.quotient(f) - sage: v = k.complex_embeddings(100) - sage: [phi(k.0^2) for phi in v] - [2.9757207403766761469671194565, -2.4088994371613850098316292196 + 1.9025410530350528612407363802*I, -2.4088994371613850098316292196 - 1.9025410530350528612407363802*I, 0.92103906697304693634806949137 - 3.0755331188457794473265418086*I, 0.92103906697304693634806949137 + 3.0755331188457794473265418086*I] + sage: k = R.quotient(f) # optional - sage.rings.number_field + sage: v = k.complex_embeddings(100) # optional - sage.rings.number_field + sage: [phi(k.0^2) for phi in v] # optional - sage.rings.number_field + [2.9757207403766761469671194565, + -2.4088994371613850098316292196 + 1.9025410530350528612407363802*I, + -2.4088994371613850098316292196 - 1.9025410530350528612407363802*I, + 0.92103906697304693634806949137 - 3.0755331188457794473265418086*I, + 0.92103906697304693634806949137 + 3.0755331188457794473265418086*I] """ CC = sage.rings.complex_mpfr.ComplexField(prec) v = self.modulus().roots(multiplicities=False, ring=CC) diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring_element.py b/src/sage/rings/polynomial/polynomial_quotient_ring_element.py index be05a312725..7dd4e836be1 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring_element.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring_element.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.pari r""" Elements of Quotients of Univariate Polynomial Rings @@ -7,8 +8,8 @@ :: sage: R. = ZZ[] - sage: S. = R.quotient(x^3 + 3*x -1) - sage: 2 * a^3 + sage: S. = R.quotient(x^3 + 3*x - 1) # optional - sage.libs.pari + sage: 2 * a^3 # optional - sage.libs.pari -6*a + 2 Next we make a univariate polynomial ring over @@ -16,24 +17,24 @@ :: - sage: S1. = S[] + sage: S1. = S[] # optional - sage.libs.pari And, we quotient out that by `y^2 + a`. :: - sage: T. = S1.quotient(y^2+a) + sage: T. = S1.quotient(y^2 + a) # optional - sage.libs.pari In the quotient `z^2` is `-a`. :: - sage: z^2 + sage: z^2 # optional - sage.libs.pari -a And since `a^3 = -3x + 1`, we have:: - sage: z^6 + sage: z^6 # optional - sage.libs.pari 3*a - 1 :: @@ -46,7 +47,7 @@ :: sage: R. = PolynomialRing(QQ) - sage: S. = R.quotient(x^3-2) + sage: S. = R.quotient(x^3 - 2) sage: a a sage: a^3 @@ -96,7 +97,7 @@ class PolynomialQuotientRingElement(polynomial_singular_interface.Polynomial_sin EXAMPLES:: sage: P. = QQ[] - sage: Q. = P.quo([(x^2+1)]) + sage: Q. = P.quo([(x^2 + 1)]) sage: xi^2 -1 sage: singular(xi) @@ -161,15 +162,15 @@ def _im_gens_(self, codomain, im_gens, base_map=None): EXAMPLES:: sage: Zx. = ZZ[] - sage: K. = NumberField(x^2 + 1) - sage: cc = K.hom([-i]) - sage: S. = K[] - sage: Q. = S.quotient(y^2*(y-1)*(y-i)) - sage: T. = S.quotient(y*(y+1)) - sage: phi = Q.hom([t+1], base_map=cc) - sage: phi(q) + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: cc = K.hom([-i]) # optional - sage.rings.number_field + sage: S. = K[] # optional - sage.rings.number_field + sage: Q. = S.quotient(y^2*(y-1)*(y-i)) # optional - sage.rings.number_field + sage: T. = S.quotient(y*(y+1)) # optional - sage.rings.number_field + sage: phi = Q.hom([t+1], base_map=cc) # optional - sage.rings.number_field + sage: phi(q) # optional - sage.rings.number_field t + 1 - sage: phi(i*q) + sage: phi(i*q) # optional - sage.rings.number_field -i*t - i """ return self._polynomial._im_gens_(codomain, im_gens, base_map=base_map) @@ -270,7 +271,7 @@ def _add_(self, right): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S. = R.quotient(x^3-2) + sage: S. = R.quotient(x^3 - 2) sage: (a^2 - 4) + (a+2) a^2 + a - 2 sage: int(1) + a @@ -286,7 +287,7 @@ def _div_(self, right): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S. = R.quotient(x^3-2) + sage: S. = R.quotient(x^3 - 2) sage: (a^2 - 4) / (a+2) a - 2 """ @@ -303,7 +304,7 @@ def _richcmp_(self, other, op): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S. = R.quotient(x^3-2) + sage: S. = R.quotient(x^3 - 2) sage: (a^2 - 4) / (a+2) == a - 2 True sage: a^2 - 4 == a @@ -321,7 +322,7 @@ def __int__(self): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S. = R.quotient(x^3-2) + sage: S. = R.quotient(x^3 - 2) sage: int(S(10)) 10 sage: int(a) @@ -345,7 +346,7 @@ def is_unit(self): sage: S. = R.quotient(x^2 + 2*x + 1) sage: (2*y).is_unit() True - sage: (y+1).is_unit() + sage: (y + 1).is_unit() False TESTS: @@ -460,59 +461,59 @@ def field_extension(self, names): - field - - homomorphism from self to field + - homomorphism from ``self`` to field - - homomorphism from field to self + - homomorphism from field to ``self`` EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S. = R.quotient(x^3-2) - sage: F., f, g = alpha.field_extension() - sage: F + sage: S. = R.quotient(x^3 - 2) + sage: F., f, g = alpha.field_extension() # optional - sage.rings.number_field + sage: F # optional - sage.rings.number_field Number Field in a with defining polynomial x^3 - 2 - sage: a = F.gen() - sage: f(alpha) + sage: a = F.gen() # optional - sage.rings.number_field + sage: f(alpha) # optional - sage.rings.number_field a - sage: g(a) + sage: g(a) # optional - sage.rings.number_field alpha Over a finite field, the corresponding field extension is not a number field:: - sage: R. = GF(25,'b')['x'] - sage: S. = R.quo(x^3 + 2*x + 1) - sage: F., g, h = a.field_extension() - sage: h(b^2 + 3) + sage: R. = GF(25,'b')['x'] # optional - sage.rings.finite_rings + sage: S. = R.quo(x^3 + 2*x + 1) # optional - sage.rings.finite_rings + sage: F., g, h = a.field_extension() # optional - sage.rings.finite_rings + sage: h(b^2 + 3) # optional - sage.rings.finite_rings a^2 + 3 - sage: g(x^2 + 2) + sage: g(x^2 + 2) # optional - sage.rings.finite_rings b^2 + 2 We do an example involving a relative number field:: sage: R. = QQ['x'] - sage: K. = NumberField(x^3-2) - sage: S. = K['X'] - sage: Q. = S.quo(X^3 + 2*X + 1) - sage: F, g, h = b.field_extension('c') + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: S. = K['X'] # optional - sage.rings.number_field + sage: Q. = S.quo(X^3 + 2*X + 1) # optional - sage.rings.number_field + sage: F, g, h = b.field_extension('c') # optional - sage.rings.number_field Another more awkward example:: sage: R. = QQ['x'] - sage: K. = NumberField(x^3-2) - sage: S. = K['X'] - sage: f = (X+a)^3 + 2*(X+a) + 1 - sage: f + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: S. = K['X'] # optional - sage.rings.number_field + sage: f = (X+a)^3 + 2*(X+a) + 1 # optional - sage.rings.number_field + sage: f # optional - sage.rings.number_field X^3 + 3*a*X^2 + (3*a^2 + 2)*X + 2*a + 3 - sage: Q. = S.quo(f) - sage: F., g, h = z.field_extension() - sage: c = g(z) - sage: f(c) + sage: Q. = S.quo(f) # optional - sage.rings.number_field + sage: F., g, h = z.field_extension() # optional - sage.rings.number_field + sage: c = g(z) # optional - sage.rings.number_field + sage: f(c) # optional - sage.rings.number_field 0 - sage: h(g(z)) + sage: h(g(z)) # optional - sage.rings.number_field z - sage: g(h(w)) + sage: g(h(w)) # optional - sage.rings.number_field w AUTHORS: @@ -693,21 +694,21 @@ def minpoly(self): sage: R. = PolynomialRing(QQ) sage: S. = R.quotient(x^3 + 2*x - 5) - sage: (a+123).minpoly() + sage: (a + 123).minpoly() x^3 - 369*x^2 + 45389*x - 1861118 - sage: (a+123).matrix().minpoly() + sage: (a + 123).matrix().minpoly() x^3 - 369*x^2 + 45389*x - 1861118 One useful application of this function is to compute a minimal polynomial of a finite-field element over an intermediate extension, rather than the absolute minimal polynomial over the prime field:: - sage: F2. = GF((431,2), modulus=[1,0,1]) - sage: F6. = F2.extension(3) - sage: (u+1).minpoly() + sage: F2. = GF((431,2), modulus=[1,0,1]) # optional - sage.rings.finite_rings + sage: F6. = F2.extension(3) # optional - sage.rings.finite_rings + sage: (u + 1).minpoly() # optional - sage.rings.finite_rings x^6 + 425*x^5 + 19*x^4 + 125*x^3 + 189*x^2 + 239*x + 302 - sage: ext = F6.over(F2) - sage: ext(u+1).minpoly() # indirect doctest + sage: ext = F6.over(F2) # optional - sage.rings.finite_rings + sage: ext(u + 1).minpoly() # indirect doctest # optional - sage.rings.finite_rings x^3 + (396*i + 428)*x^2 + (80*i + 39)*x + 9*i + 178 TESTS: @@ -715,15 +716,15 @@ def minpoly(self): We make sure that the previous example works on random examples:: sage: p = random_prime(50) - sage: K. = GF((p, randrange(1,20))) - sage: L. = K.extension(randrange(2,20)) - sage: LK = L.over(K) - sage: a = L.random_element() - sage: poly = LK(a).minpoly() # indirect doctest - sage: poly(a) + sage: K. = GF((p, randrange(1,20))) # optional - sage.rings.finite_rings + sage: L. = K.extension(randrange(2,20)) # optional - sage.rings.finite_rings + sage: LK = L.over(K) # optional - sage.rings.finite_rings + sage: a = L.random_element() # optional - sage.rings.finite_rings + sage: poly = LK(a).minpoly() # indirect doctest # optional - sage.rings.finite_rings + sage: poly(a) # optional - sage.rings.finite_rings 0 - sage: abs_deg = a.minpoly().degree() - sage: poly.degree() == abs_deg // gcd(abs_deg, K.degree()) + sage: abs_deg = a.minpoly().degree() # optional - sage.rings.finite_rings + sage: poly.degree() == abs_deg // gcd(abs_deg, K.degree()) # optional - sage.rings.finite_rings True """ poly = self.lift() @@ -741,7 +742,7 @@ def norm(self): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S. = R.quotient(x^3 -389*x^2 + 2*x - 5) + sage: S. = R.quotient(x^3 - 389*x^2 + 2*x - 5) sage: a.norm() 5 """ @@ -771,11 +772,14 @@ def rational_reconstruction(self, *args, **kwargs): EXAMPLES:: - sage: R. = GF(65537)[] - sage: m = x^11 + 25345*x^10 + 10956*x^9 + 13873*x^8 + 23962*x^7 + 17496*x^6 + 30348*x^5 + 7440*x^4 + 65438*x^3 + 7676*x^2 + 54266*x + 47805 - sage: f = 20437*x^10 + 62630*x^9 + 63241*x^8 + 12820*x^7 + 42171*x^6 + 63091*x^5 + 15288*x^4 + 32516*x^3 + 2181*x^2 + 45236*x + 2447 - sage: f_mod_m = R.quotient(m)(f) - sage: f_mod_m.rational_reconstruction() + sage: R. = GF(65537)[] # optional - sage.rings.finite_rings + sage: m = (x^11 + 25345*x^10 + 10956*x^9 + 13873*x^8 + 23962*x^7 # optional - sage.rings.finite_rings + ....: + 17496*x^6 + 30348*x^5 + 7440*x^4 + 65438*x^3 + 7676*x^2 + ....: + 54266*x + 47805) + sage: f = (20437*x^10 + 62630*x^9 + 63241*x^8 + 12820*x^7 + 42171*x^6 # optional - sage.rings.finite_rings + ....: + 63091*x^5 + 15288*x^4 + 32516*x^3 + 2181*x^2 + 45236*x + 2447) + sage: f_mod_m = R.quotient(m)(f) # optional - sage.rings.finite_rings + sage: f_mod_m.rational_reconstruction() # optional - sage.rings.finite_rings (51388*x^5 + 29141*x^4 + 59341*x^3 + 7034*x^2 + 14152*x + 23746, x^5 + 15208*x^4 + 19504*x^3 + 20457*x^2 + 11180*x + 28352) """ diff --git a/src/sage/rings/polynomial/polynomial_rational_flint.pyx b/src/sage/rings/polynomial/polynomial_rational_flint.pyx index d85ad4af690..50837b850d0 100644 --- a/src/sage/rings/polynomial/polynomial_rational_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_rational_flint.pyx @@ -193,11 +193,11 @@ cdef class Polynomial_rational_flint(Polynomial): def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): """ - Initialises the associated data for the polynomial self. + Initialises the associated data for the polynomial ``self``. INPUT: - - ``parent`` - Polynomial ring, the parent of self + - ``parent`` - Polynomial ring, the parent of ``self`` - ``x`` - Data for the new polynomial self, e.g. a polynomial, an integer, a rational, a list of rationals, a dictionary with keys the degrees and the rational coefficients, etc (default: ``None``) @@ -319,7 +319,7 @@ cdef class Polynomial_rational_flint(Polynomial): def __copy__(self): """ - Return a copy of self. + Return a copy of ``self``. TESTS:: @@ -334,7 +334,7 @@ cdef class Polynomial_rational_flint(Polynomial): def _singular_(self, singular=singular_default): """ - Return a Singular representation of self. + Return a Singular representation of ``self``. INPUT: @@ -375,7 +375,7 @@ cdef class Polynomial_rational_flint(Polynomial): """ Return the degree of ``self``. - By convention, the degree of the zero polynomial is -1. + By convention, the degree of the zero polynomial is `-1`. EXAMPLES:: @@ -418,7 +418,7 @@ cdef class Polynomial_rational_flint(Polynomial): cpdef _unsafe_mutate(self, unsigned long n, value): """ - Sets the `n`-th coefficient of self to value. + Sets the `n`-th coefficient of ``self`` to value. TESTS:: @@ -557,7 +557,7 @@ cdef class Polynomial_rational_flint(Polynomial): INPUT: - - ``n`` - The power of `t` modulo which self is truncated + - ``n`` - The power of `t` modulo which ``self`` is truncated EXAMPLES:: @@ -603,7 +603,7 @@ cdef class Polynomial_rational_flint(Polynomial): sage: f.reverse() t^4 + t^3 + 1/2*t^2 + 1/3*t + 1/4 - Next, an example we the returned polynomial has lower degree because + Next, an example where the returned polynomial has lower degree because the original polynomial has low coefficients equal to zero:: sage: R. = QQ[] @@ -612,7 +612,7 @@ cdef class Polynomial_rational_flint(Polynomial): 3/4*t^5 + 6 The next example illustrates the passing of a value for ``degree`` less - than the length of self, notationally resulting in truncation prior to + than the length of ``self``, notationally resulting in truncation prior to reversing:: sage: R. = QQ[] @@ -621,7 +621,7 @@ cdef class Polynomial_rational_flint(Polynomial): t^2 + t + 1/2 Now we illustrate the passing of a value for ``degree`` greater than - the length of self, notationally resulting in zero padding at the top + the length of ``self``, notationally resulting in zero padding at the top end prior to reversing:: sage: R. = QQ[] @@ -681,7 +681,7 @@ cdef class Polynomial_rational_flint(Polynomial): def revert_series(self, n): r""" - Return a polynomial `f` such that `f(self(x)) = self(f(x)) = x mod x^n`. + Return a polynomial `f` such that ``f(self(x)) = self(f(x)) = x mod x^n``. EXAMPLES:: @@ -721,7 +721,7 @@ cdef class Polynomial_rational_flint(Polynomial): cpdef bint is_zero(self) except -1: """ - Return whether or not self is the zero polynomial. + Return whether or not ``self`` is the zero polynomial. EXAMPLES:: @@ -756,7 +756,7 @@ cdef class Polynomial_rational_flint(Polynomial): def __bool__(self): """ - Return whether or not self is non-zero. + Return whether or not ``self`` is non-zero. EXAMPLES:: @@ -808,7 +808,7 @@ cdef class Polynomial_rational_flint(Polynomial): def __rshift__(self, n): """ - Notationally returns the quotient of Euclidean division of self + Notationally returns the quotient of Euclidean division of ``self`` by `t^n`. EXAMPLES:: @@ -922,11 +922,11 @@ cdef class Polynomial_rational_flint(Polynomial): @coerce_binop def quo_rem(self, right): - """ + r""" Return the quotient and remainder of the Euclidean division of - self and right. + ``self`` and ``right``. - Raises a ZerodivisionError if right is zero. + Raises a :class:`ZeroDivisionError` if ``right`` is zero. EXAMPLES:: @@ -953,10 +953,10 @@ cdef class Polynomial_rational_flint(Polynomial): @coerce_binop def gcd(self, right): - """ - Return the (monic) greatest common divisor of self and right. + r""" + Return the (monic) greatest common divisor of ``self`` and ``right``. - Corner cases: if self and right are both zero, returns zero. If + Corner cases: if ``self`` and ``right`` are both zero, returns zero. If only one of them is zero, returns the other polynomial, up to normalisation. @@ -982,11 +982,11 @@ cdef class Polynomial_rational_flint(Polynomial): @coerce_binop def lcm(self, right): - """ - Return the monic (or zero) least common multiple of self and right. + r""" + Return the monic (or zero) least common multiple of ``self`` and ``right``. - Corner cases: if either of self and right are zero, returns zero. - This behaviour is ensures that the relation lcm(a,b) gcd(a,b) == a b + Corner cases: if either of ``self`` and ``right`` are zero, returns zero. + This behaviour is ensures that the relation `\lcm(a,b)\cdot \gcd(a,b) = a\cdot b` holds up to multiplication by rationals. EXAMPLES:: @@ -1009,14 +1009,14 @@ cdef class Polynomial_rational_flint(Polynomial): @coerce_binop def xgcd(self, right): - """ - Return polynomials d, s, and t such that d == s * self + t * right, - where d is the (monic) greatest common divisor of self and right. - The choice of s and t is not specified any further. + r""" + Return polynomials `d`, `s`, and `t` such that ``d == s * self + t * right``, + where `d` is the (monic) greatest common divisor of ``self`` and ``right``. + The choice of `s` and `t` is not specified any further. - Corner cases: if self and right are zero, returns zero polynomials. - Otherwise, if only self is zero, returns (d, s, t) = (right, 0, 1) up - to normalisation, and similarly if only right is zero. + Corner cases: if ``self`` and ``right`` are zero, returns zero polynomials. + Otherwise, if only ``self`` is zero, returns ``(d, s, t) = (right, 0, 1)`` up + to normalisation, and similarly if only ``right`` is zero. EXAMPLES:: @@ -1050,7 +1050,7 @@ cdef class Polynomial_rational_flint(Polynomial): cpdef _mul_(self, right): """ - Return the product of self and right. + Return the product of ``self`` and ``right``. EXAMPLES:: @@ -1116,7 +1116,7 @@ cdef class Polynomial_rational_flint(Polynomial): cpdef _rmul_(self, Element left): r""" - Return left * self, where left is a rational number. + Return ``left * self``, where ``left`` is a rational number. EXAMPLES:: @@ -1136,7 +1136,7 @@ cdef class Polynomial_rational_flint(Polynomial): cpdef _lmul_(self, Element right): r""" - Return self * right, where right is a rational number. + Return ``self * right``, where ``right`` is a rational number. EXAMPLES:: @@ -1299,7 +1299,7 @@ cdef class Polynomial_rational_flint(Polynomial): def __floordiv__(Polynomial_rational_flint self, right): """ - Return the quotient of self and right obtain by Euclidean division. + Return the quotient of ``self`` and ``right`` obtained by Euclidean division. EXAMPLES:: @@ -1396,7 +1396,7 @@ cdef class Polynomial_rational_flint(Polynomial): cpdef _mod_(self, right): """ - Return the remainder of self and right obtain by Euclidean division. + Return the remainder of ``self`` and ``right`` obtain by Euclidean division. EXAMPLES:: @@ -1435,7 +1435,7 @@ cdef class Polynomial_rational_flint(Polynomial): def numerator(self): """ - Return the numerator of self. + Return the numerator of ``self``. Representing self as the quotient of an integer polynomial and a positive integer denominator (coprime to the content of the @@ -1460,7 +1460,7 @@ cdef class Polynomial_rational_flint(Polynomial): def denominator(self): """ - Return the denominator of self. + Return the denominator of ``self``. EXAMPLES:: @@ -1527,7 +1527,7 @@ cdef class Polynomial_rational_flint(Polynomial): def real_root_intervals(self): """ - Return isolating intervals for the real roots of self. + Return isolating intervals for the real roots of ``self``. EXAMPLES: @@ -1545,10 +1545,10 @@ cdef class Polynomial_rational_flint(Polynomial): @coerce_binop def resultant(Polynomial_rational_flint self, right): r""" - Return the resultant of self and right. + Return the resultant of ``self`` and ``right``. - Enumerating the roots over `\QQ` as `r_1, \cdots, r_m` and - `s_1, \cdots, s_n` and letting `x` and `y` denote the leading + Enumerating the roots over `\QQ` as `r_1, \dots, r_m` and + `s_1, \dots, s_n` and letting `x` and `y` denote the leading coefficients of `f` and `g`, the resultant of the two polynomials is defined by @@ -1610,7 +1610,7 @@ cdef class Polynomial_rational_flint(Polynomial): False sage: R(-1/2).is_irreducible() False - sage: (t+1).is_irreducible() + sage: (t + 1).is_irreducible() True Test that caching works:: @@ -2067,7 +2067,7 @@ cdef class Polynomial_rational_flint(Polynomial): - ``pari_group`` - bool (default: ``False``); if ``True`` instead return the Galois group as a PARI group. This has a useful label in it, and may be slightly faster since it doesn't require looking - up a group in Gap. To get a permutation group from a PARI + up a group in GAP. To get a permutation group from a PARI group ``P``, type ``PermutationGroup(P)``. - ``algorithm`` - ``'pari'``, ``'gap'``, ``'kash'``, ``'magma'`` (default: @@ -2075,9 +2075,7 @@ cdef class Polynomial_rational_flint(Polynomial): ``'gap'``, for degrees from 12 to 15; ``'kash'``, for degrees from 16 or more). - OUTPUT: - - - Galois group + OUTPUT: Galois group ALGORITHM: @@ -2234,23 +2232,21 @@ cdef class Polynomial_rational_flint(Polynomial): def factor_mod(self, p): """ - Return the factorization of self modulo the prime ``p``. + Return the factorization of ``self`` modulo the prime `p`. Assumes that the degree of this polynomial is at least one, and raises - a ``ValueError`` otherwise. + a :class:`ValueError` otherwise. INPUT: - ``p`` - Prime number - OUTPUT: - - - Factorization of this polynomial modulo ``p`` + OUTPUT: Factorization of this polynomial modulo `p` EXAMPLES:: sage: R. = QQ[] - sage: (x^5 + 17*x^3 + x+ 3).factor_mod(3) + sage: (x^5 + 17*x^3 + x + 3).factor_mod(3) x * (x^2 + 1)^2 sage: (x^5 + 2).factor_mod(5) (x + 2)^5 @@ -2278,7 +2274,7 @@ cdef class Polynomial_rational_flint(Polynomial): return R(1)._factor_pari_helper(G, unit=R(self).leading_coefficient()) def factor_padic(self, p, prec=10): - """ + r""" Return the `p`-adic factorization of this polynomial to the given precision. @@ -2288,47 +2284,53 @@ cdef class Polynomial_rational_flint(Polynomial): - ``prec`` - Integer; the precision - OUTPUT: - - - factorization of ``self`` viewed as a `p`-adic polynomial + OUTPUT: factorization of ``self`` viewed as a `p`-adic polynomial EXAMPLES:: sage: R. = QQ[] sage: f = x^3 - 2 sage: f.factor_padic(2) - (1 + O(2^10))*x^3 + O(2^10)*x^2 + O(2^10)*x + 2 + 2^2 + 2^3 + 2^4 + 2^5 + 2^6 + 2^7 + 2^8 + 2^9 + O(2^10) + (1 + O(2^10))*x^3 + O(2^10)*x^2 + O(2^10)*x + + 2 + 2^2 + 2^3 + 2^4 + 2^5 + 2^6 + 2^7 + 2^8 + 2^9 + O(2^10) sage: f.factor_padic(3) - (1 + O(3^10))*x^3 + O(3^10)*x^2 + O(3^10)*x + 1 + 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 + O(3^10) + (1 + O(3^10))*x^3 + O(3^10)*x^2 + O(3^10)*x + + 1 + 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 + O(3^10) sage: f.factor_padic(5) - ((1 + O(5^10))*x + 2 + 4*5 + 2*5^2 + 2*5^3 + 5^4 + 3*5^5 + 4*5^7 + 2*5^8 + 5^9 + O(5^10)) * ((1 + O(5^10))*x^2 + (3 + 2*5^2 + 2*5^3 + 3*5^4 + 5^5 + 4*5^6 + 2*5^8 + 3*5^9 + O(5^10))*x + 4 + 5 + 2*5^2 + 4*5^3 + 4*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 4*5^9 + O(5^10)) + ((1 + O(5^10))*x + + 2 + 4*5 + 2*5^2 + 2*5^3 + 5^4 + 3*5^5 + 4*5^7 + 2*5^8 + 5^9 + O(5^10)) + * ((1 + O(5^10))*x^2 + + (3 + 2*5^2 + 2*5^3 + 3*5^4 + 5^5 + 4*5^6 + 2*5^8 + 3*5^9 + O(5^10))*x + + 4 + 5 + 2*5^2 + 4*5^3 + 4*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 4*5^9 + O(5^10)) The input polynomial is considered to have "infinite" precision, therefore the `p`-adic factorization of the polynomial is not - the same as first coercing to `Q_p` and then factoring + the same as first coercing to `\QQ_p` and then factoring (see also :trac:`15422`):: sage: f = x^2 - 3^6 - sage: f.factor_padic(3,5) + sage: f.factor_padic(3, 5) ((1 + O(3^5))*x + 3^3 + O(3^5)) * ((1 + O(3^5))*x + 2*3^3 + 2*3^4 + O(3^5)) sage: f.change_ring(Qp(3,5)).factor() Traceback (most recent call last): ... - PrecisionError: p-adic factorization not well-defined since the discriminant is zero up to the requestion p-adic precision + PrecisionError: p-adic factorization not well-defined since + the discriminant is zero up to the requestion p-adic precision A more difficult example:: sage: f = 100 * (5*x + 1)^2 * (x + 5)^2 sage: f.factor_padic(5, 10) - (4*5^4 + O(5^14)) * ((1 + O(5^9))*x + 5^-1 + O(5^9))^2 * ((1 + O(5^10))*x + 5 + O(5^10))^2 + (4*5^4 + O(5^14)) * ((1 + O(5^9))*x + 5^-1 + O(5^9))^2 + * ((1 + O(5^10))*x + 5 + O(5^10))^2 Try some bogus inputs:: - sage: f.factor_padic(3,-1) + sage: f.factor_padic(3, -1) Traceback (most recent call last): ... ValueError: prec_cap must be non-negative - sage: f.factor_padic(6,10) + sage: f.factor_padic(6, 10) Traceback (most recent call last): ... ValueError: p must be prime @@ -2362,12 +2364,10 @@ cdef class Polynomial_rational_flint(Polynomial): INPUT: - - ``p`` - Prime number; coerceable to ``Integer`` - - ``e`` - Exponent; coerceable to ``Integer`` - - OUTPUT: + - ``p`` - Prime number; coerceable to :class:`Integer` + - ``e`` - Exponent; coerceable to :class:`Integer` - - Hensel lifts; list of polynomials over `\ZZ / p^e \ZZ` + OUTPUT: Hensel lifts; list of polynomials over `\ZZ / p^e \ZZ` EXAMPLES:: @@ -2388,7 +2388,7 @@ cdef class Polynomial_rational_flint(Polynomial): [] sage: R(x).hensel_lift(7, 2) [x] - sage: R(x-1).hensel_lift(7, 2) + sage: R(x - 1).hensel_lift(7, 2) [x + 48] Variable names that are reserved in PARI, such as ``I``, are @@ -2446,16 +2446,14 @@ cdef class Polynomial_rational_flint(Polynomial): The discriminant of constant polynomials is defined to be 0. - OUTPUT: - - - Discriminant, an element of the base ring of the polynomial ring + OUTPUT: Discriminant, an element of the base ring of the polynomial ring .. NOTE:: - Note the identity `R_n(f) := (-1)^(n (n-1)/2) R(f,f') a_n^(n-k-2)`, + Note the identity `R_n(f) := (-1)^{(n (n-1)/2)} R(f,f') a_n^{(n-k-2)}`, where `n` is the degree of this polynomial, `a_n` is the leading coefficient, `f'` is the derivative of `f`, and `k` is the degree - of `f'`. Calls :meth:`.resultant`. + of `f'`. Calls :meth:`resultant`. ALGORITHM: @@ -2514,14 +2512,14 @@ cdef class Polynomial_rational_flint(Polynomial): def galois_group_davenport_smith_test(self, num_trials=50, assume_irreducible=False): """ - Use the Davenport-Smith test to attempt to certify that `f` has Galois group A_n or S_n. + Use the Davenport-Smith test to attempt to certify that `f` has Galois group `A_n` or `S_n`. - Return 1 if the Galois group is certified as S_n, 2 if A_n, or 0 if no conclusion is reached. + Return 1 if the Galois group is certified as `S_n`, 2 if `A_n`, or 0 if no conclusion is reached. By default, we first check that `f` is irreducible. For extra efficiency, one can override this - by specifying `assume_irreducible=True`; this yields undefined results if `f` is not irreducible. + by specifying ``assume_irreducible=True``; this yields undefined results if `f` is not irreducible. - A corresponding function in Magma is `IsEasySnAn`. + A corresponding function in Magma is ``IsEasySnAn``. EXAMPLES:: diff --git a/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx b/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx index c13372dcd25..4b61c4aa89d 100644 --- a/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +++ b/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx @@ -6,19 +6,19 @@ TESTS: Check that operations with numpy elements work well (see :trac:`18076` and :trac:`8426`):: - sage: import numpy + sage: import numpy # optional - numpy sage: x = polygen(RR) - sage: x * numpy.int32('1') + sage: x * numpy.int32('1') # optional - numpy x - sage: numpy.int32('1') * x + sage: numpy.int32('1') * x # optional - numpy x - sage: x * numpy.int64('1') + sage: x * numpy.int64('1') # optional - numpy x - sage: numpy.int64('1') * x + sage: numpy.int64('1') * x # optional - numpy x - sage: x * numpy.float32('1.5') + sage: x * numpy.float32('1.5') # optional - numpy 1.50000000000000*x - sage: numpy.float32('1.5') * x + sage: numpy.float32('1.5') * x # optional - numpy 1.50000000000000*x """ @@ -72,7 +72,7 @@ cdef class PolynomialRealDense(Polynomial): EXAMPLES:: sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense - sage: PolynomialRealDense(RR['x'], [1, int(2), RR(3), 4/1, pi]) + sage: PolynomialRealDense(RR['x'], [1, int(2), RR(3), 4/1, pi]) # optional - sage.symbolic 3.14159265358979*x^4 + 4.00000000000000*x^3 + 3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000 sage: PolynomialRealDense(RR['x'], None) 0 @@ -81,13 +81,13 @@ cdef class PolynomialRealDense(Polynomial): Check that errors and interrupts are handled properly (see :trac:`10100`):: - sage: a = var('a') - sage: PolynomialRealDense(RR['x'], [1,a]) + sage: a = var('a') # optional - sage.symbolic + sage: PolynomialRealDense(RR['x'], [1,a]) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: cannot evaluate symbolic expression to a numeric value - sage: R. = SR[] - sage: (x-a).change_ring(RR) + sage: R. = SR[] # optional - sage.symbolic + sage: (x-a).change_ring(RR) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: cannot evaluate symbolic expression to a numeric value @@ -96,9 +96,9 @@ cdef class PolynomialRealDense(Polynomial): Test that we don't clean up uninitialized coefficients (:trac:`9826`):: - sage: k. = GF(7^3) - sage: P. = PolynomialRing(k) - sage: (a*x).complex_roots() + sage: k. = GF(7^3) # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(k) # optional - sage.rings.finite_rings + sage: (a*x).complex_roots() # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unable to convert 'a' to a real number @@ -283,14 +283,15 @@ cdef class PolynomialRealDense(Polynomial): def truncate_abs(self, RealNumber bound): """ - Truncate all high order coefficients below bound. + Truncate all high order coefficients below ``bound``. EXAMPLES:: sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RealField(10)['x'], [10^-k for k in range(10)]) sage: f - 1.0e-9*x^9 + 1.0e-8*x^8 + 1.0e-7*x^7 + 1.0e-6*x^6 + 0.000010*x^5 + 0.00010*x^4 + 0.0010*x^3 + 0.010*x^2 + 0.10*x + 1.0 + 1.0e-9*x^9 + 1.0e-8*x^8 + 1.0e-7*x^7 + 1.0e-6*x^6 + 0.000010*x^5 + + 0.00010*x^4 + 0.0010*x^3 + 0.010*x^2 + 0.10*x + 1.0 sage: f.truncate_abs(0.5e-6) 1.0e-6*x^6 + 0.000010*x^5 + 0.00010*x^4 + 0.0010*x^3 + 0.010*x^2 + 0.10*x + 1.0 sage: f.truncate_abs(10.0) @@ -513,16 +514,16 @@ cdef class PolynomialRealDense(Polynomial): EXAMPLES:: sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense - sage: f = PolynomialRealDense(RR['x'], [pi, 0, 2, 1]) - sage: f.derivative() + sage: f = PolynomialRealDense(RR['x'], [pi, 0, 2, 1]) # optional - sage.symbolic + sage: f.derivative() # optional - sage.symbolic 3.00000000000000*x^2 + 4.00000000000000*x TESTS:: - sage: x, y = var('x,y') - sage: f.derivative(x) + sage: x, y = var('x,y') # optional - sage.symbolic + sage: f.derivative(x) # optional - sage.symbolic 3.00000000000000*x^2 + 4.00000000000000*x - sage: f.derivative(y) + sage: f.derivative(y) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: cannot differentiate with respect to y @@ -541,8 +542,8 @@ cdef class PolynomialRealDense(Polynomial): EXAMPLES:: sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense - sage: f = PolynomialRealDense(RR['x'], [3, pi, 1]) - sage: f.integral() + sage: f = PolynomialRealDense(RR['x'], [3, pi, 1]) # optional - sage.symbolic + sage: f.integral() # optional - sage.symbolic 0.333333333333333*x^3 + 1.57079632679490*x^2 + 3.00000000000000*x """ cdef mpfr_rnd_t rnd = self._base_ring.rnd @@ -566,19 +567,19 @@ cdef class PolynomialRealDense(Polynomial): EXAMPLES:: - sage: f = RR['x']([-3, pi, 0, 1]) - sage: f.reverse() + sage: f = RR['x']([-3, pi, 0, 1]) # optional - sage.symbolic + sage: f.reverse() # optional - sage.symbolic -3.00000000000000*x^3 + 3.14159265358979*x^2 + 1.00000000000000 - sage: f.reverse(2) + sage: f.reverse(2) # optional - sage.symbolic -3.00000000000000*x^2 + 3.14159265358979*x - sage: f.reverse(5) + sage: f.reverse(5) # optional - sage.symbolic -3.00000000000000*x^5 + 3.14159265358979*x^4 + x^2 TESTS: We check that this implementation is compatible with the generic one:: - sage: all(f.reverse(d) == Polynomial.reverse(f, d) + sage: all(f.reverse(d) == Polynomial.reverse(f, d) # optional - sage.symbolic ....: for d in [None, 0, 1, 2, 3, 4, 5]) True """ @@ -619,9 +620,9 @@ cdef class PolynomialRealDense(Polynomial): (x^2 - 2.00000000000000, 0) sage: f = PolynomialRealDense(RR['x'], range(5)) - sage: g = PolynomialRealDense(RR['x'], [pi,3000,4]) - sage: q, r = f.quo_rem(g) - sage: g*q + r == f + sage: g = PolynomialRealDense(RR['x'], [pi,3000,4]) # optional - sage.symbolic + sage: q, r = f.quo_rem(g) # optional - sage.symbolic + sage: g*q + r == f # optional - sage.symbolic True TESTS: @@ -680,7 +681,7 @@ cdef class PolynomialRealDense(Polynomial): 2.00000000000000 sage: f(RealField(10)(2)) 2.0 - sage: f(pi) + sage: f(pi) # optional - sage.symbolic 1.00000000000000*pi^2 - 2.00000000000000 diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index ea07c8f5437..ff1d3532124 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -47,23 +47,23 @@ We create a polynomial ring over a quaternion algebra:: - sage: A. = QuaternionAlgebra(QQ, -1,-1) - sage: R. = PolynomialRing(A,sparse=True) - sage: f = w^3 + (i+j)*w + 1 - sage: f + sage: A. = QuaternionAlgebra(QQ, -1,-1) # optional - sage.combinat sage.modules + sage: R. = PolynomialRing(A, sparse=True) # optional - sage.combinat sage.modules + sage: f = w^3 + (i+j)*w + 1 # optional - sage.combinat sage.modules + sage: f # optional - sage.combinat sage.modules w^3 + (i + j)*w + 1 - sage: f^2 + sage: f^2 # optional - sage.combinat sage.modules w^6 + (2*i + 2*j)*w^4 + 2*w^3 - 2*w^2 + (2*i + 2*j)*w + 1 - sage: f = w + i ; g = w + j - sage: f * g + sage: f = w + i ; g = w + j # optional - sage.combinat sage.modules + sage: f * g # optional - sage.combinat sage.modules w^2 + (i + j)*w + k - sage: g * f + sage: g * f # optional - sage.combinat sage.modules w^2 + (i + j)*w - k :trac:`9944` introduced some changes related with coercion. Previously, a dense and a sparse polynomial ring with the same variable name over the same base ring evaluated equal, but of -course they were not identical.Coercion maps are cached - but if a +course they were not identical. Coercion maps are cached - but if a coercion to a dense ring is requested and a coercion to a sparse ring is returned instead (since the cache keys are equal!), all hell breaks loose. @@ -79,42 +79,42 @@ True sage: R.has_coerce_map_from(S) False - sage: (R.0+S.0).parent() + sage: (R.0 + S.0).parent() Univariate Polynomial Ring in x over Rational Field - sage: (S.0+R.0).parent() + sage: (S.0 + R.0).parent() Univariate Polynomial Ring in x over Rational Field It may be that one has rings of dense or sparse polynomials over different base rings. In that situation, coercion works by means of the :func:`~sage.categories.pushout.pushout` formalism:: - sage: R. = PolynomialRing(GF(5), sparse=True) + sage: R. = PolynomialRing(GF(5), sparse=True) # optional - sage.rings.finite_rings sage: S. = PolynomialRing(ZZ) - sage: R.has_coerce_map_from(S) + sage: R.has_coerce_map_from(S) # optional - sage.rings.finite_rings False - sage: S.has_coerce_map_from(R) + sage: S.has_coerce_map_from(R) # optional - sage.rings.finite_rings False - sage: S.0 + R.0 + sage: S.0 + R.0 # optional - sage.rings.finite_rings 2*x - sage: (S.0 + R.0).parent() + sage: (S.0 + R.0).parent() # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 5 - sage: (S.0 + R.0).parent().is_sparse() + sage: (S.0 + R.0).parent().is_sparse() # optional - sage.rings.finite_rings False Similarly, there is a coercion from the (non-default) NTL implementation for univariate polynomials over the integers to the default FLINT implementation, but not vice versa:: - sage: R. = PolynomialRing(ZZ, implementation = 'NTL') - sage: S. = PolynomialRing(ZZ, implementation = 'FLINT') - sage: (S.0+R.0).parent() is S + sage: R. = PolynomialRing(ZZ, implementation='NTL') # optional - sage.libs.ntl + sage: S. = PolynomialRing(ZZ, implementation='FLINT') # optional - sage.libs.flint + sage: (S.0 + R.0).parent() is S # optional - sage.libs.flint sage.libs.ntl True - sage: (R.0+S.0).parent() is S + sage: (R.0 + S.0).parent() is S # optional - sage.libs.flint sage.libs.ntl True TESTS:: - sage: K.=FractionField(QQ['x']) + sage: K. = FractionField(QQ['x']) sage: V. = K[] sage: x+z z + x @@ -122,9 +122,9 @@ Check that :trac:`5562` has been fixed:: sage: R. = PolynomialRing(RDF, 1) - sage: v1 = vector([u]) - sage: v2 = vector([CDF(2)]) - sage: v1 * v2 + sage: v1 = vector([u]) # optional - sage.modules + sage: v2 = vector([CDF(2)]) # optional - sage.modules + sage: v1 * v2 # optional - sage.modules 2.0*u """ @@ -180,7 +180,7 @@ def is_PolynomialRing(x): """ - Return True if x is a *univariate* polynomial ring (and not a + Return ``True`` if ``x`` is a *univariate* polynomial ring (and not a sparse multivariate polynomial ring in one variable). EXAMPLES:: @@ -210,11 +210,11 @@ def is_PolynomialRing(x): :: - sage: R. = PolynomialRing(ZZ, implementation="singular"); R + sage: R. = PolynomialRing(ZZ, implementation="singular"); R # optional - sage.libs.singular Multivariate Polynomial Ring in w over Integer Ring - sage: is_PolynomialRing(R) + sage: is_PolynomialRing(R) # optional - sage.libs.singular False - sage: type(R) + sage: type(R) # optional - sage.libs.singular """ return isinstance(x, PolynomialRing_general) @@ -243,7 +243,7 @@ def __init__(self, base_ring, name=None, sparse=False, implementation=None, and Category of commutative algebras over (euclidean domains and infinite enumerated sets and metric spaces) and Category of infinite sets - sage: category(GF(7)['x']) + sage: category(GF(7)['x']) # optional - sage.rings.finite_rings Join of Category of euclidean domains and Category of commutative algebras over (finite enumerated fields and subquotients of monoids and quotients of semigroups) and Category of infinite sets @@ -268,13 +268,13 @@ def __init__(self, base_ring, name=None, sparse=False, implementation=None, sage: Zmod(1)['x'].is_finite() True - sage: GF(7)['x'].is_finite() + sage: GF(7)['x'].is_finite() # optional - sage.rings.finite_rings False sage: Zmod(1)['x']['y'].is_finite() True - sage: GF(7)['x']['y'].is_finite() + sage: GF(7)['x']['y'].is_finite() # optional - sage.rings.finite_rings False """ @@ -357,9 +357,9 @@ def _element_constructor_(self, x=None, check=True, is_gen=False, Coercing in pari elements:: - sage: QQ['x'](pari('[1,2,3/5]')) + sage: QQ['x'](pari('[1,2,3/5]')) # optional - sage.libs.pari 3/5*x^2 + 2*x + 1 - sage: QQ['x'](pari('(-1/3)*x^10 + (2/3)*x - 1/5')) + sage: QQ['x'](pari('(-1/3)*x^10 + (2/3)*x - 1/5')) # optional - sage.libs.pari -1/3*x^10 + 2/3*x - 1/5 Coercing strings:: @@ -377,10 +377,10 @@ def _element_constructor_(self, x=None, check=True, is_gen=False, This shows that the issue at :trac:`4106` is fixed:: - sage: x = var('x') + sage: x = var('x') # optional - sage.symbolic sage: R = IntegerModRing(4) - sage: S = R['x'] - sage: S(x) + sage: S = R['x'] # optional - sage.symbolic + sage: S(x) # optional - sage.symbolic x Throw a TypeError if any of the coefficients cannot be coerced @@ -393,16 +393,16 @@ def _element_constructor_(self, x=None, check=True, is_gen=False, Check that the bug in :trac:`11239` is fixed:: - sage: K. = GF(5^2, prefix='z') - sage: L. = GF(5^4, prefix='z') - sage: f = K['x'].gen() + a - sage: L['x'](f) + sage: K. = GF(5^2, prefix='z') # optional - sage.rings.finite_rings + sage: L. = GF(5^4, prefix='z') # optional - sage.rings.finite_rings + sage: f = K['x'].gen() + a # optional - sage.rings.finite_rings + sage: L['x'](f) # optional - sage.rings.finite_rings x + b^3 + b^2 + b + 3 A test from :trac:`14485` :: - sage: x = SR.var('x') - sage: QQbar[x](x^6+x^5+x^4-x^3+x^2-x+2/5) + sage: x = SR.var('x') # optional - sage.symbolic + sage: QQbar[x](x^6 + x^5 + x^4 - x^3 + x^2 - x + 2/5) # optional - sage.rings.number_field sage.symbolic x^6 + x^5 + x^4 - x^3 + x^2 - x + 2/5 Check support for unicode characters (:trac:`29280`):: @@ -603,7 +603,8 @@ def flattening_morphism(self): sage: QQ['a','b']['x'].flattening_morphism() Flattening morphism: - From: Univariate Polynomial Ring in x over Multivariate Polynomial Ring in a, b over Rational Field + From: Univariate Polynomial Ring in x over + Multivariate Polynomial Ring in a, b over Rational Field To: Multivariate Polynomial Ring in a, b, x over Rational Field sage: QQ['x'].flattening_morphism() @@ -693,7 +694,7 @@ def _coerce_map_from_base_ring(self): Polynomial base injection morphism: From: Rational Field To: Univariate Polynomial Ring in x over Rational Field - sage: R.coerce_map_from(GF(7)) + sage: R.coerce_map_from(GF(7)) # optional - sage.rings.finite_rings """ from .polynomial_element import PolynomialBaseringInjection @@ -732,9 +733,9 @@ def _coerce_map_from_(self, P): sage: R. = PolynomialRing(QQ, sparse=True) sage: S. = QQ[] - sage: (R.0+S.0).parent() + sage: (R.0 + S.0).parent() Univariate Polynomial Ring in x over Rational Field - sage: (S.0+R.0).parent() + sage: (S.0 + R.0).parent() Univariate Polynomial Ring in x over Rational Field Here we test a feature that was implemented in :trac:`813`:: @@ -743,7 +744,7 @@ def _coerce_map_from_(self, P): sage: Q = Frac(QQ['x'])['y'] sage: Q.has_coerce_map_from(P) True - sage: P.0+Q.0 + sage: P.0 + Q.0 y + x In order to avoid bidirectional coercions (which are generally @@ -761,20 +762,20 @@ def _coerce_map_from_(self, P): Over the integers, there is a coercion from the NTL and generic implementation to the default FLINT implementation:: - sage: R = PolynomialRing(ZZ, 't', implementation="NTL") - sage: S = PolynomialRing(ZZ, 't', implementation="FLINT") + sage: R = PolynomialRing(ZZ, 't', implementation="NTL") # optional - sage.libs.ntl + sage: S = PolynomialRing(ZZ, 't', implementation="FLINT") # optional - sage.libs.flint sage: T = PolynomialRing(ZZ, 't', implementation="generic") - sage: R.has_coerce_map_from(S) + sage: R.has_coerce_map_from(S) # optional - sage.libs.flint sage.libs.ntl False - sage: R.has_coerce_map_from(T) + sage: R.has_coerce_map_from(T) # optional - sage.libs.ntl False - sage: S.has_coerce_map_from(T) + sage: S.has_coerce_map_from(T) # optional - sage.libs.flint True - sage: S.has_coerce_map_from(R) + sage: S.has_coerce_map_from(R) # optional - sage.libs.flint sage.libs.ntl True - sage: T.has_coerce_map_from(R) + sage: T.has_coerce_map_from(R) # optional - sage.libs.ntl False - sage: T.has_coerce_map_from(S) + sage: T.has_coerce_map_from(S) # optional - sage.libs.flint False """ base_ring = self.base_ring() @@ -843,11 +844,11 @@ def _magma_init_(self, magma): Univariate Polynomial Ring in y over Rational Field sage: S.1 # optional - magma y - sage: magma(PolynomialRing(GF(7), 'x')) # optional - magma + sage: magma(PolynomialRing(GF(7), 'x')) # optional - magma # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over GF(7) - sage: magma(PolynomialRing(GF(49,'a'), 'x')) # optional - magma + sage: magma(PolynomialRing(GF(49,'a'), 'x')) # optional - magma # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over GF(7^2) - sage: magma(PolynomialRing(PolynomialRing(ZZ,'w'), 'x')) # optional - magma + sage: magma(PolynomialRing(PolynomialRing(ZZ,'w'), 'x')) # optional - magma Univariate Polynomial Ring in x over Univariate Polynomial Ring in w over Integer Ring Watch out, Magma has different semantics from Sage, i.e., in Magma @@ -867,9 +868,9 @@ def _magma_init_(self, magma): A nested example over a Givaro finite field:: - sage: k. = GF(9) - sage: R. = k[] - sage: magma(a^2*x^3 + (a+1)*x + a) # optional - magma + sage: k. = GF(9) # optional - sage.rings.finite_rings + sage: R. = k[] # optional - sage.rings.finite_rings + sage: magma(a^2*x^3 + (a+1)*x + a) # optional - magma # optional - sage.rings.finite_rings a^2*x^3 + a^2*x + a """ B = magma(self.base_ring()) @@ -888,23 +889,23 @@ def _gap_init_(self, gap=None): EXAMPLES:: sage: R. = ZZ[] - sage: gap(R) + sage: gap(R) # optional - sage.libs.gap PolynomialRing( Integers, ["z"] ) - sage: gap(R) is gap(R) + sage: gap(R) is gap(R) # optional - sage.libs.gap True - sage: gap(z^2 + z) + sage: gap(z^2 + z) # optional - sage.libs.gap z^2+z A univariate polynomial ring over a multivariate polynomial ring over a number field:: sage: Q. = QQ[] - sage: K. = NumberField(t^2+t+1) - sage: P. = K[] - sage: S. = P[] - sage: gap(S) + sage: K. = NumberField(t^2 + t + 1) # optional - sage.rings.number_field + sage: P. = K[] # optional - sage.rings.number_field + sage: S. = P[] # optional - sage.rings.number_field + sage: gap(S) # optional - sage.libs.gap sage.rings.number_field PolynomialRing( PolynomialRing( , ["x", "y"] ), ["z"] ) - sage: gap(S) is gap(S) + sage: gap(S) is gap(S) # optional - sage.libs.gap sage.rings.number_field True """ if gap is not None: @@ -920,11 +921,11 @@ def _sage_input_(self, sib, coerced): EXAMPLES:: - sage: sage_input(GF(5)['x']['y'], verify=True) + sage: sage_input(GF(5)['x']['y'], verify=True) # optional - sage.rings.finite_rings # Verified GF(5)['x']['y'] - sage: from sage.misc.sage_input import SageInputBuilder - sage: ZZ['z']._sage_input_(SageInputBuilder(), False) + sage: from sage.misc.sage_input import SageInputBuilder # optional - sage.rings.finite_rings + sage: ZZ['z']._sage_input_(SageInputBuilder(), False) # optional - sage.rings.finite_rings {constr_parent: {subscr: {atomic:ZZ}[{atomic:'z'}]} with gens: ('z',)} """ base = sib(self.base_ring()) @@ -963,9 +964,9 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): EXAMPLES:: sage: R. = QQ[] - sage: R._is_valid_homomorphism_(GF(7), [5]) + sage: R._is_valid_homomorphism_(GF(7), [5]) # optional - sage.rings.finite_rings False - sage: R._is_valid_homomorphism_(Qp(7), [5]) + sage: R._is_valid_homomorphism_(Qp(7), [5]) # optional - sage.rings.padics True """ # Since poly rings are free, any image of the gen @@ -1004,7 +1005,7 @@ def _latex_(self): r""" EXAMPLES:: - sage: S.=ZZ[] + sage: S. = ZZ[] sage: latex(S) \Bold{Z}[\alpha_{12}] """ @@ -1012,7 +1013,7 @@ def _latex_(self): def base_extend(self, R): """ - Return the base extension of this polynomial ring to R. + Return the base extension of this polynomial ring to `R`. EXAMPLES:: @@ -1036,13 +1037,14 @@ def base_extend(self, R): def change_ring(self, R): """ - Return the polynomial ring in the same variable as self over R. + Return the polynomial ring in the same variable as ``self`` over `R`. EXAMPLES:: - sage: R. = RealIntervalField() []; R - Univariate Polynomial Ring in ZZZ over Real Interval Field with 53 bits of precision - sage: R.change_ring(GF(19^2,'b')) + sage: R. = RealIntervalField()[]; R + Univariate Polynomial Ring in ZZZ over + Real Interval Field with 53 bits of precision + sage: R.change_ring(GF(19^2, 'b')) # optional - sage.rings.finite_rings Univariate Polynomial Ring in ZZZ over Finite Field in b of size 19^2 """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -1051,7 +1053,7 @@ def change_ring(self, R): def change_var(self, var): r""" - Return the polynomial ring in variable var over the same base + Return the polynomial ring in variable ``var`` over the same base ring. EXAMPLES:: @@ -1067,8 +1069,8 @@ def change_var(self, var): def extend_variables(self, added_names, order = 'degrevlex'): r""" - Returns a multivariate polynomial ring with the same base ring but - with added_names as additional variables. + Return a multivariate polynomial ring with the same base ring but + with ``added_names`` as additional variables. EXAMPLES:: @@ -1142,11 +1144,11 @@ def characteristic(self): EXAMPLES:: - sage: R. = RealIntervalField() []; R + sage: R. = RealIntervalField()[]; R Univariate Polynomial Ring in ZZZ over Real Interval Field with 53 bits of precision sage: R.characteristic() 0 - sage: S = R.change_ring(GF(19^2,'b')); S + sage: S = R.change_ring(GF(19^2, 'b')); S # optional - sage.rings.finite_rings Univariate Polynomial Ring in ZZZ over Finite Field in b of size 19^2 sage: S.characteristic() 19 @@ -1163,23 +1165,23 @@ def cyclotomic_polynomial(self, n): EXAMPLES:: sage: R = ZZ['x'] - sage: R.cyclotomic_polynomial(8) + sage: R.cyclotomic_polynomial(8) # optional - sage.libs.pari x^4 + 1 - sage: R.cyclotomic_polynomial(12) + sage: R.cyclotomic_polynomial(12) # optional - sage.libs.pari x^4 - x^2 + 1 - sage: S = PolynomialRing(FiniteField(7), 'x') - sage: S.cyclotomic_polynomial(12) + sage: S = PolynomialRing(FiniteField(7), 'x') # optional - sage.rings.finite_rings + sage: S.cyclotomic_polynomial(12) # optional - sage.rings.finite_rings x^4 + 6*x^2 + 1 - sage: S.cyclotomic_polynomial(1) + sage: S.cyclotomic_polynomial(1) # optional - sage.rings.finite_rings x + 6 TESTS: Make sure it agrees with other systems for the trivial case:: - sage: ZZ['x'].cyclotomic_polynomial(1) + sage: ZZ['x'].cyclotomic_polynomial(1) # optional - sage.libs.pari x - 1 - sage: gp('polcyclo(1)') + sage: gp('polcyclo(1)') # optional - sage.libs.pari x - 1 """ if n <= 0: @@ -1259,7 +1261,7 @@ def is_field(self, proof = True): def is_sparse(self): """ - Return true if elements of this polynomial ring have a sparse + Return ``True`` if elements of this polynomial ring have a sparse representation. EXAMPLES:: @@ -1307,16 +1309,16 @@ def krull_dimension(self): sage: R. = QQ[] sage: R.krull_dimension() 1 - sage: R. = GF(9,'a')[]; R + sage: R. = GF(9, 'a')[]; R # optional - sage.rings.finite_rings Univariate Polynomial Ring in z over Finite Field in a of size 3^2 - sage: R.krull_dimension() + sage: R.krull_dimension() # optional - sage.rings.finite_rings 1 - sage: S. = R[] - sage: S.krull_dimension() + sage: S. = R[] # optional - sage.rings.finite_rings + sage: S.krull_dimension() # optional - sage.rings.finite_rings 2 - sage: for n in range(10): - ....: S = PolynomialRing(S,'w') - sage: S.krull_dimension() + sage: for n in range(10): # optional - sage.rings.finite_rings + ....: S = PolynomialRing(S, 'w') + sage: S.krull_dimension() # optional - sage.rings.finite_rings 12 """ return self.base_ring().krull_dimension() + 1 @@ -1361,7 +1363,7 @@ def random_element(self, degree=(-1,2), *args, **kwds): sage: R.random_element(6).degree() 6 - If a tuple of two integers is given for the degree argument, a degree + If a tuple of two integers is given for the ``degree`` argument, a degree is first uniformly chosen, then a polynomial of that degree is given:: sage: R.random_element(degree=(0, 8)).degree() in range(0, 9) @@ -1370,10 +1372,10 @@ def random_element(self, degree=(-1,2), *args, **kwds): sage: while not all(found): ....: found[R.random_element(degree=(0, 8)).degree()] = True - Note that the zero polynomial has degree ``-1``, so if you want to - consider it set the minimum degree to ``-1``:: + Note that the zero polynomial has degree `-1`, so if you want to + consider it set the minimum degree to `-1`:: - sage: while R.random_element(degree=(-1,2),x=-1,y=1) != R.zero(): + sage: while R.random_element(degree=(-1,2), x=-1, y=1) != R.zero(): ....: pass TESTS:: @@ -1390,13 +1392,13 @@ def random_element(self, degree=(-1,2), *args, **kwds): Check that :trac:`16682` is fixed:: - sage: R = PolynomialRing(GF(2), 'z') - sage: for _ in range(100): + sage: R = PolynomialRing(GF(2), 'z') # optional - sage.rings.finite_rings + sage: for _ in range(100): # optional - sage.rings.finite_rings ....: d = randint(-1,20) ....: P = R.random_element(degree=d) ....: assert P.degree() == d, "problem with {} which has not degree {}".format(P,d) - sage: R.random_element(degree=-2) + sage: R.random_element(degree=-2) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: degree should be an integer greater or equal than -1 @@ -1494,12 +1496,12 @@ def _Karatsuba_threshold(self): EXAMPLES:: - sage: R. = QQbar[] - sage: R._Karatsuba_threshold + sage: R. = QQbar[] # optional - sage.rings.number_field + sage: R._Karatsuba_threshold # optional - sage.rings.number_field 8 - sage: MS = MatrixSpace(ZZ, 2, 2) - sage: R. = MS[] - sage: R._Karatsuba_threshold + sage: MS = MatrixSpace(ZZ, 2, 2) # optional - sage.modules + sage: R. = MS[] # optional - sage.modules + sage: R._Karatsuba_threshold # optional - sage.modules 0 """ base_ring = self.base_ring() @@ -1517,7 +1519,7 @@ def _Karatsuba_threshold(self): def karatsuba_threshold(self): """ Return the Karatsuba threshold used for this ring by the method - _mul_karatsuba to fall back to the schoolbook algorithm. + :meth:`_mul_karatsuba` to fall back to the schoolbook algorithm. EXAMPLES:: @@ -1532,7 +1534,7 @@ def karatsuba_threshold(self): def set_karatsuba_threshold(self, Karatsuba_threshold): """ - Changes the default threshold for this ring in the method _mul_karatsuba + Changes the default threshold for this ring in the method :meth:`_mul_karatsuba` to fall back to the schoolbook algorithm. .. warning:: @@ -1557,21 +1559,19 @@ def polynomials( self, of_degree = None, max_degree = None ): INPUT: Pass exactly one of: - - ``max_degree`` - an int; the iterator will generate all polynomials which have degree less than or equal to - max_degree + ``max_degree`` - ``of_degree`` - an int; the iterator will generate - all polynomials which have degree of_degree - + all polynomials which have degree ``of_degree`` OUTPUT: an iterator EXAMPLES:: - sage: P = PolynomialRing(GF(3),'y') - sage: for p in P.polynomials( of_degree = 2 ): print(p) + sage: P = PolynomialRing(GF(3), 'y') # optional - sage.rings.finite_rings + sage: for p in P.polynomials(of_degree=2): print(p) # optional - sage.rings.finite_rings y^2 y^2 + 1 y^2 + 2 @@ -1590,7 +1590,7 @@ def polynomials( self, of_degree = None, max_degree = None ): 2*y^2 + 2*y 2*y^2 + 2*y + 1 2*y^2 + 2*y + 2 - sage: for p in P.polynomials( max_degree = 1 ): print(p) + sage: for p in P.polynomials(max_degree=1): print(p) # optional - sage.rings.finite_rings 0 1 2 @@ -1600,7 +1600,7 @@ def polynomials( self, of_degree = None, max_degree = None ): 2*y 2*y + 1 2*y + 2 - sage: for p in P.polynomials( max_degree = 1, of_degree = 3 ): print(p) + sage: for p in P.polynomials(max_degree=1, of_degree=3): print(p) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: you should pass exactly one of of_degree and max_degree @@ -1627,18 +1627,18 @@ def monics( self, of_degree = None, max_degree = None ): - ``max_degree`` - an int; the iterator will generate all monic polynomials which have degree less than or equal to - max_degree + ``max_degree`` - ``of_degree`` - an int; the iterator will generate - all monic polynomials which have degree of_degree + all monic polynomials which have degree ``of_degree`` OUTPUT: an iterator EXAMPLES:: - sage: P = PolynomialRing(GF(4,'a'),'y') - sage: for p in P.monics( of_degree = 2 ): print(p) + sage: P = PolynomialRing(GF(4, 'a'), 'y') # optional - sage.rings.finite_rings + sage: for p in P.monics(of_degree=2): print(p) # optional - sage.rings.finite_rings y^2 y^2 + a y^2 + a + 1 @@ -1655,13 +1655,13 @@ def monics( self, of_degree = None, max_degree = None ): y^2 + y + a y^2 + y + a + 1 y^2 + y + 1 - sage: for p in P.monics( max_degree = 1 ): print(p) + sage: for p in P.monics(max_degree=1): print(p) # optional - sage.rings.finite_rings 1 y y + a y + a + 1 y + 1 - sage: for p in P.monics( max_degree = 1, of_degree = 3 ): print(p) + sage: for p in P.monics(max_degree=1, of_degree=3): print(p) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: you should pass exactly one of of_degree and max_degree @@ -1712,25 +1712,27 @@ def quotient_by_principal_ideal(self, f, names=None, **kwds): EXAMPLES:: sage: R. = QQ[] - sage: I = (x^2-1)*R - sage: R.quotient_by_principal_ideal(I) - Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 - 1 + sage: I = (x^2 - 1) * R + sage: R.quotient_by_principal_ideal(I) # optional - sage.libs.pari + Univariate Quotient Polynomial Ring in xbar + over Rational Field with modulus x^2 - 1 The same example, using the polynomial instead of the ideal, and customizing the variable name:: sage: R. = QQ[] - sage: R.quotient_by_principal_ideal(x^2-1, names=('foo',)) - Univariate Quotient Polynomial Ring in foo over Rational Field with modulus x^2 - 1 + sage: R.quotient_by_principal_ideal(x^2 - 1, names=('foo',)) # optional - sage.libs.pari + Univariate Quotient Polynomial Ring in foo + over Rational Field with modulus x^2 - 1 TESTS: Quotienting by the zero ideal returns ``self`` (:trac:`5978`):: sage: R = QQ['x'] - sage: R.quotient_by_principal_ideal(R.zero_ideal()) is R + sage: R.quotient_by_principal_ideal(R.zero_ideal()) is R # optional - sage.libs.pari True - sage: R.quotient_by_principal_ideal(0) is R + sage: R.quotient_by_principal_ideal(0) is R # optional - sage.libs.pari True """ from sage.rings.ideal import Ideal @@ -1748,9 +1750,9 @@ def weyl_algebra(self): EXAMPLES:: sage: R = QQ['x'] - sage: W = R.weyl_algebra(); W + sage: W = R.weyl_algebra(); W # optional - sage.combinat sage.modules Differential Weyl algebra of polynomials in x over Rational Field - sage: W.polynomial_ring() == R + sage: W.polynomial_ring() == R # optional - sage.combinat sage.modules True """ from sage.algebras.weyl_algebra import DifferentialWeylAlgebra @@ -1813,12 +1815,12 @@ def __init__(self, base_ring, name="x", sparse=False, implementation=None, sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_integral_domain as PRing sage: R = PRing(ZZ, 'x'); R Univariate Polynomial Ring in x over Integer Ring - sage: type(R.gen()) + sage: type(R.gen()) # optional - sage.libs.flint - sage: R = PRing(ZZ, 'x', implementation='NTL'); R + sage: R = PRing(ZZ, 'x', implementation='NTL'); R # optional - sage.libs.ntl Univariate Polynomial Ring in x over Integer Ring (using NTL) - sage: type(R.gen()) + sage: type(R.gen()) # optional - sage.libs.ntl """ self._implementation_repr = '' @@ -1872,77 +1874,80 @@ def weil_polynomials(self, d, q, sign=1, lead=1): - ``sign`` -- integer (default `1`), the sign `s` of the functional equation - ``lead`` -- integer, list of integers or list of pairs of integers (default `1`), - constraints on the leading few coefficients of the generated polynomials. - If pairs `(a, b)` of integers are given, they are treated as a constraint - of the form `\equiv a \pmod{b}`; the moduli must be in decreasing order by - divisibility, and the modulus of the leading coefficient must be 0. + constraints on the leading few coefficients of the generated polynomials. + If pairs `(a, b)` of integers are given, they are treated as a constraint + of the form `\equiv a \pmod{b}`; the moduli must be in decreasing order by + divisibility, and the modulus of the leading coefficient must be 0. .. SEEALSO:: More documentation and additional options are available using the iterator :class:`sage.rings.polynomial.weil.weil_polynomials.WeilPolynomials` - directly. In addition, polynomials have a method `is_weil_polynomial` to + directly. In addition, polynomials have a method :meth:`is_weil_polynomial` to test whether or not the given polynomial is a Weil polynomial. EXAMPLES:: sage: R. = ZZ[] - sage: L = R.weil_polynomials(4, 2) - sage: len(L) + sage: L = R.weil_polynomials(4, 2) # optional - sage.libs.flint + sage: len(L) # optional - sage.libs.flint 35 - sage: L[9] + sage: L[9] # optional - sage.libs.flint T^4 + T^3 + 2*T^2 + 2*T + 4 - sage: all(p.is_weil_polynomial() for p in L) + sage: all(p.is_weil_polynomial() for p in L) # optional - sage.libs.flint True Setting multiple leading coefficients:: sage: R. = QQ[] - sage: l = R.weil_polynomials(4,2,lead=((1,0),(2,4),(1,2))) - sage: l + sage: l = R.weil_polynomials(4, 2, lead=((1,0), (2,4), (1,2))) # optional - sage.libs.flint + sage: l # optional - sage.libs.flint [T^4 + 2*T^3 + 5*T^2 + 4*T + 4, - T^4 + 2*T^3 + 3*T^2 + 4*T + 4, - T^4 - 2*T^3 + 5*T^2 - 4*T + 4, - T^4 - 2*T^3 + 3*T^2 - 4*T + 4] + T^4 + 2*T^3 + 3*T^2 + 4*T + 4, + T^4 - 2*T^3 + 5*T^2 - 4*T + 4, + T^4 - 2*T^3 + 3*T^2 - 4*T + 4] We do not require Weil polynomials to be monic. This example generates Weil - polynomials associated to K3 surfaces over `GF(2)` of Picard number at least 12:: + polynomials associated to K3 surfaces over `\GF{2}` of Picard number at least 12:: sage: R. = QQ[] - sage: l = R.weil_polynomials(10,1,lead=2) - sage: len(l) + sage: l = R.weil_polynomials(10, 1, lead=2) # optional - sage.libs.flint + sage: len(l) # optional - sage.libs.flint 4865 - sage: l[len(l)//2] + sage: l[len(l)//2] # optional - sage.libs.flint 2*T^10 + T^8 + T^6 + T^4 + T^2 + 2 TESTS: We check that products of Weil polynomials are also listed as Weil polynomials:: - sage: all((f * g) in R.weil_polynomials(6, q) for q in [3,4] for f in R.weil_polynomials(2, q) for g in R.weil_polynomials(4, q)) + sage: all((f * g) in R.weil_polynomials(6, q) for q in [3, 4] # optional - sage.libs.flint + ....: for f in R.weil_polynomials(2, q) for g in R.weil_polynomials(4, q)) True We check that irreducible Weil polynomials of degree 6 are CM:: - sage: simples = [f for f in R.weil_polynomials(6, 3) if f.is_irreducible()] - sage: len(simples) + sage: simples = [f for f in R.weil_polynomials(6, 3) if f.is_irreducible()] # optional - sage.libs.flint + sage: len(simples) # optional - sage.libs.flint 348 - sage: reals = [R([f[3+i] + sum((-3)^j * (i+2*j)/(i+j) * binomial(i+j,j) * f[3+i+2*j] for j in range(1,(3+i)//2+1)) for i in range(4)]) for f in simples] + sage: reals = [R([f[3+i] + sum((-3)^j * (i+2*j)/(i+j) * binomial(i+j,j) * f[3+i+2*j] # optional - sage.libs.flint + ....: for j in range(1, (3+i)//2 + 1)) + ....: for i in range(4)]) for f in simples] Check that every polynomial in this list has 3 real roots between `-2 \sqrt{3}` and `2 \sqrt{3}`:: - sage: roots = [f.roots(RR, multiplicities=False) for f in reals] - sage: all(len(L) == 3 and all(x^2 <= 12 for x in L) for L in roots) + sage: roots = [f.roots(RR, multiplicities=False) for f in reals] # optional - sage.libs.flint + sage: all(len(L) == 3 and all(x^2 <= 12 for x in L) for L in roots) # optional - sage.libs.flint True Finally, check that the original polynomials are reconstructed as CM polynomials:: - sage: all(f == T^3*r(T + 3/T) for (f, r) in zip(simples, reals)) + sage: all(f == T^3*r(T + 3/T) for (f, r) in zip(simples, reals)) # optional - sage.libs.flint True A simple check (not sufficient):: - sage: all(f.number_of_real_roots() == 0 for f in simples) + sage: all(f.number_of_real_roots() == 0 for f in simples) # optional - sage.libs.flint True """ R = self.base_ring() @@ -1981,7 +1986,7 @@ def _repr_(self): TESTS:: sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_integral_domain as PRing - sage: R = PRing(ZZ, 'x', implementation='NTL'); R + sage: R = PRing(ZZ, 'x', implementation='NTL'); R # optional - sage.libs.ntl Univariate Polynomial Ring in x over Integer Ring (using NTL) """ s = PolynomialRing_commutative._repr_(self) @@ -2001,11 +2006,11 @@ def construction(self): sage: functor.implementation is None True - sage: R = PRing(ZZ, 'x', implementation='NTL'); R + sage: R = PRing(ZZ, 'x', implementation='NTL'); R # optional - sage.libs.ntl Univariate Polynomial Ring in x over Integer Ring (using NTL) - sage: functor, arg = R.construction(); functor, arg + sage: functor, arg = R.construction(); functor, arg # optional - sage.libs.ntl (Poly[x], Integer Ring) - sage: functor.implementation + sage: functor.implementation # optional - sage.libs.ntl 'NTL' """ implementation = None @@ -2030,7 +2035,7 @@ def __init__(self, base_ring, name="x", sparse=False, implementation=None, sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_field as PRing sage: R = PRing(QQ, 'x'); R Univariate Polynomial Ring in x over Rational Field - sage: type(R.gen()) + sage: type(R.gen()) # optional - sage.libs.flint sage: R = PRing(QQ, 'x', sparse=True); R Sparse Univariate Polynomial Ring in x over Rational Field @@ -2043,7 +2048,7 @@ def __init__(self, base_ring, name="x", sparse=False, implementation=None, Demonstrate that :trac:`8762` is fixed:: - sage: R. = PolynomialRing(GF(next_prime(10^20)), sparse=True) + sage: R. = PolynomialRing(GF(next_prime(10^20)), sparse=True) # optional - sage.rings.finite_rings sage: x^(10^20) # this should be fast x^100000000000000000000 """ @@ -2090,8 +2095,8 @@ def _ideal_class_(self, n=0): EXAMPLES:: - sage: R. = GF(5)[] - sage: R._ideal_class_() + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: R._ideal_class_() # optional - sage.rings.finite_rings """ from sage.rings.polynomial.ideal import Ideal_1poly_field @@ -2107,7 +2112,7 @@ def divided_difference(self, points, full_table=False): - ``points`` -- a list of pairs `(x_0, y_0), (x_1, y_1), \dots, (x_n, y_n)` of elements of the base ring of ``self``, where `x_i - x_j` is invertible for `i \neq j`. This method - converts the `x_i` and `y_i` into the base ring of `self`. + converts the `x_i` and `y_i` into the base ring of ``self``. - ``full_table`` -- boolean (default: ``False``): If ``True``, return the full divided-difference table. If ``False``, @@ -2119,7 +2124,7 @@ def divided_difference(self, points, full_table=False): The Newton divided-difference coefficients of the `n`-th Lagrange interpolation polynomial `P_n(x)` that passes through the points in ``points`` (see :meth:`lagrange_polynomial`). - These are the coefficients `F_{0,0}, F_{1,1}, \dots, `F_{n,n}` + These are the coefficients `F_{0,0}, F_{1,1}, \dots, F_{n,n}` in the base ring of ``self`` such that .. MATH:: @@ -2131,32 +2136,29 @@ def divided_difference(self, points, full_table=False): Only return the divided-difference coefficients `F_{i,i}`. This example is taken from Example 1, page 121 of [BF2005]_:: - sage: points = [(1.0, 0.7651977), (1.3, 0.6200860), (1.6, 0.4554022), (1.9, 0.2818186), (2.2, 0.1103623)] + sage: points = [(1.0, 0.7651977), (1.3, 0.6200860), (1.6, 0.4554022), + ....: (1.9, 0.2818186), (2.2, 0.1103623)] sage: R = PolynomialRing(RR, "x") sage: R.divided_difference(points) [0.765197700000000, - -0.483705666666666, - -0.108733888888889, - 0.0658783950617283, - 0.00182510288066044] + -0.483705666666666, + -0.108733888888889, + 0.0658783950617283, + 0.00182510288066044] Now return the full divided-difference table:: - sage: points = [(1.0, 0.7651977), (1.3, 0.6200860), (1.6, 0.4554022), (1.9, 0.2818186), (2.2, 0.1103623)] + sage: points = [(1.0, 0.7651977), (1.3, 0.6200860), (1.6, 0.4554022), + ....: (1.9, 0.2818186), (2.2, 0.1103623)] sage: R = PolynomialRing(RR, "x") sage: R.divided_difference(points, full_table=True) [[0.765197700000000], - [0.620086000000000, -0.483705666666666], - [0.455402200000000, -0.548946000000000, -0.108733888888889], - [0.281818600000000, - -0.578612000000000, - -0.0494433333333339, - 0.0658783950617283], - [0.110362300000000, - -0.571520999999999, - 0.0118183333333349, - 0.0680685185185209, - 0.00182510288066044]] + [0.620086000000000, -0.483705666666666], + [0.455402200000000, -0.548946000000000, -0.108733888888889], + [0.281818600000000, -0.578612000000000, + -0.0494433333333339, 0.0658783950617283], + [0.110362300000000, -0.571520999999999, 0.0118183333333349, + 0.0680685185185209, 0.00182510288066044]] The following example is taken from Example 4.12, page 225 of [MF1999]_:: @@ -2167,11 +2169,11 @@ def divided_difference(self, points, full_table=False): [-3, 3, 6, 1, 0, 0] sage: R.divided_difference(points, full_table=True) [[-3], - [0, 3], - [15, 15, 6], - [48, 33, 9, 1], - [105, 57, 12, 1, 0], - [192, 87, 15, 1, 0, 0]] + [0, 3], + [15, 15, 6], + [48, 33, 9, 1], + [105, 57, 12, 1, 0], + [192, 87, 15, 1, 0, 0]] """ to_base_ring = self.base_ring() points = [tuple(to_base_ring(c) for c in p) for p in points] @@ -2197,7 +2199,7 @@ def lagrange_polynomial(self, points, algorithm="divided_difference", previous_r - ``points`` -- a list of pairs `(x_0, y_0), (x_1, y_1), \dots, (x_n, y_n)` of elements of the base ring of ``self``, where `x_i - x_j` is invertible for `i \neq j`. This method - converts the `x_i` and `y_i` into the base ring of `self`. + converts the `x_i` and `y_i` into the base ring of ``self``. - ``algorithm`` -- (default: ``'divided_difference'``): one of the following: @@ -2205,7 +2207,7 @@ def lagrange_polynomial(self, points, algorithm="divided_difference", previous_r - ``'divided_difference'``: use the method of divided differences. - - ``algorithm='neville'``: adapt Neville's method as + - ``'neville'``: adapt Neville's method as described on page 144 of [BF2005]_ to recursively generate the Lagrange interpolation polynomial. Neville's method generates a table of approximating polynomials, where the @@ -2236,7 +2238,7 @@ def lagrange_polynomial(self, points, algorithm="divided_difference", previous_r By default, we use the method of divided differences:: sage: R = PolynomialRing(QQ, 'x') - sage: f = R.lagrange_polynomial([(0,1),(2,2),(3,-2),(-4,9)]); f + sage: f = R.lagrange_polynomial([(0,1), (2,2), (3,-2), (-4,9)]); f -23/84*x^3 - 11/84*x^2 + 13/7*x + 1 sage: f(0) 1 @@ -2246,41 +2248,45 @@ def lagrange_polynomial(self, points, algorithm="divided_difference", previous_r -2 sage: f(-4) 9 - sage: R = PolynomialRing(GF(2**3,'a'), 'x') - sage: a = R.base_ring().gen() - sage: f = R.lagrange_polynomial([(a^2+a,a),(a,1),(a^2,a^2+a+1)]); f + sage: R = PolynomialRing(GF(2**3, 'a'), 'x') # optional - sage.rings.finite_rings + sage: a = R.base_ring().gen() # optional - sage.rings.finite_rings + sage: f = R.lagrange_polynomial([(a^2+a, a), (a, 1), (a^2, a^2+a+1)]); f # optional - sage.rings.finite_rings a^2*x^2 + a^2*x + a^2 - sage: f(a^2+a) + sage: f(a^2 + a) # optional - sage.rings.finite_rings a - sage: f(a) + sage: f(a) # optional - sage.rings.finite_rings 1 - sage: f(a^2) + sage: f(a^2) # optional - sage.rings.finite_rings a^2 + a + 1 Now use a memory efficient version of Neville's method:: sage: R = PolynomialRing(QQ, 'x') - sage: R.lagrange_polynomial([(0,1),(2,2),(3,-2),(-4,9)], algorithm="neville") + sage: R.lagrange_polynomial([(0,1), (2,2), (3,-2), (-4,9)], + ....: algorithm="neville") [9, -11/7*x + 19/7, -17/42*x^2 - 83/42*x + 53/7, -23/84*x^3 - 11/84*x^2 + 13/7*x + 1] - sage: R = PolynomialRing(GF(2**3,'a'), 'x') - sage: a = R.base_ring().gen() - sage: R.lagrange_polynomial([(a^2+a,a),(a,1),(a^2,a^2+a+1)], algorithm="neville") + sage: R = PolynomialRing(GF(2**3, 'a'), 'x') # optional - sage.rings.finite_rings + sage: a = R.base_ring().gen() # optional - sage.rings.finite_rings + sage: R.lagrange_polynomial([(a^2+a, a), (a, 1), (a^2, a^2+a+1)], # optional - sage.rings.finite_rings + ....: algorithm="neville") [a^2 + a + 1, x + a + 1, a^2*x^2 + a^2*x + a^2] Repeated use of Neville's method to get better Lagrange interpolation polynomials:: sage: R = PolynomialRing(QQ, 'x') - sage: p = R.lagrange_polynomial([(0,1),(2,2)], algorithm="neville") - sage: R.lagrange_polynomial([(0,1),(2,2),(3,-2),(-4,9)], algorithm="neville", previous_row=p)[-1] + sage: p = R.lagrange_polynomial([(0,1), (2,2)], algorithm="neville") + sage: R.lagrange_polynomial([(0,1), (2,2), (3,-2), (-4,9)], + ....: algorithm="neville", previous_row=p)[-1] -23/84*x^3 - 11/84*x^2 + 13/7*x + 1 - sage: R = PolynomialRing(GF(2**3,'a'), 'x') - sage: a = R.base_ring().gen() - sage: p = R.lagrange_polynomial([(a^2+a,a),(a,1)], algorithm="neville") - sage: R.lagrange_polynomial([(a^2+a,a),(a,1),(a^2,a^2+a+1)], algorithm="neville", previous_row=p)[-1] + sage: R = PolynomialRing(GF(2**3, 'a'), 'x') # optional - sage.rings.finite_rings + sage: a = R.base_ring().gen() # optional - sage.rings.finite_rings + sage: p = R.lagrange_polynomial([(a^2+a, a), (a, 1)], algorithm="neville") # optional - sage.rings.finite_rings + sage: R.lagrange_polynomial([(a^2+a, a), (a, 1), (a^2, a^2+a+1)], # optional - sage.rings.finite_rings + ....: algorithm="neville", previous_row=p)[-1] a^2*x^2 + a^2*x + a^2 TESTS: @@ -2322,10 +2328,10 @@ def lagrange_polynomial(self, points, algorithm="divided_difference", previous_r Check that base fields of positive characteristic are treated correctly (see :trac:`9787`):: - sage: R. = GF(101)[] - sage: R.lagrange_polynomial([[1, 0], [2, 0]]) + sage: R. = GF(101)[] # optional - sage.rings.finite_rings + sage: R.lagrange_polynomial([[1, 0], [2, 0]]) # optional - sage.rings.finite_rings 0 - sage: R.lagrange_polynomial([[1, 0], [2, 0], [3, 0]]) + sage: R.lagrange_polynomial([[1, 0], [2, 0], [3, 0]]) # optional - sage.rings.finite_rings 0 """ # Perhaps we should be slightly stricter on the input and use @@ -2411,24 +2417,25 @@ def fraction_field(self): EXAMPLES:: - sage: R. = GF(5)[] - sage: R.fraction_field() - Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: R.fraction_field() # optional - sage.rings.finite_rings + Fraction Field of Univariate Polynomial Ring in t + over Finite Field of size 5 TESTS: Check that :trac:`25449` has been resolved:: - sage: k = GF(25453) - sage: F. = FunctionField(k) - sage: R. = k[] - sage: t(x) + sage: k = GF(25453) # optional - sage.rings.finite_rings + sage: F. = FunctionField(k) # optional - sage.rings.finite_rings + sage: R. = k[] # optional - sage.rings.finite_rings + sage: t(x) # optional - sage.rings.finite_rings x - sage: k = GF(55667) - sage: F. = FunctionField(k) - sage: R. = k[] - sage: t(x) + sage: k = GF(55667) # optional - sage.rings.finite_rings + sage: F. = FunctionField(k) # optional - sage.rings.finite_rings + sage: R. = k[] # optional - sage.rings.finite_rings + sage: t(x) # optional - sage.rings.finite_rings x """ @@ -2448,24 +2455,24 @@ class PolynomialRing_dense_finite_field(PolynomialRing_field): EXAMPLES:: - sage: R = PolynomialRing(GF(27, 'a'), 'x') - sage: type(R) + sage: R = PolynomialRing(GF(27, 'a'), 'x') # optional - sage.rings.finite_rings + sage: type(R) # optional - sage.rings.finite_rings """ def __init__(self, base_ring, name="x", element_class=None, implementation=None): """ TESTS:: - sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_finite_field - sage: R = PolynomialRing_dense_finite_field(GF(5), implementation='generic') - sage: type(R(0)) + sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_finite_field # optional - sage.rings.finite_rings + sage: R = PolynomialRing_dense_finite_field(GF(5), implementation='generic') # optional - sage.rings.finite_rings + sage: type(R(0)) # optional - sage.rings.finite_rings - sage: S = PolynomialRing_dense_finite_field(GF(25, 'a'), implementation='NTL') - sage: type(S(0)) + sage: S = PolynomialRing_dense_finite_field(GF(25, 'a'), implementation='NTL') # optional - sage.rings.finite_rings + sage: type(S(0)) # optional - sage.rings.finite_rings - sage: S = PolynomialRing_dense_finite_field(GF(64), implementation='superfast') + sage: S = PolynomialRing_dense_finite_field(GF(64), implementation='superfast') # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: unknown implementation 'superfast' for dense polynomial rings over Finite Field in z6 of size 2^6 @@ -2494,16 +2501,16 @@ def _implementation_names_impl(implementation, base_ring, sparse): """ TESTS:: - sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_finite_field - sage: PolynomialRing_dense_finite_field._implementation_names_impl("NTL", GF(4), False) + sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_finite_field # optional - sage.rings.finite_rings + sage: PolynomialRing_dense_finite_field._implementation_names_impl("NTL", GF(4), False) # optional - sage.rings.finite_rings ['NTL', None] - sage: PolynomialRing_dense_finite_field._implementation_names_impl(None, GF(4), False) + sage: PolynomialRing_dense_finite_field._implementation_names_impl(None, GF(4), False) # optional - sage.rings.finite_rings ['NTL', None] - sage: PolynomialRing_dense_finite_field._implementation_names_impl("generic", GF(4), False) + sage: PolynomialRing_dense_finite_field._implementation_names_impl("generic", GF(4), False) # optional - sage.rings.finite_rings ['generic'] - sage: PolynomialRing_dense_finite_field._implementation_names_impl("FLINT", GF(4), False) + sage: PolynomialRing_dense_finite_field._implementation_names_impl("FLINT", GF(4), False) # optional - sage.rings.finite_rings NotImplemented - sage: PolynomialRing_dense_finite_field._implementation_names_impl(None, GF(4), True) + sage: PolynomialRing_dense_finite_field._implementation_names_impl(None, GF(4), True) # optional - sage.rings.finite_rings NotImplemented """ if sparse: @@ -2538,14 +2545,16 @@ def irreducible_element(self, n, algorithm=None): EXAMPLES:: - sage: f = GF(5^3, 'a')['x'].irreducible_element(2) - sage: f.degree() + sage: f = GF(5^3, 'a')['x'].irreducible_element(2) # optional - sage.rings.finite_rings + sage: f.degree() # optional - sage.rings.finite_rings 2 - sage: f.is_irreducible() + sage: f.is_irreducible() # optional - sage.rings.finite_rings True - sage: GF(19)['x'].irreducible_element(21, algorithm="first_lexicographic") + sage: R = GF(19)['x'] # optional - sage.rings.finite_rings + sage: R.irreducible_element(21, algorithm="first_lexicographic") # optional - sage.rings.finite_rings x^21 + x + 5 - sage: GF(5**2, 'a')['x'].irreducible_element(17, algorithm="first_lexicographic") + sage: R = GF(5**2, 'a')['x'] # optional - sage.rings.finite_rings + sage: R.irreducible_element(17, algorithm="first_lexicographic") # optional - sage.rings.finite_rings x^17 + a*x + 4*a + 3 AUTHORS: @@ -2606,15 +2615,15 @@ def _roth_ruckenstein(self, p, degree_bound, precision): EXAMPLES:: - sage: F = GF(17) - sage: Px. = F[] - sage: Pxy. = Px[] - sage: p = (y - (x**2 + x + 1)) * (y**2 - x + 1) * (y - (x**3 + 4*x + 16)) - sage: Px._roth_ruckenstein(p, 3, None) + sage: F = GF(17) # optional - sage.rings.finite_rings + sage: Px. = F[] # optional - sage.rings.finite_rings + sage: Pxy. = Px[] # optional - sage.rings.finite_rings + sage: p = (y - (x**2 + x + 1)) * (y**2 - x + 1) * (y - (x**3 + 4*x + 16)) # optional - sage.rings.finite_rings + sage: Px._roth_ruckenstein(p, 3, None) # optional - sage.rings.finite_rings [x^3 + 4*x + 16, x^2 + x + 1] - sage: Px._roth_ruckenstein(p, 2, None) + sage: Px._roth_ruckenstein(p, 2, None) # optional - sage.rings.finite_rings [x^2 + x + 1] - sage: Px._roth_ruckenstein(p, 1, 2) + sage: Px._roth_ruckenstein(p, 1, 2) # optional - sage.rings.finite_rings [(4*x + 16, 2), (2*x + 13, 2), (15*x + 4, 2), (x + 1, 2)] """ def roth_rec(p, lam, k, g): @@ -2705,28 +2714,29 @@ def _alekhnovich(self, p, degree_bound, precision=None, dc_threshold=None): EXAMPLES:: - sage: R. = GF(17)[] - sage: S. = R[] - sage: p = (y - 2*x^2 - 3*x - 14) * (y - 3*x + 2) * (y - 1) - sage: R._alekhnovich(p, 2) + sage: R. = GF(17)[] # optional - sage.rings.finite_rings + sage: S. = R[] # optional - sage.rings.finite_rings + sage: p = (y - 2*x^2 - 3*x - 14) * (y - 3*x + 2) * (y - 1) # optional - sage.rings.finite_rings + sage: R._alekhnovich(p, 2) # optional - sage.rings.finite_rings [3*x + 15, 2*x^2 + 3*x + 14, 1] - sage: R._alekhnovich(p, 1) + sage: R._alekhnovich(p, 1) # optional - sage.rings.finite_rings [3*x + 15, 1] - sage: R._alekhnovich(p, 1, precision = 2) + sage: R._alekhnovich(p, 1, precision=2) # optional - sage.rings.finite_rings [(3*x + 15, 2), (3*x + 14, 2), (1, 2)] Example of benchmark to check that `dc_threshold = None` is better:: - sage: p = prod(y - R.random_element(20) for _ in range(10)) * S.random_element(10,10) # not tested - sage: %timeit _alekhnovich(R, p, 20, dc_threshold = None) # not tested + sage: p = prod(y - R.random_element(20) # not tested # optional - sage.rings.finite_rings + ....: for _ in range(10)) * S.random_element(10,10) + sage: %timeit _alekhnovich(R, p, 20, dc_threshold = None) # not tested # optional - sage.rings.finite_rings 1 loop, best of 3: 418 ms per loop - sage: %timeit _alekhnovich(R, p, 20, dc_threshold = 1) # not tested + sage: %timeit _alekhnovich(R, p, 20, dc_threshold = 1) # not tested # optional - sage.rings.finite_rings 1 loop, best of 3: 416 ms per loop - sage: %timeit _alekhnovich(R, p, 20, dc_threshold = 2) # not tested + sage: %timeit _alekhnovich(R, p, 20, dc_threshold = 2) # not tested # optional - sage.rings.finite_rings 1 loop, best of 3: 418 ms per loop - sage: %timeit _alekhnovich(R, p, 20, dc_threshold = 3) # not tested + sage: %timeit _alekhnovich(R, p, 20, dc_threshold = 3) # not tested # optional - sage.rings.finite_rings 1 loop, best of 3: 454 ms per loop - sage: %timeit _alekhnovich(R, p, 20, dc_threshold = 4) # not tested + sage: %timeit _alekhnovich(R, p, 20, dc_threshold = 4) # not tested # optional - sage.rings.finite_rings 1 loop, best of 3: 519 ms per loop AUTHORS: @@ -2816,24 +2826,24 @@ def _roots_univariate_polynomial(self, p, ring=None, multiplicities=False, algor EXAMPLES:: - sage: R. = GF(13)[] - sage: S. = R[] - sage: p = y^2 + (12*x^2 + x + 11)*y + x^3 + 12*x^2 + 12*x + 1 - sage: p.roots(multiplicities=False) + sage: R. = GF(13)[] # optional - sage.rings.finite_rings + sage: S. = R[] # optional - sage.rings.finite_rings + sage: p = y^2 + (12*x^2 + x + 11)*y + x^3 + 12*x^2 + 12*x + 1 # optional - sage.rings.finite_rings + sage: p.roots(multiplicities=False) # optional - sage.rings.finite_rings [x^2 + 11*x + 1, x + 1] - sage: p.roots(multiplicities=False, degree_bound=1) + sage: p.roots(multiplicities=False, degree_bound=1) # optional - sage.rings.finite_rings [x + 1] - sage: p.roots(multiplicities=False, algorithm="Roth-Ruckenstein") + sage: p.roots(multiplicities=False, algorithm="Roth-Ruckenstein") # optional - sage.rings.finite_rings [x^2 + 11*x + 1, x + 1] TESTS: Check that :trac:`23639` is fixed:: - sage: R = GF(3)['x']['y'] - sage: R.one().roots(multiplicities=False) + sage: R = GF(3)['x']['y'] # optional - sage.rings.finite_rings + sage: R.one().roots(multiplicities=False) # optional - sage.rings.finite_rings [] - sage: R.zero().roots(multiplicities=False) + sage: R.zero().roots(multiplicities=False) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ArithmeticError: roots of 0 are not defined @@ -2878,7 +2888,7 @@ def __init__(self, base_ring, name=None, sparse=False, implementation=None, sage: isinstance(S, PolynomialRing_cdvr) False - sage: S. = Zp(5)[] + sage: S. = Zp(5)[] # optional - sage.rings.padics sage: isinstance(S, PolynomialRing_cdvr) True """ @@ -2909,8 +2919,8 @@ def __init__(self, base_ring, name=None, sparse=False, implementation=None, sage: isinstance(S, PolynomialRing_cdvf) False - sage: S. = Qp(5)[] - sage: isinstance(S, PolynomialRing_cdvf) + sage: S. = Qp(5)[] # optional - sage.rings.padics + sage: isinstance(S, PolynomialRing_cdvf) # optional - sage.rings.padics True """ if element_class is None: @@ -2927,7 +2937,7 @@ def __init__(self, base_ring, name=None, sparse=False, implementation=None, class PolynomialRing_dense_padic_ring_generic(PolynomialRing_cdvr): r""" - A class for dense polynomial ring over padic rings + A class for dense polynomial ring over p-adic rings """ def __init__(self, base_ring, name=None, implementation=None, element_class=None, category=None): PolynomialRing_cdvr.__init__(self, base_ring, sparse=False, name=name, @@ -2942,11 +2952,11 @@ def _implementation_names_impl(implementation, base_ring, sparse): TESTS:: sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_padic_ring_generic - sage: PolynomialRing_dense_padic_ring_generic._implementation_names_impl(None, Zp(2), False) + sage: PolynomialRing_dense_padic_ring_generic._implementation_names_impl(None, Zp(2), False) # optional - sage.rings.padics [None] - sage: PolynomialRing_dense_padic_ring_generic._implementation_names_impl(None, Zp(2), True) + sage: PolynomialRing_dense_padic_ring_generic._implementation_names_impl(None, Zp(2), True) # optional - sage.rings.padics NotImplemented - sage: PolynomialRing_dense_padic_ring_generic._implementation_names_impl("generic", Zp(2), False) + sage: PolynomialRing_dense_padic_ring_generic._implementation_names_impl("generic", Zp(2), False) # optional - sage.rings.padics NotImplemented """ if implementation is None and not sparse: @@ -2956,7 +2966,7 @@ def _implementation_names_impl(implementation, base_ring, sparse): class PolynomialRing_dense_padic_field_generic(PolynomialRing_cdvf): r""" - A class for dense polynomial ring over padic fields + A class for dense polynomial ring over p-adic fields """ def __init__(self, base_ring, name=None, implementation=None, element_class=None, category=None): PolynomialRing_cdvf.__init__(self, base_ring, sparse=False, name=name, @@ -2971,11 +2981,11 @@ def _implementation_names_impl(implementation, base_ring, sparse): TESTS:: sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_padic_field_generic - sage: PolynomialRing_dense_padic_field_generic._implementation_names_impl(None, Qp(2), False) + sage: PolynomialRing_dense_padic_field_generic._implementation_names_impl(None, Qp(2), False) # optional - sage.rings.padics [None] - sage: PolynomialRing_dense_padic_field_generic._implementation_names_impl(None, Qp(2), True) + sage: PolynomialRing_dense_padic_field_generic._implementation_names_impl(None, Qp(2), True) # optional - sage.rings.padics NotImplemented - sage: PolynomialRing_dense_padic_field_generic._implementation_names_impl("generic", Qp(2), False) + sage: PolynomialRing_dense_padic_field_generic._implementation_names_impl("generic", Qp(2), False) # optional - sage.rings.padics NotImplemented """ if implementation is None and not sparse: @@ -2989,9 +2999,9 @@ def __init__(self, base_ring, name=None, implementation=None, element_class=None TESTS:: sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_padic_ring_capped_relative as PRing - sage: R = PRing(Zp(13), name='t'); R + sage: R = PRing(Zp(13), name='t'); R # optional - sage.rings.padics Univariate Polynomial Ring in t over 13-adic Ring with capped relative precision 20 - sage: type(R.gen()) + sage: type(R.gen()) # optional - sage.rings.padics """ if element_class is None: @@ -3010,9 +3020,9 @@ def __init__(self, base_ring, name=None, implementation=None, element_class=None TESTS:: sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_padic_ring_capped_absolute as PRing - sage: R = PRing(Zp(13, type='capped-abs'), name='t'); R + sage: R = PRing(Zp(13, type='capped-abs'), name='t'); R # optional - sage.rings.padics Univariate Polynomial Ring in t over 13-adic Ring with capped absolute precision 20 - sage: type(R.gen()) + sage: type(R.gen()) # optional - sage.rings.padics """ if element_class is None: @@ -3030,10 +3040,10 @@ def __init__(self, base_ring, name=None, implementation=None, element_class=None TESTS:: sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_padic_ring_fixed_mod as PRing - sage: R = PRing(Zp(13, type='fixed-mod'), name='t'); R + sage: R = PRing(Zp(13, type='fixed-mod'), name='t'); R # optional - sage.rings.padics Univariate Polynomial Ring in t over 13-adic Ring of fixed modulus 13^20 - sage: type(R.gen()) + sage: type(R.gen()) # optional - sage.rings.padics """ if element_class is None: @@ -3051,9 +3061,9 @@ def __init__(self, base_ring, name=None, implementation=None, element_class=None TESTS:: sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_padic_field_capped_relative as PRing - sage: R = PRing(Qp(13), name='t'); R + sage: R = PRing(Qp(13), name='t'); R # optional - sage.rings.padics Univariate Polynomial Ring in t over 13-adic Field with capped relative precision 20 - sage: type(R.gen()) + sage: type(R.gen()) # optional - sage.rings.padics """ if element_class is None: @@ -3075,27 +3085,27 @@ def __init__(self, base_ring, name=None, element_class=None, sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_mod_n as PRing sage: R = PRing(Zmod(15), 'x'); R Univariate Polynomial Ring in x over Ring of integers modulo 15 - sage: type(R.gen()) + sage: type(R.gen()) # optional - sage.libs.flint - sage: R = PRing(Zmod(15), 'x', implementation='NTL'); R + sage: R = PRing(Zmod(15), 'x', implementation='NTL'); R # optional - sage.libs.ntl Univariate Polynomial Ring in x over Ring of integers modulo 15 (using NTL) - sage: type(R.gen()) + sage: type(R.gen()) # optional - sage.libs.ntl - sage: R = PRing(Zmod(2**63*3), 'x', implementation='NTL'); R + sage: R = PRing(Zmod(2**63*3), 'x', implementation='NTL'); R # optional - sage.libs.ntl Univariate Polynomial Ring in x over Ring of integers modulo 27670116110564327424 (using NTL) - sage: type(R.gen()) + sage: type(R.gen()) # optional - sage.libs.ntl - sage: R = PRing(Zmod(2**63*3), 'x', implementation='FLINT') + sage: R = PRing(Zmod(2**63*3), 'x', implementation='FLINT') # optional - sage.libs.flint Traceback (most recent call last): ... ValueError: FLINT does not support modulus 27670116110564327424 - sage: R = PRing(Zmod(2**63*3), 'x'); R + sage: R = PRing(Zmod(2**63*3), 'x'); R # optional - sage.libs.ntl Univariate Polynomial Ring in x over Ring of integers modulo 27670116110564327424 (using NTL) - sage: type(R.gen()) + sage: type(R.gen()) # optional - sage.libs.ntl """ if element_class is None: @@ -3186,7 +3196,7 @@ def _repr_(self): TESTS:: sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_integral_domain as PRing - sage: R = PRing(ZZ, 'x', implementation='NTL'); R + sage: R = PRing(ZZ, 'x', implementation='NTL'); R # optional - sage.libs.ntl Univariate Polynomial Ring in x over Integer Ring (using NTL) """ s = PolynomialRing_commutative._repr_(self) @@ -3198,32 +3208,38 @@ def residue_field(self, ideal, names=None): EXAMPLES:: - sage: R. = GF(2)[] - sage: k. = R.residue_field(t^3+t+1); k - Residue field in a of Principal ideal (t^3 + t + 1) of Univariate Polynomial Ring in t over Finite Field of size 2 (using GF2X) - sage: k.list() + sage: R. = GF(2)[] # optional - sage.rings.finite_rings + sage: k. = R.residue_field(t^3 + t + 1); k # optional - sage.rings.finite_rings + Residue field in a + of Principal ideal (t^3 + t + 1) of Univariate Polynomial Ring in t + over Finite Field of size 2 (using GF2X) + sage: k.list() # optional - sage.rings.finite_rings [0, a, a^2, a + 1, a^2 + a, a^2 + a + 1, a^2 + 1, 1] - sage: R.residue_field(t) - Residue field of Principal ideal (t) of Univariate Polynomial Ring in t over Finite Field of size 2 (using GF2X) - sage: P = R.irreducible_element(8) * R - sage: P - Principal ideal (t^8 + t^4 + t^3 + t^2 + 1) of Univariate Polynomial Ring in t over Finite Field of size 2 (using GF2X) - sage: k. = R.residue_field(P); k - Residue field in a of Principal ideal (t^8 + t^4 + t^3 + t^2 + 1) of Univariate Polynomial Ring in t over Finite Field of size 2 (using GF2X) - sage: k.cardinality() + sage: R.residue_field(t) # optional - sage.rings.finite_rings + Residue field of Principal ideal (t) of Univariate Polynomial Ring in t + over Finite Field of size 2 (using GF2X) + sage: P = R.irreducible_element(8) * R # optional - sage.rings.finite_rings + sage: P # optional - sage.rings.finite_rings + Principal ideal (t^8 + t^4 + t^3 + t^2 + 1) of Univariate Polynomial Ring in t + over Finite Field of size 2 (using GF2X) + sage: k. = R.residue_field(P); k # optional - sage.rings.finite_rings + Residue field in a + of Principal ideal (t^8 + t^4 + t^3 + t^2 + 1) of Univariate Polynomial Ring in t + over Finite Field of size 2 (using GF2X) + sage: k.cardinality() # optional - sage.rings.finite_rings 256 Non-maximal ideals are not accepted:: - sage: R.residue_field(t^2 + 1) + sage: R.residue_field(t^2 + 1) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ArithmeticError: ideal is not maximal - sage: R.residue_field(0) + sage: R.residue_field(0) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ArithmeticError: ideal is not maximal - sage: R.residue_field(1) + sage: R.residue_field(1) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ArithmeticError: ideal is not maximal @@ -3241,36 +3257,36 @@ def __init__(self, base_ring, name="x", implementation=None, element_class=None, """ TESTS:: - sage: P = GF(2)['x']; P + sage: P = GF(2)['x']; P # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) - sage: type(P.gen()) + sage: type(P.gen()) # optional - sage.rings.finite_rings - sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_mod_p - sage: P = PolynomialRing_dense_mod_p(GF(5), 'x'); P + sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_mod_p # optional - sage.rings.finite_rings + sage: P = PolynomialRing_dense_mod_p(GF(5), 'x'); P # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 5 - sage: type(P.gen()) + sage: type(P.gen()) # optional - sage.rings.finite_rings - sage: P = PolynomialRing_dense_mod_p(GF(5), 'x', implementation='NTL'); P + sage: P = PolynomialRing_dense_mod_p(GF(5), 'x', implementation='NTL'); P # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 5 (using NTL) - sage: type(P.gen()) + sage: type(P.gen()) # optional - sage.rings.finite_rings - sage: P = PolynomialRing_dense_mod_p(GF(9223372036854775837), 'x') - sage: P + sage: P = PolynomialRing_dense_mod_p(GF(9223372036854775837), 'x') # optional - sage.rings.finite_rings + sage: P # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 9223372036854775837 (using NTL) - sage: type(P.gen()) + sage: type(P.gen()) # optional - sage.rings.finite_rings This caching bug was fixed in :trac:`24264`:: sage: p = 2^64 + 13 - sage: A = GF(p^2) - sage: B = GF(p^3) - sage: R = A.modulus().parent() - sage: S = B.modulus().parent() - sage: R is S + sage: A = GF(p^2) # optional - sage.rings.finite_rings + sage: B = GF(p^3) # optional - sage.rings.finite_rings + sage: R = A.modulus().parent() # optional - sage.rings.finite_rings + sage: S = B.modulus().parent() # optional - sage.rings.finite_rings + sage: R is S # optional - sage.rings.finite_rings True """ if element_class is None: @@ -3312,15 +3328,15 @@ def _implementation_names_impl(implementation, base_ring, sparse): """ TESTS:: - sage: PolynomialRing(GF(2), 'x', implementation="GF2X") + sage: PolynomialRing(GF(2), 'x', implementation="GF2X") # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) - sage: PolynomialRing(GF(2), 'x', implementation="NTL") + sage: PolynomialRing(GF(2), 'x', implementation="NTL") # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) - sage: PolynomialRing(GF(2), 'x', implementation=None) + sage: PolynomialRing(GF(2), 'x', implementation=None) # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) - sage: PolynomialRing(GF(2), 'x', implementation="FLINT") + sage: PolynomialRing(GF(2), 'x', implementation="FLINT") # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 2 - sage: PolynomialRing(GF(3), 'x', implementation="GF2X") + sage: PolynomialRing(GF(3), 'x', implementation="GF2X") # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: GF2X only supports modulus 2 @@ -3356,13 +3372,13 @@ def irreducible_element(self, n, algorithm=None): Currently available options are: - ``'adleman-lenstra'``: a variant of the Adleman--Lenstra - algorithm as implemented in PARI. + algorithm as implemented in PARI. - ``'conway'``: look up the Conway polynomial of degree `n` over the field of `p` elements in the database; raise a ``RuntimeError`` if it is not found. - - ``'ffprimroot'``: use the ``ffprimroot()`` function from + - ``'ffprimroot'``: use the :pari:`ffprimroot` function from PARI. - ``'first_lexicographic'``: return the lexicographically @@ -3375,7 +3391,7 @@ def irreducible_element(self, n, algorithm=None): - ``'primitive'``: return a polynomial `f` such that a root of `f` generates the multiplicative group of the finite field extension defined by `f`. This uses the Conway polynomial if - possible, otherwise it uses ``ffprimroot``. + possible, otherwise it uses ``'ffprimroot'``. - ``'random'``: try random polynomials until an irreducible one is found. @@ -3383,7 +3399,7 @@ def irreducible_element(self, n, algorithm=None): If ``algorithm`` is ``None``, use `x - 1` in degree 1. In degree > 1, the Conway polynomial is used if it is found in the database. Otherwise, the algorithm ``minimal_weight`` - is used if `p = 2`, and the algorithm ``adleman-lenstra`` if + is used if `p = 2`, and the algorithm ``'adleman-lenstra'`` if `p > 2`. OUTPUT: @@ -3392,35 +3408,35 @@ def irreducible_element(self, n, algorithm=None): EXAMPLES:: - sage: GF(5)['x'].irreducible_element(2) + sage: GF(5)['x'].irreducible_element(2) # optional - sage.rings.finite_rings x^2 + 4*x + 2 - sage: GF(5)['x'].irreducible_element(2, algorithm="adleman-lenstra") + sage: GF(5)['x'].irreducible_element(2, algorithm="adleman-lenstra") # optional - sage.rings.finite_rings x^2 + x + 1 - sage: GF(5)['x'].irreducible_element(2, algorithm="primitive") + sage: GF(5)['x'].irreducible_element(2, algorithm="primitive") # optional - sage.rings.finite_rings x^2 + 4*x + 2 - sage: GF(5)['x'].irreducible_element(32, algorithm="first_lexicographic") + sage: GF(5)['x'].irreducible_element(32, algorithm="first_lexicographic") # optional - sage.rings.finite_rings x^32 + 2 - sage: GF(5)['x'].irreducible_element(32, algorithm="conway") + sage: GF(5)['x'].irreducible_element(32, algorithm="conway") # optional - sage.rings.finite_rings Traceback (most recent call last): ... RuntimeError: requested Conway polynomial not in database. - sage: GF(5)['x'].irreducible_element(32, algorithm="primitive") + sage: GF(5)['x'].irreducible_element(32, algorithm="primitive") # optional - sage.rings.finite_rings x^32 + ... In characteristic 2:: - sage: GF(2)['x'].irreducible_element(33) + sage: GF(2)['x'].irreducible_element(33) # optional - sage.rings.finite_rings x^33 + x^13 + x^12 + x^11 + x^10 + x^8 + x^6 + x^3 + 1 - sage: GF(2)['x'].irreducible_element(33, algorithm="minimal_weight") + sage: GF(2)['x'].irreducible_element(33, algorithm="minimal_weight") # optional - sage.rings.finite_rings x^33 + x^10 + 1 In degree 1:: - sage: GF(97)['x'].irreducible_element(1) + sage: GF(97)['x'].irreducible_element(1) # optional - sage.rings.finite_rings x + 96 - sage: GF(97)['x'].irreducible_element(1, algorithm="conway") + sage: GF(97)['x'].irreducible_element(1, algorithm="conway") # optional - sage.rings.finite_rings x + 92 - sage: GF(97)['x'].irreducible_element(1, algorithm="adleman-lenstra") + sage: GF(97)['x'].irreducible_element(1, algorithm="adleman-lenstra") # optional - sage.rings.finite_rings x AUTHORS: @@ -3489,9 +3505,9 @@ def polygen(ring_or_element, name="x"): INPUT: - - polygen(base_ring, name="x") + - ``polygen(base_ring, name="x")`` - - polygen(ring_element, name="x") + - ``polygen(ring_element, name="x")`` If the first input is a ring, return a polynomial generator over that ring. If it is a ring element, return a polynomial generator @@ -3499,7 +3515,7 @@ def polygen(ring_or_element, name="x"): EXAMPLES:: - sage: z = polygen(QQ,'z') + sage: z = polygen(QQ, 'z') sage: z^3 + z +1 z^3 + z + 1 sage: parent(z) @@ -3507,9 +3523,9 @@ def polygen(ring_or_element, name="x"): .. note:: - If you give a list or comma separated string to polygen, you'll + If you give a list or comma-separated string to :func:`polygen`, you'll get a tuple of indeterminates, exactly as if you called - polygens. + :func:`polygens`. """ if is_RingElement(ring_or_element): base_ring = ring_or_element.parent() @@ -3536,7 +3552,7 @@ def polygens(base_ring, names="x", *args): x^2 + 2*x*y + y^2 + 2*x*z + 2*y*z + z^2 sage: parent(x) Multivariate Polynomial Ring in x, y, z over Rational Field - sage: t = polygens(QQ,['x','yz','abc']) + sage: t = polygens(QQ, ['x','yz','abc']) sage: t (x, yz, abc) diff --git a/src/sage/rings/polynomial/polynomial_ring_constructor.py b/src/sage/rings/polynomial/polynomial_ring_constructor.py index 5f823ec7205..08968a5795b 100644 --- a/src/sage/rings/polynomial/polynomial_ring_constructor.py +++ b/src/sage/rings/polynomial/polynomial_ring_constructor.py @@ -114,7 +114,7 @@ def PolynomialRing(base_ring, *args, **kwds): one multivariate polynomial ring over each base ring for each choice of names of variables and term order. The names of the generators can only be temporarily changed after the ring has been - created. Do this using the localvars context: + created. Do this using the :func:`localvars` context. EXAMPLES: @@ -144,8 +144,9 @@ def PolynomialRing(base_ring, *args, **kwds): sage: R. = PolynomialRing(QQ, sparse=True); R Sparse Univariate Polynomial Ring in abc over Rational Field - sage: R. = PolynomialRing(PolynomialRing(GF(7),'k')); R - Univariate Polynomial Ring in w over Univariate Polynomial Ring in k over Finite Field of size 7 + sage: R. = PolynomialRing(PolynomialRing(GF(7),'k')); R # optional - sage.rings.finite_rings + Univariate Polynomial Ring in w over + Univariate Polynomial Ring in k over Finite Field of size 7 The square bracket notation:: @@ -164,7 +165,7 @@ def PolynomialRing(base_ring, *args, **kwds): This is exactly the same ring as what PolynomialRing returns:: - sage: R is PolynomialRing(QQ,'zz') + sage: R is PolynomialRing(QQ, 'zz') True However, rings with different variables are different:: @@ -179,32 +180,32 @@ def PolynomialRing(base_ring, *args, **kwds): like 2^1000000 * x^1000000 in FLINT may be unwise. :: - sage: ZxNTL = PolynomialRing(ZZ, 'x', implementation='NTL'); ZxNTL + sage: ZxNTL = PolynomialRing(ZZ, 'x', implementation='NTL'); ZxNTL # optional - sage.libs.ntl Univariate Polynomial Ring in x over Integer Ring (using NTL) - sage: ZxFLINT = PolynomialRing(ZZ, 'x', implementation='FLINT'); ZxFLINT + sage: ZxFLINT = PolynomialRing(ZZ, 'x', implementation='FLINT'); ZxFLINT # optional - sage.libs.flint Univariate Polynomial Ring in x over Integer Ring - sage: ZxFLINT is ZZ['x'] + sage: ZxFLINT is ZZ['x'] # optional - sage.libs.flint True - sage: ZxFLINT is PolynomialRing(ZZ, 'x') + sage: ZxFLINT is PolynomialRing(ZZ, 'x') # optional - sage.libs.flint True - sage: xNTL = ZxNTL.gen() - sage: xFLINT = ZxFLINT.gen() - sage: xNTL.parent() + sage: xNTL = ZxNTL.gen() # optional - sage.libs.ntl + sage: xFLINT = ZxFLINT.gen() # optional - sage.libs.flint + sage: xNTL.parent() # optional - sage.libs.ntl Univariate Polynomial Ring in x over Integer Ring (using NTL) - sage: xFLINT.parent() + sage: xFLINT.parent() # optional - sage.libs.flint Univariate Polynomial Ring in x over Integer Ring There is a coercion from the non-default to the default implementation, so the values can be mixed in a single expression:: - sage: (xNTL + xFLINT^2) + sage: (xNTL + xFLINT^2) # optional - sage.libs.flint sage.libs.ntl x^2 + x The result of such an expression will use the default, i.e., the FLINT implementation:: - sage: (xNTL + xFLINT^2).parent() + sage: (xNTL + xFLINT^2).parent() # optional - sage.libs.flint sage.libs.ntl Univariate Polynomial Ring in x over Integer Ring The generic implementation uses neither NTL nor FLINT:: @@ -259,9 +260,9 @@ def PolynomialRing(base_ring, *args, **kwds): The Singular implementation always returns a multivariate ring, even for 1 variable:: - sage: PolynomialRing(QQ, "x", implementation="singular") + sage: PolynomialRing(QQ, "x", implementation="singular") # optional - sage.libs.singular Multivariate Polynomial Ring in x over Rational Field - sage: P. = PolynomialRing(QQ, implementation="singular"); P + sage: P. = PolynomialRing(QQ, implementation="singular"); P # optional - sage.libs.singular Multivariate Polynomial Ring in x over Rational Field **3. PolynomialRing(base_ring, n, names, ...)** (where the arguments @@ -278,7 +279,7 @@ def PolynomialRing(base_ring, *args, **kwds): sage: PolynomialRing(QQ, 2, 'alpha0') Multivariate Polynomial Ring in alpha00, alpha01 over Rational Field - sage: PolynomialRing(GF(7), 'y', 5) + sage: PolynomialRing(GF(7), 'y', 5) # optional - sage.rings.finite_rings Multivariate Polynomial Ring in y0, y1, y2, y3, y4 over Finite Field of size 7 sage: PolynomialRing(QQ, 'y', 3, sparse=True) @@ -298,16 +299,19 @@ def PolynomialRing(base_ring, *args, **kwds): example, here is a ring with generators labeled by the primes less than 100:: - sage: R = PolynomialRing(ZZ, ['x%s'%p for p in primes(100)]); R - Multivariate Polynomial Ring in x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97 over Integer Ring + sage: R = PolynomialRing(ZZ, ['x%s'%p for p in primes(100)]); R # optional - sage.libs.pari + Multivariate Polynomial Ring in x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, + x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97 + over Integer Ring By calling the :meth:`~sage.structure.category_object.CategoryObject.inject_variables` method, all those variable names are available for interactive use:: - sage: R.inject_variables() - Defining x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97 - sage: (x2 + x41 + x71)^2 + sage: R.inject_variables() # optional - sage.libs.pari + Defining x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37, x41, x43, + x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97 + sage: (x2 + x41 + x71)^2 # optional - sage.libs.pari x2^2 + 2*x2*x41 + x41^2 + 2*x2*x71 + 2*x41*x71 + x71^2 **4. PolynomialRing(base_ring, n, ..., var_array=var_array, ...)** @@ -323,9 +327,13 @@ def PolynomialRing(base_ring, *args, **kwds): It is possible to create higher-dimensional arrays:: sage: PolynomialRing(ZZ, 2, 3, var_array=('p', 'q')) - Multivariate Polynomial Ring in p00, q00, p01, q01, p02, q02, p10, q10, p11, q11, p12, q12 over Integer Ring + Multivariate Polynomial Ring + in p00, q00, p01, q01, p02, q02, p10, q10, p11, q11, p12, q12 + over Integer Ring sage: PolynomialRing(ZZ, 2, 3, 4, var_array='m') - Multivariate Polynomial Ring in m000, m001, m002, m003, m010, m011, m012, m013, m020, m021, m022, m023, m100, m101, m102, m103, m110, m111, m112, m113, m120, m121, m122, m123 over Integer Ring + Multivariate Polynomial Ring in m000, m001, m002, m003, m010, m011, + m012, m013, m020, m021, m022, m023, m100, m101, m102, m103, m110, + m111, m112, m113, m120, m121, m122, m123 over Integer Ring The array is always at least 2-dimensional. So, if ``var_array`` is a single string and only a single number `n` @@ -352,7 +360,7 @@ def PolynomialRing(base_ring, *args, **kwds): Consider :: - sage: R. = PolynomialRing(QQ,2); R + sage: R. = PolynomialRing(QQ, 2); R Multivariate Polynomial Ring in x, y over Rational Field sage: f = x^2 - 2*y^2 @@ -418,9 +426,9 @@ def PolynomialRing(base_ring, *args, **kwds): The generic implementation is different in some cases:: - sage: R = PolynomialRing(GF(2), 'j', implementation="generic"); TestSuite(R).run(skip=['_test_construction', '_test_pickling']); type(R) + sage: R = PolynomialRing(GF(2), 'j', implementation="generic"); TestSuite(R).run(skip=['_test_construction', '_test_pickling']); type(R) # optional - sage.rings.finite_rings - sage: S = PolynomialRing(GF(2), 'j'); TestSuite(S).run(); type(S) + sage: S = PolynomialRing(GF(2), 'j'); TestSuite(S).run(); type(S) # optional - sage.rings.finite_rings sage: R = PolynomialRing(ZZ, 'x,y', implementation="generic"); TestSuite(R).run(skip=['_test_elements', '_test_elements_eq_transitive']); type(R) @@ -433,7 +441,7 @@ def PolynomialRing(base_ring, *args, **kwds): sage: R = PolynomialRing(ZZ, 'j', sparse=True); TestSuite(R).run(); type(R) - sage: R = PolynomialRing(GF(49), 'j', sparse=True); TestSuite(R).run(); type(R) + sage: R = PolynomialRing(GF(49), 'j', sparse=True); TestSuite(R).run(); type(R) # optional - sage.rings.finite_rings If the requested implementation is not known or not supported for @@ -443,7 +451,7 @@ def PolynomialRing(base_ring, *args, **kwds): Traceback (most recent call last): ... ValueError: unknown implementation 'Foo' for dense polynomial rings over Integer Ring - sage: R. = PolynomialRing(GF(2), implementation='GF2X', sparse=True) + sage: R. = PolynomialRing(GF(2), implementation='GF2X', sparse=True) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: unknown implementation 'GF2X' for sparse polynomial rings over Finite Field of size 2 @@ -555,7 +563,7 @@ def PolynomialRing(base_ring, *args, **kwds): We run the testsuite for various polynomial rings, skipping tests that currently fail:: - sage: R. = PolynomialRing(PolynomialRing(GF(7),'k')); TestSuite(R).run(); R + sage: R. = PolynomialRing(PolynomialRing(GF(7),'k')); TestSuite(R).run(); R # optional - sage.rings.finite_rings Univariate Polynomial Ring in w over Univariate Polynomial Ring in k over Finite Field of size 7 sage: ZxNTL = PolynomialRing(ZZ, 'x', implementation='NTL'); TestSuite(ZxNTL).run(skip='_test_pickling'); ZxNTL Univariate Polynomial Ring in x over Integer Ring (using NTL) @@ -577,9 +585,9 @@ def PolynomialRing(base_ring, *args, **kwds): Multivariate Polynomial Ring in x over Rational Field sage: Q0 = PolynomialRing(QQ,"x",0); TestSuite(Q0).run(skip=['_test_elements', '_test_elements_eq_transitive', '_test_gcd_vs_xgcd', '_test_quo_rem']); Q0 Multivariate Polynomial Ring in no variables over Rational Field - sage: R = PolynomialRing(GF(2), 'j', implementation="generic"); TestSuite(R).run(skip=['_test_construction', '_test_pickling']); type(R) + sage: R = PolynomialRing(GF(2), 'j', implementation="generic"); TestSuite(R).run(skip=['_test_construction', '_test_pickling']); type(R) # optional - sage.rings.finite_rings - sage: S = PolynomialRing(GF(2), 'j'); TestSuite(S).run(); type(S) + sage: S = PolynomialRing(GF(2), 'j'); TestSuite(S).run(); type(S) # optional - sage.rings.finite_rings sage: R = PolynomialRing(ZZ, 'x,y', implementation="generic"); TestSuite(R).run(skip=['_test_elements', '_test_elements_eq_transitive']); type(R) @@ -587,7 +595,7 @@ def PolynomialRing(base_ring, *args, **kwds): sage: R = PolynomialRing(ZZ, 'j', sparse=True); TestSuite(R).run(); type(R) - sage: R = PolynomialRing(GF(49), 'j', sparse=True); TestSuite(R).run(); type(R) + sage: R = PolynomialRing(GF(49), 'j', sparse=True); TestSuite(R).run(); type(R) # optional - sage.rings.finite_rings sage: P. = PolynomialRing(RealIntervalField(2)) sage: TestSuite(P).run(skip=['_test_elements', '_test_elements_eq_transitive']) @@ -930,47 +938,46 @@ def BooleanPolynomialRing_constructor(n=None, names=None, order="lex"): - ``n`` -- number of variables (an integer > 1) - ``names`` -- names of ring variables, may be a string or list/tuple of strings - - ``order`` -- term order (default: lex) + - ``order`` -- term order (default: ``'lex'``) EXAMPLES:: - sage: R. = BooleanPolynomialRing() # indirect doctest - sage: R + sage: R. = BooleanPolynomialRing(); R # indirect doctest # optional - sage.rings.polynomial.pbori Boolean PolynomialRing in x, y, z - sage: p = x*y + x*z + y*z - sage: x*p + sage: p = x*y + x*z + y*z # optional - sage.rings.polynomial.pbori + sage: x*p # optional - sage.rings.polynomial.pbori x*y*z + x*y + x*z - sage: R.term_order() + sage: R.term_order() # optional - sage.rings.polynomial.pbori Lexicographic term order - sage: R = BooleanPolynomialRing(5,'x',order='deglex(3),deglex(2)') - sage: R.term_order() + sage: R = BooleanPolynomialRing(5, 'x', order='deglex(3),deglex(2)') # optional - sage.rings.polynomial.pbori + sage: R.term_order() # optional - sage.rings.polynomial.pbori Block term order with blocks: (Degree lexicographic term order of length 3, Degree lexicographic term order of length 2) - sage: R = BooleanPolynomialRing(3,'x',order='degneglex') - sage: R.term_order() + sage: R = BooleanPolynomialRing(3, 'x', order='degneglex') # optional - sage.rings.polynomial.pbori + sage: R.term_order() # optional - sage.rings.polynomial.pbori Degree negative lexicographic term order - sage: BooleanPolynomialRing(names=('x','y')) + sage: BooleanPolynomialRing(names=('x','y')) # optional - sage.rings.polynomial.pbori Boolean PolynomialRing in x, y - sage: BooleanPolynomialRing(names='x,y') + sage: BooleanPolynomialRing(names='x,y') # optional - sage.rings.polynomial.pbori Boolean PolynomialRing in x, y TESTS:: - sage: P. = BooleanPolynomialRing(2,order='deglex') - sage: x > y + sage: P. = BooleanPolynomialRing(2, order='deglex') # optional - sage.rings.polynomial.pbori + sage: x > y # optional - sage.rings.polynomial.pbori True - sage: P. = BooleanPolynomialRing(4,order='deglex(2),deglex(2)') - sage: x0 > x1 + sage: P. = BooleanPolynomialRing(4, order='deglex(2),deglex(2)') # optional - sage.rings.polynomial.pbori + sage: x0 > x1 # optional - sage.rings.polynomial.pbori True - sage: x2 > x3 + sage: x2 > x3 # optional - sage.rings.polynomial.pbori True """ if isinstance(n, str): diff --git a/src/sage/rings/polynomial/polynomial_ring_homomorphism.pyx b/src/sage/rings/polynomial/polynomial_ring_homomorphism.pyx index 18140a24981..4b55fa8c778 100644 --- a/src/sage/rings/polynomial/polynomial_ring_homomorphism.pyx +++ b/src/sage/rings/polynomial/polynomial_ring_homomorphism.pyx @@ -73,18 +73,18 @@ cdef class PolynomialRingHomomorphism_from_base(RingHomomorphism_from_base): sage: from sage.rings.polynomial.polynomial_ring_homomorphism import PolynomialRingHomomorphism_from_base sage: R. = ZZ[] - sage: S = GF(5)['x'] - sage: f = ZZ.hom(GF(5)) - sage: F = PolynomialRingHomomorphism_from_base(R.Hom(S), f) - sage: F(2*x, check=True) + sage: S = GF(5)['x'] # optional - sage.rings.finite_rings + sage: f = ZZ.hom(GF(5)) # optional - sage.rings.finite_rings + sage: F = PolynomialRingHomomorphism_from_base(R.Hom(S), f) # optional - sage.rings.finite_rings + sage: F(2 * x, check=True) # optional - sage.rings.finite_rings 2*x - sage: k = GF(49, 'z') - sage: A = PolynomialRing(GF(7), 'x', sparse=True) - sage: B = PolynomialRing(k, 'x', sparse=True) - sage: g = GF(7).hom(k) - sage: G = PolynomialRingHomomorphism_from_base(A.Hom(B), g) - sage: G(A.gen()^1000000, True, construct=False) + sage: k = GF(49, 'z') # optional - sage.rings.finite_rings + sage: A = PolynomialRing(GF(7), 'x', sparse=True) # optional - sage.rings.finite_rings + sage: B = PolynomialRing(k, 'x', sparse=True) # optional - sage.rings.finite_rings + sage: g = GF(7).hom(k) # optional - sage.rings.finite_rings + sage: G = PolynomialRingHomomorphism_from_base(A.Hom(B), g) # optional - sage.rings.finite_rings + sage: G(A.gen()^1000000, True, construct=False) # optional - sage.rings.finite_rings x^1000000 """ diff --git a/src/sage/rings/polynomial/polynomial_singular_interface.py b/src/sage/rings/polynomial/polynomial_singular_interface.py index 254d908a592..e00cb4ca63b 100644 --- a/src/sage/rings/polynomial/polynomial_singular_interface.py +++ b/src/sage/rings/polynomial/polynomial_singular_interface.py @@ -5,16 +5,16 @@ - Martin Albrecht (2006-04-21) - Robert Bradshaw: Re-factor to avoid multiple inheritance vs. Cython (2007-09) -- Syed Ahmad Lavasani: Added function field to _singular_init_ (2011-12-16) - Added non-prime finite fields to _singular_init_ (2012-1-22) +- Syed Ahmad Lavasani: Added function field to _singular_init_ (2011-12-16); + Added non-prime finite fields to _singular_init_ (2012-1-22) TESTS:: - sage: R = PolynomialRing(GF(2**8,'a'),10,'x', order='invlex') - sage: R == loads(dumps(R)) + sage: R = PolynomialRing(GF(2**8,'a'), 10, 'x', order='invlex') # optional - sage.rings.finite_rings + sage: R == loads(dumps(R)) # optional - sage.rings.finite_rings True - sage: P. = PolynomialRing(GF(7), 2) - sage: f = (a^3 + 2*b^2*a)^7; f + sage: P. = PolynomialRing(GF(7), 2) # optional - sage.rings.finite_rings + sage: f = (a^3 + 2*b^2*a)^7; f # optional - sage.rings.finite_rings a^21 + 2*a^7*b^14 """ @@ -61,7 +61,7 @@ def _do_singular_init_(singular, base_ring, char, _vars, order): TESTS:: sage: from sage.rings.polynomial.polynomial_singular_interface import _do_singular_init_ - sage: _do_singular_init_(singular, ZZ, 0, 'X', 'dp') + sage: _do_singular_init_(singular, ZZ, 0, 'X', 'dp') # optional - sage.libs.singular (polynomial ring, over a domain, global ordering // coefficients: ZZ // number of vars : 1 @@ -214,8 +214,8 @@ def _singular_(self, singular=singular): sage: w = var('w') - sage: R. = PolynomialRing(NumberField(w^2+1,'s')) - sage: singular(R) + sage: R. = PolynomialRing(NumberField(w^2 + 1, 's')) # optional - sage.rings.number_field + sage: singular(R) # optional - sage.rings.number_field polynomial ring, over a field, global ordering // coefficients: QQ[s]/(s^2+1) // number of vars : 1 @@ -223,8 +223,8 @@ def _singular_(self, singular=singular): // : names x // block 2 : ordering C - sage: R = PolynomialRing(GF(127), 'x', implementation="singular") - sage: singular(R) + sage: R = PolynomialRing(GF(127), 'x', implementation="singular") # optional - sage.rings.finite_rings + sage: singular(R) # optional - sage.rings.finite_rings polynomial ring, over a field, global ordering // coefficients: ZZ/127 // number of vars : 1 @@ -250,8 +250,8 @@ def _singular_(self, singular=singular): // : names x // block 2 : ordering C - sage: R = PolynomialRing(GF(127),'x') - sage: singular(R) + sage: R = PolynomialRing(GF(127), 'x') # optional - sage.rings.finite_rings + sage: singular(R) # optional - sage.rings.finite_rings polynomial ring, over a field, global ordering // coefficients: ZZ/127 // number of vars : 1 @@ -305,11 +305,11 @@ def _singular_(self, singular=singular): // : names x // block 2 : ordering C - sage: k. = FiniteField(25) - sage: R = k['x'] - sage: K = R.fraction_field() - sage: S = K['y'] - sage: singular(S) + sage: k. = FiniteField(25) # optional - sage.rings.finite_rings + sage: R = k['x'] # optional - sage.rings.finite_rings + sage: K = R.fraction_field() # optional - sage.rings.finite_rings + sage: S = K['y'] # optional - sage.rings.finite_rings + sage: singular(S) # optional - sage.rings.finite_rings polynomial ring, over a field, global ordering // coefficients: ZZ/5(x) // number of vars : 2 @@ -350,7 +350,7 @@ def _singular_init_(self, singular=singular): EXAMPLES:: - sage: PolynomialRing(QQ,'u_ba')._singular_init_() + sage: PolynomialRing(QQ,'u_ba')._singular_init_() # optional - sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 1 @@ -399,23 +399,23 @@ def can_convert_to_singular(R): Avoid non absolute number fields (see :trac:`23535`):: - sage: K. = NumberField([x^2-2,x^2-5]) - sage: can_convert_to_singular(K['s,t']) + sage: K. = NumberField([x^2 - 2, x^2 - 5]) # optional - sage.rings.number_field + sage: can_convert_to_singular(K['s,t']) # optional - sage.rings.number_field False Check for :trac:`33319`:: - sage: R. = GF((2^31-1)^3)[] - sage: R._has_singular + sage: R. = GF((2^31-1)^3)[] # optional - sage.rings.finite_rings + sage: R._has_singular # optional - sage.rings.finite_rings True - sage: R. = GF((2^31+11)^2)[] - sage: R._has_singular + sage: R. = GF((2^31+11)^2)[] # optional - sage.rings.finite_rings + sage: R._has_singular # optional - sage.rings.finite_rings False - sage: R. = GF(10^20-11)[] - sage: R._has_singular + sage: R. = GF(10^20 - 11)[] # optional - sage.rings.finite_rings + sage: R._has_singular # optional - sage.rings.finite_rings True - sage: R. = Zmod(10^20+1)[] - sage: R._has_singular + sage: R. = Zmod(10^20 + 1)[] # optional - sage.libs.pari + sage: R._has_singular # optional - sage.libs.pari True """ if R.ngens() == 0: @@ -470,25 +470,25 @@ def _singular_func(self, singular=singular): EXAMPLES:: - sage: P. = PolynomialRing(GF(7), 2) - sage: f = (a^3 + 2*b^2*a)^7; f + sage: P. = PolynomialRing(GF(7), 2) # optional - sage.rings.finite_rings + sage: f = (a^3 + 2*b^2*a)^7; f # optional - sage.rings.finite_rings a^21 + 2*a^7*b^14 - sage: h = f._singular_(); h + sage: h = f._singular_(); h # optional - sage.rings.finite_rings a^21+2*a^7*b^14 - sage: P(h) + sage: P(h) # optional - sage.rings.finite_rings a^21 + 2*a^7*b^14 - sage: P(h^20) == f^20 + sage: P(h^20) == f^20 # optional - sage.rings.finite_rings True - sage: R. = PolynomialRing(GF(7)) - sage: f = (x^3 + 2*x^2*x)^7 - sage: f + sage: R. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings + sage: f = (x^3 + 2*x^2*x)^7 # optional - sage.rings.finite_rings + sage: f # optional - sage.rings.finite_rings 3*x^21 - sage: h = f._singular_(); h + sage: h = f._singular_(); h # optional - sage.rings.finite_rings 3*x^21 - sage: R(h) + sage: R(h) # optional - sage.rings.finite_rings 3*x^21 - sage: R(h^20) == f^20 + sage: R(h^20) == f^20 # optional - sage.rings.finite_rings True """ self.parent()._singular_(singular).set_ring() # this is expensive diff --git a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx index 2c7e23be960..6f30bf046d5 100644 --- a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx @@ -182,7 +182,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): EXAMPLES:: - sage: P.=GF(7)[] + sage: P. = GF(7)[] sage: P([2^60,0,1]) a^2 + 1 sage: P([]) @@ -329,12 +329,12 @@ cdef class Polynomial_zmod_flint(Polynomial_template): @coerce_binop def resultant(self, Polynomial_zmod_flint other): """ - Returns the resultant of self and other, which must lie in the same + Return the resultant of ``self`` and ``other``, which must lie in the same polynomial ring. INPUT: - - other -- a polynomial + - ``other`` -- a polynomial OUTPUT: an element of the base ring of the polynomial ring @@ -388,8 +388,8 @@ cdef class Polynomial_zmod_flint(Polynomial_template): INPUT: - - n -- degree - - value -- coefficient + - ``n`` -- degree + - ``value`` -- coefficient .. warning:: @@ -425,7 +425,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): EXAMPLES:: - sage: P.=GF(7)[] + sage: P. = GF(7)[] sage: a = P(range(10)); b = P(range(5, 15)) sage: a._mul_trunc_(b, 5) 4*a^4 + 6*a^3 + 2*a^2 + 5*a @@ -457,7 +457,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): EXAMPLES:: - sage: P.=GF(7)[] + sage: P. = GF(7)[] sage: b = P(range(10)); c = P(range(5, 15)) sage: b._mul_trunc_opposite(c, 10) 5*a^17 + 2*a^16 + 6*a^15 + 4*a^14 + 4*a^13 + 5*a^10 + 2*a^9 + 5*a^8 + 4*a^5 + 4*a^4 + 6*a^3 + 2*a^2 + 5*a @@ -522,7 +522,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): cpdef rational_reconstruction(self, m, n_deg=0, d_deg=0): """ - Construct a rational function n/d such that `p*d` is equivalent to `n` + Construct a rational function `n/d` such that `p*d` is equivalent to `n` modulo `m` where `p` is this polynomial. EXAMPLES:: @@ -594,7 +594,8 @@ cdef class Polynomial_zmod_flint(Polynomial_template): sage: (s^2).is_irreducible() Traceback (most recent call last): ... - NotImplementedError: checking irreducibility of polynomials over rings with composite characteristic is not implemented + NotImplementedError: checking irreducibility of polynomials + over rings with composite characteristic is not implemented TESTS:: @@ -610,7 +611,8 @@ cdef class Polynomial_zmod_flint(Polynomial_template): sage: S(2).is_irreducible() Traceback (most recent call last): ... - NotImplementedError: checking irreducibility of polynomials over rings with composite characteristic is not implemented + NotImplementedError: checking irreducibility of polynomials + over rings with composite characteristic is not implemented Test that caching works:: @@ -639,7 +641,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): def squarefree_decomposition(self): """ - Returns the squarefree decomposition of this polynomial. + Return the squarefree decomposition of this polynomial. EXAMPLES:: @@ -665,7 +667,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): def factor(self): """ - Returns the factorization of the polynomial. + Return the factorization of the polynomial. EXAMPLES:: @@ -720,13 +722,13 @@ cdef class Polynomial_zmod_flint(Polynomial_template): """ Return this polynomial divided by its leading coefficient. - Raises ValueError if the leading coefficient is not invertible in the + Raises :class:`ValueError` if the leading coefficient is not invertible in the base ring. EXAMPLES:: sage: R. = GF(5)[] - sage: (2*x^2+1).monic() + sage: (2*x^2 + 1).monic() x^2 + 3 TESTS:: @@ -748,7 +750,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): """ Return a polynomial with the coefficients of this polynomial reversed. - If an optional degree argument is given the coefficient list will be + If the optional argument ``degree`` is given, the coefficient list will be truncated or zero padded as necessary before computing the reverse. EXAMPLES:: @@ -819,7 +821,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): def revert_series(self, n): r""" - Return a polynomial `f` such that `f(self(x)) = self(f(x)) = x mod x^n`. + Return a polynomial `f` such that ``f(self(x)) = self(f(x)) = x`` (mod `x^n`). EXAMPLES:: @@ -872,7 +874,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): sage: R. = GF(127)[] sage: type(x) - sage: (x^5-3).minpoly_mod(x^3+5*x-1) + sage: (x^5 - 3).minpoly_mod(x^3 + 5*x - 1) x^3 + 34*x^2 + 125*x + 95 """ parent = self.parent() diff --git a/src/sage/rings/polynomial/polynomial_zz_pex.pyx b/src/sage/rings/polynomial/polynomial_zz_pex.pyx index 0d885e522ef..6d981a245f3 100644 --- a/src/sage/rings/polynomial/polynomial_zz_pex.pyx +++ b/src/sage/rings/polynomial/polynomial_zz_pex.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.ntl sage.rings.finite_rings # distutils: libraries = NTL_LIBRARIES gmp # distutils: extra_compile_args = NTL_CFLAGS # distutils: include_dirs = NTL_INCDIR @@ -67,24 +68,24 @@ cdef inline ZZ_pE_c_to_list(ZZ_pE_c x): cdef class Polynomial_ZZ_pEX(Polynomial_template): - """ - Univariate Polynomials over GF(p^n) via NTL's ZZ_pEX. + r""" + Univariate Polynomials over `\GF{p^n}` via NTL's ``ZZ_pEX``. EXAMPLES:: - sage: K.=GF(next_prime(2**60)**3) - sage: R. = PolynomialRing(K,implementation='NTL') + sage: K. = GF(next_prime(2**60)**3) + sage: R. = PolynomialRing(K, implementation='NTL') sage: (x^3 + a*x^2 + 1) * (x + a) x^4 + 2*a*x^3 + a^2*x^2 + x + a """ def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): - """ - Create a new univariate polynomials over GF(p^n). + r""" + Create a new univariate polynomials over `\GF{p^n}`. EXAMPLES:: - sage: K.=GF(next_prime(2**60)**3) - sage: R. = PolynomialRing(K,implementation='NTL') + sage: K. = GF(next_prime(2**60)**3) + sage: R. = PolynomialRing(K, implementation='NTL') sage: x^2+a x^2 + a @@ -156,14 +157,14 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): Polynomial_template.__init__(self, parent, x, check, is_gen, construct) cdef get_unsafe(self, Py_ssize_t i): - """ + r""" Return the `i`-th coefficient of ``self``. EXAMPLES:: - sage: K.=GF(next_prime(2**60)**3) - sage: R. = PolynomialRing(K,implementation='NTL') - sage: f = x^3+(2*a+1)*x+a + sage: K. = GF(next_prime(2**60)**3) + sage: R. = PolynomialRing(K, implementation='NTL') + sage: f = x^3 + (2*a+1)*x + a sage: f[0] a sage: f[1] @@ -180,7 +181,7 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): return self._parent._base(ZZ_pE_c_to_list(c_pE)) cpdef list list(self, bint copy=True): - """ + r""" Return the list of coefficients. EXAMPLES:: @@ -188,7 +189,7 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): sage: K. = GF(5^3) sage: P = PolynomialRing(K, 'x') sage: f = P.random_element(100) - sage: f.list() == [f[i] for i in range(f.degree()+1)] + sage: f.list() == [f[i] for i in range(f.degree()+1)] True sage: P.0.list() [0, 1] @@ -202,11 +203,11 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): for i in range(celement_len(&self.x, (self)._cparent))] cpdef _lmul_(self, Element left): - """ + r""" EXAMPLES:: - sage: K.=GF(next_prime(2**60)**3) - sage: R. = PolynomialRing(K,implementation='NTL') + sage: K. = GF(next_prime(2**60)**3) + sage: R. = PolynomialRing(K, implementation='NTL') sage: (2*a+1)*x # indirect doctest (2*a + 1)*x sage: x*(2*a+1) # indirect doctest @@ -223,13 +224,13 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): return r def __call__(self, *x, **kwds): - """ + r""" Evaluate polynomial at `a`. EXAMPLES:: - sage: K.=GF(next_prime(2**60)**3) - sage: R. = PolynomialRing(K,implementation='NTL') + sage: K. = GF(next_prime(2**60)**3) + sage: R. = PolynomialRing(K, implementation='NTL') sage: P = (x-u)*(x+u+1) sage: P(u) 0 @@ -243,7 +244,7 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): sage: F. = GF(4) sage: P. = F[] sage: p = y^4 + x*y^3 + y^2 + (x + 1)*y + x + 1 - sage: SR(p) + sage: SR(p) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: positive characteristic not allowed in symbolic computations @@ -288,24 +289,24 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): return K(ZZ_pE_c_to_list(c_b)) def resultant(self, other): - """ - Returns the resultant of self and other, which must lie in the same + r""" + Return the resultant of ``self`` and ``other``, which must lie in the same polynomial ring. INPUT: - :argument other: a polynomial + - ``other`` -- a polynomial OUTPUT: an element of the base ring of the polynomial ring EXAMPLES:: - sage: K.=GF(next_prime(2**60)**3) - sage: R. = PolynomialRing(K,implementation='NTL') - sage: f=(x-a)*(x-a**2)*(x+1) - sage: g=(x-a**3)*(x-a**4)*(x+a) + sage: K. = GF(next_prime(2**60)**3) + sage: R. = PolynomialRing(K, implementation='NTL') + sage: f = (x-a)*(x-a**2)*(x+1) + sage: g = (x-a**3)*(x-a**4)*(x+a) sage: r = f.resultant(g) - sage: r == prod(u-v for (u,eu) in f.roots() for (v,ev) in g.roots()) + sage: r == prod(u - v for (u,eu) in f.roots() for (v,ev) in g.roots()) True """ cdef ZZ_pE_c r @@ -320,23 +321,24 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): return K(K.polynomial_ring()(ZZ_pE_c_to_list(r))) def is_irreducible(self, algorithm="fast_when_false", iter=1): - """ - Returns `True` precisely when self is irreducible over its base ring. + r""" + Return ``True`` precisely when ``self`` is irreducible over its base ring. INPUT: - :argument algorithm: a string (default "fast_when_false"), - there are 3 available algorithms: - "fast_when_true", "fast_when_false" and "probabilistic". - :argument iter: (default: 1) if the algorithm is "probabilistic" - defines the number of iterations. The error probability is bounded - by `q**-iter` for polynomials in `GF(q)[x]`. + - ``algorithm`` -- a string (default ``"fast_when_false"``), + there are 3 available algorithms: + ``"fast_when_true"``, ``"fast_when_false"``, and ``"probabilistic".`` + + - ``iter`` -- (default: 1) if the algorithm is ``"probabilistic"``, + defines the number of iterations. The error probability is bounded + by `q^{\text{-iter}}` for polynomials in `\GF{q}[x]`. EXAMPLES:: - sage: K.=GF(next_prime(2**60)**3) - sage: R. = PolynomialRing(K,implementation='NTL') - sage: P = x^3+(2-a)*x+1 + sage: K. = GF(next_prime(2**60)**3) + sage: R. = PolynomialRing(K, implementation='NTL') + sage: P = x^3 + (2-a)*x + 1 sage: P.is_irreducible(algorithm="fast_when_false") True sage: P.is_irreducible(algorithm="fast_when_true") @@ -350,7 +352,7 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): False sage: Q.is_irreducible(algorithm="probabilistic") False - """ + """ self._parent._modulus.restore() if algorithm=="fast_when_false": sig_on() @@ -413,20 +415,20 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): return r cpdef _richcmp_(self, other, int op): - """ + r""" EXAMPLES:: - sage: K.=GF(next_prime(2**60)**3) - sage: R. = PolynomialRing(K,implementation='NTL') - sage: P1 = (a**2+a+1)*x^2+a*x+1 - sage: P2 = ( a+1)*x^2+a*x+1 + sage: K. = GF(next_prime(2**60)**3) + sage: R. = PolynomialRing(K, implementation='NTL') + sage: P1 = (a**2+a+1)*x^2 + a*x + 1 + sage: P2 = ( a+1)*x^2 + a*x + 1 sage: P1 < P2 # indirect doctests False TESTS:: - sage: P3 = (a**2+a+1)*x^2+ x+1 - sage: P4 = x+1 + sage: P3 = (a**2+a+1)*x^2 + x + 1 + sage: P4 = x + 1 sage: P1 < P3 False sage: P1 < P4 @@ -441,11 +443,11 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): return Polynomial._richcmp_(self, other, op) def shift(self, int n): - """ + r""" EXAMPLES:: - sage: K.=GF(next_prime(2**60)**3) - sage: R. = PolynomialRing(K,implementation='NTL') + sage: K. = GF(next_prime(2**60)**3) + sage: R. = PolynomialRing(K, implementation='NTL') sage: f = x^3 + x^2 + 1 sage: f.shift(1) x^4 + x^3 + x @@ -462,11 +464,11 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): return r def __lshift__(self, int n): - """ + r""" EXAMPLES:: - sage: K.=GF(next_prime(2**60)**3) - sage: R. = PolynomialRing(K,implementation='NTL') + sage: K. = GF(next_prime(2**60)**3) + sage: R. = PolynomialRing(K, implementation='NTL') sage: f = x^3 + x^2 + 1 sage: f << 1 x^4 + x^3 + x @@ -476,11 +478,11 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): return self.shift(n) def __rshift__(self, int n): - """ + r""" EXAMPLES:: - sage: K.=GF(next_prime(2**60)**3) - sage: R. = PolynomialRing(K,implementation='NTL') + sage: K. = GF(next_prime(2**60)**3) + sage: R. = PolynomialRing(K, implementation='NTL') sage: f = x^3 + x^2 + 1 sage: f >> 1 x^2 + x diff --git a/src/sage/rings/polynomial/real_roots.pyx b/src/sage/rings/polynomial/real_roots.pyx index 94fa0b84d40..3422efb7c6f 100644 --- a/src/sage/rings/polynomial/real_roots.pyx +++ b/src/sage/rings/polynomial/real_roots.pyx @@ -3129,7 +3129,7 @@ cdef class ocean: def all_done(self): """ - Returns true iff all islands are known to contain exactly one root. + Return ``True`` iff all islands are known to contain exactly one root. EXAMPLES:: diff --git a/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx b/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx index f3ff0617484..7acfec8c97f 100644 --- a/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx +++ b/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - 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 a71a217719b..9f499430d59 100644 --- a/src/sage/rings/polynomial/skew_polynomial_ring.py +++ b/src/sage/rings/polynomial/skew_polynomial_ring.py @@ -78,7 +78,7 @@ def _base_ring_to_fraction_field(S): sage: from sage.rings.polynomial.skew_polynomial_ring import _base_ring_to_fraction_field sage: R. = ZZ[] - sage: sigma = R.hom([t+1]) + sage: sigma = R.hom([t + 1]) sage: S. = R['x', sigma] sage: _base_ring_to_fraction_field(S) Ore Polynomial Ring in x over Fraction Field of Univariate Polynomial Ring in t over Integer Ring twisted by t |--> t + 1 @@ -117,11 +117,11 @@ def _minimal_vanishing_polynomial(R, eval_pts): EXAMPLES:: sage: from sage.rings.polynomial.skew_polynomial_ring import _minimal_vanishing_polynomial - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: eval_pts = [1, t, t^2] - sage: b = _minimal_vanishing_polynomial(S, eval_pts); b + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob] # optional - sage.rings.finite_rings + sage: eval_pts = [1, t, t^2] # optional - sage.rings.finite_rings + sage: b = _minimal_vanishing_polynomial(S, eval_pts); b # optional - sage.rings.finite_rings doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. See https://github.com/sagemath/sage/issues/13215 for details. @@ -172,23 +172,23 @@ def _lagrange_polynomial(R, eval_pts, values): EXAMPLES:: sage: from sage.rings.polynomial.skew_polynomial_ring import _lagrange_polynomial - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: eval_pts = [ t , t^2 ] - sage: values = [ 3*t^2 + 4*t + 4 , 4*t ] - sage: d = _lagrange_polynomial(S, eval_pts, values); d + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x', Frob] # optional - sage.rings.finite_rings + sage: eval_pts = [t , t^2] # optional - sage.rings.finite_rings + sage: values = [3*t^2 + 4*t + 4, 4*t] # optional - sage.rings.finite_rings + sage: d = _lagrange_polynomial(S, eval_pts, values); d # optional - sage.rings.finite_rings x + t - sage: d.multi_point_evaluation(eval_pts) == values + sage: d.multi_point_evaluation(eval_pts) == values # optional - sage.rings.finite_rings True The following restrictions are impossible to satisfy because the evaluation points are linearly dependent over the fixed field of the twisting morphism, and the corresponding values do not match:: - sage: eval_pts = [ t, 2*t ] - sage: values = [ 1, 3 ] - sage: _lagrange_polynomial(S, eval_pts, values) + sage: eval_pts = [t, 2*t] # optional - sage.rings.finite_rings + sage: values = [1, 3] # optional - sage.rings.finite_rings + sage: _lagrange_polynomial(S, eval_pts, values) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: the given evaluation points are linearly dependent over the fixed field of the twisting morphism, @@ -240,7 +240,7 @@ def __init__(self, base_ring, morphism, derivation, name, sparse, category=None) EXAMPLES:: sage: R. = ZZ[] - sage: sigma = R.hom([t+1]) + sage: sigma = R.hom([t + 1]) sage: S. = SkewPolynomialRing(R,sigma) sage: S.category() Category of algebras over Univariate Polynomial Ring in t over Integer Ring @@ -275,26 +275,26 @@ def minimal_vanishing_polynomial(self, eval_pts): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: eval_pts = [1, t, t^2] - sage: b = S.minimal_vanishing_polynomial(eval_pts); b + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x', Frob] # optional - sage.rings.finite_rings + sage: eval_pts = [1, t, t^2] # optional - sage.rings.finite_rings + sage: b = S.minimal_vanishing_polynomial(eval_pts); b # optional - sage.rings.finite_rings x^3 + 4 The minimal vanishing polynomial evaluates to 0 at each of the evaluation points:: - sage: eval = b.multi_point_evaluation(eval_pts); eval + sage: eval = b.multi_point_evaluation(eval_pts); eval # optional - sage.rings.finite_rings [0, 0, 0] If the evaluation points are linearly dependent over the fixed field of the twisting morphism, then the returned polynomial has lower degree than the number of evaluation points:: - sage: S.minimal_vanishing_polynomial([t]) + sage: S.minimal_vanishing_polynomial([t]) # optional - sage.rings.finite_rings x + 3*t^2 + 3*t - sage: S.minimal_vanishing_polynomial([t, 3*t]) + sage: S.minimal_vanishing_polynomial([t, 3*t]) # optional - sage.rings.finite_rings x + 3*t^2 + 3*t """ return _minimal_vanishing_polynomial(_base_ring_to_fraction_field(self), eval_pts) @@ -328,26 +328,27 @@ def lagrange_polynomial(self, points): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob] - sage: points = [(t, 3*t^2 + 4*t + 4), (t^2, 4*t)] - sage: d = S.lagrange_polynomial(points); d + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x', Frob] # optional - sage.rings.finite_rings + sage: points = [(t, 3*t^2 + 4*t + 4), (t^2, 4*t)] # optional - sage.rings.finite_rings + sage: d = S.lagrange_polynomial(points); d # optional - sage.rings.finite_rings x + t sage: R. = ZZ[] - sage: sigma = R.hom([t+1]) + sage: sigma = R.hom([t + 1]) sage: T. = R['x', sigma] - sage: points = [ (1, t^2 + 3*t + 4), (t, 2*t^2 + 3*t + 1), (t^2, t^2 + 3*t + 4) ] + sage: points = [(1, t^2 + 3*t + 4), (t, 2*t^2 + 3*t + 1), (t^2, t^2 + 3*t + 4)] sage: p = T.lagrange_polynomial(points); p - ((-t^4 - 2*t - 3)/-2)*x^2 + (-t^4 - t^3 - t^2 - 3*t - 2)*x + (-t^4 - 2*t^3 - 4*t^2 - 10*t - 9)/-2 - sage: p.multi_point_evaluation([1, t, t^2]) == [ t^2 + 3*t + 4, 2*t^2 + 3*t + 1, t^2 + 3*t + 4 ] + ((-t^4 - 2*t - 3)/-2)*x^2 + (-t^4 - t^3 - t^2 - 3*t - 2)*x + + (-t^4 - 2*t^3 - 4*t^2 - 10*t - 9)/-2 + sage: p.multi_point_evaluation([1, t, t^2]) == [t^2 + 3*t + 4, 2*t^2 + 3*t + 1, t^2 + 3*t + 4] True If the `x_i` are linearly dependent over the fixed field of ``self.twisting_morphism()``, then an error is raised:: - sage: T.lagrange_polynomial([ (t, 1), (2*t, 3) ]) + sage: T.lagrange_polynomial([(t, 1), (2*t, 3)]) Traceback (most recent call last): ... ValueError: the given evaluation points are linearly dependent over the fixed field of the twisting morphism, @@ -378,12 +379,12 @@ class SectionSkewPolynomialCenterInjection(Section): TESTS:: - sage: k. = GF(5^3) - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) - sage: Z = S.center() - sage: iota = S.convert_map_from(Z) - sage: sigma = iota.section() - sage: TestSuite(sigma).run(skip=['_test_category']) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings + sage: Z = S.center() # optional - sage.rings.finite_rings + sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings + sage: sigma = iota.section() # optional - sage.rings.finite_rings + sage: TestSuite(sigma).run(skip=['_test_category']) # optional - sage.rings.finite_rings """ def _call_(self, x): r""" @@ -391,14 +392,14 @@ def _call_(self, x): EXAMPLES:: - sage: k. = GF(5^3) - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) - sage: Z = S.center() - sage: iota = S.convert_map_from(Z) - sage: sigma = iota.section() - sage: sigma(x^3) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings + sage: Z = S.center() # optional - sage.rings.finite_rings + sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings + sage: sigma = iota.section() # optional - sage.rings.finite_rings + sage: sigma(x^3) # optional - sage.rings.finite_rings z - sage: sigma(x^2) + sage: sigma(x^2) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: x^2 is not in the center @@ -425,18 +426,18 @@ def _richcmp_(self, right, op): TESTS:: - sage: k. = GF(5^3) - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) - sage: Z = S.center() - sage: iota = S.convert_map_from(Z) - sage: sigma = iota.section() + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings + sage: Z = S.center() # optional - sage.rings.finite_rings + sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings + sage: sigma = iota.section() # optional - sage.rings.finite_rings - sage: s = loads(dumps(sigma)) - sage: s == sigma + sage: s = loads(dumps(sigma)) # optional - sage.rings.finite_rings + sage: s == sigma # optional - sage.rings.finite_rings True - sage: s != sigma + sage: s != sigma # optional - sage.rings.finite_rings False - sage: s is sigma + sage: s is sigma # optional - sage.rings.finite_rings False """ if op == op_EQ: @@ -453,11 +454,11 @@ class SkewPolynomialCenterInjection(RingHomomorphism): TESTS:: - sage: k. = GF(5^3) - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) - sage: Z = S.center() - sage: iota = S.convert_map_from(Z) - sage: TestSuite(iota).run(skip=['_test_category']) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings + sage: Z = S.center() # optional - sage.rings.finite_rings + sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings + sage: TestSuite(iota).run(skip=['_test_category']) # optional - sage.rings.finite_rings """ def __init__(self, domain, codomain, embed, order): r""" @@ -465,10 +466,10 @@ def __init__(self, domain, codomain, embed, order): EXAMPLES:: - sage: k. = GF(5^3) - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) - sage: Z = S.center() - sage: S.convert_map_from(Z) # indirect doctest + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings + sage: Z = S.center() # optional - sage.rings.finite_rings + sage: S.convert_map_from(Z) # indirect doctest # optional - sage.rings.finite_rings Embedding of the center of Ore Polynomial Ring in x over Finite Field in a of size 5^3 twisted by a |--> a^5 into this ring """ RingHomomorphism.__init__(self, Hom(domain, codomain)) @@ -483,13 +484,13 @@ def _repr_(self): EXAMPLES:: - sage: k. = GF(5^3) - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) - sage: Z = S.center() - sage: iota = S.convert_map_from(Z) - sage: iota + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings + sage: Z = S.center() # optional - sage.rings.finite_rings + sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings + sage: iota # optional - sage.rings.finite_rings Embedding of the center of Ore Polynomial Ring in x over Finite Field in a of size 5^3 twisted by a |--> a^5 into this ring - sage: iota._repr_() + sage: iota._repr_() # optional - sage.rings.finite_rings 'Embedding of the center of Ore Polynomial Ring in x over Finite Field in a of size 5^3 twisted by a |--> a^5 into this ring' """ return "Embedding of the center of %s into this ring" % self._codomain @@ -500,12 +501,12 @@ def _call_(self, x): TESTS:: - sage: k. = GF(5^3) - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) - sage: Z. = S.center() - sage: iota = S.convert_map_from(Z) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings + sage: Z. = S.center() # optional - sage.rings.finite_rings + sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings - sage: iota(z) + sage: iota(z) # optional - sage.rings.finite_rings x^3 """ k = self._codomain.base_ring() @@ -521,17 +522,17 @@ def _richcmp_(self, right, op): TESTS:: - sage: k. = GF(5^3) - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) - sage: Z = S.center() - sage: iota = S.convert_map_from(Z) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings + sage: Z = S.center() # optional - sage.rings.finite_rings + sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings - sage: i = loads(dumps(iota)) - sage: i == iota + sage: i = loads(dumps(iota)) # optional - sage.rings.finite_rings + sage: i == iota # optional - sage.rings.finite_rings True - sage: i != iota + sage: i != iota # optional - sage.rings.finite_rings False - sage: i is iota + sage: i is iota # optional - sage.rings.finite_rings False """ if op == op_EQ: @@ -546,12 +547,12 @@ def section(self): EXAMPLES:: - sage: k. = GF(5^3) - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) - sage: Z = S.center() - sage: iota = S.convert_map_from(Z) - sage: sigma = iota.section() - sage: sigma(x^3) + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings + sage: Z = S.center() # optional - sage.rings.finite_rings + sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings + sage: sigma = iota.section() # optional - sage.rings.finite_rings + sage: sigma(x^3) # optional - sage.rings.finite_rings z """ return self._section @@ -573,26 +574,26 @@ def __init__(self, base_ring, morphism, derivation, name, sparse, category=None) TESTS:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x', Frob]; S + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x', Frob]; S # optional - sage.rings.finite_rings Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 - sage: S.category() + sage: S.category() # optional - sage.rings.finite_rings Category of algebras over Finite Field in t of size 5^3 - sage: TestSuite(S).run() + sage: TestSuite(S).run() # optional - sage.rings.finite_rings We check that a call to the method :meth:`sage.rings.polynomial.skew_polynomial_finite_order.SkewPolynomial_finite_order.is_central` does not affect the behaviour of default central variable names:: - sage: k. = GF(7^4) - sage: phi = k.frobenius_endomorphism() - sage: S. = k['x', phi] - sage: (x^4).is_central() + sage: k. = GF(7^4) # optional - sage.rings.finite_rings + sage: phi = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x', phi] # optional - sage.rings.finite_rings + sage: (x^4).is_central() # optional - sage.rings.finite_rings True - sage: Z. = S.center() - sage: S.center() is Z + sage: Z. = S.center() # optional - sage.rings.finite_rings + sage: S.center() is Z # optional - sage.rings.finite_rings True """ if self.Element is None: @@ -638,55 +639,57 @@ def center(self, name=None, names=None, default=False): EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x',Frob]; S - Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x',Frob]; S # optional - sage.rings.finite_rings + Ore Polynomial Ring in x over Finite Field in t of size 5^3 + twisted by t |--> t^5 - sage: Z = S.center(); Z + sage: Z = S.center(); Z # optional - sage.rings.finite_rings Univariate Polynomial Ring in z over Finite Field of size 5 - sage: Z.gen() + sage: Z.gen() # optional - sage.rings.finite_rings z We can pass in another variable name:: - sage: S.center(name='y') + sage: S.center(name='y') # optional - sage.rings.finite_rings Univariate Polynomial Ring in y over Finite Field of size 5 or use the bracket notation:: - sage: Zy. = S.center(); Zy + sage: Zy. = S.center(); Zy # optional - sage.rings.finite_rings Univariate Polynomial Ring in y over Finite Field of size 5 - sage: y.parent() is Zy + sage: y.parent() is Zy # optional - sage.rings.finite_rings True A coercion map from the center to the skew polynomial ring is set:: - sage: S.has_coerce_map_from(Zy) + sage: S.has_coerce_map_from(Zy) # optional - sage.rings.finite_rings True - sage: P = y + x; P + sage: P = y + x; P # optional - sage.rings.finite_rings x^3 + x - sage: P.parent() - Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 - sage: P.parent() is S + sage: P.parent() # optional - sage.rings.finite_rings + Ore Polynomial Ring in x over Finite Field in t of size 5^3 + twisted by t |--> t^5 + sage: P.parent() is S # optional - sage.rings.finite_rings True together with a conversion map in the reverse direction:: - sage: Zy(x^6 + 2*x^3 + 3) + sage: Zy(x^6 + 2*x^3 + 3) # optional - sage.rings.finite_rings y^2 + 2*y + 3 - sage: Zy(x^2) + sage: Zy(x^2) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: x^2 is not in the center Two different skew polynomial rings can share the same center:: - sage: S1. = k['x1', Frob] - sage: S2. = k['x2', Frob] - sage: S1.center() is S2.center() + sage: S1. = k['x1', Frob] # optional - sage.rings.finite_rings + sage: S2. = k['x2', Frob] # optional - sage.rings.finite_rings + sage: S1.center() is S2.center() # optional - sage.rings.finite_rings True .. RUBRIC:: About the default name of the central variable @@ -696,32 +699,32 @@ 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: K. = GF(11^3) - sage: phi = K.frobenius_endomorphism() - sage: A. = K['X', phi] + sage: K. = GF(11^3) # optional - sage.rings.finite_rings + sage: phi = K.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: A. = K['X', phi] # optional - sage.rings.finite_rings - sage: C. = A.center() # first call - sage: C + sage: C. = A.center() # first call # optional - sage.rings.finite_rings + sage: C # optional - sage.rings.finite_rings Univariate Polynomial Ring in u over Finite Field of size 11 - sage: A.center() # second call: the variable name is still u + sage: A.center() # second call: the variable name is still u # optional - sage.rings.finite_rings Univariate Polynomial Ring in u over Finite Field of size 11 - sage: A.center() is C + sage: A.center() is C # optional - sage.rings.finite_rings True We can update the default variable name by passing in the argument ``default=True``:: - sage: D. = A.center(default=True) - sage: D + sage: D. = A.center(default=True) # optional - sage.rings.finite_rings + sage: D # optional - sage.rings.finite_rings Univariate Polynomial Ring in v over Finite Field of size 11 - sage: A.center() + sage: A.center() # optional - sage.rings.finite_rings Univariate Polynomial Ring in v over Finite Field of size 11 - sage: A.center() is D + sage: A.center() is D # optional - sage.rings.finite_rings True TESTS:: - sage: C. = S.center() + sage: C. = S.center() # optional - sage.rings.finite_rings Traceback (most recent call last): ... IndexError: the number of names must equal the number of generators @@ -793,9 +796,9 @@ def __init__(self, base_ring, morphism, derivation, names, sparse, category=None EXAMPLES:: - sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() - sage: T. = k['x', Frob]; T + sage: k. = GF(5^3) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: T. = k['x', Frob]; T # optional - sage.rings.finite_rings Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 """ if self.Element is None: @@ -820,21 +823,21 @@ def _new_retraction_map(self, seed=None): TESTS:: - sage: k. = GF(11^4) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x', Frob] + sage: k. = GF(11^4) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x', Frob] # optional - sage.rings.finite_rings - sage: S._new_retraction_map() - sage: S._matrix_retraction # random + sage: S._new_retraction_map() # optional - sage.rings.finite_rings + sage: S._matrix_retraction # random # optional - sage.rings.finite_rings [ 9 4 10 4] We can specify a seed:: - sage: S._new_retraction_map(seed=a) - sage: S._matrix_retraction + sage: S._new_retraction_map(seed=a) # optional - sage.rings.finite_rings + sage: S._matrix_retraction # optional - sage.rings.finite_rings [ 0 6 3 10] - sage: S._new_retraction_map(seed=a) - sage: S._matrix_retraction + sage: S._new_retraction_map(seed=a) # optional - sage.rings.finite_rings + sage: S._matrix_retraction # optional - sage.rings.finite_rings [ 0 6 3 10] """ k = self.base_ring() @@ -872,27 +875,27 @@ def _retraction(self, x, newmap=False, seed=None): TESTS:: - sage: k. = GF(11^4) - sage: Frob = k.frobenius_endomorphism() - sage: S. = k['x', Frob] + sage: k. = GF(11^4) # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings + sage: S. = k['x', Frob] # optional - sage.rings.finite_rings - sage: S._retraction(a) # random + sage: S._retraction(a) # random # optional - sage.rings.finite_rings 6 Note that a retraction map has been automatically created:: - sage: S._matrix_retraction # random + sage: S._matrix_retraction # random # optional - sage.rings.finite_rings [ 0 6 3 10] If we call again the method :meth:`_retraction`, the same retraction map is used:: - sage: S._retraction(a) # random + sage: S._retraction(a) # random # optional - sage.rings.finite_rings 6 We can specify a seed:: - sage: S._retraction(a^2, seed=a) # random + sage: S._retraction(a^2, seed=a) # random # optional - sage.rings.finite_rings 10 """ # Better to return the retraction map but more difficult diff --git a/src/sage/rings/polynomial/symmetric_ideal.py b/src/sage/rings/polynomial/symmetric_ideal.py index dfe66e9f2f5..4905e5d87a6 100644 --- a/src/sage/rings/polynomial/symmetric_ideal.py +++ b/src/sage/rings/polynomial/symmetric_ideal.py @@ -23,12 +23,13 @@ Note that ``I`` is not a symmetric Groebner basis:: - sage: G = R*I.groebner_basis() - sage: G - Symmetric Ideal (x_1^2 + x_1, x_2 - x_1) of Infinite polynomial ring in x over Rational Field - sage: Q = R.quotient(G) - sage: p = x[3]*x[1]+x[2]^2+3 - sage: Q(p) + sage: G = R * I.groebner_basis() # optional - sage.combinat + sage: G # optional - sage.combinat + Symmetric Ideal (x_1^2 + x_1, x_2 - x_1) of + Infinite polynomial ring in x over Rational Field + sage: Q = R.quotient(G) # optional - sage.combinat + sage: p = x[3]*x[1] + x[2]^2 + 3 # optional - sage.combinat + sage: Q(p) # optional - sage.combinat -2*x_1 + 3 By the second generator of ``G``, variable `x_n` is equal to `x_1` for @@ -36,7 +37,7 @@ equal to `x_1` in ``Q``. Indeed, we have :: - sage: Q(p)*x[2] == Q(p)*x[1]*x[3]*x[5] + sage: Q(p)*x[2] == Q(p)*x[1]*x[3]*x[5] # optional - sage.combinat True """ @@ -109,7 +110,7 @@ class SymmetricIdeal(Ideal_generic): EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: I = [x[1]*y[2]*y[1] + 2*x[1]*y[2]]*X + sage: I = [x[1]*y[2]*y[1] + 2*x[1]*y[2]] * X sage: I == loads(dumps(I)) True sage: latex(I) @@ -117,25 +118,26 @@ class SymmetricIdeal(Ideal_generic): The default ordering is lexicographic. We now compute a Groebner basis:: - sage: J = I.groebner_basis() ; J # about 3 seconds - [x_1*y_2*y_1 + 2*x_1*y_2, x_2*y_2*y_1 + 2*x_2*y_1, x_2*x_1*y_1^2 + 2*x_2*x_1*y_1, x_2*x_1*y_2 - x_2*x_1*y_1] + sage: J = I.groebner_basis(); J # about 3 seconds # optional - sage.combinat + [x_1*y_2*y_1 + 2*x_1*y_2, x_2*y_2*y_1 + 2*x_2*y_1, + x_2*x_1*y_1^2 + 2*x_2*x_1*y_1, x_2*x_1*y_2 - x_2*x_1*y_1] Note that even though the symmetric ideal can be generated by a single polynomial, its reduced symmetric Groebner basis comprises four elements. Ideal membership in ``I`` can now be tested by commuting symmetric reduction modulo ``J``:: - sage: I.reduce(J) + sage: I.reduce(J) # optional - sage.combinat Symmetric Ideal (0) of Infinite polynomial ring in x, y over Rational Field The Groebner basis is not point-wise invariant under permutation:: - sage: P=Permutation([2, 1]) - sage: J[2] + sage: P = Permutation([2, 1]) # optional - sage.combinat + sage: J[2] # optional - sage.combinat x_2*x_1*y_1^2 + 2*x_2*x_1*y_1 - sage: J[2]^P + sage: J[2]^P # optional - sage.combinat x_2*x_1*y_2^2 + 2*x_2*x_1*y_2 - sage: J[2]^P in J + sage: J[2]^P in J # optional - sage.combinat False However, any element of ``J`` has symmetric reduction zero even @@ -143,13 +145,13 @@ class SymmetricIdeal(Ideal_generic): permutations involve higher variable indices than the ones occurring in ``J``:: - sage: [[(p^P).reduce(J) for p in J] for P in Permutations(3)] + sage: [[(p^P).reduce(J) for p in J] for P in Permutations(3)] # optional - sage.combinat [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] Since ``I`` is not a Groebner basis, it is no surprise that it cannot detect ideal membership:: - sage: [p.reduce(I) for p in J] + sage: [p.reduce(I) for p in J] # optional - sage.combinat [0, x_2*y_2*y_1 + 2*x_2*y_1, x_2*x_1*y_1^2 + 2*x_2*x_1*y_1, x_2*x_1*y_2 - x_2*x_1*y_1] Note that we give no guarantee that the computation of a symmetric @@ -161,12 +163,14 @@ class SymmetricIdeal(Ideal_generic): product is indeed the product of ideals in the mathematical sense. :: - sage: I=X*(x[1]) - sage: I*I - Symmetric Ideal (x_1^2, x_2*x_1) of Infinite polynomial ring in x, y over Rational Field - sage: I^3 - Symmetric Ideal (x_1^3, x_2*x_1^2, x_2^2*x_1, x_3*x_2*x_1) of Infinite polynomial ring in x, y over Rational Field - sage: I*I == X*(x[1]^2) + sage: I = X * (x[1]) + sage: I * I # optional - sage.combinat + Symmetric Ideal (x_1^2, x_2*x_1) of + Infinite polynomial ring in x, y over Rational Field + sage: I^3 # optional - sage.combinat + Symmetric Ideal (x_1^3, x_2*x_1^2, x_2^2*x_1, x_3*x_2*x_1) of + Infinite polynomial ring in x, y over Rational Field + sage: I * I == X * (x[1]^2) # optional - sage.combinat False """ @@ -182,12 +186,12 @@ def __init__(self, ring, gens, coerce=True): EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: I=X*(x[1]^2+y[2]^2,x[1]*x[2]*y[3]+x[1]*y[4]) # indirect doctest + sage: I = X * (x[1]^2 + y[2]^2, x[1]*x[2]*y[3] + x[1]*y[4]) # indirect doctest sage: I Symmetric Ideal (x_1^2 + y_2^2, x_2*x_1*y_3 + x_1*y_4) of Infinite polynomial ring in x, y over Rational Field sage: from sage.rings.polynomial.symmetric_ideal import SymmetricIdeal - sage: J=SymmetricIdeal(X,[x[1]^2+y[2]^2,x[1]*x[2]*y[3]+x[1]*y[4]]) - sage: I==J + sage: J = SymmetricIdeal(X, [x[1]^2 + y[2]^2, x[1]*x[2]*y[3] + x[1]*y[4]]) + sage: I == J True """ @@ -198,7 +202,7 @@ def __repr__(self): EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: I=X*(x[1]^2+y[2]^2,x[1]*x[2]*y[3]+x[1]*y[4]) + sage: I = X * (x[1]^2 + y[2]^2, x[1]*x[2]*y[3] + x[1]*y[4]) sage: I # indirect doctest Symmetric Ideal (x_1^2 + y_2^2, x_2*x_1*y_3 + x_1*y_4) of Infinite polynomial ring in x, y over Rational Field @@ -211,7 +215,7 @@ def _latex_(self): sage: from sage.misc.latex import latex sage: X. = InfinitePolynomialRing(QQ) - sage: I=X*(x[1]*y[2]) + sage: I = X * (x[1]*y[2]) sage: latex(I) # indirect doctest \left(x_{1} y_{2}\right)\Bold{Q}[x_{\ast}, y_{\ast}][\mathfrak{S}_{\infty}] @@ -231,10 +235,11 @@ def _contains_(self, p): sage: R. = InfinitePolynomialRing(QQ) sage: I = R.ideal([x[1]*x[2] + x[3]]) - sage: I = R*I.groebner_basis() - sage: I - Symmetric Ideal (x_1^2 + x_1, x_2 - x_1) of Infinite polynomial ring in x over Rational Field - sage: x[2]^2 + x[3] in I # indirect doctest + sage: I = R * I.groebner_basis() # optional - sage.combinat + sage: I # optional - sage.combinat + Symmetric Ideal (x_1^2 + x_1, x_2 - x_1) of + Infinite polynomial ring in x over Rational Field + sage: x[2]^2 + x[3] in I # indirect doctest # optional - sage.combinat True """ try: @@ -254,8 +259,8 @@ def __mul__(self, other): EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: I=X*(x[1]) - sage: I*I # indirect doctest + sage: I = X * (x[1]) + sage: I*I # indirect doctest # optional - sage.combinat Symmetric Ideal (x_1^2, x_2*x_1) of Infinite polynomial ring in x over Rational Field """ @@ -283,7 +288,7 @@ def __mul__(self, other): def __pow__(self, n): """ - Raise self to some power. + Raise ``self`` to some power. Since the generators of a symmetric ideal are subject to a permutation action, they in fact stand for a set of @@ -294,8 +299,8 @@ def __pow__(self, n): EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: I=X*(x[1]) - sage: I^2 # indirect doctest + sage: I = X * (x[1]) + sage: I^2 # indirect doctest # optional - sage.combinat Symmetric Ideal (x_1^2, x_2*x_1) of Infinite polynomial ring in x over Rational Field """ @@ -306,7 +311,7 @@ def __pow__(self, n): def is_maximal(self): """ - Answers whether self is a maximal ideal. + Answer whether ``self`` is a maximal ideal. ASSUMPTION: @@ -314,30 +319,30 @@ def is_maximal(self): NOTE: - It is not checked whether self is in fact a symmetric Groebner + It is not checked whether ``self`` is in fact a symmetric Groebner basis. A wrong answer can result if this assumption does not - hold. A ``NotImplementedError`` is raised if the base ring is not + hold. A :class:`NotImplementedError` is raised if the base ring is not a field, since symmetric Groebner bases are not implemented in this setting. EXAMPLES:: sage: R. = InfinitePolynomialRing(QQ) - sage: I = R.ideal([x[1]+y[2], x[2]-y[1]]) - sage: I = R*I.groebner_basis() - sage: I - Symmetric Ideal (y_1, x_1) of Infinite polynomial ring in x, y over Rational Field - sage: I = R.ideal([x[1]+y[2], x[2]-y[1]]) - sage: I.is_maximal() + sage: I = R.ideal([x[1] + y[2], x[2] - y[1]]) + sage: I = R * I.groebner_basis(); I # optional - sage.combinat + Symmetric Ideal (y_1, x_1) of + Infinite polynomial ring in x, y over Rational Field + sage: I = R.ideal([x[1] + y[2], x[2] - y[1]]) # optional - sage.combinat + sage: I.is_maximal() # optional - sage.combinat False The preceding answer is wrong, since it is not the case that ``I`` is given by a symmetric Groebner basis:: - sage: I = R*I.groebner_basis() - sage: I - Symmetric Ideal (y_1, x_1) of Infinite polynomial ring in x, y over Rational Field - sage: I.is_maximal() + sage: I = R * I.groebner_basis(); I # optional - sage.combinat + Symmetric Ideal (y_1, x_1) of + Infinite polynomial ring in x, y over Rational Field + sage: I.is_maximal() # optional - sage.combinat True """ @@ -353,8 +358,8 @@ def is_maximal(self): def reduce(self, I, tailreduce=False): r""" - Symmetric reduction of self by another Symmetric Ideal or list of Infinite Polynomials, - or symmetric reduction of a given Infinite Polynomial by self. + Symmetric reduction of ``self`` by another Symmetric Ideal or list of Infinite Polynomials, + or symmetric reduction of a given Infinite Polynomial by ``self``. INPUT: @@ -377,14 +382,15 @@ def reduce(self, I, tailreduce=False): not diminish the variable indices occurring in `N` and preserves their order, so that there is some term `T\in X` with `T N^P = M`. If there is no such permutation, return `p` - 3. Replace `p` by `p-T q^P` and continue with step 1. + 3. Replace `p` by `p - T q^P` and continue with step 1. EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: I = X*(y[1]^2*y[3]+y[1]*x[3]^2) + sage: I = X * (y[1]^2*y[3] + y[1]*x[3]^2) sage: I.reduce([x[1]^2*y[2]]) - Symmetric Ideal (x_3^2*y_1 + y_3*y_1^2) of Infinite polynomial ring in x, y over Rational Field + Symmetric Ideal (x_3^2*y_1 + y_3*y_1^2) of + Infinite polynomial ring in x, y over Rational Field The preceding is correct, since any permutation that turns ``x[1]^2*y[2]`` into a factor of ``x[3]^2*y[2]`` interchanges @@ -392,18 +398,21 @@ def reduce(self, I, tailreduce=False): reduction by ``x[2]^2*y[1]`` works, since one can change variable index 1 into 2 and 2 into 3:: - sage: I.reduce([x[2]^2*y[1]]) - Symmetric Ideal (y_3*y_1^2) of Infinite polynomial ring in x, y over Rational Field + sage: I.reduce([x[2]^2*y[1]]) # optional - sage.combinat + Symmetric Ideal (y_3*y_1^2) of + Infinite polynomial ring in x, y over Rational Field The next example shows that tail reduction is not done, unless it is explicitly advised. The input can also be a symmetric ideal:: - sage: J = (y[2])*X + sage: J = (y[2]) * X sage: I.reduce(J) - Symmetric Ideal (x_3^2*y_1 + y_3*y_1^2) of Infinite polynomial ring in x, y over Rational Field - sage: I.reduce(J, tailreduce=True) - Symmetric Ideal (x_3^2*y_1) of Infinite polynomial ring in x, y over Rational Field + Symmetric Ideal (x_3^2*y_1 + y_3*y_1^2) of + Infinite polynomial ring in x, y over Rational Field + sage: I.reduce(J, tailreduce=True) # optional - sage.combinat + Symmetric Ideal (x_3^2*y_1) of + Infinite polynomial ring in x, y over Rational Field """ if I in self.ring(): # we want to reduce a polynomial by self @@ -419,15 +428,15 @@ def reduce(self, I, tailreduce=False): def interreduction(self, tailreduce=True, sorted=False, report=None, RStrat=None): """ - Return symmetrically interreduced form of self + Return symmetrically interreduced form of ``self``. INPUT: - - ``tailreduce`` -- (bool, default ``True``) If True, the + - ``tailreduce`` -- (bool, default ``True``) If ``True``, the interreduction is also performed on the non-leading monomials. - - ``sorted`` -- (bool, default ``False``) If True, it is assumed that the - generators of self are already increasingly sorted. - - ``report`` -- (object, default ``None``) If not None, some information on the + - ``sorted`` -- (bool, default ``False``) If ``True``, it is assumed that the + generators of ``self`` are already increasingly sorted. + - ``report`` -- (object, default ``None``) If not ``None``, some information on the progress of computation is printed - ``RStrat`` -- (:class:`~sage.rings.polynomial.symmetric_reduction.SymmetricReductionStrategy`, default ``None``) A reduction strategy to which the polynomials resulting @@ -437,28 +446,30 @@ def interreduction(self, tailreduce=True, sorted=False, report=None, RStrat=None OUTPUT: - A Symmetric Ideal J (sorted list of generators) coinciding - with self as an ideal, so that any generator is symmetrically + A Symmetric Ideal `J` (sorted list of generators) coinciding + with ``self`` as an ideal, so that any generator is symmetrically reduced w.r.t. the other generators. Note that the leading coefficients of the result are not necessarily 1. EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: I=X*(x[1]+x[2],x[1]*x[2]) + sage: I = X * (x[1] + x[2], x[1]*x[2]) sage: I.interreduction() - Symmetric Ideal (-x_1^2, x_2 + x_1) of Infinite polynomial ring in x over Rational Field + Symmetric Ideal (-x_1^2, x_2 + x_1) of + Infinite polynomial ring in x over Rational Field Here, we show the ``report`` option:: - sage: I.interreduction(report=True) + sage: I.interreduction(report=True) # optional - sage.combinat Symmetric interreduction [1/2] > [2/2] :> [1/2] > [2/2] T[1]> > - Symmetric Ideal (-x_1^2, x_2 + x_1) of Infinite polynomial ring in x over Rational Field + Symmetric Ideal (-x_1^2, x_2 + x_1) of + Infinite polynomial ring in x over Rational Field ``[m/n]`` indicates that polynomial number ``m`` is considered and the total number of polynomials under consideration is @@ -472,13 +483,14 @@ def interreduction(self, tailreduce=True, sorted=False, report=None, RStrat=None sage: R = SymmetricReductionStrategy(X) sage: R Symmetric Reduction Strategy in Infinite polynomial ring in x over Rational Field - sage: I.interreduction(RStrat=R) - Symmetric Ideal (-x_1^2, x_2 + x_1) of Infinite polynomial ring in x over Rational Field + sage: I.interreduction(RStrat=R) # optional - sage.combinat + Symmetric Ideal (-x_1^2, x_2 + x_1) of + Infinite polynomial ring in x over Rational Field sage: R Symmetric Reduction Strategy in Infinite polynomial ring in x over Rational Field, modulo x_1^2, x_2 + x_1 - sage: R = SymmetricReductionStrategy(X,[x[1]^2]) + sage: R = SymmetricReductionStrategy(X, [x[1]^2]) sage: I.interreduction(RStrat=R) Symmetric Ideal (x_2 + x_1) of Infinite polynomial ring in x over Rational Field @@ -560,8 +572,8 @@ def interreduced_basis(self): EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: I=X*(x[1]+x[2],x[1]*x[2]) - sage: I.interreduced_basis() + sage: I = X * (x[1] + x[2], x[1]*x[2]) + sage: I.interreduced_basis() # optional - sage.combinat [-x_1^2, x_2 + x_1] """ @@ -569,7 +581,7 @@ def interreduced_basis(self): def symmetrisation(self, N=None, tailreduce=False, report=None, use_full_group=False): """ - Apply permutations to the generators of self and interreduce + Apply permutations to the generators of ``self`` and interreduce. INPUT: @@ -581,8 +593,8 @@ def symmetrisation(self, N=None, tailreduce=False, report=None, use_full_group=F tail reductions. - ``report`` -- (object, default ``None``) If not ``None``, report on the progress of computations. - - ``use_full_group`` (optional) -- If True, apply *all* elements of - `Sym(N)` to the generators of self (this is what [AB2008]_ + - ``use_full_group`` (optional) -- If ``True``, apply *all* elements of + `Sym(N)` to the generators of ``self`` (this is what [AB2008]_ originally suggests). The default is to apply all elementary transpositions to the generators of ``self.squeezed()``, interreduce, and repeat until the result stabilises, which is @@ -592,7 +604,7 @@ def symmetrisation(self, N=None, tailreduce=False, report=None, use_full_group=F OUTPUT: A symmetrically interreduced symmetric ideal with respect to - which any `Sym(N)`-translate of a generator of self is + which any `Sym(N)`-translate of a generator of ``self`` is symmetrically reducible, where by default ``N`` is the maximal variable index that occurs in the generators of ``self.interreduction().squeezed()``. @@ -607,12 +619,13 @@ def symmetrisation(self, N=None, tailreduce=False, report=None, use_full_group=F EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: I = X*(x[1]+x[2], x[1]*x[2]) - sage: I.symmetrisation() - Symmetric Ideal (-x_1^2, x_2 + x_1) of Infinite polynomial ring in x over Rational Field - sage: I.symmetrisation(N=3) + sage: I = X * (x[1] + x[2], x[1]*x[2]) + sage: I.symmetrisation() # optional - sage.combinat + Symmetric Ideal (-x_1^2, x_2 + x_1) of + Infinite polynomial ring in x over Rational Field + sage: I.symmetrisation(N=3) # optional - sage.combinat Symmetric Ideal (-2*x_1) of Infinite polynomial ring in x over Rational Field - sage: I.symmetrisation(N=3, use_full_group=True) + sage: I.symmetrisation(N=3, use_full_group=True) # optional - sage.combinat Symmetric Ideal (-2*x_1) of Infinite polynomial ring in x over Rational Field """ @@ -656,18 +669,18 @@ def symmetrisation(self, N=None, tailreduce=False, report=None, use_full_group=F def symmetric_basis(self): """ - A symmetrised generating set (type :class:`~sage.structure.sequence.Sequence`) of self. + A symmetrised generating set (type :class:`~sage.structure.sequence.Sequence`) of ``self``. This does essentially the same as :meth:`symmetrisation` with - the option 'tailreduce', and it returns a + the option ``tailreduce``, and it returns a :class:`~sage.structure.sequence.Sequence` rather than a :class:`~sage.rings.polynomial.symmetric_ideal.SymmetricIdeal`. EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: I = X*(x[1]+x[2], x[1]*x[2]) - sage: I.symmetric_basis() + sage: I = X * (x[1] + x[2], x[1]*x[2]) + sage: I.symmetric_basis() # optional - sage.combinat [x_1^2, x_2 + x_1] """ @@ -675,16 +688,17 @@ def symmetric_basis(self): def normalisation(self): """ - Return an ideal that coincides with self, so that all generators have leading coefficient 1. + Return an ideal that coincides with ``self``, so that all generators have leading coefficient 1. Possibly occurring zeroes are removed from the generator list. EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: I = X*(1/2*x[1]+2/3*x[2], 0, 4/5*x[1]*x[2]) + sage: I = X*(1/2*x[1] + 2/3*x[2], 0, 4/5*x[1]*x[2]) sage: I.normalisation() - Symmetric Ideal (x_2 + 3/4*x_1, x_2*x_1) of Infinite polynomial ring in x over Rational Field + Symmetric Ideal (x_2 + 3/4*x_1, x_2*x_1) of + Infinite polynomial ring in x over Rational Field """ return SymmetricIdeal(self.ring(), [X/X.lc() for X in self.gens() if X._p!=0]) @@ -705,10 +719,11 @@ def squeezed(self): EXAMPLES:: - sage: X. = InfinitePolynomialRing(QQ,implementation='sparse') - sage: I = X*(x[1000]*y[100],x[50]*y[1000]) + sage: X. = InfinitePolynomialRing(QQ, implementation='sparse') + sage: I = X * (x[1000]*y[100], x[50]*y[1000]) sage: I.squeezed() - Symmetric Ideal (x_2*y_1, x_1*y_2) of Infinite polynomial ring in x, y over Rational Field + Symmetric Ideal (x_2*y_1, x_1*y_2) of + Infinite polynomial ring in x, y over Rational Field """ return SymmetricIdeal(self.ring(), [X.squeezed() for X in self.gens()]) @@ -720,7 +735,7 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= INPUT: - - ``tailreduce`` -- (bool, default ``False``) If True, use tail reduction + - ``tailreduce`` -- (bool, default ``False``) If ``True``, use tail reduction in intermediate computations - ``reduced`` -- (bool, default ``True``) If ``True``, return the reduced normalised symmetric Groebner basis. @@ -730,7 +745,7 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= progress of computation. - ``use_full_group`` -- (bool, default ``False``) If ``True`` then proceed as originally suggested by [AB2008]_. Our default method should be faster; see - :meth:`.symmetrisation` for more details. + :meth:`symmetrisation` for more details. The computation of symmetric Groebner bases also involves the computation of *classical* Groebner bases, i.e., of Groebner @@ -791,11 +806,11 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= EXAMPLES:: sage: X. = InfinitePolynomialRing(QQ) - sage: I1 = X*(x[1]+x[2],x[1]*x[2]) - sage: I1.groebner_basis() + sage: I1 = X * (x[1] + x[2], x[1]*x[2]) + sage: I1.groebner_basis() # optional - sage.combinat [x_1] - sage: I2 = X*(y[1]^2*y[3]+y[1]*x[3]) - sage: I2.groebner_basis() + sage: I2 = X * (y[1]^2*y[3] + y[1]*x[3]) + sage: I2.groebner_basis() # optional - sage.combinat [x_1*y_2 + y_2^2*y_1, x_2*y_1 + y_2*y_1^2] Note that a symmetric Groebner basis of a principal ideal is @@ -805,13 +820,13 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= and Hillar, the result is the same, but the computation takes much longer:: - sage: I2.groebner_basis(use_full_group=True) + sage: I2.groebner_basis(use_full_group=True) # optional - sage.combinat [x_1*y_2 + y_2^2*y_1, x_2*y_1 + y_2*y_1^2] Last, we demonstrate how the report on the progress of computations looks like:: - sage: I1.groebner_basis(report=True, reduced=True) + sage: I1.groebner_basis(report=True, reduced=True) # optional - sage.combinat Symmetric interreduction [1/2] > [2/2] :> @@ -879,12 +894,12 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= [x_1] The Aschenbrenner-Hillar algorithm is only guaranteed to work - if the base ring is a field. So, we raise a TypeError if this + if the base ring is a field. So, we raise a :class:`TypeError` if this is not the case:: sage: R. = InfinitePolynomialRing(ZZ) - sage: I = R*[x[1]+x[2],y[1]] - sage: I.groebner_basis() + sage: I = R * [x[1] + x[2], y[1]] + sage: I.groebner_basis() # optional - sage.combinat Traceback (most recent call last): ... TypeError: The base ring (= Integer Ring) must be a field @@ -893,14 +908,19 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= In an earlier version, the following examples failed:: - sage: X. = InfinitePolynomialRing(GF(5),order='degrevlex') - sage: I = ['-2*y_0^2 + 2*z_0^2 + 1', '-y_0^2 + 2*y_0*z_0 - 2*z_0^2 - 2*z_0 - 1', 'y_0*z_0 + 2*z_0^2 - 2*z_0 - 1', 'y_0^2 + 2*y_0*z_0 - 2*z_0^2 + 2*z_0 - 2', '-y_0^2 - 2*y_0*z_0 - z_0^2 + y_0 - 1']*X - sage: I.groebner_basis() + sage: X. = InfinitePolynomialRing(GF(5), order='degrevlex') # optional - sage.rings.finite_rings + sage: I = ['-2*y_0^2 + 2*z_0^2 + 1', + ....: '-y_0^2 + 2*y_0*z_0 - 2*z_0^2 - 2*z_0 - 1', + ....: 'y_0*z_0 + 2*z_0^2 - 2*z_0 - 1', + ....: 'y_0^2 + 2*y_0*z_0 - 2*z_0^2 + 2*z_0 - 2', + ....: '-y_0^2 - 2*y_0*z_0 - z_0^2 + y_0 - 1'] * X + sage: I.groebner_basis() # optional - sage.combinat sage.rings.finite_rings [1] - sage: Y. = InfinitePolynomialRing(GF(3), order='degrevlex', implementation='sparse') - sage: I = ['-y_3']*Y - sage: I.groebner_basis() + sage: Y. = InfinitePolynomialRing(GF(3), order='degrevlex', # optional - sage.rings.finite_rings + ....: implementation='sparse') + sage: I = ['-y_3'] * Y + sage: I.groebner_basis() # optional - sage.combinat sage.rings.finite_rings [y_1] """ diff --git a/src/sage/rings/polynomial/symmetric_reduction.pyx b/src/sage/rings/polynomial/symmetric_reduction.pyx index 25213e1318a..c8384b72977 100644 --- a/src/sage/rings/polynomial/symmetric_reduction.pyx +++ b/src/sage/rings/polynomial/symmetric_reduction.pyx @@ -51,7 +51,7 @@ EXAMPLES: First, we create an infinite polynomial ring and one of its elements:: sage: X. = InfinitePolynomialRing(QQ) - sage: p = y[1]*y[3]+y[1]^2*x[3] + sage: p = y[1]*y[3] + y[1]^2*x[3] We want to symmetrically reduce it by another polynomial. So, we put this other polynomial into a list and create a Symmetric Reduction @@ -60,7 +60,8 @@ Strategy object:: sage: from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy sage: S = SymmetricReductionStrategy(X, [y[2]^2*x[1]]) sage: S - Symmetric Reduction Strategy in Infinite polynomial ring in x, y over Rational Field, modulo + Symmetric Reduction Strategy in + Infinite polynomial ring in x, y over Rational Field, modulo x_1*y_2^2 sage: S.reduce(p) x_3*y_1^2 + y_3*y_1 @@ -74,18 +75,19 @@ change variable index 1 into 2 and 2 into 3. So, we add this to sage: S.add_generator(y[1]^2*x[2]) sage: S - Symmetric Reduction Strategy in Infinite polynomial ring in x, y over Rational Field, modulo + Symmetric Reduction Strategy in + Infinite polynomial ring in x, y over Rational Field, modulo x_2*y_1^2, x_1*y_2^2 - sage: S.reduce(p) + sage: S.reduce(p) # optional - sage.combinat y_3*y_1 The next example shows that tail reduction is not done, unless it is explicitly advised:: - sage: S.reduce(x[3] + 2*x[2]*y[1]^2 + 3*y[2]^2*x[1]) + sage: S.reduce(x[3] + 2*x[2]*y[1]^2 + 3*y[2]^2*x[1]) # optional - sage.combinat x_3 + 2*x_2*y_1^2 + 3*x_1*y_2^2 - sage: S.tailreduce(x[3] + 2*x[2]*y[1]^2 + 3*y[2]^2*x[1]) + sage: S.tailreduce(x[3] + 2*x[2]*y[1]^2 + 3*y[2]^2*x[1]) # optional - sage.combinat x_3 However, it is possible to ask for tailreduction already when the @@ -93,11 +95,12 @@ Symmetric Reduction Strategy is created:: sage: S2 = SymmetricReductionStrategy(X, [y[2]^2*x[1],y[1]^2*x[2]], tailreduce=True) sage: S2 - Symmetric Reduction Strategy in Infinite polynomial ring in x, y over Rational Field, modulo + Symmetric Reduction Strategy in + Infinite polynomial ring in x, y over Rational Field, modulo x_2*y_1^2, x_1*y_2^2 with tailreduction - sage: S2.reduce(x[3] + 2*x[2]*y[1]^2 + 3*y[2]^2*x[1]) + sage: S2.reduce(x[3] + 2*x[2]*y[1]^2 + 3*y[2]^2*x[1]) # optional - sage.combinat x_3 """ @@ -144,7 +147,7 @@ cdef class SymmetricReductionStrategy: sage: S = SymmetricReductionStrategy(X, [y[2]^2*y[1],y[1]^2*y[2]], good_input=True) sage: S.reduce(y[3] + 2*y[2]*y[1]^2 + 3*y[2]^2*y[1]) y_3 + 3*y_2^2*y_1 + 2*y_2*y_1^2 - sage: S.tailreduce(y[3] + 2*y[2]*y[1]^2 + 3*y[2]^2*y[1]) + sage: S.tailreduce(y[3] + 2*y[2]*y[1]^2 + 3*y[2]^2*y[1]) # optional - sage.combinat y_3 """ @@ -265,7 +268,8 @@ cdef class SymmetricReductionStrategy: sage: from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy sage: S = SymmetricReductionStrategy(X, [y[2]^2*y[1],y[1]^2*y[2]]) sage: S - Symmetric Reduction Strategy in Infinite polynomial ring in y over Rational Field, modulo + Symmetric Reduction Strategy in + Infinite polynomial ring in y over Rational Field, modulo y_2*y_1^2, y_2^2*y_1 sage: S.gens() @@ -295,7 +299,8 @@ cdef class SymmetricReductionStrategy: sage: R = SymmetricReductionStrategy(X) sage: R.setgens(S.gens()) sage: R - Symmetric Reduction Strategy in Infinite polynomial ring in y over Rational Field, modulo + Symmetric Reduction Strategy in + Infinite polynomial ring in y over Rational Field, modulo y_2*y_1^2, y_2^2*y_1 sage: R.gens() is S.gens() @@ -316,7 +321,8 @@ cdef class SymmetricReductionStrategy: sage: from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy sage: S = SymmetricReductionStrategy(X, [y[2]^2*y[1],y[1]^2*y[2]]) sage: S - Symmetric Reduction Strategy in Infinite polynomial ring in y over Rational Field, modulo + Symmetric Reduction Strategy in + Infinite polynomial ring in y over Rational Field, modulo y_2*y_1^2, y_2^2*y_1 sage: S.reset() @@ -336,7 +342,7 @@ cdef class SymmetricReductionStrategy: sage: from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy sage: X. = InfinitePolynomialRing(QQ) - sage: S = SymmetricReductionStrategy(X, [y[2]^2*y[1],y[1]^2*y[2]], tailreduce=True) + sage: S = SymmetricReductionStrategy(X, [y[2]^2*y[1], y[1]^2*y[2]], tailreduce=True) sage: S # indirect doctest Symmetric Reduction Strategy in Infinite polynomial ring in x, y over Rational Field, modulo y_2*y_1^2, @@ -424,18 +430,21 @@ cdef class SymmetricReductionStrategy: sage: X. = InfinitePolynomialRing(QQ) sage: S = SymmetricReductionStrategy(X) sage: S - Symmetric Reduction Strategy in Infinite polynomial ring in x, y over Rational Field + Symmetric Reduction Strategy in + Infinite polynomial ring in x, y over Rational Field sage: S.add_generator(y[3] + y[1]*(x[3]+x[1])) sage: S - Symmetric Reduction Strategy in Infinite polynomial ring in x, y over Rational Field, modulo + Symmetric Reduction Strategy in + Infinite polynomial ring in x, y over Rational Field, modulo x_3*y_1 + x_1*y_1 + y_3 Note that the first added polynomial will be simplified when adding a suitable second polynomial:: - sage: S.add_generator(x[2]+x[1]) - sage: S - Symmetric Reduction Strategy in Infinite polynomial ring in x, y over Rational Field, modulo + sage: S.add_generator(x[2] + x[1]) # optional - sage.combinat + sage: S # optional - sage.combinat + Symmetric Reduction Strategy in + Infinite polynomial ring in x, y over Rational Field, modulo y_3, x_2 + x_1 @@ -443,17 +452,19 @@ cdef class SymmetricReductionStrategy: polynomial. This can be avoided by specifying the optional parameter 'good_input':: - sage: S.add_generator(y[2]+y[1]*x[2]) - sage: S - Symmetric Reduction Strategy in Infinite polynomial ring in x, y over Rational Field, modulo + sage: S.add_generator(y[2] + y[1]*x[2]) # optional - sage.combinat + sage: S # optional - sage.combinat + Symmetric Reduction Strategy in + Infinite polynomial ring in x, y over Rational Field, modulo y_3, x_1*y_1 - y_2, x_2 + x_1 - sage: S.reduce(x[3]+x[2]) + sage: S.reduce(x[3] + x[2]) # optional - sage.combinat -2*x_1 - sage: S.add_generator(x[3]+x[2], good_input=True) - sage: S - Symmetric Reduction Strategy in Infinite polynomial ring in x, y over Rational Field, modulo + sage: S.add_generator(x[3] + x[2], good_input=True) # optional - sage.combinat + sage: S # optional - sage.combinat + Symmetric Reduction Strategy in + Infinite polynomial ring in x, y over Rational Field, modulo y_3, x_3 + x_2, x_1*y_1 - y_2, @@ -528,7 +539,7 @@ cdef class SymmetricReductionStrategy: .. NOTE:: - If tail reduction shall be forced, use :meth:`.tailreduce`. + If tail reduction shall be forced, use :meth:`tailreduce`. EXAMPLES:: @@ -540,15 +551,18 @@ cdef class SymmetricReductionStrategy: sage: S.reduce(y[4]*x[1] + y[1]*x[4], notail=True) x_4*y_1 + x_1*y_4 - Last, we demonstrate the 'report' option:: + Last, we demonstrate the ``report`` option:: - sage: S = SymmetricReductionStrategy(X, [x[2]+y[1],x[2]*y[3]+x[1]*y[2]+y[4],y[3]+y[2]]) + sage: S = SymmetricReductionStrategy(X, [x[2] + y[1], + ....: x[2]*y[3] + x[1]*y[2] + y[4], + ....: y[3] + y[2]]) sage: S - Symmetric Reduction Strategy in Infinite polynomial ring in x, y over Rational Field, modulo + Symmetric Reduction Strategy in + Infinite polynomial ring in x, y over Rational Field, modulo y_3 + y_2, x_2 + y_1, x_1*y_2 + y_4 - y_3*y_1 - sage: S.reduce(x[3] + x[1]*y[3] + x[1]*y[1],report=True) + sage: S.reduce(x[3] + x[1]*y[3] + x[1]*y[1], report=True) :::> x_1*y_1 + y_4 - y_3*y_1 - y_1 @@ -625,18 +639,21 @@ cdef class SymmetricReductionStrategy: sage: S = SymmetricReductionStrategy(X, [y[3]]) sage: S.reduce(y[4]*x[1] + y[1]*x[4]) x_4*y_1 + x_1*y_4 - sage: S.tailreduce(y[4]*x[1] + y[1]*x[4]) + sage: S.tailreduce(y[4]*x[1] + y[1]*x[4]) # optional - sage.combinat x_4*y_1 Last, we demonstrate the 'report' option:: - sage: S = SymmetricReductionStrategy(X, [x[2]+y[1],x[2]*x[3]+x[1]*y[2]+y[4],y[3]+y[2]]) + sage: S = SymmetricReductionStrategy(X, [x[2] + y[1], + ....: x[2]*x[3] + x[1]*y[2] + y[4], + ....: y[3] + y[2]]) sage: S - Symmetric Reduction Strategy in Infinite polynomial ring in x, y over Rational Field, modulo + Symmetric Reduction Strategy in + Infinite polynomial ring in x, y over Rational Field, modulo y_3 + y_2, x_2 + y_1, x_1*y_2 + y_4 + y_1^2 - sage: S.tailreduce(x[3] + x[1]*y[3] + x[1]*y[1],report=True) + sage: S.tailreduce(x[3] + x[1]*y[3] + x[1]*y[1], report=True) # optional - sage.combinat T[3]:::> T[3]:> x_1*y_1 - y_2 + y_1^2 - y_1 diff --git a/src/sage/rings/polynomial/term_order.py b/src/sage/rings/polynomial/term_order.py index bda1ec75a10..39c103e215d 100644 --- a/src/sage/rings/polynomial/term_order.py +++ b/src/sage/rings/polynomial/term_order.py @@ -272,22 +272,22 @@ EXAMPLES:: - sage: m = matrix(2,[2,3,0,1]); m + sage: m = matrix(2, [2,3,0,1]); m # optional - sage.modules [2 3] [0 1] - sage: T = TermOrder(m); T + sage: T = TermOrder(m); T # optional - sage.modules Matrix term order with matrix [2 3] [0 1] - sage: P. = PolynomialRing(QQ,2,order=T) - sage: P + sage: P. = PolynomialRing(QQ, 2, order=T) # optional - sage.modules + sage: P # optional - sage.modules Multivariate Polynomial Ring in a, b over Rational Field - sage: a > b + sage: a > b # optional - sage.modules False - sage: a^3 < b^2 + sage: a^3 < b^2 # optional - sage.modules True - sage: S = TermOrder('M(2,3,0,1)') - sage: T == S + sage: S = TermOrder('M(2,3,0,1)') # optional - sage.modules + sage: T == S # optional - sage.modules True Additionally all these monomial orders may be combined to product or block @@ -313,7 +313,7 @@ :: - sage: P. = PolynomialRing(QQ, 6,order='degrevlex(4),neglex(2)') + sage: P. = PolynomialRing(QQ, 6, order='degrevlex(4),neglex(2)') sage: a > c^4 False sage: a > e^4 @@ -341,7 +341,7 @@ Traceback (most recent call last): ... ValueError: unknown term order 'royalorder' - sage: T = TermOrder("royalorder",force=True) + sage: T = TermOrder("royalorder", force=True) sage: T royalorder term order sage: T.singular_str() @@ -647,7 +647,7 @@ def __init__(self, name='lex', n=0, force=False): :trac:`12748`):: sage: T = TermOrder('degrevlex', 6) + TermOrder('degrevlex',10) - sage: R. = PolynomialRing(QQ,order=T) + sage: R. = PolynomialRing(QQ, order=T) Traceback (most recent call last): ... ValueError: the length of the given term order (16) differs from the number of variables (15) @@ -657,7 +657,7 @@ def __init__(self, name='lex', n=0, force=False): sage: T = TermOrder('degrevlex') sage: R. = PolynomialRing(QQ, order=T) - sage: R._singular_() + sage: R._singular_() # optional - sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 3 @@ -673,7 +673,7 @@ def __init__(self, name='lex', n=0, force=False): sage: S = R.change_ring(order=T2) sage: S == T False - sage: S._singular_() + sage: S._singular_() # optional - sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 3 @@ -683,10 +683,11 @@ def __init__(self, name='lex', n=0, force=False): Check that :trac:`29635` is fixed:: - sage: T = PolynomialRing(GF(101^5), 'u,v,w', order=TermOrder('degneglex')).term_order() - sage: T.singular_str() + sage: T = PolynomialRing(GF(101^5), 'u,v,w', # optional - sage.rings.finite_rings + ....: order=TermOrder('degneglex')).term_order() + sage: T.singular_str() # optional - sage.rings.finite_rings '(a(1:3),ls(3))' - sage: (T + T).singular_str() + sage: (T + T).singular_str() # optional - sage.rings.finite_rings '(a(1:3),ls(3),a(1:3),ls(3))' """ if isinstance(name, TermOrder): @@ -929,10 +930,10 @@ def sortkey_matrix(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='m(1,3,1,0)') - sage: y > x^2 # indirect doctest + sage: P. = PolynomialRing(QQbar, 2, order='m(1,3,1,0)') # optional - sage.rings.number_field + sage: y > x^2 # indirect doctest # optional - sage.rings.number_field True - sage: y > x^3 + sage: y > x^3 # optional - sage.rings.number_field False """ return tuple(sum(l * r for l, r in zip(row, f)) @@ -949,10 +950,10 @@ def sortkey_lex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='lex') - sage: x > y^2 # indirect doctest + sage: P. = PolynomialRing(QQbar, 2, order='lex') # optional - sage.rings.number_field + sage: x > y^2 # indirect doctest # optional - sage.rings.number_field True - sage: x > 1 + sage: x > 1 # optional - sage.rings.number_field True """ return f @@ -968,10 +969,10 @@ def sortkey_invlex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='invlex') - sage: x > y^2 # indirect doctest + sage: P. = PolynomialRing(QQbar, 2, order='invlex') # optional - sage.rings.number_field + sage: x > y^2 # indirect doctest # optional - sage.rings.number_field False - sage: x > 1 + sage: x > 1 # optional - sage.rings.number_field True """ return f.reversed() @@ -987,10 +988,10 @@ def sortkey_deglex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='deglex') - sage: x > y^2 # indirect doctest + sage: P. = PolynomialRing(QQbar, 2, order='deglex') # optional - sage.rings.number_field + sage: x > y^2 # indirect doctest # optional - sage.rings.number_field False - sage: x > 1 + sage: x > 1 # optional - sage.rings.number_field True """ @@ -1007,10 +1008,10 @@ def sortkey_degrevlex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='degrevlex') - sage: x > y^2 # indirect doctest + sage: P. = PolynomialRing(QQbar, 2, order='degrevlex') # optional - sage.rings.number_field + sage: x > y^2 # indirect doctest # optional - sage.rings.number_field False - sage: x > 1 + sage: x > 1 # optional - sage.rings.number_field True """ @@ -1029,10 +1030,10 @@ def sortkey_neglex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='neglex') - sage: x > y^2 # indirect doctest + sage: P. = PolynomialRing(QQbar, 2, order='neglex') # optional - sage.rings.number_field + sage: x > y^2 # indirect doctest # optional - sage.rings.number_field False - sage: x > 1 + sage: x > 1 # optional - sage.rings.number_field False """ return tuple(-v for v in f) @@ -1048,10 +1049,10 @@ def sortkey_negdegrevlex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='negdegrevlex') - sage: x > y^2 # indirect doctest + sage: P. = PolynomialRing(QQbar, 2, order='negdegrevlex') # optional - sage.rings.number_field + sage: x > y^2 # indirect doctest # optional - sage.rings.number_field True - sage: x > 1 + sage: x > 1 # optional - sage.rings.number_field False """ return (-sum(f.nonzero_values(sort=False)), @@ -1068,10 +1069,10 @@ def sortkey_negdeglex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='negdeglex') - sage: x > y^2 # indirect doctest + sage: P. = PolynomialRing(QQbar, 2, order='negdeglex') # optional - sage.rings.number_field + sage: x > y^2 # indirect doctest # optional - sage.rings.number_field True - sage: x > 1 + sage: x > 1 # optional - sage.rings.number_field False """ return (-sum(f.nonzero_values(sort=False)), f) @@ -1087,10 +1088,10 @@ def sortkey_degneglex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='degneglex') - sage: x*y > y*z # indirect doctest + sage: P. = PolynomialRing(QQbar, 3, order='degneglex') # optional - sage.rings.number_field + sage: x*y > y*z # indirect doctest # optional - sage.rings.number_field False - sage: x*y > x + sage: x*y > x # optional - sage.rings.number_field True """ return (sum(f.nonzero_values(sort=False)), tuple(-v for v in f)) @@ -1107,10 +1108,10 @@ def sortkey_wdegrevlex(self, f): EXAMPLES:: sage: t = TermOrder('wdegrevlex',(3,2)) - sage: P. = PolynomialRing(QQbar, 2, order=t) - sage: x > y^2 # indirect doctest + sage: P. = PolynomialRing(QQbar, 2, order=t) # optional - sage.rings.number_field + sage: x > y^2 # indirect doctest # optional - sage.rings.number_field False - sage: x^2 > y^3 + sage: x^2 > y^3 # optional - sage.rings.number_field True """ return (sum(l * r for (l, r) in zip(f, self._weights)), @@ -1128,10 +1129,10 @@ def sortkey_wdeglex(self, f): EXAMPLES:: sage: t = TermOrder('wdeglex',(3,2)) - sage: P. = PolynomialRing(QQbar, 2, order=t) - sage: x > y^2 # indirect doctest + sage: P. = PolynomialRing(QQbar, 2, order=t) # optional - sage.rings.number_field + sage: x > y^2 # indirect doctest # optional - sage.rings.number_field False - sage: x > y + sage: x > y # optional - sage.rings.number_field True """ return (sum(l * r for (l, r) in zip(f, self._weights)), f) @@ -1148,10 +1149,10 @@ def sortkey_negwdeglex(self, f): EXAMPLES:: sage: t = TermOrder('negwdeglex',(3,2)) - sage: P. = PolynomialRing(QQbar, 2, order=t) - sage: x > y^2 # indirect doctest + sage: P. = PolynomialRing(QQbar, 2, order=t) # optional - sage.rings.number_field + sage: x > y^2 # indirect doctest # optional - sage.rings.number_field True - sage: x^2 > y^3 + sage: x^2 > y^3 # optional - sage.rings.number_field True """ return (-sum(l * r for (l, r) in zip(f, self._weights)), f) @@ -1168,10 +1169,10 @@ def sortkey_negwdegrevlex(self, f): EXAMPLES:: sage: t = TermOrder('negwdegrevlex',(3,2)) - sage: P. = PolynomialRing(QQbar, 2, order=t) - sage: x > y^2 # indirect doctest + sage: P. = PolynomialRing(QQbar, 2, order=t) # optional - sage.rings.number_field + sage: x > y^2 # indirect doctest # optional - sage.rings.number_field True - sage: x^2 > y^3 + sage: x^2 > y^3 # optional - sage.rings.number_field True """ return (-sum(l * r for (l, r) in zip(f, self._weights)), @@ -1188,18 +1189,19 @@ def sortkey_block(self, f): EXAMPLES:: - sage: P.=PolynomialRing(QQbar, 6, order='degrevlex(3),degrevlex(3)') - sage: a > c^4 # indirect doctest + sage: P. = PolynomialRing(QQbar, 6, # optional - sage.rings.number_field + ....: order='degrevlex(3),degrevlex(3)') + sage: a > c^4 # indirect doctest # optional - sage.rings.number_field False - sage: a > e^4 + sage: a > e^4 # optional - sage.rings.number_field True TESTS: Check that the issue in :trac:`27139` is fixed:: - sage: R. = PolynomialRing(AA, order='lex(2),lex(2)') - sage: x > y + sage: R. = PolynomialRing(AA, order='lex(2),lex(2)') # optional - sage.rings.number_field + sage: x > y # optional - sage.rings.number_field True """ key = tuple() @@ -1223,10 +1225,10 @@ def greater_tuple_matrix(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='m(1,3,1,0)') - sage: y > x^2 # indirect doctest + sage: P. = PolynomialRing(QQbar, 2, order='m(1,3,1,0)') # optional - sage.rings.number_field + sage: y > x^2 # indirect doctest # optional - sage.rings.number_field True - sage: y > x^3 + sage: y > x^3 # optional - sage.rings.number_field False """ for row in self._matrix: @@ -1252,8 +1254,8 @@ def greater_tuple_lex(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='lex') - sage: f = x + y^2; f.lm() # indirect doctest + sage: P. = PolynomialRing(QQbar, 3, order='lex') # optional - sage.rings.number_field + sage: f = x + y^2; f.lm() # indirect doctest # optional - sage.rings.number_field x This method is called by the lm/lc/lt methods of @@ -1274,10 +1276,10 @@ def greater_tuple_invlex(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='invlex') - sage: f = x + y; f.lm() # indirect doctest + sage: P. = PolynomialRing(QQbar, 3, order='invlex') # optional - sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field y - sage: f = y + x^2; f.lm() + sage: f = y + x^2; f.lm() # optional - sage.rings.number_field y This method is called by the lm/lc/lt methods of @@ -1298,10 +1300,10 @@ def greater_tuple_deglex(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='deglex') - sage: f = x + y; f.lm() # indirect doctest + sage: P. = PolynomialRing(QQbar, 3, order='deglex') # optional - sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field x - sage: f = x + y^2*z; f.lm() + sage: f = x + y^2*z; f.lm() # optional - sage.rings.number_field y^2*z This method is called by the lm/lc/lt methods of @@ -1324,10 +1326,10 @@ def greater_tuple_degrevlex(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='degrevlex') - sage: f = x + y; f.lm() # indirect doctest + sage: P. = PolynomialRing(QQbar, 3, order='degrevlex') # optional - sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field x - sage: f = x + y^2*z; f.lm() + sage: f = x + y^2*z; f.lm() # optional - sage.rings.number_field y^2*z This method is called by the lm/lc/lt methods of @@ -1350,12 +1352,12 @@ def greater_tuple_negdegrevlex(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='negdegrevlex') - sage: f = x + y; f.lm() # indirect doctest + sage: P. = PolynomialRing(QQbar, 3, order='negdegrevlex') # optional - sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field x - sage: f = x + x^2; f.lm() + sage: f = x + x^2; f.lm() # optional - sage.rings.number_field x - sage: f = x^2*y*z^2 + x*y^3*z; f.lm() + sage: f = x^2*y*z^2 + x*y^3*z; f.lm() # optional - sage.rings.number_field x*y^3*z This method is called by the lm/lc/lt methods of @@ -1378,12 +1380,12 @@ def greater_tuple_negdeglex(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='negdeglex') - sage: f = x + y; f.lm() # indirect doctest + sage: P. = PolynomialRing(QQbar, 3, order='negdeglex') # optional - sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field x - sage: f = x + x^2; f.lm() + sage: f = x + x^2; f.lm() # optional - sage.rings.number_field x - sage: f = x^2*y*z^2 + x*y^3*z; f.lm() + sage: f = x^2*y*z^2 + x*y^3*z; f.lm() # optional - sage.rings.number_field x^2*y*z^2 This method is called by the lm/lc/lt methods of @@ -1406,10 +1408,10 @@ def greater_tuple_degneglex(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='degneglex') - sage: f = x + y; f.lm() # indirect doctest + sage: P. = PolynomialRing(QQbar, 3, order='degneglex') # optional - sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field y - sage: f = x + y^2*z; f.lm() + sage: f = x + y^2*z; f.lm() # optional - sage.rings.number_field y^2*z This method is called by the lm/lc/lt methods of @@ -1435,10 +1437,11 @@ def greater_tuple_neglex(self,f,g): EXAMPLES:: - sage: P.=PolynomialRing(QQbar, 6, order='degrevlex(3),degrevlex(3)') - sage: f = a + c^4; f.lm() # indirect doctest + sage: P. = PolynomialRing(QQbar, 6, # optional - sage.rings.number_field + ....: order='degrevlex(3),degrevlex(3)') + sage: f = a + c^4; f.lm() # indirect doctest # optional - sage.rings.number_field c^4 - sage: g = a + e^4; g.lm() + sage: g = a + e^4; g.lm() # optional - sage.rings.number_field a """ return (f < g) and f or g @@ -1457,10 +1460,10 @@ def greater_tuple_wdeglex(self,f,g): EXAMPLES:: sage: t = TermOrder('wdeglex',(1,2,3)) - sage: P. = PolynomialRing(QQbar, 3, order=t) - sage: f = x + y; f.lm() # indirect doctest + sage: P. = PolynomialRing(QQbar, 3, order=t) # optional - sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field y - sage: f = x*y + z; f.lm() + sage: f = x*y + z; f.lm() # optional - sage.rings.number_field x*y This method is called by the lm/lc/lt methods of @@ -1484,10 +1487,10 @@ def greater_tuple_wdegrevlex(self,f,g): EXAMPLES:: sage: t = TermOrder('wdegrevlex',(1,2,3)) - sage: P. = PolynomialRing(QQbar, 3, order=t) - sage: f = x + y; f.lm() # indirect doctest + sage: P. = PolynomialRing(QQbar, 3, order=t) # optional - sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field y - sage: f = x + y^2*z; f.lm() + sage: f = x + y^2*z; f.lm() # optional - sage.rings.number_field y^2*z This method is called by the lm/lc/lt methods of @@ -1511,12 +1514,12 @@ def greater_tuple_negwdeglex(self,f,g): EXAMPLES:: sage: t = TermOrder('negwdeglex',(1,2,3)) - sage: P. = PolynomialRing(QQbar, 3, order=t) - sage: f = x + y; f.lm() # indirect doctest + sage: P. = PolynomialRing(QQbar, 3, order=t) # optional - sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field x - sage: f = x + x^2; f.lm() + sage: f = x + x^2; f.lm() # optional - sage.rings.number_field x - sage: f = x^3 + z; f.lm() + sage: f = x^3 + z; f.lm() # optional - sage.rings.number_field x^3 This method is called by the lm/lc/lt methods of @@ -1540,12 +1543,12 @@ def greater_tuple_negwdegrevlex(self,f,g): EXAMPLES:: sage: t = TermOrder('negwdegrevlex',(1,2,3)) - sage: P. = PolynomialRing(QQbar, 3, order=t) - sage: f = x + y; f.lm() # indirect doctest + sage: P. = PolynomialRing(QQbar, 3, order=t) # optional - sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field x - sage: f = x + x^2; f.lm() + sage: f = x + x^2; f.lm() # optional - sage.rings.number_field x - sage: f = x^3 + z; f.lm() + sage: f = x^3 + z; f.lm() # optional - sage.rings.number_field x^3 This method is called by the lm/lc/lt methods of @@ -1571,10 +1574,11 @@ def greater_tuple_block(self, f,g): EXAMPLES:: - sage: P.=PolynomialRing(QQbar, 6, order='degrevlex(3),degrevlex(3)') - sage: f = a + c^4; f.lm() # indirect doctest + sage: P. = PolynomialRing(QQbar, 6, # optional - sage.rings.number_field + ....: order='degrevlex(3),degrevlex(3)') + sage: f = a + c^4; f.lm() # indirect doctest # optional - sage.rings.number_field c^4 - sage: g = a + e^4; g.lm() + sage: g = a + e^4; g.lm() # optional - sage.rings.number_field a """ n = 0 @@ -1600,9 +1604,9 @@ def tuple_weight(self, f): EXAMPLES:: - sage: t=TermOrder('wdeglex',(1,2,3)) - sage: P.=PolynomialRing(QQbar, order=t) - sage: P.term_order().tuple_weight([3,2,1]) + sage: t = TermOrder('wdeglex',(1,2,3)) + sage: P. = PolynomialRing(QQbar, order=t) # optional - sage.rings.number_field + sage: P.term_order().tuple_weight([3,2,1]) # optional - sage.rings.number_field 10 """ return sum(l*r for (l,r) in zip(f,self._weights)) @@ -1641,17 +1645,18 @@ def _repr_(self): def singular_str(self): """ - Return a SINGULAR representation of self. + Return a SINGULAR representation of ``self``. Used to convert polynomial rings to their SINGULAR representation. EXAMPLES:: - sage: P = PolynomialRing(GF(127),10,names='x',order='lex(3),deglex(5),lex(2)') - sage: T = P.term_order() - sage: T.singular_str() + sage: P = PolynomialRing(GF(127), 10, names='x', # optional - sage.rings.finite_rings + ....: order='lex(3),deglex(5),lex(2)') + sage: T = P.term_order() # optional - sage.rings.finite_rings + sage: T.singular_str() # optional - sage.rings.finite_rings '(lp(3),Dp(5),lp(2))' - sage: P._singular_() + sage: P._singular_() # optional - sage.rings.finite_rings polynomial ring, over a field, global ordering // coefficients: ZZ/127 // number of vars : 10 @@ -1677,7 +1682,7 @@ def singular_str(self): sage: T = P.term_order() sage: T.singular_str() '(a(1:2),ls(2),a(1:2),ls(2))' - sage: P._singular_() + sage: P._singular_() # optional - sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 4 @@ -1699,7 +1704,7 @@ def singular_str(self): sage: T = TermOrder("degneglex", 2) + TermOrder("degneglex", 2) sage: T._singular_ringorder_column = 0 sage: P = PolynomialRing(QQ, 4, names='x', order=T) - sage: P._singular_() + sage: P._singular_() # optional - sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 4 @@ -1717,7 +1722,7 @@ def singular_str(self): sage: T._singular_ringorder_column = 1 sage: P = PolynomialRing(QQ, 4, names='y', order=T) - sage: P._singular_() + sage: P._singular_() # optional - sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 4 @@ -1735,7 +1740,7 @@ def singular_str(self): sage: T._singular_ringorder_column = 2 sage: P = PolynomialRing(QQ, 4, names='z', order=T) - sage: P._singular_() + sage: P._singular_() # optional - sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 4 @@ -1770,21 +1775,24 @@ def singular_str(self): def singular_moreblocks(self): """ Return a the number of additional blocks SINGULAR needs to allocate - for handling non-native orderings like `degneglex`. + for handling non-native orderings like ``degneglex``. EXAMPLES:: - sage: P = PolynomialRing(GF(127),10,names='x',order='lex(3),deglex(5),lex(2)') - sage: T = P.term_order() - sage: T.singular_moreblocks() + sage: P = PolynomialRing(GF(127), 10, names='x', # optional - sage.rings.finite_rings + ....: order='lex(3),deglex(5),lex(2)') + sage: T = P.term_order() # optional - sage.rings.finite_rings + sage: T.singular_moreblocks() # optional - sage.rings.finite_rings 0 - sage: P = PolynomialRing(GF(127),10,names='x',order='lex(3),degneglex(5),lex(2)') - sage: T = P.term_order() - sage: T.singular_moreblocks() + sage: P = PolynomialRing(GF(127), 10, names='x', # optional - sage.rings.finite_rings + ....: order='lex(3),degneglex(5),lex(2)') + sage: T = P.term_order() # optional - sage.rings.finite_rings + sage: T.singular_moreblocks() # optional - sage.rings.finite_rings 1 - sage: P = PolynomialRing(GF(127),10,names='x',order='degneglex(5),degneglex(5)') - sage: T = P.term_order() - sage: T.singular_moreblocks() + sage: P = PolynomialRing(GF(127), 10, names='x', # optional - sage.rings.finite_rings + ....: order='degneglex(5),degneglex(5)') + sage: T = P.term_order() # optional - sage.rings.finite_rings + sage: T.singular_moreblocks() # optional - sage.rings.finite_rings 2 TESTS: @@ -1807,18 +1815,19 @@ def singular_moreblocks(self): def macaulay2_str(self): """ - Return a Macaulay2 representation of self. + Return a Macaulay2 representation of ``self``. Used to convert polynomial rings to their Macaulay2 representation. EXAMPLES:: - sage: P = PolynomialRing(GF(127), 8,names='x',order='degrevlex(3),lex(5)') - sage: T = P.term_order() - sage: T.macaulay2_str() + sage: P = PolynomialRing(GF(127), 8, names='x', # optional - sage.rings.finite_rings + ....: order='degrevlex(3),lex(5)') + sage: T = P.term_order() # optional - sage.rings.finite_rings + sage: T.macaulay2_str() # optional - sage.rings.finite_rings '{GRevLex => 3,Lex => 5}' - sage: P._macaulay2_().options()['MonomialOrder'] # optional - macaulay2 + sage: P._macaulay2_().options()['MonomialOrder'] # optional - macaulay2 # optional - sage.rings.finite_rings {MonomialSize => 16 } {GRevLex => {1, 1, 1}} {Lex => 5 } @@ -1828,29 +1837,29 @@ def macaulay2_str(self): def magma_str(self): """ - Return a MAGMA representation of self. + Return a MAGMA representation of ``self``. Used to convert polynomial rings to their MAGMA representation. EXAMPLES:: - sage: P = PolynomialRing(GF(127), 10,names='x',order='degrevlex') - sage: magma(P) # optional - magma + sage: P = PolynomialRing(GF(127), 10, names='x', order='degrevlex') # optional - sage.rings.finite_rings + sage: magma(P) # optional - magma # optional - sage.rings.finite_rings Polynomial ring of rank 10 over GF(127) Order: Graded Reverse Lexicographical Variables: x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 :: - sage: T = P.term_order() - sage: T.magma_str() + sage: T = P.term_order() # optional - sage.rings.finite_rings + sage: T.magma_str() # optional - sage.rings.finite_rings '"grevlex"' """ return self._magma_str def blocks(self): """ - Return the term order blocks of self. + Return the term order blocks of ``self``. NOTE: @@ -1860,7 +1869,7 @@ def blocks(self): EXAMPLES:: - sage: t=TermOrder('deglex',2)+TermOrder('lex',2) + sage: t = TermOrder('deglex',2) + TermOrder('lex',2) sage: t.blocks() (Degree lexicographic term order, Lexicographic term order) """ @@ -1875,8 +1884,8 @@ def matrix(self): EXAMPLES:: - sage: t = TermOrder("M(1,2,0,1)") - sage: t.matrix() + sage: t = TermOrder("M(1,2,0,1)") # optional - sage.modules + sage: t.matrix() # optional - sage.modules [1 2] [0 1] @@ -1889,7 +1898,7 @@ def weights(self): EXAMPLES:: - sage: t=TermOrder('wdeglex',(2,3)) + sage: t = TermOrder('wdeglex',(2,3)) sage: t.weights() (2, 3) """ @@ -1897,7 +1906,7 @@ def weights(self): def __eq__(self, other): """ - Return true if self and other are equal. + Return ``True`` if ``self`` and ``other`` are equal. EXAMPLES:: @@ -1911,15 +1920,15 @@ def __eq__(self, other): :: - sage: T1 = TermOrder('lex',2)+TermOrder('lex',3) - sage: T2 = TermOrder('lex',3)+TermOrder('lex',2) + sage: T1 = TermOrder('lex',2) + TermOrder('lex',3) + sage: T2 = TermOrder('lex',3) + TermOrder('lex',2) sage: T1 == T2 False :: - sage: T1 = TermOrder('lex',2)+TermOrder('neglex',3) - sage: T2 = TermOrder('lex',2)+TermOrder('neglex',3) + sage: T1 = TermOrder('lex',2) + TermOrder('neglex',3) + sage: T2 = TermOrder('lex',2) + TermOrder('neglex',3) sage: T1 == T2 True @@ -1953,12 +1962,12 @@ def __eq__(self, other): def __ne__(self, other): """ - Return true if self and other are not equal. + Return ``True`` if ``self`` and ``other`` are not equal. EXAMPLES:: - sage: T1 = TermOrder('lex',2)+TermOrder('lex',3) - sage: T2 = TermOrder('lex',3)+TermOrder('lex',2) + sage: T1 = TermOrder('lex',2) + TermOrder('lex',3) + sage: T2 = TermOrder('lex',3) + TermOrder('lex',2) sage: T1 != T2 True """ @@ -2063,7 +2072,7 @@ def __iter__(self): def is_global(self): r""" - Return true if this term order is definitely + Return ``True`` if this term order is definitely global. Return false otherwise, which includes unknown term orders. @@ -2095,7 +2104,7 @@ def is_global(self): def is_local(self): r""" - Return true if this term order is definitely + Return ``True`` if this term order is definitely local. Return false otherwise, which includes unknown term orders. @@ -2122,11 +2131,11 @@ def is_local(self): def is_block_order(self): """ - Return true if self is a block term order. + Return ``True`` if ``self`` is a block term order. EXAMPLES:: - sage: t=TermOrder('deglex',2)+TermOrder('lex',2) + sage: t = TermOrder('deglex',2) + TermOrder('lex',2) sage: t.is_block_order() True """ @@ -2134,11 +2143,11 @@ def is_block_order(self): def is_weighted_degree_order(self): """ - Return true if self is a weighted degree term order. + Return ``True`` if ``self`` is a weighted degree term order. EXAMPLES:: - sage: t=TermOrder('wdeglex',(2,3)) + sage: t = TermOrder('wdeglex',(2,3)) sage: t.is_weighted_degree_order() True """ @@ -2156,13 +2165,13 @@ def termorder_from_singular(S): EXAMPLES:: sage: from sage.rings.polynomial.term_order import termorder_from_singular - sage: singular.eval('ring r1 = (9,x),(a,b,c,d,e,f),(M((1,2,3,0)),wp(2,3),lp)') + sage: singular.eval('ring r1 = (9,x),(a,b,c,d,e,f),(M((1,2,3,0)),wp(2,3),lp)') # optional - sage.libs.singular '' - sage: termorder_from_singular(singular) + sage: termorder_from_singular(singular) # optional - sage.libs.singular Block term order with blocks: (Matrix term order with matrix - [1 2] - [3 0], + [1 2] + [3 0], Weighted degree reverse lexicographic term order with weights (2, 3), Lexicographic term order of length 2) @@ -2170,7 +2179,7 @@ def termorder_from_singular(S): This information is reflected in ``_singular_ringorder_column`` attribute of the term order. :: - sage: singular.ring(0, '(x,y,z,w)', '(C,dp(2),lp(2))') + sage: singular.ring(0, '(x,y,z,w)', '(C,dp(2),lp(2))') # optional - sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 4 @@ -2179,15 +2188,15 @@ def termorder_from_singular(S): // : names x y // block 3 : ordering lp // : names z w - sage: T = termorder_from_singular(singular) - sage: T + sage: T = termorder_from_singular(singular) # optional - sage.libs.singular + sage: T # optional - sage.libs.singular Block term order with blocks: (Degree reverse lexicographic term order of length 2, Lexicographic term order of length 2) - sage: T._singular_ringorder_column + sage: T._singular_ringorder_column # optional - sage.libs.singular 0 - sage: singular.ring(0, '(x,y,z,w)', '(c,dp(2),lp(2))') + sage: singular.ring(0, '(x,y,z,w)', '(c,dp(2),lp(2))') # optional - sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 4 @@ -2196,12 +2205,12 @@ def termorder_from_singular(S): // : names x y // block 3 : ordering lp // : names z w - sage: T = termorder_from_singular(singular) - sage: T + sage: T = termorder_from_singular(singular) # optional - sage.libs.singular + sage: T # optional - sage.libs.singular Block term order with blocks: (Degree reverse lexicographic term order of length 2, Lexicographic term order of length 2) - sage: T._singular_ringorder_column + sage: T._singular_ringorder_column # optional - sage.libs.singular 1 TESTS: @@ -2209,16 +2218,16 @@ def termorder_from_singular(S): Check that ``degneglex`` term orders are converted correctly (:trac:`29635`):: - sage: _ = singular.ring(0, '(x,y,z,w)', '(a(1:4),ls(4))') - sage: termorder_from_singular(singular).singular_str() + sage: _ = singular.ring(0, '(x,y,z,w)', '(a(1:4),ls(4))') # optional - sage.libs.singular + sage: termorder_from_singular(singular).singular_str() # optional - sage.libs.singular '(a(1:4),ls(4))' - sage: _ = singular.ring(0, '(x,y,z,w)', '(a(1:2),ls(2),a(1:2),ls(2))') - sage: termorder_from_singular(singular).singular_str() + sage: _ = singular.ring(0, '(x,y,z,w)', '(a(1:2),ls(2),a(1:2),ls(2))') # optional - sage.libs.singular + sage: termorder_from_singular(singular).singular_str() # optional - sage.libs.singular '(a(1:2),ls(2),a(1:2),ls(2))' - sage: _ = singular.ring(0, '(x,y,z,w)', '(a(1:2),ls(2),C,a(1:2),ls(2))') - sage: termorder_from_singular(singular).singular_str() + sage: _ = singular.ring(0, '(x,y,z,w)', '(a(1:2),ls(2),C,a(1:2),ls(2))') # optional - sage.libs.singular + sage: termorder_from_singular(singular).singular_str() # optional - sage.libs.singular '(a(1:2),ls(2),C,a(1:2),ls(2))' - sage: PolynomialRing(QQ, 'x,y', order='degneglex')('x^2')._singular_().sage() + sage: PolynomialRing(QQ, 'x,y', order='degneglex')('x^2')._singular_().sage() # optional - sage.libs.singular x^2 """ from sage.rings.integer_ring import ZZ diff --git a/src/sage/rings/polynomial/toy_buchberger.py b/src/sage/rings/polynomial/toy_buchberger.py index 2f02ca65e05..c70cf1f90aa 100644 --- a/src/sage/rings/polynomial/toy_buchberger.py +++ b/src/sage/rings/polynomial/toy_buchberger.py @@ -24,39 +24,40 @@ Consider Katsura-6 with respect to a ``degrevlex`` ordering. :: sage: from sage.rings.polynomial.toy_buchberger import * - sage: P. = PolynomialRing(GF(32003)) - sage: I = sage.rings.ideal.Katsura(P, 6) + sage: P. = PolynomialRing(GF(32003)) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Katsura(P, 6) # optional - sage.rings.finite_rings - sage: g1 = buchberger(I) - sage: g2 = buchberger_improved(I) - sage: g3 = I.groebner_basis() + sage: g1 = buchberger(I) # optional - sage.rings.finite_rings + sage: g2 = buchberger_improved(I) # optional - sage.rings.finite_rings + sage: g3 = I.groebner_basis() # optional - sage.rings.finite_rings All algorithms actually compute a Groebner basis:: - sage: Ideal(g1).basis_is_groebner() + sage: Ideal(g1).basis_is_groebner() # optional - sage.rings.finite_rings True - sage: Ideal(g2).basis_is_groebner() + sage: Ideal(g2).basis_is_groebner() # optional - sage.rings.finite_rings True - sage: Ideal(g3).basis_is_groebner() + sage: Ideal(g3).basis_is_groebner() # optional - sage.rings.finite_rings True The results are correct:: - sage: Ideal(g1) == Ideal(g2) == Ideal(g3) + sage: Ideal(g1) == Ideal(g2) == Ideal(g3) # optional - sage.rings.finite_rings True If ``get_verbose()`` is `\ge 1`, a protocol is provided:: sage: from sage.misc.verbose import set_verbose sage: set_verbose(1) - sage: P. = PolynomialRing(GF(127)) - sage: I = sage.rings.ideal.Katsura(P) + sage: P. = PolynomialRing(GF(127)) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings // sage... ideal - sage: I - Ideal (a + 2*b + 2*c - 1, a^2 + 2*b^2 + 2*c^2 - a, 2*a*b + 2*b*c - b) of Multivariate Polynomial Ring in a, b, c over Finite Field of size 127 + sage: I # optional - sage.rings.finite_rings + Ideal (a + 2*b + 2*c - 1, a^2 + 2*b^2 + 2*c^2 - a, 2*a*b + 2*b*c - b) + of Multivariate Polynomial Ring in a, b, c over Finite Field of size 127 - sage: buchberger(I) # random + sage: buchberger(I) # random # optional - sage.rings.finite_rings (a + 2*b + 2*c - 1, a^2 + 2*b^2 + 2*c^2 - a) => -2*b^2 - 6*b*c - 6*c^2 + b + 2*c G: set([a + 2*b + 2*c - 1, 2*a*b + 2*b*c - b, a^2 + 2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c]) @@ -117,18 +118,19 @@ The original Buchberger algorithm performs 15 useless reductions to zero for this example:: - sage: gb = buchberger(I) + sage: gb = buchberger(I) # optional - sage.rings.finite_rings ... 15 reductions to zero. The 'improved' Buchberger algorithm in contrast only performs 1 reduction to zero:: - sage: gb = buchberger_improved(I) + sage: gb = buchberger_improved(I) # optional - sage.rings.finite_rings ... 1 reductions to zero. - sage: sorted(gb) - [a + 2*b + 2*c - 1, b*c + 52*c^2 + 38*b + 25*c, b^2 - 26*c^2 - 51*b + 51*c, c^3 + 22*c^2 - 55*b + 49*c] + sage: sorted(gb) # optional - sage.rings.finite_rings + [a + 2*b + 2*c - 1, b*c + 52*c^2 + 38*b + 25*c, + b^2 - 26*c^2 - 51*b + 51*c, c^3 + 22*c^2 - 55*b + 49*c] AUTHORS: @@ -191,10 +193,10 @@ def buchberger(F): sage: R. = PolynomialRing(QQ) sage: I = R.ideal([x^2 - z - 1, z^2 - y - 1, x*y^2 - x - 1]) sage: set_verbose(0) - sage: gb = buchberger(I) - sage: gb.is_groebner() + sage: gb = buchberger(I) # optional - sage.libs.singular + sage: gb.is_groebner() # optional - sage.libs.singular True - sage: gb.ideal() == I + sage: gb.ideal() == I # optional - sage.libs.singular True """ G = set(F.gens()) @@ -249,7 +251,7 @@ def buchberger_improved(F): sage: from sage.rings.polynomial.toy_buchberger import buchberger_improved sage: R. = PolynomialRing(QQ) sage: set_verbose(0) - sage: sorted(buchberger_improved(R.ideal([x^4 - y - z, x*y*z - 1]))) + sage: sorted(buchberger_improved(R.ideal([x^4 - y - z, x*y*z - 1]))) # optional - sage.libs.singular [x*y*z - 1, x^3 - y^2*z - y*z^2, y^3*z^2 + y^2*z^3 - x^2] """ F = inter_reduction(F.gens()) @@ -382,8 +384,8 @@ def select(P): sage: from sage.rings.polynomial.toy_buchberger import select sage: R. = PolynomialRing(QQ, order='lex') - sage: ps = [x^3 - z -1, z^3 - y - 1, x^5 - y - 2] - sage: pairs = [[ps[i], ps[j]] for i in range(3) for j in range(i+1, 3)] + sage: ps = [x^3 - z - 1, z^3 - y - 1, x^5 - y - 2] + sage: pairs = [[ps[i], ps[j]] for i in range(3) for j in range(i + 1, 3)] sage: select(pairs) [x^3 - z - 1, -y + z^3 - 1] """ @@ -401,10 +403,10 @@ def inter_reduction(Q): OUTPUT: - if ``Q`` is the set `(f_1, ..., f_n)`, this method returns `(g_1, - ..., g_s)` such that: + if ``Q`` is the set `f_1, ..., f_n`, this method returns `g_1, + ..., g_s` such that: - - ` = ` + - `(f_1,...,f_n) = (g_1,...,g_s)` - `LM(g_i) \neq LM(g_j)` for all `i \neq j` - `LM(g_i)` does not divide `m` for all monomials `m` of `\{g_1,...,g_{i-1}, g_{i+1},...,g_s\}` @@ -419,10 +421,10 @@ def inter_reduction(Q): :: sage: P. = QQ[] - sage: reduced = inter_reduction(set([x^2 - 5*y^2, x^3])) - sage: reduced == set([x*y^2, x^2-5*y^2]) + sage: reduced = inter_reduction(set([x^2 - 5*y^2, x^3])) # optional - sage.libs.singular + sage: reduced == set([x*y^2, x^2 - 5*y^2]) # optional - sage.libs.singular True - sage: reduced == inter_reduction(set([2*(x^2 - 5*y^2), x^3])) + sage: reduced == inter_reduction(set([2*(x^2 - 5*y^2), x^3])) # optional - sage.libs.singular True """ if not Q: diff --git a/src/sage/rings/polynomial/toy_d_basis.py b/src/sage/rings/polynomial/toy_d_basis.py index 07f83100df7..660922aaf64 100644 --- a/src/sage/rings/polynomial/toy_d_basis.py +++ b/src/sage/rings/polynomial/toy_d_basis.py @@ -20,12 +20,12 @@ First, consider an example from arithmetic geometry:: sage: A. = PolynomialRing(ZZ, 2) - sage: B. = PolynomialRing(Rationals(),2) + sage: B. = PolynomialRing(Rationals(), 2) sage: f = -y^2 - y + x^3 + 7*x + 1 sage: fx = f.derivative(x) sage: fy = f.derivative(y) - sage: I = B.ideal([B(f),B(fx),B(fy)]) - sage: I.groebner_basis() + sage: I = B.ideal([B(f), B(fx), B(fy)]) + sage: I.groebner_basis() # optional - sage.libs.singular [1] Since the output is 1, we know that there are no generic @@ -34,7 +34,7 @@ To look at the singularities of the arithmetic surface, we need to do the corresponding computation over `\ZZ`:: - sage: I = A.ideal([f,fx,fy]) + sage: I = A.ideal([f, fx, fy]) sage: gb = d_basis(I); gb [x - 2020, y - 11313, 22627] @@ -52,7 +52,7 @@ Another example. This one is from the Magma Handbook:: sage: P. = PolynomialRing(IntegerRing(), 3, order='lex') - sage: I = ideal( x^2 - 1, y^2 - 1, 2*x*y - z) + sage: I = ideal(x^2 - 1, y^2 - 1, 2*x*y - z) sage: I = Ideal(d_basis(I)) sage: x.reduce(I) x @@ -61,7 +61,7 @@ To compute modulo 4, we can add the generator 4 to our basis.:: - sage: I = ideal( x^2 - 1, y^2 - 1, 2*x*y - z, 4) + sage: I = ideal(x^2 - 1, y^2 - 1, 2*x*y - z, 4) sage: gb = d_basis(I) sage: R = P.change_ring(IntegerModRing(4)) sage: gb = [R(f) for f in gb if R(f)]; gb @@ -79,7 +79,7 @@ there are 4 equations in 3 unknowns). :: sage: P. = PolynomialRing(IntegerRing(), 3, order='degneglex') - sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 ) + sage: I = ideal(x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1) sage: I.change_ring(P.change_ring(RationalField())).groebner_basis() [1] @@ -96,19 +96,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() [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() [z - 18, y + 8, x + 39] - sage: I.change_ring( P.change_ring( GF(27173681) ) ).groebner_basis() + sage: I.change_ring( P.change_ring(GF(27173681))).groebner_basis() [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() [1] AUTHOR: diff --git a/src/sage/rings/polynomial/toy_variety.py b/src/sage/rings/polynomial/toy_variety.py index 3f2a1705989..16ccfb6cf8c 100644 --- a/src/sage/rings/polynomial/toy_variety.py +++ b/src/sage/rings/polynomial/toy_variety.py @@ -100,7 +100,7 @@ def coefficient_matrix(polys): sage: from sage.rings.polynomial.toy_variety import coefficient_matrix sage: R. = PolynomialRing(QQ) - sage: coefficient_matrix([x^2 + 1, y^2 + 1, x*y + 1]) + sage: coefficient_matrix([x^2 + 1, y^2 + 1, x*y + 1]) # optional - sage.modules [1 0 0 1] [0 0 1 1] [0 1 0 1] @@ -159,12 +159,12 @@ def is_linearly_dependent(polys) -> bool: sage: R. = PolynomialRing(QQ) sage: B = [x^2 + 1, y^2 + 1, x*y + 1] sage: p = 3*B[0] - 2*B[1] + B[2] - sage: is_linearly_dependent(B + [p]) + sage: is_linearly_dependent(B + [p]) # optional - sage.modules True - sage: p = x*B[0] - sage: is_linearly_dependent(B + [p]) + sage: p = x*B[0] # optional - sage.modules + sage: is_linearly_dependent(B + [p]) # optional - sage.modules False - sage: is_linearly_dependent([]) + sage: is_linearly_dependent([]) # optional - sage.modules False """ if not polys: @@ -204,10 +204,10 @@ def linear_representation(p, polys): EXAMPLES:: sage: from sage.rings.polynomial.toy_variety import linear_representation - sage: R. = PolynomialRing(GF(32003)) - sage: B = [x^2 + 1, y^2 + 1, x*y + 1] - sage: p = 3*B[0] - 2*B[1] + B[2] - sage: linear_representation(p, B) + sage: R. = PolynomialRing(GF(32003)) # optional - sage.rings.finite_rings + sage: B = [x^2 + 1, y^2 + 1, x*y + 1] # optional - sage.rings.finite_rings + sage: p = 3*B[0] - 2*B[1] + B[2] # optional - sage.rings.finite_rings + sage: linear_representation(p, B) # optional - sage.rings.finite_rings [3, 32001, 1] """ from sage.matrix.constructor import diagonal_matrix @@ -243,12 +243,12 @@ def triangular_factorization(B, n=-1): sage: from sage.misc.verbose import set_verbose sage: set_verbose(0) sage: from sage.rings.polynomial.toy_variety import triangular_factorization - sage: R. = PolynomialRing(GF(32003)) - sage: p1 = x^2*(x-1)^3*y^2*(z-3)^3 - sage: p2 = z^2 - z - sage: p3 = (x-2)^2*(y-1)^3 - sage: I = R.ideal(p1,p2,p3) - sage: triangular_factorization(I.groebner_basis()) + sage: R. = PolynomialRing(GF(32003)) # optional - sage.rings.finite_rings + sage: p1 = x^2*(x-1)^3*y^2*(z-3)^3 # optional - sage.rings.finite_rings + sage: p2 = z^2 - z # optional - sage.rings.finite_rings + sage: p3 = (x-2)^2*(y-1)^3 # optional - sage.rings.finite_rings + sage: I = R.ideal(p1,p2,p3) # optional - sage.rings.finite_rings + sage: triangular_factorization(I.groebner_basis()) # optional - sage.rings.finite_rings [[x^2 - 4*x + 4, y, z], [x^5 - 3*x^4 + 3*x^3 - x^2, y - 1, z], [x^2 - 4*x + 4, y, z - 1], @@ -317,12 +317,12 @@ def elim_pol(B, n=-1): sage: from sage.misc.verbose import set_verbose sage: set_verbose(0) sage: from sage.rings.polynomial.toy_variety import elim_pol - sage: R. = PolynomialRing(GF(32003)) - sage: p1 = x^2*(x-1)^3*y^2*(z-3)^3 - sage: p2 = z^2 - z - sage: p3 = (x-2)^2*(y-1)^3 - sage: I = R.ideal(p1,p2,p3) - sage: elim_pol(I.groebner_basis()) + sage: R. = PolynomialRing(GF(32003)) # optional - sage.rings.finite_rings + sage: p1 = x^2*(x-1)^3*y^2*(z-3)^3 # optional - sage.rings.finite_rings + sage: p2 = z^2 - z # optional - sage.rings.finite_rings + sage: p3 = (x-2)^2*(y-1)^3 # optional - sage.rings.finite_rings + sage: I = R.ideal(p1,p2,p3) # optional - sage.rings.finite_rings + sage: elim_pol(I.groebner_basis()) # optional - sage.rings.finite_rings z^2 - z """ # type checking in a probably vain attempt to avoid stupid errors diff --git a/src/sage/rings/polynomial/weil/weil_polynomials.pyx b/src/sage/rings/polynomial/weil/weil_polynomials.pyx index 2e2d6974fb7..8ff874bb746 100755 --- a/src/sage/rings/polynomial/weil/weil_polynomials.pyx +++ b/src/sage/rings/polynomial/weil/weil_polynomials.pyx @@ -50,7 +50,6 @@ from cysignals.signals cimport sig_on, sig_off from sage.rings.rational_field import QQ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.functions.generalized import sgn from sage.rings.integer cimport Integer from sage.libs.gmp.types cimport mpz_t @@ -319,7 +318,7 @@ class WeilPolynomials_iter(): for _ in range(d2+1-len(coefflist)): coefflist.append(0) modlist.append(1) - coeffsign = sgn(coefflist[0]) + coeffsign = coefflist[0].sign() coefflist = [x*coeffsign for x in reversed(coefflist)] if node_limit is None: node_limit = -1 diff --git a/src/sage/rings/power_series_poly.pyx b/src/sage/rings/power_series_poly.pyx index d3546fc0c72..6b7dcce74ab 100644 --- a/src/sage/rings/power_series_poly.pyx +++ b/src/sage/rings/power_series_poly.pyx @@ -105,9 +105,9 @@ cdef class PowerSeries_poly(PowerSeries): EXAMPLES:: - sage: R. = GF(7)[[]] - sage: f = 3 - t^3 + O(t^5) - sage: f.polynomial() + sage: R. = GF(7)[[]] # optional - sage.rings.finite_rings + sage: f = 3 - t^3 + O(t^5) # optional - sage.rings.finite_rings + sage: f.polynomial() # optional - sage.rings.finite_rings 6*t^3 + 3 """ return self.__f @@ -159,12 +159,12 @@ cdef class PowerSeries_poly(PowerSeries): EXAMPLES:: - sage: R. = GF(11)[[]] - sage: bool(1 + t + O(t^18)) + sage: R. = GF(11)[[]] # optional - sage.rings.finite_rings + sage: bool(1 + t + O(t^18)) # optional - sage.rings.finite_rings True - sage: bool(R(0)) + sage: bool(R(0)) # optional - sage.rings.finite_rings False - sage: bool(O(t^18)) + sage: bool(O(t^18)) # optional - sage.rings.finite_rings False """ return not not self.__f @@ -225,17 +225,17 @@ cdef class PowerSeries_poly(PowerSeries): A series defined over another ring can be substituted:: - sage: S. = GF(7)[[]] - sage: f(2*u + u^3 + O(u^5)) + sage: S. = GF(7)[[]] # optional - sage.rings.finite_rings + sage: f(2*u + u^3 + O(u^5)) # optional - sage.rings.finite_rings 4*u^2 + u^3 + 4*u^4 + 5*u^5 + O(u^6) As can a p-adic integer as long as the coefficient ring is compatible:: - sage: f(100 + O(5^7)) + sage: f(100 + O(5^7)) # optional - sage.rings.padics 5^4 + 3*5^5 + 4*5^6 + 2*5^7 + 2*5^8 + O(5^9) - sage: f.change_ring(Zp(5))(100 + O(5^7)) + sage: f.change_ring(Zp(5))(100 + O(5^7)) # optional - sage.rings.padics 5^4 + 3*5^5 + 4*5^6 + 2*5^7 + 2*5^8 + O(5^9) - sage: f.change_ring(Zp(5))(100 + O(2^7)) + sage: f.change_ring(Zp(5))(100 + O(2^7)) # optional - sage.rings.padics Traceback (most recent call last): ... ValueError: Cannot substitute this value @@ -248,7 +248,7 @@ cdef class PowerSeries_poly(PowerSeries): Traceback (most recent call last): ... ValueError: Can only substitute elements of positive valuation - sage: f(2 + O(5^3)) + sage: f(2 + O(5^3)) # optional - sage.rings.padics Traceback (most recent call last): ... ValueError: Can only substitute elements of positive valuation @@ -268,18 +268,18 @@ cdef class PowerSeries_poly(PowerSeries): Arguments beyond the first can refer to the base ring:: - sage: P. = GF(5)[] - sage: Q. = P[[]] - sage: h = (1 - x*y)^-1 + O(y^7); h + sage: P. = GF(5)[] # optional - sage.rings.finite_rings + sage: Q. = P[[]] # optional - sage.rings.finite_rings + sage: h = (1 - x*y)^-1 + O(y^7); h # optional - sage.rings.finite_rings 1 + x*y + x^2*y^2 + x^3*y^3 + x^4*y^4 + x^5*y^5 + x^6*y^6 + O(y^7) - sage: h(y^2, 3) + sage: h(y^2, 3) # optional - sage.rings.finite_rings 1 + 3*y^2 + 4*y^4 + 2*y^6 + y^8 + 3*y^10 + 4*y^12 + O(y^14) These secondary values can also be specified using keywords:: - sage: h(y=y^2, x=3) + sage: h(y=y^2, x=3) # optional - sage.rings.finite_rings 1 + 3*y^2 + 4*y^4 + 2*y^6 + y^8 + 3*y^10 + 4*y^12 + O(y^14) - sage: h(y^2, x=3) + sage: h(y^2, x=3) # optional - sage.rings.finite_rings 1 + 3*y^2 + 4*y^4 + 2*y^6 + y^8 + 3*y^10 + 4*y^12 + O(y^14) """ P = self.parent() @@ -375,27 +375,27 @@ cdef class PowerSeries_poly(PowerSeries): EXAMPLES:: - sage: R. = GF(7)[[]] - sage: f = 3 + 6*t^3 + O(t^5) - sage: f._unsafe_mutate(0, 5) - sage: f + sage: R. = GF(7)[[]] # optional - sage.rings.finite_rings + sage: f = 3 + 6*t^3 + O(t^5) # optional - sage.rings.finite_rings + sage: f._unsafe_mutate(0, 5) # optional - sage.rings.finite_rings + sage: f # optional - sage.rings.finite_rings 5 + 6*t^3 + O(t^5) - sage: f._unsafe_mutate(2, 1) ; f + sage: f._unsafe_mutate(2, 1) ; f # optional - sage.rings.finite_rings 5 + t^2 + 6*t^3 + O(t^5) - Mutating can even bump up the precision:: - sage: f._unsafe_mutate(6, 1) ; f + sage: f._unsafe_mutate(6, 1) ; f # optional - sage.rings.finite_rings 5 + t^2 + 6*t^3 + t^6 + O(t^7) - sage: f._unsafe_mutate(0, 0) ; f + sage: f._unsafe_mutate(0, 0) ; f # optional - sage.rings.finite_rings t^2 + 6*t^3 + t^6 + O(t^7) - sage: f._unsafe_mutate(1, 0) ; f + sage: f._unsafe_mutate(1, 0) ; f # optional - sage.rings.finite_rings t^2 + 6*t^3 + t^6 + O(t^7) - sage: f._unsafe_mutate(11,0) ; f + sage: f._unsafe_mutate(11,0) ; f # optional - sage.rings.finite_rings t^2 + 6*t^3 + t^6 + O(t^12) - sage: g = t + O(t^7) - sage: g._unsafe_mutate(1,0) ; g + sage: g = t + O(t^7) # optional - sage.rings.finite_rings + sage: g._unsafe_mutate(1,0) ; g # optional - sage.rings.finite_rings O(t^7) """ self.__f._unsafe_mutate(i, value) @@ -554,9 +554,9 @@ cdef class PowerSeries_poly(PowerSeries): EXAMPLES:: - sage: R. = GF(7)[[]] - sage: f = t + 3*t^4 + O(t^11) - sage: f * GF(7)(3) + sage: R. = GF(7)[[]] # optional - sage.rings.finite_rings + sage: f = t + 3*t^4 + O(t^11) # optional - sage.rings.finite_rings + sage: f * GF(7)(3) # optional - sage.rings.finite_rings 3*t + 2*t^4 + O(t^11) """ return PowerSeries_poly(self._parent, self.__f * c, self._prec, check=False) @@ -567,9 +567,9 @@ cdef class PowerSeries_poly(PowerSeries): EXAMPLES:: - sage: R. = GF(11)[[]] - sage: f = 1 + 3*t^4 + O(t^120) - sage: 2 * f + sage: R. = GF(11)[[]] # optional - sage.rings.finite_rings + sage: f = 1 + 3*t^4 + O(t^120) # optional - sage.rings.finite_rings + sage: 2 * f # optional - sage.rings.finite_rings 2 + 6*t^4 + O(t^120) """ return PowerSeries_poly(self._parent, c * self.__f, self._prec, check=False) @@ -597,11 +597,11 @@ cdef class PowerSeries_poly(PowerSeries): EXAMPLES:: - sage: R. = GF(2)[[]] - sage: f = t + t^4 + O(t^7) - sage: f >> 1 + sage: R. = GF(2)[[]] # optional - sage.rings.finite_rings + sage: f = t + t^4 + O(t^7) # optional - sage.rings.finite_rings + sage: f >> 1 # optional - sage.rings.finite_rings 1 + t^3 + O(t^6) - sage: f >> 10 + sage: f >> 10 # optional - sage.rings.finite_rings O(t^0) """ if n: @@ -733,10 +733,10 @@ cdef class PowerSeries_poly(PowerSeries): EXAMPLES:: - sage: R. = GF(2)[[]] - sage: f = 1/(1+I+O(I^8)); f + sage: R. = GF(2)[[]] # optional - sage.rings.finite_rings + sage: f = 1/(1+I+O(I^8)); f # optional - sage.rings.finite_rings 1 + I + I^2 + I^3 + I^4 + I^5 + I^6 + I^7 + O(I^8) - sage: f.truncate(5) + sage: f.truncate(5) # optional - sage.rings.finite_rings I^4 + I^3 + I^2 + I + 1 """ if prec is infinity: @@ -764,10 +764,10 @@ cdef class PowerSeries_poly(PowerSeries): EXAMPLES:: - sage: R. = GF(2)[[]] - sage: f = 1/(1+I+O(I^8)); f + sage: R. = GF(2)[[]] # optional - sage.rings.finite_rings + sage: f = 1/(1+I+O(I^8)); f # optional - sage.rings.finite_rings 1 + I + I^2 + I^3 + I^4 + I^5 + I^6 + I^7 + O(I^8) - sage: f.truncate_powerseries(5) + sage: f.truncate_powerseries(5) # optional - sage.rings.finite_rings 1 + I + I^2 + I^3 + I^4 + O(I^5) """ return PowerSeries_poly(self._parent, self.__f.truncate(prec), @@ -845,8 +845,8 @@ cdef class PowerSeries_poly(PowerSeries): TESTS:: sage: R. = PowerSeriesRing(QQ, sparse=True) - sage: x = var('x') - sage: t.derivative(x) + sage: x = var('x') # optional - sage.symbolic + sage: t.derivative(x) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: cannot differentiate with respect to x @@ -871,7 +871,7 @@ cdef class PowerSeries_poly(PowerSeries): By default, the integration variable is the variable of the power series. - Otherwise, the integration variable is the optional parameter ``var`` + Otherwise, the integration variable is the optional parameter ``var``. .. NOTE:: @@ -909,15 +909,15 @@ cdef class PowerSeries_poly(PowerSeries): def reverse(self, precision=None): """ - Return the reverse of f, i.e., the series g such that g(f(x)) = x. + Return the reverse of `f`, i.e., the series `g` such that `g(f(x)) = x`. Given an optional argument ``precision``, return the reverse with given precision (note that the reverse can have precision at most - ``f.prec()``). If ``f`` has infinite precision, and the argument + ``f.prec()``). If `f` has infinite precision, and the argument ``precision`` is not given, then the precision of the reverse defaults to the default precision of ``f.parent()``. - Note that this is only possible if the valuation of self is exactly + Note that this is only possible if the valuation of ``self`` is exactly 1. ALGORITHM: @@ -1019,7 +1019,10 @@ cdef class PowerSeries_poly(PowerSeries): sage: R. = PowerSeriesRing(QQ, default_prec=20) sage: (x - x^2).reverse() # get some Catalan numbers - x + x^2 + 2*x^3 + 5*x^4 + 14*x^5 + 42*x^6 + 132*x^7 + 429*x^8 + 1430*x^9 + 4862*x^10 + 16796*x^11 + 58786*x^12 + 208012*x^13 + 742900*x^14 + 2674440*x^15 + 9694845*x^16 + 35357670*x^17 + 129644790*x^18 + 477638700*x^19 + O(x^20) + x + x^2 + 2*x^3 + 5*x^4 + 14*x^5 + 42*x^6 + 132*x^7 + 429*x^8 + 1430*x^9 + + 4862*x^10 + 16796*x^11 + 58786*x^12 + 208012*x^13 + 742900*x^14 + + 2674440*x^15 + 9694845*x^16 + 35357670*x^17 + 129644790*x^18 + + 477638700*x^19 + O(x^20) sage: (x - x^2).reverse(precision=3) x + x^2 + O(x^3) @@ -1032,11 +1035,10 @@ cdef class PowerSeries_poly(PowerSeries): ... ValueError: Series must have valuation one for reversion. - sage: Series = PowerSeriesRing(SR, 'x') - sage: ser = Series([0, pi]) - sage: ser + sage: Series = PowerSeriesRing(SR, 'x') # optional - sage.symbolic + sage: ser = Series([0, pi]); ser # optional - sage.symbolic pi*x - sage: ser.reverse() + sage: ser.reverse() # optional - sage.symbolic 1/pi*x + O(x^20) """ if self.valuation() != 1: @@ -1195,19 +1197,19 @@ cdef class PowerSeries_poly(PowerSeries): EXAMPLES:: sage: R. = PowerSeriesRing(QQ) - sage: s = R([1,2,3,4,5],prec=10); s + sage: s = R([1,2,3,4,5], prec=10); s 1 + 2*x + 3*x^2 + 4*x^3 + 5*x^4 + O(x^10) - sage: SR(s) + sage: SR(s) # optional - sage.symbolic 1 + 2*x + 3*x^2 + 4*x^3 + 5*x^4 + Order(x^10) - sage: SR(s).is_terminating_series() + sage: SR(s).is_terminating_series() # optional - sage.symbolic False - sage: SR(s).variables() + sage: SR(s).variables() # optional - sage.symbolic (x,) sage: s = R([1,2,3,4,5]); s 1 + 2*x + 3*x^2 + 4*x^3 + 5*x^4 - sage: SR(s) + sage: SR(s) # optional - sage.symbolic 1 + 2*x + 3*x^2 + 4*x^3 + 5*x^4 - sage: _.is_terminating_series() + sage: _.is_terminating_series() # optional - sage.symbolic True TESTS: @@ -1215,7 +1217,7 @@ cdef class PowerSeries_poly(PowerSeries): Check that :trac:`18094` is fixed:: sage: R. = PolynomialRing(ZZ) - sage: SR(R(0).add_bigoh(20)) + sage: SR(R(0).add_bigoh(20)) # optional - sage.symbolic Order(x^20) """ from sage.symbolic.ring import SR diff --git a/src/sage/rings/power_series_ring.py b/src/sage/rings/power_series_ring.py index a65af81d061..65ed3311cd8 100644 --- a/src/sage/rings/power_series_ring.py +++ b/src/sage/rings/power_series_ring.py @@ -59,13 +59,13 @@ :: - sage: K. = PowerSeriesRing(SR, default_prec=5) - sage: a, b, c = var('a,b,c') - sage: f = a + b*t + c*t^2 + O(t^3) - sage: f*f + sage: K. = PowerSeriesRing(SR, default_prec=5) # optional - sage.symbolic + sage: a, b, c = var('a,b,c') # optional - sage.symbolic + sage: f = a + b*t + c*t^2 + O(t^3) # optional - sage.symbolic + sage: f*f # optional - sage.symbolic a^2 + 2*a*b*t + (b^2 + 2*a*c)*t^2 + O(t^3) - sage: f = sqrt(2) + sqrt(3)*t + O(t^3) - sage: f^2 + sage: f = sqrt(2) + sqrt(3)*t + O(t^3) # optional - sage.symbolic + sage: f^2 # optional - sage.symbolic 2 + 2*sqrt(3)*sqrt(2)*t + 3*t^2 + O(t^3) Elements are first coerced to constants in ``base_ring``, then coerced @@ -176,21 +176,21 @@ def PowerSeriesRing(base_ring, name=None, arg2=None, names=None, INPUT: - - ``base_ring`` - a commutative ring + - ``base_ring`` -- a commutative ring - - ``name``, ``names`` - name(s) of the indeterminate + - ``name``, ``names`` -- name(s) of the indeterminate - - ``default_prec`` - the default precision used if an exact object must + - ``default_prec`` -- the default precision used if an exact object must be changed to an approximate object in order to do an arithmetic operation. If left as ``None``, it will be set to the global default (20) in the univariate case, and 12 in the multivariate case. - - ``sparse`` - (default: ``False``) whether power series + - ``sparse`` -- (default: ``False``) whether power series are represented as sparse objects. - - ``order`` - (default: ``negdeglex``) term ordering, for multivariate case + - ``order`` -- (default: ``negdeglex``) term ordering, for multivariate case - - ``num_gens`` - number of generators, for multivariate case + - ``num_gens`` -- number of generators, for multivariate case There is a unique power series ring over each base ring with given @@ -216,7 +216,7 @@ def PowerSeriesRing(base_ring, name=None, arg2=None, names=None, :: - sage: S = PowerSeriesRing(QQ, 'x', default_prec = 15); S + sage: S = PowerSeriesRing(QQ, 'x', default_prec=15); S Power Series Ring in x over Rational Field sage: S.default_prec() 15 @@ -252,19 +252,19 @@ def PowerSeriesRing(base_ring, name=None, arg2=None, names=None, Power series ring over polynomial ring:: - sage: H = PowerSeriesRing(PolynomialRing(ZZ,3,'z'),4,'f'); H + sage: H = PowerSeriesRing(PolynomialRing(ZZ,3,'z'), 4, 'f'); H Multivariate Power Series Ring in f0, f1, f2, f3 over Multivariate Polynomial Ring in z0, z1, z2 over Integer Ring Power series ring over finite field:: - sage: S = PowerSeriesRing(GF(65537),'x,y'); S + sage: S = PowerSeriesRing(GF(65537),'x,y'); S # optional - sage.rings.finite_rings Multivariate Power Series Ring in x, y over Finite Field of size 65537 Power series ring with many variables:: - sage: R = PowerSeriesRing(ZZ, ['x%s'%p for p in primes(100)]); R + sage: R = PowerSeriesRing(ZZ, ['x%s'%p for p in primes(100)]); R # optional - sage.libs.pari Multivariate Power Series Ring in x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97 over Integer Ring @@ -274,12 +274,12 @@ def PowerSeriesRing(base_ring, name=None, arg2=None, names=None, :: - sage: R.inject_variables() + sage: R.inject_variables() # optional - sage.libs.pari Defining x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97 - sage: f = x47 + 3*x11*x29 - x19 + R.O(3) - sage: f in R + sage: f = x47 + 3*x11*x29 - x19 + R.O(3) # optional - sage.libs.pari + sage: f in R # optional - sage.libs.pari True @@ -450,7 +450,7 @@ def _single_variate(): def is_PowerSeriesRing(R): """ - Return True if this is a *univariate* power series ring. This is in + Return ``True`` if this is a *univariate* power series ring. This is in keeping with the behavior of ``is_PolynomialRing`` versus ``is_MPolynomialRing``. @@ -480,13 +480,13 @@ def __init__(self, base_ring, name=None, default_prec=None, sparse=False, INPUT: - - ``base_ring`` - a commutative ring + - ``base_ring`` -- a commutative ring - - ``name`` - name of the indeterminate + - ``name`` -- name of the indeterminate - - ``default_prec`` - the default precision + - ``default_prec`` -- the default precision - - ``sparse`` - whether or not power series are + - ``sparse`` -- whether or not power series are sparse - ``implementation`` -- either ``'poly'``, ``'mpoly'``, or @@ -519,11 +519,11 @@ def __init__(self, base_ring, name=None, default_prec=None, sparse=False, commutative ring, but also a complete discrete valuation ring (CDVR). The appropriate (sub)category is automatically set in this case:: - sage: k = GF(11) - sage: R. = k[[]] - sage: R.category() + sage: k = GF(11) # optional - sage.rings.finite_rings + sage: R. = k[[]] # optional - sage.rings.finite_rings + sage: R.category() # optional - sage.rings.finite_rings Category of complete discrete valuation rings - sage: TestSuite(R).run() + sage: TestSuite(R).run() # optional - sage.rings.finite_rings It is checked that the default precision is non-negative (see :trac:`19409`):: @@ -615,13 +615,13 @@ def _repr_(self): EXAMPLES:: - sage: R = GF(17)[['y']] - sage: R + sage: R = GF(17)[['y']] # optional - sage.rings.finite_rings + sage: R # optional - sage.rings.finite_rings Power Series Ring in y over Finite Field of size 17 - sage: R.__repr__() + sage: R.__repr__() # optional - sage.rings.finite_rings 'Power Series Ring in y over Finite Field of size 17' - sage: R.rename('my power series ring') - sage: R + sage: R.rename('my power series ring') # optional - sage.rings.finite_rings + sage: R # optional - sage.rings.finite_rings my power series ring """ s = "Power Series Ring in %s over %s"%(self.variable_name(), self.base_ring()) @@ -661,11 +661,11 @@ def _latex_(self): EXAMPLES:: - sage: R = GF(17)[['y']] - sage: latex(R) # indirect doctest + sage: R = GF(17)[['y']] # optional - sage.rings.finite_rings + sage: latex(R) # indirect doctest # optional - sage.rings.finite_rings \Bold{F}_{17}[[y]] - sage: R = GF(17)[['y12']] - sage: latex(R) + sage: R = GF(17)[['y12']] # optional - sage.rings.finite_rings + sage: latex(R) # optional - sage.rings.finite_rings \Bold{F}_{17}[[y_{12}]] """ return "%s[[%s]]"%(latex.latex(self.base_ring()), self.latex_variable_names()[0]) @@ -679,14 +679,14 @@ def _coerce_map_from_(self, S): EXAMPLES:: - sage: A = GF(17)[['x']] - sage: A.has_coerce_map_from(ZZ) # indirect doctest + sage: A = GF(17)[['x']] # optional - sage.rings.finite_rings + sage: A.has_coerce_map_from(ZZ) # indirect doctest # optional - sage.rings.finite_rings True - sage: A.has_coerce_map_from(ZZ['x']) + sage: A.has_coerce_map_from(ZZ['x']) # optional - sage.rings.finite_rings True - sage: A.has_coerce_map_from(ZZ['y']) + sage: A.has_coerce_map_from(ZZ['y']) # optional - sage.rings.finite_rings False - sage: A.has_coerce_map_from(ZZ[['x']]) + sage: A.has_coerce_map_from(ZZ[['x']]) # optional - sage.rings.finite_rings True """ @@ -706,12 +706,12 @@ def _element_constructor_(self, f, prec=infinity, check=True): INPUT: - - ``f`` - object, e.g., a power series ring element + - ``f`` -- object, e.g., a power series ring element - - ``prec`` - (default: infinity); truncation precision + - ``prec`` -- (default: infinity); truncation precision for coercion - - ``check`` - bool (default: True), whether to verify + - ``check`` -- bool (default: ``True``), whether to verify that the coefficients, etc., coerce in correctly. @@ -759,15 +759,15 @@ def _element_constructor_(self, f, prec=infinity, check=True): Conversion from symbolic series:: - sage: x,y = var('x,y') - sage: s=(1/(1-x)).series(x,3); s + sage: x,y = var('x,y') # optional - sage.symbolic + sage: s = (1/(1-x)).series(x,3); s # optional - sage.symbolic 1 + 1*x + 1*x^2 + Order(x^3) - sage: R. = PowerSeriesRing(QQ) - sage: R(s) + sage: R. = PowerSeriesRing(QQ) # optional - sage.symbolic + sage: R(s) # optional - sage.symbolic 1 + x + x^2 + O(x^3) - sage: ex=(gamma(1-y)).series(y,3) - sage: R. = PowerSeriesRing(SR) - sage: R(ex) + sage: ex = (gamma(1-y)).series(y,3) # optional - sage.symbolic + sage: R. = PowerSeriesRing(SR) # optional - sage.symbolic + sage: R(ex) # optional - sage.symbolic 1 + euler_gamma*y + (1/2*euler_gamma^2 + 1/12*pi^2)*y^2 + O(y^3) Laurent series with non-negative valuation are accepted (see @@ -823,7 +823,7 @@ def _element_constructor_(self, f, prec=infinity, check=True): def construction(self): """ - Return the functorial construction of self, namely, completion of + Return the functorial construction of ``self``, namely, completion of the univariate polynomial ring with respect to the indeterminate (to a given precision). @@ -891,18 +891,21 @@ def _coerce_impl(self, x): We illustrate canonical coercion between power series rings with compatible base rings:: - sage: R. = PowerSeriesRing(GF(7)['w']) + sage: R. = PowerSeriesRing(GF(7)['w']) # optional - sage.rings.finite_rings sage: S = PowerSeriesRing(ZZ, 't') sage: f = S([1,2,3,4]); f 1 + 2*t + 3*t^2 + 4*t^3 - sage: g = R.coerce(f); g + sage: g = R.coerce(f); g # optional - sage.rings.finite_rings 1 + 2*t + 3*t^2 + 4*t^3 - sage: parent(g) - Power Series Ring in t over Univariate Polynomial Ring in w over Finite Field of size 7 - sage: S.coerce(g) + sage: parent(g) # optional - sage.rings.finite_rings + Power Series Ring in t over + Univariate Polynomial Ring in w over Finite Field of size 7 + sage: S.coerce(g) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: no canonical coercion from Power Series Ring in t over Univariate Polynomial Ring in w over Finite Field of size 7 to Power Series Ring in t over Integer Ring + TypeError: no canonical coercion + from Power Series Ring in t over Univariate Polynomial Ring in w over Finite Field of size 7 + to Power Series Ring in t over Integer Ring """ try: P = x.parent() @@ -924,7 +927,7 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): EXAMPLES:: - sage: S = RationalField(); R.=PowerSeriesRing(S) + sage: S = RationalField(); R. = PowerSeriesRing(S) sage: f = R.hom([0]) sage: f(3) 3 @@ -972,17 +975,17 @@ def _poly_ring(self): def base_extend(self, R): """ - Return the power series ring over R in the same variable as self, - assuming there is a canonical coerce map from the base ring of self - to R. + Return the power series ring over `R` in the same variable as ``self``, + assuming there is a canonical coerce map from the base ring of ``self`` + to `R`. EXAMPLES:: - sage: R. = GF(7)[[]]; R + sage: R. = GF(7)[[]]; R # optional - sage.rings.finite_rings Power Series Ring in T over Finite Field of size 7 - sage: R.change_ring(ZZ) + sage: R.change_ring(ZZ) # optional - sage.rings.finite_rings Power Series Ring in T over Integer Ring - sage: R.base_extend(ZZ) + sage: R.base_extend(ZZ) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no base extension defined @@ -994,20 +997,21 @@ def base_extend(self, R): def change_ring(self, R): """ - Return the power series ring over R in the same variable as self. + Return the power series ring over `R` in the same variable as ``self``. EXAMPLES:: sage: R. = QQ[[]]; R Power Series Ring in T over Rational Field - sage: R.change_ring(GF(7)) + sage: R.change_ring(GF(7)) # optional - sage.rings.finite_rings Power Series Ring in T over Finite Field of size 7 - sage: R.base_extend(GF(7)) + sage: R.base_extend(GF(7)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no base extension defined - sage: R.base_extend(QuadraticField(3,'a')) - Power Series Ring in T over Number Field in a with defining polynomial x^2 - 3 with a = 1.732050807568878? + sage: R.base_extend(QuadraticField(3,'a')) # optional - sage.rings.number_field + Power Series Ring in T over Number Field in a + with defining polynomial x^2 - 3 with a = 1.732050807568878? """ return PowerSeriesRing(R, name = self.variable_name(), default_prec = self.default_prec()) @@ -1026,7 +1030,7 @@ def change_var(self, var): def is_exact(self): """ - Return False since the ring of power series over any ring is not + Return ``False`` since the ring of power series over any ring is not exact. EXAMPLES:: @@ -1096,13 +1100,12 @@ def random_element(self, prec=None, *args, **kwds): r""" Return a random power series. - INPUT: - - ``prec`` - Integer specifying precision of output (default: - default precision of self) + - ``prec`` -- Integer specifying precision of output (default: + default precision of ``self``) - - ``*args, **kwds`` - Passed on to the ``random_element`` method for + - ``*args``, ``**kwds`` -- Passed on to the ``random_element`` method for the base ring OUTPUT: @@ -1111,7 +1114,6 @@ def random_element(self, prec=None, *args, **kwds): random elements from the base ring, randomized subject to the arguments ``*args`` and ``**kwds`` - ALGORITHM: Call the ``random_element`` method on the underlying polynomial @@ -1131,7 +1133,8 @@ def random_element(self, prec=None, *args, **kwds): sage: T.default_prec() 20 sage: T.random_element() # random - 4 + 2*t - t^2 - t^3 + 2*t^4 + t^5 + t^6 - 2*t^7 - t^8 - t^9 + t^11 - 6*t^12 + 2*t^14 + 2*t^16 - t^17 - 3*t^18 + O(t^20) + 4 + 2*t - t^2 - t^3 + 2*t^4 + t^5 + t^6 - 2*t^7 - t^8 - t^9 + t^11 + - 6*t^12 + 2*t^14 + 2*t^16 - t^17 - 3*t^18 + O(t^20) sage: S = PowerSeriesRing(ZZ,'t', default_prec=4) sage: S.random_element() # random 2 - t - 5*t^2 + t^3 + O(t^4) @@ -1144,7 +1147,9 @@ def random_element(self, prec=None, *args, **kwds): sage: SR = PowerSeriesRing(RR,'v') sage: SZ.random_element(x=4, y=6) # random - 4 + 5*v + 5*v^2 + 5*v^3 + 4*v^4 + 5*v^5 + 5*v^6 + 5*v^7 + 4*v^8 + 5*v^9 + 4*v^10 + 4*v^11 + 5*v^12 + 5*v^13 + 5*v^14 + 5*v^15 + 5*v^16 + 5*v^17 + 4*v^18 + 5*v^19 + O(v^20) + 4 + 5*v + 5*v^2 + 5*v^3 + 4*v^4 + 5*v^5 + 5*v^6 + 5*v^7 + 4*v^8 + + 5*v^9 + 4*v^10 + 4*v^11 + 5*v^12 + 5*v^13 + 5*v^14 + 5*v^15 + + 5*v^16 + 5*v^17 + 4*v^18 + 5*v^19 + O(v^20) sage: SZ.random_element(3, x=4, y=6) # random 5 + 4*v + 5*v^2 + O(v^3) sage: SQ.random_element(3, num_bound=3, den_bound=100) # random @@ -1159,7 +1164,7 @@ def random_element(self, prec=None, *args, **kwds): def __contains__(self, x): """ - Return True if x is an element of this power series ring or + Return ``True`` if x is an element of this power series ring or canonically coerces to this ring. EXAMPLES:: @@ -1181,7 +1186,7 @@ def __contains__(self, x): def is_field(self, proof = True): """ - Return False since the ring of power series over any ring is never + Return ``False`` since the ring of power series over any ring is never a field. EXAMPLES:: @@ -1194,7 +1199,7 @@ def is_field(self, proof = True): def is_finite(self): """ - Return False since the ring of power series over any ring is never + Return ``False`` since the ring of power series over any ring is never finite. EXAMPLES:: @@ -1229,11 +1234,11 @@ def residue_field(self): EXAMPLES:: - sage: R. = PowerSeriesRing(GF(17)) - sage: R.residue_field() + sage: R. = PowerSeriesRing(GF(17)) # optional - sage.rings.finite_rings + sage: R.residue_field() # optional - sage.rings.finite_rings Finite Field of size 17 - sage: R. = PowerSeriesRing(Zp(5)) - sage: R.residue_field() + sage: R. = PowerSeriesRing(Zp(5)) # optional - sage.rings.padics + sage: R.residue_field() # optional - sage.rings.padics Finite Field of size 5 """ if self.base_ring().is_field(): @@ -1248,12 +1253,12 @@ def laurent_series_ring(self): EXAMPLES:: - sage: R. = PowerSeriesRing(ZZ,default_prec=5) + sage: R. = PowerSeriesRing(ZZ, default_prec=5) sage: S = R.laurent_series_ring(); S Laurent Series Ring in t over Integer Ring sage: S.default_prec() 5 - sage: f = 1+t; g=1/f; g + sage: f = 1 + t; g = 1/f; g 1 - t + t^2 - t^3 + t^4 + O(t^5) """ try: @@ -1326,10 +1331,10 @@ def fraction_field(self): EXAMPLES:: - sage: R. = PowerSeriesRing(GF(7)) - sage: R.fraction_field() + sage: R. = PowerSeriesRing(GF(7)) # optional - sage.rings.finite_rings + sage: R.fraction_field() # optional - sage.rings.finite_rings Laurent Series Ring in t over Finite Field of size 7 - sage: Frac(R) + sage: Frac(R) # optional - sage.rings.finite_rings Laurent Series Ring in t over Finite Field of size 7 """ return self.laurent_series_ring() @@ -1343,7 +1348,7 @@ def unpickle_power_series_ring_v0(base_ring, name, default_prec, sparse): EXAMPLES:: sage: P. = PowerSeriesRing(QQ) - sage: loads(dumps(P)) == P # indirect doctest + sage: loads(dumps(P)) == P # indirect doctest True """ return PowerSeriesRing(base_ring, name=name, default_prec = default_prec, sparse=sparse) diff --git a/src/sage/rings/power_series_ring_element.pyx b/src/sage/rings/power_series_ring_element.pyx index 2422521fba8..c2a544c4fe8 100644 --- a/src/sage/rings/power_series_ring_element.pyx +++ b/src/sage/rings/power_series_ring_element.pyx @@ -126,22 +126,22 @@ from sage.structure.richcmp cimport richcmp def is_PowerSeries(x): """ - Return True if ``x`` is an instance of a univariate + Return ``True`` if ``x`` is an instance of a univariate or multivariate power series. EXAMPLES:: sage: R. = PowerSeriesRing(ZZ) sage: from sage.rings.power_series_ring_element import is_PowerSeries - sage: is_PowerSeries(1+x^2) + sage: is_PowerSeries(1 + x^2) True - sage: is_PowerSeries(x-x) + sage: is_PowerSeries(x - x) True sage: is_PowerSeries(0) False - sage: var('x') + sage: var('x') # optional - sage.symbolic x - sage: is_PowerSeries(1+x^2) + sage: is_PowerSeries(1 + x^2) # optional - sage.symbolic False """ return isinstance(x, PowerSeries) @@ -163,9 +163,9 @@ cdef class PowerSeries(AlgebraElement): sage: PowerSeriesRing(CC, 'q') Power Series Ring in q over Complex Field with 53 bits of precision - sage: T = PowerSeriesRing(GF(3),5,'t'); T - Multivariate Power Series Ring in t0, t1, t2, t3, t4 over Finite - Field of size 3 + sage: T = PowerSeriesRing(GF(3), 5, 't'); T # optional - sage.rings.finite_rings + Multivariate Power Series Ring in t0, t1, t2, t3, t4 + over Finite Field of size 3 """ AlgebraElement.__init__(self, parent) self.__is_gen = is_gen @@ -222,7 +222,7 @@ cdef class PowerSeries(AlgebraElement): def is_gen(self): """ - Return True if this is the generator (the variable) of the power + Return ``True`` if this is the generator (the variable) of the power series ring. EXAMPLES:: @@ -285,13 +285,13 @@ cdef class PowerSeries(AlgebraElement): sage: R. = QQ[[]]; R Power Series Ring in T over Rational Field sage: f = 1 - 1/2*T + 1/3*T^2 + O(T^3) - sage: f.base_extend(GF(5)) + sage: f.base_extend(GF(5)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no base extension defined - sage: f.change_ring(GF(5)) + sage: f.change_ring(GF(5)) # optional - sage.rings.finite_rings 1 + 2*T + 2*T^2 + O(T^3) - sage: f.change_ring(GF(3)) + sage: f.change_ring(GF(3)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: inverse of Mod(0, 3) does not exist @@ -301,18 +301,18 @@ cdef class PowerSeries(AlgebraElement): :: - sage: K. = NumberField(cyclotomic_polynomial(3), 'a') - sage: R. = K[['t']] - sage: (4*t).change_ring(ZZ) + sage: K. = NumberField(cyclotomic_polynomial(3), 'a') # optional - sage.rings.number_field + sage: R. = K[['t']] # optional - sage.rings.number_field + sage: (4*t).change_ring(ZZ) # optional - sage.rings.number_field 4*t This does not succeed because ``ZZ(K(a+1))`` is not defined. :: - sage: K. = NumberField(cyclotomic_polynomial(3), 'a') - sage: R. = K[['t']] - sage: ((a+1)*t).change_ring(ZZ) + sage: K. = NumberField(cyclotomic_polynomial(3), 'a') # optional - sage.rings.number_field + sage: R. = K[['t']] # optional - sage.rings.number_field + sage: ((a+1)*t).change_ring(ZZ) # optional - sage.rings.number_field Traceback (most recent call last): ... TypeError: Unable to coerce a + 1 to an integer @@ -492,11 +492,11 @@ cdef class PowerSeries(AlgebraElement): EXAMPLES:: - sage: A. = PowerSeriesRing(GF(5)) - sage: x = t + t^2 + O(t^5) - sage: x.lift_to_precision(10) + sage: A. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: x = t + t^2 + O(t^5) # optional - sage.rings.finite_rings + sage: x.lift_to_precision(10) # optional - sage.rings.finite_rings t + t^2 + O(t^10) - sage: x.lift_to_precision() + sage: x.lift_to_precision() # optional - sage.rings.finite_rings t + t^2 """ @@ -530,8 +530,8 @@ cdef class PowerSeries(AlgebraElement): EXAMPLES:: - sage: R. = GF(49,'alpha')[[]] - sage: (t^2 + O(t^3)).base_ring() + sage: R. = GF(49,'alpha')[[]] # optional - sage.rings.finite_rings + sage: (t^2 + O(t^3)).base_ring() # optional - sage.rings.finite_rings Finite Field in alpha of size 7^2 """ return self._parent.base_ring() @@ -808,10 +808,10 @@ cdef class PowerSeries(AlgebraElement): EXAMPLES:: - sage: R. = GF(2)[[]] - sage: f = 1/(1+I+O(I^8)); f + sage: R. = GF(2)[[]] # optional - sage.rings.finite_rings + sage: f = 1/(1+I+O(I^8)); f # optional - sage.rings.finite_rings 1 + I + I^2 + I^3 + I^4 + I^5 + I^6 + I^7 + O(I^8) - sage: f.truncate(5) + sage: f.truncate(5) # optional - sage.rings.finite_rings I^4 + I^3 + I^2 + I + 1 """ if prec is infinity: @@ -952,7 +952,7 @@ cdef class PowerSeries(AlgebraElement): def __bool__(self): """ - Return True if this power series is not equal to 0. + Return ``True`` if this power series is not equal to 0. EXAMPLES:: @@ -972,7 +972,7 @@ cdef class PowerSeries(AlgebraElement): def is_unit(self): """ - Return True if this power series is invertible. + Return ``True`` if this power series is invertible. A power series is invertible precisely when the constant term is invertible. @@ -1113,9 +1113,9 @@ cdef class PowerSeries(AlgebraElement): """ EXAMPLES:: - sage: R. = Qp(7)[[]] - sage: f = (48*67 + 46*67^2)*T + (1 + 42*67 + 5*67^3)*T^2 + O(T^3) - sage: f % 67 + sage: R. = Qp(7)[[]] # optional - sage.rings.padics + sage: f = (48*67 + 46*67^2)*T + (1 + 42*67 + 5*67^3)*T^2 + O(T^3) # optional - sage.rings.padics + sage: f % 67 # optional - sage.rings.padics T^2 + O(T^3) """ from sage.rings.power_series_ring import PowerSeriesRing @@ -1203,12 +1203,12 @@ cdef class PowerSeries(AlgebraElement): EXAMPLES:: - sage: R. = PowerSeriesRing(QQ, implementation='pari') - sage: f = exp(x) + O(x^7); f + sage: R. = PowerSeriesRing(QQ, implementation='pari') # optional - sage.libs.pari + sage: f = exp(x) + O(x^7); f # optional - sage.libs.pari 1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + 1/720*x^6 + O(x^7) - sage: f << 2 + sage: f << 2 # optional - sage.libs.pari x^2 + x^3 + 1/2*x^4 + 1/6*x^5 + 1/24*x^6 + 1/120*x^7 + 1/720*x^8 + O(x^9) - sage: (f << 99) >> 99 + sage: (f << 99) >> 99 # optional - sage.libs.pari 1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + 1/720*x^6 + O(x^7) """ return self.shift(n) @@ -1221,22 +1221,22 @@ cdef class PowerSeries(AlgebraElement): EXAMPLES:: - sage: R. = PowerSeriesRing(QQ, implementation='pari') - sage: f = exp(x) + O(x^7) - sage: f >> 3 + sage: R. = PowerSeriesRing(QQ, implementation='pari') # optional - sage.libs.pari + sage: f = exp(x) + O(x^7) # optional - sage.libs.pari + sage: f >> 3 # optional - sage.libs.pari 1/6 + 1/24*x + 1/120*x^2 + 1/720*x^3 + O(x^4) - sage: f >> 7 + sage: f >> 7 # optional - sage.libs.pari O(x^0) - sage: f >> 99 + sage: f >> 99 # optional - sage.libs.pari O(x^0) - sage: (f >> 99) << 99 + sage: (f >> 99) << 99 # optional - sage.libs.pari O(x^99) """ return self.shift(-n) def is_monomial(self): """ - Return True if this element is a monomial. That is, if self is + Return ``True`` if this element is a monomial. That is, if self is `x^n` for some non-negative integer `n`. EXAMPLES:: @@ -1275,9 +1275,9 @@ cdef class PowerSeries(AlgebraElement): EXAMPLES:: - sage: R. = SR[[]] - sage: f = (1+I)*x^2 + 3*x - I - sage: f.map_coefficients(lambda z: z.conjugate()) + sage: R. = SR[[]] # optional - sage.symbolic + sage: f = (1+I)*x^2 + 3*x - I # optional - sage.symbolic + sage: f.map_coefficients(lambda z: z.conjugate()) # optional - sage.symbolic I + 3*x + (-I + 1)*x^2 sage: R. = ZZ[[]] sage: f = x^2 + 2 @@ -1287,28 +1287,28 @@ cdef class PowerSeries(AlgebraElement): Examples with different base ring:: sage: R. = ZZ[[]] - sage: k = GF(2) - sage: residue = lambda x: k(x) - sage: f = 4*x^2+x+3 - sage: g = f.map_coefficients(residue); g + sage: k = GF(2) # optional - sage.rings.finite_rings + sage: residue = lambda x: k(x) # optional - sage.rings.finite_rings + sage: f = 4*x^2+x+3 # optional - sage.rings.finite_rings + sage: g = f.map_coefficients(residue); g # optional - sage.rings.finite_rings 1 + x - sage: g.parent() + sage: g.parent() # optional - sage.rings.finite_rings Power Series Ring in x over Integer Ring - sage: g = f.map_coefficients(residue, new_base_ring = k); g + sage: g = f.map_coefficients(residue, new_base_ring=k); g # optional - sage.rings.finite_rings 1 + x - sage: g.parent() + sage: g.parent() # optional - sage.rings.finite_rings Power Series Ring in x over Finite Field of size 2 - sage: residue = k.coerce_map_from(ZZ) - sage: g = f.map_coefficients(residue); g + sage: residue = k.coerce_map_from(ZZ) # optional - sage.rings.finite_rings + sage: g = f.map_coefficients(residue); g # optional - sage.rings.finite_rings 1 + x - sage: g.parent() + sage: g.parent() # optional - sage.rings.finite_rings Power Series Ring in x over Finite Field of size 2 Tests other implementations:: - sage: R. = PowerSeriesRing(GF(11), implementation='pari') - sage: f = q - q^3 + O(q^10) - sage: f.map_coefficients(lambda c: c - 2) + sage: R. = PowerSeriesRing(GF(11), implementation='pari') # optional - sage.rings.finite_rings + sage: f = q - q^3 + O(q^10) # optional - sage.rings.finite_rings + sage: f.map_coefficients(lambda c: c - 2) # optional - sage.rings.finite_rings 10*q + 8*q^3 + O(q^10) """ pol = self.polynomial() @@ -1351,7 +1351,7 @@ cdef class PowerSeries(AlgebraElement): Another example:: - sage: (log(1+t)/t).jacobi_continued_fraction() + sage: (log(1+t)/t).jacobi_continued_fraction() # optional - sage.symbolic ((1/2, -1/12), (1/2, -1/15), (1/2, -9/140), @@ -1410,13 +1410,13 @@ cdef class PowerSeries(AlgebraElement): EXAMPLES:: sage: t = PowerSeriesRing(QQ, 't').gen() - sage: s = sum(catalan_number(k) * t**k for k in range(12)).O(12) - sage: s.stieltjes_continued_fraction() + sage: s = sum(catalan_number(k) * t**k for k in range(12)).O(12) # optional - sage.combinat + sage: s.stieltjes_continued_fraction() # optional - sage.combinat (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) Another example:: - sage: (exp(t)).stieltjes_continued_fraction() + sage: (exp(t)).stieltjes_continued_fraction() # optional - sage.symbolic (1, -1/2, 1/6, @@ -1464,7 +1464,7 @@ cdef class PowerSeries(AlgebraElement): def is_square(self): """ - Return True if this function has a square root in this ring, e.g., + Return ``True`` if this function has a square root in this ring, e.g., there is an element `y` in ``self.parent()`` such that `y^2` equals ``self``. @@ -1773,11 +1773,11 @@ cdef class PowerSeries(AlgebraElement): Positive characteristic:: - sage: R. = GF(3)[[]] - sage: p = 1 + 2 * u^2 - sage: p.nth_root(4) + sage: R. = GF(3)[[]] # optional - sage.rings.finite_rings + sage: p = 1 + 2 * u^2 # optional - sage.rings.finite_rings + sage: p.nth_root(4) # optional - sage.rings.finite_rings 1 + 2*u^2 + u^6 + 2*u^8 + u^12 + 2*u^14 + O(u^20) - sage: p.nth_root(4)**4 + sage: p.nth_root(4)**4 # optional - sage.rings.finite_rings 1 + 2*u^2 + O(u^20) TESTS: @@ -1848,14 +1848,14 @@ cdef class PowerSeries(AlgebraElement): sage: t = PowerSeriesRing(QQ, 't').gen() sage: f = (t + t**2).O(4) - sage: cos(f) + sage: cos(f) # optional - sage.symbolic 1 - 1/2*t^2 - t^3 + O(t^4) For several variables:: sage: T. = PowerSeriesRing(ZZ,2) sage: f = a + b + a*b + T.O(3) - sage: cos(f) + sage: cos(f) # optional - sage.symbolic 1 - 1/2*a^2 - a*b - 1/2*b^2 + O(a, b)^3 sage: f.cos() 1 - 1/2*a^2 - a*b - 1/2*b^2 + O(a, b)^3 @@ -1866,7 +1866,7 @@ cdef class PowerSeries(AlgebraElement): one raises an error:: sage: g = 2+f - sage: cos(g) + sage: cos(g) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: can only apply cos to formal power series with zero constant term @@ -1875,16 +1875,16 @@ cdef class PowerSeries(AlgebraElement): sage: T.default_prec() 12 - sage: cos(a) + sage: cos(a) # optional - sage.symbolic 1 - 1/2*a^2 + 1/24*a^4 - 1/720*a^6 + 1/40320*a^8 - 1/3628800*a^10 + O(a, b)^12 sage: a.cos(prec=5) 1 - 1/2*a^2 + 1/24*a^4 + O(a, b)^5 - sage: cos(a + T.O(5)) + sage: cos(a + T.O(5)) # optional - sage.symbolic 1 - 1/2*a^2 + 1/24*a^4 + O(a, b)^5 TESTS:: - sage: cos(a^2 + T.O(5)) + sage: cos(a^2 + T.O(5)) # optional - sage.symbolic 1 - 1/2*a^4 + O(a, b)^5 """ R = self.parent() @@ -1933,14 +1933,14 @@ cdef class PowerSeries(AlgebraElement): sage: t = PowerSeriesRing(QQ, 't').gen() sage: f = (t + t**2).O(4) - sage: sin(f) + sage: sin(f) # optional - sage.symbolic t + t^2 - 1/6*t^3 + O(t^4) For several variables:: sage: T. = PowerSeriesRing(ZZ,2) sage: f = a + b + a*b + T.O(3) - sage: sin(f) + sage: sin(f) # optional - sage.symbolic a + b + a*b + O(a, b)^3 sage: f.sin() a + b + a*b + O(a, b)^3 @@ -1951,7 +1951,7 @@ cdef class PowerSeries(AlgebraElement): one raises an error:: sage: g = 2+f - sage: sin(g) + sage: sin(g) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: can only apply sin to formal power series with zero constant term @@ -1960,16 +1960,16 @@ cdef class PowerSeries(AlgebraElement): sage: T.default_prec() 12 - sage: sin(a) + sage: sin(a) # optional - sage.symbolic a - 1/6*a^3 + 1/120*a^5 - 1/5040*a^7 + 1/362880*a^9 - 1/39916800*a^11 + O(a, b)^12 sage: a.sin(prec=5) a - 1/6*a^3 + O(a, b)^5 - sage: sin(a + T.O(5)) + sage: sin(a + T.O(5)) # optional - sage.symbolic a - 1/6*a^3 + O(a, b)^5 TESTS:: - sage: sin(a^2 + T.O(5)) + sage: sin(a^2 + T.O(5)) # optional - sage.symbolic a^2 + O(a, b)^5 """ R = self.parent() @@ -2019,14 +2019,14 @@ cdef class PowerSeries(AlgebraElement): sage: t = PowerSeriesRing(QQ, 't').gen() sage: f = (t + t**2).O(4) - sage: tan(f) + sage: tan(f) # optional - sage.symbolic t + t^2 + 1/3*t^3 + O(t^4) For several variables:: sage: T. = PowerSeriesRing(ZZ,2) sage: f = a + b + a*b + T.O(3) - sage: tan(f) + sage: tan(f) # optional - sage.symbolic a + b + a*b + O(a, b)^3 sage: f.tan() a + b + a*b + O(a, b)^3 @@ -2036,8 +2036,8 @@ cdef class PowerSeries(AlgebraElement): If the power series has a non-zero constant coefficient `c`, one raises an error:: - sage: g = 2+f - sage: tan(g) + sage: g = 2 + f + sage: tan(g) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: can only apply tan to formal power series with zero constant term @@ -2046,16 +2046,16 @@ cdef class PowerSeries(AlgebraElement): sage: T.default_prec() 12 - sage: tan(a) + sage: tan(a) # optional - sage.symbolic a + 1/3*a^3 + 2/15*a^5 + 17/315*a^7 + 62/2835*a^9 + 1382/155925*a^11 + O(a, b)^12 sage: a.tan(prec=5) a + 1/3*a^3 + O(a, b)^5 - sage: tan(a + T.O(5)) + sage: tan(a + T.O(5)) # optional - sage.symbolic a + 1/3*a^3 + O(a, b)^5 TESTS:: - sage: tan(a^2 + T.O(5)) + sage: tan(a^2 + T.O(5)) # optional - sage.symbolic a^2 + O(a, b)^5 """ if not self[0].is_zero(): @@ -2083,14 +2083,14 @@ cdef class PowerSeries(AlgebraElement): sage: t = PowerSeriesRing(QQ, 't').gen() sage: f = (t + t**2).O(4) - sage: sinh(f) + sage: sinh(f) # optional - sage.symbolic t + t^2 + 1/6*t^3 + O(t^4) For several variables:: sage: T. = PowerSeriesRing(ZZ,2) sage: f = a + b + a*b + T.O(3) - sage: sin(f) + sage: sinh(f) # optional - sage.symbolic a + b + a*b + O(a, b)^3 sage: f.sinh() a + b + a*b + O(a, b)^3 @@ -2100,8 +2100,8 @@ cdef class PowerSeries(AlgebraElement): If the power series has a non-zero constant coefficient `c`, one raises an error:: - sage: g = 2+f - sage: sinh(g) + sage: g = 2 + f + sage: sinh(g) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: can only apply sinh to formal power series with zero @@ -2111,17 +2111,17 @@ cdef class PowerSeries(AlgebraElement): sage: T.default_prec() 12 - sage: sinh(a) + sage: sinh(a) # optional - sage.symbolic a + 1/6*a^3 + 1/120*a^5 + 1/5040*a^7 + 1/362880*a^9 + 1/39916800*a^11 + O(a, b)^12 sage: a.sinh(prec=5) a + 1/6*a^3 + O(a, b)^5 - sage: sinh(a + T.O(5)) + sage: sinh(a + T.O(5)) # optional - sage.symbolic a + 1/6*a^3 + O(a, b)^5 TESTS:: - sage: sinh(a^2 + T.O(5)) + sage: sinh(a^2 + T.O(5)) # optional - sage.symbolic a^2 + O(a, b)^5 """ @@ -2172,14 +2172,14 @@ cdef class PowerSeries(AlgebraElement): sage: t = PowerSeriesRing(QQ, 't').gen() sage: f = (t + t**2).O(4) - sage: cosh(f) + sage: cosh(f) # optional - sage.symbolic 1 + 1/2*t^2 + t^3 + O(t^4) For several variables:: sage: T. = PowerSeriesRing(ZZ,2) sage: f = a + b + a*b + T.O(3) - sage: cosh(f) + sage: cosh(f) # optional - sage.symbolic 1 + 1/2*a^2 + a*b + 1/2*b^2 + O(a, b)^3 sage: f.cosh() 1 + 1/2*a^2 + a*b + 1/2*b^2 + O(a, b)^3 @@ -2189,8 +2189,8 @@ cdef class PowerSeries(AlgebraElement): If the power series has a non-zero constant coefficient `c`, one raises an error:: - sage: g = 2+f - sage: cosh(g) + sage: g = 2 + f + sage: cosh(g) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: can only apply cosh to formal power series with zero @@ -2200,17 +2200,17 @@ cdef class PowerSeries(AlgebraElement): sage: T.default_prec() 12 - sage: cosh(a) + sage: cosh(a) # optional - sage.symbolic 1 + 1/2*a^2 + 1/24*a^4 + 1/720*a^6 + 1/40320*a^8 + 1/3628800*a^10 + O(a, b)^12 sage: a.cosh(prec=5) 1 + 1/2*a^2 + 1/24*a^4 + O(a, b)^5 - sage: cosh(a + T.O(5)) + sage: cosh(a + T.O(5)) # optional - sage.symbolic 1 + 1/2*a^2 + 1/24*a^4 + O(a, b)^5 TESTS:: - sage: cosh(a^2 + T.O(5)) + sage: cosh(a^2 + T.O(5)) # optional - sage.symbolic 1 + 1/2*a^4 + O(a, b)^5 """ @@ -2260,14 +2260,14 @@ cdef class PowerSeries(AlgebraElement): sage: t = PowerSeriesRing(QQ, 't').gen() sage: f = (t + t**2).O(4) - sage: tanh(f) + sage: tanh(f) # optional - sage.symbolic t + t^2 - 1/3*t^3 + O(t^4) For several variables:: sage: T. = PowerSeriesRing(ZZ,2) sage: f = a + b + a*b + T.O(3) - sage: tanh(f) + sage: tanh(f) # optional - sage.symbolic a + b + a*b + O(a, b)^3 sage: f.tanh() a + b + a*b + O(a, b)^3 @@ -2277,8 +2277,8 @@ cdef class PowerSeries(AlgebraElement): If the power series has a non-zero constant coefficient `c`, one raises an error:: - sage: g = 2+f - sage: tanh(g) + sage: g = 2 + f + sage: tanh(g) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: can only apply tanh to formal power series with zero @@ -2288,17 +2288,17 @@ cdef class PowerSeries(AlgebraElement): sage: T.default_prec() 12 - sage: tanh(a) + sage: tanh(a) # optional - sage.symbolic a - 1/3*a^3 + 2/15*a^5 - 17/315*a^7 + 62/2835*a^9 - 1382/155925*a^11 + O(a, b)^12 sage: a.tanh(prec=5) a - 1/3*a^3 + O(a, b)^5 - sage: tanh(a + T.O(5)) + sage: tanh(a + T.O(5)) # optional - sage.symbolic a - 1/3*a^3 + O(a, b)^5 TESTS:: - sage: tanh(a^2 + T.O(5)) + sage: tanh(a^2 + T.O(5)) # optional - sage.symbolic a^2 + O(a, b)^5 """ @@ -2527,8 +2527,8 @@ cdef class PowerSeries(AlgebraElement): :: - sage: R. = PowerSeriesRing(GF(5)) - sage: (1 + x + O(x^2)).exp() + sage: R. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: (1 + x + O(x^2)).exp() # optional - sage.rings.finite_rings Traceback (most recent call last): ... ArithmeticError: constant term of power series does not support exponentiation @@ -2578,7 +2578,7 @@ cdef class PowerSeries(AlgebraElement): sage: t.exp().log() t + O(t^10) - sage: (1+t).log().exp() + sage: (1 + t).log().exp() 1 + t + O(t^10) sage: (-1 + t + O(t^10)).log() @@ -2617,7 +2617,7 @@ cdef class PowerSeries(AlgebraElement): 1 + x^2 + x^10 sage: p.V(3) 1 + x^6 + x^30 - sage: (p+O(x^20)).V(3) + sage: (p + O(x^20)).V(3) 1 + x^6 + x^30 + O(x^60) """ v = self.list() @@ -2652,7 +2652,7 @@ cdef class PowerSeries(AlgebraElement): Dense examples:: sage: R. = PowerSeriesRing(ZZ) - sage: f = 17*t^100 +O(t^110) + sage: f = 17*t^100 + O(t^110) sage: f.valuation() 100 sage: t.valuation() @@ -2744,7 +2744,7 @@ cdef class PowerSeries(AlgebraElement): EXAMPLES:: sage: k. = QQ[[]] - sage: f = 1+17*w+15*w^3+O(w^5) + sage: f = 1 + 17*w + 15*w^3 + O(w^5) sage: parent(f) Power Series Ring in w over Rational Field sage: g = f.laurent_series(); g @@ -2790,27 +2790,27 @@ cdef class PowerSeries(AlgebraElement): There are currently limits to the possible base rings over which this function works. See the documentation for - ``sage.rings.polynomial.polynomial_element.Polynomial.__pari__`` + :meth:`~sage.rings.polynomial.polynomial_element.Polynomial.__pari__` EXAMPLES:: sage: k. = QQ[[]] - sage: f = 1+17*w+15*w^3+O(w^5) - sage: pari(f) # indirect doctest + sage: f = 1 + 17*w + 15*w^3 + O(w^5) + sage: pari(f) # indirect doctest # optional - sage.libs.pari 1 + 17*w + 15*w^3 + O(w^5) - sage: pari(1 - 19*w + w^5) # indirect doctest + sage: pari(1 - 19*w + w^5) # indirect doctest # optional - sage.libs.pari w^5 - 19*w + 1 sage: R. = Zmod(6)[[]] - sage: pari(1 + x + 8*x^3 + O(x^8)) # indirect doctest + sage: pari(1 + x + 8*x^3 + O(x^8)) # indirect doctest # optional - sage.libs.pari Mod(1, 6) + Mod(1, 6)*x + Mod(2, 6)*x^3 + O(x^8) TESTS:: - sage: pari(1 + O(x^1)) + sage: pari(1 + O(x^1)) # optional - sage.libs.pari Mod(1, 6) + O(x) - sage: pari(O(x^1)) + sage: pari(O(x^1)) # optional - sage.libs.pari O(x) - sage: pari(O(x^0)) + sage: pari(O(x^0)) # optional - sage.libs.pari O(x^0) """ n = self.prec() diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 8339127693b..fe71e673da3 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -645,12 +645,12 @@ def order(self): def common_polynomial(self, poly): """ - Given a polynomial with algebraic coefficients, returns a + Given a polynomial with algebraic coefficients, return a wrapper that caches high-precision calculations and - factorizations. This wrapper can be passed to ``polynomial_root`` + factorizations. This wrapper can be passed to :meth:`polynomial_root` in place of the polynomial. - Using ``common_polynomial`` makes no semantic difference, but will + Using :meth:`common_polynomial` makes no semantic difference, but will improve efficiency if you are dealing with multiple roots of a single polynomial. @@ -665,13 +665,13 @@ def common_polynomial(self, poly): sage: phi * tau == -1 True - sage: x = polygen(SR) - sage: p = (x - sqrt(-5)) * (x - sqrt(3)); p + sage: x = polygen(SR) # optional - sage.symbolic + sage: p = (x - sqrt(-5)) * (x - sqrt(3)); p # optional - sage.symbolic x^2 + (-sqrt(3) - sqrt(-5))*x + sqrt(3)*sqrt(-5) - sage: p = QQbar.common_polynomial(p) - sage: a = QQbar.polynomial_root(p, CIF(RIF(-0.1, 0.1), RIF(2, 3))); a + sage: p = QQbar.common_polynomial(p) # optional - sage.symbolic + sage: a = QQbar.polynomial_root(p, CIF(RIF(-0.1, 0.1), RIF(2, 3))); a # optional - sage.symbolic 0.?e-18 + 2.236067977499790?*I - sage: b = QQbar.polynomial_root(p, RIF(1, 2)); b + sage: b = QQbar.polynomial_root(p, RIF(1, 2)); b # optional - sage.symbolic 1.732050807568878? These "common polynomials" can be shared between real and @@ -1177,7 +1177,7 @@ def _coerce_map_from_(self, from_par): True sage: a + AA(3) 5.645751311064590? - sage: AA.has_coerce_map_from(SR) + sage: AA.has_coerce_map_from(SR) # optional - sage.symbolic False sage: K = NumberField(x^3 - 2, 'a', embedding=2.**(1/3)) @@ -1683,7 +1683,7 @@ def _coerce_map_from_(self, from_par): True sage: QQbar.has_coerce_map_from(CC) False - sage: QQbar.has_coerce_map_from(SR) + sage: QQbar.has_coerce_map_from(SR) # optional - sage.symbolic False sage: i + QQbar(2) @@ -3134,7 +3134,7 @@ def root_as_algebraic(self): def is_trivial(self): """ - Return true iff this is the trivial generator (alpha == 1), which + Return ``True`` iff this is the trivial generator (alpha == 1), which does not actually extend the rationals. EXAMPLES:: @@ -4695,27 +4695,27 @@ def radical_expression(self): EXAMPLES:: - sage: AA(1/sqrt(5)).radical_expression() + sage: AA(1/sqrt(5)).radical_expression() # optional - sage.symbolic sqrt(1/5) - sage: AA(sqrt(5 + sqrt(5))).radical_expression() + sage: AA(sqrt(5 + sqrt(5))).radical_expression() # optional - sage.symbolic sqrt(sqrt(5) + 5) - sage: QQbar.zeta(5).radical_expression() + sage: QQbar.zeta(5).radical_expression() # optional - sage.symbolic 1/4*sqrt(5) + 1/2*sqrt(-1/2*sqrt(5) - 5/2) - 1/4 sage: a = QQ[x](x^7 - x - 1).roots(AA, False)[0] - sage: a.radical_expression() + sage: a.radical_expression() # optional - sage.symbolic 1.112775684278706? - sage: a.radical_expression().parent() == SR + sage: a.radical_expression().parent() == SR # optional - sage.symbolic False sage: a = sorted(QQ[x](x^7-x-1).roots(QQbar, False), key=imag)[0] - sage: a.radical_expression() + sage: a.radical_expression() # optional - sage.symbolic -0.3636235193291805? - 0.9525611952610331?*I - sage: QQbar.zeta(5).imag().radical_expression() + sage: QQbar.zeta(5).imag().radical_expression() # optional - sage.symbolic 1/2*sqrt(1/2*sqrt(5) + 5/2) - sage: AA(5/3).radical_expression() + sage: AA(5/3).radical_expression() # optional - sage.symbolic 5/3 - sage: AA(5/3).radical_expression().parent() == SR + sage: AA(5/3).radical_expression().parent() == SR # optional - sage.symbolic True - sage: QQbar(0).radical_expression() + sage: QQbar(0).radical_expression() # optional - sage.symbolic 0 TESTS: @@ -4732,7 +4732,7 @@ def radical_expression(self): sage: f = ComplexIntervalField(v.prec()) sage: [f(b.rhs()).overlaps(f(v)) for b in SR(p).solve(x)] [True, True] - sage: a.radical_expression() + sage: a.radical_expression() # optional - sage.symbolic sqrt(2) + 10000000000000000000000000 """ from sage.symbolic.ring import SR # Lazy to avoid cyclic dependency @@ -4762,15 +4762,15 @@ def _maxima_init_(self, I=None): sage: maxima(AA(7)) 7 - sage: maxima(QQbar(sqrt(5/2))) + sage: maxima(QQbar(sqrt(5/2))) # optional - sage.symbolic sqrt(10)/2 - sage: maxima(AA(-sqrt(5))) + sage: maxima(AA(-sqrt(5))) # optional - sage.symbolic -sqrt(5) - sage: maxima(QQbar(sqrt(-2))) + sage: maxima(QQbar(sqrt(-2))) # optional - sage.symbolic sqrt(2)*%i - sage: maxima(AA(2+sqrt(5))) + sage: maxima(AA(2+sqrt(5))) # optional - sage.symbolic sqrt(5)+2 - sage: maxima(QQ[x](x^7 - x - 1).roots(AA, False)[0]) + sage: maxima(QQ[x](x^7 - x - 1).roots(AA, False)[0]) # optional - sage.symbolic Traceback (most recent call last): ... NotImplementedError: cannot find radical expression @@ -4789,7 +4789,7 @@ class AlgebraicNumber(AlgebraicNumber_base): r""" The class for algebraic numbers (complex numbers which are the roots of a polynomial with integer coefficients). Much of its functionality - is inherited from ``AlgebraicNumber_base``. + is inherited from :class:`AlgebraicNumber_base`. .. automethod:: _richcmp_ """ @@ -4884,24 +4884,24 @@ def _richcmp_(self, other, op): TESTS:: - sage: QQbar.zeta(6) == QQbar(1/2 + I*sqrt(3)/2) + sage: QQbar.zeta(6) == QQbar(1/2 + I*sqrt(3)/2) # optional - sage.symbolic True sage: QQbar(I) == QQbar(I * (2^100+1)/(2^100)) False sage: QQbar(2) == 2 True - sage: QQbar(2) == GF(7)(2) + sage: QQbar(2) == GF(7)(2) # optional - sage.rings.finite_rings False - sage: GF(7)(2) in QQbar + sage: GF(7)(2) in QQbar # optional - sage.rings.finite_rings False - sage: QQbar.zeta(6) != QQbar(1/2 + I*sqrt(3)/2) + sage: QQbar.zeta(6) != QQbar(1/2 + I*sqrt(3)/2) # optional - sage.symbolic False sage: QQbar(I) != QQbar(I * (2^100+1)/(2^100)) True sage: QQbar(2) != 2 False - sage: QQbar(2) != GF(7)(2) + sage: QQbar(2) != GF(7)(2) # optional - sage.rings.finite_rings True sage: QQbar.zeta(3).real() == -1/2 @@ -5118,7 +5118,7 @@ def _rational_(self): def real(self): r""" - Return the real part of self. + Return the real part of ``self``. EXAMPLES:: @@ -5129,7 +5129,7 @@ def real(self): def imag(self): r""" - Return the imaginary part of self. + Return the imaginary part of ``self``. EXAMPLES:: @@ -5173,7 +5173,7 @@ def norm(self): def interval_exact(self, field): r""" - Given a ``ComplexIntervalField``, compute the best possible + Given a :class:`ComplexIntervalField`, compute the best possible approximation of this number in that field. Note that if either the real or imaginary parts of this number are sufficiently close to some floating-point number (and, in @@ -5186,10 +5186,10 @@ def interval_exact(self, field): 0.7071067811865475? + 0.7071067811865475?*I sage: a.interval_exact(CIF) 0.7071067811865475? + 0.7071067811865475?*I - sage: b = QQbar((1+I)*sqrt(2)/2) - sage: (a - b).interval(CIF) + sage: b = QQbar((1+I)*sqrt(2)/2) # optional - sage.symbolic + sage: (a - b).interval(CIF) # optional - sage.symbolic 0.?e-19 + 0.?e-18*I - sage: (a - b).interval_exact(CIF) + sage: (a - b).interval_exact(CIF) # optional - sage.symbolic 0 """ if not isinstance(field, sage.rings.abc.ComplexIntervalField): @@ -5216,12 +5216,12 @@ def _complex_mpfr_field_(self, field): def complex_number(self, field): r""" - Given the complex field ``field`` compute an accurate approximation of + Given the complex field ``field``, compute an accurate approximation of this element in that field. The approximation will be off by at most two ulp's in each component, except for components which are very close to zero, which will have an - absolute error at most `2^{-prec+1}` where `prec` is the precision of + absolute error at most `2^{-prec+1}` where ``prec`` is the precision of the field. EXAMPLES:: @@ -5239,10 +5239,10 @@ def complex_number(self, field): def complex_exact(self, field): r""" - Given a ``ComplexField``, return the best possible approximation of + Given a :class:`ComplexField`, return the best possible approximation of this number in that field. Note that if either component is sufficiently close to the halfway point between two floating-point - numbers in the corresponding ``RealField``, then this will trigger + numbers in the corresponding :class:`RealField`, then this will trigger exact computation, which may be very slow. EXAMPLES:: @@ -5269,7 +5269,7 @@ def multiplicative_order(self): EXAMPLES:: - sage: QQbar(-sqrt(3)/2 - I/2).multiplicative_order() + sage: QQbar(-sqrt(3)/2 - I/2).multiplicative_order() # optional - sage.symbolic 12 sage: QQbar(1).multiplicative_order() 1 @@ -5295,11 +5295,11 @@ def rational_argument(self): EXAMPLES:: - sage: QQbar((1+I)*(sqrt(2)+sqrt(5))).rational_argument() + sage: QQbar((1+I)*(sqrt(2)+sqrt(5))).rational_argument() # optional - sage.symbolic 1/8 - sage: QQbar(-1 + I*sqrt(3)).rational_argument() + sage: QQbar(-1 + I*sqrt(3)).rational_argument() # optional - sage.symbolic 1/3 - sage: QQbar(-1 - I*sqrt(3)).rational_argument() + sage: QQbar(-1 - I*sqrt(3)).rational_argument() # optional - sage.symbolic -1/3 sage: QQbar(3+4*I).rational_argument() is None True @@ -5329,9 +5329,9 @@ def _pow_(self, other): EXAMPLES:: - sage: QQbar(1) ^ QQbar(sqrt(2)) + sage: QQbar(1) ^ QQbar(sqrt(2)) # optional - sage.symbolic 1 - sage: 1 ^ QQbar(sqrt(2)) + sage: 1 ^ QQbar(sqrt(2)) # optional - sage.symbolic 1 sage: QQbar(2) ^ QQbar(2) Traceback (most recent call last): @@ -5401,8 +5401,8 @@ def _more_precision(self): EXAMPLES:: - sage: a = QQbar(sqrt(2)) - sage: a._more_precision() + sage: a = QQbar(sqrt(2)) # optional - sage.symbolic + sage: a._more_precision() # optional - sage.symbolic TESTS: @@ -5426,8 +5426,8 @@ def __reduce__(self): EXAMPLES:: - sage: t = AA(sqrt(2)) - sage: loads(dumps(t)) == t + sage: t = AA(sqrt(2)) # optional - sage.symbolic + sage: loads(dumps(t)) == t # optional - sage.symbolic True """ return (AlgebraicReal, (self._descr, )) @@ -5447,32 +5447,32 @@ def _richcmp_(self, other, op): TESTS:: - sage: AA(golden_ratio) < AA(sqrt(5)) + sage: AA(golden_ratio) < AA(sqrt(5)) # optional - sage.symbolic True - sage: AA(golden_ratio) == AA((sqrt(5)+1)/2) + sage: AA(golden_ratio) == AA((sqrt(5)+1)/2) # optional - sage.symbolic True sage: AA(7) >= AA(50/7) False Check for trivial equality with identical elements:: - sage: x1 = AA(2^(1/50)) - sage: x2 = AA(2^(1/50)) - sage: y = x1 - x2 - sage: y == y + sage: x1 = AA(2^(1/50)) # optional - sage.symbolic + sage: x2 = AA(2^(1/50)) # optional - sage.symbolic + sage: y = x1 - x2 # optional - sage.symbolic + sage: y == y # optional - sage.symbolic True - sage: y >= y + sage: y >= y # optional - sage.symbolic True - sage: y < y + sage: y < y # optional - sage.symbolic False - sage: z = x1 - x2 - sage: z == 0 + sage: z = x1 - x2 # optional - sage.symbolic + sage: z == 0 # optional - sage.symbolic True - sage: a = x1 - x2 - sage: b = x1 - x2 - sage: a == b + sage: a = x1 - x2 # optional - sage.symbolic + sage: b = x1 - x2 # optional - sage.symbolic + sage: a == b # optional - sage.symbolic True """ if self is other: @@ -5608,9 +5608,9 @@ def floor(self): EXAMPLES:: - sage: AA(sqrt(2)).floor() + sage: AA(sqrt(2)).floor() # optional - sage.symbolic 1 - sage: AA(-sqrt(2)).floor() + sage: AA(-sqrt(2)).floor() # optional - sage.symbolic -2 sage: AA(42).floor() 42 @@ -5619,8 +5619,8 @@ def floor(self): Check that :trac:`15501` is fixed:: - sage: a = QQbar((-1)^(1/4)).real() - sage: (floor(a-a) + a).parent() + sage: a = QQbar((-1)^(1/4)).real() # optional - sage.symbolic + sage: (floor(a-a) + a).parent() # optional - sage.symbolic Algebraic Real Field """ return self._floor_ceil(lambda x: x.floor()) @@ -5631,9 +5631,9 @@ def ceil(self): EXAMPLES:: - sage: AA(sqrt(2)).ceil() + sage: AA(sqrt(2)).ceil() # optional - sage.symbolic 2 - sage: AA(-sqrt(2)).ceil() + sage: AA(-sqrt(2)).ceil() # optional - sage.symbolic -1 sage: AA(42).ceil() 42 @@ -5646,7 +5646,7 @@ def round(self): EXAMPLES:: - sage: AA(sqrt(2)).round() + sage: AA(sqrt(2)).round() # optional - sage.symbolic 1 sage: AA(1/2).round() 1 @@ -5661,9 +5661,9 @@ def trunc(self): EXAMPLES:: - sage: AA(sqrt(2)).trunc() + sage: AA(sqrt(2)).trunc() # optional - sage.symbolic 1 - sage: AA(-sqrt(2)).trunc() + sage: AA(-sqrt(2)).trunc() # optional - sage.symbolic -1 sage: AA(1).trunc() 1 @@ -5682,11 +5682,11 @@ def _rational_(self): Rational Field sage: AA(-22/7)._rational_() -22/7 - sage: AA(sqrt(7))._rational_() + sage: AA(sqrt(7))._rational_() # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Cannot coerce irrational Algebraic Real 2.645751311064591? to Rational - sage: v = AA(1/2 + sqrt(2))^3 - AA(11/4*sqrt(2)); v + sage: v = AA(1/2 + sqrt(2))^3 - AA(11/4*sqrt(2)); v # optional - sage.symbolic 3.125000000000000? sage: v._rational_() 25/8 @@ -5705,10 +5705,10 @@ def real(self): EXAMPLES:: - sage: a = AA(sqrt(2) + sqrt(3)) - sage: a.real() + sage: a = AA(sqrt(2) + sqrt(3)) # optional - sage.symbolic + sage: a.real() # optional - sage.symbolic 3.146264369941973? - sage: a.real() is a + sage: a.real() is a # optional - sage.symbolic True """ return self @@ -5721,10 +5721,10 @@ def imag(self): EXAMPLES:: - sage: a = AA(sqrt(2) + sqrt(3)) - sage: a.imag() + sage: a = AA(sqrt(2) + sqrt(3)) # optional - sage.symbolic + sage: a.imag() # optional - sage.symbolic 0 - sage: parent(a.imag()) + sage: parent(a.imag()) # optional - sage.symbolic Algebraic Real Field """ return AA_0 @@ -5735,10 +5735,10 @@ def conjugate(self): EXAMPLES:: - sage: a = AA(sqrt(2) + sqrt(3)) - sage: a.conjugate() + sage: a = AA(sqrt(2) + sqrt(3)) # optional - sage.symbolic + sage: a.conjugate() # optional - sage.symbolic 3.146264369941973? - sage: a.conjugate() is a + sage: a.conjugate() is a # optional - sage.symbolic True """ return self @@ -5751,7 +5751,7 @@ def multiplicative_order(self): that `x^n = 1`. If there is no such `n`, returns ``+Infinity``. We first check that ``abs(x)`` is very close to 1. If so, we compute - `x` exactly and compare it to 1 and -1. + `x` exactly and compare it to `1` and `-1`. EXAMPLES:: @@ -5773,8 +5773,8 @@ def multiplicative_order(self): def sign(self): """ - Compute the sign of this algebraic number (return -1 if negative, - 0 if zero, or 1 if positive). + Compute the sign of this algebraic number (return `-1` if negative, + `0` if zero, or `1` if positive). This computes an interval enclosing this number using 128-bit interval arithmetic; if this interval includes 0, then fall back to @@ -5811,9 +5811,9 @@ def sign(self): sage: (a*b - b*a).sign() 0 - sage: a = AA(sqrt(1/2)) - sage: b = AA(-sqrt(1/2)) - sage: (a + b).sign() + sage: a = AA(sqrt(1/2)) # optional - sage.symbolic + sage: b = AA(-sqrt(1/2)) # optional - sage.symbolic + sage: (a + b).sign() # optional - sage.symbolic 0 TESTS: @@ -5822,17 +5822,17 @@ def sign(self): following example will take a long time (more than 5 seconds) when calling ``y.exactify()``:: - sage: x1 = AA(2^(1/50)) - sage: x2 = AA(2^(1/50)) - sage: y = x1 - x2 - sage: y.sign() + sage: x1 = AA(2^(1/50)) # optional - sage.symbolic + sage: x2 = AA(2^(1/50)) # optional - sage.symbolic + sage: y = x1 - x2 # optional - sage.symbolic + sage: y.sign() # optional - sage.symbolic 0 Simplify to rationals for binary operations when computing the sign:: - sage: a = AA(2^(1/60)) - sage: b = a - (a + 1) - sage: (b + 1).sign() + sage: a = AA(2^(1/60)) # optional - sage.symbolic + sage: b = a - (a + 1) # optional - sage.symbolic + sage: (b + 1).sign() # optional - sage.symbolic 0 """ if not self._value.contains_zero(): @@ -5928,15 +5928,15 @@ def _interval_fast(self, prec): EXAMPLES:: - sage: t = AA(sqrt(7)) - sage: t._interval_fast(100) + sage: t = AA(sqrt(7)) # optional - sage.symbolic + sage: t._interval_fast(100) # optional - sage.symbolic 2.64575131106459059050161575364? """ return self.interval_fast(RealIntervalField(prec)) def interval_exact(self, field): """ - Given a ``RealIntervalField``, compute the best possible + Given a :class:`RealIntervalField`, compute the best possible approximation of this number in that field. Note that if this number is sufficiently close to some floating-point number (and, in particular, if this number is exactly representable in @@ -6010,7 +6010,7 @@ def interval_exact(self, field): def real_number(self, field): """ - Given a ``RealField``, compute a good approximation to self in + Given a :class:`RealField`, compute a good approximation to ``self`` in that field. The approximation will be off by at most two ulp's, except for numbers which are very close to 0, which will have an absolute error at most @@ -6096,7 +6096,7 @@ def _complex_mpfr_field_(self, field): def real_exact(self, field): r""" - Given a ``RealField``, compute the best possible approximation of + Given a :class:`RealField`, compute the best possible approximation of this number in that field. Note that if this number is sufficiently close to the halfway point between two floating-point numbers in the field (for the default @@ -6413,7 +6413,7 @@ def _repr_name_(self): class ANRational(ANDescr): r""" - The subclass of ``ANDescr`` that represents an arbitrary + The subclass of :class:`ANDescr` that represents an arbitrary rational. This class is private, and should not be used directly. """ @@ -6510,7 +6510,7 @@ def generator(self): def is_complex(self): r""" - Return False, since rational numbers are real + Return ``False``, since rational numbers are real EXAMPLES:: @@ -6521,7 +6521,7 @@ def is_complex(self): def exactify(self): r""" - Calculate self exactly. Since self is a rational number, return self. + Calculate ``self`` exactly. Since ``self`` is a rational number, return ``self``. EXAMPLES:: @@ -6547,7 +6547,7 @@ def is_simple(self): def minpoly(self): r""" - Return the min poly of self over `\QQ`. + Return the min poly of ``self`` over `\QQ`. EXAMPLES:: @@ -6558,7 +6558,7 @@ def minpoly(self): def neg(self, n): r""" - Negation of self. + Negation of ``self``. EXAMPLES:: @@ -6573,7 +6573,7 @@ def neg(self, n): def invert(self, n): r""" - 1/self. + 1/``self``. EXAMPLES:: @@ -6586,7 +6586,7 @@ def invert(self, n): def abs(self, n): r""" - Absolute value of self. + Absolute value of ``self``. EXAMPLES:: @@ -6636,7 +6636,7 @@ def angle(self): def scale(self): r""" Return a rational number `r` such that ``self`` is equal to `r e^{2 \pi - i q}` for some `q \in (-1/2, 1/2]`. In other words, just return self + i q}` for some `q \in (-1/2, 1/2]`. In other words, just return ``self`` as a rational number. EXAMPLES:: @@ -6801,7 +6801,7 @@ def _repr_(self): def poly(self): r""" - Return the underlying polynomial of self. + Return the underlying polynomial of ``self``. EXAMPLES:: @@ -6838,7 +6838,7 @@ def complex_roots(self, prec, multiplicity): sage: cp = AA.common_polynomial(x^4 - 2) Note that the precision is not guaranteed to find the tightest - possible interval since ``complex_roots()`` depends on the + possible interval since :meth:`complex_roots` depends on the underlying BLAS implementation. :: sage: cp.complex_roots(30, 1) @@ -6923,7 +6923,7 @@ def factors(self): def generator(self): r""" Return an :class:`AlgebraicGenerator` for a number field containing all - the coefficients of self. + the coefficients of ``self``. EXAMPLES:: @@ -6931,7 +6931,8 @@ def generator(self): sage: p = sqrt(AA(2)) * x^2 - sqrt(AA(3)) sage: cp = AA.common_polynomial(p) sage: cp.generator() - Number Field in a with defining polynomial y^4 - 4*y^2 + 1 with a in -0.5176380902050415? + Number Field in a with defining polynomial y^4 - 4*y^2 + 1 + with a in -0.5176380902050415? """ self.exactify() return self._gen @@ -6939,7 +6940,7 @@ def generator(self): class ANRoot(ANDescr): """ - The subclass of ``ANDescr`` that represents a particular + The subclass of :class:`ANDescr` that represents a particular root of a polynomial with algebraic coefficients. This class is private, and should not be used directly. """ @@ -6992,8 +6993,8 @@ def _repr_(self): def handle_sage_input(self, sib, coerce, is_qqbar): r""" Produce an expression which will reproduce this value when evaluated, - and an indication of whether this value is worth sharing (always True, - for ``ANRoot``). + and an indication of whether this value is worth sharing (always ``True`` + for :class:`ANRoot`). EXAMPLES:: @@ -7074,7 +7075,7 @@ def is_complex(self): def conjugate(self, n): r""" - Complex conjugate of this ANRoot object. + Complex conjugate of this :class:`ANRoot` object. EXAMPLES:: @@ -7461,8 +7462,8 @@ def _complex_isolate_interval(self, interval, prec): def exactify(self): """ - Return either an ``ANRational`` or an - ``ANExtensionElement`` with the same value as this number. + Return either an :class:`ANRational` or an + :class:`ANExtensionElement` with the same value as this number. EXAMPLES:: @@ -7479,10 +7480,10 @@ def exactify(self): Verify that :trac:`12727` is fixed:: - sage: m = sqrt(sin(pi/5)); a = QQbar(m); b = AA(m) - sage: a.minpoly() + sage: m = sqrt(sin(pi/5)); a = QQbar(m); b = AA(m) # optional - sage.symbolic + sage: a.minpoly() # optional - sage.symbolic x^8 - 5/4*x^4 + 5/16 - sage: b.minpoly() + sage: b.minpoly() # optional - sage.symbolic x^8 - 5/4*x^4 + 5/16 """ gen = self._poly.generator() @@ -7624,10 +7625,10 @@ def _interval_fast(self, prec): class ANExtensionElement(ANDescr): r""" - The subclass of ``ANDescr`` that represents a number field + The subclass of :class:`ANDescr` that represents a number field element in terms of a specific generator. Consists of a polynomial with rational coefficients in terms of the generator, and the - generator itself, an ``AlgebraicGenerator``. + generator itself, an :class:`AlgebraicGenerator`. """ def __new__(self, generator, value): @@ -7668,8 +7669,8 @@ def _repr_(self): def handle_sage_input(self, sib, coerce, is_qqbar): r""" Produce an expression which will reproduce this value when evaluated, - and an indication of whether this value is worth sharing (always True, - for ``ANExtensionElement``). + and an indication of whether this value is worth sharing (always ``True`` + for :class:`ANExtensionElement`). EXAMPLES:: @@ -7737,23 +7738,23 @@ def handle_sage_input(self, sib, coerce, is_qqbar): def is_complex(self): r""" - Return True if the number field that defines this element is not real. + Return ``True`` if the number field that defines this element is not real. This does not imply that the element itself is definitely non-real, as in the example below. EXAMPLES:: - sage: rt2 = QQbar(sqrt(2)) - sage: rtm3 = QQbar(sqrt(-3)) - sage: x = rtm3 + rt2 - rtm3 - sage: x.exactify() - sage: y = x._descr - sage: type(y) + sage: rt2 = QQbar(sqrt(2)) # optional - sage.symbolic + sage: rtm3 = QQbar(sqrt(-3)) # optional - sage.symbolic + sage: x = rtm3 + rt2 - rtm3 # optional - sage.symbolic + sage: x.exactify() # optional - sage.symbolic + sage: y = x._descr # optional - sage.symbolic + sage: type(y) # optional - sage.symbolic - sage: y.is_complex() + sage: y.is_complex() # optional - sage.symbolic True - sage: x.imag() == 0 + sage: x.imag() == 0 # optional - sage.symbolic True """ return not self._exactly_real @@ -7763,25 +7764,25 @@ def is_simple(self): Check whether this descriptor represents a value with the same algebraic degree as the number field associated with the descriptor. - For ``ANExtensionElement`` elements, we check this by + For :class:`ANExtensionElement` elements, we check this by comparing the degree of the minimal polynomial to the degree of the field. EXAMPLES:: - sage: rt2 = AA(sqrt(2)) - sage: rt3 = AA(sqrt(3)) - sage: rt2b = rt3 + rt2 - rt3 - sage: rt2.exactify() - sage: rt2._descr + sage: rt2 = AA(sqrt(2)) # optional - sage.symbolic + sage: rt3 = AA(sqrt(3)) # optional - sage.symbolic + sage: rt2b = rt3 + rt2 - rt3 # optional - sage.symbolic + sage: rt2.exactify() # optional - sage.symbolic + sage: rt2._descr # optional - sage.symbolic a where a^2 - 2 = 0 and a in 1.414213562373095? - sage: rt2._descr.is_simple() + sage: rt2._descr.is_simple() # optional - sage.symbolic True - sage: rt2b.exactify() - sage: rt2b._descr + sage: rt2b.exactify() # optional - sage.symbolic + sage: rt2b._descr # optional - sage.symbolic a^3 - 3*a where a^4 - 4*a^2 + 1 = 0 and a in -0.5176380902050415? - sage: rt2b._descr.is_simple() + sage: rt2b._descr.is_simple() # optional - sage.symbolic False """ try: @@ -7792,7 +7793,7 @@ def is_simple(self): def generator(self): r""" - Return the :class:`~AlgebraicGenerator` object corresponding to self. + Return the :class:`~AlgebraicGenerator` object corresponding to ``self``. EXAMPLES:: @@ -7860,13 +7861,13 @@ def simplify(self, n): EXAMPLES:: - sage: rt2 = AA(sqrt(2)) - sage: rt3 = AA(sqrt(3)) - sage: rt2b = rt3 + rt2 - rt3 - sage: rt2b.exactify() - sage: rt2b._descr + sage: rt2 = AA(sqrt(2)) # optional - sage.symbolic + sage: rt3 = AA(sqrt(3)) # optional - sage.symbolic + sage: rt2b = rt3 + rt2 - rt3 # optional - sage.symbolic + sage: rt2b.exactify() # optional - sage.symbolic + sage: rt2b._descr # optional - sage.symbolic a^3 - 3*a where a^4 - 4*a^2 + 1 = 0 and a in -0.5176380902050415? - sage: rt2b._descr.simplify(rt2b) + sage: rt2b._descr.simplify(rt2b) # optional - sage.symbolic a where a^2 - 2 = 0 and a in 1.414213562373095? """ @@ -7894,75 +7895,84 @@ def _interval_fast(self, prec): def neg(self, n): r""" - Negation of self. + Negation of ``self``. EXAMPLES:: - sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(-3)) - sage: a.exactify() - sage: b = a._descr - sage: type(b) + sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(-3)) # optional - sage.symbolic + sage: a.exactify() # optional - sage.symbolic + sage: b = a._descr # optional - sage.symbolic + sage: type(b) # optional - sage.symbolic - sage: c = b.neg(None); c # random (not uniquely represented) - -1/3*a^3 + 1/3*a^2 - a - 1 where a^4 - 2*a^3 + a^2 + 6*a + 3 = 0 and a in 1.724744871391589? + 1.573132184970987?*I - sage: c.generator() == b.generator() and c.field_element_value() + b.field_element_value() == 0 + sage: c = b.neg(None); c # random (not uniquely represented) # optional - sage.symbolic + -1/3*a^3 + 1/3*a^2 - a - 1 where a^4 - 2*a^3 + a^2 + 6*a + 3 = 0 + and a in 1.724744871391589? + 1.573132184970987?*I + sage: (c.generator() == b.generator() # optional - sage.symbolic + ....: and c.field_element_value() + b.field_element_value() == 0) True The parameter is ignored:: - sage: b.neg("random").generator() == c.generator() and b.neg("random").field_element_value() == c.field_element_value() + sage: (b.neg("random").generator() == c.generator() # optional - sage.symbolic + ....: and b.neg("random").field_element_value() == c.field_element_value()) True """ return ANExtensionElement(self._generator, -self._value) def invert(self, n): r""" - Reciprocal of self. + Reciprocal of ``self``. EXAMPLES:: - sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(-3)) - sage: a.exactify() - sage: b = a._descr - sage: type(b) + sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(-3)) # optional - sage.symbolic + sage: a.exactify() # optional - sage.symbolic + sage: b = a._descr # optional - sage.symbolic + sage: type(b) # optional - sage.symbolic - sage: c = b.invert(None); c # random (not uniquely represented) - -7/3*a^3 + 19/3*a^2 - 7*a - 9 where a^4 - 2*a^3 + a^2 + 6*a + 3 = 0 and a in 1.724744871391589? + 1.573132184970987?*I - sage: c.generator() == b.generator() and c.field_element_value() * b.field_element_value() == 1 + sage: c = b.invert(None); c # random (not uniquely represented) # optional - sage.symbolic + -7/3*a^3 + 19/3*a^2 - 7*a - 9 where a^4 - 2*a^3 + a^2 + 6*a + 3 = 0 + and a in 1.724744871391589? + 1.573132184970987?*I + sage: (c.generator() == b.generator() # optional - sage.symbolic + ....: and c.field_element_value() * b.field_element_value() == 1) True The parameter is ignored:: - sage: b.invert("random").generator() == c.generator() and b.invert("random").field_element_value() == c.field_element_value() + sage: (b.invert("random").generator() == c.generator() # optional - sage.symbolic + ....: and b.invert("random").field_element_value() == c.field_element_value()) True """ return ANExtensionElement(self._generator, ~self._value) def conjugate(self, n): - r"""Complex conjugate of self. + r""" + Complex conjugate of ``self``. EXAMPLES:: - sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(-3)) - sage: a.exactify() - sage: b = a._descr - sage: type(b) + sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(-3)) # optional - sage.symbolic + sage: a.exactify() # optional - sage.symbolic + sage: b = a._descr # optional - sage.symbolic + sage: type(b) # optional - sage.symbolic - sage: c = b.conjugate(None); c # random (not uniquely represented) - 1/3*a^3 - 1/3*a^2 + a + 1 where a^4 - 2*a^3 + a^2 + 6*a + 3 = 0 and a in 1.724744871391589? - 1.573132184970987?*I + sage: c = b.conjugate(None); c # random (not uniquely represented) # optional - sage.symbolic + 1/3*a^3 - 1/3*a^2 + a + 1 where a^4 - 2*a^3 + a^2 + 6*a + 3 = 0 + and a in 1.724744871391589? - 1.573132184970987?*I Internally, complex conjugation is implemented by taking the same abstract field element but conjugating the complex embedding of the field:: - sage: c.generator() == b.generator().conjugate() + sage: c.generator() == b.generator().conjugate() # optional - sage.symbolic True - sage: c.field_element_value() == b.field_element_value() + sage: c.field_element_value() == b.field_element_value() # optional - sage.symbolic True The parameter is ignored:: - sage: b.conjugate("random").generator() == c.generator() and b.conjugate("random").field_element_value() == c.field_element_value() + sage: (b.conjugate("random").generator() == c.generator() # optional - sage.symbolic + ....: and b.conjugate("random").field_element_value() == c.field_element_value()) True """ @@ -7976,16 +7986,16 @@ def conjugate(self, n): def norm(self, n): r""" - Norm of self (square of complex absolute value) + Norm of ``self`` (square of complex absolute value) EXAMPLES:: - sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(-3)) - sage: a.exactify() - sage: b = a._descr - sage: type(b) + sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(-3)) # optional - sage.symbolic + sage: a.exactify() # optional - sage.symbolic + sage: b = a._descr # optional - sage.symbolic + sage: type(b) # optional - sage.symbolic - sage: b.norm(a) + sage: b.norm(a) # optional - sage.symbolic """ if self._exactly_real: @@ -7997,33 +8007,33 @@ def norm(self, n): def abs(self, n): r""" - Return the absolute value of self (square root of the norm). + Return the absolute value of ``self`` (square root of the norm). EXAMPLES:: - sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(-3)) - sage: a.exactify() - sage: b = a._descr - sage: type(b) + sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(-3)) # optional - sage.symbolic + sage: a.exactify() # optional - sage.symbolic + sage: b = a._descr # optional - sage.symbolic + sage: type(b) # optional - sage.symbolic - sage: b.abs(a) + sage: b.abs(a) # optional - sage.symbolic Root 3.146264369941972342? of x^2 - 9.89897948556636? """ return AlgebraicReal(self.norm(n)).sqrt()._descr def rational_argument(self, n): r""" - If the argument of self is `2\pi` times some rational number in `[1/2, + If the argument of ``self`` is `2\pi` times some rational number in `[1/2, -1/2)`, return that rational; otherwise, return ``None``. EXAMPLES:: - sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(3)) - sage: a.exactify() - sage: b = a._descr - sage: type(b) + sage: a = QQbar(sqrt(-2)) + QQbar(sqrt(3)) # optional - sage.symbolic + sage: a.exactify() # optional - sage.symbolic + sage: b = a._descr # optional - sage.symbolic + sage: type(b) # optional - sage.symbolic - sage: b.rational_argument(a) is None + sage: b.rational_argument(a) is None # optional - sage.symbolic True sage: x = polygen(QQ) sage: a = (x^4 + 1).roots(QQbar, multiplicities=False)[0] @@ -8074,7 +8084,7 @@ def __init__(self, arg, op): EXAMPLES:: - sage: t = ~QQbar(sqrt(2)); type(t._descr) # indirect doctest + sage: t = ~QQbar(sqrt(2)); type(t._descr) # indirect doctest # optional - sage.symbolic """ self._arg = arg @@ -8087,9 +8097,9 @@ def __reduce__(self): EXAMPLES:: - sage: t = ~QQbar(sqrt(2)); type(t._descr) + sage: t = ~QQbar(sqrt(2)); type(t._descr) # optional - sage.symbolic - sage: loads(dumps(t)) == 1/QQbar(sqrt(2)) + sage: loads(dumps(t)) == 1/QQbar(sqrt(2)) # optional - sage.symbolic True """ return (ANUnaryExpr, (self._arg, self._op)) @@ -8098,7 +8108,7 @@ def handle_sage_input(self, sib, coerce, is_qqbar): r""" Produce an expression which will reproduce this value when evaluated, and an indication of whether this value is worth sharing (always - True for ``ANUnaryExpr``). + ``True`` for :class:`ANUnaryExpr`). EXAMPLES:: @@ -8183,18 +8193,18 @@ def handle_sage_input(self, sib, coerce, is_qqbar): def is_complex(self): r""" Return whether or not this element is complex. Note that this is a data - type check, and triggers no computations -- if it returns False, the + type check, and triggers no computations -- if it returns ``False``, the element might still be real, it just doesn't know it yet. EXAMPLES:: - sage: t = AA(sqrt(2)) - sage: s = (-t)._descr - sage: s + sage: t = AA(sqrt(2)) # optional - sage.symbolic + sage: s = (-t)._descr # optional - sage.symbolic + sage: s # optional - sage.symbolic - sage: s.is_complex() + sage: s.is_complex() # optional - sage.symbolic False - sage: QQbar(-sqrt(2))._descr.is_complex() + sage: QQbar(-sqrt(2))._descr.is_complex() # optional - sage.symbolic True """ return self._complex @@ -8205,11 +8215,11 @@ def _interval_fast(self, prec): EXAMPLES:: - sage: t = AA(sqrt(2)) - sage: s = (-t)._descr - sage: s + sage: t = AA(sqrt(2)) # optional - sage.symbolic + sage: s = (-t)._descr # optional - sage.symbolic + sage: s # optional - sage.symbolic - sage: s._interval_fast(150) + sage: s._interval_fast(150) # optional - sage.symbolic -1.414213562373095048801688724209698078569671876? """ op = self._op @@ -8258,14 +8268,14 @@ def _interval_fast(self, prec): def exactify(self): r""" - Trigger exact computation of self. + Trigger exact computation of ``self``. EXAMPLES:: - sage: v = (-QQbar(sqrt(2)))._descr - sage: type(v) + sage: v = (-QQbar(sqrt(2)))._descr # optional - sage.symbolic + sage: type(v) # optional - sage.symbolic - sage: v.exactify() + sage: v.exactify() # optional - sage.symbolic -a where a^2 - 2 = 0 and a in 1.414213562373095? """ op = self._op @@ -8329,7 +8339,7 @@ def __init__(self, left, right, op): EXAMPLES:: - sage: t = QQbar(sqrt(2)) + QQbar(sqrt(3)); type(t._descr) # indirect doctest + sage: t = QQbar(sqrt(2)) + QQbar(sqrt(3)); type(t._descr) # indirect doctest # optional - sage.symbolic """ self._left = left @@ -8343,9 +8353,9 @@ def __reduce__(self): EXAMPLES:: - sage: t = QQbar(sqrt(2)) + QQbar(sqrt(3)); type(t._descr) + sage: t = QQbar(sqrt(2)) + QQbar(sqrt(3)); type(t._descr) # optional - sage.symbolic - sage: loads(dumps(t)) == QQbar(sqrt(2)) + QQbar(sqrt(3)) + sage: loads(dumps(t)) == QQbar(sqrt(2)) + QQbar(sqrt(3)) # optional - sage.symbolic True """ return (ANBinaryExpr, (self._left, self._right, self._op)) @@ -8354,7 +8364,7 @@ def handle_sage_input(self, sib, coerce, is_qqbar): r""" Produce an expression which will reproduce this value when evaluated, and an indication of whether this value is worth sharing (always - True for ``ANBinaryExpr``). + ``True`` for :class:`ANBinaryExpr`). EXAMPLES:: @@ -8393,10 +8403,10 @@ def handle_sage_input(self, sib, coerce, is_qqbar): True sage: sage_input(n) 1 + AA(3) - sage: rt3 = QQbar(sqrt(3)) - sage: one = rt3/rt3 - sage: n = sqrt(AA(2))+one - sage: one == 1 + sage: rt3 = QQbar(sqrt(3)) # optional - sage.symbolic + sage: one = rt3/rt3 # optional - sage.symbolic + sage: n = sqrt(AA(2)) + one + sage: one == 1 # optional - sage.symbolic True sage: sage_input(n) R. = AA[] @@ -8463,12 +8473,12 @@ def handle_sage_input(self, sib, coerce, is_qqbar): def is_complex(self): r""" Whether this element is complex. Does not trigger exact computation, so - may return True even if the element is real. + may return ``True`` even if the element is real. EXAMPLES:: - sage: x = (QQbar(sqrt(-2)) / QQbar(sqrt(-5)))._descr - sage: x.is_complex() + sage: x = (QQbar(sqrt(-2)) / QQbar(sqrt(-5)))._descr # optional - sage.symbolic + sage: x.is_complex() # optional - sage.symbolic True """ return self._complex @@ -8479,10 +8489,10 @@ def _interval_fast(self, prec): EXAMPLES:: - sage: x = (QQbar(sqrt(-2)) / QQbar(sqrt(-5)))._descr - sage: y= x._interval_fast(64); y + sage: x = (QQbar(sqrt(-2)) / QQbar(sqrt(-5)))._descr # optional - sage.symbolic + sage: y= x._interval_fast(64); y # optional - sage.symbolic 0.632455532033675867? - sage: y.parent() + sage: y.parent() # optional - sage.symbolic Complex Interval Field with 64 bits of precision """ op = self._op @@ -8499,8 +8509,8 @@ def exactify(self): """ TESTS:: - sage: rt2c = QQbar.zeta(3) + AA(sqrt(2)) - QQbar.zeta(3) - sage: rt2c.exactify() + sage: rt2c = QQbar.zeta(3) + AA(sqrt(2)) - QQbar.zeta(3) # optional - sage.symbolic + sage: rt2c.exactify() # optional - sage.symbolic We check to make sure that this method still works even. We do this by increasing the recursion level at each step and @@ -8588,25 +8598,27 @@ def an_binop_expr(a, b, op): EXAMPLES:: - sage: a = QQbar(sqrt(2)) + QQbar(sqrt(3)) - sage: b = QQbar(sqrt(3)) + QQbar(sqrt(5)) - sage: type(a._descr); type(b._descr) + sage: a = QQbar(sqrt(2)) + QQbar(sqrt(3)) # optional - sage.symbolic + sage: b = QQbar(sqrt(3)) + QQbar(sqrt(5)) # optional - sage.symbolic + sage: type(a._descr); type(b._descr) # optional - sage.symbolic sage: from sage.rings.qqbar import an_binop_expr - sage: x = an_binop_expr(a, b, operator.add); x + sage: x = an_binop_expr(a, b, operator.add); x # optional - sage.symbolic - sage: x.exactify() - 6/7*a^7 - 2/7*a^6 - 71/7*a^5 + 26/7*a^4 + 125/7*a^3 - 72/7*a^2 - 43/7*a + 47/7 where a^8 - 12*a^6 + 23*a^4 - 12*a^2 + 1 = 0 and a in -0.3199179336182997? + sage: x.exactify() # optional - sage.symbolic + 6/7*a^7 - 2/7*a^6 - 71/7*a^5 + 26/7*a^4 + 125/7*a^3 - 72/7*a^2 - 43/7*a + 47/7 + where a^8 - 12*a^6 + 23*a^4 - 12*a^2 + 1 = 0 and a in -0.3199179336182997? - sage: a = QQbar(sqrt(2)) + QQbar(sqrt(3)) - sage: b = QQbar(sqrt(3)) + QQbar(sqrt(5)) - sage: type(a._descr) + sage: a = QQbar(sqrt(2)) + QQbar(sqrt(3)) # optional - sage.symbolic + sage: b = QQbar(sqrt(3)) + QQbar(sqrt(5)) # optional - sage.symbolic + sage: type(a._descr) # optional - sage.symbolic - sage: x = an_binop_expr(a, b, operator.mul); x + sage: x = an_binop_expr(a, b, operator.mul); x # optional - sage.symbolic - sage: x.exactify() - 2*a^7 - a^6 - 24*a^5 + 12*a^4 + 46*a^3 - 22*a^2 - 22*a + 9 where a^8 - 12*a^6 + 23*a^4 - 12*a^2 + 1 = 0 and a in -0.3199179336182997? + sage: x.exactify() # optional - sage.symbolic + 2*a^7 - a^6 - 24*a^5 + 12*a^4 + 46*a^3 - 22*a^2 - 22*a + 9 + where a^8 - 12*a^6 + 23*a^4 - 12*a^2 + 1 = 0 and a in -0.3199179336182997? """ return ANBinaryExpr(a, b, op) @@ -8738,7 +8750,7 @@ def get_AA_golden_ratio(): EXAMPLES:: - sage: AA(golden_ratio) # indirect doctest + sage: AA(golden_ratio) # indirect doctest # optional - sage.symbolic 1.618033988749895? """ global AA_golden_ratio diff --git a/src/sage/rings/qqbar_decorators.py b/src/sage/rings/qqbar_decorators.py index 0f7a19bed50..27448c2def6 100644 --- a/src/sage/rings/qqbar_decorators.py +++ b/src/sage/rings/qqbar_decorators.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.number_field """ QQbar decorators diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index 33df6cf2e37..b683889b79a 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -38,8 +38,8 @@ ....: def reduce(self,x): ....: R = self.ring() ....: return add([c*R(m) for m,c in x if len(m) = FreeAlgebra(QQ, 3) - sage: I3 = PowerIdeal(F,3); I3 + sage: F. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: I3 = PowerIdeal(F,3); I3 # optional - sage.combinat sage.modules Twosided Ideal (x^3, x^2*y, x^2*z, x*y*x, x*y^2, x*y*z, x*z*x, x*z*y, x*z^2, y*x^2, y*x*y, y*x*z, y^2*x, y^3, y^2*z, y*z*x, y*z*y, y*z^2, z*x^2, z*x*y, z*x*z, z*y*x, z*y^2, z*y*z, z^2*x, z^2*y, z^3) of @@ -49,33 +49,33 @@ finite dimensional quotients defined by multiplication matrices. We are bypassing it, so that we obtain the default quotient:: - sage: Q3. = F.quotient(I3) - sage: Q3 + sage: Q3. = F.quotient(I3) # optional - sage.combinat sage.modules + sage: Q3 # optional - sage.combinat sage.modules Quotient of Free Algebra on 3 generators (x, y, z) over Rational Field by the ideal (x^3, x^2*y, x^2*z, x*y*x, x*y^2, x*y*z, x*z*x, x*z*y, x*z^2, y*x^2, y*x*y, y*x*z, y^2*x, y^3, y^2*z, y*z*x, y*z*y, y*z^2, z*x^2, z*x*y, z*x*z, z*y*x, z*y^2, z*y*z, z^2*x, z^2*y, z^3) - sage: (a+b+2)^4 + sage: (a+b+2)^4 # optional - sage.combinat sage.modules 16 + 32*a + 32*b + 24*a^2 + 24*a*b + 24*b*a + 24*b^2 - sage: Q3.is_commutative() + sage: Q3.is_commutative() # optional - sage.combinat sage.modules False Even though `Q_3` is not commutative, there is commutativity for products of degree three:: - sage: a*(b*c)-(b*c)*a==F.zero() + sage: a*(b*c)-(b*c)*a==F.zero() # optional - sage.combinat sage.modules True If we quotient out all terms of degree two then of course the resulting quotient ring is commutative:: - sage: I2 = PowerIdeal(F,2); I2 + sage: I2 = PowerIdeal(F,2); I2 # optional - sage.combinat sage.modules Twosided Ideal (x^2, x*y, x*z, y*x, y^2, y*z, z*x, z*y, z^2) of Free Algebra on 3 generators (x, y, z) over Rational Field - sage: Q2. = F.quotient(I2) - sage: Q2.is_commutative() + sage: Q2. = F.quotient(I2) # optional - sage.combinat sage.modules + sage: Q2.is_commutative() # optional - sage.combinat sage.modules True - sage: (a+b+2)^4 + sage: (a+b+2)^4 # optional - sage.combinat sage.modules 16 + 32*a + 32*b Since :trac:`7797`, there is an implementation of free algebras @@ -84,16 +84,17 @@ easily:: sage: from itertools import product - sage: F. = FreeAlgebra(QQ, implementation='letterplace') - sage: Q3 = F.quo(F*[F.prod(m) for m in product(F.gens(), repeat=3)]*F) - sage: Q3 - Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field by the ideal (x*x*x, x*x*y, x*x*z, x*y*x, x*y*y, x*y*z, x*z*x, x*z*y, x*z*z, y*x*x, y*x*y, y*x*z, y*y*x, y*y*y, y*y*z, y*z*x, y*z*y, y*z*z, z*x*x, z*x*y, z*x*z, z*y*x, z*y*y, z*y*z, z*z*x, z*z*y, z*z*z) - sage: Q3.0*Q3.1-Q3.1*Q3.0 + sage: F. = FreeAlgebra(QQ, implementation='letterplace') # optional - sage.combinat sage.modules + sage: Q3 = F.quo(F*[F.prod(m) for m in product(F.gens(), repeat=3)]*F) # optional - sage.combinat sage.modules + sage: Q3 # optional - sage.combinat sage.modules + Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) + over Rational Field by the ideal (x*x*x, x*x*y, x*x*z, x*y*x, x*y*y, x*y*z, x*z*x, x*z*y, x*z*z, y*x*x, y*x*y, y*x*z, y*y*x, y*y*y, y*y*z, y*z*x, y*z*y, y*z*z, z*x*x, z*x*y, z*x*z, z*y*x, z*y*y, z*y*z, z*z*x, z*z*y, z*z*z) + sage: Q3.0*Q3.1 - Q3.1*Q3.0 # optional - sage.combinat sage.modules xbar*ybar - ybar*xbar - sage: Q3.0*(Q3.1*Q3.2)-(Q3.1*Q3.2)*Q3.0 + sage: Q3.0*(Q3.1*Q3.2) - (Q3.1*Q3.2)*Q3.0 # optional - sage.combinat sage.modules 0 - sage: Q2 = F.quo(F*[F.prod(m) for m in product(F.gens(), repeat=2)]*F) - sage: Q2.is_commutative() + sage: Q2 = F.quo(F*[F.prod(m) for m in product(F.gens(), repeat=2)]*F) # optional - sage.combinat sage.modules + sage: Q2.is_commutative() # optional - sage.combinat sage.modules True """ @@ -157,7 +158,7 @@ def QuotientRing(R, I, names=None, **kwds): Some simple quotient rings with the integers:: - sage: R = QuotientRing(ZZ,7*ZZ); R + sage: R = QuotientRing(ZZ, 7*ZZ); R Quotient of Integer Ring by the ideal (7) sage: R.gens() (1,) @@ -177,13 +178,14 @@ def QuotientRing(R, I, names=None, **kwds): ring can be specified as shown below):: sage: P. = QQ[] - sage: R. = QuotientRing(P, P.ideal(x^2 + 1)) - sage: R - Univariate Quotient Polynomial Ring in xx over Rational Field with modulus x^2 + 1 - sage: R.gens(); R.gen() + sage: R. = QuotientRing(P, P.ideal(x^2 + 1)) # optional - sage.libs.pari + sage: R # optional - sage.libs.pari + Univariate Quotient Polynomial Ring in xx over Rational Field + with modulus x^2 + 1 + sage: R.gens(); R.gen() # optional - sage.libs.pari (xx,) xx - sage: for n in range(4): xx^n + sage: for n in range(4): xx^n # optional - sage.libs.pari 1 xx -1 @@ -192,13 +194,13 @@ def QuotientRing(R, I, names=None, **kwds): :: sage: P. = QQ[] - sage: S = QuotientRing(P, P.ideal(x^2 - 2)) - sage: S - Univariate Quotient Polynomial Ring in xbar over Rational Field with - modulus x^2 - 2 - sage: xbar = S.gen(); S.gen() + sage: S = QuotientRing(P, P.ideal(x^2 - 2)) # optional - sage.libs.pari + sage: S # optional - sage.libs.pari + Univariate Quotient Polynomial Ring in xbar over Rational Field + with modulus x^2 - 2 + sage: xbar = S.gen(); S.gen() # optional - sage.libs.pari xbar - sage: for n in range(3): xbar^n + sage: for n in range(3): xbar^n # optional - sage.libs.pari 1 xbar 2 @@ -206,25 +208,26 @@ def QuotientRing(R, I, names=None, **kwds): Sage coerces objects into ideals when possible:: sage: P. = QQ[] - sage: R = QuotientRing(P, x^2 + 1); R - Univariate Quotient Polynomial Ring in xbar over Rational Field with - modulus x^2 + 1 + sage: R = QuotientRing(P, x^2 + 1); R # optional - sage.libs.pari + Univariate Quotient Polynomial Ring in xbar over Rational Field + with modulus x^2 + 1 By Noether's homomorphism theorems, the quotient of a quotient ring of `R` is just the quotient of `R` by the sum of the ideals. In this example, we end up modding out the ideal `(x)` from the ring `\QQ[x,y]`:: - sage: R. = PolynomialRing(QQ,2) - sage: S. = QuotientRing(R,R.ideal(1 + y^2)) - sage: T. = QuotientRing(S,S.ideal(a)) - sage: T - Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x, y^2 + 1) - sage: R.gens(); S.gens(); T.gens() + sage: R. = PolynomialRing(QQ, 2) + sage: S. = QuotientRing(R, R.ideal(1 + y^2)) # optional - sage.libs.pari + sage: T. = QuotientRing(S, S.ideal(a)) # optional - sage.libs.pari + sage: T # optional - sage.libs.pari + Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x, y^2 + 1) + sage: R.gens(); S.gens(); T.gens() # optional - sage.libs.pari (x, y) (a, b) (0, d) - sage: for n in range(4): d^n + sage: for n in range(4): d^n # optional - sage.libs.pari 1 d -1 @@ -243,20 +246,23 @@ def QuotientRing(R, I, names=None, **kwds): Here is an example of the quotient of a free algebra by a twosided homogeneous ideal (see :trac:`7797`):: - sage: F. = FreeAlgebra(QQ, implementation='letterplace') - sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F - sage: Q. = F.quo(I); Q - Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field by the ideal (x*y + y*z, x*x + x*y - y*x - y*y) - sage: a*b + sage: F. = FreeAlgebra(QQ, implementation='letterplace') # optional - sage.combinat sage.modules + sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F # optional - sage.combinat sage.modules + sage: Q. = F.quo(I); Q # optional - sage.combinat sage.modules + Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) + over Rational Field by the ideal (x*y + y*z, x*x + x*y - y*x - y*y) + sage: a*b # optional - sage.combinat sage.modules -b*c - sage: a^3 + sage: a^3 # optional - sage.combinat sage.modules -b*c*a - b*c*b - b*c*c - sage: J = Q*[a^3-b^3]*Q - sage: R. = Q.quo(J); R - Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field by the ideal (-y*y*z - y*z*x - 2*y*z*z, x*y + y*z, x*x + x*y - y*x - y*y) - sage: i^3 + sage: J = Q * [a^3 - b^3] * Q # optional - sage.combinat sage.modules + sage: R. = Q.quo(J); R # optional - sage.combinat sage.modules + Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) + over Rational Field by the ideal + (-y*y*z - y*z*x - 2*y*z*z, x*y + y*z, x*x + x*y - y*x - y*y) + sage: i^3 # optional - sage.combinat sage.modules -j*k*i - j*k*j - j*k*k - sage: j^3 + sage: j^3 # optional - sage.combinat sage.modules -j*k*i - j*k*j - j*k*k Check that :trac:`5978` is fixed by if we quotient by the zero ideal `(0)` @@ -342,12 +348,12 @@ def is_QuotientRing(x): :: - sage: F. = FreeAlgebra(QQ, implementation='letterplace') - sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F - sage: Q = F.quo(I) - sage: is_QuotientRing(Q) + sage: F. = FreeAlgebra(QQ, implementation='letterplace') # optional - sage.combinat sage.modules + sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F # optional - sage.combinat sage.modules + sage: Q = F.quo(I) # optional - sage.combinat sage.modules + sage: is_QuotientRing(Q) # optional - sage.combinat sage.modules True - sage: is_QuotientRing(F) + sage: is_QuotientRing(F) # optional - sage.combinat sage.modules False """ return isinstance(x, QuotientRing_nc) @@ -370,24 +376,26 @@ class QuotientRing_nc(ring.Ring, sage.structure.parent_gens.ParentWithGens): Here is a quotient of a free algebra by a twosided homogeneous ideal:: - sage: F. = FreeAlgebra(QQ, implementation='letterplace') - sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F - sage: Q. = F.quo(I); Q - Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field by the ideal (x*y + y*z, x*x + x*y - y*x - y*y) - sage: a*b + sage: F. = FreeAlgebra(QQ, implementation='letterplace') # optional - sage.combinat sage.modules + sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2]*F # optional - sage.combinat sage.modules + sage: Q. = F.quo(I); Q # optional - sage.combinat sage.modules + Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field + by the ideal (x*y + y*z, x*x + x*y - y*x - y*y) + sage: a*b # optional - sage.combinat sage.modules -b*c - sage: a^3 + sage: a^3 # optional - sage.combinat sage.modules -b*c*a - b*c*b - b*c*c A quotient of a quotient is just the quotient of the original top ring by the sum of two ideals:: - sage: J = Q*[a^3-b^3]*Q - sage: R. = Q.quo(J); R - Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field by the ideal (-y*y*z - y*z*x - 2*y*z*z, x*y + y*z, x*x + x*y - y*x - y*y) - sage: i^3 + sage: J = Q * [a^3 - b^3] * Q # optional - sage.combinat sage.modules + sage: R. = Q.quo(J); R # optional - sage.combinat sage.modules + Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field + by the ideal (-y*y*z - y*z*x - 2*y*z*z, x*y + y*z, x*x + x*y - y*x - y*y) + sage: i^3 # optional - sage.combinat sage.modules -j*k*i - j*k*j - j*k*k - sage: j^3 + sage: j^3 # optional - sage.combinat sage.modules -j*k*i - j*k*j - j*k*k For rings that *do* inherit from :class:`~sage.rings.ring.CommutativeRing`, @@ -399,15 +407,16 @@ class QuotientRing_nc(ring.Ring, sage.structure.parent_gens.ParentWithGens): sage: R. = PolynomialRing(ZZ,'x') sage: I = R.ideal([4 + 3*x + x^2, 1 + x^2]) sage: S = R.quotient_ring(I); S - Quotient of Univariate Polynomial Ring in x over Integer Ring by the ideal (x^2 + 3*x + 4, x^2 + 1) + Quotient of Univariate Polynomial Ring in x over Integer Ring + by the ideal (x^2 + 3*x + 4, x^2 + 1) :: sage: R. = PolynomialRing(QQ) - sage: S. = R.quo(x^2 + y^2) - sage: a^2 + b^2 == 0 + sage: S. = R.quo(x^2 + y^2) # optional - sage.libs.singular + sage: a^2 + b^2 == 0 # optional - sage.libs.singular True - sage: S(0) == a^2 + b^2 + sage: S(0) == a^2 + b^2 # optional - sage.libs.singular True Again, a quotient of a quotient is just the quotient of the original top @@ -415,12 +424,13 @@ class QuotientRing_nc(ring.Ring, sage.structure.parent_gens.ParentWithGens): :: - sage: R. = PolynomialRing(QQ,2) - sage: S. = R.quo(1 + y^2) - sage: T. = S.quo(a) - sage: T - Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x, y^2 + 1) - sage: T.gens() + sage: R. = PolynomialRing(QQ, 2) + sage: S. = R.quo(1 + y^2) # optional - sage.libs.singular + sage: T. = S.quo(a) # optional - sage.libs.singular + sage: T # optional - sage.libs.singular + Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x, y^2 + 1) + sage: T.gens() # optional - sage.libs.singular (0, d) """ Element = quotient_ring_element.QuotientRingElement @@ -438,13 +448,15 @@ def __init__(self, R, I, names, category=None): EXAMPLES:: - sage: F. = FreeAlgebra(QQ, implementation='letterplace') - sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F - sage: Q. = F.quo(I); Q - Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field by the ideal (x*y + y*z, x*x + x*y - y*x - y*y) - sage: a*b + sage: F. = FreeAlgebra(QQ, implementation='letterplace') # optional - sage.combinat sage.modules + sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F # optional - sage.combinat sage.modules + sage: Q. = F.quo(I); Q # optional - sage.combinat sage.modules + Quotient of + Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field + by the ideal (x*y + y*z, x*x + x*y - y*x - y*y) + sage: a*b # optional - sage.combinat sage.modules -b*c - sage: a^3 + sage: a^3 # optional - sage.combinat sage.modules -b*c*a - b*c*b - b*c*c """ @@ -491,19 +503,20 @@ def construction(self): sage: I = R.ideal([4 + 3*x + x^2, 1 + x^2]) sage: R.quotient_ring(I).construction() (QuotientFunctor, Univariate Polynomial Ring in x over Integer Ring) - sage: F. = FreeAlgebra(QQ, implementation='letterplace') - sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F - sage: Q = F.quo(I) - sage: Q.construction() - (QuotientFunctor, Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field) + sage: F. = FreeAlgebra(QQ, implementation='letterplace') # optional - sage.combinat sage.modules + sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F # optional - sage.combinat sage.modules + sage: Q = F.quo(I) # optional - sage.combinat sage.modules + sage: Q.construction() # optional - sage.combinat sage.modules + (QuotientFunctor, + Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field) TESTS:: sage: F, R = Integers(5).construction() sage: F(R) Ring of integers modulo 5 - sage: F, R = GF(5).construction() - sage: F(R) + sage: F, R = GF(5).construction() # optional - sage.rings.finite_rings + sage: F(R) # optional - sage.rings.finite_rings Finite Field of size 5 """ from sage.categories.pushout import QuotientFunctor @@ -575,19 +588,19 @@ def is_commutative(self): The non-commutative case is more interesting:: - sage: F. = FreeAlgebra(QQ, implementation='letterplace') - sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F - sage: Q = F.quo(I) - sage: Q.is_commutative() + sage: F. = FreeAlgebra(QQ, implementation='letterplace') # optional - sage.combinat sage.modules + sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F # optional - sage.combinat sage.modules + sage: Q = F.quo(I) # optional - sage.combinat sage.modules + sage: Q.is_commutative() # optional - sage.combinat sage.modules False - sage: Q.1*Q.2==Q.2*Q.1 + sage: Q.1*Q.2 == Q.2*Q.1 # optional - sage.combinat sage.modules False In the next example, the generators apparently commute:: - sage: J = F*[x*y-y*x,x*z-z*x,y*z-z*y,x^3-y^3]*F - sage: R = F.quo(J) - sage: R.is_commutative() + sage: J = F * [x*y - y*x, x*z - z*x, y*z - z*y, x^3 - y^3] * F # optional - sage.combinat sage.modules + sage: R = F.quo(J) # optional - sage.combinat sage.modules + sage: R.is_commutative() # optional - sage.combinat sage.modules True """ @@ -610,12 +623,11 @@ def is_commutative(self): @cached_method def cover(self): r""" - The covering ring homomorphism `R \to R/I`, equipped with a - section. + The covering ring homomorphism `R \to R/I`, equipped with a section. EXAMPLES:: - sage: R = ZZ.quo(3*ZZ) + sage: R = ZZ.quo(3 * ZZ) sage: pi = R.cover() sage: pi Ring morphism: @@ -629,19 +641,20 @@ def cover(self): :: sage: R. = PolynomialRing(QQ) - sage: Q = R.quo( (x^2,y^2) ) - sage: pi = Q.cover() - sage: pi(x^3+y) + sage: Q = R.quo((x^2, y^2)) + sage: pi = Q.cover() # optional - sage.libs.singular + sage: pi(x^3 + y) # optional - sage.libs.singular ybar - sage: l = pi.lift(x+y^3) - sage: l + sage: l = pi.lift(x + y^3) # optional - sage.libs.singular + sage: l # optional - sage.libs.singular x - sage: l = pi.lift(); l + sage: l = pi.lift(); l # optional - sage.libs.singular Set-theoretic ring morphism: - From: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2, y^2) + From: Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x^2, y^2) To: Multivariate Polynomial Ring in x, y over Rational Field Defn: Choice of lifting map - sage: l(x+y^3) + sage: l(x + y^3) # optional - sage.libs.singular x """ try: @@ -663,40 +676,43 @@ def lifting_map(self): sage: R. = PolynomialRing(QQ, 2) sage: S = R.quotient(x^2 + y^2) - sage: pi = S.cover(); pi + sage: pi = S.cover(); pi # optional - sage.libs.singular Ring morphism: From: Multivariate Polynomial Ring in x, y over Rational Field - To: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) + To: Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x^2 + y^2) Defn: Natural quotient map - sage: L = S.lifting_map(); L + sage: L = S.lifting_map(); L # optional - sage.libs.singular Set-theoretic ring morphism: - From: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) + From: Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x^2 + y^2) To: Multivariate Polynomial Ring in x, y over Rational Field Defn: Choice of lifting map - sage: L(S.0) + sage: L(S.0) # optional - sage.libs.singular x - sage: L(S.1) + sage: L(S.1) # optional - sage.libs.singular y Note that some reduction may be applied so that the lift of a reduction need not equal the original element:: - sage: z = pi(x^3 + 2*y^2); z + sage: z = pi(x^3 + 2*y^2); z # optional - sage.libs.singular -xbar*ybar^2 + 2*ybar^2 - sage: L(z) + sage: L(z) # optional - sage.libs.singular -x*y^2 + 2*y^2 - sage: L(z) == x^3 + 2*y^2 + sage: L(z) == x^3 + 2*y^2 # optional - sage.libs.singular False Test that there also is a lift for rings that are no instances of :class:`~sage.rings.ring.Ring` (see :trac:`11068`):: - sage: MS = MatrixSpace(GF(5),2,2) - sage: I = MS*[MS.0*MS.1,MS.2+MS.3]*MS - sage: Q = MS.quo(I) - sage: Q.lift() + sage: MS = MatrixSpace(GF(5), 2, 2) # optional - sage.modules sage.rings.finite_rings + sage: I = MS * [MS.0*MS.1, MS.2 + MS.3] * MS # optional - sage.modules sage.rings.finite_rings + sage: Q = MS.quo(I) # optional - sage.modules sage.rings.finite_rings + sage: Q.lift() # optional - sage.modules sage.rings.finite_rings Set-theoretic ring morphism: - From: Quotient of Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 5 by the ideal + From: Quotient of Full MatrixSpace of 2 by 2 dense matrices + over Finite Field of size 5 by the ideal ( [0 1] [0 0], @@ -719,7 +735,7 @@ def lifting_map(self): return m # The following is to make the category framework happy. - def lift(self,x=None): + def lift(self, x=None): """ Return the lifting map to the cover, or the image of an element under the lifting map. @@ -735,12 +751,13 @@ def lift(self,x=None): sage: R. = PolynomialRing(QQ, 2) sage: S = R.quotient(x^2 + y^2) - sage: S.lift() + sage: S.lift() # optional - sage.libs.singular Set-theoretic ring morphism: - From: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) + From: Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x^2 + y^2) To: Multivariate Polynomial Ring in x, y over Rational Field Defn: Choice of lifting map - sage: S.lift(S.0) == x + sage: S.lift(S.0) == x # optional - sage.libs.singular True """ @@ -764,7 +781,7 @@ def retract(self,x): sage: R. = PolynomialRing(QQ, 2) sage: S = R.quotient(x^2 + y^2) - sage: S.retract((x+y)^2) + sage: S.retract((x+y)^2) # optional - sage.libs.singular 2*xbar*ybar """ @@ -804,12 +821,12 @@ def defining_ideal(self): homomorphism theorems, this is actually a quotient by a sum of two ideals:: - sage: R. = PolynomialRing(QQ,2) - sage: S. = QuotientRing(R,R.ideal(1 + y^2)) - sage: T. = QuotientRing(S,S.ideal(a)) - sage: S.defining_ideal() + sage: R. = PolynomialRing(QQ, 2) + sage: S. = QuotientRing(R, R.ideal(1 + y^2)) # optional - sage.libs.singular + sage: T. = QuotientRing(S, S.ideal(a)) # optional - sage.libs.singular + sage: S.defining_ideal() # optional - sage.libs.singular Ideal (y^2 + 1) of Multivariate Polynomial Ring in x, y over Rational Field - sage: T.defining_ideal() + sage: T.defining_ideal() # optional - sage.libs.singular Ideal (x, y^2 + 1) of Multivariate Polynomial Ring in x, y over Rational Field """ return self.__I @@ -822,15 +839,15 @@ def is_field(self, proof = True): TESTS:: - sage: Q = QuotientRing(ZZ,7*ZZ) - sage: Q.is_field() + sage: Q = QuotientRing(ZZ, 7*ZZ) + sage: Q.is_field() # optional - sage.libs.pari True Requires the ``is_maximal`` method of the defining ideal to be implemented:: sage: R. = ZZ[] - sage: R.quotient_ring(R.ideal([2, 4 +x])).is_field() + sage: R.quotient_ring(R.ideal([2, 4 + x])).is_field() # optional - sage.libs.pari Traceback (most recent call last): ... NotImplementedError @@ -857,19 +874,19 @@ def is_integral_domain(self, proof=True): EXAMPLES:: sage: R. = QQ[] - sage: R.quo(x^2 - y).is_integral_domain() + sage: R.quo(x^2 - y).is_integral_domain() # optional - sage.singular True - sage: R.quo(x^2 - y^2).is_integral_domain() + sage: R.quo(x^2 - y^2).is_integral_domain() # optional - sage.singular False - sage: R.quo(x^2 - y^2).is_integral_domain(proof=False) + sage: R.quo(x^2 - y^2).is_integral_domain(proof=False) # optional - sage.singular False - sage: R. = ZZ[] - sage: Q = R.quotient_ring([a, b]) - sage: Q.is_integral_domain() + sage: R. = ZZ[] # optional - sage.singular + sage: Q = R.quotient_ring([a, b]) # optional - sage.singular + sage: Q.is_integral_domain() # optional - sage.singular Traceback (most recent call last): ... NotImplementedError - sage: Q.is_integral_domain(proof=False) + sage: Q.is_integral_domain(proof=False) # optional - sage.singular False """ if proof: @@ -886,13 +903,13 @@ def is_noetherian(self): EXAMPLES:: - sage: R = QuotientRing(ZZ, 102*ZZ) + sage: R = QuotientRing(ZZ, 102 * ZZ) sage: R.is_noetherian() True sage: P. = QQ[] - sage: R = QuotientRing(P, x^2+1) - sage: R.is_noetherian() + sage: R = QuotientRing(P, x^2 + 1) # optional - sage.libs.pari + sage: R.is_noetherian() # optional - sage.libs.pari True If the cover ring of ``self`` is not Noetherian, we currently @@ -903,8 +920,8 @@ def is_noetherian(self): sage: R.is_noetherian() False sage: I = R.ideal([x[1]^2, x[2]]) - sage: S = R.quotient(I) - sage: S.is_noetherian() + sage: S = R.quotient(I) # optional - sage.libs.pari + sage: S.is_noetherian() # optional - sage.libs.pari Traceback (most recent call last): ... NotImplementedError @@ -923,15 +940,15 @@ def cover_ring(self): EXAMPLES:: - sage: Q = QuotientRing(ZZ,7*ZZ) + sage: Q = QuotientRing(ZZ, 7 * ZZ) sage: Q.cover_ring() Integer Ring :: sage: P. = QQ[] - sage: Q = QuotientRing(P, x^2 + 1) - sage: Q.cover_ring() + sage: Q = QuotientRing(P, x^2 + 1) # optional - sage.libs.pari + sage: Q.cover_ring() # optional - sage.libs.pari Univariate Polynomial Ring in x over Rational Field """ return self.__R @@ -946,11 +963,13 @@ def ideal(self, *gens, **kwds): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S = R.quotient_ring(x^2+y^2) - sage: S.ideal() - Ideal (0) of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) - sage: S.ideal(x+y+1) - Ideal (xbar + ybar + 1) of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) + sage: S = R.quotient_ring(x^2 + y^2) + sage: S.ideal() # optional - sage.libs.pari + Ideal (0) of Quotient of Multivariate Polynomial Ring in x, y + over Rational Field by the ideal (x^2 + y^2) + sage: S.ideal(x + y + 1) # optional - sage.libs.pari + Ideal (xbar + ybar + 1) of Quotient of Multivariate Polynomial Ring in x, y + over Rational Field by the ideal (x^2 + y^2) TESTS: @@ -986,10 +1005,10 @@ def _element_constructor_(self, x, coerce=True): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S = R.quotient_ring(x^2+y^2) - sage: S(x) # indirect doctest + sage: S = R.quotient_ring(x^2 + y^2) + sage: S(x) # indirect doctest # optional - sage.libs.singular xbar - sage: S(x^2 + y^2) + sage: S(x^2 + y^2) # optional - sage.libs.singular 0 The rings that coerce into the quotient ring canonically, are: @@ -1002,21 +1021,22 @@ def _element_constructor_(self, x, coerce=True): :: sage: R. = PolynomialRing(QQ, 2) - sage: S. = R.quotient(x^2 + y^2) - sage: S.coerce(0) + sage: S. = R.quotient(x^2 + y^2) # optional - sage.libs.singular + sage: S.coerce(0) # optional - sage.libs.singular 0 - sage: S.coerce(2/3) + sage: S.coerce(2/3) # optional - sage.libs.singular 2/3 - sage: S.coerce(a^2 - b) + sage: S.coerce(a^2 - b) # optional - sage.libs.singular -b^2 - b - sage: S.coerce(GF(7)(3)) + sage: S.coerce(GF(7)(3)) # optional - sage.rings.finite_rings sage.libs.singular Traceback (most recent call last): ... - TypeError: no canonical coercion from Finite Field of size 7 to Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) + TypeError: no canonical coercion from Finite Field of size 7 + to Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) TESTS:: - sage: S(x, coerce=False) + sage: S(x, coerce=False) # optional - sage.libs.singular a """ if isinstance(x, quotient_ring_element.QuotientRingElement): @@ -1039,15 +1059,15 @@ def _coerce_map_from_(self, R): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S = R.quotient_ring(x^2+y^2) + sage: S = R.quotient_ring(x^2 + y^2) sage: S.has_coerce_map_from(R) # indirect doctest True sage: S.has_coerce_map_from(QQ) True - sage: T = S.quotient_ring(x^3 - y) - sage: S.has_coerce_map_from(T) + sage: T = S.quotient_ring(x^3 - y) # optional - sage.libs.singular + sage: S.has_coerce_map_from(T) # optional - sage.libs.singular False - sage: T.has_coerce_map_from(R) + sage: T.has_coerce_map_from(R) # optional - sage.libs.singular True TESTS: @@ -1055,33 +1075,33 @@ def _coerce_map_from_(self, R): We check that :trac:`13682` is fixed:: sage: R. = PolynomialRing(QQ) - sage: I = R.ideal(x^2+y^2) - sage: J = R.ideal(x^2+y^2, x^3 - y) - sage: I < J + sage: I = R.ideal(x^2 + y^2) + sage: J = R.ideal(x^2 + y^2, x^3 - y) + sage: I < J # optional - sage.libs.singular True - sage: S = R.quotient(I) - sage: T = R.quotient(J) - sage: T.has_coerce_map_from(S) + sage: S = R.quotient(I) # optional - sage.libs.singular + sage: T = R.quotient(J) # optional - sage.libs.singular + sage: T.has_coerce_map_from(S) # optional - sage.libs.singular True - sage: S.quotient_ring(x^4-x*y+1).has_coerce_map_from(S) + sage: S.quotient_ring(x^4 - x*y + 1).has_coerce_map_from(S) # optional - sage.libs.singular True - sage: S.has_coerce_map_from(T) + sage: S.has_coerce_map_from(T) # optional - sage.libs.singular False We also allow coercions with the cover rings:: sage: Rp. = PolynomialRing(ZZ) - sage: Ip = Rp.ideal(x^2+y^2) - sage: Jp = Rp.ideal(x^2+y^2, x^3 - y) - sage: Sp = Rp.quotient(Ip) - sage: Tp = Rp.quotient(Jp) - sage: R.has_coerce_map_from(Rp) + sage: Ip = Rp.ideal(x^2 + y^2) + sage: Jp = Rp.ideal(x^2 + y^2, x^3 - y) + sage: Sp = Rp.quotient(Ip) # optional - sage.libs.singular + sage: Tp = Rp.quotient(Jp) # optional - sage.libs.singular + sage: R.has_coerce_map_from(Rp) # optional - sage.libs.singular True - sage: Sp.has_coerce_map_from(Sp) + sage: Sp.has_coerce_map_from(Sp) # optional - sage.libs.singular True - sage: T.has_coerce_map_from(Sp) + sage: T.has_coerce_map_from(Sp) # optional - sage.libs.singular True - sage: Sp.has_coerce_map_from(T) + sage: Sp.has_coerce_map_from(T) # optional - sage.libs.singular False """ C = self.cover_ring() @@ -1113,9 +1133,9 @@ def __richcmp__(self, other, op): equal, but since the generators are different, the corresponding quotient rings are not equal:: - sage: R.ideal(x^2+y^2) == R.ideal(-x^2 - y^2) + sage: R.ideal(x^2 + y^2) == R.ideal(-x^2 - y^2) # optional - sage.libs.singular True - sage: R.quotient_ring(x^2 + y^2) == R.quotient_ring(-x^2 - y^2) + sage: R.quotient_ring(x^2 + y^2) == R.quotient_ring(-x^2 - y^2) # optional - sage.libs.singular False """ if not isinstance(other, QuotientRing_nc): @@ -1137,7 +1157,7 @@ def ngens(self): EXAMPLES:: - sage: R = QuotientRing(ZZ,7*ZZ) + sage: R = QuotientRing(ZZ, 7*ZZ) sage: R.gens(); R.ngens() (1,) 1 @@ -1145,15 +1165,16 @@ def ngens(self): :: sage: R. = PolynomialRing(QQ,2) - sage: S. = QuotientRing(R,R.ideal(1 + y^2)) - sage: T. = QuotientRing(S,S.ideal(a)) - sage: T - Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x, y^2 + 1) - sage: R.gens(); S.gens(); T.gens() + sage: S. = QuotientRing(R, R.ideal(1 + y^2)) # optional - sage.libs.singular + sage: T. = QuotientRing(S, S.ideal(a)) # optional - sage.libs.singular + sage: T # optional - sage.libs.singular + Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x, y^2 + 1) + sage: R.gens(); S.gens(); T.gens() # optional - sage.libs.singular (x, y) (a, b) (0, d) - sage: R.ngens(); S.ngens(); T.ngens() + sage: R.ngens(); S.ngens(); T.ngens() # optional - sage.libs.singular 2 2 2 @@ -1166,24 +1187,25 @@ def gen(self, i=0): EXAMPLES:: - sage: R = QuotientRing(ZZ,7*ZZ) + sage: R = QuotientRing(ZZ, 7*ZZ) sage: R.gen(0) 1 :: sage: R. = PolynomialRing(QQ,2) - sage: S. = QuotientRing(R,R.ideal(1 + y^2)) - sage: T. = QuotientRing(S,S.ideal(a)) - sage: T - Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x, y^2 + 1) - sage: R.gen(0); R.gen(1) + sage: S. = QuotientRing(R, R.ideal(1 + y^2)) # optional - sage.libs.singular + sage: T. = QuotientRing(S, S.ideal(a)) # optional - sage.libs.singular + sage: T # optional - sage.libs.singular + Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x, y^2 + 1) + sage: R.gen(0); R.gen(1) # optional - sage.libs.singular x y - sage: S.gen(0); S.gen(1) + sage: S.gen(0); S.gen(1) # optional - sage.libs.singular a b - sage: T.gen(0); T.gen(1) + sage: T.gen(0); T.gen(1) # optional - sage.libs.singular 0 d """ @@ -1209,8 +1231,8 @@ def _singular_(self, singular=None): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S = R.quotient_ring(x^2+y^2) - sage: S._singular_() + sage: S = R.quotient_ring(x^2 + y^2) + sage: S._singular_() # optional - sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 2 @@ -1243,11 +1265,11 @@ def _singular_init_(self, singular=None): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S = R.quotient_ring(x^2+y^2) - sage: T = S._singular_init_() - sage: parent(S) + sage: S = R.quotient_ring(x^2 + y^2) + sage: T = S._singular_init_() # optional - sage.libs.singular + sage: parent(S) # optional - sage.libs.singular - sage: parent(T) + sage: parent(T) # optional - sage.libs.singular Singular """ if singular is None: @@ -1267,9 +1289,9 @@ def _magma_init_(self, magma): EXAMPLES:: - sage: P. = PolynomialRing(GF(2)) - sage: Q = P.quotient(sage.rings.ideal.FieldIdeal(P)) - sage: magma(Q) # optional - magma # indirect doctest + sage: P. = PolynomialRing(GF(2)) # optional - sage.rings.finite_rings + sage: Q = P.quotient(sage.rings.ideal.FieldIdeal(P)) # optional - sage.rings.finite_rings + sage: magma(Q) # optional - magma # indirect doctest # optional - sage.rings.finite_rings Affine Algebra of rank 2 over GF(2) Graded Reverse Lexicographical Order Variables: x, y @@ -1307,7 +1329,8 @@ class QuotientRing_generic(QuotientRing_nc, ring.CommutativeRing): sage: R. = PolynomialRing(ZZ) sage: I = R.ideal([4 + 3*x + x^2, 1 + x^2]) sage: S = R.quotient_ring(I); S - Quotient of Univariate Polynomial Ring in x over Integer Ring by the ideal (x^2 + 3*x + 4, x^2 + 1) + Quotient of Univariate Polynomial Ring in x over Integer Ring + by the ideal (x^2 + 3*x + 4, x^2 + 1) """ def __init__(self, R, I, names, category=None): @@ -1361,11 +1384,12 @@ def _macaulay2_init_(self, macaulay2=None): 2 2 2 (x*y - z , y - w ) - sage: R. = PolynomialRing(GF(101), 2) - sage: I = R.ideal([x^2 + x, y^2 + y]) - sage: Q = R.quotient_ring(I); Q - Quotient of Multivariate Polynomial Ring in x, y over Finite Field of size 101 by the ideal (x^2 + x, y^2 + y) - sage: Q._macaulay2_init_() # optional - macaulay2 + sage: R. = PolynomialRing(GF(101), 2) # optional - sage.rings.finite_rings + sage: I = R.ideal([x^2 + x, y^2 + y]) # optional - sage.rings.finite_rings + sage: Q = R.quotient_ring(I); Q # optional - sage.rings.finite_rings + Quotient of Multivariate Polynomial Ring in x, y over + Finite Field of size 101 by the ideal (x^2 + x, y^2 + y) + sage: Q._macaulay2_init_() # optional - macaulay2 # optional - sage.rings.finite_rings ZZ ---[x...y] 101 @@ -1439,12 +1463,12 @@ def _contains_(self, other): :: sage: R. = QQ[] - sage: S. = R.quotient(T^3-1) - sage: 1 in S.ideal(t^2-1) + sage: S. = R.quotient(T^3 - 1) # optional - sage.libs.pari + sage: 1 in S.ideal(t^2 - 1) # optional - sage.libs.pari False - sage: 7 in S.ideal(t^2+1) + sage: 7 in S.ideal(t^2 + 1) # optional - sage.libs.pari True - sage: 5-5*t in S.ideal(t^2-1) + sage: 5-5*t in S.ideal(t^2 - 1) # optional - sage.libs.pari True """ R = self.ring() diff --git a/src/sage/rings/quotient_ring_element.py b/src/sage/rings/quotient_ring_element.py index 05cc52e7681..27ceb3ceaf9 100644 --- a/src/sage/rings/quotient_ring_element.py +++ b/src/sage/rings/quotient_ring_element.py @@ -45,7 +45,8 @@ class QuotientRingElement(RingElement): sage: R. = PolynomialRing(ZZ) sage: S. = R.quo((4 + 3*x + x^2, 1 + x^2)); S - Quotient of Univariate Polynomial Ring in x over Integer Ring by the ideal (x^2 + 3*x + 4, x^2 + 1) + Quotient of Univariate Polynomial Ring in x over Integer Ring + by the ideal (x^2 + 3*x + 4, x^2 + 1) sage: v = S.gens(); v (xbar,) @@ -58,24 +59,25 @@ class QuotientRingElement(RingElement): sage: R. = PolynomialRing(QQ, 2) sage: S = R.quo(x^2 + y^2); S - Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) - sage: S.gens() + Quotient of Multivariate Polynomial Ring in x, y over Rational Field + by the ideal (x^2 + y^2) + sage: S.gens() # optional - sage.libs.singular (xbar, ybar) We name each of the generators. :: - sage: S. = R.quotient(x^2 + y^2) - sage: a + sage: S. = R.quotient(x^2 + y^2) # optional - sage.libs.singular + sage: a # optional - sage.libs.singular a - sage: b + sage: b # optional - sage.libs.singular b - sage: a^2 + b^2 == 0 + sage: a^2 + b^2 == 0 # optional - sage.libs.singular True - sage: b.lift() + sage: b.lift() # optional - sage.libs.singular y - sage: (a^3 + b^2).lift() + sage: (a^3 + b^2).lift() # optional - sage.libs.singular -x*y^2 + y^2 """ def __init__(self, parent, rep, reduce=True): @@ -87,7 +89,8 @@ def __init__(self, parent, rep, reduce=True): sage: R. = PolynomialRing(ZZ) sage: S. = R.quo((4 + 3*x + x^2, 1 + x^2)); S - Quotient of Univariate Polynomial Ring in x over Integer Ring by the ideal (x^2 + 3*x + 4, x^2 + 1) + Quotient of Univariate Polynomial Ring in x over Integer Ring + by the ideal (x^2 + 3*x + 4, x^2 + 1) sage: v = S.gens(); v (xbar,) """ @@ -106,10 +109,10 @@ def _reduce_(self): TESTS:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: a._reduce_() - sage: a._QuotientRingElement__rep + sage: a._reduce_() # optional - sage.libs.singular + sage: a._QuotientRingElement__rep # optional - sage.libs.singular x """ I = self.parent().defining_ideal() @@ -122,55 +125,55 @@ def lift(self): EXAMPLES:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: a.lift() + sage: a.lift() # optional - sage.libs.singular x - sage: (3/5*(a + a^2 + b^2)).lift() + sage: (3/5*(a + a^2 + b^2)).lift() # optional - sage.libs.singular 3/5*x """ return self.__rep def __bool__(self): """ - Return True if quotient ring element is non-zero in the + Return ``True`` if quotient ring element is non-zero in the quotient ring `R/I`, by determining whether the element is in `I`. EXAMPLES:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: bool(a) # indirect doctest + sage: bool(a) # indirect doctest # optional - sage.libs.singular True - sage: bool(S(0)) + sage: bool(S(0)) # optional - sage.libs.singular False TESTS:: - sage: bool(a - a) + sage: bool(a - a) # optional - sage.libs.singular False """ return self.__rep not in self.parent().defining_ideal() def is_unit(self): """ - Return True if self is a unit in the quotient ring. + Return ``True`` if self is a unit in the quotient ring. EXAMPLES:: - sage: R. = QQ[]; S. = R.quo(1 - x*y); type(a) + sage: R. = QQ[]; S. = R.quo(1 - x*y); type(a) # optional - sage.libs.singular - sage: a*b + sage: a*b # optional - sage.libs.singular 1 - sage: S(2).is_unit() + sage: S(2).is_unit() # optional - sage.libs.singular True Check that :trac:`29469` is fixed:: - sage: a.is_unit() + sage: a.is_unit() # optional - sage.libs.singular True - sage: (a+b).is_unit() + sage: (a+b).is_unit() # optional - sage.libs.singular False """ if self.__rep.is_unit(): @@ -191,18 +194,18 @@ def _repr_(self): TESTS:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: a-2*a*b # indirect doctest + sage: a-2*a*b # indirect doctest # optional - sage.libs.singular -2*a*b + a In :trac:`11068`, the case of quotient rings without assigned names has been covered as well:: - sage: S = SteenrodAlgebra(2) - sage: I = S*[S.0+S.1]*S - sage: Q = S.quo(I) - sage: Q.0 + sage: S = SteenrodAlgebra(2) # optional - sage.libs.singular + sage: I = S * [S.0 + S.1] * S # optional - sage.libs.singular + sage: Q = S.quo(I) # optional - sage.libs.singular + sage: Q.0 # optional - sage.libs.singular Sq(1) """ @@ -232,8 +235,8 @@ def _latex_(self): sage: a = R.gen(0) sage: I = R.ideal(a**2 + a + 1) sage: S = R.quotient(I, names=R.variable_names()) - sage: a = S.gen(0) - sage: latex(a) + sage: a = S.gen(0) # optional - sage.libs.singular + sage: latex(a) # optional - sage.libs.singular a """ from sage.structure.parent_gens import localvars @@ -257,20 +260,20 @@ def __pari__(self): EXAMPLES:: sage: R. = QQ[] - sage: I = R.ideal(x^3,y^3) - sage: S. = R.quo(I) - sage: pari(xb) + sage: I = R.ideal(x^3, y^3) + sage: S. = R.quo(I) # optional - sage.libs.singular + sage: pari(xb) # optional - sage.libs.pari sage.libs.singular Traceback (most recent call last): ... ValueError: Pari does not support quotients by non-principal ideals Note that the quotient does work in the case that the ideal is principal:: - sage: I = R.ideal(x^3+y^3) - sage: S. = R.quo(I) - sage: pari(xb)^4 + sage: I = R.ideal(x^3 + y^3) + sage: S. = R.quo(I) # optional - sage.libs.singular + sage: pari(xb)^4 # optional - sage.libs.pari sage.libs.singular Mod(-y^3*x, x^3 + y^3) - sage: pari(yb)^4 + sage: pari(yb)^4 # optional - sage.libs.pari sage.libs.singular Mod(y^4, x^3 + y^3) """ gens = self.parent().defining_ideal().gens() @@ -286,14 +289,14 @@ def _add_(self, right): EXAMPLES:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: a + b + sage: a + b # optional - sage.libs.singular a + b TESTS:: - sage: a._add_(b) + sage: a._add_(b) # optional - sage.libs.singular a + b """ return self.__class__(self.parent(), self.__rep + right.__rep) @@ -306,14 +309,14 @@ def _sub_(self, right): EXAMPLES:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: a - b + sage: a - b # optional - sage.libs.singular a - b TESTS:: - sage: a._sub_(b) + sage: a._sub_(b) # optional - sage.libs.singular a - b """ return self.__class__(self.parent(), self.__rep - right.__rep) @@ -326,16 +329,16 @@ def _mul_(self, right): EXAMPLES:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: a * b + sage: a * b # optional - sage.libs.singular a*b TESTS:: - sage: a._mul_(b) + sage: a._mul_(b) # optional - sage.libs.singular a*b - sage: a._mul_(a) + sage: a._mul_(a) # optional - sage.libs.singular -b^2 """ return self.__class__(self.parent(), self.__rep * right.__rep) @@ -350,30 +353,30 @@ def _div_(self, right): sage: R. = QQ[] sage: I = R.ideal([x^2 + 1, y^3 - 2]) - sage: S. = R.quotient(I) - sage: 1/(1+i) + sage: S. = R.quotient(I) # optional - sage.libs.singular + sage: 1/(1+i) # optional - sage.libs.singular -1/2*i + 1/2 Confirm via symbolic computation:: - sage: 1/(1+sqrt(-1)) + sage: 1/(1+sqrt(-1)) # optional - sage.symbolic -1/2*I + 1/2 Another more complicated quotient:: - sage: b = 1/(i+cuberoot); b + sage: b = 1/(i+cuberoot); b # optional - sage.libs.singular 1/5*i*cuberoot^2 - 2/5*i*cuberoot + 2/5*cuberoot^2 - 1/5*i + 1/5*cuberoot - 2/5 - sage: b*(i+cuberoot) + sage: b*(i+cuberoot) # optional - sage.libs.singular 1 Another really easy example:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: a / S(2) + sage: a / S(2) # optional - sage.libs.singular 1/2*a - sage: (a*b)._div_(b) + sage: (a*b)._div_(b) # optional - sage.libs.singular a An example in which we try to divide in a ring that is not a @@ -381,18 +384,18 @@ def _div_(self, right): sage: R. = QQ[] sage: I = R.ideal([x^2 - 1, y^3 - 2]) - sage: S. = R.quotient(I) - sage: 1/cuberoot + sage: S. = R.quotient(I) # optional - sage.libs.singular + sage: 1/cuberoot # optional - sage.libs.singular 1/2*cuberoot^2 - sage: 1/a + sage: 1/a # optional - sage.libs.singular a Check that :trac:`13670` is fixed (i.e. that the error message actually describes what happens when the result of division is not defined):: sage: R. = QQ[] - sage: S = R.quotient_ring( R.ideal(x2**2 + x1 - 2, x1**2 - 1) ) - sage: 1 / S(x1 + x2) + sage: S = R.quotient_ring( R.ideal(x2**2 + x1 - 2, x1**2 - 1) ) # optional - sage.libs.singular + sage: 1 / S(x1 + x2) # optional - sage.libs.singular Traceback (most recent call last): ... ArithmeticError: Division failed. The numerator is not a multiple of the denominator. @@ -404,7 +407,7 @@ def _div_(self, right): sage: R. = QQ[] sage: S. = R[] - sage: Z. = S.quotient([y^2 - 2, z^2 - 3]) + sage: Z. = S.quotient([y^2 - 2, z^2 - 3]) # optional - sage.libs.singular Traceback (most recent call last): ... TypeError: Can only reduce polynomials over fields. @@ -472,15 +475,15 @@ def _im_gens_(self, codomain, im_gens, base_map=None): quotient ring work correctly (see :trac:`16135`):: sage: R. = QQ[] - sage: K = R.quotient(x^2 - y^3).fraction_field() + sage: K = R.quotient(x^2 - y^3).fraction_field() # optional - sage.libs.singular sage: L. = FunctionField(QQ) - sage: f = K.hom((t^3, t^2)) - sage: list(map(f, K.gens())) + sage: f = K.hom((t^3, t^2)) # optional - sage.libs.singular + sage: list(map(f, K.gens())) # optional - sage.libs.singular [t^3, t^2] - sage: xbar, ybar = K.gens() - sage: f(1/ybar) + sage: xbar, ybar = K.gens() # optional - sage.libs.singular + sage: f(1/ybar) # optional - sage.libs.singular 1/t^2 - sage: f(xbar/ybar) + sage: f(xbar/ybar) # optional - sage.libs.singular t """ return self.lift()._im_gens_(codomain, im_gens, base_map=base_map) @@ -493,13 +496,13 @@ def __int__(self): EXAMPLES:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: int(S(-3)) # indirect doctest + sage: int(S(-3)) # indirect doctest # optional - sage.libs.singular -3 - sage: type(int(S(-3))) + sage: type(int(S(-3))) # optional - sage.libs.singular <... 'int'> - sage: int(a) + sage: int(a) # optional - sage.libs.singular Traceback (most recent call last): ... TypeError: unable to convert non-constant polynomial x to @@ -510,14 +513,14 @@ def _integer_(self, Z): """ EXAMPLES:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: ZZ(S(-3)) + sage: ZZ(S(-3)) # optional - sage.libs.singular -3 TESTS:: - sage: type(ZZ(S(-3))) + sage: type(ZZ(S(-3))) # optional - sage.libs.singular """ return Z(self.lift()) @@ -526,14 +529,14 @@ def _rational_(self): """ EXAMPLES:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: QQ(S(-2/3)) + sage: QQ(S(-2/3)) # optional - sage.libs.singular -2/3 TESTS:: - sage: type(S(-2/3)._rational_()) + sage: type(S(-2/3)._rational_()) # optional - sage.libs.singular """ from sage.rings.rational_field import QQ @@ -543,11 +546,11 @@ def __neg__(self): """ EXAMPLES:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: -a # indirect doctest + sage: -a # indirect doctest # optional - sage.libs.singular -a - sage: -(a+b) + sage: -(a+b) # optional - sage.libs.singular -a - b """ return self.__class__(self.parent(), -self.__rep) @@ -556,11 +559,11 @@ def __pos__(self): """ TESTS:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: (a+b).__pos__() + sage: (a+b).__pos__() # optional - sage.libs.singular a + b - sage: c = a+b; c.__pos__() is c + sage: c = a+b; c.__pos__() is c # optional - sage.libs.singular True """ return self @@ -569,19 +572,19 @@ def __invert__(self): """ EXAMPLES:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: ~S(2/3) + sage: ~S(2/3) # optional - sage.libs.singular 3/2 TESTS:: - sage: S(2/3).__invert__() + sage: S(2/3).__invert__() # optional - sage.libs.singular 3/2 Note that a is not invertible as an element of R:: - sage: a.__invert__() + sage: a.__invert__() # optional - sage.libs.singular Traceback (most recent call last): ... ArithmeticError: element is non-invertible @@ -596,11 +599,11 @@ def __float__(self): """ EXAMPLES:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: float(S(2/3)) + sage: float(S(2/3)) # optional - sage.libs.singular 0.6666666666666666 - sage: float(a) + sage: float(a) # optional - sage.libs.singular Traceback (most recent call last): ... TypeError: unable to convert non-constant polynomial x to @@ -611,10 +614,10 @@ def __hash__(self): r""" TESTS:: - sage: R. = QQ[] - sage: S. = R.quo(x^2 + y^2) - sage: c = a*a + b - sage: hash(a) != hash(b) + sage: R. = QQ[] # optional - sage.libs.singular + sage: S. = R.quo(x^2 + y^2) # optional - sage.libs.singular + sage: c = a*a + b # optional - sage.libs.singular + sage: hash(a) != hash(b) # optional - sage.libs.singular True """ return hash(self.__rep) @@ -623,38 +626,38 @@ def _richcmp_(self, other, op): """ EXAMPLES:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: a > b # indirect doctest + sage: a > b # indirect doctest # optional - sage.libs.singular True - sage: b > a + sage: b > a # optional - sage.libs.singular False - sage: a == loads(dumps(a)) + sage: a == loads(dumps(a)) # optional - sage.libs.singular True TESTS:: - sage: a == (a+1-1) + sage: a == (a+1-1) # optional - sage.libs.singular True - sage: a > b + sage: a > b # optional - sage.libs.singular True See :trac:`7797`:: - sage: F. = FreeAlgebra(QQ, implementation='letterplace') - sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F - sage: Q = F.quo(I) - sage: Q.0^4 # indirect doctest + sage: F. = FreeAlgebra(QQ, implementation='letterplace') # optional - sage.combinat + sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F # optional - sage.combinat + sage: Q = F.quo(I) # optional - sage.combinat sage.libs.singular + sage: Q.0^4 # indirect doctest # optional - sage.combinat sage.libs.singular ybar*zbar*zbar*xbar + ybar*zbar*zbar*ybar + ybar*zbar*zbar*zbar The issue from :trac:`8005` was most likely fixed as part of :trac:`9138`:: - sage: F = GF(5) - sage: R.=F[] - sage: I=Ideal(R, [x, y]) - sage: S.=QuotientRing(R,I) - sage: x1^4 + sage: F = GF(5) # optional - sage.rings.finite_rings + sage: R. = F[] # optional - sage.rings.finite_rings + sage: I = Ideal(R, [x, y]) # optional - sage.rings.finite_rings + sage: S. = QuotientRing(R, I) # optional - sage.rings.finite_rings + sage: x1^4 # optional - sage.rings.finite_rings 0 """ # A containment test is not implemented for univariate polynomial @@ -677,18 +680,18 @@ def lt(self): EXAMPLES:: - sage: R.=PolynomialRing(GF(7),3,order='lex') - sage: I = sage.rings.ideal.FieldIdeal(R) - sage: Q = R.quo( I ) - sage: f = Q( z*y + 2*x ) - sage: f.lt() + sage: R. = PolynomialRing(GF(7), 3, order='lex') # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.FieldIdeal(R) # optional - sage.rings.finite_rings + sage: Q = R.quo(I) # optional - sage.rings.finite_rings + sage: f = Q(z*y + 2*x) # optional - sage.rings.finite_rings + sage: f.lt() # optional - sage.rings.finite_rings 2*xbar TESTS:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: (a+3*a*b+b).lt() + sage: (a + 3*a*b + b).lt() # optional - sage.libs.singular 3*a*b """ return self.__class__(self.parent(), self.__rep.lt()) @@ -699,18 +702,18 @@ def lm(self): EXAMPLES:: - sage: R.=PolynomialRing(GF(7),3,order='lex') - sage: I = sage.rings.ideal.FieldIdeal(R) - sage: Q = R.quo( I ) - sage: f = Q( z*y + 2*x ) - sage: f.lm() + sage: R. = PolynomialRing(GF(7), 3, order='lex') # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.FieldIdeal(R) # optional - sage.rings.finite_rings + sage: Q = R.quo(I) # optional - sage.rings.finite_rings + sage: f = Q(z*y + 2*x) # optional - sage.rings.finite_rings + sage: f.lm() # optional - sage.rings.finite_rings xbar TESTS:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: (a+3*a*b+b).lm() + sage: (a+3*a*b+b).lm() # optional - sage.libs.singular a*b """ @@ -722,18 +725,18 @@ def lc(self): EXAMPLES:: - sage: R.=PolynomialRing(GF(7),3,order='lex') - sage: I = sage.rings.ideal.FieldIdeal(R) - sage: Q = R.quo( I ) - sage: f = Q( z*y + 2*x ) - sage: f.lc() + sage: R. = PolynomialRing(GF(7), 3, order='lex') # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.FieldIdeal(R) # optional - sage.rings.finite_rings + sage: Q = R.quo(I) # optional - sage.rings.finite_rings + sage: f = Q(z*y + 2*x) # optional - sage.rings.finite_rings + sage: f.lc() # optional - sage.rings.finite_rings 2 TESTS:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: (a+3*a*b+b).lc() + sage: (a + 3*a*b + b).lc() # optional - sage.libs.singular 3 """ return self.__rep.lc() @@ -749,17 +752,17 @@ def variables(self): EXAMPLES:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: a.variables() + sage: a.variables() # optional - sage.libs.singular (a,) - sage: b.variables() + sage: b.variables() # optional - sage.libs.singular (b,) - sage: s = a^2 + b^2 + 1; s + sage: s = a^2 + b^2 + 1; s # optional - sage.libs.singular 1 - sage: s.variables() + sage: s.variables() # optional - sage.libs.singular () - sage: (a+b).variables() + sage: (a + b).variables() # optional - sage.libs.singular (a, b) """ return tuple(self.__class__(self.parent(), v) for v in self.__rep.variables()) @@ -774,13 +777,13 @@ def monomials(self): EXAMPLES:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: a.monomials() + sage: a.monomials() # optional - sage.libs.singular [a] - sage: (a+a*b).monomials() + sage: (a + a*b).monomials() # optional - sage.libs.singular [a*b, a] - sage: R.zero().monomials() + sage: R.zero().monomials() # optional - sage.libs.singular [] """ return [self.__class__(self.parent(), m) for m in self.__rep.monomials()] @@ -796,10 +799,10 @@ def _singular_(self, singular=singular_default): EXAMPLES:: - sage: P. = PolynomialRing(GF(2),2) - sage: I = sage.rings.ideal.FieldIdeal(P) - sage: Q = P.quo(I) - sage: Q._singular_() + sage: P. = PolynomialRing(GF(2), 2) # optional - sage.rings.finite_rings + sage: I = sage.rings.ideal.FieldIdeal(P) # optional - sage.rings.finite_rings + sage: Q = P.quo(I) # optional - sage.rings.finite_rings + sage: Q._singular_() # optional - sage.rings.finite_rings polynomial ring, over a field, global ordering // coefficients: ZZ/2 // number of vars : 2 @@ -809,20 +812,20 @@ def _singular_(self, singular=singular_default): // quotient ring from ideal _[1]=x2+x _[2]=y2+y - sage: xbar = Q(x); xbar + sage: xbar = Q(x); xbar # optional - sage.rings.finite_rings xbar - sage: xbar._singular_() + sage: xbar._singular_() # optional - sage.rings.finite_rings x - sage: Q(xbar._singular_()) # a round-trip + sage: Q(xbar._singular_()) # a round-trip # optional - sage.rings.finite_rings xbar TESTS:: - sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) + sage: R. = QQ[]; S. = R.quo(x^2 + y^2); type(a) # optional - sage.libs.singular - sage: (a-2/3*b)._singular_() + sage: (a - 2/3*b)._singular_() # optional - sage.libs.singular x-2/3*y - sage: S((a-2/3*b)._singular_()) + sage: S((a - 2/3*b)._singular_()) # optional - sage.libs.singular a - 2/3*b """ if singular is None: @@ -835,12 +838,12 @@ def _magma_init_(self, magma): EXAMPLES:: - sage: P. = PolynomialRing(GF(2)) - sage: Q = P.quotient(sage.rings.ideal.FieldIdeal(P)) - sage: xbar, ybar = Q.gens() - sage: magma(xbar) # optional -- magma + sage: P. = PolynomialRing(GF(2)) # optional - sage.rings.finite_rings + sage: Q = P.quotient(sage.rings.ideal.FieldIdeal(P)) # optional - sage.rings.finite_rings + sage: xbar, ybar = Q.gens() # optional - sage.rings.finite_rings + sage: magma(xbar) # optional - magma # optional - sage.rings.finite_rings x - sage: xbar._magma_init_(magma) # optional -- magma + sage: xbar._magma_init_(magma) # optional - magma # optional - sage.rings.finite_rings '_sage_[...]!_sage_ref...' """ g = magma(self.__rep) @@ -853,19 +856,19 @@ def _macaulay2_(self, macaulay2=None): EXAMPLES:: - sage: R. = PolynomialRing(GF(7), 2) - sage: Q = R.quotient([x^2 - y]) - sage: x, y = Q.gens() - sage: f = (x^3 + 2*y^2*x)^7; f + sage: R. = PolynomialRing(GF(7), 2) # optional - sage.rings.finite_rings + sage: Q = R.quotient([x^2 - y]) # optional - sage.rings.finite_rings + sage: x, y = Q.gens() # optional - sage.rings.finite_rings + sage: f = (x^3 + 2*y^2*x)^7; f # optional - sage.rings.finite_rings 2*xbar*ybar^17 + xbar*ybar^10 - sage: mf = macaulay2(f); mf # optional - macaulay2 + sage: mf = macaulay2(f); mf # optional - macaulay2 # optional - sage.rings.finite_rings 17 10 2x*y + x*y - sage: mf.sage() # optional - macaulay2 + sage: mf.sage() # optional - macaulay2 # optional - sage.rings.finite_rings 2*x*y^17 + x*y^10 - sage: mf.sage() == f # optional - macaulay2 + sage: mf.sage() == f # optional - macaulay2 # optional - sage.rings.finite_rings True - sage: Q(mf) # optional - macaulay2 + sage: Q(mf) # optional - macaulay2 # optional - sage.rings.finite_rings 2*xbar*ybar^17 + xbar*ybar^10 In Macaulay2, the variable names for a quotient ring are inherited from @@ -877,15 +880,15 @@ def _macaulay2_(self, macaulay2=None): :: - sage: R. = PolynomialRing(GF(7), 2) - sage: Q = R.quotient([x^2 - y], names=R.gens()) - sage: x, y = Q.gens() - sage: f = (x^3 + 2*y^2*x)^7; f + sage: R. = PolynomialRing(GF(7), 2) # optional - sage.rings.finite_rings + sage: Q = R.quotient([x^2 - y], names=R.gens()) # optional - sage.rings.finite_rings + sage: x, y = Q.gens() # optional - sage.rings.finite_rings + sage: f = (x^3 + 2*y^2*x)^7; f # optional - sage.rings.finite_rings 2*x*y^17 + x*y^10 - sage: macaulay2(f) # optional - macaulay2 + sage: macaulay2(f) # optional - macaulay2 # optional - sage.rings.finite_rings 17 10 2x*y + x*y - sage: _.sage() # optional - macaulay2 + sage: _.sage() # optional - macaulay2 # optional - sage.rings.finite_rings 2*x*y^17 + x*y^10 TESTS: @@ -893,15 +896,15 @@ def _macaulay2_(self, macaulay2=None): Check that changing the currently defined global variables (`x`, `y`, ...) in Macaulay2 does not affect the result of this conversion:: - sage: R. = PolynomialRing(GF(7), 2) - sage: Q = R.quotient([x^2 - y], names=R.gens()) - sage: x, y = Q.gens() - sage: f = (x^3 + 2*y^2*x)^7 - sage: macaulay2(f) # optional - macaulay2 + sage: R. = PolynomialRing(GF(7), 2) # optional - sage.rings.finite_rings + sage: Q = R.quotient([x^2 - y], names=R.gens()) # optional - sage.rings.finite_rings + sage: x, y = Q.gens() # optional - sage.rings.finite_rings + sage: f = (x^3 + 2*y^2*x)^7 # optional - sage.rings.finite_rings + sage: macaulay2(f) # optional - macaulay2 # optional - sage.rings.finite_rings 17 10 2x*y + x*y - sage: macaulay2.use(R.quotient([x, y])) # optional - macaulay2 - sage: macaulay2(f) # optional - macaulay2 + sage: macaulay2.use(R.quotient([x, y])) # optional - macaulay2 # optional - sage.rings.finite_rings + sage: macaulay2(f) # optional - macaulay2 # optional - sage.rings.finite_rings 17 10 2x*y + x*y """ @@ -930,17 +933,18 @@ def reduce(self, G): EXAMPLES:: - sage: P. = PolynomialRing(GF(2), 5, order='lex') - sage: I1 = ideal([a*b + c*d + 1, a*c*e + d*e, a*b*e + c*e, b*c + c*d*e + 1]) - sage: Q = P.quotient( sage.rings.ideal.FieldIdeal(P) ) - sage: I2 = ideal([Q(f) for f in I1.gens()]) - sage: f = Q((a*b + c*d + 1)^2 + e) - sage: f.reduce(I2.gens()) + sage: P. = PolynomialRing(GF(2), 5, order='lex') # optional - sage.rings.finite_rings + sage: I1 = ideal([a*b + c*d + 1, a*c*e + d*e, # optional - sage.rings.finite_rings + ....: a*b*e + c*e, b*c + c*d*e + 1]) + sage: Q = P.quotient(sage.rings.ideal.FieldIdeal(P)) # optional - sage.rings.finite_rings + sage: I2 = ideal([Q(f) for f in I1.gens()]) # optional - sage.rings.finite_rings + sage: f = Q((a*b + c*d + 1)^2 + e) # optional - sage.rings.finite_rings + sage: f.reduce(I2.gens()) # optional - sage.rings.finite_rings ebar Notice that the result above is not minimal:: - sage: I2.reduce(f) + sage: I2.reduce(f) # optional - sage.rings.finite_rings 0 """ try: diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 0e9d1f35f47..8f5c9df7593 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -300,30 +300,31 @@ cpdef rational_power_parts(a, Rational b, factor_limit=10**5): sage: rational_power_parts(3/4, -1/2) (2, 3) - sage: t = (3/4)^(-1/2); t + sage: t = (3/4)^(-1/2); t # optional - sage.symbolic 2/3*sqrt(3) - sage: t^2 + sage: t^2 # optional - sage.symbolic 4/3 Check if :trac:`15605` is fixed:: sage: rational_power_parts(-1, -1/3) (1, -1) - sage: (-1)^(-1/3) + sage: (-1)^(-1/3) # optional - sage.symbolic -(-1)^(2/3) - sage: 1 / ((-1)^(1/3)) + sage: 1 / ((-1)^(1/3)) # optional - sage.symbolic -(-1)^(2/3) sage: rational_power_parts(-1, 2/3) (1, -1) - sage: (-1)^(2/3) + sage: (-1)^(2/3) # optional - sage.symbolic (-1)^(2/3) sage: all(rational_power_parts(-1, i/77) == (1,-1) for i in range(1,9)) True - sage: (-1)^(1/3)*(-1)^(1/5) + sage: (-1)^(1/3)*(-1)^(1/5) # optional - sage.symbolic (-1)^(8/15) - sage: bool((-1)^(2/3) == -1/2 + sqrt(3)/2*I) + sage: bool((-1)^(2/3) == -1/2 + sqrt(3)/2*I) # optional - sage.symbolic True - sage: all((-1)^(p/q) == cos(p*pi/q) + I * sin(p*pi/q) for p in srange(1,6) for q in srange(1,6)) + sage: all((-1)^(p/q) == cos(p*pi/q) + I * sin(p*pi/q) # optional - sage.symbolic + ....: for p in srange(1, 6) for q in srange(1, 6)) True A few more tests added in :trac:`26414`:: @@ -380,7 +381,7 @@ cpdef rational_power_parts(a, Rational b, factor_limit=10**5): def is_Rational(x): """ - Return true if x is of the Sage rational number type. + Return ``True`` if ``x`` is of the Sage :class:`Rational` type. EXAMPLES:: @@ -422,9 +423,10 @@ cdef class Rational(sage.structure.element.FieldElement): 1/2 sage: Rational(("2", "10"), 16) 1/8 - sage: Rational(QQbar(125/8).nth_root(3)) + sage: Rational(QQbar(125/8).nth_root(3)) # optional - sage.rings.number_field 5/2 - sage: Rational(AA(209735/343 - 17910/49*golden_ratio).nth_root(3) + 3*AA(golden_ratio)) + sage: Rational(AA(209735/343 - 17910/49*golden_ratio).nth_root(3) # optional - sage.rings.number_field + ....: + 3*AA(golden_ratio)) 53/7 sage: QQ(float(1.5)) 3/2 @@ -440,24 +442,24 @@ cdef class Rational(sage.structure.element.FieldElement): Conversion from PARI:: - sage: Rational(pari('-939082/3992923')) + sage: Rational(pari('-939082/3992923')) # optional - sage.libs.pari -939082/3992923 - sage: Rational(pari('Pol([-1/2])')) #9595 + sage: Rational(pari('Pol([-1/2])')) #9595 # optional - sage.libs.pari -1/2 Conversions from numpy:: - sage: import numpy as np - sage: QQ(np.int8('-15')) + sage: import numpy as np # optional - numpy + sage: QQ(np.int8('-15')) # optional - numpy -15 - sage: QQ(np.int16('-32')) + sage: QQ(np.int16('-32')) # optional - numpy -32 - sage: QQ(np.int32('-19')) + sage: QQ(np.int32('-19')) # optional - numpy -19 - sage: QQ(np.uint32('1412')) + sage: QQ(np.uint32('1412')) # optional - numpy 1412 - sage: QQ(np.float16('12')) + sage: QQ(np.float16('12')) # optional - numpy 12 Conversions from gmpy2:: @@ -512,7 +514,7 @@ cdef class Rational(sage.structure.element.FieldElement): 7 sage: a.__init__('70', base=8); a 56 - sage: a.__init__(pari('2/3')); a + sage: a.__init__(pari('2/3')); a # optional - sage.libs.pari 2/3 sage: a.__init__('-h/3ki', 32); a -17/3730 @@ -963,9 +965,9 @@ cdef class Rational(sage.structure.element.FieldElement): EXAMPLES:: - sage: ex = SR(QQ(7)/3); ex + sage: ex = SR(QQ(7)/3); ex # optional - sage.symbolic 7/3 - sage: parent(ex) + sage: parent(ex) # optional - sage.symbolic Symbolic Ring """ return sring._force_pyobject(self, force=True) @@ -976,12 +978,12 @@ cdef class Rational(sage.structure.element.FieldElement): EXAMPLES:: - sage: n = 1/2; n._sympy_() + sage: n = 1/2; n._sympy_() # optional - sympy 1/2 - sage: n = -1/5; n._sympy_() + sage: n = -1/5; n._sympy_() # optional - sympy -1/5 - sage: from sympy import Symbol - sage: QQ(1)+Symbol('x')*QQ(2) + sage: from sympy import Symbol # optional - sympy + sage: QQ(1) + Symbol('x')*QQ(2) # optional - sympy 2*x + 1 """ import sympy @@ -1035,7 +1037,7 @@ cdef class Rational(sage.structure.element.FieldElement): EXAMPLES:: sage: n = -485/82847 - sage: n._magma_init_(magma) # optional - magma + sage: n._magma_init_(magma) # optional - magma '-485/82847' """ return self.numerator()._magma_init_(magma) + '/' + self.denominator()._magma_init_(magma) @@ -1049,16 +1051,16 @@ cdef class Rational(sage.structure.element.FieldElement): EXAMPLES:: - sage: import numpy - sage: numpy.array([1, 2, 3/1]) + sage: import numpy # optional - numpy + sage: numpy.array([1, 2, 3/1]) # optional - numpy array([1, 2, 3]) - sage: numpy.array(QQ(2**40)).dtype + sage: numpy.array(QQ(2**40)).dtype # optional - numpy dtype('int64') - sage: numpy.array(QQ(2**400)).dtype + sage: numpy.array(QQ(2**400)).dtype # optional - numpy dtype('O') - sage: numpy.array([1, 1/2, 3/4]) + sage: numpy.array([1, 1/2, 3/4]) # optional - numpy array([1. , 0.5 , 0.75]) """ if mpz_cmp_ui(mpq_denref(self.value), 1) == 0: @@ -1114,7 +1116,7 @@ cdef class Rational(sage.structure.element.FieldElement): def content(self, other): """ - Return the content of ``self`` and ``other``, i.e. the unique positive + Return the content of ``self`` and ``other``, i.e., the unique positive rational number `c` such that ``self/c`` and ``other/c`` are coprime integers. @@ -1191,7 +1193,7 @@ cdef class Rational(sage.structure.element.FieldElement): - ``p`` -- a prime number - ``prec`` (int) -- desired floating point precision (default: - default RealField precision). + default :class:`RealField` precision). OUTPUT: @@ -1228,7 +1230,7 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - ``prec`` (int) -- desired floating point precision (default: - default RealField precision). + default :class:`RealField` precision). OUTPUT: @@ -1264,7 +1266,7 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - ``prec`` (int) -- desired floating point precision (default: - default RealField precision). + default :class:`RealField` precision). OUTPUT: @@ -1307,7 +1309,7 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - ``prec`` (int) -- desired floating point precision (default: - default RealField precision). + default :class:`RealField` precision). OUTPUT: @@ -1339,7 +1341,7 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - ``prec`` (int) -- desired floating point precision (default: - default RealField precision). + default :class:`RealField` precision). OUTPUT: @@ -1402,11 +1404,11 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``L`` -- a number field - - ``element`` -- (default: ``False``) boolean whether to also output - an element of which ``self`` is a norm - - proof -- If ``True``, then the output is correct unconditionally. - If ``False``, then the output assumes GRH. + - ``L`` -- a number field + - ``element`` -- (default: ``False``) boolean whether to also output + an element of which ``self`` is a norm + - ``proof`` -- If ``True``, then the output is correct unconditionally. + If ``False``, then the output assumes GRH. OUTPUT: @@ -1418,46 +1420,47 @@ cdef class Rational(sage.structure.element.FieldElement): ALGORITHM: - Uses PARI's bnfisnorm. See ``_bnfisnorm()``. + Uses the PARI function :pari:`bnfisnorm`. See :meth:`_bnfisnorm()`. EXAMPLES:: - sage: K = NumberField(x^2 - 2, 'beta') - sage: (1/7).is_norm(K) + sage: K = NumberField(x^2 - 2, 'beta') # optional - sage.rings.number_field + sage: (1/7).is_norm(K) # optional - sage.rings.number_field True - sage: (1/10).is_norm(K) + sage: (1/10).is_norm(K) # optional - sage.rings.number_field False - sage: 0.is_norm(K) + sage: 0.is_norm(K) # optional - sage.rings.number_field True - sage: (1/7).is_norm(K, element=True) + sage: (1/7).is_norm(K, element=True) # optional - sage.rings.number_field (True, 1/7*beta + 3/7) - sage: (1/10).is_norm(K, element=True) + sage: (1/10).is_norm(K, element=True) # optional - sage.rings.number_field (False, None) - sage: (1/691).is_norm(QQ, element=True) + sage: (1/691).is_norm(QQ, element=True) # optional - sage.rings.number_field (True, 1/691) The number field doesn't have to be defined by an integral polynomial:: - sage: B, e = (1/5).is_norm(QuadraticField(5/4, 'a'), element=True) - sage: B + sage: B, e = (1/5).is_norm(QuadraticField(5/4, 'a'), element=True) # optional - sage.rings.number_field + sage: B # optional - sage.rings.number_field True - sage: e.norm() + sage: e.norm() # optional - sage.rings.number_field 1/5 A non-Galois number field:: - sage: K. = NumberField(x^3-2) - sage: B, e = (3/5).is_norm(K, element=True); B + sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field + sage: B, e = (3/5).is_norm(K, element=True); B # optional - sage.rings.number_field True - sage: e.norm() + sage: e.norm() # optional - sage.rings.number_field 3/5 - sage: 7.is_norm(K) + sage: 7.is_norm(K) # optional - sage.rings.number_field Traceback (most recent call last): ... - NotImplementedError: is_norm is not implemented unconditionally for norms from non-Galois number fields - sage: 7.is_norm(K, proof=False) + NotImplementedError: is_norm is not implemented unconditionally + for norms from non-Galois number fields + sage: 7.is_norm(K, proof=False) # optional - sage.rings.number_field False AUTHORS: @@ -1540,9 +1543,9 @@ cdef class Rational(sage.structure.element.FieldElement): EXAMPLES:: - sage: QQ(2)._bnfisnorm(QuadraticField(-1, 'i')) + sage: QQ(2)._bnfisnorm(QuadraticField(-1, 'i')) # optional - sage.rings.number_field (i + 1, 1) - sage: 7._bnfisnorm(NumberField(x^3-2, 'b')) + sage: 7._bnfisnorm(NumberField(x^3 - 2, 'b')) # optional - sage.rings.number_field (1, 7) AUTHORS: @@ -1609,9 +1612,9 @@ cdef class Rational(sage.structure.element.FieldElement): This test makes sure we workaround a bug in GMP (see :trac:`4612`):: - sage: [ -a for a in srange(100) if not QQ(-a^3).is_perfect_power() ] + sage: [-a for a in srange(100) if not QQ(-a^3).is_perfect_power()] [] - sage: [ -a for a in srange(100) if not QQ(-a^3).is_perfect_power(True) ] + sage: [-a for a in srange(100) if not QQ(-a^3).is_perfect_power(True)] [] """ cdef int s @@ -1694,7 +1697,7 @@ cdef class Rational(sage.structure.element.FieldElement): def squarefree_part(self): """ - Return the square free part of `x`, i.e., an integer z such + Return the square free part of `x`, i.e., an integer `z` such that `x = z y^2`, for a perfect square `y^2`. EXAMPLES:: @@ -1901,16 +1904,16 @@ cdef class Rational(sage.structure.element.FieldElement): sage: x.sqrt(all=True) [10, -10] sage: x = 81/5 - sage: x.sqrt() + sage: x.sqrt() # optional - sage.symbolic 9*sqrt(1/5) sage: x = -81/3 - sage: x.sqrt() + sage: x.sqrt() # optional - sage.symbolic 3*sqrt(-3) :: sage: n = 2/3 - sage: n.sqrt() + sage: n.sqrt() # optional - sage.symbolic sqrt(2/3) sage: n.sqrt(prec=10) 0.82 @@ -1924,7 +1927,7 @@ cdef class Rational(sage.structure.element.FieldElement): Traceback (most recent call last): ... ValueError: square root of 2/3 not a rational number - sage: sqrt(-2/3, all=True) + sage: sqrt(-2/3, all=True) # optional - sage.symbolic [sqrt(-2/3), -sqrt(-2/3)] sage: sqrt(-2/3, prec=53) 0.816496580927726*I @@ -1990,20 +1993,20 @@ cdef class Rational(sage.structure.element.FieldElement): EXAMPLES:: - sage: (1/7).period() + sage: (1/7).period() # optional - sage.libs.pari 6 sage: RR(1/7) 0.142857142857143 - sage: (1/8).period() + sage: (1/8).period() # optional - sage.libs.pari 1 sage: RR(1/8) 0.125000000000000 sage: RR(1/6) 0.166666666666667 - sage: (1/6).period() + sage: (1/6).period() # optional - sage.libs.pari 1 sage: x = 333/106 - sage: x.period() + sage: x.period() # optional - sage.libs.pari 13 sage: RealField(200)(x) 3.1415094339622641509433962264150943396226415094339622641509 @@ -2022,7 +2025,7 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``n`` - integer (must fit in C int type) + - ``n`` - integer (must fit in C ``int`` type) AUTHORS: @@ -2085,7 +2088,7 @@ cdef class Rational(sage.structure.element.FieldElement): INPUT: - - ``n`` - integer (must fit in C int type) + - ``n`` - integer (must fit in C ``int`` type) .. NOTE:: @@ -2515,9 +2518,9 @@ cdef class Rational(sage.structure.element.FieldElement): sage: (2/3)^5 32/243 - sage: (-1/1)^(1/3) + sage: (-1/1)^(1/3) # optional - sage.symbolic (-1)^(1/3) - sage: (2/3)^(3/4) + sage: (2/3)^(3/4) # optional - sage.symbolic (2/3)^(3/4) sage: (-1/3)^0 1 @@ -2532,18 +2535,18 @@ cdef class Rational(sage.structure.element.FieldElement): 2/3 sage: parent(a) Rational Field - sage: (-27/125)^(1/3) + sage: (-27/125)^(1/3) # optional - sage.symbolic 3/5*(-1)^(1/3) - sage: (-27/125)^(1/2) + sage: (-27/125)^(1/2) # optional - sage.symbolic 3/5*sqrt(-3/5) The result is normalized to have the rational power in the numerator:: - sage: 2^(-1/2) + sage: 2^(-1/2) # optional - sage.symbolic 1/2*sqrt(2) - sage: 8^(-1/5) + sage: 8^(-1/5) # optional - sage.symbolic 1/8*8^(4/5) - sage: 3^(-3/2) + sage: 3^(-3/2) # optional - sage.symbolic 1/9*sqrt(3) TESTS:: @@ -2555,14 +2558,14 @@ cdef class Rational(sage.structure.element.FieldElement): This works even if the base is a Python integer:: - sage: int(2)^(1/2) + sage: int(2)^(1/2) # optional - sage.symbolic sqrt(2) sage: a = int(2)^(3/1); a 8 sage: type(a) - The exponent must fit in a long unless the base is -1, 0, or 1:: + The exponent must fit in a ``long`` unless the base is -1, 0, or 1:: sage: (1/2)^(2^100) Traceback (most recent call last): @@ -2574,7 +2577,7 @@ cdef class Rational(sage.structure.element.FieldElement): ... OverflowError: exponent must be at most 2147483647 # 32-bit OverflowError: exponent must be at most 9223372036854775807 # 64-bit - sage: QQ(-1)^(2^100) + sage: QQ(-1)^(2^100) # optional - sage.symbolic 1 """ n = other @@ -2821,7 +2824,7 @@ cdef class Rational(sage.structure.element.FieldElement): def norm(self): r""" Return the norm from `\QQ` to `\QQ` of `x` (which is just `x`). This - was added for compatibility with :class:`NumberFields`. + was added for compatibility with :class:`NumberField`. OUTPUT: @@ -2904,7 +2907,7 @@ cdef class Rational(sage.structure.element.FieldElement): sage: (1/3).charpoly('x') x - 1/3 - The default is var='x'. (:trac:`20967`):: + The default is ``var='x'``. (:trac:`20967`):: sage: a = QQ(2); a.charpoly('x') x - 2 @@ -2968,7 +2971,7 @@ cdef class Rational(sage.structure.element.FieldElement): def numerator(self): """ Return the numerator of this rational number. - numer is an alias of numerator. + :meth:`numer` is an alias of :meth:`numerator`. EXAMPLES:: @@ -3018,7 +3021,7 @@ cdef class Rational(sage.structure.element.FieldElement): def denominator(self): """ Return the denominator of this rational number. - denom is an alias of denominator. + :meth:`denom` is an alias of :meth:`denominator`. EXAMPLES:: @@ -3121,15 +3124,15 @@ cdef class Rational(sage.structure.element.FieldElement): EXAMPLES:: - sage: (124/345).log(5) + sage: (124/345).log(5) # optional - sage.symbolic log(124/345)/log(5) - sage: (124/345).log(5,100) + sage: (124/345).log(5, 100) -0.63578895682825611710391773754 - sage: log(QQ(125)) + sage: log(QQ(125)) # optional - sage.symbolic 3*log(5) sage: log(QQ(125), 5) 3 - sage: log(QQ(125), 3) + sage: log(QQ(125), 3) # optional - sage.symbolic 3*log(5)/log(3) sage: QQ(8).log(1/2) -3 @@ -3149,14 +3152,14 @@ cdef class Rational(sage.structure.element.FieldElement): -4/3 sage: (125/8).log(5/2) 3 - sage: (125/8).log(5/2,prec=53) + sage: (125/8).log(5/2, prec=53) 3.00000000000000 TESTS:: - sage: (25/2).log(5/2) + sage: (25/2).log(5/2) # optional - sage.symbolic log(25/2)/log(5/2) - sage: (-1/2).log(3) + sage: (-1/2).log(3) # optional - sage.symbolic (I*pi + log(1/2))/log(3) """ cdef int self_sgn @@ -3225,15 +3228,15 @@ cdef class Rational(sage.structure.element.FieldElement): EXAMPLES:: - sage: gamma(1/2) + sage: gamma(1/2) # optional - sage.symbolic sqrt(pi) - sage: gamma(7/2) + sage: gamma(7/2) # optional - sage.symbolic 15/8*sqrt(pi) - sage: gamma(-3/2) + sage: gamma(-3/2) # optional - sage.symbolic 4/3*sqrt(pi) - sage: gamma(6/1) + sage: gamma(6/1) # optional - sage.symbolic 120 - sage: gamma(1/3) + sage: gamma(1/3) # optional - sage.symbolic gamma(1/3) This function accepts an optional precision argument:: @@ -3341,7 +3344,7 @@ cdef class Rational(sage.structure.element.FieldElement): def round(Rational self, mode="away"): """ Return the nearest integer to ``self``, rounding away from 0 by - default, for consistency with the builtin Python round. + default, for consistency with the builtin Python :func:`round`. INPUT: @@ -3554,7 +3557,7 @@ cdef class Rational(sage.structure.element.FieldElement): def is_integral(self): r""" - Determine if a rational number is integral (i.e is in + Determine if a rational number is integral (i.e., is in `\ZZ`). OUTPUT: bool @@ -3768,11 +3771,11 @@ cdef class Rational(sage.structure.element.FieldElement): EXAMPLES:: sage: n = 9390823/17 - sage: m = n.__pari__(); m + sage: m = n.__pari__(); m # optional - sage.libs.pari 9390823/17 - sage: type(m) + sage: type(m) # optional - sage.libs.pari - sage: m.type() + sage: m.type() # optional - sage.libs.pari 't_FRAC' """ global new_gen_from_rational @@ -4124,7 +4127,8 @@ cdef class Z_to_Q(Morphism): maps (see :trac:`15618`):: sage: f.parent() - Set of Morphisms from Rational Field to Integer Ring in Category of sets with partial maps + Set of Morphisms from Rational Field to Integer Ring + in Category of sets with partial maps """ from sage.categories.sets_with_partial_maps import SetsWithPartialMaps return Q_to_Z(self._codomain.Hom(self.domain(), category=SetsWithPartialMaps())) diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index ca704238181..a5755f56206 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -11,7 +11,7 @@ Rational Field Values of various types can be converted to rational numbers by using the -``__call__`` method of ``RationalField`` (that is, by treating ``QQ`` as a +:meth:`__call__` method of :class:`RationalField` (that is, by treating ``QQ`` as a function). :: @@ -86,7 +86,7 @@ class RationalField(Singleton, number_field_base.NumberField): -930482/9320842317 sage: QQ([9320842317]) 9320842317 - sage: QQ(pari(39029384023840928309482842098430284398243982394)) + sage: QQ(pari(39029384023840928309482842098430284398243982394)) # optional - sage.libs.pari 39029384023840928309482842098430284398243982394 sage: QQ('sage') Traceback (most recent call last): @@ -105,7 +105,7 @@ class RationalField(Singleton, number_field_base.NumberField): sage: QQ(RR(1/7)) - 1/7 0 - If you specify an optional second base argument, then the string + If you specify the optional second argument ``base``, then the string representation of the float is used. :: @@ -304,7 +304,7 @@ def __len__(self): def construction(self): r""" - Returns a pair ``(functor, parent)`` such that ``functor(parent)`` + Return a pair ``(functor, parent)`` such that ``functor(parent)`` returns ``self``. This is the construction of `\QQ` as the fraction field of `\ZZ`. @@ -441,7 +441,7 @@ def __truediv__(self, I): EXAMPLES:: - sage: QQ / ZZ + sage: QQ / ZZ # optional - sage.groups Q/Z """ from sage.rings.ideal import Ideal_generic @@ -459,9 +459,9 @@ def range_by_height(self, start, end=None): Returns a Python generator for the list of rational numbers with heights in ``range(start, end)``. Follows the same - convention as Python range, see ``range?`` for details. + convention as Python :func:`range`, type ``range?`` for details. - See also ``__iter__()``. + See also :meth:`__iter__`. EXAMPLES: @@ -526,9 +526,9 @@ def primes_of_bounded_norm_iter(self, B): EXAMPLES:: sage: it = QQ.primes_of_bounded_norm_iter(10) - sage: list(it) + sage: list(it) # optional - sage.libs.pari [2, 3, 5, 7] - sage: list(QQ.primes_of_bounded_norm_iter(1)) + sage: list(QQ.primes_of_bounded_norm_iter(1)) # optional - sage.libs.pari [] """ try: @@ -607,14 +607,14 @@ def embeddings(self, K): sage: QQ.embeddings(QQ) [Identity endomorphism of Rational Field] - sage: QQ.embeddings(CyclotomicField(5)) + sage: QQ.embeddings(CyclotomicField(5)) # optional - sage.rings.number_field [Coercion map: From: Rational Field To: Cyclotomic Field of order 5 and degree 4] `K` must have characteristic 0:: - sage: QQ.embeddings(GF(3)) + sage: QQ.embeddings(GF(3)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: no embeddings of the rational field into K. @@ -627,9 +627,7 @@ def automorphisms(self): r""" Return all Galois automorphisms of ``self``. - OUTPUT: - - - a sequence containing just the identity morphism + OUTPUT: a sequence containing just the identity morphism EXAMPLES:: @@ -644,15 +642,15 @@ def automorphisms(self): def places(self, all_complex=False, prec=None): r""" - Return the collection of all infinite places of self, which - in this case is just the embedding of self into `\RR`. + Return the collection of all infinite places of ``self``, which + in this case is just the embedding of ``self`` into `\RR`. By default, this returns homomorphisms into ``RR``. If ``prec`` is not None, we simply return homomorphisms into ``RealField(prec)`` (or ``RDF`` if ``prec=53``). There is an optional flag ``all_complex``, which defaults to - False. If ``all_complex`` is True, then the real embeddings + ``False``. If ``all_complex`` is ``True``, then the real embeddings are returned as embeddings into the corresponding complex field. @@ -723,7 +721,7 @@ def residue_field(self, p, check=True): - ``p`` - a prime integer. - - ``check`` (default True) - if True check the primality of + - ``check`` (default ``True``) - if ``True``, check the primality of `p`, else do not. OUTPUT: The residue field at this prime. @@ -740,7 +738,7 @@ def residue_field(self, p, check=True): def hilbert_symbol_negative_at_S(self, S, b, check=True): r""" - Returns an integer that has a negative Hilbert symbol with respect + Return an integer that has a negative Hilbert symbol with respect to a given rational number and a given set of primes (or places). The function is algorithm 3.4.1 in [Kir2016]_. It finds an integer `a` @@ -750,10 +748,10 @@ def hilbert_symbol_negative_at_S(self, S, b, check=True): INPUT: - ``S`` -- a list of rational primes, the infinite place as real - embedding of `\QQ` or as -1 + embedding of `\QQ` or as `-1` - ``b`` -- a non-zero rational number which is a non-square locally at every prime in ``S``. - - ``check`` -- ``bool`` (default:``True``) perform additional checks on + - ``check`` -- ``bool`` (default: ``True``) perform additional checks on input and confirm the output. OUTPUT: @@ -763,37 +761,37 @@ def hilbert_symbol_negative_at_S(self, S, b, check=True): EXAMPLES:: - sage: QQ.hilbert_symbol_negative_at_S([-1,5,3,2,7,11,13,23], -10/7) + sage: QQ.hilbert_symbol_negative_at_S([-1,5,3,2,7,11,13,23], -10/7) # optional - sage.rings.padics -9867 - sage: QQ.hilbert_symbol_negative_at_S([3, 5, QQ.places()[0], 11], -15) + sage: QQ.hilbert_symbol_negative_at_S([3, 5, QQ.places()[0], 11], -15) # optional - sage.rings.padics -33 - sage: QQ.hilbert_symbol_negative_at_S([3, 5], 2) + sage: QQ.hilbert_symbol_negative_at_S([3, 5], 2) # optional - sage.rings.padics 15 TESTS:: - sage: QQ.hilbert_symbol_negative_at_S(5/2, -2) + sage: QQ.hilbert_symbol_negative_at_S(5/2, -2) # optional - sage.libs.pari sage.modules Traceback (most recent call last): ... TypeError: first argument must be a list or integer :: - sage: QQ.hilbert_symbol_negative_at_S([1, 3], 0) + sage: QQ.hilbert_symbol_negative_at_S([1, 3], 0) # optional - sage.libs.pari sage.modules Traceback (most recent call last): ... ValueError: second argument must be nonzero :: - sage: QQ.hilbert_symbol_negative_at_S([-1, 3, 5], 2) + sage: QQ.hilbert_symbol_negative_at_S([-1, 3, 5], 2) # optional - sage.libs.pari sage.modules Traceback (most recent call last): ... ValueError: list should be of even cardinality :: - sage: QQ.hilbert_symbol_negative_at_S([1, 3], 2) + sage: QQ.hilbert_symbol_negative_at_S([1, 3], 2) # optional - sage.libs.pari sage.modules Traceback (most recent call last): ... ValueError: all entries in list must be prime or -1 for @@ -801,7 +799,7 @@ def hilbert_symbol_negative_at_S(self, S, b, check=True): :: - sage: QQ.hilbert_symbol_negative_at_S([5, 7], 2) + sage: QQ.hilbert_symbol_negative_at_S([5, 7], 2) # optional - sage.libs.pari sage.modules Traceback (most recent call last): ... ValueError: second argument must be a nonsquare with @@ -809,14 +807,14 @@ def hilbert_symbol_negative_at_S(self, S, b, check=True): :: - sage: QQ.hilbert_symbol_negative_at_S([1, 3], sqrt(2)) + sage: QQ.hilbert_symbol_negative_at_S([1, 3], sqrt(2)) # optional - sage.libs.pari sage.modules Traceback (most recent call last): ... TypeError: second argument must be a rational number :: - sage: QQ.hilbert_symbol_negative_at_S([-1, 3], 2) + sage: QQ.hilbert_symbol_negative_at_S([-1, 3], 2) # optional - sage.libs.pari sage.modules Traceback (most recent call last): ... ValueError: if the infinite place is in the list, the second @@ -913,7 +911,7 @@ def phi(x): def gens(self): r""" - Return a tuple of generators of `\QQ` which is only ``(1,)``. + Return a tuple of generators of `\QQ`, which is only ``(1,)``. EXAMPLES:: @@ -926,7 +924,7 @@ def gen(self, n=0): r""" Return the ``n``-th generator of `\QQ`. - There is only the 0-th generator which is 1. + There is only the 0-th generator, which is 1. EXAMPLES:: @@ -940,7 +938,7 @@ def gen(self, n=0): def degree(self): r""" - Return the degree of `\QQ` which is 1. + Return the degree of `\QQ`, which is 1. EXAMPLES:: @@ -951,7 +949,7 @@ def degree(self): def absolute_degree(self): r""" - Return the absolute degree of `\QQ` which is 1. + Return the absolute degree of `\QQ`, which is 1. EXAMPLES:: @@ -962,7 +960,7 @@ def absolute_degree(self): def ngens(self): r""" - Return the number of generators of `\QQ` which is 1. + Return the number of generators of `\QQ`, which is 1. EXAMPLES:: @@ -1056,16 +1054,16 @@ def extension(self, poly, names, **kwds): We make a single absolute extension:: - sage: K. = QQ.extension(x^3 + 5); K + sage: K. = QQ.extension(x^3 + 5); K # optional - sage.rings.number_field Number Field in a with defining polynomial x^3 + 5 We make an extension generated by roots of two polynomials:: - sage: K. = QQ.extension([x^3 + 5, x^2 + 3]); K + sage: K. = QQ.extension([x^3 + 5, x^2 + 3]); K # optional - sage.rings.number_field Number Field in a with defining polynomial x^3 + 5 over its base field - sage: b^2 + sage: b^2 # optional - sage.rings.number_field -3 - sage: a^3 + sage: a^3 # optional - sage.rings.number_field -5 """ from sage.rings.number_field.number_field import NumberField @@ -1073,11 +1071,11 @@ def extension(self, poly, names, **kwds): def algebraic_closure(self): r""" - Return the algebraic closure of self (which is `\QQbar`). + Return the algebraic closure of ``self`` (which is `\QQbar`). EXAMPLES:: - sage: QQ.algebraic_closure() + sage: QQ.algebraic_closure() # optional - sage.rings.number_field Algebraic Field """ from sage.rings.qqbar import QQbar @@ -1085,7 +1083,7 @@ def algebraic_closure(self): def order(self): r""" - Return the order of `\QQ` which is `\infty`. + Return the order of `\QQ`, which is `\infty`. EXAMPLES:: @@ -1099,8 +1097,8 @@ def polynomial(self): r""" Return a defining polynomial of `\QQ`, as for other number fields. - This is also aliased to :meth:`self.defining_polynomial()` - and :meth:`self.absolute_polynomial()`. + This is also aliased to :meth:`defining_polynomial` + and :meth:`absolute_polynomial`. EXAMPLES:: @@ -1131,9 +1129,7 @@ def some_elements(self): See :func:`TestSuite` for a typical use case. - OUTPUT: - - An iterator over 100 elements of `\QQ`. + OUTPUT: An iterator over 100 elements of `\QQ`. EXAMPLES:: @@ -1172,7 +1168,7 @@ def some_elements(self): def random_element(self, num_bound=None, den_bound=None, *args, **kwds): r""" - Return an random element of `\QQ`. + Return a random element of `\QQ`. Elements are constructed by randomly choosing integers for the numerator and denominator, not necessarily coprime. @@ -1282,7 +1278,7 @@ def selmer_generators(self, S, m, proof=True, orders=False): - ``proof`` -- ignored - - ``orders`` (default False) -- if True, output two lists, the + - ``orders`` (default ``False``) -- if ``True``, output two lists, the generators and their orders OUTPUT: @@ -1301,7 +1297,7 @@ def selmer_generators(self, S, m, proof=True, orders=False): :meth:`RationalField.selmer_space`, which gives additional output when `m=p` is prime: as well as generators, it gives an - abstract vector space over `GF(p)` isomorphic to `\QQ(S,p)` + abstract vector space over `\GF{p}` isomorphic to `\QQ(S,p)` and maps implementing the isomorphism between this space and `\QQ(S,p)` as a subgroup of `\QQ^*/(\QQ^*)^p`. @@ -1388,7 +1384,7 @@ def selmer_space(self, S, p, proof=None): (tuple) ``QSp``, ``QSp_gens``, ``from_QSp``, ``to_QSp`` where - - ``QSp`` is an abstract vector space over `GF(p)` isomorphic to `\QQ(S,p)`; + - ``QSp`` is an abstract vector space over `\GF{p}` isomorphic to `\QQ(S,p)`; - ``QSp_gens`` is a list of elements of `\QQ^*` generating `\QQ(S,p)`; @@ -1412,45 +1408,47 @@ def selmer_space(self, S, p, proof=None): When `S` is empty, `\QQ(S,p)` is only nontrivial for `p=2`:: - sage: QS2, QS2gens, fromQS2, toQS2 = QQ.selmer_space([], 2) - sage: QS2 + sage: QS2, QS2gens, fromQS2, toQS2 = QQ.selmer_space([], 2) # optional - sage.rings.number_field + sage: QS2 # optional - sage.rings.number_field Vector space of dimension 1 over Finite Field of size 2 - sage: QS2gens + sage: QS2gens # optional - sage.rings.number_field [-1] - sage: all(QQ.selmer_space([], p)[0].dimension() == 0 for p in primes(3,10)) + sage: all(QQ.selmer_space([], p)[0].dimension() == 0 # optional - sage.libs.pari + ....: for p in primes(3, 10)) True In general there is one generator for each `p\in S`, and an additional generator of `-1` when `p=2`:: - sage: QS2, QS2gens, fromQS2, toQS2 = QQ.selmer_space([5,7], 2) - sage: QS2 + sage: QS2, QS2gens, fromQS2, toQS2 = QQ.selmer_space([5,7], 2) # optional - sage.modules + sage: QS2 # optional - sage.modules Vector space of dimension 3 over Finite Field of size 2 - sage: QS2gens + sage: QS2gens # optional - sage.modules [5, 7, -1] - sage: toQS2(-7) + sage: toQS2(-7) # optional - sage.modules (0, 1, 1) - sage: fromQS2((0,1,1)) + sage: fromQS2((0,1,1)) # optional - sage.modules -7 The map ``fromQS2`` is only well-defined modulo `p`'th powers (in this case, modulo squares):: - sage: toQS2(-5/7) + sage: toQS2(-5/7) # optional - sage.modules (1, 1, 1) - sage: fromQS2((1,1,1)) + sage: fromQS2((1,1,1)) # optional - sage.modules -35 - sage: ((-5/7)/(-35)).is_square() + sage: ((-5/7)/(-35)).is_square() # optional - sage.modules True The map ``toQS2`` is not defined on all of `\QQ^*`, only on those numbers which are squares away from `5` and `7`:: - sage: toQS2(210) + sage: toQS2(210) # optional - sage.modules Traceback (most recent call last): ... - ValueError: argument 210 should have valuations divisible by 2 at all primes in [5, 7] + ValueError: argument 210 should have valuations divisible by 2 + at all primes in [5, 7] """ from sage.rings.number_field.selmer_group import pSelmerGroup @@ -1516,7 +1514,7 @@ def _gap_init_(self): EXAMPLES:: - sage: gap(QQ) # indirect doctest + sage: gap(QQ) # indirect doctest # optional - sage.libs.gap Rationals """ return 'Rationals' @@ -1584,7 +1582,7 @@ def _sympy_(self): EXAMPLES:: - sage: QQ._sympy_() + sage: QQ._sympy_() # optional - sympy Rationals """ from sympy import Rationals @@ -1630,20 +1628,20 @@ def _factor_univariate_polynomial(self, f): TESTS:: sage: R. = QQ[] - sage: QQ._factor_univariate_polynomial( x ) + sage: QQ._factor_univariate_polynomial(x) # optional - sage.libs.pari x - sage: QQ._factor_univariate_polynomial( 2*x ) + sage: QQ._factor_univariate_polynomial(2*x) # optional - sage.libs.pari (2) * x - sage: QQ._factor_univariate_polynomial( (x^2 - 1/4)^4 ) + sage: QQ._factor_univariate_polynomial((x^2 - 1/4)^4) # optional - sage.libs.pari (x - 1/2)^4 * (x + 1/2)^4 - sage: QQ._factor_univariate_polynomial( (2*x + 1) * (3*x^2 - 5)^2 ) + sage: QQ._factor_univariate_polynomial((2*x + 1) * (3*x^2 - 5)^2) # optional - sage.libs.pari (18) * (x + 1/2) * (x^2 - 5/3)^2 - sage: f = prod((k^2*x^k + k)^(k-1) for k in primes(10)) - sage: QQ._factor_univariate_polynomial(f) + sage: f = prod((k^2*x^k + k)^(k-1) for k in primes(10)) # optional - sage.libs.pari + sage: QQ._factor_univariate_polynomial(f) # optional - sage.libs.pari (1751787911376562500) * (x^2 + 1/2) * (x^3 + 1/3)^2 * (x^5 + 1/5)^4 * (x^7 + 1/7)^6 - sage: QQ._factor_univariate_polynomial( 10*x^5 - 1 ) + sage: QQ._factor_univariate_polynomial(10*x^5 - 1) # optional - sage.libs.pari (10) * (x^5 - 1/10) - sage: QQ._factor_univariate_polynomial( 10*x^5 - 10 ) + sage: QQ._factor_univariate_polynomial(10*x^5 - 10) # optional - sage.libs.pari (10) * (x - 1) * (x^4 + x^3 + x^2 + x + 1) """ @@ -1661,9 +1659,9 @@ def valuation(self, p): EXAMPLES:: - sage: v = QQ.valuation(3); v + sage: v = QQ.valuation(3); v # optional - sage.rings.padics 3-adic valuation - sage: v(1/3) + sage: v(1/3) # optional - sage.rings.padics -1 .. SEEALSO:: diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx index b969c762e84..383376cd1ff 100644 --- a/src/sage/rings/real_arb.pyx +++ b/src/sage/rings/real_arb.pyx @@ -175,11 +175,11 @@ TESTS:: :: - sage: SR.coerce(RBF(0.42)) + sage: SR.coerce(RBF(0.42)) # optional - sage.symbolic [0.4200000000000000 +/- ...e-17] - sage: RBF(0.42) + SR(1) + sage: RBF(0.42) + SR(1) # optional - sage.symbolic [1.420000000000000 +/- ...e-16] - sage: _.parent() + sage: _.parent() # optional - sage.symbolic Symbolic Ring Classes and Methods @@ -457,7 +457,7 @@ class RealBallField(UniqueRepresentation, sage.rings.abc.RealBallField): False sage: RealBallField().has_coerce_map_from(RIF) False - sage: RealBallField().has_coerce_map_from(SR) + sage: RealBallField().has_coerce_map_from(SR) # optional - sage.symbolic False sage: RealBallField().has_coerce_map_from(RR) False @@ -2521,7 +2521,7 @@ cdef class RealBall(RingElement): def is_finite(self): """ - Return True iff the midpoint and radius of this ball are both + Return ``True`` iff the midpoint and radius of this ball are both finite floating-point numbers, i.e. not infinities or NaN. EXAMPLES:: @@ -2535,7 +2535,7 @@ cdef class RealBall(RingElement): def identical(self, RealBall other): """ - Return True iff ``self`` and ``other`` are equal as balls, i.e. + Return ``True`` iff ``self`` and ``other`` are equal as balls, i.e. have both the same midpoint and radius. Note that this is not the same thing as testing whether both ``self`` @@ -2558,7 +2558,7 @@ cdef class RealBall(RingElement): def overlaps(self, RealBall other): """ - Return True iff ``self`` and ``other`` have some point in common. + Return ``True`` iff ``self`` and ``other`` have some point in common. If either ``self`` or ``other`` contains NaN, this method always returns nonzero (as a NaN could be anything, it could in particular @@ -2641,7 +2641,7 @@ cdef class RealBall(RingElement): def __contains__(self, other): """ - Return True if ``other`` can be verified to be contained in ``self``. + Return ``True`` if ``other`` can be verified to be contained in ``self``. The test is done using interval arithmetic with a precision determined by the parent of ``self`` and may return false negatives. diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index 21a2f293ee9..dcaf1108e8c 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -5,21 +5,21 @@ EXAMPLES: We create the real double vector space of dimension `3`:: - sage: V = RDF^3; V + sage: V = RDF^3; V # optional - sage.modules Vector space of dimension 3 over Real Double Field Notice that this space is unique:: - sage: V is RDF^3 + sage: V is RDF^3 # optional - sage.modules True - sage: V is FreeModule(RDF, 3) + sage: V is FreeModule(RDF, 3) # optional - sage.modules True - sage: V is VectorSpace(RDF, 3) + sage: V is VectorSpace(RDF, 3) # optional - sage.modules True Also, you can instantly create a space of large dimension:: - sage: V = RDF^10000 + sage: V = RDF^10000 # optional - sage.modules TESTS: @@ -27,8 +27,8 @@ Test NumPy conversions:: sage: RDF(1).__array_interface__ {'typestr': '=f8'} - sage: import numpy - sage: numpy.array([RDF.pi()]).dtype + sage: import numpy # optional - numpy + sage: numpy.array([RDF.pi()]).dtype # optional - numpy dtype('float64') """ @@ -332,10 +332,10 @@ cdef class RealDoubleField_class(sage.rings.abc.RealDoubleField): sage: RLF(2/3) + RDF(1) 1.6666666666666665 - sage: import numpy - sage: RDF.coerce(numpy.int8('1')) + sage: import numpy # optional - numpy + sage: RDF.coerce(numpy.int8('1')) # optional - numpy 1.0 - sage: RDF.coerce(numpy.float64('1')) + sage: RDF.coerce(numpy.float64('1')) # optional - numpy 1.0 sage: RDF.coerce(pi) @@ -793,20 +793,20 @@ cdef class RealDoubleElement(FieldElement): EXAMPLES:: - sage: a = RDF(pi) - sage: a.ulp() + sage: a = RDF(pi) # optional - sage.symbolic + sage: a.ulp() # optional - sage.symbolic 4.440892098500626e-16 - sage: b = a + a.ulp() + sage: b = a + a.ulp() # optional - sage.symbolic Adding or subtracting an ulp always gives a different number:: - sage: a + a.ulp() == a + sage: a + a.ulp() == a # optional - sage.symbolic False - sage: a - a.ulp() == a + sage: a - a.ulp() == a # optional - sage.symbolic False - sage: b + b.ulp() == b + sage: b + b.ulp() == b # optional - sage.symbolic False - sage: b - b.ulp() == b + sage: b - b.ulp() == b # optional - sage.symbolic False Since the default rounding mode is round-to-nearest, adding or @@ -815,13 +815,13 @@ cdef class RealDoubleElement(FieldElement): can only happen if the input number is (up to sign) exactly a power of 2:: - sage: a - a.ulp()/3 == a + sage: a - a.ulp()/3 == a # optional - sage.symbolic True - sage: a + a.ulp()/3 == a + sage: a + a.ulp()/3 == a # optional - sage.symbolic True - sage: b - b.ulp()/3 == b + sage: b - b.ulp()/3 == b # optional - sage.symbolic True - sage: b + b.ulp()/3 == b + sage: b + b.ulp()/3 == b # optional - sage.symbolic True sage: c = RDF(1) sage: c - c.ulp()/3 == c @@ -980,11 +980,11 @@ cdef class RealDoubleElement(FieldElement): EXAMPLES:: - sage: s1 = RDF(sin(1)); s1 + sage: s1 = RDF(sin(1)); s1 # optional - sage.symbolic 0.8414709848078965 - sage: s1._interface_init_() + sage: s1._interface_init_() # optional - sage.symbolic '0.8414709848078965' - sage: s1 == RDF(gp(s1)) + sage: s1 == RDF(gp(s1)) # optional - sage.libs.pari sage.symbolic True """ return repr(self._value) @@ -1009,7 +1009,7 @@ cdef class RealDoubleElement(FieldElement): EXAMPLES:: - sage: sage_input(RDF(NaN)) + sage: sage_input(RDF(NaN)) # optional - sage.symbolic RDF(NaN) sage: sage_input(RDF(-infinity), verify=True) # Verified @@ -1268,12 +1268,12 @@ cdef class RealDoubleElement(FieldElement): EXAMPLES:: - sage: a = RDF(exp(1.0)); a + sage: a = RDF(exp(1.0)); a # optional - sage.symbolic 2.718281828459045 - sage: sign,mantissa,exponent = RDF(exp(1.0)).sign_mantissa_exponent() - sage: sign,mantissa,exponent + sage: sign,mantissa,exponent = RDF(exp(1.0)).sign_mantissa_exponent() # optional - sage.symbolic + sage: sign,mantissa,exponent # optional - sage.symbolic (1, 6121026514868073, -51) - sage: sign*mantissa*(2**exponent) == a + sage: sign*mantissa*(2**exponent) == a # optional - sage.symbolic True The mantissa is always a nonnegative number:: @@ -1687,7 +1687,7 @@ cdef class RealDoubleElement(FieldElement): EXAMPLES:: - sage: RDF(1.5).__pari__() + sage: RDF(1.5).__pari__() # optional - sage.libs.pari 1.50000000000000 """ global new_gen_from_real_double_element @@ -1897,7 +1897,7 @@ cdef class RealDoubleElement(FieldElement): def is_integer(self): """ - Return True if this number is a integer + Return ``True`` if this number is a integer EXAMPLES:: @@ -1975,7 +1975,7 @@ cdef class RealDoubleElement(FieldElement): sage: r = sqrt(RDF(2)); r 1.4142135623730951 - sage: r.algebraic_dependency(5) + sage: r.algebraic_dependency(5) # optional - sage.libs.pari x^2 - 2 """ return sage.arith.all.algdep(self,n) diff --git a/src/sage/rings/real_interval_absolute.pyx b/src/sage/rings/real_interval_absolute.pyx index fb505b5205b..3d630e2f2f9 100644 --- a/src/sage/rings/real_interval_absolute.pyx +++ b/src/sage/rings/real_interval_absolute.pyx @@ -1,3 +1,4 @@ +# sage.doctest: # optional - sage.symbolic """ Real intervals with a fixed absolute precision """ diff --git a/src/sage/rings/real_mpfi.pyx b/src/sage/rings/real_mpfi.pyx index 33e94b93094..1904bbff3e7 100644 --- a/src/sage/rings/real_mpfi.pyx +++ b/src/sage/rings/real_mpfi.pyx @@ -230,10 +230,10 @@ specified if given a non-interval and an interval:: TESTS:: - sage: import numpy - sage: RIF(2) == numpy.int8('2') + sage: import numpy # optional - numpy + sage: RIF(2) == numpy.int8('2') # optional - numpy True - sage: numpy.int8('2') == RIF(2) + sage: numpy.int8('2') == RIF(2) # optional - numpy True sage: RIF(0,1) < float('2') Traceback (most recent call last): diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index 18d1345ec81..61569a41ff2 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -1438,12 +1438,12 @@ cdef class RealNumber(sage.structure.element.RingElement): EXAMPLES:: - sage: import numpy - sage: numpy.arange(10.0) + sage: import numpy # optional - numpy + sage: numpy.arange(10.0) # optional - numpy array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]) - sage: numpy.array([1.0, 1.1, 1.2]).dtype + sage: numpy.array([1.0, 1.1, 1.2]).dtype # optional - numpy dtype('float64') - sage: numpy.array([1.000000000000000000000000000000000000]).dtype + sage: numpy.array([1.000000000000000000000000000000000000]).dtype # optional - numpy dtype('O') """ if (self._parent).__prec <= 53: diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index e806637c38a..9b3504aa4e0 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -165,13 +165,13 @@ cdef class Ring(ParentWithGens): sage: QQ.is_finite() False - sage: GF(2^10,'a').is_finite() + sage: GF(2^10, 'a').is_finite() # optional - sage.rings.finite_rings True - sage: R. = GF(7)[] - sage: R.is_finite() + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: R.is_finite() # optional - sage.rings.finite_rings False - sage: S. = R.quo(x^2+1) - sage: S.is_finite() + sage: S. = R.quo(x^2 + 1) # optional - sage.rings.finite_rings + sage: S.is_finite() # optional - sage.rings.finite_rings True sage: Integers(7).cardinality() @@ -255,11 +255,11 @@ cdef class Ring(ParentWithGens): """ EXAMPLES:: - sage: QQ.base_extend(GF(7)) + sage: QQ.base_extend(GF(7)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no base extension defined - sage: ZZ.base_extend(GF(7)) + sage: ZZ.base_extend(GF(7)) # optional - sage.rings.finite_rings Finite Field of size 7 """ if R.has_coerce_map_from(self): @@ -280,7 +280,7 @@ cdef class Ring(ParentWithGens): EXAMPLES:: - sage: FreeAlgebra(QQ, 3, 'x').category() # todo: use a ring which is not an algebra! + sage: FreeAlgebra(QQ, 3, 'x').category() # todo: use a ring which is not an algebra! # optional - sage.combinat sage.modules Category of algebras with basis over Rational Field Since a quotient of the integers is its own base ring, and during @@ -310,16 +310,19 @@ cdef class Ring(ParentWithGens): EXAMPLES:: - sage: F. = FreeAlgebra(ZZ, 3) - sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F - sage: Q = F.quotient(I) - sage: Q.ideal_monoid() - Monoid of ideals of Quotient of Free Algebra on 3 generators (x, y, z) over Integer Ring by the ideal (x*y + y*z, x^2 + x*y - y*x - y^2) - sage: F. = FreeAlgebra(ZZ, implementation='letterplace') - sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F - sage: Q = F.quo(I) - sage: Q.ideal_monoid() - Monoid of ideals of Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) over Integer Ring by the ideal (x*y + y*z, x*x + x*y - y*x - y*y) + sage: F. = FreeAlgebra(ZZ, 3) # optional - sage.combinat sage.modules + sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F # optional - sage.combinat sage.modules + sage: Q = F.quotient(I) # optional - sage.combinat sage.modules + sage: Q.ideal_monoid() # optional - sage.combinat sage.modules + Monoid of ideals of Quotient of Free Algebra on 3 generators (x, y, z) + over Integer Ring by the ideal (x*y + y*z, x^2 + x*y - y*x - y^2) + sage: F. = FreeAlgebra(ZZ, implementation='letterplace') # optional - sage.combinat sage.modules + sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F # optional - sage.combinat sage.modules + sage: Q = F.quo(I) # optional - sage.combinat sage.modules + sage: Q.ideal_monoid() # optional - sage.combinat sage.modules + Monoid of ideals of Quotient of Free Associative Unital Algebra + on 3 generators (x, y, z) over Integer Ring + by the ideal (x*y + y*z, x*x + x*y - y*x - y*y) """ if self.__ideal_monoid is not None: @@ -363,10 +366,10 @@ cdef class Ring(ParentWithGens): Here is an example over a non-commutative ring:: - sage: A = SteenrodAlgebra(2) - sage: A.ideal(A.1,A.2^2) + sage: A = SteenrodAlgebra(2) # optional - sage.combinat sage.modules + sage: A.ideal(A.1, A.2^2) # optional - sage.combinat sage.modules Twosided Ideal (Sq(2), Sq(2,2)) of mod 2 Steenrod algebra, milnor basis - sage: A.ideal(A.1,A.2^2,side='left') + sage: A.ideal(A.1, A.2^2, side='left') # optional - sage.combinat sage.modules Left Ideal (Sq(2), Sq(2,2)) of mod 2 Steenrod algebra, milnor basis TESTS: @@ -445,20 +448,22 @@ cdef class Ring(ParentWithGens): EXAMPLES:: - sage: R. = GF(7)[] - sage: (x+y)*R - Ideal (x + y) of Multivariate Polynomial Ring in x, y, z over Finite Field of size 7 - sage: (x+y,z+y^3)*R - Ideal (x + y, y^3 + z) of Multivariate Polynomial Ring in x, y, z over Finite Field of size 7 + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: (x + y) * R # optional - sage.rings.finite_rings + Ideal (x + y) of Multivariate Polynomial Ring in x, y, z + over Finite Field of size 7 + sage: (x + y, z + y^3) * R # optional - sage.rings.finite_rings + Ideal (x + y, y^3 + z) of Multivariate Polynomial Ring in x, y, z + over Finite Field of size 7 The following was implemented in :trac:`7797`:: - sage: A = SteenrodAlgebra(2) - sage: A*[A.1+A.2,A.1^2] + sage: A = SteenrodAlgebra(2) # optional - sage.combinat sage.modules + sage: A * [A.1 + A.2, A.1^2] # optional - sage.combinat sage.modules Left Ideal (Sq(2) + Sq(4), Sq(1,1)) of mod 2 Steenrod algebra, milnor basis - sage: [A.1+A.2,A.1^2]*A + sage: [A.1 + A.2, A.1^2] * A # optional - sage.combinat sage.modules Right Ideal (Sq(2) + Sq(4), Sq(1,1)) of mod 2 Steenrod algebra, milnor basis - sage: A*[A.1+A.2,A.1^2]*A + sage: A * [A.1 + A.2, A.1^2] * A # optional - sage.combinat sage.modules Twosided Ideal (Sq(2) + Sq(4), Sq(1,1)) of mod 2 Steenrod algebra, milnor basis """ @@ -516,18 +521,18 @@ cdef class Ring(ParentWithGens): sage: RR._ideal_class_() - sage: R. = GF(5)[] - sage: R._ideal_class_(1) + sage: R. = GF(5)[] # optional - sage.rings.finite_rings + sage: R._ideal_class_(1) # optional - sage.rings.finite_rings - sage: S = R.quo(x^3-y^2) - sage: S._ideal_class_(1) + sage: S = R.quo(x^3 - y^2) # optional - sage.rings.finite_rings + sage: S._ideal_class_(1) # optional - sage.rings.finite_rings - sage: S._ideal_class_(2) + sage: S._ideal_class_(2) # optional - sage.rings.finite_rings - sage: T. = S[] - sage: T._ideal_class_(5) + sage: T. = S[] # optional - sage.rings.finite_rings + sage: T._ideal_class_(5) # optional - sage.rings.finite_rings - sage: T._ideal_class_(1) + sage: T._ideal_class_(1) # optional - sage.rings.finite_rings Since :trac:`7797`, non-commutative rings have ideals as well:: @@ -571,7 +576,7 @@ cdef class Ring(ParentWithGens): EXAMPLES:: - sage: Zp(7).unit_ideal() + sage: Zp(7).unit_ideal() # optional - sage.rings.padics Principal ideal (1 + O(7^20)) of 7-adic Ring with capped relative precision 20 """ if self._unit_ideal is None: @@ -602,10 +607,10 @@ cdef class Ring(ParentWithGens): Make sure that :trac:`13644` is fixed:: - sage: K = Qp(3) - sage: R. = K[] - sage: L. = K.extension(a^2-3) - sage: L.ideal(a) + sage: K = Qp(3) # optional - sage.rings.padics + sage: R. = K[] # optional - sage.rings.padics + sage: L. = K.extension(a^2-3) # optional - sage.rings.padics + sage: L.ideal(a) # optional - sage.rings.padics Principal ideal (1 + O(a^40)) of 3-adic Eisenstein Extension Field in a defined by a^2 - 3 """ @@ -673,8 +678,8 @@ cdef class Ring(ParentWithGens): True sage: QQ['x,y,z'].is_commutative() True - sage: Q. = QuaternionAlgebra(QQ, -1,-1) - sage: Q.is_commutative() + sage: Q. = QuaternionAlgebra(QQ, -1, -1) # optional - sage.combinat sage.modules + sage: Q.is_commutative() # optional - sage.combinat sage.modules False """ if self.is_zero(): @@ -701,7 +706,7 @@ cdef class Ring(ParentWithGens): sage: QQ.is_field() True - sage: GF(9,'a').is_field() + sage: GF(9, 'a').is_field() # optional - sage.rings.finite_rings True sage: ZZ.is_field() False @@ -713,12 +718,12 @@ cdef class Ring(ParentWithGens): This illustrates the use of the ``proof`` parameter:: sage: R. = QQ[] - sage: S. = R.quo((b^3)) - sage: S.is_field(proof = True) + sage: S. = R.quo((b^3)) # optional - sage.libs.singular + sage: S.is_field(proof=True) # optional - sage.libs.singular Traceback (most recent call last): ... NotImplementedError - sage: S.is_field(proof = False) + sage: S.is_field(proof=False) # optional - sage.libs.singular False """ if self.is_zero(): @@ -745,9 +750,9 @@ cdef class Ring(ParentWithGens): True sage: ZZ.is_exact() True - sage: Qp(7).is_exact() + sage: Qp(7).is_exact() # optional - sage.rings.padics False - sage: Zp(7, type='capped-abs').is_exact() + sage: Zp(7, type='capped-abs').is_exact() # optional - sage.rings.padics False """ return True @@ -763,30 +768,30 @@ cdef class Ring(ParentWithGens): sage: ZZ.is_subring(QQ) True - sage: ZZ.is_subring(GF(19)) + sage: ZZ.is_subring(GF(19)) # optional - sage.rings.finite_rings False TESTS:: sage: QQ.is_subring(QQ['x']) True - sage: QQ.is_subring(GF(7)) + sage: QQ.is_subring(GF(7)) # optional - sage.rings.finite_rings False - sage: QQ.is_subring(CyclotomicField(7)) + sage: QQ.is_subring(CyclotomicField(7)) # optional - sage.rings.number_field True sage: QQ.is_subring(ZZ) False Every ring is a subring of itself, :trac:`17287`:: - sage: QQbar.is_subring(QQbar) + sage: QQbar.is_subring(QQbar) # optional - sage.rings.number_field True sage: RR.is_subring(RR) True sage: CC.is_subring(CC) True - sage: K. = NumberField(x^3-x+1/10) - sage: K.is_subring(K) + sage: K. = NumberField(x^3 - x + 1/10) # optional - sage.rings.number_field + sage: K.is_subring(K) # optional - sage.rings.number_field True sage: R. = RR[] sage: R.is_subring(R) @@ -808,15 +813,15 @@ cdef class Ring(ParentWithGens): sage: QQ.is_prime_field() True - sage: GF(3).is_prime_field() + sage: GF(3).is_prime_field() # optional - sage.rings.finite_rings True - sage: GF(9,'a').is_prime_field() + sage: GF(9, 'a').is_prime_field() # optional - sage.rings.finite_rings False sage: ZZ.is_prime_field() False sage: QQ['x'].is_prime_field() False - sage: Qp(19).is_prime_field() + sage: Qp(19).is_prime_field() # optional - sage.rings.padics False """ return False @@ -847,33 +852,32 @@ cdef class Ring(ParentWithGens): True sage: Integers(8).is_integral_domain() False - sage: Zp(7).is_integral_domain() + sage: Zp(7).is_integral_domain() # optional - sage.rings.padics True - sage: Qp(7).is_integral_domain() + sage: Qp(7).is_integral_domain() # optional - sage.rings.padics True sage: R. = QQ[] - sage: S. = R.quo((b^3)) - sage: S.is_integral_domain() + sage: S. = R.quo((b^3)) # optional - sage.libs.singular + sage: S.is_integral_domain() # optional - sage.libs.singular False This illustrates the use of the ``proof`` parameter:: sage: R. = ZZ[] - sage: S. = R.quo((b^3)) - sage: S.is_integral_domain(proof = True) + sage: S. = R.quo((b^3)) # optional - sage.libs.singular + sage: S.is_integral_domain(proof=True) # optional - sage.libs.singular Traceback (most recent call last): ... NotImplementedError - sage: S.is_integral_domain(proof = False) + sage: S.is_integral_domain(proof=False) # optional - sage.libs.singular False TESTS: Make sure :trac:`10481` is fixed:: - sage: var('x') - x - sage: R. = ZZ['x'].quo(x^2) + sage: x = polygen(ZZ, 'x') + sage: R. = ZZ['x'].quo(x^2) # optional - sage.libs.pari sage: R.fraction_field() Traceback (most recent call last): ... @@ -883,11 +887,11 @@ cdef class Ring(ParentWithGens): Forward the proof flag to ``is_field``, see :trac:`22910`:: - sage: R1. = GF(5)[] - sage: F1 = R1.quotient_ring(x^2+x+1) - sage: R2. = F1[] - sage: F2 = R2.quotient_ring(x^2+x+1) - sage: F2.is_integral_domain(False) + sage: R1. = GF(5)[] # optional - sage.rings.finite_rings + sage: F1 = R1.quotient_ring(x^2 + x + 1) # optional - sage.rings.finite_rings + sage: R2. = F1[] # optional - sage.rings.finite_rings + sage: F2 = R2.quotient_ring(x^2 + x + 1) # optional - sage.rings.finite_rings + sage: F2.is_integral_domain(False) # optional - sage.rings.finite_rings False """ if self.is_field(proof): @@ -920,7 +924,7 @@ cdef class Ring(ParentWithGens): EXAMPLES:: - sage: GF(19).order() + sage: GF(19).order() # optional - sage.rings.finite_rings 19 sage: QQ.order() +Infinity @@ -952,29 +956,29 @@ cdef class Ring(ParentWithGens): -1 sage: QQ.zeta(1) 1 - sage: CyclotomicField(6).zeta(6) + sage: CyclotomicField(6).zeta(6) # optional - sage.rings.number_field zeta6 - sage: CyclotomicField(3).zeta(3) + sage: CyclotomicField(3).zeta(3) # optional - sage.rings.number_field zeta3 - sage: CyclotomicField(3).zeta(3).multiplicative_order() + sage: CyclotomicField(3).zeta(3).multiplicative_order() # optional - sage.rings.number_field 3 - sage: a = GF(7).zeta(); a + sage: a = GF(7).zeta(); a # optional - sage.rings.finite_rings 3 - sage: a.multiplicative_order() + sage: a.multiplicative_order() # optional - sage.rings.finite_rings 6 - sage: a = GF(49,'z').zeta(); a + sage: a = GF(49,'z').zeta(); a # optional - sage.rings.finite_rings z - sage: a.multiplicative_order() + sage: a.multiplicative_order() # optional - sage.rings.finite_rings 48 - sage: a = GF(49,'z').zeta(2); a + sage: a = GF(49,'z').zeta(2); a # optional - sage.rings.finite_rings 6 - sage: a.multiplicative_order() + sage: a.multiplicative_order() # optional - sage.rings.finite_rings 2 sage: QQ.zeta(3) Traceback (most recent call last): ... ValueError: no n-th root of unity in rational field - sage: Zp(7, prec=8).zeta() + sage: Zp(7, prec=8).zeta() # optional - sage.rings.padics 3 + 4*7 + 6*7^2 + 3*7^3 + 2*7^5 + 6*7^6 + 2*7^7 + O(7^8) TESTS:: @@ -984,7 +988,7 @@ cdef class Ring(ParentWithGens): 1 sage: Ring.zeta(QQ, 2) -1 - sage: Ring.zeta(QQ, 3) + sage: Ring.zeta(QQ, 3) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no 3rd root of unity in Rational Field @@ -1021,13 +1025,13 @@ cdef class Ring(ParentWithGens): EXAMPLES:: - sage: CyclotomicField(19).zeta_order() + sage: CyclotomicField(19).zeta_order() # optional - sage.rings.number_field 38 - sage: GF(19).zeta_order() + sage: GF(19).zeta_order() # optional - sage.rings.finite_rings 18 - sage: GF(5^3,'a').zeta_order() + sage: GF(5^3,'a').zeta_order() # optional - sage.rings.finite_rings 124 - sage: Zp(7, prec=8).zeta_order() + sage: Zp(7, prec=8).zeta_order() # optional - sage.rings.padics 6 """ return self.zeta().multiplicative_order() @@ -1137,7 +1141,7 @@ cdef class Ring(ParentWithGens): For the symbolic ring, there is no reasonable answer:: - sage: SR.epsilon() + sage: SR.epsilon() # optional - sage.symbolics Traceback (most recent call last): ... NotImplementedError @@ -1195,10 +1199,11 @@ cdef class CommutativeRing(Ring): EXAMPLES:: - sage: R. = GF(3)[] - sage: R.localization((x*y, x**2+y**2)) - Multivariate Polynomial Ring in x, y over Finite Field of size 3 localized at (y, x, x^2 + y^2) - sage: ~y in _ + sage: R. = GF(3)[] # optional - sage.rings.finite_rings + sage: R.localization((x*y, x**2 + y**2)) # optional - sage.rings.finite_rings + Multivariate Polynomial Ring in x, y over Finite Field of size 3 + localized at (y, x, x^2 + y^2) + sage: ~y in _ # optional - sage.rings.finite_rings True """ if not self.is_integral_domain(): @@ -1272,11 +1277,11 @@ cdef class CommutativeRing(Ring): sage: QQ.is_commutative() True - sage: ZpCA(7).is_commutative() + sage: ZpCA(7).is_commutative() # optional - sage.rings.padics True - sage: A = QuaternionAlgebra(QQ, -1, -3, names=('i','j','k')); A + sage: A = QuaternionAlgebra(QQ, -1, -3, names=('i','j','k')); A # optional - sage.combinat sage.modules Quaternion Algebra (-1, -3) with base ring Rational Field - sage: A.is_commutative() + sage: A.is_commutative() # optional - sage.combinat sage.modules False """ return True @@ -1312,16 +1317,18 @@ cdef class CommutativeRing(Ring): All orders in number fields have Krull dimension 1, including non-maximal orders:: - sage: K. = QuadraticField(-1) - sage: R = K.maximal_order(); R - Gaussian Integers in Number Field in i with defining polynomial x^2 + 1 with i = 1*I - sage: R.krull_dimension() + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: R = K.maximal_order(); R # optional - sage.rings.number_field + Gaussian Integers in Number Field in i + with defining polynomial x^2 + 1 with i = 1*I + sage: R.krull_dimension() # optional - sage.rings.number_field 1 - sage: R = K.order(2*i); R - Order in Number Field in i with defining polynomial x^2 + 1 with i = 1*I - sage: R.is_maximal() + sage: R = K.order(2*i); R # optional - sage.rings.number_field + Order in Number Field in i + with defining polynomial x^2 + 1 with i = 1*I + sage: R.is_maximal() # optional - sage.rings.number_field False - sage: R.krull_dimension() + sage: R.krull_dimension() # optional - sage.rings.number_field 1 """ raise NotImplementedError @@ -1366,16 +1373,18 @@ cdef class CommutativeRing(Ring): sage: R = QQ['x'] sage: y = polygen(R) - sage: R.extension(y^2 - 5, 'a') - Univariate Quotient Polynomial Ring in a over Univariate Polynomial Ring in x over Rational Field with modulus a^2 - 5 + sage: R.extension(y^2 - 5, 'a') # optional - sage.libs.pari + Univariate Quotient Polynomial Ring in a over + Univariate Polynomial Ring in x over Rational Field with modulus a^2 - 5 :: - sage: P. = PolynomialRing(GF(5)) - sage: F. = GF(5).extension(x^2 - 2) - sage: P. = F[] - sage: R. = F.extension(t^2 - a); R - Univariate Quotient Polynomial Ring in b over Finite Field in a of size 5^2 with modulus b^2 + 4*a + sage: P. = PolynomialRing(GF(5)) # optional - sage.rings.finite_rings + sage: F. = GF(5).extension(x^2 - 2) # optional - sage.rings.finite_rings + sage: P. = F[] # optional - sage.rings.finite_rings + sage: R. = F.extension(t^2 - a); R # optional - sage.rings.finite_rings + Univariate Quotient Polynomial Ring in b over + Finite Field in a of size 5^2 with modulus b^2 + 4*a """ from sage.rings.polynomial.polynomial_element import Polynomial if not isinstance(poly, Polynomial): @@ -1411,17 +1420,19 @@ cdef class CommutativeRing(Ring): EXAMPLES:: - sage: K. = PowerSeriesRing(GF(5)) - sage: Frob = K.frobenius_endomorphism(); Frob - Frobenius endomorphism x |--> x^5 of Power Series Ring in u over Finite Field of size 5 - sage: Frob(u) + sage: K. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings + sage: Frob = K.frobenius_endomorphism(); Frob # optional - sage.rings.finite_rings + Frobenius endomorphism x |--> x^5 of Power Series Ring in u + over Finite Field of size 5 + sage: Frob(u) # optional - sage.rings.finite_rings u^5 We can specify a power:: - sage: f = K.frobenius_endomorphism(2); f - Frobenius endomorphism x |--> x^(5^2) of Power Series Ring in u over Finite Field of size 5 - sage: f(1+u) + sage: f = K.frobenius_endomorphism(2); f # optional - sage.rings.finite_rings + Frobenius endomorphism x |--> x^(5^2) of Power Series Ring in u + over Finite Field of size 5 + sage: f(1+u) # optional - sage.rings.finite_rings 1 + u^25 """ from .morphism import FrobeniusEndomorphism_generic @@ -1456,18 +1467,21 @@ cdef class CommutativeRing(Ring): EXAMPLES:: sage: R. = QQ[] - sage: M = R.derivation_module(); M - Module of derivations over Multivariate Polynomial Ring in x, y, z over Rational Field - sage: M.gens() + sage: M = R.derivation_module(); M # optional - sage.modules + Module of derivations over + Multivariate Polynomial Ring in x, y, z over Rational Field + sage: M.gens() # optional - sage.modules (d/dx, d/dy, d/dz) We can specify a different codomain:: sage: K = R.fraction_field() - sage: M = R.derivation_module(K); M - Module of derivations from Multivariate Polynomial Ring in x, y, z over - Rational Field to Fraction Field of Multivariate Polynomial Ring in x, y, z over Rational Field - sage: M.gen() / x + sage: M = R.derivation_module(K); M # optional - sage.modules + Module of derivations + from Multivariate Polynomial Ring in x, y, z over Rational Field + to Fraction Field of + Multivariate Polynomial Ring in x, y, z over Rational Field + sage: M.gen() / x # optional - sage.modules 1/x*d/dx Here is an example with a non-canonical defining morphism:: @@ -1480,30 +1494,32 @@ cdef class CommutativeRing(Ring): Defn: x |--> 0 y |--> 1 z |--> 2 - sage: M = R.derivation_module(ev) - sage: M - Module of derivations from Multivariate Polynomial Ring in x, y, z over Rational Field to Rational Field + sage: M = R.derivation_module(ev) # optional - sage.modules + sage: M # optional - sage.modules + Module of derivations + from Multivariate Polynomial Ring in x, y, z over Rational Field + to Rational Field Elements in `M` acts as derivations at `(0,1,2)`:: - sage: Dx = M.gen(0); Dx + sage: Dx = M.gen(0); Dx # optional - sage.modules d/dx - sage: Dy = M.gen(1); Dy + sage: Dy = M.gen(1); Dy # optional - sage.modules d/dy - sage: Dz = M.gen(2); Dz + sage: Dz = M.gen(2); Dz # optional - sage.modules d/dz sage: f = x^2 + y^2 + z^2 - sage: Dx(f) # = 2*x evaluated at (0,1,2) + sage: Dx(f) # = 2*x evaluated at (0,1,2) # optional - sage.modules 0 - sage: Dy(f) # = 2*y evaluated at (0,1,2) + sage: Dy(f) # = 2*y evaluated at (0,1,2) # optional - sage.modules 2 - sage: Dz(f) # = 2*z evaluated at (0,1,2) + sage: Dz(f) # = 2*z evaluated at (0,1,2) # optional - sage.modules 4 An example with a twisting homomorphism:: sage: theta = R.hom([x^2, y^2, z^2]) - sage: M = R.derivation_module(twist=theta); M + sage: M = R.derivation_module(twist=theta); M # optional - sage.modules Module of twisted derivations over Multivariate Polynomial Ring in x, y, z over Rational Field (twisting morphism: x |--> x^2, y |--> y^2, z |--> z^2) @@ -1542,23 +1558,23 @@ cdef class CommutativeRing(Ring): EXAMPLES:: sage: R. = QQ[] - sage: R.derivation() + sage: R.derivation() # optional - sage.modules d/dx In that case, ``arg`` could be a generator:: - sage: R.derivation(y) + sage: R.derivation(y) # optional - sage.modules d/dy or a list of coefficients:: - sage: R.derivation([1,2,3]) + sage: R.derivation([1,2,3]) # optional - sage.modules d/dx + 2*d/dy + 3*d/dz It is not possible to define derivations with respect to a polynomial which is not a variable:: - sage: R.derivation(x^2) + sage: R.derivation(x^2) # optional - sage.modules Traceback (most recent call last): ... ValueError: unable to create the derivation @@ -1567,18 +1583,18 @@ cdef class CommutativeRing(Ring): sage: R. = QQ[] sage: theta = R.hom([x^2, y^2, z^2]) - sage: f = R.derivation(twist=theta); f + sage: f = R.derivation(twist=theta); f # optional - sage.modules 0 - sage: f.parent() + sage: f.parent() # optional - sage.modules Module of twisted derivations over Multivariate Polynomial Ring in x, y, z over Rational Field (twisting morphism: x |--> x^2, y |--> y^2, z |--> z^2) Specifying a scalar, the returned twisted derivation is the corresponding multiple of `\theta - id`:: - sage: R.derivation(1, twist=theta) + sage: R.derivation(1, twist=theta) # optional - sage.modules [x |--> x^2, y |--> y^2, z |--> z^2] - id - sage: R.derivation(x, twist=theta) + sage: R.derivation(x, twist=theta) # optional - sage.modules x*([x |--> x^2, y |--> y^2, z |--> z^2] - id) """ @@ -1696,9 +1712,9 @@ cdef class IntegralDomain(CommutativeRing): True sage: QQ.is_integrally_closed() True - sage: QQbar.is_integrally_closed() + sage: QQbar.is_integrally_closed() # optional - sage.rings.number_field True - sage: GF(5).is_integrally_closed() + sage: GF(5).is_integrally_closed() # optional - sage.rings.finite_rings True sage: Z5 = Integers(5); Z5 Ring of integers modulo 5 @@ -1715,7 +1731,7 @@ cdef class IntegralDomain(CommutativeRing): EXAMPLES:: - sage: GF(7).is_field() + sage: GF(7).is_field() # optional - sage.rings.finite_rings True The following examples have their own ``is_field`` implementations:: @@ -1785,9 +1801,9 @@ cdef class DedekindDomain(IntegralDomain): sage: ZZ.krull_dimension() 1 - sage: K = NumberField(x^2 + 1, 's') - sage: OK = K.ring_of_integers() - sage: OK.krull_dimension() + sage: K = NumberField(x^2 + 1, 's') # optional - sage.rings.number_field + sage: OK = K.ring_of_integers() # optional - sage.rings.number_field + sage: OK.krull_dimension() # optional - sage.rings.number_field 1 The following are not Dedekind domains but have @@ -1804,12 +1820,13 @@ cdef class DedekindDomain(IntegralDomain): sage: U.krull_dimension() 4 - sage: K. = QuadraticField(-1) - sage: R = K.order(2*i); R - Order in Number Field in i with defining polynomial x^2 + 1 with i = 1*I - sage: R.is_maximal() + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: R = K.order(2*i); R # optional - sage.rings.number_field + Order in Number Field in i + with defining polynomial x^2 + 1 with i = 1*I + sage: R.is_maximal() # optional - sage.rings.number_field False - sage: R.krull_dimension() + sage: R.krull_dimension() # optional - sage.rings.number_field 1 """ return 1 @@ -1828,18 +1845,18 @@ cdef class DedekindDomain(IntegralDomain): sage: ZZ.is_integrally_closed() True - sage: K = NumberField(x^2 + 1, 's') - sage: OK = K.ring_of_integers() - sage: OK.is_integrally_closed() + sage: K = NumberField(x^2 + 1, 's') # optional - sage.rings.number_field + sage: OK = K.ring_of_integers() # optional - sage.rings.number_field + sage: OK.is_integrally_closed() # optional - sage.rings.number_field True These, however, are not Dedekind domains:: sage: QQ.is_integrally_closed() True - sage: S = ZZ[sqrt(5)]; S.is_integrally_closed() + sage: S = ZZ[sqrt(5)]; S.is_integrally_closed() # optional - sage.rings.number_field sage.symbolic False - sage: T. = PolynomialRing(QQ,2); T + sage: T. = PolynomialRing(QQ, 2); T Multivariate Polynomial Ring in x, y over Rational Field sage: T.is_integral_domain() True @@ -1852,11 +1869,12 @@ cdef class DedekindDomain(IntegralDomain): EXAMPLES:: - sage: K = NumberField(x^2 + 1, 's') - sage: OK = K.ring_of_integers() - sage: OK.integral_closure() - Gaussian Integers in Number Field in s with defining polynomial x^2 + 1 - sage: OK.integral_closure() == OK + sage: K = NumberField(x^2 + 1, 's') # optional - sage.rings.number_field + sage: OK = K.ring_of_integers() # optional - sage.rings.number_field + sage: OK.integral_closure() # optional - sage.rings.number_field + Gaussian Integers in Number Field in s + with defining polynomial x^2 + 1 + sage: OK.integral_closure() == OK # optional - sage.rings.number_field True sage: QQ.integral_closure() == QQ @@ -1875,9 +1893,9 @@ cdef class DedekindDomain(IntegralDomain): sage: ZZ.is_noetherian() True - sage: K = NumberField(x^2 + 1, 's') - sage: OK = K.ring_of_integers() - sage: OK.is_noetherian() + sage: K = NumberField(x^2 + 1, 's') # optional - sage.rings.number_field + sage: OK = K.ring_of_integers() # optional - sage.rings.number_field + sage: OK.is_noetherian() # optional - sage.rings.number_field True sage: QQ.is_noetherian() True @@ -1901,7 +1919,7 @@ cdef class PrincipalIdealDomain(IntegralDomain): EXAMPLES:: - sage: Zp(5).is_noetherian() + sage: Zp(5).is_noetherian() # optional - sage.rings.padics True """ return True @@ -1912,7 +1930,7 @@ cdef class PrincipalIdealDomain(IntegralDomain): EXAMPLES:: - sage: QQ.class_group() + sage: QQ.class_group() # optional - sage.groups Trivial Abelian group """ from sage.groups.abelian_gps.abelian_group import AbelianGroup @@ -1958,22 +1976,22 @@ cdef class PrincipalIdealDomain(IntegralDomain): coercible:: sage: R. = PolynomialRing(QQ) - sage: S. = NumberField(x^2 - 2, 'a') - sage: f = (x - a)*(x + a); g = (x - a)*(x^2 - 2) - sage: print(f); print(g) + sage: S. = NumberField(x^2 - 2, 'a') # optional - sage.rings.number_field + sage: f = (x - a)*(x + a); g = (x - a)*(x^2 - 2) # optional - sage.rings.number_field + sage: print(f); print(g) # optional - sage.rings.number_field x^2 - 2 x^3 - a*x^2 - 2*x + 2*a - sage: f in R + sage: f in R # optional - sage.rings.number_field True - sage: g in R + sage: g in R # optional - sage.rings.number_field False - sage: R.gcd(f,g) + sage: R.gcd(f, g) # optional - sage.rings.number_field Traceback (most recent call last): ... TypeError: Unable to coerce 2*a to a rational - sage: R.base_extend(S).gcd(f,g) + sage: R.base_extend(S).gcd(f,g) # optional - sage.rings.number_field x^2 - 2 - sage: R.base_extend(S).gcd(f, (x - a)*(x^2 - 3)) + sage: R.base_extend(S).gcd(f, (x - a)*(x^2 - 3)) # optional - sage.rings.number_field x - a """ if coerce: @@ -2066,7 +2084,7 @@ cpdef bint _is_Field(x) except -2: True sage: _is_Field(ZZ) False - sage: _is_Field(pAdicField(2)) + sage: _is_Field(pAdicField(2)) # optional - sage.rings.padics True sage: _is_Field(5) False @@ -2113,8 +2131,8 @@ cdef class Field(PrincipalIdealDomain): sage: CC.fraction_field() Complex Field with 53 bits of precision - sage: F = NumberField(x^2 + 1, 'i') - sage: F.fraction_field() + sage: F = NumberField(x^2 + 1, 'i') # optional - sage.rings.number_field + sage: F.fraction_field() # optional - sage.rings.number_field Number Field in i with defining polynomial x^2 + 1 """ return self @@ -2127,10 +2145,10 @@ cdef class Field(PrincipalIdealDomain): sage: QQ._pseudo_fraction_field() Rational Field - sage: K = GF(5) - sage: K._pseudo_fraction_field() + sage: K = GF(5) # optional - sage.rings.finite_rings + sage: K._pseudo_fraction_field() # optional - sage.rings.finite_rings Finite Field of size 5 - sage: K._pseudo_fraction_field() is K + sage: K._pseudo_fraction_field() is K # optional - sage.rings.finite_rings True """ return self @@ -2242,8 +2260,8 @@ cdef class Field(PrincipalIdealDomain): EXAMPLES:: - sage: k = GF(9, 'a') - sage: k.prime_subfield() + sage: k = GF(9, 'a') # optional - sage.rings.finite_rings + sage: k.prime_subfield() # optional - sage.rings.finite_rings Finite Field of size 3 """ if self.characteristic() == 0: @@ -2283,7 +2301,7 @@ cdef class Algebra(Ring): EXAMPLES:: - sage: A = Algebra(ZZ); A + sage: A = Algebra(ZZ); A # optional - sage.modules """ # This is a low-level class. For performance, we trust that the category @@ -2303,12 +2321,12 @@ cdef class Algebra(Ring): EXAMPLES:: - sage: A = Algebra(ZZ); A + sage: A = Algebra(ZZ); A # optional - sage.modules - sage: A.characteristic() + sage: A.characteristic() # optional - sage.modules 0 - sage: A = Algebra(GF(7^3, 'a')) - sage: A.characteristic() + sage: A = Algebra(GF(7^3, 'a')) # optional - sage.rings.finite_rings sage.modules + sage: A.characteristic() # optional - sage.rings.finite_rings sage.modules 7 """ return self.base_ring().characteristic() @@ -2323,16 +2341,16 @@ cdef class Algebra(Ring): EXAMPLES:: - sage: B = QuaternionAlgebra(2) - sage: B.has_standard_involution() + sage: B = QuaternionAlgebra(2) # optional - sage.combinat sage.modules + sage: B.has_standard_involution() # optional - sage.combinat sage.modules True sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x**2 - 2) - sage: A = QuaternionAlgebra(K,-2,5) - sage: A.has_standard_involution() + sage: K. = NumberField(x**2 - 2) # optional - sage.rings.number_field + sage: A = QuaternionAlgebra(K, -2, 5) # optional - sage.rings.number_field sage.combinat sage.modules + sage: A.has_standard_involution() # optional - sage.rings.number_field sage.combinat sage.modules True - sage: L. = FreeAlgebra(QQ,2) - sage: L.has_standard_involution() + sage: L. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules + sage: L.has_standard_involution() # optional - sage.combinat sage.modules Traceback (most recent call last): ... NotImplementedError: has_standard_involution is not implemented for this algebra @@ -2386,7 +2404,7 @@ cdef class CommutativeAlgebra(CommutativeRing): sage: sage.rings.ring.CommutativeAlgebra(QQ) - sage: sage.rings.ring.CommutativeAlgebra(QuaternionAlgebra(QQ,-1,-1)) + sage: sage.rings.ring.CommutativeAlgebra(QuaternionAlgebra(QQ, -1, -1)) # optional - sage.combinat sage.modules Traceback (most recent call last): ... TypeError: base ring must be a commutative ring @@ -2433,8 +2451,8 @@ def is_Ring(x): sage: from sage.rings.ring import is_Ring sage: is_Ring(ZZ) True - sage: MS = MatrixSpace(QQ,2) - sage: is_Ring(MS) + sage: MS = MatrixSpace(QQ, 2) # optional - sage.modules + sage: is_Ring(MS) # optional - sage.modules True """ return x in _Rings diff --git a/src/sage/rings/semirings/non_negative_integer_semiring.py b/src/sage/rings/semirings/non_negative_integer_semiring.py index ea3bce495d9..c041f18f99f 100644 --- a/src/sage/rings/semirings/non_negative_integer_semiring.py +++ b/src/sage/rings/semirings/non_negative_integer_semiring.py @@ -37,15 +37,15 @@ class NonNegativeIntegerSemiring(NonNegativeIntegers): Here is a piece of the Cayley graph for the multiplicative structure:: - sage: G = NN.cayley_graph(elements=range(9), generators=[0,1,2,3,5,7]) - sage: G + sage: G = NN.cayley_graph(elements=range(9), generators=[0,1,2,3,5,7]) # optional - sage.graphs + sage: G # optional - sage.graphs Looped multi-digraph on 9 vertices - sage: G.plot() + sage: G.plot() # optional - sage.graphs Graphics object consisting of 48 graphics primitives This is the Hasse diagram of the divisibility order on ``NN``. - sage: Poset(NN.cayley_graph(elements=[1..12], generators=[2,3,5,7,11])).show() + sage: Poset(NN.cayley_graph(elements=[1..12], generators=[2,3,5,7,11])).show() # optional - sage.combinat sage.graphs Note: as for :class:`NonNegativeIntegers `, ``NN`` is diff --git a/src/sage/rings/sum_of_squares.pyx b/src/sage/rings/sum_of_squares.pyx index a1d3edcedef..7e19380441e 100644 --- a/src/sage/rings/sum_of_squares.pyx +++ b/src/sage/rings/sum_of_squares.pyx @@ -140,7 +140,7 @@ def two_squares_pyx(uint32_t n): .. SEEALSO:: - :func:`~sage.arith.all.two_squares` is much more suited for large inputs + :func:`~sage.arith.misc.two_squares` is much more suited for large inputs EXAMPLES:: @@ -166,7 +166,7 @@ def two_squares_pyx(uint32_t n): TESTS:: sage: s = lambda t: sum(i^2 for i in t) - sage: for ij in Subsets(Subsets(45000,15).random_element(),2): + sage: for ij in Subsets(Subsets(45000, 15).random_element(), 2): # optional - sage.combinat ....: if s(two_squares_pyx(s(ij))) != s(ij): ....: print("hey") @@ -254,7 +254,7 @@ def three_squares_pyx(uint32_t n): TESTS:: sage: s = lambda t: sum(i^2 for i in t) - sage: for ijk in Subsets(Subsets(35000,15).random_element(),3): + sage: for ijk in Subsets(Subsets(35000,15).random_element(),3): # optional - sage.combinat ....: if s(three_squares_pyx(s(ijk))) != s(ijk): ....: print("hey") """ @@ -278,7 +278,7 @@ def four_squares_pyx(uint32_t n): .. SEEALSO:: - :func:`~sage.arith.all.four_squares` is much more suited for large input + :func:`~sage.arith.misc.four_squares` is much more suited for large input EXAMPLES:: diff --git a/src/sage/rings/tests.py b/src/sage/rings/tests.py index 2c4ab8ec988..d7d14aa4e0a 100644 --- a/src/sage/rings/tests.py +++ b/src/sage/rings/tests.py @@ -23,9 +23,9 @@ def prime_finite_field(): EXAMPLES:: sage: import sage.rings.tests - sage: K = sage.rings.tests.prime_finite_field(); K + sage: K = sage.rings.tests.prime_finite_field(); K # optional - sage.rings.finite_rings Finite Field of size ... - sage: K.cardinality().is_prime() + sage: K.cardinality().is_prime() # optional - sage.rings.finite_rings True """ from sage.rings.integer_ring import ZZ @@ -42,11 +42,11 @@ def finite_field(): EXAMPLES:: sage: import sage.rings.tests - sage: K = sage.rings.tests.finite_field(); K + sage: K = sage.rings.tests.finite_field(); K # optional - sage.rings.finite_rings Finite Field...of size ... - sage: K.cardinality().is_prime_power() + sage: K.cardinality().is_prime_power() # optional - sage.rings.finite_rings True - sage: while K.cardinality().is_prime(): + sage: while K.cardinality().is_prime(): # optional - sage.rings.finite_rings ....: K = sage.rings.tests.finite_field() """ from sage.rings.integer_ring import ZZ @@ -65,12 +65,12 @@ def small_finite_field(): EXAMPLES:: sage: import sage.rings.tests - sage: K = sage.rings.tests.small_finite_field(); K + sage: K = sage.rings.tests.small_finite_field(); K # optional - sage.rings.finite_rings Finite Field...of size ... - sage: q = K.cardinality() - sage: q.is_prime_power() + sage: q = K.cardinality() # optional - sage.rings.finite_rings + sage: q.is_prime_power() # optional - sage.rings.finite_rings True - sage: q <= 2^16 + sage: q <= 2^16 # optional - sage.rings.finite_rings True """ from sage.rings.integer_ring import ZZ @@ -107,7 +107,7 @@ def padic_field(): EXAMPLES:: sage: import sage.rings.tests - sage: sage.rings.tests.padic_field() + sage: sage.rings.tests.padic_field() # optional - sage.rings.padics ...-adic Field with capped relative precision ... """ from sage.rings.integer_ring import ZZ @@ -124,7 +124,7 @@ def quadratic_number_field(): EXAMPLES:: sage: import sage.rings.tests - sage: K = sage.rings.tests.quadratic_number_field(); K + sage: K = sage.rings.tests.quadratic_number_field(); K # optional - sage.rings.number_field Number Field in a with defining polynomial x^2 ... with a = ... """ from sage.rings.integer_ring import ZZ @@ -142,9 +142,9 @@ def absolute_number_field(maxdeg=10): EXAMPLES:: sage: import sage.rings.tests - sage: K = sage.rings.tests.absolute_number_field(); K + sage: K = sage.rings.tests.absolute_number_field(); K # optional - sage.rings.number_field Number Field in a with defining polynomial ... - sage: K.degree() <= 10 + sage: K.degree() <= 10 # optional - sage.rings.number_field True """ from sage.rings.integer_ring import ZZ @@ -167,26 +167,26 @@ def relative_number_field(n=2, maxdeg=2): EXAMPLES:: sage: import sage.rings.tests - sage: K = sage.rings.tests.relative_number_field(3); K + sage: K = sage.rings.tests.relative_number_field(3); K # optional - sage.rings.number_field Number Field in aaa with defining polynomial x^2 ... over its base field - sage: K.relative_degree() + sage: K.relative_degree() # optional - sage.rings.number_field 2 - sage: L = K.base_ring() - sage: L.relative_degree() + sage: L = K.base_ring() # optional - sage.rings.number_field + sage: L.relative_degree() # optional - sage.rings.number_field 2 - sage: M = L.base_ring() - sage: M.relative_degree() + sage: M = L.base_ring() # optional - sage.rings.number_field + sage: M.relative_degree() # optional - sage.rings.number_field 2 - sage: M.base_ring() is QQ + sage: M.base_ring() is QQ # optional - sage.rings.number_field True TESTS: Check that :trac:`32117` is fixed:: - sage: set_random_seed(3030) - sage: from sage.rings.tests import relative_number_field - sage: _ = relative_number_field(3) + sage: set_random_seed(3030) # optional - sage.rings.number_field + sage: from sage.rings.tests import relative_number_field # optional - sage.rings.number_field + sage: _ = relative_number_field(3) # optional - sage.rings.number_field """ from sage.rings.integer_ring import ZZ K = absolute_number_field(maxdeg) @@ -333,7 +333,7 @@ def test_random_elements(level=MAX_LEVEL, trials=1): EXAMPLES:: sage: import sage.rings.tests - sage: sage.rings.tests.test_random_elements(trials=2, seed=0) + sage: sage.rings.tests.test_random_elements(trials=2, seed=0) # optional - sage.rings.number_field survived 0 tests Rational Field -1/2 @@ -382,7 +382,7 @@ def test_random_arith(level=MAX_LEVEL, trials=1): EXAMPLES:: sage: import sage.rings.tests - sage: sage.rings.tests.test_random_arith(trials=2, seed=0) + sage: sage.rings.tests.test_random_arith(trials=2, seed=0) # optional - sage.rings.number_field survived 0 tests Rational Field -1/2 -1/95 @@ -437,12 +437,16 @@ def test_karatsuba_multiplication(base_ring, maxdeg1, maxdeg2, Test Karatsuba multiplication of polynomials of small degree over some common rings:: - sage: for C in [QQ, ZZ[I], GF(49, 'a'), MatrixSpace(GF(17), 3)]: + sage: rings = [QQ] + sage: rings += [ZZ[I], ZZ[I, sqrt(2)]] # optional - sage.rings.number_field + sage: rings += [GF(49, 'a')] # optional - sage.rings.finite_rings + sage: rings += [MatrixSpace(GF(17), 3)] # optional - sage.rings.finite_rings sage.modules + sage: for C in rings: ....: test_karatsuba_multiplication(C, 10, 10) Zero-tests over ``QQbar`` are currently very slow, so we test only very small examples:: - sage: test_karatsuba_multiplication(QQbar, 3, 3, numtests=2) # long time + sage: test_karatsuba_multiplication(QQbar, 3, 3, numtests=2) # long time # optional - sage.rings.number_field Larger degrees (over ``ZZ``, using FLINT):: @@ -452,10 +456,10 @@ def test_karatsuba_multiplication(base_ring, maxdeg1, maxdeg2, Some more aggressive tests:: - sage: testrings = [ZZ[I, sqrt(2)], ZZ[I, sqrt(2), sqrt(3)]] # long time - sage: for C in testrings: # long time + sage: testrings = [ZZ[I, sqrt(2)], ZZ[I, sqrt(2), sqrt(3)]] # long time + sage: for C in testrings: # long time ....: test_karatsuba_multiplication(C, 100, 100) - sage: test_karatsuba_multiplication(ZZ, 10000, 10000, # long time + sage: test_karatsuba_multiplication(ZZ, 10000, 10000, # long time ....: ref_mul=lambda f,g: f*g, ....: base_ring_random_elt_args=[100000]) diff --git a/src/sage/rings/universal_cyclotomic_field.py b/src/sage/rings/universal_cyclotomic_field.py index f5d2bc5b1d9..2c6097e74e8 100644 --- a/src/sage/rings/universal_cyclotomic_field.py +++ b/src/sage/rings/universal_cyclotomic_field.py @@ -521,14 +521,14 @@ def _symbolic_(self, R): r""" TESTS:: - sage: SR(E(7)) + sage: SR(E(7)) # optional - sage.symbolic e^(2/7*I*pi) - sage: SR(E(5) + 2*E(5,2) + 3*E(5,3)) + sage: SR(E(5) + 2*E(5,2) + 3*E(5,3)) # optional - sage.symbolic -sqrt(5) + 1/4*I*sqrt(2*sqrt(5) + 10) - 1/4*I*sqrt(-2*sqrt(5) + 10) - 3/2 Test that the bug reported in :trac:`19912` has been fixed:: - sage: SR(1+E(4)) + sage: SR(1+E(4)) # optional - sage.symbolic I + 1 """ from sage.symbolic.constants import pi, I diff --git a/src/sage/sandpiles/sandpile.py b/src/sage/sandpiles/sandpile.py index 2d09a660d65..9f19deaea2e 100644 --- a/src/sage/sandpiles/sandpile.py +++ b/src/sage/sandpiles/sandpile.py @@ -320,37 +320,37 @@ from IPython.lib import pretty -from sage.calculus.functional import derivative +from sage.arith.functions import lcm +from sage.arith.misc import binomial, falling_factorial +from sage.arith.srange import xsrange from sage.combinat.integer_vector import integer_vectors_nk_fast_iter from sage.combinat.parking_functions import ParkingFunctions from sage.combinat.set_partition import SetPartitions from sage.combinat.vector_partition import IntegerVectorsIterator -from sage.functions.log import exp -from sage.functions.other import binomial +from sage.features.four_ti_2 import FourTi2Executable from sage.geometry.polyhedron.constructor import Polyhedron -from sage.graphs.graph import Graph from sage.graphs.digraph import DiGraph -from sage.probability.probability_distribution import GeneralDiscreteDistribution -from sage.topology.simplicial_complex import SimplicialComplex +from sage.graphs.graph import Graph from sage.interfaces.singular import singular from sage.matrix.constructor import matrix, identity_matrix from sage.misc.functional import det, denominator +from sage.misc.lazy_import import lazy_import from sage.misc.misc import exists from sage.misc.misc_c import prod from sage.misc.temporary_file import tmp_filename -from sage.arith.srange import xsrange from sage.modules.free_module_element import vector -from sage.misc.lazy_import import lazy_import -from sage.arith.functions import lcm -from sage.arith.misc import falling_factorial +from sage.probability.probability_distribution import GeneralDiscreteDistribution from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import QQ -from sage.symbolic.constants import I, pi -from sage.symbolic.ring import SR -from sage.features.four_ti_2 import FourTi2Executable +from sage.topology.simplicial_complex import SimplicialComplex + +lazy_import("sage.calculus.functional", "derivative") +lazy_import("sage.functions.log", "exp") lazy_import("sage.plot.colors", "rainbow") +lazy_import("sage.symbolic.constants", ["I", "pi"]) +lazy_import("sage.symbolic.ring", "SR") def _sandpile_help(cls, usage, verbose=True): diff --git a/src/sage/sat/converters/polybori.py b/src/sage/sat/converters/polybori.py index a53c4e650e3..a70c5279e50 100644 --- a/src/sage/sat/converters/polybori.py +++ b/src/sage/sat/converters/polybori.py @@ -30,7 +30,6 @@ from random import Random from sage.rings.polynomial.pbori.pbori import if_then_else as ite from sage.rings.integer_ring import ZZ -from sage.functions.other import ceil from sage.misc.cachefunc import cached_method, cached_function from sage.combinat.permutation import Permutations from sage.sat.converters import ANF2CNFConverter @@ -468,7 +467,7 @@ def split_xor(self, monomial_list, equal_zero): c = self.cutting_number nm = len(monomial_list) - step = ceil((c-2)/ZZ(nm) * nm) + step = ((c-2)/ZZ(nm) * nm).ceil() M = [] new_variables = [] diff --git a/src/sage/schemes/affine/affine_morphism.py b/src/sage/schemes/affine/affine_morphism.py index 594c9815c15..4f78c3319e0 100644 --- a/src/sage/schemes/affine/affine_morphism.py +++ b/src/sage/schemes/affine/affine_morphism.py @@ -48,7 +48,8 @@ import sys -from sage.calculus.functions import jacobian +from sage.misc.lazy_import import lazy_import +lazy_import("sage.calculus.functions", "jacobian") from sage.categories.homset import Hom, End from sage.categories.fields import Fields diff --git a/src/sage/schemes/affine/affine_space.py b/src/sage/schemes/affine/affine_space.py index 4943c37402c..8e4379584b8 100644 --- a/src/sage/schemes/affine/affine_space.py +++ b/src/sage/schemes/affine/affine_space.py @@ -10,7 +10,8 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.functions.orthogonal_polys import chebyshev_T, chebyshev_U +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.orthogonal_polys", ["chebyshev_T", "chebyshev_U"]) from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing diff --git a/src/sage/schemes/cyclic_covers/charpoly_frobenius.py b/src/sage/schemes/cyclic_covers/charpoly_frobenius.py index fc5cc3b1c3e..703c9dfad1a 100644 --- a/src/sage/schemes/cyclic_covers/charpoly_frobenius.py +++ b/src/sage/schemes/cyclic_covers/charpoly_frobenius.py @@ -7,7 +7,8 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** from sage.rings.integer_ring import ZZ -from sage.functions.log import log +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.log", "log") def charpoly_frobenius(frob_matrix, charpoly_prec, p, weight, a=1, known_factor=[1]): diff --git a/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py b/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py index d2bdefa5e3a..e53cf8a3c05 100644 --- a/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py +++ b/src/sage/schemes/cyclic_covers/cycliccover_finite_field.py @@ -70,8 +70,9 @@ from sage.arith.misc import euler_phi -from sage.functions.other import ceil, binomial, floor -from sage.functions.log import log +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.other", ["ceil", "binomial", "floor"]) +lazy_import("sage.functions.log", "log") from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.power_series_ring import PowerSeriesRing from sage.rings.padics.factory import Zp, Zq, Qq diff --git a/src/sage/schemes/elliptic_curves/BSD.py b/src/sage/schemes/elliptic_curves/BSD.py index f5522de2e00..7bbf6d1d534 100644 --- a/src/sage/schemes/elliptic_curves/BSD.py +++ b/src/sage/schemes/elliptic_curves/BSD.py @@ -2,10 +2,12 @@ "Birch and Swinnerton-Dyer formulas" from sage.arith.misc import prime_divisors +from sage.misc.lazy_import import lazy_import from sage.rings.integer_ring import ZZ from sage.rings.infinity import Infinity from sage.rings.number_field.number_field import QuadraticField -from sage.functions.other import ceil + +lazy_import("sage.functions.other", "ceil") class BSD_data: diff --git a/src/sage/schemes/elliptic_curves/ell_number_field.py b/src/sage/schemes/elliptic_curves/ell_number_field.py index 001783fd03c..e01d7436d94 100644 --- a/src/sage/schemes/elliptic_curves/ell_number_field.py +++ b/src/sage/schemes/elliptic_curves/ell_number_field.py @@ -223,6 +223,7 @@ def simon_two_descent(self, verbose=0, lim1=2, lim3=4, limtriv=2, EXAMPLES:: + sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^2 + 23, 'a') sage: E = EllipticCurve(K, '37') sage: E == loads(dumps(E)) @@ -704,7 +705,8 @@ def _reduce_model(self): EXAMPLES:: - sage: K. = NumberField(x^2-38) + sage: x = polygen(ZZ, 'x') + sage: K. = NumberField(x^2 - 38) sage: E = EllipticCurve([a, -5*a + 19, -39*a + 237, 368258520200522046806318224*a - 2270097978636731786720858047, 8456608930180227786550494643437985949781*a - 52130038506835491453281450568107193773505]) sage: E.ainvs() (a, @@ -762,7 +764,8 @@ def _scale_by_units(self): EXAMPLES:: - sage: K. = NumberField(x^2-10) + sage: x = polygen(ZZ, 'x') + sage: K. = NumberField(x^2 - 10) sage: u = a + 3 sage: u.is_unit() True @@ -1259,7 +1262,8 @@ def tamagawa_number(self, P, proof=None): EXAMPLES:: - sage: K. = NumberField(x^2-5) + sage: x = polygen(ZZ, 'x') + sage: K. = NumberField(x^2 - 5) sage: E = EllipticCurve([20, 225, 750, 625*a + 6875, 31250*a + 46875]) sage: [E.tamagawa_number(P) for P in E.discriminant().support()] [1, 1, 1, 1] @@ -1974,6 +1978,7 @@ def torsion_subgroup(self): EXAMPLES:: sage: E = EllipticCurve('11a1') + sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^4 + x^3 + 11*x^2 + 41*x + 101) sage: EK = E.base_extend(K) sage: tor = EK.torsion_subgroup() # long time (2s on sage.math, 2014) @@ -2033,6 +2038,7 @@ def torsion_order(self): EXAMPLES:: sage: E = EllipticCurve('11a1') + sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^4 + x^3 + 11*x^2 + 41*x + 101) sage: EK = E.base_extend(K) sage: EK.torsion_order() # long time (2s on sage.math, 2014) @@ -2076,6 +2082,7 @@ def torsion_points(self): sage: E = EllipticCurve('11a1') sage: E.torsion_points() [(0 : 1 : 0), (5 : -6 : 1), (5 : 5 : 1), (16 : -61 : 1), (16 : 60 : 1)] + sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^4 + x^3 + 11*x^2 + 41*x + 101) sage: EK = E.base_extend(K) sage: EK.torsion_points() # long time (1s on sage.math, 2014) @@ -2179,6 +2186,7 @@ def rank_bounds(self, **kwds): EXAMPLES:: + sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^2 + 23, 'a') sage: E = EllipticCurve(K, '37') sage: E == loads(dumps(E)) @@ -2258,6 +2266,7 @@ def rank(self, **kwds): EXAMPLES:: + sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^2 + 23, 'a') sage: E = EllipticCurve(K, '37') sage: E == loads(dumps(E)) @@ -2336,6 +2345,7 @@ def gens(self, **kwds): EXAMPLES:: + sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^2 + 23, 'a') sage: E = EllipticCurve(K,[0,0,0,101,0]) sage: E.gens() @@ -2519,6 +2529,7 @@ def height_function(self): EXAMPLES:: + sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^2 - 5) sage: E = EllipticCurve(K, '11a3') sage: E.height_function() @@ -3303,6 +3314,7 @@ def reducible_primes(self, algorithm='Billerey', max_l=None, EXAMPLES:: + sage: x = polygen(ZZ, 'x') sage: K = NumberField(x**2 - 29, 'a'); a = K.gen() sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0]) sage: rho = E.galois_representation() @@ -3476,6 +3488,7 @@ def galois_representation(self): EXAMPLES:: + sage: x = polygen(ZZ, 'x') sage: K = NumberField(x**2 + 1, 'a') sage: E = EllipticCurve('11a1').change_ring(K) sage: rho = E.galois_representation() @@ -3527,6 +3540,7 @@ def cm_discriminant(self): sage: K. = QuadraticField(5) sage: EllipticCurve(j=282880*a + 632000).cm_discriminant() -20 + sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^3 - 2) sage: EllipticCurve(j=31710790944000*a^2 + 39953093016000*a + 50337742902000).cm_discriminant() -108 @@ -3573,6 +3587,7 @@ def has_cm(self): sage: K. = QuadraticField(5) sage: EllipticCurve(j=282880*a + 632000).has_cm() True + sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^3 - 2) sage: EllipticCurve(j=31710790944000*a^2 + 39953093016000*a + 50337742902000).has_cm() True @@ -3650,6 +3665,7 @@ def has_rational_cm(self, field=None): is not an extension field of Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? + sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^3 - 2) sage: E = EllipticCurve(j=31710790944000*a^2 + 39953093016000*a + 50337742902000) sage: E.has_cm() diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 420a6c7cc77..e22b6b84518 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -66,8 +66,6 @@ from sage.modular.modsym.modsym import ModularSymbols from sage.modular.pollack_stevens.space import ps_modsym_from_elliptic_curve -from sage.lfunctions.zero_sums import LFunctionZeroSum_EllipticCurve - import sage.modular.modform.constructor import sage.modular.modform.element import sage.databases.cremona @@ -88,11 +86,12 @@ import sage.misc.all as misc from sage.misc.verbose import verbose as verbose_verbose -from sage.functions.log import log +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.log", "log") import sage.matrix.all as matrix from sage.libs.pari.all import pari -from sage.functions.gamma import gamma_inc +lazy_import("sage.functions.gamma", "gamma_inc") from math import sqrt from sage.interfaces.gp import gp from sage.misc.cachefunc import cached_method @@ -1763,6 +1762,8 @@ def analytic_rank_upper_bound(self, ....: bad_primes=bad_primes, ncpus=2) 32 """ + from sage.lfunctions.zero_sums import LFunctionZeroSum_EllipticCurve + Z = LFunctionZeroSum_EllipticCurve(self, N) bound = Z.analytic_rank_upper_bound(max_Delta=max_Delta, adaptive=adaptive, diff --git a/src/sage/schemes/elliptic_curves/ell_tate_curve.py b/src/sage/schemes/elliptic_curves/ell_tate_curve.py index 0b7cd52a146..493a24e7f78 100644 --- a/src/sage/schemes/elliptic_curves/ell_tate_curve.py +++ b/src/sage/schemes/elliptic_curves/ell_tate_curve.py @@ -47,8 +47,7 @@ from sage.arith.functions import lcm as LCM from sage.modular.modform.constructor import EisensteinForms, CuspForms from sage.schemes.elliptic_curves.constructor import EllipticCurve -from sage.functions.log import log -from sage.misc.functional import denominator +from sage.misc.functional import denominator, log from sage.misc.misc_c import prod import sage.matrix.all as matrix diff --git a/src/sage/schemes/elliptic_curves/height.py b/src/sage/schemes/elliptic_curves/height.py index e9eb837d30e..915a67b45cc 100644 --- a/src/sage/schemes/elliptic_curves/height.py +++ b/src/sage/schemes/elliptic_curves/height.py @@ -45,8 +45,9 @@ from sage.arith.functions import lcm from sage.arith.misc import factorial from sage.ext.fast_callable import fast_callable -from sage.functions.log import log, exp -from sage.symbolic.ring import SR +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.log", ["log", "exp"]) +lazy_import("sage.symbolic.ring", "SR") class UnionOfIntervals: diff --git a/src/sage/schemes/elliptic_curves/lseries_ell.py b/src/sage/schemes/elliptic_curves/lseries_ell.py index 7f0e4d3e5e5..37872d483e1 100644 --- a/src/sage/schemes/elliptic_curves/lseries_ell.py +++ b/src/sage/schemes/elliptic_curves/lseries_ell.py @@ -26,7 +26,6 @@ from sage.rings.real_mpfr import RealField from sage.rings.rational_field import RationalField from math import sqrt, log, ceil -import sage.functions.exp_integral as exp_integral from sage.misc.verbose import verbose from sage.misc.cachefunc import cached_method @@ -661,32 +660,32 @@ def deriv_at1(self, k=None, prec=None): EXAMPLES:: sage: E = EllipticCurve('37a') - sage: E.lseries().deriv_at1() + sage: E.lseries().deriv_at1() # optional - sage.symbolic (0.3059866, 0.000801045) - sage: E.lseries().deriv_at1(100) + sage: E.lseries().deriv_at1(100) # optional - sage.symbolic (0.3059997738340523018204836833216764744526377745903, 1.52493e-45) - sage: E.lseries().deriv_at1(1000) + sage: E.lseries().deriv_at1(1000) # optional - sage.symbolic (0.305999773834052301820483683321676474452637774590771998..., 2.75031e-449) With less numerical precision, the error is bounded by numerical accuracy:: - sage: L,err = E.lseries().deriv_at1(100, prec=64) - sage: L,err + sage: L, err = E.lseries().deriv_at1(100, prec=64) # optional - sage.symbolic + sage: L, err # optional - sage.symbolic (0.305999773834052302, 5.55318e-18) - sage: parent(L) + sage: parent(L) # optional - sage.symbolic Real Field with 64 bits of precision - sage: parent(err) + sage: parent(err) # optional - sage.symbolic Real Field with 24 bits of precision and rounding RNDU Rank 2 and rank 3 elliptic curves:: sage: E = EllipticCurve('389a1') - sage: E.lseries().deriv_at1() + sage: E.lseries().deriv_at1() # optional - sage.symbolic (0.0000000, 0.000000) sage: E = EllipticCurve((1, 0, 1, -131, 558)) # curve 59450i1 - sage: E.lseries().deriv_at1() + sage: E.lseries().deriv_at1() # optional - sage.symbolic (-0.00010911444, 0.142428) - sage: E.lseries().deriv_at1(4000) + sage: E.lseries().deriv_at1(4000) # optional - sage.symbolic (6.990...e-50, 1.31318e-43) """ sqrtN = sqrt(self.__E.conductor()) @@ -717,10 +716,12 @@ def deriv_at1(self, k=None, prec=None): # positive, so L'(E,1) = 0. return (R.zero(), Rerror.zero()) + from sage.functions.exp_integral import exponential_integral_1 + an = self.__E.anlist(k) # list of Sage Integers pi = R.pi() sqrtN = R(self.__E.conductor()).sqrt() - v = exp_integral.exponential_integral_1(2*pi/sqrtN, k) + v = exponential_integral_1(2*pi/sqrtN, k) # Compute series sum and accumulate floating point errors L = R.zero() diff --git a/src/sage/schemes/elliptic_curves/padic_lseries.py b/src/sage/schemes/elliptic_curves/padic_lseries.py index 74581cd2479..4391e5ed5e2 100644 --- a/src/sage/schemes/elliptic_curves/padic_lseries.py +++ b/src/sage/schemes/elliptic_curves/padic_lseries.py @@ -70,10 +70,9 @@ prime_divisors, kronecker as kronecker_symbol, valuation) -from sage.functions.log import log -from sage.functions.other import floor from sage.misc.cachefunc import cached_method from sage.misc.functional import denominator +from sage.misc.lazy_import import lazy_import from sage.misc.verbose import get_verbose, verbose from sage.modules.free_module_element import vector from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as Integers @@ -88,6 +87,9 @@ from sage.structure.richcmp import richcmp_method, richcmp from sage.structure.sage_object import SageObject +lazy_import("sage.functions.log", "log") +lazy_import("sage.functions.other", "floor") + @richcmp_method class pAdicLseries(SageObject): diff --git a/src/sage/schemes/elliptic_curves/sha_tate.py b/src/sage/schemes/elliptic_curves/sha_tate.py index 33818051b8f..b7246e5d26a 100644 --- a/src/sage/schemes/elliptic_curves/sha_tate.py +++ b/src/sage/schemes/elliptic_curves/sha_tate.py @@ -80,18 +80,22 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.structure.sage_object import SageObject +from math import sqrt + +import sage.arith.all as arith + +from sage.misc.lazy_import import lazy_import +from sage.misc.verbose import verbose +from sage.modules.free_module_element import vector from sage.rings.integer import Integer +from sage.rings.padics.factory import Qp from sage.rings.real_mpfr import RealField from sage.rings.rational_field import RationalField from sage.rings.real_mpfi import RIF from sage.rings.integer_ring import ZZ -from sage.functions.log import log -from math import sqrt -from sage.misc.verbose import verbose -import sage.arith.all as arith -from sage.rings.padics.factory import Qp -from sage.modules.free_module_element import vector +from sage.structure.sage_object import SageObject + +lazy_import("sage.functions.log", "log") factor = arith.factor valuation = arith.valuation diff --git a/src/sage/schemes/generic/algebraic_scheme.py b/src/sage/schemes/generic/algebraic_scheme.py index c1434b7c5b4..a9caddd1cb3 100644 --- a/src/sage/schemes/generic/algebraic_scheme.py +++ b/src/sage/schemes/generic/algebraic_scheme.py @@ -130,7 +130,8 @@ from sage.structure.all import Sequence from sage.structure.richcmp import richcmp, richcmp_method -from sage.calculus.functions import jacobian +from sage.misc.lazy_import import lazy_import +lazy_import("sage.calculus.functions", "jacobian") from sage.arith.functions import lcm from sage.arith.misc import gcd diff --git a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py index 9ab9dfbcb4c..39d450ba546 100644 --- a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +++ b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py @@ -38,7 +38,8 @@ from sage.rings.power_series_ring import PowerSeriesRing from sage.rings.laurent_series_ring import LaurentSeriesRing from sage.rings.real_mpfr import RR -from sage.functions.all import log +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.all", "log") from sage.structure.category_object import normalize_names import sage.schemes.curves.projective_curve as plane_curve diff --git a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py index 030d8dab2e7..bc2627c3367 100644 --- a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +++ b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py @@ -11,23 +11,23 @@ # https://www.gnu.org/licenses/ # **************************************************************************** - -from sage.rings.power_series_ring import PowerSeriesRing -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.matrix.constructor import matrix +from sage.misc.lazy_import import lazy_import +from sage.modules.free_module import VectorSpace +from sage.modules.free_module_element import vector +from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF +from sage.rings.infinity import Infinity from sage.rings.integer_ring import ZZ -from sage.rings.rational_field import QQ from sage.rings.padics.factory import Qp as pAdicField -from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF -from sage.rings.real_mpfr import RR +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.power_series_ring import PowerSeriesRing +from sage.rings.rational_field import QQ from sage.rings.rational_field import RationalField -from sage.rings.infinity import Infinity -from sage.functions.log import log -from sage.modules.free_module import VectorSpace -from sage.matrix.constructor import matrix -from sage.modules.free_module_element import vector - +from sage.rings.real_mpfr import RR from sage.schemes.curves.projective_curve import ProjectivePlaneCurve_field +lazy_import("sage.functions.log", "log") + from . import hyperelliptic_generic diff --git a/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py b/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py index 321928f1464..4ff3b01f10b 100644 --- a/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +++ b/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py @@ -48,9 +48,9 @@ from sage.arith.misc import integer_ceil as ceil from sage.arith.misc import binomial -from sage.functions.log import log from sage.matrix.constructor import matrix from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import from sage.misc.misc import newton_method_sizes from sage.misc.profiler import Profiler from sage.misc.repr import repr_lincomb @@ -81,6 +81,8 @@ from sage.structure.richcmp import richcmp from sage.structure.unique_representation import UniqueRepresentation +lazy_import("sage.functions.log", "log") + class SpecialCubicQuotientRingElement(CommutativeAlgebraElement): """ diff --git a/src/sage/schemes/overview.py b/src/sage/schemes/overview.py index bd83daafac0..dff5728c1db 100644 --- a/src/sage/schemes/overview.py +++ b/src/sage/schemes/overview.py @@ -132,7 +132,7 @@ :: - sage: P([2, 1 + t]) + sage: P([2, 1 + t]) # optional - sage.rings.number_field (2 : t + 1 : 1) In fact, we need a test ``R.ideal([2, 1 + t]) == R.ideal([1])`` in order to make diff --git a/src/sage/schemes/product_projective/morphism.py b/src/sage/schemes/product_projective/morphism.py index 853ffdaf435..f28aa84e7ba 100644 --- a/src/sage/schemes/product_projective/morphism.py +++ b/src/sage/schemes/product_projective/morphism.py @@ -54,7 +54,7 @@ def __init__(self, parent, polys, check=True): - ``polys`` -- anything that defines a point in the class. - ``check`` -- Boolean. Whether or not to perform input checks. - (Default:`` True``) + (Default: ``True``) EXAMPLES:: diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index cd484292859..a76e6c6bd7e 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -67,7 +67,10 @@ from sage.misc.cachefunc import cached_method from sage.misc.lazy_attribute import lazy_attribute from sage.ext.fast_callable import fast_callable -from sage.calculus.functions import jacobian + +from sage.misc.lazy_import import lazy_import +lazy_import("sage.calculus.functions", "jacobian") + import sage.rings.abc from sage.rings.integer import Integer from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField_generic diff --git a/src/sage/schemes/riemann_surfaces/riemann_surface.py b/src/sage/schemes/riemann_surfaces/riemann_surface.py index 917de00d7b0..4ebdc3ff22f 100644 --- a/src/sage/schemes/riemann_surfaces/riemann_surface.py +++ b/src/sage/schemes/riemann_surfaces/riemann_surface.py @@ -115,7 +115,6 @@ from sage.arith.functions import lcm from sage.arith.misc import GCD, algdep from sage.ext.fast_callable import fast_callable -from sage.functions.log import lambert_w from sage.graphs.graph import Graph from sage.groups.matrix_gps.finitely_generated import MatrixGroup from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -3089,6 +3088,8 @@ def initialise(z, i): else: n_steps = 15 + from sage.functions.log import lambert_w + V = VectorSpace(self._CC, self.genus) h = one Nh = (-lambert_w(-1, -tau / 2) / la).log().ceil() diff --git a/src/sage/schemes/toric/toric_subscheme.py b/src/sage/schemes/toric/toric_subscheme.py index e425ee3d0a8..8f7477a15cb 100644 --- a/src/sage/schemes/toric/toric_subscheme.py +++ b/src/sage/schemes/toric/toric_subscheme.py @@ -20,7 +20,8 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.calculus.functions import jacobian +from sage.misc.lazy_import import lazy_import +lazy_import("sage.calculus.functions", "jacobian") from sage.rings.integer_ring import ZZ from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme diff --git a/src/sage/schemes/toric/variety.py b/src/sage/schemes/toric/variety.py index c594610f15d..3060de6f532 100644 --- a/src/sage/schemes/toric/variety.py +++ b/src/sage/schemes/toric/variety.py @@ -302,7 +302,8 @@ import sys -from sage.functions.all import factorial +from sage.misc.lazy_import import lazy_import +lazy_import("sage.functions.all", "factorial") import sage.geometry.abc from sage.geometry.cone import Cone from sage.geometry.fan import Fan diff --git a/src/sage/sets/cartesian_product.py b/src/sage/sets/cartesian_product.py index cc2ce557bd0..fb67c6738a8 100644 --- a/src/sage/sets/cartesian_product.py +++ b/src/sage/sets/cartesian_product.py @@ -36,14 +36,14 @@ class CartesianProduct(UniqueRepresentation, Parent): EXAMPLES:: - sage: G = cartesian_product([GF(5), Permutations(10)]) - sage: G.cartesian_factors() + sage: G = cartesian_product([GF(5), Permutations(10)]) # optional - sage.rings.finite_rings + sage: G.cartesian_factors() # optional - sage.rings.finite_rings (Finite Field of size 5, Standard permutations of 10) - sage: G.cardinality() + sage: G.cardinality() # optional - sage.rings.finite_rings 18144000 - sage: G.random_element() # random + sage: G.random_element() # random # optional - sage.rings.finite_rings (1, [4, 7, 6, 5, 10, 1, 3, 2, 8, 9]) - sage: G.category() + sage: G.category() # optional - sage.rings.finite_rings Join of Category of finite monoids and Category of Cartesian products of monoids and Category of Cartesian products of finite enumerated sets @@ -92,24 +92,24 @@ def _element_constructor_(self,x): EXAMPLES:: - sage: C = cartesian_product([GF(5), GF(3)]) - sage: x = C((1,3)); x + sage: C = cartesian_product([GF(5), GF(3)]) # optional - sage.rings.finite_rings + sage: x = C((1,3)); x # optional - sage.rings.finite_rings (1, 0) - sage: x.parent() + sage: x.parent() # optional - sage.rings.finite_rings The Cartesian product of (Finite Field of size 5, Finite Field of size 3) - sage: x[0].parent() + sage: x[0].parent() # optional - sage.rings.finite_rings Finite Field of size 5 - sage: x[1].parent() + sage: x[1].parent() # optional - sage.rings.finite_rings Finite Field of size 3 An iterable is also accepted as input:: - sage: C(i for i in range(2)) + sage: C(i for i in range(2)) # optional - sage.rings.finite_rings (0, 1) TESTS:: - sage: C((1,3,4)) + sage: C((1,3,4)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: (1, 3, 4) should be of length 2 diff --git a/src/sage/sets/condition_set.py b/src/sage/sets/condition_set.py index 34265775dd3..5a471e42e09 100644 --- a/src/sage/sets/condition_set.py +++ b/src/sage/sets/condition_set.py @@ -18,7 +18,7 @@ from sage.categories.sets_cat import Sets from sage.categories.enumerated_sets import EnumeratedSets from sage.misc.cachefunc import cached_method -from sage.misc.misc import _stable_uniq +from sage.combinat.subset import uniq from sage.structure.element import Expression from .set import Set, Set_base, Set_boolean_operators, Set_add_sub_operators @@ -62,28 +62,28 @@ class ConditionSet(Set_generic, Set_base, Set_boolean_operators, Set_add_sub_ope sage: 7/2 in EvensAndOdds False - sage: var('y') + sage: var('y') # optional - sage.symbolic y - sage: SmallOdds = ConditionSet(ZZ, is_odd, abs(y) <= 11, vars=[y]); SmallOdds + sage: SmallOdds = ConditionSet(ZZ, is_odd, abs(y) <= 11, vars=[y]); SmallOdds # optional - sage.symbolic { y ∈ Integer Ring : abs(y) <= 11, (y) } - sage: P = polytopes.cube(); P + sage: P = polytopes.cube(); P # optional - sage.geometry.polyhedron A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices - sage: P.rename("P") - sage: P_inter_B = ConditionSet(P, lambda x: x.norm() < 1.2); P_inter_B + sage: P.rename("P") # optional - sage.geometry.polyhedron + sage: P_inter_B = ConditionSet(P, lambda x: x.norm() < 1.2); P_inter_B # optional - sage.geometry.polyhedron { x ∈ P : at 0x...>(x) } - sage: vector([1, 0, 0]) in P_inter_B + sage: vector([1, 0, 0]) in P_inter_B # optional - sage.geometry.polyhedron True - sage: vector([1, 1, 1]) in P_inter_B + sage: vector([1, 1, 1]) in P_inter_B # optional - sage.geometry.polyhedron False - sage: predicate(x, y, z) = sqrt(x^2 + y^2 + z^2) < 1.2; predicate + sage: predicate(x, y, z) = sqrt(x^2 + y^2 + z^2) < 1.2; predicate # optional - sage.symbolic (x, y, z) |--> sqrt(x^2 + y^2 + z^2) < 1.20000000000000 - sage: P_inter_B_again = ConditionSet(P, predicate); P_inter_B_again + sage: P_inter_B_again = ConditionSet(P, predicate); P_inter_B_again # optional - sage.geometry.polyhedron sage.symbolic { (x, y, z) ∈ P : sqrt(x^2 + y^2 + z^2) < 1.20000000000000 } - sage: vector([1, 0, 0]) in P_inter_B_again + sage: vector([1, 0, 0]) in P_inter_B_again # optional - sage.geometry.polyhedron sage.symbolic True - sage: vector([1, 1, 1]) in P_inter_B_again + sage: vector([1, 1, 1]) in P_inter_B_again # optional - sage.geometry.polyhedron sage.symbolic False Iterating over subsets determined by predicates:: @@ -104,24 +104,25 @@ class ConditionSet(Set_generic, Set_base, Set_boolean_operators, Set_add_sub_ope Using ``ConditionSet`` without predicates provides a way of attaching variable names to a set:: - sage: Z3 = ConditionSet(ZZ^3, vars=['x', 'y', 'z']); Z3 - { (x, y, z) ∈ Ambient free module of rank 3 over the principal ideal domain Integer Ring } - sage: Z3.variable_names() + sage: Z3 = ConditionSet(ZZ^3, vars=['x', 'y', 'z']); Z3 # optional - sage.modules + { (x, y, z) ∈ Ambient free module of rank 3 + over the principal ideal domain Integer Ring } + sage: Z3.variable_names() # optional - sage.modules ('x', 'y', 'z') - sage: Z3.arguments() + sage: Z3.arguments() # optional - sage.modules (x, y, z) - sage: Q4. = ConditionSet(QQ^4); Q4 + sage: Q4. = ConditionSet(QQ^4); Q4 # optional - sage.modules { (a, b, c, d) ∈ Vector space of dimension 4 over Rational Field } - sage: Q4.variable_names() + sage: Q4.variable_names() # optional - sage.modules ('a', 'b', 'c', 'd') - sage: Q4.arguments() + sage: Q4.arguments() # optional - sage.modules (a, b, c, d) TESTS:: - sage: TestSuite(P_inter_B).run(skip='_test_pickling') # cannot pickle lambdas - sage: TestSuite(P_inter_B_again).run() + sage: TestSuite(P_inter_B).run(skip='_test_pickling') # cannot pickle lambdas # optional - sage.geometry.polyhedron + sage: TestSuite(P_inter_B_again).run() # optional - sage.geometry.polyhedron sage.symbolic """ @staticmethod def __classcall_private__(cls, universe, *predicates, vars=None, names=None, category=None): @@ -130,9 +131,9 @@ def __classcall_private__(cls, universe, *predicates, vars=None, names=None, cat TESTS:: - sage: ConditionSet(ZZ, names=["x"]) is ConditionSet(ZZ, names=x) + sage: ConditionSet(ZZ, names=["x"]) is ConditionSet(ZZ, names=x) # optional - sage.symbolic True - sage: ConditionSet(RR, x > 0, names=x) is ConditionSet(RR, (x > 0).function(x)) + sage: ConditionSet(RR, x > 0, names=x) is ConditionSet(RR, (x > 0).function(x)) # optional - sage.symbolic True """ if category is None: @@ -173,7 +174,7 @@ def __classcall_private__(cls, universe, *predicates, vars=None, names=None, cat else: other_predicates.append(predicate) - predicates = list(_stable_uniq(callable_symbolic_predicates + other_predicates)) + predicates = list(uniq(callable_symbolic_predicates + other_predicates)) if not other_predicates and not callable_symbolic_predicates: if names is None and category is None: @@ -224,10 +225,10 @@ def _repr_(self): EXAMPLES:: - sage: var('t') # parameter + sage: var('t') # parameter # optional - sage.symbolic t - sage: ZeroDimButNotNullary = ConditionSet(ZZ^0, t > 0, vars=("q")) - sage: ZeroDimButNotNullary._repr_() + sage: ZeroDimButNotNullary = ConditionSet(ZZ^0, t > 0, vars=("q")) # optional - sage.symbolic + sage: ZeroDimButNotNullary._repr_() # optional - sage.symbolic '{ q ∈ Ambient free module of rank 0 over the principal ideal domain Integer Ring : t > 0 }' """ @@ -257,13 +258,13 @@ def _repr_condition(self, predicate): sage: Evens = ConditionSet(ZZ, is_even) sage: Evens._repr_condition(is_even) '(x)' - sage: BigSin = ConditionSet(RR, sin(x) > 0.9, vars=[x]) - sage: BigSin._repr_condition(BigSin._predicates[0]) + sage: BigSin = ConditionSet(RR, sin(x) > 0.9, vars=[x]) # optional - sage.symbolic + sage: BigSin._repr_condition(BigSin._predicates[0]) # optional - sage.symbolic 'sin(x) > 0.900000000000000' - sage: var('t') # parameter + sage: var('t') # parameter # optional - sage.symbolic t - sage: ZeroDimButNotNullary = ConditionSet(ZZ^0, t > 0, vars=("q")) - sage: ZeroDimButNotNullary._repr_condition(ZeroDimButNotNullary._predicates[0]) + sage: ZeroDimButNotNullary = ConditionSet(ZZ^0, t > 0, vars=("q")) # optional - sage.symbolic + sage: ZeroDimButNotNullary._repr_condition(ZeroDimButNotNullary._predicates[0]) # optional - sage.symbolic 't > 0' """ if isinstance(predicate, Expression) and predicate.is_callable(): @@ -285,9 +286,9 @@ def arguments(self): sage: Odds = ConditionSet(ZZ, is_odd); Odds { x ∈ Integer Ring : (x) } - sage: args = Odds.arguments(); args + sage: args = Odds.arguments(); args # optional - sage.symbolic (x,) - sage: args[0].parent() + sage: args[0].parent() # optional - sage.symbolic Symbolic Ring """ from sage.symbolic.ring import SR @@ -339,24 +340,24 @@ def _call_predicate(self, predicate, element): TESTS:: - sage: TripleDigits = ZZ^3 - sage: predicate(x, y, z) = sqrt(x^2 + y^2 + z^2) < 12; predicate + sage: TripleDigits = ZZ^3 # optional - sage.modules + sage: predicate(x, y, z) = sqrt(x^2 + y^2 + z^2) < 12; predicate # optional - sage.symbolic (x, y, z) |--> sqrt(x^2 + y^2 + z^2) < 12 - sage: SmallTriples = ConditionSet(ZZ^3, predicate); SmallTriples + sage: SmallTriples = ConditionSet(ZZ^3, predicate); SmallTriples # optional - sage.symbolic { (x, y, z) ∈ Ambient free module of rank 3 over the principal ideal domain Integer Ring : sqrt(x^2 + y^2 + z^2) < 12 } - sage: predicate = SmallTriples._predicates[0] - sage: element = TripleDigits((1, 2, 3)) - sage: SmallTriples._call_predicate(predicate, element) + sage: predicate = SmallTriples._predicates[0] # optional - sage.symbolic + sage: element = TripleDigits((1, 2, 3)) # optional - sage.symbolic + sage: SmallTriples._call_predicate(predicate, element) # optional - sage.symbolic sqrt(14) < 12 - sage: var('t') + sage: var('t') # optional - sage.symbolic t - sage: TinyUniverse = ZZ^0 - sage: Nullary = ConditionSet(TinyUniverse, t > 0, vars=()) - sage: predicate = Nullary._predicates[0] - sage: element = TinyUniverse(0) - sage: Nullary._call_predicate(predicate, element) + sage: TinyUniverse = ZZ^0 # optional - sage.modules + sage: Nullary = ConditionSet(TinyUniverse, t > 0, vars=()) # optional - sage.symbolic + sage: predicate = Nullary._predicates[0] # optional - sage.symbolic + sage: element = TinyUniverse(0) # optional - sage.symbolic + sage: Nullary._call_predicate(predicate, element) # optional - sage.symbolic t > 0 """ if isinstance(predicate, Expression) and predicate.is_callable(): @@ -372,13 +373,13 @@ def _an_element_(self): TESTS:: - sage: TripleDigits = ZZ^3 - sage: predicate(x, y, z) = sqrt(x^2 + y^2 + z^2) < 12; predicate + sage: TripleDigits = ZZ^3 # optional - sage.modules + sage: predicate(x, y, z) = sqrt(x^2 + y^2 + z^2) < 12; predicate # optional - sage.symbolic (x, y, z) |--> sqrt(x^2 + y^2 + z^2) < 12 - sage: SmallTriples = ConditionSet(ZZ^3, predicate); SmallTriples + sage: SmallTriples = ConditionSet(ZZ^3, predicate); SmallTriples # optional - sage.symbolic { (x, y, z) ∈ Ambient free module of rank 3 over the principal ideal domain Integer Ring : sqrt(x^2 + y^2 + z^2) < 12 } - sage: SmallTriples.an_element() # indirect doctest + sage: SmallTriples.an_element() # indirect doctest # optional - sage.symbolic (1, 0, 0) """ for element in self._universe.some_elements(): @@ -406,17 +407,17 @@ def _sympy_(self): EXAMPLES:: - sage: predicate(x, y, z) = sqrt(x^2 + y^2 + z^2) < 12; predicate + sage: predicate(x, y, z) = sqrt(x^2 + y^2 + z^2) < 12; predicate # optional - sage.symbolic (x, y, z) |--> sqrt(x^2 + y^2 + z^2) < 12 - sage: SmallTriples = ConditionSet(ZZ^3, predicate); SmallTriples + sage: SmallTriples = ConditionSet(ZZ^3, predicate); SmallTriples # optional - sage.symbolic { (x, y, z) ∈ Ambient free module of rank 3 over the principal ideal domain Integer Ring : sqrt(x^2 + y^2 + z^2) < 12 } - sage: ST = SmallTriples._sympy_(); ST + sage: ST = SmallTriples._sympy_(); ST # optional - sage.symbolic ConditionSet((x, y, z), sqrt(x**2 + y**2 + z**2) < 12, ProductSet(Integers, Integers, Integers)) - sage: (1, 3, 5) in ST + sage: (1, 3, 5) in ST # optional - sage.symbolic True - sage: (5, 7, 9) in ST + sage: (5, 7, 9) in ST # optional - sage.symbolic False sage: Interval = ConditionSet(RR, x >= -7, x <= 4, vars=[x]); Interval @@ -463,15 +464,16 @@ def intersection(self, X): EXAMPLES:: - sage: in_small_oblong(x, y) = x^2 + 3 * y^2 <= 42 - sage: SmallOblongUniverse = ConditionSet(QQ^2, in_small_oblong) - sage: SmallOblongUniverse - { (x, y) ∈ Vector space of dimension 2 over Rational Field : x^2 + 3*y^2 <= 42 } - sage: parity_check(x, y) = abs(sin(pi/2*(x + y))) < 1/1000 - sage: EvenUniverse = ConditionSet(ZZ^2, parity_check); EvenUniverse + sage: in_small_oblong(x, y) = x^2 + 3 * y^2 <= 42 # optional - sage.symbolic + sage: SmallOblongUniverse = ConditionSet(QQ^2, in_small_oblong) # optional - sage.symbolic + sage: SmallOblongUniverse # optional - sage.symbolic + { (x, y) ∈ Vector space of dimension 2 + over Rational Field : x^2 + 3*y^2 <= 42 } + sage: parity_check(x, y) = abs(sin(pi/2*(x + y))) < 1/1000 # optional - sage.symbolic + sage: EvenUniverse = ConditionSet(ZZ^2, parity_check); EvenUniverse # optional - sage.symbolic { (x, y) ∈ Ambient free module of rank 2 over the principal ideal domain Integer Ring : abs(sin(1/2*pi*x + 1/2*pi*y)) < (1/1000) } - sage: SmallOblongUniverse & EvenUniverse + sage: SmallOblongUniverse & EvenUniverse # optional - sage.symbolic { (x, y) ∈ Free module of degree 2 and rank 2 over Integer Ring Echelon basis matrix: [1 0] @@ -480,13 +482,17 @@ def intersection(self, X): Combining two ``ConditionSet``s with different formal variables works correctly. The formal variables of the intersection are taken from ``self``:: - sage: SmallMirrorUniverse = ConditionSet(QQ^2, in_small_oblong, vars=(y, x)) - sage: SmallMirrorUniverse - { (y, x) ∈ Vector space of dimension 2 over Rational Field : 3*x^2 + y^2 <= 42 } - sage: SmallOblongUniverse & SmallMirrorUniverse - { (x, y) ∈ Vector space of dimension 2 over Rational Field : x^2 + 3*y^2 <= 42 } - sage: SmallMirrorUniverse & SmallOblongUniverse - { (y, x) ∈ Vector space of dimension 2 over Rational Field : 3*x^2 + y^2 <= 42 } + sage: SmallMirrorUniverse = ConditionSet(QQ^2, in_small_oblong, # optional - sage.symbolic + ....: vars=(y, x)) + sage: SmallMirrorUniverse # optional - sage.symbolic + { (y, x) ∈ Vector space of dimension 2 + over Rational Field : 3*x^2 + y^2 <= 42 } + sage: SmallOblongUniverse & SmallMirrorUniverse # optional - sage.symbolic + { (x, y) ∈ Vector space of dimension 2 + over Rational Field : x^2 + 3*y^2 <= 42 } + sage: SmallMirrorUniverse & SmallOblongUniverse # optional - sage.symbolic + { (y, x) ∈ Vector space of dimension 2 + over Rational Field : 3*x^2 + y^2 <= 42 } """ if isinstance(X, ConditionSet): return ConditionSet(self.ambient().intersection(X.ambient()), diff --git a/src/sage/sets/disjoint_union_enumerated_sets.py b/src/sage/sets/disjoint_union_enumerated_sets.py index 8e272984619..c8497e3d9b4 100644 --- a/src/sage/sets/disjoint_union_enumerated_sets.py +++ b/src/sage/sets/disjoint_union_enumerated_sets.py @@ -89,30 +89,32 @@ class DisjointUnionEnumeratedSets(UniqueRepresentation, Parent): In general the input can be any family:: - sage: U3 = DisjointUnionEnumeratedSets( + sage: U3 = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family([2,3,4], Permutations, lazy=True)) - sage: U3 - Disjoint union of Lazy family ((i))_{i in [2, 3, 4]} - sage: U3.cardinality() + sage: U3 # optional - sage.combinat + Disjoint union of Lazy family + ((i))_{i in [2, 3, 4]} + sage: U3.cardinality() # optional - sage.combinat 32 - sage: it = iter(U3) - sage: [next(it), next(it), next(it), next(it), next(it), next(it)] + sage: it = iter(U3) # optional - sage.combinat + sage: [next(it), next(it), next(it), next(it), next(it), next(it)] # optional - sage.combinat [[1, 2], [2, 1], [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1]] - sage: U3.unrank(18) + sage: U3.unrank(18) # optional - sage.combinat [2, 4, 1, 3] This allows for infinite unions:: - sage: U4 = DisjointUnionEnumeratedSets( + sage: U4 = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family(NonNegativeIntegers(), Permutations)) - sage: U4 - Disjoint union of Lazy family ((i))_{i in Non negative integers} - sage: U4.cardinality() + sage: U4 # optional - sage.combinat + Disjoint union of Lazy family + ((i))_{i in Non negative integers} + sage: U4.cardinality() # optional - sage.combinat +Infinity - sage: it = iter(U4) - sage: [next(it), next(it), next(it), next(it), next(it), next(it)] + sage: it = iter(U4) # optional - sage.combinat + sage: [next(it), next(it), next(it), next(it), next(it), next(it)] # optional - sage.combinat [[], [1], [1, 2], [2, 1], [1, 2, 3], [1, 3, 2]] - sage: U4.unrank(18) + sage: U4.unrank(18) # optional - sage.combinat [2, 3, 1, 4] .. WARNING:: @@ -125,41 +127,41 @@ class DisjointUnionEnumeratedSets(UniqueRepresentation, Parent): We demonstrate the ``keepkey`` option:: - sage: Ukeep = DisjointUnionEnumeratedSets( + sage: Ukeep = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family(list(range(4)), Permutations), keepkey=True) - sage: it = iter(Ukeep) - sage: [next(it) for i in range(6)] + sage: it = iter(Ukeep) # optional - sage.combinat + sage: [next(it) for i in range(6)] # optional - sage.combinat [(0, []), (1, [1]), (2, [1, 2]), (2, [2, 1]), (3, [1, 2, 3]), (3, [1, 3, 2])] - sage: type(next(it)[1]) + sage: type(next(it)[1]) # optional - sage.combinat We now demonstrate the ``facade`` option:: - sage: UNoFacade = DisjointUnionEnumeratedSets( + sage: UNoFacade = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family(list(range(4)), Permutations), facade=False) - sage: it = iter(UNoFacade) - sage: [next(it) for i in range(6)] + sage: it = iter(UNoFacade) # optional - sage.combinat + sage: [next(it) for i in range(6)] # optional - sage.combinat [[], [1], [1, 2], [2, 1], [1, 2, 3], [1, 3, 2]] - sage: el = next(it); el + sage: el = next(it); el # optional - sage.combinat [2, 1, 3] - sage: type(el) + sage: type(el) # optional - sage.combinat <... 'sage.structure.element_wrapper.ElementWrapper'> - sage: el.parent() == UNoFacade + sage: el.parent() == UNoFacade # optional - sage.combinat True - sage: elv = el.value; elv + sage: elv = el.value; elv # optional - sage.combinat [2, 1, 3] - sage: type(elv) + sage: type(elv) # optional - sage.combinat The elements ``el`` of the disjoint union are simple wrapped elements. So to access the methods, you need to do ``el.value``:: - sage: el[0] + sage: el[0] # optional - sage.combinat Traceback (most recent call last): ... TypeError: 'sage.structure.element_wrapper.ElementWrapper' object is not subscriptable - sage: el.value[0] + sage: el.value[0] # optional - sage.combinat 2 Possible extensions: the current enumeration order is not suitable @@ -181,12 +183,12 @@ class DisjointUnionEnumeratedSets(UniqueRepresentation, Parent): :class:`DisjointUnionEnumeratedSets`. Then, one simply writes the ``__init__`` method as usual:: - sage: class MyUnion(DisjointUnionEnumeratedSets): + sage: class MyUnion(DisjointUnionEnumeratedSets): # optional - sage.combinat ....: def __init__(self): ....: DisjointUnionEnumeratedSets.__init__(self, ....: Family([1,2], Permutations)) - sage: pp = MyUnion() - sage: pp.list() + sage: pp = MyUnion() # optional - sage.combinat + sage: pp.list() # optional - sage.combinat [[1], [1, 2], [2, 1]] In case the :meth:`__init__` method takes optional arguments, @@ -201,19 +203,21 @@ class DisjointUnionEnumeratedSets(UniqueRepresentation, Parent): sage: class UnionOfSpecialSets(DisjointUnionEnumeratedSets): ....: __classcall_private__ = staticmethod(DisjointUnionEnumeratedSets.__classcall_private__) - sage: psp = UnionOfSpecialSets(Family([1,2], Permutations)) - sage: psp.list() + sage: psp = UnionOfSpecialSets(Family([1,2], Permutations)) # optional - sage.combinat + sage: psp.list() # optional - sage.combinat [[1], [1, 2], [2, 1]] TESTS:: sage: TestSuite(U1).run() sage: TestSuite(U2).run() - sage: TestSuite(U3).run() - sage: TestSuite(U4).run() - doctest:...: UserWarning: Disjoint union of Lazy family ((i))_{i in Non negative integers} is an infinite union + sage: TestSuite(U3).run() # optional - sage.combinat + sage: TestSuite(U4).run() # optional - sage.combinat + doctest:...: UserWarning: Disjoint union of Lazy family + ((i))_{i in Non negative integers} + is an infinite union The default implementation of __contains__ can loop forever. Please overload it. - sage: TestSuite(UNoFacade).run() + sage: TestSuite(UNoFacade).run() # optional - sage.combinat We skip ``_test_an_element`` because the coercion framework does not currently allow a tuple to be returned for facade parents:: @@ -225,11 +229,11 @@ class DisjointUnionEnumeratedSets(UniqueRepresentation, Parent): been defined interactively:: sage: import __main__ - sage: __main__.MyUnion = MyUnion + sage: __main__.MyUnion = MyUnion # optional - sage.combinat sage: __main__.UnionOfSpecialSets = UnionOfSpecialSets - sage: TestSuite(pp).run() - sage: TestSuite(psp).run() + sage: TestSuite(pp).run() # optional - sage.combinat + sage: TestSuite(psp).run() # optional - sage.combinat """ @@ -322,10 +326,12 @@ def _is_a(self, x): EXAMPLES:: - sage: U4 = DisjointUnionEnumeratedSets( + sage: U4 = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family(NonNegativeIntegers(), Compositions)) - sage: U4._is_a(Composition([3,2,1,1])) - doctest:...: UserWarning: Disjoint union of Lazy family ((i))_{i in Non negative integers} is an infinite union + sage: U4._is_a(Composition([3,2,1,1])) # optional - sage.combinat + doctest:...: UserWarning: Disjoint union of Lazy family + ((i))_{i in Non negative integers} + is an infinite union The default implementation of __contains__ can loop forever. Please overload it. True """ @@ -351,17 +357,19 @@ def __contains__(self, x): EXAMPLES:: - sage: U4 = DisjointUnionEnumeratedSets( + sage: U4 = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family(NonNegativeIntegers(), Partitions)) - sage: Partition([]) in U4 - doctest:...: UserWarning: Disjoint union of Lazy family ((i))_{i in Non negative integers} is an infinite union + sage: Partition([]) in U4 # optional - sage.combinat + doctest:...: UserWarning: Disjoint union of Lazy family + ((i))_{i in Non negative integers} + is an infinite union The default implementation of __contains__ can loop forever. Please overload it. True Note: one has to use a different family from the previous one in this file otherwise the warning is not re-issued:: - sage: Partition([3,2,1,1]) in U4 + sage: Partition([3,2,1,1]) in U4 # optional - sage.combinat True The following call will loop forever:: @@ -380,21 +388,21 @@ def __iter__(self): """ TESTS:: - sage: U4 = DisjointUnionEnumeratedSets( + sage: U4 = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family(NonNegativeIntegers(), Permutations)) - sage: it = iter(U4) - sage: [next(it), next(it), next(it), next(it), next(it), next(it)] + sage: it = iter(U4) # optional - sage.combinat + sage: [next(it), next(it), next(it), next(it), next(it), next(it)] # optional - sage.combinat [[], [1], [1, 2], [2, 1], [1, 2, 3], [1, 3, 2]] - sage: U4 = DisjointUnionEnumeratedSets( + sage: U4 = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family(NonNegativeIntegers(), Permutations), ....: keepkey=True, facade=False) - sage: it = iter(U4) - sage: [next(it), next(it), next(it), next(it), next(it), next(it)] + sage: it = iter(U4) # optional - sage.combinat + sage: [next(it), next(it), next(it), next(it), next(it), next(it)] # optional - sage.combinat [(0, []), (1, [1]), (2, [1, 2]), (2, [2, 1]), (3, [1, 2, 3]), (3, [1, 3, 2])] - sage: el = next(it); el.parent() == U4 + sage: el = next(it); el.parent() == U4 # optional - sage.combinat True - sage: el.value == (3, Permutation([2,1,3])) + sage: el.value == (3, Permutation([2,1,3])) # optional - sage.combinat True """ for k in self._family.keys(): @@ -413,7 +421,7 @@ def an_element(self): EXAMPLES:: - sage: U4 = DisjointUnionEnumeratedSets( + sage: U4 = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family([3, 5, 7], Permutations)) sage: U4.an_element() [1, 2, 3] @@ -430,16 +438,16 @@ def cardinality(self): For finite disjoint unions, the cardinality is computed by summing the cardinalities of the enumerated sets:: - sage: U = DisjointUnionEnumeratedSets(Family([0,1,2,3], Permutations)) - sage: U.cardinality() + sage: U = DisjointUnionEnumeratedSets(Family([0,1,2,3], Permutations)) # optional - sage.combinat + sage: U.cardinality() # optional - sage.combinat 10 For infinite disjoint unions, this makes the assumption that the result is infinite:: - sage: U = DisjointUnionEnumeratedSets( + sage: U = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family(NonNegativeIntegers(), Permutations)) - sage: U.cardinality() + sage: U.cardinality() # optional - sage.combinat +Infinity .. WARNING:: @@ -462,14 +470,14 @@ def _element_constructor_(self): """ TESTS:: - sage: U = DisjointUnionEnumeratedSets( + sage: U = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family([1,2,3], Partitions), facade=False) - sage: U._element_constructor_ + sage: U._element_constructor_ # optional - sage.combinat - sage: U = DisjointUnionEnumeratedSets( + sage: U = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family([1,2,3], Partitions), facade=True) - sage: U._element_constructor_ + sage: U._element_constructor_ # optional - sage.combinat """ @@ -482,13 +490,13 @@ def _element_constructor_default(self, el): r""" TESTS:: - sage: U = DisjointUnionEnumeratedSets( + sage: U = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family([1,2,3], Partitions), facade=False) - sage: U([1]) # indirect doctest + sage: U([1]) # indirect doctest # optional - sage.combinat [1] - sage: U([2,1]) # indirect doctest + sage: U([2,1]) # indirect doctest # optional - sage.combinat [2, 1] - sage: U([1,3,2]) # indirect doctest + sage: U([1,3,2]) # indirect doctest # optional - sage.combinat Traceback (most recent call last): ... ValueError: value [1, 3, 2] does not belong to Disjoint union of @@ -496,13 +504,13 @@ def _element_constructor_default(self, el): 2: Partitions of the integer 2, 3: Partitions of the integer 3} - sage: U = DisjointUnionEnumeratedSets( + sage: U = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family([1,2,3], Partitions), keepkey=True, facade=False) - sage: U((1, [1])) # indirect doctest + sage: U((1, [1])) # indirect doctest # optional - sage.combinat (1, [1]) - sage: U((3,[2,1])) # indirect doctest + sage: U((3,[2,1])) # indirect doctest # optional - sage.combinat (3, [2, 1]) - sage: U((4,[2,1])) # indirect doctest + sage: U((4,[2,1])) # indirect doctest # optional - sage.combinat Traceback (most recent call last): ... ValueError: value (4, [2, 1]) does not belong to Disjoint union of @@ -521,12 +529,12 @@ def _element_constructor_facade(self, el): """ TESTS:: - sage: X = DisjointUnionEnumeratedSets({i: Partitions(i) for i in range(5)}) - sage: X([1]).parent() + sage: X = DisjointUnionEnumeratedSets({i: Partitions(i) for i in range(5)}) # optional - sage.combinat + sage: X([1]).parent() # optional - sage.combinat Partitions of the integer 1 - sage: X([2,1,1]).parent() # indirect doctest + sage: X([2,1,1]).parent() # indirect doctest # optional - sage.combinat Partitions of the integer 4 - sage: X([6]) + sage: X([6]) # optional - sage.combinat Traceback (most recent call last): ... ValueError: cannot coerce `[6]` in any parent in `Finite family {...}` @@ -535,23 +543,23 @@ def _element_constructor_facade(self, el): because this returns a `tuple`, where the coercion framework requires an :class:`Element` be returned. - sage: X = DisjointUnionEnumeratedSets({i: Partitions(i) for i in range(5)}, + sage: X = DisjointUnionEnumeratedSets({i: Partitions(i) for i in range(5)}, # optional - sage.combinat ....: keepkey=True) - sage: p = X._element_constructor_((0, [])) # indirect doctest - sage: p[1].parent() + sage: p = X._element_constructor_((0, [])) # indirect doctest # optional - sage.combinat + sage: p[1].parent() # optional - sage.combinat Partitions of the integer 0 Test that facade parents can create and properly access elements that are tuples (fixed by :trac:`22382`):: - sage: f = lambda mu: cartesian_product([mu.standard_tableaux(), + sage: f = lambda mu: cartesian_product([mu.standard_tableaux(), # optional - sage.combinat ....: mu.standard_tableaux()]) - sage: tabs = DisjointUnionEnumeratedSets(Family(Partitions(4), f)) - sage: s = StandardTableau([[1,3],[2,4]]) - sage: (s,s) in tabs + sage: tabs = DisjointUnionEnumeratedSets(Family(Partitions(4), f)) # optional - sage.combinat + sage: s = StandardTableau([[1,3],[2,4]]) # optional - sage.combinat + sage: (s,s) in tabs # optional - sage.combinat True - sage: ss = tabs( (s,s) ) - sage: ss[0] + sage: ss = tabs( (s,s) ) # optional - sage.combinat + sage: ss[0] # optional - sage.combinat [[1, 3], [2, 4]] We do not coerce when one of the elements is already in the set:: @@ -587,13 +595,13 @@ def Element(self): """ TESTS:: - sage: U = DisjointUnionEnumeratedSets( + sage: U = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family([1,2,3], Partitions), facade=False) - sage: U.Element + sage: U.Element # optional - sage.combinat <... 'sage.structure.element_wrapper.ElementWrapper'> - sage: U = DisjointUnionEnumeratedSets( + sage: U = DisjointUnionEnumeratedSets( # optional - sage.combinat ....: Family([1,2,3], Partitions), facade=True) - sage: U.Element + sage: U.Element # optional - sage.combinat Traceback (most recent call last): ... AttributeError: 'DisjointUnionEnumeratedSets_with_category' object has no attribute 'Element' diff --git a/src/sage/sets/family.py b/src/sage/sets/family.py index 10c59a02490..bd4052a58e6 100644 --- a/src/sage/sets/family.py +++ b/src/sage/sets/family.py @@ -1064,7 +1064,7 @@ def _repr_(self): Check that using a class as the function is correctly handled:: - sage: Family(NonNegativeIntegers(), PerfectMatchings) + sage: Family(NonNegativeIntegers(), PerfectMatchings) # optional - sage.combinat Lazy family ((i))_{i in Non negative integers} """ if self.function_name is not None: diff --git a/src/sage/sets/image_set.py b/src/sage/sets/image_set.py index 54b78eede7a..65676989403 100644 --- a/src/sage/sets/image_set.py +++ b/src/sage/sets/image_set.py @@ -73,12 +73,12 @@ def __init__(self, map, domain_subset, *, category=None, is_injective=None, inve EXAMPLES:: - sage: M = CombinatorialFreeModule(ZZ, [0,1,2,3]) + sage: M = CombinatorialFreeModule(ZZ, [0,1,2,3]) # optional - sage.modules sage: R. = QQ[] - sage: H = Hom(M, R, category=Sets()) - sage: f = H(lambda v: v[0]*x + v[1]*(x^2-y) + v[2]^2*(y+2) + v[3] - v[0]^2) - sage: Im = f.image() - sage: TestSuite(Im).run(skip=['_test_an_element', '_test_pickling', + sage: H = Hom(M, R, category=Sets()) # optional - sage.modules + sage: f = H(lambda v: v[0]*x + v[1]*(x^2-y) + v[2]^2*(y+2) + v[3] - v[0]^2) # optional - sage.modules + sage: Im = f.image() # optional - sage.modules + sage: TestSuite(Im).run(skip=['_test_an_element', '_test_pickling', # optional - sage.modules ....: '_test_some_elements', '_test_elements']) """ if not is_Parent(domain_subset): @@ -173,20 +173,20 @@ def ambient(self): EXAMPLES:: - sage: M = CombinatorialFreeModule(QQ, [0, 1, 2, 3]) - sage: R. = ZZ[] - sage: H = Hom(M, R, category=Sets()) - sage: f = H(lambda v: floor(v[0])*x + ceil(v[3] - v[0]^2)) - sage: Im = f.image() - sage: Im.ambient() is R + sage: M = CombinatorialFreeModule(QQ, [0, 1, 2, 3]) # optional - sage.modules + sage: R. = ZZ[] # optional - sage.modules + sage: H = Hom(M, R, category=Sets()) # optional - sage.modules + sage: f = H(lambda v: floor(v[0])*x + ceil(v[3] - v[0]^2)) # optional - sage.modules + sage: Im = f.image() # optional - sage.modules + sage: Im.ambient() is R # optional - sage.modules True - sage: P = Partitions(3).map(attrcall('conjugate')) - sage: P.ambient() is None + sage: P = Partitions(3).map(attrcall('conjugate')) # optional - sage.combinat + sage: P.ambient() is None # optional - sage.combinat True - sage: R = Permutations(10).map(attrcall('reduced_word')) - sage: R.ambient() is None + sage: R = Permutations(10).map(attrcall('reduced_word')) # optional - sage.combinat + sage: R.ambient() is None # optional - sage.combinat True """ return self._map.codomain() @@ -197,14 +197,14 @@ def lift(self, x): EXAMPLES:: - sage: M = CombinatorialFreeModule(QQ, [0, 1, 2, 3]) + sage: M = CombinatorialFreeModule(QQ, [0, 1, 2, 3]) # optional - sage.modules sage: R. = ZZ[] - sage: H = Hom(M, R, category=Sets()) - sage: f = H(lambda v: floor(v[0])*x + ceil(v[3] - v[0]^2)) - sage: Im = f.image() - sage: p = Im.lift(Im.an_element()); p + sage: H = Hom(M, R, category=Sets()) # optional - sage.modules + sage: f = H(lambda v: floor(v[0])*x + ceil(v[3] - v[0]^2)) # optional - sage.modules + sage: Im = f.image() # optional - sage.modules + sage: p = Im.lift(Im.an_element()); p # optional - sage.modules 2*x - 4 - sage: p.parent() is R + sage: p.parent() is R # optional - sage.modules True """ return x @@ -219,13 +219,13 @@ def retract(self, x): EXAMPLES:: - sage: M = CombinatorialFreeModule(QQ, [0, 1, 2, 3]) - sage: R. = ZZ[] - sage: H = Hom(M, R, category=Sets()) - sage: f = H(lambda v: floor(v[0])*x + ceil(v[3] - v[0]^2)) - sage: Im = f.image() - sage: p = 2 * x - 4 - sage: Im.retract(p).parent() + sage: M = CombinatorialFreeModule(QQ, [0, 1, 2, 3]) # optional - sage.modules + sage: R. = ZZ[] # optional - sage.modules + sage: H = Hom(M, R, category=Sets()) # optional - sage.modules + sage: f = H(lambda v: floor(v[0])*x + ceil(v[3] - v[0]^2)) # optional - sage.modules + sage: Im = f.image() # optional - sage.modules + sage: p = 2 * x - 4 # optional - sage.modules + sage: Im.retract(p).parent() # optional - sage.modules Multivariate Polynomial Ring in x, y over Integer Ring """ return x @@ -234,7 +234,7 @@ def _repr_(self) -> str: r""" TESTS:: - sage: Partitions(3).map(attrcall('conjugate')) + sage: Partitions(3).map(attrcall('conjugate')) # optional - sage.combinat Image of Partitions of the integer 3 by The map *.conjugate() from Partitions of the integer 3 """ @@ -251,8 +251,8 @@ def cardinality(self) -> Integer: :meth:`~sage.categories.enumerated_sets.EnumeratedSets.ParentMethods.map` defaults to ``is_injective=True``): - sage: R = Permutations(10).map(attrcall('reduced_word')) - sage: R.cardinality() + sage: R = Permutations(10).map(attrcall('reduced_word')) # optional - sage.combinat + sage: R.cardinality() # optional - sage.combinat 3628800 sage: Evens = ZZ.map(lambda x: 2 * x) @@ -294,12 +294,12 @@ def __iter__(self) -> Iterator: EXAMPLES:: - sage: P = Partitions() - sage: H = Hom(P, ZZ) - sage: f = H(ZZ.sum) - sage: X = f.image() - sage: it = iter(X) - sage: [next(it) for _ in range(5)] + sage: P = Partitions() # optional - sage.combinat + sage: H = Hom(P, ZZ) # optional - sage.combinat + sage: f = H(ZZ.sum) # optional - sage.combinat + sage: X = f.image() # optional - sage.combinat + sage: it = iter(X) # optional - sage.combinat + sage: [next(it) for _ in range(5)] # optional - sage.combinat [0, 1, 2, 3, 4] """ if self._is_injective and self._is_injective != 'check': @@ -322,8 +322,8 @@ def _an_element_(self): EXAMPLES:: - sage: R = SymmetricGroup(10).map(attrcall('reduced_word')) - sage: R.an_element() + sage: R = SymmetricGroup(10).map(attrcall('reduced_word')) # optional - sage.groups + sage: R.an_element() # optional - sage.groups [9, 8, 7, 6, 5, 4, 3, 2] """ domain_element = self._domain_subset.an_element() @@ -336,9 +336,9 @@ def _sympy_(self): EXAMPLES:: sage: from sage.sets.image_set import ImageSet - sage: S = ImageSet(sin, RealSet.open(0, pi/4)); S + sage: S = ImageSet(sin, RealSet.open(0, pi/4)); S # optional - sage.symbolic Image of (0, 1/4*pi) by The map sin from (0, 1/4*pi) - sage: S._sympy_() + sage: S._sympy_() # optional - sage.symbolic ImageSet(Lambda(x, sin(x)), Interval.open(0, pi/4)) """ from sympy import imageset @@ -360,23 +360,23 @@ class ImageSet(ImageSubobject, Set_base, Set_add_sub_operators, Set_boolean_oper Symbolics:: - sage: ImageSet(sin, RealSet.open(0, pi/4)) + sage: ImageSet(sin, RealSet.open(0, pi/4)) # optional - sage.symbolic Image of (0, 1/4*pi) by The map sin from (0, 1/4*pi) - sage: _.an_element() + sage: _.an_element() # optional - sage.symbolic 1/2*sqrt(-sqrt(2) + 2) - sage: sos(x,y) = x^2 + y^2; sos + sage: sos(x,y) = x^2 + y^2; sos # optional - sage.symbolic (x, y) |--> x^2 + y^2 - sage: ImageSet(sos, ZZ^2) + sage: ImageSet(sos, ZZ^2) # optional - sage.symbolic Image of Ambient free module of rank 2 over the principal ideal domain Integer Ring by The map (x, y) |--> x^2 + y^2 from Vector space of dimension 2 over Symbolic Ring - sage: _.an_element() + sage: _.an_element() # optional - sage.symbolic 1 - sage: ImageSet(sos, Set([(3, 4), (3, -4)])) + sage: ImageSet(sos, Set([(3, 4), (3, -4)])) # optional - sage.symbolic Image of {...(3, -4)...} by The map (x, y) |--> x^2 + y^2 from Vector space of dimension 2 over Symbolic Ring - sage: _.an_element() + sage: _.an_element() # optional - sage.symbolic 25 """ pass diff --git a/src/sage/sets/non_negative_integers.py b/src/sage/sets/non_negative_integers.py index 29edc3a11a1..8caf33deacb 100644 --- a/src/sage/sets/non_negative_integers.py +++ b/src/sage/sets/non_negative_integers.py @@ -100,15 +100,15 @@ def __contains__(self, elt): True sage: -1 in NN False - sage: x in NN + sage: x in NN # optional - sage.symbolic False sage: None in NN False - sage: QQbar(sqrt(2)) in NN + sage: QQbar(sqrt(2)) in NN # optional - sage.symbolic sage.rings.number_field False sage: RIF(1,2) in NN False - sage: QQbar(2) in NN + sage: QQbar(2) in NN # optional - sage.rings.number_field True sage: RIF(2) in NN True @@ -133,7 +133,7 @@ def _element_constructor_(self, i): Traceback (most recent call last): ... ValueError: Value -5 in not in Non negative integers. - sage: NN._element_constructor_(x) + sage: NN._element_constructor_(x) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Value x in not in Non negative integers. @@ -230,7 +230,7 @@ def _sympy_(self): EXAMPLES:: sage: NN = NonNegativeIntegers() - sage: NN._sympy_() + sage: NN._sympy_() # optional - sympy Naturals0 """ from sympy import Naturals0 diff --git a/src/sage/sets/positive_integers.py b/src/sage/sets/positive_integers.py index 7ed7d9657e9..34e1d77b05e 100644 --- a/src/sage/sets/positive_integers.py +++ b/src/sage/sets/positive_integers.py @@ -82,7 +82,7 @@ def _sympy_(self): EXAMPLES:: - sage: PositiveIntegers()._sympy_() + sage: PositiveIntegers()._sympy_() # optional - sympy Naturals """ from sympy import Naturals diff --git a/src/sage/sets/primes.py b/src/sage/sets/primes.py index 96558ba9215..d2fa00f4a44 100644 --- a/src/sage/sets/primes.py +++ b/src/sage/sets/primes.py @@ -123,7 +123,7 @@ def __contains__(self, x): False sage: 1.5 in P False - sage: e in P + sage: e in P # optional - sage.symbolic False """ try: diff --git a/src/sage/sets/real_set.py b/src/sage/sets/real_set.py index 47a0505de6b..b27c14e6a7f 100644 --- a/src/sage/sets/real_set.py +++ b/src/sage/sets/real_set.py @@ -48,24 +48,24 @@ Relations containing symbols and numeric values or constants:: - sage: RealSet(x != 0) + sage: RealSet(x != 0) # optional - sage.symbolic (-oo, 0) ∪ (0, +oo) - sage: RealSet(x == pi) + sage: RealSet(x == pi) # optional - sage.symbolic {pi} - sage: RealSet(x < 1/2) + sage: RealSet(x < 1/2) # optional - sage.symbolic (-oo, 1/2) - sage: RealSet(1/2 < x) + sage: RealSet(1/2 < x) # optional - sage.symbolic (1/2, +oo) - sage: RealSet(1.5 <= x) + sage: RealSet(1.5 <= x) # optional - sage.symbolic [1.50000000000000, +oo) Note that multiple arguments are combined as union:: - sage: RealSet(x >= 0, x < 1) + sage: RealSet(x >= 0, x < 1) # optional - sage.symbolic (-oo, +oo) - sage: RealSet(x >= 0, x > 1) + sage: RealSet(x >= 0, x > 1) # optional - sage.symbolic [0, +oo) - sage: RealSet(x >= 0, x > -1) + sage: RealSet(x >= 0, x > -1) # optional - sage.symbolic (-1, +oo) AUTHORS: @@ -406,9 +406,9 @@ def _latex_(self): EXAMPLES:: - sage: RealSet.open_closed(1/2, pi)._latex_() + sage: RealSet.open_closed(1/2, pi)._latex_() # optional - sage.symbolic '(\\frac{1}{2}, \\pi]' - sage: (RealSet.point(sqrt(2)))._latex_() + sage: (RealSet.point(sqrt(2)))._latex_() # optional - sage.symbolic '\\{\\sqrt{2}\\}' """ from sage.misc.latex import latex @@ -435,7 +435,7 @@ def _sympy_condition_(self, variable): EXAMPLES:: - sage: RealSet(0, 4)._sympy_condition_(x) + sage: RealSet(0, 4)._sympy_condition_(x) # optional - sage.symbolic (0 < x) & (x < 4) """ x = variable @@ -494,7 +494,7 @@ def _giac_condition_(self, variable): EXAMPLES:: - sage: RealSet(0, 4)._giac_condition_(x) + sage: RealSet(0, 4)._giac_condition_(x) # optional - sage.symbolic '((0 < sageVARx) and (sageVARx < 4))' """ x = variable @@ -985,30 +985,32 @@ class RealSet(UniqueRepresentation, Parent, Set_base, sage: i1, i2 = s1[0], s2[0] sage: RealSet(i2, i1) # union of intervals (1, 2) ∪ [3, 4] - sage: RealSet((-oo, 0), x > 6, i1, RealSet.point(5), RealSet.closed_open(4, 3)) + sage: RealSet((-oo, 0), x > 6, i1, RealSet.point(5), # optional - sage.symbolic + ....: RealSet.closed_open(4, 3)) (-oo, 0) ∪ (1, 2) ∪ [3, 4) ∪ {5} ∪ (6, +oo) Initialization from manifold objects:: - sage: R = manifolds.RealLine(); R + sage: R = manifolds.RealLine(); R # optional - sage.symbolic Real number line ℝ - sage: RealSet(R) + sage: RealSet(R) # optional - sage.symbolic (-oo, +oo) - sage: I02 = manifolds.OpenInterval(0, 2); I + sage: I02 = manifolds.OpenInterval(0, 2); I # optional - sage.symbolic I - sage: RealSet(I02) + sage: RealSet(I02) # optional - sage.symbolic (0, 2) - sage: I01_of_R = manifolds.OpenInterval(0, 1, ambient_interval=R); I01_of_R + sage: I01_of_R = manifolds.OpenInterval(0, 1, ambient_interval=R); I01_of_R # optional - sage.symbolic Real interval (0, 1) - sage: RealSet(I01_of_R) + sage: RealSet(I01_of_R) # optional - sage.symbolic (0, 1) - sage: RealSet(I01_of_R.closure()) + sage: RealSet(I01_of_R.closure()) # optional - sage.symbolic [0, 1] - sage: I01_of_I02 = manifolds.OpenInterval(0, 1, ambient_interval=I02); I01_of_I02 + sage: I01_of_I02 = manifolds.OpenInterval(0, 1, # optional - sage.symbolic + ....: ambient_interval=I02); I01_of_I02 Real interval (0, 1) - sage: RealSet(I01_of_I02) + sage: RealSet(I01_of_I02) # optional - sage.symbolic (0, 1) - sage: RealSet(I01_of_I02.closure()) + sage: RealSet(I01_of_I02.closure()) # optional - sage.symbolic (0, 1] Real sets belong to a subcategory of topological spaces:: @@ -1038,23 +1040,23 @@ class RealSet(UniqueRepresentation, Parent, Set_base, Constructing real sets as manifolds or manifold subsets by passing ``structure='differentiable'``:: - sage: RealSet(-oo, oo, structure='differentiable') + sage: RealSet(-oo, oo, structure='differentiable') # optional - sage.symbolic Real number line ℝ - sage: RealSet([0, 1], structure='differentiable') + sage: RealSet([0, 1], structure='differentiable') # optional - sage.symbolic Subset [0, 1] of the Real number line ℝ - sage: _.category() + sage: _.category() # optional - sage.symbolic Category of subobjects of sets - sage: RealSet.open_closed(0, 5, structure='differentiable') + sage: RealSet.open_closed(0, 5, structure='differentiable') # optional - sage.symbolic Subset (0, 5] of the Real number line ℝ This is implied when a coordinate name is given using the keywords ``coordinate`` or ``names``:: - sage: RealSet(0, 1, coordinate='λ') + sage: RealSet(0, 1, coordinate='λ') # optional - sage.symbolic Open subset (0, 1) of the Real number line ℝ - sage: _.category() + sage: _.category() # optional - sage.symbolic Join of Category of smooth manifolds over Real Field with 53 bits of precision and Category of connected manifolds over Real Field with 53 bits of precision and @@ -1062,44 +1064,44 @@ class RealSet(UniqueRepresentation, Parent, Set_base, It is also implied by assigning a coordinate name using generator notation:: - sage: R_xi.<ξ> = RealSet.real_line(); R_xi + sage: R_xi.<ξ> = RealSet.real_line(); R_xi # optional - sage.symbolic Real number line ℝ - sage: R_xi.canonical_chart() + sage: R_xi.canonical_chart() # optional - sage.symbolic Chart (ℝ, (ξ,)) With the keyword ``ambient``, we can construct a subset of a previously constructed manifold:: - sage: P_xi = RealSet(0, oo, ambient=R_xi); P_xi + sage: P_xi = RealSet(0, oo, ambient=R_xi); P_xi # optional - sage.symbolic Open subset (0, +oo) of the Real number line ℝ - sage: P_xi.default_chart() + sage: P_xi.default_chart() # optional - sage.symbolic Chart ((0, +oo), (ξ,)) - sage: B_xi = RealSet(0, 1, ambient=P_xi); B_xi + sage: B_xi = RealSet(0, 1, ambient=P_xi); B_xi # optional - sage.symbolic Open subset (0, 1) of the Real number line ℝ - sage: B_xi.default_chart() + sage: B_xi.default_chart() # optional - sage.symbolic Chart ((0, 1), (ξ,)) - sage: R_xi.subset_family() + sage: R_xi.subset_family() # optional - sage.symbolic Set {(0, +oo), (0, 1), ℝ} of open subsets of the Real number line ℝ - sage: F = RealSet.point(0).union(RealSet.point(1)).union(RealSet.point(2)); F + sage: F = RealSet.point(0).union(RealSet.point(1)).union(RealSet.point(2)); F # optional - sage.symbolic {0} ∪ {1} ∪ {2} - sage: F_tau = RealSet(F, names="τ"); F_tau + sage: F_tau = RealSet(F, names="τ"); F_tau # optional - sage.symbolic Subset {0} ∪ {1} ∪ {2} of the Real number line ℝ - sage: F_tau.manifold().canonical_chart() + sage: F_tau.manifold().canonical_chart() # optional - sage.symbolic Chart (ℝ, (τ,)) TESTS:: - sage: TestSuite(R_xi).run() - sage: TestSuite(P_xi).run() - sage: R_xi.point((1,)) in P_xi + sage: TestSuite(R_xi).run() # optional - sage.symbolic + sage: TestSuite(P_xi).run() # optional - sage.symbolic + sage: R_xi.point((1,)) in P_xi # optional - sage.symbolic True - sage: R_xi.point((-1,)) in P_xi + sage: R_xi.point((-1,)) in P_xi # optional - sage.symbolic False - sage: TestSuite(B_xi).run() - sage: p = B_xi.an_element(); p + sage: TestSuite(B_xi).run() # optional - sage.symbolic + sage: p = B_xi.an_element(); p # optional - sage.symbolic Point on the Real number line ℝ - sage: p.coordinates() + sage: p.coordinates() # optional - sage.symbolic (1/2,) """ @@ -1123,48 +1125,48 @@ def __classcall__(cls, *args, **kwds): TESTS:: - sage: RealSet(x != 0) + sage: RealSet(x != 0) # optional - sage.symbolic (-oo, 0) ∪ (0, +oo) - sage: RealSet(x == pi) + sage: RealSet(x == pi) # optional - sage.symbolic {pi} - sage: RealSet(x < 1/2) + sage: RealSet(x < 1/2) # optional - sage.symbolic (-oo, 1/2) - sage: RealSet(1/2 < x) + sage: RealSet(1/2 < x) # optional - sage.symbolic (1/2, +oo) - sage: RealSet(1.5 <= x) + sage: RealSet(1.5 <= x) # optional - sage.symbolic [1.50000000000000, +oo) - sage: RealSet(x >= -1) + sage: RealSet(x >= -1) # optional - sage.symbolic [-1, +oo) - sage: RealSet(x > oo) + sage: RealSet(x > oo) # optional - sage.symbolic {} - sage: RealSet(x >= oo) + sage: RealSet(x >= oo) # optional - sage.symbolic {} - sage: RealSet(x <= -oo) + sage: RealSet(x <= -oo) # optional - sage.symbolic {} - sage: RealSet(x < oo) + sage: RealSet(x < oo) # optional - sage.symbolic (-oo, +oo) - sage: RealSet(x > -oo) + sage: RealSet(x > -oo) # optional - sage.symbolic (-oo, +oo) - sage: RealSet(x != oo) + sage: RealSet(x != oo) # optional - sage.symbolic (-oo, +oo) - sage: RealSet(x <= oo) + sage: RealSet(x <= oo) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: interval cannot be closed at +oo - sage: RealSet(x == oo) + sage: RealSet(x == oo) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: interval cannot be closed at +oo - sage: RealSet(x >= -oo) + sage: RealSet(x >= -oo) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: interval cannot be closed at -oo - sage: r = RealSet(2,10) - sage: RealSet((2, 6), (4, 10)) is r + sage: r = RealSet(2,10) # optional - sage.symbolic + sage: RealSet((2, 6), (4, 10)) is r # optional - sage.symbolic True - sage: RealSet(x > 2).intersection(RealSet(x < 10)) is RealSet(r[0], normalized=True) + sage: RealSet(x > 2).intersection(RealSet(x < 10)) is RealSet(r[0], normalized=True) # optional - sage.symbolic True - sage: RealSet(x > 0, normalized=True) + sage: RealSet(x > 0, normalized=True) # optional - sage.symbolic Traceback (most recent call last): ... AttributeError: ... @@ -1628,20 +1630,20 @@ def _sympy_condition_(self, variable): EXAMPLES:: - sage: RealSet(0, 1)._sympy_condition_(x) + sage: RealSet(0, 1)._sympy_condition_(x) # optional - sage.symbolic (0 < x) & (x < 1) - sage: RealSet((0,1), [2,3])._sympy_condition_(x) + sage: RealSet((0,1), [2,3])._sympy_condition_(x) # optional - sage.symbolic ((2 <= x) & (x <= 3)) | ((0 < x) & (x < 1)) - sage: RealSet.unbounded_below_open(0)._sympy_condition_(x) + sage: RealSet.unbounded_below_open(0)._sympy_condition_(x) # optional - sage.symbolic x < 0 - sage: RealSet.unbounded_above_closed(2)._sympy_condition_(x) + sage: RealSet.unbounded_above_closed(2)._sympy_condition_(x) # optional - sage.symbolic 2 <= x TESTS:: - sage: RealSet(6,6)._sympy_condition_(x) + sage: RealSet(6,6)._sympy_condition_(x) # optional - sage.symbolic False - sage: RealSet([6,6])._sympy_condition_(x) + sage: RealSet([6,6])._sympy_condition_(x) # optional - sage.symbolic Eq(x, 6) """ x = variable @@ -1664,20 +1666,20 @@ def _giac_condition_(self, variable): EXAMPLES:: - sage: RealSet(0, 1)._giac_condition_(x) + sage: RealSet(0, 1)._giac_condition_(x) # optional - sage.symbolic '((0 < sageVARx) and (sageVARx < 1))' - sage: RealSet((0,1), [2,3])._giac_condition_(x) + sage: RealSet((0,1), [2,3])._giac_condition_(x) # optional - sage.symbolic '((0 < sageVARx) and (sageVARx < 1)) or ((2 <= sageVARx) and (sageVARx <= 3))' - sage: RealSet.unbounded_below_open(0)._giac_condition_(x) + sage: RealSet.unbounded_below_open(0)._giac_condition_(x) # optional - sage.symbolic '((true) and (sageVARx < 0))' - sage: RealSet.unbounded_above_closed(2)._giac_condition_(x) + sage: RealSet.unbounded_above_closed(2)._giac_condition_(x) # optional - sage.symbolic '((2 <= sageVARx) and (true))' TESTS:: - sage: RealSet(6,6)._giac_condition_(x) + sage: RealSet(6,6)._giac_condition_(x) # optional - sage.symbolic 'false' - sage: RealSet([6,6])._giac_condition_(x) + sage: RealSet([6,6])._giac_condition_(x) # optional - sage.symbolic 'sageVARx == 6' """ x = variable @@ -2170,7 +2172,7 @@ def intersection(self, *real_set_collection): [1, 10) sage: s5.intersection(-oo, +oo) [1, 10) - sage: s5.intersection(x != 2, (-oo, 3), RealSet.real_line()[0]) + sage: s5.intersection(x != 2, (-oo, 3), RealSet.real_line()[0]) # optional - sage.symbolic [1, 2) ∪ (2, 3) TESTS:: @@ -2284,7 +2286,7 @@ def complement(self): TESTS:: - sage: RealSet(x != 0).complement() + sage: RealSet(x != 0).complement() # optional - sage.symbolic {0} sage: RealSet.real_line().complement() {} @@ -2638,7 +2640,7 @@ def is_connected(self): (-oo, -10] ∪ (1, 3) sage: s3.is_connected() False - sage: RealSet(x != 0).is_connected() + sage: RealSet(x != 0).is_connected() # optional - sage.symbolic False sage: RealSet(-oo, oo).is_connected() True @@ -2795,7 +2797,7 @@ def __rmul__(self, other): sage: A = RealSet([0, 1/2], RealSet.unbounded_above_closed(2)); A [0, 1/2] ∪ [2, +oo) - sage: pi * A + sage: pi * A # optional - sage.symbolic [0, 1/2*pi] ∪ [2*pi, +oo) """ return self * other @@ -2806,21 +2808,21 @@ def _sympy_(self): EXAMPLES:: - sage: RealSet()._sympy_() + sage: RealSet()._sympy_() # optional - sympy EmptySet - sage: RealSet.point(5)._sympy_() # random - this output format is sympy >= 1.9 + sage: RealSet.point(5)._sympy_() # random - this format is sympy >= 1.9 # optional - sympy {5} - sage: (RealSet.point(1).union(RealSet.point(2)))._sympy_() # random + sage: (RealSet.point(1).union(RealSet.point(2)))._sympy_() # random # optional - sympy {1, 2} - sage: (RealSet(1, 2).union(RealSet.closed(3, 4)))._sympy_() + sage: (RealSet(1, 2).union(RealSet.closed(3, 4)))._sympy_() # optional - sympy Union(Interval.open(1, 2), Interval(3, 4)) - sage: RealSet(-oo, oo)._sympy_() + sage: RealSet(-oo, oo)._sympy_() # optional - sympy Reals Infinities are not elements:: - sage: import sympy - sage: RealSet(-oo, oo)._sympy_().contains(sympy.oo) + sage: import sympy # optional - sympy + sage: RealSet(-oo, oo)._sympy_().contains(sympy.oo) # optional - sympy False """ from sympy import Reals, Union diff --git a/src/sage/sets/recursively_enumerated_set.pyx b/src/sage/sets/recursively_enumerated_set.pyx index 2ee74cbae1c..5acfbc4655c 100644 --- a/src/sage/sets/recursively_enumerated_set.pyx +++ b/src/sage/sets/recursively_enumerated_set.pyx @@ -33,9 +33,9 @@ help with the enumeration. In this example, the seed is 0 and the successor function is either ``+2`` or ``+3``. This is the set of non negative linear combinations of 2 and 3:: - sage: succ = lambda a:[a+2,a+3] - sage: C = RecursivelyEnumeratedSet([0], succ) - sage: C + sage: def succ(a): + ....: return [a + 2, a + 3] + sage: C = RecursivelyEnumeratedSet([0], succ); C A recursively enumerated set (breadth first search) Breadth first search:: @@ -57,9 +57,12 @@ The origin ``(0, 0)`` as seed and the upper, lower, left and right lattice point as successor function. This function is symmetric since `p` is a successor of `q` if and only if `q` is a successor or `p`:: - sage: succ = lambda a: [(a[0]-1,a[1]), (a[0],a[1]-1), (a[0]+1,a[1]), (a[0],a[1]+1)] + sage: def succ(a): + ....: return [(a[0] - 1, a[1]), (a[0], a[1] - 1), + ....: (a[0] + 1, a[1]), (a[0], a[1] + 1)] sage: seeds = [(0,0)] - sage: C = RecursivelyEnumeratedSet(seeds, succ, structure='symmetric', enumeration='depth') + sage: C = RecursivelyEnumeratedSet(seeds, succ, structure='symmetric', + ....: enumeration='depth') sage: C A recursively enumerated set with a symmetric structure (depth first search) @@ -93,15 +96,15 @@ Identity permutation as seed and ``permutohedron_succ`` as successor function:: sage: succ = attrcall("permutohedron_succ") - sage: seed = [Permutation([1..5])] - sage: R = RecursivelyEnumeratedSet(seed, succ, structure='graded') - sage: R + sage: seed = [Permutation([1..5])] # optional - sage.combinat + sage: R = RecursivelyEnumeratedSet(seed, succ, structure='graded') # optional - sage.combinat + sage: R # optional - sage.combinat A recursively enumerated set with a graded structure (breadth first search) Depth first search iterator:: - sage: it_depth = R.depth_first_search_iterator() - sage: [next(it_depth) for _ in range(5)] + sage: it_depth = R.depth_first_search_iterator() # optional - sage.combinat + sage: [next(it_depth) for _ in range(5)] # optional - sage.combinat [[1, 2, 3, 4, 5], [1, 2, 3, 5, 4], [1, 2, 5, 3, 4], @@ -110,8 +113,8 @@ Depth first search iterator:: Breadth first search iterator:: - sage: it_breadth = R.breadth_first_search_iterator() - sage: [next(it_breadth) for _ in range(5)] + sage: it_breadth = R.breadth_first_search_iterator() # optional - sage.combinat + sage: [next(it_breadth) for _ in range(5)] # optional - sage.combinat [[1, 2, 3, 4, 5], [2, 1, 3, 4, 5], [1, 3, 2, 4, 5], @@ -120,20 +123,20 @@ Breadth first search iterator:: Elements of given depth iterator:: - sage: sorted(R.elements_of_depth_iterator(9)) + sage: sorted(R.elements_of_depth_iterator(9)) # optional - sage.combinat [[4, 5, 3, 2, 1], [5, 3, 4, 2, 1], [5, 4, 2, 3, 1], [5, 4, 3, 1, 2]] - sage: list(R.elements_of_depth_iterator(10)) + sage: list(R.elements_of_depth_iterator(10)) # optional - sage.combinat [[5, 4, 3, 2, 1]] Graded components (set of elements of the same depth):: - sage: sorted(R.graded_component(0)) + sage: sorted(R.graded_component(0)) # optional - sage.combinat [[1, 2, 3, 4, 5]] - sage: sorted(R.graded_component(1)) + sage: sorted(R.graded_component(1)) # optional - sage.combinat [[1, 2, 3, 5, 4], [1, 2, 4, 3, 5], [1, 3, 2, 4, 5], [2, 1, 3, 4, 5]] - sage: sorted(R.graded_component(9)) + sage: sorted(R.graded_component(9)) # optional - sage.combinat [[4, 5, 3, 2, 1], [5, 3, 4, 2, 1], [5, 4, 2, 3, 1], [5, 4, 3, 1, 2]] - sage: sorted(R.graded_component(10)) + sage: sorted(R.graded_component(10)) # optional - sage.combinat [[5, 4, 3, 2, 1]] Forest structure @@ -144,7 +147,8 @@ empty word by appending letter `a` or `b` as a successor function. This set has a forest structure:: sage: seeds = [''] - sage: succ = lambda w: [w+'a', w+'b'] + sage: def succ(w): + ....: return [w + 'a', w + 'b'] sage: C = RecursivelyEnumeratedSet(seeds, succ, structure='forest') sage: C An enumerated set with a forest structure @@ -233,7 +237,7 @@ or even:: We can then create the :class:`RecursivelyEnumeratedSet` object with either:: sage: S = RecursivelyEnumeratedSet([''], - ....: lambda x: [x+letter for letter in ['a', 'b', 'c']] + ....: lambda x: [x + letter for letter in ['a', 'b', 'c']] ....: if len(x) < 2 else [], ....: structure='forest', enumeration='depth', ....: category=FiniteEnumeratedSets()) @@ -273,8 +277,8 @@ convention is that the generated elements are the ``s := f(n)``, except when ....: st = set(st) # make a copy ....: if st: ....: el = st.pop() - ....: for i in range(len(lst)+1): - ....: yield (lst[0:i]+[el]+lst[i:], st) + ....: for i in range(len(lst) + 1): + ....: yield (lst[0:i] + [el] + lst[i:], st) sage: list(children(([1,2], {3,7,9}))) [([9, 1, 2], {3, 7}), ([1, 9, 2], {3, 7}), ([1, 2, 9], {3, 7})] sage: def post_process(node): @@ -361,9 +365,9 @@ def RecursivelyEnumeratedSet(seeds, successors, structure=None, A recursive set with no other information:: - sage: f = lambda a: [a+3, a+5] - sage: C = RecursivelyEnumeratedSet([0], f) - sage: C + sage: def f(a): + ....: return [a + 3, a + 5] + sage: C = RecursivelyEnumeratedSet([0], f); C A recursively enumerated set (breadth first search) sage: it = iter(C) sage: [next(it) for _ in range(10)] @@ -372,8 +376,7 @@ def RecursivelyEnumeratedSet(seeds, successors, structure=None, A recursive set with a forest structure:: sage: f = lambda a: [2*a,2*a+1] - sage: C = RecursivelyEnumeratedSet([1], f, structure='forest') - sage: C + sage: C = RecursivelyEnumeratedSet([1], f, structure='forest'); C An enumerated set with a forest structure sage: it = C.depth_first_search_iterator() sage: [next(it) for _ in range(7)] @@ -384,9 +387,9 @@ def RecursivelyEnumeratedSet(seeds, successors, structure=None, A recursive set given by a symmetric relation:: - sage: f = lambda a: [a-1,a+1] - sage: C = RecursivelyEnumeratedSet([10, 15], f, structure='symmetric') - sage: C + sage: def f(a): + ....: return [a - 1, a + 1] + sage: C = RecursivelyEnumeratedSet([10, 15], f, structure='symmetric'); C A recursively enumerated set with a symmetric structure (breadth first search) sage: it = iter(C) sage: [next(it) for _ in range(7)] @@ -394,9 +397,9 @@ def RecursivelyEnumeratedSet(seeds, successors, structure=None, A recursive set given by a graded relation:: - sage: f = lambda a: [a+1, a+I] - sage: C = RecursivelyEnumeratedSet([0], f, structure='graded') - sage: C + sage: def f(a): + ....: return [a + 1, a + I] + sage: C = RecursivelyEnumeratedSet([0], f, structure='graded'); C A recursively enumerated set with a graded structure (breadth first search) sage: it = iter(C) sage: [next(it) for _ in range(7)] @@ -407,7 +410,8 @@ def RecursivelyEnumeratedSet(seeds, successors, structure=None, If you do not set the good structure, you might obtain bad results, like elements generated twice:: - sage: f = lambda a: [a-1,a+1] + sage: def f(a): + ....: return [a - 1, a + 1] sage: C = RecursivelyEnumeratedSet([0], f, structure='graded') sage: it = iter(C) sage: [next(it) for _ in range(7)] @@ -462,7 +466,8 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): EXAMPLES:: - sage: f = lambda a:[a+1] + sage: def f(a): + ....: return [a + 1] Different structure for the sets:: @@ -490,7 +495,8 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): r""" TESTS:: - sage: f = lambda a: [a+3, a+5] + sage: def f(a): + ....: return [a + 3, a + 5] sage: C = RecursivelyEnumeratedSet([0], f) sage: C A recursively enumerated set (breadth first search) @@ -580,7 +586,8 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): EXAMPLES:: - sage: f = lambda a: [a+3, a+5] + sage: def f(a): + ....: return [a + 3, a + 5] sage: C = RecursivelyEnumeratedSet([0], f) sage: len(C) Traceback (most recent call last): @@ -598,7 +605,8 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): EXAMPLES:: - sage: f = lambda a: [a+3, a+5] + sage: def f(a): + ....: return [a + 3, a + 5] sage: it_naive = iter(RecursivelyEnumeratedSet([0], f, enumeration='naive')) sage: it_depth = iter(RecursivelyEnumeratedSet([0], f, enumeration='depth')) sage: it_breadth = iter(RecursivelyEnumeratedSet([0], f, enumeration='breadth')) @@ -632,7 +640,8 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): EXAMPLES:: - sage: f = lambda a:[a+3,a+5] + sage: def f(a): + ....: return [a + 3, a + 5] sage: R = RecursivelyEnumeratedSet([0], f) sage: R A recursively enumerated set (breadth first search) @@ -656,7 +665,8 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): r""" TESTS:: - sage: f = lambda x: [x-1, x+1] + sage: def f(x): + ....: return [x - 1, x + 1] sage: RecursivelyEnumeratedSet([1], f, structure=None) A recursively enumerated set (breadth first search) @@ -700,7 +710,7 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): EXAMPLES:: - sage: R = RecursivelyEnumeratedSet([1], lambda x: [x+1, x-1]) + sage: R = RecursivelyEnumeratedSet([1], lambda x: [x + 1, x - 1]) sage: R.seeds() [1] """ @@ -737,7 +747,8 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): EXAMPLES:: - sage: f = lambda a: [a+3, a+5] + sage: def f(a): + ....: return [a + 3, a + 5] sage: C = RecursivelyEnumeratedSet([0], f) sage: it = C.graded_component_iterator() # todo: not implemented """ @@ -765,7 +776,8 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): EXAMPLES:: - sage: f = lambda a: [a+3, a+5] + sage: def f(a): + ....: return [a + 3, a + 5] sage: C = RecursivelyEnumeratedSet([0], f) sage: C.graded_component(0) Traceback (most recent call last): @@ -792,7 +804,8 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): EXAMPLES:: - sage: f = lambda a: [a-1, a+1] + sage: def f(a): + ....: return [a - 1, a + 1] sage: S = RecursivelyEnumeratedSet([5, 10], f, structure='symmetric') sage: it = S.elements_of_depth_iterator(2) sage: sorted(it) @@ -816,7 +829,8 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): EXAMPLES:: - sage: f = lambda a: [a+3, a+5] + sage: def f(a): + ....: return [a + 3, a + 5] sage: C = RecursivelyEnumeratedSet([0], f) sage: it = C.breadth_first_search_iterator() sage: [next(it) for _ in range(10)] @@ -853,7 +867,8 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): EXAMPLES:: - sage: f = lambda a: [a+3, a+5] + sage: def f(a): + ....: return [a + 3, a + 5] sage: C = RecursivelyEnumeratedSet([0], f) sage: it = C._breadth_first_search_iterator_using_queue() sage: [next(it) for _ in range(10)] @@ -912,7 +927,8 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): EXAMPLES:: - sage: f = lambda a: [a+3, a+5] + sage: def f(a): + ....: return [a + 3, a + 5] sage: C = RecursivelyEnumeratedSet([0], f) sage: it = C.depth_first_search_iterator() sage: [next(it) for _ in range(10)] @@ -953,31 +969,36 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): EXAMPLES:: - sage: child = lambda i: [(i+3) % 10, (i+8) % 10] + sage: def child(i): + ....: return [(i+3) % 10, (i+8) % 10] sage: R = RecursivelyEnumeratedSet([0], child) - sage: R.to_digraph() + sage: R.to_digraph() # optional - sage.graphs Looped multi-digraph on 10 vertices Digraph of an 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)] - sage: seeds = [(0,0)] + sage: def succ(a): + ....: return [(a[0] - 1, a[1]), (a[0], a[1] - 1), + ....: (a[0] + 1, a[1]), (a[0], a[1] + 1)] + sage: seeds = [(0, 0)] sage: C = RecursivelyEnumeratedSet(seeds, succ, structure='symmetric') - sage: C.to_digraph(max_depth=3) + sage: C.to_digraph(max_depth=3) # optional - sage.graphs Looped multi-digraph on 41 vertices The ``max_depth`` argument can be given at the creation of the set:: - sage: C = RecursivelyEnumeratedSet(seeds, succ, structure='symmetric', max_depth=2) - sage: C.to_digraph() + sage: C = RecursivelyEnumeratedSet(seeds, succ, structure='symmetric', + ....: max_depth=2) + sage: C.to_digraph() # optional - sage.graphs Looped multi-digraph on 25 vertices Digraph of an recursively enumerated set with a graded structure:: - sage: f = lambda a: [a+1, a+I] + sage: def f(a): + ....: return [a + 1, a + I] sage: C = RecursivelyEnumeratedSet([0], f, structure='graded') - sage: C.to_digraph(max_depth=4) + sage: C.to_digraph(max_depth=4) # optional - sage.graphs Looped multi-digraph on 21 vertices """ successors = self.successors @@ -1001,7 +1022,8 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): EXAMPLES:: - sage: f = lambda a: [a-1,a+1] + sage: def f(a): + ....: return [a - 1, a + 1] sage: C = RecursivelyEnumeratedSet([0], f, structure='symmetric') sage: C A recursively enumerated set with a symmetric structure (breadth first search) @@ -1013,7 +1035,7 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): Do not use lambda functions for saving purposes:: - sage: f = lambda a: [a-1,a+1] + sage: f = lambda a: [a - 1, a + 1] sage: C = RecursivelyEnumeratedSet([0], f, structure='symmetric') sage: loads(dumps(C)) Traceback (most recent call last): @@ -1022,7 +1044,8 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): This works in the command line but apparently not as a doctest:: - sage: def f(a): return [a-1,a+1] + sage: def f(a): + ....: return [a - 1, a + 1] sage: C = RecursivelyEnumeratedSet([0], f, structure='symmetric') sage: loads(dumps(C)) Traceback (most recent call last): @@ -1047,7 +1070,9 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): EXAMPLES:: - sage: f = lambda a: [(a[0]-1,a[1]), (a[0],a[1]-1), (a[0]+1,a[1]), (a[0],a[1]+1)] + sage: def f(a): + ....: return [(a[0] - 1, a[1]), (a[0], a[1] - 1), + ....: (a[0] + 1, a[1]), (a[0], a[1] + 1)] sage: C = RecursivelyEnumeratedSet([(0,0)], f, structure='symmetric') sage: s = list(C.breadth_first_search_iterator(max_depth=2)); s [(0, 0), @@ -1111,7 +1136,8 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): EXAMPLES:: - sage: f = lambda a: [a-1, a+1] + sage: def f(a): + ....: return [a - 1, a + 1] sage: S = RecursivelyEnumeratedSet([10], f, structure='symmetric') sage: it = S.graded_component_iterator() sage: [sorted(next(it)) for _ in range(5)] @@ -1119,7 +1145,8 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): Starting with two generators:: - sage: f = lambda a: [a-1, a+1] + sage: def f(a): + ....: return [a - 1, a + 1] sage: S = RecursivelyEnumeratedSet([5, 10], f, structure='symmetric') sage: it = S.graded_component_iterator() sage: [sorted(next(it)) for _ in range(5)] @@ -1127,7 +1154,8 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): Gaussian integers:: - sage: f = lambda a: [a+1, a+I] + sage: def f(a): + ....: return [a + 1, a + I] sage: S = RecursivelyEnumeratedSet([0], f, structure='symmetric') sage: it = S.graded_component_iterator() sage: [sorted(next(it)) for _ in range(7)] @@ -1146,7 +1174,7 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): sage: def f(a): ....: sleep(0.05r) - ....: return [a-1,a+1] + ....: return [a - 1, a + 1] sage: C = RecursivelyEnumeratedSet([0], f, structure='symmetric') sage: it = C.graded_component_iterator() sage: next(it) @@ -1191,7 +1219,8 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): EXAMPLES:: - sage: f = lambda a: [a-1,a+1] + sage: def f(a): + ....: return [a - 1, a + 1] sage: C = RecursivelyEnumeratedSet([10, 15], f, structure='symmetric') sage: for i in range(5): sorted(C.graded_component(i)) [10, 15] @@ -1206,7 +1235,7 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): sage: def f(a): ....: sleep(0.1r) - ....: return [a-1,a+1] + ....: return [a - 1, a + 1] sage: C = RecursivelyEnumeratedSet([0], f, structure='symmetric') sage: from cysignals.alarm import alarm sage: alarm(0.45); C.graded_component(10) @@ -1257,7 +1286,8 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): EXAMPLES:: - sage: f = lambda a: [a-1, a+1] + sage: def f(a): + ....: return [a - 1, a + 1] sage: S = RecursivelyEnumeratedSet([5, 10], f, structure='symmetric') sage: it = S.graded_component_iterator() sage: [sorted(next(it)) for _ in range(3)] # indirect doctest @@ -1286,7 +1316,8 @@ cdef class RecursivelyEnumeratedSet_graded(RecursivelyEnumeratedSet_generic): EXAMPLES:: - sage: f = lambda a: [(a[0]+1,a[1]), (a[0],a[1]+1)] + sage: def f(a): + ....: return [(a[0] + 1, a[1]), (a[0], a[1] + 1)] sage: C = RecursivelyEnumeratedSet([(0,0)], f, structure='graded', max_depth=3) sage: C A recursively enumerated set with a graded structure (breadth first @@ -1314,7 +1345,8 @@ cdef class RecursivelyEnumeratedSet_graded(RecursivelyEnumeratedSet_generic): EXAMPLES:: - sage: f = lambda a: [(a[0]+1,a[1]), (a[0],a[1]+1)] + sage: def f(a): + ....: return [(a[0] + 1, a[1]), (a[0], a[1] + 1)] sage: C = RecursivelyEnumeratedSet([(0,0)], f, structure='graded') sage: list(C.breadth_first_search_iterator(max_depth=3)) [(0, 0), @@ -1361,7 +1393,8 @@ cdef class RecursivelyEnumeratedSet_graded(RecursivelyEnumeratedSet_generic): EXAMPLES:: - sage: f = lambda a: [(a[0]+1,a[1]), (a[0],a[1]+1)] + sage: def f(a): + ....: return [(a[0] + 1, a[1]), (a[0], a[1] + 1)] sage: C = RecursivelyEnumeratedSet([(0,0)], f, structure='graded', max_depth=3) sage: it = C.graded_component_iterator() sage: for _ in range(4): sorted(next(it)) @@ -1414,7 +1447,8 @@ cdef class RecursivelyEnumeratedSet_graded(RecursivelyEnumeratedSet_generic): EXAMPLES:: - sage: f = lambda a: [a+1, a+I] + sage: def f(a): + ....: return [a + 1, a + I] sage: C = RecursivelyEnumeratedSet([0], f, structure='graded') sage: for i in range(5): sorted(C.graded_component(i)) [0] @@ -1429,7 +1463,7 @@ cdef class RecursivelyEnumeratedSet_graded(RecursivelyEnumeratedSet_generic): sage: def f(a): ....: sleep(0.1r) - ....: return [a+1, a+I] + ....: return [a + 1, a + I] sage: C = RecursivelyEnumeratedSet([0], f, structure='graded') sage: from cysignals.alarm import alarm sage: alarm(0.45); C.graded_component(10) @@ -1472,7 +1506,8 @@ cdef class RecursivelyEnumeratedSet_graded(RecursivelyEnumeratedSet_generic): EXAMPLES:: - sage: f = lambda a: [(a[0]+1,a[1]), (a[0],a[1]+1)] + sage: def f(a): + ....: return [(a[0] + 1, a[1]), (a[0], a[1] + 1)] sage: C = RecursivelyEnumeratedSet([(0,0)], f, structure='graded') sage: it = C.graded_component_iterator() sage: [sorted(next(it)) for _ in range(2)] # indirect doctest @@ -1500,7 +1535,7 @@ def _imap_and_filter_none(function, iterable): sage: p = _imap_and_filter_none(lambda x: x if is_prime(x) else None, range(15)) sage: [next(p), next(p), next(p), next(p), next(p), next(p)] [2, 3, 5, 7, 11, 13] - sage: p = _imap_and_filter_none(lambda x: x+x, ['a','b','c','d','e']) + sage: p = _imap_and_filter_none(lambda x: x + x, ['a','b','c','d','e']) sage: [next(p), next(p), next(p), next(p), next(p)] ['aa', 'bb', 'cc', 'dd', 'ee'] """ @@ -1528,7 +1563,7 @@ def search_forest_iterator(roots, children, algorithm='depth'): three, and enumerate its nodes:: sage: from sage.sets.recursively_enumerated_set import search_forest_iterator - sage: list(search_forest_iterator([[]], lambda l: [l+[0], l+[1]] + sage: list(search_forest_iterator([[]], lambda l: [l + [0], l + [1]] ....: if len(l) < 3 else [])) [[], [0], [0, 0], [0, 0, 0], [0, 0, 1], [0, 1], [0, 1, 0], [0, 1, 1], [1], [1, 0], [1, 0, 0], [1, 0, 1], [1, 1], [1, 1, 0], [1, 1, 1]] @@ -1536,7 +1571,7 @@ def search_forest_iterator(roots, children, algorithm='depth'): By default, the nodes are iterated through by depth first search. We can instead use a breadth first search (increasing depth):: - sage: list(search_forest_iterator([[]], lambda l: [l+[0], l+[1]] + sage: list(search_forest_iterator([[]], lambda l: [l + [0], l + [1]] ....: if len(l) < 3 else [], ....: algorithm='breadth')) [[], @@ -1547,7 +1582,8 @@ def search_forest_iterator(roots, children, algorithm='depth'): This allows for iterating trough trees of infinite depth:: - sage: it = search_forest_iterator([[]], lambda l: [l+[0], l+[1]], algorithm='breadth') + sage: it = search_forest_iterator([[]], lambda l: [l + [0], l + [1]], + ....: algorithm='breadth') sage: [ next(it) for i in range(16) ] [[], [0], [1], [0, 0], [0, 1], [1, 0], [1, 1], @@ -1559,7 +1595,9 @@ def search_forest_iterator(roots, children, algorithm='depth'): letters in `0,1,2` without repetitions, sorted by length; the leaves are therefore permutations:: - sage: list(search_forest_iterator([[]], lambda l: [l + [i] for i in range(3) if i not in l], + sage: def f(l): + ....: return [l + [i] for i in range(3) if i not in l] + sage: list(search_forest_iterator([[]], f, ....: algorithm='breadth')) [[], [0], [1], [2], @@ -1626,7 +1664,7 @@ class RecursivelyEnumeratedSet_forest(Parent): sage: from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest sage: S = RecursivelyEnumeratedSet_forest( [[]], - ....: lambda l: [l+[0], l+[1]] if len(l) < 3 else [], + ....: lambda l: [l + [0], l + [1]] if len(l) < 3 else [], ....: category=FiniteEnumeratedSets()) sage: S.list() [[], @@ -1665,10 +1703,13 @@ class RecursivelyEnumeratedSet_forest(Parent): builds the set of all ordered pairs `(i,j)` of nonnegative integers such that `j\leq 1`:: + sage: def f(l): + ....: if l[1] == 0: + ....: return [(l[0] + 1, l[1]), (l[0], 1)] + ....: else: + ....: return [(l[0], l[1] + 1)] sage: from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest - sage: I = RecursivelyEnumeratedSet_forest([(0,0)], - ....: lambda l: [(l[0]+1, l[1]), (l[0], 1)] - ....: if l[1] == 0 else [(l[0], l[1]+1)]) + sage: I = RecursivelyEnumeratedSet_forest([(0, 0)], f) With a depth first search, only the elements of the form `(i,0)` are generated:: @@ -1710,9 +1751,10 @@ class RecursivelyEnumeratedSet_forest(Parent): sage: class A(UniqueRepresentation, RecursivelyEnumeratedSet_forest): ....: def __init__(self): ....: RecursivelyEnumeratedSet_forest.__init__(self, [()], - ....: lambda x : [x+(0,), x+(1,)] if sum(x) < 3 else [], - ....: lambda x : sum(x[i]*2^i for i in range(len(x))) if sum(x) != 0 and x[-1] != 0 else None, - ....: algorithm = 'breadth', + ....: lambda x: [x + (0,), x + (1,)] if sum(x) < 3 else [], + ....: lambda x: sum(x[i]*2^i for i in range(len(x))) + ....: if sum(x) != 0 and x[-1] != 0 else None, + ....: algorithm='breadth', ....: category=InfiniteEnumeratedSets()) sage: MyForest = A(); MyForest An enumerated set with a forest structure @@ -1720,7 +1762,8 @@ class RecursivelyEnumeratedSet_forest(Parent): Category of infinite enumerated sets sage: p = iter(MyForest) sage: [next(p) for i in range(30)] - [1, 2, 3, 4, 6, 5, 7, 8, 12, 10, 14, 9, 13, 11, 16, 24, 20, 28, 18, 26, 22, 17, 25, 21, 19, 32, 48, 40, 56, 36] + [1, 2, 3, 4, 6, 5, 7, 8, 12, 10, 14, 9, 13, 11, 16, 24, + 20, 28, 18, 26, 22, 17, 25, 21, 19, 32, 48, 40, 56, 36] An alternative approach is to implement ``roots`` and ``children`` as methods of the subclass (in fact they could also be attributes @@ -1733,13 +1776,13 @@ class RecursivelyEnumeratedSet_forest(Parent): sage: from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest sage: class A(UniqueRepresentation, RecursivelyEnumeratedSet_forest): ....: def __init__(self): - ....: RecursivelyEnumeratedSet_forest.__init__(self, algorithm = 'breadth', + ....: RecursivelyEnumeratedSet_forest.__init__(self, algorithm='breadth', ....: category=InfiniteEnumeratedSets()) ....: def roots(self): ....: return [()] ....: def children(self, x): ....: if sum(x) < 3: - ....: return [x+(0,), x+(1,)] + ....: return [x + (0,), x + (1,)] ....: else: ....: return [] ....: def post_process(self, x): @@ -1753,7 +1796,8 @@ class RecursivelyEnumeratedSet_forest(Parent): Category of infinite enumerated sets sage: p = iter(MyForest) sage: [next(p) for i in range(30)] - [1, 2, 3, 4, 6, 5, 7, 8, 12, 10, 14, 9, 13, 11, 16, 24, 20, 28, 18, 26, 22, 17, 25, 21, 19, 32, 48, 40, 56, 36] + [1, 2, 3, 4, 6, 5, 7, 8, 12, 10, 14, 9, 13, 11, 16, 24, + 20, 28, 18, 26, 22, 17, 25, 21, 19, 32, 48, 40, 56, 36] .. warning:: @@ -1762,8 +1806,8 @@ class RecursivelyEnumeratedSet_forest(Parent): anonymous or interactively defined functions:: sage: def children(x): - ....: return [x+1] - sage: S = RecursivelyEnumeratedSet_forest( [1], children, category=InfiniteEnumeratedSets()) + ....: return [x + 1] + sage: S = RecursivelyEnumeratedSet_forest([1], children, category=InfiniteEnumeratedSets()) sage: dumps(S) Traceback (most recent call last): ... @@ -1773,7 +1817,7 @@ class RecursivelyEnumeratedSet_forest(Parent): sage: import __main__ sage: __main__.children = children - sage: S = RecursivelyEnumeratedSet_forest( [1], children, category=InfiniteEnumeratedSets()) + sage: S = RecursivelyEnumeratedSet_forest([1], children, category=InfiniteEnumeratedSets()) sage: loads(dumps(S)) An enumerated set with a forest structure """ @@ -1783,7 +1827,7 @@ class RecursivelyEnumeratedSet_forest(Parent): TESTS:: sage: from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest - sage: S = RecursivelyEnumeratedSet_forest(NN, lambda x : [], lambda x: x^2 if x.is_prime() else None) + sage: S = RecursivelyEnumeratedSet_forest(NN, lambda x: [], lambda x: x^2 if x.is_prime() else None) sage: S.category() Category of enumerated sets """ @@ -1815,10 +1859,15 @@ class RecursivelyEnumeratedSet_forest(Parent): EXAMPLES:: sage: from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest - sage: I = RecursivelyEnumeratedSet_forest([(0,0)], lambda l: [(l[0]+1, l[1]), (l[0], 1)] if l[1] == 0 else [(l[0], l[1]+1)]) + sage: def f(l): + ....: if l[1] == 0: + ....: return [(l[0] + 1, l[1]), (l[0], 1)] + ....: else: + ....: return [(l[0], l[1] + 1)] + sage: I = RecursivelyEnumeratedSet_forest([(0, 0)], f) sage: [i for i in I.roots()] [(0, 0)] - sage: I = RecursivelyEnumeratedSet_forest([(0,0),(1,1)], lambda l: [(l[0]+1, l[1]), (l[0], 1)] if l[1] == 0 else [(l[0], l[1]+1)]) + sage: I = RecursivelyEnumeratedSet_forest([(0, 0), (1, 1)], f) sage: [i for i in I.roots()] [(0, 0), (1, 1)] """ @@ -1835,7 +1884,12 @@ class RecursivelyEnumeratedSet_forest(Parent): EXAMPLES:: sage: from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest - sage: I = RecursivelyEnumeratedSet_forest([(0,0)], lambda l: [(l[0]+1, l[1]), (l[0], 1)] if l[1] == 0 else [(l[0], l[1]+1)]) + sage: def f(l): + ....: if l[1] == 0: + ....: return [(l[0] + 1, l[1]), (l[0], 1)] + ....: else: + ....: return [(l[0], l[1] + 1)] + sage: I = RecursivelyEnumeratedSet_forest([(0, 0)], f) sage: [i for i in I.children((0,0))] [(1, 0), (0, 1)] sage: [i for i in I.children((1,0))] @@ -1856,7 +1910,7 @@ class RecursivelyEnumeratedSet_forest(Parent): sage: from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest sage: def children(l): - ....: return [l+[0], l+[1]] + ....: return [l + [0], l + [1]] sage: C = RecursivelyEnumeratedSet_forest(([],), children) sage: f = C.__iter__() sage: next(f) @@ -1881,9 +1935,10 @@ class RecursivelyEnumeratedSet_forest(Parent): sage: from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest sage: f = RecursivelyEnumeratedSet_forest([[]], - ....: lambda l: [l+[0], l+[1]] if len(l) < 3 else []) + ....: lambda l: [l + [0], l + [1]] if len(l) < 3 else []) sage: list(f.depth_first_search_iterator()) - [[], [0], [0, 0], [0, 0, 0], [0, 0, 1], [0, 1], [0, 1, 0], [0, 1, 1], [1], [1, 0], [1, 0, 0], [1, 0, 1], [1, 1], [1, 1, 0], [1, 1, 1]] + [[], [0], [0, 0], [0, 0, 0], [0, 0, 1], [0, 1], [0, 1, 0], [0, 1, 1], + [1], [1, 0], [1, 0, 0], [1, 0, 1], [1, 1], [1, 1, 0], [1, 1, 1]] """ return iter(self) @@ -1895,12 +1950,21 @@ class RecursivelyEnumeratedSet_forest(Parent): sage: from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest sage: f = RecursivelyEnumeratedSet_forest([[]], - ....: lambda l: [l+[0], l+[1]] if len(l) < 3 else []) + ....: lambda l: [l + [0], l + [1]] if len(l) < 3 else []) sage: list(f.breadth_first_search_iterator()) - [[], [0], [1], [0, 0], [0, 1], [1, 0], [1, 1], [0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]] - sage: S = RecursivelyEnumeratedSet_forest([(0,0)], - ....: lambda x : [(x[0], x[1]+1)] if x[1] != 0 else [(x[0]+1,0), (x[0],1)], - ....: post_process = lambda x: x if ((is_prime(x[0]) and is_prime(x[1])) and ((x[0] - x[1]) == 2)) else None) + [[], [0], [1], [0, 0], [0, 1], [1, 0], [1, 1], + [0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]] + sage: def f(x): + ....: if x[1] != 0: + ....: return [(x[0], x[1] + 1)] + ....: else: + ....: return [(x[0] + 1, 0), (x[0], 1)] + sage: def post_process(x): + ....: if (is_prime(x[0]) and is_prime(x[1])) and ((x[0] - x[1]) == 2): + ....: return x + ....: return None + sage: S = RecursivelyEnumeratedSet_forest([(0, 0)], f, + ....: post_process=post_process) sage: p = S.breadth_first_search_iterator() sage: [next(p), next(p), next(p), next(p), next(p), next(p), next(p)] [(5, 3), (7, 5), (13, 11), (19, 17), (31, 29), (43, 41), (61, 59)] @@ -1952,14 +2016,21 @@ class RecursivelyEnumeratedSet_forest(Parent): EXAMPLES:: sage: from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest - sage: S = RecursivelyEnumeratedSet_forest([(0,0)] , - ....: lambda x : [(x[0], x[1]+1)] if x[1] != 0 else [(x[0]+1,0), (x[0],1)], - ....: post_process = lambda x: x if ((is_prime(x[0]) and is_prime(x[1])) - ....: and ((x[0] - x[1]) == 2)) else None) + sage: def f(x): + ....: if x[1] != 0: + ....: return [(x[0], x[1] + 1)] + ....: else: + ....: return [(x[0] + 1, 0), (x[0], 1)] + sage: def post_process(x): + ....: if (is_prime(x[0]) and is_prime(x[1])) and ((x[0] - x[1]) == 2): + ....: return x + ....: return None + sage: S = RecursivelyEnumeratedSet_forest([(0, 0)], f, + ....: post_process=post_process) sage: p = S.elements_of_depth_iterator(8) sage: next(p) (5, 3) - sage: S = RecursivelyEnumeratedSet_forest(NN, lambda x : [], + sage: S = RecursivelyEnumeratedSet_forest(NN, lambda x: [], ....: lambda x: x^2 if x.is_prime() else None) sage: p = S.elements_of_depth_iterator(0) sage: [next(p), next(p), next(p), next(p), next(p)] @@ -1984,7 +2055,8 @@ class RecursivelyEnumeratedSet_forest(Parent): EXAMPLES:: sage: from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest - sage: S = RecursivelyEnumeratedSet_forest( [[]], lambda l: [l+[0], l+[1]] if len(l) < 3 else [], category=FiniteEnumeratedSets()) + sage: S = RecursivelyEnumeratedSet_forest([[]], lambda l: [l + [0], l + [1]] if len(l) < 3 else [], + ....: category=FiniteEnumeratedSets()) sage: [4] in S False sage: [1] in S @@ -1993,12 +2065,12 @@ class RecursivelyEnumeratedSet_forest(Parent): False sage: all(S.__contains__(i) for i in iter(S)) True - sage: S = RecursivelyEnumeratedSet_forest([1], lambda x: [x+1], category=InfiniteEnumeratedSets()) + sage: S = RecursivelyEnumeratedSet_forest([1], lambda x: [x + 1], category=InfiniteEnumeratedSets()) sage: 1 in S True sage: 732 in S True - sage: -1 in S # not tested : Will never stop + sage: -1 in S # not tested : Will never stop The algorithm uses a random enumeration of the nodes of the forest. This choice was motivated by examples in which both @@ -2008,8 +2080,9 @@ class RecursivelyEnumeratedSet_forest(Parent): roots has an infinite number of children:: sage: from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest - sage: S = RecursivelyEnumeratedSet_forest(Family(NN, lambda x : (x, 0)), - ....: lambda x : Family(PositiveIntegers(), lambda y : (x[0], y)) if x[1] == 0 else []) + sage: S = RecursivelyEnumeratedSet_forest( + ....: Family(NN, lambda x: (x, 0)), + ....: lambda x: Family(PositiveIntegers(), lambda y: (x[0], y)) if x[1] == 0 else []) sage: p = S.depth_first_search_iterator() sage: [next(p), next(p), next(p), next(p), next(p), next(p), next(p)] [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6)] @@ -2031,7 +2104,8 @@ class RecursivelyEnumeratedSet_forest(Parent): child. From each root starts an infinite branch of breadth `1`:: - sage: S = RecursivelyEnumeratedSet_forest(Family(NN, lambda x : (x, 0)) , lambda x : [(x[0], x[1]+1)]) + sage: S = RecursivelyEnumeratedSet_forest(Family(NN, lambda x: (x, 0)), + ....: lambda x: [(x[0], x[1] + 1)]) sage: p = S.depth_first_search_iterator() sage: [next(p), next(p), next(p), next(p), next(p), next(p), next(p)] [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6)] @@ -2086,20 +2160,26 @@ class RecursivelyEnumeratedSet_forest(Parent): EXAMPLES:: - sage: seeds = [([i],i, i) for i in range(1,10)] + sage: seeds = [([i], i, i) for i in range(1, 10)] sage: def succ(t): ....: list, sum, last = t ....: return [(list + [i], sum + i, i) for i in range(1, last)] sage: F = RecursivelyEnumeratedSet(seeds, succ, - ....: structure='forest', enumeration='depth') + ....: structure='forest', enumeration='depth') - sage: y = var('y') + sage: y = var('y') # optional - sage.symbolic sage: def map_function(t): ....: li, sum, _ = t ....: return y ^ sum - sage: reduce_function = lambda x,y: x + y - sage: F.map_reduce(map_function, reduce_function, 0) - y^45 + y^44 + y^43 + 2*y^42 + 2*y^41 + 3*y^40 + 4*y^39 + 5*y^38 + 6*y^37 + 8*y^36 + 9*y^35 + 10*y^34 + 12*y^33 + 13*y^32 + 15*y^31 + 17*y^30 + 18*y^29 + 19*y^28 + 21*y^27 + 21*y^26 + 22*y^25 + 23*y^24 + 23*y^23 + 23*y^22 + 23*y^21 + 22*y^20 + 21*y^19 + 21*y^18 + 19*y^17 + 18*y^16 + 17*y^15 + 15*y^14 + 13*y^13 + 12*y^12 + 10*y^11 + 9*y^10 + 8*y^9 + 6*y^8 + 5*y^7 + 4*y^6 + 3*y^5 + 2*y^4 + 2*y^3 + y^2 + y + sage: def reduce_function(x, y): + ....: return x + y + sage: F.map_reduce(map_function, reduce_function, 0) # optional - sage.symbolic + y^45 + y^44 + y^43 + 2*y^42 + 2*y^41 + 3*y^40 + 4*y^39 + 5*y^38 + 6*y^37 + + 8*y^36 + 9*y^35 + 10*y^34 + 12*y^33 + 13*y^32 + 15*y^31 + 17*y^30 + + 18*y^29 + 19*y^28 + 21*y^27 + 21*y^26 + 22*y^25 + 23*y^24 + 23*y^23 + + 23*y^22 + 23*y^21 + 22*y^20 + 21*y^19 + 21*y^18 + 19*y^17 + 18*y^16 + + 17*y^15 + 15*y^14 + 13*y^13 + 12*y^12 + 10*y^11 + 9*y^10 + 8*y^9 + 6*y^8 + + 5*y^7 + 4*y^6 + 3*y^5 + 2*y^4 + 2*y^3 + y^2 + y Here is an example with the default values:: diff --git a/src/sage/sets/set.py b/src/sage/sets/set.py index a1789c61300..1853d980a15 100644 --- a/src/sage/sets/set.py +++ b/src/sage/sets/set.py @@ -71,7 +71,7 @@ def has_finite_length(obj): True sage: has_finite_length(iter(range(10))) False - sage: has_finite_length(GF(17^127)) + sage: has_finite_length(GF(17^127)) # optional - sage.rings.finite_rings True sage: has_finite_length(ZZ) False @@ -100,22 +100,24 @@ def Set(X=None, category=None): EXAMPLES:: - sage: X = Set(GF(9,'a')) - sage: X + sage: X = Set(GF(9, 'a')) # optional - sage.rings.finite_rings + sage: X # optional - sage.rings.finite_rings {0, 1, 2, a, a + 1, a + 2, 2*a, 2*a + 1, 2*a + 2} - sage: type(X) + sage: type(X) # optional - sage.rings.finite_rings - sage: Y = X.union(Set(QQ)) - sage: Y - Set-theoretic union of {0, 1, 2, a, a + 1, a + 2, 2*a, 2*a + 1, 2*a + 2} and Set of elements of Rational Field - sage: type(Y) + sage: Y = X.union(Set(QQ)) # optional - sage.rings.finite_rings + sage: Y # optional - sage.rings.finite_rings + Set-theoretic union of + {0, 1, 2, a, a + 1, a + 2, 2*a, 2*a + 1, 2*a + 2} and + Set of elements of Rational Field + sage: type(Y) # optional - sage.rings.finite_rings Usually sets can be used as dictionary keys. :: - sage: d={Set([2*I,1+I]):10} + sage: d = {Set([2*I, 1 + I]): 10} sage: d # key is randomly ordered {{I + 1, 2*I}: 10} sage: d[Set([1+I,2*I])] @@ -218,18 +220,24 @@ def union(self, X): EXAMPLES:: sage: Set(QQ).union(Set(ZZ)) - Set-theoretic union of Set of elements of Rational Field and Set of elements of Integer Ring + Set-theoretic union of + Set of elements of Rational Field and + Set of elements of Integer Ring sage: Set(QQ) + Set(ZZ) - Set-theoretic union of Set of elements of Rational Field and Set of elements of Integer Ring - sage: X = Set(QQ).union(Set(GF(3))); X - Set-theoretic union of Set of elements of Rational Field and {0, 1, 2} - sage: 2/3 in X + Set-theoretic union of + Set of elements of Rational Field and + Set of elements of Integer Ring + sage: X = Set(QQ).union(Set(GF(3))); X # optional - sage.rings.finite_rings + Set-theoretic union of + Set of elements of Rational Field and + {0, 1, 2} + sage: 2/3 in X # optional - sage.rings.finite_rings True - sage: GF(3)(2) in X + sage: GF(3)(2) in X # optional - sage.rings.finite_rings True - sage: GF(5)(2) in X + sage: GF(5)(2) in X # optional - sage.rings.finite_rings False - sage: sorted(Set(GF(7)) + Set(GF(3)), key=int) + sage: sorted(Set(GF(7)) + Set(GF(3)), key=int) # optional - sage.rings.finite_rings [0, 0, 1, 1, 2, 2, 3, 4, 5, 6] """ if isinstance(X, (Set_generic, Set_base)): @@ -253,12 +261,10 @@ def intersection(self, X): sage: 2/1 in X True - sage: X = Set(GF(9,'b')).intersection(Set(GF(27,'c'))) - sage: X + sage: X = Set(GF(9,'b')).intersection(Set(GF(27,'c'))); X # optional - sage.rings.finite_rings {} - sage: X = Set(GF(9,'b')).intersection(Set(GF(27,'b'))) - sage: X + sage: X = Set(GF(9,'b')).intersection(Set(GF(27,'b'))); X # optional - sage.rings.finite_rings {} """ if isinstance(X, (Set_generic, Set_base)): @@ -282,12 +288,10 @@ def difference(self, X): sage: 4/1 in X True - sage: X = Set(GF(9,'b')).difference(Set(GF(27,'c'))) - sage: X + sage: X = Set(GF(9,'b')).difference(Set(GF(27,'c'))); X # optional - sage.rings.finite_rings {0, 1, 2, b, b + 1, b + 2, 2*b, 2*b + 1, 2*b + 2} - sage: X = Set(GF(9,'b')).difference(Set(GF(27,'b'))) - sage: X + sage: X = Set(GF(9,'b')).difference(Set(GF(27,'b'))); X # optional - sage.rings.finite_rings {0, 1, 2, b, b + 1, b + 2, 2*b, 2*b + 1, 2*b + 2} """ if isinstance(X, (Set_generic, Set_base)): @@ -325,7 +329,7 @@ def _test_as_set_object(self, tester=None, **options): Instances of other subclasses of :class:`Set_base` run this method:: - sage: Polyhedron()._test_as_set_object(verbose=True) + sage: Polyhedron()._test_as_set_object(verbose=True) # optional - sage.geometry.polyhedron Running the test suite of Set(self) running ._test_an_element() . . . pass ... @@ -407,15 +411,15 @@ def __add__(self, X): EXAMPLES:: - sage: Set(RealField()) + Set(QQ^5) + sage: Set(RealField()) + Set(QQ^5) # optional - sage.modules Set-theoretic union of Set of elements of Real Field with 53 bits of precision and Set of elements of Vector space of dimension 5 over Rational Field - sage: Set(GF(3)) + Set(GF(2)) + sage: Set(GF(3)) + Set(GF(2)) # optional - sage.rings.finite_rings {0, 1, 2, 0, 1} - sage: Set(GF(2)) + Set(GF(4,'a')) + sage: Set(GF(2)) + Set(GF(4,'a')) # optional - sage.rings.finite_rings {0, 1, a, a + 1} - sage: sorted(Set(GF(8,'b')) + Set(GF(4,'a')), key=str) + sage: sorted(Set(GF(8,'b')) + Set(GF(4,'a')), key=str) # optional - sage.rings.finite_rings [0, 0, 1, 1, a, a + 1, b, b + 1, b^2, b^2 + 1, b^2 + b, b^2 + b + 1] """ return self.union(X) @@ -441,14 +445,14 @@ class Set_object(Set_generic, Set_base, Set_boolean_operators, Set_add_sub_opera EXAMPLES:: - sage: K = GF(19) - sage: Set(K) + sage: K = GF(19) # optional - sage.rings.finite_rings + sage: Set(K) # optional - sage.rings.finite_rings {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18} - sage: S = Set(K) + sage: S = Set(K) # optional - sage.rings.finite_rings - sage: latex(S) + sage: latex(S) # optional - sage.rings.finite_rings \left\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\right\} - sage: TestSuite(S).run() + sage: TestSuite(S).run() # optional - sage.rings.finite_rings sage: latex(Set(ZZ)) \Bold{Z} @@ -606,7 +610,7 @@ def __contains__(self, x): sage: X = Set(ZZ) sage: 5 in X True - sage: GF(7)(3) in X + sage: GF(7)(3) in X # optional - sage.rings.finite_rings True sage: 2/1 in X True @@ -618,16 +622,16 @@ def __contains__(self, x): Finite fields better illustrate the difference between ``__contains__`` for objects and their underlying sets:: - sage: X = Set(GF(7)) - sage: X + sage: X = Set(GF(7)) # optional - sage.rings.finite_rings + sage: X # optional - sage.rings.finite_rings {0, 1, 2, 3, 4, 5, 6} - sage: 5/3 in X + sage: 5/3 in X # optional - sage.rings.finite_rings False - sage: 5/3 in GF(7) + sage: 5/3 in GF(7) # optional - sage.rings.finite_rings False - sage: sorted(Set(GF(7)).union(Set(GF(5))), key=int) + sage: sorted(Set(GF(7)).union(Set(GF(5))), key=int) # optional - sage.rings.finite_rings [0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6] - sage: Set(GF(7)).intersection(Set(GF(5))) + sage: Set(GF(7)).intersection(Set(GF(5))) # optional - sage.rings.finite_rings {} """ return x in self.__object @@ -671,9 +675,9 @@ def cardinality(self): +Infinity sage: Primes().cardinality() +Infinity - sage: Set(GF(5)).cardinality() + sage: Set(GF(5)).cardinality() # optional - sage.rings.finite_rings 5 - sage: Set(GF(5^2,'a')).cardinality() + sage: Set(GF(5^2,'a')).cardinality() # optional - sage.rings.finite_rings 25 """ if self in Sets().Infinite(): @@ -711,7 +715,7 @@ def is_empty(self): False sage: Set([1..100]).is_empty() False - sage: Set(SymmetricGroup(2).list()).is_empty() + sage: Set(SymmetricGroup(2).list()).is_empty() # optional - sage.groups False sage: Set(ZZ).is_empty() False @@ -724,7 +728,7 @@ def is_empty(self): False sage: Set([1..100]).is_empty() False - sage: Set(DihedralGroup(4).list()).is_empty() + sage: Set(DihedralGroup(4).list()).is_empty() # optional - sage.groups False sage: Set(QQ).is_empty() False @@ -739,7 +743,7 @@ def is_finite(self): sage: Set(QQ).is_finite() False - sage: Set(GF(250037)).is_finite() + sage: Set(GF(250037)).is_finite() # optional - sage.rings.finite_rings True sage: Set(Integers(2^1000000)).is_finite() True @@ -781,9 +785,9 @@ def subsets(self, size=None): EXAMPLES:: sage: X = Set([1, 2, 3]) - sage: list(X.subsets()) + sage: list(X.subsets()) # optional - sage.combinat [{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}] - sage: list(X.subsets(2)) + sage: list(X.subsets(2)) # optional - sage.combinat [{1, 2}, {1, 3}, {2, 3}] """ from sage.combinat.subset import Subsets @@ -796,10 +800,10 @@ def subsets_lattice(self): EXAMPLES:: sage: X = Set([1,2,3]) - sage: X.subsets_lattice() + sage: X.subsets_lattice() # optional - sage.combinat Finite lattice containing 8 elements sage: Y = Set() - sage: Y.subsets_lattice() + sage: Y.subsets_lattice() # optional - sage.combinat Finite lattice containing 1 elements """ @@ -835,7 +839,7 @@ def _sympy_(self): sage: X = Set(ZZ); X Set of elements of Integer Ring - sage: X._sympy_() + sage: X._sympy_() # optional - sympy Integers """ from sage.interfaces.sympy import sympy_init @@ -853,13 +857,13 @@ def __init__(self, X, category=None): EXAMPLES:: - sage: S = Set(GF(19)); S + sage: S = Set(GF(19)); S # optional - sage.rings.finite_rings {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18} - sage: S.category() + sage: S.category() # optional - sage.rings.finite_rings Category of finite enumerated sets - sage: print(latex(S)) + sage: print(latex(S)) # optional - sage.rings.finite_rings \left\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\right\} - sage: TestSuite(S).run() + sage: TestSuite(S).run() # optional - sage.rings.finite_rings """ Set_object.__init__(self, X, category=FiniteEnumeratedSets().or_subcategory(category)) @@ -884,7 +888,7 @@ def is_finite(self): EXAMPLES:: - sage: Set(GF(19)).is_finite() + sage: Set(GF(19)).is_finite() # optional - sage.rings.finite_rings True """ return True @@ -916,15 +920,15 @@ def __iter__(self): EXAMPLES:: - sage: S = Set(GF(19)) - sage: I = iter(S) - sage: next(I) + sage: S = Set(GF(19)) # optional - sage.rings.finite_rings + sage: I = iter(S) # optional - sage.rings.finite_rings + sage: next(I) # optional - sage.rings.finite_rings 0 - sage: next(I) + sage: next(I) # optional - sage.rings.finite_rings 1 - sage: next(I) + sage: next(I) # optional - sage.rings.finite_rings 2 - sage: next(I) + sage: next(I) # optional - sage.rings.finite_rings 3 """ return iter(self.set()) @@ -935,8 +939,8 @@ def _latex_(self): EXAMPLES:: - sage: S = Set(GF(2)) - sage: latex(S) + sage: S = Set(GF(2)) # optional - sage.rings.finite_rings + sage: latex(S) # optional - sage.rings.finite_rings \left\{0, 1\right\} """ return '\\left\\{' + ', '.join(latex(x) for x in self.set()) + '\\right\\}' @@ -947,8 +951,8 @@ def _repr_(self): EXAMPLES:: - sage: S = Set(GF(2)) - sage: S + sage: S = Set(GF(2)) # optional - sage.rings.finite_rings + sage: S # optional - sage.rings.finite_rings {0, 1} TESTS:: @@ -967,12 +971,12 @@ def list(self): EXAMPLES:: - sage: X = Set(GF(8,'c')) - sage: X + sage: X = Set(GF(8,'c')) # optional - sage.rings.finite_rings + sage: X # optional - sage.rings.finite_rings {0, 1, c, c + 1, c^2, c^2 + 1, c^2 + c, c^2 + c + 1} - sage: X.list() + sage: X.list() # optional - sage.rings.finite_rings [0, 1, c, c + 1, c^2, c^2 + 1, c^2 + c, c^2 + c + 1] - sage: type(X.list()) + sage: type(X.list()) # optional - sage.rings.finite_rings <... 'list'> .. TODO:: @@ -995,14 +999,14 @@ def set(self): EXAMPLES:: - sage: X = Set(GF(8,'c')) - sage: X + sage: X = Set(GF(8,'c')) # optional - sage.rings.finite_rings + sage: X # optional - sage.rings.finite_rings {0, 1, c, c + 1, c^2, c^2 + 1, c^2 + c, c^2 + c + 1} - sage: X.set() + sage: X.set() # optional - sage.rings.finite_rings {0, 1, c, c + 1, c^2, c^2 + 1, c^2 + c, c^2 + c + 1} - sage: type(X.set()) + sage: type(X.set()) # optional - sage.rings.finite_rings <... 'set'> - sage: type(X) + sage: type(X) # optional - sage.rings.finite_rings """ return set(self.object()) @@ -1014,22 +1018,22 @@ def frozenset(self): EXAMPLES:: - sage: X = Set(GF(8,'c')) - sage: X + sage: X = Set(GF(8,'c')) # optional - sage.rings.finite_rings + sage: X # optional - sage.rings.finite_rings {0, 1, c, c + 1, c^2, c^2 + 1, c^2 + c, c^2 + c + 1} - sage: s = X.set(); s + sage: s = X.set(); s # optional - sage.rings.finite_rings {0, 1, c, c + 1, c^2, c^2 + 1, c^2 + c, c^2 + c + 1} - sage: hash(s) + sage: hash(s) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unhashable type: 'set' - sage: s = X.frozenset(); s + sage: s = X.frozenset(); s # optional - sage.rings.finite_rings frozenset({0, 1, c, c + 1, c^2, c^2 + 1, c^2 + c, c^2 + c + 1}) - sage: hash(s) != hash(tuple(X.set())) + sage: hash(s) != hash(tuple(X.set())) # optional - sage.rings.finite_rings True - sage: type(s) + sage: type(s) # optional - sage.rings.finite_rings <... 'frozenset'> """ return frozenset(self.object()) @@ -1040,8 +1044,8 @@ def __hash__(self): EXAMPLES:: - sage: s = Set(GF(8,'c')) - sage: hash(s) == hash(s) + sage: s = Set(GF(8,'c')) # optional - sage.rings.finite_rings + sage: hash(s) == hash(s) # optional - sage.rings.finite_rings True """ return hash(self.frozenset()) @@ -1052,10 +1056,10 @@ def __richcmp__(self, other, op): EXAMPLES:: - sage: X = Set(GF(8,'c')) - sage: X == Set(GF(8,'c')) + sage: X = Set(GF(8,'c')) # optional - sage.rings.finite_rings + sage: X == Set(GF(8,'c')) # optional - sage.rings.finite_rings True - sage: X == Set(GF(4,'a')) + sage: X == Set(GF(4,'a')) # optional - sage.rings.finite_rings False sage: Set(QQ) == Set(ZZ) False @@ -1101,7 +1105,7 @@ def issubset(self, other): TESTS:: - sage: len([Z for Z in Y.subsets() if Z.issubset(X)]) + sage: len([Z for Z in Y.subsets() if Z.issubset(X)]) # optional - sage.combinat 8 """ if not isinstance(other, Set_object_enumerated): @@ -1129,7 +1133,7 @@ def issuperset(self, other): TESTS:: - sage: len([Z for Z in Y.subsets() if Z.issuperset(X)]) + sage: len([Z for Z in Y.subsets() if Z.issuperset(X)]) # optional - sage.combinat 4 """ if not isinstance(other, Set_object_enumerated): @@ -1142,13 +1146,13 @@ def union(self, other): EXAMPLES:: - sage: X = Set(GF(8,'c')) - sage: Y = Set([GF(8,'c').0, 1, 2, 3]) - sage: X + sage: X = Set(GF(8,'c')) # optional - sage.rings.finite_rings + sage: Y = Set([GF(8,'c').0, 1, 2, 3]) # optional - sage.rings.finite_rings + sage: X # optional - sage.rings.finite_rings {0, 1, c, c + 1, c^2, c^2 + 1, c^2 + c, c^2 + c + 1} - sage: sorted(Y) + sage: sorted(Y) # optional - sage.rings.finite_rings [1, 2, 3, c] - sage: sorted(X.union(Y), key=str) + sage: sorted(X.union(Y), key=str) # optional - sage.rings.finite_rings [0, 1, 2, 3, c, c + 1, c^2, c^2 + 1, c^2 + c, c^2 + c + 1] """ if not isinstance(other, Set_object_enumerated): @@ -1161,9 +1165,9 @@ def intersection(self, other): EXAMPLES:: - sage: X = Set(GF(8,'c')) - sage: Y = Set([GF(8,'c').0, 1, 2, 3]) - sage: X.intersection(Y) + sage: X = Set(GF(8,'c')) # optional - sage.rings.finite_rings + sage: Y = Set([GF(8,'c').0, 1, 2, 3]) # optional - sage.rings.finite_rings + sage: X.intersection(Y) # optional - sage.rings.finite_rings {1, c} """ if not isinstance(other, Set_object_enumerated): @@ -1227,16 +1231,16 @@ def _sympy_(self): sage: X = Set({1, 2, 3}); X {1, 2, 3} - sage: sX = X._sympy_(); sX + sage: sX = X._sympy_(); sX # optional - sympy Set(1, 2, 3) - sage: sX.is_empty is None + sage: sX.is_empty is None # optional - sympy True sage: Empty = Set([]); Empty {} - sage: sEmpty = Empty._sympy_(); sEmpty + sage: sEmpty = Empty._sympy_(); sEmpty # optional - sympy EmptySet - sage: sEmpty.is_empty + sage: sEmpty.is_empty # optional - sympy True """ from sympy import Set, EmptySet @@ -1264,10 +1268,10 @@ class Set_object_binary(Set_object, metaclass=ClasscallMetaclass): EXAMPLES:: - sage: X = Set(QQ^2) + sage: X = Set(QQ^2) # optional - sage.modules sage: Y = Set(ZZ) sage: from sage.sets.set import Set_object_binary - sage: S = Set_object_binary(X, Y, "union", "\\cup"); S + sage: S = Set_object_binary(X, Y, "union", "\\cup"); S # optional - sage.modules Set-theoretic union of Set of elements of Vector space of dimension 2 over Rational Field and Set of elements of Integer Ring @@ -1281,9 +1285,9 @@ def __classcall__(cls, X, Y, *args, **kwds): TESTS:: sage: from sage.sets.set import Set_object_binary - sage: X = QQ^2 + sage: X = QQ^2 # optional - sage.modules sage: Y = ZZ - sage: Set_object_binary(X, Y, "union", "\\cup") + sage: Set_object_binary(X, Y, "union", "\\cup") # optional - sage.modules Set-theoretic union of Set of elements of Vector space of dimension 2 over Rational Field and Set of elements of Integer Ring @@ -1301,10 +1305,10 @@ def __init__(self, X, Y, op, latex_op, category=None): TESTS:: sage: from sage.sets.set import Set_object_binary - sage: X = Set(QQ^2) + sage: X = Set(QQ^2) # optional - sage.modules sage: Y = Set(ZZ) - sage: S = Set_object_binary(X, Y, "union", "\\cup") - sage: type(S) + sage: S = Set_object_binary(X, Y, "union", "\\cup") # optional - sage.modules + sage: type(S) # optional - sage.modules """ self._X = X @@ -1319,7 +1323,7 @@ def _repr_(self): EXAMPLES:: - sage: Set(ZZ).union(Set(GF(5))) + sage: Set(ZZ).union(Set(GF(5))) # optional - sage.rings.finite_rings Set-theoretic union of Set of elements of Integer Ring and {0, 1, 2, 3, 4} """ return "Set-theoretic {} of {} and {}".format(self._op, self._X, self._Y) @@ -1330,7 +1334,7 @@ def _latex_(self): EXAMPLES:: - sage: latex(Set(ZZ).union(Set(GF(5)))) + sage: latex(Set(ZZ).union(Set(GF(5)))) # optional - sage.rings.finite_rings \Bold{Z} \cup \left\{0, 1, 2, 3, 4\right\} """ return latex(self._X) + self._latex_op + latex(self._Y) @@ -1344,9 +1348,9 @@ def __hash__(self): The hash values of equal sets are in general not equal since it is not decidable whether two sets are equal:: - sage: X = Set(GF(13)).intersection(Set(ZZ)) - sage: Y = Set(ZZ).intersection(Set(GF(13))) - sage: hash(X) == hash(Y) + sage: X = Set(GF(13)).intersection(Set(ZZ)) # optional - sage.rings.finite_rings + sage: Y = Set(ZZ).intersection(Set(GF(13))) # optional - sage.rings.finite_rings + sage: hash(X) == hash(Y) # optional - sage.rings.finite_rings False TESTS: @@ -1371,17 +1375,19 @@ def __init__(self, X, Y, category=None): EXAMPLES:: - sage: S = Set(QQ^2) + sage: S = Set(QQ^2) # optional - sage.modules sage: T = Set(ZZ) - sage: X = S.union(T); X - Set-theoretic union of Set of elements of Vector space of dimension 2 over Rational Field and Set of elements of Integer Ring - sage: X.category() + sage: X = S.union(T); X # optional - sage.modules + Set-theoretic union of + Set of elements of Vector space of dimension 2 over Rational Field and + Set of elements of Integer Ring + sage: X.category() # optional - sage.modules Category of infinite sets - sage: latex(X) + sage: latex(X) # optional - sage.modules \Bold{Q}^{2} \cup \Bold{Z} - sage: TestSuite(X).run() + sage: TestSuite(X).run() # optional - sage.modules """ if category is None: category = Sets() @@ -1422,11 +1428,11 @@ def __richcmp__(self, right, op): EXAMPLES:: - sage: Y = Set(ZZ^2).union(Set(ZZ^3)) - sage: X = Set(ZZ^3).union(Set(ZZ^2)) - sage: X == Y + sage: Y = Set(ZZ^2).union(Set(ZZ^3)) # optional - sage.modules + sage: X = Set(ZZ^3).union(Set(ZZ^2)) # optional - sage.modules + sage: X == Y # optional - sage.modules True - sage: Y == X + sage: Y == X # optional - sage.modules True This illustrates that equality testing for formal unions @@ -1452,7 +1458,7 @@ def __iter__(self): EXAMPLES:: - sage: [x for x in Set(GF(3)).union(Set(GF(2)))] + sage: [x for x in Set(GF(3)).union(Set(GF(2)))] # optional - sage.rings.finite_rings [0, 1, 2, 0, 1] """ for x in self._X: @@ -1466,14 +1472,14 @@ def __contains__(self, x): EXAMPLES:: - sage: X = Set(GF(3)).union(Set(GF(2))) - sage: GF(5)(1) in X + sage: X = Set(GF(3)).union(Set(GF(2))) # optional - sage.rings.finite_rings + sage: GF(5)(1) in X # optional - sage.rings.finite_rings False - sage: GF(3)(2) in X + sage: GF(3)(2) in X # optional - sage.rings.finite_rings True - sage: GF(2)(0) in X + sage: GF(2)(0) in X # optional - sage.rings.finite_rings True - sage: GF(5)(0) in X + sage: GF(5)(0) in X # optional - sage.rings.finite_rings False """ return x in self._X or x in self._Y @@ -1484,14 +1490,14 @@ def cardinality(self): EXAMPLES:: - sage: X = Set(GF(3)).union(Set(GF(2))) - sage: X + sage: X = Set(GF(3)).union(Set(GF(2))) # optional - sage.rings.finite_rings + sage: X # optional - sage.rings.finite_rings {0, 1, 2, 0, 1} - sage: X.cardinality() + sage: X.cardinality() # optional - sage.rings.finite_rings 5 - sage: X = Set(GF(3)).union(Set(ZZ)) - sage: X.cardinality() + sage: X = Set(GF(3)).union(Set(ZZ)) # optional - sage.rings.finite_rings + sage: X.cardinality() # optional - sage.rings.finite_rings +Infinity """ return self._X.cardinality() + self._Y.cardinality() @@ -1505,7 +1511,7 @@ def _sympy_(self): sage: X = Set(ZZ).union(Set([1/2])); X Set-theoretic union of Set of elements of Integer Ring and {1/2} - sage: X._sympy_() + sage: X._sympy_() # optional - sympy Union(Integers, Set(1/2)) """ from sympy import Union @@ -1524,13 +1530,15 @@ def __init__(self, X, Y, category=None): EXAMPLES:: - sage: S = Set(QQ^2) - sage: T = Set(ZZ) - sage: X = S.intersection(T); X - Set-theoretic intersection of Set of elements of Vector space of dimension 2 over Rational Field and Set of elements of Integer Ring - sage: X.category() + sage: S = Set(QQ^2) # optional - sage.modules + sage: T = Set(ZZ) # optional - sage.modules + sage: X = S.intersection(T); X # optional - sage.modules + Set-theoretic intersection of + Set of elements of Vector space of dimension 2 over Rational Field and + Set of elements of Integer Ring + sage: X.category() # optional - sage.modules Category of enumerated sets - sage: latex(X) + sage: latex(X) # optional - sage.modules \Bold{Q}^{2} \cap \Bold{Z} sage: X = Set(IntegerRange(100)).intersection(Primes()) @@ -1684,7 +1692,7 @@ def _sympy_(self): Set-theoretic intersection of Set of elements of Integer Ring and Set of elements of [3/2, 11/2] - sage: X._sympy_() + sage: X._sympy_() # optional - sympy Range(2, 6, 1) """ from sympy import Intersection @@ -1706,7 +1714,9 @@ def __init__(self, X, Y, category=None): sage: S = Set(QQ) sage: T = Set(ZZ) sage: X = S.difference(T); X - Set-theoretic difference of Set of elements of Rational Field and Set of elements of Integer Ring + Set-theoretic difference of + Set of elements of Rational Field and + Set of elements of Integer Ring sage: X.category() Category of sets sage: latex(X) @@ -1853,7 +1863,7 @@ def _sympy_(self): Set of elements of Integer Ring sage: X.category() Category of sets - sage: X._sympy_() + sage: X._sympy_() # optional - sympy Complement(Rationals, Integers) sage: X = Set(ZZ).difference(Set(QQ)); X @@ -1862,7 +1872,7 @@ def _sympy_(self): Set of elements of Rational Field sage: X.category() Category of enumerated sets - sage: X._sympy_() + sage: X._sympy_() # optional - sympy EmptySet """ from sympy import Complement @@ -2029,7 +2039,7 @@ def _sympy_(self): Set-theoretic symmetric difference of Set of elements of Integer Ring and {0, 1, 2, 1/3, 2/3, 4/3, 5/3, 7/3, 8/3} - sage: X._sympy_() + sage: X._sympy_() # optional - sympy Union(Complement(Integers, Set(0, 1, 2, 1/3, 2/3, 4/3, 5/3, 7/3, 8/3)), Complement(Set(0, 1, 2, 1/3, 2/3, 4/3, 5/3, 7/3, 8/3), Integers)) """ diff --git a/src/sage/sets/set_from_iterator.py b/src/sage/sets/set_from_iterator.py index a99a559b691..fbbbbe4c9a0 100644 --- a/src/sage/sets/set_from_iterator.py +++ b/src/sage/sets/set_from_iterator.py @@ -460,7 +460,7 @@ def _instancedoc_(self): sage: print(sage_getdoc(d)) # indirect doctest Test whether "self" is prime. ... - Calls the PARI "isprime" function. + Calls the PARI ...isprime... """ # Duplicates sage.misc.cachefunc.CachedFunction._instancedoc_ from sage.misc.sageinspect import sage_getsourcelines, sage_getfile_relative, _extract_embedded_position diff --git a/src/sage/sets/totally_ordered_finite_set.py b/src/sage/sets/totally_ordered_finite_set.py index 8a6966a845a..e6138644510 100644 --- a/src/sage/sets/totally_ordered_finite_set.py +++ b/src/sage/sets/totally_ordered_finite_set.py @@ -45,7 +45,7 @@ def __init__(self, parent, data): r""" TESTS:: - sage: T = TotallyOrderedFiniteSet([3,2,1],facade=False) + sage: T = TotallyOrderedFiniteSet([3,2,1], facade=False) sage: TestSuite(T.an_element()).run() """ Element.__init__(self, parent) @@ -173,8 +173,8 @@ class TotallyOrderedFiniteSet(FiniteEnumeratedSet): sage: T1 = TotallyOrderedFiniteSet([3,2,5,1]) sage: T1(3) < T1(1) False - sage: T2 = TotallyOrderedFiniteSet([3,var('x')]) - sage: T2(3) < T2(var('x')) + sage: T2 = TotallyOrderedFiniteSet([3, x]) # optional - sage.symbolic + sage: T2(3) < T2(x) # optional - sage.symbolic 3 < x To make the above example work, you should set the argument facade to diff --git a/src/sage/stats/basic_stats.py b/src/sage/stats/basic_stats.py index d83f08111f0..64459f7ff24 100644 --- a/src/sage/stats/basic_stats.py +++ b/src/sage/stats/basic_stats.py @@ -40,7 +40,8 @@ ###################################################################### from sage.rings.integer_ring import ZZ -from sage.symbolic.constants import NaN +from sage.misc.lazy_import import lazy_import +lazy_import("sage.symbolic.constants", "NaN") from sage.misc.functional import sqrt from sage.misc.superseded import deprecation @@ -216,9 +217,9 @@ def std(v, bias=False): + (5*sqrt(2) - 10*I + 3)^2 + (5*sqrt(2) + 5*I - 6)^2) sage: std([RIF(1.0103, 1.0103), RIF(2)]) 0.6998235813403261? - sage: import numpy - sage: x = numpy.array([1,2,3,4,5]) - sage: std(x, bias=False) + sage: import numpy # optional - numpy + sage: x = numpy.array([1,2,3,4,5]) # optional - numpy + sage: std(x, bias=False) # optional - numpy 1.5811388300841898 sage: x = stats.TimeSeries([1..100]) sage: std(x) @@ -295,9 +296,9 @@ def variance(v, bias=False): + 1/450*(5*sqrt(2) + 5*I - 6)^2 sage: variance([RIF(1.0103, 1.0103), RIF(2)]) 0.4897530450000000? - sage: import numpy - sage: x = numpy.array([1,2,3,4,5]) - sage: variance(x, bias=False) + sage: import numpy # optional - numpy + sage: x = numpy.array([1,2,3,4,5]) # optional - numpy + sage: variance(x, bias=False) # optional - numpy 2.5 sage: x = stats.TimeSeries([1..100]) sage: variance(x) diff --git a/src/sage/stats/distributions/discrete_gaussian_lattice.py b/src/sage/stats/distributions/discrete_gaussian_lattice.py index 766cb2d4a41..c3a72ac22e2 100644 --- a/src/sage/stats/distributions/discrete_gaussian_lattice.py +++ b/src/sage/stats/distributions/discrete_gaussian_lattice.py @@ -56,17 +56,20 @@ # policies, either expressed or implied, of the FreeBSD Project. #*****************************************************************************/ -from sage.functions.log import exp -from sage.functions.other import ceil -from sage.rings.real_mpfr import RealField -from sage.rings.real_mpfr import RR -from sage.rings.integer_ring import ZZ -from sage.rings.rational_field import QQ -from .discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler -from sage.structure.sage_object import SageObject from sage.matrix.constructor import matrix, identity_matrix +from sage.misc.lazy_import import lazy_import from sage.modules.free_module import FreeModule from sage.modules.free_module_element import vector +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.real_mpfr import RR +from sage.rings.real_mpfr import RealField +from sage.structure.sage_object import SageObject + +lazy_import("sage.functions.log", "exp") +lazy_import("sage.functions.other", "ceil") + +from .discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler def _iter_vectors(n, lower, upper, step=None): diff --git a/src/sage/stats/distributions/discrete_gaussian_polynomial.py b/src/sage/stats/distributions/discrete_gaussian_polynomial.py index 0f4e7e59361..7598f9beb99 100644 --- a/src/sage/stats/distributions/discrete_gaussian_polynomial.py +++ b/src/sage/stats/distributions/discrete_gaussian_polynomial.py @@ -14,11 +14,11 @@ EXAMPLES:: sage: from sage.stats.distributions.discrete_gaussian_polynomial import DiscreteGaussianDistributionPolynomialSampler - sage: sigma = 3.0; n=1000 + sage: sigma = 3.0; n = 1000 sage: l = [DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], 64, sigma)() for _ in range(n)] sage: l = [vector(f).norm().n() for f in l] - sage: from numpy import mean - sage: mean(l), sqrt(64)*sigma # abs tol 5e-1 + sage: from numpy import mean # optional - numpy + sage: mean(l), sqrt(64)*sigma # abs tol 5e-1 # optional - numpy (24.0, 24.0) """ @@ -74,7 +74,9 @@ class DiscreteGaussianDistributionPolynomialSampler(SageObject): True sage: gs = DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], 8, 3.0) sage: [gs() for _ in range(3)] # random - [4*x^7 + 4*x^6 - 4*x^5 + 2*x^4 + x^3 - 4*x + 7, -5*x^6 + 4*x^5 - 3*x^3 + 4*x^2 + x, 2*x^7 + 2*x^6 + 2*x^5 - x^4 - 2*x^2 + 3*x + 1] + [4*x^7 + 4*x^6 - 4*x^5 + 2*x^4 + x^3 - 4*x + 7, + -5*x^6 + 4*x^5 - 3*x^3 + 4*x^2 + x, + 2*x^7 + 2*x^6 + 2*x^5 - x^4 - 2*x^2 + 3*x + 1] .. automethod:: __init__ .. automethod:: __call__ diff --git a/src/sage/stats/time_series.pyx b/src/sage/stats/time_series.pyx index 01a735a9679..9d69f200e43 100644 --- a/src/sage/stats/time_series.pyx +++ b/src/sage/stats/time_series.pyx @@ -102,22 +102,22 @@ cdef class TimeSeries: Conversion from a NumPy 1-D array, which is very fast:: sage: v = stats.TimeSeries([1..5]) - sage: w = v.numpy() - sage: stats.TimeSeries(w) + sage: w = v.numpy() # optional - numpy + sage: stats.TimeSeries(w) # optional - numpy [1.0000, 2.0000, 3.0000, 4.0000, 5.0000] Conversion from an n-dimensional NumPy array also works:: - sage: import numpy - sage: v = numpy.array([[1,2], [3,4]], dtype=float); v + sage: import numpy # optional - numpy + sage: v = numpy.array([[1,2], [3,4]], dtype=float); v # optional - numpy array([[1., 2.], [3., 4.]]) - sage: stats.TimeSeries(v) + sage: stats.TimeSeries(v) # optional - numpy [1.0000, 2.0000, 3.0000, 4.0000] - sage: stats.TimeSeries(v[:,0]) + sage: stats.TimeSeries(v[:,0]) # optional - numpy [1.0000, 3.0000] - sage: u = numpy.array([[1,2],[3,4]]) - sage: stats.TimeSeries(u) + sage: u = numpy.array([[1,2],[3,4]]) # optional - numpy + sage: stats.TimeSeries(u) # optional - numpy [1.0000, 2.0000, 3.0000, 4.0000] For speed purposes we don't initialize (so value is garbage):: diff --git a/src/sage/structure/category_object.pyx b/src/sage/structure/category_object.pyx index 52abd7d918b..ce6bc22c52b 100644 --- a/src/sage/structure/category_object.pyx +++ b/src/sage/structure/category_object.pyx @@ -36,14 +36,14 @@ This example illustrates generators for a free module over `\ZZ`. :: - sage: M = FreeModule(ZZ, 4) - sage: M + sage: M = FreeModule(ZZ, 4) # optional - sage.modules + sage: M # optional - sage.modules Ambient free module of rank 4 over the principal ideal domain Integer Ring - sage: M.ngens() + sage: M.ngens() # optional - sage.modules 4 - sage: M.gen(0) + sage: M.gen(0) # optional - sage.modules (1, 0, 0, 0) - sage: M.gens() + sage: M.gens() # optional - sage.modules ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)) """ @@ -271,8 +271,8 @@ cdef class CategoryObject(SageObject): EXAMPLES:: - sage: B. = BooleanPolynomialRing() - sage: B.gens_dict() + sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: B.gens_dict() # optional - sage.rings.polynomial.pbori {'a': a, 'b': b, 'c': c, 'd': d} TESTS:: @@ -352,16 +352,16 @@ cdef class CategoryObject(SageObject): For orders, we correctly use the ring generator, see :trac:`15348`:: - sage: A. = ZZ.extension(x^2 + 1) - sage: i + sage: A. = ZZ.extension(x^2 + 1) # optional - sage.rings.number_field + sage: i # optional - sage.rings.number_field i - sage: parent(i) + sage: parent(i) # optional - sage.rings.number_field Order in Number Field in i with defining polynomial x^2 + 1 :: - sage: B. = EquationOrder(x^2 + 3) - sage: z.minpoly() + sage: B. = EquationOrder(x^2 + 3) # optional - sage.rings.number_field + sage: z.minpoly() # optional - sage.rings.number_field x^2 + 3 """ return self._defining_names()[:n] @@ -389,18 +389,18 @@ cdef class CategoryObject(SageObject): For orders, we correctly use the ring generator, see :trac:`15348`:: - sage: B. = EquationOrder(x^2 + 3) - sage: B._defining_names() + sage: B. = EquationOrder(x^2 + 3) # optional - sage.rings.number_field + sage: B._defining_names() # optional - sage.rings.number_field (z,) For vector spaces and free modules, we get a basis (which can be different from the given generators):: - sage: V = ZZ^3 - sage: V._defining_names() + sage: V = ZZ^3 # optional - sage.modules + sage: V._defining_names() # optional - sage.modules ((1, 0, 0), (0, 1, 0), (0, 0, 1)) - sage: W = V.span([(0, 1, 0), (1/2, 1, 0)]) - sage: W._defining_names() + sage: W = V.span([(0, 1, 0), (1/2, 1, 0)]) # optional - sage.modules + sage: W._defining_names() # optional - sage.modules ((1/2, 0, 0), (0, 1, 0)) """ return self.gens() @@ -501,10 +501,10 @@ cdef class CategoryObject(SageObject): wants to print elements of the quotient of such an "unnamed" ring, an error resulted. That was fixed in :trac:`11068`:: - sage: MS = MatrixSpace(GF(5),2,2) - sage: I = MS*[MS.0*MS.1,MS.2+MS.3]*MS - sage: Q. = MS.quo(I) - sage: a #indirect doctest + sage: MS = MatrixSpace(GF(5), 2, 2) # optional - sage.rings.finite_rings sage.modules + sage: I = MS * [MS.0*MS.1, MS.2 + MS.3] * MS # optional - sage.rings.finite_rings sage.modules + sage: Q. = MS.quo(I) # optional - sage.rings.finite_rings sage.modules + sage: a #indirect doctest # optional - sage.rings.finite_rings sage.modules [1 0] [0 0] @@ -563,42 +563,42 @@ cdef class CategoryObject(SageObject): EXAMPLES:: - sage: from sage.modules.module import Module - sage: Module(ZZ).base_ring() + sage: from sage.modules.module import Module # optional - sage.modules + sage: Module(ZZ).base_ring() # optional - sage.modules Integer Ring - sage: F = FreeModule(ZZ,3) - sage: F.base_ring() + sage: F = FreeModule(ZZ, 3) # optional - sage.modules + sage: F.base_ring() # optional - sage.modules Integer Ring - sage: F.__class__.base_ring + sage: F.__class__.base_ring # optional - sage.modules Note that the coordinates of the elements of a module can lie in a bigger ring, the ``coordinate_ring``:: - sage: M = (ZZ^2) * (1/2) - sage: v = M([1/2, 0]) - sage: v.base_ring() + sage: M = (ZZ^2) * (1/2) # optional - sage.modules + sage: v = M([1/2, 0]) # optional - sage.modules + sage: v.base_ring() # optional - sage.modules Integer Ring - sage: parent(v[0]) + sage: parent(v[0]) # optional - sage.modules Rational Field - sage: v.coordinate_ring() + sage: v.coordinate_ring() # optional - sage.modules Rational Field More examples:: - sage: F = FreeAlgebra(QQ, 'x') - sage: F.base_ring() + sage: F = FreeAlgebra(QQ, 'x') # optional - sage.combinat sage.modules + sage: F.base_ring() # optional - sage.combinat sage.modules Rational Field - sage: F.__class__.base_ring + sage: F.__class__.base_ring # optional - sage.combinat sage.modules - sage: E = CombinatorialFreeModule(ZZ, [1,2,3]) - sage: F = CombinatorialFreeModule(ZZ, [2,3,4]) - sage: H = Hom(E, F) - sage: H.base_ring() + sage: E = CombinatorialFreeModule(ZZ, [1,2,3]) # optional - sage.modules + sage: F = CombinatorialFreeModule(ZZ, [2,3,4]) # optional - sage.modules + sage: H = Hom(E, F) # optional - sage.modules + sage: H.base_ring() # optional - sage.modules Integer Ring - sage: H.__class__.base_ring + sage: H.__class__.base_ring # optional - sage.modules .. TODO:: @@ -627,7 +627,9 @@ cdef class CategoryObject(SageObject): sage: R. = PolynomialRing(QQ, 2) sage: R.Hom(QQ) - Set of Homomorphisms from Multivariate Polynomial Ring in x, y over Rational Field to Rational Field + Set of Homomorphisms + from Multivariate Polynomial Ring in x, y over Rational Field + to Rational Field Homspaces are defined for very general Sage objects, even elements of familiar rings. @@ -635,7 +637,7 @@ cdef class CategoryObject(SageObject): sage: n = 5; Hom(n,7) Set of Morphisms from 5 to 7 in Category of elements of Integer Ring - sage: z=(2/3); Hom(z,8/1) + sage: z = 2/3; Hom(z, 8/1) Set of Morphisms from 2/3 to 8 in Category of elements of Rational Field This example illustrates the optional third argument:: @@ -663,7 +665,8 @@ cdef class CategoryObject(SageObject): sage: x (x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) sage: R.latex_variable_names () - ['x_{0}', 'x_{1}', 'x_{2}', 'x_{3}', 'x_{4}', 'x_{5}', 'x_{6}', 'x_{7}', 'x_{8}', 'x_{9}', 'x_{10}', 'x_{11}'] + ['x_{0}', 'x_{1}', 'x_{2}', 'x_{3}', 'x_{4}', 'x_{5}', 'x_{6}', + 'x_{7}', 'x_{8}', 'x_{9}', 'x_{10}', 'x_{11}'] sage: f = x[0]^3 + 15/3 * x[1]^10 sage: print(latex(f)) 5 x_{1}^{10} + x_{0}^{3} @@ -890,8 +893,8 @@ cdef class CategoryObject(SageObject): _test_some_elements _test_zero _test_zero_divisors - sage: F = GF(9,'a') - sage: dir(F) + sage: F = GF(9,'a') # optional - sage.rings.finite_rings + sage: dir(F) # optional - sage.rings.finite_rings [..., '__class__', ..., '_test_pickling', ..., 'extension', ...] """ diff --git a/src/sage/structure/coerce.pyx b/src/sage/structure/coerce.pyx index 86664258c8c..2c525ffd5ca 100644 --- a/src/sage/structure/coerce.pyx +++ b/src/sage/structure/coerce.pyx @@ -21,9 +21,9 @@ there. For example:: Rational Field sage: b = ZZ['x'].gen(); b.parent() Univariate Polynomial Ring in x over Integer Ring - sage: a+b + sage: a + b x + 1/2 - sage: (a+b).parent() + sage: (a + b).parent() Univariate Polynomial Ring in x over Rational Field If there is a coercion (see below) from one of the parents to the other, @@ -124,17 +124,17 @@ cpdef py_scalar_parent(py_type): sage: py_scalar_parent(fractions.Fraction) Rational Field - sage: import numpy - sage: py_scalar_parent(numpy.int16) + sage: import numpy # optional - numpy + sage: py_scalar_parent(numpy.int16) # optional - numpy Integer Ring - sage: py_scalar_parent(numpy.int32) + sage: py_scalar_parent(numpy.int32) # optional - numpy Integer Ring - sage: py_scalar_parent(numpy.uint64) + sage: py_scalar_parent(numpy.uint64) # optional - numpy Integer Ring sage: py_scalar_parent(float) Real Double Field - sage: py_scalar_parent(numpy.double) + sage: py_scalar_parent(numpy.double) # optional - numpy Real Double Field sage: py_scalar_parent(complex) @@ -248,15 +248,15 @@ cpdef py_scalar_to_element(x): sage: for x in elt: ....: assert py_scalar_parent(type(x)) == py_scalar_to_element(x).parent() - sage: import numpy - sage: elt = [numpy.int8('-12'), numpy.uint8('143'), + sage: import numpy # optional - numpy + sage: elt = [numpy.int8('-12'), numpy.uint8('143'), # optional - numpy ....: numpy.int16('-33'), numpy.uint16('122'), ....: numpy.int32('-19'), numpy.uint32('44'), ....: numpy.int64('-3'), numpy.uint64('552'), ....: numpy.float16('-1.23'), numpy.float32('-2.22'), ....: numpy.float64('-3.412'), numpy.complex64(1.2+I), - ....: numpy.complex128(-2+I)] - sage: for x in elt: + ....: numpy.complex128(-2+I)] + sage: for x in elt: # optional - numpy ....: assert py_scalar_parent(type(x)) == py_scalar_to_element(x).parent() sage: elt = [gmpy2.mpz(42), gmpy2.mpq('3/4'), @@ -323,10 +323,10 @@ cpdef bint parent_is_integers(P) except -1: sage: parent_is_integers(dict) False - sage: import numpy - sage: parent_is_integers(numpy.int16) + sage: import numpy # optional - numpy + sage: parent_is_integers(numpy.int16) # optional - numpy True - sage: parent_is_integers(numpy.uint64) + sage: parent_is_integers(numpy.uint64) # optional - numpy True sage: parent_is_integers(float) False @@ -365,12 +365,17 @@ def parent_is_numerical(P): EXAMPLES:: sage: from sage.structure.coerce import parent_is_numerical - sage: import gmpy2, numpy - sage: [parent_is_numerical(R) for R in [RR, CC, QQ, QuadraticField(-1), - ....: int, complex, gmpy2.mpc, numpy.complexfloating]] - [True, True, True, True, True, True, True, True] - sage: [parent_is_numerical(R) for R in [SR, QQ['x'], QQ[['x']], str]] - [False, False, False, False] + sage: import gmpy2 + sage: [parent_is_numerical(R) for R in [RR, CC, QQ, int, complex, gmpy2.mpc]] + [True, True, True, True, True, True] + sage: parent_is_numerical(QuadraticField(-1)) # optional - sage.rings.number_field + True + sage: import numpy; parent_is_numerical(numpy.complexfloating) # optional - numpy + True + sage: parent_is_numerical(SR) # optional - sage.symbolic + False + sage: [parent_is_numerical(R) for R in [QQ['x'], QQ[['x']], str]] + [False, False, False] sage: [parent_is_numerical(R) for R in [RIF, RBF, CIF, CBF]] [False, False, False, False] """ @@ -388,15 +393,22 @@ def parent_is_real_numerical(P): EXAMPLES:: sage: from sage.structure.coerce import parent_is_real_numerical - sage: import gmpy2, numpy - sage: [parent_is_real_numerical(R) for R in [RR, QQ, ZZ, RLF, - ....: QuadraticField(2), int, float, gmpy2.mpq, numpy.integer]] - [True, True, True, True, True, True, True, True, True] - sage: [parent_is_real_numerical(R) for R in [CC, QuadraticField(-1), - ....: complex, gmpy2.mpc, numpy.complexfloating]] - [False, False, False, False, False] - sage: [parent_is_real_numerical(R) for R in [SR, QQ['x'], QQ[['x']], str]] + sage: import gmpy2 + sage: [parent_is_real_numerical(R) for R in [RR, QQ, ZZ, RLF, int, float, gmpy2.mpq]] + [True, True, True, True, True, True, True] + sage: parent_is_real_numerical(QuadraticField(2)) # optional - sage.rings.number_field + True + sage: import numpy; parent_is_real_numerical(numpy.integer) # optional - numpy + True + sage: parent_is_real_numerical(QuadraticField(-1)) # optional - sage.rings.number_field + False + sage: [parent_is_real_numerical(R) + ....: for R in [CC, complex, gmpy2.mpc, numpy.complexfloating]] [False, False, False, False] + sage: [parent_is_real_numerical(R) for R in [QQ['x'], QQ[['x']], str]] + [False, False, False] + sage: parent_is_real_numerical(SR) # optional - sage.symbolic + False sage: [parent_is_real_numerical(R) for R in [RIF, RBF, CIF, CBF]] [False, False, False, False] """ @@ -415,14 +427,14 @@ cpdef bint is_numpy_type(t): EXAMPLES:: sage: from sage.structure.coerce import is_numpy_type - sage: import numpy - sage: is_numpy_type(numpy.int16) + sage: import numpy # optional - numpy + sage: is_numpy_type(numpy.int16) # optional - numpy True - sage: is_numpy_type(numpy.floating) + sage: is_numpy_type(numpy.floating) # optional - numpy True - sage: is_numpy_type(numpy.ndarray) + sage: is_numpy_type(numpy.ndarray) # optional - numpy True - sage: is_numpy_type(numpy.matrix) + sage: is_numpy_type(numpy.matrix) # optional - numpy True sage: is_numpy_type(int) False @@ -465,12 +477,12 @@ cpdef bint is_mpmath_type(t): sage: from sage.structure.coerce import is_mpmath_type sage: is_mpmath_type(int) False - sage: import mpmath - sage: is_mpmath_type(mpmath.mpc(2)) + sage: import mpmath # optional - mpmath + sage: is_mpmath_type(mpmath.mpc(2)) # optional - mpmath False - sage: is_mpmath_type(type(mpmath.mpc(2))) + sage: is_mpmath_type(type(mpmath.mpc(2))) # optional - mpmath True - sage: is_mpmath_type(type(mpmath.mpf(2))) + sage: is_mpmath_type(type(mpmath.mpf(2))) # optional - mpmath True """ return isinstance(t, type) and \ @@ -479,17 +491,18 @@ cpdef bint is_mpmath_type(t): cdef class CoercionModel: """ - See also sage.categories.pushout + See also :mod:`sage.categories.pushout` EXAMPLES:: - sage: f = ZZ['t','x'].0 + QQ['x'].0 + CyclotomicField(13).gen(); f + sage: f = ZZ['t', 'x'].0 + QQ['x'].0 + CyclotomicField(13).gen(); f # optional - sage.rings.number_field t + x + zeta13 - sage: f.parent() - Multivariate Polynomial Ring in t, x over Cyclotomic Field of order 13 and degree 12 + sage: f.parent() # optional - sage.rings.number_field + Multivariate Polynomial Ring in t, x + over Cyclotomic Field of order 13 and degree 12 sage: ZZ['x','y'].0 + ~Frac(QQ['y']).0 (x*y + 1)/y - sage: MatrixSpace(ZZ['x'], 2, 2)(2) + ~Frac(QQ['x']).0 + sage: MatrixSpace(ZZ['x'], 2, 2)(2) + ~Frac(QQ['x']).0 # optional - sage.modules [(2*x + 1)/x 0] [ 0 (2*x + 1)/x] sage: f = ZZ['x,y,z'].0 + QQ['w,x,z,a'].0; f @@ -503,11 +516,11 @@ cdef class CoercionModel: Check that :trac:`8426` is fixed (see also :trac:`18076`):: - sage: import numpy + sage: import numpy # optional - numpy sage: x = polygen(RR) - sage: numpy.float32('1.5') * x + sage: numpy.float32('1.5') * x # optional - numpy 1.50000000000000*x - sage: x * numpy.float32('1.5') + sage: x * numpy.float32('1.5') # optional - numpy 1.50000000000000*x sage: p = x**3 + 2*x - 1 sage: p(float('1.2')) @@ -517,26 +530,26 @@ cdef class CoercionModel: This used to fail (see :trac:`18076`):: - sage: 1/3 + numpy.int8('12') + sage: 1/3 + numpy.int8('12') # optional - numpy 37/3 - sage: -2/3 + numpy.int16('-2') + sage: -2/3 + numpy.int16('-2') # optional - numpy -8/3 - sage: 2/5 + numpy.uint8('2') + sage: 2/5 + numpy.uint8('2') # optional - numpy 12/5 The numpy types do not interact well with the Sage coercion framework. More precisely, if a numpy type is the first operand in a binary operation then this operation is done in numpy. The result is hence a numpy type:: - sage: numpy.uint8('2') + 3 + sage: numpy.uint8('2') + 3 # optional - numpy 5 - sage: type(_) + sage: type(_) # optional - numpy # 32-bit # 64-bit - sage: numpy.int8('12') + 1/3 + sage: numpy.int8('12') + 1/3 # optional - numpy 12.333333333333334 - sage: type(_) + sage: type(_) # optional - numpy AUTHOR: @@ -549,8 +562,9 @@ cdef class CoercionModel: sage: from sage.structure.coerce import CoercionModel sage: cm = CoercionModel() - sage: K = NumberField(x^2-2, 'a') - sage: A = cm.get_action(ZZ, K, operator.mul) + sage: x = polygen(ZZ, 'x') + sage: K = NumberField(x^2 - 2, 'a') # optional - sage.rings.number_field + sage: A = cm.get_action(ZZ, K, operator.mul) # optional - sage.rings.number_field sage: f, g = cm.coercion_maps(QQ, int) sage: f, g = cm.coercion_maps(ZZ, int) """ @@ -591,7 +605,7 @@ cdef class CoercionModel: EXAMPLES:: sage: cm = sage.structure.element.get_coercion_model() - sage: cm.canonical_coercion(1,2/3) + sage: cm.canonical_coercion(1, 2/3) (1, 2/3) sage: maps, actions = cm.get_cache() @@ -635,7 +649,8 @@ cdef class CoercionModel: 1/2*x sage: maps, actions = cm.get_cache() sage: act = actions[QQ, R, operator.mul]; act - Left scalar multiplication by Rational Field on Univariate Polynomial Ring in x over Integer Ring + Left scalar multiplication by Rational Field + on Univariate Polynomial Ring in x over Integer Ring sage: act.actor() Rational Field sage: act.domain() @@ -685,7 +700,7 @@ cdef class CoercionModel: sage: cm = sage.structure.element.get_coercion_model() sage: cm.record_exceptions() - sage: 1+1/2+2 # make sure there aren't any errors hanging around + sage: 1 + 1/2 + 2 # make sure there aren't any errors hanging around 7/2 sage: cm.exception_stack() [] @@ -747,29 +762,32 @@ cdef class CoercionModel: 5/2 sage: cm.exception_stack() [] - sage: 1/2 + GF(3)(2) + sage: 1/2 + GF(3)(2) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for +: 'Rational Field' and 'Finite Field of size 3' + TypeError: unsupported operand parent(s) for +: + 'Rational Field' and 'Finite Field of size 3' Now see what the actual problem was:: sage: import traceback - sage: cm.exception_stack() + sage: cm.exception_stack() # optional - sage.rings.finite_rings ['Traceback (most recent call last):...', 'Traceback (most recent call last):...'] - sage: print(cm.exception_stack()[-1]) + sage: print(cm.exception_stack()[-1]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Rational Field' and 'Finite Field of size 3' + TypeError: no common canonical parent for objects with parents: + 'Rational Field' and 'Finite Field of size 3' This is typically accessed via the :func:`coercion_traceback` function. :: - sage: coercion_traceback() + sage: coercion_traceback() # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Rational Field' and 'Finite Field of size 3' + TypeError: no common canonical parent for objects with parents: + 'Rational Field' and 'Finite Field of size 3' """ if not self._exceptions_cleared: self._exception_stack = [] @@ -805,7 +823,8 @@ cdef class CoercionModel: sage: R = ZZ['x'] sage: cm.explain(R, QQ) Action discovered. - Right scalar multiplication by Rational Field on Univariate Polynomial Ring in x over Integer Ring + Right scalar multiplication by Rational Field + on Univariate Polynomial Ring in x over Integer Ring Result lives in Univariate Polynomial Ring in x over Rational Field Univariate Polynomial Ring in x over Rational Field @@ -874,7 +893,8 @@ cdef class CoercionModel: sage: cm.explain(ZZx, ZZ, operator.truediv) Action discovered. - Right inverse action by Rational Field on Univariate Polynomial Ring in x over Integer Ring + Right inverse action by Rational Field + on Univariate Polynomial Ring in x over Integer Ring with precomposition on right by Natural morphism: From: Integer Ring To: Rational Field @@ -914,17 +934,17 @@ cdef class CoercionModel: EXAMPLES:: sage: cm = sage.structure.element.get_coercion_model() - sage: GF7 = GF(7) - sage: steps, res = cm.analyse(GF7, ZZ) - sage: steps + sage: GF7 = GF(7) # optional - sage.rings.finite_rings + sage: steps, res = cm.analyse(GF7, ZZ) # optional - sage.rings.finite_rings + sage: steps # optional - sage.rings.finite_rings ['Coercion on right operand via', Natural morphism: From: Integer Ring To: Finite Field of size 7, 'Arithmetic performed after coercions.'] - sage: res + sage: res # optional - sage.rings.finite_rings Finite Field of size 7 - sage: f = steps[1]; type(f) + sage: f = steps[1]; type(f) # optional - sage.rings.finite_rings - sage: f(100) + sage: f(100) # optional - sage.rings.finite_rings 2 """ self._exceptions_cleared = False @@ -1044,7 +1064,9 @@ cdef class CoercionModel: sage: cm.common_parent(QQxy, QQzt, QQyz) Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Multivariate Polynomial Ring in x, y over Rational Field' and 'Multivariate Polynomial Ring in z, t over Rational Field' + TypeError: no common canonical parent for objects with parents: + 'Multivariate Polynomial Ring in x, y over Rational Field' and + 'Multivariate Polynomial Ring in z, t over Rational Field' """ base = None for x in args: @@ -1079,8 +1101,8 @@ cdef class CoercionModel: sage: ZZx = ZZ['x'] sage: cm.division_parent(ZZx) Fraction Field of Univariate Polynomial Ring in x over Integer Ring - sage: K = GF(41) - sage: cm.division_parent(K) + sage: K = GF(41) # optional - sage.rings.finite_rings + sage: cm.division_parent(K) # optional - sage.rings.finite_rings Finite Field of size 41 sage: Zmod100 = Integers(100) sage: cm.division_parent(Zmod100) @@ -1130,14 +1152,14 @@ cdef class CoercionModel: The operator can be any callable:: sage: R. = ZZ['x'] - sage: cm.bin_op(x^2-1, x+1, gcd) + sage: cm.bin_op(x^2 - 1, x + 1, gcd) x + 1 Actions are detected and performed:: - sage: M = matrix(ZZ, 2, 2, range(4)) - sage: V = vector(ZZ, [5,7]) - sage: cm.bin_op(M, V, operator.mul) + sage: M = matrix(ZZ, 2, 2, range(4)) # optional - sage.modules + sage: V = vector(ZZ, [5,7]) # optional - sage.modules + sage: cm.bin_op(M, V, operator.mul) # optional - sage.modules (7, 31) TESTS:: @@ -1261,14 +1283,14 @@ cdef class CoercionModel: sage: cm = sage.structure.element.get_coercion_model() sage: cm.canonical_coercion(mod(2, 10), 17) (2, 7) - sage: x, y = cm.canonical_coercion(1/2, matrix(ZZ, 2, 2, range(4))) - sage: x + sage: x, y = cm.canonical_coercion(1/2, matrix(ZZ, 2, 2, range(4))) # optional - sage.modules + sage: x # optional - sage.modules [1/2 0] [ 0 1/2] - sage: y + sage: y # optional - sage.modules [0 1] [2 3] - sage: parent(x) is parent(y) + sage: parent(x) is parent(y) # optional - sage.modules True There is some support for non-Sage datatypes as well:: @@ -1293,9 +1315,9 @@ cdef class CoercionModel: We also make an exception for 0, even if `\ZZ` does not map in:: - sage: canonical_coercion(vector([1, 2, 3]), 0) + sage: canonical_coercion(vector([1, 2, 3]), 0) # optional - sage.modules ((1, 2, 3), (0, 0, 0)) - sage: canonical_coercion(GF(5)(0), float(0)) + sage: canonical_coercion(GF(5)(0), float(0)) # optional - sage.rings.finite_rings (0, 0) """ xp = parent(x) @@ -1436,35 +1458,35 @@ cdef class CoercionModel: From: Rational Field To: Univariate Polynomial Ring in x over Rational Field - sage: K = GF(7) - sage: cm.coercion_maps(QQ, K) is None + sage: K = GF(7) # optional - sage.rings.finite_rings + sage: cm.coercion_maps(QQ, K) is None # optional - sage.rings.finite_rings True Note that to break symmetry, if there is a coercion map in both directions, the parent on the left is used:: - sage: V = QQ^3 - sage: W = V.__class__(QQ, 3) - sage: V == W + sage: V = QQ^3 # optional - sage.modules + sage: W = V.__class__(QQ, 3) # optional - sage.modules + sage: V == W # optional - sage.modules True - sage: V is W + sage: V is W # optional - sage.modules False - sage: cm = sage.structure.element.get_coercion_model() - sage: cm.coercion_maps(V, W) + sage: cm = sage.structure.element.get_coercion_model() # optional - sage.modules + sage: cm.coercion_maps(V, W) # optional - sage.modules (None, (map internal to coercion system -- copy before use) Coercion map: From: Vector space of dimension 3 over Rational Field To: Vector space of dimension 3 over Rational Field) - sage: cm.coercion_maps(W, V) + sage: cm.coercion_maps(W, V) # optional - sage.modules (None, (map internal to coercion system -- copy before use) Coercion map: From: Vector space of dimension 3 over Rational Field To: Vector space of dimension 3 over Rational Field) - sage: v = V([1,2,3]) - sage: w = W([1,2,3]) - sage: parent(v+w) is V + sage: v = V([1,2,3]) # optional - sage.modules + sage: w = W([1,2,3]) # optional - sage.modules + sage: parent(v + w) is V # optional - sage.modules True - sage: parent(w+v) is W + sage: parent(w + v) is W # optional - sage.modules True TESTS: @@ -1473,19 +1495,19 @@ cdef class CoercionModel: garbage collection after being involved in binary operations:: sage: import gc - sage: T=type(GF(2)) + sage: T = type(GF(2)) # optional - sage.rings.finite_rings sage: gc.collect() #random 852 - sage: N0=len(list(o for o in gc.get_objects() if type(o) is T)) - sage: L=[ZZ(1)+GF(p)(1) for p in prime_range(2,50)] - sage: N1=len(list(o for o in gc.get_objects() if type(o) is T)) - sage: N1 > N0 + sage: N0 = len(list(o for o in gc.get_objects() if type(o) is T)) # optional - sage.rings.finite_rings + sage: L = [ZZ(1) + GF(p)(1) for p in prime_range(2, 50)] # optional - sage.rings.finite_rings + sage: N1 = len(list(o for o in gc.get_objects() if type(o) is T)) # optional - sage.rings.finite_rings + sage: N1 > N0 # optional - sage.rings.finite_rings True - sage: del L + sage: del L # optional - sage.rings.finite_rings sage: gc.collect() #random 3939 - sage: N2=len(list(o for o in gc.get_objects() if type(o) is T)) - sage: N2-N0 + sage: N2 = len(list(o for o in gc.get_objects() if type(o) is T)) # optional - sage.rings.finite_rings + sage: N2 - N0 # optional - sage.rings.finite_rings 0 """ @@ -1553,9 +1575,11 @@ cdef class CoercionModel: sage: cm.verify_coercion_maps(ZZ, QQ, homs) == homs Traceback (most recent call last): ... - RuntimeError: ('BUG in coercion model, codomains must be identical', Natural morphism: + RuntimeError: ('BUG in coercion model, codomains must be identical', + Natural morphism: From: Integer Ring - To: Rational Field, Generic map: + To: Rational Field, + Generic map: From: Rational Field To: Real Field with 53 bits of precision) """ @@ -1616,7 +1640,7 @@ cdef class CoercionModel: If R is S, then two identity morphisms suffice:: - sage: cm.discover_coercion(SR, SR) + sage: cm.discover_coercion(SR, SR) # optional - sage.symbolic (None, None) If there is a coercion map either direction, use that:: @@ -1694,18 +1718,22 @@ cdef class CoercionModel: sage: cm = sage.structure.element.get_coercion_model() sage: ZZx = ZZ['x'] sage: cm.get_action(ZZx, ZZ, operator.mul) - Right scalar multiplication by Integer Ring on Univariate Polynomial Ring in x over Integer Ring + Right scalar multiplication by Integer Ring + on Univariate Polynomial Ring in x over Integer Ring sage: cm.get_action(ZZx, QQ, operator.mul) - Right scalar multiplication by Rational Field on Univariate Polynomial Ring in x over Integer Ring + Right scalar multiplication by Rational Field + on Univariate Polynomial Ring in x over Integer Ring sage: QQx = QQ['x'] sage: cm.get_action(QQx, int, operator.mul) - Right scalar multiplication by Integer Ring on Univariate Polynomial Ring in x over Rational Field + Right scalar multiplication by Integer Ring + on Univariate Polynomial Ring in x over Rational Field with precomposition on right by Native morphism: From: Set of Python objects of class 'int' To: Integer Ring sage: A = cm.get_action(QQx, ZZ, operator.truediv); A - Right inverse action by Rational Field on Univariate Polynomial Ring in x over Rational Field + Right inverse action by Rational Field + on Univariate Polynomial Ring in x over Rational Field with precomposition on right by Natural morphism: From: Integer Ring To: Rational Field @@ -1734,7 +1762,8 @@ cdef class CoercionModel: sage: R. = ZZ['x'] sage: cm = sage.structure.element.get_coercion_model() sage: cm.verify_action(R.get_action(QQ), R, QQ, operator.mul) - Right scalar multiplication by Rational Field on Univariate Polynomial Ring in x over Integer Ring + Right scalar multiplication by Rational Field + on Univariate Polynomial Ring in x over Integer Ring sage: cm.verify_action(R.get_action(QQ), RDF, R, operator.mul) Traceback (most recent call last): ... @@ -1743,8 +1772,9 @@ cdef class CoercionModel: R = Real Double Field S = Univariate Polynomial Ring in x over Integer Ring (should be Univariate Polynomial Ring in x over Integer Ring, Rational Field) - action = Right scalar multiplication by Rational Field on - Univariate Polynomial Ring in x over Integer Ring () + action = Right scalar multiplication by Rational Field + on Univariate Polynomial Ring in x over Integer Ring + () """ if action is None: return action @@ -1799,7 +1829,8 @@ cdef class CoercionModel: sage: P. = ZZ['x'] sage: P.get_action(ZZ) - Right scalar multiplication by Integer Ring on Univariate Polynomial Ring in x over Integer Ring + Right scalar multiplication by Integer Ring on + Univariate Polynomial Ring in x over Integer Ring sage: ZZ.get_action(P) is None True sage: cm = sage.structure.element.get_coercion_model() @@ -1807,43 +1838,48 @@ cdef class CoercionModel: If R or S is a Parent, ask it for an action by/on R:: sage: cm.discover_action(ZZ, P, operator.mul) - Left scalar multiplication by Integer Ring on Univariate Polynomial Ring in x over Integer Ring + Left scalar multiplication by Integer Ring on + Univariate Polynomial Ring in x over Integer Ring If R or S a type, recursively call get_action with the Sage versions of R and/or S:: sage: cm.discover_action(P, int, operator.mul) - Right scalar multiplication by Integer Ring on Univariate Polynomial Ring in x over Integer Ring - with precomposition on right by Native morphism: + Right scalar multiplication by Integer Ring on + Univariate Polynomial Ring in x over Integer Ring + with precomposition on right by Native morphism: From: Set of Python objects of class 'int' To: Integer Ring If op is division, look for action on right by inverse:: sage: cm.discover_action(P, ZZ, operator.truediv) - Right inverse action by Rational Field on Univariate Polynomial Ring in x over Integer Ring + Right inverse action by Rational Field on + Univariate Polynomial Ring in x over Integer Ring with precomposition on right by Natural morphism: From: Integer Ring To: Rational Field Check that :trac:`17740` is fixed:: - sage: R = GF(5)['x'] - sage: cm.discover_action(R, ZZ, operator.truediv) - Right inverse action by Finite Field of size 5 on Univariate Polynomial Ring in x over Finite Field of size 5 + sage: R = GF(5)['x'] # optional - sage.rings.finite_rings + sage: cm.discover_action(R, ZZ, operator.truediv) # optional - sage.rings.finite_rings + Right inverse action by Finite Field of size 5 + on Univariate Polynomial Ring in x over Finite Field of size 5 with precomposition on right by Natural morphism: From: Integer Ring To: Finite Field of size 5 - sage: cm.bin_op(R.gen(), 7, operator.truediv).parent() + sage: cm.bin_op(R.gen(), 7, operator.truediv).parent() # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 5 Check that :trac:`18221` is fixed:: - sage: F. = FreeAlgebra(QQ) - sage: x / 2 + sage: F. = FreeAlgebra(QQ) # optional - sage.combinat sage.modules + sage: x / 2 # optional - sage.combinat sage.modules 1/2*x - sage: cm.discover_action(F, ZZ, operator.truediv) - Right inverse action by Rational Field on Free Algebra on 1 generators (x,) over Rational Field - with precomposition on right by Natural morphism: + sage: cm.discover_action(F, ZZ, operator.truediv) # optional - sage.combinat sage.modules + Right inverse action by Rational Field on + Free Algebra on 1 generators (x,) over Rational Field + with precomposition on right by Natural morphism: From: Integer Ring To: Rational Field """ @@ -1933,15 +1969,16 @@ cdef class CoercionModel: If there is no coercion, we only support ``==`` and ``!=``:: - sage: x = QQ.one(); y = GF(2).one() - sage: richcmp(x, y, op_EQ) + sage: x = QQ.one(); y = GF(2).one() # optional - sage.rings.finite_rings + sage: richcmp(x, y, op_EQ) # optional - sage.rings.finite_rings False - sage: richcmp(x, y, op_NE) + sage: richcmp(x, y, op_NE) # optional - sage.rings.finite_rings True - sage: richcmp(x, y, op_GT) + sage: richcmp(x, y, op_GT) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for >: 'Rational Field' and 'Finite Field of size 2' + TypeError: unsupported operand parent(s) for >: + 'Rational Field' and 'Finite Field of size 2' We support non-Sage types with the usual Python convention:: diff --git a/src/sage/structure/coerce_actions.pyx b/src/sage/structure/coerce_actions.pyx index 3096282f068..50babb96570 100644 --- a/src/sage/structure/coerce_actions.pyx +++ b/src/sage/structure/coerce_actions.pyx @@ -55,9 +55,11 @@ cdef class GenericAction(Action): for otherwise they could be garbage collected, giving rise to random errors (see :trac:`18157`). :: - sage: M = MatrixSpace(ZZ,2) - sage: sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) - Left action by Full MatrixSpace of 2 by 2 dense matrices over Integer Ring on Set P^1(QQ) of all cusps + sage: M = MatrixSpace(ZZ, 2) # optional - sage.modules + sage: sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) # optional - sage.modules + Left action + by Full MatrixSpace of 2 by 2 dense matrices over Integer Ring + on Set P^1(QQ) of all cusps sage: Z6 = Zmod(6) sage: sage.structure.coerce_actions.GenericAction(QQ, Z6, True) @@ -92,9 +94,9 @@ cdef class GenericAction(Action): errors (see :trac:`18157`). :: - sage: M = MatrixSpace(ZZ,2) - sage: A = sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) - sage: A.codomain() + sage: M = MatrixSpace(ZZ, 2) # optional - sage.modules + sage: A = sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) # optional - sage.modules + sage: A.codomain() # optional - sage.modules Set P^1(QQ) of all cusps sage: S3 = SymmetricGroup(3) # optional - sage.groups @@ -123,7 +125,7 @@ cdef class ActOnAction(GenericAction): sage: A = sage.structure.coerce_actions.ActOnAction(G, R, False) # optional - sage.groups sage: A(x^2 + y - z, G((1,2))) # optional - sage.groups y^2 + x - z - sage: A(x+2*y+3*z, G((1,3,2))) # optional - sage.groups + sage: A(x + 2*y + 3*z, G((1,3,2))) # optional - sage.groups 2*x + 3*y + z sage: type(A) # optional - sage.groups @@ -140,14 +142,14 @@ cdef class ActedUponAction(GenericAction): """ TESTS:: - sage: M = MatrixSpace(ZZ,2) - sage: A = sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) - sage: A.act(matrix(ZZ, 2, [1,0,2,-1]), Cusp(1,2)) + sage: M = MatrixSpace(ZZ, 2) # optional - sage.modules + sage: A = sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) # optional - sage.modules + sage: A.act(matrix(ZZ, 2, [1,0,2,-1]), Cusp(1,2)) # optional - sage.modules Infinity - sage: A(matrix(ZZ, 2, [1,0,2,-1]), Cusp(1,2)) + sage: A(matrix(ZZ, 2, [1,0,2,-1]), Cusp(1,2)) # optional - sage.modules Infinity - sage: type(A) + sage: type(A) # optional - sage.modules <... 'sage.structure.coerce_actions.ActedUponAction'> """ return (x)._acted_upon_(g, not self._is_left) @@ -166,14 +168,17 @@ def detect_element_action(Parent X, Y, bint X_on_left, X_el=None, Y_el=None): sage: from sage.structure.coerce_actions import detect_element_action sage: ZZx = ZZ['x'] - sage: M = MatrixSpace(ZZ,2) + sage: M = MatrixSpace(ZZ, 2) # optional - sage.modules sage: detect_element_action(ZZx, ZZ, False) - Left scalar multiplication by Integer Ring on Univariate Polynomial Ring in x over Integer Ring + Left scalar multiplication by Integer Ring + on Univariate Polynomial Ring in x over Integer Ring sage: detect_element_action(ZZx, QQ, True) - Right scalar multiplication by Rational Field on Univariate Polynomial Ring in x over Integer Ring - sage: detect_element_action(Cusps, M, False) - Left action by Full MatrixSpace of 2 by 2 dense matrices over Integer Ring on Set P^1(QQ) of all cusps - sage: detect_element_action(Cusps, M, True), + Right scalar multiplication by Rational Field + on Univariate Polynomial Ring in x over Integer Ring + sage: detect_element_action(Cusps, M, False) # optional - sage.modules + Left action by Full MatrixSpace of 2 by 2 dense matrices over Integer Ring + on Set P^1(QQ) of all cusps + sage: detect_element_action(Cusps, M, True), # optional - sage.modules (None,) sage: detect_element_action(ZZ, QQ, True), (None,) @@ -295,7 +300,8 @@ cdef class ModuleAction(Action): sage: LeftModuleAction(QQ, ZZx) Left scalar multiplication by Rational Field on Univariate Polynomial Ring in x over Integer Ring sage: LeftModuleAction(QQ, ZZxy) - Left scalar multiplication by Rational Field on Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Integer Ring + Left scalar multiplication by Rational Field + on Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Integer Ring The following tests against a problem that was relevant during work on :trac:`9944`:: @@ -393,14 +399,16 @@ cdef class ModuleAction(Action): sage: from sage.structure.coerce_actions import LeftModuleAction, RightModuleAction sage: ZZx = ZZ['x'] sage: A = LeftModuleAction(ZZ, ZZx); A - Left scalar multiplication by Integer Ring on Univariate Polynomial Ring in x over Integer Ring + Left scalar multiplication by Integer Ring + on Univariate Polynomial Ring in x over Integer Ring sage: A._repr_name_() 'scalar multiplication' - sage: GF5 = GF(5) - sage: GF5t = GF5[['t']] - sage: RightModuleAction(GF5, GF5t) - Right scalar multiplication by Finite Field of size 5 on Power Series Ring in t over Finite Field of size 5 + sage: GF5 = GF(5) # optional - sage.rings.finite_rings + sage: GF5t = GF5[['t']] # optional - sage.rings.finite_rings + sage: RightModuleAction(GF5, GF5t) # optional - sage.rings.finite_rings + Right scalar multiplication by Finite Field of size 5 + on Power Series Ring in t over Finite Field of size 5 """ return "scalar multiplication" @@ -481,18 +489,20 @@ cdef class ModuleAction(Action): sage: A(x, 2) 1/2*x - sage: GF5x = GF(5)['x'] - sage: A = ~RightModuleAction(ZZ, GF5x); A - Right inverse action by Finite Field of size 5 on Univariate Polynomial Ring in x over Finite Field of size 5 + sage: GF5x = GF(5)['x'] # optional - sage.rings.finite_rings + sage: A = ~RightModuleAction(ZZ, GF5x); A # optional - sage.rings.finite_rings + Right inverse action by Finite Field of size 5 + on Univariate Polynomial Ring in x over Finite Field of size 5 with precomposition on right by Natural morphism: From: Integer Ring To: Finite Field of size 5 - sage: A(x, 2) + sage: A(x, 2) # optional - sage.rings.finite_rings 3*x - sage: GF5xy = GF5x['y'] - sage: A = ~RightModuleAction(ZZ, GF5xy); A - Right inverse action by Finite Field of size 5 on Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Finite Field of size 5 + sage: GF5xy = GF5x['y'] # optional - sage.rings.finite_rings + sage: A = ~RightModuleAction(ZZ, GF5xy); A # optional - sage.rings.finite_rings + Right inverse action by Finite Field of size 5 + on Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Finite Field of size 5 with precomposition on right by Natural morphism: From: Integer Ring To: Finite Field of size 5 @@ -516,14 +526,15 @@ cdef class ModuleAction(Action): See :trac:`19521`:: - sage: Q. = SR.subring(no_variables=True)[[]] - sage: (y / 1).parent() + sage: Q. = SR.subring(no_variables=True)[[]] # optional - sage.symbolic + sage: (y / 1).parent() # optional - sage.symbolic Power Series Ring in y over Symbolic Constants Subring - sage: R. = SR.subring(no_variables=True)[] - sage: cm = sage.structure.element.get_coercion_model() - sage: cm.explain(x, 1, operator.truediv) + sage: R. = SR.subring(no_variables=True)[] # optional - sage.symbolic + sage: cm = sage.structure.element.get_coercion_model() # optional - sage.symbolic + sage: cm.explain(x, 1, operator.truediv) # optional - sage.symbolic Action discovered. - Right inverse action by Symbolic Constants Subring on Univariate Polynomial Ring in x over Symbolic Constants Subring + Right inverse action by Symbolic Constants Subring + on Univariate Polynomial Ring in x over Symbolic Constants Subring with precomposition on right by Conversion via _symbolic_ method map: From: Integer Ring To: Symbolic Constants Subring @@ -743,13 +754,13 @@ cdef class IntegerMulAction(IntegerAction): random errors (see :trac:`18157`). :: sage: from sage.structure.coerce_actions import IntegerMulAction - sage: GF101 = GF(101) - sage: act = IntegerMulAction(ZZ, GF101) - sage: act(3, 9) + sage: GF101 = GF(101) # optional - sage.rings.finite_rings + sage: act = IntegerMulAction(ZZ, GF101) # optional - sage.rings.finite_rings + sage: act(3, 9) # optional - sage.rings.finite_rings 27 - sage: act(3^689, 9) + sage: act(3^689, 9) # optional - sage.rings.finite_rings 42 - sage: 3^689 * mod(9, 101) + sage: 3^689 * mod(9, 101) # optional - sage.rings.finite_rings 42 TESTS: @@ -763,14 +774,14 @@ cdef class IntegerMulAction(IntegerAction): This used to hang before :trac:`17844`:: - sage: E = EllipticCurve(GF(5), [4,0]) - sage: P = E.random_element() - sage: (-2^63)*P + sage: E = EllipticCurve(GF(5), [4,0]) # optional - sage.rings.finite_rings + sage: P = E.random_element() # optional - sage.rings.finite_rings + sage: (-2^63)*P # optional - sage.rings.finite_rings (0 : 1 : 0) Check that large multiplications can be interrupted:: - sage: alarm(0.001); 2^(10^7) * P + sage: alarm(0.001); 2^(10^7) * P # optional - sage.rings.finite_rings Traceback (most recent call last): ... AlarmInterrupt @@ -778,8 +789,8 @@ cdef class IntegerMulAction(IntegerAction): Verify that cysignals correctly detects that the above exception has been handled:: - sage: from cysignals.tests import print_sig_occurred - sage: print_sig_occurred() + sage: from cysignals.tests import print_sig_occurred # optional - sage.rings.finite_rings + sage: print_sig_occurred() # optional - sage.rings.finite_rings No current exception """ cdef int err = 0 @@ -800,9 +811,10 @@ cdef class IntegerMulAction(IntegerAction): random errors (see :trac:`18157`). :: sage: from sage.structure.coerce_actions import IntegerMulAction - sage: GF5 = GF(5) - sage: IntegerMulAction(ZZ, GF5) - Left Integer Multiplication by Integer Ring on Finite Field of size 5 + sage: GF5 = GF(5) # optional - sage.rings.finite_rings + sage: IntegerMulAction(ZZ, GF5) # optional - sage.rings.finite_rings + Left Integer Multiplication by Integer Ring + on Finite Field of size 5 """ return "Integer Multiplication" @@ -847,11 +859,11 @@ cdef class IntegerPowAction(IntegerAction): :: - sage: var('x,y') + sage: var('x,y') # optional - sage.symbolic (x, y) - sage: RDF('-2.3')^(x+y^3+sin(x)) + sage: RDF('-2.3')^(x+y^3+sin(x)) # optional - sage.symbolic (-2.3)^(y^3 + x + sin(x)) - sage: RDF('-2.3')^x + sage: RDF('-2.3')^x # optional - sage.symbolic (-2.3)^x """ def __init__(self, Z, M, is_left=False, m=None): @@ -875,13 +887,13 @@ cdef class IntegerPowAction(IntegerAction): ``GF(101)``:: sage: from sage.structure.coerce_actions import IntegerPowAction - sage: GF101 = GF(101) - sage: act = IntegerPowAction(ZZ, GF101) - sage: act(3, 100) + sage: GF101 = GF(101) # optional - sage.rings.finite_rings + sage: act = IntegerPowAction(ZZ, GF101) # optional - sage.rings.finite_rings + sage: act(3, 100) # optional - sage.rings.finite_rings 1 - sage: act(3, -1) + sage: act(3, -1) # optional - sage.rings.finite_rings 34 - sage: act(3, 1000000000000000000000000000000000000000000001) + sage: act(3, 1000000000000000000000000000000000000000000001) # optional - sage.rings.finite_rings 3 """ cdef Element e = a diff --git a/src/sage/structure/coerce_dict.pyx b/src/sage/structure/coerce_dict.pyx index 440993aadd6..e9c923c6343 100644 --- a/src/sage/structure/coerce_dict.pyx +++ b/src/sage/structure/coerce_dict.pyx @@ -41,12 +41,12 @@ However, this leak was fixed by :trac:`715`, using weak references:: ....: E = EllipticCurve(j=a) ....: P = E.random_point() ....: Q = 2*P - sage: L = [Partitions(n) for n in range(200)] # purge strong cache in CachedRepresentation + sage: L = [Partitions(n) for n in range(200)] # purge strong cache in CachedRepresentation # optional - sage.rings.finite_rings sage.combinat sage: import gc sage: n = gc.collect() - sage: from sage.schemes.elliptic_curves.ell_finite_field import EllipticCurve_finite_field - sage: LE = [x for x in gc.get_objects() if isinstance(x, EllipticCurve_finite_field)] - sage: len(LE) + sage: from sage.schemes.elliptic_curves.ell_finite_field import EllipticCurve_finite_field # optional - sage.rings.finite_rings sage.combinat + sage: LE = [x for x in gc.get_objects() if isinstance(x, EllipticCurve_finite_field)] # optional - sage.rings.finite_rings sage.combinat + sage: len(LE) # optional - sage.rings.finite_rings sage.combinat 1 """ diff --git a/src/sage/structure/coerce_maps.pyx b/src/sage/structure/coerce_maps.pyx index 3537c24e678..7ccc402c43a 100644 --- a/src/sage/structure/coerce_maps.pyx +++ b/src/sage/structure/coerce_maps.pyx @@ -34,16 +34,19 @@ cdef class DefaultConvertMap(Map): Maps of this type are morphisms in the category of sets with partial maps (see :trac:`15618`):: - sage: f = GF(11).convert_map_from(GF(7)); f + sage: f = GF(11).convert_map_from(GF(7)); f # optional - sage.rings.finite_rings Conversion map: From: Finite Field of size 7 To: Finite Field of size 11 - sage: f.parent() - Set of Morphisms from Finite Field of size 7 to Finite Field of size 11 in Category of sets with partial maps + sage: f.parent() # optional - sage.rings.finite_rings + Set of Morphisms + from Finite Field of size 7 + to Finite Field of size 11 + in Category of sets with partial maps Test that :trac:`23211` is resolved:: - sage: f._is_coercion + sage: f._is_coercion # optional - sage.rings.finite_rings False sage: QQ[['x']].coerce_map_from(QQ)._is_coercion True @@ -52,7 +55,8 @@ cdef class DefaultConvertMap(Map): sage: from sage.structure.coerce_maps import DefaultConvertMap sage: DefaultConvertMap(ZZ, ZZ) - doctest:...: DeprecationWarning: DefaultConvertMap is deprecated, use DefaultConvertMap_unique instead. This probably means that _element_constructor_ should be a method and not some other kind of callable + doctest:...: DeprecationWarning: DefaultConvertMap is deprecated, use DefaultConvertMap_unique instead. + This probably means that _element_constructor_ should be a method and not some other kind of callable See https://github.com/sagemath/sage/issues/26879 for details. Conversion map: From: Integer Ring @@ -83,8 +87,8 @@ cdef class DefaultConvertMap(Map): EXAMPLES:: - sage: f = GF(11).convert_map_from(GF(7)) - sage: f._repr_type() + sage: f = GF(11).convert_map_from(GF(7)) # optional - sage.rings.finite_rings + sage: f._repr_type() # optional - sage.rings.finite_rings 'Conversion' """ return self._repr_type_str or ("Coercion" if self._is_coercion else "Conversion") @@ -193,13 +197,13 @@ cdef class NamedConvertMap(Map): EXAMPLES:: sage: from sage.structure.coerce_maps import NamedConvertMap - sage: var('t') + sage: var('t') # optional - sage.symbolic t - sage: mor = NamedConvertMap(SR, QQ['t'], '_polynomial_') - sage: mor(t^2/4+1) + sage: mor = NamedConvertMap(SR, QQ['t'], '_polynomial_') # optional - sage.symbolic + sage: mor(t^2/4 + 1) # optional - sage.symbolic 1/4*t^2 + 1 - sage: mor = NamedConvertMap(SR, GF(7)[['t']], '_polynomial_') - sage: mor(t^2/4+1) + sage: mor = NamedConvertMap(SR, GF(7)[['t']], '_polynomial_') # optional - sage.symbolic + sage: mor(t^2/4 + 1) # optional - sage.symbolic 1 + 2*t^2 """ if isinstance(domain, type): @@ -216,19 +220,19 @@ cdef class NamedConvertMap(Map): EXAMPLES:: sage: from sage.structure.coerce_maps import NamedConvertMap - sage: var('t') + sage: var('t') # optional - sage.symbolic t - sage: phi = NamedConvertMap(SR, QQ['t'], '_polynomial_') - sage: psi = copy(phi) # indirect doctest - sage: psi + sage: phi = NamedConvertMap(SR, QQ['t'], '_polynomial_') # optional - sage.symbolic + sage: psi = copy(phi) # indirect doctest # optional - sage.symbolic + sage: psi # optional - sage.symbolic Conversion via _polynomial_ method map: From: Symbolic Ring To: Univariate Polynomial Ring in t over Rational Field - sage: phi == psi # todo: comparison not implemented + sage: phi == psi # todo: comparison not implemented # optional - sage.symbolic True - sage: psi(t^2/4+1) + sage: psi(t^2/4 + 1) # optional - sage.symbolic 1/4*t^2 + 1 - sage: psi(t^2/4+1) == phi(t^2/4+1) + sage: psi(t^2/4 + 1) == phi(t^2/4 + 1) # optional - sage.symbolic True """ slots = Map._extra_slots(self) @@ -242,19 +246,19 @@ cdef class NamedConvertMap(Map): EXAMPLES:: sage: from sage.structure.coerce_maps import NamedConvertMap - sage: var('t') + sage: var('t') # optional - sage.symbolic t - sage: phi = NamedConvertMap(SR, QQ['t'], '_polynomial_') - sage: psi = copy(phi) # indirect doctest - sage: psi + sage: phi = NamedConvertMap(SR, QQ['t'], '_polynomial_') # optional - sage.symbolic + sage: psi = copy(phi) # indirect doctest # optional - sage.symbolic + sage: psi # optional - sage.symbolic Conversion via _polynomial_ method map: From: Symbolic Ring To: Univariate Polynomial Ring in t over Rational Field - sage: phi == psi # todo: comparison not implemented + sage: phi == psi # todo: comparison not implemented # optional - sage.symbolic True - sage: psi(t^2/4+1) + sage: psi(t^2/4 + 1) # optional - sage.symbolic 1/4*t^2 + 1 - sage: psi(t^2/4+1) == phi(t^2/4+1) + sage: psi(t^2/4 + 1) == phi(t^2/4 + 1) # optional - sage.symbolic True """ self.method_name = _slots['method_name'] @@ -265,13 +269,13 @@ cdef class NamedConvertMap(Map): EXAMPLES:: sage: from sage.structure.coerce_maps import NamedConvertMap - sage: f = NamedConvertMap(GF(5), QQ, '_integer_'); f + sage: f = NamedConvertMap(GF(5), QQ, '_integer_'); f # optional - sage.rings.finite_rings Conversion via _integer_ method map: From: Finite Field of size 5 To: Rational Field - sage: f(19) + sage: f(19) # optional - sage.rings.finite_rings 4 - sage: f(19).parent() + sage: f(19).parent() # optional - sage.rings.finite_rings Rational Field """ cdef Parent C = self._codomain @@ -299,8 +303,8 @@ cdef class NamedConvertMap(Map): EXAMPLES:: sage: from sage.structure.coerce_maps import NamedConvertMap - sage: f = NamedConvertMap(SR, ZZ['x'], '_polynomial_') - sage: f(x^2+1, check=True) + sage: f = NamedConvertMap(SR, ZZ['x'], '_polynomial_') # optional - sage.symbolic + sage: f(x^2 + 1, check=True) # optional - sage.symbolic x^2 + 1 """ cdef Parent C = self._codomain @@ -333,12 +337,12 @@ cdef class CallableConvertMap(Map): :: - sage: f = CallableConvertMap(RR, RR, exp, parent_as_first_arg=False) - sage: f(0) + sage: f = CallableConvertMap(RR, RR, exp, parent_as_first_arg=False) # optional - sage.symbolic + sage: f(0) # optional - sage.symbolic 1.00000000000000 - sage: f(1) + sage: f(1) # optional - sage.symbolic 2.71828182845905 - sage: f(-3) + sage: f(-3) # optional - sage.symbolic 0.0497870683678639 """ if isinstance(domain, type): diff --git a/src/sage/structure/element.pxd b/src/sage/structure/element.pxd index 5c6e295a4b8..4403ddd685a 100644 --- a/src/sage/structure/element.pxd +++ b/src/sage/structure/element.pxd @@ -132,12 +132,12 @@ cpdef inline bint have_same_parent(left, right): These have different types but the same parent:: sage: a = RLF(2) - sage: b = exp(a) - sage: type(a) + sage: b = exp(a) # optional - sage.symbolic + sage: type(a) # optional - sage.symbolic <... 'sage.rings.real_lazy.LazyWrapper'> - sage: type(b) + sage: type(b) # optional - sage.symbolic <... 'sage.rings.real_lazy.LazyNamedUnop'> - sage: have_same_parent(a, b) + sage: have_same_parent(a, b) # optional - sage.symbolic True """ return HAVE_SAME_PARENT(classify_elements(left, right)) diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index e52f4665a3f..c304407aaea 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -360,7 +360,7 @@ def is_Element(x): sage: from sage.structure.element import is_Element sage: is_Element(2/3) True - sage: is_Element(QQ^3) + sage: is_Element(QQ^3) # optional - sage.modules False """ return isinstance(x, Element) @@ -654,7 +654,7 @@ cdef class Element(SageObject): sage: QQ.base_ring() Rational Field - sage: identity_matrix(3).base_ring() + sage: identity_matrix(3).base_ring() # optional - sage.modules Integer Ring """ return self._parent.base_ring() @@ -896,17 +896,17 @@ cdef class Element(SageObject): EXAMPLES:: - sage: from sage.libs.mpmath.all import mp, mpmathify - sage: mp.dps = 30 - sage: 25._mpmath_(53) + sage: from sage.libs.mpmath.all import mp, mpmathify # optional - mpmath + sage: mp.dps = 30 # optional - mpmath + sage: 25._mpmath_(53) # optional - mpmath mpf('25.0') - sage: mpmathify(3+4*I) + sage: mpmathify(3 + 4*I) # optional - mpmath mpc(real='3.0', imag='4.0') - sage: mpmathify(1+pi) + sage: mpmathify(1 + pi) # optional - mpmath mpf('4.14159265358979323846264338327933') - sage: (1+pi)._mpmath_(10) + sage: (1 + pi)._mpmath_(10) # optional - mpmath mpf('4.140625') - sage: (1+pi)._mpmath_(mp.prec) + sage: (1 + pi)._mpmath_(mp.prec) # optional - mpmath mpf('4.14159265358979323846264338327933') """ return self.n(prec)._mpmath_(prec=prec) @@ -927,11 +927,11 @@ cdef class Element(SageObject): EXAMPLES:: - sage: x, y = PolynomialRing(ZZ,2,'xy').gens() + sage: x, y = PolynomialRing(ZZ, 2, 'xy').gens() sage: f = x^2 + y + x^2*y^2 + 5 sage: f((5,y)) 25*y^2 + y + 30 - sage: f.substitute({x:5}) + sage: f.substitute({x: 5}) 25*y^2 + y + 30 sage: f.substitute(x=5) 25*y^2 + y + 30 @@ -1031,13 +1031,13 @@ cdef class Element(SageObject): Verify that :trac:`5185` is fixed:: - sage: v = vector({1: 1, 3: -1}) - sage: w = vector({1: -1, 3: 1}) - sage: v + w + sage: v = vector({1: 1, 3: -1}) # optional - sage.modules + sage: w = vector({1: -1, 3: 1}) # optional - sage.modules + sage: v + w # optional - sage.modules (0, 0, 0, 0) - sage: (v+w).is_zero() + sage: (v + w).is_zero() # optional - sage.modules True - sage: bool(v+w) + sage: bool(v + w) # optional - sage.modules False """ @@ -1137,7 +1137,7 @@ cdef class Element(SageObject): We now create an ``Element`` class where we define ``_richcmp_`` and check that comparison works:: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: from sage.structure.richcmp cimport rich_to_bool ....: from sage.structure.element cimport Element @@ -1150,9 +1150,9 @@ cdef class Element(SageObject): ....: cdef float x2 = (other).x ....: return rich_to_bool(op, (x1 > x2) - (x1 < x2)) ....: ''') - sage: a = FloatCmp(1) # optional - sage.misc.cython - sage: b = FloatCmp(2) # optional - sage.misc.cython - sage: a <= b, b <= a # optional - sage.misc.cython + sage: a = FloatCmp(1) # optional - sage.misc.cython + sage: b = FloatCmp(2) # optional - sage.misc.cython + sage: a <= b, b <= a # optional - sage.misc.cython (True, False) """ # Obvious case @@ -1287,16 +1287,16 @@ cdef class Element(SageObject): EXAMPLES:: - sage: cython( # long time # optional - sage.misc.cython + sage: cython( # long time # optional - sage.misc.cython ....: ''' ....: from sage.structure.element cimport Element ....: cdef class MyElement(Element): ....: cdef _add_long(self, long n): ....: return n ....: ''') - sage: e = MyElement(Parent()) # long time # optional - sage.misc.cython - sage: i = int(42) # optional - sage.misc.cython - sage: i + e, e + i # long time # optional - sage.misc.cython + sage: e = MyElement(Parent()) # long time # optional - sage.misc.cython + sage: i = int(42) # optional - sage.misc.cython + sage: i + e, e + i # long time # optional - sage.misc.cython (42, 42) """ return coercion_model.bin_op(self, n, add) @@ -1497,13 +1497,13 @@ cdef class Element(SageObject): :: - sage: A = AlgebrasWithBasis(QQ).example(); A + sage: A = AlgebrasWithBasis(QQ).example(); A # optional - sage.combinat sage.modules An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field - sage: x = A.an_element() - sage: x + sage: x = A.an_element() # optional - sage.combinat sage.modules + sage: x # optional - sage.combinat sage.modules B[word: ] + 2*B[word: a] + 3*B[word: b] + B[word: bab] - sage: x.__mul__(x) + sage: x.__mul__(x) # optional - sage.combinat sage.modules B[word: ] + 4*B[word: a] + 4*B[word: aa] + 6*B[word: ab] + 2*B[word: abab] + 6*B[word: b] + 6*B[word: ba] + 2*B[word: bab] + 2*B[word: baba] + 3*B[word: babb] @@ -1565,16 +1565,16 @@ cdef class Element(SageObject): EXAMPLES:: - sage: cython( # long time # optional - sage.misc.cython + sage: cython( # long time # optional - sage.misc.cython ....: ''' ....: from sage.structure.element cimport Element ....: cdef class MyElement(Element): ....: cdef _mul_long(self, long n): ....: return n ....: ''') - sage: e = MyElement(Parent()) # long time # optional - sage.misc.cython - sage: i = int(42) # optional - sage.misc.cython - sage: i * e, e * i # long time # optional - sage.misc.cython + sage: e = MyElement(Parent()) # long time # optional - sage.misc.cython + sage: i = int(42) # optional - sage.misc.cython + sage: i * e, e * i # long time # optional - sage.misc.cython (42, 42) """ return coercion_model.bin_op(self, n, mul) @@ -1682,11 +1682,11 @@ cdef class Element(SageObject): sage: operator.truediv(2, 3) 2/3 - sage: operator.truediv(pi, 3) + sage: operator.truediv(pi, 3) # optional - sage.symbolic 1/3*pi sage: x = polygen(QQ, 'x') - sage: K. = NumberField(x^2 + 1) - sage: operator.truediv(2, K.ideal(i+1)) + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: operator.truediv(2, K.ideal(i + 1)) # optional - sage.rings.number_field Fractional ideal (-i + 1) :: @@ -2001,15 +2001,15 @@ cdef class Element(SageObject): :: - sage: (2/3)^I + sage: (2/3)^I # optional - sage.symbolic (2/3)^I - sage: (2/3)^sqrt(2) + sage: (2/3)^sqrt(2) # optional - sage.symbolic (2/3)^sqrt(2) - sage: var('x,y,z,n') + sage: var('x,y,z,n') # optional - sage.symbolic (x, y, z, n) - sage: (2/3)^(x^n + y^n + z^n) + sage: (2/3)^(x^n + y^n + z^n) # optional - sage.symbolic (2/3)^(x^n + y^n + z^n) - sage: (-7/11)^(tan(x)+exp(x)) + sage: (-7/11)^(tan(x)+exp(x)) # optional - sage.symbolic (-7/11)^(e^x + tan(x)) sage: float(1.2)**(1/2) 1.0954451150103321 @@ -2147,7 +2147,7 @@ def is_ModuleElement(x): sage: from sage.structure.element import is_ModuleElement sage: is_ModuleElement(2/3) True - sage: is_ModuleElement((QQ^3).0) + sage: is_ModuleElement((QQ^3).0) # optional - sage.modules True sage: is_ModuleElement('a') False @@ -2226,7 +2226,7 @@ cdef class ElementWithCachedMethod(Element): ....: "from sage.structure.parent cimport Parent", ....: "cdef class MyParent(Parent):", ....: " Element = MyElement"] - sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython + sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython sage: cython_code = ["from sage.misc.cachefunc import cached_method", ....: "from sage.misc.cachefunc import cached_in_parent_method", ....: "from sage.categories.category import Category", @@ -2249,21 +2249,21 @@ cdef class ElementWithCachedMethod(Element): ....: " @cached_method", ....: " def invert(self, x):", ....: " return -x"] - sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython - sage: C = MyCategory() # optional - sage.misc.cython - sage: P = MyParent(category=C) # optional - sage.misc.cython - sage: ebroken = MyBrokenElement(P, 5) # optional - sage.misc.cython - sage: e = MyElement(P, 5) # optional - sage.misc.cython + sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython + sage: C = MyCategory() # optional - sage.misc.cython + sage: P = MyParent(category=C) # optional - sage.misc.cython + sage: ebroken = MyBrokenElement(P, 5) # optional - sage.misc.cython + sage: e = MyElement(P, 5) # optional - sage.misc.cython The cached methods inherited by ``MyElement`` works:: - sage: e.element_cache_test() # optional - sage.misc.cython + sage: e.element_cache_test() # optional - sage.misc.cython <-5> - sage: e.element_cache_test() is e.element_cache_test() # optional - sage.misc.cython + sage: e.element_cache_test() is e.element_cache_test() # optional - sage.misc.cython True - sage: e.element_via_parent_test() # optional - sage.misc.cython + sage: e.element_via_parent_test() # optional - sage.misc.cython <-5> - sage: e.element_via_parent_test() is e.element_via_parent_test() # optional - sage.misc.cython + sage: e.element_via_parent_test() is e.element_via_parent_test() # optional - sage.misc.cython True The other element class can only inherit a @@ -2271,36 +2271,36 @@ cdef class ElementWithCachedMethod(Element): parent. In fact, equal elements share the cache, even if they are of different types:: - sage: e == ebroken # optional - sage.misc.cython + sage: e == ebroken # optional - sage.misc.cython True - sage: type(e) == type(ebroken) # optional - sage.misc.cython + sage: type(e) == type(ebroken) # optional - sage.misc.cython False - sage: ebroken.element_via_parent_test() is e.element_via_parent_test() # optional - sage.misc.cython + sage: ebroken.element_via_parent_test() is e.element_via_parent_test() # optional - sage.misc.cython True However, the cache of the other inherited method breaks, although the method as such works:: - sage: ebroken.element_cache_test() # optional - sage.misc.cython + sage: ebroken.element_cache_test() # optional - sage.misc.cython <-5> - sage: ebroken.element_cache_test() is ebroken.element_cache_test() # optional - sage.misc.cython + sage: ebroken.element_cache_test() is ebroken.element_cache_test() # optional - sage.misc.cython False Since ``e`` and ``ebroken`` share the cache, when we empty it for one element it is empty for the other as well:: - sage: b = ebroken.element_via_parent_test() # optional - sage.misc.cython - sage: e.element_via_parent_test.clear_cache() # optional - sage.misc.cython - sage: b is ebroken.element_via_parent_test() # optional - sage.misc.cython + sage: b = ebroken.element_via_parent_test() # optional - sage.misc.cython + sage: e.element_via_parent_test.clear_cache() # optional - sage.misc.cython + sage: b is ebroken.element_via_parent_test() # optional - sage.misc.cython False Note that the cache only breaks for elements that do no allow attribute assignment. A Python version of ``MyBrokenElement`` therefore allows for cached methods:: - sage: epython = MyPythonElement(P, 5) # optional - sage.misc.cython - sage: epython.element_cache_test() # optional - sage.misc.cython + sage: epython = MyPythonElement(P, 5) # optional - sage.misc.cython + sage: epython.element_cache_test() # optional - sage.misc.cython <-5> - sage: epython.element_cache_test() is epython.element_cache_test() # optional - sage.misc.cython + sage: epython.element_cache_test() is epython.element_cache_test() # optional - sage.misc.cython True """ @@ -2317,7 +2317,7 @@ cdef class ElementWithCachedMethod(Element): EXAMPLES:: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: from sage.structure.element cimport ElementWithCachedMethod ....: cdef class MyElement(ElementWithCachedMethod): @@ -2343,12 +2343,12 @@ cdef class ElementWithCachedMethod(Element): ....: def my_lazy_attr(self): ....: return 'lazy attribute of <%s>'%self.x ....: ''') - sage: C = MyCategory() # optional - sage.misc.cython - sage: P = MyParent(category=C) # optional - sage.misc.cython - sage: e = MyElement(P, 5) # optional - sage.misc.cython - sage: e.my_lazy_attr # optional - sage.misc.cython + sage: C = MyCategory() # optional - sage.misc.cython + sage: P = MyParent(category=C) # optional - sage.misc.cython + sage: e = MyElement(P, 5) # optional - sage.misc.cython + sage: e.my_lazy_attr # optional - sage.misc.cython 'lazy attribute of <5>' - sage: e.my_lazy_attr is e.my_lazy_attr # optional - sage.misc.cython + sage: e.my_lazy_attr is e.my_lazy_attr # optional - sage.misc.cython True """ try: @@ -2460,8 +2460,8 @@ cdef class ModuleElementWithMutability(ModuleElement): """ EXAMPLES:: - sage: v = sage.modules.free_module_element.FreeModuleElement(QQ^3) - sage: type(v) + sage: v = sage.modules.free_module_element.FreeModuleElement(QQ^3) # optional - sage.modules + sage: type(v) # optional - sage.modules """ self._parent = parent @@ -2473,11 +2473,11 @@ cdef class ModuleElementWithMutability(ModuleElement): EXAMPLES:: - sage: v = vector([1..5]); v + sage: v = vector([1..5]); v # optional - sage.modules (1, 2, 3, 4, 5) - sage: v[1] = 10 - sage: v.set_immutable() - sage: v[1] = 10 + sage: v[1] = 10 # optional - sage.modules + sage: v.set_immutable() # optional - sage.modules + sage: v[1] = 10 # optional - sage.modules Traceback (most recent call last): ... ValueError: vector is immutable; please change a copy instead (use copy()) @@ -2491,10 +2491,10 @@ cdef class ModuleElementWithMutability(ModuleElement): EXAMPLES:: - sage: v = vector(QQ['x,y'], [1..5]); v.is_mutable() + sage: v = vector(QQ['x,y'], [1..5]); v.is_mutable() # optional - sage.modules True - sage: v.set_immutable() - sage: v.is_mutable() + sage: v.set_immutable() # optional - sage.modules + sage: v.is_mutable() # optional - sage.modules False """ return not self._is_immutable @@ -2506,10 +2506,10 @@ cdef class ModuleElementWithMutability(ModuleElement): EXAMPLES:: - sage: v = vector(QQ['x,y'], [1..5]); v.is_immutable() + sage: v = vector(QQ['x,y'], [1..5]); v.is_immutable() # optional - sage.modules False - sage: v.set_immutable() - sage: v.is_immutable() + sage: v.set_immutable() # optional - sage.modules + sage: v.is_immutable() # optional - sage.modules True """ return self._is_immutable @@ -2557,9 +2557,9 @@ cdef class MonoidElement(Element): EXAMPLES:: - sage: G = SymmetricGroup(4) # optional - sage.groups - sage: g = G([2, 3, 4, 1]) # optional - sage.groups - sage: g.powers(4) # optional - sage.groups + sage: G = SymmetricGroup(4) # optional - sage.groups + sage: g = G([2, 3, 4, 1]) # optional - sage.groups + sage: g.powers(4) # optional - sage.groups [(), (1,2,3,4), (1,3)(2,4), (1,4,3,2)] """ if n < 0: @@ -2688,22 +2688,22 @@ cdef class RingElement(ModuleElement): True sage: p(a,200) * p(a,-64) == p(a,136) True - sage: p(2, 1/2) + sage: p(2, 1/2) # optional - sage.symbolic sqrt(2) TESTS: These are not testing this code, but they are probably good to have around:: - sage: 2r**(SR(2)-1-1r) + sage: 2r**(SR(2)-1-1r) # optional - sage.symbolic 1 - sage: 2r^(1/2) + sage: 2r^(1/2) # optional - sage.symbolic sqrt(2) Exponent overflow should throw an OverflowError (:trac:`2956`):: - sage: K. = AA[] - sage: x^(2^64 + 12345) + sage: K. = AA[] # optional - sage.rings.number_field + sage: x^(2^64 + 12345) # optional - sage.rings.number_field Traceback (most recent call last): ... OverflowError: exponent overflow (2147483648) @@ -2800,8 +2800,8 @@ cdef class RingElement(ModuleElement): :: - sage: R. = GF(7)[] - sage: divmod(x^2, x-1) + sage: R. = GF(7)[] # optional - sage.libs.pari + sage: divmod(x^2, x - 1) # optional - sage.libs.pari (x + 1, 1) :: @@ -2846,8 +2846,8 @@ cdef class RingElement(ModuleElement): sage: a = QQ(0) sage: a.is_nilpotent() True - sage: m = matrix(QQ,3,[[3,2,3],[9,0,3],[-9,0,-3]]) - sage: m.is_nilpotent() + sage: m = matrix(QQ, 3, [[3,2,3], [9,0,3], [-9,0,-3]]) # optional - sage.modules + sage: m.is_nilpotent() # optional - sage.modules Traceback (most recent call last): ... AttributeError: ... object has no attribute 'is_nilpotent' @@ -2891,30 +2891,30 @@ cdef class RingElement(ModuleElement): For polynomial rings, prime is the same as irreducible:: sage: R. = QQ[] - sage: x.is_prime() + sage: x.is_prime() # optional - sage.libs.singular True - sage: (x^2 + y^3).is_prime() + sage: (x^2 + y^3).is_prime() # optional - sage.libs.singular True - sage: (x^2 - y^2).is_prime() + sage: (x^2 - y^2).is_prime() # optional - sage.libs.singular False - sage: R(0).is_prime() + sage: R(0).is_prime() # optional - sage.libs.singular False - sage: R(2).is_prime() + sage: R(2).is_prime() # optional - sage.libs.singular False For the Gaussian integers:: - sage: K. = QuadraticField(-1) - sage: ZI = K.ring_of_integers() - sage: ZI(3).is_prime() + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: ZI = K.ring_of_integers() # optional - sage.rings.number_field + sage: ZI(3).is_prime() # optional - sage.rings.number_field True - sage: ZI(5).is_prime() + sage: ZI(5).is_prime() # optional - sage.rings.number_field False - sage: ZI(2+i).is_prime() + sage: ZI(2 + i).is_prime() # optional - sage.rings.number_field True - sage: ZI(0).is_prime() + sage: ZI(0).is_prime() # optional - sage.rings.number_field False - sage: ZI(1).is_prime() + sage: ZI(1).is_prime() # optional - sage.rings.number_field False In fields, an element is never prime:: @@ -2937,13 +2937,13 @@ cdef class RingElement(ModuleElement): redefines :meth:`is_prime` to determine primality in the ring of integers:: - sage: (1+i).is_prime() + sage: (1 + i).is_prime() # optional - sage.rings.number_field True - sage: K(5).is_prime() + sage: K(5).is_prime() # optional - sage.rings.number_field False - sage: K(7).is_prime() + sage: K(7).is_prime() # optional - sage.rings.number_field True - sage: K(7/13).is_prime() + sage: K(7/13).is_prime() # optional - sage.rings.number_field False However, for rationals, :meth:`is_prime` *does* follow the @@ -2987,16 +2987,16 @@ cdef class CommutativeRingElement(RingElement): EXAMPLES:: - sage: F = GF(25) - sage: x = F.gen() - sage: z = F.zero() - sage: x.inverse_mod(F.ideal(z)) + sage: F = GF(25) # optional - sage.libs.pari + sage: x = F.gen() # optional - sage.libs.pari + sage: z = F.zero() # optional - sage.libs.pari + sage: x.inverse_mod(F.ideal(z)) # optional - sage.libs.pari 2*z2 + 3 - sage: x.inverse_mod(F.ideal(1)) + sage: x.inverse_mod(F.ideal(1)) # optional - sage.libs.pari 1 - sage: z.inverse_mod(F.ideal(1)) + sage: z.inverse_mod(F.ideal(1)) # optional - sage.libs.pari 1 - sage: z.inverse_mod(F.ideal(z)) + sage: z.inverse_mod(F.ideal(z)) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: an element of a proper ideal does not have an inverse modulo that ideal @@ -3019,24 +3019,24 @@ cdef class CommutativeRingElement(RingElement): sage: P. = PolynomialRing(QQ) sage: x.divides(x^2) True - sage: x.divides(x^2+2) + sage: x.divides(x^2 + 2) False - sage: (x^2+2).divides(x) + sage: (x^2 + 2).divides(x) False sage: P. = PolynomialRing(ZZ) sage: x.divides(x^2) True - sage: x.divides(x^2+2) + sage: x.divides(x^2 + 2) False - sage: (x^2+2).divides(x) + sage: (x^2 + 2).divides(x) False :trac:`5347` has been fixed:: - sage: K = GF(7) - sage: K(3).divides(1) + sage: K = GF(7) # optional - sage.libs.pari + sage: K(3).divides(1) # optional - sage.libs.pari True - sage: K(3).divides(K(1)) + sage: K(3).divides(K(1)) # optional - sage.libs.pari True :: @@ -3160,22 +3160,22 @@ cdef class CommutativeRingElement(RingElement): and an ideal:: sage: R. = PolynomialRing(QQ, 3) - sage: (x^2 + y^2 + z^2).mod(x+y+z) + sage: (x^2 + y^2 + z^2).mod(x + y + z) # optional - sage.libs.singular 2*y^2 + 2*y*z + 2*z^2 Notice above that `x` is eliminated. In the next example, both `y` and `z` are eliminated:: - sage: (x^2 + y^2 + z^2).mod( (x - y, y - z) ) + sage: (x^2 + y^2 + z^2).mod( (x - y, y - z) ) # optional - sage.libs.singular 3*z^2 sage: f = (x^2 + y^2 + z^2)^2; f x^4 + 2*x^2*y^2 + y^4 + 2*x^2*z^2 + 2*y^2*z^2 + z^4 - sage: f.mod( (x - y, y - z) ) + sage: f.mod( (x - y, y - z) ) # optional - sage.libs.singular 9*z^4 In this example `y` is eliminated:: - sage: (x^2 + y^2 + z^2).mod( (x^3, y - z) ) + sage: (x^2 + y^2 + z^2).mod( (x^3, y - z) ) # optional - sage.libs.singular x^2 + 2*z^2 """ from sage.rings.ideal import is_Ideal @@ -3367,7 +3367,7 @@ cdef class Expression(CommutativeRingElement): EXAMPLES:: - sage: isinstance(SR.var('y'), sage.structure.element.Expression) # optional - sage.symbolic + sage: isinstance(SR.var('y'), sage.structure.element.Expression) # optional - sage.symbolic True By design, there is a unique direct subclass:: @@ -3404,195 +3404,251 @@ cdef class Vector(ModuleElementWithMutability): Here we test (vector * vector) multiplication:: - sage: parent(vector(ZZ,[1,2])*vector(ZZ,[1,2])) + sage: parent(vector(ZZ, [1,2]) * vector(ZZ, [1,2])) # optional - sage.modules Integer Ring - sage: parent(vector(ZZ,[1,2])*vector(QQ,[1,2])) + sage: parent(vector(ZZ, [1,2]) * vector(QQ, [1,2])) # optional - sage.modules Rational Field - sage: parent(vector(QQ,[1,2])*vector(ZZ,[1,2])) + sage: parent(vector(QQ, [1,2]) * vector(ZZ, [1,2])) # optional - sage.modules Rational Field - sage: parent(vector(QQ,[1,2])*vector(QQ,[1,2])) + sage: parent(vector(QQ, [1,2]) * vector(QQ, [1,2])) # optional - sage.modules Rational Field - sage: parent(vector(QQ,[1,2,3,4])*vector(ZZ['x'],[1,2,3,4])) + sage: parent(vector(QQ, [1,2,3,4]) * vector(ZZ['x'], [1,2,3,4])) # optional - sage.modules Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x'],[1,2,3,4])*vector(QQ,[1,2,3,4])) + sage: parent(vector(ZZ['x'], [1,2,3,4]) * vector(QQ, [1,2,3,4])) # optional - sage.modules Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(QQ,[1,2,3,4])*vector(ZZ['x']['y'],[1,2,3,4])) + sage: parent(vector(QQ, [1,2,3,4]) * vector(ZZ['x']['y'], [1,2,3,4])) # optional - sage.modules Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2,3,4])*vector(QQ,[1,2,3,4])) + sage: parent(vector(ZZ['x']['y'], [1,2,3,4]) * vector(QQ, [1,2,3,4])) # optional - sage.modules Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(QQ['x'],[1,2,3,4])*vector(ZZ['x']['y'],[1,2,3,4])) + sage: parent(vector(QQ['x'], [1,2,3,4]) * vector(ZZ['x']['y'], [1,2,3,4])) # optional - sage.modules Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2,3,4])*vector(QQ['x'],[1,2,3,4])) + sage: parent(vector(ZZ['x']['y'], [1,2,3,4]) * vector(QQ['x'], [1,2,3,4])) # optional - sage.modules Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(QQ['y'],[1,2,3,4])*vector(ZZ['x']['y'],[1,2,3,4])) + sage: parent(vector(QQ['y'], [1,2,3,4]) * vector(ZZ['x']['y'], [1,2,3,4])) # optional - sage.modules Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2,3,4])*vector(QQ['y'],[1,2,3,4])) + sage: parent(vector(ZZ['x']['y'], [1,2,3,4]) * vector(QQ['y'], [1,2,3,4])) # optional - sage.modules Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x'],[1,2,3,4])*vector(ZZ['y'],[1,2,3,4])) + sage: parent(vector(ZZ['x'], [1,2,3,4]) * vector(ZZ['y'], [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Integer Ring' - sage: parent(vector(ZZ['x'],[1,2,3,4])*vector(QQ['y'],[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and + 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Integer Ring' + sage: parent(vector(ZZ['x'], [1,2,3,4]) * vector(QQ['y'], [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' - sage: parent(vector(QQ['x'],[1,2,3,4])*vector(ZZ['y'],[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and + 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' + sage: parent(vector(QQ['x'], [1,2,3,4]) * vector(ZZ['y'], [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Integer Ring' - sage: parent(vector(QQ['x'],[1,2,3,4])*vector(QQ['y'],[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and + 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Integer Ring' + sage: parent(vector(QQ['x'], [1,2,3,4]) * vector(QQ['y'], [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and + 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' Here we test (vector * matrix) multiplication:: - sage: parent(vector(ZZ,[1,2])*matrix(ZZ,2,2,[1,2,3,4])) + sage: parent(vector(ZZ, [1,2]) * matrix(ZZ, 2, 2, [1,2,3,4])) # optional - sage.modules Ambient free module of rank 2 over the principal ideal domain Integer Ring - sage: parent(vector(QQ,[1,2])*matrix(ZZ,2,2,[1,2,3,4])) + sage: parent(vector(QQ, [1,2]) * matrix(ZZ, 2, 2, [1,2,3,4])) # optional - sage.modules Vector space of dimension 2 over Rational Field - sage: parent(vector(ZZ,[1,2])*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(vector(ZZ, [1,2]) * matrix(QQ, 2, 2, [1,2,3,4])) # optional - sage.modules Vector space of dimension 2 over Rational Field - sage: parent(vector(QQ,[1,2])*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(vector(QQ, [1,2]) * matrix(QQ, 2, 2, [1,2,3,4])) # optional - sage.modules Vector space of dimension 2 over Rational Field - sage: parent(vector(QQ,[1,2])*matrix(ZZ['x'],2,2,[1,2,3,4])) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x'],[1,2])*matrix(QQ,2,2,[1,2,3,4])) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(QQ,[1,2])*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2])*matrix(QQ,2,2,[1,2,3,4])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(QQ['x'],[1,2])*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2])*matrix(QQ['x'],2,2,[1,2,3,4])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(QQ['y'],[1,2])*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2])*matrix(QQ['y'],2,2,[1,2,3,4])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(ZZ['x'],[1,2])*matrix(ZZ['y'],2,2,[1,2,3,4])) + sage: parent(vector(QQ, [1,2]) * matrix(ZZ['x'], 2, 2, [1,2,3,4])) # optional - sage.modules + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x'], [1,2]) * matrix(QQ, 2, 2, [1,2,3,4])) # optional - sage.modules + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x over Rational Field + + sage: parent(vector(QQ, [1,2]) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x']['y'], [1,2]) * matrix(QQ, 2, 2, [1,2,3,4])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(vector(QQ['x'], [1,2]) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x']['y'], [1,2]) * matrix(QQ['x'], 2, 2, [1,2,3,4])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(vector(QQ['y'], [1,2]) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x']['y'], [1,2]) * matrix(QQ['y'], 2, 2, [1,2,3,4])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(vector(ZZ['x'], [1,2]) * matrix(ZZ['y'], 2, 2, [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' - sage: parent(vector(ZZ['x'],[1,2])*matrix(QQ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' + sage: parent(vector(ZZ['x'], [1,2]) * matrix(QQ['y'], 2, 2, [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' - sage: parent(vector(QQ['x'],[1,2])*matrix(ZZ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' + sage: parent(vector(QQ['x'], [1,2]) * matrix(ZZ['y'], 2, 2, [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' - sage: parent(vector(QQ['x'],[1,2])*matrix(QQ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' + sage: parent(vector(QQ['x'], [1,2]) * matrix(QQ['y'], 2, 2, [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' Here we test (vector * scalar) multiplication:: - sage: parent(vector(ZZ,[1,2])*ZZ(1)) + sage: parent(vector(ZZ, [1,2]) * ZZ(1)) # optional - sage.modules Ambient free module of rank 2 over the principal ideal domain Integer Ring - sage: parent(vector(QQ,[1,2])*ZZ(1)) + sage: parent(vector(QQ, [1,2]) * ZZ(1)) # optional - sage.modules Vector space of dimension 2 over Rational Field - sage: parent(vector(ZZ,[1,2])*QQ(1)) + sage: parent(vector(ZZ, [1,2]) * QQ(1)) # optional - sage.modules Vector space of dimension 2 over Rational Field - sage: parent(vector(QQ,[1,2])*QQ(1)) + sage: parent(vector(QQ, [1,2]) * QQ(1)) # optional - sage.modules Vector space of dimension 2 over Rational Field - sage: parent(vector(QQ,[1,2])*ZZ['x'](1)) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x'],[1,2])*QQ(1)) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(QQ,[1,2])*ZZ['x']['y'](1)) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2])*QQ(1)) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(QQ['x'],[1,2])*ZZ['x']['y'](1)) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2])*QQ['x'](1)) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(QQ['y'],[1,2])*ZZ['x']['y'](1)) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(vector(ZZ['x']['y'],[1,2])*QQ['y'](1)) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(vector(ZZ['x'],[1,2])*ZZ['y'](1)) + sage: parent(vector(QQ, [1,2]) * ZZ['x'](1)) # optional - sage.modules + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x'], [1,2]) * QQ(1)) # optional - sage.modules + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x over Rational Field + + sage: parent(vector(QQ, [1,2]) * ZZ['x']['y'](1)) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x']['y'], [1,2]) * QQ(1)) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(vector(QQ['x'], [1,2]) * ZZ['x']['y'](1)) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x']['y'], [1,2]) * QQ['x'](1)) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(vector(QQ['y'], [1,2]) * ZZ['x']['y'](1)) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(vector(ZZ['x']['y'], [1,2]) * QQ['y'](1)) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(vector(ZZ['x'], [1,2]) * ZZ['y'](1)) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Polynomial Ring in y over Integer Ring' - sage: parent(vector(ZZ['x'],[1,2])*QQ['y'](1)) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and + 'Univariate Polynomial Ring in y over Integer Ring' + sage: parent(vector(ZZ['x'], [1,2]) * QQ['y'](1)) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Polynomial Ring in y over Rational Field' - sage: parent(vector(QQ['x'],[1,2])*ZZ['y'](1)) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and + 'Univariate Polynomial Ring in y over Rational Field' + sage: parent(vector(QQ['x'], [1,2]) * ZZ['y'](1)) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Univariate Polynomial Ring in y over Integer Ring' - sage: parent(vector(QQ['x'],[1,2])*QQ['y'](1)) + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and + 'Univariate Polynomial Ring in y over Integer Ring' + sage: parent(vector(QQ['x'], [1,2]) * QQ['y'](1)) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and + 'Univariate Polynomial Ring in y over Rational Field' Here we test (scalar * vector) multiplication:: - sage: parent(ZZ(1)*vector(ZZ,[1,2])) + sage: parent(ZZ(1) * vector(ZZ, [1,2])) # optional - sage.modules Ambient free module of rank 2 over the principal ideal domain Integer Ring - sage: parent(QQ(1)*vector(ZZ,[1,2])) + sage: parent(QQ(1) * vector(ZZ, [1,2])) # optional - sage.modules Vector space of dimension 2 over Rational Field - sage: parent(ZZ(1)*vector(QQ,[1,2])) + sage: parent(ZZ(1) * vector(QQ, [1,2])) # optional - sage.modules Vector space of dimension 2 over Rational Field - sage: parent(QQ(1)*vector(QQ,[1,2])) + sage: parent(QQ(1) * vector(QQ, [1,2])) # optional - sage.modules Vector space of dimension 2 over Rational Field - sage: parent(QQ(1)*vector(ZZ['x'],[1,2])) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x'](1)*vector(QQ,[1,2])) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - - sage: parent(QQ(1)*vector(ZZ['x']['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x']['y'](1)*vector(QQ,[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(QQ['x'](1)*vector(ZZ['x']['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x']['y'](1)*vector(QQ['x'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(QQ['y'](1)*vector(ZZ['x']['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x']['y'](1)*vector(QQ['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(ZZ['x'](1)*vector(ZZ['y'],[1,2])) + sage: parent(QQ(1) * vector(ZZ['x'], [1,2])) # optional - sage.modules + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x over Rational Field + sage: parent(ZZ['x'](1) * vector(QQ, [1,2])) # optional - sage.modules + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x over Rational Field + + sage: parent(QQ(1) * vector(ZZ['x']['y'], [1,2])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(ZZ['x']['y'](1) * vector(QQ, [1,2])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(QQ['x'](1) * vector(ZZ['x']['y'], [1,2])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(ZZ['x']['y'](1) * vector(QQ['x'], [1,2])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(QQ['y'](1) * vector(ZZ['x']['y'], [1,2])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(ZZ['x']['y'](1) * vector(QQ['y'], [1,2])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(ZZ['x'](1) * vector(ZZ['y'], [1,2])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' - sage: parent(ZZ['x'](1)*vector(QQ['y'],[1,2])) + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Integer Ring' and + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' + sage: parent(ZZ['x'](1) * vector(QQ['y'], [1,2])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' - sage: parent(QQ['x'](1)*vector(ZZ['y'],[1,2])) + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Integer Ring' and + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' + sage: parent(QQ['x'](1) * vector(ZZ['y'], [1,2])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' - sage: parent(QQ['x'](1)*vector(QQ['y'],[1,2])) + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Rational Field' and + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' + sage: parent(QQ['x'](1) * vector(QQ['y'], [1,2])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Rational Field' and + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' """ if have_same_parent(left, right): return (left)._dot_product_(right) @@ -3613,14 +3669,14 @@ cdef class Vector(ModuleElementWithMutability): TESTS:: - sage: A = matrix([[1, 2], [0, 3]]) - sage: b = vector([0, 1]) - sage: x = b / A; x + sage: A = matrix([[1, 2], [0, 3]]) # optional - sage.modules + sage: b = vector([0, 1]) # optional - sage.modules + sage: x = b / A; x # optional - sage.modules (0, 1/3) - sage: x == b * ~A + sage: x == b * ~A # optional - sage.modules True - sage: A = matrix([[1, 2], [0, 3], [1, 5]]) - sage: (b / A) * A == b + sage: A = matrix([[1, 2], [0, 3], [1, 5]]) # optional - sage.modules + sage: (b / A) * A == b # optional - sage.modules True """ right = py_scalar_to_element(right) @@ -3647,32 +3703,33 @@ cdef class Vector(ModuleElementWithMutability): EXAMPLES:: - sage: v = vector([1,2,3]) - sage: v._magma_init_(magma) # optional - magma + sage: v = vector([1,2,3]) # optional - sage.modules + sage: v._magma_init_(magma) # optional - magma # optional - sage.modules '_sage_[...]![1,2,3]' - sage: mv = magma(v); mv # optional - magma + sage: mv = magma(v); mv # optional - magma # optional - sage.modules (1 2 3) - sage: mv.Type() # optional - magma + sage: mv.Type() # optional - magma # optional - sage.modules ModTupRngElt - sage: mv.Parent() # optional - magma + sage: mv.Parent() # optional - magma # optional - sage.modules Full RSpace of degree 3 over Integer Ring - sage: v = vector(QQ, [1/2, 3/4, 5/6]) - sage: mv = magma(v); mv # optional - magma + sage: v = vector(QQ, [1/2, 3/4, 5/6]) # optional - sage.modules + sage: mv = magma(v); mv # optional - magma # optional - sage.modules (1/2 3/4 5/6) - sage: mv.Type() # optional - magma + sage: mv.Type() # optional - magma # optional - sage.modules ModTupFldElt - sage: mv.Parent() # optional - magma + sage: mv.Parent() # optional - magma # optional - sage.modules Full Vector space of degree 3 over Rational Field A more demanding example:: sage: R. = QQ[] - sage: v = vector([x^3, y, 2/3*z + x/y]) - sage: magma(v) # optional - magma + sage: v = vector([x^3, y, 2/3*z + x/y]) # optional - sage.modules + sage: magma(v) # optional - magma # optional - sage.modules ( x^3 y (2/3*y*z + x)/y) - sage: magma(v).Parent() # optional - magma - Full Vector space of degree 3 over Multivariate rational function field of rank 3 over Rational Field + sage: magma(v).Parent() # optional - magma # optional - sage.modules + Full Vector space of degree 3 + over Multivariate rational function field of rank 3 over Rational Field """ V = magma(self._parent) v = [x._magma_init_(magma) for x in self.list()] @@ -3706,210 +3763,269 @@ cdef class Matrix(ModuleElement): Here we test (matrix * matrix) multiplication:: - sage: parent(matrix(ZZ,2,2,[1,2,3,4])*matrix(ZZ,2,2,[1,2,3,4])) + sage: parent(matrix(ZZ, 2, 2, [1,2,3,4]) * matrix(ZZ, 2, 2, [1,2,3,4])) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: parent(matrix(QQ,2,2,[1,2,3,4])*matrix(ZZ,2,2,[1,2,3,4])) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * matrix(ZZ, 2, 2, [1,2,3,4])) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(matrix(ZZ,2,2,[1,2,3,4])*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(matrix(ZZ, 2, 2, [1,2,3,4]) * matrix(QQ, 2, 2, [1,2,3,4])) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * matrix(QQ, 2, 2, [1,2,3,4])) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*matrix(ZZ['x'],2,2,[1,2,3,4])) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * matrix(ZZ['x'], 2, 2, [1,2,3,4])) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * matrix(QQ, 2, 2, [1,2,3,4])) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*matrix(QQ,2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*matrix(QQ['x'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(QQ['y'],2,2,[1,2,3,4])*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*matrix(QQ['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*matrix(ZZ['y'],2,2,[1,2,3,4])) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * matrix(QQ, 2, 2, [1,2,3,4])) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * matrix(QQ['x'], 2, 2, [1,2,3,4])) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(QQ['y'], 2, 2, [1,2,3,4]) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * matrix(QQ['y'], 2, 2, [1,2,3,4])) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * matrix(ZZ['y'], 2, 2, [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*matrix(QQ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * matrix(QQ['y'], 2, 2, [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*matrix(ZZ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * matrix(ZZ['y'], 2, 2, [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*matrix(QQ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * matrix(QQ['y'], 2, 2, [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' We test that the bug reported in :trac:`27352` has been fixed:: - sage: A = matrix(QQ, [[1, 2], [-1, 0], [1, 1]]) - sage: B = matrix(QQ, [[0, 4], [1, -1], [1, 2]]) - sage: A*B + sage: A = matrix(QQ, [[1, 2], [-1, 0], [1, 1]]) # optional - sage.modules + sage: B = matrix(QQ, [[0, 4], [1, -1], [1, 2]]) # optional - sage.modules + sage: A * B # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 3 by 2 dense matrices over Rational Field' and 'Full MatrixSpace of 3 by 2 dense matrices over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 3 by 2 dense matrices over Rational Field' and 'Full MatrixSpace of 3 by 2 dense matrices over Rational Field' Here we test (matrix * vector) multiplication:: - sage: parent(matrix(ZZ,2,2,[1,2,3,4])*vector(ZZ,[1,2])) + sage: parent(matrix(ZZ, 2, 2, [1,2,3,4]) * vector(ZZ, [1,2])) # optional - sage.modules Ambient free module of rank 2 over the principal ideal domain Integer Ring - sage: parent(matrix(QQ,2,2,[1,2,3,4])*vector(ZZ,[1,2])) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * vector(ZZ, [1,2])) # optional - sage.modules Vector space of dimension 2 over Rational Field - sage: parent(matrix(ZZ,2,2,[1,2,3,4])*vector(QQ,[1,2])) + sage: parent(matrix(ZZ, 2, 2, [1,2,3,4]) * vector(QQ, [1,2])) # optional - sage.modules Vector space of dimension 2 over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*vector(QQ,[1,2])) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * vector(QQ, [1,2])) # optional - sage.modules Vector space of dimension 2 over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*vector(ZZ['x'],[1,2])) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*vector(QQ,[1,2])) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(QQ,2,2,[1,2,3,4])*vector(ZZ['x']['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*vector(QQ,[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*vector(ZZ['x']['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*vector(QQ['x'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(QQ['y'],2,2,[1,2,3,4])*vector(ZZ['x']['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*vector(QQ['y'],[1,2])) - Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*vector(ZZ['y'],[1,2])) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * vector(ZZ['x'], [1,2])) # optional - sage.modules + Ambient free module of rank 2 over the principal ideal domain + Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * vector(QQ, [1,2])) # optional - sage.modules + Ambient free module of rank 2 over the principal ideal domain + Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * vector(ZZ['x']['y'], [1,2])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * vector(QQ, [1,2])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * vector(ZZ['x']['y'], [1,2])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * vector(QQ['x'], [1,2])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(QQ['y'], 2, 2, [1,2,3,4]) * vector(ZZ['x']['y'], [1,2])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * vector(QQ['y'], [1,2])) # optional - sage.modules + Ambient free module of rank 2 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * vector(ZZ['y'], [1,2])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*vector(QQ['y'],[1,2])) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * vector(QQ['y'], [1,2])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*vector(ZZ['y'],[1,2])) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * vector(ZZ['y'], [1,2])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*vector(QQ['y'],[1,2])) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and + 'Ambient free module of rank 2 over the integral domain Univariate Polynomial Ring in y over Integer Ring' + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * vector(QQ['y'], [1,2])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' Here we test (matrix * scalar) multiplication:: - sage: parent(matrix(ZZ,2,2,[1,2,3,4])*ZZ(1)) + sage: parent(matrix(ZZ, 2, 2, [1,2,3,4]) * ZZ(1)) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: parent(matrix(QQ,2,2,[1,2,3,4])*ZZ(1)) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * ZZ(1)) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(matrix(ZZ,2,2,[1,2,3,4])*QQ(1)) + sage: parent(matrix(ZZ, 2, 2, [1,2,3,4]) * QQ(1)) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*QQ(1)) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * QQ(1)) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*ZZ['x'](1)) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * ZZ['x'](1)) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*QQ(1)) + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * QQ(1)) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(QQ,2,2,[1,2,3,4])*ZZ['x']['y'](1)) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*QQ(1)) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*ZZ['x']['y'](1)) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*QQ['x'](1)) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(QQ['y'],2,2,[1,2,3,4])*ZZ['x']['y'](1)) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(matrix(ZZ['x']['y'],2,2,[1,2,3,4])*QQ['y'](1)) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*ZZ['y'](1)) + sage: parent(matrix(QQ, 2, 2, [1,2,3,4]) * ZZ['x']['y'](1)) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * QQ(1)) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * ZZ['x']['y'](1)) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * QQ['x'](1)) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(QQ['y'], 2, 2, [1,2,3,4]) * ZZ['x']['y'](1)) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(matrix(ZZ['x']['y'], 2, 2, [1,2,3,4]) * QQ['y'](1)) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * ZZ['y'](1)) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Polynomial Ring in y over Integer Ring' - sage: parent(matrix(ZZ['x'],2,2,[1,2,3,4])*QQ['y'](1)) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and + 'Univariate Polynomial Ring in y over Integer Ring' + sage: parent(matrix(ZZ['x'], 2, 2, [1,2,3,4]) * QQ['y'](1)) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Polynomial Ring in y over Rational Field' - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*ZZ['y'](1)) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Integer Ring' and + 'Univariate Polynomial Ring in y over Rational Field' + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * ZZ['y'](1)) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Univariate Polynomial Ring in y over Integer Ring' - sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*QQ['y'](1)) + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and + 'Univariate Polynomial Ring in y over Integer Ring' + sage: parent(matrix(QQ['x'], 2, 2, [1,2,3,4]) * QQ['y'](1)) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and + 'Univariate Polynomial Ring in y over Rational Field' Here we test (scalar * matrix) multiplication:: - sage: parent(ZZ(1)*matrix(ZZ,2,2,[1,2,3,4])) + sage: parent(ZZ(1) * matrix(ZZ, 2, 2, [1,2,3,4])) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: parent(QQ(1)*matrix(ZZ,2,2,[1,2,3,4])) + sage: parent(QQ(1) * matrix(ZZ, 2, 2, [1,2,3,4])) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(ZZ(1)*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(ZZ(1) * matrix(QQ, 2, 2, [1,2,3,4])) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(QQ(1)*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(QQ(1) * matrix(QQ, 2, 2, [1,2,3,4])) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: parent(QQ(1)*matrix(ZZ['x'],2,2,[1,2,3,4])) + sage: parent(QQ(1) * matrix(ZZ['x'], 2, 2, [1,2,3,4])) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x'](1)*matrix(QQ,2,2,[1,2,3,4])) + sage: parent(ZZ['x'](1) * matrix(QQ, 2, 2, [1,2,3,4])) # optional - sage.modules Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field - sage: parent(QQ(1)*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x']['y'](1)*matrix(QQ,2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(QQ['x'](1)*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x']['y'](1)*matrix(QQ['x'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(QQ['y'](1)*matrix(ZZ['x']['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - sage: parent(ZZ['x']['y'](1)*matrix(QQ['y'],2,2,[1,2,3,4])) - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field - - sage: parent(ZZ['x'](1)*matrix(ZZ['y'],2,2,[1,2,3,4])) + sage: parent(QQ(1) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(ZZ['x']['y'](1) * matrix(QQ, 2, 2, [1,2,3,4])) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(QQ['x'](1) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(ZZ['x']['y'](1) * matrix(QQ['x'], 2, 2, [1,2,3,4])) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(QQ['y'](1) * matrix(ZZ['x']['y'], 2, 2, [1,2,3,4])) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices + over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + sage: parent(ZZ['x']['y'](1) * matrix(QQ['y'], 2, 2, [1,2,3,4])) # optional - sage.modules + Full MatrixSpace of 2 by 2 dense matrices + over Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + + sage: parent(ZZ['x'](1) * matrix(ZZ['y'], 2, 2, [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' - sage: parent(ZZ['x'](1)*matrix(QQ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Integer Ring' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' + sage: parent(ZZ['x'](1) * matrix(QQ['y'], 2, 2, [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Integer Ring' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' - sage: parent(QQ['x'](1)*matrix(ZZ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Integer Ring' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' + sage: parent(QQ['x'](1) * matrix(ZZ['y'], 2, 2, [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' - sage: parent(QQ['x'](1)*matrix(QQ['y'],2,2,[1,2,3,4])) + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Rational Field' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Integer Ring' + sage: parent(QQ['x'](1) * matrix(QQ['y'], 2, 2, [1,2,3,4])) # optional - sage.modules Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Univariate Polynomial Ring in x over Rational Field' and 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Univariate Polynomial Ring in x over Rational Field' and + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field' Examples with matrices having matrix coefficients:: - sage: m = matrix - sage: a = m([[m([[1,2],[3,4]]),m([[5,6],[7,8]])],[m([[9,10],[11,12]]),m([[13,14],[15,16]])]]) - sage: 3*a + sage: m = matrix # optional - sage.modules + sage: a = m([[m([[1,2],[3,4]]),m([[5,6],[7,8]])],[m([[9,10],[11,12]]),m([[13,14],[15,16]])]]) # optional - sage.modules + sage: 3 * a # optional - sage.modules [[ 3 6] [ 9 12] [15 18] [21 24]] @@ -3917,9 +4033,9 @@ cdef class Matrix(ModuleElement): [33 36] [39 42] [45 48]] - sage: m = matrix - sage: a = m([[m([[1,2],[3,4]]),m([[5,6],[7,8]])],[m([[9,10],[11,12]]),m([[13,14],[15,16]])]]) - sage: a*3 + sage: m = matrix # optional - sage.modules + sage: a = m([[m([[1,2],[3,4]]),m([[5,6],[7,8]])],[m([[9,10],[11,12]]),m([[13,14],[15,16]])]]) # optional - sage.modules + sage: a * 3 # optional - sage.modules [[ 3 6] [ 9 12] [15 18] [21 24]] @@ -3961,32 +4077,32 @@ cdef class Matrix(ModuleElement): EXAMPLES:: - sage: a = matrix(ZZ, 2, range(4)) - sage: operator.truediv(a, 5) + sage: a = matrix(ZZ, 2, range(4)) # optional - sage.modules + sage: operator.truediv(a, 5) # optional - sage.modules [ 0 1/5] [2/5 3/5] - sage: a = matrix(ZZ, 2, range(4)) - sage: b = matrix(ZZ, 2, [1,1,0,5]) - sage: operator.truediv(a, b) + sage: a = matrix(ZZ, 2, range(4)) # optional - sage.modules + sage: b = matrix(ZZ, 2, [1,1,0,5]) # optional - sage.modules + sage: operator.truediv(a, b) # optional - sage.modules [ 0 1/5] [ 2 1/5] - sage: c = matrix(QQ, 2, [3,2,5,7]) - sage: operator.truediv(c, a) + sage: c = matrix(QQ, 2, [3,2,5,7]) # optional - sage.modules + sage: operator.truediv(c, a) # optional - sage.modules [-5/2 3/2] [-1/2 5/2] TESTS:: - sage: a = matrix(ZZ, [[1, 2], [0, 3]]) - sage: b = matrix(ZZ, 3, 2, range(6)) - sage: x = b / a; x + sage: a = matrix(ZZ, [[1, 2], [0, 3]]) # optional - sage.modules + sage: b = matrix(ZZ, 3, 2, range(6)) # optional - sage.modules + sage: x = b / a; x # optional - sage.modules [ 0 1/3] [ 2 -1/3] [ 4 -1] - sage: x == b * ~a + sage: x == b * ~a # optional - sage.modules True - sage: a = matrix(ZZ, [[1, 2], [0, 3], [1, 5]]) - sage: (b / a) * a == b + sage: a = matrix(ZZ, [[1, 2], [0, 3], [1, 5]]) # optional - sage.modules + sage: (b / a) * a == b # optional - sage.modules True """ if is_Matrix(right): @@ -4042,14 +4158,14 @@ cdef class PrincipalIdealDomainElement(DedekindDomainElement): :trac:`30849`:: - sage: 2.gcd(pari(3)) + sage: 2.gcd(pari(3)) # optional - sage.libs.pari 1 - sage: type(2.gcd(pari(3))) + sage: type(2.gcd(pari(3))) # optional - sage.libs.pari - sage: 2.gcd(pari('1/3')) + sage: 2.gcd(pari('1/3')) # optional - sage.libs.pari 1/3 - sage: type(2.gcd(pari('1/3'))) + sage: type(2.gcd(pari('1/3'))) # optional - sage.libs.pari sage: import gmpy2 @@ -4060,7 +4176,7 @@ cdef class PrincipalIdealDomainElement(DedekindDomainElement): sage: 2.gcd(gmpy2.mpq(1,3)) 1/3 - sage: type(2.gcd(pari('1/3'))) + sage: type(2.gcd(pari('1/3'))) # optional - sage.libs.pari """ # NOTE: in order to handle nicely pari or gmpy2 integers we do not rely only on coercion @@ -4081,14 +4197,14 @@ cdef class PrincipalIdealDomainElement(DedekindDomainElement): :trac:`30849`:: - sage: 2.lcm(pari(3)) + sage: 2.lcm(pari(3)) # optional - sage.libs.pari 6 - sage: type(2.lcm(pari(3))) + sage: type(2.lcm(pari(3))) # optional - sage.libs.pari - sage: 2.lcm(pari('1/3')) + sage: 2.lcm(pari('1/3')) # optional - sage.libs.pari 2 - sage: type(2.lcm(pari('1/3'))) + sage: type(2.lcm(pari('1/3'))) # optional - sage.libs.pari sage: import gmpy2 @@ -4138,15 +4254,15 @@ cdef class EuclideanDomainElement(PrincipalIdealDomainElement): EXAMPLES:: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: from sage.structure.element cimport EuclideanDomainElement ....: cdef class MyElt(EuclideanDomainElement): ....: def quo_rem(self, other): ....: return self._parent.var('quo,rem') ....: ''') - sage: e = MyElt(SR) # optional - sage.misc.cython - sage: e // e # optional - sage.misc.cython + sage: e = MyElt(SR) # optional - sage.misc.cython + sage: e // e # optional - sage.misc.cython quo """ Q, _ = self.quo_rem(right) @@ -4169,15 +4285,15 @@ cdef class EuclideanDomainElement(PrincipalIdealDomainElement): :: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: from sage.structure.element cimport EuclideanDomainElement ....: cdef class MyElt(EuclideanDomainElement): ....: def quo_rem(self, other): ....: return self._parent.var('quo,rem') ....: ''') - sage: e = MyElt(SR) # optional - sage.misc.cython - sage: e % e # optional - sage.misc.cython + sage: e = MyElt(SR) # optional - sage.misc.cython + sage: e % e # optional - sage.misc.cython rem """ _, R = self.quo_rem(other) @@ -4198,12 +4314,12 @@ cdef class FieldElement(CommutativeRingElement): EXAMPLES:: - sage: K. = NumberField(x^4 + x^2 + 2/3) - sage: c = (1+b) // (1-b); c + sage: K. = NumberField(x^4 + x^2 + 2/3) # optional - sage.rings.number_field + sage: c = (1+b) // (1-b); c # optional - sage.rings.number_field 3/4*b^3 + 3/4*b^2 + 3/2*b + 1/2 - sage: (1+b) / (1-b) == c + sage: (1+b) / (1-b) == c # optional - sage.rings.number_field True - sage: c * (1-b) + sage: c * (1-b) # optional - sage.rings.number_field b + 1 """ return self._div_(right) @@ -4253,10 +4369,10 @@ cdef class FieldElement(CommutativeRingElement): Test if :trac:`8671` is fixed:: sage: R. = QQ[] - sage: S. = R.quo(y^2 + 1) - sage: S.is_field = lambda : False - sage: F = Frac(S); u = F.one() - sage: u.quo_rem(u) + sage: S. = R.quo(y^2 + 1) # optional - sage.libs.pari + sage: S.is_field = lambda: False # optional - sage.libs.pari + sage: F = Frac(S); u = F.one() # optional - sage.libs.pari + sage: u.quo_rem(u) # optional - sage.libs.pari (1, 0) """ if not isinstance(right, FieldElement) or not (parent(right) is self._parent): @@ -4272,14 +4388,14 @@ cdef class FieldElement(CommutativeRingElement): EXAMPLES:: - sage: K. = QQ[sqrt(3)] - sage: K(0).divides(rt3) + sage: K. = QQ[sqrt(3)] # optional - sage.rings.number_field sage.symbolic + sage: K(0).divides(rt3) # optional - sage.rings.number_field sage.symbolic False - sage: rt3.divides(K(17)) + sage: rt3.divides(K(17)) # optional - sage.rings.number_field sage.symbolic True - sage: K(0).divides(K(0)) + sage: K(0).divides(K(0)) # optional - sage.rings.number_field sage.symbolic True - sage: rt3.divides(K(0)) + sage: rt3.divides(K(0)) # optional - sage.rings.number_field sage.symbolic True """ if not (other._parent is self._parent): @@ -4294,8 +4410,8 @@ def is_AlgebraElement(x): TESTS:: sage: from sage.structure.element import is_AlgebraElement - sage: R. = FreeAlgebra(QQ,2) - sage: is_AlgebraElement(x*y) + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules + sage: is_AlgebraElement(x * y) # optional - sage.combinat sage.modules True sage: is_AlgebraElement(1) @@ -4353,8 +4469,8 @@ cpdef canonical_coercion(x, y): EXAMPLES:: - sage: A = Matrix([[0, 1], [1, 0]]) - sage: canonical_coercion(A, 1) + sage: A = Matrix([[0, 1], [1, 0]]) # optional - sage.modules + sage: canonical_coercion(A, 1) # optional - sage.modules ( [0 1] [1 0] [1 0], [0 1] @@ -4404,14 +4520,16 @@ def coercion_traceback(dump=True): sage: 1 + 1/5 6/5 sage: coercion_traceback() # Should be empty, as all went well. - sage: 1/5 + GF(5).gen() + sage: 1/5 + GF(5).gen() # optional - sage.libs.pari Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for +: 'Rational Field' and 'Finite Field of size 5' - sage: coercion_traceback() + TypeError: unsupported operand parent(s) for +: + 'Rational Field' and 'Finite Field of size 5' + sage: coercion_traceback() # optional - sage.libs.pari Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Rational Field' and 'Finite Field of size 5' + TypeError: no common canonical parent for objects with parents: + 'Rational Field' and 'Finite Field of size 5' """ if dump: for traceback in coercion_model.exception_stack(): @@ -4444,7 +4562,7 @@ def coerce_binop(method): Sparse polynomial rings uses `@coerce_binop` on `gcd`:: - sage: S. = PolynomialRing(ZZ,sparse=True) + sage: S. = PolynomialRing(ZZ, sparse=True) sage: f = x^2 sage: g = x sage: f.gcd(g) #indirect doctest @@ -4465,15 +4583,15 @@ def coerce_binop(method): sage: h = R2(1) sage: f.gcd(g) 1 - sage: f.gcd(g,algorithm='modular') + sage: f.gcd(g, algorithm='modular') 1 sage: f.gcd(h) 1 - sage: f.gcd(h,algorithm='modular') + sage: f.gcd(h, algorithm='modular') 1 sage: h.gcd(f) 1 - sage: h.gcd(f,'modular') + sage: h.gcd(f, 'modular') 1 We demonstrate a small class using `@coerce_binop` on a method:: diff --git a/src/sage/structure/element_wrapper.pyx b/src/sage/structure/element_wrapper.pyx index f77bcce6ea5..44aa88ea530 100644 --- a/src/sage/structure/element_wrapper.pyx +++ b/src/sage/structure/element_wrapper.pyx @@ -209,8 +209,8 @@ cdef class ElementWrapper(Element): sage: from sage.structure.element_wrapper import DummyParent sage: ElementWrapper(DummyParent("A parent"), 1)._ascii_art_() 1 - sage: x = var('x') - sage: ElementWrapper(DummyParent("A parent"), x^2 + x)._ascii_art_() + sage: x = var('x') # optional - sage.symbolic + sage: ElementWrapper(DummyParent("A parent"), x^2 + x)._ascii_art_() # optional - sage.symbolic 2 x + x """ @@ -226,8 +226,8 @@ cdef class ElementWrapper(Element): sage: from sage.structure.element_wrapper import DummyParent sage: ElementWrapper(DummyParent("A parent"), 1)._ascii_art_() 1 - sage: x = var('x') - sage: ElementWrapper(DummyParent("A parent"), x^2 + x)._unicode_art_() + sage: x = var('x') # optional - sage.symbolic + sage: ElementWrapper(DummyParent("A parent"), x^2 + x)._unicode_art_() # optional - sage.symbolic 2 x + x """ @@ -561,8 +561,8 @@ cdef class ElementWrapperCheckWrappedClass(ElementWrapper): :: sage: A = cartesian_product([ZZ, ZZ]) - sage: B = cartesian_product([GF(3), GF(5)]) - sage: A((3,5)) == B((0,0)) + sage: B = cartesian_product([GF(3), GF(5)]) # optional - sage.rings.finite_rings + sage: A((3,5)) == B((0,0)) # optional - sage.rings.finite_rings True """ if type(self) is type(right): diff --git a/src/sage/structure/factorization.py b/src/sage/structure/factorization.py index b2caa14a285..0d4a704783c 100644 --- a/src/sage/structure/factorization.py +++ b/src/sage/structure/factorization.py @@ -70,22 +70,22 @@ sage: f = -5*(x-2)*(x-3) sage: f -5*x^2 + 25*x - 30 - sage: F = f.factor(); F + sage: F = f.factor(); F # optional - sage.libs.pari (-5) * (x - 3) * (x - 2) - sage: F.unit() + sage: F.unit() # optional - sage.libs.pari -5 - sage: F.value() + sage: F.value() # optional - sage.libs.pari -5*x^2 + 25*x - 30 The underlying list is the list of pairs `(p_i, e_i)`, where each `p_i` is a 'prime' and each `e_i` is an integer. The unit part is discarded by the list:: - sage: list(F) + sage: list(F) # optional - sage.libs.pari [(x - 3, 1), (x - 2, 1)] - sage: len(F) + sage: len(F) # optional - sage.libs.pari 2 - sage: F[1] + sage: F[1] # optional - sage.libs.pari (x - 2, 1) In the ring `\ZZ[x]`, the integer `-5` is not a unit, so the @@ -95,56 +95,59 @@ sage: f = -5*(x-2)*(x-3) sage: f -5*x^2 + 25*x - 30 - sage: F = f.factor(); F + sage: F = f.factor(); F # optional - sage.libs.pari (-1) * 5 * (x - 3) * (x - 2) - sage: F.universe() + sage: F.universe() # optional - sage.libs.pari Univariate Polynomial Ring in x over Integer Ring - sage: F.unit() + sage: F.unit() # optional - sage.libs.pari -1 - sage: list(F) + sage: list(F) # optional - sage.libs.pari [(5, 1), (x - 3, 1), (x - 2, 1)] - sage: F.value() + sage: F.value() # optional - sage.libs.pari -5*x^2 + 25*x - 30 - sage: len(F) + sage: len(F) # optional - sage.libs.pari 3 On the other hand, -1 is a unit in `\ZZ`, so it is included in the unit:: sage: x = ZZ['x'].0 - sage: f = -1*(x-2)*(x-3) - sage: F = f.factor(); F + sage: f = -1*(x-2)*(x-3) # optional - sage.libs.pari + sage: F = f.factor(); F # optional - sage.libs.pari (-1) * (x - 3) * (x - 2) - sage: F.unit() + sage: F.unit() # optional - sage.libs.pari -1 - sage: list(F) + sage: list(F) # optional - sage.libs.pari [(x - 3, 1), (x - 2, 1)] Factorizations can involve fairly abstract mathematical objects:: sage: F = ModularSymbols(11,4).factorization() sage: F - (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) * - (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) * - (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) + (Modular Symbols subspace of dimension 2 of Modular Symbols space + of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) * + (Modular Symbols subspace of dimension 2 of Modular Symbols space + of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) * + (Modular Symbols subspace of dimension 2 of Modular Symbols space + of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) sage: type(F) - sage: K. = NumberField(x^2 + 3); K + sage: K. = NumberField(x^2 + 3); K # optional - sage.rings.number_field Number Field in a with defining polynomial x^2 + 3 - sage: f = K.factor(15); f + sage: f = K.factor(15); f # optional - sage.rings.number_field (Fractional ideal (1/2*a + 3/2))^2 * (Fractional ideal (5)) - sage: f.universe() + sage: f.universe() # optional - sage.rings.number_field Monoid of ideals of Number Field in a with defining polynomial x^2 + 3 - sage: f.unit() + sage: f.unit() # optional - sage.rings.number_field Fractional ideal (1) - sage: g=K.factor(9); g + sage: g = K.factor(9); g # optional - sage.rings.number_field (Fractional ideal (1/2*a + 3/2))^4 - sage: f.lcm(g) + sage: f.lcm(g) # optional - sage.rings.number_field (Fractional ideal (1/2*a + 3/2))^4 * (Fractional ideal (5)) - sage: f.gcd(g) + sage: f.gcd(g) # optional - sage.rings.number_field (Fractional ideal (1/2*a + 3/2))^2 - sage: f.is_integral() + sage: f.is_integral() # optional - sage.rings.number_field True TESTS:: @@ -206,7 +209,7 @@ class Factorization(SageObject): -1 sage: loads(F.dumps()) == F True - sage: F = Factorization([(x,1/3)]) + sage: F = Factorization([(x, 1/3)]) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: no conversion of this rational to integer @@ -281,13 +284,13 @@ def __init__(self, x, unit=None, cr=False, sort=True, simplify=True): sage: Factorization([(2, 7), (5,2), (2, 5)]) 2^12 * 5^2 - sage: R. = FreeAlgebra(QQ,2) - sage: Factorization([(a,1),(b,1),(a,2)]) + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules + sage: Factorization([(a,1), (b,1), (a,2)]) # optional - sage.combinat sage.modules a * b * a^2 Autosorting (the default) swaps around the factors below:: - sage: F = Factorization([(ZZ^3, 2), (ZZ^2, 5)], cr=True); F + sage: F = Factorization([(ZZ^3, 2), (ZZ^2, 5)], cr=True); F # optional - sage.modules (Ambient free module of rank 2 over the principal ideal domain Integer Ring)^5 * (Ambient free module of rank 3 over the principal ideal domain Integer Ring)^2 """ @@ -413,7 +416,7 @@ def __richcmp__(self, other, op): sage: x = polygen(QQ) sage: x^2 - 1 > x^2 - 4 True - sage: factor(x^2 - 1) > factor(x^2 - 4) + sage: factor(x^2 - 1) > factor(x^2 - 4) # optional - sage.libs.pari True """ if not isinstance(other, Factorization): @@ -520,9 +523,9 @@ def universe(self): sage: F.universe() Integer Ring - sage: R. = FreeAlgebra(QQ, 3) - sage: F = Factorization([(z, 2)], 3) - sage: (F*F^-1).universe() + sage: R. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: F = Factorization([(z, 2)], 3) # optional - sage.combinat sage.modules + sage: (F*F^-1).universe() # optional - sage.combinat sage.modules Free Algebra on 3 generators (x, y, z) over Rational Field sage: F = ModularSymbols(11,4).factorization() @@ -551,11 +554,11 @@ def base_change(self, U): possible:: sage: g = x^2 - 1 - sage: F = factor(g); F + sage: F = factor(g); F # optional - sage.libs.pari (x - 1) * (x + 1) - sage: F.universe() + sage: F.universe() # optional - sage.libs.pari Univariate Polynomial Ring in x over Integer Ring - sage: F.base_change(ZZ) + sage: F.base_change(ZZ) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: Impossible to coerce the factors of (x - 1) * (x + 1) into Integer Ring @@ -576,15 +579,15 @@ def is_commutative(self): sage: F = factor(2006) sage: F.is_commutative() True - sage: K = QuadraticField(23, 'a') - sage: F = K.factor(13) - sage: F.is_commutative() + sage: K = QuadraticField(23, 'a') # optional - sage.rings.number_field + sage: F = K.factor(13) # optional - sage.rings.number_field + sage: F.is_commutative() # optional - sage.rings.number_field True - sage: R. = FreeAlgebra(QQ, 3) - sage: F = Factorization([(z, 2)], 3) - sage: F.is_commutative() + sage: R. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: F = Factorization([(z, 2)], 3) # optional - sage.combinat sage.modules + sage: F.is_commutative() # optional - sage.combinat sage.modules False - sage: (F*F^-1).is_commutative() + sage: (F*F^-1).is_commutative() # optional - sage.combinat sage.modules False """ try: @@ -602,14 +605,14 @@ def _set_cr(self, cr): EXAMPLES:: sage: x = polygen(QQ,'x') - sage: F = factor(x^6 - 1); F + sage: F = factor(x^6 - 1); F # optional - sage.libs.pari (x - 1) * (x + 1) * (x^2 - x + 1) * (x^2 + x + 1) - sage: F._set_cr(True); F + sage: F._set_cr(True); F # optional - sage.libs.pari (x - 1) * (x + 1) * (x^2 - x + 1) * (x^2 + x + 1) - sage: F._set_cr(False); F + sage: F._set_cr(False); F # optional - sage.libs.pari (x - 1) * (x + 1) * (x^2 - x + 1) * (x^2 + x + 1) """ self.__cr = bool(cr) @@ -620,12 +623,12 @@ def simplify(self): TESTS:: - sage: R. = FreeAlgebra(ZZ, 2) - sage: F = Factorization([(x,3), (y, 2), (y,2)], simplify=False); F + sage: R. = FreeAlgebra(ZZ, 2) # optional - sage.combinat sage.modules + sage: F = Factorization([(x,3), (y, 2), (y,2)], simplify=False); F # optional - sage.combinat sage.modules x^3 * y^2 * y^2 - sage: F.simplify(); F + sage: F.simplify(); F # optional - sage.combinat sage.modules x^3 * y^4 - sage: F * Factorization([(y, -2)], 2) + sage: F * Factorization([(y, -2)], 2) # optional - sage.combinat sage.modules (2) * x^3 * y^2 """ repeat = False @@ -673,14 +676,14 @@ def sort(self, key=None): We create a factored polynomial:: - sage: x = polygen(QQ,'x') - sage: F = factor(x^3 + 1); F + sage: x = polygen(QQ, 'x') + sage: F = factor(x^3 + 1); F # optional - sage.libs.pari (x + 1) * (x^2 - x + 1) We sort it by decreasing degree:: - sage: F.sort(key=lambda x:(-x[0].degree(), x)) - sage: F + sage: F.sort(key=lambda x: (-x[0].degree(), x)) # optional - sage.libs.pari + sage: F # optional - sage.libs.pari (x^2 - x + 1) * (x + 1) """ if len(self) == 0: @@ -861,7 +864,7 @@ def _latex_(self): -1 \cdot 2^{2} \cdot 5^{2} sage: f._latex_() '-1 \\cdot 2^{2} \\cdot 5^{2}' - sage: x = AA['x'].0; factor(x^2 + x + 1)._latex_() # trac 12178 + sage: x = AA['x'].0; factor(x^2 + x + 1)._latex_() # trac 12178 # optional - sage.rings.number_field '(x^{2} + x + 1.000000000000000?)' """ if len(self) == 0: @@ -898,12 +901,12 @@ def __pari__(self): EXAMPLES:: sage: f = factor(-24) - sage: pari(f) + sage: pari(f) # optional - sage.libs.pari [-1, 1; 2, 3; 3, 1] sage: R. = QQ[] - sage: g = factor(x^10 - 1) - sage: pari(g) + sage: g = factor(x^10 - 1) # optional - sage.libs.pari + sage: pari(g) # optional - sage.libs.pari [x - 1, 1; x + 1, 1; x^4 - x^3 + x^2 - x + 1, 1; x^4 + x^3 + x^2 + x + 1, 1] """ @@ -1003,12 +1006,12 @@ def __rmul__(self, left): -2 * 3 * 5 sage: a * -2 -2 * 3 * 5 - sage: R. = FreeAlgebra(QQ,2) - sage: f = Factorization([(x,2),(y,3)]); f + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules + sage: f = Factorization([(x,2), (y,3)]); f # optional - sage.combinat sage.modules x^2 * y^3 - sage: x * f + sage: x * f # optional - sage.combinat sage.modules x^3 * y^3 - sage: f * x + sage: f * x # optional - sage.combinat sage.modules x^2 * y^3 * x Note that this does not automatically factor ``left``:: @@ -1035,12 +1038,12 @@ def __mul__(self, other): sage: factor(-10) * factor(16) -1 * 2^5 * 5 - sage: R. = FreeAlgebra(ZZ, 2) - sage: F = Factorization([(x,3), (y, 2), (x,1)]); F + sage: R. = FreeAlgebra(ZZ, 2) # optional - sage.combinat sage.modules + sage: F = Factorization([(x,3), (y, 2), (x,1)]); F # optional - sage.combinat sage.modules x^3 * y^2 * x - sage: F*F + sage: F*F # optional - sage.combinat sage.modules x^3 * y^2 * x^4 * y^2 * x - sage: -1 * F + sage: -1 * F # optional - sage.combinat sage.modules (-1) * x^3 * y^2 * x sage: P. = ZZ[] @@ -1097,16 +1100,17 @@ def __pow__(self, n): sage: f^4 2^8 * 5^8 - sage: K. = NumberField(x^3 - 39*x - 91) - sage: F = K.factor(7); F + sage: x = polygen(ZZ, 'x') + sage: K. = NumberField(x^3 - 39*x - 91) # optional - sage.rings.number_field + sage: F = K.factor(7); F # optional - sage.rings.number_field (Fractional ideal (7, a)) * (Fractional ideal (7, a + 2)) * (Fractional ideal (7, a - 2)) - sage: F^9 + sage: F^9 # optional - sage.rings.number_field (Fractional ideal (7, a))^9 * (Fractional ideal (7, a + 2))^9 * (Fractional ideal (7, a - 2))^9 - sage: R. = FreeAlgebra(ZZ, 2) - sage: F = Factorization([(x,3), (y, 2), (x,1)]); F + sage: R. = FreeAlgebra(ZZ, 2) # optional - sage.combinat sage.modules + sage: F = Factorization([(x,3), (y, 2), (x,1)]); F # optional - sage.combinat sage.modules x^3 * y^2 * x - sage: F**2 + sage: F**2 # optional - sage.combinat sage.modules x^3 * y^2 * x^4 * y^2 * x """ from sage.rings.integer import Integer @@ -1138,10 +1142,10 @@ def __invert__(self): sage: F^-1 2^-1 * 17^-1 * 59^-1 - sage: R. = FreeAlgebra(QQ, 2) - sage: F = Factorization([(x,3), (y, 2), (x,1)], 2); F + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules + sage: F = Factorization([(x,3), (y, 2), (x,1)], 2); F # optional - sage.combinat sage.modules (2) * x^3 * y^2 * x - sage: F^-1 + sage: F^-1 # optional - sage.combinat sage.modules (1/2) * x^-1 * y^-2 * x^-3 """ return Factorization([(p,-e) for p,e in reversed(self)], @@ -1159,12 +1163,12 @@ def __truediv__(self, other): sage: factor(-10) / factor(16) -1 * 2^-3 * 5 - sage: R. = FreeAlgebra(QQ, 2) - sage: F = Factorization([(x,3), (y, 2), (x,1)]); F + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules + sage: F = Factorization([(x,3), (y, 2), (x,1)]); F # optional - sage.combinat sage.modules x^3 * y^2 * x - sage: G = Factorization([(y, 1), (x,1)],1); G + sage: G = Factorization([(y, 1), (x,1)],1); G # optional - sage.combinat sage.modules y * x - sage: F / G + sage: F / G # optional - sage.combinat sage.modules x^3 * y """ if not isinstance(other, Factorization): @@ -1182,10 +1186,10 @@ def value(self): sage: F.value() -2006 - sage: R. = FreeAlgebra(ZZ, 2) - sage: F = Factorization([(x,3), (y, 2), (x,1)]); F + sage: R. = FreeAlgebra(ZZ, 2) # optional - sage.combinat sage.modules + sage: F = Factorization([(x,3), (y, 2), (x,1)]); F # optional - sage.combinat sage.modules x^3 * y^2 * x - sage: F.value() + sage: F.value() # optional - sage.combinat sage.modules x^3*y^2*x """ from sage.misc.misc_c import prod @@ -1211,7 +1215,7 @@ def gcd(self, other): 2 * 5 sage: R. = ZZ[] - sage: (factor(-20).gcd(factor(5*x+10))).universe() + sage: (factor(-20).gcd(factor(5*x+10))).universe() # optional - sage.libs.pari Univariate Polynomial Ring in x over Integer Ring """ if not isinstance(other, Factorization): @@ -1253,7 +1257,7 @@ def lcm(self, other): 2^4 * 5 sage: R. = ZZ[] - sage: (factor(-20).lcm(factor(5*x+10))).universe() + sage: (factor(-20).lcm(factor(5*x + 10))).universe() # optional - sage.libs.pari Univariate Polynomial Ring in x over Integer Ring """ if not isinstance(other, Factorization): diff --git a/src/sage/structure/factory.pyx b/src/sage/structure/factory.pyx index a1a28a0da7a..f47f0ea96fa 100644 --- a/src/sage/structure/factory.pyx +++ b/src/sage/structure/factory.pyx @@ -196,7 +196,7 @@ cdef class UniqueFactory(SageObject): :class:`object`. The third allows attribute assignment and is derived from :class:`object`. :: - sage: cython("cdef class C: pass") # optional - sage.misc.cython + sage: cython("cdef class C: pass") # optional - sage.misc.cython sage: class D: ....: def __init__(self, *args): ....: self.t = args @@ -214,7 +214,7 @@ cdef class UniqueFactory(SageObject): It is impossible to create an instance of ``C`` with our factory, since it does not allow weak references:: - sage: F(1, impl='C') # optional - sage.misc.cython + sage: F(1, impl='C') # optional - sage.misc.cython Traceback (most recent call last): ... TypeError: cannot create weak reference to '....C' object @@ -222,14 +222,14 @@ cdef class UniqueFactory(SageObject): Let us try again, with a Cython class that does allow weak references. Now, creation of an instance using the factory works:: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: cdef class C: ....: cdef __weakref__ ....: ''') ....: - sage: c = F(1, impl='C') # optional - sage.misc.cython - sage: isinstance(c, C) # optional - sage.misc.cython + sage: c = F(1, impl='C') # optional - sage.misc.cython + sage: isinstance(c, C) # optional - sage.misc.cython True The cache is used when calling the factory again---even if it is suggested @@ -237,16 +237,16 @@ cdef class UniqueFactory(SageObject): only considered an "extra argument" that does not count for the key. :: - sage: c is F(1, impl='C') is F(1, impl="D") is F(1) # optional - sage.misc.cython + sage: c is F(1, impl='C') is F(1, impl="D") is F(1) # optional - sage.misc.cython True However, pickling and unpickling does not use the cache. This is because the factory has tried to assign an attribute to the instance that provides information on the key used to create the instance, but failed:: - sage: loads(dumps(c)) is c # optional - sage.misc.cython + sage: loads(dumps(c)) is c # optional - sage.misc.cython False - sage: hasattr(c, '_factory_data') # optional - sage.misc.cython + sage: hasattr(c, '_factory_data') # optional - sage.misc.cython False We have already seen that our factory will only take the requested @@ -302,7 +302,7 @@ cdef class UniqueFactory(SageObject): sage: fake_factory = UniqueFactory('ZZ') sage: loads(dumps(fake_factory)) Integer Ring - sage: fake_factory = UniqueFactory('sage.rings.all.QQ') + sage: fake_factory = UniqueFactory('sage.rings.rational_field.QQ') sage: loads(dumps(fake_factory)) Rational Field """ @@ -313,17 +313,17 @@ cdef class UniqueFactory(SageObject): """ EXAMPLES:: - sage: A = FiniteField(127) - sage: A is loads(dumps(A)) # indirect doctest + sage: A = FiniteField(127) # optional - sage.rings.finite_rings + sage: A is loads(dumps(A)) # indirect doctest # optional - sage.rings.finite_rings True - sage: B = FiniteField(3^3,'b') - sage: B is loads(dumps(B)) + sage: B = FiniteField(3^3,'b') # optional - sage.rings.finite_rings + sage: B is loads(dumps(B)) # optional - sage.rings.finite_rings True - sage: C = FiniteField(2^16,'c') - sage: C is loads(dumps(C)) + sage: C = FiniteField(2^16,'c') # optional - sage.rings.finite_rings + sage: C is loads(dumps(C)) # optional - sage.rings.finite_rings True - sage: D = FiniteField(3^20,'d') - sage: D is loads(dumps(D)) + sage: D = FiniteField(3^20,'d') # optional - sage.rings.finite_rings + sage: D is loads(dumps(D)) # optional - sage.rings.finite_rings True TESTS:: @@ -396,10 +396,10 @@ cdef class UniqueFactory(SageObject): Check that :trac:`16317` has been fixed, i.e., caching works for unhashable objects:: - sage: K. = Qq(4) - sage: d = test_factory.get_object(3.0, (K(1), 'c'), {}) # optional - sage.rings.padics + sage: K. = Qq(4) # optional - sage.rings.padics + sage: d = test_factory.get_object(3.0, (K(1), 'c'), {}) # optional - sage.rings.padics Making object (1 + O(2^20), 'c') - sage: d is test_factory.get_object(3.0, (K(1), 'c'), {}) # optional - sage.rings.padics + sage: d is test_factory.get_object(3.0, (K(1), 'c'), {}) # optional - sage.rings.padics True """ @@ -468,7 +468,7 @@ cdef class UniqueFactory(SageObject): sage: from sage.structure.test_factory import test_factory sage: test_factory.create_key_and_extra_args(1, 2, key=5) ((1, 2), {}) - sage: GF.create_key_and_extra_args(3) + sage: GF.create_key_and_extra_args(3) # optional - sage.rings.finite_rings ((3, ('x',), None, 'modn', 3, 1, True, None, None, None, True, False), {}) """ return self.create_key(*args, **kwds), {} @@ -518,15 +518,15 @@ cdef class UniqueFactory(SageObject): The ``GF`` factory used to have a custom :meth:`other_keys` method, but this was removed in :trac:`16934`:: - sage: key, _ = GF.create_key_and_extra_args(27, 'k'); key + sage: key, _ = GF.create_key_and_extra_args(27, 'k'); key # optional - sage.rings.finite_rings (27, ('k',), x^3 + 2*x + 1, 'givaro', 3, 3, True, None, 'poly', True, True, True) - sage: K = GF.create_object(0, key); K + sage: K = GF.create_object(0, key); K # optional - sage.rings.finite_rings Finite Field in k of size 3^3 - sage: GF.other_keys(key, K) + sage: GF.other_keys(key, K) # optional - sage.rings.finite_rings [] - sage: K = GF(7^40, 'a') - sage: loads(dumps(K)) is K + sage: K = GF(7^40, 'a') # optional - sage.rings.finite_rings + sage: loads(dumps(K)) is K # optional - sage.rings.finite_rings True """ return [] @@ -540,12 +540,12 @@ cdef class UniqueFactory(SageObject): EXAMPLES:: - sage: from sage.modules.free_module import FreeModuleFactory_with_standard_basis as F - sage: V = F(ZZ, 5) - sage: factory, data = F.reduce_data(V) - sage: factory(*data) + sage: from sage.modules.free_module import FreeModuleFactory_with_standard_basis as F # optional - sage.modules + sage: V = F(ZZ, 5) # optional - sage.modules + sage: factory, data = F.reduce_data(V) # optional - sage.modules + sage: factory(*data) # optional - sage.modules Ambient free module of rank 5 over the principal ideal domain Integer Ring - sage: factory(*data) is V + sage: factory(*data) is V # optional - sage.modules True sage: from sage.structure.test_factory import test_factory @@ -638,12 +638,12 @@ def generic_factory_unpickle(factory, *args): EXAMPLES:: - sage: from sage.modules.free_module import FreeModuleFactory_with_standard_basis as F - sage: V = F(ZZ, 5) - sage: func, data = F.reduce_data(V) - sage: func is sage.structure.factory.generic_factory_unpickle + sage: from sage.modules.free_module import FreeModuleFactory_with_standard_basis as F # optional - sage.modules + sage: V = F(ZZ, 5) # optional - sage.modules + sage: func, data = F.reduce_data(V) # optional - sage.modules + sage: func is sage.structure.factory.generic_factory_unpickle # optional - sage.modules True - sage: sage.structure.factory.generic_factory_unpickle(*data) is V + sage: sage.structure.factory.generic_factory_unpickle(*data) is V # optional - sage.modules True TESTS: @@ -730,8 +730,8 @@ def generic_factory_reduce(self, proto): EXAMPLES:: - sage: V = QQ^6 - sage: sage.structure.factory.generic_factory_reduce(V, 1) == V.__reduce_ex__(1) + sage: V = QQ^6 # optional - sage.modules + sage: sage.structure.factory.generic_factory_reduce(V, 1) == V.__reduce_ex__(1) # optional - sage.modules True """ if self._factory_data is None: diff --git a/src/sage/structure/formal_sum.py b/src/sage/structure/formal_sum.py index 98178afca79..fc6b0735bae 100644 --- a/src/sage/structure/formal_sum.py +++ b/src/sage/structure/formal_sum.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules """ Formal sums @@ -103,24 +104,24 @@ def __init__(self, x, parent=None, check=True, reduce=True): sage: a.reduce() sage: a 4*2/3 - 5*7 - sage: FormalSum([(1,2/3), (3,2/3), (-5, 7)], parent=FormalSums(GF(5))) + sage: FormalSum([(1, 2/3), (3, 2/3), (-5, 7)], parent=FormalSums(GF(5))) # optional - sage.rings.finite_rings 4*2/3 Notice below that the coefficient 5 doesn't get reduced modulo 5:: - sage: FormalSum([(1,2/3), (3,2/3), (-5, 7)], parent=FormalSums(GF(5)), check=False) + sage: FormalSum([(1,2/3), (3,2/3), (-5, 7)], parent=FormalSums(GF(5)), check=False) # optional - sage.rings.finite_rings 4*2/3 - 5*7 Make sure we first reduce before checking coefficient types:: - sage: x,y = var('x, y') - sage: FormalSum([(1/2,x), (2,y)], FormalSums(QQ)) + sage: x,y = var('x, y') # optional - sage.symbolic + sage: FormalSum([(1/2,x), (2,y)], FormalSums(QQ)) # optional - sage.symbolic 1/2*x + 2*y - sage: FormalSum([(1/2,x), (2,y)], FormalSums(ZZ)) + sage: FormalSum([(1/2,x), (2,y)], FormalSums(ZZ)) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: no conversion of this rational to integer - sage: FormalSum([(1/2,x), (1/2,x), (2,y)], FormalSums(ZZ)) + sage: FormalSum([(1/2,x), (1/2,x), (2,y)], FormalSums(ZZ)) # optional - sage.symbolic x + 2*y """ if x == 0: @@ -309,11 +310,12 @@ class FormalSums(UniqueRepresentation, Module): Abelian Group of all Formal Finite Sums over Integer Ring sage: FormalSums(ZZ) Abelian Group of all Formal Finite Sums over Integer Ring - sage: FormalSums(GF(7)) + sage: FormalSums(GF(7)) # optional - sage.rings.finite_rings Abelian Group of all Formal Finite Sums over Finite Field of size 7 - sage: FormalSums(ZZ[sqrt(2)]) - Abelian Group of all Formal Finite Sums over Order in Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? - sage: FormalSums(GF(9,'a')) + sage: FormalSums(ZZ[sqrt(2)]) # optional - sage.symbolic sage.rings.number_field + Abelian Group of all Formal Finite Sums over Order in Number Field in sqrt2 + with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? + sage: FormalSums(GF(9,'a')) # optional - sage.rings.finite_rings Abelian Group of all Formal Finite Sums over Finite Field in a of size 3^2 TESTS:: @@ -338,9 +340,9 @@ def _repr_(self): """ EXAMPLES:: - sage: FormalSums(GF(7)) + sage: FormalSums(GF(7)) # optional - sage.rings.finite_rings Abelian Group of all Formal Finite Sums over Finite Field of size 7 - sage: FormalSums(GF(7))._repr_() + sage: FormalSums(GF(7))._repr_() # optional - sage.rings.finite_rings 'Abelian Group of all Formal Finite Sums over Finite Field of size 7' """ return "Abelian Group of all Formal Finite Sums over %s"%self.base_ring() @@ -400,12 +402,12 @@ def base_extend(self, R): """ EXAMPLES:: - sage: F7 = FormalSums(ZZ).base_extend(GF(7)); F7 + sage: F7 = FormalSums(ZZ).base_extend(GF(7)); F7 # optional - sage.rings.finite_rings Abelian Group of all Formal Finite Sums over Finite Field of size 7 The following tests against a bug that was fixed at :trac:`18795`:: - sage: isinstance(F7, F7.category().parent_class) + sage: isinstance(F7, F7.category().parent_class) # optional - sage.rings.finite_rings True """ if self.base_ring().has_coerce_map_from(R): @@ -418,7 +420,8 @@ def _get_action_(self, other, op, self_is_left): EXAMPLES:: sage: A = FormalSums(RR); A.get_action(RR) # indirect doctest - Right scalar multiplication by Real Field with 53 bits of precision on Abelian Group of all Formal Finite Sums over Real Field with 53 bits of precision + Right scalar multiplication by Real Field with 53 bits of precision + on Abelian Group of all Formal Finite Sums over Real Field with 53 bits of precision sage: A = FormalSums(ZZ); A.get_action(QQ) Right scalar multiplication by Rational Field on Abelian Group of all Formal Finite Sums over Rational Field diff --git a/src/sage/structure/global_options.py b/src/sage/structure/global_options.py index c97cee38b3f..b202d7e7871 100644 --- a/src/sage/structure/global_options.py +++ b/src/sage/structure/global_options.py @@ -387,7 +387,7 @@ class options(GlobalOptions): Here is an example to test the pickling of a :class:`GlobalOptions` instance:: - sage: TestSuite(Partitions.options).run() + sage: TestSuite(Partitions.options).run() # optional - sage.combinat TESTS: @@ -526,15 +526,15 @@ class Option(): EXAMPLES:: - sage: Partitions.options.display + sage: Partitions.options.display # optional - sage.combinat list - sage: Partitions.options.display='compact' - sage: Partitions.options.display('list') - sage: Partitions.options._reset() + sage: Partitions.options.display = 'compact' # optional - sage.combinat + sage: Partitions.options.display('list') # optional - sage.combinat + sage: Partitions.options._reset() # optional - sage.combinat TESTS:: - sage: TestSuite(Partitions.options.display).run() + sage: TestSuite(Partitions.options.display).run() # optional - sage.combinat """ __name__ = 'Option class' @@ -545,7 +545,7 @@ def __init__(self, options, name): EXAMPLES:: - sage: type(Partitions.options.display) # indirect doctest + sage: type(Partitions.options.display) # indirect doctest # optional - sage.combinat """ self._name = name @@ -559,7 +559,7 @@ def __repr__(self): EXAMPLES:: - sage: Partitions.options.display # indirect doctest + sage: Partitions.options.display # indirect doctest # optional - sage.combinat list """ # NOTE: we intentionally use str() instead of repr() @@ -572,7 +572,7 @@ def __add__(self, other): EXAMPLES:: - sage: Tableaux.options.convention +' is good' + sage: Tableaux.options.convention + ' is good' # optional - sage.combinat 'English is good' """ return self._options[self._name] + other @@ -584,7 +584,7 @@ def __radd__(self, other): EXAMPLES:: - sage: 'Good '+Tableaux.options.convention + sage: 'Good ' + Tableaux.options.convention # optional - sage.combinat 'Good English' """ return other + self._options[self._name] @@ -596,7 +596,7 @@ def __mul__(self, other): EXAMPLES:: - sage: Tableaux.options.convention +' is good' + sage: Tableaux.options.convention + ' is good' # optional - sage.combinat 'English is good' """ return self._options[self._name] * other @@ -608,7 +608,7 @@ def __rmul__(self, other): EXAMPLES:: - sage: 'Good '+Tableaux.options.convention + sage: 'Good ' + Tableaux.options.convention # optional - sage.combinat 'Good English' """ return other * self._options[self._name] @@ -619,14 +619,14 @@ def __bool__(self) -> bool: EXAMPLES:: - sage: RiggedConfigurations.options.half_width_boxes_type_B + sage: RiggedConfigurations.options.half_width_boxes_type_B # optional - sage.combinat True - sage: 'yes' if RiggedConfigurations.options.half_width_boxes_type_B else 'no' + sage: 'yes' if RiggedConfigurations.options.half_width_boxes_type_B else 'no' # optional - sage.combinat 'yes' - sage: RiggedConfigurations.options.half_width_boxes_type_B=False - sage: 'yes' if RiggedConfigurations.options.half_width_boxes_type_B else 'no' + sage: RiggedConfigurations.options.half_width_boxes_type_B = False # optional - sage.combinat + sage: 'yes' if RiggedConfigurations.options.half_width_boxes_type_B else 'no' # optional - sage.combinat 'no' - sage: RiggedConfigurations.options._reset() + sage: RiggedConfigurations.options._reset() # optional - sage.combinat """ return bool(self._options[self._name]) @@ -636,12 +636,12 @@ def __call__(self, *args, **kwds): EXAMPLES:: - sage: Partitions.options.display() # indirect doctest + sage: Partitions.options.display() # indirect doctest # optional - sage.combinat 'list' - sage: Partitions.options.display('exp') # indirect doctest - sage: Partitions.options.display() # indirect doctest + sage: Partitions.options.display('exp') # indirect doctest # optional - sage.combinat + sage: Partitions.options.display() # indirect doctest # optional - sage.combinat 'exp_low' - sage: Partitions.options._reset() + sage: Partitions.options._reset() # optional - sage.combinat TESTS: @@ -696,11 +696,11 @@ def __eq__(self, other): EXAMPLES:: - sage: Tableaux.options.convention + sage: Tableaux.options.convention # optional - sage.combinat English - sage: Tableaux.options.convention == "English" + sage: Tableaux.options.convention == "English" # optional - sage.combinat True - sage: Tableaux.options.convention == "French" + sage: Tableaux.options.convention == "French" # optional - sage.combinat False """ return self._options[self._name] == other @@ -712,11 +712,11 @@ def __ne__(self, other): EXAMPLES:: - sage: Tableaux.options.convention + sage: Tableaux.options.convention # optional - sage.combinat English - sage: Tableaux.options.convention != "English" + sage: Tableaux.options.convention != "English" # optional - sage.combinat False - sage: Tableaux.options.convention != "French" + sage: Tableaux.options.convention != "French" # optional - sage.combinat True """ return self._options[self._name] != other @@ -728,7 +728,7 @@ def __hash__(self): EXAMPLES:: - sage: hash(Tableaux.options.convention) == hash(Tableaux.options('convention')) + sage: hash(Tableaux.options.convention) == hash(Tableaux.options('convention')) # optional - sage.combinat True """ return hash(self._options[self._name]) @@ -740,7 +740,7 @@ def __str__(self): EXAMPLES:: - sage: str(Tableaux.options.convention) + sage: str(Tableaux.options.convention) # optional - sage.combinat 'English' """ return str(self._options[self._name]) @@ -1232,7 +1232,7 @@ def _instancedoc_(self): EXAMPLES:: - sage: print(Partitions.options.__doc__) + sage: print(Partitions.options.__doc__) # optional - sage.combinat Sets and displays the global options for elements of the partition, skew partition, and partition tuple classes. If no parameters are @@ -1273,12 +1273,12 @@ def __setattr__(self, name, value=None): EXAMPLES:: - sage: Partitions.options.display = 'exp' - sage: Partitions.options.dispplay = 'list' + sage: Partitions.options.display = 'exp' # optional - sage.combinat + sage: Partitions.options.dispplay = 'list' # optional - sage.combinat Traceback (most recent call last): ... ValueError: dispplay is not an option for Partitions - sage: Partitions.options._reset() + sage: Partitions.options._reset() # optional - sage.combinat """ # Underscore, and "special", attributes are set using type.__setattr__ if name[0] == '_' or name in ['reset', 'dispatch', 'default_value']: @@ -1298,24 +1298,24 @@ def __setstate__(self, state): EXAMPLES:: - sage: Partitions.options() + sage: Partitions.options() # optional - sage.combinat Current options for Partitions - convention: English - diagram_str: * - display: list - latex: young_diagram - latex_diagram_str: \ast - sage: Partitions.options.convention="French" - sage: pickle = dumps(Partitions.options) - sage: Partitions.options._reset() # reset options - sage: loads(pickle) # indirect doctest + sage: Partitions.options.convention = "French" # optional - sage.combinat + sage: pickle = dumps(Partitions.options) # optional - sage.combinat + sage: Partitions.options._reset() # reset options # optional - sage.combinat + sage: loads(pickle) # indirect doctest # optional - sage.combinat Current options for Partitions - convention: French - diagram_str: * - display: list - latex: young_diagram - latex_diagram_str: \ast - sage: Partitions.options._reset() + sage: Partitions.options._reset() # optional - sage.combinat """ # open the options for the corresponding "parent" and copy all of # the data from its options class into unpickle @@ -1350,8 +1350,8 @@ def __getstate__(self): EXAMPLES:: - sage: Partitions.options._reset() - sage: Partitions.options.__getstate__() + sage: Partitions.options._reset() # optional - sage.combinat + sage: Partitions.options.__getstate__() # optional - sage.combinat {'convention': 'English', 'option_class': 'Partitions', 'options_module': 'sage.combinat.partition'} @@ -1385,9 +1385,9 @@ def __eq__(self, other): EXAMPLES:: - sage: Partitions.options == PartitionsGreatestLE.options # indirect doctest + sage: Partitions.options == PartitionsGreatestLE.options # indirect doctest # optional - sage.combinat True - sage: Partitions.options == Tableaux.options + sage: Partitions.options == Tableaux.options # optional - sage.combinat False """ return isinstance(other, GlobalOptions) and self.__getstate__() == other.__getstate__() diff --git a/src/sage/structure/indexed_generators.py b/src/sage/structure/indexed_generators.py index 4cf80c3522d..5573ff60834 100644 --- a/src/sage/structure/indexed_generators.py +++ b/src/sage/structure/indexed_generators.py @@ -174,8 +174,8 @@ def indices(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) - sage: F.indices() + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules + sage: F.indices() # optional - sage.modules {'a', 'b', 'c'} """ return self._indices @@ -186,14 +186,14 @@ def prefix(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) - sage: F.prefix() + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules + sage: F.prefix() # optional - sage.modules 'B' :: - sage: X = SchubertPolynomialRing(QQ) - sage: X.prefix() + sage: X = SchubertPolynomialRing(QQ) # optional - sage.combinat + sage: X.prefix() # optional - sage.combinat 'X' """ return self._print_options['prefix'] @@ -229,16 +229,16 @@ def print_options(self, **kwds): EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, [1,2,3], prefix='x') - sage: F.print_options() + sage: F = CombinatorialFreeModule(ZZ, [1,2,3], prefix='x') # optional - sage.modules + sage: F.print_options() # optional - sage.modules {...'prefix': 'x'...} - sage: F.print_options(bracket='(') - sage: F.print_options() + sage: F.print_options(bracket='(') # optional - sage.modules + sage: F.print_options() # optional - sage.modules {...'bracket': '('...} TESTS:: - sage: sorted(F.print_options().items()) + sage: sorted(F.print_options().items()) # optional - sage.modules [('bracket', '('), ('iterate_key', False), ('latex_bracket', False), ('latex_names', None), ('latex_prefix', None), ('latex_scalar_mult', None), @@ -247,7 +247,7 @@ def print_options(self, **kwds): ('sorting_key', at ...>), ('sorting_reverse', False), ('string_quotes', True), ('tensor_symbol', None)] - sage: F.print_options(bracket='[') # reset + sage: F.print_options(bracket='[') # reset # optional - sage.modules """ # don't just use kwds.get(...) because I want to distinguish # between an argument like "option=None" and the option not @@ -270,33 +270,33 @@ def _parse_names(self, m, use_latex): EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, [1,2,3], names='a,b,c', + sage: F = CombinatorialFreeModule(ZZ, [1,2,3], names='a,b,c', # optional - sage.modules ....: latex_names='x,y,z') - sage: F._parse_names(1, False) + sage: F._parse_names(1, False) # optional - sage.modules 'a' - sage: F._parse_names(1, True) + sage: F._parse_names(1, True) # optional - sage.modules 'x' - sage: F.print_options(latex_names=None) - sage: F._parse_names(1, True) + sage: F.print_options(latex_names=None) # optional - sage.modules + sage: F._parse_names(1, True) # optional - sage.modules 'a' - sage: F.print_options(latex_names={1:'x', 2:'y'}, names=None) - sage: F._parse_names(1, False) is None + sage: F.print_options(latex_names={1:'x', 2:'y'}, names=None) # optional - sage.modules + sage: F._parse_names(1, False) is None # optional - sage.modules True - sage: F._parse_names(1, True) + sage: F._parse_names(1, True) # optional - sage.modules 'x' - sage: F._parse_names(3, True) is None + sage: F._parse_names(3, True) is None # optional - sage.modules True - sage: F.print_options(names={1:'a', 3:'c'}, latex_names=None) - sage: F._parse_names(1, False) + sage: F.print_options(names={1:'a', 3:'c'}, latex_names=None) # optional - sage.modules + sage: F._parse_names(1, False) # optional - sage.modules 'a' - sage: F._parse_names(1, True) + sage: F._parse_names(1, True) # optional - sage.modules 'a' - sage: F._parse_names(2, False) is None + sage: F._parse_names(2, False) is None # optional - sage.modules True - sage: F._parse_names(2, True) is None + sage: F._parse_names(2, True) is None # optional - sage.modules True """ names = self._print_options.get('names', None) @@ -349,69 +349,69 @@ def _repr_generator(self, m): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) - sage: e = F.basis() - sage: e['a'] + 2*e['b'] # indirect doctest + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: e['a'] + 2*e['b'] # indirect doctest # optional - sage.modules B['a'] + 2*B['b'] - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix="F") - sage: e = F.basis() - sage: e['a'] + 2*e['b'] # indirect doctest + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix="F") # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: e['a'] + 2*e['b'] # indirect doctest # optional - sage.modules F['a'] + 2*F['b'] - sage: F.print_options(string_quotes=False) - sage: e['a'] + 2*e['b'] + sage: F.print_options(string_quotes=False) # optional - sage.modules + sage: e['a'] + 2*e['b'] # optional - sage.modules F[a] + 2*F[b] - sage: F = CombinatorialFreeModule(QQ, ['aa', 'bb', 'cc'], prefix="F") - sage: e = F.basis() - sage: F.print_options(iterate_key=True) - sage: e['aa'] + 2*e['bb'] + sage: F = CombinatorialFreeModule(QQ, ['aa', 'bb', 'cc'], prefix="F") # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: F.print_options(iterate_key=True) # optional - sage.modules + sage: e['aa'] + 2*e['bb'] # optional - sage.modules F['a', 'a'] + 2*F['b', 'b'] - sage: F.print_options(string_quotes=False) - sage: e['aa'] + 2*e['bb'] + sage: F.print_options(string_quotes=False) # optional - sage.modules + sage: e['aa'] + 2*e['bb'] # optional - sage.modules F[a, a] + 2*F[b, b] - sage: QS3 = CombinatorialFreeModule(QQ, Permutations(3), prefix="") - sage: original_print_options = QS3.print_options() - sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) - sage: a # indirect doctest + sage: QS3 = CombinatorialFreeModule(QQ, Permutations(3), prefix="") # optional - sage.combinat sage.modules + sage: original_print_options = QS3.print_options() # optional - sage.combinat sage.modules + sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) # optional - sage.combinat sage.modules + sage: a # indirect doctest # optional - sage.combinat sage.modules 2*[[1, 2, 3]] + 4*[[3, 2, 1]] - sage: QS3.print_options(bracket = False) - sage: a # indirect doctest + sage: QS3.print_options(bracket = False) # optional - sage.combinat sage.modules + sage: a # indirect doctest # optional - sage.combinat sage.modules 2*[1, 2, 3] + 4*[3, 2, 1] - sage: QS3.print_options(prefix='') - sage: a # indirect doctest + sage: QS3.print_options(prefix='') # optional - sage.combinat sage.modules + sage: a # indirect doctest # optional - sage.combinat sage.modules 2*[1, 2, 3] + 4*[3, 2, 1] - sage: QS3.print_options(bracket="|", scalar_mult=" *@* ") - sage: a # indirect doctest + sage: QS3.print_options(bracket="|", scalar_mult=" *@* ") # optional - sage.combinat sage.modules + sage: a # indirect doctest # optional - sage.combinat sage.modules 2 *@* |[1, 2, 3]| + 4 *@* |[3, 2, 1]| - sage: QS3.print_options(bracket="|", scalar_mult="*", iterate_key=True) - sage: a # indirect doctest + sage: QS3.print_options(bracket="|", scalar_mult="*", iterate_key=True) # optional - sage.combinat sage.modules + sage: a # indirect doctest # optional - sage.combinat sage.modules 2*|1, 2, 3| + 4*|3, 2, 1| - sage: QS3.print_options(**original_print_options) # reset + sage: QS3.print_options(**original_print_options) # reset # optional - sage.combinat sage.modules TESTS:: - sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), ('c','d')]) - sage: e = F.basis() - sage: e[('a','b')] + 2*e[('c','d')] # indirect doctest + sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), ('c','d')]) # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: e[('a','b')] + 2*e[('c','d')] # indirect doctest # optional - sage.modules B[('a', 'b')] + 2*B[('c', 'd')] - sage: F. = CombinatorialFreeModule(QQ) - sage: a + 2*b + sage: F. = CombinatorialFreeModule(QQ) # optional - sage.modules + sage: a + 2*b # optional - sage.modules a + 2*b - sage: F = CombinatorialFreeModule(QQ, ZZ) - sage: e = F.basis() - sage: 3*e[1] + 2*e[-2] + sage: F = CombinatorialFreeModule(QQ, ZZ) # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: 3*e[1] + 2*e[-2] # optional - sage.modules 2*B[-2] + 3*B[1] - sage: F.print_options(iterate_key=True) - sage: 3*e[1] + 2*e[-2] + sage: F.print_options(iterate_key=True) # optional - sage.modules + sage: 3*e[1] + 2*e[-2] # optional - sage.modules 2*B[-2] + 3*B[1] """ ret = self._parse_names(m, False) @@ -457,24 +457,24 @@ def _ascii_art_generator(self, m): TESTS:: - sage: R = NonCommutativeSymmetricFunctions(QQ).R() - sage: ascii_art(R[1,2,2,4]) + sage: R = NonCommutativeSymmetricFunctions(QQ).R() # optional - sage.combinat + sage: ascii_art(R[1,2,2,4]) # optional - sage.combinat R **** ** ** * - sage: Partitions.options(diagram_str="#", convention="french") - sage: ascii_art(R[1,2,2,4]) + sage: Partitions.options(diagram_str="#", convention="french") # optional - sage.combinat + sage: ascii_art(R[1,2,2,4]) # optional - sage.combinat R # ## ## #### - sage: Partitions.options._reset() + sage: Partitions.options._reset() # optional - sage.combinat - sage: F. = CombinatorialFreeModule(QQ) - sage: ascii_art(a + 2*b) + sage: F. = CombinatorialFreeModule(QQ) # optional - sage.modules + sage: ascii_art(a + 2*b) # optional - sage.modules a + 2*b """ from sage.typeset.ascii_art import AsciiArt, ascii_art @@ -493,26 +493,26 @@ def _unicode_art_generator(self, m): TESTS:: - sage: R = NonCommutativeSymmetricFunctions(QQ).R() - sage: unicode_art(R[1,2,2,4]) + sage: R = NonCommutativeSymmetricFunctions(QQ).R() # optional - sage.combinat + sage: unicode_art(R[1,2,2,4]) # optional - sage.combinat R ┌┬┬┬┐ ┌┼┼┴┴┘ ┌┼┼┘ ├┼┘ └┘ - sage: Partitions.options.convention="french" - sage: unicode_art(R[1,2,2,4]) + sage: Partitions.options.convention="french" # optional - sage.combinat + sage: unicode_art(R[1,2,2,4]) # optional - sage.combinat R ┌┐ ├┼┐ └┼┼┐ └┼┼┬┬┐ └┴┴┴┘ - sage: Partitions.options._reset() + sage: Partitions.options._reset() # optional - sage.combinat - sage: F. = CombinatorialFreeModule(QQ) - sage: unicode_art(a + 2*b) + sage: F. = CombinatorialFreeModule(QQ) # optional - sage.modules + sage: unicode_art(a + 2*b) # optional - sage.modules a + 2*b """ from sage.typeset.unicode_art import UnicodeArt, unicode_art @@ -546,47 +546,49 @@ def _latex_generator(self, m): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) - sage: e = F.basis() - sage: latex(e['a'] + 2*e['b']) # indirect doctest + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: latex(e['a'] + 2*e['b']) # indirect doctest # optional - sage.modules B_{a} + 2 B_{b} - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix="C") - sage: e = F.basis() - sage: latex(e['a'] + 2*e['b']) # indirect doctest + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix="C") # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: latex(e['a'] + 2*e['b']) # indirect doctest # optional - sage.modules C_{a} + 2 C_{b} - sage: QS3 = CombinatorialFreeModule(QQ, Permutations(3), prefix="", scalar_mult="*") - sage: original_print_options = QS3.print_options() - sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) - sage: latex(a) # indirect doctest + sage: QS3 = CombinatorialFreeModule(QQ, Permutations(3), # optional - sage.combinat sage.modules + ....: prefix="", scalar_mult="*") + sage: original_print_options = QS3.print_options() # optional - sage.combinat sage.modules + sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) # optional - sage.combinat sage.modules + sage: latex(a) # indirect doctest # optional - sage.combinat sage.modules 2 [1, 2, 3] + 4 [3, 2, 1] - sage: QS3.print_options(latex_bracket=True) - sage: latex(a) # indirect doctest + sage: QS3.print_options(latex_bracket=True) # optional - sage.combinat sage.modules + sage: latex(a) # indirect doctest # optional - sage.combinat sage.modules 2 \left[ [1, 2, 3] \right] + 4 \left[ [3, 2, 1] \right] - sage: QS3.print_options(latex_bracket="(") - sage: latex(a) # indirect doctest + sage: QS3.print_options(latex_bracket="(") # optional - sage.combinat sage.modules + sage: latex(a) # indirect doctest # optional - sage.combinat sage.modules 2 \left( [1, 2, 3] \right) + 4 \left( [3, 2, 1] \right) - sage: QS3.print_options(latex_bracket=('\\myleftbracket', '\\myrightbracket')) - sage: latex(a) # indirect doctest + sage: QS3.print_options(latex_bracket=('\\myleftbracket', # optional - sage.combinat sage.modules + ....: '\\myrightbracket')) + sage: latex(a) # indirect doctest # optional - sage.combinat sage.modules 2 \myleftbracket [1, 2, 3] \myrightbracket + 4 \myleftbracket [3, 2, 1] \myrightbracket - sage: QS3.print_options(**original_print_options) # reset + sage: QS3.print_options(**original_print_options) # reset # optional - sage.combinat sage.modules TESTS:: - sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), (0,1,2)]) - sage: e = F.basis() - sage: latex(e[('a','b')]) # indirect doctest + sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), (0,1,2)]) # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: latex(e[('a','b')]) # indirect doctest # optional - sage.modules B_{('a', 'b')} - sage: latex(2*e[(0,1,2)]) # indirect doctest + sage: latex(2*e[(0,1,2)]) # indirect doctest # optional - sage.modules 2 B_{\left(0, 1, 2\right)} - sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), (0,1,2)], prefix="") - sage: e = F.basis() - sage: latex(2*e[(0,1,2)]) # indirect doctest + sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), (0,1,2)], prefix="") # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: latex(2*e[(0,1,2)]) # indirect doctest # optional - sage.modules 2 \left(0, 1, 2\right) - sage: F. = CombinatorialFreeModule(QQ, latex_names='x,y,z') - sage: latex(a + 2*b) + sage: F. = CombinatorialFreeModule(QQ, latex_names='x,y,z') # optional - sage.modules + sage: latex(a + 2*b) # optional - sage.modules x + 2 y """ from sage.misc.latex import latex diff --git a/src/sage/structure/nonexact.py b/src/sage/structure/nonexact.py index 4157295be90..f5894af43ac 100644 --- a/src/sage/structure/nonexact.py +++ b/src/sage/structure/nonexact.py @@ -9,7 +9,7 @@ sage: R. = PowerSeriesRing(QQ) sage: R.default_prec() 20 - sage: cos(x) + sage: cos(x) # optional - sage.symbolic 1 - 1/2*x^2 + 1/24*x^4 - 1/720*x^6 + 1/40320*x^8 - 1/3628800*x^10 + 1/479001600*x^12 - 1/87178291200*x^14 + 1/20922789888000*x^16 - 1/6402373705728000*x^18 + O(x^20) @@ -50,6 +50,7 @@ def default_prec(self): EXAMPLES:: + sage: x = polygen(ZZ, 'x') sage: R = QQ[[x]] sage: R.default_prec() 20 diff --git a/src/sage/structure/parent.pyx b/src/sage/structure/parent.pyx index 25c4157c3df..d3aa238e01f 100644 --- a/src/sage/structure/parent.pyx +++ b/src/sage/structure/parent.pyx @@ -86,7 +86,7 @@ TESTS: This came up in some subtle bug once:: - sage: gp(2) + gap(3) + sage: gp(2) + gap(3) # optional - sage.libs.pari 5 """ # **************************************************************************** @@ -362,16 +362,22 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: sage: P. = QQ[] - sage: Q = P.quotient(x^2+2) + sage: Q = P.quotient(x^2 + 2) sage: Q.category() - Join of Category of commutative rings and Category of subquotients of monoids and Category of quotients of semigroups + Join of + Category of commutative rings and + Category of subquotients of monoids and + Category of quotients of semigroups sage: first_class = Q.__class__ sage: Q._refine_category_(Fields()) sage: Q.category() - Join of Category of fields and Category of subquotients of monoids and Category of quotients of semigroups + Join of + Category of fields and + Category of subquotients of monoids and + Category of quotients of semigroups sage: first_class == Q.__class__ False - sage: TestSuite(Q).run() + sage: TestSuite(Q).run() # optional - sage.libs.singular TESTS: @@ -585,8 +591,8 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: k = GF(5) - sage: k._set_element_constructor() + sage: k = GF(5) # optional - sage.rings.finite_rings + sage: k._set_element_constructor() # optional - sage.rings.finite_rings """ try: _element_constructor_ = self._element_constructor_ @@ -824,7 +830,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: ZZ._repr_option('ascii_art') False - sage: MatrixSpace(ZZ, 2)._repr_option('element_ascii_art') + sage: MatrixSpace(ZZ, 2)._repr_option('element_ascii_art') # optional - sage.modules True """ if not isinstance(key, basestring): @@ -910,36 +916,36 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: MS = MatrixSpace(QQ,2,2) + sage: MS = MatrixSpace(QQ, 2, 2) # optional - sage.modules This matrix space is in fact an algebra, and in particular it is a ring, from the point of view of categories:: - sage: MS.category() + sage: MS.category() # optional - sage.modules Category of infinite finite dimensional algebras with basis over (number fields and quotient fields and metric spaces) - sage: MS in Rings() + sage: MS in Rings() # optional - sage.modules True However, its class does not inherit from the base class ``Ring``:: - sage: isinstance(MS,Ring) + sage: isinstance(MS, Ring) # optional - sage.modules False Its ``_mul_`` method is inherited from the category, and can be used to create a left or right ideal:: - sage: MS._mul_.__module__ + sage: MS._mul_.__module__ # optional - sage.modules 'sage.categories.rings' - sage: MS*MS.1 # indirect doctest + sage: MS * MS.1 # indirect doctest # optional - sage.modules Left Ideal ( [0 1] [0 0] ) of Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: MS*[MS.1,2] + sage: MS * [MS.1, 2] # optional - sage.modules Left Ideal ( [0 1] @@ -949,14 +955,14 @@ cdef class Parent(sage.structure.category_object.CategoryObject): [0 2] ) of Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: MS.1*MS + sage: MS.1 * MS # optional - sage.modules Right Ideal ( [0 1] [0 0] ) of Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: [MS.1,2]*MS + sage: [MS.1, 2] * MS # optional - sage.modules Right Ideal ( [0 1] @@ -1005,22 +1011,22 @@ cdef class Parent(sage.structure.category_object.CategoryObject): TESTS:: - sage: ZZ^3 + sage: ZZ^3 # optional - sage.modules Ambient free module of rank 3 over the principal ideal domain Integer Ring - sage: QQ^3 + sage: QQ^3 # optional - sage.modules Vector space of dimension 3 over Rational Field - sage: QQ[x]^3 + sage: QQ['x']^3 # optional - sage.modules Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - sage: IntegerModRing(6)^3 + sage: IntegerModRing(6)^3 # optional - sage.modules Ambient free module of rank 3 over Ring of integers modulo 6 sage: 3^ZZ Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for ^: 'Integer Ring' and '' - sage: Partitions(3)^3 + sage: Partitions(3)^3 # optional - sage.combinat sage.modules Traceback (most recent call last): ... TypeError: unsupported operand type(s) for ** or pow(): 'Partitions_n_with_category' and 'int' @@ -1130,9 +1136,9 @@ cdef class Parent(sage.structure.category_object.CategoryObject): Check that :trac:`13824` is fixed:: - sage: 4/3 in GF(3) + sage: 4/3 in GF(3) # optional - sage.rings.finite_rings False - sage: 15/50 in GF(25, 'a') + sage: 15/50 in GF(25, 'a') # optional - sage.rings.finite_rings False sage: 7/4 in Integers(4) False @@ -1195,8 +1201,8 @@ cdef class Parent(sage.structure.category_object.CategoryObject): We make an exception for zero:: - sage: V = GF(7)^7 - sage: V.coerce(0) + sage: V = GF(7)^7 # optional - sage.rings.finite_rings + sage: V.coerce(0) # optional - sage.rings.finite_rings (0, 0, 0, 0, 0, 0, 0) """ cdef R = parent(x) @@ -1234,7 +1240,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: VectorSpace(GF(7), 3)[:10] + sage: VectorSpace(GF(7), 3)[:10] # optional - sage.rings.finite_rings [(0, 0, 0), (1, 0, 0), (2, 0, 0), @@ -1371,29 +1377,30 @@ cdef class Parent(sage.structure.category_object.CategoryObject): 6 sage: R. = PolynomialRing(QQ) - sage: f = R.hom([5], GF(7)) + sage: f = R.hom([5], GF(7)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: relations do not all (canonically) map to 0 under map determined by images of generators + ValueError: relations do not all (canonically) map to 0 + under map determined by images of generators - sage: R. = PolynomialRing(GF(7)) - sage: f = R.hom([3], GF(49,'a')) - sage: f + sage: R. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings + sage: f = R.hom([3], GF(49,'a')) # optional - sage.rings.finite_rings + sage: f # optional - sage.rings.finite_rings Ring morphism: From: Univariate Polynomial Ring in x over Finite Field of size 7 To: Finite Field in a of size 7^2 Defn: x |--> 3 - sage: f(x+6) + sage: f(x + 6) # optional - sage.rings.finite_rings 2 - sage: f(x^2+1) + sage: f(x^2 + 1) # optional - sage.rings.finite_rings 3 Natural morphism:: - sage: f = ZZ.hom(GF(5)) - sage: f(7) + sage: f = ZZ.hom(GF(5)) # optional - sage.rings.finite_rings + sage: f(7) # optional - sage.rings.finite_rings 2 - sage: f + sage: f # optional - sage.rings.finite_rings Natural morphism: From: Integer Ring To: Finite Field of size 5 @@ -1678,30 +1685,30 @@ cdef class Parent(sage.structure.category_object.CategoryObject): ....: return a.parent()(D) sage: R. = QQ['x, y, z'] - sage: G = SymmetricGroup(3) - sage: act = SymmetricGroupAction(G, R) + sage: G = SymmetricGroup(3) # optional - sage.groups + sage: act = SymmetricGroupAction(G, R) # optional - sage.groups sage: t = x + 2*y + 3*z - sage: act(G((1, 2)), t) + sage: act(G((1, 2)), t) # optional - sage.groups 2*x + y + 3*z - sage: act(G((2, 3)), t) + sage: act(G((2, 3)), t) # optional - sage.groups x + 3*y + 2*z - sage: act(G((1, 2, 3)), t) + sage: act(G((1, 2, 3)), t) # optional - sage.groups 3*x + y + 2*z This should fail, since we have not registered the left action:: - sage: G((1,2)) * t + sage: G((1,2)) * t # optional - sage.groups Traceback (most recent call last): ... TypeError: ... Now let's make it work:: - sage: R._unset_coercions_used() - sage: R.register_action(act) - sage: G((1, 2)) * t + sage: R._unset_coercions_used() # optional - sage.groups + sage: R.register_action(act) # optional - sage.groups + sage: G((1, 2)) * t # optional - sage.groups 2*x + y + 3*z """ if self._coercions_used: @@ -1762,35 +1769,35 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: S3 = AlternatingGroup(3) - sage: G = SL(3, QQ) - sage: p = S3[2]; p.matrix() + sage: S3 = AlternatingGroup(3) # optional - sage.groups + sage: G = SL(3, QQ) # optional - sage.groups + sage: p = S3[2]; p.matrix() # optional - sage.groups [0 0 1] [1 0 0] [0 1 0] In general one cannot mix matrices and permutations:: - sage: G(p) + sage: G(p) # optional - sage.groups Traceback (most recent call last): ... TypeError: unable to convert (1,3,2) to a rational - sage: phi = S3.hom(lambda p: G(p.matrix()), codomain = G) - sage: phi(p) + sage: phi = S3.hom(lambda p: G(p.matrix()), codomain=G) # optional - sage.groups + sage: phi(p) # optional - sage.groups [0 0 1] [1 0 0] [0 1 0] - sage: S3._unset_coercions_used() - sage: S3.register_embedding(phi) + sage: S3._unset_coercions_used() # optional - sage.groups + sage: S3.register_embedding(phi) # optional - sage.groups By :trac:`14711`, coerce maps should be copied when using outside of the coercion system:: - sage: phi = copy(S3.coerce_embedding()); phi + sage: phi = copy(S3.coerce_embedding()); phi # optional - sage.groups Generic morphism: From: Alternating group of order 3!/2 as a permutation group To: Special Linear Group of degree 3 over Rational Field - sage: phi(p) + sage: phi(p) # optional - sage.groups [0 0 1] [1 0 0] [0 1 0] @@ -1798,11 +1805,11 @@ cdef class Parent(sage.structure.category_object.CategoryObject): This does not work since matrix groups are still old-style parents (see :trac:`14014`):: - sage: G(p) # todo: not implemented + sage: G(p) # todo: not implemented # optional - sage.groups Though one can have a permutation act on the rows of a matrix:: - sage: G(1) * p + sage: G(1) * p # optional - sage.groups [0 0 1] [1 0 0] [0 1 0] @@ -1811,29 +1818,30 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: x = QQ['x'].0 sage: t = abs(ZZ.random_element(10^6)) - sage: K = NumberField(x^2 + 2*3*7*11, "a"+str(t)) - sage: a = K.gen() - sage: K_into_MS = K.hom([a.matrix()]) - sage: K._unset_coercions_used() - sage: K.register_embedding(K_into_MS) - - sage: L = NumberField(x^2 + 2*3*7*11*19*31, "b"+str(abs(ZZ.random_element(10^6)))) - sage: b = L.gen() - sage: L_into_MS = L.hom([b.matrix()]) - sage: L._unset_coercions_used() - sage: L.register_embedding(L_into_MS) - - sage: K.coerce_embedding()(a) + sage: K = NumberField(x^2 + 2*3*7*11, "a"+str(t)) # optional - sage.rings.number_field + sage: a = K.gen() # optional - sage.rings.number_field + sage: K_into_MS = K.hom([a.matrix()]) # optional - sage.rings.number_field + sage: K._unset_coercions_used() # optional - sage.rings.number_field + sage: K.register_embedding(K_into_MS) # optional - sage.rings.number_field + + sage: L = NumberField(x^2 + 2*3*7*11*19*31, # optional - sage.rings.number_field + ....: "b" + str(abs(ZZ.random_element(10^6)))) + sage: b = L.gen() # optional - sage.rings.number_field + sage: L_into_MS = L.hom([b.matrix()]) # optional - sage.rings.number_field + sage: L._unset_coercions_used() # optional - sage.rings.number_field + sage: L.register_embedding(L_into_MS) # optional - sage.rings.number_field + + sage: K.coerce_embedding()(a) # optional - sage.rings.number_field [ 0 1] [-462 0] - sage: L.coerce_embedding()(b) + sage: L.coerce_embedding()(b) # optional - sage.rings.number_field [ 0 1] [-272118 0] - sage: a.matrix() * b.matrix() + sage: a.matrix() * b.matrix() # optional - sage.rings.number_field [-272118 0] [ 0 -462] - sage: a.matrix() * b.matrix() + sage: a.matrix() * b.matrix() # optional - sage.rings.number_field [-272118 0] [ 0 -462] """ @@ -1862,16 +1870,18 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: K.=NumberField(x^3+x^2+1,embedding=1) - sage: K.coerce_embedding() + sage: K. = NumberField(x^3 + x^2 + 1, embedding=1) # optional - sage.rings.number_field + sage: K.coerce_embedding() # optional - sage.rings.number_field Generic morphism: - From: Number Field in a with defining polynomial x^3 + x^2 + 1 with a = -1.465571231876768? + From: Number Field in a with defining polynomial x^3 + x^2 + 1 + with a = -1.465571231876768? To: Real Lazy Field Defn: a -> -1.465571231876768? - sage: K.=NumberField(x^3+x^2+1,embedding=CC.gen()) - sage: K.coerce_embedding() + sage: K. = NumberField(x^3 + x^2 + 1, embedding=CC.gen()) # optional - sage.rings.number_field + sage: K.coerce_embedding() # optional - sage.rings.number_field Generic morphism: - From: Number Field in a with defining polynomial x^3 + x^2 + 1 with a = 0.2327856159383841? + 0.7925519925154479?*I + From: Number Field in a with defining polynomial x^3 + x^2 + 1 + with a = 0.2327856159383841? + 0.7925519925154479?*I To: Complex Lazy Field Defn: a -> 0.2327856159383841? + 0.7925519925154479?*I """ @@ -1922,11 +1932,11 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: QQ['x']._generic_convert_map(SR) + sage: QQ['x']._generic_convert_map(SR) # optional - sage.symbolic Conversion via _polynomial_ method map: From: Symbolic Ring To: Univariate Polynomial Ring in x over Rational Field - sage: GF(11)._generic_convert_map(GF(7)) + sage: GF(11)._generic_convert_map(GF(7)) # optional - sage.rings.finite_rings Conversion map: From: Finite Field of size 7 To: Finite Field of size 11 @@ -2098,13 +2108,13 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: import gc sage: _ = gc.collect() - sage: K = GF(1<<55,'t') - sage: for i in range(50): + sage: K = GF(1<<55,'t') # optional - sage.rings.finite_rings + sage: for i in range(50): # optional - sage.rings.finite_rings ....: a = K.random_element() ....: E = EllipticCurve(j=a) ....: b = K.has_coerce_map_from(E) - sage: _ = gc.collect() - sage: len([x for x in gc.get_objects() if isinstance(x,type(E))]) + sage: _ = gc.collect() # optional - sage.rings.finite_rings + sage: len([x for x in gc.get_objects() if isinstance(x, type(E))]) # optional - sage.rings.finite_rings 1 TESTS: @@ -2112,12 +2122,12 @@ cdef class Parent(sage.structure.category_object.CategoryObject): The following was fixed in :trac:`12969`:: sage: R = QQ['q,t'].fraction_field() - sage: Sym = sage.combinat.sf.sf.SymmetricFunctions(R) - sage: H = Sym.macdonald().H() - sage: P = Sym.macdonald().P() - sage: m = Sym.monomial() - sage: Ht = Sym.macdonald().Ht() - sage: phi = m.coerce_map_from(P) + sage: Sym = sage.combinat.sf.sf.SymmetricFunctions(R) # optional - sage.combinat + sage: H = Sym.macdonald().H() # optional - sage.combinat + sage: P = Sym.macdonald().P() # optional - sage.combinat + sage: m = Sym.monomial() # optional - sage.combinat + sage: Ht = Sym.macdonald().Ht() # optional - sage.combinat + sage: phi = m.coerce_map_from(P) # optional - sage.combinat """ return copy(self._internal_coerce_map_from(S)) @@ -2148,15 +2158,15 @@ cdef class Parent(sage.structure.category_object.CategoryObject): To: Rational Field sage: R = QQ['q,t'].fraction_field() - sage: Sym = sage.combinat.sf.sf.SymmetricFunctions(R) - sage: P = Sym.macdonald().P() - sage: Ht = Sym.macdonald().Ht() - sage: Ht._internal_coerce_map_from(P) + sage: Sym = sage.combinat.sf.sf.SymmetricFunctions(R) # optional - sage.combinat + sage: P = Sym.macdonald().P() # optional - sage.combinat + sage: Ht = Sym.macdonald().Ht() # optional - sage.combinat + sage: Ht._internal_coerce_map_from(P) # optional - sage.combinat (map internal to coercion system -- copy before use) Composite map: From: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald P basis To: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald Ht basis - sage: copy(Ht._internal_coerce_map_from(P)) + sage: copy(Ht._internal_coerce_map_from(P)) # optional - sage.combinat Composite map: From: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald P basis To: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald Ht basis @@ -2174,8 +2184,8 @@ cdef class Parent(sage.structure.category_object.CategoryObject): The following was fixed in :trac:`4740`:: - sage: F = GF(13) - sage: F._internal_coerce_map_from(F) is F._internal_coerce_map_from(F) + sage: F = GF(13) # optional - sage.rings.finite_rings + sage: F._internal_coerce_map_from(F) is F._internal_coerce_map_from(F) # optional - sage.rings.finite_rings True """ if not good_as_coerce_domain(S): @@ -2285,18 +2295,18 @@ cdef class Parent(sage.structure.category_object.CategoryObject): Another test:: - sage: K = NumberField([x^2-2, x^2-3], 'a,b') - sage: M = K.absolute_field('c') - sage: M_to_K, K_to_M = M.structure() - sage: M.register_coercion(K_to_M) - sage: K.register_coercion(M_to_K) - sage: phi = M.coerce_map_from(QQ) - sage: p = QQ.random_element() - sage: c = phi(p) - p; c + sage: K = NumberField([x^2 - 2, x^2 - 3], 'a,b') # optional - sage.rings.number_field + sage: M = K.absolute_field('c') # optional - sage.rings.number_field + sage: M_to_K, K_to_M = M.structure() # optional - sage.rings.number_field + sage: M.register_coercion(K_to_M) # optional - sage.rings.number_field + sage: K.register_coercion(M_to_K) # optional - sage.rings.number_field + sage: phi = M.coerce_map_from(QQ) # optional - sage.rings.number_field + sage: p = QQ.random_element() # optional - sage.rings.number_field + sage: c = phi(p) - p; c # optional - sage.rings.number_field 0 - sage: c.parent() is M + sage: c.parent() is M # optional - sage.rings.number_field True - sage: K.coerce_map_from(QQ) + sage: K.coerce_map_from(QQ) # optional - sage.rings.number_field Coercion map: From: Rational Field To: Number Field in a with defining polynomial x^2 - 2 over its base field @@ -2318,16 +2328,18 @@ cdef class Parent(sage.structure.category_object.CategoryObject): Check that :trac:`14982` is fixed, and more generally that we discover sensible coercion paths in the presence of embeddings:: - sage: K. = NumberField(x^2+1/2, embedding=CC(0,1)) - sage: L = NumberField(x^2+2, 'b', embedding=1/a) - sage: PolynomialRing(L, 'x').coerce_map_from(L) + sage: K. = NumberField(x^2 + 1/2, embedding=CC(0, 1)) # optional - sage.rings.number_field + sage: L = NumberField(x^2 + 2, 'b', embedding=1/a) # optional - sage.rings.number_field + sage: PolynomialRing(L, 'x').coerce_map_from(L) # optional - sage.rings.number_field Polynomial base injection morphism: From: Number Field in b with defining polynomial x^2 + 2 with b = -2*a - To: Univariate Polynomial Ring in x over Number Field in b with defining polynomial x^2 + 2 with b = -2*a - sage: PolynomialRing(K, 'x').coerce_map_from(L) + To: Univariate Polynomial Ring in x over Number Field in b + with defining polynomial x^2 + 2 with b = -2*a + sage: PolynomialRing(K, 'x').coerce_map_from(L) # optional - sage.rings.number_field Composite map: From: Number Field in b with defining polynomial x^2 + 2 with b = -2*a - To: Univariate Polynomial Ring in x over Number Field in a with defining polynomial x^2 + 1/2 with a = 0.7071067811865475?*I + To: Univariate Polynomial Ring in x over Number Field in a + with defining polynomial x^2 + 1/2 with a = 0.7071067811865475?*I Defn: Generic morphism: From: Number Field in b with defining polynomial x^2 + 2 with b = -2*a To: Number Field in a with defining polynomial x^2 + 1/2 with a = 0.7071067811865475?*I @@ -2335,15 +2347,18 @@ cdef class Parent(sage.structure.category_object.CategoryObject): then Polynomial base injection morphism: From: Number Field in a with defining polynomial x^2 + 1/2 with a = 0.7071067811865475?*I - To: Univariate Polynomial Ring in x over Number Field in a with defining polynomial x^2 + 1/2 with a = 0.7071067811865475?*I - sage: MatrixSpace(L, 2, 2).coerce_map_from(L) + To: Univariate Polynomial Ring in x over Number Field in a + with defining polynomial x^2 + 1/2 with a = 0.7071067811865475?*I + sage: MatrixSpace(L, 2, 2).coerce_map_from(L) # optional - sage.rings.number_field Coercion map: From: Number Field in b with defining polynomial x^2 + 2 with b = -2*a - To: Full MatrixSpace of 2 by 2 dense matrices over Number Field in b with defining polynomial x^2 + 2 with b = -2*a - sage: PowerSeriesRing(L, 'x').coerce_map_from(L) + To: Full MatrixSpace of 2 by 2 dense matrices over Number Field in b + with defining polynomial x^2 + 2 with b = -2*a + sage: PowerSeriesRing(L, 'x').coerce_map_from(L) # optional - sage.rings.number_field Coercion map: From: Number Field in b with defining polynomial x^2 + 2 with b = -2*a - To: Power Series Ring in x over Number Field in b with defining polynomial x^2 + 2 with b = -2*a + To: Power Series Ring in x over Number Field in b + with defining polynomial x^2 + 2 with b = -2*a """ if isinstance(S, Parent) and (S)._embedding is not None: if (S)._embedding.codomain() is self: @@ -2539,10 +2554,14 @@ cdef class Parent(sage.structure.category_object.CategoryObject): TESTS:: - sage: M = QQ['y']^3 - sage: M.get_action(ZZ['x']['y']) - Right scalar multiplication by Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Integer Ring on Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field - sage: print(M.get_action(ZZ['x'])) + sage: M = QQ['y']^3 # optional - sage.modules + sage: M.get_action(ZZ['x']['y']) # optional - sage.modules + Right scalar multiplication + by Univariate Polynomial Ring in y + over Univariate Polynomial Ring in x over Integer Ring + on Ambient free module of rank 3 over the principal ideal domain + Univariate Polynomial Ring in y over Rational Field + sage: print(M.get_action(ZZ['x'])) # optional - sage.modules None """ action = self._get_action_(S, op, self_on_left) @@ -2563,27 +2582,34 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: E = EllipticCurve([1,0]) sage: coercion_model.get_action(E, ZZ, operator.mul) - Right Integer Multiplication by Integer Ring on Elliptic Curve defined by y^2 = x^3 + x over Rational Field + Right Integer Multiplication by Integer Ring + on Elliptic Curve defined by y^2 = x^3 + x over Rational Field sage: coercion_model.get_action(ZZ, E, operator.mul) - Left Integer Multiplication by Integer Ring on Elliptic Curve defined by y^2 = x^3 + x over Rational Field + Left Integer Multiplication by Integer Ring + on Elliptic Curve defined by y^2 = x^3 + x over Rational Field sage: coercion_model.get_action(E, int, operator.mul) - Right Integer Multiplication by Set of Python objects of class 'int' on Elliptic Curve defined by y^2 = x^3 + x over Rational Field + Right Integer Multiplication by Set of Python objects of class 'int' + on Elliptic Curve defined by y^2 = x^3 + x over Rational Field sage: coercion_model.get_action(int, E, operator.mul) - Left Integer Multiplication by Set of Python objects of class 'int' on Elliptic Curve defined by y^2 = x^3 + x over Rational Field + Left Integer Multiplication by Set of Python objects of class 'int' + on Elliptic Curve defined by y^2 = x^3 + x over Rational Field :: sage: R. = CDF[] sage: coercion_model.get_action(R, ZZ, operator.pow) - Right Integer Powering by Integer Ring on Univariate Polynomial Ring in x over Complex Double Field + Right Integer Powering by Integer Ring + on Univariate Polynomial Ring in x over Complex Double Field sage: print(coercion_model.get_action(ZZ, R, operator.pow)) None sage: coercion_model.get_action(R, int, operator.pow) - Right Integer Powering by Set of Python objects of class 'int' on Univariate Polynomial Ring in x over Complex Double Field + Right Integer Powering by Set of Python objects of class 'int' + on Univariate Polynomial Ring in x over Complex Double Field sage: print(coercion_model.get_action(int, R, operator.pow)) None sage: coercion_model.get_action(R, IntegerModRing(7), operator.pow) - Right Integer Powering by Ring of integers modulo 7 on Univariate Polynomial Ring in x over Complex Double Field + Right Integer Powering by Ring of integers modulo 7 + on Univariate Polynomial Ring in x over Complex Double Field :: @@ -2791,9 +2817,9 @@ cdef class Parent(sage.structure.category_object.CategoryObject): True sage: ZZ.is_exact() True - sage: Qp(7).is_exact() + sage: Qp(7).is_exact() # optional - sage.rings.padics False - sage: Zp(7, type='capped-abs').is_exact() + sage: Zp(7, type='capped-abs').is_exact() # optional - sage.rings.padics False """ return True @@ -2806,10 +2832,14 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: [R._is_numerical() for R in [RR, CC, QQ, QuadraticField(-1)]] - [True, True, True, True] - sage: [R._is_numerical() for R in [SR, QQ['x'], QQ[['x']]]] - [False, False, False] + sage: QuadraticField(-1)._is_numerical() # optional - sage.rings.number_field + True + sage: [R._is_numerical() for R in [RR, CC, QQ]] + [True, True, True] + sage: SR._is_numerical() # optional - sage.symbolic + False + sage: [R._is_numerical() for R in [QQ['x'], QQ[['x']]]] + [False, False] sage: [R._is_numerical() for R in [RIF, RBF, CIF, CBF]] [False, False, False, False] """ @@ -2832,12 +2862,18 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: [R._is_real_numerical() for R in [RR, QQ, ZZ, RLF, QuadraticField(2)]] - [True, True, True, True, True] - sage: [R._is_real_numerical() for R in [CC, QuadraticField(-1)]] + sage: QuadraticField(2)._is_real_numerical() # optional - sage.rings.number_field + True + sage: [R._is_real_numerical() for R in [RR, QQ, ZZ, RLF]] + [True, True, True, True] + sage: QuadraticField(-1)._is_real_numerical() # optional - sage.rings.number_field + False + sage: CC._is_real_numerical() + False + sage: SR._is_real_numerical() # optional - sage.symbolic + False + sage: [R._is_real_numerical() for R in [QQ['x'], QQ[['x']]]] [False, False] - sage: [R._is_real_numerical() for R in [SR, QQ['x'], QQ[['x']]]] - [False, False, False] sage: [R._is_real_numerical() for R in [RIF, RBF, CIF, CBF]] [False, False, False, False] """ @@ -2885,7 +2921,7 @@ cdef class Set_generic(Parent): sage: bool(Set(QQ)) True - sage: bool(Set(GF(3))) + sage: bool(Set(GF(3))) # optional - sage.rings.finite_rings True """ return not (self.is_finite() and len(self) == 0) @@ -2926,9 +2962,9 @@ cdef class EltPair: Verify that :trac:`16341` has been resolved:: - sage: K. = Qq(9) # optional - sage.rings.padics - sage: E = EllipticCurve_from_j(0).base_extend(K) # optional - sage.rings.padics - sage: E.get_action(ZZ) # optional - sage.rings.padics + sage: K. = Qq(9) # optional - sage.rings.padics + sage: E = EllipticCurve_from_j(0).base_extend(K) # optional - sage.rings.padics + sage: E.get_action(ZZ) # optional - sage.rings.padics Right Integer Multiplication by Integer Ring on Elliptic Curve defined by y^2 + (1+O(3^20))*y = x^3 diff --git a/src/sage/structure/parent_gens.pyx b/src/sage/structure/parent_gens.pyx index c4155736e99..4b84aa909d4 100644 --- a/src/sage/structure/parent_gens.pyx +++ b/src/sage/structure/parent_gens.pyx @@ -47,14 +47,14 @@ This example illustrates generators for a free module over `\ZZ`. :: - sage: M = FreeModule(ZZ, 4) - sage: M + sage: M = FreeModule(ZZ, 4) # optional - sage.modules + sage: M # optional - sage.modules Ambient free module of rank 4 over the principal ideal domain Integer Ring - sage: M.ngens() + sage: M.ngens() # optional - sage.modules 4 - sage: M.gen(0) + sage: M.gen(0) # optional - sage.modules (1, 0, 0, 0) - sage: M.gens() + sage: M.gens() # optional - sage.modules ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)) """ @@ -243,31 +243,31 @@ cdef class ParentWithGens(ParentWithBase): 6 sage: R. = PolynomialRing(QQ) - sage: f = R.hom([5], GF(7)) + sage: f = R.hom([5], GF(7)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: relations do not all (canonically) map to 0 under map determined by images of generators - sage: R. = PolynomialRing(GF(7)) - sage: f = R.hom([3], GF(49,'a')) - sage: f + sage: R. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings + sage: f = R.hom([3], GF(49, 'a')) # optional - sage.rings.finite_rings + sage: f # optional - sage.rings.finite_rings Ring morphism: From: Univariate Polynomial Ring in x over Finite Field of size 7 To: Finite Field in a of size 7^2 Defn: x |--> 3 - sage: f(x+6) + sage: f(x + 6) # optional - sage.rings.finite_rings 2 - sage: f(x^2+1) + sage: f(x^2 + 1) # optional - sage.rings.finite_rings 3 EXAMPLES: Natural morphism :: - sage: f = ZZ.hom(GF(5)) - sage: f(7) + sage: f = ZZ.hom(GF(5)) # optional - sage.rings.finite_rings + sage: f(7) # optional - sage.rings.finite_rings 2 - sage: f + sage: f # optional - sage.rings.finite_rings Natural morphism: From: Integer Ring To: Finite Field of size 5 @@ -283,13 +283,13 @@ cdef class ParentWithGens(ParentWithBase): You can specify a map on the base ring:: - sage: k = GF(2) - sage: R. = k[] - sage: l. = k.extension(a^3 + a^2 + 1) - sage: R. = l[] - sage: m. = l.extension(b^2 + b + a) - sage: n. = GF(2^6) - sage: m.hom([z^4 + z^3 + 1], base_map=l.hom([z^5 + z^4 + z^2])) + sage: k = GF(2) # optional - sage.rings.finite_rings + sage: R. = k[] # optional - sage.rings.finite_rings + sage: l. = k.extension(a^3 + a^2 + 1) # optional - sage.rings.finite_rings + sage: R. = l[] # optional - sage.rings.finite_rings + sage: m. = l.extension(b^2 + b + a) # optional - sage.rings.finite_rings + sage: n. = GF(2^6) # optional - sage.rings.finite_rings + sage: m.hom([z^4 + z^3 + 1], base_map=l.hom([z^5 + z^4 + z^2])) # optional - sage.rings.finite_rings Ring morphism: From: Univariate Quotient Polynomial Ring in b over Finite Field in a of size 2^3 with modulus b^2 + b + a To: Finite Field in z of size 2^6 @@ -338,7 +338,7 @@ cdef class localvars: EXAMPLES:: - sage: R. = PolynomialRing(QQ,2) + sage: R. = PolynomialRing(QQ, 2) sage: with localvars(R, 'z,w'): ....: print(x^3 + y^3 - x*y) z^3 + w^3 - z*w diff --git a/src/sage/structure/parent_old.pyx b/src/sage/structure/parent_old.pyx index 630f0ca8613..a99f586fbfc 100644 --- a/src/sage/structure/parent_old.pyx +++ b/src/sage/structure/parent_old.pyx @@ -13,7 +13,7 @@ TESTS: This came up in some subtle bug once:: - sage: gp(2) + gap(3) + sage: gp(2) + gap(3) # optional - sage.libs.pari 5 """ @@ -48,19 +48,19 @@ cdef class Parent(parent.Parent): TESTS:: - sage: V = VectorSpace(GF(2,'a'),2) - sage: V.list() + sage: V = VectorSpace(GF(2,'a'), 2) # optional - sage.rings.finite_rings + sage: V.list() # optional - sage.rings.finite_rings [(0, 0), (1, 0), (0, 1), (1, 1)] - sage: MatrixSpace(GF(3), 1, 1).list() + sage: MatrixSpace(GF(3), 1, 1).list() # optional - sage.rings.finite_rings [[0], [1], [2]] - sage: DirichletGroup(3).list() + sage: DirichletGroup(3).list() # optional - sage.groups [Dirichlet character modulo 3 of conductor 1 mapping 2 |--> 1, Dirichlet character modulo 3 of conductor 3 mapping 2 |--> -1] - sage: K = GF(7^6,'a') - sage: K.list()[:10] # long time + sage: K = GF(7^6,'a') # optional - sage.rings.finite_rings + sage: K.list()[:10] # long time # optional - sage.rings.finite_rings [0, 1, 2, 3, 4, 5, 6, a, a + 1, a + 2] - sage: K. = GF(4) - sage: K.list() + sage: K. = GF(4) # optional - sage.rings.finite_rings + sage: K.list() # optional - sage.rings.finite_rings [0, a, a + 1, 1] """ diff --git a/src/sage/structure/proof/proof.py b/src/sage/structure/proof/proof.py index 24532380e8a..a8e91de77d5 100644 --- a/src/sage/structure/proof/proof.py +++ b/src/sage/structure/proof/proof.py @@ -192,14 +192,16 @@ def get_flag(t = None, subsystem = None): class WithProof(): """ - Use WithProof to temporarily set the value of one of the proof + Use :class:`WithProof` to temporarily set the value of one of the proof systems for a block of code, with a guarantee that it will be set back to how it was before after the block is done, even if there is an error. - EXAMPLES:: + EXAMPLES: + + This would hang "forever" if attempted with ``proof=True``:: sage: proof.arithmetic(True) - sage: with proof.WithProof('arithmetic',False): # this would hang "forever" if attempted with proof=True + sage: with proof.WithProof('arithmetic', False): # optional - sage.libs.pari ....: print((10^1000 + 453).is_prime()) ....: print(1/0) Traceback (most recent call last): diff --git a/src/sage/structure/sequence.py b/src/sage/structure/sequence.py index 6cdaa84e4ef..dfda29da4e3 100644 --- a/src/sage/structure/sequence.py +++ b/src/sage/structure/sequence.py @@ -45,8 +45,8 @@ special parent. This is what should happen, e.g., with finite field elements of different characteristics:: - sage: v = Sequence([GF(3)(1), GF(7)(1)]) - sage: v.universe() + sage: v = Sequence([GF(3)(1), GF(7)(1)]) # optional - sage.rings.finite_rings + sage: v.universe() # optional - sage.rings.finite_rings Category of objects You can make a list immutable with ``v.freeze()``. Assignment is @@ -201,9 +201,9 @@ def Sequence(x, universe=None, check=True, immutable=False, cr=False, cr_str=Non This example illustrates how every element of a list is taken into account when constructing a sequence.:: - sage: v = Sequence([1,7,6,GF(5)(3)]); v + sage: v = Sequence([1, 7, 6, GF(5)(3)]); v # optional - sage.rings.finite_rings [1, 2, 1, 3] - sage: v.universe() + sage: v.universe() # optional - sage.rings.finite_rings Finite Field of size 5 TESTS:: @@ -397,9 +397,9 @@ class Sequence_generic(sage.structure.sage_object.SageObject, list): :: - sage: v = Sequence([1,7,6,GF(5)(3)]); v + sage: v = Sequence([1, 7, 6, GF(5)(3)]); v # optional - sage.rings.finite_rings [1, 2, 1, 3] - sage: v.universe() + sage: v.universe() # optional - sage.rings.finite_rings Finite Field of size 5 """ @@ -674,11 +674,11 @@ def _latex_(self): r""" TESTS:: - sage: t= Sequence([sqrt(x), exp(x), x^(x-1)], universe=SR); t + sage: t= Sequence([sqrt(x), exp(x), x^(x-1)], universe=SR); t # optional - sage.symbolic [sqrt(x), e^x, x^(x - 1)] - sage: t._latex_() + sage: t._latex_() # optional - sage.symbolic '\\left[\\sqrt{x}, e^{x}, x^{x - 1}\\right]' - sage: latex(t) + sage: latex(t) # optional - sage.symbolic \left[\sqrt{x}, e^{x}, x^{x - 1}\right] """ from sage.misc.latex import list_function as list_latex_function @@ -710,9 +710,9 @@ def universe(self): EXAMPLES:: - sage: Sequence([1,2/3,-2/5]).universe() + sage: Sequence([1, 2/3, -2/5]).universe() Rational Field - sage: Sequence([1,2/3,'-2/5']).universe() + sage: Sequence([1, 2/3, '-2/5']).universe() Category of objects """ return self.__universe @@ -738,7 +738,7 @@ def set_immutable(self): EXAMPLES:: - sage: v = Sequence([1,2,3,4/5]) + sage: v = Sequence([1, 2, 3, 4/5]) sage: v[0] = 5 sage: v [5, 2, 3, 4/5] @@ -759,7 +759,7 @@ def is_immutable(self): EXAMPLES:: - sage: v = Sequence([1,2,3,4/5]) + sage: v = Sequence([1, 2, 3, 4/5]) sage: v[0] = 5 sage: v [5, 2, 3, 4/5] @@ -778,7 +778,7 @@ def is_mutable(self): """ EXAMPLES:: - sage: a = Sequence([1,2/3,-2/5]) + sage: a = Sequence([1, 2/3, -2/5]) sage: a.is_mutable() True sage: a[0] = 100 diff --git a/src/sage/structure/unique_representation.py b/src/sage/structure/unique_representation.py index 7d30c39d66c..40571dcb217 100644 --- a/src/sage/structure/unique_representation.py +++ b/src/sage/structure/unique_representation.py @@ -21,13 +21,13 @@ instances constructed with the same arguments share the same memory representation. For example, calling twice:: - sage: G = SymmetricGroup(6) - sage: H = SymmetricGroup(6) + sage: G = SymmetricGroup(6) # optional - sage.groups + sage: H = SymmetricGroup(6) # optional - sage.groups to create the symmetric group on six elements gives back the same object:: - sage: G is H + sage: G is H # optional - sage.groups True This is a standard design pattern. Besides saving memory, it allows for @@ -100,9 +100,9 @@ class will by default also be used as keys for the cache:: since ``C(1)`` already is in the cache, and since the unit elements in different finite fields are all equal to the integer one, we find:: - sage: GF(5)(1) == 1 == GF(3)(1) + sage: GF(5)(1) == 1 == GF(3)(1) # optional - sage.rings.finite_rings True - sage: C(1) is C(GF(3)(1)) is C(GF(5)(1)) + sage: C(1) is C(GF(3)(1)) is C(GF(5)(1)) # optional - sage.rings.finite_rings True But ``C(2)`` is not in the cache, and the number two is not equal in different @@ -112,9 +112,9 @@ class will by default also be used as keys for the cache:: when comparing elements of *distinct* algebraic structures!!). Hence, we have:: - sage: GF(5)(2) == GF(3)(2) + sage: GF(5)(2) == GF(3)(2) # optional - sage.rings.finite_rings False - sage: C(GF(3)(2)) is C(GF(5)(2)) + sage: C(GF(3)(2)) is C(GF(5)(2)) # optional - sage.rings.finite_rings False Normalising the arguments @@ -424,10 +424,10 @@ class is directly created, then the cache is not used:: Using :class:`CachedRepresentation` has the advantage that one has a class and creates cached instances of this class by the usual Python syntax:: - sage: G = SymmetricGroup(6) - sage: issubclass(SymmetricGroup, sage.structure.unique_representation.CachedRepresentation) + sage: G = SymmetricGroup(6) # optional - sage.groups + sage: issubclass(SymmetricGroup, sage.structure.unique_representation.CachedRepresentation) # optional - sage.groups True - sage: isinstance(G, SymmetricGroup) + sage: isinstance(G, SymmetricGroup) # optional - sage.groups True In contrast, a factory is just a callable object that returns something that @@ -436,14 +436,14 @@ class is directly created, then the cache is not used:: sage: isinstance(GF, sage.structure.factory.UniqueFactory) True - sage: K5 = GF(5) - sage: type(K5) + sage: K5 = GF(5) # optional - sage.rings.finite_rings + sage: type(K5) # optional - sage.rings.finite_rings - sage: K25 = GF(25, 'x') - sage: type(K25) + sage: K25 = GF(25, 'x') # optional - sage.rings.finite_rings + sage: type(K25) # optional - sage.rings.finite_rings - sage: Kp = GF(next_prime_power(1000000)^2, 'x') - sage: type(Kp) + sage: Kp = GF(next_prime_power(1000000)^2, 'x') # optional - sage.rings.finite_rings + sage: type(Kp) # optional - sage.rings.finite_rings This can be confusing to the user. Namely, the user might determine the class @@ -498,13 +498,13 @@ class :class:`~sage.misc.fast_methods.WithEqualityById`, which provides since they are equal to groups created in a totally different way, namely to subgroups:: - sage: G = SymmetricGroup(6) - sage: G3 = G.subgroup([G((1,2,3,4,5,6)),G((1,2))]) - sage: G is G3 + sage: G = SymmetricGroup(6) # optional - sage.groups + sage: G3 = G.subgroup([G((1,2,3,4,5,6)), G((1,2))]) # optional - sage.groups + sage: G is G3 # optional - sage.groups False - sage: type(G) == type(G3) + sage: type(G) == type(G3) # optional - sage.groups False - sage: G == G3 + sage: G == G3 # optional - sage.groups True The unique representation behaviour can conveniently be implemented with a @@ -517,9 +517,9 @@ class that inherits from :class:`UniqueRepresentation`: By adding ring. Thus, it is reasonable to use :class:`UniqueRepresentation` in this case:: - sage: isinstance(SymmetricFunctions(CC), SymmetricFunctions) + sage: isinstance(SymmetricFunctions(CC), SymmetricFunctions) # optional - sage.combinat True - sage: issubclass(SymmetricFunctions, UniqueRepresentation) + sage: issubclass(SymmetricFunctions, UniqueRepresentation) # optional - sage.combinat True :class:`UniqueRepresentation` differs from :class:`CachedRepresentation` only @@ -1188,15 +1188,15 @@ class UniqueRepresentation(CachedRepresentation, WithEqualityById): the same memory representation), if and only if they were created using equal arguments. For example, calling twice:: - sage: f = SymmetricFunctions(QQ) - sage: g = SymmetricFunctions(QQ) + sage: f = SymmetricFunctions(QQ) # optional - sage.combinat + sage: g = SymmetricFunctions(QQ) # optional - sage.combinat to create the symmetric function algebra over `\QQ` actually gives back the same object:: - sage: f == g + sage: f == g # optional - sage.combinat True - sage: f is g + sage: f is g # optional - sage.combinat True This is a standard design pattern. It allows for sharing cached data (say @@ -1211,14 +1211,14 @@ class UniqueRepresentation(CachedRepresentation, WithEqualityById): derive from it, or make sure some of its super classes does. Also, it groups together the class and the factory in a single gadget:: - sage: isinstance(SymmetricFunctions(CC), SymmetricFunctions) + sage: isinstance(SymmetricFunctions(CC), SymmetricFunctions) # optional - sage.combinat True - sage: issubclass(SymmetricFunctions, UniqueRepresentation) + sage: issubclass(SymmetricFunctions, UniqueRepresentation) # optional - sage.combinat True This nice behaviour is not available when one just uses a factory:: - sage: isinstance(GF(7), GF) + sage: isinstance(GF(7), GF) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: isinstance() arg 2 must be a type... diff --git a/src/sage/symbolic/constants.py b/src/sage/symbolic/constants.py index fe99c7a6656..4fc2f23f0b9 100644 --- a/src/sage/symbolic/constants.py +++ b/src/sage/symbolic/constants.py @@ -602,8 +602,8 @@ def _sympy_(self): EXAMPLES:: - sage: import sympy - sage: sympy.pi == pi # indirect doctest + sage: import sympy # optional - sympy + sage: sympy.pi == pi # indirect doctest # optional - sympy True """ import sympy @@ -742,10 +742,10 @@ def _sympy_(self): EXAMPLES:: - sage: bool(NaN._sympy_()._sage_() == NaN) + sage: bool(NaN._sympy_()._sage_() == NaN) # optional - sympy True - sage: import sympy - sage: sympy.nan == NaN # this should be fixed + sage: import sympy # optional - sympy + sage: sympy.nan == NaN # this should be fixed # optional - sympy False """ import sympy @@ -846,8 +846,8 @@ def _sympy_(self): EXAMPLES:: - sage: import sympy - sage: sympy.GoldenRatio == golden_ratio # indirect doctest + sage: import sympy # optional - sympy + sage: sympy.GoldenRatio == golden_ratio # indirect doctest # optional - sympy True """ import sympy @@ -999,8 +999,8 @@ def _sympy_(self): EXAMPLES:: - sage: import sympy - sage: sympy.EulerGamma == euler_gamma # indirect doctest + sage: import sympy # optional - sympy + sage: sympy.EulerGamma == euler_gamma # indirect doctest # optional - sympy True """ import sympy @@ -1067,8 +1067,8 @@ def _sympy_(self): EXAMPLES:: - sage: import sympy - sage: sympy.Catalan == catalan # indirect doctest + sage: import sympy # optional - sympy + sage: sympy.Catalan == catalan # indirect doctest # optional - sympy True """ import sympy diff --git a/src/sage/symbolic/constants_c_impl.pxi b/src/sage/symbolic/constants_c_impl.pxi index 093f9b79037..8821b224ba8 100644 --- a/src/sage/symbolic/constants_c_impl.pxi +++ b/src/sage/symbolic/constants_c_impl.pxi @@ -105,8 +105,8 @@ cdef class E(Expression): 2.7182818284590452353602874714 sage: e._real_double_(RDF) # abs tol 5e-16 2.718281828459045 - sage: import sympy - sage: sympy.E == e # indirect doctest + sage: import sympy # optional - sympy + sage: sympy.E == e # indirect doctest # optional - sympy True TESTS:: diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 7f3afff8bce..61d758f964d 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -437,12 +437,18 @@ cpdef bint is_SymbolicEquation(x): """ Return True if *x* is a symbolic equation. + This function is deprecated. + EXAMPLES: The following two examples are symbolic equations:: sage: from sage.symbolic.expression import is_SymbolicEquation sage: is_SymbolicEquation(sin(x) == x) + doctest:warning... + DeprecationWarning: is_SymbolicEquation is deprecated; use + 'isinstance(x, sage.structure.element.Expression) and x.is_relational()' instead + See https://github.com/sagemath/sage/issues/35505 for details. True sage: is_SymbolicEquation(sin(x) < x) True @@ -462,6 +468,10 @@ cpdef bint is_SymbolicEquation(x): True """ + from sage.misc.superseded import deprecation + deprecation(35505, + "is_SymbolicEquation is deprecated; use " + "'isinstance(x, sage.structure.element.Expression) and x.is_relational()' instead") return isinstance(x, Expression) and is_a_relational((x)._gobj) @@ -474,8 +484,12 @@ cpdef bint _is_SymbolicVariable(x): sage: from sage.symbolic.ring import is_SymbolicVariable sage: is_SymbolicVariable(x) + doctest:warning... + DeprecationWarning: is_SymbolicVariable is deprecated; use + 'isinstance(x, sage.structure.element.Expression) and x.is_symbol()' instead + See https://github.com/sagemath/sage/issues/35505 for details. True - sage: is_SymbolicVariable(x+2) + sage: is_SymbolicVariable(x + 2) False TESTS:: @@ -483,6 +497,10 @@ cpdef bint _is_SymbolicVariable(x): sage: ZZ['x'] Univariate Polynomial Ring in x over Integer Ring """ + from sage.misc.superseded import deprecation + deprecation(35505, + "is_SymbolicVariable is deprecated; use " + "'isinstance(x, sage.structure.element.Expression) and x.is_symbol()' instead") return isinstance(x, Expression) and is_a_symbol((x)._gobj) @@ -3004,7 +3022,7 @@ cdef class Expression(Expression_abc): sig_off() cpdef bint is_relational(self): - """ + r""" Return ``True`` if ``self`` is a relational expression. EXAMPLES:: @@ -3019,8 +3037,8 @@ cdef class Expression(Expression_abc): return is_a_relational(self._gobj) def is_exact(self): - """ - Return True if this expression only contains exact numerical coefficients. + r""" + Return ``True`` if this expression only contains exact numerical coefficients. EXAMPLES:: diff --git a/src/sage/symbolic/expression_conversions.py b/src/sage/symbolic/expression_conversions.py index 6073110887a..edb6c983f3b 100644 --- a/src/sage/symbolic/expression_conversions.py +++ b/src/sage/symbolic/expression_conversions.py @@ -660,25 +660,25 @@ class SympyConverter(Converter): EXAMPLES:: - sage: import sympy + sage: import sympy # optional - sympy sage: var('x,y') (x, y) sage: f = exp(x^2) - arcsin(pi+x)/y - sage: f._sympy_() + sage: f._sympy_() # optional - sympy exp(x**2) - asin(x + pi)/y - sage: _._sage_() + sage: _._sage_() # optional - sympy -arcsin(pi + x)/y + e^(x^2) - sage: sympy.sympify(x) # indirect doctest + sage: sympy.sympify(x) # indirect doctest # optional - sympy x TESTS: Make sure we can convert I (:trac:`6424`):: - sage: bool(I._sympy_() == I) + sage: bool(I._sympy_() == I) # optional - sympy True - sage: (x+I)._sympy_() + sage: (x+I)._sympy_() # optional - sympy x + I """ @@ -686,9 +686,9 @@ def __init__(self): """ TESTS:: - sage: from sage.symbolic.expression_conversions import SympyConverter - sage: s = SympyConverter() # indirect doctest - sage: TestSuite(s).run(skip="_test_pickling") + sage: from sage.symbolic.expression_conversions import SympyConverter # optional - sympy + sage: s = SympyConverter() # indirect doctest # optional - sympy + sage: TestSuite(s).run(skip="_test_pickling") # optional - sympy """ from sage.interfaces.sympy import sympy_init sympy_init() @@ -697,11 +697,11 @@ def __call__(self, ex=None): """ EXAMPLES:: - sage: from sage.symbolic.expression_conversions import SympyConverter - sage: s = SympyConverter() + sage: from sage.symbolic.expression_conversions import SympyConverter # optional - sympy + sage: s = SympyConverter() # optional - sympy sage: f(x, y) = x^2 + y^2; f (x, y) |--> x^2 + y^2 - sage: s(f) + sage: s(f) # optional - sympy Lambda((x, y), x**2 + y**2) """ if isinstance(ex, Expression) and ex.is_callable(): @@ -714,12 +714,12 @@ def pyobject(self, ex, obj): """ EXAMPLES:: - sage: from sage.symbolic.expression_conversions import SympyConverter - sage: s = SympyConverter() + sage: from sage.symbolic.expression_conversions import SympyConverter # optional - sympy + sage: s = SympyConverter() # optional - sympy sage: f = SR(2) - sage: s.pyobject(f, f.pyobject()) + sage: s.pyobject(f, f.pyobject()) # optional - sympy 2 - sage: type(_) + sage: type(_) # optional - sympy """ try: @@ -731,10 +731,10 @@ def arithmetic(self, ex, operator): """ EXAMPLES:: - sage: from sage.symbolic.expression_conversions import SympyConverter - sage: s = SympyConverter() + sage: from sage.symbolic.expression_conversions import SympyConverter # optional - sympy + sage: s = SympyConverter() # optional - sympy sage: f = x + 2 - sage: s.arithmetic(f, f.operator()) + sage: s.arithmetic(f, f.operator()) # optional - sympy x + 2 """ import sympy @@ -757,11 +757,11 @@ def symbol(self, ex): """ EXAMPLES:: - sage: from sage.symbolic.expression_conversions import SympyConverter - sage: s = SympyConverter() - sage: s.symbol(x) + sage: from sage.symbolic.expression_conversions import SympyConverter # optional - sympy + sage: s = SympyConverter() # optional - sympy + sage: s.symbol(x) # optional - sympy x - sage: type(_) + sage: type(_) # optional - sympy """ import sympy @@ -771,16 +771,16 @@ def relation(self, ex, op): """ EXAMPLES:: - sage: import operator - sage: from sage.symbolic.expression_conversions import SympyConverter - sage: s = SympyConverter() - sage: s.relation(x == 3, operator.eq) + sage: import operator # optional - sympy + sage: from sage.symbolic.expression_conversions import SympyConverter # optional - sympy + sage: s = SympyConverter() # optional - sympy + sage: s.relation(x == 3, operator.eq) # optional - sympy Eq(x, 3) - sage: s.relation(pi < 3, operator.lt) + sage: s.relation(pi < 3, operator.lt) # optional - sympy pi < 3 - sage: s.relation(x != pi, operator.ne) + sage: s.relation(x != pi, operator.ne) # optional - sympy Ne(x, pi) - sage: s.relation(x > 0, operator.gt) + sage: s.relation(x > 0, operator.gt) # optional - sympy x > 0 """ from sympy import Eq, Ne, Gt, Lt, Ge, Le @@ -791,15 +791,15 @@ def composition(self, ex, operator): """ EXAMPLES:: - sage: from sage.symbolic.expression_conversions import SympyConverter - sage: s = SympyConverter() + sage: from sage.symbolic.expression_conversions import SympyConverter # optional - sympy + sage: s = SympyConverter() # optional - sympy sage: f = sin(2) - sage: s.composition(f, f.operator()) + sage: s.composition(f, f.operator()) # optional - sympy sin(2) - sage: type(_) + sage: type(_) # optional - sympy sin sage: f = arcsin(2) - sage: s.composition(f, f.operator()) + sage: s.composition(f, f.operator()) # optional - sympy asin(2) """ g = ex.operands() @@ -823,26 +823,26 @@ def tuple(self, ex): EXAMPLES:: sage: t = SR._force_pyobject((3, 4, e^x)) - sage: t._sympy_() + sage: t._sympy_() # optional - sympy (3, 4, e^x) sage: t = SR._force_pyobject((cos(x),)) - sage: t._sympy_() + sage: t._sympy_() # optional - sympy (cos(x),) TESTS:: - sage: from sage.symbolic.expression_conversions import sympy_converter + sage: from sage.symbolic.expression_conversions import sympy_converter # optional - sympy sage: F = hypergeometric([1/3,2/3],[1,1],x) - sage: F._sympy_() + sage: F._sympy_() # optional - sympy hyper((1/3, 2/3), (1, 1), x) sage: F = hypergeometric([1/3,2/3],[1],x) - sage: F._sympy_() + sage: F._sympy_() # optional - sympy hyper((1/3, 2/3), (1,), x) sage: var('a,b,c,d') (a, b, c, d) - sage: hypergeometric((a,b,),(c,),d)._sympy_() + sage: hypergeometric((a,b,),(c,),d)._sympy_() # optional - sympy hyper((a, b), (c,), d) """ return tuple(ex.operands()) @@ -863,20 +863,20 @@ def derivative(self, ex, operator): (x, y) sage: f_sage = function('f_sage')(x, y) - sage: f_sympy = f_sage._sympy_() + sage: f_sympy = f_sage._sympy_() # optional - sympy sage: df_sage = f_sage.diff(x, 2, y, 1); df_sage diff(f_sage(x, y), x, x, y) - sage: df_sympy = df_sage._sympy_(); df_sympy + sage: df_sympy = df_sage._sympy_(); df_sympy # optional - sympy Derivative(f_sage(x, y), (x, 2), y) - sage: df_sympy == f_sympy.diff(x, 2, y, 1) + sage: df_sympy == f_sympy.diff(x, 2, y, 1) # optional - sympy True Check that :trac:`28964` is fixed:: sage: f = function('f') sage: _ = var('x,t') - sage: diff(f(x, t), x)._sympy_(), diff(f(x, t), t)._sympy_() + sage: diff(f(x, t), x)._sympy_(), diff(f(x, t), t)._sympy_() # optional - sympy (Derivative(f(x, t), x), Derivative(f(x, t), t)) Check differentiating by variables with multiple occurrences @@ -884,15 +884,15 @@ def derivative(self, ex, operator): sage: f = function('f') sage: _ = var('x1,x2,x3,x,t') - sage: f(x, x, t).diff(x)._sympy_()._sage_() + sage: f(x, x, t).diff(x)._sympy_()._sage_() # optional - sympy D[0](f)(x, x, t) + D[1](f)(x, x, t) sage: g = f(x1, x2, x3, t).diff(x1, 2, x2).subs(x1==x, x2==x, x3==x); g D[0, 0, 1](f)(x, x, x, t) - sage: g._sympy_() + sage: g._sympy_() # optional - sympy Subs(Derivative(f(_xi_1, _xi_2, x, t), (_xi_1, 2), _xi_2), (_xi_1, _xi_2), (x, x)) - sage: assert g._sympy_()._sage_() == g + sage: assert g._sympy_()._sage_() == g # optional - sympy Check that the use of dummy variables does not cause a collision:: @@ -900,7 +900,7 @@ def derivative(self, ex, operator): sage: _ = var('x1,x2,x,xi_1') sage: g = f(x1, x2, xi_1).diff(x1).subs(x1==x, x2==x); g D[0](f)(x, x, xi_1) - sage: assert g._sympy_()._sage_() == g + sage: assert g._sympy_()._sage_() == g # optional - sympy """ import sympy diff --git a/src/sage/symbolic/function.pyx b/src/sage/symbolic/function.pyx index 0d347103756..e5ad9371901 100644 --- a/src/sage/symbolic/function.pyx +++ b/src/sage/symbolic/function.pyx @@ -433,8 +433,8 @@ cdef class Function(SageObject): We can also handle numpy types:: - sage: import numpy - sage: sin(numpy.arange(5)) + sage: import numpy # optional - numpy + sage: sin(numpy.arange(5)) # optional - numpy array([ 0. , 0.84147098, 0.90929743, 0.14112001, -0.7568025 ]) Symbolic functions evaluate non-exact input numerically, and return @@ -483,9 +483,10 @@ cdef class Function(SageObject): Make sure we can pass mpmath arguments (:trac:`13608`):: - sage: import mpmath - sage: with mpmath.workprec(128): sin(mpmath.mpc('0.5', '1.2')) - mpc(real='0.86807452059118713192871150787046523179886', imag='1.3246769633571289324095313649562791720086') + sage: import mpmath # optional - mpmath + sage: with mpmath.workprec(128): sin(mpmath.mpc('0.5', '1.2')) # optional - mpmath + mpc(real='0.86807452059118713192871150787046523179886', + imag='1.3246769633571289324095313649562791720086') Check that :trac:`10133` is fixed:: @@ -504,11 +505,11 @@ cdef class Function(SageObject): Check that ``real_part`` and ``imag_part`` still works after :trac:`21216`:: - sage: import numpy - sage: a = numpy.array([1+2*I, -2-3*I], dtype=complex) - sage: real_part(a) + sage: import numpy # optional - numpy + sage: a = numpy.array([1+2*I, -2-3*I], dtype=complex) # optional - numpy + sage: real_part(a) # optional - numpy array([ 1., -2.]) - sage: imag_part(a) + sage: imag_part(a) # optional - numpy array([ 2., -3.]) """ if self._nargs > 0 and len(args) != self._nargs: @@ -742,13 +743,13 @@ cdef class Function(SageObject): EXAMPLES:: - sage: import numpy - sage: a = numpy.arange(5) - sage: csc(a) + sage: import numpy # optional - numpy + sage: a = numpy.arange(5) # optional - numpy + sage: csc(a) # optional - numpy doctest:...: RuntimeWarning: divide by zero encountered in ...divide array([ inf, 1.18839511, 1.09975017, 7.0861674 , -1.32134871]) - sage: factorial(a) + sage: factorial(a) # optional - numpy Traceback (most recent call last): ... NotImplementedError: The Function factorial does not support numpy arrays as arguments @@ -769,8 +770,8 @@ cdef class Function(SageObject): implementation, using sage reals instead of mpmath ones. This might change when aliases for these functions are established:: - sage: import mpmath - sage: with mpmath.workprec(128): arcsin(mpmath.mpf('0.5')) + sage: import mpmath # optional - mpmath + sage: with mpmath.workprec(128): arcsin(mpmath.mpf('0.5')) # optional - mpmath mpf('0.52359877559829887307710723054658381403157') TESTS: @@ -779,7 +780,7 @@ cdef class Function(SageObject): not using mpmath, we have to create a custom function which will certainly never get created in mpmath. :: - sage: import mpmath + sage: import mpmath # optional - mpmath sage: from sage.symbolic.function import BuiltinFunction sage: class NoMpmathFn(BuiltinFunction): ....: def _eval_(self, arg): @@ -787,13 +788,13 @@ cdef class Function(SageObject): ....: prec = parent.prec() ....: assert parent == RealField(prec) ....: return prec - sage: noMpmathFn = NoMpmathFn("noMpmathFn") - sage: with mpmath.workprec(64): noMpmathFn(sqrt(mpmath.mpf('2'))) + sage: noMpmathFn = NoMpmathFn("noMpmathFn") # optional - mpmath + sage: with mpmath.workprec(64): noMpmathFn(sqrt(mpmath.mpf('2'))) # optional - mpmath 64 - sage: mpmath.noMpmathFn = lambda x: 123 - sage: with mpmath.workprec(64): noMpmathFn(sqrt(mpmath.mpf('2'))) + sage: mpmath.noMpmathFn = lambda x: 123 # optional - mpmath + sage: with mpmath.workprec(64): noMpmathFn(sqrt(mpmath.mpf('2'))) # optional - mpmath 123 - sage: del mpmath.noMpmathFn + sage: del mpmath.noMpmathFn # optional - mpmath """ import mpmath @@ -944,16 +945,16 @@ cdef class BuiltinFunction(Function): (1.5430806348152437-0j) sage: assert type(_) is complex - sage: import mpmath - sage: cos(mpmath.mpf('1.321412')) + sage: import mpmath # optional - mpmath + sage: cos(mpmath.mpf('1.321412')) # optional - mpmath mpf('0.24680737898640387') - sage: cos(mpmath.mpc(1,1)) + sage: cos(mpmath.mpc(1,1)) # optional - mpmath mpc(real='0.83373002513114902', imag='-0.98889770576286506') - sage: import numpy - sage: sin(numpy.int32(0)) + sage: import numpy # optional - numpy + sage: sin(numpy.int32(0)) # optional - numpy 0.0 - sage: type(_) + sage: type(_) # optional - numpy TESTS:: diff --git a/src/sage/symbolic/integration/external.py b/src/sage/symbolic/integration/external.py index 0760f20920b..cc18073733b 100644 --- a/src/sage/symbolic/integration/external.py +++ b/src/sage/symbolic/integration/external.py @@ -3,7 +3,7 @@ TESTS:: sage: from sage.symbolic.integration.external import sympy_integrator - sage: sympy_integrator(sin(x), x) + sage: sympy_integrator(sin(x), x) # optional - sympy -cos(x) """ from sage.symbolic.expression import Expression @@ -54,9 +54,9 @@ def sympy_integrator(expression, v, a=None, b=None): EXAMPLES:: sage: from sage.symbolic.integration.external import sympy_integrator - sage: sympy_integrator(sin(x), x) + sage: sympy_integrator(sin(x), x) # optional - sympy -cos(x) - sage: sympy_integrator(cos(x), x) + sage: sympy_integrator(cos(x), x) # optional - sympy sin(x) """ import sympy diff --git a/src/sage/symbolic/ring.pyx b/src/sage/symbolic/ring.pyx index a0c497dc65d..932d4ebda93 100644 --- a/src/sage/symbolic/ring.pyx +++ b/src/sage/symbolic/ring.pyx @@ -1167,17 +1167,17 @@ cdef class NumpyToSRMorphism(Morphism): We check that :trac:`8949` and :trac:`9769` are fixed (see also :trac:`18076`):: - sage: import numpy + sage: import numpy # optional - numpy sage: f(x) = x^2 - sage: f(numpy.int8('2')) + sage: f(numpy.int8('2')) # optional - numpy 4 - sage: f(numpy.int32('3')) + sage: f(numpy.int32('3')) # optional - numpy 9 Note that the answer is a Sage integer and not a numpy type:: - sage: a = f(numpy.int8('2')).pyobject() - sage: type(a) + sage: a = f(numpy.int8('2')).pyobject() # optional - numpy + sage: type(a) # optional - numpy This behavior also applies to standard functions:: @@ -1200,15 +1200,15 @@ cdef class NumpyToSRMorphism(Morphism): EXAMPLES:: - sage: import numpy + sage: import numpy # optional - numpy sage: from sage.symbolic.ring import NumpyToSRMorphism - sage: f = NumpyToSRMorphism(numpy.float64) - sage: f(numpy.float64('2.0')) + sage: f = NumpyToSRMorphism(numpy.float64) # optional - numpy + sage: f(numpy.float64('2.0')) # optional - numpy 2.0 - sage: _.parent() + sage: _.parent() # optional - numpy Symbolic Ring - sage: NumpyToSRMorphism(str) + sage: NumpyToSRMorphism(str) # optional - numpy Traceback (most recent call last): ... TypeError: <... 'str'> is not a numpy number type @@ -1235,18 +1235,18 @@ cdef class NumpyToSRMorphism(Morphism): This should be called when coercing or converting a NumPy float or complex to the Symbolic Ring:: - sage: import numpy - sage: SR(numpy.int32('1')).pyobject().parent() + sage: import numpy # optional - numpy + sage: SR(numpy.int32('1')).pyobject().parent() # optional - numpy Integer Ring - sage: SR(numpy.int64('-2')).pyobject().parent() + sage: SR(numpy.int64('-2')).pyobject().parent() # optional - numpy Integer Ring - sage: SR(numpy.float16('1')).pyobject().parent() + sage: SR(numpy.float16('1')).pyobject().parent() # optional - numpy Real Double Field - sage: SR(numpy.float64('2.0')).pyobject().parent() + sage: SR(numpy.float64('2.0')).pyobject().parent() # optional - numpy Real Double Field - sage: SR(numpy.complex64(1jr)).pyobject().parent() + sage: SR(numpy.complex64(1jr)).pyobject().parent() # optional - numpy Complex Double Field """ return new_Expression_from_pyobject(self.codomain(), self._intermediate_ring(a), True) @@ -1260,13 +1260,13 @@ cdef class UnderscoreSageMorphism(Morphism): EXAMPLES:: - sage: import sympy + sage: import sympy # optional - sympy sage: from sage.symbolic.ring import UnderscoreSageMorphism - sage: b = sympy.var('b') - sage: f = UnderscoreSageMorphism(type(b), SR) - sage: f(b) + sage: b = sympy.var('b') # optional - sympy + sage: f = UnderscoreSageMorphism(type(b), SR) # optional - sympy + sage: f(b) # optional - sympy b - sage: _.parent() + sage: _.parent() # optional - sympy Symbolic Ring """ import sage.categories.homset @@ -1282,9 +1282,9 @@ cdef class UnderscoreSageMorphism(Morphism): This should be called when coercing or converting a SymPy object to the Symbolic Ring:: - sage: import sympy - sage: b = sympy.var('b') - sage: bool(SR(b) == SR(b._sage_())) + sage: import sympy # optional - sympy + sage: b = sympy.var('b') # optional - sympy + sage: bool(SR(b) == SR(b._sage_())) # optional - sympy True """ return self.codomain()(a._sage_()) diff --git a/src/sage/topology/cell_complex.py b/src/sage/topology/cell_complex.py index 24379a7ca7b..1b40ed49d40 100644 --- a/src/sage/topology/cell_complex.py +++ b/src/sage/topology/cell_complex.py @@ -48,7 +48,6 @@ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.misc.abstract_method import abstract_method -from sage.homology.chains import Chains, Cochains class GenericCellComplex(SageObject): @@ -509,21 +508,22 @@ def homology(self, dim=None, base_ring=ZZ, subcomplex=None, {0: 0, 1: C2, 2: 0} sage: P.homology(reduced=False) {0: Z, 1: C2, 2: 0} - sage: P.homology(base_ring=GF(2)) + sage: P.homology(base_ring=GF(2)) # optional - sage.modules sage.rings.finite_rings {0: Vector space of dimension 0 over Finite Field of size 2, 1: Vector space of dimension 1 over Finite Field of size 2, 2: Vector space of dimension 1 over Finite Field of size 2} sage: S7 = delta_complexes.Sphere(7) - sage: S7.homology(7) + sage: S7.homology(7) # optional - sage.modules Z - sage: cubical_complexes.KleinBottle().homology(1, base_ring=GF(2)) + sage: cubical_complexes.KleinBottle().homology(1, base_ring=GF(2)) # optional - sage.modules sage.rings.finite_rings Vector space of dimension 2 over Finite Field of size 2 Sage can compute generators of homology groups:: sage: S2 = simplicial_complexes.Sphere(2) - sage: S2.homology(dim=2, generators=True, base_ring=GF(2)) - [(Vector space of dimension 1 over Finite Field of size 2, (0, 1, 2) + (0, 1, 3) + (0, 2, 3) + (1, 2, 3))] + sage: S2.homology(dim=2, generators=True, base_ring=GF(2)) # optional - sage.modules sage.rings.finite_rings + [(Vector space of dimension 1 over Finite Field of size 2, + (0, 1, 2) + (0, 1, 3) + (0, 2, 3) + (1, 2, 3))] When generators are computed, Sage returns a pair for each dimension: the group and the list of generators. For @@ -532,14 +532,15 @@ def homology(self, dim=None, base_ring=ZZ, subcomplex=None, complexes, each generator is a linear combination of cubes:: sage: S2_cub = cubical_complexes.Sphere(2) - sage: S2_cub.homology(dim=2, generators=True) + sage: S2_cub.homology(dim=2, generators=True) # optional - sage.modules [(Z, - [0,0] x [0,1] x [0,1] - [0,1] x [0,0] x [0,1] + [0,1] x [0,1] x [0,0] - [0,1] x [0,1] x [1,1] + [0,1] x [1,1] x [0,1] - [1,1] x [0,1] x [0,1])] + [0,0] x [0,1] x [0,1] - [0,1] x [0,0] x [0,1] + [0,1] x [0,1] x [0,0] + - [0,1] x [0,1] x [1,1] + [0,1] x [1,1] x [0,1] - [1,1] x [0,1] x [0,1])] Similarly for simpicial sets:: sage: S = simplicial_sets.Sphere(2) - sage: S.homology(generators=True) + sage: S.homology(generators=True) # optional - sage.modules {0: [], 1: 0, 2: [(Z, sigma_2)]} """ from sage.topology.cubical_complex import CubicalComplex @@ -623,28 +624,32 @@ def cohomology(self, dim=None, base_ring=ZZ, subcomplex=None, 0 sage: circle.cohomology(1) Z - sage: P2 = SimplicialComplex([[0,1,2], [0,2,3], [0,1,5], [0,4,5], [0,3,4], [1,2,4], [1,3,4], [1,3,5], [2,3,5], [2,4,5]]) # projective plane - sage: P2.cohomology(2) + + Projective plane:: + + sage: P2 = SimplicialComplex([[0,1,2], [0,2,3], [0,1,5], [0,4,5], [0,3,4], + ....: [1,2,4], [1,3,4], [1,3,5], [2,3,5], [2,4,5]]) + sage: P2.cohomology(2) # optional - sage.modules C2 - sage: P2.cohomology(2, base_ring=GF(2)) + sage: P2.cohomology(2, base_ring=GF(2)) # optional - sage.modules sage.rings.finite_rings Vector space of dimension 1 over Finite Field of size 2 - sage: P2.cohomology(2, base_ring=GF(3)) + sage: P2.cohomology(2, base_ring=GF(3)) # optional - sage.modules sage.rings.finite_rings Vector space of dimension 0 over Finite Field of size 3 - sage: cubical_complexes.KleinBottle().cohomology(2) + sage: cubical_complexes.KleinBottle().cohomology(2) # optional - sage.modules C2 Relative cohomology:: sage: T = SimplicialComplex([[0,1]]) sage: U = SimplicialComplex([[0], [1]]) - sage: T.cohomology(1, subcomplex=U) + sage: T.cohomology(1, subcomplex=U) # optional - sage.modules Z A `\Delta`-complex example:: sage: s5 = delta_complexes.Sphere(5) - sage: s5.cohomology(base_ring=GF(7))[5] + sage: s5.cohomology(base_ring=GF(7))[5] # optional - sage.modules sage.rings.finite_rings Vector space of dimension 1 over Finite Field of size 7 """ return self.homology(dim=dim, cohomology=True, base_ring=base_ring, @@ -775,6 +780,8 @@ def n_chains(self, n, base_ring=ZZ, cochains=False): sage: list(simplicial_complexes.Sphere(2).n_chains(1, QQ, cochains=True).basis()) [\chi_(0, 1), \chi_(0, 2), \chi_(0, 3), \chi_(1, 2), \chi_(1, 3), \chi_(2, 3)] """ + from sage.homology.chains import Chains, Cochains + n_cells = tuple(self._n_cells_sorted(n)) if cochains: return Cochains(self, n, n_cells, base_ring) @@ -836,25 +843,26 @@ def homology_with_basis(self, base_ring=QQ, cohomology=False): EXAMPLES:: sage: K = simplicial_complexes.KleinBottle() - sage: H = K.homology_with_basis(QQ); H + sage: H = K.homology_with_basis(QQ); H # optional - sage.modules Homology module of Minimal triangulation of the Klein bottle over Rational Field - sage: sorted(H.basis(), key=str) + sage: sorted(H.basis(), key=str) # optional - sage.modules [h_{0,0}, h_{1,0}] - sage: H = K.homology_with_basis(GF(2)); H + sage: H = K.homology_with_basis(GF(2)); H # optional - sage.modules sage.rings.finite_rings Homology module of Minimal triangulation of the Klein bottle over Finite Field of size 2 - sage: sorted(H.basis(), key=str) + sage: sorted(H.basis(), key=str) # optional - sage.modules sage.rings.finite_rings [h_{0,0}, h_{1,0}, h_{1,1}, h_{2,0}] The homology is constructed as a graded object, so for example, you can ask for the basis in a single degree:: - sage: H.basis(1) + sage: H.basis(1) # optional - sage.modules sage.rings.finite_rings Finite family {(1, 0): h_{1,0}, (1, 1): h_{1,1}} + sage: S3 = delta_complexes.Sphere(3) - sage: H = S3.homology_with_basis(QQ, cohomology=True) - sage: list(H.basis(3)) + sage: H = S3.homology_with_basis(QQ, cohomology=True) # optional - sage.modules + sage: list(H.basis(3)) # optional - sage.modules [h^{3,0}] """ from sage.homology.homology_vector_space_with_basis import HomologyVectorSpaceWithBasis @@ -899,10 +907,10 @@ def cohomology_ring(self, base_ring=QQ): over Rational Field sage: sorted(H.basis(), key=str) [h^{0,0}, h^{1,0}] - sage: H = K.cohomology_ring(GF(2)); H + sage: H = K.cohomology_ring(GF(2)); H # optional - sage.rings.finite_rings Cohomology ring of Minimal triangulation of the Klein bottle over Finite Field of size 2 - sage: sorted(H.basis(), key=str) + sage: sorted(H.basis(), key=str) # optional - sage.rings.finite_rings [h^{0,0}, h^{1,0}, h^{1,1}, h^{2,0}] sage: X = delta_complexes.SurfaceOfGenus(2) @@ -933,12 +941,12 @@ def cohomology_ring(self, base_ring=QQ): Cohomology operations:: - sage: RP2 = simplicial_complexes.RealProjectivePlane() - sage: K = RP2.suspension() - sage: K.set_immutable() - sage: y = K.cohomology_ring(GF(2)).basis()[2,0]; y + sage: RP2 = simplicial_complexes.RealProjectivePlane() # optional - sage.groups + sage: K = RP2.suspension() # optional - sage.graphs sage.groups + sage: K.set_immutable() # optional - sage.graphs sage.groups + sage: y = K.cohomology_ring(GF(2)).basis()[2,0]; y # optional - sage.graphs sage.groups sage.rings.finite_rings h^{2,0} - sage: y.Sq(1) + sage: y.Sq(1) # optional - sage.graphs sage.groups sage.rings.finite_rings h^{3,0} To compute the cohomology ring, the complex must be @@ -1031,13 +1039,13 @@ def face_poset(self): EXAMPLES:: - sage: P = SimplicialComplex([[0, 1], [1,2], [2,3]]).face_poset(); P + sage: P = SimplicialComplex([[0, 1], [1,2], [2,3]]).face_poset(); P # optional - sage.combinat sage.graphs Finite poset containing 7 elements - sage: sorted(P.list()) + sage: sorted(P.list()) # optional - sage.combinat sage.graphs [(0,), (0, 1), (1,), (1, 2), (2,), (2, 3), (3,)] sage: S2 = cubical_complexes.Sphere(2) - sage: S2.face_poset() + sage: S2.face_poset() # optional - sage.combinat sage.graphs Finite poset containing 26 elements """ from sage.combinat.posets.posets import Poset @@ -1079,27 +1087,26 @@ def is_connected(self): EXAMPLES:: - sage: V = SimplicialComplex([[0,1,2],[3]]) - sage: V + sage: V = SimplicialComplex([[0,1,2],[3]]); V Simplicial complex with vertex set (0, 1, 2, 3) and facets {(3,), (0, 1, 2)} - sage: V.is_connected() + sage: V.is_connected() # optional - sage.graphs False sage: X = SimplicialComplex([[0,1,2]]) - sage: X.is_connected() + sage: X.is_connected() # optional - sage.graphs True sage: U = simplicial_complexes.ChessboardComplex(3,3) - sage: U.is_connected() + sage: U.is_connected() # optional - sage.graphs True sage: W = simplicial_complexes.Sphere(3) - sage: W.is_connected() + sage: W.is_connected() # optional - sage.graphs True sage: S = SimplicialComplex([[0,1],[2,3]]) - sage: S.is_connected() + sage: S.is_connected() # optional - sage.graphs False - sage: cubical_complexes.Sphere(0).is_connected() + sage: cubical_complexes.Sphere(0).is_connected() # optional - sage.graphs False - sage: cubical_complexes.Sphere(2).is_connected() + sage: cubical_complexes.Sphere(2).is_connected() # optional - sage.graphs True """ return self.graph().is_connected() diff --git a/src/sage/topology/cubical_complex.py b/src/sage/topology/cubical_complex.py index 0ce508ec2c1..227dfbe8219 100644 --- a/src/sage/topology/cubical_complex.py +++ b/src/sage/topology/cubical_complex.py @@ -26,7 +26,8 @@ `(0,2)` to `(0,3)` to `(1,3)` to `(1,2)` to `(0,2)`. In Sage, this is done with the following command:: - sage: S1 = CubicalComplex([([0,0], [2,3]), ([0,1], [3,3]), ([0,1], [2,2]), ([1,1], [2,3])]); S1 + sage: S1 = CubicalComplex([([0,0], [2,3]), ([0,1], [3,3]), + ....: ([0,1], [2,2]), ([1,1], [2,3])]); S1 Cubical complex with 4 vertices and 8 cubes The argument to ``CubicalComplex`` is a list of the maximal "cubes" in @@ -47,7 +48,8 @@ sage: S1.homology() {0: 0, 1: Z} - sage: X = CubicalComplex([([0,0], [2,3], [2]), ([0,1], [3,3], [2]), ([0,1], [2,2], [2]), ([1,1], [2,3], [2])]) + sage: X = CubicalComplex([([0,0], [2,3], [2]), ([0,1], [3,3], [2]), + ....: ([0,1], [2,2], [2]), ([1,1], [2,3], [2])]) sage: X.homology() {0: 0, 1: Z} @@ -771,8 +773,8 @@ class :class:`Cube`, or lists or tuples suitable for conversion to A "circle" (four edges connecting the vertices (0,2), (0,3), (1,2), and (1,3)):: - sage: S1 = CubicalComplex([([0,0], [2,3]), ([0,1], [3,3]), ([0,1], [2,2]), ([1,1], [2,3])]) - sage: S1 + sage: S1 = CubicalComplex([([0,0], [2,3]), ([0,1], [3,3]), + ....: ([0,1], [2,2]), ([1,1], [2,3])]); S1 Cubical complex with 4 vertices and 8 cubes sage: S1.homology() {0: 0, 1: Z} @@ -832,12 +834,12 @@ class :class:`Cube`, or lists or tuples suitable for conversion to Cubical complex with 16 vertices and 64 cubes sage: T.chain_complex() Chain complex with at most 3 nonzero terms over Integer Ring - sage: T.homology(base_ring=QQ) + sage: T.homology(base_ring=QQ) # optional - sage.modules {0: Vector space of dimension 0 over Rational Field, 1: Vector space of dimension 2 over Rational Field, 2: Vector space of dimension 1 over Rational Field} sage: RP2 = cubical_complexes.RealProjectivePlane() - sage: RP2.cohomology(dim=[1, 2], base_ring=GF(2)) + sage: RP2.cohomology(dim=[1, 2], base_ring=GF(2)) # optional - sage.modules sage.rings.finite_rings {1: Vector space of dimension 1 over Finite Field of size 2, 2: Vector space of dimension 1 over Finite Field of size 2} @@ -1330,7 +1332,7 @@ def graph(self): EXAMPLES:: - sage: cubical_complexes.Sphere(2).graph() + sage: cubical_complexes.Sphere(2).graph() # optional - sage.graphs Graph on 8 vertices """ from sage.graphs.graph import Graph @@ -1549,12 +1551,12 @@ def connected_sum(self, other): sage: T = cubical_complexes.Torus() sage: S2 = cubical_complexes.Sphere(2) - sage: T.connected_sum(S2).cohomology() == T.cohomology() + sage: T.connected_sum(S2).cohomology() == T.cohomology() # optional - sage.modules True sage: RP2 = cubical_complexes.RealProjectivePlane() - sage: T.connected_sum(RP2).homology(1) + sage: T.connected_sum(RP2).homology(1) # optional - sage.modules Z x Z x C2 - sage: RP2.connected_sum(RP2).connected_sum(RP2).homology(1) + sage: RP2.connected_sum(RP2).connected_sum(RP2).homology(1) # optional - sage.modules Z x Z x C2 """ # connected_sum: first check whether the complexes are pure @@ -1670,14 +1672,14 @@ def algebraic_topological_model(self, base_ring=None): EXAMPLES:: sage: RP2 = cubical_complexes.RealProjectivePlane() - sage: phi, M = RP2.algebraic_topological_model(GF(2)) - sage: M.homology() + sage: phi, M = RP2.algebraic_topological_model(GF(2)) # optional - sage.rings.finite_rings + sage: M.homology() # optional - sage.modules sage.rings.finite_rings {0: Vector space of dimension 1 over Finite Field of size 2, 1: Vector space of dimension 1 over Finite Field of size 2, 2: Vector space of dimension 1 over Finite Field of size 2} sage: T = cubical_complexes.Torus() sage: phi, M = T.algebraic_topological_model(QQ) - sage: M.homology() + sage: M.homology() # optional - sage.modules {0: Vector space of dimension 1 over Rational Field, 1: Vector space of dimension 2 over Rational Field, 2: Vector space of dimension 1 over Rational Field} diff --git a/src/sage/topology/delta_complex.py b/src/sage/topology/delta_complex.py index 012b92e351d..d4430d074b0 100644 --- a/src/sage/topology/delta_complex.py +++ b/src/sage/topology/delta_complex.py @@ -944,22 +944,22 @@ def product(self, other): sage: K = delta_complexes.KleinBottle() sage: X = K.product(K) - sage: X.homology(1) + sage: X.homology(1) # optional - sage.modules Z x Z x C2 x C2 - sage: X.homology(2) + sage: X.homology(2) # optional - sage.modules Z x C2 x C2 x C2 - sage: X.homology(3) + sage: X.homology(3) # optional - sage.modules C2 - sage: X.homology(4) + sage: X.homology(4) # optional - sage.modules 0 - sage: X.homology(base_ring=GF(2)) + sage: X.homology(base_ring=GF(2)) # optional - sage.modules sage.rings.finite_rings {0: Vector space of dimension 0 over Finite Field of size 2, 1: Vector space of dimension 4 over Finite Field of size 2, 2: Vector space of dimension 6 over Finite Field of size 2, 3: Vector space of dimension 4 over Finite Field of size 2, 4: Vector space of dimension 1 over Finite Field of size 2} sage: S1 = delta_complexes.Sphere(1) - sage: K.product(S1).homology() == S1.product(K).homology() + sage: K.product(S1).homology() == S1.product(K).homology() # optional - sage.modules True sage: S1.product(S1) == delta_complexes.Torus() True @@ -1063,7 +1063,7 @@ def disjoint_union(self, right): sage: S1 = delta_complexes.Sphere(1) sage: S2 = delta_complexes.Sphere(2) - sage: S1.disjoint_union(S2).homology() + sage: S1.disjoint_union(S2).homology() # optional - sage.modules {0: Z, 1: Z, 2: Z} """ dim = max(self.dimension(), right.dimension()) @@ -1095,7 +1095,7 @@ def wedge(self, right): sage: S1 = delta_complexes.Sphere(1) sage: S2 = delta_complexes.Sphere(2) - sage: S1.wedge(S2).homology() + sage: S1.wedge(S2).homology() # optional - sage.modules {0: 0, 1: Z, 2: Z} """ data = self.disjoint_union(right).cells() @@ -1146,14 +1146,14 @@ def connected_sum(self, other): sage: T = delta_complexes.Torus() sage: S2 = delta_complexes.Sphere(2) - sage: T.connected_sum(S2).cohomology() == T.cohomology() + sage: T.connected_sum(S2).cohomology() == T.cohomology() # optional - sage.modules True sage: RP2 = delta_complexes.RealProjectivePlane() - sage: T.connected_sum(RP2).homology(1) + sage: T.connected_sum(RP2).homology(1) # optional - sage.modules Z x Z x C2 - sage: T.connected_sum(RP2).homology(2) + sage: T.connected_sum(RP2).homology(2) # optional - sage.modules 0 - sage: RP2.connected_sum(RP2).connected_sum(RP2).homology(1) + sage: RP2.connected_sum(RP2).connected_sum(RP2).homology(1) # optional - sage.modules Z x Z x C2 """ if not self.dimension() == other.dimension(): @@ -1272,7 +1272,7 @@ def elementary_subdivision(self, idx=-1): Delta complex with 2 vertices and 13 simplices sage: X.elementary_subdivision() Delta complex with 3 vertices and 19 simplices - sage: X.homology() == T.homology() + sage: X.homology() == T.homology() # optional - sage.modules True """ pi = self._epi_from_standard_simplex(idx=idx) @@ -1453,7 +1453,7 @@ def face_poset(self): EXAMPLES:: sage: T = delta_complexes.Torus() - sage: T.face_poset() + sage: T.face_poset() # optional - sage.combinat sage.graphs Finite poset containing 6 elements """ from sage.combinat.posets.posets import Poset @@ -1581,14 +1581,14 @@ def algebraic_topological_model(self, base_ring=None): EXAMPLES:: sage: RP2 = delta_complexes.RealProjectivePlane() - sage: phi, M = RP2.algebraic_topological_model(GF(2)) - sage: M.homology() + sage: phi, M = RP2.algebraic_topological_model(GF(2)) # optional - sage.rings.finite_rings + sage: M.homology() # optional - sage.modules sage.rings.finite_rings {0: Vector space of dimension 1 over Finite Field of size 2, 1: Vector space of dimension 1 over Finite Field of size 2, 2: Vector space of dimension 1 over Finite Field of size 2} sage: T = delta_complexes.Torus() sage: phi, M = T.algebraic_topological_model(QQ) - sage: M.homology() + sage: M.homology() # optional - sage.modules {0: Vector space of dimension 1 over Rational Field, 1: Vector space of dimension 2 over Rational Field, 2: Vector space of dimension 1 over Rational Field} @@ -1649,7 +1649,7 @@ def Sphere(self,n): EXAMPLES:: - sage: delta_complexes.Sphere(4).cohomology(4, base_ring=GF(3)) + sage: delta_complexes.Sphere(4).cohomology(4, base_ring=GF(3)) # optional - sage.modules sage.rings.finite_rings Vector space of dimension 1 over Finite Field of size 3 """ if n == 1: @@ -1682,13 +1682,13 @@ def RealProjectivePlane(self): EXAMPLES:: sage: P = delta_complexes.RealProjectivePlane() - sage: P.cohomology(1) + sage: P.cohomology(1) # optional - sage.modules 0 - sage: P.cohomology(2) + sage: P.cohomology(2) # optional - sage.modules C2 - sage: P.cohomology(dim=1, base_ring=GF(2)) + sage: P.cohomology(dim=1, base_ring=GF(2)) # optional - sage.modules sage.rings.finite_rings Vector space of dimension 1 over Finite Field of size 2 - sage: P.cohomology(dim=2, base_ring=GF(2)) + sage: P.cohomology(dim=2, base_ring=GF(2)) # optional - sage.modules sage.rings.finite_rings Vector space of dimension 1 over Finite Field of size 2 """ return DeltaComplex((((), ()), ((1, 0), (1, 0), (0, 0)), @@ -1744,9 +1744,9 @@ def SurfaceOfGenus(self, g, orientable=True): sage: delta_complexes.SurfaceOfGenus(1, orientable=False) Delta complex with 2 vertices and 8 simplices - sage: delta_complexes.SurfaceOfGenus(3, orientable=False).homology(1) + sage: delta_complexes.SurfaceOfGenus(3, orientable=False).homology(1) # optional - sage.modules Z x Z x C2 - sage: delta_complexes.SurfaceOfGenus(3, orientable=False).homology(2) + sage: delta_complexes.SurfaceOfGenus(3, orientable=False).homology(2) # optional - sage.modules 0 Compare to simplicial complexes:: @@ -1757,7 +1757,7 @@ def SurfaceOfGenus(self, g, orientable=True): sage: simpl_g4 = simplicial_complexes.SurfaceOfGenus(4) sage: simpl_g4.f_vector() [1, 19, 75, 50] - sage: delta_g4.homology() == simpl_g4.homology() + sage: delta_g4.homology() == simpl_g4.homology() # optional - sage.modules True """ try: diff --git a/src/sage/topology/filtered_simplicial_complex.py b/src/sage/topology/filtered_simplicial_complex.py index a8193680b29..f99f41dd81a 100644 --- a/src/sage/topology/filtered_simplicial_complex.py +++ b/src/sage/topology/filtered_simplicial_complex.py @@ -21,20 +21,20 @@ Sage can compute persistent homology of simplicial complexes:: sage: X = FilteredSimplicialComplex([([0], 0), ([1], 0), ([0, 1], 1)]) - sage: X.persistence_intervals(0) + sage: X.persistence_intervals(0) # optional - sage.rings.finite_rings [(0, 1), (0, +Infinity)] FilteredSimplicialComplex objects are mutable. Filtration values can be set with the ``filtration`` method as follows:: sage: X = FilteredSimplicialComplex() # returns an empty complex - sage: X.persistence_intervals(1) + sage: X.persistence_intervals(1) # optional - sage.rings.finite_rings [] sage: X.filtration(Simplex([0, 2]), 0) # recursively adds faces sage: X.filtration(Simplex([0, 1]), 0) sage: X.filtration(Simplex([1, 2]), 0) sage: X.filtration(Simplex([0, 1, 2]), 1) # closes the circle - sage: X.persistence_intervals(1) + sage: X.persistence_intervals(1) # optional - sage.rings.finite_rings [(0, 1)] The filtration value of a simplex can be accessed as well with the @@ -394,7 +394,7 @@ def _persistent_homology(self, field=2, strict=True, verbose=False): EXAMPLES:: sage: X = FilteredSimplicialComplex([([0], 0), ([1], 0), ([0,1], 2)]) - sage: X._persistent_homology()[0] + sage: X._persistent_homology()[0] # optional - sage.rings.finite_rings [(0, 2), (0, +Infinity)] Some homology elements may have a lifespan or persistence of 0. @@ -402,7 +402,7 @@ def _persistent_homology(self, field=2, strict=True, verbose=False): sage: X = FilteredSimplicialComplex() sage: X.insert([0,1],1) # opens a hole and closes it instantly - sage: X._persistent_homology(strict=False)[0] + sage: X._persistent_homology(strict=False)[0] # optional - sage.rings.finite_rings [(1, 1), (1, +Infinity)] REFERENCES: @@ -417,11 +417,11 @@ def _persistent_homology(self, field=2, strict=True, verbose=False): ....: ([1, 2], 1), ([0, 3], 2), ([2, 3], 2), ([0, 2], 3), ....: ([0, 1, 2], 4), ([0, 2, 3], 5)] sage: X = FilteredSimplicialComplex(l) - sage: X.persistence_intervals(0) + sage: X.persistence_intervals(0) # optional - sage.rings.finite_rings [(0, 1), (1, 2), (0, +Infinity)] - sage: X.persistence_intervals(1) + sage: X.persistence_intervals(1) # optional - sage.rings.finite_rings [(3, 4), (2, 5)] - sage: X.persistence_intervals(0, strict=False) + sage: X.persistence_intervals(0, strict=False) # optional - sage.rings.finite_rings [(0, 1), (1, 1), (1, 2), (0, +Infinity)] """ # first, order the simplices in lexico order @@ -507,18 +507,18 @@ def _add_interval(self, s, t, intervals): TESTS:: sage: X = FilteredSimplicialComplex([([0], 0), ([1, 2], 10)]) - sage: int_list = X._persistent_homology() - sage: int_list[0] + sage: int_list = X._persistent_homology() # optional - sage.rings.finite_rings + sage: int_list[0] # optional - sage.rings.finite_rings [(0, +Infinity), (10, +Infinity)] - sage: X._add_interval(Simplex([0]), Simplex([1, 2]),int_list) - sage: int_list[0] + sage: X._add_interval(Simplex([0]), Simplex([1, 2]),int_list) # optional - sage.rings.finite_rings + sage: int_list[0] # optional - sage.rings.finite_rings [(0, +Infinity), (10, +Infinity), (0, 10)] Infinite interval:: - sage: int_list2 = [[],[]] - sage: X._add_interval(Simplex([1, 2]), None, int_list2) - sage: int_list2[1] + sage: int_list2 = [[],[]] # optional - sage.rings.finite_rings + sage: X._add_interval(Simplex([1, 2]), None, int_list2) # optional - sage.rings.finite_rings + sage: int_list2[1] # optional - sage.rings.finite_rings [(10, +Infinity)] """ # figure out dimension of homology element @@ -552,12 +552,12 @@ def _remove_pivot_rows(self, s, simplices): sage: l = [([0], 0), ([1], 0), ([2], 1), ([3], 1), ([0, 1], 1), ([1, 2], 1), ....: ([0, 3], 2), ([2, 3], 2), ([0, 2], 3), ([0, 1, 2], 4)] sage: X = FilteredSimplicialComplex(l) - sage: X._persistent_homology() + sage: X._persistent_homology() # optional - sage.rings.finite_rings [[(0, 1), (1, 2), (0, +Infinity)], [(3, 4), (2, +Infinity)], []] - sage: X._remove_pivot_rows(Simplex([0,1,2]), list(X._filtration_dict)) + sage: X._remove_pivot_rows(Simplex([0,1,2]), list(X._filtration_dict)) # optional - sage.rings.finite_rings 0 sage: X.insert([0,2,3],5) - sage: X._remove_pivot_rows(Simplex([0,2,3]), list(X._filtration_dict)) + sage: X._remove_pivot_rows(Simplex([0,2,3]), list(X._filtration_dict)) # optional - sage.rings.finite_rings B[(2, 3)] """ d = self._chaingroup() @@ -603,12 +603,12 @@ def _max_index(self, d): TESTS:: sage: X = FilteredSimplicialComplex([([0], 0), ([1], 5), ([0, 1], 18), ([0, 2, 3], 32)]) - sage: X._persistent_homology() + sage: X._persistent_homology() # optional - sage.rings.finite_rings [[(5, 18), (0, +Infinity)], [], []] - sage: a = X._chaingroup(Simplex([0, 1])) - sage: b = X._chaingroup(Simplex([0, 3])) - sage: d = a + b - sage: X._max_index(d) + sage: a = X._chaingroup(Simplex([0, 1])) # optional - sage.rings.finite_rings + sage: b = X._chaingroup(Simplex([0, 3])) # optional - sage.rings.finite_rings + sage: d = a + b # optional - sage.rings.finite_rings + sage: X._max_index(d) # optional - sage.rings.finite_rings 6 """ currmax = -1 @@ -637,7 +637,7 @@ def persistence_intervals(self, dimension, field=2, strict=True, verbose=None): EXAMPLES:: sage: X = FilteredSimplicialComplex([([0], 0), ([1], 1), ([0,1], 2)]) - sage: X.persistence_intervals(0) + sage: X.persistence_intervals(0) # optional - sage.rings.finite_rings [(1, 2), (0, +Infinity)] """ if verbose is None: @@ -672,16 +672,16 @@ def betti_number(self, k, a, b, field=2, strict=True, verbose=None): EXAMPLES:: sage: X = FilteredSimplicialComplex([([0], 0), ([1], 0), ([0,1], 2)]) - sage: X.betti_number(0, 0.5, 1) + sage: X.betti_number(0, 0.5, 1) # optional - sage.rings.finite_rings 2 - sage: X.betti_number(0, 1.5, 1) + sage: X.betti_number(0, 1.5, 1) # optional - sage.rings.finite_rings 1 If an element vanishes at time ``a + b`` exactly, it does not count towards the Betti number:: sage: X = FilteredSimplicialComplex([([0], 0), ([1], 0), ([0,1], 2)]) - sage: X.betti_number(0, 1.5, 0.5) + sage: X.betti_number(0, 1.5, 0.5) # optional - sage.rings.finite_rings 1 """ if verbose is None: diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index 9f3412543ec..d4d906512bf 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -173,8 +173,6 @@ from sage.misc.latex import latex from sage.misc.superseded import deprecation from sage.matrix.constructor import matrix -from sage.homology.chain_complex import ChainComplex -from sage.graphs.graph import Graph from functools import total_ordering from itertools import combinations, chain lazy_import('sage.categories.simplicial_complexes', 'SimplicialComplexes') @@ -1474,12 +1472,12 @@ def g_vector(self): EXAMPLES:: - sage: S3 = simplicial_complexes.Sphere(3).barycentric_subdivision() - sage: S3.f_vector() + sage: S3 = simplicial_complexes.Sphere(3).barycentric_subdivision() # optional - sage.combinat sage.graphs + sage: S3.f_vector() # optional - sage.combinat sage.graphs [1, 30, 150, 240, 120] - sage: S3.h_vector() + sage: S3.h_vector() # optional - sage.combinat sage.graphs [1, 26, 66, 26, 1] - sage: S3.g_vector() + sage: S3.g_vector() # optional - sage.combinat sage.graphs [1, 25, 40] """ d = self.dimension() @@ -1601,14 +1599,14 @@ def F_triangle(self, S): EXAMPLES:: sage: cs = simplicial_complexes.Torus() - sage: cs.F_triangle(cs.facets()[0]) + sage: cs.F_triangle(cs.facets()[0]) # optional - sage.combinat F: x^3 + 9*x^2*y + 3*x*y^2 + y^3 + 6*x^2 + 12*x*y + 3*y^2 + 4*x + 3*y + 1 TESTS:: sage: S = SimplicialComplex([]) - sage: S.F_triangle(S.facets()[0]) + sage: S.F_triangle(S.facets()[0]) # optional - sage.combinat F: 1 """ x, y = polygens(ZZ, 'x, y') @@ -1626,8 +1624,8 @@ def posi(f): def flip_graph(self): """ - If ``self`` is pure, then it returns the flip graph of ``self``, - otherwise, it returns ``None``. + If ``self`` is pure, return the flip graph of ``self``, + otherwise, return ``None``. The flip graph of a pure simplicial complex is the (undirected) graph with vertices being the facets, such that two facets are joined by @@ -1638,29 +1636,29 @@ def flip_graph(self): EXAMPLES:: sage: S0 = simplicial_complexes.Sphere(0) - sage: G = S0.flip_graph() - sage: G.vertices(sort=True); G.edges(sort=True, labels=False) + sage: G = S0.flip_graph() # optional - sage.graphs + sage: G.vertices(sort=True); G.edges(sort=True, labels=False) # optional - sage.graphs [(0,), (1,)] [((0,), (1,))] - sage: G = (S0.wedge(S0)).flip_graph() - sage: G.vertices(sort=True); G.edges(sort=True, labels=False) + sage: G = (S0.wedge(S0)).flip_graph() # optional - sage.graphs + sage: G.vertices(sort=True); G.edges(sort=True, labels=False) # optional - sage.graphs [(0,), ('L1',), ('R1',)] [((0,), ('L1',)), ((0,), ('R1',)), (('L1',), ('R1',))] sage: S1 = simplicial_complexes.Sphere(1) sage: S2 = simplicial_complexes.Sphere(2) - sage: G = (S1.wedge(S1)).flip_graph() - sage: len(G.vertices(sort=False)) + sage: G = (S1.wedge(S1)).flip_graph() # optional - sage.graphs + sage: len(G.vertices(sort=False)) # optional - sage.graphs 6 - sage: len(G.edges(sort=False)) + sage: len(G.edges(sort=False)) # optional - sage.graphs 10 - sage: (S1.wedge(S2)).flip_graph() is None + sage: (S1.wedge(S2)).flip_graph() is None # optional - sage.graphs True - sage: G = S2.flip_graph() - sage: G.vertices(sort=True); G.edges(sort=True, labels=False) + sage: G = S2.flip_graph() # optional - sage.graphs + sage: G.vertices(sort=True); G.edges(sort=True, labels=False) # optional - sage.graphs [(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)] [((0, 1, 2), (0, 1, 3)), ((0, 1, 2), (0, 2, 3)), @@ -1669,13 +1667,15 @@ def flip_graph(self): ((0, 1, 3), (1, 2, 3)), ((0, 2, 3), (1, 2, 3))] - sage: T = simplicial_complexes.Torus() - sage: G = T.suspension(4).flip_graph() - sage: len(G.vertices(sort=False)); len(G.edges(sort=False, labels=False)) + sage: T = simplicial_complexes.Torus() # optional - sage.graphs + sage: G = T.suspension(4).flip_graph() # optional - sage.graphs + sage: len(G.vertices(sort=False)); len(G.edges(sort=False, labels=False)) # optional - sage.graphs 46 161 """ from collections import defaultdict + from sage.graphs.graph import Graph + if not self.is_pure(): return None d = self.dimension() @@ -1699,7 +1699,7 @@ def flip_graph(self): def is_pseudomanifold(self): """ - Return True if self is a pseudomanifold. + Return True if ``self`` is a pseudomanifold. A pseudomanifold is a simplicial complex with the following properties: @@ -1720,20 +1720,20 @@ def is_pseudomanifold(self): EXAMPLES:: sage: S0 = simplicial_complexes.Sphere(0) - sage: S0.is_pseudomanifold() + sage: S0.is_pseudomanifold() # optional - sage.graphs True - sage: (S0.wedge(S0)).is_pseudomanifold() + sage: (S0.wedge(S0)).is_pseudomanifold() # optional - sage.graphs False sage: S1 = simplicial_complexes.Sphere(1) sage: S2 = simplicial_complexes.Sphere(2) - sage: (S1.wedge(S1)).is_pseudomanifold() + sage: (S1.wedge(S1)).is_pseudomanifold() # optional - sage.graphs False - sage: (S1.wedge(S2)).is_pseudomanifold() + sage: (S1.wedge(S2)).is_pseudomanifold() # optional - sage.graphs False - sage: S2.is_pseudomanifold() + sage: S2.is_pseudomanifold() # optional - sage.graphs True sage: T = simplicial_complexes.Torus() - sage: T.suspension(4).is_pseudomanifold() + sage: T.suspension(4).is_pseudomanifold() # optional - sage.graphs True """ if not self.is_pure(): @@ -1858,7 +1858,8 @@ def join(self, right, rename_vertices=True, is_mutable=True): sage: S.join(T) Simplicial complex with vertex set ('L0', 'L1', 'R2', 'R3') and 4 facets sage: S.join(T, rename_vertices=False) - Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2), (0, 3), (1, 2), (1, 3)} + Simplicial complex with vertex set (0, 1, 2, 3) + and facets {(0, 2), (0, 3), (1, 2), (1, 3)} The notation '*' may be used, as well:: @@ -1938,7 +1939,7 @@ def suspension(self, n=1, is_mutable=True): sage: S0 = SimplicialComplex([[0], [1]]) sage: S0.suspension() == simplicial_complexes.Sphere(1) True - sage: S3 = S0.suspension(3) # the 3-sphere + sage: S3 = S0.suspension(3) # the 3-sphere # optional - sage.graphs sage: S3.homology() {0: 0, 1: 0, 2: 0, 3: Z} @@ -2217,6 +2218,8 @@ def chain_complex(self, subcomplex=None, augmented=False, current = self._n_cells_sorted(n-1, subcomplex=subcomplex) differentials[n-1] = matrix(base_ring, 0, len(current)) # finally, return the chain complex + from sage.homology.chain_complex import ChainComplex + if cochain: return ChainComplex(data=differentials, degree=1, base_ring=base_ring, check=check) @@ -2312,7 +2315,7 @@ def _homology_(self, dim=None, base_ring=ZZ, subcomplex=None, {0: 0, 1: 0, 2: Z} sage: sphere._homology_(reduced=False) {0: Z, 1: 0, 2: Z} - sage: sphere._homology_(base_ring=GF(2), reduced=False) + sage: sphere._homology_(base_ring=GF(2), reduced=False) # optional - sage.rings.finite_rings {0: Vector space of dimension 1 over Finite Field of size 2, 1: Vector space of dimension 0 over Finite Field of size 2, 2: Vector space of dimension 1 over Finite Field of size 2} @@ -2479,9 +2482,9 @@ def algebraic_topological_model(self, base_ring=None): EXAMPLES:: - sage: RP2 = simplicial_complexes.RealProjectivePlane() - sage: phi, M = RP2.algebraic_topological_model(GF(2)) - sage: M.homology() + sage: RP2 = simplicial_complexes.RealProjectivePlane() # optional - sage.rings.finite_rings + sage: phi, M = RP2.algebraic_topological_model(GF(2)) # optional - sage.rings.finite_rings + sage: M.homology() # optional - sage.rings.finite_rings {0: Vector space of dimension 1 over Finite Field of size 2, 1: Vector space of dimension 1 over Finite Field of size 2, 2: Vector space of dimension 1 over Finite Field of size 2} @@ -3583,8 +3586,7 @@ def barycentric_subdivision(self): EXAMPLES:: sage: triangle = SimplicialComplex([[0,1], [1,2], [0, 2]]) - sage: hexagon = triangle.barycentric_subdivision() - sage: hexagon + sage: hexagon = triangle.barycentric_subdivision(); hexagon # optional - sage.combinat sage.graphs Simplicial complex with 6 vertices and 6 facets sage: hexagon.homology(1) == triangle.homology(1) True @@ -3699,12 +3701,14 @@ def graph(self): EXAMPLES:: sage: S = SimplicialComplex([[0,1,2,3]]) - sage: G = S.graph(); G + sage: G = S.graph(); G # optional - sage.graphs Graph on 4 vertices - sage: G.edges(sort=True) + sage: G.edges(sort=True) # optional - sage.graphs [(0, 1, None), (0, 2, None), (0, 3, None), (1, 2, None), (1, 3, None), (2, 3, None)] """ if self._graph is None: + from sage.graphs.graph import Graph + edges = self.n_cells(1) vertices = [min(f) for f in self._facets if f.dimension() == 0] used_vertices = [] # vertices which are in an edge @@ -3774,11 +3778,11 @@ def is_flag_complex(self): EXAMPLES:: - sage: h = Graph({0:[1,2,3,4],1:[2,3,4],2:[3]}) - sage: x = h.clique_complex() - sage: x - Simplicial complex with vertex set (0, 1, 2, 3, 4) and facets {(0, 1, 4), (0, 1, 2, 3)} - sage: x.is_flag_complex() + sage: h = Graph({0: [1,2,3,4], 1: [2,3,4], 2: [3]}) # optional - sage.graphs + sage: x = h.clique_complex(); x # optional - sage.graphs + Simplicial complex with vertex set (0, 1, 2, 3, 4) + and facets {(0, 1, 4), (0, 1, 2, 3)} + sage: x.is_flag_complex() # optional - sage.graphs True sage: X = simplicial_complexes.ChessboardComplex(3,3) @@ -4015,20 +4019,22 @@ def connected_component(self, simplex=None): EXAMPLES:: sage: S1 = simplicial_complexes.Sphere(1) - sage: S1 == S1.connected_component() + sage: S1 == S1.connected_component() # optional - sage.graphs True sage: X = S1.disjoint_union(S1) - sage: X == X.connected_component() + sage: X == X.connected_component() # optional - sage.graphs False - sage: X.connected_component(Simplex(['L0'])) == X.connected_component(Simplex(['R0'])) + sage: CL0 = X.connected_component(Simplex(['L0'])) # optional - sage.graphs + sage: CR0 = X.connected_component(Simplex(['R0'])) # optional - sage.graphs + sage: CL0 == CR0 # optional - sage.graphs False sage: S0 = simplicial_complexes.Sphere(0) sage: S0.vertices() (0, 1) - sage: S0.connected_component() + sage: S0.connected_component() # optional - sage.graphs Simplicial complex with vertex set (0,) and facets {(0,)} - sage: S0.connected_component(Simplex((1,))) + sage: S0.connected_component(Simplex((1,))) # optional - sage.graphs Simplicial complex with vertex set (1,) and facets {(1,)} sage: SimplicialComplex([[]]).connected_component() @@ -4075,51 +4081,51 @@ def fundamental_group(self, base_point=None, simplify=True): EXAMPLES:: sage: S1 = simplicial_complexes.Sphere(1) - sage: S1.fundamental_group() + sage: S1.fundamental_group() # optional - sage.graphs sage.groups Finitely presented group < e | > If we pass the argument ``simplify=False``, we get generators and relations in a form which is not usually very helpful. Here is the cyclic group of order 2, for instance:: - sage: RP2 = simplicial_complexes.RealProjectiveSpace(2) - sage: C2 = RP2.fundamental_group(simplify=False) - sage: C2 - Finitely presented group < e0, e1, e2, e3, e4, e5, e6, e7, e8, e9 | e0, e3, e4, e7, e9, e5*e2^-1*e0, e7*e2^-1*e1, e8*e3^-1*e1, e8*e6^-1*e4, e9*e6^-1*e5 > - sage: C2.simplified() + sage: RP2 = simplicial_complexes.RealProjectiveSpace(2) # optional - sage.libs.pari + sage: C2 = RP2.fundamental_group(simplify=False); C2 # optional - sage.graphs sage.groups sage.libs.pari + Finitely presented group < e0, e1, e2, e3, e4, e5, e6, e7, e8, e9 | e0, e3, + e4, e7, e9, e5*e2^-1*e0, e7*e2^-1*e1, e8*e3^-1*e1, e8*e6^-1*e4, e9*e6^-1*e5 > + sage: C2.simplified() # optional - sage.graphs sage.groups sage.libs.pari Finitely presented group < e1 | e1^2 > This is the same answer given if the argument ``simplify`` is True (the default):: - sage: RP2.fundamental_group() + sage: RP2.fundamental_group() # optional - sage.graphs sage.groups sage.libs.pari Finitely presented group < e1 | e1^2 > You must specify a base point to compute the fundamental group of a non-connected complex:: - sage: K = S1.disjoint_union(RP2) - sage: K.fundamental_group() + sage: K = S1.disjoint_union(RP2) # optional - sage.graphs sage.groups sage.libs.pari + sage: K.fundamental_group() # optional - sage.graphs sage.groups sage.libs.pari Traceback (most recent call last): ... ValueError: this complex is not connected, so you must specify a base point - sage: K.fundamental_group(base_point='L0') + sage: K.fundamental_group(base_point='L0') # optional - sage.graphs sage.groups sage.libs.pari Finitely presented group < e | > - sage: K.fundamental_group(base_point='R0').order() + sage: K.fundamental_group(base_point='R0').order() # optional - sage.graphs sage.groups sage.libs.pari 2 Some other examples:: - sage: S1.wedge(S1).fundamental_group() + sage: S1.wedge(S1).fundamental_group() # optional - sage.graphs sage.groups Finitely presented group < e0, e1 | > - sage: simplicial_complexes.Torus().fundamental_group() + sage: simplicial_complexes.Torus().fundamental_group() # optional - sage.graphs sage.groups Finitely presented group < e1, e4 | e4^-1*e1^-1*e4*e1 > - sage: G = simplicial_complexes.MooreSpace(5).fundamental_group() - sage: G.ngens() + sage: G = simplicial_complexes.MooreSpace(5).fundamental_group() # optional - sage.graphs sage.groups + sage: G.ngens() # optional - sage.graphs sage.groups 1 - sage: x = G.gen(0) - sage: [(x**n).is_one() for n in range(1,6)] + sage: x = G.gen(0) # optional - sage.graphs sage.groups + sage: [(x**n).is_one() for n in range(1,6)] # optional - sage.graphs sage.groups [False, False, False, False, True] """ if not self.is_connected(): @@ -4188,18 +4194,18 @@ def is_isomorphic(self, other, certificate=False): sage: Z1 = SimplicialComplex([[0,1],[1,2],[2,3,4],[4,5]]) sage: Z2 = SimplicialComplex([['a','b'],['b','c'],['c','d','e'],['e','f']]) sage: Z3 = SimplicialComplex([[1,2,3]]) - sage: Z1.is_isomorphic(Z2) + sage: Z1.is_isomorphic(Z2) # optional - sage.graphs True - sage: Z1.is_isomorphic(Z2, certificate=True) + sage: Z1.is_isomorphic(Z2, certificate=True) # optional - sage.graphs (True, {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f'}) - sage: Z3.is_isomorphic(Z2) + sage: Z3.is_isomorphic(Z2) # optional - sage.graphs False We check that :trac:`20751` is fixed:: sage: C1 = SimplicialComplex([[1,2,3], [2,4], [3,5], [5,6]]) sage: C2 = SimplicialComplex([['a','b','c'], ['b','d'], ['c','e'], ['e','f']]) - sage: C1.is_isomorphic(C2, certificate=True) + sage: C1.is_isomorphic(C2, certificate=True) # optional - sage.graphs (True, {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f'}) """ # Check easy invariants agree @@ -4207,6 +4213,9 @@ def is_isomorphic(self, other, certificate=False): != sorted(x.dimension() for x in other._facets) or len(self.vertices()) != len(other.vertices())): return False + + from sage.graphs.graph import Graph + g1 = Graph() g2 = Graph() # With Python 3, "is_isomorphic" for graphs works best if the @@ -4252,27 +4261,28 @@ def automorphism_group(self): EXAMPLES:: sage: S = simplicial_complexes.Simplex(3) - sage: S.automorphism_group().is_isomorphic(SymmetricGroup(4)) + sage: S.automorphism_group().is_isomorphic(SymmetricGroup(4)) # optional - sage.graphs True sage: P = simplicial_complexes.RealProjectivePlane() - sage: P.automorphism_group().is_isomorphic(AlternatingGroup(5)) + sage: P.automorphism_group().is_isomorphic(AlternatingGroup(5)) # optional - sage.graphs True sage: Z = SimplicialComplex([['1','2'],['2','3','a']]) - sage: Z.automorphism_group().is_isomorphic(CyclicPermutationGroup(2)) + sage: Z.automorphism_group().is_isomorphic(CyclicPermutationGroup(2)) # optional - sage.graphs True - sage: group = Z.automorphism_group() - sage: sorted(group.domain()) + sage: group = Z.automorphism_group() # optional - sage.graphs + sage: sorted(group.domain()) # optional - sage.graphs ['1', '2', '3', 'a'] Check that :trac:`17032` is fixed:: sage: s = SimplicialComplex([[(0,1),(2,3)]]) - sage: s.automorphism_group().cardinality() + sage: s.automorphism_group().cardinality() # optional - sage.graphs 2 """ from sage.groups.perm_gps.permgroup import PermutationGroup + from sage.graphs.graph import Graph G = Graph() G.add_vertices(self.vertices()) @@ -4309,26 +4319,25 @@ def fixed_complex(self, G): sage: S4 = simplicial_complexes.Sphere(4) sage: S3 = simplicial_complexes.Sphere(3) - sage: fix = S4.fixed_complex([S4.automorphism_group()([(0,1)])]) - sage: fix + sage: fix = S4.fixed_complex([S4.automorphism_group()([(0,1)])]); fix # optional - sage.groups Simplicial complex with vertex set (0, 2, 3, 4, 5) and 5 facets - sage: fix.is_isomorphic(S3) + sage: fix.is_isomorphic(S3) # optional - sage.groups True Another simple example:: sage: T = SimplicialComplex([[1,2,3],[2,3,4]]) - sage: G = T.automorphism_group() - sage: T.fixed_complex([G([(1,4)])]) + sage: G = T.automorphism_group() # optional - sage.groups + sage: T.fixed_complex([G([(1,4)])]) # optional - sage.groups Simplicial complex with vertex set (2, 3) and facets {(2, 3)} A more sophisticated example:: sage: RP2 = simplicial_complexes.ProjectivePlane() sage: CP2 = simplicial_complexes.ComplexProjectivePlane() - sage: G = CP2.automorphism_group() - sage: H = G.subgroup([G([(2,3),(5,6),(8,9)])]) - sage: CP2.fixed_complex(H).is_isomorphic(RP2) + sage: G = CP2.automorphism_group() # optional - sage.groups + sage: H = G.subgroup([G([(2,3),(5,6),(8,9)])]) # optional - sage.groups + sage: CP2.fixed_complex(H).is_isomorphic(RP2) # optional - sage.groups True """ from sage.categories.groups import Groups @@ -4621,7 +4630,8 @@ def decone(self): sage: SimplicialComplex([[1,2,3]]).decone() Simplicial complex with vertex set () and facets {()} sage: SimplicialComplex([[1,2,3], [1,3,4], [1,5,6]]).decone() - Simplicial complex with vertex set (2, 3, 4, 5, 6) and facets {(2, 3), (3, 4), (5, 6)} + Simplicial complex with vertex set (2, 3, 4, 5, 6) + and facets {(2, 3), (3, 4), (5, 6)} sage: X = SimplicialComplex([[1,2,3], [1,3,4], [2,5,6]]) sage: X.decone() == X True @@ -4653,29 +4663,29 @@ def is_balanced(self, check_purity=False, certificate=False): A 1-dim simplicial complex is balanced iff it is bipartite:: - sage: X = SimplicialComplex([[1,2],[1,4],[3,4],[2,5]]) - sage: X.is_balanced() + sage: X = SimplicialComplex([[1,2], [1,4], [3,4], [2,5]]) + sage: X.is_balanced() # optional - sage.graphs True - sage: sorted(X.is_balanced(certificate=True)) + sage: sorted(X.is_balanced(certificate=True)) # optional - sage.graphs [[1, 3, 5], [2, 4]] - sage: X = SimplicialComplex([[1,2],[1,4],[3,4],[2,4]]) - sage: X.is_balanced() + sage: X = SimplicialComplex([[1,2], [1,4], [3,4], [2,4]]) + sage: X.is_balanced() # optional - sage.graphs False Any barycentric division is balanced:: - sage: X = SimplicialComplex([[1,2,3],[1,2,4],[2,3,4]]) - sage: X.is_balanced() + sage: X = SimplicialComplex([[1,2,3], [1,2,4], [2,3,4]]) + sage: X.is_balanced() # optional - sage.graphs False - sage: X.barycentric_subdivision().is_balanced() + sage: X.barycentric_subdivision().is_balanced() # optional - sage.graphs True A non-pure balanced complex:: - sage: X=SimplicialComplex([[1,2,3],[3,4]]) - sage: X.is_balanced(check_purity=True) + sage: X = SimplicialComplex([[1,2,3], [3,4]]) + sage: X.is_balanced(check_purity=True) # optional - sage.graphs False - sage: sorted(X.is_balanced(certificate=True)) + sage: sorted(X.is_balanced(certificate=True)) # optional - sage.graphs [[1, 4], [2], [3]] """ d = 1 + self.dimension() @@ -4730,7 +4740,7 @@ def is_partitionable(self, certificate=False, Simplices are trivially partitionable:: - sage: X = SimplicialComplex([ [1,2,3,4] ]) + sage: X = SimplicialComplex([[1,2,3,4]]) sage: X.is_partitionable() True sage: X.is_partitionable(certificate=True) @@ -4738,23 +4748,27 @@ def is_partitionable(self, certificate=False, Shellable complexes are partitionable:: - sage: X = SimplicialComplex([ [1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5],[2,3,6],[2,4,5] ]) + sage: X = SimplicialComplex([[1,3,5], [1,3,6], [1,4,5], [1,4,6], + ....: [2,3,5], [2,3,6], [2,4,5]]) sage: X.is_partitionable() True sage: P = X.is_partitionable(certificate=True) - sage: n_intervals_containing = lambda f: len([ RF for RF in P if RF[0].is_face(f) and f.is_face(RF[1]) ]) - sage: all( n_intervals_containing(f)==1 for k in X.faces().keys() for f in X.faces()[k] ) + sage: def n_intervals_containing(f): + ....: return len([RF for RF in P + ....: if RF[0].is_face(f) and f.is_face(RF[1])]) + sage: all(n_intervals_containing(f) == 1 + ....: for k in X.faces().keys() for f in X.faces()[k]) True A non-shellable, non-Cohen-Macaulay, partitionable example, constructed by Björner:: - sage: X = SimplicialComplex([ [1,2,3],[1,2,4],[1,3,4],[2,3,4],[1,5,6] ]) + sage: X = SimplicialComplex([[1,2,3], [1,2,4], [1,3,4], [2,3,4], [1,5,6]]) sage: X.is_partitionable() True The bowtie complex is not partitionable:: - sage: X = SimplicialComplex([ [1,2,3],[1,4,5] ]) + sage: X = SimplicialComplex([[1,2,3], [1,4,5]]) sage: X.is_partitionable() False """ @@ -4785,9 +4799,9 @@ def intersection(self, other): EXAMPLES:: - sage: X = SimplicialComplex([[1,2,3],[1,2,4]]) - sage: Y = SimplicialComplex([[1,2,3],[1,4,5]]) - sage: Z = SimplicialComplex([[1,2,3],[1,4],[2,4]]) + sage: X = SimplicialComplex([[1,2,3], [1,2,4]]) + sage: Y = SimplicialComplex([[1,2,3], [1,4,5]]) + sage: Z = SimplicialComplex([[1,2,3], [1,4], [2,4]]) sage: sorted(X.intersection(Y).facets()) [(1, 2, 3), (1, 4)] sage: X.intersection(X) == X diff --git a/src/sage/topology/simplicial_complex_examples.py b/src/sage/topology/simplicial_complex_examples.py index a1403bcd43c..084d2687a8a 100644 --- a/src/sage/topology/simplicial_complex_examples.py +++ b/src/sage/topology/simplicial_complex_examples.py @@ -229,7 +229,7 @@ def __classcall__(self, maximal_faces=None, name=None, **kwds): Testing ``from_characteristic_function``:: - sage: UniqueSimplicialComplex(from_characteristic_function=(lambda x:sum(x)<=4, range(5))) + sage: UniqueSimplicialComplex(from_characteristic_function=(lambda x: sum(x) <= 4, range(5))) Simplicial complex with vertex set (0, 1, 2, 3, 4) and facets {(0, 4), (0, 1, 2), (0, 1, 3)} """ char_fcn = kwds.get('from_characteristic_function', None) @@ -469,7 +469,7 @@ def MooreSpace(q): INPUT: - - ``q`` -0 integer, at least 2 + - ``q`` -- integer, at least 2 This is a simplicial complex with simplices of dimension 0, 1, and 2, such that its reduced homology is isomorphic to @@ -572,14 +572,14 @@ def QuaternionicProjectivePlane(): EXAMPLES:: - sage: HP2 = simplicial_complexes.QuaternionicProjectivePlane() ; HP2 + sage: HP2 = simplicial_complexes.QuaternionicProjectivePlane(); HP2 # optional - sage.groups Simplicial complex with 15 vertices and 490 facets - sage: HP2.f_vector() + sage: HP2.f_vector() # optional - sage.groups [1, 15, 105, 455, 1365, 3003, 4515, 4230, 2205, 490] Checking its automorphism group:: - sage: HP2.automorphism_group().is_isomorphic(AlternatingGroup(5)) + sage: HP2.automorphism_group().is_isomorphic(AlternatingGroup(5)) # optional - sage.groups True """ from sage.groups.perm_gps.permgroup import PermutationGroup @@ -852,7 +852,7 @@ def K3Surface(): EXAMPLES:: - sage: K3=simplicial_complexes.K3Surface() ; K3 + sage: K3 = simplicial_complexes.K3Surface(); K3 Minimal triangulation of the K3 surface sage: K3.f_vector() [1, 16, 120, 560, 720, 288] @@ -975,7 +975,7 @@ def BarnetteSphere(): EXAMPLES:: - sage: BS = simplicial_complexes.BarnetteSphere() ; BS + sage: BS = simplicial_complexes.BarnetteSphere(); BS Barnette's triangulation of the 3-sphere sage: BS.f_vector() [1, 8, 27, 38, 19] @@ -992,7 +992,7 @@ def BarnetteSphere(): ....: [3, 4, 5, 8], [4, 5, 6, 8], [1, 2, 6, 8], ....: [1, 5, 6, 8], [1, 3, 5, 8], [2, 4, 6, 8], ....: [1, 3, 5, 7]]) - sage: BS.is_isomorphic(BS2) + sage: BS.is_isomorphic(BS2) # optional - sage.graphs True """ return UniqueSimplicialComplex([ @@ -1018,7 +1018,7 @@ def BrucknerGrunbaumSphere(): EXAMPLES:: - sage: BGS = simplicial_complexes.BrucknerGrunbaumSphere() ; BGS + sage: BGS = simplicial_complexes.BrucknerGrunbaumSphere(); BGS Bruckner and Grunbaum's triangulation of the 3-sphere sage: BGS.f_vector() [1, 8, 28, 40, 20] @@ -1116,8 +1116,7 @@ def MatchingComplex(n): EXAMPLES:: sage: M = simplicial_complexes.MatchingComplex(7) - sage: H = M.homology() - sage: H + sage: H = M.homology(); H {0: 0, 1: C3, 2: Z^20} sage: H[2].ngens() 20 @@ -1401,15 +1400,15 @@ def RandomTwoSphere(n): EXAMPLES:: - sage: G = simplicial_complexes.RandomTwoSphere(6); G + sage: G = simplicial_complexes.RandomTwoSphere(6); G # optional - sage.graphs Simplicial complex with vertex set (0, 1, 2, 3, 4, 5) and 8 facets - sage: G.homology() + sage: G.homology() # optional - sage.graphs {0: 0, 1: 0, 2: Z} - sage: G.is_pure() + sage: G.is_pure() # optional - sage.graphs True - sage: fg = G.flip_graph(); fg + sage: fg = G.flip_graph(); fg # optional - sage.graphs Graph on 8 vertices - sage: fg.is_planar() and fg.is_regular(3) + sage: fg.is_planar() and fg.is_regular(3) # optional - sage.graphs True """ from sage.graphs.generators.random import RandomTriangulation @@ -1448,14 +1447,14 @@ def ShiftedComplex(generators): EXAMPLES:: - sage: X = simplicial_complexes.ShiftedComplex([ Simplex([1, 6]), (2, 4), [8] ]) - sage: sorted(X.facets()) + sage: X = simplicial_complexes.ShiftedComplex([Simplex([1, 6]), (2, 4), [8]]) # optional - sage.combinat + sage: sorted(X.facets()) # optional - sage.combinat [(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 3), (2, 4), (7,), (8,)] - sage: X = simplicial_complexes.ShiftedComplex([ [2, 3, 5] ]) - sage: sorted(X.facets()) + sage: X = simplicial_complexes.ShiftedComplex([[2, 3, 5]]) # optional - sage.combinat + sage: sorted(X.facets()) # optional - sage.combinat [(1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5), (2, 3, 4), (2, 3, 5)] - sage: X = simplicial_complexes.ShiftedComplex([ [1, 3, 5], [2, 6] ]) - sage: sorted(X.facets()) + sage: X = simplicial_complexes.ShiftedComplex([[1, 3, 5], [2, 6]]) # optional - sage.combinat + sage: sorted(X.facets()) # optional - sage.combinat [(1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5), (1, 6), (2, 6)] """ from sage.combinat.partition import Partitions @@ -1577,14 +1576,14 @@ def FareyMap(p): EXAMPLES:: - sage: S5 = simplicial_complexes.FareyMap(5); S5 + sage: S5 = simplicial_complexes.FareyMap(5); S5 # optional - sage.groups Simplicial complex with 12 vertices and 20 facets - sage: S5.automorphism_group().cardinality() + sage: S5.automorphism_group().cardinality() # optional - sage.groups 120 - sage: S7 = simplicial_complexes.FareyMap(7); S7 + sage: S7 = simplicial_complexes.FareyMap(7); S7 # optional - sage.groups Simplicial complex with 24 vertices and 56 facets - sage: S7.f_vector() + sage: S7.f_vector() # optional - sage.groups [1, 24, 84, 56] REFERENCES: @@ -1642,7 +1641,7 @@ def GenusSix(): EXAMPLES:: sage: S = simplicial_complexes.GenusSix() - sage: S.automorphism_group().cardinality() + sage: S.automorphism_group().cardinality() # optional - sage.groups 12 sage: S.betti() {0: 1, 1: 12, 2: 1} diff --git a/src/sage/topology/simplicial_set.py b/src/sage/topology/simplicial_set.py index 321442fdc8f..305a1d2987c 100644 --- a/src/sage/topology/simplicial_set.py +++ b/src/sage/topology/simplicial_set.py @@ -41,10 +41,9 @@ sage: simplicial_sets.Torus() Torus - sage: simplicial_sets.RealProjectiveSpace(7) + sage: simplicial_sets.RealProjectiveSpace(7) # optional - sage.groups RP^7 - sage: S5 = simplicial_sets.Sphere(5) - sage: S5 + sage: S5 = simplicial_sets.Sphere(5); S5 S^5 sage: S5.nondegenerate_simplices() [v_0, sigma_5] @@ -817,14 +816,14 @@ def __deepcopy__(self, memo): copies of simplicial sets:: sage: from sage.topology.simplicial_set import SimplicialSet - sage: RP3 = simplicial_sets.RealProjectiveSpace(3) - sage: dict(copy.copy(RP3._data)) == dict(RP3._data) + sage: RP3 = simplicial_sets.RealProjectiveSpace(3) # optional - sage.groups + sage: dict(copy.copy(RP3._data)) == dict(RP3._data) # optional - sage.groups True - sage: dict(copy.deepcopy(RP3._data)) == dict(RP3._data) + sage: dict(copy.deepcopy(RP3._data)) == dict(RP3._data) # optional - sage.groups False - sage: SimplicialSet(RP3) == RP3 + sage: SimplicialSet(RP3) == RP3 # optional - sage.groups False - sage: copy.copy(RP3) == RP3 + sage: copy.copy(RP3) == RP3 # optional - sage.groups False """ underlying = self.nondegenerate() @@ -1151,11 +1150,11 @@ def faces(self, simplex): sage: S2.faces(sigma.apply_degeneracies(0)) [sigma_2, sigma_2, s_1 s_0 v_0, s_1 s_0 v_0] - sage: C3 = groups.misc.MultiplicativeAbelian([3]) - sage: BC3 = simplicial_sets.ClassifyingSpace(C3) - sage: f2 = BC3.n_cells(1)[1]; f2 + sage: C3 = groups.misc.MultiplicativeAbelian([3]) # optional - sage.groups + sage: BC3 = simplicial_sets.ClassifyingSpace(C3) # optional - sage.groups + sage: f2 = BC3.n_cells(1)[1]; f2 # optional - sage.groups f^2 - sage: BC3.faces(f2) + sage: BC3.faces(f2) # optional - sage.groups (1, 1) TESTS:: @@ -1356,11 +1355,11 @@ def nondegenerate_simplices(self, max_dim=None): Test an infinite example:: - sage: C3 = groups.misc.MultiplicativeAbelian([3]) - sage: BC3 = simplicial_sets.ClassifyingSpace(C3) - sage: BC3.nondegenerate_simplices(2) + sage: C3 = groups.misc.MultiplicativeAbelian([3]) # optional - sage.groups + sage: BC3 = simplicial_sets.ClassifyingSpace(C3) # optional - sage.groups + sage: BC3.nondegenerate_simplices(2) # optional - sage.groups [1, f, f^2, f * f, f * f^2, f^2 * f, f^2 * f^2] - sage: BC3.nondegenerate_simplices() + sage: BC3.nondegenerate_simplices() # optional - sage.groups Traceback (most recent call last): ... NotImplementedError: this simplicial set may be infinite, so specify max_dim @@ -1411,20 +1410,20 @@ def cells(self, subcomplex=None, max_dim=None): sage: S1.cells() {0: [v], 1: [e]} - sage: S0.cells(S0.subsimplicial_set([v, w])) + sage: S0.cells(S0.subsimplicial_set([v, w])) # optional - sage.graphs {0: [*]} sage: X = SimplicialSet({e: (v,w)}) - sage: X.cells(X.subsimplicial_set([v, w])) + sage: X.cells(X.subsimplicial_set([v, w])) # optional - sage.graphs {0: [*], 1: [e]} Test an infinite example:: - sage: C3 = groups.misc.MultiplicativeAbelian([3]) - sage: BC3 = simplicial_sets.ClassifyingSpace(C3) - sage: BC3.cells(max_dim=2) + sage: C3 = groups.misc.MultiplicativeAbelian([3]) # optional - sage.groups + sage: BC3 = simplicial_sets.ClassifyingSpace(C3) # optional - sage.groups + sage: BC3.cells(max_dim=2) # optional - sage.groups {0: [1], 1: [f, f^2], 2: [f * f, f * f^2, f^2 * f, f^2 * f^2]} - sage: BC3.cells() + sage: BC3.cells() # optional - sage.groups Traceback (most recent call last): ... NotImplementedError: this simplicial set may be infinite, so specify max_dim @@ -1470,9 +1469,9 @@ def n_cells(self, n, subcomplex=None): [sigma_3] sage: simplicial_sets.Sphere(3).n_cells(2) [] - sage: C2 = groups.misc.MultiplicativeAbelian([2]) - sage: BC2 = C2.nerve() - sage: BC2.n_cells(3) + sage: C2 = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: BC2 = C2.nerve() # optional - sage.groups + sage: BC2.n_cells(3) # optional - sage.groups [f * f * f] """ cells = self.cells(subcomplex=subcomplex, max_dim=n) @@ -1530,9 +1529,9 @@ def all_n_simplices(self, n): An example involving an infinite simplicial set:: - sage: C3 = groups.misc.MultiplicativeAbelian([3]) - sage: BC3 = simplicial_sets.ClassifyingSpace(C3) - sage: BC3.all_n_simplices(2) + sage: C3 = groups.misc.MultiplicativeAbelian([3]) # optional - sage.groups + sage: BC3 = simplicial_sets.ClassifyingSpace(C3) # optional - sage.groups + sage: BC3.all_n_simplices(2) # optional - sage.groups [f * f, f * f^2, f^2 * f, @@ -1576,9 +1575,10 @@ def identity(self): Simplicial set endomorphism of S^3 Defn: Identity map - sage: BC3 = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([3])) - sage: one = BC3.identity() - sage: [(sigma, one(sigma)) for sigma in BC3.n_cells(2)] + sage: C3 = groups.misc.MultiplicativeAbelian([3]) # optional - sage.groups + sage: BC3 = simplicial_sets.ClassifyingSpace(C3) # optional - sage.groups + sage: one = BC3.identity() # optional - sage.groups + sage: [(sigma, one(sigma)) for sigma in BC3.n_cells(2)] # optional - sage.groups [(f * f, f * f), (f * f^2, f * f^2), (f^2 * f, f^2 * f), @@ -1616,8 +1616,8 @@ def constant_map(self, codomain=None, point=None): To: S^0 Defn: Constant map at v_0 - sage: Sigma3 = groups.permutation.Symmetric(3) - sage: Sigma3.nerve().constant_map() + sage: Sigma3 = groups.permutation.Symmetric(3) # optional - sage.groups + sage: Sigma3.nerve().constant_map() # optional - sage.groups Simplicial set morphism: From: Nerve of Symmetric group of order 3! as a permutation group To: Point @@ -1656,8 +1656,8 @@ def graph(self): EXAMPLES:: sage: Delta3 = simplicial_sets.Simplex(3) - sage: G = Delta3.graph() - sage: G.edges(sort=True) + sage: G = Delta3.graph() # optional - sage.graphs + sage: G.edges(sort=True) # optional - sage.graphs [((0,), (1,), (0, 1)), ((0,), (2,), (0, 2)), ((0,), (3,), (0, 3)), @@ -1666,20 +1666,20 @@ def graph(self): ((2,), (3,), (2, 3))] sage: T = simplicial_sets.Torus() - sage: T.graph() + sage: T.graph() # optional - sage.graphs Looped multi-graph on 1 vertex - sage: len(T.graph().edges(sort=False)) + sage: len(T.graph().edges(sort=False)) # optional - sage.graphs 3 sage: CP3 = simplicial_sets.ComplexProjectiveSpace(3) - sage: G = CP3.graph() - sage: len(G.vertices(sort=False)) + sage: G = CP3.graph() # optional - sage.graphs + sage: len(G.vertices(sort=False)) # optional - sage.graphs 1 - sage: len(G.edges(sort=False)) + sage: len(G.edges(sort=False)) # optional - sage.graphs 0 - sage: Sigma3 = groups.permutation.Symmetric(3) - sage: Sigma3.nerve().is_connected() + sage: Sigma3 = groups.permutation.Symmetric(3) # optional - sage.groups + sage: Sigma3.nerve().is_connected() # optional - sage.graphs sage.groups True """ from sage.graphs.graph import Graph @@ -1699,14 +1699,14 @@ def is_connected(self): sage: T = simplicial_sets.Torus() sage: K = simplicial_sets.KleinBottle() - sage: X = T.disjoint_union(K) - sage: T.is_connected() + sage: X = T.disjoint_union(K) # optional - sage.graphs + sage: T.is_connected() # optional - sage.graphs True - sage: K.is_connected() + sage: K.is_connected() # optional - sage.graphs True - sage: X.is_connected() + sage: X.is_connected() # optional - sage.graphs False - sage: simplicial_sets.Sphere(0).is_connected() + sage: simplicial_sets.Sphere(0).is_connected() # optional - sage.graphs False """ return self.graph().is_connected() @@ -1740,8 +1740,7 @@ def subsimplicial_set(self, simplices): sage: f = AbstractSimplex(1, name='f') sage: X = SimplicialSet({e: (v, w), f: (w, v)}) - sage: Y = X.subsimplicial_set([e]) - sage: Y + sage: Y = X.subsimplicial_set([e]); Y Simplicial set with 3 non-degenerate simplices sage: Y.nondegenerate_simplices() [v, w, e] @@ -1757,13 +1756,12 @@ def subsimplicial_set(self, simplices): A subsimplicial set knows about its ambient space and the inclusion map into it:: - sage: RP4 = simplicial_sets.RealProjectiveSpace(4) - sage: M = RP4.n_skeleton(2) - sage: M + sage: RP4 = simplicial_sets.RealProjectiveSpace(4) # optional - sage.groups + sage: M = RP4.n_skeleton(2); M # optional - sage.groups Simplicial set with 3 non-degenerate simplices - sage: M.ambient_space() + sage: M.ambient_space() # optional - sage.groups RP^4 - sage: M.inclusion_map() + sage: M.inclusion_map() # optional - sage.groups Simplicial set morphism: From: Simplicial set with 3 non-degenerate simplices To: RP^4 @@ -1771,11 +1769,12 @@ def subsimplicial_set(self, simplices): An infinite ambient simplicial set:: - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: BxB = B.product(B) - sage: BxB.n_cells(2)[5:] + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: BxB = B.product(B) # optional - sage.groups + sage: BxB.n_cells(2)[5:] # optional - sage.groups [(s_0 f, s_1 f), (s_1 f, f * f), (s_1 f, s_0 f), (s_1 s_0 1, f * f)] - sage: BxB.subsimplicial_set(BxB.n_cells(2)[5:]) + sage: BxB.subsimplicial_set(BxB.n_cells(2)[5:]) # optional - sage.groups Simplicial set with 8 non-degenerate simplices TESTS: @@ -1913,14 +1912,14 @@ def chain_complex(self, dimensions=None, base_ring=ZZ, augmented=False, sage: simplicial_sets.Sphere(5).chain_complex() Chain complex with at most 3 nonzero terms over Integer Ring - sage: C3 = groups.misc.MultiplicativeAbelian([3]) - sage: BC3 = simplicial_sets.ClassifyingSpace(C3) - sage: BC3.chain_complex(range(4), base_ring=GF(3)) + sage: C3 = groups.misc.MultiplicativeAbelian([3]) # optional - sage.groups + sage: BC3 = simplicial_sets.ClassifyingSpace(C3) # optional - sage.groups + sage: BC3.chain_complex(range(4), base_ring=GF(3)) # optional - sage.groups sage.rings.finite_rings Chain complex with at most 4 nonzero terms over Finite Field of size 3 TESTS:: - sage: BC3.chain_complex() + sage: BC3.chain_complex() # optional - sage.groups sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: this simplicial set may be infinite, so specify dimensions when computing its chain complex @@ -1966,33 +1965,34 @@ def homology(self, dim=None, **kwds): EXAMPLES:: - sage: simplicial_sets.Sphere(5).homology() + sage: simplicial_sets.Sphere(5).homology() # optional - sage.modules {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: Z} - sage: C3 = groups.misc.MultiplicativeAbelian([3]) - sage: BC3 = simplicial_sets.ClassifyingSpace(C3) - sage: BC3.homology(range(4), base_ring=GF(3)) + sage: C3 = groups.misc.MultiplicativeAbelian([3]) # optional - sage.groups + sage: BC3 = simplicial_sets.ClassifyingSpace(C3) # optional - sage.groups + sage: BC3.homology(range(4), base_ring=GF(3)) # optional - sage.groups sage.modules sage.rings.finite_rings {0: Vector space of dimension 0 over Finite Field of size 3, 1: Vector space of dimension 1 over Finite Field of size 3, 2: Vector space of dimension 1 over Finite Field of size 3, 3: Vector space of dimension 1 over Finite Field of size 3} - sage: BC2 = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: BK = BC2.product(BC2) - sage: BK.homology(range(4)) + sage: C2 = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: BC2 = simplicial_sets.ClassifyingSpace(C2) # optional - sage.groups + sage: BK = BC2.product(BC2) # optional - sage.groups + sage: BK.homology(range(4)) # optional - sage.groups sage.modules {0: 0, 1: C2 x C2, 2: C2, 3: C2 x C2 x C2} TESTS:: sage: S3 = simplicial_sets.Sphere(3) - sage: S3.homology(0) + sage: S3.homology(0) # optional - sage.modules 0 - sage: S3.homology((0,)) + sage: S3.homology((0,)) # optional - sage.modules {0: 0} - sage: S3.homology(0, reduced=False) + sage: S3.homology(0, reduced=False) # optional - sage.modules Z - sage: BC3.homology() + sage: BC3.homology() # optional - sage.modules Traceback (most recent call last): ... NotImplementedError: this simplicial set may be infinite, so specify dimensions when computing homology @@ -2098,9 +2098,9 @@ def betti(self, dim=None, subcomplex=None): sage: simplicial_sets.Sphere(5).betti() {0: 1, 1: 0, 2: 0, 3: 0, 4: 0, 5: 1} - sage: C3 = groups.misc.MultiplicativeAbelian([3]) - sage: BC3 = simplicial_sets.ClassifyingSpace(C3) - sage: BC3.betti(range(4)) + sage: C3 = groups.misc.MultiplicativeAbelian([3]) # optional - sage.groups + sage: BC3 = simplicial_sets.ClassifyingSpace(C3) # optional - sage.groups + sage: BC3.betti(range(4)) # optional - sage.groups sage.modules {0: 1, 1: 0, 2: 0, 3: 0} """ dict = {} @@ -2140,11 +2140,11 @@ def n_chains(self, n, base_ring=ZZ, cochains=False): sage: C = S3.n_chains(3, cochains=True) sage: list(C.basis()) [\chi_sigma_3] - sage: Sigma3 = groups.permutation.Symmetric(3) - sage: BSigma3 = simplicial_sets.ClassifyingSpace(Sigma3) - sage: list(BSigma3.n_chains(1).basis()) + sage: Sigma3 = groups.permutation.Symmetric(3) # optional - sage.groups + sage: BSigma3 = simplicial_sets.ClassifyingSpace(Sigma3) # optional - sage.groups + sage: list(BSigma3.n_chains(1).basis()) # optional - sage.groups [(1,2), (1,2,3), (1,3), (1,3,2), (2,3)] - sage: list(BSigma3.n_chains(1, cochains=True).basis()) + sage: list(BSigma3.n_chains(1, cochains=True).basis()) # optional - sage.groups [\chi_(1,2), \chi_(1,2,3), \chi_(1,3), \chi_(1,3,2), \chi_(2,3)] """ if self.is_finite(): @@ -2192,29 +2192,29 @@ def quotient(self, subcomplex, vertex_name='*'): sage: e = AbstractSimplex(1, name='e') sage: f = AbstractSimplex(1, name='f') sage: X = SimplicialSet({e: (v, w), f: (v, w)}) - sage: Y = X.quotient([f]) - sage: Y.nondegenerate_simplices() + sage: Y = X.quotient([f]) # optional - sage.graphs + sage: Y.nondegenerate_simplices() # optional - sage.graphs [*, e] - sage: Y.homology(1) + sage: Y.homology(1) # optional - sage.graphs Z sage: E = SimplicialSet({e: (v, w)}) - sage: Z = E.quotient([v, w]) - sage: Z.nondegenerate_simplices() + sage: Z = E.quotient([v, w]) # optional - sage.graphs + sage: Z.nondegenerate_simplices() # optional - sage.graphs [*, e] - sage: Z.homology(1) + sage: Z.homology(1) # optional - sage.graphs Z - sage: F = E.quotient([v]) - sage: F.nondegenerate_simplices() + sage: F = E.quotient([v]) # optional - sage.graphs + sage: F.nondegenerate_simplices() # optional - sage.graphs [*, w, e] - sage: F.base_point() + sage: F.base_point() # optional - sage.graphs * sage: RP5 = simplicial_sets.RealProjectiveSpace(5) sage: RP2 = RP5.n_skeleton(2) - sage: RP5_2 = RP5.quotient(RP2) - sage: RP5_2.homology(base_ring=GF(2)) + sage: RP5_2 = RP5.quotient(RP2) # optional - sage.graphs + sage: RP5_2.homology(base_ring=GF(2)) # optional - sage.graphs sage.modules sage.rings.finite_rings {0: Vector space of dimension 0 over Finite Field of size 2, 1: Vector space of dimension 0 over Finite Field of size 2, 2: Vector space of dimension 0 over Finite Field of size 2, @@ -2222,15 +2222,16 @@ def quotient(self, subcomplex, vertex_name='*'): 4: Vector space of dimension 1 over Finite Field of size 2, 5: Vector space of dimension 1 over Finite Field of size 2} - sage: RP5_2.ambient() + sage: RP5_2.ambient() # optional - sage.graphs RP^5 - sage: RP5_2.subcomplex() + sage: RP5_2.subcomplex() # optional - sage.graphs Simplicial set with 3 non-degenerate simplices - sage: RP5_2.quotient_map() + sage: RP5_2.quotient_map() # optional - sage.graphs Simplicial set morphism: From: RP^5 To: Quotient: (RP^5/Simplicial set with 3 non-degenerate simplices) - Defn: [1, f, f * f, f * f * f, f * f * f * f, f * f * f * f * f] --> [*, s_0 *, s_1 s_0 *, f * f * f, f * f * f * f, f * f * f * f * f] + Defn: [1, f, f * f, f * f * f, f * f * f * f, f * f * f * f * f] + --> [*, s_0 *, s_1 s_0 *, f * f * f, f * f * f * f, f * f * f * f * f] Behavior of base points:: @@ -2240,7 +2241,7 @@ def quotient(self, subcomplex, vertex_name='*'): sage: L = K.subsimplicial_set([K.n_cells(1)[-1]]) sage: L.nondegenerate_simplices() [(2,), (3,), (2, 3)] - sage: K.quotient([K.n_cells(1)[-1]]).base_point() + sage: K.quotient([K.n_cells(1)[-1]]).base_point() # optional - sage.graphs * sage: K = K.set_base_point(K.n_cells(0)[0]) @@ -2249,15 +2250,14 @@ def quotient(self, subcomplex, vertex_name='*'): sage: L = K.subsimplicial_set([K.n_cells(1)[-1]]) sage: L.nondegenerate_simplices() [(2,), (3,), (2, 3)] - sage: K.quotient(L).base_point() + sage: K.quotient(L).base_point() # optional - sage.graphs (0,) TESTS:: - sage: pt = RP5.quotient(RP5.n_skeleton(5)) - sage: pt + sage: pt = RP5.quotient(RP5.n_skeleton(5)); pt # optional - sage.graphs sage.groups Quotient: (RP^5/RP^5) - sage: len(pt.nondegenerate_simplices()) + sage: len(pt.nondegenerate_simplices()) # optional - sage.graphs sage.groups 1 """ from .simplicial_set_constructions import SubSimplicialSet @@ -2303,37 +2303,37 @@ def disjoint_union(self, *others): sage: f = AbstractSimplex(1, name='f') sage: X = SimplicialSet({e: (v, v)}) sage: Y = SimplicialSet({f: (v, w)}) - sage: Z = X.disjoint_union(Y) + sage: Z = X.disjoint_union(Y) # optional - sage.graphs Since ``X`` and ``Y`` have simplices in common, Sage uses a copy of ``Y`` when constructing the disjoint union. Note the name conflict in the list of simplices: ``v`` appears twice:: - sage: Z = X.disjoint_union(Y) - sage: Z.nondegenerate_simplices() + sage: Z = X.disjoint_union(Y) # optional - sage.graphs + sage: Z.nondegenerate_simplices() # optional - sage.graphs [v, v, w, e, f] Factors and inclusion maps:: sage: T = simplicial_sets.Torus() sage: S2 = simplicial_sets.Sphere(2) - sage: A = T.disjoint_union(S2) - sage: A.factors() + sage: A = T.disjoint_union(S2) # optional - sage.graphs + sage: A.factors() # optional - sage.graphs (Torus, S^2) - sage: i = A.inclusion_map(0) - sage: i.domain() + sage: i = A.inclusion_map(0) # optional - sage.graphs + sage: i.domain() # optional - sage.graphs Torus - sage: i.codomain() + sage: i.codomain() # optional - sage.graphs Disjoint union: (Torus u S^2) Empty factors are ignored:: sage: from sage.topology.simplicial_set_examples import Empty sage: E = Empty() - sage: K = S2.disjoint_union(S2, E, E, S2) - sage: K == S2.disjoint_union(S2, S2) + sage: K = S2.disjoint_union(S2, E, E, S2) # optional - sage.graphs + sage: K == S2.disjoint_union(S2, S2) # optional - sage.graphs True - sage: K.factors() + sage: K.factors() # optional - sage.graphs (S^2, S^2, S^2) """ from .simplicial_set_constructions import DisjointUnionOfSimplicialSets, \ @@ -2364,35 +2364,40 @@ def coproduct(self, *others): sage: Y = S2.unset_base_point() sage: Z = K.unset_base_point() - sage: S2.coproduct(K).is_pointed() + sage: S2.coproduct(K).is_pointed() # optional - sage.graphs True - sage: S2.coproduct(K) + sage: S2.coproduct(K) # optional - sage.graphs Wedge: (S^2 v Klein bottle) - sage: D3.coproduct(Y, Z).is_pointed() + sage: D3.coproduct(Y, Z).is_pointed() # optional - sage.graphs False - sage: D3.coproduct(Y, Z) - Disjoint union: (3-simplex u Simplicial set with 2 non-degenerate simplices u Simplicial set with 6 non-degenerate simplices) + sage: D3.coproduct(Y, Z) # optional - sage.graphs + Disjoint union: (3-simplex u Simplicial set with 2 non-degenerate simplices + u Simplicial set with 6 non-degenerate simplices) The coproduct comes equipped with an inclusion map from each summand, as long as the summands are all finite:: - sage: S2.coproduct(K).inclusion_map(0) + sage: S2.coproduct(K).inclusion_map(0) # optional - sage.graphs Simplicial set morphism: From: S^2 To: Wedge: (S^2 v Klein bottle) Defn: [v_0, sigma_2] --> [*, sigma_2] - sage: D3.coproduct(Y, Z).inclusion_map(2) + sage: D3.coproduct(Y, Z).inclusion_map(2) # optional - sage.graphs Simplicial set morphism: From: Simplicial set with 6 non-degenerate simplices - To: Disjoint union: (3-simplex u Simplicial set with 2 non-degenerate simplices u Simplicial set with 6 non-degenerate simplices) - Defn: [Delta_{0,0}, Delta_{1,0}, Delta_{1,1}, Delta_{1,2}, Delta_{2,0}, Delta_{2,1}] --> [Delta_{0,0}, Delta_{1,0}, Delta_{1,1}, Delta_{1,2}, Delta_{2,0}, Delta_{2,1}] + To: Disjoint union: (3-simplex + u Simplicial set with 2 non-degenerate simplices + u Simplicial set with 6 non-degenerate simplices) + Defn: [Delta_{0,0}, Delta_{1,0}, Delta_{1,1}, Delta_{1,2}, Delta_{2,0}, Delta_{2,1}] + --> [Delta_{0,0}, Delta_{1,0}, Delta_{1,1}, Delta_{1,2}, Delta_{2,0}, Delta_{2,1}] TESTS:: - sage: D3.coproduct(S2, Z) + sage: D3.coproduct(S2, Z) # optional - sage.graphs Traceback (most recent call last): ... - ValueError: some, but not all, of the simplicial sets are pointed, so the categorical coproduct is not defined: the category is ambiguous + ValueError: some, but not all, of the simplicial sets are pointed, + so the categorical coproduct is not defined: the category is ambiguous """ if self.is_pointed() and all(X.is_pointed() for X in others): return self.wedge(*others) @@ -2441,7 +2446,7 @@ def product(self, *others): sage: S1 = simplicial_sets.Sphere(1) sage: T = S1.product(S1) - sage: T.homology(reduced=False) + sage: T.homology(reduced=False) # optional - sage.modules {0: Z, 1: Z x Z, 2: Z} Since ``S1`` is pointed, so is ``T``:: @@ -2541,8 +2546,7 @@ def pushout(self, *maps): sage: K = simplicial_sets.Simplex(4) sage: L = K.n_skeleton(3) - sage: S4 = L.pushout(L.constant_map(), L.inclusion_map()) - sage: S4 + sage: S4 = L.pushout(L.constant_map(), L.inclusion_map()); S4 # optional - sage.graphs Pushout of maps: Simplicial set morphism: From: Simplicial set with 30 non-degenerate simplices @@ -2551,10 +2555,22 @@ def pushout(self, *maps): Simplicial set morphism: From: Simplicial set with 30 non-degenerate simplices To: 4-simplex - Defn: [(0,), (1,), (2,), (3,), (4,), (0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4), (0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 2, 3), (0, 2, 4), (0, 3, 4), (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4), (0, 1, 2, 3), (0, 1, 2, 4), (0, 1, 3, 4), (0, 2, 3, 4), (1, 2, 3, 4)] --> [(0,), (1,), (2,), (3,), (4,), (0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4), (0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 2, 3), (0, 2, 4), (0, 3, 4), (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4), (0, 1, 2, 3), (0, 1, 2, 4), (0, 1, 3, 4), (0, 2, 3, 4), (1, 2, 3, 4)] - sage: len(S4.nondegenerate_simplices()) + Defn: [(0,), (1,), (2,), (3,), (4,), + (0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), + (2, 3), (2, 4), (3, 4), + (0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 2, 3), (0, 2, 4), + (0, 3, 4), (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4), + (0, 1, 2, 3), (0, 1, 2, 4), (0, 1, 3, 4), (0, 2, 3, 4), + (1, 2, 3, 4)] + --> [(0,), (1,), (2,), (3,), (4,), + (0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), + (2, 3), (2, 4), (3, 4), + (0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 2, 3), (0, 2, 4), (0, 3, 4), + (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4), + (0, 1, 2, 3), (0, 1, 2, 4), (0, 1, 3, 4), (0, 2, 3, 4), (1, 2, 3, 4)] + sage: len(S4.nondegenerate_simplices()) # optional - sage.graphs 2 - sage: S4.homology(4) + sage: S4.homology(4) # optional - sage.graphs sage.modules Z The associated maps:: @@ -2562,40 +2578,41 @@ def pushout(self, *maps): sage: S1 = simplicial_sets.Sphere(1) sage: T = S1.product(S1) sage: K = T.factor(0, as_subset=True) - sage: W = S1.wedge(T) # wedge, constructed as a pushout - sage: W.defining_map(1) + sage: W = S1.wedge(T) # wedge, constructed as a pushout # optional - sage.graphs + sage: W.defining_map(1) # optional - sage.graphs Simplicial set morphism: From: Point To: S^1 x S^1 Defn: Constant map at (v_0, v_0) - sage: W.structure_map(0) + sage: W.structure_map(0) # optional - sage.graphs Simplicial set morphism: From: S^1 To: Wedge: (S^1 v S^1 x S^1) Defn: [v_0, sigma_1] --> [*, sigma_1] - sage: f = S1.Hom(T)({S1.n_cells(0)[0]:K.n_cells(0)[0], S1.n_cells(1)[0]:K.n_cells(1)[0]}) + sage: f = S1.Hom(T)({S1.n_cells(0)[0]: K.n_cells(0)[0], # optional - sage.graphs sage.modules + ....: S1.n_cells(1)[0]: K.n_cells(1)[0]}) The maps `f: S^1 \to T` and `1: T \to T` induce a map `S^1 \vee T \to T`:: - sage: g = W.universal_property(f, Hom(T,T).identity()) - sage: g.domain() == W + sage: g = W.universal_property(f, Hom(T,T).identity()) # optional - sage.graphs sage.modules + sage: g.domain() == W # optional - sage.graphs sage.modules True - sage: g.codomain() == T + sage: g.codomain() == T # optional - sage.graphs sage.modules True TESTS:: sage: K = simplicial_sets.Simplex(5) - sage: K.pushout() + sage: K.pushout() # optional - sage.graphs Empty simplicial set sage: S0 = simplicial_sets.Sphere(0) sage: pt_map = S0.base_point_map() - sage: pt_map.domain().pushout(pt_map) == S0 + sage: pt_map.domain().pushout(pt_map) == S0 # optional - sage.graphs True - sage: K.pushout(K.constant_map(), pt_map) + sage: K.pushout(K.constant_map(), pt_map) # optional - sage.graphs Traceback (most recent call last): ... ValueError: the domains of the maps must be equal @@ -2682,14 +2699,15 @@ def pullback(self, *maps): sage: S1 = simplicial_sets.Sphere(1) sage: T = S1.product(S1) sage: K = T.factor(0, as_subset=True) - sage: f = S1.Hom(T)({S1.n_cells(0)[0]:K.n_cells(0)[0], S1.n_cells(1)[0]:K.n_cells(1)[0]}) - sage: D = S1.cone() # the cone C(S^1) - sage: g = D.map_from_base() # map from S^1 to C(S^1) - sage: P = T.product(D) - sage: h = P.universal_property(f, g) - sage: h.domain() == S1 + sage: f = S1.Hom(T)({S1.n_cells(0)[0]: K.n_cells(0)[0], + ....: S1.n_cells(1)[0]: K.n_cells(1)[0]}) + sage: D = S1.cone() # the cone C(S^1) # optional - sage.graphs + sage: g = D.map_from_base() # map from S^1 to C(S^1) # optional - sage.graphs + sage: P = T.product(D) # optional - sage.graphs + sage: h = P.universal_property(f, g) # optional - sage.graphs + sage: h.domain() == S1 # optional - sage.graphs True - sage: h.codomain() == P + sage: h.codomain() == P # optional - sage.graphs True TESTS:: @@ -2740,25 +2758,25 @@ def wedge(self, *others): sage: f = AbstractSimplex(1, name='f') sage: X = SimplicialSet({e: (v, v)}, base_point=v) sage: Y = SimplicialSet({f: (w, w)}, base_point=w) - sage: W = X.wedge(Y) - sage: W.nondegenerate_simplices() + sage: W = X.wedge(Y) # optional - sage.graphs + sage: W.nondegenerate_simplices() # optional - sage.graphs [*, e, f] - sage: W.homology() + sage: W.homology() # optional - sage.graphs {0: 0, 1: Z x Z} sage: S2 = simplicial_sets.Sphere(2) - sage: X.wedge(S2).homology(reduced=False) + sage: X.wedge(S2).homology(reduced=False) # optional - sage.graphs {0: Z, 1: Z, 2: Z} - sage: X.wedge(X).nondegenerate_simplices() + sage: X.wedge(X).nondegenerate_simplices() # optional - sage.graphs [*, e, e] sage: S3 = simplicial_sets.Sphere(3) - sage: W = S2.wedge(S3, S2) - sage: W.inclusion_map(2) + sage: W = S2.wedge(S3, S2) # optional - sage.graphs + sage: W.inclusion_map(2) # optional - sage.graphs Simplicial set morphism: From: S^2 To: Wedge: (S^2 v S^3 v S^2) Defn: [v_0, sigma_2] --> [*, sigma_2] - sage: W.projection_map(1) + sage: W.projection_map(1) # optional - sage.graphs Simplicial set morphism: From: Wedge: (S^2 v S^3 v S^2) To: Quotient: (Wedge: (S^2 v S^3 v S^2)/Simplicial set with 3 non-degenerate simplices) @@ -2770,15 +2788,15 @@ def wedge(self, *others): sage: S2.f_vector() [1, 0, 1] - sage: W.projection_map(2).codomain().f_vector() + sage: W.projection_map(2).codomain().f_vector() # optional - sage.graphs [1, 0, 1] - sage: (W.projection_map(2) * W.inclusion_map(2)).is_bijective() + sage: (W.projection_map(2) * W.inclusion_map(2)).is_bijective() # optional - sage.graphs True TESTS:: sage: Z = SimplicialSet({e: (v,w)}) - sage: X.wedge(Z) + sage: X.wedge(Z) # optional - sage.graphs Traceback (most recent call last): ... ValueError: the simplicial sets must be pointed @@ -2813,18 +2831,18 @@ def cone(self): sage: v = AbstractSimplex(0, name='v') sage: e = AbstractSimplex(1, name='e') sage: X = SimplicialSet({e: (v, v)}) - sage: CX = X.cone() # unreduced cone, since X not pointed - sage: CX.nondegenerate_simplices() + sage: CX = X.cone() # unreduced cone, since X not pointed # optional - sage.graphs + sage: CX.nondegenerate_simplices() # optional - sage.graphs [*, v, (v,*), e, (e,*)] - sage: CX.base_point() + sage: CX.base_point() # optional - sage.graphs * `X` as a subset of the cone, and also the map from `X`, in the unreduced case:: - sage: CX.base_as_subset() + sage: CX.base_as_subset() # optional - sage.graphs Simplicial set with 2 non-degenerate simplices - sage: CX.map_from_base() + sage: CX.map_from_base() # optional - sage.graphs Simplicial set morphism: From: Simplicial set with 2 non-degenerate simplices To: Cone of Simplicial set with 2 non-degenerate simplices @@ -2833,10 +2851,10 @@ def cone(self): In the reduced case, only the map from `X` is available:: sage: X = X.set_base_point(v) - sage: CX = X.cone() # reduced cone - sage: CX.nondegenerate_simplices() + sage: CX = X.cone() # reduced cone # optional - sage.graphs + sage: CX.nondegenerate_simplices() # optional - sage.graphs [*, e, (e,*)] - sage: CX.map_from_base() + sage: CX.map_from_base() # optional - sage.graphs Simplicial set morphism: From: Simplicial set with 2 non-degenerate simplices To: Reduced cone of Simplicial set with 2 non-degenerate simplices @@ -2871,25 +2889,25 @@ def suspension(self, n=1): EXAMPLES:: - sage: RP4 = simplicial_sets.RealProjectiveSpace(4) - sage: S1 = simplicial_sets.Sphere(1) - sage: SigmaRP4 = RP4.suspension() - sage: S1_smash_RP4 = S1.smash_product(RP4) - sage: SigmaRP4.homology() == S1_smash_RP4.homology() + sage: RP4 = simplicial_sets.RealProjectiveSpace(4) # optional - sage.groups + sage: S1 = simplicial_sets.Sphere(1) # optional - sage.groups + sage: SigmaRP4 = RP4.suspension() # optional - sage.graphs sage.groups + sage: S1_smash_RP4 = S1.smash_product(RP4) # optional - sage.graphs sage.groups + sage: SigmaRP4.homology() == S1_smash_RP4.homology() # optional - sage.graphs sage.groups True The version of the suspension obtained by the smash product is typically less efficient than the reduced suspension produced here:: - sage: SigmaRP4.f_vector() + sage: SigmaRP4.f_vector() # optional - sage.graphs sage.groups [1, 0, 1, 1, 1, 1] - sage: S1_smash_RP4.f_vector() + sage: S1_smash_RP4.f_vector() # optional - sage.graphs sage.groups [1, 1, 4, 6, 8, 5] TESTS:: - sage: RP4.suspension(-3) + sage: RP4.suspension(-3) # optional - sage.graphs sage.groups Traceback (most recent call last): ... ValueError: n must be non-negative @@ -2946,22 +2964,22 @@ def reduce(self): sage: K = simplicial_sets.Simplex(2) sage: K.is_reduced() False - sage: X = K.reduce() - sage: X.is_reduced() + sage: X = K.reduce() # optional - sage.graphs + sage: X.is_reduced() # optional - sage.graphs True ``X`` is reduced, so calling ``reduce`` on it again returns ``X`` itself:: - sage: X is X.reduce() + sage: X is X.reduce() # optional - sage.graphs True - sage: K is K.reduce() + sage: K is K.reduce() # optional - sage.graphs False Raise an error for disconnected simplicial sets:: sage: S0 = simplicial_sets.Sphere(0) - sage: S0.reduce() + sage: S0.reduce() # optional - sage.graphs Traceback (most recent call last): ... ValueError: this simplicial set is not connected @@ -3219,7 +3237,7 @@ def __init__(self, data, base_point=None, name=None, check=True, sage: skip = ["_test_pickling", "_test_elements"] sage: TestSuite(S1).run(skip=skip) sage: TestSuite(simplicial_sets.Sphere(5)).run(skip=skip) - sage: TestSuite(simplicial_sets.RealProjectiveSpace(6)).run(skip=skip) + sage: TestSuite(simplicial_sets.RealProjectiveSpace(6)).run(skip=skip) # optional - sage.groups """ def face(sigma, i): """ @@ -3556,7 +3574,7 @@ def euler_characteristic(self): EXAMPLES:: - sage: simplicial_sets.RealProjectiveSpace(4).euler_characteristic() + sage: simplicial_sets.RealProjectiveSpace(4).euler_characteristic() # optional - sage.groups 1 sage: simplicial_sets.Sphere(6).euler_characteristic() 2 @@ -3609,16 +3627,16 @@ def chain_complex(self, dimensions=None, base_ring=ZZ, augmented=False, sage: degen = v.apply_degeneracies(1, 0) # s_1 s_0 applied to v sage: sigma = AbstractSimplex(3) sage: S3 = SimplicialSet({sigma: (degen, degen, degen, degen)}) # the 3-sphere - sage: S3.chain_complex().homology() + sage: S3.chain_complex().homology() # optional - sage.modules {0: Z, 3: Z} - sage: S3.chain_complex(augmented=True).homology() + sage: S3.chain_complex(augmented=True).homology() # optional - sage.modules {-1: 0, 0: 0, 3: Z} - sage: S3.chain_complex(dimensions=range(3), base_ring=QQ).homology() + sage: S3.chain_complex(dimensions=range(3), base_ring=QQ).homology() # optional - sage.modules {0: Vector space of dimension 1 over Rational Field} - sage: RP5 = simplicial_sets.RealProjectiveSpace(5) - sage: RP2 = RP5.n_skeleton(2) - sage: RP5.chain_complex(subcomplex=RP2).homology() + sage: RP5 = simplicial_sets.RealProjectiveSpace(5) # optional - sage.groups + sage: RP2 = RP5.n_skeleton(2) # optional - sage.groups + sage: RP5.chain_complex(subcomplex=RP2).homology() # optional - sage.groups sage.modules {0: Z, 3: C2, 4: 0, 5: Z} TESTS: @@ -3627,12 +3645,13 @@ def chain_complex(self, dimensions=None, base_ring=ZZ, augmented=False, simplicial sets, and compare homology calculations:: sage: T = simplicial_complexes.Torus() - sage: T.homology() == SimplicialSet(T).homology() + sage: T.homology() == SimplicialSet(T).homology() # optional - sage.modules True - sage: RP2 = delta_complexes.RealProjectivePlane() - sage: RP2.homology() == SimplicialSet(RP2).homology() + sage: RP2 = delta_complexes.RealProjectivePlane() # optional - sage.groups sage.modules + sage: RP2.homology() == SimplicialSet(RP2).homology() # optional - sage.groups sage.modules True - sage: RP2.cohomology(base_ring=GF(2)) == SimplicialSet(RP2).cohomology(base_ring=GF(2)) + sage: cohoRP2 = RP2.cohomology(base_ring=GF(2)) # optional - sage.groups sage.modules sage.rings.finite_rings + sage: cohoRP2 == SimplicialSet(RP2).cohomology(base_ring=GF(2)) # optional - sage.groups sage.modules sage.rings.finite_rings True """ from sage.homology.chain_complex import ChainComplex diff --git a/src/sage/topology/simplicial_set_catalog.py b/src/sage/topology/simplicial_set_catalog.py index d20df19e4a1..94208f14dac 100644 --- a/src/sage/topology/simplicial_set_catalog.py +++ b/src/sage/topology/simplicial_set_catalog.py @@ -34,14 +34,14 @@ EXAMPLES:: - sage: RP10 = simplicial_sets.RealProjectiveSpace(8) - sage: RP10.homology() + sage: RP10 = simplicial_sets.RealProjectiveSpace(8) # optional - sage.groups + sage: RP10.homology() # optional - sage.groups sage.modules {0: 0, 1: C2, 2: 0, 3: C2, 4: 0, 5: C2, 6: 0, 7: C2, 8: 0} sage: eta = simplicial_sets.HopfMap() sage: S3 = eta.domain() sage: S2 = eta.codomain() - sage: S3.wedge(S2).homology() + sage: S3.wedge(S2).homology() # optional - sage.graphs sage.modules {0: 0, 1: 0, 2: Z, 3: Z} """ diff --git a/src/sage/topology/simplicial_set_constructions.py b/src/sage/topology/simplicial_set_constructions.py index e5a14632098..039d9630690 100644 --- a/src/sage/topology/simplicial_set_constructions.py +++ b/src/sage/topology/simplicial_set_constructions.py @@ -15,14 +15,14 @@ sage: K = simplicial_sets.Simplex(1) sage: endpoints = K.n_skeleton(0) - sage: circle = K.quotient(endpoints) + sage: circle = K.quotient(endpoints) # optional - sage.graphs The mapping cone of a morphism of simplicial sets is constructed as a pushout:: sage: eta = simplicial_sets.HopfMap() - sage: CP2 = eta.mapping_cone() - sage: type(CP2) + sage: CP2 = eta.mapping_cone() # optional - sage.graphs + sage: type(CP2) # optional - sage.graphs See the main documentation for simplicial sets, as well as for the @@ -34,7 +34,7 @@ for example, if ``K`` is a simplicial set, calling ``K.suspension()`` twice returns the same result both times:: - sage: CP2.suspension() is CP2.suspension() + sage: CP2.suspension() is CP2.suspension() # optional - sage.graphs True So on one hand, a command like ``simplicial_sets.Sphere(2)`` @@ -143,14 +143,14 @@ def __init__(self, data, ambient=None): sage: S3 = simplicial_sets.Sphere(3) sage: K = simplicial_sets.KleinBottle() - sage: X = S3.disjoint_union(K) - sage: Y = X.structure_map(0).image() # the S3 summand - sage: Y.inclusion_map() + sage: X = S3.disjoint_union(K) # optional - sage.graphs + sage: Y = X.structure_map(0).image() # the S3 summand # optional - sage.graphs + sage: Y.inclusion_map() # optional - sage.graphs Simplicial set morphism: From: Simplicial set with 2 non-degenerate simplices To: Disjoint union: (S^3 u Klein bottle) Defn: [v_0, sigma_3] --> [v_0, sigma_3] - sage: Y.ambient_space() + sage: Y.ambient_space() # optional - sage.graphs Disjoint union: (S^3 u Klein bottle) TESTS:: @@ -191,9 +191,9 @@ def inclusion_map(self): EXAMPLES:: - sage: RP6 = simplicial_sets.RealProjectiveSpace(6) - sage: K = RP6.n_skeleton(2) - sage: K.inclusion_map() + sage: RP6 = simplicial_sets.RealProjectiveSpace(6) # optional - sage.groups + sage: K = RP6.n_skeleton(2) # optional - sage.groups + sage: K.inclusion_map() # optional - sage.groups Simplicial set morphism: From: Simplicial set with 3 non-degenerate simplices To: RP^6 @@ -202,7 +202,7 @@ def inclusion_map(self): `RP^6` itself is constructed as a subsimplicial set of `RP^\infty`:: - sage: latex(RP6.inclusion_map()) + sage: latex(RP6.inclusion_map()) # optional - sage.groups RP^{6} \to RP^{\infty} """ return self._inclusion @@ -217,7 +217,7 @@ def ambient_space(self): sage: eight = T.wedge_as_subset() sage: eight Simplicial set with 3 non-degenerate simplices - sage: eight.fundamental_group() + sage: eight.fundamental_group() # optional - sage.groups Finitely presented group < e0, e1 | > sage: eight.ambient_space() Torus @@ -267,10 +267,10 @@ def __init__(self, maps=None): base point map gives a simplicial set isomorphic to the original subcomplex:: - sage: RP5 = simplicial_sets.RealProjectiveSpace(5) - sage: K = RP5.quotient(RP5.n_skeleton(2)) - sage: X = K.pullback(K.quotient_map(), K.base_point_map()) - sage: X.homology() == RP5.n_skeleton(2).homology() + sage: RP5 = simplicial_sets.RealProjectiveSpace(5) # optional - sage.groups + sage: K = RP5.quotient(RP5.n_skeleton(2)) # optional - sage.groups + sage: X = K.pullback(K.quotient_map(), K.base_point_map()) # optional - sage.groups + sage: X.homology() == RP5.n_skeleton(2).homology() # optional - sage.groups True Pullbacks of identity maps:: @@ -319,17 +319,18 @@ def n_skeleton(self, n): EXAMPLES:: - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: one = Hom(B,B).identity() - sage: c = Hom(B,B).constant_map() - sage: P = B.pullback(one, c) - sage: P.n_skeleton(2) + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: one = Hom(B,B).identity() # optional - sage.groups + sage: c = Hom(B,B).constant_map() # optional - sage.groups + sage: P = B.pullback(one, c) # optional - sage.groups + sage: P.n_skeleton(2) # optional - sage.groups Pullback of maps: Simplicial set endomorphism of Simplicial set with 3 non-degenerate simplices Defn: Identity map Simplicial set endomorphism of Simplicial set with 3 non-degenerate simplices Defn: Constant map at 1 - sage: P.n_skeleton(3).homology() + sage: P.n_skeleton(3).homology() # optional - sage.groups {0: 0, 1: C2, 2: 0, 3: Z} """ if self.is_finite(): @@ -362,15 +363,15 @@ def defining_map(self, i): EXAMPLES:: - sage: RP5 = simplicial_sets.RealProjectiveSpace(5) - sage: K = RP5.quotient(RP5.n_skeleton(2)) - sage: Y = K.pullback(K.quotient_map(), K.base_point_map()) - sage: Y.defining_map(1) + sage: RP5 = simplicial_sets.RealProjectiveSpace(5) # optional - sage.groups + sage: K = RP5.quotient(RP5.n_skeleton(2)) # optional - sage.groups + sage: Y = K.pullback(K.quotient_map(), K.base_point_map()) # optional - sage.groups + sage: Y.defining_map(1) # optional - sage.groups Simplicial set morphism: From: Point To: Quotient: (RP^5/Simplicial set with 3 non-degenerate simplices) Defn: Constant map at * - sage: Y.defining_map(0).domain() + sage: Y.defining_map(0).domain() # optional - sage.groups RP^5 """ return self._maps[i] @@ -444,10 +445,11 @@ def __init__(self, maps=None): sage: S2.pullback(eta, c).is_finite() True - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: one = Hom(B,B).identity() - sage: c = Hom(B,B).constant_map() - sage: B.pullback(one, c).is_finite() + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: one = Hom(B,B).identity() # optional - sage.groups + sage: c = Hom(B,B).constant_map() # optional - sage.groups + sage: B.pullback(one, c).is_finite() # optional - sage.groups False TESTS:: @@ -614,28 +616,29 @@ def structure_map(self, i): EXAMPLES:: - sage: RP5 = simplicial_sets.RealProjectiveSpace(5) - sage: K = RP5.quotient(RP5.n_skeleton(2)) - sage: Y = K.pullback(K.quotient_map(), K.base_point_map()) - sage: Y.structure_map(0) + sage: RP5 = simplicial_sets.RealProjectiveSpace(5) # optional - sage.groups + sage: K = RP5.quotient(RP5.n_skeleton(2)) # optional - sage.groups + sage: Y = K.pullback(K.quotient_map(), K.base_point_map()) # optional - sage.groups + sage: Y.structure_map(0) # optional - sage.groups Simplicial set morphism: From: Pullback of maps: Simplicial set morphism: From: RP^5 To: Quotient: (RP^5/Simplicial set with 3 non-degenerate simplices) - Defn: [1, f, f * f, f * f * f, f * f * f * f, f * f * f * f * f] --> [*, s_0 *, s_1 s_0 *, f * f * f, f * f * f * f, f * f * f * f * f] + Defn: [1, f, f * f, f * f * f, f * f * f * f, f * f * f * f * f] + --> [*, s_0 *, s_1 s_0 *, f * f * f, f * f * f * f, f * f * f * f * f] Simplicial set morphism: From: Point To: Quotient: (RP^5/Simplicial set with 3 non-degenerate simplices) Defn: Constant map at * To: RP^5 Defn: [(1, *), (f, s_0 *), (f * f, s_1 s_0 *)] --> [1, f, f * f] - sage: Y.structure_map(1).codomain() + sage: Y.structure_map(1).codomain() # optional - sage.groups Point - These maps are also accessible via ``projection_map``:: + These maps are also accessible via :meth:`projection_map`:: - sage: Y.projection_map(1).codomain() + sage: Y.projection_map(1).codomain() # optional - sage.groups Point """ if len(self._maps) == 1: @@ -667,7 +670,8 @@ def universal_property(self, *maps): sage: S1 = simplicial_sets.Sphere(1) sage: T = S1.product(S1) sage: K = T.factor(0, as_subset=True) - sage: f = S1.Hom(T)({S1.n_cells(0)[0]:K.n_cells(0)[0], S1.n_cells(1)[0]:K.n_cells(1)[0]}) + sage: f = S1.Hom(T)({S1.n_cells(0)[0]: K.n_cells(0)[0], + ....: S1.n_cells(1)[0]: K.n_cells(1)[0]}) sage: P = S1.product(T) sage: P.universal_property(S1.Hom(S1).identity(), f) Simplicial set morphism: @@ -716,11 +720,11 @@ def factors(self): EXAMPLES:: - sage: S2 = simplicial_sets.Sphere(2) - sage: S3 = simplicial_sets.Sphere(3) - sage: S2.wedge(S3).factors() == (S2, S3) + sage: S2 = simplicial_sets.Sphere(2) # optional - sage.graphs + sage: S3 = simplicial_sets.Sphere(3) # optional - sage.graphs + sage: S2.wedge(S3).factors() == (S2, S3) # optional - sage.graphs True - sage: S2.product(S3).factors()[0] + sage: S2.product(S3).factors()[0] # optional - sage.graphs S^2 """ return self._factors @@ -737,14 +741,15 @@ def factor(self, i): sage: S2 = simplicial_sets.Sphere(2) sage: S3 = simplicial_sets.Sphere(3) - sage: K = S2.disjoint_union(S3) - sage: K.factor(0) + sage: K = S2.disjoint_union(S3) # optional - sage.graphs + sage: K.factor(0) # optional - sage.graphs S^2 - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: X = B.wedge(S3, B) - sage: X.factor(1) + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: X = B.wedge(S3, B) # optional - sage.groups + sage: X.factor(1) # optional - sage.groups S^3 - sage: X.factor(2) + sage: X.factor(2) # optional - sage.groups Classifying space of Multiplicative Abelian group isomorphic to C2 """ return self.factors()[i] @@ -881,9 +886,11 @@ def n_skeleton(self, n): sage: S3 = simplicial_sets.Sphere(3) sage: S2.product(S3).n_skeleton(2) Simplicial set with 2 non-degenerate simplices - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: X = B.product(B) - sage: X.n_skeleton(2) + + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: X = B.product(B) # optional - sage.groups + sage: X.n_skeleton(2) # optional - sage.groups Simplicial set with 13 non-degenerate simplices """ n_skel = SimplicialSet_finite.n_skeleton @@ -961,10 +968,11 @@ def _repr_(self): sage: S2 = simplicial_sets.Sphere(2) sage: K = simplicial_sets.KleinBottle() - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: S2.product(S2) + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: S2.product(S2) # optional - sage.groups S^2 x S^2 - sage: S2.product(K, B) + sage: S2.product(K, B) # optional - sage.groups S^2 x Klein bottle x Classifying space of Multiplicative Abelian group isomorphic to C2 """ return ' x '.join(str(X) for X in self._factors) @@ -978,8 +986,8 @@ def _latex_(self): sage: S2 = simplicial_sets.Sphere(2) sage: latex(S2.product(S2)) S^{2} \times S^{2} - sage: RPoo = simplicial_sets.RealProjectiveSpace(Infinity) - sage: latex(S2.product(RPoo, S2)) + sage: RPoo = simplicial_sets.RealProjectiveSpace(Infinity) # optional - sage.groups + sage: latex(S2.product(RPoo, S2)) # optional - sage.groups S^{2} \times RP^{\infty} \times S^{2} """ return ' \\times '.join(latex(X) for X in self._factors) @@ -1186,17 +1194,17 @@ def __init__(self, maps=None, vertex_name=None): sage: f1_data = {a:v, b:v, e2:v.apply_degeneracies(0)} sage: f0 = X.Hom(Y0)(f0_data) sage: f1 = X.Hom(Y1)(f1_data) - sage: P = X.pushout(f0, f1) - sage: P.nondegenerate_simplices() + sage: P = X.pushout(f0, f1) # optional - sage.graphs + sage: P.nondegenerate_simplices() # optional - sage.graphs [a, c, e_0, e_1] There are defining maps `f_i: X \to Y_i` and structure maps `\bar{f}_i: Y_i \to P`; the latter are only implemented in Sage when each `Y_i` is finite. :: - sage: P.defining_map(0) == f0 + sage: P.defining_map(0) == f0 # optional - sage.graphs True - sage: P.structure_map(1) + sage: P.structure_map(1) # optional - sage.graphs Simplicial set morphism: From: 0-simplex To: Pushout of maps: @@ -1209,9 +1217,9 @@ def __init__(self, maps=None, vertex_name=None): To: 0-simplex Defn: Constant map at (0,) Defn: Constant map at a - sage: P.structure_map(0).domain() == Y0 + sage: P.structure_map(0).domain() == Y0 # optional - sage.graphs True - sage: P.structure_map(0).codomain() == P + sage: P.structure_map(0).codomain() == P # optional - sage.graphs True An inefficient way of constructing a suspension for an @@ -1222,28 +1230,30 @@ def __init__(self, maps=None, vertex_name=None): sage: T = T.unset_base_point() sage: CT = T.cone() sage: inc = CT.base_as_subset().inclusion_map() - sage: P = T.pushout(inc, inc) - sage: P.homology() + sage: P = T.pushout(inc, inc) # optional - sage.graphs + sage: P.homology() # optional - sage.graphs {0: 0, 1: 0, 2: Z x Z, 3: Z} - sage: len(P.nondegenerate_simplices()) + sage: len(P.nondegenerate_simplices()) # optional - sage.graphs 20 It is more efficient to construct the suspension as the quotient `CX/X`:: - sage: len(CT.quotient(CT.base_as_subset()).nondegenerate_simplices()) + sage: len(CT.quotient(CT.base_as_subset()).nondegenerate_simplices()) # optional - sage.graphs 8 It is more efficient still if the original simplicial set has a base point:: sage: T = simplicial_sets.Torus() - sage: len(T.suspension().nondegenerate_simplices()) + sage: len(T.suspension().nondegenerate_simplices()) # optional - sage.graphs 6 sage: S1 = simplicial_sets.Sphere(1) sage: pt = simplicial_sets.Point() - sage: bouquet = pt.pushout(S1.base_point_map(), S1.base_point_map(), S1.base_point_map()) + sage: bouquet = pt.pushout(S1.base_point_map(), # optional - sage.graphs + ....: S1.base_point_map(), + ....: S1.base_point_map()) sage: bouquet.homology(1) Z x Z x Z """ @@ -1278,10 +1288,11 @@ def n_skeleton(self, n): EXAMPLES:: - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: K = B.n_skeleton(3) - sage: Q = K.pushout(K.inclusion_map(), K.constant_map()) - sage: Q.n_skeleton(5).homology() + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: K = B.n_skeleton(3) # optional - sage.groups + sage: Q = K.pushout(K.inclusion_map(), K.constant_map()) # optional - sage.groups + sage: Q.n_skeleton(5).homology() # optional - sage.groups {0: 0, 1: 0, 2: 0, 3: 0, 4: Z, 5: Z} Of course, computing the `n`-skeleton and then taking homology @@ -1289,7 +1300,7 @@ def n_skeleton(self, n): dimension `n`, since the latter computation will use the `(n+1)`-skeleton:: - sage: Q.homology(range(6)) + sage: Q.homology(range(6)) # optional - sage.groups {0: 0, 1: 0, 2: 0, 3: 0, 4: Z, 5: C2} """ if self.is_finite(): @@ -1327,15 +1338,15 @@ def defining_map(self, i): sage: S1 = simplicial_sets.Sphere(1) sage: T = simplicial_sets.Torus() - sage: X = S1.wedge(T) # a pushout - sage: X.defining_map(0) + sage: X = S1.wedge(T) # a pushout # optional - sage.graphs + sage: X.defining_map(0) # optional - sage.graphs Simplicial set morphism: From: Point To: S^1 Defn: Constant map at v_0 - sage: X.defining_map(1).domain() + sage: X.defining_map(1).domain() # optional - sage.graphs Point - sage: X.defining_map(1).codomain() + sage: X.defining_map(1).codomain() # optional - sage.graphs Torus """ return self._maps[i] @@ -1349,7 +1360,7 @@ def _repr_(self): sage: S2 = simplicial_sets.Sphere(2) sage: S3 = simplicial_sets.Sphere(3) sage: pt = simplicial_sets.Point() - sage: pt.pushout(S2.base_point_map(), S3.base_point_map()) + sage: pt.pushout(S2.base_point_map(), S3.base_point_map()) # optional - sage.graphs Pushout of maps: Simplicial set morphism: From: Point @@ -1387,7 +1398,7 @@ def __classcall_private__(cls, maps=None, vertex_name=None): sage: from sage.topology.simplicial_set_constructions import PushoutOfSimplicialSets_finite sage: S2 = simplicial_sets.Sphere(2) sage: one = S2.Hom(S2).identity() - sage: PushoutOfSimplicialSets_finite([one, one]) == PushoutOfSimplicialSets_finite((one, one)) + sage: PushoutOfSimplicialSets_finite([one, one]) == PushoutOfSimplicialSets_finite((one, one)) # optional - sage.graphs True """ if maps: @@ -1411,9 +1422,9 @@ def __init__(self, maps=None, vertex_name=None): sage: from sage.topology.simplicial_set_constructions import PushoutOfSimplicialSets_finite sage: T = simplicial_sets.Torus() sage: S2 = simplicial_sets.Sphere(2) - sage: PushoutOfSimplicialSets_finite([T.base_point_map(), S2.base_point_map()]).n_cells(0)[0] + sage: PushoutOfSimplicialSets_finite([T.base_point_map(), S2.base_point_map()]).n_cells(0)[0] # optional - sage.graphs * - sage: PushoutOfSimplicialSets_finite([T.base_point_map(), S2.base_point_map()], vertex_name='v').n_cells(0)[0] + sage: PushoutOfSimplicialSets_finite([T.base_point_map(), S2.base_point_map()], vertex_name='v').n_cells(0)[0] # optional - sage.graphs v """ from sage.graphs.graph import Graph @@ -1584,15 +1595,15 @@ def structure_map(self, i): sage: S1 = simplicial_sets.Sphere(1) sage: T = simplicial_sets.Torus() - sage: X = S1.disjoint_union(T) # a pushout - sage: X.structure_map(0) + sage: X = S1.disjoint_union(T) # a pushout # optional - sage.graphs + sage: X.structure_map(0) # optional - sage.graphs Simplicial set morphism: From: S^1 To: Disjoint union: (S^1 u Torus) Defn: [v_0, sigma_1] --> [v_0, sigma_1] - sage: X.structure_map(1).domain() + sage: X.structure_map(1).domain() # optional - sage.graphs Torus - sage: X.structure_map(1).codomain() + sage: X.structure_map(1).codomain() # optional - sage.graphs Disjoint union: (S^1 u Torus) """ return self._structure[i] @@ -1625,12 +1636,14 @@ def universal_property(self, *maps): sage: Y_1 = SimplicialSet({evx: (x, v)}) sage: f_0 = Hom(X, Y_0)({v:v, w:w, x:x, evw:evw, evx:evx}) - sage: f_1 = Hom(X, Y_1)({v:v, w:v, x:x, evw:v.apply_degeneracies(0), evx:evx}) - sage: P = X.pushout(f_0, f_1) + sage: f_1 = Hom(X, Y_1)({v:v, w:v, x:x, + ....: evw:v.apply_degeneracies(0), evx:evx}) + sage: P = X.pushout(f_0, f_1) # optional - sage.graphs sage: one = Hom(Y_1, Y_1).identity() - sage: g = Hom(Y_0, Y_1)({v:v, w:v, x:x, evw:v.apply_degeneracies(0), evx:evx, ewx:evx}) - sage: P.universal_property(g, one) + sage: g = Hom(Y_0, Y_1)({v:v, w:v, x:x, + ....: evw:v.apply_degeneracies(0), evx:evx, ewx:evx}) + sage: P.universal_property(g, one) # optional - sage.graphs Simplicial set morphism: From: Pushout of maps: Simplicial set morphism: @@ -1683,16 +1696,16 @@ def __init__(self, inclusion, vertex_name='*'): EXAMPLES:: - sage: RP5 = simplicial_sets.RealProjectiveSpace(5) - sage: RP2 = RP5.n_skeleton(2) - sage: RP5_2 = RP5.quotient(RP2) - sage: RP5_2 + sage: RP5 = simplicial_sets.RealProjectiveSpace(5) # optional - sage.groups + sage: RP2 = RP5.n_skeleton(2) # optional - sage.groups + sage: RP5_2 = RP5.quotient(RP2); RP5_2 # optional - sage.graphs sage.groups Quotient: (RP^5/Simplicial set with 3 non-degenerate simplices) - sage: RP5_2.quotient_map() + sage: RP5_2.quotient_map() # optional - sage.graphs sage.groups Simplicial set morphism: From: RP^5 To: Quotient: (RP^5/Simplicial set with 3 non-degenerate simplices) - Defn: [1, f, f * f, f * f * f, f * f * f * f, f * f * f * f * f] --> [*, s_0 *, s_1 s_0 *, f * f * f, f * f * f * f, f * f * f * f * f] + Defn: [1, f, f * f, f * f * f, f * f * f * f, f * f * f * f * f] + --> [*, s_0 *, s_1 s_0 *, f * f * f, f * f * f * f, f * f * f * f * f] """ subcomplex = inclusion.domain() PushoutOfSimplicialSets.__init__(self, [inclusion, @@ -1712,16 +1725,17 @@ def ambient(self): EXAMPLES:: - sage: RP5 = simplicial_sets.RealProjectiveSpace(5) - sage: RP2 = RP5.n_skeleton(2) - sage: RP5_2 = RP5.quotient(RP2) - sage: RP5_2.ambient() + sage: RP5 = simplicial_sets.RealProjectiveSpace(5) # optional - sage.groups + sage: RP2 = RP5.n_skeleton(2) # optional - sage.groups + sage: RP5_2 = RP5.quotient(RP2) # optional - sage.graphs sage.groups + sage: RP5_2.ambient() # optional - sage.graphs RP^5 - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: K = B.n_skeleton(3) - sage: Q = B.quotient(K) - sage: Q.ambient() + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: K = B.n_skeleton(3) # optional - sage.groups + sage: Q = B.quotient(K) # optional - sage.graphs sage.groups + sage: Q.ambient() # optional - sage.graphs sage.groups Classifying space of Multiplicative Abelian group isomorphic to C2 """ return self._maps[0].codomain() @@ -1734,16 +1748,17 @@ def subcomplex(self): EXAMPLES:: - sage: RP5 = simplicial_sets.RealProjectiveSpace(5) - sage: RP2 = RP5.n_skeleton(2) - sage: RP5_2 = RP5.quotient(RP2) - sage: RP5_2.subcomplex() + sage: RP5 = simplicial_sets.RealProjectiveSpace(5) # optional - sage.groups + sage: RP2 = RP5.n_skeleton(2) # optional - sage.groups + sage: RP5_2 = RP5.quotient(RP2) # optional - sage.graphs sage.groups + sage: RP5_2.subcomplex() # optional - sage.graphs sage.groups Simplicial set with 3 non-degenerate simplices - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: K = B.n_skeleton(3) - sage: Q = B.quotient(K) - sage: Q.subcomplex() + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: K = B.n_skeleton(3) # optional - sage.groups + sage: Q = B.quotient(K) # optional - sage.graphs sage.groups + sage: Q.subcomplex() # optional - sage.graphs sage.groups Simplicial set with 4 non-degenerate simplices """ return self._maps[0].domain() @@ -1764,12 +1779,15 @@ def n_skeleton(self, n): EXAMPLES:: - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: K = B.n_skeleton(3) - sage: Q = B.quotient(K) - sage: Q.n_skeleton(6) - Quotient: (Simplicial set with 7 non-degenerate simplices/Simplicial set with 4 non-degenerate simplices) - sage: Q.n_skeleton(6).homology() + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: K = B.n_skeleton(3) # optional - sage.groups + sage: Q = B.quotient(K) # optional - sage.graphs sage.groups + sage: Q.n_skeleton(6) # optional - sage.graphs sage.groups + Quotient: (Simplicial set with 7 + non-degenerate simplices/Simplicial set with 4 + non-degenerate simplices) + sage: Q.n_skeleton(6).homology() # optional - sage.graphs sage.groups {0: 0, 1: 0, 2: 0, 3: 0, 4: Z, 5: C2, 6: 0} """ if self.is_finite(): @@ -1797,7 +1815,7 @@ def _repr_(self): EXAMPLES:: sage: T = simplicial_sets.Torus() - sage: T.quotient(T.n_skeleton(1)) + sage: T.quotient(T.n_skeleton(1)) # optional - sage.graphs Quotient: (Torus/Simplicial set with 4 non-degenerate simplices) """ return 'Quotient: ({}/{})'.format(self.ambient(), self.subcomplex()) @@ -1808,10 +1826,10 @@ def _latex_(self): EXAMPLES:: - sage: RPoo = simplicial_sets.RealProjectiveSpace(Infinity) - sage: RP3 = RPoo.n_skeleton(3) - sage: RP3.rename_latex('RP^{3}') - sage: latex(RPoo.quotient(RP3)) + sage: RPoo = simplicial_sets.RealProjectiveSpace(Infinity) # optional - sage.groups + sage: RP3 = RPoo.n_skeleton(3) # optional - sage.groups + sage: RP3.rename_latex('RP^{3}') # optional - sage.groups + sage: latex(RPoo.quotient(RP3)) # optional - sage.graphs sage.groups RP^{\infty} / RP^{3} """ return '{} / {}'.format(latex(self.ambient()), latex(self.subcomplex())) @@ -1833,16 +1851,16 @@ def __init__(self, inclusion, vertex_name='*'): EXAMPLES:: - sage: RP5 = simplicial_sets.RealProjectiveSpace(5) - sage: RP2 = RP5.n_skeleton(2) - sage: RP5_2 = RP5.quotient(RP2) - sage: RP5_2 + sage: RP5 = simplicial_sets.RealProjectiveSpace(5) # optional - sage.groups + sage: RP2 = RP5.n_skeleton(2) # optional - sage.groups + sage: RP5_2 = RP5.quotient(RP2); RP5_2 # optional - sage.graphs sage.groups Quotient: (RP^5/Simplicial set with 3 non-degenerate simplices) - sage: RP5_2.quotient_map() + sage: RP5_2.quotient_map() # optional - sage.graphs sage.groups Simplicial set morphism: From: RP^5 To: Quotient: (RP^5/Simplicial set with 3 non-degenerate simplices) - Defn: [1, f, f * f, f * f * f, f * f * f * f, f * f * f * f * f] --> [*, s_0 *, s_1 s_0 *, f * f * f, f * f * f * f, f * f * f * f * f] + Defn: [1, f, f * f, f * f * f, f * f * f * f, f * f * f * f * f] + --> [*, s_0 *, s_1 s_0 *, f * f * f, f * f * f * f, f * f * f * f * f] """ subcomplex = inclusion.domain() PushoutOfSimplicialSets_finite.__init__(self, [inclusion, @@ -1861,16 +1879,16 @@ def quotient_map(self): EXAMPLES:: sage: K = simplicial_sets.Simplex(1) - sage: S1 = K.quotient(K.n_skeleton(0)) - sage: q = S1.quotient_map() - sage: q + sage: S1 = K.quotient(K.n_skeleton(0)) # optional - sage.graphs + sage: q = S1.quotient_map() # optional - sage.graphs + sage: q # optional - sage.graphs Simplicial set morphism: From: 1-simplex To: Quotient: (1-simplex/Simplicial set with 2 non-degenerate simplices) Defn: [(0,), (1,), (0, 1)] --> [*, *, (0, 1)] - sage: q.domain() == K + sage: q.domain() == K # optional - sage.graphs True - sage: q.codomain() == S1 + sage: q.codomain() == S1 # optional - sage.graphs True """ return self.structure_map(0) @@ -1885,7 +1903,7 @@ def __classcall__(cls, factors=None): sage: from sage.topology.simplicial_set_constructions import SmashProductOfSimplicialSets_finite as Smash sage: S2 = simplicial_sets.Sphere(2) - sage: Smash([S2, S2]) == Smash((S2, S2)) + sage: Smash([S2, S2]) == Smash((S2, S2)) # optional - sage.graphs True """ if factors: @@ -1913,7 +1931,7 @@ def __init__(self, factors=None): sage: T = simplicial_sets.Torus() sage: S2 = simplicial_sets.Sphere(2) - sage: T.smash_product(S2).homology() == T.suspension(2).homology() + sage: T.smash_product(S2).homology() == T.suspension(2).homology() # optional - sage.graphs True """ if any(not space.is_pointed() for space in factors): @@ -1929,9 +1947,9 @@ def _repr_(self): EXAMPLES:: - sage: RP4 = simplicial_sets.RealProjectiveSpace(4) - sage: S1 = simplicial_sets.Sphere(1) - sage: S1.smash_product(RP4, S1) + sage: RP4 = simplicial_sets.RealProjectiveSpace(4) # optional - sage.groups + sage: S1 = simplicial_sets.Sphere(1) # optional - sage.groups + sage: S1.smash_product(RP4, S1) # optional - sage.graphs sage.groups Smash product: (S^1 ^ RP^4 ^ S^1) """ s = 'Smash product: (' @@ -1945,9 +1963,9 @@ def _latex_(self): EXAMPLES:: - sage: RP4 = simplicial_sets.RealProjectiveSpace(4) - sage: S1 = simplicial_sets.Sphere(1) - sage: latex(S1.smash_product(RP4, S1)) + sage: RP4 = simplicial_sets.RealProjectiveSpace(4) # optional - sage.groups + sage: S1 = simplicial_sets.Sphere(1) # optional - sage.groups + sage: latex(S1.smash_product(RP4, S1)) # optional - sage.graphs sage.groups S^{1} \wedge RP^{4} \wedge S^{1} """ return ' \\wedge '.join(latex(X) for X in self._factors) @@ -1961,7 +1979,7 @@ def __classcall__(cls, factors=None): sage: from sage.topology.simplicial_set_constructions import WedgeOfSimplicialSets sage: S2 = simplicial_sets.Sphere(2) - sage: WedgeOfSimplicialSets([S2, S2]) == WedgeOfSimplicialSets((S2, S2)) + sage: WedgeOfSimplicialSets([S2, S2]) == WedgeOfSimplicialSets((S2, S2)) # optional - sage.graphs True """ if factors: @@ -1991,26 +2009,27 @@ def __init__(self, factors=None): sage: CP2 = simplicial_sets.ComplexProjectiveSpace(2) sage: K = simplicial_sets.KleinBottle() - sage: W = CP2.wedge(K) - sage: W.homology() + sage: W = CP2.wedge(K) # optional - sage.graphs + sage: W.homology() # optional - sage.graphs {0: 0, 1: Z x C2, 2: Z, 3: 0, 4: Z} - sage: W.inclusion_map(1) + sage: W.inclusion_map(1) # optional - sage.graphs Simplicial set morphism: From: Klein bottle To: Wedge: (CP^2 v Klein bottle) - Defn: [Delta_{0,0}, Delta_{1,0}, Delta_{1,1}, Delta_{1,2}, Delta_{2,0}, Delta_{2,1}] --> [*, Delta_{1,0}, Delta_{1,1}, Delta_{1,2}, Delta_{2,0}, Delta_{2,1}] + Defn: [Delta_{0,0}, Delta_{1,0}, Delta_{1,1}, Delta_{1,2}, Delta_{2,0}, Delta_{2,1}] + --> [*, Delta_{1,0}, Delta_{1,1}, Delta_{1,2}, Delta_{2,0}, Delta_{2,1}] - sage: W.projection_map(0).domain() + sage: W.projection_map(0).domain() # optional - sage.graphs Wedge: (CP^2 v Klein bottle) - sage: W.projection_map(0).codomain() # copy of CP^2 + sage: W.projection_map(0).codomain() # copy of CP^2 # optional - sage.graphs Quotient: (Wedge: (CP^2 v Klein bottle)/Simplicial set with 6 non-degenerate simplices) - sage: W.projection_map(0).codomain().homology() + sage: W.projection_map(0).codomain().homology() # optional - sage.graphs {0: 0, 1: 0, 2: Z, 3: 0, 4: Z} An error occurs if any of the factors is not pointed:: - sage: CP2.wedge(simplicial_sets.Simplex(1)) + sage: CP2.wedge(simplicial_sets.Simplex(1)) # optional - sage.graphs Traceback (most recent call last): ... ValueError: the simplicial sets must be pointed @@ -2036,7 +2055,7 @@ def _repr_(self): EXAMPLES:: sage: K = simplicial_sets.KleinBottle() - sage: K.wedge(K, K) + sage: K.wedge(K, K) # optional - sage.graphs Wedge: (Klein bottle v Klein bottle v Klein bottle) """ s = 'Wedge: (' @@ -2050,9 +2069,9 @@ def _latex_(self): EXAMPLES:: - sage: RP4 = simplicial_sets.RealProjectiveSpace(4) - sage: S1 = simplicial_sets.Sphere(1) - sage: latex(S1.wedge(RP4, S1)) + sage: RP4 = simplicial_sets.RealProjectiveSpace(4) # optional - sage.groups + sage: S1 = simplicial_sets.Sphere(1) # optional - sage.groups + sage: latex(S1.wedge(RP4, S1)) # optional - sage.graphs sage.groups S^{1} \vee RP^{4} \vee S^{1} """ return ' \\vee '.join(latex(X) for X in self._factors) @@ -2078,7 +2097,7 @@ def __init__(self, factors=None): sage: from sage.topology.simplicial_set_constructions import WedgeOfSimplicialSets_finite sage: K = simplicial_sets.Simplex(3) - sage: WedgeOfSimplicialSets_finite((K,K)) + sage: WedgeOfSimplicialSets_finite((K,K)) # optional - sage.graphs Traceback (most recent call last): ... ValueError: the simplicial sets must be pointed @@ -2102,15 +2121,15 @@ def inclusion_map(self, i): sage: S1 = simplicial_sets.Sphere(1) sage: S2 = simplicial_sets.Sphere(2) - sage: W = S1.wedge(S2, S1) - sage: W.inclusion_map(1) + sage: W = S1.wedge(S2, S1) # optional - sage.graphs + sage: W.inclusion_map(1) # optional - sage.graphs Simplicial set morphism: From: S^2 To: Wedge: (S^1 v S^2 v S^1) Defn: [v_0, sigma_2] --> [*, sigma_2] - sage: W.inclusion_map(0).domain() + sage: W.inclusion_map(0).domain() # optional - sage.graphs S^1 - sage: W.inclusion_map(2).domain() + sage: W.inclusion_map(2).domain() # optional - sage.graphs S^1 """ return self.structure_map(i) @@ -2123,15 +2142,16 @@ def projection_map(self, i): sage: S1 = simplicial_sets.Sphere(1) sage: S2 = simplicial_sets.Sphere(2) - sage: W = S1.wedge(S2, S1) - sage: W.projection_map(1) + sage: W = S1.wedge(S2, S1) # optional - sage.graphs + sage: W.projection_map(1) # optional - sage.graphs Simplicial set morphism: From: Wedge: (S^1 v S^2 v S^1) - To: Quotient: (Wedge: (S^1 v S^2 v S^1)/Simplicial set with 3 non-degenerate simplices) + To: Quotient: (Wedge: (S^1 v S^2 v S^1)/Simplicial set with + 3 non-degenerate simplices) Defn: [*, sigma_1, sigma_1, sigma_2] --> [*, s_0 *, s_0 *, sigma_2] - sage: W.projection_map(1).image().homology(1) + sage: W.projection_map(1).image().homology(1) # optional - sage.graphs 0 - sage: W.projection_map(1).image().homology(2) + sage: W.projection_map(1).image().homology(2) # optional - sage.graphs Z """ m = len(self._factors) @@ -2180,15 +2200,16 @@ def __init__(self, factors=None): sage: CP2 = simplicial_sets.ComplexProjectiveSpace(2) sage: K = simplicial_sets.KleinBottle() - sage: W = CP2.disjoint_union(K) - sage: W.homology() + sage: W = CP2.disjoint_union(K) # optional - sage.graphs + sage: W.homology() # optional - sage.graphs {0: Z, 1: Z x C2, 2: Z, 3: 0, 4: Z} - sage: W.inclusion_map(1) + sage: W.inclusion_map(1) # optional - sage.graphs Simplicial set morphism: From: Klein bottle To: Disjoint union: (CP^2 u Klein bottle) - Defn: [Delta_{0,0}, Delta_{1,0}, Delta_{1,1}, Delta_{1,2}, Delta_{2,0}, Delta_{2,1}] --> [Delta_{0,0}, Delta_{1,0}, Delta_{1,1}, Delta_{1,2}, Delta_{2,0}, Delta_{2,1}] + Defn: [Delta_{0,0}, Delta_{1,0}, Delta_{1,1}, Delta_{1,2}, Delta_{2,0}, Delta_{2,1}] + --> [Delta_{0,0}, Delta_{1,0}, Delta_{1,1}, Delta_{1,2}, Delta_{2,0}, Delta_{2,1}] """ PushoutOfSimplicialSets.__init__(self, [space._map_from_empty_set() for space in factors]) @@ -2212,10 +2233,11 @@ def n_skeleton(self, n): EXAMPLES:: - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: T = simplicial_sets.Torus() - sage: X = B.disjoint_union(T) - sage: X.n_skeleton(3).homology() + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: T = simplicial_sets.Torus() # optional - sage.groups + sage: X = B.disjoint_union(T) # optional - sage.groups + sage: X.n_skeleton(3).homology() # optional - sage.groups {0: Z, 1: Z x Z x C2, 2: Z, 3: Z} """ if self.is_finite(): @@ -2241,8 +2263,8 @@ def _repr_(self): EXAMPLES:: sage: T = simplicial_sets.Torus() - sage: RP3 = simplicial_sets.RealProjectiveSpace(3) - sage: T.disjoint_union(T, RP3) + sage: RP3 = simplicial_sets.RealProjectiveSpace(3) # optional - sage.groups + sage: T.disjoint_union(T, RP3) # optional - sage.groups Disjoint union: (Torus u Torus u RP^3) """ s = 'Disjoint union: (' @@ -2256,9 +2278,9 @@ def _latex_(self): EXAMPLES:: - sage: RP4 = simplicial_sets.RealProjectiveSpace(4) + sage: RP4 = simplicial_sets.RealProjectiveSpace(4) # optional - sage.groups sage: S1 = simplicial_sets.Sphere(1) - sage: latex(S1.disjoint_union(RP4, S1)) + sage: latex(S1.disjoint_union(RP4, S1)) # optional - sage.graphs sage.groups S^{1} \amalg RP^{4} \amalg S^{1} """ return ' \\amalg '.join(latex(X) for X in self._factors) @@ -2287,9 +2309,9 @@ def __init__(self, factors=None): sage: from sage.topology.simplicial_set_constructions import DisjointUnionOfSimplicialSets_finite sage: from sage.topology.simplicial_set_examples import Empty sage: S = simplicial_sets.Sphere(4) - sage: DisjointUnionOfSimplicialSets_finite((S,S,S)) + sage: DisjointUnionOfSimplicialSets_finite((S,S,S)) # optional - sage.graphs Disjoint union: (S^4 u S^4 u S^4) - sage: DisjointUnionOfSimplicialSets_finite([Empty(), Empty()]) == Empty() + sage: DisjointUnionOfSimplicialSets_finite([Empty(), Empty()]) == Empty() # optional - sage.graphs True """ if not factors: @@ -2307,15 +2329,15 @@ def inclusion_map(self, i): sage: S1 = simplicial_sets.Sphere(1) sage: S2 = simplicial_sets.Sphere(2) - sage: W = S1.disjoint_union(S2, S1) - sage: W.inclusion_map(1) + sage: W = S1.disjoint_union(S2, S1) # optional - sage.graphs + sage: W.inclusion_map(1) # optional - sage.graphs Simplicial set morphism: From: S^2 To: Disjoint union: (S^1 u S^2 u S^1) Defn: [v_0, sigma_2] --> [v_0, sigma_2] - sage: W.inclusion_map(0).domain() + sage: W.inclusion_map(0).domain() # optional - sage.graphs S^1 - sage: W.inclusion_map(2).domain() + sage: W.inclusion_map(2).domain() # optional - sage.graphs S^1 """ return self.structure_map(i) @@ -2373,10 +2395,11 @@ def n_skeleton(self, n): EXAMPLES:: - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: X = B.disjoint_union(B) - sage: CX = B.cone() - sage: CX.n_skeleton(3).homology() + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: X = B.disjoint_union(B) # optional - sage.graphs sage.groups + sage: CX = B.cone() # optional - sage.graphs sage.groups + sage: CX.n_skeleton(3).homology() # optional - sage.graphs sage.groups {0: 0, 1: 0, 2: 0, 3: Z} """ if self.is_finite(): @@ -2397,7 +2420,7 @@ def _repr_(self): EXAMPLES:: - sage: simplicial_sets.Simplex(3).cone() + sage: simplicial_sets.Simplex(3).cone() # optional - sage.graphs Cone of 3-simplex """ return 'Cone of {}'.format(self._base) @@ -2408,7 +2431,7 @@ def _latex_(self): EXAMPLES:: - sage: latex(simplicial_sets.Simplex(3).cone()) + sage: latex(simplicial_sets.Simplex(3).cone()) # optional - sage.graphs C \Delta^{3} """ return 'C {}'.format(latex(self._base)) @@ -2479,11 +2502,11 @@ def base_as_subset(self): EXAMPLES:: - sage: X = simplicial_sets.RealProjectiveSpace(4).unset_base_point() - sage: Y = X.cone() - sage: Y.base_as_subset() + sage: X = simplicial_sets.RealProjectiveSpace(4).unset_base_point() # optional - sage.groups + sage: Y = X.cone() # optional - sage.graphs sage.groups + sage: Y.base_as_subset() # optional - sage.graphs sage.groups Simplicial set with 5 non-degenerate simplices - sage: Y.base_as_subset() == X + sage: Y.base_as_subset() == X # optional - sage.graphs sage.groups True """ X = self._base @@ -2496,12 +2519,13 @@ def map_from_base(self): EXAMPLES:: sage: X = simplicial_sets.Simplex(2).n_skeleton(1) - sage: Y = X.cone() - sage: Y.map_from_base() + sage: Y = X.cone() # optional - sage.graphs + sage: Y.map_from_base() # optional - sage.graphs Simplicial set morphism: From: Simplicial set with 6 non-degenerate simplices To: Cone of Simplicial set with 6 non-degenerate simplices - Defn: [(0,), (1,), (2,), (0, 1), (0, 2), (1, 2)] --> [(0,), (1,), (2,), (0, 1), (0, 2), (1, 2)] + Defn: [(0,), (1,), (2,), (0, 1), (0, 2), (1, 2)] + --> [(0,), (1,), (2,), (0, 1), (0, 2), (1, 2)] """ return self.base_as_subset().inclusion_map() @@ -2531,8 +2555,8 @@ def __init__(self, base): sage: e = AbstractSimplex(1, name='e') sage: X = SimplicialSet({e: (v, v)}) sage: X = X.set_base_point(v) - sage: CX = X.cone() # indirect doctest - sage: CX.nondegenerate_simplices() + sage: CX = X.cone() # indirect doctest # optional - sage.graphs + sage: CX.nondegenerate_simplices() # optional - sage.graphs [*, e, (e,*)] """ C = ConeOfSimplicialSet(base) @@ -2563,8 +2587,9 @@ def n_skeleton(self, n): EXAMPLES:: - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: B.cone().n_skeleton(3).homology() + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: B.cone().n_skeleton(3).homology() # optional - sage.graphs sage.groups sage.modules {0: 0, 1: 0, 2: 0, 3: Z} """ if self.is_finite(): @@ -2585,7 +2610,7 @@ def _repr_(self): EXAMPLES:: sage: X = simplicial_sets.Sphere(4) - sage: X.cone() + sage: X.cone() # optional - sage.graphs Reduced cone of S^4 """ return 'Reduced cone of {}'.format(self._base) @@ -2596,7 +2621,7 @@ def _latex_(self): EXAMPLES:: - sage: latex(simplicial_sets.Sphere(4).cone()) + sage: latex(simplicial_sets.Sphere(4).cone()) # optional - sage.graphs C S^{4} """ return 'C {}'.format(latex(self._base)) @@ -2628,8 +2653,8 @@ def __init__(self, base): sage: e = AbstractSimplex(1, name='e') sage: X = SimplicialSet({e: (v, v)}) sage: X = X.set_base_point(v) - sage: CX = X.cone() # indirect doctest - sage: CX.nondegenerate_simplices() + sage: CX = X.cone() # indirect doctest # optional - sage.graphs + sage: CX.nondegenerate_simplices() # optional - sage.graphs [*, e, (e,*)] """ C = ConeOfSimplicialSet_finite(base) @@ -2657,8 +2682,8 @@ def map_from_base(self): EXAMPLES:: sage: S3 = simplicial_sets.Sphere(3) - sage: CS3 = S3.cone() - sage: CS3.map_from_base() + sage: CS3 = S3.cone() # optional - sage.graphs + sage: CS3.map_from_base() # optional - sage.graphs Simplicial set morphism: From: S^3 To: Reduced cone of S^3 @@ -2692,18 +2717,19 @@ def __init__(self, base): EXAMPLES:: - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: B.suspension() + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: B.suspension() # optional - sage.graphs sage.groups Sigma(Classifying space of Multiplicative Abelian group isomorphic to C2) - sage: B.suspension().n_skeleton(3).homology() + sage: B.suspension().n_skeleton(3).homology() # optional - sage.graphs sage.groups {0: 0, 1: 0, 2: C2, 3: 0} If ``X`` is finite, the suspension comes with a quotient map from the cone:: sage: S3 = simplicial_sets.Sphere(3) - sage: S4 = S3.suspension() - sage: S4.quotient_map() + sage: S4 = S3.suspension() # optional - sage.graphs + sage: S4.quotient_map() # optional - sage.graphs Simplicial set morphism: From: Reduced cone of S^3 To: Sigma(S^3) @@ -2711,11 +2737,11 @@ def __init__(self, base): TESTS:: - sage: S3.suspension() == S3.suspension() + sage: S3.suspension() == S3.suspension() # optional - sage.graphs True - sage: S3.suspension() == simplicial_sets.Sphere(3).suspension() + sage: S3.suspension() == simplicial_sets.Sphere(3).suspension() # optional - sage.graphs False - sage: B.suspension() == B.suspension() + sage: B.suspension() == B.suspension() # optional - sage.graphs sage.groups True """ Cat = SimplicialSets() @@ -2748,9 +2774,10 @@ def n_skeleton(self, n): EXAMPLES:: - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: SigmaB = B.suspension() - sage: SigmaB.n_skeleton(4).homology(base_ring=GF(2)) + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: SigmaB = B.suspension() # optional - sage.graphs sage.groups + sage: SigmaB.n_skeleton(4).homology(base_ring=GF(2)) # optional - sage.graphs sage.groups sage.modules sage.rings.finite_rings {0: Vector space of dimension 0 over Finite Field of size 2, 1: Vector space of dimension 0 over Finite Field of size 2, 2: Vector space of dimension 1 over Finite Field of size 2, @@ -2783,10 +2810,10 @@ def __repr_or_latex__(self, output_type=None): EXAMPLES:: sage: T = simplicial_sets.Torus() - sage: K = T.suspension(10) - sage: K.__repr_or_latex__() + sage: K = T.suspension(10) # optional - sage.graphs + sage: K.__repr_or_latex__() # optional - sage.graphs 'Sigma^10(Torus)' - sage: K.__repr_or_latex__('latex') + sage: K.__repr_or_latex__('latex') # optional - sage.graphs '\\Sigma^{10}(S^{1} \\times S^{1})' """ latex_output = (output_type == 'latex') @@ -2824,12 +2851,12 @@ def _repr_(self): EXAMPLES:: sage: S2 = simplicial_sets.Sphere(2) - sage: S2.suspension(3) + sage: S2.suspension(3) # optional - sage.graphs Sigma^3(S^2) sage: K = simplicial_sets.Simplex(2) - sage: K.suspension(3) + sage: K.suspension(3) # optional - sage.graphs S^3(2-simplex) - sage: K.suspension() + sage: K.suspension() # optional - sage.graphs S(2-simplex) """ return self.__repr_or_latex__() @@ -2844,12 +2871,12 @@ def _latex_(self): EXAMPLES:: sage: S2 = simplicial_sets.Sphere(2) - sage: latex(S2.suspension(3)) + sage: latex(S2.suspension(3)) # optional - sage.graphs \Sigma^{3}(S^{2}) sage: K = simplicial_sets.Simplex(2) - sage: latex(K.suspension(3)) + sage: latex(K.suspension(3)) # optional - sage.graphs S^{3}(\Delta^{2}) - sage: latex(K.suspension()) + sage: latex(K.suspension()) # optional - sage.graphs S(\Delta^{2}) """ return self.__repr_or_latex__('latex') @@ -2873,10 +2900,10 @@ def __init__(self, base): EXAMPLES:: sage: X = simplicial_sets.Sphere(3) - sage: X.suspension(2) + sage: X.suspension(2) # optional - sage.graphs Sigma^2(S^3) sage: Y = X.unset_base_point() - sage: Y.suspension(2) + sage: Y.suspension(2) # optional - sage.graphs S^2(Simplicial set with 2 non-degenerate simplices) """ self._base = base diff --git a/src/sage/topology/simplicial_set_examples.py b/src/sage/topology/simplicial_set_examples.py index 30bfa0fbaab..94925d7248a 100644 --- a/src/sage/topology/simplicial_set_examples.py +++ b/src/sage/topology/simplicial_set_examples.py @@ -31,7 +31,6 @@ import re import os -from pyparsing import OneOrMore, nestedExpr from sage.env import SAGE_ENV from sage.misc.cachefunc import cached_method, cached_function @@ -108,11 +107,11 @@ def __eq__(self, other): EXAMPLES:: - sage: C3 = groups.misc.MultiplicativeAbelian([3]) - sage: C3.nerve() == C3.nerve() + sage: C3 = groups.misc.MultiplicativeAbelian([3]) # optional - sage.groups + sage: C3.nerve() == C3.nerve() # optional - sage.groups False - sage: BC3 = C3.nerve() - sage: BC3 == BC3 + sage: BC3 = C3.nerve() # optional - sage.groups + sage: BC3 == BC3 # optional - sage.groups True """ return (isinstance(other, Nerve) @@ -125,11 +124,11 @@ def __ne__(self, other): EXAMPLES:: - sage: C3 = groups.misc.MultiplicativeAbelian([3]) - sage: G3 = groups.permutation.Cyclic(3) - sage: C3.nerve() != G3.nerve() + sage: C3 = groups.misc.MultiplicativeAbelian([3]) # optional - sage.groups + sage: G3 = groups.permutation.Cyclic(3) # optional - sage.groups + sage: C3.nerve() != G3.nerve() # optional - sage.groups True - sage: C3.nerve() != C3.nerve() + sage: C3.nerve() != C3.nerve() # optional - sage.groups True """ return not self == other @@ -141,17 +140,17 @@ def __hash__(self): EXAMPLES:: - sage: G3 = groups.permutation.Cyclic(3) - sage: hash(G3.nerve()) # random + sage: G3 = groups.permutation.Cyclic(3) # optional - sage.groups + sage: hash(G3.nerve()) # random # optional - sage.groups 17 Different instances yield different base points, hence different hashes:: - sage: X = G3.nerve() - sage: Y = G3.nerve() - sage: X.base_point() != Y.base_point() + sage: X = G3.nerve() # optional - sage.groups + sage: Y = G3.nerve() # optional - sage.groups + sage: X.base_point() != Y.base_point() # optional - sage.groups True - sage: hash(X) != hash(Y) + sage: hash(X) != hash(Y) # optional - sage.groups True """ return hash(self._monoid) ^ hash(self.base_point()) @@ -169,13 +168,13 @@ def n_skeleton(self, n): EXAMPLES:: - sage: K4 = groups.misc.MultiplicativeAbelian([2,2]) - sage: BK4 = simplicial_sets.ClassifyingSpace(K4) - sage: BK4.n_skeleton(3) + sage: K4 = groups.misc.MultiplicativeAbelian([2,2]) # optional - sage.groups + sage: BK4 = simplicial_sets.ClassifyingSpace(K4) # optional - sage.groups + sage: BK4.n_skeleton(3) # optional - sage.groups Simplicial set with 40 non-degenerate simplices - sage: BK4.n_cells(1) == BK4.n_skeleton(3).n_cells(1) + sage: BK4.n_cells(1) == BK4.n_skeleton(3).n_cells(1) # optional - sage.groups True - sage: BK4.n_cells(3) == BK4.n_skeleton(1).n_cells(3) + sage: BK4.n_cells(3) == BK4.n_skeleton(1).n_cells(3) # optional - sage.groups False """ from .simplicial_set_constructions import SubSimplicialSet @@ -314,17 +313,16 @@ def ClassifyingSpace(group): EXAMPLES:: - sage: C2 = groups.misc.MultiplicativeAbelian([2]) - sage: BC2 = simplicial_sets.ClassifyingSpace(C2) - sage: H = BC2.homology(range(9), base_ring=GF(2)) - sage: [H[i].dimension() for i in range(9)] + sage: C2 = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: BC2 = simplicial_sets.ClassifyingSpace(C2) # optional - sage.groups + sage: H = BC2.homology(range(9), base_ring=GF(2)) # optional - sage.groups sage.modules sage.rings.finite_rings + sage: [H[i].dimension() for i in range(9)] # optional - sage.groups sage.modules sage.rings.finite_rings [0, 1, 1, 1, 1, 1, 1, 1, 1] - sage: Klein4 = groups.misc.MultiplicativeAbelian([2, 2]) - sage: BK = simplicial_sets.ClassifyingSpace(Klein4) - sage: BK + sage: Klein4 = groups.misc.MultiplicativeAbelian([2, 2]) # optional - sage.groups + sage: BK = simplicial_sets.ClassifyingSpace(Klein4); BK # optional - sage.groups Classifying space of Multiplicative Abelian group isomorphic to C2 x C2 - sage: BK.homology(range(5), base_ring=GF(2)) # long time (1 second) + sage: BK.homology(range(5), base_ring=GF(2)) # long time (1 second) # optional - sage.groups sage.modules sage.rings.finite_rings {0: Vector space of dimension 0 over Finite Field of size 2, 1: Vector space of dimension 2 over Finite Field of size 2, 2: Vector space of dimension 3 over Finite Field of size 2, @@ -346,18 +344,18 @@ def RealProjectiveSpace(n): EXAMPLES:: - sage: simplicial_sets.RealProjectiveSpace(7) + sage: simplicial_sets.RealProjectiveSpace(7) # optional - sage.groups RP^7 - sage: RP5 = simplicial_sets.RealProjectiveSpace(5) - sage: RP5.homology() + sage: RP5 = simplicial_sets.RealProjectiveSpace(5) # optional - sage.groups + sage: RP5.homology() # optional - sage.groups {0: 0, 1: C2, 2: 0, 3: C2, 4: 0, 5: Z} - sage: RP5 + sage: RP5 # optional - sage.groups RP^5 - sage: latex(RP5) + sage: latex(RP5) # optional - sage.groups RP^{5} - sage: BC2 = simplicial_sets.RealProjectiveSpace(Infinity) - sage: latex(BC2) + sage: BC2 = simplicial_sets.RealProjectiveSpace(Infinity) # optional - sage.groups + sage: latex(BC2) # optional - sage.groups RP^{\infty} """ if n == Infinity: @@ -385,7 +383,7 @@ def KleinBottle(): sage: K = simplicial_sets.KleinBottle() sage: K.f_vector() [1, 3, 2] - sage: K.homology(reduced=False) + sage: K.homology(reduced=False) # optional - sage.modules {0: Z, 1: Z x C2, 2: 0} sage: K Klein bottle @@ -410,7 +408,7 @@ def Torus(): sage: T = simplicial_sets.Torus() sage: T.f_vector() [1, 3, 2] - sage: T.homology(reduced=False) + sage: T.homology(reduced=False) # optional - sage.modules {0: Z, 1: Z x Z, 2: Z} """ S1 = Sphere(1) @@ -536,23 +534,23 @@ def ComplexProjectiveSpace(n): sage: simplicial_sets.ComplexProjectiveSpace(2).homology(reduced=False) {0: Z, 1: 0, 2: Z, 3: 0, 4: Z} - sage: CP3 = simplicial_sets.ComplexProjectiveSpace(3) - sage: CP3 + sage: CP3 = simplicial_sets.ComplexProjectiveSpace(3) # optional - pyparsing + sage: CP3 # optional - pyparsing CP^3 - sage: latex(CP3) + sage: latex(CP3) # optional - pyparsing CP^{3} - sage: CP3.f_vector() + sage: CP3.f_vector() # optional - pyparsing [1, 0, 3, 10, 25, 30, 15] - sage: K = CP3.suspension() # long time (1 second) - sage: R = K.cohomology_ring(GF(2)) # long time - sage: R.gens() # long time + sage: K = CP3.suspension() # long time (1 second) # optional - pyparsing + sage: R = K.cohomology_ring(GF(2)) # long time # optional - pyparsing + sage: R.gens() # long time # optional - pyparsing (h^{0,0}, h^{3,0}, h^{5,0}, h^{7,0}) - sage: x = R.gens()[1] # long time - sage: x.Sq(2) # long time + sage: x = R.gens()[1] # long time # optional - pyparsing + sage: x.Sq(2) # long time # optional - pyparsing h^{5,0} - sage: simplicial_sets.ComplexProjectiveSpace(4).f_vector() + sage: simplicial_sets.ComplexProjectiveSpace(4).f_vector() # optional - pyparsing [1, 0, 4, 22, 97, 255, 390, 315, 105] sage: simplicial_sets.ComplexProjectiveSpace(5) @@ -646,10 +644,12 @@ def simplicial_data_from_kenzo_output(filename): sage: from sage.topology.simplicial_set_examples import simplicial_data_from_kenzo_output sage: from sage.topology.simplicial_set import SimplicialSet sage: sphere = os.path.join(SAGE_ENV['SAGE_EXTCODE'], 'kenzo', 'S4.txt') - sage: S4 = SimplicialSet(simplicial_data_from_kenzo_output(sphere)) - sage: S4.homology(reduced=False) + sage: S4 = SimplicialSet(simplicial_data_from_kenzo_output(sphere)) # optional - pyparsing + sage: S4.homology(reduced=False) # optional - pyparsing {0: Z, 1: 0, 2: 0, 3: 0, 4: Z} """ + from pyparsing import OneOrMore, nestedExpr + with open(filename, 'r') as f: data = f.read() dim = 0 @@ -732,14 +732,14 @@ def HopfMap(): Using the Hopf map to attach a cell:: - sage: X = g.mapping_cone() - sage: CP2 = simplicial_sets.ComplexProjectiveSpace(2) - sage: X.homology() == CP2.homology() + sage: X = g.mapping_cone() # optional - sage.graphs + sage: CP2 = simplicial_sets.ComplexProjectiveSpace(2) # optional - sage.graphs + sage: X.homology() == CP2.homology() # optional - sage.graphs True - sage: X.f_vector() + sage: X.f_vector() # optional - sage.graphs [1, 0, 5, 9, 6] - sage: CP2.f_vector() + sage: CP2.f_vector() # optional - sage.graphs [1, 0, 2, 3, 3] """ # The 2-sphere and its simplices. @@ -811,19 +811,17 @@ def PresentationComplex(G): EXAMPLES:: - sage: G = SymmetricGroup(2).as_finitely_presented_group() - sage: G + sage: G = SymmetricGroup(2).as_finitely_presented_group(); G # optional - sage.groups Finitely presented group < a | a^2 > - sage: S = simplicial_sets.PresentationComplex(G) - sage: S + sage: S = simplicial_sets.PresentationComplex(G); S # optional - sage.groups Simplicial set with 5 non-degenerate simplices - sage: S.face_data() + sage: S.face_data() # optional - sage.groups {Delta^0: None, a: (Delta^0, Delta^0), a^-1: (Delta^0, Delta^0), Ta: (a, s_0 Delta^0, a^-1), a^2: (a, s_0 Delta^0, a)} - sage: S.fundamental_group() + sage: S.fundamental_group() # optional - sage.groups Finitely presented group < e0 | e0^2 > """ O = AbstractSimplex(0) diff --git a/src/sage/topology/simplicial_set_morphism.py b/src/sage/topology/simplicial_set_morphism.py index 263679c9254..39aa8727523 100644 --- a/src/sage/topology/simplicial_set_morphism.py +++ b/src/sage/topology/simplicial_set_morphism.py @@ -101,8 +101,8 @@ def diagonal_morphism(self): EXAMPLES:: - sage: RP2 = simplicial_sets.RealProjectiveSpace(2) - sage: Hom(RP2, RP2.product(RP2)).diagonal_morphism() + sage: RP2 = simplicial_sets.RealProjectiveSpace(2) # optional - sage.groups + sage: Hom(RP2, RP2.product(RP2)).diagonal_morphism() # optional - sage.groups Simplicial set morphism: From: RP^2 To: RP^2 x RP^2 @@ -619,9 +619,9 @@ def __call__(self, x): sage: one(e) == e True - sage: B = AbelianGroup([2]).nerve() - sage: c = B.constant_map() - sage: c(B.n_cells(2)[0]) + sage: B = AbelianGroup([2]).nerve() # optional - sage.groups + sage: c = B.constant_map() # optional - sage.groups + sage: c(B.n_cells(2)[0]) # optional - sage.groups s_1 s_0 * """ if x not in self.domain(): @@ -699,10 +699,11 @@ def image(self): sage: f.image().homology() {0: 0, 1: Z} - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: B.constant_map().image() + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: B.constant_map().image() # optional - sage.groups Point - sage: Hom(B,B).identity().image() == B + sage: Hom(B,B).identity().image() == B # optional - sage.groups True """ if self._is_identity: @@ -745,16 +746,17 @@ def is_identity(self): sage: (f*g).induced_homology_morphism().to_matrix(1) [0] - sage: RP5 = simplicial_sets.RealProjectiveSpace(5) - sage: RP5.n_skeleton(2).inclusion_map().is_identity() + sage: RP5 = simplicial_sets.RealProjectiveSpace(5) # optional - sage.groups + sage: RP5.n_skeleton(2).inclusion_map().is_identity() # optional - sage.groups False - sage: RP5.n_skeleton(5).inclusion_map().is_identity() + sage: RP5.n_skeleton(5).inclusion_map().is_identity() # optional - sage.groups True - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: Hom(B,B).identity().is_identity() + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: Hom(B,B).identity().is_identity() # optional - sage.groups True - sage: Hom(B,B).constant_map().is_identity() + sage: Hom(B,B).constant_map().is_identity() # optional - sage.groups False """ ans = (self._is_identity or @@ -770,18 +772,18 @@ def is_surjective(self): EXAMPLES:: - sage: RP5 = simplicial_sets.RealProjectiveSpace(5) - sage: RP2 = RP5.n_skeleton(2) - sage: RP2.inclusion_map().is_surjective() + sage: RP5 = simplicial_sets.RealProjectiveSpace(5) # optional - sage.groups + sage: RP2 = RP5.n_skeleton(2) # optional - sage.groups + sage: RP2.inclusion_map().is_surjective() # optional - sage.groups False - sage: RP5_2 = RP5.quotient(RP2) - sage: RP5_2.quotient_map().is_surjective() + sage: RP5_2 = RP5.quotient(RP2) # optional - sage.groups + sage: RP5_2.quotient_map().is_surjective() # optional - sage.groups True - sage: K = RP5_2.pullback(RP5_2.quotient_map(), RP5_2.base_point_map()) - sage: f = K.universal_property(RP2.inclusion_map(), RP2.constant_map()) - sage: f.is_surjective() + sage: K = RP5_2.pullback(RP5_2.quotient_map(), RP5_2.base_point_map()) # optional - sage.groups + sage: f = K.universal_property(RP2.inclusion_map(), RP2.constant_map()) # optional - sage.groups + sage: f.is_surjective() # optional - sage.groups True """ return self._is_identity or self.image() == self.codomain() @@ -792,18 +794,18 @@ def is_injective(self): EXAMPLES:: - sage: RP5 = simplicial_sets.RealProjectiveSpace(5) - sage: RP2 = RP5.n_skeleton(2) - sage: RP2.inclusion_map().is_injective() + sage: RP5 = simplicial_sets.RealProjectiveSpace(5) # optional - sage.groups + sage: RP2 = RP5.n_skeleton(2) # optional - sage.groups + sage: RP2.inclusion_map().is_injective() # optional - sage.groups True - sage: RP5_2 = RP5.quotient(RP2) - sage: RP5_2.quotient_map().is_injective() + sage: RP5_2 = RP5.quotient(RP2) # optional - sage.groups + sage: RP5_2.quotient_map().is_injective() # optional - sage.groups False - sage: K = RP5_2.pullback(RP5_2.quotient_map(), RP5_2.base_point_map()) - sage: f = K.universal_property(RP2.inclusion_map(), RP2.constant_map()) - sage: f.is_injective() + sage: K = RP5_2.pullback(RP5_2.quotient_map(), RP5_2.base_point_map()) # optional - sage.groups + sage: f = K.universal_property(RP2.inclusion_map(), RP2.constant_map()) # optional - sage.groups + sage: f.is_injective() # optional - sage.groups True """ if self._is_identity: @@ -822,18 +824,18 @@ def is_bijective(self): EXAMPLES:: - sage: RP5 = simplicial_sets.RealProjectiveSpace(5) - sage: RP2 = RP5.n_skeleton(2) - sage: RP2.inclusion_map().is_bijective() + sage: RP5 = simplicial_sets.RealProjectiveSpace(5) # optional - sage.groups + sage: RP2 = RP5.n_skeleton(2) # optional - sage.groups + sage: RP2.inclusion_map().is_bijective() # optional - sage.groups False - sage: RP5_2 = RP5.quotient(RP2) - sage: RP5_2.quotient_map().is_bijective() + sage: RP5_2 = RP5.quotient(RP2) # optional - sage.groups + sage: RP5_2.quotient_map().is_bijective() # optional - sage.groups False - sage: K = RP5_2.pullback(RP5_2.quotient_map(), RP5_2.base_point_map()) - sage: f = K.universal_property(RP2.inclusion_map(), RP2.constant_map()) - sage: f.is_bijective() + sage: K = RP5_2.pullback(RP5_2.quotient_map(), RP5_2.base_point_map()) # optional - sage.groups + sage: f = K.universal_property(RP2.inclusion_map(), RP2.constant_map()) # optional - sage.groups + sage: f.is_bijective() # optional - sage.groups True """ return self.is_injective() and self.is_surjective() @@ -915,8 +917,7 @@ def pushout(self, *others): sage: K = simplicial_sets.KleinBottle() sage: init_T = T._map_from_empty_set() sage: init_K = K._map_from_empty_set() - sage: D = init_T.pushout(init_K) # the disjoint union as a pushout - sage: D + sage: D = init_T.pushout(init_K); D # the disjoint union as a pushout # optional - sage.graphs Pushout of maps: Simplicial set morphism: From: Empty simplicial set @@ -951,8 +952,7 @@ def pullback(self, *others): sage: K = simplicial_sets.KleinBottle() sage: term_T = T.constant_map() sage: term_K = K.constant_map() - sage: P = term_T.pullback(term_K) # the product as a pullback - sage: P + sage: P = term_T.pullback(term_K); P # the product as a pullback Pullback of maps: Simplicial set morphism: From: Torus @@ -1057,8 +1057,7 @@ def coequalizer(self, other): sage: f = K.inclusion_map() sage: v,w = K.n_cells(0) sage: g = Hom(K,L)({v:pt, w:pt, e:pt.apply_degeneracies(0)}) - sage: P = f.coequalizer(g) - sage: P + sage: P = f.coequalizer(g); P # optional - sage.graphs Pushout of maps: Simplicial set morphism: From: Disjoint union: (Simplicial set with 3 non-degenerate simplices u 2-simplex) @@ -1096,7 +1095,8 @@ def mapping_cone(self): sage: L = K.set_base_point(K.n_cells(0)[0]) sage: u,v,w = L.n_cells(0) sage: e,f,g = L.n_cells(1) - sage: h = L.Hom(S1)({u:v_0, v:v_0, w:v_0, e:sigma_1, f:v_0.apply_degeneracies(0), g:sigma_1}) + sage: h = L.Hom(S1)({u:v_0, v:v_0, w:v_0, e:sigma_1, + ....: f:v_0.apply_degeneracies(0), g:sigma_1}) sage: h Simplicial set morphism: From: Simplicial set with 6 non-degenerate simplices @@ -1106,8 +1106,8 @@ def mapping_cone(self): [1|0] [-+-] [0|2] - sage: X = h.mapping_cone() - sage: X.homology() == simplicial_sets.RealProjectiveSpace(2).homology() + sage: X = h.mapping_cone() # optional - sage.graphs + sage: X.homology() == simplicial_sets.RealProjectiveSpace(2).homology() # optional - sage.graphs sage.modules True """ dom = self.domain() @@ -1154,10 +1154,10 @@ def coproduct(self, *others): sage: S1 = simplicial_sets.Sphere(1) sage: f = Hom(S1,S1).identity() - sage: f.coproduct(f).is_bijective() + sage: f.coproduct(f).is_bijective() # optional - sage.graphs True sage: g = S1.constant_map(S1) - sage: g.coproduct(g).is_bijective() + sage: g.coproduct(g).is_bijective() # optional - sage.graphs False """ codomain = self.codomain().coproduct(*[g.codomain() for g in others]) @@ -1177,8 +1177,9 @@ def suspension(self, n=1): EXAMPLES:: sage: eta = simplicial_sets.HopfMap() - sage: susp_eta = eta.suspension() - sage: susp_eta.mapping_cone().homology() == eta.mapping_cone().suspension().homology() + sage: mc_susp_eta = eta.suspension().mapping_cone() # optional - sage.graphs + sage: susp_mc_eta = eta.mapping_cone().suspension() # optional - sage.graphs + sage: mc_susp_eta.homology() == susp_mc_eta.homology() # optional - sage.graphs True This uses reduced suspensions if the original morphism is @@ -1188,19 +1189,19 @@ def suspension(self, n=1): sage: L = simplicial_sets.Simplex(1) sage: L.constant_map().is_pointed() False - sage: f = L.constant_map().suspension() - sage: f.is_constant() + sage: f = L.constant_map().suspension() # optional - sage.graphs + sage: f.is_constant() # optional - sage.graphs False sage: K = simplicial_sets.Sphere(3) sage: K.constant_map().is_pointed() True - sage: g = K.constant_map().suspension() - sage: g.is_constant() + sage: g = K.constant_map().suspension() # optional - sage.graphs + sage: g.is_constant() # optional - sage.graphs True - sage: h = K.identity().suspension() - sage: h.is_identity() + sage: h = K.identity().suspension() # optional - sage.graphs + sage: h.is_identity() # optional - sage.graphs True """ domain = self.domain() @@ -1248,13 +1249,14 @@ def n_skeleton(self, n, domain=None, codomain=None): EXAMPLES:: - sage: B = simplicial_sets.ClassifyingSpace(groups.misc.MultiplicativeAbelian([2])) - sage: one = Hom(B,B).identity() - sage: one.n_skeleton(3) + sage: G = groups.misc.MultiplicativeAbelian([2]) # optional - sage.groups + sage: B = simplicial_sets.ClassifyingSpace(G) # optional - sage.groups + sage: one = Hom(B,B).identity() # optional - sage.groups + sage: one.n_skeleton(3) # optional - sage.groups Simplicial set endomorphism of Simplicial set with 4 non-degenerate simplices Defn: Identity map - sage: c = Hom(B,B).constant_map() - sage: c.n_skeleton(3) + sage: c = Hom(B,B).constant_map() # optional - sage.groups + sage: c.n_skeleton(3) # optional - sage.groups Simplicial set endomorphism of Simplicial set with 4 non-degenerate simplices Defn: Constant map at 1 @@ -1388,8 +1390,8 @@ def induced_homology_morphism(self, base_ring=None, cohomology=False): [1|0] [-+-] [0|2] - sage: g3 = f.induced_homology_morphism(base_ring=GF(3), cohomology=True) - sage: g3.to_matrix() + sage: g3 = f.induced_homology_morphism(base_ring=GF(3), cohomology=True) # optional - sage.rings.finite_rings + sage: g3.to_matrix() # optional - sage.rings.finite_rings [1|0] [-+-] [0|2] diff --git a/src/sage/typeset/ascii_art.py b/src/sage/typeset/ascii_art.py index fe2fd4c419b..73ab45f9b90 100644 --- a/src/sage/typeset/ascii_art.py +++ b/src/sage/typeset/ascii_art.py @@ -15,18 +15,18 @@ EXAMPLES:: - sage: n = var('n') - sage: integrate(n^2/x,x) + sage: n = var('n') # optional - sage.symbolic + sage: integrate(n^2/x, x) # optional - sage.symbolic n^2*log(x) - sage: ascii_art(integrate(n^2/x,x)) + sage: ascii_art(integrate(n^2/x, x)) # optional - sage.symbolic 2 n *log(x) - sage: ascii_art(integrate(n^2/(pi*x),x)) + sage: ascii_art(integrate(n^2/(pi*x), x)) # optional - sage.symbolic 2 n *log(x) --------- pi - sage: ascii_art(list(Partitions(6))) + sage: ascii_art(list(Partitions(6))) # optional - sage.combinat [ * ] [ ** * ] [ *** ** * * ] @@ -40,18 +40,18 @@ sage: from sage.repl.interpreter import get_test_shell sage: shell = get_test_shell() sage: shell.run_cell('%display ascii_art') - sage: shell.run_cell("i = var('i')") - sage: shell.run_cell('sum(factorial(i)*x^i, i, 0, 10)') + sage: shell.run_cell("i = var('i')") # optional - sage.symbolic + sage: shell.run_cell('sum(factorial(i)*x^i, i, 0, 10)') # optional - sage.symbolic 10 9 8 7 6 5 4 3 3628800*x + 362880*x + 40320*x + 5040*x + 720*x + 120*x + 24*x + 6*x 2 + 2*x + x + 1 - sage: shell.run_cell('3/(7*x)') + sage: shell.run_cell('3/(7*x)') # optional - sage.symbolic 3 --- 7*x - sage: shell.run_cell('list(Compositions(5))') + sage: shell.run_cell('list(Compositions(5))') # optional - sage.combinat [ * [ * ** * * * [ * * ** *** * ** * * ** * * @@ -173,8 +173,8 @@ class AsciiArt(CharacterArt): EXAMPLES:: - sage: i = var('i') - sage: ascii_art(sum(pi^i/factorial(i)*x^i, i, 0, oo)) + sage: i = var('i') # optional - sage.symbolic + sage: ascii_art(sum(pi^i/factorial(i)*x^i, i, 0, oo)) # optional - sage.symbolic pi*x e """ @@ -216,9 +216,9 @@ def ascii_art(*obj, **kwds): EXAMPLES:: - sage: result = ascii_art(integral(exp(x+x^2)/(x+1), x)) + sage: result = ascii_art(integral(exp(x+x^2)/(x+1), x)) # optional - sage.symbolic ... - sage: result + sage: result # optional - sage.symbolic / | | 2 @@ -255,7 +255,7 @@ def ascii_art(*obj, **kwds): an ascii art separator:: sage: sep_line = ascii_art('\n'.join(' | ' for _ in range(6)), baseline=6) - sage: ascii_art(*Partitions(6), separator=sep_line, sep_baseline=0) + sage: ascii_art(*Partitions(6), separator=sep_line, sep_baseline=0) # optional - sage.combinat | | | | | | | | | | * | | | | | | | | | ** | * | | | | | | *** | | ** | * | * @@ -265,14 +265,14 @@ def ascii_art(*obj, **kwds): TESTS:: - sage: n = var('n') - sage: ascii_art(sum(binomial(2 * n, n + 1) * x^n, n, 0, oo)) + sage: n = var('n') # optional - sage.symbolic + sage: ascii_art(sum(binomial(2 * n, n + 1) * x^n, n, 0, oo)) # optional - sage.symbolic / _________ \ -\2*x + \/ 1 - 4*x - 1/ ------------------------- _________ 2*x*\/ 1 - 4*x - sage: ascii_art(list(DyckWords(3))) + sage: ascii_art(list(DyckWords(3))) # optional - sage.combinat [ /\ ] [ /\ /\ /\/\ / \ ] [ /\/\/\, /\/ \, / \/\, / \, / \ ] diff --git a/src/sage/typeset/character_art.py b/src/sage/typeset/character_art.py index dd1107db48d..1ba93ceea6b 100644 --- a/src/sage/typeset/character_art.py +++ b/src/sage/typeset/character_art.py @@ -58,8 +58,8 @@ def __init__(self, lines=[], breakpoints=[], baseline=None): EXAMPLES:: - sage: i = var('i') - sage: ascii_art(sum(pi^i/factorial(i)*x^i, i, 0, oo)) + sage: i = var('i') # optional - sage.symbolic + sage: ascii_art(sum(pi^i/factorial(i)*x^i, i, 0, oo)) # optional - sage.symbolic pi*x e diff --git a/src/sage/typeset/character_art_factory.py b/src/sage/typeset/character_art_factory.py index d83aa4da4f5..dc2354e58c8 100644 --- a/src/sage/typeset/character_art_factory.py +++ b/src/sage/typeset/character_art_factory.py @@ -84,9 +84,9 @@ def build(self, obj, baseline=None): EXAMPLES:: - sage: result = ascii_art(integral(exp(x+x^2)/(x+1), x)) + sage: result = ascii_art(integral(exp(x+x^2)/(x+1), x)) # optional - sage.symbolic ... - sage: result + sage: result # optional - sage.symbolic / | | 2 @@ -99,14 +99,14 @@ def build(self, obj, baseline=None): TESTS:: - sage: n = var('n') - sage: ascii_art(sum(binomial(2 * n, n + 1) * x^n, n, 0, oo)) + sage: n = var('n') # optional - sage.symbolic + sage: ascii_art(sum(binomial(2 * n, n + 1) * x^n, n, 0, oo)) # optional - sage.symbolic / _________ \ -\2*x + \/ 1 - 4*x - 1/ ------------------------- _________ 2*x*\/ 1 - 4*x - sage: ascii_art(list(DyckWords(3))) + sage: ascii_art(list(DyckWords(3))) # optional - sage.combinat [ /\ ] [ /\ /\ /\/\ / \ ] [ /\/\/\, /\/ \, / \/\, / \, / \ ] @@ -161,10 +161,10 @@ def build_from_magic_method(self, obj, baseline=None): EXAMPLES:: sage: from sage.typeset.ascii_art import _ascii_art_factory as factory - sage: out = factory.build_from_magic_method(identity_matrix(2)); out + sage: out = factory.build_from_magic_method(identity_matrix(2)); out # optional - sage.modules [1 0] [0 1] - sage: type(out) + sage: type(out) # optional - sage.modules """ magic_method = getattr(obj, self.magic_method_name) @@ -243,12 +243,12 @@ def build_container(self, content, left_border, right_border, baseline=0): TESTS:: - sage: l = ascii_art(list(DyckWords(3))) # indirect doctest - sage: l + sage: l = ascii_art(list(DyckWords(3))) # indirect doctest # optional - sage.combinat + sage: l # optional - sage.combinat [ /\ ] [ /\ /\ /\/\ / \ ] [ /\/\/\, /\/ \, / \/\, / \, / \ ] - sage: l._breakpoints + sage: l._breakpoints # optional - sage.combinat [9, 17, 25, 33] Check that zero-height strings are handled (:trac:`28527`):: @@ -289,7 +289,7 @@ def build_set(self, s, baseline=0): iteration over sets is non-deterministic so too is the results of this test:: - sage: ascii_art(set(DyckWords(3))) # indirect doctest random + sage: ascii_art(set(DyckWords(3))) # indirect doctest random # optional - sage.combinat { /\ } { /\ /\/\ /\ / \ } { / \/\, / \, /\/\/\, /\/ \, / \ } @@ -298,7 +298,7 @@ def build_set(self, s, baseline=0): a set, but still obtain the same output formatting:: sage: from sage.typeset.ascii_art import _ascii_art_factory as factory - sage: factory.build_set(sorted(set(DyckWords(3)))) + sage: factory.build_set(sorted(set(DyckWords(3)))) # optional - sage.combinat { /\ } { /\ /\ /\/\ / \ } { /\/\/\, /\/ \, / \/\, / \, / \ } @@ -316,13 +316,13 @@ def build_dict(self, d, baseline=0): TESTS:: sage: from collections import OrderedDict - sage: d = OrderedDict(enumerate(DyckWords(3))) - sage: art = ascii_art(d) # indirect doctest - sage: art + sage: d = OrderedDict(enumerate(DyckWords(3))) # optional - sage.combinat + sage: art = ascii_art(d) # indirect doctest # optional - sage.combinat + sage: art # optional - sage.combinat { /\ } { /\ /\ /\/\ / \ } { 0:/\/\/\, 1:/\/ \, 2:/ \/\, 3:/ \, 4:/ \ } - sage: art._breakpoints + sage: art._breakpoints # optional - sage.combinat [11, 21, 31, 41] Check that :trac:`29447` is fixed:: @@ -357,18 +357,18 @@ def build_list(self, l, baseline=0): TESTS:: - sage: l = ascii_art(list(DyckWords(3))) # indirect doctest - sage: l + sage: l = ascii_art(list(DyckWords(3))) # indirect doctest # optional - sage.combinat + sage: l # optional - sage.combinat [ /\ ] [ /\ /\ /\/\ / \ ] [ /\/\/\, /\/ \, / \/\, / \, / \ ] - sage: l._breakpoints + sage: l._breakpoints # optional - sage.combinat [9, 17, 25, 33] The breakpoints of the object are used as breakpoints:: - sage: l = ascii_art([DyckWords(2).list(), DyckWords(2).list()]) - sage: l._breakpoints + sage: l = ascii_art([DyckWords(2).list(), DyckWords(2).list()]) # optional - sage.combinat + sage: l._breakpoints # optional - sage.combinat [(2, [7]), 17, (18, [7])] The parentheses only stretch as high as the content (:trac:`28527`):: @@ -399,7 +399,7 @@ def build_tuple(self, t, baseline=0): TESTS:: - sage: ascii_art(tuple(DyckWords(3))) # indirect doctest + sage: ascii_art(tuple(DyckWords(3))) # indirect doctest # optional - sage.combinat ( /\ ) ( /\ /\ /\/\ / \ ) ( /\/\/\, /\/ \, / \/\, / \, / \ ) @@ -440,8 +440,8 @@ def concatenate(self, iterable, separator, empty=None, baseline=0, EXAMPLES:: - sage: i2 = identity_matrix(2) - sage: ascii_art(i2, i2, i2, sep=ascii_art(1/x)) + sage: i2 = identity_matrix(2) # optional - sage.modules + sage: ascii_art(i2, i2, i2, sep=ascii_art(1/x)) # optional - sage.modules sage.symbolic 1 1 [1 0]-[1 0]-[1 0] [0 1]x[0 1]x[0 1] diff --git a/src/sage/typeset/unicode_art.py b/src/sage/typeset/unicode_art.py index caed3475afe..0b4177e6a60 100644 --- a/src/sage/typeset/unicode_art.py +++ b/src/sage/typeset/unicode_art.py @@ -44,8 +44,8 @@ class UnicodeArt(CharacterArt): EXAMPLES:: - sage: i = var('i') - sage: unicode_art(sum(pi^i/factorial(i)*x^i, i, 0, oo)) + sage: i = var('i') # optional - sage.symbolic + sage: unicode_art(sum(pi^i/factorial(i)*x^i, i, 0, oo)) # optional - sage.symbolic π⋅x ℯ """ @@ -88,9 +88,9 @@ def unicode_art(*obj, **kwds): EXAMPLES:: - sage: result = unicode_art(integral(exp(sqrt(x))/(x+pi), x)) + sage: result = unicode_art(integral(exp(sqrt(x))/(x+pi), x)) # optional - sage.symbolic ... - sage: result + sage: result # optional - sage.symbolic ⌠ ⎮ √x ⎮ ℯ @@ -107,7 +107,7 @@ def unicode_art(*obj, **kwds): an unicode art separator:: sage: sep_line = unicode_art('\n'.join(' ⎟ ' for _ in range(5)), baseline=5) - sage: unicode_art(*AlternatingSignMatrices(3), + sage: unicode_art(*AlternatingSignMatrices(3), # optional - sage.combinat ....: separator=sep_line, sep_baseline=1) ⎟ ⎟ ⎟ ⎟ ⎟ ⎟ ⎛1 0 0⎞ ⎟ ⎛0 1 0⎞ ⎟ ⎛1 0 0⎞ ⎟ ⎛ 0 1 0⎞ ⎟ ⎛0 0 1⎞ ⎟ ⎛0 1 0⎞ ⎟ ⎛0 0 1⎞ @@ -117,14 +117,14 @@ def unicode_art(*obj, **kwds): TESTS:: - sage: n = var('n') - sage: unicode_art(sum(binomial(2 * n, n + 1) * x^n, n, 0, oo)) + sage: n = var('n') # optional - sage.symbolic + sage: unicode_art(sum(binomial(2 * n, n + 1) * x^n, n, 0, oo)) # optional - sage.symbolic ⎛ _________ ⎞ -⎝2⋅x + ╲╱ 1 - 4⋅x - 1⎠ ───────────────────────── _________ 2⋅x⋅╲╱ 1 - 4⋅x - sage: unicode_art(list(DyckWords(3))) + sage: unicode_art(list(DyckWords(3))) # optional - sage.combinat ⎡ ╱╲ ⎤ ⎢ ╱╲ ╱╲ ╱╲╱╲ ╱ ╲ ⎥ ⎣ ╱╲╱╲╱╲, ╱╲╱ ╲, ╱ ╲╱╲, ╱ ╲, ╱ ╲ ⎦